Agent Skills › lingfengQAQ/webnovel-writer

lingfengQAQ/webnovel-writer

GitHub

对网文项目执行只读体检,检查目录、文件、JSON、SQLite、RAG配置及依赖完整性。遵循阶段感知原则,提供缺失项影响与修复建议,不修改文件或安装依赖。

8 skills 5,909

Install All Skills

npx skills add lingfengQAQ/webnovel-writer --all -g -y
More Options

List skills in collection

npx skills add lingfengQAQ/webnovel-writer --list

Skills in Collection (8)

对网文项目执行只读体检,检查目录、文件、JSON、SQLite、RAG配置及依赖完整性。遵循阶段感知原则,提供缺失项影响与修复建议,不修改文件或安装依赖。
用户请求诊断网文项目状态 需要检查项目文件与配置完整性 排查构建或运行前的环境准备情况
webnovel-writer/skills/webnovel-doctor/SKILL.md
npx skills add lingfengQAQ/webnovel-writer --skill webnovel-doctor -g -y
SKILL.md
Frontmatter
{
    "name": "webnovel-doctor",
    "version": "0.1.0",
    "description": "对网文项目做只读体检\/诊断(\/webnovel-doctor)——检查目录、文件、JSON、SQLite、RAG 配置、依赖与 Dashboard 构建产物是否完整。",
    "allowed-tools": "Read Bash",
    "argument-hint": "[--chapter N] [--deep]"
}

Webnovel Doctor

目标

只读诊断当前书项目:确认所处阶段应有的目录、文件、JSON、SQLite、RAG 配置、Python 依赖与 Dashboard 构建产物是否完整。

原则

  1. 只读诊断:不写项目文件、不自动修复、不安装依赖、不启动 Dashboard。
  2. project-status 取短状态,再 doctor 做阶段感知检查。
  3. 统一用 python -X utf8,避免中文路径编码问题。
  4. 缺失项按 runtime 推导的阶段解释影响与修复建议,不把 init 刚结束的项目按已写多章项目检查。

执行

准备路径:

export WORKSPACE_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
export SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT:?}/scripts"

短状态:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" project-status --format summary

标准体检:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" doctor --format text

指定章节加 --chapter {chapter_num},深度体检加 --deep

输出方式

汇报包含:当前 phasetarget_chapter、是否有 blocker、缺失或异常文件路径、RAG / Python / Dashboard 配置是否缺失、每个问题的影响和建议修复动作。

不执行真实修复,不展示或要求粘贴 API key。

启动只读Web面板,用于查看小说创作进度、实体图谱及章节数据。通过校验环境并运行Python服务暴露API状态,支持自定义端口与无头模式,确保纯只读访问项目文件。
用户希望查看小说项目的整体状态或创作进度 需要可视化展示角色关系图谱或章节内容 检查Story Runtime主链的健康状态或最新提交
webnovel-writer/skills/webnovel-dashboard/SKILL.md
npx skills add lingfengQAQ/webnovel-writer --skill webnovel-dashboard -g -y
SKILL.md
Frontmatter
{
    "name": "webnovel-dashboard",
    "description": "启动只读小说管理面板,查看项目状态、实体图谱与章节内容。",
    "allowed-tools": "Bash Read"
}

Webnovel Dashboard

目标

  • 在本地启动只读 Web 面板,查看创作进度、设定词典、关系图谱、章节内容与追读力数据。
  • 暴露 Story Runtime 主链状态:/api/story-runtime/health、latest commit、fallback 情况。
  • 可监听 .webnovel/ 变化,但不修改任何项目文件。

执行流程

Step 1:确认环境与模块目录

export WORKSPACE_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"

if [ -z "${CLAUDE_PLUGIN_ROOT}" ] || [ ! -d "${CLAUDE_PLUGIN_ROOT}/dashboard" ]; then
  echo "ERROR: 未找到 dashboard 模块: ${CLAUDE_PLUGIN_ROOT}/dashboard" >&2
  exit 1
fi

export DASHBOARD_DIR="${CLAUDE_PLUGIN_ROOT}/dashboard"
export SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT}/scripts"

Step 2:解析项目根目录

export PROJECT_ROOT="$(python "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" where)"
echo "项目路径: ${PROJECT_ROOT}"

PROJECT_ROOT 必须解析成功。

Step 3:校验前端产物与依赖

if [ -n "${PYTHONPATH:-}" ]; then
  export PYTHONPATH="${CLAUDE_PLUGIN_ROOT}:${PYTHONPATH}"
else
  export PYTHONPATH="${CLAUDE_PLUGIN_ROOT}"
fi

if [ ! -f "${DASHBOARD_DIR}/frontend/dist/index.html" ]; then
  echo "ERROR: 缺少前端构建产物 ${DASHBOARD_DIR}/frontend/dist/index.html(dist 应随插件打包,确认插件完整安装)" >&2
  exit 1
fi

不默认安装依赖。仅当 Step 4 因缺依赖启动失败时,提示用户手动执行:

python -m pip install -r "${DASHBOARD_DIR}/requirements.txt"

Step 4:启动 Dashboard

python -m dashboard.server --project-root "${PROJECT_ROOT}"

不自动打开浏览器时加 --no-browser;自定义端口加 --port 9000

启动后优先确认接口可用:/api/story-runtime/health/api/preflight

成功标准

  • Dashboard 进程已启动并输出可访问 URL;页面显示项目数据(章节列表、实体图谱等)。

失败恢复

故障 恢复方式
启动报缺依赖 手动 pip install -r "${DASHBOARD_DIR}/requirements.txt",检查 Python 版本与网络
前端 dist/ 缺失 确认插件完整安装,dist 应随插件打包
项目根解析失败 检查 .webnovel/state.json 是否存在,确认 WORKSPACE_ROOT 正确
端口占用 --port <其他端口> 或关闭占用进程
页面空白/数据缺失 确认 .webnovel/ 下有 state.json、index.db 等数据文件

安全边界

  • 纯只读面板,不提供修改接口,不修改任何项目文件。
  • 文件访问限制在 PROJECT_ROOT 范围内,默认仅监听 localhost。
深度初始化网文项目,通过分阶段交互收集创作信息,生成项目骨架与约束文件。支持灵感来源询问、参考书拆解及多维度设定采集,确保后续规划与写作流程顺畅运行。
用户希望创建新的网文项目 需要深度结构化地收集故事设定与大纲
webnovel-writer/skills/webnovel-init/SKILL.md
npx skills add lingfengQAQ/webnovel-writer --skill webnovel-init -g -y
SKILL.md
Frontmatter
{
    "name": "webnovel-init",
    "description": "深度初始化网文项目。通过分阶段交互收集完整创作信息,生成可直接进入规划与写作的项目骨架与约束文件。",
    "allowed-tools": "Read Write Edit Grep Bash Agent AskUserQuestion WebSearch WebFetch",
    "argument-hint": "[书名或灵感(可选)]"
}

Project Initialization (Deep Mode)

目标

  • 结构化交互收集足够信息,避免"先生成再返工"。
  • 产出可落地骨架:.webnovel/state.json设定集/*大纲/总纲.md.webnovel/idea_bank.json.story-system/MASTER_SETTING.json
  • 保证后续 /webnovel-plan/webnovel-write 可直接运行。

执行原则

  1. 先收集,再生成;未过充分性闸门,不执行 webnovel.py init
  2. 分波次提问,每轮只问"当前缺失且会阻塞下一步"的信息;用户已明确的不重复问,冲突让用户裁决。
  3. 参考书拆解只返回结构化结果;用户确认前不得写入 idea_bank.json.story-system设定集大纲正文.webnovel/state.json 或任何 canon/read model 文件。

引用加载策略

路径说明:references/skills/webnovel-init/references/../../references/ 指共享 references。详细采集字段见 references/init-collection-schema.md(按需区段读,逐项收集,必填项以「充分性闸门」为准)。

Step Trigger Reference
Step 1 always references/system-data-flow.mdreferences/genre-tropes.md
题材/卖点采集 always ../../references/genre-profiles.md(只读当前 genre 段)
角色卡顿 人物扁平 references/worldbuilding/character-design.md
世界观/力量 按需 references/worldbuilding/faction-systems.mdreferences/worldbuilding/power-systems.mdreferences/worldbuilding/world-rules.mdreferences/worldbuilding/setting-consistency.md
创意约束 Step 6 references/creativity/creativity-constraints.md(区段:采集读 ## 一、创意包 Schema (Idea Package)## 六、硬约束驱动创意 (Hard Constraints)## 八、评分系统 (Scoring System),评分展示读 ### 8.1 五维评分)、references/creativity/selling-points.md(区段:## 9. 核心卖点定位模板 骨架,按需补 ### 1.3 核心卖点黄金公式## 7. 实战检查清单);复合题材读 creative-combination.md;卡顿读 inspiration-collection.md;题材命中读 anti-trope-*.md
命名 开始命名 python -X utf8 "${SCRIPTS_DIR}/reference_search.py" --skill init --table 命名规则 --query "{命名对象} {题材}" --genre {题材}

按需读取上述长细则(创意约束、反套路库、世界观设计指南、卖点模板),不内联其条目。

工具策略

  • Read/Grep:读项目上下文与参考文件。
  • Bash:执行 webnovel.py init、文件存在性检查、最小验证。
  • Agent:拆分并行子任务;Step 1.5 用户选择参考书拆解作灵感来源时调用 webnovel-writer:deconstruction-agent
  • AskUserQuestion:关键分歧裁决、候选选择、最终确认。
  • WebSearch/WebFetch:仅在用户要求市场趋势/平台风向、创意约束需时间敏感依据、或题材信息明显不确定时使用,先 search 后 fetch 核验。

交互流程(Deep)

Step 1:预检与上下文加载

环境设置(bash 命令执行前):

export WORKSPACE_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"

if [ -z "${CLAUDE_PLUGIN_ROOT}" ] || [ ! -d "${CLAUDE_PLUGIN_ROOT}/scripts" ]; then
  echo "ERROR: 未设置 CLAUDE_PLUGIN_ROOT 或缺少目录: ${CLAUDE_PLUGIN_ROOT}/scripts" >&2
  exit 1
fi
export SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT}/scripts"

必须做:

  • 确认当前目录可写;确认入口脚本 ${SCRIPTS_DIR}/webnovel.py 存在(仅支持插件目录)。
  • 初始化前不要用 whereWORKSPACE_ROOT 解析成书项目根;新项目尚不存在时 where 可能命中旧指针或旧项目。
  • 只打印工作区与脚本目录,确认生成目标将在工作区下的书名安全化子目录中。
  • 加载最小参考:references/system-data-flow.mdreferences/genre-tropes.mdtemplates/genres/ 仅在选定题材后按需读取。

输出:进入 Deep 采集前的"已知信息清单"和"待收集清单"。

Step 1.5:灵感来源询问(可选)

进入故事核采集前,必须先用 AskUserQuestion 或直接提问确认用户是否提供灵感来源。不要默认拆书,也不要把参考作品当作必填项。

建议询问:

你这本书的灵感来源想从哪里开始?可以直接说原创想法,也可以提供参考作品做拆书提炼。若要拆书,请给参考书名+平台,并尽量提供章节摘录或文本路径;没有参考也可以直接跳过。

可接受来源:原创想法、参考作品拆书(书名/平台/章节摘录/文本路径)、市场趋势、题材模板/反套路库/已有脑洞片段。

当用户选择参考作品拆书且提供文本路径或章节摘录时,必须使用 Agent 工具调用 webnovel-writer:deconstruction-agent,不得由 init 主流程口头替代拆解结果。

Use the Agent tool to run `webnovel-writer:deconstruction-agent`.

Prompt: reference_title={reference_title}; reference_source={reference_source}; reference_text_path={reference_text_path}; reference_text_excerpt={reference_text_excerpt}; analysis_mode={quick|deep|auto}; init_goal={当前初始化故事方向或空}; target_genre={题材或空}。只返回 init_reference_research JSON 对象,不写任何文件,不创建目录,不写 .story-system、.webnovel、设定集、大纲、正文、idea_bank.json、state.json 或任何 canon/read model 文件。

调用后主流程必须记录一份 SubagentRun 汇总(仅供最终报告使用,不写入 canon):

{
  "name": "deconstruction-agent",
  "user_label": "参考作品拆解",
  "status": "completed | partial | failed | skipped",
  "problems": [],
  "auto_handled": [],
  "needs_user_action": false,
  "duration_ms": 0,
  "outputs": []
}

quality.passed=falseconfidence < 0.85、输入不足、文本不可读、降级 quick mode 或输出不完整时,必须写入 problems,并让最终报告进入“建议确认 / 必须处理”。

处理规则:

  • 只有书名/平台、无文本或摘录时,先问能否提供摘录/路径;不能提供则把参考书仅作"方向线索",不得编造其黄金三章、角色、设定或剧情事实。
  • 接收返回的 init_reference_research JSON 后,只使用 reader_promiseopening_hook_patternscool_point_loopsprotagonist_patternsantagonist_pressure_patternspacing_notesborrowable_structuresdifferentiation_requirementsinit_candidatesquality
  • 先检查 qualityquality.passed=falseconfidence < 0.85warnings 非空时,不得把候选折叠进创意约束包,只能把风险和需补充材料展示给用户确认。
  • do_not_copycanon_contamination_warnings 必须进入已知信息清单,作为后续创意生成红线。
  • Step 2-6 只能使用用户确认过、并已变形为本书差异化表达的模式;禁止把参考书角色、设定、组织、地点、金手指、剧情事实原样写入生成项目文件。

Step 2:故事核与商业定位

必收:书名、题材(支持 A+B 复合)、目标规模(总字数或总章数)、一句话故事、核心冲突、目标读者/平台。

canonical 题材集合(写入 project_info.genre):都市、玄幻、仙侠、奇幻、科幻、历史、悬疑、游戏、古言、现言、幻言、年代、种田、快穿、衍生。

可自由输入细分 preset / 套路 / 形式,初始化脚本会映射到 canonical 并按 taxonomy 加载模板(示例:修仙、系统流、规则怪谈、宫斗宅斗、电竞、末世)。优先让用户自由描述再二次结构化确认;卡住时给 2-4 个候选方向。

Step 3:角色骨架与关系冲突

必收:主角姓名、主角欲望、主角缺陷(会害他付代价)、主角结构(单/多主角)、感情线配置(无/单女主/多女主)、反派分层(小/中/大)与镜像对抗一句话。可选:主角原型标签、多主角分工。

Step 4:金手指与兑现机制

必收:金手指类型(可为"无金手指")、名称/系统名(无则留空)、风格、可见度、不可逆代价(必须有代价或明确"无+理由")、成长节奏。 条件必收:系统流给系统性格+升级节奏;重生给重生时间点+记忆完整度;传承/器灵给辅助边界+出手限制。

Step 5:世界观与力量规则

必收:世界规模(单城/多域/大陆/多界)、力量体系类型、势力格局、社会阶层与资源分配。 题材相关:货币体系与兑换规则、宗门/组织层级、境界链与小境界。

Step 6:创意约束包(差异化核心)

流程:

  1. 汇总 Step 1.5 已确认的灵感来源:原创想法、参考拆书结果、市场趋势、题材模板或反套路库。
  2. 基于题材映射加载反套路库(最多 2 个主相关库)。
  3. 生成 2-3 套创意包,每套含:一句话卖点、反套路规则 1 条、硬约束 2-3 条、主角缺陷驱动一句话、反派镜像一句话、开篇钩子。
  4. 三问筛选:为什么这题材必须这么写?换常规主角会不会塌?卖点能否一句话讲清且不撞模板?
  5. 展示五维评分(详见 references/creativity/creativity-constraints.md8.1 五维评分)辅助决策。
  6. 用户选择最终方案,或拒绝并给出原因。

备注:

  • 若用户要求"贴近当下市场",可触发外部检索并标注时间戳。
  • 若使用了参考拆解,展示候选时必须标明参考来源、转换方式、不可复制项和差异化要求;用户未明确确认前,不写入 idea_bank.json 或任何生成项目文件。

Step 7:一致性复述与最终确认

必须输出"初始化摘要草案"并让用户确认:故事核(题材/一句话故事/核心冲突)、主角核(欲望/缺陷)、金手指核(能力与代价)、世界核(规模/力量/势力)、创意约束核(反套路+硬约束)。

确认规则:用户未明确确认,不执行生成;用户仅改局部,回到对应 Step 最小重采集。

充分性闸门(必须通过)

未满足以下条件前,禁止执行 webnovel.py init

  1. 书名、题材(可复合)已确定。
  2. 目标规模可计算(字数或章数至少一个)。
  3. 主角姓名 + 欲望 + 缺陷完整。
  4. 世界规模 + 力量体系类型完整。
  5. 金手指类型已确定(允许"无金手指")。
  6. 创意约束已确定:反套路规则 1 条 + 硬约束至少 2 条,或用户明确拒绝并记录原因。

项目目录安全规则(必须)

  • project_root 必须由书名安全化生成:PROJECT_ROOT="${WORKSPACE_ROOT}/${PROJECT_SLUG}";安全化结果为空或以 . 开头时自动前缀 proj-
  • 禁止在插件目录(${CLAUDE_PLUGIN_ROOT})下生成项目文件;禁止直接把 WORKSPACE_ROOT 当作 PROJECT_ROOT,除非用户明确指定当前目录就是书项目根。
  • 初始化前必须展示并确认 WORKSPACE_ROOTPROJECT_SLUGPROJECT_ROOT
PROJECT_SLUG="$(python -X utf8 -c "import re,sys; title=sys.argv[1].strip(); slug=re.sub(r'[\\\\/:*?\"<>|]+','',title); slug=re.sub(r'\\s+','-',slug).strip('-'); print(('proj-' + slug) if (not slug or slug.startswith('.')) else slug)" "{title}")"
PROJECT_ROOT="${WORKSPACE_ROOT}/${PROJECT_SLUG}"
echo "WORKSPACE_ROOT=${WORKSPACE_ROOT}"
echo "PROJECT_SLUG=${PROJECT_SLUG}"
echo "PROJECT_ROOT=${PROJECT_ROOT}"

执行生成

1) 运行初始化脚本

参数全部来自上面的采集对象(书名/题材/主角/金手指/世界观/反派/创意约束等),逐字段映射为 webnovel.py init--* 选项;完整字段清单见 references/init-collection-schema.md,可用 python "${SCRIPTS_DIR}/webnovel.py" init --help 核对选项名。

python "${SCRIPTS_DIR}/webnovel.py" init \
  "${PROJECT_ROOT}" "{title}" "{genre}" \
  --protagonist-name "{protagonist_name}" \
  --target-words {target_words} --target-chapters {target_chapters} \
  --protagonist-desire "{protagonist_desire}" --protagonist-flaw "{protagonist_flaw}" \
  --golden-finger-type "{gf_type}" --gf-irreversible-cost "{gf_irreversible_cost}" \
  --world-scale "{world_scale}" --power-system-type "{power_system_type}" \
  --core-selling-points "{core_points}"
  # 其余字段(结构/感情线/反派/势力/货币/境界/原型/读者/平台等)按采集对象继续追加对应 --* 选项

2) 写入 idea_bank.json

写入 .webnovel/idea_bank.json,内容必须与最终选定方案一致:

{
  "selected_idea": {"title": "", "one_liner": "", "anti_trope": "", "hard_constraints": []},
  "constraints_inherited": {"anti_trope": "", "hard_constraints": [], "protagonist_flaw": "", "antagonist_mirror": "", "opening_hook": ""}
}

3) Patch 总纲

大纲/总纲.md 必须补齐:故事一句话、核心主线/暗线、创意约束(反套路、硬约束、主角缺陷、反派镜像)、反派分层、关键爽点里程碑(2-3 条)。

4) 生成写前合同树(Story System 初始化)

init 完成后立即生成 MASTER_SETTING,让后续 plan 有调性/禁忌参照。此处不传 --chapter(只生成 MASTER_SETTING.jsonanti_patterns.json),也不传 --emit-runtime-contracts(还没有卷/章级数据);plan 拆到具体章节时再生成 volume/chapter/review 合同。

GENRE="$(python -X utf8 -c "import json,os; root=os.environ['PROJECT_ROOT']; s=json.load(open(root + '/.webnovel/state.json',encoding='utf-8')); pi=s.get('project_info',{}); print(pi.get('genre') or s.get('project',{}).get('genre',''))")"

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" \
  story-system "${GENRE}" --genre "${GENRE}" --persist --format json

验证与交付

test -f "${PROJECT_ROOT}/.webnovel/state.json"
find "${PROJECT_ROOT}/设定集" -maxdepth 1 -type f -name "*.md"
test -f "${PROJECT_ROOT}/大纲/总纲.md"
test -f "${PROJECT_ROOT}/.webnovel/idea_bank.json"
test -f "${PROJECT_ROOT}/.story-system/MASTER_SETTING.json"
test "$(basename "${PROJECT_ROOT}")" = "${PROJECT_SLUG}"

成功标准:

  • state.json 存在且 title/genre/target_words/target_chapters 不为空。
  • 设定集核心文件存在:世界观.md力量体系.md主角卡.md;单主角不生成 主角组.mdheroine_config=无女主 不生成 女主卡.md
  • 默认不生成 金手指设计.md复合题材-融合逻辑.md爽点规划.md 或空目录;这些以主角卡、世界观、卷纲为事实源。
  • 总纲.md 已填核心主线与约束字段;idea_bank.json 已写入且与最终选定方案一致。
  • .story-system/MASTER_SETTING.json 存在且 route.primary_genre 非空。

失败处理(最小回滚)

触发:关键文件缺失;总纲关键字段缺失;约束启用但 idea_bank.json 缺失或不一致。

恢复:只补缺失字段,不全量重问;只重跑最小步骤(文件缺失→重跑 webnovel.py init;总纲缺字段→只 patch 总纲;idea_bank 不一致→只重写该文件);重新验证,全部通过后结束。

作者友好过程提示与恢复契约

初始化开始前先说明本次会经历:收集故事核心 -> 确认创意约束 -> 生成项目骨架 -> 写入初始故事档案 -> 验证能否进入规划。过程提示用作者语言,不直接输出原始 JSON、traceback 或长命令日志;技术详情写入 .webnovel/logs/run_last.log

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" run-log \
  --event init-progress \
  --payload-json "{\"stage\": \"init\"}" \
  --format text

过程提示每次不超过两行,只说当前动作和影响,例如“正在生成项目骨架:会创建设定集、总纲和初始故事档案”。少打扰确认策略:默认继续收集和生成;只有核心设定、参考拆解采用、项目目录安全、写入 canon 前的最终方案需要用户拍板。

需要用户裁决时使用有限选项,并说明每个选项影响;例如保留当前设定 / 修改局部 / 暂停初始化。卡住时必须说明卡点、已完成内容和恢复建议,例如“设定集已生成,Story System 初始档案缺失;重新运行 /webnovel-init 会只补缺失文件”。

不可恢复故障才在最终报告提示 .webnovel/logs/run_last.log;平时只保留日志,不打扰作者。收尾必须调用作者报告 helper:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" user-report \
  --stage init \
  --format text

作者友好最终报告契约

最终回复必须面向作者,不输出原始 JSON、traceback 或长命令日志。使用固定三段式,并以一句总状态开头:

总状态:已完成 / 部分完成 / 需要你处理 / 未完成。

一、产生的文件与完成情况
- ...

二、过程中遇到的问题与异常耗时
- 已自动处理:...
- 建议确认:...
- 必须处理:...

三、下一步建议
- ...

必须汇报:

  • 项目目录、.webnovel/state.json.webnovel/idea_bank.json
  • 设定集/世界观.md设定集/力量体系.md设定集/主角卡.md设定集/反派设计.md
  • 大纲/总纲.md.story-system/MASTER_SETTING.json
  • 是否使用参考作品拆解;用户确认前未写入 canon 的情况。
  • 缺失信息是否影响后续 /webnovel-plan

异常分类:

  • 已自动处理:脚本补齐目录、重跑最小初始化步骤、重新生成缺失的非内容文件等。
  • 建议确认:参考拆解质量略低、候选创意需用户再看一眼。
  • 必须处理:核心设定未确认、项目目录不安全、关键文件仍缺失。

下一步建议必须使用任务化语言 + 可复制命令,例如:

- 接下来可以规划第一卷:
  /webnovel-plan 1

不写 token 统计;如需排查故障,只给日志路径或建议运行 /webnovel-doctor

从当前会话提取成功写作模式并追加至 project_memory.json。需验证项目根目录,读取章节状态,解析用户输入或对话认可写法,归类类型后调用脚本写入,支持去重与失败恢复。
用户希望总结当前对话中的有效写作技巧 用户手动触发 /webnovel-learn 命令以保存经验
webnovel-writer/skills/webnovel-learn/SKILL.md
npx skills add lingfengQAQ/webnovel-writer --skill webnovel-learn -g -y
SKILL.md
Frontmatter
{
    "name": "webnovel-learn",
    "description": "从当前会话提取成功写作模式并写入 project_memory.json",
    "allowed-tools": "Read Bash",
    "argument-hint": "[要记住的写作经验]"
}

/webnovel-learn

Project Root Guard(必须先确认)

  • 必须在项目根目录执行(需存在 .webnovel/state.json
  • 用统一入口解析项目根,避免写错目录:
export WORKSPACE_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
export SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT:?}/scripts"
export PROJECT_ROOT="$(python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" where)"

目标

提取可复用的写作模式(钩子/节奏/对话/微兑现等),追加到 .webnovel/project_memory.json

执行流程

  1. 读取 "$PROJECT_ROOT/.webnovel/state.json"progress.current_chapter 作为当前章节号;缺失则用 source_chapter: null,不阻断。
  2. 解析用户输入(/webnovel-learn 后的经验文本;为空则取本次对话中用户认可的写法),归类 pattern_type(hook/pacing/dialogue/payoff/emotion/format/other,无法归类用 other)。
  3. 调用 project-memory add-pattern 写入,不得手写或拼接 JSON:
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" project-memory add-pattern \
  --pattern-type "{pattern_type}" \
  --description "{用户输入或提炼后的完整描述}" \
  --category "{分类,可空}" \
  --importance "{high|medium|low}"

约束

  • 不删除旧记录,仅追加。
  • 追加前扫描已有 patternspattern_type + description 完全相同则跳过并告知用户,部分相似不去重。
  • 禁止使用 Write 或手工编辑 .webnovel/project_memory.json

成功标准

  • project_memory.json 存在且格式合法,新 pattern 已追加到 patterns 数组。
  • 输出包含 status: success 和完整 learned 对象。

失败恢复

故障 恢复方式
project_memory.json 不存在 脚本自动初始化 {"patterns": []} 后继续
JSON 解析失败 不写入脏数据,告知用户文件损坏并建议手动修复
state.json 缺失无法取章节号 source_chapter: null,不阻断
基于总纲增量生成卷纲、时间线和章纲,并将新增设定写回设定集。遵循不重写全局文档原则,严格执行时间线硬约束与冲突阻断机制,按需读取参考文件以优化效率。
需要细化卷大纲或章纲时 发现新增设定需同步至设定集时 生成章节时间线规划时
webnovel-writer/skills/webnovel-plan/SKILL.md
npx skills add lingfengQAQ/webnovel-writer --skill webnovel-plan -g -y
SKILL.md
Frontmatter
{
    "name": "webnovel-plan",
    "description": "基于总纲生成卷纲、时间线和章纲,并把新增设定增量写回现有设定集。",
    "allowed-tools": "Read Write Edit Bash AskUserQuestion",
    "argument-hint": "[卷号,如 1]"
}

Outline Planning

主 agent 职责:基于总纲增量细化卷纲/时间线/章纲,把新增设定写回设定集,并刷新 Story System 写作合同。不重做全局故事,不重写整份总纲或设定集。

执行原则

  1. 只做增量补齐,不重写整份总纲或设定集。
  2. 先锁定卷级节奏,再批量拆章。
  3. 时间线是硬约束,所有章纲必须带时间字段。
  4. 若发现总纲与设定冲突,先阻断,再等用户裁决。
  5. 优先级链:用户明确要求 > 总纲核心冲突与卷末高潮 > 时间线硬约束 > skill 默认流程 > reference 建议。

阻断条件

  • 项目根不合法或总纲缺失。
  • 总纲缺少卷名 / 章节范围 / 核心冲突 / 卷末高潮 → 阻断并请求用户补全。
  • Step 2 / Step 8 发现设定冲突 → 标记 BLOCKER,等待用户裁决。
  • 批量拆章时时间回跳且未标注闪回 → 阻断当前批次。
  • Step 9 验证失败 → 只重做失败批次,不覆盖整卷。

环境准备

export WORKSPACE_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
export SKILL_ROOT="${CLAUDE_PLUGIN_ROOT}/skills/webnovel-plan"
export SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT}/scripts"
export PROJECT_ROOT="$(python "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" where)"

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" placeholder-scan --format text

规划开始 / 结束都运行 placeholder-scan;plan 阶段发现占位先警告并补齐相关文件,进入写章前不得保留当前章相关实体的 [待...] / 暂名 / {占位}

读取策略(按阶段触发,不预读全部 reference)

每个 reference 只在对应 Step 触发时读取,且优先区段读:先用 Grep 匹配 ^#{2,4} 定位标题锚点行号,再用 Read 的 offset/limit 取目标段。

触发 读取方式 文件
Step 4 全文 ${SKILL_ROOT}/../../templates/output/大纲-卷节拍表.md
Step 5 全文 ${SKILL_ROOT}/../../templates/output/大纲-卷时间线.md
Step 6 always 区段 ${SKILL_ROOT}/../../references/genre-profiles.md(仅当前 genre 的 ### 2.x 段)
Step 6 always 全文 ${SKILL_ROOT}/../../references/shared/strand-weave-pattern.md
章纲拆分 always 区段 ${SKILL_ROOT}/../../references/outlining/plot-signal-vs-spoiler.md
Step 6 需要爽点 区段 ${SKILL_ROOT}/../../references/shared/cool-points-guide.md
Step 6/7 需要冲突 区段 ${SKILL_ROOT}/references/outlining/conflict-design.md
Step 6/7 特定节奏 区段 ${SKILL_ROOT}/references/outlining/genre-volume-pacing.md
Step 7 追读力分析 区段 ${SKILL_ROOT}/../../references/reading-power-taxonomy.md
Step 7 章纲细化 + 节点规范 区段 ${SKILL_ROOT}/references/outlining/chapter-planning.md

CSV 创作参考用检索读,不 cat 整表:

python -X utf8 "${SCRIPTS_DIR}/reference_search.py" --skill plan --table 爽点与节奏 --query "{卷级核心冲突}" --genre "${GENRE}"
python -X utf8 "${SCRIPTS_DIR}/reference_search.py" --skill plan --table 桥段套路 --query "{卷级核心冲突}" --genre "${GENRE}"
python -X utf8 "${SCRIPTS_DIR}/reference_search.py" --skill plan --table 命名规则 --query "角色命名" --genre "${GENRE}"

执行流程

Step 1:加载项目数据并确认前置条件

# 项目配置/投影状态(兼容读取,不作为写后事实真源)
cat "$PROJECT_ROOT/.webnovel/state.json"

# 总纲(全局蓝图);确认卷名/章节范围/核心冲突/卷末高潮,不足则阻断
cat "$PROJECT_ROOT/大纲/总纲.md"

# 题材(来自 init 配置快照,后续 CSV 检索和裁决匹配依赖此值);写后主链真源仍是 .story-system/
GENRE="$(python -X utf8 -c "import json; s=json.load(open('${PROJECT_ROOT}/.webnovel/state.json',encoding='utf-8')); pi=s.get('project_info',{}); print(pi.get('genre') or s.get('project',{}).get('genre',''))")"

按需读取设定集:设定集/世界观.md设定集/力量体系.md设定集/主角卡.md设定集/反派设计.md.webnovel/idea_bank.json

跨卷状态读取(已有已完成卷,即 .webnovel/summaries/ 下有文件时必须执行):

# 最近 5 章摘要
for ch in $(seq $((START_CH - 5)) $((START_CH - 1))); do
  cat "$PROJECT_ROOT/.webnovel/summaries/ch$(printf '%04d' $ch).md" 2>/dev/null
done

# 核心角色当前状态 / 核心关系当前状态 / 活跃伏笔(跨卷未回收)
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" knowledge query-entity-state --entity "{protagonist_id}" --at-chapter {上一卷最后章}
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" knowledge query-relationships --entity "{protagonist_id}" --at-chapter {上一卷最后章}
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" memory-contract get-open-loops

Step 2:补齐设定基线

让设定集从骨架进入"可规划、可写作"。增量补齐,不清空、不重写整文件;发现冲突先列出并阻断。

  • 设定集/世界观.md:世界边界、社会结构、关键地点用途。
  • 设定集/力量体系.md:境界链、限制、代价与冷却。
  • 设定集/主角卡.md:欲望、缺陷、初始资源与限制。
  • 设定集/反派设计.md:小/中/大反派层级与镜像关系。

Step 3:选择目标卷并确认范围

确认卷名、章节范围、核心冲突,以及是否有特殊要求(视角、情感线、题材偏移)。

Step 4:生成卷节拍表

加载模板 ${SKILL_ROOT}/../../templates/output/大纲-卷节拍表.md

硬要求:必须填写中段反转,确无则写"无(理由:...)";危机链至少 3 次递增;卷末新钩子必须能落到最后一章的章末未闭合问题。

输出文件:大纲/第{volume_id}卷-节拍表.md

Step 5:生成卷时间线表

加载模板 ${SKILL_ROOT}/../../templates/output/大纲-卷时间线.md

硬要求:必须明确时间体系与本卷时间跨度;有倒计时事件时列出并标记 D-N。

输出文件:大纲/第{volume_id}卷-时间线.md

Step 6:生成卷纲骨架

必读 ${SKILL_ROOT}/../../references/genre-profiles.md${SKILL_ROOT}/../../references/shared/strand-weave-pattern.md;按需读取爽点 / 冲突 / 节奏 reference(见读取策略表)。

卷纲必须明确:卷摘要、关键人物与反派层级、Strand 分布、爽点密度规划、伏笔规划、约束触发规划。

跨卷一致性检查(非首卷必须执行):

  • 上一卷未回收的伏笔必须出现在新卷伏笔规划中(继续推进或标记回收)。
  • 角色关系变化必须延续,不能当上一卷没发生过。
  • 主角能力 / 境界必须承接,不回退也不跳级(除非有剧情解释)。

Step 7:批量生成章纲

批次规则:默认 10章/批;复杂题材或多线并进降到 8章/批;简单升级流放宽到 12章/批;不建议单批超过 12章

按需读取 ${SKILL_ROOT}/../../references/reading-power-taxonomy.md${SKILL_ROOT}/references/outlining/chapter-planning.md

每章必须包含:目标、阻力、代价、时间锚点、章内时间跨度、与上章时间差、倒计时状态、爽点、Strand、反派层级、视角/主角、关键实体、本章变化、章末未闭合问题、钩子,以及结构化节点 CBNCPNsCEN必须覆盖节点本章禁区

结构化节点

节点格式统一为 主体 | 动作/变化 | 对象/结果(写作执行骨架,不追求严格语法 SVO)。完整格式说明、字段细则与示例见 ${SKILL_ROOT}/references/outlining/chapter-planning.md 的「结构化节点规范」,按需区段读,不在本文件内联。

核心约束:

  • 每章固定 1 个 CBN2-4 个 CPN、固定 1 个 CENCPNs 按时间顺序排列。
  • 相邻章节 CEN -> 下一章 CBN 必须逻辑承接(首章和末章除外)。
  • 必须覆盖节点最多 4 个,建议 CBN + CEN + 1~2 个核心 CPN;可选节点只作建议,不作 fail 主依据。
  • 本章禁区不超过 5 条,只写本章绝对不能发生的硬禁区,不写风格类建议。
  • 向后兼容:旧项目章纲缺失上述字段时,下游流程正常执行,仅跳过结构化检查。

输出文件:大纲/第{volume_id}卷-详细大纲.md

Step 8:把新增设定写回现有设定集

输入:卷节拍表、卷时间线表、卷详细大纲、现有设定集文件。

写回规则:只增量补充相关段落;新角色写入角色卡或角色组;新势力 / 地点 / 规则写入世界观或力量体系;新反派层级写入反派设计。

硬规则:若发现与总纲或既有设定冲突,标记 BLOCKER 并停止后续更新。

Step 9:验证、保存并更新状态

必须通过:节拍表 / 时间线表 / 详细大纲均存在且非空;每章时间字段齐全;时间线单调递增;倒计时推进正确;新设定已回写;BLOCKER=0;有节点时相邻章节 CEN -> CBN 无明显逻辑冲突且每章必须覆盖节点不超过 4 个。

验证全部通过后,生成显式结构化写回文件 大纲/第{volume_id}卷-总纲写回.json(只写规划中显式列出的伏笔 / 开放环,禁止从卷纲自由文本推断):

{
  "next_volume_anchor": {
    "volume": 2,
    "volume_name": "下一卷卷名",
    "core_conflict": "下一卷核心冲突",
    "volume_end_climax": "下一卷卷末高潮"
  },
  "foreshadow_writeback": [
    {"content": "本卷规划明确新增的伏笔", "buried_chapter": "第10章", "payoff_chapter": "", "level": "卷级"}
  ],
  "open_loop_writeback": [
    {"content": "本卷结束后仍持续开放的问题", "buried_chapter": "", "payoff_chapter": "", "level": "持续开放环"}
  ]
}

执行最小总纲写回(只更新 大纲/总纲.md 的 V+1 卷名 / 核心冲突 / 卷末高潮与伏笔表,不生成下一卷详细大纲 / 节拍表 / 时间线 / 章纲):

python "${SCRIPTS_DIR}/webnovel.py" --project-root "$PROJECT_ROOT" master-outline-sync \
  --volume {volume_id} \
  --writeback-file "大纲/第{volume_id}卷-总纲写回.json" \
  --format text

更新状态:

python "${SCRIPTS_DIR}/webnovel.py" --project-root "$PROJECT_ROOT" update-state -- \
  --volume-planned {volume_id} \
  --chapters-range "{start}-{end}"

Step 10:刷新 Story System 写作合同(本次规划已落到具体章节时必须执行)

genre 从 state.json 初始化配置快照读取;写前主链真源是 .story-system/ 合同树。必须先从详细大纲解析真实 CHAPTER_GOAL,禁止传 {章纲目标} / 第N章章纲目标 这类占位文本。

GENRE="$(python -X utf8 -c "import json; s=json.load(open('${PROJECT_ROOT}/.webnovel/state.json',encoding='utf-8')); pi=s.get('project_info',{}); print(pi.get('genre') or s.get('project',{}).get('genre',''))")"

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" story-system "${CHAPTER_GOAL}" \
  --genre "${GENRE}" --chapter {chapter_num} --persist --emit-runtime-contracts --format both

生成后必须把 .story-system/MASTER_SETTING.json.story-system/volumes/.story-system/chapters/.story-system/reviews/ 视为后续写作主链输入。进入写章前不得保留当前章相关实体的 [待...] / 暂名 / {占位}

硬失败条件

  • 节拍表 / 时间线表 / 详细大纲不存在或为空。
  • 中段反转缺失且未给出理由。
  • 任一章节缺少时间字段;时间回跳且未标注闪回;倒计时算术冲突。
  • 与总纲核心冲突或卷末高潮明显冲突。
  • 存在 BLOCKER 未裁决。

恢复规则

  1. 只重做失败批次,不覆盖整卷文件。
  2. 最后一个批次无效时,只删除并重写该批次。
  3. 仅在全部验证通过后更新状态。

作者友好过程提示与恢复契约

规划开始前先说明本次会经历:检查总纲与设定 -> 生成节拍表 -> 生成时间线 -> 拆章纲 -> 写回新增设定 -> 刷新写作合同。过程提示用作者语言,不直接输出原始 JSON、traceback 或长命令日志;技术详情写入 .webnovel/logs/run_last.log

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" run-log \
  --event plan-progress \
  --payload-json "{\"stage\": \"plan\", \"volume\": {volume_id}}" \
  --format text

过程提示每次不超过两行,只说当前动作和影响,例如“正在拆本卷章纲:会把每章目标、时间锚点和禁区写清楚”。少打扰确认策略:默认继续推进;只有总纲 / 设定冲突、时间线回跳、卷末钩子取舍、需要覆盖已有规划时才询问。

需要用户裁决时使用有限选项,并说明影响;例如沿用总纲 / 修改设定 / 暂停规划。卡住时必须说明卡点、已完成内容和恢复建议,例如“节拍表和时间线已保留,第 21-30 章拆分失败;重新运行 /webnovel-plan {volume_id} 会只重做失败批次”。

不可恢复故障才在最终报告提示 .webnovel/logs/run_last.log;平时只保留日志,不打扰作者。收尾必须调用作者报告 helper:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" user-report \
  --stage plan \
  --volume {volume_id} \
  --format text

作者友好最终报告契约

最终回复必须面向作者,不输出原始 JSON、traceback 或长命令日志。使用固定三段式,并以一句总状态开头:

总状态:已完成 / 部分完成 / 需要你处理 / 未完成。

一、产生的文件与完成情况
- ...

二、过程中遇到的问题与异常耗时
- 已自动处理:...
- 建议确认:...
- 必须处理:...

三、下一步建议
- ...

必须汇报:

  • 大纲/第{volume_id}卷-节拍表.md
  • 大纲/第{volume_id}卷-时间线.md
  • 大纲/第{volume_id}卷-详细大纲.md
  • 新增设定写回了哪些设定集文件。
  • 大纲/第{volume_id}卷-总纲写回.json
  • master-outline-syncupdate-state、Story System 合同刷新是否完成。
  • 占位符、时间线、节点承接是否通过。

异常分类:

  • 已自动处理:只重做失败批次、补齐非阻断占位、重跑合同刷新。
  • 建议确认:新增角色名、势力名、卷末钩子需要作者看一眼。
  • 必须处理:总纲 / 设定冲突、时间线回跳、BLOCKER 未裁决、当前章相关占位残留。

下一步建议必须使用任务化语言 + 可复制命令,例如:

- 接下来可以写第一章:
  /webnovel-write 1

不写 token 统计;如需排查故障,只给日志路径或建议运行 /webnovel-doctor

用于查询小说项目的设定、角色、力量体系、势力及伏笔等信息。通过识别查询类型,按需调用最窄工具检索写前/写后真源或记忆数据,支持紧急度分析与金手指状态查询,避免全量加载。
用户询问故事设定、角色历史状态或境界变化 用户查询实体关系、敌友阵营归属 用户咨询世界规则、力量体系约束 用户查找伏笔、未闭合悬念或紧急伏笔 用户需要综合跨类型的长期记忆与时间线联合查询
webnovel-writer/skills/webnovel-query/SKILL.md
npx skills add lingfengQAQ/webnovel-writer --skill webnovel-query -g -y
SKILL.md
Frontmatter
{
    "name": "webnovel-query",
    "description": "查询项目设定、角色、力量体系、势力、伏笔等信息。支持紧急度分析与金手指状态查询。",
    "allowed-tools": "Read Grep Bash",
    "argument-hint": "[查询词,如 角色名\/伏笔\/境界]"
}

Information Query Skill

Use when

用户询问关于故事设定、角色、力量体系、势力、伏笔、金手指、节奏等项目内信息时触发。

项目根保护

export WORKSPACE_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
export SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT}/scripts"
export SKILL_ROOT="${CLAUDE_PLUGIN_ROOT}/skills/webnovel-query"
export PROJECT_ROOT="$(python "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" where)"
  • PROJECT_ROOT 必须包含 .webnovel/state.json
  • 禁止${CLAUDE_PLUGIN_ROOT}/ 下读取或写入项目文件

查询分类 → 最窄工具

先识别查询类型,再用下表最窄工具。不默认全量加载,只在综合 / 跨多类型查询时用 memory-contract load-context

查询类型 关键词 最窄工具
角色历史状态 某角色在第N章时 / 时间点状态 / 境界变化 knowledge query-entity-state
实体关系 关系 / 敌友 / 师徒 / 阵营归属 knowledge query-relationships
世界规则 力量规则 / 设定铁律 / 境界体系约束 memory-contract query-rules
伏笔 / open loop 伏笔 / 紧急伏笔 / 未闭合悬念 memory-contract get-open-loops
综合 / 复杂 跨多类型、需要时间线 + 长期记忆联合 memory-contract load-context
静态设定 角色卡 / 力量体系 / 世界观 / 势力 / 标签格式 Grep + Read 设定集

引用加载策略

按查询类型按需加载,先识别再加载。路径说明:references/ 指 skill 私有 skills/webnovel-query/references/../../references/ 指共享 references。

查询类型 Reference 实际路径
数据流 / 优先级 数据流规范 ${SKILL_ROOT}/references/system-data-flow.md
伏笔分析 伏笔分析 ${SKILL_ROOT}/references/advanced/foreshadowing.md
节奏分析 Strand 模式 ${SKILL_ROOT}/../../references/shared/strand-weave-pattern.md
格式查询 标签规范 ${SKILL_ROOT}/references/tag-specification.md

不得同时加载两个以上 reference,除非用户请求明确跨多类型。

查询流程

  1. 识别查询类型:按「查询分类 → 最窄工具」表匹配关键词。

  2. 按优先级定位写前真源(写前真源 → 写后真源 → 投影层):

    1. .story-system/MASTER_SETTING.json - 全书主设定(题材、调性、核心禁忌)
    2. .story-system/volumes/*.json - 卷级合同(本卷目标、节奏策略)
    3. .story-system/chapters/*.json - 章级合同(本章焦点、动态上下文)
    4. latest accepted .story-system/commits/chapter_XXX.commit.json - 写后事实(已发布章节的定稿状态)
    5. memory-contract 系列查询 - 记忆编排结果(长期记忆、伏笔、时间线)
    6. .webnovel/state.json / index.db - 投影层(仅 fallback / read-model,类比网文后台的"角色卡"、"章节列表")

    优先级说明

    • 写前真源(1-3):作者开写前必须遵守的"大纲、设定、禁区"
    • 写后真源(4):已发布章节的"定稿状态",不可篡改
    • 投影层(5-6):从写后真源自动生成的"查询视图",方便快速检索
  3. 调用最窄工具检索:按类型只调用所需命令,不默认全量 load-context

# 角色历史状态:某实体在指定章节时的状态
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" knowledge query-entity-state --entity "{entity_id}" --at-chapter {N}

# 实体关系:某实体在指定章节时的所有关系
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" knowledge query-relationships --entity "{entity_id}" --at-chapter {N}

# 世界规则
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" memory-contract query-rules --chapter {chapter_num}

# 伏笔 / open loop
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" memory-contract get-open-loops

# 仅综合 / 复杂查询:需要时间线 + 长期记忆联合时才用
python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" memory-contract load-context --chapter {chapter_num}

静态设定(角色卡 / 力量体系 / 世界观 / 标签格式)直接用 Grep 定位行号再 Read 取片段,不经 memory-contract。

  1. 格式化输出:按下方模板输出。

输出格式

# 查询结果:{关键词}

## 概要
- **匹配类型**: {type}
- **数据源**: {实际命中的真源 / 投影层}
- **匹配数量**: X 条

## 详细信息
{结构化数据,含文件路径和行号}

## 数据一致性检查
{state.json 与静态文件的差异,若无差异则省略}

边界与失败恢复

  • 只读操作,不修改任何项目文件
  • 若数据源缺失,明确告知用户缺少什么文件
  • 若查询无匹配,返回空结果并建议检查范围
  • .story-system/ 合同与 accepted commit 缺失,必须显式说明当前查询已降级到 legacy fallback
解析小说项目根,调度reviewer审查指定章节质量。流程包括校验环境、刷新合同、加载参考、调用Agent生成JSON报告并落库,最终由pipeline产出指标。遇阻断问题或需裁决项时停止或交用户处理。
需要评估小说章节质量 触发结构化审查并生成报告
webnovel-writer/skills/webnovel-review/SKILL.md
npx skills add lingfengQAQ/webnovel-writer --skill webnovel-review -g -y
SKILL.md
Frontmatter
{
    "name": "webnovel-review",
    "description": "使用审查 Agent 评估章节质量,生成报告并写回审查指标。",
    "allowed-tools": "Read Grep Write Edit Bash Agent AskUserQuestion",
    "argument-hint": "[章号或范围,如 5 或 1-5]"
}

Quality Review Skill

目标

  • 解析真实书项目根,调度统一 reviewer 完成结构化审查并落库。
  • 主链事实以 .story-system/reviews/chapter_{NNN}.review.json 与 latest accepted CHAPTER_COMMIT 为准;.webnovel/state.json 仅为兼容投影。
  • blocking=true 问题时交用户裁决。

红线

  • 必须通过 Agent 工具调用 reviewer,禁止主流程伪造结论或口头总结代替 subagent 输出。
  • reviewer 只返回严格 JSON;主流程负责把返回值写入 ${PROJECT_ROOT}/.webnovel/tmp/review_results.json,随后由 review-pipeline 覆盖为标准 review_result artifact。
  • 报告与 metrics 只由 review-pipeline --save-metrics 产出;主流程不伪造 overall_score
  • 项目根不合法 / 缺 .webnovel/state.json / 缺待审正文 → 阻断。

执行流程

Step 1:解析项目根

export WORKSPACE_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
export SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT}/scripts"
export PROJECT_ROOT="$(python "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" where)"

PROJECT_ROOT 必须包含 .webnovel/state.json,否则阻断。

Step 2:目标章缺合同时刷新 runtime 合同

目标章缺 runtime 合同时,先用详细大纲的真实本章目标刷新(CHAPTER_GOAL 禁止 {章纲目标} / 第N章章纲目标 占位文本):

GENRE="$(python -X utf8 -c "import json; s=json.load(open('${PROJECT_ROOT}/.webnovel/state.json',encoding='utf-8')); pi=s.get('project_info',{}); print(pi.get('genre') or s.get('project',{}).get('genre',''))")"

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" \
  story-system "${CHAPTER_GOAL}" --genre "${GENRE}" --chapter {chapter_num} --persist --emit-runtime-contracts --format both

Step 3:按需加载参考

Trigger Reference
always ../../references/shared/core-constraints.md
always ../../references/review-schema.md
审查涉及爽点或钩子 ../../references/shared/cool-points-guide.md
审查涉及多线交织 ../../references/shared/strand-weave-pattern.md
blocking issue 需用户裁决 (Step 8) ../../references/review/blocking-override-guidelines.md

Step 4:加载投影状态与待审正文

cat "${PROJECT_ROOT}/.webnovel/state.json"

确认当前章节号与对应正文文件;缺正文或缺兼容状态文件立即阻断。

Step 5:调用统一审查 Agent

必须通过 Agent 工具调用 reviewer。审查方法与维度细则由 reviewer 自带,本 Skill 不展开。

Use the Agent tool to run `webnovel-writer:reviewer`.

Prompt: chapter={chapter_num}; chapter_file={chapter_file}; project_root=${PROJECT_ROOT}; scripts_dir=${SCRIPTS_DIR}。严格输出 reviewer schema JSON,不评分,不口头总结。

reviewer 返回后,主流程把严格 JSON 写入 ${PROJECT_ROOT}/.webnovel/tmp/review_results.json(reviewer 不持 Write,是这份 artifact 的非写入方)。review-pipeline 必须把同一路径覆盖为标准 review_result artifact(含 blocking_count)。

调用后主流程必须记录 SubagentRun 汇总(仅供最终报告使用):

{
  "name": "reviewer",
  "user_label": "写作检查",
  "status": "completed | partial | failed | skipped",
  "problems": [],
  "auto_handled": [],
  "needs_user_action": false,
  "duration_ms": 0,
  "outputs": []
}

reviewer 跳过、失败、输出不完整、正文为空、维度跳过、blocking issue 或耗时异常,必须写入 problems / auto_handled,不得在最终报告中静默。

Step 6:生成报告并落库

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" review-pipeline \
  --chapter {chapter_num} \
  --review-results "${PROJECT_ROOT}/.webnovel/tmp/review_results.json" \
  --metrics-out "${PROJECT_ROOT}/.webnovel/tmp/review_metrics.json" \
  --report-file "审查报告/第{chapter_num}章审查报告.md" \
  --save-metrics

review-pipeline --save-metrics 同时完成报告生成、review_metrics.json 输出、review_metrics 表写入。阻断判断以 review_results 中的 blocking=true 为准。

Step 7:写入兼容审查记录

python "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" update-state -- --add-review "{chapter_num}-{chapter_num}" "审查报告/第{chapter_num}章审查报告.md"

兼容投影 / read model,不是写后事实真源。

Step 8:处理阻断

存在任意 blocking=true 问题时,用 AskUserQuestion 让用户裁决:

  • 立即修复:输出返工清单,仅在用户明确授权下做最小修改。
  • 仅保存报告,稍后处理:保留报告与指标记录,结束流程。

成功标准

  1. 已解析真实书项目根。
  2. 已通过 reviewer 输出结构化问题 JSON,落盘到 .webnovel/tmp/review_results.json
  3. 审查报告已生成,review_metrics 已写入 index.dbreview_metrics.json 已输出。
  4. 审查记录已写入 .webnovel/state.json 兼容投影。
  5. 存在阻断问题时,用户已明确选择处理策略。

作者友好过程提示与恢复契约

审查开始前先说明本次会经历:定位待审正文 -> 刷新缺失合同 -> 写作检查 -> 生成报告和指标 -> 处理阻断裁决。过程提示用作者语言,不直接输出原始 JSON、traceback 或长命令日志;技术详情写入 .webnovel/logs/run_last.log

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" run-log \
  --event review-progress \
  --payload-json "{\"stage\": \"review\", \"chapter\": {chapter_num}}" \
  --format text

过程提示每次不超过两行,只说当前动作和影响,例如“正在生成审查报告:会把阻断问题和最值得改的建议放到顶部”。少打扰确认策略:无阻断时不询问;存在 blocking issue、缺待审正文、用户要求是否立即修改时才询问。

需要用户裁决时使用有限选项,并说明影响;例如立即修复 / 仅保存报告稍后处理 / 放弃本次审查。卡住时必须说明卡点、已完成内容和恢复建议,例如“reviewer 结果已保存,metrics 落库失败;重新运行 /webnovel-review {chapter_num} 会从报告落库继续”。

不可恢复故障才在最终报告提示 .webnovel/logs/run_last.log;平时只保留日志,不打扰作者。收尾必须调用作者报告 helper:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" user-report \
  --stage review \
  --chapter {chapter_num} \
  --format text

作者友好最终报告契约

最终回复必须面向作者,不输出原始 JSON、traceback 或长命令日志。使用固定三段式,并以一句总状态开头:

总状态:已完成 / 部分完成 / 需要你处理 / 未完成。

一、产生的文件与完成情况
- ...

二、过程中遇到的问题与异常耗时
- 已自动处理:...
- 建议确认:...
- 必须处理:...

三、下一步建议
- ...

必须汇报:

  • 审查报告文件。
  • .webnovel/tmp/review_results.json
  • .webnovel/tmp/review_metrics.json
  • review_metrics 是否落库。
  • 阻断问题数量。
  • 用户裁决状态。
  • 如果无阻断,明确可以继续写作。

状态规则:

  • 有 blocking 问题且用户未选择处理策略时,最终状态为“需要你处理”。
  • 只保存报告、稍后处理时,最终状态为“需要你处理”或“部分完成”。
  • reviewer 跳过、失败或输出不完整时,最终状态不得写“已完成”。

异常分类:

  • 已自动处理:重复生成报告、覆盖本次旧审查中间文件、成功补写 metrics。
  • 建议确认:非阻断但高收益修改建议、命名或设定细节建议看一眼。
  • 必须处理:blocking issue、缺待审正文、reviewer 输出不完整、metrics 落库失败。

下一步建议必须使用任务化语言 + 可复制命令,例如:

- 审查无阻断,可以继续写下一章:
  /webnovel-write {next_chapter}

不写 token 统计;如需排查故障,只给日志路径或建议运行 /webnovel-doctor

用于生成可发布网文章节的自动化技能,遵循上下文提取、起草、审查、润色及备份流程。支持默认、快速和最小三种模式,强制使用Agent调用子代理,严格校验项目约束与写作任务书,确保内容符合大纲设定且质量达标。
用户请求撰写或更新小说章节 需要生成符合特定章纲和角色设定的正文草稿
webnovel-writer/skills/webnovel-write/SKILL.md
npx skills add lingfengQAQ/webnovel-writer --skill webnovel-write -g -y
SKILL.md
Frontmatter
{
    "name": "webnovel-write",
    "description": "产出可发布章节,完整执行上下文→起草→审查→润色→提交→备份。",
    "allowed-tools": "Read Write Edit Grep Bash Agent AskUserQuestion",
    "argument-hint": "[章号] [--fast|--minimal]"
}

写章流程

目标

产出可发布章节到 正文/第{NNNN}章-{title}.md。默认 2000-2500 字,用户/大纲另有要求时从之。

模式

模式 流程
默认 Step 1→2→3→4→5→6
--fast Step 1→2→3(轻量)→4→5→6
--minimal Step 1→2→3(写 no-review artifact)→4(仅排版)→5→6

硬规则

  • 禁止并步、跳步、伪造审查
  • 必须使用 Agent 工具调用指定 subagent;不得用主流程口头代替 subagent 输出
  • 审查只跑一轮;blocking issue 定点修复或经用户裁决后才进 Step 4/5
  • 失败只补跑失败步骤,不回退
  • 参考资料按步骤按需加载

优先级

用户要求 > 状态机硬门槛 > 项目约束(总纲/设定/记忆)> skill 流程 > reference 建议

CSV 检索(Step 2 按需)

python -X utf8 "${SCRIPTS_DIR}/reference_search.py" --skill write --table {表名} --query "{关键词}" --genre {题材}

触发条件:新角色→命名规则,战斗→场景写法,多角色对话→写作技法,情感描写→写作技法,高频桥段→场景写法。

执行流程

准备:预检

export WORKSPACE_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
export SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT:?}/scripts"
export SKILL_ROOT="${CLAUDE_PLUGIN_ROOT:?}/skills/webnovel-write"

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" preflight
export PROJECT_ROOT="$(python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${WORKSPACE_ROOT}" where)"

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" placeholder-scan --format text

准备:刷新合同树

genre 从 .webnovel/state.json 的初始化配置快照读取,用于刷新合同树;写前主链真源仍是 .story-system/ 合同。调用 story-system 前必须先从详细大纲解析真实本章目标,禁止传 {章纲目标}第N章章纲目标 等占位 query。

GENRE="$(python -X utf8 -c "import json,sys; s=json.load(open('${PROJECT_ROOT}/.webnovel/state.json',encoding='utf-8')); pi=s.get('project_info',{}); print(pi.get('genre') or s.get('project',{}).get('genre',''))")"

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" \
  story-system "${CHAPTER_GOAL}" --genre "${GENRE}" --chapter {chapter_num} --persist --emit-runtime-contracts --format both

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" \
  write-gate --chapter {chapter_num} --stage prewrite --format json

必备文件:MASTER_SETTING.json(调性/禁忌)、volume_{NNN}.json(卷级节奏)、chapter_{NNN}.review.json(必须节点/禁区)。缺失则阻断。

chapter_{NNN}.json 必须优先检查顶层 chapter_directivechapter_focus 只能来自 chapter_directive.goal 或真实 query,不得从 dynamic_context 的参考摘要继承。

写作任务书排序必须固定为:

  1. 本章硬性约束:chapter_directive.goal/time_anchor/chapter_span/countdown/chapter_end_open_question
  2. CBN/CPNs/CEN 与 must_cover_nodes
  3. 本章禁区:forbidden_zones,违反即不通过
  4. 风格指引:reasoning、主角卡 OOC 警戒、anti_patterns
  5. 场景写法补充:dynamic_context,仅作风格参考,不能覆盖章纲约束

Step 1:context-agent 生成写作任务书

必须使用 Agent 工具调用 context-agent,不得由主流程自行整理任务书。

Use the Agent tool to run webnovel-writer:context-agent.

Task:

  • chapter={chapter_num}
  • project_root=${PROJECT_ROOT}
  • scripts_dir=${SCRIPTS_DIR}
  • storage_path=${PROJECT_ROOT}/.webnovel
  • state_file=${PROJECT_ROOT}/.webnovel/state.json(projection/read-model,仅兼容读取)
  • 先 research,再按 本章硬性约束 → CBN/CPNs/CEN → 本章禁区 → 风格指引 → dynamic_context 补充参考 的顺序输出五段写作任务书。
  • 上下文不足时返回 blocker。

产物:一份写作任务书,能独立支撑 Step 2 起草。

调用后主流程必须记录 SubagentRun 汇总(仅供最终报告使用):

{
  "name": "context-agent",
  "user_label": "整理写作依据",
  "status": "completed | partial | failed | skipped",
  "problems": [],
  "auto_handled": [],
  "needs_user_action": false,
  "duration_ms": 0,
  "outputs": []
}

上下文不足、legacy fallback、伏笔数据缺失、任务书不完整或耗时异常,必须写入 problems / auto_handled,不得在最终报告中静默。

Step 2:起草正文

只根据任务书起草。不加载 core-constraints/anti-ai-guide(已内化到任务书)。只输出纯正文,无占位符。有结构化节点时围绕 CBN→CPNs→CEN 展开。中文思维写作。

Step 3:审查

必须使用 Agent 工具调用 reviewer,不得由主流程伪造审查 JSON。

Use the Agent tool to run webnovel-writer:reviewer.

Task:

  • chapter={chapter_num}
  • chapter_file=${CHAPTER_FILE}
  • project_root=${PROJECT_ROOT}
  • scripts_dir=${SCRIPTS_DIR}
  • 只返回严格的 reviewer schema JSON,不写任何文件。
  • 不评分、不口头总结。

reviewer 只返回 JSON;主流程负责用 Write 把返回的 JSON 写入 ${PROJECT_ROOT}/.webnovel/tmp/review_results.json(reviewer 不持 Write,是这份 artifact 的非写入方)。随后必须运行 review-pipeline;review-pipeline 会把同一路径覆盖为标准 review_result artifact(含 blocking_count),供 precommit gate 与后续提交命令使用。

调用后主流程必须记录 SubagentRun 汇总(仅供最终报告使用):

{
  "name": "reviewer",
  "user_label": "写作检查",
  "status": "completed | partial | failed | skipped",
  "problems": [],
  "auto_handled": [],
  "needs_user_action": false,
  "duration_ms": 0,
  "outputs": []
}

reviewer 跳过、失败、输出不完整、--minimal 写 no-review artifact、blocking issue、维度跳过或耗时异常,必须写入 problems / auto_handled,不得在最终报告中静默。

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" review-pipeline \
  --chapter {chapter_num} \
  --review-results "${PROJECT_ROOT}/.webnovel/tmp/review_results.json" \
  --metrics-out "${PROJECT_ROOT}/.webnovel/tmp/review_metrics.json" \
  --report-file "审查报告/第{chapter_num}章审查报告.md" \
  --save-metrics

审查只跑一轮,reviewer 只调用一次。blocking=true 的问题在不改剧情、不破设定的前提下定点修复后直接进 Step 4,不重新调用 reviewer;确实无法修复的 blocking 问题用 AskUserQuestion 让用户裁决(接受当前版本 / 手动修复 / 放弃)。非 blocking issue 交给 Step 4 处理。--fast 只检查 setting/timeline/continuity。

--minimal 不调用 reviewer 与 review-pipeline,但必须覆盖写入本章新的 no-review review_results.json(禁止复用旧 artifact),使 Step 5 提交链有有效 --review-result(成功标准“审查已落库”对 --minimal 的豁免仍成立):

python -X utf8 -c "import json,os; from pathlib import Path; root=Path(os.environ['PROJECT_ROOT']); ch=int('{chapter_num}'); p=root/'.webnovel'/'tmp'/'review_results.json'; p.parent.mkdir(parents=True,exist_ok=True); p.write_text(json.dumps({'chapter':ch,'issues':[],'issues_count':0,'blocking_count':0,'has_blocking':False,'summary':'minimal mode: reviewer skipped by user-selected --minimal flow','review_skipped':True,'review_mode':'minimal'},ensure_ascii=False,indent=2),encoding='utf-8')"

Step 4:润色

references/polish-guide.md 区段读:先 Grep 匹配 ^#{1,3} 定位锚点行号,再 Read 的 offset/limit 取段——主路径取 ## 2. 执行顺序(必须按序);Anti-AI 终检单独区段取 ## 2A. Anti-AI 检测细则## Phase 1 增补:Anti-AI 规范(7层,原版)(词库段),不全文读。references/writing/typesetting.mdreferences/style-adapter.md 短文件,全文读。

顺序:修复非 blocking issue → 风格适配 → 排版 → Anti-AI 终检。

只改表达不改事实。anti_ai_force_check=fail 时不进 Step 5。--minimal 仅排版。

Step 5:提交

5.1 Data Agent 提取事实

必须使用 Agent 工具调用 data-agent,产出 fulfillment_result / disambiguation_result / extraction_result 三份 JSON,并复用 Step 3 的 review_results。

Use the Agent tool to run webnovel-writer:data-agent.

Task:

  • chapter={chapter_num}
  • chapter_file=${CHAPTER_FILE}
  • project_root=${PROJECT_ROOT}
  • scripts_dir=${SCRIPTS_DIR}
  • output_dir=${PROJECT_ROOT}/.webnovel/tmp
  • 按你自己的 schema(见 data-agent 输出格式段)生成 fulfillment_result.json、disambiguation_result.json、extraction_result.json 三份 artifact。
  • 你是这三份 artifact 的唯一写入者;不直接写 state/index/summaries/memory/vectors/projection。

artifact 字段 schema 由 data-agent 自身定义、runtime validator 校验;主流程只检查文件存在与 schema,不重写、不补写、不口头替代。

调用后主流程必须记录 SubagentRun 汇总(仅供最终报告使用):

{
  "name": "data-agent",
  "user_label": "保存本章故事事实",
  "status": "completed | partial | failed | skipped",
  "problems": [],
  "auto_handled": [],
  "needs_user_action": false,
  "duration_ms": 0,
  "outputs": []
}

三份 artifact 写入状态、schema 不合格、pending 消歧、长时间无进展或输出不完整,必须写入 problems;自动重跑或降级处理必须写入 auto_handled

5.2 提交前校验与 CHAPTER_COMMIT

先跑 precommit gate:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" \
  write-gate --chapter {chapter_num} --stage precommit --format json

precommit 通过后,运行提交前只读 git diff 变更面校验(写入所有权 sanity check,只读、不 stage、不提交):

if git -C "${PROJECT_ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  git -C "${PROJECT_ROOT}" diff --name-status -- .
  git -C "${PROJECT_ROOT}" diff --check -- .
fi

变更面不得出现插件目录、其他书项目、其他章节正文或不属于本章流程的手写状态文件;git diff 只覆盖 git 可见文件,SQLite / .webnovel/ 内部语义由 5.3 postcommit 与 runtime 只读查询验证。若项目根不是 git worktree,记录“跳过 git diff 校验”,不得因此跳过 precommit gate。本步只读,禁止在此执行 git add/git commit

校验通过后运行 chapter-commit:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" chapter-commit \
  --chapter {chapter_num} \
  --review-result "${PROJECT_ROOT}/.webnovel/tmp/review_results.json" \
  --fulfillment-result "${PROJECT_ROOT}/.webnovel/tmp/fulfillment_result.json" \
  --disambiguation-result "${PROJECT_ROOT}/.webnovel/tmp/disambiguation_result.json" \
  --extraction-result "${PROJECT_ROOT}/.webnovel/tmp/extraction_result.json"

自动判定:blocking_count>0 或 missed_nodes 非空 或 pending 非空 → rejected,否则 accepted。

5.3 验证投影

projection_status 五项(state/index/summary/memory/vector)全部 done 或 skipped。

chapter_status 由 projection writer 自动推进:accepted→committed,rejected→rejected。

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" \
  write-gate --chapter {chapter_num} --stage postcommit --format json

5.4 失败隔离

commit 未生成→重跑 5.2。projection 失败→只补跑 projection,不回退 Step 1-4。

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" \
  projections retry --chapter {chapter_num} --format json

Step 6:Git 备份

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" backup \
  --chapter {chapter_num} \
  --chapter-title "{title}"

备份必须以解析后的 PROJECT_ROOT 为准,禁止从工作区父目录执行裸全量 Git add,避免把书项目仓库作为父仓库的嵌入仓库/submodule 加入。

作者友好过程提示与恢复契约

开始写章前先用作者语言说明本次目标、主要阶段和是否需要守在旁边,不承诺固定耗时。过程提示只说当前在做什么和会产生什么,不直接输出原始 JSON、traceback 或长命令日志;技术详情写入 .webnovel/logs/run_last.log

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" run-log \
  --event write-start \
  --payload-json "{\"chapter\": {chapter_num}, \"mode\": \"{mode}\"}" \
  --format text

写章过程节点(最多 6 个):

  1. 检查项目环境:确认项目、占位符和本章要求可用。
  2. 整理写作依据:读取章纲、最近剧情和未回收伏笔。
  3. 起草正文:根据写作任务书生成本章正文。
  4. 写作检查:审查阻断问题和高收益修改建议。
  5. 保存本章故事事实:提取本章目标完成情况、歧义和新事实。
  6. 提交备份:把本章事实入账、更新故事资料并备份。

重复执行同一章时,先读取可信断点:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" run-ledger write-resume \
  --chapter {chapter_num} \
  --mode "{mode}" \
  --format json

run-ledger write-resume 只给续跑建议,不自动覆盖文件。它会根据正文、审查结果、data artifacts、commit、projection 和备份状态判断从哪里继续。正文被手动改过、章纲更新晚于正文、本章已 accepted 又重跑时,必须停下用有限选项询问:沿用当前正文 / 重新起草 / 只查看状态;不得覆盖作者手改。

每个关键步骤完成后记录 run-ledger record-write-step,至少记录 step、status、输入/输出文件路径、problems、auto_handled 和 duration_ms,供下一次续跑和最终报告使用。

少打扰确认策略:默认继续推进;只有创作方向、事实一致性、文件覆盖风险或 blocking issue 无法定点处理时才问。需要用户裁决时给 2-3 个有限选项,并说明每个选项影响。

卡住时必须说明卡点、已完成内容和恢复建议:例如“正文和审查报告已保留,保存本章故事事实失败;重新运行 /webnovel-write {chapter_num} 会从 data-agent 继续”。不可恢复故障才在最终报告提示 .webnovel/logs/run_last.log;平时只保留日志,不打扰作者。

收尾必须调用作者报告 helper,优先以 helper 输出组织最终回复:

python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" user-report \
  --stage write \
  --chapter {chapter_num} \
  --format text

充分性闸门

  1. 正文文件存在且非空
  2. 审查已落库(--minimal 除外)
  3. blocking=true 必须在 Step 3 定点修复或经用户裁决
  4. anti_ai_force_check=pass(--minimal 除外)
  5. accepted CHAPTER_COMMIT,projection 五项 done/skipped
  6. chapter_status=committed(projection 自动推进)
  7. write-gate 的 prewrite / precommit / postcommit 均通过

失败恢复

审查缺失→重跑 Step 3。摘要/状态/记忆缺失→重跑 Step 5。润色失真→回 Step 4 修复后重跑 Step 5。

作者友好最终报告契约

最终回复必须面向作者,不输出原始 JSON、traceback 或长命令日志。使用固定三段式,并以一句总状态开头:

总状态:已完成 / 部分完成 / 需要你处理 / 未完成。

一、产生的文件与完成情况
- ...

二、过程中遇到的问题与异常耗时
- 已自动处理:...
- 建议确认:...
- 必须处理:...

三、下一步建议
- ...

必须汇报:

  • 正文文件路径。
  • 审查报告路径。
  • .webnovel/tmp/review_results.json
  • .webnovel/tmp/fulfillment_result.json
  • .webnovel/tmp/disambiguation_result.json
  • .webnovel/tmp/extraction_result.json
  • .story-system/commits/chapter_{NNN}.commit.json
  • state / index / summary / memory / vector 更新状态。
  • 备份状态。
  • 是否可以继续写下一章。

状态规则:

  • chapter-commit rejected、任一 write-gate failed、projection failed 时,最终状态不得写“已完成”。
  • --fast--minimal 的跳过项必须说明;--minimal 跳过审查时归入“已自动处理”或“建议确认”,不得假装已完成完整审查。
  • projection retry 发生时必须说明已自动处理和最终结果。

异常分类:

  • 已自动处理:projection retry 成功、RAG 临时降级但不影响结果、旧 no-review artifact 被本章新 artifact 覆盖。
  • 建议确认:新增角色名 / 设定名、低置信歧义但不阻断、非阻断审查建议。
  • 必须处理:blocking issue 未裁决、data artifacts 缺失或 schema 不完整、commit rejected、projection failed。

下一步建议必须使用任务化语言 + 可复制命令,例如:

- 接下来可以写下一章:
  /webnovel-write {next_chapter}

不写 token 统计;如需排查故障,只给日志路径或建议运行 /webnovel-doctor

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-21 03:26
浙ICP备14020137号-1 $Carte des visiteurs$