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,77 +1,77 @@
1
- """Small local agent presence registry for the operator dashboard."""
2
- from __future__ import annotations
3
-
4
- import json
5
- import threading
6
- import time
7
-
8
- from . import paths
9
-
10
- _LOCK = threading.RLock()
11
- _FILE = paths.DATA_DIR / "agent_presence.json"
12
- _STALE_S = 180
13
-
14
-
15
- def _load():
16
- try:
17
- value = json.loads(_FILE.read_text(encoding="utf-8"))
18
- return value if isinstance(value, dict) else {}
19
- except Exception:
20
- return {}
21
-
22
-
23
- def _save(value):
24
- _FILE.parent.mkdir(parents=True, exist_ok=True)
25
- tmp = _FILE.with_suffix(".tmp")
26
- tmp.write_text(json.dumps(value, ensure_ascii=False, indent=2), encoding="utf-8")
27
- tmp.replace(_FILE)
28
-
29
-
30
- def heartbeat(agent_id, label="", capabilities=None, task_id="", status="idle", metadata=None):
31
- aid = str(agent_id or "").strip()[:100]
32
- if not aid:
33
- raise ValueError("agent_id 必填")
34
- if capabilities is not None and not isinstance(capabilities, list):
35
- raise ValueError("capabilities 必须是列表")
36
- if status is not None and not isinstance(status, str):
37
- raise ValueError("status 必须是文本")
38
- now = time.time()
39
- with _LOCK:
40
- data = _load()
41
- safe_meta = metadata if isinstance(metadata, dict) else {}
42
- # Presence is a hot, user-controlled endpoint; keep the durable
43
- # registry bounded even when an agent sends oversized diagnostics.
44
- safe_meta = {str(k)[:80]: str(v)[:500] for k, v in list(safe_meta.items())[:30]}
45
- data[aid] = {"agent_id": aid, "label": str(label or aid)[:120],
46
- "capabilities": [str(x)[:80] for x in (capabilities or [])][:30],
47
- "task_id": str(task_id or "")[:100], "status": str(status or "idle")[:30],
48
- "metadata": safe_meta,
49
- "last_seen": now}
50
- _save(data)
51
- return data[aid]
52
-
53
-
54
- def list_agents():
55
- now = time.time()
56
- with _LOCK:
57
- rows = []
58
- for row in _load().values():
59
- item = dict(row)
60
- try:
61
- last_seen = float(item.get("last_seen") or 0)
62
- except (TypeError, ValueError):
63
- last_seen = 0.0
64
- age = max(0, now - last_seen)
65
- item["age_s"] = int(age)
66
- item["online"] = age <= _STALE_S
67
- rows.append(item)
68
- return sorted(rows, key=lambda x: (not x["online"], x.get("label") or ""))
69
-
70
-
71
- def remove(agent_id):
72
- with _LOCK:
73
- data = _load()
74
- existed = str(agent_id or "") in data
75
- data.pop(str(agent_id or ""), None)
76
- _save(data)
77
- return existed
1
+ """Small local agent presence registry for the operator dashboard."""
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ import threading
6
+ import time
7
+
8
+ from . import paths
9
+
10
+ _LOCK = threading.RLock()
11
+ _FILE = paths.DATA_DIR / "agent_presence.json"
12
+ _STALE_S = 180
13
+
14
+
15
+ def _load():
16
+ try:
17
+ value = json.loads(_FILE.read_text(encoding="utf-8"))
18
+ return value if isinstance(value, dict) else {}
19
+ except Exception:
20
+ return {}
21
+
22
+
23
+ def _save(value):
24
+ _FILE.parent.mkdir(parents=True, exist_ok=True)
25
+ tmp = _FILE.with_suffix(".tmp")
26
+ tmp.write_text(json.dumps(value, ensure_ascii=False, indent=2), encoding="utf-8")
27
+ tmp.replace(_FILE)
28
+
29
+
30
+ def heartbeat(agent_id, label="", capabilities=None, task_id="", status="idle", metadata=None):
31
+ aid = str(agent_id or "").strip()[:100]
32
+ if not aid:
33
+ raise ValueError("agent_id 必填")
34
+ if capabilities is not None and not isinstance(capabilities, list):
35
+ raise ValueError("capabilities 必须是列表")
36
+ if status is not None and not isinstance(status, str):
37
+ raise ValueError("status 必须是文本")
38
+ now = time.time()
39
+ with _LOCK:
40
+ data = _load()
41
+ safe_meta = metadata if isinstance(metadata, dict) else {}
42
+ # Presence is a hot, user-controlled endpoint; keep the durable
43
+ # registry bounded even when an agent sends oversized diagnostics.
44
+ safe_meta = {str(k)[:80]: str(v)[:500] for k, v in list(safe_meta.items())[:30]}
45
+ data[aid] = {"agent_id": aid, "label": str(label or aid)[:120],
46
+ "capabilities": [str(x)[:80] for x in (capabilities or [])][:30],
47
+ "task_id": str(task_id or "")[:100], "status": str(status or "idle")[:30],
48
+ "metadata": safe_meta,
49
+ "last_seen": now}
50
+ _save(data)
51
+ return data[aid]
52
+
53
+
54
+ def list_agents():
55
+ now = time.time()
56
+ with _LOCK:
57
+ rows = []
58
+ for row in _load().values():
59
+ item = dict(row)
60
+ try:
61
+ last_seen = float(item.get("last_seen") or 0)
62
+ except (TypeError, ValueError):
63
+ last_seen = 0.0
64
+ age = max(0, now - last_seen)
65
+ item["age_s"] = int(age)
66
+ item["online"] = age <= _STALE_S
67
+ rows.append(item)
68
+ return sorted(rows, key=lambda x: (not x["online"], x.get("label") or ""))
69
+
70
+
71
+ def remove(agent_id):
72
+ with _LOCK:
73
+ data = _load()
74
+ existed = str(agent_id or "") in data
75
+ data.pop(str(agent_id or ""), None)
76
+ _save(data)
77
+ return existed