@jspg-ai/coding-bb 0.0.3-beta.9 → 0.0.5-beta.1

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 (109) hide show
  1. package/README.md +1 -0
  2. package/cbb/dev-standards/rules/cbb-ai-behavior.md +0 -15
  3. package/cbb/dev-standards/rules/cbb-workspace-discipline.md +38 -0
  4. package/cbb/lib/external/index.js +228 -0
  5. package/cbb/lib/install/agents-nav.js +92 -0
  6. package/cbb/lib/install/claude-code.js +8 -1
  7. package/cbb/lib/install/command-skill.js +105 -0
  8. package/cbb/lib/install/init.js +399 -129
  9. package/cbb/lib/install/minimax.js +60 -0
  10. package/cbb/lib/install/rule-rewrite.js +1 -1
  11. package/cbb/lib/install/setup-decision.js +92 -0
  12. package/cbb/lib/install/tool-selection.js +23 -0
  13. package/cbb/lib/install/trae.js +18 -8
  14. package/cbb/lib/install/workbuddy.js +36 -0
  15. package/cbb/lib/install/workspaces.js +15 -61
  16. package/cbb/lib/utils/check-update.js +13 -5
  17. package/cbb/lib/utils/githook.js +230 -0
  18. package/cbb/lib/utils/gitignore.js +17 -4
  19. package/cbb/lib/utils/plugin-hook.js +92 -0
  20. package/cbb/worktrees/_shared/scripts/check-local-state.js +114 -0
  21. package/cbb/worktrees/_shared/scripts/check-unarchived.js +77 -0
  22. package/cbb/worktrees/_shared/scripts/delete-branches.js +147 -0
  23. package/cbb/worktrees/_shared/scripts/deprecate-branches.js +119 -0
  24. package/cbb/worktrees/_shared/scripts/find-target-worktree.js +148 -96
  25. package/cbb/worktrees/_shared/scripts/find-workspace-root.js +8 -8
  26. package/cbb/worktrees/_shared/scripts/install-git-hook.js +70 -0
  27. package/cbb/worktrees/_shared/scripts/junction-ai-config.js +192 -0
  28. package/cbb/worktrees/_shared/scripts/merge-branches.js +580 -0
  29. package/cbb/worktrees/_shared/scripts/push-core.js +1 -1
  30. package/cbb/worktrees/_shared/scripts/silence-popup.js +1 -1
  31. package/cbb/worktrees/_shared/scripts/start-local.js +180 -0
  32. package/cbb/worktrees/skills/cbb-local-mode/SKILL.md +194 -0
  33. package/cbb/worktrees/skills/cbb-local-mode/scripts/check-local-state.js +114 -0
  34. package/cbb/worktrees/skills/cbb-local-mode/scripts/delete-branches.js +147 -0
  35. package/cbb/worktrees/skills/cbb-local-mode/scripts/deprecate-branches.js +119 -0
  36. package/cbb/worktrees/skills/cbb-local-mode/scripts/install-git-hook.js +70 -0
  37. package/cbb/worktrees/skills/cbb-local-mode/scripts/merge-branches.js +580 -0
  38. package/cbb/worktrees/skills/cbb-local-mode/scripts/silence-popup.js +23 -0
  39. package/cbb/worktrees/skills/cbb-local-mode/scripts/start-local.js +180 -0
  40. package/cbb/worktrees/skills/cbb-worktree-close/SKILL.md +134 -81
  41. package/cbb/worktrees/skills/cbb-worktree-close/scripts/check-env.js +3 -3
  42. package/cbb/worktrees/skills/cbb-worktree-close/scripts/check-unarchived.js +77 -48
  43. package/cbb/worktrees/skills/cbb-worktree-close/scripts/delete-branches.js +147 -136
  44. package/cbb/worktrees/skills/cbb-worktree-close/scripts/deprecate-branches.js +119 -0
  45. package/cbb/worktrees/skills/cbb-worktree-close/scripts/discover-apps.js +14 -5
  46. package/cbb/worktrees/skills/cbb-worktree-close/scripts/find-target-worktree.js +148 -96
  47. package/cbb/worktrees/skills/cbb-worktree-close/scripts/find-workspace-root.js +8 -8
  48. package/cbb/worktrees/skills/cbb-worktree-close/scripts/junction-ai-config.js +192 -0
  49. package/cbb/worktrees/skills/cbb-worktree-close/scripts/merge-branches.js +580 -0
  50. package/cbb/worktrees/skills/cbb-worktree-close/scripts/remove-worktrees.js +44 -9
  51. package/cbb/worktrees/skills/cbb-worktree-close/scripts/safety-check.js +15 -4
  52. package/cbb/worktrees/skills/cbb-worktree-close/scripts/silence-popup.js +1 -1
  53. package/cbb/worktrees/skills/cbb-worktree-init/SKILL.md +131 -120
  54. package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-env.js +1 -1
  55. package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-repos.js +2 -2
  56. package/cbb/worktrees/skills/cbb-worktree-init/scripts/create-branches.js +33 -8
  57. package/cbb/worktrees/skills/cbb-worktree-init/scripts/create-worktrees.js +60 -46
  58. package/cbb/worktrees/skills/cbb-worktree-init/scripts/install-git-hook.js +70 -0
  59. package/cbb/worktrees/skills/cbb-worktree-init/scripts/junction-ai-config.js +192 -0
  60. package/cbb/worktrees/skills/cbb-worktree-init/scripts/parse-config.js +7 -7
  61. package/cbb/worktrees/skills/cbb-worktree-init/scripts/push-branches.js +3 -3
  62. package/cbb/worktrees/skills/cbb-worktree-init/scripts/push-core.js +1 -1
  63. package/cbb/worktrees/skills/cbb-worktree-init/scripts/silence-popup.js +1 -1
  64. package/cbb/worktrees/skills/cbb-worktree-init/scripts/sync-repos.js +11 -7
  65. package/cbb/worktrees/skills/cbb-worktree-init/scripts/update-gitignore.js +17 -5
  66. package/cbb/worktrees/skills/cbb-worktree-push/SKILL.md +213 -56
  67. package/cbb/worktrees/skills/cbb-worktree-push/scripts/check-unarchived.js +77 -0
  68. package/cbb/worktrees/skills/cbb-worktree-push/scripts/commit-worktrees.js +70 -12
  69. package/cbb/worktrees/skills/cbb-worktree-push/scripts/find-target-worktree.js +148 -96
  70. package/cbb/worktrees/skills/cbb-worktree-push/scripts/find-workspace-root.js +8 -8
  71. package/cbb/worktrees/skills/cbb-worktree-push/scripts/make-mr-urls.js +211 -0
  72. package/cbb/worktrees/skills/cbb-worktree-push/scripts/merge-branches.js +580 -0
  73. package/cbb/worktrees/skills/cbb-worktree-push/scripts/push-core.js +1 -1
  74. package/cbb/worktrees/skills/cbb-worktree-push/scripts/push-worktrees.js +67 -20
  75. package/cbb/worktrees/skills/cbb-worktree-push/scripts/silence-popup.js +1 -1
  76. package/config/{workspace-config.sample.json → CBB-WORKSPACE.sample.json} +1 -1
  77. package/config/openspec/schemas/spec-driven/schema.yaml +20 -0
  78. package/config/upstream-mirrors.json +5 -0
  79. package/external/frontend-design/.version +6 -0
  80. package/external/frontend-design/LICENSE.txt +177 -0
  81. package/external/frontend-design/SKILL.md +71 -0
  82. package/openspec/.version +2 -2
  83. package/openspec/commands/archive.md +15 -8
  84. package/openspec/commands/bulk-archive.md +13 -6
  85. package/openspec/commands/continue.md +0 -1
  86. package/openspec/commands/explore.md +1 -1
  87. package/openspec/commands/ff.md +1 -1
  88. package/openspec/commands/onboard.md +9 -4
  89. package/openspec/commands/update.md +11 -5
  90. package/openspec/commands/verify.md +57 -26
  91. package/openspec/skills/openspec-apply-change/SKILL.md +1 -1
  92. package/openspec/skills/openspec-archive-change/SKILL.md +16 -9
  93. package/openspec/skills/openspec-bulk-archive-change/SKILL.md +14 -7
  94. package/openspec/skills/openspec-continue-change/SKILL.md +1 -2
  95. package/openspec/skills/openspec-explore/SKILL.md +2 -2
  96. package/openspec/skills/openspec-ff-change/SKILL.md +2 -2
  97. package/openspec/skills/openspec-new-change/SKILL.md +1 -1
  98. package/openspec/skills/openspec-onboard/SKILL.md +10 -5
  99. package/openspec/skills/openspec-propose/SKILL.md +1 -1
  100. package/openspec/skills/openspec-sync-specs/SKILL.md +1 -1
  101. package/openspec/skills/openspec-update-change/SKILL.md +12 -6
  102. package/openspec/skills/openspec-verify-change/SKILL.md +59 -27
  103. package/package.json +3 -2
  104. package/superpowers/.version +3 -3
  105. package/superpowers/skills/writing-plans/SKILL.md +32 -20
  106. package/cbb/lib/install/codebuddy.js +0 -30
  107. package/cbb/worktrees/skills/cbb-worktree-init/scripts/find-workspace-root.js +0 -67
  108. package/config/workspace-agents.sample.md +0 -41
  109. package/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +0 -49
@@ -7,6 +7,8 @@ require('./silence-popup');
7
7
  * force: "true" 启用 --force,"false" 不启用
8
8
  *
9
9
  * 行为:
10
+ * 0. 物理删除前先显式拆除 AI 配置 junction(源文件零接触,防 Windows
11
+ * 删除例程遗留/穿透——实测 git worktree remove 遇 junction 会静默残留)
10
12
  * 1. 先移除各应用 worktree
11
13
  * 2. 再移除 workspace worktree
12
14
  * 3. 三层降级:git worktree remove → prune+rm → 仅 prune
@@ -32,6 +34,8 @@ if (!wsRoot || !branch || !forceStr) {
32
34
 
33
35
  const force = forceStr === 'true';
34
36
  const wtDir = path.join(wsRoot, '.worktrees', 'worktree-' + branch);
37
+ // AI 配置 junction 拆除脚本(close 自包含副本;源真 _shared/scripts/junction-ai-config.js)
38
+ const junctionScript = path.join(__dirname, 'junction-ai-config.js');
35
39
 
36
40
  function run(cmd, cwd) {
37
41
  try {
@@ -42,11 +46,14 @@ function run(cmd, cwd) {
42
46
  }
43
47
 
44
48
  function removePhysicalDir(dir) {
45
- // Windows 用 rmdir /s /q,Unix 用 rm -rf
46
- if (process.platform === 'win32') {
47
- return run('rmdir /s /q "' + dir + '"');
49
+ // 统一 Node fs.rmSync:跨平台;对 reparse point(junction/symlink)只删链接不穿透目标。
50
+ // 不用 rmdir /s /q / rm -rf——两者对 junction 的行为因实现/版本而异(实测 git 会静默残留目录树)
51
+ try {
52
+ fs.rmSync(dir, { recursive: true, force: true });
53
+ return { ok: true, out: '' };
54
+ } catch (e) {
55
+ return { ok: false, err: e.message };
48
56
  }
49
- return run('rm -rf "' + dir + '"');
50
57
  }
51
58
 
52
59
  const lockedDirs = [];
@@ -58,14 +65,33 @@ function removeWt(repoPath, wtPath, name) {
58
65
  return;
59
66
  }
60
67
 
68
+ // 第 0 层:显式拆除 AI 配置 junction(只解除链接、源文件零接触;
69
+ // 实测 Windows 删除例程遇 junction 会静默失败、残留整个目录树)
70
+ const jr = run('node "' + junctionScript + '" "' + wsRoot + '" "' + wtPath + '" --remove');
71
+ if (jr.ok) {
72
+ const m = (jr.out || '').match(/JUNCTION_REMOVE_RESULT (.+)$/m);
73
+ if (m) {
74
+ try {
75
+ const data = JSON.parse(m[1]);
76
+ if (data.removed && data.removed.length) console.log('🔗 ' + name + ' AI 配置 junction 已拆除:' + data.removed.join(', '));
77
+ } catch (e) {}
78
+ }
79
+ } else {
80
+ console.log('⚠️ ' + name + ' junction 拆除失败(继续移除):' + (jr.err || ''));
81
+ }
82
+
61
83
  const forceFlag = force ? ' --force' : '';
62
84
  // 第 1 层:git worktree remove
63
85
  const r1 = run('git worktree remove' + forceFlag + ' "' + wtPath + '"', repoPath);
64
- if (r1.ok) {
86
+ if (r1.ok && !fs.existsSync(wtPath)) {
65
87
  console.log('✅ ' + name + ' worktree 已移除');
66
88
  results.push({ name, status: 'removed' });
67
89
  return;
68
90
  }
91
+ if (r1.ok && fs.existsSync(wtPath)) {
92
+ // git 报成功但物理目录残留(Windows + junction/系统差异的静默失败)→ 物理兜底
93
+ console.log('⚠️ ' + name + ':git 元数据已移除但物理目录残留,执行物理清理');
94
+ }
69
95
 
70
96
  // 第 2 层:prune + 物理目录清理(解耦)
71
97
  run('git worktree prune', repoPath);
@@ -78,19 +104,28 @@ function removeWt(repoPath, wtPath, name) {
78
104
 
79
105
  // 第 3 层:目录被锁
80
106
  lockedDirs.push(wtPath);
81
- console.log('⏳ ' + name + ' 元数据已清理,物理目录被锁定(将在下次 init 时自动清理)');
107
+ console.log('⏳ ' + name + ' 元数据已清理,物理目录被锁定(init 不会自动删除目录,需手动清理)');
82
108
  results.push({ name, status: 'locked' });
83
109
  }
84
110
 
85
111
  // 1. 应用 worktrees
86
- const configPath = path.join(wsRoot, 'workspace-config.json');
112
+ const configPath = path.join(wsRoot, 'CBB-WORKSPACE.json');
87
113
  let config = {};
88
114
  try { config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (e) {}
89
115
 
90
116
  const apps = config.apps || [];
117
+ /** 解析 app worktree 物理路径:新布局 .codespace/<app> 优先,兼容 ≤beta.23 旧平铺 <app> */
118
+ function resolveAppWt(appName) {
119
+ const nested = path.join(wtDir, '.codespace', appName);
120
+ if (fs.existsSync(path.join(nested, '.git'))) return nested;
121
+ const legacy = path.join(wtDir, appName);
122
+ if (fs.existsSync(path.join(legacy, '.git'))) return legacy;
123
+ return nested;
124
+ }
125
+
91
126
  console.log('=== 移除应用 Worktrees ===');
92
127
  for (const app of apps) {
93
- const appWt = path.join(wtDir, app.name);
128
+ const appWt = resolveAppWt(app.name);
94
129
  const appPath = path.join(wsRoot, '.codespace', app.name);
95
130
  removeWt(appPath, appWt, app.name);
96
131
  }
@@ -110,7 +145,7 @@ if (lockedDirs.length > 0) {
110
145
  console.log('');
111
146
  console.log('⏳ 以下目录被外部进程占用(IDE 等),git 元数据已清理,物理目录仍保留:');
112
147
  lockedDirs.forEach(d => console.log(' - ' + d));
113
- console.log(' → 请关闭占用这些目录的程序(如 IDE)后手动删除;或下次 init-worktree 时自动清理');
148
+ console.log(' → 请关闭占用这些目录的程序(如 IDE)后手动删除(init 不再自动清理物理目录)');
114
149
  }
115
150
 
116
151
  console.log('---');
@@ -38,8 +38,10 @@ function mergedTo(repoPath, from, to) {
38
38
  if (!run('git rev-parse --verify --quiet "' + from + '"', repoPath).ok) return 1;
39
39
  if (!run('git rev-parse --verify --quiet "' + to + '"', repoPath).ok) return 2;
40
40
  if (run('git merge-base --is-ancestor "' + from + '" "' + to + '" && echo Y', repoPath).out === 'Y') return 0;
41
- const cherry = run('git cherry "' + to + '" "' + from + '" | grep -q "^+" && echo N || echo Y', repoPath);
42
- if (cherry.out === 'N') return 1;
41
+ // 跨平台:不用 grep(Windows 无 grep),解析 git cherry 输出(+ 前缀 = 未合并提交)
42
+ const cherry = run('git cherry "' + to + '" "' + from + '"', repoPath);
43
+ if (!cherry.ok) return 1;
44
+ if (cherry.out.split(/\r?\n/).filter(Boolean).some(l => l.indexOf('+') === 0)) return 1;
43
45
  return 0;
44
46
  }
45
47
 
@@ -152,19 +154,28 @@ function checkRepo(name, repoPath, wtPath) {
152
154
  return { name, wt: wtPath, fetch_ok: fetchOk, dirty_files: dirtyFiles, merged, main, remote_exists: remoteExists, remote: remoteName, unpushed_count: unpushedCount };
153
155
  }
154
156
 
155
- const configPath = path.join(wsRoot, 'workspace-config.json');
157
+ const configPath = path.join(wsRoot, 'CBB-WORKSPACE.json');
156
158
  let config = {};
157
159
  try { config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch (e) {}
158
160
 
159
161
  const apps = config.apps || [];
160
162
  const wtDir = path.join(wsRoot, '.worktrees', 'worktree-' + branch);
161
163
 
164
+ /** 解析 app worktree 物理路径:新布局 .codespace/<app> 优先,兼容 ≤beta.23 旧平铺 <app> */
165
+ function resolveAppWt(appName) {
166
+ const nested = path.join(wtDir, '.codespace', appName);
167
+ if (fs.existsSync(path.join(nested, '.git'))) return nested;
168
+ const legacy = path.join(wtDir, appName);
169
+ if (fs.existsSync(path.join(legacy, '.git'))) return legacy;
170
+ return nested;
171
+ }
172
+
162
173
  const results = [];
163
174
 
164
175
  results.push(checkRepo('workspace', wsRoot, wtDir));
165
176
 
166
177
  for (const app of apps) {
167
- const appWt = path.join(wtDir, app.name);
178
+ const appWt = resolveAppWt(app.name);
168
179
  const appPath = path.join(wsRoot, '.codespace', app.name);
169
180
  results.push(checkRepo(app.name, appPath, appWt));
170
181
  }
@@ -4,7 +4,7 @@
4
4
  // koffi is resolved from cbb global install (no local node_modules needed).
5
5
  //
6
6
  // 唯一真源:cbb/worktrees/_shared/scripts/silence-popup.js
7
- // 由 scripts/sync-shared.js 展开到各 skill 的 scripts/ 下(init / extend / close / push)。
7
+ // 由 scripts/sync-shared.js 展开到各 skill 的 scripts/ 下(init / close / push / local-mode)。
8
8
  // skill 内同目录引用:脚本第一行 `require('./silence-popup')`。
9
9
  if (process.platform === 'win32') {
10
10
  try {