codebee 0.1.101 → 0.1.103

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 (134) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +21 -21
  3. package/README.md +3 -6
  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/acceptance.py +100 -100
  12. package/app/core/acp_client.py +457 -426
  13. package/app/core/aiflavor.py +197 -197
  14. package/app/core/analytics.py +38 -38
  15. package/app/core/artifacts.py +148 -148
  16. package/app/core/assets.py +110 -110
  17. package/app/core/attachments.py +623 -623
  18. package/app/core/audit.py +30 -30
  19. package/app/core/backend_profiles.py +188 -188
  20. package/app/core/backup.py +470 -470
  21. package/app/core/beekeeper.py +183 -183
  22. package/app/core/benchstore.py +102 -102
  23. package/app/core/board.py +21 -17
  24. package/app/core/bookmeta.py +1036 -1036
  25. package/app/core/bookmeta_catalog.py +180 -180
  26. package/app/core/branching.py +137 -137
  27. package/app/core/builtin_agent.py +13 -4
  28. package/app/core/capability.py +144 -144
  29. package/app/core/catalog.py +28 -6
  30. package/app/core/chaptersafe.py +32 -32
  31. package/app/core/checkpoints.py +117 -31
  32. package/app/core/cleanup.py +303 -303
  33. package/app/core/command_auth.py +302 -302
  34. package/app/core/compaction.py +201 -201
  35. package/app/core/contracts.py +255 -255
  36. package/app/core/covergen.py +356 -356
  37. package/app/core/defectretro.py +43 -43
  38. package/app/core/diagnostics.py +114 -114
  39. package/app/core/dispatch.py +1 -1
  40. package/app/core/dispatch_log.py +128 -128
  41. package/app/core/env_scrub.py +85 -85
  42. package/app/core/errorlog.py +137 -137
  43. package/app/core/eval_matrix.py +91 -82
  44. package/app/core/evaluation.py +174 -174
  45. package/app/core/failure_notify.py +290 -290
  46. package/app/core/flow_graph.py +33 -33
  47. package/app/core/goal_service.py +167 -167
  48. package/app/core/health.py +389 -389
  49. package/app/core/history.py +38 -38
  50. package/app/core/hooks.py +162 -162
  51. package/app/core/knowledge_pipeline.py +86 -86
  52. package/app/core/manager.py +2385 -2385
  53. package/app/core/mcp_client.py +7 -2
  54. package/app/core/mocks.py +64 -64
  55. package/app/core/notify.py +201 -201
  56. package/app/core/novel_quality.py +181 -181
  57. package/app/core/openapi.py +217 -209
  58. package/app/core/operations.py +228 -228
  59. package/app/core/paihang.py +145 -145
  60. package/app/core/pipeline.py +6 -3
  61. package/app/core/policy.py +9 -0
  62. package/app/core/portguard.py +111 -111
  63. package/app/core/presence.py +77 -77
  64. package/app/core/preview.py +293 -293
  65. package/app/core/project_memory.py +206 -206
  66. package/app/core/prompt_guard.py +78 -78
  67. package/app/core/publish/__init__.py +7 -7
  68. package/app/core/publish/auto.py +659 -562
  69. package/app/core/publish/chaprows.py +138 -138
  70. package/app/core/publish/fanqie.py +16 -10
  71. package/app/core/publish/flow.py +29 -1
  72. package/app/core/publish/flows-fanqie-calibrated.json +442 -442
  73. package/app/core/publish/manager.py +1185 -1177
  74. package/app/core/publish/qimao.py +193 -193
  75. package/app/core/publish/volumes.py +108 -108
  76. package/app/core/publish/ws.py +139 -139
  77. package/app/core/quality_gate.py +201 -201
  78. package/app/core/redact.py +38 -38
  79. package/app/core/repeat_guard.py +129 -129
  80. package/app/core/retrieval.py +137 -137
  81. package/app/core/sandbox_runtime.py +95 -0
  82. package/app/core/selfupdate.py +384 -384
  83. package/app/core/session_log.py +161 -161
  84. package/app/core/sessions.py +312 -312
  85. package/app/core/settings.py +215 -215
  86. package/app/core/settings_schema.py +282 -282
  87. package/app/core/share_page.py +114 -114
  88. package/app/core/skill_scan.py +139 -139
  89. package/app/core/skillpacks/market/character-bible.md +66 -66
  90. package/app/core/skillpacks/market/code-risk-checklist.md +58 -58
  91. package/app/core/skillpacks/market/git-workflow.md +57 -57
  92. package/app/core/skillpacks/market/release-notes.md +72 -72
  93. package/app/core/skillpacks/market/weekly-report.md +71 -71
  94. package/app/core/skillpacks/market/worldview-consistency.md +70 -70
  95. package/app/core/step_runner.py +132 -132
  96. package/app/core/store.py +13 -3
  97. package/app/core/story_tracking.py +275 -275
  98. package/app/core/task_compile.py +199 -199
  99. package/app/core/telemetry.py +292 -292
  100. package/app/core/tlsctx.py +64 -64
  101. package/app/core/token_meter.py +147 -147
  102. package/app/core/tool_outputs.py +107 -107
  103. package/app/core/tracing.py +207 -207
  104. package/app/core/upstream.py +41 -41
  105. package/app/core/usage.py +1038 -1038
  106. package/app/core/volumes.py +389 -389
  107. package/app/core/webhooks.py +89 -89
  108. package/app/core/wxdigest.py +865 -865
  109. package/app/core/zentao.py +2692 -2692
  110. package/app/main.py +1 -0
  111. package/app/mcp_server.py +244 -244
  112. package/app/output/_createbook_body.json +1 -0
  113. package/app/output/_probe_fq_click.py +50 -0
  114. package/app/output/_probe_fq_form.py +42 -0
  115. package/app/output/_probe_fq_modal.py +55 -0
  116. package/app/output/_probe_fq_points.py +71 -0
  117. package/app/output/_probe_fq_submit.py +34 -0
  118. package/app/output/_probe_fq_watch.py +62 -0
  119. package/app/output/workbench-clean-preview.jpg +0 -0
  120. package/app/output/workbench-reference-render.png +0 -0
  121. package/app/output/workbench-shell.png +0 -0
  122. package/app/pick_dialog.py +110 -110
  123. package/app/ui/app.js +165 -29
  124. package/app/ui/artdiff.js +74 -74
  125. package/app/ui/hive3d.js +491 -223
  126. package/app/ui/i18n.js +18 -1
  127. package/app/ui/icons/bee.svg +79 -79
  128. package/app/ui/index.html +24 -4
  129. package/app/ui/manifest.json +16 -16
  130. package/app/ui/qrcode.js +2297 -2297
  131. package/app/ui/style.css +548 -18
  132. package/bin/tutti.js +147 -147
  133. package/package.json +1 -1
  134. package/tools/wx_reader.py +261 -261
@@ -1,209 +1,217 @@
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
- "BackendProfile": {"type": "object", "required": ["label", "command"], "properties": {
55
- "id": {"type": "string"}, "agent_id": {"type": "string"},
56
- "label": {"type": "string", "maxLength": 80}, "command": {"type": "string", "maxLength": 500},
57
- "args": {"type": "array", "maxItems": 80, "items": {"type": "string"}},
58
- "env": {"type": "object", "additionalProperties": {"type": "string"}},
59
- "workspace_path": {"type": "string"}, "enabled": {"type": "boolean"}}},
60
- "CommandAuth": {"type": "object", "properties": {
61
- "mode": {"type": "string", "enum": ["legacy", "restricted"]},
62
- "pending": {"type": "array"}, "rules": {"type": "array"}, "audit": {"type": "array"}}},
63
- }
64
-
65
- def body(schema):
66
- return {"required": True, "content": {"application/json": {"schema": schema}}}
67
-
68
- def response(description, schema=None):
69
- out = {"description": description}
70
- if schema is not None:
71
- out["content"] = {"application/json": {"schema": schema}}
72
- return out
73
-
74
- ref = lambda name: {"$ref": "#/components/schemas/" + name}
75
- security = [{"codebeeToken": []}, {"codebeeQueryToken": []}]
76
- errors = {code: response(desc, ref("Error")) for code, desc in (
77
- ("400", "请求无效"), ("401", "缺少或错误的访问令牌"),
78
- ("404", "资源不存在"), ("409", "状态冲突或审批未完成"),
79
- ("423", "其他设备持有控制权"))}
80
- ok = response("成功", {"type": "object", "properties": {"ok": {"type": "boolean"}}})
81
-
82
- paths = {
83
- "/api/tasks": {"post": {"summary": "创建并启动任务", "security": security,
84
- "requestBody": body(ref("TaskCreate")),
85
- "responses": {"200": response("已排队", ref("TaskResult")),
86
- "503": response("运行记录或入队失败", ref("Error")), **errors}}},
87
- "/api/a2a/tasks": {"post": {"summary": "A2A-lite 创建任务", "security": security,
88
- "requestBody": body(ref("TaskCreate")),
89
- "responses": {"200": response("已排队", ref("TaskResult")), "400": errors["400"],
90
- "401": errors["401"], "423": errors["423"]}}},
91
- "/api/a2a/tasks/{task_id}": {"get": {"summary": "A2A-lite 读取任务状态", "security": security,
92
- "responses": {"200": response("任务、运行和契约", {"type": "object"}),
93
- "401": errors["401"], "404": errors["404"]}}},
94
- "/api/tasks/{task_id}/detail": {"get": {"summary": "读取任务详情和契约", "security": security,
95
- "responses": {"200": response("任务详情", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
96
- "/api/tasks/{task_id}/contract": {
97
- "get": {"summary": "读取任务契约", "security": security,
98
- "responses": {"200": response("契约", ref("Contract")), "401": errors["401"], "404": errors["404"]}},
99
- "post": {"summary": "更新契约、追加证据或审批任务", "security": security,
100
- "requestBody": body({"type": "object", "properties": {
101
- "op": {"type": "string", "enum": ["update", "create", "evidence", "approve", "reject", "blocked"]},
102
- "acceptance_criteria": {"type": "array", "items": {"type": "string"}},
103
- "approval_required": {"type": "boolean"}, "evidence": ref("Evidence"),
104
- "note": {"type": "string", "maxLength": 1000}, "reason": {"type": "string", "maxLength": 1000}}}),
105
- "responses": {"200": response("契约已更新", {"type": "object", "properties": {"contract": ref("Contract")}}), **errors}}},
106
- "/api/tasks/{task_id}/story-tracking": {
107
- "get": {"summary": "读取小说追踪状态", "security": security,
108
- "responses": {"200": response("追踪状态", ref("StoryTrackingResult")), "401": errors["401"],
109
- "404": errors["404"], "409": errors["409"]}},
110
- "post": {"summary": "提交章节结构化状态", "security": security, "requestBody": body(ref("StoryChapter")),
111
- "responses": {"200": response("追踪状态已更新", ref("StoryTrackingResult")), **errors}}},
112
- "/api/agents/presence": {
113
- "get": {"summary": "Agent 在线状态", "security": security,
114
- "responses": {"200": response("在线 Agent 列表", {"type": "object"}), "401": errors["401"]}},
115
- "post": {"summary": "Agent 心跳", "security": security, "requestBody": body(ref("Presence")),
116
- "responses": {"200": response("心跳已记录", {"type": "object"}), "400": errors["400"],
117
- "401": errors["401"], "423": errors["423"]}}},
118
- "/api/backend-profiles": {
119
- "get": {"summary": "读取 ACP Backend Profiles(密钥脱敏)", "security": security,
120
- "responses": {"200": response("Profiles", {"type": "object"}), "401": errors["401"]}},
121
- "post": {"summary": "保存 ACP Backend Profile", "security": security,
122
- "requestBody": body(ref("BackendProfile")),
123
- "responses": {"200": response("Profile", {"type": "object"}), "400": errors["400"], "401": errors["401"]}}},
124
- "/api/backend-profiles/{profile_id}/delete": {
125
- "post": {"summary": "删除 ACP Backend Profile", "security": security,
126
- "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"]}}},
127
- "/api/command-auth": {
128
- "get": {"summary": "读取命令授权策略与待处理请求", "security": security,
129
- "responses": {"200": response("Authorization state", ref("CommandAuth")), "401": errors["401"]}},
130
- "post": {"summary": "切换命令授权策略", "security": security,
131
- "requestBody": body({"type": "object", "properties": {"mode": {"type": "string", "enum": ["legacy", "restricted"]}}}),
132
- "responses": {"200": response("Authorization state", ref("CommandAuth")), "400": errors["400"], "401": errors["401"]}}},
133
- "/api/command-auth/requests/{request_id}": {
134
- "post": {"summary": "批准或拒绝等待中的命令", "security": security,
135
- "requestBody": body({"type": "object", "required": ["approve"], "properties": {
136
- "approve": {"type": "boolean"}, "scope": {"type": "string"}, "match": {"type": "string"}, "prefix": {"type": "string"}}}),
137
- "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"]}}},
138
- "/api/command-auth/rules/{rule_id}/revoke": {
139
- "post": {"summary": "撤销命令授权规则", "security": security,
140
- "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"]}}},
141
- "/api/retrieval/search": {"get": {"summary": "本地检索", "security": security,
142
- "parameters": [{"name": "q", "in": "query", "required": True,
143
- "schema": {"type": "string", "maxLength": 500}},
144
- {"name": "limit", "in": "query",
145
- "schema": {"type": "integer", "minimum": 1, "maximum": 50}}],
146
- "responses": {"200": response("检索结果", {"type": "object"}), "400": errors["400"], "401": errors["401"]}}},
147
- "/api/retrieval/index": {"post": {"summary": "为配置工作区/任务目录建立本地检索索引", "security": security,
148
- "requestBody": body({"type": "object", "properties": {
149
- "source": {"type": "string"}, "text": {"type": "string"}, "metadata": {"type": "object"},
150
- "doc_id": {"type": "string"}, "root": {"type": "string"}, "task_id": {"type": "string"},
151
- "limit": {"type": "integer", "minimum": 1, "maximum": 500}}}),
152
- "responses": {"200": response("索引已更新", {"type": "object"}), "400": errors["400"],
153
- "401": errors["401"], "404": errors["404"], "423": errors["423"]}}},
154
- "/api/analytics": {"get": {"summary": "任务成本质量分析", "security": security,
155
- "responses": {"200": response("分析摘要", {"type": "object"}), "401": errors["401"]}}},
156
- "/api/runs/{run_id}": {"get": {"summary": "读取运行状态", "security": security,
157
- "responses": {"200": response("运行状态", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
158
- "/api/runs/{run_id}/trace": {"get": {"summary": "读取脱敏 trace", "security": security,
159
- "responses": {"200": response("Trace", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
160
- "/api/runs/{run_id}/otel": {"get": {"summary": "导出 OTLP JSON trace", "security": security,
161
- "responses": {"200": response("OTLP trace", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
162
- "/api/runs/{run_id}/checkpoints": {"get": {"summary": "读取 checkpoint 回放预览", "security": security,
163
- "responses": {"200": response("Checkpoint", {"type": "object"}), "401": errors["401"]}}},
164
- "/api/flows/{flow_id}/graph": {"get": {"summary": "读取流程图投影", "security": security,
165
- "responses": {"200": response("Flow graph", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
166
- "/api/hooks/run": {"post": {"summary": "Webhook 触发任务(可选 HMAC)", "security": security,
167
- "requestBody": body(ref("TaskCreate")),
168
- "responses": {"200": response("已排队", ref("TaskResult")), "401": errors["401"], "403": errors["401"], "400": errors["400"]}}},
169
- "/api/eval-matrix/normalize": {"post": {"summary": "规范化评测矩阵 manifest", "security": security,
170
- "requestBody": body({"type": "object"}), "responses": {"200": response("Manifest", {"type": "object"}), "400": errors["400"]}}},
171
- "/api/eval-matrix/evaluate": {"post": {"summary": "对比评测矩阵与 baseline", "security": security,
172
- "requestBody": body({"type": "object"}), "responses": {"200": response("Report", {"type": "object"}), "400": errors["400"]}}},
173
- "/api/knowledge/pipeline": {"get": {"summary": "读取知识管线质量报告", "security": security,
174
- "parameters": [{"name": "ingest_id", "in": "query", "schema": {"type": "string"}}],
175
- "responses": {"200": response("Quality report", {"type": "object"})}},
176
- "post": {"summary": "分块并建立知识索引", "security": security,
177
- "requestBody": body({"type": "object"}), "responses": {"200": response("Ingest report", {"type": "object"}), "400": errors["400"]}}},
178
- "/api/policy": {"get": {"summary": "读取规范化沙箱策略", "security": security,
179
- "parameters": [{"name": "workdir", "in": "query", "schema": {"type": "string"}}],
180
- "responses": {"200": response("Sandbox policy", {"type": "object"})}}},
181
- "/api/runs/{run_id}/resume_now": {"post": {"summary": "立即重试运行", "security": security,
182
- "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"], "423": errors["423"]}}},
183
- "/api/control": {
184
- "get": {"summary": "读取当前控制权", "security": security,
185
- "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}},
186
- "post": {"summary": "接管或释放控制权", "security": security,
187
- "requestBody": body({"type": "object", "required": ["action"], "properties": {
188
- "action": {"type": "string", "enum": ["acquire", "release"]},
189
- "force": {"type": "boolean"}}}),
190
- "responses": {"200": response("控制权已更新", {"type": "object"}),
191
- "400": errors["400"], "401": errors["401"], "423": errors["423"]}}},
192
- "/api/control/heartbeat": {
193
- "get": {"summary": "续期当前控制权", "security": security,
194
- "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}},
195
- "post": {"summary": "续期当前控制权", "security": security,
196
- "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}}},
197
- "/api/openapi.json": {"get": {"summary": "读取 OpenAPI 文档", "security": security,
198
- "responses": {"200": response("OpenAPI 文档", {"type": "object"}), "401": errors["401"]}}},
199
- "/api/health": {"get": {"summary": "读取服务健康状态", "security": security,
200
- "responses": {"200": response("健康状态", {"type": "object"}), "401": errors["401"]}}},
201
- "/api/state": {"get": {"summary": "读取任务状态聚合", "security": security,
202
- "responses": {"200": response("状态聚合", {"type": "object"}), "401": errors["401"]}}},
203
- }
204
- return {"openapi": "3.0.3", "info": {"title": "CodeBee API", "version": "1.0",
205
- "description": "本机/局域网 API。远程请求需 X-CodeBee-Token 或 token 查询参数;本机 loopback 默认免令牌。"},
206
- "servers": [{"url": "/"}], "components": {"securitySchemes": {
207
- "codebeeToken": {"type": "apiKey", "in": "header", "name": "X-CodeBee-Token"},
208
- "codebeeQueryToken": {"type": "apiKey", "in": "query", "name": "token"}},
209
- "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
+ "sandbox": {"type": "object", "properties": {
16
+ "backend": {"type": "string", "enum": ["native", "docker"]},
17
+ "docker_image": {"type": "string", "maxLength": 240},
18
+ "allowed_roots": {"type": "array", "maxItems": 16,
19
+ "items": {"type": "string", "maxLength": 1024}},
20
+ "env_allowlist": {"type": "array", "maxItems": 64,
21
+ "items": {"type": "string", "maxLength": 128}},
22
+ "network": {"type": "boolean"}, "timeout_s": {"type": "integer"}}},
23
+ "acceptance_criteria": {"type": "array", "maxItems": 40,
24
+ "items": {"type": "string", "maxLength": 500}},
25
+ "approval_required": {"type": "boolean"}}},
26
+ "TaskResult": {"type": "object", "required": ["task_id", "run_id"], "properties": {
27
+ "task_id": {"type": "string"}, "run_id": {"type": "string"}}},
28
+ "Evidence": {"type": "object", "required": ["status"], "properties": {
29
+ "id": {"type": "string"}, "criterion": {"type": "string", "maxLength": 500},
30
+ "status": {"type": "string", "enum": ["passed", "failed", "unknown", "not_evaluated"]},
31
+ "summary": {"type": "string", "maxLength": 2000},
32
+ "source": {"type": "string", "maxLength": 80}, "created_at": {"type": "string"}}},
33
+ "Contract": {"type": "object", "properties": {
34
+ "task_id": {"type": "string"},
35
+ "acceptance_criteria": {"type": "array", "items": {"type": "string"}},
36
+ "evidence": {"type": "array", "items": {"$ref": "#/components/schemas/Evidence"}},
37
+ "approval_required": {"type": "boolean"}, "approval": {"type": "object"},
38
+ "blocked_reason": {"type": "string"}, "completion_receipt": {"type": "object"}}},
39
+ "StoryChapter": {"type": "object", "properties": {
40
+ "op": {"type": "string"},
41
+ "chapter": {"type": "integer", "minimum": 1, "maximum": 5000},
42
+ "outline": {"type": "string", "maxLength": 12000}, "prose": {"type": "string"},
43
+ "facts": {"type": "array", "items": {"type": "string"}},
44
+ "characters": {"type": "array", "items": {"type": "string"}},
45
+ "timeline": {"type": "array", "items": {"type": "string"}},
46
+ "foreshadowing": {"type": "array", "items": {"type": "object"}},
47
+ "next_promises": {"type": "array", "items": {"type": "string"}},
48
+ "author_truth": {"type": "array", "items": {"type": "string"}},
49
+ "reader_known": {"type": "array", "items": {"type": "string"}}},
50
+ "oneOf": [
51
+ {"required": ["op"], "properties": {"op": {"const": "init"}}},
52
+ {"required": ["chapter", "outline", "prose"]},
53
+ ]},
54
+ "StoryTrackingResult": {"type": "object", "properties": {
55
+ "state": {"type": "object"}, "check": {"type": "object"}}},
56
+ "Presence": {"type": "object", "required": ["agent_id"], "properties": {
57
+ "agent_id": {"type": "string", "maxLength": 100}, "label": {"type": "string", "maxLength": 120},
58
+ "capabilities": {"type": "array", "maxItems": 30,
59
+ "items": {"type": "string", "maxLength": 80}},
60
+ "task_id": {"type": "string", "maxLength": 100}, "status": {"type": "string", "maxLength": 30},
61
+ "metadata": {"type": "object"}}},
62
+ "BackendProfile": {"type": "object", "required": ["label", "command"], "properties": {
63
+ "id": {"type": "string"}, "agent_id": {"type": "string"},
64
+ "label": {"type": "string", "maxLength": 80}, "command": {"type": "string", "maxLength": 500},
65
+ "args": {"type": "array", "maxItems": 80, "items": {"type": "string"}},
66
+ "env": {"type": "object", "additionalProperties": {"type": "string"}},
67
+ "workspace_path": {"type": "string"}, "enabled": {"type": "boolean"}}},
68
+ "CommandAuth": {"type": "object", "properties": {
69
+ "mode": {"type": "string", "enum": ["legacy", "restricted"]},
70
+ "pending": {"type": "array"}, "rules": {"type": "array"}, "audit": {"type": "array"}}},
71
+ }
72
+
73
+ def body(schema):
74
+ return {"required": True, "content": {"application/json": {"schema": schema}}}
75
+
76
+ def response(description, schema=None):
77
+ out = {"description": description}
78
+ if schema is not None:
79
+ out["content"] = {"application/json": {"schema": schema}}
80
+ return out
81
+
82
+ ref = lambda name: {"$ref": "#/components/schemas/" + name}
83
+ security = [{"codebeeToken": []}, {"codebeeQueryToken": []}]
84
+ errors = {code: response(desc, ref("Error")) for code, desc in (
85
+ ("400", "请求无效"), ("401", "缺少或错误的访问令牌"),
86
+ ("404", "资源不存在"), ("409", "状态冲突或审批未完成"),
87
+ ("423", "其他设备持有控制权"))}
88
+ ok = response("成功", {"type": "object", "properties": {"ok": {"type": "boolean"}}})
89
+
90
+ paths = {
91
+ "/api/tasks": {"post": {"summary": "创建并启动任务", "security": security,
92
+ "requestBody": body(ref("TaskCreate")),
93
+ "responses": {"200": response("已排队", ref("TaskResult")),
94
+ "503": response("运行记录或入队失败", ref("Error")), **errors}}},
95
+ "/api/a2a/tasks": {"post": {"summary": "A2A-lite 创建任务", "security": security,
96
+ "requestBody": body(ref("TaskCreate")),
97
+ "responses": {"200": response("已排队", ref("TaskResult")), "400": errors["400"],
98
+ "401": errors["401"], "423": errors["423"]}}},
99
+ "/api/a2a/tasks/{task_id}": {"get": {"summary": "A2A-lite 读取任务状态", "security": security,
100
+ "responses": {"200": response("任务、运行和契约", {"type": "object"}),
101
+ "401": errors["401"], "404": errors["404"]}}},
102
+ "/api/tasks/{task_id}/detail": {"get": {"summary": "读取任务详情和契约", "security": security,
103
+ "responses": {"200": response("任务详情", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
104
+ "/api/tasks/{task_id}/contract": {
105
+ "get": {"summary": "读取任务契约", "security": security,
106
+ "responses": {"200": response("契约", ref("Contract")), "401": errors["401"], "404": errors["404"]}},
107
+ "post": {"summary": "更新契约、追加证据或审批任务", "security": security,
108
+ "requestBody": body({"type": "object", "properties": {
109
+ "op": {"type": "string", "enum": ["update", "create", "evidence", "approve", "reject", "blocked"]},
110
+ "acceptance_criteria": {"type": "array", "items": {"type": "string"}},
111
+ "approval_required": {"type": "boolean"}, "evidence": ref("Evidence"),
112
+ "note": {"type": "string", "maxLength": 1000}, "reason": {"type": "string", "maxLength": 1000}}}),
113
+ "responses": {"200": response("契约已更新", {"type": "object", "properties": {"contract": ref("Contract")}}), **errors}}},
114
+ "/api/tasks/{task_id}/story-tracking": {
115
+ "get": {"summary": "读取小说追踪状态", "security": security,
116
+ "responses": {"200": response("追踪状态", ref("StoryTrackingResult")), "401": errors["401"],
117
+ "404": errors["404"], "409": errors["409"]}},
118
+ "post": {"summary": "提交章节结构化状态", "security": security, "requestBody": body(ref("StoryChapter")),
119
+ "responses": {"200": response("追踪状态已更新", ref("StoryTrackingResult")), **errors}}},
120
+ "/api/agents/presence": {
121
+ "get": {"summary": "Agent 在线状态", "security": security,
122
+ "responses": {"200": response("在线 Agent 列表", {"type": "object"}), "401": errors["401"]}},
123
+ "post": {"summary": "Agent 心跳", "security": security, "requestBody": body(ref("Presence")),
124
+ "responses": {"200": response("心跳已记录", {"type": "object"}), "400": errors["400"],
125
+ "401": errors["401"], "423": errors["423"]}}},
126
+ "/api/backend-profiles": {
127
+ "get": {"summary": "读取 ACP Backend Profiles(密钥脱敏)", "security": security,
128
+ "responses": {"200": response("Profiles", {"type": "object"}), "401": errors["401"]}},
129
+ "post": {"summary": "保存 ACP Backend Profile", "security": security,
130
+ "requestBody": body(ref("BackendProfile")),
131
+ "responses": {"200": response("Profile", {"type": "object"}), "400": errors["400"], "401": errors["401"]}}},
132
+ "/api/backend-profiles/{profile_id}/delete": {
133
+ "post": {"summary": "删除 ACP Backend Profile", "security": security,
134
+ "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"]}}},
135
+ "/api/command-auth": {
136
+ "get": {"summary": "读取命令授权策略与待处理请求", "security": security,
137
+ "responses": {"200": response("Authorization state", ref("CommandAuth")), "401": errors["401"]}},
138
+ "post": {"summary": "切换命令授权策略", "security": security,
139
+ "requestBody": body({"type": "object", "properties": {"mode": {"type": "string", "enum": ["legacy", "restricted"]}}}),
140
+ "responses": {"200": response("Authorization state", ref("CommandAuth")), "400": errors["400"], "401": errors["401"]}}},
141
+ "/api/command-auth/requests/{request_id}": {
142
+ "post": {"summary": "批准或拒绝等待中的命令", "security": security,
143
+ "requestBody": body({"type": "object", "required": ["approve"], "properties": {
144
+ "approve": {"type": "boolean"}, "scope": {"type": "string"}, "match": {"type": "string"}, "prefix": {"type": "string"}}}),
145
+ "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"]}}},
146
+ "/api/command-auth/rules/{rule_id}/revoke": {
147
+ "post": {"summary": "撤销命令授权规则", "security": security,
148
+ "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"]}}},
149
+ "/api/retrieval/search": {"get": {"summary": "本地检索", "security": security,
150
+ "parameters": [{"name": "q", "in": "query", "required": True,
151
+ "schema": {"type": "string", "maxLength": 500}},
152
+ {"name": "limit", "in": "query",
153
+ "schema": {"type": "integer", "minimum": 1, "maximum": 50}}],
154
+ "responses": {"200": response("检索结果", {"type": "object"}), "400": errors["400"], "401": errors["401"]}}},
155
+ "/api/retrieval/index": {"post": {"summary": "为配置工作区/任务目录建立本地检索索引", "security": security,
156
+ "requestBody": body({"type": "object", "properties": {
157
+ "source": {"type": "string"}, "text": {"type": "string"}, "metadata": {"type": "object"},
158
+ "doc_id": {"type": "string"}, "root": {"type": "string"}, "task_id": {"type": "string"},
159
+ "limit": {"type": "integer", "minimum": 1, "maximum": 500}}}),
160
+ "responses": {"200": response("索引已更新", {"type": "object"}), "400": errors["400"],
161
+ "401": errors["401"], "404": errors["404"], "423": errors["423"]}}},
162
+ "/api/analytics": {"get": {"summary": "任务成本质量分析", "security": security,
163
+ "responses": {"200": response("分析摘要", {"type": "object"}), "401": errors["401"]}}},
164
+ "/api/runs/{run_id}": {"get": {"summary": "读取运行状态", "security": security,
165
+ "responses": {"200": response("运行状态", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
166
+ "/api/runs/{run_id}/trace": {"get": {"summary": "读取脱敏 trace", "security": security,
167
+ "responses": {"200": response("Trace", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
168
+ "/api/runs/{run_id}/otel": {"get": {"summary": "导出 OTLP JSON trace", "security": security,
169
+ "responses": {"200": response("OTLP trace", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
170
+ "/api/runs/{run_id}/checkpoints": {"get": {"summary": "读取 checkpoint 回放预览", "security": security,
171
+ "responses": {"200": response("Checkpoint", {"type": "object"}), "401": errors["401"]}}},
172
+ "/api/flows/{flow_id}/graph": {"get": {"summary": "读取流程图投影", "security": security,
173
+ "responses": {"200": response("Flow graph", {"type": "object"}), "401": errors["401"], "404": errors["404"]}}},
174
+ "/api/hooks/run": {"post": {"summary": "Webhook 触发任务(可选 HMAC)", "security": security,
175
+ "requestBody": body(ref("TaskCreate")),
176
+ "responses": {"200": response("已排队", ref("TaskResult")), "401": errors["401"], "403": errors["401"], "400": errors["400"]}}},
177
+ "/api/eval-matrix/normalize": {"post": {"summary": "规范化评测矩阵 manifest", "security": security,
178
+ "requestBody": body({"type": "object"}), "responses": {"200": response("Manifest", {"type": "object"}), "400": errors["400"]}}},
179
+ "/api/eval-matrix/evaluate": {"post": {"summary": "对比评测矩阵与 baseline", "security": security,
180
+ "requestBody": body({"type": "object"}), "responses": {"200": response("Report", {"type": "object"}), "400": errors["400"]}}},
181
+ "/api/knowledge/pipeline": {"get": {"summary": "读取知识管线质量报告", "security": security,
182
+ "parameters": [{"name": "ingest_id", "in": "query", "schema": {"type": "string"}}],
183
+ "responses": {"200": response("Quality report", {"type": "object"})}},
184
+ "post": {"summary": "分块并建立知识索引", "security": security,
185
+ "requestBody": body({"type": "object"}), "responses": {"200": response("Ingest report", {"type": "object"}), "400": errors["400"]}}},
186
+ "/api/policy": {"get": {"summary": "读取规范化沙箱策略", "security": security,
187
+ "parameters": [{"name": "workdir", "in": "query", "schema": {"type": "string"}}],
188
+ "responses": {"200": response("Sandbox policy", {"type": "object"})}}},
189
+ "/api/runs/{run_id}/resume_now": {"post": {"summary": "立即重试运行", "security": security,
190
+ "responses": {"200": ok, "400": errors["400"], "401": errors["401"], "404": errors["404"], "423": errors["423"]}}},
191
+ "/api/control": {
192
+ "get": {"summary": "读取当前控制权", "security": security,
193
+ "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}},
194
+ "post": {"summary": "接管或释放控制权", "security": security,
195
+ "requestBody": body({"type": "object", "required": ["action"], "properties": {
196
+ "action": {"type": "string", "enum": ["acquire", "release"]},
197
+ "force": {"type": "boolean"}}}),
198
+ "responses": {"200": response("控制权已更新", {"type": "object"}),
199
+ "400": errors["400"], "401": errors["401"], "423": errors["423"]}}},
200
+ "/api/control/heartbeat": {
201
+ "get": {"summary": "续期当前控制权", "security": security,
202
+ "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}},
203
+ "post": {"summary": "续期当前控制权", "security": security,
204
+ "responses": {"200": response("控制权状态", {"type": "object"}), "401": errors["401"]}}},
205
+ "/api/openapi.json": {"get": {"summary": "读取 OpenAPI 文档", "security": security,
206
+ "responses": {"200": response("OpenAPI 文档", {"type": "object"}), "401": errors["401"]}}},
207
+ "/api/health": {"get": {"summary": "读取服务健康状态", "security": security,
208
+ "responses": {"200": response("健康状态", {"type": "object"}), "401": errors["401"]}}},
209
+ "/api/state": {"get": {"summary": "读取任务状态聚合", "security": security,
210
+ "responses": {"200": response("状态聚合", {"type": "object"}), "401": errors["401"]}}},
211
+ }
212
+ return {"openapi": "3.0.3", "info": {"title": "CodeBee API", "version": "1.0",
213
+ "description": "本机/局域网 API。远程请求需 X-CodeBee-Token 或 token 查询参数;本机 loopback 默认免令牌。"},
214
+ "servers": [{"url": "/"}], "components": {"securitySchemes": {
215
+ "codebeeToken": {"type": "apiKey", "in": "header", "name": "X-CodeBee-Token"},
216
+ "codebeeQueryToken": {"type": "apiKey", "in": "query", "name": "token"}},
217
+ "schemas": schemas}, "paths": paths}