@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
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * 跨平台 .tar.gz 解压工具。
5
+ *
6
+ * 用 zlib + 手写 tar parser,避开 OS shell tar(Windows 上是 bsdtar、行为不完全一致),
7
+ * 与仓库「脚本语言统一 Node.js、禁止平台绑定脚本」的约定一致。
8
+ *
9
+ * 支持:
10
+ * - gzip 压缩的 tar(GitHub tarball / npm registry tgz 都是这种)
11
+ * - 目录项(type '5' 或名字以 '/' 结尾)
12
+ * - 跳过 pax 扩展头('g'/'x')等元数据伪条目
13
+ * - 路径穿越防护(拒绝 ../ 逃逸 destDir)
14
+ *
15
+ * 不支持(上游 tarball 均不使用,遇到时跳过而非静默损坏):
16
+ * - GNU longname/longlink('L'/'K')—— 超过 100 字符的路径
17
+ */
18
+
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+ const zlib = require('zlib');
22
+
23
+ // 非文件、非目录的 tar 条目类型(pax 扩展头、GNU 长名等)
24
+ const META_TYPE_FLAGS = new Set(['g', 'x', 'L', 'K', 'V', 'N']);
25
+
26
+ /**
27
+ * 解析 tar buffer,返回条目列表(不落盘)。
28
+ * @param {Buffer} data - 已解压的 tar 数据
29
+ * @returns {Array<{name: string, size: number, typeFlag: string, dataStart: number}>}
30
+ */
31
+ function listTar(data) {
32
+ const entries = [];
33
+ let off = 0;
34
+ while (off + 512 <= data.length) {
35
+ const header = data.subarray(off, off + 512);
36
+ off += 512;
37
+
38
+ // 连续两个 512 字节零块 = tar 终止
39
+ if (header.every(b => b === 0)) break;
40
+
41
+ // 文件名 header[0..100](NUL 终止)
42
+ let nameEnd = 0;
43
+ while (nameEnd < 100 && header[nameEnd] !== 0) nameEnd++;
44
+ const name = header.subarray(0, nameEnd).toString('utf-8');
45
+
46
+ // 文件大小 header[124..136](八进制 ASCII)
47
+ const size = parseInt(header.subarray(124, 136).toString('utf-8').trim(), 8) || 0;
48
+
49
+ // 类型标志 header[156]('0'/NUL = 普通文件,'5' = 目录)
50
+ const typeFlag = String.fromCharCode(header[156]);
51
+
52
+ entries.push({ name, size, typeFlag, dataStart: off });
53
+ off += Math.ceil(size / 512) * 512;
54
+ }
55
+ return entries;
56
+ }
57
+
58
+ /**
59
+ * 解压 .tar.gz buffer 到目标目录。
60
+ * @param {Buffer} compressed - .tar.gz 文件内容
61
+ * @param {string} destDir - 解压目标根目录(不存在则创建)
62
+ * @returns {{files: number, dirs: number}} 落盘计数
63
+ */
64
+ function extractTarGz(compressed, destDir) {
65
+ const data = zlib.gunzipSync(compressed);
66
+ const root = path.resolve(destDir);
67
+ let files = 0;
68
+ let dirs = 0;
69
+
70
+ for (const entry of listTar(data)) {
71
+ if (!entry.name) continue;
72
+ // 跳过 pax 扩展头等元数据伪条目
73
+ if (META_TYPE_FLAGS.has(entry.typeFlag)) continue;
74
+
75
+ const target = path.resolve(root, entry.name);
76
+ // 路径穿越防护:解压目标必须落在 destDir 内
77
+ if (target !== root && !target.startsWith(root + path.sep)) continue;
78
+
79
+ if (entry.typeFlag === '5' || entry.name.endsWith('/')) {
80
+ fs.mkdirSync(target, { recursive: true });
81
+ dirs += 1;
82
+ } else {
83
+ fs.mkdirSync(path.dirname(target), { recursive: true });
84
+ fs.writeFileSync(target, data.subarray(entry.dataStart, entry.dataStart + entry.size));
85
+ files += 1;
86
+ }
87
+ }
88
+
89
+ return { files, dirs };
90
+ }
91
+
92
+ module.exports = { extractTarGz, listTar };
@@ -0,0 +1,90 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * 上游内容拉取的共享工具。
5
+ *
6
+ * 维护者侧(cbbm update --upstream-*)需要访问 GitHub / npm registry。
7
+ * 本模块提供:
8
+ * - 镜像前缀列表加载(config/upstream-mirrors.json,仓库内维护)
9
+ * - 带重定向跟随的 HTTPS GET
10
+ * - 「按镜像列表依次尝试」的拉取策略(首个成功即用)
11
+ *
12
+ * 镜像前缀为空字符串表示直连;列表末位通常放 "" 作为兜底。
13
+ */
14
+
15
+ const fs = require('fs');
16
+ const https = require('https');
17
+ const path = require('path');
18
+
19
+ const SHARED_STANDARDS_DIR = path.join(__dirname, '..', '..', '..');
20
+ const MIRRORS_FILE = path.join(SHARED_STANDARDS_DIR, 'config', 'upstream-mirrors.json');
21
+
22
+ /**
23
+ * 读取指定上游的镜像前缀列表。
24
+ * 文件缺失 / 解析失败 / 未配置该上游时返回 [''](仅直连)。
25
+ * @param {string} name - 上游名(如 'superpowers')
26
+ * @returns {string[]}
27
+ */
28
+ function loadMirrors(name) {
29
+ try {
30
+ const data = JSON.parse(fs.readFileSync(MIRRORS_FILE, 'utf-8'));
31
+ const list = data[name];
32
+ if (Array.isArray(list) && list.length > 0) {
33
+ return list.map(m => String(m));
34
+ }
35
+ } catch (_) { /* 回退到直连 */ }
36
+ return [''];
37
+ }
38
+
39
+ /**
40
+ * 发起 HTTPS GET,跟随重定向(最多 8 次),返回响应体 Buffer。
41
+ * @param {string} url
42
+ * @param {number} [redirectCount]
43
+ * @returns {Promise<Buffer>}
44
+ */
45
+ function httpsGetBuffer(url, redirectCount = 0) {
46
+ if (redirectCount > 8) return Promise.reject(new Error('Too many redirects'));
47
+ return new Promise((resolve, reject) => {
48
+ https.get(url, { headers: { 'User-Agent': 'cbb-cli' } }, res => {
49
+ if ([301, 302, 307, 308].includes(res.statusCode) && res.headers.location) {
50
+ res.resume();
51
+ return httpsGetBuffer(res.headers.location, redirectCount + 1).then(resolve, reject);
52
+ }
53
+ if (res.statusCode !== 200) {
54
+ res.resume();
55
+ return reject(new Error(`HTTP ${res.statusCode}: ${url}`));
56
+ }
57
+ const chunks = [];
58
+ res.on('data', c => chunks.push(c));
59
+ res.on('end', () => resolve(Buffer.concat(chunks)));
60
+ res.on('error', reject);
61
+ }).on('error', reject);
62
+ });
63
+ }
64
+
65
+ /**
66
+ * 按镜像列表依次尝试拉取,首个成功即返回。
67
+ * @param {string[]} mirrors - 镜像前缀列表('' = 直连)
68
+ * @param {(prefix: string) => string} buildUrl - 由前缀构造完整 URL
69
+ * @returns {Promise<{buffer: Buffer, mirror: string, url: string}>}
70
+ */
71
+ async function fetchWithMirrors(mirrors, buildUrl) {
72
+ const errors = [];
73
+ for (const mirror of mirrors) {
74
+ const url = buildUrl(mirror);
75
+ try {
76
+ const buffer = await httpsGetBuffer(url);
77
+ return { buffer, mirror, url };
78
+ } catch (err) {
79
+ errors.push(`${mirror || '(直连)'}: ${err.message}`);
80
+ }
81
+ }
82
+ throw new Error(`所有镜像均失败:\n ${errors.join('\n ')}`);
83
+ }
84
+
85
+ module.exports = {
86
+ MIRRORS_FILE,
87
+ loadMirrors,
88
+ httpsGetBuffer,
89
+ fetchWithMirrors,
90
+ };
@@ -1,12 +1,6 @@
1
1
  ---
2
2
  name: cbb-worktree-close
3
3
  description: "关闭/清理/删除需求工作空间的 worktree 和分支。触发:用户明确说关闭/清理/删除 worktree、结束隔离开发、合并完要清理。禁止在 cbb-worktree-init 执行后自动调用——只有用户主动要求关闭时才触发。"
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
  # Close Worktree(跨平台脚本化版本 v2.0)
@@ -29,12 +23,28 @@ metadata:
29
23
 
30
24
  ---
31
25
 
26
+ ## 调用脚本的统一方式
27
+
28
+ **重要**:本技能的所有脚本位于**本 SKILL.md 所在目录的 `scripts/` 下**(skill 目录)。
29
+
30
+ 调用时用**本技能目录的绝对路径**拼接脚本名(AI 读取本 SKILL.md 时即已知该目录),例如:
31
+
32
+ ```bash
33
+ node "<skill_dir>/scripts/<name>.js" <参数>
34
+ ```
35
+
36
+ > - `<skill_dir>` = 本 SKILL.md 所在目录的绝对路径(AI 从读取路径即可推出)
37
+ > - **cwd 必须保持在工作空间根目录**:脚本按 cwd 定位 `workspace-config.json` 与 git 仓库
38
+ > - 不要用 `./scripts/...` 裸相对路径(AI 的 cwd 不是技能目录,会解析失败)
39
+
40
+ ---
41
+
32
42
  ## Step 0:前置校验
33
43
 
34
44
  ### 0.1 环境健康探活
35
45
 
36
46
  ```bash
37
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/check-env.js"
47
+ node "<skill_dir>/scripts/check-env.js"
38
48
  ```
39
49
 
40
50
  **解读输出**:
@@ -45,7 +55,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/check-env.
45
55
  ### 0.2 定位工作空间根目录
46
56
 
47
57
  ```bash
48
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/find-workspace-root.js"
58
+ node "<skill_dir>/scripts/find-workspace-root.js"
49
59
  ```
50
60
 
51
61
  **解读输出**:
@@ -69,7 +79,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/find-works
69
79
  3. AI agent 列出 `.worktrees/` 下的所有 worktree:
70
80
 
71
81
  ```bash
72
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/find-target-worktree.js "<ws_root>"
82
+ node "<skill_dir>/scripts/find-target-worktree.js "<ws_root>"
73
83
  ```
74
84
 
75
85
  > 注:本技能支持工作空间根目录或 worktree 内执行,find-target-worktree 自动从 cwd 反推或列出。
@@ -84,7 +94,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/find-targe
84
94
  ### 1.2 发现关联应用 worktree
85
95
 
86
96
  ```bash
87
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/discover-apps.js "<ws_root>" "<branch>"
97
+ node "<skill_dir>/scripts/discover-apps.js "<ws_root>" "<branch>"
88
98
  ```
89
99
 
90
100
  脚本自动从 `workspace-config.json` 读取应用列表,扫描 `.worktrees/worktree-<branch>/<应用名>/` 实际存在的子目录。
@@ -93,12 +103,12 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/discover-a
93
103
  - `workspace` 字段:workspace worktree 绝对路径(AI agent 记录供后续命令使用)
94
104
  - `apps` 数组:实际存在的应用 worktree 列表(每项含 `name`, `repo`, `side`, `wt_path`, `app_path`)
95
105
 
96
- > 说明:app worktree 物理嵌套在 workspace worktree 内,移除 workspace worktree 时嵌套的子目录会一并消失,但各 app 仓库的 git worktree 元数据(`.git/worktrees/`)仍需通过 `git worktree remove` 逐个清理。AI 配置目录(`.claude/`、`.qoder/`、`.cbb/`)在每个 worktree 内由 init-worktree 独立安装,随 worktree 目录删除而清理,skill 无需特殊处理。
106
+ > 说明:app worktree 物理嵌套在 workspace worktree 内,移除 workspace worktree 时嵌套的子目录会一并消失,但各 app 仓库的 git worktree 元数据(`.git/worktrees/`)仍需通过 `git worktree remove` 逐个清理。AI 配置只装在业务空间根(单层安装),worktree 内没有 AI 配置目录,无需特殊处理。
97
107
 
98
108
  ### 1.3 检查未归档 change
99
109
 
100
110
  ```bash
101
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/check-unarchived.js "<ws_root>"
111
+ node "<skill_dir>/scripts/check-unarchived.js "<ws_root>"
102
112
  ```
103
113
 
104
114
  脚本扫描 `openspec/changes/` 目录,筛选出非 `archive/` 子目录的 change 名称列表。
@@ -117,7 +127,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/check-unar
117
127
  对 workspace worktree 和每个关联应用 worktree,依次执行三项检查并汇总成安全状态表。**这是破坏性操作前的必经环节,结果将驱动 Step 3 的用户决策。**
118
128
 
119
129
  ```bash
120
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/safety-check.js "<ws_root>" "<branch>"
130
+ node "<skill_dir>/scripts/safety-check.js "<ws_root>" "<branch>"
121
131
  ```
122
132
 
123
133
  脚本内部对每个仓库自动执行:
@@ -226,10 +236,10 @@ AskUserQuestion({
226
236
 
227
237
  ```bash
228
238
  # 仅删本地分支(已合并自动 -d,未合并自动 -D;含 squash 合并 -D 兜底)
229
- node "<skill>/scripts/delete-branches.js" "<ws_root>" "<branch>" local
239
+ node "<skill_dir>/scripts/delete-branches.js" "<ws_root>" "<branch>" local
230
240
 
231
241
  # 删本地 + 远程分支
232
- node "<skill>/scripts/delete-branches.js" "<ws_root>" "<branch>" local_remote
242
+ node "<skill_dir>/scripts/delete-branches.js" "<ws_root>" "<branch>" local_remote
233
243
  ```
234
244
 
235
245
  **调用前的强警告**(调用方需自评):
@@ -260,7 +270,7 @@ node "<skill>/scripts/delete-branches.js" "<ws_root>" "<branch>" local_remote
260
270
  [中止] 终止流程,我先手动处理
261
271
  ```
262
272
 
263
- - 用户选择「先推送」→ AI 引导用户执行 `cbb-worktree-push`(或 `/cbb:worktree-push`),完成后**重新跑** Step 2 safety-check 确认 `unpushed_count = 0` 再回到本步骤
273
+ - 用户选择「先推送」→ AI 引导用户执行 `cbb-worktree-push` skill(或 `/cbb-worktree-push`),完成后**重新跑** Step 2 safety-check 确认 `unpushed_count = 0` 再回到本步骤
264
274
  - 用户选择「接受丢失」→ 必须二次确认(ahead 提交真的会丢),确认后继续 Step 4
265
275
  - 用户选择「中止」→ 终止流程
266
276
 
@@ -289,14 +299,14 @@ node "<skill>/scripts/delete-branches.js" "<ws_root>" "<branch>" local_remote
289
299
  **顺序:先移除各应用 worktree,再移除 workspace worktree**(逆序于创建;也为后续删分支扫清"分支仍被检出"的障碍)。
290
300
 
291
301
  ```bash
292
- node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/remove-worktrees.js "<ws_root>" "<branch>" "<force>"
302
+ node "<skill_dir>/scripts/remove-worktrees.js "<ws_root>" "<branch>" "<force>"
293
303
  ```
294
304
 
295
305
  **三层降级策略**:`git worktree remove` 实际包含两个动作——①清理 git 元数据(`.git/worktrees/`)②删除物理目录。当 IDE 占用目录时 ② 会被 Windows 文件锁阻塞,但 ① 永远不受影响。脚本将这两个动作解耦:
296
306
 
297
307
  - **第 1 层(正常路径):** `git worktree remove` 一步完成元数据 + 物理目录清理
298
308
  - **第 2 层(解耦清理):** 当目录被锁时,先 `prune` 清理 git 元数据(始终成功),再 `rmdir`/`rm -rf` 尝试物理删除
299
- - **第 3 层(延迟清理):** Windows 下 IDE 持有排他句柄时触发。元数据已清理保证分支删除不受影响;物理目录留给 init-worktree 下次创建时自愈(见 init Step 4.0)
309
+ - **第 3 层(延迟清理):** Windows 下 IDE 持有排他句柄时触发。元数据已清理保证分支删除不受影响;物理目录**不会被 init 自动删除**(0.0.3-beta.11 init prune 元数据、绝不删目录,防误删活跃 worktree),需用户关闭 IDE 后手动删除,或重跑 close 补删
300
310
 
301
311
  **解读末行 `REMOVE_RESULT`**:
302
312
  - `has_locked: false` → 全部清理成功
@@ -333,9 +343,9 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/remove-wor
333
343
  如用户在 Step 1.1 选定 worktree 时已要求"删除分支",或运行后需要单独清理,可在此步骤**手动调用**:
334
344
 
335
345
  ```bash
336
- node "<skill>/scripts/delete-branches.js" "<ws_root>" "<branch>" local
346
+ node "<skill_dir>/scripts/delete-branches.js" "<ws_root>" "<branch>" local
337
347
  # 或
338
- node "<skill>/scripts/delete-branches.js" "<ws_root>" "<branch>" local_remote
348
+ node "<skill_dir>/scripts/delete-branches.js" "<ws_root>" "<branch>" local_remote
339
349
  ```
340
350
 
341
351
  脚本内部对每个仓库:
@@ -388,7 +398,6 @@ git -C "<ws_root>" worktree list
388
398
  ⏭️ fix-payment-timeout → 用户选择跳过
389
399
  (无未归档 change 时不显示本节)
390
400
  分支处理:feature-xxx 已保留(默认行为;如需删除分支,手动调用 scripts/delete-branches.js)
391
- AI 配置:worktree 内独立安装,随 worktree 删除而清理;工作空间根目录的 AI 配置保留
392
401
  剩余工作空间 worktree:<列出仍存在的,或 "无" >
393
402
  Workspace cleaned up.
394
403
  ```
@@ -411,10 +420,10 @@ git -C "<ws_root>" worktree list
411
420
  - 未经用户确认用 `--force` 丢弃未提交修改,或主动调用 `delete-branches.js` 对未合并分支执行 `-D` 强删
412
421
  - 操作 `.worktrees/worktree-<需求名>` 以外的任何 worktree(如 `~/.qoder/worktree/...` 会话 worktree)
413
422
  - 移除/删除前跳过 Step 2 安全评估
414
- - 删除工作空间根目录的 AI 配置目录(`.claude/`、`.qoder/`、`.cbb/` 等源目录)
423
+ - 删除工作空间根目录的 AI 配置目录(`.claude/`、`.qoder/`、`.opencode/` 等)
415
424
  - 用 `AskUserQuestion` 收集自由文本(分支名等直接对话提问)
416
425
  - 手动改任何仓库的 `.gitignore`(关闭流程不碰它)
417
- - 沙箱内 node 不可用时强行继续 → 改为 fail-fast 提示用户
426
+ - 运行环境 node 不可用时强行继续 → 改为 fail-fast 提示用户
418
427
 
419
428
  ### 必须执行
420
429
 
@@ -429,7 +438,7 @@ git -C "<ws_root>" worktree list
429
438
  - **合并判定依赖刷新后的远程引用,故 Step 2.0 先主动 `git fetch`**:feature 多由他人经 MR 合入远端,本地引用否则会陈旧误判
430
439
  - **并行块用临时文件收结果、不用共享变量**:原 bash 版本中 `&` 后台任务跑在独立子 shell;Node.js 同步执行无此问题
431
440
  - **`.gitignore` 无需清理**:创建时的 `.worktrees/` 条目提交在 feature 分支上,删分支时随分支消失(未合并)或无害保留(已合并)
432
- - **AI 配置目录在每个 worktree 内独立安装**:关闭 worktree 时这些目录随 worktree 目录一起删除
441
+ - **AI 配置只装在空间根(单层安装)**:worktree 内没有 AI 配置目录,关闭时无需处理
433
442
  - **部分 `worktree remove` 失败**:已移除的无需回退,未移除的报告详情让用户处理后重跑
434
443
  - **Windows IDE 目录锁的三层降级**:`git worktree remove` 内部做两件事——①清元数据 ②删目录。Windows 文件锁只阻塞 ②,不阻塞 ①
435
444
 
@@ -34,7 +34,7 @@ const checks = {};
34
34
  // ── 必检:git ─────────────────────────────────────────
35
35
  checks.git = tryExec('git --version');
36
36
  if (!checks.git.ok) {
37
- console.error('❌ git 启动失败(可能是 Qoder 沙箱 DLL 问题 0xc0000142)');
37
+ console.error('❌ git 启动失败(可能是 Agent 运行环境 DLL 问题 0xc0000142)');
38
38
  console.error(' 解决方案:到系统终端重新执行本技能');
39
39
  process.exit(1);
40
40
  }
@@ -57,12 +57,12 @@ if (!checks.node.ok) {
57
57
  console.log('✅ node OK:', checks.node.out);
58
58
  }
59
59
 
60
- // ── 沙箱检测 ─────────────────────────────────────────
60
+ // ── 运行环境检测 ─────────────────────────────────────────
61
61
  const inWorktree = !!(process.env.QODER_AGENT || process.env.QODER_WORKTREE);
62
62
  if (inWorktree) {
63
- console.log('🛡️ Qoder 沙箱环境:移除 worktree 时如遇 IDE 锁,将降级处理');
63
+ console.log('🛡️ Qoder Agent 运行环境:移除 worktree 时如遇 IDE 锁,将降级处理');
64
64
  } else {
65
- console.log('✅ 非沙箱环境');
65
+ console.log('✅ 系统终端环境');
66
66
  }
67
67
 
68
68
  const summary = {
@@ -78,7 +78,7 @@ function removeWt(repoPath, wtPath, name) {
78
78
 
79
79
  // 第 3 层:目录被锁
80
80
  lockedDirs.push(wtPath);
81
- console.log('⏳ ' + name + ' 元数据已清理,物理目录被锁定(将在下次 init 时自动清理)');
81
+ console.log('⏳ ' + name + ' 元数据已清理,物理目录被锁定(init 不会自动删除目录,需手动清理)');
82
82
  results.push({ name, status: 'locked' });
83
83
  }
84
84
 
@@ -110,7 +110,7 @@ if (lockedDirs.length > 0) {
110
110
  console.log('');
111
111
  console.log('⏳ 以下目录被外部进程占用(IDE 等),git 元数据已清理,物理目录仍保留:');
112
112
  lockedDirs.forEach(d => console.log(' - ' + d));
113
- console.log(' → 请关闭占用这些目录的程序(如 IDE)后手动删除;或下次 init-worktree 时自动清理');
113
+ console.log(' → 请关闭占用这些目录的程序(如 IDE)后手动删除(init 不再自动清理物理目录)');
114
114
  }
115
115
 
116
116
  console.log('---');