@forgeailab/create-spark 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/.claude/skills/architecture-cutline/SKILL.md +96 -0
  2. package/.claude/skills/board-review/SKILL.md +77 -0
  3. package/.claude/skills/code-review/SKILL.md +76 -0
  4. package/.claude/skills/execute-task/SKILL.md +80 -0
  5. package/.claude/skills/idea-sharpen/SKILL.md +65 -0
  6. package/.claude/skills/implementation-brief/SKILL.md +87 -0
  7. package/.claude/skills/mvp-board/SKILL.md +95 -0
  8. package/.claude/skills/mvp-grill/SKILL.md +60 -0
  9. package/.claude/skills/mvp-spec/SKILL.md +78 -0
  10. package/.claude/skills/new-pack/SKILL.md +156 -0
  11. package/.claude/skills/next-task/SKILL.md +65 -0
  12. package/.claude/skills/pack-add/SKILL.md +64 -0
  13. package/.claude/skills/pack-resolve/SKILL.md +67 -0
  14. package/.claude/skills/parallel-execution/SKILL.md +68 -0
  15. package/.claude/skills/qa-verify/SKILL.md +77 -0
  16. package/.claude/skills/risk-check/SKILL.md +88 -0
  17. package/.claude/skills/sync-board/SKILL.md +76 -0
  18. package/.claude/skills/ux-theme/SKILL.md +93 -0
  19. package/.codex/skills/architecture-cutline/SKILL.md +94 -0
  20. package/.codex/skills/board-review/SKILL.md +75 -0
  21. package/.codex/skills/code-review/SKILL.md +73 -0
  22. package/.codex/skills/execute-task/SKILL.md +76 -0
  23. package/.codex/skills/idea-sharpen/SKILL.md +63 -0
  24. package/.codex/skills/implementation-brief/SKILL.md +85 -0
  25. package/.codex/skills/mvp-board/SKILL.md +93 -0
  26. package/.codex/skills/mvp-grill/SKILL.md +58 -0
  27. package/.codex/skills/mvp-spec/SKILL.md +76 -0
  28. package/.codex/skills/new-pack/SKILL.md +153 -0
  29. package/.codex/skills/next-task/SKILL.md +64 -0
  30. package/.codex/skills/pack-add/SKILL.md +62 -0
  31. package/.codex/skills/pack-resolve/SKILL.md +65 -0
  32. package/.codex/skills/parallel-execution/SKILL.md +66 -0
  33. package/.codex/skills/qa-verify/SKILL.md +74 -0
  34. package/.codex/skills/risk-check/SKILL.md +86 -0
  35. package/.codex/skills/sync-board/SKILL.md +72 -0
  36. package/.codex/skills/ux-theme/SKILL.md +91 -0
  37. package/package.json +10 -4
  38. package/packs/README.md +132 -0
  39. package/packs/ai-anthropic/files/app/api/ai/route.ts +57 -0
  40. package/packs/ai-anthropic/files/lib/anthropic.ts +15 -0
  41. package/packs/ai-anthropic/pack.toml +32 -0
  42. package/packs/ai-anthropic/skills/ai-feature-patterns/SKILL.md +87 -0
  43. package/packs/ai-anthropic/tasks.yaml +9 -0
  44. package/packs/ai-openai/files/app/api/ai-openai/route.ts +55 -0
  45. package/packs/ai-openai/files/lib/openai.ts +21 -0
  46. package/packs/ai-openai/pack.toml +30 -0
  47. package/packs/ai-openai/tasks.yaml +9 -0
  48. package/packs/analytics-posthog/files/components/PostHogProvider.tsx +19 -0
  49. package/packs/analytics-posthog/files/lib/posthog/client.ts +20 -0
  50. package/packs/analytics-posthog/files/lib/posthog/server.ts +24 -0
  51. package/packs/analytics-posthog/pack.toml +35 -0
  52. package/packs/analytics-posthog/tasks.yaml +15 -0
  53. package/packs/auth-better-auth/files/app/(auth)/login/page.tsx +58 -0
  54. package/packs/auth-better-auth/files/app/api/auth/[...all]/route.ts +4 -0
  55. package/packs/auth-better-auth/files/lib/auth.ts +21 -0
  56. package/packs/auth-better-auth/pack.toml +32 -0
  57. package/packs/auth-better-auth/tasks.yaml +10 -0
  58. package/packs/auth-better-auth-pg/files/app/api/auth/[...all]/route.ts +4 -0
  59. package/packs/auth-better-auth-pg/files/lib/auth.ts +86 -0
  60. package/packs/auth-better-auth-pg/pack.toml +32 -0
  61. package/packs/auth-better-auth-pg/tasks.yaml +17 -0
  62. package/packs/auth-supabase/files/app/(auth)/login/page.tsx +64 -0
  63. package/packs/auth-supabase/files/app/auth/callback/route.ts +15 -0
  64. package/packs/auth-supabase/files/middleware.ts +41 -0
  65. package/packs/auth-supabase/pack.toml +34 -0
  66. package/packs/auth-supabase/tasks.yaml +10 -0
  67. package/packs/db-postgres/files/compose/postgres.yml +28 -0
  68. package/packs/db-postgres/files/docker-compose.include.yml +1 -0
  69. package/packs/db-postgres/files/docker-compose.yml +6 -0
  70. package/packs/db-postgres/files/drizzle.config.ts +10 -0
  71. package/packs/db-postgres/files/lib/db/index.ts +10 -0
  72. package/packs/db-postgres/files/lib/db/schema.ts +11 -0
  73. package/packs/db-postgres/pack.toml +53 -0
  74. package/packs/db-postgres/tasks.yaml +11 -0
  75. package/packs/db-sqlite/files/drizzle.config.ts +10 -0
  76. package/packs/db-sqlite/files/lib/db.ts +8 -0
  77. package/packs/db-sqlite/files/lib/schema.ts +13 -0
  78. package/packs/db-sqlite/pack.toml +34 -0
  79. package/packs/db-sqlite/tasks.yaml +6 -0
  80. package/packs/db-supabase/files/lib/supabase/client.ts +8 -0
  81. package/packs/db-supabase/files/lib/supabase/server.ts +27 -0
  82. package/packs/db-supabase/pack.toml +32 -0
  83. package/packs/db-supabase/skills/supabase-patterns/SKILL.md +82 -0
  84. package/packs/db-supabase/tasks.yaml +6 -0
  85. package/packs/deploy-vercel/files/docs/deploy.md +21 -0
  86. package/packs/deploy-vercel/files/vercel.json +4 -0
  87. package/packs/deploy-vercel/pack.toml +30 -0
  88. package/packs/deploy-vercel/tasks.yaml +14 -0
  89. package/packs/docker-compose-dev/files/.env.docker.example +2 -0
  90. package/packs/docker-compose-dev/files/compose/redis.yml +17 -0
  91. package/packs/docker-compose-dev/files/docker-compose.include.yml +1 -0
  92. package/packs/docker-compose-dev/files/docker-compose.yml +6 -0
  93. package/packs/docker-compose-dev/pack.toml +38 -0
  94. package/packs/docker-compose-dev/tasks.yaml +9 -0
  95. package/packs/email-resend/files/app/api/email/test/route.ts +38 -0
  96. package/packs/email-resend/files/emails/welcome.tsx +66 -0
  97. package/packs/email-resend/files/lib/email.ts +40 -0
  98. package/packs/email-resend/pack.toml +34 -0
  99. package/packs/email-resend/tasks.yaml +9 -0
  100. package/packs/example/pack.toml +69 -0
  101. package/packs/payments-stripe/files/app/api/billing-portal/route.ts +24 -0
  102. package/packs/payments-stripe/files/app/api/checkout/route.ts +58 -0
  103. package/packs/payments-stripe/files/app/api/webhooks/stripe/route.ts +84 -0
  104. package/packs/payments-stripe/files/lib/stripe.ts +60 -0
  105. package/packs/payments-stripe/pack.toml +49 -0
  106. package/packs/payments-stripe/skills/stripe-patterns/SKILL.md +93 -0
  107. package/packs/payments-stripe/tasks.yaml +16 -0
  108. package/packs/sync-zero/files/components/ZeroProvider.tsx +3 -0
  109. package/packs/sync-zero/files/compose/zero-cache.yml +26 -0
  110. package/packs/sync-zero/files/docker-compose.include.yml +1 -0
  111. package/packs/sync-zero/files/docker-compose.yml +6 -0
  112. package/packs/sync-zero/files/lib/zero/client.ts +18 -0
  113. package/packs/sync-zero/files/lib/zero/schema.ts +17 -0
  114. package/packs/sync-zero/files/zero.config.ts +26 -0
  115. package/packs/sync-zero/pack.toml +61 -0
  116. package/packs/sync-zero/skills/zero-patterns/SKILL.md +69 -0
  117. package/packs/sync-zero/tasks.yaml +16 -0
  118. package/packs/testing-playwright/files/e2e/example.spec.ts +7 -0
  119. package/packs/testing-playwright/files/playwright.config.ts +33 -0
  120. package/packs/testing-playwright/pack.toml +25 -0
  121. package/packs/testing-playwright/tasks.yaml +9 -0
  122. package/packs/ui-shadcn/files/app/globals.css +56 -0
  123. package/packs/ui-shadcn/files/components/ui/button.tsx +47 -0
  124. package/packs/ui-shadcn/files/components/ui/card.tsx +33 -0
  125. package/packs/ui-shadcn/files/lib/utils.ts +6 -0
  126. package/packs/ui-shadcn/files/postcss.config.mjs +7 -0
  127. package/packs/ui-shadcn/files/tailwind.config.ts +57 -0
  128. package/packs/ui-shadcn/pack.toml +44 -0
  129. package/packs/ui-shadcn/skills/shadcn-dashboard-patterns/SKILL.md +85 -0
  130. package/packs/ui-shadcn/tasks.yaml +6 -0
  131. package/presets/docs-site.toml +4 -0
  132. package/presets/internal-tool.toml +4 -0
  133. package/presets/lean-saas.toml +4 -0
  134. package/presets/local-ai-mvp.toml +4 -0
  135. package/presets/saas-classic.toml +4 -0
  136. package/scripts/sync-skills.ts +223 -0
  137. package/src/paths.ts +22 -4
  138. package/templates/README.md +43 -0
  139. package/templates/astro/README.md +3 -0
  140. package/templates/astro/template.toml +4 -0
  141. package/templates/astro-starlight/README.md +3 -0
  142. package/templates/astro-starlight/template.toml +4 -0
  143. package/templates/nextjs/.ai/architecture.md +13 -0
  144. package/templates/nextjs/.ai/board.md +7 -0
  145. package/templates/nextjs/.ai/product-spec.md +11 -0
  146. package/templates/nextjs/.claude/skills/.gitkeep +0 -0
  147. package/templates/nextjs/.codex/skills/.gitkeep +0 -0
  148. package/templates/nextjs/AGENTS.md +95 -0
  149. package/templates/nextjs/CLAUDE.md +3 -0
  150. package/templates/nextjs/README.md +20 -0
  151. package/templates/nextjs/app/(app)/home/page.tsx +43 -0
  152. package/templates/nextjs/app/(app)/home/posts-panel.tsx +83 -0
  153. package/templates/nextjs/app/(app)/layout.tsx +12 -0
  154. package/templates/nextjs/app/(auth)/login/page.tsx +97 -0
  155. package/templates/nextjs/app/globals.css +23 -0
  156. package/templates/nextjs/app/layout.tsx +20 -0
  157. package/templates/nextjs/app/page.tsx +39 -0
  158. package/templates/nextjs/lib/auth-placeholder.ts +21 -0
  159. package/templates/nextjs/lib/posts-placeholder.ts +30 -0
  160. package/templates/nextjs/next.config.ts +5 -0
  161. package/templates/nextjs/package.json +26 -0
  162. package/templates/nextjs/postcss.config.mjs +7 -0
  163. package/templates/nextjs/spark.config.json +4 -0
  164. package/templates/nextjs/template.toml +4 -0
  165. package/templates/nextjs/tsconfig.json +27 -0
  166. package/templates/nextjs/types/post.ts +13 -0
  167. package/templates/one/README.md +5 -0
  168. package/templates/one/template.toml +4 -0
  169. package/templates/vite-react/README.md +3 -0
  170. package/templates/vite-react/template.toml +4 -0
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: qa-verify
3
+ description: Verify the app actually runs and the feature works end-to-end, not just that code compiles. Use after a feature batch lands, before a demo, when the user says "does this actually work?", "run it and check", or before flipping a task to `Validated`. Do NOT use as a substitute for `/code-review` — they cover different failure modes.
4
+ # Generated from .claude/skills/qa-verify/SKILL.md — DO NOT EDIT directly
5
+ ---
6
+
7
+ # Skill: qa-verify
8
+
9
+ ## Goal
10
+
11
+ Boot the app, click through the real user flow, and confirm the acceptance criteria hold when humans actually use the product. Type-checks and unit tests pass != feature works.
12
+
13
+ ## Recommended model
14
+
15
+ Sonnet 4.6. This is execution, not judgment.
16
+
17
+ ## Inputs
18
+
19
+ Read these (required):
20
+
21
+ - `.ai/board.md` — task(s) being verified
22
+ - `.ai/product-spec.md` — the core user journey
23
+
24
+ Read if useful:
25
+
26
+ - `.ai/ux-theme.md` for empty / loading / error patterns
27
+ - `README.md` / `package.json` for the run command
28
+
29
+ ## Rules
30
+
31
+ - Always run the app. If you cannot launch it, report that explicitly — do not claim verification from reading code.
32
+ - Walk the **core user journey from `product-spec.md`**, not just the changed feature. Regressions in adjacent flows count.
33
+ - Check empty / loading / error / mobile states for every screen touched. MVPs feel broken at the seams, not the happy path.
34
+ - Capture exact commands and outputs so the user can reproduce.
35
+ - Use a real browser or device when relevant (Playwright MCP if available). Curl-ing an API endpoint is not UI verification.
36
+
37
+ ## Workflow
38
+
39
+ 1. Find the run command (project README, `package.json` scripts, or ask).
40
+ 2. Boot the app. Note the URL.
41
+ 3. Walk the core journey step by step from the spec.
42
+ 4. Re-walk the specific feature(s) from the task(s).
43
+ 5. Probe empty / loading / error / mobile.
44
+ 6. Write the report.
45
+
46
+ ## Output format
47
+
48
+ ```md
49
+ ## QA verification — <TASK-ID(s)> / <feature name>
50
+
51
+ ### Boot
52
+ - Command: `<cmd>`
53
+ - Result: app running at <url> | failed (<reason>)
54
+
55
+ ### Core user journey (from spec)
56
+ - [x|✗] Step 1: <description> — <observation>
57
+ - [x|✗] Step 2: ...
58
+
59
+ ### Feature-specific checks
60
+ - [x|✗] <acceptance criterion> — <observation>
61
+
62
+ ### Edge states
63
+ - Empty state: <ok | broken | missing>
64
+ - Loading state: <ok | broken | missing>
65
+ - Error state: <ok | broken | missing>
66
+ - Mobile / narrow viewport: <ok | broken>
67
+
68
+ ### Broken flows discovered
69
+ - <one-line description> — <repro steps>
70
+
71
+ ### Recommended board update
72
+ - <TASK-ID>: review → Validated | review → In progress
73
+ - New tasks to add: <list or none>
74
+ ```
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: risk-check
3
+ description: Detect whether the project is drifting — scope creep, architecture creep, hidden dependencies, missing tests, unclear tasks, plus stale hybrid-pack helper versions (more than two minor versions behind the latest published). Use every few sessions, when the user says "are we on track?", "is this getting out of hand?", or before a demo. The anti-overthinking and anti-feature-creep skill.
4
+ # Generated from .claude/skills/risk-check/SKILL.md — DO NOT EDIT directly
5
+ ---
6
+
7
+ # Skill: risk-check
8
+
9
+ ## Goal
10
+
11
+ Be the brake. Compare the current state of the project to the spec and architecture, and call out where reality is drifting. Recommend concrete cuts.
12
+
13
+ ## Recommended model
14
+
15
+ Opus 4.7 or GPT-5.5.
16
+
17
+ ## Inputs
18
+
19
+ Read these (required):
20
+
21
+ - `.ai/product-spec.md`
22
+ - `.ai/architecture.md`
23
+ - `.ai/board.md`
24
+ - `.ai/decision-log.md` if it exists
25
+ - `.spark/state.json` if it exists
26
+ - `packs/*/pack.toml` if pack state exists and the registry is available
27
+
28
+ Sample reality:
29
+
30
+ - `git log --oneline -30`
31
+ - top-level directory listing
32
+ - list of dependencies in `package.json` / `pyproject.toml` / equivalent
33
+
34
+ ## Rules
35
+
36
+ - Compare **what is in the code now** to **what the spec said**. Highlight gaps in both directions: missing must-haves, plus things built that the spec did not ask for.
37
+ - Treat the spec's non-goals list as a checklist of things that should NOT be present in code. Violations are creep, not features.
38
+ - Recommend cuts, not additions. The default fix is "remove or defer," not "build more."
39
+ - Distinguish **drift** (planned scope grew quietly) from **discovery** (new task properly added to the board). Discovery is fine; silent drift is not.
40
+ - For pack-level drift, inspect `.spark/state.json` when present. For each installed pack, determine its provided capabilities from state or from `packs/<name>/pack.toml`; if none of those capabilities are referenced in `.ai/product-spec.md` or `.ai/architecture.md`, flag it as drift.
41
+ - The pack-level drift recommendation is exactly: **review or revert the pack-install commit via git**. Do not suggest a CLI removal command; v1 has no pack uninstall flow.
42
+ - For each installed pack whose manifest declares `[runtime_package]` (hybrid pack), inspect the consumer project's `package.json` (`dependencies` + `devDependencies`) for the named helper. Compare the installed version against the latest published version on the npm registry (use `bun pm view <pkg> version` or `npm view <pkg> version` via Bash). If the installed version is more than two minor versions behind the latest, flag it under "Stale helper". A `file:` specifier counts as "local dev link" and is NOT stale.
43
+
44
+ ## Checklist
45
+
46
+ - **Scope creep** — features in code that are not in `MVP feature list`, or are in `Non-goals`.
47
+ - **Architecture creep** — services / dependencies / abstractions beyond what `architecture.md` declared.
48
+ - **Pack-level drift** — installed packs whose provided capabilities are not justified by the spec or architecture.
49
+ - **Stale helper** — hybrid packs whose helper package is more than two minor versions behind the latest on npm.
50
+ - **Unclear tasks** — open board tasks without observable acceptance criteria.
51
+ - **Missing tests / verification** — tasks marked `Validated` with no run command or no review.
52
+ - **Hidden dependencies** — packages added not justified by a task or decision.
53
+ - **Stalled tasks** — tasks in `In progress` for more than ~2 sessions with no commits.
54
+
55
+ ## Output format
56
+
57
+ ```md
58
+ ## Pack-level drift
59
+ - no drift detected
60
+ - <pack-name>: provides <capability tag(s)>; none are referenced in `.ai/product-spec.md` or `.ai/architecture.md` — **recommend: review or revert the pack-install commit via git**
61
+
62
+ ## Stale helper
63
+ - no stale helpers
64
+ - <pack-name>: helper `<helper-package>` installed at <installed-version>, latest is <latest-version> — **recommend: `bun update <helper-package>`**
65
+
66
+ ## Risk check
67
+
68
+ ### Scope creep
69
+ - <thing built / in progress> — not in spec / in non-goals — **recommend: cut | defer | keep with decision log entry**
70
+
71
+ ### Architecture creep
72
+ - <new service / dep / abstraction> — **recommend: revert | document in architecture.md**
73
+
74
+ ### Unclear tasks
75
+ - <TASK-ID>: criteria are vague — **recommend: rewrite or send to `/board-review`**
76
+
77
+ ### Hidden dependencies
78
+ - <package> added in <commit> — justification: <none | <task>>
79
+
80
+ ### Stalled tasks
81
+ - <TASK-ID>: in progress since <when> — **recommend: split | unblock | drop**
82
+
83
+ ### Summary
84
+ - Drift severity: low | medium | high
85
+ - Suggested next action: <one line>
86
+ ```
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: sync-board
3
+ description: Update `.ai/board.md` to reflect actual code progress — apply status changes from execution reports, add discovered tasks, and recommend the next batch. Use after `/execute-task`, at the end of a working session, or when the user says "update the board", "sync progress", "what's next?". Do NOT use to create the initial board — that is `/mvp-board`.
4
+ # Generated from .claude/skills/sync-board/SKILL.md — DO NOT EDIT directly
5
+ ---
6
+
7
+ # Skill: sync-board
8
+
9
+ ## Goal
10
+
11
+ Keep `.ai/board.md` in sync with reality. The board is the source of truth — if it drifts from what is actually built, the whole system breaks.
12
+
13
+ ## Recommended model
14
+
15
+ Sonnet 4.6. This is mechanical reconciliation, not planning.
16
+
17
+ ## Inputs
18
+
19
+ Read these (required):
20
+
21
+ - `.ai/board.md`
22
+
23
+ Read if available:
24
+
25
+ - the most recent `/execute-task` report in the conversation
26
+ - `git status` and `git log` (one screenful) to confirm what actually changed
27
+ - `.ai/execution-log.md` if it exists
28
+
29
+ ## Rules
30
+
31
+ - **Trust git, not claims.** If a report says a file changed but git disagrees, flag it and do not advance the task.
32
+ - Never set status to `Validated` directly from execution. `Validated` requires a `/code-review` pass and, for user-facing changes, a `/qa-verify` pass. Update `Validation state` accordingly: `code-reviewed`, `qa-verified`, or `both`.
33
+ - Status flow is: `In progress` → `Needs review` → `Validated`. `Blocked` can come from any state.
34
+ - Never move a task to `Approved for execution`. That is `/board-review`'s job.
35
+ - New work discovered during execution becomes a new task in `Clarifying`, at the bottom of the relevant epic — not a silent edit to an existing task.
36
+ - Tasks the user explicitly cut go in the `Cut from MVP` section with a reason — never delete them.
37
+ - If a task is `Blocked`, record the specific blocker in a `Blocked by:` line.
38
+ - When a PR is opened, update `Linked PR:`. When a preview deploy exists, update `Demo URL:`.
39
+ - Append a one-line entry per state change to `.ai/execution-log.md` (create it if missing).
40
+
41
+ ## Workflow
42
+
43
+ 1. Read the board and the latest execution report.
44
+ 2. Run `git status` and a short `git log` to confirm actual changes.
45
+ 3. For each affected task: update status, append changed-files and verification result.
46
+ 4. Add any follow-up tasks discovered.
47
+ 5. Identify the next recommended task (or batch) based on dependencies.
48
+ 6. Write the updated board and append to the execution log.
49
+
50
+ ## Output format
51
+
52
+ After writing, return:
53
+
54
+ ```md
55
+ ## Board synced
56
+
57
+ ### Status changes
58
+ - <TASK-ID>: <old> → <new>
59
+
60
+ ### Tasks added
61
+ - <NEW-TASK-ID>: <title> (in <EPIC>)
62
+
63
+ ### Blockers
64
+ - <TASK-ID>: <reason>
65
+
66
+ ### Next recommended
67
+ - <TASK-ID> (or batch from `/parallel-execution`)
68
+ - Why now: <one line>
69
+
70
+ ### Drift detected
71
+ - <e.g. "claimed edit to foo.ts but git shows no change"> | none
72
+ ```
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: ux-theme
3
+ description: Define the visual and product direction (vibe, layout, color, typography, component style) before coding starts. Use when the user says "what should this look like?", "pick a theme", "make it feel like Linear/Notion/Vercel", or right before scaffolding UI. Do NOT use for fine-grained component styling — that belongs in execution.
4
+ # Generated from .claude/skills/ux-theme/SKILL.md — DO NOT EDIT directly
5
+ ---
6
+
7
+ # Skill: ux-theme
8
+
9
+ ## Goal
10
+
11
+ Produce `.ai/ux-theme.md` — a concrete visual direction that every executor task can consult. Lovable-style theme control: one clear vibe, one set of patterns, one reference product.
12
+
13
+ ## Recommended model
14
+
15
+ Opus 4.7 or GPT-5.5 for the direction. Sonnet 4.6 can implement against it later.
16
+
17
+ ## Inputs
18
+
19
+ Read these if they exist:
20
+
21
+ - `.ai/product-spec.md`
22
+ - `.ai/architecture.md`
23
+ - `.ai/decision-log.md`
24
+
25
+ ## Rules
26
+
27
+ - Pick **one** vibe. Not "minimal but playful but also enterprise."
28
+ - Name **one** reference product to imitate. "Linear-style productivity SaaS" beats "clean and modern."
29
+ - Give concrete tokens (color names, type scale, spacing) so executors do not invent their own.
30
+ - Define empty / loading / error patterns up front — these are where MVPs feel broken.
31
+ - Do not generate full design files. This is a brief, not Figma.
32
+
33
+ ## Reference directions (pick one or describe a new one)
34
+
35
+ - Linear-style productivity SaaS
36
+ - Notion-like workspace
37
+ - Vercel-like developer tool
38
+ - Stripe-like admin dashboard
39
+ - Arc-like playful consumer app
40
+
41
+ ## Output format
42
+
43
+ Write `.ai/ux-theme.md`:
44
+
45
+ ```md
46
+ # UX Theme — <name>
47
+
48
+ ## Vibe
49
+ <one sentence>
50
+
51
+ ## Reference product
52
+ <one product, with a link or short description of what to copy>
53
+
54
+ ## Layout style
55
+ <sidebar + content / centered single column / dashboard grid / etc.>
56
+
57
+ ## Color direction
58
+ - Background:
59
+ - Surface:
60
+ - Text primary:
61
+ - Text muted:
62
+ - Accent:
63
+ - Danger:
64
+ (prefer Tailwind palette names or hex)
65
+
66
+ ## Typography
67
+ - Display:
68
+ - Body:
69
+ - Mono:
70
+ - Scale: <e.g. 12 / 14 / 16 / 20 / 24 / 32>
71
+
72
+ ## Component style
73
+ - Corners: <radius>
74
+ - Borders: <weight, color>
75
+ - Shadows: <none / soft / layered>
76
+ - Buttons: <filled / outlined / ghost variants>
77
+ - Inputs: <style>
78
+
79
+ ## Patterns
80
+ - Empty state:
81
+ - Loading state:
82
+ - Error state:
83
+ - Table:
84
+ - Card:
85
+ - Dialog / modal:
86
+
87
+ ## Constraints
88
+ - <hard "no" rules, e.g. "no gradients", "no emoji in UI">
89
+ ```
90
+
91
+ After writing, recommend `/mvp-board` next.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeailab/create-spark",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Interactive scaffolder for spark projects with guided pack picker.",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -8,14 +8,20 @@
8
8
  },
9
9
  "files": [
10
10
  "src",
11
- "README.md"
11
+ "README.md",
12
+ "packs",
13
+ "presets",
14
+ "templates",
15
+ ".claude",
16
+ ".codex",
17
+ "scripts"
12
18
  ],
13
19
  "bin": {
14
20
  "create-spark": "./src/cli.ts"
15
21
  },
16
22
  "dependencies": {
17
- "@forgeailab/spark": "^0.1.1",
18
- "@forgeailab/spark-schema": "^0.1.1",
23
+ "@forgeailab/spark": "^0.1.3",
24
+ "@forgeailab/spark-schema": "^0.1.3",
19
25
  "@clack/prompts": "latest",
20
26
  "citty": "latest",
21
27
  "picocolors": "latest"
@@ -0,0 +1,132 @@
1
+ # Packs
2
+
3
+ A **pack** is a self-contained unit of capability — auth, db, payments, UI, AI SDK, email, deploy target, … — that the `spark` CLI can install into a scaffolded project. Packs are TOML-manifested, declarative (no shell hooks), and capability-resolved.
4
+
5
+ ## Directory layout
6
+
7
+ ```
8
+ packs/<name>/
9
+ ├── pack.toml # manifest (REQUIRED)
10
+ ├── files/ # tree of files to copy into the project (optional)
11
+ ├── skills/ # SKILL.md folders shipped with this pack (optional)
12
+ └── tasks.yaml # board tasks seeded into .ai/board.md on install (optional)
13
+ ```
14
+
15
+ ## `pack.toml`
16
+
17
+ See [`docs/pack-spec.md`](../docs/pack-spec.md) for the full schema. The Zod source of truth is `packages/spark-schema/src/pack.ts`.
18
+
19
+ A minimum-viable pack:
20
+
21
+ ```toml
22
+ name = "db-sqlite"
23
+ version = "0.1.0"
24
+ category = "db"
25
+ description = "Local SQLite database via bun:sqlite + drizzle-orm."
26
+
27
+ provides = ["db"]
28
+ requires = []
29
+ conflicts = ["db"]
30
+ requires_runtime = ["server"]
31
+ compatible_scaffolds = ["nextjs"]
32
+
33
+ [dependencies]
34
+ runtime = ["drizzle-orm"]
35
+ dev = ["drizzle-kit"]
36
+
37
+ [env]
38
+ required = ["DATABASE_URL"]
39
+
40
+ [[files]]
41
+ mode = "create"
42
+ from = "files/lib/db.ts"
43
+ to = "lib/db.ts"
44
+
45
+ [tasks]
46
+ file = "tasks.yaml"
47
+ ```
48
+
49
+ ## File modes
50
+
51
+ | Mode | Behavior |
52
+ |---|---|
53
+ | `create` | Fails if the destination already exists |
54
+ | `append` | Idempotent; uses `# >>> spark:<pack> >>>` / `# <<<` markers |
55
+ | `merge-json` | Deep-merges into an existing JSON file with deterministic key order |
56
+ | `template` | Handlebars-style substitution from `spark.config.json` (e.g. `{{appName}}`) |
57
+
58
+ ## Capability enums (closed)
59
+
60
+ **Pack capabilities** (`provides` / `requires` / `conflicts`):
61
+ `db, auth, payments, email, ui-kit, local-runtime, deploy-target, e2e, ai-sdk, blob-storage, analytics, sync`
62
+
63
+ Exclusive (one provider per project): `db, auth, payments, ui-kit, sync`
64
+ Non-exclusive (multiple providers OK): `ai-sdk, analytics, email, blob-storage, e2e, deploy-target, local-runtime`
65
+
66
+ **Template capabilities** (`requires_runtime`):
67
+ `static, server, react, native, vue, svelte, mdx-content, edge-runtime`
68
+
69
+ The two enums are separate and never overlap. Adding a new value requires a registry-wide change.
70
+
71
+ ## What is NOT allowed
72
+
73
+ - `post_install`, `hooks`, `pre_add`, `scripts` — packs MUST be declarative. If your pack needs a setup step that can't be expressed in `[[files]]`, ship it as a seeded board task the user runs manually.
74
+ - Pack-name conflicts (`conflicts = ["other-pack-name"]`). Use capability tags only.
75
+ - Cross-pack file ownership. Two packs MUST NOT write the same `to` path with `create` mode.
76
+
77
+ ## Adding a new pack
78
+
79
+ ```bash
80
+ # In Claude Code:
81
+ /new-pack realtime-supabase category=db
82
+ ```
83
+
84
+ Then fill in the generated `packs/realtime-supabase/pack.toml`. Validate with:
85
+
86
+ ```bash
87
+ bun -e "import {parsePackToml} from './packages/spark-schema/src/parse.ts'; import {readFileSync} from 'node:fs'; const r = parsePackToml(readFileSync('packs/realtime-supabase/pack.toml','utf8')); console.log(r.ok ? 'OK' : r.error);"
88
+ ```
89
+
90
+ See `packs/example/pack.toml` for a manifest that exercises every field.
91
+
92
+ ## v1 catalog
93
+
94
+ Each pack is either **copy** (ships file trees the user owns) or **hybrid** (ships thin wiring + imports runtime logic from a versioned `@forgeailab/spark-*` helper under `libs/`). The mode is inferred from the presence of a `[runtime_package]` block in the manifest.
95
+
96
+ | Pack | Category | Mode | Runtime helper |
97
+ |---|---|---|---|
98
+ | `auth-better-auth` | auth | **hybrid** | `@forgeailab/spark-auth-better-auth` (SQLite) |
99
+ | `auth-better-auth-pg` | auth | **hybrid** | `@forgeailab/spark-auth-better-auth` (Postgres) |
100
+ | `auth-supabase` | auth | copy | — |
101
+ | `db-sqlite` | db | copy | — |
102
+ | `db-postgres` | db | copy | — |
103
+ | `db-supabase` | db | copy | — |
104
+ | `sync-zero` | infra | **hybrid** | `@forgeailab/spark-sync-zero` |
105
+ | `payments-stripe` | payments | **hybrid** | `@forgeailab/spark-stripe-helpers` |
106
+ | `ai-anthropic` | ai | **hybrid** | `@forgeailab/spark-anthropic` |
107
+ | `ai-openai` | ai | copy | — |
108
+ | `ui-shadcn` | ui | copy | — |
109
+ | `email-resend` | email | copy | — |
110
+ | `analytics-posthog` | analytics | copy | — |
111
+ | `docker-compose-dev` | infra | copy | — |
112
+ | `testing-playwright` | testing | copy | — |
113
+ | `deploy-vercel` | deploy | copy | — |
114
+
115
+ ### Picking a db + auth pair
116
+
117
+ `auth-better-auth` and `auth-better-auth-pg` share the same runtime helper
118
+ (`@forgeailab/spark-auth-better-auth`) — they differ only in the `provider:`
119
+ their generated `lib/auth.ts` template hands to `drizzleAdapter`. Pair them:
120
+
121
+ - `db-sqlite` + `auth-better-auth` — fastest path, single file db, no infra.
122
+ - `db-postgres` + `auth-better-auth-pg` — production-shaped, **required for `sync-zero`** (Zero needs Postgres logical replication).
123
+ - `db-supabase` + `auth-better-auth-pg` — Supabase-hosted Postgres + Better Auth on top.
124
+
125
+ The two auth packs both `conflicts = ["auth"]`, so the resolver prevents
126
+ installing both. Mixing wrong pairs (e.g. `db-sqlite` + `auth-better-auth-pg`)
127
+ typechecks but fails at runtime — the drizzle adapter will reject sqlite tables
128
+ with `provider: 'pg'`.
129
+
130
+ The hybrid packs were authored against [`reference/full-stack-saas/`](../reference/full-stack-saas/) — the canonical integration showing all four helpers working together. When debugging a hybrid pack, start there.
131
+
132
+ See the root `README.md` for the catalog summary.
@@ -0,0 +1,57 @@
1
+ import { anthropic, streamResponse, type AnthropicChatMessage } from '@/lib/anthropic';
2
+ import { NextResponse, type NextRequest } from 'next/server';
3
+
4
+ export const runtime = 'nodejs';
5
+
6
+ const DEFAULT_MODEL = 'claude-sonnet-4-5';
7
+ const DEFAULT_MAX_TOKENS = 1_024;
8
+ const HARD_MAX_TOKENS = 4_096;
9
+
10
+ type ChatRequest = {
11
+ messages?: unknown;
12
+ system?: string;
13
+ model?: string;
14
+ maxTokens?: number;
15
+ };
16
+
17
+ function normalizeMessages(value: unknown): AnthropicChatMessage[] | undefined {
18
+ if (!Array.isArray(value)) return undefined;
19
+ const messages: AnthropicChatMessage[] = [];
20
+ for (const entry of value) {
21
+ if (typeof entry !== 'object' || entry === null) return undefined;
22
+ const role = 'role' in entry ? entry.role : undefined;
23
+ const content = 'content' in entry ? entry.content : undefined;
24
+ if ((role !== 'user' && role !== 'assistant') || typeof content !== 'string') return undefined;
25
+ messages.push({ role, content });
26
+ }
27
+ return messages.length > 0 ? messages : undefined;
28
+ }
29
+
30
+ export async function POST(request: NextRequest) {
31
+ const body = (await request.json().catch(() => ({}))) as ChatRequest;
32
+ const messages = normalizeMessages(body.messages);
33
+
34
+ if (!messages) {
35
+ return NextResponse.json(
36
+ { error: 'messages must be a non-empty array of user/assistant strings' },
37
+ { status: 400 },
38
+ );
39
+ }
40
+
41
+ const maxTokens = Math.min(Math.max(1, body.maxTokens ?? DEFAULT_MAX_TOKENS), HARD_MAX_TOKENS);
42
+
43
+ const stream = streamResponse(anthropic, {
44
+ model: body.model ?? DEFAULT_MODEL,
45
+ max_tokens: maxTokens,
46
+ system: body.system,
47
+ messages,
48
+ });
49
+
50
+ return new Response(stream, {
51
+ headers: {
52
+ 'Content-Type': 'text/event-stream; charset=utf-8',
53
+ 'Cache-Control': 'no-cache, no-transform',
54
+ Connection: 'keep-alive',
55
+ },
56
+ });
57
+ }
@@ -0,0 +1,15 @@
1
+ import type Anthropic from '@anthropic-ai/sdk';
2
+ import { createAnthropicClient, streamResponse } from '@forgeailab/spark-anthropic';
3
+
4
+ function requireEnv(name: string): string {
5
+ const value = process.env[name];
6
+ if (!value) {
7
+ throw new Error(`Missing required environment variable: ${name}`);
8
+ }
9
+ return value;
10
+ }
11
+
12
+ export const anthropic = createAnthropicClient(requireEnv('ANTHROPIC_API_KEY'));
13
+
14
+ export { streamResponse };
15
+ export type AnthropicChatMessage = Anthropic.Messages.MessageParam;
@@ -0,0 +1,32 @@
1
+ name = "ai-anthropic"
2
+ version = "1.0.0"
3
+ category = "ai"
4
+ description = "Anthropic SDK client and streaming chat endpoint."
5
+ provides = ["ai-sdk"]
6
+ requires = []
7
+ conflicts = []
8
+ requires_runtime = ["server"]
9
+ compatible_scaffolds = []
10
+
11
+ [runtime_package]
12
+ package = "@forgeailab/spark-anthropic"
13
+ version = "^0.1"
14
+
15
+ [env]
16
+ required = ["ANTHROPIC_API_KEY"]
17
+
18
+ [[files]]
19
+ mode = "create"
20
+ from = "lib/anthropic.ts"
21
+ to = "lib/anthropic.ts"
22
+
23
+ [[files]]
24
+ mode = "create"
25
+ from = "app/api/ai/route.ts"
26
+ to = "app/api/ai/route.ts"
27
+
28
+ [skills]
29
+ copy = ["skills/ai-feature-patterns"]
30
+
31
+ [tasks]
32
+ file = "tasks.yaml"
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: ai-feature-patterns
3
+ description: Build Anthropic-backed AI features with streaming UX, prompt discipline, and cost controls. Use when implementing or reviewing features after the ai-anthropic pack is installed.
4
+ allowed-tools:
5
+ - Read
6
+ - Write
7
+ - Edit
8
+ - Bash
9
+ ---
10
+
11
+ # Skill: ai-feature-patterns
12
+
13
+ ## Goal
14
+
15
+ Add one focused AI capability that helps the product journey without turning the
16
+ MVP into a generic chat app. Keep prompts inspectable, streams responsive, and
17
+ cost bounded by server-side controls.
18
+
19
+ ## Recommended model
20
+
21
+ Opus 4.7 or GPT-5.5 for prompt architecture and evaluation. Sonnet 4.6 or GPT-5
22
+ family executor for endpoint, UI, and test wiring.
23
+
24
+ ## Inputs
25
+
26
+ Read these before changing AI behavior:
27
+
28
+ - `.ai/product-spec.md` for the user workflow and non-goals
29
+ - `.ai/architecture.md` for persistence, auth, and runtime boundaries
30
+ - `.ai/board.md` for the exact AI task and acceptance criteria
31
+ - `lib/anthropic.ts` for shared client setup
32
+ - `app/api/ai/route.ts` for request, stream, and guardrail behavior
33
+
34
+ If the spec does not name the decision or artifact the AI should improve, stop
35
+ and ask. Do not add chat just because an AI SDK is installed.
36
+
37
+ ## Prompt Patterns
38
+
39
+ - Put durable behavior in a server-owned system prompt.
40
+ - Put user-specific state in structured context, not prose pasted from the UI.
41
+ - Keep task prompts narrow: role, input facts, output format, refusal boundary.
42
+ - Prefer JSON or Markdown output contracts only when the UI actually needs them.
43
+ - Do not ask the model to enforce authorization, billing, or data access rules.
44
+ - Include the smallest useful context window; retrieve or summarize before
45
+ sending long histories.
46
+
47
+ ## Streaming UX
48
+
49
+ - Stream text when the user is waiting on generation or analysis.
50
+ - Show partial output in the destination surface, not a separate debug pane.
51
+ - Preserve a cancel path when requests can take more than a few seconds.
52
+ - Persist the final answer only after the stream completes successfully.
53
+ - Treat stream errors as recoverable UI state with a retry action.
54
+
55
+ ## Cost Controls
56
+
57
+ - Cap `max_tokens` on the server, even when the client sends a smaller hint.
58
+ - Rate limit by user, organization, or IP before calling Anthropic.
59
+ - Add a cheap preflight check for empty prompts and unsupported file sizes.
60
+ - Log model, token caps, latency, and user/account id for cost review.
61
+ - Use smaller models or cached summaries for low-stakes transformations.
62
+ - Keep generated artifacts small enough to review and edit.
63
+
64
+ ## Safety and Privacy
65
+
66
+ - Send only the data needed for the requested feature.
67
+ - Redact secrets and credentials from context before model calls.
68
+ - Avoid storing raw prompts if they may contain sensitive customer data.
69
+ - Make model output advisory unless the product spec explicitly automates action.
70
+ - Require human confirmation before sending emails, charging users, or deleting data.
71
+
72
+ ## Common Pitfalls
73
+
74
+ - Do not stream from the browser directly with the API key.
75
+ - Do not let the client choose unlimited tokens or arbitrary expensive models.
76
+ - Do not hide prompt changes in component code; keep prompts close to API routes.
77
+ - Do not make acceptance criteria depend on subjective model quality alone.
78
+ - Do not add vector search, agents, or tool calls unless the board asks for them.
79
+
80
+ ## Verification
81
+
82
+ Use a small real prompt and confirm all of these:
83
+
84
+ - The endpoint streams incremental `text` events.
85
+ - The final event is `done`.
86
+ - Invalid input returns a 400 before calling Anthropic.
87
+ - Token caps and rate limits are enforced server-side.