@comate/zulu 1.3.3 → 1.3.4-beta.2

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 (32) hide show
  1. package/comate-engine/assets/skills/auto-commit-comate/SKILL.md +42 -62
  2. package/comate-engine/assets/skills/auto-commit-comate/references/data_structures.md +69 -75
  3. package/comate-engine/assets/skills/auto-commit-comate/references/interaction_instruction.md +220 -0
  4. package/comate-engine/assets/skills/auto-commit-comate/scripts/build_git_commit_payload.py +195 -0
  5. package/comate-engine/assets/skills/auto-commit-comate/scripts/build_icafe_cards_payload.py +80 -0
  6. package/comate-engine/assets/skills/auto-commit-comate/scripts/cache_manager.py +69 -0
  7. package/comate-engine/assets/skills/auto-commit-comate/scripts/git_diff_cli.py +5 -0
  8. package/comate-engine/assets/skills/auto-commit-comate/scripts/match_card_cli.py +5 -1
  9. package/comate-engine/assets/skills/auto-commit-comate/scripts/payload_validators.py +309 -0
  10. package/comate-engine/assets/skills/code-security-comate/SKILL.md +2 -1
  11. package/comate-engine/assets/skills/code-security-comate/references/vul_repair-go_sql_injection.md +627 -5
  12. package/comate-engine/assets/skills/code-security-comate/references/vul_repair-java_sql_injection.md +545 -21
  13. package/comate-engine/assets/skills/code-security-comate/references/vul_repair-php_sql_injection.md +596 -13
  14. package/comate-engine/assets/skills/code-security-comate/references/vul_repair-python_sql_injection.md +480 -82
  15. package/comate-engine/assets/skills/code-security-comate/scripts/http_client.py +10 -2
  16. package/comate-engine/assets/skills/code-security-comate/scripts/repair_vulnerability.py +12 -10
  17. package/comate-engine/assets/skills/code-security-comate/scripts/report_chat.py +1 -1
  18. package/comate-engine/assets/skills/comate-docs-comate/SKILL.md +70 -105
  19. package/comate-engine/assets/skills/comate-docs-comate/references/doc-map-extended.md +52 -7
  20. package/comate-engine/assets/skills/comate-docs-comate/references/models-and-billing.md +45 -26
  21. package/comate-engine/assets/skills/comate-docs-comate/references/product-overview.md +60 -14
  22. package/comate-engine/assets/skills/create-image-comate/SKILL.md +7 -7
  23. package/comate-engine/assets/skills/get-ugate-token-comate/SKILL.md +2 -0
  24. package/comate-engine/node_modules/@comate/plugin-engine/dist/index.js +1 -1
  25. package/comate-engine/node_modules/@comate/plugin-host/dist/index-7HvPXRep.js +1 -0
  26. package/comate-engine/node_modules/@comate/plugin-host/dist/index.js +1 -1
  27. package/comate-engine/node_modules/@comate/plugin-host/dist/main.js +1 -1
  28. package/comate-engine/node_modules/@comate/plugin-host/dist/user-DVjAG3wH.js +44 -0
  29. package/comate-engine/node_modules/@comate/plugin-shared-internals/dist/index.js +8 -8
  30. package/comate-engine/server.js +378 -266
  31. package/dist/bundle/index.js +3 -3
  32. package/package.json +1 -1
@@ -27,64 +27,19 @@ metadata:
27
27
  - **iCode 仓库** (`is_icode_repo = true`):步骤 0 → 1+2(并行) → 3 → 4 → 5 → 6 → 7 → 8 → 9
28
28
  - **非 iCode 仓库** (`is_icode_repo = false`):步骤 0 → 2 → 7 → 8 → 9(跳过 1/3/4/5/6,commit message 不带卡片 ID)
29
29
 
30
- **版本交互方式:** 根据步骤 0a 判定的版本,后续命令和交互有差异:
31
- - **新版本**:参考 `references/new_version_instruction.md`。**新版本下 Agent 必须通过 `__interactive:` UI 组件与用户交互(步骤 4 用 `__interactive:icafe-cards`,步骤 8 用 `__interactive:git-commit`),禁止用纯文本输出替代 UI。**
32
- - **旧版本**:参考 `references/old_version_instruction.md`
30
+ **Agent 必须通过 `__interactive:` UI 组件与用户交互(步骤 4 用 `__interactive:icafe-cards`,步骤 8 用 `__interactive:git-commit`)。禁止自行拼接 payload JSON,必须通过 builder 脚本验证后调用。**
33
31
 
34
32
  ---
35
33
 
36
34
  ## 步骤 0:前置检查(串行执行,完全静默)
37
35
 
38
- **整个前置检查过程完全静默,禁止输出任何版本、兼容性相关信息。**
36
+ **整个前置检查过程完全静默。**
39
37
 
40
- ### 0a. 版本兼容性检查(纯文本判断,无需命令)
41
-
42
- 通过检查「版本信息」占位符是否被替换来判断:
43
- 1. IDE 名称仍含 `COMATE_IDE_NAME`(未替换)→ **旧版本**
44
- 2. 插件版本仍含 `COMATE_PLUGIN_VERSION`(未替换)→ **旧版本**
45
- 3. 版本号 < `4.3.0` → **旧版本**
46
- 4. 否则 → **新版本**
47
-
48
- 新版本命令加 `__silent:` 前缀,旧版本不加。**继续执行 0b。**
49
-
50
- ### 0b. 开关检查 + Python 检测 + iCode 仓库检测(三条命令并行)
51
-
52
- **说明:命令 1 的开关检查读取用户本地配置(`enableSmartCommit`),是用户个人的开关偏好。步骤 1 中的 `result.disabled` 是服务端/空间级别的开关,两者独立,互不替代。**
53
-
54
- #### 命令 1:开关检查(纯 shell,无外部依赖)
55
-
56
- **macOS / Linux:**
57
- ```
58
- [__silent: ]cat ~/.comate/settings.json 2>/dev/null || echo "{}"
59
- ```
60
- **Windows(cmd):**
61
- ```
62
- [__silent: ]type "%USERPROFILE%\.comate\settings.json" 2>NUL || echo {}
63
- ```
64
-
65
- 解析输出 JSON,检查 `enableSmartCommit` 字段:
66
- - `false` → 立即结束 skill,不再输出任何内容
67
- - `true`/不存在/文件不存在(输出 `{}`) → 继续
68
-
69
- #### 命令 2:Python 可用性检测
70
-
71
- **macOS / Linux:**
72
- ```
73
- [__silent: ]python3 --version 2>/dev/null || python --version 2>/dev/null
74
- ```
75
- **Windows(cmd):**
76
- ```
77
- [__silent: ]python --version 2>NUL || python3 --version 2>NUL || py -3 --version 2>NUL
78
- ```
79
-
80
- - 成功 → 记住**输出中实际成功的命令名**(`python3`/`python`/`py -3`),后续所有 `python3` 替换为该命令名
81
- - 全部失败 → 标记 `python_available = false`,后续步骤 1 直接进入"iCafe 获取失败降级"流程,步骤 2 中 Agent 直接执行 git 命令获取 diff
82
-
83
- #### 命令 3:iCode 仓库检测
38
+ ### iCode 仓库检测
84
39
 
85
40
  对第一个 workspace 执行:
86
41
  ```
87
- [__silent: ]cd <第一个workspace_path> && git remote -v
42
+ __silent: cd <第一个workspace_path> && git remote -v
88
43
  ```
89
44
 
90
45
  检查输出是否包含 `icode.baidu.com`:包含 → `is_icode_repo = true`,不包含或失败 → `is_icode_repo = false`。
@@ -95,10 +50,10 @@ metadata:
95
50
 
96
51
  执行:
97
52
  ```bash
98
- [__silent: ]python3 <skill_directory>/scripts/match_card_cli.py --username "${COMATE_USERNAME}"
53
+ __silent: python3 <skill_directory>/scripts/match_card_cli.py --username "${COMATE_USERNAME}"
99
54
  ```
100
55
 
101
- 解析 stdout 的 JSON 为 `result`。先检查 `result.disabled`,为 `True` 则立即结束。
56
+ 解析 stdout 的 JSON 为 `result`。先检查 `result.disabled`,为 `True` 则立即结束。脚本会自动将 result 写入统一缓存文件(`/tmp/__comate_auto_commit_cache.json`),供步骤 4 使用。
102
57
 
103
58
  **失败降级**:脚本报错/超时/非 JSON → 标记 `icafe_failed = true`,跳过步骤 3-6,直接进入步骤 7 生成无卡片 commit message。
104
59
 
@@ -111,15 +66,15 @@ metadata:
111
66
  对每个 workspace 执行:
112
67
 
113
68
  ```bash
114
- [__silent: ]python3 <skill_directory>/scripts/git_diff_cli.py --workspace <workspace_path>
69
+ __silent: python3 <skill_directory>/scripts/git_diff_cli.py --workspace <workspace_path>
115
70
  ```
116
71
 
117
72
  同时对第一个 workspace 并行执行获取 commit 风格:
118
73
  ```bash
119
- [__silent: ]cd <第一个workspace_path> && git log --oneline -n 20
74
+ __silent: cd <第一个workspace_path> && git log --oneline -n 20
120
75
  ```
121
76
 
122
- Agent 从 git log 分析 `commit_style`(前缀格式、语言、描述风格),供步骤 3/7 生成 commit message 时保持风格一致。**不输出任何内容。**
77
+ Agent 从 git log 分析 `commit_style`(前缀格式、语言、描述风格),供步骤 3/7 生成 commit message 时保持风格一致。**不输出任何内容。** 脚本同时将 diff 结果写入统一缓存文件(`/tmp/__comate_auto_commit_cache.json`),供步骤 8 自动构建 payload。
123
78
 
124
79
  脚本输出 JSON 格式、以及如何构建 `workspace_diffs` 和 `diff_summary`,详见 `references/data_structures.md`(包含脚本输出示例和合并规则)。
125
80
 
@@ -159,15 +114,27 @@ Agent 内部基于 diff 内容生成 `defaults.title`(建卡默认标题):
159
114
 
160
115
  **上下文快捷匹配:** 如果对话中用户已指定卡片(卡片 ID、iCafe 链接等),直接作为 `selected_card`,跳过 UI。
161
116
 
162
- **否则,必须展示卡片选择 UI,禁止自行替用户选择或创建卡片。** 根据版本展示交互 UI,参考对应 reference 文件。**新版本必须使用 `__interactive:icafe-cards` 展示,禁止用文本列表替代。**
117
+ **否则,必须通过 builder 脚本验证 payload 后展示卡片选择 UI。禁止自行拼接 JSON 或替用户选择/创建卡片。**
118
+
119
+ 具体操作:
120
+ 1. 确定模型决策:`viewMode`(`"list"` 或 `"create"`)、`defaults.title`(Agent 根据 diff 语义生成)、`cards`(步骤 3 排序后,可选)
121
+ 2. 调用 builder 脚本(脚本自动从 `/tmp/__comate_icafe_result.json` 读取 result,不需要模型传文件):
122
+ ```
123
+ __silent: python3 <skill_directory>/scripts/build_icafe_cards_payload.py --view-mode list --default-title "优化 xxx 相关功能"
124
+ ```
125
+ **⚠️ 不需要传 --result-file、不需要手动转换字段名、不需要拼 JSON。脚本自动完成所有转换。`--cards` 可选,不传则使用 result 中的原始顺序。**
126
+ 3. 解析输出:
127
+ - `{"valid": true, "payload": {...}}` → 提取 `payload` 内层 JSON,使用 `run_command` 调用 `__interactive:icafe-cards`(禁止将整个 `{"valid":true,"payload":{...}}` 传入,禁止将 payload 作为文本输出)
128
+ - `{"valid": false, "errors": [...]}` → 根据 errors 修正数据,重试一次;仍失败则按 `references/interaction_instruction.md` 降级为文本交互
129
+ - `{"error": "..."}` → 直接降级为文本交互
163
130
 
164
131
  ## 步骤 5:处理用户操作
165
132
 
166
- 根据版本处理用户选择/创建/跳过,参考对应 reference 文件。
133
+ 根据用户选择/创建/跳过处理,参考 `references/interaction_instruction.md`。
167
134
 
168
135
  **创建卡片命令模板:**
169
136
  ```
170
- [__silent: ]cd <用户项目目录> && python3 <skill_directory>/scripts/create_card_cli.py --title "<card.title>" --space-prefix "<card.spacePrefix>" --type-name "<card.typeName>" --username "${COMATE_USERNAME}"
137
+ __silent: cd <用户项目目录> && python3 <skill_directory>/scripts/create_card_cli.py --title "<card.title>" --space-prefix "<card.spacePrefix>" --type-name "<card.typeName>" --username "${COMATE_USERNAME}"
171
138
  ```
172
139
 
173
140
  ## 步骤 6:存储关联的 iCafe 卡片 ID
@@ -202,11 +169,26 @@ Agent 内部分析以下信号判断是否展示提交确认,**不输出任何
202
169
 
203
170
  ## 步骤 8:展示提交确认
204
171
 
205
- 根据版本展示确认 UI,参考对应 reference 文件。**新版本必须使用 `__interactive:git-commit` 展示,禁止用文本替代。** payload 必须严格遵循 `references/data_structures.md` 中「步骤 8 提交确认 payload」的结构定义,禁止自行发明字段或扁平化结构。
172
+ 必须通过 builder 脚本构造并验证 payload 后展示,禁止自行拼接 JSON 或用文本替代。
173
+
174
+ ### 推荐方式:缓存模式(Agent 不需要手动构造 workspaces)
175
+
176
+ 1. 调用 builder 脚本,传入 commit message 和绑定卡片:
177
+ ```
178
+ __silent: python3 <skill_directory>/scripts/build_git_commit_payload.py --cache --commit-message "<commit_message>" --bound-card '<card JSON 或 null>'
179
+ ```
180
+ - `--cache`:从统一缓存读取 diff 数据,自动执行 git branch 命令获取分支信息
181
+ - `--commit-message`:必填
182
+ - `--bound-card`:选定的卡片 JSON(步骤 5 获得),非 iCode 仓库或无卡片传 `'null'`
183
+
184
+ 2. 解析输出:
185
+ - `{"valid": true, "payload": {...}}` → 提取 `payload` 内层 JSON,使用 `run_command` 调用 `__interactive:git-commit`(禁止将整个 `{"valid":true,"payload":{...}}` 传入,禁止将 payload 作为文本输出)
186
+ - `{"valid": false, "errors": [...]}` → 根据 errors 修正数据,重试一次;仍失败则按 `references/interaction_instruction.md` 降级为文本交互
187
+ - `{"error": "..."}` → 直接降级为文本交互
206
188
 
207
189
  ## 步骤 9:执行提交 + 输出结果
208
190
 
209
- 根据版本处理提交,参考对应 reference 文件。
191
+ 参考 `references/interaction_instruction.md` 执行提交。
210
192
 
211
193
  **推送方式:** 统一使用 `git push origin HEAD:refs/for/<branch>` 推送到 Gerrit 代码评审。
212
194
 
@@ -247,14 +229,12 @@ Agent 内部分析以下信号判断是否展示提交确认,**不输出任何
247
229
  代码变更未完成,请确认后再提交
248
230
  ```
249
231
 
250
- 旧版本 IDE 提交成功后额外提示推送命令。
251
-
252
232
  ---
253
233
 
254
234
  ## 配置
255
235
 
256
236
  **认证**:token 按优先级读取 `COMATE_AUTH_TOKEN` 环境变量 → `~/.comate/login` 文件。
257
237
 
258
- **跨平台**:所有 `python3` 替换为步骤 0b 检测到的命令名;Windows 上 `cd` 改为 `cd /d`,错误抑制用 `2>NUL`。
238
+ **跨平台**:统一使用 `python3` 调用脚本,如果执行失败(命令不存在),自动依次尝试 `python`、`py -3`,某个成功则后续统一使用该命令名。
259
239
 
260
240
  **卡片链接**:`https://console.cloud.baidu-int.com/devops/icafe/issue/{space_prefix}-{card_sequence}/show`
@@ -67,84 +67,90 @@ diff_summary = {
67
67
 
68
68
  ---
69
69
 
70
- ## 步骤 4:卡片选择 payload(新版本 UI)
70
+ ## 统一缓存文件
71
71
 
72
- 通过 `__interactive:icafe-cards <payload JSON>` 展示。
72
+ 路径:`/tmp/__comate_auto_commit_cache.json`
73
73
 
74
- ### ⚠️ 字段命名强约束
74
+ 结构:
75
+ ```json
76
+ {
77
+ "icafe_result": { /* match_card_cli.py 完整输出 */ },
78
+ "git_diffs": {
79
+ "/path/to/workspace1": { /* git_diff_cli.py 完整输出 */ },
80
+ "/path/to/workspace2": { /* git_diff_cli.py 完整输出 */ }
81
+ }
82
+ }
83
+ ```
75
84
 
76
- payload 使用 **camelCase**,但脚本 `match_card_cli.py` 返回的是 **snake_case**。Agent 必须在构造 payload 时完成转换,禁止将脚本原始字段名直接传入:
85
+ 写入时机:
86
+ - `icafe_result`:步骤 1 由 `match_card_cli.py` 写入
87
+ - `git_diffs[workspace]`:步骤 2 由 `git_diff_cli.py` 对每个 workspace 写入
77
88
 
78
- | 脚本返回(snake_case) | payload 字段(camelCase) |
79
- |------------------------|--------------------------|
80
- | `space_prefix` | `spacePrefix` |
81
- | `space_id` | `spaceId` |
82
- | `space_name` | `spaceName` |
83
- | `available_spaces` | `availableSpaces` |
84
- | `defaults.type_id` | `defaults.typeId` |
85
- | `defaults.type_name` | `defaults.typeName` |
89
+ 清理时机:步骤 9 执行完成后由 Agent 清理(`rm -f /tmp/__comate_auto_commit_cache.json`)。
86
90
 
87
- **❌ 禁止直接使用脚本原始字段名:**
88
- ```json
89
- {"cards":[],"space_prefix":"dkx","space_id":12345,"space_name":"测试空间","view_mode":"list"}
90
- ```
91
+ ---
91
92
 
92
- **✅ 正确结构(camelCase):**
93
- ```json
94
- {
95
- "cards": [],
96
- "spacePrefix": "dkx",
97
- "spaceId": 12345,
98
- "spaceName": "测试空间",
99
- "availableSpaces": [{"id": 12345, "prefix": "dkx", "name": "测试空间", "types": [{"id": "5009", "name": "Bug"}]}],
100
- "viewMode": "list",
101
- "defaults": {
102
- "title": "推荐标题",
103
- "typeId": "5009",
104
- "typeName": "Bug",
105
- "spaceId": 12345
106
- }
107
- }
93
+ ## Payload Builder 脚本
94
+
95
+ Agent 在构造 `__interactive:` payload 时,**禁止自行拼接 JSON**,必须通过以下脚本验证并生成。脚本会对输入数据进行结构校验,返回验证结果。
96
+
97
+ ### 通用用法
98
+
99
+ ```bash
100
+ __silent: python3 <skill_directory>/scripts/<script_name>.py --json '<camelCase 数据 JSON>'
108
101
  ```
109
102
 
110
- 字段直接从 `result` 对象映射:`cards` 已按匹配度排序,`viewMode` 由步骤 3 确定,`defaults` 中的 `title`/`typeName` 由 Agent 根据 diff 语义生成。
103
+ ### 输出格式
104
+
105
+ - 验证通过:`{"valid": true, "payload": {...}}`
106
+ - 验证失败:`{"valid": false, "errors": ["具体错误描述", ...]}`
107
+ - 系统错误:`{"error": "..."}`
108
+
109
+ ### 处理流程
110
+
111
+ 1. Agent 构造 camelCase 数据
112
+ 2. 调用 builder 脚本传入数据
113
+ 3. 解析脚本输出:
114
+ - `valid: true` → 用 `payload` 调用 `__interactive:` UI
115
+ - `valid: false` → 根据 `errors` 修正数据,重新调用脚本(最多重试 1 次)
116
+ - 重试仍失败或 `error` → 降级为文本交互(参考 interaction_instruction.md 中降级格式)
111
117
 
112
118
  ---
113
119
 
114
- ## 步骤 8:提交确认 payload(新版本 UI
120
+ ### build_icafe_cards_payload.py(步骤 4
115
121
 
116
- 通过 `__interactive:git-commit <payload JSON>` 展示。
122
+ **作用**:从缓存文件读取原始数据,自动完成 snake_case → camelCase 转换并验证,输出 `__interactive:icafe-cards` payload
117
123
 
118
- Agent 仅对 `hasChanges: true` 的 workspace 执行 `git branch -vv` + `git branch -r --sort=-committerdate`(`__silent:` 前缀),无变更的 workspace 跳过分支查询。多 workspace 的分支查询命令必须并行发出。
124
+ **用法**(最简形式):
125
+ ```bash
126
+ python3 build_icafe_cards_payload.py --view-mode list --default-title "优化 xxx 相关功能"
127
+ ```
119
128
 
120
- ### ⚠️ payload 顶层结构强约束
129
+ 脚本自动读取 `/tmp/__comate_icafe_result.json`(由 `match_card_cli.py` 在步骤 1 自动写入)。
121
130
 
122
- **顶层有且仅有 3 个字段,字段名使用 camelCase:**
131
+ **Agent 不需要手动转换任何字段名,不需要拼 JSON,不需要传文件路径。** 只需传入 2 个必填参数(`--view-mode`、`--default-title`)和 1 个可选参数(`--cards`,排序后的卡片列表)。
123
132
 
124
- | 顶层字段 | 类型 | 说明 |
125
- |----------|------|------|
126
- | `commitMessage` | string | commit message(注意:不是 `commit_message`) |
127
- | `boundCard` | object \| null | 绑定的 iCafe 卡片(注意:不是 `icafe_card`) |
128
- | `workspaces` | array | workspace 数组(注意:是复数 `workspaces`,不是单数 `workspace`) |
133
+ **验证规则**:
134
+ - `cards` 为数组,每项含 `sequence/title/type/status`
135
+ - `viewMode` `"list"` `"create"`
136
+ - `availableSpaces` 每项含 `id/prefix/name/types`,`types` 每项含 `id/name`
137
+ - `defaults` `title(string)/typeId(string)/typeName(string)/spaceId(int)`
129
138
 
130
- **❌ 禁止出现在顶层的字段(常见错误):**
131
- - `workspace`(单数字符串)→ 应为 `workspaces`(复数数组)
132
- - `commit_message`(snake_case)→ 应为 `commitMessage`(camelCase)
133
- - `changed_files` → 应嵌套在 `workspaces[].diffSummary.changed_files`
134
- - `icafe_card` → 应为 `boundCard`
135
- - 任何其他扁平化字段
139
+ ---
136
140
 
137
- **❌ 错误示例(绝对禁止生成此结构):**
138
- ```json
139
- {
140
- "commit_message": "study-ai-823 fix: ...",
141
- "workspace": "/path/to/repo",
142
- "changed_files": [{"file": "src/service.go", "insertions": 16, "deletions": 8}],
143
- "icafe_card": {"sequence": 823, "title": "...", "spacePrefix": "study-ai"}
144
- }
141
+ ### build_git_commit_payload.py(步骤 8)
142
+
143
+ **作用**:验证并输出 `__interactive:git-commit` 的 payload。
144
+
145
+ **用法**:脚本自动从统一缓存读取 diff 数据,执行 git branch 获取分支信息,Agent 只需传入 commit message 和绑定卡片:
146
+ ```bash
147
+ python3 build_git_commit_payload.py --cache --commit-message "<message>" --bound-card '<card JSON 或 null>'
145
148
  ```
149
+ - `--commit-message`(必填):commit message
150
+ - `--bound-card`(必填):选定卡片 JSON 对象,无卡片传字符串 `'null'`
151
+
152
+ **输出 payload 结构**:
146
153
 
147
- **✅ 正确结构(即使只有 1 个 workspace 也必须用数组):**
148
154
  ```json
149
155
  {
150
156
  "commitMessage": "dkx-200 修复登录问题",
@@ -160,28 +166,16 @@ Agent 仅对 `hasChanges: true` 的 workspace 执行 `git branch -vv` + `git bra
160
166
  "changed_files": [{"file": "src/App.tsx", "insertions": 76, "deletions": 66}],
161
167
  "stat_summary": "2 files, +100, -78"
162
168
  }
163
- },
164
- {
165
- "workspace": "/path/to/shared-utils",
166
- "repoName": "shared-utils",
167
- "currentBranch": "",
168
- "remoteBranches": [],
169
- "hasChanges": false,
170
- "diffSummary": null
171
169
  }
172
170
  ]
173
171
  }
174
172
  ```
175
173
 
176
- ### 字段构造规则
177
-
178
- - `commitMessage`:iCode 仓库格式 `"<spacePrefix>-<sequence> <描述>"`;非 iCode 仓库不带卡片 ID
179
- - `boundCard`:步骤 5 选定的卡片,非 iCode 或无卡片时为 `null`
180
- - `workspaces`:必须包含所有 workspace(含无变更的)
181
- - `repoName`:路径最后一段
182
- - `currentBranch`:有变更时从 `git branch -vv` 解析,无变更时空字符串
183
- - `remoteBranches`:有变更时从 `git branch -r` 解析,跳过含 `->` 的行(HEAD 指针),去掉 `origin/` 前缀,标记当前追踪分支为 `isCurrent: true`,最多 10 个分支(当前追踪分支必须包含)
184
- - `diffSummary`:有变更时用 `workspace_diffs` 中的 `changed_files` + `stat_summary`,无变更时 `null`
174
+ **验证规则**(脚本内部自动保证,Agent 无需关心):
175
+ - 顶层包含 `commitMessage`, `boundCard`, `workspaces`
176
+ - `boundCard` `null` 或包含 `sequence/title/type/status/spacePrefix` 的对象
177
+ - 每个 workspace 自动填充 `workspace/repoName/currentBranch/remoteBranches/hasChanges/diffSummary`
178
+ - `diffSummary` 内部的 `changed_files` 和 `stat_summary` 保持 snake_case(与 git_diff_cli.py 输出一致)
185
179
 
186
180
  ### 用户操作返回
187
181
 
@@ -0,0 +1,220 @@
1
+ # 交互指南
2
+
3
+ 本文档描述 auto-commit skill 中 UI 交互和数据提交的具体操作方式。
4
+
5
+ ---
6
+
7
+ ## 全局规则
8
+
9
+ **⚠️ 全局静默要求:整个流程中 Agent 仅通过 `__interactive:` UI 组件与用户交互。除步骤 9 的最终结果文字外,Agent 禁止向用户输出任何文字内容,包括但不限于:**
10
+ - **过渡性话语**:如 "Now I have the data"、"Let me perform matching"、"让我分析一下"
11
+ - **内部分析过程**:如 "Card 26: xxx - Score: 95"、"Matching analysis:"、匹配评分细节
12
+ - **状态说明**:如 "has_good_match: true"、"Cards sorted by score"
13
+ - **JSON 数据或代码片段**
14
+
15
+ **Agent 应在内部完成所有思考后,直接调用对应的 `run_command`,不在工具调用之间输出任何文字。**
16
+
17
+ **⚠️ 重要:所有 `run_command` 调用(`__interactive:` 除外)必须加 `__silent:` 前缀。唯一例外是步骤 9 的 git commit 命令,需要展示提交结果给用户。**
18
+
19
+ **⚠️ 禁止额外命令:Agent 不得在流程步骤之外自行执行任何 shell 命令(如 `git status`、`ls` 等)。iCafe 数据由步骤 1 的 Python 脚本获取,git diff 由步骤 2 中 Agent 按规定命令获取。**
20
+
21
+ **⚠️ 工作目录规则:Skill 执行时的工作目录可能不是用户项目目录。当命令需要在用户项目目录下执行时(如 git 操作、Python 脚本),必须在命令中加 `cd <用户项目目录> &&` 切换目录。但 `__silent:` 或 `__interactive:` 前缀必须始终在命令最开头。**
22
+
23
+ **⚠️ 多 Workspace 规则:用户可能打开了多个代码库(multi-root workspace)。环境上下文中的 `Workspace Path` 会列出所有 workspace 路径。在步骤 2 和步骤 8 中,Agent 必须对每个 workspace 分别执行 git 命令,不可只处理第一个 workspace 后忽略其余的。**
24
+
25
+ 正确格式:
26
+ ```
27
+ __silent: cd /path/to/project && git add .
28
+ __interactive:icafe-cards {...}
29
+ ```
30
+
31
+ 错误格式(禁止):
32
+ ```
33
+ cd /path/to/project && __silent: git add .
34
+ cd /path/to/project && __interactive:icafe-cards {...}
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 步骤 1:获取 iCafe 数据
40
+
41
+ 使用 SKILL.md 步骤 1 中定义的命令模板执行。
42
+
43
+ ---
44
+
45
+ ## 步骤 2:获取 git diff
46
+
47
+ 使用 SKILL.md 步骤 2 中定义的命令模板执行。
48
+
49
+ ---
50
+
51
+ ## 步骤 4:展示卡片选择
52
+
53
+ ### 4a. 构造并通过脚本验证 payload
54
+
55
+ **⚠️ 不需要手动转换 snake_case/camelCase,不需要拼 JSON,不需要传文件路径。** 脚本自动读取步骤 1 留下的缓存文件,Agent 只需传入简单的 CLI 参数。
56
+
57
+ ```bash
58
+ __silent: python3 <skill_directory>/scripts/build_icafe_cards_payload.py --view-mode list --default-title "优化 xxx 相关功能"
59
+ ```
60
+
61
+ 参数说明:
62
+ - `--view-mode`(必填):`list` 或 `create`,由步骤 3 确定
63
+ - `--default-title`(必填):Agent 根据 diff 语义生成的推荐标题
64
+ - `--cards`(可选):排序后的 cards JSON 数组,不传则使用 result 中的原始顺序
65
+ - `--result-file`(可选):默认读取 `/tmp/__comate_icafe_result.json`(步骤 1 自动写入)
66
+
67
+ **脚本自动从缓存文件读取所有数据并完成 snake_case → camelCase 转换,Agent 不需要手动处理任何字段名。**
68
+
69
+ ### 4b. 解析脚本输出并调用 UI
70
+
71
+ **如果脚本返回 `{"valid": true, "payload": {...}}`:**
72
+
73
+ **⚠️ 必须提取 `payload` 字段的值(内层 JSON),使用 `run_command` 工具调用 UI,禁止将 payload 作为文本输出给用户。**
74
+
75
+ 例如脚本返回:
76
+ ```json
77
+ {"valid": true, "payload": {"cards": [...], "spacePrefix": "dkx", ...}}
78
+ ```
79
+ 则调用:
80
+ ```
81
+ run_command(command="__interactive:icafe-cards {\"cards\": [...], \"spacePrefix\": \"dkx\", ...}")
82
+ ```
83
+ **禁止**(作为文本输出或传入错误数据):
84
+ ```
85
+ __interactive:icafe-cards {"valid": true, "payload": {"cards": [...], ...}}
86
+ ```
87
+
88
+ **如果脚本返回 `{"valid": false, "errors": [...]}`:**
89
+
90
+ 根据 `errors` 中的具体描述修正数据,重新调用脚本(最多重试 1 次)。如果重试后仍返回 `valid: false`,或脚本返回 `{"error": "..."}`,则**降级为文本交互**(见下方降级格式)。
91
+
92
+ ---
93
+
94
+ ## 步骤 5:处理用户操作
95
+
96
+ UI 组件返回 JSON,可能的 action 值:
97
+
98
+ | action | 含义 | 处理方式 |
99
+ |--------|------|----------|
100
+ | `select` | 选择已有卡片 | 保存 `card` 中的卡片信息,继续步骤 7 |
101
+ | `recognize` | 链接或卡片 ID 识别 | 调用 `recognize_card_cli.py` 获取卡片详情,继续步骤 7 |
102
+ | `create` | 新建卡片 | 调用 `create_card_cli.py` 创建卡片,继续步骤 7 |
103
+ | `skip` | 跳过 | 输出"已跳过卡片绑定和代码提交。",**结束 skill** |
104
+ | `do_not_show_again` | 不再提示 | 输出"已关闭推荐卡片提示。",**结束 skill** |
105
+
106
+ **recognize 处理:**
107
+ ```
108
+ __silent: cd <用户项目目录> && python3 <skill_directory>/scripts/recognize_card_cli.py --link "<用户返回的link>"
109
+ ```
110
+
111
+ **create 处理:**
112
+
113
+ 使用 SKILL.md 步骤 5 中定义的「创建卡片命令模板」,**加 `__silent:` 前缀**执行。
114
+
115
+ ---
116
+
117
+ ## 步骤 8:展示提交确认
118
+
119
+ ### 8a. 构造并通过脚本验证 payload
120
+
121
+ **推荐:使用缓存模式**(脚本自动从缓存读取 diff、执行 git branch 获取分支信息):
122
+
123
+ ```bash
124
+ __silent: python3 <skill_directory>/scripts/build_git_commit_payload.py --cache --commit-message "<commitMessage>" --bound-card '<boundCard JSON 或 null>'
125
+ ```
126
+
127
+ 参数说明:
128
+ - `--commit-message`(必填):iCode 仓库格式 `"<spacePrefix>-<sequence> <描述>"`;非 iCode 仓库不带卡片 ID
129
+ - `--bound-card`(必填):步骤 5 选定的卡片对象 JSON,无卡片时传字符串 `'null'`
130
+
131
+ **⚠️ 所有命令必须带 `__silent:` 前缀(`__interactive:` 除外)。**
132
+
133
+ ### 8b. 解析脚本输出并调用 UI
134
+
135
+ **如果脚本返回 `{"valid": true, "payload": {...}}`:**
136
+
137
+ **⚠️ 必须提取 `payload` 字段的值(内层 JSON),使用 `run_command` 工具调用 UI,禁止将 payload 作为文本输出给用户。**
138
+
139
+ 例如脚本返回:
140
+ ```json
141
+ {"valid": true, "payload": {"commitMessage": "dkx-200 fix", "boundCard": {...}, "workspaces": [...]}}
142
+ ```
143
+ 则调用:
144
+ ```
145
+ run_command(command="__interactive:git-commit {\"commitMessage\": \"dkx-200 fix\", \"boundCard\": {...}, \"workspaces\": [...]}")
146
+ ```
147
+ **禁止**(作为文本输出或传入错误数据):
148
+ ```
149
+ __interactive:git-commit {"valid": true, "payload": {"commitMessage": "dkx-200 fix", ...}}
150
+ ```
151
+
152
+ **如果脚本返回 `{"valid": false, "errors": [...]}`:**
153
+
154
+ 根据 `errors` 中的具体描述修正数据,重新调用脚本(最多重试 1 次)。如果重试后仍返回 `valid: false`,或脚本返回 `{"error": "..."}`,则**降级为文本交互**(见下方降级格式)。
155
+
156
+ 用户操作后,tool output 返回 JSON:
157
+ - 确认提交:`{"action": "submit", "repos": [{"workspace": "...", "commitMessage": "...", "branch": "..."}]}`
158
+ - 取消提交:`{"action": "cancel"}`
159
+
160
+ ---
161
+
162
+ ## 步骤 9:执行提交
163
+
164
+ 从 tool output 解析用户操作:
165
+
166
+ **如果是 action === "submit":**
167
+
168
+ UI 返回的结果格式:
169
+ ```json
170
+ {"action": "submit", "repos": [{"workspace": "/path/to/repo", "commitMessage": "dkx-200 修复...", "branch": "feature/xxx"}]}
171
+ ```
172
+
173
+ Agent 收到后,对 `repos` 数组中的每个仓库自主决定执行方式:
174
+ - `cd` 到对应 workspace 目录
175
+ - 执行 `git add .`、`git commit -m "<commitMessage>"`(git commit 命令不使用 `__silent:`,展示提交结果给用户)
176
+ - 如果用户选择了特定分支且不是当前分支,先 `git checkout` 切换
177
+ - **推送方式根据仓库类型区分:**
178
+ - 统一使用 `git push origin HEAD:refs/for/<branch>` 推送到 Gerrit 代码评审
179
+ - 多仓库时逐个执行,每个仓库独立处理
180
+
181
+ **如果是 action === "cancel":**
182
+ - 输出"已取消提交"
183
+
184
+ ---
185
+
186
+ ## 降级文本交互格式
187
+
188
+ 当 builder 脚本验证失败且重试仍失败,或脚本返回系统错误时,Agent 降级为纯文本交互。
189
+
190
+ ### 步骤 4 降级(卡片选择)
191
+
192
+ ```
193
+ 请选择要绑定的 iCafe 卡片(回复编号):
194
+
195
+ 1. dkx-200 修复登录问题 [Bug] [开发中]
196
+ 2. dkx-198 新增导出功能 [Story] [待开发]
197
+ 3. dkx-195 优化查询性能 [Task] [进行中]
198
+
199
+ 回复 N 选择对应卡片,或回复卡片链接/ID,或回复 "新建" 创建卡片,回复 "跳过" 跳过。
200
+ ```
201
+
202
+ 用户回复后,Agent 按步骤 5 的规则处理对应操作。
203
+
204
+ ### 步骤 8 降级(提交确认)
205
+
206
+ ```
207
+ 📝 提交确认
208
+
209
+ Commit Message: dkx-200 修复登录问题
210
+ 绑定卡片: dkx-200 修复登录问题 (Bug)
211
+
212
+ 变更文件:
213
+ - frontend-app: 2 files, +100, -78
214
+ - src/App.tsx (+76, -66)
215
+ - src/utils.ts (+24, -12)
216
+
217
+ 回复 "确认" 提交代码,回复 "取消" 放弃提交。
218
+ ```
219
+
220
+ 用户回复后,Agent 按步骤 9 的规则处理对应操作。