codebee 0.1.90 → 0.1.92

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/CHANGELOG.md CHANGED
@@ -6,6 +6,17 @@ README 元数据带回,供老版本在「发现新版本」时展示新版更
6
6
 
7
7
  ## 未发布
8
8
 
9
+ ## v0.1.92(2026-10-07)
10
+
11
+ - **英文界面属性级 i18n 修复**:浏览器工具栏/侧栏导航/验收标准字段共 16 处元素此前在英文界面悬停提示与读屏标签中文裸奔,补齐 data-i18n-title/-aria/-ph 钩子 + 13 条英文词条,恢复英文显示(中文界面零变化)。
12
+ - **i18n 回归契约上闸**:新增「中文属性必有同值钩子+词条」全量对账测试与修复面点名锁定;JS 侧 t() 字面量对账补单引号形态盲区,并修复对账正则因钩子键名含数字导致的 241 处假阳性。
13
+
14
+ ## v0.1.91(2026-10-07)
15
+
16
+ - **质量护栏收口**:经验库蒸馏写入路径回归守卫 +4 用例(闭集落类/首写不分裂/复查合并 seen+1 不分裂/空输入拒写);全量 266 个测试模块逐模块净进程全绿核验(单进程 discover 在 32 位环境的中途崩退为在案已知风险,逐模块净进程为可执行全量形态)。
17
+ - **调研沉淀**:批2 学习记忆/自我改进域竞品雷达收口(115 查询 467 仓),keywords 补 2 个域专属 awesome 源;knowledge-work-plugins(26.5k★ 官方知识工作者插件仓)深挖完成,「域→技能族」对标口径蒸馏入经验库,整仓不接入(三问不过)。
18
+ - 应用代码与 v0.1.90 相同,无行为变更(本轮为测试与调研沉淀件)。
19
+
9
20
  ## v0.1.90(2026-10-07)
10
21
 
11
22
  - **英文界面 54 处文案补全**:首次建立 app.js 全量 `t()` 字面量↔词条对账(1,726 唯一键实测),补齐 54 键缺失词条——英文界面 toast/状态/弹窗标题/表单标签不再中文裸奔(加载失败/插件安装/重试任务等)。
package/README.md CHANGED
@@ -33,10 +33,10 @@ Trae Agent、OpenClaw……),提供
33
33
  ---
34
34
 
35
35
  <!-- relnotes:start -->
36
- ### 最新版更新内容(v0.1.90)
36
+ ### 最新版更新内容(v0.1.92)
37
37
 
38
- - 英文界面 54 处文案补全:全量 t() 字面量对账首次建立,英文界面不再中文裸奔
39
- - 新增对账测试契约锁定:加文案漏词条先红
38
+ - 英文界面属性级 i18n 修复:浏览器工具栏/侧栏导航/验收标准字段共 16 处悬停与读屏恢复英文,中文界面零变化
39
+ - i18n 回归契约上闸:「中文属性必有钩子+词条」全量对账测试,防部分回退
40
40
  <!-- relnotes:end -->
41
41
 
42
42
 
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- """错误台账:把分散在各处的失败(步骤失败/超时/看门狗击杀、CLI 启动失败)
2
+ """错误台账:把分散在各处的失败(步骤失败/运行收口/超时/看门狗击杀、CLI 启动失败)
3
3
  统一落成结构化记录——「客户遇到了问题我们根本不知道」的第一块拼图。
4
4
 
5
5
  落盘:data/errors/errors-YYYYMM.jsonl(按月分文件,append-only,一行一记录)。
@@ -304,7 +304,12 @@ def block_for(task):
304
304
  entries.sort(key=lambda x: x.get("id") or "")
305
305
  entries = entries[:KNOWLEDGE_MAX_INJECT]
306
306
 
307
- lines, used = [], []
307
+ # 整条装箱(对照 skills.py 包区纪律):当前条完整放得下才收入,放不下
308
+ # 即停——拦腰截出的半条知识是模型噪音;被预算丢弃的条目不记 hits,
309
+ # 否则「从未被读到」的内容反而升权、继续挤占预算(反馈回路缺陷)。
310
+ header = "## 知识库(已确认的领域知识,供参考)\n\n"
311
+ lines, used, skipped = [], [], 0
312
+ total = len(header)
308
313
  for x in entries:
309
314
  stale = _is_stale(x.get("as_of"))
310
315
  mark = ("(事实截至 %s,可能过期,请自行核实时效)" % x.get("as_of") if stale
@@ -314,11 +319,36 @@ def block_for(task):
314
319
  conf = str(x.get("confidence") or "medium").strip().lower()
315
320
  if conf == "high":
316
321
  mark += "[有据]"
317
- lines.append("- **%s**%s:%s" % (x["title"], mark, x["body"]))
322
+ line = "- **%s**%s:%s" % (x["title"], mark, x["body"])
323
+ separator = 1 if lines else 0
324
+ if total + separator + len(line) > KNOWLEDGE_BUDGET:
325
+ skipped = len(entries) - len(used)
326
+ break
327
+ lines.append(line)
318
328
  used.append(x["id"])
319
- text = "## 知识库(已确认的领域知识,供参考)\n\n" + "\n".join(lines)
320
- if len(text) > KNOWLEDGE_BUDGET:
321
- text = text[:KNOWLEDGE_BUDGET] + "\n…(已截断)"
329
+ total += separator + len(line)
330
+ text = header + "\n".join(lines)
331
+ if skipped:
332
+ # 预算也包含诊断尾注;若尾注放不下,继续整条回退已选条目,绝不
333
+ # 让“提示词未超预算”被尾注本身打破。极小预算连尾注都放不下时,
334
+ # 保留标题(或返回空串)比输出超预算文本更安全。
335
+ while lines:
336
+ note = "\n…(%d 条超出预算未注入)" % skipped
337
+ if len(text) + len(note) <= KNOWLEDGE_BUDGET:
338
+ break
339
+ lines.pop()
340
+ used.pop()
341
+ skipped = len(entries) - len(used)
342
+ text = header + "\n".join(lines)
343
+ note = "\n…(%d 条超出预算未注入)" % skipped
344
+ if len(text) + len(note) <= KNOWLEDGE_BUDGET:
345
+ text += note
346
+ elif len(header) <= KNOWLEDGE_BUDGET:
347
+ text = header
348
+ used = []
349
+ else:
350
+ text = ""
351
+ used = []
322
352
  if used:
323
353
  _bump_hits(used)
324
354
  return text
package/app/core/store.py CHANGED
@@ -673,6 +673,7 @@ def _sanitize_run_text(r):
673
673
 
674
674
 
675
675
  def load_all():
676
+ recovered_failures = []
676
677
  with LOCK:
677
678
  for p in paths.TASKS_DIR.glob("*.json"):
678
679
  try:
@@ -698,6 +699,9 @@ def load_all():
698
699
  r["status"] = "failed"
699
700
  r["error"] = r.get("error") or "服务重启中断,可重试"
700
701
  _save_json(p, r)
702
+ # 读盘收尸绕过 update_run,需在释放存储锁后补一条 run
703
+ # 级错误记录;避免错误台账的文件 I/O 拉长全局锁。
704
+ recovered_failures.append(dict(r))
701
705
  _RUNS[r["id"]] = r
702
706
  except Exception:
703
707
  pass
@@ -716,6 +720,8 @@ def load_all():
716
720
  if latest.get("status") in ("done", "failed", "cancelled", "timeout"):
717
721
  t["status"] = latest["status"]
718
722
  _save_json(paths.TASKS_DIR / (t["id"] + ".json"), t)
723
+ for run in recovered_failures:
724
+ _record_run_failure(run)
719
725
 
720
726
 
721
727
  # ---------------------------------------------------------------- 运行(含管理操作)
@@ -834,6 +840,57 @@ def _execution_snapshot(task):
834
840
  TERMINAL_STATUSES = ("done", "failed", "cancelled", "timeout")
835
841
 
836
842
 
843
+ def _record_run_failure(run):
844
+ """把 run 级失败写入错误台账,避免启动/调度异常只留在 run.json。
845
+
846
+ 步骤失败已经由 pipeline 记录;这里只覆盖 run 的收口失败(例如
847
+ enqueue/线程启动失败、服务重启恢复和超时),并由调用方保证同一 run
848
+ 只在首次进入终态时调用。只写稳定原因和安全摘要,不把原始错误或任务
849
+ 正文复制进遥测台账。
850
+ """
851
+ try:
852
+ from . import errorlog
853
+ from .error_codes import ErrorCode, classify_error_text, error_code_value, safe_error_summary
854
+
855
+ status = str(run.get("status") or "failed")
856
+ raw_code = run.get("error_code")
857
+ if not raw_code:
858
+ failed_steps = [s for s in (run.get("steps") or [])
859
+ if isinstance(s, dict) and s.get("status") in ("failed", "timeout")]
860
+ if failed_steps:
861
+ raw_code = failed_steps[-1].get("error_code")
862
+ if not raw_code:
863
+ raw_code = classify_error_text(run.get("error") or "")
864
+
865
+ try:
866
+ code = ErrorCode(raw_code) if raw_code else None
867
+ except (TypeError, ValueError):
868
+ code = None
869
+ if code is not None:
870
+ reason = error_code_value(code)
871
+ detail = safe_error_summary(code)
872
+ elif status == "timeout":
873
+ reason, detail = "TIMEOUT", "调用超时"
874
+ else:
875
+ reason, detail = "RUN_FAILED", "运行失败"
876
+
877
+ step = next((s for s in reversed(run.get("steps") or [])
878
+ if isinstance(s, dict) and s.get("status") in ("failed", "timeout")), {})
879
+ provider = step.get("provider") or run.get("provider") or ""
880
+ if isinstance(provider, dict):
881
+ provider = provider.get("id") or provider.get("name") or ""
882
+ errorlog.record(
883
+ category="run", reason=reason, detail=detail,
884
+ provider=provider, model=step.get("model") or run.get("model") or "",
885
+ tool=step.get("agent") or run.get("tool") or "",
886
+ role=step.get("role") or "", run_id=run.get("id") or "",
887
+ task_id=run.get("task_id") or "", step=step.get("n") or 0,
888
+ exit_code=step.get("exit_code"))
889
+ except Exception:
890
+ # 诊断台账是旁路能力,绝不能阻塞状态收口。
891
+ pass
892
+
893
+
837
894
  def create_run(kind, title, task_id=None, entry_id=None, op=None):
838
895
  run = {
839
896
  "id": _new_id("r" if kind == "orchestration" else "m"),
@@ -1058,6 +1115,7 @@ def update_run(run_id, expected_status=None, **fields):
1058
1115
  防止陈旧执行方(被取消的 worker、崩溃恢复前的旧线程)覆盖新状态
1059
1116
  ——防御模式「异步状态不是同步状态」。不传则保持原行为。"""
1060
1117
  audit = None
1118
+ failure_audit = None
1061
1119
  with LOCK:
1062
1120
  run = _RUNS.get(run_id)
1063
1121
  if not run:
@@ -1126,6 +1184,8 @@ def update_run(run_id, expected_status=None, **fields):
1126
1184
  # (UI 补写、迟到写手)不得二次入账。快照在锁内浅拷,锁外调用
1127
1185
  # 审计器——审计器会回读 store,锁内调用即自锁。
1128
1186
  audit = dict(run)
1187
+ if st in ("failed", "timeout"):
1188
+ failure_audit = dict(run)
1129
1189
  if st in ("done", "failed", "cancelled", "timeout"):
1130
1190
  # run_end 钩子(2026-09-22):终态即触发,后台跑副作用型脚本
1131
1191
  # (回写知识库等);失败/超时静默,绝不拖慢收尾路径
@@ -1144,6 +1204,8 @@ def update_run(run_id, expected_status=None, **fields):
1144
1204
  # 「在跑」直到下一次无关 bump(2026-09-22 侧栏假在跑案)。
1145
1205
  # 调用都是步骤级边界,不会形成推送风暴;CAS 拒绝/无此 run 的早退
1146
1206
  # 路径不动版本号。
1207
+ if failure_audit is not None:
1208
+ _record_run_failure(failure_audit)
1147
1209
  if audit is not None and _RUN_AUDITOR is not None:
1148
1210
  try:
1149
1211
  _RUN_AUDITOR(audit)
package/app/ui/i18n.js CHANGED
@@ -3049,6 +3049,21 @@
3049
3049
  "P95 ": "P95 ",
3050
3050
  "复制失败,请手动长按/右键复制": "Copy failed — long-press / right-click to copy manually",
3051
3051
  "✓ 远程端点连通,可上传": "✓ Remote endpoint reachable, ready to upload",
3052
+ // 2026-10-07 落地班:属性级 i18n 缺口补齐——浏览器工具栏/侧栏导航/验收标准字段
3053
+ // 的 title·aria-label·placeholder 挂了中文却缺翻译钩子(英文界面悬停/读屏中文裸奔)
3054
+ "主导航": "Main navigation",
3055
+ "切换工作区": "Switch workspace",
3056
+ "工作区": "Workspace",
3057
+ "验收标准(每行一条)": "Acceptance criteria (one per line)",
3058
+ "例如:测试全部通过\n例如:产出文件存在": "e.g. all tests pass\ne.g. output file exists",
3059
+ "浏览器标签页": "Browser tabs",
3060
+ "新建标签页": "New tab",
3061
+ "后退": "Back",
3062
+ "前进": "Forward",
3063
+ "主页": "Home",
3064
+ "网址": "Address",
3065
+ "在系统浏览器打开": "Open in system browser",
3066
+ "CodeBee 浏览器": "CodeBee Browser",
3052
3067
  };
3053
3068
 
3054
3069
  // ---------- 工具 ----------
package/app/ui/index.html CHANGED
@@ -108,7 +108,7 @@
108
108
  <div id="app">
109
109
 
110
110
  <!-- Codex 式一级导航:保留原有侧栏功能,增加一条可快速切换主视图的窄轨道。 -->
111
- <nav class="side-rail" aria-label="主导航">
111
+ <nav class="side-rail" aria-label="主导航" data-i18n-aria="主导航">
112
112
  <button type="button" class="rail-btn active" data-rail-page="tasks" title="任务" aria-label="任务" data-i18n-title="任务" data-i18n-aria="任务" onclick="exitSettings()">
113
113
  <svg class="ico" aria-hidden="true"><use href="#i-gauge"></use></svg>
114
114
  </button>
@@ -122,7 +122,7 @@
122
122
  <svg class="ico" aria-hidden="true"><use href="#i-browser"></use></svg>
123
123
  </button>
124
124
  <span class="rail-spacer"></span>
125
- <button type="button" class="rail-btn" title="设置" aria-label="设置" onclick="document.getElementById('btn-settings').click()">
125
+ <button type="button" class="rail-btn" title="设置" aria-label="设置" data-i18n-title="设置" data-i18n-aria="设置" onclick="document.getElementById('btn-settings').click()">
126
126
  <svg class="ico" aria-hidden="true"><use href="#i-gear"></use></svg>
127
127
  </button>
128
128
  </nav>
@@ -132,7 +132,7 @@
132
132
  <!-- 常规视图:任务树 -->
133
133
  <div class="side-main">
134
134
  <div class="brand-row">
135
- <button id="btn-brand" class="brand" type="button" title="切换工作区" aria-label="切换工作区" aria-haspopup="menu" aria-expanded="false" onclick="toggleBrandMenu()">
135
+ <button id="btn-brand" class="brand" type="button" title="切换工作区" aria-label="切换工作区" data-i18n-title="切换工作区" data-i18n-aria="切换工作区" aria-haspopup="menu" aria-expanded="false" onclick="toggleBrandMenu()">
136
136
  <span class="brand-name">CodeBee</span>
137
137
  <svg class="ico brand-caret" aria-hidden="true"><use href="#i-chevron-r"></use></svg>
138
138
  </button>
@@ -140,13 +140,13 @@
140
140
  data-i18n-title="完成/待裁决提示音" data-i18n-aria="完成/待裁决提示音">
141
141
  <svg class="ico" aria-hidden="true"><use href="#i-bell"></use></svg>
142
142
  </button>
143
- <button class="brand-tool side-search" id="btn-cmdk" title="搜索" aria-label="搜索" data-i18n-title="搜索">
143
+ <button class="brand-tool side-search" id="btn-cmdk" title="搜索" aria-label="搜索" data-i18n-title="搜索" data-i18n-aria="搜索">
144
144
  <svg class="ico" aria-hidden="true"><use href="#i-search"></use></svg>
145
145
  <span class="ss-label" data-i18n="搜索">搜索</span>
146
146
  <span class="kbd" aria-hidden="true">Ctrl K</span>
147
147
  </button>
148
148
  </div>
149
- <div id="brand-menu" class="brand-menu hidden" role="menu" aria-label="工作区">
149
+ <div id="brand-menu" class="brand-menu hidden" role="menu" aria-label="工作区" data-i18n-aria="工作区">
150
150
  <div class="brand-menu-item selected" role="menuitem">
151
151
  <span><b>CodeBee</b><small>多智能体编排台</small></span>
152
152
  <svg class="ico" aria-hidden="true"><use href="#i-check"></use></svg>
@@ -487,7 +487,7 @@
487
487
  </div>
488
488
  <div class="field"><label data-i18n="上下文">上下文</label><textarea id="f-context" rows="2" placeholder="背景信息、约束、相关文件(可空)" data-i18n-ph="背景信息、约束、相关文件(可空)"></textarea></div>
489
489
  <div class="grid-2">
490
- <div class="field"><label>验收标准(每行一条)</label><textarea id="f-acceptance" rows="3" placeholder="例如:测试全部通过&#10;例如:产出文件存在"></textarea></div>
490
+ <div class="field"><label data-i18n="验收标准(每行一条)">验收标准(每行一条)</label><textarea id="f-acceptance" rows="3" placeholder="例如:测试全部通过&#10;例如:产出文件存在" data-i18n-ph="例如:测试全部通过&#10;例如:产出文件存在"></textarea></div>
491
491
  <div class="field"><label class="checkline"><input id="f-approval-required" type="checkbox"> 完成前需要人工审批</label><p class="hint">启用后,Git 合并和发布会等待审批记录。</p></div>
492
492
  </div>
493
493
 
@@ -1363,25 +1363,25 @@
1363
1363
  <div id="sub-browser" class="subpage hidden">
1364
1364
  <div class="browser-shell">
1365
1365
  <div class="browser-head">
1366
- <div class="browser-tabs" id="browser-tabs" role="tablist" aria-label="浏览器标签页">
1366
+ <div class="browser-tabs" id="browser-tabs" role="tablist" aria-label="浏览器标签页" data-i18n-aria="浏览器标签页">
1367
1367
  <button class="browser-tab active" type="button" data-browser-tab="home" role="tab" aria-selected="true">
1368
1368
  <svg class="ico" aria-hidden="true"><use href="#i-browser"></use></svg><span>CodeBee 浏览器</span>
1369
1369
  </button>
1370
- <button class="browser-tab-add" id="browser-new-tab" type="button" title="新建标签页" aria-label="新建标签页"><svg class="ico" aria-hidden="true"><use href="#i-plus"></use></svg></button>
1370
+ <button class="browser-tab-add" id="browser-new-tab" type="button" title="新建标签页" aria-label="新建标签页" data-i18n-title="新建标签页" data-i18n-aria="新建标签页"><svg class="ico" aria-hidden="true"><use href="#i-plus"></use></svg></button>
1371
1371
  </div>
1372
1372
  <div class="browser-status"><span class="browser-status-dot"></span><span data-i18n="本地浏览器工作区">本地浏览器工作区</span></div>
1373
1373
  </div>
1374
1374
  <div class="browser-toolbar">
1375
- <button class="icon-btn" id="browser-back" type="button" title="后退" aria-label="后退"><svg class="ico" aria-hidden="true"><use href="#i-arrow-left"></use></svg></button>
1376
- <button class="icon-btn" id="browser-forward" type="button" title="前进" aria-label="前进"><svg class="ico" aria-hidden="true"><use href="#i-arrow-right"></use></svg></button>
1377
- <button class="icon-btn" id="browser-reload" type="button" title="刷新" aria-label="刷新"><svg class="ico" aria-hidden="true"><use href="#i-refresh"></use></svg></button>
1378
- <button class="icon-btn" id="browser-home" type="button" title="主页" aria-label="主页"><svg class="ico" aria-hidden="true"><use href="#i-home"></use></svg></button>
1375
+ <button class="icon-btn" id="browser-back" type="button" title="后退" aria-label="后退" data-i18n-title="后退" data-i18n-aria="后退"><svg class="ico" aria-hidden="true"><use href="#i-arrow-left"></use></svg></button>
1376
+ <button class="icon-btn" id="browser-forward" type="button" title="前进" aria-label="前进" data-i18n-title="前进" data-i18n-aria="前进"><svg class="ico" aria-hidden="true"><use href="#i-arrow-right"></use></svg></button>
1377
+ <button class="icon-btn" id="browser-reload" type="button" title="刷新" aria-label="刷新" data-i18n-title="刷新" data-i18n-aria="刷新"><svg class="ico" aria-hidden="true"><use href="#i-refresh"></use></svg></button>
1378
+ <button class="icon-btn" id="browser-home" type="button" title="主页" aria-label="主页" data-i18n-title="主页" data-i18n-aria="主页"><svg class="ico" aria-hidden="true"><use href="#i-home"></use></svg></button>
1379
1379
  <form id="browser-nav-form" class="browser-address-wrap">
1380
1380
  <svg class="ico browser-lock" aria-hidden="true"><use href="#i-lock"></use></svg>
1381
- <input id="browser-address" type="text" autocomplete="off" spellcheck="false" placeholder="输入网址或搜索内容" data-i18n-ph="输入网址或搜索内容" aria-label="网址">
1382
- <button class="browser-go" type="submit" title="打开" aria-label="打开"><svg class="ico" aria-hidden="true"><use href="#i-arrow-right"></use></svg></button>
1381
+ <input id="browser-address" type="text" autocomplete="off" spellcheck="false" placeholder="输入网址或搜索内容" data-i18n-ph="输入网址或搜索内容" aria-label="网址" data-i18n-aria="网址">
1382
+ <button class="browser-go" type="submit" title="打开" aria-label="打开" data-i18n-title="打开" data-i18n-aria="打开"><svg class="ico" aria-hidden="true"><use href="#i-arrow-right"></use></svg></button>
1383
1383
  </form>
1384
- <button class="ghost small browser-external" id="browser-open-external" type="button" title="在系统浏览器打开"><svg class="ico" aria-hidden="true"><use href="#i-external"></use></svg><span data-i18n="系统浏览器">系统浏览器</span></button>
1384
+ <button class="ghost small browser-external" id="browser-open-external" type="button" title="在系统浏览器打开" data-i18n-title="在系统浏览器打开"><svg class="ico" aria-hidden="true"><use href="#i-external"></use></svg><span data-i18n="系统浏览器">系统浏览器</span></button>
1385
1385
  </div>
1386
1386
  <div class="browser-shortcuts" id="browser-shortcuts">
1387
1387
  <button type="button" class="browser-shortcut" data-browser-url="https://www.google.com"><span class="shortcut-mark google">G</span><span>Google</span></button>
@@ -1466,7 +1466,7 @@
1466
1466
  <p id="browser-frame-error-text" data-i18n="Google 等网站会拦截 iframe 或自动化挑战;页面本身未必不可访问。">Google 等网站会拦截 iframe 或自动化挑战;页面本身未必不可访问。</p>
1467
1467
  <button class="primary small" id="browser-frame-error-open" type="button"><svg class="ico" aria-hidden="true"><use href="#i-external"></use></svg><span data-i18n="用系统浏览器继续">用系统浏览器继续</span></button>
1468
1468
  </div>
1469
- <iframe id="browser-frame" class="browser-frame hidden" title="CodeBee 浏览器" sandbox="allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-downloads" referrerpolicy="no-referrer"></iframe>
1469
+ <iframe id="browser-frame" class="browser-frame hidden" title="CodeBee 浏览器" data-i18n-title="CodeBee 浏览器" sandbox="allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-downloads" referrerpolicy="no-referrer"></iframe>
1470
1470
  </div>
1471
1471
  </div>
1472
1472
  <div class="browser-foot"><span id="browser-hint" data-i18n="外部网站可能禁止嵌入;可用右上角系统浏览器打开。">外部网站可能禁止嵌入;可用右上角系统浏览器打开。</span><span class="spacer"></span><span id="browser-history-count"></span></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebee",
3
- "version": "0.1.90",
3
+ "version": "0.1.92",
4
4
  "description": "CodeBee · 多智能体编排台 — 统一编排本机 AI 编码 CLI(Codex / Claude Code / QwenCode / OpenCode / Aider…):目标→拆解→路由→执行→验证→跨厂商评审→修复→报告。纯 Python 标准库实现,本地 Web UI。",
5
5
  "license": "MIT",
6
6
  "bin": {