@akagilnc/pi-workflow-roles 0.1.5252 → 0.1.5273

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.
@@ -2839,7 +2839,6 @@ var init_host_descriptions = __esm({
2839
2839
  modelFlag: "--model"
2840
2840
  }),
2841
2841
  modelPassing: "argv",
2842
- boundResume: "session/load",
2843
2842
  sessionBindingFile: "grok-acp-session.json"
2844
2843
  }),
2845
2844
  /**
@@ -2857,7 +2856,6 @@ var init_host_descriptions = __esm({
2857
2856
  thinkingFlag: "--reasoning"
2858
2857
  }),
2859
2858
  modelPassing: "set_model",
2860
- boundResume: "session/load",
2861
2859
  sessionBindingFile: "hermes-acp-session.json",
2862
2860
  seatProfileSoul: Object.freeze({
2863
2861
  flag: "-p",
@@ -3764,7 +3762,6 @@ __export(durable_principal_exports, {
3764
3762
  issuePiDurablePrincipalCoordinates: () => issuePiDurablePrincipalCoordinates,
3765
3763
  piDurablePrincipalAuthority: () => piDurablePrincipalAuthority
3766
3764
  });
3767
- import { lstat } from "node:fs/promises";
3768
3765
  import { join as join9 } from "node:path";
3769
3766
  function encode(coordinates) {
3770
3767
  return coordinates;
@@ -3817,15 +3814,6 @@ var init_durable_principal = __esm({
3817
3814
  sessionDirectory: record4.sessionDirectory,
3818
3815
  sessionFile: typeof record4.sessionFile === "string" && record4.sessionFile.trim() !== "" ? record4.sessionFile : join9(record4.sessionDirectory, "session.jsonl")
3819
3816
  };
3820
- },
3821
- async isAvailable(principal) {
3822
- const { sessionFile } = this.decode(principal);
3823
- try {
3824
- const stat2 = await lstat(sessionFile);
3825
- return stat2.isFile() && !stat2.isSymbolicLink();
3826
- } catch {
3827
- return false;
3828
- }
3829
3817
  }
3830
3818
  };
3831
3819
  }
@@ -4427,8 +4415,8 @@ function formatTerminalResult(result) {
4427
4415
  `diagnostic ${encodeTerminalField(result.roleOutcome.diagnostic)}`
4428
4416
  );
4429
4417
  }
4430
- if (result.roleOutcome.kind === "failure" || result.roleOutcome.kind === "no_receipt" || result.roleOutcome.kind === "audit_escalation") {
4431
- const facts = result.roleOutcome.decisiveFacts ?? {};
4418
+ if (result.roleOutcome.kind === "failure" || result.roleOutcome.kind === "no_receipt" || result.roleOutcome.kind === "audit_escalation" || result.roleOutcome.decisiveFacts?.failedAttempts !== void 0) {
4419
+ const facts = result.roleOutcome.kind === "accepted" ? { failedAttempts: result.roleOutcome.decisiveFacts?.failedAttempts } : result.roleOutcome.decisiveFacts ?? {};
4432
4420
  for (const [key, value] of Object.entries(facts)) {
4433
4421
  if (value === void 0) continue;
4434
4422
  const rendered = typeof value === "string" ? value : JSON.stringify(value);
@@ -5841,7 +5829,7 @@ var init_ticket_provenance = __esm({
5841
5829
 
5842
5830
  // src/notary-source-run.ts
5843
5831
  import { dirname as dirname12, isAbsolute as isAbsolute5, join as join17, resolve as resolve10, basename as basename6 } from "node:path";
5844
- import { lstat as lstat2, realpath as realpath3 } from "node:fs/promises";
5832
+ import { lstat, realpath as realpath3 } from "node:fs/promises";
5845
5833
  async function readRetainedIdentity(runDirectory) {
5846
5834
  try {
5847
5835
  return await readRoleRunIdentity(runDirectory);
@@ -5869,7 +5857,7 @@ async function requireRunDirectory(candidate, display) {
5869
5857
  }
5870
5858
  let stat2;
5871
5859
  try {
5872
- stat2 = await lstat2(real);
5860
+ stat2 = await lstat(real);
5873
5861
  } catch (error) {
5874
5862
  throw new NotarySourceRunError(
5875
5863
  `notary --source-run is not a readable run directory: ${display}`,
@@ -7033,7 +7021,7 @@ var init_option_definitions = __esm({
7033
7021
  import { execFileSync as execFileSync2 } from "node:child_process";
7034
7022
  import { existsSync as existsSync4 } from "node:fs";
7035
7023
  import {
7036
- lstat as lstat3,
7024
+ lstat as lstat2,
7037
7025
  mkdtemp as mkdtemp2,
7038
7026
  readFile as readFile13,
7039
7027
  realpath as realpath4,
@@ -7595,7 +7583,7 @@ async function readRegularFileAttachment(sourcePath) {
7595
7583
  const absolute = isAbsolute6(sourcePath) ? sourcePath : resolve11(sourcePath);
7596
7584
  let st;
7597
7585
  try {
7598
- st = await lstat3(absolute);
7586
+ st = await lstat2(absolute);
7599
7587
  } catch (error) {
7600
7588
  throw new CliUsageError(
7601
7589
  `attachment is not a readable regular file: ${sourcePath}`,
@@ -12578,12 +12566,6 @@ function createSessionIdentityAuthority(authority, sessionBindingFile) {
12578
12566
  }
12579
12567
  };
12580
12568
  }
12581
- function resolveHostAwareSessionAvailability(host, principalAuthority) {
12582
- if (host === void 0 || host === DEFAULT_ROLE_TURN_HOST) {
12583
- return (principal) => principalAuthority.isAvailable(principal);
12584
- }
12585
- return async (principal) => await readStoredHostSessionId(host, principalAuthority, principal) !== void 0;
12586
- }
12587
12569
  async function readStoredHostSessionId(host, authority, principal) {
12588
12570
  if (host === void 0 || host === DEFAULT_ROLE_TURN_HOST) return void 0;
12589
12571
  const description = lookupHostDescription(host) ?? lookupHeadlessHostDescription(host);
@@ -12883,9 +12865,9 @@ var init_host_session_record = __esm({
12883
12865
  // src/public-cli/auto-resume.ts
12884
12866
  import { constants as fsConstants2 } from "node:fs";
12885
12867
  import { randomUUID as randomUUID6 } from "node:crypto";
12886
- import { lstat as lstat5, mkdir as mkdir3, open } from "node:fs/promises";
12868
+ import { lstat as lstat4, mkdir as mkdir3, open } from "node:fs/promises";
12887
12869
  import { join as join31 } from "node:path";
12888
- async function persistReturnedRunState(admitted, authority, options) {
12870
+ async function persistReturnedRunState(admitted, options) {
12889
12871
  if (options?.lawful === true) {
12890
12872
  await markRunTerminal(admitted.runDirectory);
12891
12873
  return;
@@ -12895,10 +12877,8 @@ async function persistReturnedRunState(admitted, authority, options) {
12895
12877
  });
12896
12878
  const typedHttp429 = resumeObservation.typedHttp429;
12897
12879
  if (admitted.principal !== void 0 && typedHttp429 !== void 0) {
12898
- if (await authority.isAvailable(admitted.principal)) {
12899
- await markRunResumable(admitted.runDirectory, typedHttp429);
12900
- return;
12901
- }
12880
+ await markRunResumable(admitted.runDirectory, typedHttp429);
12881
+ return;
12902
12882
  }
12903
12883
  await markRunTerminal(admitted.runDirectory);
12904
12884
  }
@@ -12920,20 +12900,20 @@ async function finalizeExceptionRunBestEffort(runDirectory, io) {
12920
12900
  }
12921
12901
  }
12922
12902
  async function ensureRealArtifactsDirectory(runDirectory) {
12923
- const runStat = await lstat5(runDirectory);
12903
+ const runStat = await lstat4(runDirectory);
12924
12904
  if (runStat.isSymbolicLink() || !runStat.isDirectory()) {
12925
12905
  throw new Error("run artifact retention: run directory is not a real directory");
12926
12906
  }
12927
12907
  const artifactsDir = roleRunArtifactsDirectory(runDirectory);
12928
12908
  try {
12929
- const existing = await lstat5(artifactsDir);
12909
+ const existing = await lstat4(artifactsDir);
12930
12910
  if (existing.isSymbolicLink() || !existing.isDirectory()) {
12931
12911
  throw new Error("run artifact retention: artifacts path is not a real directory");
12932
12912
  }
12933
12913
  } catch (error) {
12934
12914
  if (!isMissingPathError5(error)) throw error;
12935
12915
  await mkdir3(artifactsDir, { recursive: true });
12936
- const created = await lstat5(artifactsDir);
12916
+ const created = await lstat4(artifactsDir);
12937
12917
  if (created.isSymbolicLink() || !created.isDirectory()) {
12938
12918
  throw new Error("run artifact retention: artifacts directory is not a real directory");
12939
12919
  }
@@ -13064,7 +13044,6 @@ function dispatchExceptionFailureTerminal(input) {
13064
13044
  async function runWithAutoResumeLoop(options) {
13065
13045
  const limit = options.autoResumeLimit ?? AUTO_RESUME_LIMIT;
13066
13046
  parseAutoResumeLimit(limit);
13067
- const isPrincipalAvailable = options.isPrincipalAvailable ?? ((principal) => options.principalAuthority.isAvailable(principal));
13068
13047
  let autoResumeAttempts = 0;
13069
13048
  let isFirst = true;
13070
13049
  let currentPayload = options.buildInitialPayload();
@@ -13072,6 +13051,9 @@ async function runWithAutoResumeLoop(options) {
13072
13051
  let lastThrownError;
13073
13052
  let everyAttemptThrew = true;
13074
13053
  const retainedErrorFiles = [];
13054
+ const failedAttempts = [];
13055
+ let stoppedResult;
13056
+ let endReason;
13075
13057
  while (true) {
13076
13058
  let result;
13077
13059
  let turnStartedBeforeThrow = false;
@@ -13080,6 +13062,11 @@ async function runWithAutoResumeLoop(options) {
13080
13062
  result = await options.dispatch(currentPayload, lease, isFirst, dummyIo);
13081
13063
  } catch (error) {
13082
13064
  lastThrownError = error;
13065
+ const failedAttempt = {
13066
+ attempt: dispatchOrdinal,
13067
+ diagnostic: describeErrorIdentity(unwrapTurnDispatchedFailure(error))
13068
+ };
13069
+ failedAttempts.push(failedAttempt);
13083
13070
  turnStartedBeforeThrow = error instanceof TurnDispatchedFailure;
13084
13071
  const attempt = dispatchOrdinal;
13085
13072
  try {
@@ -13091,6 +13078,7 @@ async function runWithAutoResumeLoop(options) {
13091
13078
  error
13092
13079
  );
13093
13080
  retainedErrorFiles.push(file);
13081
+ failedAttempt.errorFile = file;
13094
13082
  options.io.stderr(
13095
13083
  `dispatch attempt ${attempt} threw (${describeErrorIdentity(error)}); full error retained at ${file}
13096
13084
  `
@@ -13111,100 +13099,30 @@ async function runWithAutoResumeLoop(options) {
13111
13099
  dispatchOrdinal += 1;
13112
13100
  if (result !== void 0) {
13113
13101
  everyAttemptThrew = false;
13114
- const terminal = result.terminal;
13115
- if (terminal !== void 0) {
13116
- terminal.autoResumeCount = autoResumeAttempts;
13117
- }
13118
- const lawful = terminal !== void 0 && isLawfulTypedTerminalOutcome(terminal.roleOutcome);
13119
- if (lawful) {
13120
- if (terminal !== void 0) {
13121
- options.io.stdout(formatTerminalResult(terminal));
13102
+ const terminal2 = result.terminal;
13103
+ if (terminal2 !== void 0) {
13104
+ terminal2.autoResumeCount = autoResumeAttempts;
13105
+ if (terminal2.roleOutcome.kind === "failure") {
13106
+ failedAttempts.push({
13107
+ attempt: dispatchOrdinal - 1,
13108
+ diagnostic: terminal2.roleOutcome.diagnostic,
13109
+ decisiveFacts: terminal2.roleOutcome.decisiveFacts
13110
+ });
13122
13111
  }
13123
- return result;
13124
13112
  }
13125
- if (result.skipAutoResume === true) {
13126
- if (terminal !== void 0) presentTerminal(terminal, options.io);
13127
- return result;
13128
- }
13129
- if (processCancelSignalName(options.signal) !== void 0) {
13130
- if (terminal !== void 0) presentTerminal(terminal, options.io);
13131
- return result;
13132
- }
13133
- }
13134
- if (result !== void 0) {
13135
- const terminal = result.terminal;
13136
- if (autoResumeAttempts >= limit) {
13137
- if (terminal !== void 0) presentTerminal(terminal, options.io);
13138
- return result;
13139
- }
13140
- if (result.turnDispatched === true && !await isPrincipalAvailable(options.admitted.principal)) {
13141
- if (terminal !== void 0) presentTerminal(terminal, options.io);
13142
- return result;
13113
+ if (terminal2 !== void 0 && isLawfulTypedTerminalOutcome(terminal2.roleOutcome) || result.skipAutoResume === true || autoResumeAttempts >= limit || processCancelSignalName(options.signal) !== void 0) {
13114
+ stoppedResult = result;
13115
+ break;
13143
13116
  }
13144
13117
  } else {
13145
13118
  if (autoResumeAttempts >= limit) {
13146
- const terminal = await attachDispatchExceptionTerminal(
13147
- options.admitted,
13148
- dispatchExceptionFailureTerminal({
13149
- role: options.admitted.role,
13150
- runId: options.admitted.runId,
13151
- causeError: lastThrownError,
13152
- errorFiles: retainedErrorFiles,
13153
- autoResumeAttempts,
13154
- endReason: "auto-resume budget exhausted",
13155
- everyAttemptThrew
13156
- }),
13157
- options.io
13158
- );
13159
- await finalizeExceptionRunBestEffort(options.admitted.runDirectory, options.io);
13160
- presentTerminal(terminal, options.io);
13161
- return {
13162
- exitCode: 1,
13163
- terminal
13164
- };
13119
+ endReason = "auto-resume budget exhausted";
13120
+ break;
13165
13121
  }
13166
13122
  const cancelName = processCancelSignalName(options.signal);
13167
13123
  if (cancelName !== void 0) {
13168
- const terminal = await attachDispatchExceptionTerminal(
13169
- options.admitted,
13170
- dispatchExceptionFailureTerminal({
13171
- role: options.admitted.role,
13172
- runId: options.admitted.runId,
13173
- causeError: lastThrownError,
13174
- errorFiles: retainedErrorFiles,
13175
- autoResumeAttempts,
13176
- endReason: `ak-role terminated by ${cancelName}`,
13177
- everyAttemptThrew
13178
- }),
13179
- options.io
13180
- );
13181
- await finalizeExceptionRunBestEffort(options.admitted.runDirectory, options.io);
13182
- presentTerminal(terminal, options.io);
13183
- return {
13184
- exitCode: 1,
13185
- terminal
13186
- };
13187
- }
13188
- if (!await isPrincipalAvailable(options.admitted.principal)) {
13189
- const terminal = await attachDispatchExceptionTerminal(
13190
- options.admitted,
13191
- dispatchExceptionFailureTerminal({
13192
- role: options.admitted.role,
13193
- runId: options.admitted.runId,
13194
- causeError: lastThrownError,
13195
- errorFiles: retainedErrorFiles,
13196
- autoResumeAttempts,
13197
- endReason: "session principal unavailable before further resume",
13198
- everyAttemptThrew
13199
- }),
13200
- options.io
13201
- );
13202
- await finalizeExceptionRunBestEffort(options.admitted.runDirectory, options.io);
13203
- presentTerminal(terminal, options.io);
13204
- return {
13205
- exitCode: 1,
13206
- terminal
13207
- };
13124
+ endReason = `ak-role terminated by ${cancelName}`;
13125
+ break;
13208
13126
  }
13209
13127
  }
13210
13128
  autoResumeAttempts++;
@@ -13213,6 +13131,34 @@ async function runWithAutoResumeLoop(options) {
13213
13131
  isFirst = false;
13214
13132
  }
13215
13133
  }
13134
+ const terminal = stoppedResult === void 0 ? await attachDispatchExceptionTerminal(
13135
+ options.admitted,
13136
+ dispatchExceptionFailureTerminal({
13137
+ role: options.admitted.role,
13138
+ runId: options.admitted.runId,
13139
+ causeError: lastThrownError,
13140
+ errorFiles: retainedErrorFiles,
13141
+ autoResumeAttempts,
13142
+ endReason,
13143
+ everyAttemptThrew
13144
+ }),
13145
+ options.io
13146
+ ) : stoppedResult.terminal;
13147
+ if (stoppedResult === void 0) {
13148
+ await finalizeExceptionRunBestEffort(options.admitted.runDirectory, options.io);
13149
+ }
13150
+ const complete = terminal !== void 0 && failedAttempts.length > 0 ? { ...terminal, roleOutcome: {
13151
+ ...terminal.roleOutcome,
13152
+ decisiveFacts: { ...terminal.roleOutcome.decisiveFacts, failedAttempts }
13153
+ } } : terminal;
13154
+ if (complete !== void 0) {
13155
+ if (isLawfulTypedTerminalOutcome(complete.roleOutcome)) {
13156
+ options.io.stdout(formatTerminalResult(complete));
13157
+ } else {
13158
+ presentTerminal(complete, options.io);
13159
+ }
13160
+ }
13161
+ return stoppedResult === void 0 ? { exitCode: 1, terminal: complete } : { ...stoppedResult, ...complete === void 0 ? {} : { terminal: complete } };
13216
13162
  }
13217
13163
  var dummyIo, TurnDispatchedFailure, DISPATCH_ERROR_RETENTION_ENTRY_TYPE;
13218
13164
  var init_auto_resume = __esm({
@@ -13381,14 +13327,9 @@ async function presentControlledFailure2(admitted, failureInput, adapters, autho
13381
13327
  ...failureInput.knownDiagnostic === void 0 ? {} : { knownDiagnostic: failureInput.knownDiagnostic },
13382
13328
  ...session === void 0 ? {} : { session }
13383
13329
  });
13384
- let resumable = false;
13385
- const typedHttp429 = resumeObservation.typedHttp429;
13386
- if (admitted.principal !== void 0) {
13387
- const sessionPrincipalAvailable = await authority.isAvailable(admitted.principal);
13388
- resumable = sessionPrincipalAvailable && typedHttp429 !== void 0;
13389
- }
13330
+ const resumable = admitted.principal !== void 0 && resumeObservation.typedHttp429 !== void 0;
13390
13331
  if (persistRunState && !failureInput.skipRunStateWrite) {
13391
- await persistReturnedRunState(admitted, authority);
13332
+ await persistReturnedRunState(admitted);
13392
13333
  }
13393
13334
  let publishedErrorPath;
13394
13335
  let terminal;
@@ -13433,7 +13374,7 @@ async function settleDeferredPersist(admitted, authority, adapters, io, result)
13433
13374
  const { needsPersist: _needsPersist, ...settledResult } = result;
13434
13375
  const lawful = isLawfulTypedTerminalOutcome(result.terminal.roleOutcome);
13435
13376
  try {
13436
- await persistReturnedRunState(admitted, authority, lawful ? { lawful: true } : void 0);
13377
+ await persistReturnedRunState(admitted, lawful ? { lawful: true } : void 0);
13437
13378
  return settledResult;
13438
13379
  } catch (error) {
13439
13380
  const failed = await settleAfterTurnStarted(
@@ -13711,7 +13652,7 @@ async function dispatchPostAdmissionTurn(input) {
13711
13652
  }
13712
13653
  if (persistRunState) {
13713
13654
  try {
13714
- await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
13655
+ await persistReturnedRunState(admitted, { lawful: true });
13715
13656
  } catch (error) {
13716
13657
  await recordBestEffortPostDispatchDiagnostic(
13717
13658
  admitted,
@@ -13796,7 +13737,7 @@ async function dispatchPostAdmissionTurn(input) {
13796
13737
  }
13797
13738
  if (persistRunState) {
13798
13739
  try {
13799
- await persistReturnedRunState(admitted, env.principalAuthority, { lawful: true });
13740
+ await persistReturnedRunState(admitted, { lawful: true });
13800
13741
  } catch (error) {
13801
13742
  await recordBestEffortPostDispatchDiagnostic(
13802
13743
  admitted,
@@ -14013,10 +13954,6 @@ async function runPostAdmissionSeatResume(input) {
14013
13954
  return await runWithAutoResumeLoop({
14014
13955
  admitted: loaded.admitted,
14015
13956
  principalAuthority: env.principalAuthority,
14016
- isPrincipalAvailable: resolveHostAwareSessionAvailability(
14017
- env.host,
14018
- env.principalAuthority
14019
- ),
14020
13957
  io: input.io,
14021
13958
  sessionAppender: env.sessionAppender,
14022
13959
  autoResumeLimit: env.autoResumeLimit,
@@ -14204,7 +14141,6 @@ async function runPostAdmissionResumable(input) {
14204
14141
  return runWithAutoResumeLoop({
14205
14142
  admitted,
14206
14143
  principalAuthority: env.principalAuthority,
14207
- isPrincipalAvailable: resolveHostAwareSessionAvailability(env.host, env.principalAuthority),
14208
14144
  io,
14209
14145
  sessionAppender: env.sessionAppender,
14210
14146
  autoResumeLimit: env.autoResumeLimit,
@@ -14326,7 +14262,7 @@ var init_seat_ticket_binding = __esm({
14326
14262
 
14327
14263
  // src/public-cli/machine-method-skills.ts
14328
14264
  import { accessSync, constants as constants2, statSync as statSync4 } from "node:fs";
14329
- import { lstat as lstat6, mkdir as mkdir4, symlink } from "node:fs/promises";
14265
+ import { lstat as lstat5, mkdir as mkdir4, symlink } from "node:fs/promises";
14330
14266
  import { join as join33 } from "node:path";
14331
14267
  import { spawnSync as spawnSync2 } from "node:child_process";
14332
14268
  function skillRoot(home) {
@@ -14356,7 +14292,7 @@ function linkedSkillRoot(home, host) {
14356
14292
  }
14357
14293
  async function occupied(path) {
14358
14294
  try {
14359
- await lstat6(path);
14295
+ await lstat5(path);
14360
14296
  return true;
14361
14297
  } catch (error) {
14362
14298
  if (error.code !== "ENOENT") throw error;
@@ -15441,7 +15377,7 @@ async function runPublicInstructionSeatResume(request, env, io) {
15441
15377
  };
15442
15378
  let binding;
15443
15379
  try {
15444
- const loaded = await loadResumablePublicRole(env.home, request.runId, env.principalAuthority, true);
15380
+ const loaded = await loadResumablePublicRole(env.home, request.runId, env.principalAuthority);
15445
15381
  binding = loaded.admitted.role === "auditor" ? await readAuditorResumeBinding(loaded.admitted.runDirectory) : void 0;
15446
15382
  } catch (error) {
15447
15383
  if (!(error instanceof CliUsageError)) throw error;
@@ -15484,7 +15420,7 @@ async function queueConclusionFromChild(child, env, io) {
15484
15420
  }
15485
15421
  }
15486
15422
  async function continueParentAfterChild(parentRunId, child, env, io) {
15487
- const loaded = await loadResumablePublicRole(env.home, parentRunId, env.principalAuthority, true);
15423
+ const loaded = await loadResumablePublicRole(env.home, parentRunId, env.principalAuthority);
15488
15424
  if (loaded.run.state !== "admitted" && !AUDITED_ROLES.has(loaded.admitted.role)) {
15489
15425
  return runPublicInstructionSeatResume({ runId: parentRunId }, env, io);
15490
15426
  }
@@ -15679,7 +15615,7 @@ async function auditSubmittedRole(turn, env, io, passedOfficer, passedReceipt, p
15679
15615
  const escalation = chain.passes.at(-1);
15680
15616
  const escalatedRunId = escalation?.runId ?? (escalation?.runDirectory === void 0 ? void 0 : runIdFromRunDirectory(escalation.runDirectory));
15681
15617
  if (escalatedRunId === void 0) throw new Error("escalated audit has no resumable run identity");
15682
- const officer = await loadResumablePublicRole(env.home, escalatedRunId, env.principalAuthority, true);
15618
+ const officer = await loadResumablePublicRole(env.home, escalatedRunId, env.principalAuthority);
15683
15619
  const terminal2 = await trySettlePublicSeat(officer.admitted, env.principalAuthority, void 0);
15684
15620
  if (terminal2 === void 0) throw new Error("escalated audit has no terminal result");
15685
15621
  io.stdout(formatTerminalResult(terminal2));
@@ -19603,7 +19539,6 @@ __export(run_lifecycle_exports, {
19603
19539
  describeErrorIdentity: () => describeErrorIdentity,
19604
19540
  findLatestRunIdForSeatTicket: () => findLatestRunIdForSeatTicket,
19605
19541
  findRunDirectoryById: () => findRunDirectoryById,
19606
- isDurablePrincipalAvailable: () => isDurablePrincipalAvailable,
19607
19542
  isV1ResumableProvider: () => isV1ResumableProvider,
19608
19543
  loadResumablePublicRole: () => loadResumablePublicRole,
19609
19544
  markRunAdmitted: () => markRunAdmitted,
@@ -19623,7 +19558,7 @@ __export(run_lifecycle_exports, {
19623
19558
  renderResumeCommand: () => renderResumeCommand,
19624
19559
  writeRoleRunState: () => writeRoleRunState
19625
19560
  });
19626
- import { chmod, lstat as lstat7, open as open3, readdir as readdir7, readFile as readFile22, unlink as unlink5, writeFile as writeFile9 } from "node:fs/promises";
19561
+ import { chmod, lstat as lstat6, open as open3, readdir as readdir7, readFile as readFile22, unlink as unlink5, writeFile as writeFile9 } from "node:fs/promises";
19627
19562
  import { basename as basename10, join as join40 } from "node:path";
19628
19563
  function buildAutoResumeContinuationPrompt(options) {
19629
19564
  return appendEngineSessionMaterial(
@@ -19937,9 +19872,6 @@ async function clearCurrentCourt(runDirectory, expectedCourtAttemptId) {
19937
19872
  ...current.resumable === void 0 ? {} : { resumable: current.resumable }
19938
19873
  });
19939
19874
  }
19940
- async function isDurablePrincipalAvailable(principal, authority) {
19941
- return authority.isAvailable(principal);
19942
- }
19943
19875
  function describeErrorIdentity(error) {
19944
19876
  const candidate = error;
19945
19877
  const name = typeof candidate?.name === "string" && candidate.name !== "" ? candidate.name : typeof error;
@@ -20181,7 +20113,7 @@ async function runHasFormedSessionPrincipal(runDirectory) {
20181
20113
  if (disk === void 0) return false;
20182
20114
  const sessionFile = typeof disk.principalWire.sessionFile === "string" && disk.principalWire.sessionFile.trim() !== "" ? disk.principalWire.sessionFile : join40(disk.principalWire.sessionDirectory, "session.jsonl");
20183
20115
  try {
20184
- const stat2 = await lstat7(sessionFile);
20116
+ const stat2 = await lstat6(sessionFile);
20185
20117
  return stat2.isFile() && !stat2.isSymbolicLink();
20186
20118
  } catch (error) {
20187
20119
  if (errorCodeOf(error) === "ENOENT") return false;
@@ -20273,7 +20205,7 @@ function restoredTicketFields(fields) {
20273
20205
  ...fields.courtTicketNumbers === void 0 ? {} : { courtTicketNumbers: fields.courtTicketNumbers }
20274
20206
  };
20275
20207
  }
20276
- async function loadResumableRunRecord(home, runId, authority, allowUnformedAdmitted = false) {
20208
+ async function loadResumableRunRecord(home, runId, authority) {
20277
20209
  const runDirectory = await findRunDirectoryById(home, runId);
20278
20210
  if (runDirectory === void 0) {
20279
20211
  throw new CliUsageError(`unknown role run id: ${runId}`);
@@ -20287,11 +20219,6 @@ async function loadResumableRunRecord(home, runId, authority, allowUnformedAdmit
20287
20219
  throw new CliUsageError(`unknown role run id: ${runId}`);
20288
20220
  }
20289
20221
  const { run, principal } = materialized;
20290
- if (!(allowUnformedAdmitted && run.state === "admitted") && !await isDurablePrincipalAvailable(principal, authority)) {
20291
- throw new CliUsageError(
20292
- `role run Pi session principal is unavailable: ${runId}`
20293
- );
20294
- }
20295
20222
  let instruction = "";
20296
20223
  let instructionEmpty = true;
20297
20224
  let attachments = [];
@@ -20568,8 +20495,8 @@ async function peekRoleRunRole(home, runId) {
20568
20495
  const run = await readRoleRunIdentity(runDirectory);
20569
20496
  return run?.role;
20570
20497
  }
20571
- async function loadResumablePublicRole(home, runId, authority, allowUnformedAdmitted = false) {
20572
- const loaded = await loadResumableRunRecord(home, runId, authority, allowUnformedAdmitted);
20498
+ async function loadResumablePublicRole(home, runId, authority) {
20499
+ const loaded = await loadResumableRunRecord(home, runId, authority);
20573
20500
  return seatLoadedResult(loaded, admitResumedRole(loaded));
20574
20501
  }
20575
20502
  function admitResumedRole(loaded) {
@@ -21649,9 +21576,14 @@ function createNativeNavigatorSessionFactory(deps) {
21649
21576
  }
21650
21577
  if (outcome.kind === "failure") {
21651
21578
  providerFailure = navigatorProviderFailureFromPublicTerminal(outcome);
21579
+ const failedAttempts = outcome.decisiveFacts.failedAttempts;
21580
+ const attemptReasons = Array.isArray(failedAttempts) ? failedAttempts.map((entry, index) => {
21581
+ const fact = entry !== null && typeof entry === "object" ? entry : void 0;
21582
+ return `${typeof fact?.attempt === "number" ? fact.attempt + 1 : index + 1}: ${typeof fact?.diagnostic === "string" ? fact.diagnostic : outcome.diagnostic}`;
21583
+ }) : [];
21652
21584
  throw navigatorUnavailableError(
21653
21585
  providerFailure.source,
21654
- new Error(outcome.diagnostic),
21586
+ new Error(attemptReasons.length > 0 ? attemptReasons.join("\n") : outcome.diagnostic),
21655
21587
  providerFailure.cause
21656
21588
  );
21657
21589
  }
@@ -26424,297 +26356,307 @@ function createHeadlessRoleTurnHost(config) {
26424
26356
  try {
26425
26357
  const explicitHostSessionId = request.continuation.kind === "resume" ? request.continuation.hostSessionId : void 0;
26426
26358
  let sessionId = explicitHostSessionId !== void 0 && explicitHostSessionId !== "" ? explicitHostSessionId : await config.sessionIdentity.load(request.principal);
26427
- let sessionKind = request.continuation.kind === "resume" && sessionId !== void 0 && sessionId !== "" ? "resume" : "new";
26428
- if (sessionKind === "new" && !codex) {
26429
- sessionId = randomUUID10();
26430
- await config.sessionIdentity.bind(request.principal, sessionId);
26431
- }
26432
- const env = { ...process.env, ...config.env ?? {} };
26433
- const systemPromptPath = join47(request.runDirectory, "headless-system-prompt.txt");
26434
- await writeFile11(systemPromptPath, systemPrompt, "utf8");
26435
- let mcpConfigPath;
26436
- let outputSchemaPath;
26437
- if (codex) {
26438
- if (prepared.terminatingToolName !== NAVIGATOR_OUTPUT_TOOL_NAME) {
26439
- outputSchemaPath = join47(request.runDirectory, "headless-output-schema.json");
26359
+ if (request.continuation.kind === "resume" && (sessionId === void 0 || sessionId === "")) {
26360
+ outcome = failure(
26361
+ "session",
26362
+ "HeadlessSessionFailure",
26363
+ "session-id-missing",
26364
+ void 0,
26365
+ "resume requires a bound session id"
26366
+ );
26367
+ } else {
26368
+ let sessionKind = request.continuation.kind === "resume" ? "resume" : "new";
26369
+ if (sessionKind === "new" && !codex) {
26370
+ sessionId = randomUUID10();
26371
+ await config.sessionIdentity.bind(request.principal, sessionId);
26372
+ }
26373
+ const env = { ...process.env, ...config.env ?? {} };
26374
+ const systemPromptPath = join47(request.runDirectory, "headless-system-prompt.txt");
26375
+ await writeFile11(systemPromptPath, systemPrompt, "utf8");
26376
+ let mcpConfigPath;
26377
+ let outputSchemaPath;
26378
+ if (codex) {
26379
+ if (prepared.terminatingToolName !== NAVIGATOR_OUTPUT_TOOL_NAME) {
26380
+ outputSchemaPath = join47(request.runDirectory, "headless-output-schema.json");
26381
+ await writeFile11(
26382
+ outputSchemaPath,
26383
+ `${JSON.stringify(closeJsonSchemaForCodex(prepared.jsonSchema), null, 2)}
26384
+ `,
26385
+ "utf8"
26386
+ );
26387
+ }
26388
+ } else {
26389
+ mcpConfigPath = join47(request.runDirectory, "headless-mcp-config.json");
26440
26390
  await writeFile11(
26441
- outputSchemaPath,
26442
- `${JSON.stringify(closeJsonSchemaForCodex(prepared.jsonSchema), null, 2)}
26391
+ mcpConfigPath,
26392
+ `${JSON.stringify(headlessMcpConfigDocument(prepared.mcpServers), null, 2)}
26443
26393
  `,
26444
26394
  "utf8"
26445
26395
  );
26446
26396
  }
26447
- } else {
26448
- mcpConfigPath = join47(request.runDirectory, "headless-mcp-config.json");
26449
- await writeFile11(
26450
- mcpConfigPath,
26451
- `${JSON.stringify(headlessMcpConfigDocument(prepared.mcpServers), null, 2)}
26452
- `,
26453
- "utf8"
26454
- );
26455
- }
26456
- const sessionParent = config.sessionIdentity.resolveSessionFile(request.principal);
26457
- let exitedSessionId;
26458
- try {
26459
- outcome = await driveExternalRoleTurnRounds(prepared, request, {
26460
- roundLimitName: "HeadlessRoundLimit",
26461
- currentSessionId: () => sessionId,
26462
- afterRetry() {
26463
- sessionKind = "resume";
26464
- },
26465
- async runRound({ prompt, abortSignal }) {
26466
- let args;
26467
- try {
26468
- const gitCommonDir = codex ? resolveGitCommonDir(request.cwd) : void 0;
26469
- args = buildTurnArgs({
26470
- description: config.description,
26471
- systemPromptPath,
26472
- // #959: navigator prose exit — no closed JSON schema on claude either.
26473
- ...prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME ? {} : { jsonSchema: prepared.jsonSchema },
26474
- mcpServers: prepared.mcpServers,
26475
- ...mcpConfigPath === void 0 ? {} : { mcpConfigPath },
26476
- ...outputSchemaPath === void 0 ? {} : { outputSchemaPath },
26477
- ...request.model?.model !== void 0 ? { model: request.model.model } : {},
26478
- ...request.model?.thinking !== void 0 ? { effort: request.model.thinking } : {},
26479
- sessionId,
26480
- sessionKind,
26481
- cwd: request.cwd,
26482
- ...gitCommonDir === void 0 ? {} : { writableRoots: [gitCommonDir] }
26483
- });
26484
- } catch (error) {
26485
- const message = error instanceof Error ? error.message : String(error);
26486
- return {
26487
- status: "terminal",
26488
- result: failure("session", "HeadlessArgvFailure", "argv-failed", { diagnostic: message }, message)
26489
- };
26490
- }
26491
- const codexObserver = codex ? createCodexExecTurnObserver() : void 0;
26492
- let pointerRecorded = false;
26493
- let codexIdObserved = false;
26494
- if (sessionId !== void 0 && sessionId !== "") {
26495
- pointerRecorded = recordNativeSessionPointer({
26496
- host: config.hostName,
26497
- sessionId,
26498
- cwd: request.cwd,
26499
- sessionParent,
26500
- home: request.home
26501
- }) !== void 0;
26502
- }
26503
- let spawned;
26504
- let childExited = false;
26505
- try {
26506
- spawned = await spawnHeadlessTurn({
26507
- onClose() {
26508
- childExited = true;
26509
- },
26510
- binary: config.binary,
26511
- args,
26512
- cwd: request.cwd,
26513
- env,
26514
- stdin: prompt,
26515
- ...abortSignal === void 0 ? {} : { signal: abortSignal },
26516
- ...request.timeoutMs === void 0 ? {} : { timeoutMs: request.timeoutMs },
26517
- onStdoutLine(line2) {
26518
- const trimmed = line2.trim();
26519
- if (trimmed === "") return;
26520
- let event;
26521
- try {
26522
- event = JSON.parse(trimmed);
26523
- } catch {
26524
- return;
26525
- }
26526
- codexObserver?.observe(event);
26527
- if (!codex && typeof event === "object" && event !== null && "session_id" in event && typeof event.session_id === "string" && event.session_id !== "" && event.session_id !== sessionId) {
26528
- sessionId = event.session_id;
26529
- recordNativeSessionPointer({ host: config.hostName, sessionId, cwd: request.cwd, sessionParent, home: request.home });
26530
- }
26531
- if (codex && !codexIdObserved) {
26532
- const tid = codexObserver?.result().threadId;
26533
- if (tid !== void 0 && tid !== "") {
26534
- codexIdObserved = true;
26535
- pointerRecorded = recordNativeSessionPointer({
26536
- host: config.hostName,
26537
- sessionId: tid,
26538
- cwd: request.cwd,
26539
- sessionParent,
26540
- home: request.home
26541
- }) !== void 0;
26542
- }
26543
- }
26544
- }
26545
- });
26546
- const roundSessionId = (codex ? codexObserver?.result().threadId : void 0) ?? sessionId;
26547
- exitedSessionId = roundSessionId;
26548
- if (codex && roundSessionId !== void 0 && roundSessionId !== "" && !pointerRecorded) {
26549
- recordNativeSessionPointer({ host: config.hostName, sessionId: roundSessionId, cwd: request.cwd, sessionParent, home: request.home });
26550
- }
26551
- } catch (error) {
26552
- if (childExited) exitedSessionId = (codex ? codexObserver?.result().threadId : void 0) ?? sessionId;
26553
- if (isHostAbortedError(error)) throw error;
26554
- const message = error instanceof Error ? error.message : String(error);
26555
- const observedHostFailure = codexObserver?.result().failureDiagnostic;
26556
- if (observedHostFailure !== void 0) {
26397
+ const sessionParent = config.sessionIdentity.resolveSessionFile(request.principal);
26398
+ let exitedSessionId;
26399
+ try {
26400
+ outcome = await driveExternalRoleTurnRounds(prepared, request, {
26401
+ roundLimitName: "HeadlessRoundLimit",
26402
+ currentSessionId: () => sessionId,
26403
+ afterRetry() {
26404
+ sessionKind = "resume";
26405
+ },
26406
+ async runRound({ prompt, abortSignal }) {
26407
+ let args;
26408
+ try {
26409
+ const gitCommonDir = codex ? resolveGitCommonDir(request.cwd) : void 0;
26410
+ args = buildTurnArgs({
26411
+ description: config.description,
26412
+ systemPromptPath,
26413
+ // #959: navigator prose exit — no closed JSON schema on claude either.
26414
+ ...prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME ? {} : { jsonSchema: prepared.jsonSchema },
26415
+ mcpServers: prepared.mcpServers,
26416
+ ...mcpConfigPath === void 0 ? {} : { mcpConfigPath },
26417
+ ...outputSchemaPath === void 0 ? {} : { outputSchemaPath },
26418
+ ...request.model?.model !== void 0 ? { model: request.model.model } : {},
26419
+ ...request.model?.thinking !== void 0 ? { effort: request.model.thinking } : {},
26420
+ sessionId,
26421
+ sessionKind,
26422
+ cwd: request.cwd,
26423
+ ...gitCommonDir === void 0 ? {} : { writableRoots: [gitCommonDir] }
26424
+ });
26425
+ } catch (error) {
26426
+ const message = error instanceof Error ? error.message : String(error);
26557
26427
  return {
26558
26428
  status: "terminal",
26559
- result: failure("output", "HeadlessCliError", "codex-turn-failed", {
26560
- diagnostic: observedHostFailure,
26561
- sessionRecordDiagnostic: message,
26562
- sessionId
26563
- }, observedHostFailure)
26429
+ result: failure("session", "HeadlessArgvFailure", "argv-failed", { diagnostic: message }, message)
26564
26430
  };
26565
26431
  }
26566
- return {
26567
- status: "terminal",
26568
- result: failure("activation", "HeadlessSpawnFailure", "spawn-failed", {
26569
- diagnostic: message,
26570
- binary: config.binary
26571
- }, message)
26572
- };
26573
- }
26574
- if (spawned.timedOut) {
26575
- return terminalFromSpawned(spawned, {
26576
- cause: "timeout",
26577
- identity: { name: "HeadlessTimeout", code: "timeout" },
26578
- details: { sessionId }
26579
- });
26580
- }
26581
- if (codex) {
26582
- const observation = codexObserver.result();
26583
- if (observation.threadId !== void 0 && observation.threadId !== "") {
26584
- sessionId = observation.threadId;
26585
- }
26586
- let sessionBindingDiagnostic;
26587
- const hostFailed = observation.failureDiagnostic !== void 0 || spawned.code !== 0 && spawned.code !== null;
26588
- if (hostFailed && observation.threadId !== void 0 && observation.threadId !== "") {
26589
- try {
26590
- await config.sessionIdentity.bind(request.principal, observation.threadId);
26591
- } catch (error) {
26592
- sessionBindingDiagnostic = error instanceof Error ? error.message : String(error);
26593
- }
26594
- }
26595
- if (observation.failureDiagnostic !== void 0) {
26596
- return terminalFromSpawned(spawned, {
26597
- cause: "output",
26598
- identity: { name: "HeadlessCliError", code: "codex-turn-failed" },
26599
- diagnostic: observation.failureDiagnostic,
26600
- details: {
26601
- sessionId,
26602
- exitCode: spawned.code,
26603
- ...sessionBindingDiagnostic === void 0 ? {} : { sessionBindingDiagnostic }
26604
- }
26605
- });
26432
+ const codexObserver = codex ? createCodexExecTurnObserver() : void 0;
26433
+ let pointerRecorded = false;
26434
+ let codexIdObserved = false;
26435
+ if (sessionId !== void 0 && sessionId !== "") {
26436
+ pointerRecorded = recordNativeSessionPointer({
26437
+ host: config.hostName,
26438
+ sessionId,
26439
+ cwd: request.cwd,
26440
+ sessionParent,
26441
+ home: request.home
26442
+ }) !== void 0;
26606
26443
  }
26607
- if (spawned.code !== 0 && spawned.code !== null) {
26608
- return terminalFromSpawned(spawned, {
26609
- cause: "output",
26610
- identity: { name: "HeadlessCliError", code: "codex-nonzero-exit" },
26611
- diagnostic: spawned.stderr.trim() || `codex exec exited ${String(spawned.code)}`,
26612
- details: {
26613
- sessionId,
26614
- exitCode: spawned.code,
26615
- ...sessionBindingDiagnostic === void 0 ? {} : { sessionBindingDiagnostic }
26444
+ let spawned;
26445
+ let childExited = false;
26446
+ try {
26447
+ spawned = await spawnHeadlessTurn({
26448
+ onClose() {
26449
+ childExited = true;
26450
+ },
26451
+ binary: config.binary,
26452
+ args,
26453
+ cwd: request.cwd,
26454
+ env,
26455
+ stdin: prompt,
26456
+ ...abortSignal === void 0 ? {} : { signal: abortSignal },
26457
+ ...request.timeoutMs === void 0 ? {} : { timeoutMs: request.timeoutMs },
26458
+ onStdoutLine(line2) {
26459
+ const trimmed = line2.trim();
26460
+ if (trimmed === "") return;
26461
+ let event;
26462
+ try {
26463
+ event = JSON.parse(trimmed);
26464
+ } catch {
26465
+ return;
26466
+ }
26467
+ codexObserver?.observe(event);
26468
+ if (!codex && typeof event === "object" && event !== null && "session_id" in event && typeof event.session_id === "string" && event.session_id !== "" && event.session_id !== sessionId) {
26469
+ sessionId = event.session_id;
26470
+ recordNativeSessionPointer({ host: config.hostName, sessionId, cwd: request.cwd, sessionParent, home: request.home });
26471
+ }
26472
+ if (codex && !codexIdObserved) {
26473
+ const tid = codexObserver?.result().threadId;
26474
+ if (tid !== void 0 && tid !== "") {
26475
+ codexIdObserved = true;
26476
+ pointerRecorded = recordNativeSessionPointer({
26477
+ host: config.hostName,
26478
+ sessionId: tid,
26479
+ cwd: request.cwd,
26480
+ sessionParent,
26481
+ home: request.home
26482
+ }) !== void 0;
26483
+ }
26484
+ }
26616
26485
  }
26617
26486
  });
26487
+ const roundSessionId = (codex ? codexObserver?.result().threadId : void 0) ?? sessionId;
26488
+ exitedSessionId = roundSessionId;
26489
+ if (codex && roundSessionId !== void 0 && roundSessionId !== "" && !pointerRecorded) {
26490
+ recordNativeSessionPointer({ host: config.hostName, sessionId: roundSessionId, cwd: request.cwd, sessionParent, home: request.home });
26491
+ }
26492
+ } catch (error) {
26493
+ if (childExited) exitedSessionId = (codex ? codexObserver?.result().threadId : void 0) ?? sessionId;
26494
+ if (isHostAbortedError(error)) throw error;
26495
+ const message = error instanceof Error ? error.message : String(error);
26496
+ const observedHostFailure = codexObserver?.result().failureDiagnostic;
26497
+ if (observedHostFailure !== void 0) {
26498
+ return {
26499
+ status: "terminal",
26500
+ result: failure("output", "HeadlessCliError", "codex-turn-failed", {
26501
+ diagnostic: observedHostFailure,
26502
+ sessionRecordDiagnostic: message,
26503
+ sessionId
26504
+ }, observedHostFailure)
26505
+ };
26506
+ }
26507
+ return {
26508
+ status: "terminal",
26509
+ result: failure("activation", "HeadlessSpawnFailure", "spawn-failed", {
26510
+ diagnostic: message,
26511
+ binary: config.binary
26512
+ }, message)
26513
+ };
26618
26514
  }
26619
- if (observation.threadId === void 0 || observation.threadId === "") {
26620
- return terminalFromSpawned(spawned, {
26621
- cause: "session",
26622
- identity: { name: "HeadlessMissingThreadId", code: "missing-thread-id" },
26623
- diagnostic: "codex exec emitted no thread.started thread_id",
26624
- details: { sessionId, exitCode: spawned.code }
26625
- });
26626
- }
26627
- sessionId = observation.threadId;
26628
- await config.sessionIdentity.bind(request.principal, sessionId);
26629
- if (!observation.turnCompleted) {
26630
- return terminalFromSpawned(spawned, {
26631
- cause: "output",
26632
- identity: { name: "HeadlessCliError", code: "codex-missing-terminal-event" },
26633
- diagnostic: "codex exec exited without turn.completed",
26634
- details: { sessionId, exitCode: spawned.code }
26635
- });
26636
- }
26637
- if (observation.finalMessage === void 0) {
26515
+ if (spawned.timedOut) {
26638
26516
  return terminalFromSpawned(spawned, {
26639
- cause: "output",
26640
- identity: { name: "HeadlessEmptyOutput", code: "empty-stdout" },
26641
- diagnostic: spawned.stderr.trim() || "codex exec produced no agent_message",
26642
- details: { sessionId, exitCode: spawned.code }
26517
+ cause: "timeout",
26518
+ identity: { name: "HeadlessTimeout", code: "timeout" },
26519
+ details: { sessionId }
26643
26520
  });
26644
26521
  }
26645
- if (prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME) {
26646
- if (observation.finalMessage.trim() === "") {
26522
+ if (codex) {
26523
+ const observation = codexObserver.result();
26524
+ if (observation.threadId !== void 0 && observation.threadId !== "") {
26525
+ sessionId = observation.threadId;
26526
+ }
26527
+ let sessionBindingDiagnostic;
26528
+ const hostFailed = observation.failureDiagnostic !== void 0 || spawned.code !== 0 && spawned.code !== null;
26529
+ if (hostFailed && observation.threadId !== void 0 && observation.threadId !== "") {
26530
+ try {
26531
+ await config.sessionIdentity.bind(request.principal, observation.threadId);
26532
+ } catch (error) {
26533
+ sessionBindingDiagnostic = error instanceof Error ? error.message : String(error);
26534
+ }
26535
+ }
26536
+ if (observation.failureDiagnostic !== void 0) {
26537
+ return terminalFromSpawned(spawned, {
26538
+ cause: "output",
26539
+ identity: { name: "HeadlessCliError", code: "codex-turn-failed" },
26540
+ diagnostic: observation.failureDiagnostic,
26541
+ details: {
26542
+ sessionId,
26543
+ exitCode: spawned.code,
26544
+ ...sessionBindingDiagnostic === void 0 ? {} : { sessionBindingDiagnostic }
26545
+ }
26546
+ });
26547
+ }
26548
+ if (spawned.code !== 0 && spawned.code !== null) {
26549
+ return terminalFromSpawned(spawned, {
26550
+ cause: "output",
26551
+ identity: { name: "HeadlessCliError", code: "codex-nonzero-exit" },
26552
+ diagnostic: spawned.stderr.trim() || `codex exec exited ${String(spawned.code)}`,
26553
+ details: {
26554
+ sessionId,
26555
+ exitCode: spawned.code,
26556
+ ...sessionBindingDiagnostic === void 0 ? {} : { sessionBindingDiagnostic }
26557
+ }
26558
+ });
26559
+ }
26560
+ if (observation.threadId === void 0 || observation.threadId === "") {
26561
+ return terminalFromSpawned(spawned, {
26562
+ cause: "session",
26563
+ identity: { name: "HeadlessMissingThreadId", code: "missing-thread-id" },
26564
+ diagnostic: "codex exec emitted no thread.started thread_id",
26565
+ details: { sessionId, exitCode: spawned.code }
26566
+ });
26567
+ }
26568
+ sessionId = observation.threadId;
26569
+ await config.sessionIdentity.bind(request.principal, sessionId);
26570
+ if (!observation.turnCompleted) {
26571
+ return terminalFromSpawned(spawned, {
26572
+ cause: "output",
26573
+ identity: { name: "HeadlessCliError", code: "codex-missing-terminal-event" },
26574
+ diagnostic: "codex exec exited without turn.completed",
26575
+ details: { sessionId, exitCode: spawned.code }
26576
+ });
26577
+ }
26578
+ if (observation.finalMessage === void 0) {
26647
26579
  return terminalFromSpawned(spawned, {
26648
26580
  cause: "output",
26649
26581
  identity: { name: "HeadlessEmptyOutput", code: "empty-stdout" },
26650
- diagnostic: spawned.stderr.trim() || "codex exec produced empty agent_message",
26582
+ diagnostic: spawned.stderr.trim() || "codex exec produced no agent_message",
26651
26583
  details: { sessionId, exitCode: spawned.code }
26652
26584
  });
26653
26585
  }
26654
- await prepared.ingestStructuredOutput({ prose: observation.finalMessage });
26586
+ if (prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME) {
26587
+ if (observation.finalMessage.trim() === "") {
26588
+ return terminalFromSpawned(spawned, {
26589
+ cause: "output",
26590
+ identity: { name: "HeadlessEmptyOutput", code: "empty-stdout" },
26591
+ diagnostic: spawned.stderr.trim() || "codex exec produced empty agent_message",
26592
+ details: { sessionId, exitCode: spawned.code }
26593
+ });
26594
+ }
26595
+ await prepared.ingestStructuredOutput({ prose: observation.finalMessage });
26596
+ return { status: "delivered", stderr: spawned.stderr };
26597
+ }
26598
+ let receipt;
26599
+ try {
26600
+ receipt = JSON.parse(observation.finalMessage);
26601
+ } catch {
26602
+ return terminalFromSpawned(spawned, {
26603
+ cause: "output",
26604
+ identity: { name: "HeadlessEmptyOutput", code: "unparseable-final-message" },
26605
+ diagnostic: "codex final agent_message was not JSON",
26606
+ details: { sessionId, exitCode: spawned.code }
26607
+ });
26608
+ }
26609
+ await prepared.ingestStructuredOutput(receipt);
26655
26610
  return { status: "delivered", stderr: spawned.stderr };
26656
26611
  }
26657
- let receipt;
26658
- try {
26659
- receipt = JSON.parse(observation.finalMessage);
26660
- } catch {
26612
+ const envelope = parseHeadlessCliStdout(spawned.stdout);
26613
+ if (envelope === void 0) {
26661
26614
  return terminalFromSpawned(spawned, {
26662
26615
  cause: "output",
26663
- identity: { name: "HeadlessEmptyOutput", code: "unparseable-final-message" },
26664
- diagnostic: "codex final agent_message was not JSON",
26616
+ identity: { name: "HeadlessEmptyOutput", code: "empty-stdout" },
26617
+ diagnostic: spawned.stderr.length > 0 ? spawned.stderr : "headless CLI produced no parseable result",
26665
26618
  details: { sessionId, exitCode: spawned.code }
26666
26619
  });
26667
26620
  }
26668
- await prepared.ingestStructuredOutput(receipt);
26621
+ if (typeof envelope.session_id === "string" && envelope.session_id !== "") {
26622
+ sessionId = envelope.session_id;
26623
+ await config.sessionIdentity.bind(request.principal, sessionId);
26624
+ }
26625
+ if (envelope.is_error === true || typeof envelope.subtype === "string" && envelope.subtype.startsWith("error_")) {
26626
+ const errorCode = typeof envelope.subtype === "string" && envelope.subtype.startsWith("error_") ? envelope.subtype : envelope.is_error === true ? "is_error" : "cli-error";
26627
+ const diagnostic = typeof envelope.result === "string" ? envelope.result : Array.isArray(envelope.errors) ? envelope.errors.map(String).join("\n") : spawned.stderr.length > 0 ? spawned.stderr : "headless CLI reported is_error";
26628
+ return terminalFromSpawned(spawned, {
26629
+ cause: "output",
26630
+ identity: { name: "HeadlessCliError", code: errorCode },
26631
+ diagnostic,
26632
+ details: {
26633
+ sessionId,
26634
+ subtype: envelope.subtype,
26635
+ errors: envelope.errors,
26636
+ exitCode: spawned.code
26637
+ }
26638
+ });
26639
+ }
26640
+ if (envelope.structured_output !== void 0) {
26641
+ await prepared.ingestStructuredOutput(envelope.structured_output);
26642
+ } else if (prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME && typeof envelope.result === "string" && envelope.result.trim() !== "") {
26643
+ await prepared.ingestStructuredOutput({ prose: envelope.result });
26644
+ }
26669
26645
  return { status: "delivered", stderr: spawned.stderr };
26670
26646
  }
26671
- const envelope = parseHeadlessCliStdout(spawned.stdout);
26672
- if (envelope === void 0) {
26673
- return terminalFromSpawned(spawned, {
26674
- cause: "output",
26675
- identity: { name: "HeadlessEmptyOutput", code: "empty-stdout" },
26676
- diagnostic: spawned.stderr.length > 0 ? spawned.stderr : "headless CLI produced no parseable result",
26677
- details: { sessionId, exitCode: spawned.code }
26678
- });
26679
- }
26680
- if (typeof envelope.session_id === "string" && envelope.session_id !== "") {
26681
- sessionId = envelope.session_id;
26682
- await config.sessionIdentity.bind(request.principal, sessionId);
26683
- }
26684
- if (envelope.is_error === true || typeof envelope.subtype === "string" && envelope.subtype.startsWith("error_")) {
26685
- const errorCode = typeof envelope.subtype === "string" && envelope.subtype.startsWith("error_") ? envelope.subtype : envelope.is_error === true ? "is_error" : "cli-error";
26686
- const diagnostic = typeof envelope.result === "string" ? envelope.result : Array.isArray(envelope.errors) ? envelope.errors.map(String).join("\n") : spawned.stderr.length > 0 ? spawned.stderr : "headless CLI reported is_error";
26687
- return terminalFromSpawned(spawned, {
26688
- cause: "output",
26689
- identity: { name: "HeadlessCliError", code: errorCode },
26690
- diagnostic,
26691
- details: {
26692
- sessionId,
26693
- subtype: envelope.subtype,
26694
- errors: envelope.errors,
26695
- exitCode: spawned.code
26696
- }
26697
- });
26698
- }
26699
- if (envelope.structured_output !== void 0) {
26700
- await prepared.ingestStructuredOutput(envelope.structured_output);
26701
- } else if (prepared.terminatingToolName === NAVIGATOR_OUTPUT_TOOL_NAME && typeof envelope.result === "string" && envelope.result.trim() !== "") {
26702
- await prepared.ingestStructuredOutput({ prose: envelope.result });
26703
- }
26704
- return { status: "delivered", stderr: spawned.stderr };
26705
- }
26706
- });
26707
- } finally {
26708
- if (exitedSessionId !== void 0 && exitedSessionId !== "") copyAndRecordHostDossier({
26709
- host: config.hostName,
26710
- sessionId: exitedSessionId,
26711
- cwd: request.cwd,
26712
- sessionDirectory: join47(request.runDirectory, "session"),
26713
- sessionParent,
26714
- continuation: request.continuation,
26715
- ...request.model !== void 0 ? { model: request.model } : {},
26716
- ...request.home !== void 0 ? { home: request.home } : {}
26717
- });
26647
+ });
26648
+ } finally {
26649
+ if (exitedSessionId !== void 0 && exitedSessionId !== "") copyAndRecordHostDossier({
26650
+ host: config.hostName,
26651
+ sessionId: exitedSessionId,
26652
+ cwd: request.cwd,
26653
+ sessionDirectory: join47(request.runDirectory, "session"),
26654
+ sessionParent,
26655
+ continuation: request.continuation,
26656
+ ...request.model !== void 0 ? { model: request.model } : {},
26657
+ ...request.home !== void 0 ? { home: request.home } : {}
26658
+ });
26659
+ }
26718
26660
  }
26719
26661
  } finally {
26720
26662
  try {