codebee 0.1.103 → 0.1.105

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 (128) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -21
  3. package/README.md +5 -3
  4. package/app/core/acceptance.py +100 -100
  5. package/app/core/acp_client.py +457 -457
  6. package/app/core/aiflavor.py +197 -197
  7. package/app/core/analytics.py +38 -38
  8. package/app/core/artifacts.py +148 -148
  9. package/app/core/assets.py +110 -110
  10. package/app/core/attachments.py +623 -623
  11. package/app/core/audit.py +30 -30
  12. package/app/core/backend_profiles.py +188 -188
  13. package/app/core/backup.py +470 -470
  14. package/app/core/beekeeper.py +183 -183
  15. package/app/core/benchstore.py +102 -102
  16. package/app/core/bookmeta.py +1036 -1036
  17. package/app/core/bookmeta_catalog.py +180 -180
  18. package/app/core/branching.py +137 -137
  19. package/app/core/capability.py +144 -144
  20. package/app/core/chaptersafe.py +32 -32
  21. package/app/core/checkpoints.py +48 -5
  22. package/app/core/cleanup.py +303 -303
  23. package/app/core/command_auth.py +302 -302
  24. package/app/core/compaction.py +201 -201
  25. package/app/core/contracts.py +255 -255
  26. package/app/core/covergen.py +356 -356
  27. package/app/core/defectretro.py +43 -43
  28. package/app/core/diagnostics.py +114 -114
  29. package/app/core/dispatch_log.py +128 -128
  30. package/app/core/env_scrub.py +85 -85
  31. package/app/core/errorlog.py +137 -137
  32. package/app/core/eval_matrix.py +91 -91
  33. package/app/core/evaluation.py +174 -174
  34. package/app/core/failure_notify.py +290 -290
  35. package/app/core/flow_graph.py +33 -33
  36. package/app/core/goal_service.py +167 -167
  37. package/app/core/health.py +389 -389
  38. package/app/core/history.py +38 -38
  39. package/app/core/hooks.py +162 -162
  40. package/app/core/knowledge_pipeline.py +86 -86
  41. package/app/core/manager.py +2386 -2385
  42. package/app/core/mocks.py +64 -64
  43. package/app/core/notify.py +201 -201
  44. package/app/core/novel_quality.py +285 -181
  45. package/app/core/openapi.py +246 -217
  46. package/app/core/operations.py +228 -228
  47. package/app/core/paihang.py +145 -145
  48. package/app/core/pipeline.py +81 -11
  49. package/app/core/planner.py +7 -0
  50. package/app/core/portguard.py +111 -111
  51. package/app/core/presence.py +77 -77
  52. package/app/core/preview.py +293 -293
  53. package/app/core/project_memory.py +252 -206
  54. package/app/core/prompt_guard.py +78 -78
  55. package/app/core/publish/__init__.py +7 -7
  56. package/app/core/publish/auto.py +659 -659
  57. package/app/core/publish/chaprows.py +138 -138
  58. package/app/core/publish/flows-fanqie-calibrated.json +442 -442
  59. package/app/core/publish/manager.py +1185 -1185
  60. package/app/core/publish/qimao.py +193 -193
  61. package/app/core/publish/volumes.py +108 -108
  62. package/app/core/publish/ws.py +139 -139
  63. package/app/core/quality_gate.py +201 -201
  64. package/app/core/redact.py +38 -38
  65. package/app/core/registry.py +35 -0
  66. package/app/core/repeat_guard.py +129 -129
  67. package/app/core/retrieval.py +137 -137
  68. package/app/core/review_requests.py +119 -0
  69. package/app/core/runner.py +5 -1
  70. package/app/core/sandbox_runtime.py +95 -95
  71. package/app/core/selfupdate.py +384 -384
  72. package/app/core/session_log.py +161 -161
  73. package/app/core/sessions.py +312 -312
  74. package/app/core/settings.py +215 -215
  75. package/app/core/settings_schema.py +282 -282
  76. package/app/core/share_page.py +114 -114
  77. package/app/core/skill_scan.py +139 -139
  78. package/app/core/skillpacks/market/character-bible.md +66 -66
  79. package/app/core/skillpacks/market/code-risk-checklist.md +58 -58
  80. package/app/core/skillpacks/market/git-workflow.md +57 -57
  81. package/app/core/skillpacks/market/release-notes.md +72 -72
  82. package/app/core/skillpacks/market/weekly-report.md +71 -71
  83. package/app/core/skillpacks/market/worldview-consistency.md +70 -70
  84. package/app/core/step_runner.py +132 -132
  85. package/app/core/story_tracking.py +275 -275
  86. package/app/core/task_compile.py +199 -199
  87. package/app/core/telemetry.py +292 -292
  88. package/app/core/tlsctx.py +64 -64
  89. package/app/core/token_meter.py +147 -147
  90. package/app/core/tool_outputs.py +107 -107
  91. package/app/core/tracing.py +207 -207
  92. package/app/core/upstream.py +41 -41
  93. package/app/core/usage.py +1038 -1038
  94. package/app/core/volumes.py +389 -389
  95. package/app/core/webhooks.py +89 -89
  96. package/app/core/wxdigest.py +865 -865
  97. package/app/core/zentao.py +2692 -2692
  98. package/app/main.py +43 -0
  99. package/app/mcp_server.py +244 -244
  100. package/app/pick_dialog.py +110 -110
  101. package/app/ui/app.js +21 -2
  102. package/app/ui/artdiff.js +74 -74
  103. package/app/ui/hive3d.js +54 -31
  104. package/app/ui/i18n.js +32 -1
  105. package/app/ui/icons/bee.svg +79 -79
  106. package/app/ui/index.html +1 -0
  107. package/app/ui/manifest.json +16 -16
  108. package/app/ui/qrcode.js +2297 -2297
  109. package/bin/tutti.js +147 -147
  110. package/package.json +1 -1
  111. package/tools/wx_reader.py +261 -261
  112. package/app/.playwright-cli/console-2026-09-23T08-26-03-635Z.log +0 -88
  113. package/app/.playwright-cli/page-2026-09-23T08-26-03-845Z.yml +0 -126
  114. package/app/.playwright-cli/page-2026-09-23T08-29-44-203Z.png +0 -0
  115. package/app/.playwright-cli/page-2026-09-23T08-35-42-046Z.yml +0 -210
  116. package/app/.playwright-cli/page-2026-09-23T08-36-52-858Z.png +0 -0
  117. package/app/.playwright-cli/page-2026-09-23T08-37-33-938Z.png +0 -0
  118. package/app/.playwright-cli/run-detail-after.png +0 -0
  119. package/app/output/_createbook_body.json +0 -1
  120. package/app/output/_probe_fq_click.py +0 -50
  121. package/app/output/_probe_fq_form.py +0 -42
  122. package/app/output/_probe_fq_modal.py +0 -55
  123. package/app/output/_probe_fq_points.py +0 -71
  124. package/app/output/_probe_fq_submit.py +0 -34
  125. package/app/output/_probe_fq_watch.py +0 -62
  126. package/app/output/workbench-clean-preview.jpg +0 -0
  127. package/app/output/workbench-reference-render.png +0 -0
  128. package/app/output/workbench-shell.png +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ CodeBee 的用户可感知变更记录。发布新版时:最上面加一节,
4
4
  `<!-- relnotes:start -->…<!-- relnotes:end -->` 段(那段会被 `npm view` 的
5
5
  README 元数据带回,供老版本在「发现新版本」时展示新版更新内容)。
6
6
 
7
+ ## v0.1.105(2026-10-12)
8
+
9
+ - **claude CLI 输出上限 16000→32000**:全局评审读 40 万字级书稿(约 28 万 token 输入)时按旧值反复续烧 23 分钟后报「response exceeded the 16000 output token maximum」三连挂(实案:单次 $3 零产出);32000=claude CLI 官方默认档,`setdefault` 语义保留——用户显式配置不覆盖
10
+ - **治理契约:外部人工评审请求通道**:新增 append-only 评审请求台账(requested→assigned→approved/changes_requested/dismissed/expired 幂等流转)与 `/api/reviews`、`/api/reviews/<id>/transition` 路由,外部智能体可按契约提交待人工评审的产物;配套 `/api/capabilities` 能力清单与 `/api/tasks/<id>/memory/preview` 任务记忆注入预览接口
11
+ - **项目记忆注入预算封顶 20000**:注入预算配置值超过 20000 时按 20000 收敛,防止过大预算挤占提示词(含回归测试锁定)
12
+ - **蜂巢 3D 蜜蜂翅膀精修**:翅膀更纤薄透明、减淡青雾、脉络几何强化,助手蜂手臂/键盘手部姿态与腕端高光对齐,视觉契约测试全程护航(约 40 笔打磨)
13
+ - 英文界面补齐「会话续跑」能力标签词条
14
+
15
+ ## v0.1.104(2026-10-11)
16
+
17
+ - **连载「一直重写不达标」根因防线(马甲指纹三道防线)**:「落笔入册」「整段连排」类跨章复用此前只能靠评审判死,而重写用的是同一作者模型、长出来的还是同族指纹——循环烧钱永不达标。现把防线前移到生成侧:①**章稿落盘确定性查重闸**:整段(≥40 字)/整句(≥12 字)/完整对白(≥6 字)逐字重复检测,阈值按真实事故章校准,白描短句复沓不误伤;带重复的章稿直接打回,同作者重试与换将的提示词自动追加消重指令(同提示重跑只会长出同族事故);②**起草负样例注入**:近 4 章实际开笔/收束摘录随提示词下发(`__REUSE_GUARD__`),跨章句式同款从评审判据前移成起草约束;③**大纲轮换纪律**:开笔方式与收束形态批内硬性轮换。查重证据自动进评审面可见。生效范围:发版后的新批连载
18
+
7
19
  ## v0.1.103(2026-10-11)
8
20
 
9
21
  - **设置页「模型评测」子页顶栏标题修复**:标题表漏 `evalbench` 键,点入「模型评测」子页后顶栏回退显示「设置」;现正确显示「模型评测」(英文界面 Model Bench),并补静态断言回归防回流
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 scwuxinping
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 scwuxinping
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -25,10 +25,12 @@ Trae Agent、OpenClaw……),提供
25
25
  ---
26
26
 
27
27
  <!-- relnotes:start -->
28
- ### 最新版更新内容(v0.1.103)
28
+ ### 最新版更新内容(v0.1.105)
29
29
 
30
- - 设置页「模型评测」子页顶栏标题修复:点入不再回退显示「设置」,英文界面正确显示 Model Bench
31
- - 文案巡检勘误与死项清理:扫榜四平台口径、缺陷复盘类型标注等全部对齐实际行为,零逻辑改动
30
+ - 修复 40 万字级书稿全局评审被 claude 输出上限 16000 顶爆三连挂:上限提到 32000(用户显式配置不覆盖)
31
+ - 新增治理契约:外部人工评审请求通道(append-only 台账+幂等流转)+ 能力清单/记忆注入预览接口
32
+ - 蜂巢 3D 蜜蜂翅膀精修:更纤薄透明、脉络清晰、手部姿态自然
33
+ - 项目记忆注入预算封顶 20000 防挤占
32
34
  <!-- relnotes:end -->
33
35
 
34
36
 
@@ -1,100 +1,100 @@
1
- # -*- coding: utf-8 -*-
2
- """Run acceptance matrix and evidence normalization.
3
-
4
- The matrix keeps correctness, performance, boundary behavior, exception
5
- handling, readability and security as separate conclusions. Missing evidence
6
- is reported as ``not_evaluated``/``unknown`` rather than being inferred from a
7
- successful process exit.
8
- """
9
- from __future__ import annotations
10
-
11
- import time
12
-
13
- CASES = ("correctness", "performance", "boundary", "exception",
14
- "readability", "security")
15
-
16
-
17
- def _case(name, status, evidence=None, reason=""):
18
- return {"case": name, "status": status,
19
- "evidence": [evidence] if isinstance(evidence, dict) else [],
20
- "reason": str(reason or "")[:300]}
21
-
22
-
23
- def _quality_verdict(run):
24
- verdict = run.get("verdict") or {}
25
- for key in ("pass", "publishable", "verify_pass"):
26
- if isinstance(verdict.get(key), bool):
27
- return verdict.get(key), key
28
- return None, ""
29
-
30
-
31
- def evaluate_run(run, task=None):
32
- """Build a deterministic acceptance result from persisted run evidence."""
33
- run = run or {}
34
- task = task or {}
35
- status = str(run.get("status") or "")
36
- verdict = run.get("verdict") or {}
37
- out = []
38
-
39
- correct, source = _quality_verdict(run)
40
- if status in ("failed", "timeout", "cancelled"):
41
- out.append(_case("correctness", "unknown",
42
- {"source": "run.status", "value": status},
43
- "任务终态未形成可判定的质量结论"))
44
- elif correct is not None:
45
- out.append(_case("correctness", "passed" if correct else "failed",
46
- {"source": "run.verdict", "field": source,
47
- "value": bool(correct)}))
48
- else:
49
- out.append(_case("correctness", "not_evaluated", reason="缺少验证或质量门证据"))
50
-
51
- duration = run.get("duration_s")
52
- if duration is None and run.get("started_at") and run.get("ended_at"):
53
- duration = "recorded"
54
- has_duration = isinstance(duration, (int, float)) and duration >= 0
55
- has_usage = any(isinstance(run.get(key), (int, float)) and run.get(key) > 0
56
- for key in ("tokens", "cost_usd"))
57
- if has_duration or has_usage:
58
- out.append(_case("performance", "passed", {
59
- "source": "run.metrics", "duration_s": duration,
60
- "tokens": run.get("tokens", 0), "cost_usd": run.get("cost_usd", 0),
61
- }, "仅表示性能数据已记录,不代表达到业务阈值"))
62
- else:
63
- out.append(_case("performance", "not_evaluated", reason="缺少耗时或用量证据"))
64
-
65
- boundary = verdict.get("boundary_checks")
66
- if isinstance(boundary, list) and boundary and all(
67
- isinstance(x, dict) and isinstance(x.get("passed"), bool) for x in boundary):
68
- failed = [x for x in boundary if x.get("passed") is False]
69
- out.append(_case("boundary", "failed" if failed else "passed",
70
- {"source": "run.verdict.boundary_checks", "count": len(boundary),
71
- "failed": len(failed)}))
72
- else:
73
- out.append(_case("boundary", "not_evaluated", reason="当前任务未声明边界检查证据"))
74
-
75
- exception = verdict.get("exception")
76
- if isinstance(exception, bool):
77
- out.append(_case("exception", "passed" if exception else "failed",
78
- {"source": "run.verdict.exception", "value": exception}))
79
- elif status in ("failed", "timeout"):
80
- out.append(_case("exception", "failed" if status in ("failed", "timeout") else "unknown",
81
- {"source": "run.error", "status": status,
82
- "error": str(run.get("error") or "")[:300]}))
83
- elif status == "cancelled":
84
- out.append(_case("exception", "unknown",
85
- {"source": "run.status", "value": status}))
86
- else:
87
- out.append(_case("exception", "not_evaluated", reason="缺少独立异常处理证据"))
88
-
89
- for name, key in (("readability", "readability"), ("security", "security")):
90
- value = verdict.get(key)
91
- if isinstance(value, bool):
92
- out.append(_case(name, "passed" if value else "failed",
93
- {"source": "run.verdict.%s" % key, "value": value}))
94
- else:
95
- out.append(_case(name, "not_evaluated", reason="未提供独立 %s 证据" % name))
96
-
97
- # 总体通过要求六个维度都有明确通过证据;缺证据不能被两个局部绿灯掩盖。
98
- return {"version": 1, "evaluated_at": time.time(),
99
- "passed": bool(out and all(x["status"] == "passed" for x in out)),
100
- "cases": out}
1
+ # -*- coding: utf-8 -*-
2
+ """Run acceptance matrix and evidence normalization.
3
+
4
+ The matrix keeps correctness, performance, boundary behavior, exception
5
+ handling, readability and security as separate conclusions. Missing evidence
6
+ is reported as ``not_evaluated``/``unknown`` rather than being inferred from a
7
+ successful process exit.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import time
12
+
13
+ CASES = ("correctness", "performance", "boundary", "exception",
14
+ "readability", "security")
15
+
16
+
17
+ def _case(name, status, evidence=None, reason=""):
18
+ return {"case": name, "status": status,
19
+ "evidence": [evidence] if isinstance(evidence, dict) else [],
20
+ "reason": str(reason or "")[:300]}
21
+
22
+
23
+ def _quality_verdict(run):
24
+ verdict = run.get("verdict") or {}
25
+ for key in ("pass", "publishable", "verify_pass"):
26
+ if isinstance(verdict.get(key), bool):
27
+ return verdict.get(key), key
28
+ return None, ""
29
+
30
+
31
+ def evaluate_run(run, task=None):
32
+ """Build a deterministic acceptance result from persisted run evidence."""
33
+ run = run or {}
34
+ task = task or {}
35
+ status = str(run.get("status") or "")
36
+ verdict = run.get("verdict") or {}
37
+ out = []
38
+
39
+ correct, source = _quality_verdict(run)
40
+ if status in ("failed", "timeout", "cancelled"):
41
+ out.append(_case("correctness", "unknown",
42
+ {"source": "run.status", "value": status},
43
+ "任务终态未形成可判定的质量结论"))
44
+ elif correct is not None:
45
+ out.append(_case("correctness", "passed" if correct else "failed",
46
+ {"source": "run.verdict", "field": source,
47
+ "value": bool(correct)}))
48
+ else:
49
+ out.append(_case("correctness", "not_evaluated", reason="缺少验证或质量门证据"))
50
+
51
+ duration = run.get("duration_s")
52
+ if duration is None and run.get("started_at") and run.get("ended_at"):
53
+ duration = "recorded"
54
+ has_duration = isinstance(duration, (int, float)) and duration >= 0
55
+ has_usage = any(isinstance(run.get(key), (int, float)) and run.get(key) > 0
56
+ for key in ("tokens", "cost_usd"))
57
+ if has_duration or has_usage:
58
+ out.append(_case("performance", "passed", {
59
+ "source": "run.metrics", "duration_s": duration,
60
+ "tokens": run.get("tokens", 0), "cost_usd": run.get("cost_usd", 0),
61
+ }, "仅表示性能数据已记录,不代表达到业务阈值"))
62
+ else:
63
+ out.append(_case("performance", "not_evaluated", reason="缺少耗时或用量证据"))
64
+
65
+ boundary = verdict.get("boundary_checks")
66
+ if isinstance(boundary, list) and boundary and all(
67
+ isinstance(x, dict) and isinstance(x.get("passed"), bool) for x in boundary):
68
+ failed = [x for x in boundary if x.get("passed") is False]
69
+ out.append(_case("boundary", "failed" if failed else "passed",
70
+ {"source": "run.verdict.boundary_checks", "count": len(boundary),
71
+ "failed": len(failed)}))
72
+ else:
73
+ out.append(_case("boundary", "not_evaluated", reason="当前任务未声明边界检查证据"))
74
+
75
+ exception = verdict.get("exception")
76
+ if isinstance(exception, bool):
77
+ out.append(_case("exception", "passed" if exception else "failed",
78
+ {"source": "run.verdict.exception", "value": exception}))
79
+ elif status in ("failed", "timeout"):
80
+ out.append(_case("exception", "failed" if status in ("failed", "timeout") else "unknown",
81
+ {"source": "run.error", "status": status,
82
+ "error": str(run.get("error") or "")[:300]}))
83
+ elif status == "cancelled":
84
+ out.append(_case("exception", "unknown",
85
+ {"source": "run.status", "value": status}))
86
+ else:
87
+ out.append(_case("exception", "not_evaluated", reason="缺少独立异常处理证据"))
88
+
89
+ for name, key in (("readability", "readability"), ("security", "security")):
90
+ value = verdict.get(key)
91
+ if isinstance(value, bool):
92
+ out.append(_case(name, "passed" if value else "failed",
93
+ {"source": "run.verdict.%s" % key, "value": value}))
94
+ else:
95
+ out.append(_case(name, "not_evaluated", reason="未提供独立 %s 证据" % name))
96
+
97
+ # 总体通过要求六个维度都有明确通过证据;缺证据不能被两个局部绿灯掩盖。
98
+ return {"version": 1, "evaluated_at": time.time(),
99
+ "passed": bool(out and all(x["status"] == "passed" for x in out)),
100
+ "cases": out}