@nathapp/nax 0.67.18 → 0.67.19
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/nax.js +87 -13
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -31242,7 +31242,7 @@ ${STEP2}${frameworkLine}
|
|
|
31242
31242
|
${STEP3_HEADER}
|
|
31243
31243
|
${STEP3_SHARED_RULES}
|
|
31244
31244
|
- **File output (REQUIRED)**: Write the acceptance test file DIRECTLY to the path shown below. Do NOT output the test code in your response. After writing the file, reply with a brief confirmation.
|
|
31245
|
-
- **Path anchor (CRITICAL)**: Write the test file to this exact path: \`${p.targetTestFilePath}\`.
|
|
31245
|
+
- **Path anchor (CRITICAL \u2014 do NOT deviate)**: Write the test file to this exact path: \`${p.targetTestFilePath}\`. This path is intentional and computed by the orchestrator \u2014 do not change it based on what you observe in the project. In particular: if you see a \`.nax/features/\` directory at the repo root, that is for stories scoped to the repo root. When a story belongs to a specific package (e.g. \`packages/core\`), its acceptance test lives inside that package's \`.nax/features/\` directory so the test runner can resolve the package's imports correctly. The package root is 3 levels above the test file (\`../../../\` relative to the test file).
|
|
31246
31246
|
- **Process cwd**: When spawning child processes to invoke a CLI or binary, set the working directory to the **package root** (\`join(import.meta.dir, "../../..")\`) as your default \u2014 unless your Step 2 exploration reveals the CLI uses a different working directory convention (e.g. reads config from \`~/.config/\`, or resolves paths relative to a flag value). Always check how the CLI resolves file paths before assuming.${implSection}`;
|
|
31247
31247
|
}
|
|
31248
31248
|
buildGeneratorFromSpecPrompt(p) {
|
|
@@ -33716,6 +33716,35 @@ function acFailureToFinding(acId, output) {
|
|
|
33716
33716
|
fixTarget: "source"
|
|
33717
33717
|
};
|
|
33718
33718
|
}
|
|
33719
|
+
function executionFailureToFinding(params) {
|
|
33720
|
+
const tail = tailLines(params.output, 40);
|
|
33721
|
+
const exitStr = params.exitCode !== undefined ? ` (exit ${params.exitCode})` : "";
|
|
33722
|
+
const message = `Test runner exited non-zero without structured failures${exitStr}. Command: \`${params.command}\`
|
|
33723
|
+
|
|
33724
|
+
--- runner output (last 40 lines) ---
|
|
33725
|
+
${tail}`;
|
|
33726
|
+
return {
|
|
33727
|
+
source: "test-runner",
|
|
33728
|
+
severity: "error",
|
|
33729
|
+
category: "execution-failed",
|
|
33730
|
+
message,
|
|
33731
|
+
fixTarget: "source",
|
|
33732
|
+
meta: {
|
|
33733
|
+
command: params.command,
|
|
33734
|
+
exitCode: params.exitCode,
|
|
33735
|
+
packageDir: params.packageDir,
|
|
33736
|
+
cwd: params.cwd
|
|
33737
|
+
}
|
|
33738
|
+
};
|
|
33739
|
+
}
|
|
33740
|
+
function tailLines(s, n) {
|
|
33741
|
+
if (!s)
|
|
33742
|
+
return "(no output)";
|
|
33743
|
+
const lines = s.split(`
|
|
33744
|
+
`);
|
|
33745
|
+
return lines.slice(Math.max(0, lines.length - n)).join(`
|
|
33746
|
+
`);
|
|
33747
|
+
}
|
|
33719
33748
|
function acSentinelToFinding(sentinel, _output) {
|
|
33720
33749
|
if (sentinel === "AC-HOOK") {
|
|
33721
33750
|
return {
|
|
@@ -37792,7 +37821,9 @@ async function runVerificationCore(options) {
|
|
|
37792
37821
|
success: options.acceptOnTimeout ?? false,
|
|
37793
37822
|
countsTowardEscalation: false,
|
|
37794
37823
|
error: execution.error,
|
|
37795
|
-
output: execution.output
|
|
37824
|
+
output: execution.output,
|
|
37825
|
+
exitCode: execution.exitCode,
|
|
37826
|
+
command: finalCommand
|
|
37796
37827
|
};
|
|
37797
37828
|
}
|
|
37798
37829
|
const exitCode = execution.exitCode ?? 1;
|
|
@@ -37806,7 +37837,9 @@ async function runVerificationCore(options) {
|
|
|
37806
37837
|
error: analysis.error,
|
|
37807
37838
|
output: execution.output,
|
|
37808
37839
|
passCount: analysis.passCount,
|
|
37809
|
-
failCount: analysis.failCount
|
|
37840
|
+
failCount: analysis.failCount,
|
|
37841
|
+
exitCode,
|
|
37842
|
+
command: finalCommand
|
|
37810
37843
|
};
|
|
37811
37844
|
}
|
|
37812
37845
|
return {
|
|
@@ -37815,10 +37848,19 @@ async function runVerificationCore(options) {
|
|
|
37815
37848
|
countsTowardEscalation: true,
|
|
37816
37849
|
output: execution.output,
|
|
37817
37850
|
passCount: analysis.passCount,
|
|
37818
|
-
failCount: analysis.failCount
|
|
37851
|
+
failCount: analysis.failCount,
|
|
37852
|
+
exitCode,
|
|
37853
|
+
command: finalCommand
|
|
37819
37854
|
};
|
|
37820
37855
|
}
|
|
37821
|
-
return {
|
|
37856
|
+
return {
|
|
37857
|
+
status: "SUCCESS",
|
|
37858
|
+
success: true,
|
|
37859
|
+
countsTowardEscalation: true,
|
|
37860
|
+
output: execution.output,
|
|
37861
|
+
exitCode,
|
|
37862
|
+
command: finalCommand
|
|
37863
|
+
};
|
|
37822
37864
|
}
|
|
37823
37865
|
async function fullSuite(options) {
|
|
37824
37866
|
return runVerificationCore(options);
|
|
@@ -37895,7 +37937,9 @@ var init_full_suite_gate = __esm(() => {
|
|
|
37895
37937
|
failed: parsedSummary.failed ?? 0,
|
|
37896
37938
|
output: result.output ?? "",
|
|
37897
37939
|
parsedSummary,
|
|
37898
|
-
timedOut: result.status === "TIMEOUT"
|
|
37940
|
+
timedOut: result.status === "TIMEOUT",
|
|
37941
|
+
exitCode: result.exitCode,
|
|
37942
|
+
command: result.command ?? gateCtx.testCmd
|
|
37899
37943
|
};
|
|
37900
37944
|
}
|
|
37901
37945
|
};
|
|
@@ -37922,6 +37966,13 @@ var init_full_suite_gate = __esm(() => {
|
|
|
37922
37966
|
};
|
|
37923
37967
|
}
|
|
37924
37968
|
const gateCtx = await deps.resolveGateContext(input, ctx);
|
|
37969
|
+
logger.info("verify[regression]", "Running full-suite gate", {
|
|
37970
|
+
storyId: input.story.id,
|
|
37971
|
+
packageDir: input.story.workdir,
|
|
37972
|
+
cwd: input.workdir,
|
|
37973
|
+
command: gateCtx.testCmd,
|
|
37974
|
+
timeoutSeconds: gateCtx.fullSuiteTimeout
|
|
37975
|
+
});
|
|
37925
37976
|
const testResult = await deps.runTests(input, gateCtx);
|
|
37926
37977
|
if (testResult.passed) {
|
|
37927
37978
|
return { success: true, passed: true, status: "passed", estimatedCostUsd: 0, attempts: 0, findings: [] };
|
|
@@ -37955,13 +38006,27 @@ var init_full_suite_gate = __esm(() => {
|
|
|
37955
38006
|
}
|
|
37956
38007
|
const findings = testSummaryToFindings(testResult.parsedSummary);
|
|
37957
38008
|
if (findings.length === 0) {
|
|
38009
|
+
const cmd = testResult.command ?? gateCtx.testCmd;
|
|
38010
|
+
const synth = executionFailureToFinding({
|
|
38011
|
+
command: cmd,
|
|
38012
|
+
exitCode: testResult.exitCode,
|
|
38013
|
+
output: testResult.output,
|
|
38014
|
+
packageDir: input.story.workdir,
|
|
38015
|
+
cwd: input.workdir
|
|
38016
|
+
});
|
|
38017
|
+
logger.warn("verify[regression]", "Full-suite gate execution-failed \u2014 emitting synth finding", {
|
|
38018
|
+
storyId: input.story.id,
|
|
38019
|
+
command: cmd,
|
|
38020
|
+
exitCode: testResult.exitCode,
|
|
38021
|
+
packageDir: input.story.workdir
|
|
38022
|
+
});
|
|
37958
38023
|
return {
|
|
37959
38024
|
success: false,
|
|
37960
38025
|
passed: false,
|
|
37961
38026
|
status: "execution-failed",
|
|
37962
38027
|
estimatedCostUsd: 0,
|
|
37963
38028
|
attempts: 0,
|
|
37964
|
-
findings: []
|
|
38029
|
+
findings: [synth]
|
|
37965
38030
|
};
|
|
37966
38031
|
}
|
|
37967
38032
|
return { success: false, passed: false, status: "failed", estimatedCostUsd: 0, attempts: 0, findings };
|
|
@@ -37973,7 +38038,7 @@ var init_full_suite_gate = __esm(() => {
|
|
|
37973
38038
|
function makeFullSuiteRectifyStrategy(story, config2) {
|
|
37974
38039
|
return {
|
|
37975
38040
|
name: "full-suite-rectify",
|
|
37976
|
-
appliesTo: (finding) => finding.source === "test-runner" && finding.category === "failed-test",
|
|
38041
|
+
appliesTo: (finding) => finding.source === "test-runner" && (finding.category === "failed-test" || finding.category === "execution-failed"),
|
|
37977
38042
|
fixOp: implementerOp,
|
|
37978
38043
|
buildInput: (findings) => ({
|
|
37979
38044
|
story,
|
|
@@ -38665,6 +38730,15 @@ var init_verify_scoped = __esm(() => {
|
|
|
38665
38730
|
command: selection.effectiveCommand
|
|
38666
38731
|
});
|
|
38667
38732
|
}
|
|
38733
|
+
const scopedTimeout = ctxConfig.execution?.regressionGate?.timeoutSeconds ?? 600;
|
|
38734
|
+
logger.info("verify[scoped]", "Running scoped tests", {
|
|
38735
|
+
storyId: input.storyId,
|
|
38736
|
+
packageDir: input.packageDir,
|
|
38737
|
+
cwd: input.workdir,
|
|
38738
|
+
command: selection.effectiveCommand,
|
|
38739
|
+
timeoutSeconds: scopedTimeout,
|
|
38740
|
+
isFullSuite: selection.isFullSuite
|
|
38741
|
+
});
|
|
38668
38742
|
const start = Date.now();
|
|
38669
38743
|
const result = await deps.regression({
|
|
38670
38744
|
workdir: input.workdir,
|
|
@@ -51491,9 +51565,9 @@ var init_acceptance2 = __esm(() => {
|
|
|
51491
51565
|
function logTestOutput(logger, stage, output, opts = {}) {
|
|
51492
51566
|
if (!logger || !output)
|
|
51493
51567
|
return;
|
|
51494
|
-
const
|
|
51568
|
+
const tailLines2 = opts.tailLines ?? 20;
|
|
51495
51569
|
const lines = output.split(`
|
|
51496
|
-
`).slice(-
|
|
51570
|
+
`).slice(-tailLines2).join(`
|
|
51497
51571
|
`);
|
|
51498
51572
|
logger.debug(stage, "Test output (tail)", {
|
|
51499
51573
|
...opts.storyId !== undefined && { storyId: opts.storyId },
|
|
@@ -57943,7 +58017,7 @@ var package_default;
|
|
|
57943
58017
|
var init_package = __esm(() => {
|
|
57944
58018
|
package_default = {
|
|
57945
58019
|
name: "@nathapp/nax",
|
|
57946
|
-
version: "0.67.
|
|
58020
|
+
version: "0.67.19",
|
|
57947
58021
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
57948
58022
|
type: "module",
|
|
57949
58023
|
bin: {
|
|
@@ -58038,8 +58112,8 @@ var init_version = __esm(() => {
|
|
|
58038
58112
|
NAX_VERSION = package_default.version;
|
|
58039
58113
|
NAX_COMMIT = (() => {
|
|
58040
58114
|
try {
|
|
58041
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
58042
|
-
return "
|
|
58115
|
+
if (/^[0-9a-f]{6,10}$/.test("e80ba4d6"))
|
|
58116
|
+
return "e80ba4d6";
|
|
58043
58117
|
} catch {}
|
|
58044
58118
|
try {
|
|
58045
58119
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|