feat: standardize skill data management and actions
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
161
references/ACTIONS.md
Normal file
161
references/ACTIONS.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Skill Action Manifest(匠厂宿主)
|
||||
|
||||
本文件说明 `assets/actions.json` 与 `scripts/main.py` CLI 的对应关系,供 Agent 编排与宿主 **Skill Action Runtime** 使用。
|
||||
|
||||
**边界:** 用户市场说明见根目录 [`README.md`](../README.md);CLI 参数与错误码细节见 [`CLI.md`](CLI.md)。
|
||||
|
||||
## Action 是否必需
|
||||
|
||||
Action 是**可选能力**:
|
||||
|
||||
- 没有宿主直接操作需求的技能,**可以不提供** `actions.json`。
|
||||
- 需要出现在**数据管理按钮**、**技能详情**、**定时任务**或 **Agent 直接调用**中的技能,**必须**提供 `assets/actions.json`。
|
||||
|
||||
## 文件位置
|
||||
|
||||
```text
|
||||
{skill_root}/assets/actions.json
|
||||
```
|
||||
|
||||
宿主扫描路径示例:
|
||||
|
||||
```text
|
||||
~/.openclaw/skills/your-skill-slug/assets/actions.json
|
||||
```
|
||||
|
||||
## 顶层结构
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `schemaVersion` | 是 | 当前固定为 `1` |
|
||||
| `skill` | 是 | 必须与 `SKILL.md` 的 `metadata.openclaw.slug` 一致 |
|
||||
| `actions` | 是 | Action 数组,每项 `id` 唯一 |
|
||||
|
||||
模板最小示例见 [`assets/actions.json`](../assets/actions.json);JSON Schema 见 [`assets/schemas/skill-actions.schema.json`](../assets/schemas/skill-actions.schema.json)。
|
||||
|
||||
## 执行模型
|
||||
|
||||
宿主将 action 转为 argv,再执行:
|
||||
|
||||
```text
|
||||
python {skill_root}/scripts/main.py <command> <args...>
|
||||
```
|
||||
|
||||
- `entrypoint.type` 当前只支持 `cli`
|
||||
- `entrypoint.command` → CLI 子命令(须真实存在)
|
||||
- `entrypoint.args` → 子命令参数(**必须为 JSON 数组**)
|
||||
- `{{fieldName}}` → 来自 `inputSchema` 用户输入的简单模板替换
|
||||
|
||||
完整子命令定义见 [`scripts/cli/app.py`](../scripts/cli/app.py)。
|
||||
|
||||
### CLI 输出契约
|
||||
|
||||
技能 CLI 必须:
|
||||
|
||||
- 使用稳定的退出码
|
||||
- 成功时输出可解析的结构化结果
|
||||
- 失败时输出稳定错误信息
|
||||
- 对可预期错误提供稳定错误码
|
||||
- 对用户可处理的问题提供 `HINT`
|
||||
- 不依赖 Agent 连续对话才能完成
|
||||
- 不自行实现宿主任务中心
|
||||
- 长时间任务允许异步执行,由宿主任务中心承载状态
|
||||
- 不在 CLI 中硬编码宿主安装目录
|
||||
- 不直接依赖某个具体 UI 页面
|
||||
|
||||
建议错误输出格式:
|
||||
|
||||
```text
|
||||
ERROR:<CODE>: <message>
|
||||
HINT: <next step>
|
||||
```
|
||||
|
||||
## placements(入口位置)
|
||||
|
||||
| 值 | 含义 |
|
||||
|----|------|
|
||||
| `toolbar` | 数据管理第一排技能按钮 |
|
||||
| `skill-detail` | 技能详情或技能市场详情页 |
|
||||
| `agent` | Agent 可直接调用 |
|
||||
| `cron` | 定时任务可直接调用 |
|
||||
|
||||
**预留能力(当前宿主可能尚未完整支持,模板示例请勿使用):**
|
||||
|
||||
| 值 | 说明 |
|
||||
|----|------|
|
||||
| `row` | 行内操作(未来扩展) |
|
||||
| `batch` | 批量操作(未来扩展) |
|
||||
|
||||
可以在 manifest 中作为未来扩展值定义,但不要让技能作者误以为 `row` / `batch` 已经完整可用。
|
||||
|
||||
## inputSchema 与参数表单
|
||||
|
||||
当前宿主稳定支持:
|
||||
|
||||
- `object` / `string` / `number` / `boolean`
|
||||
- `enum` / `default` / `required` / `sensitive`
|
||||
- 简单模板替换(`{{fieldName}}`)
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"required": ["query"],
|
||||
"properties": {
|
||||
"query": {
|
||||
"type": "string",
|
||||
"title": "查询条件"
|
||||
},
|
||||
"limit": {
|
||||
"type": "number",
|
||||
"title": "返回数量",
|
||||
"default": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
约定:
|
||||
|
||||
- `boolean` 在宿主中渲染为开关
|
||||
- `enum` 在宿主中渲染为选择框
|
||||
- `required` 字段在提交前校验
|
||||
- `sensitive` 字段不得出现在低信任入口
|
||||
- 需要确认的副作用操作使用 `confirmation.message`
|
||||
- 模板参数使用 `{{fieldName}}`,且必须在 `inputSchema.properties` 中声明
|
||||
- `entrypoint.args` 项当前只允许 `string`、`number`、`boolean`;不允许对象或 `null`
|
||||
- **不要**在当前模板中宣传 `nested object`、`oneOf`、复杂数组等尚未稳定支持的能力
|
||||
|
||||
## 风险与入口配置
|
||||
|
||||
- 查询、诊断、版本检查可以放到 `skill-detail` 或 `agent`
|
||||
- 低风险、常用动作才考虑放 `toolbar`
|
||||
- 会修改本地数据、访问外部系统、执行长时间任务的动作必须谨慎配置
|
||||
- 有副作用的动作应添加 `confirmation.message`
|
||||
- 高风险动作不应默认出现在 `toolbar`
|
||||
- 含 `sensitive` 参数的 action 不应放入 `toolbar` 或 `cron`,除非有明确安全设计
|
||||
- 不要为了「按钮多」而暴露所有 CLI 子命令
|
||||
- 一个 CLI 命令可以拆成多个语义清晰的 action,但每个 action 必须有明确语义
|
||||
|
||||
## 模板示例 action 一览
|
||||
|
||||
| id | CLI | placements | 说明 |
|
||||
|----|-----|------------|------|
|
||||
| `health` | `health` | skill-detail, agent | 运行环境检查 |
|
||||
| `version` | `version` | skill-detail | 版本 JSON |
|
||||
| `config-path` | `config-path` | skill-detail | 配置路径 JSON |
|
||||
|
||||
复制为新技能后,请按业务需要增删 action;不需要宿主入口时可删除整个 `actions.json`。
|
||||
|
||||
## 与宿主 API(参考)
|
||||
|
||||
| 宿主 API | 用途 |
|
||||
|----------|------|
|
||||
| `GET /api/skill-actions/{skillSlug}` | 读取 manifest |
|
||||
| `POST /api/skill-actions/run` | `{ skillSlug, actionId, input?, source? }` |
|
||||
| `GET /api/skill-actions/jobs` | 任务中心 |
|
||||
|
||||
具体路径与字段以宿主实现为准;技能侧只需保证 manifest 与 CLI 契约稳定。
|
||||
@@ -13,7 +13,8 @@
|
||||
| 根目录 [`README.md`](../README.md) | 用户市场详情页说明 |
|
||||
| [`SKILL.md`](../SKILL.md) | LLM / OpenClaw 平台技能入口 |
|
||||
| [`CLI.md`](CLI.md) | 命令行入口、参数与调用契约 |
|
||||
| [`SCHEMA.md`](SCHEMA.md) | 输入输出、数据库与字段说明 |
|
||||
| [`SCHEMA.md`](SCHEMA.md) | 本地 SQLite 与数据管理展示契约 |
|
||||
| [`ACTIONS.md`](ACTIONS.md) | Skill Action manifest 与宿主入口契约 |
|
||||
| [`../development/`](../development/) | 开发、测试、技术规范(给开发者 / AI 编程代理) |
|
||||
|
||||
按需阅读:编排任务时优先 `CLI.md`;解析结构化字段时读 `SCHEMA.md`;运行时环境细节见 `../development/RUNTIME.md`。
|
||||
按需阅读:编排任务时优先 `CLI.md`;解析结构化字段时读 `SCHEMA.md`;配置宿主按钮/定时任务/Agent 入口时读 `ACTIONS.md`;运行时环境细节见 `../development/RUNTIME.md`。
|
||||
|
||||
@@ -5,10 +5,27 @@
|
||||
|
||||
## 职责边界
|
||||
|
||||
| 层级 | 负责内容 |
|
||||
|------|----------|
|
||||
| **技能(本仓库)** | `SKILL.md.name` 中文技能名;英文物理表/字段名;`_jiangchang_*` 中文展示元数据;`CREATE TABLE` 字段物理顺序 |
|
||||
| **宿主(匠厂)** | 读取元数据与 PRAGMA 顺序并展示;不猜测业务语义、不按英文字段名重排 |
|
||||
### 技能负责
|
||||
|
||||
- 定义真实 SQLite 表结构
|
||||
- 使用英文 `snake_case` 表名和字段名
|
||||
- 使用 `_jiangchang_tables` 提供表级展示元数据
|
||||
- 使用 `_jiangchang_columns` 提供字段级展示元数据
|
||||
- 定义哪些字段可见、可搜索、可创建、可编辑
|
||||
- 定义字段展示类型和枚举选项
|
||||
- 保证元数据与真实数据库结构一致
|
||||
- 保证元数据初始化幂等
|
||||
|
||||
### 宿主负责
|
||||
|
||||
- 读取 `_jiangchang_*` 元数据
|
||||
- 读取 SQLite `PRAGMA table_info`
|
||||
- 根据 schema 渲染数据管理页面
|
||||
- 根据 `editable` 推导字段是否可创建或编辑
|
||||
- 执行通用查询、新增、编辑、删除、导入、导出
|
||||
- 对字段名、表名、类型和权限进行最终校验
|
||||
- 不猜测技能业务含义
|
||||
- 不根据具体技能名称写特殊逻辑
|
||||
|
||||
SQLite **没有**可靠的 `COMMENT ON TABLE/COLUMN`;SQL 文件里的 `-- 注释` 也不会成为可查询结构。
|
||||
因此中文展示名称必须写入元数据表;字段顺序必须写在 `CREATE TABLE` 的列定义顺序中(`PRAGMA table_info` 的 `cid`)。
|
||||
@@ -27,9 +44,9 @@ metadata:
|
||||
---
|
||||
```
|
||||
|
||||
- `name`:用户可见的中文业务名称(可含品牌,如 `GEO 文章生成`、`1688 联系人采集`)。
|
||||
- `name`:用户可见的中文业务名称。
|
||||
- `description`:能力说明,不是技能名称。
|
||||
- `metadata.openclaw.slug`:机器标识,kebab-case 英文;目录名与默认数据库文件名使用 slug。slug 语义规范见 [`../development/NAMING.md`](../development/NAMING.md);本文件仅描述数据库与 kebab-case 格式。
|
||||
- `metadata.openclaw.slug`:机器标识,kebab-case 英文;目录名与默认数据库文件名使用 slug。slug 语义规范见 [`../development/NAMING.md`](../development/NAMING.md)。
|
||||
- 复制模板后不得将 `your-skill-slug`、`My Skill` 等占位内容作为正式技能发布名称。
|
||||
|
||||
## 数据库路径与命名
|
||||
@@ -38,48 +55,145 @@ metadata:
|
||||
{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/{skill-slug}/{skill-slug}.db
|
||||
```
|
||||
|
||||
- 数据库文件:英文 slug,例如 `scrape-contacts.db`、`account-manager.db`(默认 `{skill-slug}.db`)。
|
||||
- 业务表、字段:**英文 snake_case** 物理名,例如 `task_logs`、`created_at`。
|
||||
- 数据库文件:英文 slug,例如 `your-skill-slug.db`(默认 `{skill-slug}.db`)。
|
||||
- 业务表、字段:**英文 snake_case** 物理名,例如 `demo_items`、`task_logs`、`created_at`。
|
||||
- **禁止**用中文作为 SQLite 真实表名或字段名。
|
||||
|
||||
## 外部来源只读与本地数据可写
|
||||
|
||||
某些技能会从外部系统读取数据并写入技能自己的本地数据库。需要区分:
|
||||
|
||||
```text
|
||||
外部来源数据库:
|
||||
可能只读,不应被修改
|
||||
|
||||
技能本地数据库:
|
||||
可以根据业务语义允许新增、编辑或删除
|
||||
```
|
||||
|
||||
不要把「外部来源只读」错误理解成「技能本地数据库一定只读」。技能通过 `_jiangchang_tables.readonly` 与 `_jiangchang_columns.editable` 声明本地表的实际写权限。
|
||||
|
||||
## 元数据表(宿主兼容)
|
||||
|
||||
宿主读取字段(与 `jiangchang` `metadata-resolver.ts` 一致):
|
||||
宿主读取字段(与匠厂 `metadata-resolver` 一致):
|
||||
|
||||
### `_jiangchang_tables`
|
||||
### `_jiangchang_tables` 表级标准
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `table_name` | 是 | 物理表名 |
|
||||
| `display_name` | 是 | 中文表名(用户可见) |
|
||||
| `table_name` | 是 | 真实英文表名 |
|
||||
| `display_name` | 是 | 用户可见的中文业务名称 |
|
||||
| `description` | 否 | 表说明 |
|
||||
| `sort_order` | 否 | 宿主目录排序;与字段顺序无关 |
|
||||
| `visible` | 是 | `1` 展示 / `0` 隐藏 |
|
||||
| `readonly` | 是 | `1` 只读 / `0` 可写(业务语义) |
|
||||
| `sort_order` | 否 | 兼容保留字段,不用于替代物理字段顺序 |
|
||||
| `visible` | 是 | `1` 在宿主数据管理中展示 / `0` 隐藏 |
|
||||
| `readonly` | 是 | `1` 整张表只读;`0` 允许宿主根据字段权限执行写操作 |
|
||||
|
||||
### `_jiangchang_columns`
|
||||
禁止:
|
||||
|
||||
- 使用中文真实表名
|
||||
- 使用 `_schema_meta` 作为新的正式契约
|
||||
- 只写英文物理名而不写中文 `display_name`
|
||||
- 让元数据引用不存在的表
|
||||
|
||||
### `_jiangchang_columns` 字段级标准
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `table_name` | 是 | 物理表名 |
|
||||
| `column_name` | 是 | 物理字段名 |
|
||||
| `display_name` | 是 | 中文字段名(用户可见) |
|
||||
| `table_name` | 是 | 所属物理表 |
|
||||
| `column_name` | 是 | 真实英文字段名 |
|
||||
| `display_name` | 是 | 用户可见的中文字段名 |
|
||||
| `description` | 否 | 字段说明 |
|
||||
| `display_order` | 否 | **遗留兼容字段;模板写入时固定 NULL,重复初始化会清理历史非空值,不得用于调整展示顺序** |
|
||||
| `visible` | 是 | 是否展示 |
|
||||
| `searchable` | 是 | 是否可搜索 |
|
||||
| `editable` | 是 | 是否可编辑(与宿主权限结合) |
|
||||
| `display_type` | 否 | 如 `text` / `textarea` / `datetime_unix_seconds`(标准时间字段见下文) |
|
||||
| `display_order` | 否 | 兼容字段,默认保持 `NULL` |
|
||||
| `visible` | 是 | 是否在数据管理表格中展示 |
|
||||
| `searchable` | 是 | 是否参与搜索 |
|
||||
| `editable` | 是 | `1` 业务字段允许宿主用于新增和编辑;`0` 系统/只读字段 |
|
||||
| `display_type` | 否 | 字段渲染类型(如 `text`、`textarea`、`datetime_unix_seconds`) |
|
||||
| `options_json` | 否 | 枚举选项 JSON |
|
||||
|
||||
这两张表是**数据字典**,不是业务数据;宿主不会把它们当作普通业务表展示。
|
||||
|
||||
写入应**幂等**(`INSERT … ON CONFLICT DO UPDATE`),数据库升级时同步维护元数据。
|
||||
## editable 与 createable 的关系
|
||||
|
||||
## 业务字段物理顺序
|
||||
技能模板只维护 `editable` 这一份字段权限声明:
|
||||
|
||||
用户在「数据管理」中看到的列顺序 = `CREATE TABLE` 定义顺序 = `PRAGMA table_info` 的 `cid` 顺序。
|
||||
**宿主不会**按英文字段名、`display_order` 或语义规则重排。
|
||||
```text
|
||||
skill metadata:
|
||||
editable
|
||||
|
||||
host runtime:
|
||||
createable / editable
|
||||
```
|
||||
|
||||
宿主根据以下因素计算字段是否能够出现在新增或编辑表单中:
|
||||
|
||||
- 表级 `readonly`
|
||||
- 字段 `editable`
|
||||
- 主键
|
||||
- generated 字段
|
||||
- sensitive 字段
|
||||
- BLOB 类型
|
||||
- not-null 约束
|
||||
- default value
|
||||
|
||||
通用规则:
|
||||
|
||||
```text
|
||||
新增表单:
|
||||
editable = 1
|
||||
且不是主键
|
||||
且不是 generated
|
||||
且不是敏感字段
|
||||
且不是 BLOB
|
||||
|
||||
编辑表单:
|
||||
editable = 1
|
||||
且不是主键
|
||||
且不是 generated
|
||||
且不是敏感字段
|
||||
且不是 BLOB
|
||||
```
|
||||
|
||||
若一张表:
|
||||
|
||||
```text
|
||||
readonly = 0
|
||||
但所有字段 editable = 0
|
||||
```
|
||||
|
||||
则:
|
||||
|
||||
- 这张表技术上可写,但不适合手工新增或编辑
|
||||
- 宿主不应打开空白新增表单
|
||||
- 技能应通过自身业务流程产生数据
|
||||
- 这不是宿主猜测业务,而是技能通过元数据声明的结果
|
||||
|
||||
## 系统字段标准
|
||||
|
||||
通常保持 `editable = 0` 的字段类型包括:
|
||||
|
||||
- 自增主键
|
||||
- generated 字段
|
||||
- `created_at` / `updated_at`
|
||||
- 同步时间戳
|
||||
- 内容哈希
|
||||
- 计算结果
|
||||
- 内部状态
|
||||
- 删除标记
|
||||
- 审计字段
|
||||
- 敏感凭据或密钥字段
|
||||
|
||||
不要把具体业务字段名写死;按字段类型和职责设置 `editable`。
|
||||
|
||||
## 表结构标准
|
||||
|
||||
- 业务表和字段使用英文 `snake_case`
|
||||
- 可写表优先使用单字段主键
|
||||
- 自增主键优先放在 `CREATE TABLE` 第一列
|
||||
- `created_at` 和 `updated_at` 放在业务字段末尾
|
||||
- 字段展示顺序以 `CREATE TABLE` 和 `PRAGMA table_info(cid)` 为准
|
||||
- 不依赖 `display_order` 重新排列字段
|
||||
- 不要让宿主通过英文字段名推断展示顺序
|
||||
- 复杂字段需要通过 `display_type` 或 `visible` 明确处理
|
||||
|
||||
推荐顺序(可按业务裁剪,但已有字段应遵守相对位置):
|
||||
|
||||
@@ -90,6 +204,7 @@ metadata:
|
||||
4. 状态、结果、错误等辅助字段
|
||||
5. created_at(如有)
|
||||
6. updated_at(如有)
|
||||
```
|
||||
|
||||
## 标准时间字段(新技能统一规范)
|
||||
|
||||
@@ -101,7 +216,7 @@ metadata:
|
||||
| 存储格式 | Unix 秒级整数 |
|
||||
| 展示元数据 `display_type` | `datetime_unix_seconds` |
|
||||
| 中文名 | `created_at` → **创建时间**;`updated_at` → **更新时间** |
|
||||
| 用户编辑 | `editable = 0`(系统字段,宿主只展示格式化结果,不写回字符串) |
|
||||
| 用户编辑 | `editable = 0`(系统字段,宿主只展示格式化结果) |
|
||||
| 字段顺序 | 位于业务字段末尾:`… → created_at → updated_at` |
|
||||
| 排序 | **不使用** `display_order`;顺序仅来自 `PRAGMA table_info` |
|
||||
|
||||
@@ -109,7 +224,7 @@ metadata:
|
||||
|
||||
- **created_at**:`INTEGER NOT NULL DEFAULT (unixepoch())`;插入时可省略,由数据库生成。
|
||||
- **updated_at**:`INTEGER NOT NULL DEFAULT (unixepoch())`;插入时同样可省略。
|
||||
- **updated_at 更新**:模板默认表 `task_logs` 通过 SQLite trigger `{table}_set_updated_at` 在业务字段更新后自动刷新;若技能所有 UPDATE 都经过统一 repository,也可在 repository 层设置 `updated_at = unixepoch()`,**不要**叠加两套机制。
|
||||
- **updated_at 更新**:模板默认表 `task_logs` 通过 SQLite trigger `{table}_set_updated_at` 在业务字段更新后自动刷新。
|
||||
|
||||
实现参考:
|
||||
|
||||
@@ -117,9 +232,7 @@ metadata:
|
||||
- 中文元数据种子:`scripts/db/display_metadata.py`
|
||||
- 自检:`scripts/db/display_metadata_validator.py`
|
||||
|
||||
宿主(匠厂)只负责把 `display_type = datetime_unix_seconds` 格式化为 `YYYY-MM-DD HH:mm:ss` 展示,**不修改**数据库原始值。
|
||||
|
||||
> `datetime_unix_milliseconds`、`datetime_iso` 是宿主兼容能力,**不是**新技能模板推荐标准。
|
||||
宿主只负责把 `display_type = datetime_unix_seconds` 格式化为 `YYYY-MM-DD HH:mm:ss` 展示,**不修改**数据库原始值。
|
||||
|
||||
### 模板默认:`task_logs`
|
||||
|
||||
@@ -140,33 +253,79 @@ CREATE TABLE IF NOT EXISTS task_logs (
|
||||
);
|
||||
```
|
||||
|
||||
插入时可省略 `created_at`、`updated_at`;`updated_at` 在 UPDATE 时由 trigger `task_logs_set_updated_at` 自动维护(见 `scripts/db/timestamp_columns.py`)。
|
||||
|
||||
对应中文展示(由 `init_db()` 写入元数据表):
|
||||
|
||||
| 物理字段 | 中文名 |
|
||||
|----------|--------|
|
||||
| id | 编号 |
|
||||
| task_type | 任务类型 |
|
||||
| target_id | 目标编号 |
|
||||
| input_id | 输入编号 |
|
||||
| input_title | 输入标题 |
|
||||
| status | 状态 |
|
||||
| error_msg | 错误信息 |
|
||||
| result_summary | 结果摘要 |
|
||||
| created_at | 创建时间(`display_type = datetime_unix_seconds`,不可编辑) |
|
||||
| updated_at | 更新时间(`display_type = datetime_unix_seconds`,不可编辑) |
|
||||
| 物理字段 | 中文名 | editable |
|
||||
|----------|--------|----------|
|
||||
| id | 编号 | 0 |
|
||||
| task_type | 任务类型 | 1 |
|
||||
| target_id | 目标编号 | 1 |
|
||||
| input_id | 输入编号 | 1 |
|
||||
| input_title | 输入标题 | 1 |
|
||||
| status | 状态 | 1 |
|
||||
| error_msg | 错误信息 | 1 |
|
||||
| result_summary | 结果摘要 | 1 |
|
||||
| created_at | 创建时间 | 0 |
|
||||
| updated_at | 更新时间 | 0 |
|
||||
|
||||
表中文名:**任务日志**。
|
||||
表中文名:**任务日志**;表级 `readonly = 0`。
|
||||
|
||||
禁止事项:
|
||||
### 通用示例:`demo_items`(测试 fixture 参考)
|
||||
|
||||
- 不要把 `created_at` 放在第一列;
|
||||
- 不要把 `id` 随意放在中间;
|
||||
- 不要指望宿主按英文字段名排序;
|
||||
- 若需调整历史表字段顺序,应通过规范迁移**重建表**,而不是在宿主侧配置掩盖。
|
||||
以下表结构用于模板测试演示数据管理契约,**不是**模板默认业务表:
|
||||
|
||||
复合主键或特殊表结构,请在本文档或技能自有 SCHEMA 补充中说明例外。
|
||||
```sql
|
||||
CREATE TABLE demo_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'draft',
|
||||
generated_value TEXT,
|
||||
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
||||
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
||||
);
|
||||
```
|
||||
|
||||
对应元数据要点:
|
||||
|
||||
| 物理字段 | editable | 说明 |
|
||||
|----------|----------|------|
|
||||
| id | 0 | 自增主键 |
|
||||
| title | 1 | 业务字段 |
|
||||
| description | 1 | 业务字段 |
|
||||
| status | 1 | 枚举,`options_json` 演示 |
|
||||
| generated_value | 0 | 系统/计算字段 |
|
||||
| created_at | 0 | 系统时间 |
|
||||
| updated_at | 0 | 系统时间 |
|
||||
|
||||
## 枚举字段 options_json
|
||||
|
||||
`options_json` 为 JSON 数组,每项包含 `value` 与 `label`:
|
||||
|
||||
```json
|
||||
[
|
||||
{"value": "draft", "label": "草稿"},
|
||||
{"value": "published", "label": "已发布"},
|
||||
{"value": "archived", "label": "已归档"}
|
||||
]
|
||||
```
|
||||
|
||||
宿主据此渲染选择框;技能侧负责保证 JSON 合法且与物理字段取值一致。
|
||||
|
||||
## 幂等初始化标准
|
||||
|
||||
- `_jiangchang_tables` 和 `_jiangchang_columns` 必须通过 upsert 初始化
|
||||
- 多次执行初始化不能重复记录
|
||||
- 重新初始化可以更新展示名、描述、`visible`、`searchable`、`editable`、`display_type`、`options_json`
|
||||
- 元数据不能残留旧字段(删除或重命名字段时必须同步清理)
|
||||
- 元数据不能引用不存在的表或字段
|
||||
- 新增字段或表时必须同步增加元数据
|
||||
- 不要直接修改用户真实数据库作为迁移方式
|
||||
|
||||
实现 helper:
|
||||
|
||||
- `upsert_table_metadata` / `upsert_column_metadata` — 幂等写入
|
||||
- `prune_stale_column_metadata` — 清理已删除物理字段的元数据
|
||||
|
||||
## 中文命名质量
|
||||
|
||||
@@ -188,17 +347,19 @@ CREATE TABLE IF NOT EXISTS task_logs (
|
||||
|----------|-----------|-----------|----------|
|
||||
| 发布类 | publish | 账号 ID | 内容 ID |
|
||||
| 工资代发 | disburse | 付款账户 | 批次 ID |
|
||||
| 对账 | reconcile | 银行/平台 | 对账批次 ID |
|
||||
| 对账 | reconcile | 平台标识 | 对账批次 ID |
|
||||
| 发票验真 | verify | 税务地区 | 发票批次 ID |
|
||||
|
||||
业务特有字段优先放入 `result_summary`(JSON 字符串),避免随意加列;若确需新列,必须同步元数据并保持合理物理顺序。
|
||||
|
||||
## 开发自检
|
||||
|
||||
- `init_db()` 后运行 `tests/test_display_metadata.py`。
|
||||
- `init_db()` 后运行 `tests/test_display_metadata.py` 与 `tests/test_data_management_contract.py`。
|
||||
- 若提供宿主 Action 入口,运行 `tests/test_actions_manifest.py`。
|
||||
- 复制为真实技能后,使用 `scripts/db/display_metadata_validator.py` 中的校验函数检查 SKILL 名称、slug 与元数据完整性。
|
||||
|
||||
## 模板原则
|
||||
|
||||
- 模板不做复杂历史迁移框架;新 skill 从当前 schema 起步。
|
||||
- 元数据 DDL 与 `task_logs` 中文种子以 `scripts/db/display_metadata.py` 为单一权威来源。
|
||||
- 模板定义「如何声明能力」;具体技能定义「声明什么业务能力」;宿主负责「如何通用渲染和执行」。
|
||||
|
||||
Reference in New Issue
Block a user