draftgo-cli 4.0.1 → 4.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +87 -11
  2. package/package.json +9 -4
  3. package/resources/custom-service-sdk/ai.go +520 -0
  4. package/resources/custom-service-sdk/ai_test.go +156 -0
  5. package/resources/custom-service-sdk/auth_test.go +56 -0
  6. package/resources/custom-service-sdk/billing.go +596 -0
  7. package/resources/custom-service-sdk/billing_test.go +150 -0
  8. package/resources/custom-service-sdk/go.mod +3 -0
  9. package/resources/custom-service-sdk/manifest.json +77 -0
  10. package/resources/custom-service-sdk/platform.go +345 -0
  11. package/resources/custom-service-sdk/platform_logger_test.go +24 -0
  12. package/resources/custom-service-sdk/registration_test.go +39 -0
  13. package/resources/custom-service-sdk/resources.go +246 -0
  14. package/resources/custom-service-sdk/resources_billing_test.go +115 -0
  15. package/resources/custom-service-sdk/resources_files_test.go +57 -0
  16. package/resources/custom-service-sdk/resources_scope_test.go +87 -0
  17. package/resources/custom-service-sdk/sdk.go +208 -0
  18. package/resources/skill/SKILL.md +36 -88
  19. package/resources/skill/init/SKILL.md +4 -4
  20. package/resources/skill/manifest.json +5 -1
  21. package/resources/skill/references/aihub.md +25 -2
  22. package/resources/skill/references/app-api.md +56 -6
  23. package/resources/skill/references/architecture.md +2 -2
  24. package/resources/skill/references/chat-sdk.md +4 -2
  25. package/resources/skill/references/checkout.md +17 -3
  26. package/resources/skill/references/custom-services.md +112 -47
  27. package/resources/skill/references/data.md +19 -4
  28. package/resources/skill/references/delivery.md +33 -0
  29. package/resources/skill/references/diagnostics.md +51 -0
  30. package/resources/skill/references/frontend.md +34 -46
  31. package/resources/skill/references/mcp.md +33 -5
  32. package/resources/skill/references/methods.md +189 -0
  33. package/resources/skill/references/modules.md +37 -9
  34. package/resources/skill/references/runtime.md +23 -1
  35. package/src/cli.js +24 -0
  36. package/src/commandRegistry.js +9 -1
  37. package/src/commands/api.js +21 -10
  38. package/src/commands/apiKey.js +34 -0
  39. package/src/commands/capabilities.js +93 -0
  40. package/src/commands/checkout.js +1 -1
  41. package/src/commands/commit.js +1 -1
  42. package/src/commands/components.js +550 -0
  43. package/src/commands/conflict.js +1 -1
  44. package/src/commands/connect.js +18 -8
  45. package/src/commands/customService.js +20 -4
  46. package/src/commands/dataRange.js +33 -0
  47. package/src/commands/delete.js +12 -1
  48. package/src/commands/diff.js +18 -2
  49. package/src/commands/grant.js +29 -0
  50. package/src/commands/group.js +38 -0
  51. package/src/commands/help.js +64 -20
  52. package/src/commands/init.js +3 -3
  53. package/src/commands/map.js +145 -17
  54. package/src/commands/mcp.js +2 -2
  55. package/src/commands/reconcile.js +1 -1
  56. package/src/commands/role.js +32 -0
  57. package/src/commands/space.js +41 -0
  58. package/src/commands/status.js +110 -7
  59. package/src/commands/update.js +23 -11
  60. package/src/commands/verify.js +75 -0
  61. package/src/commands/worklog.js +6 -2
  62. package/src/consoleEncoding.js +34 -0
  63. package/src/contractCompatibility.js +57 -0
  64. package/src/customServices.js +138 -18
  65. package/src/diffReport.js +106 -0
  66. package/src/index.js +2 -0
  67. package/src/localRuntime/compose.js +14 -17
  68. package/src/localRuntime/index.js +22 -23
  69. package/src/localRuntime/services.js +27 -36
  70. package/src/mcp/client.js +11 -2
  71. package/src/mcp/protocol.js +22 -2
  72. package/src/mcp/tools.js +14 -1
  73. package/src/platforms.js +9 -0
  74. package/src/projectConfig.js +6 -4
  75. package/src/releaseInstall.js +105 -0
  76. package/src/updateCheck.js +48 -28
  77. package/src/worklog.js +2 -1
  78. package/src/worktree/backend.js +1 -1
  79. package/src/worktree/index.js +7 -2
@@ -1,26 +1,40 @@
1
1
  ---
2
- read_when: 编写、修改、调试或评审自定义服务时;使用服务 SDK、路由、事件、定时任务或服务依赖时
2
+ read_when: 编写、修改、试运行、发布或评审自定义服务时;使用服务 SDK、Route、Event、Scheduled handler 或服务依赖时
3
3
  ---
4
4
 
5
5
  # Go 自定义服务契约
6
6
 
7
- 自定义服务是完整的 Go `package main`。平台构建源码和 `go.mod`/`go.sum`,执行 `Register` 保存触发器清单,并在独立子进程中运行 handler。SDK 固定导入 `draftgo/sdk`;它由构建器注入,不写进 `require` 或 `replace`。
7
+ 自定义服务是完整的 Go `package main`。平台从源码生成并锁定依赖,执行 `Register` 保存触发器清单,并在独立子进程中运行 handler。SDK 固定导入 `draftgo/sdk`,由构建器注入。
8
8
 
9
- ## 开发流程
9
+ ## 最短流程
10
10
 
11
- 完整正文使用:
11
+ 先通过 MCP resource/API operation 定位或创建服务并取得 ID;operation schema 以实时 describe 为准。完整正文只走两文件 worktree:
12
12
 
13
13
  ```bash
14
14
  draftgo checkout custom-services <id...>
15
+ draftgo diff custom-services <id>
15
16
  draftgo commit custom-services <id...>
16
17
  draftgo validate custom-services <id>
17
- draftgo test custom-services <id> [--handler route:POST:/path]
18
+ draftgo test custom-services <id> --source draft --handler route:POST:/path --input request.json
18
19
  draftgo publish custom-services <id...>
19
20
  ```
20
21
 
21
- checkout 目录包含 `service.go`、`go.mod`、`go.sum`、`service.json` 及对应 base。commit 只保存共享 cloud draft;publish 才切换线上版本。定位、创建、权限和结构化元数据通过 MCP 实时 operation 完成,创建后取得 ID 再 checkout。
22
+ `commit custom-services` 是一体化交付入口,会依次完成 commit、validate 和 publish,并在成功后启用线上版本。`publish custom-services` 仍保留为兼容入口;`validate` `test` 仍会先 commit 当前 worktree。不同服务可并发,同一服务保持 edit -> diff -> commit 顺序。
22
23
 
23
- 不同服务可并发处理;同一服务保持 commit -> validate -> test/publish 顺序。草稿 revision 是内容版本,`validated_revision` / `validated_hash` 是该版本的验证凭证。保存会清空凭证;测试和发布必须使用当前 revision。CLI 会复用有效凭证,不重复 commit、checkout validate
24
+ `test` 默认执行 cloud draft;`--source published` 直接测试线上版本且不会提交本地改动,`--source auto` 按生命周期选择。草稿 revision 是内容版本,`validated_revision` / `validated_hash` 绑定源码、依赖、SDK Runner 协议;保存会使旧凭证失效。Runner/SDK 变化导致 `validation_stale` 时,publish 只自动重新 validate 一次;revision 冲突直接停止。
25
+
26
+ ## Worktree
27
+
28
+ | 文件 | 用法 |
29
+ |---|---|
30
+ | `service.go` | 完整 `package main`;在 `Register` 中声明 handler |
31
+ | `service.json` | 服务元数据;以实时 checkout/API schema 标出的可编辑字段为准 |
32
+
33
+ 两个文件都必须保留。`service.json` 中的 `schema_version`、`id`、`revision`、`validation_status`、`validated_revision`、`validated_hash` 是服务端状态,不手工伪造;`Register` 是 Route/Event/Scheduled handler 的唯一事实来源,不在元数据中维护触发器或运行模式。
34
+
35
+ CLI 只支持当前 schema v2 的 `service.go`/`service.json` worktree。旧四文件或 schema v1 会明确拒绝;删除旧 worktree 后重新执行 checkout 即可。
36
+
37
+ SDK 固定导入 `draftgo/sdk`。第三方依赖在 `service.go` 顶部声明 `//draftgo:require github.com/google/uuid@v1.6.0`;必须固定显式版本,禁止 floating version、本地路径与自定义 replace。CLI 会从随包发布的 SDK 快照生成 `go.mod/go.sum`、`draftgo_local_main.go` 与 `.draftgo-sdk/`,仅供 gopls 和本地 `go build`;这些带托管标记的文件会自动刷新,不能手工维护,也不会上传。服务端仍独立生成并锁定实际运行依赖。
24
38
 
25
39
  ## 最小服务
26
40
 
@@ -31,19 +45,14 @@ import "draftgo/sdk"
31
45
 
32
46
  func Register(app *sdk.App) {
33
47
  app.Route("GET", "/health", health)
34
- app.On("order.paid", afterPaid)
35
- app.Schedule("0 9 * * 1-5", weekdayReport)
36
48
  }
37
49
 
38
- func health(draftgo *sdk.Context) (any, error) {
39
- return draftgo.Respond(map[string]any{"ok": true}, 200, nil), nil
50
+ func health(ctx *sdk.Context) (any, error) {
51
+ return ctx.Respond(map[string]any{"ok": true}, 200, nil), nil
40
52
  }
41
-
42
- func afterPaid(draftgo *sdk.Context) (any, error) { return nil, nil }
43
- func weekdayReport(draftgo *sdk.Context) (any, error) { return nil, nil }
44
53
  ```
45
54
 
46
- `Register` 只注册 handler,不访问网络、数据库或通知系统。新服务使用 `mode=mixed`;第三方依赖锁定明确版本并写入 `go.mod`,可选校验和写入 `go.sum`。
55
+ `Register` 只注册 handler,不访问网络、数据库或通知系统。平台在 validate 时执行它并自动记录 handler。
47
56
 
48
57
  ## 触发器
49
58
 
@@ -51,9 +60,9 @@ func weekdayReport(draftgo *sdk.Context) (any, error) { return nil, nil }
51
60
 
52
61
  `app.Route("POST", "/orders", createOrder)` 在 `slug=commerce` 时对应 `POST /api/x/commerce/orders`。Route 精确匹配,不支持 `/orders/{id}` 模板;ID 使用 query 或 body。
53
62
 
54
- 输入字段为 `method`、`headers`、`body`、`query_params`、`path_params`。身份由 `draftgo.Auth.CurrentUser()` 获取。普通 `draftgo.DB`、`Users` 等调用继承请求调用者权限;管理员创建服务、持有 SAT 或 `RequireAdmin` 都不会自动提升 SDK 调用。
63
+ 输入字段为 `method`、`headers`、`body`、`query_params`、`path_params`。身份由 `ctx.Auth.CurrentUser()` 获取。普通 `ctx.DB`、`ctx.Users`、`ctx.Billing` 等调用继承请求调用者权限;管理员创建服务、持有服务凭据或 `RequireAdmin` 都不会自动提升 SDK 调用。
55
64
 
56
- 可信服务需要管理员能力时逐次显式调用 `draftgo.Admin.*`。它只提升该次 RPC,并审计服务、版本、真实调用者、操作、资源和结果;服务代码拿不到 SAT、数据库连接或管理员凭据。Route 返回值仍需自行脱敏。
65
+ `ctx.Admin.*` 是自定义服务显式选择的单次系统内部授权:该次 RPC 按 `*:*:all` 全权限执行,可跨用户/空间,不检查调用者或服务主体 AccessGrant;服务主体仅保留用于 ownership 与审计。每次调用都会进入审计,内部授权不会泄漏到后续普通调用。服务代码仍拿不到服务凭据、数据库连接或管理员凭据。公开 Route 不应无条件调用 Admin;先完成业务鉴权、参数校验和幂等设计,返回值仍需自行脱敏。
57
66
 
58
67
  ### Event
59
68
 
@@ -61,7 +70,21 @@ func weekdayReport(draftgo *sdk.Context) (any, error) { return nil, nil }
61
70
 
62
71
  ### Scheduled
63
72
 
64
- `app.Schedule("0 2 * * *", cleanup)` 使用五字段 cron,也支持 `interval:5m`。定时任务没有调用者,以系统身份执行;仅可信编辑者可维护,并应限制写入范围、记录业务日志。
73
+ `app.Schedule("0 2 * * *", cleanup)` 使用五字段 cron,也支持 `interval:5m`。定时任务没有用户调用者;执行空间来自服务持久化的 ResourceOwnership,服务 principal 还必须有覆盖目标资源的 AccessGrant。运行时不会猜测用户或回退到 platform。
74
+
75
+ ## 试运行
76
+
77
+ ```bash
78
+ # Route;request.json 是 handler input object
79
+ draftgo test custom-services 12 --source draft --handler route:POST:/orders --input request.json
80
+
81
+ # Event / Scheduled / 直接 handler 名
82
+ draftgo test custom-services 12 --handler event:order.paid --input event.json
83
+ draftgo test custom-services 12 --handler scheduled:weekday-report
84
+ draftgo test custom-services 12 --handler health
85
+ ```
86
+
87
+ `--source draft` 是默认值,会提交并验证当前工作树草稿;`--source published` 直接试运行已发布版本,不提交本地改动;`auto` 由服务生命周期决定。`--headers headers.json` 与 `--user user.json` 注入测试上下文,文件必须是 UTF-8 JSON object。默认 `--side-effect-policy deny`:外部 HTTP、通知和 AI 调用会失败;用 `mock` 返回模拟结果。只有用户明确要求真实副作用时才使用 `--side-effect-policy live --test-write`。数据库等 SDK 写操作同样必须显式 `--test-write`。试运行结果包含 execution ID、来源 revision、状态、输出、HTTP 状态/响应头、日志和 SDK operation 摘要。
65
88
 
66
89
  ## SDK
67
90
 
@@ -69,55 +92,96 @@ func weekdayReport(draftgo *sdk.Context) (any, error) { return nil, nil }
69
92
 
70
93
  | 入口 | 核心能力 |
71
94
  |---|---|
72
- | `draftgo.DB` | Create/CreateMany/Get/Update/UpdateMany/Delete/Query |
73
- | `draftgo.Users` | Get/List/Update |
74
- | `draftgo.Auth` | RequireLogin/RequireAdmin/RequireRole/CurrentUser |
75
- | `draftgo.Notify` | 站内通知 |
76
- | `draftgo.HTTP` | Get/Post/Put/Patch/Delete |
77
- | `draftgo.Cache` / `Config` | 缓存与系统配置 |
78
- | `draftgo.AIHub` | Agent/模型推理、图片、Embedding、AI 资产与运行记录 |
79
- | `draftgo.Knowledge` | 知识库、文档、Chunk、上传、检索和重建 |
80
- | `draftgo.Memory` | 长期记忆与全局检索配置 |
95
+ | `ctx.DB` | Create/CreateMany/Get/Update/UpdateMany/Delete/Query |
96
+ | `ctx.Users` | Get/List/Update |
97
+ | `ctx.Auth` | RequireLogin/RequireAdmin/RequireRole/CurrentUser |
98
+ | `ctx.Notify` | 站内通知 |
99
+ | `ctx.HTTP` | Get/Post/Put/Patch/Delete |
100
+ | `ctx.Cache` / `Config` | 缓存与系统配置 |
101
+ | `ctx.AIHub` | Agent/模型推理、图片、Embedding、AI 资产与运行记录 |
102
+ | `ctx.Knowledge` | 知识库、文档、Chunk、上传、检索和重建 |
103
+ | `ctx.Memory` | 长期记忆与全局检索配置 |
104
+ | `ctx.Files` | 文件夹、资产上传/下载、绑定、回收站和恢复 |
105
+ | `ctx.Scope` | 当前 platform/space、principal 与 ResourceOwnership 授权检查 |
106
+ | `ctx.Billing` | 账本、权益、支付、套餐、订阅和 AI 计费;所有写操作按实时权限与风险契约执行 |
81
107
 
82
108
  常用示例:
83
109
 
84
110
  ```go
85
- records, err := draftgo.DB.Query("order", sdk.QueryOptions{
111
+ records, err := ctx.DB.Query("order", sdk.QueryOptions{
86
112
  Filters: map[string]any{"status": "paid"}, Page: 1, PageSize: 20,
87
113
  })
88
- reply, err := draftgo.AIHub.Chat(draftgo.Context(), sdk.AIChatRequest{
114
+ reply, err := ctx.AIHub.Chat(ctx.Context(), sdk.AIChatRequest{
89
115
  AgentID: 12, Message: "总结订单",
90
116
  })
91
- response, err := draftgo.HTTP.Get(draftgo.Context(), "https://api.example.com/health", nil, 10*time.Second)
117
+ response, err := ctx.HTTP.Get(ctx.Context(), "https://api.example.com/health", nil, 10*time.Second)
92
118
  ```
93
119
 
94
- HTTP host 可由 `config.http_allowed_hosts` 限制;timeout 最终为 1-30 秒,响应体最大 5 MB。日志每次执行最多 500 条、单条 4096 字符,不记录 token、Cookie、密码或完整个人信息。
120
+ 精确签名以 checkout 后自动生成的 `.draftgo-sdk/billing.go` 为准;该文件由 CLI 同步当前 SDK,只读不改。不要猜方法名、字段或直接调用账务 HTTP API。
95
121
 
96
- ### AI 权限
122
+ ### Billing 决策与用法
123
+
124
+ 需要余额、退款、权益、套餐或订阅时使用 `ctx.Billing` / `ctx.Admin.Billing`,不得用动态 DB、缓存或自行维护余额重建金钱状态。金额统一使用最小货币单位:人民币 `AmountMinor: 990` 表示 9.90 元。
97
125
 
98
- 普通 AIHub/Knowledge/Memory 继承用户身份并经过 `aihub:*` 等权限。`draftgo.Admin.AIHub`、`Admin.Knowledge`、`Admin.Memory` 与普通入口同构,但逐次以管理员执行并审计。
126
+ | 场景 | 方法 |
127
+ |---|---|
128
+ | 当前调用者操作服务归属内账务 | `ctx.Billing.*` |
129
+ | 自定义服务执行系统级账务管理 | `ctx.Admin.Billing.*`;单次调用按系统全权限执行并审计 |
130
+ | 金额已确定且应立即扣除 | `DebitAccount` |
131
+ | 最终金额不确定或业务可能失败 | `HoldFunds` -> `SettleHold`;失败时 `ReleaseHold` |
132
+ | 更正已入账流水 | `ReverseJournal`,不要用反向充值伪造冲正 |
133
+ | 次数、额度或功能许可 | `ConsumeEntitlement`,不要混用钱包余额 |
134
+ | 三方支付退款 | `RefundPaymentOrder` |
99
135
 
100
- 普通推理还必须在服务配置中启用:
136
+ 直接扣款示例:
101
137
 
102
- ```json
103
- {
104
- "aihub": {
105
- "enabled": true,
106
- "allowed_agents": [12],
107
- "allow_direct_model_call": true,
108
- "allowed_models": ["gpt-4.1-mini"],
109
- "allow_images": true
110
- }
138
+ ```go
139
+ result, err := ctx.Billing.DebitAccount(ctx.Context(), sdk.MoneyOperationRequest{
140
+ AmountMinor: 990,
141
+ Reference: "order:20260829-001",
142
+ Reason: "购买专业版功能",
143
+ IdempotencyKey: "order:20260829-001:debit",
144
+ })
145
+ if err != nil {
146
+ return ctx.Respond(map[string]any{"error": "扣款失败"}, 409, nil), nil
111
147
  }
148
+ return ctx.Respond(map[string]any{
149
+ "journal_id": result.JournalID,
150
+ "balance_minor": result.BalanceMinor,
151
+ }, 200, nil), nil
152
+ ```
153
+
154
+ 每个金额写操作都必须使用可持久复用、业务唯一的 `IdempotencyKey`,推荐 `{业务类型}:{业务ID}:{动作}`;不得使用时间戳或每次重试生成的新 UUID。相同 key 的相同请求安全重试;同一 key 改变目标或金额会发生幂等冲突。余额不足时操作失败且不会产生负余额。
155
+
156
+ 预授权流程必须为 `HoldFunds` -> `SettleHold` / `ReleaseHold`,三个动作分别使用稳定幂等键,并持久化返回的 `HoldID`。不确定远端调用是否已成功时,先按业务 ID 或流水回读,不自动换 key 重扣。日志只能记录业务引用、`JournalID` / `HoldID` 和脱敏错误,不记录完整用户资料或支付凭据。
157
+
158
+ 试运行真实账务写入必须显式执行:
159
+
160
+ ```bash
161
+ draftgo test custom-services 12 --source draft --handler route:POST:/charge --input request.json --side-effect-policy live --test-write
112
162
  ```
113
163
 
114
- 空白名单表示不额外限制,不会绕过用户权限、Agent 调用权限或模型外部调用策略。typed helper 未覆盖的新端点可使用 `AIHub.Request`,但 path 只能位于平台允许的 AI/Knowledge/Memory 前缀,不能传外部 URL、路径穿越或内嵌 query。
164
+ 只验证编译与路由时不要开启真实写入。涉及金额的测试使用专门测试账户、最小金额和唯一业务 ID,完成后回读余额与流水;禁止在生产用户账户上试扣。
165
+
166
+ HTTP host 可由 `config.http_allowed_hosts` 限制;timeout 最终为 1-30 秒,响应体最大 5 MB。日志每次执行最多 500 条、单条 4096 字符,不记录 token、Cookie、密码或完整个人信息。
167
+
168
+ ### AI 权限
169
+
170
+ 普通 AIHub、Knowledge、Memory 使用调用者与服务 Grant 的权限交集。AIHub 使用 `aihub:*`,Knowledge 独立使用 `knowledge:*`;两组权限互不包含。显式 `ctx.Admin.AIHub`、`ctx.Admin.Knowledge`、`ctx.Admin.Memory` 对单次可信服务调用启用管理提升并写入审计。
171
+
172
+ 服务不再配置 AI 启用开关、图片开关、直接模型调用开关、Agent 白名单或模型白名单;`config.aihub` 会被拒绝。Agent 与模型是否可调用直接跟随 AI 板块自身配置。普通调用按调用者与服务 Grant 的交集鉴权;只有源码中显式选择的 `ctx.Admin.*` 才启用单次可信管理提升。
173
+
174
+ typed helper 未覆盖的新端点可使用 `ctx.AIHub.Request`,但 path 只能位于平台允许的 AI/Knowledge/Memory 前缀,不能传外部 URL、路径穿越或内嵌 query。
115
175
 
116
176
  ## 权限与运行
117
177
 
118
178
  - `scripts:read/create/update/delete/execute` 控制服务管理。
119
- - Route 仍受服务 `permission` `config.route_security` 控制。
120
- - 只有显式 `draftgo.Admin.*`、定时任务和无可解析用户的事件是提升身份例外。
179
+ - Role 不带作用域;服务必须通过覆盖持久化 ResourceOwnership 的有效 AccessGrant 授权。工作区成员关系不能单独授权。
180
+ - platform Grant 可跨空间但只能使用显式权限;space Grant 不能跨根。请求中的范围不能覆盖服务已保存的归属。
181
+ - 普通服务调用访问动态 DB 时仍受目标 DB 的 DataRange(`none` / `own` / `all`)限制;`ctx.Admin.*` 只应用于源码明确选择的单次可信管理操作,不能从请求参数隐式开启。
182
+ - Route 不接受服务级 `permission`;入口由宿主认证、服务 ownership 和调用者 `scripts:execute` AccessGrant 控制,业务级公开/登录规则在 handler 内显式实现。
183
+ - 定时任务和无可解析用户的事件默认使用服务主体及其持久化空间;需要平台级或跨归属管理时必须在对应单次调用显式使用 `ctx.Admin.*`。
184
+ - 服务 principal 由平台运行时注入;不要在 `service.json`、源码、测试参数或日志中保存/模拟服务身份凭据。Route/Event 取调用者与服务 Grant 的权限交集,Scheduled 使用服务持久化 ownership,而不是假造用户 API Key。
121
185
  - `config.timeout`、`max_concurrency`、`queue_timeout_ms` 控制执行;Route 饱和返回 429。
122
186
  - 超时会终止独立子进程。运行器不是不可信多租户安全沙箱,只授予可信编辑者服务权限。
123
187
  - 构建键覆盖源码、依赖、SDK 和 Runner 协议;有效验证凭证绑定该键,任一部分变化都必须重新验证。
@@ -131,6 +195,7 @@ HTTP host 可由 `config.http_allowed_hosts` 限制;timeout 最终为 1-30 秒
131
195
  ## 完成条件
132
196
 
133
197
  - `package main` 且实现无业务副作用的 `Register(app *sdk.App)`。
198
+ - `service.go`、`service.json` 齐全,handler 仅在 `Register` 注册,服务端状态字段未被手工伪造。
134
199
  - trigger 与 handler 签名正确,第三方依赖已锁定。
135
200
  - Route 权限、管理员调用和返回脱敏符合真实调用者范围。
136
- - `draftgo validate` 通过;需要运行行为证据时执行相关 `draftgo test`。发布仅在用户任务包含发布时进行。
201
+ - `draftgo commit custom-services` 成功并显示 published;需要运行行为证据时执行相关 `draftgo test`。
@@ -4,6 +4,21 @@ read_when: 操作动态 DB 之前 · 设计数据结构时 · 使用 filters 检
4
4
 
5
5
  # 动态 DB & 数据层
6
6
 
7
+ ## 最短管理流程
8
+
9
+ 结构和记录都走实时 API 契约,不 checkout:
10
+
11
+ ```bash
12
+ draftgo api search "db meta"
13
+ draftgo api describe <operation_id>
14
+ draftgo api call <operation_id> --input request.json --output json
15
+ draftgo api search "dynamic db record"
16
+ ```
17
+
18
+ 创建或修改 schema 后,先回读目标 `type`,再调用记录 operation 验证最小 CRUD;不要把管理端 `db_meta` operation 与页面运行时的 `App.get/post/put/delete('db/...')` 混用。失败时优先核对 describe 的字段容器、`searchable`、权限、记录 owner 和分页,而不是猜静态路径。
19
+
20
+ 完成条件:schema 可按 `type` 回读,目标角色的最小 CRUD 与筛选行为通过;批量写入还要验证失败时整批回滚。
21
+
7
22
  ## DB Meta 结构
8
23
 
9
24
  ```json
@@ -46,12 +61,12 @@ read_when: 操作动态 DB 之前 · 设计数据结构时 · 使用 filters 检
46
61
 
47
62
  ---
48
63
 
49
- ## 自定义服务内的 draftgo.DB.Query
64
+ ## 自定义服务内的 ctx.DB.Query
50
65
 
51
- Go 自定义服务使用 `draftgo.DB.Query(type, sdk.QueryOptions{...})` 操作动态 DB,返回 `sdk.QueryResult`:
66
+ Go 自定义服务使用 `ctx.DB.Query(type, sdk.QueryOptions{...})` 操作动态 DB,返回 `sdk.QueryResult`:
52
67
 
53
68
  ```go
54
- result, err := draftgo.DB.Query("order", sdk.QueryOptions{
69
+ result, err := ctx.DB.Query("order", sdk.QueryOptions{
55
70
  Filters: map[string]any{"status": "paid"},
56
71
  Page: 1, PageSize: 20, OrderBy: "id", Order: "desc",
57
72
  })
@@ -71,7 +86,7 @@ items := result.Items
71
86
  `filters` 操作符示例:
72
87
 
73
88
  ```go
74
- draftgo.DB.Query("order", sdk.QueryOptions{Filters: map[string]any{
89
+ ctx.DB.Query("order", sdk.QueryOptions{Filters: map[string]any{
75
90
  "status": "paid",
76
91
  "customer_name": map[string]any{"op": "like", "value": "张"},
77
92
  "amount": map[string]any{"op": "gte", "value": 100},
@@ -0,0 +1,33 @@
1
+ ---
2
+ read_when: 准备验证、提交、发布、交付或标记工作项完成时
3
+ ---
4
+
5
+ # 交付验收
6
+
7
+ 先按资源类型选择唯一交付链,不把“本地验证通过”写成“已发布”。
8
+
9
+ ## 长正文
10
+
11
+ ```bash
12
+ draftgo diff pages 42 --stat
13
+ draftgo verify pages 42
14
+ draftgo commit pages 42
15
+ draftgo check --remote --output json
16
+ ```
17
+
18
+ `nav`、`docs` 同理。先用 `--stat` 或 `--summary` 确认变更范围,只有需要审查正文时才展开完整 diff。`commit` 返回新版本与哈希后,再用远端检查确认基线一致。409/412、未解决冲突或远端状态不明时停止。
19
+
20
+ ## 结构化资源与自定义服务
21
+
22
+ 结构化资源按最新 describe 调用写 operation,再用 get/list operation 回读。自定义服务执行 `diff -> commit`,其中 commit 自动完成 validate 和 publish;需要运行行为证据时再执行 test。
23
+
24
+ ## 统一收尾
25
+
26
+ ```bash
27
+ draftgo verify
28
+ draftgo work complete <ref> --note "<结果与证据>"
29
+ ```
30
+
31
+ 默认 `verify` 不启动浏览器。只有用户明确要求视觉验收时,才增加 `--url <url> --screenshot always`;需要 DOM 或交互验证时再用 `--ui always`。所有 commit、MCP 写入、必要 test/publish 和回读都成功后才能 complete;失败项保持 active,并在 note 外记录可脱敏的 request ID。
32
+
33
+ 完成条件:本地检查通过,目标远端资源可回读,版本/哈希或结构化状态与预期一致,任务要求的运行或视觉证据齐全,且证据不含凭据。
@@ -0,0 +1,51 @@
1
+ ---
2
+ read_when: 运行失败、MCP/API 调用异常、远端状态不一致或需要查询运行日志时
3
+ ---
4
+
5
+ # 运行诊断
6
+
7
+ ## 最短诊断链
8
+
9
+ ```bash
10
+ draftgo status --output json
11
+ draftgo mcp status
12
+ draftgo mcp test
13
+ draftgo map --type pages --summary --output json
14
+ draftgo check --remote --output json
15
+ ```
16
+
17
+ `draftgo status` 的 `connection.health` 报告 `healthy`、`unhealthy` 或 `not_configured`,并输出当前 `platform`/`space` TokenScope;space 上下文同时带 `workspace_id` 与 `space_id`。只执行与故障层级有关的命令:连接失败看 `mcp test`;已知页面可用 `map --type pages --route <path>` 或 `--title <title>` 精确检查,未知资源先看 `map --summary`;checkout、哈希或版本异常看 `check --remote`。需要浏览时用 `--limit <1-100>`(默认 20)和单一类型的 `--cursor`,不运行默认全量 map。命令失败仍保留其非零退出码和脱敏输出。
18
+
19
+ API 运行失败时,用原 operation 生成结构化诊断:
20
+
21
+ ```bash
22
+ draftgo api describe <operation_id>
23
+ draftgo api call <operation_id> --input request.json --output json
24
+ draftgo api search "AI run logs"
25
+ ```
26
+
27
+ 记录 `operation_id`、`status_code`、`server_code`、`request_id`,再通过实时日志 operation 查询对应 run。AI 调用按入口 Agent/模型和 request ID 定位;子 Agent 链路从 span 查,不把一次入口请求误算成多条主 run。自定义服务再按 `custom-services.md` 执行 validate/test,页面运行时再读 `runtime.md`。
28
+
29
+ ## 权限与范围诊断
30
+
31
+ | 结果 | 最短定位 |
32
+ |---|---|
33
+ | 400 | 重新 `draftgo api describe <operation_id>`,核对当前 registry revision、`path/query/body/multipart` 容器、必填字段和 `scope_type/space_id` 组合。不要靠修改字段名试探契约。 |
34
+ | 401 | 运行 `draftgo status`;检查项目是否连接、当前用户 API Key 是否缺失、过期或已撤销。重新连接或轮换后再试一次,不把密钥放进输入、宿主配置或日志。 |
35
+ | 403 | 从结构化错误读取 `error_code`、`permission` 和 `scope_type`;核对 operation 所需 permission、API Key TokenScope、持久化 ResourceOwnership、有效 AccessGrant 和 DataRange。管理员身份与工作区成员关系都不是授权来源。 |
36
+ | space 跨根拒绝 | 这是预期边界。确认目标资源保存的 workspace root 与 Grant 所属 root;改用同根 self/subtree Grant 或合法迁移流程。只有实时契约支持且明确需要跨空间管理时,才检查显式 permission 的 platform Grant。不要篡改 workspace/space ID 或 header 重试。 |
37
+
38
+ 解释 Grant 来源时先用实时契约,不从角色名或 UI 状态推测:
39
+
40
+ ```bash
41
+ draftgo grant list --input request.json
42
+ draftgo api search "access grant explain"
43
+ draftgo api describe <explain_operation_id>
44
+ draftgo api call <explain_operation_id> --input request.json --output json
45
+ ```
46
+
47
+ 按解释结果核对直接用户 Grant 与用户组 Grant 的并集、Role 中的精确 permission、space 的 self/subtree 覆盖、Grant/Role/成员/组的启用状态和有效期,以及最终 `matched_grant_ids` / DataRange。没有匹配来源时保持拒绝,不临时授予更大的 platform 权限来验证。
48
+
49
+ 不要在 issue、工作日志、命令参数或诊断文件中写 API Key、服务凭据、Authorization、完整请求头或上游服务地址。非幂等写入失败后先回读状态,不自动重试。
50
+
51
+ 完成条件:故障已定位到连接、契约、权限、资源版本、Runner 或业务运行中的一层,并保留可关联的 request ID/run 证据;无法定位时明确缺少哪项服务端证据。
@@ -10,6 +10,19 @@ version: 2.0.0
10
10
 
11
11
  ## 页面决策
12
12
 
13
+ ## DraftGo Components
14
+
15
+ 开发 Page 前先查询当前实例的组件目录:
16
+
17
+ ```text
18
+ draftgo components search <query> --output json
19
+ draftgo components show <library/component> --output json
20
+ ```
21
+
22
+ 有合适组件时优先使用 `data-dg-use="library/component"`、`data-dg-instance`、`data-dg-prop-*` 和 `data-dg-slot`。个性化优先改 props、slots、CSS 变量和 Page 局部 class;高度个性化时使用 `draftgo components expand --page <id> --instance <name>`,展开后就是普通 HTML/CSS/JavaScript,不再跟随组件库升级。展开后的 Page 仍必须经过 `draftgo diff`、`draftgo verify`、`draftgo commit`。
23
+
24
+ 开发组件库组件使用 `draftgo components checkout <library/component>`,直接编辑生成的 `component.html/css/js`、`contract.json` 和 `component.json`,然后依次执行 `components diff`、`components verify`、`components commit`。`commit` 只保存草稿;只有用户明确要求上线时才执行 `components publish`。库管理和组件创建、复制、删除、ZIP 导入导出均使用 `components libraries|create|copy|delete|import|export`,不要绕过 CLI 直接修改 DraftGo 数据库。
25
+
13
26
  ### 页面身份与创建
14
27
 
15
28
  业务新页面默认是数据库中的完整 HTML 页面。先结合用户意图与 MCP 中的标题、route、用途和入口判断目标:
@@ -51,9 +64,10 @@ version: 2.0.0
51
64
  - 数据型页面应让主要操作、分页、批量操作和保存控件在空、短、长列表下都可达;滚动边界明确,横向溢出不能隐藏核心操作。
52
65
  - 展示可维护内容时判断是否需要管理入口并复用同一份真实数据。列表、详情和编辑结构按任务差异设计,不复制大量同构工作台。
53
66
  - 按钮、标签、导航项、徽章等视觉整体内部使用 `white-space: nowrap`;整组可换行,但图标与文字不能被拆散。
54
- - 空态需有明确文案和下一步操作;自定义空态用 flex 对齐图标与文字,不依赖 `text-align` 居中块级图标。
67
+ - 空态需有明确文案和下一步操作;已有固定主操作入口时使用紧凑说明和就近操作,自定义空态用 flex 对齐图标与文字。
55
68
  - 弹窗和抽屉把滚动放在内容区,避免双滚动条;flex 内容区使用 `min-height: 0` 保持滚动可用。
56
- - 下拉选择使用组件库选择器或可访问的自定义弹层,不使用浏览器默认 `<select>`。
69
+ - 官方内置页的复杂选择器优先使用 Basecoat 或可访问的自定义弹层;普通 Page 可按场景使用原生 `<select>`,并补齐主题、焦点、禁用、空值和错误状态。
70
+ - 运营表格可把排序和筛选放在对应表头的弹层中,保持数据列、条件和结果之间的直接关系;具体交互由数据规模与操作频率决定。
57
71
 
58
72
  ### 响应式
59
73
 
@@ -71,25 +85,23 @@ GSAP 从 `/assets/vendor/gsap/gsap.min.js` 先加载核心,再按需加载插
71
85
 
72
86
  - DraftGo 壳层位于 `frontend/`,使用 React 19 + Vite 8 + Tailwind CSS 4。只有用户明确要求修改壳层时才编辑该源码。
73
87
  - 业务页面与导航存储为数据库中的完整 HTML 文档,由壳层在 iframe 中运行。不得写入 TSX、ESM import、npm 依赖或 Vite 构建产物。
74
- - 数据库页面需要 React 时,只能使用内置 React 18 UMD `window.React` / `window.ReactDOM`;不要混入壳层 React 19 或其他版本。
88
+ - 数据库 Page 使用普通 HTML + Tailwind CSS 4 + 原生 JavaScript;官方内置 Page 默认搭配 Basecoat UI,按需使用下方列出的本地资源。
75
89
  - 页面使用 `const App = window.parent?.App`。参数读取 `window.__DG_ROUTE_CONTEXT__.query`;页面跳转使用父窗口;登出调用 `await App.logout()`。
76
90
 
77
- ## 必须与禁止
78
-
79
- 必须:
91
+ ## 实践建议
80
92
 
81
93
  - 提交完整 `<html><head><body>` 文档,静态资源使用下方本地路径。
94
+ - Basecoat 是默认 Page 组件库;Oat 是 Web Components 场景的可选组件库,版本处于 pre-1.0。每个 Page 按场景选择其中一套组件库。
82
95
  - 默认使用 `var(--dg-*)` 主题 token,并支持浅色/深色;用户输入或不可信 HTML 经 DOMPurify 净化。
83
96
  - 使用 `App.confirm()`、`App.toast()` 或对应反馈 API;关键状态不能只靠颜色或动画。
97
+ - 建议调用全局 `App.formatDateTime(value, options)` 来适配系统时间显示;API 时间按 UTC 解析,页面不要直接按浏览器本地时区展示。
84
98
  - 初始渲染立即显示稳定的加载状态。
85
-
86
- 禁止:
87
-
88
- - 境外 CDN(googleapis、jsdelivr、cdnjs、unpkg);品牌图标的明确例外见资源章节。
89
- - `window.alert/confirm/prompt`、`App()`、`window.location.search`、页面内直接 `window.location.href=...`。
90
- - TSX、ESM、npm 依赖或构建产物写进数据库 HTML。
91
- - 在业务页面实现全局浮窗、客服、统计脚本或重复 Toast;使用 `frontend_global_*` 槽位和系统配置。
92
- - 用无作用域 CSS 覆盖组件库内部 hover、focus、disabled、error 状态。
99
+ - 空间业务页先读取有效的 `{ scope_type: 'space', space_id }` 再发送业务请求;上下文就绪期间保持稳定加载状态,没有可用工作空间时呈现紧凑的工作空间状态和重试入口。完整写法见 `app-api.md`。
100
+ - 页面文案使用页面级 `page_i18n`:静态 HTML 可用 `data-i18n-key` / `data-i18n-placeholder`,JavaScript 使用 `App.t(key, fallback, values)`;不要创建公共词条表或自定义 namespace。翻译输入必须保持原 messages key 集合和 ICU 占位符不变。
101
+ - 选择器、Toast 等交互控件优先采用项目已有组件或统一封装,使视觉、状态和反馈与页面设计系统保持一致;提示就近呈现并说明下一步操作。
102
+ - 外部资源优先使用项目内置文件;品牌图标的明确例外见资源章节。
103
+ - 数据库 HTML 保持为可直接运行的页面文档,依赖和构建产物使用平台提供的本地资源。
104
+ - 全局浮窗、客服、统计脚本或公共 Toast 统一使用 `frontend_global_*` 槽位和系统配置;组件库状态样式通过其公开 API 或局部作用域进行适配。
93
105
 
94
106
  ## 组件与资源
95
107
 
@@ -97,52 +109,27 @@ GSAP 从 `/assets/vendor/gsap/gsap.min.js` 先加载核心,再按需加载插
97
109
 
98
110
  | 名称 | 版本与形态 | 本地资源 |
99
111
  |---|---|---|
100
- | Ant Design | 5.29.3,React 18 UMD,`window.antd` | `/assets/antd/reset.css`、React、ReactDOM、dayjs、`/assets/antd/antd.min.js` |
101
112
  | Basecoat UI | 1.0.2,HTML/CSS/JS,`window.basecoat` | `/assets/vendor/basecoat/basecoat.min.css`、`basecoat.min.js` |
102
113
  | Oat UI | 0.7.0,Web Components,`window.ot` | `/assets/vendor/oat/oat.min.css`、`oat.min.js` |
103
114
 
104
- `/assets/adapters/draftgo-ui.js` 提供 `window.DraftGoUI` 与 `DraftGoUI.load('antd'|'basecoat'|'oat')`。Basecoat/Oat `/assets/adapters/draftgo-theme.css` 必须位于对应组件 CSS 之后。组件选择取决于任务,不强制套用。
105
-
106
- ### Ant Design 契约
107
-
108
- 手工加载顺序不可变:
109
-
110
- ```html
111
- <link href="/assets/antd/reset.css" rel="stylesheet">
112
- <script src="/assets/react/react.min.js"></script>
113
- <script src="/assets/react-dom/react-dom.min.js"></script>
114
- <script src="/assets/dayjs/dayjs.min.js"></script>
115
- <script src="/assets/antd/antd.min.js"></script>
116
- ```
117
-
118
- 不要加载 `antd.min.css`、ESM/CDN AntD 或其他版本。根组件使用 `antd.ConfigProvider`,根据 `App.theme` 选择 `antd.theme.darkAlgorithm/defaultAlgorithm`,并把 `--dg-accent` 传给 `token.colorPrimary`;监听根元素的 `style/class/data-theme` 变化以刷新主题。
119
-
120
- 组件库是其内部状态样式的唯一所有者:优先用 ConfigProvider、design token 或公开 API。自建组件才由页面 CSS 管理状态,且规则限定在组件类或页面根内。
121
-
122
- | AntD | 平台反馈 |
123
- |---|---|
124
- | `Modal.confirm` | `await App.confirm(msg, title)` |
125
- | `Modal.info/warning` | `App.showModal(msg, title)` |
126
- | `message.success/error` | `App.showSuccess/showError(msg)` |
127
- | `message.info/warning` | `App.showInfo/showWarning(msg)` |
115
+ `/assets/adapters/draftgo-ui.js` 提供 `window.DraftGoUI` 与 `DraftGoUI.load('basecoat'|'oat')`。壳层自动注入 `/assets/adapters/draftgo-theme.css` 与组件运行时,Page 可直接使用;第三方 Page 按产品需求自主选择技术与视觉方案。使用组件库时通过公开类名/API 和 DraftGo 语义 token 适配。
128
116
 
129
- Tooltip 可保留组件库原生实现。
117
+ 确认、信息弹层和反馈优先使用 `App.confirm()`、`App.showModal()`、`App.showSuccess/showError/showInfo/showWarning()`,避免页面各自复制 Toast 或浏览器原生对话框。
130
118
 
131
119
  ### 本地资源
132
120
 
133
121
  | 能力 | 路径 |
134
122
  |---|---|
135
- | Tailwind runtime | `/assets/tailwindcss.js` |
136
- | React/AntD | `/assets/react/react.min.js`、`/assets/react-dom/react-dom.min.js`、`/assets/dayjs/dayjs.min.js`、`/assets/antd/antd.min.js` |
123
+ | Tailwind CSS 4.3.1 Browser Runtime | `/assets/tailwindcss.js` |
137
124
  | UI adapters | `/assets/adapters/draftgo-ui.js`、`/assets/adapters/draftgo-theme.css` |
138
125
  | Basecoat/Oat | `/assets/vendor/basecoat/*`、`/assets/vendor/oat/*` |
139
- | Icons/fonts | `/assets/fontawesome/css/all.min.css`、`/assets/icons/{name}.svg`、`/assets/icons/manifest.json`、`/assets/fonts/*.css` |
140
- | Markdown/code | `/assets/vendor/marked/marked.min.js`、`/assets/vendor/highlightjs/highlight.min.js`、`/assets/vendor/prism/prism.min.js` |
141
- | HTML/security/export | `/assets/vendor/dompurify/purify.min.js`、`/assets/vendor/html2canvas/html2canvas.min.js` |
126
+ | Icons | `/assets/fontawesome/css/all.min.css`、`/assets/icons/{name}.svg`、`/assets/icons/manifest.json` |
127
+ | Markdown/code | `/assets/vendor/marked/marked.min.js`、`/assets/vendor/highlightjs/highlight.min.js`、`/assets/vendor/highlightjs/styles/github.min.css` |
128
+ | HTML security | `/assets/vendor/dompurify/purify.min.js` |
142
129
  | Chat | `/assets/draftgo-chat.js` |
143
130
  | Motion | `/assets/vendor/gsap/*.js` |
144
131
 
145
- 通用图标优先使用本地图标或 FontAwesome。模型/Provider 品牌标识可用固定版本的 LobeHub `@lobehub/icons-static-svg` npmmirror URL;不得用 `latest`,也不得替代通用 UI 图标。
132
+ 正文使用系统无衬线字体栈,代码使用系统等宽字体栈。通用图标优先使用项目内置 SVG,其他通用图标可使用 Font Awesome。模型/Provider 品牌标识可用固定版本的 LobeHub `@lobehub/icons-static-svg` npmmirror URL
146
133
 
147
134
  ## 主题
148
135
 
@@ -167,3 +154,4 @@ AI 对话 UI 使用:
167
154
  动态创建使用 `DraftGoChat.create()`;无 UI 文本或图片调用可用同一脚本的 `DraftGoAI` 兼容门面。完整事件、会话和安全契约见 `chat-sdk.md`,Agent `spec` 见 `aihub.md`。
168
155
 
169
156
  平台请求与反馈见 `app-api.md`;iframe 路由、认证与全局层见 `runtime.md`;动态 DB、`scope=mine`、筛选和关系见 `data.md`。
157
+ Chat JSON 配置按 DraftGo 当前 `contracts/chat-sdk.schema.json` 校验,函数型扩展只在 JavaScript 注册。
@@ -6,6 +6,34 @@ read_when: 配置或诊断 DraftGo MCP 时 · 查询实时资源或 API 契约
6
6
 
7
7
  根 `SKILL.md` 已负责任务路由。本文件只保留 MCP 的实时契约、调用优化和安全边界,不重复页面、前端或交付规则。
8
8
 
9
+ ## 最短流程
10
+
11
+ ```bash
12
+ draftgo mcp status
13
+ draftgo mcp test
14
+ draftgo api search "<业务能力>"
15
+ draftgo api describe <operation_id>
16
+ draftgo api call <operation_id> --input request.json --output json
17
+ draftgo capabilities search <query> --output json
18
+ draftgo capabilities show <operation_id> --output json
19
+ draftgo capabilities audit --output json
20
+
21
+ # 领域快捷命令(仍使用实时 operation describe/cache)
22
+ draftgo role list
23
+ draftgo space list
24
+ draftgo grant create --input request.json
25
+ draftgo data-range list
26
+ draftgo api-key status
27
+
28
+ # 领域快捷命令(仍使用实时 operation describe/cache)
29
+ draftgo role list
30
+ draftgo group list --input request.json
31
+ draftgo grant list --input request.json
32
+ draftgo api-key status
33
+ ```
34
+
35
+ 已配置且连接正常时无需每次运行前两条;只在初次配置、配置变化或 MCP 失败时执行。完成标准是 initialize、tools/list 和关键 tools/call 可用,目标 operation 的 schema 已确认且调用结果可回读。401/403 查用户 API Key 或权限,session/uninitialized 查会话与服务重启,5xx 记录 request ID 后查服务日志;不要用重复写入测试连接。
36
+
9
37
  ## 边界
10
38
 
11
39
  MCP 用于实时发现、结构化查询和普通 API 操作。pages、navigations、docs/articles、custom_services 的完整正文走 `draftgo checkout` / `draftgo commit`;工具返回 `artifact` 或 `omitted` 时保留该语义,不要求模型展开长内容。
@@ -30,7 +58,7 @@ MCP 用于实时发现、结构化查询和普通 API 操作。pages、navigatio
30
58
  1. operation 未知时才 search;已有精确 `operation_id` 时跳过 search。
31
59
  2. 第一次使用 operation 时 describe,检查 method、path、parameters、request body、responses、permission、risk、`destructive`、`idempotent`、`input_schema` 和 `response_policy`。
32
60
  3. 同一 server 的 operation 描述按 `registry_revision` 复用。CLI 将缓存写在私有 `.draftgo/api-contract-cache.json`,不把 schema 注入 Skill 或对话上下文。
33
- 4. call 携带缓存的 `registry_revision`。服务返回 `CONTRACT_CHANGED` 时重新 describe 并重试一次;其他工具错误不触发自动重试。
61
+ 4. call 携带缓存的 `registry_revision`。服务返回 `CONTRACT_CHANGED` 时重新 describe;只读或 operation 契约未变化时最多重试一次。危险 operation 自身契约变化或服务端明确报告 CLI/契约不兼容时停止调用,升级 CLI 后重新 describe 和确认;其他工具错误不触发自动重试。
34
62
 
35
63
  describe 缺少本次调用需要的 schema、权限、风险或响应契约时停止并报告,不猜字段、不拼路径、不绕过 MCP。多个 operation 仍可能匹配时继续缩小 search,而不是任选一个。
36
64
 
@@ -50,7 +78,7 @@ describe 缺少本次调用需要的 schema、权限、风险或响应契约时
50
78
  }
51
79
  ```
52
80
 
53
- 只传 operation schema 需要的容器。路径参数放 `path`,查询参数放 `query`,JSON 放 `body`,文件或表单字段放 `multipart`。不得传 tenant override、SAT、Authorization 或其他凭据。
81
+ 只传 operation schema 需要的容器。路径参数放 `path`,查询参数放 `query`,JSON 放 `body`,文件或表单字段放 `multipart`。不得传 tenant override、API Key、Authorization 或其他凭据。
54
82
 
55
83
  高风险 operation 仅在用户意图和影响范围明确时设置 `confirm=true`;不要拼 `X-Confirm-Token` 或调用旧 reauth 流程。按 describe 的 responses 与实际 `status_code` 解释结果,不对自定义 Route、OpenAI 兼容流等强套 `{code,data,message}`。`response_policy.checkout_required=true` 时改走 checkout/commit。
56
84
 
@@ -76,13 +104,13 @@ draftgo mcp serve
76
104
  {"command":"draftgo","args":["mcp","serve"]}
77
105
  ```
78
106
 
79
- Codex 使用 `[mcp_servers.draftgo]`;GitHub Copilot 使用 `servers` 且声明 `type="stdio"`;其他支持宿主使用各自 `mcpServers`。配置不得包含 SAT、token、Authorization、headers、远端 `/mcp` URL、`env` 或带凭据命令。bridge 从当前项目 `.draftgo/config.json` 读取 server/SAT
107
+ Codex 使用 `[mcp_servers.draftgo]`;GitHub Copilot 使用 `servers` 且声明 `type="stdio"`;其他支持宿主使用各自 `mcpServers`。配置不得包含 API Key、token、Authorization、headers、远端 `/mcp` URL、`env` 或带凭据命令。bridge 从当前项目 `.draftgo/config.json` 读取 server/API Key
80
108
 
81
109
  `draftgo connect` 只保存并验证连接,不下载业务资源或创建本地镜像。MCP 不可用时运行 `draftgo mcp test` 收集证据。
82
110
 
83
111
  ## 安全
84
112
 
85
- - stdio stdout 只输出 MCP JSON-RPC;日志写 stderr,且不得包含 SAT
113
+ - stdio stdout 只输出 MCP JSON-RPC;日志写 stderr,且不得包含 API Key
86
114
  - 代理 initialize、tools/list、tools/call、通知、取消、错误和流式响应,不改写底座结果。
87
- - HTTP 401/403、协议错误和工具缺失必须清晰失败;输出前脱敏 SAT 与 Authorization。
115
+ - HTTP 401/403、协议错误和工具缺失必须清晰失败;输出前脱敏 API Key 与 Authorization。
88
116
  - `.draftgo/config.json`、`.draftgo/api-contract-cache.json`、worktree 和 conflicts 都是私有运行时状态并应 gitignore。