@kennethsolomon/shipkit 3.1.0 → 3.3.0

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.
package/README.md CHANGED
@@ -102,7 +102,7 @@ Brainstorm → Plan → Branch → [Schema] → Write Tests → Implement → Co
102
102
  | 19 | `/sk:smart-commit` | Auto-skip if already clean |
103
103
  | 20 | **`/sk:review`** | **GATE** — Review + Simplify — 0 issues including nitpicks |
104
104
  | 21 | `/sk:smart-commit` | Auto-skip if already clean |
105
- | 22 | **`/sk:e2e`** | **GATE** — E2E Tests — all end-to-end tests must pass |
105
+ | 22 | **`/sk:e2e`** | **GATE** — E2E Tests — prefers Playwright CLI when config detected, falls back to agent-browser; all scenarios must pass |
106
106
  | 23 | `/sk:smart-commit` | Auto-skip if already clean |
107
107
  | 24 | `/sk:update-task` | Mark done, log completion |
108
108
  | 25 | `/sk:finish-feature` | Changelog + PR |
@@ -196,6 +196,12 @@ Requirement changes → /sk:change → re-enter at correct step
196
196
  | `/sk:debug` | Structured bug investigation: reproduce → isolate → fix |
197
197
  | `/sk:hotfix` | Emergency fix workflow — skips design and TDD |
198
198
 
199
+ ### Prototyping
200
+
201
+ | Command | Description |
202
+ |---------|-------------|
203
+ | `/sk:mvp` | Generate a complete MVP from a single idea prompt — landing page with waitlist + working app with fake data. Supports Next.js, Nuxt, Laravel, React+Vite. Optional Pencil MCP design phase and Playwright MCP visual validation. |
204
+
199
205
  ### Quality Gates
200
206
 
201
207
  | Command | Description |
@@ -204,6 +210,7 @@ Requirement changes → /sk:change → re-enter at correct step
204
210
  | `/sk:test` | Auto-detect and run all test suites, verify 100% coverage on new code |
205
211
  | `/sk:security-check` | OWASP security audit across changed code |
206
212
  | `/sk:perf` | Performance audit: bundle size, N+1 queries, Core Web Vitals |
213
+ | `/sk:seo-audit` | SEO audit — dual-mode (source templates + dev server), ask-before-fix, checklist output to `tasks/seo-findings.md` |
207
214
  | `/sk:review` | Rigorous self-review across 7 dimensions |
208
215
 
209
216
  ### Shipping
@@ -108,7 +108,7 @@ Detect the project stack from `CLAUDE.md`, `package.json`, `composer.json`, `pyp
108
108
 
109
109
  ## Generate Report
110
110
 
111
- Write findings to `tasks/security-findings.md` using this format:
111
+ Write findings to `tasks/security-findings.md` using this format. **Never overwrite** `tasks/security-findings.md` — append new audits with a date header. Old run checkboxes stay as-is (audit trail); only update findings from the current run.
112
112
 
113
113
  ```markdown
114
114
  # Security Audit — YYYY-MM-DD
@@ -119,42 +119,43 @@ Write findings to `tasks/security-findings.md` using this format:
119
119
 
120
120
  ## Critical (must fix before deploy)
121
121
 
122
- - **[FILE:LINE]** Description of vulnerability
122
+ - [ ] **[FILE:LINE]** Description of vulnerability
123
123
  **Standard:** OWASP A03 — Injection (CWE-89)
124
124
  **Risk:** What could happen if exploited
125
125
  **Recommendation:** How to fix it
126
+ - [x] **[FILE:LINE]** Description *(resolved)*
126
127
 
127
128
  ## High (fix before production)
128
129
 
129
- - **[FILE:LINE]** Description
130
+ - [ ] **[FILE:LINE]** Description
130
131
  **Standard:** ...
131
132
  **Risk:** ...
132
133
  **Recommendation:** ...
133
134
 
134
135
  ## Medium (should fix)
135
136
 
136
- - **[FILE:LINE]** Description
137
+ - [ ] **[FILE:LINE]** Description
137
138
  **Standard:** ...
138
139
  **Recommendation:** ...
139
140
 
140
141
  ## Low / Informational
141
142
 
142
- - **[FILE:LINE]** Description
143
+ - [ ] **[FILE:LINE]** Description
143
144
  **Recommendation:** ...
144
145
 
145
146
  ## Passed Checks
146
147
 
147
- - List of categories that passed with no findings
148
+ - [Categories with no findings]
148
149
 
149
150
  ## Summary
150
151
 
151
- | Severity | Count |
152
- |----------|-------|
153
- | Critical | N |
154
- | High | N |
155
- | Medium | N |
156
- | Low | N |
157
- | **Total** | **N** |
152
+ | Severity | Open | Resolved this run |
153
+ |----------|------|-------------------|
154
+ | Critical | N | N |
155
+ | High | N | N |
156
+ | Medium | N | N |
157
+ | Low | N | N |
158
+ | **Total** | **N** | **N** |
158
159
  ```
159
160
 
160
161
  ## When Done
@@ -162,12 +163,12 @@ Write findings to `tasks/security-findings.md` using this format:
162
163
  Tell the user:
163
164
 
164
165
  > "Security audit complete. Findings saved to `tasks/security-findings.md`.
165
- > - **Critical:** N | **High:** N | **Medium:** N | **Low:** N
166
+ > - **Critical:** N open (N resolved) | **High:** N open (N resolved) | **Medium:** N open | **Low:** N open
166
167
  >
167
168
  > Review the findings, then run `/sk:finish-feature` when ready to finalize."
168
169
 
169
170
  If there are Critical or High findings:
170
- > "There are critical/high findings that should be addressed before merging. Fix them, then re-run `/sk:security-check` to verify."
171
+ > "There are critical/high findings that MUST be fixed before merging. These are HARD GATE items — `- [ ]` findings block all forward progress. Fix them, then re-run `/sk:security-check` to verify."
171
172
 
172
173
  **Do not auto-fix.** The user decides what to address.
173
174
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kennethsolomon/shipkit",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "A structured workflow toolkit for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",
@@ -89,20 +89,25 @@ Write findings to `tasks/accessibility-findings.md`:
89
89
 
90
90
  ## Failures (must fix)
91
91
 
92
- - **[Component/File:Line]** Description
92
+ - [ ] **[Component/File:Line]** Description
93
+ **Criterion:** WCAG X.X.X — [Name]
94
+ **Impact:** [Who is affected and how]
95
+ **Recommendation:** [How to fix]
96
+
97
+ - [x] **[Component/File:Line]** Description *(resolved)*
93
98
  **Criterion:** WCAG X.X.X — [Name]
94
99
  **Impact:** [Who is affected and how]
95
100
  **Recommendation:** [How to fix]
96
101
 
97
102
  ## Warnings (should fix)
98
103
 
99
- - **[Component/File:Line]** Description
104
+ - [ ] **[Component/File:Line]** Description
100
105
  **Criterion:** WCAG X.X.X — [Name]
101
106
  **Recommendation:** [How to fix]
102
107
 
103
108
  ## Manual Checks Required
104
109
 
105
- - [Things that require human/screen reader testing]
110
+ - [ ] [Things that require human/screen reader testing]
106
111
 
107
112
  ## Passed Checks
108
113
 
@@ -110,11 +115,11 @@ Write findings to `tasks/accessibility-findings.md`:
110
115
 
111
116
  ## Summary
112
117
 
113
- | Level | Count |
114
- |----------|-------|
115
- | Failures | N |
116
- | Warnings | N |
117
- | Manual | N |
118
+ | Level | Open | Resolved this run |
119
+ |----------|------|-------------------|
120
+ | Failures | N | N |
121
+ | Warnings | N | N |
122
+ | Manual | N | N |
118
123
  ```
119
124
 
120
125
  **Never overwrite** `tasks/accessibility-findings.md` — append new audits with a date header.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sk:e2e
3
- description: "Run E2E behavioral verification using agent-browser as the final quality gate before finalize. Tests the complete, reviewed, secure implementation from a user's perspective."
3
+ description: "Run E2E behavioral verification as the final quality gate before finalize. Prefers Playwright CLI when playwright.config.ts is detected; falls back to agent-browser otherwise. Tests the complete, reviewed, secure implementation from a user's perspective."
4
4
  ---
5
5
 
6
6
  # /sk:e2e
@@ -22,22 +22,97 @@ Read these files to understand what to test:
22
22
  - `tasks/findings.md` — design decisions and expected behaviors
23
23
  - `tasks/progress.md` — implementation notes
24
24
 
25
- ### 2. Check agent-browser is Available
25
+ ### 2. Detect E2E Runner
26
+
27
+ Check which runner is available, in priority order:
28
+
29
+ **Priority 1 — Playwright (preferred)**
30
+
31
+ ```bash
32
+ ls playwright.config.ts 2>/dev/null || ls playwright.config.js 2>/dev/null
33
+ ```
34
+
35
+ If a Playwright config exists → use Playwright CLI (Step 3a). This is the preferred path because:
36
+ - Uses headless Chromium (no conflict with system Chrome)
37
+ - No additional global install required (`@playwright/test` in devDeps)
38
+ - Test files in `e2e/` or `tests/e2e/` are picked up automatically
39
+ - `webServer` in `playwright.config.ts` auto-starts the dev server
40
+
41
+ **Playwright config requirements** (verify before running):
42
+ - `headless: true` must be set under `use:`
43
+ - `channel: undefined` (or omitted) — must NOT be `'chrome'` or `'msedge'` to avoid system browser conflicts
44
+ - `webServer.reuseExistingServer: true` — avoids double-starting the dev server
45
+
46
+ If config has `channel: 'chrome'` or `headless: false`, warn:
47
+ > "playwright.config.ts uses system Chrome or headed mode — this may conflict with a running browser. Consider setting `headless: true` and `channel: undefined`."
48
+
49
+ **Priority 2 — agent-browser (fallback)**
26
50
 
27
51
  ```bash
28
52
  agent-browser --version
29
53
  ```
30
54
 
31
- If not found, instruct the user:
55
+ Only use `agent-browser` if NO `playwright.config.ts` / `playwright.config.js` exists.
56
+
57
+ If `agent-browser` is also not found, AND no Playwright config exists:
58
+
32
59
  ```
33
- agent-browser is required. Install it:
60
+ Neither Playwright nor agent-browser is configured. To fix permanently:
61
+
62
+ Option A (recommended) — Playwright:
63
+ npm install -D @playwright/test
64
+ npx playwright install chromium
65
+ # Create playwright.config.ts with headless: true, channel: undefined
66
+
67
+ Option B — agent-browser:
34
68
  npm install -g agent-browser
35
- agent-browser install # downloads Chrome (~100MB)
69
+ agent-browser install
70
+
36
71
  Then re-run /sk:e2e.
37
72
  ```
38
- Stop if not available.
73
+ Stop if neither runner is available.
74
+
75
+ ### 3a. Run E2E via Playwright CLI
76
+
77
+ Locate test files:
78
+ ```bash
79
+ ls e2e/ 2>/dev/null
80
+ ls tests/e2e/ 2>/dev/null
81
+ find . -name "*.spec.ts" -not -path "*/node_modules/*"
82
+ ```
83
+
84
+ If spec files exist, run them:
85
+ ```bash
86
+ npx playwright test --reporter=list
87
+ ```
88
+
89
+ To run a specific file:
90
+ ```bash
91
+ npx playwright test e2e/my-feature.spec.ts --reporter=list
92
+ ```
93
+
94
+ To run with visible output on failure:
95
+ ```bash
96
+ npx playwright test --reporter=list 2>&1
97
+ ```
98
+
99
+ **Interpreting results:**
100
+ - Exit code 0 = all tests passed
101
+ - Exit code 1 = one or more tests failed (output includes which tests and why)
102
+ - Each failing test shows: test name, expected vs. actual, screenshot path (if `trace: 'on-first-retry'` is set)
103
+
104
+ If no spec files exist → derive scenarios from `tasks/todo.md` acceptance criteria and write them to `e2e/<feature>.spec.ts` before running. Follow the test file patterns already present in the project (check `e2e/helpers/` for shared utilities).
39
105
 
40
- ### 3. Detect Local Server
106
+ After running, record for each test:
107
+ - Test name / suite
108
+ - Result: PASS or FAIL
109
+ - On FAIL: error message and relevant snapshot
110
+
111
+ Skip to **Step 5 (Report Results)**.
112
+
113
+ ### 3b. Detect Local Server (agent-browser path only)
114
+
115
+ Only needed if using agent-browser (Playwright's `webServer` handles this automatically).
41
116
 
42
117
  Determine what URL to test against:
43
118
  - Check for a dev server command in `package.json` scripts (`dev`, `start`)
@@ -46,7 +121,7 @@ Determine what URL to test against:
46
121
  - If a server is already running (check common ports: 3000, 5173, 8000, 8080), use it
47
122
  - If no server is running, start one in the background and note the URL
48
123
 
49
- ### 4. Locate E2E Test Files
124
+ ### 4. Locate E2E Test Files (agent-browser path only)
50
125
 
51
126
  Find E2E test scenarios written during the Write Tests step:
52
127
  ```bash
@@ -56,7 +131,7 @@ ls tests/e2e/ 2>/dev/null
56
131
 
57
132
  If no E2E test files exist, derive scenarios from `tasks/todo.md` acceptance criteria and `tasks/findings.md`.
58
133
 
59
- ### 5. Run E2E Scenarios
134
+ ### 4b. Run E2E Scenarios via agent-browser
60
135
 
61
136
  For each scenario, use agent-browser following this core pattern:
62
137
 
@@ -90,9 +165,10 @@ For each scenario, record:
90
165
  - Result: PASS or FAIL
91
166
  - On FAIL: what was expected vs. what was found (include snapshot excerpt)
92
167
 
93
- ### 6. Report Results
168
+ ### 5. Report Results
94
169
 
95
170
  ```
171
+ E2E Runner: Playwright CLI (or: agent-browser)
96
172
  E2E Results:
97
173
  PASS [scenario name]
98
174
  PASS [scenario name]
@@ -130,6 +206,81 @@ If failures remain after fixes:
130
206
 
131
207
  ---
132
208
 
209
+ ## Playwright Setup Reference
210
+
211
+ When setting up Playwright for the first time in a project:
212
+
213
+ ```bash
214
+ npm install -D @playwright/test
215
+ npx playwright install chromium
216
+ ```
217
+
218
+ Minimal `playwright.config.ts` (headless, no system Chrome conflict):
219
+
220
+ ```ts
221
+ import { defineConfig, devices } from '@playwright/test'
222
+
223
+ export default defineConfig({
224
+ testDir: './e2e',
225
+ fullyParallel: true,
226
+ retries: process.env.CI ? 2 : 0,
227
+ reporter: 'list',
228
+ use: {
229
+ baseURL: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3000',
230
+ headless: true, // REQUIRED — avoids system Chrome conflict
231
+ trace: 'on-first-retry',
232
+ },
233
+ projects: [
234
+ {
235
+ name: 'chromium',
236
+ use: { ...devices['Desktop Chrome'], channel: undefined }, // REQUIRED — use Playwright's Chromium, not system Chrome
237
+ },
238
+ ],
239
+ webServer: {
240
+ command: 'npm run dev', // or 'php artisan serve', 'yarn dev', etc.
241
+ url: 'http://localhost:3000',
242
+ reuseExistingServer: true,
243
+ timeout: 120_000,
244
+ },
245
+ })
246
+ ```
247
+
248
+ E2E test helpers go in `e2e/helpers/`. Auth helper pattern:
249
+
250
+ ```ts
251
+ // e2e/helpers/auth.ts
252
+ import { Page } from '@playwright/test'
253
+
254
+ export async function signIn(page: Page, email: string, password: string) {
255
+ await page.goto('/login')
256
+ await page.getByLabel(/email/i).fill(email)
257
+ await page.getByLabel(/password/i).fill(password)
258
+ await page.getByRole('button', { name: /sign in|log in/i }).click()
259
+ await page.waitForURL('/dashboard', { timeout: 15_000 })
260
+ }
261
+
262
+ export const TEST_USERS = {
263
+ regular: {
264
+ email: process.env.E2E_USER_EMAIL ?? '',
265
+ password: process.env.E2E_USER_PASSWORD ?? '',
266
+ },
267
+ admin: {
268
+ email: process.env.E2E_ADMIN_EMAIL ?? '',
269
+ password: process.env.E2E_ADMIN_PASSWORD ?? '',
270
+ },
271
+ }
272
+ ```
273
+
274
+ Test credentials go in `.env.local` (never hardcoded):
275
+ ```
276
+ E2E_USER_EMAIL=...
277
+ E2E_USER_PASSWORD=...
278
+ E2E_ADMIN_EMAIL=...
279
+ E2E_ADMIN_PASSWORD=...
280
+ ```
281
+
282
+ ---
283
+
133
284
  ## Model Routing
134
285
 
135
286
  Read `.shipkit/config.json` from the project root if it exists.
@@ -0,0 +1,266 @@
1
+ ---
2
+ name: sk:mvp
3
+ description: Generate a complete MVP validation app from a prompt — landing page with waitlist + working app with fake data. Use this skill when the user wants to quickly validate a product idea, build a proof of concept, create a landing page with email collection, scaffold an MVP, build a prototype for market validation, or test if an idea is worth pursuing. Produces a full working codebase locally.
4
+ compatibility: Optional — Pencil MCP (for visual mockups), Playwright MCP (for visual validation)
5
+ ---
6
+
7
+ # /sk:mvp — MVP Validation App Generator
8
+
9
+ Generate a complete, aesthetically polished MVP from a single idea prompt. Outputs a landing page with waitlist email collection + a working app with fake data. Purpose: validate market interest before investing in a full build.
10
+
11
+ ## Hard Rules
12
+
13
+ - Generate ALL code locally — never deploy, push, or publish anything.
14
+ - Landing page is MANDATORY for every MVP. Never skip it.
15
+ - Use FAKE data only — no real databases, no auth systems, no third-party API integrations.
16
+ - Every page must be functional: buttons navigate, forms submit, modals open/close.
17
+ - Design must be distinctive and polished — never use default Tailwind colors or generic layouts. Read `references/design-system.md` for aesthetic guidelines.
18
+ - Keep the app secure enough (no XSS, no open redirects) but don't over-engineer security for a prototype.
19
+
20
+ ---
21
+
22
+ ## Step 1 — Gather the Idea
23
+
24
+ Ask the user to describe their product idea. If not already provided, ask:
25
+
26
+ > **What's your product idea? Describe it in 1-3 sentences — what does it do and who is it for?**
27
+
28
+ Extract from their answer:
29
+ - **Product name** (or ask them to pick one)
30
+ - **One-line value proposition**
31
+ - **Target audience**
32
+ - **Key features** (3-5 core features for the app)
33
+
34
+ Confirm your understanding before proceeding.
35
+
36
+ ---
37
+
38
+ ## Step 2 — Pick a Tech Stack
39
+
40
+ Present these preset options:
41
+
42
+ > **Pick a tech stack:**
43
+ >
44
+ > 1. **Next.js + Tailwind** — React ecosystem, SSR, API routes built-in
45
+ > 2. **Nuxt + Tailwind** — Vue ecosystem, SSR, server routes built-in
46
+ > 3. **Laravel + Blade + Tailwind** — PHP ecosystem, full backend, Blade templates
47
+ > 4. **React + Vite + Tailwind** — Lightweight SPA, no backend (waitlist via Formspree)
48
+ >
49
+ > Or type your own stack (I'll adapt).
50
+
51
+ Once the user picks, note the selection and load the corresponding reference file in Step 6.
52
+
53
+ ---
54
+
55
+ ## Step 3 — Optional Design Phase (Pencil MCP)
56
+
57
+ Check if the user invoked with `--pencil` flag or ask:
58
+
59
+ > **Would you like to design the UI visually in Pencil before coding? (Requires Pencil app + MCP) (y/n)**
60
+ >
61
+ > If no, I'll go straight to code generation with a great default design.
62
+
63
+ ### If YES — Pencil MCP Design Phase
64
+
65
+ Follow this flow (adapted from sk:frontend-design):
66
+
67
+ **3a. Find or create .pen file**
68
+ - Check `docs/design/` for existing `.pen` file matching this MVP.
69
+ - Existing: `open_document(filePath)` → skip to 3c.
70
+ - None: `open_document('new')` → save to `docs/design/{product-slug}.pen`.
71
+
72
+ **3b. Load design context**
73
+ 1. `get_guidelines(topic='landing-page')` — load landing page design rules.
74
+ 2. `get_style_guide_tags` → `get_style_guide(tags)` — pick tags matching the product's tone (e.g., modern, SaaS, minimal, bold).
75
+
76
+ **3c. Set color palette as variables**
77
+ Decide a distinctive color palette based on the product's tone and audience. Call `set_variables` with the palette:
78
+ ```json
79
+ {
80
+ "color-bg": "#xxxxxx",
81
+ "color-fg": "#xxxxxx",
82
+ "color-accent": "#xxxxxx",
83
+ "color-muted": "#xxxxxx"
84
+ }
85
+ ```
86
+
87
+ **3d. Build mockup screens**
88
+ Use `batch_design` to create:
89
+ 1. Landing page frame — hero, features, pricing, waitlist section
90
+ 2. App main screen frame — dashboard or primary view
91
+ 3. App secondary screen frame — detail view or key interaction
92
+
93
+ Work one frame per `batch_design` call. Apply the color variables and typography.
94
+
95
+ **3e. Validate and iterate**
96
+ After each frame: `get_screenshot` to inspect. If off: `snapshot_layout` → fix with `batch_design`. Iterate until the design matches the vision.
97
+
98
+ **3f. Get user approval**
99
+ Present screenshots and ask:
100
+ > **Does this design direction look good? Any changes before I start coding?**
101
+
102
+ Wait for approval. Apply feedback if given. Do not proceed to code without explicit approval.
103
+
104
+ **3g. Record the design**
105
+ Note the `.pen` file path. The design decisions (colors, typography, layout) carry forward into code generation.
106
+
107
+ ### If NO — Skip to Step 4
108
+
109
+ Use the aesthetic guidelines from `references/design-system.md` to make distinctive design choices automatically. Briefly state the design direction chosen (color scheme, typography, layout style) so the user knows what to expect.
110
+
111
+ ---
112
+
113
+ ## Step 4 — Scaffold the Project
114
+
115
+ Read the stack-specific reference file:
116
+ - Next.js → `references/stacks/nextjs.md`
117
+ - Nuxt → `references/stacks/nuxt.md`
118
+ - Laravel → `references/stacks/laravel.md`
119
+ - React + Vite → `references/stacks/react-vite.md`
120
+
121
+ Run the scaffold command from the reference file. Then customize the Tailwind config with the chosen color palette and typography.
122
+
123
+ ---
124
+
125
+ ## Step 5 — Generate the Landing Page
126
+
127
+ Read `references/landing-page.md` for section patterns and structure.
128
+
129
+ Generate a complete landing page with these sections (all mandatory):
130
+
131
+ 1. **Navbar** — logo/product name + nav links (Features, Pricing, Waitlist) + CTA button
132
+ 2. **Hero** — headline (benefit-driven) + subheadline + primary CTA + hero visual/illustration area
133
+ 3. **Social proof bar** — "Trusted by X+" or logo strip (use placeholder logos)
134
+ 4. **Features grid** — 3-6 feature cards with icons, titles, descriptions (based on the key features from Step 1)
135
+ 5. **How it works** — 3-step process with numbered steps and descriptions
136
+ 6. **Pricing** — 2-3 tier cards (Free / Pro / Enterprise) with fake but realistic pricing
137
+ 7. **Testimonials** — 2-3 fake testimonial cards with names, roles, photos (use placeholder avatars)
138
+ 8. **Waitlist / CTA section** — email input + submit button + success message + form validation
139
+ 9. **Footer** — product name, links, copyright
140
+
141
+ ### Waitlist Email Collection
142
+
143
+ **For stacks with backend (Next.js, Nuxt, Laravel):**
144
+ - Create an API route that accepts POST `{ email }`.
145
+ - Validate the email format server-side.
146
+ - Read existing `waitlist.json`, append the new entry with timestamp, write back.
147
+ - Return success/error JSON response.
148
+ - Wire the landing page form to POST to this route via fetch.
149
+ - Show success state ("You're on the list!") and error state on the form.
150
+
151
+ **For static stacks (React + Vite):**
152
+ - Use Formspree: form action points to `https://formspree.io/f/{form_id}`.
153
+ - Add a comment/note telling the user to create a free Formspree account and replace `{form_id}`.
154
+ - Handle success/error states client-side.
155
+
156
+ ---
157
+
158
+ ## Step 6 — Generate the App
159
+
160
+ Generate a working multi-page app with:
161
+
162
+ 1. **Navigation** — sidebar or top nav with links to all pages. Active state highlighting.
163
+ 2. **Dashboard / Home** — summary cards, charts (use simple CSS/SVG charts or placeholder), recent activity list. All fake data.
164
+ 3. **Primary feature page** — the main thing the product does. Functional UI with fake data. Buttons, modals, forms all work (client-side only).
165
+ 4. **Secondary feature page** — a supporting feature. Table or list view with filtering/sorting (client-side).
166
+ 5. **Settings / Profile page** — simple form with fake prefilled data. Save button shows a toast/notification.
167
+
168
+ ### Design Standards (apply to every page)
169
+
170
+ Read `references/design-system.md` and apply:
171
+ - Distinctive color palette — never default Tailwind. Custom `tailwind.config` colors.
172
+ - Thoughtful typography — use Google Fonts. Pair a display font with a body font.
173
+ - Consistent spacing scale — use a rhythm (e.g., 4/8/12/16/24/32/48).
174
+ - Polished components — rounded corners, shadows, hover states, transitions.
175
+ - Responsive — must look good on mobile and desktop.
176
+ - Fake data should feel realistic — use real-sounding names, numbers, dates.
177
+
178
+ ---
179
+
180
+ ## Step 7 — Visual Validation (Playwright MCP)
181
+
182
+ After code generation is complete, validate the output visually.
183
+
184
+ **If Playwright MCP is available:**
185
+
186
+ 1. Start the dev server (use the stack's dev command from the reference file).
187
+ 2. Use Playwright MCP to navigate to each page:
188
+ - Landing page (`/`)
189
+ - Dashboard (`/dashboard`)
190
+ - Each app page
191
+ 3. Take screenshots of each page at desktop (1280px) and mobile (375px) widths.
192
+ 4. Check for:
193
+ - Broken layouts (overlapping elements, overflow, misaligned sections)
194
+ - Missing content (empty sections, broken images, placeholder text not filled)
195
+ - Non-functional interactions (click buttons, submit forms, open modals)
196
+ - Visual consistency (colors match palette, typography is consistent)
197
+ 5. If issues found: fix them and re-validate.
198
+
199
+ **If Playwright MCP is NOT available:**
200
+
201
+ Tell the user:
202
+ > Playwright MCP is not connected — skipping visual validation. Start the dev server with `{dev command}` and check the pages manually.
203
+
204
+ ---
205
+
206
+ ## Step 8 — Quality Loop
207
+
208
+ If visual validation found issues:
209
+
210
+ 1. Fix the identified issues.
211
+ 2. Re-run Playwright validation (Step 7).
212
+ 3. Repeat until all pages pass — no broken layouts, all interactions work, design is consistent.
213
+
214
+ Maximum 3 loop iterations. If issues persist after 3 loops, present remaining issues to the user and ask how to proceed.
215
+
216
+ ---
217
+
218
+ ## Step 9 — Present the Output
219
+
220
+ Summarize what was generated:
221
+
222
+ ```
223
+ ## MVP Generated
224
+
225
+ **Product:** {name}
226
+ **Stack:** {stack}
227
+ **Files:** {count} files generated
228
+
229
+ ### Landing Page
230
+ - URL: http://localhost:{port}/
231
+ - Sections: hero, features, pricing, waitlist, testimonials
232
+ - Waitlist: {API route path or Formspree}
233
+
234
+ ### App Pages
235
+ - Dashboard: http://localhost:{port}/dashboard
236
+ - {Feature 1}: http://localhost:{port}/{path}
237
+ - {Feature 2}: http://localhost:{port}/{path}
238
+ - Settings: http://localhost:{port}/settings
239
+
240
+ ### Start the dev server
241
+ {exact command to run}
242
+
243
+ ### What's next
244
+ - Review the generated code and tweak the design to your liking
245
+ - Replace placeholder content with your real copy
246
+ - Replace fake data with real API integrations when ready
247
+ - Deploy when you're happy with it
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Model Routing
253
+
254
+ Read `.shipkit/config.json` from the project root if it exists.
255
+
256
+ - If `model_overrides["sk:mvp"]` is set, use that model — it takes precedence.
257
+ - Otherwise use the `profile` field. Default: `balanced`.
258
+
259
+ | Profile | Model |
260
+ |---------|-------|
261
+ | `full-sail` | opus (inherit) |
262
+ | `quality` | opus (inherit) |
263
+ | `balanced` | sonnet |
264
+ | `budget` | sonnet |
265
+
266
+ > `opus` = inherit (uses the current session model). When spawning sub-agents via the Agent tool, pass `model: "<resolved-model>"`.