@auto-engineer/information-architect 1.8.0 → 1.10.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +1 -1
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +40 -0
- package/dist/auto-ux-schema.json +42 -7
- package/dist/src/auto-ux-schema.json +42 -7
- package/dist/src/ia-agent.d.ts +1 -1
- package/dist/src/ia-agent.d.ts.map +1 -1
- package/dist/src/ia-agent.js +149 -28
- package/dist/src/ia-agent.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/auto-ux-schema.json +42 -7
- package/src/ia-agent.ts +170 -30
package/package.json
CHANGED
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"fast-glob": "^3.3.2",
|
|
17
|
-
"@auto-engineer/
|
|
18
|
-
"@auto-engineer/
|
|
19
|
-
"@auto-engineer/
|
|
17
|
+
"@auto-engineer/message-bus": "1.10.0",
|
|
18
|
+
"@auto-engineer/narrative": "1.10.0",
|
|
19
|
+
"@auto-engineer/ai-gateway": "1.10.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@auto-engineer/cli": "1.
|
|
22
|
+
"@auto-engineer/cli": "1.10.0"
|
|
23
23
|
},
|
|
24
|
-
"version": "1.
|
|
24
|
+
"version": "1.10.0",
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "tsc && tsx ../../scripts/fix-esm-imports.ts && cp src/auto-ux-schema.json dist/",
|
|
27
27
|
"test": "vitest run --reporter=dot",
|
package/src/auto-ux-schema.json
CHANGED
|
@@ -164,8 +164,8 @@
|
|
|
164
164
|
},
|
|
165
165
|
"required": ["description", "items"]
|
|
166
166
|
},
|
|
167
|
-
"
|
|
168
|
-
"description": "
|
|
167
|
+
"templates": {
|
|
168
|
+
"description": "Page-level layout structures that place organisms into a layout. Templates define the skeletal framework and content structure without real data.",
|
|
169
169
|
"type": "object",
|
|
170
170
|
"properties": {
|
|
171
171
|
"description": {
|
|
@@ -177,9 +177,6 @@
|
|
|
177
177
|
"^[A-Z][a-zA-Z0-9]*$": {
|
|
178
178
|
"type": "object",
|
|
179
179
|
"properties": {
|
|
180
|
-
"route": {
|
|
181
|
-
"type": "string"
|
|
182
|
-
},
|
|
183
180
|
"description": {
|
|
184
181
|
"type": "string"
|
|
185
182
|
},
|
|
@@ -195,6 +192,44 @@
|
|
|
195
192
|
},
|
|
196
193
|
"required": ["organisms"]
|
|
197
194
|
},
|
|
195
|
+
"specs": {
|
|
196
|
+
"type": "array",
|
|
197
|
+
"items": {
|
|
198
|
+
"type": "string"
|
|
199
|
+
},
|
|
200
|
+
"description": "Optional. Array of behavioral test specifications. Uses ' → ' to show nested context."
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
"required": ["description", "layout"]
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"required": ["description", "items"]
|
|
209
|
+
},
|
|
210
|
+
"pages": {
|
|
211
|
+
"description": "Specific instances of templates with real representative content. Tied to routes and populated with actual data.",
|
|
212
|
+
"type": "object",
|
|
213
|
+
"properties": {
|
|
214
|
+
"description": {
|
|
215
|
+
"type": "string"
|
|
216
|
+
},
|
|
217
|
+
"items": {
|
|
218
|
+
"type": "object",
|
|
219
|
+
"patternProperties": {
|
|
220
|
+
"^[A-Z][a-zA-Z0-9]*$": {
|
|
221
|
+
"type": "object",
|
|
222
|
+
"properties": {
|
|
223
|
+
"route": {
|
|
224
|
+
"type": "string"
|
|
225
|
+
},
|
|
226
|
+
"description": {
|
|
227
|
+
"type": "string"
|
|
228
|
+
},
|
|
229
|
+
"template": {
|
|
230
|
+
"type": "string",
|
|
231
|
+
"description": "Reference to a template that defines the page's layout structure."
|
|
232
|
+
},
|
|
198
233
|
"navigation": {
|
|
199
234
|
"type": "array",
|
|
200
235
|
"items": {
|
|
@@ -257,7 +292,7 @@
|
|
|
257
292
|
"description": "Optional. Array of behavioral test specifications. Uses ' → ' to show nested context."
|
|
258
293
|
}
|
|
259
294
|
},
|
|
260
|
-
"required": ["route", "description", "
|
|
295
|
+
"required": ["route", "description", "template"]
|
|
261
296
|
}
|
|
262
297
|
}
|
|
263
298
|
}
|
|
@@ -265,5 +300,5 @@
|
|
|
265
300
|
"required": ["description", "items"]
|
|
266
301
|
}
|
|
267
302
|
},
|
|
268
|
-
"required": ["schema_description", "atoms", "molecules", "organisms", "pages"]
|
|
303
|
+
"required": ["schema_description", "atoms", "molecules", "organisms", "templates", "pages"]
|
|
269
304
|
}
|
package/src/ia-agent.ts
CHANGED
|
@@ -29,16 +29,33 @@ interface ItemsContainer {
|
|
|
29
29
|
items?: Record<string, ComponentDefinition>;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
interface TemplateDefinition {
|
|
33
|
+
layout?: {
|
|
34
|
+
organisms?: string[];
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface TemplatesContainer {
|
|
39
|
+
items?: Record<string, TemplateDefinition>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface PageDefinition {
|
|
43
|
+
template?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
interface IASchema {
|
|
33
47
|
atoms?: ItemsContainer;
|
|
34
48
|
molecules?: ItemsContainer;
|
|
35
49
|
organisms?: ItemsContainer;
|
|
36
|
-
|
|
50
|
+
templates?: TemplatesContainer;
|
|
51
|
+
pages?: {
|
|
52
|
+
items?: Record<string, PageDefinition>;
|
|
53
|
+
};
|
|
37
54
|
}
|
|
38
55
|
|
|
39
56
|
export interface ValidationError {
|
|
40
57
|
component: string;
|
|
41
|
-
type: 'molecule' | 'organism';
|
|
58
|
+
type: 'molecule' | 'organism' | 'template' | 'page';
|
|
42
59
|
field: string;
|
|
43
60
|
invalidReferences: string[];
|
|
44
61
|
message: string;
|
|
@@ -52,7 +69,9 @@ export function validateCompositionReferences(schema: unknown, designSystemAtoms
|
|
|
52
69
|
const atomNames = new Set([...schemaAtoms, ...designSystemAtoms]);
|
|
53
70
|
const moleculeNames = new Set(Object.keys(s.molecules?.items ?? {}));
|
|
54
71
|
const organismNames = new Set(Object.keys(s.organisms?.items ?? {}));
|
|
72
|
+
const templateNames = new Set(Object.keys(s.templates?.items ?? {}));
|
|
55
73
|
|
|
74
|
+
// Validate molecules reference only atoms
|
|
56
75
|
for (const [name, def] of Object.entries(s.molecules?.items ?? {})) {
|
|
57
76
|
const referencedAtoms = def.composition?.atoms ?? [];
|
|
58
77
|
const invalidAtoms = referencedAtoms.filter((atom: string) => !atomNames.has(atom));
|
|
@@ -67,6 +86,7 @@ export function validateCompositionReferences(schema: unknown, designSystemAtoms
|
|
|
67
86
|
}
|
|
68
87
|
}
|
|
69
88
|
|
|
89
|
+
// Validate organisms reference only molecules
|
|
70
90
|
for (const [name, def] of Object.entries(s.organisms?.items ?? {})) {
|
|
71
91
|
const referencedMolecules = def.composition?.molecules ?? [];
|
|
72
92
|
|
|
@@ -97,6 +117,35 @@ export function validateCompositionReferences(schema: unknown, designSystemAtoms
|
|
|
97
117
|
}
|
|
98
118
|
}
|
|
99
119
|
|
|
120
|
+
// Validate templates reference only organisms
|
|
121
|
+
for (const [name, def] of Object.entries(s.templates?.items ?? {})) {
|
|
122
|
+
const referencedOrganisms = def.layout?.organisms ?? [];
|
|
123
|
+
const invalidOrganisms = referencedOrganisms.filter((org: string) => !organismNames.has(org));
|
|
124
|
+
if (invalidOrganisms.length > 0) {
|
|
125
|
+
errors.push({
|
|
126
|
+
component: name,
|
|
127
|
+
type: 'template',
|
|
128
|
+
field: 'layout.organisms',
|
|
129
|
+
invalidReferences: invalidOrganisms,
|
|
130
|
+
message: `Template "${name}" references non-existent organisms: ${invalidOrganisms.join(', ')}`,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Validate pages reference only templates
|
|
136
|
+
for (const [name, def] of Object.entries(s.pages?.items ?? {})) {
|
|
137
|
+
const referencedTemplate = def.template;
|
|
138
|
+
if (referencedTemplate && !templateNames.has(referencedTemplate)) {
|
|
139
|
+
errors.push({
|
|
140
|
+
component: name,
|
|
141
|
+
type: 'page',
|
|
142
|
+
field: 'template',
|
|
143
|
+
invalidReferences: [referencedTemplate],
|
|
144
|
+
message: `Page "${name}" references non-existent template: ${referencedTemplate}`,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
100
149
|
return errors;
|
|
101
150
|
}
|
|
102
151
|
|
|
@@ -157,16 +206,68 @@ ${errorContext}
|
|
|
157
206
|
IMPORTANT: Only generate pages and components that are directly referenced in the provided model's flows. Do NOT add any extra pages or components, and do NOT make assumptions outside the flows. If something is not mentioned in the flows, it should NOT appear in the output.
|
|
158
207
|
IMPORTANT: try your best to reuse the existing atoms, and try not to generate atoms with context: like Submit Button, because the submit part is mainly irrelevant, instead just use the Button atom if provided.
|
|
159
208
|
|
|
160
|
-
CRITICAL COMPOSITION RULES - THESE ARE STRICT AND MUST BE FOLLOWED:
|
|
209
|
+
CRITICAL COMPOSITION RULES - THESE ARE STRICT AND MUST BE FOLLOWED (Atomic Design Methodology):
|
|
161
210
|
1. Atoms: Basic UI primitives (Button, Text, Input, Icon, etc.). Atoms do NOT compose other atoms.
|
|
162
211
|
2. Molecules: Composed ONLY of atoms. A molecule's "composition.atoms" array must ONLY reference items that exist in "atoms.items".
|
|
163
212
|
3. Organisms: Composed of atoms AND molecules. An organism's "composition.molecules" array must ONLY reference items that exist in "molecules.items". An organism MUST NOT reference other organisms.
|
|
164
|
-
4.
|
|
213
|
+
4. Templates: Page-level layout structures that place organisms into a layout. A template's "layout.organisms" array must ONLY reference items that exist in "organisms.items". Templates define the skeletal framework without real content.
|
|
214
|
+
5. Pages: Specific instances of templates with real representative content. A page's "template" field must reference a template that exists in "templates.items". Pages are tied to routes and populated with actual data.
|
|
215
|
+
|
|
216
|
+
VISUAL DESIGN PRINCIPLES - Apply these to create beautiful, professional UIs:
|
|
217
|
+
|
|
218
|
+
1. TYPOGRAPHY HIERARCHY (every component should consider text sizing):
|
|
219
|
+
- Headlines/Titles: Large size, bold weight, commanding presence
|
|
220
|
+
- Subheadings: Medium-large size, semi-bold weight, clear section breaks
|
|
221
|
+
- Body text: Comfortable reading size with good line height
|
|
222
|
+
- Labels/Captions: Small size, subtle color, supporting information
|
|
223
|
+
|
|
224
|
+
2. COMPONENT PURPOSE & VISUAL ROLE:
|
|
225
|
+
- Molecules should be self-contained, visually complete units (cards, forms, list items)
|
|
226
|
+
- Organisms should compose molecules into meaningful sections (hero sections, feature grids, data tables)
|
|
227
|
+
- Templates define visual rhythm and spacing structure
|
|
228
|
+
|
|
229
|
+
3. INTERACTIVE ELEMENTS:
|
|
230
|
+
- Every interactive molecule/organism should specify hover, focus, and active states in specs
|
|
231
|
+
- Forms need clear validation states (success, error, loading)
|
|
232
|
+
- Lists need empty states and loading states
|
|
233
|
+
|
|
234
|
+
4. SEMANTIC NAMING FOR VISUAL CLARITY:
|
|
235
|
+
- Use descriptive names that hint at visual purpose: "HeroSection", "FeatureCard", "StatsGrid", "NavigationSidebar"
|
|
236
|
+
- Avoid generic names like "Section1" or "Component"
|
|
237
|
+
|
|
238
|
+
5. LAYOUT CONSIDERATIONS IN TEMPLATES:
|
|
239
|
+
- Define clear visual regions: header, sidebar, main content, footer
|
|
240
|
+
- Consider responsive behavior in template specs
|
|
241
|
+
- Use common patterns: dashboard layout, marketing layout, form-centric layout
|
|
242
|
+
|
|
243
|
+
6. TEMPLATE NAMING AND PURPOSE:
|
|
244
|
+
- Name templates based on their layout structure (e.g., SidebarLayout, CenteredLayout, FullWidthLayout)
|
|
245
|
+
- Templates should be reusable across different pages
|
|
246
|
+
- Include layout-related specs like "responsive sidebar" or "sticky header"
|
|
247
|
+
|
|
248
|
+
7. ORGANISM DESCRIPTIONS SHOULD SPECIFY VISUAL ROLE:
|
|
249
|
+
Good: "Card grid displaying items with image, title, and action buttons"
|
|
250
|
+
Good: "Navigation bar with logo, menu items, and user actions"
|
|
251
|
+
Bad: "Shows items" (too vague)
|
|
252
|
+
Bad: "Navigation" (no visual details)
|
|
253
|
+
|
|
254
|
+
8. SPECS SHOULD INCLUDE VISUAL BEHAVIORS:
|
|
255
|
+
Good specs:
|
|
256
|
+
- "displays loading skeleton while fetching data"
|
|
257
|
+
- "shows empty state with icon and action button when no items"
|
|
258
|
+
- "items have hover effect with shadow elevation"
|
|
259
|
+
- "responsive grid: 1 column mobile, 2 tablet, 3 desktop"
|
|
260
|
+
Bad specs (too vague):
|
|
261
|
+
- "shows data"
|
|
262
|
+
- "handles loading"
|
|
263
|
+
- "is responsive"
|
|
165
264
|
|
|
166
265
|
VALIDATION CHECKLIST (the schema will be rejected if these rules are violated):
|
|
167
266
|
- Every item in a molecule's "composition.atoms" MUST exist in "atoms.items"
|
|
168
267
|
- Every item in an organism's "composition.molecules" MUST exist in "molecules.items"
|
|
169
268
|
- An organism's "composition.molecules" MUST NOT contain names that only exist in "organisms.items"
|
|
269
|
+
- Every item in a template's "layout.organisms" MUST exist in "organisms.items"
|
|
270
|
+
- Every page's "template" MUST reference a template that exists in "templates.items"
|
|
170
271
|
- Cross-check all composition references before finalizing the output
|
|
171
272
|
|
|
172
273
|
$${atoms ? `Here is a list of available atomic components (atoms) from the design system. Use these atoms and their props as much as possible. Only create new atoms if absolutely necessary. And only put the new atoms created into the schema. \n\nAtoms:\n${JSON.stringify(atoms, null, 2)}\n` : ''}
|
|
@@ -181,25 +282,32 @@ Instructions:
|
|
|
181
282
|
|
|
182
283
|
- NEVER generate any data_requirements queries or mutations if NONE were provided from the flow schema
|
|
183
284
|
- Respond ONLY with a JSON object, no explanation, no markdown, no text before or after.
|
|
184
|
-
- The JSON should have
|
|
185
|
-
- In "
|
|
285
|
+
- The JSON should have sections for: "atoms", "molecules", "organisms", "templates", and "pages".
|
|
286
|
+
- In "atoms", "molecules", and "organisms", define composite UI elements with:
|
|
186
287
|
- A description
|
|
187
|
-
- A "composition" field listing the building blocks used
|
|
188
|
-
- "atoms"
|
|
189
|
-
- "molecules"
|
|
190
|
-
|
|
191
|
-
- Example:
|
|
288
|
+
- A "composition" field listing the building blocks used:
|
|
289
|
+
- For molecules: "atoms" array referencing atomic UI primitives
|
|
290
|
+
- For organisms: "molecules" array referencing molecule components
|
|
291
|
+
- Example for molecule:
|
|
192
292
|
"composition": {
|
|
193
|
-
"atoms": ["Button", "Text"]
|
|
194
|
-
"molecules": ["SearchBar"],
|
|
195
|
-
"organisms": ["TopNavBar"]
|
|
293
|
+
"atoms": ["Button", "Text"]
|
|
196
294
|
}
|
|
197
|
-
-
|
|
295
|
+
- Example for organism:
|
|
296
|
+
"composition": {
|
|
297
|
+
"molecules": ["SearchBar", "FilterPanel"]
|
|
298
|
+
}
|
|
299
|
+
- In "templates", define page-level layout structures with:
|
|
300
|
+
- description (what this layout structure provides - be specific about visual arrangement)
|
|
301
|
+
- layout.organisms (array of organisms that make up the template's skeleton)
|
|
302
|
+
- specs (optional array describing layout requirements like "responsive sidebar", "sticky header", "scrollable content area")
|
|
303
|
+
- Templates define the structural framework WITHOUT real content
|
|
304
|
+
- Common template patterns: DashboardTemplate (sidebar + main), MarketingTemplate (full-width sections), FormTemplate (centered narrow container)
|
|
305
|
+
- In "pages", define each page as a specific instance of a template, with:
|
|
198
306
|
- route (URL path)
|
|
199
307
|
- description
|
|
200
|
-
- template (
|
|
308
|
+
- template (reference to a template in "templates.items" that defines the page's layout)
|
|
201
309
|
- navigation (array of navigation actions, e.g., { "on": "Click Listing Card", "to": "ListingDetailPage" })
|
|
202
|
-
- data_requirements (array
|
|
310
|
+
- data_requirements (array for page-level data fetching - this is the "real content" that populates the template)
|
|
203
311
|
- For each component or page, if there are any specs defined in the model's flow slices, look at slice.client.specs which is an array of strings.
|
|
204
312
|
- These specs describe behavioral requirements with nested context preserved using ' → ' separator (e.g., "Form → Validation → shows error").
|
|
205
313
|
- Assign these specs directly to the 'specs' field for the corresponding component/page.
|
|
@@ -209,17 +317,37 @@ Use the following structure as a template for your response:
|
|
|
209
317
|
----
|
|
210
318
|
{
|
|
211
319
|
"atoms": {
|
|
320
|
+
"description": "Basic UI primitives",
|
|
212
321
|
"items": {
|
|
213
322
|
"AtomName": {
|
|
214
|
-
|
|
323
|
+
"description": "What this atom does."
|
|
215
324
|
}
|
|
216
325
|
}
|
|
217
326
|
},
|
|
218
327
|
"molecules": {
|
|
328
|
+
"description": "Components composed from atoms - these are reusable visual units",
|
|
219
329
|
"items": {
|
|
220
|
-
"
|
|
221
|
-
"description": "What this
|
|
222
|
-
"composition": { "
|
|
330
|
+
"MoleculeName": {
|
|
331
|
+
"description": "What this molecule does and its visual appearance (e.g., 'Card displaying user info with avatar, name, and action button').",
|
|
332
|
+
"composition": { "atoms": ["Atom1", "Atom2"] },
|
|
333
|
+
"specs": [
|
|
334
|
+
"hover state shows shadow elevation",
|
|
335
|
+
"click navigates to detail view"
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
"organisms": {
|
|
341
|
+
"description": "Smart UI components composed of molecules - these are visually complete sections",
|
|
342
|
+
"items": {
|
|
343
|
+
"OrganismName": {
|
|
344
|
+
"description": "What this organism does and its visual role (e.g., 'Hero section with headline, subtext, and CTA buttons').",
|
|
345
|
+
"composition": { "molecules": ["Molecule1", "Molecule2"] },
|
|
346
|
+
"specs": [
|
|
347
|
+
"displays loading skeleton while fetching",
|
|
348
|
+
"shows empty state when no data",
|
|
349
|
+
"hover effect on interactive cards"
|
|
350
|
+
],
|
|
223
351
|
"data_requirements": [
|
|
224
352
|
{
|
|
225
353
|
"type": "query",
|
|
@@ -233,18 +361,30 @@ Use the following structure as a template for your response:
|
|
|
233
361
|
]
|
|
234
362
|
}
|
|
235
363
|
}
|
|
236
|
-
|
|
364
|
+
},
|
|
365
|
+
"templates": {
|
|
366
|
+
"description": "Page-level layout structures that define visual rhythm and regions",
|
|
367
|
+
"items": {
|
|
368
|
+
"TemplateName": {
|
|
369
|
+
"description": "What layout structure this template provides (e.g., 'Dashboard layout with collapsible sidebar and main content area').",
|
|
370
|
+
"layout": { "organisms": ["Organism1", "Organism2"] },
|
|
371
|
+
"specs": ["responsive sidebar collapses on mobile", "sticky header", "scrollable main content"]
|
|
372
|
+
}
|
|
373
|
+
}
|
|
237
374
|
},
|
|
238
375
|
"pages": {
|
|
239
|
-
"
|
|
240
|
-
|
|
241
|
-
"
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
376
|
+
"description": "Specific instances of templates with real content",
|
|
377
|
+
"items": {
|
|
378
|
+
"PageName": {
|
|
379
|
+
"route": "/route",
|
|
380
|
+
"description": "What this page does.",
|
|
381
|
+
"template": "TemplateName",
|
|
382
|
+
"navigation": [{ "on": "Event", "to": "TargetPage" }],
|
|
383
|
+
"data_requirements": [
|
|
384
|
+
// ... as above
|
|
385
|
+
]
|
|
386
|
+
}
|
|
246
387
|
}
|
|
247
|
-
// ... more pages
|
|
248
388
|
}
|
|
249
389
|
}
|
|
250
390
|
----
|