@wix/ditto-codegen-public 1.0.16 → 1.0.17

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 (2) hide show
  1. package/dist/out.js +707 -130
  2. package/package.json +2 -2
package/dist/out.js CHANGED
@@ -114034,16 +114034,23 @@ var require_index_node = __commonJS({
114034
114034
  var require_utils14 = __commonJS({
114035
114035
  "dist/agents/utils.js"(exports2) {
114036
114036
  "use strict";
114037
+ var __importDefault2 = exports2 && exports2.__importDefault || function(mod2) {
114038
+ return mod2 && mod2.__esModule ? mod2 : { "default": mod2 };
114039
+ };
114037
114040
  Object.defineProperty(exports2, "__esModule", { value: true });
114038
- exports2.getHttpClient = exports2.withCaching = exports2.GeneratedFileSchema = exports2.FileSchema = void 0;
114041
+ exports2.buildUserPromptForCodeGenerationAgent = exports2.getHttpClient = exports2.withCaching = exports2.FileSchema = void 0;
114042
+ exports2.loadRelevantFilesAsString = loadRelevantFilesAsString;
114039
114043
  var zod_1 = require_zod();
114040
114044
  var http_client_1 = require_index_node();
114041
- exports2.FileSchema = zod_1.z.object({
114042
- content: zod_1.z.string().describe("Complete file content as a string (for JSON files, stringify the object)")
114045
+ var fs_1 = __importDefault2(require("fs"));
114046
+ var path_1 = __importDefault2(require("path"));
114047
+ var FileItemSchema = zod_1.z.object({
114048
+ operation: zod_1.z.enum(["insert", "update", "delete"]).describe("File operation: insert (new file), update (modify existing), delete (remove file)").default("insert"),
114049
+ path: zod_1.z.string().describe("Relative file path from project root").optional(),
114050
+ content: zod_1.z.string().describe("Complete file content as a string (for JSON files, stringify the object). Required for insert and update operations.").optional()
114043
114051
  });
114044
- exports2.GeneratedFileSchema = zod_1.z.object({
114045
- path: zod_1.z.string().describe("Relative file path from project root"),
114046
- content: exports2.FileSchema.shape.content
114052
+ exports2.FileSchema = zod_1.z.object({
114053
+ files: zod_1.z.array(FileItemSchema).default([])
114047
114054
  });
114048
114055
  var withCaching = (ttl = "5m") => {
114049
114056
  return {
@@ -114068,6 +114075,78 @@ var require_utils14 = __commonJS({
114068
114075
  timeout: 6e6
114069
114076
  });
114070
114077
  exports2.getHttpClient = getHttpClient;
114078
+ function loadRelevantFiles(relevantFilePaths = [], basePath) {
114079
+ return relevantFilePaths.map((filePath) => {
114080
+ const fullPath = path_1.default.isAbsolute(basePath) ? path_1.default.join(basePath, filePath) : path_1.default.join(process.cwd(), basePath, filePath);
114081
+ try {
114082
+ if (!fs_1.default.existsSync(fullPath)) {
114083
+ return `Path: ${filePath}
114084
+
114085
+ [File does not exist]`;
114086
+ }
114087
+ const stats = fs_1.default.statSync(fullPath);
114088
+ if (stats.isDirectory()) {
114089
+ return `Path: ${filePath}
114090
+
114091
+ [Path is a directory, not a file]`;
114092
+ }
114093
+ const content = fs_1.default.readFileSync(fullPath, "utf8");
114094
+ return `Path: ${filePath}
114095
+
114096
+ ${content}`;
114097
+ } catch (error) {
114098
+ return `Path: ${filePath}
114099
+
114100
+ [Could not read file: ${error instanceof Error ? error.message : "Unknown error"}]`;
114101
+ }
114102
+ });
114103
+ }
114104
+ function loadRelevantFilesAsString(relevantFilePaths = [], basePath) {
114105
+ const srcOnlyPaths = relevantFilePaths.filter((p) => {
114106
+ const normalized = path_1.default.normalize(p);
114107
+ return normalized.startsWith("src" + path_1.default.sep);
114108
+ });
114109
+ return loadRelevantFiles(srcOnlyPaths, basePath).join("\n\n---\n\n");
114110
+ }
114111
+ var buildUserPromptForCodeGenerationAgent = (params, primaryAction) => {
114112
+ const { extension, blueprint, scaffold, userRequestSummary, relevantFilePaths, createdCollections, basePath } = params;
114113
+ const contextSections = [];
114114
+ if (extension.name)
114115
+ contextSections.push(`Extension Name: ${extension.name}`);
114116
+ if (extension.description)
114117
+ contextSections.push(`Extension Description: ${extension.description}`);
114118
+ if (blueprint?.summary) {
114119
+ contextSections.push(`App Summary: ${blueprint.summary}`);
114120
+ }
114121
+ if (userRequestSummary) {
114122
+ contextSections.push(`
114123
+ ## USER REQUEST
114124
+ ${userRequestSummary}`);
114125
+ }
114126
+ if (relevantFilePaths) {
114127
+ const relevantFiles = loadRelevantFilesAsString(relevantFilePaths, basePath);
114128
+ contextSections.push(`
114129
+ ## RELEVANT FILES
114130
+ ${relevantFiles}`);
114131
+ }
114132
+ if (scaffold) {
114133
+ contextSections.push(`
114134
+ ## CURRENT SCAFFOLDED FILE
114135
+ Path: ${scaffold.path}
114136
+ \`\`\`
114137
+ ${scaffold.content}
114138
+ \`\`\``);
114139
+ }
114140
+ if (createdCollections) {
114141
+ contextSections.push(`
114142
+ ## CREATED COLLECTIONS
114143
+ ${JSON.stringify(createdCollections, null, 2)}`);
114144
+ }
114145
+ const userMessage = `${primaryAction}:
114146
+ ${contextSections.join("\n")}`;
114147
+ return userMessage;
114148
+ };
114149
+ exports2.buildUserPromptForCodeGenerationAgent = buildUserPromptForCodeGenerationAgent;
114071
114150
  }
114072
114151
  });
114073
114152
 
@@ -114351,22 +114430,17 @@ var require_SPIAgent = __commonJS({
114351
114430
  buildSystemPrompt(spiNames = []) {
114352
114431
  return (0, servicePluginPrompt_1.getServicePluginPrompt)(spiNames);
114353
114432
  }
114354
- async generate(extension, blueprint, scaffold) {
114433
+ async generate(params) {
114434
+ const { extension, blueprint } = params;
114355
114435
  const examples = (0, load_examples_1.loadExamples)([load_examples_1.types.ServicePluginExtension]);
114356
114436
  const allSpiNames = extension.relatedSpis?.map((spi) => spi.name).filter((name) => !!name) || [];
114357
114437
  const systemPrompt = `${this.buildSystemPrompt(allSpiNames)}
114358
114438
  ${examples}
114359
114439
  `;
114360
114440
  console.log(`SPI Agent System Prompt length: ${systemPrompt.length} (is that what you expect?)`);
114361
- const userMessage = `Customize the Wix CLI service plugin scaffolding for the app "${blueprint.appName}":
114362
- Extension Name: ${extension.name}
114363
- Extension Description: ${extension.description}
114364
- App Summary: ${blueprint.summary}
114365
- ## CURRENT SCAFFOLDED FILE
114366
- Path: ${scaffold.path}
114367
- \`\`\`
114368
- ${scaffold.content}
114369
- \`\`\``;
114441
+ const appName = blueprint?.appName ? `'${blueprint.appName}'` : "";
114442
+ const primaryAction = `Customize the Wix CLI service plugin scaffolding for the app ${appName}`;
114443
+ const userMessage = (0, utils_1.buildUserPromptForCodeGenerationAgent)(params, primaryAction);
114370
114444
  const model = (0, anthropic_1.createAnthropic)({
114371
114445
  apiKey: this.apiKey
114372
114446
  })("claude-sonnet-4-20250514");
@@ -114391,7 +114465,7 @@ ${scaffold.content}
114391
114465
  maxRetries: 3,
114392
114466
  temperature: 0
114393
114467
  });
114394
- return result.object;
114468
+ return result.object.files;
114395
114469
  }
114396
114470
  };
114397
114471
  exports2.SPIAgent = SPIAgent;
@@ -115220,6 +115294,39 @@ ${blocks}
115220
115294
  }
115221
115295
  });
115222
115296
 
115297
+ // dist/system-prompts/dashboardPage/data.js
115298
+ var require_data = __commonJS({
115299
+ "dist/system-prompts/dashboardPage/data.js"(exports2) {
115300
+ "use strict";
115301
+ Object.defineProperty(exports2, "__esModule", { value: true });
115302
+ exports2.dataPrompt = void 0;
115303
+ exports2.dataPrompt = `<wix_data_docs>
115304
+ Summary:
115305
+ - Read: items.query('Collection').filter/sort.limit.find() \u2192 { items, totalCount, hasNext }
115306
+ - Write: items.insert | update | remove. Ensure collection permissions allow the action
115307
+
115308
+ Access data using the collection schema:
115309
+ - Always use the exact field keys you defined in the collection schema.
115310
+ - YOU MUST use the collection id exactly as you defined it in the collection schema.
115311
+
115312
+ Example - Insert / Update / Delete (if permissions allow):
115313
+ import { items } from '@wix/data';
115314
+
115315
+ async function addItem(collectionId: string, itemData: WixDataItem) {
115316
+ return items.insert(collectionId, itemData);
115317
+ }
115318
+
115319
+ async function renameItem(collectionId: string, itemData: WixDataItem) {
115320
+ await items.update(collectionId, itemData);
115321
+ }
115322
+
115323
+ async function deleteItem(collectionId: string, itemId: WixDataItem) {
115324
+ await items.remove(collectionId, itemId);
115325
+ }
115326
+ </wix_data_docs>`;
115327
+ }
115328
+ });
115329
+
115223
115330
  // dist/system-prompts/dashboardPage/dashboardPagePrompt.js
115224
115331
  var require_dashboardPagePrompt = __commonJS({
115225
115332
  "dist/system-prompts/dashboardPage/dashboardPagePrompt.js"(exports2) {
@@ -115229,6 +115336,7 @@ var require_dashboardPagePrompt = __commonJS({
115229
115336
  var ecomPackage_1 = require_ecomPackage();
115230
115337
  var dashboardPackage_1 = require_dashboardPackage();
115231
115338
  var wdsPackage_1 = require_wdsPackage();
115339
+ var data_1 = require_data();
115232
115340
  var wdsPackage_2 = require_wdsPackage();
115233
115341
  Object.defineProperty(exports2, "buildWdsSystemPrompt", { enumerable: true, get: function() {
115234
115342
  return wdsPackage_2.buildWdsSystemPrompt;
@@ -115257,7 +115365,7 @@ var require_dashboardPagePrompt = __commonJS({
115257
115365
  "ToggleSwitch",
115258
115366
  "InfoIcon"
115259
115367
  ];
115260
- var dashboardPagePrompt = async () => {
115368
+ var dashboardPagePrompt = async (useData) => {
115261
115369
  const wdsPrompt = await (0, wdsPackage_1.buildWdsSystemPrompt)(listOfWdsComponents);
115262
115370
  return `
115263
115371
  <WIXCLI_DASHBOARD_PAGE_SYSTEM_PROMPT>
@@ -115321,8 +115429,6 @@ ${dashboardPackage_1.dashboardPackage}
115321
115429
  ${ecomPackage_1.ecomPackage}
115322
115430
  </api_references>
115323
115431
 
115324
-
115325
-
115326
115432
  <wds_reference>
115327
115433
  ${wdsPrompt}
115328
115434
  </wds_reference>
@@ -115336,30 +115442,7 @@ ${wdsPrompt}
115336
115442
  - Do NOT use // @ts-ignore or // @ts-expect-error; fix the types or add guards instead
115337
115443
  </typescript_quality_guidelines>
115338
115444
 
115339
- <wix_data_docs>
115340
- Summary:
115341
- - Read: items.query('Collection').filter/sort.limit.find() \u2192 { items, totalCount, hasNext }
115342
- - Write: items.insert | update | remove. Ensure collection permissions allow the action
115343
-
115344
- Access data using the collection schema:
115345
- - Always use the exact field keys you defined in the collection schema.
115346
- - YOU MUST use the collection id exactly as you defined it in the collection schema.
115347
-
115348
- Example - Insert / Update / Delete (if permissions allow):
115349
- import { items } from '@wix/data';
115350
-
115351
- async function addItem(collectionId: string, itemData: WixDataItem) {
115352
- return items.insert(collectionId, itemData);
115353
- }
115354
-
115355
- async function renameItem(collectionId: string, itemData: WixDataItem) {
115356
- await items.update(collectionId, itemData);
115357
- }
115358
-
115359
- async function deleteItem(collectionId: string, itemId: WixDataItem) {
115360
- await items.remove(collectionId, itemId);
115361
- }
115362
- </wix_data_docs>
115445
+ ${useData ? data_1.dataPrompt : ""}
115363
115446
  </WIXCLI_DASHBOARD_PAGE_SYSTEM_PROMPT>
115364
115447
  `;
115365
115448
  };
@@ -115383,28 +115466,20 @@ var require_DashboardPageAgent = __commonJS({
115383
115466
  this.apiKey = apiKey;
115384
115467
  this.name = "DashboardPageAgent";
115385
115468
  }
115386
- async buildSystemPrompt() {
115387
- return (0, dashboardPagePrompt_1.dashboardPagePrompt)();
115469
+ async buildSystemPrompt(useData) {
115470
+ return (0, dashboardPagePrompt_1.dashboardPagePrompt)(useData);
115388
115471
  }
115389
- async generate(extension, blueprint, scaffold, createdCollections) {
115472
+ async generate(params) {
115473
+ const { blueprint, createdCollections } = params;
115390
115474
  const examples = (0, load_examples_1.loadExamples)([load_examples_1.types.DashboardPage]);
115391
- const systemPrompt = `${await this.buildSystemPrompt()}
115475
+ const useData = Boolean(createdCollections && createdCollections.length > 0);
115476
+ const systemPrompt = `${await this.buildSystemPrompt(useData)}
115392
115477
  ${examples}
115393
115478
  `;
115394
115479
  console.log(`Dashboard Agent System Prompt length: ${systemPrompt.length} (is that what you expect?)`);
115395
- const userMessage = `Customize the Wix CLI dashboard page scaffolding for the app "${blueprint.appName}":
115396
- Extension Name: ${extension.name}
115397
- Extension Description: ${extension.description}
115398
- App Summary: ${blueprint.summary}
115399
-
115400
- ## CREATED COLLECTIONS
115401
- ${JSON.stringify(createdCollections, null, 2)}
115402
-
115403
- ## CURRENT SCAFFOLDED FILE
115404
- Path: ${scaffold.path}
115405
- \`\`\`
115406
- ${scaffold.content}
115407
- \`\`\``;
115480
+ const appName = blueprint?.appName ? `'${blueprint.appName}'` : "";
115481
+ const primaryAction = `Customize the Wix CLI dashboard page scaffolding for the app ${appName}`;
115482
+ const userMessage = (0, utils_1.buildUserPromptForCodeGenerationAgent)(params, primaryAction);
115408
115483
  const model = (0, anthropic_1.createAnthropic)({ apiKey: this.apiKey })("claude-sonnet-4-20250514");
115409
115484
  const result = await (0, ai_1.generateObject)({
115410
115485
  model,
@@ -115428,7 +115503,7 @@ ${scaffold.content}
115428
115503
  maxRetries: 3,
115429
115504
  temperature: 0
115430
115505
  });
115431
- return result.object;
115506
+ return result.object.files;
115432
115507
  }
115433
115508
  };
115434
115509
  exports2.DashboardPageAgent = DashboardPageAgent;
@@ -115437,7 +115512,7 @@ ${scaffold.content}
115437
115512
  });
115438
115513
 
115439
115514
  // dist/system-prompts/planner/data.js
115440
- var require_data = __commonJS({
115515
+ var require_data2 = __commonJS({
115441
115516
  "dist/system-prompts/planner/data.js"(exports2) {
115442
115517
  "use strict";
115443
115518
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -115536,7 +115611,7 @@ var require_planner = __commonJS({
115536
115611
  "use strict";
115537
115612
  Object.defineProperty(exports2, "__esModule", { value: true });
115538
115613
  exports2.plannerPrompt = void 0;
115539
- var data_1 = require_data();
115614
+ var data_1 = require_data2();
115540
115615
  var plannerPrompt = () => `
115541
115616
  <WIXCLI_PLANNER_SYSTEM_PROMPT>
115542
115617
  ${(0, data_1.cmsPlannerPrompt)()}
@@ -119122,18 +119197,12 @@ var require_SiteComponentAgent = __commonJS({
119122
119197
  async buildSystemPrompt() {
119123
119198
  return (0, siteComponentPrompt_1.siteComponentPrompt)();
119124
119199
  }
119125
- async generate(extension, blueprint, scaffold) {
119200
+ async generate(params) {
119201
+ const { blueprint } = params;
119126
119202
  const systemPrompt = `${await this.buildSystemPrompt()}`;
119127
- const userMessage = `Customize the Wix CLI dashboard page scaffolding for the app "${blueprint.appName}":
119128
- Extension Name: ${extension.name}
119129
- Extension Description: ${extension.description}
119130
- App Summary: ${blueprint.summary}
119131
-
119132
- ## CURRENT SCAFFOLDED FILE
119133
- Path: ${scaffold.path}
119134
- \`\`\`
119135
- ${scaffold.content}
119136
- \`\`\``;
119203
+ const appName = blueprint?.appName ? `'${blueprint.appName}'` : "";
119204
+ const primaryAction = `Customize the Wix CLI site component scaffolding for the app ${appName}`;
119205
+ const userMessage = (0, utils_1.buildUserPromptForCodeGenerationAgent)(params, primaryAction);
119137
119206
  const model = (0, anthropic_1.createAnthropic)({ apiKey: this.apiKey })("claude-sonnet-4-20250514");
119138
119207
  const result = await (0, ai_1.generateObject)({
119139
119208
  model,
@@ -119157,7 +119226,7 @@ ${scaffold.content}
119157
119226
  maxRetries: 3,
119158
119227
  temperature: 0
119159
119228
  });
119160
- return result.object;
119229
+ return result.object.files;
119161
119230
  }
119162
119231
  };
119163
119232
  exports2.SiteComponentAgent = SiteComponentAgent;
@@ -119165,6 +119234,261 @@ ${scaffold.content}
119165
119234
  }
119166
119235
  });
119167
119236
 
119237
+ // dist/system-prompts/iterationAgent/iterationAgentPrompt.js
119238
+ var require_iterationAgentPrompt = __commonJS({
119239
+ "dist/system-prompts/iterationAgent/iterationAgentPrompt.js"(exports2) {
119240
+ "use strict";
119241
+ Object.defineProperty(exports2, "__esModule", { value: true });
119242
+ exports2.iterationAgentPrompt = void 0;
119243
+ var iterationAgentPrompt = () => `
119244
+ <WIXCLI_ITERATION_AGENT_SYSTEM_PROMPT>
119245
+
119246
+ <role>
119247
+ You are an iteration agent for a Wix app code generation system.
119248
+ Given the full chat history, current user request, blueprint, and all project files:
119249
+ 1. Generate a clear summary of what the user wants to achieve
119250
+ 2. Identify which existing extensions should be triggered to handle this request
119251
+ 3. Map each triggered extension to the relevant file paths it needs to modify
119252
+ 4. Propose new extensions if the request requires functionality not covered by existing ones
119253
+ </role>
119254
+
119255
+ <supported_extension_types>
119256
+
119257
+ <dashboard_page>
119258
+ **Use when:**
119259
+ - User wants to create a management interface/admin panel
119260
+ - Need to display data tables, forms, or configuration screens
119261
+ - Building settings pages, analytics dashboards, or content management interfaces
119262
+ - Example: 'Create a dashboard to manage FAQ items', 'Add settings page for the app'
119263
+ </dashboard_page>
119264
+
119265
+ <site_component>
119266
+ **Use when:**
119267
+ - User wants to create a custom UI component for the site frontend
119268
+ - Need to build interactive widgets, forms, or display components for visitors
119269
+ - Creating custom elements that appear on the site (not admin interfaces)
119270
+ - Building components that integrate with site data or user interactions
119271
+ - Example: 'Create a product showcase widget', 'Add a contact form component', 'Build a testimonial slider'
119272
+ </site_component>
119273
+
119274
+ <service_plugin>
119275
+ **Use when:**
119276
+ - User needs custom business logic for eCommerce (fees, shipping, discounts, validations)
119277
+ - Integrating with external payment providers
119278
+ - Custom pricing calculations for bookings
119279
+ - Form validation logic
119280
+ - Example: 'Calculate custom shipping rates', 'Add payment validation', 'Custom discount rules'
119281
+
119282
+ **Available SPI Names (choose appropriate ones for relatedSpis):**
119283
+ - "ecom.shippingRates.getShippingRates" - For custom shipping rate calculations
119284
+ - "ecom.additionalFees.calculateAdditionalFees" - For calculating additional fees (handling, processing, etc.)
119285
+ - "ecom.paymentSettings.getPaymentSettings" - For payment configuration and 3D Secure settings
119286
+ - "ecom.validations.getValidationViolations" - For cart and checkout validations
119287
+ - "ecom.customTriggers.getEligibleTriggers" - For custom discount trigger logic
119288
+ - "ecom.customTriggers.listTriggers" - For listing available custom discount triggers
119289
+ - "ecom.giftCardsProvider.redeem" - For gift card redemption logic
119290
+ - "ecom.giftCardsProvider._void" - For voiding gift card transactions
119291
+ - "ecom.giftCardsProvider.getBalance" - For checking gift card balances
119292
+ - "ecom.taxCalculationProvider.calculateTax" - For custom tax calculations
119293
+ - "ecom.recommendationsProvider.getRecommendations" - For product recommendations
119294
+ - "ecom.catalog.getCatalogItems" - For external catalog integration
119295
+
119296
+ **SPI Selection Guidelines:**
119297
+ - For shipping-related requests \u2192 use "ecom.shippingRates.getShippingRates"
119298
+ - For fee calculations \u2192 use "ecom.additionalFees.calculateAdditionalFees"
119299
+ - For payment processing \u2192 use "ecom.paymentSettings.getPaymentSettings"
119300
+ - For cart/checkout validation \u2192 use "ecom.validations.getValidationViolations"
119301
+ - For discount logic \u2192 use "ecom.customTriggers.getEligibleTriggers" or "ecom.customTriggers.listTriggers"
119302
+ - For gift card functionality \u2192 use appropriate "ecom.giftCardsProvider.*" methods
119303
+ - For tax calculations \u2192 use "ecom.taxCalculationProvider.calculateTax"
119304
+ - For product recommendations \u2192 use "ecom.recommendationsProvider.getRecommendations"
119305
+ - For external catalog \u2192 use "ecom.catalog.getCatalogItems"
119306
+ </service_plugin>
119307
+
119308
+ </supported_extension_types>
119309
+
119310
+ <extension_selection_logic>
119311
+
119312
+ <selection_rules>
119313
+ 1. **For UI/Admin interfaces**: Use DASHBOARD_PAGE
119314
+ 2. **For site frontend components**: Use SITE_COMPONENT
119315
+ 3. **For eCommerce business logic**: Use SERVICE_PLUGIN
119316
+ 4. **For management interfaces**: Use DASHBOARD_PAGE
119317
+ 5. **For eCommerce features**: Combine SERVICE_PLUGIN (logic) + DASHBOARD_PAGE (configuration UI)
119318
+ 6. **For site features**: Combine SITE_COMPONENT (frontend) + SERVICE_PLUGIN (backend logic) + DASHBOARD_PAGE (admin interface)
119319
+ </selection_rules>
119320
+
119321
+ <common_patterns>
119322
+ - **eCommerce Extensions**: SERVICE_PLUGIN + DASHBOARD_PAGE
119323
+ - **Configuration/Settings Apps**: DASHBOARD_PAGE only
119324
+ - **Site Frontend Features**: SITE_COMPONENT only
119325
+ - **Full-Featured Apps**: SITE_COMPONENT + SERVICE_PLUGIN + DASHBOARD_PAGE
119326
+ </common_patterns>
119327
+
119328
+ </extension_selection_logic>
119329
+
119330
+ <constraints>
119331
+ - Return the JSON schema with currentExtensions, additionalExtensions, and summary
119332
+ - Only propose additional extensions if existing ones cannot fulfill the user's request
119333
+ - Be specific about which file paths are relevant for each current extension (all extension types)
119334
+ - Consider the full chat history context when making decisions
119335
+ - Prioritize reusing existing extensions over creating new ones
119336
+ - **SUPPORTED EXTENSION TYPES ONLY**: DASHBOARD_PAGE, SERVICE_PLUGIN, and SITE_COMPONENT
119337
+ - **IMPORTANT**: The "type" field is ONLY for SERVICE_PLUGIN extensions - specify the SPI type
119338
+ - The "paths" field is for ALL extension types - specify relevant file paths to modify
119339
+ - Choose SPI types based on the specific eCommerce functionality requested (shipping, fees, validation, etc.)
119340
+ - Each extension should have a clear relevantUserRequest explaining what part of the request it addresses
119341
+ - If files already exist for an extension (e.g., dashboard page component files or a service plugin \`plugin.ts\` under the relevant SPI directory), you MUST treat it as a currentExtensions item and update it, NOT as an additionalExtensions item
119342
+ - For currentExtensions, ensure relevantUserRequest precisely reflects the change to be applied in those files (e.g., "Update static fee from 5 ILS to 10 ILS"), not a generic description
119343
+ - Propose additionalExtensions ONLY when there is no existing file that matches the requested capability; avoid duplicates like proposing a new \`ecom.additionalFees.calculateAdditionalFees\` when one already exists in the project
119344
+ </constraints>
119345
+
119346
+ <output_format>
119347
+ The response must be a valid JSON object matching the IterationPlanSchema:
119348
+
119349
+ **Required Structure:**
119350
+ {
119351
+ "currentExtensions": [
119352
+ {
119353
+ "extensionName": "SERVICE_PLUGIN",
119354
+ "relatedSpis": ["ecom.shippingRates.getShippingRates"], // Only for SERVICE_PLUGIN extensions
119355
+ "paths": ["src/backend/service-plugins/shipping/custom-rates/plugin.ts"],
119356
+ "relevantUserRequest": "Calculate shipping rates based on product weight"
119357
+ },
119358
+ {
119359
+ "extensionName": "DASHBOARD_PAGE",
119360
+ "paths": ["src/dashboard/pages/AdminPage.tsx", "src/dashboard/components/SettingsForm.tsx"],
119361
+ "relevantUserRequest": "Provide admin interface for managing shipping settings"
119362
+ },
119363
+ {
119364
+ "extensionName": "SITE_COMPONENT",
119365
+ "paths": ["src/site/components/ProductShowcase/component.tsx"],
119366
+ "relevantUserRequest": "Create a product showcase widget for the site frontend"
119367
+ }
119368
+ ],
119369
+ "additionalExtensions": [
119370
+ {
119371
+ "extensionName": "SERVICE_PLUGIN",
119372
+ "relatedSpis": ["ecom.additionalFees.calculateAdditionalFees"], // Only for SERVICE_PLUGIN extensions
119373
+ "relevantUserRequest": "Add handling fees for fragile items"
119374
+ }
119375
+ ],
119376
+ "summary": "User wants to implement custom shipping rates and add handling fees for their eCommerce store"
119377
+ }
119378
+
119379
+ **Key Points:**
119380
+ - currentExtensions: Existing extensions that should be triggered/modified (use extensionName of "SERVICE_PLUGIN", "DASHBOARD_PAGE", or "SITE_COMPONENT")
119381
+ - additionalExtensions: New extensions that need to be created (use extensionName of "SERVICE_PLUGIN", "DASHBOARD_PAGE", or "SITE_COMPONENT")
119382
+ - summary: Brief summary combining the chat history and current user request
119383
+ - "relatedSpis" field: ONLY for SERVICE_PLUGIN extensions - specify the SPI name
119384
+ - "paths" field: For ALL extension types - specify relevant file paths to modify
119385
+ - For currentExtensions, always include paths; for additionalExtensions, paths are not needed
119386
+ </output_format>
119387
+
119388
+ </WIXCLI_ITERATION_AGENT_SYSTEM_PROMPT>
119389
+ `;
119390
+ exports2.iterationAgentPrompt = iterationAgentPrompt;
119391
+ }
119392
+ });
119393
+
119394
+ // dist/agents/IterationAgent.js
119395
+ var require_IterationAgent = __commonJS({
119396
+ "dist/agents/IterationAgent.js"(exports2) {
119397
+ "use strict";
119398
+ Object.defineProperty(exports2, "__esModule", { value: true });
119399
+ exports2.IterationAgent = exports2.IterationPlanSchema = exports2.AdditionalExtensionSchema = exports2.CurrentExtensionSchema = void 0;
119400
+ var anthropic_1 = require_dist5();
119401
+ var ai_1 = require_dist7();
119402
+ var zod_1 = require_zod();
119403
+ var utils_1 = require_utils14();
119404
+ var types_1 = require_types_impl();
119405
+ var iterationAgentPrompt_1 = require_iterationAgentPrompt();
119406
+ exports2.CurrentExtensionSchema = zod_1.z.object({
119407
+ extensionName: zod_1.z.nativeEnum(types_1.ExtensionType).describe("The extension kind to trigger"),
119408
+ relatedSpis: zod_1.z.array(zod_1.z.string()).optional().describe("Optional value, only for SPI extensions - specify the SPI types"),
119409
+ paths: zod_1.z.array(zod_1.z.string()).describe("Paths relevant for this extension"),
119410
+ relevantUserRequest: zod_1.z.string().describe("What part of the user request this extension addresses")
119411
+ });
119412
+ exports2.AdditionalExtensionSchema = zod_1.z.object({
119413
+ extensionName: zod_1.z.nativeEnum(types_1.ExtensionType).describe("The extension kind to add"),
119414
+ relatedSpis: zod_1.z.array(zod_1.z.string()).optional().describe("Optional value, only for SPI extensions - specify the SPI types"),
119415
+ relevantUserRequest: zod_1.z.string().describe("What part of the user request this extension addresses")
119416
+ });
119417
+ exports2.IterationPlanSchema = zod_1.z.object({
119418
+ currentExtensions: zod_1.z.array(exports2.CurrentExtensionSchema).describe("Existing extensions to be triggered"),
119419
+ additionalExtensions: zod_1.z.array(exports2.AdditionalExtensionSchema).describe("New extensions to be created"),
119420
+ summary: zod_1.z.string().describe("Summary of the chat with the user request")
119421
+ });
119422
+ var IterationAgent = class {
119423
+ constructor(apiKey) {
119424
+ this.apiKey = apiKey;
119425
+ this.name = "IterationAgent";
119426
+ }
119427
+ buildSystemPrompt() {
119428
+ return (0, iterationAgentPrompt_1.iterationAgentPrompt)();
119429
+ }
119430
+ mapExtensionType(extensionName) {
119431
+ switch (extensionName) {
119432
+ case "SERVICE_PLUGIN":
119433
+ return types_1.ExtensionType.SERVICE_PLUGIN;
119434
+ case "DASHBOARD_PAGE":
119435
+ return types_1.ExtensionType.DASHBOARD_PAGE;
119436
+ case "SITE_COMPONENT":
119437
+ return types_1.ExtensionType.SITE_COMPONENT;
119438
+ default:
119439
+ throw new Error(`Unsupported extension type: ${extensionName}`);
119440
+ }
119441
+ }
119442
+ async generate(outputPath, candidateFilePaths, currentUserRequest, chatHistory) {
119443
+ const model = (0, anthropic_1.createAnthropic)({ apiKey: this.apiKey })("claude-3-5-haiku-latest");
119444
+ const historyStr = (chatHistory || []).map((m) => `${m.role.toUpperCase()}: ${m.text}`).join("\n\n");
119445
+ const allFilesContent = (0, utils_1.loadRelevantFilesAsString)(candidateFilePaths, outputPath);
119446
+ const userContent = [
119447
+ `
119448
+ Full Chat History:
119449
+ ${historyStr}`,
119450
+ `
119451
+ Current User Request: ${currentUserRequest}`,
119452
+ `
119453
+ All Project Files (relative to output path):
119454
+ ${candidateFilePaths.slice(0, 1e3).join("\n")}`,
119455
+ `
119456
+ All Project Files Content:
119457
+ ${allFilesContent}`
119458
+ ].join("\n\n");
119459
+ const result = await (0, ai_1.generateObject)({
119460
+ model,
119461
+ schema: exports2.IterationPlanSchema,
119462
+ messages: [
119463
+ {
119464
+ role: "system",
119465
+ content: this.buildSystemPrompt(),
119466
+ providerOptions: (0, utils_1.withCaching)("1h")
119467
+ },
119468
+ { role: "user", content: userContent }
119469
+ ],
119470
+ maxRetries: 3,
119471
+ temperature: 0,
119472
+ experimental_telemetry: { isEnabled: true, functionId: this.name }
119473
+ });
119474
+ const resultObject = result.object;
119475
+ resultObject.currentExtensions = result.object.currentExtensions.map((ext) => ({
119476
+ ...ext,
119477
+ extensionName: this.mapExtensionType(ext.extensionName)
119478
+ }));
119479
+ resultObject.additionalExtensions = result.object.additionalExtensions.map((ext) => ({
119480
+ ...ext,
119481
+ extensionName: this.mapExtensionType(ext.extensionName)
119482
+ }));
119483
+ console.log("IterationAgent result:", JSON.stringify(resultObject, null, 2));
119484
+ return resultObject;
119485
+ }
119486
+ };
119487
+ exports2.IterationAgent = IterationAgent;
119488
+ exports2.default = IterationAgent;
119489
+ }
119490
+ });
119491
+
119168
119492
  // dist/agents/AgentsFactory.js
119169
119493
  var require_AgentsFactory = __commonJS({
119170
119494
  "dist/agents/AgentsFactory.js"(exports2) {
@@ -119181,6 +119505,7 @@ var require_AgentsFactory = __commonJS({
119181
119505
  var CMSAgent_1 = require_CMSAgent();
119182
119506
  var CMSDataAgent_1 = require_CMSDataAgent();
119183
119507
  var SiteComponentAgent_1 = __importDefault2(require_SiteComponentAgent());
119508
+ var IterationAgent_1 = __importDefault2(require_IterationAgent());
119184
119509
  var AgentsFactory = class {
119185
119510
  constructor(apiKey) {
119186
119511
  this.apiKey = apiKey;
@@ -119197,6 +119522,8 @@ var require_AgentsFactory = __commonJS({
119197
119522
  return new CMSDataAgent_1.CMSDataAgent(this.apiKey);
119198
119523
  case "PLANNER":
119199
119524
  return new PlannerAgent_1.default(this.apiKey);
119525
+ case "ITERATION_AGENT":
119526
+ return new IterationAgent_1.default(this.apiKey);
119200
119527
  case types_1.ExtensionType.SITE_COMPONENT:
119201
119528
  return new SiteComponentAgent_1.default(this.apiKey);
119202
119529
  default:
@@ -119225,6 +119552,9 @@ var require_cli_listeners = __commonJS({
119225
119552
  console.log(`\u{1F527} Extensions to generate: ${info.extensionsCount}
119226
119553
  `);
119227
119554
  });
119555
+ orchestrator.onEvent("start:iteration", () => {
119556
+ console.log("\n\u{1F680} Starting code iteration for app");
119557
+ });
119228
119558
  orchestrator.onEvent("scaffold:start", ({ extension }) => {
119229
119559
  console.log(`\u{1F4E6} Scaffolding ${extId(extension)}...`);
119230
119560
  });
@@ -119268,8 +119598,22 @@ var require_cli_listeners = __commonJS({
119268
119598
  timer.delete("PlannerAgent");
119269
119599
  console.log(`\u{1F916}\u2714\uFE0F Generated plan in ${duration / 1e3}s`);
119270
119600
  });
119601
+ orchestrator.onEvent("iterationAgent:start", () => {
119602
+ timer.set("IterationAgent", Date.now());
119603
+ console.log("\u{1F916} Generating iteration plan...");
119604
+ });
119605
+ orchestrator.onEvent("iterationAgent:done", ({ newExtensions, currentExtensions }) => {
119606
+ const duration = Date.now() - timer.get("IterationAgent");
119607
+ timer.delete("IterationAgent");
119608
+ console.log(`\u{1F916}\u2714\uFE0F Generated ${newExtensions} new extensions and modified ${currentExtensions} extensions in ${duration / 1e3}s`);
119609
+ });
119271
119610
  orchestrator.onEvent("finish", ({ outputPath, durationMs }) => {
119272
119611
  console.log(`
119612
+ \u2705 Done in ${durationMs}ms`);
119613
+ console.log(`\u{1F4C1} Files generated in: ${outputPath}`);
119614
+ });
119615
+ orchestrator.onEvent("finish:iteration", ({ outputPath, durationMs }) => {
119616
+ console.log(`
119273
119617
  \u2705 Done in ${durationMs}ms`);
119274
119618
  console.log(`\u{1F4C1} Files generated in: ${outputPath}`);
119275
119619
  });
@@ -119575,6 +119919,10 @@ ${b}
119575
119919
  )`).join("\n")};
119576
119920
  `;
119577
119921
  const filePath = path_1.default.join(outputPath, "src", "extensions.ts");
119922
+ const dir = path_1.default.dirname(filePath);
119923
+ if (!fs_1.default.existsSync(dir)) {
119924
+ fs_1.default.mkdirSync(dir, { recursive: true });
119925
+ }
119578
119926
  fs_1.default.writeFileSync(filePath, content);
119579
119927
  console.log(`\u{1F4DD} Generated: ${path_1.default.relative(outputPath, filePath)}`);
119580
119928
  }
@@ -119868,24 +120216,15 @@ var require_orchestrator = __commonJS({
119868
120216
  return mod2 && mod2.__esModule ? mod2 : { "default": mod2 };
119869
120217
  };
119870
120218
  Object.defineProperty(exports2, "__esModule", { value: true });
119871
- exports2.DittoOrchestrator = exports2.FilesSchema = exports2.FileSchema = void 0;
120219
+ exports2.DittoOrchestrator = void 0;
119872
120220
  var path_1 = __importDefault2(require("path"));
119873
120221
  var events_1 = require("events");
119874
120222
  var ditto_scaffolding_1 = require_dist11();
119875
120223
  var fs_1 = __importDefault2(require("fs"));
119876
120224
  var extensions_file_1 = require_extensions_file();
119877
- var zod_1 = require_zod();
119878
120225
  var ValidatorFactory_1 = __importDefault2(require_ValidatorFactory());
119879
120226
  var FixerFactory_1 = __importDefault2(require_FixerFactory());
119880
120227
  var MAX_FIX_ATTEMPTS = 3;
119881
- exports2.FileSchema = zod_1.z.object({
119882
- path: zod_1.z.string().describe("Relative file path from project root"),
119883
- content: zod_1.z.string().describe("Complete file content as a string (for JSON files, stringify the object)"),
119884
- type: zod_1.z.enum(["typescript", "json"]).describe("File type for syntax highlighting")
119885
- });
119886
- exports2.FilesSchema = zod_1.z.object({
119887
- files: zod_1.z.array(exports2.FileSchema).describe("Array of files to generate")
119888
- });
119889
120228
  var DittoOrchestrator = class extends events_1.EventEmitter {
119890
120229
  constructor(agentsFactory, apiKey) {
119891
120230
  super();
@@ -119900,21 +120239,54 @@ var require_orchestrator = __commonJS({
119900
120239
  emitEvent(event, payload) {
119901
120240
  return super.emit(event, payload);
119902
120241
  }
119903
- /**
119904
- * Generic method to generate code using Claude with tool execution
119905
- * @param systemPrompt - The system prompt to use
119906
- * @param userMessage - The initial user message
119907
- * @param outputPath - Where to output files
119908
- */
119909
- // Generation fully delegated to agents
119910
- writeFile(file, outputPath) {
119911
- const fullPath = path_1.default.join(outputPath, file.path);
119912
- const dir = path_1.default.dirname(fullPath);
119913
- if (!fs_1.default.existsSync(dir)) {
119914
- fs_1.default.mkdirSync(dir, { recursive: true });
120242
+ writeFile(files, outputPath) {
120243
+ if (!files) {
120244
+ console.warn("\u26A0\uFE0F Skipping file operation: no files provided");
120245
+ return;
120246
+ }
120247
+ for (const file of files) {
120248
+ if (!file.path) {
120249
+ console.warn("\u26A0\uFE0F Skipping file operation: no path specified");
120250
+ continue;
120251
+ }
120252
+ const fullPath = path_1.default.join(outputPath, file.path);
120253
+ switch (file.operation) {
120254
+ case "insert":
120255
+ if (!file.content) {
120256
+ console.warn(`\u26A0\uFE0F Skipping insert operation for ${file.path}: no content provided`);
120257
+ continue;
120258
+ }
120259
+ const dir = path_1.default.dirname(fullPath);
120260
+ if (!fs_1.default.existsSync(dir)) {
120261
+ fs_1.default.mkdirSync(dir, { recursive: true });
120262
+ }
120263
+ fs_1.default.writeFileSync(fullPath, file.content.trim());
120264
+ console.log(`\u{1F4DD} Inserted: ${file.path}`);
120265
+ break;
120266
+ case "update":
120267
+ if (!file.content) {
120268
+ console.warn(`\u26A0\uFE0F Skipping update operation for ${file.path}: no content provided`);
120269
+ continue;
120270
+ }
120271
+ if (!fs_1.default.existsSync(fullPath)) {
120272
+ console.warn(`\u26A0\uFE0F Skipping update operation for ${file.path}: file does not exist`);
120273
+ continue;
120274
+ }
120275
+ fs_1.default.writeFileSync(fullPath, file.content.trim());
120276
+ console.log(`\u{1F4DD} Updated: ${file.path}`);
120277
+ break;
120278
+ case "delete":
120279
+ if (fs_1.default.existsSync(fullPath)) {
120280
+ fs_1.default.unlinkSync(fullPath);
120281
+ console.log(`\u{1F5D1}\uFE0F Deleted: ${file.path}`);
120282
+ } else {
120283
+ console.warn(`\u26A0\uFE0F Skipping delete operation for ${file.path}: file does not exist`);
120284
+ }
120285
+ break;
120286
+ default:
120287
+ throw new Error(`Unknown operation "${file.operation}" for file ${file.path}`);
120288
+ }
119915
120289
  }
119916
- fs_1.default.writeFileSync(fullPath, file.content.trim());
119917
- console.log(`\u{1F4DD} Generated: ${file.path}`);
119918
120290
  }
119919
120291
  async generatePlanAndResources(request) {
119920
120292
  const { siteId, accessToken, blueprint } = request;
@@ -119941,6 +120313,65 @@ var require_orchestrator = __commonJS({
119941
120313
  }
119942
120314
  return { createdCollections };
119943
120315
  }
120316
+ async runIterationPlanningAndAugmentExtensions(outputPath, chatHistory) {
120317
+ const iterationAgent = this.agentsFactory.getAgent({
120318
+ type: "ITERATION_AGENT"
120319
+ });
120320
+ const candidateFiles = this.listGeneratedAppFiles(outputPath);
120321
+ const currentUserRequest = chatHistory[chatHistory.length - 1]?.text || "";
120322
+ const iterationPlan = await iterationAgent.generate(outputPath, candidateFiles, currentUserRequest, chatHistory);
120323
+ return iterationPlan;
120324
+ }
120325
+ async processExtension({ extension, blueprint, outputPath, createdCollections }) {
120326
+ this.emitEvent("scaffold:start", { extension });
120327
+ const [scaffold] = await (0, ditto_scaffolding_1.copyScaffoldingTemplate)(extension, outputPath);
120328
+ this.emitEvent("scaffold:done", {
120329
+ extension,
120330
+ scaffoldPath: scaffold.path
120331
+ });
120332
+ const agent = this.agentsFactory.getAgent(extension);
120333
+ this.emitEvent("agent:start", { extension, name: agent.name });
120334
+ const files = await agent.generate({
120335
+ extension,
120336
+ blueprint,
120337
+ scaffold,
120338
+ createdCollections,
120339
+ basePath: outputPath
120340
+ });
120341
+ this.writeFile(files, outputPath);
120342
+ this.emitEvent("agent:done", {
120343
+ extension,
120344
+ name: agent.name,
120345
+ files
120346
+ });
120347
+ }
120348
+ async processIterationExtension({ extension, paths, relevantUserRequest, outputPath, newExtension }) {
120349
+ let scaffold;
120350
+ if (newExtension) {
120351
+ this.emitEvent("scaffold:start", { extension });
120352
+ const [result] = await (0, ditto_scaffolding_1.copyScaffoldingTemplate)(extension, outputPath);
120353
+ scaffold = result;
120354
+ this.emitEvent("scaffold:done", {
120355
+ extension,
120356
+ scaffoldPath: scaffold.path
120357
+ });
120358
+ }
120359
+ const agent = this.agentsFactory.getAgent(extension);
120360
+ this.emitEvent("agent:start", { extension, name: agent.name });
120361
+ const files = await agent.generate({
120362
+ extension,
120363
+ scaffold,
120364
+ userRequestSummary: relevantUserRequest,
120365
+ relevantFilePaths: paths,
120366
+ basePath: outputPath
120367
+ });
120368
+ this.writeFile(files, outputPath);
120369
+ this.emitEvent("agent:done", {
120370
+ extension,
120371
+ name: agent.name,
120372
+ files
120373
+ });
120374
+ }
119944
120375
  async generateCMSData(request, createdCollections) {
119945
120376
  const { siteId, accessToken, blueprint } = request;
119946
120377
  this.emitEvent("cms-data:start", {
@@ -119959,10 +120390,6 @@ var require_orchestrator = __commonJS({
119959
120390
  totalItemsInserted
119960
120391
  });
119961
120392
  }
119962
- /**
119963
- * AI Generation Methods for customizing scaffolding
119964
- * Currently supports: SERVICE_PLUGIN, DASHBOARD_PAGE
119965
- */
119966
120393
  async generateCode(request) {
119967
120394
  const { blueprint, outputPath, siteId, accessToken } = request;
119968
120395
  this.emitEvent("start", {
@@ -119978,33 +120405,16 @@ var require_orchestrator = __commonJS({
119978
120405
  const planAndResourcesResult = await this.generatePlanAndResources(request);
119979
120406
  createdCollections.push(...planAndResourcesResult.createdCollections);
119980
120407
  }
119981
- const parallelTasks = extensions.map(async (extension) => {
119982
- this.emitEvent("scaffold:start", { extension });
119983
- const [scaffold] = await (0, ditto_scaffolding_1.copyScaffoldingTemplate)(extension, outputPath);
119984
- if (!scaffold) {
119985
- console.warn("Failed to scaffold for extension", extension);
119986
- }
119987
- this.emitEvent("scaffold:done", {
119988
- extension,
119989
- scaffoldPath: scaffold.path
119990
- });
119991
- const agent = this.agentsFactory.getAgent(extension);
119992
- this.emitEvent("agent:start", { extension, name: agent.name });
119993
- const file = await agent.generate(extension, blueprint, scaffold, createdCollections);
119994
- const files = [
119995
- { path: scaffold.path, content: file.content }
119996
- ];
119997
- this.writeFile(files[0], outputPath);
119998
- this.emitEvent("agent:done", {
119999
- extension,
120000
- name: agent.name,
120001
- files
120002
- });
120003
- });
120408
+ const parallelTasks = extensions.map((extension) => this.processExtension({
120409
+ extension,
120410
+ blueprint,
120411
+ outputPath,
120412
+ createdCollections
120413
+ }));
120004
120414
  if (createdCollections.length > 0 && siteId && accessToken) {
120005
120415
  parallelTasks.push(this.generateCMSData(request, createdCollections));
120006
120416
  }
120007
- await Promise.all(parallelTasks);
120417
+ await Promise.all(parallelTasks.filter(Boolean));
120008
120418
  (0, extensions_file_1.generateExtensionsFile)(outputPath, extensions);
120009
120419
  const durationMsCodeGeneration = Date.now() - start;
120010
120420
  this.emitEvent("finish:code-generation", {
@@ -120018,6 +120428,80 @@ var require_orchestrator = __commonJS({
120018
120428
  const durationMs = Date.now() - start;
120019
120429
  this.emitEvent("finish", { outputPath, durationMs });
120020
120430
  }
120431
+ async generateIterationCode(request) {
120432
+ this.emitEvent("start:iteration", {});
120433
+ const { outputPath, chatHistory } = request;
120434
+ const start = Date.now();
120435
+ this.emitEvent("iterationAgent:start", {});
120436
+ const iterationPlan = await this.runIterationPlanningAndAugmentExtensions(outputPath, chatHistory);
120437
+ this.emitEvent("iterationAgent:done", {
120438
+ newExtensions: iterationPlan?.additionalExtensions?.length || 0,
120439
+ currentExtensions: iterationPlan?.currentExtensions?.length || 0
120440
+ });
120441
+ const parallelTasks = iterationPlan?.additionalExtensions?.map((extension) => {
120442
+ const extensionObj = {
120443
+ type: extension.extensionName,
120444
+ name: "",
120445
+ description: `Generated from iteration: ${extension.relevantUserRequest}`,
120446
+ relatedSpis: extension.relatedSpis?.map((spi) => ({
120447
+ name: spi,
120448
+ purpose: ""
120449
+ })) || []
120450
+ };
120451
+ return this.processIterationExtension({
120452
+ extension: extensionObj,
120453
+ paths: [],
120454
+ relevantUserRequest: iterationPlan.summary,
120455
+ outputPath,
120456
+ newExtension: true
120457
+ });
120458
+ }) || [];
120459
+ if (iterationPlan?.currentExtensions && iterationPlan.currentExtensions.length > 0) {
120460
+ parallelTasks.push(...iterationPlan.currentExtensions.map((extension) => {
120461
+ const extensionObj = {
120462
+ type: extension.extensionName,
120463
+ name: "",
120464
+ description: `Generated from iteration: ${extension.relevantUserRequest}`,
120465
+ relatedSpis: extension.relatedSpis?.map((spi) => ({
120466
+ name: spi,
120467
+ purpose: ""
120468
+ })) || []
120469
+ };
120470
+ return this.processIterationExtension({
120471
+ extension: extensionObj,
120472
+ paths: extension.paths,
120473
+ relevantUserRequest: extension.relevantUserRequest,
120474
+ outputPath,
120475
+ newExtension: false
120476
+ });
120477
+ }));
120478
+ }
120479
+ await Promise.all(parallelTasks.filter(Boolean));
120480
+ const finalExtensionsToWrite = iterationPlan?.additionalExtensions?.map((extension) => {
120481
+ const extensionObj = {
120482
+ type: extension.extensionName,
120483
+ name: "",
120484
+ description: `Generated from iteration: ${extension.relevantUserRequest}`,
120485
+ relatedSpis: extension.relatedSpis?.map((spi) => ({
120486
+ name: spi,
120487
+ purpose: ""
120488
+ })) || []
120489
+ };
120490
+ return extensionObj;
120491
+ });
120492
+ (0, extensions_file_1.generateExtensionsFile)(outputPath, finalExtensionsToWrite);
120493
+ const durationMsCodeGeneration = Date.now() - start;
120494
+ this.emitEvent("finish:code-generation", {
120495
+ outputPath,
120496
+ durationMs: durationMsCodeGeneration
120497
+ });
120498
+ await this.startFixFlow({
120499
+ projectDir: outputPath,
120500
+ apiKey: this.apiKey
120501
+ });
120502
+ const durationMs = Date.now() - start;
120503
+ this.emitEvent("finish:iteration", { outputPath, durationMs });
120504
+ }
120021
120505
  async startFixFlow(request) {
120022
120506
  const { projectDir, apiKey } = request;
120023
120507
  this.emitEvent("validation:start", { outputPath: projectDir });
@@ -120053,6 +120537,26 @@ ${unfixedValidationErrors}`)
120053
120537
  throw new Error(`Validation failed after ${MAX_FIX_ATTEMPTS} attempts. Errors:
120054
120538
  ${unfixedValidationErrors}`);
120055
120539
  }
120540
+ listGeneratedAppFiles(outputPath) {
120541
+ const root = outputPath;
120542
+ const srcDir = path_1.default.join(root, "src");
120543
+ const results = [];
120544
+ if (!fs_1.default.existsSync(srcDir)) {
120545
+ return results;
120546
+ }
120547
+ const walk = (dir) => {
120548
+ const entries = fs_1.default.existsSync(dir) ? fs_1.default.readdirSync(dir, { withFileTypes: true }) : [];
120549
+ for (const entry of entries) {
120550
+ const full = path_1.default.join(dir, entry.name);
120551
+ if (entry.isDirectory())
120552
+ walk(full);
120553
+ else
120554
+ results.push(path_1.default.relative(root, full));
120555
+ }
120556
+ };
120557
+ walk(srcDir);
120558
+ return results;
120559
+ }
120056
120560
  };
120057
120561
  exports2.DittoOrchestrator = DittoOrchestrator;
120058
120562
  DittoOrchestrator.DEFAULT_OUTPUT_PATH = "generated-app";
@@ -120172,6 +120676,72 @@ var require_init_codegen = __commonJS({
120172
120676
  }
120173
120677
  });
120174
120678
 
120679
+ // dist/flows/iterate-codegen.js
120680
+ var require_iterate_codegen = __commonJS({
120681
+ "dist/flows/iterate-codegen.js"(exports2) {
120682
+ "use strict";
120683
+ var __importDefault2 = exports2 && exports2.__importDefault || function(mod2) {
120684
+ return mod2 && mod2.__esModule ? mod2 : { "default": mod2 };
120685
+ };
120686
+ Object.defineProperty(exports2, "__esModule", { value: true });
120687
+ exports2.runIterateCodegenFlow = void 0;
120688
+ var path_1 = __importDefault2(require("path"));
120689
+ var __1 = require_index();
120690
+ var AgentsFactory_1 = require_AgentsFactory();
120691
+ var cli_listeners_1 = require_cli_listeners();
120692
+ var context_1 = require_context();
120693
+ var job_context_storage_1 = require_job_context_storage();
120694
+ var orchestrator_1 = require_orchestrator();
120695
+ var CodeGenService_1 = require_CodeGenService();
120696
+ var utils_1 = require_utils18();
120697
+ var slugify = (str = "") => {
120698
+ return str.toLowerCase().replace(/ /g, "-");
120699
+ };
120700
+ var runIterateCodegenFlow = async (chatHistory) => {
120701
+ const localJobContext = job_context_storage_1.jobContextStorage.getStore();
120702
+ console.log(`[Iterate] Starting iterate codegen task: jobId=${localJobContext?.jobId}, taskId=${localJobContext?.taskId}`);
120703
+ await __1.codeGenerationService.updateTask(localJobContext.jobId, localJobContext.taskId, CodeGenService_1.TaskStatus.RUNNING, {});
120704
+ console.log(`[Init] Marked task RUNNING: jobId=${localJobContext.jobId}, taskId=${localJobContext.taskId}`);
120705
+ try {
120706
+ const outputDir = process.env.OUTPUT_PATH || orchestrator_1.DittoOrchestrator.DEFAULT_OUTPUT_PATH;
120707
+ const outputPath = outputDir.startsWith("/") ? outputDir : path_1.default.join(process.cwd(), outputDir);
120708
+ const agentsFactory = new AgentsFactory_1.AgentsFactory(context_1.ctx?.apiKey);
120709
+ const orchestrator = new orchestrator_1.DittoOrchestrator(agentsFactory);
120710
+ orchestrator.onEvent("agent:start", ({ extension }) => {
120711
+ console.log(`[Agent] start: ${extension.name}`);
120712
+ __1.codeGenerationService.addTask(localJobContext.jobId, {
120713
+ id: `${localJobContext.taskId}-${slugify(extension.name)}`,
120714
+ kind: "run_agent",
120715
+ status: CodeGenService_1.TaskStatus.RUNNING,
120716
+ name: "run_agent",
120717
+ description: `Run agent for ${extension.name}`,
120718
+ payload: { extension }
120719
+ });
120720
+ });
120721
+ orchestrator.onEvent("agent:done", ({ extension, files }) => {
120722
+ console.log(`[Agent] done: ${extension.name}`);
120723
+ __1.codeGenerationService.updateTask(localJobContext.jobId, `${localJobContext.taskId}-${slugify(extension.name)}`, CodeGenService_1.TaskStatus.COMPLETED, { taskOutput: { files } });
120724
+ });
120725
+ (0, cli_listeners_1.attachOrchestratorListeners)(orchestrator);
120726
+ await orchestrator.generateIterationCode({
120727
+ chatHistory,
120728
+ outputPath,
120729
+ siteId: context_1.ctx.siteId,
120730
+ accessToken: context_1.ctx.accessToken
120731
+ });
120732
+ await __1.codeGenerationService.updateTask(localJobContext.jobId, localJobContext.taskId, CodeGenService_1.TaskStatus.COMPLETED, {});
120733
+ console.log(`[Init] Completed iterate codegen task: jobId=${localJobContext.jobId}, taskId=${localJobContext.taskId}`);
120734
+ } catch (error) {
120735
+ await __1.codeGenerationService.updateTask(localJobContext.jobId, localJobContext.taskId, CodeGenService_1.TaskStatus.FAILED, {
120736
+ error: (0, utils_1.serializeError)(error)
120737
+ });
120738
+ console.error(`\u274C [Init] Failed iterate codegen task: jobId=${localJobContext.jobId}, taskId=${localJobContext.taskId}`, error);
120739
+ }
120740
+ };
120741
+ exports2.runIterateCodegenFlow = runIterateCodegenFlow;
120742
+ }
120743
+ });
120744
+
120175
120745
  // dist/index.js
120176
120746
  var require_index = __commonJS({
120177
120747
  "dist/index.js"(exports2) {
@@ -120219,6 +120789,7 @@ var require_index = __commonJS({
120219
120789
  var CodeGenService_1 = __importStar2(require_CodeGenService());
120220
120790
  var job_context_storage_1 = require_job_context_storage();
120221
120791
  var init_codegen_1 = require_init_codegen();
120792
+ var iterate_codegen_1 = require_iterate_codegen();
120222
120793
  var initializeTracing = async () => {
120223
120794
  try {
120224
120795
  await instrumentation_1.tracingReady;
@@ -120279,8 +120850,14 @@ var require_index = __commonJS({
120279
120850
  context_1.ctx.setJobStatus(job.jobId, CodeGenService_1.TaskStatus.RUNNING);
120280
120851
  console.log(`[Job] Marked job RUNNING: jobId=${job.jobId}, initTaskId=${task.id}`);
120281
120852
  console.log("Task Payload", JSON.stringify(task.payload, null, 2));
120282
- await job_context_storage_1.jobContextStorage.run({ jobId: job.jobId, taskId: task.id }, async () => {
120283
- await (0, init_codegen_1.runInitCodegenFlow)(task.payload.blueprint);
120853
+ await job_context_storage_1.jobContextStorage.run({ jobId: job.jobId, taskId: task.id, kind: task.kind }, async () => {
120854
+ const payload = task?.payload || {};
120855
+ if (task.kind === "ITERATE_CODEGEN") {
120856
+ const chatHistory = payload.history ?? [];
120857
+ await (0, iterate_codegen_1.runIterateCodegenFlow)(chatHistory);
120858
+ } else if (task.kind === "INIT_CODEGEN") {
120859
+ await (0, init_codegen_1.runInitCodegenFlow)(payload.blueprint);
120860
+ }
120284
120861
  });
120285
120862
  }
120286
120863
  (0, context_1.initCtx)("dafdsf").then((ctx) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/ditto-codegen-public",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "AI-powered Wix CLI app generator - standalone executable",
5
5
  "scripts": {
6
6
  "build": "node build.mjs",
@@ -24,5 +24,5 @@
24
24
  "@wix/ditto-codegen": "1.0.0",
25
25
  "esbuild": "^0.25.9"
26
26
  },
27
- "falconPackageHash": "8ddfeb0447ecad792ac842099f8b1b9f7ff9a88a00c7dffe496475c3"
27
+ "falconPackageHash": "70fbc8a04729200a2076d5870d3ced40e10ef55b8ce324003c82c4bf"
28
28
  }