Add sp-stack implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
411
docs/superpowers/plans/2026-05-29-sp-stack-composer.md
Normal file
411
docs/superpowers/plans/2026-05-29-sp-stack-composer.md
Normal file
@@ -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)
|
||||
<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.
|
||||
Reference in New Issue
Block a user