@nathapp/nax 0.67.1 → 0.67.2
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 +48 -11
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -35108,6 +35108,24 @@ async function getChangedFiles(workdir, fromRef = "HEAD") {
|
|
|
35108
35108
|
return output.trim().split(`
|
|
35109
35109
|
`).filter(Boolean);
|
|
35110
35110
|
}
|
|
35111
|
+
async function getAddedLinesPerFile(workdir, fromRef = "HEAD") {
|
|
35112
|
+
const proc = _isolationDeps.spawn(["git", "diff", "--numstat", fromRef], {
|
|
35113
|
+
cwd: workdir,
|
|
35114
|
+
stdout: "pipe",
|
|
35115
|
+
stderr: "pipe"
|
|
35116
|
+
});
|
|
35117
|
+
const output = await Bun.readableStreamToText(proc.stdout);
|
|
35118
|
+
await proc.exited;
|
|
35119
|
+
const result = new Map;
|
|
35120
|
+
for (const line of output.trim().split(`
|
|
35121
|
+
`).filter(Boolean)) {
|
|
35122
|
+
const [addedStr, _deletedStr, path4] = line.split("\t");
|
|
35123
|
+
const added = Number.parseInt(addedStr ?? "", 10);
|
|
35124
|
+
if (path4 && Number.isFinite(added))
|
|
35125
|
+
result.set(path4, added);
|
|
35126
|
+
}
|
|
35127
|
+
return result;
|
|
35128
|
+
}
|
|
35111
35129
|
function matchesAllowedPath(filePath, allowedPaths) {
|
|
35112
35130
|
return allowedPaths.some((pattern) => {
|
|
35113
35131
|
const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\//g, "\\/");
|
|
@@ -35115,17 +35133,25 @@ function matchesAllowedPath(filePath, allowedPaths) {
|
|
|
35115
35133
|
return regex.test(filePath);
|
|
35116
35134
|
});
|
|
35117
35135
|
}
|
|
35118
|
-
async function verifyTestWriterIsolation(workdir, beforeRef, allowedPaths = ["src/index.ts", "src/**/index.ts"], testFilePatterns = DEFAULT_TEST_FILE_PATTERNS) {
|
|
35136
|
+
async function verifyTestWriterIsolation(workdir, beforeRef, allowedPaths = ["src/index.ts", "src/**/index.ts"], testFilePatterns = DEFAULT_TEST_FILE_PATTERNS, mode = "strict") {
|
|
35119
35137
|
const changed = await getChangedFiles(workdir, beforeRef);
|
|
35120
35138
|
const sourceFiles = changed.filter((f) => isSourceFile(f) && !isTestFileByPatterns(f, testFilePatterns));
|
|
35139
|
+
const addedLines = mode === "lite" && sourceFiles.length > 0 ? await getAddedLinesPerFile(workdir, beforeRef) : null;
|
|
35121
35140
|
const softViolations = [];
|
|
35122
35141
|
const violations = [];
|
|
35123
35142
|
for (const file3 of sourceFiles) {
|
|
35124
35143
|
if (matchesAllowedPath(file3, allowedPaths)) {
|
|
35125
35144
|
softViolations.push(file3);
|
|
35126
|
-
|
|
35127
|
-
|
|
35145
|
+
continue;
|
|
35146
|
+
}
|
|
35147
|
+
if (addedLines) {
|
|
35148
|
+
const added = addedLines.get(file3) ?? Number.POSITIVE_INFINITY;
|
|
35149
|
+
if (added <= LITE_STUB_ADDED_LINES_CEILING) {
|
|
35150
|
+
softViolations.push(file3);
|
|
35151
|
+
continue;
|
|
35152
|
+
}
|
|
35128
35153
|
}
|
|
35154
|
+
violations.push(file3);
|
|
35129
35155
|
}
|
|
35130
35156
|
return {
|
|
35131
35157
|
passed: violations.length === 0,
|
|
@@ -35151,7 +35177,7 @@ async function verifyImplementerIsolation(workdir, beforeRef, testFilePatterns =
|
|
|
35151
35177
|
description: "Implementer should not modify test files"
|
|
35152
35178
|
};
|
|
35153
35179
|
}
|
|
35154
|
-
var _isolationDeps, SRC_PATTERNS;
|
|
35180
|
+
var _isolationDeps, SRC_PATTERNS, LITE_STUB_ADDED_LINES_CEILING = 20;
|
|
35155
35181
|
var init_isolation = __esm(() => {
|
|
35156
35182
|
init_test_runners();
|
|
35157
35183
|
init_bun_deps();
|
|
@@ -35235,7 +35261,7 @@ var init_write_test = __esm(() => {
|
|
|
35235
35261
|
return parsed;
|
|
35236
35262
|
const allowedPaths = ctx.config.tdd?.testWriterAllowedPaths ?? ["src/index.ts", "src/**/index.ts"];
|
|
35237
35263
|
const testFilePatterns = typeof ctx.packageView.config.execution?.smartTestRunner === "object" && ctx.packageView.config.execution.smartTestRunner !== null ? ctx.packageView.config.execution.smartTestRunner.testFilePatterns : undefined;
|
|
35238
|
-
const isolation = await verifyTestWriterIsolation(ctx.packageView.packageDir, input.beforeRef, allowedPaths, testFilePatterns);
|
|
35264
|
+
const isolation = await verifyTestWriterIsolation(ctx.packageView.packageDir, input.beforeRef, allowedPaths, testFilePatterns, input.lite ? "lite" : "strict");
|
|
35239
35265
|
return { ...parsed, isolation };
|
|
35240
35266
|
}
|
|
35241
35267
|
};
|
|
@@ -54368,10 +54394,13 @@ class ExecutionPlan {
|
|
|
54368
54394
|
const phaseOutputs = {};
|
|
54369
54395
|
const startedAt = Date.now();
|
|
54370
54396
|
const logger = getSafeLogger();
|
|
54371
|
-
const
|
|
54397
|
+
const verifierPresent = this.state.verifier !== undefined;
|
|
54398
|
+
const rectificationExempt = this.state.rectification ? [
|
|
54372
54399
|
...this.state.fullSuiteGate ? [this.state.fullSuiteGate.slot.op.name] : [],
|
|
54373
54400
|
...this.state.verifier ? [this.state.verifier.slot.op.name] : []
|
|
54374
|
-
]
|
|
54401
|
+
] : [];
|
|
54402
|
+
const verifierExempt = verifierPresent && this.state.fullSuiteGate ? [this.state.fullSuiteGate.slot.op.name] : [];
|
|
54403
|
+
const shortCircuitExempt = new Set([...rectificationExempt, ...verifierExempt]);
|
|
54375
54404
|
for (const phase of collectOrderedPhases(this.state)) {
|
|
54376
54405
|
try {
|
|
54377
54406
|
await runPhase(this.ctx, phase.slot, phaseCosts, phaseOutputs, this.isThreeSession);
|
|
@@ -54599,7 +54628,8 @@ async function assemblePlanInputsFromCtx(ctx) {
|
|
|
54599
54628
|
story,
|
|
54600
54629
|
promptMarkdown: testWriterPrompt,
|
|
54601
54630
|
featureContextMarkdown: ctx.featureContextMarkdown,
|
|
54602
|
-
constitution: ctx.constitution?.content
|
|
54631
|
+
constitution: ctx.constitution?.content,
|
|
54632
|
+
lite: isLite
|
|
54603
54633
|
} : undefined;
|
|
54604
54634
|
const greenfieldGateInput = _isTdd && _isFreshRun && resolvedTestPatterns ? { story, workdir: ctx.workdir, resolvedTestPatterns } : undefined;
|
|
54605
54635
|
const implementerInput = {
|
|
@@ -54800,6 +54830,13 @@ function deriveTddFailureCategory(phaseOutputs) {
|
|
|
54800
54830
|
}
|
|
54801
54831
|
return "tests-failing";
|
|
54802
54832
|
}
|
|
54833
|
+
const verifierPassed = verifierOutput?.success === true;
|
|
54834
|
+
if (!verifierPassed) {
|
|
54835
|
+
const gateOutput = phaseOutputs[fullSuiteGateOp.name];
|
|
54836
|
+
if (gateOutput && (gateOutput.success === false || gateOutput.passed === false)) {
|
|
54837
|
+
return "tests-failing";
|
|
54838
|
+
}
|
|
54839
|
+
}
|
|
54803
54840
|
const implOutput = phaseOutputs[implementerOp.name];
|
|
54804
54841
|
if (implOutput?.success === false) {
|
|
54805
54842
|
return "session-failure";
|
|
@@ -59182,7 +59219,7 @@ var package_default;
|
|
|
59182
59219
|
var init_package = __esm(() => {
|
|
59183
59220
|
package_default = {
|
|
59184
59221
|
name: "@nathapp/nax",
|
|
59185
|
-
version: "0.67.
|
|
59222
|
+
version: "0.67.2",
|
|
59186
59223
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
59187
59224
|
type: "module",
|
|
59188
59225
|
bin: {
|
|
@@ -59277,8 +59314,8 @@ var init_version = __esm(() => {
|
|
|
59277
59314
|
NAX_VERSION = package_default.version;
|
|
59278
59315
|
NAX_COMMIT = (() => {
|
|
59279
59316
|
try {
|
|
59280
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
59281
|
-
return "
|
|
59317
|
+
if (/^[0-9a-f]{6,10}$/.test("d2b13ea6"))
|
|
59318
|
+
return "d2b13ea6";
|
|
59282
59319
|
} catch {}
|
|
59283
59320
|
try {
|
|
59284
59321
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|