16 KiB
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/(excludingdocs/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:
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:
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:
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
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)
<category>/
README.md
<subcategory>/
README.md
<package>/
README.md
src/
<module>.md
skills/sp/
SKILL.md # this file
- Step 4: Replace the two grep Patterns examples
Change:
grep -ri "sms" .claude/plugins/suaveplan-skills/docs/*/README.md
grep -ri "twilio" .claude/plugins/suaveplan-skills/docs/
to:
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:
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
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, thedocs/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/<category>/<subcategory>/<pkg>/ to plugins/document-navigator/docs/<category>/<subcategory>/<pkg>/.
- Step 3: Verify
Run: grep -c "suaveplan-skills/docs" GUIDELINES.md
Expected: 0.
- Step 4: Commit
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)
# 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:
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 <path> line means that
manifest row points at a doc that does not exist — fix the path before continuing.)
- Step 3: Commit
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
---
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 →
`<category>/README.md` → `<subcategory>/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/<name>` 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:
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
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(frontmatterdescription)
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:
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
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:
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.