Files
web-terminal/docs/PROGRESS_LOG.md
2026-06-16 08:10:38 +02:00

175 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 后端 ✓(T3/T4/T5/T6/T7,128 测试全绿)→ 下一步 **W1 前端批次 T8T11**
- **任务**: 派第二批 W1(前端,parallel):T8 index.html · T9 style.css · T10 keybar · T11 main.ts。
之后 W2 **T12 session**(opus,依赖 T6 ring-buffer + T3 mock,均已就绪)。
- **下一步**: 按 DISPATCH 派 T8T11(general-purpose + §4 模型;**注**自定义 agent 需重启会话才加载,本会话用 general-purpose 内联角色)。
- **阻塞**: 无。
- **最后更新**: 2026-06-16
---
## 任务总览 (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` | `[ ]` | 0/1 | — |
| T9 | W1 | `public/style.css` | `[ ]` | 0/1 | — |
| T10 | W1 | `public/keybar.ts` | `[ ]` | 0/4 | — |
| T11 | W1 | `public/main.ts` | `[ ]` | 0/6 | — |
| T12 | W2 | `session/session.ts` | `[ ]` | 0/7 | — |
| T13 | W3 | `session/manager.ts` | `[ ]` | 0/6 | — |
| T14 | W4 | `server.ts` 接线 | `[ ]` | 0/6 | — |
| T15 | W4 | 集成 / E2E 测试 | `[ ]` | 0/2 | — |
| T16 | W5 | 验收 F1F3(终端/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)
> **倒序**,最新在最上。每个子任务一条。复制下方模板填写。
<!-- ========== 条目模板(复制此块,删除注释) ==========
### YYYY-MM-DD · S?.? <子任务标题>
- **状态**: `[x]` DONE / `[~]` IN PROGRESS / `[!]` BLOCKED
- **改动**: <文件:函数/范围,如 src/protocol.ts:parseClientMessage、test/protocol.test.ts>
- **验证**: <跑了什么命令 + 结果。如 `npm test` → 12 passed;或贴关键断言>
- **决策 / 偏离 PLAN**: <无 / 为何偏离 + 是否已回写 PLAN.md>
- **遗留 / 待办**: <无 / 后续子任务需注意的点>
- **阻塞**(仅 `[!]` 时): <卡在哪,需要什么>
- **commit**: <hash 或 N/A>
======================================================= -->
### 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-16 · W1 后端批次(T3/T4/T5/T6/T7)— 5 个并行 builder
- **状态**: `[x]` ALL DONE
- **派活方式**: 5 个 `general-purpose` subagent 并行(自定义 module-builder agent 需重启会话才加载,故本会话内联角色),
共享工作树 + **文件所有权严格不交叉** + scoped `vitest run <name>`(官方文件分区法,替代 worktree;合并即 commit)。模型按 §4。
- **改动**(各 agent 仅在 Owns 内):
- **T3** `test/helpers/mock-pty.ts`(+ smoke test):IPty 替身,`emitData`/`emitExit` 手动触发、记录 write/resize/kill、onData/onExit 返回 IDisposable。
- **T4** `src/config.ts`(+ test):`loadConfig(EnvLike)`;M1 origins 由 `os.networkInterfaces()` 推导(含 localhost,**剔除 0.0.0.0/internal**,http+https),wsPath 默认 /term,非法值 fail-fast,`Object.freeze`
- **T5** `src/protocol.ts`(+ test):`SESSION_ID_RE`(UUID v4)、`parseClientMessage`(永不抛,全分支校验,M7 拒 `abc123`)、`serialize`
- **T6** `src/session/ring-buffer.ts`(+ test):M2 按真实字节(Buffer)计量、按 chunk 边界淘汰、不切碎 UTF-8/ANSI、snapshot 补 `\x1b[0m`
- **T7** `src/http/origin.ts`(+ test):用 WHATWG `URL` 比 protocol+host+port,undefined/解析失败拒绝。
- **验证(orchestrator 独立复核,非仅信 agent)**: `npx tsc -p tsconfig.json --noEmit` PASS;`npm test`(全量)
**5 文件 / 128 测试全绿**(T4 32 + T5 60 + T6 15 + T7 12 + T3 9)。
- **决策 / 偏离**: 无源码偏离。流程上:本批用 general-purpose 内联角色(见上)。T6 对"单块 > 容量"按 M2"绝不切碎"保留整块(测试固化),属忠实落地。
- **遗留 / 待办**: W1 前端 T8T11 待派;之后 T12 session(mock+ring-buffer 已就绪)。
- **commit**: `0fa0b69`
### 2026-06-16 · T2 冻结共享类型契约 src/types.ts
- **状态**: `[x]` DONE
- **改动**: 新建 `src/types.ts`(纯类型,无实现);删 `src/.gitkeep`。含 Config、ClientMessage/ServerMessage/
ParseResult、Dims、IPty(子集)+ IDisposable/PtyEvent、RingBuffer、WebSocketLike + WS_OPEN、SessionMeta/Session
(lastOutputAt/exitedAt/exitCode)、SessionManager、MountKeybar;各模块工厂函数签名以注释列为 import 锚点。
同步更新 ARCHITECTURE §3.1/§3.4(加 wsPath、EnvLike、WebSocketLike 注记,防漂移)。
- **验证**: `npx tsc -p tsconfig.json --noEmit` PASS;grep 确认无 `ws`/`NodeJS`/DOM 外部类型依赖(仅注释提及)。
- **决策 / 偏离 ARCHITECTURE §3**(为"前后端共享 → 必须无外部类型依赖"):
1. `loadConfig(env: EnvLike)` 替代 `NodeJS.ProcessEnv`(`EnvLike = Readonly<Record<string,string|undefined>>`,process.env 可赋值)。
2. `Session.attachedWs: WebSocketLike` 替代 `ws``WebSocket`(真实 ws 结构兼容);导出 `WS_OPEN=1` 供 M5 守卫。
3. **新增 `Config.wsPath`**(默认 '/term'):不变量 8 要求 WS 路径入 config,§3.1 原 Config 漏列,已补;T4 需从 env `WS_PATH` 读、T14 用 `cfg.wsPath`
三处均已回写 ARCHITECTURE,types.ts 为权威冻结源。
- **遗留 / 待办**: 无。W1 全部任务现可只读 import `src/types.ts`。**注意**:IPty/WebSocketLike 是结构子集,
实现方(T12/T14)可把真实 node-pty IPty / ws.WebSocket 直接赋值(结构兼容)。
- **commit**: (见下次提交)
### 2026-06-16 · T1 补记 — 前端打包定为 esbuild
- **状态**: `[x]` DONE
- **改动**: 装 `esbuild`(dev);`package.json``build:web`/`dev:web`(打包 `public/main.ts``public/build/main.js`);
`.gitignore` 改忽略 `public/build/`;`tsconfig.web.json` 注释更新为"仅类型检查";前端构建约定写入
`PLAN §1` 并更新 T8/T11/T14 与 `DISPATCH.md``ARCHITECTURE §5`
- **验证**: esbuild 0.28.1;临时入口 `--bundle --format=esm --outdir=public/build``main.js`+`.map`,smoke 通过。
- **决策**: 三选一中选 **esbuild**(极快、零配置、与 node-pty/tsx 生态一致);**现在装好**避免 W1 并发 install。
约定:入口 main.ts、产物 public/build/(已 gitignore)、index.html 用 `<script type=module src=./build/main.js>`、server 静态托管 public/。
- **commit**: (见下次提交)
### 2026-06-15 · T0 项目记录起点(计划就绪)
- **状态**: `[x]` DONE
- **改动**: 创建 `docs/PROGRESS_LOG.md``docs/PLAN.md`(细粒度 T1T21、为多 agent 并行设计);`CLAUDE.md` 加入 plan/log 工作流约束。
- **验证**: 文档自检;LOG 任务总览的 Steps 总数已与 PLAN 各任务勾选项对齐。
- **决策 / 偏离 PLAN**: 采用 TypeScript(ARCHITECTURE §0);两份设计文档已多团队交叉验证并修订 12 项;计划按依赖分 W0W5 波次,W1 含 9 个零交叉并行任务。
- **遗留 / 待办**: 进入 **W0 / T1**(脚手架 + 装齐依赖);T1 完成后 T2 冻结 `src/types.ts`,随后 W1 可大规模并行。
- **commit**: N/A