@getcoherent/cli 0.6.10 → 0.6.11

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.
@@ -194,48 +194,172 @@ NEVER include app-style elements (sidebar widgets, data tables, filters) on mark
194
194
  var DESIGN_QUALITY_APP = `
195
195
  ## DESIGN QUALITY \u2014 APP PAGES
196
196
 
197
+ ### Reference Patterns (COPY these exact patterns)
198
+
199
+ PAGE HEADER:
200
+ \`\`\`
201
+ <div className="flex items-center justify-between">
202
+ <div className="space-y-1">
203
+ <h1 className="text-2xl font-bold tracking-tight">Page Title</h1>
204
+ <p className="text-sm text-muted-foreground">Page description</p>
205
+ </div>
206
+ <Button><Plus className="size-4 mr-2 shrink-0" />New Item</Button>
207
+ </div>
208
+ \`\`\`
209
+
210
+ FILTER TOOLBAR (search + dropdowns + action):
211
+ \`\`\`
212
+ <div className="flex flex-wrap items-center gap-2">
213
+ <div className="relative flex-1">
214
+ <Search className="absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground shrink-0" />
215
+ <Input placeholder="Search..." className="pl-9" />
216
+ </div>
217
+ <Select>
218
+ <SelectTrigger className="w-[180px]">
219
+ <SelectValue placeholder="All Status" />
220
+ </SelectTrigger>
221
+ <SelectContent>
222
+ <SelectItem value="all">All Status</SelectItem>
223
+ <SelectItem value="active">Active</SelectItem>
224
+ </SelectContent>
225
+ </Select>
226
+ <Button><Plus className="size-4 mr-2 shrink-0" />New Item</Button>
227
+ </div>
228
+ \`\`\`
229
+ CRITICAL: NEVER use <Select> with native <option> elements. Always use the shadcn compound pattern above (SelectTrigger + SelectValue + SelectContent + SelectItem).
230
+ Do NOT add standalone filter icon buttons. The Select dropdowns ARE the filters.
231
+
232
+ STATS GRID:
233
+ \`\`\`
234
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
235
+ <Card>
236
+ <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
237
+ <CardTitle className="text-sm font-medium">Metric Name</CardTitle>
238
+ <TrendingUp className="size-4 text-muted-foreground shrink-0" />
239
+ </CardHeader>
240
+ <CardContent>
241
+ <div className="text-2xl font-bold">1,234</div>
242
+ <p className="text-xs text-muted-foreground">+12% from last month</p>
243
+ </CardContent>
244
+ </Card>
245
+ </div>
246
+ \`\`\`
247
+
248
+ DATA TABLE:
249
+ \`\`\`
250
+ <div className="overflow-x-auto">
251
+ <Table>
252
+ <TableHeader>
253
+ <TableRow>
254
+ <TableHead>Name</TableHead>
255
+ <TableHead>Status</TableHead>
256
+ <TableHead className="w-[50px]"></TableHead>
257
+ </TableRow>
258
+ </TableHeader>
259
+ <TableBody>
260
+ <TableRow className="hover:bg-muted/50">
261
+ <TableCell className="font-medium">Item name</TableCell>
262
+ <TableCell><Badge variant="default">Active</Badge></TableCell>
263
+ <TableCell>
264
+ <DropdownMenu>
265
+ <DropdownMenuTrigger asChild>
266
+ <Button variant="ghost" size="icon"><MoreHorizontal className="size-4 shrink-0" /></Button>
267
+ </DropdownMenuTrigger>
268
+ <DropdownMenuContent align="end">
269
+ <DropdownMenuItem>Edit</DropdownMenuItem>
270
+ <DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem>
271
+ </DropdownMenuContent>
272
+ </DropdownMenu>
273
+ </TableCell>
274
+ </TableRow>
275
+ </TableBody>
276
+ </Table>
277
+ </div>
278
+ \`\`\`
279
+
280
+ EMPTY STATE (when list/table has zero items):
281
+ \`\`\`
282
+ <div className="flex flex-col items-center justify-center py-12 text-center">
283
+ <Inbox className="size-12 text-muted-foreground mb-4 shrink-0" />
284
+ <h3 className="text-lg font-semibold">No items yet</h3>
285
+ <p className="text-sm text-muted-foreground mt-1 max-w-sm">Create your first item to get started.</p>
286
+ <Button className="mt-4"><Plus className="size-4 mr-2 shrink-0" />Create Item</Button>
287
+ </div>
288
+ \`\`\`
289
+
290
+ DATA CARD GRID:
291
+ \`\`\`
292
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
293
+ <Card className="hover:border-border/30 transition-colors">
294
+ <CardHeader className="flex flex-row items-start justify-between space-y-0">
295
+ <div className="space-y-1">
296
+ <CardTitle>Item Name</CardTitle>
297
+ <p className="text-sm text-muted-foreground">Description</p>
298
+ </div>
299
+ <DropdownMenu>
300
+ <DropdownMenuTrigger asChild>
301
+ <Button variant="ghost" size="icon"><MoreHorizontal className="size-4 shrink-0" /></Button>
302
+ </DropdownMenuTrigger>
303
+ <DropdownMenuContent align="end">
304
+ <DropdownMenuItem>Edit</DropdownMenuItem>
305
+ <DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem>
306
+ </DropdownMenuContent>
307
+ </DropdownMenu>
308
+ </CardHeader>
309
+ <CardContent>...</CardContent>
310
+ </Card>
311
+ </div>
312
+ \`\`\`
313
+
197
314
  ### Spacing
198
315
  - gap-4 md:gap-6 between sections
199
316
  - p-4 lg:p-6 content padding
200
- - Within cards: p-4 to p-6 (compact)
201
- - Between cards in grid: gap-4 (tight)
202
-
203
- ### Layout
204
- - Data tables, card grids, filters, stat rows
205
317
  - Page wrapper: flex flex-1 flex-col gap-4 p-4 lg:p-6
206
- - Stats grid: grid gap-4 md:grid-cols-2 lg:grid-cols-4
207
- - Content: functional, scannable, data-dense
208
-
209
- ### Toolbars & Filters
210
- - Filter row: flex flex-wrap items-center gap-2 (plain div, NOT inside a Card)
211
- - Search input: MUST use flex-1 to fill remaining horizontal space. NEVER fixed-width search.
212
- - Filters/selects: fixed width (w-[180px] or auto), do NOT flex-grow
213
- - On mobile (sm:): search full width, filters wrap to next line
214
- - Do NOT wrap search/filter toolbars in Card components. They are plain flex rows above content.
215
-
216
- ### Tabs
217
- - Always use <TabsList variant="line"> for a clean underline style (not the pill/segmented control default)
218
- - The variant="line" prop removes the bg-muted pill container and uses an underline indicator instead
219
318
 
220
319
  NEVER include marketing sections (hero, pricing, testimonials) on app pages.
221
320
  `;
222
321
  var DESIGN_QUALITY_AUTH = `
223
322
  ## DESIGN QUALITY \u2014 AUTH PAGES
224
323
 
225
- ### Layout
226
- - The auth layout ALREADY provides centering (flex items-center justify-center min-h-svh). Do NOT add your own centering wrapper or min-h-svh.
227
- - Just output: <div className="w-full max-w-md"> containing a Card
324
+ ### Reference Pattern (COPY this exact pattern)
325
+
326
+ AUTH CARD:
327
+ \`\`\`
328
+ <div className="w-full max-w-md">
329
+ <Card>
330
+ <CardHeader className="space-y-1">
331
+ <CardTitle className="font-bold text-center">Welcome back</CardTitle>
332
+ <p className="text-sm text-muted-foreground text-center">Enter your credentials</p>
333
+ </CardHeader>
334
+ <CardContent>
335
+ <form className="space-y-4">
336
+ <div className="space-y-2">
337
+ <Label htmlFor="email">Email</Label>
338
+ <Input id="email" type="email" placeholder="Enter your email" />
339
+ </div>
340
+ <div className="space-y-2">
341
+ <Label htmlFor="password">Password</Label>
342
+ <Input id="password" type="password" placeholder="Enter your password" />
343
+ </div>
344
+ <Button type="submit" className="w-full">Sign in</Button>
345
+ </form>
346
+ </CardContent>
347
+ <CardFooter className="text-center">
348
+ <p className="text-sm text-muted-foreground">
349
+ Don't have an account?{' '}
350
+ <Link href="/register" className="text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground transition-colors">Sign up</Link>
351
+ </p>
352
+ </CardFooter>
353
+ </Card>
354
+ </div>
355
+ \`\`\`
356
+
357
+ ### Rules
358
+ - The auth layout ALREADY provides centering (flex items-center justify-center min-h-svh). Do NOT add your own centering wrapper.
228
359
  - Card width: w-full max-w-md
229
- - No navigation, no section containers, no sidebar
230
- - Single focused form with clear CTA
231
- - Card \u2192 CardHeader (title + description) \u2192 CardContent (form with space-y-4) \u2192 CardFooter (link to other auth page)
232
-
233
- ### Form Spacing
234
360
  - Form fields inside CardContent: space-y-4 between field groups
235
- - Ensure visible gap between the last input field and the submit button (use space-y-4 or space-y-6)
236
361
  - Each field group (Label + Input): space-y-2
237
-
238
- NEVER include navigation bars, sidebars, or multi-section layouts on auth pages.
362
+ - No navigation bars, sidebars, or multi-section layouts on auth pages.
239
363
  `;
240
364
  var DESIGN_QUALITY_CRITICAL = `
241
365
  ## CRITICAL CODE RULES (violations will be auto-corrected)
@@ -366,9 +490,7 @@ MULTI-SELECT / TAG INPUT:
366
490
  var RULES_DATA_DISPLAY = `
367
491
  DATA DISPLAY RULES:
368
492
 
369
- STAT / METRIC CARDS:
370
- - Pattern: Card > CardHeader(flex flex-row items-center justify-between space-y-0 pb-2) > CardTitle(text-sm font-medium) + Icon(size-4 text-muted-foreground) ; CardContent > metric(text-2xl font-bold) + change(text-xs text-muted-foreground).
371
- - Grid: grid gap-4 md:grid-cols-2 lg:grid-cols-4.
493
+ STAT / METRIC CARDS: See the Stats Grid reference pattern in DESIGN QUALITY \u2014 APP PAGES. Follow that exact pattern.
372
494
  - Trend up: text-emerald-600 (light) / text-emerald-400 (dark) \u2014 exception to semantic-only rule for trend indicators.
373
495
  - Trend down: text-destructive.
374
496
  - Trend icon: ArrowUp / ArrowDown className="size-3 inline mr-1".
@@ -389,12 +511,7 @@ PAGINATION:
389
511
  - Placement: below the list/table, centered. <div className="flex justify-center mt-4">
390
512
  - For short lists (<20 items): no pagination. For feeds: "Load more" button (variant="outline" className="w-full").
391
513
 
392
- EMPTY STATES:
393
- - Pattern: <div className="flex flex-col items-center justify-center py-12 text-center">
394
- - Icon: size-12 text-muted-foreground mb-4 (larger than normal icons \u2014 exception).
395
- - Title: <h3 className="text-lg font-semibold">No projects yet</h3>
396
- - Description: <p className="text-sm text-muted-foreground mt-1 max-w-sm">Create your first project to get started.</p>
397
- - CTA: <Button className="mt-4">Create project</Button>
514
+ EMPTY STATES: See the Empty State reference pattern in DESIGN QUALITY \u2014 APP PAGES. Follow that exact pattern.
398
515
  - Search empty: "No results for 'query'. Try different keywords." + clear search button.
399
516
  - Filtered empty: "No items match your filters." + reset filters button.
400
517
 
@@ -431,9 +548,7 @@ TRUNCATION:
431
548
  - When to truncate: card descriptions (2 lines), table cells (single line), list item subtitles (1-2 lines).
432
549
  - Always set title={fullText} for accessibility on truncated text.
433
550
 
434
- SEARCH INPUT:
435
- - Pattern: <div className="relative"><Search className="absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" /><Input placeholder="Search..." className="pl-9" /></div>
436
- - Placement: top of the list/table it filters, max-w-sm.
551
+ SEARCH INPUT: See the Filter Toolbar reference pattern in DESIGN QUALITY \u2014 APP PAGES. Use the search input + Select layout shown there.
437
552
  - Clear button: X icon on right when value is not empty.
438
553
  - Debounce: 300ms on keystroke. No search button.
439
554
  `;
@@ -1125,6 +1240,8 @@ async function generateSharedComponentsFromPlan(plan, styleContext, projectRoot,
1125
1240
  const componentSpecs = plan.sharedComponents.map(
1126
1241
  (c) => `- ${c.name}: ${c.description}. Props: ${c.props}. Type: ${c.type}. shadcn deps: ${c.shadcnDeps.join(", ") || "none"}`
1127
1242
  ).join("\n");
1243
+ const designRules = `${CORE_CONSTRAINTS}
1244
+ ${getDesignQualityForType("app")}`;
1128
1245
  const prompt = `Generate React components as separate files. For EACH component below, return an add-page request with name and pageCode fields.
1129
1246
 
1130
1247
  Components to generate:
@@ -1132,6 +1249,8 @@ ${componentSpecs}
1132
1249
 
1133
1250
  Style context: ${styleContext || "default"}
1134
1251
 
1252
+ ${designRules}
1253
+
1135
1254
  Requirements:
1136
1255
  - Each component MUST have \`export default function ComponentName\`
1137
1256
  - Use shadcn/ui imports from @/components/ui/*
@@ -1183,6 +1302,7 @@ Return JSON with { requests: [{ type: "add-page", changes: { name: "ComponentNam
1183
1302
  export {
1184
1303
  DESIGN_THINKING,
1185
1304
  CORE_CONSTRAINTS,
1305
+ DESIGN_QUALITY_COMMON,
1186
1306
  getDesignQualityForType,
1187
1307
  inferPageTypeFromRoute,
1188
1308
  DESIGN_QUALITY,