Accept plugin manifest apiVersion 2.0-experimental
Why: Downstream repositories need a versioned public manifest for skills, MCP, knowledge, parsers, agents, channels, and pages without forking the base. Evidence: go test ./... passed after omitzero on empty scope and backend so the golden plugin_manifest stays stable. Impact: apiVersion 1.0 remains accepted. New provides fields are optional. Scope and backend are omitted when zero. Refs: docs/proposals/2026-10-01-plugin-contract-v2.md Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,35 +8,44 @@ import "encoding/json"
|
||||
const PluginAPIVersion = "1.0"
|
||||
|
||||
type PluginManifest struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
APIVersion string `json:"apiVersion"`
|
||||
Requires PluginRequires `json:"requires,omitempty"`
|
||||
Provides PluginProvides `json:"provides"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
APIVersion string `json:"apiVersion"`
|
||||
Requires PluginRequires `json:"requires,omitempty"`
|
||||
Provides PluginProvides `json:"provides"`
|
||||
Scope PluginScope `json:"scope,omitzero"`
|
||||
Backend PluginBackend `json:"backend,omitzero"`
|
||||
}
|
||||
|
||||
type PluginRequires struct {
|
||||
Network []string `json:"network,omitempty"` // 允许访问的域名(展示用,v1 自装自审)
|
||||
Network []string `json:"network,omitempty"` // 出站域名白名单;v2 空名单拒绝出站,v1 空名单保持放行
|
||||
}
|
||||
|
||||
type PluginProvides struct {
|
||||
Tools []string `json:"tools,omitempty"` // tools/ 目录下的资产名
|
||||
Workflows []string `json:"workflows,omitempty"`
|
||||
Intents []string `json:"intents,omitempty"`
|
||||
Prompts []string `json:"prompts,omitempty"`
|
||||
Panels []string `json:"panels,omitempty"`
|
||||
Cards []string `json:"cards,omitempty"`
|
||||
Settings []string `json:"settings,omitempty"`
|
||||
Commands []string `json:"commands,omitempty"` // commands/ 资产名(spec 权威在 Agent-Command 库)
|
||||
Tools []string `json:"tools,omitempty"` // tools/ 目录下的资产名
|
||||
Workflows []string `json:"workflows,omitempty"`
|
||||
Intents []string `json:"intents,omitempty"`
|
||||
Prompts []string `json:"prompts,omitempty"`
|
||||
Panels []string `json:"panels,omitempty"`
|
||||
Cards []string `json:"cards,omitempty"`
|
||||
Settings []string `json:"settings,omitempty"`
|
||||
Commands []string `json:"commands,omitempty"` // commands/ 资产名(spec 权威在 Agent-Command 库)
|
||||
Workspaces []string `json:"workspaces,omitempty"` // workspaces/ 资产名(工作区弹层)
|
||||
Skills []string `json:"skills,omitempty"`
|
||||
MCPServers []string `json:"mcpServers,omitempty"`
|
||||
Knowledge []string `json:"knowledge,omitempty"`
|
||||
Parsers []string `json:"parsers,omitempty"`
|
||||
Agents []string `json:"agents,omitempty"`
|
||||
Channels []string `json:"channels,omitempty"`
|
||||
Pages []string `json:"pages,omitempty"`
|
||||
}
|
||||
|
||||
// PluginPanel:右栏面板声明(UI schema 静态骨架 + 可选数据提供者)。
|
||||
type PluginPanel struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Body []UINode `json:"body"`
|
||||
// Tool 绑定:面板挂载时调用该工具刷新 Body 中的动态区(v1 简化为整体刷新)。
|
||||
RefreshTool string `json:"refreshTool,omitempty"`
|
||||
@@ -44,23 +53,23 @@ type PluginPanel struct {
|
||||
|
||||
// WorkflowDef:工作流即数据(4.6)。Step 可产 HITL 卡片、调工具、产出工件。
|
||||
type WorkflowDef struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description,omitempty"`
|
||||
IntentID string `json:"intentId,omitempty"` // 绑定意图(命中即启动)
|
||||
Steps []WorkflowStep `json:"steps"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description,omitempty"`
|
||||
IntentID string `json:"intentId,omitempty"` // 绑定意图(命中即启动)
|
||||
Steps []WorkflowStep `json:"steps"`
|
||||
}
|
||||
|
||||
type WorkflowStep struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Kind string `json:"kind"` // prompt | tool | hitl | artifact | card
|
||||
Prompt string `json:"prompt,omitempty"` // prompt: 发给模型的指令模板
|
||||
Tool string `json:"tool,omitempty"` // tool: 工具名
|
||||
Args json.RawMessage `json:"args,omitempty"` // tool: 参数模板
|
||||
Hitl *HITLCardTemplate `json:"hitl,omitempty"` // hitl: 卡片模板
|
||||
Artifact string `json:"artifact,omitempty"` // artifact: 产出工件名模板
|
||||
Card *ActivityCardTemplate `json:"card,omitempty"` // card: 产收件箱任务卡
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Kind string `json:"kind"` // prompt | tool | hitl | artifact | card
|
||||
Prompt string `json:"prompt,omitempty"` // prompt: 发给模型的指令模板
|
||||
Tool string `json:"tool,omitempty"` // tool: 工具名
|
||||
Args json.RawMessage `json:"args,omitempty"` // tool: 参数模板
|
||||
Hitl *HITLCardTemplate `json:"hitl,omitempty"` // hitl: 卡片模板
|
||||
Artifact string `json:"artifact,omitempty"` // artifact: 产出工件名模板
|
||||
Card *ActivityCardTemplate `json:"card,omitempty"` // card: 产收件箱任务卡
|
||||
}
|
||||
|
||||
// ActivityCardTemplate:工作流步骤产卡模板(kind=card)——步骤执行时生成
|
||||
@@ -76,20 +85,20 @@ type ActivityCardTemplate struct {
|
||||
// PluginWorkspace:工作区弹层声明(深读与治理视图;Esc/遮罩关闭回对话现场,
|
||||
// 不承载任何唯一步骤——每个操作必须另有命令路径,提案 D31)。
|
||||
type PluginWorkspace struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Shortcut string `json:"shortcut,omitempty"` // "1"–"9"(⌘N / Ctrl+N 召出)
|
||||
BadgeTool string `json:"badgeTool,omitempty"` // 角标提供者工具:返回 {count,tone}
|
||||
Body []UINode `json:"body"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Shortcut string `json:"shortcut,omitempty"` // "1"–"9"(⌘N / Ctrl+N 召出)
|
||||
BadgeTool string `json:"badgeTool,omitempty"` // 角标提供者工具:返回 {count,tone}
|
||||
Body []UINode `json:"body"`
|
||||
// RefreshTool:挂载时调用刷新 Body 动态区(与 Panel 同机制,v1 整体刷新)。
|
||||
RefreshTool string `json:"refreshTool,omitempty"`
|
||||
}
|
||||
|
||||
type HITLCardTemplate struct {
|
||||
Question string `json:"question"`
|
||||
Kind HITLKind `json:"kind"`
|
||||
Choices []HITLChoice `json:"choices,omitempty"`
|
||||
AllowFreeInput bool `json:"allowFreeInput"`
|
||||
FreeInputHint string `json:"freeInputHint,omitempty"`
|
||||
Question string `json:"question"`
|
||||
Kind HITLKind `json:"kind"`
|
||||
Choices []HITLChoice `json:"choices,omitempty"`
|
||||
AllowFreeInput bool `json:"allowFreeInput"`
|
||||
FreeInputHint string `json:"freeInputHint,omitempty"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user