@nathapp/nax 0.61.1 → 0.61.2-canary.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 +98 -8
  2. package/package.json +1 -1
package/dist/nax.js CHANGED
@@ -3657,6 +3657,18 @@ function parseAcpxJsonLine(line, state) {
3657
3657
  };
3658
3658
  }
3659
3659
  }
3660
+ if (event.error && typeof event.error === "object") {
3661
+ const err = event.error;
3662
+ let errorMsg = typeof err.message === "string" ? err.message : JSON.stringify(event.error);
3663
+ if (err.data && typeof err.data === "object") {
3664
+ const data = err.data;
3665
+ const suffix = [data.acpxCode, data.detailCode].filter(Boolean).join("/");
3666
+ if (suffix)
3667
+ errorMsg = `${errorMsg} [${suffix}]`;
3668
+ }
3669
+ if (!state.error)
3670
+ state.error = errorMsg;
3671
+ }
3660
3672
  return;
3661
3673
  }
3662
3674
  if (event.content && typeof event.content === "string")
@@ -3807,12 +3819,15 @@ class SpawnAcpSession {
3807
3819
  Promise.race([stderrPromise, drainB.promise]).finally(() => drainB.cancel())
3808
3820
  ]);
3809
3821
  if (exitCode !== 0) {
3822
+ const parsedOnError = finalizeParseState(parseState);
3823
+ const errorContent = parsedOnError.error || stderr || `Exit code ${exitCode}`;
3810
3824
  getSafeLogger()?.warn("acp-adapter", `Session prompt exited with code ${exitCode}`, {
3811
3825
  exitCode,
3812
- stderr: stderr.slice(0, 500)
3826
+ error: errorContent.slice(0, 500),
3827
+ ...stderr && stderr !== errorContent ? { banner: stderr.trim().slice(0, 200) } : {}
3813
3828
  });
3814
3829
  return {
3815
- messages: [{ role: "assistant", content: stderr || `Exit code ${exitCode}` }],
3830
+ messages: [{ role: "assistant", content: errorContent }],
3816
3831
  stopReason: "error"
3817
3832
  };
3818
3833
  }
@@ -19087,7 +19102,10 @@ class AcpAgentAdapter {
19087
19102
  try {
19088
19103
  const result = await this._runWithClient(options, startTime, currentAgent);
19089
19104
  if (!result.success) {
19090
- getSafeLogger()?.warn("acp-adapter", `Run failed for ${currentAgent}`, { exitCode: result.exitCode });
19105
+ getSafeLogger()?.warn("acp-adapter", `Run failed for ${currentAgent}`, {
19106
+ exitCode: result.exitCode,
19107
+ ...result.output ? { output: result.output.slice(0, 500) } : {}
19108
+ });
19091
19109
  if (result.sessionError && _acpAdapterDeps.shouldRetrySessionError && !sessionErrorRetried) {
19092
19110
  sessionErrorRetried = true;
19093
19111
  getSafeLogger()?.warn("acp-adapter", "Session error \u2014 retrying with fresh session", {
@@ -32381,7 +32399,8 @@ async function runTddSession(role, agent, story, config2, workdir, modelTier, be
32381
32399
  role,
32382
32400
  storyId: story.id,
32383
32401
  durationMs: Date.now() - startTime,
32384
- exitCode: result.exitCode
32402
+ exitCode: result.exitCode,
32403
+ ...result.output ? { output: result.output.slice(0, 500) } : {}
32385
32404
  });
32386
32405
  }
32387
32406
  await _sessionRunnerDeps.autoCommitIfDirty(workdir, "tdd", role, story.id);
@@ -36657,7 +36676,7 @@ var package_default;
36657
36676
  var init_package = __esm(() => {
36658
36677
  package_default = {
36659
36678
  name: "@nathapp/nax",
36660
- version: "0.61.1",
36679
+ version: "0.61.2-canary.1",
36661
36680
  description: "AI Coding Agent Orchestrator \u2014 loops until done",
36662
36681
  type: "module",
36663
36682
  bin: {
@@ -36737,8 +36756,8 @@ var init_version = __esm(() => {
36737
36756
  NAX_VERSION = package_default.version;
36738
36757
  NAX_COMMIT = (() => {
36739
36758
  try {
36740
- if (/^[0-9a-f]{6,10}$/.test("a11d3b57"))
36741
- return "a11d3b57";
36759
+ if (/^[0-9a-f]{6,10}$/.test("7e54444a"))
36760
+ return "7e54444a";
36742
36761
  } catch {}
36743
36762
  try {
36744
36763
  const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
@@ -41081,6 +41100,68 @@ var init_run_initialization = __esm(() => {
41081
41100
  };
41082
41101
  });
41083
41102
 
41103
+ // src/execution/lifecycle/paused-story-prompts.ts
41104
+ var exports_paused_story_prompts = {};
41105
+ __export(exports_paused_story_prompts, {
41106
+ promptForPausedStories: () => promptForPausedStories
41107
+ });
41108
+ async function promptForPausedStories(prd, chain, featureName) {
41109
+ const logger = getSafeLogger();
41110
+ const summary = { resumed: [], skipped: [], kept: [] };
41111
+ const pausedStories = prd.userStories.filter((s) => s.status === "paused");
41112
+ for (const story of pausedStories) {
41113
+ const lastReason = (story.priorErrors?.slice(-1)[0] ?? "no reason recorded").replace(/\n/g, " ").slice(0, 200);
41114
+ logger?.info("run-initialization", "Paused story found \u2014 prompting user", {
41115
+ storyId: story.id,
41116
+ attempts: story.attempts
41117
+ });
41118
+ const response = await chain.prompt({
41119
+ id: `ix-${story.id}-paused-resume`,
41120
+ type: "choose",
41121
+ featureName,
41122
+ storyId: story.id,
41123
+ stage: "pre-flight",
41124
+ summary: `Story ${story.id} is paused \u2014 how to proceed?`,
41125
+ detail: `"${story.title}"
41126
+ Last reason: ${lastReason}
41127
+ Attempts so far: ${story.attempts}`,
41128
+ options: [
41129
+ { key: "resume", label: "Resume", description: "Reset to pending and retry on this run" },
41130
+ { key: "skip", label: "Skip", description: "Mark as skipped, won't be retried" },
41131
+ { key: "keep", label: "Keep paused", description: "Leave paused, skip for this run" }
41132
+ ],
41133
+ timeout: 300000,
41134
+ fallback: "continue",
41135
+ createdAt: Date.now()
41136
+ });
41137
+ const effectiveAction = chain.applyFallback(response, "continue");
41138
+ const resolvedKey = effectiveAction === "approve" ? "keep" : response.action;
41139
+ switch (resolvedKey) {
41140
+ case "resume": {
41141
+ story.status = "pending";
41142
+ summary.resumed.push(story.id);
41143
+ logger?.info("run-initialization", "User resumed paused story", { storyId: story.id });
41144
+ break;
41145
+ }
41146
+ case "skip": {
41147
+ story.status = "skipped";
41148
+ summary.skipped.push(story.id);
41149
+ logger?.info("run-initialization", "User skipped paused story", { storyId: story.id });
41150
+ break;
41151
+ }
41152
+ default: {
41153
+ summary.kept.push(story.id);
41154
+ logger?.info("run-initialization", "Keeping story paused", { storyId: story.id });
41155
+ break;
41156
+ }
41157
+ }
41158
+ }
41159
+ return summary;
41160
+ }
41161
+ var init_paused_story_prompts = __esm(() => {
41162
+ init_logger2();
41163
+ });
41164
+
41084
41165
  // src/execution/lifecycle/run-setup.ts
41085
41166
  var exports_run_setup = {};
41086
41167
  __export(exports_run_setup, {
@@ -41209,7 +41290,16 @@ async function setupRun(options) {
41209
41290
  agentGetFn: options.agentGetFn
41210
41291
  });
41211
41292
  prd = initResult.prd;
41212
- const counts = initResult.storyCounts;
41293
+ statusWriter.setPrd(prd);
41294
+ let counts = initResult.storyCounts;
41295
+ if (counts.paused > 0 && interactionChain !== null) {
41296
+ const { promptForPausedStories: promptForPausedStories2 } = await Promise.resolve().then(() => (init_paused_story_prompts(), exports_paused_story_prompts));
41297
+ const pausedSummary = await promptForPausedStories2(prd, interactionChain, feature);
41298
+ if (pausedSummary.resumed.length > 0 || pausedSummary.skipped.length > 0) {
41299
+ await savePRD(prd, prdPath);
41300
+ counts = countStories(prd);
41301
+ }
41302
+ }
41213
41303
  return {
41214
41304
  statusWriter,
41215
41305
  pidRegistry,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nathapp/nax",
3
- "version": "0.61.1",
3
+ "version": "0.61.2-canary.1",
4
4
  "description": "AI Coding Agent Orchestrator — loops until done",
5
5
  "type": "module",
6
6
  "bin": {