@jspg-ai/coding-bb 0.0.1 → 0.0.2-beta.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 (145) hide show
  1. package/cbb/bin/cbb.js +6 -0
  2. package/cbb/bin/cbbm.js +6 -0
  3. package/cbb/dev-standards/rules/cbb-ai-behavior.md +103 -103
  4. package/cbb/dev-standards/rules/cbb-priority.md +55 -55
  5. package/cbb/lib/install/claude-code.js +2 -0
  6. package/cbb/lib/install/init.js +496 -290
  7. package/cbb/lib/install/opencode.js +31 -0
  8. package/cbb/lib/install/qoder.js +2 -0
  9. package/cbb/lib/install/workspaces.js +53 -13
  10. package/cbb/lib/openspec/index.js +3 -3
  11. package/cbb/lib/superpowers/index.js +1 -1
  12. package/cbb/lib/utils/check-update.js +16 -14
  13. package/cbb/lib/utils/gitignore.js +2 -1
  14. package/cbb/lib/utils/output.js +92 -4
  15. package/cbb/lib/utils/version.js +2 -31
  16. package/cbb/lib/wiki/cli.js +25 -25
  17. package/cbb/lib/wiki/index.js +16 -16
  18. package/cbb/tools/cbb-design-to-wiki/SKILL.md +14 -14
  19. package/cbb/tools/cbb-wiki-ops/SKILL.md +22 -22
  20. package/cbb/worktrees/_shared/scripts/find-target-worktree.js +2 -2
  21. package/cbb/worktrees/_shared/scripts/find-workspace-root.js +7 -7
  22. package/cbb/worktrees/_shared/scripts/push-core.js +18 -0
  23. package/cbb/worktrees/commands/{close.md → worktree-close.md} +8 -8
  24. package/cbb/worktrees/commands/{init.md → worktree-init.md} +9 -9
  25. package/cbb/worktrees/commands/{push.md → worktree-push.md} +3 -3
  26. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/SKILL.md +20 -20
  27. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/check-env.js +4 -4
  28. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/check-unarchived.js +1 -1
  29. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/delete-branches.js +3 -3
  30. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/discover-apps.js +6 -6
  31. package/cbb/worktrees/skills/{openspec-extend-worktree → cbb-worktree-close}/scripts/find-target-worktree.js +2 -2
  32. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-close}/scripts/find-workspace-root.js +7 -7
  33. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/remove-worktrees.js +4 -4
  34. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/safety-check.js +4 -4
  35. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/SKILL.md +81 -107
  36. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/auto-open.js +1 -1
  37. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/check-env-deep.js +4 -4
  38. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/check-env.js +6 -6
  39. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/check-repos.js +4 -4
  40. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/create-branches.js +4 -4
  41. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/create-worktrees.js +8 -7
  42. package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-init}/scripts/find-workspace-root.js +7 -7
  43. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/install-ai.js +33 -33
  44. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/parse-config.js +7 -7
  45. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/push-branches.js +9 -7
  46. package/cbb/worktrees/skills/{openspec-extend-worktree → cbb-worktree-init}/scripts/push-core.js +18 -0
  47. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/sync-repos.js +10 -12
  48. package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-init}/scripts/update-gitignore.js +19 -6
  49. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/SKILL.md +16 -16
  50. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/scripts/commit-worktrees.js +2 -2
  51. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/scripts/find-target-worktree.js +2 -2
  52. package/cbb/worktrees/skills/{openspec-extend-worktree → cbb-worktree-push}/scripts/find-workspace-root.js +7 -7
  53. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/scripts/push-core.js +18 -0
  54. package/cbb/worktrees/skills/{openspec-push-worktrees → cbb-worktree-push}/scripts/push-worktrees.js +7 -5
  55. package/config/workspace-config.sample.json +18 -0
  56. package/config/workspaces.json +11 -6
  57. package/openspec/.version +6 -6
  58. package/openspec/commands/apply.md +7 -7
  59. package/openspec/commands/archive.md +7 -7
  60. package/openspec/commands/bulk-archive.md +7 -7
  61. package/openspec/commands/continue.md +7 -7
  62. package/openspec/commands/explore.md +7 -7
  63. package/openspec/commands/ff.md +7 -7
  64. package/openspec/commands/new.md +7 -7
  65. package/openspec/commands/onboard.md +7 -7
  66. package/openspec/commands/propose.md +7 -7
  67. package/openspec/commands/sync.md +7 -7
  68. package/openspec/commands/update.md +7 -7
  69. package/openspec/commands/verify.md +7 -7
  70. package/openspec/skills/openspec-apply-change/SKILL.md +187 -187
  71. package/openspec/skills/openspec-archive-change/SKILL.md +181 -181
  72. package/openspec/skills/openspec-bulk-archive-change/SKILL.md +338 -338
  73. package/openspec/skills/openspec-continue-change/SKILL.md +117 -117
  74. package/openspec/skills/openspec-explore/SKILL.md +342 -342
  75. package/openspec/skills/openspec-ff-change/SKILL.md +116 -116
  76. package/openspec/skills/openspec-new-change/SKILL.md +76 -76
  77. package/openspec/skills/openspec-onboard/SKILL.md +560 -560
  78. package/openspec/skills/openspec-propose/SKILL.md +162 -162
  79. package/openspec/skills/openspec-sync-specs/SKILL.md +261 -261
  80. package/openspec/skills/openspec-update-change/SKILL.md +90 -90
  81. package/openspec/skills/openspec-verify-change/SKILL.md +174 -174
  82. package/package.json +4 -3
  83. package/superpowers/.version +6 -6
  84. package/superpowers/skills/brainstorming/SKILL.md +250 -250
  85. package/superpowers/skills/brainstorming/scripts/helper.js +167 -167
  86. package/superpowers/skills/brainstorming/scripts/start-server.sh +209 -209
  87. package/superpowers/skills/brainstorming/scripts/stop-server.sh +120 -120
  88. package/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +49 -49
  89. package/superpowers/skills/brainstorming/visual-companion.md +299 -299
  90. package/superpowers/skills/dispatching-parallel-agents/SKILL.md +167 -167
  91. package/superpowers/skills/executing-plans/SKILL.md +64 -64
  92. package/superpowers/skills/finishing-a-development-branch/SKILL.md +225 -225
  93. package/superpowers/skills/receiving-code-review/SKILL.md +205 -205
  94. package/superpowers/skills/requesting-code-review/SKILL.md +95 -95
  95. package/superpowers/skills/requesting-code-review/code-reviewer.md +181 -181
  96. package/superpowers/skills/subagent-driven-development/SKILL.md +568 -568
  97. package/superpowers/skills/subagent-driven-development/implementer-prompt.md +154 -154
  98. package/superpowers/skills/subagent-driven-development/re-review-prompt.md +115 -115
  99. package/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +207 -207
  100. package/superpowers/skills/systematic-debugging/CREATION-LOG.md +119 -119
  101. package/superpowers/skills/systematic-debugging/SKILL.md +283 -283
  102. package/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
  103. package/superpowers/skills/systematic-debugging/condition-based-waiting.md +115 -115
  104. package/superpowers/skills/systematic-debugging/defense-in-depth.md +122 -122
  105. package/superpowers/skills/systematic-debugging/find-polluter.sh +72 -72
  106. package/superpowers/skills/systematic-debugging/root-cause-tracing.md +169 -169
  107. package/superpowers/skills/systematic-debugging/test-academic.md +14 -14
  108. package/superpowers/skills/systematic-debugging/test-pressure-1.md +58 -58
  109. package/superpowers/skills/systematic-debugging/test-pressure-2.md +68 -68
  110. package/superpowers/skills/systematic-debugging/test-pressure-3.md +69 -69
  111. package/superpowers/skills/test-driven-development/SKILL.md +320 -320
  112. package/superpowers/skills/test-driven-development/writing-good-tests.md +198 -198
  113. package/superpowers/skills/using-git-worktrees/SKILL.md +167 -167
  114. package/superpowers/skills/using-superpowers/SKILL.md +63 -63
  115. package/superpowers/skills/using-superpowers/references/antigravity-tools.md +23 -23
  116. package/superpowers/skills/using-superpowers/references/codex-tools.md +108 -108
  117. package/superpowers/skills/using-superpowers/references/gemini-tools.md +63 -63
  118. package/superpowers/skills/using-superpowers/references/hermes-tools.md +56 -56
  119. package/superpowers/skills/using-superpowers/references/pi-tools.md +16 -16
  120. package/superpowers/skills/verification-before-completion/SKILL.md +120 -120
  121. package/superpowers/skills/writing-plans/SKILL.md +171 -171
  122. package/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +49 -49
  123. package/superpowers/skills/writing-skills/SKILL.md +679 -679
  124. package/superpowers/skills/writing-skills/anthropic-best-practices.md +1150 -1150
  125. package/superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -189
  126. package/superpowers/skills/writing-skills/persuasion-principles.md +187 -187
  127. package/superpowers/skills/writing-skills/render-graphs.js +169 -169
  128. package/superpowers/skills/writing-skills/testing-skills-with-subagents.md +384 -384
  129. package/cbb/worktrees/commands/extend.md +0 -65
  130. package/cbb/worktrees/skills/openspec-close-worktree/scripts/find-target-worktree.js +0 -96
  131. package/cbb/worktrees/skills/openspec-extend-worktree/SKILL.md +0 -390
  132. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/check-env.js +0 -95
  133. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/check-repos.js +0 -98
  134. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/create-branches-and-worktrees.js +0 -135
  135. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/install-ai.js +0 -150
  136. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/list-available-apps.js +0 -88
  137. package/cbb/worktrees/skills/openspec-extend-worktree/scripts/sync-repos.js +0 -93
  138. package/cbb/worktrees/skills/openspec-init-worktree/scripts/find-workspace-root.js +0 -67
  139. package/cbb/worktrees/skills/openspec-init-worktree/scripts/generate-app-options.js +0 -93
  140. package/cbb/worktrees/skills/openspec-init-worktree/scripts/push-core.js +0 -136
  141. package/cbb/worktrees/skills/openspec-push-worktrees/scripts/silence-popup.js +0 -23
  142. package/config/config.sample.json +0 -16
  143. /package/cbb/worktrees/skills/{openspec-close-worktree → cbb-worktree-close}/scripts/silence-popup.js +0 -0
  144. /package/cbb/worktrees/skills/{openspec-extend-worktree → cbb-worktree-init}/scripts/silence-popup.js +0 -0
  145. /package/cbb/worktrees/skills/{openspec-init-worktree → cbb-worktree-push}/scripts/silence-popup.js +0 -0
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  require('./silence-popup');
3
3
  /**
4
- * openspec-init-worktree 创建 Worktree(含自愈清理)
4
+ * cbb-worktree-init 创建 Worktree(含自愈清理)
5
5
  *
6
- * 用法:node create-worktrees.js <ws_root> '<apps_json>' <branch>
6
+ * 用法:node create-worktrees.js <ws_root> <branch>
7
+ * (apps 由脚本内部从 <ws_root>/workspace-config.json 读取)
7
8
  *
8
9
  * 行为:
9
10
  * 1. 自愈清理:prune + 物理目录清理
@@ -31,7 +32,7 @@ if (!wsRoot || !branch) {
31
32
  }
32
33
 
33
34
  function loadAppsFromConfig() {
34
- const configPath = path.join(wsRoot, 'CONFIG.json');
35
+ const configPath = path.join(wsRoot, 'workspace-config.json');
35
36
  if (!fs.existsSync(configPath)) return null;
36
37
  try {
37
38
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
@@ -41,7 +42,7 @@ function loadAppsFromConfig() {
41
42
 
42
43
  const apps = loadAppsFromConfig();
43
44
  if (!apps) {
44
- console.error('❌ CONFIG.json 缺失或 apps 为空');
45
+ console.error('❌ workspace-config.json 缺失或 apps 为空');
45
46
  process.exit(1);
46
47
  }
47
48
 
@@ -57,7 +58,7 @@ function run(cmd, cwd) {
57
58
  console.log('=== 自愈清理 ===');
58
59
 
59
60
  // 1.1 prune 所有仓库
60
- const allRepos = [wsRoot, ...apps.map(a => path.join(wsRoot, '.code', a.name))];
61
+ const allRepos = [wsRoot, ...apps.map(a => path.join(wsRoot, '.codespace', a.name))];
61
62
  for (const repo of allRepos) {
62
63
  if (fs.existsSync(repo)) {
63
64
  run('git worktree prune', repo);
@@ -114,7 +115,7 @@ if (fs.existsSync(wtDir)) {
114
115
  console.log('=== 创建 App Worktrees ===');
115
116
  const results = [];
116
117
  for (const app of apps) {
117
- const appPath = path.join(wsRoot, '.code', app.name);
118
+ const appPath = path.join(wsRoot, '.codespace', app.name);
118
119
  const nestedWt = path.join(wtDir, app.name);
119
120
 
120
121
  if (fs.existsSync(nestedWt) && fs.existsSync(path.join(nestedWt, '.git'))) {
@@ -141,7 +142,7 @@ if (hasFailed) {
141
142
  console.error('⚠️ 部分 app worktree 创建失败,需手动清理:');
142
143
  console.error(' cd ' + wsRoot + ' && git worktree remove .worktrees/worktree-' + branch);
143
144
  for (const r of results.filter(x => x.status === 'failed')) {
144
- console.error(' git -C .code/' + r.name + ' worktree remove <worktree-path>');
145
+ console.error(' git -C .codespace/' + r.name + ' worktree remove <worktree-path>');
145
146
  }
146
147
  console.error('---');
147
148
  console.error('WORKTREE_RESULT', JSON.stringify(results));
@@ -5,8 +5,8 @@ require('./silence-popup');
5
5
  * 唯一真源:cbb/worktrees/_shared/scripts/find-workspace-root.js
6
6
  * 由 scripts/sync-shared.js 展开到各 skill 的 scripts/ 下(init / extend / close / push)。
7
7
  *
8
- * 优先:git worktree list 第一行(主仓库根目录,不受 worktree 内 CONFIG.json 副本干扰)
9
- * 兜底:当前目录含 CONFIG.json
8
+ * 优先:git worktree list 第一行(主仓库根目录,不受 worktree 内 workspace-config.json 副本干扰)
9
+ * 兜底:当前目录含 workspace-config.json
10
10
  *
11
11
  * 退出码:
12
12
  * 0 - 定位成功,输出 WS_ROOT 绝对路径
@@ -44,19 +44,19 @@ if (worktreeList.ok) {
44
44
  }
45
45
  }
46
46
 
47
- // 兜底:当前目录含 CONFIG.json
47
+ // 兜底:当前目录含 workspace-config.json
48
48
  if (!wsRoot) {
49
49
  const cwd = process.cwd();
50
- if (fs.existsSync(path.join(cwd, 'CONFIG.json'))) {
50
+ if (fs.existsSync(path.join(cwd, 'workspace-config.json'))) {
51
51
  wsRoot = cwd;
52
52
  }
53
53
  }
54
54
 
55
55
  // 校验
56
- if (!wsRoot || !fs.existsSync(path.join(wsRoot, 'CONFIG.json'))) {
56
+ if (!wsRoot || !fs.existsSync(path.join(wsRoot, 'workspace-config.json'))) {
57
57
  console.error('❌ 未找到工作空间根目录');
58
- console.error(' 原因:git worktree list 失败且当前目录无 CONFIG.json');
59
- console.error(' 请在业务工作空间根目录(由 cbb setup 初始化、包含 CONFIG.json)下执行本技能');
58
+ console.error(' 原因:git worktree list 失败且当前目录无 workspace-config.json');
59
+ console.error(' 请在业务工作空间根目录(由 cbb setup 初始化、包含 workspace-config.json)下执行本技能');
60
60
  process.exit(1);
61
61
  }
62
62
 
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  require('./silence-popup');
3
3
  /**
4
- * openspec-init-worktree 在 worktree 中安装 AI 配置(必要步骤)
4
+ * cbb-worktree-init 在 worktree 中安装 AI 配置(必要步骤)
5
5
  *
6
6
  * 用法:node install-ai.js <wt_path>
7
7
  *
8
8
  * 行为:
9
- * 1. 检测 cbb 是否全局安装,未安装则自动安装
10
- * 2. 直接用 npm 全局 bin 路径调用 cbb(避免 PowerShell PATH 缓存)
11
- * 3. 在 worktree 内执行 cbb init --yes
9
+ * 1. 检测 cbbm 是否全局安装,未安装则自动安装
10
+ * 2. 直接用 npm 全局 bin 路径调用 cbbm(避免 PowerShell PATH 缓存)
11
+ * 3. 在 worktree 内执行 cbbm init --yes
12
12
  * 4. 失败则 exit 2,阻塞 init-worktree 流程(与 push-branches.js 语义一致)
13
13
  *
14
14
  * 退出码:
15
15
  * 0 - 成功
16
16
  * 1 - 参数错误(脚本 bug 或调用错误)
17
- * 2 - cbb init 执行失败(**阻塞 init-worktree**,用户必须手动恢复)
17
+ * 2 - cbbm init 执行失败(**阻塞 init-worktree**,用户必须手动恢复)
18
18
  */
19
19
  const { execSync } = require('child_process');
20
20
  const fs = require('fs');
@@ -40,11 +40,11 @@ function run(cmd, cwd, env) {
40
40
  }
41
41
  }
42
42
 
43
- // 查找 cbb 可执行文件:先 PATH,再 npm 全局 bin
43
+ // 查找 cbbm 可执行文件:先 PATH,再 npm 全局 bin
44
44
  function findCbb() {
45
- // 1. 直接调用 cbb --version
46
- let r = run('cbb --version');
47
- if (r.ok) return { cmd: 'cbb', version: r.out };
45
+ // 1. 直接调用 cbbm --version
46
+ let r = run('cbbm --version');
47
+ if (r.ok) return { cmd: 'cbbm', version: r.out };
48
48
 
49
49
  // 2. 查 npm 全局 bin 目录
50
50
  const npmRoot = run('npm root -g');
@@ -53,15 +53,15 @@ function findCbb() {
53
53
  // Unix: <npm_root>/../bin/cbb
54
54
  const candidates = [];
55
55
  if (process.platform === 'win32') {
56
- candidates.push(path.join(npmRoot.out, 'cbb.cmd'));
57
- candidates.push(path.join(npmRoot.out, '..', 'cbb.cmd'));
58
- candidates.push(path.join(npmRoot.out, '..', 'bin', 'cbb.cmd'));
59
- // npm 全局 bin 通常是 %APPDATA%\npm\cbb.cmd
60
- const appdata = process.env.APPDATA || process.env.USERPROFILE;
61
- if (appdata) candidates.push(path.join(appdata, 'npm', 'cbb.cmd'));
62
- } else {
63
- candidates.push(path.join(npmRoot.out, '..', 'bin', 'cbb'));
64
- candidates.push(path.join(npmRoot.out, '..', 'cbb'));
56
+ candidates.push(path.join(npmRoot.out, 'cbbm.cmd'));
57
+ candidates.push(path.join(npmRoot.out, '..', 'cbbm.cmd'));
58
+ candidates.push(path.join(npmRoot.out, '..', 'bin', 'cbbm.cmd'));
59
+ // npm 全局 bin 通常是 %APPDATA%\npm\cbbm.cmd
60
+ const appdata = process.env.APPDATA || process.env.USERPROFILE;
61
+ if (appdata) candidates.push(path.join(appdata, 'npm', 'cbbm.cmd'));
62
+ } else {
63
+ candidates.push(path.join(npmRoot.out, '..', 'bin', 'cbbm'));
64
+ candidates.push(path.join(npmRoot.out, '..', 'cbbm'));
65
65
  }
66
66
  for (const c of candidates) {
67
67
  if (fs.existsSync(c)) {
@@ -77,7 +77,7 @@ function findCbb() {
77
77
  // 1. 检测/安装 cbb
78
78
  let cbbInfo = findCbb();
79
79
  if (!cbbInfo) {
80
- console.log('WARN: cbb not globally installed, try auto-install...');
80
+ console.log('WARN: cbbm not globally installed, try auto-install...');
81
81
  const install = run('npm install -g @jspg-ai/coding-bb');
82
82
  if (!install.ok) {
83
83
  console.error('ERROR: cbb auto-install failed: ' + install.err);
@@ -85,7 +85,7 @@ if (!cbbInfo) {
85
85
  console.error('━━━ init-worktree 已中断 ━━━');
86
86
  console.error('请手动安装 cbb 后重跑 init-worktree:');
87
87
  console.error(' 1. npm install -g @jspg-ai/coding-bb');
88
- console.error(' 2. cd "' + wtPath + '" && cbb init --yes');
88
+ console.error(' 2. cd "' + wtPath + '" && cbbm init --yes');
89
89
  console.error(' 3. 在 ai-workspace 根目录重跑 init-worktree');
90
90
  console.log('---');
91
91
  console.log('AI_INIT_FAILED');
@@ -98,8 +98,8 @@ if (!cbbInfo) {
98
98
  const npmRoot = run('npm root -g');
99
99
  if (npmRoot.ok) {
100
100
  const candidates = process.platform === 'win32'
101
- ? [path.join(npmRoot.out, '..', 'cbb.cmd'), path.join(npmRoot.out, '..', 'bin', 'cbb.cmd')]
102
- : [path.join(npmRoot.out, '..', 'bin', 'cbb')];
101
+ ? [path.join(npmRoot.out, '..', 'cbbm.cmd'), path.join(npmRoot.out, '..', 'bin', 'cbbm.cmd')]
102
+ : [path.join(npmRoot.out, '..', 'bin', 'cbbm')];
103
103
  for (const c of candidates) {
104
104
  if (fs.existsSync(c)) {
105
105
  cbbInfo = { cmd: '"' + c + '"', version: 'located at ' + c };
@@ -109,26 +109,26 @@ if (!cbbInfo) {
109
109
  }
110
110
  }
111
111
  if (!cbbInfo) {
112
- console.error('ERROR: cbb not found after install. Likely npm PATH cache issue.');
112
+ console.error('ERROR: cbbm not found after install. Likely npm PATH cache issue.');
113
113
  console.error('');
114
114
  console.error('━━━ init-worktree 已中断 ━━━');
115
115
  console.error('可能原因:npm 全局 bin 目录不在当前 shell 的 PATH 中。');
116
116
  console.error('手动恢复步骤:');
117
- console.error(' 1. 重启终端让 PATH 生效,或手动定位 cbb:');
117
+ console.error(' 1. 重启终端让 PATH 生效,或手动定位 cbbm:');
118
118
  console.error(' npm root -g # 拿到全局 node_modules 路径');
119
- console.error(' <path>/../cbb.cmd # Windows / <path>/../bin/cbb # Unix');
120
- console.error(' 2. cd "' + wtPath + '" && cbb init --yes');
119
+ console.error(' <path>/../cbbm.cmd # Windows / <path>/../bin/cbbm # Unix');
120
+ console.error(' 2. cd "' + wtPath + '" && cbbm init --yes');
121
121
  console.error(' 3. 在 ai-workspace 根目录重跑 init-worktree');
122
122
  console.log('---');
123
123
  console.log('AI_INIT_FAILED');
124
124
  process.exit(2);
125
125
  }
126
- console.log('OK: cbb located: ' + cbbInfo.version);
126
+ console.log('OK: cbbm located: ' + cbbInfo.version);
127
127
  } else {
128
- console.log('OK: cbb found: ' + cbbInfo.version);
128
+ console.log('OK: cbbm found: ' + cbbInfo.version);
129
129
  }
130
130
 
131
- // 2. 在 worktree 中执行 cbb init --yes
131
+ // 2. 在 worktree 中执行 cbbm init --yes
132
132
  console.log('Installing AI config in worktree: ' + wtPath);
133
133
  const initCmd = cbbInfo.cmd + ' init --yes';
134
134
  const init = run(initCmd, wtPath);
@@ -145,21 +145,21 @@ if (init.ok) {
145
145
  console.error('ERROR: AI config install failed: ' + init.err);
146
146
  console.error('');
147
147
  console.error('━━━ init-worktree 已中断 ━━━');
148
- console.error('原因:cbb init 是必要步骤。AI 配置缺失将导致后续 openspec-* ');
148
+ console.error('原因:cbbm init 是必要步骤。AI 配置缺失将导致后续 openspec-* ');
149
149
  console.error(' (propose/apply/verify/ff 等)技能全部不可用。');
150
150
  console.error('');
151
151
  console.error('━━━ 手动恢复步骤(请按顺序执行)━━━');
152
152
  console.error('');
153
153
  console.error('1. 验证环境');
154
- console.error(' $ cbb --version');
154
+ console.error(' $ cbbm --version');
155
155
  console.error(' $ node --version # 需要 >= 16.7.0');
156
156
  console.error('');
157
- console.error('2. cbb 未安装,先安装');
157
+ console.error('2. 若未安装(cbbm 不在 PATH),先安装');
158
158
  console.error(' $ npm install -g @jspg-ai/coding-bb');
159
159
  console.error('');
160
160
  console.error('3. 进入 worktree 并初始化 AI 配置');
161
161
  console.error(' $ cd "' + wtPath + '"');
162
- console.error(' $ cbb init --yes');
162
+ console.error(' $ cbbm init --yes');
163
163
  console.error('');
164
164
  console.error('4. 重新执行 init-worktree');
165
165
  console.error(' 在 ai-workspace 根目录重跑,会跳过已初始化的部分');
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  require('./silence-popup');
3
3
  /**
4
- * openspec-init-worktree 读取并校验 CONFIG.json
4
+ * cbb-worktree-init 读取并校验 workspace-config.json
5
5
  *
6
6
  * 退出码:
7
7
  * 0 - 成功,输出应用列表 JSON
@@ -15,10 +15,10 @@ require('./silence-popup');
15
15
  const fs = require('fs');
16
16
  const path = require('path');
17
17
 
18
- const configPath = path.join(process.cwd(), 'CONFIG.json');
18
+ const configPath = path.join(process.cwd(), 'workspace-config.json');
19
19
 
20
20
  if (!fs.existsSync(configPath)) {
21
- console.error('❌ CONFIG.json 不存在');
21
+ console.error('❌ workspace-config.json 不存在');
22
22
  console.error(' 请先在 cbb setup 阶段创建,或手动配置');
23
23
  console.error('---');
24
24
  console.error('CONFIG_MISSING');
@@ -29,7 +29,7 @@ let config;
29
29
  try {
30
30
  config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
31
31
  } catch (e) {
32
- console.error('❌ CONFIG.json 解析失败:', e.message);
32
+ console.error('❌ workspace-config.json 解析失败:', e.message);
33
33
  console.error(' 请检查 JSON 格式');
34
34
  console.error('---');
35
35
  console.error('CONFIG_INVALID');
@@ -38,8 +38,8 @@ try {
38
38
 
39
39
  const apps = config.apps || [];
40
40
  if (apps.length === 0) {
41
- console.error('❌ CONFIG.json 中 apps 为空');
42
- console.error(' 请编辑 CONFIG.json 配置关联应用');
41
+ console.error('❌ workspace-config.json 中 apps 为空');
42
+ console.error(' 请编辑 workspace-config.json 配置关联应用');
43
43
  console.error('---');
44
44
  console.error('CONFIG_EMPTY');
45
45
  process.exit(2);
@@ -61,7 +61,7 @@ for (const app of apps) {
61
61
  }
62
62
  }
63
63
 
64
- console.log('✅ CONFIG.json 有效(' + apps.length + ' 个应用)');
64
+ console.log('✅ workspace-config.json 有效(' + apps.length + ' 个应用)');
65
65
  console.log('---');
66
66
  console.log('CONFIG_OK', JSON.stringify(apps));
67
67
  process.exit(0);
@@ -1,9 +1,9 @@
1
1
  require('./silence-popup');
2
2
  /**
3
- * openspec-init-worktree 推送并建立 upstream
3
+ * cbb-worktree-init 推送并建立 upstream
4
4
  *
5
5
  * 薄壳脚本:核心 push 逻辑委托给同目录的 push-core.js(共享脚本,源仓库真源在 _shared/scripts/)。
6
- * 本脚本只负责 CLI 入口编排(编排 init-worktree 关注的 workspace + .code/<app>/ 列表)。
6
+ * 本脚本只负责 CLI 入口编排(编排 init-worktree 关注的 workspace + .codespace/<app>/ 列表)。
7
7
  *
8
8
  * Usage: node push-branches.js <ws_root> <branch>
9
9
  *
@@ -12,7 +12,7 @@ require('./silence-popup');
12
12
  * 1 - 参数错误(CONFIG 缺失或 argv 不足)
13
13
  * 2 - 部分/全部失败(AI agent 必须阻塞流程)
14
14
  *
15
- * 新场景(开发完成后跨 worktree 推送)请使用 openspec-push-worktrees/scripts/push-worktrees.js。
15
+ * 新场景(开发完成后跨 worktree 推送)请使用 cbb-worktree-push/scripts/push-worktrees.js。
16
16
  */
17
17
 
18
18
  const { pushSingle, classifyError, collectRemoteMetadata } = require('./push-core');
@@ -20,7 +20,7 @@ const fs = require('fs');
20
20
  const path = require('path');
21
21
 
22
22
  function loadAppsFromConfig(wsRoot) {
23
- const configPath = path.join(wsRoot, 'CONFIG.json');
23
+ const configPath = path.join(wsRoot, 'workspace-config.json');
24
24
  if (!fs.existsSync(configPath)) return null;
25
25
  try {
26
26
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
@@ -40,7 +40,7 @@ function executePush(opts) {
40
40
  const branch = opts.branch;
41
41
  const apps = opts.apps != null ? opts.apps : loadAppsFromConfig(wsRoot);
42
42
  if (apps == null) {
43
- throw new Error('CONFIG.json missing or apps empty');
43
+ throw new Error('workspace-config.json missing or apps empty');
44
44
  }
45
45
 
46
46
  const results = [];
@@ -48,7 +48,7 @@ function executePush(opts) {
48
48
  results.push(pushSingle(wsRoot, 'workspace', branch, { execSyncImpl: opts.execSyncImpl }));
49
49
  // apps
50
50
  for (const app of apps) {
51
- const appPath = path.join(wsRoot, '.code', app.name);
51
+ const appPath = path.join(wsRoot, '.codespace', app.name);
52
52
  results.push(pushSingle(appPath, app.name, branch, { execSyncImpl: opts.execSyncImpl }));
53
53
  }
54
54
  return results;
@@ -68,7 +68,7 @@ function main() {
68
68
 
69
69
  const apps = loadAppsFromConfig(wsRoot);
70
70
  if (apps == null) {
71
- console.error('❌ CONFIG.json 缺失或 apps 为空');
71
+ console.error('❌ workspace-config.json 缺失或 apps 为空');
72
72
  process.exit(1);
73
73
  }
74
74
 
@@ -81,6 +81,8 @@ function main() {
81
81
  for (const r of results) {
82
82
  if (r.status === 'pushed') {
83
83
  console.log('✅ ' + r.name + ': 已推送 ' + r.upstream);
84
+ } else if (r.status === 'skipped') {
85
+ console.log('⏭️ ' + r.name + ': 远程分支与本地一致,跳过推送');
84
86
  } else if (r.status === 'remote-exists') {
85
87
  console.log('⚠️ ' + r.name + ': 远程分支已存在(需用户决策)');
86
88
  } else {
@@ -12,6 +12,12 @@ require('./silence-popup');
12
12
  * - pushSingle(repoPath, repoName, branch) 推送单个仓库并建立 upstream
13
13
  * - collectRemoteMetadata(repoPath, branch, remote) 采集远程 commit 元信息
14
14
  *
15
+ * pushSingle 状态契约:
16
+ * - pushed 本次推送成功(新建分支或快进)
17
+ * - skipped 远程同名分支已存在且与本地一致 → 无需推送(幂等,重跑 init 场景)
18
+ * - remote-exists 远程同名分支存在但与本地不一致 → 需用户决策(附 metadata)
19
+ * - failed 推送失败,error 见错误码契约
20
+ *
15
21
  * 错误码契约(classifyError 输出):
16
22
  * - ssh-auth-failed Permission denied (publickey)
17
23
  * - https-auth-failed Authentication failed
@@ -115,6 +121,18 @@ function pushSingle(repoPath, repoName, branch, opts) {
115
121
  const r = remote.out.split(/\r?\n/)[0];
116
122
  const branchEsc = escapeBranch(branch);
117
123
  const remoteEsc = '"' + String(r).replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
124
+
125
+ // 幂等:远程同名分支已存在且 hash 与本地完全一致 → 此前已推送,直接跳过。
126
+ // 让 init-worktree 可安全重跑(补齐新增应用/中断恢复),且不会重复推送或误报 remote-exists。
127
+ const lsRemote = tryExec('git ls-remote --heads ' + remoteEsc + ' ' + escapeBranch('refs/heads/' + branch), repoPath, execImpl);
128
+ if (lsRemote.ok && lsRemote.out) {
129
+ const remoteHash = lsRemote.out.split(/\s+/)[0];
130
+ const localHash = tryExec('git rev-parse --verify ' + branchEsc, repoPath, execImpl);
131
+ if (localHash.ok && localHash.out && localHash.out === remoteHash) {
132
+ return { name: repoName, status: 'skipped', upstream: r + '/' + branch, message: '远程分支与本地一致,无需推送' };
133
+ }
134
+ }
135
+
118
136
  const pushResult = tryExec('git push -u ' + remoteEsc + ' ' + branchEsc, repoPath, execImpl);
119
137
  if (pushResult.ok) {
120
138
  return { name: repoName, status: 'pushed', upstream: r + '/' + branch };
@@ -1,14 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  require('./silence-popup');
3
3
  /**
4
- * openspec-init-worktree 同步 .code/ 仓库
4
+ * cbb-worktree-init 同步 .codespace/ 仓库
5
5
  *
6
- * 用法:node sync-repos.js <ws_root> '<apps_json>'
7
- * - ws_root: 工作空间根绝对路径
8
- * - apps_json: 应用列表 JSON 数组(来自 parse-config.js)
6
+ * 用法:node sync-repos.js <ws_root>
7
+ * - ws_root: 工作空间根绝对路径(apps 从 <ws_root>/workspace-config.json 读取)
9
8
  *
10
9
  * 对每个 app:
11
- * - .code/<name>/.git 存在 → fetch --all
10
+ * - .codespace/<name>/.git 存在 → fetch --all
12
11
  * - 不存在 → clone(从 repo URL)
13
12
  *
14
13
  * 退出码:
@@ -22,7 +21,6 @@ const fs = require('fs');
22
21
  const path = require('path');
23
22
 
24
23
  const wsRoot = process.argv[2];
25
- const appsJson = process.argv[3];
26
24
 
27
25
  if (!wsRoot) {
28
26
  console.error('❌ 用法:node sync-repos.js <ws_root>');
@@ -30,23 +28,23 @@ if (!wsRoot) {
30
28
  }
31
29
 
32
30
  /**
33
- * 从 CONFIG.json 读取 apps(避免 shell 字符串传递中的转义问题)
31
+ * 从 workspace-config.json 读取 apps(避免 shell 字符串传递中的转义问题)
34
32
  */
35
33
  function loadAppsFromConfig() {
36
- const configPath = path.join(wsRoot, 'CONFIG.json');
34
+ const configPath = path.join(wsRoot, 'workspace-config.json');
37
35
  if (!fs.existsSync(configPath)) {
38
- console.error('❌ CONFIG.json 不存在:' + configPath);
36
+ console.error('❌ workspace-config.json 不存在:' + configPath);
39
37
  return null;
40
38
  }
41
39
  try {
42
40
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
43
41
  if (!config.apps || !Array.isArray(config.apps) || config.apps.length === 0) {
44
- console.error('❌ CONFIG.json 中 apps 为空');
42
+ console.error('❌ workspace-config.json 中 apps 为空');
45
43
  return null;
46
44
  }
47
45
  return config.apps;
48
46
  } catch (e) {
49
- console.error('❌ CONFIG.json 解析失败:' + e.message);
47
+ console.error('❌ workspace-config.json 解析失败:' + e.message);
50
48
  return null;
51
49
  }
52
50
  }
@@ -56,7 +54,7 @@ if (!apps) {
56
54
  process.exit(1);
57
55
  }
58
56
 
59
- const codeDir = path.join(wsRoot, '.code');
57
+ const codeDir = path.join(wsRoot, '.codespace');
60
58
  fs.mkdirSync(codeDir, { recursive: true });
61
59
 
62
60
  const results = [];
@@ -1,19 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  require('./silence-popup');
3
3
  /**
4
- * openspec-init-worktree 安全更新 .gitignore
4
+ * cbb-worktree-init 安全更新 .gitignore
5
5
  *
6
6
  * 用法:node update-gitignore.js <ws_root> <branch>
7
7
  *
8
8
  * 行为:
9
9
  * 1. stash 当前未提交修改
10
10
  * 2. 切换到目标分支
11
- * 3. 检查 .worktrees/ 和 .code/ 是否在 .gitignore
11
+ * 3. 检查 .worktrees/ 和 .codespace/ 是否在 .gitignore
12
12
  * 4. 添加缺失条目
13
13
  * 5. 提交 .gitignore
14
14
  * 6. 切回原分支
15
15
  * 7. pop stash(如有)
16
16
  *
17
+ * 幂等:目标分支已在某个 worktree 中检出(init-worktree 重跑场景,上次已处理过
18
+ * .gitignore)时,跳过全部操作直接输出 GITIGNORE_OK——避免 checkout 与 worktree 检出冲突。
19
+ *
17
20
  * 退出码:
18
21
  * 0 - 成功
19
22
  * 1 - 参数错误
@@ -48,6 +51,16 @@ if (!origBranch.ok) {
48
51
  }
49
52
  console.log('当前分支:' + origBranch.out);
50
53
 
54
+ // 1.1 幂等检查:目标分支已被某 worktree 检出 → 上次 init-worktree 已处理 .gitignore
55
+ const wtList = run('git worktree list --porcelain', wsRoot);
56
+ const branchInWorktree = wtList.ok && wtList.out.split(/\r?\n/).some(l => l.trim() === 'branch refs/heads/' + branch);
57
+ if (branchInWorktree) {
58
+ console.log('ℹ️ 分支 ' + branch + ' 已在 worktree 中检出(init-worktree 重跑场景),跳过 .gitignore 处理');
59
+ console.log('---');
60
+ console.log('GITIGNORE_OK');
61
+ process.exit(0);
62
+ }
63
+
51
64
  // 2. stash 当前未提交修改
52
65
  let stashed = false;
53
66
  const status = run('git status --porcelain', wsRoot);
@@ -73,13 +86,13 @@ if (!checkout.ok) {
73
86
  }
74
87
  console.log('✅ 切换到分支:' + branch);
75
88
 
76
- // 4. 检查并添加 .worktrees/ 和 .code/ 到 .gitignore
89
+ // 4. 检查并添加 .worktrees/ 和 .codespace/ 到 .gitignore
77
90
  const gitignorePath = path.join(wsRoot, '.gitignore');
78
91
  let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
79
92
  const original = content;
80
93
  const needCommit = [];
81
94
 
82
- for (const dir of ['.worktrees/', '.code/']) {
95
+ for (const dir of ['.worktrees/', '.codespace/']) {
83
96
  const check = run('git check-ignore -q "' + dir + '"', wsRoot);
84
97
  if (!check.ok) {
85
98
  // 未忽略:添加
@@ -90,7 +103,7 @@ for (const dir of ['.worktrees/', '.code/']) {
90
103
  }
91
104
 
92
105
  if (needCommit.length === 0) {
93
- console.log('ℹ️ .worktrees/ 和 .code/ 均已在 .gitignore 中,跳过提交');
106
+ console.log('ℹ️ .worktrees/ 和 .codespace/ 均已在 .gitignore 中,跳过提交');
94
107
  } else {
95
108
  fs.writeFileSync(gitignorePath, content);
96
109
  console.log('✅ .gitignore 已添加:' + needCommit.join(', '));
@@ -101,7 +114,7 @@ if (needCommit.length === 0) {
101
114
  if (stashed) run('git stash pop', wsRoot);
102
115
  process.exit(2);
103
116
  }
104
- const commit = run('git commit -m "chore: add .worktrees/ and .code/ to gitignore"', wsRoot);
117
+ const commit = run('git commit -m "chore: add .worktrees/ and .codespace/ to gitignore"', wsRoot);
105
118
  if (!commit.ok) {
106
119
  console.error('❌ git commit 失败:' + commit.err);
107
120
  run('git checkout "' + origBranch.out + '"', wsRoot);
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: openspec-push-worktrees
2
+ name: cbb-worktree-push
3
3
  description: "跨 worktree 提交并推送当前需求的所有关联仓库。触发:用户说'提交'/'commit'/'push'/'推送'/'提交并push'/'推到远端';用户在 .worktrees/worktree-<需求名>/ 下工作要求批量推送;apply 完成后准备推送所有 worktree;close-worktree 前需要先推送未提交改动。"
4
4
  license: MIT
5
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).
@@ -11,17 +11,17 @@ metadata:
11
11
 
12
12
  # Push Worktrees(跨平台脚本化版本 v1.0)
13
13
 
14
- 跨 worktree 提交并推送当前需求的所有关联仓库到 origin。专门解决"开发完成后批量推送"和"用户口语化提交并push"两类场景,弥补 [openspec-init-worktree Step 3.4](file:///d:/workspace/va-ai/coding-bb/cbb/worktrees/skills/openspec-init-worktree/SKILL.md) 仅推送初始空 commit 的缺口。
14
+ 跨 worktree 提交并推送当前需求的所有关联仓库到 origin。专门解决"开发完成后批量推送"和"用户口语化提交并push"两类场景,弥补 [cbb-worktree-init Step 3.4](file:///d:/workspace/va-ai/coding-bb/cbb/worktrees/skills/cbb-worktree-init/SKILL.md) 仅推送初始空 commit 的缺口。
15
15
 
16
- **启动时声明:** "我正在使用 openspec-push-worktrees 技能来批量提交并推送当前需求的所有 worktree 仓库。"
16
+ **启动时声明:** "我正在使用 cbb-worktree-push 技能来批量提交并推送当前需求的所有 worktree 仓库。"
17
17
 
18
18
  ## 核心原则
19
19
 
20
20
  - 本技能的所有原子操作封装为 `scripts/*.js` Node.js 脚本,**跨平台执行**
21
21
  - **两阶段**:先 `commit-worktrees.js` 提交所有 dirty 仓库,再 `push-worktrees.js` 推送所有 worktree 仓库。两个脚本独立退出码,AI agent 区分阶段
22
- - 复用 `openspec-push-worktrees/scripts/push-core.js` 的 `pushSingle` / `classifyError` —— 与 `openspec-init-worktree` 的 `push-branches.js` 行为完全一致,错误码契约统一
23
- - `find-workspace-root.js` / `find-target-worktree.js` 为共享脚本:源仓库真源在 `cbb/worktrees/_shared/scripts/`,部署后位于本 skill 的 `scripts/` 下,与 `openspec-extend-worktree` / `openspec-close-worktree` 逻辑完全一致
24
- - **本技能支持两层执行位置**(与 `openspec-close-worktree` 对称):
22
+ - 复用 `cbb-worktree-push/scripts/push-core.js` 的 `pushSingle` / `classifyError` —— 与 `cbb-worktree-init` 的 `push-branches.js` 行为完全一致,错误码契约统一
23
+ - `find-workspace-root.js` / `find-target-worktree.js` 为共享脚本:源仓库真源在 `cbb/worktrees/_shared/scripts/`,部署后位于本 skill 的 `scripts/` 下,与 `cbb-worktree-init` / `cbb-worktree-close` 逻辑完全一致
24
+ - **本技能支持两层执行位置**(与 `cbb-worktree-close` 对称):
25
25
  - 工作空间根目录(`WS_ROOT/`)
26
26
  - worktree 内部(`WS_ROOT/.worktrees/worktree-<需求名>/` 或其子目录)
27
27
  - 输入约定:**自由文本**(commit 信息、需求名等)直接在对话中提问并等待回复;**固定选项多选**(如 "应用统一信息 vs 分别信息")使用 `AskUserQuestion`
@@ -33,7 +33,7 @@ metadata:
33
33
  **所有脚本必须用绝对路径调用**(Qoder 沙箱中 AI agent 的 cwd 不一定是技能目录)。
34
34
 
35
35
  ```
36
- node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/<name>.js" <参数>
36
+ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/<name>.js" <参数>
37
37
  ```
38
38
 
39
39
  脚本输出:
@@ -46,7 +46,7 @@ node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/<name>.js" <参数
46
46
  ## Step 0:定位工作空间
47
47
 
48
48
  ```bash
49
- node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/find-workspace-root.js"
49
+ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/find-workspace-root.js"
50
50
  ```
51
51
 
52
52
  **解读末行**:
@@ -58,13 +58,13 @@ node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/find-workspace-roo
58
58
  ## Step 1:识别目标 worktree
59
59
 
60
60
  ```bash
61
- node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/find-target-worktree.js" "<ws_root>"
61
+ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/find-target-worktree.js" "<ws_root>"
62
62
  ```
63
63
 
64
64
  **解读末行**:
65
65
  - 退出码 0 + 末行(需求名) → 唯一识别,自动用之
66
66
  - 退出码 1 + 末行 `MULTIPLE_WORKTREEES` → 多个 worktree,AI agent 在对话中让用户输入序号或分支名
67
- - 退出码 2 + 末行 `NO_WORKTREE` → 无 worktree,提示用户先用 `openspec-init-worktree`
67
+ - 退出码 2 + 末行 `NO_WORKTREE` → 无 worktree,提示用户先用 `cbb-worktree-init`
68
68
 
69
69
  ---
70
70
 
@@ -72,7 +72,7 @@ node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/find-target-worktr
72
72
 
73
73
  ```bash
74
74
  # 仅 commit 阶段先做 dry-run 预览
75
- node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/commit-worktrees.js" "<ws_root>" "<branch>" --message "preview" --dry-run
75
+ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/commit-worktrees.js" "<ws_root>" "<branch>" --message "preview" --dry-run
76
76
  ```
77
77
 
78
78
  **解读末行 `COMMIT_RESULT`**:每项仓库的状态
@@ -94,7 +94,7 @@ AI agent 在执行真实 commit 前**必须**在对话中向用户确认 commit
94
94
 
95
95
  ```
96
96
  检测到以下 worktree 仓库有未提交改动:
97
- - workspace: 5 个文件(CONFIG.json, openspec/changes/foo/...)
97
+ - workspace: 5 个文件(workspace-config.json, openspec/changes/foo/...)
98
98
  - ep-foo-app: 12 个文件
99
99
  - ep-bar-app: 3 个文件
100
100
 
@@ -119,7 +119,7 @@ AI agent 在执行真实 commit 前**必须**在对话中向用户确认 commit
119
119
 
120
120
  ```bash
121
121
  # 统一信息
122
- node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/commit-worktrees.js" "<ws_root>" "<branch>" --message "feat(<branch>): 实现客户运费逻辑"
122
+ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/commit-worktrees.js" "<ws_root>" "<branch>" --message "feat(<branch>): 实现客户运费逻辑"
123
123
 
124
124
  # 多仓库分别
125
125
  node "..." "<ws_root>" "<branch>" --per-repo "ep-foo-app:feat(<branch>): 实现 saveClientExpectFreight;ep-bar-app:refactor(<branch>): 拆分 PlanService"
@@ -155,7 +155,7 @@ node "..." "<ws_root>/.worktrees/worktree-<branch>" --message "..."
155
155
  ## Step 5:批量 push
156
156
 
157
157
  ```bash
158
- node "<ws_root>/.qoder/skills/openspec-push-worktrees/scripts/push-worktrees.js" "<ws_root>" "<branch>"
158
+ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/push-worktrees.js" "<ws_root>" "<branch>"
159
159
 
160
160
  # 或 wt_path 形式
161
161
  node "..." "<ws_root>/.worktrees/worktree-<branch>"
@@ -211,7 +211,7 @@ node "..." "<ws_root>/.worktrees/worktree-<branch>"
211
211
  ep-foo-app: ✅ origin/<branch>
212
212
  ep-bar-app: ⚠️ 远程分支已存在(需用户决策 → 已关联)
213
213
  AI 配置目录:worktree 内独立安装,无需处理
214
- 后续:可继续开发 / 调 /opsx:verify 验证 / 调 /opsx:archive 归档 / 调 /opsx:close 关闭
214
+ 后续:可继续开发 / 调 /opsx:verify 验证 / 调 /opsx:archive 归档 / 调 /cbb:worktree-close 关闭
215
215
  ```
216
216
 
217
217
  ---
@@ -258,7 +258,7 @@ node "..." "<ws_root>/.worktrees/worktree-<branch>"
258
258
 
259
259
  ### 多仓库用同一条 commit 信息
260
260
 
261
- - **问题:** workspace 改了 CONFIG.json,ep-foo-app 改了 Java 代码,硬塞同一条 "feat: 实现 XX" 信息不准确
261
+ - **问题:** workspace 改了 workspace-config.json,ep-foo-app 改了 Java 代码,硬塞同一条 "feat: 实现 XX" 信息不准确
262
262
  - **修复:** 用 `--per-repo` 模式,让用户逐仓库提供
263
263
 
264
264
  ### push 失败时跳过失败仓库直接继续