posthog/author-stepwise-skill
Scaffold a new context-mill skill that walks an agent through an ordered series of narrowly-scoped reference files. Works for any number of steps. Use when the user wants to add a docs-only skill where the agent must read each step in strict order, one at a time, with each step isolated, with clear endpoints, and no prefetching.
npx skills add https://github.com/PostHog/context-mill --skill author-stepwise-skill
This skill scaffolds a multistep skill. A docs-only context-mill skill made of an ordered chain of reference files. The agent reads one file at a time and never sees later files until it finishes the current one.
This shape gives you three things:
Use the multistep pattern when all of these are true:
If the skill is just a bag of related references that the agent can read in any order, do not use this shape. Use a flat docs-only skill. Extra ceremony hurts.
The mechanics that follow (references.preamble, per-file next_step, "do not Glob/ls/find", "do not preload", "do not re-read earlier files") make progressive disclosure the path of least resistance. Do not weaken them. A step that says "for context, also read X" defeats the pattern.
Keep the scope tight:
# Heading should name a single goal. If you need "and" or a comma, it is two steps.<location>" is. You should be able to verify that the step has completed and is correct by some condition, test, or tool call.If you find yourself wanting to add "context" or "background" to help the agent decide, the step is not tight enough. Decide for the agent at authoring time. Do not push the decision into the run.
context/skills/<group>/
├── config.yaml
├── description.md # SKILL.md template (entry point)
└── references/
├── 1-<step-name>.md # frontmatter: next_step: 2-<step-name>.md
├── 2-<step-name>.md # frontmatter: next_step: 3-<step-name>.md
├── …
└── N-<step-name>.md # frontmatter: next_step: null (terminal)
<group> is the directory name. With a single id: all variant it also becomes the generated skill ID.
config.yamltype: docs-only
template: description.md
description: <one-line description for SKILL.md frontmatter>
tags: [<tag>]
references:
preamble: "**Read ONLY this file.** Do not read any other reference file until this one tells you to."
shared_docs: [] # optional. PostHog doc URLs every step can rely on.
variants:
- id: all
display_name: <human title>
tags: [<tag>]
docs_urls: []
The build injects references.preamble after the first # Heading of every reference file that has a next_step. It also appends a Upon completion, continue with: <next> link at the bottom. The terminal file (with next_step: null) gets neither.
Non-terminal step:
---
next_step: 2-<step-name>.md
---
# Step 1: <narrow goal>
<one paragraph: what this step does, what it does NOT do, and what the previous step has already settled.>
…step body…
Terminal step:
---
next_step: null
---
# Step N: <final goal>
…step body…
Notes:
next_step is the filename relative to references/. Not a path.next_step. A file with no frontmatter is treated as a standalone reference (no preamble, no link). Fine for one-off references, wrong for a chain.description.md (SKILL.md template)The entry point. Keep it short. The real work lives in the reference chain. It must:
references/1-<step-name>.md by exact path. Forbid Glob, ls, and find on the skill directory. Forbid preloading future steps.[STATUS] and [ABORT] conventions (see next section) so each step can use them.{commandments} to inherit the framework guidelines for the skill's tags.The wizard runner reads two prefixed line patterns from the agent's output:
[STATUS] <message> updates the live "Working on…" banner. Use these often. They are cheap. Each step file should list the exact [STATUS] strings to emit at each sub-step (for example, [STATUS] Scanning manifests, [STATUS] Writing report).[ABORT] <reason> terminates the run. The runner catches this and stops. Use it for unrecoverable preconditions (no SDK found, missing credentials, etc.). The agent does not need to halt itself after emitting [ABORT].Declare both in description.md so every step can rely on them. Then list the specific [STATUS] strings (and any [ABORT] reasons) inline in each step file at the points they apply. Existing skills like revenue-analytics/ and quack/ show the shape.
npm run build
Unzip dist/skills/<group>.zip and confirm the chain is intact: non-terminal references have the preamble and continuation link, the terminal has neither.
npm test
Should stay green. The reference-folder test (scripts/lib/tests/skill-generator-references-folder.test.js) covers the copy path.
revenue-analytics/ and quack/ for shape.next_step is a single filename. If a step has two follow-ups, split into two skills, or have step N enumerate the choices and let step N+1 handle both.error-tracking/ and feature-flags/ do not use references/ chains. Use this shape only when sequencing matters.A minimal chain has two files: an opener and a terminal step. The shape generalizes to N steps by inserting more files in the middle.
context/skills/example-stepwise/
├── config.yaml
├── description.md
└── references/
├── 1-discover.md
└── 2-emit.md
config.yamltype: docs-only
template: description.md
description: Two-step example skill. Discover, then emit.
tags: [example]
references:
preamble: "**Read ONLY this file.** Follow its contents in sequence. Do not read any other reference file until this one tells you to."
shared_docs: []
variants:
- id: all
display_name: Example stepwise skill
tags: [example]
docs_urls: []
description.md (becomes SKILL.md)# Example stepwise skill
This skill walks the agent through a two-step task. First discover the target. Then emit the result.
**Start by reading `references/1-discover.md`.** Do not Glob, ls, or find the skill directory. Do not preload `2-emit.md`.
Each step persists its output to `<known-location>` so the next step can read it without re-opening earlier step files.
## Status
Report progress with `[STATUS]` prefixed messages. Each step lists the exact strings to emit.
## Abort
Report unrecoverable failures with `[ABORT] <reason>`. The runner terminates the run. Do not halt yourself.
- No target found
## Reference files
{references}
## Framework guidelines
{commandments}
references/1-discover.md---
next_step: 2-emit.md
---
# Step 1: Discover the target
This step locates the target and writes its identifier to `<known-location>`. It does NOT format, transform, or emit the result. That belongs to step 2.
Emit `[STATUS] Locating target` at the start of the search. If no target exists, emit `[ABORT] No target found` and stop.
…step body, ending with a single tool call or write that produces the target identifier…
references/2-emit.md---
next_step: null
---
# Step 2: Emit the result
The target identifier is at `<known-location>` (written by step 1 into `targets.json`). This step formats and emits the result into a markdown file. Do not re-read step 1.
…step body, ending with the final emission…
Take posthog/author-stepwise-skill from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.