@wix/ditto-codegen-public 1.0.473 → 1.0.474

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.
@@ -1,8 +1,30 @@
1
1
  import { tool } from "@opencode-ai/plugin";
2
+ import { readdir } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+
5
+ const EDITOR_COMPONENTS_DIR = "src/extensions/site/components";
6
+
7
+ async function containsTypeScriptFile(directory: string): Promise<boolean> {
8
+ let entries;
9
+ try {
10
+ entries = await readdir(directory, { withFileTypes: true });
11
+ } catch (error) {
12
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return false;
13
+ throw error;
14
+ }
15
+
16
+ for (const entry of entries) {
17
+ const path = join(directory, entry.name);
18
+ if (entry.isDirectory() && (await containsTypeScriptFile(path))) return true;
19
+ if (entry.isFile() && /\.tsx?$/.test(entry.name)) return true;
20
+ }
21
+ return false;
22
+ }
2
23
 
3
24
  export default tool({
4
25
  description:
5
- "Run project validation: TypeScript check by default, optionally a full build. " +
26
+ "Run project validation: TypeScript check by default, optionally a full build " +
27
+ "and editor-component manifest generation. " +
6
28
  "Use this instead of running npm install, tsc, and wix build separately.",
7
29
  args: {
8
30
  installDeps: tool.schema
@@ -18,7 +40,8 @@ export default tool({
18
40
  .boolean()
19
41
  .optional()
20
42
  .describe(
21
- "Default false (tsc only). Pass true to also run `wix build`. validate " +
43
+ "Default false (tsc only). Pass true to also run `wix build` and generate " +
44
+ "manifests when editor components exist. validate " +
22
45
  "runs tsc FIRST and builds only if tsc passes, so pass runBuild: true on " +
23
46
  "the FIRST call to typecheck+build in one pass — it fails fast on type " +
24
47
  "errors before the ~20s build, so a separate tsc-only call is redundant. " +
@@ -67,6 +90,30 @@ export default tool({
67
90
  }
68
91
  steps.push("wix build: OK");
69
92
 
93
+ const hasEditorComponents = await containsTypeScriptFile(
94
+ join(cwd, EDITOR_COMPONENTS_DIR),
95
+ );
96
+ if (!hasEditorComponents) {
97
+ steps.push(
98
+ "wix generate manifest: skipped (no editor components)",
99
+ );
100
+ return steps.join("\n");
101
+ }
102
+
103
+ const manifest = await Bun.$`npx wix generate manifest`
104
+ .cwd(cwd)
105
+ .nothrow()
106
+ .quiet();
107
+ if (manifest.exitCode !== 0) {
108
+ return [
109
+ ...steps,
110
+ `FAILED at wix generate manifest (exit ${manifest.exitCode}):`,
111
+ manifest.stdout.toString(),
112
+ manifest.stderr.toString(),
113
+ ].join("\n");
114
+ }
115
+ steps.push("wix generate manifest: OK");
116
+
70
117
  return steps.join("\n");
71
118
  },
72
119
  });
package/dist/out.js CHANGED
@@ -10700,6 +10700,41 @@ var require_ProcessExecutionError = __commonJS({
10700
10700
  }
10701
10701
  });
10702
10702
 
10703
+ // ../codegen-types/dist/errors/HostValidationError.js
10704
+ var require_HostValidationError = __commonJS({
10705
+ "../codegen-types/dist/errors/HostValidationError.js"(exports2) {
10706
+ "use strict";
10707
+ Object.defineProperty(exports2, "__esModule", { value: true });
10708
+ exports2.HostValidationError = void 0;
10709
+ var BaseCodegenError_1 = require_BaseCodegenError();
10710
+ var ErrorTypes_1 = require_ErrorTypes();
10711
+ var HostValidationError = class extends BaseCodegenError_1.BaseCodegenError {
10712
+ constructor(message, options) {
10713
+ super(message);
10714
+ this.name = "HostValidationError";
10715
+ this.errorType = ErrorTypes_1.ErrorType.PROCESS_EXECUTION_ERROR;
10716
+ this.expected = true;
10717
+ this.retryable = false;
10718
+ this.stage = options.stage;
10719
+ this.command = options.command;
10720
+ this.exitCode = options.exitCode;
10721
+ this.timedOut = options.timedOut;
10722
+ this.diagnosticSummary = options.diagnosticSummary;
10723
+ }
10724
+ getAdditionalProperties() {
10725
+ return {
10726
+ stage: this.stage,
10727
+ command: this.command,
10728
+ timedOut: this.timedOut,
10729
+ ...this.exitCode === void 0 ? {} : { exitCode: this.exitCode },
10730
+ ...this.diagnosticSummary ? { diagnosticSummary: this.diagnosticSummary } : {}
10731
+ };
10732
+ }
10733
+ };
10734
+ exports2.HostValidationError = HostValidationError;
10735
+ }
10736
+ });
10737
+
10703
10738
  // ../codegen-types/dist/errors/UnexpectedError.js
10704
10739
  var require_UnexpectedError = __commonJS({
10705
10740
  "../codegen-types/dist/errors/UnexpectedError.js"(exports2) {
@@ -10858,6 +10893,7 @@ var require_errors2 = __commonJS({
10858
10893
  __exportStar2(require_enums(), exports2);
10859
10894
  __exportStar2(require_BaseCodegenError(), exports2);
10860
10895
  __exportStar2(require_ProcessExecutionError(), exports2);
10896
+ __exportStar2(require_HostValidationError(), exports2);
10861
10897
  __exportStar2(require_UnexpectedError(), exports2);
10862
10898
  __exportStar2(require_TimeoutError(), exports2);
10863
10899
  __exportStar2(require_MissingJobIdError(), exports2);
@@ -11055,8 +11091,8 @@ var require_CodeGenService = __commonJS({
11055
11091
  retryable: error.retryable,
11056
11092
  expected: error.expected,
11057
11093
  ..."processType" in error && error.processType && { processType: PROCESS_TYPE[error.processType] },
11058
- ..."exitCode" in error && { exitCode: error.exitCode },
11059
- ..."stderr" in error && { stderr: error.stderr }
11094
+ ..."exitCode" in error ? { exitCode: error.exitCode } : {},
11095
+ ..."diagnosticSummary" in error ? { stderr: error.diagnosticSummary } : "stderr" in error ? { stderr: error.stderr } : {}
11060
11096
  };
11061
11097
  }
11062
11098
  function toApiExtension(ext) {
@@ -11611,10 +11647,19 @@ RECOVERY STRATEGY:
11611
11647
  or split it across several files and import them.
11612
11648
  3. Prefer many small steps over one big step.`;
11613
11649
  function buildRecoveryPrompt(originalPrompt, filesChanged, error, failureReason) {
11650
+ const isHostValidationFailure = failureReason === "host validation failure";
11614
11651
  const strategy = failureReason === "stall" ? `
11615
11652
  ${INCREMENTAL_WRITE_STRATEGY}
11616
11653
  ` : "";
11617
- return buildPrompt(`You are continuing a code generation task that was interrupted due to a session error.
11654
+ const introduction = isHostValidationFailure ? "You are continuing a code generation task because the agent finished, but the required project validation failed." : "You are continuing a code generation task that was interrupted due to a session error.";
11655
+ const recoveryInstructions = isHostValidationFailure ? `1. Review the failed validation stage and diagnostics above
11656
+ 2. Inspect the files already changed and fix only the cause of the validation failure
11657
+ 3. Run full validation after fixing the reported problem
11658
+ 4. Complete the original task without adding unrelated features` : `1. Review the files listed above that were already created/modified in the previous session
11659
+ 2. Continue with any remaining work needed to fulfill the original task
11660
+ 3. Do NOT recreate files that already exist and are correct - only modify them if needed
11661
+ 4. Complete any remaining extensions or files that haven't been created yet`;
11662
+ return buildPrompt(`${introduction}
11618
11663
 
11619
11664
  ORIGINAL TASK:
11620
11665
  ${originalPrompt}
@@ -11626,10 +11671,7 @@ PREVIOUS SESSION ERROR:
11626
11671
  ${error}
11627
11672
  ${strategy}
11628
11673
  INSTRUCTIONS:
11629
- 1. Review the files listed above that were already created/modified in the previous session
11630
- 2. Continue with any remaining work needed to fulfill the original task
11631
- 3. Do NOT recreate files that already exist and are correct - only modify them if needed
11632
- 4. Complete any remaining extensions or files that haven't been created yet`);
11674
+ ${recoveryInstructions}`);
11633
11675
  }
11634
11676
  }
11635
11677
  });
@@ -11838,12 +11880,13 @@ var require_subagents = __commonJS({
11838
11880
  exports2.PRIMARY_AGENT_NAME = "codegen";
11839
11881
  exports2.VALIDATOR_SUBAGENT_NAME = "codegen-validator";
11840
11882
  exports2.SUBAGENT_AGENT_NAMES = [exports2.VALIDATOR_SUBAGENT_NAME];
11841
- var VALIDATOR_DESCRIPTION = `Runs validate (tsc + wix build) and fixes the reported errors, consulting the
11842
- skills or wix-mcp for SDK-shape errors; returns when the build is clean
11883
+ var VALIDATOR_DESCRIPTION = `Runs validate (tsc + wix build + editor-component manifests) and fixes the reported errors, consulting the
11884
+ skills or wix-mcp for SDK-shape errors; returns when validation is clean
11843
11885
  or reports what it couldn't fix. Validation step only \u2014 never generates features.`;
11844
11886
  var VALIDATOR_PROMPT = `Run 'validate({ runBuild: true })', fix the errors it reports, and re-run until
11845
11887
  it passes. You are fixing EXISTING code \u2014 do NOT add features or rewrite whole
11846
- files, and do NOT run 'npx wix generate manifest' \u2014 that is the caller's step.
11888
+ files, and do NOT run 'npx wix generate manifest' directly \u2014 the validate tool
11889
+ does that automatically when editor components exist.
11847
11890
  NEVER force a green build by suppressing types: no 'as any', no
11848
11891
  '@ts-ignore', no NEW '@ts-expect-error', and do NOT switch a correct named import to
11849
11892
  'import * as' just to satisfy tsc \u2014 that ships code that compiles but breaks
@@ -14971,12 +15014,12 @@ var require_codegen_rules = __commonJS({
14971
15014
  var shared_rules_1 = require_shared_rules();
14972
15015
  var model_knobs_1 = require_model_knobs();
14973
15016
  var DELEGATED_VALIDATION = {
14974
- toolRule: "- `validate` (tsc + build) is run by the `codegen-validator` subagent \u2014 do NOT call it directly; delegate via `task` at step 5.",
14975
- step: `5. **Validate**: Dispatch ONE \`task({ subagent: "codegen-validator", prompt: "Run validate({ runBuild: true }) \u2014 it typechecks AND builds in a single pass (tsc runs first and fails fast before the build). Fix any errors and re-run until it passes. Pass installDeps: true only if package.json changed and npm install was not already run in this session." })\`. Wait for the subagent to return. Do NOT call \`validate\` directly from the primary agent, and do NOT make a separate tsc-only call first \u2014 the single runBuild pass already fails fast on type errors. VERIFY the subagent actually FINISHED with a clean build: read its returned summary and confirm it converged. If it reports remaining/unresolved errors or was cut off before finishing (e.g. "Maximum steps reached"), do NOT treat it as success \u2014 re-dispatch \`codegen-validator\` to finish the remaining errors before moving on. After the validator confirms a clean build, if you created or modified an EDITOR_REACT_COMPONENT extension in this task, run \`npx wix generate manifest\` via bash (the validator is instructed not to run it, so this is the only run).`
15017
+ toolRule: "- `validate` (tsc + build + editor-component manifests) is run by the `codegen-validator` subagent \u2014 do NOT call it directly; delegate via `task` at step 5.",
15018
+ step: `5. **Validate**: Dispatch ONE \`task({ subagent: "codegen-validator", prompt: "Run validate({ runBuild: true }) \u2014 it typechecks, builds, and generates manifests when editor components exist. Fix any errors and re-run until it passes. Pass installDeps: true only if package.json changed and npm install was not already run in this session." })\`. Wait for the subagent to return. Do NOT call \`validate\` directly from the primary agent, and do NOT make a separate tsc-only call first \u2014 the single runBuild pass already fails fast on type errors. VERIFY the subagent actually FINISHED with clean validation: read its returned summary and confirm it converged. If it reports remaining/unresolved errors or was cut off before finishing (e.g. "Maximum steps reached"), do NOT treat it as success \u2014 re-dispatch \`codegen-validator\` to finish the remaining errors before moving on. Do NOT inspect extension types or run \`npx wix generate manifest\` directly; \`validate\` handles manifest generation when editor components exist.`
14976
15019
  };
14977
15020
  var DIRECT_VALIDATION = {
14978
- toolRule: "- `validate` (tsc + build) \u2014 you call it yourself at step 5. Do NOT delegate it.",
14979
- step: `5. **Validate**: Call \`validate({ runBuild: true })\` yourself \u2014 it typechecks AND builds in a single pass (tsc runs first and fails fast before the build). Fix any errors and re-run until it passes. Pass installDeps: true only if package.json changed and npm install was not already run in this session. Do NOT delegate this to a subagent, and do NOT make a separate tsc-only call first \u2014 the single runBuild pass already fails fast on type errors. NEVER force a green build: no \`as any\`, no \`@ts-ignore\`, no NEW \`@ts-expect-error\`, no switching a correct named import to \`import * as\`, and no changing runtime behaviour (e.g. unwanted \`defaultProps\` values) or deleting the failing code just to satisfy tsc. Do NOT move on until the build is clean. After the build is clean, if you created or modified an EDITOR_REACT_COMPONENT extension in this task, run \`npx wix generate manifest\` via bash (idempotent).`
15021
+ toolRule: "- `validate` (tsc + build + editor-component manifests) \u2014 you call it yourself at step 5. Do NOT delegate it.",
15022
+ step: `5. **Validate**: Call \`validate({ runBuild: true })\` yourself \u2014 it typechecks, builds, and generates manifests when editor components exist (tsc runs first and fails fast before the build). Fix any errors and re-run until it passes. Pass installDeps: true only if package.json changed and npm install was not already run in this session. Do NOT delegate this to a subagent, and do NOT make a separate tsc-only call first \u2014 the single runBuild pass already fails fast on type errors. NEVER force a green build: no \`as any\`, no \`@ts-ignore\`, no NEW \`@ts-expect-error\`, no switching a correct named import to \`import * as\`, and no changing runtime behaviour (e.g. unwanted \`defaultProps\` values) or deleting the failing code just to satisfy tsc. Do NOT move on until validation is clean. Do NOT inspect extension types or run \`npx wix generate manifest\` directly; \`validate\` handles manifest generation when editor components exist.`
14980
15023
  };
14981
15024
  var buildCoreRules = (validation) => `CORE PRINCIPLES:
14982
15025
  - Do NOT invent or assume new types, modules, functions, props, events, or imports.
@@ -15021,7 +15064,7 @@ FILE CREATION:
15021
15064
  - Do NOT output comments in code unless they explain non-obvious logic.
15022
15065
 
15023
15066
  GENERATED FILES:
15024
- - \`src/extensions/site/components/**/*.generated.ts\` is an auto-generated editor-react-component manifest \u2014 NEVER hand-edit. Change a manifest VALUE in the component's \`*.extension.ts\`; change anything else in the \`*.tsx\` / \`*.module.css\` / \`*.props.ts\` source, then regenerate (workflow step 5). No other \`.generated.ts\` path is affected.
15067
+ - \`src/extensions/site/components/**/*.generated.ts\` is an auto-generated editor-react-component manifest \u2014 NEVER hand-edit. Change a manifest VALUE in the component's \`*.extension.ts\`; change anything else in the \`*.tsx\` / \`*.module.css\` / \`*.props.ts\` source. \`validate({ runBuild: true })\` regenerates the manifest when editor components exist. No other \`.generated.ts\` path is affected.
15025
15068
  - A write guard rejects \`write\`/\`edit\`/\`batch-write\`/\`multi-edit\`/\`apply_patch\` there, dropping the ENTIRE call \u2014 never batch that path with real edits (or put it in a patch alongside other hunks), or those are lost too and must be resubmitted.
15026
15069
 
15027
15070
  TYPESCRIPT:
@@ -15125,7 +15168,7 @@ MINIMIZE TEXT OUTPUT \u2014 CRITICAL:
15125
15168
  - Every text token costs money. Use tools, not words.
15126
15169
 
15127
15170
  TOOL USAGE:
15128
- - \`validate\` for all validation (tsc + build). Run it after resolving the conflicts to make sure nothing breaks.
15171
+ - \`validate\` for TypeScript, build, and editor-component manifest validation. Run it after resolving the conflicts; it generates manifests when editor components exist.
15129
15172
  ${(0, shared_rules_1.buildFileOperationsRules)("resolving conflicts")}
15130
15173
  - NEVER run preview, dev, release, or promote commands.
15131
15174
 
@@ -15767,6 +15810,361 @@ export const SubagentToolLogger = async () => {
15767
15810
  }
15768
15811
  });
15769
15812
 
15813
+ // dist/extension-reporting/detect.js
15814
+ var require_detect = __commonJS({
15815
+ "dist/extension-reporting/detect.js"(exports2) {
15816
+ "use strict";
15817
+ Object.defineProperty(exports2, "__esModule", { value: true });
15818
+ exports2.BUILDER_EXTENSION_TYPES = void 0;
15819
+ exports2.isSpiExtension = isSpiExtension;
15820
+ exports2.isExtensionsFile = isExtensionsFile;
15821
+ exports2.detectExtension = detectExtension;
15822
+ exports2.matchQuotedExtensionConfigProperty = matchQuotedExtensionConfigProperty;
15823
+ exports2.extractExtensionDisplayTitle = extractExtensionDisplayTitle;
15824
+ exports2.injectCreatedBy = injectCreatedBy;
15825
+ var CONTAINER_ROOT_PREFIX = /^\/user-code\//;
15826
+ var EXTENSION_FILE_PATTERN = /\/extensions\.ts$|\.extension\.ts$/;
15827
+ var SPI_EXTENSION_TYPES = [
15828
+ "ecomShippingRates",
15829
+ "ecomAdditionalFees",
15830
+ "ecomValidations",
15831
+ "ecomDiscountTriggers",
15832
+ "ecomGiftCards",
15833
+ "ecomPaymentSettings",
15834
+ "bookingsStaffSortingProvider"
15835
+ ];
15836
+ exports2.BUILDER_EXTENSION_TYPES = [
15837
+ "dashboardPage",
15838
+ "dashboardModal",
15839
+ "dashboardPlugin",
15840
+ "dashboardMenuPlugin",
15841
+ "embeddedScript",
15842
+ "event",
15843
+ "customElement",
15844
+ "siteComponent",
15845
+ "editorReactComponent",
15846
+ "sitePlugin",
15847
+ ...SPI_EXTENSION_TYPES,
15848
+ "contextProvider",
15849
+ "functionLibrary",
15850
+ "dataCollections"
15851
+ ];
15852
+ var SPI_EXTENSION_TYPE_SET = new Set(SPI_EXTENSION_TYPES);
15853
+ function isSpiExtension(extensionType) {
15854
+ return SPI_EXTENSION_TYPE_SET.has(extensionType);
15855
+ }
15856
+ function normalizeFilePath(filePath) {
15857
+ return filePath.replace(CONTAINER_ROOT_PREFIX, "");
15858
+ }
15859
+ function isExtensionsFile(filePath) {
15860
+ return EXTENSION_FILE_PATTERN.test(filePath);
15861
+ }
15862
+ function detectExtension(content) {
15863
+ for (const extensionType of exports2.BUILDER_EXTENSION_TYPES) {
15864
+ if (content.includes(`extensions.${extensionType}(`) || content.includes(`experimentalExtensions.${extensionType}(`)) {
15865
+ return extensionType;
15866
+ }
15867
+ }
15868
+ return null;
15869
+ }
15870
+ function toTitleCase(str) {
15871
+ return str.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
15872
+ }
15873
+ function extractExtensionName(filePath) {
15874
+ const parts = normalizeFilePath(filePath).split("/");
15875
+ const folderName = parts[parts.length - 2] || "";
15876
+ return toTitleCase(folderName);
15877
+ }
15878
+ function matchQuotedExtensionConfigProperty(content, propName) {
15879
+ const objectPropertyQuotedStringValuePattern = `\\b${propName}\\s*:\\s*(?:"([^"\\\\]*)"|'([^'\\\\]*)')`;
15880
+ const objectPropertyQuotedStringValueRegex = new RegExp(
15881
+ objectPropertyQuotedStringValuePattern,
15882
+ // `m` = multiline: `^` / `$` match line starts/ends, not only the whole string.
15883
+ "m"
15884
+ );
15885
+ const quotedStringValueMatch = content.match(objectPropertyQuotedStringValueRegex);
15886
+ if (!quotedStringValueMatch)
15887
+ return null;
15888
+ return quotedStringValueMatch[1] ?? quotedStringValueMatch[2] ?? null;
15889
+ }
15890
+ function extractExtensionDisplayTitle(content, filePath) {
15891
+ const title = matchQuotedExtensionConfigProperty(content, "title");
15892
+ if (title)
15893
+ return title;
15894
+ const name = matchQuotedExtensionConfigProperty(content, "name");
15895
+ if (name)
15896
+ return name;
15897
+ const displayName = matchQuotedExtensionConfigProperty(content, "displayName");
15898
+ if (displayName)
15899
+ return displayName;
15900
+ const idSuffix = matchQuotedExtensionConfigProperty(content, "idSuffix");
15901
+ if (idSuffix)
15902
+ return idSuffix;
15903
+ return extractExtensionName(filePath);
15904
+ }
15905
+ function injectCreatedBy(content) {
15906
+ if (content.includes("createdBy"))
15907
+ return content;
15908
+ const isGeneric = content.includes("genericExtension(");
15909
+ const createdByValue = isGeneric ? ' createdBy: "CODE_GEN",' : ' createdBy: {\n author: "CODE_GEN",\n },';
15910
+ return content.replace(/(\S)(\n)(}\))(;?\s*)$/, (_match, preChar, newline, closeBrace, tail) => {
15911
+ const needsComma = preChar !== "," && preChar !== "{";
15912
+ const separator = needsComma ? `${preChar},` : preChar;
15913
+ return `${separator}${newline}${createdByValue}
15914
+ ${closeBrace}${tail}`;
15915
+ });
15916
+ }
15917
+ }
15918
+ });
15919
+
15920
+ // dist/git/repository-status.js
15921
+ var require_repository_status = __commonJS({
15922
+ "dist/git/repository-status.js"(exports2) {
15923
+ "use strict";
15924
+ Object.defineProperty(exports2, "__esModule", { value: true });
15925
+ exports2.isMissingGitRepository = isMissingGitRepository;
15926
+ exports2.hasGitRepository = hasGitRepository;
15927
+ var child_process_1 = require("child_process");
15928
+ var util_1 = require("util");
15929
+ var execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
15930
+ function isMissingGitRepository(exitCode, stderr) {
15931
+ return exitCode === 128 && /^fatal: not a git repository\b/m.test(stderr);
15932
+ }
15933
+ async function hasGitRepository(cwd) {
15934
+ try {
15935
+ await execFileAsync("git", ["rev-parse", "--is-inside-work-tree"], {
15936
+ cwd,
15937
+ env: { ...process.env, LC_ALL: "C" }
15938
+ });
15939
+ return true;
15940
+ } catch (error) {
15941
+ if (error instanceof Error && "code" in error && typeof error.code === "number" && "stderr" in error && typeof error.stderr === "string" && isMissingGitRepository(error.code, error.stderr))
15942
+ return false;
15943
+ throw error;
15944
+ }
15945
+ }
15946
+ }
15947
+ });
15948
+
15949
+ // dist/extension-reporting/prepare-created-by.js
15950
+ var require_prepare_created_by = __commonJS({
15951
+ "dist/extension-reporting/prepare-created-by.js"(exports2) {
15952
+ "use strict";
15953
+ Object.defineProperty(exports2, "__esModule", { value: true });
15954
+ exports2.prepareCreatedExtensionFiles = prepareCreatedExtensionFiles;
15955
+ exports2.prepareCreatedByForValidation = prepareCreatedByForValidation;
15956
+ var child_process_1 = require("child_process");
15957
+ var promises_1 = require("fs/promises");
15958
+ var path_12 = require("path");
15959
+ var util_1 = require("util");
15960
+ var detect_1 = require_detect();
15961
+ var repository_status_1 = require_repository_status();
15962
+ var execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
15963
+ async function prepareCreatedExtensionFiles(paths, read, write, inject, builders) {
15964
+ for (const path of new Set(paths)) {
15965
+ if (!/(^|\/)extensions\.ts$|\.extension\.ts$/.test(path))
15966
+ continue;
15967
+ const original = await read(path);
15968
+ if (!builders.some((builder) => original.includes(`extensions.${builder}(`) || original.includes(`experimentalExtensions.${builder}(`)))
15969
+ continue;
15970
+ const injected = inject(original);
15971
+ if (injected !== original)
15972
+ await write(path, injected);
15973
+ }
15974
+ }
15975
+ async function prepareCreatedByForValidation(cwd, baseline) {
15976
+ if (!await (0, repository_status_1.hasGitRepository)(cwd))
15977
+ return;
15978
+ const [added, untracked] = await Promise.all([
15979
+ execFileAsync("git", baseline ? [
15980
+ "diff",
15981
+ "--name-only",
15982
+ "--diff-filter=A",
15983
+ "--no-renames",
15984
+ "-z",
15985
+ baseline
15986
+ ] : ["ls-files", "--cached", "-z"], { cwd }),
15987
+ execFileAsync("git", ["ls-files", "--others", "--exclude-standard", "-z"], {
15988
+ cwd
15989
+ })
15990
+ ]);
15991
+ await prepareCreatedExtensionFiles((added.stdout + untracked.stdout).split("\0").filter(Boolean), (path) => (0, promises_1.readFile)((0, path_12.join)(cwd, path), "utf8"), (path, content) => (0, promises_1.writeFile)((0, path_12.join)(cwd, path), content, "utf8"), detect_1.injectCreatedBy, detect_1.BUILDER_EXTENSION_TYPES);
15992
+ }
15993
+ }
15994
+ });
15995
+
15996
+ // dist/opencode-integration/plugins/validation-state.js
15997
+ var require_validation_state = __commonJS({
15998
+ "dist/opencode-integration/plugins/validation-state.js"(exports2) {
15999
+ "use strict";
16000
+ Object.defineProperty(exports2, "__esModule", { value: true });
16001
+ exports2.VALIDATION_NUDGE = exports2.VALIDATION_STATE_PLUGIN_FILENAME = exports2.VALIDATION_LOADED_EVENT_TYPE = exports2.VALIDATION_STATE_EVENT_TYPE = void 0;
16002
+ exports2.isReadOnlyShellCommand = isReadOnlyShellCommand;
16003
+ exports2.buildValidationStateSource = buildValidationStateSource;
16004
+ exports2.writeValidationStatePlugin = writeValidationStatePlugin;
16005
+ var write_plugin_1 = require_write_plugin();
16006
+ var detect_1 = require_detect();
16007
+ var prepare_created_by_1 = require_prepare_created_by();
16008
+ var repository_status_1 = require_repository_status();
16009
+ function isReadOnlyShellCommand(command) {
16010
+ return /^(?:ls|pwd|cat|head|tail|wc|grep)(?:[ \t]+[A-Za-z0-9_./:@%+=,-]+)*[ \t]*$/.test(command);
16011
+ }
16012
+ exports2.VALIDATION_STATE_EVENT_TYPE = "validation_state";
16013
+ exports2.VALIDATION_LOADED_EVENT_TYPE = "validation_loaded";
16014
+ exports2.VALIDATION_STATE_PLUGIN_FILENAME = "validation-state.ts";
16015
+ exports2.VALIDATION_NUDGE = "Project files need validation. Follow your validation workflow (delegate to codegen-validator if your instructions require it), run validate({ runBuild: true }), and fix any errors before finishing.";
16016
+ function buildValidationStateSource() {
16017
+ return String.raw`// Generated by @wix/ditto-codegen (validation-state). Do not edit.
16018
+ const EVENT_TYPE = ${JSON.stringify(exports2.VALIDATION_STATE_EVENT_TYPE)};
16019
+ const LOADED_EVENT_TYPE = ${JSON.stringify(exports2.VALIDATION_LOADED_EVENT_TYPE)};
16020
+ const VALIDATION_NUDGE = ${JSON.stringify(exports2.VALIDATION_NUDGE)};
16021
+ const BUILDERS = ${JSON.stringify(detect_1.BUILDER_EXTENSION_TYPES)};
16022
+ const injectCreatedBy = ${detect_1.injectCreatedBy.toString()};
16023
+ const prepareCreatedExtensionFiles = ${prepare_created_by_1.prepareCreatedExtensionFiles.toString()};
16024
+ const isMissingGitRepository = ${repository_status_1.isMissingGitRepository.toString()};
16025
+ const isReadOnlyShellCommand = ${isReadOnlyShellCommand.toString()};
16026
+ const MUTATING_TOOLS = new Set(["write", "edit", "apply_patch", "batch-write", "multi-edit", "wix-generate", "bash"]);
16027
+
16028
+ export const ValidationState = async ({ client, directory, $ }) => {
16029
+ const runGit = async (args) => {
16030
+ const command = Object.assign(["LC_ALL=C git ", ""], { raw: ["LC_ALL=C git ", ""] });
16031
+ return await $(command, args).cwd(directory).nothrow().quiet();
16032
+ };
16033
+ const git = async (args) => {
16034
+ const result = await runGit(args);
16035
+ if (result.exitCode !== 0) throw new Error("Cannot inspect project validation state: " + result.stderr.toString());
16036
+ return result.stdout.toString().split("\0").filter(Boolean);
16037
+ };
16038
+
16039
+ const repository = await runGit(["rev-parse", "--is-inside-work-tree"]);
16040
+ // No loaded marker: the host must run the compatibility gate instead.
16041
+ if (isMissingGitRepository(repository.exitCode, repository.stderr.toString())) return {};
16042
+ if (repository.exitCode !== 0) throw new Error("Cannot inspect Git repository: " + repository.stderr.toString());
16043
+ const snapshot = async () => {
16044
+ const paths = [...new Set(await git(["ls-files", "--cached", "--others", "--exclude-standard", "-z"]))]
16045
+ .filter((path) => !path.startsWith(".agents/")).sort();
16046
+ const hash = new Bun.CryptoHasher("sha256");
16047
+ for (const path of paths) {
16048
+ hash.update(path + "\0");
16049
+ const file = Bun.file(directory + "/" + path);
16050
+ hash.update(await file.exists() ? await file.arrayBuffer() : "<deleted>");
16051
+ hash.update("\0");
16052
+ }
16053
+ return hash.digest("hex");
16054
+ };
16055
+ const prepareMetadata = async () => {
16056
+ if (process.env.CODEGEN_PREPARE_EXTENSION_METADATA !== "1") return;
16057
+ const baseline = process.env.CODEGEN_VALIDATION_BASELINE;
16058
+ const paths = [
16059
+ ...await git(baseline ? ["diff", "--name-only", "--diff-filter=A", "--no-renames", "-z", baseline] : ["ls-files", "--cached", "-z"]),
16060
+ ...await git(["ls-files", "--others", "--exclude-standard", "-z"]),
16061
+ ];
16062
+ await prepareCreatedExtensionFiles(paths,
16063
+ (path) => Bun.file(directory + "/" + path).text(),
16064
+ async (path, content) => { await Bun.write(directory + "/" + path, content); },
16065
+ injectCreatedBy, BUILDERS);
16066
+ };
16067
+
16068
+ let cleanFingerprint = await snapshot();
16069
+ let currentFingerprint = cleanFingerprint;
16070
+ let hasValidationFailure = process.env.CODEGEN_REQUIRE_VALIDATION === "1";
16071
+ let hasUnvalidatedMutation = false;
16072
+ let lastClean;
16073
+ let mutationEpoch = 0;
16074
+ let revisionNudges = 0;
16075
+ let totalNudges = 0;
16076
+ const remindedMessages = new Set();
16077
+ const validations = new Map();
16078
+ const activeMutations = new Set();
16079
+ const key = (input) => input.sessionID + ":" + input.callID;
16080
+ const emit = (sessionID, clean) => {
16081
+ if (lastClean === clean) return;
16082
+ lastClean = clean;
16083
+ process.stdout.write(JSON.stringify({ type: EVENT_TYPE, sessionID, clean }) + "\n");
16084
+ };
16085
+ const refresh = async (sessionID) => {
16086
+ const fingerprint = await snapshot();
16087
+ if (fingerprint !== currentFingerprint) revisionNudges = 0;
16088
+ currentFingerprint = fingerprint;
16089
+ const clean = !hasValidationFailure && !hasUnvalidatedMutation && activeMutations.size === 0 &&
16090
+ validations.size === 0 && fingerprint === cleanFingerprint;
16091
+ emit(sessionID, clean);
16092
+ return clean;
16093
+ };
16094
+ process.stdout.write(JSON.stringify({ type: LOADED_EVENT_TYPE }) + "\n");
16095
+ if (hasValidationFailure) emit("repair", false);
16096
+
16097
+ return {
16098
+ event: async ({ event }) => {
16099
+ const part = event.type === "message.part.updated" ? event.properties?.part : undefined;
16100
+ if (part?.type !== "tool" || part.state?.status !== "error") return;
16101
+ const callKey = part.sessionID + ":" + part.callID;
16102
+ activeMutations.delete(callKey);
16103
+ if (validations.delete(callKey)) hasValidationFailure = true;
16104
+ },
16105
+ "tool.execute.before": async (input, output) => {
16106
+ const args = output.args;
16107
+ if (input.tool === "validate") {
16108
+ if (args.runBuild === true || args.installDeps === true) {
16109
+ emit(input.sessionID, false);
16110
+ hasValidationFailure = true;
16111
+ await prepareMetadata();
16112
+ currentFingerprint = await snapshot();
16113
+ validations.set(key(input), mutationEpoch);
16114
+ }
16115
+ } else if (MUTATING_TOOLS.has(input.tool)) {
16116
+ if (input.tool !== "bash" || typeof args.command !== "string" || !isReadOnlyShellCommand(args.command)) {
16117
+ hasUnvalidatedMutation = true;
16118
+ revisionNudges = 0;
16119
+ }
16120
+ mutationEpoch += 1;
16121
+ activeMutations.add(key(input));
16122
+ emit(input.sessionID, false);
16123
+ }
16124
+ },
16125
+ "tool.execute.after": async (input, output) => {
16126
+ if (input.tool === "validate") {
16127
+ const epoch = validations.get(key(input));
16128
+ validations.delete(key(input));
16129
+ const passed = typeof output.output === "string" && !/^FAILED at/m.test(output.output);
16130
+ if (!passed) hasValidationFailure = true;
16131
+ if (passed && input.args?.runBuild === true) {
16132
+ const fingerprint = await snapshot();
16133
+ if (epoch === mutationEpoch && activeMutations.size === 0 && validations.size === 0) {
16134
+ cleanFingerprint = fingerprint;
16135
+ hasValidationFailure = false;
16136
+ hasUnvalidatedMutation = false;
16137
+ }
16138
+ }
16139
+ await refresh(input.sessionID);
16140
+ } else if (MUTATING_TOOLS.has(input.tool)) {
16141
+ activeMutations.delete(key(input));
16142
+ await refresh(input.sessionID);
16143
+ }
16144
+ },
16145
+ "experimental.text.complete": async (input) => {
16146
+ if (await refresh(input.sessionID)) return;
16147
+ const messageKey = input.sessionID + ":" + input.messageID;
16148
+ if (remindedMessages.has(messageKey) || revisionNudges >= 2 || totalNudges >= 8) return;
16149
+ remindedMessages.add(messageKey);
16150
+ revisionNudges += 1;
16151
+ totalNudges += 1;
16152
+ await client.session.prompt({
16153
+ path: { id: input.sessionID },
16154
+ body: { noReply: true, parts: [{ type: "text", text: VALIDATION_NUDGE }] },
16155
+ });
16156
+ },
16157
+ };
16158
+ };
16159
+
16160
+ `;
16161
+ }
16162
+ async function writeValidationStatePlugin() {
16163
+ await (0, write_plugin_1.writeGeneratedPlugin)(exports2.VALIDATION_STATE_PLUGIN_FILENAME, buildValidationStateSource());
16164
+ }
16165
+ }
16166
+ });
16167
+
15770
16168
  // dist/opencode-integration/apply-patch.js
15771
16169
  var require_apply_patch = __commonJS({
15772
16170
  "dist/opencode-integration/apply-patch.js"(exports2) {
@@ -15786,6 +16184,9 @@ var require_parser = __commonJS({
15786
16184
  "dist/opencode-integration/execution/parser.js"(exports2) {
15787
16185
  "use strict";
15788
16186
  Object.defineProperty(exports2, "__esModule", { value: true });
16187
+ exports2.hasValidationPluginLoaded = hasValidationPluginLoaded;
16188
+ exports2.parseLastValidationState = parseLastValidationState;
16189
+ exports2.parseRequiredPermissionsDeclaration = parseRequiredPermissionsDeclaration;
15789
16190
  exports2.parseRequiredPermissions = parseRequiredPermissions;
15790
16191
  exports2.parseAnswerText = parseAnswerText;
15791
16192
  exports2.createEmptyUsageStats = createEmptyUsageStats;
@@ -15795,9 +16196,26 @@ var require_parser = __commonJS({
15795
16196
  exports2.summarizeOpenCodeLine = summarizeOpenCodeLine;
15796
16197
  var types_1 = require_types4();
15797
16198
  var subagent_tool_logger_1 = require_subagent_tool_logger();
16199
+ var validation_state_1 = require_validation_state();
15798
16200
  var apply_patch_1 = require_apply_patch();
15799
- function parseRequiredPermissions(output) {
15800
- let permissions = [];
16201
+ function hasValidationPluginLoaded(output) {
16202
+ return output.split("\n").some((line) => (0, types_1.tryParseJson)(line)?.type === validation_state_1.VALIDATION_LOADED_EVENT_TYPE);
16203
+ }
16204
+ function parseLastValidationState(output) {
16205
+ let validationState;
16206
+ for (const line of output.split("\n")) {
16207
+ if (!line.trim())
16208
+ continue;
16209
+ const event = (0, types_1.tryParseJson)(line);
16210
+ if (event?.type !== validation_state_1.VALIDATION_STATE_EVENT_TYPE || typeof event.sessionID !== "string" || typeof event.clean !== "boolean") {
16211
+ continue;
16212
+ }
16213
+ validationState = event;
16214
+ }
16215
+ return validationState;
16216
+ }
16217
+ function parseRequiredPermissionsDeclaration(output) {
16218
+ let permissions;
15801
16219
  const lines = output.split("\n");
15802
16220
  for (const line of lines) {
15803
16221
  if (!line.trim())
@@ -15813,6 +16231,9 @@ var require_parser = __commonJS({
15813
16231
  }
15814
16232
  return permissions;
15815
16233
  }
16234
+ function parseRequiredPermissions(output) {
16235
+ return parseRequiredPermissionsDeclaration(output) ?? [];
16236
+ }
15816
16237
  function parseAnswerText(output) {
15817
16238
  const messages = output.split("\n").map((line) => (0, types_1.tryParseJson)(line)).filter((event) => event?.type === "text").map((event) => event.part?.text ?? "");
15818
16239
  return (messages[messages.length - 1] ?? "").trim();
@@ -16181,113 +16602,6 @@ var require_progress_handler = __commonJS({
16181
16602
  }
16182
16603
  });
16183
16604
 
16184
- // dist/extension-reporting/detect.js
16185
- var require_detect = __commonJS({
16186
- "dist/extension-reporting/detect.js"(exports2) {
16187
- "use strict";
16188
- Object.defineProperty(exports2, "__esModule", { value: true });
16189
- exports2.BUILDER_EXTENSION_TYPES = void 0;
16190
- exports2.isSpiExtension = isSpiExtension;
16191
- exports2.isExtensionsFile = isExtensionsFile;
16192
- exports2.detectExtension = detectExtension;
16193
- exports2.matchQuotedExtensionConfigProperty = matchQuotedExtensionConfigProperty;
16194
- exports2.extractExtensionDisplayTitle = extractExtensionDisplayTitle;
16195
- exports2.injectCreatedBy = injectCreatedBy;
16196
- var CONTAINER_ROOT_PREFIX = /^\/user-code\//;
16197
- var EXTENSION_FILE_PATTERN = /\/extensions\.ts$|\.extension\.ts$/;
16198
- var SPI_EXTENSION_TYPES = [
16199
- "ecomShippingRates",
16200
- "ecomAdditionalFees",
16201
- "ecomValidations",
16202
- "ecomDiscountTriggers",
16203
- "ecomGiftCards",
16204
- "ecomPaymentSettings",
16205
- "bookingsStaffSortingProvider"
16206
- ];
16207
- exports2.BUILDER_EXTENSION_TYPES = [
16208
- "dashboardPage",
16209
- "dashboardModal",
16210
- "dashboardPlugin",
16211
- "dashboardMenuPlugin",
16212
- "embeddedScript",
16213
- "event",
16214
- "customElement",
16215
- "siteComponent",
16216
- "editorReactComponent",
16217
- "sitePlugin",
16218
- ...SPI_EXTENSION_TYPES,
16219
- "contextProvider",
16220
- "functionLibrary",
16221
- "dataCollections"
16222
- ];
16223
- var SPI_EXTENSION_TYPE_SET = new Set(SPI_EXTENSION_TYPES);
16224
- function isSpiExtension(extensionType) {
16225
- return SPI_EXTENSION_TYPE_SET.has(extensionType);
16226
- }
16227
- function normalizeFilePath(filePath) {
16228
- return filePath.replace(CONTAINER_ROOT_PREFIX, "");
16229
- }
16230
- function isExtensionsFile(filePath) {
16231
- return EXTENSION_FILE_PATTERN.test(filePath);
16232
- }
16233
- function detectExtension(content) {
16234
- for (const extensionType of exports2.BUILDER_EXTENSION_TYPES) {
16235
- if (content.includes(`extensions.${extensionType}(`) || content.includes(`experimentalExtensions.${extensionType}(`)) {
16236
- return extensionType;
16237
- }
16238
- }
16239
- return null;
16240
- }
16241
- function toTitleCase(str) {
16242
- return str.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
16243
- }
16244
- function extractExtensionName(filePath) {
16245
- const parts = normalizeFilePath(filePath).split("/");
16246
- const folderName = parts[parts.length - 2] || "";
16247
- return toTitleCase(folderName);
16248
- }
16249
- function matchQuotedExtensionConfigProperty(content, propName) {
16250
- const objectPropertyQuotedStringValuePattern = `\\b${propName}\\s*:\\s*(?:"([^"\\\\]*)"|'([^'\\\\]*)')`;
16251
- const objectPropertyQuotedStringValueRegex = new RegExp(
16252
- objectPropertyQuotedStringValuePattern,
16253
- // `m` = multiline: `^` / `$` match line starts/ends, not only the whole string.
16254
- "m"
16255
- );
16256
- const quotedStringValueMatch = content.match(objectPropertyQuotedStringValueRegex);
16257
- if (!quotedStringValueMatch)
16258
- return null;
16259
- return quotedStringValueMatch[1] ?? quotedStringValueMatch[2] ?? null;
16260
- }
16261
- function extractExtensionDisplayTitle(content, filePath) {
16262
- const title = matchQuotedExtensionConfigProperty(content, "title");
16263
- if (title)
16264
- return title;
16265
- const name = matchQuotedExtensionConfigProperty(content, "name");
16266
- if (name)
16267
- return name;
16268
- const displayName = matchQuotedExtensionConfigProperty(content, "displayName");
16269
- if (displayName)
16270
- return displayName;
16271
- const idSuffix = matchQuotedExtensionConfigProperty(content, "idSuffix");
16272
- if (idSuffix)
16273
- return idSuffix;
16274
- return extractExtensionName(filePath);
16275
- }
16276
- function injectCreatedBy(content) {
16277
- if (content.includes("createdBy"))
16278
- return content;
16279
- const isGeneric = content.includes("genericExtension(");
16280
- const createdByValue = isGeneric ? ' createdBy: "CODE_GEN",' : ' createdBy: {\n author: "CODE_GEN",\n },';
16281
- return content.replace(/(\S)(\n)(}\))(;?\s*)$/, (_match, preChar, newline, closeBrace, tail) => {
16282
- const needsComma = preChar !== "," && preChar !== "{";
16283
- const separator = needsComma ? `${preChar},` : preChar;
16284
- return `${separator}${newline}${createdByValue}
16285
- ${closeBrace}${tail}`;
16286
- });
16287
- }
16288
- }
16289
- });
16290
-
16291
16605
  // dist/opencode-integration/task-tracker/derived-progress.js
16292
16606
  var require_derived_progress = __commonJS({
16293
16607
  "dist/opencode-integration/task-tracker/derived-progress.js"(exports2) {
@@ -17005,12 +17319,150 @@ var require_process_handlers = __commonJS({
17005
17319
  }
17006
17320
  });
17007
17321
 
17322
+ // dist/validation/editor-components.js
17323
+ var require_editor_components = __commonJS({
17324
+ "dist/validation/editor-components.js"(exports2) {
17325
+ "use strict";
17326
+ Object.defineProperty(exports2, "__esModule", { value: true });
17327
+ exports2.containsTypeScriptFile = containsTypeScriptFile;
17328
+ var promises_1 = require("fs/promises");
17329
+ var path_12 = require("path");
17330
+ async function containsTypeScriptFile(directory) {
17331
+ const entries = await (0, promises_1.readdir)(directory, { withFileTypes: true }).catch((error) => {
17332
+ if (error.code === "ENOENT")
17333
+ return [];
17334
+ throw error;
17335
+ });
17336
+ for (const entry of entries) {
17337
+ if (entry.isFile() && /\.tsx?$/.test(entry.name))
17338
+ return true;
17339
+ if (entry.isDirectory() && await containsTypeScriptFile((0, path_12.join)(directory, entry.name)))
17340
+ return true;
17341
+ }
17342
+ return false;
17343
+ }
17344
+ }
17345
+ });
17346
+
17347
+ // dist/validation/host-validation.js
17348
+ var require_host_validation = __commonJS({
17349
+ "dist/validation/host-validation.js"(exports2) {
17350
+ "use strict";
17351
+ Object.defineProperty(exports2, "__esModule", { value: true });
17352
+ exports2.HostValidationError = exports2.HOST_VALIDATION_STAGE_TIMEOUT_MS = void 0;
17353
+ exports2.runHostValidation = runHostValidation;
17354
+ var child_process_1 = require("child_process");
17355
+ var util_1 = require("util");
17356
+ var ditto_codegen_types_12 = require_dist4();
17357
+ var logger_12 = require_logger();
17358
+ var path_12 = require("path");
17359
+ var editor_components_1 = require_editor_components();
17360
+ var execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
17361
+ var MAX_OUTPUT_BUFFER_BYTES = 10 * 1024 * 1024;
17362
+ var MAX_DIAGNOSTIC_CHARS = 2e4;
17363
+ var MAX_DIAGNOSTIC_SUMMARY_CHARS = 2e3;
17364
+ exports2.HOST_VALIDATION_STAGE_TIMEOUT_MS = 5 * 6e4;
17365
+ var VALIDATION_COMMANDS = [
17366
+ {
17367
+ stage: "typescript",
17368
+ executable: "npx",
17369
+ args: ["tsc", "--noEmit", "-p", "."]
17370
+ },
17371
+ {
17372
+ stage: "wix build",
17373
+ executable: "npx",
17374
+ args: ["wix", "build"]
17375
+ },
17376
+ {
17377
+ stage: "wix generate manifest",
17378
+ executable: "npx",
17379
+ args: ["wix", "generate", "manifest"]
17380
+ }
17381
+ ];
17382
+ var HostValidationError = class extends ditto_codegen_types_12.HostValidationError {
17383
+ constructor(stage, command, options) {
17384
+ const diagnostics = [options.stdout, options.stderr].filter((output) => Boolean(output?.trim())).join("\n").trim();
17385
+ const exit = options.timedOut ? `timed out after ${options.timeoutMs}ms` : options.exitCode === void 0 ? "could not start" : `exited ${options.exitCode}`;
17386
+ super(`Project validation failed at ${stage}: ${command} ${exit}`, {
17387
+ stage,
17388
+ command,
17389
+ exitCode: options.exitCode,
17390
+ timedOut: options.timedOut ?? false,
17391
+ diagnosticSummary: outputAsString(diagnostics, MAX_DIAGNOSTIC_SUMMARY_CHARS)
17392
+ });
17393
+ this.stage = stage;
17394
+ this.validationType = stage;
17395
+ this.command = command;
17396
+ this.timedOut = options.timedOut ?? false;
17397
+ Object.defineProperties(this, {
17398
+ stdout: { value: options.stdout, enumerable: false },
17399
+ stderr: { value: options.stderr, enumerable: false },
17400
+ cause: { value: options.cause, enumerable: false }
17401
+ });
17402
+ }
17403
+ };
17404
+ exports2.HostValidationError = HostValidationError;
17405
+ var executeValidationCommand = async (executable, args, cwd, timeoutMs) => {
17406
+ return execFileAsync(executable, args, {
17407
+ cwd,
17408
+ killSignal: "SIGTERM",
17409
+ maxBuffer: MAX_OUTPUT_BUFFER_BYTES,
17410
+ timeout: timeoutMs
17411
+ });
17412
+ };
17413
+ function outputAsString(output, maxChars = MAX_DIAGNOSTIC_CHARS) {
17414
+ const text = typeof output === "string" ? output : output?.toString() ?? "";
17415
+ if (text.length <= maxChars)
17416
+ return text;
17417
+ const omitted = text.length - maxChars;
17418
+ return `[truncated ${omitted} leading characters]
17419
+ ${text.slice(-maxChars)}`;
17420
+ }
17421
+ function numericExitCode(error) {
17422
+ return typeof error.code === "number" ? error.code : void 0;
17423
+ }
17424
+ async function runHostValidation(cwd, execute = executeValidationCommand) {
17425
+ for (const command of VALIDATION_COMMANDS) {
17426
+ if (command.stage === "wix generate manifest" && !await (0, editor_components_1.containsTypeScriptFile)((0, path_12.join)(cwd, "src/extensions/site/components")))
17427
+ continue;
17428
+ const displayCommand = [command.executable, ...command.args].join(" ");
17429
+ const startTime = Date.now();
17430
+ logger_12.logger.info("[Host Validation] Starting stage", {
17431
+ stage: command.stage,
17432
+ command: displayCommand
17433
+ });
17434
+ try {
17435
+ await execute(command.executable, command.args, cwd, exports2.HOST_VALIDATION_STAGE_TIMEOUT_MS);
17436
+ logger_12.logger.info("[Host Validation] Stage passed", {
17437
+ stage: command.stage,
17438
+ durationMs: Date.now() - startTime
17439
+ });
17440
+ } catch (error) {
17441
+ const failure = error instanceof Error ? error : new Error(String(error));
17442
+ const timedOut = failure.killed === true && failure.signal === "SIGTERM";
17443
+ const stderr = outputAsString(failure.stderr) || (timedOut ? `Command timed out after ${exports2.HOST_VALIDATION_STAGE_TIMEOUT_MS}ms` : failure.message);
17444
+ throw new HostValidationError(command.stage, displayCommand, {
17445
+ exitCode: numericExitCode(failure),
17446
+ stdout: outputAsString(failure.stdout),
17447
+ stderr,
17448
+ timedOut,
17449
+ timeoutMs: exports2.HOST_VALIDATION_STAGE_TIMEOUT_MS
17450
+ });
17451
+ }
17452
+ }
17453
+ }
17454
+ }
17455
+ });
17456
+
17008
17457
  // dist/opencode-integration/execution/executor.js
17009
17458
  var require_executor = __commonJS({
17010
17459
  "dist/opencode-integration/execution/executor.js"(exports2) {
17011
17460
  "use strict";
17012
17461
  Object.defineProperty(exports2, "__esModule", { value: true });
17462
+ exports2.reserveHostValidationRepairAttempt = reserveHostValidationRepairAttempt;
17463
+ exports2.updateRequiredPermissions = updateRequiredPermissions;
17013
17464
  exports2.classifyAttempt = classifyAttempt;
17465
+ exports2.applyPostRunValidation = applyPostRunValidation;
17014
17466
  exports2.executeOpenCode = executeOpenCode;
17015
17467
  exports2.resolveFinalRunCost = resolveFinalRunCost;
17016
17468
  var child_process_1 = require("child_process");
@@ -17027,11 +17479,16 @@ var require_executor = __commonJS({
17027
17479
  var process_manager_1 = require_process_manager();
17028
17480
  var process_handlers_1 = require_process_handlers();
17029
17481
  var logger_12 = require_logger();
17482
+ var host_validation_1 = require_host_validation();
17030
17483
  var MAX_RETRIES = 5;
17484
+ var MAX_HOST_VALIDATION_FAILURES = 2;
17031
17485
  var MAX_STALL_ATTEMPTS = 2;
17032
17486
  function failureReason(result) {
17033
17487
  if (result.stalled)
17034
17488
  return "stall";
17489
+ if (result.error instanceof host_validation_1.HostValidationError) {
17490
+ return "host validation failure";
17491
+ }
17035
17492
  if ((0, parser_1.hasSessionError)(result.stdout))
17036
17493
  return "session error";
17037
17494
  if (result.error instanceof ditto_codegen_types_12.ProcessExecutionError) {
@@ -17042,13 +17499,50 @@ var require_executor = __commonJS({
17042
17499
  }
17043
17500
  return null;
17044
17501
  }
17045
- function classifyAttempt(result, stalls) {
17502
+ function reserveHostValidationRepairAttempt(maxAttempts, hostValidationFailures) {
17503
+ return hostValidationFailures === 1 ? maxAttempts + 1 : maxAttempts;
17504
+ }
17505
+ function updateRequiredPermissions(current, result) {
17506
+ if (!result.success || failureReason(result))
17507
+ return current;
17508
+ return (0, parser_1.parseRequiredPermissionsDeclaration)(result.stdout) ?? current;
17509
+ }
17510
+ function classifyAttempt(result, stalls, hostValidationFailures = 0) {
17046
17511
  const reason = failureReason(result);
17047
17512
  if (!reason)
17048
17513
  return { retryable: false, reason: null };
17514
+ if (reason === "host validation failure") {
17515
+ if (result.error instanceof host_validation_1.HostValidationError && result.error.stage === "agent validation state") {
17516
+ return { retryable: false, reason };
17517
+ }
17518
+ return {
17519
+ retryable: hostValidationFailures < MAX_HOST_VALIDATION_FAILURES,
17520
+ reason
17521
+ };
17522
+ }
17049
17523
  return { retryable: stalls < MAX_STALL_ATTEMPTS, reason };
17050
17524
  }
17051
- async function executeOpenCode(options) {
17525
+ async function applyPostRunValidation(result, postRunValidation) {
17526
+ if (!result.success || !postRunValidation)
17527
+ return result;
17528
+ try {
17529
+ await postRunValidation(result.stdout);
17530
+ return result;
17531
+ } catch (error) {
17532
+ const validationError = error instanceof host_validation_1.HostValidationError ? error : new host_validation_1.HostValidationError("project finalization", "project finalization", {
17533
+ stderr: error instanceof Error ? error.message : String(error),
17534
+ cause: error
17535
+ });
17536
+ return {
17537
+ ...result,
17538
+ success: false,
17539
+ exitCode: validationError.exitCode ?? null,
17540
+ stderr: validationError.stderr ?? result.stderr,
17541
+ error: validationError
17542
+ };
17543
+ }
17544
+ }
17545
+ async function executeOpenCode(options, executeAttempt = executeOpenCodeOnce) {
17052
17546
  let lastResult = null;
17053
17547
  let accumulatedUsage = (0, parser_1.createEmptyUsageStats)();
17054
17548
  const accumulatedSkills = [];
@@ -17056,26 +17550,35 @@ var require_executor = __commonJS({
17056
17550
  let currentPrompt = options.prompt;
17057
17551
  let lastFailureReason = null;
17058
17552
  let stalls = 0;
17553
+ let hostValidationFailures = 0;
17554
+ let requiredPermissions = [];
17555
+ let maxAttempts = MAX_RETRIES;
17059
17556
  const forceFresh = process.env.CODEGEN_FRESH_SESSION === "true";
17060
17557
  let continueSession = forceFresh ? false : options.continueSession ?? false;
17061
17558
  const env = (0, config_12.getOpenCodeEnv)(options.projectId, job_context_storage_12.jobContextStorage.getStore()?.kind);
17062
17559
  const statsBaseline = await (0, cost_tracker_1.fetchOpenCodeStats)(options.outputPath, env);
17063
17560
  const baselineCost = statsBaseline ? (0, cost_tracker_1.parseStatsTotalCost)(statsBaseline) : null;
17064
17561
  logger_12.logger.debug("[OpenCode] Stats baseline before run", { baselineCost });
17065
- for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
17562
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
17066
17563
  if (attempt > 1) {
17067
- const failureDetail = lastResult?.error?.message || lastResult?.stderr || "Process timed out";
17068
- logger_12.logger.info(`[OpenCode] Retry attempt ${attempt}/${MAX_RETRIES} after ${lastFailureReason} - starting fresh session with recovery context`, { reason: lastFailureReason, detail: failureDetail.slice(0, 500) });
17564
+ const failureDetail = lastResult?.error instanceof host_validation_1.HostValidationError ? [lastResult.error.message, lastResult.error.stderr].filter((value) => Boolean(value)).join("\n") : lastResult?.error?.message || lastResult?.stderr || "Process timed out";
17565
+ logger_12.logger.info(`[OpenCode] Retry attempt ${attempt}/${maxAttempts} after ${lastFailureReason} - starting fresh session with recovery context`, { reason: lastFailureReason, detail: failureDetail.slice(0, 500) });
17069
17566
  const filesChanged = await (0, file_changes_1.collectGitFileChanges)(options.outputPath, options.gitBaseline);
17070
17567
  currentPrompt = (0, prompts_1.buildRecoveryPrompt)(options.prompt, filesChanged, failureDetail, lastFailureReason);
17071
17568
  continueSession = false;
17072
17569
  }
17073
- const result = await executeOpenCodeOnce({ ...options, prompt: currentPrompt, continueSession }, attempt, toolUsage);
17570
+ let result = await executeAttempt({ ...options, prompt: currentPrompt, continueSession }, attempt, maxAttempts, toolUsage);
17074
17571
  accumulatedUsage = (0, parser_1.mergeUsageStats)(accumulatedUsage, result.usage);
17075
17572
  accumulatedSkills.push(...result.skillsUsed);
17573
+ requiredPermissions = updateRequiredPermissions(requiredPermissions, result);
17574
+ result = await applyPostRunValidation(result, options.postRunValidation);
17076
17575
  if (result.stalled)
17077
17576
  stalls += 1;
17078
- const { retryable, reason } = classifyAttempt(result, stalls);
17577
+ if (result.error instanceof host_validation_1.HostValidationError && result.error.stage !== "agent validation state") {
17578
+ hostValidationFailures += 1;
17579
+ maxAttempts = reserveHostValidationRepairAttempt(maxAttempts, hostValidationFailures);
17580
+ }
17581
+ const { retryable, reason } = classifyAttempt(result, stalls, hostValidationFailures);
17079
17582
  if (!retryable) {
17080
17583
  if (reason) {
17081
17584
  logger_12.logger.warn(`[OpenCode] Not retrying after ${reason}`, {
@@ -17087,6 +17590,7 @@ var require_executor = __commonJS({
17087
17590
  const finalResult2 = {
17088
17591
  ...result,
17089
17592
  agentMessage: (0, parser_1.parseAnswerText)(result.stdout),
17593
+ requiredPermissions,
17090
17594
  usage: accumulatedUsage,
17091
17595
  skillsUsed: accumulatedSkills,
17092
17596
  toolUsage: toolUsage.toSummary()
@@ -17098,17 +17602,18 @@ var require_executor = __commonJS({
17098
17602
  lastFailureReason = reason;
17099
17603
  logger_12.logger.warn(`[OpenCode] Attempt failed due to ${reason}, will retry`, {
17100
17604
  attempt,
17101
- maxRetries: MAX_RETRIES,
17605
+ maxRetries: maxAttempts,
17102
17606
  detail: (result.error?.message || result.stderr || "").slice(0, 500)
17103
17607
  });
17104
17608
  }
17105
17609
  logger_12.logger.warn("[OpenCode] All retry attempts exhausted", {
17106
- maxRetries: MAX_RETRIES
17610
+ maxRetries: maxAttempts
17107
17611
  });
17108
17612
  accumulatedUsage = await resolveFinalRunCost(accumulatedUsage, options, baselineCost);
17109
17613
  const finalResult = {
17110
17614
  ...lastResult,
17111
17615
  agentMessage: (0, parser_1.parseAnswerText)(lastResult.stdout),
17616
+ requiredPermissions,
17112
17617
  usage: accumulatedUsage,
17113
17618
  skillsUsed: Array.from(accumulatedSkills),
17114
17619
  toolUsage: toolUsage.toSummary()
@@ -17140,7 +17645,7 @@ var require_executor = __commonJS({
17140
17645
  const sessionArgs = continueSession ? ["--continue"] : [];
17141
17646
  return ["run", ...sessionArgs, "--format", "json", prompt];
17142
17647
  }
17143
- async function executeOpenCodeOnce(options, attempt, toolUsage) {
17648
+ async function executeOpenCodeOnce(options, attempt, maxAttempts, toolUsage) {
17144
17649
  const { prompt, outputPath, projectId, onStdout, onStderr, continueSession = false } = options;
17145
17650
  const startTime = Date.now();
17146
17651
  const taskTracker = new task_tracker_1.OpenCodeTaskTracker(outputPath, toolUsage);
@@ -17179,7 +17684,7 @@ var require_executor = __commonJS({
17179
17684
  const args = buildArgs(prompt, continueSession);
17180
17685
  logger_12.logger.info("[OpenCode] Executing opencode run", {
17181
17686
  attempt,
17182
- maxRetries: MAX_RETRIES,
17687
+ maxRetries: maxAttempts,
17183
17688
  workingDirectory: outputPath,
17184
17689
  continueSession,
17185
17690
  model: (0, model_knobs_1.getModel)(),
@@ -17187,6 +17692,9 @@ var require_executor = __commonJS({
17187
17692
  });
17188
17693
  logger_12.logger.debug("[OpenCode] Full prompt", { prompt });
17189
17694
  const env = (0, config_12.getOpenCodeEnv)(projectId, job_context_storage_12.jobContextStorage.getStore()?.kind);
17695
+ env.CODEGEN_VALIDATION_BASELINE = options.gitBaseline;
17696
+ env.CODEGEN_PREPARE_EXTENSION_METADATA = options.prepareExtensionMetadata ? "1" : "0";
17697
+ env.CODEGEN_REQUIRE_VALIDATION = attempt > 1 ? "1" : "0";
17190
17698
  ctx.child = (0, child_process_1.spawn)("opencode", args, {
17191
17699
  cwd: outputPath,
17192
17700
  env,
@@ -17222,6 +17730,41 @@ var require_executor = __commonJS({
17222
17730
  }
17223
17731
  });
17224
17732
 
17733
+ // dist/validation/session-validation.js
17734
+ var require_session_validation = __commonJS({
17735
+ "dist/validation/session-validation.js"(exports2) {
17736
+ "use strict";
17737
+ Object.defineProperty(exports2, "__esModule", { value: true });
17738
+ exports2.validateSessionOrFallback = validateSessionOrFallback;
17739
+ var parser_1 = require_parser();
17740
+ var prepare_created_by_1 = require_prepare_created_by();
17741
+ var logger_12 = require_logger();
17742
+ var host_validation_1 = require_host_validation();
17743
+ async function validateSessionOrFallback(outputPath, stdout, metadataBaseline) {
17744
+ const validationState = (0, parser_1.parseLastValidationState)(stdout);
17745
+ if (!validationState) {
17746
+ if ((0, parser_1.hasValidationPluginLoaded)(stdout))
17747
+ return;
17748
+ logger_12.logger.info("[Validation State] No plugin state found; running host validation fallback");
17749
+ if (metadataBaseline !== void 0)
17750
+ await (0, prepare_created_by_1.prepareCreatedByForValidation)(outputPath, metadataBaseline);
17751
+ await (0, host_validation_1.runHostValidation)(outputPath);
17752
+ return;
17753
+ }
17754
+ if (validationState.clean) {
17755
+ logger_12.logger.info("[Validation State] Agent session ended clean", {
17756
+ sessionID: validationState.sessionID
17757
+ });
17758
+ return;
17759
+ }
17760
+ throw new host_validation_1.HostValidationError("agent validation state", "validate({ runBuild: true })", {
17761
+ exitCode: 1,
17762
+ stderr: "Project files remain unvalidated after the in-session validation reminders."
17763
+ });
17764
+ }
17765
+ }
17766
+ });
17767
+
17225
17768
  // dist/opencode-integration/execution/opencode-runner.js
17226
17769
  var require_opencode_runner = __commonJS({
17227
17770
  "dist/opencode-integration/execution/opencode-runner.js"(exports2) {
@@ -17234,6 +17777,7 @@ var require_opencode_runner = __commonJS({
17234
17777
  var prompts_1 = require_prompts();
17235
17778
  var executor_1 = require_executor();
17236
17779
  var parser_1 = require_parser();
17780
+ var session_validation_1 = require_session_validation();
17237
17781
  async function runOpenCodeInit(options) {
17238
17782
  const { blueprint, outputPath, projectId, chatHistory, gitBaseline, onStdout, onStderr } = options;
17239
17783
  const prompt = (0, prompts_1.buildInitPrompt)(blueprint, chatHistory);
@@ -17242,6 +17786,8 @@ var require_opencode_runner = __commonJS({
17242
17786
  outputPath,
17243
17787
  projectId,
17244
17788
  gitBaseline,
17789
+ prepareExtensionMetadata: true,
17790
+ postRunValidation: (stdout) => (0, session_validation_1.validateSessionOrFallback)(outputPath, stdout, gitBaseline),
17245
17791
  onStdout,
17246
17792
  onStderr
17247
17793
  });
@@ -17255,6 +17801,8 @@ var require_opencode_runner = __commonJS({
17255
17801
  projectId,
17256
17802
  continueSession: true,
17257
17803
  gitBaseline,
17804
+ prepareExtensionMetadata: true,
17805
+ postRunValidation: (stdout) => (0, session_validation_1.validateSessionOrFallback)(outputPath, stdout, gitBaseline),
17258
17806
  onStdout,
17259
17807
  onStderr
17260
17808
  });
@@ -17286,6 +17834,7 @@ var require_opencode_runner = __commonJS({
17286
17834
  outputPath,
17287
17835
  projectId,
17288
17836
  gitBaseline,
17837
+ postRunValidation: (stdout) => (0, session_validation_1.validateSessionOrFallback)(outputPath, stdout),
17289
17838
  onStdout,
17290
17839
  onStderr
17291
17840
  });
@@ -17672,39 +18221,6 @@ var require_codegen_flow_helpers = __commonJS({
17672
18221
  }
17673
18222
  });
17674
18223
 
17675
- // dist/extension-reporting/inject-created-by.js
17676
- var require_inject_created_by = __commonJS({
17677
- "dist/extension-reporting/inject-created-by.js"(exports2) {
17678
- "use strict";
17679
- Object.defineProperty(exports2, "__esModule", { value: true });
17680
- exports2.injectCreatedByIntoExtensionFiles = injectCreatedByIntoExtensionFiles;
17681
- var promises_1 = require("fs/promises");
17682
- var path_12 = require("path");
17683
- var logger_12 = require_logger();
17684
- var detect_1 = require_detect();
17685
- async function injectCreatedByIntoExtensionFiles(cwd, createdExtensions) {
17686
- for (const { path: filePath } of createdExtensions) {
17687
- const absolutePath = (0, path_12.join)(cwd, filePath);
17688
- try {
17689
- const original = await (0, promises_1.readFile)(absolutePath, "utf-8");
17690
- const injected = (0, detect_1.injectCreatedBy)(original);
17691
- if (injected !== original) {
17692
- await (0, promises_1.writeFile)(absolutePath, injected, "utf-8");
17693
- logger_12.logger.info("[OpenCode] Injected createdBy into extension file", {
17694
- filePath
17695
- });
17696
- }
17697
- } catch (error) {
17698
- logger_12.logger.error("[OpenCode] Failed to inject createdBy", {
17699
- filePath,
17700
- error: error instanceof Error ? error.message : String(error)
17701
- });
17702
- }
17703
- }
17704
- }
17705
- }
17706
- });
17707
-
17708
18224
  // ../../node_modules/@wix/bi-logger-dev-tools-data/dist/cjs/v2/index.js
17709
18225
  var require_v2 = __commonJS({
17710
18226
  "../../node_modules/@wix/bi-logger-dev-tools-data/dist/cjs/v2/index.js"(exports2) {
@@ -22787,7 +23303,6 @@ var require_opencode_init = __commonJS({
22787
23303
  var logger_12 = require_logger();
22788
23304
  var model_knobs_1 = require_model_knobs();
22789
23305
  var file_changes_1 = require_file_changes();
22790
- var inject_created_by_1 = require_inject_created_by();
22791
23306
  var job_payload_1 = require_job_payload2();
22792
23307
  var bi_events_1 = require_bi_events();
22793
23308
  var expensive_run_1 = require_expensive_run();
@@ -22853,7 +23368,6 @@ var require_opencode_init = __commonJS({
22853
23368
  filesChanged = files.length > 0;
22854
23369
  const agentOutput = (0, agent_io_1.readAgentOutput)(outputPath);
22855
23370
  const extensions = await (0, job_payload_1.buildExtensionsJobPayload)(outputPath, files);
22856
- await (0, inject_created_by_1.injectCreatedByIntoExtensionFiles)(outputPath, extensions.created);
22857
23371
  await (0, codegen_flow_helpers_12.updateJobPayload)(localJobContext, {
22858
23372
  requiredPermissions: result.requiredPermissions,
22859
23373
  agentMessage: result.agentMessage,
@@ -23008,7 +23522,6 @@ var require_opencode_iterate = __commonJS({
23008
23522
  var logger_12 = require_logger();
23009
23523
  var model_knobs_1 = require_model_knobs();
23010
23524
  var file_changes_1 = require_file_changes();
23011
- var inject_created_by_1 = require_inject_created_by();
23012
23525
  var job_payload_1 = require_job_payload2();
23013
23526
  var expensive_run_1 = require_expensive_run();
23014
23527
  var bi_events_1 = require_bi_events();
@@ -23062,7 +23575,6 @@ var require_opencode_iterate = __commonJS({
23062
23575
  filesChanged = files.length > 0;
23063
23576
  const agentOutput = (0, agent_io_1.readAgentOutput)(outputPath);
23064
23577
  const extensions = await (0, job_payload_1.buildExtensionsJobPayload)(outputPath, files);
23065
- await (0, inject_created_by_1.injectCreatedByIntoExtensionFiles)(outputPath, extensions.created);
23066
23578
  await (0, codegen_flow_helpers_12.updateJobPayload)(localJobContext, {
23067
23579
  requiredPermissions: result.requiredPermissions,
23068
23580
  agentMessage: result.agentMessage,
@@ -23196,6 +23708,42 @@ var require_opencode_ask_orchestrator = __commonJS({
23196
23708
  }
23197
23709
  });
23198
23710
 
23711
+ // dist/extension-reporting/inject-created-by.js
23712
+ var require_inject_created_by = __commonJS({
23713
+ "dist/extension-reporting/inject-created-by.js"(exports2) {
23714
+ "use strict";
23715
+ Object.defineProperty(exports2, "__esModule", { value: true });
23716
+ exports2.injectCreatedByIntoExtensionFiles = injectCreatedByIntoExtensionFiles;
23717
+ var promises_1 = require("fs/promises");
23718
+ var path_12 = require("path");
23719
+ var logger_12 = require_logger();
23720
+ var detect_1 = require_detect();
23721
+ async function injectCreatedByIntoExtensionFiles(cwd, createdExtensions) {
23722
+ let hasWrittenFiles = false;
23723
+ for (const { path: filePath } of createdExtensions) {
23724
+ const absolutePath = (0, path_12.join)(cwd, filePath);
23725
+ try {
23726
+ const original = await (0, promises_1.readFile)(absolutePath, "utf-8");
23727
+ const injected = (0, detect_1.injectCreatedBy)(original);
23728
+ if (injected !== original) {
23729
+ hasWrittenFiles = true;
23730
+ await (0, promises_1.writeFile)(absolutePath, injected, "utf-8");
23731
+ logger_12.logger.info("[OpenCode] Injected createdBy into extension file", {
23732
+ filePath
23733
+ });
23734
+ }
23735
+ } catch (error) {
23736
+ logger_12.logger.error("[OpenCode] Failed to inject createdBy", {
23737
+ filePath,
23738
+ error: error instanceof Error ? error.message : String(error)
23739
+ });
23740
+ }
23741
+ }
23742
+ return hasWrittenFiles;
23743
+ }
23744
+ }
23745
+ });
23746
+
23199
23747
  // dist/flows/opencode-ask.js
23200
23748
  var require_opencode_ask = __commonJS({
23201
23749
  "dist/flows/opencode-ask.js"(exports2) {
@@ -24345,6 +24893,7 @@ var require_plugins3 = __commonJS({
24345
24893
  var generated_files_guard_1 = require_generated_files_guard();
24346
24894
  var subagent_tool_logger_1 = require_subagent_tool_logger();
24347
24895
  var tool_policies_1 = require_tool_policies3();
24896
+ var validation_state_1 = require_validation_state();
24348
24897
  var tool_policies_drift_1 = require_tool_policies_drift();
24349
24898
  Object.defineProperty(exports2, "validateToolPolicies", { enumerable: true, get: function() {
24350
24899
  return tool_policies_drift_1.validateToolPolicies;
@@ -24354,7 +24903,8 @@ var require_plugins3 = __commonJS({
24354
24903
  (0, docs_feedback_nudge_1.writeDocsFeedbackNudgePlugin)(),
24355
24904
  (0, generated_files_guard_1.writeGeneratedFilesGuardPlugin)(),
24356
24905
  (0, subagent_tool_logger_1.writeSubagentToolLoggerPlugin)(),
24357
- (0, tool_policies_1.writeToolPoliciesPlugin)(toolPolicies)
24906
+ (0, tool_policies_1.writeToolPoliciesPlugin)(toolPolicies),
24907
+ (0, validation_state_1.writeValidationStatePlugin)()
24358
24908
  ]);
24359
24909
  }
24360
24910
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/ditto-codegen-public",
3
- "version": "1.0.473",
3
+ "version": "1.0.474",
4
4
  "description": "AI-powered Wix CLI app generator - standalone executable",
5
5
  "scripts": {
6
6
  "build": "node build.mjs",
@@ -29,5 +29,5 @@
29
29
  "esbuild": "^0.27.2",
30
30
  "vitest": "^4.0.16"
31
31
  },
32
- "falconPackageHash": "d57aed781560712e54702652eaf61c531616393b40b98cca45a25e11"
32
+ "falconPackageHash": "8269ada8fd7fe966143942252728a71519b497b91e418c123662b47d"
33
33
  }