--- name: awesome-novel description: 和 AI 协作写小说的工作流系统。7 个 agent 协作完成从设定到归档的完整写作流程。入口检测 → 初始化/迁移 → 交 novel-agent 调度。适用场景:从零写新小说、导入已有小说。 --- # Novel — 小说创作工作流 和 AI 一起写小说。本 skill 负责项目状态检测、新项目初始化、旧版项目自动迁移,完成后将控制权交给 novel-agent。 ## OpenCode 集成说明 本 skill 也支持 OpenCode。安装在 `~/.config/opencode/skills/awesome-novel/` 后,项目初始化脚本会自动部署 agent 定义到 `.opencode/agents/`,OpenCode 即可自动发现: - `@novel-agent` — 加载总指挥 agent - `@volume-planner`、`@chapter-planner` 等 — 加载子 agent - **Task 工具** — novel-agent 通过 Task 工具调用子 agent **调度机制:** novel-agent 写 order 文件到 `.agent/task/` → Task 工具调用子 agent → 子 agent 读取 order 执行 → 清理 order 后退回。 ## 检测流程 — 严格按此执行,禁止跳过 ``` 检测项目状态 ├─ story.yaml 存在 → 旧版 2.x → 执行自动迁移(见下文) ├─ story.md 不存在 → 询问作者是否初始化 → 是则执行 init.py │ └─ python tools/init.py [project-path] [--genre <编号>] → 完成后 @novel-agent └─ story.md 存在 → 已有项目 ├─ 检查同步新鲜度 │ ├─ python tools/sync-project.py . --check → exit 0 → 已最新,略过 │ ├─ python tools/sync-project.py . --check → exit 1 → 有更新 │ │ └─ 展示变更文件,询问作者是否同步 │ │ ├─ 确认 → 运行 python tools/sync-project.py . │ │ └─ 跳过 → 继续 │ └─ .agent/.sync-fingerprint 不存在(首次) │ └─ 静默运行 python tools/sync-project.py . → 写入指纹 └─ → @novel-agent 继续写作 ``` **强制规则:** - `story.md` 不存在时,**先询问作者**是否要在此目录创建小说项目,确认后再运行 `init.py` - 禁止未经确认直接执行 `init.py` - 确认后必须运行 `init.py`,禁止手动创建目录结构替代 - **禁止在 skill 安装目录(含 `skills/awesome-novel` 路径)内运行 `init.py`** — 此目录是技能仓库,不是小说项目 - 如果当前目录是 skill 安装目录,应提示作者切换到目标目录后再执行 - `init.py` 执行完毕后,确认 `.agent/status.md` 和 `.opencode/agents/` 已生成,方可进入 `@novel-agent` - 如果 `init.py` 报错,必须先修复问题重新执行,不允许绕过 ## 初始化 — 先询问,确认后执行,不可跳过 全新项目先询问作者是否初始化,确认后运行 `init.py`(项目路径可选,默认当前目录): ``` python tools/init.py [project-path] [--genre <编号>] ``` **禁止以任何理由跳过 init.py:** 手动创建目录、复制模板、直接调用 agent 都属于违规行为。`init.py` 是初始化入口,必须执行且完整运行。 `init.py` 会: 1. 选题材 2. 创建项目骨架(settings/、volumes/、chapters/、prompts/、archives/) 3. 部署 agent 定义到 `.opencode/agents/`(OpenCode)或 `.claude/agents/`(Claude Code) 4. 按题材继承反 AI 规则和文风偏好到 `.claude/knowledge/` 5. 按题材继承格式规范、题材案例到 `.claude/knowledge/` 6. 创建空白的写作记忆文件(`.claude/memory/*.md`) 7. 创建永久记忆占位文件(`.claude/knowledge/permanent-memory.md`) 8. 生成 CLAUDE.md(OpenCode 下生成 AGENTS.md) 9. 初始化状态文件 `.agent/status.md` 以上 9 步全部由 `init.py` 自动完成,AI 无需也不应手动干预。 **检查:** 运行后确认 `.agent/status.md` 存在且内容正确,方可进入 `@novel-agent`。 ## 设定讨论 — novel-agent 与作者讨论后,由 updater 写入 `init.py` 完成后进入 `@novel-agent`,此时 `phase=setup`,按以下流程: 1. **novel-agent 检测到 setup 阶段**,与作者逐项讨论设定(世界观/角色/风格/题材)。如果作者需要帮忙取书名,参考 `knowledge/title-craft/index.md` 的方法论给出建议 2. 讨论完毕后,novel-agent **写 order 文件** `.agent/task/setting-update-order.md` 3. novel-agent 通过 **Agent 工具调用 updater** 4. **updater 读取 order**,写入 `settings/world-setting.md`、`settings/genre-setting.md`、`settings/character-setting/*.md` 等设定文件 5. updater 清理 order 文件并结束 6. **novel-agent 确认 order 已清理**,推进 phase → outline,进入卷纲规划 **权限规则:** novel-agent 不得直接写 `settings/` 下的文件,设定写入必须通过 updater 的 setting-update 模式完成。 ## 自动迁移(2.x → 3.0) 检测到 `story.yaml` 存在时,按以下流程自动迁移: ### Step 1: 展示迁移计划 扫描项目目录,给作者看三张清单: **文件清单:** - 设定文件:story.yaml + settings/ 下所有文件 - 角色文件:settings/character-setting/ 下所有文件 - 卷纲:volumes/ 下所有文件 - 正文:archives/ 下 `.md` 文件数量 - 章纲(已归档):chapters/ 下 `status: archived` 的章节数量 - 章纲(跳过):chapters/ 下 `status != archived` 的章节列表 - 提示词:prompts/ 下文件数量 **废弃清理(直接丢弃):** - `author-intent.md`、`current-focus.md` - `drafts/`、`drifts/`、`tmp/`、`temp-*.txt` - `manuscripts/`、`.vscode/` **作者确认后继续。** ### Step 2: 备份旧文件 ```bash mkdir -p old mv story.yaml settings/ volumes/ chapters/ archives/ prompts/ old/ rm -rf drafts/ drifts/ tmp/ manuscripts/ .vscode/ author-intent.md current-focus.md ``` ### Step 3: 初始化新骨架 ```bash python tools/init.py [project-path] [--genre <编号>] ``` `init.py` 创建目录结构 + 空模板 + agent 定义 + 记忆/知识库。后续迁移步骤负责填数据。 ### Step 4: 迁移设定(逐文件按 templates/migration/ 映射) 对照 `templates/migration/migration-spec.md` 的字段映射表,按优先级逐文件转换: | 优先级 | 旧文件 → 新文件 | 参考模板 | |--------|----------------|---------| | P0 | `old/settings/character-setting/*.yaml` → `settings/character-setting/*.md` | `templates/migration/character.md.template` | | P1 | `old/story.yaml` + `old/volumes/*.yaml` → `story.md` | `templates/migration/story.md.template` | | P2 | `old/volumes/*.yaml` → `volumes/volume-{N}.md` | `templates/migration/volume.md.template` | | P3 | `old/chapters/*.yaml`(archived)→ `chapters/vol-{N}-ch-{M}.md` | `templates/migration/chapter.md.template` | | P4 | `old/settings/world-setting.yaml` → `settings/world-setting.md` | `templates/migration/world-setting.md.template` | | P5 | `old/settings/writing-style.yaml` → `settings/writing-style.md` | `templates/migration/writing-style.md.template` | | P6 | `old/settings/anti-ai.yaml` → `settings/anti-ai.md` | `templates/migration/anti-ai.md.template` | | P7 | `old/settings/hooks.yaml` → `settings/foreshadowing.md` | `templates/migration/foreshadowing.md.template` | | P8 | 无旧源 → `settings/genre-setting.md` | `templates/migration/genre-setting.md.template` | 字段映射细节在 `templates/migration/migration-spec.md` 中有完整定义。 ### Step 5: 拷贝已归档正文 + 提示词 只拷贝已定稿的正文(非 `.draft.md`),提示词全部复制: ```bash # 正文:只拷定稿(跳过 draft) for f in old/archives/*.md; do [ -f "$f" ] || continue case "$f" in *.draft.md) ;; *) cp "$f" archives/ ;; esac done cp old/prompts/*.md prompts/ 2>/dev/null cp old/prompts/*.txt prompts/ 2>/dev/null ``` 正文不做任何修改。 ### Step 6: 验收 - [ ] story.md 存在,skill_version = 4.0 - [ ] settings/world-setting.md 存在且已填充 - [ ] settings/writing-style.md 存在且已填充 - [ ] settings/genre-setting.md 存在 - [ ] settings/anti-ai.md 存在 - [ ] settings/foreshadowing.md 存在 - [ ] settings/character-setting/ 角色数与旧版一致 - [ ] volumes/ 卷数与旧版一致 - [ ] chapters/ 所有 archived 章节已迁移 - [ ] archives/ 正文全部复制 - [ ] prompts/ 提示词全部复制 - [ ] 旧 .yaml 已移入 old/(无残留) - [ ] 废弃文件已清理 ### Step 7: 交接 novel-agent 评估补充 迁移完成后,调度 `@novel-agent`,由其执行: 1. **项目空间评估** — 扫描全部迁移后的文件,对照验收清单识别缺失项 2. **补充决策** — 判断缺失项该由哪个 agent 处理: - 设定缺失(世界观/角色/风格/题材等)→ 调度 updater(setting-update 模式) - 其他 → 直接向作者提问 3. **逐项引导补充** — 每次调度一个 agent 完成补充后,再评估下一项,直到项目就绪 4. **汇报就绪** — 全部就绪后向作者展示迁移+补充结果,进入写作循环。确认无误后,作者可手动删除 `old/` 目录。 ## 边界条件 | 场景 | 处理 | |------|------| | `story.yaml` 存在 → `story.md` 不存在 | 旧版 2.x → 执行自动迁移流程 | | `story.md` 存在但 `skill_version` < 4.0 | 待升级 → 执行自动迁移流程 | | `story.md` 存在且版本匹配 | 已有项目 → @novel-agent | | 两者都不存在 | 全新项目 → init.py → @novel-agent | | `init.py` 不可用 | 手动创建目录结构 + 复制 `templates/` 文件 | | 检测到未提交的 git 变更 | 提示作者先提交/stash | ## 项目目录结构 ``` {project-name}/ ├── story.md # ★ 项目索引 ├── settings/ │ ├── world-setting.md # 世界观 │ ├── writing-style.md # 写作风格 │ ├── genre-setting.md # 题材设定 │ └── character-setting/ │ └── .md # 每角色一个文件 ├── volumes/ │ └── volume-{N}.md # 卷纲 ├── chapters/ │ └── vol-{N}-ch-{M}.md # ★ 章纲(status: outline → draft → archived) ├── prompts/ │ └── vol-{N}-ch-{M}-prompt.md # 提示词 ├── sandbox/ │ └── vol-{N}-ch-{M}/ # 剧情推演记录(可选) ├── archives/ │ ├── *.draft.md # 草稿 │ └── *.md # 定稿 ├── .agent/ │ ├── status.md # 进度追踪 │ └── task/ # agent 间 order 文件 ├── .opencode/ │ └── agents/ # Agent 定义(OpenCode 用) └── .claude/ ├── agents/ # Agent 定义(Claude Code 用) ├── knowledge/ # 反 AI 规则、文风偏好、永久记忆、格式规范 └── memory/ # 写作动态记忆 ``` ## Agent 协作架构 ``` novel-agent(总指挥) ├─ 新项目 → 调度 volume-planner(规划卷纲) ├─ 卷纲就绪 → 调度 chapter-planner(生成章纲) ├─ 章纲就绪 → 调度 prompt-crafter(组装提示词) ├─ 提示词就绪 → 调度 writer(写正文) ├─ 正文就绪 → 可选调度 reader(深度评审) └─ 作者确认 → 调度 updater(归档 + lore-keeping) ``` 各 agent 定义在 `.opencode/agents/`(OpenCode)或 `.claude/agents/`(Claude Code),skill SOP 在 `skills/`。agent 间通过 `.agent/task/*-order.md` 文件通信。 **可选工具:** 剧情推演沙盘(`skills/roleplay-sandbox.md`)是独立的交互式工具,不在 agent 调度链中。作者卡剧情时主动调用,产出推演记录(`sandbox/`)供编写章纲时参考。 **调度规则:** novel-agent 是唯一调度者,只写 order 文件 + 调用子 agent。所有内容创作(卷纲/章纲/提示词/正文)、设定维护、归档更新均由子 agent 完成,novel-agent 不得越权代劳。子 agent 完成任务后清理 order 文件,novel-agent 检测到清理即确认完成。 **重要:novel-agent 是顶层入口,通过 `@novel-agent` 加载进主 agent,禁止通过 Agent 工具将 novel-agent 作为 subagent 调度。** 主 agent 加载 novel-agent 定义后即扮演总指挥角色,拥有完整的 Agent 工具权限来调度子 agent。如果 novel-agent 被作为 subagent 派出,它将失去 Agent 工具调用能力,导致调度链断裂。 ## 工具契约 | 工具 | 用途 | 谁用 | |------|------|------| | **Bash** | 执行 init.py;迁移备份/拷贝命令;版本检测 | skill 入口(非 agent) | | **Read** | 检测项目文件、读取设定/状态 | 所有 agent | | **Write** | 写 order 文件(novel-agent);写设定/记忆/知识(子 agent) | 各 agent 按权限 | | **Agent** | novel-agent 调用子 agent | novel-agent 专用 | | **Edit** | 写 settings/、.claude/ 下的内容文件 | 子 agent(非 novel-agent) | | **Glob** | 扫描文件 | 所有 agent | | **Grep** | 搜索内容 | 所有 agent |