plan-small
Plan a single-PR change end-to-end before writing code. Writes a terse `.plans/<slug>/plan.html` (HTML, with inline UI mockups where a screen changes, rendered through the shared design system) covering files to touch, data-model changes, edge cases, verification, and decisions/assumptions sourced to code or user. Use whenever the user says "plan this", "scope this out", "write up a plan for X", "/plan-small", "let's plan the new flag", or "plan before we start". Also use whenever the user describes a small feature without explicitly asking to plan — propose a plan before coding. Asks only what code can't answer (in-repo PRDs count), surfaces planned assumptions alongside questions, then runs a blind self-review subagent before presenting. Do NOT use for multi-PR work, schema migrations beyond adding a nullable column, or sequenced increments — bail to `plan-large` at Step 0. Do NOT use to start implementing — that's `/implement-plan` after the plan is approved.
适合你,如果你希望每次改动前都先明确方案再动手
npx oh-my-skill add hawkyre/hawk-skills/plan-smallcurl -fsSL https://oh-my-skill.com/install.sh | bash -s -- hawkyre/hawk-skills/plan-smallnpx oh-my-skill verify hawkyre/hawk-skills/plan-small怎么用
商店整理自技能原文 · 版本 6ffb2d6 · 表述以原文为准在写代码前,Claude 会先制定一个详细计划,生成 HTML 文件,列出要修改的文件、数据模型变化、边界情况、验证方法及决策依据,并自动进行自我审查。
当你说出“plan this”、“scope this out”等关键词,或描述一个小功能时,Claude 会主动提议先做计划再写代码。
技能原文 SKILL.md
Plan a Small Feature
Output: a terse .plans/<slug>/plan.html an implementer can execute in a fresh session and a reviewer can scan in one screen — HTML so a UI change can carry an inline mockup and the plan gets review-tracking through the shared .plans/_assets/ design system. Soft length budget: ≤ 400 words of prose for a typical plan. If it blows that, the work is probably plan-large.
Process
Step 0 — Right-size
Bail to plan-large if any of these hold:
- Touches persistence beyond adding a nullable column.
- Touches more than ~5 files or crosses more than one architectural boundary (e.g. auth + billing).
- Has sequenced dependencies — must ship A before B can begin.
- Obviously won't fit one PR.
If the user explicitly invoked plan-small, trust them — but flag a triggered criterion in one line and hand off.
Step 1 — Understand intent
Read the request. Identify WHAT, not HOW. Capture explicit and implicit requirements (scale, error tolerance, observability).
Step 2 — Load context
- Relevant
.agents/standards/(readindex.ymlfirst; narrow long files withrg). - Relevant
.agents/common-mistakes/(readindex.ymlfirst). - The project check command (look it up — don't assume).
Step 3 — Question gate (two tracks)
Generate the top 3–6 questions whose answers will shape the plan, then sort into two tracks.
Track A — product / feature-design. Ask the user. These are questions only they can answer: MVP scope, real-time vs batch, in-app vs email, which user segment, what counts as success, acceptable failure modes. Default to asking unless the request already pins them down.
Track B — code architecture. Search code first. Look for existing functions/helpers, config files, schemas, types, migrations, neighbouring-feature patterns. In-repo PRDs and design docs count as "code can answer" by analogy — search docs/, *.md files near the relevant module, before promoting.
If code answers, record under ## Decisions and assumptions as Source: code @ <file:line> and don't ask. If code is silent, promote to the user.
In one AskUserQuestion call, present:
- Track A questions plus any unanswered Track B questions.
- The core assumptions and decisions the skill is currently planning to take, each framed as a confirmable choice.
Example shapes:
- _(Track A — scope)_ "Export includes archived items, or only active?"
- _(Track A — assumption)_ "On send failure, I'm planning a toast vs silent retry vs blocking the form — confirm or override."
- _(Track B — assumption, code silent)_ "I'm planning to put the new endpoint at
/api/v1/widgets— confirm or override."
If there are no Track A questions, no unanswered Track B questions, and no non-trivial assumptions, skip the call.
Step 4 — Write the plan file
Slug: kebab-case from the request, ≤ 4 words. If .plans/<slug>/ exists, append -2, -3. Plan path: .plans/<slug>/plan.html.
Bootstrap assets first. If .plans/_assets/ does not exist, copy plan.css, mockup.css, plan.js, and serve.js from this skill's references/assets/ into it. If it exists, leave it untouched.
Copy references/plan-template.html to .plans/<slug>/plan.html and fill it. Section order is fixed — the summary section lands first so a reviewer hits the elevator pitch before reference material. The full document contract (section ids, asset links, mockup vocabulary) is references/contract.md.
Four template invariants:
- The
data-modelsection is mandatory when persistence is touched. Even a single-column change deserves the seven-bullet treatment — writing "N/A — <reason>" for backfill is itself a decision. Omission is not. Delete the section entirely when no persistence is touched. - Per-file blocks are prose, not bullet lists. The implementer reads the code for signatures. Reserve inline detail for genuinely novel files (new module, new API surface, novel error model).
- Mockups only for UI. If the change renders or changes a screen, sketch it in the
filessection with the.mock-*vocabulary (assets/mockup.css). No UI change → no mockup. - HTML-encode all filled content.
&→&,<→<,>→>in element content; also"→"in attributes. Code artifacts (Promise<User>,x <> y) break the markup or open an XSS hole otherwise. Seereferences/contract.md. - "Done when" uses EARS or GIVEN/WHEN/THEN. Both grammars disqualify weasel words by leaving nowhere to put them.
Step 5 — Self-review
Call plan-reviewer with Posture: plan-small. The agent owns the dimensions (eight standard plus plan-small extensions: noise budget, source-checking, done-criteria observability, data-model section).
Agent(subagent_type="plan-reviewer", prompt=<USER PROMPT>)
Where <USER PROMPT> is:
## Posture
plan-small
## Plan content (reviewer view — HTML, mockups elided)
{{full content of .plans/<slug>/plan.html, with each <div class="mock-*">…</div>
replaced by a one-line <!-- mockup: <description> --> placeholder}}
## Standards
{{full content of relevant .agents/standards/ files, narrowed via rg if long}}
## Common mistakes
{{full content of relevant .agents/common-mistakes/ files}}
The reviewer is blind to .plans/ — paste content inline.
Step 6 — Apply findings
- Apply every MUST-FIX directly to the plan file.
- Apply every SHOULD-FIX directly. If a SHOULD-FIX conflicts with a Step 3 user-confirmed decision, downgrade to CONSIDER and flag to the user rather than overriding.
- Append every CONSIDER as a list item in the
open-questionssection of the plan file.
Step 7 — Present
Print:
- The plan path.
- The text of the
summarysection, read back from the file (the file is canonical). - The
data-modelsection verbatim if present (schema decisions get front-of-presentation visibility). - The decisions/assumptions list.
- The CONSIDER items appended in Step 6.
Do not start implementing. The user decides when to invoke /implement-plan or /implement-plan-audited.
Step 8 — Serve and open (always the last thing)
The final action, every run: launch the tracker, which auto-picks a free port and opens the plan in the browser itself. One command, as a persistent background process (it must keep serving after the command returns):
node .plans/_assets/serve.js --open "<slug>/plan.html" > /tmp/hawk-plan-serve.log 2>&1 &
serve.js prefers port 7777 and falls back to the next free port if it's taken (so two repos never collide), then opens <slug>/plan.html via the OS opener (xdg-open / open / start). It prints the chosen URL as a PLAN_SERVER_URL=… line in the log — surface that to the user in case no browser opener is available.
Step 9 — Watch for in-page feedback
The plan page has a feedback composer (a per-section "note" and a plan-wide box). Sent notes append to .plans/<slug>/feedback.jsonl, one { ts, sectionId, text } per line. Tell the user they can type feedback directly in the page and send it whenever they want — then watch for it:
- Record the cursor:
N= current line count offeedback.jsonl(0 if absent). - Wait for new feedback with the Monitor tool (until-loop): condition =
wc -l < .plans/<slug>/feedback.jsonlis greater thanN. This yields control while the user reviews; a chat message from the user interrupts it normally. - When it fires, read lines
N+1…end. For each entry, act on it — revise the section named bysectionId(or the whole plan for a global note), answer a question, or record a decision in the plan — then re-run the self-review if the change is non-trivial. - Advance
Nto the new line count and watch again. Stop when the user says they're done (or starts driving via chat). Never re-process a line below the cursor — each entry is handled once.
The page is an additional channel, not a replacement: plain chat feedback works exactly as before.
Failure modes
- The reviewer keeps finding MUST-FIX after two passes. Stop applying patch-fix-patch. Surface the open MUST-FIX list to the user — the underlying disagreement is usually a Step 3 decision the plan went around.
- Step 3 reveals the work is actually
plan-large. Don't keep writing — bail mid-Step. The sunk cost of a partial plan is small; a mis-sized plan compounds across implementation. - The plan says "the code is correct" or "handles errors gracefully" instead of an observable done-criterion. This is the lazy-patch case. Replace with a runnable command, a query result, an HTTP response, or a UI state — never prose. The reviewer's done-criteria observability check will catch this; fix it before re-running rather than arguing.
- Scope creeps mid-write. If a new requirement surfaces in Step 4 that doesn't fit, split into a follow-up plan in
.plans/<slug>-followup/rather than ballooning this one. - A schema decision conflicts with a user answer. The user wins. Update the plan, record the override in
## Decisions and assumptionswithSource: user-confirmed, and re-run Step 5.
Big-output discipline
Heavy command output goes to /tmp/hawk-plan-small-<step>.log; extract with rg -n '<pattern>' /tmp/hawk-plan-small-<step>.log | head -50. Read with offset/limit. Long standards files are narrowed via rg before pasting into the reviewer prompt.