@nathapp/nax 0.68.0 → 0.68.1

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.
Files changed (2) hide show
  1. package/dist/nax.js +46 -12
  2. package/package.json +1 -1
package/dist/nax.js CHANGED
@@ -21971,6 +21971,10 @@ function tryParseLLMJson(text) {
21971
21971
  }
21972
21972
 
21973
21973
  // src/agents/retry/parse-retry.ts
21974
+ function previewOutput(output, maxBytes) {
21975
+ const collapsed = output.replace(/\s+/g, " ").trim();
21976
+ return collapsed.length > maxBytes ? `${collapsed.slice(0, maxBytes)}\u2026` : collapsed;
21977
+ }
21974
21978
  function makeParseRetryStrategy(opts) {
21975
21979
  const parse5 = opts.parse ?? tryParseLLMJson;
21976
21980
  const checkTruncated = opts.looksTruncated ?? looksLikeTruncatedJson;
@@ -22003,16 +22007,19 @@ function makeParseRetryStrategy(opts) {
22003
22007
  const isTruncated = checkTruncated(ctx.lastOutput);
22004
22008
  const nextPrompt = isTruncated ? opts.prompts.truncated() : opts.prompts.invalid();
22005
22009
  const logger = opts._logger ?? getSafeLogger();
22010
+ const preview = opts.outputPreviewBytes && opts.outputPreviewBytes > 0 ? { outputPreview: previewOutput(ctx.lastOutput, opts.outputPreviewBytes) } : {};
22006
22011
  if (isTruncated) {
22007
22012
  logger?.warn(opts.reviewerKind, "JSON parse retry \u2014 likely truncated", {
22008
22013
  storyId: ctx.storyId,
22009
22014
  originalByteSize: ctx.lastOutput.length,
22015
+ ...preview,
22010
22016
  ...opts.logContext
22011
22017
  });
22012
22018
  } else {
22013
22019
  logger?.warn(opts.reviewerKind, "JSON parse retry \u2014 invalid shape", {
22014
22020
  storyId: ctx.storyId,
22015
22021
  originalByteSize: ctx.lastOutput.length,
22022
+ ...preview,
22016
22023
  ...opts.logContext
22017
22024
  });
22018
22025
  }
@@ -36897,6 +36904,7 @@ var verifierOp;
36897
36904
  var init_verify = __esm(() => {
36898
36905
  init_retry();
36899
36906
  init_config();
36907
+ init_logger2();
36900
36908
  init_tdd_builder();
36901
36909
  init_isolation();
36902
36910
  init_verdict();
@@ -36915,6 +36923,7 @@ var init_verify = __esm(() => {
36915
36923
  },
36916
36924
  reviewerKind: "verifier",
36917
36925
  maxAttempts: 2,
36926
+ outputPreviewBytes: 600,
36918
36927
  prompts: {
36919
36928
  invalid: () => TddPromptBuilder.verdictRetry(),
36920
36929
  truncated: () => TddPromptBuilder.verdictRetryCondensed()
@@ -36943,24 +36952,38 @@ var init_verify = __esm(() => {
36943
36952
  },
36944
36953
  async recover(input, verifyCtx) {
36945
36954
  const packageDir = verifyCtx.packageView.packageDir;
36955
+ const logger = getSafeLogger();
36956
+ const storyId = input.story.id;
36946
36957
  try {
36947
36958
  const verdict = await readVerdict(packageDir);
36948
36959
  if (verdict) {
36949
36960
  const testsAllPassing = verdict.tests.allPassing === true;
36950
36961
  const categorization = categorizeVerdict(verdict, testsAllPassing);
36951
36962
  const isolation = await runVerifierIsolation(input.beforeRef, verifyCtx);
36963
+ const normalizedFindings = buildVerifierFindings(verdict, categorization);
36964
+ logger?.warn("verifier", "Recovered verdict from disk after unparseable stdout", {
36965
+ storyId,
36966
+ packageDir,
36967
+ success: categorization.success,
36968
+ findingsCount: normalizedFindings.length,
36969
+ ...categorization.failureCategory && { failureCategory: categorization.failureCategory }
36970
+ });
36952
36971
  return {
36953
36972
  success: categorization.success,
36954
36973
  filesChanged: [],
36955
36974
  estimatedCostUsd: 0,
36956
36975
  durationMs: 0,
36957
36976
  output: "",
36958
- normalizedFindings: buildVerifierFindings(verdict, categorization),
36977
+ normalizedFindings,
36959
36978
  ...categorization.failureCategory && { failureCategory: categorization.failureCategory },
36960
36979
  ...categorization.reviewReason && { reviewReason: categorization.reviewReason },
36961
36980
  ...isolation && { isolation }
36962
36981
  };
36963
36982
  }
36983
+ logger?.error("verifier", "No usable verdict \u2014 unparseable stdout and no verdict file on disk (fail-closed)", {
36984
+ storyId,
36985
+ packageDir
36986
+ });
36964
36987
  return {
36965
36988
  success: false,
36966
36989
  filesChanged: [],
@@ -52981,23 +53004,34 @@ function logUnifiedReviewPhaseStart(storyId, opName) {
52981
53004
  logger?.info("review", "Running adversarial check", { storyId });
52982
53005
  }
52983
53006
  }
52984
- function logDeterministicPhaseOutcome(storyId, opName, output, durationMs, isTddPhase, stage) {
52985
- if (isTddPhase)
52986
- return;
52987
- if (opName === "semantic-review" || opName === "adversarial-review")
52988
- return;
53007
+ function buildPhaseOutcomeLogData(storyId, opName, output, durationMs) {
52989
53008
  if (output === null || output === undefined || typeof output !== "object")
52990
- return;
52991
- const logger = getSafeLogger();
53009
+ return null;
52992
53010
  const r = output;
52993
53011
  const success2 = r.success === true || r.passed === true;
52994
- const findingsCount = Array.isArray(r.findings) ? r.findings.length : undefined;
53012
+ const findingsCount = Array.isArray(r.normalizedFindings) ? r.normalizedFindings.length : Array.isArray(r.findings) ? r.findings.length : undefined;
52995
53013
  const status = typeof r.status === "string" ? r.status : undefined;
52996
53014
  const data = { storyId, phase: opName, durationMs };
52997
53015
  if (findingsCount !== undefined)
52998
53016
  data.findingsCount = findingsCount;
52999
53017
  if (status !== undefined)
53000
53018
  data.status = status;
53019
+ if (typeof r.failureCategory === "string")
53020
+ data.failureCategory = r.failureCategory;
53021
+ if (typeof r.reviewReason === "string")
53022
+ data.reviewReason = r.reviewReason;
53023
+ return { success: success2, data };
53024
+ }
53025
+ function logDeterministicPhaseOutcome(storyId, opName, output, durationMs, isTddPhase, stage) {
53026
+ if (isTddPhase)
53027
+ return;
53028
+ if (opName === "semantic-review" || opName === "adversarial-review")
53029
+ return;
53030
+ const built = buildPhaseOutcomeLogData(storyId, opName, output, durationMs);
53031
+ if (!built)
53032
+ return;
53033
+ const { success: success2, data } = built;
53034
+ const logger = getSafeLogger();
53001
53035
  const message = formatPhaseResultMessage(opName, success2, stage);
53002
53036
  if (stage === "rectification") {
53003
53037
  logger?.info("story-orchestrator", message, data);
@@ -57849,7 +57883,7 @@ var package_default;
57849
57883
  var init_package = __esm(() => {
57850
57884
  package_default = {
57851
57885
  name: "@nathapp/nax",
57852
- version: "0.68.0",
57886
+ version: "0.68.1",
57853
57887
  description: "AI Coding Agent Orchestrator \u2014 loops until done",
57854
57888
  type: "module",
57855
57889
  bin: {
@@ -57944,8 +57978,8 @@ var init_version = __esm(() => {
57944
57978
  NAX_VERSION = package_default.version;
57945
57979
  NAX_COMMIT = (() => {
57946
57980
  try {
57947
- if (/^[0-9a-f]{6,10}$/.test("d56db412"))
57948
- return "d56db412";
57981
+ if (/^[0-9a-f]{6,10}$/.test("5d69e4e4"))
57982
+ return "5d69e4e4";
57949
57983
  } catch {}
57950
57984
  try {
57951
57985
  const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nathapp/nax",
3
- "version": "0.68.0",
3
+ "version": "0.68.1",
4
4
  "description": "AI Coding Agent Orchestrator — loops until done",
5
5
  "type": "module",
6
6
  "bin": {