create-auto-app 0.8.5 → 0.8.7

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.
Files changed (24) hide show
  1. package/package.json +2 -2
  2. package/templates/shopping-app/.context/schema.graphql +4 -4
  3. package/templates/shopping-app/.context/schema.json +54 -62
  4. package/templates/shopping-app/.context/server/server/package.json +1 -2
  5. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.specs.ts +0 -1
  6. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/events.ts +0 -1
  7. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/react.specs.ts +0 -1
  8. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.specs.ts +0 -1
  9. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/events.ts +0 -1
  10. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/decide.ts +1 -1
  11. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/handle.ts +2 -2
  12. package/templates/shopping-app/auto.config.ts +19 -11
  13. package/templates/shopping-app/example-integrations/ai-chat-completion/package.json +1 -2
  14. package/templates/shopping-app/example-integrations/cart/package.json +1 -2
  15. package/templates/shopping-app/example-integrations/cart-api/package.json +1 -2
  16. package/templates/shopping-app/example-integrations/product-catalogue/package.json +1 -2
  17. package/templates/shopping-app/example-integrations/product-catalogue-api/package.json +1 -2
  18. package/templates/shopping-app/flows/shopping-assistant.flow.ts +80 -97
  19. package/templates/shopping-app/package.json +2 -2
  20. package/templates/shopping-app/server/scripts/generate-schema.ts +1 -1
  21. package/templates/shopping-app/server/src/integrations/product-catalogue/product-catalogue-integration.ts +8 -29
  22. package/templates/shopping-app/tsconfig.json +3 -1
  23. package/templates/shopping-app/turbo.json +19 -0
  24. package/templates/shopping-app/client/postcss.config.js +0 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-auto-app",
3
- "version": "0.8.5",
3
+ "version": "0.8.7",
4
4
  "description": "Create Auto Engineer apps with no configuration",
5
5
  "type": "module",
6
6
  "bin": {
@@ -39,7 +39,7 @@
39
39
  "node": ">=18.0.0"
40
40
  },
41
41
  "scripts": {
42
- "copy-templates": "rm -rf templates/shopping-app && rsync -av --exclude='node_modules' --exclude='.turbo' --exclude='dist' --exclude='build' ../../examples/shopping-app/ templates/shopping-app/",
42
+ "copy-templates": "rm -rf templates/shopping-app && rsync -a --exclude='node_modules' --exclude='.turbo' --exclude='dist' --exclude='build' --exclude='**/*.js' --exclude='**/*.js.map' ../../examples/shopping-app/ templates/shopping-app/",
43
43
  "build": "npm run copy-templates && tsc && chmod +x dist/index.js",
44
44
  "type-check": "tsc --noEmit",
45
45
  "lint": "eslint 'src/**/*.ts' --max-warnings 0 --config ../../eslint.config.ts --ignore-pattern 'templates/**'",
@@ -30,9 +30,9 @@ type MutationError {
30
30
  message: String
31
31
  }
32
32
 
33
- input SuggestShoppingItemsInput {
33
+ input AddItemsToCartInput {
34
34
  sessionId: String!
35
- prompt: String!
35
+ items: String!
36
36
  }
37
37
 
38
38
  input EnterShoppingCriteriaInput {
@@ -40,7 +40,7 @@ input EnterShoppingCriteriaInput {
40
40
  criteria: String!
41
41
  }
42
42
 
43
- input AddItemsToCartInput {
43
+ input SuggestShoppingItemsInput {
44
44
  sessionId: String!
45
- items: String!
45
+ prompt: String!
46
46
  }
@@ -9,15 +9,17 @@
9
9
  "type": "command",
10
10
  "client": {
11
11
  "description": "",
12
- "specs": [
13
- "Assistant Chat Interface",
14
- "allow shopper to describe their shopping needs in natural language",
15
- "provide a text input for entering criteria",
16
- "show examples of what to include (age, interests, budget)",
17
- "show a button to submit the criteria",
18
- "generate a persisted session id for a visit",
19
- "show the header on top of the page"
20
- ]
12
+ "specs": {
13
+ "name": "Assistant Chat Interface",
14
+ "rules": [
15
+ "allow shopper to describe their shopping needs in natural language",
16
+ "provide a text input for entering criteria",
17
+ "show examples of what to include (age, interests, budget)",
18
+ "show a button to submit the criteria",
19
+ "generate a persisted session id for a visit",
20
+ "show the header on top of the page"
21
+ ]
22
+ }
21
23
  },
22
24
  "request": "mutation EnterShoppingCriteria($input: EnterShoppingCriteriaInput!) {\n enterShoppingCriteria(input: $input) {\n success\n error {\n type\n message\n }\n }\n}",
23
25
  "server": {
@@ -54,8 +56,7 @@
54
56
  "eventRef": "ShoppingCriteriaEntered",
55
57
  "exampleData": {
56
58
  "sessionId": "shopper-123",
57
- "criteria": "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.",
58
- "timestamp": "2025-09-04T21:20:20.309Z"
59
+ "criteria": "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering."
59
60
  }
60
61
  }
61
62
  ]
@@ -83,8 +84,7 @@
83
84
  "eventRef": "ShoppingCriteriaEntered",
84
85
  "exampleData": {
85
86
  "sessionId": "session-abc",
86
- "criteria": "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.",
87
- "timestamp": "2025-09-04T21:20:20.309Z"
87
+ "criteria": "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering."
88
88
  }
89
89
  }
90
90
  ],
@@ -108,8 +108,7 @@
108
108
  "name": "selects items relevant to the shopping criteria",
109
109
  "type": "command",
110
110
  "client": {
111
- "description": "",
112
- "specs": []
111
+ "description": ""
113
112
  },
114
113
  "server": {
115
114
  "description": "",
@@ -135,7 +134,7 @@
135
134
  },
136
135
  "origin": {
137
136
  "type": "integration",
138
- "systems": ["product-catalog"]
137
+ "systems": ["ProductCatalog"]
139
138
  }
140
139
  }
141
140
  },
@@ -160,6 +159,7 @@
160
159
  "description": "Product catalog with matching items generates suggestions",
161
160
  "given": [
162
161
  {
162
+ "stateRef": "Products",
163
163
  "exampleData": {
164
164
  "products": [
165
165
  {
@@ -195,8 +195,7 @@
195
195
  "imageUrl": "https://example.com/mtg-starter.jpg"
196
196
  }
197
197
  ]
198
- },
199
- "stateRef": "Products"
198
+ }
200
199
  }
201
200
  ],
202
201
  "when": {
@@ -252,13 +251,15 @@
252
251
  "type": "query",
253
252
  "client": {
254
253
  "description": "",
255
- "specs": [
256
- "Suggested Items Screen",
257
- "display all suggested items with names and reasons",
258
- "show quantity selectors for each item",
259
- "have an \"Add to Cart\" button for selected items",
260
- "allow removing items from the suggestions"
261
- ]
254
+ "specs": {
255
+ "name": "Suggested Items Screen",
256
+ "rules": [
257
+ "display all suggested items with names and reasons",
258
+ "show quantity selectors for each item",
259
+ "have an \"Add to Cart\" button for selected items",
260
+ "allow removing items from the suggestions"
261
+ ]
262
+ }
262
263
  },
263
264
  "request": "query GetSuggestedItems($sessionId: ID!) {\n suggestedItems(sessionId: $sessionId) {\n items {\n productId\n name\n quantity\n reason\n }\n }\n}",
264
265
  "server": {
@@ -362,12 +363,14 @@
362
363
  "type": "command",
363
364
  "client": {
364
365
  "description": "",
365
- "specs": [
366
- "Suggested Items Screen",
367
- "allow selecting specific items to add",
368
- "update quantities before adding to cart",
369
- "provide feedback when items are added"
370
- ]
366
+ "specs": {
367
+ "name": "Suggested Items Screen",
368
+ "rules": [
369
+ "allow selecting specific items to add",
370
+ "update quantities before adding to cart",
371
+ "provide feedback when items are added"
372
+ ]
373
+ }
371
374
  },
372
375
  "server": {
373
376
  "description": "",
@@ -437,8 +440,7 @@
437
440
  "productId": "prod-mtg-starter",
438
441
  "quantity": 1
439
442
  }
440
- ],
441
- "timestamp": "2025-09-04T21:20:20.310Z"
443
+ ]
442
444
  }
443
445
  }
444
446
  ]
@@ -569,20 +571,6 @@
569
571
  "version": 1
570
572
  }
571
573
  },
572
- {
573
- "type": "state",
574
- "name": "Products",
575
- "fields": [
576
- {
577
- "name": "products",
578
- "type": "Array<{ productId: string; name: string; category: string; price: number; tags: Array<string>; imageUrl: string }>",
579
- "required": true
580
- }
581
- ],
582
- "metadata": {
583
- "version": 1
584
- }
585
- },
586
574
  {
587
575
  "type": "command",
588
576
  "name": "EnterShoppingCriteria",
@@ -615,11 +603,6 @@
615
603
  "name": "criteria",
616
604
  "type": "string",
617
605
  "required": true
618
- },
619
- {
620
- "name": "timestamp",
621
- "type": "Date",
622
- "required": true
623
606
  }
624
607
  ],
625
608
  "source": "internal",
@@ -646,6 +629,20 @@
646
629
  "version": 1
647
630
  }
648
631
  },
632
+ {
633
+ "type": "state",
634
+ "name": "Products",
635
+ "fields": [
636
+ {
637
+ "name": "products",
638
+ "type": "Array<{ productId: string; name: string; category: string; price: number; tags: Array<string>; imageUrl: string }>",
639
+ "required": true
640
+ }
641
+ ],
642
+ "metadata": {
643
+ "version": 1
644
+ }
645
+ },
649
646
  {
650
647
  "type": "event",
651
648
  "name": "ShoppingItemsSuggested",
@@ -717,11 +714,6 @@
717
714
  "name": "items",
718
715
  "type": "Array<{ productId: string; quantity: number }>",
719
716
  "required": true
720
- },
721
- {
722
- "name": "timestamp",
723
- "type": "Date",
724
- "required": true
725
717
  }
726
718
  ],
727
719
  "source": "internal",
@@ -737,13 +729,13 @@
737
729
  "source": "@auto-engineer/ai-integration"
738
730
  },
739
731
  {
740
- "name": "product-catalog",
741
- "description": "product-catalog integration",
742
- "source": "@auto-engineer/product-catalog-integration"
732
+ "name": "ProductCatalog",
733
+ "description": "ProductCatalog integration",
734
+ "source": "@auto-engineer/productcatalog-integration"
743
735
  },
744
736
  {
745
- "name": "cart",
746
- "description": "cart integration",
737
+ "name": "Cart",
738
+ "description": "Cart integration",
747
739
  "source": "@auto-engineer/cart-integration"
748
740
  }
749
741
  ]
@@ -6,7 +6,7 @@
6
6
  "scripts": {
7
7
  "start": "tsx --no-deprecation src/server.ts",
8
8
  "type-check": "tsc --noEmit",
9
- "test": "vitest run --reporter=dot",
9
+ "test": "vitest run",
10
10
  "dev": "tsx --no-deprecation src/server.ts"
11
11
  },
12
12
  "dependencies": {
@@ -20,7 +20,6 @@
20
20
  },
21
21
  "devDependencies": {
22
22
  "typescript": "~5.8.3",
23
- "vitest": "^3.2.3",
24
23
  "tsx": "^4.7.1"
25
24
  }
26
25
  }
@@ -38,7 +38,6 @@ describe('Seasonal Assistant | accepts items and adds to their cart', () => {
38
38
  { productId: 'prod-laptop-bag', quantity: 1 },
39
39
  { productId: 'prod-mtg-starter', quantity: 1 },
40
40
  ],
41
- timestamp: new Date('2025-09-04T21:20:20.310Z'),
42
41
  },
43
42
  },
44
43
  ]);
@@ -5,6 +5,5 @@ export type ItemsAddedToCart = Event<
5
5
  {
6
6
  sessionId: string;
7
7
  items: Array<{ productId: string; quantity: number }>;
8
- timestamp: Date;
9
8
  }
10
9
  >;
@@ -34,7 +34,6 @@ describe('SeasonalAssistant | CreatesAChatSession', () => {
34
34
  sessionId: 'session-abc',
35
35
  criteria:
36
36
  'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
37
- timestamp: new Date('2025-09-04T21:20:20.309Z'),
38
37
  },
39
38
  })
40
39
 
@@ -30,7 +30,6 @@ describe('Seasonal Assistant | enters shopping criteria into assistant', () => {
30
30
  sessionId: 'shopper-123',
31
31
  criteria:
32
32
  'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
33
- timestamp: new Date('2025-09-04T21:20:20.309Z'),
34
33
  },
35
34
  },
36
35
  ]);
@@ -5,6 +5,5 @@ export type ShoppingCriteriaEntered = Event<
5
5
  {
6
6
  sessionId: string;
7
7
  criteria: string;
8
- timestamp: Date;
9
8
  }
10
9
  >;
@@ -2,7 +2,7 @@ import { IllegalStateError } from '@event-driven-io/emmett';
2
2
  import type { State } from './state';
3
3
  import type { SuggestShoppingItems } from './commands';
4
4
  import type { ShoppingItemsSuggested } from './events';
5
- import type { Products } from '@auto-engineer/product-catalog-integration';
5
+ import type { Products } from '@auto-engineer/productcatalog-integration';
6
6
 
7
7
  export const decide = (command: SuggestShoppingItems, state: State, products?: Products): ShoppingItemsSuggested => {
8
8
  switch (command.type) {
@@ -1,8 +1,8 @@
1
- import '@auto-engineer/product-catalog-integration';
1
+ import '@auto-engineer/productcatalog-integration';
2
2
 
3
3
  import { AI } from '@auto-engineer/ai-integration';
4
4
 
5
- import { Products } from '@auto-engineer/product-catalog-integration';
5
+ import { Products } from '@auto-engineer/productcatalog-integration';
6
6
 
7
7
  import { CommandHandler, type EventStore, type MessageHandlerResult } from '@event-driven-io/emmett';
8
8
  import { evolve } from './evolve';
@@ -29,6 +29,7 @@ import {
29
29
  type ClientImplementedEvent,
30
30
  type ClientImplementationFailedEvent,
31
31
  } from '@auto-engineer/frontend-implementer';
32
+ import { type GenerateClientCommand } from '@auto-engineer/frontend-generator-react-graphql';
32
33
 
33
34
  // Plugin configuration
34
35
  export default {
@@ -100,7 +101,10 @@ const completedOperations = fold<string[], Event>('*', (state = [], event) => {
100
101
  on<SchemaExportedEvent>('SchemaExported', (event) =>
101
102
  dispatch<GenerateServerCommand>({
102
103
  type: 'GenerateServer',
103
- data: { schemaPath: event.data.outputPath, destination: event.data.outputPath.replace('/schema.json', '/server') },
104
+ data: {
105
+ schemaPath: event.data.outputPath,
106
+ destination: event.data.outputPath.replace('/.context/schema.json', '/server'),
107
+ },
104
108
  }),
105
109
  );
106
110
 
@@ -122,16 +126,20 @@ on<ServerGeneratedEvent>('ServerGenerated', (event) =>
122
126
  // ]),
123
127
  // );
124
128
 
125
- // on<IAGeneratedEvent>('IAGenerated', (event) =>
126
- // dispatch<ImplementClientCommand>({
127
- // type: 'ImplementClient',
128
- // data: {
129
- // projectDir: event.data.outputDir.replace('/.context', '/client'),
130
- // iaSchemeDir: event.data.outputDir,
131
- // designSystemPath: './.context/design-system.md',
132
- // },
133
- // }),
134
- // );
129
+ on<SchemaExportedEvent>('SchemaExported', (event) =>
130
+ dispatch<GenerateClientCommand>({
131
+ type: 'GenerateClient',
132
+ data: {
133
+ starterDir:
134
+ '/Users/sam/WebstormProjects/top/auto-engineer/packages/frontend-generator-react-graphql/shadcn-starter',
135
+ targetDir: '/Users/sam/WebstormProjects/top/auto-engineer/examples/shopping-app/client',
136
+ iaSchemaPath: '/Users/sam/WebstormProjects/top/auto-engineer/examples/shopping-app/.context/auto-ia-scheme.json',
137
+ gqlSchemaPath: '/Users/sam/WebstormProjects/top/auto-engineer/examples/shopping-app/.context/schema.graphql',
138
+ figmaVariablesPath:
139
+ '/Users/sam/WebstormProjects/top/auto-engineer/examples/shopping-app/.context/figma-variables.json',
140
+ },
141
+ }),
142
+ );
135
143
 
136
144
  // on<ClientImplementedEvent>('ClientImplemented', (event) =>
137
145
  // dispatch<CheckClientCommand>({ type: 'CheckClient', data: { clientDirectory: './client', skipBrowserChecks: true } }),
@@ -22,7 +22,6 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "@eslint/js": "^8.57.0",
25
- "typescript-eslint": "^7.0.0",
26
- "vitest": "^3.2.4"
25
+ "typescript-eslint": "^7.0.0"
27
26
  }
28
27
  }
@@ -24,7 +24,6 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "@eslint/js": "^8.57.0",
27
- "typescript-eslint": "^7.0.0",
28
- "vitest": "^3.2.4"
27
+ "typescript-eslint": "^7.0.0"
29
28
  }
30
29
  }
@@ -35,8 +35,7 @@
35
35
  "supertest": "^6.3.3",
36
36
  "ts-node": "^10.9.1",
37
37
  "tsx": "^4.20.3",
38
- "typescript": "^5.3.3",
39
- "vitest": "^1.0.0"
38
+ "typescript": "^5.3.3"
40
39
  },
41
40
  "keywords": [
42
41
  "cart",
@@ -25,7 +25,6 @@
25
25
  },
26
26
  "devDependencies": {
27
27
  "@eslint/js": "^8.57.0",
28
- "typescript-eslint": "^7.0.0",
29
- "vitest": "^3.2.4"
28
+ "typescript-eslint": "^7.0.0"
30
29
  }
31
30
  }
@@ -35,8 +35,7 @@
35
35
  "supertest": "^6.3.3",
36
36
  "ts-node": "^10.9.1",
37
37
  "tsx": "^4.20.3",
38
- "typescript": "^5.3.3",
39
- "vitest": "^1.0.0"
38
+ "typescript": "^5.3.3"
40
39
  },
41
40
  "keywords": [
42
41
  "product",
@@ -23,7 +23,6 @@ type ShoppingCriteriaEntered = Event<
23
23
  {
24
24
  sessionId: string;
25
25
  criteria: string;
26
- timestamp: Date;
27
26
  }
28
27
  >;
29
28
 
@@ -32,7 +31,6 @@ type ItemsAddedToCart = Event<
32
31
  {
33
32
  sessionId: string;
34
33
  items: { productId: string; quantity: number }[];
35
- timestamp: Date;
36
34
  }
37
35
  >;
38
36
 
@@ -76,8 +74,6 @@ type AddItemsToCart = Command<
76
74
  }
77
75
  >;
78
76
 
79
- // Using generic DSL instead of typed builders
80
-
81
77
  flow('Seasonal Assistant', () => {
82
78
  commandSlice('enters shopping criteria into assistant')
83
79
  .client(() => {
@@ -111,14 +107,11 @@ flow('Seasonal Assistant', () => {
111
107
  criteria:
112
108
  'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
113
109
  })
114
- .then<ShoppingCriteriaEntered>([
115
- {
116
- sessionId: 'shopper-123',
117
- criteria:
118
- 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
119
- timestamp: new Date(),
120
- },
121
- ]);
110
+ .then<ShoppingCriteriaEntered>({
111
+ sessionId: 'shopper-123',
112
+ criteria:
113
+ 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
114
+ });
122
115
  });
123
116
  });
124
117
  });
@@ -127,21 +120,16 @@ flow('Seasonal Assistant', () => {
127
120
  specs('When shopping criteria are entered, request wishlist creation', () => {
128
121
  rule('Shopping criteria should trigger item suggestion', () => {
129
122
  example('Criteria entered triggers wishlist creation')
130
- .when<ShoppingCriteriaEntered>([
131
- {
132
- sessionId: 'session-abc',
133
- criteria:
134
- 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
135
- timestamp: new Date(),
136
- },
137
- ])
138
- .then<SuggestShoppingItems>([
139
- {
140
- sessionId: 'session-abc',
141
- prompt:
142
- 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
143
- },
144
- ]);
123
+ .when<ShoppingCriteriaEntered>({
124
+ sessionId: 'session-abc',
125
+ criteria:
126
+ 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
127
+ })
128
+ .then<SuggestShoppingItems>({
129
+ sessionId: 'session-abc',
130
+ prompt:
131
+ 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
132
+ });
145
133
  });
146
134
  });
147
135
  });
@@ -161,80 +149,76 @@ flow('Seasonal Assistant', () => {
161
149
  specs('When chat is triggered, AI suggests items based on product catalog', () => {
162
150
  rule('AI should suggest relevant items from available products', () => {
163
151
  example('Product catalog with matching items generates suggestions')
164
- .given<Products>([
165
- {
166
- products: [
167
- {
168
- productId: 'prod-soccer-ball',
169
- name: 'Super Soccer Ball',
170
- category: 'Sports',
171
- price: 10,
172
- tags: ['soccer', 'sports'],
173
- imageUrl: 'https://example.com/soccer-ball.jpg',
174
- },
175
- {
176
- productId: 'prod-craft-kit',
177
- name: 'Deluxe Craft Kit',
178
- category: 'Arts & Crafts',
179
- price: 25,
180
- tags: ['crafts', 'art', 'creative'],
181
- imageUrl: 'https://example.com/craft-kit.jpg',
182
- },
183
- {
184
- productId: 'prod-laptop-bag',
185
- name: 'Tech Laptop Backpack',
186
- category: 'School Supplies',
187
- price: 45,
188
- tags: ['computers', 'tech', 'school'],
189
- imageUrl: 'https://example.com/laptop-bag.jpg',
190
- },
191
- {
192
- productId: 'prod-mtg-starter',
193
- name: 'Magic the Gathering Starter Set',
194
- category: 'Games',
195
- price: 30,
196
- tags: ['magic', 'tcg', 'games'],
197
- imageUrl: 'https://example.com/mtg-starter.jpg',
198
- },
199
- ],
200
- },
201
- ])
152
+ .given<Products>({
153
+ products: [
154
+ {
155
+ productId: 'prod-soccer-ball',
156
+ name: 'Super Soccer Ball',
157
+ category: 'Sports',
158
+ price: 10,
159
+ tags: ['soccer', 'sports'],
160
+ imageUrl: 'https://example.com/soccer-ball.jpg',
161
+ },
162
+ {
163
+ productId: 'prod-craft-kit',
164
+ name: 'Deluxe Craft Kit',
165
+ category: 'Arts & Crafts',
166
+ price: 25,
167
+ tags: ['crafts', 'art', 'creative'],
168
+ imageUrl: 'https://example.com/craft-kit.jpg',
169
+ },
170
+ {
171
+ productId: 'prod-laptop-bag',
172
+ name: 'Tech Laptop Backpack',
173
+ category: 'School Supplies',
174
+ price: 45,
175
+ tags: ['computers', 'tech', 'school'],
176
+ imageUrl: 'https://example.com/laptop-bag.jpg',
177
+ },
178
+ {
179
+ productId: 'prod-mtg-starter',
180
+ name: 'Magic the Gathering Starter Set',
181
+ category: 'Games',
182
+ price: 30,
183
+ tags: ['magic', 'tcg', 'games'],
184
+ imageUrl: 'https://example.com/mtg-starter.jpg',
185
+ },
186
+ ],
187
+ })
202
188
  .when<SuggestShoppingItems>({
203
189
  sessionId: 'session-abc',
204
190
  prompt:
205
191
  'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
206
192
  })
207
- .then<ShoppingItemsSuggested>([
208
- {
209
- sessionId: 'session-abc',
210
- suggestedItems: [
211
- {
212
- productId: 'prod-soccer-ball',
213
- name: 'Super Soccer Ball',
214
- quantity: 1,
215
- reason: 'Perfect for your daughter who loves soccer',
216
- },
217
- {
218
- productId: 'prod-craft-kit',
219
- name: 'Deluxe Craft Kit',
220
- quantity: 1,
221
- reason: 'Great for creative activities and crafts',
222
- },
223
- {
224
- productId: 'prod-laptop-bag',
225
- name: 'Tech Laptop Backpack',
226
- quantity: 1,
227
- reason: `Essential for your son's school computer needs`,
228
- },
229
- {
230
- productId: 'prod-mtg-starter',
231
- name: 'Magic the Gathering Starter Set',
232
- quantity: 1,
233
- reason: 'Ideal starter set for Magic the Gathering enthusiasts',
234
- },
235
- ],
236
- },
237
- ]);
193
+ .then<ShoppingItemsSuggested>({
194
+ sessionId: 'session-abc',
195
+ suggestedItems: [
196
+ {
197
+ productId: 'prod-soccer-ball',
198
+ name: 'Super Soccer Ball',
199
+ quantity: 1,
200
+ reason: 'Perfect for your daughter who loves soccer',
201
+ },
202
+ {
203
+ productId: 'prod-craft-kit',
204
+ name: 'Deluxe Craft Kit',
205
+ quantity: 1,
206
+ reason: 'Great for creative activities and crafts',
207
+ },
208
+ {
209
+ productId: 'prod-laptop-bag',
210
+ name: 'Tech Laptop Backpack',
211
+ quantity: 1,
212
+ reason: `Essential for your son's school computer needs`,
213
+ },
214
+ {
215
+ productId: 'prod-mtg-starter',
216
+ name: 'Magic the Gathering Starter Set',
217
+ quantity: 1,
218
+ reason: 'Ideal starter set for Magic the Gathering enthusiasts',
219
+ },
220
+ ],
221
+ });
238
222
  });
239
223
  });
240
224
  });
@@ -358,7 +342,6 @@ flow('Seasonal Assistant', () => {
358
342
  { productId: 'prod-laptop-bag', quantity: 1 },
359
343
  { productId: 'prod-mtg-starter', quantity: 1 },
360
344
  ],
361
- timestamp: new Date(),
362
345
  });
363
346
  });
364
347
  });
@@ -3,8 +3,8 @@
3
3
  "private": true,
4
4
  "type": "module",
5
5
  "scripts": {
6
- "auto": "auto",
7
- "auto:debug": "DEBUG=flow:*,cli:* auto",
6
+ "auto": "node ../../packages/cli/dist/bin/auto.js",
7
+ "auto:debug": "DEBUG=flow:*,cli:*,auto*,ai*,-*file-syncer node ../../packages/cli/dist/bin/auto.js",
8
8
  "start": "dotenv -e .env -- pnpm --parallel start",
9
9
  "build": "tsc",
10
10
  "start:ecommerce-site": "cd examples/ecommerce-site && pnpm start",
@@ -14,7 +14,7 @@ async function main() {
14
14
  });
15
15
  const printedSchema = printSchema(schema);
16
16
 
17
- const contextDir = path.resolve('/Users/sam/WebstormProjects/top/my-shop', '.context');
17
+ const contextDir = path.resolve('../.context');
18
18
  const schemaPath = path.join(contextDir, 'schema.graphql');
19
19
  await writeFile(schemaPath, printedSchema, 'utf-8');
20
20
 
@@ -1,5 +1,6 @@
1
1
  import type { State, Integration } from '@auto-engineer/flow';
2
- import { registerTool, z } from '@auto-engineer/ai-gateway';
2
+ import { registerTool } from '@auto-engineer/ai-gateway';
3
+ import { z } from 'zod';
3
4
 
4
5
  import { createClient } from './generated/product-catalog/client';
5
6
  import type {
@@ -109,6 +110,7 @@ const _ProductCatalog: Integration<'product-catalog', ProductCatalogQueries> = {
109
110
  // ---------- Lazy MCP tool registration ----------
110
111
  let _toolsRegistered = false;
111
112
 
113
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
112
114
  function registerProductCatalogToolsOnce(): void {
113
115
  if (_toolsRegistered) return;
114
116
  _toolsRegistered = true;
@@ -126,12 +128,6 @@ function registerProductCatalogToolsOnce(): void {
126
128
  },
127
129
  async () => {
128
130
  const queries = _ProductCatalog.Queries as ProductCatalogQueries;
129
- if (!queries?.Products) {
130
- return {
131
- content: [{ type: 'text' as const, text: 'ProductCatalog.Queries.Products is not available' }],
132
- isError: true,
133
- };
134
- }
135
131
  const result = await queries.Products();
136
132
  return { content: [{ type: 'text' as const, text: JSON.stringify(result.data.products, null, 2) }] };
137
133
  },
@@ -151,14 +147,8 @@ function registerProductCatalogToolsOnce(): void {
151
147
  schemaName: 'GetApiProductsCategoryByCategoryResponse',
152
148
  schemaDescription: 'Array of ProductCatalogItem',
153
149
  },
154
- async ({ category }) => {
150
+ async ({ category }: ProductsByCategoryParams) => {
155
151
  const queries = _ProductCatalog.Queries as ProductCatalogQueries;
156
- if (!queries?.ProductsByCategory) {
157
- return {
158
- content: [{ type: 'text' as const, text: 'ProductCatalog.Queries.ProductsByCategory is not available' }],
159
- isError: true,
160
- };
161
- }
162
152
  const result = await queries.ProductsByCategory({ category });
163
153
  return { content: [{ type: 'text' as const, text: JSON.stringify(result.data.products, null, 2) }] };
164
154
  },
@@ -178,14 +168,8 @@ function registerProductCatalogToolsOnce(): void {
178
168
  schemaName: 'GetApiProductsSearchResponse',
179
169
  schemaDescription: 'Array of ProductCatalogItem',
180
170
  },
181
- async ({ query }) => {
171
+ async ({ query }: ProductSearchParams) => {
182
172
  const queries = _ProductCatalog.Queries as ProductCatalogQueries;
183
- if (!queries?.ProductSearchResults) {
184
- return {
185
- content: [{ type: 'text' as const, text: 'ProductCatalog.Queries.ProductSearchResults is not available' }],
186
- isError: true,
187
- };
188
- }
189
173
  const result = await queries.ProductSearchResults({ query });
190
174
  return { content: [{ type: 'text' as const, text: JSON.stringify(result.data.products, null, 2) }] };
191
175
  },
@@ -205,14 +189,8 @@ function registerProductCatalogToolsOnce(): void {
205
189
  schemaName: 'GetApiProductsByIdResponse',
206
190
  schemaDescription: 'Single ProductCatalogItem',
207
191
  },
208
- async ({ id }) => {
192
+ async ({ id }: ProductDetailsParams) => {
209
193
  const queries = _ProductCatalog.Queries as ProductCatalogQueries;
210
- if (!queries?.ProductDetails) {
211
- return {
212
- content: [{ type: 'text' as const, text: 'ProductCatalog.Queries.ProductDetails is not available' }],
213
- isError: true,
214
- };
215
- }
216
194
  const result = await queries.ProductDetails({ id });
217
195
  if (result.data.product === null) {
218
196
  return { content: [{ type: 'text' as const, text: `Product with ID "${id}" not found` }], isError: true };
@@ -221,12 +199,13 @@ function registerProductCatalogToolsOnce(): void {
221
199
  },
222
200
  );
223
201
  }
202
+ /* eslint-enable @typescript-eslint/no-unsafe-call */
224
203
 
225
204
  // registers tools on *first usage* of the integration
226
205
  export const ProductCatalog: Integration<'product-catalog', ProductCatalogQueries> = new Proxy(_ProductCatalog, {
227
206
  get(target, prop, receiver) {
228
207
  // First touch of ProductCatalog triggers tool registration
229
208
  registerProductCatalogToolsOnce();
230
- return Reflect.get(target, prop, receiver);
209
+ return Reflect.get(target, prop, receiver) as unknown;
231
210
  },
232
211
  });
@@ -8,7 +8,9 @@
8
8
  "experimentalDecorators": true,
9
9
  "outDir": "./dist",
10
10
  "rootDir": ".",
11
- "noEmit": false
11
+ "noEmit": false,
12
+ "strict": true,
13
+ "strictNullChecks": true
12
14
  },
13
15
  "include": ["flows/**/*", "vitest.config.ts"],
14
16
  "exclude": ["dist", "node_modules"]
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "extends": ["//"],
4
+ "tasks": {
5
+ "auto": {
6
+ "dependsOn": ["^build"],
7
+ "inputs": []
8
+ },
9
+ "auto:debug": {
10
+ "dependsOn": ["^build"],
11
+ "inputs": []
12
+ },
13
+ "build": {
14
+ "dependsOn": ["^build"],
15
+ "inputs": [],
16
+ "outputs": []
17
+ }
18
+ }
19
+ }
@@ -1,6 +0,0 @@
1
- export default {
2
- plugins: {
3
- tailwindcss: {},
4
- autoprefixer: {},
5
- },
6
- };