# Web Terminal 实施进度日志 (Progress Log) > **用途**: 记录 [PLAN.md](./PLAN.md) 各任务的完成情况,作为**跨会话记忆文件**。 > 新会话开工前**必读本文件**。只记**已发生的事实**(含失败、跳过),不预填未来,不写愿望。 > **谁来写(G1)**: 本文件**仅由 orchestrator(主会话)写入** —— 它不在任何任务的 `Owns:` 里, > 防止并行 subagent 并发写冲突。被派的 subagent **不写本文件**,而是把日志条目作为返回结果交回, > 由 orchestrator 在每批 agent 返回后**立即追加**(不要攒到最后)。 > 完整维护规则见 [CLAUDE.md → Development Workflow](../CLAUDE.md)。 --- ## 状态图例 | 标记 | 含义 | |------|------| | `[ ]` | TODO — 未开始 | | `[~]` | IN PROGRESS — 进行中 | | `[x]` | DONE — 完成且已验证 | | `[!]` | BLOCKED — 受阻(须在详细日志写明阻塞原因) | --- ## 当前焦点 (Current Focus) > 新会话读到的第一块。保持准确,只描述"此刻"。 - **Wave**: W0 ✓ · W1 ✓ · **W2/W3/W4 ✓**(T12 session · T13 manager · T14 server · T15 集成)→ 下一步 **W5 验收 + 收尾** - **进度**: **15/21 任务 · 187 测试全绿 · 真 PTY 端到端已验证**(集成 ⑤⑥ sandbox-off 6/6:attach→output + 重连回放 F5/F6 含 CJK/ANSI)。产品功能完整。 - **任务**: W5 = T16–T20 验收(F1–F9,多数需**真浏览器/真机**)+ T21(orchestrator:安全核对 + README + LOG 收尾)。 已由集成测试覆盖的:**F9**(①②坏Origin/路径)、**F5/F6**(⑤⑥回放)、**F8 部分**(④exit)。需真机的:F1–F4、F7。 - **下一步**: orchestrator 做 T21(README+安全),并对 F1–F3 尝试无头浏览器 smoke;F4(局域网)/F7(手机)交用户真机验。 - **阻塞**: 无。 - **次要 tech-debt**: main.ts 1 处 `@ts-ignore`(CSS import);未来加 `*.css` d.ts。 - **最后更新**: 2026-06-17 --- ## 任务总览 (Task Overview) > 任务定义见 [PLAN.md](./PLAN.md);按 Wave 分组。`Steps` 完成数 = PLAN 中该任务的勾选项。 > **多 agent 并行**:同一 Wave 内任务互不依赖,可并行;跨 Wave 按依赖推进。 | 任务 | Wave | 模块 | 状态 | Steps (完成/总) | 完成日期 | |------|------|------|------|------------------|----------| | T1 | W0 | 脚手架 + 装齐依赖 | `[x]` | 5/5 | 2026-06-16 | | T2 | W0 | `src/types.ts` 共享契约(冻结源) | `[x]` | 8/8 | 2026-06-16 | | T3 | W0 | mock IPty 测试替身 | `[x]` | 2/2 | 2026-06-16 | | T4 | W1 | `config.ts` | `[x]` | 5/5 | 2026-06-16 | | T5 | W1 | `protocol.ts` | `[x]` | 4/4 | 2026-06-16 | | T6 | W1 | `ring-buffer.ts` | `[x]` | 4/4 | 2026-06-16 | | T7 | W1 | `http/origin.ts` | `[x]` | 3/3 | 2026-06-16 | | T8 | W1 | `public/index.html` | `[x]` | 1/1 | 2026-06-16 | | T9 | W1 | `public/style.css` | `[x]` | 1/1 | 2026-06-16 | | T10 | W1 | `public/keybar.ts` | `[x]` | 4/4 | 2026-06-16 | | T11 | W1 | `public/main.ts` | `[x]` | 6/6 | 2026-06-16 | | T12 | W2 | `session/session.ts` | `[x]` | 7/7 | 2026-06-16 | | T13 | W3 | `session/manager.ts` | `[x]` | 6/6 | 2026-06-16 | | T14 | W4 | `server.ts` 接线 | `[x]` | 6/6 | 2026-06-17 | | T15 | W4 | 集成 / E2E 测试 | `[x]` | 2/2 | 2026-06-17 | | T16 | W5 | 验收 F1–F3(终端/TUI/resize) | `[ ]` | 0/3 | — | | T17 | W5 | 验收 F4+F9(LAN/Origin) | `[ ]` | 0/2 | — | | T18 | W5 | 验收 F5+F6(保活/回放) | `[ ]` | 0/2 | — | | T19 | W5 | 验收 F7(移动键栏) | `[ ]` | 0/1 | — | | T20 | W5 | 验收 F8(退出处理) | `[ ]` | 0/2 | — | | T21 | W5 | 安全核对 + README + LOG 收尾 | `[ ]` | 0/3 | — | --- ## 验收清单映射 (Acceptance — TECH_DOC §8) > 功能验收独立于阶段勾选;F* 全绿才算 v0.1 完成。 | 编号 | 功能 | 状态 | 验证方式 / 备注 | |------|------|------|-----------------| | F1 | 交互式终端(ls/补全/Ctrl+C/历史) | `[ ]` | | | F2 | 全彩 + 全屏程序(vim/top/claude) | `[ ]` | | | F3 | 终端自适应(resize 不错位) | `[ ]` | | | F4 | 局域网访问(手机/他机) | `[ ]` | 与 F9 联测,确认 Origin 白名单含网卡 IP | | F5 | 会话保活(断开重连仍在跑) | `[ ]` | | | F6 | 重连回放(环形缓冲) | `[ ]` | 验证 ANSI/中文不乱码(M2) | | F7 | 移动快捷键栏 | `[ ]` | | | F8 | 进程退出处理 | `[ ]` | 含 detach 后退出补发 exit(L1) | | F9 | Origin 校验(401) | `[ ]` | 含 `/term` 路径限制(L3) | --- ## 详细日志 (Detailed Log) > **倒序**,最新在最上。每个子任务一条。复制下方模板填写。 ### 2026-06-16 · T1 脚手架 + 一次性装齐依赖 - **状态**: `[x]` DONE - **改动**: `package.json`(scripts + 全部依赖 + `postinstall`)、`tsconfig.json`(后端 NodeNext/strict)、 `tsconfig.web.json`(前端 DOM/Bundler,当前 noEmit 仅类型检查)、`vitest.config.ts`(node 环境 + `passWithNoTests`)、`.gitignore`、`package-lock.json`、目录骨架 `src{,/http,/session} public test{,/helpers,/integration}`(各带 `.gitkeep`)。 - **验证**: - `npm install` 成功(运行时 72 包 + 开发包,0 漏洞)。解析版本(均比预期新的主版本):express **5.2**、 @xterm/xterm **6.0**、addon-fit 0.11、ws 8.21、node-pty 1.1;dev:typescript **6.0**、vitest **4.1**、tsx 4.22、@types/node 25。 - `node -e require('node-pty')` → OK;**真实 PTY spawn** `echo hello-from-pty` → 16 bytes、exitCode 0(沙箱外验证)。 - `npm test` → exit 0(passWithNoTests)。 - **决策 / 偏离 PLAN**: 1. **node-pty spawn-helper 修复**:1.1.0 的 prebuild 自带 `spawn-helper` 但权限 `-rw-r--r--`(缺 +x), 导致 `posix_spawnp failed`。加 `postinstall: chmod +x .../prebuilds/darwin-*/spawn-helper`(对 Linux 无害,`|| true`), 使每次 install / 每个 worktree 自动修复。**T12 spawn PTY 依赖此修复。** 2. 依赖解析到较新主版本(express 5 / xterm 6 / typescript 6 / vitest 4):**T7/T11/T14/T15 注意 API 差异** (express 5 路由、xterm 6 import 形态)。 3. 加了 PLAN 未列的脚本 `dev`/`typecheck` 与 `postinstall`(便利 + 必需修复),属合理补充,未改 PLAN 意图。 - **遗留 / 待办**: 无(原前端打包待决项已解决,见下补记)。 - **commit**: `b126cf0` ### 2026-06-17 · W2/W3/W4 — 会话核心 + 集成(T12/T13/T14/T15) - **状态**: `[x]` ALL DONE · 串行(各有依赖),单 builder/任务 - **T12 `session/session.ts`**(opus,19 测试):createSession/attachWs/detachWs/writeInput/resize/kill;onData→buffer+lastOutputAt+转发;onExit→exitedAt/exitCode+发exit+注入onExit;**spawn 失败抛(M4)**;sendIfOpen 守卫 readyState(M5);detach 不杀 PTY;exit 后 write/resize 忽略(L4);detach 后退出保留会话(L1)。测试 `vi.mock('node-pty')`→mock IPty,沙箱内可跑。 - **T13 `session/manager.ts`**(sonnet,21 测试):handleAttach 四路径(新建/存活/已退出 L1/查不到);reapIdle `now-max(detachedAt,lastOutputAt)>idleTtl`(M3);shutdown 全 kill;注入 onExit 在线退出删表、detach 后退出保留待 L1(L2)。 - **T14 `server.ts`**(sonnet,~200 行):Express 静态 public/+build/;`WebSocketServer({noServer,maxPayload})`(L5);upgrade 门(非 wsPath→destroy、坏 Origin→401、过→handleUpgrade,L3);connection 等 attach,try/catch→spawn 失败 exit(-1)+关连接(M4);message 路由;close→detach(不杀);SIGINT/TERM→shutdown;reapIdle 定时器;safeSend 守卫(M5)。导出 startServer 供 T15。 - **T15 集成**(sonnet,6 用例):真 ws 客户端打 startServer。①坏Origin 401 ②错路径 destroy ③超 maxPayload 1009 ④spawn失败 exit(-1) —— 沙箱内全绿;⑤attach→output ⑥重连回放(F5/F6,含 `__MARK_测试__` CJK)—— **orchestrator 加 `PTY_AVAILABLE` 门控(沙箱自动 skip,真机跑),关沙箱验证 6/6 全绿**。 - **验证(orchestrator 独立复核)**: 每步 `tsc --noEmit` ✓ + 全量 `npm test` 递增至 **187 全绿**;集成 sandbox-off 6/6(真 PTY)。 - **决策 / 偏离**: T12 onData 时间戳用 Date.now()(事件时刻,符合 lastOutputAt 语义);T15 由 orchestrator 加 PTY 可用性门控(原 `it.skip` → `itPty`),使真机会跑、沙箱自动跳过。 - **commit**: `20212dd`(T12)·`a2897b2`(T13)·`0dac54b`(T14)·`cdec19a`(T15) ### 2026-06-16 · W1 前端批次(T8/T9/T10/T11) - **状态**: `[x]` ALL DONE - **派活方式**: 因 T11 import T10 的 mountKeybar 且验收是整目录 tsc.web,分两步:**先并行 T8+T9+T10(haiku),后 T11(sonnet)**。general-purpose 内联角色,共享树 + 文件不交叉。 - **改动**: - **T8** `public/index.html`:#term/#keybar、viewport、`