@nathapp/nax 0.67.8 → 0.67.9
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 +120 -21
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -30381,18 +30381,19 @@ Schema: {"passed": boolean, "findings": [{"severity": string, "category": string
|
|
|
30381
30381
|
const line = opts.finding.verifiedBy?.line ?? opts.finding.line;
|
|
30382
30382
|
return `Your previous verifiedBy.observed value did not match the referenced file on disk.
|
|
30383
30383
|
|
|
30384
|
+
You MUST use your file-reading tool to open ${file3} and copy the actual bytes around line ${line}. Do NOT quote from memory or from the prior conversation \u2014 the previous quote was wrong precisely because it was not read from disk. If you reply without a file-read tool call, the quote will be rejected.
|
|
30385
|
+
|
|
30384
30386
|
Return ONLY this JSON object:
|
|
30385
30387
|
{"file":"${file3}","line":${line},"observed":"exact 1-3 line quote"}
|
|
30386
30388
|
|
|
30387
30389
|
Finding issue: ${opts.finding.issue}
|
|
30388
30390
|
Referenced file: ${file3}
|
|
30389
30391
|
Referenced line: ${line}
|
|
30390
|
-
Previous observed: ${opts.previousObserved}
|
|
30391
30392
|
|
|
30392
30393
|
Rules:
|
|
30393
|
-
-
|
|
30394
|
-
- observed must be a 1-3 line excerpt that proves the claim.
|
|
30395
|
-
- If you cannot
|
|
30394
|
+
- Read ${file3} with your file tool first. Then copy observed verbatim from the read result.
|
|
30395
|
+
- observed must be a 1-3 line excerpt that proves the claim, taken from at or near line ${line}.
|
|
30396
|
+
- If after reading the file you cannot find anything that proves the claim, set observed to "".
|
|
30396
30397
|
- Do not return a full review. Do not include markdown fences or explanation.`;
|
|
30397
30398
|
}
|
|
30398
30399
|
}
|
|
@@ -31851,7 +31852,20 @@ async function checkFindingEvidence(opts) {
|
|
|
31851
31852
|
const contents = await readSafeFile(opts.workdir, file3);
|
|
31852
31853
|
if (contents === null)
|
|
31853
31854
|
return { status: "unreadable", file: file3, line, observed };
|
|
31854
|
-
return
|
|
31855
|
+
return matchesEvidence(contents, observed, line) ? { status: "matched", file: file3, line, observed } : { status: "unmatched", file: file3, line, observed };
|
|
31856
|
+
}
|
|
31857
|
+
function matchesEvidence(contents, observed, line) {
|
|
31858
|
+
if (!line || line <= 0) {
|
|
31859
|
+
return normalizedIncludes(contents, observed);
|
|
31860
|
+
}
|
|
31861
|
+
const lines = contents.split(`
|
|
31862
|
+
`);
|
|
31863
|
+
const cited = Math.min(Math.max(0, line - 1), lines.length - 1);
|
|
31864
|
+
const start = Math.max(0, cited - EVIDENCE_LINE_WINDOW);
|
|
31865
|
+
const end = Math.min(lines.length, cited + EVIDENCE_LINE_WINDOW + 1);
|
|
31866
|
+
const windowText = lines.slice(start, end).join(`
|
|
31867
|
+
`);
|
|
31868
|
+
return normalizedIncludes(windowText, observed);
|
|
31855
31869
|
}
|
|
31856
31870
|
function downgradeUnsubstantiatedFinding(opts) {
|
|
31857
31871
|
_evidenceDeps.getLogger()?.warn("review", "Downgraded unsubstantiated review finding", {
|
|
@@ -31899,7 +31913,7 @@ function stripWrappingQuotes(text) {
|
|
|
31899
31913
|
function isMatchingWrapper(first, last) {
|
|
31900
31914
|
return first === "`" && last === "`" || first === `"` && last === `"` || first === "'" && last === "'";
|
|
31901
31915
|
}
|
|
31902
|
-
var OBSERVED_PREVIEW_CHARS = 160, ISSUE_PREVIEW_CHARS = 200, SEMANTIC_FINDING_DOWNGRADED_EVENT = "review.semantic.finding.downgraded", ADVERSARIAL_FINDING_DOWNGRADED_EVENT = "review.adversarial.finding.downgraded", _evidenceDeps;
|
|
31916
|
+
var OBSERVED_PREVIEW_CHARS = 160, ISSUE_PREVIEW_CHARS = 200, EVIDENCE_LINE_WINDOW = 10, SEMANTIC_FINDING_DOWNGRADED_EVENT = "review.semantic.finding.downgraded", ADVERSARIAL_FINDING_DOWNGRADED_EVENT = "review.adversarial.finding.downgraded", _evidenceDeps;
|
|
31903
31917
|
var init_semantic_evidence = __esm(() => {
|
|
31904
31918
|
init_logger2();
|
|
31905
31919
|
init_path_security2();
|
|
@@ -35057,7 +35071,7 @@ async function requoteBlockingFindings(findings, ctx) {
|
|
|
35057
35071
|
if (used >= maxRequotes)
|
|
35058
35072
|
break;
|
|
35059
35073
|
used += 1;
|
|
35060
|
-
const retry = await ctx.send(ReviewPromptBuilder.requoteVerbatim({ finding
|
|
35074
|
+
const retry = await ctx.send(ReviewPromptBuilder.requoteVerbatim({ finding }));
|
|
35061
35075
|
extraCostUsd += retry.estimatedCostUsd ?? 0;
|
|
35062
35076
|
const requote = parseRequoteResponse(retry.output);
|
|
35063
35077
|
if (!requote) {
|
|
@@ -37334,14 +37348,45 @@ var init_full_suite_rectify = __esm(() => {
|
|
|
37334
37348
|
init_implement();
|
|
37335
37349
|
});
|
|
37336
37350
|
|
|
37351
|
+
// src/operations/_finding-to-check.ts
|
|
37352
|
+
function findingsToFailedChecks(findings) {
|
|
37353
|
+
const grouped = new Map;
|
|
37354
|
+
for (const finding of findings) {
|
|
37355
|
+
const check2 = SOURCE_TO_CHECK[finding.source];
|
|
37356
|
+
if (!check2)
|
|
37357
|
+
continue;
|
|
37358
|
+
const bucket = grouped.get(check2) ?? [];
|
|
37359
|
+
bucket.push(finding);
|
|
37360
|
+
grouped.set(check2, bucket);
|
|
37361
|
+
}
|
|
37362
|
+
return [...grouped.entries()].map(([check2, grpFindings]) => ({
|
|
37363
|
+
check: check2,
|
|
37364
|
+
success: false,
|
|
37365
|
+
command: "",
|
|
37366
|
+
exitCode: 1,
|
|
37367
|
+
output: "",
|
|
37368
|
+
durationMs: 0,
|
|
37369
|
+
findings: grpFindings
|
|
37370
|
+
}));
|
|
37371
|
+
}
|
|
37372
|
+
var SOURCE_TO_CHECK;
|
|
37373
|
+
var init__finding_to_check = __esm(() => {
|
|
37374
|
+
SOURCE_TO_CHECK = {
|
|
37375
|
+
"semantic-review": "semantic",
|
|
37376
|
+
"adversarial-review": "adversarial",
|
|
37377
|
+
lint: "lint",
|
|
37378
|
+
typecheck: "typecheck"
|
|
37379
|
+
};
|
|
37380
|
+
});
|
|
37381
|
+
|
|
37337
37382
|
// src/operations/autofix-implementer-strategy.ts
|
|
37338
37383
|
function makeAutofixImplementerStrategy(story) {
|
|
37339
37384
|
return {
|
|
37340
37385
|
name: "autofix-implementer",
|
|
37341
37386
|
appliesTo: (f) => f.fixTarget === "source" && IMPLEMENTER_SOURCES.has(f.source),
|
|
37342
37387
|
fixOp: implementerRectifyOp,
|
|
37343
|
-
buildInput: (
|
|
37344
|
-
failedChecks:
|
|
37388
|
+
buildInput: (findings, _prior, _cycleCtx) => ({
|
|
37389
|
+
failedChecks: findingsToFailedChecks(findings),
|
|
37345
37390
|
story
|
|
37346
37391
|
}),
|
|
37347
37392
|
extractApplied: (output) => ({
|
|
@@ -37354,6 +37399,7 @@ function makeAutofixImplementerStrategy(story) {
|
|
|
37354
37399
|
}
|
|
37355
37400
|
var IMPLEMENTER_SOURCES;
|
|
37356
37401
|
var init_autofix_implementer_strategy = __esm(() => {
|
|
37402
|
+
init__finding_to_check();
|
|
37357
37403
|
init_autofix_implementer();
|
|
37358
37404
|
IMPLEMENTER_SOURCES = new Set(["lint", "typecheck", "semantic-review"]);
|
|
37359
37405
|
});
|
|
@@ -37364,8 +37410,8 @@ function makeAutofixTestWriterStrategy(story, config2) {
|
|
|
37364
37410
|
name: "autofix-test-writer",
|
|
37365
37411
|
appliesTo: (f) => f.fixTarget === "test" || f.source === "adversarial-review",
|
|
37366
37412
|
fixOp: testWriterRectifyOp,
|
|
37367
|
-
buildInput: (
|
|
37368
|
-
failedChecks:
|
|
37413
|
+
buildInput: (findings, _prior, _cycleCtx) => ({
|
|
37414
|
+
failedChecks: findingsToFailedChecks(findings),
|
|
37369
37415
|
story,
|
|
37370
37416
|
blockingThreshold: config2.review?.blockingThreshold
|
|
37371
37417
|
}),
|
|
@@ -37374,6 +37420,7 @@ function makeAutofixTestWriterStrategy(story, config2) {
|
|
|
37374
37420
|
};
|
|
37375
37421
|
}
|
|
37376
37422
|
var init_autofix_test_writer_strategy = __esm(() => {
|
|
37423
|
+
init__finding_to_check();
|
|
37377
37424
|
init_autofix_test_writer();
|
|
37378
37425
|
});
|
|
37379
37426
|
|
|
@@ -37857,6 +37904,7 @@ var init_operations = __esm(() => {
|
|
|
37857
37904
|
init_full_suite_rectify();
|
|
37858
37905
|
init_autofix_implementer_strategy();
|
|
37859
37906
|
init_autofix_test_writer_strategy();
|
|
37907
|
+
init__finding_to_check();
|
|
37860
37908
|
init_mechanical_lintfix_strategy();
|
|
37861
37909
|
init_mechanical_formatfix_strategy();
|
|
37862
37910
|
init_lint_check();
|
|
@@ -38062,7 +38110,10 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
|
|
|
38062
38110
|
if (allExhausted) {
|
|
38063
38111
|
let liteFindingsAfter;
|
|
38064
38112
|
try {
|
|
38065
|
-
liteFindingsAfter = await cycle.validate(ctx, {
|
|
38113
|
+
liteFindingsAfter = await cycle.validate(ctx, {
|
|
38114
|
+
mode: "lite",
|
|
38115
|
+
strategiesRun: group.map((s) => s.name)
|
|
38116
|
+
});
|
|
38066
38117
|
} catch (err) {
|
|
38067
38118
|
const finishedAt3 = now();
|
|
38068
38119
|
cycle.iterations.push({
|
|
@@ -38134,7 +38185,7 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
|
|
|
38134
38185
|
let validatorAttempt = 0;
|
|
38135
38186
|
for (;; ) {
|
|
38136
38187
|
try {
|
|
38137
|
-
findingsAfter = await cycle.validate(ctx, { mode: "full" });
|
|
38188
|
+
findingsAfter = await cycle.validate(ctx, { mode: "full", strategiesRun: group.map((s) => s.name) });
|
|
38138
38189
|
break;
|
|
38139
38190
|
} catch (err) {
|
|
38140
38191
|
if (validatorAttempt >= cycle.config.validatorRetries) {
|
|
@@ -51975,9 +52026,19 @@ function extractPhaseFindings(output) {
|
|
|
51975
52026
|
const success2 = "success" in record2 ? record2.success === true : ("passed" in record2) ? record2.passed === true : findings.length === 0;
|
|
51976
52027
|
return success2 ? [] : findings;
|
|
51977
52028
|
}
|
|
51978
|
-
function
|
|
52029
|
+
function shouldSkipPhaseForRectification(phase, state, phaseOutputs) {
|
|
52030
|
+
if (phase.kind !== "full-suite-gate")
|
|
52031
|
+
return false;
|
|
52032
|
+
const verifierName = state.verifier?.slot.op.name;
|
|
52033
|
+
if (!verifierName)
|
|
52034
|
+
return false;
|
|
52035
|
+
return phaseExplicitlyPassed(phaseOutputs[verifierName]);
|
|
52036
|
+
}
|
|
52037
|
+
function gatherRectificationFindings(phaseOutputs, phases, state) {
|
|
51979
52038
|
const findings = [];
|
|
51980
52039
|
for (const phase of phases) {
|
|
52040
|
+
if (shouldSkipPhaseForRectification(phase, state, phaseOutputs))
|
|
52041
|
+
continue;
|
|
51981
52042
|
findings.push(...extractPhaseFindings(phaseOutputs[phase.slot.op.name]));
|
|
51982
52043
|
}
|
|
51983
52044
|
return findings;
|
|
@@ -51993,6 +52054,21 @@ function collectRectificationPhases(state) {
|
|
|
51993
52054
|
state.adversarialReview
|
|
51994
52055
|
].filter((phase) => phase !== undefined);
|
|
51995
52056
|
}
|
|
52057
|
+
function phasesToRevalidate(strategiesRun, allPhases) {
|
|
52058
|
+
const sourceFiltered = allPhases.filter((p) => p.kind !== "verifier");
|
|
52059
|
+
if (!strategiesRun || strategiesRun.length === 0)
|
|
52060
|
+
return sourceFiltered;
|
|
52061
|
+
const unknown2 = strategiesRun.some((name) => STRATEGY_TO_REVALIDATION_PHASES[name] === undefined);
|
|
52062
|
+
if (unknown2)
|
|
52063
|
+
return sourceFiltered;
|
|
52064
|
+
const needed = new Set;
|
|
52065
|
+
for (const name of strategiesRun) {
|
|
52066
|
+
for (const kind of STRATEGY_TO_REVALIDATION_PHASES[name] ?? []) {
|
|
52067
|
+
needed.add(kind);
|
|
52068
|
+
}
|
|
52069
|
+
}
|
|
52070
|
+
return sourceFiltered.filter((p) => needed.has(p.kind));
|
|
52071
|
+
}
|
|
51996
52072
|
function toReviewDecisionPayload(opName, output) {
|
|
51997
52073
|
if (output === null || output === undefined || typeof output !== "object")
|
|
51998
52074
|
return null;
|
|
@@ -52148,7 +52224,7 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs) {
|
|
|
52148
52224
|
if (ctx.runtime.signal?.aborted) {
|
|
52149
52225
|
return {};
|
|
52150
52226
|
}
|
|
52151
|
-
const initialFindings = gatherRectificationFindings(phaseOutputs, validationPhases);
|
|
52227
|
+
const initialFindings = gatherRectificationFindings(phaseOutputs, validationPhases, state);
|
|
52152
52228
|
if (initialFindings.length === 0) {
|
|
52153
52229
|
return {};
|
|
52154
52230
|
}
|
|
@@ -52168,13 +52244,22 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs) {
|
|
|
52168
52244
|
validate: async (_validateCtx, opts) => {
|
|
52169
52245
|
if (ctx.runtime.signal?.aborted)
|
|
52170
52246
|
return [];
|
|
52171
|
-
const lite = opts?.mode === "lite";
|
|
52247
|
+
const lite = (opts?.mode ?? "full") === "lite";
|
|
52248
|
+
const phases = phasesToRevalidate(opts?.strategiesRun, validationPhases);
|
|
52249
|
+
getSafeLogger()?.debug("story-orchestrator", "rectification validate scope", {
|
|
52250
|
+
storyId: ctx.storyId,
|
|
52251
|
+
mode: opts?.mode ?? "full",
|
|
52252
|
+
strategiesRun: opts?.strategiesRun,
|
|
52253
|
+
phasesSelected: phases.map((p) => p.kind)
|
|
52254
|
+
});
|
|
52172
52255
|
const findings = [];
|
|
52173
|
-
for (const phase of
|
|
52256
|
+
for (const phase of phases) {
|
|
52174
52257
|
if (lite && phase.kind === "full-suite-gate") {
|
|
52175
52258
|
continue;
|
|
52176
52259
|
}
|
|
52177
52260
|
await runPhase(ctx, phase.slot, phaseCosts, phaseOutputs);
|
|
52261
|
+
if (shouldSkipPhaseForRectification(phase, state, phaseOutputs))
|
|
52262
|
+
continue;
|
|
52178
52263
|
findings.push(...extractPhaseFindings(phaseOutputs[phase.slot.op.name]));
|
|
52179
52264
|
}
|
|
52180
52265
|
return findings;
|
|
@@ -52321,7 +52406,7 @@ class StoryOrchestratorBuilder {
|
|
|
52321
52406
|
return new ExecutionPlan(ctx, { ...this.state }, opts.isThreeSession ?? false);
|
|
52322
52407
|
}
|
|
52323
52408
|
}
|
|
52324
|
-
var _storyOrchestratorDeps, TDD_OP_NAMES, CANONICAL_ORDER, PHASE_KIND_TO_STATE_KEY;
|
|
52409
|
+
var _storyOrchestratorDeps, TDD_OP_NAMES, CANONICAL_ORDER, PHASE_KIND_TO_STATE_KEY, STRATEGY_TO_REVALIDATION_PHASES;
|
|
52325
52410
|
var init_story_orchestrator = __esm(() => {
|
|
52326
52411
|
init_errors();
|
|
52327
52412
|
init_findings();
|
|
@@ -52359,6 +52444,20 @@ var init_story_orchestrator = __esm(() => {
|
|
|
52359
52444
|
"semantic-review": "semanticReview",
|
|
52360
52445
|
"adversarial-review": "adversarialReview"
|
|
52361
52446
|
};
|
|
52447
|
+
STRATEGY_TO_REVALIDATION_PHASES = {
|
|
52448
|
+
"mechanical-lintfix": ["lint-check"],
|
|
52449
|
+
"mechanical-formatfix": ["lint-check"],
|
|
52450
|
+
"autofix-implementer": [
|
|
52451
|
+
"lint-check",
|
|
52452
|
+
"typecheck-check",
|
|
52453
|
+
"full-suite-gate",
|
|
52454
|
+
"verify-scoped",
|
|
52455
|
+
"semantic-review",
|
|
52456
|
+
"adversarial-review"
|
|
52457
|
+
],
|
|
52458
|
+
"autofix-test-writer": ["lint-check", "typecheck-check", "full-suite-gate", "verify-scoped", "adversarial-review"],
|
|
52459
|
+
"full-suite-rectify": ["lint-check", "typecheck-check", "full-suite-gate", "verify-scoped", "semantic-review"]
|
|
52460
|
+
};
|
|
52362
52461
|
});
|
|
52363
52462
|
|
|
52364
52463
|
// src/execution/build-plan-for-strategy.ts
|
|
@@ -56844,7 +56943,7 @@ var package_default;
|
|
|
56844
56943
|
var init_package = __esm(() => {
|
|
56845
56944
|
package_default = {
|
|
56846
56945
|
name: "@nathapp/nax",
|
|
56847
|
-
version: "0.67.
|
|
56946
|
+
version: "0.67.9",
|
|
56848
56947
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
56849
56948
|
type: "module",
|
|
56850
56949
|
bin: {
|
|
@@ -56939,8 +57038,8 @@ var init_version = __esm(() => {
|
|
|
56939
57038
|
NAX_VERSION = package_default.version;
|
|
56940
57039
|
NAX_COMMIT = (() => {
|
|
56941
57040
|
try {
|
|
56942
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
56943
|
-
return "
|
|
57041
|
+
if (/^[0-9a-f]{6,10}$/.test("ab2db4bb"))
|
|
57042
|
+
return "ab2db4bb";
|
|
56944
57043
|
} catch {}
|
|
56945
57044
|
try {
|
|
56946
57045
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|