@slowcook-ai/cli 0.19.0-alpha.18 → 0.19.0-alpha.40

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 (92) hide show
  1. package/dist/cli.js +28 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/brand/index.d.ts +58 -0
  4. package/dist/commands/brand/index.d.ts.map +1 -0
  5. package/dist/commands/brand/index.js +257 -0
  6. package/dist/commands/brand/index.js.map +1 -0
  7. package/dist/commands/budget/index.d.ts +2 -0
  8. package/dist/commands/budget/index.d.ts.map +1 -0
  9. package/dist/commands/budget/index.js +252 -0
  10. package/dist/commands/budget/index.js.map +1 -0
  11. package/dist/commands/dev-env/config.d.ts +136 -0
  12. package/dist/commands/dev-env/config.d.ts.map +1 -0
  13. package/dist/commands/dev-env/config.js +96 -0
  14. package/dist/commands/dev-env/config.js.map +1 -0
  15. package/dist/commands/dev-env/index.d.ts +27 -0
  16. package/dist/commands/dev-env/index.d.ts.map +1 -0
  17. package/dist/commands/dev-env/index.js +226 -0
  18. package/dist/commands/dev-env/index.js.map +1 -0
  19. package/dist/commands/dev-env/init.d.ts +28 -0
  20. package/dist/commands/dev-env/init.d.ts.map +1 -0
  21. package/dist/commands/dev-env/init.js +135 -0
  22. package/dist/commands/dev-env/init.js.map +1 -0
  23. package/dist/commands/eval/index.d.ts.map +1 -1
  24. package/dist/commands/eval/index.js +15 -1
  25. package/dist/commands/eval/index.js.map +1 -1
  26. package/dist/commands/init/mock-vite.d.ts +54 -0
  27. package/dist/commands/init/mock-vite.d.ts.map +1 -0
  28. package/dist/commands/init/mock-vite.js +611 -0
  29. package/dist/commands/init/mock-vite.js.map +1 -0
  30. package/dist/commands/init/mock.d.ts +6 -0
  31. package/dist/commands/init/mock.d.ts.map +1 -1
  32. package/dist/commands/init/mock.js +20 -4
  33. package/dist/commands/init/mock.js.map +1 -1
  34. package/dist/commands/plate/agent.d.ts +7 -0
  35. package/dist/commands/plate/agent.d.ts.map +1 -1
  36. package/dist/commands/plate/agent.js +1 -1
  37. package/dist/commands/plate/agent.js.map +1 -1
  38. package/dist/commands/plate/index.d.ts.map +1 -1
  39. package/dist/commands/plate/index.js +6 -0
  40. package/dist/commands/plate/index.js.map +1 -1
  41. package/dist/commands/refine/agent.d.ts +12 -0
  42. package/dist/commands/refine/agent.d.ts.map +1 -1
  43. package/dist/commands/refine/agent.js +173 -13
  44. package/dist/commands/refine/agent.js.map +1 -1
  45. package/dist/commands/refine/brownfield-answer.d.ts +81 -0
  46. package/dist/commands/refine/brownfield-answer.d.ts.map +1 -0
  47. package/dist/commands/refine/brownfield-answer.js +231 -0
  48. package/dist/commands/refine/brownfield-answer.js.map +1 -0
  49. package/dist/commands/refine/context.d.ts.map +1 -1
  50. package/dist/commands/refine/context.js +18 -0
  51. package/dist/commands/refine/context.js.map +1 -1
  52. package/dist/commands/refine/history-index.d.ts +29 -0
  53. package/dist/commands/refine/history-index.d.ts.map +1 -1
  54. package/dist/commands/refine/history-index.js +63 -0
  55. package/dist/commands/refine/history-index.js.map +1 -1
  56. package/dist/commands/refine/index.d.ts.map +1 -1
  57. package/dist/commands/refine/index.js +32 -1
  58. package/dist/commands/refine/index.js.map +1 -1
  59. package/dist/commands/refine/proposals-synth.d.ts +50 -1
  60. package/dist/commands/refine/proposals-synth.d.ts.map +1 -1
  61. package/dist/commands/refine/proposals-synth.js +199 -35
  62. package/dist/commands/refine/proposals-synth.js.map +1 -1
  63. package/dist/commands/refine/spec-yaml.d.ts +274 -250
  64. package/dist/commands/refine/spec-yaml.d.ts.map +1 -1
  65. package/dist/commands/refine/spec-yaml.js +10 -0
  66. package/dist/commands/refine/spec-yaml.js.map +1 -1
  67. package/dist/commands/run-mock/index.d.ts.map +1 -1
  68. package/dist/commands/run-mock/index.js +7 -1
  69. package/dist/commands/run-mock/index.js.map +1 -1
  70. package/dist/commands/testgen/agent.d.ts.map +1 -1
  71. package/dist/commands/testgen/agent.js +34 -9
  72. package/dist/commands/testgen/agent.js.map +1 -1
  73. package/dist/commands/vibe/agent.d.ts +7 -0
  74. package/dist/commands/vibe/agent.d.ts.map +1 -1
  75. package/dist/commands/vibe/agent.js +2 -2
  76. package/dist/commands/vibe/agent.js.map +1 -1
  77. package/dist/commands/vibe/index.d.ts.map +1 -1
  78. package/dist/commands/vibe/index.js +7 -1
  79. package/dist/commands/vibe/index.js.map +1 -1
  80. package/dist/cost-store.d.ts +52 -0
  81. package/dist/cost-store.d.ts.map +1 -0
  82. package/dist/cost-store.js +108 -0
  83. package/dist/cost-store.js.map +1 -0
  84. package/dist/lib/budget.d.ts +123 -0
  85. package/dist/lib/budget.d.ts.map +1 -0
  86. package/dist/lib/budget.js +225 -0
  87. package/dist/lib/budget.js.map +1 -0
  88. package/dist/lib/mock-shape.d.ts +44 -0
  89. package/dist/lib/mock-shape.d.ts.map +1 -0
  90. package/dist/lib/mock-shape.js +77 -0
  91. package/dist/lib/mock-shape.js.map +1 -0
  92. package/package.json +4 -4
@@ -0,0 +1,611 @@
1
+ /**
2
+ * `slowcook init mock --shape vite` — scaffold a Vite/React SPA mock.
3
+ *
4
+ * Sibling of the Next.js scaffolder (`mock.ts`). The Vite shape is the
5
+ * preferred default for new consumers as of sc#82 — solves the focus-
6
+ * loss / hydration-mismatch / `'use client'`-everywhere class of bugs
7
+ * that the Next.js shape inherits from production.
8
+ *
9
+ * Layout produced:
10
+ *
11
+ * mock/
12
+ * ├── package.json vite + react + react-router-dom + @slowcook-ai/mock-runtime
13
+ * ├── vite.config.ts port 3100; @/ → src/ alias
14
+ * ├── tsconfig.json ESNext + bundler resolution + jsx react-jsx
15
+ * ├── index.html #root mount
16
+ * ├── .gitignore node_modules, dist
17
+ * ├── README.md run instructions + how vibe extends the router
18
+ * └── src/
19
+ * ├── main.tsx StrictMode + BrowserRouter + ScenarioRegistryProvider
20
+ * ├── App.tsx <Routes /> — vibe appends new screen routes here
21
+ * ├── design-system/ ← `slowcook brand` populates this; seeded minimal here
22
+ * │ ├── tokens.ts
23
+ * │ ├── css.ts
24
+ * │ └── index.ts
25
+ * ├── lib/
26
+ * │ └── scenario-registry.ts
27
+ * └── apps/.gitkeep
28
+ *
29
+ * Plus, at the repo root:
30
+ * .brewing/mock.yaml downstream agents read this to know the shape
31
+ *
32
+ * The design-system files seeded here are MINIMAL — a neutral palette,
33
+ * just enough so `npm run dev` renders something. The full design-system
34
+ * (logo, full primitives, ds-* utility CSS) is the output of the
35
+ * `slowcook brand` agent (Phase 4 of sc#82); it runs once per project
36
+ * and overwrites these seed files.
37
+ */
38
+ import { writeFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
39
+ import { dirname, join } from "node:path";
40
+ function detectMockPackageName(cwd) {
41
+ try {
42
+ const parent = JSON.parse(readFileSync(join(cwd, "package.json"), "utf8"));
43
+ if (parent.name && /^[@a-z0-9_-]/i.test(parent.name)) {
44
+ const base = parent.name.replace(/^@[^/]+\//, "");
45
+ return `${base}-mock`;
46
+ }
47
+ }
48
+ catch {
49
+ /* ignore */
50
+ }
51
+ return "slowcook-mock";
52
+ }
53
+ export function planMockViteFiles(args) {
54
+ const pkgName = detectMockPackageName(args.cwd);
55
+ return [
56
+ { path: "mock/package.json", contents: PACKAGE_JSON(args.runtimeVersion, pkgName), skipIfExists: true },
57
+ { path: "mock/vite.config.ts", contents: VITE_CONFIG, skipIfExists: true },
58
+ { path: "mock/tsconfig.json", contents: TSCONFIG, skipIfExists: true },
59
+ { path: "mock/index.html", contents: INDEX_HTML, skipIfExists: true },
60
+ { path: "mock/.gitignore", contents: GITIGNORE, skipIfExists: true },
61
+ { path: "mock/README.md", contents: README, skipIfExists: true },
62
+ { path: "mock/src/main.tsx", contents: MAIN_TSX, skipIfExists: true },
63
+ { path: "mock/src/App.tsx", contents: APP_TSX, skipIfExists: true },
64
+ { path: "mock/src/design-system/tokens.ts", contents: TOKENS_TS, skipIfExists: true },
65
+ { path: "mock/src/design-system/css.ts", contents: CSS_TS, skipIfExists: true },
66
+ { path: "mock/src/design-system/index.ts", contents: DS_INDEX_TS, skipIfExists: true },
67
+ { path: "mock/src/lib/scenario-registry.tsx", contents: SCENARIO_REGISTRY, skipIfExists: true },
68
+ { path: "mock/src/apps/.gitkeep", contents: "", skipIfExists: true },
69
+ { path: "mock/scenarios/.gitkeep", contents: "", skipIfExists: true },
70
+ { path: ".brewing/mock.yaml", contents: MOCK_YAML, skipIfExists: true },
71
+ ];
72
+ }
73
+ export function applyMockViteFiles(args, files) {
74
+ for (const f of files) {
75
+ const abs = join(args.cwd, f.path);
76
+ if (existsSync(abs) && f.skipIfExists && !args.force) {
77
+ console.log(` skip ${f.path} (exists)`);
78
+ continue;
79
+ }
80
+ if (args.dryRun) {
81
+ console.log(` would write ${f.path}`);
82
+ continue;
83
+ }
84
+ mkdirSync(dirname(abs), { recursive: true });
85
+ writeFileSync(abs, f.contents, "utf8");
86
+ console.log(` write ${f.path}`);
87
+ }
88
+ }
89
+ // ---------------------------------------------------------------------------
90
+ // Template contents
91
+ // ---------------------------------------------------------------------------
92
+ const PACKAGE_JSON = (_runtimeVersion, pkgName) => JSON.stringify({
93
+ name: pkgName,
94
+ private: true,
95
+ version: "0.0.0",
96
+ type: "module",
97
+ scripts: {
98
+ dev: "vite",
99
+ build: "tsc -b && vite build",
100
+ preview: "vite preview",
101
+ typecheck: "tsc --noEmit",
102
+ },
103
+ // No `@slowcook-ai/mock-runtime` for vite shape — that package pins
104
+ // a `next@>=15` + `react@>=19` peer set incompatible with a Vite
105
+ // SPA. The Vite mock inlines the minimal scenario types + picker
106
+ // directly (see src/lib/scenario-registry.ts). When mock-runtime
107
+ // grows a Vite-compatible build (sc#82 Phase 4-ish), wire it back.
108
+ dependencies: {
109
+ react: "^18.3.1",
110
+ "react-dom": "^18.3.1",
111
+ "react-router-dom": "^6.27.0",
112
+ },
113
+ devDependencies: {
114
+ "@types/react": "^18.3.12",
115
+ "@types/react-dom": "^18.3.1",
116
+ "@vitejs/plugin-react": "^4.3.4",
117
+ typescript: "^5.6.3",
118
+ vite: "^6.0.5",
119
+ },
120
+ }, null, 2) + "\n";
121
+ const VITE_CONFIG = `import { defineConfig } from 'vite';
122
+ import react from '@vitejs/plugin-react';
123
+ import path from 'node:path';
124
+
125
+ // vite.config.ts — slowcook Vite mock (sc#82).
126
+ //
127
+ // Port 3100 mirrors the legacy Next.js mock's port so existing tooling
128
+ // (slowcook run-mock, dev-env yaml) keeps working without changes.
129
+ // '@/' alias makes import paths consistent with the Next.js mock shape
130
+ // so agents can read either shape via the same import conventions.
131
+ export default defineConfig({
132
+ plugins: [react()],
133
+ resolve: {
134
+ alias: {
135
+ '@': path.resolve(__dirname, './src'),
136
+ },
137
+ },
138
+ server: {
139
+ port: 3100,
140
+ host: '0.0.0.0',
141
+ },
142
+ preview: {
143
+ port: 3100,
144
+ host: '0.0.0.0',
145
+ },
146
+ });
147
+ `;
148
+ const TSCONFIG = `{
149
+ "compilerOptions": {
150
+ "target": "ESNext",
151
+ "useDefineForClassFields": true,
152
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
153
+ "module": "ESNext",
154
+ "skipLibCheck": true,
155
+ "moduleResolution": "bundler",
156
+ "allowImportingTsExtensions": false,
157
+ "isolatedModules": true,
158
+ "moduleDetection": "force",
159
+ "noEmit": true,
160
+ "jsx": "react-jsx",
161
+ "strict": true,
162
+ "noUnusedLocals": false,
163
+ "noUnusedParameters": false,
164
+ "noFallthroughCasesInSwitch": true,
165
+ "baseUrl": ".",
166
+ "paths": {
167
+ "@/*": ["./src/*"]
168
+ }
169
+ },
170
+ "include": ["src", "vite.config.ts"]
171
+ }
172
+ `;
173
+ const INDEX_HTML = `<!doctype html>
174
+ <html lang="en">
175
+ <head>
176
+ <meta charset="UTF-8" />
177
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
178
+ <title>Mock</title>
179
+ </head>
180
+ <body>
181
+ <div id="root"></div>
182
+ <script type="module" src="/src/main.tsx"></script>
183
+ </body>
184
+ </html>
185
+ `;
186
+ const GITIGNORE = `node_modules
187
+ dist
188
+ .env.local
189
+ .env.*.local
190
+ .vite
191
+ `;
192
+ const README = `# \`mock/\` — singular UI mock app (Vite/React)
193
+
194
+ Per-consumer mock app, scaffolded by \`slowcook init mock --shape vite\`.
195
+ The runtime (scenario types, hooks, picker UI) ships via
196
+ \`@slowcook-ai/mock-runtime\`; the bits in this directory are the
197
+ consumer-owned shell.
198
+
199
+ ## Run it
200
+
201
+ \`\`\`bash
202
+ cd mock
203
+ npm install
204
+ npm run dev
205
+ # → http://localhost:3100
206
+ \`\`\`
207
+
208
+ The homepage is the **scenario picker** (mounted at \`/\` by default).
209
+ Each scenario maps to one story (or one flow within a story); clicking
210
+ a scenario navigates to that story's preferred initial path.
211
+
212
+ ## Where things live
213
+
214
+ | Path | What it is |
215
+ |---|---|
216
+ | \`src/App.tsx\` | Top-level \`<Routes>\`. Vibe appends new screen routes here. |
217
+ | \`src/main.tsx\` | Root mount + BrowserRouter + ScenarioRegistryProvider. |
218
+ | \`src/design-system/\` | Tokens, primitives, icons, layout, css. Output of \`slowcook brand\`. |
219
+ | \`src/apps/<role>/screens/\` | One file per screen. Vibe writes these. |
220
+ | \`src/lib/scenario-registry.ts\` | Vibe-managed scenario imports. |
221
+ | \`scenarios/\` | One file per scenario. Vibe writes these. |
222
+
223
+ ## Why Vite instead of Next.js
224
+
225
+ The mock is a private dev surface — no SEO, no API routes, no SSR
226
+ needed. Vite gives us instant HMR, no \`'use client'\` directives, no
227
+ hydration mismatches, and a static build that scp's to a server with
228
+ nginx alpine. See sc#82 for the migration rationale.
229
+
230
+ The brew step still emits Next.js production code; \`slowcook port\`
231
+ translates Vite/React-Router screens to Next.js App Router pages.
232
+
233
+ ## Add a scenario by hand
234
+
235
+ \`\`\`ts
236
+ // mock/scenarios/story-017.ts
237
+ import type { Scenario } from '@slowcook-ai/mock-runtime';
238
+
239
+ const scenario: Scenario = {
240
+ id: '017',
241
+ name: 'Owner with 3 pins, 8 reactions',
242
+ user: { id: 'amin', handle: 'amin', display_name: 'Amin Azar' },
243
+ initialPath: '/u/amin',
244
+ fixtures: { /* ... */ },
245
+ };
246
+
247
+ export default scenario;
248
+ \`\`\`
249
+
250
+ Then add to \`mock/src/lib/scenario-registry.tsx\`:
251
+
252
+ \`\`\`ts
253
+ import story017 from '../../scenarios/story-017';
254
+ export const registry = defineScenarios([story017]);
255
+ \`\`\`
256
+ `;
257
+ const MAIN_TSX = `import { StrictMode } from 'react';
258
+ import { createRoot } from 'react-dom/client';
259
+ import { BrowserRouter } from 'react-router-dom';
260
+ import { App } from './App';
261
+ import { ScenarioRegistryProvider } from './lib/scenario-registry';
262
+ import { registry } from './lib/scenario-registry';
263
+ import { makeGlobalCSS } from './design-system/css';
264
+
265
+ // Inject the design-system global stylesheet. Replaces the need for a
266
+ // separate index.css; vibe/brand can overwrite makeGlobalCSS without
267
+ // editing main.tsx.
268
+ const styleEl = document.createElement('style');
269
+ styleEl.textContent = makeGlobalCSS('en');
270
+ document.head.appendChild(styleEl);
271
+
272
+ const rootEl = document.getElementById('root');
273
+ if (!rootEl) throw new Error('No #root element in index.html');
274
+
275
+ createRoot(rootEl).render(
276
+ <StrictMode>
277
+ <BrowserRouter>
278
+ <ScenarioRegistryProvider registry={registry}>
279
+ <App />
280
+ </ScenarioRegistryProvider>
281
+ </BrowserRouter>
282
+ </StrictMode>,
283
+ );
284
+ `;
285
+ const APP_TSX = `import { Routes, Route, Navigate } from 'react-router-dom';
286
+ import { ScenarioPicker } from './lib/scenario-registry';
287
+
288
+ // ┌──────────────────────────────────────────────────────────────────┐
289
+ // │ Vibe-managed route imports — don't reorder; vibe appends below. │
290
+ // └──────────────────────────────────────────────────────────────────┘
291
+ // import { Dashboard } from './apps/patient/screens/Dashboard';
292
+
293
+ export function App() {
294
+ return (
295
+ <Routes>
296
+ <Route path="/" element={<ScenarioPicker />} />
297
+
298
+ {/* ┌────────────────────────────────────────────────────────────┐ */}
299
+ {/* │ Vibe-managed routes — don't reorder; vibe appends below. │ */}
300
+ {/* └────────────────────────────────────────────────────────────┘ */}
301
+ {/* <Route path="/patient/dashboard" element={<Dashboard />} /> */}
302
+
303
+ <Route path="*" element={<Navigate to="/" replace />} />
304
+ </Routes>
305
+ );
306
+ }
307
+ `;
308
+ const TOKENS_TS = `// design-system/tokens.ts — minimal seed.
309
+ //
310
+ // \`slowcook brand\` overwrites these tokens with a brand-specific palette
311
+ // derived from a brief/screenshot/reference. Until brand runs, agents
312
+ // use these neutral values.
313
+
314
+ export const COLORS = {
315
+ // Brand (neutral seed — slowcook brand overwrites)
316
+ primary: '#3B82F6',
317
+ primaryLight: '#60A5FA',
318
+ primaryDark: '#1D4ED8',
319
+ primaryGhost: 'rgba(59,130,246,0.12)',
320
+
321
+ accent: '#F59E0B',
322
+ accentLight: '#FBBF24',
323
+ accentGhost: 'rgba(245,158,11,0.15)',
324
+
325
+ // Semantic
326
+ success: '#10B981',
327
+ successGhost: 'rgba(16,185,129,0.12)',
328
+ danger: '#EF4444',
329
+ dangerGhost: 'rgba(239,68,68,0.12)',
330
+ warn: '#D97706',
331
+ warnGhost: '#FEF3C7',
332
+
333
+ // Surfaces
334
+ bg: '#F9FAFB',
335
+ bgDark: '#111827',
336
+ white: '#FFFFFF',
337
+ sidebar: '#F3F4F6',
338
+
339
+ // Borders + neutrals
340
+ cardBorder: 'rgba(0,0,0,0.06)',
341
+ sidebarBorder: 'rgba(0,0,0,0.08)',
342
+ sand: '#D1D5DB',
343
+ cream: '#F3F4F6',
344
+
345
+ // Text
346
+ textDark: '#111827',
347
+ textMid: '#4B5563',
348
+ textLight: '#9CA3AF',
349
+ };
350
+
351
+ export const SPACING = { xs: 4, sm: 8, md: 14, lg: 20, xl: 28, xxl: 40 };
352
+ export const RADIUS = { sm: 8, md: 12, lg: 17, xl: 22, pill: 100, full: '50%' as const };
353
+
354
+ export const SHADOW = {
355
+ card: '0 2px 18px rgba(0,0,0,0.05)',
356
+ stat: '0 2px 12px rgba(0,0,0,0.04)',
357
+ btn: '0 3px 12px rgba(59,130,246,0.28)',
358
+ btnAccent: '0 3px 12px rgba(245,158,11,0.30)',
359
+ nav: '0 -3px 16px rgba(0,0,0,0.08)',
360
+ };
361
+
362
+ export const FONTS = {
363
+ en: {
364
+ heading: "'Inter', sans-serif",
365
+ body: "'Inter', sans-serif",
366
+ import: 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
367
+ },
368
+ fa: {
369
+ heading: "'Vazirmatn', sans-serif",
370
+ body: "'Vazirmatn', sans-serif",
371
+ import: 'https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700&display=swap',
372
+ },
373
+ };
374
+
375
+ export type Lang = keyof typeof FONTS;
376
+ `;
377
+ const CSS_TS = `import { COLORS, FONTS, RADIUS } from './tokens';
378
+ import type { Lang } from './tokens';
379
+
380
+ // makeGlobalCSS(lang) — returns the full global stylesheet as one
381
+ // string. Inject at app root (\`main.tsx\` does this). Direction-aware:
382
+ // \`fa\` → RTL, anything else → LTR.
383
+ //
384
+ // \`slowcook brand\` overwrites this file to encode brand-specific rules
385
+ // (animations, ds-* utility classes, custom scrollbars, etc.). The
386
+ // seed below is the bare minimum so \`vite dev\` renders readable text.
387
+ export function makeGlobalCSS(lang: Lang): string {
388
+ const f = FONTS[lang];
389
+ const dir = lang === 'fa' ? 'rtl' : 'ltr';
390
+ return \`
391
+ @import url('\${f.import}');
392
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
393
+ html { scroll-behavior: smooth; }
394
+ body {
395
+ direction: \${dir};
396
+ font-family: \${f.body};
397
+ background: \${COLORS.bg};
398
+ color: \${COLORS.textDark};
399
+ min-height: 100vh;
400
+ -webkit-font-smoothing: antialiased;
401
+ }
402
+ a { color: \${COLORS.primary}; text-decoration: none; }
403
+ input, textarea, select {
404
+ font-family: \${f.body};
405
+ border: 1px solid \${COLORS.sand};
406
+ border-radius: \${RADIUS.md}px;
407
+ padding: 10px 14px;
408
+ font-size: 13px;
409
+ background: white;
410
+ width: 100%;
411
+ }
412
+ input:focus, textarea:focus, select:focus {
413
+ outline: none;
414
+ border-color: \${COLORS.primary};
415
+ box-shadow: 0 0 0 3px \${COLORS.primaryGhost};
416
+ }
417
+ \`;
418
+ }
419
+ `;
420
+ const DS_INDEX_TS = `// Re-exports — keep one stable import surface for screens:
421
+ // import { COLORS, makeGlobalCSS, ... } from '@/design-system';
422
+ //
423
+ // \`slowcook brand\` extends this file when it generates primitives.tsx
424
+ // and icons.tsx.
425
+
426
+ export * from './tokens';
427
+ export { makeGlobalCSS } from './css';
428
+ `;
429
+ const SCENARIO_REGISTRY = `import { createContext, useContext, type ReactNode } from 'react';
430
+ import { Link } from 'react-router-dom';
431
+
432
+ // ┌──────────────────────────────────────────────────────────────────┐
433
+ // │ Inline scenario primitives — Vite mock has no \`mock-runtime\` dep │
434
+ // │ (see mock-vite.ts comment for why). Replace with the upstream │
435
+ // │ package once it ships a Vite-compatible build. │
436
+ // └──────────────────────────────────────────────────────────────────┘
437
+
438
+ export interface Scenario {
439
+ id: string;
440
+ name: string;
441
+ description?: string;
442
+ initialPath?: string;
443
+ user?: { id: string; handle: string; display_name: string };
444
+ fixtures?: Record<string, unknown>;
445
+ expectedInteractions?: string[];
446
+ }
447
+
448
+ const Ctx = createContext<{ registry: Scenario[] }>({ registry: [] });
449
+
450
+ export function ScenarioRegistryProvider({
451
+ registry,
452
+ children,
453
+ }: {
454
+ registry: Scenario[];
455
+ children: ReactNode;
456
+ }) {
457
+ return <Ctx.Provider value={{ registry }}>{children}</Ctx.Provider>;
458
+ }
459
+
460
+ export function useScenarios(): Scenario[] {
461
+ return useContext(Ctx).registry;
462
+ }
463
+
464
+ export function defineScenarios(items: Scenario[]): Scenario[] {
465
+ return items;
466
+ }
467
+
468
+ export function ScenarioPicker() {
469
+ const scenarios = useScenarios();
470
+ return (
471
+ <main
472
+ style={{
473
+ maxWidth: 720,
474
+ margin: '0 auto',
475
+ padding: '40px 24px',
476
+ fontFamily: 'inherit',
477
+ }}
478
+ >
479
+ <h1 style={{ fontSize: 28, marginBottom: 12 }}>Scenarios</h1>
480
+ <p style={{ color: '#6b7280', marginBottom: 24 }}>
481
+ Pick a scenario to navigate to its initial path.
482
+ </p>
483
+ {scenarios.length === 0 ? (
484
+ <div
485
+ style={{
486
+ padding: 20,
487
+ background: '#F3F4F6',
488
+ borderRadius: 12,
489
+ color: '#4B5563',
490
+ }}
491
+ >
492
+ No scenarios yet. <code>slowcook vibe</code> will add them as stories
493
+ ship.
494
+ </div>
495
+ ) : (
496
+ <ul style={{ listStyle: 'none', display: 'grid', gap: 10 }}>
497
+ {scenarios.map((s) => (
498
+ <li key={s.id}>
499
+ <Link
500
+ to={s.initialPath ?? '/'}
501
+ style={{
502
+ display: 'block',
503
+ padding: 16,
504
+ borderRadius: 12,
505
+ background: 'white',
506
+ border: '1px solid rgba(0,0,0,0.08)',
507
+ color: 'inherit',
508
+ textDecoration: 'none',
509
+ }}
510
+ >
511
+ <div style={{ fontWeight: 600 }}>{s.name}</div>
512
+ <div
513
+ style={{
514
+ fontSize: 12,
515
+ color: '#6b7280',
516
+ marginTop: 4,
517
+ }}
518
+ >
519
+ story-{s.id} · {s.initialPath ?? '/'}
520
+ </div>
521
+ </Link>
522
+ </li>
523
+ ))}
524
+ </ul>
525
+ )}
526
+ </main>
527
+ );
528
+ }
529
+
530
+ /**
531
+ * Consumer-owned scenario registry.
532
+ *
533
+ * Vibe extends this when it adds a new scenario:
534
+ * - one new \`import\` line for the scenario file
535
+ * - one new entry in the \`defineScenarios([...])\` array
536
+ *
537
+ * Hand-edits are fine — vibe + plate respect existing entries and
538
+ * only append.
539
+ */
540
+
541
+ // Vibe-managed imports below this line. Don't reorder; vibe inserts
542
+ // new lines at the bottom of the import block.
543
+ // e.g. import story017 from '../../scenarios/story-017';
544
+
545
+ export const registry = defineScenarios([
546
+ // story017,
547
+ ]);
548
+ `;
549
+ const MOCK_YAML = `# .brewing/mock.yaml — mock shape config (sc#82).
550
+ #
551
+ # Downstream slowcook agents read this to know where the mock lives
552
+ # and what shape it has. Update when migrating between shapes.
553
+ schema_version: 1
554
+
555
+ # vite | nextjs — the runtime + dev-server flavour for mock/.
556
+ shape: vite
557
+
558
+ # Where mock files live, relative to repo root.
559
+ mock_root: mock
560
+
561
+ # Where vibe writes screen files. Glob shape varies by shape:
562
+ # vite: mock/src/apps/<role>/screens/<Screen>.tsx
563
+ # nextjs: mock/src/app/<route>/page.tsx
564
+ screens_root: mock/src/apps
565
+
566
+ # Where brand emits the design system. brand runs once per project +
567
+ # overwrites these files on --refresh.
568
+ design_system_dir: mock/src/design-system
569
+
570
+ # Where the top-level router lives (vite shape only). Vibe appends new
571
+ # routes here.
572
+ router_file: mock/src/App.tsx
573
+
574
+ # Where scenarios live. Vibe writes \`scenarios/story-<id>.ts\` files.
575
+ scenarios_dir: mock/scenarios
576
+
577
+ # Where the scenario registry lives. Vibe appends imports + array entries.
578
+ scenario_registry_file: mock/src/lib/scenario-registry.tsx
579
+ `;
580
+ export async function initMockVite(argv, cliVersion) {
581
+ const { mockRuntimeVersionFor } = await import("./mock.js");
582
+ const args = {
583
+ cwd: process.cwd(),
584
+ force: false,
585
+ dryRun: false,
586
+ runtimeVersion: mockRuntimeVersionFor(cliVersion),
587
+ };
588
+ for (let i = 0; i < argv.length; i++) {
589
+ const a = argv[i];
590
+ const next = argv[i + 1];
591
+ if (a === "--cwd" && next) {
592
+ args.cwd = next;
593
+ i++;
594
+ }
595
+ else if (a === "--force") {
596
+ args.force = true;
597
+ }
598
+ else if (a === "--dry-run") {
599
+ args.dryRun = true;
600
+ }
601
+ else if (a === "--runtime-version" && next) {
602
+ args.runtimeVersion = next;
603
+ i++;
604
+ }
605
+ }
606
+ const files = planMockViteFiles(args);
607
+ applyMockViteFiles(args, files);
608
+ console.log(`\nDone. cd mock && npm install && npm run dev → http://localhost:3100\n` +
609
+ `Next: \`slowcook brand\` populates the design system before vibe runs.`);
610
+ }
611
+ //# sourceMappingURL=mock-vite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-vite.js","sourceRoot":"","sources":["../../../src/commands/init/mock-vite.ts"],"names":[],"mappings":"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"}
@@ -89,5 +89,11 @@ export declare function ensurePnpmWorkspace(cwd: string): EnsureWorkspaceResult;
89
89
  * malforming a file with comments).
90
90
  */
91
91
  export declare function ensureMockInTsconfigExclude(tsconfigPath: string): boolean;
92
+ /**
93
+ * The mock-runtime package versions track slowcook's overall release
94
+ * cadence. Until 0.16 final cuts we hardcode the latest known version
95
+ * here. After 0.16 the cli's package.json could carry a peer-pin field.
96
+ */
97
+ export declare function mockRuntimeVersionFor(_cliVersion: string): string;
92
98
  export {};
93
99
  //# sourceMappingURL=mock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/commands/init/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,YAAY,CAoBtF;AAsDD,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,EAAE,CAmC/D;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmGhF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAC7B,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAKrC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAYlE;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAiDtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAmBzE"}
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/commands/init/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,YAAY,CAoBtF;AAsDD,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,EAAE,CAmC/D;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoHhF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAC7B,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAKrC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAYlE;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAiDtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAmBzE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAIjE"}
@@ -134,6 +134,22 @@ export function planMockFiles(args) {
134
134
  ];
135
135
  }
136
136
  export async function initMock(argv, cliVersion) {
137
+ // 0.19.0+ (sc#82) — `--shape vite` scaffolds a Vite/React SPA mock
138
+ // instead of the legacy Next.js mock. Vite shape is the new default
139
+ // for greenfield consumers; Next.js shape stays for backwards
140
+ // compatibility with consumers already on it.
141
+ const shapeIdx = argv.findIndex((a) => a === "--shape");
142
+ const shape = shapeIdx >= 0 ? argv[shapeIdx + 1] : "vite";
143
+ if (shape !== "vite" && shape !== "nextjs") {
144
+ console.error(`--shape must be 'vite' or 'nextjs', got: ${shape ?? "(missing)"}`);
145
+ process.exit(2);
146
+ }
147
+ if (shape === "vite") {
148
+ const { initMockVite } = await import("./mock-vite.js");
149
+ // Strip the --shape flag + value from argv before delegating.
150
+ const rest = argv.filter((_, i) => i !== shapeIdx && i !== shapeIdx + 1);
151
+ return initMockVite(rest, cliVersion);
152
+ }
137
153
  const runtimeVersion = mockRuntimeVersionFor(cliVersion);
138
154
  const args = parseMockInitArgs(argv, runtimeVersion);
139
155
  const files = planMockFiles(args);
@@ -375,10 +391,10 @@ export function ensureMockInTsconfigExclude(tsconfigPath) {
375
391
  * cadence. Until 0.16 final cuts we hardcode the latest known version
376
392
  * here. After 0.16 the cli's package.json could carry a peer-pin field.
377
393
  */
378
- function mockRuntimeVersionFor(_cliVersion) {
379
- // Pin to ^0.1.0 — what's actually on npm. ^ picks up 0.1.x patches
380
- // when they publish; bumping past 0.2 needs an intentional cli release.
381
- return "^0.1.0";
394
+ export function mockRuntimeVersionFor(_cliVersion) {
395
+ // Pin to ^0.3.0 — what's actually on npm. ^ picks up 0.3.x patches
396
+ // when they publish; bumping major needs an intentional cli release.
397
+ return "^0.3.0";
382
398
  }
383
399
  // ---------------- templates ----------------
384
400
  const PACKAGE_JSON = (runtimeVersion, name) => `{