Files
skills/docs/superpowers/plans/2026-05-29-sp-stack-composer.md
admin 0b75ed5ce3 Add sp-stack implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 22:51:43 +01:00

412 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
<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:
```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/<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**
```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 <path>` 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 →
`<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:
```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.