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
@@ -1775,7 +1775,11 @@ def run_agent(agent, prompt, workdir=None, readonly=True,
1775
1775
  bash = find_git_bash()
1776
1776
  if bash:
1777
1777
  base_env.setdefault("CLAUDE_CODE_GIT_BASH_PATH", bash)
1778
- base_env.setdefault("CLAUDE_CODE_MAX_OUTPUT_TOKENS", "16000")
1778
+ # 32000=claude CLI 官方默认(自定义网关模型常见上限):旧值 16000 在
1779
+ # 全局评审读 40 万字书稿时被输出顶爆——CLI 按 16000/轮反复续烧 23.5
1780
+ # 分钟、$3 后报 "response exceeded the 16000 output token maximum"
1781
+ # (2026-10-11 实案×3);setdefault 保留:用户显式配置不覆盖
1782
+ base_env.setdefault("CLAUDE_CODE_MAX_OUTPUT_TOKENS", "32000")
1779
1783
  sid = (resume or "").strip() if agent.get("mode") == "real" else ""
1780
1784
  if sid and kind == "generic" and not agent.get("resume_argv_template"):
1781
1785
  return {"ok": False, "text": "", "json": None, "cost_usd": 0.0, "tokens": 0,
@@ -1,95 +1,95 @@
1
- """Optional process sandbox launchers.
2
-
3
- The default CodeBee install has no container dependency. Docker is an explicit
4
- opt-in backend selected by a task policy and a configured image; this module
5
- only builds argv and never silently falls back to a weaker backend.
6
- """
7
- from __future__ import annotations
8
-
9
- import os
10
- import re
11
- import shutil
12
- from pathlib import Path
13
-
14
-
15
- class SandboxUnavailable(RuntimeError):
16
- pass
17
-
18
-
19
- def requested_backend(sandbox):
20
- value = str((sandbox or {}).get("backend") or "native").strip().lower()
21
- return value or "native"
22
-
23
-
24
- def docker_argv(command, *, sandbox, workdir, image=None, extra_args=(),
25
- container_workdir=None,
26
- container_command=("/bin/sh", "-lc")):
27
- """Build a restricted ``docker run`` argv for a command or stdio server."""
28
- if requested_backend(sandbox) != "docker":
29
- raise SandboxUnavailable("Docker 后端未被任务策略启用")
30
- docker = shutil.which("docker")
31
- if not docker:
32
- raise SandboxUnavailable("当前系统没有可用的 Docker CLI")
33
- root = Path(workdir or ".").expanduser().resolve(strict=True)
34
- image = str(image or (sandbox or {}).get("docker_image") or "").strip()
35
- if not image or len(image) > 240 or not re.match(r"^[A-Za-z0-9][A-Za-z0-9._/:@-]*$", image):
36
- raise SandboxUnavailable("Docker 后端必须配置可信镜像")
37
- roots = []
38
- for value in (sandbox or {}).get("allowed_roots") or [str(root)]:
39
- candidate = Path(value).expanduser().resolve(strict=True)
40
- # Docker currently mounts exactly one root. Require the task workspace
41
- # itself; narrower roots need a separately resolved container cwd and
42
- # must never accidentally broaden into an ancestor mount.
43
- if candidate != root:
44
- raise SandboxUnavailable("Docker 目前只支持挂载任务工作目录")
45
- if candidate not in roots:
46
- roots.append(candidate)
47
- if not roots:
48
- raise SandboxUnavailable("Docker 后端没有允许目录")
49
- selected_root = next((candidate for candidate in roots
50
- if candidate == root or candidate in root.parents
51
- or root in candidate.parents), None)
52
- if selected_root is None:
53
- raise SandboxUnavailable("当前工作目录不在 Docker 允许目录内")
54
- if len(roots) != 1:
55
- raise SandboxUnavailable("Docker 暂只支持一个明确的允许目录")
56
- argv = [docker, "run", "--rm", "--init", "--read-only",
57
- "--security-opt", "no-new-privileges", "--cap-drop=ALL",
58
- "--ipc=none", "--pids-limit", "256", "--memory", "2g", "--cpus", "2",
59
- "--tmpfs", "/tmp:rw,noexec,nosuid,size=64m"]
60
- if hasattr(os, "getuid") and hasattr(os, "getgid"):
61
- argv += ["--user", "%d:%d" % (os.getuid(), os.getgid())]
62
- else:
63
- argv += ["--user", "65534:65534"]
64
- argv += ["--network", "none" if not bool((sandbox or {}).get("network", True)) else "bridge"]
65
- for name in (sandbox or {}).get("env_allowlist") or []:
66
- name = str(name)
67
- if name and name in os.environ:
68
- # Value is supplied through the filtered Docker client environment;
69
- # never place credentials in argv, where process/log inspection sees them.
70
- argv += ["--env", name]
71
- for candidate in roots:
72
- if "," in str(candidate):
73
- raise SandboxUnavailable("Docker 允许目录包含不支持的逗号")
74
- argv += ["--mount", "type=bind,src=%s,dst=/workspace" % str(candidate)]
75
- if container_workdir is None:
76
- rel_workdir = root.relative_to(selected_root).as_posix()
77
- container_workdir = "/workspace" + ("/" + rel_workdir if rel_workdir != "." else "")
78
- if not str(container_workdir).startswith("/") or ".." in Path(container_workdir).parts:
79
- raise SandboxUnavailable("Docker 容器工作目录无效")
80
- argv += ["--workdir", str(container_workdir), *list(extra_args), image]
81
- if isinstance(command, (list, tuple)):
82
- argv += [str(x) for x in command]
83
- else:
84
- argv += list(container_command) + [str(command)]
85
- return argv
86
-
87
-
88
- def docker_env(sandbox):
89
- """Docker receives only explicitly allowed host environment values."""
90
- out = {"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
91
- "HOME": "/tmp", "TMPDIR": "/tmp"}
92
- for name in (sandbox or {}).get("env_allowlist") or []:
93
- if name in os.environ:
94
- out[str(name)] = os.environ[str(name)]
95
- return out
1
+ """Optional process sandbox launchers.
2
+
3
+ The default CodeBee install has no container dependency. Docker is an explicit
4
+ opt-in backend selected by a task policy and a configured image; this module
5
+ only builds argv and never silently falls back to a weaker backend.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ import re
11
+ import shutil
12
+ from pathlib import Path
13
+
14
+
15
+ class SandboxUnavailable(RuntimeError):
16
+ pass
17
+
18
+
19
+ def requested_backend(sandbox):
20
+ value = str((sandbox or {}).get("backend") or "native").strip().lower()
21
+ return value or "native"
22
+
23
+
24
+ def docker_argv(command, *, sandbox, workdir, image=None, extra_args=(),
25
+ container_workdir=None,
26
+ container_command=("/bin/sh", "-lc")):
27
+ """Build a restricted ``docker run`` argv for a command or stdio server."""
28
+ if requested_backend(sandbox) != "docker":
29
+ raise SandboxUnavailable("Docker 后端未被任务策略启用")
30
+ docker = shutil.which("docker")
31
+ if not docker:
32
+ raise SandboxUnavailable("当前系统没有可用的 Docker CLI")
33
+ root = Path(workdir or ".").expanduser().resolve(strict=True)
34
+ image = str(image or (sandbox or {}).get("docker_image") or "").strip()
35
+ if not image or len(image) > 240 or not re.match(r"^[A-Za-z0-9][A-Za-z0-9._/:@-]*$", image):
36
+ raise SandboxUnavailable("Docker 后端必须配置可信镜像")
37
+ roots = []
38
+ for value in (sandbox or {}).get("allowed_roots") or [str(root)]:
39
+ candidate = Path(value).expanduser().resolve(strict=True)
40
+ # Docker currently mounts exactly one root. Require the task workspace
41
+ # itself; narrower roots need a separately resolved container cwd and
42
+ # must never accidentally broaden into an ancestor mount.
43
+ if candidate != root:
44
+ raise SandboxUnavailable("Docker 目前只支持挂载任务工作目录")
45
+ if candidate not in roots:
46
+ roots.append(candidate)
47
+ if not roots:
48
+ raise SandboxUnavailable("Docker 后端没有允许目录")
49
+ selected_root = next((candidate for candidate in roots
50
+ if candidate == root or candidate in root.parents
51
+ or root in candidate.parents), None)
52
+ if selected_root is None:
53
+ raise SandboxUnavailable("当前工作目录不在 Docker 允许目录内")
54
+ if len(roots) != 1:
55
+ raise SandboxUnavailable("Docker 暂只支持一个明确的允许目录")
56
+ argv = [docker, "run", "--rm", "--init", "--read-only",
57
+ "--security-opt", "no-new-privileges", "--cap-drop=ALL",
58
+ "--ipc=none", "--pids-limit", "256", "--memory", "2g", "--cpus", "2",
59
+ "--tmpfs", "/tmp:rw,noexec,nosuid,size=64m"]
60
+ if hasattr(os, "getuid") and hasattr(os, "getgid"):
61
+ argv += ["--user", "%d:%d" % (os.getuid(), os.getgid())]
62
+ else:
63
+ argv += ["--user", "65534:65534"]
64
+ argv += ["--network", "none" if not bool((sandbox or {}).get("network", True)) else "bridge"]
65
+ for name in (sandbox or {}).get("env_allowlist") or []:
66
+ name = str(name)
67
+ if name and name in os.environ:
68
+ # Value is supplied through the filtered Docker client environment;
69
+ # never place credentials in argv, where process/log inspection sees them.
70
+ argv += ["--env", name]
71
+ for candidate in roots:
72
+ if "," in str(candidate):
73
+ raise SandboxUnavailable("Docker 允许目录包含不支持的逗号")
74
+ argv += ["--mount", "type=bind,src=%s,dst=/workspace" % str(candidate)]
75
+ if container_workdir is None:
76
+ rel_workdir = root.relative_to(selected_root).as_posix()
77
+ container_workdir = "/workspace" + ("/" + rel_workdir if rel_workdir != "." else "")
78
+ if not str(container_workdir).startswith("/") or ".." in Path(container_workdir).parts:
79
+ raise SandboxUnavailable("Docker 容器工作目录无效")
80
+ argv += ["--workdir", str(container_workdir), *list(extra_args), image]
81
+ if isinstance(command, (list, tuple)):
82
+ argv += [str(x) for x in command]
83
+ else:
84
+ argv += list(container_command) + [str(command)]
85
+ return argv
86
+
87
+
88
+ def docker_env(sandbox):
89
+ """Docker receives only explicitly allowed host environment values."""
90
+ out = {"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
91
+ "HOME": "/tmp", "TMPDIR": "/tmp"}
92
+ for name in (sandbox or {}).get("env_allowlist") or []:
93
+ if name in os.environ:
94
+ out[str(name)] = os.environ[str(name)]
95
+ return out