@jspg-ai/coding-bb 0.0.2-beta.28 → 0.0.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cbb/bin/cbbm.js +1 -1
- package/cbb/dev-standards/rules/cbb-ai-behavior.md +13 -0
- package/cbb/lib/install/init.js +122 -209
- package/cbb/lib/install/workspaces.js +24 -0
- package/cbb/lib/utils/check-update.js +1 -1
- package/cbb/lib/utils/checkbox.js +11 -11
- package/cbb/lib/utils/output.js +38 -16
- package/cbb/worktrees/commands/worktree-close.md +1 -1
- package/cbb/worktrees/commands/worktree-init.md +6 -10
- package/cbb/worktrees/skills/cbb-worktree-close/SKILL.md +1 -1
- package/cbb/worktrees/skills/cbb-worktree-close/scripts/check-env.js +4 -4
- package/cbb/worktrees/skills/cbb-worktree-init/SKILL.md +26 -51
- package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-env-deep.js +3 -33
- package/cbb/worktrees/skills/cbb-worktree-init/scripts/check-env.js +5 -14
- package/cbb/worktrees/skills/cbb-worktree-push/SKILL.md +2 -2
- package/config/workspace-agents.sample.md +39 -37
- package/config/workspaces.json +5 -0
- package/package.json +2 -2
- package/cbb/worktrees/skills/cbb-worktree-init/scripts/auto-open.js +0 -136
- package/cbb/worktrees/skills/cbb-worktree-init/scripts/install-ai.js +0 -177
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jspg-ai/coding-bb",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3-beta.1",
|
|
4
4
|
"description": "整合业界热门且高价值的工具、框架与技能,为 AI CODING AGENT 提供统一的行为准则与工作流,辅助开发者将需求高效落地为符合规范的代码",
|
|
5
5
|
"main": "cbb/lib/install/init.js",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"sync:shared": "node scripts/sync-shared.js",
|
|
21
21
|
"pretest": "node scripts/sync-shared.js --check",
|
|
22
|
-
"test": "node test/lib/install/cleanup.test.js && node test/lib/utils/settings.test.js && node test/lib/utils/gitignore.test.js && node test/lib/utils/version.test.js && node test/lib/install/workspaces.test.js && node test/lib/utils/checkbox.test.js && node test/lib/utils/output.test.js && node test/lib/install/cli-help.test.js && node test/lib/wiki/wiki-publish.test.js && node test/lib/wiki/wiki-parse-args.test.js && node test/lib/wiki/wiki-split.test.js && node test/lib/superpowers/superpowers.test.js && node test/worktrees/push-branches.test.js && node test/worktrees/commit-worktrees.test.js && node test/worktrees/push-worktrees.test.js && node test/worktrees/
|
|
22
|
+
"test": "node test/lib/install/cleanup.test.js && node test/lib/utils/settings.test.js && node test/lib/utils/gitignore.test.js && node test/lib/utils/version.test.js && node test/lib/install/workspaces.test.js && node test/lib/utils/checkbox.test.js && node test/lib/utils/output.test.js && node test/lib/install/cli-help.test.js && node test/lib/wiki/wiki-publish.test.js && node test/lib/wiki/wiki-parse-args.test.js && node test/lib/wiki/wiki-split.test.js && node test/lib/superpowers/superpowers.test.js && node test/worktrees/push-branches.test.js && node test/worktrees/commit-worktrees.test.js && node test/worktrees/push-worktrees.test.js && node test/worktrees/check-env-deep.test.js && node test/lib/openspec/openspec-render.test.js"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"cbb",
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
require('./silence-popup');
|
|
3
|
-
/**
|
|
4
|
-
* cbb-worktree-init 环境感知 + 自动打开 IDE/CLI
|
|
5
|
-
*
|
|
6
|
-
* 用法:node auto-open.js <wt_path>
|
|
7
|
-
*
|
|
8
|
-
* 检测当前运行环境并自动在新窗口打开 worktree:
|
|
9
|
-
* - Qoder GUI → qoder --new-window
|
|
10
|
-
* - Cursor GUI → cursor --new-window
|
|
11
|
-
* - VS Code GUI → code --new-window
|
|
12
|
-
* - JetBrains → 通过 Windows 注册表 / macOS open -a / Linux command -v 查找(launcher 默认开新窗口)
|
|
13
|
-
* - CLI 模式 → 仅切换 cwd,输出 ENV=CLI
|
|
14
|
-
*
|
|
15
|
-
* 输出末行:
|
|
16
|
-
* ENV=QODER_GUI / CURSOR_GUI / VSCODE_GUI / JETBRAINS_GUI / CLI
|
|
17
|
-
* 或 OPEN_FAILED
|
|
18
|
-
*
|
|
19
|
-
* 退出码:始终 0(失败也返回,由末行判断)
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
const { execSync } = require('child_process');
|
|
23
|
-
const fs = require('fs');
|
|
24
|
-
const os = require('os');
|
|
25
|
-
const path = require('path');
|
|
26
|
-
|
|
27
|
-
const wtPath = process.argv[2];
|
|
28
|
-
|
|
29
|
-
if (!wtPath) {
|
|
30
|
-
console.error('❌ 用法:node auto-open.js <wt_path>');
|
|
31
|
-
process.error = 'USAGE_ERROR';
|
|
32
|
-
process.exit(0);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!fs.existsSync(wtPath)) {
|
|
36
|
-
console.error('❌ worktree 路径不存在:' + wtPath);
|
|
37
|
-
console.log('---');
|
|
38
|
-
console.log('OPEN_FAILED');
|
|
39
|
-
process.exit(0);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function run(cmd, opts) {
|
|
43
|
-
try {
|
|
44
|
-
return { ok: true, out: execSync(cmd, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'], ...opts }).trim() };
|
|
45
|
-
} catch (e) {
|
|
46
|
-
return { ok: false };
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const qoderAgent = process.env.QODER_AGENT === 'true';
|
|
51
|
-
const vscodePid = process.env.VSCODE_PID;
|
|
52
|
-
const vscodeBrand = process.env.VSCODE_BRAND;
|
|
53
|
-
const termEmu = process.env.TERMINAL_EMULATOR || '';
|
|
54
|
-
|
|
55
|
-
// Qoder GUI
|
|
56
|
-
if (qoderAgent && vscodePid) {
|
|
57
|
-
const r = run('qoder --new-window "' + wtPath + '"');
|
|
58
|
-
if (r.ok) {
|
|
59
|
-
console.log('ENV=QODER_GUI');
|
|
60
|
-
} else {
|
|
61
|
-
console.log('OPEN_FAILED');
|
|
62
|
-
}
|
|
63
|
-
process.exit(0);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Cursor GUI
|
|
67
|
-
if (vscodePid && vscodeBrand === 'Cursor') {
|
|
68
|
-
const r = run('cursor --new-window "' + wtPath + '"');
|
|
69
|
-
if (r.ok) {
|
|
70
|
-
console.log('ENV=CURSOR_GUI');
|
|
71
|
-
} else {
|
|
72
|
-
console.log('OPEN_FAILED');
|
|
73
|
-
}
|
|
74
|
-
process.exit(0);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// 其他 VS Code 分支
|
|
78
|
-
if (vscodePid) {
|
|
79
|
-
const r = run('code --new-window "' + wtPath + '"');
|
|
80
|
-
if (r.ok) {
|
|
81
|
-
console.log('ENV=VSCODE_GUI');
|
|
82
|
-
} else {
|
|
83
|
-
console.log('OPEN_FAILED');
|
|
84
|
-
}
|
|
85
|
-
process.exit(0);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// JetBrains
|
|
89
|
-
if (/jetbrains/i.test(termEmu)) {
|
|
90
|
-
const platform = os.platform();
|
|
91
|
-
let launcher = '';
|
|
92
|
-
|
|
93
|
-
if (platform === 'win32') {
|
|
94
|
-
// Windows:通过 PowerShell 查注册表
|
|
95
|
-
const psCmd = 'powershell -NoProfile -Command "Get-ItemProperty \'HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\',\'HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\',\'HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\' -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -match \'IntelliJ|WebStorm|PyCharm|GoLand|PhpStorm|Rider|CLion|RubyMine|DataGrip\' } | Select-Object -First 1 -ExpandProperty DisplayIcon"';
|
|
96
|
-
const r = run(psCmd);
|
|
97
|
-
if (r.ok && r.out) launcher = r.out;
|
|
98
|
-
} else if (platform === 'darwin') {
|
|
99
|
-
// macOS:通过 open -Ra 查找
|
|
100
|
-
const apps = ['IntelliJ IDEA', 'WebStorm', 'PyCharm', 'GoLand', 'PhpStorm', 'Rider', 'CLion', 'RubyMine', 'DataGrip'];
|
|
101
|
-
for (const app of apps) {
|
|
102
|
-
const check = run('open -Ra "' + app + '"');
|
|
103
|
-
if (check.ok) {
|
|
104
|
-
const open = run('open -a "' + app + '" "' + wtPath + '"');
|
|
105
|
-
if (open.ok) {
|
|
106
|
-
console.log('ENV=JETBRAINS_GUI');
|
|
107
|
-
process.exit(0);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
} else {
|
|
112
|
-
// Linux:通过 command -v 查找
|
|
113
|
-
const cmds = ['idea64', 'idea', 'webstorm64', 'webstorm', 'pycharm64', 'pycharm', 'goland64', 'goland'];
|
|
114
|
-
for (const c of cmds) {
|
|
115
|
-
const which = run('command -v "' + c + '"');
|
|
116
|
-
if (which.ok && which.out) {
|
|
117
|
-
launcher = which.out;
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (launcher) {
|
|
124
|
-
const r = run('"' + launcher + '" "' + wtPath + '"');
|
|
125
|
-
if (r.ok) {
|
|
126
|
-
console.log('ENV=JETBRAINS_GUI');
|
|
127
|
-
process.exit(0);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
console.log('ENV=CLI');
|
|
131
|
-
process.exit(0);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// CLI 模式
|
|
135
|
-
console.log('ENV=CLI');
|
|
136
|
-
process.exit(0);
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
require('./silence-popup');
|
|
3
|
-
/**
|
|
4
|
-
* cbb-worktree-init 在 worktree 中安装 AI 配置(必要步骤)
|
|
5
|
-
*
|
|
6
|
-
* 用法:node install-ai.js <wt_path>
|
|
7
|
-
*
|
|
8
|
-
* 行为:
|
|
9
|
-
* 1. 检测 cbbm 是否全局安装,未安装则自动安装
|
|
10
|
-
* 2. 直接用 npm 全局 bin 路径调用 cbbm(避免 PowerShell PATH 缓存)
|
|
11
|
-
* 3. 在 worktree 内执行 cbbm init --yes
|
|
12
|
-
* 4. 失败则 exit 2,阻塞 init-worktree 流程(与 push-branches.js 语义一致)
|
|
13
|
-
*
|
|
14
|
-
* 退出码:
|
|
15
|
-
* 0 - 成功
|
|
16
|
-
* 1 - 参数错误(脚本 bug 或调用错误)
|
|
17
|
-
* 2 - cbbm init 执行失败(**阻塞 init-worktree**,用户必须手动恢复)
|
|
18
|
-
*/
|
|
19
|
-
const { execSync } = require('child_process');
|
|
20
|
-
const fs = require('fs');
|
|
21
|
-
const path = require('path');
|
|
22
|
-
|
|
23
|
-
const wtPath = process.argv[2];
|
|
24
|
-
|
|
25
|
-
if (!wtPath) {
|
|
26
|
-
console.error('Usage: node install-ai.js <wt_path>');
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!fs.existsSync(wtPath)) {
|
|
31
|
-
console.error('ERROR: worktree path not exist: ' + wtPath);
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function run(cmd, cwd, env) {
|
|
36
|
-
try {
|
|
37
|
-
return { ok: true, out: execSync(cmd, { cwd: cwd || process.cwd(), encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], env: env || process.env, input: '\n' }).trim() };
|
|
38
|
-
} catch (e) {
|
|
39
|
-
return { ok: false, err: (e.stderr || e.message || String(e)).trim() };
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// 查找 cbbm 可执行文件:先 PATH,再 npm 全局 bin
|
|
44
|
-
function findCbb() {
|
|
45
|
-
// 1. 直接调用 cbbm --version
|
|
46
|
-
let r = run('cbbm --version');
|
|
47
|
-
if (r.ok) return { cmd: 'cbbm', version: r.out };
|
|
48
|
-
|
|
49
|
-
// 2. 查 npm 全局 bin 目录
|
|
50
|
-
const npmRoot = run('npm root -g');
|
|
51
|
-
if (npmRoot.ok) {
|
|
52
|
-
// Windows: <npm_root>\..\cbb.cmd (bin 在 npm_root 的父目录)
|
|
53
|
-
// Unix: <npm_root>/../bin/cbb
|
|
54
|
-
const candidates = [];
|
|
55
|
-
if (process.platform === 'win32') {
|
|
56
|
-
candidates.push(path.join(npmRoot.out, 'cbbm.cmd'));
|
|
57
|
-
candidates.push(path.join(npmRoot.out, '..', 'cbbm.cmd'));
|
|
58
|
-
candidates.push(path.join(npmRoot.out, '..', 'bin', 'cbbm.cmd'));
|
|
59
|
-
// npm 全局 bin 通常是 %APPDATA%\npm\cbbm.cmd
|
|
60
|
-
const appdata = process.env.APPDATA || process.env.USERPROFILE;
|
|
61
|
-
if (appdata) candidates.push(path.join(appdata, 'npm', 'cbbm.cmd'));
|
|
62
|
-
} else {
|
|
63
|
-
candidates.push(path.join(npmRoot.out, '..', 'bin', 'cbbm'));
|
|
64
|
-
candidates.push(path.join(npmRoot.out, '..', 'cbbm'));
|
|
65
|
-
}
|
|
66
|
-
for (const c of candidates) {
|
|
67
|
-
if (fs.existsSync(c)) {
|
|
68
|
-
// 尝试执行
|
|
69
|
-
r = run('"' + c + '" --version');
|
|
70
|
-
if (r.ok) return { cmd: '"' + c + '"', version: r.out };
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// 1. 检测/安装 cbb
|
|
78
|
-
let cbbInfo = findCbb();
|
|
79
|
-
if (!cbbInfo) {
|
|
80
|
-
console.log('WARN: cbbm not globally installed, try auto-install...');
|
|
81
|
-
const install = run('npm install -g @jspg-ai/coding-bb');
|
|
82
|
-
if (!install.ok) {
|
|
83
|
-
console.error('ERROR: cbb auto-install failed: ' + install.err);
|
|
84
|
-
console.error('');
|
|
85
|
-
console.error('━━━ init-worktree 已中断 ━━━');
|
|
86
|
-
console.error('请手动安装 cbb 后重跑 init-worktree:');
|
|
87
|
-
console.error(' 1. npm install -g @jspg-ai/coding-bb');
|
|
88
|
-
console.error(' 2. cd "' + wtPath + '" && cbbm init --yes');
|
|
89
|
-
console.error(' 3. 在 ai-workspace 根目录重跑 init-worktree');
|
|
90
|
-
console.log('---');
|
|
91
|
-
console.log('AI_INIT_FAILED');
|
|
92
|
-
process.exit(2);
|
|
93
|
-
}
|
|
94
|
-
// 重新查找(npm install 后 PATH 可能仍未刷新)
|
|
95
|
-
cbbInfo = findCbb();
|
|
96
|
-
if (!cbbInfo) {
|
|
97
|
-
// 最后尝试直接用 npm 全局 bin
|
|
98
|
-
const npmRoot = run('npm root -g');
|
|
99
|
-
if (npmRoot.ok) {
|
|
100
|
-
const candidates = process.platform === 'win32'
|
|
101
|
-
? [path.join(npmRoot.out, '..', 'cbbm.cmd'), path.join(npmRoot.out, '..', 'bin', 'cbbm.cmd')]
|
|
102
|
-
: [path.join(npmRoot.out, '..', 'bin', 'cbbm')];
|
|
103
|
-
for (const c of candidates) {
|
|
104
|
-
if (fs.existsSync(c)) {
|
|
105
|
-
cbbInfo = { cmd: '"' + c + '"', version: 'located at ' + c };
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (!cbbInfo) {
|
|
112
|
-
console.error('ERROR: cbbm not found after install. Likely npm PATH cache issue.');
|
|
113
|
-
console.error('');
|
|
114
|
-
console.error('━━━ init-worktree 已中断 ━━━');
|
|
115
|
-
console.error('可能原因:npm 全局 bin 目录不在当前 shell 的 PATH 中。');
|
|
116
|
-
console.error('手动恢复步骤:');
|
|
117
|
-
console.error(' 1. 重启终端让 PATH 生效,或手动定位 cbbm:');
|
|
118
|
-
console.error(' npm root -g # 拿到全局 node_modules 路径');
|
|
119
|
-
console.error(' <path>/../cbbm.cmd # Windows / <path>/../bin/cbbm # Unix');
|
|
120
|
-
console.error(' 2. cd "' + wtPath + '" && cbbm init --yes');
|
|
121
|
-
console.error(' 3. 在 ai-workspace 根目录重跑 init-worktree');
|
|
122
|
-
console.log('---');
|
|
123
|
-
console.log('AI_INIT_FAILED');
|
|
124
|
-
process.exit(2);
|
|
125
|
-
}
|
|
126
|
-
console.log('OK: cbbm located: ' + cbbInfo.version);
|
|
127
|
-
} else {
|
|
128
|
-
console.log('OK: cbbm found: ' + cbbInfo.version);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// 2. 在 worktree 中执行 cbbm init --yes
|
|
132
|
-
console.log('Installing AI config in worktree: ' + wtPath);
|
|
133
|
-
const initCmd = cbbInfo.cmd + ' init --yes';
|
|
134
|
-
const init = run(initCmd, wtPath);
|
|
135
|
-
if (init.ok) {
|
|
136
|
-
console.log('OK: AI config installed');
|
|
137
|
-
// 输出 init 的最后几行(init 通常输出大量日志)
|
|
138
|
-
const lines = init.out.split(/\r?\n/);
|
|
139
|
-
const tail = lines.slice(-5).join('\n');
|
|
140
|
-
console.log(tail);
|
|
141
|
-
console.log('---');
|
|
142
|
-
console.log('AI_INIT_OK');
|
|
143
|
-
process.exit(0);
|
|
144
|
-
} else {
|
|
145
|
-
console.error('ERROR: AI config install failed: ' + init.err);
|
|
146
|
-
console.error('');
|
|
147
|
-
console.error('━━━ init-worktree 已中断 ━━━');
|
|
148
|
-
console.error('原因:cbbm init 是必要步骤。AI 配置缺失将导致后续 openspec-* ');
|
|
149
|
-
console.error(' (propose/apply/verify/ff 等)技能全部不可用。');
|
|
150
|
-
console.error('');
|
|
151
|
-
console.error('━━━ 手动恢复步骤(请按顺序执行)━━━');
|
|
152
|
-
console.error('');
|
|
153
|
-
console.error('1. 验证环境');
|
|
154
|
-
console.error(' $ cbbm --version');
|
|
155
|
-
console.error(' $ node --version # 需要 >= 16.7.0');
|
|
156
|
-
console.error('');
|
|
157
|
-
console.error('2. 若未安装(cbbm 不在 PATH),先安装');
|
|
158
|
-
console.error(' $ npm install -g @jspg-ai/coding-bb');
|
|
159
|
-
console.error('');
|
|
160
|
-
console.error('3. 进入 worktree 并初始化 AI 配置');
|
|
161
|
-
console.error(' $ cd "' + wtPath + '"');
|
|
162
|
-
console.error(' $ cbbm init --yes');
|
|
163
|
-
console.error('');
|
|
164
|
-
console.error('4. 重新执行 init-worktree');
|
|
165
|
-
console.error(' 在 ai-workspace 根目录重跑,会跳过已初始化的部分');
|
|
166
|
-
console.error(' (用 .cbb/.managed-by-cbb 判重)');
|
|
167
|
-
console.error('');
|
|
168
|
-
console.error('━━━ 常见失败原因对照 ━━━');
|
|
169
|
-
console.error(' • 0xc0000142 DLL 初始化失败 → 退出 Qoder 后重试,或到系统终端执行');
|
|
170
|
-
console.error(' • npm ERR! network → 检查代理:npm config get registry');
|
|
171
|
-
console.error(' • EACCES permission denied → 关闭杀毒软件或用管理员终端');
|
|
172
|
-
console.error(' • npm login 401 → token 过期,重新 npm login');
|
|
173
|
-
console.log('---');
|
|
174
|
-
console.log('AI_INIT_FAILED');
|
|
175
|
-
process.exit(2);
|
|
176
|
-
}
|
|
177
|
-
|