@almadar/skills 1.0.13 → 1.1.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/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, writeFileSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import { generateBehaviorsDocs, getAllBehaviors, generateModulesDocs, getAllStdOperators } from '@almadar/std';
4
4
  import { OPERATORS, UI_SLOTS, PATTERN_TYPES, ViewTypeSchema } from '@almadar/core/types';
5
- import { getPatternPropsCompact, getPatternActionsRef, getAllPatternTypes, getPatternsGroupedByCategory } from '@almadar/patterns';
5
+ import { getPatternPropsCompact, getPatternActionsRef, getAllPatternTypes } from '@almadar/patterns';
6
6
 
7
7
  // src/generators/utils.ts
8
8
  function formatFrontmatter(fm) {
@@ -46,24 +46,6 @@ Writing ${skills.length} skills to ${baseDir}...`);
46
46
  console.log(`
47
47
  \u2713 Generated ${skills.length} skills`);
48
48
  }
49
- function getMinimalTypeReference() {
50
- const patternsByCategory = getPatternsGroupedByCategory();
51
- const categories = Object.keys(patternsByCategory);
52
- return `## Type Reference
53
-
54
- ### Pattern Types
55
- ${categories.map((cat) => `- **${cat}**: ${patternsByCategory[cat].slice(0, 5).join(", ")}...`).join("\n")}
56
-
57
- Total: ${PATTERN_TYPES.length} patterns
58
-
59
- ### Operators
60
- Use S-expressions for guards and effects. See std library for full list.
61
-
62
- **Math**: \`+\`, \`-\`, \`*\`, \`/\`, \`>\`, \`<\`, \`>=\`, \`<=\`, \`=\`, \`!=\`
63
- **Logic**: \`and\`, \`or\`, \`not\`
64
- **Effects**: \`set\`, \`++\`, \`--\`, \`persist\`, \`fetch\`, \`emit\`, \`render-ui\`
65
- `;
66
- }
67
49
  function getSExprQuickRef() {
68
50
  return `## S-Expression Syntax
69
51
 
@@ -280,35 +262,23 @@ function getValidViewTypes() {
280
262
  const validTypes = ViewTypeSchema.options;
281
263
  return validTypes.map((t) => `\`${t}\``).join(", ");
282
264
  }
283
- function getCommonErrorsSection() {
265
+ function getCommonErrorsSection(level = "full") {
266
+ const critical = getCriticalErrors();
267
+ if (level === "top6") return critical;
268
+ return critical + getEdgeCaseErrors();
269
+ }
270
+ function getCriticalErrors() {
284
271
  return `## Critical Rules
285
272
 
286
- ### NEVER Use @payload in set Effects (CRITICAL)
287
-
288
- The \`set\` effect modifies entity state. **@payload is READ-ONLY** - it contains event data.
289
-
290
- \`\`\`json
291
- // WRONG - @payload is read-only!
292
- ["set", "@payload.data.createdAt", "@now"]
293
- ["set", "@payload.data.status", "active"]
294
-
295
- // CORRECT - Use @entity to modify state
296
- ["set", "@entity.createdAt", "@now"]
297
- ["set", "@entity.status", "active"]
298
- \`\`\`
299
-
300
- **Rule:** \`set\` target MUST start with \`@entity\`, never \`@payload\`.
301
-
302
- ### INIT Transition Required (CRITICAL)
273
+ ### 1. INIT Transition Required (CRITICAL)
303
274
 
304
275
  Every trait MUST have an INIT self-loop transition. The runtime fires \`INIT\` when page loads.
305
276
 
306
277
  \`\`\`json
307
- // REQUIRED in EVERY trait:
308
278
  {
309
279
  "from": "Browsing",
310
280
  "to": "Browsing",
311
- "event": "INIT", // \u2190 Runtime fires this on page load
281
+ "event": "INIT",
312
282
  "effects": [
313
283
  ["render-ui", "main", { "type": "page-header", ... }],
314
284
  ["render-ui", "main", { "type": "entity-table", ... }]
@@ -318,43 +288,40 @@ Every trait MUST have an INIT self-loop transition. The runtime fires \`INIT\` w
318
288
 
319
289
  Without INIT: Page loads blank, nothing renders, no UI appears.
320
290
 
321
- ### Valid Patterns ONLY (CRITICAL)
291
+ ### 2. NEVER Use @payload in set Effects
322
292
 
323
- **DO NOT invent custom patterns!** Only these patterns exist:
293
+ The \`set\` effect modifies entity state. **@payload is READ-ONLY**.
324
294
 
325
- ${getPatternCategories()}
295
+ \`\`\`json
296
+ // WRONG
297
+ ["set", "@payload.data.status", "active"]
298
+
299
+ // CORRECT
300
+ ["set", "@entity.status", "active"]
301
+ \`\`\`
326
302
 
327
- **NEVER use**: \`onboarding-welcome\`, \`category-selector\`, \`assessment-question\`, etc. - these DO NOT exist!
303
+ **Rule:** \`set\` target MUST start with \`@entity\`, never \`@payload\`.
328
304
 
329
- ### Valid viewType Values
305
+ ### 3. Valid Patterns ONLY
330
306
 
331
- Pages must use valid viewType values: ${getValidViewTypes()}
307
+ **DO NOT invent custom patterns!** Only these patterns exist:
332
308
 
333
- Invalid values like \`form\`, \`wizard\`, \`onboarding\` will cause validation errors.
309
+ ${getPatternCategories()}
334
310
 
335
- ${getPatternPropsCompact()}
311
+ **NEVER use**: \`onboarding-welcome\`, \`category-selector\`, \`assessment-question\`, etc.
336
312
 
337
- ${getPatternActionsRef()}
313
+ Valid viewType values: ${getValidViewTypes()}
338
314
 
339
- ### Page Structure Required (CRITICAL)
315
+ ### 4. Page Structure Required
340
316
 
341
317
  Every page MUST have \`path\` and \`traits\` properties:
342
318
 
343
319
  \`\`\`json
344
- // WRONG - missing path and traits:
345
- {
346
- "pages": [{
347
- "name": "TasksPage",
348
- "entity": "Task" // \u274C Missing path and traits!
349
- }]
350
- }
351
-
352
- // CORRECT - complete page definition:
353
320
  {
354
321
  "pages": [{
355
322
  "name": "TasksPage",
356
- "path": "/tasks", // \u2190 REQUIRED: starts with /
357
- "traits": [{ "ref": "TaskManagement" }] // \u2190 REQUIRED: trait-driven UI
323
+ "path": "/tasks",
324
+ "traits": [{ "ref": "TaskManagement" }]
358
325
  }]
359
326
  }
360
327
  \`\`\`
@@ -362,232 +329,119 @@ Every page MUST have \`path\` and \`traits\` properties:
362
329
  Without \`path\`: Validation error \`ORB_P_MISSING_PATH\`
363
330
  Without \`traits\`: Validation error \`ORB_P_MISSING_TRAITS\`
364
331
 
365
- ### Valid Field Types ONLY (CRITICAL)
332
+ ### 5. Valid Field Types ONLY
366
333
 
367
334
  Field types MUST be one of: \`string\`, \`number\`, \`boolean\`, \`date\`, \`timestamp\`, \`datetime\`, \`array\`, \`object\`, \`enum\`, \`relation\`
368
335
 
369
336
  \`\`\`json
370
337
  // WRONG - using entity name as type:
371
- { "name": "author", "type": "User" } // \u274C "User" is not a valid type!
372
- { "name": "post", "type": "BlogPost" } // \u274C Invalid!
338
+ { "name": "author", "type": "User" }
373
339
 
374
- // CORRECT - use relation type with entity reference:
340
+ // CORRECT - use relation type:
375
341
  { "name": "author", "type": "relation", "relation": { "entity": "User", "cardinality": "one" } }
376
- { "name": "post", "type": "relation", "relation": { "entity": "BlogPost", "cardinality": "one" } }
377
-
378
- // CORRECT for arrays of primitives:
379
- { "name": "tags", "type": "array", "items": { "type": "string" } }
380
-
381
- // CORRECT for enums:
382
- { "name": "status", "type": "enum", "values": ["pending", "active", "done"] }
383
342
  \`\`\`
384
343
 
385
- ### Event Listeners Structure
344
+ ### 6. Modal State Machine Pattern
386
345
 
387
- Event listeners go INSIDE traits, not at orbital level:
346
+ When a transition opens a modal/drawer, the target state MUST have CLOSE and CANCEL transitions:
388
347
 
389
348
  \`\`\`json
390
- // WRONG - at orbital level:
391
- {
392
- "name": "Task Management",
393
- "listens": ["SOME_EVENT"] // \u274C Wrong location, wrong format
394
- }
395
-
396
- // CORRECT - inside trait:
397
- {
398
- "traits": [{
399
- "name": "TaskInteraction",
400
- "listens": [
401
- { "event": "USER_UPDATED", "handler": "REFRESH_LIST" } // \u2705 Object format
402
- ]
403
- }]
404
- }
349
+ { "from": "Browsing", "to": "Creating", "event": "CREATE",
350
+ "effects": [["render-ui", "modal", { "type": "form-section", "cancelEvent": "CANCEL", ... }]] },
351
+ { "from": "Creating", "to": "Browsing", "event": "CANCEL",
352
+ "effects": [["render-ui", "modal", null]] },
353
+ { "from": "Creating", "to": "Browsing", "event": "CLOSE",
354
+ "effects": [["render-ui", "modal", null]] },
355
+ { "from": "Creating", "to": "Browsing", "event": "SAVE",
356
+ "effects": [["persist", "create", "Entity", "@payload.data"], ["render-ui", "modal", null], ["emit", "INIT"]] }
405
357
  \`\`\`
406
358
 
359
+ **CLOSE** = user clicks outside modal/presses Escape. **CANCEL** = form cancel button. Both needed.
360
+ `;
361
+ }
362
+ function getEdgeCaseErrors() {
363
+ return `
407
364
  ---
408
365
 
409
- ## Common Errors (AVOID)
410
-
411
- ### 1. Missing INIT Transition
412
- \`\`\`
413
- WRONG: No INIT transition \u2192 Page loads blank
414
- CORRECT: { "from": "browsing", "to": "browsing", "event": "INIT", "effects": [...render-ui...] }
415
- \`\`\`
366
+ ## Additional Errors (Edge Cases)
416
367
 
417
- ### 2. Over-Generating Pages
368
+ ### 7. Over-Generating Pages
418
369
  \`\`\`
419
370
  WRONG: TaskListPage, TaskCreatePage, TaskEditPage, TaskViewPage (4 pages!)
420
371
  CORRECT: TasksPage with EntityManagement trait (1 page)
421
372
  \`\`\`
422
373
 
423
- ### 3. Duplicate Slot Rendering
374
+ ### 8. Duplicate Slot Rendering
424
375
  \`\`\`
425
376
  WRONG: Two traits both render to "main" on page load
426
377
  CORRECT: ONE trait owns each slot
427
378
  \`\`\`
428
379
 
429
- ### 4. Missing onSubmit in form-section
380
+ ### 9. Missing onSubmit in form-section
430
381
  \`\`\`
431
382
  WRONG: { "type": "form-section", "entity": "Task" }
432
383
  CORRECT: { "type": "form-section", "entity": "Task", "onSubmit": "SAVE" }
433
384
  \`\`\`
434
385
 
435
- ### 5. Duplicate Transitions (Same from+event)
386
+ ### 10. Duplicate Transitions (Same from+event)
436
387
  \`\`\`
437
388
  WRONG: Two transitions with same "from" and "event" without guards
438
389
  CORRECT: Use GUARDS to differentiate transitions
439
390
  \`\`\`
440
391
 
441
- ### 6. Using "render" Instead of "render-ui"
392
+ ### 11. Using "render" Instead of "render-ui"
442
393
  \`\`\`
443
394
  WRONG: ["render", "main", {...}]
444
395
  CORRECT: ["render-ui", "main", {...}]
445
396
  \`\`\`
446
397
 
447
- ### 7. Generating Sections Array (Legacy)
398
+ ### 12. Generating Sections Array (Legacy)
448
399
  \`\`\`
449
400
  WRONG: { "pages": [{ "sections": [...] }] }
450
401
  CORRECT: { "pages": [{ "traits": [...] }] } - UI comes from render-ui effects
451
402
  \`\`\`
452
403
 
453
- ### 8. Using form-actions Pattern (DOES NOT EXIST!)
404
+ ### 13. Using form-actions Pattern (DOES NOT EXIST!)
454
405
  \`\`\`
455
406
  WRONG: ["render-ui", "main", { "type": "form-actions", "actions": [...] }]
456
- CORRECT: Use form-section with onSubmit/onCancel props:
457
- { "type": "form-section", "entity": "Task", "fields": [...], "onSubmit": "SAVE", "onCancel": "CANCEL" }
407
+ CORRECT: Use form-section with onSubmit/onCancel props
458
408
  \`\`\`
459
- Actions are INSIDE patterns, not separate patterns. The form-section pattern includes submit/cancel buttons.
409
+ Actions are INSIDE patterns, not separate patterns.
460
410
 
461
- ### 9. Forgetting itemActions in entity-table
411
+ ### 14. Forgetting itemActions in entity-table
462
412
  \`\`\`
463
- WRONG: { "type": "entity-table", "entity": "Task" } // No row actions
464
- CORRECT: { "type": "entity-table", "entity": "Task", "itemActions": [{"label": "Edit", "event": "EDIT"}, {"label": "Delete", "event": "DELETE"}] }
413
+ WRONG: { "type": "entity-table", "entity": "Task" }
414
+ CORRECT: { "type": "entity-table", "entity": "Task", "itemActions": [{"label": "Edit", "event": "EDIT"}] }
465
415
  \`\`\`
466
416
 
467
- ### 10. Duplicate Trait Names Across Orbitals
417
+ ### 15. Duplicate Trait Names Across Orbitals
468
418
  \`\`\`
469
419
  WRONG: UserOrbital uses "EntityManagement", TaskOrbital uses "EntityManagement"
470
420
  CORRECT: UserOrbital uses "UserManagement", TaskOrbital uses "TaskManagement"
471
421
  \`\`\`
472
422
  Each trait name MUST be unique. Pattern: \`{Entity}{Purpose}\`
473
423
 
474
- ### 11. Using @payload in set Effect
424
+ ### 16. Hallucinated itemAction Properties
475
425
  \`\`\`
476
- WRONG: ["set", "@payload.acceptedAt", "@now"] // @payload is read-only!
477
- CORRECT: ["set", "@entity.acceptedAt", "@now"] // set modifies entity state
478
- \`\`\`
479
- \`set\` effect MUST use \`@entity.field\` binding. \`@payload\` is read-only event data.
480
-
481
- ### 12. Hallucinated itemAction Properties
482
- \`\`\`
483
- WRONG: { "label": "View", "event": "VIEW", "condition": "@entity.status === 'active'" }
484
- CORRECT: { "label": "View", "event": "VIEW", "showWhen": ["=", "@entity.status", "active"] }
426
+ WRONG: { "label": "View", "event": "VIEW", "condition": "..." }
427
+ CORRECT: { "label": "View", "event": "VIEW" }
485
428
  \`\`\`
486
429
  Valid itemAction props: \`label\`, \`event\`, \`navigatesTo\`, \`placement\`, \`variant\`, \`showWhen\`
487
- Note: \`showWhen\` is defined but NOT yet implemented - actions always visible.
488
-
489
- ### 14. Missing Page Path
490
- \`\`\`
491
- WRONG: { "pages": [{ "name": "TasksPage", "entity": "Task" }] }
492
- CORRECT: { "pages": [{ "name": "TasksPage", "path": "/tasks", "traits": [...] }] }
493
- \`\`\`
494
-
495
- ### 15. Using Entity Name as Field Type
496
- \`\`\`
497
- WRONG: { "name": "author", "type": "User" }
498
- CORRECT: { "name": "author", "type": "relation", "relation": { "entity": "User", "cardinality": "one" } }
499
- \`\`\`
500
-
501
- ### 16. Missing Traits Array on Page
502
- \`\`\`
503
- WRONG: { "pages": [{ "name": "TasksPage", "path": "/tasks" }] }
504
- CORRECT: { "pages": [{ "name": "TasksPage", "path": "/tasks", "traits": [{ "ref": "TaskManagement" }] }] }
505
- \`\`\`
506
-
507
- ### 13. Modal State Machine Pattern (CRITICAL)
508
-
509
- When a transition opens a modal (renders to \`modal\` or \`drawer\` slot), the target state MUST have:
510
- 1. A **CLOSE** transition to clear the modal and return to browsing state
511
- 2. A **CANCEL** transition (for forms with cancel buttons)
512
- 3. The CLOSE/CANCEL effects MUST include \`["render-ui", "modal", null]\` to clear the slot
513
-
514
- \`\`\`json
515
- // WRONG - Modal opens but no way to close it!
516
- {
517
- "from": "browsing", "to": "creating", "event": "CREATE",
518
- "effects": [["render-ui", "modal", { "type": "form-section", ... }]]
519
- }
520
- // No CLOSE or CANCEL transition from "creating" \u2192 Page gets stuck!
521
-
522
- // CORRECT - Full modal open/close cycle:
523
- {
524
- "from": "browsing", "to": "creating", "event": "CREATE",
525
- "effects": [["render-ui", "modal", { "type": "form-section", "cancelEvent": "CANCEL", ... }]]
526
- },
527
- {
528
- "from": "creating", "to": "browsing", "event": "CANCEL",
529
- "effects": [["render-ui", "modal", null]]
530
- },
531
- {
532
- "from": "creating", "to": "browsing", "event": "CLOSE",
533
- "effects": [["render-ui", "modal", null]]
534
- },
535
- {
536
- "from": "creating", "to": "browsing", "event": "SAVE",
537
- "effects": [
538
- ["persist", "create", "Entity", "@payload.data"],
539
- ["render-ui", "modal", null], // \u2190 IMPORTANT: Clear modal on save too!
540
- ["fetch", "Entity", {}]
541
- ]
542
- }
543
- \`\`\`
544
-
545
- **Why CLOSE is needed:** The UI sends \`CLOSE\` when user clicks outside the modal or presses Escape.
546
- **Why CANCEL is needed:** Forms emit \`CANCEL\` when user clicks the Cancel button.
547
- **Both are needed** for complete modal behavior. Without them, the modal cannot be dismissed and reopened.
548
-
549
- ### 14. Wrong Filtering Pattern (Use Query Singleton)
550
- \`\`\`
551
- WRONG: Individual filter buttons with manual FILTER events
552
- { "type": "button", "label": "Active", "action": "FILTER", "data": { "status": "active" } }
553
-
554
- CORRECT: Use Query Singleton entity + filter-group pattern:
555
- \`\`\`
556
-
557
- **Query Singleton Pattern for Filtering:**
558
-
559
- 1. Define a singleton entity to hold filter state:
560
- \`\`\`json
561
- {
562
- "name": "TaskQuery",
563
- "entity": {
564
- "name": "TaskQuery",
565
- "singleton": true,
566
- "runtime": true,
567
- "fields": [
568
- { "name": "status", "type": "string" },
569
- { "name": "search", "type": "string" }
570
- ]
571
- }
572
- }
573
- \`\`\`
574
430
 
575
- 2. Use \`set\` effects to update filter state:
431
+ ### 17. Event Listeners Structure
432
+ Event listeners go INSIDE traits, not at orbital level:
576
433
  \`\`\`json
577
- {
578
- "from": "Browsing", "to": "Browsing", "event": "FILTER",
579
- "effects": [["set", "@TaskQuery.status", "@payload.status"]]
580
- }
434
+ "traits": [{ "name": "TaskInteraction",
435
+ "listens": [{ "event": "USER_UPDATED", "handler": "REFRESH_LIST" }] }]
581
436
  \`\`\`
582
437
 
583
- 3. Reference query in patterns:
438
+ ### 18. Wrong Filtering Pattern (Use Query Singleton)
439
+ Use a singleton entity for filter state + \`query\` prop on entity-table:
584
440
  \`\`\`json
585
- ["render-ui", "main", {
586
- "type": "entity-table",
587
- "entity": "Task",
588
- "query": "@TaskQuery"
589
- }]
441
+ { "name": "TaskQuery", "entity": { "name": "TaskQuery", "singleton": true, "runtime": true,
442
+ "fields": [{ "name": "status", "type": "string" }, { "name": "search", "type": "string" }] } }
590
443
  \`\`\`
444
+ Reference: \`["render-ui", "main", { "type": "entity-table", "entity": "Task", "query": "@TaskQuery" }]\`
591
445
  `;
592
446
  }
593
447
  function getValidationHintsSection() {
@@ -706,6 +560,78 @@ function getDecompositionChecklist() {
706
560
  - [ ] emits/listens defined for cross-orbital events
707
561
  `;
708
562
  }
563
+ function getDecompositionCompact() {
564
+ return `## Orbital Decomposition Protocol
565
+
566
+ ### Step 0: Classify Domain
567
+ | Domain | Keywords | Key Traits |
568
+ |--------|----------|------------|
569
+ | business | manage, track, workflow | EntityManagement, SearchAndFilter |
570
+ | game | play, score, level | Physics2D, Health, GameState |
571
+ | form | wizard, onboarding | Wizard, FormSubmission |
572
+ | dashboard | metrics, KPI | EntityManagement |
573
+ | content | blog, CMS | none (page navigation) |
574
+
575
+ ### Step 1: Identify Entities (ONE Orbital Per Entity)
576
+ - What are the core data objects?
577
+ - persistent (DB), runtime (memory), or singleton (config)?
578
+ - **CRITICAL: Create exactly ONE orbital per entity**
579
+
580
+ ### Step 2: Select Interaction Model
581
+ | Domain | Create | View | Edit | Delete |
582
+ |--------|--------|------|------|--------|
583
+ | business | modal | drawer | modal | confirm |
584
+ | game | none | none | none | none |
585
+ | form | wizard | drawer | page | confirm |
586
+
587
+ ### Step 3: Choose Traits
588
+ - Business: EntityManagement (handles CRUD via render-ui)
589
+ - Game: Physics2D, Health, Score, Collision
590
+ - Form: Wizard (multi-step) or FormSubmission (single)
591
+
592
+ ### Step 4: Define State Machine
593
+ \`\`\`
594
+ states: Identify user-facing modes (browsing, creating, editing, viewing)
595
+ events: Identify user actions (INIT, CREATE, VIEW, EDIT, SAVE, CLOSE)
596
+ transitions: Map (from, event) \u2192 (to, effects)
597
+ \`\`\`
598
+
599
+ ### Step 5: Add INIT Transition (CRITICAL)
600
+ Every trait MUST have an INIT self-loop with render-ui effects. Without INIT, the page loads blank!
601
+
602
+ ### Step 6: Define Pages
603
+ - ONE page per entity (business) or workflow (form)
604
+ - Attach traits to pages via \`traits\` array
605
+ - Add \`"guard"\` (singular) S-expressions on SAVE transitions for business rules
606
+ `;
607
+ }
608
+ function getConnectivityCompact() {
609
+ return `## Orbital Connectivity
610
+
611
+ For multi-entity apps, connect orbitals:
612
+
613
+ \`\`\`json
614
+ {
615
+ "entity": {
616
+ "fields": [
617
+ { "name": "customerId", "type": "relation", "relation": { "entity": "Customer", "cardinality": "one" } }
618
+ ]
619
+ },
620
+ "emits": ["ORDER_COMPLETED"],
621
+ "listens": [{ "event": "MENU_ITEM_UNAVAILABLE", "triggers": "DISABLE_ITEM" }],
622
+ "design": {
623
+ "uxHints": {
624
+ "relatedLinks": [{ "relation": "customerId", "label": "View Customer", "targetView": "detail" }]
625
+ }
626
+ }
627
+ }
628
+ \`\`\`
629
+
630
+ - **relation fields**: Link entities (Order \u2192 Customer)
631
+ - **emits/listens**: Cross-orbital event communication
632
+ - **relatedLinks**: Navigation between related records
633
+ `;
634
+ }
709
635
  function getFlowPatternSection() {
710
636
  return `## Flow Pattern Selection
711
637
 
@@ -811,6 +737,151 @@ Orbitals communicate via events:
811
737
  - Add relatedLinks for navigation between related records
812
738
  `;
813
739
  }
740
+ function getRenderUIDesignGuide() {
741
+ return `## Render-UI Design Guide
742
+
743
+ ### Syntax
744
+ \`["render-ui", slot, { "type": pattern, ...props }]\`
745
+ Clear slot: \`["render-ui", "modal", null]\`
746
+
747
+ ### Slot Strategy
748
+ | Slot | Use For | Composable? |
749
+ |------|---------|-------------|
750
+ | \`main\` | Primary content | **YES** \u2014 stack multiple render-ui calls |
751
+ | \`modal\` | Forms (create/edit), confirmations | One at a time |
752
+ | \`drawer\` | Detail views, quick edits | One at a time |
753
+ | \`sidebar\` | Navigation, persistent filters | One at a time |
754
+ | \`overlay\` | Confirmations, alerts | One at a time |
755
+
756
+ ### Pattern Selection by Intent
757
+ | Intent | Patterns | Key Props |
758
+ |--------|----------|-----------|
759
+ | List/browse data | \`entity-table\`, \`entity-cards\`, \`entity-list\` | columns, itemActions, searchable |
760
+ | Show metrics/KPIs | \`stats\` | metrics: [{label, value, icon, trend}] |
761
+ | Filter/search | \`filter-group\`, \`search-input\` | filters (from entity enum fields) |
762
+ | Create/edit form | \`form-section\` | fields, submitEvent, cancelEvent |
763
+ | View details | \`entity-detail\`, \`detail-panel\` | fields/fieldNames, actions |
764
+ | Organize content | \`tabs\` | tabs: [{label, content}] |
765
+ | Dashboard layout | \`dashboard-grid\` | columns (number) |
766
+ | Charts | \`chart\` | chartType, data, xAxis, yAxis |
767
+ | Progress | \`progress-bar\`, \`meter\` | value, max, label |
768
+ | Timeline | \`timeline\` | items: [{date, title, description}] |
769
+ | Page heading | \`page-header\` | title, subtitle, actions |
770
+ | Confirmation | \`confirmation\` | title, message, onConfirm, onCancel |
771
+ | Master/detail | \`master-detail\` | Split list + detail |
772
+ | Cards grid | \`entity-cards\` | columns, itemActions, layout |
773
+
774
+ ### Composition Recipes
775
+
776
+ **CRUD Browsing INIT** (most common \u2014 compose ALL of these in main slot):
777
+ \`\`\`json
778
+ ["render-ui", "main", { "type": "page-header", "title": "Tasks", "subtitle": "Manage your tasks", "actions": [{ "label": "New Task", "event": "CREATE", "variant": "primary" }] }],
779
+ ["render-ui", "main", { "type": "stats", "entity": "Task", "metrics": [{ "label": "Total", "value": "@count", "icon": "clipboard" }, { "label": "Active", "value": "@count:status=active", "icon": "clock" }, { "label": "Done", "value": "@count:status=done", "icon": "check-circle" }] }],
780
+ ["render-ui", "main", { "type": "entity-table", "entity": "Task", "columns": ["title", "status", "createdAt"], "searchable": true, "itemActions": [{ "label": "View", "event": "VIEW" }, { "label": "Edit", "event": "EDIT" }, { "label": "Delete", "event": "DELETE" }] }]
781
+ \`\`\`
782
+
783
+ **Dashboard INIT**:
784
+ \`\`\`
785
+ main: page-header \u2192 title + date range actions
786
+ main: dashboard-grid \u2192 columns: 3
787
+ main: stats \u2192 computed KPIs from entity counts
788
+ main: chart \u2192 primary data visualization
789
+ main: entity-cards \u2192 recent items (limit: 6)
790
+ \`\`\`
791
+
792
+ **Detail View (drawer)**:
793
+ \`\`\`
794
+ drawer: entity-detail \u2192 all fields + [Edit, Delete] actions
795
+ drawer: tabs \u2192 related collections (if entity has relation fields)
796
+ \`\`\`
797
+
798
+ **Wizard Flow**:
799
+ \`\`\`
800
+ main: wizard-progress \u2192 steps array + currentStep
801
+ main: wizard-container \u2192 current step content
802
+ main: wizard-navigation \u2192 Back/Next/Submit buttons
803
+ \`\`\`
804
+
805
+ ### Layout Composition (stack, box, grid)
806
+
807
+ Layout patterns wrap other patterns via \`children\` arrays for rich, structured views.
808
+
809
+ **VStack** (vertical stack): \`{ "type": "stack", "direction": "vertical", ... }\`
810
+ **HStack** (horizontal stack): \`{ "type": "stack", "direction": "horizontal", ... }\`
811
+ **Box** (styled container): \`{ "type": "box", ... }\`
812
+
813
+ #### Stack Props
814
+ | Prop | Values | Default |
815
+ |------|--------|---------|
816
+ | \`direction\` | \`"vertical"\`, \`"horizontal"\` | \`"vertical"\` |
817
+ | \`gap\` | \`"none"\`, \`"xs"\`, \`"sm"\`, \`"md"\`, \`"lg"\`, \`"xl"\` | \`"md"\` |
818
+ | \`align\` | \`"start"\`, \`"center"\`, \`"end"\`, \`"stretch"\` | \`"stretch"\` |
819
+ | \`justify\` | \`"start"\`, \`"center"\`, \`"end"\`, \`"between"\`, \`"around"\` | \`"start"\` |
820
+ | \`wrap\` | \`true\`, \`false\` | \`false\` |
821
+
822
+ #### Box Props
823
+ | Prop | Values |
824
+ |------|--------|
825
+ | \`padding\` / \`paddingX\` / \`paddingY\` | \`"none"\`, \`"xs"\`, \`"sm"\`, \`"md"\`, \`"lg"\`, \`"xl"\` |
826
+ | \`bg\` | \`"default"\`, \`"muted"\`, \`"card"\`, \`"primary"\`, \`"secondary"\`, \`"accent"\` |
827
+ | \`border\` | \`true\`, \`false\` |
828
+ | \`rounded\` | \`"none"\`, \`"sm"\`, \`"md"\`, \`"lg"\`, \`"full"\` |
829
+ | \`shadow\` | \`"none"\`, \`"sm"\`, \`"md"\`, \`"lg"\` |
830
+
831
+ #### Grid Props
832
+ | Prop | Values |
833
+ |------|--------|
834
+ | \`cols\` | \`1\`\u2013\`12\` or \`{ sm: 1, md: 2, lg: 3 }\` |
835
+ | \`gap\` | \`"none"\`, \`"xs"\`, \`"sm"\`, \`"md"\`, \`"lg"\`, \`"xl"\` |
836
+
837
+ #### Nesting Example \u2014 Page Header + Stats Row + Table
838
+ \`\`\`json
839
+ ["render-ui", "main", {
840
+ "type": "stack", "direction": "vertical", "gap": "lg",
841
+ "children": [
842
+ { "type": "stack", "direction": "horizontal", "justify": "between", "align": "center",
843
+ "children": [
844
+ { "type": "typography", "variant": "h1", "text": "Orders" },
845
+ { "type": "button", "label": "New Order", "event": "CREATE", "variant": "primary" }
846
+ ]
847
+ },
848
+ { "type": "stack", "direction": "horizontal", "gap": "md", "wrap": true,
849
+ "children": [
850
+ { "type": "box", "padding": "md", "bg": "card", "border": true, "rounded": "md",
851
+ "children": [{ "type": "stats", "metrics": [{ "label": "Total", "value": "@count" }] }]
852
+ },
853
+ { "type": "box", "padding": "md", "bg": "card", "border": true, "rounded": "md",
854
+ "children": [{ "type": "stats", "metrics": [{ "label": "Pending", "value": "@count:status=pending" }] }]
855
+ }
856
+ ]
857
+ },
858
+ { "type": "entity-table", "entity": "Order", "columns": ["customer", "total", "status"], "searchable": true }
859
+ ]
860
+ }]
861
+ \`\`\`
862
+
863
+ #### When to Use Layout Patterns
864
+ - **VStack**: Default page layout \u2014 stack header, content sections, tables vertically
865
+ - **HStack**: Side-by-side elements \u2014 stat cards, action buttons, header with controls
866
+ - **Box**: Visual grouping \u2014 cards, panels, highlighted sections with borders/backgrounds
867
+ - **Grid**: Equal-width columns \u2014 dashboard cards, stat grids, gallery layouts
868
+
869
+ > **Tip**: A single \`render-ui\` call with a top-level \`stack\` containing nested children produces a more cohesive layout than multiple flat \`render-ui\` calls to the same slot.
870
+
871
+ ### Domain-Aware Pattern Selection
872
+ | Domain | List Pattern | Extras |
873
+ |--------|-------------|--------|
874
+ | business/admin | \`entity-table\` (searchable) | \`stats\`, \`filter-group\` |
875
+ | e-commerce | \`entity-cards\` | \`stats\` (revenue), \`chart\` |
876
+ | content/CMS | \`entity-cards\` | \`tabs\`, \`media-gallery\` |
877
+ | dashboard | \`dashboard-grid\` | \`stats\`, \`chart\`, \`meter\`, \`timeline\` |
878
+ | workflow | \`entity-table\` | \`progress-bar\`, \`timeline\` |
879
+
880
+ ${getPatternPropsCompact()}
881
+
882
+ ${getPatternActionsRef()}
883
+ `;
884
+ }
814
885
 
815
886
  // src/prompts/skill-sections/custom-traits.ts
816
887
  function getCustomTraitSection() {
@@ -1896,13 +1967,16 @@ function generateLeanOrbitalSkill(options = {}) {
1896
1967
  const {
1897
1968
  includeExample = true,
1898
1969
  includeToolWorkflow = true,
1899
- includeStdLibrary = true,
1970
+ includeStdLibrary = false,
1900
1971
  stdLibraryFull = false,
1901
- includeStdStateMachines = true,
1902
- includeSchemaUpdates = true
1972
+ includeStdStateMachines = false,
1973
+ includeSchemaUpdates = false,
1974
+ includeCustomTraits = false,
1975
+ errorLevel = "top6",
1976
+ includeDesignGuide = true
1903
1977
  } = options;
1904
1978
  let stdSection = "";
1905
- if (includeStdLibrary) {
1979
+ if (includeStdLibrary || includeStdStateMachines) {
1906
1980
  if (includeStdStateMachines) {
1907
1981
  stdSection = `---
1908
1982
 
@@ -1924,6 +1998,8 @@ ${getStdMinimalReference()}
1924
1998
  `;
1925
1999
  }
1926
2000
  }
2001
+ const decompositionSection = includeStdStateMachines || includeCustomTraits ? getDecompositionSection() : getDecompositionCompact();
2002
+ const connectivitySection = includeStdStateMachines || includeCustomTraits ? getOrbitalConnectivitySection() : getConnectivityCompact();
1927
2003
  return `# Orbital Generation Skill
1928
2004
 
1929
2005
  > Generate Orbital applications using Orbital Units: Entity \xD7 Traits \xD7 Patterns
@@ -1932,15 +2008,11 @@ ${getArchitectureSection()}
1932
2008
 
1933
2009
  ---
1934
2010
 
1935
- ${getMinimalTypeReference()}
1936
-
1937
- ---
1938
-
1939
2011
  ${getSExprQuickRef()}
1940
2012
 
1941
2013
  ---
1942
2014
 
1943
- ${getRenderUIQuickRef()}
2015
+ ${includeDesignGuide ? getRenderUIDesignGuide() : ""}
1944
2016
 
1945
2017
  ${stdSection}
1946
2018
  ---
@@ -1949,7 +2021,7 @@ ${getFlowPatternSection()}
1949
2021
 
1950
2022
  ---
1951
2023
 
1952
- ${getDecompositionSection()}
2024
+ ${decompositionSection}
1953
2025
 
1954
2026
  ---
1955
2027
 
@@ -1957,7 +2029,7 @@ ${getPortableOrbitalOutputSection()}
1957
2029
 
1958
2030
  ---
1959
2031
 
1960
- ${getOrbitalConnectivitySection()}
2032
+ ${connectivitySection}
1961
2033
 
1962
2034
  ---
1963
2035
 
@@ -1965,12 +2037,12 @@ ${getContextUsageCompact()}
1965
2037
 
1966
2038
  ---
1967
2039
 
1968
- ${getCommonErrorsSection()}
2040
+ ${getCommonErrorsSection(errorLevel)}
1969
2041
 
1970
- ---
2042
+ ${includeCustomTraits ? `---
1971
2043
 
1972
2044
  ${getCustomTraitSection()}
1973
-
2045
+ ` : ""}
1974
2046
  ${includeToolWorkflow ? getToolWorkflowSection() : ""}
1975
2047
 
1976
2048
  ${includeSchemaUpdates ? `---
@@ -2031,17 +2103,67 @@ function getToolWorkflowSection() {
2031
2103
 
2032
2104
  ## Tool Workflow
2033
2105
 
2034
- 1. **DECOMPOSE**: Break requirements into OrbitalUnits
2035
- 2. **GENERATE**: Call \`generate_orbital\` for each orbital
2036
- 3. **COMBINE**: Call \`construct_combined_schema\` (FINAL STEP)
2106
+ ### Phase 1: DECOMPOSE
2107
+ Break requirements into OrbitalUnits (pure reasoning, no tools).
2108
+
2109
+ ### Phase 2: GENERATE
2110
+ Call \`generate_orbital\` for each orbital:
2037
2111
 
2038
2112
  \`\`\`
2039
2113
  generate_orbital({ orbital: {...}, orbitalIndex: 0, totalOrbitals: N })
2040
2114
  generate_orbital({ orbital: {...}, orbitalIndex: 1, totalOrbitals: N })
2041
2115
  ...
2042
- construct_combined_schema({ name: "App", description: "..." })
2043
- # STOP HERE - job is done
2044
2116
  \`\`\`
2117
+
2118
+ Each orbital is written to \`.orbitals/<name>.json\` with ALL effects (render-ui, persist, emit, set, etc.).
2119
+
2120
+ ### Phase 3: COMBINE
2121
+ Call \`finish_task\` to auto-combine and validate:
2122
+
2123
+ \`\`\`
2124
+ finish_task({ appName: "App" })
2125
+ # Reads .orbitals/*.json \u2192 schema.json \u2192 orbital validate
2126
+ \`\`\`
2127
+
2128
+ ### Phase 4: DESIGN REFINEMENT (optional but recommended)
2129
+
2130
+ After \`finish_task\` produces \`schema.json\`, enhance key transitions with \`design_transition\`.
2131
+
2132
+ **When to use**: INIT transitions (they benefit most from rich composition \u2014 header + stats + content), and CREATE/VIEW transitions for polished forms and detail views.
2133
+
2134
+ **Step-by-step:**
2135
+
2136
+ 1. Call \`design_transition\` for the transition:
2137
+ \`\`\`json
2138
+ {
2139
+ "from": "Browsing", "to": "Browsing", "event": "INIT",
2140
+ "slot": "main", "entityName": "Task",
2141
+ "entityFields": [{"name": "title", "type": "string"}, {"name": "status", "type": "enum", "values": ["pending", "active", "done"]}],
2142
+ "domainCategory": "business"
2143
+ }
2144
+ \`\`\`
2145
+ Returns: \`{ "success": true, "effects": [["render-ui", "main", {...}], ...] }\`
2146
+
2147
+ 2. Extract the orbital chunk:
2148
+ \`\`\`json
2149
+ { "file": "schema.json", "type": "orbital", "name": "Task Management" }
2150
+ \`\`\`
2151
+
2152
+ 3. Edit the chunk file: replace render-ui effects in the target transition with the designed effects. **Keep all non-render-ui effects** (persist, emit, set) \u2014 only replace the render-ui tuples.
2153
+
2154
+ 4. Apply the chunk back:
2155
+ \`\`\`json
2156
+ { "chunkId": "<id from extract_chunk>" }
2157
+ \`\`\`
2158
+
2159
+ **Splicing rule**: For a transition with mixed effects like:
2160
+ \`\`\`json
2161
+ [["persist", "create", "Task", "@payload.data"], ["render-ui", "modal", null], ["emit", "INIT"]]
2162
+ \`\`\`
2163
+ Keep \`persist\` and \`emit\`, replace \`render-ui\` with the designed effects.
2164
+ For INIT transitions (render-ui only), replace all effects.
2165
+
2166
+ **Skip design_transition for**: SAVE, CANCEL, CONFIRM_DELETE transitions (they have persist/emit effects with simple slot-clearing \u2014 no UI to design).
2045
2167
  `;
2046
2168
  }
2047
2169
  function getMinimalExample() {
@@ -2079,8 +2201,9 @@ function getMinimalExample() {
2079
2201
  {
2080
2202
  "from": "Browsing", "to": "Browsing", "event": "INIT",
2081
2203
  "effects": [
2082
- ["render-ui", "main", { "type": "page-header", "title": "Tasks", "actions": [{ "label": "New Task", "event": "CREATE", "variant": "primary" }] }],
2083
- ["render-ui", "main", { "type": "entity-table", "entity": "Task", "columns": ["title", "status"], "itemActions": [{ "label": "View", "event": "VIEW" }, { "label": "Edit", "event": "EDIT" }, { "label": "Delete", "event": "DELETE" }] }]
2204
+ ["render-ui", "main", { "type": "page-header", "title": "Tasks", "subtitle": "Manage your tasks", "actions": [{ "label": "New Task", "event": "CREATE", "variant": "primary" }] }],
2205
+ ["render-ui", "main", { "type": "stats", "entity": "Task", "metrics": [{ "label": "Total", "value": "@count", "icon": "clipboard" }, { "label": "Active", "value": "@count:status=active", "icon": "clock" }, { "label": "Done", "value": "@count:status=done", "icon": "check-circle" }] }],
2206
+ ["render-ui", "main", { "type": "entity-table", "entity": "Task", "columns": ["title", "status"], "searchable": true, "itemActions": [{ "label": "View", "event": "VIEW" }, { "label": "Edit", "event": "EDIT" }, { "label": "Delete", "event": "DELETE" }] }]
2084
2207
  ]
2085
2208
  },
2086
2209
  {
@@ -2137,14 +2260,15 @@ function getMinimalExample() {
2137
2260
 
2138
2261
  **Key points**:
2139
2262
  - ONE page (TasksPage) not four (list/create/edit/view)
2140
- - INIT transition renders initial UI (page-header + entity-table)
2263
+ - INIT transition composes **multiple patterns**: page-header + stats + entity-table
2141
2264
  - States are OBJECTS with \`isInitial\` flag
2142
2265
  - **Actions are INSIDE patterns (use unified props)**:
2143
2266
  - \`page-header\` has \`actions: [{label, event, variant}]\`
2144
- - \`entity-table\` has \`itemActions: [{label, event}]\`
2267
+ - \`entity-table\` has \`itemActions: [{label, event}]\` and \`searchable: true\`
2145
2268
  - \`form-section\` has \`submitEvent\` and \`cancelEvent\` (NOT onSubmit/onCancel!)
2146
2269
  - \`entity-detail\` has \`actions\` (NOT headerActions!)
2147
2270
  - \`confirmation\` emits action events
2271
+ - \`stats\` has \`metrics: [{label, value, icon}]\`
2148
2272
  - **NEVER use**: \`onSubmit\`, \`onCancel\`, \`headerActions\`, \`loading\` (use \`isLoading\`)
2149
2273
  - NO separate "form-actions" pattern - it doesn't exist!
2150
2274
  `;
@@ -2155,15 +2279,18 @@ function generateKflowOrbitalsSkill(compact = false) {
2155
2279
  const frontmatter = {
2156
2280
  name: "kflow-orbitals",
2157
2281
  description: "Generate KFlow schemas using the Orbitals composition model. Decomposes applications into atomic Orbital Units (Entity x Traits x Patterns) with structural caching for efficiency.",
2158
- allowedTools: ["Read", "Write", "Edit"],
2159
- version: "3.1.0"
2160
- // Bumped version for compact option
2282
+ allowedTools: ["Read", "Write", "Edit", "generate_orbital", "design_transition", "finish_task", "query_schema_structure", "extract_chunk", "apply_chunk"],
2283
+ version: "4.1.0"
2284
+ // v4.1: design refinement workflow with design_transition
2161
2285
  };
2162
2286
  const content = generateLeanOrbitalSkill({
2163
2287
  includeExample: true,
2164
2288
  includeToolWorkflow: true,
2165
- includeStdStateMachines: !compact
2166
- // Full std/* examples (21K chars)
2289
+ includeStdStateMachines: false,
2290
+ includeSchemaUpdates: false,
2291
+ includeCustomTraits: false,
2292
+ errorLevel: "top6",
2293
+ includeDesignGuide: true
2167
2294
  });
2168
2295
  return {
2169
2296
  name: "kflow-orbitals",
@@ -2208,10 +2335,6 @@ ${getArchitectureSection()}
2208
2335
 
2209
2336
  ---
2210
2337
 
2211
- ${getMinimalTypeReference()}
2212
-
2213
- ---
2214
-
2215
2338
  ${getSExprQuickRef()}
2216
2339
 
2217
2340
  ---
@@ -2232,7 +2355,11 @@ ${getOverGenerationSection()}` : ""}
2232
2355
 
2233
2356
  ---
2234
2357
 
2235
- ${getCommonErrorsSection()}
2358
+ ${getCommonErrorsSection("full")}
2359
+
2360
+ ---
2361
+
2362
+ ${getCustomTraitSection()}
2236
2363
 
2237
2364
  ${includeSchemaUpdates ? `---
2238
2365
 
@@ -2483,11 +2610,358 @@ Output the complete updated domain language text.
2483
2610
  content
2484
2611
  };
2485
2612
  }
2613
+ function getMinimalTypeReference() {
2614
+ return `
2615
+ ## Orbital Schema Structure
2616
+
2617
+ \`\`\`typescript
2618
+ interface OrbitalDefinition {
2619
+ name: string; // Entity name (PascalCase)
2620
+ entity: Entity; // Data model
2621
+ traits: TraitRef[]; // State machines (names or definitions)
2622
+ pages: Page[]; // Routes and views
2623
+ emits?: string[]; // Events this orbital emits
2624
+ listens?: EventListener[]; // Events this orbital listens to
2625
+ }
2626
+ \`\`\`
2627
+
2628
+ ### Entity Fields
2629
+
2630
+ \`\`\`typescript
2631
+ { name: "title", type: "string", required: true }
2632
+ { name: "count", type: "number", default: 0 }
2633
+ { name: "status", type: "enum", values: ["pending", "active", "done"] }
2634
+ { name: "dueDate", type: "date" }
2635
+ \`\`\`
2636
+
2637
+ ### Trait State Machine
2638
+
2639
+ \`\`\`typescript
2640
+ {
2641
+ states: [{ name: "Idle", isInitial: true }, { name: "Active" }],
2642
+ events: ["INIT", "ACTIVATE", "COMPLETE"],
2643
+ transitions: [
2644
+ { from: "Idle", to: "Active", event: "ACTIVATE",
2645
+ guards: [["condition"]],
2646
+ effects: [["action"]] }
2647
+ ]
2648
+ }
2649
+ \`\`\`
2650
+ `.trim();
2651
+ }
2652
+ function getPatternTypesCompact() {
2653
+ const patterns = getAllPatternTypes();
2654
+ return `
2655
+ ## Available Pattern Types
2656
+
2657
+ ${patterns.map((p) => `- \`${p}\``).join("\n")}
2658
+
2659
+ ${getPatternPropsCompact()}
2660
+ `.trim();
2661
+ }
2662
+ function getSExprQuickRef2() {
2663
+ const operators = Object.keys(OPERATORS).slice(0, 15);
2664
+ return `
2665
+ ## S-Expression Quick Reference
2666
+
2667
+ ### Guard Expressions (Conditions)
2668
+
2669
+ \`\`\`typescript
2670
+ ["=", "@entity.status", "active"] // Equality
2671
+ [">", "@entity.count", 0] // Greater than
2672
+ ["and", ["cond1"], ["cond2"]] // Logical AND
2673
+ ["or", ["cond1"], ["cond2"]] // Logical OR
2674
+ ["not", ["condition"]] // Logical NOT
2675
+ \`\`\`
2676
+
2677
+ ### Effect Expressions (Actions)
2678
+
2679
+ \`\`\`typescript
2680
+ ["set", "@entity.field", value] // Update field
2681
+ ["emit", "EVENT_NAME", payload] // Emit event
2682
+ ["navigate", "/path"] // Navigate to route
2683
+ ["render-ui", "main", { type, props }] // Render pattern
2684
+ ["persist", "create", "Entity", data] // Database operation
2685
+ \`\`\`
2686
+
2687
+ ### Available Operators
2688
+
2689
+ ${operators.map((op) => `- \`${op}\``).join("\n")}
2690
+ `.trim();
2691
+ }
2692
+ function getRenderUIQuickRef2() {
2693
+ const slots = UI_SLOTS;
2694
+ return `
2695
+ ## Render-UI Effect Reference
2696
+
2697
+ ### Syntax
2698
+
2699
+ \`\`\`typescript
2700
+ ["render-ui", slot, patternConfig | null]
2701
+ \`\`\`
2702
+
2703
+ ### UI Slots
2704
+
2705
+ ${slots.map((slot) => `- \`${slot}\``).join("\n")}
2706
+
2707
+ ### Example
2708
+
2709
+ \`\`\`typescript
2710
+ ["render-ui", "main", {
2711
+ type: "entity-table",
2712
+ entity: "Task",
2713
+ columns: ["title", "status"],
2714
+ itemActions: [{ label: "Edit", event: "EDIT" }]
2715
+ }]
2716
+ \`\`\`
2717
+
2718
+ Clear slot: \`["render-ui", "modal", null]\`
2719
+ `.trim();
2720
+ }
2721
+ function getFieldTypesCompact() {
2722
+ return `
2723
+ ## Field Types
2724
+
2725
+ | Type | Example | Notes |
2726
+ |------|---------|-------|
2727
+ | \`string\` | \`{ name: "title", type: "string" }\` | Text |
2728
+ | \`number\` | \`{ name: "count", type: "number" }\` | Integer or float |
2729
+ | \`boolean\` | \`{ name: "active", type: "boolean" }\` | true/false |
2730
+ | \`date\` | \`{ name: "birthday", type: "date" }\` | Date only |
2731
+ | \`timestamp\` | \`{ name: "createdAt", type: "timestamp" }\` | Date + time |
2732
+ | \`enum\` | \`{ name: "status", type: "enum", values: ["a", "b"] }\` | Fixed options |
2733
+ | \`array\` | \`{ name: "tags", type: "array", items: "string" }\` | List |
2734
+ | \`relation\` | \`{ name: "user", type: "relation", relation: { entity: "User", cardinality: "one" } }\` | Foreign key |
2735
+
2736
+ ### Field Properties
2737
+
2738
+ - \`required: true\` - Must have value
2739
+ - \`default: value\` - Default value
2740
+ - \`unique: true\` - Must be unique
2741
+ `.trim();
2742
+ }
2743
+
2744
+ // src/generators/kflow-design.ts
2745
+ function getTransitionContextGuide() {
2746
+ return `## Transition Context
2747
+
2748
+ You receive a single transition to design. Use these inputs to make UI decisions:
2749
+
2750
+ ### Input Fields
2751
+ | Field | What It Tells You |
2752
+ |-------|-------------------|
2753
+ | \`from\` | Current state (e.g., "Browsing", "Creating") |
2754
+ | \`to\` | Target state (e.g., "Browsing", "Viewing") |
2755
+ | \`event\` | What the user did (e.g., "INIT", "CREATE", "VIEW") |
2756
+ | \`currentSlot\` | Which slot to render into (\`main\`, \`modal\`, \`drawer\`) |
2757
+ | \`entity\` | Entity name + fields (drives column/field selection) |
2758
+ | \`designHints\` | Style + UX hints from decomposition |
2759
+ | \`domainContext\` | Category + vocabulary (drives pattern choice) |
2760
+ | \`existingEffects\` | Current render-ui effects (if enhancing) |
2761
+
2762
+ ### Decision Flow
2763
+
2764
+ \`\`\`
2765
+ 1. What EVENT is this?
2766
+ \u251C\u2500 INIT \u2192 Compose full page layout (header + content + data)
2767
+ \u251C\u2500 CREATE/EDIT \u2192 Form in modal or drawer
2768
+ \u251C\u2500 VIEW \u2192 Detail in drawer or inline
2769
+ \u251C\u2500 DELETE \u2192 Confirmation in overlay
2770
+ \u2514\u2500 SAVE/CANCEL \u2192 Clear slot (return null)
2771
+
2772
+ 2. What SLOT?
2773
+ \u251C\u2500 main \u2192 Compose multiple patterns (stack them)
2774
+ \u251C\u2500 modal \u2192 Single form or confirmation
2775
+ \u251C\u2500 drawer \u2192 Detail view or quick edit form
2776
+ \u2514\u2500 overlay \u2192 Confirmation dialog
2777
+
2778
+ 3. What DOMAIN?
2779
+ \u251C\u2500 business \u2192 entity-table + stats + filter-group
2780
+ \u251C\u2500 dashboard \u2192 dashboard-grid + chart + stats
2781
+ \u251C\u2500 e-commerce \u2192 entity-cards + stats (revenue)
2782
+ \u251C\u2500 content \u2192 entity-cards + tabs + media
2783
+ \u2514\u2500 workflow \u2192 timeline + progress-bar
2784
+
2785
+ 4. What ENTITY FIELDS suggest?
2786
+ \u251C\u2500 enum fields \u2192 filter-group, badge columns
2787
+ \u251C\u2500 date fields \u2192 timeline, date columns
2788
+ \u251C\u2500 number fields \u2192 stats, chart, meter
2789
+ \u251C\u2500 relation fields \u2192 tabs for related collections
2790
+ \u2514\u2500 image/url fields \u2192 entity-cards (visual)
2791
+ \`\`\``;
2792
+ }
2793
+ function getLayoutCompositionGuide() {
2794
+ return `## Layout Composition
2795
+
2796
+ Use layout patterns to create structured, visually rich views.
2797
+
2798
+ ### Stack (VStack / HStack)
2799
+ \`{ "type": "stack", "direction": "vertical"|"horizontal", "gap": "sm"|"md"|"lg", "children": [...] }\`
2800
+
2801
+ ### Box (Styled Container)
2802
+ \`{ "type": "box", "padding": "md", "bg": "card", "border": true, "rounded": "md", "children": [...] }\`
2803
+
2804
+ ### Grid (Multi-Column)
2805
+ \`{ "type": "grid", "cols": 3, "gap": "md", "children": [...] }\`
2806
+
2807
+ ### Composition Patterns
2808
+
2809
+ **Page Layout** \u2014 VStack wrapping all content:
2810
+ \`\`\`json
2811
+ ["render-ui", "main", {
2812
+ "type": "stack", "direction": "vertical", "gap": "lg",
2813
+ "children": [
2814
+ { "type": "page-header", "title": "...", "actions": [...] },
2815
+ { "type": "stack", "direction": "horizontal", "gap": "md", "wrap": true,
2816
+ "children": [
2817
+ { "type": "box", "padding": "md", "bg": "card", "border": true, "rounded": "md",
2818
+ "children": [{ "type": "stats", "metrics": [...] }] },
2819
+ { "type": "box", "padding": "md", "bg": "card", "border": true, "rounded": "md",
2820
+ "children": [{ "type": "stats", "metrics": [...] }] }
2821
+ ]
2822
+ },
2823
+ { "type": "entity-table", "entity": "...", "columns": [...], "searchable": true }
2824
+ ]
2825
+ }]
2826
+ \`\`\`
2827
+
2828
+ **Dashboard Layout** \u2014 Grid of cards:
2829
+ \`\`\`json
2830
+ ["render-ui", "main", {
2831
+ "type": "stack", "direction": "vertical", "gap": "lg",
2832
+ "children": [
2833
+ { "type": "page-header", "title": "Dashboard" },
2834
+ { "type": "grid", "cols": { "sm": 1, "md": 2, "lg": 3 }, "gap": "md",
2835
+ "children": [
2836
+ { "type": "box", "padding": "lg", "bg": "card", "border": true, "rounded": "md",
2837
+ "children": [{ "type": "stats", "metrics": [...] }] },
2838
+ { "type": "box", "padding": "lg", "bg": "card", "border": true, "rounded": "md",
2839
+ "children": [{ "type": "chart", "chartType": "line", "data": [...] }] },
2840
+ { "type": "box", "padding": "lg", "bg": "card", "border": true, "rounded": "md",
2841
+ "children": [{ "type": "entity-cards", "entity": "...", "columns": 1 }] }
2842
+ ]
2843
+ }
2844
+ ]
2845
+ }]
2846
+ \`\`\`
2847
+
2848
+ **Detail Drawer** \u2014 Stacked sections:
2849
+ \`\`\`json
2850
+ ["render-ui", "drawer", {
2851
+ "type": "stack", "direction": "vertical", "gap": "md",
2852
+ "children": [
2853
+ { "type": "entity-detail", "entity": "...", "actions": [{ "label": "Edit", "event": "EDIT" }] },
2854
+ { "type": "tabs", "tabs": [
2855
+ { "label": "Related Items", "content": { "type": "entity-table", "entity": "..." } },
2856
+ { "label": "Activity", "content": { "type": "timeline", "items": [...] } }
2857
+ ]}
2858
+ ]
2859
+ }]
2860
+ \`\`\`
2861
+
2862
+ ### When to Use Layout vs Flat
2863
+ - **Flat** (multiple render-ui calls): Simple pages, 2-3 patterns stacked vertically
2864
+ - **Nested** (single render-ui with layout): Complex pages, side-by-side elements, cards with backgrounds, dashboard grids`;
2865
+ }
2866
+ function getOutputFormatSection() {
2867
+ return `## Output Format
2868
+
2869
+ Return ONLY a JSON array of render-ui effect tuples. No explanation, no markdown.
2870
+
2871
+ ### Simple (multiple flat effects):
2872
+ \`\`\`json
2873
+ [
2874
+ ["render-ui", "main", { "type": "page-header", "title": "...", "actions": [...] }],
2875
+ ["render-ui", "main", { "type": "stats", "entity": "...", "metrics": [...] }],
2876
+ ["render-ui", "main", { "type": "entity-table", "entity": "...", "columns": [...] }]
2877
+ ]
2878
+ \`\`\`
2879
+
2880
+ ### Composed (single effect with layout nesting):
2881
+ \`\`\`json
2882
+ [
2883
+ ["render-ui", "main", { "type": "stack", "direction": "vertical", "gap": "lg", "children": [...] }]
2884
+ ]
2885
+ \`\`\`
2886
+
2887
+ ### Clear slot:
2888
+ \`\`\`json
2889
+ [
2890
+ ["render-ui", "modal", null]
2891
+ ]
2892
+ \`\`\`
2893
+
2894
+ ### Rules
2895
+ 1. Return valid JSON array \u2014 nothing else
2896
+ 2. Every effect must be \`["render-ui", slot, config]\`
2897
+ 3. Use entity fields from the input for columns, form fields, stats
2898
+ 4. Match domain vocabulary for labels (e.g., "Place Order" not "Create")
2899
+ 5. Include \`itemActions\` on tables/cards with appropriate events
2900
+ 6. Use \`searchable: true\` on tables for business domains
2901
+ 7. For INIT transitions, ALWAYS compose multiple patterns (never just a table)
2902
+ 8. For CREATE/EDIT, always include \`submitEvent\` and \`cancelEvent\` on form-section`;
2903
+ }
2904
+ function generateKflowDesignSkill() {
2905
+ const frontmatter = {
2906
+ name: "kflow-design",
2907
+ description: "Design rich render-ui effects for orbital schema transitions. Focused on pattern selection, layout composition, and domain-aware UI authoring.",
2908
+ allowedTools: ["Read", "Write", "Edit"],
2909
+ version: "1.0.0"
2910
+ };
2911
+ const content = `# Render-UI Design Skill
2912
+
2913
+ > Design rich, polished render-ui effects for orbital schema transitions.
2914
+
2915
+ You are a UI design specialist for KFlow orbital schemas. Your job is to take a
2916
+ transition context (state, event, entity, domain) and produce the best possible
2917
+ render-ui effects using the full pattern catalog.
2918
+
2919
+ **Your goal**: Every transition should produce UI that is visually rich, functionally
2920
+ complete, and domain-appropriate. Never default to just "entity-table" \u2014 compose
2921
+ layouts with headers, stats, filters, and appropriate patterns.
2922
+
2923
+ ---
2924
+
2925
+ ${getTransitionContextGuide()}
2926
+
2927
+ ---
2928
+
2929
+ ${getRenderUIDesignGuide()}
2930
+
2931
+ ---
2932
+
2933
+ ${getLayoutCompositionGuide()}
2934
+
2935
+ ---
2936
+
2937
+ ${getSExprQuickRef2()}
2938
+
2939
+ ---
2940
+
2941
+ ${getCommonErrorsSection("top6")}
2942
+
2943
+ ---
2944
+
2945
+ ${getOutputFormatSection()}
2946
+ `;
2947
+ return {
2948
+ name: "kflow-design",
2949
+ frontmatter,
2950
+ content
2951
+ };
2952
+ }
2953
+ function getDesignSkillStats() {
2954
+ const skill = generateKflowDesignSkill();
2955
+ return {
2956
+ lines: skill.content.split("\n").length,
2957
+ chars: skill.content.length
2958
+ };
2959
+ }
2960
+
2961
+ // src/orbitals-skills-generators/lean/lean-orbital-generator.ts
2962
+ var LEAN_CORE_INSTRUCTIONS = `
2963
+ ## Core Instructions
2486
2964
 
2487
- // src/orbitals-skills-generators/lean/lean-orbital-generator.ts
2488
- var LEAN_CORE_INSTRUCTIONS = `
2489
- ## Core Instructions
2490
-
2491
2965
  Generate orbital schemas using **Domain Language** - a natural, readable format.
2492
2966
 
2493
2967
  **Output Format**: Domain Language text (NOT JSON)
@@ -3079,139 +3553,10 @@ function generateAllBuilderSkills() {
3079
3553
  },
3080
3554
  content: generateLeanFixingSkill2()
3081
3555
  },
3082
- generateDomainLanguageSkill()
3556
+ generateDomainLanguageSkill(),
3557
+ generateKflowDesignSkill()
3083
3558
  ];
3084
3559
  }
3085
- function getMinimalTypeReference2() {
3086
- return `
3087
- ## Orbital Schema Structure
3088
-
3089
- \`\`\`typescript
3090
- interface OrbitalDefinition {
3091
- name: string; // Entity name (PascalCase)
3092
- entity: Entity; // Data model
3093
- traits: TraitRef[]; // State machines (names or definitions)
3094
- pages: Page[]; // Routes and views
3095
- emits?: string[]; // Events this orbital emits
3096
- listens?: EventListener[]; // Events this orbital listens to
3097
- }
3098
- \`\`\`
3099
-
3100
- ### Entity Fields
3101
-
3102
- \`\`\`typescript
3103
- { name: "title", type: "string", required: true }
3104
- { name: "count", type: "number", default: 0 }
3105
- { name: "status", type: "enum", values: ["pending", "active", "done"] }
3106
- { name: "dueDate", type: "date" }
3107
- \`\`\`
3108
-
3109
- ### Trait State Machine
3110
-
3111
- \`\`\`typescript
3112
- {
3113
- states: [{ name: "Idle", isInitial: true }, { name: "Active" }],
3114
- events: ["INIT", "ACTIVATE", "COMPLETE"],
3115
- transitions: [
3116
- { from: "Idle", to: "Active", event: "ACTIVATE",
3117
- guards: [["condition"]],
3118
- effects: [["action"]] }
3119
- ]
3120
- }
3121
- \`\`\`
3122
- `.trim();
3123
- }
3124
- function getPatternTypesCompact() {
3125
- const patterns = getAllPatternTypes();
3126
- return `
3127
- ## Available Pattern Types
3128
-
3129
- ${patterns.map((p) => `- \`${p}\``).join("\n")}
3130
-
3131
- ${getPatternPropsCompact()}
3132
- `.trim();
3133
- }
3134
- function getSExprQuickRef2() {
3135
- const operators = Object.keys(OPERATORS).slice(0, 15);
3136
- return `
3137
- ## S-Expression Quick Reference
3138
-
3139
- ### Guard Expressions (Conditions)
3140
-
3141
- \`\`\`typescript
3142
- ["=", "@entity.status", "active"] // Equality
3143
- [">", "@entity.count", 0] // Greater than
3144
- ["and", ["cond1"], ["cond2"]] // Logical AND
3145
- ["or", ["cond1"], ["cond2"]] // Logical OR
3146
- ["not", ["condition"]] // Logical NOT
3147
- \`\`\`
3148
-
3149
- ### Effect Expressions (Actions)
3150
-
3151
- \`\`\`typescript
3152
- ["set", "@entity.field", value] // Update field
3153
- ["emit", "EVENT_NAME", payload] // Emit event
3154
- ["navigate", "/path"] // Navigate to route
3155
- ["render-ui", "main", { type, props }] // Render pattern
3156
- ["persist", "create", "Entity", data] // Database operation
3157
- \`\`\`
3158
-
3159
- ### Available Operators
3160
-
3161
- ${operators.map((op) => `- \`${op}\``).join("\n")}
3162
- `.trim();
3163
- }
3164
- function getRenderUIQuickRef2() {
3165
- const slots = UI_SLOTS;
3166
- return `
3167
- ## Render-UI Effect Reference
3168
-
3169
- ### Syntax
3170
-
3171
- \`\`\`typescript
3172
- ["render-ui", slot, patternConfig | null]
3173
- \`\`\`
3174
-
3175
- ### UI Slots
3176
-
3177
- ${slots.map((slot) => `- \`${slot}\``).join("\n")}
3178
-
3179
- ### Example
3180
-
3181
- \`\`\`typescript
3182
- ["render-ui", "main", {
3183
- type: "entity-table",
3184
- entity: "Task",
3185
- columns: ["title", "status"],
3186
- itemActions: [{ label: "Edit", event: "EDIT" }]
3187
- }]
3188
- \`\`\`
3189
-
3190
- Clear slot: \`["render-ui", "modal", null]\`
3191
- `.trim();
3192
- }
3193
- function getFieldTypesCompact() {
3194
- return `
3195
- ## Field Types
3196
-
3197
- | Type | Example | Notes |
3198
- |------|---------|-------|
3199
- | \`string\` | \`{ name: "title", type: "string" }\` | Text |
3200
- | \`number\` | \`{ name: "count", type: "number" }\` | Integer or float |
3201
- | \`boolean\` | \`{ name: "active", type: "boolean" }\` | true/false |
3202
- | \`date\` | \`{ name: "birthday", type: "date" }\` | Date only |
3203
- | \`timestamp\` | \`{ name: "createdAt", type: "timestamp" }\` | Date + time |
3204
- | \`enum\` | \`{ name: "status", type: "enum", values: ["a", "b"] }\` | Fixed options |
3205
- | \`array\` | \`{ name: "tags", type: "array", items: "string" }\` | List |
3206
- | \`relation\` | \`{ name: "user", type: "relation", relation: { entity: "User", cardinality: "one" } }\` | Foreign key |
3207
-
3208
- ### Field Properties
3209
-
3210
- - \`required: true\` - Must have value
3211
- - \`default: value\` - Default value
3212
- - \`unique: true\` - Must be unique
3213
- `.trim();
3214
- }
3215
3560
 
3216
3561
  // src/prompts/generation-prompts.ts
3217
3562
  function getOrbitalDecompositionPrompt() {
@@ -3251,7 +3596,7 @@ ${getArchitectureSection()}
3251
3596
 
3252
3597
  ---
3253
3598
 
3254
- ${getMinimalTypeReference2()}
3599
+ ${getMinimalTypeReference()}
3255
3600
 
3256
3601
  ---
3257
3602
 
@@ -3385,6 +3730,6 @@ Use with: \`uses: [{ from: "std/behaviors/crud", as: "CRUD" }]\`
3385
3730
  `;
3386
3731
  }
3387
3732
 
3388
- export { formatFrontmatter, generateAllBuilderSkills, generateDomainLanguageSkill, generateKflowOrbitalFixingSkill, generateKflowOrbitalsSkill, generateLeanFixingSkill2 as generateLeanFixingSkill, generateLeanFixingSkill as generateLeanFixingSkillFull, generateLeanOrbitalSkill2 as generateLeanOrbitalSkill, generateLeanOrbitalSkill as generateLeanOrbitalSkillFull, getArchitectureSection, getAssetRefSection, getCommonErrorsSection, getCommonFixPatternsSection, getCompletionRulesSection, getContextUsageCompact, getContextUsageSection, getCustomTraitCompact, getCustomTraitSection, getDecompositionChecklist, getDecompositionSection, getDesignErrorsCompact, getDesignErrorsSection, getEfficiencySection, getFieldTypesCompact, getFixingWorkflowSection, getFlowPatternSection, getFullOrbitalPrompt, getGameAsOrbitalsSection, getGameEntityTemplatesSection, getGamePatternsSection, getGameTraitsSection, getGameTypesSection, getIconLibraryCompact, getIconLibrarySection, getKeyBehaviorsReference2 as getKeyBehaviorsReference, getMinimalTypeReference2 as getMinimalTypeReference, getMultiFileSection, getOrbitalConnectivitySection, getOrbitalDecompositionPrompt, getOverGenerationSection, getPatternTypesCompact, getPortableOrbitalOutputSection, getRenderUIQuickRef2 as getRenderUIQuickRef, getRequirementsDecomposePrompt, getRequirementsTraitPrompt, getSExprQuickRef2 as getSExprQuickRef, getSchemaUpdateCompact, getSchemaUpdateSection, getUsesImportCompact, getUsesImportSection, getValidationHintsSection, writeAllSkills, writeSkill };
3733
+ export { formatFrontmatter, generateAllBuilderSkills, generateDomainLanguageSkill, generateKflowDesignSkill, generateKflowOrbitalFixingSkill, generateKflowOrbitalsSkill, generateLeanFixingSkill2 as generateLeanFixingSkill, generateLeanFixingSkill as generateLeanFixingSkillFull, generateLeanOrbitalSkill2 as generateLeanOrbitalSkill, generateLeanOrbitalSkill as generateLeanOrbitalSkillFull, getArchitectureSection, getAssetRefSection, getCommonErrorsSection, getCommonFixPatternsSection, getCompletionRulesSection, getConnectivityCompact, getContextUsageCompact, getContextUsageSection, getCustomTraitCompact, getCustomTraitSection, getDecompositionChecklist, getDecompositionCompact, getDecompositionSection, getDesignErrorsCompact, getDesignErrorsSection, getDesignSkillStats, getEfficiencySection, getFieldTypesCompact, getFixingWorkflowSection, getFlowPatternSection, getFullOrbitalPrompt, getGameAsOrbitalsSection, getGameEntityTemplatesSection, getGamePatternsSection, getGameTraitsSection, getGameTypesSection, getIconLibraryCompact, getIconLibrarySection, getKeyBehaviorsReference2 as getKeyBehaviorsReference, getMinimalTypeReference, getMultiFileSection, getOrbitalConnectivitySection, getOrbitalDecompositionPrompt, getOverGenerationSection, getPatternTypesCompact, getPortableOrbitalOutputSection, getRenderUIDesignGuide, getRenderUIQuickRef2 as getRenderUIQuickRef, getRequirementsDecomposePrompt, getRequirementsTraitPrompt, getSExprQuickRef2 as getSExprQuickRef, getSchemaUpdateCompact, getSchemaUpdateSection, getUsesImportCompact, getUsesImportSection, getValidationHintsSection, writeAllSkills, writeSkill };
3389
3734
  //# sourceMappingURL=index.js.map
3390
3735
  //# sourceMappingURL=index.js.map