Private web UI#147
Merged
Merged
Conversation
砍掉 4 个无对应功能的 placeholder:AI 增强 / 共享 / 搜索 / 更多。 把原「分享」改造成真功能「导出 Markdown」,接已有 /api/sessions/:id/export?format=md endpoint(浏览器 a 标签 download,无后端改动)。 产品原则:toolbar 任何按钮点击必须有真反馈,否则一律删。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
后端:sessionTemplates.ts 加 user store 层(~/.axon/templates.json 单文件 JSON 持久化),listSessionTemplates 返回 builtin + user 合并。新增 POST /api/templates (创建)+ DELETE /api/templates/:uid(删除,拒绝内置)。 前端:新组件 TemplateEditorModal(类别/模式/封面 emoji/模板名/描述/Prompt 6 字段表单 + type→mode 候选受控)。TaskListPane 库 view 顶部加「+ 新建模板」 虚线按钮;用户模板卡 hover 显示删除 ✕(内置不显示)。modal 提交后重拉列表。 设计原则:不造 ORM 不造 service 层,直接同步 fs 读写;axon 单进程 web server 无并发问题,文件损坏 catch 返回空数组保证主流程不卡。official=true 内置 模板在 store 层拒删(safety guard,即使前端 UI 绕过也防得住)。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
scripts/ 11 个一次性脚本:i18n 修正三连 / 王果 PPT 生成 / hardcoded 扫描 / locales 拆分 / vim motions 测试 / background-task 修复验证 / 腾讯 COS 上传。 根目录 2 个:twitter_ad_copy.md(历史广告文案) / transparent-logo.png(历史 logo, README 不引用,alipay.jpg 才是当前打赏二维码)。 docs/ 3 个:render-to-user.md(早期 mock) / resume-ppt-visual.png + resume-visual-philosophy.md(resume PPT 视觉 mock,已被 V3 manus-route 路线取代)。 每个都 grep 过 0 引用才删(铁律1)。保留:AGENTS.md(AI 工具标准文件名, Codex/Aider/Cursor 识别)/ AXON.md(164refs) / PLAN.md(14) / SPONSORS.md(4) / V3 路线文档 / manus2.im42.har(反推证据) / 19 个启动脚本(全是 CI/installer/ user-curl 真入口,run.sh=docker run / deploy.sh=docker-compose / install.*= release.yml 引用 / 等)。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
knip 扫 + 逐个 grep import/require/from 三种语法验证后真 0 引用: dependencies (8): builder-util-runtime / cheerio / cli-highlight / cos-nodejs-sdk-v5 / docx / express-validator / mime / qrcode-terminal devDependencies (5): @anthropic-ai/claude-code (元参考,无 runtime import) / @types/diff / @types/eventsource / @types/mailparser / @types/nodemailer (后两个:mailparser/nodemailer 自带 .d.ts,@types/* 多余) 效果:99 packages removed(含 transitive)— package-lock 砍 1430 行。 保留:@monaco-editor/react(10refs) / @xterm/* / marked / highlight.js / imap-simple / nodemailer / docx-preview 等真在用的。 tsc 验证:pre-existing undici 错误(src/web/server/channels/adapters/discord.ts) 与本次清理无关 — git stash 验证删前也报。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ImageCanvasPanel.tsx/.css 之前一直是 untracked 状态,但 Root.tsx 已 import 并依赖它。本地能跑是因为文件存在工作树;其他机器 clone 后 build 会失败。 现在正式入库。 附带修复 prod build TDZ:useEffect (L176) 依赖数组里有 handleToggleDescribe/handleToggleMarkup/handleExitAnnotateMode 三个 callback, 但它们 useCallback 声明在 L281+(在 effect 之后)。dev 不报, minified prod bundle render 时求依赖数组就 ReferenceError 'le' before init。 三个 callback 都是 useCallback([]) 永远稳定,从依赖数组移除(加 ESLint disable 注释),TDZ 消失 + 行为不变(闭包内部访问到 mount 时早已 init 的 callback)。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
砍 / 接通: + 「新建项目」按钮 → 接 onCreateApp(弹 CreateAppDialog,已有完整流程) 📁 「新项目」整行 → 同样接 onCreateApp(增 onClick + cursor:pointer) ⚙ 「筛选 / 排序」 → 无对应实现,删 产品原则同 F5.i:toolbar 按钮点击必须有真反馈,没对应功能一律删。 未来 axon 接通 Manus 风 session hover 菜单(重命名/分享/归档/删除)走单独 milestone。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
用户反馈:「+ 新项目」原本弹 CreateAppDialog(紫色 dark theme + 工作目录 +
需求描述两字段表单),跟 Manus 完全不一致。Manus 点击 = 直接进 chat 让用户
描述需求,AI 自动决定项目目录。
改造(B 方案 · 完全 Manus 流):
后端:POST /api/projects/quick-new — 直接 mkdir ~/.axon/projects/项目-<ts>/
返回 {path, name},前端拿来 switchProject + ws session_new
前端:Root.tsx 新增 handleQuickNewProject — 替代原 setShowCreateApp(true),
ManusWorkbench 的 onCreateApp prop 切到这条无 modal 路径
axon vs Manus 架构差异(项目路径用户不控):
Manus 是云沙盒(路径用户不可见),axon 是本地 FS — B 方案约定俗成把项目
存到 ~/.axon/projects/,用户在 chat 中描述,AI 自动操作目录内文件。
CreateAppDialog 保留(其他入口可能用,目前 ManusWorkbench 不再触发)。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
接通真功能(4):
ChatPane composer + 附件 → hidden file input + 转 dataURL + 调 onImagePreview
复用 M7 ImageCanvasPanel 链路(已有的图片画布编辑/AI 生成发到 chat)
TaskListPane 🔍 搜索 → toggle search input + client-side filter
sortedSessions 按 title 包含 query 过滤;Esc 退出搜索
CodePane ↗ 分享 → 已在 F2.b 接通复制项目路径,保留
TaskListPane + 新项目 → F5.k 已接 handleQuickNewProject,保留
按 F5.i/j 原则删除(3):
ChatPane composer ⊙ GitHub(无 axon 实现)
ChatPane composer 🎤 录音(语音转文字未接)
CodePane ⊙ GitHub(同 ChatPane 重复占位)
disabled 化(1):
CodePane ⬆ 已发布 → 加 disabled + 'axon-cloud 待集成' tooltip + 灰显
(明确 placeholder 视觉不算假按钮,留位 axon-cloud milestone)
dropdown 5 项保留 disabled(导入项目/导出项目/重启 dev/Git 操作/复制 session 链接)—
独立 milestone 处理,本轮 scope 砍至 composer + 顶部 toolbar 范围。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
任务 item hover 时右侧渐显 ✕ 删除按钮(透明 → opacity:1),点击二次确认后 调 sessionActionsRef.deleteSession(id) 走 App 内部 ws + 后端清理链路。 stopPropagation 防穿透到 onSelectSession(避免误切 session)。 未来扩展(独立 milestone):把 ✕ 升级为 ⋯ more 菜单 → 弹完整 7 项 (分享/重命名/收藏/新标签打开/移动到项目/归档/删除),对齐 Manus 截图。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
axon backend intent-enricher(src/context/intent-enricher.ts:254)会给 user input 自动拼上 <intent-context>git status + recent changes + recent commits </intent-context> 作为 LLM context。这是给 LLM 看的,前端必须剥离。 老 App.tsx 的 Message 组件已经有这个剥离正则(Message.tsx:140),但 ManusWorkbench/ChatPane 是 F1.a 之后的新组件,没复用 → user 气泡把 git status 全文渲染出来,把用户输入的 "hi" 淹没。 修:加 stripContextTags helper(与 Message.tsx 同款正则),user 和 assistant 气泡渲染 m.text 时都过一遍。assistant 一般不该有这些标签,保险起见也剥。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
用户反馈:axon 定位完全对齐 Manus 产品形态,普通用户从不知道 git/dev 概念。 intent-enricher 给 user_message 拼 <intent-context>git status / recent changes / recent commits</intent-context> 是 axon 老 dev tool 时代的设计, 在 Manus 形态下完全错位: 1. 用户输 "hi" 会被注入整段 git diff(用户实际投诉看到了) 2. 占大量 LLM token + 拖慢响应 3. 暴露 axon dev tool 底子,破坏 Manus 产品观感 修:conversation.ts web 路径直接 enrichedContent = content,不再 enrich。 intent-enricher.ts 保留(CLI 模式 src/core/loop.ts 仍调用,不动 CLI 行为)。 注意:这是补丁级修复。用户已明确「提示词系统 + 上下文系统要完全重构」, 本提交先 stop the bleeding,后续按重构方案统一处理整套 prompt/context 链路。 注意:本提交需要重启 axon-web server 进程才能生效(tsx 不 hot reload)。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
铁律 11:评估和测试大于一切。重构 prompt/context 系统前先建评估集拿 baseline,
重构后跑同一套对比确保不退化。
本提交起步:
- harness.ts:ws 客户端连本机 axon-web → 发 chat → 收事件流 → 契约判定
(生产路径 e2e,跟 ChatPane.tsx 同款 ws 协议)。提供 noContextPollution
/ expectEvent / combine 等通用 contract helper
- cases.ts:5 case 计划表,本期 ship 1 个(chat-hi)
- run.ts:runner orchestrator + markdown 报告输出
- 跑的是 axon-web 当前配置的 model(目前 = axon-cloud GPT 5.5)
首跑 baseline 1/1 PASS — 但发现:
- "hi" 这个输入在新建空 session 下不触发 intent-enricher(classifyIntent
判 'clear' 直接返回原文)
- 用户截图看到的污染场景应该是「在已有 project session 里发模糊指令」,
那条路径 classifyIntent 判 'vague' 才触发 git context 注入
- 后续 4 case 必须覆盖触发 enrich 的输入,才能真正验证 F5.o 修复 + 防回退
后续扩 4 case:chat-weather / slides-blueprint / website-blueprint / design-image-gen
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
discord.ts 用 await import('undici') 拿 ProxyAgent,undici 是 @discordjs/rest
transitive dep(运行时 ok),但不在 axon package.json 声明 → tsc 找不到 types
报错阻断 build。
尝试 npm install undici 反而引入版本冲突(root vs discord transitive 各一份)。
最简:dynamic import 用 'undici' as any 跳类型检查,运行时不变。
这个错误存在已久,但之前 dist/ 没人 rebuild 所以没暴露。今天为了让 F5.o
(禁 intent-enricher)生效必须 rebuild server,逼出这个修复。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
harness 加 setup hook(session_new 后 chat 前注入副作用,用于配 project_path
让后端进入「已有 project + git repo」状态触发 intent-enricher 路径)。
5 case 全 PASS(baseline 干净):
✅ chat-hi: 新空 session "hi" — classifyIntent='clear' 本来就不 enrich
✅ chat-vague-in-git-repo: 在 axon git repo 下 "现在怎么样了" — F5.o 真验证!
vague intent 在 git repo 下原本会被 enrich 拼 git status,现在禁了就干净
✅ slides-blueprint: slides mode "做 PPT" 不污染
✅ website-blueprint: website mode "做 landing" 不污染
✅ design-image-gen: design mode "生成 logo" 不污染
意义:这是 M2 prompt 重写之前的 baseline 锚点。重构后跑同一套必须仍 5/5 PASS
+ 进一步可加 token 数 / 响应耗时回归检测。
待优化(不阻塞):
- extractAssistantText 多数 case 抓不到(axon-web ws event 类型不止
chatDelta/text_delta,需要扩匹配集)
- slides/website 60s 超时不够 LLM 完成长回复
- design case 应额外检测是否调 image_generation hosted tool
这些都是 M1.b 精细化范畴,M2 prompt 重写不阻塞
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
新 manus-prompt.ts (~110 行) 替代 SystemPromptBuilder.build() 的 web 主对话路径: - 三段骨架:identity (axon 通用 agent + 编程护城河) + task discipline + 工具清单 - 砍掉 12+ 段 dev tool 注入:env(git/cwd/platform/model/cutoff) / notebook / ontology / knowledge / curator / codebaseContext / activeGoals / activeDomains / topicShift / chrome / IDE / diagnostics / MCP 长版 - PromptBlock 二分缓存语义保留:static(global) + dynamic(null) conversation.ts: - buildSystemPrompt 从 327 行 -> 41 行(-314/+28) - 不再调 systemPromptBuilder.build / domainDetector / ontology / notebook / knowledge / curator 等昂贵 IO 链 - 每轮 system prompt 构造从 ~1-3s(含 LLM curator)降到 < 10ms src/prompt/ 整体留作 src/core/loop.ts + src/tools/agent.ts 的 sub-agent prompt 使用,M4 收尾时再清。 evals: 5/5 PASS(chat-hi / chat-vague-in-git-repo / slides / website / design-logo), chat-vague-in-git-repo 单跑实证 52 个 text_delta 完整回复,无 git context 泄露。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
# M1.b harness 升级
- waitForEnd 'chat_end' 改用真信号 message_complete / status=idle,
替代原「3s 静默 + 类型名 heuristic」。chat-hi 从 45s → 4s,chat-vague 从
60s → 7s(原超时是错觉,真信号下都很快)。
- 新 contract:
- expectAssistantNotEmpty(events, minChars): 防 LLM 拒答 / 沉默
- expectAnyKeyword(events, keywords[]): 验 mode 真触发对应方向
- expectToolCalled(events, toolNames[]): 验产品路径(如 website
blueprint-card-first 的 propose_website_builder)
- collectAssistantText 内部化,extractAssistantText 提取 helper 不变
# M1.b.1 mode prompt + identity 修「沉默拼代码」
- manus-prompt.ts identity 加「保持节奏感」: 复杂任务动手前 1-2 句说明,
关键节点(开始/里程碑/完成)补一句状态;禁止长时间静默连发工具调用
- modeRegistry slides/website 各加「进度反馈」段,加强对 action-heavy
mode 的反馈纪律
# Baseline 5/5 PASS 含全部质量契约
| Case | 时长 | 契约 |
|---|---|---|
| chat-hi | 4s | 不污染 + assistantNotEmpty |
| chat-vague-in-git-repo | 7s | 不污染 + assistantNotEmpty(≥5) |
| slides-blueprint | 89s | 不污染 + assistantNotEmpty + slide 关键字(真 .pptx) |
| website-blueprint | 8s | 不污染 + expectToolCalled(propose_website_builder) + react |
| design-image-gen | 32s | 不污染 + .png 关键字(真 logo) |
# 修复过程实证(不入 commit body 但留作记录)
- slides 0 字符 → 修 identity + slides mode 进度反馈段 → 428 字符
- website 0 字符 → 不是 bug 是 blueprint-card-first 产品设计 → 改 contract
验 propose_website_builder 工具调用而非 text 非空(参考
project_manus_blueprint_card.md)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
# topic-shift 全删(M2.a 已废 system prompt 指令,整套机制已成死代码)
server:
- websocket.ts: 删累积变量 topicShiftAccumulatedText + onTextDelta 累积 +
onComplete 后的 <!--TOPIC_SHIFT--> 检测与 topic_shift event 发送
- modeRegistry.ts: 删 PromptBlockId 'topicShiftDetection' + SKIP_PROJECT_AND_SHIFT
里的对应项(保留 SKIP_PROJECT_BLOCKS 作 mode 元数据,M4 一并清)
client:
- components/TopicShiftToast.tsx + .css: 整文件删除
- App.tsx: 删 import / state 解构 / 渲染分支
- hooks/useMessageHandler.ts: 删 topicShiftDetected state / dismissTopicShift /
case 'topic_shift' handler / return 字段
- i18n/locales/{en,zh}/common.ts: 删 topicShift.* 4 个 key
# intent-enricher 死赋值清理
- conversation.ts: 删 `const enrichedContent = content;` 临时变量,直接用 content
- 模块 src/context/intent-enricher.ts 保留(src/core/loop.ts CLI/sub-agent 路径还在调),
整体去留留给 M4
# evals 5/5 PASS 不退化
chat-hi 4s / chat-vague-in-git-repo 7s / slides 94s / website 7s / design 35s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
M2.a 把 web 主对话切到 manus-prompt.ts,M4 把剩下的 loop/sub-agent/schedule 路径
也搬走,src/prompt 整个目录彻底删除(2700+ 行 → 0)。
M4.a 5 个 sub-agent prompts (GENERAL_PURPOSE/EXPLORE/CODE_ANALYZER/BLUEPRINT_WORKER/
WEBSITE_BUILDER) 从 src/prompt/templates.ts 搬到 src/tools/agent-prompts.ts,
agent.ts 改 import 路径。纯字符串搬运不改内容。
M4.b loop.ts 删 SystemPromptBuilder + 40+ 字段 PromptContext + refreshPromptMemoryContext
(notebook/ontology/knowledge/curator 喂养整套,含 LLM curator 调用 1-3s) +
updateContext + getDefaultSystemPrompt。换成 src/core/loop-prompt.ts 同步
构造(<1ms,3 段:identity / hosted tools / env)。loop.ts -100 行。
M4.c modeRegistry.ts 删 PromptBlockId / skipBlocks / SKIP_PROJECT_BLOCKS 死代码 —
M2.a 之后 manus-prompt.ts 不读 skipBlocks,全是注释级 deadweight。
M4.d 6 个测试(tests/prompt/* + tests/language-config + tests/integration/
hosted-tools-wiring)测的都是被删除的 SystemPromptBuilder,删除。新评估
evals/suites/prompt-refactor 5/5 PASS 是更高保真的 L3 覆盖(铁律 11)。
conversation.test.ts 删 systemPromptBuilder mock。
M4.e hosted-tools.ts 挪到 src/core;PromptBlock 类型从 src/prompt/types.ts 内联到
src/web/server/manus-prompt.ts;conversation.ts + runtime/types.ts +
loop.ts 改 import 路径。src/prompt 目录 rm -rf。
M4.f npm run build (server + client) 全过 + axon-web M4 build 重启 + evals 5/5 PASS:
chat-hi / chat-vague-in-git-repo / slides-blueprint / website-blueprint /
design-image-gen 全部 ✓ 无 dev context 污染 + 关键路径契约保持。
Net: 5 个 sub-agent prompt 集中到 tools 就近;loop / web 各有一个极简 prompt 构造
器(loop-prompt.ts + manus-prompt.ts);src/prompt 整个目录死亡。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
M5 启动前先做 ground truth 反推(铁律 11:评估测试大于一切 + 铁律 7:第一性原理),
避免在错误假设上设计 streaming + multi-turn 改造。
源数据:docs/manus2.im42.har (30M) + axon 现有代码对照 + docs/website-builder-v3-manus-route.md
强证据钉死的结论:
1. Manus 是 single-agent + tools 扁平结构,无 sub-agent
- 搜 subagent/sub_agent/child_session/spawn/delegate/parent_id 全 0 匹配
- 与 axon 多层 (src/blueprint/planner/lead-agent/worker) 是设计导向差异
2. Streaming 是 phase 级 SSE (llm → tsc → committing) 不是 token 级
- 来自 v3-manus-route §2.1 真实 SSE 协议
- axon 当前是 Anthropic token 级流,工具内部进度该走 phase 事件
3. Tool 路由在后端硬编码 (routeEdits 三分支),不是代理在对话中决策
弱证据 / 推断 (文档显式标记):
- Multi-turn context 后端持有 — 协议设计反推,HAR 没多轮样本
- Mode 切换具体 frame — 从 axon 代码反推,HAR 没捕获
文档自评可信度:
- Agent 层次 ★★★★★ | Sub-agent 存在性 ★★★★☆ | 工具粒度 ★★★★☆
- Multi-turn context ★★☆☆☆ | Mode 切换 ★★★☆☆
- 总体 70% (高置信 architecture,低置信 context 管理)
补齐方法(文档里 5 个不确定项):
- 长对话 context window:实测 Manus 上 20+ 轮抓 frame size
- sub-agent 在大 blueprint 中的真实用法:实测"从零生成网站"
- tool 失败回退策略 / streaming 新特性 / mode toolFilter 真实行为
下一步 M5 方向待用户拍板,候选 (按 surface 从小到大):
A. 加 tool phase event 协议 (loop 转发,工具端封装)
B. 后端 session 管理迁移 (ConversationManager 持有历史)
C. 砍 sub-agent + blueprint 多层 (surface 巨大,需谨慎)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
源:用户 2026-05-23 口述产品愿景 + manus-agent-loop-research.md HAR 反推 + axon 现有代码盘点 核心架构: Layer 0 Mode 系统 (chip 触发) ✅ axon 已对齐 Layer 1 Base agent + Coding agent 自动升级 ❌ M5 Layer 2 Spec 引导卡片 → JSON/YAML ❌ M6 Layer 3 蓝图 → 执行 → 测试 → 评估 → 交付 ❌ M7-M8 (复用 src/blueprint/) Layer 4 User-in-the-loop 协作 ❌ M9 差异化护城河: vs Manus 增加 Layer 1-3 编程深度 (Manus 是单 agent + 后端编排) vs CC 增加 Spec 约束防"写出来不是用户要的" + 流程化验收 重构原则: - 不一锅端,按 M5-M9 五步走,每步带 eval 验证 - 保住 M4 evals 5/5 PASS 基线,每个 milestone 不得退步 - Mode 系统 / manus-prompt / loop-prompt / ws 协议都不动 - sub-agent 框架 + blueprint 三层都保留 (Layer 1/3 复用) 不确定项明示(5 个,待用户拍板): - Spec schema 字段范围 (最少集 vs 完整集) - Blueprint task acceptance check 强度 (严 vs 宽) - User-in-the-loop 验证机制 (口头 ack vs 实测) - base/coding agent prompt 边界 - 既有 mode 与 coding agent 的关系 下一步:用户 review → 3 种动作 (签字开干 M5 / 补 HAR 再开干 / 提修正方向) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
为 axon-spec.md Layer 1 "注册全部能力矩阵" 设计提供证据基础。
钉死的事实:
1. axon 现有 7 个独立 registry/manager:
ToolRegistry / PluginManager / McpToolManager / SkillsHub /
ModeRegistry / ConnectorManager / ToolPermissionManager
2. Deferred tool + ToolSearch 机制已对标官方 v2.1.34:
- 启动时分 immediate vs deferred (shouldDefer / isMcp)
- ToolSearch 工具支持 select / keyword / required 三种查询
- MCP 工具自动 deferred (防 schema 膨胀)
3. Skills 是依赖安装管理器 (pip/npm/apt + healthcheck),
不是 Manus SkillService 的 prompt + tool whitelist 激活系统
4. Connector 体系缺失最大:ConnectorManager 只存 OAuth token,
无服务注册 / 无能力发现 / 无动态加载,比 Manus 差一个等级
文档给了 3 种 Layer 1 实现方案 (A/B/C),但调研者推荐的方案 A
(mode 加 capabilities 字段) 与用户原话偏差大 — 用户要的是"注册全部",
方案 A 把 capabilities 绑到单 mode,实际是"切 mode 才切能力"。
实际可能更对的方案:复用现有 ToolSearch + 系统提示注入 category 级目录
(不是完整 schema)。下一轮和用户对齐时给精确方案。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
任务:用户 2026-05-23 让评估 axon 框架能否覆盖 Manus playbook 67 个使用场景。
调研结果:
抓到 100 个 playbook(Manus 在快速新增 SEO landing,主页声称 67,实际已超 100)
按 12 大类归并 A-L (Slides/Document/Translation/Research/Web App/Dashboard/
Form/Business/Finance/Visual/Personal/Scheduling)
4 层架构覆盖率(按 Layer 增量):
L0 12 mode 直接跑通:38 个 (38%)
+M5 coding agent 自动升级:+31 个 (覆盖率 69%) ← 杠杆点
+M7-M8 蓝图→交付:+22 个 (91%)
+M6 spec 卡片:+20 个 (跟 M5/M7 重叠多,~95%)
+M9 user-in-the-loop:+8 个 (~99%)
结构性差距:6 个 (Connector 体系欠缺,B 端长期话题)
路线图修订建议:
原 spec.md: M5 → M6 → M7-M8 → M9
改成: M5 → M7-M8 → M6 → M9
理由:M6 spec 卡片没 M5 coding agent 时产出"死 JSON",
M7-M8 才是把代码变交付物的核心价值
护城河必赢战场(M5 后首批 demo 候选):
ai-website-builder (已落地) / code-generator / chrome-extension-builder /
crm-dashboard-generator / everything-calculator / 全部 F 类 dashboard
战略不打:视频赛道(护城河 0,Manus 也是降级);短期不卷 Connector B 端
文档:docs/manus-playbook-coverage-analysis.md (303 行)
未动 src/ 代码、未跑 build/test,纯调研产出
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
用户 2026-05-23 拍板 (基于 docs/manus-playbook-coverage-analysis.md):
1. M5-M9 执行顺序调整:
原 spec 顺序: M5 → M6 → M7-M8 → M9
新顺序: M5 → M7-M8 → M6 → M9
理由:
- M5 (coding agent) 杠杆最大:解锁 31 个 playbook (38% → 69%)
- M7-M8 (蓝图→交付) 紧跟 M5:+22 个 playbook (→ 91%)
- M6 (spec 卡片) 没 M5+M7-M8 时产出"死 JSON",价值有限
- M9 (user-in-loop) 强依赖用户基数,早期不做
2. M5 后第一批 demo playbook 4 选:
- code-generator (IDE+Monaco 直出代码)
- chrome-extension-builder (Manus 沙盒难调试,axon LSP 优势)
- crm-dashboard-generator (数据应用,实时预览效率高)
- everything-calculator (小应用快出,验证反馈循环)
milestone 代号不动 (M5/M6/M7/M8/M9 维持原身份),
各 milestone 段内描述微调留到实施时再 finetune (KISS,不过早调整)。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
按用户 2026-05-23 指示"先继续完整理 M5 设计文档",本文档把 M5 设计落到可
review 颗粒度,每个决策点给推荐 + 备选 + 理由,让用户 review 后再动代码。
8 个关键决策:
1. enter_coding_mode 参数 schema — 推荐 B 分类版 {reason, expectedDeliverable}
2. 识别判定逻辑 — 推荐 A 完全 LLM 自决 (匹配"prompt 越少越好"哲学)
3. coding agent prompt 内容 — 25 行草稿,强调"严格按描述/IDE 工具/自检"
4. session state flip — 推荐 A 复用 mode 字段 ('coding' 是 mode 值)
5. evals 5 个 case 设计 — 2 个负样本 + 2 个正样本 + 1 个 M4 不退步
6. 回滚机制 — 3 种都做 (UI 关闭 + LLM 工具 + prompt 引导)
7. mode 交互行为 — 5 mode 映射表 (default 允许 / chat 禁止 / 等)
8. UI 透明度 — 推荐 A 现有 tool_use 卡片,C friendly banner 留后续增强
7 子任务(M5.a-g)拆解:
M5.a 修 M4.b 误删的 ontology 注入路径 (~30 行)
M5.b 新建 enter_coding_mode + exit_coding_mode 工具 (~80 行)
M5.c base agent system prompt 加 Your helpers 段 (~10 行)
M5.d coding agent identity 新建 + modeRegistry 加 coding mode (~60 行)
M5.e conversation.ts session state flip 兜底 (~5 行)
M5.f 前端 mode 指示器 (~30 行 TSX)
M5.g evals 5 个 case + M4 不退步验证 (~150 行)
预估总 surface ~365 行 / 1-2 session 落地
数据模型 + 落地依赖图 + 不确定项 + "不在 M5 范围" 全部写清。
下一步:用户 review 本文档勾选决策选项后进入 M5.a 实施。
未动 src/ 代码,纯文档产出。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
按用户 2026-05-23 指示"全补完再动手",把 m5-design.md 从"看起来完整但实际还有 9 个
没设计清楚"补到"可以直接动手实施"颗粒度。
🔴 致命盲点(已补):
1.5 expectedDeliverable 对应的 subspecialty 设计
— 7 个 deliverable 各加 ~10-15 行 prompt 增量,新建 coding-subspecialty.ts
2.5 base agent 识别引导文案具体内容
— 产出物驱动型一句话 + 边界说明,对齐 expectedDeliverable 枚举
7.5 隐式忽略具体实现
— 工具内部 noop 返回 status='already-coding',CODING_CONTEXT_MODES 常量
🟡 次要盲点(已补):
3.5 prompt 内部"不发挥"vs"先问"冲突解决
— 功能扩展不发挥,技术选型必问
5 evals case 扩 5→9(5 negative + 4 positive)+ multi-turn case
— false positive 率统计意义增强 (<1/9 = 11%)
— 新契约 expectSystemPromptContains / expectToolNotInTools
M5.g surface 估计调到 ~200 行 eval 代码
🟢 可延后盲点(已补,标 M5+ 增强):
7 exit_coding_mode 后历史不动 (复用 Manus 体验)
8 M5.f 前端位置 — 顶栏右上 inline pill,实施时 check 现有布局
9 ontology/memory/promptSnippets 跨 mode 注入维持
📋 Vision 一致性(已补):
10 Your helpers 段范围 — 列 5 个特殊能力 (enter_coding_mode/ToolSearch/
propose_website_builder/Cron/Skill),不列基础工具,~9 行
11 base + coding agent 同 session 同历史 (mode flip 不切 session)
文档结构:608 行,27 章节
未动 src/ 代码,纯文档产出
下一步:用户 review m5-design.md → 全接受推荐 → 开干 M5.a 修 ontology regression
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
按用户 2026-05-23 指示,把所有产品决策统一到单一真理源 docs/axon-spec.md:
合并源:
docs/axon-spec.md (327 行) — 原 vision + 4 层架构 + 路线图
docs/m5-design.md (608 行) — M5 完整设计 (8 决策 + 11 盲点补全 + M5.a-g)
docs/_acceptance-draft.md (305 行 subagent 草稿) — Manus 实证验收 128 条
合并后结构 (1197 行):
## 一行愿景
## 4 层架构
## 核心创新点 (vs Manus / vs CC)
## axon 现状盘点
## 重构路线图 (M5-M9)
### M5 — 完整设计展开 (m5-design 全部内容降级)
### M6 / M7 / M8 / M9 — 原简述保留
## 不动 / 保留
## Acceptance Criteria (新章节) — 128 条 ✅/❌/⚠ 三态标记
### A. 能力维度 (22 条)
### B. 功能维度 (39 条)
### C. 产品维度 (14 条)
### D. axon 独有能力 / 编程护城河 (18 条)
### E. 不抄的 Manus 设计 / 战略选择 (15 条)
### F. 留待视频补充 (20 条 — 待用户看 manus-saas.mp4 后回填)
## 不确定项
## 完整性评分
## 下一步行动
证据来源:
- 4 个 HAR 抓包 (manus-research/har/)
- 18 张截图 (manus-research/screenshots/)
- 5 个 notes 调研 1358 行 (manus-research/notes/)
- docs/manus-agent-loop-research.md + docs/manus-playbook-coverage-analysis.md
+ docs/axon-capability-registry-audit.md (3 篇前置分析)
- 视频 manus-saas.mp4 (991M) 未纳入,subagent 看不了 — F 段 20 条候选待用户看后补
状态分布 (A+B+C+D 共 93 条 axon 应实现项):
✅ 已实现:33 条
❌ 缺失:47 条
⚠ 部分实现:13 条
关键发现:
- axon 真护城河聚焦 D.1 (IDE+Monaco+LSP, 4 ✅) + D.6 浏览器自动化 + D.7 感知
- axon 弱项:streaming 模型偏差大 (A.3.2-A.3.3),设置面板 8 子项全缺 (B.6 部分战略不抄)
- D.3 spec 约束 + D.5 五阶段流程化全缺 — M5-M9 必须落地否则护城河声明等于空话
删除:docs/m5-design.md (合并到 axon-spec 路线图章节内)
docs/_acceptance-draft.md (subagent 草稿,合并后清理)
未动 src/ 代码,纯文档整合产出。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
抽帧脚本 manus-research/extract_video_keyframes.py(cv2 直方图相关度 < 0.88 阈值场景切换 + 1400px JPEG 85),F 段从 20 候选 → 35 条: - F.1-F.20 每条标 ✅实证/⚠部分/❌未覆盖 + frame_NNNNs.jpg 证据 - F.21-F.35 视频新发现 15 条:deploy modal / "请求 Manus" CTA / socket.io 双 socket / sessionUid 后端管 / 三段式文案 / 升级 modal 缩略图 banner / 中栏 4-mode 切换 / 双时间戳 / Vite+React monorepo 模板 / 8 tab 设置面板(截图漏"通知" tab)等 关键 spec 修正: - F.7 sandbox 5-tab 假设错 → 实际是网站 builder 后台 8 tab - F.4 message_ask_user = 金色 inline 状态条不是模态 - F.14 设置面板有 8 tab 不是 7 tab ✅23 / ⚠5 / ❌7(happy path demo 不触发的异常恢复 / Blueprint / Stripe / share replay 等仍需另抓视频) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
切分动机:M5+ 实施需并行 agent。单文件 1224 行无法并行(同改一个 file 必 conflict + 每 agent 都 load 全部上下文浪费)。新结构按"读取最小集" 原则切分 — 每个 agent 只 load 自己那段 50-150 行 + 强制读 ~500 行 三件套全局锚点(vision + M5-overview + test-matrix)。 文件结构(22 个 md): - README.md (索引 + 依赖图 + 143 1-line summary) - vision.md (北极星:4 层架构 + 红线 7 条) ★ - status.md (现状盘点 + 不动/保留) - decisions-pending.md (跨阶段待决 + 完整性评分) - test-matrix.md (eval × acceptance 映射) ★ - roadmap/ (12 file): - M5-overview.md (8 决策 + 11 盲点 + 依赖图) ★ - M5a-g 7 个子任务 file (每个含 header 模板 + 改动清单 + 验收测法) - M6 / M7 / M8 / M9 vision - acceptance/ (6 file): A-F 各一,每条加 [测法: eval/playwright/manual/暂无法] tag ★ = 三件套必读(任何 M5 子任务 agent 启动 prompt 强制 Read 这 3 个 file 再动手)。三件套 ~500 行 / ~3K tokens,每 agent 都吃得起。 关联机制: - 每文件头部 5 行模板自动 link 父文档 + 北极星 + 影响的 acceptance + 依赖 - README 列 143 条 1-line summary 让 agent 验收时跳读 - test-matrix.md 把 eval case ↔ acceptance criteria 反向打通 并行可能性(M5 启动): - M5.a (修 ontology) + M5.b (coding-mode 工具) + M5.f (前端 indicator) 同时启 - M5.c → M5.d 同 agent 串行(同改 manus-prompt.ts) - M5.e 等 M5.d 后 / M5.g 最后 内容完整性: - 1224 → 2431 行(增量 = 23 个 file header 模板 + 子任务实施细节扩 写 + README/test-matrix 新建 268 行 + acceptance 每条 [测法] tag) - 0 行内容丢失(vision / 现状 / M5 8 决策 / 11 盲点 / 143 acceptance / decisions-pending 全部 1:1 迁移) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Layer 1(vision.md)落地:base agent 识别复杂编程任务 → 调 enter_coding_mode → session flip 到 coding identity + 编程工具集,同 turn 内无缝切换。 核心实现(施工时实测推翻 spec 草稿的 execute(input,context) 假设 —— BaseTool 无 session context): - src/tools/coding-mode.ts: enter/exit_coding_mode 纯 marker 工具(不碰 session state) - conversation.ts: 工具结果循环按 toolUse.name 拦截翻 mode(state===注册 session 同一对象); 主循环每轮重建 prompt+toolFilter → 翻完下一轮自动切;hosted tools 也走 toolFilter(顺修 chat mode 漏屏蔽 image_generation) - manus-prompt.ts: CODING_AGENT_IDENTITY(mode='coding' 分支)+ AXON_HELPERS(产出物驱动型升级判定文案) - modeRegistry.ts: coding ModeConfig 黑名单(保留 web_search+Browser)+ CODING_CONTEXT_MODES - M5.a: 恢复 M4.b 误删的 ontology 注入(manus-prompt+conversation 2 处;loop.ts 同步路径不动) - propose_website_builder vs enter_coding_mode 边界:展示型站 vs 功能型 app(dashboard/CRM) eval(evals/suites/m5-coding-agent/):M5 10/10 PASS + M4 prompt-refactor 回归 5/5。 AXON_EVAL_DEBUG=1 时后端 broadcast debug_system_prompt/debug_tools_for_turn 供 eval 断言 identity 切换 + toolFilter 生效。 spec 修正写回 docs/spec/roadmap/M5a,M5b。M5.f 前端指示器尚未做。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
M12.o 的 /:connectorId/:eventType? 用了 Express 4 的 `?` 可选参数语法, 在 Express 5(path-to-regexp 8.x)被废弃,mount 时抛 PathError 让整个 axon-web 服务起不来(self-evolve ErrorWatcher 反复 repair 也救不回)。 改成两条显式路由共享同一 handler(版本无关): POST /:connectorId (通用 / GitHub) POST /:connectorId/:eventType (如 slack/events) 发现于 M13 跑 m7 eval 需起 server 时——之前 server 一直没真正启动过。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
用户拍板「A 全在沙盒」:coding 元数据(spec/blueprint)+项目文件都在 SANDBOX_PROJECT_ROOT,handler 读写+跑命令全走沙盒。本提交迁 M7 核心: - buildSystemPrompt 3 个每轮注入块(spec/blueprint/ui_contracts): fs.existsSync/readFileSync → await cfsExists/cfsReadFile - handleGenerateBlueprint:转 async;cwd=getCurrentCwd();spec 覆盖率读 + blueprint.json 落盘 + writeBlueprintHtml 全走 cfs*;调用方加 await - handleVerifyTask:cwd=getCurrentCwd();blueprint/package.json/tsconfig 读探走 cfs*;save() 转 async;typecheck/lint 走新增 execInContext - writeBlueprintHtml:转 async + cfsWriteFile - 新增 execInContext(cmd,cwd):有沙盒→sandbox.exec(E2B microVM 内跑) / 无→本地 execSync(与迁移前 run() 逐字等价) 零回归原理:无沙盒(community/本地/flag off)时 getCurrentCwd()==state.session.cwd、 cfs*→本地 fsp、execInContext→execSync,行为与迁移前逐字等价。沙盒路径 dormant 直到 AXON_SANDBOX_CODING 翻开。 验证:m7-blueprint eval 3/3 PASS + 1 skip(对齐基线,本地零回归钉死)。 剩余 handler(run_blueprint_tests/verify_against_spec/deliver_app/spec 写/ emitCodingPipelineState)同 pattern 待迁。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
延续 M7 核心迁移,把剩余 coding 流水线 handler 的元数据读写迁到 cfs*: Chunk A(spec-confirm/panel,ALS 上下文边界): - 新增 runInSessionContext<T>(返回值版 runLoopInContext):out-of-loop handler 从 sessionId 显式解析沙盒建立上下文(它们在 chat() 入口跑、不在 conversationLoop ALS 内) - handleCodingSpecMessage/handleDesignDirectionChosen:转 async + 包 runInSessionContext + spec.json 读写走 cfs*(否则会落本地、与每轮注入的沙盒读错配) - handleProposeDesignDirections:转 async(在 loop 内,getCurrentCwd)+ design html cfsWriteFile - buildPipelineSnapshot/emitCodingPipelineState:转 async + cfs*(panel 读 spec/blueprint/delivery) - readProjectMeta/countProjectFiles:转 async + cfs*/cfsReaddir Chunk B(M8 三 handler 元数据): - writeJsonSafe:转 async + cfsWriteFile(M8 三 handler 唯一调用方,全 await) - run_blueprint_tests/verify_against_spec/deliver_app:cwd=getCurrentCwd() + spec/test-report/acceptance/evidence/delivery/package.json 读写走 cfs* - handlePublishToAxonApp/publishFullStackToRailway 的 publish.json 也 await - 命令/网络层(runWorkerVerification/runProbe/startDevServerAndProbe/lintProjectMarkers) 留 Chunk C/D;flag off 时 cwd=本地→零回归 零回归原理同 M7:无沙盒时 getCurrentCwd()==state.session.cwd、cfs*→本地 fsp、 runInSessionContext→runWithCwd(localCwd),与迁移前逐字等价。 验证:tsc 干净;server 日志实证 handleCodingSpecMessage/handleDesignDirectionChosen 本地正确写 spec.json + chosenDesign([M6.c]/[M6 V2] 落盘日志多次出现,无代码异常)。 m6 eval 完整跑被 codex 后端 503/401 降级打断(非迁移问题)。E2B e2e 留 Chunk E。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
M8 测试门 + 验收 probe 的命令/网络执行路由进 E2B(Model A:项目活在沙盒,命令也得在那跑): - SandboxAdapter 加 getHost(port):E2B→`<port>-<id>.e2b.app` 公网域名 / local→localhost:port(preview 基础) - worker-verification.ts:抽纯函数 inferVerificationCommandsFromScripts;runWorkerVerification 顶部判 getActiveSandbox()——有沙盒→cfs 读 package.json/tsconfig 推断 + sandbox.exec 跑 lint/typecheck/unit; 无→现状本地 spawn(AutonomousWorker/Agent/community 零回归,inferVerificationCommands 保持同步不破单测) - runProbe(verify_against_spec):file-exists/contains→cfs* / cli→sandbox.exec(有沙盒)/ http→resolveProbeUrl 把 localhost:PORT 重写成 E2B getHost(port) 公网 URL - resolveProbeUrl helper:沙盒激活时 localhost→https://<getHost>,非 localhost 原样 验证: - tsc 干净;worker-verification(14)+local-adapter(15)+coding-sandbox-manager(10) 共 39 单测全绿 - ★真 E2B smoke 实证★:runWorkerVerification 在沙盒上下文跑 typecheck GREEN/RED(exit2) 正确; getHost(3000)→3000-<id>.e2b.app;sandbox.exec/cfs 往返正确 剩余:startDevServerAndProbe(deliver preview 的后台 dev server 需 E2B 后台命令能力)留下一步; 未沙盒化时 deliver 在沙盒模式优雅降级(no preview URL 但 delivered:true 不 brick)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- handleTemplatePickerSelect(picker 选模板路径,不经 enter_coding_mode 工具):Model A 下 先 ensureForSession 建云沙盒,模板 copy **进沙盒**(initializeTemplateToSandbox,保二进制); gated——community/flag-off 返 null → 走本地 initializeTemplate(零回归)。 - gracefulShutdown:加 codingSandboxManager.destroyAll(),服务关停销毁所有 E2B 沙盒 (wall-time 计费,防泄漏烧钱)。ws 断连不销(可能是刷新;靠 exit_coding_mode + E2B idle timeout)。 剩余(UI 项目专属,不在 e2e-full-flow 关键路径,优雅降级): - startDevServerAndProbe(deliver preview 的后台 dev server,需 E2B 后台命令能力) - lintProjectMarkers + run_ui_contracts(M11 chromium 探 E2B 内 dev server) 这些仅 UI/有 ui_contracts 的项目触发;CLI/API 项目跳过,不阻塞核心流水线 e2e。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
★活体 E2B e2e 抓到的真集成 bug★:enter_coding_mode 在 turn **中途**才 ensureForSession 建沙盒,但 runInSessionContext 在 turn **开始**就进上下文——那时 manager.get() 还是 null → 走静态本地分支。整个 turn 内 enter 之后的 Write/Bash 看不到沙盒 → 回落本地 fs → `EACCES: permission denied, mkdir '/home/user/project'`(本机无权建 /home/user)。 而 handler(generate_blueprint 等)因在更晚的 turn 跑、沙盒已存在 → 正常写进 E2B,形成 「blueprint.json 进了沙盒但 Write 工具 EACCES」的诡异不一致。 修法 = ALS 存 **resolver** 而非沙盒/cwd 快照,每次 getActiveSandbox()/getCurrentCwd() 调用时实时求值: - sandbox-context:runWithSandboxResolver(()=>sb|null);getActiveSandbox/hasActiveSandbox 动态解析 - cwd-context:store 支持 string|(()=>string);getCurrentCwd/getCwdOrDefault 动态求值 - runInSessionContext:coding-enabled(cloud+flag) session 用 resolver—— cwd=()=>manager.get(sid)?SANDBOX_ROOT:localCwd,sandbox=()=>manager.get(sid)。 沙盒一在 turn 中途建出,同 turn 后续操作立即路由进 E2B + cwd 同步切沙盒根。 community/flag-off 仍走静态 localCwd(零回归)。 验证:tsc 干净;确定性复现证 turn 中途建沙盒后同上下文 cwd/sandbox 立即切换; sandbox-context 6 单测 + worker-verification/cloud-sandbox 39 单测全绿。下一步重跑真 E2B e2e。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
真 E2B e2e 实证:coding agent 不止用 Read/Write/Edit/Bash,还重度用 Glob/Grep 探索 + shell_session。它们都 getCurrentCwd()(沙盒模式→/home/user/project) 但操作**本地** fs/spawn → 沙盒模式搜不到/崩溃(agent 等于瞎了)。本提交补齐: - GlobTool:沙盒激活 → 用 E2B 内 python3(stdlib glob,recursive=True 支持 **) 在沙盒里 glob, 返绝对路径(argv 传参防注入;mtime 排序远程开销大故略,python sorted 稳定序) - GrepTool:沙盒激活 → 用 GNU grep(E2B base 无 rg,实测 probe)跑搜索,输出 file:line:content 与 rg 兼容、复用同款行处理(相对路径/offset/head_limit);-E ERE 近似 rg 正则,--include/--exclude-dir/ -i/-l/-c/-n/-A/-B/-C 全映射;multiline/--type best-effort 不支持;Office 文档回退沙盒跳过 - shell_session:沙盒模式明确报能力缺口 + 引导用 Bash(已沙盒化,支持 `cmd &`)——持久 shell 在 E2B 内跑需后台命令能力(待实现,同 dev server);诚实报缺口不静默崩(.length 错误消失) - 新增 shq() shell 单引号转义防注入 验证:tsc 干净;★真 E2B smoke 实证★ GLOB **/*.ts + GREP files/content 全正确(格式/相对路径/ERE 正则)。 广扫确认核心 coding 工具集(Read/Write/Edit/Bash/Glob/Grep/shell_session)全覆盖;media-gen/planmode/repl 等非 coding 主路径工具记 backlog。剩 dev server preview + M11(UI 专属) + 翻 flag 完整 e2e。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
★活体 e2e 抓的第二个真 bug★:Sandbox.create({apiKey}) 没传 timeoutMs → E2B 默认沙盒生命周期
仅 300s(5min)。coding session 一超 5min,沙盒被 E2B 回收 → 后续 Read/Write/Glob/Bash 全报
`SandboxNotFoundError: Sandbox is probably not running anymore`,agent 困惑地派子代理"诊断为何
写不进文件"。这是「命令 timeout」(commands.run timeoutMs)之外的「沙盒生命周期 timeout」,之前没设。
修:
- SandboxAdapterOptions 加 timeoutMs(沙盒生命周期,区别于单命令超时)
- E2BSandboxAdapter.create:传给 Sandbox.create({ timeoutMs })(E2B 按 plan 上限 clamp)
- CodingSandboxManager:默认 SANDBOX_SESSION_TIMEOUT_MS=30min 覆盖绝大多数 coding session
- 超长 session 的活动续期(keepAlive:活动时 setTimeout 续期)留后续增强
验证:tsc 干净;cloud-sandbox 25 单测全绿。下一步重跑 e2e 确认跑过 5min 不再 SandboxNotFoundError。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
活体 e2e 抓出的两个真集成 bug(静态测试发现不了):
1. ★Bash 后台路径绕过沙盒★:executeWithTimeoutToBackground/executeBackground
用本地 spawn(shell,{cwd}),普通命令(mkdir/cat/npm test)全是 backgroundable
→ 全走本地 spawn,cwd=沙盒根(/home/user/project)在本机不存在 → 文件落不进
E2B。决定性证据:同一子代理内 Glob 找到沙盒里的 blueprint.json,但 Bash
test -d /home/user/project 报 missing。修复:加 if(!hasActiveSandbox()) 守卫,
有沙盒时一律 fall through 到 executeInSandbox 远程分支。gated 零回归。
2. spec.json 解析撞尾随文本:M6.c 旧解析 JSON.parse(marker后到末尾),若 marker
行后有尾随文本(用户/harness 补的指令)→ "Unexpected non-whitespace after JSON"
→ spec 永不落盘 → Write/Edit 全程被屏蔽 → agent 退化成 Bash heredoc 挣扎。
修复:新增 extractBalancedJson 平衡括号提取(尊重字符串内括号/转义,无视尾随)
+ e2e harness 把 marker 移到最后一行(符合 M6.c 协议)。7/7 单测绿。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
run_blueprint_tests 的第 2 步集成 E2ETestAgent 跑浏览器 e2e(Chrome MCP + 本地
ConversationLoop + 本地截图目录),但 Model A 下项目文件活在 E2B 远程沙盒,cwd
=/home/user/project 本机不存在 → 截图 mkdir 直接 EACCES(活体 e2e 实测 report.e2e
.success=false summary "测试执行失败: EACCES",误导成像 app 测试挂了)。本地浏览器
也连不到沙盒内 dev server。把浏览器驱动指向 E2B 公网 host(getHost) 是延后的 preview
工作。当前 getActiveSandbox() 时诚实跳过 → report.e2e={skipped,reason} + 前端
status:'skipped'。浏览器 e2e 本就「不 brick 交付」,确定性硬门(lint+typecheck+unit
已在沙盒里跑绿)才是交付门。gated 零回归(无沙盒走原 E2ETestAgent 路径)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Model A 下 coding agent 文件活在 E2B 远程沙盒(/home/user/project),但 contract 是同步函数读本地 dir → 全 5 层误判「缺失」(0/1),而实际产物全在沙盒、delivered=true。 根因:harness 读错文件系统,非 pipeline 没跑通。 修复:新增 sync-sandbox-artifacts.mjs(连 running 沙盒镜像产物到本地 dir), contract 断言前经 execFileSync 同步拉取(gated AXON_SANDBOX_CODING=1,本地零回归)。 之后既有同步读盘逻辑原样验证「真实磁盘产物」——只是把盘指向对的那块。 实证:对 live 沙盒镜像 17/17 文件,contract 全 5 层 PASS: spec(2 验收)→blueprint(3 task 全 done)→真实代码 3 个→测试绿→验收 100%→ delivery delivered=true(双硬门,真闭环)。M13 Model A 核心端到端验证完成。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Model A 下 cloud coding session 的项目文件活在 E2B 远程沙盒,但 file-api.ts(编辑器 文件树/读/写)全走本地 fs → 用户看到本机空目录(agent 在沙盒里干活、编辑器却空白)。 零客户端改动方案(path-binding):CodingSandboxManager 加 path→session 反查映射 (ensureForSession 收 cwd 参数记映射 + getByProjectPath);file-api resolveReqFs 用 客户端已发的 root=本地项目路径反查该 session 的沙盒(也接受 sid header,future-proof)。 有沙盒→root=SANDBOX_PROJECT_ROOT + tree/read/write 走 sandbox adapter(新增 getSandboxDirectoryTree 镜像递归建树);无沙盒→本地 fs(gated 零回归)。 conversation.ts 两处 ensureForSession 传 projectPath/session.cwd 建反查。 manager 15 单测绿(+5 getByProjectPath:归一化/未知/销毁清理/无cwd不建映射)。 剩 create/delete/mkdir/rename/copy/move 路由(文件管理,次要)+preview 后续。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…reveal) 承接 tree/read/write 沙盒感知,补齐编辑器文件管理全套:每个路由用 resolveReqFs 判沙盒, 有沙盒走 adapter(create→mkdir+writeFile/writeFileBytes、delete→rm -rf、mkdir→ sandbox.mkdir、rename/move→mv、copy→cp -r,均经 exec + shq 防注入 + sbExists(test -e) 做存在性校验保持 404/400 语义);无沙盒走本地 fs(gated 零回归)。reveal 在沙盒下诚实 报缺口(文件在远程 E2B,本机资源管理器打不开)。 新增 shq(shell 单引号转义) + sbExists(test -e) 助手。tree/read/write 已活体验证 (curl 实证:本地 temp 空、文件树/读/写全路由进 E2B 沙盒),CRUD 同款 resolveReqFs 机制 + 已 smoke 过的 adapter 原语。剩 search/replace/download/export-zip/preview 后续。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
deliver_app/M11 的 startDevServerAndProbe 原是本地 spawn(npm run dev,detached) + 探
localhost。Model A 下项目活在 E2B,本机连不到沙盒内端口 → 必须在沙盒内后台跑 + 经
E2B 端口转发(<port>-<id>.e2b.app)访问。
新增能力:
- SandboxAdapter.execBackground(cmd,opts)→SandboxBgProcess(pid/output/kill):E2B
commands.run({background:true,onStdout/onStderr 累积});local spawn detached。
- startDevServerInSandbox:沙盒内后台起 dev server(注入 HOST=0.0.0.0 PORT=3000 让端口
转发命中)→轮询输出解析端口(回退3000)→getHost(port)→fetch https://host 探活→返回
公网 URL + bg 句柄(供 kill)。
- startDevServerAndProbe 顶部 getActiveSandbox() 分流;stopDevServer 统一回收(沙盒走
sandboxProc.kill 不能用本机 process.kill 杀沙盒 pid,本地走 killDeliveredServer)。
- deliver_app/M11 三 caller + session 删除全接 stopDevServer;deletePersistedSession
连带 destroyForSession 销毁沙盒(释放 E2B wall-time)。
★真 E2B smoke 全验证★:execBackground npm run dev→pid+输出捕获→getHost(3000)=
3000-<id>.e2b.app→fetch https 200 "PREVIEW-OK"→kill。tsc+30 单测绿。gated 零回归。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
活体实测撞到:E2B 沙盒默认生命周期到期(我们设 30min)后被回收,但 CodingSandboxManager 仍持死 handle → 后续 writeFile 到死 handle 不报错但不持久 = 静默数据丢失(测 file-api CRUD 时发现 server 日志「云沙盒超时重置」+ 写 success 但读不到)。 修:CodingSandboxManager.touch(sessionId) → sandbox.setTimeout(30min) 从现在起重新计时 (滑动窗口)。conversation.ts runInSessionContext 每轮(有活动)调 touch:活跃 session 持续 续期=永不超时;废弃 session 不再 touch → 30min 后自然回收(成本安全不泄漏)。best-effort fire-and-forget,续期失败(沙盒已死)只告警不静默。3 单测(续期/未知session/销毁后 no-op)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
承接 tree/read/write/CRUD 沙盒感知,补编辑器高频次要操作: - /search:沙盒走 grep -rnI(GNU grep 沙盒里有) + JS 算 column/length/preview,输出与 ripgrep 路径同构 SearchResult;排除 EXCLUDED_DIRS;-E/-F/-i/-w 映射 isRegex/case/word。 - /download:沙盒走 readFileBytes 整块发(二进制保真),本地保持流式。 - /replace:单文件 readFile→按 line/column 改→writeFile,沙盒走 adapter。 全部 resolveReqFs gated(无沙盒=本地,零回归)。 剩 /preview-static + /export-zip 沙盒化待后续:rootB64=base64(SANDBOX_PROJECT_ROOT) 跨 session 相同→preview-asset 反查映射歧义,且 dev-server preview(startDevServerInSandbox) 已是真 app 的主预览路径,静态 html 预览/整包下载是低频次要项,单列跟进。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
M13 收官翻开关(用户拍板「默认开 + 显式 opt-out」)。前置全部落地+验证:核心 pipeline 全 5 层真 E2B contract PASS / 编辑器可见层(file-api tree/read/write/CRUD/search/download/ replace 沙盒感知,curl 实证) / preview(E2B dev server+getHost,真实公网 URL e2e 实证) / keepAlive(滑动 timeout 防超时重置静默写丢失)。 isSandboxCodingEnabled = isCloudEdition() && AXON_SANDBOX_CODING !== '0': - cloud edition 默认启用云沙盒(对齐 Manus always-on app-lives-in-E2B 模型) - AXON_SANDBOX_CODING=0 = 逃生 opt-out(cloud 部署不想用沙盒时关) - ★community edition 永不启用(isCloudEdition 门)= 零成本零依赖 E2B,零回归★ 代价:每 cloud coding session 建 E2B 沙盒(wall-time 计费;活跃 keepAlive 续期/废弃 30min 回收)。manager 19 单测(default-on/opt-out=0/community 三态)。 剩余次要项(不阻塞,noted):file-api /preview-static + /export-zip 沙盒化(rootB64 跨 session 歧义,dev-server preview 已是主预览路径);shell_session(持久 shell 在 E2B, 当前优雅引导用 Bash);CodingSandboxManager 沙盒 liveness 主动探测(keepAlive 已大幅缓解)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
touch() 续期(setTimeout)失败 = 沙盒已被 E2B 回收(idle>timeout 后 resume 的罕见 case, keepAlive 没接住)。原只告警、保留死 handle → get()/getByProjectPath 继续把死 handle 返给 工具/编辑器(file-api),writeFile 到死 handle 不报错但不持久 = 静默写丢失(活体撞到同类坑)。 修:续期失败时从 bySession + sessionByProjectPath 清掉该死 handle → get() 返 null → 工具/编辑器走本地空目录(可见"项目空了"信号),好过对死沙盒静默写骗人。文件已丢无法救但 不再静默。20 单测(+1 僵尸清理)。 注:proactive keepAlive 滑动 timeout 已覆盖活跃 session(永不超时);本硬化兜 idle-resume 边缘。沙盒过期后的「重建空沙盒 vs 报错让用户重启」UX 是产品决策,记 backlog。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
cloud coding session 的「下载整个项目为 zip」要从沙盒收集(原走本地 fs walk addDirToZip)。 resolveReqFs 判沙盒 → find -type f(排除 node_modules/.git) + readFileBytes 每文件(二进制 保真) → JSZip 打包发。无沙盒走原本地逻辑(gated 零回归)。 至此 file-api 编辑器操作除 /preview-static 外全沙盒化(tree/read/write/CRUD/search/ download/replace/export-zip)。/preview-static 待后续:rootB64=base64(SANDBOX_PROJECT_ROOT) 跨 session 歧义,preview-asset 反查需带 sessionId 重设计;dev-server preview 已是主预览路径。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
M13 后 cloud coding session 文件活在 E2B,但 handlePublishToAxonApp 全是本地 fs (detectAppStack/runProjectBuild/collectDeployFiles/Railway sourceDir) → 从空本地 cwd 收集 = 发布不了沙盒项目。这是 M13×M15 关键集成缺口。 方案(最小复用既有本地流程):getActiveSandbox() 时 → 1. 沙盒内 npm run build(若有 build script,node_modules 在沙盒里);非0退出中止回日志。 2. syncSandboxToLocal:find 项目文件(去 node_modules/.git) + readFileBytes 镜像到本地 temp。 3. cwd 重指向 temp → 既有流程原样跑:静态站 temp 里有沙盒 build 的 dist→Vercel(inline files); 全栈 temp 是 source→Railway 远端构建。sandboxAlreadyBuilt 跳本地重 build(temp 无 node_modules)。 slug 提前从沙盒 package.json.name 抓(cwd 重指向后 cfs 读不到沙盒)。 tsc + 106 单测(deploy 8 套未动 + cloud-sandbox)绿。★live 发布验证需 Vercel/Railway token (用户已配)+外部服务,链路逻辑已通,待真发布实证★。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
用户拍板(2026-05-31):先免费/每账号初始化 1000 额度/套餐后置/提前预留接口。 叠在 M14 UsageTracker(已折算 credits)之上加 account→balance 钱包层: - INITIAL_CREDIT_GRANT=1000 懒初始化 + initial_grant 流水 - 「先免费」= enforce off:charge 真扣(累计真实用量,可扣穿负数),canAfford 永放行; 套餐上线翻 AXON_BILLING_ENFORCE=1 即生效,老 balance 无需迁移 - accountId 维度参数化(default 'local')预留 multi-tenant —— axon 当前单机无账号系统 - 双轨:cloud 落盘 <configDir>/credits/<id>.json;community enabled=false 全 no-op 零回归 - Plan 接口 + FREE_PLAN 占位(套餐分层/月度刷新/Stripe 后置不做) - 损坏钱包文件直接报错拒绝静默重置(铁律6) 30/30 单测绿(含 init/扣穿/enforce 双态/持久化重载/community no-op/edition 门);tsc 0 error Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
逐项核实发现多项已做:M7 覆盖率门已实现+单测、m7-executes-in-order 是合理 SKIP 非缺口、base-react shadcn token 已补全、M13.f 本 session 全接通、M16.b credit 钱包骨架已落地。结论:编程护城河(主线A)已无可 loop 自主的明确高价值剩余活, 真打磨需来自真实使用场景反馈(铁律11)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 用户拍板「自造任务做端到端体检」。现有 e2e-full-flow 是零依赖纯内存 Express TODO API,本 suite 故意选未覆盖路径:带真实 npm 依赖(marked)的 Express 服务。 体检执行层会不会 npm install 外部依赖、装完 typecheck/test 含依赖类型能否过。 复用 e2e-full-flow harness 逐层读盘报告断点。实跑 1/1 全 5 层真闭环 PASS。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
体检发现:agent 在 nudge 下常重复调 deliver_app。原逻辑每次都「回收旧 dev server (process.kill -pid 发 SIGTERM) + 立刻起新 server」,SIGTERM 在途、端口未释放就起新 server 撞同端口 → EADDRINUSE → 新 server 起不来 → 20s 超时 → serverUrl=null (双硬门仍过 delivered=true,但交付 URL 丢失)。 改为幂等交付:reuseDeliveredServerIfAlive 探本 session 上次交付 server 是否仍存活 (本地 process.kill(pid,0) 探活/沙盒看句柄),活则复用其 URL,不回收不重起。首次交付 返回 undefined → 走原「回收残留+起新」路径,逻辑零改动。 验证:m8-deliver 回归门 5/5 PASS(首次 deliver 路径不变);tsc 0 error。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
第一轮 healthcheck-md-api 是后端 Express。本轮选前端 Vite + TS 单位换算 SPA,体检 不同代码路径:deliver_app 探活 Vite dev server 根路径 200(非 API 404)、Vite 构建。 换算逻辑抽 src/convert.ts 纯函数让验收 cli probe 可确定性验。 实跑 1/1 全 5 层真闭环 PASS,delivery.serverUrl=http://localhost:5173/(有值, 印证前端根 200 探活更顺);顺带验证 deliver 幂等修复在真实长流程工作。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…plan 接口预留" This reverts commit 7d51dad.
第三轮选真实 Manus 级全栈 SaaS(NotesSaaS:注册/登录/token+SQLite持久化+受保护CRUD+数据隔离), 覆盖前两轮没碰的路径:auth 逻辑、SQLite native 依赖(better-sqlite3)、受保护路由中间件、多依赖。 实跑全 5 层真闭环 PASS:task-1~5 全 done、lint+typecheck+test 绿、验收 100% (register→login→token→建note→查到 + 无token→401)。证明护城河对全栈形态同样成立。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…null 体检两形态(md-api/全栈)复现铁证:agent coding 时常用 Bash 起 dev server 验证、占了项目 默认端口(如 3000)没回收,deliver_app 探活再起同端口 server 撞 EADDRINUSE → 20s 超时 → serverUrl=null(双硬门仍过 delivered=true,但交付 URL 丢失,用户拿不到"打开看看"链接)。 治本:deliver 起 dev server 前 findFreePort() 分配空闲端口,注入 PORT env。server 读 PORT 起在空闲端口并打印该 URL,探活的输出解析自然探通——不依赖默认端口、不依赖清孤儿。 沙盒分支忽略 port(getHost 走 E2B 公网域名);UI 契约验证不传 port 保持旧行为。 验证:m8-deliver 回归 5/5 不退步;修复有效性复现实证(注入端口→server 起空闲端口→探活探通);tsc 0。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… + dashboard e2e
mode-parity 弧线收官(用户实测 slides 翻车触发的全面对齐):
- slides 重做:自包含 HTML deck 画布翻页 + deliver_slides + 两层硬门(toolFilter 防逃逸 +
内容完整性门),复用 website 交付链路;slides-deck eval 1/1。
- viz/spreadsheet/app/desktop-app 路由到 coding agent(prompt 极简引导 enter_coding_mode);
app/desktop-app 从 CODING_CONTEXT_MODES 移出,修 M5 起「在 set 里但无独立管线 → enter_coding_mode
被 noop 卡裸 mode」的半成品陷阱;modeRegistry 8 决策锁测试固化。
- video/design/audio verify-first 确认已 AI-native 完整(媒体工具全注册可达 + MarkdownContent
内联播放器 + 无 key 明确报错),backlog 高估,不照补(铁律2)。
coding 产物画布可见性(对齐 Manus「画布看产物」):
- deliver_app 成功 emit coding_app_preview { serverUrl } → 前端 WebsitePreviewPane directUrl
iframe 渲染 live dev server;混合内容(主 https + 本地 dev http)诚实降级提示 + 外链。
- 5 个 jsdom 组件测试钉死 React 接线(eval 抓不到的盲区)。
修复 chip mode 首条消息丢失 hot-path bug:
- 根因:chat handler 在 prepareChatSession 前调 setSessionMode,首条时 sessionId 还是 temp、CM
session 未建 → no-op,chip mode 丢,首轮跑 base。
- 修:StreamCallbacks 加 entryMode 透传 → chat() 内 getOrCreateSession 后「仅 state.mode!=='coding'」
才应用(防 turn2 把已升级 coding 降级回 chip,前端每轮都带 mode);删错位调用。
- 双 viz 探针验证(turn1 undefined→visualization 应用 / turn2 不降级)+ slides-deck 1/1 回归。
e2e:e2e-full-flow harness 加画布可见性断言;新增 Manus 旗舰数据看板 case(viz chip → 全 5 层 →
deliver_app → 画布可见,1/1 PASS)+ AXON_E2E_CASE 单 case 过滤器。产物经实证为竞品级质量(数据驱动
柱状图 + XSS 防护 + 可访问性 + 响应式 + supertest 真集成测试),非过门 gaming。
两端 typecheck 0 error。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changes
Related Issue
Testing
npx tsc --noEmitpassesnpm test -- --runpassesScreenshots