@jspg-ai/coding-bb 0.0.2-beta.29 → 0.0.3-beta.12

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 (107) hide show
  1. package/cbb/bin/cbbm.js +1 -1
  2. package/cbb/dev-standards/rules/cbb-ai-behavior.md +118 -103
  3. package/cbb/lib/install/claude-code.js +1 -3
  4. package/cbb/lib/install/codebuddy.js +30 -0
  5. package/cbb/lib/install/init.js +354 -305
  6. package/cbb/lib/install/opencode.js +35 -31
  7. package/cbb/lib/install/qoder.js +1 -3
  8. package/cbb/lib/install/rule-rewrite.js +27 -0
  9. package/cbb/lib/install/trae.js +33 -0
  10. package/cbb/lib/install/workspaces.js +24 -0
  11. package/cbb/lib/openspec/index.js +337 -554
  12. package/cbb/lib/superpowers/index.js +246 -265
  13. package/cbb/lib/utils/check-update.js +9 -2
  14. package/cbb/lib/utils/gitignore.js +2 -0
  15. package/cbb/lib/utils/settings.js +17 -4
  16. package/cbb/lib/utils/tar.js +92 -0
  17. package/cbb/lib/utils/upstream.js +90 -0
  18. package/cbb/worktrees/skills/cbb-worktree-close/SKILL.md +33 -24
  19. package/cbb/worktrees/skills/cbb-worktree-close/scripts/check-env.js +4 -4
  20. package/cbb/worktrees/skills/cbb-worktree-close/scripts/remove-worktrees.js +2 -2
  21. package/cbb/worktrees/skills/cbb-worktree-init/SKILL.md +61 -78
  22. package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-env-deep.js +3 -33
  23. package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-env.js +5 -14
  24. package/cbb/worktrees/skills/cbb-worktree-init/scripts/create-worktrees.js +15 -37
  25. package/cbb/worktrees/skills/cbb-worktree-init/scripts/update-gitignore.js +25 -9
  26. package/cbb/worktrees/skills/cbb-worktree-push/SKILL.md +67 -31
  27. package/config/openspec/schemas/spec-driven/schema.yaml +29 -30
  28. package/config/openspec/schemas/spec-driven/templates/design.md +0 -18
  29. package/config/openspec/schemas/spec-driven/templates/proposal.md +4 -3
  30. package/config/upstream-mirrors.json +12 -0
  31. package/config/workspace-agents.sample.md +17 -13
  32. package/config/workspaces.json +5 -0
  33. package/openspec/.version +2 -3
  34. package/openspec/commands/apply.md +189 -175
  35. package/openspec/commands/archive.md +237 -216
  36. package/openspec/commands/bulk-archive.md +355 -327
  37. package/openspec/commands/continue.md +116 -105
  38. package/openspec/commands/explore.md +230 -199
  39. package/openspec/commands/ff.md +115 -104
  40. package/openspec/commands/new.md +74 -63
  41. package/openspec/commands/onboard.md +557 -548
  42. package/openspec/commands/propose.md +161 -150
  43. package/openspec/commands/sync.md +277 -249
  44. package/openspec/commands/update.md +92 -80
  45. package/openspec/commands/verify.md +175 -162
  46. package/openspec/skills/openspec-apply-change/SKILL.md +20 -5
  47. package/openspec/skills/openspec-archive-change/SKILL.md +30 -8
  48. package/openspec/skills/openspec-bulk-archive-change/SKILL.md +36 -6
  49. package/openspec/skills/openspec-continue-change/SKILL.md +14 -2
  50. package/openspec/skills/openspec-explore/SKILL.md +21 -9
  51. package/openspec/skills/openspec-ff-change/SKILL.md +14 -2
  52. package/openspec/skills/openspec-new-change/SKILL.md +13 -1
  53. package/openspec/skills/openspec-onboard/SKILL.md +49 -39
  54. package/openspec/skills/openspec-propose/SKILL.md +15 -3
  55. package/openspec/skills/openspec-sync-specs/SKILL.md +31 -2
  56. package/openspec/skills/openspec-update-change/SKILL.md +27 -14
  57. package/openspec/skills/openspec-verify-change/SKILL.md +17 -3
  58. package/package.json +2 -2
  59. package/superpowers/.version +4 -4
  60. package/superpowers/skills/brainstorming/SKILL.md +47 -12
  61. package/superpowers/skills/brainstorming/scripts/frame-template.html +213 -213
  62. package/superpowers/skills/brainstorming/scripts/server.cjs +723 -723
  63. package/superpowers/skills/brainstorming/visual-companion.md +6 -6
  64. package/superpowers/skills/diagnosing-superpowers/SKILL.md +120 -0
  65. package/superpowers/skills/diagnosing-superpowers/prompts/analyst-common.md +38 -0
  66. package/superpowers/skills/diagnosing-superpowers/prompts/cost-and-time.md +28 -0
  67. package/superpowers/skills/diagnosing-superpowers/prompts/plan-adherence.md +29 -0
  68. package/superpowers/skills/diagnosing-superpowers/prompts/quality-evidence.md +26 -0
  69. package/superpowers/skills/diagnosing-superpowers/prompts/repeated-work.md +30 -0
  70. package/superpowers/skills/diagnosing-superpowers/prompts/request-conflicts.md +20 -0
  71. package/superpowers/skills/diagnosing-superpowers/prompts/scrub-audit.md +33 -0
  72. package/superpowers/skills/diagnosing-superpowers/prompts/scrub.md +29 -0
  73. package/superpowers/skills/diagnosing-superpowers/prompts/similar-session.md +38 -0
  74. package/superpowers/skills/diagnosing-superpowers/prompts/skill-timeline.md +30 -0
  75. package/superpowers/skills/diagnosing-superpowers/prompts/stumbles.md +28 -0
  76. package/superpowers/skills/diagnosing-superpowers/references/context-safety.md +22 -0
  77. package/superpowers/skills/diagnosing-superpowers/references/github-issues.md +47 -0
  78. package/superpowers/skills/diagnosing-superpowers/references/redaction-policy.md +34 -0
  79. package/superpowers/skills/diagnosing-superpowers/references/session-discovery.md +31 -0
  80. package/superpowers/skills/diagnosing-superpowers/templates/bundle-README.md +77 -0
  81. package/superpowers/skills/diagnosing-superpowers/templates/case.md +64 -0
  82. package/superpowers/skills/diagnosing-superpowers/templates/issue.md +51 -0
  83. package/superpowers/skills/diagnosing-superpowers/templates/report.md +82 -0
  84. package/superpowers/skills/executing-plans/SKILL.md +350 -41
  85. package/superpowers/skills/executing-plans/scripts/task-done +52 -0
  86. package/superpowers/skills/executing-plans/scripts/task-start +28 -0
  87. package/superpowers/skills/requesting-code-review/SKILL.md +1 -1
  88. package/superpowers/skills/requesting-code-review/code-reviewer.md +17 -0
  89. package/superpowers/skills/subagent-driven-development/SKILL.md +18 -18
  90. package/superpowers/skills/subagent-driven-development/re-review-prompt.md +1 -1
  91. package/superpowers/skills/subagent-driven-development/scripts/review-package +53 -46
  92. package/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +82 -40
  93. package/superpowers/skills/subagent-driven-development/scripts/task-brief +43 -41
  94. package/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +2 -2
  95. package/superpowers/skills/systematic-debugging/root-cause-tracing.md +1 -1
  96. package/superpowers/skills/test-driven-development/SKILL.md +10 -0
  97. package/superpowers/skills/using-superpowers/SKILL.md +2 -0
  98. package/superpowers/skills/using-superpowers/references/claude-code-tools.md +29 -0
  99. package/superpowers/skills/using-superpowers/references/muse-tools.md +35 -0
  100. package/superpowers/skills/writing-plans/SKILL.md +30 -9
  101. package/superpowers/skills/writing-skills/SKILL.md +4 -2
  102. package/superpowers/skills/writing-skills/graphviz-conventions.dot +171 -171
  103. package/cbb/worktrees/commands/worktree-close.md +0 -64
  104. package/cbb/worktrees/commands/worktree-init.md +0 -55
  105. package/cbb/worktrees/commands/worktree-push.md +0 -42
  106. package/cbb/worktrees/skills/cbb-worktree-init/scripts/auto-open.js +0 -136
  107. package/cbb/worktrees/skills/cbb-worktree-init/scripts/install-ai.js +0 -177
@@ -1,12 +1,6 @@
1
1
  ---
2
2
  name: cbb-worktree-init
3
3
  description: "为一个需求在 workspace 与各关联应用仓库(= workspace-config.json 全量 apps)同步创建同名物理 git worktree,直聚在 `.worktrees/worktree-<需求名>/` 下。触发:用户明确要求创建需求工作空间/开发隔离环境,或为已有需求补齐新增应用(重跑本技能即幂等)。禁止自动串联 cbb-worktree-close——除非用户明确说了要关闭。"
4
- license: MIT
5
- compatibility: Requires git (>=2.30) and Node.js (>=16.7.0). All commands are pure Node.js scripts under `scripts/`, fully cross-platform (Windows / macOS / Linux, bash / PowerShell / Git Bash).
6
- metadata:
7
- author: Contributors
8
- version: "2.0"
9
- generatedBy: coding-bb
10
4
  ---
11
5
 
12
6
  # Init Worktree(跨平台脚本化版本 v2.0)
@@ -28,13 +22,18 @@ metadata:
28
22
 
29
23
  ## 调用脚本的统一方式
30
24
 
31
- **重要**:所有脚本必须用**绝对路径**调用。`./scripts/...` 相对路径在 Qoder 沙箱中不适用(AI agent 的 cwd 不一定是技能目录)。
25
+ **重要**:本技能的所有脚本位于**本 SKILL.md 所在目录的 `scripts/` 下**(skill 目录)。
32
26
 
33
- 调用方式(推荐用绝对路径):
34
- ```
35
- node "D:\workspace\<用户工作空间>\.qoder\skills\cbb-worktree-init\scripts\<name>.js" <参数>
27
+ 调用时用**本技能目录的绝对路径**拼接脚本名(AI 读取本 SKILL.md 时即已知该目录),例如:
28
+
29
+ ```bash
30
+ node "<skill_dir>/scripts/<name>.js" <参数>
36
31
  ```
37
32
 
33
+ > - `<skill_dir>` = 本 SKILL.md 所在目录的绝对路径(AI 从读取路径即可推出)
34
+ > - **cwd 必须保持在工作空间根目录**:脚本按 cwd 定位 `workspace-config.json` 与 git 仓库
35
+ > - 不要用 `./scripts/...` 裸相对路径(AI 的 cwd 不是技能目录,会解析失败)
36
+
38
37
  脚本输出:
39
38
  - 人类可读报告(OK / FAIL / WARN)
40
39
  - 机器可读摘要(末行以 XXX_OK / XXX_FAILED / XXX_RESULT 开头)
@@ -54,20 +53,20 @@ node "D:\workspace\<用户工作空间>\.qoder\skills\cbb-worktree-init\scripts\
54
53
  ### 0.1 环境健康探活
55
54
 
56
55
  ```bash
57
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/check-env.js"
56
+ node "<skill_dir>/scripts/check-env.js"
58
57
  ```
59
58
 
60
59
  **解读输出**:
61
60
  - 退出码 0 + 末行 `ENV_OK {...}` → 探活通过,继续
62
- - 退出码 1 → git 不可用(沙箱 DLL 问题),**终止流程,提示用户到系统终端重试**
61
+ - 退出码 1 → git 不可用(运行环境 DLL 问题),**终止流程,提示用户到系统终端重试**
63
62
  - 退出码 2 → 当前不在 git 仓库,**终止流程,提示用户到工作空间根目录**
64
63
 
65
64
  ### 0.1.5 环境健康自检(check-env-deep)
66
65
 
67
- 提前检测网络/权限/版本问题,把可能在 Step 3.4 push 或 Step 4 install-ai 暴露的失败前移到流程最开始:
66
+ 提前检测权限/版本问题,把可能在后续步骤暴露的失败前移到流程最开始:
68
67
 
69
68
  ```bash
70
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/check-env-deep.js"
69
+ node "<skill_dir>/scripts/check-env-deep.js"
71
70
  ```
72
71
 
73
72
  **解读输出**:
@@ -76,14 +75,12 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/check-env-d
76
75
 
77
76
  **检测项**:
78
77
  - Node.js >= 16.7.0
79
- - npm 官方源可达(`https://registry.npmjs.org`)
80
- - cbb 是否已安装(未安装仅警告,由 Step 4 自动安装)
81
78
  - `.worktrees/` 目录可写
82
79
 
83
80
  ### 0.2 读取并校验 workspace-config.json
84
81
 
85
82
  ```bash
86
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/parse-config.js"
83
+ node "<skill_dir>/scripts/parse-config.js"
87
84
  ```
88
85
 
89
86
  **解读输出**:
@@ -150,7 +147,7 @@ worktree 需要知道要关联哪些应用仓库。
150
147
 
151
148
  ```bash
152
149
  # ws_root 来自 AI agent 维护的状态
153
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/sync-repos.js" "<ws_root>"
150
+ node "<skill_dir>/scripts/sync-repos.js" "<ws_root>"
154
151
  ```
155
152
 
156
153
  **用法**:
@@ -194,7 +191,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/sync-repos.
194
191
  | 当前在主分支上 | ✅ | ❌ |
195
192
 
196
193
  ```bash
197
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/check-repos.js" "<ws_root>"
194
+ node "<skill_dir>/scripts/check-repos.js" "<ws_root>"
198
195
  ```
199
196
 
200
197
  **解读输出**:
@@ -222,21 +219,23 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/check-repos
222
219
  ### 3.2 安全更新 .gitignore(前置)
223
220
 
224
221
  ```bash
225
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/update-gitignore.js "<ws_root>" "<branch>"
222
+ node "<skill_dir>/scripts/update-gitignore.js" "<ws_root>" "<branch>"
226
223
  ```
227
224
 
228
- 脚本内部自动完成:stash 保护 → 切分支 → 添加 `.worktrees/` 和 `.codespace/` → 提交 → 切回 → pop stash
225
+ 脚本内部自动完成:stash 保护 → 分支不存在则从 HEAD 创建 → 切分支 → 添加 `.worktrees/` 和 `.codespace/` → 提交 → 切回 → pop stash
229
226
 
230
227
  **解读输出**:
231
228
  - 退出码 0 + 末行 `GITIGNORE_OK` → 成功
232
229
  - 退出码 2 → 执行失败,**终止流程**
233
230
 
234
- > ⚠️ 必须在提交后切回主分支,否则 Step 3.4 `git worktree add` 会因分支已检出而失败(脚本已自动处理)。
231
+ > **分支自动创建**:本步骤先于 Step 3.3 执行,workspace 分支此时不存在,脚本会自动从 HEAD 创建(与 `create-branches.js` workspace 的行为一致,Step 3.3 报 `reused`)。`.gitignore` 提交正好落在需求分支上,由 Step 3.4 push 一并推送。
232
+
233
+ > ⚠️ 必须在提交后切回主分支,否则 Step 3.5 的 `git worktree add` 会因分支已检出而失败(脚本已自动处理)。
235
234
 
236
235
  ### 3.3 创建分支
237
236
 
238
237
  ```bash
239
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/create-branches.js" "<ws_root>" "<branch>"
238
+ node "<skill_dir>/scripts/create-branches.js" "<ws_root>" "<branch>"
240
239
  ```
241
240
 
242
241
  **解读输出**:
@@ -261,7 +260,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/create-bran
261
260
  ### 3.4 推送并建立 upstream
262
261
 
263
262
  ```bash
264
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/push-branches.js" "<ws_root>" "<branch>"
263
+ node "<skill_dir>/scripts/push-branches.js" "<ws_root>" "<branch>"
265
264
  ```
266
265
 
267
266
  脚本内部自动完成:
@@ -286,20 +285,20 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/push-branch
286
285
 
287
286
  **为什么 push 放在 worktree 之前:** 失败早暴露,无 worktree 损失;成功后再创建 worktree,分支天然有 upstream;独立脚本便于单测。
288
287
 
289
- ### 3.5 创建 Worktree(含自愈清理)
288
+ ### 3.5 创建 Worktree
290
289
 
291
290
  ```bash
292
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/create-worktrees.js" "<ws_root>" "<branch>"
291
+ node "<skill_dir>/scripts/create-worktrees.js" "<ws_root>" "<branch>"
293
292
  ```
294
293
 
295
294
  脚本内部自动完成:
296
- 1. **自愈清理**:`git worktree prune` + 物理目录清理(close IDE 锁未能删除的物理目录)
295
+ 1. **元数据自愈**:仅 `git worktree prune`(清理"目录已缺失/失效"的注册项);**绝不删除任何物理目录**(0.0.3-beta.11 起——旧版"清理无元数据残留目录"因 Windows 路径分隔符不匹配会误删活跃 worktree,已整体移除)
297
296
  2. **workspace worktree 创建**:`git worktree add .worktrees/worktree-<branch> <branch>`
298
297
  3. **app worktree 创建**(物理嵌套在 workspace worktree 内)
299
298
 
300
299
  **解读输出**:
301
- - 退出码 0 + 末行 `WT_PATH <绝对路径>` → 全部成功,AI 解析出 worktree 绝对路径供后续 Step 4/5 使用
302
- - 退出码 2 → workspace worktree 创建失败(分支已检出/权限不足),**终止流程**
300
+ - 退出码 0 + 末行 `WT_PATH <绝对路径>` → 全部成功,AI 解析出 worktree 绝对路径供后续 Step 4 使用
301
+ - 退出码 2 → workspace worktree 创建失败(分支已检出/权限不足),或目标目录存在但非有效 worktree(上次 close 被 IDE 锁残留)——**终止流程**,按脚本提示引导用户跑 `cbb-worktree-close` 或手动删除该目录 + `git worktree prune` 后重跑
303
302
  - 退出码 3 → 部分 app worktree 创建失败,**报告已创建/失败详情,用户需手动清理**
304
303
 
305
304
  **报告示例**:
@@ -313,52 +312,38 @@ WT_PATH d:\workspace\xxx\.worktrees\worktree-feature-login
313
312
 
314
313
  > ⓘ **tracked 内容自动 checkout**:workspace 主分支 tracked 的所有内容(openspec/、cbb/ 等)在 workspace 工作树创建时**自动从 git 对象库 checkout**——**不需要 `cp`、`git clone` 或任何“带过来”动作**。各应用 worktree 同理。
315
314
 
316
- > ⓘ **AI 配置目录(.claude/、.qoder/ 等)**:workspace 主分支中这些目录通常为 gitignore'd,不会自动出现在 worktree 中。本 skill 在 Step 4 统一在 worktree 内执行 `cbbm init -y` 安装 AI 配置,无需依赖用户手动配置。
315
+ > ⓘ **AI 配置目录(.claude/、.qoder/、.opencode/ 等)**:统一安装在业务空间根(`cbb setup` / `cbb update`),**worktree 内不安装**;AI 会话始终以空间根为基础,开发动作指向本 worktree 路径。
317
316
 
318
317
  ---
319
318
 
320
- ## Step 4:安装 AI 配置(必要步骤)
321
-
322
- workspace 主分支的 `.claude/` `.qoder/` `.cbb/` 通常为 gitignore'd,创建 worktree 时不会自动带入。
323
- **本步骤在 worktree 内执行 `cbbm init --yes` 是必要步骤**——缺失 AI 配置会导致后续
324
- openspec-propose/apply/verify/ff 等技能全部不可用,worktree 将处于"半残"状态。
325
-
326
- > 与 push-branches(Step 3.4)一致:**本步骤失败将阻塞 init-worktree**,用户必须手动恢复后重跑。
327
-
328
- ```bash
329
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/install-ai.js "<wt_path>"
330
- ```
319
+ ## Step 4:收尾与交接(必要步骤)
331
320
 
332
- **解读输出**:
333
- - 退出码 0 + 末行 `AI_INIT_OK` → 成功,继续 Step 5
334
- - 退出码 1 → 参数错误(脚本 bug)
335
- - 退出码 2 + 末行 `AI_INIT_FAILED` → cbbm init 执行失败,**init-worktree 中断**,
336
- 按错误提示手动执行 `cd "<wt_path>" && cbbm init --yes` 后重跑
321
+ 不执行脚本。AI agent 向用户输出最终报告(格式见「最终报告」),并完成以下交接声明:
337
322
 
338
- > `-y` 表示非交互模式:默认选中所有适配器、前置依赖未安装时自动继续,适合 skill 自动化执行。
323
+ 1. **继续在当前会话开发**:本技能不打开新窗口;需求工作目录为 `<wt_path>`
324
+ 2. **目录纪律**:本会话后续所有产生写操作的命令(git commit / openspec / 构建 / 测试等)必须以 `<wt_path>`(或其应用子目录)为工作目录(显式 `cd` 或绝对路径);**禁止在空间根(主分支)执行任何写操作**
325
+ 3. 不自动安装依赖:各仓库技术栈不一(Maven 依赖本机 `~/.m2` 全局共享、无需初始化;Node/Python 等由你进入 worktree 后执行正确的命令,如 `npm ci` / `pnpm`)
326
+ 4. **输出下一步建议**:最终报告必须包含「下一步建议」段(格式见「最终报告」),告知用户后续可走的流程;仅提示,不自动串联执行任何后续技能
339
327
 
340
328
  ---
341
329
 
342
- ## Step 5:环境收尾
330
+ ## 最终报告
343
331
 
344
- 所有步骤完成后,检测当前运行环境,**在新窗口打开 IDE** 并定位到 workspace worktree 目录。
332
+ 最终报告格式:
345
333
 
346
- ```bash
347
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/auto-open.js "<wt_path>"
334
+ ```
335
+ worktree 已创建:<wt_path>
336
+ 关联应用:<应用名 → 嵌套路径> 列表
337
+ 📌 继续在当前会话开发:后续写操作命令一律以上述目录为工作目录
338
+ 👉 下一步建议:
339
+ 1. 开始需求开发(二选一):
340
+ - 走 OpenSpec 工作流:/opsx:propose → /opsx:apply → /opsx:verify → /opsx:archive
341
+ - 或直接对话开发:把需求告诉我,在 <wt_path> 内实现
342
+ 2. 开发中提交推送:说"提交并推送"(cbb-worktree-push)
343
+ 3. 需求完成后:说"关闭工作空间"(cbb-worktree-close)
348
344
  ```
349
345
 
350
- **解读末行**:
351
- - `ENV=QODER_GUI` / `CURSOR_GUI` / `VSCODE_GUI` / `JETBRAINS_GUI` → GUI 模式(已在新窗口打开 IDE)
352
- - `ENV=CLI` → CLI 模式(AI agent 自行 cd 到 wt_path)
353
- - `OPEN_FAILED` → 自动打开失败,提示用户手动操作
354
-
355
- ---
356
-
357
- ## 最终报告
358
-
359
- 最终报告由 AI agent 根据 `auto-open.js` 的末行输出生成,格式同 v1(GUI / CLI / OPEN_FAILED 三种)。
360
-
361
- > 不自动安装依赖:各仓库技术栈不一(Maven 依赖本机 `~/.m2` 全局共享、无需初始化;Node/Python 等由你进入 worktree 后执行正确的命令,如 `npm ci` / `pnpm`)。猜测安装命令易出错,故不在本步骤处理。
346
+ > 若 Step 3.5 为部分失败(退出码 3),报告必须列出已创建/失败详情与回滚清理命令。
362
347
 
363
348
  ---
364
349
 
@@ -370,7 +355,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/auto-open.j
370
355
  |------|----------|
371
356
  | 空间新增了应用(编辑 `workspace-config.json` 后) | Step 1 拉取新应用代码 → Step 3.3 为新应用建分支 → Step 3.4 推送(已一致的分支 `skipped`,不一致则阻塞询问)→ Step 3.5 创建缺失的嵌套 worktree |
372
357
  | 上次 init 中途失败 | 已存在的分支 / worktree 自动复用,`.gitignore` 处理自动跳过,仅补齐缺失部分 |
373
- | 应用从 config 移除 | 已创建的分支 / worktree **不会**自动删除;如需清理用 `/cbb:worktree-close` 关闭后重建 |
358
+ | 应用从 config 移除 | 已创建的分支 / worktree **不会**自动删除;如需清理用 `cbb-worktree-close` skill 关闭后重建 |
374
359
 
375
360
  > ⓘ 重跑**不会静默推送**开发中的本地提交:远程分支已存在但与本地不一致时,Step 3.4 走阻塞式 `remote-exists` 决策(展示 commit 元信息让用户选择)。
376
361
 
@@ -381,17 +366,17 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/auto-open.j
381
366
  | 场景 | 处理方式 |
382
367
  |------|----------|
383
368
  | `.worktrees/` 或 `.codespace/` 未在 `.gitignore` | workspace 仓库自动添加并提交(在 Step 3.2) |
384
- | `git worktree add` 权限被拒 | 沙箱降级,中断并告知用户 |
369
+ | `git worktree add` 权限被拒 | 运行环境降级,中断并告知用户 |
385
370
  | 状态检查任一失败 | 终止并报告所有问题 |
386
371
  | 部分应用 worktree 创建失败 | 提示已创建的回滚清理命令 |
387
372
  | workspace 主分支 tracked 内容(openspec/、cbb/ 等) | 自动 checkout 到工作树,无需额外动作(cp/clone 都是多余的) |
388
- | AI 配置目录(.claude/、.qoder/ 等) | gitignore'd,不在仓库中;**Step 4 是必要步骤**,执行 `cbbm init --yes` 自动安装(失败会阻塞 init-worktree |
373
+ | AI 配置目录(.claude/、.qoder/、.opencode/ 等) | 统一安装在空间根(`cbb setup` / `cbb update`);worktree 内不安装、也不需要 |
389
374
  | 需求名(同时作分支名和工作树目录名) | 用户在对话中纯文本输入,参考 Step 3.1 命名规则(kebab-case,禁 `..`、路径分隔符、空格) |
390
375
  | 关联应用范围 | 固定为 `workspace-config.json` 全量 apps(无勾选);增减应用后重跑本技能(幂等) |
391
- | 沙箱内 node 不可用 | 脚本 fail-fast 并提示用户到系统终端重试 |
376
+ | 运行环境 node 不可用 | 脚本 fail-fast 并提示用户到系统终端重试 |
392
377
  | push 失败(SSH/HTTPS/网络/保护) | push-branches.js 退出码 2,AI 阻塞并询问用户三选项(修复后重试/跳过失败仓库/完全终止) |
393
378
  | 远程分支已存在 | push-branches.js 输出 metadata,AI 展示 commit 元信息后询问两选项(关联/终止+重新创建) |
394
- | 开发过程中推送所有 worktree | Step 3.4 仅覆盖创建时的空 commit;开发过程中产生的提交必须调 `/cbb:worktree-push` 或 `cbb-worktree-push` skill 推送(详见该 skill) |
379
+ | 开发过程中推送所有 worktree | Step 3.4 仅覆盖创建时的空 commit;开发过程中产生的提交必须调 `cbb-worktree-push` skill 推送(详见该 skill) |
395
380
 
396
381
  ---
397
382
 
@@ -462,10 +447,10 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/auto-open.j
462
447
  - **问题:** 试图在 Bash 调用中嵌套 Node 脚本与 shell 变量,导致变量解析失败
463
448
  - **修复:** 所有脚本参数(`<ws_root>`、`<branch>`)由 AI agent 在对话上下文中维护,**作为字符串参数传入脚本**,不要在 Bash 命令中拼 shell 变量
464
449
 
465
- ### 把 install-ai 当作可失败步骤
450
+ ### 在空间根执行写操作命令
466
451
 
467
- - **问题:** 以为 worktree 创建成功就能继续工作,忽略了 Step 4 失败,导致后续 openspec-* 技能全部报"找不到 skill"
468
- - **修复:** Step 4 失败必须手动 `cd <wt_path> && cbbm init --yes`,然后重跑 init-worktree(脚本会自动跳过已初始化的部分)
452
+ - **问题:** worktree 创建成功后,会话仍在空间根运行 git commit / openspec / 构建命令,污染主分支或把变更产物生成在主分支上
453
+ - **修复:** Step 4 交接已声明需求工作目录 `<wt_path>`;所有写操作命令必须显式 `cd` 或用绝对路径指向 worktree
469
454
 
470
455
  ---
471
456
 
@@ -479,18 +464,18 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/auto-open.j
479
464
  - workspace 仓库创建工作树前不验证 `.worktrees/` 和 `.codespace/` 在 `.gitignore`
480
465
  - 用 `git checkout -b` 切分支后再建 worktree(分支检出冲突)
481
466
  - 用 `AskUserQuestion` 收集自由文本(需求名 / 分支选项等)
482
- - 沙箱内 node 不可用时强行继续 → 改为 fail-fast 提示用户
467
+ - 运行环境 node 不可用时强行继续 → 改为 fail-fast 提示用户
483
468
  - **Step 3.4 推送失败后跳过失败仓库直接继续** → 必须阻塞并询问用户决策
484
469
  - **远程分支已存在时脚本自动 set-upstream-to** → 必须由用户决策,避免关联到他人的同名分支
485
470
  - **AI 询问关联选项前不输出 commit 元信息** → 必须先在 AskUserQuestion 之前输出远程 hash/author/date/message + 本地 hash
486
- - **Step 4 install-ai 失败时强行继续** 必须阻塞并按错误提示恢复,AI 不得绕过退出码 2 继续执行
471
+ - **在空间根执行 git/openspec/构建等写操作命令**必须显式指定需求工作树路径(`<wt_path>` 或其应用子目录)
487
472
 
488
473
  **必须执行**
489
474
 
490
475
  - workspace 仓库标准检查(当前在主分支等),app 仓库轻量检查(fetch + `origin/main` 可用即可)
491
476
  - app 仓库分支从 `origin/main` 创建(`git branch <需求名> ${REMOTE}/${MAIN}`),不依赖本地主分支状态
492
477
  - 严格 Step 3.3 → Step 3.4 顺序(先统一创建分支,再统一创建 worktree;workspace 工作树先建,各应用按序补建)
493
- - 所有脚本调用以 `node "<WS_ROOT>\.qoder\skills\cbb-worktree-init\scripts\<name>.js" "<绝对路径>" "<branch>"` 形式发起(apps 由脚本内部从 workspace-config.json 读取),**不依赖跨调用的 cwd**
478
+ - 所有脚本调用以 `node "<skill_dir>/scripts/<name>.js" "<绝对路径>" "<branch>"` 形式发起(apps 由脚本内部从 workspace-config.json 读取);**执行时 cwd 保持在工作空间根**(`check-env.js` / `parse-config.js` 按 cwd 定位)
494
479
  - **Step 3.4 push 步骤必须执行且插入在 create-branches.js (3.3) 之后、create-worktrees.js (3.5) 之前** — 失败时阻塞整个 init-worktree 流程
495
480
  - **Step 3.4 仅覆盖创建 worktree 时的空 commit** — 开发过程中产生的本地 commit(如 apply 任务实现)必须由用户在 worktree 中手动提交并调 `cbb-worktree-push` 推送;不允许依赖 Step 3.4 之后的自动推送(不存在)
496
481
 
@@ -506,8 +491,6 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/auto-open.j
506
491
  | `check-repos.js` | 状态检查 | ws_root | 0/1/2 |
507
492
  | `update-gitignore.js` | 安全更新 .gitignore | ws_root, branch | 0/1/2 |
508
493
  | `create-branches.js` | 创建分支 | ws_root, branch | 0/1/2 |
509
- | `create-worktrees.js` | 创建 worktree(含自愈清理) | ws_root, branch | 0/1/2/3 |
510
- | `install-ai.js` | 安装 AI 配置(**必要步骤**) | wt_path | 0/1/2 |
494
+ | `create-worktrees.js` | 创建 worktree(仅 prune 元数据,不删物理目录) | ws_root, branch | 0/1/2/3 |
511
495
  | `push-branches.js` | 推送并建立 upstream(已一致则 skipped;带错误归类 + 元信息采集) | ws_root, branch | 0/1/2 |
512
- | `check-env-deep.js` | 环境健康自检(Node 版本 / npm 源 / 权限) | 无 | 0/2 |
513
- | `auto-open.js` | 环境感知自动打开(**新窗口**) | wt_path | 0(始终) |
496
+ | `check-env-deep.js` | 环境健康自检(Node 版本 / 权限) | 无 | 0/2 |
@@ -7,26 +7,15 @@ require('./silence-popup');
7
7
  *
8
8
  * 检测项:
9
9
  * 1. Node.js 版本(>= 16.7.0)
10
- * 2. npm 官方源可达性(https://registry.npmjs.org)
11
- * 3. cbb 是否已安装(未安装视为软警告,由 Step 4 自动安装)
12
- * 4. .worktrees/ 目录可写性
10
+ * 2. .worktrees/ 目录可写性
13
11
  *
14
12
  * 退出码:
15
13
  * 0 - 全部通过(DOCTOR_OK)
16
- * 2 - 致命问题(Node 版本 / npm 源 / 权限),必须修复后重试
14
+ * 2 - 致命问题(Node 版本 / 权限),必须修复后重试
17
15
  */
18
- const { execSync } = require('child_process');
19
16
  const fs = require('fs');
20
17
  const path = require('path');
21
18
 
22
- function run(cmd) {
23
- try {
24
- return { ok: true, out: execSync(cmd, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim() };
25
- } catch (e) {
26
- return { ok: false, err: (e.stderr || e.message || String(e)).trim() };
27
- }
28
- }
29
-
30
19
  let hasFatal = false;
31
20
 
32
21
  // ── 1. Node.js 版本 ──
@@ -40,26 +29,7 @@ if (nodeMajor < 16 || (nodeMajor === 16 && parseInt(nodeVersion.split('.')[1], 1
40
29
  console.log('✅ Node.js: ' + nodeVersion);
41
30
  }
42
31
 
43
- // ── 2. npm 内部源可达性 ──
44
- const npmPing = run('npm ping --registry=https://registry.npmjs.org');
45
- if (!npmPing.ok) {
46
- console.error('❌ npm 内部源不可达:' + npmPing.err);
47
- console.error(' → 检查代理设置:npm config get registry');
48
- console.error(' → 检查网络是否能访问 https://registry.npmjs.org');
49
- hasFatal = true;
50
- } else {
51
- console.log('✅ npm 官方源可达(https://registry.npmjs.org)');
52
- }
53
-
54
- // ── 3. cbbm 检测(软警告) ──
55
- const cbbInfo = run('cbbm --version');
56
- if (cbbInfo.ok) {
57
- console.log('✅ cbbm 已安装:' + cbbInfo.out);
58
- } else {
59
- console.log('⚠️ cbbm 未安装(Step 4 install-ai 会自动安装,软警告不阻塞)');
60
- }
61
-
62
- // ── 4. .worktrees 目录可写性 ──
32
+ // ── 2. .worktrees 目录可写性 ──
63
33
  const wsRoot = process.cwd();
64
34
  const wtDir = path.join(wsRoot, '.worktrees');
65
35
  try {
@@ -3,7 +3,7 @@ require('./silence-popup');
3
3
  /**
4
4
  * cbb-worktree-init 环境健康探活
5
5
  *
6
- * 提前发现 Qoder 沙箱 DLL 问题(0xc0000142)以及其他子进程启动失败。
6
+ * 提前发现 Agent 运行环境 DLL 问题(0xc0000142)以及其他子进程启动失败。
7
7
  * 失败时输出明确错误信息并以非零退出码终止,AI agent 据此决定是否继续。
8
8
  *
9
9
  * 跨平台:
@@ -38,7 +38,7 @@ const checks = {};
38
38
  checks.git = tryExec('git --version');
39
39
  if (!checks.git.ok) {
40
40
  console.error('❌ git 启动失败');
41
- console.error(' 可能是 Qoder 沙箱 DLL 问题(0xc0000142)');
41
+ console.error(' 可能是 Agent 运行环境 DLL 问题(0xc0000142)');
42
42
  console.error(' 解决方案:到系统终端(非 Qoder AI 终端)重新执行本技能');
43
43
  process.exit(1);
44
44
  }
@@ -61,27 +61,18 @@ if (!checks.node.ok) {
61
61
  console.log('✅ node OK:', checks.node.out);
62
62
  }
63
63
 
64
- // ── 选检:cbbm(Step 5 才需要) ────────────────────
65
- checks.cbbInfo = tryExec('cbbm --version');
66
- if (!checks.cbbInfo.ok) {
67
- console.log('ℹ️ cbbm 未全局安装(Step 5 会兜底自动安装)');
68
- } else {
69
- console.log('✅ cbbm OK:', checks.cbbInfo.out);
70
- }
71
-
72
- // ── 沙箱检测 ─────────────────────────────────────────
64
+ // ── 运行环境检测 ───────────────────────────────────────
73
65
  const inWorktree = !!(process.env.QODER_AGENT || process.env.QODER_WORKTREE);
74
66
  if (inWorktree) {
75
- console.log('🛡️ Qoder 沙箱环境:若后续 node/git DLL 错误,请到系统终端重试');
67
+ console.log('🛡️ Qoder Agent 运行环境:若后续 node/git DLL 错误,请到系统终端重试');
76
68
  } else {
77
- console.log('✅ 非沙箱环境:所有子进程以默认 PATH 运行');
69
+ console.log('✅ 系统终端环境:所有子进程以默认 PATH 运行');
78
70
  }
79
71
 
80
72
  // 输出机器可读摘要(AI agent 可解析)
81
73
  const summary = {
82
74
  git: checks.git.ok,
83
75
  node: checks.node.ok,
84
- cbbInfo: checks.cbbInfo.ok,
85
76
  inWorktree,
86
77
  ok: true,
87
78
  };
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  require('./silence-popup');
3
3
  /**
4
- * cbb-worktree-init 创建 Worktree(含自愈清理)
4
+ * cbb-worktree-init 创建 Worktree(自愈清理仅限元数据 prune)
5
5
  *
6
6
  * 用法:node create-worktrees.js <ws_root> <branch>
7
7
  * (apps 由脚本内部从 <ws_root>/workspace-config.json 读取)
8
8
  *
9
9
  * 行为:
10
- * 1. 自愈清理:prune + 物理目录清理
10
+ * 1. 自愈清理:仅 git worktree prune(元数据),**绝不删除任何物理目录**
11
+ * (0.0.3-beta.11 事故修复:旧版按"不在 worktree list"负向推断递归删残留目录,
12
+ * Windows 下 git 输出正斜杠路径与 realpathSync 反斜杠永不匹配,误删活跃 worktree)
11
13
  * 2. workspace worktree 创建(.worktrees/worktree-<branch>)
12
14
  * 3. 各 app worktree 创建(物理嵌套在 workspace worktree 内)
13
15
  * 4. 失败时输出回滚提示
@@ -15,7 +17,7 @@ require('./silence-popup');
15
17
  * 退出码:
16
18
  * 0 - 全部成功
17
19
  * 1 - 参数错误
18
- * 2 - workspace worktree 创建失败
20
+ * 2 - workspace worktree 创建失败(含目标目录存在但非有效 worktree 的残留场景)
19
21
  * 3 - 部分 app worktree 创建失败
20
22
  */
21
23
 
@@ -54,52 +56,28 @@ function run(cmd, cwd) {
54
56
  }
55
57
  }
56
58
 
57
- // 1. 自愈清理
58
- console.log('=== 自愈清理 ===');
59
+ // 1. 自愈清理(仅元数据:prune 只清理"目录已缺失/失效"的 worktree 注册项,不碰物理目录)
60
+ console.log('=== 自愈清理(仅 prune 元数据,不删物理目录)===');
59
61
 
60
- // 1.1 prune 所有仓库
61
62
  const allRepos = [wsRoot, ...apps.map(a => path.join(wsRoot, '.codespace', a.name))];
62
63
  for (const repo of allRepos) {
63
64
  if (fs.existsSync(repo)) {
64
65
  run('git worktree prune', repo);
65
66
  }
66
67
  }
67
- console.log('✅ 已 prune 所有仓库的 worktree 元数据');
68
-
69
- // 1.2 清理 .worktrees/ 下无元数据的物理目录
70
- const worktreesDir = path.join(wsRoot, '.worktrees');
71
- if (fs.existsSync(worktreesDir)) {
72
- const validWts = run('git worktree list --porcelain', wsRoot);
73
- const validPaths = new Set();
74
- if (validWts.ok) {
75
- validWts.out.split('\n').forEach(line => {
76
- if (line.startsWith('worktree ')) {
77
- validPaths.add(line.substring(9).trim());
78
- }
79
- });
80
- }
81
-
82
- const entries = fs.readdirSync(worktreesDir, { withFileTypes: true });
83
- for (const entry of entries) {
84
- if (!entry.isDirectory()) continue;
85
- const dir = path.join(worktreesDir, entry.name);
86
- let absDir;
87
- try { absDir = fs.realpathSync(dir); } catch { continue; }
88
- if (!validPaths.has(absDir)) {
89
- try {
90
- fs.rmSync(dir, { recursive: true, force: true });
91
- console.log('🧹 已清理残留目录:' + entry.name);
92
- } catch (e) {
93
- console.log('⏳ 残留目录仍被占用,跳过:' + entry.name);
94
- }
95
- }
96
- }
97
- }
68
+ console.log('✅ 已 prune 所有仓库的 worktree 元数据(物理目录一律保留)');
98
69
 
99
70
  // 2. workspace worktree 创建
100
71
  console.log('=== 创建 Workspace Worktree ===');
101
72
  const wtDir = path.join(wsRoot, '.worktrees', 'worktree-' + branch);
102
73
  if (fs.existsSync(wtDir)) {
74
+ if (!fs.existsSync(path.join(wtDir, '.git'))) {
75
+ console.error('❌ 目标目录已存在但不是有效 worktree(缺 .git 指针):' + wtDir);
76
+ console.error(' 可能是上次 close / init 中断的残留。本脚本不会自动删除任何目录,请二选一后重跑:');
77
+ console.error(' 1) 执行 cbb-worktree-close 技能清理该需求');
78
+ console.error(' 2) 手动删除上述目录后执行:git -C "' + wsRoot + '" worktree prune');
79
+ process.exit(2);
80
+ }
103
81
  console.log('⏭️ workspace worktree 已存在,复用:' + wtDir);
104
82
  } else {
105
83
  const created = run('git worktree add ".worktrees/worktree-' + branch + '" "' + branch + '"', wsRoot);
@@ -6,13 +6,13 @@ require('./silence-popup');
6
6
  * 用法:node update-gitignore.js <ws_root> <branch>
7
7
  *
8
8
  * 行为:
9
- * 1. stash 当前未提交修改
10
- * 2. 切换到目标分支
11
- * 3. 检查 .worktrees/ 和 .codespace/ 是否在 .gitignore
12
- * 4. 添加缺失条目
13
- * 5. 提交 .gitignore
14
- * 6. 切回原分支
15
- * 7. pop stash(如有)
9
+ * 1. stash 当前未提交修改(仅 untracked 时不产生 stash)
10
+ * 2. 目标分支不存在则从 HEAD 创建(首跑时分支尚未由 create-branches.js 建立,
11
+ * 顺序无关自愈;create-branches.js 后续会报 reused)
12
+ * 3. 切换到目标分支
13
+ * 4. 检查 .worktrees/ 和 .codespace/ 是否在 .gitignore,缺失则添加并提交
14
+ * 5. 切回原分支
15
+ * 6. pop stash(如有)
16
16
  *
17
17
  * 幂等:目标分支已在某个 worktree 中检出(init-worktree 重跑场景,上次已处理过
18
18
  * .gitignore)时,跳过全部操作直接输出 GITIGNORE_OK——避免 checkout 与 worktree 检出冲突。
@@ -67,8 +67,12 @@ const status = run('git status --porcelain', wsRoot);
67
67
  if (status.ok && status.out) {
68
68
  const stash = run('git stash push -m "init-worktree-temp"', wsRoot);
69
69
  if (stash.ok) {
70
- stashed = true;
71
- console.log(' stash 未提交修改');
70
+ if (/No local changes to save/.test(stash.out)) {
71
+ console.log('ℹ️ 仅 untracked 文件,无需 stash');
72
+ } else {
73
+ stashed = true;
74
+ console.log('✅ 已 stash 未提交修改');
75
+ }
72
76
  } else {
73
77
  console.error('❌ git stash 失败:' + stash.err);
74
78
  process.exit(2);
@@ -77,6 +81,18 @@ if (status.ok && status.out) {
77
81
  console.log('ℹ️ 无未提交修改,跳过 stash');
78
82
  }
79
83
 
84
+ // 2.1 目标分支不存在则从 HEAD 创建(Step 3.2 先于 Step 3.3 执行时分支尚未建立)
85
+ const branchList = run('git branch --list "' + branch + '"', wsRoot);
86
+ if (branchList.ok && !branchList.out) {
87
+ const create = run('git branch "' + branch + '"', wsRoot);
88
+ if (!create.ok) {
89
+ console.error('❌ 创建分支 ' + branch + ' 失败:' + create.err);
90
+ if (stashed) run('git stash pop', wsRoot);
91
+ process.exit(2);
92
+ }
93
+ console.log('✅ 分支 ' + branch + ' 不存在,已从 HEAD 创建');
94
+ }
95
+
80
96
  // 3. 切换到目标分支
81
97
  const checkout = run('git checkout "' + branch + '"', wsRoot);
82
98
  if (!checkout.ok) {