Compare commits

...
Author SHA1 Message Date
Matt Pocock 733d312884 Add skills.sh badge to README for visibility 2026-05-07 07:34:11 +01:00
Matt Pocock 3bb0b1b917 Update issue listing command in GitLab documentation for clarity 2026-05-07 07:20:57 +01:00
Matt Pocock 70141119e9 Update triage label in PRD writing instructions to 'ready-for-agent' 2026-05-06 16:07:58 +01:00
Matt Pocock 494e4b2699 Exclude deprecated skills from linking in the link-skills script 2026-05-06 14:22:15 +01:00
Matt Pocock 918f3fe30f Add instruction to read the handoff file before writing to it 2026-05-06 13:40:13 +01:00
Matt Pocock c8364b0d1f Add suggestion for skills to be used in next session in handoff documentation 2026-05-06 12:56:32 +01:00
Matt Pocock c63fd971a7 Remove disable-model-invocation flag from handoff skill documentation 2026-05-06 12:53:07 +01:00
Matt Pocock b27a1a46f8 Add handoff skill documentation for agent transition 2026-05-06 09:33:40 +01:00
Matt Pocock ff3ee1dda5 Add prototype skill and related documentation for interactive design exploration 2026-05-06 09:26:48 +01:00
Matt Pocock e736396b35 Clarify issue publication instructions for AFK agents in SKILL.md 2026-05-06 07:40:30 +01:00
Matt PocockandCopilot b843cb5ea7 Add structured sections for 'what-to-do' and 'supporting-info' in SKILL.md
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 12:38:11 +01:00
Matt Pocock 839025ae17 Remove disable-model-invocation flag from grill-with-docs 2026-04-30 11:46:00 +01:00
Matt Pocock 3dae2b1945 Add verify/check mode documentation and list-skills script 2026-04-30 10:12:35 +01:00
Matt PocockandClaude Opus 4.7 f71bb975bf Add out-of-scope note: issue trackers must be mainstream
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 10:56:28 +01:00
Matt PocockandClaude Opus 4.7 4369256220 Add GitLab as a first-class issue-tracker option
Closes #98

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 08:21:19 +01:00
Matt PocockandClaude Opus 4.7 b56795bed1 Add out-of-scope note for grilling question limits
Records the rejection of #44 (request for a hard cap on grilling
questions) so the reasoning isn't lost when the issue is closed and so
future similar requests can be deduplicated against it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 19:25:12 +01:00
Matt PocockandCopilot 179a14e721 Swapped 'backlog' for 'issue tracker
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 19:06:32 +01:00
Matt Pocock 5fed805a92 Enhance quickstart instructions in README; clarify setup steps for /setup-matt-pocock-skills and triage labels 2026-04-28 16:51:49 +01:00
Matt PocockandGitHub 0e51243253 Merge pull request #90 from mattpocock/setup-skill-and-vague-prose
Add setup-matt-pocock-skills; rename github-triage; migrate skills to vague prose
2026-04-28 16:46:49 +01:00
28 changed files with 688 additions and 48 deletions
+1
View File
@@ -10,6 +10,7 @@
"./skills/engineering/to-issues",
"./skills/engineering/to-prd",
"./skills/engineering/zoom-out",
"./skills/engineering/prototype",
"./skills/productivity/caveman",
"./skills/productivity/grill-me",
"./skills/productivity/write-a-skill"
@@ -0,0 +1,25 @@
# Issue tracker integrations are limited to mainstream tools
`setup-matt-pocock-skills` only offers first-class support for **mainstream** issue trackers. Requests to add support for niche, new, or single-vendor experimental trackers are out of scope.
## Why this is out of scope
Every issue-tracker backend hard-codes a CLI shape into the skills (commands, flags, output parsing). Each new backend is permanent maintenance surface — it has to keep working as the tool's CLI evolves, and it has to keep being tested against `/to-prd`, `/to-issues`, `/triage`, and friends. That cost is only worth paying for trackers a meaningful fraction of users actually have.
"Mainstream" is a judgment call, not a numeric bar:
- GitHub, GitLab, and Backlog.md are the kind of tools we'd consider mainstream — broadly known, widely used, well past the experimental phase.
- A brand-new agent-focused tool with a few hundred GitHub stars is not, no matter how interesting the design.
Stars, age, and download counts are useful signals when making the call but none of them is the rule. The rule is: would a typical engineer recognise this tool and have plausibly chosen it for their team?
The escape hatches for non-mainstream trackers already exist:
- `local markdown` for lightweight in-repo tracking.
- `other/custom` for users who want to wire something up themselves.
Neither requires the core skills to know about the specific tool.
## Prior requests
- #99 — "Add dex as an issue tracker backend" (dex was ~3 months old and ~300 stars at the time of the request)
+18
View File
@@ -0,0 +1,18 @@
# Hard limits on the number of questions during grilling
The `/grill-me` skill (and grilling sessions inside other skills) does not enforce a maximum number of questions. Requests to add a configurable cap or hard ceiling are out of scope.
## Why this is out of scope
Grilling is intentionally open-ended. The point is to keep digging until each branch of the decision tree is resolved — some plans need three questions, some need fifty. A fixed cap would either cut off useful exploration on hard problems or feel arbitrary on easy ones.
If a session feels too long, the right escape hatches already exist:
- The user can stop the session at any time and accept the current state of the plan.
- The user can tell the model to wrap up, summarise, and move on — natural-language steering is the intended control surface, not a numeric limit.
Adding a hard cap would also conflate two different failure modes: a model that asks too many questions because the plan is genuinely under-specified (working as intended) vs. a model that asks redundant or low-value questions (a prompt-quality issue, not a quantity issue). The fix for the latter belongs in the skill prompt, not in a counter.
## Prior requests
- #44 — "Codex just asked me 200 questions"
+15
View File
@@ -0,0 +1,15 @@
# Verify/Check Mode for `setup-matt-pocock-skills`
This project will not add a dedicated verify/check mode (or a separate verify skill) for `setup-matt-pocock-skills`.
## Why this is out of scope
A second skill — or a `--verify` flag — for checking whether `docs/agents/*.md` artifacts still match the seed-template schema would duplicate work the existing setup skill already handles in conversation.
The intended workflow is: **run `/setup-matt-pocock-skills` and tell it to verify your current setup.** The skill is prompt-driven, so the maintainer can scope it to a verification pass ("don't rewrite anything, just check my existing files against the current seed templates and report drift") without needing a separate code path. Adding a flag or a sibling skill would split the surface area of a feature that's already expressible through the natural-language entry point.
Keeping configuration management to a single skill also avoids the maintenance cost of two skills drifting from each other when seed templates evolve.
## Prior requests
- #106 — Feature request: verify/check mode for setup-matt-pocock-skills
+2 -1
View File
@@ -4,9 +4,10 @@ Skills are organized into bucket folders under `skills/`:
- `productivity/` — daily non-code workflow tools
- `misc/` — kept around but rarely used
- `personal/` — tied to my own setup, not promoted
- `in-progress/` — drafts not yet ready to ship
- `deprecated/` — no longer used
Every skill in `engineering/`, `productivity/`, or `misc/` must have a reference in the top-level `README.md` and an entry in `.claude-plugin/plugin.json`. Skills in `personal/` and `deprecated/` must not appear in either.
Every skill in `engineering/`, `productivity/`, or `misc/` must have a reference in the top-level `README.md` and an entry in `.claude-plugin/plugin.json`. Skills in `personal/`, `in-progress/`, and `deprecated/` must not appear in either.
Each skill entry in the top-level `README.md` must link the skill name to its `SKILL.md`.
+26
View File
@@ -0,0 +1,26 @@
# Matt Pocock Skills
A collection of agent skills (slash commands and behaviors) loaded by Claude Code. Skills are organized into buckets and consumed by per-repo configuration emitted by `/setup-matt-pocock-skills`.
## Language
**Issue tracker**:
The tool that hosts a repo's issues — GitHub Issues, Linear, a local `.scratch/` markdown convention, or similar. Skills like `to-issues`, `to-prd`, `triage`, and `qa` read from and write to it.
_Avoid_: backlog manager, backlog backend, issue host
**Issue**:
A single tracked unit of work inside an **Issue tracker** — a bug, task, PRD, or slice produced by `to-issues`.
_Avoid_: ticket (use only when quoting external systems that call them tickets)
**Triage role**:
A canonical state-machine label applied to an **Issue** during triage (e.g. `needs-triage`, `ready-for-afk`). Each role maps to a real label string in the **Issue tracker** via `docs/agents/triage-labels.md`.
## Relationships
- An **Issue tracker** holds many **Issues**
- An **Issue** carries one **Triage role** at a time
## Flagged ambiguities
- "backlog" was previously used to mean both the *tool* hosting issues and the *body of work* inside it — resolved: the tool is the **Issue tracker**; "backlog" is no longer used as a domain term.
- "backlog backend" / "backlog manager" — resolved: collapsed into **Issue tracker**.
+12 -4
View File
@@ -10,6 +10,8 @@
# Skills For Real Engineers
[![skills.sh](https://skills.sh/b/mattpocock/skills)](https://skills.sh/mattpocock/skills)
My agent skills that I use every day to do real engineering - not vibe coding.
Developing real applications is hard. Approaches like GSD, BMAD, and Spec-Kit try to help by owning the process. But while doing so, they take away your control and make bugs in the process hard to resolve.
@@ -28,9 +30,14 @@ If you want to keep up with changes to these skills, and any new ones I create,
npx skills@latest add mattpocock/skills
```
2. Pick the skills you want, and which coding agents you want to install them on.
2. Pick the skills you want, and which coding agents you want to install them on. **Make sure you select `/setup-matt-pocock-skills`**.
3. Bam - you're ready to go.
3. Run `/setup-matt-pocock-skills` in your agent. It will:
- Ask you which issue tracker you want to use (GitHub, Linear, or local files)
- Ask you what labels you apply to ticks when you triage them (`/triage` uses labels)
- Ask you where you want to save any docs we create
4. Bam - you're ready to go.
## Why These Skills Exist
@@ -141,13 +148,14 @@ Skills I use daily for code work.
- **[diagnose](./skills/engineering/diagnose/SKILL.md)** — Disciplined diagnosis loop for hard bugs and performance regressions: reproduce → minimise → hypothesise → instrument → fix → regression-test.
- **[grill-with-docs](./skills/engineering/grill-with-docs/SKILL.md)** — Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates `CONTEXT.md` and ADRs inline.
- **[triage](./skills/engineering/triage/SKILL.md)** — Triage backlog issues through a state machine of triage roles.
- **[triage](./skills/engineering/triage/SKILL.md)** — Triage issues through a state machine of triage roles.
- **[improve-codebase-architecture](./skills/engineering/improve-codebase-architecture/SKILL.md)** — Find deepening opportunities in a codebase, informed by the domain language in `CONTEXT.md` and the decisions in `docs/adr/`.
- **[setup-matt-pocock-skills](./skills/engineering/setup-matt-pocock-skills/SKILL.md)** — Scaffold the per-repo config (backlog backend, triage label vocabulary, domain doc layout) that the other engineering skills consume. Run once per repo before using `to-issues`, `to-prd`, `triage`, `diagnose`, `tdd`, `improve-codebase-architecture`, or `zoom-out`.
- **[setup-matt-pocock-skills](./skills/engineering/setup-matt-pocock-skills/SKILL.md)** — Scaffold the per-repo config (issue tracker, triage label vocabulary, domain doc layout) that the other engineering skills consume. Run once per repo before using `to-issues`, `to-prd`, `triage`, `diagnose`, `tdd`, `improve-codebase-architecture`, or `zoom-out`.
- **[tdd](./skills/engineering/tdd/SKILL.md)** — Test-driven development with a red-green-refactor loop. Builds features or fixes bugs one vertical slice at a time.
- **[to-issues](./skills/engineering/to-issues/SKILL.md)** — Break any plan, spec, or PRD into independently-grabbable GitHub issues using vertical slices.
- **[to-prd](./skills/engineering/to-prd/SKILL.md)** — Turn the current conversation context into a PRD and submit it as a GitHub issue. No interview — just synthesizes what you've already discussed.
- **[zoom-out](./skills/engineering/zoom-out/SKILL.md)** — Tell the agent to zoom out and give broader context or a higher-level perspective on an unfamiliar section of code.
- **[prototype](./skills/engineering/prototype/SKILL.md)** — Build a throwaway prototype to flush out a design — either a runnable terminal app for state/business-logic questions, or several radically different UI variations toggleable from one route.
### Productivity
@@ -1,6 +1,6 @@
# Explicit `/setup-matt-pocock-skills` pointer only for hard dependencies
Engineering skills depend on per-repo config (backlog backend, triage label vocabulary, domain doc layout) seeded by `/setup-matt-pocock-skills`. Some skills cannot meaningfully function without that config — they have to publish to a specific backlog or apply a specific label string. Others only use it to sharpen output (vocabulary, ADR awareness) and degrade gracefully without it.
Engineering skills depend on per-repo config (issue tracker, triage label vocabulary, domain doc layout) seeded by `/setup-matt-pocock-skills`. Some skills cannot meaningfully function without that config — they have to publish to a specific issue tracker or apply a specific label string. Others only use it to sharpen output (vocabulary, ADR awareness) and degrade gracefully without it.
We split these into **hard-dependency** and **soft-dependency** skills:
+1 -1
View File
@@ -23,7 +23,7 @@ fi
mkdir -p "$DEST"
find "$REPO/skills" -name SKILL.md -not -path '*/node_modules/*' -print0 |
find "$REPO/skills" -name SKILL.md -not -path '*/node_modules/*' -not -path '*/deprecated/*' -print0 |
while IFS= read -r -d '' skill_md; do
src="$(dirname "$skill_md")"
name="$(basename "$src")"
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
REPO="$(cd "$(dirname "$0")/.." && pwd)"
cd "$REPO"
find . -name SKILL.md -not -path '*/node_modules/*' | sed 's|^\./||' | sort
+3 -2
View File
@@ -4,10 +4,11 @@ Skills I use daily for code work.
- **[diagnose](./diagnose/SKILL.md)** — Disciplined diagnosis loop for hard bugs and performance regressions: reproduce → minimise → hypothesise → instrument → fix → regression-test.
- **[grill-with-docs](./grill-with-docs/SKILL.md)** — Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates `CONTEXT.md` and ADRs inline.
- **[triage](./triage/SKILL.md)** — Triage backlog issues through a state machine of triage roles.
- **[triage](./triage/SKILL.md)** — Triage issues through a state machine of triage roles.
- **[improve-codebase-architecture](./improve-codebase-architecture/SKILL.md)** — Find deepening opportunities in a codebase, informed by the domain language in `CONTEXT.md` and the decisions in `docs/adr/`.
- **[setup-matt-pocock-skills](./setup-matt-pocock-skills/SKILL.md)** — Scaffold the per-repo config (backlog backend, triage label vocabulary, domain doc layout) that the other engineering skills consume.
- **[setup-matt-pocock-skills](./setup-matt-pocock-skills/SKILL.md)** — Scaffold the per-repo config (issue tracker, triage label vocabulary, domain doc layout) that the other engineering skills consume.
- **[tdd](./tdd/SKILL.md)** — Test-driven development with a red-green-refactor loop. Builds features or fixes bugs one vertical slice at a time.
- **[to-issues](./to-issues/SKILL.md)** — Break any plan, spec, or PRD into independently-grabbable GitHub issues using vertical slices.
- **[to-prd](./to-prd/SKILL.md)** — Turn the current conversation context into a PRD and submit it as a GitHub issue.
- **[zoom-out](./zoom-out/SKILL.md)** — Tell the agent to zoom out and give broader context or a higher-level perspective on an unfamiliar section of code.
- **[prototype](./prototype/SKILL.md)** — Build a throwaway prototype to flush out a design — either a runnable terminal app for state/business-logic questions, or several radically different UI variations toggleable from one route.
+8 -1
View File
@@ -1,15 +1,20 @@
---
name: grill-with-docs
description: Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.
disable-model-invocation: true
---
<what-to-do>
Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
Ask the questions one at a time, waiting for feedback on each question before continuing.
If a question can be answered by exploring the codebase, explore the codebase instead.
</what-to-do>
<supporting-info>
## Domain awareness
During codebase exploration, also look for existing documentation:
@@ -79,3 +84,5 @@ Only offer to create an ADR when all three are true:
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons
If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md).
</supporting-info>
+79
View File
@@ -0,0 +1,79 @@
# Logic Prototype
A tiny interactive terminal app that lets the user drive a state model by hand. Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
## When this is the right shape
- "I'm not sure if this state machine handles the edge case where X then Y."
- "Does this data model actually let me represent the case where..."
- "I want to feel out what the API should look like before writing it."
- Anything where the user wants to **press buttons and watch state change**.
If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
## Process
### 1. State the question
Before writing code, write down what state model and what question you're prototyping. One paragraph, in the prototype's README or a comment at the top of the file. A logic prototype that answers the wrong question is pure waste — make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK.
### 2. Pick the language
Use whatever the host project uses. If the project has no obvious runtime (e.g. a docs repo), ask.
Match the project's existing conventions for tooling — don't add a new package manager or runtime just for the prototype.
### 3. Isolate the logic in a portable module
Put the actual logic — the bit that's answering the question — behind a small, pure interface that could be lifted out and dropped into the real codebase later. The TUI around it is throwaway; the logic module shouldn't be.
The right shape depends on the question:
- **A pure reducer** — `(state, action) => state`. Good when actions are discrete events and state is a single value.
- **A state machine** — explicit states and transitions. Good when "which actions are even legal right now" is part of the question.
- **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations.
- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a TUI. Keep it pure: no I/O, no terminal code, no `console.log` for control flow. The TUI imports it and calls into it; nothing flows the other direction.
This is what makes the prototype useful past its own lifetime. When the question's been answered, the validated reducer / machine / function set can be lifted into the real module — the TUI shell gets deleted.
### 4. Build the smallest TUI that exposes the state
Build it as a **lightweight TUI** — on every tick, clear the screen (`console.clear()` / `print("\033[2J\033[H")` / equivalent) and re-render the whole frame. The user should always see one stable view, not an ever-growing scrollback.
Each frame has two parts, in this order:
1. **Current state**, pretty-printed and diff-friendly (one field per line, or formatted JSON). Use **bold** for field names or section headers and **dim** for less important context (timestamps, IDs, derived values). Native ANSI escape codes are fine — `\x1b[1m` bold, `\x1b[2m` dim, `\x1b[0m` reset. No need to pull in a styling library unless one is already in the project.
2. **Keyboard shortcuts**, listed at the bottom: `[a] add user [d] delete user [t] tick clock [q] quit`. Bold the key, dim the description, or vice-versa — whatever reads cleanly.
Behaviour:
1. **Initialise state** — a single in-memory object/struct. Render the first frame on start.
2. **Read one keystroke (or one line)** at a time, dispatch to a handler that mutates state.
3. **Re-render** the full frame after every action — don't append, replace.
4. **Loop until quit.**
The whole frame should fit on one screen.
### 5. Make it runnable in one command
Add a script to the project's existing task runner (`package.json` scripts, `Makefile`, `justfile`, `pyproject.toml`). The user should run `pnpm run <prototype-name>` or equivalent — never need to remember a path.
If the host project has no task runner, just put the command at the top of the prototype's README.
### 6. Hand it over
Give the user the run command. They'll drive it themselves; the interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different" — those are the bugs in the _idea_, which is the whole point. If they want new actions added, add them. Prototypes evolve.
### 7. Capture the answer
When the prototype has done its job, the answer to the question is the only thing worth keeping. If the user is around, ask what it taught them. If not, leave a `NOTES.md` next to the prototype so the answer can be filled in (or filled in by you, if you've watched the session) before the prototype gets deleted.
## Anti-patterns
- **Don't add tests.** A prototype that needs tests is no longer a prototype.
- **Don't wire it to the real database.** Use an in-memory store unless the question is specifically about persistence.
- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
- **Don't blur the logic and the TUI together.** If the reducer / state machine references `console.log`, prompts, or terminal escape codes, it's no longer portable. Keep the TUI as a thin shell over a pure module.
- **Don't ship the TUI shell into production.** The shell is optimised for being driven by hand from a terminal. The logic module behind it is the bit worth keeping.
+30
View File
@@ -0,0 +1,30 @@
---
name: prototype
description: Build a throwaway prototype to flush out a design before committing to it. Routes between two branches — a runnable terminal app for state/business-logic questions, or several radically different UI variations toggleable from one route. Use when the user wants to prototype, sanity-check a data model or state machine, mock up a UI, explore design options, or says "prototype this", "let me play with it", "try a few designs".
---
# Prototype
A prototype is **throwaway code that answers a question**. The question decides the shape.
## Pick a branch
Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around:
- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a tiny interactive terminal app that pushes the state machine through cases that are hard to reason about on paper.
- **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
The two branches produce very different artifacts — getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype.
## Rules that apply to both
1. **Throwaway from day one, and clearly marked as such.** Locate the prototype code close to where it will actually be used (next to the module or page it's prototyping for) so context is obvious — but name it so a casual reader can see it's a prototype, not production. For throwaway UI routes, obey whatever routing convention the project already uses; don't invent a new top-level structure.
2. **One command to run.** Whatever the project's existing task runner supports — `pnpm <name>`, `python <path>`, `bun <path>`, etc. The user must be able to start it without thinking.
3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is *checking*, not something it should depend on. If the question explicitly involves a database, hit a scratch DB or a local file with a clear "PROTOTYPE — wipe me" name.
4. **Skip the polish.** No tests, no error handling beyond what makes the prototype *runnable*, no abstractions. The point is to learn something fast and then delete it.
5. **Surface the state.** After every action (logic) or on every variant switch (UI), print or render the full relevant state so the user can see what changed.
6. **Delete or absorb when done.** When the prototype has answered its question, either delete it or fold the validated decision into the real code — don't leave it rotting in the repo.
## When done
The *answer* is the only thing worth keeping from a prototype. Capture it somewhere durable (commit message, ADR, issue, or a `NOTES.md` next to the prototype) along with the question it was answering. If the user is around, that capture is a quick conversation; if not, leave the placeholder so they (or you, on the next pass) can fill in the verdict before deleting the prototype.
+112
View File
@@ -0,0 +1,112 @@
# UI Prototype
Generate **several radically different UI variations** on a single route, switchable from a floating bottom bar. The user flips between variants in the browser, picks one (or steals bits from each), then throws the rest away.
If the question is about logic/state rather than what something looks like — wrong branch. Use [LOGIC.md](LOGIC.md).
## When this is the right shape
- "What should this page look like?"
- "I want to see a few options for this dashboard before committing."
- "Try a different layout for the settings screen."
- Any time the user would otherwise spend a day picking between three vague mockups in their head.
## Two sub-shapes — strongly prefer sub-shape A
A UI prototype is much easier to judge when it's **butting up against the rest of the app** — real header, real sidebar, real data, real density. A throwaway route on its own is a vacuum: every variant looks fine in isolation. Default to sub-shape A whenever there's a plausible existing page to host the variants. Only reach for sub-shape B if the prototype genuinely has no nearby home.
### Sub-shape A — adjustment to an existing page (preferred)
The route already exists. Variants are rendered **on the same route**, gated by a `?variant=` URL search param. The existing data fetching, params, and auth all stay — only the rendering swaps. This is the default; pick it unless there's a specific reason not to.
If the prototype is for something that doesn't yet have a page but *would naturally live inside one* (a new section of the dashboard, a new card on the settings screen, a new step in an existing flow) — that's still sub-shape A. Mount the variants inside the host page.
### Sub-shape B — a new page (last resort)
Only use this when the thing being prototyped genuinely has no existing page to live inside — e.g. an entirely new top-level surface, or a flow that can't be embedded anywhere sensible.
Create a **throwaway route** following whatever routing convention the project already uses — don't invent a new top-level structure. Name it so it's obviously a prototype (e.g. include the word `prototype` in the path or filename). Same `?variant=` pattern.
Before committing to sub-shape B, sanity-check: is there really no existing page this could be embedded in? An empty route hides design problems that a populated one would expose.
In both sub-shapes the floating bottom bar is identical.
## Process
### 1. State the question and pick N
Default to **3 variants**. More than 5 stops being radically different and starts being noise — cap there.
Write down the plan in one line, in the prototype's location or a top-of-file comment:
> "Three variants of the settings page, switchable via `?variant=`, on the existing `/settings` route."
This works whether the user is here to push back or not.
### 2. Generate radically different variants
Draft each variant. Hold each one to:
- The page's purpose and the data it has access to.
- The project's component library / styling system (TailwindCSS, shadcn, MUI, plain CSS, whatever).
- A clear exported component name, e.g. `VariantA`, `VariantB`, `VariantC`.
Variants must be **structurally different** — different layout, different information hierarchy, different primary affordance, not just different colours. Three slightly-tweaked card grids isn't a UI prototype, it's wallpaper. If two drafts come out too similar, redo one with explicit "do not use a card grid" guidance.
### 3. Wire them together
Create a single switcher component on the route:
```tsx
// pseudo-code — adapt to the project's framework
const variant = searchParams.get('variant') ?? 'A';
return (
<>
{variant === 'A' && <VariantA {...data} />}
{variant === 'B' && <VariantB {...data} />}
{variant === 'C' && <VariantC {...data} />}
<PrototypeSwitcher variants={['A','B','C']} current={variant} />
</>
);
```
For sub-shape A (existing page): keep all the existing data fetching above the switcher; only the rendered subtree changes per variant.
For sub-shape B (new page): the throwaway route under `/prototype/<name>` mounts the same switcher.
### 4. Build the floating switcher
A small fixed-position bar at the bottom-centre of the screen with three pieces:
- **Left arrow** — cycles to the previous variant (wraps around).
- **Variant label** — shows the current variant key and, if the variant exports a name, that name too. e.g. `B — Sidebar layout`.
- **Right arrow** — cycles forward (wraps around).
Behaviour:
- Clicking an arrow updates the URL search param (use the framework's router — `router.replace` on Next, `navigate` on React Router, etc) so the variant is shareable and reload-stable.
- Keyboard: `←` and `→` arrow keys also cycle. Don't intercept arrow keys when an `<input>`, `<textarea>`, or `[contenteditable]` is focused.
- Visually distinct from the page (e.g. high-contrast pill, subtle shadow) so it's obviously not part of the design being evaluated.
- Hidden in production builds — gate on `process.env.NODE_ENV !== 'production'` or an equivalent check, so a stray prototype merge can't ship the bar to users.
Put the switcher in a single shared component so both sub-shapes can reuse it. Locate it wherever shared UI lives in the project.
### 5. Hand it over
Surface the URL (and the `?variant=` keys). The user will flip through whenever they get to it. The interesting feedback is usually **"I want the header from B with the sidebar from C"** — that's the actual design they want.
### 6. Capture the answer and clean up
Once a variant has won, write down which one and why (commit message, ADR, issue, or a `NOTES.md` next to the prototype if running AFK and the user hasn't responded yet). Then:
- **Sub-shape A** — delete the losing variants and the switcher; fold the winner into the existing page.
- **Sub-shape B** — promote the winning variant to a real route, delete the throwaway route and the switcher.
Don't leave variant components or the switcher lying around. They rot fast and confuse the next reader.
## Anti-patterns
- **Variants that differ only in colour or copy.** That's a tweak, not a prototype. Real variants disagree about structure.
- **Sharing too much code between variants.** A shared `<Header>` is fine; a shared `<Layout>` defeats the point. Each variant should be free to throw out the layout.
- **Wiring variants to real mutations.** Read-only prototypes are fine. If a variant needs to mutate, point it at a stub — the question is "what should this look like", not "does the backend work".
- **Promoting the prototype directly to production.** The variant code was written under prototype constraints (no tests, minimal error handling). Rewrite it properly when you fold it in.
@@ -1,6 +1,6 @@
---
name: setup-matt-pocock-skills
description: Sets up an `## Agent skills` block in AGENTS.md/CLAUDE.md and `docs/agents/` so the engineering skills know this repo's backlog backend (GitHub or local markdown), triage label vocabulary, and domain doc layout. Run before first use of `to-issues`, `to-prd`, `triage`, `diagnose`, `tdd`, `improve-codebase-architecture`, or `zoom-out` — or if those skills appear to be missing context about the backlog, triage labels, or domain docs.
description: Sets up an `## Agent skills` block in AGENTS.md/CLAUDE.md and `docs/agents/` so the engineering skills know this repo's issue tracker (GitHub or local markdown), triage label vocabulary, and domain doc layout. Run before first use of `to-issues`, `to-prd`, `triage`, `diagnose`, `tdd`, `improve-codebase-architecture`, or `zoom-out` — or if those skills appear to be missing context about the issue tracker, triage labels, or domain docs.
disable-model-invocation: true
---
@@ -8,7 +8,7 @@ disable-model-invocation: true
Scaffold the per-repo configuration that the engineering skills assume:
- **Backlog** — where issues/tickets live (GitHub by default; local markdown is also supported out of the box)
- **Issue tracker** — where issues live (GitHub by default; local markdown is also supported out of the box)
- **Triage labels** — the strings used for the five canonical triage roles
- **Domain docs** — where `CONTEXT.md` and ADRs live, and the consumer rules for reading them
@@ -25,7 +25,7 @@ Look at the current repo to understand its starting state. Read whatever exists;
- `CONTEXT.md` and `CONTEXT-MAP.md` at the repo root
- `docs/adr/` and any `src/*/docs/adr/` directories
- `docs/agents/` — does this skill's prior output already exist?
- `.scratch/` — sign that a local-markdown backlog convention is already in use
- `.scratch/` — sign that a local-markdown issue tracker convention is already in use
### 2. Present findings and ask
@@ -33,19 +33,20 @@ Summarise what's present and what's missing. Then walk the user through the thre
Assume the user does not know what these terms mean. Each section starts with a short explainer (what it is, why these skills need it, what changes if they pick differently). Then show the choices and the default.
**Section A — Backlog backend.**
**Section A — Issue tracker.**
> Explainer: "Backlog" is where issues/tickets live for this repo. Skills like `to-issues`, `triage`, `to-prd`, and `qa` read from and write to it — they need to know whether to call `gh issue create`, write a markdown file under `.scratch/`, or follow some other workflow you describe. Pick the place you actually track work for this repo.
> Explainer: The "issue tracker" is where issues live for this repo. Skills like `to-issues`, `triage`, `to-prd`, and `qa` read from and write to it — they need to know whether to call `gh issue create`, write a markdown file under `.scratch/`, or follow some other workflow you describe. Pick the place you actually track work for this repo.
Default posture: these skills were designed for GitHub. If a `git remote` points at GitHub, propose that. Otherwise (or if the user prefers), offer:
Default posture: these skills were designed for GitHub. If a `git remote` points at GitHub, propose that. If a `git remote` points at GitLab (`gitlab.com` or a self-hosted host), propose GitLab. Otherwise (or if the user prefers), offer:
- **GitHub** — issues live in the repo's GitHub Issues
- **Local markdown** — issues live as files under `.scratch/<feature>/` in this repo (good for solo projects or repos without a GitHub remote)
- **GitHub** — issues live in the repo's GitHub Issues (uses the `gh` CLI)
- **GitLab** — issues live in the repo's GitLab Issues (uses the [`glab`](https://gitlab.com/gitlab-org/cli) CLI)
- **Local markdown** — issues live as files under `.scratch/<feature>/` in this repo (good for solo projects or repos without a remote)
- **Other** (Jira, Linear, etc.) — ask the user to describe the workflow in one paragraph; the skill will record it as freeform prose
**Section B — Triage label vocabulary.**
> Explainer: When the `triage` skill processes an incoming issue, it moves it through a state machine — needs evaluation, waiting on reporter, ready for an AFK agent to pick up, ready for a human, or won't fix. To do that, it needs to apply labels (or the equivalent in your backlog) that match strings *you've actually configured*. If your repo already uses different label names (e.g. `bug:triage` instead of `needs-triage`), map them here so the skill applies the right ones instead of creating duplicates.
> Explainer: When the `triage` skill processes an incoming issue, it moves it through a state machine — needs evaluation, waiting on reporter, ready for an AFK agent to pick up, ready for a human, or won't fix. To do that, it needs to apply labels (or the equivalent in your issue tracker) that match strings *you've actually configured*. If your repo already uses different label names (e.g. `bug:triage` instead of `needs-triage`), map them here so the skill applies the right ones instead of creating duplicates.
The five canonical roles:
@@ -55,7 +56,7 @@ The five canonical roles:
- `ready-for-human` — needs human implementation
- `wontfix` — will not be actioned
Default: each role's string equals its name. Ask the user if they want to override any. If their backlog has no existing labels, the defaults are fine.
Default: each role's string equals its name. Ask the user if they want to override any. If their issue tracker has no existing labels, the defaults are fine.
**Section C — Domain docs.**
@@ -71,7 +72,7 @@ Confirm the layout:
Show the user a draft of:
- The `## Agent skills` block to add to whichever of `CLAUDE.md` / `AGENTS.md` is being edited (see step 4 for selection rules)
- The contents of `docs/agents/backlog.md`, `docs/agents/triage-labels.md`, `docs/agents/domain.md`
- The contents of `docs/agents/issue-tracker.md`, `docs/agents/triage-labels.md`, `docs/agents/domain.md`
Let them edit before writing.
@@ -92,9 +93,9 @@ The block:
```markdown
## Agent skills
### Backlog
### Issue tracker
[one-line summary of where the backlog lives]. See `docs/agents/backlog.md`.
[one-line summary of where issues are tracked]. See `docs/agents/issue-tracker.md`.
### Triage labels
@@ -107,13 +108,14 @@ The block:
Then write the three docs files using the seed templates in this skill folder as a starting point:
- [backlog-github.md](./backlog-github.md) — GitHub backlog
- [backlog-local.md](./backlog-local.md) — local-markdown backlog
- [issue-tracker-github.md](./issue-tracker-github.md) — GitHub issue tracker
- [issue-tracker-gitlab.md](./issue-tracker-gitlab.md) — GitLab issue tracker
- [issue-tracker-local.md](./issue-tracker-local.md) — local-markdown issue tracker
- [triage-labels.md](./triage-labels.md) — label mapping
- [domain.md](./domain.md) — domain doc consumer rules + layout
For "other" backlog backends, write `docs/agents/backlog.md` from scratch using the user's description.
For "other" issue trackers, write `docs/agents/issue-tracker.md` from scratch using the user's description.
### 5. Done
Tell the user the setup is complete and which engineering skills will now read from these files. Mention they can edit `docs/agents/*.md` directly later — re-running this skill is only necessary if they want to switch backlog backends or restart from scratch.
Tell the user the setup is complete and which engineering skills will now read from these files. Mention they can edit `docs/agents/*.md` directly later — re-running this skill is only necessary if they want to switch issue trackers or restart from scratch.
@@ -1,4 +1,4 @@
# Backlog: GitHub
# Issue tracker: GitHub
Issues and PRDs for this repo live as GitHub issues. Use the `gh` CLI for all operations.
@@ -13,7 +13,7 @@ Issues and PRDs for this repo live as GitHub issues. Use the `gh` CLI for all op
Infer the repo from `git remote -v``gh` does this automatically when run inside a clone.
## When a skill says "publish to the backlog"
## When a skill says "publish to the issue tracker"
Create a GitHub issue.
@@ -0,0 +1,23 @@
# Issue tracker: GitLab
Issues and PRDs for this repo live as GitLab issues. Use the [`glab`](https://gitlab.com/gitlab-org/cli) CLI for all operations.
## Conventions
- **Create an issue**: `glab issue create --title "..." --description "..."`. Use a heredoc for multi-line descriptions. Pass `--description -` to open an editor.
- **Read an issue**: `glab issue view <number> --comments`. Use `-F json` for machine-readable output.
- **List issues**: `glab issue list -F json` with appropriate `--label` filters.
- **Comment on an issue**: `glab issue note <number> --message "..."`. GitLab calls comments "notes".
- **Apply / remove labels**: `glab issue update <number> --label "..."` / `--unlabel "..."`. Multiple labels can be comma-separated or by repeating the flag.
- **Close**: `glab issue close <number>`. `glab issue close` does not accept a closing comment, so post the explanation first with `glab issue note <number> --message "..."`, then close.
- **Merge requests**: GitLab calls PRs "merge requests". Use `glab mr create`, `glab mr view`, `glab mr note`, etc. — the same shape as `gh pr ...` with `mr` in place of `pr` and `note`/`--message` in place of `comment`/`--body`.
Infer the repo from `git remote -v``glab` does this automatically when run inside a clone.
## When a skill says "publish to the issue tracker"
Create a GitLab issue.
## When a skill says "fetch the relevant ticket"
Run `glab issue view <number> --comments`.
@@ -1,4 +1,4 @@
# Backlog: Local Markdown
# Issue tracker: Local Markdown
Issues and PRDs for this repo live as markdown files in `.scratch/`.
@@ -10,7 +10,7 @@ Issues and PRDs for this repo live as markdown files in `.scratch/`.
- Triage state is recorded as a `Status:` line near the top of each issue file (see `triage-labels.md` for the role strings)
- Comments and conversation history append to the bottom of the file under a `## Comments` heading
## When a skill says "publish to the backlog"
## When a skill says "publish to the issue tracker"
Create a new file under `.scratch/<feature-slug>/` (creating the directory if needed).
@@ -1,8 +1,8 @@
# Triage Labels
The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's backlog.
The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
| Label in mattpocock/skills | Label in our backlog | Meaning |
| Label in mattpocock/skills | Label in our tracker | Meaning |
| -------------------------- | -------------------- | ---------------------------------------- |
| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue |
| `needs-info` | `needs-info` | Waiting on reporter for more information |
+9 -7
View File
@@ -1,19 +1,19 @@
---
name: to-issues
description: Break a plan, spec, or PRD into independently-grabbable issues on the project backlog using tracer-bullet vertical slices. Use when user wants to convert a plan into issues, create implementation tickets, or break down work into issues.
description: Break a plan, spec, or PRD into independently-grabbable issues on the project issue tracker using tracer-bullet vertical slices. Use when user wants to convert a plan into issues, create implementation tickets, or break down work into issues.
---
# To Issues
Break a plan into independently-grabbable backlog issues using vertical slices (tracer bullets).
Break a plan into independently-grabbable issues using vertical slices (tracer bullets).
The backlog backend and triage label vocabulary should have been provided to you — run `/setup-matt-pocock-skills` if not.
The issue tracker and triage label vocabulary should have been provided to you — run `/setup-matt-pocock-skills` if not.
## Process
### 1. Gather context
Work from whatever is already in the conversation context. If the user passes a backlog ticket reference (issue number, URL, or path) as an argument, fetch it from the backlog and read its full body and comments.
Work from whatever is already in the conversation context. If the user passes an issue reference (issue number, URL, or path) as an argument, fetch it from the issue tracker and read its full body and comments.
### 2. Explore the codebase (optional)
@@ -49,21 +49,23 @@ Ask the user:
Iterate until the user approves the breakdown.
### 5. Publish the issues to the backlog
### 5. Publish the issues to the issue tracker
For each approved slice, publish a new issue to the backlog. Use the issue body template below. Apply the `needs-triage` triage label so each issue enters the normal triage flow.
For each approved slice, publish a new issue to the issue tracker. Use the issue body template below. These issues are considered ready for AFK agents, so publish them with the correct triage label unless instructed otherwise.
Publish issues in dependency order (blockers first) so you can reference real issue identifiers in the "Blocked by" field.
<issue-template>
## Parent
A reference to the parent ticket on the backlog (if the source was a backlog ticket, otherwise omit this section).
A reference to the parent issue on the issue tracker (if the source was an existing issue, otherwise omit this section).
## What to build
A concise description of this vertical slice. Describe the end-to-end behavior, not layer-by-layer implementation.
Avoid specific file paths or code snippets — they go stale fast. Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it here and note briefly that it came from a prototype. Trim to the decision-rich parts — not a working demo, just the important bits.
## Acceptance criteria
- [ ] Criterion 1
+5 -3
View File
@@ -1,11 +1,11 @@
---
name: to-prd
description: Turn the current conversation context into a PRD and publish it to the project backlog. Use when user wants to create a PRD from the current context.
description: Turn the current conversation context into a PRD and publish it to the project issue tracker. Use when user wants to create a PRD from the current context.
---
This skill takes the current conversation context and codebase understanding and produces a PRD. Do NOT interview the user — just synthesize what you already know.
The backlog backend and triage label vocabulary should have been provided to you — run `/setup-matt-pocock-skills` if not.
The issue tracker and triage label vocabulary should have been provided to you — run `/setup-matt-pocock-skills` if not.
## Process
@@ -17,7 +17,7 @@ A deep module (as opposed to a shallow module) is one which encapsulates a lot o
Check with the user that these modules match their expectations. Check with the user which modules they want tests written for.
3. Write the PRD using the template below, then publish it to the project backlog. Apply the `needs-triage` triage label so it enters the normal triage flow.
3. Write the PRD using the template below, then publish it to the project issue tracker. Apply the `ready-for-agent` triage label - no need for additional triage.
<prd-template>
@@ -55,6 +55,8 @@ A list of implementation decisions that were made. This can include:
Do NOT include specific file paths or code snippets. They may end up being outdated very quickly.
Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it within the relevant decision and note briefly that it came from a prototype. Trim to the decision-rich parts — not a working demo, just the important bits.
## Testing Decisions
A list of testing decisions that were made. Include:
+5 -5
View File
@@ -1,13 +1,13 @@
---
name: triage
description: Triage backlog issues through a state machine driven by triage roles. Use when user wants to create an issue, triage issues, review incoming bugs or feature requests, prepare issues for an AFK agent, or manage issue workflow.
description: Triage issues through a state machine driven by triage roles. Use when user wants to create an issue, triage issues, review incoming bugs or feature requests, prepare issues for an AFK agent, or manage issue workflow.
---
# Triage
Move issues on the project backlog through a small state machine of triage roles.
Move issues on the project issue tracker through a small state machine of triage roles.
Every comment or issue posted to the backlog during triage **must** start with this disclaimer:
Every comment or issue posted to the issue tracker during triage **must** start with this disclaimer:
```
> *This was generated by AI during triage.*
@@ -35,7 +35,7 @@ Five **state** roles:
Every triaged issue should carry exactly one category role and one state role. If state roles conflict, flag it and ask the maintainer before doing anything else.
These are canonical role names — the actual label strings used on the backlog may differ. The mapping should have been provided to you - run `/setup-matt-pocock-skills` if not.
These are canonical role names — the actual label strings used in the issue tracker may differ. The mapping should have been provided to you - run `/setup-matt-pocock-skills` if not.
State transitions: an unlabeled issue normally goes to `needs-triage` first; from there it moves to `needs-info`, `ready-for-agent`, `ready-for-human`, or `wontfix`. `needs-info` returns to `needs-triage` once the reporter replies. The maintainer can override at any time — flag transitions that look unusual and ask before proceeding.
@@ -50,7 +50,7 @@ The maintainer invokes `/triage` and describes what they want in natural languag
## Show what needs attention
Query the backlog and present three buckets, oldest first:
Query the issue tracker and present three buckets, oldest first:
1. **Unlabeled** — never triaged.
2. **`needs-triage`** — evaluation in progress.
+8
View File
@@ -0,0 +1,8 @@
# In Progress
Skills that are still being developed. They're not ready to ship — expect rough edges, breaking changes, and abandoned experiments. They're excluded from the plugin and the top-level README until they graduate to a stable bucket.
- **[handoff](./handoff/SKILL.md)** — Compact the current conversation into a handoff document so another agent can continue the work.
- **[writing-beats](./writing-beats/SKILL.md)** — Shape an article as a journey of beats, choose-your-own-adventure style. Pick a starting beat, write only that beat, then pivot to the next, until the article reaches a natural end.
- **[writing-fragments](./writing-fragments/SKILL.md)** — Grilling session that mines you for fragments — heterogeneous nuggets of writing — and appends them to a single document as raw material for a future article.
- **[writing-shape](./writing-shape/SKILL.md)** — Take a markdown file of raw material and shape it into an article paragraph by paragraph, arguing format choices at each step.
+13
View File
@@ -0,0 +1,13 @@
---
name: handoff
description: Compact the current conversation into a handoff document for another agent to pick up.
argument-hint: "What will the next session be used for?"
---
Write a handoff document summarising the current conversation so a fresh agent can continue the work. Save it to a path produced by `mktemp -t handoff-XXXXXX.md` (read the file before you write to it).
Suggest the skills to be used, if any, by the next session.
Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead.
If the user passed arguments, treat them as a description of what the next session will focus on and tailor the doc accordingly.
+101
View File
@@ -0,0 +1,101 @@
---
name: writing-beats
description: Shape an article as a journey of beats, choose-your-own-adventure style. The user picks a starting beat from the raw material, you write only that beat, then offer options for where to pivot next, beat by beat, until the article reaches a natural end. Use when the user has raw material and wants to assemble it as a narrative rather than an argument.
---
<what-to-do>
The user has passed (or will pass) a markdown file of raw material.
If the user did not say where to save the article, ask once and remember the path.
Then run a beat-by-beat journey:
1. Write 23 candidate **starting beats**, drawn from the raw material. Each is a different entry point into the article. Show the user the beats before writing it to the article file. The user picks one.
2. Once the user picks a starting beat, write **only that beat** to the article file. A beat may be one sentence or several paragraphs — whatever that beat naturally is. Stop there.
3. Re-read the article file from disk. Then offer 23 candidate **next beats** — different directions the journey could pivot to from where the article now stands.
4. Loop steps 24 until the article reaches a natural end.
</what-to-do>
<supporting-info>
## What is a beat
A beat is one move in the journey. It does one thing — sets a scene, lands a point, asks a question, tells a small story, drops an aside, twists the angle. Then it stops, leaving the reader at a place where the next beat can pivot.
A beat is sized by what it needs:
- A single sentence if that's all the move is ("And then nothing happened for three weeks.").
- A short paragraph if the move needs setup.
- Multiple paragraphs if the beat is a self-contained vignette, argument, or example.
If a "beat" needs five paragraphs and three subheadings, it's not a beat — it's two beats glued together. Split it.
## Offering candidate beats
Each candidate should be genuinely different — different angle, different tone, different move. Not three flavours of the same paragraph. The user is choosing a _direction_, so the choices need to diverge.
Format the offer like a menu:
```
Where do you want to start?
1. **Open with the failure.** Drop the reader into the moment it broke —
the bug, the silence, the wrong number on the dashboard. Hooks on shock.
2. **Open with the contradiction.** State the thing everyone believes,
then state the thing that turns out to be true. Hooks on curiosity.
3. **Open with the small scene.** A specific morning, a specific
conversation. Hooks on intimacy.
```
Sketch the move, not the prose. The user picks a direction; you write the prose afterward.
Always end the menu with your recommendation and a one-line reason. Don't sit on the fence — pick one. Example: "I'd go with **2** — the contradiction sets up the strongest through-line for what's in the pile." The user can override; they usually won't, but they need your read.
## Writing one beat
Once a beat is picked, write _that beat only_ to the article file. Do not write the next beat. Do not foreshadow the next beat. Do not write transitions out of the beat — the next beat will pivot, and pivots are written when their beat is written.
Pull material from the raw pile to populate the beat. You can paraphrase, split, recombine, or quote. The pile is a quarry.
If the beat needs something the pile doesn't have, name the gap before writing: "this beat wants a concrete example and the pile doesn't have one — give me one or pick a different beat."
## Pivoting to the next beat
After the user has edited, re-read the article file. The article may have changed in ways that change what the next beat should be. Then offer 23 candidates again.
The candidates should respect the article so far. Useful pivot moves:
- **Continue** — push further in the same direction, deepen what's there.
- **Contrast** — introduce the opposite, the counterexample, the doubt.
- **Zoom in** — narrow to a specific case, scene, or detail.
- **Zoom out** — widen to the broader implication or pattern.
- **Aside** — break the fourth wall, drop a tip, add a footnote-shaped paragraph.
- **Pivot hard** — deliberately change subject, trusting the connection will land later.
Mix the candidates. If you've offered three "continue" options in a row, force a contrast or zoom into the next menu.
## Ending the journey
The article ends when the journey is complete — not when the pile is empty. Most piles will have leftover fragments that don't make it in. That is fine; that is the point of having more raw material than you need.
When you sense an ending is near, say so: "we could end on the last beat, or add one more that lands the takeaway — which?" Let the user decide.
## Writing rhythm
- Append one beat at a time. Never write ahead.
- Re-read the article file from disk before every write. Preserve user edits absolutely.
- If the user edits a previous beat substantially, let it change what comes next. The journey is alive.
- If the user says "rewrite that beat" or "go back and try a different beat 3", do it — edit in place, leave the rest alone.
## Out of scope
- Outlining the whole article up front.
- Writing multiple beats in a single turn.
- Editing the raw material file.
- Imposing a fixed structure (intro/body/conclusion). The structure is whatever the journey turns out to be.
</supporting-info>
@@ -0,0 +1,95 @@
---
name: writing-fragments
description: Grilling session that mines the user for fragments — heterogeneous nuggets of writing (claims, vignettes, sharp sentences, half-thoughts) — and appends them to a single document as raw material for a future article. Use when the user wants to develop ideas before imposing structure, or mentions "fragments", "ideate", or "raw material" for writing.
---
<what-to-do>
Run a grilling session that produces fragments. Interview the user relentlessly about whatever they want to write about. Do not impose phases, outlines, or structure — that is explicitly out of scope.
As fragments emerge from either side of the conversation, append them to a single markdown file. The user will be editing this file during the session; always re-read it before writing so their edits are preserved.
If the user did not pass a path, ask once where to save the document, then remember it for the rest of the session.
On first write, put a single H1 at the top with a working title (it can change later) and nothing else — no metadata, no TOC, no date.
</what-to-do>
<supporting-info>
## What is a fragment
A fragment is any piece of text that might survive into the final article. It must be _readable by the author_ — the author can tell what it means — but it does not need to define its terms or be comprehensible to a cold reader. The bar is "is this a piece of good writing?", not "is this a self-contained argument?"
Fragments are deliberately heterogeneous. Examples of what could be a fragment:
- A sharp sentence you'd want to deploy somewhere but don't yet know where.
- A claim with a one-line justification.
- A vignette: a thing that happened, a code snippet, a scenario, an analogy.
- A half-thought: "something about how X feels like Y, work this out later."
- A quote, a piece of dialogue, an overheard line.
- A list of related observations that hang together by feel.
- A complaint, a confession, a punchline.
The novelist's diary is the model: years of unstructured noticings that later get mined for raw material. Fragments are noticings.
## How the session feels
Like a grilling session, with fragments as a by-product. The shape:
- Start by asking what the user is circling around. Let them ramble.
- Catch fragments from their words. When they say something quotable, capture it verbatim or slightly sharpened.
- Generate candidate fragments back at them. Try things on. Offer two or three versions of the same idea and let them pick or reject.
- When something lands, append it. When it doesn't, drop it.
- Press for more. Excavate. "You said X — say it three different ways." "What's the version of that you wouldn't say in public?" "What's the example that made you believe this in the first place?"
- Push on quality. The article will only be as good as its fragments. If a fragment is mushy, propose a sharper rewrite before appending.
Blue-sky generously, but apply pressure to deepen and tighten. Do not rush to outline. Do not group. Do not propose a structure. If the user starts asking about structure, redirect: "We're still mining. Structure comes later."
## File format
```markdown
# Working title
A first fragment lives here.
It can be multiple paragraphs. It can include lists, code, quotes — whatever
shape the fragment naturally takes.
---
A second fragment.
---
> A quoted line that the user wants to keep around.
A reaction to it.
---
- A cluster of related observations
- That hang together by feel
- And want to be near each other
```
Fragments are separated by a horizontal rule (`\n---\n`). No headings inside the body. No tags. No order beyond the order they were added.
## Writing rhythm
Append silently. Don't ask permission for each fragment. Mention what you added in passing ("adding that"), but don't interrupt the conversation with save dialogs.
Before every write: re-read the file from disk. The user may have edited, reordered, or deleted fragments between turns — preserve their changes. Never overwrite the file; only append (or, if the user asks, edit a specific fragment in place).
The user can say "cut the last one", "rewrite that one sharper", "merge those two" at any time. Treat those as first-class instructions.
## Out of scope
- Outlines, section plans, paragraph structure, transitions.
- Deciding the article's thesis, argument, or audience.
- Producing prose that reads as finished writing.
- Linking fragments together with connective tissue.
If the user is ready for any of that, the session is over and a different tool takes over. Do not name or recommend that tool — just stop.
</supporting-info>
+64
View File
@@ -0,0 +1,64 @@
---
name: writing-shape
description: Take a markdown file of raw material and shape it into an article through a conversational session — drafting candidate openings, growing the piece paragraph by paragraph, arguing about format (lists, tables, callouts, quotes) at each step. Use when the user has a pile of notes, fragments, or a rough draft and wants help turning it into something publishable.
---
<what-to-do>
The user has passed (or will pass) a markdown file of raw material. Treat it as the input pile — anything from a tidy list of fragments to a wall of unstructured prose to a transcript. The format does not matter. Read it end-to-end before doing anything else.
Then run a shaping session that produces a separate article document. Do not edit the raw material file — it is read-only to this skill.
If the user did not say where to save the article, ask once and remember the path. The user will be editing the article file during the session; always re-read it before writing so their edits are preserved.
</what-to-do>
<supporting-info>
## The loop
1. **Read the pile.** Read the input file in full. Form a sense of what's in it.
2. **Draft 23 candidate openings.** Each opening should imply a different thesis or angle for the article. Show all of them. Force the user to pick or compose a hybrid. The chosen opening defines what the rest of the article must do.
3. **Grow paragraph by paragraph.** After the opening lands, ask "given this opening, what does the reader need to hear next?" Pull material from the pile to answer. Argue about whether the next beat is a paragraph, a list, a table, a callout, a quote, a code block. Each format choice should be deliberate and defensible.
4. **Append to the article file as you go.** Don't batch. Write each agreed paragraph or block immediately so the user can see the article taking shape.
5. **Loop step 3 until the article is done.** The user decides when it's done.
## Conversational feel
This is a grilling session inverted. In ideation, the question was "what are you actually noticing?" Here it's "what is this article actually arguing, and in what order does the reader need to hear it?" Push back. Refuse to let weak transitions slide. If a paragraph doesn't earn its place, cut it.
Specific moves to keep using:
- "What does this paragraph do for the reader that the previous one didn't?"
- "If I cut this, what breaks?"
- "Is this prose, or should it be a list? Why prose?"
- "This sentence is doing two jobs — split it or pick one."
- "The opening promised X. We've drifted to Y. Either re-thread it or change the opening."
## Pulling from the pile
Treat the raw material as a quarry, not a script. Pull a fragment, rework it to fit the surrounding paragraph, and place it. A fragment may be split across multiple paragraphs, merged with another, or paraphrased. The pile's job is to be mined; the article's job is to read as one voice.
If the pile lacks something the article needs, name the gap explicitly: "We need an example here and the pile doesn't have one — give me one now or we cut this section."
## Format arguments to actually have
When choosing how to render a beat, weigh these tradeoffs out loud with the user, not silently:
- **Prose vs. list.** Prose carries argument; lists carry parallel items. If items aren't truly parallel, prose is better. If they are, a list is faster to scan.
- **Inline vs. callout.** Tips, warnings, and asides go in callouts (`> [!TIP]`, `> [!NOTE]`) — but only if they'd genuinely derail the main argument inline. Otherwise leave them inline.
- **Table vs. repeated structure.** If the same shape repeats 3+ times with the same fields, a table. Otherwise prose with bold leads.
- **Quote vs. paraphrase.** Quote when the original wording is the point. Paraphrase when only the idea matters.
- **Code block vs. inline code.** Multi-line, runnable, or illustrative → block. Single token or identifier → inline.
## Writing rhythm
Append to the article file as each block is agreed. Re-read the file from disk before every write — the user may have edited between turns. Never overwrite blindly. If the user wants a paragraph rewritten, edit that specific paragraph in place; leave the rest alone.
## Out of scope
- Mining for new fragments that aren't in the pile (the pile is the input — if it's incomplete, name the gap and either get the user to fill it or cut the section).
- Editing the raw material file.
- Publishing, formatting for a specific platform, or adding frontmatter the user didn't ask for.
</supporting-info>