codebee 0.1.95 → 0.1.96

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 (138) hide show
  1. package/CHANGELOG.md +725 -720
  2. package/LICENSE +21 -21
  3. package/README.md +515 -509
  4. package/app/core/acceptance.py +100 -100
  5. package/app/core/agent_context.py +100 -0
  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/backup.py +470 -470
  13. package/app/core/beekeeper.py +183 -183
  14. package/app/core/benchstore.py +102 -95
  15. package/app/core/board.py +209 -209
  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/builtin_agent.py +1680 -1680
  20. package/app/core/capability.py +144 -144
  21. package/app/core/chaptersafe.py +32 -32
  22. package/app/core/checkpoints.py +143 -0
  23. package/app/core/cleanup.py +303 -303
  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.py +198 -191
  30. package/app/core/dispatch_log.py +128 -128
  31. package/app/core/env_scrub.py +85 -85
  32. package/app/core/errorlog.py +137 -137
  33. package/app/core/eval_matrix.py +82 -0
  34. package/app/core/evalbench.py +184 -91
  35. package/app/core/evaluation.py +174 -174
  36. package/app/core/failure_notify.py +290 -290
  37. package/app/core/flow_graph.py +33 -0
  38. package/app/core/goal_service.py +167 -167
  39. package/app/core/health.py +389 -389
  40. package/app/core/history.py +38 -38
  41. package/app/core/hooks.py +162 -162
  42. package/app/core/jobs.py +25 -4
  43. package/app/core/knowledge_pipeline.py +86 -0
  44. package/app/core/manager.py +2232 -2232
  45. package/app/core/mocks.py +64 -64
  46. package/app/core/notify.py +201 -201
  47. package/app/core/novel_quality.py +181 -189
  48. package/app/core/openapi.py +177 -154
  49. package/app/core/operations.py +228 -228
  50. package/app/core/paihang.py +145 -145
  51. package/app/core/pipeline.py +43 -19
  52. package/app/core/planner.py +17 -11
  53. package/app/core/policy.py +52 -0
  54. package/app/core/portguard.py +111 -111
  55. package/app/core/presence.py +77 -77
  56. package/app/core/preview.py +293 -293
  57. package/app/core/prompt_guard.py +78 -78
  58. package/app/core/publish/__init__.py +7 -7
  59. package/app/core/publish/auto.py +26 -3
  60. package/app/core/publish/browser.py +655 -655
  61. package/app/core/publish/chaprows.py +138 -0
  62. package/app/core/publish/fanqie.py +210 -165
  63. package/app/core/publish/flow.py +753 -640
  64. package/app/core/publish/flows-fanqie-calibrated.json +349 -336
  65. package/app/core/publish/ledger.py +13 -1
  66. package/app/core/publish/manager.py +1150 -1118
  67. package/app/core/publish/qimao.py +176 -176
  68. package/app/core/publish/volumes.py +108 -0
  69. package/app/core/publish/ws.py +139 -139
  70. package/app/core/quality_gate.py +194 -194
  71. package/app/core/redact.py +38 -38
  72. package/app/core/repeat_guard.py +129 -129
  73. package/app/core/retrieval.py +137 -137
  74. package/app/core/router.py +398 -398
  75. package/app/core/runner.py +2238 -2238
  76. package/app/core/selfupdate.py +384 -384
  77. package/app/core/session_log.py +161 -161
  78. package/app/core/sessions.py +312 -312
  79. package/app/core/settings.py +20 -0
  80. package/app/core/settings_schema.py +270 -270
  81. package/app/core/share_page.py +114 -114
  82. package/app/core/skill_scan.py +139 -139
  83. package/app/core/skillpacks/fanqie-novel.md +8 -6
  84. package/app/core/skillpacks/market/character-bible.md +66 -66
  85. package/app/core/skillpacks/market/code-risk-checklist.md +58 -58
  86. package/app/core/skillpacks/market/git-workflow.md +57 -57
  87. package/app/core/skillpacks/market/release-notes.md +72 -72
  88. package/app/core/skillpacks/market/weekly-report.md +71 -71
  89. package/app/core/skillpacks/market/worldview-consistency.md +70 -70
  90. package/app/core/skillpacks/qimao-signing.md +14 -11
  91. package/app/core/skills.py +32 -21
  92. package/app/core/step_runner.py +132 -132
  93. package/app/core/store.py +9 -0
  94. package/app/core/story_tracking.py +275 -275
  95. package/app/core/task_compile.py +199 -199
  96. package/app/core/telemetry.py +292 -292
  97. package/app/core/tlsctx.py +64 -64
  98. package/app/core/token_meter.py +147 -147
  99. package/app/core/tracing.py +207 -144
  100. package/app/core/upstream.py +41 -41
  101. package/app/core/usage.py +1038 -1038
  102. package/app/core/volumes.py +389 -389
  103. package/app/core/webhooks.py +89 -0
  104. package/app/core/wxdigest.py +858 -858
  105. package/app/core/zentao.py +2692 -2692
  106. package/app/main.py +104 -9
  107. package/app/mcp_server.py +244 -244
  108. package/app/pick_dialog.py +110 -110
  109. package/app/ui/app.js +286 -18
  110. package/app/ui/artdiff.js +74 -74
  111. package/app/ui/assets/community-qr.png +0 -0
  112. package/app/ui/assets/donate-alipay.jpg +0 -0
  113. package/app/ui/assets/donate-qr.jpg +0 -0
  114. package/app/ui/board.html +162 -162
  115. package/app/ui/board.js +305 -305
  116. package/app/ui/i18n.js +33 -0
  117. package/app/ui/icons/bee.svg +79 -79
  118. package/app/ui/index.html +32 -3
  119. package/app/ui/manifest.json +16 -16
  120. package/app/ui/qrcode.js +2297 -2297
  121. package/app/ui/style.css +196 -2
  122. package/bin/tutti.js +147 -147
  123. package/package.json +48 -48
  124. package/tools/wx_reader.py +261 -261
  125. package/app/.playwright-cli/console-2026-09-23T08-26-03-635Z.log +0 -88
  126. package/app/.playwright-cli/page-2026-09-23T08-26-03-845Z.yml +0 -126
  127. package/app/.playwright-cli/page-2026-09-23T08-29-44-203Z.png +0 -0
  128. package/app/.playwright-cli/page-2026-09-23T08-35-42-046Z.yml +0 -210
  129. package/app/.playwright-cli/page-2026-09-23T08-36-52-858Z.png +0 -0
  130. package/app/.playwright-cli/page-2026-09-23T08-37-33-938Z.png +0 -0
  131. package/app/.playwright-cli/run-detail-after.png +0 -0
  132. package/app/output/_createbook_body.json +0 -1
  133. package/app/output/_probe_fq_click.py +0 -50
  134. package/app/output/_probe_fq_form.py +0 -42
  135. package/app/output/_probe_fq_modal.py +0 -55
  136. package/app/output/_probe_fq_points.py +0 -71
  137. package/app/output/_probe_fq_submit.py +0 -34
  138. package/app/output/_probe_fq_watch.py +0 -62
@@ -1,154 +1,177 @@
1
- """OpenAPI 3 contract for the stable headless CodeBee integrations."""
2
-
3
-
4
- def document():
5
- schemas = {
6
- "Error": {"type": "object", "required": ["error"], "properties": {
7
- "error": {"type": "string"}, "control": {"$ref": "#/components/schemas/Control"}}},
8
- "Control": {"type": "object", "properties": {
9
- "mode": {"type": "string", "enum": ["free", "held"]},
10
- "mine": {"type": "boolean"}, "holder": {"type": "string"},
11
- "expires_in": {"type": "integer", "minimum": 0}}},
12
- "TaskCreate": {"type": "object", "required": ["goal"], "properties": {
13
- "type": {"type": "string"}, "title": {"type": "string"},
14
- "goal": {"type": "string", "maxLength": 4000}, "workdir": {"type": "string"},
15
- "acceptance_criteria": {"type": "array", "maxItems": 40,
16
- "items": {"type": "string", "maxLength": 500}},
17
- "approval_required": {"type": "boolean"}}},
18
- "TaskResult": {"type": "object", "required": ["task_id", "run_id"], "properties": {
19
- "task_id": {"type": "string"}, "run_id": {"type": "string"}}},
20
- "Evidence": {"type": "object", "required": ["status"], "properties": {
21
- "id": {"type": "string"}, "criterion": {"type": "string", "maxLength": 500},
22
- "status": {"type": "string", "enum": ["passed", "failed", "unknown", "not_evaluated"]},
23
- "summary": {"type": "string", "maxLength": 2000},
24
- "source": {"type": "string", "maxLength": 80}, "created_at": {"type": "string"}}},
25
- "Contract": {"type": "object", "properties": {
26
- "task_id": {"type": "string"},
27
- "acceptance_criteria": {"type": "array", "items": {"type": "string"}},
28
- "evidence": {"type": "array", "items": {"$ref": "#/components/schemas/Evidence"}},
29
- "approval_required": {"type": "boolean"}, "approval": {"type": "object"},
30
- "blocked_reason": {"type": "string"}, "completion_receipt": {"type": "object"}}},
31
- "StoryChapter": {"type": "object", "properties": {
32
- "op": {"type": "string"},
33
- "chapter": {"type": "integer", "minimum": 1, "maximum": 5000},
34
- "outline": {"type": "string", "maxLength": 12000}, "prose": {"type": "string"},
35
- "facts": {"type": "array", "items": {"type": "string"}},
36
- "characters": {"type": "array", "items": {"type": "string"}},
37
- "timeline": {"type": "array", "items": {"type": "string"}},
38
- "foreshadowing": {"type": "array", "items": {"type": "object"}},
39
- "next_promises": {"type": "array", "items": {"type": "string"}},
40
- "author_truth": {"type": "array", "items": {"type": "string"}},
41
- "reader_known": {"type": "array", "items": {"type": "string"}}},
42
- "oneOf": [
43
- {"required": ["op"], "properties": {"op": {"const": "init"}}},
44
- {"required": ["chapter", "outline", "prose"]},
45
- ]},
46
- "StoryTrackingResult": {"type": "object", "properties": {
47
- "state": {"type": "object"}, "check": {"type": "object"}}},
48
- "Presence": {"type": "object", "required": ["agent_id"], "properties": {
49
- "agent_id": {"type": "string", "maxLength": 100}, "label": {"type": "string", "maxLength": 120},
50
- "capabilities": {"type": "array", "maxItems": 30,
51
- "items": {"type": "string", "maxLength": 80}},
52
- "task_id": {"type": "string", "maxLength": 100}, "status": {"type": "string", "maxLength": 30},
53
- "metadata": {"type": "object"}}},
54
- }
55
-
56
- def body(schema):
57
- return {"required": True, "content": {"application/json": {"schema": schema}}}
58
-
59
- def response(description, schema=None):
60
- out = {"description": description}
61
- if schema is not None:
62
- out["content"] = {"application/json": {"schema": schema}}
63
- return out
64
-
65
- ref = lambda name: {"$ref": "#/components/schemas/" + name}
66
- security = [{"codebeeToken": []}, {"codebeeQueryToken": []}]
67
- errors = {code: response(desc, ref("Error")) for code, desc in (
68
- ("400", "请求无效"), ("401", "缺少或错误的访问令牌"),
69
- ("404", "资源不存在"), ("409", "状态冲突或审批未完成"),
70
- ("423", "其他设备持有控制权"))}
71
- ok = response("成功", {"type": "object", "properties": {"ok": {"type": "boolean"}}})
72
-
73
- paths = {
74
- "/api/tasks": {"post": {"summary": "创建并启动任务", "security": security,
75
- "requestBody": body(ref("TaskCreate")),
76
- "responses": {"200": response("已排队", ref("TaskResult")),
77
- "503": response("运行记录或入队失败", ref("Error")), **errors}}},
78
- "/api/a2a/tasks": {"post": {"summary": "A2A-lite 创建任务", "security": security,
79
- "requestBody": body(ref("TaskCreate")),
80
- "responses": {"200": response("已排队", ref("TaskResult")), "400": errors["400"],
81
- "401": errors["401"], "423": errors["423"]}}},
82
- "/api/a2a/tasks/{task_id}": {"get": {"summary": "A2A-lite 读取任务状态", "security": security,
83
- "responses": {"200": response("任务、运行和契约", {"type": "object"}),
84
- "401": errors["401"], "404": errors["404"]}}},
85
- "/api/tasks/{task_id}/detail": {"get": {"summary": "读取任务详情和契约", "security": security,
86
- "responses": {"200": response("任务详情", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
87
- "/api/tasks/{task_id}/contract": {
88
- "get": {"summary": "读取任务契约", "security": security,
89
- "responses": {"200": response("契约", ref("Contract")), "401": errors["401"], "404": errors["404"]}},
90
- "post": {"summary": "更新契约、追加证据或审批任务", "security": security,
91
- "requestBody": body({"type": "object", "properties": {
92
- "op": {"type": "string", "enum": ["update", "create", "evidence", "approve", "reject", "blocked"]},
93
- "acceptance_criteria": {"type": "array", "items": {"type": "string"}},
94
- "approval_required": {"type": "boolean"}, "evidence": ref("Evidence"),
95
- "note": {"type": "string", "maxLength": 1000}, "reason": {"type": "string", "maxLength": 1000}}}),
96
- "responses": {"200": response("契约已更新", {"type": "object", "properties": {"contract": ref("Contract")}}), **errors}}},
97
- "/api/tasks/{task_id}/story-tracking": {
98
- "get": {"summary": "读取小说追踪状态", "security": security,
99
- "responses": {"200": response("追踪状态", ref("StoryTrackingResult")), "401": errors["401"],
100
- "404": errors["404"], "409": errors["409"]}},
101
- "post": {"summary": "提交章节结构化状态", "security": security, "requestBody": body(ref("StoryChapter")),
102
- "responses": {"200": response("追踪状态已更新", ref("StoryTrackingResult")), **errors}}},
103
- "/api/agents/presence": {
104
- "get": {"summary": "Agent 在线状态", "security": security,
105
- "responses": {"200": response("在线 Agent 列表", {"type": "object"}), "401": errors["401"]}},
106
- "post": {"summary": "Agent 心跳", "security": security, "requestBody": body(ref("Presence")),
107
- "responses": {"200": response("心跳已记录", {"type": "object"}), "400": errors["400"],
108
- "401": errors["401"], "423": errors["423"]}}},
109
- "/api/retrieval/search": {"get": {"summary": "本地检索", "security": security,
110
- "parameters": [{"name": "q", "in": "query", "required": True,
111
- "schema": {"type": "string", "maxLength": 500}},
112
- {"name": "limit", "in": "query",
113
- "schema": {"type": "integer", "minimum": 1, "maximum": 50}}],
114
- "responses": {"200": response("检索结果", {"type": "object"}), "400": errors["400"], "401": errors["401"]}}},
115
- "/api/retrieval/index": {"post": {"summary": "为配置工作区/任务目录建立本地检索索引", "security": security,
116
- "requestBody": body({"type": "object", "properties": {
117
- "source": {"type": "string"}, "text": {"type": "string"}, "metadata": {"type": "object"},
118
- "doc_id": {"type": "string"}, "root": {"type": "string"}, "task_id": {"type": "string"},
119
- "limit": {"type": "integer", "minimum": 1, "maximum": 500}}}),
120
- "responses": {"200": response("索引已更新", {"type": "object"}), "400": errors["400"],
121
- "401": errors["401"], "404": errors["404"], "423": errors["423"]}}},
122
- "/api/analytics": {"get": {"summary": "任务成本质量分析", "security": security,
123
- "responses": {"200": response("分析摘要", {"type": "object"}), "401": errors["401"]}}},
124
- "/api/runs/{run_id}": {"get": {"summary": "读取运行状态", "security": security,
125
- "responses": {"200": response("运行状态", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
126
- "/api/runs/{run_id}/resume_now": {"post": {"summary": "立即重试运行", "security": security,
127
- "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"], "423": errors["423"]}}},
128
- "/api/control": {
129
- "get": {"summary": "读取当前控制权", "security": security,
130
- "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}},
131
- "post": {"summary": "接管或释放控制权", "security": security,
132
- "requestBody": body({"type": "object", "required": ["action"], "properties": {
133
- "action": {"type": "string", "enum": ["acquire", "release"]},
134
- "force": {"type": "boolean"}}}),
135
- "responses": {"200": response("控制权已更新", {"type": "object"}),
136
- "400": errors["400"], "401": errors["401"], "423": errors["423"]}}},
137
- "/api/control/heartbeat": {
138
- "get": {"summary": "续期当前控制权", "security": security,
139
- "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}},
140
- "post": {"summary": "续期当前控制权", "security": security,
141
- "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}}},
142
- "/api/openapi.json": {"get": {"summary": "读取 OpenAPI 文档", "security": security,
143
- "responses": {"200": response("OpenAPI 文档", {"type": "object"}), "401": errors["401"]}}},
144
- "/api/health": {"get": {"summary": "读取服务健康状态", "security": security,
145
- "responses": {"200": response("健康状态", {"type": "object"}), "401": errors["401"]}}},
146
- "/api/state": {"get": {"summary": "读取任务状态聚合", "security": security,
147
- "responses": {"200": response("状态聚合", {"type": "object"}), "401": errors["401"]}}},
148
- }
149
- return {"openapi": "3.0.3", "info": {"title": "CodeBee API", "version": "1.0",
150
- "description": "本机/局域网 API。远程请求需 X-CodeBee-Token 或 token 查询参数;本机 loopback 默认免令牌。"},
151
- "servers": [{"url": "/"}], "components": {"securitySchemes": {
152
- "codebeeToken": {"type": "apiKey", "in": "header", "name": "X-CodeBee-Token"},
153
- "codebeeQueryToken": {"type": "apiKey", "in": "query", "name": "token"}},
154
- "schemas": schemas}, "paths": paths}
1
+ """OpenAPI 3 contract for the stable headless CodeBee integrations."""
2
+
3
+
4
+ def document():
5
+ schemas = {
6
+ "Error": {"type": "object", "required": ["error"], "properties": {
7
+ "error": {"type": "string"}, "control": {"$ref": "#/components/schemas/Control"}}},
8
+ "Control": {"type": "object", "properties": {
9
+ "mode": {"type": "string", "enum": ["free", "held"]},
10
+ "mine": {"type": "boolean"}, "holder": {"type": "string"},
11
+ "expires_in": {"type": "integer", "minimum": 0}}},
12
+ "TaskCreate": {"type": "object", "required": ["goal"], "properties": {
13
+ "type": {"type": "string"}, "title": {"type": "string"},
14
+ "goal": {"type": "string", "maxLength": 4000}, "workdir": {"type": "string"},
15
+ "acceptance_criteria": {"type": "array", "maxItems": 40,
16
+ "items": {"type": "string", "maxLength": 500}},
17
+ "approval_required": {"type": "boolean"}}},
18
+ "TaskResult": {"type": "object", "required": ["task_id", "run_id"], "properties": {
19
+ "task_id": {"type": "string"}, "run_id": {"type": "string"}}},
20
+ "Evidence": {"type": "object", "required": ["status"], "properties": {
21
+ "id": {"type": "string"}, "criterion": {"type": "string", "maxLength": 500},
22
+ "status": {"type": "string", "enum": ["passed", "failed", "unknown", "not_evaluated"]},
23
+ "summary": {"type": "string", "maxLength": 2000},
24
+ "source": {"type": "string", "maxLength": 80}, "created_at": {"type": "string"}}},
25
+ "Contract": {"type": "object", "properties": {
26
+ "task_id": {"type": "string"},
27
+ "acceptance_criteria": {"type": "array", "items": {"type": "string"}},
28
+ "evidence": {"type": "array", "items": {"$ref": "#/components/schemas/Evidence"}},
29
+ "approval_required": {"type": "boolean"}, "approval": {"type": "object"},
30
+ "blocked_reason": {"type": "string"}, "completion_receipt": {"type": "object"}}},
31
+ "StoryChapter": {"type": "object", "properties": {
32
+ "op": {"type": "string"},
33
+ "chapter": {"type": "integer", "minimum": 1, "maximum": 5000},
34
+ "outline": {"type": "string", "maxLength": 12000}, "prose": {"type": "string"},
35
+ "facts": {"type": "array", "items": {"type": "string"}},
36
+ "characters": {"type": "array", "items": {"type": "string"}},
37
+ "timeline": {"type": "array", "items": {"type": "string"}},
38
+ "foreshadowing": {"type": "array", "items": {"type": "object"}},
39
+ "next_promises": {"type": "array", "items": {"type": "string"}},
40
+ "author_truth": {"type": "array", "items": {"type": "string"}},
41
+ "reader_known": {"type": "array", "items": {"type": "string"}}},
42
+ "oneOf": [
43
+ {"required": ["op"], "properties": {"op": {"const": "init"}}},
44
+ {"required": ["chapter", "outline", "prose"]},
45
+ ]},
46
+ "StoryTrackingResult": {"type": "object", "properties": {
47
+ "state": {"type": "object"}, "check": {"type": "object"}}},
48
+ "Presence": {"type": "object", "required": ["agent_id"], "properties": {
49
+ "agent_id": {"type": "string", "maxLength": 100}, "label": {"type": "string", "maxLength": 120},
50
+ "capabilities": {"type": "array", "maxItems": 30,
51
+ "items": {"type": "string", "maxLength": 80}},
52
+ "task_id": {"type": "string", "maxLength": 100}, "status": {"type": "string", "maxLength": 30},
53
+ "metadata": {"type": "object"}}},
54
+ }
55
+
56
+ def body(schema):
57
+ return {"required": True, "content": {"application/json": {"schema": schema}}}
58
+
59
+ def response(description, schema=None):
60
+ out = {"description": description}
61
+ if schema is not None:
62
+ out["content"] = {"application/json": {"schema": schema}}
63
+ return out
64
+
65
+ ref = lambda name: {"$ref": "#/components/schemas/" + name}
66
+ security = [{"codebeeToken": []}, {"codebeeQueryToken": []}]
67
+ errors = {code: response(desc, ref("Error")) for code, desc in (
68
+ ("400", "请求无效"), ("401", "缺少或错误的访问令牌"),
69
+ ("404", "资源不存在"), ("409", "状态冲突或审批未完成"),
70
+ ("423", "其他设备持有控制权"))}
71
+ ok = response("成功", {"type": "object", "properties": {"ok": {"type": "boolean"}}})
72
+
73
+ paths = {
74
+ "/api/tasks": {"post": {"summary": "创建并启动任务", "security": security,
75
+ "requestBody": body(ref("TaskCreate")),
76
+ "responses": {"200": response("已排队", ref("TaskResult")),
77
+ "503": response("运行记录或入队失败", ref("Error")), **errors}}},
78
+ "/api/a2a/tasks": {"post": {"summary": "A2A-lite 创建任务", "security": security,
79
+ "requestBody": body(ref("TaskCreate")),
80
+ "responses": {"200": response("已排队", ref("TaskResult")), "400": errors["400"],
81
+ "401": errors["401"], "423": errors["423"]}}},
82
+ "/api/a2a/tasks/{task_id}": {"get": {"summary": "A2A-lite 读取任务状态", "security": security,
83
+ "responses": {"200": response("任务、运行和契约", {"type": "object"}),
84
+ "401": errors["401"], "404": errors["404"]}}},
85
+ "/api/tasks/{task_id}/detail": {"get": {"summary": "读取任务详情和契约", "security": security,
86
+ "responses": {"200": response("任务详情", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
87
+ "/api/tasks/{task_id}/contract": {
88
+ "get": {"summary": "读取任务契约", "security": security,
89
+ "responses": {"200": response("契约", ref("Contract")), "401": errors["401"], "404": errors["404"]}},
90
+ "post": {"summary": "更新契约、追加证据或审批任务", "security": security,
91
+ "requestBody": body({"type": "object", "properties": {
92
+ "op": {"type": "string", "enum": ["update", "create", "evidence", "approve", "reject", "blocked"]},
93
+ "acceptance_criteria": {"type": "array", "items": {"type": "string"}},
94
+ "approval_required": {"type": "boolean"}, "evidence": ref("Evidence"),
95
+ "note": {"type": "string", "maxLength": 1000}, "reason": {"type": "string", "maxLength": 1000}}}),
96
+ "responses": {"200": response("契约已更新", {"type": "object", "properties": {"contract": ref("Contract")}}), **errors}}},
97
+ "/api/tasks/{task_id}/story-tracking": {
98
+ "get": {"summary": "读取小说追踪状态", "security": security,
99
+ "responses": {"200": response("追踪状态", ref("StoryTrackingResult")), "401": errors["401"],
100
+ "404": errors["404"], "409": errors["409"]}},
101
+ "post": {"summary": "提交章节结构化状态", "security": security, "requestBody": body(ref("StoryChapter")),
102
+ "responses": {"200": response("追踪状态已更新", ref("StoryTrackingResult")), **errors}}},
103
+ "/api/agents/presence": {
104
+ "get": {"summary": "Agent 在线状态", "security": security,
105
+ "responses": {"200": response("在线 Agent 列表", {"type": "object"}), "401": errors["401"]}},
106
+ "post": {"summary": "Agent 心跳", "security": security, "requestBody": body(ref("Presence")),
107
+ "responses": {"200": response("心跳已记录", {"type": "object"}), "400": errors["400"],
108
+ "401": errors["401"], "423": errors["423"]}}},
109
+ "/api/retrieval/search": {"get": {"summary": "本地检索", "security": security,
110
+ "parameters": [{"name": "q", "in": "query", "required": True,
111
+ "schema": {"type": "string", "maxLength": 500}},
112
+ {"name": "limit", "in": "query",
113
+ "schema": {"type": "integer", "minimum": 1, "maximum": 50}}],
114
+ "responses": {"200": response("检索结果", {"type": "object"}), "400": errors["400"], "401": errors["401"]}}},
115
+ "/api/retrieval/index": {"post": {"summary": "为配置工作区/任务目录建立本地检索索引", "security": security,
116
+ "requestBody": body({"type": "object", "properties": {
117
+ "source": {"type": "string"}, "text": {"type": "string"}, "metadata": {"type": "object"},
118
+ "doc_id": {"type": "string"}, "root": {"type": "string"}, "task_id": {"type": "string"},
119
+ "limit": {"type": "integer", "minimum": 1, "maximum": 500}}}),
120
+ "responses": {"200": response("索引已更新", {"type": "object"}), "400": errors["400"],
121
+ "401": errors["401"], "404": errors["404"], "423": errors["423"]}}},
122
+ "/api/analytics": {"get": {"summary": "任务成本质量分析", "security": security,
123
+ "responses": {"200": response("分析摘要", {"type": "object"}), "401": errors["401"]}}},
124
+ "/api/runs/{run_id}": {"get": {"summary": "读取运行状态", "security": security,
125
+ "responses": {"200": response("运行状态", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
126
+ "/api/runs/{run_id}/trace": {"get": {"summary": "读取脱敏 trace", "security": security,
127
+ "responses": {"200": response("Trace", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
128
+ "/api/runs/{run_id}/otel": {"get": {"summary": "导出 OTLP JSON trace", "security": security,
129
+ "responses": {"200": response("OTLP trace", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
130
+ "/api/runs/{run_id}/checkpoints": {"get": {"summary": "读取 checkpoint 回放预览", "security": security,
131
+ "responses": {"200": response("Checkpoint", {"type": "object"}), "401": errors["401"]}}},
132
+ "/api/flows/{flow_id}/graph": {"get": {"summary": "读取流程图投影", "security": security,
133
+ "responses": {"200": response("Flow graph", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
134
+ "/api/hooks/run": {"post": {"summary": "Webhook 触发任务(可选 HMAC)", "security": security,
135
+ "requestBody": body(ref("TaskCreate")),
136
+ "responses": {"200": response("已排队", ref("TaskResult")), "401": errors["401"], "403": errors["401"], "400": errors["400"]}}},
137
+ "/api/eval-matrix/normalize": {"post": {"summary": "规范化评测矩阵 manifest", "security": security,
138
+ "requestBody": body({"type": "object"}), "responses": {"200": response("Manifest", {"type": "object"}), "400": errors["400"]}}},
139
+ "/api/eval-matrix/evaluate": {"post": {"summary": "对比评测矩阵与 baseline", "security": security,
140
+ "requestBody": body({"type": "object"}), "responses": {"200": response("Report", {"type": "object"}), "400": errors["400"]}}},
141
+ "/api/knowledge/pipeline": {"get": {"summary": "读取知识管线质量报告", "security": security,
142
+ "parameters": [{"name": "ingest_id", "in": "query", "schema": {"type": "string"}}],
143
+ "responses": {"200": response("Quality report", {"type": "object"})}},
144
+ "post": {"summary": "分块并建立知识索引", "security": security,
145
+ "requestBody": body({"type": "object"}), "responses": {"200": response("Ingest report", {"type": "object"}), "400": errors["400"]}}},
146
+ "/api/policy": {"get": {"summary": "读取规范化沙箱策略", "security": security,
147
+ "parameters": [{"name": "workdir", "in": "query", "schema": {"type": "string"}}],
148
+ "responses": {"200": response("Sandbox policy", {"type": "object"})}}},
149
+ "/api/runs/{run_id}/resume_now": {"post": {"summary": "立即重试运行", "security": security,
150
+ "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"], "423": errors["423"]}}},
151
+ "/api/control": {
152
+ "get": {"summary": "读取当前控制权", "security": security,
153
+ "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}},
154
+ "post": {"summary": "接管或释放控制权", "security": security,
155
+ "requestBody": body({"type": "object", "required": ["action"], "properties": {
156
+ "action": {"type": "string", "enum": ["acquire", "release"]},
157
+ "force": {"type": "boolean"}}}),
158
+ "responses": {"200": response("控制权已更新", {"type": "object"}),
159
+ "400": errors["400"], "401": errors["401"], "423": errors["423"]}}},
160
+ "/api/control/heartbeat": {
161
+ "get": {"summary": "续期当前控制权", "security": security,
162
+ "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}},
163
+ "post": {"summary": "续期当前控制权", "security": security,
164
+ "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}}},
165
+ "/api/openapi.json": {"get": {"summary": "读取 OpenAPI 文档", "security": security,
166
+ "responses": {"200": response("OpenAPI 文档", {"type": "object"}), "401": errors["401"]}}},
167
+ "/api/health": {"get": {"summary": "读取服务健康状态", "security": security,
168
+ "responses": {"200": response("健康状态", {"type": "object"}), "401": errors["401"]}}},
169
+ "/api/state": {"get": {"summary": "读取任务状态聚合", "security": security,
170
+ "responses": {"200": response("状态聚合", {"type": "object"}), "401": errors["401"]}}},
171
+ }
172
+ return {"openapi": "3.0.3", "info": {"title": "CodeBee API", "version": "1.0",
173
+ "description": "本机/局域网 API。远程请求需 X-CodeBee-Token 或 token 查询参数;本机 loopback 默认免令牌。"},
174
+ "servers": [{"url": "/"}], "components": {"securitySchemes": {
175
+ "codebeeToken": {"type": "apiKey", "in": "header", "name": "X-CodeBee-Token"},
176
+ "codebeeQueryToken": {"type": "apiKey", "in": "query", "name": "token"}},
177
+ "schemas": schemas}, "paths": paths}