SuperAPI AI Directory

story-setup

Writing & research

View repository

Updated 10-16 04:54

About this skill

story-setup: Web fiction writing toolset infrastructure deployment

You are the writing infrastructure deployer. Deploy the web fiction writing toolset to the user's project directory: adapted CLIs use dedicated hooks/agents/config; environments such as NarraFork, Web AI, and custom Agents use the generic file mode.

Iron rule of execution: do not overwrite the user's existing configuration; merge rather than replace.

Interactive tool compatibility gate: In this Skill, AskUserQuestion means "the user must be made to choose"; it does not mean a tool with the same name must exist. When the current runtime does not expose this tool (including some TRAE Code, WorkBuddy / CodeBuddy Code, and Web AI sessions), the main Agent must directly ask the same short question in the current main conversation and wait for an answer; it must not skip confirmation because the tool is missing, fabricate a selected result, or have a sub-Agent ask on its behalf.


Phase 1: Detect project status

First self-check the reference directory: Based on the directory where the currently executing SKILL.md resides, list the subdirectories under the references/ at the same level as it, and verify whether all 10 names below are presentand all non-empty——agent-references、templates、opencode、codex、zcode、trae、workbuddy、openclaw、reasonix、generic; the same-level scripts/merge-claude-settings.py、scripts/merge-codex-hooks.py、scripts/merge-trae-hooks.py、scripts/trae-core-ownership.py、scripts/merge-workbuddy-settings.py and scripts/copy-path-safety.py must also exist (Claude/Codex/TRAE/WorkBuddy hooks merging, shared-core ownership verification, and recursive copy safety pre-checks depend on them). If anything is missing, the skill package was not fully installed,stop immediately and do not write any deployment files, distinguish in the report between "missing directory" and "empty directory", and give repair instructions: "The story-setup reference package is incomplete, missing {directory name}. Reinstall oh-story-claudecode according to your installation method (for command-line installs, rerun npx skills add https://github.com/qin1473692580-ux/oh-story-claudecode/releases/latest/download/oh-story-release.zip -y -g, for marketplace / Plugin Management installs, reinstall in the panel), then run /story-setup."

The criterion is "whether there is SKILL.md": only look at the SKILL.md at the same level as the currently executing references/. In-project .claude/skills/story-setup/、.codex/skills/story-setup/ and OpenCode's skills/story-setup/ only have references/agent-references/, and do not contain SKILL.md, so they will not be the execution directory, and you should not use them for verification either. The project copies for ZCode / TRAE Code / WorkBuddy / CodeBuddy Code / OpenClaw / Reasonix / generic are copies of the entire skill and come with SKILL.md, so the 10 subdirectories are complete by nature; verify them as usual.

  1. Check whether the current directory has already been deployed (exists .story-deployed)
    • agents_version missing, non-integer, or less than 39 → mark as pending update, continue with the current deployment
    • agents_version: 39 → use AskUserQuestion to confirm whether to redeploy; state in the prompt that redeployment only usesthe current local skill packageto refresh project files; to get a new version of the skill itself, first rerun with the pinned GitHub Release asset npx skills add https://github.com/qin1473692580-ux/oh-story-claudecode/releases/latest/download/oh-story-release.zip -y -g, then come back and rerun
    • agents_version greater than 39 → the current story-setup is older than the project deployment; stop to avoid a downgrade overwrite, prompt to update oh-story-claudecode first, and do not write any deployment files
    • Also read the target_cli field.For deployed projects, the value in the sentinel takes precedence: When non-empty (comma-separated multi-target combinations are preserved as-is), skip the environment detection and selection in steps 5-14 below, and redeploy directly according to these targets. Only when the field is missing or empty does it fall back to detection. When the user explicitly requests adding or removing target ends, use AskUserQuestion to modify based on the existing values, and write the modified values back to the sentinel.
  2. Check whether there is a book-title directory (a directory containing the 追踪/ subdirectory, or a user-defined structure)
    • Yes → identify as a long-form project, display current project information
    • No → identify as a new project or short-form project
  3. Check whether .claude/settings.local.json exists
    • Exists → read the existing configuration, merge later
    • Does not exist → create a new file later
  4. Check whether the .active-book file exists
    • Exists → display the currently active book
    • Does not exist → skip
  5. Check whether opencode.json or .opencode/ exists
    • Exists → identify as an opencode project,target_cli = opencode
    • Does not exist → skip
  6. Check the Codex section in .codex/、.codex/config.toml、.codex/agents/、.codex/hooks.json、AGENTS.md Codex section in
    • Exists → identify as a Codex project,target_cli = codex
    • Does not exist → skip
  7. Check the ZCode section in .zcode/、.zcode/config.json、zcode.json、.zcode/skills/、.zcode/commands/、AGENTS.md ZCode section in
    • Exists → identify as a ZCode project,target_cli = zcode
    • Does not exist → skip
  8. Check .trae/、.trae/hooks.json、.trae/skills/、.trae/agents/、.trae/commands/、.trae/rules/, or the TRAE section in AGENTS.md (title line contains 网文写作工具集(TRAE Code))
    • Exists → identify as a TRAE Code project,target_cli = trae
    • Does not exist → skip
  9. Check .codebuddy/、.codebuddy/settings.json、.codebuddy/skills/、.codebuddy/agents/、.codebuddy/commands/、.codebuddy/rules/, or .codebuddy/CODEBUDDY.md / root CODEBUDDY.md / root AGENTS.md the oh-story WorkBuddy management section in
    • Exists → identify as a WorkBuddy / CodeBuddy Code project,target_cli = workbuddy
    • Does not exist → skip
  10. Check openclaw.json、.openclaw/, or the OpenClaw section in AGENTS.md (title line contains 网文写作工具集(OpenClaw))
  • Exists → identify as an OpenClaw project,target_cli = openclaw
  • Does not exist → skip
  1. Check .reasonix/、reasonix-plugin.json、REASONIX.md, or the Reasonix section in AGENTS.md (title line contains 网文写作工具集(Reasonix))
  • Exists → identify as a Reasonix project,target_cli = reasonix
  • Does not exist → skip
  1. Check the generic section in AGENTS.md (title line contains 网文写作工具集(通用 Agent / Web AI))
  • Exists → identify as a generic Web AI project,target_cli = generic
  • Does not exist → skip

Steps 8-12 only recognize each target'smutually exclusivemarkers.skills/*/SKILL.md of metadata.openclaw is not used as an OpenClaw signal: canonical Chinese main-package Skills all carry this field, and the skills/ deployed by the three skills-only paths OpenClaw / Reasonix / generic look the same, so using it for determination would misidentify the latter two as OpenClaw without exception..agents/skills/ For the same reason, it is shared by Codex and Reasonix, and also does not serve as a sole criterion. TRAE only recognizes .trae/ or the TRAE-specific title line; WorkBuddy only recognizes .codebuddy/ or its CODEBUDDY management section; the real distinguishing point of the three skills-only targets is the title line of their respective AGENTS.md templates.

  1. If .claude/ or CLAUDE.md, OpenCode, Codex, ZCode, TRAE Code, WorkBuddy / CodeBuddy Code, OpenClaw, Reasonix, and generic markers all exist at the same time → use AskUserQuestion to let the user choose the target environment (options: Claude Code / OpenCode / Codex / ZCode / TRAE Code / WorkBuddy / CodeBuddy Code / OpenClaw / Reasonix / Generic Web AI or other Agent / any combination)
  2. If none of the nine types of markers exist (brand-new project) → use AskUserQuestion to let the user choose the target environment
  • User selects opencode → target_cli = opencode, create during deployment opencode.json and .opencode/
  • User selects claude-code → handle according to the existing logic
  • User selects codex → target_cli = codex, create during deployment .codex/
  • User selects zcode → target_cli = zcode, create during deployment .zcode/, merge root AGENTS.md, do not create project custom agents
  • User selects TRAE Code → target_cli = trae, create during deployment .trae/and merge root AGENTS.md、.trae/hooks.json, deploy native Skills / Subagents / Commands / Rules / Hooks
  • User selects WorkBuddy / CodeBuddy Code → target_cli = workbuddy, create during deployment .codebuddy/, select a single memory file according to the "WorkBuddy memory merge strategy" and merge .codebuddy/settings.json, deploy native Skills / Agents / Commands / Rules / Hooks
  • User selects openclaw → target_cli = openclaw, during deployment copy OpenClaw-compatible skills to the project skills/
  • User selects reasonix → target_cli = reasonix, during deployment copy skills to the project skills/, write the Reasonix version of AGENTS.md, do not create project custom agents/hooks
  • User selects Generic Web AI / other Agent → target_cli = generic, deploy generic AGENTS.md and project-local skills/; do not write platform-specific hooks/agents
  • User selects multi-platform → target_cli = claude-code,opencode,codex,zcode,trae,workbuddy,openclaw,reasonix,generic subset (containing only the platforms selected by the user)

Phase 2: Deploy infrastructure

After using AskUserQuestion to confirm the deployment location, execute in order.

The entire Phase 2 is idempotent: directory copying, file writing, and the merge algorithms in the table below produce consistent results when executed repeatedly. If it fails midway due to environmental reasons (tool unavailable, permission denied, network failure), directly rerun this Phase from the beginning; there is no need to clean up partial artifacts first;create only if absent user state files (see the Owner class in the table below) will not be overwritten a second time.

Step 1: Deployment manifest (mechanically checkable)

Recursive copy safety precheck (before any directory replace/copy): first resolve the Source path to an absolute path inside the "currently executing story-setup skill package", resolve the Target path to an absolute path inside the user project, then use the available python3/python/py to run scripts/copy-path-safety.py <source> <target>. Read its JSON result:

  • status=safe: Only if the paths do not contain each other may this copy item continue.
  • status=same: The source and target point to the same object via realpath/samefile; record this item as an idempotent no-op,must not recursively copy again。
  • status=unsafe: The target is inside the source, or the source is inside the target; immediately stop the entire Phase 2, do not perform deletion/overwrite, and report reason and the two realpaths.
  • status=error: The source is missing or path resolution fails; treat it as an incomplete deployment package and stop immediately.

This pre-check must not be replaced by a string prefix, an unexpanded relative path, or "it doesn't look like the same directory"; symlinks/aliases must be judged by realpath. File-level replace may continue to follow the existing atomic write rules; all recursive directory copies must pass through this gate item by item.

TRAE ownership and backup gate (target_cli contains trae when): before modifying any existing .trae/ file, first back up the original files that will be modified this time by relative path to .trae/.oh-story-backups/<UTC时间戳>/; the directory backup itself must also first run copy-path-safety.py. Only replacement is allowed for canonical Chinese main-package skill / command / agent / rule / AGENTS managed blocks bearing the oh-story-managed marker, for story_trae_hook.jswhose header comment explicitly identifies it as the oh-story TRAE adapter, and for story_hook_core.jsthat satisfies any of the following ownership evidence: contains the generic marker oh-story-managed: shared-hook-coretrue scripts/trae-core-ownership.py ; after validation with references/trae/legacy-managed-sha256.jsonthe sha256 matches the sole authoritative SKILL.md true metadata.openclaw.source points to this repository, or is precisely marked <!-- oh-story-managed: skill/{name} -->. User files with the same name but no ownership evidence must be retained and reported as conflicts, and must not be overwritten..trae/hooks.json is always merged by the helper according to a stable command identity, and the entire file is never replaced. Newly created artifacts must be written with the corresponding management marker, so that they can be safely upgraded next time.

TRAE and Claude Hook deduplication gate: TRAE will compatibly read the project .claude/settings*.json. Claude settings commands keep the cross-platform-executable direct bash ... form, without embedding POSIX if; all Claude shell entry points, after source lib/common.sh , are detected by the shared library as TRAE_PROJECT_DIR and exit successfully and silently. Execute as usual in Claude, and in the TRAE process let .trae/hooks.json execute exclusively. After deployment, verify with synthetic input from both sides that the same event produces only one set of oh-story output; "the two prompts look the same" must not be treated as acceptable.

WorkBuddy ownership and Hook mutual-exclusion gate (target_cli contains workbuddy when): only replace canonical Chinese main-package skill / command / agent / rule / CODEBUDDY (or AGENTS) managed blocks bearing the oh-story-managed marker, as well as hook files with adapter header comments or the generic shared-core marker; Skill directories use the same dual evidence of repository metadata / <!-- oh-story-managed: skill/{name} --> as TRAE. User files with the same name are retained and reported as conflicts..codebuddy/settings.json merges only through merge-workbuddy-settings.py . If the current skill comes from an enabled oh-story CodeBuddy plugin (the actual execution path is located at the plugin installation root, or the current session registry / codebuddy plugin list explicitly shows that oh-story is enabled), plugin hooks are loaded automatically; at this point the empty template must be used to remove the old oh-story-managed hook registrations in the project, and project-hooks.jsonmust no longer be merged; only in project-local skills mode are project hooks written, to prevent double triggering of the same event. The presence of .codebuddy-plugin/plugin.json in the repository or the fact that the plugin was once installed does not count as evidence that it is "currently enabled".

WorkBuddy namespace gate: plugin mode exposes Skills, Agents and Hooks only through .codebuddy-plugin/plugin.json ; it must not simultaneously expose Commands with the same names as Skills in the manifest, otherwise /oh-story:story-* will have component name competition. Plugin mode invokes namespace-qualified Skills such as /oh-story:story、/oh-story:story-long-write ; only after running story-setup does project mode expose via .codebuddy/commands/ true /story、/story-long-write and other bare commands. The two modes must be documented separately in the installation report; bare commands must not be described as plugin commands.

Source path Target path Owner class Merge mode Validation check
skills/story-setup/references/templates/CLAUDE.md.tmpl CLAUDE.md user+managed marker/section merge contains story skill routing sections
skills/story-setup/references/templates/hooks/ .claude/hooks/ story-setup managed recursive replace session-*.sh, detect-story-gaps.sh, validate-story-commit.sh, guard-outline-before-prose.sh, check-prose-after-write.sh, story_hook_core.js, story_hook_cli.js, lib/common.sh, lib/sentinel.sh exist;story_hook_core.js byte-identical to the OpenCode/ZCode copy
skills/story-setup/references/templates/rules/*.md .claude/rules/*.md story-setup managed replace every rule contains paths frontmatter
skills/story-setup/references/templates/agents/*.md .claude/agents/*.md story-setup managed replace 8 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; legacy matcher registrations migrated, one copy of each current template command, user hooks preserved
skills/story-setup/scripts/merge-claude-settings.py executed at deployment time, not copied into the project story-setup helper execute replace known story hook registrations, preserve user hooks/top-level fields, historical matcher migration and repeated execution idempotent
skills/story-setup/references/templates/质检进度.md.tmpl {书名}/追踪/质检进度.md user state create only if absent never overwrite existing progress table
generated sentinel .story-deployed story-setup managed replace contains agents_version, setup_skill_version, target_cli, resolver_strategy, references_dir
skills/story-setup/references/opencode/AGENTS.md.tmpl AGENTS.md user+managed marker/section merge contains story skill routing sections
skills/story-setup/references/opencode/agents/ .opencode/agents/ story-setup managed replace 8 agent files exist (before replace, cache existing ones per "Preserve existing model configuration" in "Configure OpenCode Agent Models" 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; byte-identical to the ZCode copy; imported by story-hooks.ts
skills/story-setup/references/opencode/commands/ .opencode/commands/ story-setup managed replace command count matches the current OpenCode template manifest
skills/story-setup/references/opencode/opencode.json.patch merge into opencode.json user+managed merge by plugin/permission key plugin entry registered
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 .git/hooks/pre-commit user+managed append or create file exists and is executable; if it contains a marker block, replace the block contents; if not, detect the exit 0 position and insert intelligently
skills/story-setup/references/codex/AGENTS.md.tmpl AGENTS.md user+managed marker/section merge contains Codex story skill routing sections
skills/story-setup/references/codex/agents/ .codex/agents/ story-setup managed replace 8 TOML agent files parse and contain name/description/developer_instructions
skills/story-setup/references/codex/hooks/hooks.json .codex/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} .codex/hooks/ same-named file story-setup managed replace Python/shell/cmd launcher files complete
skills/story-setup/scripts/merge-codex-hooks.py executed at deployment time, not copied into the project story-setup helper execute replace known management registrations, preserve user hooks and unknown top-level fields, result idempotent
skills/story-setup/scripts/copy-path-safety.py executed before each recursive directory copy, not copied into the project story-setup helper execute same=no-op; ancestor/descendant nesting=block; only safe can be copied
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 AGENTS.md user+managed marker/section merge contains ZCode $story-* routing and solo fallback
canonical repository skills/{browser-cdp,story*}/ .zcode/skills/{browser-cdp,story*}/ story-setup managed for 18 known skill names replace known skill dirs only SKILL.md name set matches the Chinese main package's 18 Skill manifest and satisfies ZCode frontmatter restrictions
skills/story-setup/references/zcode/commands/ .zcode/commands/ story-setup managed for 18 known command names replace known command files only commands have valid names/frontmatter and cover the canonical skill list
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 .zcode/config.json user+managed merge by event+matcher+process args JSON valid; validated per the hooks mutual-exclusion branch in step 4 of the "ZCode Deployment Algorithm"—when the oh-story plugin is not installed hooks.enabled=true, only supported events; when the plugin is installed, validate .zcode/config.json does not contain (or has removed) this batch of oh-story hooks registrations
skills/story-setup/references/trae/AGENTS.md.tmpl AGENTS.md user+managed marker/section merge contains TRAE Code story routing and fallback contract
canonical repository skills/{browser-cdp,story*}/ .trae/skills/{skill-name}/ story-setup managed for the fixed 18 source names backup + replace managed dirs only target SKILL.md count/names match the Chinese main package's 18 Skill manifest; if source and target are the same, no-op
skills/story-setup/references/trae/commands/ .trae/commands/{skill-name}.md story-setup managed by oh-story-managed marker backup + replace 18 managed files only each canonical skill has exactly one same-named command, frontmatter contains name / description
skills/story-setup/references/trae/agents/ .trae/agents/ story-setup managed by oh-story-managed marker backup + replace exact common roster (8 files) name set exactly chapter-extractor, character-designer, consistency-checker, narrative-writer, revision-governor, story-architect, story-explorer, story-researcher; TRAE frontmatter parseable
repository skills/story-data-analyze/agents/trae/ .trae/agents/ story-setup managed by oh-story-managed marker backup + replace exact data roster (5 files) name set exactly story-data-fetcher, story-data-method-validator, story-data-metrics-analyst, story-data-supervisor, story-data-text-improvement-planner; no duplicate names with common roles
skills/story-setup/references/trae/rules/ .trae/rules/ story-setup managed by oh-story-managed marker backup + replace managed files only rules frontmatter contains alwaysApply / globs
skills/story-setup/references/trae/hooks/{story_trae_hook.js,story_hook_core.js} .trae/hooks/ same-named file runner by adapter header; core by fixed name + packaged hash backup + replace managed files only Node syntax valid; shared core consistent with other adapter copies
skills/story-setup/references/trae/hooks/hooks.json .trae/hooks.json user+managed replace managed registrations by stable hook command identity version: 1; contains only TRAE-supported events; user hook/top-level fields preserved
skills/story-setup/scripts/merge-trae-hooks.py executed at deployment time, not copied into the project story-setup helper execute migrate legacy matcher/command, preserve user configuration, repeated execution byte-idempotent
skills/story-setup/scripts/trae-core-ownership.py + references/trae/legacy-managed-sha256.json executed at deployment time, not copied into the project story-setup ownership helper/registry classify before replace marker / legacy SHA judged managed; unknown/error preserved and reported
skills/story-setup/references/workbuddy/CODEBUDDY.md.tmpl existing CODEBUDDY.md / .codebuddy/CODEBUDDY.md, or when neither exists, AGENTS.md / .codebuddy/CODEBUDDY.md user+managed per "WorkBuddy memory merge strategy", merge only the marker block does not shadow existing AGENTS; conditional import placeholders resolved; management block unique
canonical repository skills/{browser-cdp,story*}/ .codebuddy/skills/{skill-name}/ story-setup managed for the fixed 18 source names replace managed dirs only SKILL.md name set matches the Chinese main package's 18 Skill manifest; if source and target are the same, no-op
skills/story-setup/references/workbuddy/commands/ .codebuddy/commands/{skill-name}.md story-setup managed by oh-story-managed marker replace 18 managed files only commands correspond one-to-one with canonical skills, frontmatter uses only CodeBuddy-supported fields
skills/story-setup/references/workbuddy/agents/ .codebuddy/agents/ story-setup managed by marker replace exact common roster (8 files) name set exactly chapter-extractor, character-designer, consistency-checker, narrative-writer, revision-governor, story-architect, story-explorer, story-researcher; WorkBuddy frontmatter is valid, and project Agent names do not carry a plugin namespace
repository skills/story-data-analyze/agents/workbuddy/ .codebuddy/agents/ story-setup managed by marker replace the exact data physical roster (2 files) the name set is exactly story-data-fetcher, story-data-readonly-runner; the 4 logical role cards remain in Skill references
skills/story-setup/references/workbuddy/rules/ .codebuddy/rules/ story-setup managed by marker replace managed files only alwaysApply is parseable; user rules are preserved
skills/story-setup/references/workbuddy/hooks/{story_workbuddy_hook.js,story_hook_core.js} .codebuddy/hooks/ files with the same name story-setup managed replace managed files only Node syntax valid;shared core byte-parity
skills/story-setup/references/workbuddy/hooks/project-hooks.json merge into .codebuddy/settings.json user+managed merge or remove by plugin mutex only project-local mode registers once each; plugin mode is zero; user settings and hooks are preserved
skills/story-setup/scripts/merge-workbuddy-settings.py executed at deployment time, not copied into the project story-setup helper execute stable runner identity removal of old entries, merge/removal is idempotent
skills/story-setup/references/openclaw/AGENTS.md.tmpl AGENTS.md user+managed marker/section merge contains OpenClaw story skill routing sections
skills/story-setup/references/generic/AGENTS.md.tmpl AGENTS.md user+managed marker/section merge contains generic story skill routing sections
skills/story-setup/references/reasonix/AGENTS.md.tmpl AGENTS.md user+managed marker/section merge contains Reasonix story skill routing sections and solo/direct fallback
canonical repository skills/{browser-cdp,story*}/ skills/{browser-cdp,story*}/ story-setup managed for 18 known skill names replace known skill dirs only SKILL.md the name set matches the 18-Skill list of the Chinese main package; the OpenClaw branch validates frontmatter compatibility
skills/story-setup/references/agent-references/ skills/story-setup/references/agent-references/ story-setup managed replace via full skill copy every reference resolves

opencode.json merge algorithm

When deploying opencode.json.patch , merge according to the following rules:

  1. Read the existing opencode.json(if present), parse the JSON
  2. Merge the plugin array: add ./.opencode/plugins/story-hooks.ts to the array and deduplicate
  3. Preserve other configuration fields the user already has (permission、model、provider , etc.), do not overwrite
  4. Write the merged opencode.json

Step 2: Deploy CLAUDE.md

  • Read skills/story-setup/references/templates/CLAUDE.md.tmpl
  • Replace placeholders (see the "Template placeholders" section below)
  • Write to the project root CLAUDE.md(if it already exists, handle it according to the "CLAUDE.md merge strategy")

Step 3: Deploy Hooks

  • Recursively copy the complete directory tree: copy skills/story-setup/references/templates/hooks/ to the user project .claude/hooks/
  • The subdirectory lib/must be preserved, where:
    • lib/common.sh provides project_root、discover_active_book、discover_all_books
    • lib/sentinel.sh provides .story-deployed field reading
  • Only set execute permission for .claude/hooks/*.sh (chmod +x);lib/*.sh is handled by the hook source, the executable bit is not required

Step 4: Deploy Rules

  • Read all skills/story-setup/references/templates/rules/ files under .md files
  • Copy to the user project's .claude/rules/ directory

Step 5: Deploy Agents

  • Read all skills/story-setup/references/templates/agents/ files under .md files
  • Copy to the user project's .claude/agents/ directory
  • Agent files are story-setup managed files and can be safely overwritten; on version upgrades, redeploy according to UPGRADING.md 's version detection result
  • target_cli When opencode is included, overwrite .opencode/agents/ , first execute Step 1 of "Configure OpenCode Agent model" below to cache the existing model:. That step is written later in this section, but it must be run first—reading in order and doing what you read would overwrite before caching, and the user's already configured models would be lost.
  • A new session must be started after deployment: agents are only registered at session startup; for the reason and the report text that must be output, see "Output installation report" in "Verify installation".

Agent compatibility handling

  • Agent frontmatter is primarily based on Claude Code; OpenCode's .opencode/agents/*.md, Codex's .codex/agents/*.toml, TRAE's .trae/agents/*.md and WorkBuddy's .codebuddy/agents/*.md all use pre-generated artifacts under the corresponding adapter, and frontmatter from other clients must not be copied directly. The only source for the TRAE general role is references/trae/agents/, the only source for the data analysis role is skills/story-data-analyze/agents/trae/; the corresponding sources for WorkBuddy are references/workbuddy/agents/ and skills/story-data-analyze/agents/workbuddy/. Do not mechanically carry over Claude model aliases or proprietary fields from one side to the other. OpenCode/Codex/WorkBuddy pre-generated artifacts are generated by repository maintenance scripts; these scripts are not distributed with story-setup, and deployment only copies committed artifacts.
  • ZCode 3.3.4 does not deploy project agents: its custom sub-agents only support user-level ~/.zcode/agents/, and the plugin manifest's agents is currently not executed. Do not create .zcode/agents/ or modify the user home; related Skills must go directly solo/direct and report fallback.
  • OpenClaw Phase 1 does not deploy agents: OpenClaw only deploys skills; skills related to agent collaboration must be downgraded to solo/direct according to the existing fallback rules. Do not directly copy Claude/OpenCode agent frontmatter into an OpenClaw agent.
  • After deployment to the project, reference materials referenced within an agent must use the story-setup/references/agent-references/*.md copy path within this same skill; do not reference other skills' references across skills. Each adapter only uses the current canonical prefix: for Claude Code it is .claude/skills/, for OpenCode / OpenClaw / Reasonix / generic it is skills/, for Codex it is .codex/skills/, for ZCode it is .zcode/skills/, for TRAE Code it is .trae/skills/, for WorkBuddy / CodeBuddy Code it is .codebuddy/skills/; in plugin mode, the platform-inlined ${CODEBUDDY_PLUGIN_ROOT}/skills/may be used. Do not traverse historical alternative paths at runtime.

Deploy Agent References

  • Copy all skills/story-setup/references/agent-references/ under .md into the project's .claude/skills/story-setup/references/agent-references/
  • Validation: wherever story-setup/references/agent-references/<file>.mdappears in an agent or reference, both the source package and the target package must have <file>.md

Deploy Codex Agents (when target_cli includes codex)

  • Read all skills/story-setup/references/codex/agents/ under .toml files and copy them to the user project's .codex/agents/
  • Agent files are story-setup managed files and can be safely overwritten;references/codex/agents/ the TOML in is deterministically generated from the Claude agent template by the repository root's scripts/generate-codex-agents.py and committed to the repository; deployment only copies
  • Validate that every TOML can be parsed and contains the fields required by Codex:name、description、developer_instructions
  • Read-only responsibility agents (chapter-extractor、consistency-checker、revision-governor、story-explorer) must retain sandbox_mode = "read-only"
  • After deployment you must trust + open a new Codex session(for the report wording and fallback rules, see "Verify Codex Deployment"); if the runtime returns unknown agent_type, 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 primary in-project reference path for Codex agents

Deploy TRAE Agents (when target_cli includes trae)

  • First validate that the name set of references/trae/agents/ is exactly chapter-extractor, character-designer, consistency-checker, narrative-writer, revision-governor, story-architect, story-explorer, story-researcher(8 general cards), then validate that the name set of canonical story-data-analyze/agents/trae/ is exactly story-data-fetcher, story-data-method-validator, story-data-metrics-analyst, story-data-supervisor, story-data-text-improvement-planner(5 data cards). The two groups must have no duplicate names, and after merging the roster must be exactly 13 cards; if any required directory is missing, empty, has a name set mismatch, has duplicate names, or has unparseable frontmatter, stop the TRAE branch and do not perform a partial deployment.
  • Write in sequence .trae/agents/, only create or replace same-named files with the <!-- oh-story-managed: agent/<agent-name> --> marker; same-named files without the marker are retained and reported. Do not delete other user agents.
  • TRAE frontmatter only uses its native fields:name、description, the comma-separated string form of tools / disallowedTools and the optional TRAE built-in model; it is forbidden to automatically write in Claude model aliases.
  • After deployment, prompt the user to start a new TRAE session and confirm that the Subagents Beta feature is available. If the current TRAE version/session does not support native Agents, you must degrade according to each skill's contract solo/direct, report Fallback: TRAE subagent unavailable -> solo/direct; do not claim that the full/lean multi-Agent setup is in effect.

Deploy WorkBuddy Agents (when target_cli includes workbuddy)

  • First verify that the name set of references/workbuddy/agents/ is exactly chapter-extractor, character-designer, consistency-checker, narrative-writer, revision-governor, story-architect, story-explorer, story-researcher(8 general cards); then verify that the physical name set of skills/story-data-analyze/agents/workbuddy/ is exactly story-data-fetcher, story-data-readonly-runner(2 data cards), and that the four read-only logical role cards remain intact in that Skill's WorkBuddy role-card references. All physical names must have no duplicates, and after merging, the Chinese main package's physical name roster must be exactly 10 cards.
  • CodeBuddy currently, during the agentic registry query phase, hard-caps the total number of built-in + project Subagents at 20. The exact 10 physical WorkBuddy cards listed in this section are below the platform limit; the deployer does not inject project extension cards into that roster, and does not hide capacity issues through sorting or truncation.
  • Each Markdown must have valid YAML frontmatter,name must match the filename,description must be non-empty,tools / disallowedTools must be a comma-separated string and use only current CodeBuddy tool names. plugin agents are prohibited from hooks、mcpServers、permissionMode; project agents also do not depend on these fields.
  • Only create or replace those marked with <!-- oh-story-managed: agent/<name> --> marked .codebuddy/agents/<name>.md; files with the same name that are unmarked are kept and the conflict is reported. Project definitions take precedence over plugin/user agents; project mode uniformly uses bare names and Agent(subagent_type: "<name>")。
  • pooled runner logical role cards remain within the owning Skill and must not be copied into .codebuddy/agents/. The main coordinator must select the runner according to that Skill's runtime mapping, and pass in the prompt logical_role, the absolute path of the role card, the project root, the input isolation contract, and the task body; the runner must fully read and verify the role card before executing.
  • In plugin-only mode, the UI name is oh-story:<name>; only use it when the current registry actually exposes that name. When story-setup has not been run, do not guess from the on-disk manifest that the registry has loaded it; if the call fails, immediately degrade according to the Skill contract. After project deployment is complete, uniformly use .codebuddy/agents/ 's bare name to avoid namespace divergence.
  • After deployment, start a new WorkBuddy / CodeBuddy session and use /agents or the current registry to confirm that all exact 10 physical cards listed in this section are visible; then smoke-test one general Agent and one pooled runner logical role separately. Child Agents must not recursively spawn.

Configure OpenCode Agent models

Execute only when target_cli includes opencode . When an OpenCode subagent does not specify a model, it inherits the main model, causing low-cost Agents to also consume the main model's quota. This step automatically detects the user's model and writes it to the model: field.

Step 1: Preserve the existing model configuration (must be executed before the replace of .opencode/agents/ )

OpenCode agents deployment is replace, and will overwrite the previously written model:. So before executing that replace beforefirst scan the existing .opencode/agents/*.md, and cache each agent's model:(agent name → model ID). If subsequent detection fails/times out, or the user skips a tier, backfill with the cached value to avoid overwriting the user's previously configured low-cost model with the main model. If replace has already occurred and the cache is empty, treat it as a fresh deployment and note "failed to preserve the previous model configuration" in the installation report.

Step 2: Get model list

Preferentially execute opencode models --verbose, which outputs metadata including cost (input/output/cache unit price), context, and capabilities; if unavailable or parsing fails, fall back to opencode models plain text (each line provider/model). Both use a 60000ms (60 second) timeout, because the first run needs to load the models.dev cache.

  • Success → proceed to "Model Tiering"
  • Timeout → retry once (the cache may not be warmed up); if it still times out, backfill the existing model:from the "preserve existing model configuration" cache, skip automatic configuration, and output a manual configuration guide in the installation report
  • Failure (command does not exist, output is empty, etc.) → same as above: backfill the "preserve existing model configuration" cache, skip automatic configuration, and output a manual configuration guide
Step 3: Model tiering

Prefer tiering by cost (when --verbose is present): tier by each model's actual cost from low to high—the low tier takes the cheapest/free tier, the mid tier takes the mid-priced tier, and the high tier takes the most expensive or the tier with the strongest context/capabilities. Free models are classified as low tier based on their real cost=0,not based on marketing words in the name(e.g., nemotron-3-ultra-free has ultra in its name but cost=0, so it should be classified as low tier). Models without cost data also enter the candidates on this basis and are not discarded.

Fall back to tiering by keywords (when there is no --verbose or no cost): take the model name after the last / in the model ID and split it by -、.、_ into segments, then exactly match keywords segment by segment (case-insensitive). For example, minimax-m3 is split into [minimax, m3], which matches neither mini nor max;claude-haiku-4.5 is split into [claude, haiku, 4, 5], which matches haiku. Keyword tiering is heuristic; in the installation report, label 分级依据:关键词(heuristic)。

tier matching keyword corresponding Agent
low tier haiku, flash, mini, nano, lite chapter-extractor, consistency-checker, story-explorer
mid tier sonnet, plus story-researcher, narrative-writer, character-designer, revision-governor
high tier opus, pro, ultra, max story-architect
  • A model may match keywords for multiple tiers; take the highest tier
  • Under keyword fallback, models that do not match any keyword are still included in the candidates as additional suggestions (under cost tiering, all are included), and are listed in the installation report with the note "can be used via custom input"
  • Within the same tier, if multiple model providers are included, prioritize listing models from well-known providers (anthropic, openai, google, deepseek)
Step 4: Tier-by-tier interactive selection

In the order low tier → mid tier → high tier, use AskUserQuestion at each tier to let the user choose.

Low tier option structure:

问题:"为低成本 Agent(chapter-extractor, consistency-checker, story-explorer)选择模型:"
选项:
  - provider/model-id
  - provider/model-id
  - 自定义输入(手动输入完整模型 ID,ID 拼写错误要到运行时才会暴露)
  - 跳过,使用主模型(成本可能较高)

Mid tier option structure:

问题:"为写作质量关键 Agent(narrative-writer, character-designer, story-researcher, revision-governor)选择模型:"
选项:
  - provider/model-id
  - provider/model-id
  - 自定义输入(请勿使用低端模型,会影响正文质量;ID 拼写错误要到运行时才会暴露)
  - 跳过,使用主模型(主模型质量通常足够)

High tier option structure:

问题:"为总指挥 Agent(story-architect)选择模型:"
选项:
  - provider/model-id
  - provider/model-id
  - 自定义输入(手动输入完整模型 ID,ID 拼写错误要到运行时才会暴露)
  - 跳过,使用主模型(成本可能较高)

Rules:

  • Show at most 5 candidates; if there are more, truncate and prompt "for more models, please use custom input".At each tier, regardless of whether the number of candidates is 0, pop up AskUserQuestion, and the options must include at least: candidate models (if any),自定义输入、保留现有模型(cache the "preserve existing model configuration" to that agent's model; if none, do not show this item),跳过,用主模型. Even when the candidate count is 0, still show the prompt, and include the corresponding warning in the question description + list ungraded/ungrouped models for reference—no longer silently skip the interaction (otherwise the user cannot reach the custom input).
  • 自定义输入: user enters provider/model-id full ID; before writing, validate that it is a single line, contains no control characters, and matches ^[A-Za-z0-9._-]+/[A-Za-z0-9._:+-]+$; if it does not match, prompt for re-entry or choose to skip.
  • 保留现有模型: write back the cached agent model for "keep existing model config" (preserve the user's previous config on redeploy); this does not count as "skip".
  • 跳过,用主模型: explicitly clear—do not write the agent's model:; the agent inherits the main model. To keep the previous config, choose 保留现有模型。
  • When the candidate count for any tier is 0, include a hint in the question description:
    • low tier: "No low-cost model detected; these 3 agents will use the main model, costs may be higher"
    • mid tier: "No matching mid-tier model detected. narrative-writer, character-designer, story-researcher will use the main model. If the main model's quality is sufficient, this config is reasonable; if you need to reduce cost, use custom input to specify a mid-tier model no lower than the main model's quality, or choose from the ungraded models below."
    • high tier: "No high-tier model detected; story-architect will use the main model"
Step 5: write the model field

the agent file corresponding to the user's choice (.opencode/agents/*.md, already deployed before this step by the OpenCode agents deployment step in the deploy manifest), at the end of the frontmatter, before the closing --- , usinga zero-indentation top-level fieldinsert model:(do not insert it inside the indented block of a multi-line map such as permission: ). If the value contains YAML special characters, quote it to ensure the frontmatter is not broken:

---
description: ...
mode: subagent
permission:
  read: allow
  edit: deny
steps: 12
model: provider/model-id
---
  • If the agent file already has a model: field (redeploy scenario), replace the value of that top-level model: ; do not add a duplicate key
  • 保留现有模型: write back the cached agent model for "keep existing model config"
  • 跳过,用主模型: do not write the model: field
  • Detection failure/timeout, or tiers that did not reach this step: use the "keep existing model config" cache to backfill model:, to avoid replace wiping out the user's previous config

Step 6: deploy the QC progress template

  • 追踪/上下文.md is no longer deployed by this step. It has been changed to a derived view of _tracking-state.json , rendered on commit by the tracking transaction tool bundled with the writing skill; story-setup no longer creates or overwrites it
  • read skills/story-setup/references/templates/质检进度.md.tmpl
  • Only when it has been identified as a long-form book list and {书名}/追踪/ already exists, create the missing {书名}/追踪/质检进度.md
  • If the target file already exists, do not overwrite; a short-form project must not create 追踪/ directory because of this. This table is the mechanically checkable record required by Phase 5 (consistency-checker, independent AI-flavor review), and must not be missing just because the project is already being written

Step 7: merge Hooks registration into settings.local.json

  1. Detect Python per the existing cross-platform rules:for PYBIN in python3 python py; do "$PYBIN" -c "" 2>/dev/null && break; done; if no usable interpreter is found, stop; do not hand-write or simplify the merge.
  2. Call "$PYBIN" "{story-setup skill目录}/scripts/merge-claude-settings.py" --existing "{项目}/.claude/settings.local.json" --template "{story-setup skill目录}/references/templates/settings-hooks.json" --output "{项目}/.claude/settings.local.json"。
  3. The helper removes all historical registrations of known story-setup hooks, then appends the current template; therefore matcher, timeout, and if can upgrade with versions, while user hooks and unknown top-level fields mixed into old blocks are preserved as-is. After writing, parse the JSON, verify that there is one copy of each template command and that user config remains, then rerun the helper and compare file bytes to confirm idempotence.

Codex hooks.json merge algorithm (when target_cli contains codex)

Codex project hooks are deployed to .codex/hooks.json; the runtime script is deployed to .codex/hooks/story_codex_hook.py、run-story-hook.sh、run-story-hook.cmd. JSON is only responsible for locating the project root and passing the event; interpreter detection is handled uniformly by the platform launcher.

  1. Locate the current story-setup skill directory, read references/codex/hooks/hooks.json as the sole current template, read the project's .codex/hooks.json(treated as an empty object if it does not exist).
  2. Detect available Python according to the existing cross-platform rules:for PYBIN in python3 python py; do "$PYBIN" -c "" 2>/dev/null && break; done; if no usable interpreter is found, stop; do not hand-write or simplify the JSON merge.
  3. Invoke "$PYBIN" "{story-setup skill目录}/scripts/merge-codex-hooks.py" --existing "{项目}/.codex/hooks.json" --template "{story-setup skill目录}/references/codex/hooks/hooks.json" --output "{项目}/.codex/hooks.json". This helper recognizes the old direct-call story_codex_hook.py, the current run-story-hook.sh , and run-story-hook.cmd management identities; it first removes all known management registrations, then appends the current template.
  4. Preserve the user's existing non-story-setup hooks, matcher blocks, and unknown top-level fields. Repeated execution must be idempotent; do not append and deduplicate again by the raw command string, otherwise the v17 direct-call command will be double-registered with the v18 launcher.
  5. After writing, parse the JSON to verify: the old direct-call story_codex_hook.py command count is 0, each of the current template's 6 registrations exists exactly once, and user hooks and unknown top-level fields are still present. Then prompt the user: the project .codex/ layer needs to be trusted by Codex, and non-managed command hooks also need to be reviewed/trusted in /hooks before they will run; on Windows use commandWindows, and the launcher locates the project .codex/hooks/upward from the current directory, consistent with the nested-directory behavior of POSIX paths.

Deployment source resolution (prevent self-copying from an old project copy)

  1. Record the currently executing story-setup directory and its parent skills root, called bootstrap_root. If it is located under the target project's .trae/skills/、.codebuddy/skills/、.zcode/skills/、.codex/skills/、.claude/skills/ or root skills/ , it is merely a "deployed snapshot" and must not be treated wholesale as the authoritative upgrade source.
  2. For a deployed project, additionally enumerate these verifiable candidates: the currently enabled plugin's ${CODEBUDDY_PLUGIN_ROOT}/skills/story-setup、~/.agents/skills/story-setup、~/.claude/skills/story-setup、~/.codex/skills/story-setup, as well as the local installation directory explicitly provided by the user this time. Do not search the entire disk, and do not directly execute unverified content from web pages or floating repositories.
  3. A candidate is valid only when all of the following conditions hold:SKILL.md frontmatter's name=story-setup、version is a comparable three-part numeric SemVer,metadata.openclaw.source points to this oh-story repository, and all references and helper self-checks listed in Phase 1 pass. Invalid candidates are only reported; do not read other content.
  4. Among valid candidates and bootstrap_root , select the latest complete package by SemVer as canonical_root; when versions are equal, prefer the installation package outside the project, and an external package with a lower version must not be used to downgrade the project. The installation report must state bootstrap_root、canonical_root, their respective versions/purposes, and the reason for selection.
  5. Subsequent templates, helpers, and the 18 Chinese main-package Skills are all read from canonical_root ; project-custom Skills do not enter the TRAE/WorkBuddy adaptation deployment source for this round, and existing user Skills are left untouched.
  6. copy-path-safety.py 's status=same only makes that one current source/target item a no-op; do not skip refreshing other Skills, Commands, Agents, Rules, and Hooks from story-setup just because the project's canonical_root copy points to itself.

canonical Chinese main-package Skill list (shared by all skills copy branches)

  1. canonical_root/skills/ must exactly contain these 18 deployable Skills:browser-cdp、story、story-cover、story-data-analyze、story-deslop、story-explore、story-import、story-long-analyze、story-long-scan、story-long-write、story-publish、story-release-package、story-research、story-review、story-setup、story-short-analyze、story-short-scan、story-short-write。
  2. Read each according to the above fixed name set SKILL.md frontmatter's name / description; if any is missing, the directory name is inconsistent with name , or there are duplicate names, stop deployment. Do not expand the main package because extra story* directories appear at the project root.
  3. For each source Skill directory and the corresponding target directory, execute item by item copy-path-safety.py;same record as no-op,unsafe/error stop, only safe may be copied. Do not delete or wholesale replace the entire user skills root directory.

TRAE / WorkBuddy fixed Agent roster

  1. The common roster shared by both ends is exactly 8 cards:chapter-extractor, character-designer, consistency-checker, narrative-writer, revision-governor, story-architect, story-explorer, story-researcher。
  2. The TRAE data roster is exactly 5 cards:story-data-fetcher, story-data-method-validator, story-data-metrics-analyst, story-data-supervisor, story-data-text-improvement-planner. The TRAE physical roster must be exactly equal to the union of the aforementioned 8 common cards and these 5 data cards, 13 cards in total.
  3. The WorkBuddy data physical roster is exactly 2 cards:story-data-fetcher, story-data-readonly-runner. The WorkBuddy physical roster must be exactly equal to the union of the aforementioned 8 common cards and these 2 data cards, 10 cards in total. The four read-only logical role cards are deployed along with the data analysis Skill itself, located via its runtime mapping, and are not registered as physical Agents.
  4. Both ends only back up/replace the above exact marker cards, preserving user Agents; cards that were managed last time but are not in the corresponding exact name set this time go through "managed asset convergence": back up then delete.

ZCode deployment algorithm (when target_cli includes zcode)

ZCode's first version deploys Skills, Commands, AGENTS.md, and Hooks within supported events; it does not deploy .zcode/agents or .zcode/rules。

  1. Copy to .zcode/skills/{skill-name}/according to the "canonical Chinese main package Skill list"; only replace these 18 known directories, preserving the user's other Skills.
  2. Copy references/zcode/commands/*.md to .zcode/commands/; only replace management commands with the same name as canonical skills, preserving the user's other Commands. If a skill in the main package lacks a pre-generated template, consider the package incomplete and stop; do not temporarily generate commands as project extensions.
  3. Copy references/zcode/hooks/story_zcode_hook.js and references/zcode/hooks/story_hook_core.js to .zcode/hooks/。
  4. Read references/zcode/config.json.patch and the existing .zcode/config.json(if only root zcode.json, still create .zcode/config.json to host oh-story project Hooks, without rewriting the root file):
    • Preserve all user unknown fields, MCP, plugins, skills/commands disable overrides;
    • hooks are mutually exclusive (to avoid double triggering): if this project runs via an already-installed oh-story plugin (marketplace install, repository root .zcode-plugin/plugin.json 's hooks.json has globally registered SessionStart/PreToolUse/PostToolUse), thenskipbelow merge config.json.patch 's hooks block into .zcode/config.json——the plugin manifest has already registered these hooks, and merging again would run the same event twice (PreToolUse intercepts twice, PostToolUse injects twice). Only merge hooks when the plugin is not installed (direct clone / manual import of references). When uncertain, use "whether ZCode has already registered this set of hooks via this plugin" as the standard; skills/commands/hook files/AGENTS and the non-hook fields of config are deployed as usual on both paths.
    • Merge hooks (only when the plugin is not installed): set hooks.enabled: true; if the user already has a larger timeoutMs then keep it, otherwise take the template value; for hooks.events 's SessionStart, PreToolUse, PostToolUse, follow event + matcher + process command + args Deduplicate and append; do not copy PreCompact, PostCompact, SessionEnd, or SubagentStop, which ZCode does not support, nor Notification.
  5. Write references/zcode/AGENTS.md.tmpl into the root AGENTS.md。
  6. .story-deployed of target_cli write zcode or a multi-target combination,references_dir write .zcode/skills/story-setup/references/agent-references。
  7. The installation report clearly states: ZCode 3.3.4 project/plugin custom agents do not execute, and all specialized roles go through solo/direct; the system needs an available node command to run project Hooks.

Plugin installation does not go through this algorithm: repository root .zcode-plugin/plugin.json directly exposes the same set of Skills/Commands/Hooks. Plugin Skills have lower priority than workspace .zcode/skills; when both exist, the project snapshot takes precedence, and upgrading the project snapshot requires rerunning $story-setup。Hooks can only be registered once: the plugin manifest and workspace .zcode/config.json register the same batch of events, so once the plugin is installed, do not merge the hooks of config.json.patch into .zcode/config.json(see the hooks mutual exclusion in step 4 of the above algorithm), otherwise PreToolUse/PostToolUse will trigger twice; when the plugin is present, the plugin manifest is the sole registration source for hooks.

TRAE hooks.json merge algorithm (when target_cli includes trae)

  1. Read references/trae/hooks/hooks.json as the sole current template, and read project .trae/hooks.json(treated as an empty object when absent). The valid TRAE schema is top-level { "version": 1, "hooks": {...} }, event values are matcher group arrays, within a group are matcher + hooks, and each hook uses only { "type": "command", "command": "<单一 shell command 字符串>", "timeout": <秒> }。
  2. Detect according to cross-platform rules python3/python/py; when no usable interpreter is available, stop the TRAE branch, and do not hand-write or wholesale overwrite the JSON.
  3. Invoke "$PYBIN" "{story-setup skill目录}/scripts/merge-trae-hooks.py" --existing "{项目}/.trae/hooks.json" --template "{story-setup skill目录}/references/trae/hooks/hooks.json" --output "{项目}/.trae/hooks.json". The helper recognizes only registrations whose command contains .trae/hooks/story_trae_hook.js as oh-story managed items: first remove them from historical event/matcher blocks, then append the current template. User hooks in the same matcher block, other events, and unknown top-level fields are all preserved.
  4. Validate after writing version == 1; event names may only come from the TRAE supported set SessionStart、UserPromptSubmit、PreToolUse、PostToolUse、Stop、Notification, and the current template must not contain SessionEnd、PreCompact、PostCompact、SubagentStop; within hooks, ZCode's process/args/timeoutMs or Claude's ifmust not appear. Body tool matchers cover TRAE native RunCommand|Write|Edit, commit advisory covers RunCommand。
  5. Verify that each oh-story command identity in the template appears exactly once in the result, and that user hooks/top-level fields are still present; running the helper again must produce byte-identical output to the previous run.

TRAE Code native deployment algorithm (when target_cli includes trae)

The TRAE branch deploys native Skills / Subagents / Commands / Rules / Hooks, and does not use the generic skills-only degraded mode.

  1. Confirm the fixed 18 Skills according to the "canonical Chinese main package Skill list". Before any writing, establish UTC-timestamped backups for the existing managed assets to be modified this time according to the "TRAE ownership and backup gate"; upon encountering files with the same name but without the oh-story-managed marker, retain them, record the conflict, and stop writing that asset.
  2. After passing each item through copy-path-safety.py , copy the 18 canonical Skills to .trae/skills/{skill-name}/. If the target is missing, create it; only if it is already an oh-story skill (SKILL.md 's metadata.openclaw.source points to this repository, or contains the exact marker <!-- oh-story-managed: skill/{skill-name} -->) may it be backed up and then replaced. An existing sentinel cannot substitute for ownership evidence of an individual Skill; without evidence, retain and report.status=same 's Skill only verifies, does not copy into itself.
  3. Deploy one by one for the 18 canonical names references/trae/commands/{name}.md; if any template is missing, stop as an incomplete deployment package, and do not generate fallback commands for the project's extra Skills. Only replace files with the same management marker.
  4. According to "Deploy TRAE Agents" and the "TRAE / WorkBuddy fixed Agent roster", deploy the exact union of the general 8 names and the TRAE data 5 names (13 files) to .trae/agents/. Only Agent built-in Agents can invoke sub-Agents; when the skill process encounters an unavailable sub-Agent, it must use the defined solo/direct fallback。
  5. Write references/trae/rules/*.md to .trae/rules/, only replacing files with the <!-- oh-story-managed: rule/... --> marker; TRAE rule frontmatter uses alwaysApply: false and globs, and does not copy Claude paths frontmatter. Write references/trae/AGENTS.md.tmpl according to the "AGENTS.md merge strategy" into the root AGENTS.md, only replacing the block between <!-- BEGIN oh-story-managed: trae --> and <!-- END oh-story-managed: trae --> , preserving the user's other paragraphs.
  6. Write references/trae/hooks/story_trae_hook.js and story_hook_core.js to .trae/hooks/; the runner only replaces files of the same name whose header comment proves them to be the oh-story TRAE adapter. For an existing shared core, it must first run trae-core-ownership.py --candidate <文件> --registry references/trae/legacy-managed-sha256.json, or prove byte-identity with a trusted sibling core in the same project; exit 3 (unmanaged)/2 (registry error) are both retained and reported, not overwritten. After replacement, run node --check and the cross-adapter byte-parity check, then merge according to the "TRAE hooks.json merge algorithm" .trae/hooks.json; it is forbidden to overwrite the user configuration wholesale with a template. Windows native RunCommand is provided by PowerShell, and the runner must simultaneously cover the tested static Set-Content、Add-Content、Out-File、Copy-Item、Move-Item、New-Item disk-write forms; dynamic expressions, splatting,.NET API, and unrecognized external programs are still covered by the Skill self-check and post-write backstop, and it must not claim that all PowerShell writes can be hard-blocked in PreToolUse.
  7. Verify that the managed name sets of .trae/skills/ and .trae/commands/ are both exactly equal to canonical 18, that the managed Agent name set is exactly equal to the TRAE 13-name union listed in the "TRAE / WorkBuddy fixed Agent roster", that the rule/hooks/AGENTS markers are complete, and that the hooks contract tests pass. The user's other .trae assets must still be present.
  8. .story-deployed 's target_cli writes trae or a multi-target combination,references_dir writes .trae/skills/story-setup/references/agent-references. The installation report lists the backup directory, conflicts/no-op, the 18 Skill / 18 Command / 13 Agent verification results, and Agent availability, and prompts the user to open a new TRAE session to refresh Skills / Commands / Rules / Subagents / Hooks.

WorkBuddy settings.json merge algorithm (when target_cli includes workbuddy)

  1. First determine whether this session has actually enabled the oh-story plugin: only accept that the currently executing Skill path is located under the CodeBuddy plugin installation root, that the runtime registry explicitly returns oh-story, or that an available codebuddy plugin list explicitly shows the plugin as enabled. A manifest in the repository, a disabled copy on disk, or the user saying verbally "I installed it" cannot substitute for runtime evidence.
  2. When the plugin is enabled, choose references/workbuddy/hooks/disabled-hooks.json; for project-local mode, choose references/workbuddy/hooks/project-hooks.json. Detect python3/python/pyaccording to cross-platform rules, and call merge-workbuddy-settings.py --existing {项目}/.codebuddy/settings.json --template <所选模板> --output {项目}/.codebuddy/settings.json; if there is no Python, stop the WorkBuddy branch and do not hand-write JSON.
  3. The helper only includes in the command story_workbuddy_hook.js is registered as an oh-story managed item: first remove it from all historical events/matchers, then append it according to the selected template. User hooks, permissions, models, MCP, and unknown top-level fields are all preserved; repeated execution must be byte-idempotent.
  4. project-local mode writes story_workbuddy_hook.js and story_hook_core.js into .codebuddy/hooks/, and confirms that each of the four current registrations occurs exactly once. plugin mode no longer registers a second set of project Hooks,.codebuddy/settings.json oh-story runner registrations must be zero. "Both copies produce identical output" must not be used to prove compatibility.
  5. Validate that Hook output uses only CodeBuddy-supported fields: all JSON output branches have top-level continue: true; PreToolUse denial uses hookSpecificOutput.permissionDecision=deny; commit reminders use top-level systemMessage; healthy no-op stdout is empty. matchers declare only tools already covered by the runner's target-resolution fixtures.

WorkBuddy / CodeBuddy Code native deployment algorithm (when target_cli contains workbuddy)

WorkBuddy Desktop embeds the CodeBuddy Code CLI; project mode natively discovers .codebuddy/skills/、.codebuddy/commands/、.codebuddy/agents/、.codebuddy/rules/ and .codebuddy/settings.json. It must not be downgraded to generic skills-only.

  1. Per the "canonical Chinese main package Skill list", copy the 18 Skills to .codebuddy/skills/{skill-name}/; replace only main package directories whose ownership can be proven by this repository's metadata or exact markers, and preserve the user's other Skills. When source and target are the same, record no-op.
  2. For each of the 18 canonical Skills, copy references/workbuddy/commands/{name}.md to .codebuddy/commands/{name}.md; if a template is missing, stop as the package is incomplete, and do not generate fallback commands for project extensions. Here these are project bare commands /story-*; the plugin manifest does not load this batch of Commands.
  3. Per "Deploy WorkBuddy Agents" and the "TRAE / WorkBuddy fixed Agent roster", deploy the exact union (10 cards) of the 8 generic names and the 2 WorkBuddy data physical names to .codebuddy/agents/; project cards use bare agent names, invoked by the Agent tool's subagent_type field. The four read-only logical data-analysis roles call the pooled runner by mapping, and the logical cards are not copied to the registry. The plugin-only name oh-story:<name> may be used only when the current registry actually returns it.
  4. Merge references/workbuddy/rules/*.md into .codebuddy/rules/, replacing only files with the same management marker; then handle the currently single effective memory file per the "WorkBuddy memory merge strategy". It is forbidden to use a very short CODEBUDDY file to obscure an existing AGENTS.md。
  5. Per the "WorkBuddy settings.json merge algorithm", choose the mutually exclusive project-local or plugin branch, and run the Node syntax, shared core byte-parity, Chinese body pre-write/post-write gates, and merge idempotency fixtures. On Windows, if PowerShell is used, only static write commands already covered by dedicated fixtures are hard gates; dynamic expressions, splatting, .NET APIs, or unrecognized external disk-writing programs must still rely on Skill self-checks and post-write fallbacks, and the installation report must not claim that "all PowerShell writes can be hard-intercepted".
  6. Validate that .codebuddy/skills/ and .codebuddy/commands/ 's managed name set is exactly equal to canonical 18, the managed Agent name set is exactly equal to the union of the WorkBuddy 10 names listed in the "TRAE / WorkBuddy fixed Agent roster", the rule/memory markers are unique, and the user's other .codebuddy assets are still present. Validate that the pooled runner's four logical role mappings are complete, unique, and point to real cards within the Skill; if the WorkBuddy embedded or standalone codebuddycan be found on this machine, also run at the repository root codebuddy plugin validate . Verify the plugin manifest; when a command is unavailable, explicitly record it as not executed, and do not falsely claim it passed.
  7. .story-deployed 's target_cli write workbuddy or multi-target combination,references_dir write .codebuddy/skills/story-setup/references/agent-references. The installation report separately lists: project command /story-*;plugin-only Skill /oh-story:story-*; the Hook's current sole registration source; Agent registry results; PowerShell hard-gate boundaries. After deployment, fully execute references/workbuddy/runtime-activation.md, open a new WorkBuddy / CodeBuddy session to refresh discovery results; when not actually confirmed in /skills、/agents、/hooks , only static/synthetic runtime pass may be reported.

Plugin installation does not go through the project copy algorithm: repository root .codebuddy-plugin/plugin.json is the only canonical manifest, all paths start with ./ , exposing only Skills, Agents, Hooks, and not Commands with the same names. Plugin hooks and project hooks must be mutually exclusive; even if project story-setup deployment of Skills/Commands/Agents/Rules is subsequently run, plugin hooks remain the sole registration source, and disabled-hooks.json is used to clear old project registrations.

Managed asset convergence and endpoint reduction (required for TRAE / WorkBuddy)

  1. Phase 1, before modifying target_cli , simultaneously save previous_targets and desired_targets. First complete deployment of the new endpoint and retirement of the removed endpoint; only after all verification passes may the sentinel be atomically written back; do not modify .story-deployed first and leave old assets that would still be discovered by the platform.
  2. When the target endpoint is still retained, name-set convergence must also be done: Skill / Command use canonical 18 as the sole roster, TRAE Agent uses the common 8 names listed in "TRAE / WorkBuddy fixed Agent roster" + the 5 TRAE data names (13 total) as the sole roster, and WorkBuddy Agent uses the common 8 names listed in the same section + the 2 physical WorkBuddy data names (10 total) as the sole roster. List as stale managed assets any Skill / Command / Agent / Rule that has an existing exact management marker/repository metadata but is no longer in the corresponding exact name set. Back up first, then delete only these stale items whose attribution can be proven; items with the same name but no marker are never deleted. After deletion, remove an empty directory only when the directory is truly empty.
  3. When removing previous_targets from trae :
    • For the .trae/ managed assets about to be changed, create .trae/.oh-story-backups/<UTC时间戳>/ full relative-path backup;
    • use merge-trae-hooks.py --template references/trae/hooks/disabled-hooks.json to remove from .trae/hooks.json and remove only story_trae_hook.js registration, preserve user hooks/top-level fields, and rerun to confirm byte idempotence;
    • delete only the .trae/skills、commands、agents、rules managed items and the two management hook scripts that can be proven by this section's attribution gate; from AGENTS.md remove only the TRAE BEGIN/END management block.
  4. When removing previous_targets from workbuddy :
    • First back up the project management assets about to be changed to .codebuddy/.oh-story-backups/<UTC时间戳>/;
    • Use merge-workbuddy-settings.py --template references/workbuddy/hooks/disabled-hooks.json to remove from .codebuddy/settings.json the project oh-story Hook registration, leave user settings and hooks untouched, and rerun to confirm byte idempotence;
    • delete only .codebuddy/skills、commands、agents、rules managed items and project hook scripts with exact attribution evidence; from the current sole memory file remove only the WorkBuddy BEGIN/END block. If that memory file was created by story-setup and only whitespace remains after removal, it may be deleted after backup; otherwise keep it.
    • Project endpoint reduction does not equal uninstalling user-level/plugin-level oh-story; an enabled plugin is uninstalled only separately via the CodeBuddy plugin management command.
  5. The two project runners must also check the sentinel at every event entry: if a valid target_cli exists and does not contain the current end, immediately return success with empty stdout. This is the defense line for mid-way failures and cannot replace the aforementioned physical registration/discovery asset cleanup.
  6. Retirement acceptance must simultaneously prove: managed Hook registrations are 0; managed Skill/Command/Agent/Rule/memory blocks are no longer discovered by the target platform; user asset bytes are unchanged; the backup can be rolled back; running again is a no-op. If any item fails, do not update the sentinel, and report the partial retirement path.

OpenClaw skills-only deployment algorithm (when target_cli contains openclaw)

OpenClaw Phase 1 deploys only skills, not OpenClaw agents/hooks/plugin.

  1. Read the fixed 18 Skill directories according to the "canonical Chinese main package Skill list".
  2. Write to the target project skills/{skill-name}/, replacing only these 18 story-setup managed directories; retain the user's other directories under skills/ , and do not inject them into the Chinese main package.
  3. Each SKILL.md must satisfy the OpenClaw frontmatter constraints:name / description is a single-line key-value,metadata is a single-line JSON object and contains metadata.openclaw。
  4. Copy skills/story-setup/references/openclaw/AGENTS.md.tmpl to the project AGENTS.md, and merge according to the "AGENTS.md merge strategy".
  5. .story-deployed 's target_cli write to openclaw or a multi-end combination;references_dir for OpenClaw write skills/story-setup/references/agent-references。
  6. Installation report prompt items are in Phase 3 Step 12.

Reasonix skills-only deployment algorithm (when target_cli contains reasonix)

Reasonix (DeepSeek-Reasonix CLI) currently deploys only skills and AGENTS.md, not Reasonix hooks/custom agents (the hook I/O contract and sub-agent behavior lack a verifiable real CLI, left for a later phase).

  1. Copy the fixed 18 Skills to the target project according to the "canonical Chinese main package Skill list" skills/{skill-name}/; replace only these known directories managed by story-setup, and retain the user's other directories.
  2. Create at the project root .agents/skills → ../skills a relative symlink (the skill root shared with Codex), so that when Reasonix natively scans .agents/skills it discovers these skills; if it is already a symlink pointing to skills/ keep it, and if it is occupied as a normal directory do not overwrite it and prompt in the installation report. When symlinks are not enabled on Windows, skip this step and instead go through the root reasonix-plugin.json 's reasonix plugin install。
  3. Copy skills/story-setup/references/reasonix/AGENTS.md.tmpl to the project AGENTS.md, and merge according to the "AGENTS.md merge strategy".
  4. Verify skills/story-setup/references/agent-references/ has been copied into place along with the complete story-setup skill. If the current execution source is the same path within the project, the safety precheck returns same, and this step must be a no-op; copying the directory into itself again is prohibited.
  5. .story-deployed 's target_cli write to reasonix or a multi-end combination;references_dir for Reasonix write skills/story-setup/references/agent-references。
  6. Installation report prompt items are in Phase 3 Step 14.

Generic Web AI / other Agent deployment algorithm (when target_cli contains generic)

The generic path targets environments that can read project files, such as NarraFork, Web AI, and custom Agents, and deploys only generic files, without declaring platform-native hooks/agents capabilities.

  1. Copy the fixed 18 Skills to the target project according to the "canonical Chinese main package Skill list" skills/{skill-name}/; replace only these known directories managed by story-setup, and retain the user's other directories.
  2. Copy skills/story-setup/references/generic/AGENTS.md.tmpl to the project AGENTS.md, and merge according to the "AGENTS.md merge strategy".
  3. Verify that skills/story-setup/references/agent-references/ has been copied into place along with the complete story-setup skill. If the current execution source is the same path within the project, the safety precheck returns same, and this step must be a no-op; it is forbidden to copy the directory into itself again.
  4. .story-deployed 's target_cli write generic or a multi-target combination;references_dir for generic, write skills/story-setup/references/agent-references。
  5. See Phase 3 Step 13 for installation report reminder items.

Step 8: Create deployment marker

  • Create the .story-deployed file (sentinel file)
  • Write the following fields (YAML key: value format, read by the hook using references/templates/hooks/lib/sentinel.sh ):
    deployed_at: <date -u +"%Y-%m-%dT%H:%M:%SZ">
    agents_version: 39
    setup_skill_version: 1.2.22
    target_cli: claude-code(或 opencode、codex、zcode、trae、workbuddy、openclaw、reasonix、generic,或其任意组合)
    resolver_strategy: project-local-skill-reference
    references_dir: .claude/skills/story-setup/references/agent-references(Codex 写 .codex/skills/...;ZCode 写 .zcode/skills/...;TRAE 写 .trae/skills/...;WorkBuddy 写 .codebuddy/skills/...;OpenClaw / Reasonix / generic 写 skills/...;多端用逗号分隔)
    
  • This file is used by session-start.sh and the writing skills to detect deployment status and avoid repeated reminders
  • When target_cli includes claude-code, also create a one-time marker file .claude/.agents-pending-restart(an empty file is sufficient). At the start of the next session, session-start.sh uses it to confirm that agents have been registered with the new session and automatically deletes the marker—used to confirm to the user that "the restart has taken effect." ZCode does not create this marker because it does not deploy project agents.
  • If .story-deployed already exists but agents_version is missing, non-integer, or less than 39, update hooks/agents/rules/reference bundle according to this flow (see UPGRADING.mdfor specific changes); if it is greater than 39 , execution has already stopped in Phase 1 and must not be overwritten with a downgrade

Phase 3: Verify installation

  1. Verify hooks registration:
    • Check whether the hooks field in .claude/settings.local.json is correct
    • Check whether the scripts under .claude/hooks/ exist and have execute permission
    • Check whether .claude/hooks/lib/common.sh and .claude/hooks/lib/sentinel.sh exist
  2. Verify rules paths:
    • Check whether the rule files under .claude/rules/ exist and contain paths frontmatter
  3. Verify agents:
    • Check whether the 8 agent definition files under .claude/agents/ exist
  4. Verify agent reference bundle:
    • Check that 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
  5. Verify deployment marker:
    • Check whether .story-deployed exists and contains a timestamp,agents_version: 39、setup_skill_version: 1.2.22、target_cli、resolver_strategy、references_dir
  6. Output installation report:
    • List all deployed files
    • List items that need attention (such as existing configurations that have been merged)
    • ⚠️ Restart reminder (must be output prominently): this deployment wrote .claude/agents/, but these custom agents are only registered by Claude Code as subagent_type。Please start a new Claude Code session before you begin writing, otherwise in the current session, when story-review / story-long-write etc. try to spawn story-architect、narrative-writer etc., they will get "subagent_type unavailable" and fall back to solo (single perspective, losing multi-agent collaboration). To determine whether it has taken effect: run /story-reviewin a new session. If the report header is Effective Mode: full/lean , registration succeeded; if it is Fallback: ... -> solo Note that it is still in an old session or not registered.
    • It can be used after restart /story-long-write or /story-short-write
    • If "Configure OpenCode Agent Model" was executed, output the Agent model configuration summary:
      Agent 模型配置:
        story-architect          → <高端模型>(provider/model-id)
        narrative-writer         → <中端模型>(provider/model-id)
        character-designer       → <中端模型>(provider/model-id)
        story-researcher         → <中端模型>(provider/model-id)
        revision-governor        → <中端模型>(provider/model-id)
        chapter-extractor        → <低端模型>(provider/model-id)
        consistency-checker      → <低端模型>(provider/model-id)
        story-explorer           → <低端模型>(provider/model-id)
      
    • If automatic detection fails (opencode models unavailable), output the manual configuration guide:
      无法自动检测模型列表。以下 Agent 未配置模型,将使用主模型,成本可能较高:
        - chapter-extractor(建议使用低成本模型)
        - consistency-checker(建议使用低成本模型)
        - story-explorer(建议使用低成本模型)
      
      手动配置方法:编辑 .opencode/agents/{agent名}.md,在 frontmatter 中添加:
        model: provider/model-id
      
      可用模型列表与成本可通过 opencode models --verbose 查看(输出含每模型 cost/context)。
      模型库与定价见 OpenCode 官方模型源 https://models.dev/。
      
  7. Verify the opencode deployment (only when target_cli contains opencode):
    • Check whether .opencode/agents/ the 8 agent definition files under exist, and whether the frontmatter contains mode: subagent and permission fields
    • Check whether .opencode/plugins/story-hooks.ts exists
    • Check whether .opencode/plugins/lib/story_hook_core.js exists and node --check passes (story-hooks.ts imports it, the shared body-writing guard core byte-identical to the .zcode copy; placed in the lib/ subdirectory to avoid OpenCode single-level .opencode/plugins/*.js plugin auto-discovery)
    • Check whether .opencode/commands/ the command name set under matches the current OpenCode template manifest
    • Check whether skills/story-setup/references/agent-references/ the reference files under are complete and the count matches the source directory
    • Check whether opencode.json the plugin array contains the story-hooks entry
    • Check whether .git/hooks/pre-commit exists and has execute permission (skip the execute permission check on Windows)
    • Check whether .opencode/agents/ the agent file frontmatter under can be parsed by YAML, andmodel:(if configured) is a valid top-level scalar, rather than merely grepping the model: substring
  8. Verify the Codex deployment (only when target_cli contains codex):
    • Check whether AGENTS.md contains the Codex story skill routing sections
    • Check whether .codex/agents/ the 8 .toml agent definition files under exist and can be parsed
    • Check whether .codex/hooks.json exists and the JSON is valid, Unix command only started via run-story-hook.sh , Windows commandWindows only started via run-story-hook.cmd , there is no registration that directly calls story_codex_hook.py registration of
    • Check whether .codex/hooks/story_codex_hook.py、run-story-hook.sh、run-story-hook.cmd exists, the Python syntax is valid, and the POSIX/Windows launcher can locate the project root from a nested cwd
    • Check whether .codex/skills/story-setup/references/agent-references/ the reference files under are complete and the count matches the source directory
    • The installation report must indicate: Codex requires trusting the project .codex/ configuration layer, and at /hooks review/trust non-managed hooks; after deployment, open a new Codex session for the custom agents to take effect; if the current runtime still returns unknown agent_type, degrade to solo/direct according to each skill's fallback rules
  9. Verify the ZCode deployment (only when target_cli contains zcode):
    • Check whether the root AGENTS.md contains the ZCode $story-* routing, outline guard, and solo/direct fallback
    • Check according to the "canonical Chinese main package Skill manifest" whether .zcode/skills/ and .zcode/commands/ are exactly 18 names, and verify that the frontmatter and naming are consistent
    • Check whether .zcode/hooks/story_zcode_hook.js、.zcode/hooks/story_hook_core.js exists and node --check passes
    • Check .zcode/config.json JSON is valid, and validate according to the hooks mutual-exclusion branch in Step 4 of the "ZCode Deployment Algorithm": when the oh-story plugin is not installed,hooks.enabled=true, register only ZCode-supported events, and all process args point to the project Hook; when the oh-story plugin is installed (.zcode-plugin/plugin.json has globally registered this batch of hooks), instead validate that .zcode/config.json does not contain (or has removed) this batch of oh-story hooks registrations——must notmerge the config.json.patch hooks block back in just to make validation pass, otherwise the same event will be triggered twice
    • Check .zcode/skills/story-setup/references/agent-references/ is complete and all reference paths are resolvable
    • Use fixtures to invoke SessionStart, PreToolUse deny/allow, and PostToolUse, confirming that stdout is empty when there are no findings, and that output conforms to ZCode strict JSON when there is output
    • The installation report must note: ZCode 3.3.4 does not execute project/plugin custom agents, and full/lean multi-Agent requests will reliably degrade to solo/direct; Hooks depend on nodein PATH; after deployment, open a new ZCode session to refresh Skills/Commands/AGENTS.md
  10. Verify TRAE Code deployment (only when target_cli contains trae):
    • Check that root AGENTS.md has only one complete oh-story-managed: trae management block, and the user's other sections are still present
    • Check that the managed name sets of .trae/skills/ and .trae/commands/ are both exactly equal to canonical 18; each skill has SKILL.md, and each command has name / description and oh-story-managed markers
    • Check that the managed name set of .trae/agents/ is exactly equal to the 8 generic names + 5 TRAE data names (13 total) listed in the "TRAE / WorkBuddy Fixed Agent Roster", frontmatter is parseable,name is unique, there are no Claude-only fields, and management markers are complete
    • Check that the management files of .trae/rules/ contain alwaysApply / globs, and do not contain Claude paths frontmatter
    • Check that .trae/hooks/story_trae_hook.js、story_hook_core.js exists and node --check passes;.trae/hooks.json is version: 1, uses only TRAE-supported events and the {type,command,timeout} hook schema, matcher covers RunCommand|Write|Edit, and SubagentStop
    • Use fixtures to invoke SessionStart, PreToolUse deny/allow, and PostToolUse, confirming that stdout is empty when there are no findings, and that output conforms to TRAE hookSpecificOutput; rerun merge-trae-hooks.py to confirm user hooks/unknown fields are preserved and byte-idempotent
    • Check that the oh-story command in .claude/settings*.json remains a direct bash ...(must not embed a POSIX-only parseable if); all Claude entrypoints source TRAE_PROJECT_DIR which contains lib/common.shsilent-exit logic. Use the same PreToolUse fixture to prove that the Claude-imported Hook produces no output under TRAE, and the TRAE native Hook executes only once
    • The installation report must list .trae/.oh-story-backups/ the backup location for this run and any conflicts/no-ops, and note: review/enable this project's Hooks on the Hooks page in TRAE Settings, and confirm the project AGENTS.md / Rules import enabled, then open a new TRAE session to refresh native Skills / Commands / Rules / Subagents / Hooks; if Subagents Beta is unavailable, full/lean multi-Agent requests must report Fallback: TRAE subagent unavailable -> solo/direct
  11. Verify WorkBuddy / CodeBuddy Code deployment (only when target_cli contains workbuddy):
    • Check whether the managed name sets of .codebuddy/skills/ and .codebuddy/commands/ are exactly equal to canonical 18; each command has valid frontmatter and management markers
    • Check whether the managed name set of .codebuddy/agents/ is exactly equal to the general 8 names listed in the "TRAE / WorkBuddy fixed Agent roster" + WorkBuddy data physical 2 names (10 cards total), with a total of no more than 19, unique names, and frontmatter using only CodeBuddy-supported fields; each logical role of the pooled runner must map uniquely to a real card within a Skill. In a new session, actually invoke the base Agent,story-data-fetcher and one logical role of the pooled runner separately; only after success may you report that multi-Agent mode is in effect; the settings page "enable all" cannot replace Task registry evidence
    • Check the management block of .codebuddy/rules/ and the uniquely effective memory file; the project's original AGENTS.md content must still be read directly or imported via @AGENTS.md / @../AGENTS.md , and template conditional placeholders must not remain; when both root and .codebuddy/ two CODEBUDDY files exist, a conflict must be reported rather than guessing the priority
    • Check whether .codebuddy/settings.json preserves user fields, and verify by mutually exclusive branches: in project-local mode the current 4 oh-story Hook registrations each appear exactly once, with events only SessionStart / PreToolUse / PostToolUse; in plugin mode project registrations are zero. Running the helper twice must be byte-idempotent
    • Use fixtures to invoke SessionStart (including agents_version 38/39/40), PreToolUse deny/allow/commit, and PostToolUse; confirm that healthy no-op stdout is empty and all output has continue: true, that deny and reminder fields conform to the CodeBuddy schema, and that path escapes cannot bypass the project root
    • Check that the plugin manifest does not contain a commands field with the same name as Skills, and that all custom paths start with ./ ; if available, run real codebuddy plugin validate .. The installation report clearly states the project /story-* and plugin /oh-story:story-* differences, the sole Hook source, the PowerShell hard-gate boundary, and prompts to open a new session
  12. Verify OpenClaw deployment (only when target_cli contains openclaw):
    • Check whether AGENTS.md contains OpenClaw story skill routing sections
    • According to the "canonical Chinese main package Skill list", check the fixed 18 target Skills under skills/ , and that each SKILL.md contains a single-line name, a single-line description, and single-line JSON metadata.openclaw
    • Check whether the reference files under skills/story-setup/references/agent-references/ are complete and the count matches the source directory
    • The installation report must state: OpenClaw Phase 1 is skills-only; OpenClaw agents/hooks are not deployed, runtime hard interception is unavailable, and the outline guard before writing body text, commit reminders, and session/compact automatic injection serve only as soft constraints within skills; OpenClaw snapshots eligible skills at session startup, so after deployment, if commands/skills do not appear, a new OpenClaw session must be opened or you must wait for the skills watcher to refresh
  13. Verify generic Web AI / other Agent deployment (only when target_cli contains generic):
    • Check AGENTS.md contains generic story skill routing sections
    • According to the "canonical Chinese main package Skill list", check skills/ for the fixed 18 target Skills, and each SKILL.md is readable
    • Check skills/story-setup/references/agent-references/ for complete reference files with a count matching the source directory
    • The installation report must state: generic does not deploy platform-specific hooks/custom agents; hard blocks such as outline guard, commit reminders, session/compact injection, and multi-agent collaboration are all executed as soft constraints within the skill or via solo/direct fallback
  14. Verify Reasonix deployment (only when target_cli includes reasonix):
    • Check AGENTS.md contains Reasonix story skill routing sections and solo/direct fallback instructions
    • According to the "canonical Chinese main package Skill list", check skills/ for the fixed 18 target Skills, and each SKILL.md is readable
    • Check that project .agents/skills is a symlink pointing to skills/ (POSIX; enables Reasonix native scanning to discover skills); when the symlink is not created on Windows, instead confirm that the root reasonix-plugin.json can be used for reasonix plugin install
    • Check skills/story-setup/references/agent-references/ for complete reference files with a count matching the source directory
    • The installation report must state: Reasonix is currently skills-only; Reasonix hooks/custom agents are not deployed, so before writing the main text the outline guard, commit reminders, and session/compact auto-injection only exist as soft constraints within the skill, and Skills involving specialized Agents use solo/direct fallback; you can use reasonix doctor capabilities to verify skill discovery, and after deployment if the new skills are not displayed, open a new Reasonix session or use the root reasonix-plugin.json native plugin installation

Template placeholder

Placeholder Replacement rule Example
{项目名} User project name or directory name "Sword Comes", "Hidden Guard"
{书名} Book title directory name (consistent with the directory) Same as {项目名} , or user-defined
{目标平台} Target publishing platform Qidian, Fanqie, Jinjiang, Zhihu Yanyan
{作者名} User pen name or nickname When unspecified, use "Author"

Remove the curly braces when replacing. If the user does not specify a project name, use the current directory name. Unspecified placeholders are left as-is and not replaced.

CLAUDE.md merge strategy

When the user already has a CLAUDE.md, merge by marker/section:

  1. Prefer to identify the story-setup managed block marker (if an old project already has the marker, only replace the content inside the marker)
  2. When there is no marker, read the user's existing CLAUDE.md and split it into a section map by ## heading
  3. Read the template CLAUDE.md.tmpl and split it in the same way
  4. Standard sections in the template (Skill routing table, file structure, collaboration rules, restore context after Compact)overwritethe user's section with the same name
  5. Sections unique to the user (custom content)retainleave unchanged
  6. For unknown conflicts, use AskUserQuestion to let the user choose which version to keep

AGENTS.md merge strategy (OpenCode / Codex / ZCode / TRAE Code / OpenClaw / Reasonix / generic)

When the user already has AGENTS.md, merge by marker/section:

  1. Prioritize identifying the story-setup management block marker (if the old project already has the marker, only replace the content inside the marker)
  2. When there is no marker, read the user's existing AGENTS.md and split it by ## headings into a section map
  3. 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; TRAE Code uses skills/story-setup/references/trae/AGENTS.md.tmpl(only replace the oh-story-managed: trae marker block); OpenClaw uses skills/story-setup/references/openclaw/AGENTS.md.tmpl; Reasonix uses skills/story-setup/references/reasonix/AGENTS.md.tmpl; general-purpose Web AI / other Agents use skills/story-setup/references/generic/AGENTS.md.tmpl
  4. the template's standard sections (Skill routing table, file structure, collaboration rules, context recovery after Compact) override sections with the same name; user-unique sections are preserved
  5. When deploying to multiple platforms simultaneously, keep only one copy of the common paragraphs usable by Codex/OpenCode/ZCode/TRAE/OpenClaw/Reasonix/generic; distinguish tool-specific notes with subsections or platform management markers to avoid overwriting each other

WorkBuddy memory merge strategy

CodeBuddy treats the root CODEBUDDY.md and .codebuddy/CODEBUDDY.md as project memory, and only falls back to reading AGENTS.mdwhen there is no CODEBUDDY memory. Therefore, a short template must not be unconditionally created to shadow existing common conventions.

  1. Also check the root CODEBUDDY.md、.codebuddy/CODEBUDDY.md and the root AGENTS.md. If both CODEBUDDY copies exist, stop memory writing and report the conflict, asking the user to choose a single canonical location; do not guess the loading priority, and do not delete either copy. Other WorkBuddy assets may continue to be verified, but the installation report must be marked as memory not closed-loop.
  2. When only one CODEBUDDY copy exists, marker-merge the WorkBuddy management block in place; if AGENTS.mdalso exists, replace the template placeholder {{OH_STORY_AGENTS_IMPORT}} according to the target location with the root file's @AGENTS.md or the .codebuddy file's @../AGENTS.md, ensuring the original common conventions still enter the context. When there is no AGENTS, replace with a blank line.
  3. When neither CODEBUDDY copy exists but AGENTS.md already exists, directly merge the WorkBuddy management block into the existing AGENTS.md, and replace the import placeholder with blank; do not create a new CODEBUDDY file, thereby continuing to use CodeBuddy's AGENTS fallback.
  4. When none of the three exists, create .codebuddy/CODEBUDDY.md, replacing the import placeholder with blank. All branches only replace the text inside BEGIN/END oh-story-managed: workbuddy , preserving user-unique content.
  5. Post-write verification: exactly one management block;{{OH_STORY_AGENTS_IMPORT}} must not remain; when an existing AGENTS is present and CODEBUDDY is ultimately used, the correct relative import must be present; merging again is byte-idempotent.

Redeploy

  • .story-deployed does not exist → fresh install, execute all of Phase 2
  • .story-deployed exists and agents_version: 39 → prompt that it is already deployed, AskUserQuestion to confirm whether to redeploy; state in the prompt that redeployment only uses the current local skill package to refresh project files, while formal updates to the skill itself go through the fixed GitHub Release asset:npx skills add https://github.com/qin1473692580-ux/oh-story-claudecode/releases/latest/download/oh-story-release.zip -y -g
  • .story-deployed exists but agents_version is missing, not an integer, or less than 39 → prompt that an update is needed, re-execute Phase 2 to refresh the agents/hooks/rules/reference bundle managed by story-setup; CLAUDE.md / AGENTS.md / CODEBUDDY.md / settings.local.json / .codex/hooks.json / .zcode/config.json / .trae/hooks.json / .codebuddy/settings.json follow the merge strategy; back up TRAE managed assets first; re-evaluate WorkBuddy hooks for plugin/project mutual exclusion
  • .story-deployed exists and agents_version is greater than 39 → current skill version is too old, stop and prompt to update oh-story-claudecode first; do not overwrite the project's updated deployment

Reference Materials

File Purpose
references/templates/hooks/ 8 hook script templates + story_hook_core.js(shared implementation for main-text network/word count/outline guard/continuity/commit detection, the same copy as OpenCode/ZCode) + story_hook_cli.js(node bridge for bash hook to call the core) + lib/common.sh/lib/sentinel.sh(check-prose-after-write.sh handles the PostToolUse fallback for Write/Edit; Bash redirection,tee、touch、cp、mv、install main-text writing is best-effort recognized by the shared PreToolUse core and executes the outline/tracking gate; unrecognized Bash writes are still covered by the Codex Stop end-of-turn git scan)
references/templates/rules/ 4 path-scoped rule templates
references/templates/agents/ 8 agent definition templates (story-architect, character-designer, narrative-writer, consistency-checker, revision-governor, story-researcher, story-explorer, chapter-extractor)
references/agent-references/ Reference material copies included with Agent templates; deploy to .claude/skills/story-setup/references/agent-references/to avoid cross-skill references
references/templates/settings-hooks.json hooks registration JSON fragment
references/templates/inspection progress.md.tmpl Per-chapter Phase 5 QC sub-item completion status table, mechanically checkable
references/codex/AGENTS.md.tmpl Codex project root AGENTS.md template
references/codex/agents/ 8 Codex custom agent TOML templates
references/codex/hooks/hooks.json Codex hooks registration JSON template (deploy to .codex/hooks.json)
references/codex/hooks/story_codex_hook.py Codex hook adapter (deploy to .codex/hooks/story_codex_hook.py)
references/openclaw/AGENTS.md.tmpl OpenClaw project root AGENTS.md template (skills-only)
references/generic/AGENTS.md.tmpl Generic Web AI / other Agent project root AGENTS.md template (skills + soft checks)
references/zcode/ ZCode AGENTS, Commands, workspace config patch and strict JSON Hook runner
references/trae/ TRAE Code native AGENTS, Commands, Agents, Rules and Hooks adapter
scripts/merge-trae-hooks.py Merge by stable command identity .trae/hooks.json, preserving user configuration
scripts/trae-core-ownership.py + references/trae/legacy-managed-sha256.json Before overwriting the TRAE shared core, classify ownership precisely by marker / old-version SHA; fail closed on unknown files
references/workbuddy/ WorkBuddy / CodeBuddy Code native memory templates, project Commands, Agents, Rules and Hooks adapter; plugin-mode Skills/Agents/Hooks also reuse these verified artifacts
scripts/merge-workbuddy-settings.py Merge or remove project Hooks in .codebuddy/settings.json by stable runner identity, preserving user configuration and ensuring plugin/project mutual exclusivity
Repository root .codebuddy-plugin/plugin.json CodeBuddy plugin specification manifest; expose only Skills, Agents, Hooks to avoid conflicts with same-named Commands
Repository root scripts/generate-workbuddy-adapter.py During maintenance, deterministically generate WorkBuddy artifacts from the reviewed TRAE roles/commands and shared core; not delivered with project deployment

Process Handoff

Pipeline: Deploy Location: initialization (frontmost)

Timing Jump to Command
Deployment complete, start writing story-long-write / story-short-write /story-long-write or /story-short-write
Import an existing novel for breakdown story-import /story-import
Requires browser login state (ranking scan/breakdown text retrieval) browser-cdp /browser-cdp; generic requires the platform to allow local scripts/browser control

Invocation syntax per platform: Claude /名、Codex/ZCode $名、TRAE Code /名, WorkBuddy project mode /名, WorkBuddy plugin-only mode /oh-story:名、OpenClaw /skill 名, Reasonix / generic directly naming the skill.