@almadar/skills 1.1.3 → 1.2.1
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.d.ts +129 -41
- package/dist/index.js +1212 -556
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ 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
5
|
import { getPatternPropsCompact, getPatternActionsRef, getAllPatternTypes } from '@almadar/patterns';
|
|
6
|
+
import { BINDING_DOCS, CORE_BINDINGS } from '@almadar/core';
|
|
6
7
|
|
|
7
8
|
// src/generators/utils.ts
|
|
8
9
|
function formatFrontmatter(fm) {
|
|
@@ -204,7 +205,7 @@ Trait State Machine \u2192 render-ui \u2192 UI Component \u2192 User Action \u21
|
|
|
204
205
|
| **One trait per slot** | Each slot (main, modal, drawer) owned by ONE trait |
|
|
205
206
|
| **INIT renders UI** | Every trait needs INIT self-loop to render initial UI |
|
|
206
207
|
| **One page per entity** | Use trait's render-ui for create/edit/view, not separate pages |
|
|
207
|
-
| **form-section has
|
|
208
|
+
| **form-section has submitEvent** | Connects form to trait events (NOT onSubmit!) |
|
|
208
209
|
| **std/* are templates** | Guide LLM generation, not runtime code |
|
|
209
210
|
|
|
210
211
|
### Slot Ownership
|
|
@@ -215,7 +216,7 @@ Trait State Machine \u2192 render-ui \u2192 UI Component \u2192 User Action \u21
|
|
|
215
216
|
\u2502 TaskManagement trait OWNS: \u2502
|
|
216
217
|
\u2502 \u2022 main \u2192 entity-table, page-header \u2502
|
|
217
218
|
\u2502 \u2022 modal \u2192 form-section (create/edit) \u2502
|
|
218
|
-
\u2502 \u2022 drawer \u2192
|
|
219
|
+
\u2502 \u2022 drawer \u2192 detail-panel (view) \u2502
|
|
219
220
|
\u2502 \u2502
|
|
220
221
|
\u2502 NO other trait should render to these slots \u2502
|
|
221
222
|
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
@@ -273,6 +274,7 @@ function getCriticalErrors() {
|
|
|
273
274
|
### 1. INIT Transition Required (CRITICAL)
|
|
274
275
|
|
|
275
276
|
Every trait MUST have an INIT self-loop transition. The runtime fires \`INIT\` when page loads.
|
|
277
|
+
The INIT render-ui MUST be a **single composed stack**, not flat calls:
|
|
276
278
|
|
|
277
279
|
\`\`\`json
|
|
278
280
|
{
|
|
@@ -280,8 +282,19 @@ Every trait MUST have an INIT self-loop transition. The runtime fires \`INIT\` w
|
|
|
280
282
|
"to": "Browsing",
|
|
281
283
|
"event": "INIT",
|
|
282
284
|
"effects": [
|
|
283
|
-
["render-ui", "main", {
|
|
284
|
-
|
|
285
|
+
["render-ui", "main", {
|
|
286
|
+
"type": "stack", "direction": "vertical", "gap": "lg",
|
|
287
|
+
"children": [
|
|
288
|
+
{ "type": "stack", "direction": "horizontal", "justify": "between", "align": "center",
|
|
289
|
+
"children": [
|
|
290
|
+
{ "type": "typography", "variant": "h1", "text": "Title" },
|
|
291
|
+
{ "type": "button", "label": "Create", "event": "CREATE", "variant": "primary" }
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
{ "type": "entity-table", "entity": "EntityName", "columns": ["..."], "searchable": true,
|
|
295
|
+
"itemActions": [{ "label": "View", "event": "VIEW" }] }
|
|
296
|
+
]
|
|
297
|
+
}]
|
|
285
298
|
]
|
|
286
299
|
}
|
|
287
300
|
\`\`\`
|
|
@@ -377,10 +390,11 @@ WRONG: Two traits both render to "main" on page load
|
|
|
377
390
|
CORRECT: ONE trait owns each slot
|
|
378
391
|
\`\`\`
|
|
379
392
|
|
|
380
|
-
### 9. Missing
|
|
393
|
+
### 9. Missing submitEvent in form-section
|
|
381
394
|
\`\`\`
|
|
382
395
|
WRONG: { "type": "form-section", "entity": "Task" }
|
|
383
|
-
|
|
396
|
+
ALSO WRONG: { "type": "form-section", "entity": "Task", "onSubmit": "SAVE" }
|
|
397
|
+
CORRECT: { "type": "form-section", "entity": "Task", "submitEvent": "SAVE", "cancelEvent": "CANCEL" }
|
|
384
398
|
\`\`\`
|
|
385
399
|
|
|
386
400
|
### 10. Duplicate Transitions (Same from+event)
|
|
@@ -404,7 +418,7 @@ CORRECT: { "pages": [{ "traits": [...] }] } - UI comes from render-ui effects
|
|
|
404
418
|
### 13. Using form-actions Pattern (DOES NOT EXIST!)
|
|
405
419
|
\`\`\`
|
|
406
420
|
WRONG: ["render-ui", "main", { "type": "form-actions", "actions": [...] }]
|
|
407
|
-
CORRECT: Use form-section with
|
|
421
|
+
CORRECT: Use form-section with submitEvent/cancelEvent props
|
|
408
422
|
\`\`\`
|
|
409
423
|
Actions are INSIDE patterns, not separate patterns.
|
|
410
424
|
|
|
@@ -453,7 +467,7 @@ function getValidationHintsSection() {
|
|
|
453
467
|
| ORB_P_MISSING_TRAITS | Add \`traits\` array to page with at least one trait ref |
|
|
454
468
|
| ORB_E_INVALID_FIELD_TYPE | Use valid type: string, number, boolean, date, enum, relation. NOT entity names! |
|
|
455
469
|
| ORB_INIT_MISSING | Add INIT self-loop transition with render-ui effects |
|
|
456
|
-
| ORB_FORM_SUBMIT | Add
|
|
470
|
+
| ORB_FORM_SUBMIT | Add submitEvent and cancelEvent to form-section pattern |
|
|
457
471
|
| ORB_DUPE_TRANS | Add guards to differentiate same-event transitions |
|
|
458
472
|
| ORB_SLOT_CONTENTION | Merge traits or use different slots |
|
|
459
473
|
| ORB_DUPE_PAGE_TRAITS | Remove duplicate trait references from page |
|
|
@@ -743,145 +757,461 @@ Orbitals communicate via events:
|
|
|
743
757
|
- Add relatedLinks for navigation between related records
|
|
744
758
|
`;
|
|
745
759
|
}
|
|
760
|
+
function getBindingsGuide() {
|
|
761
|
+
const lines = [
|
|
762
|
+
"## Valid Binding References",
|
|
763
|
+
"",
|
|
764
|
+
"Bindings reference runtime values using `@root.path` syntax:",
|
|
765
|
+
"",
|
|
766
|
+
"| Binding | Description | Example |",
|
|
767
|
+
"|---------|-------------|---------|"
|
|
768
|
+
];
|
|
769
|
+
for (const [bindingKey, docs] of Object.entries(BINDING_DOCS)) {
|
|
770
|
+
const example = docs.examples[0] || `@${bindingKey}`;
|
|
771
|
+
lines.push(`| \`@${bindingKey}\` | ${docs.description} | \`${example}\` |`);
|
|
772
|
+
}
|
|
773
|
+
lines.push(
|
|
774
|
+
"",
|
|
775
|
+
"### Binding Rules",
|
|
776
|
+
"",
|
|
777
|
+
"- `@entity.field` - Access entity fields (e.g., `@entity.status`, `@entity.count`)",
|
|
778
|
+
"- `@payload.field` - Access event payload data (read-only)",
|
|
779
|
+
"- `@state` - Current state name (no path)",
|
|
780
|
+
"- `@now` - Current timestamp (no path)",
|
|
781
|
+
"- `@config.field` - Trait configuration values",
|
|
782
|
+
"",
|
|
783
|
+
"### Common Mistakes",
|
|
784
|
+
"",
|
|
785
|
+
"| \u274C Invalid | \u2705 Correct |",
|
|
786
|
+
"|------------|------------|",
|
|
787
|
+
'| `@count` | Use `stats` pattern or static text (e.g., `"Total Tasks"`) |',
|
|
788
|
+
"| `@count:status=pending` | Use filtered entity-table or static labels |",
|
|
789
|
+
"| `@entity.task.title` | `@entity.title` (entity type is implicit) |",
|
|
790
|
+
"| `@payload.field` in `set` effect | `@entity.field` (set modifies entity only) |",
|
|
791
|
+
""
|
|
792
|
+
);
|
|
793
|
+
return lines.join("\n");
|
|
794
|
+
}
|
|
795
|
+
function getBindingsCompact() {
|
|
796
|
+
const validBindings = CORE_BINDINGS.map((b) => `@${b}`).join(", ");
|
|
797
|
+
return `Valid bindings: ${validBindings}`;
|
|
798
|
+
}
|
|
799
|
+
function getBindingContextRules() {
|
|
800
|
+
return `
|
|
801
|
+
## Binding Context Rules
|
|
802
|
+
|
|
803
|
+
| Context | Allowed Bindings | Notes |
|
|
804
|
+
|---------|-----------------|-------|
|
|
805
|
+
| Guards | @entity, @payload, @state, @now | Read-only conditions |
|
|
806
|
+
| Effects | @entity, @payload, @state, @now | @entity can be modified via set |
|
|
807
|
+
| Ticks | @entity, @state, @now | No payload (no event) |
|
|
808
|
+
| Render-UI | @entity, @payload, @state, @config | Display values only |
|
|
809
|
+
|
|
810
|
+
**Critical Rule:** The ".set" effect ONLY modifies @entity fields.
|
|
811
|
+
`.trim();
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// src/prompts/skill-sections/pattern-design-guide.ts
|
|
746
815
|
function getRenderUIDesignGuide() {
|
|
747
|
-
return `## Render-UI
|
|
816
|
+
return `## Render-UI Atomic Composition Guide (v5.0)
|
|
748
817
|
|
|
749
|
-
###
|
|
750
|
-
|
|
751
|
-
|
|
818
|
+
### The Five Rules of Sophisticated Composition (MANDATORY)
|
|
819
|
+
|
|
820
|
+
Every render-ui effect MUST satisfy ALL five rules:
|
|
821
|
+
|
|
822
|
+
| Rule | Requirement | Validation |
|
|
823
|
+
|------|-------------|------------|
|
|
824
|
+
| **1** | **Single Render-UI** per transition | One render-ui effect only |
|
|
825
|
+
| **2** | **Three Atomic Levels** | Atoms (2+) + Molecules (1+) + Organisms (1+) |
|
|
826
|
+
| **3** | **Layout Wrapper** | Root must be stack/box/container/grid |
|
|
827
|
+
| **4** | **Theme Variables** | ALL visual props use CSS vars |
|
|
828
|
+
| **5** | **Template Quality** | Match CrudTemplate/ListTemplate sophistication |
|
|
752
829
|
|
|
753
|
-
|
|
754
|
-
| Slot | Use For | Composable? |
|
|
755
|
-
|------|---------|-------------|
|
|
756
|
-
| \`main\` | Primary content | **YES** \u2014 stack multiple render-ui calls |
|
|
757
|
-
| \`modal\` | Forms (create/edit), confirmations | One at a time |
|
|
758
|
-
| \`drawer\` | Detail views, quick edits | One at a time |
|
|
759
|
-
| \`sidebar\` | Navigation, persistent filters | One at a time |
|
|
760
|
-
| \`overlay\` | Confirmations, alerts | One at a time |
|
|
830
|
+
---
|
|
761
831
|
|
|
762
|
-
###
|
|
763
|
-
| Intent | Patterns | Key Props |
|
|
764
|
-
|--------|----------|-----------|
|
|
765
|
-
| List/browse data | \`entity-table\`, \`entity-cards\`, \`entity-list\` | columns, itemActions, searchable |
|
|
766
|
-
| Show metrics/KPIs | \`stats\` | metrics: [{label, value, icon, trend}] |
|
|
767
|
-
| Filter/search | \`filter-group\`, \`search-input\` | filters (from entity enum fields) |
|
|
768
|
-
| Create/edit form | \`form-section\` | fields, submitEvent, cancelEvent |
|
|
769
|
-
| View details | \`entity-detail\`, \`detail-panel\` | fields/fieldNames, actions |
|
|
770
|
-
| Organize content | \`tabs\` | tabs: [{label, content}] |
|
|
771
|
-
| Dashboard layout | \`dashboard-grid\` | columns (number) |
|
|
772
|
-
| Charts | \`chart\` | chartType, data, xAxis, yAxis |
|
|
773
|
-
| Progress | \`progress-bar\`, \`meter\` | value, max, label |
|
|
774
|
-
| Timeline | \`timeline\` | items: [{date, title, description}] |
|
|
775
|
-
| Page heading | \`page-header\` | title, subtitle, actions |
|
|
776
|
-
| Confirmation | \`confirmation\` | title, message, onConfirm, onCancel |
|
|
777
|
-
| Master/detail | \`master-detail\` | Split list + detail |
|
|
778
|
-
| Cards grid | \`entity-cards\` | columns, itemActions, layout |
|
|
832
|
+
### Rule 1: Single Render-UI Per Transition
|
|
779
833
|
|
|
780
|
-
|
|
834
|
+
Each transition executes exactly ONE render-ui effect with composed children:
|
|
781
835
|
|
|
782
|
-
**CRUD Browsing INIT** (most common \u2014 compose ALL of these in main slot):
|
|
783
836
|
\`\`\`json
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
837
|
+
// \u2705 CORRECT: Single render-ui with composed children
|
|
838
|
+
{
|
|
839
|
+
"from": "Browsing",
|
|
840
|
+
"to": "Browsing",
|
|
841
|
+
"event": "INIT",
|
|
842
|
+
"effects": [
|
|
843
|
+
["render-ui", "main", {
|
|
844
|
+
"type": "stack",
|
|
845
|
+
"direction": "vertical",
|
|
846
|
+
"gap": "lg",
|
|
847
|
+
"children": [
|
|
848
|
+
{ "type": "page-header", "title": "...", "actions": [...] },
|
|
849
|
+
{ "type": "entity-table", "entity": "...", ... }
|
|
850
|
+
]
|
|
851
|
+
}]
|
|
852
|
+
]
|
|
853
|
+
}
|
|
788
854
|
|
|
789
|
-
|
|
855
|
+
// \u274C WRONG: Multiple flat render-ui calls
|
|
856
|
+
{
|
|
857
|
+
"effects": [
|
|
858
|
+
["render-ui", "main", { "type": "page-header", ... }],
|
|
859
|
+
["render-ui", "main", { "type": "entity-table", ... }]
|
|
860
|
+
]
|
|
861
|
+
}
|
|
790
862
|
\`\`\`
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
863
|
+
|
|
864
|
+
---
|
|
865
|
+
|
|
866
|
+
### Rule 2: Three Atomic Levels Required
|
|
867
|
+
|
|
868
|
+
Every composition MUST contain ALL three levels:
|
|
869
|
+
|
|
870
|
+
#### Level 1: Atoms (Minimum 2 distinct types)
|
|
871
|
+
|
|
872
|
+
| Type | Purpose | Example Usage |
|
|
873
|
+
|------|---------|---------------|
|
|
874
|
+
| \`typography\` | All text content | Headlines, labels, body text |
|
|
875
|
+
| \`badge\` | Status indicators | Active, Pending, Completed |
|
|
876
|
+
| \`button\` | User actions | Create, Edit, Delete |
|
|
877
|
+
| \`avatar\` | User/entity images | Profile pictures |
|
|
878
|
+
| \`icon\` | Decorative icons | Plus, Edit, Trash |
|
|
879
|
+
| \`progress-bar\` | Progress indicators | Upload progress |
|
|
880
|
+
| \`divider\` | Visual separation | Section dividers |
|
|
881
|
+
|
|
882
|
+
#### Level 2: Molecules (Minimum 1)
|
|
883
|
+
|
|
884
|
+
| Type | Purpose | Example Usage |
|
|
885
|
+
|------|---------|---------------|
|
|
886
|
+
| \`box\` | Visual containers | Stat cards, panels |
|
|
887
|
+
| \`card\` | Content grouping | Feature cards |
|
|
888
|
+
| \`modal\` | Dialog overlays | Create/edit forms |
|
|
889
|
+
| \`drawer\` | Side panels | Detail views |
|
|
890
|
+
| \`tabs\` | Content organization | Filter tabs |
|
|
891
|
+
| \`alert\` | Notifications | Success/error messages |
|
|
892
|
+
| \`accordion\` | Collapsible sections | FAQ, settings |
|
|
893
|
+
|
|
894
|
+
#### Level 3: Organisms (Minimum 1 for data views)
|
|
895
|
+
|
|
896
|
+
| Type | Purpose | Example Usage |
|
|
897
|
+
|------|---------|---------------|
|
|
898
|
+
| \`entity-table\` | Data tables | List views |
|
|
899
|
+
| \`form-section\` | Forms | Create/edit |
|
|
900
|
+
| \`detail-panel\` | Detail views | View record |
|
|
901
|
+
| \`page-header\` | Page headers | Title + actions |
|
|
902
|
+
| \`chart\` | Data visualization | Analytics |
|
|
903
|
+
| \`timeline\` | Chronological events | Activity history |
|
|
904
|
+
| \`stats\` | KPI metrics | Dashboard stats |
|
|
905
|
+
|
|
906
|
+
---
|
|
907
|
+
|
|
908
|
+
### Rule 3: Layout-First Structure
|
|
909
|
+
|
|
910
|
+
Root element MUST be a layout primitive:
|
|
911
|
+
|
|
912
|
+
\`\`\`json
|
|
913
|
+
// \u2705 CORRECT: Layout wrappers
|
|
914
|
+
{ "type": "stack", "direction": "vertical", "gap": "lg", "children": [...] }
|
|
915
|
+
{ "type": "stack", "direction": "horizontal", "gap": "md", "children": [...] }
|
|
916
|
+
{ "type": "box", "padding": "lg", "bg": "var(--color-card)", "children": [...] }
|
|
917
|
+
{ "type": "container", "size": "xl", "padding": "lg", "children": [...] }
|
|
918
|
+
{ "type": "grid", "cols": 3, "gap": "md", "children": [...] }
|
|
919
|
+
|
|
920
|
+
// \u274C WRONG: No layout wrapper
|
|
921
|
+
{ "type": "page-header", "title": "..." }
|
|
922
|
+
{ "type": "entity-table", "entity": "..." }
|
|
796
923
|
\`\`\`
|
|
797
924
|
|
|
798
|
-
|
|
925
|
+
#### Layout Props Reference
|
|
926
|
+
|
|
927
|
+
**Stack (VStack/HStack)**
|
|
928
|
+
\`\`\`json
|
|
929
|
+
{
|
|
930
|
+
"type": "stack",
|
|
931
|
+
"direction": "vertical" | "horizontal",
|
|
932
|
+
"gap": "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl",
|
|
933
|
+
"align": "start" | "center" | "end" | "stretch",
|
|
934
|
+
"justify": "start" | "center" | "end" | "between" | "around",
|
|
935
|
+
"wrap": true | false
|
|
936
|
+
}
|
|
799
937
|
\`\`\`
|
|
800
|
-
|
|
801
|
-
|
|
938
|
+
|
|
939
|
+
**Box**
|
|
940
|
+
\`\`\`json
|
|
941
|
+
{
|
|
942
|
+
"type": "box",
|
|
943
|
+
"padding": "none" | "xs" | "sm" | "md" | "lg" | "xl",
|
|
944
|
+
"bg": "var(--color-card)" | "var(--color-muted)" | "var(--color-primary)",
|
|
945
|
+
"border": true | false,
|
|
946
|
+
"borderColor": "var(--color-border)",
|
|
947
|
+
"rounded": "var(--radius-none)" | "var(--radius-sm)" | "var(--radius-md)" | "var(--radius-lg)" | "var(--radius-xl)",
|
|
948
|
+
"shadow": "var(--shadow-none)" | "var(--shadow-sm)" | "var(--shadow-md)" | "var(--shadow-lg)"
|
|
949
|
+
}
|
|
802
950
|
\`\`\`
|
|
803
951
|
|
|
804
|
-
**
|
|
952
|
+
**Container**
|
|
953
|
+
\`\`\`json
|
|
954
|
+
{
|
|
955
|
+
"type": "container",
|
|
956
|
+
"size": "sm" | "md" | "lg" | "xl" | "full",
|
|
957
|
+
"padding": "none" | "xs" | "sm" | "md" | "lg" | "xl"
|
|
958
|
+
}
|
|
805
959
|
\`\`\`
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
960
|
+
|
|
961
|
+
**Grid**
|
|
962
|
+
\`\`\`json
|
|
963
|
+
{
|
|
964
|
+
"type": "grid",
|
|
965
|
+
"cols": 1 | 2 | 3 | 4 | 6 | 12 | { "sm": 1, "md": 2, "lg": 3 },
|
|
966
|
+
"gap": "none" | "xs" | "sm" | "md" | "lg" | "xl"
|
|
967
|
+
}
|
|
809
968
|
\`\`\`
|
|
810
969
|
|
|
811
|
-
|
|
970
|
+
---
|
|
971
|
+
|
|
972
|
+
### Rule 4: Theme Variable Enforcement
|
|
812
973
|
|
|
813
|
-
|
|
974
|
+
ALL visual properties MUST use CSS theme variables:
|
|
814
975
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
976
|
+
| Property | \u2705 CORRECT | \u274C WRONG |
|
|
977
|
+
|----------|-----------|----------|
|
|
978
|
+
| Colors | "var(--color-primary)" | "#3b82f6", "blue", "white" |
|
|
979
|
+
| Backgrounds | "var(--color-card)" | "#ffffff", "white" |
|
|
980
|
+
| Text colors | "var(--color-foreground)" | "#000000", "black" |
|
|
981
|
+
| Spacing | "var(--spacing-lg)" | "16px", "1rem" |
|
|
982
|
+
| Radius | "var(--radius-md)" | "8px", "0.5rem" |
|
|
983
|
+
| Shadows | "var(--shadow-sm)" | "0 2px 4px rgba(0,0,0,0.1)" |
|
|
818
984
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
985
|
+
---
|
|
986
|
+
|
|
987
|
+
### Rule 5: Template-Quality Composition
|
|
988
|
+
|
|
989
|
+
Match the sophistication of reference templates in \`packages/almadar-ui/components/templates/\`.
|
|
990
|
+
|
|
991
|
+
#### CrudTemplate Structure
|
|
992
|
+
\`\`\`
|
|
993
|
+
Container (size: xl, padding: lg)
|
|
994
|
+
\u2514\u2500\u2500 VStack (gap: lg)
|
|
995
|
+
\u251C\u2500\u2500 PageHeader (title + actions)
|
|
996
|
+
\u251C\u2500\u2500 Alert (error state)
|
|
997
|
+
\u251C\u2500\u2500 EntityTable (searchable, sortable, actions)
|
|
998
|
+
\u2514\u2500\u2500 Modal (form-section for create/edit)
|
|
999
|
+
\`\`\`
|
|
1000
|
+
|
|
1001
|
+
#### ListTemplate Structure
|
|
1002
|
+
\`\`\`
|
|
1003
|
+
Container (size: md, padding: lg)
|
|
1004
|
+
\u2514\u2500\u2500 VStack (gap: lg)
|
|
1005
|
+
\u251C\u2500\u2500 Typography (h2 title)
|
|
1006
|
+
\u251C\u2500\u2500 Input (search)
|
|
1007
|
+
\u251C\u2500\u2500 HStack (filter buttons)
|
|
1008
|
+
\u2514\u2500\u2500 VStack (list items)
|
|
1009
|
+
\`\`\`
|
|
1010
|
+
|
|
1011
|
+
#### Dashboard Structure
|
|
1012
|
+
\`\`\`
|
|
1013
|
+
Container (size: full, padding: lg)
|
|
1014
|
+
\u2514\u2500\u2500 Grid (cols: { sm: 1, md: 2, lg: 4 })
|
|
1015
|
+
\u251C\u2500\u2500 Box (stat card 1)
|
|
1016
|
+
\u251C\u2500\u2500 Box (stat card 2)
|
|
1017
|
+
\u251C\u2500\u2500 Box (stat card 3)
|
|
1018
|
+
\u2514\u2500\u2500 Box (stat card 4)
|
|
1019
|
+
\`\`\`
|
|
827
1020
|
|
|
828
|
-
####
|
|
829
|
-
| Prop | Values |
|
|
830
|
-
|------|--------|
|
|
831
|
-
| \`padding\` / \`paddingX\` / \`paddingY\` | \`"none"\`, \`"xs"\`, \`"sm"\`, \`"md"\`, \`"lg"\`, \`"xl"\` |
|
|
832
|
-
| \`bg\` | \`"default"\`, \`"muted"\`, \`"card"\`, \`"primary"\`, \`"secondary"\`, \`"accent"\` |
|
|
833
|
-
| \`border\` | \`true\`, \`false\` |
|
|
834
|
-
| \`rounded\` | \`"none"\`, \`"sm"\`, \`"md"\`, \`"lg"\`, \`"full"\` |
|
|
835
|
-
| \`shadow\` | \`"none"\`, \`"sm"\`, \`"md"\`, \`"lg"\` |
|
|
1021
|
+
#### Stats Cards - Static Text Only
|
|
836
1022
|
|
|
837
|
-
|
|
838
|
-
| Prop | Values |
|
|
839
|
-
|------|--------|
|
|
840
|
-
| \`cols\` | \`1\`\u2013\`12\` or \`{ sm: 1, md: 2, lg: 3 }\` |
|
|
841
|
-
| \`gap\` | \`"none"\`, \`"xs"\`, \`"sm"\`, \`"md"\`, \`"lg"\`, \`"xl"\` |
|
|
1023
|
+
For stats/overview sections, use **static text labels**, NOT computed bindings:
|
|
842
1024
|
|
|
843
|
-
#### Nesting Example \u2014 Page Header + Stats Row + Table
|
|
844
1025
|
\`\`\`json
|
|
845
|
-
|
|
846
|
-
|
|
1026
|
+
// \u2705 CORRECT: Static text for labels
|
|
1027
|
+
{
|
|
1028
|
+
"type": "box",
|
|
1029
|
+
"padding": "md",
|
|
1030
|
+
"bg": "var(--color-card)",
|
|
847
1031
|
"children": [
|
|
848
|
-
{ "type": "
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1032
|
+
{ "type": "typography", "variant": "caption", "text": "Total Tasks" },
|
|
1033
|
+
{ "type": "typography", "variant": "h2", "text": "--" }
|
|
1034
|
+
]
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// \u2705 CORRECT: Using stats pattern with entity
|
|
1038
|
+
{
|
|
1039
|
+
"type": "stats",
|
|
1040
|
+
"entity": "Task",
|
|
1041
|
+
"label": "Total Tasks"
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
// \u274C WRONG: Invented computed bindings
|
|
1045
|
+
{ "text": "@count" }
|
|
1046
|
+
{ "text": "@count:status=pending" }
|
|
1047
|
+
\`\`\`
|
|
1048
|
+
|
|
1049
|
+
---
|
|
1050
|
+
|
|
1051
|
+
### Validated Example: Task Management
|
|
1052
|
+
|
|
1053
|
+
This example has been validated with \`npx @almadar/cli validate\`:
|
|
1054
|
+
|
|
1055
|
+
\`\`\`json
|
|
1056
|
+
{
|
|
1057
|
+
"name": "Taskly",
|
|
1058
|
+
"version": "1.0.0",
|
|
1059
|
+
"orbitals": [{
|
|
1060
|
+
"name": "Task Management",
|
|
1061
|
+
"entity": {
|
|
1062
|
+
"name": "Task",
|
|
1063
|
+
"collection": "tasks",
|
|
1064
|
+
"fields": [
|
|
1065
|
+
{ "name": "title", "type": "string", "required": true },
|
|
1066
|
+
{ "name": "status", "type": "enum", "values": ["pending", "active", "done"] },
|
|
1067
|
+
{ "name": "priority", "type": "enum", "values": ["low", "medium", "high"] }
|
|
862
1068
|
]
|
|
863
1069
|
},
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
1070
|
+
"traits": [{
|
|
1071
|
+
"name": "TaskInteraction",
|
|
1072
|
+
"category": "interaction",
|
|
1073
|
+
"linkedEntity": "Task",
|
|
1074
|
+
"emits": [{ "event": "INIT", "scope": "internal" }],
|
|
1075
|
+
"stateMachine": {
|
|
1076
|
+
"states": [
|
|
1077
|
+
{ "name": "Browsing", "isInitial": true },
|
|
1078
|
+
{ "name": "Creating" }
|
|
1079
|
+
],
|
|
1080
|
+
"events": [
|
|
1081
|
+
{ "key": "INIT", "name": "Initialize" },
|
|
1082
|
+
{ "key": "CREATE", "name": "Create" },
|
|
1083
|
+
{ "key": "SAVE", "name": "Save", "payload": [{ "name": "data", "type": "object" }] },
|
|
1084
|
+
{ "key": "CANCEL", "name": "Cancel" }
|
|
1085
|
+
],
|
|
1086
|
+
"transitions": [
|
|
1087
|
+
{
|
|
1088
|
+
"from": "Browsing",
|
|
1089
|
+
"to": "Browsing",
|
|
1090
|
+
"event": "INIT",
|
|
1091
|
+
"effects": [
|
|
1092
|
+
["render-ui", "main", {
|
|
1093
|
+
"type": "stack",
|
|
1094
|
+
"direction": "vertical",
|
|
1095
|
+
"gap": "lg",
|
|
1096
|
+
"children": [
|
|
1097
|
+
{
|
|
1098
|
+
"type": "page-header",
|
|
1099
|
+
"title": "Task Management",
|
|
1100
|
+
"actions": [{ "label": "Create Task", "event": "CREATE", "variant": "primary" }]
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
"type": "entity-table",
|
|
1104
|
+
"entity": "Task",
|
|
1105
|
+
"columns": ["title", "status", "priority"],
|
|
1106
|
+
"searchable": true,
|
|
1107
|
+
"itemActions": [
|
|
1108
|
+
{ "label": "Edit", "event": "EDIT" },
|
|
1109
|
+
{ "label": "Delete", "event": "DELETE" }
|
|
1110
|
+
]
|
|
1111
|
+
}
|
|
1112
|
+
]
|
|
1113
|
+
}]
|
|
1114
|
+
]
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
"from": "Browsing",
|
|
1118
|
+
"to": "Creating",
|
|
1119
|
+
"event": "CREATE",
|
|
1120
|
+
"effects": [
|
|
1121
|
+
["render-ui", "modal", {
|
|
1122
|
+
"type": "form-section",
|
|
1123
|
+
"entity": "Task",
|
|
1124
|
+
"fields": ["title", "status", "priority"],
|
|
1125
|
+
"submitEvent": "SAVE",
|
|
1126
|
+
"cancelEvent": "CANCEL"
|
|
1127
|
+
}]
|
|
1128
|
+
]
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
"from": "Creating",
|
|
1132
|
+
"to": "Browsing",
|
|
1133
|
+
"event": "SAVE",
|
|
1134
|
+
"effects": [
|
|
1135
|
+
["persist", "create", "Task", "@payload.data"],
|
|
1136
|
+
["render-ui", "modal", null],
|
|
1137
|
+
["emit", "INIT"]
|
|
1138
|
+
]
|
|
1139
|
+
},
|
|
1140
|
+
{
|
|
1141
|
+
"from": "Creating",
|
|
1142
|
+
"to": "Browsing",
|
|
1143
|
+
"event": "CANCEL",
|
|
1144
|
+
"effects": [
|
|
1145
|
+
["render-ui", "modal", null]
|
|
1146
|
+
]
|
|
1147
|
+
}
|
|
1148
|
+
]
|
|
1149
|
+
}
|
|
1150
|
+
}],
|
|
1151
|
+
"pages": [{
|
|
1152
|
+
"name": "TasksPage",
|
|
1153
|
+
"path": "/tasks",
|
|
1154
|
+
"viewType": "list",
|
|
1155
|
+
"isInitial": true,
|
|
1156
|
+
"entity": "Task",
|
|
1157
|
+
"traits": [{ "ref": "TaskInteraction" }]
|
|
1158
|
+
}],
|
|
1159
|
+
"emits": [],
|
|
1160
|
+
"listens": []
|
|
1161
|
+
}]
|
|
1162
|
+
}
|
|
1163
|
+
\`\`\`
|
|
1164
|
+
|
|
1165
|
+
---
|
|
1166
|
+
|
|
1167
|
+
${getBindingsGuide()}
|
|
1168
|
+
|
|
1169
|
+
---
|
|
1170
|
+
|
|
1171
|
+
### Critical Validation Rules
|
|
1172
|
+
|
|
1173
|
+
| Element | Correct Format | Wrong Format | Error |
|
|
1174
|
+
|---------|----------------|--------------|-------|
|
|
1175
|
+
| **Events** | \`{ "key": "INIT", "name": "Init" }\` | \`"INIT"\` | ORB_T_EVT_INVALID_FORMAT |
|
|
1176
|
+
| **Emits** | \`[{ "event": "INIT", "scope": "internal" }}]\` | \`["INIT"]\` | ORB_T_UNDEFINED_TRAIT |
|
|
1177
|
+
| **Payload events** | \`{ "key": "SAVE", "payload": [...] }\` | No payload | ORB_BINDING_PAYLOAD_FIELD_UNDECLARED |
|
|
1178
|
+
| **Page traits** | \`{ "ref": "TraitName" }\` | With linkedEntity | ORB_P_INVALID_TRAIT_REF |
|
|
1179
|
+
| **Category** | \`"category": "interaction"\` | Missing | ORB_T_MISSING_CATEGORY |
|
|
1180
|
+
|
|
1181
|
+
---
|
|
1182
|
+
|
|
1183
|
+
### Composition Quality Checklist
|
|
1184
|
+
|
|
1185
|
+
Before calling \`finish_task\`, verify:
|
|
1186
|
+
|
|
1187
|
+
\`\`\`
|
|
1188
|
+
\u25A1 Single render-ui per transition
|
|
1189
|
+
\u25A1 Root element is layout (stack/box/container/grid)
|
|
1190
|
+
\u25A1 Contains 2+ atoms (typography, badge, button, etc.)
|
|
1191
|
+
\u25A1 Contains 1+ molecules (box, card, tabs, alert)
|
|
1192
|
+
\u25A1 Contains 1+ organisms (entity-table, form-section, page-header)
|
|
1193
|
+
\u25A1 Uses theme variables for ALL visual properties
|
|
1194
|
+
\u25A1 Has 3+ distinct sections (header, content, actions)
|
|
1195
|
+
\u25A1 Matches template quality from almadar-ui/components/templates/
|
|
1196
|
+
\u25A1 Passes npx @almadar/cli validate with zero errors
|
|
867
1197
|
\`\`\`
|
|
868
1198
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
- **Box**: Visual grouping \u2014 cards, panels, highlighted sections with borders/backgrounds
|
|
873
|
-
- **Grid**: Equal-width columns \u2014 dashboard cards, stat grids, gallery layouts
|
|
1199
|
+
---
|
|
1200
|
+
|
|
1201
|
+
### BANNED Patterns
|
|
874
1202
|
|
|
875
|
-
|
|
1203
|
+
| Wrong | Correct |
|
|
1204
|
+
|-------|---------|
|
|
1205
|
+
| Multiple flat render-ui calls | Single composed render-ui |
|
|
1206
|
+
| Root organism without layout | Layout wrapper required |
|
|
1207
|
+
| Hex colors | Theme CSS variables |
|
|
1208
|
+
| Pixel values | Theme spacing variables |
|
|
1209
|
+
| Events as strings \`"INIT"\` | Event objects \`{ "key": "INIT" }\` |
|
|
1210
|
+
| Emits as strings \`["INIT"]\` | Emit objects \`[{ "event": "INIT" }]\` |
|
|
1211
|
+
| \`onSubmit\` / \`onCancel\` | \`submitEvent\` / \`cancelEvent\` |
|
|
1212
|
+
| \`headerActions\` | \`actions\` |
|
|
876
1213
|
|
|
877
|
-
|
|
878
|
-
| Domain | List Pattern | Extras |
|
|
879
|
-
|--------|-------------|--------|
|
|
880
|
-
| business/admin | \`entity-table\` (searchable) | \`stats\`, \`filter-group\` |
|
|
881
|
-
| ecommerce | \`entity-cards\` | \`stats\` (revenue), \`chart\` |
|
|
882
|
-
| content/CMS | \`entity-cards\` | \`tabs\`, \`media-gallery\` |
|
|
883
|
-
| dashboard | \`dashboard-grid\` | \`stats\`, \`chart\`, \`meter\`, \`timeline\` |
|
|
884
|
-
| workflow | \`entity-table\` | \`progress-bar\`, \`timeline\` |
|
|
1214
|
+
---
|
|
885
1215
|
|
|
886
1216
|
${getPatternPropsCompact()}
|
|
887
1217
|
|
|
@@ -889,6 +1219,244 @@ ${getPatternActionsRef()}
|
|
|
889
1219
|
`;
|
|
890
1220
|
}
|
|
891
1221
|
|
|
1222
|
+
// src/prompts/skill-sections/theme-guide.ts
|
|
1223
|
+
function getThemeGuide() {
|
|
1224
|
+
return `## Theme Variable System (MANDATORY)
|
|
1225
|
+
|
|
1226
|
+
All visual properties MUST use CSS theme variables. Never use hardcoded values.
|
|
1227
|
+
|
|
1228
|
+
### \u274C BANNED: Hardcoded Values
|
|
1229
|
+
|
|
1230
|
+
| Type | Wrong | Why |
|
|
1231
|
+
|------|-------|-----|
|
|
1232
|
+
| Hex colors | "#3b82f6", "#ffffff", "#000000" | Not themeable |
|
|
1233
|
+
| Named colors | "white", "black", "red", "blue" | Not themeable |
|
|
1234
|
+
| Pixel values | "16px", "8px", "24px" | Not scalable |
|
|
1235
|
+
| Rem values | "1rem", "0.5rem" | Inconsistent |
|
|
1236
|
+
| Arbitrary values | "0 2px 4px rgba(0,0,0,0.1)" | Not themeable |
|
|
1237
|
+
|
|
1238
|
+
### \u2705 REQUIRED: Theme Variables
|
|
1239
|
+
|
|
1240
|
+
### Color Variables
|
|
1241
|
+
|
|
1242
|
+
| Variable | Usage | Example Context |
|
|
1243
|
+
|----------|-------|-----------------|
|
|
1244
|
+
| \`var(--color-foreground)\` | Primary text | Headlines, body text |
|
|
1245
|
+
| \`var(--color-muted-foreground)\` | Secondary text | Captions, labels, hints |
|
|
1246
|
+
| \`var(--color-background)\` | Page background | Main container bg |
|
|
1247
|
+
| \`var(--color-card)\` | Card backgrounds | Box containers, panels |
|
|
1248
|
+
| \`var(--color-muted)\` | Subtle sections | Alternating rows, disabled states |
|
|
1249
|
+
| \`var(--color-primary)\` | Primary actions | Main buttons, active states |
|
|
1250
|
+
| \`var(--color-primary-foreground)\` | Text on primary | Button labels |
|
|
1251
|
+
| \`var(--color-secondary)\` | Secondary actions | Secondary buttons |
|
|
1252
|
+
| \`var(--color-secondary-foreground)\` | Text on secondary | Secondary button labels |
|
|
1253
|
+
| \`var(--color-success)\` | Success states | Completed badges, success alerts |
|
|
1254
|
+
| \`var(--color-warning)\` | Warnings | Warning badges, alerts |
|
|
1255
|
+
| \`var(--color-destructive)\` | Errors, delete | Danger buttons, error states |
|
|
1256
|
+
| \`var(--color-border)\` | Borders, dividers | Card outlines, separators |
|
|
1257
|
+
| \`var(--color-input)\` | Input backgrounds | Form field backgrounds |
|
|
1258
|
+
| \`var(--color-ring)\` | Focus rings | Input focus states |
|
|
1259
|
+
|
|
1260
|
+
### Spacing Variables
|
|
1261
|
+
|
|
1262
|
+
| Variable | Value | Usage |
|
|
1263
|
+
|----------|-------|-------|
|
|
1264
|
+
| \`var(--spacing-xs)\` | 4px | Tight gaps, icon spacing |
|
|
1265
|
+
| \`var(--spacing-sm)\` | 8px | Small gaps, compact layouts |
|
|
1266
|
+
| \`var(--spacing-md)\` | 12px | Standard gaps |
|
|
1267
|
+
| \`var(--spacing-lg)\` | 16px | Large gaps, section padding |
|
|
1268
|
+
| \`var(--spacing-xl)\` | 24px | Extra large gaps |
|
|
1269
|
+
| \`var(--spacing-2xl)\` | 32px | Page-level spacing |
|
|
1270
|
+
| \`var(--spacing-3xl)\` | 48px | Major section spacing |
|
|
1271
|
+
| \`var(--spacing-4xl)\` | 64px | Hero section spacing |
|
|
1272
|
+
|
|
1273
|
+
### Radius Variables
|
|
1274
|
+
|
|
1275
|
+
| Variable | Value | Usage |
|
|
1276
|
+
|----------|-------|-------|
|
|
1277
|
+
| \`var(--radius-none)\` | 0px | Sharp corners |
|
|
1278
|
+
| \`var(--radius-sm)\` | 2px | Small elements, tags |
|
|
1279
|
+
| \`var(--radius-md)\` | 6px | Buttons, inputs, small cards |
|
|
1280
|
+
| \`var(--radius-lg)\` | 8px | Cards, panels, modals |
|
|
1281
|
+
| \`var(--radius-xl)\` | 12px | Large containers |
|
|
1282
|
+
| \`var(--radius-2xl)\` | 16px | Extra large containers |
|
|
1283
|
+
| \`var(--radius-full)\` | 9999px | Pills, avatars, badges |
|
|
1284
|
+
|
|
1285
|
+
### Shadow Variables
|
|
1286
|
+
|
|
1287
|
+
| Variable | Usage |
|
|
1288
|
+
|----------|-------|
|
|
1289
|
+
| \`var(--shadow-none)\` | Flat design, no elevation |
|
|
1290
|
+
| \`var(--shadow-sm)\` | Subtle elevation, cards |
|
|
1291
|
+
| \`var(--shadow-md)\` | Cards, dropdowns, popovers |
|
|
1292
|
+
| \`var(--shadow-lg)\` | Modals, dialogs |
|
|
1293
|
+
| \`var(--shadow-xl)\` | High elevation elements |
|
|
1294
|
+
| \`var(--shadow-2xl)\` | Maximum elevation |
|
|
1295
|
+
|
|
1296
|
+
### Pattern-Specific Examples
|
|
1297
|
+
|
|
1298
|
+
#### Box / Card Container
|
|
1299
|
+
\`\`\`json
|
|
1300
|
+
{
|
|
1301
|
+
"type": "box",
|
|
1302
|
+
"padding": "lg",
|
|
1303
|
+
"bg": "var(--color-card)",
|
|
1304
|
+
"border": true,
|
|
1305
|
+
"borderColor": "var(--color-border)",
|
|
1306
|
+
"rounded": "var(--radius-lg)",
|
|
1307
|
+
"shadow": "var(--shadow-sm)"
|
|
1308
|
+
}
|
|
1309
|
+
\`\`\`
|
|
1310
|
+
|
|
1311
|
+
#### Typography
|
|
1312
|
+
\`\`\`json
|
|
1313
|
+
// Page title
|
|
1314
|
+
{
|
|
1315
|
+
"type": "typography",
|
|
1316
|
+
"variant": "h1",
|
|
1317
|
+
"text": "Page Title",
|
|
1318
|
+
"color": "var(--color-foreground)"
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
// Secondary text
|
|
1322
|
+
{
|
|
1323
|
+
"type": "typography",
|
|
1324
|
+
"variant": "caption",
|
|
1325
|
+
"text": "Label text",
|
|
1326
|
+
"color": "var(--color-muted-foreground)"
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// Success text
|
|
1330
|
+
{
|
|
1331
|
+
"type": "typography",
|
|
1332
|
+
"variant": "body",
|
|
1333
|
+
"text": "Completed",
|
|
1334
|
+
"color": "var(--color-success)"
|
|
1335
|
+
}
|
|
1336
|
+
\`\`\`
|
|
1337
|
+
|
|
1338
|
+
#### Button (use variant, not manual colors)
|
|
1339
|
+
\`\`\`json
|
|
1340
|
+
// Primary action
|
|
1341
|
+
{
|
|
1342
|
+
"type": "button",
|
|
1343
|
+
"label": "Save",
|
|
1344
|
+
"event": "SAVE",
|
|
1345
|
+
"variant": "primary"
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
// Secondary action
|
|
1349
|
+
{
|
|
1350
|
+
"type": "button",
|
|
1351
|
+
"label": "Cancel",
|
|
1352
|
+
"event": "CANCEL",
|
|
1353
|
+
"variant": "secondary"
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
// Danger action
|
|
1357
|
+
{
|
|
1358
|
+
"type": "button",
|
|
1359
|
+
"label": "Delete",
|
|
1360
|
+
"event": "DELETE",
|
|
1361
|
+
"variant": "danger"
|
|
1362
|
+
}
|
|
1363
|
+
\`\`\`
|
|
1364
|
+
|
|
1365
|
+
#### Badge (variant maps to semantic colors)
|
|
1366
|
+
\`\`\`json
|
|
1367
|
+
{
|
|
1368
|
+
"type": "badge",
|
|
1369
|
+
"text": "Active",
|
|
1370
|
+
"variant": "primary"
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
{
|
|
1374
|
+
"type": "badge",
|
|
1375
|
+
"text": "Completed",
|
|
1376
|
+
"variant": "success"
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
{
|
|
1380
|
+
"type": "badge",
|
|
1381
|
+
"text": "Pending",
|
|
1382
|
+
"variant": "warning"
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
{
|
|
1386
|
+
"type": "badge",
|
|
1387
|
+
"text": "Error",
|
|
1388
|
+
"variant": "danger"
|
|
1389
|
+
}
|
|
1390
|
+
\`\`\`
|
|
1391
|
+
|
|
1392
|
+
#### Stack Layout
|
|
1393
|
+
\`\`\`json
|
|
1394
|
+
{
|
|
1395
|
+
"type": "stack",
|
|
1396
|
+
"direction": "vertical",
|
|
1397
|
+
"gap": "lg",
|
|
1398
|
+
"align": "stretch",
|
|
1399
|
+
"justify": "start"
|
|
1400
|
+
}
|
|
1401
|
+
\`\`\`
|
|
1402
|
+
|
|
1403
|
+
### Theme Validation Checklist
|
|
1404
|
+
|
|
1405
|
+
Before calling \`finish_task\`, verify:
|
|
1406
|
+
|
|
1407
|
+
- [ ] No hex colors (#fff, #000, #3b82f6, etc.)
|
|
1408
|
+
- [ ] No named colors (white, black, red, blue, etc.)
|
|
1409
|
+
- [ ] No pixel values (16px, 8px, 24px, etc.)
|
|
1410
|
+
- [ ] No rem values (1rem, 0.5rem, etc.)
|
|
1411
|
+
- [ ] All colors use var(--color-*)
|
|
1412
|
+
- [ ] All spacing uses var(--spacing-*)
|
|
1413
|
+
- [ ] All radius uses var(--radius-*)
|
|
1414
|
+
- [ ] All shadows use var(--shadow-*)
|
|
1415
|
+
|
|
1416
|
+
### Auto-Correction Reference
|
|
1417
|
+
|
|
1418
|
+
The system will auto-correct these common mistakes:
|
|
1419
|
+
|
|
1420
|
+
| Wrong | Auto-Corrected To |
|
|
1421
|
+
|-------|-------------------|
|
|
1422
|
+
| "#fff" or "white" | "var(--color-background)" |
|
|
1423
|
+
| "#000" or "black" | "var(--color-foreground)" |
|
|
1424
|
+
| "#3b82f6" | "var(--color-primary)" |
|
|
1425
|
+
| "#10b981" | "var(--color-success)" |
|
|
1426
|
+
| "#f59e0b" | "var(--color-warning)" |
|
|
1427
|
+
| "#ef4444" | "var(--color-destructive)" |
|
|
1428
|
+
| "16px" | "var(--spacing-lg)" |
|
|
1429
|
+
| "8px" | "var(--spacing-sm)" |
|
|
1430
|
+
| "24px" | "var(--spacing-xl)" |
|
|
1431
|
+
| "8px" (radius) | "var(--radius-md)" |
|
|
1432
|
+
`;
|
|
1433
|
+
}
|
|
1434
|
+
function getBannedProps() {
|
|
1435
|
+
return `## BANNED PROPS (NEVER USE)
|
|
1436
|
+
|
|
1437
|
+
| Wrong Prop | Correct Prop | Pattern |
|
|
1438
|
+
|------------|--------------|---------|
|
|
1439
|
+
| \`onSubmit\` | \`submitEvent\` | form-section |
|
|
1440
|
+
| \`onCancel\` | \`cancelEvent\` | form-section |
|
|
1441
|
+
| \`headerActions\` | \`actions\` | detail-panel |
|
|
1442
|
+
| \`loading\` | \`isLoading\` | all patterns |
|
|
1443
|
+
| \`fieldNames\` | \`fields\` | detail-panel, form-section |
|
|
1444
|
+
| \`onConfirm\` | (use event transitions) | confirmation |
|
|
1445
|
+
| \`placement\` | (remove) | itemActions |
|
|
1446
|
+
| \`isDestructive\` | (use variant: "danger") | itemActions |
|
|
1447
|
+
|
|
1448
|
+
### Banned Value Patterns
|
|
1449
|
+
|
|
1450
|
+
| Wrong | Correct |
|
|
1451
|
+
|-------|---------|
|
|
1452
|
+
| Hex colors: "#3b82f6" | Theme vars: "var(--color-primary)" |
|
|
1453
|
+
| Named colors: "white", "red" | Theme vars: "var(--color-background)" |
|
|
1454
|
+
| Pixel values: "16px" | Theme vars: "var(--spacing-lg)" |
|
|
1455
|
+
| Events as strings: "INIT" | Event objects: { "key": "INIT", "name": "Init" } |
|
|
1456
|
+
| Emits as strings: ["INIT"] | Emit objects: [{ "event": "INIT", "scope": "internal" }] |
|
|
1457
|
+
`;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
892
1460
|
// src/prompts/skill-sections/custom-traits.ts
|
|
893
1461
|
function getCustomTraitSection() {
|
|
894
1462
|
return `## Custom Trait Guide
|
|
@@ -968,7 +1536,7 @@ Every \`interaction\` trait MUST have:
|
|
|
968
1536
|
"title": "In Review"
|
|
969
1537
|
}],
|
|
970
1538
|
["render-ui", "main", {
|
|
971
|
-
"type": "
|
|
1539
|
+
"type": "detail-panel",
|
|
972
1540
|
"entity": "Document",
|
|
973
1541
|
"fieldNames": ["title", "content"]
|
|
974
1542
|
}],
|
|
@@ -1004,7 +1572,7 @@ Every \`interaction\` trait MUST have:
|
|
|
1004
1572
|
"title": "Published!"
|
|
1005
1573
|
}],
|
|
1006
1574
|
["render-ui", "main", {
|
|
1007
|
-
"type": "
|
|
1575
|
+
"type": "detail-panel",
|
|
1008
1576
|
"entity": "Document"
|
|
1009
1577
|
}]
|
|
1010
1578
|
]
|
|
@@ -1148,7 +1716,7 @@ When traits need to communicate across orbitals, you MUST:
|
|
|
1148
1716
|
| \`page-header\` | \`actions: [{label, event}]\` | Top-right buttons (New, Export) |
|
|
1149
1717
|
| \`form-section\` | \`onSubmit\`, \`onCancel\` | Form submit/cancel buttons |
|
|
1150
1718
|
| \`entity-table\` | \`itemActions: [{label, event}]\` | Row action buttons (Edit, Delete) |
|
|
1151
|
-
| \`
|
|
1719
|
+
| \`detail-panel\` | \`actions: [{label, event}]\` | Detail view header buttons |
|
|
1152
1720
|
| \`confirmation\` | \`onConfirm\`, \`onCancel\` | Confirmation dialog buttons |
|
|
1153
1721
|
`;
|
|
1154
1722
|
}
|
|
@@ -1557,7 +2125,7 @@ function getCommonFixPatternsSection() {
|
|
|
1557
2125
|
| \`entity-table\` | itemActions | \`"itemActions": [{ "label": "Edit", "event": "EDIT" }]\` |
|
|
1558
2126
|
| \`form-section\` | onSubmit | \`"onSubmit": "SAVE"\` |
|
|
1559
2127
|
| \`form-section\` | fields | \`"fields": ["field1", "field2"]\` |
|
|
1560
|
-
| \`
|
|
2128
|
+
| \`detail-panel\` | fields | \`"fields": ["field1", "field2"]\` |
|
|
1561
2129
|
| \`page-header\` | actions | \`"actions": [{ "label": "New", "event": "CREATE" }]\` |`;
|
|
1562
2130
|
}
|
|
1563
2131
|
function getOverGenerationSection() {
|
|
@@ -2020,6 +2588,14 @@ ${getSExprQuickRef()}
|
|
|
2020
2588
|
|
|
2021
2589
|
${includeDesignGuide ? getRenderUIDesignGuide() : ""}
|
|
2022
2590
|
|
|
2591
|
+
${includeDesignGuide ? `---
|
|
2592
|
+
|
|
2593
|
+
${getThemeGuide()}
|
|
2594
|
+
|
|
2595
|
+
---
|
|
2596
|
+
|
|
2597
|
+
${getBannedProps()}` : ""}
|
|
2598
|
+
|
|
2023
2599
|
${stdSection}
|
|
2024
2600
|
---
|
|
2025
2601
|
|
|
@@ -2131,55 +2707,29 @@ finish_task({ appName: "App" })
|
|
|
2131
2707
|
# Reads .orbitals/*.json \u2192 schema.json \u2192 orbital validate
|
|
2132
2708
|
\`\`\`
|
|
2133
2709
|
|
|
2134
|
-
### Phase 4:
|
|
2135
|
-
|
|
2136
|
-
After \`finish_task\` produces \`schema.json\`, enhance key transitions with \`design_transition\`.
|
|
2137
|
-
|
|
2138
|
-
**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.
|
|
2139
|
-
|
|
2140
|
-
**Step-by-step:**
|
|
2141
|
-
|
|
2142
|
-
1. Call \`design_transition\` for the transition:
|
|
2143
|
-
\`\`\`json
|
|
2144
|
-
{
|
|
2145
|
-
"from": "Browsing", "to": "Browsing", "event": "INIT",
|
|
2146
|
-
"slot": "main", "entityName": "Task",
|
|
2147
|
-
"entityFields": [{"name": "title", "type": "string"}, {"name": "status", "type": "enum", "values": ["pending", "active", "done"]}],
|
|
2148
|
-
"domainCategory": "business"
|
|
2149
|
-
}
|
|
2150
|
-
\`\`\`
|
|
2151
|
-
Returns: \`{ "success": true, "effects": [["render-ui", "main", {...}], ...] }\`
|
|
2152
|
-
|
|
2153
|
-
2. Extract the orbital chunk:
|
|
2154
|
-
\`\`\`json
|
|
2155
|
-
{ "file": "schema.json", "type": "orbital", "name": "Task Management" }
|
|
2156
|
-
\`\`\`
|
|
2157
|
-
|
|
2158
|
-
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.
|
|
2710
|
+
### Phase 4: VERIFY COMPOSITION QUALITY
|
|
2159
2711
|
|
|
2160
|
-
|
|
2161
|
-
\`\`\`json
|
|
2162
|
-
{ "chunkId": "<id from extract_chunk>" }
|
|
2163
|
-
\`\`\`
|
|
2712
|
+
Before calling \`finish_task\`, verify each INIT transition:
|
|
2164
2713
|
|
|
2165
|
-
**
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
Keep \`persist\` and \`emit\`, replace \`render-ui\` with the designed effects.
|
|
2170
|
-
For INIT transitions (render-ui only), replace all effects.
|
|
2714
|
+
1. **Uses a single \`render-ui\` call** with top-level \`stack\` and \`children\` \u2014 NOT flat sequential calls
|
|
2715
|
+
2. **Has 3+ composed sections**: header (HStack: title + action), metrics (HStack/Grid of Box cards), data (entity-table/entity-cards)
|
|
2716
|
+
3. **Uses domain-appropriate atoms**: \`badge\` for status, \`typography\` for labels/values, \`button\` for actions
|
|
2717
|
+
4. **Props are correct**: \`submitEvent\` not \`onSubmit\`, \`actions\` not \`headerActions\`, \`fields\` not \`fieldNames\`
|
|
2171
2718
|
|
|
2172
|
-
|
|
2719
|
+
If any INIT transition is flat (just \`page-header\` + \`entity-table\`), redesign it as a composed VStack hierarchy before finishing.
|
|
2173
2720
|
`;
|
|
2174
2721
|
}
|
|
2175
2722
|
function getMinimalExample() {
|
|
2176
2723
|
return `---
|
|
2177
2724
|
|
|
2178
|
-
## Example: Task Manager
|
|
2725
|
+
## Example: Task Manager (Atomic Composition - VALIDATED)
|
|
2726
|
+
|
|
2727
|
+
This example passes \`npx @almadar/cli validate\` with zero errors:
|
|
2179
2728
|
|
|
2180
2729
|
\`\`\`json
|
|
2181
2730
|
{
|
|
2182
2731
|
"name": "Taskly",
|
|
2732
|
+
"version": "1.0.0",
|
|
2183
2733
|
"orbitals": [{
|
|
2184
2734
|
"name": "Task Management",
|
|
2185
2735
|
"entity": {
|
|
@@ -2194,40 +2744,51 @@ function getMinimalExample() {
|
|
|
2194
2744
|
"name": "TaskInteraction",
|
|
2195
2745
|
"category": "interaction",
|
|
2196
2746
|
"linkedEntity": "Task",
|
|
2747
|
+
"emits": [{ "event": "INIT", "scope": "internal" }],
|
|
2197
2748
|
"stateMachine": {
|
|
2198
2749
|
"states": [
|
|
2199
2750
|
{ "name": "Browsing", "isInitial": true },
|
|
2200
|
-
{ "name": "Creating" }
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
{ "name": "
|
|
2751
|
+
{ "name": "Creating" }
|
|
2752
|
+
],
|
|
2753
|
+
"events": [
|
|
2754
|
+
{ "key": "INIT", "name": "Initialize" },
|
|
2755
|
+
{ "key": "CREATE", "name": "Create" },
|
|
2756
|
+
{ "key": "SAVE", "name": "Save", "payload": [{ "name": "data", "type": "object" }] },
|
|
2757
|
+
{ "key": "CANCEL", "name": "Cancel" }
|
|
2204
2758
|
],
|
|
2205
|
-
"events": ["INIT", "CREATE", "VIEW", "EDIT", "DELETE", "SAVE", "CANCEL", "CONFIRM_DELETE"],
|
|
2206
2759
|
"transitions": [
|
|
2207
2760
|
{
|
|
2208
2761
|
"from": "Browsing", "to": "Browsing", "event": "INIT",
|
|
2209
2762
|
"effects": [
|
|
2210
|
-
["render-ui", "main", {
|
|
2211
|
-
|
|
2212
|
-
|
|
2763
|
+
["render-ui", "main", {
|
|
2764
|
+
"type": "stack", "direction": "vertical", "gap": "lg",
|
|
2765
|
+
"children": [
|
|
2766
|
+
{ "type": "stack", "direction": "horizontal", "justify": "between", "align": "center",
|
|
2767
|
+
"children": [
|
|
2768
|
+
{ "type": "typography", "variant": "h1", "text": "Tasks" },
|
|
2769
|
+
{ "type": "button", "label": "New Task", "event": "CREATE", "variant": "primary" }
|
|
2770
|
+
]
|
|
2771
|
+
},
|
|
2772
|
+
{ "type": "stack", "direction": "horizontal", "gap": "md", "wrap": true,
|
|
2773
|
+
"children": [
|
|
2774
|
+
{ "type": "box", "padding": "md", "bg": "var(--color-card)", "border": true, "rounded": "var(--radius-md)",
|
|
2775
|
+
"children": [{ "type": "typography", "variant": "caption", "text": "Total" }, { "type": "typography", "variant": "h2", "text": "@count" }] },
|
|
2776
|
+
{ "type": "box", "padding": "md", "bg": "var(--color-card)", "border": true, "rounded": "var(--radius-md)",
|
|
2777
|
+
"children": [{ "type": "typography", "variant": "caption", "text": "Active" }, { "type": "badge", "variant": "primary", "text": "@count:status=active" }] },
|
|
2778
|
+
{ "type": "box", "padding": "md", "bg": "var(--color-card)", "border": true, "rounded": "var(--radius-md)",
|
|
2779
|
+
"children": [{ "type": "typography", "variant": "caption", "text": "Done" }, { "type": "badge", "variant": "success", "text": "@count:status=done" }] }
|
|
2780
|
+
]
|
|
2781
|
+
},
|
|
2782
|
+
{ "type": "entity-table", "entity": "Task", "columns": ["title", "status"], "searchable": true,
|
|
2783
|
+
"itemActions": [{ "label": "View", "event": "VIEW" }, { "label": "Edit", "event": "EDIT" }, { "label": "Delete", "event": "DELETE" }] }
|
|
2784
|
+
]
|
|
2785
|
+
}]
|
|
2213
2786
|
]
|
|
2214
2787
|
},
|
|
2215
2788
|
{
|
|
2216
2789
|
"from": "Browsing", "to": "Creating", "event": "CREATE",
|
|
2217
2790
|
"effects": [["render-ui", "modal", { "type": "form-section", "entity": "Task", "fields": ["title", "status"], "submitEvent": "SAVE", "cancelEvent": "CANCEL" }]]
|
|
2218
2791
|
},
|
|
2219
|
-
{
|
|
2220
|
-
"from": "Browsing", "to": "Viewing", "event": "VIEW",
|
|
2221
|
-
"effects": [["render-ui", "drawer", { "type": "entity-detail", "entity": "Task", "actions": [{ "label": "Edit", "event": "EDIT" }, { "label": "Delete", "event": "DELETE", "variant": "danger" }] }]]
|
|
2222
|
-
},
|
|
2223
|
-
{
|
|
2224
|
-
"from": "Browsing", "to": "Editing", "event": "EDIT",
|
|
2225
|
-
"effects": [["render-ui", "modal", { "type": "form-section", "entity": "Task", "fields": ["title", "status"], "submitEvent": "SAVE", "cancelEvent": "CANCEL" }]]
|
|
2226
|
-
},
|
|
2227
|
-
{
|
|
2228
|
-
"from": "Browsing", "to": "Deleting", "event": "DELETE",
|
|
2229
|
-
"effects": [["render-ui", "overlay", { "type": "confirmation", "title": "Delete Task?", "message": "This action cannot be undone." }]]
|
|
2230
|
-
},
|
|
2231
2792
|
{
|
|
2232
2793
|
"from": "Creating", "to": "Browsing", "event": "SAVE",
|
|
2233
2794
|
"effects": [["persist", "create", "Task", "@payload.data"], ["render-ui", "modal", null], ["emit", "INIT"]]
|
|
@@ -2235,15 +2796,7 @@ function getMinimalExample() {
|
|
|
2235
2796
|
{
|
|
2236
2797
|
"from": "Creating", "to": "Browsing", "event": "CANCEL",
|
|
2237
2798
|
"effects": [["render-ui", "modal", null]]
|
|
2238
|
-
}
|
|
2239
|
-
{
|
|
2240
|
-
"from": "Viewing", "to": "Browsing", "event": "CANCEL",
|
|
2241
|
-
"effects": [["render-ui", "drawer", null]]
|
|
2242
|
-
},
|
|
2243
|
-
{
|
|
2244
|
-
"from": "Editing", "to": "Browsing", "event": "SAVE",
|
|
2245
|
-
"effects": [["persist", "update", "Task", "@payload.data"], ["render-ui", "modal", null], ["emit", "INIT"]]
|
|
2246
|
-
},
|
|
2799
|
+
}
|
|
2247
2800
|
{
|
|
2248
2801
|
"from": "Editing", "to": "Browsing", "event": "CANCEL",
|
|
2249
2802
|
"effects": [["render-ui", "modal", null]]
|
|
@@ -2259,24 +2812,35 @@ function getMinimalExample() {
|
|
|
2259
2812
|
]
|
|
2260
2813
|
}
|
|
2261
2814
|
}],
|
|
2262
|
-
"pages": [{
|
|
2815
|
+
"pages": [{
|
|
2816
|
+
"name": "TasksPage",
|
|
2817
|
+
"path": "/tasks",
|
|
2818
|
+
"viewType": "list",
|
|
2819
|
+
"isInitial": true,
|
|
2820
|
+
"entity": "Task",
|
|
2821
|
+
"traits": [{ "ref": "TaskInteraction" }]
|
|
2822
|
+
}],
|
|
2823
|
+
"emits": [],
|
|
2824
|
+
"listens": []
|
|
2263
2825
|
}]
|
|
2264
2826
|
}
|
|
2265
2827
|
\`\`\`
|
|
2266
2828
|
|
|
2267
|
-
**Key points**:
|
|
2268
|
-
-
|
|
2269
|
-
-
|
|
2270
|
-
-
|
|
2271
|
-
- **
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
-
|
|
2279
|
-
-
|
|
2829
|
+
**Key points \u2014 Atomic Composition**:
|
|
2830
|
+
- **INIT uses a SINGLE \`render-ui\` call** with a top-level \`stack\` containing composed \`children\`
|
|
2831
|
+
- **3 sections composed**: header (HStack: title + button), metrics (HStack of Box stat cards), data (entity-table)
|
|
2832
|
+
- **Atoms used**: \`typography\` (h1, h2, caption), \`badge\` (status indicators), \`button\` (actions)
|
|
2833
|
+
- **Layout used**: \`stack\` (vertical page, horizontal rows), \`box\` (stat cards)
|
|
2834
|
+
- **Organism used**: \`entity-table\` with searchable + itemActions
|
|
2835
|
+
- **Theme variables**: All colors use \`var(--color-*)\`, spacing uses \`var(--spacing-*)\`, radius uses \`var(--radius-*)\`
|
|
2836
|
+
|
|
2837
|
+
**Validation Rules** (MANDATORY):
|
|
2838
|
+
- Events: \`{ "key": "INIT", "name": "Initialize" }\` \u2014 NOT \`"INIT"\`
|
|
2839
|
+
- Emits: \`[{ "event": "INIT", "scope": "internal" }]\` \u2014 NOT \`["INIT"]\`
|
|
2840
|
+
- Payload events MUST declare payload: \`{ "key": "SAVE", "payload": [{ "name": "data", "type": "object" }] }\`
|
|
2841
|
+
- Page traits: \`{ "ref": "TaskInteraction" }\` \u2014 NOT with linkedEntity
|
|
2842
|
+
- Props: \`submitEvent\` (not \`onSubmit\`), \`actions\` (not \`headerActions\`), \`fields\` (not \`fieldNames\`)
|
|
2843
|
+
- Theme: All visual properties use CSS variables
|
|
2280
2844
|
`;
|
|
2281
2845
|
}
|
|
2282
2846
|
|
|
@@ -2285,9 +2849,9 @@ function generateKflowOrbitalsSkill(compact = false) {
|
|
|
2285
2849
|
const frontmatter = {
|
|
2286
2850
|
name: "kflow-orbitals",
|
|
2287
2851
|
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.",
|
|
2288
|
-
allowedTools: ["Read", "Write", "Edit", "generate_orbital", "
|
|
2289
|
-
version: "
|
|
2290
|
-
//
|
|
2852
|
+
allowedTools: ["Read", "Write", "Edit", "generate_orbital", "finish_task", "query_schema_structure", "extract_chunk", "apply_chunk"],
|
|
2853
|
+
version: "5.0.0"
|
|
2854
|
+
// v5.0: atomic composition (removed design_transition, single-pass design)
|
|
2291
2855
|
};
|
|
2292
2856
|
const content = generateLeanOrbitalSkill({
|
|
2293
2857
|
includeExample: true,
|
|
@@ -2608,7 +3172,7 @@ Output the complete updated domain language text.
|
|
|
2608
3172
|
2. **Follow naming conventions** - PascalCase for entities/pages, camelCase for fields
|
|
2609
3173
|
3. **Include all required fields** - Every entity needs at least one field
|
|
2610
3174
|
4. **Define page paths** - Use RESTful URL patterns
|
|
2611
|
-
5. **Match patterns to view types** - list\u2192entity-list, detail\
|
|
3175
|
+
5. **Match patterns to view types** - list\u2192entity-list/entity-table, detail\u2192detail-panel, create/edit\u2192form-section
|
|
2612
3176
|
`.trim();
|
|
2613
3177
|
return {
|
|
2614
3178
|
name: "domain-language",
|
|
@@ -2616,353 +3180,6 @@ Output the complete updated domain language text.
|
|
|
2616
3180
|
content
|
|
2617
3181
|
};
|
|
2618
3182
|
}
|
|
2619
|
-
function getMinimalTypeReference() {
|
|
2620
|
-
return `
|
|
2621
|
-
## Orbital Schema Structure
|
|
2622
|
-
|
|
2623
|
-
\`\`\`typescript
|
|
2624
|
-
interface OrbitalDefinition {
|
|
2625
|
-
name: string; // Entity name (PascalCase)
|
|
2626
|
-
entity: Entity; // Data model
|
|
2627
|
-
traits: TraitRef[]; // State machines (names or definitions)
|
|
2628
|
-
pages: Page[]; // Routes and views
|
|
2629
|
-
emits?: string[]; // Events this orbital emits
|
|
2630
|
-
listens?: EventListener[]; // Events this orbital listens to
|
|
2631
|
-
}
|
|
2632
|
-
\`\`\`
|
|
2633
|
-
|
|
2634
|
-
### Entity Fields
|
|
2635
|
-
|
|
2636
|
-
\`\`\`typescript
|
|
2637
|
-
{ name: "title", type: "string", required: true }
|
|
2638
|
-
{ name: "count", type: "number", default: 0 }
|
|
2639
|
-
{ name: "status", type: "enum", values: ["pending", "active", "done"] }
|
|
2640
|
-
{ name: "dueDate", type: "date" }
|
|
2641
|
-
\`\`\`
|
|
2642
|
-
|
|
2643
|
-
### Trait State Machine
|
|
2644
|
-
|
|
2645
|
-
\`\`\`typescript
|
|
2646
|
-
{
|
|
2647
|
-
states: [{ name: "Idle", isInitial: true }, { name: "Active" }],
|
|
2648
|
-
events: ["INIT", "ACTIVATE", "COMPLETE"],
|
|
2649
|
-
transitions: [
|
|
2650
|
-
{ from: "Idle", to: "Active", event: "ACTIVATE",
|
|
2651
|
-
guards: [["condition"]],
|
|
2652
|
-
effects: [["action"]] }
|
|
2653
|
-
]
|
|
2654
|
-
}
|
|
2655
|
-
\`\`\`
|
|
2656
|
-
`.trim();
|
|
2657
|
-
}
|
|
2658
|
-
function getPatternTypesCompact() {
|
|
2659
|
-
const patterns = getAllPatternTypes();
|
|
2660
|
-
return `
|
|
2661
|
-
## Available Pattern Types
|
|
2662
|
-
|
|
2663
|
-
${patterns.map((p) => `- \`${p}\``).join("\n")}
|
|
2664
|
-
|
|
2665
|
-
${getPatternPropsCompact()}
|
|
2666
|
-
`.trim();
|
|
2667
|
-
}
|
|
2668
|
-
function getSExprQuickRef2() {
|
|
2669
|
-
const operators = Object.keys(OPERATORS).slice(0, 15);
|
|
2670
|
-
return `
|
|
2671
|
-
## S-Expression Quick Reference
|
|
2672
|
-
|
|
2673
|
-
### Guard Expressions (Conditions)
|
|
2674
|
-
|
|
2675
|
-
\`\`\`typescript
|
|
2676
|
-
["=", "@entity.status", "active"] // Equality
|
|
2677
|
-
[">", "@entity.count", 0] // Greater than
|
|
2678
|
-
["and", ["cond1"], ["cond2"]] // Logical AND
|
|
2679
|
-
["or", ["cond1"], ["cond2"]] // Logical OR
|
|
2680
|
-
["not", ["condition"]] // Logical NOT
|
|
2681
|
-
\`\`\`
|
|
2682
|
-
|
|
2683
|
-
### Effect Expressions (Actions)
|
|
2684
|
-
|
|
2685
|
-
\`\`\`typescript
|
|
2686
|
-
["set", "@entity.field", value] // Update field
|
|
2687
|
-
["emit", "EVENT_NAME", payload] // Emit event
|
|
2688
|
-
["navigate", "/path"] // Navigate to route
|
|
2689
|
-
["render-ui", "main", { type, props }] // Render pattern
|
|
2690
|
-
["persist", "create", "Entity", data] // Database operation
|
|
2691
|
-
\`\`\`
|
|
2692
|
-
|
|
2693
|
-
### Available Operators
|
|
2694
|
-
|
|
2695
|
-
${operators.map((op) => `- \`${op}\``).join("\n")}
|
|
2696
|
-
`.trim();
|
|
2697
|
-
}
|
|
2698
|
-
function getRenderUIQuickRef2() {
|
|
2699
|
-
const slots = UI_SLOTS;
|
|
2700
|
-
return `
|
|
2701
|
-
## Render-UI Effect Reference
|
|
2702
|
-
|
|
2703
|
-
### Syntax
|
|
2704
|
-
|
|
2705
|
-
\`\`\`typescript
|
|
2706
|
-
["render-ui", slot, patternConfig | null]
|
|
2707
|
-
\`\`\`
|
|
2708
|
-
|
|
2709
|
-
### UI Slots
|
|
2710
|
-
|
|
2711
|
-
${slots.map((slot) => `- \`${slot}\``).join("\n")}
|
|
2712
|
-
|
|
2713
|
-
### Example
|
|
2714
|
-
|
|
2715
|
-
\`\`\`typescript
|
|
2716
|
-
["render-ui", "main", {
|
|
2717
|
-
type: "entity-table",
|
|
2718
|
-
entity: "Task",
|
|
2719
|
-
columns: ["title", "status"],
|
|
2720
|
-
itemActions: [{ label: "Edit", event: "EDIT" }]
|
|
2721
|
-
}]
|
|
2722
|
-
\`\`\`
|
|
2723
|
-
|
|
2724
|
-
Clear slot: \`["render-ui", "modal", null]\`
|
|
2725
|
-
`.trim();
|
|
2726
|
-
}
|
|
2727
|
-
function getFieldTypesCompact() {
|
|
2728
|
-
return `
|
|
2729
|
-
## Field Types
|
|
2730
|
-
|
|
2731
|
-
| Type | Example | Notes |
|
|
2732
|
-
|------|---------|-------|
|
|
2733
|
-
| \`string\` | \`{ name: "title", type: "string" }\` | Text |
|
|
2734
|
-
| \`number\` | \`{ name: "count", type: "number" }\` | Integer or float |
|
|
2735
|
-
| \`boolean\` | \`{ name: "active", type: "boolean" }\` | true/false |
|
|
2736
|
-
| \`date\` | \`{ name: "birthday", type: "date" }\` | Date only |
|
|
2737
|
-
| \`timestamp\` | \`{ name: "createdAt", type: "timestamp" }\` | Date + time |
|
|
2738
|
-
| \`enum\` | \`{ name: "status", type: "enum", values: ["a", "b"] }\` | Fixed options |
|
|
2739
|
-
| \`array\` | \`{ name: "tags", type: "array", items: "string" }\` | List |
|
|
2740
|
-
| \`relation\` | \`{ name: "user", type: "relation", relation: { entity: "User", cardinality: "one" } }\` | Foreign key |
|
|
2741
|
-
|
|
2742
|
-
### Field Properties
|
|
2743
|
-
|
|
2744
|
-
- \`required: true\` - Must have value
|
|
2745
|
-
- \`default: value\` - Default value
|
|
2746
|
-
- \`unique: true\` - Must be unique
|
|
2747
|
-
`.trim();
|
|
2748
|
-
}
|
|
2749
|
-
|
|
2750
|
-
// src/generators/kflow-design.ts
|
|
2751
|
-
function getTransitionContextGuide() {
|
|
2752
|
-
return `## Transition Context
|
|
2753
|
-
|
|
2754
|
-
You receive a single transition to design. Use these inputs to make UI decisions:
|
|
2755
|
-
|
|
2756
|
-
### Input Fields
|
|
2757
|
-
| Field | What It Tells You |
|
|
2758
|
-
|-------|-------------------|
|
|
2759
|
-
| \`from\` | Current state (e.g., "Browsing", "Creating") |
|
|
2760
|
-
| \`to\` | Target state (e.g., "Browsing", "Viewing") |
|
|
2761
|
-
| \`event\` | What the user did (e.g., "INIT", "CREATE", "VIEW") |
|
|
2762
|
-
| \`currentSlot\` | Which slot to render into (\`main\`, \`modal\`, \`drawer\`) |
|
|
2763
|
-
| \`entity\` | Entity name + fields (drives column/field selection) |
|
|
2764
|
-
| \`designHints\` | Style + UX hints from decomposition |
|
|
2765
|
-
| \`domainContext\` | Category + vocabulary (drives pattern choice) |
|
|
2766
|
-
| \`existingEffects\` | Current render-ui effects (if enhancing) |
|
|
2767
|
-
|
|
2768
|
-
### Decision Flow
|
|
2769
|
-
|
|
2770
|
-
\`\`\`
|
|
2771
|
-
1. What EVENT is this?
|
|
2772
|
-
\u251C\u2500 INIT \u2192 Compose full page layout (header + content + data)
|
|
2773
|
-
\u251C\u2500 CREATE/EDIT \u2192 Form in modal or drawer
|
|
2774
|
-
\u251C\u2500 VIEW \u2192 Detail in drawer or inline
|
|
2775
|
-
\u251C\u2500 DELETE \u2192 Confirmation in overlay
|
|
2776
|
-
\u2514\u2500 SAVE/CANCEL \u2192 Clear slot (return null)
|
|
2777
|
-
|
|
2778
|
-
2. What SLOT?
|
|
2779
|
-
\u251C\u2500 main \u2192 Compose multiple patterns (stack them)
|
|
2780
|
-
\u251C\u2500 modal \u2192 Single form or confirmation
|
|
2781
|
-
\u251C\u2500 drawer \u2192 Detail view or quick edit form
|
|
2782
|
-
\u2514\u2500 overlay \u2192 Confirmation dialog
|
|
2783
|
-
|
|
2784
|
-
3. What DOMAIN?
|
|
2785
|
-
\u251C\u2500 business \u2192 entity-table + stats + filter-group
|
|
2786
|
-
\u251C\u2500 dashboard \u2192 dashboard-grid + chart + stats
|
|
2787
|
-
\u251C\u2500 ecommerce \u2192 entity-cards + stats (revenue)
|
|
2788
|
-
\u251C\u2500 content \u2192 entity-cards + tabs + media
|
|
2789
|
-
\u2514\u2500 workflow \u2192 timeline + progress-bar
|
|
2790
|
-
|
|
2791
|
-
4. What ENTITY FIELDS suggest?
|
|
2792
|
-
\u251C\u2500 enum fields \u2192 filter-group, badge columns
|
|
2793
|
-
\u251C\u2500 date fields \u2192 timeline, date columns
|
|
2794
|
-
\u251C\u2500 number fields \u2192 stats, chart, meter
|
|
2795
|
-
\u251C\u2500 relation fields \u2192 tabs for related collections
|
|
2796
|
-
\u2514\u2500 image/url fields \u2192 entity-cards (visual)
|
|
2797
|
-
\`\`\``;
|
|
2798
|
-
}
|
|
2799
|
-
function getLayoutCompositionGuide() {
|
|
2800
|
-
return `## Layout Composition
|
|
2801
|
-
|
|
2802
|
-
Use layout patterns to create structured, visually rich views.
|
|
2803
|
-
|
|
2804
|
-
### Stack (VStack / HStack)
|
|
2805
|
-
\`{ "type": "stack", "direction": "vertical"|"horizontal", "gap": "sm"|"md"|"lg", "children": [...] }\`
|
|
2806
|
-
|
|
2807
|
-
### Box (Styled Container)
|
|
2808
|
-
\`{ "type": "box", "padding": "md", "bg": "card", "border": true, "rounded": "md", "children": [...] }\`
|
|
2809
|
-
|
|
2810
|
-
### Grid (Multi-Column)
|
|
2811
|
-
\`{ "type": "grid", "cols": 3, "gap": "md", "children": [...] }\`
|
|
2812
|
-
|
|
2813
|
-
### Composition Patterns
|
|
2814
|
-
|
|
2815
|
-
**Page Layout** \u2014 VStack wrapping all content:
|
|
2816
|
-
\`\`\`json
|
|
2817
|
-
["render-ui", "main", {
|
|
2818
|
-
"type": "stack", "direction": "vertical", "gap": "lg",
|
|
2819
|
-
"children": [
|
|
2820
|
-
{ "type": "page-header", "title": "...", "actions": [...] },
|
|
2821
|
-
{ "type": "stack", "direction": "horizontal", "gap": "md", "wrap": true,
|
|
2822
|
-
"children": [
|
|
2823
|
-
{ "type": "box", "padding": "md", "bg": "card", "border": true, "rounded": "md",
|
|
2824
|
-
"children": [{ "type": "stats", "metrics": [...] }] },
|
|
2825
|
-
{ "type": "box", "padding": "md", "bg": "card", "border": true, "rounded": "md",
|
|
2826
|
-
"children": [{ "type": "stats", "metrics": [...] }] }
|
|
2827
|
-
]
|
|
2828
|
-
},
|
|
2829
|
-
{ "type": "entity-table", "entity": "...", "columns": [...], "searchable": true }
|
|
2830
|
-
]
|
|
2831
|
-
}]
|
|
2832
|
-
\`\`\`
|
|
2833
|
-
|
|
2834
|
-
**Dashboard Layout** \u2014 Grid of cards:
|
|
2835
|
-
\`\`\`json
|
|
2836
|
-
["render-ui", "main", {
|
|
2837
|
-
"type": "stack", "direction": "vertical", "gap": "lg",
|
|
2838
|
-
"children": [
|
|
2839
|
-
{ "type": "page-header", "title": "Dashboard" },
|
|
2840
|
-
{ "type": "grid", "cols": { "sm": 1, "md": 2, "lg": 3 }, "gap": "md",
|
|
2841
|
-
"children": [
|
|
2842
|
-
{ "type": "box", "padding": "lg", "bg": "card", "border": true, "rounded": "md",
|
|
2843
|
-
"children": [{ "type": "stats", "metrics": [...] }] },
|
|
2844
|
-
{ "type": "box", "padding": "lg", "bg": "card", "border": true, "rounded": "md",
|
|
2845
|
-
"children": [{ "type": "chart", "chartType": "line", "data": [...] }] },
|
|
2846
|
-
{ "type": "box", "padding": "lg", "bg": "card", "border": true, "rounded": "md",
|
|
2847
|
-
"children": [{ "type": "entity-cards", "entity": "...", "columns": 1 }] }
|
|
2848
|
-
]
|
|
2849
|
-
}
|
|
2850
|
-
]
|
|
2851
|
-
}]
|
|
2852
|
-
\`\`\`
|
|
2853
|
-
|
|
2854
|
-
**Detail Drawer** \u2014 Stacked sections:
|
|
2855
|
-
\`\`\`json
|
|
2856
|
-
["render-ui", "drawer", {
|
|
2857
|
-
"type": "stack", "direction": "vertical", "gap": "md",
|
|
2858
|
-
"children": [
|
|
2859
|
-
{ "type": "entity-detail", "entity": "...", "actions": [{ "label": "Edit", "event": "EDIT" }] },
|
|
2860
|
-
{ "type": "tabs", "tabs": [
|
|
2861
|
-
{ "label": "Related Items", "content": { "type": "entity-table", "entity": "..." } },
|
|
2862
|
-
{ "label": "Activity", "content": { "type": "timeline", "items": [...] } }
|
|
2863
|
-
]}
|
|
2864
|
-
]
|
|
2865
|
-
}]
|
|
2866
|
-
\`\`\`
|
|
2867
|
-
|
|
2868
|
-
### When to Use Layout vs Flat
|
|
2869
|
-
- **Flat** (multiple render-ui calls): Simple pages, 2-3 patterns stacked vertically
|
|
2870
|
-
- **Nested** (single render-ui with layout): Complex pages, side-by-side elements, cards with backgrounds, dashboard grids`;
|
|
2871
|
-
}
|
|
2872
|
-
function getOutputFormatSection() {
|
|
2873
|
-
return `## Output Format
|
|
2874
|
-
|
|
2875
|
-
Return ONLY a JSON array of render-ui effect tuples. No explanation, no markdown.
|
|
2876
|
-
|
|
2877
|
-
### Simple (multiple flat effects):
|
|
2878
|
-
\`\`\`json
|
|
2879
|
-
[
|
|
2880
|
-
["render-ui", "main", { "type": "page-header", "title": "...", "actions": [...] }],
|
|
2881
|
-
["render-ui", "main", { "type": "stats", "entity": "...", "metrics": [...] }],
|
|
2882
|
-
["render-ui", "main", { "type": "entity-table", "entity": "...", "columns": [...] }]
|
|
2883
|
-
]
|
|
2884
|
-
\`\`\`
|
|
2885
|
-
|
|
2886
|
-
### Composed (single effect with layout nesting):
|
|
2887
|
-
\`\`\`json
|
|
2888
|
-
[
|
|
2889
|
-
["render-ui", "main", { "type": "stack", "direction": "vertical", "gap": "lg", "children": [...] }]
|
|
2890
|
-
]
|
|
2891
|
-
\`\`\`
|
|
2892
|
-
|
|
2893
|
-
### Clear slot:
|
|
2894
|
-
\`\`\`json
|
|
2895
|
-
[
|
|
2896
|
-
["render-ui", "modal", null]
|
|
2897
|
-
]
|
|
2898
|
-
\`\`\`
|
|
2899
|
-
|
|
2900
|
-
### Rules
|
|
2901
|
-
1. Return valid JSON array \u2014 nothing else
|
|
2902
|
-
2. Every effect must be \`["render-ui", slot, config]\`
|
|
2903
|
-
3. Use entity fields from the input for columns, form fields, stats
|
|
2904
|
-
4. Match domain vocabulary for labels (e.g., "Place Order" not "Create")
|
|
2905
|
-
5. Include \`itemActions\` on tables/cards with appropriate events
|
|
2906
|
-
6. Use \`searchable: true\` on tables for business domains
|
|
2907
|
-
7. For INIT transitions, ALWAYS compose multiple patterns (never just a table)
|
|
2908
|
-
8. For CREATE/EDIT, always include \`submitEvent\` and \`cancelEvent\` on form-section`;
|
|
2909
|
-
}
|
|
2910
|
-
function generateKflowDesignSkill() {
|
|
2911
|
-
const frontmatter = {
|
|
2912
|
-
name: "kflow-design",
|
|
2913
|
-
description: "Design rich render-ui effects for orbital schema transitions. Focused on pattern selection, layout composition, and domain-aware UI authoring.",
|
|
2914
|
-
allowedTools: ["Read", "Write", "Edit"],
|
|
2915
|
-
version: "1.0.0"
|
|
2916
|
-
};
|
|
2917
|
-
const content = `# Render-UI Design Skill
|
|
2918
|
-
|
|
2919
|
-
> Design rich, polished render-ui effects for orbital schema transitions.
|
|
2920
|
-
|
|
2921
|
-
You are a UI design specialist for KFlow orbital schemas. Your job is to take a
|
|
2922
|
-
transition context (state, event, entity, domain) and produce the best possible
|
|
2923
|
-
render-ui effects using the full pattern catalog.
|
|
2924
|
-
|
|
2925
|
-
**Your goal**: Every transition should produce UI that is visually rich, functionally
|
|
2926
|
-
complete, and domain-appropriate. Never default to just "entity-table" \u2014 compose
|
|
2927
|
-
layouts with headers, stats, filters, and appropriate patterns.
|
|
2928
|
-
|
|
2929
|
-
---
|
|
2930
|
-
|
|
2931
|
-
${getTransitionContextGuide()}
|
|
2932
|
-
|
|
2933
|
-
---
|
|
2934
|
-
|
|
2935
|
-
${getRenderUIDesignGuide()}
|
|
2936
|
-
|
|
2937
|
-
---
|
|
2938
|
-
|
|
2939
|
-
${getLayoutCompositionGuide()}
|
|
2940
|
-
|
|
2941
|
-
---
|
|
2942
|
-
|
|
2943
|
-
${getSExprQuickRef2()}
|
|
2944
|
-
|
|
2945
|
-
---
|
|
2946
|
-
|
|
2947
|
-
${getCommonErrorsSection("top6")}
|
|
2948
|
-
|
|
2949
|
-
---
|
|
2950
|
-
|
|
2951
|
-
${getOutputFormatSection()}
|
|
2952
|
-
`;
|
|
2953
|
-
return {
|
|
2954
|
-
name: "kflow-design",
|
|
2955
|
-
frontmatter,
|
|
2956
|
-
content
|
|
2957
|
-
};
|
|
2958
|
-
}
|
|
2959
|
-
function getDesignSkillStats() {
|
|
2960
|
-
const skill = generateKflowDesignSkill();
|
|
2961
|
-
return {
|
|
2962
|
-
lines: skill.content.split("\n").length,
|
|
2963
|
-
chars: skill.content.length
|
|
2964
|
-
};
|
|
2965
|
-
}
|
|
2966
3183
|
|
|
2967
3184
|
// src/orbitals-skills-generators/lean/lean-orbital-generator.ts
|
|
2968
3185
|
var LEAN_CORE_INSTRUCTIONS = `
|
|
@@ -3168,7 +3385,7 @@ The tools handle proper prompting, caching, and S-Expression syntax. Writing dir
|
|
|
3168
3385
|
{ "name": "TasksPage", "path": "/tasks", "viewType": "list", "isInitial": true }
|
|
3169
3386
|
],
|
|
3170
3387
|
"traits": ["TaskManager"],
|
|
3171
|
-
"patterns": ["page-header", "entity-table", "form-section", "
|
|
3388
|
+
"patterns": ["page-header", "entity-table", "form-section", "detail-panel"]
|
|
3172
3389
|
}
|
|
3173
3390
|
\`\`\`
|
|
3174
3391
|
|
|
@@ -3265,7 +3482,7 @@ TaskManager behavior:
|
|
|
3265
3482
|
then ["render-ui", "modal", null]
|
|
3266
3483
|
|
|
3267
3484
|
- From Browsing to Viewing on VIEW
|
|
3268
|
-
then ["render-ui", "drawer", {"type": "
|
|
3485
|
+
then ["render-ui", "drawer", {"type": "detail-panel", "entity": "Task", "fields": ["title", "description", "status", "priority", "dueDate"], "actions": [{"label": "Edit", "event": "EDIT"}, {"label": "Delete", "event": "DELETE", "variant": "danger"}]}]
|
|
3269
3486
|
|
|
3270
3487
|
- From Viewing to Editing on EDIT
|
|
3271
3488
|
then ["render-ui", "drawer", null]
|
|
@@ -3559,10 +3776,139 @@ function generateAllBuilderSkills() {
|
|
|
3559
3776
|
},
|
|
3560
3777
|
content: generateLeanFixingSkill2()
|
|
3561
3778
|
},
|
|
3562
|
-
generateDomainLanguageSkill()
|
|
3563
|
-
generateKflowDesignSkill()
|
|
3779
|
+
generateDomainLanguageSkill()
|
|
3564
3780
|
];
|
|
3565
3781
|
}
|
|
3782
|
+
function getMinimalTypeReference() {
|
|
3783
|
+
return `
|
|
3784
|
+
## Orbital Schema Structure
|
|
3785
|
+
|
|
3786
|
+
\`\`\`typescript
|
|
3787
|
+
interface OrbitalDefinition {
|
|
3788
|
+
name: string; // Entity name (PascalCase)
|
|
3789
|
+
entity: Entity; // Data model
|
|
3790
|
+
traits: TraitRef[]; // State machines (names or definitions)
|
|
3791
|
+
pages: Page[]; // Routes and views
|
|
3792
|
+
emits?: string[]; // Events this orbital emits
|
|
3793
|
+
listens?: EventListener[]; // Events this orbital listens to
|
|
3794
|
+
}
|
|
3795
|
+
\`\`\`
|
|
3796
|
+
|
|
3797
|
+
### Entity Fields
|
|
3798
|
+
|
|
3799
|
+
\`\`\`typescript
|
|
3800
|
+
{ name: "title", type: "string", required: true }
|
|
3801
|
+
{ name: "count", type: "number", default: 0 }
|
|
3802
|
+
{ name: "status", type: "enum", values: ["pending", "active", "done"] }
|
|
3803
|
+
{ name: "dueDate", type: "date" }
|
|
3804
|
+
\`\`\`
|
|
3805
|
+
|
|
3806
|
+
### Trait State Machine
|
|
3807
|
+
|
|
3808
|
+
\`\`\`typescript
|
|
3809
|
+
{
|
|
3810
|
+
states: [{ name: "Idle", isInitial: true }, { name: "Active" }],
|
|
3811
|
+
events: ["INIT", "ACTIVATE", "COMPLETE"],
|
|
3812
|
+
transitions: [
|
|
3813
|
+
{ from: "Idle", to: "Active", event: "ACTIVATE",
|
|
3814
|
+
guards: [["condition"]],
|
|
3815
|
+
effects: [["action"]] }
|
|
3816
|
+
]
|
|
3817
|
+
}
|
|
3818
|
+
\`\`\`
|
|
3819
|
+
`.trim();
|
|
3820
|
+
}
|
|
3821
|
+
function getPatternTypesCompact() {
|
|
3822
|
+
const patterns = getAllPatternTypes();
|
|
3823
|
+
return `
|
|
3824
|
+
## Available Pattern Types
|
|
3825
|
+
|
|
3826
|
+
${patterns.map((p) => `- \`${p}\``).join("\n")}
|
|
3827
|
+
|
|
3828
|
+
${getPatternPropsCompact()}
|
|
3829
|
+
`.trim();
|
|
3830
|
+
}
|
|
3831
|
+
function getSExprQuickRef2() {
|
|
3832
|
+
const operators = Object.keys(OPERATORS).slice(0, 15);
|
|
3833
|
+
return `
|
|
3834
|
+
## S-Expression Quick Reference
|
|
3835
|
+
|
|
3836
|
+
### Guard Expressions (Conditions)
|
|
3837
|
+
|
|
3838
|
+
\`\`\`typescript
|
|
3839
|
+
["=", "@entity.status", "active"] // Equality
|
|
3840
|
+
[">", "@entity.count", 0] // Greater than
|
|
3841
|
+
["and", ["cond1"], ["cond2"]] // Logical AND
|
|
3842
|
+
["or", ["cond1"], ["cond2"]] // Logical OR
|
|
3843
|
+
["not", ["condition"]] // Logical NOT
|
|
3844
|
+
\`\`\`
|
|
3845
|
+
|
|
3846
|
+
### Effect Expressions (Actions)
|
|
3847
|
+
|
|
3848
|
+
\`\`\`typescript
|
|
3849
|
+
["set", "@entity.field", value] // Update field
|
|
3850
|
+
["emit", "EVENT_NAME", payload] // Emit event
|
|
3851
|
+
["navigate", "/path"] // Navigate to route
|
|
3852
|
+
["render-ui", "main", { type, props }] // Render pattern
|
|
3853
|
+
["persist", "create", "Entity", data] // Database operation
|
|
3854
|
+
\`\`\`
|
|
3855
|
+
|
|
3856
|
+
### Available Operators
|
|
3857
|
+
|
|
3858
|
+
${operators.map((op) => `- \`${op}\``).join("\n")}
|
|
3859
|
+
`.trim();
|
|
3860
|
+
}
|
|
3861
|
+
function getRenderUIQuickRef2() {
|
|
3862
|
+
const slots = UI_SLOTS;
|
|
3863
|
+
return `
|
|
3864
|
+
## Render-UI Effect Reference
|
|
3865
|
+
|
|
3866
|
+
### Syntax
|
|
3867
|
+
|
|
3868
|
+
\`\`\`typescript
|
|
3869
|
+
["render-ui", slot, patternConfig | null]
|
|
3870
|
+
\`\`\`
|
|
3871
|
+
|
|
3872
|
+
### UI Slots
|
|
3873
|
+
|
|
3874
|
+
${slots.map((slot) => `- \`${slot}\``).join("\n")}
|
|
3875
|
+
|
|
3876
|
+
### Example
|
|
3877
|
+
|
|
3878
|
+
\`\`\`typescript
|
|
3879
|
+
["render-ui", "main", {
|
|
3880
|
+
type: "entity-table",
|
|
3881
|
+
entity: "Task",
|
|
3882
|
+
columns: ["title", "status"],
|
|
3883
|
+
itemActions: [{ label: "Edit", event: "EDIT" }]
|
|
3884
|
+
}]
|
|
3885
|
+
\`\`\`
|
|
3886
|
+
|
|
3887
|
+
Clear slot: \`["render-ui", "modal", null]\`
|
|
3888
|
+
`.trim();
|
|
3889
|
+
}
|
|
3890
|
+
function getFieldTypesCompact() {
|
|
3891
|
+
return `
|
|
3892
|
+
## Field Types
|
|
3893
|
+
|
|
3894
|
+
| Type | Example | Notes |
|
|
3895
|
+
|------|---------|-------|
|
|
3896
|
+
| \`string\` | \`{ name: "title", type: "string" }\` | Text |
|
|
3897
|
+
| \`number\` | \`{ name: "count", type: "number" }\` | Integer or float |
|
|
3898
|
+
| \`boolean\` | \`{ name: "active", type: "boolean" }\` | true/false |
|
|
3899
|
+
| \`date\` | \`{ name: "birthday", type: "date" }\` | Date only |
|
|
3900
|
+
| \`timestamp\` | \`{ name: "createdAt", type: "timestamp" }\` | Date + time |
|
|
3901
|
+
| \`enum\` | \`{ name: "status", type: "enum", values: ["a", "b"] }\` | Fixed options |
|
|
3902
|
+
| \`array\` | \`{ name: "tags", type: "array", items: "string" }\` | List |
|
|
3903
|
+
| \`relation\` | \`{ name: "user", type: "relation", relation: { entity: "User", cardinality: "one" } }\` | Foreign key |
|
|
3904
|
+
|
|
3905
|
+
### Field Properties
|
|
3906
|
+
|
|
3907
|
+
- \`required: true\` - Must have value
|
|
3908
|
+
- \`default: value\` - Default value
|
|
3909
|
+
- \`unique: true\` - Must be unique
|
|
3910
|
+
`.trim();
|
|
3911
|
+
}
|
|
3566
3912
|
|
|
3567
3913
|
// src/prompts/generation-prompts.ts
|
|
3568
3914
|
function getOrbitalDecompositionPrompt() {
|
|
@@ -3736,6 +4082,316 @@ Use with: \`uses: [{ from: "std/behaviors/crud", as: "CRUD" }]\`
|
|
|
3736
4082
|
`;
|
|
3737
4083
|
}
|
|
3738
4084
|
|
|
3739
|
-
|
|
4085
|
+
// src/evals/composition-quality.ts
|
|
4086
|
+
var EVAL_CASES = [
|
|
4087
|
+
{
|
|
4088
|
+
name: "task-management-basic",
|
|
4089
|
+
description: "Generate a basic task management view with CRUD",
|
|
4090
|
+
prompt: `Generate an Orbital schema for a task management app.
|
|
4091
|
+
|
|
4092
|
+
Entity: Task with fields: title (string, required), status (enum: pending/active/done), priority (enum: low/medium/high)
|
|
4093
|
+
|
|
4094
|
+
Requirements:
|
|
4095
|
+
- List view with search and actions (view, edit, delete)
|
|
4096
|
+
- Modal form for creating tasks
|
|
4097
|
+
- Use atomic composition with stack layouts
|
|
4098
|
+
- Include stats/overview section showing counts`,
|
|
4099
|
+
expectedPatterns: ["stack", "page-header", "entity-table", "form-section", "box", "typography", "badge", "button"],
|
|
4100
|
+
minScore: 70,
|
|
4101
|
+
domain: "general"
|
|
4102
|
+
},
|
|
4103
|
+
{
|
|
4104
|
+
name: "patient-portal-dashboard",
|
|
4105
|
+
description: "Generate a healthcare patient portal dashboard",
|
|
4106
|
+
prompt: `Generate an Orbital schema for a healthcare patient portal.
|
|
4107
|
+
|
|
4108
|
+
Entities:
|
|
4109
|
+
- Patient: name, dateOfBirth, medicalRecordNumber, insuranceStatus
|
|
4110
|
+
- Appointment: date, time, doctor, status, notes
|
|
4111
|
+
|
|
4112
|
+
Requirements:
|
|
4113
|
+
- Dashboard with patient statistics (total, active, critical)
|
|
4114
|
+
- Patient list with filters by status
|
|
4115
|
+
- Appointment scheduling view
|
|
4116
|
+
- Use healthcare-appropriate layouts (calm, organized)
|
|
4117
|
+
- Include tabs for different views`,
|
|
4118
|
+
expectedPatterns: ["stack", "grid", "page-header", "entity-table", "tabs", "badge", "card", "stats"],
|
|
4119
|
+
minScore: 75,
|
|
4120
|
+
domain: "healthcare"
|
|
4121
|
+
},
|
|
4122
|
+
{
|
|
4123
|
+
name: "ecommerce-product-catalog",
|
|
4124
|
+
description: "Generate an e-commerce product catalog",
|
|
4125
|
+
prompt: `Generate an Orbital schema for an e-commerce product catalog.
|
|
4126
|
+
|
|
4127
|
+
Entities:
|
|
4128
|
+
- Product: name, price, category, stockLevel, rating, imageUrl
|
|
4129
|
+
- Category: name, description
|
|
4130
|
+
|
|
4131
|
+
Requirements:
|
|
4132
|
+
- Product grid with cards (use grid layout)
|
|
4133
|
+
- Filters by category and price range
|
|
4134
|
+
- Product detail view with image
|
|
4135
|
+
- Shopping cart indicator
|
|
4136
|
+
- Use product-appropriate layouts (visual, appealing)`,
|
|
4137
|
+
expectedPatterns: ["stack", "grid", "entity-cards", "filter-group", "badge", "card", "image"],
|
|
4138
|
+
minScore: 75,
|
|
4139
|
+
domain: "ecommerce"
|
|
4140
|
+
},
|
|
4141
|
+
{
|
|
4142
|
+
name: "project-management-kanban",
|
|
4143
|
+
description: "Generate a project management kanban board",
|
|
4144
|
+
prompt: `Generate an Orbital schema for a project management kanban board.
|
|
4145
|
+
|
|
4146
|
+
Entities:
|
|
4147
|
+
- Project: name, status, deadline, progress, owner
|
|
4148
|
+
- Task: title, status (todo/in-progress/done), assignee, priority, dueDate
|
|
4149
|
+
|
|
4150
|
+
Requirements:
|
|
4151
|
+
- Kanban board with columns for each status
|
|
4152
|
+
- Task cards with drag-drop feel (visual design)
|
|
4153
|
+
- Project overview with progress bars
|
|
4154
|
+
- Team member avatars
|
|
4155
|
+
- Due date indicators`,
|
|
4156
|
+
expectedPatterns: ["stack", "grid", "card", "progress-bar", "avatar", "badge", "page-header"],
|
|
4157
|
+
minScore: 80,
|
|
4158
|
+
domain: "project-management"
|
|
4159
|
+
},
|
|
4160
|
+
{
|
|
4161
|
+
name: "analytics-dashboard",
|
|
4162
|
+
description: "Generate an analytics dashboard with charts",
|
|
4163
|
+
prompt: `Generate an Orbital schema for an analytics dashboard.
|
|
4164
|
+
|
|
4165
|
+
Entities:
|
|
4166
|
+
- Metric: name, value, change, trend
|
|
4167
|
+
- Report: title, date, type, status
|
|
4168
|
+
|
|
4169
|
+
Requirements:
|
|
4170
|
+
- Stats cards with trend indicators (up/down)
|
|
4171
|
+
- Chart visualization area
|
|
4172
|
+
- Recent reports list
|
|
4173
|
+
- Date range selector
|
|
4174
|
+
- Professional, data-dense layout`,
|
|
4175
|
+
expectedPatterns: ["stack", "grid", "stats", "chart", "entity-table", "badge", "card"],
|
|
4176
|
+
minScore: 75,
|
|
4177
|
+
domain: "general"
|
|
4178
|
+
}
|
|
4179
|
+
];
|
|
4180
|
+
function analyzeComposition(schema) {
|
|
4181
|
+
const metrics = {
|
|
4182
|
+
renderUICount: 0,
|
|
4183
|
+
atomTypes: [],
|
|
4184
|
+
moleculeTypes: [],
|
|
4185
|
+
organismTypes: [],
|
|
4186
|
+
layoutRoot: null,
|
|
4187
|
+
nestingDepth: 0,
|
|
4188
|
+
sectionCount: 0,
|
|
4189
|
+
themeVariableUsage: 0,
|
|
4190
|
+
hardcodedValues: []
|
|
4191
|
+
};
|
|
4192
|
+
for (const orbital of schema.orbitals) {
|
|
4193
|
+
for (const trait of orbital.traits) {
|
|
4194
|
+
const t = trait;
|
|
4195
|
+
if (!t.stateMachine?.transitions) continue;
|
|
4196
|
+
for (const transition of t.stateMachine.transitions) {
|
|
4197
|
+
if (!transition.effects) continue;
|
|
4198
|
+
for (const effect of transition.effects) {
|
|
4199
|
+
if (!Array.isArray(effect)) continue;
|
|
4200
|
+
if (effect[0] !== "render-ui") continue;
|
|
4201
|
+
metrics.renderUICount++;
|
|
4202
|
+
const pattern = effect[2];
|
|
4203
|
+
if (pattern && typeof pattern === "object") {
|
|
4204
|
+
analyzePattern(pattern, metrics, 0);
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
const totalValues = metrics.atomTypes.length + metrics.moleculeTypes.length + metrics.organismTypes.length;
|
|
4211
|
+
if (totalValues > 0) {
|
|
4212
|
+
metrics.themeVariableUsage = 100 - metrics.hardcodedValues.length / totalValues * 100;
|
|
4213
|
+
}
|
|
4214
|
+
return metrics;
|
|
4215
|
+
}
|
|
4216
|
+
function analyzePattern(pattern, metrics, depth) {
|
|
4217
|
+
if (!pattern || typeof pattern !== "object") return;
|
|
4218
|
+
metrics.nestingDepth = Math.max(metrics.nestingDepth, depth);
|
|
4219
|
+
if (depth === 0 && ["stack", "box", "container", "grid"].includes(pattern.type)) {
|
|
4220
|
+
metrics.layoutRoot = pattern.type;
|
|
4221
|
+
}
|
|
4222
|
+
const atomTypes = ["typography", "badge", "button", "avatar", "icon", "progress-bar", "divider"];
|
|
4223
|
+
const moleculeTypes = ["card", "modal", "drawer", "tabs", "alert", "accordion", "box"];
|
|
4224
|
+
const organismTypes = ["entity-table", "form-section", "detail-panel", "page-header", "chart", "timeline", "stats"];
|
|
4225
|
+
if (atomTypes.includes(pattern.type) && !metrics.atomTypes.includes(pattern.type)) {
|
|
4226
|
+
metrics.atomTypes.push(pattern.type);
|
|
4227
|
+
}
|
|
4228
|
+
if (moleculeTypes.includes(pattern.type) && !metrics.moleculeTypes.includes(pattern.type)) {
|
|
4229
|
+
metrics.moleculeTypes.push(pattern.type);
|
|
4230
|
+
}
|
|
4231
|
+
if (organismTypes.includes(pattern.type) && !metrics.organismTypes.includes(pattern.type)) {
|
|
4232
|
+
metrics.organismTypes.push(pattern.type);
|
|
4233
|
+
}
|
|
4234
|
+
for (const [key, value] of Object.entries(pattern)) {
|
|
4235
|
+
if (typeof value === "string") {
|
|
4236
|
+
if (value.startsWith("#") || /^\d+px$/.test(value) || ["white", "black", "red", "blue"].includes(value.toLowerCase())) {
|
|
4237
|
+
metrics.hardcodedValues.push(`${key}: ${value}`);
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
4241
|
+
if (depth === 1 && pattern.type) {
|
|
4242
|
+
metrics.sectionCount++;
|
|
4243
|
+
}
|
|
4244
|
+
if (pattern.children && Array.isArray(pattern.children)) {
|
|
4245
|
+
for (const child of pattern.children) {
|
|
4246
|
+
analyzePattern(child, metrics, depth + 1);
|
|
4247
|
+
}
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
4250
|
+
function scoreStructure(metrics, schema) {
|
|
4251
|
+
let score = 0;
|
|
4252
|
+
const transitions = countTransitions(schema);
|
|
4253
|
+
if (metrics.renderUICount <= transitions) {
|
|
4254
|
+
score += 5;
|
|
4255
|
+
}
|
|
4256
|
+
if (metrics.layoutRoot) {
|
|
4257
|
+
score += 5;
|
|
4258
|
+
}
|
|
4259
|
+
if (metrics.nestingDepth >= 3) {
|
|
4260
|
+
score += 5;
|
|
4261
|
+
} else if (metrics.nestingDepth >= 2) {
|
|
4262
|
+
score += 3;
|
|
4263
|
+
}
|
|
4264
|
+
score += 5;
|
|
4265
|
+
if (hasClosedCircuit(schema)) {
|
|
4266
|
+
score += 5;
|
|
4267
|
+
}
|
|
4268
|
+
return Math.min(25, score);
|
|
4269
|
+
}
|
|
4270
|
+
function scoreComposition(metrics) {
|
|
4271
|
+
let score = 0;
|
|
4272
|
+
if (metrics.atomTypes.length >= 4) {
|
|
4273
|
+
score += 10;
|
|
4274
|
+
} else if (metrics.atomTypes.length === 3) {
|
|
4275
|
+
score += 7;
|
|
4276
|
+
} else if (metrics.atomTypes.length === 2) {
|
|
4277
|
+
score += 5;
|
|
4278
|
+
}
|
|
4279
|
+
if (metrics.moleculeTypes.length >= 3) {
|
|
4280
|
+
score += 7;
|
|
4281
|
+
} else if (metrics.moleculeTypes.length === 2) {
|
|
4282
|
+
score += 5;
|
|
4283
|
+
} else if (metrics.moleculeTypes.length === 1) {
|
|
4284
|
+
score += 3;
|
|
4285
|
+
}
|
|
4286
|
+
if (metrics.organismTypes.length >= 2) {
|
|
4287
|
+
score += 8;
|
|
4288
|
+
} else if (metrics.organismTypes.length === 1) {
|
|
4289
|
+
score += 5;
|
|
4290
|
+
}
|
|
4291
|
+
return Math.min(25, score);
|
|
4292
|
+
}
|
|
4293
|
+
function scoreTheme(metrics) {
|
|
4294
|
+
let score = 0;
|
|
4295
|
+
if (metrics.themeVariableUsage >= 95) {
|
|
4296
|
+
score += 15;
|
|
4297
|
+
} else if (metrics.themeVariableUsage >= 85) {
|
|
4298
|
+
score += 10;
|
|
4299
|
+
} else if (metrics.themeVariableUsage >= 75) {
|
|
4300
|
+
score += 5;
|
|
4301
|
+
}
|
|
4302
|
+
const hasNoHardcodedColors = !metrics.hardcodedValues.some((v) => v.includes("#") || ["white", "black"].some((c) => v.toLowerCase().includes(c)));
|
|
4303
|
+
if (hasNoHardcodedColors) {
|
|
4304
|
+
score += 5;
|
|
4305
|
+
}
|
|
4306
|
+
const hasNoHardcodedSpacing = !metrics.hardcodedValues.some((v) => /\d+px/.test(v));
|
|
4307
|
+
if (hasNoHardcodedSpacing) {
|
|
4308
|
+
score += 5;
|
|
4309
|
+
}
|
|
4310
|
+
return Math.min(25, score);
|
|
4311
|
+
}
|
|
4312
|
+
function scoreQuality(metrics, testCase) {
|
|
4313
|
+
let score = 0;
|
|
4314
|
+
if (metrics.sectionCount >= 4) {
|
|
4315
|
+
score += 8;
|
|
4316
|
+
} else if (metrics.sectionCount === 3) {
|
|
4317
|
+
score += 6;
|
|
4318
|
+
} else if (metrics.sectionCount === 2) {
|
|
4319
|
+
score += 4;
|
|
4320
|
+
}
|
|
4321
|
+
const expectedPresent = testCase.expectedPatterns.filter(
|
|
4322
|
+
(p) => metrics.atomTypes.includes(p) || metrics.moleculeTypes.includes(p) || metrics.organismTypes.includes(p)
|
|
4323
|
+
).length;
|
|
4324
|
+
score += expectedPresent / testCase.expectedPatterns.length * 8;
|
|
4325
|
+
score += 5;
|
|
4326
|
+
score += 4;
|
|
4327
|
+
return Math.min(25, score);
|
|
4328
|
+
}
|
|
4329
|
+
function calculateTotalScore(schema, testCase, validationErrors) {
|
|
4330
|
+
const metrics = analyzeComposition(schema);
|
|
4331
|
+
const breakdown = {
|
|
4332
|
+
structure: scoreStructure(metrics, schema),
|
|
4333
|
+
composition: scoreComposition(metrics),
|
|
4334
|
+
theme: scoreTheme(metrics),
|
|
4335
|
+
quality: scoreQuality(metrics, testCase)
|
|
4336
|
+
};
|
|
4337
|
+
if (validationErrors.length > 0) {
|
|
4338
|
+
breakdown.structure = Math.max(0, breakdown.structure - validationErrors.length * 2);
|
|
4339
|
+
}
|
|
4340
|
+
const total = breakdown.structure + breakdown.composition + breakdown.theme + breakdown.quality;
|
|
4341
|
+
return {
|
|
4342
|
+
score: Math.min(100, Math.round(total)),
|
|
4343
|
+
breakdown
|
|
4344
|
+
};
|
|
4345
|
+
}
|
|
4346
|
+
function countTransitions(schema) {
|
|
4347
|
+
let count = 0;
|
|
4348
|
+
for (const orbital of schema.orbitals) {
|
|
4349
|
+
for (const trait of orbital.traits) {
|
|
4350
|
+
const t = trait;
|
|
4351
|
+
if (t.stateMachine?.transitions) {
|
|
4352
|
+
count += t.stateMachine.transitions.length;
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4355
|
+
}
|
|
4356
|
+
return count;
|
|
4357
|
+
}
|
|
4358
|
+
function hasClosedCircuit(schema) {
|
|
4359
|
+
for (const orbital of schema.orbitals) {
|
|
4360
|
+
for (const trait of orbital.traits) {
|
|
4361
|
+
const t = trait;
|
|
4362
|
+
if (!t.stateMachine) continue;
|
|
4363
|
+
const states = new Set((t.stateMachine.states || []).map((s) => s.name));
|
|
4364
|
+
const incomingStates = /* @__PURE__ */ new Set();
|
|
4365
|
+
const outgoingStates = /* @__PURE__ */ new Set();
|
|
4366
|
+
for (const transition of t.stateMachine.transitions || []) {
|
|
4367
|
+
incomingStates.add(transition.to);
|
|
4368
|
+
outgoingStates.add(transition.from);
|
|
4369
|
+
}
|
|
4370
|
+
for (const state of states) {
|
|
4371
|
+
const stateObj = (t.stateMachine.states || []).find((s) => s.name === state);
|
|
4372
|
+
if (!stateObj?.isInitial && !incomingStates.has(state)) {
|
|
4373
|
+
return false;
|
|
4374
|
+
}
|
|
4375
|
+
}
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
return true;
|
|
4379
|
+
}
|
|
4380
|
+
function generateComparisonMatrix(comparisons) {
|
|
4381
|
+
let markdown = "# Composition Quality Provider Comparison\n\n";
|
|
4382
|
+
markdown += "| Provider | Average Score | task-mgmt | patient | ecommerce | kanban | analytics |\n";
|
|
4383
|
+
markdown += "|----------|---------------|-----------|---------|-----------|--------|-----------|\n";
|
|
4384
|
+
for (const comp of comparisons) {
|
|
4385
|
+
const scores = EVAL_CASES.map((tc) => {
|
|
4386
|
+
const result = comp.cases.find((c) => c.caseName === tc.name);
|
|
4387
|
+
return result ? `${result.score}${result.passed ? "\u2713" : ""}` : "N/A";
|
|
4388
|
+
});
|
|
4389
|
+
markdown += `| ${comp.provider} | ${comp.averageScore} | ${scores.join(" | ")} |
|
|
4390
|
+
`;
|
|
4391
|
+
}
|
|
4392
|
+
return markdown;
|
|
4393
|
+
}
|
|
4394
|
+
|
|
4395
|
+
export { EVAL_CASES, analyzeComposition, calculateTotalScore, formatFrontmatter, generateAllBuilderSkills, generateComparisonMatrix, generateDomainLanguageSkill, generateKflowOrbitalFixingSkill, generateKflowOrbitalsSkill, generateLeanFixingSkill2 as generateLeanFixingSkill, generateLeanFixingSkill as generateLeanFixingSkillFull, generateLeanOrbitalSkill2 as generateLeanOrbitalSkill, generateLeanOrbitalSkill as generateLeanOrbitalSkillFull, getArchitectureSection, getAssetRefSection, getBannedProps, getBindingContextRules, getBindingsCompact, getBindingsGuide, getCommonErrorsSection, getCommonFixPatternsSection, getCompletionRulesSection, getConnectivityCompact, getContextUsageCompact, getContextUsageSection, getCustomTraitCompact, getCustomTraitSection, getDecompositionChecklist, getDecompositionCompact, getDecompositionSection, getDesignErrorsCompact, getDesignErrorsSection, 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, getThemeGuide, getUsesImportCompact, getUsesImportSection, getValidationHintsSection, writeAllSkills, writeSkill };
|
|
3740
4396
|
//# sourceMappingURL=index.js.map
|
|
3741
4397
|
//# sourceMappingURL=index.js.map
|