@liberseek/boft-cli-win32-arm64 0.6.4 → 0.6.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.
@@ -776,10 +776,10 @@ function mergeDefs(...defs) {
776
776
  function cloneDef(schema) {
777
777
  return mergeDefs(schema._zod.def);
778
778
  }
779
- function getElementAtPath(obj, path12) {
780
- if (!path12)
779
+ function getElementAtPath(obj, path14) {
780
+ if (!path14)
781
781
  return obj;
782
- return path12.reduce((acc, key) => acc?.[key], obj);
782
+ return path14.reduce((acc, key) => acc?.[key], obj);
783
783
  }
784
784
  function promiseAllObject(promisesObj) {
785
785
  const keys = Object.keys(promisesObj);
@@ -1188,11 +1188,11 @@ function explicitlyAborted(x2, startIndex = 0) {
1188
1188
  }
1189
1189
  return false;
1190
1190
  }
1191
- function prefixIssues(path12, issues) {
1191
+ function prefixIssues(path14, issues) {
1192
1192
  return issues.map((iss) => {
1193
1193
  var _a4;
1194
1194
  (_a4 = iss).path ?? (_a4.path = []);
1195
- iss.path.unshift(path12);
1195
+ iss.path.unshift(path14);
1196
1196
  return iss;
1197
1197
  });
1198
1198
  }
@@ -1339,16 +1339,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
1339
1339
  }
1340
1340
  function formatError(error52, mapper = (issue2) => issue2.message) {
1341
1341
  const fieldErrors = { _errors: [] };
1342
- const processError = (error53, path12 = []) => {
1342
+ const processError = (error53, path14 = []) => {
1343
1343
  for (const issue2 of error53.issues) {
1344
1344
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1345
- issue2.errors.map((issues) => processError({ issues }, [...path12, ...issue2.path]));
1345
+ issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
1346
1346
  } else if (issue2.code === "invalid_key") {
1347
- processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
1347
+ processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
1348
1348
  } else if (issue2.code === "invalid_element") {
1349
- processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
1349
+ processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
1350
1350
  } else {
1351
- const fullpath = [...path12, ...issue2.path];
1351
+ const fullpath = [...path14, ...issue2.path];
1352
1352
  if (fullpath.length === 0) {
1353
1353
  fieldErrors._errors.push(mapper(issue2));
1354
1354
  } else {
@@ -1375,17 +1375,17 @@ function formatError(error52, mapper = (issue2) => issue2.message) {
1375
1375
  }
1376
1376
  function treeifyError(error52, mapper = (issue2) => issue2.message) {
1377
1377
  const result = { errors: [] };
1378
- const processError = (error53, path12 = []) => {
1378
+ const processError = (error53, path14 = []) => {
1379
1379
  var _a4, _b2;
1380
1380
  for (const issue2 of error53.issues) {
1381
1381
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1382
- issue2.errors.map((issues) => processError({ issues }, [...path12, ...issue2.path]));
1382
+ issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
1383
1383
  } else if (issue2.code === "invalid_key") {
1384
- processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
1384
+ processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
1385
1385
  } else if (issue2.code === "invalid_element") {
1386
- processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
1386
+ processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
1387
1387
  } else {
1388
- const fullpath = [...path12, ...issue2.path];
1388
+ const fullpath = [...path14, ...issue2.path];
1389
1389
  if (fullpath.length === 0) {
1390
1390
  result.errors.push(mapper(issue2));
1391
1391
  continue;
@@ -1417,8 +1417,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
1417
1417
  }
1418
1418
  function toDotPath(_path) {
1419
1419
  const segs = [];
1420
- const path12 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
- for (const seg of path12) {
1420
+ const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
+ for (const seg of path14) {
1422
1422
  if (typeof seg === "number")
1423
1423
  segs.push(`[${seg}]`);
1424
1424
  else if (typeof seg === "symbol")
@@ -14110,13 +14110,13 @@ function resolveRef(ref, ctx) {
14110
14110
  if (!ref.startsWith("#")) {
14111
14111
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14112
14112
  }
14113
- const path12 = ref.slice(1).split("/").filter(Boolean);
14114
- if (path12.length === 0) {
14113
+ const path14 = ref.slice(1).split("/").filter(Boolean);
14114
+ if (path14.length === 0) {
14115
14115
  return ctx.rootSchema;
14116
14116
  }
14117
14117
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14118
- if (path12[0] === defsKey) {
14119
- const key = path12[1];
14118
+ if (path14[0] === defsKey) {
14119
+ const key = path14[1];
14120
14120
  if (!key || !ctx.defs[key]) {
14121
14121
  throw new Error(`Reference not found: ${ref}`);
14122
14122
  }
@@ -15525,6 +15525,12 @@ function parseHostUsage(value) {
15525
15525
  throw new Error(`Harness Usage contains unknown field '${key}'`);
15526
15526
  }
15527
15527
  }
15528
+ for (const field of ["totalCredits", "contextUsagePercent"]) {
15529
+ const candidate = value[field];
15530
+ if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
15531
+ throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
15532
+ }
15533
+ }
15528
15534
  for (const field of tokenFields) {
15529
15535
  const candidate = value[field];
15530
15536
  if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
@@ -15710,6 +15716,8 @@ var createSchema = external_exports.object({
15710
15716
  }).strict();
15711
15717
  var resumeSchema = external_exports.object({
15712
15718
  kind: external_exports.literal("resume"),
15719
+ model: harnessModelRefSchema.optional(),
15720
+ thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
15713
15721
  nativeRef: nativeSessionRefSchema,
15714
15722
  cwd: cwdSchema,
15715
15723
  knownTurnRefs: external_exports.array(nativeTurnRefSchema).max(1e5).optional()
@@ -15722,6 +15730,9 @@ var forkSchema = external_exports.object({
15722
15730
  }).strict();
15723
15731
  var rollbackSchema = external_exports.object({
15724
15732
  kind: external_exports.literal("rollbackLastTurn"),
15733
+ model: harnessModelRefSchema.optional(),
15734
+ thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
15735
+ permissionModeId: harnessPermissionModeIdSchema.optional(),
15725
15736
  sourceRef: nativeSessionRefSchema,
15726
15737
  cwd: cwdSchema
15727
15738
  }).strict();
@@ -16431,8 +16442,8 @@ var BrokeredHarnessAdapter = class {
16431
16442
  };
16432
16443
 
16433
16444
  // dist/claude-code-adapter.js
16434
- import { randomUUID as randomUUID2 } from "node:crypto";
16435
- import path10 from "node:path";
16445
+ import { randomUUID as randomUUID3 } from "node:crypto";
16446
+ import path12 from "node:path";
16436
16447
 
16437
16448
  // ../../../node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
16438
16449
  import { createRequire as DW } from "node:module";
@@ -20339,8 +20350,8 @@ var qU = v(function(BU) {
20339
20350
  BU._globalThis = void 0;
20340
20351
  BU._globalThis = typeof globalThis === "object" ? globalThis : global;
20341
20352
  });
20342
- var GU = v(function(os4) {
20343
- var Axe = os4 && os4.__createBinding || (Object.create ? function(e, t, r, n) {
20353
+ var GU = v(function(os5) {
20354
+ var Axe = os5 && os5.__createBinding || (Object.create ? function(e, t, r, n) {
20344
20355
  if (n === void 0) n = r;
20345
20356
  Object.defineProperty(e, n, { enumerable: true, get: function() {
20346
20357
  return t[r];
@@ -20348,11 +20359,11 @@ var GU = v(function(os4) {
20348
20359
  } : function(e, t, r, n) {
20349
20360
  if (n === void 0) n = r;
20350
20361
  e[n] = t[r];
20351
- }), kxe = os4 && os4.__exportStar || function(e, t) {
20362
+ }), kxe = os5 && os5.__exportStar || function(e, t) {
20352
20363
  for (var r in e) if (r !== "default" && !Object.prototype.hasOwnProperty.call(t, r)) Axe(t, e, r);
20353
20364
  };
20354
- Object.defineProperty(os4, "__esModule", { value: true });
20355
- kxe(qU(), os4);
20365
+ Object.defineProperty(os5, "__esModule", { value: true });
20366
+ kxe(qU(), os5);
20356
20367
  });
20357
20368
  var WU = v(function(is) {
20358
20369
  var Oxe = is && is.__createBinding || (Object.create ? function(e, t, r, n) {
@@ -42589,8 +42600,136 @@ function resolveClaudeCodeExecutable(input = {}, dependencies = {}) {
42589
42600
  return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path4.resolve(resolution.executable);
42590
42601
  }
42591
42602
 
42592
- // dist/claude-fork.js
42603
+ // dist/pending-session.js
42604
+ import { randomUUID as randomUUID2 } from "node:crypto";
42605
+ import { mkdir, open, readFile as readFile2, rename, rm as rm2, stat, unlink } from "node:fs/promises";
42606
+ import os3 from "node:os";
42593
42607
  import path5 from "node:path";
42608
+ var reservationSchema = external_exports.strictObject({
42609
+ version: external_exports.literal(1),
42610
+ sessionId: external_exports.uuid(),
42611
+ cwd: external_exports.string().min(1),
42612
+ configuration: harnessConfigurationStateSchema
42613
+ });
42614
+ function isPendingClaudeSession(ref) {
42615
+ return ref.locator !== void 0;
42616
+ }
42617
+ var ClaudePendingSessions = class {
42618
+ #directory;
42619
+ constructor(environment) {
42620
+ this.#directory = path5.join(path5.resolve(environment.CLAUDE_CONFIG_DIR ?? path5.join(os3.homedir(), ".claude")), "codexhost", "pending-sessions");
42621
+ }
42622
+ #path(ref, cwd) {
42623
+ if (ref.harnessId !== "claude-code" || !external_exports.uuid().safeParse(ref.nativeSessionId).success || !external_exports.strictObject({ pendingSession: external_exports.literal(1) }).safeParse(ref.locator).success || !path5.isAbsolute(cwd)) {
42624
+ throw new Error("Claude Code pending Session identity is invalid");
42625
+ }
42626
+ return path5.join(this.#directory, ref.nativeSessionId);
42627
+ }
42628
+ async create(cwd, configuration) {
42629
+ const ref = nativeSessionRefSchema.parse({
42630
+ harnessId: "claude-code",
42631
+ nativeSessionId: randomUUID2(),
42632
+ locator: { pendingSession: 1 },
42633
+ formatVersion: 1
42634
+ });
42635
+ const directory = this.#path(ref, cwd);
42636
+ const reservation = reservationSchema.parse({
42637
+ version: 1,
42638
+ sessionId: ref.nativeSessionId,
42639
+ cwd,
42640
+ configuration
42641
+ });
42642
+ await mkdir(this.#directory, { recursive: true, mode: 448 });
42643
+ await mkdir(directory, { mode: 448 });
42644
+ try {
42645
+ const file2 = await open(path5.join(directory, "session.json"), "wx", 384);
42646
+ try {
42647
+ await file2.writeFile(JSON.stringify(reservation));
42648
+ await file2.sync();
42649
+ } finally {
42650
+ await file2.close();
42651
+ }
42652
+ } catch (error52) {
42653
+ await rm2(directory, { recursive: true, force: true });
42654
+ throw error52;
42655
+ }
42656
+ await this.#sync(directory);
42657
+ await this.#sync(this.#directory);
42658
+ return ref;
42659
+ }
42660
+ async read(ref, cwd) {
42661
+ const directory = this.#path(ref, cwd);
42662
+ const reservation = reservationSchema.parse(JSON.parse(await readFile2(path5.join(directory, "session.json"), "utf8")));
42663
+ if (reservation.sessionId !== ref.nativeSessionId || reservation.cwd !== cwd) {
42664
+ throw new Error("Claude Code pending Session does not belong to this working directory");
42665
+ }
42666
+ let started = false;
42667
+ try {
42668
+ const claim = await stat(path5.join(directory, "started"));
42669
+ if (!claim.isFile())
42670
+ throw new Error("Claude Code pending Session claim is invalid");
42671
+ started = true;
42672
+ } catch (error52) {
42673
+ if (error52.code !== "ENOENT")
42674
+ throw error52;
42675
+ }
42676
+ return { started, configuration: reservation.configuration };
42677
+ }
42678
+ async saveConfiguration(ref, cwd, configuration) {
42679
+ await this.read(ref, cwd);
42680
+ const directory = this.#path(ref, cwd);
42681
+ const temporary = path5.join(directory, `${randomUUID2()}.tmp`);
42682
+ try {
42683
+ const file2 = await open(temporary, "wx", 384);
42684
+ try {
42685
+ await file2.writeFile(JSON.stringify(reservationSchema.parse({
42686
+ version: 1,
42687
+ sessionId: ref.nativeSessionId,
42688
+ cwd,
42689
+ configuration
42690
+ })));
42691
+ await file2.sync();
42692
+ } finally {
42693
+ await file2.close();
42694
+ }
42695
+ await rename(temporary, path5.join(directory, "session.json"));
42696
+ await this.#sync(directory);
42697
+ } finally {
42698
+ await rm2(temporary, { force: true });
42699
+ }
42700
+ }
42701
+ async #sync(directory) {
42702
+ if (process.platform === "win32")
42703
+ return;
42704
+ const handle = await open(directory, "r");
42705
+ try {
42706
+ await handle.sync();
42707
+ } finally {
42708
+ await handle.close();
42709
+ }
42710
+ }
42711
+ async claim(ref, cwd) {
42712
+ await this.read(ref, cwd);
42713
+ const claim = await open(path5.join(this.#path(ref, cwd), "started"), "wx", 384);
42714
+ try {
42715
+ await claim.sync();
42716
+ } finally {
42717
+ await claim.close();
42718
+ }
42719
+ await this.#sync(this.#path(ref, cwd));
42720
+ }
42721
+ /** Only the claim owner may release, after proven close and before submitting any native input. */
42722
+ async release(ref, cwd) {
42723
+ await unlink(path5.join(this.#path(ref, cwd), "started"));
42724
+ await this.#sync(this.#path(ref, cwd));
42725
+ }
42726
+ async discard(ref, cwd) {
42727
+ await rm2(this.#path(ref, cwd), { recursive: true, force: true });
42728
+ }
42729
+ };
42730
+
42731
+ // dist/claude-fork.js
42732
+ import path6 from "node:path";
42594
42733
  import { isDeepStrictEqual } from "node:util";
42595
42734
 
42596
42735
  // dist/item-identity.js
@@ -42680,9 +42819,19 @@ function visibleUserTextParts(message) {
42680
42819
  return [];
42681
42820
  return parts.filter((part) => !isLocalCommandRecord(part) && !isTaskNotificationRecord(part));
42682
42821
  }
42822
+ function isInterruptionRecord(value, promptId) {
42823
+ if (value.type !== "user" || promptId === null || value.promptId !== promptId || value.promptSource !== void 0 || !isRecord2(value.message))
42824
+ return false;
42825
+ const content = value.message.content;
42826
+ if (!Array.isArray(content) || content.length !== 1)
42827
+ return false;
42828
+ const part = content[0];
42829
+ return isRecord2(part) && part.type === "text" && (part.text === "[Request interrupted by user]" || part.text === "[Request interrupted by user for tool use]");
42830
+ }
42683
42831
  function conversationMessages(values, sessionId) {
42684
42832
  const messages = [];
42685
42833
  const ids = /* @__PURE__ */ new Set();
42834
+ let promptId = null;
42686
42835
  for (const value of values) {
42687
42836
  if (!isRecord2(value))
42688
42837
  throw new Error("Claude history contains a malformed message");
@@ -42694,13 +42843,19 @@ function conversationMessages(values, sessionId) {
42694
42843
  if (ids.has(value.uuid))
42695
42844
  throw new Error("Claude history contains duplicate message IDs");
42696
42845
  ids.add(value.uuid);
42697
- messages.push({
42846
+ const interrupted = isInterruptionRecord(value, promptId);
42847
+ const message = {
42698
42848
  type: value.type,
42699
42849
  uuid: value.uuid,
42700
42850
  message: value.message,
42701
42851
  timestampMs: isoToMs(value.timestamp),
42702
- syntheticUser: value.type === "user" && (value.isSynthetic === true || value.isMeta === true || isTaskNotificationOrigin(value) || value.toolUseResult !== void 0 && value.toolUseResult !== null)
42703
- });
42852
+ interrupted,
42853
+ syntheticUser: value.type === "user" && (interrupted || value.isSynthetic === true || value.isMeta === true || isTaskNotificationOrigin(value) || value.toolUseResult !== void 0 && value.toolUseResult !== null)
42854
+ };
42855
+ messages.push(message);
42856
+ if (isHumanUser(message)) {
42857
+ promptId = typeof value.promptId === "string" && value.promptId.length > 0 ? value.promptId : null;
42858
+ }
42704
42859
  }
42705
42860
  return messages;
42706
42861
  }
@@ -42708,6 +42863,8 @@ function isHumanUser(message) {
42708
42863
  return visibleUserTextParts(message).length > 0;
42709
42864
  }
42710
42865
  function turnOutcome(messages) {
42866
+ if (messages.some(({ interrupted }) => interrupted))
42867
+ return { status: "cancelled", reason: "Cancelled by user" };
42711
42868
  const assistants = messages.filter(({ type }) => type === "assistant");
42712
42869
  const failed = assistants.some(({ message }) => typeof message.error === "string");
42713
42870
  if (failed) {
@@ -42755,7 +42912,7 @@ function mapClaudeSnapshot(values, sessionId) {
42755
42912
  const turnMessages = messages.slice(index, end);
42756
42913
  const outcome = turnOutcome(turnMessages);
42757
42914
  const results = toolResultBlocks(turnMessages);
42758
- const checkpointMessage = turnMessages.findLast(({ type }) => type === "assistant");
42915
+ const checkpointMessage = turnMessages.findLast(({ type, interrupted }) => type === "assistant" || interrupted);
42759
42916
  const startedAtMs = turnMessages[0]?.timestampMs;
42760
42917
  const completedAtMs = turnMessages.at(-1)?.timestampMs;
42761
42918
  let agentMessageOrdinal = 0;
@@ -43099,6 +43256,7 @@ function comparableTurn(turn) {
43099
43256
  outcome
43100
43257
  })),
43101
43258
  outcome: turn.outcome,
43259
+ hasCheckpoint: turn.checkpoint !== void 0,
43102
43260
  ...turn.model ? { model: turn.model } : {}
43103
43261
  };
43104
43262
  }
@@ -43135,8 +43293,8 @@ async function readSnapshot(dependencies, cwd, sessionId) {
43135
43293
  }
43136
43294
  async function forkClaudeSession(input) {
43137
43295
  const sourceRef = nativeSessionRefSchema.safeParse(input.sourceRef);
43138
- const checkpoint = nativeCheckpointRefSchema.safeParse(input.checkpoint);
43139
- if (!sourceRef.success || !checkpoint.success || sourceRef.data.harnessId !== input.harnessId || checkpoint.data.harnessId !== input.harnessId || checkpoint.data.nativeSessionId !== sourceRef.data.nativeSessionId) {
43296
+ const checkpoint = input.kind === "fork" ? nativeCheckpointRefSchema.safeParse(input.checkpoint) : null;
43297
+ if (!sourceRef.success || sourceRef.data.harnessId !== input.harnessId || checkpoint && (!checkpoint.success || checkpoint.data.harnessId !== input.harnessId || checkpoint.data.nativeSessionId !== sourceRef.data.nativeSessionId)) {
43140
43298
  return {
43141
43299
  ok: false,
43142
43300
  error: error51("invalidRequest", "Claude Code Fork identity does not belong to the source Session", false)
@@ -43165,7 +43323,7 @@ async function forkClaudeSession(input) {
43165
43323
  error: error51("protocolError", "Claude Code Session working directory is unavailable", false)
43166
43324
  };
43167
43325
  }
43168
- if (path5.resolve(sourceInfo.cwd) !== input.cwd) {
43326
+ if (path6.resolve(sourceInfo.cwd) !== input.cwd) {
43169
43327
  return {
43170
43328
  ok: false,
43171
43329
  error: error51("unsupported", "Claude Code cannot Fork across working directories", false)
@@ -43174,8 +43332,39 @@ async function forkClaudeSession(input) {
43174
43332
  const source = await readSnapshot(input.dependencies, input.cwd, sourceRef.data.nativeSessionId);
43175
43333
  if (!source.ok)
43176
43334
  return source;
43177
- const boundaryIndex = source.value.turns.findIndex((turn) => turn.checkpoint?.checkpointId === checkpoint.data.checkpointId);
43178
- if (boundaryIndex < 0) {
43335
+ if (input.kind === "rollbackLastTurn" && source.value.turns.length === 0) {
43336
+ return {
43337
+ ok: false,
43338
+ error: error51("invalidRequest", "Claude Code Session has no Turn to roll back", false)
43339
+ };
43340
+ }
43341
+ if (input.kind === "rollbackLastTurn" && source.value.turns.length === 1) {
43342
+ let nativeRef;
43343
+ try {
43344
+ nativeRef = await input.pendingSessions.create(input.cwd, input.configuration);
43345
+ } catch {
43346
+ return {
43347
+ ok: false,
43348
+ error: error51("nativeFailure", "Claude Code empty rollback could not be persisted", true)
43349
+ };
43350
+ }
43351
+ const sourceAfter2 = await readSnapshot(input.dependencies, input.cwd, sourceRef.data.nativeSessionId);
43352
+ if (!sourceAfter2.ok || !isDeepStrictEqual(sourceAfter2.value, source.value)) {
43353
+ await input.pendingSessions.discard(nativeRef, input.cwd).catch(() => void 0);
43354
+ return {
43355
+ ok: false,
43356
+ error: error51("protocolError", "Claude Code source history changed during rollback", false)
43357
+ };
43358
+ }
43359
+ return {
43360
+ ok: true,
43361
+ value: { sessionId: nativeRef.nativeSessionId, nativeRef, openMode: "create" }
43362
+ };
43363
+ }
43364
+ const boundaryIndex = input.kind === "rollbackLastTurn" ? source.value.turns.length - 2 : source.value.turns.findIndex((turn) => checkpoint?.success && turn.checkpoint?.checkpointId === checkpoint.data.checkpointId);
43365
+ const retained = source.value.turns[boundaryIndex];
43366
+ const boundaryId = retained?.checkpoint?.checkpointId ?? (input.kind === "rollbackLastTurn" ? retained?.nativeTurnRef.nativeTurnKey : void 0);
43367
+ if (boundaryIndex < 0 || !boundaryId) {
43179
43368
  return {
43180
43369
  ok: false,
43181
43370
  error: error51("checkpointNotFound", "Claude Code Fork Checkpoint is unavailable", false)
@@ -43184,7 +43373,7 @@ async function forkClaudeSession(input) {
43184
43373
  let derivedSessionId;
43185
43374
  try {
43186
43375
  const forked = await input.dependencies.forkSession({
43187
- checkpointId: checkpoint.data.checkpointId,
43376
+ checkpointId: boundaryId,
43188
43377
  cwd: input.cwd,
43189
43378
  sourceSessionId: sourceRef.data.nativeSessionId
43190
43379
  });
@@ -43223,7 +43412,7 @@ async function forkClaudeSession(input) {
43223
43412
  const derivedContent = derived.value.turns.map(comparableTurn);
43224
43413
  const sourceIds = nativeIds(source.value);
43225
43414
  const derivedIds = nativeIds(derived.value);
43226
- if (!isDeepStrictEqual(sourceAfter.value.turns.slice(0, boundaryIndex + 1), sourcePrefix) || !isDeepStrictEqual(derivedContent, expectedPrefix) || derivedIds.size === 0 || [...derivedIds].some((id) => sourceIds.has(id))) {
43415
+ if (input.kind === "rollbackLastTurn" && sourceAfter.value.turns.length !== source.value.turns.length || sourceAfter.value.turns.length < source.value.turns.length || !isDeepStrictEqual(sourceAfter.value.turns.slice(0, source.value.turns.length), source.value.turns) || !isDeepStrictEqual(derivedContent, expectedPrefix) || derivedIds.size === 0 || [...derivedIds].some((id) => sourceIds.has(id))) {
43227
43416
  await cleanup();
43228
43417
  return {
43229
43418
  ok: false,
@@ -43234,8 +43423,8 @@ async function forkClaudeSession(input) {
43234
43423
  }
43235
43424
 
43236
43425
  // dist/claude-session-import.js
43237
- import { realpath, stat } from "node:fs/promises";
43238
- import path6 from "node:path";
43426
+ import { realpath, stat as stat2 } from "node:fs/promises";
43427
+ import path7 from "node:path";
43239
43428
  function titleFromMetadata(metadata) {
43240
43429
  for (const value of [metadata.customTitle, metadata.summary, metadata.firstPrompt]) {
43241
43430
  if (typeof value !== "string")
@@ -43257,14 +43446,14 @@ async function sourceFromMetadata(metadata, isRunning, signal, canonicalCwds, pr
43257
43446
  ];
43258
43447
  let cwd = null;
43259
43448
  for (const candidate2 of new Set(candidates)) {
43260
- if (!path6.isAbsolute(candidate2))
43449
+ if (!path7.isAbsolute(candidate2))
43261
43450
  continue;
43262
43451
  let canonical = canonicalCwds.get(candidate2);
43263
43452
  if (!canonical) {
43264
43453
  canonical = (async () => {
43265
43454
  try {
43266
43455
  const resolved = await realpath(candidate2);
43267
- return (await stat(resolved)).isDirectory() ? resolved : null;
43456
+ return (await stat2(resolved)).isDirectory() ? resolved : null;
43268
43457
  } catch {
43269
43458
  return null;
43270
43459
  }
@@ -43334,7 +43523,7 @@ var ClaudeSessionImportIndex = class {
43334
43523
  if (!metadata || metadata.sessionId !== nativeSessionId)
43335
43524
  return null;
43336
43525
  const preferredCwds = [];
43337
- if (typeof metadata.cwd === "string" && path6.isAbsolute(metadata.cwd)) {
43526
+ if (typeof metadata.cwd === "string" && path7.isAbsolute(metadata.cwd)) {
43338
43527
  try {
43339
43528
  const messages = await this.#dependencies.readSessionMessages({
43340
43529
  cwd: metadata.cwd,
@@ -43347,7 +43536,7 @@ var ClaudeSessionImportIndex = class {
43347
43536
  continue;
43348
43537
  }
43349
43538
  const cwd = message.cwd;
43350
- if (path6.isAbsolute(cwd) && !preferredCwds.includes(cwd))
43539
+ if (path7.isAbsolute(cwd) && !preferredCwds.includes(cwd))
43351
43540
  preferredCwds.push(cwd);
43352
43541
  }
43353
43542
  } catch {
@@ -43358,25 +43547,25 @@ var ClaudeSessionImportIndex = class {
43358
43547
  };
43359
43548
 
43360
43549
  // dist/claude-transcript.js
43361
- import os3 from "node:os";
43362
- import path7 from "node:path";
43363
- import { readFile as readFile2, readdir, stat as stat2 } from "node:fs/promises";
43550
+ import os4 from "node:os";
43551
+ import path8 from "node:path";
43552
+ import { readFile as readFile3, readdir, stat as stat3 } from "node:fs/promises";
43364
43553
  function projectDirectoryName(cwd) {
43365
43554
  return cwd.replace(/[^A-Za-z0-9]/gu, "-");
43366
43555
  }
43367
43556
  function configDirectory(environment) {
43368
- return environment.CLAUDE_CONFIG_DIR ? path7.resolve(environment.CLAUDE_CONFIG_DIR) : path7.join(os3.homedir(), ".claude");
43557
+ return environment.CLAUDE_CONFIG_DIR ? path8.resolve(environment.CLAUDE_CONFIG_DIR) : path8.join(os4.homedir(), ".claude");
43369
43558
  }
43370
43559
  async function existingFile(file2) {
43371
43560
  try {
43372
- return (await stat2(file2)).isFile();
43561
+ return (await stat3(file2)).isFile();
43373
43562
  } catch {
43374
43563
  return false;
43375
43564
  }
43376
43565
  }
43377
43566
  async function findTranscriptFile(environment, cwd, relativeName) {
43378
- const projectsDirectory = path7.join(configDirectory(environment), "projects");
43379
- const expected = path7.join(projectsDirectory, projectDirectoryName(cwd), relativeName);
43567
+ const projectsDirectory = path8.join(configDirectory(environment), "projects");
43568
+ const expected = path8.join(projectsDirectory, projectDirectoryName(cwd), relativeName);
43380
43569
  if (await existingFile(expected))
43381
43570
  return expected;
43382
43571
  let projects;
@@ -43386,7 +43575,7 @@ async function findTranscriptFile(environment, cwd, relativeName) {
43386
43575
  return null;
43387
43576
  }
43388
43577
  for (const project of projects) {
43389
- const candidate = path7.join(projectsDirectory, project, relativeName);
43578
+ const candidate = path8.join(projectsDirectory, project, relativeName);
43390
43579
  if (await existingFile(candidate))
43391
43580
  return candidate;
43392
43581
  }
@@ -43417,14 +43606,14 @@ async function readClaudeTranscript(input) {
43417
43606
  const transcript = await findTranscriptFile(input.environment, input.cwd, `${input.sessionId}.jsonl`);
43418
43607
  if (!transcript)
43419
43608
  return null;
43420
- return parseTranscriptRecords(await readFile2(transcript, "utf8"), input.sessionId);
43609
+ return parseTranscriptRecords(await readFile3(transcript, "utf8"), input.sessionId);
43421
43610
  }
43422
43611
  async function readClaudeSubagentTranscript(input) {
43423
- const relativeName = path7.join(input.sessionId, "subagents", `agent-${input.nativeSubagentId}.jsonl`);
43612
+ const relativeName = path8.join(input.sessionId, "subagents", `agent-${input.nativeSubagentId}.jsonl`);
43424
43613
  const transcript = await findTranscriptFile(input.environment, input.cwd, relativeName);
43425
43614
  if (!transcript)
43426
43615
  return null;
43427
- return parseTranscriptRecords(await readFile2(transcript, "utf8"), input.sessionId);
43616
+ return parseTranscriptRecords(await readFile3(transcript, "utf8"), input.sessionId);
43428
43617
  }
43429
43618
 
43430
43619
  // dist/model-catalog.js
@@ -43686,8 +43875,8 @@ function projectClaudeAccountUsage(usage, account) {
43686
43875
  }
43687
43876
 
43688
43877
  // dist/gateway-models.js
43689
- import { readFile as readFile3 } from "node:fs/promises";
43690
- import path8 from "node:path";
43878
+ import { readFile as readFile4 } from "node:fs/promises";
43879
+ import path9 from "node:path";
43691
43880
  var GATEWAY_MODELS_TIMEOUT_MS = 3e3;
43692
43881
  var GATEWAY_MODELS_MAX_BYTES = 2 * 1024 * 1024;
43693
43882
  var OFFICIAL_ANTHROPIC_HOST = "api.anthropic.com";
@@ -43729,14 +43918,14 @@ function claudeConfigDirectory(environment) {
43729
43918
  if (configured)
43730
43919
  return configured;
43731
43920
  const home = trimmedEnv(environment, "HOME") ?? trimmedEnv(environment, "USERPROFILE");
43732
- return home ? path8.join(home, ".claude") : void 0;
43921
+ return home ? path9.join(home, ".claude") : void 0;
43733
43922
  }
43734
43923
  async function readClaudeUserSettingsEnv(environment) {
43735
43924
  const configDir = claudeConfigDirectory(environment);
43736
43925
  if (!configDir)
43737
43926
  return {};
43738
43927
  try {
43739
- const raw = await readFile3(path8.join(configDir, "settings.json"), "utf8");
43928
+ const raw = await readFile4(path9.join(configDir, "settings.json"), "utf8");
43740
43929
  const parsed = JSON.parse(raw);
43741
43930
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
43742
43931
  return {};
@@ -43868,7 +44057,7 @@ async function applyGatewayModelCatalog(snapshot, environment, dependencies = {}
43868
44057
  }
43869
44058
 
43870
44059
  // dist/file-change.js
43871
- import path9 from "node:path";
44060
+ import path10 from "node:path";
43872
44061
  var hunkSchema = external_exports.object({
43873
44062
  oldStart: external_exports.number().int().nonnegative(),
43874
44063
  oldLines: external_exports.number().int().nonnegative(),
@@ -43916,10 +44105,10 @@ function parseClaudeNativeFileChange(toolName, value) {
43916
44105
  };
43917
44106
  }
43918
44107
  function displayPath(nativePath, cwd) {
43919
- const resolvedCwd = path9.resolve(cwd);
43920
- const resolvedPath = path9.isAbsolute(nativePath) ? path9.resolve(nativePath) : path9.resolve(cwd, nativePath);
43921
- const relative = path9.relative(resolvedCwd, resolvedPath);
43922
- const selected = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path9.sep}`) ? relative : resolvedPath;
44108
+ const resolvedCwd = path10.resolve(cwd);
44109
+ const resolvedPath = path10.isAbsolute(nativePath) ? path10.resolve(nativePath) : path10.resolve(cwd, nativePath);
44110
+ const relative = path10.relative(resolvedCwd, resolvedPath);
44111
+ const selected = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path10.sep}`) ? relative : resolvedPath;
43923
44112
  const normalized = selected.replaceAll("\\", "/");
43924
44113
  return validNativePath(normalized) && normalized !== "." ? normalized : null;
43925
44114
  }
@@ -43931,7 +44120,7 @@ function projectClaudeFileChange(value, cwd) {
43931
44120
  `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`,
43932
44121
  ...hunk.lines
43933
44122
  ]);
43934
- const absoluteDisplayPath = path9.posix.isAbsolute(normalizedPath);
44123
+ const absoluteDisplayPath = path10.posix.isAbsolute(normalizedPath);
43935
44124
  const oldHeader = value.kind === "add" ? "/dev/null" : absoluteDisplayPath ? normalizedPath : `a/${normalizedPath}`;
43936
44125
  const newHeader = absoluteDisplayPath ? normalizedPath : `b/${normalizedPath}`;
43937
44126
  const unifiedDiff = [`--- ${oldHeader}`, `+++ ${newHeader}`, ...body, ""].join("\n");
@@ -44625,6 +44814,59 @@ var ClaudeNativeTurnAccumulator = class {
44625
44814
  }
44626
44815
  };
44627
44816
 
44817
+ // dist/process-fence.js
44818
+ import { execFile } from "node:child_process";
44819
+ import path11 from "node:path";
44820
+ import { setTimeout as setTimeout2 } from "node:timers/promises";
44821
+ import { promisify } from "node:util";
44822
+ var executeFile = promisify(execFile);
44823
+ function signalGroup(pid, signal) {
44824
+ try {
44825
+ process.kill(-pid, signal);
44826
+ return true;
44827
+ } catch (error52) {
44828
+ if (error52.code === "ESRCH")
44829
+ return false;
44830
+ if (signal === 0 && error52.code === "EPERM")
44831
+ return true;
44832
+ throw error52;
44833
+ }
44834
+ }
44835
+ async function closeClaudeProcessGroup(child, timeoutMs) {
44836
+ const pid = child.pid;
44837
+ if (!pid)
44838
+ return;
44839
+ if (process.platform === "win32") {
44840
+ if (child.exitCode !== null || child.signalCode !== null)
44841
+ throw new Error("Claude process tree cannot be confirmed after its Windows root exited");
44842
+ const root = process.env.SystemRoot ?? process.env.SYSTEMROOT;
44843
+ if (!root || !path11.win32.isAbsolute(root))
44844
+ throw new Error("Windows SystemRoot is unavailable");
44845
+ await executeFile(path11.win32.join(root, "System32", "taskkill.exe"), ["/PID", String(pid), "/T", "/F"], {
44846
+ timeout: timeoutMs,
44847
+ windowsHide: true
44848
+ });
44849
+ return;
44850
+ }
44851
+ if (!signalGroup(pid, "SIGTERM"))
44852
+ return;
44853
+ const gracefulDeadline = Date.now() + timeoutMs;
44854
+ while (Date.now() < gracefulDeadline) {
44855
+ if (!signalGroup(pid, 0))
44856
+ return;
44857
+ await setTimeout2(10);
44858
+ }
44859
+ if (!signalGroup(pid, "SIGKILL"))
44860
+ return;
44861
+ const deadline = Date.now() + timeoutMs;
44862
+ while (Date.now() < deadline) {
44863
+ if (!signalGroup(pid, 0))
44864
+ return;
44865
+ await setTimeout2(10);
44866
+ }
44867
+ throw new Error("Claude SDK process group did not exit");
44868
+ }
44869
+
44628
44870
  // dist/sdk-transport.js
44629
44871
  var CLIENT_APP = "codexhost-claude-code-adapter/0.0.0";
44630
44872
  var APPROVAL_TITLE_MAX_LENGTH = 120;
@@ -44875,6 +45117,7 @@ var ClaudeSdkTransport = class {
44875
45117
  #provider;
44876
45118
  #query = null;
44877
45119
  #started = false;
45120
+ #backgroundTasks = /* @__PURE__ */ new Set();
44878
45121
  constructor(options) {
44879
45122
  this.sessionId = options.sessionId;
44880
45123
  this.#cwd = options.cwd;
@@ -44994,7 +45237,7 @@ var ClaudeSdkTransport = class {
44994
45237
  return this.runTurn("/recap", userMessageId, onEvent);
44995
45238
  }
44996
45239
  runTurn(input, userMessageId, onEvent) {
44997
- if (!this.#started || !this.#query) {
45240
+ if (this.#closePromise || !this.#started || !this.#query) {
44998
45241
  return Promise.reject(new Error("Claude SDK transport is not started"));
44999
45242
  }
45000
45243
  if (this.#active)
@@ -45149,25 +45392,56 @@ var ClaudeSdkTransport = class {
45149
45392
  }
45150
45393
  }
45151
45394
  async #close() {
45395
+ const failures = [];
45152
45396
  if (this.#active)
45153
45397
  this.#closeInteractions(this.#active, "cancelled");
45398
+ try {
45399
+ const timeout = rejectAfter(this.#closeTimeoutMs, "Claude background tasks did not stop");
45400
+ try {
45401
+ await Promise.race([this.#stopBackgroundTasks(), timeout.promise]);
45402
+ } finally {
45403
+ timeout.cancel();
45404
+ }
45405
+ } catch (error52) {
45406
+ failures.push(error52);
45407
+ }
45408
+ const stopOwnedProcesses = async () => {
45409
+ const stopped = await Promise.allSettled(this.#children.map((child) => closeClaudeProcessGroup(child, this.#closeTimeoutMs)));
45410
+ for (const result of stopped)
45411
+ if (result.status === "rejected")
45412
+ failures.push(result.reason);
45413
+ };
45414
+ if (process.platform === "win32")
45415
+ await stopOwnedProcesses();
45154
45416
  this.#input.end();
45155
- this.#query?.close();
45156
- await Promise.race([
45157
- this.#consumeTask?.catch(() => void 0) ?? Promise.resolve(),
45158
- delay(this.#closeTimeoutMs)
45159
- ]);
45160
- for (const child of this.#children) {
45161
- if (!processExited(child))
45162
- child.kill("SIGTERM");
45417
+ try {
45418
+ this.#query?.close();
45419
+ } catch (error52) {
45420
+ failures.push(error52);
45163
45421
  }
45164
- await Promise.race([
45165
- Promise.all(this.#children.map((child) => this.#waitForExit(child))),
45166
- delay(this.#closeTimeoutMs)
45167
- ]);
45168
- for (const child of this.#children) {
45169
- if (!processExited(child))
45170
- child.kill("SIGKILL");
45422
+ if (process.platform !== "win32")
45423
+ await stopOwnedProcesses();
45424
+ const exitTimeout = rejectAfter(this.#closeTimeoutMs, "Claude SDK process did not exit");
45425
+ try {
45426
+ await Promise.race([
45427
+ Promise.all(this.#children.map((child) => this.#waitForExit(child))),
45428
+ exitTimeout.promise
45429
+ ]);
45430
+ } catch (error52) {
45431
+ failures.push(error52);
45432
+ } finally {
45433
+ exitTimeout.cancel();
45434
+ }
45435
+ const drainTimeout = rejectAfter(this.#closeTimeoutMs, "Claude SDK output did not drain");
45436
+ try {
45437
+ await Promise.race([
45438
+ this.#consumeTask?.catch(() => void 0) ?? Promise.resolve(),
45439
+ drainTimeout.promise
45440
+ ]);
45441
+ } catch (error52) {
45442
+ failures.push(error52);
45443
+ } finally {
45444
+ drainTimeout.cancel();
45171
45445
  }
45172
45446
  this.#query = null;
45173
45447
  const active = this.#active;
@@ -45176,10 +45450,40 @@ var ClaudeSdkTransport = class {
45176
45450
  this.#idleAccumulator = null;
45177
45451
  this.#idleLive = false;
45178
45452
  active?.reject(new Error("Claude SDK transport closed"));
45453
+ if (failures.length > 0)
45454
+ throw new AggregateError(failures, "Claude SDK shutdown could not be confirmed");
45455
+ }
45456
+ async #stopBackgroundTasks() {
45457
+ const requested = /* @__PURE__ */ new Set();
45458
+ const deadline = Date.now() + this.#closeTimeoutMs;
45459
+ while (this.#backgroundTasks.size > 0) {
45460
+ if (Date.now() >= deadline || !this.#query)
45461
+ throw new Error("Claude background tasks remain active");
45462
+ for (const id of this.#backgroundTasks) {
45463
+ if (requested.has(id))
45464
+ continue;
45465
+ requested.add(id);
45466
+ await this.#query.stopTask(id);
45467
+ }
45468
+ if (this.#backgroundTasks.size > 0)
45469
+ await delay(10);
45470
+ }
45471
+ }
45472
+ #observeBackgroundTasks(message) {
45473
+ if (!isRecord6(message) || message.type !== "system")
45474
+ return;
45475
+ if (message.subtype === "background_tasks_changed" && Array.isArray(message.tasks)) {
45476
+ this.#backgroundTasks = new Set(message.tasks.flatMap((task) => isRecord6(task) && typeof task.task_id === "string" ? [task.task_id] : []));
45477
+ } else if (message.subtype === "task_started" && typeof message.task_id === "string") {
45478
+ this.#backgroundTasks.add(message.task_id);
45479
+ } else if (message.subtype === "task_notification" && typeof message.task_id === "string" && ["completed", "failed", "stopped"].includes(String(message.status))) {
45480
+ this.#backgroundTasks.delete(message.task_id);
45481
+ }
45179
45482
  }
45180
45483
  async #consume(activeQuery) {
45181
45484
  try {
45182
45485
  for await (const message of activeQuery) {
45486
+ this.#observeBackgroundTasks(message);
45183
45487
  const permissionMode = permissionModeFromMessage(message);
45184
45488
  if (permissionMode && permissionMode !== this.#permissionMode) {
45185
45489
  this.#permissionMode = permissionMode;
@@ -45256,7 +45560,8 @@ var ClaudeSdkTransport = class {
45256
45560
  env: options.env,
45257
45561
  signal: options.signal,
45258
45562
  stdio: ["pipe", "pipe", "pipe"],
45259
- windowsHide: true
45563
+ windowsHide: true,
45564
+ detached: process.platform !== "win32"
45260
45565
  });
45261
45566
  child.stderr.on("data", (chunk) => {
45262
45567
  this.#stderrTail = sanitizeDiagnosticTail(`${this.#stderrTail}${chunk.toString()}`);
@@ -46071,6 +46376,10 @@ var ClaudeHarnessSession = class {
46071
46376
  #onClosed;
46072
46377
  #onPlanLimitObserved;
46073
46378
  #openMode;
46379
+ #pendingSessions;
46380
+ #pendingClaimed = false;
46381
+ #submittedInput = false;
46382
+ #startupTask = null;
46074
46383
  #randomUUID;
46075
46384
  #requestedModel;
46076
46385
  #requestedPermissionModeId;
@@ -46088,7 +46397,9 @@ var ClaudeHarnessSession = class {
46088
46397
  #readingHistory = false;
46089
46398
  #state;
46090
46399
  #statePublished = false;
46400
+ #unpersistedMessageIds = [];
46091
46401
  #transport = null;
46402
+ #hardCancelTask = null;
46092
46403
  #usageGeneration = 0;
46093
46404
  #latestUsage = null;
46094
46405
  #minimumContextUsedTokens = null;
@@ -46115,6 +46426,7 @@ var ClaudeHarnessSession = class {
46115
46426
  #continuationQuiescence = null;
46116
46427
  constructor(cwd, dependencies, closeTimeoutMs, onClosed, onPlanLimitObserved, options) {
46117
46428
  this.#cwd = cwd;
46429
+ this.#pendingSessions = options.pendingSessions;
46118
46430
  const environment = options.environment;
46119
46431
  this.#createTransport = environment ? (input) => dependencies.createTransport({ ...input, environment }) : dependencies.createTransport;
46120
46432
  this.#randomUUID = dependencies.randomUUID;
@@ -46130,7 +46442,7 @@ var ClaudeHarnessSession = class {
46130
46442
  this.#sessionId = options.sessionId;
46131
46443
  this.#toolOutputLimit = options.toolOutputLimit;
46132
46444
  this.#continuationQuiescenceMs = options.continuationQuiescenceMs;
46133
- this.#nativeRef = nativeSessionRefSchema.parse({
46445
+ this.#nativeRef = options.nativeRef ?? nativeSessionRefSchema.parse({
46134
46446
  harnessId: this.harnessId,
46135
46447
  nativeSessionId: this.#sessionId,
46136
46448
  formatVersion: 1
@@ -46139,9 +46451,17 @@ var ClaudeHarnessSession = class {
46139
46451
  list: async () => ({ ok: true, value: claudeCommandCatalog }),
46140
46452
  execute: (command) => this.#executeHarnessCommand(command)
46141
46453
  };
46142
- this.initialState = this.#openMode === "resume" ? { nativeRef: this.#nativeRef } : {};
46454
+ const durable = this.#openMode === "resume" || options.nativeRef !== void 0;
46455
+ this.initialState = durable ? {
46456
+ nativeRef: this.#nativeRef,
46457
+ ...options.knownConfiguration ? {
46458
+ ...options.requestedModel ? { effectiveModel: options.requestedModel } : {},
46459
+ effectiveThinkingOptionId: this.#requestedThinkingOptionId,
46460
+ effectivePermissionModeId: this.#requestedPermissionModeId
46461
+ } : {}
46462
+ } : {};
46143
46463
  this.#state = this.initialState;
46144
- this.#statePublished = this.#openMode === "resume";
46464
+ this.#statePublished = durable;
46145
46465
  this.outputs = this.#channel.outputs;
46146
46466
  }
46147
46467
  async readSnapshot() {
@@ -46164,7 +46484,29 @@ var ClaudeHarnessSession = class {
46164
46484
  try {
46165
46485
  let messages;
46166
46486
  try {
46167
- messages = await this.#readSessionMessages({ cwd: this.#cwd, sessionId: this.#sessionId });
46487
+ const deadline = Date.now() + this.#closeTimeoutMs;
46488
+ for (; ; ) {
46489
+ messages = await this.#readSessionMessages({
46490
+ cwd: this.#cwd,
46491
+ sessionId: this.#sessionId
46492
+ });
46493
+ const ids = new Set(messages.flatMap((message) => isRecord9(message) && typeof message.uuid === "string" ? [message.uuid] : []));
46494
+ if (this.#unpersistedMessageIds.every((id) => ids.has(id))) {
46495
+ this.#unpersistedMessageIds = [];
46496
+ break;
46497
+ }
46498
+ if (Date.now() >= deadline || this.#phase !== "open") {
46499
+ return {
46500
+ ok: false,
46501
+ error: {
46502
+ code: "sessionBusy",
46503
+ message: "Claude Code history is still being persisted",
46504
+ retryable: true
46505
+ }
46506
+ };
46507
+ }
46508
+ await delay2(25);
46509
+ }
46168
46510
  } catch {
46169
46511
  return {
46170
46512
  ok: false,
@@ -46175,6 +46517,22 @@ var ClaudeHarnessSession = class {
46175
46517
  }
46176
46518
  };
46177
46519
  }
46520
+ if (messages.length === 0 && isPendingClaudeSession(this.#nativeRef)) {
46521
+ try {
46522
+ const pending = await this.#pendingSessions.read(this.#nativeRef, this.#cwd);
46523
+ if (!pending.started)
46524
+ return { ok: true, value: { turns: [], state: this.#state } };
46525
+ } catch {
46526
+ return {
46527
+ ok: false,
46528
+ error: {
46529
+ code: "sessionNotFound",
46530
+ message: "Claude Code pending Session is unavailable",
46531
+ retryable: false
46532
+ }
46533
+ };
46534
+ }
46535
+ }
46178
46536
  if (messages.length === 0) {
46179
46537
  return {
46180
46538
  ok: false,
@@ -46319,6 +46677,7 @@ var ClaudeHarnessSession = class {
46319
46677
  resolveCompletion
46320
46678
  };
46321
46679
  this.#active = active;
46680
+ this.#submittedInput = true;
46322
46681
  this.#event({ type: "turn.started", turnId: command.turnId });
46323
46682
  this.#event({ type: "item.started", turnId: command.turnId, item });
46324
46683
  try {
@@ -46426,6 +46785,7 @@ var ClaudeHarnessSession = class {
46426
46785
  resolveCompletion
46427
46786
  };
46428
46787
  this.#active = active;
46788
+ this.#submittedInput = true;
46429
46789
  this.#event({ type: "turn.started", turnId: command.turnId });
46430
46790
  if (item)
46431
46791
  this.#event({ type: "item.started", turnId: command.turnId, item });
@@ -46447,6 +46807,12 @@ var ClaudeHarnessSession = class {
46447
46807
  this.#requestContextUsage(this.#transport, this.#active?.command.turnId, CONTEXT_USAGE_RETRY_DELAYS_MS);
46448
46808
  return this.#contextRefreshInFlight ?? Promise.resolve();
46449
46809
  }
46810
+ blocksRollback(sessionId) {
46811
+ return this.#sessionId === sessionId && (this.#phase !== "open" || this.#active !== null || this.#acceptingTurn || this.#configurationTask !== null || this.#readingHistory);
46812
+ }
46813
+ async prepareRollback(sessionId) {
46814
+ return this.#sessionId === sessionId ? this.readSnapshot() : { ok: true, value: null };
46815
+ }
46450
46816
  close() {
46451
46817
  if (!this.#closePromise)
46452
46818
  this.#closePromise = this.#close();
@@ -46500,6 +46866,9 @@ var ClaudeHarnessSession = class {
46500
46866
  }
46501
46867
  }
46502
46868
  this.#requestedModel = command.model;
46869
+ const persistenceError = await this.#savePendingConfiguration();
46870
+ if (persistenceError)
46871
+ return { ok: false, error: persistenceError };
46503
46872
  this.#publishState(this.#configuredState());
46504
46873
  return { ok: true, value: { completed: true } };
46505
46874
  } finally {
@@ -46555,6 +46924,9 @@ var ClaudeHarnessSession = class {
46555
46924
  }
46556
46925
  }
46557
46926
  this.#requestedThinkingOptionId = thinkingOptionId;
46927
+ const persistenceError = await this.#savePendingConfiguration();
46928
+ if (persistenceError)
46929
+ return { ok: false, error: persistenceError };
46558
46930
  this.#publishState(this.#configuredState());
46559
46931
  return { ok: true, value: { completed: true } };
46560
46932
  } finally {
@@ -46611,6 +46983,9 @@ var ClaudeHarnessSession = class {
46611
46983
  }
46612
46984
  }
46613
46985
  this.#requestedPermissionModeId = transport ? encodeClaudePermissionModeId(transport.getPermissionMode()) : command.permissionModeId;
46986
+ const persistenceError = await this.#savePendingConfiguration();
46987
+ if (persistenceError)
46988
+ return { ok: false, error: persistenceError };
46614
46989
  this.#publishState(this.#configuredState());
46615
46990
  return { ok: true, value: { completed: true } };
46616
46991
  } finally {
@@ -46743,6 +47118,7 @@ var ClaudeHarnessSession = class {
46743
47118
  async #close() {
46744
47119
  if (this.#phase === "closed")
46745
47120
  return;
47121
+ this.#phase = "closing";
46746
47122
  this.#usageGeneration += 1;
46747
47123
  this.#contextUsageFreshUntilMs = 0;
46748
47124
  this.#contextUsageCooldownUntilMs = 0;
@@ -46752,78 +47128,133 @@ var ClaudeHarnessSession = class {
46752
47128
  this.#contextRefreshWake = null;
46753
47129
  this.#clearCancelEscalation();
46754
47130
  this.#clearContinuationQuiescence();
46755
- if (this.#phase !== "faulted")
46756
- this.#phase = "closing";
46757
- const configurationTask = this.#configurationTask;
46758
- if (configurationTask) {
46759
- await Promise.race([configurationTask, delay2(this.#closeTimeoutMs)]);
46760
- }
46761
- let transportClosed = false;
46762
- const active = this.#active;
46763
- if (active) {
46764
- active.cancellationRequested = true;
46765
- if (active.held) {
46766
- this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
46767
- } else {
46768
- await this.#transport?.abort().catch(() => void 0);
46769
- await Promise.race([active.completion, delay2(this.#closeTimeoutMs)]);
46770
- if (this.#active === active) {
46771
- await this.#transport?.close().catch(() => void 0);
46772
- transportClosed = true;
46773
- this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
46774
- }
47131
+ const failures = [];
47132
+ const settle = async (task) => {
47133
+ if (!task)
47134
+ return;
47135
+ const timeout = rejectAfter2(this.#closeTimeoutMs * 4, "Claude Code Session close timed out");
47136
+ try {
47137
+ await Promise.race([task, timeout.promise]);
47138
+ } catch (error52) {
47139
+ failures.push(error52);
47140
+ } finally {
47141
+ timeout.cancel();
46775
47142
  }
46776
- }
46777
- if (!transportClosed)
46778
- await this.#transport?.close().catch(() => void 0);
47143
+ };
47144
+ const closingTransport = this.#transport;
47145
+ await settle(closingTransport?.close());
47146
+ await settle(this.#configurationTask ?? void 0);
47147
+ await settle(this.#startupTask?.then(() => void 0, () => void 0));
47148
+ if (this.#transport !== closingTransport)
47149
+ await settle(this.#transport?.close());
47150
+ if (failures.length === 0)
47151
+ await settle(this.#releaseUnusedClaim());
47152
+ const active = this.#active;
47153
+ if (active)
47154
+ this.#finishFailed(active, invalidState("Claude Code Session closed during active Turn"));
46779
47155
  this.#phase = "closed";
46780
47156
  this.#channel.end();
46781
47157
  this.#onClosed();
47158
+ if (failures.length > 0)
47159
+ throw new AggregateError(failures, "Claude Code Session could not stop safely");
46782
47160
  }
46783
- async #ensureTransport() {
47161
+ #ensureTransport() {
47162
+ if (this.#startupTask)
47163
+ return this.#startupTask;
46784
47164
  if (this.#transport)
46785
- return this.#transport;
47165
+ return Promise.resolve(this.#transport);
47166
+ const task = this.#startTransport();
47167
+ this.#startupTask = task;
47168
+ void task.finally(() => {
47169
+ if (this.#startupTask === task)
47170
+ this.#startupTask = null;
47171
+ }).catch(() => void 0);
47172
+ return task;
47173
+ }
47174
+ async #startTransport() {
47175
+ if (this.#openMode === "create" && isPendingClaudeSession(this.#nativeRef)) {
47176
+ await this.#pendingSessions.claim(this.#nativeRef, this.#cwd);
47177
+ this.#pendingClaimed = true;
47178
+ }
47179
+ if (this.#phase !== "open") {
47180
+ await this.#releaseUnusedClaim();
47181
+ throw new Error("Claude Code Session closed during startup");
47182
+ }
46786
47183
  const selectedModel = this.#requestedModel ?? (this.#openMode === "create" ? CLAUDE_DEFAULT_MODEL_REF : void 0);
46787
47184
  const model = selectedModel ? decodeClaudeModelRef(selectedModel) : void 0;
46788
47185
  const permissionMode = decodeClaudePermissionModeId(this.#requestedPermissionModeId);
46789
- const transport = this.#createTransport({
46790
- cwd: this.#cwd,
46791
- sessionId: this.#sessionId,
46792
- openMode: this.#openMode,
46793
- ...model ? { model } : {},
46794
- thinkingOptionId: this.#requestedThinkingOptionId,
46795
- permissionMode,
46796
- onPermissionModeChanged: (mode) => this.#handlePermissionModeChanged(mode),
46797
- onFault: () => this.#fault(faultError()),
46798
- onPlanLimit: (planLimit) => this.#handlePlanLimit(planLimit)
46799
- });
46800
- transport.setAutonomousTurnHandler((turn) => this.#handleAutonomousTurn(turn));
46801
- transport.setIdleTurnHandler({
46802
- onEvent: (event) => {
46803
- const active = this.#active;
46804
- if (active)
46805
- this.#handleTurnEvent(active, event);
46806
- },
46807
- onTerminal: (result) => {
46808
- const active = this.#active;
46809
- if (active)
46810
- this.#finishResult(active, result);
46811
- }
46812
- });
47186
+ let transport;
46813
47187
  try {
47188
+ transport = this.#createTransport({
47189
+ cwd: this.#cwd,
47190
+ sessionId: this.#sessionId,
47191
+ openMode: this.#openMode,
47192
+ ...model ? { model } : {},
47193
+ thinkingOptionId: this.#requestedThinkingOptionId,
47194
+ permissionMode,
47195
+ onPermissionModeChanged: (mode) => this.#handlePermissionModeChanged(mode),
47196
+ onFault: () => this.#fault(faultError()),
47197
+ onPlanLimit: (planLimit) => this.#handlePlanLimit(planLimit)
47198
+ });
47199
+ this.#transport = transport;
47200
+ transport.setAutonomousTurnHandler((turn) => this.#handleAutonomousTurn(turn));
47201
+ transport.setIdleTurnHandler({
47202
+ onEvent: (event) => {
47203
+ const active = this.#active;
47204
+ if (active)
47205
+ this.#handleTurnEvent(active, event);
47206
+ },
47207
+ onTerminal: (result) => {
47208
+ const active = this.#active;
47209
+ if (active)
47210
+ this.#finishResult(active, result);
47211
+ }
47212
+ });
46814
47213
  await transport.start();
46815
47214
  this.#state = {
46816
47215
  ...this.#configuredState(true),
46817
47216
  effectivePermissionModeId: encodeClaudePermissionModeId(transport.getPermissionMode())
46818
47217
  };
46819
47218
  } catch (error52) {
46820
- await transport.close().catch(() => void 0);
47219
+ try {
47220
+ await this.#transport?.close();
47221
+ } catch (closeError) {
47222
+ this.#fault(faultError());
47223
+ throw closeError;
47224
+ }
47225
+ this.#transport = null;
47226
+ await this.#releaseUnusedClaim();
46821
47227
  throw error52;
46822
47228
  }
46823
47229
  this.#openMode = "resume";
46824
47230
  this.#transport = transport;
46825
47231
  return transport;
46826
47232
  }
47233
+ async #releaseUnusedClaim() {
47234
+ if (!this.#pendingClaimed || this.#submittedInput)
47235
+ return;
47236
+ await this.#pendingSessions.release(this.#nativeRef, this.#cwd);
47237
+ this.#pendingClaimed = false;
47238
+ this.#openMode = "create";
47239
+ }
47240
+ async #savePendingConfiguration() {
47241
+ if (!isPendingClaudeSession(this.#nativeRef))
47242
+ return null;
47243
+ const configuration = { ...this.#configuredState() };
47244
+ delete configuration.nativeRef;
47245
+ try {
47246
+ await this.#pendingSessions.saveConfiguration(this.#nativeRef, this.#cwd, configuration);
47247
+ return null;
47248
+ } catch {
47249
+ const error52 = {
47250
+ code: "nativeFailure",
47251
+ message: "Claude Code pending configuration could not be persisted",
47252
+ retryable: false
47253
+ };
47254
+ this.#fault(error52);
47255
+ return error52;
47256
+ }
47257
+ }
46827
47258
  #configuredState(nativeReady = this.#state.nativeRef !== void 0) {
46828
47259
  const effectiveModel = this.#requestedModel ?? (this.#openMode === "create" ? CLAUDE_DEFAULT_MODEL_REF : this.#state.effectiveModel);
46829
47260
  return {
@@ -47312,7 +47743,7 @@ var ClaudeHarnessSession = class {
47312
47743
  }
47313
47744
  }
47314
47745
  #finishResult(active, result) {
47315
- if (this.#active !== active)
47746
+ if (this.#active !== active || this.#hardCancelTask)
47316
47747
  return;
47317
47748
  if (result.status === "succeeded" && (active.tools.size > 0 || active.subagents.size > 0)) {
47318
47749
  this.#finishFailed(active, transportFailure("protocol"));
@@ -47649,6 +48080,12 @@ var ClaudeHarnessSession = class {
47649
48080
  checkpointId: active.checkpointId,
47650
48081
  formatVersion: 1
47651
48082
  }) : null;
48083
+ this.#unpersistedMessageIds = [
48084
+ .../* @__PURE__ */ new Set([
48085
+ ...active.nativeTurnRef ? [active.nativeTurnRef.nativeTurnKey] : [],
48086
+ ...active.checkpointId ? [active.checkpointId] : []
48087
+ ])
48088
+ ];
47652
48089
  this.#event({
47653
48090
  type: "turn.completed",
47654
48091
  turnId: active.command.turnId,
@@ -47688,14 +48125,19 @@ var ClaudeHarnessSession = class {
47688
48125
  this.#cancelEscalation = null;
47689
48126
  }
47690
48127
  #hardCancel(active) {
47691
- if (this.#active !== active)
48128
+ if (this.#active !== active || this.#hardCancelTask)
47692
48129
  return;
47693
48130
  this.#clearCancelEscalation();
47694
48131
  const transport = this.#transport;
47695
- this.#transport = null;
47696
- this.#openMode = "resume";
47697
- this.#finish(active, { status: "cancelled", reason: "Cancelled by user" });
47698
- void transport?.close().catch(() => void 0);
48132
+ this.#hardCancelTask = Promise.resolve().then(() => transport?.close()).then(() => {
48133
+ if (this.#phase !== "open" || this.#active !== active)
48134
+ return;
48135
+ this.#transport = null;
48136
+ this.#openMode = "resume";
48137
+ this.#finish(active, { status: "cancelled", reason: "Cancelled by user" });
48138
+ }, () => this.#fault(faultError())).finally(() => {
48139
+ this.#hardCancelTask = null;
48140
+ });
47699
48141
  }
47700
48142
  #fault(error52) {
47701
48143
  if (this.#phase === "closed" || this.#phase === "closing" || this.#phase === "faulted")
@@ -47714,8 +48156,7 @@ var ClaudeHarnessSession = class {
47714
48156
  this.#phase = "faulted";
47715
48157
  this.#event({ type: "session.faulted", error: error52 });
47716
48158
  this.#channel.end();
47717
- void this.#transport?.close();
47718
- this.#onClosed();
48159
+ void this.#transport?.close().catch(() => void 0);
47719
48160
  }
47720
48161
  #event(event) {
47721
48162
  this.#channel.emit({ kind: "event", event });
@@ -47789,6 +48230,7 @@ var ClaudeCodeAdapter = class {
47789
48230
  #importAbort = new AbortController();
47790
48231
  #importIndex;
47791
48232
  #importRequests = /* @__PURE__ */ new Set();
48233
+ #pendingSessions;
47792
48234
  #toolOutputLimit;
47793
48235
  #continuationQuiescenceMs;
47794
48236
  #inspectionCache = /* @__PURE__ */ new Map();
@@ -47799,6 +48241,7 @@ var ClaudeCodeAdapter = class {
47799
48241
  #latestPlanLimit = null;
47800
48242
  #accountInspection = null;
47801
48243
  constructor(options = {}, dependencies) {
48244
+ this.#pendingSessions = new ClaudePendingSessions(options.environment ?? process.env);
47802
48245
  this.#closeTimeoutMs = options.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS;
47803
48246
  this.#cancelTimeoutMs = options.cancelTimeoutMs ?? DEFAULT_CANCEL_TIMEOUT_MS;
47804
48247
  if (!Number.isSafeInteger(this.#cancelTimeoutMs) || this.#cancelTimeoutMs <= 0) {
@@ -47813,7 +48256,7 @@ var ClaudeCodeAdapter = class {
47813
48256
  throw new RangeError("Claude Code continuation quiescence must be a positive safe integer");
47814
48257
  }
47815
48258
  this.#dependencies = dependencies ?? {
47816
- randomUUID: randomUUID2,
48259
+ randomUUID: randomUUID3,
47817
48260
  inspectInstallation: () => {
47818
48261
  resolveClaudeCodeExecutable({
47819
48262
  ...options.command ? { command: options.command } : {},
@@ -47893,7 +48336,7 @@ var ClaudeCodeAdapter = class {
47893
48336
  error: invalidState("Claude Code Adapter is closing")
47894
48337
  };
47895
48338
  }
47896
- const cwd = path10.resolve(input.cwd ?? process.cwd());
48339
+ const cwd = path12.resolve(input.cwd ?? process.cwd());
47897
48340
  if (!input.refresh) {
47898
48341
  const cached2 = this.#inspectionCache.get(cwd);
47899
48342
  if (cached2)
@@ -48023,79 +48466,18 @@ var ClaudeCodeAdapter = class {
48023
48466
  }
48024
48467
  };
48025
48468
  }
48026
- let rollback;
48027
- if (input.kind === "rollbackLastTurn") {
48028
- const sourceRef = nativeSessionRefSchema.safeParse(input.sourceRef);
48029
- if (!sourceRef.success || sourceRef.data.harnessId !== this.harnessId) {
48030
- return {
48031
- ok: false,
48032
- error: {
48033
- code: "invalidRequest",
48034
- message: "Claude Code cannot roll back another Harness's Native Session",
48035
- retryable: false
48036
- }
48037
- };
48038
- }
48039
- let sourceSnapshot;
48040
- try {
48041
- const messages = await this.#dependencies.readSessionMessages({
48042
- cwd: path10.resolve(input.cwd),
48043
- sessionId: sourceRef.data.nativeSessionId
48044
- });
48045
- sourceSnapshot = mapClaudeSnapshot(messages, sourceRef.data.nativeSessionId);
48046
- } catch {
48047
- return {
48048
- ok: false,
48049
- error: {
48050
- code: "nativeFailure",
48051
- message: "Claude Code history could not be read",
48052
- retryable: true
48053
- }
48054
- };
48055
- }
48056
- if (sourceSnapshot.turns.length === 0) {
48057
- return {
48058
- ok: false,
48059
- error: {
48060
- code: "invalidState",
48061
- message: "Claude Code Native Session has no Turn to roll back",
48062
- retryable: false
48063
- }
48064
- };
48065
- }
48066
- const retained = sourceSnapshot.turns.at(-2);
48067
- if (!retained) {
48068
- rollback = {
48069
- openMode: "create",
48070
- sessionId: this.#dependencies.randomUUID()
48071
- };
48072
- } else if (!retained.checkpoint?.checkpointId) {
48073
- return {
48074
- ok: false,
48075
- error: {
48076
- code: "checkpointNotFound",
48077
- message: "Claude Code last-Turn rollback boundary is unavailable",
48078
- retryable: false
48079
- }
48080
- };
48081
- } else {
48082
- const forked2 = await forkClaudeSession({
48083
- checkpoint: retained.checkpoint,
48084
- cwd: path10.resolve(input.cwd),
48085
- dependencies: this.#dependencies,
48086
- harnessId: this.harnessId,
48087
- sourceRef: sourceRef.data
48088
- });
48089
- if (!forked2.ok)
48090
- return forked2;
48091
- rollback = {
48092
- openMode: "resume",
48093
- sessionId: forked2.value.sessionId
48094
- };
48095
- }
48469
+ if (input.kind === "rollbackLastTurn" && [...this.#sessions].some((session2) => session2.blocksRollback(input.sourceRef.nativeSessionId))) {
48470
+ return {
48471
+ ok: false,
48472
+ error: {
48473
+ code: "sessionBusy",
48474
+ message: "Claude Code Session is busy during rollback",
48475
+ retryable: true
48476
+ }
48477
+ };
48096
48478
  }
48097
48479
  let requestedThinkingOptionId = CLAUDE_DEFAULT_THINKING_OPTION_ID;
48098
- if (input.kind === "create" && input.thinkingOptionId) {
48480
+ if ((input.kind === "create" || input.kind === "rollbackLastTurn" || input.kind === "resume") && input.thinkingOptionId) {
48099
48481
  try {
48100
48482
  requestedThinkingOptionId = parseClaudeThinkingOptionId(input.thinkingOptionId);
48101
48483
  } catch {
@@ -48109,7 +48491,7 @@ var ClaudeCodeAdapter = class {
48109
48491
  };
48110
48492
  }
48111
48493
  }
48112
- if (input.kind === "create" && input.model) {
48494
+ if ((input.kind === "create" || input.kind === "rollbackLastTurn" || input.kind === "resume") && input.model) {
48113
48495
  try {
48114
48496
  decodeClaudeModelRef(input.model);
48115
48497
  } catch {
@@ -48123,7 +48505,7 @@ var ClaudeCodeAdapter = class {
48123
48505
  };
48124
48506
  }
48125
48507
  }
48126
- const requestedPermissionModeId = input.kind === "create" ? input.permissionModeId ?? (input.executionPolicy === "unattended-full-access" ? encodeClaudePermissionModeId("auto") : CLAUDE_DEFAULT_PERMISSION_MODE_ID) : CLAUDE_DEFAULT_PERMISSION_MODE_ID;
48508
+ let requestedPermissionModeId = input.kind === "create" ? input.permissionModeId ?? (input.executionPolicy === "unattended-full-access" ? encodeClaudePermissionModeId("auto") : CLAUDE_DEFAULT_PERMISSION_MODE_ID) : input.kind === "rollbackLastTurn" || input.kind === "resume" ? input.permissionModeId ?? CLAUDE_DEFAULT_PERMISSION_MODE_ID : CLAUDE_DEFAULT_PERMISSION_MODE_ID;
48127
48509
  try {
48128
48510
  decodeClaudePermissionModeId(requestedPermissionModeId);
48129
48511
  } catch {
@@ -48136,7 +48518,14 @@ var ClaudeCodeAdapter = class {
48136
48518
  }
48137
48519
  };
48138
48520
  }
48139
- const cwd = path10.resolve(input.cwd);
48521
+ const cwd = path12.resolve(input.cwd);
48522
+ if (input.kind === "rollbackLastTurn") {
48523
+ for (const source of this.#sessions) {
48524
+ const ready = await source.prepareRollback(input.sourceRef.nativeSessionId);
48525
+ if (!ready.ok)
48526
+ return ready;
48527
+ }
48528
+ }
48140
48529
  const nativeRef = input.kind === "resume" ? nativeSessionRefSchema.safeParse(input.nativeRef) : null;
48141
48530
  if (nativeRef && (!nativeRef.success || nativeRef.data.harnessId !== this.harnessId)) {
48142
48531
  return {
@@ -48148,8 +48537,16 @@ var ClaudeCodeAdapter = class {
48148
48537
  }
48149
48538
  };
48150
48539
  }
48151
- const forked = input.kind === "fork" ? await forkClaudeSession({
48152
- checkpoint: input.checkpoint,
48540
+ const forked = input.kind === "fork" || input.kind === "rollbackLastTurn" ? await forkClaudeSession({
48541
+ ...input.kind === "fork" ? { kind: "fork", checkpoint: input.checkpoint } : {
48542
+ kind: "rollbackLastTurn",
48543
+ pendingSessions: this.#pendingSessions,
48544
+ configuration: {
48545
+ ...input.model ? { effectiveModel: input.model } : {},
48546
+ effectiveThinkingOptionId: requestedThinkingOptionId,
48547
+ effectivePermissionModeId: requestedPermissionModeId
48548
+ }
48549
+ },
48153
48550
  cwd,
48154
48551
  dependencies: this.#dependencies,
48155
48552
  harnessId: this.harnessId,
@@ -48157,11 +48554,49 @@ var ClaudeCodeAdapter = class {
48157
48554
  }) : null;
48158
48555
  if (forked && !forked.ok)
48159
48556
  return forked;
48557
+ const durableRef = forked?.ok ? forked.value.nativeRef : nativeRef?.success ? nativeRef.data : void 0;
48558
+ let openMode = forked?.ok && forked.value.openMode === "create" || input.kind === "create" ? "create" : "resume";
48559
+ let requestedModel = input.kind !== "fork" ? input.model : void 0;
48560
+ if (durableRef && isPendingClaudeSession(durableRef)) {
48561
+ try {
48562
+ const pending = await this.#pendingSessions.read(durableRef, cwd);
48563
+ if (!pending.started) {
48564
+ const messages = await this.#dependencies.readSessionMessages({
48565
+ cwd,
48566
+ sessionId: durableRef.nativeSessionId
48567
+ });
48568
+ if (messages.length > 0 || input.kind === "resume" && input.knownTurnRefs?.length)
48569
+ throw new Error("Pending Session unexpectedly contains history");
48570
+ openMode = "create";
48571
+ }
48572
+ if (pending.configuration.effectiveModel)
48573
+ decodeClaudeModelRef(pending.configuration.effectiveModel);
48574
+ if (pending.configuration.effectiveThinkingOptionId)
48575
+ parseClaudeThinkingOptionId(pending.configuration.effectiveThinkingOptionId);
48576
+ if (pending.configuration.effectivePermissionModeId)
48577
+ decodeClaudePermissionModeId(pending.configuration.effectivePermissionModeId);
48578
+ requestedModel = pending.configuration.effectiveModel ?? requestedModel;
48579
+ requestedThinkingOptionId = pending.configuration.effectiveThinkingOptionId ?? requestedThinkingOptionId;
48580
+ requestedPermissionModeId = input.kind === "resume" && input.permissionModeId ? input.permissionModeId : pending.configuration.effectivePermissionModeId ?? requestedPermissionModeId;
48581
+ } catch {
48582
+ return {
48583
+ ok: false,
48584
+ error: {
48585
+ code: "sessionNotFound",
48586
+ message: "Claude Code pending Session cannot be recovered",
48587
+ retryable: false
48588
+ }
48589
+ };
48590
+ }
48591
+ }
48160
48592
  const session = new ClaudeHarnessSession(cwd, this.#dependencies, this.#closeTimeoutMs, () => this.#sessions.delete(session), (planLimit) => this.#recordPlanLimit(session, planLimit), {
48161
48593
  ...input.environment ? { environment: input.environment } : {},
48162
- openMode: rollback?.openMode ?? (input.kind === "create" ? "create" : "resume"),
48163
- sessionId: rollback?.sessionId ?? (forked?.ok ? forked.value.sessionId : nativeRef?.success ? nativeRef.data.nativeSessionId : this.#dependencies.randomUUID()),
48164
- ...input.kind === "create" && input.model ? { requestedModel: input.model } : {},
48594
+ openMode,
48595
+ pendingSessions: this.#pendingSessions,
48596
+ knownConfiguration: input.kind === "rollbackLastTurn" || input.kind === "resume" && Boolean(input.model || input.thinkingOptionId) || Boolean(durableRef && isPendingClaudeSession(durableRef)),
48597
+ ...durableRef ? { nativeRef: durableRef } : {},
48598
+ sessionId: forked?.ok ? forked.value.sessionId : nativeRef?.success ? nativeRef.data.nativeSessionId : this.#dependencies.randomUUID(),
48599
+ ...requestedModel ? { requestedModel } : {},
48165
48600
  requestedPermissionModeId,
48166
48601
  requestedThinkingOptionId,
48167
48602
  toolOutputLimit: this.#toolOutputLimit,
@@ -48206,7 +48641,7 @@ var ClaudeCodeAdapter = class {
48206
48641
  };
48207
48642
 
48208
48643
  // dist/user-shell-environment.js
48209
- import path11 from "node:path";
48644
+ import path13 from "node:path";
48210
48645
  import { spawnSync } from "node:child_process";
48211
48646
  var ENVIRONMENT_MARKER = Buffer.from("\0CODEXHOST_USER_SHELL_ENV_V1\0");
48212
48647
  var ENVIRONMENT_COMMAND = "printf '\\0CODEXHOST_USER_SHELL_ENV_V1\\0'; /usr/bin/env -0";
@@ -48249,7 +48684,7 @@ function withUserShellEnvironment(environment, dependencies) {
48249
48684
  if (platform === "win32" || !environment.HOME)
48250
48685
  return environment;
48251
48686
  const shell = environment.SHELL?.trim() || defaultShell(platform);
48252
- if (!shell || !SUPPORTED_SHELLS.has(path11.basename(shell)))
48687
+ if (!shell || !SUPPORTED_SHELLS.has(path13.basename(shell)))
48253
48688
  return environment;
48254
48689
  const cacheKey = `${platform}\0${shell}\0${environment.HOME}`;
48255
48690
  const cached2 = dependencies ? void 0 : shellEnvironmentCache.get(cacheKey);