story-setup: Infrastructure Deployment for Web Novel Writing Toolset
You are the writing infrastructure deployer. Deploy the web novel writing toolset to the user's project directory: Adapted CLIs use dedicated hooks/agents/config; environments like NarraFork, Web AI, and custom Agents use the general file mode.
Iron Rule of Execution: Do not overwrite existing user configurations, merge instead of replacing.
Phase 1: Detect Project Status
First self-check reference directory: Based on the directory where this executing
is located, list the subdirectories under the sibling
, and verify that all 8 names below exist
and are non-empty —
,
,
,
,
,
,
,
; the sibling
scripts/merge-claude-settings.py
,
scripts/merge-codex-hooks.py
and
scripts/copy-path-safety.py
must also exist (they are dependencies for merging Claude/Codex hooks and recursive copy safety checks). If any are missing, the skill package is not fully installed,
stop immediately without writing any deployment files, distinguish between "missing directory", "empty directory" and "missing script" in the report, and provide repair instructions: "The story-setup reference package is incomplete, missing {path}. Reinstall oh-story-claudecode according to your installation method (run
npx skills add zenstory-ai/oh-story-claudecode -y -g
again if installed via command line, reinstall via the panel if installed via marketplace / Plugin Management), then execute /story-setup."
The criterion is "whether
exists": Only check the
at the same level as the executing
. The project's
.claude/skills/story-setup/
,
.codex/skills/story-setup/
and OpenCode's
only have
references/agent-references/
and do not contain
, so they will not be the execution directory, and do not use them for verification. The project copies of ZCode / OpenClaw / Reasonix / generic are full skill copies with their own
, and the 8 subdirectories are complete, so verify as usual.
-
Check if the current directory has been deployed (
exists)
- is missing, non-integer or less than → Mark as pending update, continue with current deployment
- → Use AskUserQuestion to confirm whether to redeploy; clearly state in the prompt that redeployment only refreshes project files using the current local skill package, to get a new version of the skill itself, you need to update oh-story-claudecode first (via or marketplace), then run /story-setup again
- is greater than → The current story-setup is older than the project deployment; stop to avoid downgrade overwriting, prompt to update oh-story-claudecode first, do not write any deployment files
- At the same time, read the field. For deployed projects, follow the value in the sentinel: When non-empty (multi-end combination separated by commas is retained as-is), skip steps 5-12 below for environment detection and selection, and redeploy directly according to these ends. Only when the field is missing or empty, fall back to detection. When the user explicitly requests to add or remove target ends, use AskUserQuestion to modify based on the existing value, and write the modified value back to the sentinel.
-
Check if there is a book title directory (a directory containing a
subdirectory, or a user-defined structure)
- Exists → Identify as a long-form project, display current project information
- Does not exist → Identify as a new project or short-form project
-
Check if
.claude/settings.local.json
exists
- Exists → Read existing configuration, merge later
- Does not exist → Create a new file later
-
- Exists → Display current active book title
- Does not exist → Skip
-
- Exists → Identify as an opencode project,
- Does not exist → Skip
-
Check
,
,
,
, Codex section in
- Exists → Identify as a Codex project,
- Does not exist → Skip
-
Check
,
,
,
,
, ZCode section in
- Exists → Identify as a ZCode project,
- Does not exist → Skip
-
Check
,
, or OpenClaw section in
(title line contains "网文写作工具集(OpenClaw)")
- Exists → Identify as an OpenClaw project,
- Does not exist → Skip
-
Check
,
,
, or Reasonix section in
(title line contains "网文写作工具集(Reasonix)")
- Exists → Identify as a Reasonix project,
- Does not exist → Skip
-
Check the general section in
(title line contains "网文写作工具集(通用 Agent / Web AI)")
- Exists → Identify as a general Web AI project,
- Does not exist → Skip
Steps 8-10 only recognize
mutually exclusive markers for each end.
in
is not used as an OpenClaw signal: All 13 skills have this field, and the
deployed by the three skills-only paths of OpenClaw / Reasonix / generic look the same, so using it to judge will misidentify the latter two as OpenClaw.
is also shared by Codex and Reasonix, so it is not used alone. The real distinguishing point for the three ends is the title line of their respective
templates.
-
If
or
, OpenCode, Codex, ZCode, OpenClaw, Reasonix, and generic markers exist at the same time → Use AskUserQuestion to let the user select the target environment (options: Claude Code / OpenCode / Codex / ZCode / OpenClaw / Reasonix / General Web AI or other Agent / Any combination)
-
If none of the seven types of markers exist (brand new project) → Use AskUserQuestion to let the user select the target environment
- User selects opencode → , create and during deployment
- User selects claude-code → Process according to existing logic
- User selects codex → , create during deployment
- User selects zcode → , merge root during deployment, do not create project custom agents
- User selects openclaw → , copy OpenClaw-compatible skills to project during deployment
- User selects reasonix → , copy skills to project and write Reasonix version during deployment, do not create project custom agents/hooks
- User selects General Web AI / other Agent → , deploy general and project local ; do not write platform-specific hooks/agents
- User selects multiple ends →
target_cli = subset of claude-code,opencode,codex,zcode,openclaw,reasonix,generic
(only includes the ends selected by the user)
Phase 2: Deploy Infrastructure
Use AskUserQuestion to confirm the deployment location, then execute in sequence.
The entire Phase 2 is idempotent: The results of directory copying, file writing, and each merge algorithm in the table below are consistent when executed repeatedly. If it fails halfway due to environmental reasons (unavailable tools, permission denied, network failure), restart this Phase directly from the beginning without cleaning up semi-finished products first; user status files marked as
(see Owner class in the table below) will not be overwritten for the second time.
The two columns have different base directories:
is relative to the executing skill package,
is relative to the user's project root. Before executing each line (and each recursive copy step in the deployment algorithms of each end below), first convert wildcards into specific source/target paths, then use
scripts/copy-path-safety.py
at the same level as this
to check. This script follows existing symlinks according to
/
semantics, and uses
to verify filesystem objects when both sides exist;
just converting to absolute paths or comparing strings does not count as completing the check. Read its JSON: When
, no-op, copying is prohibited; only when
can copying be performed; if
,
unsafe_target_within_source
or
filesystem_identity_error
occurs, this step must be stopped and reported. If the script cannot be run, only use the filesystem API of the current environment to perform the same canonical realpath, same-object and target-descendant checks; if it cannot be confirmed, stop and do not attempt to copy. The project copies of OpenClaw / Reasonix / generic are full skill copies, and the one executed during rerunning is the one in the project; Reasonix / Codex may also be loaded via
.agents/skills → ../skills
symlink, and different path texts may point to the same directory, so copying literally will embed the directory into itself and fill up the disk.
Clean up self-nested residues before deployment: If there is an extra
layer (possibly multiple nested layers) in
{.claude,.codex,.zcode}/skills/story-setup/references/agent-references/
and the project root
skills/story-setup/references/agent-references/
, as well as
skills/story-setup/skills/
, delete the entire segment before deployment, and list the deleted paths in the installation report.
Step 1: Deployment Checklist (Mechanically Verifiable)
| Source path | Target path | Owner class | Merge mode | Validation check |
|---|
skills/story-setup/references/templates/CLAUDE.md.tmpl
| | user+managed | marker/section merge | contains story skill routing sections |
skills/story-setup/references/templates/hooks/
| | story-setup managed | recursive replace | , , , guard-outline-before-prose.sh
, check-prose-after-write.sh
, , , , exist; has identical bytes with OpenCode/ZCode copies |
skills/story-setup/references/templates/rules/*.md
| | story-setup managed | replace | every rule contains frontmatter |
skills/story-setup/references/templates/agents/*.md
| | story-setup managed | replace | 7 agent files exist |
skills/story-setup/references/agent-references/*.md
| .claude/skills/story-setup/references/agent-references/*.md
| story-setup managed | replace | every story-setup/references/agent-references/*.md
reference resolves |
skills/story-setup/references/templates/settings-hooks.json
| .claude/settings.local.json
| user+managed | replace managed registrations by stable hook identity | hook JSON valid;old matcher registrations have been migrated, each current template command exists once, user hooks are retained |
skills/story-setup/scripts/merge-claude-settings.py
| Executed during deployment, not copied to project | story-setup helper | execute | replaces known story hook registrations, retains user hooks/top-level fields, v24→v25 migration and repeated execution are idempotent |
skills/story-setup/scripts/copy-path-safety.py
| Executed before each recursive copy step, not copied to project-specific directory | story-setup helper | execute | JSON allows copying only when ; symlink to same object is no-op; stop when target is within source |
| generated sentinel | | story-setup managed | replace | contains , , , , |
skills/story-setup/references/opencode/AGENTS.md.tmpl
| | user+managed | marker/section merge | contains story skill routing sections |
skills/story-setup/references/opencode/agents/
| | story-setup managed | replace | 7 agent files exist (before replace, cache existing according to "Retain existing model configuration" in "Configure OpenCode Agent Model" to avoid overwriting user-configured models) |
skills/story-setup/references/opencode/plugin.ts
| .opencode/plugins/story-hooks.ts
| story-setup managed | replace | TypeScript plugin file exists |
skills/story-setup/references/opencode/story_hook_core.js
| .opencode/plugins/lib/story_hook_core.js
| story-setup managed | replace | Node syntax valid;has identical bytes with ZCode copies;imported by story-hooks.ts |
skills/story-setup/references/opencode/commands/
| | story-setup managed | replace | 13 command files exist |
skills/story-setup/references/opencode/opencode.json.patch
| merge into | user+managed | merge by plugin/permission key | plugin entry registered |
repository skills/story-setup/references/agent-references/
| skills/story-setup/references/agent-references/
| story-setup managed | replace | every reference resolves |
skills/story-setup/references/opencode/pre-commit.sh
| | user+managed | append or create | file exists and is executable;if marker block exists, replace block content, if not, intelligently insert by detecting exit 0 position |
skills/story-setup/references/codex/AGENTS.md.tmpl
| | user+managed | marker/section merge | contains Codex story skill routing sections |
skills/story-setup/references/codex/agents/
| | story-setup managed | replace | 7 TOML agent files parse and contain // |
skills/story-setup/references/codex/hooks/hooks.json
| | user+managed | replace managed registrations by stable hook identity | hook JSON valid; all stale direct/launcher registrations removed, current 6 registrations present exactly once |
skills/story-setup/references/codex/hooks/{story_codex_hook.py,run-story-hook.sh,run-story-hook.cmd}
| Same-named files in | story-setup managed | replace | Python/shell/cmd launcher files are complete |
skills/story-setup/scripts/merge-codex-hooks.py
| Executed during deployment, not copied to project | story-setup helper | execute | replaces known managed registrations, retains user hooks and unknown top-level fields, results are idempotent |
skills/story-setup/references/agent-references/
| .codex/skills/story-setup/references/agent-references/
| story-setup managed | replace | every reference resolves |
skills/story-setup/references/zcode/AGENTS.md.tmpl
| | user+managed | marker/section merge | contains ZCode routing and solo fallback |
repository skills/{browser-cdp,story*}/
| .zcode/skills/{browser-cdp,story*}/
| story-setup managed for known skill names | replace known skill dirs only | 13 files exist and satisfy ZCode frontmatter limits |
skills/story-setup/references/zcode/commands/
| | story-setup managed for known command names | replace known command files only | 13 commands have valid names/frontmatter |
skills/story-setup/references/zcode/hooks/story_zcode_hook.js
| .zcode/hooks/story_zcode_hook.js
| story-setup managed | replace | Node syntax valid; hook contract tests pass |
skills/story-setup/references/zcode/hooks/story_hook_core.js
| .zcode/hooks/story_hook_core.js
| story-setup managed | replace | Node syntax valid; hook contract tests pass |
skills/story-setup/references/zcode/config.json.patch
| merge into | user+managed | merge by event+matcher+process args | JSON valid; verify according to hooks mutually exclusive branch in "ZCode Deployment Algorithm" Step 4 — when oh-story plugin is not installed, 、only supported events; when plugin is installed, verify that does not contain (or has removed) these oh-story hook registrations |
skills/story-setup/references/openclaw/AGENTS.md.tmpl
| | user+managed | marker/section merge | contains OpenClaw story skill routing sections |
skills/story-setup/references/generic/AGENTS.md.tmpl
| | user+managed | marker/section merge | contains generic story skill routing sections |
skills/story-setup/references/reasonix/AGENTS.md.tmpl
| | user+managed | marker/section merge | contains Reasonix story skill routing sections and solo/direct fallback |
repository skills/{browser-cdp,story*}/
| skills/{browser-cdp,story*}/
| story-setup managed for known skill names | replace known skill dirs only | 13 files exist; OpenClaw-compatible frontmatter |
repository skills/story-setup/references/agent-references/
| Landed with the full skill copy in the previous line, no-op for this line | story-setup managed | No separate copy | every reference resolves |
opencode.json Merge Algorithm
When deploying
, merge according to the following rules:
- Read the existing (if exists), parse JSON
- Merge the array: Add
./.opencode/plugins/story-hooks.ts
to the array and deduplicate
- Retain other existing configuration fields of the user (such as , , ), do not overwrite
- Write the merged
Step 2: Deploy CLAUDE.md
- Read
skills/story-setup/references/templates/CLAUDE.md.tmpl
- Replace placeholders (see "Template Placeholders" section below)
- Write to project root directory (if it already exists, process according to "CLAUDE.md Merge Strategy")
Step 3: Deploy Hooks
- Recursively copy the complete directory tree: Copy
skills/story-setup/references/templates/hooks/
to the user's project
- Must retain the subdirectory , where:
- provides , ,
- provides field reading
- Only need to set execution permissions () for ; is sourced by hooks, no need for executable bits
Step 4: Deploy Rules
- Read all files under
skills/story-setup/references/templates/rules/
- Copy to the directory of the user's project
Step 5: Deploy Agents
- Read all files under
skills/story-setup/references/templates/agents/
- Copy to the directory of the user's project
- Agent files are managed by story-setup and can be safely overwritten; redeploy according to the version detection results in during version upgrade
- When contains opencode, execute Step 1 of "Configure OpenCode Agent Model" to cache existing before overwriting . This step is written later in this section, but must be run first — if you follow the order and overwrite first then cache, the user's configured model will be lost.
- Must start a new session after deployment: Agents are only registered when the session starts; the reason and the report copy that must be output are in "Output Installation Report" in "Verify Installation".
Agent Compatibility Handling
- Agent frontmatter is mainly based on Claude Code; OpenCode's and Codex's are directly copied from pre-generated products under
references/opencode/agents/
and , which are the only sources for deployment. The pre-generated products are maintained by and scripts/generate-codex-agents.py
at the root of the oh-story-claudecode repository; these two scripts are repository maintenance tools, not distributed with story-setup, and do not need to be called during deployment.
- ZCode 3.3.4 does not deploy project agents: Its custom sub-agents only support user-level , and the in the plugin manifest is not currently executed. Do not create or modify the user's home; related Skills must directly use solo/direct and report fallback.
- OpenClaw Phase 1 does not deploy agents: OpenClaw only deploys skills, and skills related to agent collaboration must be downgraded to solo/direct according to existing fallback rules, do not directly copy Claude/OpenCode agent frontmatter as OpenClaw agents.
- After deployment to the project, the reference materials referenced in the agent must use the intra-skill copy path
story-setup/references/agent-references/*.md
; do not reference references from other skills across skills. Each adapter only uses the current specification prefix: Claude Code uses , OpenCode / OpenClaw / Reasonix / generic use , Codex uses , ZCode uses ; does not traverse historical alternative paths at runtime.
Deploy Agent References
- Copy all files under
skills/story-setup/references/agent-references/
to .claude/skills/story-setup/references/agent-references/
in the project
- Verification: For every occurrence of
story-setup/references/agent-references/<file>.md
in agents or references, must exist in both the source package and the target package
Deploy Codex Agents (when target_cli contains codex)
- Read all files under
skills/story-setup/references/codex/agents/
, copy to the user's project
- Agent files are managed by story-setup and can be safely overwritten; the TOML in is deterministically generated from Claude agent templates by
scripts/generate-codex-agents.py
at the root of the repository and committed to the repository, deployment only does copying
- Verify that each TOML can be parsed and contains Codex required fields: , ,
- Read-only responsibility agents (, , ) must retain
sandbox_mode = "read-only"
- Must trust + start a new Codex session after deployment (report copy and fallback rules are in "Verify Codex Deployment"); if is returned at runtime, the caller must downgrade to solo/direct and report fallback.
- Synchronously copy
skills/story-setup/references/agent-references/
to .codex/skills/story-setup/references/agent-references/
as the main path for intra-project reference materials of Codex agents
Configure OpenCode Agent Model
Only execute when
contains
. When OpenCode sub-agents do not specify a model, they inherit the main model, resulting in low-cost Agents also consuming main model quotas. This step automatically detects the user's model and writes the
field.
Step 1: Retain Existing Model Configuration (must be executed before replacing )
OpenCode agent deployment uses
, which will overwrite the previously written
. Therefore, before executing this replace, first scan the existing
and cache the
of each agent (agent name → model ID). If detection fails/timeout later, or the user skips a certain level, use the cached value to fill in, avoiding overwriting the user's previously configured low-cost model with the main model. If replace has already occurred and the cache is empty, process it as a new deployment, and prompt "Failed to retain previous model configuration" in the installation report.
Step 2: Get Model List
优先执行
opencode models --verbose
,它输出含 cost(input/output/cache 单价)、context、capabilities 的 metadata;不可用或解析失败时回退到
纯文本(每行
)。两者都用 60000ms(60 秒)超时,因为首次运行需加载 models.dev 缓存。
- Success → Enter "Model Classification"
- Timeout → Retry once (cache may not be preheated); if still timeout, fill in the existing with the cache from "Retain Existing Model Configuration", skip automatic configuration, and output manual configuration guide in the installation report
- Failure (command does not exist, output is empty, etc.) → Same as above: Fill in the cache from "Retain Existing Model Configuration", skip automatic configuration, output manual configuration guide
Step 3: Model Classification
Prioritize classification by cost (when is available): Grade each model from lowest to highest cost — low-end takes the cheapest/free tier, mid-end takes the mid-priced tier, high-end takes the most expensive or the one with the strongest context/capabilities. Free models are classified as low-end with real cost=0,
do not rely on marketing words in the name (e.g.,
contains
in the name but cost=0, should be classified as low-end). Models without cost data are also included in candidates and not discarded.
Fallback to classification by keywords (when no or no cost): Split the model name after the last
in the model ID into segments by
,
,
, and match keywords exactly segment by segment (case-insensitive). For example,
is split into
, does not match
or
;
is split into
, matches
. Keyword classification is heuristic, mark "Classification basis: keywords (heuristic)" in the installation report.
| Grade | Matching Keywords | Corresponding Agents |
|---|
| Low-end | , , , , | chapter-extractor, consistency-checker, story-explorer |
| Mid-end | , | story-researcher, narrative-writer, character-designer |
| High-end | , , , | story-architect |
- A model may match keywords of multiple grades, take the highest grade
- Models that do not match any keywords in keyword fallback are still included in candidate additional suggestions (all are included in cost classification), and listed in the installation report, prompting "Can be used via custom input"
- Within the same grade, if multiple model providers are included, prioritize models from well-known providers (anthropic, openai, google, deepseek)
Step 4: Step-by-Step Interactive Selection
In the order of low-end → mid-end → high-end, use AskUserQuestion to let the user select at each level.
Low-end option structure:
Question: "Select model for low-cost Agents (chapter-extractor, consistency-checker, story-explorer):"
Options:
- provider/model-id
- provider/model-id
- Custom input (manually enter full model ID, ID spelling errors will only be exposed at runtime)
- Skip, use main model (cost may be higher)
Mid-end option structure:
Question: "Select model for writing quality-critical Agents (narrative-writer, character-designer, story-researcher):"
Options:
- provider/model-id
- provider/model-id
- Custom input (do not use low-end models, which will affect text quality; ID spelling errors will only be exposed at runtime)
- Skip, use main model (main model quality is usually sufficient)
High-end option structure:
Question: "Select model for command Agent (story-architect):"
Options:
- provider/model-id
- provider/model-id
- Custom input (manually enter full model ID, ID spelling errors will only be exposed at runtime)
- Skip, use main model (cost may be higher)
Rules:
- Display up to 5 candidates, truncate if more than 5 and prompt "For more models, use custom input". Pop up AskUserQuestion at each level regardless of whether the number of candidates is 0, options must include: candidate models (if any), , (the model of this agent cached in "Retain Existing Model Configuration", do not display this item if none), . When candidates are 0, still pop up the window, and give a corresponding warning in the question description + list unclassified/ungraded models for reference — do not silently skip interaction (otherwise the user cannot access custom input).
- : User enters full ; verify it is a single line, no control characters, matches
^[A-Za-z0-9._-]+/[A-Za-z0-9._:+-]+$
before writing, if not, prompt to re-enter or choose to skip.
- : Write back the model of this agent cached in "Retain Existing Model Configuration" (preserve the user's previous configuration during redeployment), not counted as "skip".
- : Explicitly clear — do not write the field for this agent, the agent inherits the main model. To retain previous configuration, select .
- When candidates are 0 at each level, give prompts in the question description:
- Low-end: "No low-cost models detected, these 3 agents will use the main model, cost may be higher"
- Mid-end: "No matching mid-end models detected. narrative-writer, character-designer, story-researcher will use the main model. This configuration is reasonable if the main model quality is sufficient; if cost reduction is needed, specify a mid-end model not lower than the main model quality via custom input, or select from the ungraded models below."
- High-end: "No high-end models detected, story-architect will use the main model"
Step 5: Write model Field
For the agent files corresponding to the user's selection (
, which have been deployed by the OpenCode agents deployment step in the deployment checklist before this step), insert
as a
top-level field with zero indentation at the end of the frontmatter, before the closing
(do not insert into the indentation block of multi-line maps such as
). Add quotes if the value contains YAML special characters to ensure the frontmatter is not damaged:
yaml
---
description: ...
mode: subagent
permission:
read: allow
edit: deny
steps: 12
model: provider/model-id
---
- If the agent file already has a field (redeployment scenario), replace the value of this top-level , do not add duplicate keys
- : Write back the model of this agent cached in "Retain Existing Model Configuration"
- : Do not write the field
- For levels that failed/timeout and did not reach this step: Fill in with the cache from "Retain Existing Model Configuration", avoiding overwriting the user's previous configuration due to replace
Step 6: Merge Hook Registrations to settings.local.json
- Detect Python according to existing cross-platform rules:
for PYBIN in python3 python py; do "$PYBIN" -c "" 2>/dev/null && break; done
; stop if no available interpreter, do not manually write or simplify merging.
- Call
"$PYBIN" "{story-setup skill directory}/scripts/merge-claude-settings.py" --existing "{project}/.claude/settings.local.json" --template "{story-setup skill directory}/references/templates/settings-hooks.json" --output "{project}/.claude/settings.local.json"
.
- The helper will remove all historical registrations of known story-setup hooks, then append the current template; therefore, matcher/timeout/if can be upgraded with the version, while user hooks and unknown top-level fields mixed in the old block are retained as-is. Parse JSON after writing, verify that each template command exists once, user configuration is still present, then re-run the helper to compare file bytes to confirm idempotency.
Codex hooks.json Merge Algorithm (when target_cli contains codex)
Codex project hooks are deployed to
; run scripts to deploy to
.codex/hooks/story_codex_hook.py
,
,
. JSON is only responsible for locating the project root and passing events, interpreter detection is uniformly handled by the platform launcher.
- Locate the current story-setup skill directory, read
references/codex/hooks/hooks.json
as the only current template, read the project's (treat as empty object if it does not exist).
- Detect available Python according to existing cross-platform rules:
for PYBIN in python3 python py; do "$PYBIN" -c "" 2>/dev/null && break; done
; stop if no available interpreter, do not manually write or simplify JSON merging.
- Call
"$PYBIN" "{story-setup skill directory}/scripts/merge-codex-hooks.py" --existing "{project}/.codex/hooks.json" --template "{story-setup skill directory}/references/codex/hooks/hooks.json" --output "{project}/.codex/hooks.json"
. This helper will identify three types of managed identities: old direct call , current and , first remove all known managed registrations, then append the current template.
- Retain non-story-setup hooks, matcher blocks and unknown top-level fields already present in the user's configuration. Repeated execution must be idempotent;禁止再按原始 字符串追加去重,否则 v17 直调命令会与 v18 launcher 双重注册。
- Parse JSON after writing to verify: The number of old direct call commands is 0, each of the 6 current template registrations exists exactly once, user hooks and unknown top-level fields are still present. Then prompt the user: The project's layer needs to be trusted by Codex, non-managed command hooks also need to be reviewed/trusted in before running; on Windows, use , the launcher locates the project's from the current directory upwards, consistent with the nested directory behavior of POSIX paths.
ZCode Deployment Algorithm (when target_cli contains zcode)
The first version of ZCode deploys Skills, Commands, AGENTS.md and Hooks within supported events; does not deploy
or
.
- Copy the 13 directories containing under the current repository's to
.zcode/skills/{skill-name}/
; only replace these known directories, retain other Skills of the user.
- Copy
references/zcode/commands/*.md
to ; only replace 13 commands with the same name, retain other Commands of the user.
- Copy
references/zcode/hooks/story_zcode_hook.js
and references/zcode/hooks/story_hook_core.js
to .
- Read
references/zcode/config.json.patch
and the existing (if only the root exists, still create to carry oh-story project Hooks, do not modify the root file):
- Retain all unknown fields, MCP, plugins, skills/commands disable overrides of the user;
- Hooks mutual exclusion (avoid double triggering): If this project runs via the installed oh-story plugin (marketplace installation, in
.zcode-plugin/plugin.json
at the repository root has globally registered SessionStart/PreToolUse/PostToolUse), then skip merging the block of into below — the plugin manifest has already registered these hooks, merging again will cause the same event to run twice (PreToolUse intercepted twice, PostToolUse injected twice). Only merge hooks when the plugin is not installed (directly cloned / manually imported references). When uncertain, take "Whether ZCode has registered this set of hooks via this plugin" as the criterion; non-hook fields of skills/commands/hook files/AGENTS and config are deployed as usual via both paths.
- Merge hooks (only when plugin is not installed): Set ; retain if the user already has a larger , otherwise take the template value; deduplicate and append SessionStart, PreToolUse, PostToolUse in by
event + matcher + process command + args
; do not copy PreCompact, PostCompact, SessionEnd, SubagentStop, Notification which are not supported by ZCode.
- Write the root according to "AGENTS.md Merge Strategy" using
references/zcode/AGENTS.md.tmpl
.
- Write or multi-end combination to in , write
.zcode/skills/story-setup/references/agent-references
to .
- The installation report must clearly state: ZCode 3.3.4 does not execute project/plugin custom agents, full/lean multi-Agent requests will be stably downgraded to solo/direct; the system requires an available command to run project Hooks.
Plugin installation does not go through this algorithm:
.zcode-plugin/plugin.json
at the repository root directly exposes the same set of Skills/Commands/Hooks. Plugin Skills have lower priority than workspace
; if both exist, the project snapshot takes precedence, and upgrading the project snapshot requires re-running
.
Only one set of Hooks can be registered: The plugin manifest and workspace
register the same set of events, do not merge the hooks of
into
when the plugin is installed (see hooks mutual exclusion in Step 4 of the above algorithm), otherwise PreToolUse/PostToolUse will be triggered twice; when the plugin is present, the plugin manifest is the only registration source for hooks.
OpenClaw skills-only Deployment Algorithm (when target_cli contains openclaw)
OpenClaw Phase 1 only deploys skills, does not deploy OpenClaw agents/hooks/plugin.
- Read all story skill directories containing under the current repository's (13: and ).
- Write to the target project's , only replace these story-setup managed known skill directories; retain other directories of the user under .
- Each must meet OpenClaw frontmatter constraints: / are single-line key-value pairs, is a single-line JSON object and contains .
- Copy
skills/story-setup/references/openclaw/AGENTS.md.tmpl
to the project's , merge according to "AGENTS.md Merge Strategy".
- Write or multi-end combination to in ; write
skills/story-setup/references/agent-references
to for OpenClaw.
- Prompt items in the installation report are in Step 10 of Phase 3.
Reasonix skills-only Deployment Algorithm (when target_cli contains reasonix)
Reasonix (DeepSeek-Reasonix CLI) currently only deploys skills and
, does not deploy Reasonix hooks/custom agents (hook I/O contract and sub-agent behavior lack verifiable real CLI, to be added in subsequent phases).
- Read all story skill directories containing under the current repository's (13: and ) to the target project's ; only replace these story-setup managed known skill directories, retain other directories of the user.
- Create a relative symlink
.agents/skills → ../skills
in the project root (shared with Codex's skill root), so that Reasonix can discover these skills when natively scanning ; if it is already a symlink pointing to , retain it, if it is occupied as a normal directory, do not overwrite and prompt in the installation report. Skip this step when symlink is not enabled on Windows, instead use the root for .
- Copy
skills/story-setup/references/reasonix/AGENTS.md.tmpl
to the project's , merge according to "AGENTS.md Merge Strategy".
- Write or multi-end combination to in ; write
skills/story-setup/references/agent-references
to for Reasonix.
- Prompt items in the installation report are in Step 12 of Phase 3.
General Web AI / Other Agent Deployment Algorithm (when target_cli contains generic)
The general path is for environments that can read project files such as NarraFork, Web AI, custom Agents, only deploys general files, does not declare platform-native hooks/agents capabilities.
- Copy all story skill directories containing under the current repository's (13: and ) to the target project's ; only replace these story-setup managed known skill directories, retain other directories of the user.
- Copy
skills/story-setup/references/generic/AGENTS.md.tmpl
to the project's , merge according to "AGENTS.md Merge Strategy".
- Write or multi-end combination to in ; write
skills/story-setup/references/agent-references
to for generic.
- Prompt items in the installation report are in Step 11 of Phase 3.
Step 7: Create Deployment Marker
- Create file (sentinel file)
- Write the following fields (YAML format, read by
references/templates/hooks/lib/sentinel.sh
in hooks):
deployed_at: <date -u +"%Y-%m-%dT%H:%M:%SZ">
agents_version: 25
setup_skill_version: 1.2.7
target_cli: claude-code (or opencode, codex, zcode, openclaw, reasonix, generic, or any combination thereof)
resolver_strategy: project-local-skill-reference
references_dir: .claude/skills/story-setup/references/agent-references (Codex writes .codex/skills/...; ZCode writes .zcode/skills/...; OpenClaw / Reasonix / generic write skills/...; multi-end uses comma separation)
- This file is used by session-start.sh and writing skills to detect deployment status and avoid repeated prompts
- When target_cli contains claude-code, also create a one-time marker file
.claude/.agents-pending-restart
(empty file is sufficient). session-start.sh will confirm that agents have been registered with the new session when the next session starts, and automatically delete this marker — used to confirm "restart has taken effect" to the user. ZCode does not create this marker because it does not deploy project agents.
- If exists but is missing, non-integer or less than , update hooks/agents/rules/reference bundle according to this process (specific changes see ); if greater than , stop in Phase 1 and do not downgrade overwrite
Phase 3: Verify Installation
- Verify hook registration:
- Check if the hooks field in
.claude/settings.local.json
is correct
- Check if the scripts under exist and have execution permissions
- Check if
.claude/hooks/lib/common.sh
and .claude/hooks/lib/sentinel.sh
exist
- Verify rules path:
- Check if the rule files under exist and contain frontmatter
- Verify agents:
- Check if the 7 agent definition files under exist
- Verify agent reference bundle:
- Check if the reference files under
.claude/skills/story-setup/references/agent-references/
are complete
- Check that all
story-setup/references/agent-references/<file>.md
can resolve to the deployed bundle
- Verify deployment marker:
- Check if exists and contains timestamp, ,
setup_skill_version: 1.2.7
, , ,
- Output installation report:
- List all deployed files
- List matters needing attention (such as existing configurations have been merged)
- ⚠️ Restart Prompt (must be output prominently): This deployment wrote to , but these custom agents are only registered as by Claude Code when the "session starts".Please start a new Claude Code session before writing, otherwise when story-review / story-long-write etc. try to spawn , etc. in the current session, they will get "subagent_type unavailable" and downgrade to solo (single perspective, losing multi-agent collaboration). To judge whether it takes effect: Run in the new session, if the report header is
Effective Mode: full/lean
, registration is successful; if it is , it means you are still in the old session or not registered.
- You can use or after restart
- If "Configure OpenCode Agent Model" was executed, output Agent model configuration summary:
Agent Model Configuration:
story-architect → <high-end model> (provider/model-id)
narrative-writer → <mid-end model> (provider/model-id)
character-designer → <mid-end model> (provider/model-id)
story-researcher → <mid-end model> (provider/model-id)
chapter-extractor → <low-end model> (provider/model-id)
consistency-checker → <low-end model> (provider/model-id)
story-explorer → <low-end model> (provider/model-id)
- If automatic detection fails ( is unavailable), output manual configuration guide:
Unable to automatically detect model list. The following Agents are not configured with models and will use the main model, cost may be higher:
- chapter-extractor (recommended to use low-cost model)
- consistency-checker (recommended to use low-cost model)
- story-explorer (recommended to use low-cost model)
Manual configuration method: Edit .opencode/agents/{agent-name}.md, add to frontmatter:
model: provider/model-id
Available model list and cost can be viewed via opencode models --verbose (output includes cost/context per model).
Model library and pricing see OpenCode official model source https://models.dev/.
- Verify opencode deployment (only when target_cli contains opencode):
- Check if the 7 agent definition files under exist, and the frontmatter contains and fields
- Check if
.opencode/plugins/story-hooks.ts
exists
- Check if
.opencode/plugins/lib/story_hook_core.js
exists and passes (imported by story-hooks.ts, shared prose guard core with identical bytes to copy; placed in subdirectory to avoid OpenCode's automatic discovery of single-layer plugins)
- Check if the 13 command files under exist
- Check if the reference files under
skills/story-setup/references/agent-references/
are complete and the quantity is the same as the source directory
- Check if the array in contains the story-hooks entry
- Check if exists and has execution permissions (skip execution permission check on Windows)
- Check if the frontmatter of agent files under can be parsed by YAML, and (if configured) is a valid top-level scalar, not just grep for substring
- Verify Codex deployment (only when target_cli contains codex):
- Check if contains Codex story skill routing sections
- Check if 7 agent definition files under exist and can be parsed
- Check if exists and is JSON valid, Unix is only started via , Windows is only started via ; no registration of direct call exists
- Check if
.codex/hooks/story_codex_hook.py
, , exist, Python syntax is valid, POSIX/Windows launcher can locate project root from nested cwd
- Check if the reference files under
.codex/skills/story-setup/references/agent-references/
are complete and the quantity is the same as the source directory
- The installation report must prompt: Codex needs to trust the project's configuration layer, and review/trust non-managed hooks in ; start a new Codex session after deployment to make custom agents take effect; if the current runtime still returns , downgrade to solo/direct according to the fallback rules of each skill
- Verify ZCode deployment (only when target_cli contains zcode):
- Check if the root contains ZCode routing, outline guard and solo/direct fallback
- Check 13 Skills under and 13 Commands under , verify frontmatter and naming
- Check if
.zcode/hooks/story_zcode_hook.js
, .zcode/hooks/story_hook_core.js
exist and pass
- Check if is JSON valid, and verify according to hooks mutual exclusion branch in Step 4 of "ZCode Deployment Algorithm": When oh-story plugin is not installed, , only register ZCode supported events, all args point to project Hook; when oh-story plugin is installed (
.zcode-plugin/plugin.json
has globally registered these hooks), instead verify that does not contain (or has removed) these oh-story hook registrations —do not merge the hooks block of back to make verification pass, otherwise the same event will be triggered twice
- Check if
.zcode/skills/story-setup/references/agent-references/
is complete and all reference paths can be resolved
- Call SessionStart, PreToolUse deny/allow, PostToolUse with fixture, confirm stdout is empty when no discovery, and conforms to ZCode strict JSON when there is output
- The installation report must prompt: ZCode 3.3.4 does not execute project/plugin custom agents, full/lean multi-Agent requests will be stably downgraded to solo/direct; Hook depends on in PATH; start a new ZCode session after deployment to refresh Skills/Commands/AGENTS.md
- Verify OpenClaw deployment (only when target_cli contains openclaw):
- Check if contains OpenClaw story skill routing sections
- Check if 13 story skill directories under exist, and each contains single-line , single-line , single-line JSON
- Check if the reference files under
skills/story-setup/references/agent-references/
are complete and the quantity is the same as the source directory
- The installation report must prompt: OpenClaw Phase 1 is skills-only; OpenClaw agents/hooks are not deployed, runtime hard interception is unavailable, outline guard before writing prose, commit reminder, session/compact automatic injection only serve as soft constraints within skills; OpenClaw snapshots eligible skills when the session starts, if commands/skills do not appear after deployment, start a new OpenClaw session or wait for skills watcher to refresh
- Verify General Web AI / Other Agent deployment (only when target_cli contains generic):
- Check if contains general story skill routing sections
- Check if 13 story skill directories under exist, and each is readable
- Check if the reference files under
skills/story-setup/references/agent-references/
are complete and the quantity is the same as the source directory
- The installation report must prompt: generic does not deploy platform-specific hooks/custom agents; hard interception such as outline guard, commit reminder, session/compact injection and multi-agent collaboration are executed according to soft constraints within skills or solo/direct fallback
- Verify Reasonix deployment (only when target_cli contains reasonix):
- Check if contains Reasonix story skill routing sections and solo/direct fallback instructions
- Check if 13 story skill directories under exist, and each is readable
- Check if the project's is a symlink pointing to (POSIX; allows Reasonix native scanning to discover skills); when symlink is not created on Windows, instead confirm that the root can be used for
- Check if the reference files under
skills/story-setup/references/agent-references/
are complete and the quantity is the same as the source directory
- The installation report must prompt: Reasonix is currently skills-only; Reasonix hooks/custom agents are not deployed, outline guard before writing prose, commit reminder, session/compact automatic injection only serve as soft constraints within skills, Skills involving professional Agents use solo/direct fallback; use
reasonix doctor capabilities
to verify skill discovery, if new skills do not appear after deployment, start a new Reasonix session or use root for native plugin installation
Template Placeholders
| Placeholder | Replacement Rule | Example |
|---|
| User project name or directory name | 《Sword Comes》, 《Dark Guard》 |
| Book title directory name (consistent with directory) | Same as , or user-defined |
| Target publishing platform | Qidian, Tomato, Jinjiang, Zhihu Yanyan |
| User pen name or nickname | Use "Author" if not specified |
Remove curly braces when replacing. If the user does not specify a project name, use the current directory name. Unspecified placeholders are retained as-is.
CLAUDE.md Merge Strategy
When the user already has CLAUDE.md, merge by marker/section:
- Prioritize identifying story-setup managed block markers (if the old project already has markers, only replace the content within the markers)
- If no markers exist, read the user's existing CLAUDE.md and split into section map by titles
- Read the template CLAUDE.md.tmpl and split in the same way
- Standard sections in the template (Skill routing table, file structure, collaboration rules, restore context after Compact) override the user's sections with the same name
- User's unique sections (custom content) retained unchanged
- For unknown conflicts, use AskUserQuestion to let the user choose which version to retain
AGENTS.md Merge Strategy (OpenCode / Codex / ZCode / OpenClaw / Reasonix / generic)
When the user already has AGENTS.md, merge by marker/section:
- Prioritize identifying story-setup managed block markers (if the old project already has markers, only replace the content within the markers)
- If no markers exist, read the user's existing AGENTS.md and split into section map by titles
- OpenCode uses
skills/story-setup/references/opencode/AGENTS.md.tmpl
; Codex uses skills/story-setup/references/codex/AGENTS.md.tmpl
; ZCode uses skills/story-setup/references/zcode/AGENTS.md.tmpl
; OpenClaw uses skills/story-setup/references/openclaw/AGENTS.md.tmpl
; Reasonix uses skills/story-setup/references/reasonix/AGENTS.md.tmpl
; General Web AI / Other Agents use skills/story-setup/references/generic/AGENTS.md.tmpl
- Standard sections in the template (Skill routing table, file structure, collaboration rules, restore context after Compact) override sections with the same name; user's unique sections are retained
- When deploying to multiple ends, retain only one copy of general paragraphs common to Codex/OpenCode/ZCode/OpenClaw/Reasonix/generic; tool-specific instructions are distinguished by subsections to avoid overwriting each other
Redeployment
- does not exist → New installation, execute all of Phase 2
- exists and → Prompt that it has been deployed, use AskUserQuestion to confirm whether to redeploy; clearly state in the prompt that redeployment only refreshes project files using the current local skill package, skill updates are done via or marketplace
- exists but is missing, non-integer or less than → Prompt that update is needed, re-execute Phase 2 to overwrite agents/hooks/rules/reference bundle, CLAUDE.md / AGENTS.md / settings.local.json / .codex/hooks.json / .zcode/config.json follow merge strategy
- exists and is greater than → Current skill version is too old, stop and prompt to update oh-story-claudecode first; do not overwrite updated deployment in the project
Reference Materials
| File | Purpose |
|---|
| references/templates/hooks/ | 8 hook script templates + (shared implementation of prose web/word count/outline guard/consistency/commit detection, same copy as OpenCode/ZCode) + (node bridge for bash hook calling core) + / (prose fallback check-prose-after-write.sh
is limited to PostToolUse Write/Edit; Bash writing prose such as / is covered by git scanning at the end of Codex Stop round, Bash of Claude/OpenCode only uses pre-guard) |
| references/zcode/ | ZCode AGENTS, 13 Commands, workspace config patch and strict JSON Hook runner |
Process Connection
Pipeline: Deployment
Position: Initialization (most front-end)
| Timing | Jump to | Command |
|---|
| Deployment completed, start writing | story-long-write / story-short-write | or |
| Import existing novel for disassembly | story-import | |
| Need browser login state (rank scanning/extract original text from novel) | browser-cdp | ; generic requires platform to allow local scripts/browser control |
Calling syntax for each end: Claude
, Codex/ZCode
, OpenClaw
, Reasonix / generic directly name the skill.