@jspg-ai/coding-bb 0.0.3-beta.3 → 0.0.3-beta.4
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.
- package/cbb/lib/install/init.js +56 -15
- package/cbb/lib/install/opencode.js +2 -0
- package/cbb/worktrees/commands/worktree-close.md +3 -4
- package/cbb/worktrees/commands/worktree-init.md +4 -5
- package/cbb/worktrees/commands/worktree-push.md +1 -1
- package/cbb/worktrees/skills/cbb-worktree-close/SKILL.md +7 -7
- package/cbb/worktrees/skills/cbb-worktree-init/SKILL.md +12 -12
- package/cbb/worktrees/skills/cbb-worktree-push/SKILL.md +6 -6
- package/config/workspace-agents.sample.md +2 -2
- package/package.json +1 -1
package/cbb/lib/install/init.js
CHANGED
|
@@ -68,8 +68,8 @@ const SUPERPOWERS_WHITELIST = [
|
|
|
68
68
|
'test-driven-development', // TDD 计划结构 + TDD Evidence 方法论基底
|
|
69
69
|
];
|
|
70
70
|
|
|
71
|
-
// worktree
|
|
72
|
-
//
|
|
71
|
+
// worktree 运行时部署清单:init / close / push 三件套(SKILL.md + scripts),
|
|
72
|
+
// 部署到 .cbb/skills/<name>/(每空间一份,不分工具;命令文件统一指向此处)
|
|
73
73
|
const WORKTREE_SKILLS = ['cbb-worktree-init', 'cbb-worktree-close', 'cbb-worktree-push'];
|
|
74
74
|
|
|
75
75
|
// 装到空间的 tools skills:当前不分发。
|
|
@@ -560,18 +560,41 @@ function deployCommandFiles(adapter, srcDir, destDir, prefix, filter) {
|
|
|
560
560
|
const srcPath = path.join(srcDir, f);
|
|
561
561
|
const destPath = path.join(destDir, prefix + f);
|
|
562
562
|
removePath(destPath);
|
|
563
|
-
const content = sanitizeCommandFrontmatter(applyContentRewrites(adapter, fs.readFileSync(srcPath, 'utf-8')));
|
|
563
|
+
const content = rewriteCommandName(adapter, sanitizeCommandFrontmatter(applyContentRewrites(adapter, fs.readFileSync(srcPath, 'utf-8'))));
|
|
564
564
|
fs.writeFileSync(destPath, content);
|
|
565
565
|
});
|
|
566
566
|
|
|
567
567
|
return { count: commandFiles.length, names: commandFiles.map(f => prefix + f) };
|
|
568
568
|
}
|
|
569
569
|
|
|
570
|
+
/**
|
|
571
|
+
* worktree 运行时部署:SKILL.md + scripts 复制到 .cbb/skills/<name>/(每空间一份,不分工具)。
|
|
572
|
+
* 单形态 command 收敛后,worktree 不进各工具的 skills 目录——新版工具会把 skills 暴露成
|
|
573
|
+
* 斜杠命令,与命令文件在面板里重复;脚本与流程文档统一放 .cbb/skills/,命令文件指向此处。
|
|
574
|
+
*/
|
|
575
|
+
function deployWorktreeRuntime(newPaths) {
|
|
576
|
+
const srcDir = path.join(SHARED_STANDARDS_DIR, 'cbb', 'worktrees', 'skills');
|
|
577
|
+
if (!fs.existsSync(srcDir)) return 0;
|
|
578
|
+
const runtimeDir = path.join(TARGET_DIR, '.cbb', 'skills');
|
|
579
|
+
fs.mkdirSync(runtimeDir, { recursive: true });
|
|
580
|
+
let count = 0;
|
|
581
|
+
WORKTREE_SKILLS.forEach(name => {
|
|
582
|
+
const src = path.join(srcDir, name);
|
|
583
|
+
if (!fs.existsSync(src)) return;
|
|
584
|
+
const destDir = path.join(runtimeDir, name);
|
|
585
|
+
removePath(destDir);
|
|
586
|
+
fs.cpSync(src, destDir, { recursive: true });
|
|
587
|
+
newPaths.add(`.cbb/skills/${name}`);
|
|
588
|
+
count++;
|
|
589
|
+
});
|
|
590
|
+
return count;
|
|
591
|
+
}
|
|
592
|
+
|
|
570
593
|
/**
|
|
571
594
|
* 命令 frontmatter 消毒:opencode 新版校验命令配置(description 必须为 string | undefined),
|
|
572
595
|
* 上游个别命令(openspec/commands/update.md)的 description 为空值(YAML 解析为 null),
|
|
573
|
-
* 会导致 opencode
|
|
574
|
-
*
|
|
596
|
+
* 会导致 opencode 拒绝加载整个项目配置。此处对部署副本回填正文首句作为描述
|
|
597
|
+
* (超过 120 字截断),上游源文件不动(CLI 接管区)。
|
|
575
598
|
*/
|
|
576
599
|
function sanitizeCommandFrontmatter(content) {
|
|
577
600
|
const lines = content.split('\n');
|
|
@@ -581,16 +604,38 @@ function sanitizeCommandFrontmatter(content) {
|
|
|
581
604
|
if ((lines[i] || '').trim() === '---') { end = i; break; }
|
|
582
605
|
}
|
|
583
606
|
if (end === -1) return content;
|
|
607
|
+
let sentence = '';
|
|
608
|
+
for (let i = end + 1; i < lines.length; i++) {
|
|
609
|
+
const t = (lines[i] || '').trim();
|
|
610
|
+
if (t) { sentence = t; break; }
|
|
611
|
+
}
|
|
584
612
|
let changed = false;
|
|
585
613
|
for (let i = 1; i < end; i++) {
|
|
586
614
|
if (/^description:\s*(null|~)?\s*\r?$/.test(lines[i])) {
|
|
587
|
-
|
|
615
|
+
if (sentence) {
|
|
616
|
+
if (sentence.length > 120) sentence = sentence.slice(0, 117) + '...';
|
|
617
|
+
lines[i] = 'description: ' + JSON.stringify(sentence) + (lines[i].endsWith('\r') ? '\r' : '');
|
|
618
|
+
} else {
|
|
619
|
+
lines[i] = null; // 无正文可回填则移除(undefined 同样合法)
|
|
620
|
+
}
|
|
588
621
|
changed = true;
|
|
589
622
|
}
|
|
590
623
|
}
|
|
591
624
|
return changed ? lines.filter(l => l !== null).join('\n') : content;
|
|
592
625
|
}
|
|
593
626
|
|
|
627
|
+
/**
|
|
628
|
+
* opencode 命令显示名取自 frontmatter name,上游为大写空格风格("OPSX: Propose"),
|
|
629
|
+
* 与文档写法(/opsx-propose)不一致;部署副本统一重写为 kebab-case。
|
|
630
|
+
*/
|
|
631
|
+
function rewriteCommandName(adapter, content) {
|
|
632
|
+
if (!adapter.commandNameKebab) return content;
|
|
633
|
+
return content.replace(/^name:\s*"?([A-Za-z]+):\s*([^"\r\n]+?)"?\s*\r?$/m, (m0, ns, rest) => {
|
|
634
|
+
const kebab = (ns + '-' + rest).toLowerCase().replace(/\s+/g, '-');
|
|
635
|
+
return `name: "${kebab}"`;
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
|
|
594
639
|
/** 官方 OpenSpec 命令(openspec/commands/ → adapter.commandsDir) */
|
|
595
640
|
function deployCommands(adapter, isUpgrade, managedPaths, srcDir, filter) {
|
|
596
641
|
if (!adapter.commandsDir) return { count: 0, names: [] };
|
|
@@ -969,11 +1014,10 @@ async function init(targetDir, options = {}) {
|
|
|
969
1014
|
if (skillsAdapters.length > 0) {
|
|
970
1015
|
console.log(`\n 🔧 ${action}按需加载 Skills...`);
|
|
971
1016
|
const standardsSkillsSrc = path.join(SHARED_STANDARDS_DIR, 'cbb', 'dev-standards', 'skills');
|
|
972
|
-
const openspecExtendsSkillsSrc = path.join(SHARED_STANDARDS_DIR, 'cbb', 'worktrees', 'skills');
|
|
973
1017
|
const extendsSkillsSrc = path.join(SHARED_STANDARDS_DIR, 'cbb', 'tools');
|
|
974
1018
|
|
|
975
1019
|
const skillsDests = skillsAdapters.map(a => a.skillsDir);
|
|
976
|
-
let stdCount = 0,
|
|
1020
|
+
let stdCount = 0, extCount = 0;
|
|
977
1021
|
skillsAdapters.forEach(adapter => {
|
|
978
1022
|
// 通用编码规范 Skills(cbb/dev-standards/skills)
|
|
979
1023
|
const stdResult = deploySkills(adapter, isUpgrade, managedPaths, standardsSkillsSrc);
|
|
@@ -983,12 +1027,6 @@ async function init(targetDir, options = {}) {
|
|
|
983
1027
|
}
|
|
984
1028
|
// 官方 OpenSpec Skills(openspec/skills/)不部署——工作流入口统一为 /opsx:* 斜杠命令
|
|
985
1029
|
//(openspec/commands/ 在下方 Commands 段部署),避免双形态重复
|
|
986
|
-
// worktree 扩展 Skills:init / close / push 三件套(单层安装,空间根是唯一安装点)
|
|
987
|
-
const osExtResult = deploySkills(adapter, isUpgrade, managedPaths, openspecExtendsSkillsSrc, WORKTREE_SKILLS);
|
|
988
|
-
if (osExtResult.count > 0) {
|
|
989
|
-
osCount = osExtResult.count;
|
|
990
|
-
osExtResult.names.forEach(name => newPaths.add(`${adapter.skillsDir}/${name}`));
|
|
991
|
-
}
|
|
992
1030
|
// 工具 Skills:当前不分发(恢复方式见 TOOLS_SKILLS 注释)
|
|
993
1031
|
const extResult = deploySkills(adapter, isUpgrade, managedPaths, extendsSkillsSrc, TOOLS_SKILLS);
|
|
994
1032
|
if (extResult.count > 0) {
|
|
@@ -997,7 +1035,6 @@ async function init(targetDir, options = {}) {
|
|
|
997
1035
|
}
|
|
998
1036
|
});
|
|
999
1037
|
if (stdCount > 0) log(`规范 Skills → ${skillsDests.join(', ')} (${stdCount} 个)`, 'success');
|
|
1000
|
-
if (osCount > 0) log(`worktree Skills → ${skillsDests.join(', ')} (${osCount} 个)`, 'success');
|
|
1001
1038
|
if (extCount > 0) log(`扩展 Skills → ${skillsDests.join(', ')} (${extCount} 个)`, 'success');
|
|
1002
1039
|
|
|
1003
1040
|
// 部署 Superpowers Skills(白名单:openspec 工作流依赖 + 方法论基底)
|
|
@@ -1021,6 +1058,10 @@ async function init(targetDir, options = {}) {
|
|
|
1021
1058
|
await detectUserLevelSuperpowers(selectedAdapters, yes);
|
|
1022
1059
|
}
|
|
1023
1060
|
|
|
1061
|
+
// worktree 运行时(SKILL.md + scripts)→ .cbb/skills/(每空间一份,不分工具)
|
|
1062
|
+
const runtimeCount = deployWorktreeRuntime(newPaths);
|
|
1063
|
+
if (runtimeCount > 0) log(`worktree 运行时 → .cbb/skills (${runtimeCount} 个)`, 'success');
|
|
1064
|
+
|
|
1024
1065
|
// 安装 Commands(官方 11 个 → /opsx:*,onboard 不分发;worktree 管理 → /cbb:worktree-*,init/close/push 三件套)
|
|
1025
1066
|
const commandsAdapters = selectedAdapters.filter(a => a.commandsDir);
|
|
1026
1067
|
if (commandsAdapters.length > 0) {
|
|
@@ -27,6 +27,8 @@ module.exports = {
|
|
|
27
27
|
worktreeCommandPrefix: 'cbb-',
|
|
28
28
|
// 部署副本中将该引用串改写为 opencode 的命令风格(配合 commandPrefix)
|
|
29
29
|
contentRewrites: [['/opsx:', '/opsx-'], ['/cbb:', '/cbb-']],
|
|
30
|
+
// 命令显示名取自 frontmatter name,部署副本重写为 kebab-case(/opsx-propose,与文档一致)
|
|
31
|
+
commandNameKebab: true,
|
|
30
32
|
// rules 加载登记:写入 .opencode/opencode.json 的 instructions。
|
|
31
33
|
// instructions 相对路径的解析基准(配置文件目录 vs 项目根)文档未写死,
|
|
32
34
|
// 登记双 glob 对冲:任一基准下恰有一个命中,另一个空匹配。
|
|
@@ -11,12 +11,11 @@ tags: [worktree, cleanup, worktree, git-worktree]
|
|
|
11
11
|
|
|
12
12
|
**禁止**用 `ls` / `find` / `cat` / `head` / `grep` 等 bash 命令搜索 SKILL.md。这些命令在 Agent 运行环境(Qoder Windows PowerShell 等)中经常失败。
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
- Claude Code 适配器:`.claude/skills/cbb-worktree-close/SKILL.md`
|
|
14
|
+
**直接路径**(各工具统一,worktree 运行时部署在空间根 `.cbb/skills/`):
|
|
15
|
+
- `.cbb/skills/cbb-worktree-close/SKILL.md`
|
|
17
16
|
|
|
18
17
|
**第一步**:
|
|
19
|
-
1. 用 Read 工具直接打开 SKILL.md
|
|
18
|
+
1. 用 Read 工具直接打开 `.cbb/skills/cbb-worktree-close/SKILL.md`
|
|
20
19
|
2. 按 SKILL.md 的 Step 0 → 1 → 2 → 3 → 4 → 5 → 6 顺序执行
|
|
21
20
|
3. 每次调用 Node.js 脚本时使用**绝对路径**
|
|
22
21
|
|
|
@@ -11,16 +11,15 @@ tags: [worktree, isolation, worktree, git-worktree]
|
|
|
11
11
|
|
|
12
12
|
**禁止**用 `ls` / `find` / `cat` / `head` / `grep` 等 bash 命令搜索 SKILL.md 是否存在。**这些命令在 Agent 运行环境(Qoder Windows PowerShell 等)中经常失败**(如 `head` 不存在、stderr 重定向无效等)。
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
- Claude Code 适配器:`.claude/skills/cbb-worktree-init/SKILL.md`
|
|
14
|
+
**直接路径**(各工具统一,worktree 运行时部署在空间根 `.cbb/skills/`):
|
|
15
|
+
- `.cbb/skills/cbb-worktree-init/SKILL.md`
|
|
17
16
|
|
|
18
17
|
**第一步**:
|
|
19
|
-
1. 用 Read 工具直接打开 `.
|
|
18
|
+
1. 用 Read 工具直接打开 `.cbb/skills/cbb-worktree-init/SKILL.md`
|
|
20
19
|
2. 按 SKILL.md 的 Step 0 → 1 → 2 → 3 → 4 顺序执行
|
|
21
20
|
3. 每次调用 Node.js 脚本时,使用**绝对路径**(避免依赖相对路径):
|
|
22
21
|
```
|
|
23
|
-
node "D:\workspace\<用户工作空间>\.
|
|
22
|
+
node "D:\workspace\<用户工作空间>\.cbb\skills\cbb-worktree-init\scripts\<name>.js" <参数>
|
|
24
23
|
```
|
|
25
24
|
- 参数形式:
|
|
26
25
|
- `check-env.js`:无参数
|
|
@@ -16,7 +16,7 @@ tags: [workflow, push, commit, worktree, experimental]
|
|
|
16
16
|
- 开发过程中想保存中间进度
|
|
17
17
|
- 用户口语化说"提交并push" / "推一下"
|
|
18
18
|
|
|
19
|
-
**Steps
|
|
19
|
+
**Steps 摘要**(详细流程见空间根 `.cbb/skills/cbb-worktree-push/SKILL.md`):
|
|
20
20
|
|
|
21
21
|
1. **Step 0**:定位工作空间根(find-workspace-root.js)
|
|
22
22
|
2. **Step 1**:识别目标 worktree(find-target-worktree.js)
|
|
@@ -34,7 +34,7 @@ metadata:
|
|
|
34
34
|
### 0.1 环境健康探活
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
node "D:/workspace/<ws_root>/.
|
|
37
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-close/scripts/check-env.js"
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
**解读输出**:
|
|
@@ -45,7 +45,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/check-env.
|
|
|
45
45
|
### 0.2 定位工作空间根目录
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
node "D:/workspace/<ws_root>/.
|
|
48
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-close/scripts/find-workspace-root.js"
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
**解读输出**:
|
|
@@ -69,7 +69,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/find-works
|
|
|
69
69
|
3. AI agent 列出 `.worktrees/` 下的所有 worktree:
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
|
-
node "D:/workspace/<ws_root>/.
|
|
72
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-close/scripts/find-target-worktree.js "<ws_root>"
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
> 注:本技能支持工作空间根目录或 worktree 内执行,find-target-worktree 自动从 cwd 反推或列出。
|
|
@@ -84,7 +84,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/find-targe
|
|
|
84
84
|
### 1.2 发现关联应用 worktree
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
-
node "D:/workspace/<ws_root>/.
|
|
87
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-close/scripts/discover-apps.js "<ws_root>" "<branch>"
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
脚本自动从 `workspace-config.json` 读取应用列表,扫描 `.worktrees/worktree-<branch>/<应用名>/` 实际存在的子目录。
|
|
@@ -98,7 +98,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/discover-a
|
|
|
98
98
|
### 1.3 检查未归档 change
|
|
99
99
|
|
|
100
100
|
```bash
|
|
101
|
-
node "D:/workspace/<ws_root>/.
|
|
101
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-close/scripts/check-unarchived.js "<ws_root>"
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
脚本扫描 `openspec/changes/` 目录,筛选出非 `archive/` 子目录的 change 名称列表。
|
|
@@ -117,7 +117,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-close/scripts/check-unar
|
|
|
117
117
|
对 workspace worktree 和每个关联应用 worktree,依次执行三项检查并汇总成安全状态表。**这是破坏性操作前的必经环节,结果将驱动 Step 3 的用户决策。**
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
node "D:/workspace/<ws_root>/.
|
|
120
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-close/scripts/safety-check.js "<ws_root>" "<branch>"
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
脚本内部对每个仓库自动执行:
|
|
@@ -289,7 +289,7 @@ node "<skill>/scripts/delete-branches.js" "<ws_root>" "<branch>" local_remote
|
|
|
289
289
|
**顺序:先移除各应用 worktree,再移除 workspace worktree**(逆序于创建;也为后续删分支扫清"分支仍被检出"的障碍)。
|
|
290
290
|
|
|
291
291
|
```bash
|
|
292
|
-
node "D:/workspace/<ws_root>/.
|
|
292
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-close/scripts/remove-worktrees.js "<ws_root>" "<branch>" "<force>"
|
|
293
293
|
```
|
|
294
294
|
|
|
295
295
|
**三层降级策略**:`git worktree remove` 实际包含两个动作——①清理 git 元数据(`.git/worktrees/`)②删除物理目录。当 IDE 占用目录时 ② 会被 Windows 文件锁阻塞,但 ① 永远不受影响。脚本将这两个动作解耦:
|
|
@@ -28,11 +28,11 @@ metadata:
|
|
|
28
28
|
|
|
29
29
|
## 调用脚本的统一方式
|
|
30
30
|
|
|
31
|
-
**重要**:所有脚本必须用**绝对路径**调用。`./scripts/...` 相对路径在 Agent 运行环境中不适用(AI agent 的 cwd 不一定是技能目录)。
|
|
31
|
+
**重要**:所有脚本必须用**绝对路径**调用。`./scripts/...` 相对路径在 Agent 运行环境中不适用(AI agent 的 cwd 不一定是技能目录)。worktree 运行时统一部署在空间根 `.cbb/skills/` 下,各工具一致。
|
|
32
32
|
|
|
33
33
|
调用方式(推荐用绝对路径):
|
|
34
34
|
```
|
|
35
|
-
node "D:\workspace\<用户工作空间>\.
|
|
35
|
+
node "D:\workspace\<用户工作空间>\.cbb\skills\cbb-worktree-init\scripts\<name>.js" <参数>
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
脚本输出:
|
|
@@ -54,7 +54,7 @@ node "D:\workspace\<用户工作空间>\.qoder\skills\cbb-worktree-init\scripts\
|
|
|
54
54
|
### 0.1 环境健康探活
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
node "D:/workspace/<ws_root>/.
|
|
57
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/check-env.js"
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
**解读输出**:
|
|
@@ -67,7 +67,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/check-env.j
|
|
|
67
67
|
提前检测权限/版本问题,把可能在后续步骤暴露的失败前移到流程最开始:
|
|
68
68
|
|
|
69
69
|
```bash
|
|
70
|
-
node "D:/workspace/<ws_root>/.
|
|
70
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/check-env-deep.js"
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
**解读输出**:
|
|
@@ -81,7 +81,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/check-env-d
|
|
|
81
81
|
### 0.2 读取并校验 workspace-config.json
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
|
-
node "D:/workspace/<ws_root>/.
|
|
84
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/parse-config.js"
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
**解读输出**:
|
|
@@ -148,7 +148,7 @@ worktree 需要知道要关联哪些应用仓库。
|
|
|
148
148
|
|
|
149
149
|
```bash
|
|
150
150
|
# ws_root 来自 AI agent 维护的状态
|
|
151
|
-
node "D:/workspace/<ws_root>/.
|
|
151
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/sync-repos.js" "<ws_root>"
|
|
152
152
|
```
|
|
153
153
|
|
|
154
154
|
**用法**:
|
|
@@ -192,7 +192,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/sync-repos.
|
|
|
192
192
|
| 当前在主分支上 | ✅ | ❌ |
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
|
-
node "D:/workspace/<ws_root>/.
|
|
195
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/check-repos.js" "<ws_root>"
|
|
196
196
|
```
|
|
197
197
|
|
|
198
198
|
**解读输出**:
|
|
@@ -220,7 +220,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/check-repos
|
|
|
220
220
|
### 3.2 安全更新 .gitignore(前置)
|
|
221
221
|
|
|
222
222
|
```bash
|
|
223
|
-
node "D:/workspace/<ws_root>/.
|
|
223
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/update-gitignore.js "<ws_root>" "<branch>"
|
|
224
224
|
```
|
|
225
225
|
|
|
226
226
|
脚本内部自动完成:stash 保护 → 切分支 → 添加 `.worktrees/` 和 `.codespace/` → 提交 → 切回 → pop stash
|
|
@@ -234,7 +234,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/update-giti
|
|
|
234
234
|
### 3.3 创建分支
|
|
235
235
|
|
|
236
236
|
```bash
|
|
237
|
-
node "D:/workspace/<ws_root>/.
|
|
237
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/create-branches.js" "<ws_root>" "<branch>"
|
|
238
238
|
```
|
|
239
239
|
|
|
240
240
|
**解读输出**:
|
|
@@ -259,7 +259,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/create-bran
|
|
|
259
259
|
### 3.4 推送并建立 upstream
|
|
260
260
|
|
|
261
261
|
```bash
|
|
262
|
-
node "D:/workspace/<ws_root>/.
|
|
262
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/push-branches.js" "<ws_root>" "<branch>"
|
|
263
263
|
```
|
|
264
264
|
|
|
265
265
|
脚本内部自动完成:
|
|
@@ -287,7 +287,7 @@ node "D:/workspace/<ws_root>/.qoder/skills/cbb-worktree-init/scripts/push-branch
|
|
|
287
287
|
### 3.5 创建 Worktree(含自愈清理)
|
|
288
288
|
|
|
289
289
|
```bash
|
|
290
|
-
node "D:/workspace/<ws_root>/.
|
|
290
|
+
node "D:/workspace/<ws_root>/.cbb/skills/cbb-worktree-init/scripts/create-worktrees.js" "<ws_root>" "<branch>"
|
|
291
291
|
```
|
|
292
292
|
|
|
293
293
|
脚本内部自动完成:
|
|
@@ -467,7 +467,7 @@ WT_PATH d:\workspace\xxx\.worktrees\worktree-feature-login
|
|
|
467
467
|
- workspace 仓库标准检查(当前在主分支等),app 仓库轻量检查(fetch + `origin/main` 可用即可)
|
|
468
468
|
- app 仓库分支从 `origin/main` 创建(`git branch <需求名> ${REMOTE}/${MAIN}`),不依赖本地主分支状态
|
|
469
469
|
- 严格 Step 3.3 → Step 3.4 顺序(先统一创建分支,再统一创建 worktree;workspace 工作树先建,各应用按序补建)
|
|
470
|
-
- 所有脚本调用以 `node "<WS_ROOT>\.
|
|
470
|
+
- 所有脚本调用以 `node "<WS_ROOT>\.cbb\skills\cbb-worktree-init\scripts\<name>.js" "<绝对路径>" "<branch>"` 形式发起(apps 由脚本内部从 workspace-config.json 读取),**不依赖跨调用的 cwd**
|
|
471
471
|
- **Step 3.4 push 步骤必须执行且插入在 create-branches.js (3.3) 之后、create-worktrees.js (3.5) 之前** — 失败时阻塞整个 init-worktree 流程
|
|
472
472
|
- **Step 3.4 仅覆盖创建 worktree 时的空 commit** — 开发过程中产生的本地 commit(如 apply 任务实现)必须由用户在 worktree 中手动提交并调 `cbb-worktree-push` 推送;不允许依赖 Step 3.4 之后的自动推送(不存在)
|
|
473
473
|
|
|
@@ -33,7 +33,7 @@ metadata:
|
|
|
33
33
|
**所有脚本必须用绝对路径调用**(Agent 运行环境中 AI agent 的 cwd 不一定是技能目录)。
|
|
34
34
|
|
|
35
35
|
```
|
|
36
|
-
node "<ws_root>/.
|
|
36
|
+
node "<ws_root>/.cbb/skills/cbb-worktree-push/scripts/<name>.js" <参数>
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
脚本输出:
|
|
@@ -46,7 +46,7 @@ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/<name>.js" <参数>
|
|
|
46
46
|
## Step 0:定位工作空间
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
node "<ws_root>/.
|
|
49
|
+
node "<ws_root>/.cbb/skills/cbb-worktree-push/scripts/find-workspace-root.js"
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
**解读末行**:
|
|
@@ -58,7 +58,7 @@ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/find-workspace-root.js"
|
|
|
58
58
|
## Step 1:识别目标 worktree
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
node "<ws_root>/.
|
|
61
|
+
node "<ws_root>/.cbb/skills/cbb-worktree-push/scripts/find-target-worktree.js" "<ws_root>"
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
**解读末行**:
|
|
@@ -72,7 +72,7 @@ node "<ws_root>/.qoder/skills/cbb-worktree-push/scripts/find-target-worktree.js"
|
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
74
|
# 仅 commit 阶段先做 dry-run 预览
|
|
75
|
-
node "<ws_root>/.
|
|
75
|
+
node "<ws_root>/.cbb/skills/cbb-worktree-push/scripts/commit-worktrees.js" "<ws_root>" "<branch>" --message "preview" --dry-run
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
**解读末行 `COMMIT_RESULT`**:每项仓库的状态
|
|
@@ -119,7 +119,7 @@ AI agent 在执行真实 commit 前**必须**在对话中向用户确认 commit
|
|
|
119
119
|
|
|
120
120
|
```bash
|
|
121
121
|
# 统一信息
|
|
122
|
-
node "<ws_root>/.
|
|
122
|
+
node "<ws_root>/.cbb/skills/cbb-worktree-push/scripts/commit-worktrees.js" "<ws_root>" "<branch>" --message "feat(<branch>): 实现客户运费逻辑"
|
|
123
123
|
|
|
124
124
|
# 多仓库分别
|
|
125
125
|
node "..." "<ws_root>" "<branch>" --per-repo "ep-foo-app:feat(<branch>): 实现 saveClientExpectFreight;ep-bar-app:refactor(<branch>): 拆分 PlanService"
|
|
@@ -155,7 +155,7 @@ node "..." "<ws_root>/.worktrees/worktree-<branch>" --message "..."
|
|
|
155
155
|
## Step 5:批量 push
|
|
156
156
|
|
|
157
157
|
```bash
|
|
158
|
-
node "<ws_root>/.
|
|
158
|
+
node "<ws_root>/.cbb/skills/cbb-worktree-push/scripts/push-worktrees.js" "<ws_root>" "<branch>"
|
|
159
159
|
|
|
160
160
|
# 或 wt_path 形式
|
|
161
161
|
node "..." "<ws_root>/.worktrees/worktree-<branch>"
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
| `.codespace/` | 各关联应用的基准代码(每个应用一个子目录) | `cbb setup` 与 worktree 流程自动 clone / fetch;**勿手动编辑**;已 gitignore,不提交 |
|
|
21
21
|
| `.worktrees/` | 需求隔离开发区(每个需求一个 `worktree-<需求名>/` 目录) | worktree 命令自动创建 / 清理;不提交(首次执行 worktree 流程时自动加入 .gitignore) |
|
|
22
22
|
| `openspec/` | OpenSpec 工作流配置(`config.yaml` + `schemas/`) | 由 cbb 安装;需求变更产物(`openspec/changes/` 等)在**需求工作树内**生成,随需求分支提交 |
|
|
23
|
-
| `.claude/` `.qoder/` `.opencode/` | AI 工具适配目录:编码规范规则、OpenSpec 命令、worktree
|
|
24
|
-
| `.cbb/` | cbb
|
|
23
|
+
| `.claude/` `.qoder/` `.opencode/` | AI 工具适配目录:编码规范规则、OpenSpec 命令、worktree 管理命令 | 由 cbb 按 setup 时选择的工具安装;已 gitignore,不提交,勿手动改 |
|
|
24
|
+
| `.cbb/` | cbb 安装清单 + worktree 运行时(`.cbb/skills/`:流程文档与脚本,各工具命令共用) | 由 cbb 管理;**勿手动编辑** |
|
|
25
25
|
|
|
26
26
|
## 典型流程
|
|
27
27
|
|