@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.
- package/dist/cli.js +28 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/brand/index.d.ts +58 -0
- package/dist/commands/brand/index.d.ts.map +1 -0
- package/dist/commands/brand/index.js +257 -0
- package/dist/commands/brand/index.js.map +1 -0
- package/dist/commands/budget/index.d.ts +2 -0
- package/dist/commands/budget/index.d.ts.map +1 -0
- package/dist/commands/budget/index.js +252 -0
- package/dist/commands/budget/index.js.map +1 -0
- package/dist/commands/dev-env/config.d.ts +136 -0
- package/dist/commands/dev-env/config.d.ts.map +1 -0
- package/dist/commands/dev-env/config.js +96 -0
- package/dist/commands/dev-env/config.js.map +1 -0
- package/dist/commands/dev-env/index.d.ts +27 -0
- package/dist/commands/dev-env/index.d.ts.map +1 -0
- package/dist/commands/dev-env/index.js +226 -0
- package/dist/commands/dev-env/index.js.map +1 -0
- package/dist/commands/dev-env/init.d.ts +28 -0
- package/dist/commands/dev-env/init.d.ts.map +1 -0
- package/dist/commands/dev-env/init.js +135 -0
- package/dist/commands/dev-env/init.js.map +1 -0
- package/dist/commands/eval/index.d.ts.map +1 -1
- package/dist/commands/eval/index.js +15 -1
- package/dist/commands/eval/index.js.map +1 -1
- package/dist/commands/init/mock-vite.d.ts +54 -0
- package/dist/commands/init/mock-vite.d.ts.map +1 -0
- package/dist/commands/init/mock-vite.js +611 -0
- package/dist/commands/init/mock-vite.js.map +1 -0
- package/dist/commands/init/mock.d.ts +6 -0
- package/dist/commands/init/mock.d.ts.map +1 -1
- package/dist/commands/init/mock.js +20 -4
- package/dist/commands/init/mock.js.map +1 -1
- package/dist/commands/plate/agent.d.ts +7 -0
- package/dist/commands/plate/agent.d.ts.map +1 -1
- package/dist/commands/plate/agent.js +1 -1
- package/dist/commands/plate/agent.js.map +1 -1
- package/dist/commands/plate/index.d.ts.map +1 -1
- package/dist/commands/plate/index.js +6 -0
- package/dist/commands/plate/index.js.map +1 -1
- package/dist/commands/refine/agent.d.ts +12 -0
- package/dist/commands/refine/agent.d.ts.map +1 -1
- package/dist/commands/refine/agent.js +173 -13
- package/dist/commands/refine/agent.js.map +1 -1
- package/dist/commands/refine/brownfield-answer.d.ts +81 -0
- package/dist/commands/refine/brownfield-answer.d.ts.map +1 -0
- package/dist/commands/refine/brownfield-answer.js +231 -0
- package/dist/commands/refine/brownfield-answer.js.map +1 -0
- package/dist/commands/refine/context.d.ts.map +1 -1
- package/dist/commands/refine/context.js +18 -0
- package/dist/commands/refine/context.js.map +1 -1
- package/dist/commands/refine/history-index.d.ts +29 -0
- package/dist/commands/refine/history-index.d.ts.map +1 -1
- package/dist/commands/refine/history-index.js +63 -0
- package/dist/commands/refine/history-index.js.map +1 -1
- package/dist/commands/refine/index.d.ts.map +1 -1
- package/dist/commands/refine/index.js +32 -1
- package/dist/commands/refine/index.js.map +1 -1
- package/dist/commands/refine/proposals-synth.d.ts +50 -1
- package/dist/commands/refine/proposals-synth.d.ts.map +1 -1
- package/dist/commands/refine/proposals-synth.js +199 -35
- package/dist/commands/refine/proposals-synth.js.map +1 -1
- package/dist/commands/refine/spec-yaml.d.ts +274 -250
- package/dist/commands/refine/spec-yaml.d.ts.map +1 -1
- package/dist/commands/refine/spec-yaml.js +10 -0
- package/dist/commands/refine/spec-yaml.js.map +1 -1
- package/dist/commands/run-mock/index.d.ts.map +1 -1
- package/dist/commands/run-mock/index.js +7 -1
- package/dist/commands/run-mock/index.js.map +1 -1
- package/dist/commands/testgen/agent.d.ts.map +1 -1
- package/dist/commands/testgen/agent.js +34 -9
- package/dist/commands/testgen/agent.js.map +1 -1
- package/dist/commands/vibe/agent.d.ts +7 -0
- package/dist/commands/vibe/agent.d.ts.map +1 -1
- package/dist/commands/vibe/agent.js +2 -2
- package/dist/commands/vibe/agent.js.map +1 -1
- package/dist/commands/vibe/index.d.ts.map +1 -1
- package/dist/commands/vibe/index.js +7 -1
- package/dist/commands/vibe/index.js.map +1 -1
- package/dist/cost-store.d.ts +52 -0
- package/dist/cost-store.d.ts.map +1 -0
- package/dist/cost-store.js +108 -0
- package/dist/cost-store.js.map +1 -0
- package/dist/lib/budget.d.ts +123 -0
- package/dist/lib/budget.d.ts.map +1 -0
- package/dist/lib/budget.js +225 -0
- package/dist/lib/budget.js.map +1 -0
- package/dist/lib/mock-shape.d.ts +44 -0
- package/dist/lib/mock-shape.d.ts.map +1 -0
- package/dist/lib/mock-shape.js +77 -0
- package/dist/lib/mock-shape.js.map +1 -0
- 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,
|
|
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.
|
|
380
|
-
// when they publish; bumping
|
|
381
|
-
return "^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) => `{
|