- Delete `packages/internal` workspace package — `registry-build.ts` and `module-new.ts` move to top-level `scripts/` (no `package.json`, not shipped); `pnpm registry:build` and `pnpm module:new` scripts updated in root `package.json` and `turbo.json`; CLAUDE.md / TODO.md references updated - Relocate CLI internals from `apps/cli/src/` → `apps/cli/src/lib/` — `codemod-runner.ts`, `manifest.ts`, `region-tracker.ts`, `registry-loader.ts`, `wizard.ts`; all intra-CLI imports updated to `@/lib/*` path alias via tsconfig `paths`; add `@types/bun` to CLI devDependencies - `stanza remove` now dispatches `revertCodemods()` as step 1 (before declarative cleanup) — re-loads the module adapter from the registry, calls imperative reverts while framework files are still intact, then sweeps remaining region claims; fixes `wrap-root-layout` / `re-export` regions previously left as "needs manual cleanup" despite shipping working reverts
8.0 KiB
TODO
State at end of last session: declarative slot-package extraction landed — auth/db/orm modules now install into their own internal workspace packages (packages/auth/, packages/db/ named @<project>/<dir>); the app consumes via workspace:*. Cross-package wiring is declared via peerPackages and templated via {{<dir>PackageName}} substitution. stanza add composes modules across slots (verified: framework next → db postgres → orm drizzle → auth better-auth produces a working tree with the right adapter selection and the auth package depending on the db package). 49 unit tests pass. apps/web is a minimal Vite-native TanStack Start scaffold — needs the actual builder UI.
Web app (apps/web) — priority
The builder is functionally wired but visually unfinished. It's inline-styled radios + a code block.
- Add Tailwind 4 to
apps/web— use the@tailwindcss/viteplugin (mirror what thestyling-tailwindmodule emits for thetanstack-startadapter) - Hand-roll a small component layer or pull in shadcn (web variant) for cards, buttons, inputs, code blocks
- Replace the radio-list
Builderwith a card grid per slot, showing module label + description + homepage link - Show why a module is filtered out (e.g. "needs
framework: next, you picked tanstack-start") instead of just dropping it - Deep linking: encode selections in URL search params (
?framework=next&orm=drizzle&...) so users can share configurations - Copy-to-clipboard for the generated
pnpm create stanza ...command - Preview pane: list of files stanza will write (derived from
module.adapters[].templates[].destfor the selected adapter combo) - Show pinned npm versions per selected module (from
adapter.dependencies/adapter.devDependencies) - Module detail route at
/m/$slot/$id— full description, all adapters, deps, env vars, templates list - Search route at
/searchbacked by the same registry index - Layout: header (logo, GitHub link, docs link), footer
- Dark mode (Tailwind 4
light-dark()+ system pref) - SEO: meta tags via
head()on routes, OG image, sitemap - Host the registry on the same domain — wire the registry-build output (
scripts/registry-build.ts→dist/registry/) toapps/web/public/registry/and serve statically, or via a Vercel route handler - Vercel deploy config —
vercel.jsonif needed, env vars forSTANZA_REGISTRY(point dev at local FS, prod at the deployed CDN path) - Docs section (could be MDX routes): overview, authoring guide, registry spec
CLI (apps/cli)
The wizard and verbs work but a few things from the plan are stubbed.
- Implement opt-out PostHog telemetry — wire
posthog-node(already a dep), prompt on first run, store atelemetryIdinstanza.json, respect--no-telemetryandDO_NOT_TRACK=1 --yesflag for non-interactiveinit— pick defaults via flags (--framework=nextetc.); essential for CI tests- HTTP registry loader path is implemented but unverified — smoke test against the static JSON output
stanza init: today'sbootstrapShelldoesn't emitturbo.json. Decide whether stanza ships that or a tooling module does. Also: the rootpnpm-workspace.yamlmust coverpackages/*so the runner's bootstrapped slot packages link correctly- Better error messages for
RegionConflictError(current message is technical; should suggeststanza remove <slot>or manual cleanup) bun buildthe CLI for publish — script exists, not yet exercised- Tests for command handlers (
init,add,remove) — current coverage is just codemods + resolver
Modules
Functional but a few real issues to fix.
auth-better-authtanstack-start adapter referencesimport.meta.env.VITE_BETTER_AUTH_URLbut the env var is declared asBETTER_AUTH_URL— either addVITE_prefix or read it server-sideauth-better-authdrizzleauth.tshardcodesprovider: "pg"in thedrizzleAdaptercall — wrong for the sqlite peer. Split the template per-db or pass the provider through a substitution varauth-better-authsqlite schema variant exists (shared/auth-schema.drizzle-sqlite.ts); confirm it matches what better-auth actually expects on SQLite end-to-endstyling-tailwind+framework-nextadapter writesapp/globals.cssover the framework's own — confirm the merge order produces the right import (@import "tailwindcss")- Authoring guide: docs page covering
defineModule, slot/peer/capability semantics, template vs. codemod choice, region ownership, and thescope: "package"+peerPackagesstory
Registry expansion
The full first-party module roadmap lives in REGISTRY.md. These are the schema/resolver changes needed before most of those modules can land.
- Add new slots to
KNOWN_SLOTS+slotOrder:api,ai,ui,payments,email,tooling,testing,deploy. Decide ordering for the wizard's topological prompts (deploy last; testing/tooling near the end; api/ai after framework) - Multi-choice slot support —
testingis the first slot where two modules co-exist (vitest + playwright). Either (a) make the slot valuestring[]instanza.jsonand update the resolver/UI, or (b) split intotesting-unit+testing-e2esub-slots. Pick before implementing the testing modules - Capability tag expansion — current set is
web | native | react | node | edge | ssr | rsc. Adding Nuxt/Svelte/Solid needsvue,svelte,solidcapabilities; existing React-only modules must addrequires: ['react']so the resolver filters correctly monorepois hardcoded to Turborepo inbootstrapShell— promote to a real slot only when a second option landspackageManagerYarn support — different workspace/lockfile semantics than pnpm/bun/npm; needs its own bootstrap branch- Cross-framework adapter explosion — Better Auth, tRPC, oRPC, the AI SDKs, etc. each need a sub-adapter per framework (next/tanstack-start/nuxt/svelte/solid). Decide whether to ship them all in one module with many adapters, or split per framework. Lean toward many-adapters-per-module to keep the slot count sane
Infrastructure
- GitHub Actions CI: typecheck (every workspace), unit tests, registry build, lint (add Biome or ESLint)
- Golden snapshot tests per module combination (per the plan's verification section) — for each valid
(framework, orm, db, auth, styling, pm)tuple, runstanza initheadless, snapshot the tree, compare against fixture - Integration test for the canonical stack — Docker Postgres + Playwright sign-up flow
- Registry deploy pipeline — on push to main, build
dist/registry/and push to Vercel/CF - npm publish workflow for
@stanza/cli+create-stanza(Changesets recommended; no changesets config yet) .env.exampleat repo root listingSTANZA_REGISTRY, PostHog key, etc.
Open items from the plan
- Domain clearance — confirm
stanza.dev/stanza.shavailability + decide - npm scope clearance —
@stanzascope availability (the CLI assumes@stanza/cli); fall back to unscopedstanzaif taken - Better Auth vs Clerk feature parity — Clerk wraps its own UI, Better Auth is headless; document the difference or ship shared UI stubs (
SignInForm, callback page) that each adapter fills in
Out of scope for now
These are real future work but consciously deferred — don't pull them in opportunistically.
stanza swap <slot> <to>— manifest already recordsversion+regionsto support it; slot-package extraction now means swap can replace the contents ofpackages/<dir>/without touching app importsstanza update— pinned-version 3-way merge- Third-party registry hosting — the spec exists implicitly; publish it formally later
- React Native / Expo modules — needs the
nativecapability + cross-platform framework slot - Additional first-party modules — full catalog tracked in REGISTRY.md; land the slot taxonomy changes above first