diff --git a/.claude/skills/build-feature/SKILL.md b/.claude/skills/build-feature/SKILL.md new file mode 100644 index 00000000000..56a7804adb7 --- /dev/null +++ b/.claude/skills/build-feature/SKILL.md @@ -0,0 +1,91 @@ +--- +name: build-feature +description: >- + Execute an approved feature plan as atomic slices on a clean branch. Use for + /build-feature, or when the user says build/start/go after /plan-feature. + One slice at a time: implement, verify, describe, commit; pause at See/Work + checkpoints. Never big-bang scaffold. Requires a plan from /plan-feature + (or an equivalent phased slice list in the conversation). +icon: hammer +color: green +--- + +# Build Feature + +Execute an approved `/plan-feature` plan as a linear sequence of tiny, +finishable slices. Never scaffold a whole feature up front. + +Read `references/phase-model.md` for See / Work / Deepen rules and pause points. + +Companion: `/plan-feature` produces the plan. If there is no approved plan (or +equivalent phased slice list) in the conversation, stop and tell the user to +run `/plan-feature` first — or ask them to paste/attach the plan. + +--- + +## 0. Preconditions + +Before any code: + +1. Confirm the plan (or the subset to run: "See only", "through Work", specific phase IDs). +2. Confirm working tree is clean of unrelated work; stop if mixed junk is present. +3. Create a **brand new branch** off the plan's base (usually `6.x`): + +```bash +git fetch origin +git checkout +git pull origin +git checkout -b / +``` + +- Never pile a new feature onto a dirty mixed-purpose branch. +- One feature effort → one branch (stacked branches only if the plan says so). + +## 1. One slice at a time + +Work slices in plan order. For each slice: + +1. **Announce** the slice id + intent (e.g. `W2.1 — save create form`). +2. **Implement only that slice** — nothing speculative for later slices. +3. **Verify** — run the slice's stated checks (PHPUnit/Vitest/manual CP poke). +4. **Describe** — short note of what changed and how to see it. +5. **Commit** — focused message matching the slice's commit intent. +6. **Honor pause points** — after See / Work phase boundaries (and any plan-marked pause), stop. Tell the user what to open/click/run. Wait for "continue" unless they pre-approved a longer run ("do all See", "through Work"). + +## 2. Progression rules + +- Each commit leaves the project **coherent** — not necessarily complete, not a landmine. Prefer vertical thin slices over horizontal layers. +- See-phase code may be ugly or partial; still runnable enough to inspect. +- Finish Work happy path before starting Deepen. +- If a slice proves the plan wrong: pause, propose a small plan amendment, get a nod. For a full re-plan, send them back to `/plan-feature`. + +## 3. Testing bar + +- Add/adjust tests in the same slice that introduces behavior. +- No final "Phase N: dump all tests" unless the plan explicitly isolated a test-only slice for good reason. +- Manual CP verification counts for UI-only slices — say exactly where to look. + +## 4. Anti-patterns + +- Scaffolding models + CP + API + tests in one go +- Skipping commits until "it all works" +- Implementing Deepen items early "while we're here" +- Continuing past a pause point without approval +- Re-planning from scratch instead of a surgical amendment (unless asked) + +## 5. Done / pause summary + +At each pause and at the end: + +- What shipped (phase / slice ids) +- How to try it +- What's next (next slice/phase, or deferred Deepen) +- If the agreed scope is finished, say so plainly + +--- + +## Communication style + +- Expert, terse. Slice id first, then work. +- No giant status essays between slices. +- Don't re-litigate the plan unless blocked. diff --git a/.claude/skills/build-feature/references/phase-model.md b/.claude/skills/build-feature/references/phase-model.md new file mode 100644 index 00000000000..d86997502d4 --- /dev/null +++ b/.claude/skills/build-feature/references/phase-model.md @@ -0,0 +1,77 @@ +# Phase model + +Phases exist so a human can **stop, look, and poke** — not so an agent can batch work. + +## Phase groups + +Every plan assigns each phase to one group: + +### See — "I want to see it" + +- Make the feature **visible or tangible** as early as possible. +- Wire the thinnest possible path to something on screen / in CLI / in a test dump. +- Incomplete, stubbed, or broken behavior is OK if the shape is inspectable. +- Typical slices: route + empty CP view, fieldtype shell, config key that appears, nav item, read-only listing with fake data. +- Exit criterion: user can open/run something and recognize the feature. + +### Work — "I want to see it work" + +- Make the **core happy path** real. +- Still avoid secondary drivers, rare edge cases, and polish. +- Typical slices: create/edit/delete, persistence, validation, primary UX interaction, essential permissions. +- Exit criterion: user can complete the main job without fake data or "TODO" walls. + +### Deepen — "make it product-grade" + +- Integrations and parity that would have slowed See/Work. +- Examples for Statamic: Eloquent driver, GraphQL/REST, revisions, multisite, translations, docs, performance, addon hooks, a11y pass. +- Exit criterion: each deepen phase has its own demo/verify story; don't amalgamate into "the rest". + +## How many phases? + +As many as needed. Prefer **more small phases** over few large ones. + +Good: + +- See-1: CP nav + blank screen +- See-2: list UI with hard-coded rows +- Work-1: read from Stache +- Work-2: create form saves +- Work-3: edit + delete +- Deepen-1: permissions +- Deepen-2: Eloquent parity +- Deepen-3: translations + docs + +Bad: + +- Phase 1: everything backend +- Phase 2: everything frontend +- Phase 3: tests and docs + +## Atomic slices + +A slice is too big if you cannot: + +- explain it in one sentence, **and** +- verify it without building the next slice, **and** +- commit it without leaving half-related files "for later" uncommitted. + +If a slice needs a temporary seam (stub, fake data, feature flag), prefer that over pulling forward the next slice's real implementation. + +## Vertical over horizontal + +Prefer end-to-end thin cuts: + +`nav → view → one action → one test` + +over layer cakes: + +`all models → all controllers → all Vue → all tests` + +## Pause points + +After every See phase and every Work phase, the plan must include: + +> **Pause:** try X. Say continue when ready. + +Build mode honors these unless the user pre-authorizes a longer run ("do all See phases"). diff --git a/.claude/skills/plan-feature/SKILL.md b/.claude/skills/plan-feature/SKILL.md new file mode 100644 index 00000000000..37210fcd7a7 --- /dev/null +++ b/.claude/skills/plan-feature/SKILL.md @@ -0,0 +1,129 @@ +--- +name: plan-feature +description: >- + Plan new features from a brain dump: gap analysis, competitive research, + clarifying questions, and a phased See → Work → Deepen plan with atomic + slices. Use for /plan-feature, "plan this", "come up with a plan", or when + starting a feature from a rough dump. Does not implement — hand off to + /build-feature when the plan is approved. +icon: map +color: blue +--- + +# Plan Feature + +Turn a rough feature dump into a researched, phased plan with atomic slices. +**Do not write feature code in this skill.** When the plan is approved, tell +the user to run `/build-feature`. + +Read `references/phase-model.md` before writing phases. +Read `references/plan-template.md` when drafting the plan document. +Read `references/competitive-research.md` when doing competitor / peer research. + +Companion: `/build-feature` executes the approved plan. + +--- + +## 1. Ingest the dump + +Treat the user's message(s) as raw material, not a finished spec. + +- Extract goals, constraints, non-goals, named UI/UX beats, tech hunches, and open worries. +- Do **not** start coding. +- Do **not** ask one question at a time mid-ingest. Gather context first. + +## 2. Ground in this repo + +Before proposing anything: + +- Find existing related code, fieldtypes, CP patterns, APIs, config, and tests. +- Prefer extending established patterns over inventing parallel systems. +- Note Eloquent / Stache / GraphQL / REST / CP / frontend touchpoints that may matter later (often Deepen-phase work). + +## 3. Gap analysis (things they forgot) + +Actively hunt for omissions. Typical Statamic/CMS gaps: + +- Permissions, roles, and Pro vs free boundaries +- Multisite, localization, and publish states +- Revisions, blueprints, and default config +- Stache vs Eloquent driver parity +- API / GraphQL exposure +- Upgrade path, migrations, and backward compatibility +- Empty states, errors, loading, and keyboard/a11y in CP +- Docs, changelog, and translation strings +- Performance, caching, and large-site behavior +- Addon extension points / events / tags / modifiers + +List forgotten items as either **must decide**, **defer to Deepen**, or **out of scope**. + +## 4. Competitive / peer research + +Do lightweight but real research. Use web search / docs fetch when available. + +- Compare how peer products solve the same job (not feature checklists for vanity). +- Capture: interaction model, naming, defaults, killer detail worth stealing, traps to avoid. +- Prefer primary docs and recent product UI over random blogs. +- Fold findings into the plan as **recommendations**, not a separate essay. + +See `references/competitive-research.md` for who to check by domain. + +## 5. Clarifying questions + +After research + gap analysis, ask a **single batched** set of questions. + +Rules: + +- Only ask what changes the plan or sequencing. +- Prefer multiple-choice / opinionated defaults when possible ("Default: X — override?"). +- Separate **blockers** (need answer before planning further) from **nice-to-know**. +- If the user said "just plan" and leftovers are non-blocking, state assumptions and continue. + +Wait for answers on blockers before finalizing the plan (unless they explicitly want a draft plan with assumptions called out). + +## 6. Produce the plan + +Write the plan using `references/plan-template.md`. + +Hard requirements for every plan: + +1. **Phase groups** — organize work into groups the human can pause and explore: + - **See** — visible presence / spike. OK if incomplete or broken. Goal: *I can see it.* + - **Work** — core path actually works. Goal: *I can use it.* + - **Deepen** — integrations, parity, polish, edge cases (Eloquent, APIs, a11y, docs, etc.). Goal: *It belongs in the product.* +2. **Phases inside groups** — as many as needed (2 or 10). Each phase ends in something the user can open, click, run, or otherwise inspect. +3. **Atomic slices** — every phase is broken into the **smallest** finishable pieces. One concern per slice. No "set up the whole feature" slices. +4. **Linear dependency** — slices build on prior slices. No parallel mega-scaffolding. +5. **Per-slice contract** — each slice lists: intent, files/areas touched (best guess), how to verify, and commit message intent. +6. **Stop points** — explicit "pause for Jack to explore" markers after See phases and after Work phases (and anytime a phase changes what can be demoed). + +Anti-patterns (reject these in your own draft): + +- "Phase 1: scaffold models, CP Vue, API, and tests" +- Big-bang branches with everything half-wired +- Deepen work (Eloquent, GraphQL, …) blocking the first visible spike +- Vague slices ("improve UX", "handle edge cases") without a verify step + +## 7. Handoff + +Present the plan. Ask for approval or edits. **Do not implement.** + +When the plan looks good (approved, or user says go / build / start), end with an +explicit handoff — not a silent mode switch: + +> Plan's ready. Run **`/build-feature`** to execute it (clean branch, one slice +> at a time, pause at See/Work checkpoints). Say which phases to run if you +> don't want the whole thing yet (e.g. "See only"). + +If they ask you to build in the same turn without invoking the build skill, +still point them at `/build-feature` and follow that skill's instructions +(read `.claude/skills/build-feature/SKILL.md`) before writing code. + +--- + +## Communication style + +- Treat the user as an expert. Be terse and opinionated. +- Lead with the plan / questions, not process narration. +- Competitive notes: sharp takeaways only. +- Never drift into implementation during planning. diff --git a/.claude/skills/plan-feature/references/competitive-research.md b/.claude/skills/plan-feature/references/competitive-research.md new file mode 100644 index 00000000000..89fc4985fef --- /dev/null +++ b/.claude/skills/plan-feature/references/competitive-research.md @@ -0,0 +1,52 @@ +# Competitive / peer research + +Research informs the plan. It is not a slide deck. + +## How to research + +1. Name the **job** (e.g. "schedule publish UI", "asset folder permissions"), not the implementation. +2. Pick 2–4 peers that actually solve that job. +3. Prefer official docs + current product behavior over third-party listicles. +4. For each peer, capture only: + - How users accomplish the job + - Defaults / opinionated choices + - One thing they do better than our likely approach + - One thing to avoid +5. End with a **recommendation** that changes our phases or UX — or explicitly "no change; peers confirm X". + +Timebox: enough to improve the plan, not a market study. + +## Who to check (by domain) + +Use judgment; skip irrelevant columns. + +| Domain | Often worth checking | +| --- | --- | +| CMS / content modeling | Craft CMS, WordPress (+ Gutenberg), Kirby, Directus, Sanity, Storyblok, Contentful | +| Control panel UX | Craft CP, Filament, Nova, WordPress admin (for familiarity traps) | +| Assets / media | Craft Assets, WordPress Media, Cloudinary-style DAM patterns | +| Permissions / roles | Craft, WordPress roles/caps, Laravel policies / Filament shields | +| Live preview / front-end editing | Craft live preview, WordPress editor, visual editors generally | +| Search | Scout-style, Algolia docs patterns, Meilisearch | +| Multisite / i18n | Craft multi-site, WordPress multisite / multilingual plugins, Kirby languages | +| Forms | Craft Formie-class patterns, WordPress form plugins, Typeform-ish UX only if relevant | +| Commerce-ish | Only if the feature is commerce; otherwise skip | + +Also check **our own** prior art: Statamic addons, old issues, discussions, and similar fieldtypes/CP tools in this repo. + +## Output shape in the plan + +Keep it brutal: + +```markdown +## Competitive notes +- **Craft**: … → we should … +- **Kirby**: … → avoid … +- **Recommendation**: Prefer A over B in See/Work; leave C for Deepen. +``` + +## Anti-patterns + +- Feature matrices with 20 columns and no decision +- Citing competitors without tying to a phase or UX choice +- Letting competitor scope inflate Deepen into a rewrite of their entire product diff --git a/.claude/skills/plan-feature/references/phase-model.md b/.claude/skills/plan-feature/references/phase-model.md new file mode 100644 index 00000000000..d86997502d4 --- /dev/null +++ b/.claude/skills/plan-feature/references/phase-model.md @@ -0,0 +1,77 @@ +# Phase model + +Phases exist so a human can **stop, look, and poke** — not so an agent can batch work. + +## Phase groups + +Every plan assigns each phase to one group: + +### See — "I want to see it" + +- Make the feature **visible or tangible** as early as possible. +- Wire the thinnest possible path to something on screen / in CLI / in a test dump. +- Incomplete, stubbed, or broken behavior is OK if the shape is inspectable. +- Typical slices: route + empty CP view, fieldtype shell, config key that appears, nav item, read-only listing with fake data. +- Exit criterion: user can open/run something and recognize the feature. + +### Work — "I want to see it work" + +- Make the **core happy path** real. +- Still avoid secondary drivers, rare edge cases, and polish. +- Typical slices: create/edit/delete, persistence, validation, primary UX interaction, essential permissions. +- Exit criterion: user can complete the main job without fake data or "TODO" walls. + +### Deepen — "make it product-grade" + +- Integrations and parity that would have slowed See/Work. +- Examples for Statamic: Eloquent driver, GraphQL/REST, revisions, multisite, translations, docs, performance, addon hooks, a11y pass. +- Exit criterion: each deepen phase has its own demo/verify story; don't amalgamate into "the rest". + +## How many phases? + +As many as needed. Prefer **more small phases** over few large ones. + +Good: + +- See-1: CP nav + blank screen +- See-2: list UI with hard-coded rows +- Work-1: read from Stache +- Work-2: create form saves +- Work-3: edit + delete +- Deepen-1: permissions +- Deepen-2: Eloquent parity +- Deepen-3: translations + docs + +Bad: + +- Phase 1: everything backend +- Phase 2: everything frontend +- Phase 3: tests and docs + +## Atomic slices + +A slice is too big if you cannot: + +- explain it in one sentence, **and** +- verify it without building the next slice, **and** +- commit it without leaving half-related files "for later" uncommitted. + +If a slice needs a temporary seam (stub, fake data, feature flag), prefer that over pulling forward the next slice's real implementation. + +## Vertical over horizontal + +Prefer end-to-end thin cuts: + +`nav → view → one action → one test` + +over layer cakes: + +`all models → all controllers → all Vue → all tests` + +## Pause points + +After every See phase and every Work phase, the plan must include: + +> **Pause:** try X. Say continue when ready. + +Build mode honors these unless the user pre-authorizes a longer run ("do all See phases"). diff --git a/.claude/skills/plan-feature/references/plan-template.md b/.claude/skills/plan-feature/references/plan-template.md new file mode 100644 index 00000000000..7110365659a --- /dev/null +++ b/.claude/skills/plan-feature/references/plan-template.md @@ -0,0 +1,81 @@ +# Plan template + +Copy this structure. Omit sections only when truly empty — prefer an explicit "None" over silent gaps. + +```markdown +# Feature: + +## Problem / job to be done +<1–3 sentences> + +## Goals +- … + +## Non-goals +- … + +## Assumptions +- … (call out anything guessed) + +## Existing code to lean on +- `path` — why + +## Gaps / risks we almost forgot +| Item | Decision | +| --- | --- | +| … | must decide / defer (Deepen-N) / out of scope | + +## Competitive notes +- ****: takeaway → how it affects us +- **Recommendation**: … + +## Open questions +### Blockers +1. … + +### Non-blocking +1. … (default: …) + +## Approach (short) + + +## Phased build + +### See +#### Phase S1 — +**Demo:** <what Jack opens/clicks/runs> +**Pause after:** yes/no + +| Slice | Intent | Verify | Commit intent | +| --- | --- | --- | --- | +| S1.1 | … | … | … | +| S1.2 | … | … | … | + +#### Phase S2 — … +… + +### Work +#### Phase W1 — … +… + +### Deepen +#### Phase D1 — … +… + +## Branch +- Base: `6.x` (or …) +- Branch: `feature/<name>` + +## Definition of done (for agreed scope) +- [ ] … + +## Handoff +Execute with `/build-feature` (optionally: See only / through Work / full plan). +``` + +## Writing tips + +- Slice IDs stay stable (`S1.2`, `W2.1`) so `/build-feature` can say "doing W2.1". +- Verify column must be concrete: `./vendor/bin/phpunit --filter FooTest`, "CP → Foo → create → save", etc. +- If competitive research found nothing useful, say so in one line — don't pad. +- Always close the plan by pointing at `/build-feature`.