@jspg-ai/coding-bb 0.0.3-beta.24 → 0.0.3-beta.25

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 (33) hide show
  1. package/cbb/dev-standards/rules/cbb-ai-behavior.md +2 -2
  2. package/cbb/lib/install/init.js +23 -21
  3. package/cbb/lib/install/workspaces.js +15 -15
  4. package/cbb/lib/utils/githook.js +9 -7
  5. package/cbb/worktrees/_shared/scripts/find-workspace-root.js +7 -7
  6. package/cbb/worktrees/_shared/scripts/install-git-hook.js +1 -1
  7. package/cbb/worktrees/_shared/scripts/start-local.js +4 -4
  8. package/cbb/worktrees/skills/cbb-local-mode/scripts/install-git-hook.js +1 -1
  9. package/cbb/worktrees/skills/cbb-local-mode/scripts/start-local.js +4 -4
  10. package/cbb/worktrees/skills/cbb-worktree-close/SKILL.md +7 -7
  11. package/cbb/worktrees/skills/cbb-worktree-close/scripts/check-env.js +3 -3
  12. package/cbb/worktrees/skills/cbb-worktree-close/scripts/delete-branches.js +1 -1
  13. package/cbb/worktrees/skills/cbb-worktree-close/scripts/discover-apps.js +4 -4
  14. package/cbb/worktrees/skills/cbb-worktree-close/scripts/find-workspace-root.js +7 -7
  15. package/cbb/worktrees/skills/cbb-worktree-close/scripts/remove-worktrees.js +1 -1
  16. package/cbb/worktrees/skills/cbb-worktree-close/scripts/safety-check.js +1 -1
  17. package/cbb/worktrees/skills/cbb-worktree-init/SKILL.md +22 -22
  18. package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-env.js +1 -1
  19. package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-repos.js +2 -2
  20. package/cbb/worktrees/skills/cbb-worktree-init/scripts/create-branches.js +3 -3
  21. package/cbb/worktrees/skills/cbb-worktree-init/scripts/create-worktrees.js +4 -4
  22. package/cbb/worktrees/skills/cbb-worktree-init/scripts/find-workspace-root.js +7 -7
  23. package/cbb/worktrees/skills/cbb-worktree-init/scripts/install-git-hook.js +1 -1
  24. package/cbb/worktrees/skills/cbb-worktree-init/scripts/parse-config.js +7 -7
  25. package/cbb/worktrees/skills/cbb-worktree-init/scripts/push-branches.js +3 -3
  26. package/cbb/worktrees/skills/cbb-worktree-init/scripts/sync-repos.js +6 -6
  27. package/cbb/worktrees/skills/cbb-worktree-push/SKILL.md +7 -7
  28. package/cbb/worktrees/skills/cbb-worktree-push/scripts/commit-worktrees.js +2 -2
  29. package/cbb/worktrees/skills/cbb-worktree-push/scripts/find-workspace-root.js +7 -7
  30. package/cbb/worktrees/skills/cbb-worktree-push/scripts/push-worktrees.js +2 -2
  31. package/config/{workspace-config.sample.json → CBB-WORKSPACE.sample.json} +1 -1
  32. package/config/workspace-agents.sample.md +4 -44
  33. package/package.json +1 -1
@@ -16,9 +16,9 @@ description: "为一个需求在 workspace 与各关联应用仓库同步创建
16
16
  - 所有仓库使用统一的分支名(不加前缀);worktree 目录名自动加 `worktree-` 前缀;**分支基线统一取 `origin/<main>`(ADR 0002,不取 HEAD)**
17
17
  - **lazy push(ADR 0002)**:本技能**不向远端推送任何分支**——远端副作用收敛到 `cbb-worktree-push` 唯一出口;推送失败早暴露的职责由 push 技能的 dry-run 承担
18
18
  - **AI 配置 junction(ADR 0002 防线 B)**:创建 worktree 后把根的 AI 配置**内容子目录**(rules / skills / commands)junction 进工作树——开发会话开在 `<wt_path>`(上游 `/opsx:*` 相对路径原样生效,零翻译);工具状态落在工作树自建空壳目录,不互相污染;`cbb update` 在根跑一次全 worktree 生效
19
- - **本技能必须在业务工作空间根目录执行**(即由 `cbb setup` 初始化、包含 `workspace-config.json` 的目录)
19
+ - **本技能必须在业务工作空间根目录执行**(即由 `cbb setup` 初始化、包含 `CBB-WORKSPACE.json` 的目录)
20
20
  - 输入约定:**自由文本**(需求名等)直接在对话中提问并等待回复,禁止使用 `AskUserQuestion`;`AskUserQuestion` 仅用于固定选项决策场景(如 push 失败处理、远程分支已存在时的二选一)
21
- - 关联应用默认为 `workspace-config.json` 的**全量 apps**;支持按需求语境传入**应用子集**(见 Step 1),需要增减应用时编辑该文件并重跑本技能(幂等)
21
+ - 关联应用默认为 `CBB-WORKSPACE.json` 的**全量 apps**;支持按需求语境传入**应用子集**(见 Step 1),需要增减应用时编辑该文件并重跑本技能(幂等)
22
22
  - **模式选择(ADR 0002)**:接到需求先判断用户要哪种模式——要**并行 / 隔离** → 本技能;**单线程快改、当前会话就地干** → 引导 `cbb-local-mode`。用户明确指定即遵从,agent 只给推荐不代决
23
23
 
24
24
  ---
@@ -34,7 +34,7 @@ node "<skill_dir>/scripts/<name>.js" <参数>
34
34
  ```
35
35
 
36
36
  > - `<skill_dir>` = 本 SKILL.md 所在目录的绝对路径(AI 从读取路径即可推出)
37
- > - **cwd 必须保持在工作空间根目录**:脚本按 cwd 定位 `workspace-config.json` 与 git 仓库
37
+ > - **cwd 必须保持在工作空间根目录**:脚本按 cwd 定位 `CBB-WORKSPACE.json` 与 git 仓库
38
38
  > - 不要用 `./scripts/...` 裸相对路径(AI 的 cwd 不是技能目录,会解析失败)
39
39
 
40
40
  脚本输出:
@@ -47,7 +47,7 @@ node "<skill_dir>/scripts/<name>.js" <参数>
47
47
  - `<branch>`:需求名字符串
48
48
  - `<wt_path>`:worktree 绝对路径
49
49
 
50
- 所有脚本读 workspace-config.json:app 列表从 `<ws_root>/workspace-config.json` 读取,不需要传 JSON 参数。
50
+ 所有脚本读 CBB-WORKSPACE.json:app 列表从 `<ws_root>/CBB-WORKSPACE.json` 读取,不需要传 JSON 参数。
51
51
 
52
52
  ---
53
53
 
@@ -80,7 +80,7 @@ node "<skill_dir>/scripts/check-env-deep.js"
80
80
  - Node.js >= 16.7.0
81
81
  - `.worktrees/` 目录可写
82
82
 
83
- ### 0.2 读取并校验 workspace-config.json
83
+ ### 0.2 读取并校验 CBB-WORKSPACE.json
84
84
 
85
85
  ```bash
86
86
  node "<skill_dir>/scripts/parse-config.js"
@@ -93,23 +93,23 @@ node "<skill_dir>/scripts/parse-config.js"
93
93
 
94
94
  ### 0.3 配置引导
95
95
 
96
- 当 `workspace-config.json` 缺失、`apps` 为空或格式错误时,向用户说明情况并给出两个选项:
96
+ 当 `CBB-WORKSPACE.json` 缺失、`apps` 为空或格式错误时,向用户说明情况并给出两个选项:
97
97
 
98
98
  ```
99
- ⚠️ 当前工作空间尚未配置关联应用(workspace-config.json 缺失或 apps 为空)。
99
+ ⚠️ 当前工作空间尚未配置关联应用(CBB-WORKSPACE.json 缺失或 apps 为空)。
100
100
  worktree 需要知道要关联哪些应用仓库。
101
101
 
102
102
  请选择:
103
- [1] 我自行配置 workspace-config.json,配好后告诉你继续
104
- [2] 提供应用仓库地址,我帮你写入 workspace-config.json
103
+ [1] 我自行配置 CBB-WORKSPACE.json,配好后告诉你继续
104
+ [2] 提供应用仓库地址,我帮你写入 CBB-WORKSPACE.json
105
105
  ```
106
106
 
107
107
  **选项 1:用户自行配置**
108
108
  - 停止当前技能流程
109
- - 提示用户:*"请编辑 workspace-config.json 后回复'继续',或重新执行 init-worktree。"*
109
+ - 提示用户:*"请编辑 CBB-WORKSPACE.json 后回复'继续',或重新执行 init-worktree。"*
110
110
  - 用户回复"继续"后,重新从 Step 0 开始校验
111
111
 
112
- **选项 2:帮用户写入 workspace-config.json**
112
+ **选项 2:帮用户写入 CBB-WORKSPACE.json**
113
113
  - 直接在对话中请用户提供应用信息,格式示例:
114
114
  ```
115
115
  应用名: ep-user-auth-app
@@ -120,7 +120,7 @@ worktree 需要知道要关联哪些应用仓库。
120
120
  仓库地址: git@code.example.com:team/ep-user-info-server.git
121
121
  类型: back(可选值:front 前端 / back 后端 / mixed 前后端混合)
122
122
  ```
123
- - 解析后写入 `workspace-config.json`:
123
+ - 解析后写入 `CBB-WORKSPACE.json`:
124
124
  ```json
125
125
  {
126
126
  "apps": [
@@ -131,20 +131,20 @@ worktree 需要知道要关联哪些应用仓库。
131
131
  ```
132
132
  - 写入成功后提交到当前分支(确保 Step 2 状态检查通过):
133
133
  ```bash
134
- git add workspace-config.json
135
- git commit -m "chore: add workspace-config.json"
134
+ git add CBB-WORKSPACE.json
135
+ git commit -m "chore: add CBB-WORKSPACE.json"
136
136
  ```
137
137
  > 若当前不在主分支上,提示用户切回主分支后再提交;若已在主分支上则直接提交。
138
138
  - 提交后重新从 Step 0 校验,通过后继续 Step 1
139
139
 
140
- > ⚠️ **禁止**:在 workspace-config.json 无效时跳过本步骤直接创建 worktree,否则无法确定关联应用。
140
+ > ⚠️ **禁止**:在 CBB-WORKSPACE.json 无效时跳过本步骤直接创建 worktree,否则无法确定关联应用。
141
141
 
142
142
  ---
143
143
 
144
144
  ## Step 1:关联应用与代码同步
145
145
 
146
146
  > ⓘ **关联应用 = 需求涉及的应用子集**:从需求语境提取("改订单导出" → 订单相关应用);纯 workspace 内容的需求 → 仅 workspace。子集判断错了零代价——重跑本技能幂等补齐(已存在的分支/worktree 自动复用,详见「幂等重跑」章节)。涉及全部应用 / 不确定时用全量。
147
- > 需要增减应用时,编辑 `workspace-config.json` 后**重跑本技能**即可。
147
+ > 需要增减应用时,编辑 `CBB-WORKSPACE.json` 后**重跑本技能**即可。
148
148
 
149
149
  ### 1.1 同步 `.codespace/` 目录代码
150
150
 
@@ -154,7 +154,7 @@ node "<skill_dir>/scripts/sync-repos.js" "<ws_root>"
154
154
  ```
155
155
 
156
156
  **用法**:
157
- - `<ws_root>`:工作空间根绝对路径(apps 由脚本内部从 `<ws_root>/workspace-config.json` 读取,全量 fetch/clone)
157
+ - `<ws_root>`:工作空间根绝对路径(apps 由脚本内部从 `<ws_root>/CBB-WORKSPACE.json` 读取,全量 fetch/clone)
158
158
 
159
159
  **解读输出**:
160
160
  - 退出码 0 + 末行 `SYNC_RESULT [...]` → 全部成功
@@ -354,7 +354,7 @@ node "<skill_dir>/scripts/junction-ai-config.js" "<ws_root>" "<wt_path>"
354
354
 
355
355
  | 场景 | 重跑行为 |
356
356
  |------|----------|
357
- | 空间新增了应用(编辑 `workspace-config.json` 后) | Step 1 拉取新应用代码 → Step 3.3 为新应用建分支 → Step 3.5 在 `.codespace/` 容器内创建缺失的 app worktree → Step 3.6 补 junction |
357
+ | 空间新增了应用(编辑 `CBB-WORKSPACE.json` 后) | Step 1 拉取新应用代码 → Step 3.3 为新应用建分支 → Step 3.5 在 `.codespace/` 容器内创建缺失的 app worktree → Step 3.6 补 junction |
358
358
  | 上次 init 中途失败 | 已存在的分支 / worktree 自动复用,`.gitignore` 处理自动跳过,仅补齐缺失部分 |
359
359
  | 应用从 config 移除 | 已创建的分支 / worktree **不会**自动删除;如需清理用 `cbb-worktree-close` skill 关闭后重建 |
360
360
  | **本地模式升级 worktree**(ADR 0002) | Step 3.3 分支已存在 → reused(本地阶段提交随身带走);先 `git checkout main` 腾出各仓库本地检出,再重跑本技能 |
@@ -385,10 +385,10 @@ node "<skill_dir>/scripts/junction-ai-config.js" "<ws_root>" "<wt_path>"
385
385
 
386
386
  ## 常见错误
387
387
 
388
- ### 跳过 workspace-config.json 直接硬编码仓库地址
388
+ ### 跳过 CBB-WORKSPACE.json 直接硬编码仓库地址
389
389
 
390
390
  - **问题:** 直接在代码中写死仓库 URL 或本地路径,不同团队的仓库地址不同
391
- - **修复:** 始终从 `workspace-config.json` 读取应用与远程仓库的映射;配置缺失/为空时按 Step 0.3 配置引导处理,不支持在流程中临时指定配置外的仓库
391
+ - **修复:** 始终从 `CBB-WORKSPACE.json` 读取应用与远程仓库的映射;配置缺失/为空时按 Step 0.3 配置引导处理,不支持在流程中临时指定配置外的仓库
392
392
 
393
393
  ### 状态检查对 app 仓库执行完整五项检查
394
394
 
@@ -468,7 +468,7 @@ node "<skill_dir>/scripts/junction-ai-config.js" "<ws_root>" "<wt_path>"
468
468
  - 所有仓库分支统一从 `origin/<main>` 创建(`git branch <需求名> ${REMOTE}/${MAIN}`),不依赖本地检出状态(本地模式进行中重跑不受污染)
469
469
  - 严格 Step 3.3 → Step 3.5 顺序(先统一创建分支,再统一创建 worktree;workspace 工作树先建,各应用按序补建)
470
470
  - Step 3.6 junction AI 配置(失败不阻塞,但要报告)
471
- - 所有脚本调用以 `node "<skill_dir>/scripts/<name>.js" "<绝对路径>" "<branch>"` 形式发起(apps 缺省由脚本内部从 workspace-config.json 读取,子集用 `--apps` 传入);**执行时 cwd 保持在工作空间根**(`check-env.js` / `parse-config.js` 按 cwd 定位)
471
+ - 所有脚本调用以 `node "<skill_dir>/scripts/<name>.js" "<绝对路径>" "<branch>"` 形式发起(apps 缺省由脚本内部从 CBB-WORKSPACE.json 读取,子集用 `--apps` 传入);**执行时 cwd 保持在工作空间根**(`check-env.js` / `parse-config.js` 按 cwd 定位)
472
472
  - Step 4 交接必须声明"开发会话开在 `<wt_path>`、根会话保留作控制面"
473
473
 
474
474
  ---
@@ -478,7 +478,7 @@ node "<skill_dir>/scripts/junction-ai-config.js" "<ws_root>" "<wt_path>"
478
478
  | 脚本 | 功能 | 参数 | 退出码 |
479
479
  |------|------|------|--------|
480
480
  | `check-env.js` | 环境探活 | 无 | 0/1/2 |
481
- | `parse-config.js` | 解析 workspace-config.json | 无 | 0/1/2 |
481
+ | `parse-config.js` | 解析 CBB-WORKSPACE.json | 无 | 0/1/2 |
482
482
  | `sync-repos.js` | 同步 .codespace/ 仓库(兜底 clone 时补装提交防线 hook) | ws_root | 0/1/2 |
483
483
  | `check-repos.js` | 状态检查 | ws_root | 0/1/2 |
484
484
  | `update-gitignore.js` | 安全更新 .gitignore | ws_root, branch | 0/1/2 |
@@ -48,7 +48,7 @@ console.log('✅ git OK:', checks.git.out);
48
48
  const insideRepo = tryExec('git rev-parse --is-inside-work-tree');
49
49
  if (!insideRepo.ok || insideRepo.out !== 'true') {
50
50
  console.error('❌ 当前目录不是 Git 仓库');
51
- console.error(' init-worktree 必须在工作空间根目录(包含 workspace-config.json)下执行');
51
+ console.error(' init-worktree 必须在工作空间根目录(包含 CBB-WORKSPACE.json)下执行');
52
52
  process.exit(2);
53
53
  }
54
54
  console.log('✅ 当前目录是 git 仓库');
@@ -36,7 +36,7 @@ if (!wsRoot) {
36
36
  }
37
37
 
38
38
  function loadAppsFromConfig() {
39
- const configPath = path.join(wsRoot, "workspace-config.json");
39
+ const configPath = path.join(wsRoot, "CBB-WORKSPACE.json");
40
40
  if (!fs.existsSync(configPath)) return null;
41
41
  try {
42
42
  const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
@@ -46,7 +46,7 @@ function loadAppsFromConfig() {
46
46
 
47
47
  const apps = loadAppsFromConfig();
48
48
  if (!apps) {
49
- console.error("workspace-config.json missing or apps empty");
49
+ console.error("CBB-WORKSPACE.json missing or apps empty");
50
50
  process.exit(1);
51
51
  }
52
52
 
@@ -25,7 +25,7 @@ if (appsFlagIdx >= 0) {
25
25
  }
26
26
 
27
27
  function loadAppsFromConfig() {
28
- const configPath = path.join(wsRoot, 'workspace-config.json');
28
+ const configPath = path.join(wsRoot, 'CBB-WORKSPACE.json');
29
29
  if (!fs.existsSync(configPath)) return null;
30
30
  try {
31
31
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
@@ -35,7 +35,7 @@ function loadAppsFromConfig() {
35
35
 
36
36
  const allApps = loadAppsFromConfig();
37
37
  if (!allApps) {
38
- console.error('workspace-config.json missing or apps empty');
38
+ console.error('CBB-WORKSPACE.json missing or apps empty');
39
39
  process.exit(1);
40
40
  }
41
41
 
@@ -46,7 +46,7 @@ const apps = appFilter
46
46
  if (appFilter) {
47
47
  const unknown = [...appFilter].filter(n => !allApps.some(a => a.name === n));
48
48
  if (unknown.length > 0) {
49
- console.error('❌ --apps 中的应用不在 workspace-config.json:' + unknown.join(', '));
49
+ console.error('❌ --apps 中的应用不在 CBB-WORKSPACE.json:' + unknown.join(', '));
50
50
  process.exit(1);
51
51
  }
52
52
  console.log('ℹ️ 应用子集(' + apps.length + '/' + allApps.length + '):' + apps.map(a => a.name).join(', '));
@@ -4,7 +4,7 @@ require('./silence-popup');
4
4
  * cbb-worktree-init 创建 Worktree(自愈清理仅限元数据 prune)
5
5
  *
6
6
  * 用法:node create-worktrees.js <ws_root> <branch>
7
- * (apps 由脚本内部从 <ws_root>/workspace-config.json 读取)
7
+ * (apps 由脚本内部从 <ws_root>/CBB-WORKSPACE.json 读取)
8
8
  *
9
9
  * 行为:
10
10
  * 1. 自愈清理:仅 git worktree prune(元数据),**绝不删除任何物理目录**
@@ -41,7 +41,7 @@ if (appsFlagIdx >= 0) {
41
41
  }
42
42
 
43
43
  function loadAppsFromConfig() {
44
- const configPath = path.join(wsRoot, 'workspace-config.json');
44
+ const configPath = path.join(wsRoot, 'CBB-WORKSPACE.json');
45
45
  if (!fs.existsSync(configPath)) return null;
46
46
  try {
47
47
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
@@ -51,7 +51,7 @@ function loadAppsFromConfig() {
51
51
 
52
52
  const allApps = loadAppsFromConfig();
53
53
  if (!allApps) {
54
- console.error('❌ workspace-config.json 缺失或 apps 为空');
54
+ console.error('❌ CBB-WORKSPACE.json 缺失或 apps 为空');
55
55
  process.exit(1);
56
56
  }
57
57
 
@@ -62,7 +62,7 @@ const apps = appFilter
62
62
  if (appFilter) {
63
63
  const unknown = [...appFilter].filter(n => !allApps.some(a => a.name === n));
64
64
  if (unknown.length > 0) {
65
- console.error('❌ --apps 中的应用不在 workspace-config.json:' + unknown.join(', '));
65
+ console.error('❌ --apps 中的应用不在 CBB-WORKSPACE.json:' + unknown.join(', '));
66
66
  process.exit(1);
67
67
  }
68
68
  console.log('ℹ️ 应用子集(' + apps.length + '/' + allApps.length + '):' + apps.map(a => a.name).join(', '));
@@ -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 内 workspace-config.json 副本干扰)
9
- * 兜底:当前目录含 workspace-config.json
8
+ * 优先:git worktree list 第一行(主仓库根目录,不受 worktree 内 CBB-WORKSPACE.json 副本干扰)
9
+ * 兜底:当前目录含 CBB-WORKSPACE.json
10
10
  *
11
11
  * 退出码:
12
12
  * 0 - 定位成功,输出 WS_ROOT 绝对路径
@@ -44,19 +44,19 @@ if (worktreeList.ok) {
44
44
  }
45
45
  }
46
46
 
47
- // 兜底:当前目录含 workspace-config.json
47
+ // 兜底:当前目录含 CBB-WORKSPACE.json
48
48
  if (!wsRoot) {
49
49
  const cwd = process.cwd();
50
- if (fs.existsSync(path.join(cwd, 'workspace-config.json'))) {
50
+ if (fs.existsSync(path.join(cwd, 'CBB-WORKSPACE.json'))) {
51
51
  wsRoot = cwd;
52
52
  }
53
53
  }
54
54
 
55
55
  // 校验
56
- if (!wsRoot || !fs.existsSync(path.join(wsRoot, 'workspace-config.json'))) {
56
+ if (!wsRoot || !fs.existsSync(path.join(wsRoot, 'CBB-WORKSPACE.json'))) {
57
57
  console.error('❌ 未找到工作空间根目录');
58
- console.error(' 原因:git worktree list 失败且当前目录无 workspace-config.json');
59
- console.error(' 请在业务工作空间根目录(由 cbb setup 初始化、包含 workspace-config.json)下执行本技能');
58
+ console.error(' 原因:git worktree list 失败且当前目录无 CBB-WORKSPACE.json');
59
+ console.error(' 请在业务工作空间根目录(由 cbb setup 初始化、包含 CBB-WORKSPACE.json)下执行本技能');
60
60
  process.exit(1);
61
61
  }
62
62
 
@@ -20,7 +20,7 @@ const HOOK_FILE = 'pre-commit';
20
20
  const BACKUP_SUFFIX = '.cbb-backup';
21
21
 
22
22
  // 与 cbb/lib/utils/githook.js 的 buildPreCommitSource() 输出完全一致(构建时注入)
23
- const PRE_COMMIT_SOURCE = "#!/usr/bin/env node\n// managed-by-cbb v1 —— 分支感知提交防线(ADR 0002)\n// main 上:workspace 仓库只放行控制面白名单,应用仓库全拦;非 main 一律放行。\n// 绕过逃生口仅限用户显式 git commit --no-verify。\nconst { execSync } = require('child_process');\nconst fs = require('fs');\nfunction run(cmd) {\n try { return execSync(cmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim(); }\n catch (e) { return null; }\n}\nconst branch = run('git branch --show-current') || '';\n// 主干名:优先远端 HEAD 指向;探测失败按本地 main/master 存在性回退\nlet main = null;\nconst remotes = run('git remote');\nif (remotes) {\n const r = remotes.split(/\\r?\\n/)[0];\n const sym = run('git symbolic-ref \"refs/remotes/' + r + '/HEAD\"');\n if (sym) main = sym.replace('refs/remotes/' + r + '/', '');\n}\nif (!main) {\n if (run('git rev-parse --verify --quiet refs/heads/main')) main = 'main';\n else if (run('git rev-parse --verify --quiet refs/heads/master')) main = 'master';\n}\n// 非主干(含 detached / 探测失败)→ 放行\nif (!main || branch !== main) process.exit(0);\n\n// 主干上的提交:收集 staged 变更(空提交放行)\nconst staged = run('git diff --cached --name-only') || '';\nconst files = staged.split(/\\r?\\n/).filter(Boolean);\nif (files.length === 0) process.exit(0);\n\n// 仓库类型:workspace 仓库 = 检出含 workspace-config.json\nconst isWorkspace = fs.existsSync('workspace-config.json');\n\nfunction deny(bad) {\n console.error('[cbb-guard] 主干上拦截载荷提交(ADR 0002):');\n bad.forEach(f => console.error(' ' + f));\n console.error('需求载荷须在需求分支上提交:本地模式先 git checkout -b <需求名>;worktree 模式在 .worktrees/ 工作树内提交。');\n console.error('控制面白名单:workspace-config.json / .gitignore / AGENTS.md / openspec/config.yaml / openspec/schemas/** / .cbb/**');\n console.error('如确需在主干提交,须由用户显式 git commit --no-verify。');\n process.exit(1);\n}\n\nif (isWorkspace) {\n const EXACT = new Set(['workspace-config.json', '.gitignore', 'AGENTS.md', 'openspec/config.yaml']);\n const PREFIXES = ['openspec/schemas/', '.cbb/'];\n const bad = files.filter(f => !EXACT.has(f) && !PREFIXES.some(p => f.indexOf(p) === 0));\n if (bad.length) deny(bad);\n} else {\n deny(files);\n}\nprocess.exit(0);\n";
23
+ const PRE_COMMIT_SOURCE = "#!/usr/bin/env node\n// managed-by-cbb v1 —— 分支感知提交防线(ADR 0002)\n// main 上:workspace 仓库只放行控制面白名单,应用仓库全拦;非 main 一律放行。\n// 绕过逃生口仅限用户显式 git commit --no-verify。\nconst { execSync } = require('child_process');\nconst fs = require('fs');\nfunction run(cmd) {\n try { return execSync(cmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim(); }\n catch (e) { return null; }\n}\nconst branch = run('git branch --show-current') || '';\n// 主干名:优先远端 HEAD 指向;探测失败按本地 main/master 存在性回退\nlet main = null;\nconst remotes = run('git remote');\nif (remotes) {\n const r = remotes.split(/\\r?\\n/)[0];\n const sym = run('git symbolic-ref \"refs/remotes/' + r + '/HEAD\"');\n if (sym) main = sym.replace('refs/remotes/' + r + '/', '');\n}\nif (!main) {\n if (run('git rev-parse --verify --quiet refs/heads/main')) main = 'main';\n else if (run('git rev-parse --verify --quiet refs/heads/master')) main = 'master';\n}\n// 非主干(含 detached / 探测失败)→ 放行\nif (!main || branch !== main) process.exit(0);\n\n// 主干上的提交:收集 staged 变更(空提交放行)\nconst staged = run('git diff --cached --name-only') || '';\nconst files = staged.split(/\\r?\\n/).filter(Boolean);\nif (files.length === 0) process.exit(0);\n\n// 仓库类型:workspace 仓库 = 检出含 CBB-WORKSPACE.json(或旧名,改名过渡期识别)\nconst isWorkspace = fs.existsSync('CBB-WORKSPACE.json') || fs.existsSync('workspace-config.json');\n\nfunction deny(bad) {\n console.error('[cbb-guard] 主干上拦截载荷提交(ADR 0002):');\n bad.forEach(f => console.error(' ' + f));\n console.error('需求载荷须在需求分支上提交:本地模式先 git checkout -b <需求名>;worktree 模式在 .worktrees/ 工作树内提交。');\n console.error('控制面白名单:CBB-WORKSPACE.json / .gitignore / AGENTS.md / openspec/config.yaml / openspec/schemas/** / .cbb/**');\n console.error('如确需在主干提交,须由用户显式 git commit --no-verify。');\n process.exit(1);\n}\n\nif (isWorkspace) {\n // 旧名仅放行删除条目:更名迁移提交(git mv)会产生旧名删除 + 新名新增两条\n const EXACT = new Set(['CBB-WORKSPACE.json', 'workspace-config.json', '.gitignore', 'AGENTS.md', 'openspec/config.yaml']);\n const PREFIXES = ['openspec/schemas/', '.cbb/'];\n const bad = files.filter(f => !EXACT.has(f) && !PREFIXES.some(p => f.indexOf(p) === 0));\n if (bad.length) deny(bad);\n} else {\n deny(files);\n}\nprocess.exit(0);\n";
24
24
 
25
25
  function isCbbHookContent(content) {
26
26
  return typeof content === 'string' && content.includes(HOOK_MARKER);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  require('./silence-popup');
3
3
  /**
4
- * cbb-worktree-init 读取并校验 workspace-config.json
4
+ * cbb-worktree-init 读取并校验 CBB-WORKSPACE.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(), 'workspace-config.json');
18
+ const configPath = path.join(process.cwd(), 'CBB-WORKSPACE.json');
19
19
 
20
20
  if (!fs.existsSync(configPath)) {
21
- console.error('❌ workspace-config.json 不存在');
21
+ console.error('❌ CBB-WORKSPACE.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('❌ workspace-config.json 解析失败:', e.message);
32
+ console.error('❌ CBB-WORKSPACE.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('❌ workspace-config.json 中 apps 为空');
42
- console.error(' 请编辑 workspace-config.json 配置关联应用');
41
+ console.error('❌ CBB-WORKSPACE.json 中 apps 为空');
42
+ console.error(' 请编辑 CBB-WORKSPACE.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('✅ workspace-config.json 有效(' + apps.length + ' 个应用)');
64
+ console.log('✅ CBB-WORKSPACE.json 有效(' + apps.length + ' 个应用)');
65
65
  console.log('---');
66
66
  console.log('CONFIG_OK', JSON.stringify(apps));
67
67
  process.exit(0);
@@ -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, 'workspace-config.json');
23
+ const configPath = path.join(wsRoot, 'CBB-WORKSPACE.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('workspace-config.json missing or apps empty');
43
+ throw new Error('CBB-WORKSPACE.json missing or apps empty');
44
44
  }
45
45
 
46
46
  const results = [];
@@ -68,7 +68,7 @@ function main() {
68
68
 
69
69
  const apps = loadAppsFromConfig(wsRoot);
70
70
  if (apps == null) {
71
- console.error('❌ workspace-config.json 缺失或 apps 为空');
71
+ console.error('❌ CBB-WORKSPACE.json 缺失或 apps 为空');
72
72
  process.exit(1);
73
73
  }
74
74
 
@@ -4,7 +4,7 @@ require('./silence-popup');
4
4
  * cbb-worktree-init 同步 .codespace/ 仓库
5
5
  *
6
6
  * 用法:node sync-repos.js <ws_root>
7
- * - ws_root: 工作空间根绝对路径(apps 从 <ws_root>/workspace-config.json 读取)
7
+ * - ws_root: 工作空间根绝对路径(apps 从 <ws_root>/CBB-WORKSPACE.json 读取)
8
8
  *
9
9
  * 对每个 app:
10
10
  * - .codespace/<name>/.git 存在 → fetch --all
@@ -29,23 +29,23 @@ if (!wsRoot) {
29
29
  }
30
30
 
31
31
  /**
32
- * 从 workspace-config.json 读取 apps(避免 shell 字符串传递中的转义问题)
32
+ * 从 CBB-WORKSPACE.json 读取 apps(避免 shell 字符串传递中的转义问题)
33
33
  */
34
34
  function loadAppsFromConfig() {
35
- const configPath = path.join(wsRoot, 'workspace-config.json');
35
+ const configPath = path.join(wsRoot, 'CBB-WORKSPACE.json');
36
36
  if (!fs.existsSync(configPath)) {
37
- console.error('❌ workspace-config.json 不存在:' + configPath);
37
+ console.error('❌ CBB-WORKSPACE.json 不存在:' + configPath);
38
38
  return null;
39
39
  }
40
40
  try {
41
41
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
42
42
  if (!config.apps || !Array.isArray(config.apps) || config.apps.length === 0) {
43
- console.error('❌ workspace-config.json 中 apps 为空');
43
+ console.error('❌ CBB-WORKSPACE.json 中 apps 为空');
44
44
  return null;
45
45
  }
46
46
  return config.apps;
47
47
  } catch (e) {
48
- console.error('❌ workspace-config.json 解析失败:' + e.message);
48
+ console.error('❌ CBB-WORKSPACE.json 解析失败:' + e.message);
49
49
  return null;
50
50
  }
51
51
  }
@@ -36,7 +36,7 @@ node "<skill_dir>/scripts/<name>.js" <参数>
36
36
  ```
37
37
 
38
38
  > - `<skill_dir>` = 本 SKILL.md 所在目录的绝对路径(AI 从读取路径即可推出)
39
- > - **cwd 必须保持在工作空间根目录**:脚本按 cwd 定位 `workspace-config.json` 与 git 仓库
39
+ > - **cwd 必须保持在工作空间根目录**:脚本按 cwd 定位 `CBB-WORKSPACE.json` 与 git 仓库
40
40
  > - 不要用 `./scripts/...` 裸相对路径(AI 的 cwd 不是技能目录,会解析失败)
41
41
 
42
42
  脚本输出:
@@ -54,9 +54,9 @@ node "<skill_dir>/scripts/<name>.js" <参数>
54
54
 
55
55
  | 场景 | 判据 | 策略 |
56
56
  |------|------|------|
57
- | **A. cbb 工作空间根** | cwd(或其 git 顶层)含 `workspace-config.json`;`find-workspace-root.js` 退出码 0 | 走 **Step 1 → 6** 的跨 worktree 批量流程 |
57
+ | **A. cbb 工作空间根** | cwd(或其 git 顶层)含 `CBB-WORKSPACE.json`;`find-workspace-root.js` 退出码 0 | 走 **Step 1 → 6** 的跨 worktree 批量流程 |
58
58
  | **B. worktree 内** | cwd 命中 `<ws_root>/.worktrees/worktree-<需求名>/` | 用 cwd 反推 `<需求名>`,走 **Step 1 → 6** 批量流程 |
59
- | **C. 普通 git 仓库** | 在 git 仓库内,但无 `workspace-config.json`(`find-workspace-root.js` 退出码 1) | **降级为单仓库提交推送**:不调 worktree 脚本,按常规 `git add -u` → 向用户询问 commit 信息 → `git commit` → `git push`(保留本 skill 的"必问 commit 信息"约束) |
59
+ | **C. 普通 git 仓库** | 在 git 仓库内,但无 `CBB-WORKSPACE.json`(`find-workspace-root.js` 退出码 1) | **降级为单仓库提交推送**:不调 worktree 脚本,按常规 `git add -u` → 向用户询问 commit 信息 → `git commit` → `git push`(保留本 skill 的"必问 commit 信息"约束) |
60
60
  | **D. 非 git 目录** | `git rev-parse --is-inside-work-tree` 失败 | 说明"当前目录不是 git 仓库",终止,不做任何操作 |
61
61
 
62
62
  **判场景与定位(A/B 场景):**
@@ -80,7 +80,7 @@ node "<skill_dir>/scripts/find-workspace-root.js"
80
80
  5. `git push`(无 upstream 时先询问用户是否 `-u`)
81
81
  6. 汇报结果;**不要**提及 worktree 批量流程
82
82
 
83
- > 场景 C 是兜底:让"提交代码"在普通仓库里也能正常完成,而不是因找不到 `workspace-config.json` 报错。
83
+ > 场景 C 是兜底:让"提交代码"在普通仓库里也能正常完成,而不是因找不到 `CBB-WORKSPACE.json` 报错。
84
84
 
85
85
  ---
86
86
 
@@ -123,7 +123,7 @@ AI agent 在执行真实 commit 前**必须**在对话中向用户确认 commit
123
123
 
124
124
  ```
125
125
  检测到以下 worktree 仓库有未提交改动:
126
- - workspace: 5 个文件(workspace-config.json, openspec/changes/foo/...)
126
+ - workspace: 5 个文件(CBB-WORKSPACE.json, openspec/changes/foo/...)
127
127
  - ep-foo-app: 12 个文件
128
128
  - ep-bar-app: 3 个文件
129
129
 
@@ -284,7 +284,7 @@ node "<skill_dir>/scripts/make-mr-urls.js" "<ws_root>" "<branch>" "<target>" --o
284
284
  | **任何触发** | **先做 Step 0 场景识别**,再决定策略 |
285
285
  | 场景 A:cwd 在 cbb 工作空间根 | find-workspace-root 成功 → 多个 worktree 时让用户选 |
286
286
  | 场景 B:cwd 在 worktree 内 | 自动用 cwd 反推分支,扫描后进入询问 commit 信息 |
287
- | 场景 C:cwd 在普通 git 仓库(无 workspace-config.json) | **降级为单仓库提交推送**,不调用 worktree 脚本 |
287
+ | 场景 C:cwd 在普通 git 仓库(无 CBB-WORKSPACE.json) | **降级为单仓库提交推送**,不调用 worktree 脚本 |
288
288
  | 场景 D:cwd 非 git 目录 | 说明情况并终止,不做任何操作 |
289
289
  | commit 信息缺失 | 必须询问用户;禁止自动生成(可基于 apply task 上下文给建议) |
290
290
  | 多仓库需不同 commit 信息 | 用 `--per-repo "ep-foo:m1;ep-bar:m2"`,必须由用户逐条提供 |
@@ -330,7 +330,7 @@ node "<skill_dir>/scripts/make-mr-urls.js" "<ws_root>" "<branch>" "<target>" --o
330
330
 
331
331
  ### 多仓库用同一条 commit 信息
332
332
 
333
- - **问题:** workspace 改了 workspace-config.json,ep-foo-app 改了 Java 代码,硬塞同一条 "feat: 实现 XX" 信息不准确
333
+ - **问题:** workspace 改了 CBB-WORKSPACE.json,ep-foo-app 改了 Java 代码,硬塞同一条 "feat: 实现 XX" 信息不准确
334
334
  - **修复:** 用 `--per-repo` 模式,让用户逐仓库提供
335
335
 
336
336
  ### push 失败时跳过失败仓库直接继续
@@ -97,10 +97,10 @@ function isGitRepo(p) {
97
97
  return fs.existsSync(path.join(p, '.git'));
98
98
  }
99
99
 
100
- /** 读取 workspace-config.json 的 app 名列表(旧布局兼容判定用;缺失返回 []) */
100
+ /** 读取 CBB-WORKSPACE.json 的 app 名列表(旧布局兼容判定用;缺失返回 []) */
101
101
  function loadAppNames(wsRoot) {
102
102
  try {
103
- const cfg = JSON.parse(fs.readFileSync(path.join(wsRoot, 'workspace-config.json'), 'utf-8'));
103
+ const cfg = JSON.parse(fs.readFileSync(path.join(wsRoot, 'CBB-WORKSPACE.json'), 'utf-8'));
104
104
  return Array.isArray(cfg.apps) ? cfg.apps.map(a => a.name).filter(Boolean) : [];
105
105
  } catch (e) {
106
106
  return [];
@@ -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 内 workspace-config.json 副本干扰)
9
- * 兜底:当前目录含 workspace-config.json
8
+ * 优先:git worktree list 第一行(主仓库根目录,不受 worktree 内 CBB-WORKSPACE.json 副本干扰)
9
+ * 兜底:当前目录含 CBB-WORKSPACE.json
10
10
  *
11
11
  * 退出码:
12
12
  * 0 - 定位成功,输出 WS_ROOT 绝对路径
@@ -44,19 +44,19 @@ if (worktreeList.ok) {
44
44
  }
45
45
  }
46
46
 
47
- // 兜底:当前目录含 workspace-config.json
47
+ // 兜底:当前目录含 CBB-WORKSPACE.json
48
48
  if (!wsRoot) {
49
49
  const cwd = process.cwd();
50
- if (fs.existsSync(path.join(cwd, 'workspace-config.json'))) {
50
+ if (fs.existsSync(path.join(cwd, 'CBB-WORKSPACE.json'))) {
51
51
  wsRoot = cwd;
52
52
  }
53
53
  }
54
54
 
55
55
  // 校验
56
- if (!wsRoot || !fs.existsSync(path.join(wsRoot, 'workspace-config.json'))) {
56
+ if (!wsRoot || !fs.existsSync(path.join(wsRoot, 'CBB-WORKSPACE.json'))) {
57
57
  console.error('❌ 未找到工作空间根目录');
58
- console.error(' 原因:git worktree list 失败且当前目录无 workspace-config.json');
59
- console.error(' 请在业务工作空间根目录(由 cbb setup 初始化、包含 workspace-config.json)下执行本技能');
58
+ console.error(' 原因:git worktree list 失败且当前目录无 CBB-WORKSPACE.json');
59
+ console.error(' 请在业务工作空间根目录(由 cbb setup 初始化、包含 CBB-WORKSPACE.json)下执行本技能');
60
60
  process.exit(1);
61
61
  }
62
62
 
@@ -59,10 +59,10 @@ function isGitRepo(p) {
59
59
  }
60
60
  }
61
61
 
62
- /** 读取 workspace-config.json 的 app 名列表(旧布局兼容判定用;缺失返回 []) */
62
+ /** 读取 CBB-WORKSPACE.json 的 app 名列表(旧布局兼容判定用;缺失返回 []) */
63
63
  function loadAppNames(wsRoot) {
64
64
  try {
65
- const cfg = JSON.parse(fs.readFileSync(path.join(wsRoot, 'workspace-config.json'), 'utf-8'));
65
+ const cfg = JSON.parse(fs.readFileSync(path.join(wsRoot, 'CBB-WORKSPACE.json'), 'utf-8'));
66
66
  return Array.isArray(cfg.apps) ? cfg.apps.map(a => a.name).filter(Boolean) : [];
67
67
  } catch (e) {
68
68
  return [];
@@ -1,5 +1,5 @@
1
1
  {
2
- "_comment": "AI 开发工作空间配置样例(请勿修改本文件,复制为工作空间根目录的 workspace-config.json 后编辑使用)。apps 数组中每个对象需包含:name(应用名,同时作为 .codespace/ 子目录名)、repo(Git 仓库地址,支持 SSH 或 HTTPS)、side(仓库类型,'front' 表示前端工程,'back' 表示后端工程,'mixed' 表示前后端混合工程);可选 desc(该应用的职责描述,便于人与 AI 理解应用分工)。",
2
+ "_comment": "AI 开发工作空间配置样例(请勿修改本文件,复制为工作空间根目录的 CBB-WORKSPACE.json 后编辑使用)。apps 数组中每个对象需包含:name(应用名,同时作为 .codespace/ 子目录名)、repo(Git 仓库地址,支持 SSH 或 HTTPS)、side(仓库类型,'front' 表示前端工程,'back' 表示后端工程,'mixed' 表示前后端混合工程);可选 desc(该应用的职责描述,便于人与 AI 理解应用分工)。",
3
3
  "apps":
4
4
  [
5
5
  {
@@ -1,50 +1,10 @@
1
- # 业务空间使用说明(AI Agent 导航)
1
+ # AGENTS.md
2
2
 
3
- 本目录是由 `@jspg-ai/coding-bb` 初始化的**多仓库联动开发业务空间**。
4
- 进入本目录工作时,请先按本文件理解目录职责与协作约定,再动手。
3
+ 本空间由 `@jspg-ai/coding-bb` 初始化(升级用 `cbb update`)。
5
4
 
6
- ## 核心约定
7
-
8
- 1. **双模式开发,用户选择制**:接到需求先问"要不要隔离/并行"——要 → **worktree 模式**(`/cbb-worktree-init <需求名>`,隔离目录、可多需求并行);不要 → **本地模式**(`/cbb-local-mode`,根与 `.codespace/<app>/` 就地切同名分支、当前会话直接干)。两模式能力对称(都能改 workspace 内容与应用代码、都强制分支隔离、交付都走 MR),agent 只给推荐,用户拍板。模式选错零代价:本地模式中途重跑 `/cbb-worktree-init` 即升级隔离(分支复用,提交随身带走)。
9
- 2. **基准 = `origin/main`(唯一真相源)**:`.codespace/<app>/` 是各应用的**标准本地检出(视图)**——main 检出是基准快照,本地模式下可 checkout 到需求分支暂态占用(收尾恢复)。读"main 现状"先看检出分支或用 `git show main:<path>`,不要默认工作区即基准。
10
- 3. **严禁直接在 main 检出上提交载荷**:分支感知 pre-commit hook 会机械拦截(workspace 仓库仅放行控制面白名单:`workspace-config.json` / `.gitignore` / `AGENTS.md` / `openspec/config.yaml` / `openspec/schemas/**`;应用仓库 main 全拦)——被拦是防线生效,不是故障;`--no-verify` 仅限用户显式要求。
11
- 4. **开发会话开在开发目录**:本地模式 = 当前会话原地(根检出分支后);worktree 模式 = 新会话开进 `.worktrees/worktree-<需求名>/`(AI 配置已 junction,`/opsx:*` 等命令可用)——相对路径原样生效。空间根会话保留作**控制面**(模式调度、worktree 生灭、`cbb update`)。
12
- 5. **远端推送唯一出口 = "提交并推送"**(`/cbb-worktree-push`,dry-run 预览 → 确认 commit 信息 → push → MR 预填链接)。worktree 创建流程零远端操作(lazy push)。
13
- 6. **开工前必做状态自检**:对 `cbb-local-mode` 说开工(或跑其状态自检)——干净态零交互;**遗留态(上一需求没收尾)必须先由用户决策**(继续 / 收尾 / 升级 / 丢弃)。本地模式一次只承载一个需求;并行需求走 worktree 模式(互不干扰)。
14
- 7. **关联应用增减只改配置**:编辑 `workspace-config.json` 的 `apps` 数组(`name` / `repo` / `side` / `desc`),然后重跑对应模式技能即幂等补齐;不要手工 `git clone` 应用仓库。
15
-
16
- ## 目录结构与职责
17
-
18
- | 路径 | 职责 | 维护方式 |
19
- |------|----------|----------|
20
- | `workspace-config.json` | 关联应用清单,所有应用联动的唯一数据源 | 人工编辑(控制面白名单,可直接提交 main) |
21
- | `.codespace/` | 各应用的**标准本地检出**(基准 = `origin/main`) | `cbb setup` 与技能自动 clone / fetch;本地模式可在其中**切需求分支开发**(main 检出禁改);已 gitignore,不提交 |
22
- | `.worktrees/` | 需求隔离开发区(每个需求一个 `worktree-<需求名>/`,内含 AI 配置 junction 与 `.codespace/<app>/` 应用检出,**镜像本空间布局**) | worktree 技能自动创建 / 清理;已 gitignore,不提交 |
23
- | `openspec/` | OpenSpec 工作流配置(`config.yaml` + `schemas/`) | `config.yaml`/`schemas/` 为控制面白名单(`cbb update` 部署,可直改);变更产物(`openspec/changes/`)落需求分支随 MR 合入 |
24
- | `.claude/` `.qoder/` `.opencode/` `.workbuddy/` `.trae/` | AI 工具适配目录:编码规范规则、OpenSpec 命令、技能 | 由 cbb 按 setup 时选择的工具安装(**唯一物理副本在此**);worktree 内经 junction 引用同一份;已 gitignore,不提交,勿手动改 |
25
- | `.cbb/` | cbb 安装清单与状态(`.managed-by-cbb`、`.last-tools`) | 由 cbb 管理;**勿手动编辑** |
26
-
27
- ## 典型流程
28
-
29
- ```
30
- 需求进来 → 选模式(agent 推荐 + 用户拍板)
31
- ├─ 本地模式(单线程快改):
32
- │ /cbb-local-mode(自检 → 确认布局 → 根+涉及 app 就地切分支)
33
- │ → 当前会话直接开发:/opsx:propose → apply → verify
34
- │ → 说"提交并推送"(push 技能自动发现本地布局)→ MR 预填链接
35
- │ → 验收通过 → /opsx:archive → MR 合并 → 收尾(各仓库回 main + 删分支)
36
- └─ worktree 模式(并行 / 隔离):
37
- /cbb-worktree-init <需求名>(建分支+worktree+AI 配置 junction,不推远端)
38
- → 开发会话开进 .worktrees/worktree-<需求名>/ → opsx 全流程
39
- → 说"提交并推送" → MR 预填链接(测试分支)
40
- → 测试环境验收 → /opsx:archive → 正式合并走公司流程
41
- → 说"关闭工作空间"(/cbb-worktree-close)
42
- ```
43
-
44
- > worktree 管理技能(init / close / push)与本地模式技能(cbb-local-mode)均以 **skill 形态**分发:既能被 AI 在对话中按意图**自动触发**(如"为 xxx 创建工作空间"、"本地模式开发"、"提交并推送"、"关闭工作空间"),也能用斜杠命令手动指定(各工具一致)。OpenSpec 命令为 `/opsx:propose`(opencode 扁平化为 `/opsx-propose`)。
5
+ - **行为准则与开发纪律**(双模式、基准 = `origin/main`、提交防线、推送出口):见你所用 AI 工具规则目录中的 `cbb-ai-behavior.md`——各工具自动加载;未适配的工具可任选一处直接读,如 `.claude/rules/cbb-ai-behavior.md` 或 `.qoder/rules/` 下同名文件。
6
+ - **空间事实**:关联应用清单(增减应用即编辑它)见 `CBB-WORKSPACE.json`;目录职责建议维护在你自己的 `README.md`。
45
7
 
46
8
  ---
47
9
 
48
10
  本文件由 `@jspg-ai/coding-bb` 生成(仅缺失时写入,之后不会覆盖或删除,可自由增补团队约定)。
49
-
50
- > ⓘ 本文件仅供导航;开发模式纪律以 cbb 安装的编码规范规则(`cbb-ai-behavior.md` 第 8 条)为准,该规则随 `cbb update` 更新。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jspg-ai/coding-bb",
3
- "version": "0.0.3-beta.24",
3
+ "version": "0.0.3-beta.25",
4
4
  "description": "整合业界热门且高价值的工具、框架与技能,为 AI CODING AGENT 提供统一的行为准则与工作流,辅助开发者将需求高效落地为符合规范的代码",
5
5
  "main": "cbb/lib/install/init.js",
6
6
  "bin": {