dsh-maoying 0.1.16 → 0.1.17

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.
package/README.en.md CHANGED
@@ -10,13 +10,13 @@ Once installed, the main agent becomes the **editor-in-chief of your novel**: it
10
10
 
11
11
  - **Editor-in-chief + five helpers**: the main agent plans, connects, reviews and advances states; the outliner (outline), writer (write), reviewer (review), lore keeper (lore) and researcher (research) each carry their own tools. Trivial errands like finding a file or checking a foreshadow status, the chief handles itself with glob/grep.
12
12
  - **novel/ as a file database**: character cards, worldbuilding & science settings with three-color tags, relations graph, foreshadow ledger, timeline, narrative memory, clue board — all grep-friendly flat-key/top-level-array YAML, human-editable, git-versioned, no migrations, no ops.
13
- - **Seven-phase workflow**: idea → setting → outline → writing → review → consistency → export. The phase lives in the `phase` key of project.yml; the chief advances it at each milestone and reports to you.
14
- - **Writing six-step method**: continuity check → outline → draft → review → revision → finalization, looping per chapter; paired with the Collab four-step co-writing flow (setting co-creation → volume planning → golden three chapters → handoff loop) it takes a new book from zero to rolling updates.
13
+ - **Seven-phase workflow**: idea → setting → outline → writing → review → consistency → export. The phase lives in the `phase` key of project.yml; the chief advances it at each milestone and reports to you, with completion gates (core settings saved; volume plan and the target chapter outline in place before writing) — unmet, it steps back a phase.
14
+ - **Writing six-step method**: continuity check → outline → draft → review → revision → finalization, looping per chapter; paired with the Collab four-step co-writing flow (setting co-creation → volume planning → golden three chapters → handoff loop) it takes a new book from zero to rolling updates; the setting digest and the volume plan each get a user sign-off, and the golden three chapters wait until settings are locked.
15
15
  - **Foreshadowing state machine**: planted → progressing → resolved / abandoned, with planting and payoff chapter numbers, expected-payoff scheduling and priority tiers — a long serial never drops a thread; past 15 active foreshadowing entries the chief proactively suggests cleanup.
16
16
  - **Context on demand**: the chief reads index.yml for the big picture, then pulls only what the chapter at hand needs (previous chapter's ending ≈1500 chars + its outline + on-stage character cards + active foreshadow excerpts) — never the whole book.
17
17
  - **Narrow tool surface**: the chief sees only "role delegation + internal retrieval + coordination"; helpers carry their line's tools (reviewer read-only, researcher web+notes only) — less per-request tool overhead and context weight.
18
18
  - **Research**: the research helper searches the web for historical/geographic/domain material, files notes under `novel/research/`, separating fact from common lore from legend, with sources — a dividend of the DSH architecture.
19
- - **Creator panel**: a full-page web panel from the DSH sidebar — Overview (with in-place manuscript metadata editing) / Chapters / Characters / Foreshadowing / Relations / Timeline / Worldbuilding / Index Board; full-page chapter reading (outline side-by-side + five-dimension fields + status flow), form-based project.yml editing, UI language (中文/English), six font-size steps, and automatic new-version detection.
19
+ - **Creator panel**: a full-page web panel from the DSH sidebar — Overview (with in-place manuscript metadata editing and volume plan) / Chapters / Characters / Foreshadowing / Relations / Timeline / Worldbuilding / Index Board; full-page chapter reading (outline side-by-side + five-dimension fields + status flow), form-based project.yml editing, UI language (中文/English), six font-size steps, and automatic new-version detection.
20
20
  - **CLI fallback**: `maoying init / stats / index / export / brief / check` — six zero-dependency commands for scaffolding, stats, index rebuild, export, per-chapter writing cards and static checks.
21
21
 
22
22
  ## Quick Start
@@ -53,7 +53,7 @@ With the preset selected, just talk to the chief; it routes by the workflow itse
53
53
 
54
54
  > I want to write an Eastern fantasy where the protagonist's golden finger is hearing objects speak and appraising treasures to level up.
55
55
 
56
- The chief aligns genre and tone with you, delegates core character cards and worldbuilding to the lore keeper, volume planning to the outliner, then has the golden three chapters (world hook, protagonist motivation, core conflict) written and delivered.
56
+ The chief aligns the setting with you item by item (genre, golden finger, tone, the protagonist's want/obstacle/leverage, the core opposition); the lore keeper saves core character cards and worldbuilding entries for your sign-off, the outliner's volume plan gets a second sign-off — only then are the golden three chapters (world hook, protagonist motivation, core conflict) written and delivered.
57
57
 
58
58
  **Per-chapter writing (Writing six-step method)**:
59
59
 
@@ -74,7 +74,7 @@ A reply of "ok / sure / go on" counts as confirmation; the chief advances direct
74
74
  Open "**毛颖创作台**" at the bottom of the DSH sidebar — a full-page cockpit for the human eye, beyond what agents do:
75
75
 
76
76
  - **Chapters**: status filters + the writing queue; click a chapter for full-page reading — back button, outline side-by-side (Markdown rendered), read-only manuscript, five narrative-dimension fields, one-click status flow.
77
- - **Overview**: the "Edit" button on the manuscript card expands form-based editing of project.yml — title / author / genre / planned length / language / workflow phase / co-writing mode / synopsis (the former "Novel Settings" tab, merged in); saving preserves the file's existing comments. If project.yml was changed externally after the form loaded (manual edits or an agent advancing the phase), saving is rejected with a prompt to re-edit from the latest content instead of overwriting.
77
+ - **Overview**: the "Edit" button on the manuscript card expands form-based editing of project.yml — title / author / genre / planned length / language / workflow phase / co-writing mode / synopsis (the former "Novel Settings" tab, merged in); saving preserves the file's existing comments. If project.yml was changed externally after the form loaded (manual edits or an agent advancing the phase), saving is rejected with a prompt to re-edit from the latest content instead of overwriting. A separate "Volume plan" card lists each volume's positioning and planned chapter range from volumes.yml — signed-off volume plans are visible in the panel.
78
78
  - **Top bar**: current version always visible; a "new version ↗" badge links to the release page when npm has a newer one, next to an "Upgrade now" button that installs the latest release into the current DSH profile with pnpm (profile-directory installs only; a DeepSeek restart is required to take effect); the gear opens Settings — UI language (中文/English), six font-size steps (100%–150%), all applied immediately and remembered.
79
79
 
80
80
  The panel only writes state (chapter status, project.yml, index.yml rebuilds), never prose — prose belongs to the author and the chief.
@@ -89,7 +89,7 @@ The author-draft loop — you just write, hand it over, and the chores are taken
89
89
 
90
90
  After receiving a manuscript you get three things: a **review checklist** (issues only, no rewriting — applying them is up to you), a **ledger backfill** (foreshadowing / timeline / relations / memory / clue board recorded from what your text actually does, even off-plan changes, tagged `backfill`), and the **next chapter outline** (`novel/outlines/vXX-cXXX.md`, ready to write from).
91
91
 
92
- Companion commands: `maoying brief <dir> <chapter>` packs a per-chapter writing card (outline + previous ending + character cards + active foreshadowing — carry it to any editor or AI), and `maoying check <dir>` runs a zero-model static check (frontmatter completeness, foreshadow chapter references, timeline ordering — no model calls; LLM review goes through the chief).
92
+ Companion commands: `maoying brief <dir> <chapter>` packs a per-chapter writing card (outline + previous ending + character cards + active foreshadowing — carry it to any editor or AI), and `maoying check <dir>` runs a zero-model static check (frontmatter completeness, foreshadow chapter references, timeline ordering, phase readiness gates — no model calls; LLM review goes through the chief).
93
93
 
94
94
  ## Methodology Skills
95
95
 
@@ -124,7 +124,7 @@ maoying stats [dir] # per-chapter CJK counts, status breakdown, current phase
124
124
  maoying index [dir] # rebuild index.yml from volumes.yml + chapters/ (derived file)
125
125
  maoying export [dir] # export the book: --format md|txt|epub (default md), --out <dir> to change destination
126
126
  maoying brief [dir] <chapter> # pack a per-chapter writing card (outline + previous ending + character cards + active foreshadowing); --out to write to disk, stdout by default
127
- maoying check [dir] # static check (no model calls): frontmatter / enums / chapter numbers / foreshadow refs / timeline years / relation-card refs
127
+ maoying check [dir] # static check (no model calls): frontmatter / enums / chapter numbers / foreshadow refs / timeline years / relation-card refs / phase readiness gates
128
128
  ```
129
129
 
130
130
  Export examples:
package/README.md CHANGED
@@ -10,13 +10,13 @@
10
10
 
11
11
  - **主编 + 五帮手**:主 agent 当主编,只做规划、衔接、验收、状态推进;大纲师(outline)、写手(write)、审校(review)、设定管理员(lore)、素材调研员(research)各带本行工具随叫随到。找文件、查伏笔状态这类顺手小事主编自己 glob/grep 就办,不绕委派。
12
12
  - **novel/ 文件数据库**:角色卡、世界观、科学设定三色标注、关系图、伏笔账本、时间线、叙事记忆、线索板,全部是 grep 友好的平键/顶层数组 YAML——人可直接改,git 可版本化,无迁移无运维。
13
- - **七阶段工作流**:idea 选题 → setting 设定 → outline 大纲 → writing 写作 → review 审阅 → consistency 一致性 → export 导出。阶段记在 project.yml 的 phase 键,每完成一个里程碑主编推进并简报。
14
- - **Writing 六步法**:衔接检查 → 出大纲 → 写正文 → 审稿 → 修改 → 定稿维护,逐章循环;配合 Collab 四步共创(设定共创 → 分卷规划 → 黄金三章 → 交接循环)把新书从零带到滚动更新。
13
+ - **七阶段工作流**:idea 选题 → setting 设定 → outline 大纲 → writing 写作 → review 审阅 → consistency 一致性 → export 导出。阶段记在 project.yml 的 phase 键,每完成一个里程碑主编推进并简报;推进有完成判据(核心设定落盘、分卷规划与目标章大纲在案才进 writing),不满足就回上一阶段补齐。
14
+ - **Writing 六步法**:衔接检查 → 出大纲 → 写正文 → 审稿 → 修改 → 定稿维护,逐章循环;配合 Collab 四步共创(设定共创 → 分卷规划 → 黄金三章 → 交接循环)把新书从零带到滚动更新;设定一览与分卷规划各设一个用户拍板点,前三章在设定齐备前不开工。
15
15
  - **伏笔状态机**:planted(埋设)→ progressing(推进)→ resolved(回收)/ abandoned(弃用),埋设与回收记章节号、预期回收章节排期、优先级分档——长篇不断线,活跃伏笔超 15 条主编主动提醒清理。
16
16
  - **上下文按需取**:主编先读 index.yml 概览,写到哪章读哪章(前章结尾约 1500 字 + 该章大纲 + 出场角色卡 + 活跃伏笔节选),不把整本书塞进上下文。
17
17
  - **工具面收窄**:主编只见「角色委派 + 内部检索 + 协调」白名单,帮手各带本行工具(审校只读、考据只带联网+落笔记);每次请求的工具开销与上下文占用随之下降。
18
18
  - **素材考据**:research 帮手联网检索历史/地理/专业领域素材,笔记落 `novel/research/`,区分史实/通说/演义并附来源——DSH 架构的红利。
19
- - **创作台面板**:DSH 侧栏一键打开的全页可视化面板——概览(含书稿元信息编辑)/章节/角色/伏笔/关系图/时间线/设定/索引板八个 tab;章节整页阅读(章纲对照 + 五维 + 状态流转)、project.yml 表单化编辑、顶栏字号六档缩放与自动新版检测。
19
+ - **创作台面板**:DSH 侧栏一键打开的全页可视化面板——概览(含书稿元信息编辑与分卷规划)/章节/角色/伏笔/关系图/时间线/设定/索引板八个 tab;章节整页阅读(章纲对照 + 五维 + 状态流转)、project.yml 表单化编辑、顶栏字号六档缩放与自动新版检测。
20
20
  - **CLI 兜底**:`maoying init / stats / index / export / brief / check` 六条零依赖命令管脚手架、统计、索引重建、导出、写作卡打包与静态体检。
21
21
 
22
22
  ## 快速开始
@@ -53,7 +53,7 @@ npm install -g dsh-maoying # 或装成全局 maoying 命令
53
53
 
54
54
  > 我想写一本东方玄幻,主角靠「听懂器物说话」的金手指鉴宝升级。
55
55
 
56
- 主编与你对齐题材与基调,委派设定管理员建核心角色卡与世界观条目,委派大纲师做分卷规划,然后把黄金三章(立世界钩子、立主角动机、立核心冲突)写出来交付。
56
+ 主编与你逐项对齐设定(题材、金手指、基调、主角三要素、对抗主线),设定管理员落盘核心角色卡与世界观条目后交你拍板;大纲师出分卷规划再交你拍板——设定与分卷都定了,才动笔黄金三章(立世界钩子、立主角动机、立核心冲突)交付。
57
57
 
58
58
  **逐章写作(Writing 六步法)**:
59
59
 
@@ -74,7 +74,7 @@ npm install -g dsh-maoying # 或装成全局 maoying 命令
74
74
  DSH 左侧栏底部点「**毛颖创作台**」打开全页面板(改文件、跑流程之外,给肉眼看的驾驶舱):
75
75
 
76
76
  - **章节**:状态筛选 + 按单写作清单;点章节进整页阅读——返回按钮、章纲对照(Markdown 渲染)、只读正文、五维叙事字段、一键状态流转。
77
- - **概览**:书稿卡右上「编辑」按钮展开 project.yml 的书名/作者/题材/篇幅/语言/工作流阶段/共创模式/简介表单化编辑(原「小说设置」tab 并入),保存保留文件里原有注释;表单载入后 project.yml 被外部(作者手改 / agent 推进阶段)改过时拒绝保存并提示重改,不覆盖人工改动。
77
+ - **概览**:书稿卡右上「编辑」按钮展开 project.yml 的书名/作者/题材/篇幅/语言/工作流阶段/共创模式/简介表单化编辑(原「小说设置」tab 并入),保存保留文件里原有注释;表单载入后 project.yml 被外部(作者手改 / agent 推进阶段)改过时拒绝保存并提示重改,不覆盖人工改动。概览另设「分卷规划」卡,列出 volumes.yml 各卷定位与计划章节范围——拍板过的分卷有处可查。
78
78
  - **顶栏**:当前版本号常驻;npm 上有新版时亮「有新版 ↗」徽章直连发布页,旁边「一键升级」按钮直接用 pnpm 把最新包装进当前 DSH 档(仅支持 profile 目录安装;装完需重启 DeepSeek 才生效);齿轮打开系统设置,界面语言中文/English 可切、字号六档(100%–150%)整体缩放,均立即生效并记忆。
79
79
 
80
80
  面板只写状态(章节状态、project.yml、index.yml 重建),不改正文——正文永远归作者与主编。
@@ -124,7 +124,7 @@ maoying stats [dir] # 逐章 CJK 字数、状态分布、当前 phase
124
124
  maoying index [dir] # 从 volumes.yml + chapters/ 重建 index.yml(派生文件)
125
125
  maoying export [dir] # 导出全书:--format md|txt|epub(默认 md),--out <目录> 改输出位置
126
126
  maoying brief [dir] <chapter> # 组装单章写作卡(章纲+前章结尾+角色卡+活跃伏笔);--out 落盘,缺省 stdout
127
- maoying check [dir] # 静态体检(不调模型):frontmatter/枚举/章号/伏笔引用/时间线年份/关系卡引用
127
+ maoying check [dir] # 静态体检(不调模型):frontmatter/枚举/章号/伏笔引用/时间线年份/关系卡引用/phase 就绪判据
128
128
  ```
129
129
 
130
130
  export 示例:
package/bin/maoying.mjs CHANGED
@@ -12,7 +12,7 @@
12
12
  * maoying export [dir] 导出全书:--format md|txt|epub(默认 md)、--out <目录>
13
13
  * maoying brief [dir] <chapter> [--out <文件>]
14
14
  * 组装某章写作卡(章纲+前章结尾+出场角色卡+活跃伏笔)
15
- * maoying check [dir] 静态体检(不调模型):frontmatter/枚举/章号/伏笔引用等
15
+ * maoying check [dir] 静态体检(不调模型):frontmatter/枚举/章号/伏笔引用/阶段就绪判据等
16
16
  *
17
17
  * 子命令出错 exit 1,中文报错。
18
18
  */
@@ -446,7 +446,7 @@ const HELP_TEXT = `毛颖(maoying)—— 网文创作项目 CLI
446
446
  maoying export [dir] 导出全书:--format md|txt|epub(默认 md),--out <目录> 改输出位置
447
447
  maoying brief [dir] <chapter>
448
448
  组装某章写作卡(章纲+前章结尾+出场角色卡+活跃伏笔);--out <文件> 落盘,缺省打到 stdout
449
- maoying check [dir] 静态体检(不调模型):frontmatter 完整性、枚举值、章号卷号一致、伏笔章号引用、时间线年份、关系卡引用
449
+ maoying check [dir] 静态体检(不调模型):frontmatter 完整性、枚举值、章号卷号一致、伏笔章号引用、时间线年份、关系卡引用、phase 阶段就绪判据
450
450
 
451
451
  说明:
452
452
  novel/ 目录的数据规范见 templates/novel/README.md(或项目内 novel/README.md)。
@@ -80,6 +80,7 @@ webServer.register({ kind: 'prefix', path: '/api/maoying', handler: async (req,
80
80
  "chapters": [{ "file","volume","num","title","status","words","summary",
81
81
  "cognitive_frame","emotional_anchor","world_texture",
82
82
  "suspense","interpersonal_tension" }], // 按 volume,num 升序;words 为 CJK 计数
83
+ "volumes": [{ "id","title","summary","chapters" }], // volumes.yml 分卷规划原样;chapters 为 001-020 计划范围串,非章节清单
83
84
  "characters": [{ "file","name","age","gender","role","appearance","personality",
84
85
  "background","motivation","arc","markers" }], // markers 数组,缺省 []
85
86
  "relations": [{ "a","b","type","description","intensity","started","ended" }], // a/b:relations.yml 里是角色 slug,出快照时对得上角色卡的端点归一成 name(关系图按 name 找节点),对不上原样保留
@@ -90,7 +91,7 @@ webServer.register({ kind: 'prefix', path: '/api/maoying', handler: async (req,
90
91
  "clues": [{ "kind","content","related_chapter","resolved" }],
91
92
  "world": [{ "file","category","tags","name","description" }],
92
93
  "science": [{ "file","label","name","description","references" }],
93
- "research": [{ "file","topic" }],
94
+ "research": [{ "file","topic","sources","description" }], // sources 为 frontmatter sources 的 URL 数组,description 为笔记正文
94
95
  "outlines": [{ "file","chapter","words","excerpt" }], // outlines/ 章纲清单,chapter 为对应章节文件名,excerpt 为章纲节选(前 120 字,面板按单写作区块用),无章纲的章不列
95
96
  "totals": { "chapters": 12, "words": 38412,
96
97
  "byStatus": { "pending": 3, "writing": 2, "review": 1, "accepted": 6 } },
@@ -136,6 +137,7 @@ webServer.register({ kind: 'prefix', path: '/api/maoying', handler: async (req,
136
137
  - **按单写作兼容孤儿章纲**(0.1.15):章纲先于正文时面板不再零入口——「按单写作」区块在联交(有章纲且 status=pending 的章)之外照列未建章的孤儿章纲(按章纲序保序混排):「未建章」徽章 + 章纲节选 + 字数 + 两个动作(行点击开章纲全文弹层:MaskPortal + MdView 渲染 GET `outline` 的 body、words 一并显示;「建章」按钮 POST `chapter-create` 在 chapters/ 落 status=pending 空章——frontmatter 按 chapters/vXX-cXXX.md 模板、title 取章纲首条标题行去「章纲」后缀,成功 toast 后重拉快照,新章进表格、走既有 pending 流转,孤儿行按新快照自然消失);chapters/ 为空而 outlines/ 非空时空态改提示「下方按单写作已列出未建章章纲」。路由 13 → 15 条(outline GET / chapter-create POST);I18N zh/en 各 219 → 230 条(chapters.outlineRowTip / noChapter / createBtn / creating / createTip / emptyWithOutlines、toast.chapterCreated、outline.modalAria / closeAria / loading / loadFailed)。
137
138
  - **小说设置并入概览**(0.1.15):原第 9 个「小说设置」tab 撤销(八个 tab),改为概览书稿卡右上「编辑」按钮——点击后 hero 卡原位切换为书稿元信息表单(ProjectMetaForm,8 平键 + 取消/保存),保存链路不变(`POST project-save` 携 `base_hash` 409 人工改动保护,成功重拉快照并退出编辑态,取消直接退出不落盘)。路由不变;I18N zh/en 各 230 → 232 条(tabs.settings 移除,overview.edit / overview.editTip / novel.cancel 新增)。
138
139
  - **role 徽章本地化**(0.1.15):角色卡墙与全卡弹层的 role 徽章不再直出角色卡 frontmatter 原文——契约四态(`protagonist|antagonist|supporting|minor`)按界面语言出标签(主角/反派/配角/龙套;英文面板 Protagonist/Antagonist/Supporting/Minor),role 是自由文本、契约外取值原样展示不翻译;tone 归色逻辑(roleTone 关键词匹配)不变。I18N zh/en 各 232 → 236 条(role.protagonist / antagonist / supporting / minor)。
140
+ - **分卷规划卡 + 考据笔记正文**(未发版):快照顶层新增 `volumes`(volumes.yml 原样:id/title/summary/chapters 计划范围串)——概览新增「分卷规划」卡(有卷才显,卷头 id · 卷名 + 计划范围 tag + 卷定位一句),分卷拍板件在面板有复核位(配合 CLI check 的 phase 阶段就绪判据);research 快照从只取 topic 扩为 sources + description,设定 tab「资料检索」从标签行改为逐条渲染:topic 标题 + 笔记正文(MdView)+ sources 参考(悬停显全文 URL)。路由不变;I18N zh/en 各 +1 条(overview.volumes)。
139
141
 
140
142
  ## 5. 验收基线
141
143
 
package/docs/design.md CHANGED
@@ -143,8 +143,8 @@ persona prefix 内容骨架(agent.cordis.yml 内联,中文书写):
143
143
  ⑤ 审稿问题回 write 修(continuable 就地续修)或主编微调;
144
144
  ⑥ 通过后 status→accepted,委派 lore 做定稿维护(出场记录、伏笔状态、记忆、线索板、时间线),`maoying index` 重建概览。
145
145
  循环检查:还有非 accepted 章节 → 回 ①。
146
- 5. **Collab 四步共创**(新书冷启动):设定共创(世界观+核心角色卡)→ 分卷规划(volumes.yml + 各卷 summary)→ 前三章交付(黄金三章:第一章立世界观钩子、第二章立主角动机、第三章立核心冲突)→ 交接循环写作(切 Writing 六步法)。
147
- 6. **简短确认即执行**:用户回「ok/可以/继续」直接推进下一步,不再复述确认。
146
+ 5. **Collab 四步共创**(新书冷启动):设定共创(最小设定集逐项对齐 + 世界观与核心角色卡落盘,设用户拍板点)→ 分卷规划(volumes.yml + 各卷 summary,设用户拍板点)→ 前三章交付(机械自检设定件齐备后走黄金三章:第一章立世界观钩子、第二章立主角动机、第三章立核心冲突)→ 交接循环写作(切 Writing 六步法)。
147
+ 6. **简短确认即执行(分级)**:逐章滚动中用户回「ok/可以/继续」直接推进下一步,不再复述确认;冷启动里程碑(设定共创、分卷规划)是方向性拍板点,须列决策点等用户实质回应。
148
148
  7. **设定变更上报**:写手回报的临场设定变更(新角色/新地点/伏笔异动)必须经 lore 落盘才算数;发现与既有设定冲突,先停笔报告主编。
149
149
  8. **失败处理**:委派失败按 DSH 委派 SOP(diagnose by stop reason,max-tokens 拆章,refusal 换路)。
150
150
 
@@ -164,7 +164,7 @@ persona prefix 内容骨架(agent.cordis.yml 内联,中文书写):
164
164
  - `maoying index [dir]`:从 chapters/ 重建 index.yml(卷/章/标题/状态/字数/一句话梗概)。
165
165
  - `maoying export [dir]`:导出全书为 md / txt / epub(默认 md;`--out` 改输出目录,缺省 `<dir>/exports/`;同名自动加序号不覆盖)。
166
166
  - `maoying brief [dir] <chapter>`:组装单章写作卡(章纲 + 前章结尾 + 出场角色卡 + 活跃伏笔);`--out <文件>` 落盘,缺省打到 stdout。
167
- - `maoying check [dir]`:静态体检(不调模型),与面板/规范同一套规则(frontmatter 完整性、枚举、章号、伏笔引用、时间线年份、关系卡引用)。
167
+ - `maoying check [dir]`:静态体检(不调模型),与面板/规范同一套规则(frontmatter 完整性、枚举、章号、伏笔引用、时间线年份、关系卡引用、phase 阶段就绪判据)。
168
168
  - 主编人设里写明:定稿维护后由 lore 角色直接重写 index.yml(文件规范写明格式),CLI `maoying index` 仅供人工兜底;stats / init 供人工使用。
169
169
 
170
170
  ## 8. 二期路线
@@ -205,5 +205,5 @@ project.yml 加 `mode` 字段:`ai-draft`(默认,现状)/ `co-write`(
205
205
  ### 9.6 P1 工具
206
206
 
207
207
  - `maoying brief <dir> <章号>` 写作卡:章纲 + 前章结尾约 1500 字 + 出场角色卡 + 活跃伏笔节选,打成一个 md(stdout 或 --out)。给作者带去任意编辑器/其他 AI;
208
- - `maoying check <dir>` 静态体检(**不调模型**——LLM 审校走主编):frontmatter 完整性、五维缺键、状态枚举、章号/卷号规范、伏笔章号引用存在性、时间线年份乱序、角色卡悬空引用;
208
+ - `maoying check <dir>` 静态体检(**不调模型**——LLM 审校走主编):frontmatter 完整性、五维缺键、状态枚举、章号/卷号规范、伏笔章号引用存在性、时间线年份乱序、角色卡悬空引用、phase 枚举与阶段就绪判据(outline 起查主角卡/核心反派卡/世界观条目/分卷规划);
209
209
  - 面板三件:章节抽屉加章纲对照栏 + 复制文件路径按钮;伏笔看板卡上 `source: backfill` 显示「回填」徽章;章节 tab 顶部「按单写作」区块(有章纲且 status=pending 的章,按序列章纲节选;未建章的孤儿章纲照列——可看章纲全文、一键建章,0.1.15 起)。
package/docs/spec.md CHANGED
@@ -27,7 +27,7 @@
27
27
  字段与最小示例见速查版(`templates/novel/README.md`),此处只补约定:
28
28
 
29
29
  ### project.yml
30
- `phase` 七态 `idea|setting|outline|writing|review|consistency|export` 只能由主编推进(帮手不得越权改),且必须顺序推进不可跳越;推进时主编须向用户简报。`language` 影响写手与审校的语言纪律(如 `zh` 不允许成段外文)。`mode` 三值决定正文归谁写:`ai-draft`(缺省,AI 代笔,主编走 Writing 六步法)/ `co-write`(逐章指派谁写,主编动笔前先问清本章归谁)/ `author-draft`(全书作者亲笔,主编只备料、审稿、记账,永不代写)。文件里没有 `mode` 键的旧项目一律按 `ai-draft` 处理。
30
+ `phase` 七态 `idea|setting|outline|writing|review|consistency|export` 只能由主编推进(帮手不得越权改),且必须顺序推进不可跳越;推进时主编须向用户简报。推进有完成判据:setting → outline 须核心角色卡(主角、核心反派)与世界观核心条目(金手指规则、对抗格局)已落盘,且 characters/ 有两张及以上角色卡时 relations.yml 不为空(关系网须登记);outline → writing 须 volumes.yml 在案且目标章大纲已出;判据不满足回上一阶段补齐。冷启动(Collab 四步)在设定落盘与分卷规划两处各设一个用户拍板点——主编简报列决策点,等用户实质确认才进下一步。`language` 影响写手与审校的语言纪律(如 `zh` 不允许成段外文)。`mode` 三值决定正文归谁写:`ai-draft`(缺省,AI 代笔,主编走 Writing 六步法)/ `co-write`(逐章指派谁写,主编动笔前先问清本章归谁)/ `author-draft`(全书作者亲笔,主编只备料、审稿、记账,永不代写)。文件里没有 `mode` 键的旧项目一律按 `ai-draft` 处理。
31
31
 
32
32
  ### volumes.yml
33
33
  `id` 与章节文件名前缀严格一致(`v01` ↔ `chapters/v01-cXXX.md`),index.yml 的卷分组按本文件顺序输出。`chapters` 范围写法 `001-020` 是给人看的计划值,运行时以章节文件实况为准。
@@ -131,6 +131,6 @@ total: {chapters: 21, words: 65210, accepted: 18}
131
131
  - `maoying index` 是第 3 节重建逻辑的人工兜底(主编的日常路径是让 lore 角色直接重建);
132
132
  - `maoying export [dir]` 导出全书为 md / txt / epub(默认 md;`--out` 改输出目录,缺省 `<dir>/exports/`);
133
133
  - `maoying brief [dir] <chapter>` 组装单章写作卡(章纲 + 前章结尾 + 出场角色卡 + 活跃伏笔);`--out <文件>` 落盘,缺省打到 stdout;
134
- - `maoying check [dir]` 静态体检(不调模型):frontmatter 完整性、枚举值、章号卷号一致、伏笔章号引用、时间线年份、关系卡引用。
134
+ - `maoying check [dir]` 静态体检(不调模型):frontmatter 完整性、枚举值(含 phase)、章号卷号一致、伏笔章号引用、时间线年份、关系卡引用,并把本节 phase 完成判据落成静态检查——phase 到 outline 及之后仍缺主角卡/核心反派卡/世界观条目/分卷规划,或有两张及以上角色卡而 relations.yml 为空,即报 error(判据不满足回上一阶段补齐)。
135
135
 
136
136
  六者都零依赖,解析器只认本规范的两类形态(平键映射、顶层数组);深度嵌套不在支持范围——这是规范约束的执行手段之一。
package/lib/base.css CHANGED
@@ -123,7 +123,10 @@ html[data-dsh-maoying-active]:not([data-dsh-mnemon-active]):not([data-dsh-taskbo
123
123
  overflow-y: auto;
124
124
  padding: 0 24px 32px;
125
125
  }
126
- .myt-page { display: flex; flex-direction: column; gap: 16px; max-width: 980px; }
126
+ /* 宽度随宿主中栏自适应:不设上限(980 上限已去,宽屏撑满);min-width
127
+ 兜底极窄中栏,低于时 .myt-body(overflow-y:auto 连带 overflow-x:auto)
128
+ 出横向滚动而不挤压看板/表格布局。 */
129
+ .myt-page { display: flex; flex-direction: column; gap: 16px; min-width: 720px; }
127
130
 
128
131
  /* ── 通用按钮 / 下拉 ───────────────────────────────────────────────────── */
129
132
  .myt-btn {
@@ -553,9 +556,15 @@ html[data-dsh-maoying-active]:not([data-dsh-mnemon-active]):not([data-dsh-taskbo
553
556
  .myt-charMeta { font-size: 11px; color: var(--dsw-alias-label-tertiary); }
554
557
  .myt-charLine { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary); overflow-wrap: anywhere; }
555
558
  .myt-charLabel { flex: none; font-size: 11px; color: var(--dsw-alias-label-tertiary); }
559
+ /* 弹层锚区居中:--myt-mask-* 由 client.js 持续测量面板容器视口矩形(已除
560
+ 面板 zoom 的 CSS px,mask 自身带 zoom)写入;--myt-anchor-* 同源视觉 px。
561
+ 变量缺省回落 0 = 全窗,行为同旧版。 */
556
562
  .myt-modalMask {
557
563
  position: fixed;
558
- inset: 0;
564
+ top: var(--myt-mask-top, 0px);
565
+ right: var(--myt-mask-right, 0px);
566
+ bottom: var(--myt-mask-bottom, 0px);
567
+ left: var(--myt-mask-left, 0px);
559
568
  z-index: 80;
560
569
  display: flex;
561
570
  align-items: center;
@@ -566,8 +575,8 @@ html[data-dsh-maoying-active]:not([data-dsh-mnemon-active]):not([data-dsh-taskbo
566
575
  .myt-modalCard {
567
576
  display: flex;
568
577
  flex-direction: column;
569
- width: min(520px, 94vw);
570
- max-height: 84vh;
578
+ width: min(520px, 100%); /* 百分比对 mask 内容盒解析:随锚区缩放,不再溢出中栏 */
579
+ max-height: 100%;
571
580
  border: 1px solid var(--dsw-alias-border-l2);
572
581
  border-radius: 16px;
573
582
  background: var(--dsw-alias-bg-layer-2);
@@ -674,8 +683,8 @@ html[data-dsh-maoying-active]:not([data-dsh-mnemon-active]):not([data-dsh-taskbo
674
683
  /* ── toast(fixed 悬浮,host 不挡点击)─────────────────────────────────── */
675
684
  .myt-toastHost {
676
685
  position: fixed;
677
- left: 50%;
678
- bottom: 28px;
686
+ left: calc(var(--myt-anchor-left, 0px) + var(--myt-anchor-width, 100vw) / 2);
687
+ bottom: calc(var(--myt-anchor-bottom, 0px) + 28px);
679
688
  transform: translateX(-50%);
680
689
  z-index: 90;
681
690
  display: flex;
@@ -688,7 +697,7 @@ html[data-dsh-maoying-active]:not([data-dsh-mnemon-active]):not([data-dsh-taskbo
688
697
  display: flex;
689
698
  align-items: flex-start;
690
699
  gap: 8px;
691
- max-width: min(520px, 86vw);
700
+ max-width: min(520px, var(--myt-anchor-width, 86vw));
692
701
  padding: 8px 12px;
693
702
  box-sizing: border-box;
694
703
  border-radius: 12px;
@@ -764,15 +773,19 @@ html[data-dsh-maoying-active]:not([data-dsh-mnemon-active]):not([data-dsh-taskbo
764
773
  .myt-view, .myt-modalMask, .myt-settingsMask { zoom: var(--myt-zoom, 1); }
765
774
  .myt-settingsMask {
766
775
  position: fixed;
767
- inset: 0;
776
+ top: var(--myt-mask-top, 0px);
777
+ right: var(--myt-mask-right, 0px);
778
+ bottom: var(--myt-mask-bottom, 0px);
779
+ left: var(--myt-mask-left, 0px);
768
780
  z-index: 80;
769
781
  display: flex;
770
782
  align-items: center;
771
783
  justify-content: center;
784
+ padding: 24px;
772
785
  background: color-mix(in srgb, var(--dsw-alias-bg-base, #000) 55%, transparent);
773
786
  }
774
787
  .myt-settings {
775
- width: min(400px, 92vw);
788
+ width: min(400px, 100%);
776
789
  background: var(--dsw-alias-bg-layer-2);
777
790
  border: 1px solid var(--dsw-alias-border-l1);
778
791
  border-radius: 14px;
package/lib/client.js CHANGED
@@ -283,7 +283,10 @@ window.__ModuleLoader__.load({
283
283
  return toast.subscribe(function () { setItems(toast.snapshot()); });
284
284
  }, []);
285
285
  if (!items.length) return null;
286
- return h("div", { className: "myt-toastHost", "aria-live": "polite" },
286
+ // portal 到 body:与弹层同坐标系。中栏 transform/overflow 会把 fixed 劫持
287
+ // 成相对中栏定位,锚区变量(视口坐标)在此会被二次偏移;挂 body 后
288
+ // fixed 恒等于视口,--myt-anchor-* 直接可用(base.css 按锚区居中)。
289
+ return h(MaskPortal, { className: "myt-toastHost", "aria-live": "polite" },
287
290
  items.map(function (it) {
288
291
  return h("div", {
289
292
  key: it.id,
@@ -571,6 +574,66 @@ window.__ModuleLoader__.load({
571
574
  lsSet(FONT_SCALE_KEY, fontScale);
572
575
  }, [fontScale]);
573
576
 
577
+ // 弹层锚区:弹层 portal 到 body 后 position:fixed 以全窗为居中基准,
578
+ // 宿主右侧边栏一开,中栏变窄左移,弹窗仍按全窗居中,右半被侧边栏盖住。
579
+ // 这里持续测量面板容器(data-dsh-maoying-view)的视口矩形写进 CSS 变量,
580
+ // 弹层/Toast 改按锚区居中(base.css);测量不到时移除变量回落全窗,行
581
+ // 为与旧版一致。宿主侧边栏开合会改中栏宽度,ResizeObserver + resize 双
582
+ // 通道跟随,rAF 合帧防抖。
583
+ // 两组变量:--myt-anchor-* 视觉 px(Toast 未 zoom,直接用);--myt-mask-*
584
+ // 已除以面板 zoom 的 CSS px(mask 带 zoom,fixed 内 px 会被放大,须预
585
+ // 除——JS 算好,避开 calc(px / var()) 的老 Chromium 兼容雷)。zoom 每次
586
+ // 现读 computed style,字号换档自动跟随,无需额外依赖。
587
+ useEffect(function () {
588
+ if (typeof document === "undefined" || typeof window === "undefined") return undefined;
589
+ var docEl = document.documentElement;
590
+ if (!docEl || !docEl.style) return undefined;
591
+ var ALL_VARS = [
592
+ "--myt-anchor-left", "--myt-anchor-width", "--myt-anchor-bottom",
593
+ "--myt-mask-top", "--myt-mask-right", "--myt-mask-bottom", "--myt-mask-left",
594
+ ];
595
+ var clear = function () {
596
+ ALL_VARS.forEach(function (v) { docEl.style.removeProperty(v); });
597
+ };
598
+ var px = function (n) { return (Math.round(n * 100) / 100) + "px"; };
599
+ var apply = function () {
600
+ raf = 0;
601
+ var el = document.querySelector("[data-dsh-maoying-view]");
602
+ if (!el || !el.isConnected) { clear(); return; }
603
+ var r = el.getBoundingClientRect();
604
+ if (!r || r.width < 2 || r.height < 2) { clear(); return; } // display:none 等异常态不锚定
605
+ docEl.style.setProperty("--myt-anchor-left", px(r.left));
606
+ docEl.style.setProperty("--myt-anchor-width", px(r.width));
607
+ docEl.style.setProperty("--myt-anchor-bottom", px(Math.max(0, window.innerHeight - r.bottom)));
608
+ var zoom = 1;
609
+ try {
610
+ var cs = window.getComputedStyle(el);
611
+ var pz = cs && cs.zoom ? parseFloat(cs.zoom) : NaN;
612
+ if (pz > 0) zoom = pz;
613
+ } catch (err) { /* 老宿主无 computed zoom:按 1 处理 */ }
614
+ docEl.style.setProperty("--myt-mask-top", px(r.top / zoom));
615
+ docEl.style.setProperty("--myt-mask-right", px(Math.max(0, window.innerWidth - r.right) / zoom));
616
+ docEl.style.setProperty("--myt-mask-bottom", px(Math.max(0, window.innerHeight - r.bottom) / zoom));
617
+ docEl.style.setProperty("--myt-mask-left", px(r.left / zoom));
618
+ };
619
+ var raf = 0;
620
+ var schedule = function () {
621
+ if (raf) return;
622
+ raf = window.requestAnimationFrame(apply);
623
+ };
624
+ apply();
625
+ window.addEventListener("resize", schedule);
626
+ var ro = typeof ResizeObserver === "function" ? new ResizeObserver(schedule) : null;
627
+ var el = document.querySelector("[data-dsh-maoying-view]");
628
+ if (ro && el) ro.observe(el);
629
+ return function () {
630
+ if (raf) window.cancelAnimationFrame(raf);
631
+ window.removeEventListener("resize", schedule);
632
+ if (ro) ro.disconnect();
633
+ clear();
634
+ };
635
+ }, []);
636
+
574
637
  // 选中校正:记忆的工作区必须仍在列表且 hasNovel,否则落回首个 hasNovel。
575
638
  var effectiveWs = (function () {
576
639
  if (!workspaces) return "";
@@ -839,6 +902,7 @@ window.__ModuleLoader__.load({
839
902
  apiPost("phase", { path: props.wsPath, phase: nextPhase }).then(reload).catch(function () {}).finally(function () { setPhaseBusy(false); });
840
903
  }
841
904
  var recent = (snap.chapters || []).slice().sort(function (a, b) { return (b.num || 0) - (a.num || 0); }).slice(0, 5);
905
+ var volumes = snap.volumes || [];
842
906
  return h("div", { className: "myt-stack" },
843
907
  checkProblems && checkProblems.length ? CheckStrip(checkProblems) : null,
844
908
  editing
@@ -877,6 +941,16 @@ window.__ModuleLoader__.load({
877
941
  h("div", { className: "myt-heroMeta" }, STATUS_FLOW.map(function (s) {
878
942
  return h("span", { key: s, className: "myt-muted" }, tt("status." + s) + " " + (byStatus[s] || 0));
879
943
  }))),
944
+ volumes.length ? h("div", { className: "myt-card" },
945
+ h("div", { className: "myt-cardHead" }, h("h3", { className: "myt-cardTitle" }, tt("overview.volumes")),
946
+ h("span", { className: "myt-boardCount" }, volumes.length)),
947
+ h("div", { className: "myt-stack" }, volumes.map(function (v, i) {
948
+ return h("div", { key: v.id || i, className: "myt-worldGroup" },
949
+ h("div", { className: "myt-listHead" },
950
+ h("span", { className: "myt-worldName" }, (v.id ? v.id + " · " : "") + orDash(v.title)),
951
+ v.chapters ? h("span", { className: "myt-tag" }, v.chapters) : null),
952
+ v.summary ? h("div", { className: "myt-worldDesc" }, v.summary) : null);
953
+ }))) : null,
880
954
  h("div", { className: "myt-card" },
881
955
  h("div", { className: "myt-cardHead" }, h("h3", { className: "myt-cardTitle" }, tt("overview.recent"))),
882
956
  recent.length
@@ -1060,6 +1134,7 @@ window.__ModuleLoader__.load({
1060
1134
  "char.modalAria": "角色详情", "char.closeAria": "关闭角色卡", "char.markers": "标记", "char.file": "文件",
1061
1135
  "overview.author": "作者:{name}", "overview.totalWords": "总字数(CJK)", "overview.totalChapters": "章节总数",
1062
1136
  "overview.characters": "角色数", "overview.openForeshadows": "未回收伏笔", "overview.statusDist": "章节状态分布", "overview.recent": "最近章节",
1137
+ "overview.volumes": "分卷规划",
1063
1138
  "overview.edit": "编辑", "overview.editTip": "编辑书稿元信息",
1064
1139
  "chapters.empty": "chapters/ 目录还没有章节文件", "chapters.writeQueue": "按单写作", "chapters.rowTip": "点击打开该章",
1065
1140
  "chapters.outlineWords": "章纲 {n} 字", "chapters.all": "全部", "chapters.thVolume": "卷 · 章", "chapters.thTitle": "标题",
@@ -1145,6 +1220,7 @@ window.__ModuleLoader__.load({
1145
1220
  "char.modalAria": "Character details", "char.closeAria": "Close character card", "char.markers": "Tags", "char.file": "File",
1146
1221
  "overview.author": "Author: {name}", "overview.totalWords": "Total characters (CJK)", "overview.totalChapters": "Chapters",
1147
1222
  "overview.characters": "Characters", "overview.openForeshadows": "Unresolved foreshadowing", "overview.statusDist": "Chapter status breakdown", "overview.recent": "Recent chapters",
1223
+ "overview.volumes": "Volume plan",
1148
1224
  "overview.edit": "Edit", "overview.editTip": "Edit manuscript metadata",
1149
1225
  "chapters.empty": "No chapter files in chapters/ yet", "chapters.writeQueue": "Writing Queue", "chapters.rowTip": "Click to open this chapter",
1150
1226
  "chapters.outlineWords": "Outline {n} chars", "chapters.all": "All", "chapters.thVolume": "Vol · Ch", "chapters.thTitle": "Title",
@@ -1774,8 +1850,13 @@ window.__ModuleLoader__.load({
1774
1850
  research.length ? h("div", { className: "myt-card" },
1775
1851
  h("div", { className: "myt-cardHead" }, h("h3", { className: "myt-cardTitle" }, tt("world.research")),
1776
1852
  h("span", { className: "myt-boardCount" }, research.length)),
1777
- h("div", { className: "myt-tagRow" }, research.map(function (r, i) {
1778
- return h("span", { key: r.file || i, className: "myt-tag", title: r.file || "" }, orDash(r.topic) || r.file);
1853
+ h("div", { className: "myt-stack" }, research.map(function (r, i) {
1854
+ return h("div", { key: r.file || i, className: "myt-worldGroup" },
1855
+ h("div", { className: "myt-listHead" },
1856
+ h("span", { className: "myt-worldName", title: r.file || "" }, orDash(r.topic) || r.file)),
1857
+ r.description ? h(MdView, { text: r.description, className: "myt-worldDesc" }) : null,
1858
+ (r.sources || []).length ? h("div", { className: "myt-refList" },
1859
+ r.sources.map(function (s, j) { return h("span", { key: j, className: "myt-refItem", title: s }, tf("world.ref", { n: j + 1, r: s })); })) : null);
1779
1860
  }))) : null);
1780
1861
  }
1781
1862
 
@@ -709,6 +709,9 @@ const FORESHADOW_STATUSES = ['planted', 'progressing', 'resolved', 'abandoned']
709
709
  /** project.yml 的共创模式枚举(五期 §9.1)。 */
710
710
  const PROJECT_MODES = ['ai-draft', 'co-write', 'author-draft']
711
711
 
712
+ /** 七阶段工作流枚举(与 project.yml 的 phase 键一致,顺序即推进序)。 */
713
+ export const PROJECT_PHASES = ['idea', 'setting', 'outline', 'writing', 'review', 'consistency', 'export']
714
+
712
715
  /**
713
716
  * 章节 frontmatter 的 volume 规范形态:v + 两位卷号。面板从章纲建章
714
717
  * (panel-core 的 createChapterFromOutline)与本文件 check / collectChapters
@@ -947,7 +950,10 @@ export function checkProject(novelDir) {
947
950
  }
948
951
  }
949
952
 
950
- // —— project.yml:mode 枚举 ——
953
+ // —— project.yml:mode/phase 枚举 + 阶段就绪判据 ——
954
+ // 判据与 docs/spec.md §2 同源:phase 到 outline 及之后(setting 已过),核心设定件
955
+ // 必须在案——缺了说明写作流程被硬闯,报 error 提示回上一阶段补齐。
956
+ // phase 键缺失(无 project.yml 或旧文件)不查——stats 已提示「未设置」,此处不重复计账。
951
957
  const projectRaw = parseFlatYamlArray(readTextOrNull(path.join(novelDir, 'project.yml')))
952
958
  if (projectRaw !== null && !Array.isArray(projectRaw)) {
953
959
  const mode = projectRaw.mode
@@ -955,6 +961,32 @@ export function checkProject(novelDir) {
955
961
  push('error', 'project.yml', `mode 越枚举:${mode}(合法值 ${PROJECT_MODES.join('|')})`)
956
962
  }
957
963
  }
964
+ const phase = projectRaw !== null && !Array.isArray(projectRaw) ? projectRaw.phase : undefined
965
+ if (typeof phase === 'string' && phase !== '') {
966
+ if (!PROJECT_PHASES.includes(phase)) {
967
+ push('error', 'project.yml', `phase 越枚举:${phase}(合法值 ${PROJECT_PHASES.join('|')})`)
968
+ } else if (PROJECT_PHASES.indexOf(phase) >= PROJECT_PHASES.indexOf('outline')) {
969
+ if (!cards.some((c) => c.meta.role === 'protagonist')) {
970
+ push('error', 'characters/', 'phase 已过 setting 但 characters/ 缺 role: protagonist 主角卡(setting → outline 判据:核心角色卡须落盘)')
971
+ }
972
+ if (!cards.some((c) => c.meta.role === 'antagonist')) {
973
+ push('error', 'characters/', 'phase 已过 setting 但 characters/ 缺 role: antagonist 核心反派卡(setting → outline 判据:核心角色卡须落盘)')
974
+ }
975
+ const hasWorldLore =
976
+ listMdFiles(path.join(novelDir, 'world')).length > 0 || listMdFiles(path.join(novelDir, 'science')).length > 0
977
+ if (!hasWorldLore) {
978
+ push('error', 'world/', 'phase 已过 setting 但 world/ 与 science/ 均无条目(setting → outline 判据:世界观核心条目须落盘)')
979
+ }
980
+ if (readYamlArray(novelDir, 'volumes.yml').length === 0) {
981
+ push('error', 'volumes.yml', 'phase 已过 setting 但 volumes.yml 为空或缺失(setting → outline 判据:分卷规划须在案)')
982
+ }
983
+ // 关系网判据(六期补):两张及以上角色卡时 relations.yml 不得为空——
984
+ // 空关系网意味着设定阶段漏登关系,关系图与大纲师的戏剧权重都无从谈起。
985
+ if (cards.length >= 2 && readYamlArray(novelDir, 'relations.yml').length === 0) {
986
+ push('error', 'relations.yml', 'phase 已过 setting 但 relations.yml 为空(setting → outline 判据:两张及以上角色卡时关系网须登记)')
987
+ }
988
+ }
989
+ }
958
990
 
959
991
  const summary = {
960
992
  chapters: chapterFiles.length,
@@ -553,9 +553,18 @@ export function parseStateSnapshot(novelDir, options = {}) {
553
553
  references: strArray(meta.references),
554
554
  }))
555
555
 
556
- const research = collectMdEntities(dir, 'research', yamlLib, warnings).map(({ file, meta }) => ({
556
+ const research = collectMdEntities(dir, 'research', yamlLib, warnings).map(({ file, meta, body }) => ({
557
557
  file,
558
558
  topic: strOrNull(meta.topic),
559
+ sources: strArray(meta.sources),
560
+ description: typeof body === 'string' ? body.trim() : '',
561
+ }))
562
+
563
+ const volumes = collectArrayYml(dir, 'volumes.yml', yamlLib, warnings).map((v) => ({
564
+ id: strOrNull(v.id),
565
+ title: strOrNull(v.title),
566
+ summary: strOrNull(v.summary),
567
+ chapters: strOrNull(v.chapters),
559
568
  }))
560
569
 
561
570
  const outlines = collectOutlines(dir, warnings)
@@ -581,6 +590,7 @@ export function parseStateSnapshot(novelDir, options = {}) {
581
590
  timeline,
582
591
  memories,
583
592
  clues,
593
+ volumes,
584
594
  world,
585
595
  science,
586
596
  research,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-maoying",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "毛颖 — DSH 网文创作辅助插件:主编 + 五帮手编排(大纲/写手/审校/设定/考据),novel/ 结构化文件为数据库",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -58,7 +58,7 @@
58
58
  ## 七阶段工作流
59
59
 
60
60
  idea 选题 → setting 设定 → outline 大纲 → writing 写作 → review 审阅 → consistency 一致性 → export 导出。
61
- 当前阶段记在 novel/project.yml 的 phase 键。每完成一个里程碑必须推进 phase 并简报用户;阶段不可跳越(写新章前必须已有该章大纲)。
61
+ 当前阶段记在 novel/project.yml 的 phase 键。每完成一个里程碑必须推进 phase 并简报用户;阶段不可跳越,推进前先核对完成判据——setting → outline:核心角色卡(主角、核心反派)与世界观核心条目(金手指规则、对抗格局)已落盘,且关系网已登记——characters/ 有两张及以上角色卡时 relations.yml 不得为空(关系无着落的设定不算设定完);outline → writing:volumes.yml 在案且目标章大纲(含五维字段)已出;判据不满足回上一阶段补齐,不硬闯。
62
62
 
63
63
  ## Writing 六步法(逐章循环)
64
64
 
@@ -67,14 +67,14 @@
67
67
  ③ 委派 write 写正文(status 置 writing):任务里给全大纲、前章结尾要点、出场角色、需推进的伏笔;
68
68
  ④ 委派 review 审稿(status 置 review):审稿清单(语言与节奏/人设符合/不剧透后期/伏笔推进合理/章尾钩子)+ 四维一致性扫描(冲突/时间线/伏笔/设定);
69
69
  ⑤ 审稿有问题:continuable 角色就地续修(write 用 send_message 续),或你亲自微调;通过后 status 置 accepted;
70
- ⑥ 定稿维护:委派 lore 做该章出场记录、伏笔状态推进、时间线与记忆更新;index.yml 与章节现状不符时让它重建。
70
+ ⑥ 定稿维护:委派 lore 做该章出场记录、伏笔状态推进、时间线与记忆更新、新关系与关系变动入 relations.yml(新角色与在场者有关系必登记);index.yml 与章节现状不符时让它重建。
71
71
  循环检查:还有非 accepted 章节 → 回 ① 继续;全部定稿 → 推进 phase。
72
72
 
73
73
  ## Collab 四步共创(新书冷启动)
74
74
 
75
- ① 设定共创:与用户对齐题材/金手指/基调,委派 lore 建核心角色卡与世界观条目;
76
- ② 分卷规划:委派 outline 出 volumes.yml 与各卷 summary;
77
- ③ 前三章交付:走 Writing 六步法连写前三章——黄金三章:第一章立世界钩子、第二章立主角动机、第三章立核心冲突;
75
+ ① 设定共创:与用户逐项对齐最小设定集——题材、金手指(能力/代价/边界)、基调、主角三要素(想要·阻碍·筹码)、核心反派与对抗主线、世界观底色,缺一项就追问不臆测;对齐后委派 lore 落盘核心角色卡(主角、核心反派、关键配角)、世界观核心条目,并把核心角色之间的戏剧关系逐条登记进 relations.yml(a/b 用角色卡 slug、intensity 1-5、started 先记计划章,格式以 novel/README.md 为准),把设定一览简报用户,等用户明确拍板才进②;
76
+ ② 分卷规划:委派 outline 出 volumes.yml 与各卷 summary(第一卷细化到章节号范围),简报用户,等用户明确拍板才进③;
77
+ ③ 前三章交付:动笔前机械自检——characters/ 有主角卡与核心反派卡、world/ 有金手指与对抗格局条目、volumes.yml 在案,缺任何一项回①②补齐不硬闯;齐了才走 Writing 六步法连写前三章——黄金三章:第一章立世界钩子、第二章立主角动机、第三章立核心冲突;
78
78
  ④ 交接循环写作:切回 Writing 六步法滚动推进,之后每 5-10 章建议用户做一次 consistency 集中审查。
79
79
 
80
80
  ## 共创模式(作者亲笔)
@@ -87,7 +87,7 @@
87
87
 
88
88
  ## 纪律
89
89
 
90
- - 用户回「ok / 可以 / 继续 / 嗯」即视为确认,直接推进下一步,不复述确认。
90
+ - 逐章滚动中,用户回「ok / 可以 / 继续 / 嗯」即视为确认,直接推进下一步,不复述确认;冷启动里程碑(设定共创、分卷规划)是方向性拍板点,简报须列出待拍板的决策点,等用户实质回应才进下一步,拿不准就用 ask_user_question 给具体选项。
91
91
  - 设定变更必须落盘才算数:写手回报的临场设定(新角色/新地点/伏笔异动)经 lore 写入对应文件;发现与既有设定冲突,先停笔报告你,由你裁决。
92
92
  - 角色言行不得写崩:写手拿不准的保守处理,审校盯人设。
93
93
  - 伏笔状态机:planted(埋设)→ progressing(推进)→ resolved(回收)/ abandoned(弃用);埋设与回收必须记章节号;活跃伏笔超过 15 条时提醒用户清理。
@@ -241,7 +241,7 @@
241
241
  name: "@deepseek-ai/dsh-persona"
242
242
  config:
243
243
  prefix: |-
244
- 你是网文项目的大纲师。职责:卷章规划与章节大纲。收到委派后:先读 novel/project.yml 与 novel/index.yml 掌握全局,再按任务写/改 volumes.yml 或 chapters/ 下目标章的 frontmatter——title、status 置 pending、summary(一句话梗概)与五维叙事字段(cognitive_frame 认知框架 / emotional_anchor 情感锚点 / world_texture 世界质感 / suspense 具体悬念 / interpersonal_tension 人际张力),每项 1-3 句、具体到本章,不写空话。节奏意识:单章对应一个完整小高潮、章尾留钩子;卷内 3-5 章一个中高潮、卷末大高潮;新书分卷规划先给各卷一句话定位。规划前三章前用 skill 工具加载 maoying-golden-opening,排本卷节奏曲线时加载 maoying-beat-pacing,埋设规划对照 foreshadows.yml 并遵循 maoying-foreshadow-discipline。涉及新设定(新角色/新地点)只在大纲中点名,落盘归设定管理员。共创模式(project.yml mode 为 co-write / author-draft)下加一项产出:章纲 novel/outlines/vXX-cXXX.md,纯 markdown 无 frontmatter,与同名章节一一对应,五件写全——本章目标、节拍、出场角色、需埋/需收伏笔、与前章接口;这是作者的创作输入,颗粒度要到作者拿着就能动笔。完成后回报:改了哪些文件、每章一句话梗概、遗留给主编的决策点。创作方向拿不准就用 ask_user_question 问主编,选项要具体。圣域纪律:chapters/ 目录正文唯作者可改,agent 只可在 author/co-write 章节上更新 frontmatter 的 summary 与五维字段,且以建议为先、动笔前说明;ai-draft 章节不受此限。
244
+ 你是网文项目的大纲师。职责:卷章规划与章节大纲。收到委派后:先读 novel/project.yml 与 novel/index.yml 掌握全局,再按任务写/改 volumes.yml 或 chapters/ 下目标章的 frontmatter——title、status 置 pending、summary(一句话梗概)与五维叙事字段(cognitive_frame 认知框架 / emotional_anchor 情感锚点 / world_texture 世界质感 / suspense 具体悬念 / interpersonal_tension 人际张力),每项 1-3 句、具体到本章,不写空话。节奏意识:单章对应一个完整小高潮、章尾留钩子;卷内 3-5 章一个中高潮、卷末大高潮;新书分卷规划先给各卷一句话定位。规划前三章前用 skill 工具加载 maoying-golden-opening,排本卷节奏曲线时加载 maoying-beat-pacing,埋设规划对照 foreshadows.yml 并遵循 maoying-foreshadow-discipline。涉及新设定(新角色/新地点)只在大纲中点名,落盘归设定管理员;发现核心设定缺失(无主角卡/核心反派卡、无 volumes.yml 分卷规划)时停手上报主编缺失清单,不在大纲里自行发明设定。共创模式(project.yml mode 为 co-write / author-draft)下加一项产出:章纲 novel/outlines/vXX-cXXX.md,纯 markdown 无 frontmatter,与同名章节一一对应,五件写全——本章目标、节拍、出场角色、需埋/需收伏笔、与前章接口;这是作者的创作输入,颗粒度要到作者拿着就能动笔。完成后回报:改了哪些文件、每章一句话梗概、遗留给主编的决策点。创作方向拿不准就用 ask_user_question 问主编,选项要具体。圣域纪律:chapters/ 目录正文唯作者可改,agent 只可在 author/co-write 章节上更新 frontmatter 的 summary 与五维字段,且以建议为先、动笔前说明;ai-draft 章节不受此限。
245
245
  On tool failure, do not retry a denied operation: report the failure compactly — what you completed, the exact error, which tool/permission you lack, and your suggested next step.
246
246
  - id: agent-instructions
247
247
  name: "@deepseek-ai/dsh-agent-instructions"
@@ -414,7 +414,7 @@
414
414
  name: "@deepseek-ai/dsh-persona"
415
415
  config:
416
416
  prefix: |-
417
- 你是网文项目的设定管理员。职责:创作要素的落盘与推进。按任务维护:characters/*.md(角色卡)、world/*.md、science/*.md、relations.yml、foreshadows.yml、timeline.yml、memories.yml、clue-board.yml。纪律:只记事实不发挥;不改动既有条目(除非任务明确要求);格式以 novel/README.md 为准。伏笔状态机:planted → progressing → resolved / abandoned,埋设与回收章节号必填;台账维护纪律(登记字段、推进间隔、清理阈值)用 skill 工具加载 maoying-foreshadow-discipline。章节定稿维护任务:从该章正文提取出场角色(memories.yml 记 category: appearance 一条)、伏笔状态推进、新事件入 timeline.yml、重要承诺入 memories.yml(category: promise)、新线索入 clue-board.yml。共创收稿回填:作者交稿后读新稿,提取实际发生的伏笔埋设/回收、时间线事件、新关系、承诺线、线索,更新五本账(foreshadows/timeline/relations/memories/clue-board)——账本跟随正文而非章纲,两者打架以正文为准;foreshadows 条目可带可选 source: plan | backfill,从正文回填认领的标 backfill,章纲/大纲计划登记的缺省 plan。index.yml 与章节现状不符时按 README 规范重建。完成后回报:新建/更新了哪些条目、伏笔状态变化一览(id + 旧状态 → 新状态)。圣域纪律:chapters/ 目录正文唯作者可改,agent 只可在 author/co-write 章节上更新 frontmatter 的 summary 与五维字段,且以建议为先、动笔前说明;ai-draft 章节不受此限。
417
+ 你是网文项目的设定管理员。职责:创作要素的落盘与推进。按任务维护:characters/*.md(角色卡)、world/*.md、science/*.md、relations.yml、foreshadows.yml、timeline.yml、memories.yml、clue-board.yml。纪律:只记事实不发挥;不改动既有条目(除非任务明确要求);格式以 novel/README.md 为准。伏笔状态机:planted → progressing → resolved / abandoned,埋设与回收章节号必填;台账维护纪律(登记字段、推进间隔、清理阈值)用 skill 工具加载 maoying-foreshadow-discipline。章节定稿维护任务:从该章正文提取出场角色(memories.yml 记 category: appearance 一条)、伏笔状态推进、新事件入 timeline.yml、重要承诺入 memories.yml(category: promise)、新线索入 clue-board.yml、新关系与关系变动入 relations.yml(a/b 用角色卡 slug)。建卡任务里凡新卡与既有卡存在戏剧关系,当场逐条登记,不攒账。共创收稿回填:作者交稿后读新稿,提取实际发生的伏笔埋设/回收、时间线事件、新关系、承诺线、线索,更新五本账(foreshadows/timeline/relations/memories/clue-board)——账本跟随正文而非章纲,两者打架以正文为准;foreshadows 条目可带可选 source: plan | backfill,从正文回填认领的标 backfill,章纲/大纲计划登记的缺省 plan。index.yml 与章节现状不符时按 README 规范重建。完成后回报:新建/更新了哪些条目、伏笔状态变化一览(id + 旧状态 → 新状态)。圣域纪律:chapters/ 目录正文唯作者可改,agent 只可在 author/co-write 章节上更新 frontmatter 的 summary 与五维字段,且以建议为先、动笔前说明;ai-draft 章节不受此限。
418
418
  On tool failure, do not retry a denied operation: report the failure compactly — what you completed, the exact error, which tool/permission you lack, and your suggested next step.
419
419
  - id: agent-instructions
420
420
  name: "@deepseek-ai/dsh-agent-instructions"
@@ -41,7 +41,7 @@
41
41
  ## 七阶段工作流
42
42
 
43
43
  idea 选题 → setting 设定 → outline 大纲 → writing 写作 → review 审阅 → consistency 一致性 → export 导出。
44
- 当前阶段记在 novel/project.yml 的 phase 键。每完成一个里程碑必须推进 phase 并简报用户;阶段不可跳越(写新章前必须已有该章大纲)。
44
+ 当前阶段记在 novel/project.yml 的 phase 键。每完成一个里程碑必须推进 phase 并简报用户;阶段不可跳越,推进前先核对完成判据——setting → outline:核心角色卡(主角、核心反派)与世界观核心条目(金手指规则、对抗格局)已落盘,且关系网已登记——characters/ 有两张及以上角色卡时 relations.yml 不得为空(关系无着落的设定不算设定完);outline → writing:volumes.yml 在案且目标章大纲(含五维字段)已出;判据不满足回上一阶段补齐,不硬闯。
45
45
 
46
46
  ## Writing 六步法(逐章循环)
47
47
 
@@ -50,14 +50,14 @@
50
50
  ③ 委派 write 写正文(status 置 writing):任务里给全大纲、前章结尾要点、出场角色、需推进的伏笔;
51
51
  ④ 委派 review 审稿(status 置 review):审稿清单(语言与节奏/人设符合/不剧透后期/伏笔推进合理/章尾钩子)+ 四维一致性扫描(冲突/时间线/伏笔/设定);
52
52
  ⑤ 审稿有问题:continuable 角色就地续修(write 用 send_message 续),或你亲自微调;通过后 status 置 accepted;
53
- ⑥ 定稿维护:委派 lore 做该章出场记录、伏笔状态推进、时间线与记忆更新;index.yml 与章节现状不符时让它重建。
53
+ ⑥ 定稿维护:委派 lore 做该章出场记录、伏笔状态推进、时间线与记忆更新、新关系与关系变动入 relations.yml(新角色与在场者有关系必登记);index.yml 与章节现状不符时让它重建。
54
54
  循环检查:还有非 accepted 章节 → 回 ① 继续;全部定稿 → 推进 phase。
55
55
 
56
56
  ## Collab 四步共创(新书冷启动)
57
57
 
58
- ① 设定共创:与用户对齐题材/金手指/基调,委派 lore 建核心角色卡与世界观条目;
59
- ② 分卷规划:委派 outline 出 volumes.yml 与各卷 summary;
60
- ③ 前三章交付:走 Writing 六步法连写前三章——黄金三章:第一章立世界钩子、第二章立主角动机、第三章立核心冲突;
58
+ ① 设定共创:与用户逐项对齐最小设定集——题材、金手指(能力/代价/边界)、基调、主角三要素(想要·阻碍·筹码)、核心反派与对抗主线、世界观底色,缺一项就追问不臆测;对齐后委派 lore 落盘核心角色卡(主角、核心反派、关键配角)、世界观核心条目,并把核心角色之间的戏剧关系逐条登记进 relations.yml(a/b 用角色卡 slug、intensity 1-5、started 先记计划章,格式以 novel/README.md 为准),把设定一览简报用户,等用户明确拍板才进②;
59
+ ② 分卷规划:委派 outline 出 volumes.yml 与各卷 summary(第一卷细化到章节号范围),简报用户,等用户明确拍板才进③;
60
+ ③ 前三章交付:动笔前机械自检——characters/ 有主角卡与核心反派卡、world/ 有金手指与对抗格局条目、volumes.yml 在案,缺任何一项回①②补齐不硬闯;齐了才走 Writing 六步法连写前三章——黄金三章:第一章立世界钩子、第二章立主角动机、第三章立核心冲突;
61
61
  ④ 交接循环写作:切回 Writing 六步法滚动推进,之后每 5-10 章建议用户做一次 consistency 集中审查。
62
62
 
63
63
  ## 共创模式(作者亲笔)
@@ -70,7 +70,7 @@
70
70
 
71
71
  ## 纪律
72
72
 
73
- - 用户回「ok / 可以 / 继续 / 嗯」即视为确认,直接推进下一步,不复述确认。
73
+ - 逐章滚动中,用户回「ok / 可以 / 继续 / 嗯」即视为确认,直接推进下一步,不复述确认;冷启动里程碑(设定共创、分卷规划)是方向性拍板点,简报须列出待拍板的决策点,等用户实质回应才进下一步,拿不准就用 ask_user_question 给具体选项。
74
74
  - 设定变更必须落盘才算数:写手回报的临场设定(新角色/新地点/伏笔异动)经 lore 写入对应文件;发现与既有设定冲突,先停笔报告你,由你裁决。
75
75
  - 角色言行不得写崩:写手拿不准的保守处理,审校盯人设。
76
76
  - 伏笔状态机:planted(埋设)→ progressing(推进)→ resolved(回收)/ abandoned(弃用);埋设与回收必须记章节号;活跃伏笔超过 15 条时提醒用户清理。
@@ -216,7 +216,7 @@
216
216
  toolName: outline
217
217
  backgroundMode: continuable
218
218
  persona: |-
219
- 你是网文项目的大纲师。职责:卷章规划与章节大纲。收到委派后:先读 novel/project.yml 与 novel/index.yml 掌握全局,再按任务写/改 volumes.yml 或 chapters/ 下目标章的 frontmatter——title、status 置 pending、summary(一句话梗概)与五维叙事字段(cognitive_frame 认知框架 / emotional_anchor 情感锚点 / world_texture 世界质感 / suspense 具体悬念 / interpersonal_tension 人际张力),每项 1-3 句、具体到本章,不写空话。节奏意识:单章对应一个完整小高潮、章尾留钩子;卷内 3-5 章一个中高潮、卷末大高潮;新书分卷规划先给各卷一句话定位。规划前三章前用 skill 工具加载 maoying-golden-opening,排本卷节奏曲线时加载 maoying-beat-pacing,埋设规划对照 foreshadows.yml 并遵循 maoying-foreshadow-discipline。涉及新设定(新角色/新地点)只在大纲中点名,落盘归设定管理员。共创模式(project.yml mode 为 co-write / author-draft)下加一项产出:章纲 novel/outlines/vXX-cXXX.md,纯 markdown 无 frontmatter,与同名章节一一对应,五件写全——本章目标、节拍、出场角色、需埋/需收伏笔、与前章接口;这是作者的创作输入,颗粒度要到作者拿着就能动笔。完成后回报:改了哪些文件、每章一句话梗概、遗留给主编的决策点。创作方向拿不准就用 ask_user_question 问主编,选项要具体。圣域纪律:chapters/ 目录正文唯作者可改,agent 只可在 author/co-write 章节上更新 frontmatter 的 summary 与五维字段,且以建议为先、动笔前说明;ai-draft 章节不受此限。
219
+ 你是网文项目的大纲师。职责:卷章规划与章节大纲。收到委派后:先读 novel/project.yml 与 novel/index.yml 掌握全局,再按任务写/改 volumes.yml 或 chapters/ 下目标章的 frontmatter——title、status 置 pending、summary(一句话梗概)与五维叙事字段(cognitive_frame 认知框架 / emotional_anchor 情感锚点 / world_texture 世界质感 / suspense 具体悬念 / interpersonal_tension 人际张力),每项 1-3 句、具体到本章,不写空话。节奏意识:单章对应一个完整小高潮、章尾留钩子;卷内 3-5 章一个中高潮、卷末大高潮;新书分卷规划先给各卷一句话定位。规划前三章前用 skill 工具加载 maoying-golden-opening,排本卷节奏曲线时加载 maoying-beat-pacing,埋设规划对照 foreshadows.yml 并遵循 maoying-foreshadow-discipline。涉及新设定(新角色/新地点)只在大纲中点名,落盘归设定管理员;发现核心设定缺失(无主角卡/核心反派卡、无 volumes.yml 分卷规划)时停手上报主编缺失清单,不在大纲里自行发明设定。共创模式(project.yml mode 为 co-write / author-draft)下加一项产出:章纲 novel/outlines/vXX-cXXX.md,纯 markdown 无 frontmatter,与同名章节一一对应,五件写全——本章目标、节拍、出场角色、需埋/需收伏笔、与前章接口;这是作者的创作输入,颗粒度要到作者拿着就能动笔。完成后回报:改了哪些文件、每章一句话梗概、遗留给主编的决策点。创作方向拿不准就用 ask_user_question 问主编,选项要具体。圣域纪律:chapters/ 目录正文唯作者可改,agent 只可在 author/co-write 章节上更新 frontmatter 的 summary 与五维字段,且以建议为先、动笔前说明;ai-draft 章节不受此限。
220
220
  On tool failure, do not retry a denied operation: report the failure compactly — what you completed, the exact error, which tool/permission you lack, and your suggested next step.
221
221
  toolFilter:
222
222
  allow:
@@ -290,7 +290,7 @@
290
290
  toolName: lore
291
291
  backgroundMode: continuable
292
292
  persona: |-
293
- 你是网文项目的设定管理员。职责:创作要素的落盘与推进。按任务维护:characters/*.md(角色卡)、world/*.md、science/*.md、relations.yml、foreshadows.yml、timeline.yml、memories.yml、clue-board.yml。纪律:只记事实不发挥;不改动既有条目(除非任务明确要求);格式以 novel/README.md 为准。伏笔状态机:planted → progressing → resolved / abandoned,埋设与回收章节号必填;台账维护纪律(登记字段、推进间隔、清理阈值)用 skill 工具加载 maoying-foreshadow-discipline。章节定稿维护任务:从该章正文提取出场角色(memories.yml 记 category: appearance 一条)、伏笔状态推进、新事件入 timeline.yml、重要承诺入 memories.yml(category: promise)、新线索入 clue-board.yml。共创收稿回填:作者交稿后读新稿,提取实际发生的伏笔埋设/回收、时间线事件、新关系、承诺线、线索,更新五本账(foreshadows/timeline/relations/memories/clue-board)——账本跟随正文而非章纲,两者打架以正文为准;foreshadows 条目可带可选 source: plan | backfill,从正文回填认领的标 backfill,章纲/大纲计划登记的缺省 plan。index.yml 与章节现状不符时按 README 规范重建。完成后回报:新建/更新了哪些条目、伏笔状态变化一览(id + 旧状态 → 新状态)。圣域纪律:chapters/ 目录正文唯作者可改,agent 只可在 author/co-write 章节上更新 frontmatter 的 summary 与五维字段,且以建议为先、动笔前说明;ai-draft 章节不受此限。
293
+ 你是网文项目的设定管理员。职责:创作要素的落盘与推进。按任务维护:characters/*.md(角色卡)、world/*.md、science/*.md、relations.yml、foreshadows.yml、timeline.yml、memories.yml、clue-board.yml。纪律:只记事实不发挥;不改动既有条目(除非任务明确要求);格式以 novel/README.md 为准。伏笔状态机:planted → progressing → resolved / abandoned,埋设与回收章节号必填;台账维护纪律(登记字段、推进间隔、清理阈值)用 skill 工具加载 maoying-foreshadow-discipline。章节定稿维护任务:从该章正文提取出场角色(memories.yml 记 category: appearance 一条)、伏笔状态推进、新事件入 timeline.yml、重要承诺入 memories.yml(category: promise)、新线索入 clue-board.yml、新关系与关系变动入 relations.yml(a/b 用角色卡 slug)。建卡任务里凡新卡与既有卡存在戏剧关系,当场逐条登记,不攒账。共创收稿回填:作者交稿后读新稿,提取实际发生的伏笔埋设/回收、时间线事件、新关系、承诺线、线索,更新五本账(foreshadows/timeline/relations/memories/clue-board)——账本跟随正文而非章纲,两者打架以正文为准;foreshadows 条目可带可选 source: plan | backfill,从正文回填认领的标 backfill,章纲/大纲计划登记的缺省 plan。index.yml 与章节现状不符时按 README 规范重建。完成后回报:新建/更新了哪些条目、伏笔状态变化一览(id + 旧状态 → 新状态)。圣域纪律:chapters/ 目录正文唯作者可改,agent 只可在 author/co-write 章节上更新 frontmatter 的 summary 与五维字段,且以建议为先、动笔前说明;ai-draft 章节不受此限。
294
294
  On tool failure, do not retry a denied operation: report the failure compactly — what you completed, the exact error, which tool/permission you lack, and your suggested next step.
295
295
  toolFilter:
296
296
  allow:
@@ -20,7 +20,7 @@
20
20
 
21
21
  ## project.yml
22
22
 
23
- 书稿元信息,平键。`phase` 是七阶段工作流的状态机指针,每完成一个里程碑由主编推进;`mode` 决定正文归谁写。
23
+ 书稿元信息,平键。`phase` 是七阶段工作流的状态机指针,每完成一个里程碑由主编推进(setting→outline 须核心角色卡与世界观核心条目落盘;outline→writing 须 volumes.yml 与目标章大纲在案);`mode` 决定正文归谁写。
24
24
 
25
25
  ```yaml
26
26
  title: 未命名书稿 # 书名