@jspg-ai/coding-bb 0.0.3-beta.3 → 0.0.3-beta.31

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/dev-standards/rules/cbb-ai-behavior.md +135 -116
  2. package/cbb/lib/external/index.js +228 -0
  3. package/cbb/lib/install/agents-nav.js +92 -0
  4. package/cbb/lib/install/claude-code.js +7 -2
  5. package/cbb/lib/install/command-skill.js +105 -0
  6. package/cbb/lib/install/init.js +502 -168
  7. package/cbb/lib/install/minimax.js +60 -0
  8. package/cbb/lib/install/opencode.js +3 -5
  9. package/cbb/lib/install/qoder.js +1 -3
  10. package/cbb/lib/install/rule-rewrite.js +27 -0
  11. package/cbb/lib/install/setup-decision.js +48 -0
  12. package/cbb/lib/install/tool-selection.js +45 -0
  13. package/cbb/lib/install/trae.js +43 -0
  14. package/cbb/lib/install/workbuddy.js +36 -0
  15. package/cbb/lib/install/workspaces.js +21 -17
  16. package/cbb/lib/openspec/index.js +337 -554
  17. package/cbb/lib/superpowers/index.js +246 -265
  18. package/cbb/lib/utils/check-update.js +17 -2
  19. package/cbb/lib/utils/githook.js +226 -0
  20. package/cbb/lib/utils/gitignore.js +16 -3
  21. package/cbb/lib/utils/plugin-hook.js +92 -0
  22. package/cbb/lib/utils/settings.js +17 -4
  23. package/cbb/lib/utils/tar.js +92 -0
  24. package/cbb/lib/utils/upstream.js +90 -0
  25. package/cbb/worktrees/_shared/scripts/check-local-state.js +114 -0
  26. package/cbb/worktrees/_shared/scripts/find-target-worktree.js +148 -96
  27. package/cbb/worktrees/_shared/scripts/find-workspace-root.js +7 -7
  28. package/cbb/worktrees/_shared/scripts/install-git-hook.js +70 -0
  29. package/cbb/worktrees/_shared/scripts/junction-ai-config.js +127 -0
  30. package/cbb/worktrees/_shared/scripts/start-local.js +180 -0
  31. package/cbb/worktrees/skills/cbb-local-mode/SKILL.md +158 -0
  32. package/cbb/worktrees/skills/cbb-local-mode/scripts/check-local-state.js +114 -0
  33. package/cbb/worktrees/skills/cbb-local-mode/scripts/install-git-hook.js +70 -0
  34. package/cbb/worktrees/skills/cbb-local-mode/scripts/silence-popup.js +23 -0
  35. package/cbb/worktrees/skills/cbb-local-mode/scripts/start-local.js +180 -0
  36. package/cbb/worktrees/skills/cbb-worktree-close/SKILL.md +60 -43
  37. package/cbb/worktrees/skills/cbb-worktree-close/scripts/check-env.js +3 -3
  38. package/cbb/worktrees/skills/cbb-worktree-close/scripts/check-unarchived.js +75 -48
  39. package/cbb/worktrees/skills/cbb-worktree-close/scripts/delete-branches.js +1 -1
  40. package/cbb/worktrees/skills/cbb-worktree-close/scripts/discover-apps.js +14 -5
  41. package/cbb/worktrees/skills/cbb-worktree-close/scripts/find-target-worktree.js +148 -96
  42. package/cbb/worktrees/skills/cbb-worktree-close/scripts/find-workspace-root.js +7 -7
  43. package/cbb/worktrees/skills/cbb-worktree-close/scripts/remove-worktrees.js +13 -4
  44. package/cbb/worktrees/skills/cbb-worktree-close/scripts/safety-check.js +11 -2
  45. package/cbb/worktrees/skills/cbb-worktree-init/SKILL.md +138 -129
  46. package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-env.js +1 -1
  47. package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-repos.js +2 -2
  48. package/cbb/worktrees/skills/cbb-worktree-init/scripts/create-branches.js +33 -8
  49. package/cbb/worktrees/skills/cbb-worktree-init/scripts/create-worktrees.js +60 -46
  50. package/cbb/worktrees/skills/cbb-worktree-init/scripts/find-workspace-root.js +7 -7
  51. package/cbb/worktrees/skills/cbb-worktree-init/scripts/install-git-hook.js +70 -0
  52. package/cbb/worktrees/skills/cbb-worktree-init/scripts/junction-ai-config.js +127 -0
  53. package/cbb/worktrees/skills/cbb-worktree-init/scripts/parse-config.js +7 -7
  54. package/cbb/worktrees/skills/cbb-worktree-init/scripts/push-branches.js +3 -3
  55. package/cbb/worktrees/skills/cbb-worktree-init/scripts/sync-repos.js +11 -7
  56. package/cbb/worktrees/skills/cbb-worktree-init/scripts/update-gitignore.js +37 -9
  57. package/cbb/worktrees/skills/cbb-worktree-push/SKILL.md +140 -71
  58. package/cbb/worktrees/skills/cbb-worktree-push/scripts/commit-worktrees.js +70 -12
  59. package/cbb/worktrees/skills/cbb-worktree-push/scripts/find-target-worktree.js +148 -96
  60. package/cbb/worktrees/skills/cbb-worktree-push/scripts/find-workspace-root.js +7 -7
  61. package/cbb/worktrees/skills/cbb-worktree-push/scripts/make-mr-urls.js +211 -0
  62. package/cbb/worktrees/skills/cbb-worktree-push/scripts/push-worktrees.js +67 -20
  63. package/config/{workspace-config.sample.json → CBB-WORKSPACE.sample.json} +1 -1
  64. package/config/openspec/schemas/spec-driven/schema.yaml +40 -30
  65. package/config/openspec/schemas/spec-driven/templates/design.md +0 -18
  66. package/config/openspec/schemas/spec-driven/templates/proposal.md +4 -3
  67. package/config/upstream-mirrors.json +17 -0
  68. package/config/workspace-agents.sample.md +4 -33
  69. package/external/frontend-design/.version +6 -0
  70. package/external/frontend-design/LICENSE.txt +177 -0
  71. package/external/frontend-design/SKILL.md +71 -0
  72. package/openspec/.version +2 -3
  73. package/openspec/commands/apply.md +189 -175
  74. package/openspec/commands/archive.md +244 -216
  75. package/openspec/commands/bulk-archive.md +362 -327
  76. package/openspec/commands/continue.md +115 -105
  77. package/openspec/commands/explore.md +230 -199
  78. package/openspec/commands/ff.md +115 -104
  79. package/openspec/commands/new.md +74 -63
  80. package/openspec/commands/onboard.md +562 -548
  81. package/openspec/commands/propose.md +161 -150
  82. package/openspec/commands/sync.md +277 -249
  83. package/openspec/commands/update.md +98 -80
  84. package/openspec/commands/verify.md +206 -162
  85. package/openspec/skills/openspec-apply-change/SKILL.md +20 -5
  86. package/openspec/skills/openspec-archive-change/SKILL.md +40 -11
  87. package/openspec/skills/openspec-bulk-archive-change/SKILL.md +46 -9
  88. package/openspec/skills/openspec-continue-change/SKILL.md +14 -3
  89. package/openspec/skills/openspec-explore/SKILL.md +22 -10
  90. package/openspec/skills/openspec-ff-change/SKILL.md +15 -3
  91. package/openspec/skills/openspec-new-change/SKILL.md +13 -1
  92. package/openspec/skills/openspec-onboard/SKILL.md +58 -43
  93. package/openspec/skills/openspec-propose/SKILL.md +15 -3
  94. package/openspec/skills/openspec-sync-specs/SKILL.md +31 -2
  95. package/openspec/skills/openspec-update-change/SKILL.md +34 -15
  96. package/openspec/skills/openspec-verify-change/SKILL.md +72 -26
  97. package/package.json +3 -2
  98. package/superpowers/.version +4 -4
  99. package/superpowers/skills/brainstorming/SKILL.md +47 -12
  100. package/superpowers/skills/brainstorming/scripts/frame-template.html +213 -213
  101. package/superpowers/skills/brainstorming/scripts/server.cjs +723 -723
  102. package/superpowers/skills/brainstorming/visual-companion.md +6 -6
  103. package/superpowers/skills/diagnosing-superpowers/SKILL.md +120 -0
  104. package/superpowers/skills/diagnosing-superpowers/prompts/analyst-common.md +38 -0
  105. package/superpowers/skills/diagnosing-superpowers/prompts/cost-and-time.md +28 -0
  106. package/superpowers/skills/diagnosing-superpowers/prompts/plan-adherence.md +29 -0
  107. package/superpowers/skills/diagnosing-superpowers/prompts/quality-evidence.md +26 -0
  108. package/superpowers/skills/diagnosing-superpowers/prompts/repeated-work.md +30 -0
  109. package/superpowers/skills/diagnosing-superpowers/prompts/request-conflicts.md +20 -0
  110. package/superpowers/skills/diagnosing-superpowers/prompts/scrub-audit.md +33 -0
  111. package/superpowers/skills/diagnosing-superpowers/prompts/scrub.md +29 -0
  112. package/superpowers/skills/diagnosing-superpowers/prompts/similar-session.md +38 -0
  113. package/superpowers/skills/diagnosing-superpowers/prompts/skill-timeline.md +30 -0
  114. package/superpowers/skills/diagnosing-superpowers/prompts/stumbles.md +28 -0
  115. package/superpowers/skills/diagnosing-superpowers/references/context-safety.md +22 -0
  116. package/superpowers/skills/diagnosing-superpowers/references/github-issues.md +47 -0
  117. package/superpowers/skills/diagnosing-superpowers/references/redaction-policy.md +34 -0
  118. package/superpowers/skills/diagnosing-superpowers/references/session-discovery.md +31 -0
  119. package/superpowers/skills/diagnosing-superpowers/templates/bundle-README.md +77 -0
  120. package/superpowers/skills/diagnosing-superpowers/templates/case.md +64 -0
  121. package/superpowers/skills/diagnosing-superpowers/templates/issue.md +51 -0
  122. package/superpowers/skills/diagnosing-superpowers/templates/report.md +82 -0
  123. package/superpowers/skills/executing-plans/SKILL.md +350 -41
  124. package/superpowers/skills/executing-plans/scripts/task-done +52 -0
  125. package/superpowers/skills/executing-plans/scripts/task-start +28 -0
  126. package/superpowers/skills/requesting-code-review/SKILL.md +1 -1
  127. package/superpowers/skills/requesting-code-review/code-reviewer.md +17 -0
  128. package/superpowers/skills/subagent-driven-development/SKILL.md +18 -18
  129. package/superpowers/skills/subagent-driven-development/re-review-prompt.md +1 -1
  130. package/superpowers/skills/subagent-driven-development/scripts/review-package +53 -46
  131. package/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +82 -40
  132. package/superpowers/skills/subagent-driven-development/scripts/task-brief +43 -41
  133. package/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +2 -2
  134. package/superpowers/skills/systematic-debugging/root-cause-tracing.md +1 -1
  135. package/superpowers/skills/test-driven-development/SKILL.md +10 -0
  136. package/superpowers/skills/using-superpowers/SKILL.md +2 -0
  137. package/superpowers/skills/using-superpowers/references/claude-code-tools.md +29 -0
  138. package/superpowers/skills/using-superpowers/references/muse-tools.md +35 -0
  139. package/superpowers/skills/writing-plans/SKILL.md +62 -29
  140. package/superpowers/skills/writing-skills/SKILL.md +4 -2
  141. package/superpowers/skills/writing-skills/graphviz-conventions.dot +171 -171
  142. package/cbb/worktrees/commands/worktree-close.md +0 -64
  143. package/cbb/worktrees/commands/worktree-init.md +0 -51
  144. package/cbb/worktrees/commands/worktree-push.md +0 -42
  145. package/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +0 -49
@@ -0,0 +1,60 @@
1
+ /**
2
+ * MiniMax Code(mcode CLI)适配器
3
+ *
4
+ * 官方源码考证结论(agent.minimaxi.com 文档站 + 源码浅克隆):
5
+ * - rules:MiniMax 无原生 rules 自动读取逻辑(源码无 .minimax/rules 读取),
6
+ * 规则照常分发到 .minimax/rules/,靠 AGENTS.md 托管导航块(agentsNav)引导
7
+ * AI 主动读取——AGENTS.md 是 MiniMax 唯一的项目级规则注入通道
8
+ * (local-runtime/src/project/instructions.ts,32KB 预算)。
9
+ * - skills:.minimax/skills 为原生 workspace skill 根(skills/roots.ts),
10
+ * 标准 Agent Skills 格式(目录名 = frontmatter name)零改写。
11
+ * - commands:MiniMax 无项目级 commands 目录,openspec 命令转 skill 形态分发
12
+ * (skill 即其命令形态,/opsx-propose 斜杠照常可用),commandsAsSkills: true。
13
+ * - hooks:无 Claude 式 settings.json hooks(hooks 仅插件作用域),版本检查改用
14
+ * 用户级本地插件(<data-dir>/plugins/cbb-check-update,声明 UserPromptSubmit)。
15
+ *
16
+ * 数据目录:MINIMAX_DATA_DIR(优先)> MAVIS_DATA_DIR > ~/.minimax,与 mcode
17
+ * 运行时一致;用户若改过数据目录,需重跑 cbb update 以重装插件到新位置。
18
+ *
19
+ * 退市(selectable: false):实测 MiniMax Code 不支持目录级 skill 与 command
20
+ * (无项目级 commands 目录,skill 亦需插件形态承载),当前分发形态不可用。
21
+ * 适配器代码与全部能力保留(备将来改走插件形态),但不在安装面板提供;
22
+ * 已安装过(beta.29)的空间按 .last-tools 记录**粘性维护**,内容不被清理。
23
+ */
24
+
25
+ const path = require('path');
26
+ const os = require('os');
27
+
28
+ /** 解析 mcode 数据目录(调用时求值,便于环境变量覆盖与测试) */
29
+ function resolveDataDir() {
30
+ return process.env.MINIMAX_DATA_DIR
31
+ || process.env.MAVIS_DATA_DIR
32
+ || path.join(os.homedir(), '.minimax');
33
+ }
34
+
35
+ module.exports = {
36
+ name: 'minimax',
37
+ displayName: 'MiniMax Code',
38
+ rulesDir: '.minimax/rules',
39
+ skillsDir: '.minimax/skills',
40
+ // 无项目级 commands 目录:openspec 命令转 <skillsDir>/<prefix><name>/SKILL.md
41
+ commandsAsSkills: true,
42
+ commandPrefix: 'opsx-',
43
+ // 部署副本中把 /opsx: 与 /cbb: 引用改写为 skill 斜杠风格(/opsx-propose)
44
+ contentRewrites: [['/opsx:', '/opsx-'], ['/cbb:', '/cbb-']],
45
+ // AGENTS.md 托管导航块(幂等注入 / 卸载精确摘除,不触碰块外用户内容)
46
+ agentsNav: {
47
+ file: 'AGENTS.md',
48
+ text: '⚠️ 规则优先:在当前目录下执行的任何任务(不限于编码任务)开始前,必须先读取并遵循 `.minimax/rules/` 中的相关规则文件。',
49
+ },
50
+ // 版本检查 hook:用户级本地插件(<dataDir>/plugins/<dirName>,自动发现热加载、默认启用)
51
+ pluginHook: {
52
+ dirName: 'cbb-check-update',
53
+ events: ['UserPromptSubmit'],
54
+ // 解析上限:MiniMax timeout 单位为秒,1–10(超出视为非法回落 5s)
55
+ timeout: 10,
56
+ },
57
+ resolveDataDir,
58
+ // 退市:不在安装面板提供(代码保留,存量空间粘性维护)
59
+ selectable: false,
60
+ };
@@ -9,8 +9,7 @@
9
9
  * 官方支持的配置位置:全局目录 / 项目根 / .opencode 目录内均会被发现)
10
10
  * - skills:.opencode/skills/<name>/SKILL.md,结构与 Claude 同构
11
11
  * - commands:命令名 = 文件名(嵌套目录无命名空间,且 init.md 等会撞内置 /init),
12
- * 因此扁平化为 opsx-<name>.md(/opsx-propose);worktree 管理命令同理扁平化为
13
- * cbb-<name>.md(/cbb-worktree-init),部署副本中的 /opsx: 与 /cbb: 引用同步改写
12
+ * 因此扁平化为 opsx-<name>.md(/opsx-propose);部署副本中的 /opsx: 与 /cbb: 引用同步改写
14
13
  * - hooks:opencode 无 UserPromptSubmit 等价事件,版本检查 hook 不安装(settingsFile 留空即跳过)
15
14
  */
16
15
 
@@ -22,11 +21,10 @@ module.exports = {
22
21
  commandsDir: '.opencode/commands',
23
22
  // 部署时给命令文件名加此前缀(规避内置命令名冲突)
24
23
  commandPrefix: 'opsx-',
25
- // worktree 管理命令(非 openspec 上游)落在同一扁平目录,用 cbb- 前缀区分
26
- worktreeCommandsDir: '.opencode/commands',
27
- worktreeCommandPrefix: 'cbb-',
28
24
  // 部署副本中将该引用串改写为 opencode 的命令风格(配合 commandPrefix)
29
25
  contentRewrites: [['/opsx:', '/opsx-'], ['/cbb:', '/cbb-']],
26
+ // 命令显示名取自 frontmatter name,部署副本重写为 kebab-case(/opsx-propose,与文档一致)
27
+ commandNameKebab: true,
30
28
  // rules 加载登记:写入 .opencode/opencode.json 的 instructions。
31
29
  // instructions 相对路径的解析基准(配置文件目录 vs 项目根)文档未写死,
32
30
  // 登记双 glob 对冲:任一基准下恰有一个命中,另一个空匹配。
@@ -13,9 +13,7 @@ module.exports = {
13
13
  rulesDir: '.qoder/rules',
14
14
  skillsDir: '.qoder/skills',
15
15
  commandsDir: '.qoder/commands/opsx',
16
- // worktree 管理命令(非 openspec 上游):独立命名空间 /cbb:worktree-*
17
- worktreeCommandsDir: '.qoder/commands/cbb',
18
- // 用户级 settings,写入全局生效,不污染项目目录
16
+ // 用户级 settings,写入全局生效,不污染项目目录
19
17
  settingsFile: path.join(os.homedir(), '.qoder', 'settings.json'),
20
18
  settingsFileIsUserLevel: true,
21
19
  hookEvents: ['UserPromptSubmit'],
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * 规则 frontmatter 改写(纯函数,无副作用,便于单测)。
5
+ *
6
+ * 源规则(cbb/dev-standards/rules/*.md)用 Qoder 的 frontmatter 约定
7
+ * `trigger: always_on`。各工具对"始终生效"的字段名不同:
8
+ * - Qoder:trigger: always_on(源格式)
9
+ * - Claude Code / opencode:无该字段,靠各自机制加载
10
+ * - WorkBuddy、Trae:alwaysApply: true
11
+ *
12
+ * 适配器通过 ruleRewrites([[from, to], ...])声明改写规则,部署时套用;
13
+ * 无 ruleRewrites 的适配器原样返回。
14
+ */
15
+
16
+ /**
17
+ * 按适配器的 ruleRewrites 改写规则文本。
18
+ * @param {object} adapter 适配器配置
19
+ * @param {string} text 规则文件原文
20
+ * @returns {string} 改写后的文本(无 ruleRewrites 时原样返回)
21
+ */
22
+ function applyRuleRewrites(adapter, text) {
23
+ if (!adapter || !adapter.ruleRewrites) return text;
24
+ return adapter.ruleRewrites.reduce((t, [from, to]) => t.split(from).join(to), text);
25
+ }
26
+
27
+ module.exports = { applyRuleRewrites };
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * cbb setup 空间级安装的跳过判定(纯逻辑,可单测)。
5
+ *
6
+ * 背景 bug(0.0.3-beta.15 修复):旧版 decideUpgradeIfInstalled 只比较
7
+ * 「已装版本 vs 当前包版本」,版本一致即 skip——导致「空间已是当前版本 +
8
+ * 本次新选了工具(如 WorkBuddy)」被整体跳过,新工具的空间级目录
9
+ * (.workbuddy/ 等)永不生成,.last-tools 也不更新。
10
+ */
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+
15
+ /**
16
+ * 读取 <targetDir>/.cbb/.last-tools 的已装工具集合。
17
+ * @param {string} targetDir 业务空间根
18
+ * @returns {Set<string>|null} 工具名集合;无文件或解析失败返回 null
19
+ */
20
+ function readLastToolsFrom(targetDir) {
21
+ const filePath = path.join(targetDir, '.cbb', '.last-tools');
22
+ if (!fs.existsSync(filePath)) return null;
23
+ try {
24
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
25
+ return new Set(data.tools || []);
26
+ } catch (_) {
27
+ return null;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * 判定已安装空间本次 setup 应跳过还是继续安装。
33
+ * @param {object} p
34
+ * @param {boolean} p.sameVersion 已装版本 == 当前包版本
35
+ * @param {Set<string>|null} p.lastTools .last-tools 记录(null = 无记录)
36
+ * @param {string[]} p.selectedNames 本次选中的工具名
37
+ * @returns {{action:'skip'|'install', newTools:string[], reason:string}}
38
+ * reason: 'version-changed' | 'no-tools-record' | 'new-tools' | 'up-to-date'
39
+ */
40
+ function decideSetupAction({ sameVersion, lastTools, selectedNames }) {
41
+ if (!sameVersion) return { action: 'install', newTools: [], reason: 'version-changed' };
42
+ if (lastTools === null) return { action: 'install', newTools: [], reason: 'no-tools-record' };
43
+ const newTools = (selectedNames || []).filter(n => !lastTools.has(n));
44
+ if (newTools.length > 0) return { action: 'install', newTools, reason: 'new-tools' };
45
+ return { action: 'skip', newTools: [], reason: 'up-to-date' };
46
+ }
47
+
48
+ module.exports = { decideSetupAction, readLastToolsFrom };
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * 工具选择策略:安装面板的可见集合 + 退市工具的粘性保留。
5
+ *
6
+ * 背景(2026-09-28 决策):MiniMax Code 实测不支持目录级 skill 与 command、
7
+ * Claude Code 团队当前未用,两者**退市**——适配器与全部能力保留(见各适配器
8
+ * 文件头),仅不在 `cbb setup` / `cbb update` 的安装面板提供。
9
+ *
10
+ * 两条规则:
11
+ * 1. **可选项**(selectableAdapters):面板项、非交互全选兜底、setup 默认预选、
12
+ * 用户级组件新装,一律只用未退市适配器(`selectable !== false`);
13
+ * 2. **粘性保留**(carryOverRetired):某空间的 `.last-tools` 记录过退市工具
14
+ * (即确曾安装),则继续纳入本次安装/升级集合——面板不出现,内容不因退市
15
+ * 被清单差集清删;`.last-tools` 一并保持该记录,避免记录丢失导致下次清理。
16
+ *
17
+ * 恢复入口:删掉适配器的 `selectable: false` 即回到面板(决策:不留参数开关)。
18
+ */
19
+
20
+ /** 面板/默认可选适配器(未标 selectable: false 的全部) */
21
+ function selectableAdapters(adapters) {
22
+ return adapters.filter(a => a.selectable !== false);
23
+ }
24
+
25
+ /**
26
+ * 把「本空间旧记录中的退市工具」并入选择结果(按注册表顺序追加,去重)。
27
+ * @param {Array} adapters 注册表全量
28
+ * @param {Array} selected 本次选择(面板 / 预设 / 记录沿用)
29
+ * @param {Set<string>|null} lastTools 该空间的旧工具记录(.last-tools)
30
+ * @returns {Array} 并入后的有序数组(无退市工具需保留时原样返回)
31
+ */
32
+ function carryOverRetired(adapters, selected, lastTools) {
33
+ if (!lastTools || lastTools.size === 0) return selected;
34
+ const selectedNames = new Set(selected.map(a => a.name));
35
+ const carried = adapters.filter(a =>
36
+ a.selectable === false && lastTools.has(a.name) && !selectedNames.has(a.name));
37
+ return carried.length > 0 ? selected.concat(carried) : selected;
38
+ }
39
+
40
+ /** 结果集中退市工具的显示名(供安装输出提示,如「保留上次选择的 Claude Code」) */
41
+ function retiredNames(selected) {
42
+ return selected.filter(a => a.selectable === false).map(a => a.displayName);
43
+ }
44
+
45
+ module.exports = { selectableAdapters, carryOverRetired, retiredNames };
@@ -0,0 +1,43 @@
1
+ /**
2
+ * TraeWork / TraeCode 适配器(中国版)
3
+ *
4
+ * 中国版 TraeCode IDE 与 TraeWork 的项目级配置目录为 `.trae/`
5
+ * (官方文档 docs.trae.cn:项目规则 `.trae/rules/`、项目命令 `.trae/commands`),
6
+ * `.trae-cn/` 仅是中国版**用户级**目录(~/.trae-cn/hooks.json、user_rules、commands),
7
+ * 与国际版共用项目级 `.trae/` 命名。cbb 仅支持中国版(我司均用中国版)。
8
+ *
9
+ * 与 Claude Code / Qoder 的映射差异:
10
+ * - rules:`.trae/rules/*.md`(扁平文件、支持子目录,最多 3 层),frontmatter 用
11
+ * `alwaysApply: true`(Qoder 的 `trigger: always_on` 需改写,见 ruleRewrites)
12
+ * - skills:`.trae/skills/<name>/SKILL.md`,结构与 Claude 同构
13
+ * - commands:命令名 = 文件名,无 Claude 式"目录:命令"命名空间(实测嵌套目录 +
14
+ * `name: "OPSX: Apply"` 不出现在斜杠列表),故与 opencode 同款扁平化为
15
+ * `.trae/commands/opsx-<name>.md`(/opsx-propose),frontmatter name 同步 kebab 化
16
+ * - hooks:`~/.trae-cn/hooks.json`(用户级),格式与 Claude 相近但需顶层 `version: 1`
17
+ * (由 settingsManager 的 hookDialect 处理),事件名/输出字段一致
18
+ *
19
+ * 注意:不设 legacyDirs —— `.trae/` 本就是正确的项目级目录,无需清理。
20
+ */
21
+
22
+ const path = require('path');
23
+ const os = require('os');
24
+
25
+ module.exports = {
26
+ name: 'trae',
27
+ displayName: 'TraeWork(TraeCode·中国版)',
28
+ rulesDir: '.trae/rules',
29
+ skillsDir: '.trae/skills',
30
+ commandsDir: '.trae/commands',
31
+ // 命令扁平化(同 opencode):中国版命令名 = 文件名,不支持 "目录:命令" 命名空间
32
+ commandPrefix: 'opsx-',
33
+ contentRewrites: [['/opsx:', '/opsx-'], ['/cbb:', '/cbb-']],
34
+ commandNameKebab: true,
35
+ // 规则 frontmatter 改写:Qoder 风格 → Trae 风格
36
+ ruleRewrites: [['trigger: always_on', 'alwaysApply: true']],
37
+ // 用户级 hooks 配置(中国版目录为 ~/.trae-cn/,项目级才是 .trae/)
38
+ settingsFile: path.join(os.homedir(), '.trae-cn', 'hooks.json'),
39
+ settingsFileIsUserLevel: true,
40
+ hookEvents: ['UserPromptSubmit'],
41
+ // Trae 的 hooks.json 需顶层 version: 1(Claude 风格 settings.json 无此字段)
42
+ hookDialect: 'trae',
43
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * WorkBuddy 适配器
3
+ *
4
+ * 腾讯 WorkBuddy 桌面工作台的项目级配置目录为 `.workbuddy/`(业务空间实测:
5
+ * skill 只有放在 `.workbuddy/skills/` 才生效;旧版假设「与 CodeBuddy 共用
6
+ * .codebuddy/」不成立)。0.0.3-beta.16 起目录与用户级 settings 切到
7
+ * `.workbuddy`;0.0.3-beta.17 起不再支持 CodeBuddy,`.codebuddy` 仅作为
8
+ * legacy 由安装流程迁移清理(legacyDirs / legacySettingsFile)。
9
+ *
10
+ * 与 Claude Code / Qoder 的映射差异:
11
+ * - rules:`.workbuddy/rules/*.md`(扁平文件、递归加载),frontmatter 用
12
+ * `alwaysApply: true`(Qoder 的 `trigger: always_on` 需改写,见 ruleRewrites)
13
+ * - skills:`.workbuddy/skills/<name>/SKILL.md`,结构与 Claude 同构
14
+ * - commands:`.workbuddy/commands/`,支持目录嵌套(`/group:command`),与 Claude 同风格
15
+ * - hooks:兼容 Claude Code Hooks 规范,settings 结构一致,直接复用 settingsManager
16
+ */
17
+
18
+ const path = require('path');
19
+ const os = require('os');
20
+
21
+ module.exports = {
22
+ name: 'workbuddy',
23
+ displayName: 'WorkBuddy',
24
+ rulesDir: '.workbuddy/rules',
25
+ skillsDir: '.workbuddy/skills',
26
+ commandsDir: '.workbuddy/commands/opsx',
27
+ // 规则 frontmatter 改写:Qoder 风格 → WorkBuddy 风格
28
+ ruleRewrites: [['trigger: always_on', 'alwaysApply: true']],
29
+ // 用户级 settings,写入全局生效,不污染项目目录
30
+ settingsFile: path.join(os.homedir(), '.workbuddy', 'settings.json'),
31
+ settingsFileIsUserLevel: true,
32
+ hookEvents: ['UserPromptSubmit'],
33
+ // 旧版(beta.15 及以前按 CodeBuddy 装的 .codebuddy):安装时迁移清理
34
+ legacyDirs: ['.codebuddy'],
35
+ legacySettingsFile: path.join(os.homedir(), '.codebuddy', 'settings.json'),
36
+ };
@@ -16,7 +16,7 @@ const path = require('path');
16
16
  const { execSync } = require('child_process');
17
17
 
18
18
  const DEFAULT_CONFIG = 'config/workspaces.json';
19
- const SAMPLE_CONFIG = 'config/workspace-config.sample.json';
19
+ const SAMPLE_CONFIG = 'config/CBB-WORKSPACE.sample.json';
20
20
  const SAMPLE_AGENTS_MD = 'config/workspace-agents.sample.md';
21
21
 
22
22
  /**
@@ -104,7 +104,7 @@ function loadWorkspaces(configPath = DEFAULT_CONFIG) {
104
104
  }
105
105
 
106
106
  /**
107
- * 校验业务工作空间 workspace-config.json 的格式是否合法。
107
+ * 校验业务工作空间 CBB-WORKSPACE.json 的格式是否合法。
108
108
  *
109
109
  * 校验项:
110
110
  * - 文件存在且为合法 JSON
@@ -113,31 +113,31 @@ function loadWorkspaces(configPath = DEFAULT_CONFIG) {
113
113
  * - name、repo 为非空字符串;side 必须为 'front'、'back' 或 'mixed'
114
114
  * - desc 为可选字段;一旦出现必须是非空字符串(应用职责描述)
115
115
  *
116
- * @param {string} configPath workspace-config.json 的绝对路径
116
+ * @param {string} configPath CBB-WORKSPACE.json 的绝对路径
117
117
  * @returns {{ valid: boolean, message?: string, config?: object }}
118
118
  */
119
119
  function validateWorkspaceConfig(configPath) {
120
120
  if (!fs.existsSync(configPath)) {
121
- return { valid: false, message: `workspace-config.json 不存在:${configPath}` };
121
+ return { valid: false, message: `CBB-WORKSPACE.json 不存在:${configPath}` };
122
122
  }
123
123
 
124
124
  let raw;
125
125
  try {
126
126
  raw = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
127
127
  } catch (e) {
128
- return { valid: false, message: `workspace-config.json 不是合法 JSON:${e.message}` };
128
+ return { valid: false, message: `CBB-WORKSPACE.json 不是合法 JSON:${e.message}` };
129
129
  }
130
130
 
131
131
  if (!raw || typeof raw !== 'object') {
132
- return { valid: false, message: 'workspace-config.json 内容应为 JSON 对象' };
132
+ return { valid: false, message: 'CBB-WORKSPACE.json 内容应为 JSON 对象' };
133
133
  }
134
134
 
135
135
  if (!Array.isArray(raw.apps)) {
136
- return { valid: false, message: 'workspace-config.json 缺少 apps 数组' };
136
+ return { valid: false, message: 'CBB-WORKSPACE.json 缺少 apps 数组' };
137
137
  }
138
138
 
139
139
  if (raw.apps.length === 0) {
140
- return { valid: false, message: 'workspace-config.json 中 apps 数组为空,请至少配置一个关联应用' };
140
+ return { valid: false, message: 'CBB-WORKSPACE.json 中 apps 数组为空,请至少配置一个关联应用' };
141
141
  }
142
142
 
143
143
  const VALID_SIDES = ['front', 'back', 'mixed'];
@@ -146,22 +146,22 @@ function validateWorkspaceConfig(configPath) {
146
146
  const label = `第 ${i + 1} 项`;
147
147
 
148
148
  if (!app || typeof app !== 'object') {
149
- return { valid: false, message: `workspace-config.json ${label}不是对象` };
149
+ return { valid: false, message: `CBB-WORKSPACE.json ${label}不是对象` };
150
150
  }
151
151
  if (typeof app.name !== 'string' || !app.name.trim()) {
152
- return { valid: false, message: `workspace-config.json ${label}缺少 name(应用名)` };
152
+ return { valid: false, message: `CBB-WORKSPACE.json ${label}缺少 name(应用名)` };
153
153
  }
154
154
  if (typeof app.repo !== 'string' || !app.repo.trim()) {
155
- return { valid: false, message: `workspace-config.json "${app.name}" 缺少 repo(Git 仓库地址)` };
155
+ return { valid: false, message: `CBB-WORKSPACE.json "${app.name}" 缺少 repo(Git 仓库地址)` };
156
156
  }
157
157
  if (typeof app.side !== 'string' || !app.side.trim()) {
158
- return { valid: false, message: `workspace-config.json "${app.name}" 缺少 side(仓库类型,可选值:front / back / mixed)` };
158
+ return { valid: false, message: `CBB-WORKSPACE.json "${app.name}" 缺少 side(仓库类型,可选值:front / back / mixed)` };
159
159
  }
160
160
  if (!VALID_SIDES.includes(app.side.trim())) {
161
- return { valid: false, message: `workspace-config.json "${app.name}" 的 side 字段值无效:"${app.side}"(可选值:front / back / mixed)` };
161
+ return { valid: false, message: `CBB-WORKSPACE.json "${app.name}" 的 side 字段值无效:"${app.side}"(可选值:front / back / mixed)` };
162
162
  }
163
163
  if (app.desc !== undefined && (typeof app.desc !== 'string' || !app.desc.trim())) {
164
- return { valid: false, message: `workspace-config.json "${app.name}" 的 desc 字段应为非空字符串(该应用的职责描述),不需要可整条删除` };
164
+ return { valid: false, message: `CBB-WORKSPACE.json "${app.name}" 的 desc 字段应为非空字符串(该应用的职责描述),不需要可整条删除` };
165
165
  }
166
166
  }
167
167
 
@@ -186,11 +186,15 @@ function ensureWorkspaceAgentsMd(targetDir) {
186
186
  return 'created';
187
187
  }
188
188
 
189
- // 旧版空间导航模板(0.0.3 单层安装改造前)的特征语句。
190
- // 该文件归用户所有、永不覆盖,故只能提示用户删除后重跑 cbb update 重新生成。
189
+ // 旧版空间导航模板的特征语句(命中即提示用户删除后重跑 cbb update 重新生成;
190
+ // 该文件归用户所有、永不覆盖)。分两代:
191
+ // - 0.0.3 单层安装改造前:前两条
192
+ // - 双模式重构前(≤0.0.3-beta.21,worktree 默认 + 轻量模式):后两条
191
193
  const LEGACY_AGENTS_MD_MARKERS = [
192
194
  '故意不含编码规范',
193
195
  '自动安装沙箱内的编码规范',
196
+ '轻量模式',
197
+ 'AI 会话始终停在空间根',
194
198
  ];
195
199
 
196
200
  /**
@@ -268,7 +272,7 @@ function extractRepoBasename(url) {
268
272
 
269
273
  /**
270
274
  * 判断 repo 是否为样例占位地址(RFC 2606 保留域名)。
271
- * 样例 workspace-config.json 的 repo 用 example.com 等占位,clone 必然失败;
275
+ * 样例 CBB-WORKSPACE.json 的 repo 用 example.com 等占位,clone 必然失败;
272
276
  * setup 据此逐条跳过空跑并给出明确编辑提示。
273
277
  * 支持 SSH(git@host:path)与 URL(ssh://、https://、git://)两种形式的 host 提取。
274
278
  *