# M5 安装器与多本书 ## Goal 作者在干净环境(含 Windows 中文用户名路径)一条命令装出可用的工作目录,建起第一本书;写章八阶段的每一步都有宿主可调的 CLI 通道,`finalize→next` 主循环可全程经 CLI 跑通。 对应实施计划 0.3 §2「M5 安装器与多本书」,上游依据:`multi-agent-adaptation-spec` v3.5 §8(init/update)、`story-repo-spec` 0.9 §2.0(工作目录层)、M1-M4 review follow-up F1(宿主 CLI 缝清单)。 ## Background(已确认事实) - M0-M4 已交付:格式层 41 读接口、写章脚本面(prepare-chapter/mechanical-check)、状态机 7 态 + git 隐身、AI 角色层 + 壳生成器(`src/host-shells/generate.js` + `scripts/build-host-shells.mjs --check` 已进 CI)。边界收口任务已归档,292 测试绿。 - `src/installer/index.js` 是占位空文件。 - **落盘用例已齐但无 CLI 通道**:`persistDraftOutline` / `persistCreateBook` / `persistVolumeReview` / `persistRepair`(`src/state-machine/persist.js`)、`assembleReviewInput` / `runReviews`(`src/review/index.js`)、`finalizeChapter`(`src/finalize/index.js`)只能进程内调用——真宿主(AI 会话)无法驱动写章后半段,M4 真模型 smoke 因此推迟 beta(registry `smoke_status: deferred-beta`)。 - **工作目录定位未做**:`bin/webnovel-writer.js` 写死 `repoPath = process.cwd()`(M1 design 注释「M3 后续处理」,M3 未做)。装出的工作目录里跑 CLI 会把 `.cache` 建在工作目录而非书仓库,M5 必须先解决。 - `books.jsonl` 读侧 + 扫描重建自愈已在 M4(`src/session/index.js`,含 `writeBooksRegistry` 自愈回写);**写侧(建书登记/换书)归 M5**(源码注释明示)。 - 工作目录 `AGENTS.md` 模板已有(`v7/templates/AGENTS.md`,含 `` 标记块);书仓库指路 `AGENTS.md`(spec §2.1「建书时自动生成」)尚无实现——`persistCreateBook` 不写它。 - 壳生成器产物形状:`{ : { 'skills/webnovel-writer/SKILL.md', 'agents/<角色>.md|.toml' } }`,无 hook 接线;claude-code 的 SessionStart hook 注入(multi-agent spec §5.5)需要 M5 在装出的 `.claude/` 里接线。 - SKILL.md 当前硬编码 `webnovel-writer <命令>` 调用形式;spec §5.9 要求命令引用语法做成平台上下文变量。 - Node 版本门槛(≥ 22.13.0)与人话提示已在 `src/runtime/node-version.js`,bin 已接。 - 运行时依赖仅 `js-yaml`(spec §2.2),`.webnovel/` 自带脚本时需一并解决其可用性。 - CI 现状(`.github/workflows/v7-ci.yml`):双平台 × 双 Node 版本,`node --test` + drift check + `--version` 冒烟;无安装器链路用例。 ## Requirements ### A. 安装器 `init` / `update`(multi-agent spec §8) - A1 `init`:环境检测(Node 门槛复用现有函数;按 registry 顺序探测已装 agent CLI)→ 生成工作目录布局: - `AGENTS.md`(公约数层,标记块管理;块外用户内容保留) - `.webnovel/`(Node 脚本 + 角色定义 + 模板哈希清单 + `books.jsonl` 占位)——工作目录自包含,脚本离线可跑 - 检测到的各平台壳(`.claude/`、`.codex/` 等,由 M4 生成器按条件块编译;claude-code 含 SessionStart hook 接线) - 结束输出报告:装到了哪、各宿主支持等级、降级说明、下一步人话指引 - A2 `update`:模板哈希追踪——哈希未变的文件直接更新;用户改过的提示并跳过(不静默覆盖),非交互默认跳过并列清单,`--force` 显式覆盖;`AGENTS.md` 只更新标记块内内容 - A3 边界(spec §8.3):不装 Node 之外的运行时、不改用户全局配置、不联网、不把工作目录变成 git 仓库;重复 `init` 幂等(等价于 update 语义或明确提示) - A4 平台壳 SKILL.md 的命令引用语法改为模板变量(§5.9),指向装出的 `.webnovel/` 内脚本;SKILL.md 写章流程同步接 F1 通道(`review-input`→两审→`save-review`→`finalize`,「继续」吃 `next --json` DTO) ### B. 多本书与工作目录定位(story-repo spec §2.0) - B1 `books.jsonl` 写侧:建书登记(字段含 书名/目录/当前/最后打开)、换书(改「当前」标记)、书单列出;与 M4 读侧/自愈共用一个模块,不双写格式 - B2 工作目录定位:bin 启动时判定——cwd 含 `book.yaml` → 书仓库直启(兼容开发/测试);cwd 含 `.webnovel/` → 按 `books.jsonl` 当前书解析 `repoPath`,无当前书给人话指引;两者都不是 → 人话提示「请从工作目录启动」。`init` 等工作目录层命令不受此约束 - B3 书仓库指路 `AGENTS.md`:并入建书落盘(`persistCreateBook`),内容按 spec §2.1(误启动/单独 clone 时指回工作目录) - B4 SessionStart 注入接线:claude-code 壳带 hook 配置调 CLI 的会话上下文命令(输出复用 M4 `assembleSessionContext`,两宿主路径注入逐字一致) ### C. F1 宿主 CLI 缝(实施计划 0.3 M5 清单,逐条) - C1 `next --json`:输出完整状态机 DTO(`{ok, gitHealth, 序, state, needsAI, message, dto}`);不带 flag 保留现有人读 message - C2 `review-input <章号>`:组装 ReviewInput 并落盘供宿主读取 - C3 `save-review <章号> --file=<两审json>`:读文件 → schema 校验 → 合并 → 落审稿单与评审报告(复用 `runReviews` 的校验/合并/落盘路径) - C4 `persist-outline` / `persist-book` / `persist-volume-review` / `persist-repair`:AI 态产物回流,`--file=` 进;`persist-book` 同时完成 books.jsonl 登记 + 指路 AGENTS.md(B1/B3) - C5 `finalize <章号> --payload=<定稿包json路径>`:调 `finalizeChapter`,定稿后刷新缓存 - C6 JSON 一律走 `--file`/`--payload` 文件路径,不走 stdin(Windows 中文管道编码雷区);出错人话报错、退出码非零、永不带栈崩溃 ### D. CI 与验收链路 - D1 Windows 中文路径安装链路 CI:干净临时目录(路径含中文,模拟中文用户名)→ 一条命令 init → 建书(经 CLI)→ 布局断言(beta 判据「Windows 中文路径全链路」的 M5 补全) - D2 `finalize→next` 端到端经 CLI(子进程 spawn bin,非进程内调用)跑通:细纲→草稿→机检→审稿→定稿→next 报下一章 ## Acceptance Criteria - [ ] AC1 干净 Windows 中文用户名环境一条命令装出工作目录并建第一本书:CI 用例绿(npm pack 产物 + 中文路径临时目录全链路)+ 手测一次通过 —— CI 半已达成(run 28663338317 双平台 install-e2e 绿);**余用户手测** - [x] AC2 `init` 装出的布局逐项存在且内容正确:`AGENTS.md`(标记块)、`.webnovel/`(脚本可 `node` 直跑、`books.jsonl`、哈希清单)、检测到的平台壳;报告输出含支持等级与下一步指引 - [x] AC3 `update`:未改文件被更新;手改文件被跳过且列出;`AGENTS.md` 块外内容保留;`--force` 可覆盖 - [x] AC4 写章八阶段每一步都有宿主可调 CLI 通道:F1 清单 8 个命令逐个有测试(含 schema 校验失败、文件缺失的人话报错) - [x] AC5 `finalize→next` 端到端经 CLI 子进程跑通,next 报「起草第 N+1 章」不重抄 - [x] AC6 工作目录定位三分支(书仓库直启 / 工作目录+当前书 / 无处可依)各有测试;换书后 next 作用于新书 - [x] AC7 SessionStart 注入:hook 路径与无 hook 宿主状态机入口路径输出逐字一致(既有测试延伸到 CLI 通道) - [x] AC8 全量测试绿 + CI 双平台绿;drift check 对新增模板变量仍确定性通过 —— 335 绿;run 28663338317 六 job 全绿(4 测试矩阵 + 2 install-e2e) ## Out of Scope - 真实 npm 发布——「一条命令」验收用 npm pack 产物在 CI/手测模拟(与 npx 消费同一份包内容),真发 alpha 推迟 beta 入口:alpha 阶段没有外部用户,提前发包只引来不完整版本的使用(决策 D-1,start 评审可推翻)。随之推迟的发版联动:升 7.0.0、README 版本表 / marketplace / CHANGELOG 同步(版本 CI 不查 v7/package.json,保持 7.0.0-alpha 无风险) - 真模型 smoke(Claude Code / Codex 亲测)——推迟 beta(registry 已记 `deferred-beta`),M5 只负责让它可行 - M5.5 体检统计项(高频意象/句式/文体指纹) - M6 自动模式、M7 导出与 /migrate - 二级宿主(gemini-cli / cursor)的实测核验——壳照常生成,支持等级按 registry 如实标注 ## 规划决策(用户暂离,按推荐采纳;start 评审时可推翻) - D-1 发布形态:npm pack 模拟,真发推迟 beta(见 Out of Scope 首条) - D-2 检测缺省:init 未检测到任何 agent CLI → 只装公约数层(AGENTS.md + `.webnovel/`)并在报告指引 `--hosts` 补装——忠于 spec「按检测生成」,不掩盖探测失败 - D-3 任务结构:单任务推进,沿 M1-M4 先例;三块交付物(基座与多本书 / F1 缝 / 安装器)在 implement.md 里按依赖序分步、分批 commit,可独立回滚