diff --git a/docs/superpowers/plans/2026-05-29-sp-stack-composer.md b/docs/superpowers/plans/2026-05-29-sp-stack-composer.md new file mode 100644 index 0000000..0768221 --- /dev/null +++ b/docs/superpowers/plans/2026-05-29-sp-stack-composer.md @@ -0,0 +1,411 @@ +# sp-stack Full-Stack Library Composer Implementation Plan + +> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add an `sp-stack` skill that turns a whole-app description into a complete `@suaveplan/*` library set, wiring, and starter code — and relocate the `docs/` tree into the plugin that owns it. + +**Architecture:** Approach C (hybrid). A curated capability manifest (`capabilities.md`) covers the common app capabilities with turnkey, code-minimal picks; the existing `sp` docs-traversal is the long-tail fallback. Both skills live in `document-navigator` and share the relocated `docs/` tree, referenced via `${CLAUDE_PLUGIN_ROOT}/docs/`. + +**Tech Stack:** Claude Code plugin skills (Markdown + YAML frontmatter). No build step, no test runner — verification is path-resolution and content checks via `grep` / `test -f`. + +**Spec:** `docs/superpowers/specs/2026-05-29-sp-stack-composer-design.md` + +--- + +## Chunk 1: Relocate docs/ and rewrite path references + +### Task 1: Move the docs tree into the plugin + +**Files:** +- Move: `docs/` (excluding `docs/superpowers/`) → `plugins/document-navigator/docs/` + +> Note: `docs/superpowers/` holds these specs/plans and must STAY at the repo root. +> Only the package-mirror categories move. + +- [ ] **Step 1: Snapshot the pre-move reference set (verification baseline)** + +Run: +```bash +grep -rIl --exclude-dir=.git -e "suaveplan-skills/docs" -e "\.\./docs/" -e " docs/" \ + plugins GUIDELINES.md .claude-plugin +``` +Expected: `plugins/document-navigator/skills/sp/SKILL.md` and `GUIDELINES.md` only. (These are rewritten in Tasks 2 and 4. If any OTHER file appears, stop and reassess — it is an unplanned reference into the docs tree.) + +- [ ] **Step 2: Confirm what is under docs/ root** + +Run: `ls docs/` +Expected: the 18 package categories (`api-stack`, `commerce`, `communication`, `devtools`, `foundation`, `gaming`, `geospatial`, …) plus the root files `README.md` and `_intro.md`, and the `superpowers/` directory. The `git mv` loop in Step 3 moves everything except `superpowers/` (so `README.md` and `_intro.md` move too). + +- [ ] **Step 3: Move every category (not superpowers/) with git mv** + +Run: +```bash +mkdir -p plugins/document-navigator/docs +for entry in docs/*; do + base="$(basename "$entry")" + [ "$base" = "superpowers" ] && continue + git mv "$entry" "plugins/document-navigator/docs/$base" +done +``` + +- [ ] **Step 4: Verify the move landed and superpowers/ stayed** + +Run: +```bash +test -f plugins/document-navigator/docs/README.md && echo "DOCS-OK" +test -f plugins/document-navigator/docs/api-stack/api/api-plugin-payment/README.md && echo "SEED-OK" +test -d docs/superpowers && echo "SPECS-STAYED" +test ! -e docs/api-stack && echo "ROOT-CLEAN" +``` +Expected: `DOCS-OK`, `SEED-OK`, `SPECS-STAYED`, `ROOT-CLEAN` all print. + +- [ ] **Step 5: Commit** + +```bash +git add -A +git commit -m "Move docs/ package mirror into document-navigator plugin" +``` + +--- + +### Task 2: Rewrite docs path references in sp/SKILL.md + +**Files:** +- Modify: `plugins/document-navigator/skills/sp/SKILL.md` + +The current file hard-codes `.claude/plugins/suaveplan-skills/docs/` in the Architecture table, File Structure block, and the two `grep` Patterns examples. Replace every occurrence with the portable `${CLAUDE_PLUGIN_ROOT}/docs/`. + +- [ ] **Step 1: Write the failing check** + +Run: `grep -c "suaveplan-skills/docs" plugins/document-navigator/skills/sp/SKILL.md` +Expected (before fix): a non-zero count (the stale paths still present). + +- [ ] **Step 2: Replace the docs-tree row in the Architecture table** + +Change: +``` +| Docs tree | `.claude/plugins/suaveplan-skills/docs/` (`.md`-only mirror of `packages/`, maintained externally) | +``` +to: +``` +| Docs tree | `${CLAUDE_PLUGIN_ROOT}/docs/` (`.md`-only mirror of `packages/`, maintained externally) | +``` + +- [ ] **Step 3: Replace the File Structure block** + +Change the fenced block that begins `.claude/plugins/suaveplan-skills/` so its root is `${CLAUDE_PLUGIN_ROOT}/` and the tree reads: +``` +${CLAUDE_PLUGIN_ROOT}/ + docs/ # mirrored .md tree (maintained externally) + / + README.md + / + README.md + / + README.md + src/ + .md + skills/sp/ + SKILL.md # this file +``` + +- [ ] **Step 4: Replace the two grep Patterns examples** + +Change: +```bash +grep -ri "sms" .claude/plugins/suaveplan-skills/docs/*/README.md +grep -ri "twilio" .claude/plugins/suaveplan-skills/docs/ +``` +to: +```bash +grep -ri "sms" ${CLAUDE_PLUGIN_ROOT}/docs/*/README.md +grep -ri "twilio" ${CLAUDE_PLUGIN_ROOT}/docs/ +``` + +- [ ] **Step 5: Run the check to verify it passes** + +Run: +```bash +grep -c "suaveplan-skills/docs" plugins/document-navigator/skills/sp/SKILL.md +grep -c "CLAUDE_PLUGIN_ROOT" plugins/document-navigator/skills/sp/SKILL.md +``` +Expected: first command prints `0`; second prints a non-zero count. + +- [ ] **Step 6: Commit** + +```bash +git add plugins/document-navigator/skills/sp/SKILL.md +git commit -m "Point sp skill at \${CLAUDE_PLUGIN_ROOT}/docs" +``` + +--- + +### Task 3: Update the docs path in GUIDELINES.md + +**Files:** +- Modify: `GUIDELINES.md` (§7.2, the `docs/` tree description, ~line 148) + +- [ ] **Step 1: Locate the stale reference** + +Run: `grep -n "suaveplan-skills/docs" GUIDELINES.md` +Expected: one hit in §7.2. + +- [ ] **Step 2: Rewrite it to the new repo location** + +Change `.claude/plugins/suaveplan-skills/docs////` to `plugins/document-navigator/docs////`. + +- [ ] **Step 3: Verify** + +Run: `grep -c "suaveplan-skills/docs" GUIDELINES.md` +Expected: `0`. + +- [ ] **Step 4: Commit** + +```bash +git add GUIDELINES.md +git commit -m "Update docs tree path in GUIDELINES §7.2" +``` + +--- + +## Chunk 2: The sp-stack skill and capability manifest + +### Task 4: Author the capability manifest + +**Files:** +- Create: `plugins/document-navigator/skills/sp-stack/capabilities.md` + +Each row maps a capability to its turnkey `primary` pick, supporting packages, the +`example_doc` path (relative to `docs/`), and external prerequisites. All `example_doc` +paths below were verified to exist under the relocated tree. + +- [ ] **Step 1: Create capabilities.md with the v1 seed (15–20 capabilities)** + +```markdown +# Capability Manifest + +Curated map of common app capabilities to turnkey `@suaveplan/*` packages. The +`sp-stack` skill consults this first; capabilities not listed fall back to the +`sp` docs-traversal. `example_doc` paths are relative to `${CLAUDE_PLUGIN_ROOT}/docs/`. + +| capability | layer | primary | supporting | example_doc | external | +|---|---|---|---|---|---| +| api-host | backend | @suaveplan/api | — | api-stack/api/api/README.md | — | +| auth | backend | @suaveplan/api-plugin-auth | @suaveplan/api-auth-better-auth | api-stack/api/api-plugin-auth/README.md | Better-Auth config | +| multi-tenancy | backend | @suaveplan/api-plugin-tenant | @suaveplan/api-tenant | api-stack/api/api-plugin-tenant/README.md | — | +| payments | backend | @suaveplan/api-plugin-payment | @suaveplan/payment | api-stack/api/api-plugin-payment/README.md | Stripe/Adyen/PayPal account + secret key | +| email-campaigns | backend | @suaveplan/campaigns | @suaveplan/suppression, @suaveplan/delivery-tracking | communication/emails/campaigns/README.md | — | +| transactional-email | backend | @suaveplan/emailer | @suaveplan/email-templates | communication/emails/emailer/README.md | SMTP creds or Gmail REST token | +| file-upload | backend | @suaveplan/api-plugin-file-upload | — | api-stack/api/api-plugin-file-upload/README.md | storage backend | +| search | backend | @suaveplan/api-plugin-search | — | api-stack/api/api-plugin-search/README.md | — | +| realtime-sse | backend | @suaveplan/api-plugin-sse | @suaveplan/api-sse-bun | api-stack/api/api-plugin-sse/README.md | — | +| rate-limiting | backend | @suaveplan/api-plugin-rate-limit | @suaveplan/rate-limiter | api-stack/api/api-plugin-rate-limit/README.md | — | +| notifications | backend | @suaveplan/api-plugin-notifications | @suaveplan/notification-channel | api-stack/api/api-plugin-notifications/README.md | APNs key (push) | +| webhooks | backend | @suaveplan/api-plugin-webhook | @suaveplan/webhook-client | api-stack/api/api-plugin-webhook/README.md | — | +| booking | backend | @suaveplan/booking | — | commerce/booking/booking/README.md | — | +| validation | foundation | @suaveplan/validation | — | foundation/data/validation/README.md | — | +| pwa | frontend | @suaveplan/pwa | — | foundation/data/pwa/README.md | — | +| client-data-hooks | frontend | @suaveplan/react-packer | @suaveplan/packer-browser | foundation/data/react-packer/README.md | React 19 | +| cli | devtools | @suaveplan/cli | — | devtools/tooling/cli/README.md | — | +| testing | devtools | @suaveplan/test-vite | — | devtools/tooling/test-vite/README.md | — | +``` + +(`booking` doc path is verified present at `commerce/booking/booking/README.md`.) + +- [ ] **Step 2: Verify every example_doc path resolves** + +Filter to data rows by **content**, not line number (the preamble makes line offsets +brittle): keep only lines starting with `|`, drop the header row (the `capability` +column is `$2` because the leading `|` makes `$1` empty) and the `|---|` separator +(`$6` is only dashes/spaces). + +Run: +```bash +cd plugins/document-navigator +awk -F'|' '/^\|/ && $2 !~ /capability/ && $6 !~ /^[- ]*$/ {gsub(/ /,"",$6); print $6}' \ + skills/sp-stack/capabilities.md \ + | grep -v '^$' | grep -v '^—$' \ + | while read p; do [ -f "docs/$p" ] && echo OK || echo "MISSING $p"; done \ + | sort | uniq -c +cd - +``` +Expected: a single line `18 OK`; no `MISSING` lines. (A `MISSING ` line means that +manifest row points at a doc that does not exist — fix the path before continuing.) + +- [ ] **Step 3: Commit** + +```bash +git add plugins/document-navigator/skills/sp-stack/capabilities.md +git commit -m "Add sp-stack capability manifest (v1 seed)" +``` + +--- + +### Task 5: Author the sp-stack SKILL.md + +**Files:** +- Create: `plugins/document-navigator/skills/sp-stack/SKILL.md` + +- [ ] **Step 1: Create SKILL.md** + +````markdown +--- +name: sp-stack +description: Describe a whole website, service, or app and get the complete @suaveplan/* library set, host wiring, and starter code — selected to minimise the code you write. +--- + +# Stack Composer for Suaveplan + +Turn a natural-language description of an entire website, service, or app into the full +set of `@suaveplan/*` packages needed across all layers, plus the wiring and starter +code to compose them. Selection always prefers the highest-level turnkey package so the +user writes as little code as possible. + +This skill is the whole-app counterpart to `sp` (which finds a library for a single +stated need). Use `sp-stack` when the input describes a product; use `sp` for "which +library does X" or "how do I use Y". + +## Inputs + +A product description, e.g. *"a multi-tenant SaaS with email campaigns, Stripe billing, +and a booking calendar"*. + +## Sources + +| Source | Path | +|--------|------| +| Capability manifest | `${CLAUDE_PLUGIN_ROOT}/skills/sp-stack/capabilities.md` | +| Docs tree (fallback + examples) | `${CLAUDE_PLUGIN_ROOT}/docs/` | + +## Flow + +1. **Decompose.** Parse the description into a list of capabilities and infer the + app-type (service / website / app / game). Map each capability to the manifest + vocabulary (auth, multi-tenancy, payments, email-campaigns, file-upload, search, + realtime-sse, rate-limiting, notifications, webhooks, booking, validation, pwa, + client-data-hooks, cli, testing, …). + +2. **Resolve each capability.** + - **Manifest hit** → take `primary` + `supporting`; open its `example_doc` under + `${CLAUDE_PLUGIN_ROOT}/docs/` and read the quick-start block verbatim. + - **Manifest miss** → fall back to the `sp` docs-traversal: root README → + `/README.md` → `/README.md` → package README, ranking + turnkey `api-plugin-*` / engine packages above low-level primitives. + +3. **Assemble.** Dedupe packages, order by dependency (turnkey plugins first), group by + `layer` (backend / frontend / foundation / devtools). + +4. **Read examples.** Pull the quick-start code verbatim from each chosen package's + docs. Never fabricate import paths. + +5. **Emit** the output below. + +## Output + +- **Bill of materials** — grouped by layer, one-line reason per package. +- **Install** — a single `bun add @suaveplan/… …`. +- **Wiring** — the `createHost({ plugins: [...] })` composition (see + `docs/api-stack/api/api/README.md` for the host entry point). +- **Starter code** — stitched from the verbatim docs examples. +- **Gaps & prerequisites** — capabilities with no `@suaveplan` package (the user writes + custom code or brings a third-party lib) and required external services (API keys, + datastores) drawn from each manifest row's `external` column. + +## Constraints + +- Only reference packages that exist under `${CLAUDE_PLUGIN_ROOT}/docs/`. Never invent + package names. +- Use exact `@suaveplan/` identifiers. +- Extract code examples verbatim from `.md` files; do not fabricate import paths. +- Prefer the turnkey package for a capability (the manifest's `primary`) over + hand-assembling low-level primitives. +- Be honest about gaps — do not imply coverage that the catalog does not provide. + +## Checklist + +1. Description decomposed into capabilities + app-type. +2. Each capability resolved via manifest, or via docs-traversal fallback when absent. +3. Packages deduped, dependency-ordered, grouped by layer. +4. Code examples pulled verbatim from the docs tree, not invented. +5. Gaps and external prerequisites stated explicitly. +```` + +- [ ] **Step 2: Verify frontmatter and source paths** + +Run: +```bash +f=plugins/document-navigator/skills/sp-stack/SKILL.md +grep -q "^name: sp-stack$" "$f" && echo "NAME-OK" +grep -q "^description: " "$f" && echo "DESC-OK" +grep -q "CLAUDE_PLUGIN_ROOT}/skills/sp-stack/capabilities.md" "$f" && echo "MANIFEST-REF-OK" +test -f plugins/document-navigator/skills/sp-stack/capabilities.md && echo "MANIFEST-EXISTS" +``` +Expected: `NAME-OK`, `DESC-OK`, `MANIFEST-REF-OK`, `MANIFEST-EXISTS` all print. + +- [ ] **Step 3: Commit** + +```bash +git add plugins/document-navigator/skills/sp-stack/SKILL.md +git commit -m "Add sp-stack composer skill" +``` + +--- + +### Task 6: Narrow the sp skill description + +**Files:** +- Modify: `plugins/document-navigator/skills/sp/SKILL.md` (frontmatter `description`) + +So Claude reliably routes single-need lookups to `sp` and whole-app requests to +`sp-stack`, sharpen `sp`'s description to the single-capability role. + +- [ ] **Step 1: Replace the description line** + +Change: +``` +description: Navigate the 500+ @suaveplan/* packages to find libraries matching a stated development need. Extracts code examples from the mirrored docs tree. +``` +to: +``` +description: Find the @suaveplan/* package for a single stated need ("which library does X", "how do I use Y") and extract its code examples from the docs tree. For whole-app stacks, use sp-stack. +``` + +- [ ] **Step 2: Verify the two descriptions are distinct and cross-referenced** + +Run: +```bash +grep "^description:" plugins/document-navigator/skills/sp/SKILL.md +grep "^description:" plugins/document-navigator/skills/sp-stack/SKILL.md +grep -q "sp-stack" plugins/document-navigator/skills/sp/SKILL.md && echo "CROSSREF-OK" +``` +Expected: two clearly different description lines print; `CROSSREF-OK` prints. + +- [ ] **Step 3: Commit** + +```bash +git add plugins/document-navigator/skills/sp/SKILL.md +git commit -m "Narrow sp skill description to single-need lookups" +``` + +--- + +## Final verification + +- [ ] **Step 1: End-to-end path + structure check** + +Run: +```bash +test -f plugins/document-navigator/docs/README.md && echo "DOCS-MOVED" +test -f plugins/document-navigator/skills/sp/SKILL.md && echo "SP-OK" +test -f plugins/document-navigator/skills/sp-stack/SKILL.md && echo "SPSTACK-OK" +test -f plugins/document-navigator/skills/sp-stack/capabilities.md && echo "MANIFEST-OK" +grep -rc "suaveplan-skills/docs" plugins GUIDELINES.md | grep -v ':0' || echo "NO-STALE-PATHS" +``` +Expected: `DOCS-MOVED`, `SP-OK`, `SPSTACK-OK`, `MANIFEST-OK`, `NO-STALE-PATHS` all print. + +- [ ] **Step 2: Manual smoke test (human or driving agent)** + +In a session with the plugin loaded, give `sp-stack` the prompt *"a multi-tenant SaaS +with email campaigns, Stripe billing, and a booking calendar"* and confirm the output +contains: a layered BOM, a `bun add` line, a `createHost` wiring block, starter code, +and a gaps/prerequisites section naming the Stripe key.