@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/opencode-tools/validate.ts +49 -2
- package/dist/out.js +748 -177
- package/package.json +2 -2
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
|
|
11059
|
-
..."stderr" in error
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
15789
|
-
|
|
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
|
|
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
|
|
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 <=
|
|
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}/${
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
}
|