codebee 0.1.62 → 0.1.64

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 (101) hide show
  1. package/CHANGELOG.md +507 -490
  2. package/LICENSE +21 -21
  3. package/README.md +487 -486
  4. package/app/.playwright-cli/console-2026-09-23T08-26-03-635Z.log +88 -0
  5. package/app/.playwright-cli/page-2026-09-23T08-26-03-845Z.yml +126 -0
  6. package/app/.playwright-cli/page-2026-09-23T08-29-44-203Z.png +0 -0
  7. package/app/.playwright-cli/page-2026-09-23T08-35-42-046Z.yml +210 -0
  8. package/app/.playwright-cli/page-2026-09-23T08-36-52-858Z.png +0 -0
  9. package/app/.playwright-cli/page-2026-09-23T08-37-33-938Z.png +0 -0
  10. package/app/.playwright-cli/run-detail-after.png +0 -0
  11. package/app/core/aiflavor.py +197 -197
  12. package/app/core/artifacts.py +148 -0
  13. package/app/core/attachments.py +532 -532
  14. package/app/core/automation.py +758 -758
  15. package/app/core/backup.py +470 -470
  16. package/app/core/beekeeper.py +183 -183
  17. package/app/core/board.py +209 -209
  18. package/app/core/bookmeta.py +215 -19
  19. package/app/core/bookmeta_catalog.py +180 -180
  20. package/app/core/branching.py +137 -137
  21. package/app/core/builtin_agent.py +1191 -1191
  22. package/app/core/capability.py +144 -144
  23. package/app/core/catalog.py +19 -14
  24. package/app/core/chaptersafe.py +32 -32
  25. package/app/core/cleanup.py +303 -303
  26. package/app/core/compaction.py +186 -186
  27. package/app/core/covergen.py +356 -356
  28. package/app/core/diagnostics.py +114 -114
  29. package/app/core/dispatch.py +173 -173
  30. package/app/core/dispatch_log.py +113 -113
  31. package/app/core/env_scrub.py +85 -85
  32. package/app/core/error_codes.py +64 -64
  33. package/app/core/errorlog.py +137 -137
  34. package/app/core/flows.py +355 -355
  35. package/app/core/goal_service.py +167 -167
  36. package/app/core/health.py +341 -341
  37. package/app/core/history.py +38 -38
  38. package/app/core/hooks.py +156 -156
  39. package/app/core/jobs.py +1022 -1022
  40. package/app/core/manager.py +1996 -1996
  41. package/app/core/market.py +362 -362
  42. package/app/core/market_remote.py +66 -66
  43. package/app/core/mocks.py +64 -64
  44. package/app/core/modelhub.py +3332 -3266
  45. package/app/core/notify.py +106 -106
  46. package/app/core/paihang.py +109 -109
  47. package/app/core/paths.py +2 -2
  48. package/app/core/pipeline.py +4483 -4426
  49. package/app/core/planner.py +27 -27
  50. package/app/core/portguard.py +111 -111
  51. package/app/core/preview.py +293 -293
  52. package/app/core/publish/__init__.py +7 -7
  53. package/app/core/publish/auto.py +367 -367
  54. package/app/core/publish/browser.py +533 -533
  55. package/app/core/publish/fanqie.py +128 -128
  56. package/app/core/publish/flow.py +406 -406
  57. package/app/core/publish/ledger.py +198 -198
  58. package/app/core/publish/manager.py +590 -590
  59. package/app/core/publish/qimao.py +141 -141
  60. package/app/core/publish/ws.py +139 -139
  61. package/app/core/redact.py +38 -38
  62. package/app/core/repeat_guard.py +124 -124
  63. package/app/core/router.py +20 -3
  64. package/app/core/runner.py +2019 -1991
  65. package/app/core/selfupdate.py +384 -384
  66. package/app/core/session_log.py +161 -161
  67. package/app/core/sessions.py +312 -312
  68. package/app/core/settings.py +149 -149
  69. package/app/core/settings_schema.py +262 -262
  70. package/app/core/share_page.py +114 -114
  71. package/app/core/skill_scan.py +106 -106
  72. package/app/core/skillpacks/fanqie-novel.md +80 -80
  73. package/app/core/skillpacks/market/character-bible.md +66 -66
  74. package/app/core/skillpacks/market/code-risk-checklist.md +58 -58
  75. package/app/core/skillpacks/market/git-workflow.md +57 -57
  76. package/app/core/skillpacks/market/release-notes.md +72 -72
  77. package/app/core/skillpacks/market/weekly-report.md +71 -71
  78. package/app/core/skillpacks/market/worldview-consistency.md +70 -70
  79. package/app/core/step_runner.py +132 -132
  80. package/app/core/store.py +13 -70
  81. package/app/core/task_compile.py +199 -199
  82. package/app/core/telemetry.py +292 -292
  83. package/app/core/tlsctx.py +64 -64
  84. package/app/core/token_meter.py +147 -147
  85. package/app/core/volumes.py +355 -355
  86. package/app/core/wxdigest.py +858 -858
  87. package/app/core/zentao.py +2447 -2090
  88. package/app/main.py +2832 -2826
  89. package/app/pick_dialog.py +110 -110
  90. package/app/ui/app.js +13977 -13977
  91. package/app/ui/board.html +162 -162
  92. package/app/ui/board.js +305 -305
  93. package/app/ui/i18n.js +2711 -2711
  94. package/app/ui/icons/bee.svg +79 -79
  95. package/app/ui/index.html +1 -1
  96. package/app/ui/manifest.json +16 -16
  97. package/app/ui/qrcode.js +2297 -2297
  98. package/app/ui/style.css +6125 -6125
  99. package/bin/tutti.js +147 -147
  100. package/package.json +41 -41
  101. package/tools/wx_reader.py +261 -261
package/bin/tutti.js CHANGED
@@ -1,147 +1,147 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
- /*
4
- * CodeBee 启动垫片:在本机找 Python 3.8+,以子进程方式运行包内 app/main.py。
5
- * npm 只负责分发与版本管理,不携带解释器——所以运行时才探测 python,
6
- * 找不到就报错并给出安装指引(不写 postinstall,避免在别人机器上制造环境事故)。
7
- *
8
- * 安全边界:
9
- * - 子进程可执行文件全部是本文件内的字面量(py / python / python3)——包括
10
- * TUTTI_PYTHON 覆盖时:它只允许在这三个字面量里选一个,绝不拼接任意路径;
11
- * - 参数数组全由字面量常量拼成,不启用 shell;
12
- * - 探测只传 `--version`(不向解释器传递任何代码);Windows 商店的 python.exe
13
- * 假占位会非零退出,被 catch 后自然跳过;
14
- * - 用户参数逐个过白名单校验(仅字母数字与 _ - . : = / @ % 空格),
15
- * 含 shell 元字符/控制字符的参数直接拒绝。
16
- */
17
- const { execFileSync, spawn } = require('child_process');
18
- const path = require('path');
19
-
20
- const MIN_MAJOR = 3;
21
- const MIN_MINOR = 8;
22
- const MAIN = path.join(__dirname, '..', 'app', 'main.py');
23
- const SAFE_ARG = /^[A-Za-z0-9_\-.:=/@% ]+$/;
24
-
25
- // 解析 `--version` 输出:形如 "Python 3.12.4",返回 {ver, major, minor} 或 null。
26
- // 纯字符串切分,不用正则匹配执行路径。
27
- function parseVersion(text) {
28
- const at = String(text).indexOf('Python ');
29
- if (at === -1) return null;
30
- const parts = String(text).slice(at + 7).trim().split(' ')[0].split('.');
31
- const major = Number(parts[0]);
32
- const minor = Number(parts[1]);
33
- if (!Number.isFinite(major) || !Number.isFinite(minor)) return null;
34
- return { ver: major + '.' + minor, major: major, minor: minor };
35
- }
36
-
37
- function probePy() {
38
- try {
39
- return parseVersion(execFileSync('py', ['-3', '--version'],
40
- { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }));
41
- } catch (e) { return null; }
42
- }
43
- function probePython() {
44
- try {
45
- return parseVersion(execFileSync('python', ['--version'],
46
- { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }));
47
- } catch (e) { return null; }
48
- }
49
- function probePython3() {
50
- try {
51
- return parseVersion(execFileSync('python3', ['--version'],
52
- { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }));
53
- } catch (e) { return null; }
54
- }
55
-
56
- // 探测顺序:win32 优先 py 启动器(跨版本选真 3.x),其余按 python3 → python。
57
- function resolvePython() {
58
- const order = process.platform === 'win32'
59
- ? [['py', probePy], ['python', probePython], ['python3', probePython3]]
60
- : [['python3', probePython3], ['python', probePython]];
61
- for (const [name, probe] of order) {
62
- const hit = probe();
63
- if (!hit) continue;
64
- if (hit.major > MIN_MAJOR || (hit.major === MIN_MAJOR && hit.minor >= MIN_MINOR)) {
65
- return { name: name };
66
- }
67
- return { tooOld: true, name: name, ver: hit.ver };
68
- }
69
- return null;
70
- }
71
-
72
- function guide() {
73
- const url = { win32: 'https://www.python.org/downloads/windows/',
74
- darwin: 'https://www.python.org/downloads/macos/',
75
- linux: 'https://docs.python.org/3/using/unix.html' }[process.platform]
76
- || 'https://www.python.org/downloads/';
77
- return 'CodeBee 需要本机安装 Python 3.8+(npm 包不含解释器)。\n'
78
- + ' · 安装:' + url + '\n'
79
- + ' · Windows 安装时勾选 “Add python.exe to PATH”(自带 py 启动器)\n'
80
- + '装好后重新运行:codebee';
81
- }
82
-
83
- const py = resolvePython();
84
- if (!py) {
85
- console.error('[CodeBee] 未找到可用的 Python。\n' + guide());
86
- process.exit(1);
87
- }
88
- if (py.tooOld) {
89
- console.error('[CodeBee] 找到 ' + py.name + '(' + py.ver + '),但版本过低。\n' + guide());
90
- process.exit(1);
91
- }
92
-
93
- const userArgs = [];
94
- for (const a of process.argv.slice(2)) {
95
- if (typeof a === 'string' && SAFE_ARG.test(a)) {
96
- userArgs.push(a);
97
- } else {
98
- console.error('[CodeBee] 参数含非法字符,已拒绝:' + String(a).slice(0, 80));
99
- process.exit(2);
100
- }
101
- }
102
-
103
- // CLI 转发契约:codebee 之后的用户参数(已过白名单)原样作为 main.py 的 argv。
104
- // 控制台日志即见:GBK 控制台下强制 UTF-8 输出(否则中文 print 触发 UnicodeEncodeError 静默卡死)。
105
- const childEnv = Object.assign({}, process.env, { PYTHONIOENCODING: 'utf-8', PYTHONUTF8: '1', PYTHONUNBUFFERED: '1' });
106
- // TUTTI_PYTHON 覆盖解释器:只允许在三个字面量里选(py/python/python3,.exe
107
- // 后缀可选、大小写不限)——环境变量永远只做「选择题」,不做「填空题」;
108
- // 机器上有多个解释器且探测选错时,用它切换。
109
- let exe = py.name;
110
- const ovRaw = String(process.env.TUTTI_PYTHON || '').trim().toLowerCase();
111
- const ov = ovRaw.endsWith('.exe') ? ovRaw.slice(0, -4) : ovRaw;
112
- if (ov === 'python') {
113
- exe = 'python';
114
- } else if (ov === 'python3') {
115
- exe = 'python3';
116
- } else if (ov === 'py') {
117
- exe = 'py';
118
- }
119
-
120
- let child;
121
- if (exe === 'py') {
122
- child = spawn('py', ['-3', MAIN, ...userArgs], { stdio: 'inherit', env: childEnv });
123
- } else if (exe === 'python') {
124
- child = spawn('python', [MAIN, ...userArgs], { stdio: 'inherit', env: childEnv });
125
- } else {
126
- child = spawn('python3', [MAIN, ...userArgs], { stdio: 'inherit', env: childEnv });
127
- }
128
- console.log('[CodeBee] 正在启动(Python: ' + exe + ')… 浏览器将自动打开 http://127.0.0.1:8765;'
129
- + '本窗口保持开着就是服务,Ctrl+C 退出。');
130
-
131
- for (const sig of ['SIGINT', 'SIGTERM']) {
132
- process.on(sig, () => { try { child.kill(sig); } catch (e) { /* 已退出 */ } });
133
- }
134
- const t0 = Date.now();
135
- child.on('exit', (code, signal) => {
136
- if (!signal && code != null && code !== 0 && Date.now() - t0 < 4000) {
137
- // 秒退:多半是 py 启动器指到了坏解释器(如损坏的 Anaconda)。给排障出口。
138
- console.error('[CodeBee] 启动失败:Python 进程 ' + (code ? '退出码 ' + code : '异常终止') + '。'
139
- + '\n · 运行 python --version 确认可用且为 3.8+'
140
- + '\n · 若装有多个 Python,可设环境变量 TUTTI_PYTHON 切换(cmd:set TUTTI_PYTHON=python)');
141
- }
142
- process.exit(signal ? 1 : (code == null ? 0 : code));
143
- });
144
- child.on('error', (e) => {
145
- console.error('[CodeBee] 无法启动 Python:' + e.message);
146
- process.exit(1);
147
- });
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /*
4
+ * CodeBee 启动垫片:在本机找 Python 3.8+,以子进程方式运行包内 app/main.py。
5
+ * npm 只负责分发与版本管理,不携带解释器——所以运行时才探测 python,
6
+ * 找不到就报错并给出安装指引(不写 postinstall,避免在别人机器上制造环境事故)。
7
+ *
8
+ * 安全边界:
9
+ * - 子进程可执行文件全部是本文件内的字面量(py / python / python3)——包括
10
+ * TUTTI_PYTHON 覆盖时:它只允许在这三个字面量里选一个,绝不拼接任意路径;
11
+ * - 参数数组全由字面量常量拼成,不启用 shell;
12
+ * - 探测只传 `--version`(不向解释器传递任何代码);Windows 商店的 python.exe
13
+ * 假占位会非零退出,被 catch 后自然跳过;
14
+ * - 用户参数逐个过白名单校验(仅字母数字与 _ - . : = / @ % 空格),
15
+ * 含 shell 元字符/控制字符的参数直接拒绝。
16
+ */
17
+ const { execFileSync, spawn } = require('child_process');
18
+ const path = require('path');
19
+
20
+ const MIN_MAJOR = 3;
21
+ const MIN_MINOR = 8;
22
+ const MAIN = path.join(__dirname, '..', 'app', 'main.py');
23
+ const SAFE_ARG = /^[A-Za-z0-9_\-.:=/@% ]+$/;
24
+
25
+ // 解析 `--version` 输出:形如 "Python 3.12.4",返回 {ver, major, minor} 或 null。
26
+ // 纯字符串切分,不用正则匹配执行路径。
27
+ function parseVersion(text) {
28
+ const at = String(text).indexOf('Python ');
29
+ if (at === -1) return null;
30
+ const parts = String(text).slice(at + 7).trim().split(' ')[0].split('.');
31
+ const major = Number(parts[0]);
32
+ const minor = Number(parts[1]);
33
+ if (!Number.isFinite(major) || !Number.isFinite(minor)) return null;
34
+ return { ver: major + '.' + minor, major: major, minor: minor };
35
+ }
36
+
37
+ function probePy() {
38
+ try {
39
+ return parseVersion(execFileSync('py', ['-3', '--version'],
40
+ { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }));
41
+ } catch (e) { return null; }
42
+ }
43
+ function probePython() {
44
+ try {
45
+ return parseVersion(execFileSync('python', ['--version'],
46
+ { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }));
47
+ } catch (e) { return null; }
48
+ }
49
+ function probePython3() {
50
+ try {
51
+ return parseVersion(execFileSync('python3', ['--version'],
52
+ { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }));
53
+ } catch (e) { return null; }
54
+ }
55
+
56
+ // 探测顺序:win32 优先 py 启动器(跨版本选真 3.x),其余按 python3 → python。
57
+ function resolvePython() {
58
+ const order = process.platform === 'win32'
59
+ ? [['py', probePy], ['python', probePython], ['python3', probePython3]]
60
+ : [['python3', probePython3], ['python', probePython]];
61
+ for (const [name, probe] of order) {
62
+ const hit = probe();
63
+ if (!hit) continue;
64
+ if (hit.major > MIN_MAJOR || (hit.major === MIN_MAJOR && hit.minor >= MIN_MINOR)) {
65
+ return { name: name };
66
+ }
67
+ return { tooOld: true, name: name, ver: hit.ver };
68
+ }
69
+ return null;
70
+ }
71
+
72
+ function guide() {
73
+ const url = { win32: 'https://www.python.org/downloads/windows/',
74
+ darwin: 'https://www.python.org/downloads/macos/',
75
+ linux: 'https://docs.python.org/3/using/unix.html' }[process.platform]
76
+ || 'https://www.python.org/downloads/';
77
+ return 'CodeBee 需要本机安装 Python 3.8+(npm 包不含解释器)。\n'
78
+ + ' · 安装:' + url + '\n'
79
+ + ' · Windows 安装时勾选 “Add python.exe to PATH”(自带 py 启动器)\n'
80
+ + '装好后重新运行:codebee';
81
+ }
82
+
83
+ const py = resolvePython();
84
+ if (!py) {
85
+ console.error('[CodeBee] 未找到可用的 Python。\n' + guide());
86
+ process.exit(1);
87
+ }
88
+ if (py.tooOld) {
89
+ console.error('[CodeBee] 找到 ' + py.name + '(' + py.ver + '),但版本过低。\n' + guide());
90
+ process.exit(1);
91
+ }
92
+
93
+ const userArgs = [];
94
+ for (const a of process.argv.slice(2)) {
95
+ if (typeof a === 'string' && SAFE_ARG.test(a)) {
96
+ userArgs.push(a);
97
+ } else {
98
+ console.error('[CodeBee] 参数含非法字符,已拒绝:' + String(a).slice(0, 80));
99
+ process.exit(2);
100
+ }
101
+ }
102
+
103
+ // CLI 转发契约:codebee 之后的用户参数(已过白名单)原样作为 main.py 的 argv。
104
+ // 控制台日志即见:GBK 控制台下强制 UTF-8 输出(否则中文 print 触发 UnicodeEncodeError 静默卡死)。
105
+ const childEnv = Object.assign({}, process.env, { PYTHONIOENCODING: 'utf-8', PYTHONUTF8: '1', PYTHONUNBUFFERED: '1' });
106
+ // TUTTI_PYTHON 覆盖解释器:只允许在三个字面量里选(py/python/python3,.exe
107
+ // 后缀可选、大小写不限)——环境变量永远只做「选择题」,不做「填空题」;
108
+ // 机器上有多个解释器且探测选错时,用它切换。
109
+ let exe = py.name;
110
+ const ovRaw = String(process.env.TUTTI_PYTHON || '').trim().toLowerCase();
111
+ const ov = ovRaw.endsWith('.exe') ? ovRaw.slice(0, -4) : ovRaw;
112
+ if (ov === 'python') {
113
+ exe = 'python';
114
+ } else if (ov === 'python3') {
115
+ exe = 'python3';
116
+ } else if (ov === 'py') {
117
+ exe = 'py';
118
+ }
119
+
120
+ let child;
121
+ if (exe === 'py') {
122
+ child = spawn('py', ['-3', MAIN, ...userArgs], { stdio: 'inherit', env: childEnv });
123
+ } else if (exe === 'python') {
124
+ child = spawn('python', [MAIN, ...userArgs], { stdio: 'inherit', env: childEnv });
125
+ } else {
126
+ child = spawn('python3', [MAIN, ...userArgs], { stdio: 'inherit', env: childEnv });
127
+ }
128
+ console.log('[CodeBee] 正在启动(Python: ' + exe + ')… 浏览器将自动打开 http://127.0.0.1:8765;'
129
+ + '本窗口保持开着就是服务,Ctrl+C 退出。');
130
+
131
+ for (const sig of ['SIGINT', 'SIGTERM']) {
132
+ process.on(sig, () => { try { child.kill(sig); } catch (e) { /* 已退出 */ } });
133
+ }
134
+ const t0 = Date.now();
135
+ child.on('exit', (code, signal) => {
136
+ if (!signal && code != null && code !== 0 && Date.now() - t0 < 4000) {
137
+ // 秒退:多半是 py 启动器指到了坏解释器(如损坏的 Anaconda)。给排障出口。
138
+ console.error('[CodeBee] 启动失败:Python 进程 ' + (code ? '退出码 ' + code : '异常终止') + '。'
139
+ + '\n · 运行 python --version 确认可用且为 3.8+'
140
+ + '\n · 若装有多个 Python,可设环境变量 TUTTI_PYTHON 切换(cmd:set TUTTI_PYTHON=python)');
141
+ }
142
+ process.exit(signal ? 1 : (code == null ? 0 : code));
143
+ });
144
+ child.on('error', (e) => {
145
+ console.error('[CodeBee] 无法启动 Python:' + e.message);
146
+ process.exit(1);
147
+ });
package/package.json CHANGED
@@ -1,41 +1,41 @@
1
- {
2
- "name": "codebee",
3
- "version": "0.1.62",
4
- "description": "CodeBee · 多智能体编排台 — 统一编排本机 AI 编码 CLI(Codex / Claude Code / QwenCode / OpenCode / Aider…):目标→拆解→路由→执行→验证→跨厂商评审→修复→报告。纯 Python 标准库实现,本地 Web UI。",
5
- "license": "MIT",
6
- "bin": {
7
- "codebee": "bin/tutti.js"
8
- },
9
- "files": [
10
- "app",
11
- "bin",
12
- "tools/wx_reader.py",
13
- "CHANGELOG.md",
14
- "README.md",
15
- "LICENSE"
16
- ],
17
- "engines": {
18
- "node": ">=14"
19
- },
20
- "os": [
21
- "win32",
22
- "darwin",
23
- "linux"
24
- ],
25
- "keywords": [
26
- "agent",
27
- "orchestration",
28
- "codex",
29
- "claude",
30
- "llm",
31
- "cli",
32
- "multi-agent"
33
- ],
34
- "repository": {
35
- "type": "git",
36
- "url": "git+https://github.com/Vercel-By-WXP/CodeBee.git"
37
- },
38
- "publishConfig": {
39
- "access": "public"
40
- }
41
- }
1
+ {
2
+ "name": "codebee",
3
+ "version": "0.1.64",
4
+ "description": "CodeBee · 多智能体编排台 — 统一编排本机 AI 编码 CLI(Codex / Claude Code / QwenCode / OpenCode / Aider…):目标→拆解→路由→执行→验证→跨厂商评审→修复→报告。纯 Python 标准库实现,本地 Web UI。",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "codebee": "bin/tutti.js"
8
+ },
9
+ "files": [
10
+ "app",
11
+ "bin",
12
+ "tools/wx_reader.py",
13
+ "CHANGELOG.md",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "engines": {
18
+ "node": ">=14"
19
+ },
20
+ "os": [
21
+ "win32",
22
+ "darwin",
23
+ "linux"
24
+ ],
25
+ "keywords": [
26
+ "agent",
27
+ "orchestration",
28
+ "codex",
29
+ "claude",
30
+ "llm",
31
+ "cli",
32
+ "multi-agent"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/Vercel-By-WXP/CodeBee.git"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ }
41
+ }