482 lines
20 KiB
JSON
482 lines
20 KiB
JSON
{
|
||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
"$id": "https://openclaw.local/skill-template/skill-actions.schema.json",
|
||
"title": "SkillActionManifest",
|
||
"description": "匠厂 skill-template 对新技能的严格 Action manifest 规范(schemaVersion 1)。additionalProperties=false 表示模板推荐契约;宿主运行时可能为兼容历史 manifest 接受部分缺省字段,但新技能不应依赖缺省行为。含可选 hostEffects/steps(匠厂宿主 ≥2.8.5)与可选 hoverHint(数据管理工具栏悬停,需宿主已支持该字段)。",
|
||
"type": "object",
|
||
"required": ["schemaVersion", "skill", "actions"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"schemaVersion": {
|
||
"type": "integer",
|
||
"const": 1
|
||
},
|
||
"skill": {
|
||
"type": "string",
|
||
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
|
||
"description": "与 SKILL.md metadata.openclaw.slug 一致"
|
||
},
|
||
"actions": {
|
||
"type": "array",
|
||
"minItems": 1,
|
||
"items": { "$ref": "#/$defs/action" },
|
||
"description": "Action 列表。同一 placement(toolbar/row/batch)下,宿主按本数组中匹配项的相对顺序展示。toolbar/batch:表顶栏全部直接展示(无「更多操作」溢出)。row:行级入口,宿主可呈现为操作列、行右键和/或行内「⋯」(同一批 Action、同一顺序);不在本字段配置排序、截断或菜单树。调整顺序即调整数组先后。无独立 sortOrder 字段。宿主内置刷新/导出/查看等不参与本顺序。表顶栏宽时左右横排,窄时左右分栏且栏内竖排。"
|
||
},
|
||
"policy": {
|
||
"$ref": "#/$defs/policyDeclaration",
|
||
"description": "可选。启用 Data Policy(L1/L2)。缺省或不 enabled = L0,宿主不拉 Snapshot。详见 references/POLICY.md。"
|
||
},
|
||
"cellPresentation": {
|
||
"$ref": "#/$defs/cellPresentationDeclaration",
|
||
"description": "可选。启用数据管理单元格呈现(P1)。缺省或不 enabled = P0,宿主不读标色。详见 references/CELL_PRESENTATION.md。"
|
||
}
|
||
},
|
||
"$defs": {
|
||
"cellPresentationDeclaration": {
|
||
"type": "object",
|
||
"required": ["enabled"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"enabled": {
|
||
"type": "boolean",
|
||
"description": "仅 true 启用;false 等同 P0。"
|
||
}
|
||
}
|
||
},
|
||
"policyDeclaration": {
|
||
"type": "object",
|
||
"required": ["enabled"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"enabled": {
|
||
"type": "boolean",
|
||
"description": "仅 true 启用;false 等同 L0。"
|
||
},
|
||
"entrypoint": {
|
||
"$ref": "#/$defs/entrypoint",
|
||
"description": "enabled=true 时必填。推荐 command=policy,args 可含 {{table}}/{{skill}}/{{userId}}。"
|
||
},
|
||
"appliesTo": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string",
|
||
"enum": ["data-management"]
|
||
},
|
||
"description": "缺省 [\"data-management\"]。本期宿主只实现 data-management。"
|
||
}
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"properties": { "enabled": { "const": true } },
|
||
"required": ["enabled"]
|
||
},
|
||
"then": {
|
||
"required": ["entrypoint"]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"placement": {
|
||
"type": "string",
|
||
"enum": ["toolbar", "row", "batch", "cron", "agent", "skill-detail"],
|
||
"description": "稳定支持 toolbar/row/batch/cron/agent/skill-detail(对齐匠厂宿主)。row=行级入口(操作列/行右键/⋯ 等由宿主呈现,无独立 row-context-menu placement)。placements 与 executionProfile 正交,不做条件限制。"
|
||
},
|
||
"mutationKind": {
|
||
"type": "string",
|
||
"enum": ["create", "update", "delete", "import"],
|
||
"description": "可选。接管数据管理默认按钮:create=新增、update=编辑、delete=删除、import=导入。须配合非空 bind.tables;无配置时宿主仍直写 SQLite。import 时 UI 仍用宿主「导入数据」面板,确认后调用本 Action 写库。"
|
||
},
|
||
"scalarArg": {
|
||
"type": ["string", "number", "boolean"]
|
||
},
|
||
"inputProperty": {
|
||
"type": "object",
|
||
"required": ["type"],
|
||
"additionalProperties": true,
|
||
"properties": {
|
||
"type": {
|
||
"type": "string",
|
||
"enum": ["string", "number", "boolean", "object"],
|
||
"description": "模板 Phase 1 仅推荐 string/number/boolean;根 inputSchema.type=object 的 properties 使用基础标量类型"
|
||
},
|
||
"title": { "type": "string" },
|
||
"description": { "type": "string" },
|
||
"default": {},
|
||
"enum": {
|
||
"type": "array",
|
||
"minItems": 1
|
||
},
|
||
"sensitive": { "type": "boolean" },
|
||
"readOnly": {
|
||
"type": "boolean",
|
||
"description": "宿主数据管理表单只读展示该字段(仍会随提交传入 entrypoint);用于行内/勾选预填的主键等"
|
||
},
|
||
"column": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-z][a-z0-9_]*$",
|
||
"description": "可选。绑定业务表物理列名;Action 弹窗(toolbar/batch)与 replaces create/update 抽屉均可复用该列的中文名与 lookup 下拉"
|
||
},
|
||
"display_type": {
|
||
"type": "string",
|
||
"enum": ["textarea", "date", "datetime_unix_seconds", "url", "email", "lookup", "directory", "file"],
|
||
"description": "可选。表单控件提示;与 format 二选一即可。lookup=关联下拉(须配 lookup 对象或绑到已有 lookup 列)。file/directory=本地路径选择(可选 pathRoot 指定起始目录,见 ACTIONS.md)。须与 CRUD display_type 语义对齐。"
|
||
},
|
||
"format": {
|
||
"type": "string",
|
||
"enum": ["textarea", "date", "datetime_unix_seconds", "url", "email", "lookup", "directory", "file"],
|
||
"description": "可选。display_type 别名,语义相同。"
|
||
},
|
||
"pathRoot": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"description": "可选。仅对 display_type/format 为 file 或 directory 有意义:原生选文件/目录对话框的起始文件夹,相对当前技能数据根(如 input/库存数据)。省略则宿主默认打开 {skill_data}/input。禁止绝对路径、盘符与 ..。Agent/CLI 忽略。见 references/ACTIONS.md「本地路径选择与 pathRoot」。"
|
||
},
|
||
"lookup": {
|
||
"$ref": "#/$defs/lookupConfig",
|
||
"description": "可选。内联同库表关联 Lookup(与列 options_json lookup 对象同构)。用于当前表没有对应列时;推荐同时设 display_type=lookup。见 ACTIONS.md「跨表引用:Lookup」。"
|
||
},
|
||
"visibleWhen": {
|
||
"description": "可选。表单字段条件显隐。宿主在数据管理/定时任务参数表单中:规则不满足则隐藏该字段、提交时省略、且不校验 required。支持 {field,equals} / {field,in:[...]},或单键简写 {collectMode:\"按关键词采集\"} / {collectMode:[\"a\",\"b\"]}。Agent/CLI 无 UI 时同样按当前 input 求值后剥离隐藏字段。",
|
||
"oneOf": [
|
||
{
|
||
"type": "object",
|
||
"required": ["field", "equals"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"field": { "type": "string", "minLength": 1 },
|
||
"equals": { "type": ["string", "number", "boolean"] }
|
||
}
|
||
},
|
||
{
|
||
"type": "object",
|
||
"required": ["field", "in"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"field": { "type": "string", "minLength": 1 },
|
||
"in": {
|
||
"type": "array",
|
||
"minItems": 1,
|
||
"items": { "type": ["string", "number", "boolean"] }
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"type": "object",
|
||
"minProperties": 1,
|
||
"maxProperties": 1,
|
||
"additionalProperties": {
|
||
"oneOf": [
|
||
{ "type": ["string", "number", "boolean"] },
|
||
{
|
||
"type": "array",
|
||
"minItems": 1,
|
||
"items": { "type": ["string", "number", "boolean"] }
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"lookupConfig": {
|
||
"type": "object",
|
||
"required": ["ref_table", "value_column", "label_column"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"ref_table": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
||
"description": "同库被引用表名"
|
||
},
|
||
"value_column": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
||
"description": "提交值列(编号 / 外键)"
|
||
},
|
||
"label_column": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
||
"description": "主文案列"
|
||
},
|
||
"extra_column": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
||
"description": "可选。第三展示列;有值时宿主拼成「value · label(extra)」"
|
||
},
|
||
"filter_column": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
||
"description": "可选。等值过滤列"
|
||
},
|
||
"filter_value": {
|
||
"type": ["string", "number", "boolean", "null"],
|
||
"description": "可选。与 filter_column 配对的等值"
|
||
},
|
||
"multiple": {
|
||
"type": "boolean",
|
||
"description": "可选。true=多选 Lookup(存/提交 TEXT 逗号分隔 id);省略或 false=单选(默认)。与 CRUD options_json lookup 同构。"
|
||
}
|
||
},
|
||
"description": "同库 FK 式 Lookup。展示:value · label;有 extra 时 value · label(extra)。multiple 时多选。宿主亦接受 camelCase 键名。"
|
||
},
|
||
"inputSchema": {
|
||
"type": "object",
|
||
"required": ["type", "properties"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"type": { "const": "object" },
|
||
"required": {
|
||
"type": "array",
|
||
"items": { "type": "string" }
|
||
},
|
||
"properties": {
|
||
"type": "object",
|
||
"additionalProperties": { "$ref": "#/$defs/inputProperty" }
|
||
}
|
||
}
|
||
},
|
||
"entrypoint": {
|
||
"type": "object",
|
||
"required": ["type", "command", "args"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"type": { "const": "cli" },
|
||
"command": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"args": {
|
||
"type": "array",
|
||
"items": { "$ref": "#/$defs/scalarArg" },
|
||
"description": "仅允许 string/number/boolean 标量数组"
|
||
}
|
||
}
|
||
},
|
||
"confirmation": {
|
||
"type": "object",
|
||
"required": ["message"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"message": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
}
|
||
}
|
||
},
|
||
"bind": {
|
||
"type": "object",
|
||
"required": ["tables"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"tables": {
|
||
"type": "array",
|
||
"minItems": 1,
|
||
"uniqueItems": true,
|
||
"items": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-z][a-z0-9_]*$",
|
||
"description": "英文 snake_case 业务表名;须真实存在于技能 SQLite / _jiangchang_tables"
|
||
},
|
||
"description": "数据管理表级绑定:决定 toolbar/row/batch Action 出现在哪些表。宿主兼容旧技能时,缺失 bind 可视为全表展示;新技能 toolbar Action 必须显式声明。"
|
||
},
|
||
"inputMapping": {
|
||
"type": "object",
|
||
"additionalProperties": { "type": "string", "minLength": 1 },
|
||
"description": "可选。将 $row.$pk / $row.col / $selection.ids 等映射到 inputSchema 字段名,供 row/batch 预填。"
|
||
},
|
||
"columnMapping": {
|
||
"type": "object",
|
||
"additionalProperties": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-z][a-z0-9_]*$"
|
||
},
|
||
"description": "可选。将 inputSchema 属性名映射到业务表物理列名,供 Action 弹窗与 replaces create/update 抽屉复用列 displayName / lookup options。"
|
||
}
|
||
},
|
||
"description": "表级绑定;toolbar 必填。可选 inputMapping / columnMapping。concurrency/locks 勿写入。"
|
||
},
|
||
"hostEffectId": {
|
||
"type": "string",
|
||
"enum": ["reloadTable", "refreshCatalog", "clearSelection"],
|
||
"description": "数据管理 UI 副作用(匠厂宿主 ≥2.8.5)。reloadTable=刷新当前表(含 Data Policy);refreshCatalog=刷新技能目录;clearSelection=清空多选。"
|
||
},
|
||
"hostEffects": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"onSuccess": {
|
||
"type": "array",
|
||
"items": { "$ref": "#/$defs/hostEffectId" },
|
||
"uniqueItems": true,
|
||
"description": "sync 退出 0,或 async 任务已被任务中心接收时触发(不是 Job 跑完)。"
|
||
},
|
||
"onFailure": {
|
||
"type": "array",
|
||
"items": { "$ref": "#/$defs/hostEffectId" },
|
||
"uniqueItems": true,
|
||
"description": "sync 失败,或 async 启动被拒时触发。"
|
||
}
|
||
},
|
||
"description": "可选。UI 副作用简写;省略则宿主不额外改 UI。与 placements/executionProfile/interaction 正交;cron/agent 忽略。新技能有编排需求时优先用 steps。"
|
||
},
|
||
"actionStep": {
|
||
"type": "object",
|
||
"required": ["when", "do"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"when": {
|
||
"type": "string",
|
||
"enum": ["before", "afterSuccess", "afterFailure"],
|
||
"description": "before=CLI 前;afterSuccess/afterFailure 时机同 hostEffects.onSuccess/onFailure。"
|
||
},
|
||
"do": {
|
||
"type": "string",
|
||
"enum": ["deleteByFk", "deleteRows", "reloadTable", "refreshCatalog", "clearSelection"],
|
||
"description": "闭环操作或 UI 效果。deleteByFk/deleteRows 须配合 table(及 fk)。"
|
||
},
|
||
"table": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-z][a-z0-9_]*$",
|
||
"description": "deleteByFk / deleteRows 目标表(snake_case)。"
|
||
},
|
||
"fk": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"pattern": "^[a-z][a-z0-9_]*$",
|
||
"description": "deleteByFk 时子表外键列名。"
|
||
}
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"properties": { "do": { "const": "deleteByFk" } },
|
||
"required": ["do"]
|
||
},
|
||
"then": { "required": ["table", "fk"] }
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "do": { "const": "deleteRows" } },
|
||
"required": ["do"]
|
||
},
|
||
"then": { "required": ["table"] }
|
||
}
|
||
]
|
||
},
|
||
"action": {
|
||
"type": "object",
|
||
"required": ["id", "label", "description", "placements", "entrypoint", "executionProfile"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"id": {
|
||
"type": "string",
|
||
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
|
||
"minLength": 1
|
||
},
|
||
"label": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"description": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"hoverHint": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"description": "可选。数据管理工具栏悬停文案。与 description / confirmation.message 独立;省略则不显示悬停,不回退。需宿主已支持该字段。当前实现为顶栏技能按钮,不含宿主内置删除/刷新/新增/导入/导出。"
|
||
},
|
||
"placements": {
|
||
"type": "array",
|
||
"minItems": 0,
|
||
"items": { "$ref": "#/$defs/placement" },
|
||
"description": "决定 Action 出现在哪里;与 executionProfile 正交。仅 replaces 接管默认 CRUD 时可为空数组。数据管理 toolbar/row/batch 的顺序由顶层 actions 数组相对顺序决定。表顶栏 toolbar/batch 全部直接展示(无溢出菜单);row 为行级入口(操作列/行右键/⋯),不在本字段配置排序、截断或菜单树。"
|
||
},
|
||
"replaces": { "$ref": "#/$defs/mutationKind" },
|
||
"entrypoint": { "$ref": "#/$defs/entrypoint" },
|
||
"inputSchema": { "$ref": "#/$defs/inputSchema" },
|
||
"confirmation": { "$ref": "#/$defs/confirmation" },
|
||
"executionProfile": {
|
||
"type": "string",
|
||
"enum": ["sync", "async"],
|
||
"description": "sync=调用方等待结构化结果(不建 Job);async=宿主建后台 Job 并进任务中心。必须显式写出;长耗时建议 async,但不限制 placements。"
|
||
},
|
||
"interaction": {
|
||
"type": "string",
|
||
"enum": ["auto", "direct", "confirm", "form"],
|
||
"description": "数据管理等可点击入口的交互方式(与 executionProfile 正交)。direct=一点即跑;confirm=轻量确认(文案用 confirmation.message);form=参数表单;auto/省略=宿主按 inputSchema+confirmation 推断。cron 触发与 agent 忽略本字段。"
|
||
},
|
||
"interactionByPlacement": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"toolbar": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"row": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"batch": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"cron": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"agent": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"skill-detail": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"create": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"update": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"delete": { "type": "string", "enum": ["direct", "confirm", "form"] },
|
||
"import": { "type": "string", "enum": ["direct", "confirm", "form"] }
|
||
},
|
||
"description": "按 placement / replaces 覆盖 interaction(只能写 concrete 模式,不能写 auto)。"
|
||
},
|
||
"bind": { "$ref": "#/$defs/bind" },
|
||
"hostEffects": { "$ref": "#/$defs/hostEffects" },
|
||
"steps": {
|
||
"type": "array",
|
||
"maxItems": 8,
|
||
"items": { "$ref": "#/$defs/actionStep" },
|
||
"description": "可选。有序宿主编排(before / afterSuccess / afterFailure);单次最多 8 步。与 hostEffects 可并存(同效果可能各跑一次)。新技能优先用 steps。省略则无额外步骤。需匠厂宿主 ≥2.8.5。"
|
||
},
|
||
"authz": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"capability": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"description": "可选文档/静态提示用能力名;宿主不得仅凭此显隐按钮,运行时以 policy Snapshot 为准。"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"if": {
|
||
"properties": {
|
||
"placements": {
|
||
"contains": { "const": "toolbar" }
|
||
}
|
||
},
|
||
"required": ["placements"]
|
||
},
|
||
"then": {
|
||
"required": ["bind"]
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"required": ["replaces"]
|
||
},
|
||
"then": {
|
||
"required": ["bind"]
|
||
}
|
||
}
|
||
],
|
||
"description": "concurrency/locks 为未稳定预留字段,勿写入新技能 manifest。placements 含 toolbar 或声明 replaces 时必须声明 bind.tables。无 replaces 时 placements 建议非空(模板测试强制)。"
|
||
}
|
||
}
|
||
}
|