@c0x12c/spartan-ai-toolkit 1.0.1

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 (166) hide show
  1. package/.claude-plugin/marketplace.json +16 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/README.md +300 -0
  4. package/VERSION +1 -0
  5. package/agents/idea-killer.md +72 -0
  6. package/agents/micronaut-backend-expert.md +45 -0
  7. package/agents/research-planner.md +70 -0
  8. package/agents/solution-architect-cto.md +49 -0
  9. package/bin/cli.js +589 -0
  10. package/claude-md/00-header.md +39 -0
  11. package/claude-md/01-core.md +94 -0
  12. package/claude-md/05-database.md +20 -0
  13. package/claude-md/11-backend-micronaut.md +36 -0
  14. package/claude-md/20-frontend-react.md +23 -0
  15. package/claude-md/30-project-mgmt.md +91 -0
  16. package/claude-md/40-product.md +36 -0
  17. package/claude-md/50-ops.md +34 -0
  18. package/claude-md/60-research.md +75 -0
  19. package/claude-md/90-footer.md +21 -0
  20. package/commands/spartan/brainstorm.md +134 -0
  21. package/commands/spartan/brownfield.md +157 -0
  22. package/commands/spartan/careful.md +94 -0
  23. package/commands/spartan/content.md +17 -0
  24. package/commands/spartan/context-save.md +161 -0
  25. package/commands/spartan/daily.md +42 -0
  26. package/commands/spartan/debug.md +156 -0
  27. package/commands/spartan/deep-dive.md +55 -0
  28. package/commands/spartan/deploy.md +207 -0
  29. package/commands/spartan/e2e.md +264 -0
  30. package/commands/spartan/env-setup.md +166 -0
  31. package/commands/spartan/fe-review.md +134 -0
  32. package/commands/spartan/figma-to-code.md +244 -0
  33. package/commands/spartan/forensics.md +46 -0
  34. package/commands/spartan/freeze.md +84 -0
  35. package/commands/spartan/full-run.md +78 -0
  36. package/commands/spartan/fundraise.md +53 -0
  37. package/commands/spartan/gsd-upgrade.md +376 -0
  38. package/commands/spartan/guard.md +42 -0
  39. package/commands/spartan/init-project.md +178 -0
  40. package/commands/spartan/interview.md +154 -0
  41. package/commands/spartan/kickoff.md +52 -0
  42. package/commands/spartan/kotlin-service.md +109 -0
  43. package/commands/spartan/lean-canvas.md +222 -0
  44. package/commands/spartan/map-codebase.md +72 -0
  45. package/commands/spartan/migration.md +82 -0
  46. package/commands/spartan/next-app.md +317 -0
  47. package/commands/spartan/next-feature.md +197 -0
  48. package/commands/spartan/outreach.md +16 -0
  49. package/commands/spartan/phase.md +119 -0
  50. package/commands/spartan/pitch.md +18 -0
  51. package/commands/spartan/pr-ready.md +200 -0
  52. package/commands/spartan/project.md +106 -0
  53. package/commands/spartan/quickplan.md +122 -0
  54. package/commands/spartan/research.md +19 -0
  55. package/commands/spartan/review.md +102 -0
  56. package/commands/spartan/teardown.md +161 -0
  57. package/commands/spartan/testcontainer.md +97 -0
  58. package/commands/spartan/think.md +221 -0
  59. package/commands/spartan/unfreeze.md +13 -0
  60. package/commands/spartan/update.md +81 -0
  61. package/commands/spartan/validate.md +193 -0
  62. package/commands/spartan/workstreams.md +109 -0
  63. package/commands/spartan/write.md +16 -0
  64. package/commands/spartan.md +222 -0
  65. package/frameworks/00-framework-comparison-guide.md +317 -0
  66. package/frameworks/01-lean-canvas.md +196 -0
  67. package/frameworks/02-design-sprint.md +304 -0
  68. package/frameworks/03-foundation-sprint.md +337 -0
  69. package/frameworks/04-business-model-canvas.md +391 -0
  70. package/frameworks/05-customer-development.md +426 -0
  71. package/frameworks/06-jobs-to-be-done.md +358 -0
  72. package/frameworks/07-mom-test.md +392 -0
  73. package/frameworks/08-value-proposition-canvas.md +488 -0
  74. package/frameworks/09-javelin-board.md +428 -0
  75. package/frameworks/10-build-measure-learn.md +467 -0
  76. package/frameworks/11-mvp-approaches.md +533 -0
  77. package/frameworks/think-before-build.md +593 -0
  78. package/lib/assembler.js +52 -0
  79. package/lib/packs.js +16 -0
  80. package/lib/resolver.js +144 -0
  81. package/lib/resolver.test.js +140 -0
  82. package/package.json +48 -0
  83. package/packs/backend-micronaut.yaml +34 -0
  84. package/packs/backend-nodejs.yaml +15 -0
  85. package/packs/backend-python.yaml +15 -0
  86. package/packs/core.yaml +25 -0
  87. package/packs/database.yaml +21 -0
  88. package/packs/frontend-react.yaml +23 -0
  89. package/packs/ops.yaml +16 -0
  90. package/packs/packs.compiled.json +281 -0
  91. package/packs/product.yaml +20 -0
  92. package/packs/project-mgmt.yaml +21 -0
  93. package/packs/research.yaml +39 -0
  94. package/packs/shared-backend.yaml +14 -0
  95. package/rules/backend-micronaut/API_DESIGN.md +250 -0
  96. package/rules/backend-micronaut/CONTROLLERS.md +755 -0
  97. package/rules/backend-micronaut/KOTLIN.md +483 -0
  98. package/rules/backend-micronaut/RETROFIT_PLACEMENT.md +258 -0
  99. package/rules/backend-micronaut/SERVICES_AND_BEANS.md +673 -0
  100. package/rules/core/NAMING_CONVENTIONS.md +208 -0
  101. package/rules/database/ORM_AND_REPO.md +393 -0
  102. package/rules/database/SCHEMA.md +146 -0
  103. package/rules/database/TRANSACTIONS.md +311 -0
  104. package/rules/frontend-react/FRONTEND.md +344 -0
  105. package/rules/shared-backend/ARCHITECTURE.md +46 -0
  106. package/skills/api-endpoint-creator/SKILL.md +560 -0
  107. package/skills/api-endpoint-creator/error-handling-guide.md +244 -0
  108. package/skills/api-endpoint-creator/examples.md +522 -0
  109. package/skills/api-endpoint-creator/testing-patterns.md +302 -0
  110. package/skills/article-writing/SKILL.md +95 -0
  111. package/skills/backend-api-design/SKILL.md +187 -0
  112. package/skills/brainstorm/SKILL.md +85 -0
  113. package/skills/competitive-teardown/SKILL.md +105 -0
  114. package/skills/content-engine/SKILL.md +101 -0
  115. package/skills/database-patterns/SKILL.md +145 -0
  116. package/skills/database-table-creator/SKILL.md +588 -0
  117. package/skills/database-table-creator/examples.md +552 -0
  118. package/skills/database-table-creator/migration-template.sql +68 -0
  119. package/skills/database-table-creator/validation-checklist.md +337 -0
  120. package/skills/deep-research/SKILL.md +94 -0
  121. package/skills/idea-validation/SKILL.md +115 -0
  122. package/skills/investor-materials/SKILL.md +115 -0
  123. package/skills/investor-outreach/SKILL.md +98 -0
  124. package/skills/kotlin-best-practices/SKILL.md +145 -0
  125. package/skills/market-research/SKILL.md +113 -0
  126. package/skills/security-checklist/SKILL.md +150 -0
  127. package/skills/startup-pipeline/SKILL.md +125 -0
  128. package/skills/testing-strategies/SKILL.md +156 -0
  129. package/skills/ui-ux-pro-max/SKILL.md +377 -0
  130. package/skills/ui-ux-pro-max/data/charts.csv +26 -0
  131. package/skills/ui-ux-pro-max/data/colors.csv +97 -0
  132. package/skills/ui-ux-pro-max/data/icons.csv +101 -0
  133. package/skills/ui-ux-pro-max/data/landing.csv +31 -0
  134. package/skills/ui-ux-pro-max/data/products.csv +97 -0
  135. package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  136. package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  137. package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  138. package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  139. package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  140. package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  141. package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  142. package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  143. package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  144. package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  145. package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  146. package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  147. package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  148. package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  149. package/skills/ui-ux-pro-max/data/styles.csv +68 -0
  150. package/skills/ui-ux-pro-max/data/typography.csv +58 -0
  151. package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  152. package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  153. package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  154. package/skills/ui-ux-pro-max/scripts/core.py +253 -0
  155. package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  156. package/skills/ui-ux-pro-max/scripts/search.py +114 -0
  157. package/templates/competitor-analysis.md +60 -0
  158. package/templates/content/AGENT_TEMPLATE.md +47 -0
  159. package/templates/content/COMMAND_TEMPLATE.md +27 -0
  160. package/templates/content/RULE_TEMPLATE.md +40 -0
  161. package/templates/content/SKILL_TEMPLATE.md +41 -0
  162. package/templates/idea-canvas.md +47 -0
  163. package/templates/prd-template.md +84 -0
  164. package/templates/project-readme.md +35 -0
  165. package/templates/user-interview.md +69 -0
  166. package/templates/validation-checklist.md +108 -0
@@ -0,0 +1,317 @@
1
+ ---
2
+ name: spartan:next-app
3
+ description: Scaffold a complete new Next.js application from scratch — App Router, TypeScript, Tailwind, testing setup, API client layer, auth scaffolding, and CI config.
4
+ argument-hint: "[app name] [brief description]"
5
+ ---
6
+
7
+ # New Next.js App: {{ args[0] }}
8
+ Description: {{ args[1] }}
9
+
10
+ Scaffolding a **production-ready** Next.js application. This is more complete than
11
+ `/spartan:next-feature` — use this for a brand-new frontend project.
12
+
13
+ ---
14
+
15
+ ## Step 1: Clarify before building
16
+
17
+ Ask:
18
+ 1. **Auth**: None / NextAuth.js / custom JWT / Clerk / Auth0?
19
+ 2. **State management**: Server-only (preferred) / Zustand / React Query for client state?
20
+ 3. **Connects to which BE service(s)?** (Kotlin service names/URLs)
21
+ 4. **Deploy target**: Railway / Vercel / AWS / Docker+K8s?
22
+ 5. **Database** (if any — for full-stack Next.js with Prisma): Yes / No, using separate BE
23
+
24
+ **Auto mode on?** → Use defaults: No auth, Server-only state, Railway deploy, no DB (separate BE). Proceed immediately.
25
+ **Auto mode off?** → Wait for answers.
26
+
27
+ ---
28
+
29
+ ## Step 2: Bootstrap with create-next-app
30
+
31
+ ```bash
32
+ npx create-next-app@latest {{ args[0] }} \
33
+ --typescript \
34
+ --tailwind \
35
+ --app \
36
+ --src-dir \
37
+ --import-alias "@/*" \
38
+ --no-eslint # we configure this ourselves
39
+
40
+ cd {{ args[0] }}
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Step 3: Install core dependencies
46
+
47
+ ```bash
48
+ # Testing
49
+ npm install -D vitest @vitejs/plugin-react jsdom
50
+ npm install -D @testing-library/react @testing-library/user-event @testing-library/jest-dom
51
+
52
+ # API + validation
53
+ npm install zod
54
+
55
+ # Auth (if NextAuth chosen)
56
+ npm install next-auth@beta # v5 for App Router
57
+
58
+ # Dev tooling
59
+ npm install -D eslint-config-next @typescript-eslint/eslint-plugin prettier
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Step 4: Configure project structure
65
+
66
+ ```
67
+ src/
68
+ ├── app/ # App Router
69
+ │ ├── (auth)/ # Route group — auth pages
70
+ │ │ ├── login/page.tsx
71
+ │ │ └── layout.tsx
72
+ │ ├── (dashboard)/ # Route group — protected pages
73
+ │ │ ├── layout.tsx # ← auth check here
74
+ │ │ └── [feature]/
75
+ │ ├── api/ # API routes (only when server actions aren't enough)
76
+ │ ├── globals.css
77
+ │ └── layout.tsx # Root layout
78
+ ├── components/
79
+ │ ├── ui/ # Shared primitives (Button, Input, Card...)
80
+ │ └── [feature]/ # Feature-specific components
81
+ ├── lib/
82
+ │ ├── api/ # BE API client functions
83
+ │ │ ├── client.ts # Base fetch wrapper
84
+ │ │ └── [service].api.ts # Per-service functions
85
+ │ ├── auth/ # Auth utilities
86
+ │ └── utils.ts # cn(), formatDate(), etc.
87
+ ├── hooks/ # Custom React hooks (client-side)
88
+ ├── types/ # Shared TypeScript types
89
+ │ └── api.types.ts # Mirror Kotlin DTOs here
90
+ └── middleware.ts # Auth + route protection
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Step 5: Create base API client
96
+
97
+ ```typescript
98
+ // src/lib/api/client.ts
99
+ const BASE_URL = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:8080'
100
+
101
+ type ApiError = {
102
+ message: string
103
+ code: string
104
+ status: number
105
+ }
106
+
107
+ export class ApiClient {
108
+ private static async request<T>(
109
+ path: string,
110
+ options?: RequestInit & { tags?: string[] }
111
+ ): Promise<T> {
112
+ const res = await fetch(`${BASE_URL}${path}`, {
113
+ ...options,
114
+ headers: {
115
+ 'Content-Type': 'application/json',
116
+ ...options?.headers,
117
+ },
118
+ next: options?.tags ? { tags: options.tags } : undefined,
119
+ })
120
+
121
+ if (!res.ok) {
122
+ const error: ApiError = await res.json().catch(() => ({
123
+ message: 'Unknown error',
124
+ code: 'UNKNOWN',
125
+ status: res.status,
126
+ }))
127
+ throw new Error(error.message)
128
+ }
129
+
130
+ return res.json()
131
+ }
132
+
133
+ static get<T>(path: string, tags?: string[]) {
134
+ return this.request<T>(path, { tags })
135
+ }
136
+
137
+ static post<T>(path: string, body: unknown) {
138
+ return this.request<T>(path, {
139
+ method: 'POST',
140
+ body: JSON.stringify(body),
141
+ })
142
+ }
143
+
144
+ static put<T>(path: string, body: unknown) {
145
+ return this.request<T>(path, {
146
+ method: 'PUT',
147
+ body: JSON.stringify(body),
148
+ })
149
+ }
150
+
151
+ static delete<T>(path: string) {
152
+ return this.request<T>(path, { method: 'DELETE' })
153
+ }
154
+ }
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Step 6: Configure Vitest
160
+
161
+ ```typescript
162
+ // vitest.config.ts
163
+ import { defineConfig } from 'vitest/config'
164
+ import react from '@vitejs/plugin-react'
165
+ import path from 'path'
166
+
167
+ export default defineConfig({
168
+ plugins: [react()],
169
+ test: {
170
+ environment: 'jsdom',
171
+ globals: true,
172
+ setupFiles: ['./src/test/setup.ts'],
173
+ },
174
+ resolve: {
175
+ alias: {
176
+ '@': path.resolve(__dirname, './src'),
177
+ },
178
+ },
179
+ })
180
+ ```
181
+
182
+ ```typescript
183
+ // src/test/setup.ts
184
+ import '@testing-library/jest-dom'
185
+ import { vi } from 'vitest'
186
+
187
+ // Mock Next.js navigation
188
+ vi.mock('next/navigation', () => ({
189
+ useRouter: () => ({ push: vi.fn(), replace: vi.fn(), back: vi.fn() }),
190
+ usePathname: () => '/',
191
+ useSearchParams: () => new URLSearchParams(),
192
+ }))
193
+ ```
194
+
195
+ Add to `package.json`:
196
+ ```json
197
+ {
198
+ "scripts": {
199
+ "test": "vitest",
200
+ "test:run": "vitest run",
201
+ "test:coverage": "vitest run --coverage"
202
+ }
203
+ }
204
+ ```
205
+
206
+ ---
207
+
208
+ ## Step 7: Environment variables
209
+
210
+ Create `.env.local`:
211
+ ```bash
212
+ NEXT_PUBLIC_API_URL=http://localhost:8080
213
+ # NEXTAUTH_URL=http://localhost:3000
214
+ # NEXTAUTH_SECRET= # generate: openssl rand -base64 32
215
+ ```
216
+
217
+ Create `.env.example` (commit this):
218
+ ```bash
219
+ NEXT_PUBLIC_API_URL=http://localhost:8080
220
+ # NEXTAUTH_URL=https://your-domain.com
221
+ # NEXTAUTH_SECRET=your-secret-here
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Step 8: Deploy configuration
227
+
228
+ **Railway** (`railway.toml`):
229
+ ```toml
230
+ [build]
231
+ builder = "nixpacks"
232
+
233
+ [deploy]
234
+ startCommand = "npm start"
235
+ healthcheckPath = "/api/health"
236
+ healthcheckTimeout = 30
237
+ ```
238
+
239
+ Create `src/app/api/health/route.ts`:
240
+ ```typescript
241
+ export function GET() {
242
+ return Response.json({ status: 'ok', timestamp: new Date().toISOString() })
243
+ }
244
+ ```
245
+
246
+ **Docker** (`Dockerfile`):
247
+ ```dockerfile
248
+ FROM node:20-alpine AS deps
249
+ WORKDIR /app
250
+ COPY package*.json ./
251
+ RUN npm ci
252
+
253
+ FROM node:20-alpine AS builder
254
+ WORKDIR /app
255
+ COPY --from=deps /app/node_modules ./node_modules
256
+ COPY . .
257
+ RUN npm run build
258
+
259
+ FROM node:20-alpine AS runner
260
+ WORKDIR /app
261
+ ENV NODE_ENV=production
262
+ COPY --from=builder /app/.next/standalone ./
263
+ COPY --from=builder /app/.next/static ./.next/static
264
+ COPY --from=builder /app/public ./public
265
+ EXPOSE 3000
266
+ CMD ["node", "server.js"]
267
+ ```
268
+
269
+ Add to `next.config.ts`: `output: 'standalone'`
270
+
271
+ ---
272
+
273
+ ## Step 9: First test — smoke test
274
+
275
+ ```typescript
276
+ // src/app/page.test.tsx
277
+ import { render, screen } from '@testing-library/react'
278
+ import { describe, it, expect } from 'vitest'
279
+ import Home from './page'
280
+
281
+ describe('Home page', () => {
282
+ it('renders without crashing', () => {
283
+ render(<Home />)
284
+ expect(document.body).toBeDefined()
285
+ })
286
+ })
287
+ ```
288
+
289
+ Run: `npm test` — must be green before moving on.
290
+
291
+ ---
292
+
293
+ ## Step 10: GitHub Actions CI
294
+
295
+ ```yaml
296
+ # .github/workflows/ci.yml
297
+ name: CI
298
+
299
+ on: [push, pull_request]
300
+
301
+ jobs:
302
+ test:
303
+ runs-on: ubuntu-latest
304
+ steps:
305
+ - uses: actions/checkout@v4
306
+ - uses: actions/setup-node@v4
307
+ with:
308
+ node-version: '20'
309
+ cache: 'npm'
310
+ - run: npm ci
311
+ - run: npm run test:run
312
+ - run: npm run build
313
+ ```
314
+
315
+ After scaffolding complete:
316
+ "✅ App scaffolded. Run `npm run dev` to start. First test is green.
317
+ Use `/spartan:next-feature [name]` to build individual features."
@@ -0,0 +1,197 @@
1
+ ---
2
+ name: spartan:next-feature
3
+ description: Scaffold a new Next.js feature following App Router conventions — pages, components, server actions, types, and tests.
4
+ argument-hint: "[feature name] [brief description]"
5
+ ---
6
+
7
+ # Next.js Feature: {{ args[0] }}
8
+ Description: {{ args[1] }}
9
+
10
+ You are scaffolding a new Next.js feature following **App Router** conventions for the Spartan frontend.
11
+
12
+ ---
13
+
14
+ ## Step 1: Clarify before building
15
+
16
+ Ask the user:
17
+ 1. Is this a **page** (new route), a **component** (reusable UI), or a **feature** (page + components + logic)?
18
+ 2. Does it need **data fetching** from the Kotlin BE? If yes, which API endpoints?
19
+ 3. Is any part **interactive** (needs `'use client'`)? What interactions?
20
+ 4. Any **auth/access control** requirements?
21
+
22
+ **Auto mode on?** → Infer answers from the feature name and codebase context. Assume "feature" type, check existing API patterns, proceed immediately.
23
+ **Auto mode off?** → Wait for answers, then proceed.
24
+
25
+ ---
26
+
27
+ ## Step 2: Map the directory structure
28
+
29
+ Based on answers, propose this structure under `app/` or `components/`:
30
+
31
+ ```
32
+ # For a new PAGE feature:
33
+ app/[feature-name]/
34
+ page.tsx ← Server Component (data fetching here)
35
+ page.test.tsx ← Tests
36
+ layout.tsx ← Only if needs own layout
37
+ loading.tsx ← Loading UI (Suspense boundary)
38
+ error.tsx ← Error boundary
39
+ _components/ ← Feature-local components
40
+ FeatureCard.tsx
41
+ FeatureCard.test.tsx
42
+ _actions/ ← Server Actions for mutations
43
+ createFeature.ts
44
+ updateFeature.ts
45
+ _types/ ← TypeScript types
46
+ feature.types.ts
47
+
48
+ # For a reusable COMPONENT:
49
+ components/[ComponentName]/
50
+ [ComponentName].tsx
51
+ [ComponentName].test.tsx
52
+ [ComponentName].stories.tsx ← If using Storybook
53
+ index.ts ← Re-export
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Step 3: Create types first
59
+
60
+ In `_types/feature.types.ts`:
61
+
62
+ ```typescript
63
+ // Mirror the Kotlin DTO structure from BE
64
+ export interface FeatureDto {
65
+ id: string
66
+ // ... fields from BE response
67
+ createdAt: string // ISO string from BE
68
+ }
69
+
70
+ // For API responses — always typed
71
+ export interface ApiResponse<T> {
72
+ data: T
73
+ message?: string
74
+ }
75
+
76
+ // For form/mutation input
77
+ export interface CreateFeatureInput {
78
+ // ...
79
+ }
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Step 4: Create API client
85
+
86
+ ```typescript
87
+ // lib/api/feature.api.ts
88
+
89
+ import { FeatureDto, CreateFeatureInput } from '@/app/[feature]/_types/feature.types'
90
+
91
+ export async function getFeature(id: string): Promise<FeatureDto> {
92
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/features/${id}`, {
93
+ next: { revalidate: 60 }, // ISR: revalidate every 60s
94
+ })
95
+
96
+ if (!res.ok) {
97
+ throw new Error(`Failed to fetch feature: ${res.status}`)
98
+ }
99
+
100
+ return res.json()
101
+ }
102
+
103
+ export async function createFeature(input: CreateFeatureInput): Promise<FeatureDto> {
104
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/features`, {
105
+ method: 'POST',
106
+ headers: { 'Content-Type': 'application/json' },
107
+ body: JSON.stringify(input),
108
+ })
109
+
110
+ if (!res.ok) {
111
+ const error = await res.json()
112
+ throw new Error(error.message || 'Failed to create feature')
113
+ }
114
+
115
+ return res.json()
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Step 5: Create Server Component page
122
+
123
+ ```typescript
124
+ // app/[feature-name]/page.tsx
125
+ import { getFeature } from '@/lib/api/feature.api'
126
+ import { FeatureCard } from './_components/FeatureCard'
127
+
128
+ // Metadata for SEO
129
+ export const metadata = {
130
+ title: '[Feature Name] | Spartan',
131
+ }
132
+
133
+ interface PageProps {
134
+ params: { id: string }
135
+ searchParams: { [key: string]: string | undefined }
136
+ }
137
+
138
+ export default async function FeaturePage({ params }: PageProps) {
139
+ // Data fetching directly in Server Component
140
+ const feature = await getFeature(params.id)
141
+
142
+ return (
143
+ <main>
144
+ <FeatureCard feature={feature} />
145
+ </main>
146
+ )
147
+ }
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Step 6: Write tests FIRST (TDD)
153
+
154
+ ```typescript
155
+ // page.test.tsx — Server Component test
156
+ import { render, screen } from '@testing-library/react'
157
+ import { describe, it, expect, vi } from 'vitest'
158
+ import FeaturePage from './page'
159
+
160
+ // Mock the API call
161
+ vi.mock('@/lib/api/feature.api', () => ({
162
+ getFeature: vi.fn()
163
+ }))
164
+
165
+ describe('FeaturePage', () => {
166
+ it('renders feature data when loaded', async () => {
167
+ // given
168
+ const mockFeature = { id: '1', name: 'Test Feature' }
169
+ vi.mocked(getFeature).mockResolvedValue(mockFeature)
170
+
171
+ // when
172
+ const page = await FeaturePage({ params: { id: '1' }, searchParams: {} })
173
+ render(page)
174
+
175
+ // then
176
+ expect(screen.getByText('Test Feature')).toBeInTheDocument()
177
+ })
178
+ })
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Step 7: Environment variables check
184
+
185
+ Ensure these are set in `.env.local` (and in Railway env vars):
186
+ ```
187
+ NEXT_PUBLIC_API_URL=http://localhost:8080 # local
188
+ # Railway: set to production BE service URL
189
+ ```
190
+
191
+ After scaffolding, run:
192
+ ```bash
193
+ npm run dev
194
+ npm test -- --watch [feature-name]
195
+ ```
196
+
197
+ Say: "Feature scaffolded. First failing test written. Say **'go'** to implement."
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: spartan:outreach
3
+ description: Draft personalized investor outreach emails — cold, warm intro, and follow-up
4
+ argument-hint: "[investor name or context]"
5
+ ---
6
+
7
+ # Outreach: {{ args[0] | default: "investor email" }}
8
+
9
+ Draft investor communication.
10
+
11
+ ## Steps
12
+
13
+ 1. Use the `investor-outreach` skill
14
+ 2. If investor name is given, search for their thesis, portfolio, recent activity
15
+ 3. Personalize the email based on real data
16
+ 4. If no investor info is available, create a template and flag what needs personalizing
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: spartan:phase
3
+ description: Manage project phases — discuss requirements, plan tasks, execute work, verify results. This is the Spartan wrapper for GSD phase commands. Use after /spartan:project new.
4
+ argument-hint: "[discuss | plan | execute | verify] [phase number]"
5
+ ---
6
+
7
+ # Phase {{ args[1] | default: "?" }}: {{ args[0] | default: "discuss" }}
8
+
9
+ You are managing a phase in the current GSD project.
10
+ The user does NOT need to know about `/gsd:*` commands — everything runs through `/spartan:*`.
11
+
12
+ ---
13
+
14
+ {% if args[0] == "discuss" %}
15
+ ## Discuss Phase {{ args[1] | default: "N" }}
16
+
17
+ Gathering requirements for this phase. But first — Office Hours.
18
+
19
+ **MANDATORY: Ask these 3 forcing questions BEFORE gathering requirements:**
20
+
21
+ 1. **"What pain are we actually solving?"** (not the feature — the underlying pain)
22
+ 2. **"What's the narrowest version we can ship to learn?"** (force MVP thinking)
23
+ 3. **"What assumption are we making that could be wrong?"** (surface hidden risks)
24
+
25
+ **Auto mode on?** → Still ask these 3 questions. They prevent building the wrong thing.
26
+
27
+ Only after the user answers all 3 → proceed:
28
+
29
+ **Run:** `/gsd:discuss-phase {{ args[1] | default: "N" }}`
30
+
31
+ After discussion, decompose requirements into work units (WUs) per GSD v5:
32
+ - Each WU: max 3 files, max half-day, one commit
33
+ - Group into waves by dependency
34
+
35
+ Then tell the user:
36
+ "Requirements gathered and decomposed into [N] work units across [N] waves. Next step: `/spartan:phase plan {{ args[1] | default: "N" }}`"
37
+
38
+ {% elif args[0] == "plan" %}
39
+ ## Plan Phase {{ args[1] | default: "N" }}
40
+
41
+ Generating the execution plan with wave-parallel tasks.
42
+
43
+ **Before planning, check `.memory/index.md`** for relevant patterns, decisions, and knowledge from previous phases.
44
+
45
+ **Run:** `/gsd:plan-phase {{ args[1] | default: "N" }}`
46
+
47
+ The plan should include:
48
+ - Work units grouped into waves
49
+ - Wave 1 = independent tasks (can run in parallel tabs)
50
+ - Wave 2+ = depends on previous wave
51
+ - Each task has: files to touch, test to write first, commit message
52
+
53
+ Then tell the user:
54
+ "Plan ready with [N] waves. Next step: `/spartan:phase execute {{ args[1] | default: "N" }}`"
55
+
56
+ If the user has multiple Claude Code tabs available, suggest:
57
+ "Wave 1 has [N] independent tasks — you can run them in parallel tabs for speed."
58
+
59
+ {% elif args[0] == "execute" %}
60
+ ## Execute Phase {{ args[1] | default: "N" }}
61
+
62
+ Running the planned tasks wave by wave.
63
+
64
+ **Run:** `/gsd:execute-phase {{ args[1] | default: "N" }}`
65
+
66
+ During execution:
67
+ - Follow TDD: test first → implement → verify
68
+ - Respect safety guardrails if active (careful/freeze/guard)
69
+ - After each wave, verify all tests pass before starting next wave
70
+ - Capture new knowledge to `.memory/` as you go
71
+
72
+ After execution, tell the user:
73
+ "Phase {{ args[1] | default: "N" }} executed. [N] commits made. Next step: `/spartan:phase verify {{ args[1] | default: "N" }}`"
74
+
75
+ {% elif args[0] == "verify" %}
76
+ ## Verify Phase {{ args[1] | default: "N" }}
77
+
78
+ Running acceptance criteria checks and UAT.
79
+
80
+ **Run:** `/gsd:verify-work {{ args[1] | default: "N" }}`
81
+
82
+ After verification:
83
+ 1. Check all acceptance criteria from the discuss phase
84
+ 2. Run full test suite
85
+ 3. Extract decisions made → `.memory/decisions/`
86
+ 4. Extract patterns discovered → `.memory/patterns/`
87
+ 5. Update `.memory/index.md`
88
+
89
+ Then tell the user:
90
+ - If passed: "Phase {{ args[1] | default: "N" }} verified ✅. Next: `/spartan:phase discuss [N+1]` for the next phase, or `/spartan:project milestone-complete` if milestone is done."
91
+ - If failed: "Phase {{ args[1] | default: "N" }} has [N] issues. Fix them, then re-run `/spartan:phase verify {{ args[1] | default: "N" }}`."
92
+
93
+ {% else %}
94
+ ## Unknown action: {{ args[0] }}
95
+
96
+ Available actions:
97
+ - `/spartan:phase discuss N` — Gather requirements (starts with Office Hours)
98
+ - `/spartan:phase plan N` — Generate wave-parallel execution plan
99
+ - `/spartan:phase execute N` — Execute tasks wave by wave
100
+ - `/spartan:phase verify N` — Run acceptance criteria + UAT
101
+
102
+ Example: `/spartan:phase discuss 1`
103
+ {% endif %}
104
+
105
+ ---
106
+
107
+ ## Phase Lifecycle (for reference)
108
+
109
+ ```
110
+ /spartan:phase discuss N ← Office Hours → requirements → decompose
111
+
112
+ /spartan:phase plan N ← Wave-parallel plan from .memory/ context
113
+
114
+ /spartan:phase execute N ← TDD, wave by wave, safety guardrails
115
+
116
+ /spartan:phase verify N ← UAT + capture knowledge to .memory/
117
+
118
+ [next phase or milestone complete]
119
+ ```
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: spartan:pitch
3
+ description: Create investor-facing materials — deck outline, one-pager, memo, or financial model
4
+ argument-hint: "[what you need: deck, one-pager, memo, model]"
5
+ ---
6
+
7
+ # Pitch: {{ args[0] | default: "deck outline" }}
8
+
9
+ Create investor materials.
10
+
11
+ ## Steps
12
+
13
+ 1. Use the `investor-materials` skill
14
+ 2. Check for existing research in the project's `02-research/` and `03-validation/` folders
15
+ 3. Use that data as the source of truth
16
+ 4. Save to the project's `04-build/` folder
17
+
18
+ If there's no prior research, warn that the materials will be weaker without data.