@auto-engineer/information-architect 0.11.20 → 0.12.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +22 -0
- package/dist/auto-ux-schema.json +4 -4
- package/dist/src/auto-ux-schema.json +4 -4
- package/dist/src/commands/generate-ia.d.ts.map +1 -1
- package/dist/src/commands/generate-ia.js +18 -1
- package/dist/src/commands/generate-ia.js.map +1 -1
- package/dist/src/ia-agent.d.ts.map +1 -1
- package/dist/src/ia-agent.js +4 -3
- package/dist/src/ia-agent.js.map +1 -1
- package/dist/src/spec-utils.d.ts +3 -0
- package/dist/src/spec-utils.d.ts.map +1 -0
- package/dist/src/spec-utils.js +32 -0
- package/dist/src/spec-utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/auto-ux-schema.json +4 -4
- package/src/commands/generate-ia.ts +22 -1
- package/src/ia-agent.ts +4 -3
- package/src/spec-utils.ts +39 -0
package/package.json
CHANGED
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"fast-glob": "^3.3.2",
|
|
17
|
-
"@auto-engineer/ai-gateway": "0.
|
|
18
|
-
"@auto-engineer/message-bus": "0.
|
|
19
|
-
"@auto-engineer/narrative": "0.
|
|
17
|
+
"@auto-engineer/ai-gateway": "0.12.1",
|
|
18
|
+
"@auto-engineer/message-bus": "0.12.1",
|
|
19
|
+
"@auto-engineer/narrative": "0.12.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@auto-engineer/cli": "0.
|
|
22
|
+
"@auto-engineer/cli": "0.12.1"
|
|
23
23
|
},
|
|
24
|
-
"version": "0.
|
|
24
|
+
"version": "0.12.1",
|
|
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
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"items": {
|
|
30
30
|
"type": "string"
|
|
31
31
|
},
|
|
32
|
-
"description": "Optional.
|
|
32
|
+
"description": "Optional. Array of behavioral test specifications. Uses ' → ' to show nested context."
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"required": ["description"]
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"items": {
|
|
73
73
|
"type": "string"
|
|
74
74
|
},
|
|
75
|
-
"description": "Optional.
|
|
75
|
+
"description": "Optional. Array of behavioral test specifications. Uses ' → ' to show nested context."
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
"required": ["description", "composition"]
|
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
"items": {
|
|
155
155
|
"type": "string"
|
|
156
156
|
},
|
|
157
|
-
"description": "Optional.
|
|
157
|
+
"description": "Optional. Array of behavioral test specifications. Uses ' → ' to show nested context."
|
|
158
158
|
}
|
|
159
159
|
},
|
|
160
160
|
"required": ["description", "composition"]
|
|
@@ -254,7 +254,7 @@
|
|
|
254
254
|
"items": {
|
|
255
255
|
"type": "string"
|
|
256
256
|
},
|
|
257
|
-
"description": "Optional.
|
|
257
|
+
"description": "Optional. Array of behavioral test specifications. Uses ' → ' to show nested context."
|
|
258
258
|
}
|
|
259
259
|
},
|
|
260
260
|
"required": ["route", "description", "layout"]
|
|
@@ -6,6 +6,7 @@ import { processFlowsWithAI } from '../index';
|
|
|
6
6
|
import { type UXSchema } from '../types';
|
|
7
7
|
import createDebug from 'debug';
|
|
8
8
|
import { Model } from '@auto-engineer/narrative';
|
|
9
|
+
import { flattenClientSpecs } from '../spec-utils';
|
|
9
10
|
|
|
10
11
|
const debug = createDebug('auto:information-architect:generate-command');
|
|
11
12
|
const debugSchema = createDebug('auto:information-architect:generate-command:schema');
|
|
@@ -110,6 +111,22 @@ async function getModelFromContext(modelPath: string): Promise<Model> {
|
|
|
110
111
|
return JSON.parse(modelContent) as Model;
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
function preprocessModelForAI(model: Model): Model {
|
|
115
|
+
const processedModel = JSON.parse(JSON.stringify(model)) as Model;
|
|
116
|
+
|
|
117
|
+
for (const narrative of processedModel.narratives) {
|
|
118
|
+
for (const slice of narrative.slices) {
|
|
119
|
+
if ('client' in slice && slice.client !== undefined && slice.client.specs !== undefined) {
|
|
120
|
+
const flattenedSpecs = flattenClientSpecs(slice.client.specs);
|
|
121
|
+
(slice.client as Record<string, unknown>).specs = flattenedSpecs;
|
|
122
|
+
debug('Flattened %d client specs for slice: %s', flattenedSpecs.length, slice.name);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return processedModel;
|
|
128
|
+
}
|
|
129
|
+
|
|
113
130
|
async function getUniqueSchemaPath(
|
|
114
131
|
outputDir: string,
|
|
115
132
|
): Promise<{ filePath: string; existingSchema: object | undefined }> {
|
|
@@ -155,6 +172,10 @@ async function handleGenerateIACommandInternal(
|
|
|
155
172
|
const model = await getModelFromContext(modelPath);
|
|
156
173
|
debugFiles('Reading %d flow files', model.narratives.length);
|
|
157
174
|
|
|
175
|
+
// Preprocess model to flatten client specs for AI
|
|
176
|
+
const processedModel = preprocessModelForAI(model);
|
|
177
|
+
debug('Model preprocessed with flattened client specs');
|
|
178
|
+
|
|
158
179
|
// Get unique schema path and existing schema
|
|
159
180
|
const { filePath, existingSchema } = await getUniqueSchemaPath(outputDir);
|
|
160
181
|
|
|
@@ -169,7 +190,7 @@ async function handleGenerateIACommandInternal(
|
|
|
169
190
|
debug(' Existing schema: %s', existingSchema ? 'yes' : 'no');
|
|
170
191
|
debug(' Atom count: %d', atoms.length);
|
|
171
192
|
|
|
172
|
-
const iaSchema = await processFlowsWithAI(
|
|
193
|
+
const iaSchema = await processFlowsWithAI(processedModel, uxSchema, existingSchema, atoms);
|
|
173
194
|
debug('AI processing complete');
|
|
174
195
|
|
|
175
196
|
// Write the schema to file
|
package/src/ia-agent.ts
CHANGED
|
@@ -92,9 +92,10 @@ Instructions:
|
|
|
92
92
|
- template (what wrapper does the page use)
|
|
93
93
|
- navigation (array of navigation actions, e.g., { "on": "Click Listing Card", "to": "ListingDetailPage" })
|
|
94
94
|
- data_requirements (array, as above, for page-level data fetching)
|
|
95
|
-
- For each component or page, if there are any specs defined in the model's flow slices
|
|
96
|
-
-
|
|
97
|
-
-
|
|
95
|
+
- 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.
|
|
96
|
+
- These specs describe behavioral requirements with nested context preserved using ' → ' separator (e.g., "Form → Validation → shows error").
|
|
97
|
+
- Assign these specs directly to the 'specs' field for the corresponding component/page.
|
|
98
|
+
- If no client.specs exist for a slice, omit the 'specs' field.
|
|
98
99
|
|
|
99
100
|
Use the following structure as a template for your response:
|
|
100
101
|
----
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ClientSpecNode } from '@auto-engineer/narrative';
|
|
2
|
+
|
|
3
|
+
function buildFullPath(path: string[], title: string, separator: string): string {
|
|
4
|
+
return path.length > 0 ? path.join(separator) + separator + title : title;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function shouldIncludeTitleInPath(title: string | undefined): boolean {
|
|
8
|
+
return title !== undefined && title !== '' && title.trim() !== '';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function createNewPath(path: string[], title: string | undefined): string[] {
|
|
12
|
+
return shouldIncludeTitleInPath(title) && title !== undefined ? [...path, title] : path;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function hasChildren(node: ClientSpecNode): boolean {
|
|
16
|
+
return node.type === 'describe' && node.children !== undefined && node.children.length > 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function flattenClientSpecs(nodes: ClientSpecNode[] | undefined, separator: string = ' → '): string[] {
|
|
20
|
+
if (!nodes || nodes.length === 0) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const results: string[] = [];
|
|
25
|
+
|
|
26
|
+
function traverse(nodes: ClientSpecNode[], path: string[] = []): void {
|
|
27
|
+
for (const node of nodes) {
|
|
28
|
+
if (node.type === 'it') {
|
|
29
|
+
results.push(buildFullPath(path, node.title, separator));
|
|
30
|
+
} else if (hasChildren(node) && node.children !== undefined) {
|
|
31
|
+
const newPath = createNewPath(path, node.title);
|
|
32
|
+
traverse(node.children, newPath);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
traverse(nodes);
|
|
38
|
+
return results;
|
|
39
|
+
}
|