@wix/ditto-codegen-public 1.0.472 → 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.
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
@@ -14378,7 +14421,7 @@ var require_site = __commonJS({
14378
14421
  "../codegen-common-logic/dist/tool-policies/site.js"(exports2) {
14379
14422
  "use strict";
14380
14423
  Object.defineProperty(exports2, "__esModule", { value: true });
14381
- exports2.SITE_POLICIES = exports2.SITE_DATA_COLLECTION_GENERATE_POLICY = exports2.STORES_VERSIONING_POLICY = void 0;
14424
+ exports2.SITE_POLICIES = exports2.SITE_PACKAGE_LOCK_POLICY = exports2.SITE_DATA_COLLECTION_GENERATE_POLICY = exports2.STORES_VERSIONING_POLICY = void 0;
14382
14425
  exports2.STORES_VERSIONING_POLICY = {
14383
14426
  type: "read",
14384
14427
  mode: "prepend",
@@ -14391,9 +14434,20 @@ var require_site = __commonJS({
14391
14434
  blockedExtensionTypes: ["DATA_COLLECTION"],
14392
14435
  message: `BLOCKED: DATA_COLLECTION extensions are not scaffolded in this environment. Invoke the wix-site-data-collection skill to create or change collections. Do not retry with wix generate.`
14393
14436
  };
14437
+ exports2.SITE_PACKAGE_LOCK_POLICY = {
14438
+ type: "commandBlock",
14439
+ commandFragments: [
14440
+ "--package-lock=false",
14441
+ "--package-lock false",
14442
+ "--no-package-lock",
14443
+ "npm_config_package_lock=false"
14444
+ ],
14445
+ message: `BLOCKED: do not disable the package lockfile (--package-lock=false, --package-lock false, --no-package-lock). Run the install without it; if the packages are heavy, install them in several smaller commands (the sandbox has a memory limit).`
14446
+ };
14394
14447
  exports2.SITE_POLICIES = [
14395
14448
  exports2.STORES_VERSIONING_POLICY,
14396
- exports2.SITE_DATA_COLLECTION_GENERATE_POLICY
14449
+ exports2.SITE_DATA_COLLECTION_GENERATE_POLICY,
14450
+ exports2.SITE_PACKAGE_LOCK_POLICY
14397
14451
  ];
14398
14452
  }
14399
14453
  });
@@ -14939,7 +14993,7 @@ ${environmentIdentity}`;
14939
14993
  - List any manual setup the user must still do for the feature to work, as short "next steps" (e.g. installing a dependent app or enabling a dashboard setting).
14940
14994
  - Be honest: if you didn't fully build what was asked (e.g. stored data but didn't send it), say so. Keep it short.`;
14941
14995
  function buildFileOperationsRules(multiEditContextClause) {
14942
- return `- Package dependencies \u2014 \`npm install <pkg>\` any package not already in \`package.json\` BEFORE the first \`validate\` (do NOT wait for \`TS2307\`); install all needed packages in ONE command. Do NOT hand-edit \`package.json\` for deps unless npm cannot be used.
14996
+ return `- Package dependencies \u2014 \`npm install <pkg>\` any package not already in \`package.json\` BEFORE the first \`validate\` (do NOT wait for \`TS2307\`); install all needed packages in ONE command, except heavy ones: the sandbox has a memory limit and an install that exceeds it kills the machine and loses the whole run, so install those in several smaller commands. Do NOT hand-edit \`package.json\` for deps unless npm cannot be used. Never pass \`--package-lock=false\`.
14943
14997
  - File operations \u2014 pick the BATCH tool whenever you have 2+ files; the single-file variants are 5\u201310\xD7 slower:
14944
14998
  - \`batch-write\` to create N new files in one call. NEVER call \`write\` more than once per turn \u2014 use batch-write instead. \`write\` is reserved for single-file creation.
14945
14999
  - \`batch-read\` to read N files in one call. NEVER call \`read\` more than once per turn \u2014 use batch-read instead.
@@ -14960,12 +15014,12 @@ var require_codegen_rules = __commonJS({
14960
15014
  var shared_rules_1 = require_shared_rules();
14961
15015
  var model_knobs_1 = require_model_knobs();
14962
15016
  var DELEGATED_VALIDATION = {
14963
- toolRule: "- `validate` (tsc + build) is run by the `codegen-validator` subagent \u2014 do NOT call it directly; delegate via `task` at step 5.",
14964
- 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.`
14965
15019
  };
14966
15020
  var DIRECT_VALIDATION = {
14967
- toolRule: "- `validate` (tsc + build) \u2014 you call it yourself at step 5. Do NOT delegate it.",
14968
- 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.`
14969
15023
  };
14970
15024
  var buildCoreRules = (validation) => `CORE PRINCIPLES:
14971
15025
  - Do NOT invent or assume new types, modules, functions, props, events, or imports.
@@ -15010,7 +15064,7 @@ FILE CREATION:
15010
15064
  - Do NOT output comments in code unless they explain non-obvious logic.
15011
15065
 
15012
15066
  GENERATED FILES:
15013
- - \`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.
15014
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.
15015
15069
 
15016
15070
  TYPESCRIPT:
@@ -15114,7 +15168,7 @@ MINIMIZE TEXT OUTPUT \u2014 CRITICAL:
15114
15168
  - Every text token costs money. Use tools, not words.
15115
15169
 
15116
15170
  TOOL USAGE:
15117
- - \`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.
15118
15172
  ${(0, shared_rules_1.buildFileOperationsRules)("resolving conflicts")}
15119
15173
  - NEVER run preview, dev, release, or promote commands.
15120
15174
 
@@ -15756,6 +15810,361 @@ export const SubagentToolLogger = async () => {
15756
15810
  }
15757
15811
  });
15758
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
+
15759
16168
  // dist/opencode-integration/apply-patch.js
15760
16169
  var require_apply_patch = __commonJS({
15761
16170
  "dist/opencode-integration/apply-patch.js"(exports2) {
@@ -15775,6 +16184,9 @@ var require_parser = __commonJS({
15775
16184
  "dist/opencode-integration/execution/parser.js"(exports2) {
15776
16185
  "use strict";
15777
16186
  Object.defineProperty(exports2, "__esModule", { value: true });
16187
+ exports2.hasValidationPluginLoaded = hasValidationPluginLoaded;
16188
+ exports2.parseLastValidationState = parseLastValidationState;
16189
+ exports2.parseRequiredPermissionsDeclaration = parseRequiredPermissionsDeclaration;
15778
16190
  exports2.parseRequiredPermissions = parseRequiredPermissions;
15779
16191
  exports2.parseAnswerText = parseAnswerText;
15780
16192
  exports2.createEmptyUsageStats = createEmptyUsageStats;
@@ -15784,9 +16196,26 @@ var require_parser = __commonJS({
15784
16196
  exports2.summarizeOpenCodeLine = summarizeOpenCodeLine;
15785
16197
  var types_1 = require_types4();
15786
16198
  var subagent_tool_logger_1 = require_subagent_tool_logger();
16199
+ var validation_state_1 = require_validation_state();
15787
16200
  var apply_patch_1 = require_apply_patch();
15788
- function parseRequiredPermissions(output) {
15789
- 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;
15790
16219
  const lines = output.split("\n");
15791
16220
  for (const line of lines) {
15792
16221
  if (!line.trim())
@@ -15802,6 +16231,9 @@ var require_parser = __commonJS({
15802
16231
  }
15803
16232
  return permissions;
15804
16233
  }
16234
+ function parseRequiredPermissions(output) {
16235
+ return parseRequiredPermissionsDeclaration(output) ?? [];
16236
+ }
15805
16237
  function parseAnswerText(output) {
15806
16238
  const messages = output.split("\n").map((line) => (0, types_1.tryParseJson)(line)).filter((event) => event?.type === "text").map((event) => event.part?.text ?? "");
15807
16239
  return (messages[messages.length - 1] ?? "").trim();
@@ -16170,113 +16602,6 @@ var require_progress_handler = __commonJS({
16170
16602
  }
16171
16603
  });
16172
16604
 
16173
- // dist/extension-reporting/detect.js
16174
- var require_detect = __commonJS({
16175
- "dist/extension-reporting/detect.js"(exports2) {
16176
- "use strict";
16177
- Object.defineProperty(exports2, "__esModule", { value: true });
16178
- exports2.BUILDER_EXTENSION_TYPES = void 0;
16179
- exports2.isSpiExtension = isSpiExtension;
16180
- exports2.isExtensionsFile = isExtensionsFile;
16181
- exports2.detectExtension = detectExtension;
16182
- exports2.matchQuotedExtensionConfigProperty = matchQuotedExtensionConfigProperty;
16183
- exports2.extractExtensionDisplayTitle = extractExtensionDisplayTitle;
16184
- exports2.injectCreatedBy = injectCreatedBy;
16185
- var CONTAINER_ROOT_PREFIX = /^\/user-code\//;
16186
- var EXTENSION_FILE_PATTERN = /\/extensions\.ts$|\.extension\.ts$/;
16187
- var SPI_EXTENSION_TYPES = [
16188
- "ecomShippingRates",
16189
- "ecomAdditionalFees",
16190
- "ecomValidations",
16191
- "ecomDiscountTriggers",
16192
- "ecomGiftCards",
16193
- "ecomPaymentSettings",
16194
- "bookingsStaffSortingProvider"
16195
- ];
16196
- exports2.BUILDER_EXTENSION_TYPES = [
16197
- "dashboardPage",
16198
- "dashboardModal",
16199
- "dashboardPlugin",
16200
- "dashboardMenuPlugin",
16201
- "embeddedScript",
16202
- "event",
16203
- "customElement",
16204
- "siteComponent",
16205
- "editorReactComponent",
16206
- "sitePlugin",
16207
- ...SPI_EXTENSION_TYPES,
16208
- "contextProvider",
16209
- "functionLibrary",
16210
- "dataCollections"
16211
- ];
16212
- var SPI_EXTENSION_TYPE_SET = new Set(SPI_EXTENSION_TYPES);
16213
- function isSpiExtension(extensionType) {
16214
- return SPI_EXTENSION_TYPE_SET.has(extensionType);
16215
- }
16216
- function normalizeFilePath(filePath) {
16217
- return filePath.replace(CONTAINER_ROOT_PREFIX, "");
16218
- }
16219
- function isExtensionsFile(filePath) {
16220
- return EXTENSION_FILE_PATTERN.test(filePath);
16221
- }
16222
- function detectExtension(content) {
16223
- for (const extensionType of exports2.BUILDER_EXTENSION_TYPES) {
16224
- if (content.includes(`extensions.${extensionType}(`) || content.includes(`experimentalExtensions.${extensionType}(`)) {
16225
- return extensionType;
16226
- }
16227
- }
16228
- return null;
16229
- }
16230
- function toTitleCase(str) {
16231
- return str.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
16232
- }
16233
- function extractExtensionName(filePath) {
16234
- const parts = normalizeFilePath(filePath).split("/");
16235
- const folderName = parts[parts.length - 2] || "";
16236
- return toTitleCase(folderName);
16237
- }
16238
- function matchQuotedExtensionConfigProperty(content, propName) {
16239
- const objectPropertyQuotedStringValuePattern = `\\b${propName}\\s*:\\s*(?:"([^"\\\\]*)"|'([^'\\\\]*)')`;
16240
- const objectPropertyQuotedStringValueRegex = new RegExp(
16241
- objectPropertyQuotedStringValuePattern,
16242
- // `m` = multiline: `^` / `$` match line starts/ends, not only the whole string.
16243
- "m"
16244
- );
16245
- const quotedStringValueMatch = content.match(objectPropertyQuotedStringValueRegex);
16246
- if (!quotedStringValueMatch)
16247
- return null;
16248
- return quotedStringValueMatch[1] ?? quotedStringValueMatch[2] ?? null;
16249
- }
16250
- function extractExtensionDisplayTitle(content, filePath) {
16251
- const title = matchQuotedExtensionConfigProperty(content, "title");
16252
- if (title)
16253
- return title;
16254
- const name = matchQuotedExtensionConfigProperty(content, "name");
16255
- if (name)
16256
- return name;
16257
- const displayName = matchQuotedExtensionConfigProperty(content, "displayName");
16258
- if (displayName)
16259
- return displayName;
16260
- const idSuffix = matchQuotedExtensionConfigProperty(content, "idSuffix");
16261
- if (idSuffix)
16262
- return idSuffix;
16263
- return extractExtensionName(filePath);
16264
- }
16265
- function injectCreatedBy(content) {
16266
- if (content.includes("createdBy"))
16267
- return content;
16268
- const isGeneric = content.includes("genericExtension(");
16269
- const createdByValue = isGeneric ? ' createdBy: "CODE_GEN",' : ' createdBy: {\n author: "CODE_GEN",\n },';
16270
- return content.replace(/(\S)(\n)(}\))(;?\s*)$/, (_match, preChar, newline, closeBrace, tail) => {
16271
- const needsComma = preChar !== "," && preChar !== "{";
16272
- const separator = needsComma ? `${preChar},` : preChar;
16273
- return `${separator}${newline}${createdByValue}
16274
- ${closeBrace}${tail}`;
16275
- });
16276
- }
16277
- }
16278
- });
16279
-
16280
16605
  // dist/opencode-integration/task-tracker/derived-progress.js
16281
16606
  var require_derived_progress = __commonJS({
16282
16607
  "dist/opencode-integration/task-tracker/derived-progress.js"(exports2) {
@@ -16994,12 +17319,150 @@ var require_process_handlers = __commonJS({
16994
17319
  }
16995
17320
  });
16996
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
+
16997
17457
  // dist/opencode-integration/execution/executor.js
16998
17458
  var require_executor = __commonJS({
16999
17459
  "dist/opencode-integration/execution/executor.js"(exports2) {
17000
17460
  "use strict";
17001
17461
  Object.defineProperty(exports2, "__esModule", { value: true });
17462
+ exports2.reserveHostValidationRepairAttempt = reserveHostValidationRepairAttempt;
17463
+ exports2.updateRequiredPermissions = updateRequiredPermissions;
17002
17464
  exports2.classifyAttempt = classifyAttempt;
17465
+ exports2.applyPostRunValidation = applyPostRunValidation;
17003
17466
  exports2.executeOpenCode = executeOpenCode;
17004
17467
  exports2.resolveFinalRunCost = resolveFinalRunCost;
17005
17468
  var child_process_1 = require("child_process");
@@ -17016,11 +17479,16 @@ var require_executor = __commonJS({
17016
17479
  var process_manager_1 = require_process_manager();
17017
17480
  var process_handlers_1 = require_process_handlers();
17018
17481
  var logger_12 = require_logger();
17482
+ var host_validation_1 = require_host_validation();
17019
17483
  var MAX_RETRIES = 5;
17484
+ var MAX_HOST_VALIDATION_FAILURES = 2;
17020
17485
  var MAX_STALL_ATTEMPTS = 2;
17021
17486
  function failureReason(result) {
17022
17487
  if (result.stalled)
17023
17488
  return "stall";
17489
+ if (result.error instanceof host_validation_1.HostValidationError) {
17490
+ return "host validation failure";
17491
+ }
17024
17492
  if ((0, parser_1.hasSessionError)(result.stdout))
17025
17493
  return "session error";
17026
17494
  if (result.error instanceof ditto_codegen_types_12.ProcessExecutionError) {
@@ -17031,13 +17499,50 @@ var require_executor = __commonJS({
17031
17499
  }
17032
17500
  return null;
17033
17501
  }
17034
- 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) {
17035
17511
  const reason = failureReason(result);
17036
17512
  if (!reason)
17037
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
+ }
17038
17523
  return { retryable: stalls < MAX_STALL_ATTEMPTS, reason };
17039
17524
  }
17040
- 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) {
17041
17546
  let lastResult = null;
17042
17547
  let accumulatedUsage = (0, parser_1.createEmptyUsageStats)();
17043
17548
  const accumulatedSkills = [];
@@ -17045,26 +17550,35 @@ var require_executor = __commonJS({
17045
17550
  let currentPrompt = options.prompt;
17046
17551
  let lastFailureReason = null;
17047
17552
  let stalls = 0;
17553
+ let hostValidationFailures = 0;
17554
+ let requiredPermissions = [];
17555
+ let maxAttempts = MAX_RETRIES;
17048
17556
  const forceFresh = process.env.CODEGEN_FRESH_SESSION === "true";
17049
17557
  let continueSession = forceFresh ? false : options.continueSession ?? false;
17050
17558
  const env = (0, config_12.getOpenCodeEnv)(options.projectId, job_context_storage_12.jobContextStorage.getStore()?.kind);
17051
17559
  const statsBaseline = await (0, cost_tracker_1.fetchOpenCodeStats)(options.outputPath, env);
17052
17560
  const baselineCost = statsBaseline ? (0, cost_tracker_1.parseStatsTotalCost)(statsBaseline) : null;
17053
17561
  logger_12.logger.debug("[OpenCode] Stats baseline before run", { baselineCost });
17054
- for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
17562
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
17055
17563
  if (attempt > 1) {
17056
- const failureDetail = lastResult?.error?.message || lastResult?.stderr || "Process timed out";
17057
- 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) });
17058
17566
  const filesChanged = await (0, file_changes_1.collectGitFileChanges)(options.outputPath, options.gitBaseline);
17059
17567
  currentPrompt = (0, prompts_1.buildRecoveryPrompt)(options.prompt, filesChanged, failureDetail, lastFailureReason);
17060
17568
  continueSession = false;
17061
17569
  }
17062
- const result = await executeOpenCodeOnce({ ...options, prompt: currentPrompt, continueSession }, attempt, toolUsage);
17570
+ let result = await executeAttempt({ ...options, prompt: currentPrompt, continueSession }, attempt, maxAttempts, toolUsage);
17063
17571
  accumulatedUsage = (0, parser_1.mergeUsageStats)(accumulatedUsage, result.usage);
17064
17572
  accumulatedSkills.push(...result.skillsUsed);
17573
+ requiredPermissions = updateRequiredPermissions(requiredPermissions, result);
17574
+ result = await applyPostRunValidation(result, options.postRunValidation);
17065
17575
  if (result.stalled)
17066
17576
  stalls += 1;
17067
- 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);
17068
17582
  if (!retryable) {
17069
17583
  if (reason) {
17070
17584
  logger_12.logger.warn(`[OpenCode] Not retrying after ${reason}`, {
@@ -17076,6 +17590,7 @@ var require_executor = __commonJS({
17076
17590
  const finalResult2 = {
17077
17591
  ...result,
17078
17592
  agentMessage: (0, parser_1.parseAnswerText)(result.stdout),
17593
+ requiredPermissions,
17079
17594
  usage: accumulatedUsage,
17080
17595
  skillsUsed: accumulatedSkills,
17081
17596
  toolUsage: toolUsage.toSummary()
@@ -17087,17 +17602,18 @@ var require_executor = __commonJS({
17087
17602
  lastFailureReason = reason;
17088
17603
  logger_12.logger.warn(`[OpenCode] Attempt failed due to ${reason}, will retry`, {
17089
17604
  attempt,
17090
- maxRetries: MAX_RETRIES,
17605
+ maxRetries: maxAttempts,
17091
17606
  detail: (result.error?.message || result.stderr || "").slice(0, 500)
17092
17607
  });
17093
17608
  }
17094
17609
  logger_12.logger.warn("[OpenCode] All retry attempts exhausted", {
17095
- maxRetries: MAX_RETRIES
17610
+ maxRetries: maxAttempts
17096
17611
  });
17097
17612
  accumulatedUsage = await resolveFinalRunCost(accumulatedUsage, options, baselineCost);
17098
17613
  const finalResult = {
17099
17614
  ...lastResult,
17100
17615
  agentMessage: (0, parser_1.parseAnswerText)(lastResult.stdout),
17616
+ requiredPermissions,
17101
17617
  usage: accumulatedUsage,
17102
17618
  skillsUsed: Array.from(accumulatedSkills),
17103
17619
  toolUsage: toolUsage.toSummary()
@@ -17129,7 +17645,7 @@ var require_executor = __commonJS({
17129
17645
  const sessionArgs = continueSession ? ["--continue"] : [];
17130
17646
  return ["run", ...sessionArgs, "--format", "json", prompt];
17131
17647
  }
17132
- async function executeOpenCodeOnce(options, attempt, toolUsage) {
17648
+ async function executeOpenCodeOnce(options, attempt, maxAttempts, toolUsage) {
17133
17649
  const { prompt, outputPath, projectId, onStdout, onStderr, continueSession = false } = options;
17134
17650
  const startTime = Date.now();
17135
17651
  const taskTracker = new task_tracker_1.OpenCodeTaskTracker(outputPath, toolUsage);
@@ -17168,7 +17684,7 @@ var require_executor = __commonJS({
17168
17684
  const args = buildArgs(prompt, continueSession);
17169
17685
  logger_12.logger.info("[OpenCode] Executing opencode run", {
17170
17686
  attempt,
17171
- maxRetries: MAX_RETRIES,
17687
+ maxRetries: maxAttempts,
17172
17688
  workingDirectory: outputPath,
17173
17689
  continueSession,
17174
17690
  model: (0, model_knobs_1.getModel)(),
@@ -17176,6 +17692,9 @@ var require_executor = __commonJS({
17176
17692
  });
17177
17693
  logger_12.logger.debug("[OpenCode] Full prompt", { prompt });
17178
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";
17179
17698
  ctx.child = (0, child_process_1.spawn)("opencode", args, {
17180
17699
  cwd: outputPath,
17181
17700
  env,
@@ -17211,6 +17730,41 @@ var require_executor = __commonJS({
17211
17730
  }
17212
17731
  });
17213
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
+
17214
17768
  // dist/opencode-integration/execution/opencode-runner.js
17215
17769
  var require_opencode_runner = __commonJS({
17216
17770
  "dist/opencode-integration/execution/opencode-runner.js"(exports2) {
@@ -17223,6 +17777,7 @@ var require_opencode_runner = __commonJS({
17223
17777
  var prompts_1 = require_prompts();
17224
17778
  var executor_1 = require_executor();
17225
17779
  var parser_1 = require_parser();
17780
+ var session_validation_1 = require_session_validation();
17226
17781
  async function runOpenCodeInit(options) {
17227
17782
  const { blueprint, outputPath, projectId, chatHistory, gitBaseline, onStdout, onStderr } = options;
17228
17783
  const prompt = (0, prompts_1.buildInitPrompt)(blueprint, chatHistory);
@@ -17231,6 +17786,8 @@ var require_opencode_runner = __commonJS({
17231
17786
  outputPath,
17232
17787
  projectId,
17233
17788
  gitBaseline,
17789
+ prepareExtensionMetadata: true,
17790
+ postRunValidation: (stdout) => (0, session_validation_1.validateSessionOrFallback)(outputPath, stdout, gitBaseline),
17234
17791
  onStdout,
17235
17792
  onStderr
17236
17793
  });
@@ -17244,6 +17801,8 @@ var require_opencode_runner = __commonJS({
17244
17801
  projectId,
17245
17802
  continueSession: true,
17246
17803
  gitBaseline,
17804
+ prepareExtensionMetadata: true,
17805
+ postRunValidation: (stdout) => (0, session_validation_1.validateSessionOrFallback)(outputPath, stdout, gitBaseline),
17247
17806
  onStdout,
17248
17807
  onStderr
17249
17808
  });
@@ -17275,6 +17834,7 @@ var require_opencode_runner = __commonJS({
17275
17834
  outputPath,
17276
17835
  projectId,
17277
17836
  gitBaseline,
17837
+ postRunValidation: (stdout) => (0, session_validation_1.validateSessionOrFallback)(outputPath, stdout),
17278
17838
  onStdout,
17279
17839
  onStderr
17280
17840
  });
@@ -17661,39 +18221,6 @@ var require_codegen_flow_helpers = __commonJS({
17661
18221
  }
17662
18222
  });
17663
18223
 
17664
- // dist/extension-reporting/inject-created-by.js
17665
- var require_inject_created_by = __commonJS({
17666
- "dist/extension-reporting/inject-created-by.js"(exports2) {
17667
- "use strict";
17668
- Object.defineProperty(exports2, "__esModule", { value: true });
17669
- exports2.injectCreatedByIntoExtensionFiles = injectCreatedByIntoExtensionFiles;
17670
- var promises_1 = require("fs/promises");
17671
- var path_12 = require("path");
17672
- var logger_12 = require_logger();
17673
- var detect_1 = require_detect();
17674
- async function injectCreatedByIntoExtensionFiles(cwd, createdExtensions) {
17675
- for (const { path: filePath } of createdExtensions) {
17676
- const absolutePath = (0, path_12.join)(cwd, filePath);
17677
- try {
17678
- const original = await (0, promises_1.readFile)(absolutePath, "utf-8");
17679
- const injected = (0, detect_1.injectCreatedBy)(original);
17680
- if (injected !== original) {
17681
- await (0, promises_1.writeFile)(absolutePath, injected, "utf-8");
17682
- logger_12.logger.info("[OpenCode] Injected createdBy into extension file", {
17683
- filePath
17684
- });
17685
- }
17686
- } catch (error) {
17687
- logger_12.logger.error("[OpenCode] Failed to inject createdBy", {
17688
- filePath,
17689
- error: error instanceof Error ? error.message : String(error)
17690
- });
17691
- }
17692
- }
17693
- }
17694
- }
17695
- });
17696
-
17697
18224
  // ../../node_modules/@wix/bi-logger-dev-tools-data/dist/cjs/v2/index.js
17698
18225
  var require_v2 = __commonJS({
17699
18226
  "../../node_modules/@wix/bi-logger-dev-tools-data/dist/cjs/v2/index.js"(exports2) {
@@ -22776,7 +23303,6 @@ var require_opencode_init = __commonJS({
22776
23303
  var logger_12 = require_logger();
22777
23304
  var model_knobs_1 = require_model_knobs();
22778
23305
  var file_changes_1 = require_file_changes();
22779
- var inject_created_by_1 = require_inject_created_by();
22780
23306
  var job_payload_1 = require_job_payload2();
22781
23307
  var bi_events_1 = require_bi_events();
22782
23308
  var expensive_run_1 = require_expensive_run();
@@ -22842,7 +23368,6 @@ var require_opencode_init = __commonJS({
22842
23368
  filesChanged = files.length > 0;
22843
23369
  const agentOutput = (0, agent_io_1.readAgentOutput)(outputPath);
22844
23370
  const extensions = await (0, job_payload_1.buildExtensionsJobPayload)(outputPath, files);
22845
- await (0, inject_created_by_1.injectCreatedByIntoExtensionFiles)(outputPath, extensions.created);
22846
23371
  await (0, codegen_flow_helpers_12.updateJobPayload)(localJobContext, {
22847
23372
  requiredPermissions: result.requiredPermissions,
22848
23373
  agentMessage: result.agentMessage,
@@ -22997,7 +23522,6 @@ var require_opencode_iterate = __commonJS({
22997
23522
  var logger_12 = require_logger();
22998
23523
  var model_knobs_1 = require_model_knobs();
22999
23524
  var file_changes_1 = require_file_changes();
23000
- var inject_created_by_1 = require_inject_created_by();
23001
23525
  var job_payload_1 = require_job_payload2();
23002
23526
  var expensive_run_1 = require_expensive_run();
23003
23527
  var bi_events_1 = require_bi_events();
@@ -23051,7 +23575,6 @@ var require_opencode_iterate = __commonJS({
23051
23575
  filesChanged = files.length > 0;
23052
23576
  const agentOutput = (0, agent_io_1.readAgentOutput)(outputPath);
23053
23577
  const extensions = await (0, job_payload_1.buildExtensionsJobPayload)(outputPath, files);
23054
- await (0, inject_created_by_1.injectCreatedByIntoExtensionFiles)(outputPath, extensions.created);
23055
23578
  await (0, codegen_flow_helpers_12.updateJobPayload)(localJobContext, {
23056
23579
  requiredPermissions: result.requiredPermissions,
23057
23580
  agentMessage: result.agentMessage,
@@ -23185,6 +23708,42 @@ var require_opencode_ask_orchestrator = __commonJS({
23185
23708
  }
23186
23709
  });
23187
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
+
23188
23747
  // dist/flows/opencode-ask.js
23189
23748
  var require_opencode_ask = __commonJS({
23190
23749
  "dist/flows/opencode-ask.js"(exports2) {
@@ -24082,6 +24641,7 @@ var require_tool_policies3 = __commonJS({
24082
24641
  commandFragments,
24083
24642
  message
24084
24643
  }));
24644
+ const commandBlocks = emitKind("commandBlock", ({ commandFragments, message }) => ({ commandFragments, message }));
24085
24645
  const skillPrepends = emitKind("skillContent", ({ skillNames, message }) => ({
24086
24646
  skillNames,
24087
24647
  message
@@ -24091,6 +24651,7 @@ const BLOCK_READS = ${emitReads("block")};
24091
24651
  const PREPEND_READS = ${emitReads("prepend")};
24092
24652
  const GENERATE_POLICIES = ${generatePolicies};
24093
24653
  const COMMAND_PREPENDS = ${commandPrepends};
24654
+ const COMMAND_BLOCKS = ${commandBlocks};
24094
24655
  const SKILL_PREPENDS = ${skillPrepends};
24095
24656
  // Appended once after every prepend banner (see OVERRIDE_AUTHORITY_NOTE):
24096
24657
  // part of the override contract, so no policy can ship without it.
@@ -24131,6 +24692,14 @@ export const ToolPolicies = async () => ({
24131
24692
  )[0];
24132
24693
  if (blocked) throw new Error(blocked.message);
24133
24694
 
24695
+ if (input.tool === "${"bash"}" && typeof args.command === "string") {
24696
+ const command = args.command.replace(/\\s+/g, " ");
24697
+ const blockedCommand = COMMAND_BLOCKS.find((policy) =>
24698
+ policy.commandFragments.some((fragment) => command.includes(fragment)),
24699
+ );
24700
+ if (blockedCommand) throw new Error(blockedCommand.message);
24701
+ }
24702
+
24134
24703
  if (GENERATE_POLICIES.length === 0) return;
24135
24704
  if (input.tool === "${"wix-generate"}" && Array.isArray(args.extensions)) {
24136
24705
  for (const extension of args.extensions) {
@@ -24324,6 +24893,7 @@ var require_plugins3 = __commonJS({
24324
24893
  var generated_files_guard_1 = require_generated_files_guard();
24325
24894
  var subagent_tool_logger_1 = require_subagent_tool_logger();
24326
24895
  var tool_policies_1 = require_tool_policies3();
24896
+ var validation_state_1 = require_validation_state();
24327
24897
  var tool_policies_drift_1 = require_tool_policies_drift();
24328
24898
  Object.defineProperty(exports2, "validateToolPolicies", { enumerable: true, get: function() {
24329
24899
  return tool_policies_drift_1.validateToolPolicies;
@@ -24333,7 +24903,8 @@ var require_plugins3 = __commonJS({
24333
24903
  (0, docs_feedback_nudge_1.writeDocsFeedbackNudgePlugin)(),
24334
24904
  (0, generated_files_guard_1.writeGeneratedFilesGuardPlugin)(),
24335
24905
  (0, subagent_tool_logger_1.writeSubagentToolLoggerPlugin)(),
24336
- (0, tool_policies_1.writeToolPoliciesPlugin)(toolPolicies)
24906
+ (0, tool_policies_1.writeToolPoliciesPlugin)(toolPolicies),
24907
+ (0, validation_state_1.writeValidationStatePlugin)()
24337
24908
  ]);
24338
24909
  }
24339
24910
  }