@nathapp/nax 0.67.4 → 0.67.6
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 +86 -4
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -51902,6 +51902,82 @@ function collectRectificationPhases(state) {
|
|
|
51902
51902
|
state.adversarialReview
|
|
51903
51903
|
].filter((phase) => phase !== undefined);
|
|
51904
51904
|
}
|
|
51905
|
+
function toReviewDecisionPayload(opName, output) {
|
|
51906
|
+
if (output === null || output === undefined || typeof output !== "object")
|
|
51907
|
+
return null;
|
|
51908
|
+
const record2 = output;
|
|
51909
|
+
const reviewer = opName === "semantic-review" ? "semantic" : opName === "adversarial-review" ? "adversarial" : null;
|
|
51910
|
+
if (!reviewer)
|
|
51911
|
+
return null;
|
|
51912
|
+
if (record2.failOpen === true) {
|
|
51913
|
+
return { reviewer, parsed: false, passed: true, failOpen: true, result: null };
|
|
51914
|
+
}
|
|
51915
|
+
if (record2.looksLikeFail === true) {
|
|
51916
|
+
return { reviewer, parsed: false, passed: false, looksLikeFail: true, result: null };
|
|
51917
|
+
}
|
|
51918
|
+
if (typeof record2.passed !== "boolean" || !Array.isArray(record2.findings)) {
|
|
51919
|
+
return null;
|
|
51920
|
+
}
|
|
51921
|
+
return {
|
|
51922
|
+
reviewer,
|
|
51923
|
+
parsed: true,
|
|
51924
|
+
passed: record2.passed,
|
|
51925
|
+
result: { passed: record2.passed, findings: record2.findings }
|
|
51926
|
+
};
|
|
51927
|
+
}
|
|
51928
|
+
function emitReviewDecision(ctx, opName, output) {
|
|
51929
|
+
const payload = toReviewDecisionPayload(opName, output);
|
|
51930
|
+
if (!payload)
|
|
51931
|
+
return;
|
|
51932
|
+
ctx.runtime.dispatchEvents.emitReviewDecision({
|
|
51933
|
+
kind: "review-decision",
|
|
51934
|
+
runId: ctx.runtime.runId,
|
|
51935
|
+
reviewer: payload.reviewer,
|
|
51936
|
+
workdir: ctx.packageDir,
|
|
51937
|
+
projectDir: ctx.runtime.projectDir,
|
|
51938
|
+
outputDir: ctx.runtime.outputDir,
|
|
51939
|
+
storyId: ctx.storyId,
|
|
51940
|
+
featureName: ctx.featureName,
|
|
51941
|
+
timestamp: Date.now(),
|
|
51942
|
+
parsed: payload.parsed,
|
|
51943
|
+
looksLikeFail: payload.parsed ? undefined : payload.looksLikeFail,
|
|
51944
|
+
failOpen: payload.parsed ? false : payload.failOpen,
|
|
51945
|
+
passed: payload.passed,
|
|
51946
|
+
result: payload.result
|
|
51947
|
+
});
|
|
51948
|
+
}
|
|
51949
|
+
function logUnifiedReviewPhaseStart(storyId, opName) {
|
|
51950
|
+
const logger = getSafeLogger();
|
|
51951
|
+
if (opName === "semantic-review") {
|
|
51952
|
+
logger?.info("review", "Running semantic check", { storyId });
|
|
51953
|
+
} else if (opName === "adversarial-review") {
|
|
51954
|
+
logger?.info("review", "Running adversarial check", { storyId });
|
|
51955
|
+
}
|
|
51956
|
+
}
|
|
51957
|
+
function logUnifiedReviewPhaseResult(storyId, opName, output) {
|
|
51958
|
+
const logger = getSafeLogger();
|
|
51959
|
+
const payload = toReviewDecisionPayload(opName, output);
|
|
51960
|
+
if (!payload)
|
|
51961
|
+
return;
|
|
51962
|
+
if (!payload.parsed) {
|
|
51963
|
+
if (payload.failOpen) {
|
|
51964
|
+
logger?.warn("review", `${payload.reviewer} review fail-open`, { storyId });
|
|
51965
|
+
} else if (payload.looksLikeFail) {
|
|
51966
|
+
logger?.warn("review", `${payload.reviewer} review returned truncated failure`, { storyId });
|
|
51967
|
+
}
|
|
51968
|
+
return;
|
|
51969
|
+
}
|
|
51970
|
+
const findingsCount = payload.result.findings.length;
|
|
51971
|
+
const title = payload.reviewer === "semantic" ? "Semantic review" : "Adversarial review";
|
|
51972
|
+
if (payload.passed) {
|
|
51973
|
+
logger?.info("review", `${title} passed`, { storyId });
|
|
51974
|
+
} else {
|
|
51975
|
+
logger?.warn("review", `${title} failed: ${findingsCount} findings`, {
|
|
51976
|
+
storyId,
|
|
51977
|
+
findingsCount
|
|
51978
|
+
});
|
|
51979
|
+
}
|
|
51980
|
+
}
|
|
51905
51981
|
async function runPhase(ctx, slot, phaseCosts, phaseOutputs, isThreeSession = false) {
|
|
51906
51982
|
const logger = getSafeLogger();
|
|
51907
51983
|
const opName = slot.op.name;
|
|
@@ -51913,11 +51989,14 @@ async function runPhase(ctx, slot, phaseCosts, phaseOutputs, isThreeSession = fa
|
|
|
51913
51989
|
} else if (isThreeSession && opName === "full-suite-gate") {
|
|
51914
51990
|
logger?.info("tdd", "-> Running full test suite gate (before Verifier)", { storyId: ctx.storyId });
|
|
51915
51991
|
}
|
|
51992
|
+
logUnifiedReviewPhaseStart(ctx.storyId, opName);
|
|
51916
51993
|
const phaseStartedAt = Date.now();
|
|
51917
51994
|
const scope = ctx.runtime.costAggregator.openScope();
|
|
51918
51995
|
try {
|
|
51919
51996
|
const output = await _storyOrchestratorDeps.callOp({ ...ctx, scopeId: scope.scopeId }, slot.op, dispatchInput);
|
|
51920
51997
|
phaseOutputs[opName] = output;
|
|
51998
|
+
emitReviewDecision(ctx, opName, output);
|
|
51999
|
+
logUnifiedReviewPhaseResult(ctx.storyId, opName, output);
|
|
51921
52000
|
if (isTddPhase) {
|
|
51922
52001
|
const durationMs = Date.now() - phaseStartedAt;
|
|
51923
52002
|
logger?.info("tdd", `Session complete: ${opName}`, {
|
|
@@ -52555,6 +52634,9 @@ async function closeAllRunSessions(sessionManager, agentGetFn, opts) {
|
|
|
52555
52634
|
}
|
|
52556
52635
|
|
|
52557
52636
|
// src/execution/post-run.ts
|
|
52637
|
+
function shouldRollbackTddFailure(tddMode, failureCategory) {
|
|
52638
|
+
return tddMode?.rollbackEnabled === true && failureCategory === "isolation-violation";
|
|
52639
|
+
}
|
|
52558
52640
|
function extractPauseReason(phaseOutputs) {
|
|
52559
52641
|
for (const output of Object.values(phaseOutputs)) {
|
|
52560
52642
|
if (output !== null && typeof output === "object") {
|
|
@@ -52737,7 +52819,7 @@ async function decideStageAction(ctx, planResult, inspection, opts) {
|
|
|
52737
52819
|
const logger = getLogger();
|
|
52738
52820
|
const isTdd = opts.tddMode !== null;
|
|
52739
52821
|
const isLiteMode = opts.tddMode?.isLite ?? false;
|
|
52740
|
-
const shouldRollback = opts.tddMode
|
|
52822
|
+
const shouldRollback = shouldRollbackTddFailure(opts.tddMode, inspection.failureCategory);
|
|
52741
52823
|
const { agentResult, selfVerificationFailed, pauseReason, failureCategory, needsHumanReview, combinedOutput } = inspection;
|
|
52742
52824
|
if (planResult.rectificationExhausted && planResult.unfixedFindings && planResult.unfixedFindings.length > 0) {
|
|
52743
52825
|
const sources = new Set(planResult.unfixedFindings.map((f) => f.source));
|
|
@@ -56654,7 +56736,7 @@ var package_default;
|
|
|
56654
56736
|
var init_package = __esm(() => {
|
|
56655
56737
|
package_default = {
|
|
56656
56738
|
name: "@nathapp/nax",
|
|
56657
|
-
version: "0.67.
|
|
56739
|
+
version: "0.67.6",
|
|
56658
56740
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
56659
56741
|
type: "module",
|
|
56660
56742
|
bin: {
|
|
@@ -56749,8 +56831,8 @@ var init_version = __esm(() => {
|
|
|
56749
56831
|
NAX_VERSION = package_default.version;
|
|
56750
56832
|
NAX_COMMIT = (() => {
|
|
56751
56833
|
try {
|
|
56752
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
56753
|
-
return "
|
|
56834
|
+
if (/^[0-9a-f]{6,10}$/.test("8e8f2b3a"))
|
|
56835
|
+
return "8e8f2b3a";
|
|
56754
56836
|
} catch {}
|
|
56755
56837
|
try {
|
|
56756
56838
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|