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.
- package/CHANGELOG.md +14 -0
- package/LICENSE +21 -21
- package/README.md +3 -6
- package/app/.playwright-cli/console-2026-09-23T08-26-03-635Z.log +88 -0
- package/app/.playwright-cli/page-2026-09-23T08-26-03-845Z.yml +126 -0
- package/app/.playwright-cli/page-2026-09-23T08-29-44-203Z.png +0 -0
- package/app/.playwright-cli/page-2026-09-23T08-35-42-046Z.yml +210 -0
- package/app/.playwright-cli/page-2026-09-23T08-36-52-858Z.png +0 -0
- package/app/.playwright-cli/page-2026-09-23T08-37-33-938Z.png +0 -0
- package/app/.playwright-cli/run-detail-after.png +0 -0
- package/app/core/acceptance.py +100 -100
- package/app/core/acp_client.py +457 -426
- package/app/core/aiflavor.py +197 -197
- package/app/core/analytics.py +38 -38
- package/app/core/artifacts.py +148 -148
- package/app/core/assets.py +110 -110
- package/app/core/attachments.py +623 -623
- package/app/core/audit.py +30 -30
- package/app/core/backend_profiles.py +188 -188
- package/app/core/backup.py +470 -470
- package/app/core/beekeeper.py +183 -183
- package/app/core/benchstore.py +102 -102
- package/app/core/board.py +21 -17
- package/app/core/bookmeta.py +1036 -1036
- package/app/core/bookmeta_catalog.py +180 -180
- package/app/core/branching.py +137 -137
- package/app/core/builtin_agent.py +13 -4
- package/app/core/capability.py +144 -144
- package/app/core/catalog.py +28 -6
- package/app/core/chaptersafe.py +32 -32
- package/app/core/checkpoints.py +117 -31
- package/app/core/cleanup.py +303 -303
- package/app/core/command_auth.py +302 -302
- package/app/core/compaction.py +201 -201
- package/app/core/contracts.py +255 -255
- package/app/core/covergen.py +356 -356
- package/app/core/defectretro.py +43 -43
- package/app/core/diagnostics.py +114 -114
- package/app/core/dispatch.py +1 -1
- package/app/core/dispatch_log.py +128 -128
- package/app/core/env_scrub.py +85 -85
- package/app/core/errorlog.py +137 -137
- package/app/core/eval_matrix.py +91 -82
- package/app/core/evaluation.py +174 -174
- package/app/core/failure_notify.py +290 -290
- package/app/core/flow_graph.py +33 -33
- package/app/core/goal_service.py +167 -167
- package/app/core/health.py +389 -389
- package/app/core/history.py +38 -38
- package/app/core/hooks.py +162 -162
- package/app/core/knowledge_pipeline.py +86 -86
- package/app/core/manager.py +2385 -2385
- package/app/core/mcp_client.py +7 -2
- package/app/core/mocks.py +64 -64
- package/app/core/notify.py +201 -201
- package/app/core/novel_quality.py +181 -181
- package/app/core/openapi.py +217 -209
- package/app/core/operations.py +228 -228
- package/app/core/paihang.py +145 -145
- package/app/core/pipeline.py +6 -3
- package/app/core/policy.py +9 -0
- package/app/core/portguard.py +111 -111
- package/app/core/presence.py +77 -77
- package/app/core/preview.py +293 -293
- package/app/core/project_memory.py +206 -206
- package/app/core/prompt_guard.py +78 -78
- package/app/core/publish/__init__.py +7 -7
- package/app/core/publish/auto.py +659 -562
- package/app/core/publish/chaprows.py +138 -138
- package/app/core/publish/fanqie.py +16 -10
- package/app/core/publish/flow.py +29 -1
- package/app/core/publish/flows-fanqie-calibrated.json +442 -442
- package/app/core/publish/manager.py +1185 -1177
- package/app/core/publish/qimao.py +193 -193
- package/app/core/publish/volumes.py +108 -108
- package/app/core/publish/ws.py +139 -139
- package/app/core/quality_gate.py +201 -201
- package/app/core/redact.py +38 -38
- package/app/core/repeat_guard.py +129 -129
- package/app/core/retrieval.py +137 -137
- package/app/core/sandbox_runtime.py +95 -0
- package/app/core/selfupdate.py +384 -384
- package/app/core/session_log.py +161 -161
- package/app/core/sessions.py +312 -312
- package/app/core/settings.py +215 -215
- package/app/core/settings_schema.py +282 -282
- package/app/core/share_page.py +114 -114
- package/app/core/skill_scan.py +139 -139
- package/app/core/skillpacks/market/character-bible.md +66 -66
- package/app/core/skillpacks/market/code-risk-checklist.md +58 -58
- package/app/core/skillpacks/market/git-workflow.md +57 -57
- package/app/core/skillpacks/market/release-notes.md +72 -72
- package/app/core/skillpacks/market/weekly-report.md +71 -71
- package/app/core/skillpacks/market/worldview-consistency.md +70 -70
- package/app/core/step_runner.py +132 -132
- package/app/core/store.py +13 -3
- package/app/core/story_tracking.py +275 -275
- package/app/core/task_compile.py +199 -199
- package/app/core/telemetry.py +292 -292
- package/app/core/tlsctx.py +64 -64
- package/app/core/token_meter.py +147 -147
- package/app/core/tool_outputs.py +107 -107
- package/app/core/tracing.py +207 -207
- package/app/core/upstream.py +41 -41
- package/app/core/usage.py +1038 -1038
- package/app/core/volumes.py +389 -389
- package/app/core/webhooks.py +89 -89
- package/app/core/wxdigest.py +865 -865
- package/app/core/zentao.py +2692 -2692
- package/app/main.py +1 -0
- package/app/mcp_server.py +244 -244
- package/app/output/_createbook_body.json +1 -0
- package/app/output/_probe_fq_click.py +50 -0
- package/app/output/_probe_fq_form.py +42 -0
- package/app/output/_probe_fq_modal.py +55 -0
- package/app/output/_probe_fq_points.py +71 -0
- package/app/output/_probe_fq_submit.py +34 -0
- package/app/output/_probe_fq_watch.py +62 -0
- package/app/output/workbench-clean-preview.jpg +0 -0
- package/app/output/workbench-reference-render.png +0 -0
- package/app/output/workbench-shell.png +0 -0
- package/app/pick_dialog.py +110 -110
- package/app/ui/app.js +165 -29
- package/app/ui/artdiff.js +74 -74
- package/app/ui/hive3d.js +491 -223
- package/app/ui/i18n.js +18 -1
- package/app/ui/icons/bee.svg +79 -79
- package/app/ui/index.html +24 -4
- package/app/ui/manifest.json +16 -16
- package/app/ui/qrcode.js +2297 -2297
- package/app/ui/style.css +548 -18
- package/bin/tutti.js +147 -147
- package/package.json +1 -1
- package/tools/wx_reader.py +261 -261
package/app/core/presence.py
CHANGED
|
@@ -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
|