diff --git a/docs/superpowers/specs/2026-05-29-sp-stack-composer-design.md b/docs/superpowers/specs/2026-05-29-sp-stack-composer-design.md new file mode 100644 index 0000000..66ece0e --- /dev/null +++ b/docs/superpowers/specs/2026-05-29-sp-stack-composer-design.md @@ -0,0 +1,136 @@ +# sp-stack — Full-Stack Library Composer + +**Date:** 2026-05-29 +**Status:** Approved (design) +**Plugin:** `document-navigator` + +## Problem + +The marketplace exposes two ways into the 472-package `@suaveplan/*` catalog: + +- `library-navigator` — 383 self-contained `sp-` skills, one per library. +- `document-navigator/skills/sp` — greps the mirrored `docs/` tree to match a single + stated need to a package and pull verbatim code examples. + +Neither answers the question a user actually starts with: *"I want to build a +multi-tenant SaaS with email campaigns, Stripe billing, and a booking calendar — +which libraries do I need, and how do they fit together?"* Answering that today +means many manual `sp` lookups and hand-assembling the result. + +We need a skill that takes a whole-app description and returns the complete library +set, the wiring, and starter code — selected to **minimise the code the user writes** +(prefer a turnkey `api-plugin-payment` over hand-assembling `payment` + `retry` + +`webhook-client`). + +## Goals + +- Map a natural-language app description to the full set of `@suaveplan/*` packages + needed, across all 18 categories (backend, frontend, foundation, devtools). +- Always prefer the highest-level turnkey package for each capability. +- Emit a bill of materials, install command, host wiring, and starter code stitched + from **verbatim** docs examples — never fabricated imports. +- Surface gaps honestly: capabilities with no `@suaveplan` package, and external + prerequisites (API keys, datastores). + +## Non-Goals + +- No automated or batch generation of per-library skills (GUIDELINES.md §1 stands; + the capability manifest is a separate hand-curated artifact). +- No runtime/scaffolding tool — the skill emits code as text, it does not write a + project to disk. +- No change to the 383 `library-navigator` skills. + +## Decisions + +1. **Approach C (hybrid).** A curated capability manifest covers the common 80% with + precise, code-minimal picks; the existing `sp` docs-traversal is the fallback for + the long tail. This is the only approach that both guarantees the "prefer turnkey" + behavior and cannot silently miss a library. +2. **Housed in `document-navigator`**, sharing the relocated `docs/` tree. The composer + is a docs-navigation concern, so co-locating it avoids duplicating 32 MB or relying + on cross-plugin paths (which Claude Code has no mechanism for). +3. **`docs/` moves under the plugin** so the plugin is self-contained and portable + regardless of distribution. + +## Architecture + +### File layout + +``` +plugins/document-navigator/ + .claude-plugin/plugin.json + docs/ # moved from repo root (32 MB, ~6k .md) + skills/ + sp/SKILL.md # existing — description narrowed (see below) + sp-stack/ + SKILL.md # new composer skill + capabilities.md # curated capability manifest +``` + +### docs/ relocation + +`docs/` moves from the repo root to `plugins/document-navigator/docs/`. Every `docs/` +reference in `sp/SKILL.md` is rewritten from the hard-coded +`.claude/plugins/suaveplan-skills/docs/` path to `${CLAUDE_PLUGIN_ROOT}/docs/`. + +A repo-root path that only resolves when the entire marketplace is cloned together is +replaced by a plugin-relative path that resolves however the plugin is installed. + +### Capability manifest (`capabilities.md`) + +A small, hand-curated table — the heart of Approach C. One row per common capability: + +| Field | Purpose | +|---|---| +| `capability` | e.g. `payments`, `multi-tenancy`, `email-campaigns`, `file-upload` | +| `layer` | `backend` / `frontend` / `foundation` / `devtools` — drives grouping | +| `primary` | the turnkey package, the minimise-code pick (`@suaveplan/api-plugin-payment`) | +| `supporting` | deps it pulls in / commonly paired packages | +| `example_doc` | path into `docs/` where the verbatim quick-start lives | +| `external` | non-suaveplan prerequisites (Stripe keys, SurrealDB, SMTP) | + +The manifest is the only place the "prefer turnkey over low-level primitives" rule is +encoded, so selection is deterministic rather than re-derived per request. + +## Composer flow + +1. Parse the app description into a capability list plus an inferred app-type. +2. For each capability: + - **Manifest hit** → take `primary` + `supporting`, read its `example_doc` verbatim. + - **Manifest miss** → fall back to the `sp` docs-traversal (root → category → + subcategory → package) to locate candidates. +3. Dedupe packages, order by dependency (turnkey plugins first), group by `layer`. +4. Read the verbatim quick-start blocks from the docs tree. +5. Emit the output. + +## Output shape + +- **Bill of materials** grouped by layer, with a one-line reason per package. +- **Install command** — a single `bun add …`. +- **Wiring** — the `createHost({ plugins: [...] })` composition. +- **Starter code** — stitched from the verbatim docs examples. +- **Gaps & prerequisites** — capabilities with no `@suaveplan` package (write custom + or bring third-party) and required external services. + +## Coexistence with `sp` + +Two skills, differentiated sharply by description so Claude selects the right one: + +- **`sp`** — narrowed to *"find the library for a single stated need / how do I use X."* +- **`sp-stack`** — *"Describe a whole website/service/app; get the complete library set, + wiring, and starter code."* + +## Constraints inherited from existing skills + +- Only reference packages that exist under the docs tree; never invent package names. +- Use exact `@suaveplan/` identifiers. +- Extract code examples verbatim; never fabricate import paths. + +## Risks + +- **Manifest drift.** New packages need manual addition. Mitigation: the docs-traversal + fallback keeps the long tail reachable, so a missing manifest row degrades to the + current `sp` behavior rather than a wrong answer. +- **Two code paths.** Manifest + fallback. Both are simple, and the fallback is the + existing, already-exercised traversal. +```