@codexhost/cli-win32-arm64 0.15.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5369,7 +5369,8 @@ function createBackgroundUpdateManager(dependencies2 = {}) {
5369
5369
  kind: "npm",
5370
5370
  node_path: await requireRegularFile(options2.nodePath, "npm Node.js executable"),
5371
5371
  npm_cli_path: await requireRegularFile(options2.npmCliPath, "npm CLI"),
5372
- npm_launcher_path: await requireRegularFile(options2.npmLauncherPath, "npm codexhost launcher")
5372
+ npm_launcher_path: await requireRegularFile(options2.npmLauncherPath, "npm codexhost launcher"),
5373
+ npm_package_root: requireAbsolutePath(options2.packageRoot, "npm platform package root")
5373
5374
  });
5374
5375
  } catch (error51) {
5375
5376
  await writeFailedStatus(common.statusPath, common.version, "npm", error51);
@@ -20114,6 +20115,8 @@ var usageStatisticsTotalsSchema = external_exports.strictObject({
20114
20115
  cachedInputTokens: count,
20115
20116
  cacheWriteInputTokens: count,
20116
20117
  cacheKnownInputTokens: count,
20118
+ cacheHitCachedInputTokens: count,
20119
+ cacheHitInputTokens: count,
20117
20120
  outputTokens: count,
20118
20121
  reasoningOutputTokens: count,
20119
20122
  /** USD at the public price, summed over the priced requests only. */
@@ -21024,7 +21027,10 @@ var harnessPluginRouteSchema = external_exports.object({
21024
21027
  harnessId: harnessPluginIdSchema,
21025
21028
  model: harnessModelRefSchema.optional(),
21026
21029
  thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
21027
- permissionModeId: harnessPermissionModeIdSchema.optional()
21030
+ permissionModeId: harnessPermissionModeIdSchema.optional(),
21031
+ /** A draft prewarm create: stays unsubmitted until the user's first Turn.
21032
+ * Desktop forwards only the Model of a main-process prewarm to thread/start. */
21033
+ prewarm: external_exports.literal(true).optional()
21028
21034
  }).strict();
21029
21035
  function encodeHarnessPluginRoute(route) {
21030
21036
  const parsed2 = harnessPluginRouteSchema.parse(route);
@@ -22494,8 +22500,110 @@ function retainRendererHostResponses(client, hostId2, target) {
22494
22500
  };
22495
22501
  }
22496
22502
 
22503
+ // packages/desktop-control/dist/renderer-prewarm-consumption.js
22504
+ function isolateRendererPrewarmConsumption(manager, discardExternal) {
22505
+ const record5 = (value2) => value2 !== null && typeof value2 === "object";
22506
+ if (!record5(manager) || !record5(manager.threadCreation))
22507
+ return null;
22508
+ const creation = manager.threadCreation;
22509
+ const originalStart = manager.startConversation;
22510
+ const original = creation.createConversation;
22511
+ const params = creation.params;
22512
+ if (typeof originalStart !== "function" || typeof original !== "function" || !record5(params))
22513
+ return null;
22514
+ const prototype = Object.getPrototypeOf(creation);
22515
+ if (!record5(prototype) || typeof prototype.constructor !== "function")
22516
+ return null;
22517
+ if (Object.keys(creation).some((key) => key !== "params" && typeof creation[key] !== "function") || /#[A-Za-z_$]/u.test(Function.prototype.toString.call(prototype.constructor)))
22518
+ return null;
22519
+ const pool = params.prewarmedThreadManager;
22520
+ if (!record5(pool) || typeof pool.hasPrewarmedThread !== "function" || typeof pool.consumePrewarmedThread !== "function" || typeof pool.deletePrewarmedThread !== "function")
22521
+ return null;
22522
+ const consume = pool.consumePrewarmedThread;
22523
+ const hasPrewarm = pool.hasPrewarmedThread;
22524
+ const draftModels = /* @__PURE__ */ new Map();
22525
+ const draftIdentity = /* @__PURE__ */ Symbol("codexhost draft creation");
22526
+ const external = (model2) => typeof model2 === "string" && model2.startsWith("codexhost/");
22527
+ const routedStart = function(input, options2, ...args) {
22528
+ const draftId = record5(options2) ? options2.clientThreadId : null;
22529
+ const mode = record5(input) && record5(input.collaborationMode) ? input.collaborationMode : null;
22530
+ const origin = mode ? Reflect.get(mode, draftIdentity) : void 0;
22531
+ if (mode && record5(mode.settings) && external(mode.settings.model))
22532
+ return originalStart.call(this, input, options2, ...args);
22533
+ const model2 = (typeof draftId === "string" ? draftModels.get(draftId) : void 0) ?? (typeof origin === "string" ? draftModels.get(origin) : void 0);
22534
+ if (!model2)
22535
+ return originalStart.call(this, input, options2, ...args);
22536
+ if (!record5(input) || !record5(input.collaborationMode) || !record5(input.collaborationMode.settings))
22537
+ throw new Error("External draft creation is missing its native Model settings");
22538
+ const routed = {
22539
+ ...input,
22540
+ collaborationMode: {
22541
+ ...input.collaborationMode,
22542
+ settings: { ...input.collaborationMode.settings, model: model2 }
22543
+ }
22544
+ };
22545
+ return originalStart.call(this, routed, options2, ...args);
22546
+ };
22547
+ const wrapped = function(input, ...args) {
22548
+ const mode = record5(input) && record5(input.collaborationMode) ? input.collaborationMode : null;
22549
+ const expected = mode && record5(mode.settings) ? mode.settings.model : null;
22550
+ const scopedPool = Object.create(pool);
22551
+ scopedPool.hasPrewarmedThread = (...parameters) => hasPrewarm.apply(pool, parameters);
22552
+ scopedPool.consumePrewarmedThread = async (...consumeArgs) => {
22553
+ const warmed = await consume.apply(pool, consumeArgs);
22554
+ if (!record5(warmed) || !record5(warmed.response))
22555
+ return warmed;
22556
+ const response = warmed.response;
22557
+ if (!external(expected) && !external(response.model))
22558
+ return warmed;
22559
+ if (external(expected) && expected === response.model)
22560
+ return warmed;
22561
+ if (record5(response.thread) && typeof response.thread.id === "string") {
22562
+ const threadId2 = response.thread.id;
22563
+ if (external(response.model))
22564
+ discardExternal(threadId2);
22565
+ else
22566
+ void Promise.resolve().then(() => pool.deletePrewarmedThread(threadId2)).catch(() => void 0);
22567
+ }
22568
+ return null;
22569
+ };
22570
+ const invocation = Object.create(creation);
22571
+ invocation.params = { ...params, prewarmedThreadManager: scopedPool };
22572
+ return original.call(invocation, input, ...args);
22573
+ };
22574
+ creation.createConversation = wrapped;
22575
+ manager.startConversation = routedStart;
22576
+ return {
22577
+ selectDraft(draftId, model2, creationModes = []) {
22578
+ if (draftId === void 0) {
22579
+ if (model2 === null)
22580
+ draftModels.clear();
22581
+ } else if (model2 === null)
22582
+ draftModels.delete(draftId);
22583
+ else {
22584
+ if (!draftId.startsWith("client-new-thread:") || !external(model2))
22585
+ throw new Error("External draft route is missing its client Thread identity");
22586
+ draftModels.set(draftId, model2);
22587
+ for (const mode of creationModes)
22588
+ Object.defineProperty(mode, draftIdentity, {
22589
+ configurable: true,
22590
+ enumerable: true,
22591
+ value: draftId
22592
+ });
22593
+ }
22594
+ },
22595
+ dispose() {
22596
+ draftModels.clear();
22597
+ if (manager.startConversation === routedStart)
22598
+ manager.startConversation = originalStart;
22599
+ if (creation.createConversation === wrapped)
22600
+ creation.createConversation = original;
22601
+ }
22602
+ };
22603
+ }
22604
+
22497
22605
  // packages/desktop-control/dist/renderer-draft-prewarm-runtime.js
22498
- function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewarmedThreadManager, isCurrentManager, retainResponses = retainRendererHostResponses) {
22606
+ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewarmedThreadManager, isCurrentManager, retainResponses = retainRendererHostResponses, isolateConsumption = isolateRendererPrewarmConsumption) {
22499
22607
  let disposed = false;
22500
22608
  const originalSend = bridge.sendRequest;
22501
22609
  const originalPrewarm = bridge.prewarmThreadStart;
@@ -22885,25 +22993,15 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
22885
22993
  return false;
22886
22994
  return selectedModel !== null && (method.startsWith("thread/") || method.startsWith("turn/") || method.startsWith("review/"));
22887
22995
  };
22888
- const routeThreadStart = (parameters) => {
22889
- if (!isRecord19(parameters) || parameters.ephemeral === true) {
22890
- return parameters;
22891
- }
22892
- return {
22893
- ...parameters,
22894
- ...selectedModel === null ? {} : { model: selectedModel }
22895
- };
22896
- };
22897
22996
  const routedSend = (method, parameters, options2) => {
22898
22997
  if (method === "turn/start" || method === "thread/resume" || method === "codexhost/thread/command/execute") {
22899
22998
  const threadId2 = threadIdFromParameters(parameters);
22900
22999
  if (threadId2)
22901
23000
  externalPrewarms.delete(threadId2);
22902
23001
  }
22903
- const routedParameters = method === "thread/start" ? routeThreadStart(parameters) : parameters;
22904
- const sendBridged = () => initializeBridge().then(() => enqueueBridgeRequest(method, routedParameters, options2));
22905
- const sendDirect = () => options2 === void 0 ? originalSend.call(bridge, method, routedParameters) : originalSend.call(bridge, method, routedParameters, options2);
22906
- const unresolvedThreadId = shouldResolveThreadOwnership(method, routedParameters);
23002
+ const sendBridged = () => initializeBridge().then(() => enqueueBridgeRequest(method, parameters, options2));
23003
+ const sendDirect = () => options2 === void 0 ? originalSend.call(bridge, method, parameters) : originalSend.call(bridge, method, parameters, options2);
23004
+ const unresolvedThreadId = shouldResolveThreadOwnership(method, parameters);
22907
23005
  if (unresolvedThreadId) {
22908
23006
  return resolveThreadOwnership(unresolvedThreadId).then((owner) => owner === "external" ? sendBridged() : sendDirect(), (error51) => {
22909
23007
  if ((method === "thread/read" || method === "thread/resume") && isUnsupportedPosixBridgeSpawn(error51)) {
@@ -22916,7 +23014,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
22916
23014
  throw error51;
22917
23015
  });
22918
23016
  }
22919
- return shouldUseBridge(method, routedParameters) ? sendBridged() : sendDirect();
23017
+ return shouldUseBridge(method, parameters) ? sendBridged() : sendDirect();
22920
23018
  };
22921
23019
  const publishDraftWorkspace = (parameters) => {
22922
23020
  if (!isRecord19(parameters) || parameters.ephemeral === true)
@@ -22945,10 +23043,10 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
22945
23043
  for (const threadId2 of externalPrewarms)
22946
23044
  discardExternalPrewarm(threadId2);
22947
23045
  };
23046
+ const restoreConsumption = isolateConsumption(manager, discardExternalPrewarm);
22948
23047
  const routedPrewarm = (parameters, options2) => {
22949
- const routed = routeThreadStart(parameters);
22950
- const external = isRecord19(routed) && routed.ephemeral !== true && typeof routed.model === "string" && routed.model.startsWith("codexhost/");
22951
- const routedParameters = external ? { ...routed, codexhostPrewarm: true } : routed;
23048
+ const external = isRecord19(parameters) && parameters.ephemeral !== true && typeof parameters.model === "string" && parameters.model.startsWith("codexhost/");
23049
+ const routedParameters = external ? { ...parameters, codexhostPrewarm: true } : parameters;
22952
23050
  const generation = prewarmGeneration;
22953
23051
  publishDraftWorkspace(routedParameters);
22954
23052
  const pending = shouldUseBridge("thread/start", routedParameters) ? routedSend("thread/start", routedParameters, options2) : options2 === void 0 ? originalPrewarm.call(bridge, routedParameters) : originalPrewarm.call(bridge, routedParameters, options2);
@@ -23004,6 +23102,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23004
23102
  const policy = Object.freeze({
23005
23103
  state: "ready",
23006
23104
  hostId: hostId2,
23105
+ scopedCreation: restoreConsumption !== null,
23007
23106
  owns(candidateManager, candidate, candidateHostId, candidatePrewarmedThreadManager, requiresCurrentManager) {
23008
23107
  return !disposed && candidateManager === manager && candidate === bridge && candidateHostId === hostId2 && candidatePrewarmedThreadManager === prewarmedThreadManager && requiresCurrentManager === !!isCurrentManager;
23009
23108
  },
@@ -23012,12 +23111,13 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23012
23111
  throw new Error("Renderer request manager is retired");
23013
23112
  return manager;
23014
23113
  },
23015
- select(model2) {
23114
+ select(model2, draftId, creationModes) {
23016
23115
  if (disposed || isCurrentManager && !isCurrentManager())
23017
23116
  throw new Error("Renderer request manager is retired");
23018
23117
  if (model2 !== null && (typeof model2 !== "string" || !model2.startsWith("codexhost/"))) {
23019
23118
  throw new Error("Draft route Model must be a codexhost transport carrier");
23020
23119
  }
23120
+ restoreConsumption?.selectDraft(draftId, model2, creationModes);
23021
23121
  if (selectedModel === model2)
23022
23122
  return false;
23023
23123
  selectedModel = model2;
@@ -23040,6 +23140,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23040
23140
  disposed = true;
23041
23141
  prewarmGeneration += 1;
23042
23142
  retireResponses();
23143
+ restoreConsumption?.dispose();
23043
23144
  if (bridge.sendRequest === routedSend)
23044
23145
  bridge.sendRequest = originalSend;
23045
23146
  if (bridge.prewarmThreadStart === routedPrewarm) {
@@ -23077,14 +23178,14 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23077
23178
 
23078
23179
  // packages/desktop-control/dist/renderer-host-discovery.js
23079
23180
  function requestManagerFromHookState(value2, hostId2) {
23080
- const record4 = (candidate) => typeof candidate === "object" && candidate !== null;
23181
+ const record5 = (candidate) => typeof candidate === "object" && candidate !== null;
23081
23182
  const manager = (candidate) => {
23082
- if (!record4(candidate) || !record4(candidate.requestClient) || !record4(candidate.prewarmedThreadManager))
23183
+ if (!record5(candidate) || !record5(candidate.requestClient) || !record5(candidate.prewarmedThreadManager))
23083
23184
  return null;
23084
23185
  const bridge = candidate.requestClient;
23085
23186
  return typeof candidate.sendRequest === "function" && typeof bridge.sendRequest === "function" && typeof bridge.prewarmThreadStart === "function" && typeof bridge.enqueueRequest === "function" && typeof candidate.prewarmedThreadManager.discardAllPrewarmedThreads === "function" ? candidate : null;
23086
23187
  };
23087
- if (!record4(value2))
23188
+ if (!record5(value2))
23088
23189
  return null;
23089
23190
  const direct = manager(value2) ?? manager(value2.manager);
23090
23191
  if (direct)
@@ -23288,6 +23389,372 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
23288
23389
  return routing;
23289
23390
  }
23290
23391
 
23392
+ // packages/desktop-control/dist/renderer-host-rpc-discovery.js
23393
+ function findRendererAppScopeStore(root) {
23394
+ const MAX_VISITED_FIBERS = 5e4;
23395
+ const record5 = (value2) => typeof value2 === "object" && value2 !== null;
23396
+ const container = root.getElementById?.("root");
23397
+ if (!record5(container))
23398
+ return null;
23399
+ const key = Object.getOwnPropertyNames(container).find((name) => name.startsWith("__reactContainer$"));
23400
+ const first = key ? container[key] : null;
23401
+ if (!record5(first))
23402
+ return null;
23403
+ const isScopeHandle = (value2) => record5(value2) && record5(value2.node) && "chain" in value2 && "scope" in value2 && typeof value2.get === "function" && typeof value2.set === "function" && typeof value2.watch === "function";
23404
+ const stack = [first];
23405
+ const seen = /* @__PURE__ */ new Set();
23406
+ while (stack.length && seen.size < MAX_VISITED_FIBERS) {
23407
+ const fiber = stack.pop();
23408
+ if (seen.has(fiber))
23409
+ continue;
23410
+ seen.add(fiber);
23411
+ let hook = fiber.memoizedState;
23412
+ for (let index = 0; record5(hook) && "next" in hook && index < 150; index += 1) {
23413
+ const state = hook.memoizedState;
23414
+ const handle = record5(state) ? state.current : null;
23415
+ if (isScopeHandle(handle)) {
23416
+ let node = handle.node;
23417
+ const nodes = /* @__PURE__ */ new Set();
23418
+ while (record5(node.parent) && !nodes.has(node.parent)) {
23419
+ nodes.add(node);
23420
+ node = node.parent;
23421
+ }
23422
+ const bindings = node.familyBindings;
23423
+ return record5(bindings) && typeof bindings.get === "function" && typeof bindings.entries === "function" ? node : null;
23424
+ }
23425
+ hook = hook.next;
23426
+ }
23427
+ if (record5(fiber.sibling))
23428
+ stack.push(fiber.sibling);
23429
+ if (record5(fiber.child))
23430
+ stack.push(fiber.child);
23431
+ }
23432
+ return null;
23433
+ }
23434
+ function findRendererHostRpcFamily(store) {
23435
+ const record5 = (value2) => typeof value2 === "object" && value2 !== null;
23436
+ const families = /* @__PURE__ */ new Set();
23437
+ for (const [definition, members] of store.familyBindings) {
23438
+ if (!record5(definition) || definition.kind !== "signal-family")
23439
+ continue;
23440
+ if (!record5(members) || typeof members.get !== "function")
23441
+ continue;
23442
+ for (const [hostId2, member] of members) {
23443
+ if (typeof hostId2 !== "string" || !record5(member))
23444
+ continue;
23445
+ const signal = member.value;
23446
+ if (!record5(signal) || typeof signal.get !== "function")
23447
+ continue;
23448
+ let value2;
23449
+ try {
23450
+ value2 = signal.get();
23451
+ } catch {
23452
+ continue;
23453
+ }
23454
+ if (record5(value2) && Object.keys(value2).length === 2 && typeof value2.status === "string" && record5(value2.client) && value2.client.hostId === hostId2 && "rpc" in value2.client) {
23455
+ families.add(members);
23456
+ break;
23457
+ }
23458
+ }
23459
+ }
23460
+ if (families.size !== 1)
23461
+ return null;
23462
+ return { store, family: families.values().next().value };
23463
+ }
23464
+ function resolveRendererHostRpc(discovery, hostId2) {
23465
+ const record5 = (value3) => typeof value3 === "object" && value3 !== null;
23466
+ const signal = discovery.family.get(hostId2)?.value;
23467
+ if (!record5(signal) || typeof signal.get !== "function")
23468
+ return null;
23469
+ let value2;
23470
+ try {
23471
+ value2 = signal.get();
23472
+ } catch {
23473
+ return null;
23474
+ }
23475
+ if (!record5(value2) || value2.status !== "ready" || !record5(value2.client) || value2.client.hostId !== hostId2)
23476
+ return null;
23477
+ const rpc = value2.client.rpc;
23478
+ return typeof rpc === "function" || record5(rpc) ? rpc : null;
23479
+ }
23480
+ function rendererHostRpcHostIds(discovery) {
23481
+ return [...discovery.family.keys()].filter((hostId2) => typeof hostId2 === "string");
23482
+ }
23483
+
23484
+ // packages/desktop-control/dist/renderer-host-rpc-routing.js
23485
+ function installRendererHostRpcRouting(root, target, dependencies2) {
23486
+ const existing = target.__codexhostHostRoutingV1;
23487
+ if (existing)
23488
+ return existing;
23489
+ let disposed = false;
23490
+ let discovery = null;
23491
+ const routes = /* @__PURE__ */ new Map();
23492
+ const read = () => {
23493
+ if (disposed)
23494
+ return null;
23495
+ if (!discovery) {
23496
+ const store = dependencies2.findStore(root);
23497
+ discovery = store ? dependencies2.findFamily(store) : null;
23498
+ }
23499
+ return discovery;
23500
+ };
23501
+ if (!read())
23502
+ return null;
23503
+ const isRecord19 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
23504
+ const externalDrafts = /* @__PURE__ */ new Map();
23505
+ const selectedModels = /* @__PURE__ */ new Map();
23506
+ const prewarmCarrier = (carrier) => {
23507
+ const prefix = "codexhost/plugin-v1@";
23508
+ if (!carrier.startsWith(prefix))
23509
+ return null;
23510
+ try {
23511
+ const json2 = carrier.slice(prefix.length).replace(/[a-f0-9]{2}/gu, (byte) => String.fromCharCode(Number.parseInt(byte, 16)));
23512
+ const route = JSON.parse(json2);
23513
+ if (!isRecord19(route))
23514
+ return null;
23515
+ const payload = [...JSON.stringify({ ...route, prewarm: true })].map((character) => character.charCodeAt(0).toString(16).padStart(2, "0")).join("");
23516
+ return `${prefix}${payload}`;
23517
+ } catch {
23518
+ return null;
23519
+ }
23520
+ };
23521
+ const publishDraftWorkspace = (hostId2, cwd) => {
23522
+ if (typeof cwd !== "string" || cwd.length === 0)
23523
+ return;
23524
+ const drafts = isRecord19(target.__codexhostDraftWorkspacesV1) ? target.__codexhostDraftWorkspacesV1 : {};
23525
+ if (drafts[hostId2] === cwd)
23526
+ return;
23527
+ drafts[hostId2] = cwd;
23528
+ Object.defineProperty(target, "__codexhostDraftWorkspacesV1", {
23529
+ configurable: true,
23530
+ value: drafts
23531
+ });
23532
+ if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function") {
23533
+ target.dispatchEvent(new CustomEvent("codexhost:draft-workspace", { detail: { hostId: hostId2, cwd } }));
23534
+ }
23535
+ };
23536
+ const routeCreationCall = (message2) => {
23537
+ if (!Array.isArray(message2) || message2.length !== 2 || message2[0] !== "push")
23538
+ return message2;
23539
+ const expression = message2[1];
23540
+ if (!Array.isArray(expression) || expression.length !== 4 || expression[0] !== "pipeline")
23541
+ return message2;
23542
+ const [, importId, path43, args] = expression;
23543
+ if (!Array.isArray(path43) || path43.length !== 1 || !Array.isArray(args))
23544
+ return message2;
23545
+ const [input, options2] = args;
23546
+ if (!isRecord19(input) || !isRecord19(input.collaborationMode))
23547
+ return message2;
23548
+ const settings = input.collaborationMode.settings;
23549
+ if (!isRecord19(settings))
23550
+ return message2;
23551
+ let model2 = null;
23552
+ if (path43[0] === "startConversation") {
23553
+ const draftId = isRecord19(options2) ? options2.clientThreadId : null;
23554
+ model2 = typeof draftId === "string" ? externalDrafts.get(draftId)?.model ?? null : null;
23555
+ } else if (path43[0] === "prewarmConversation") {
23556
+ if (input.ephemeral !== true)
23557
+ publishDraftWorkspace("local", input.cwd);
23558
+ const selected = selectedModels.get("local");
23559
+ model2 = selected ? prewarmCarrier(selected) : null;
23560
+ }
23561
+ if (!model2)
23562
+ return message2;
23563
+ return [
23564
+ "push",
23565
+ [
23566
+ "pipeline",
23567
+ importId,
23568
+ path43,
23569
+ [
23570
+ {
23571
+ ...input,
23572
+ collaborationMode: { ...input.collaborationMode, settings: { ...settings, model: model2 } }
23573
+ },
23574
+ ...args.slice(1)
23575
+ ]
23576
+ ]
23577
+ ];
23578
+ };
23579
+ const port = dependencies2.portPrototype;
23580
+ const originalPostMessage = port.postMessage;
23581
+ const postMessage = function(message2, ...rest) {
23582
+ let routed = message2;
23583
+ try {
23584
+ routed = disposed ? message2 : routeCreationCall(message2);
23585
+ } catch {
23586
+ routed = message2;
23587
+ }
23588
+ return originalPostMessage.call(this, routed, ...rest);
23589
+ };
23590
+ port.postMessage = postMessage;
23591
+ const createRoute = (hostId2, rpc) => {
23592
+ let retired = false;
23593
+ const isCurrent = () => !retired && !disposed && routes.get(hostId2)?.rpc === rpc;
23594
+ const manager = Object.freeze({
23595
+ kind: "main-process-rpc",
23596
+ getHostId: () => hostId2,
23597
+ sendRequest(method, params, options2) {
23598
+ if (!isCurrent())
23599
+ return Promise.reject(new Error(`Renderer request manager is retired for ${hostId2}`));
23600
+ return options2 === void 0 ? rpc.sendRequest(method, params) : rpc.sendRequest(method, params, options2);
23601
+ },
23602
+ // The main process broadcasts every app-server notification to its windows,
23603
+ // including codexhost methods Desktop's own notification table drops.
23604
+ addNotificationCallback(methods, listener) {
23605
+ const accepted = new Set(typeof methods === "string" ? [methods] : methods);
23606
+ const onMessage = (event) => {
23607
+ const { source, data } = event;
23608
+ if (source != null && source !== target)
23609
+ return;
23610
+ if (!isRecord19(data) || data.type !== "mcp-notification" || data.hostId !== hostId2 || typeof data.method !== "string" || !accepted.has(data.method) || !isCurrent())
23611
+ return;
23612
+ listener({ method: data.method, params: data.params });
23613
+ };
23614
+ target.addEventListener?.("message", onMessage);
23615
+ return () => target.removeEventListener?.("message", onMessage);
23616
+ }
23617
+ });
23618
+ const clearDrafts = () => {
23619
+ for (const [draftId, draft] of externalDrafts) {
23620
+ if (draft.owner === policy)
23621
+ externalDrafts.delete(draftId);
23622
+ }
23623
+ };
23624
+ const clear = () => isCurrent() ? Promise.resolve(rpc.clearPrewarmedThreads()).then(() => void 0) : Promise.reject(new Error("Renderer request manager is retired"));
23625
+ const policy = Object.freeze({
23626
+ state: "ready",
23627
+ hostId: hostId2,
23628
+ scopedCreation: true,
23629
+ requestTarget: () => {
23630
+ if (!isCurrent())
23631
+ throw new Error("Renderer request manager is retired");
23632
+ return manager;
23633
+ },
23634
+ select(model2, draftId) {
23635
+ if (!isCurrent())
23636
+ throw new Error("Renderer request manager is retired");
23637
+ if (model2 !== null && (typeof model2 !== "string" || !model2.startsWith("codexhost/"))) {
23638
+ throw new Error("Draft route Model must be a codexhost transport carrier");
23639
+ }
23640
+ if (draftId === void 0) {
23641
+ if (model2 === null)
23642
+ clearDrafts();
23643
+ } else if (model2 === null) {
23644
+ if (externalDrafts.get(draftId)?.owner === policy)
23645
+ externalDrafts.delete(draftId);
23646
+ } else {
23647
+ if (!draftId.startsWith("client-new-thread:"))
23648
+ throw new Error("External draft route is missing its client Thread identity");
23649
+ externalDrafts.set(draftId, { model: model2, owner: policy });
23650
+ }
23651
+ if ((selectedModels.get(hostId2) ?? null) === model2)
23652
+ return false;
23653
+ if (model2 === null)
23654
+ selectedModels.delete(hostId2);
23655
+ else
23656
+ selectedModels.set(hostId2, model2);
23657
+ void clear().catch(() => void 0);
23658
+ return true;
23659
+ },
23660
+ clear,
23661
+ dispose() {
23662
+ if (retired)
23663
+ return;
23664
+ retired = true;
23665
+ clearDrafts();
23666
+ selectedModels.delete(hostId2);
23667
+ }
23668
+ });
23669
+ return { hostId: hostId2, manager, policy };
23670
+ };
23671
+ const retire = (hostId2) => {
23672
+ const entry = routes.get(hostId2);
23673
+ routes.delete(hostId2);
23674
+ entry?.route.policy.dispose();
23675
+ };
23676
+ const routeFor = (hostId2) => {
23677
+ const current = read();
23678
+ const rpc = current ? dependencies2.resolve(current, hostId2) : null;
23679
+ const previous = routes.get(hostId2);
23680
+ if (rpc && previous?.rpc === rpc)
23681
+ return previous.route;
23682
+ retire(hostId2);
23683
+ if (!rpc)
23684
+ return null;
23685
+ const route = createRoute(hostId2, rpc);
23686
+ routes.set(hostId2, { route, rpc });
23687
+ return route;
23688
+ };
23689
+ const publish = (route) => {
23690
+ const policy = route?.policy;
23691
+ if (target.__codexhostDraftPrewarmPolicyV1 === policy)
23692
+ return;
23693
+ Object.defineProperty(target, "__codexhostDraftPrewarmPolicyV1", {
23694
+ configurable: true,
23695
+ value: policy
23696
+ });
23697
+ if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function") {
23698
+ target.dispatchEvent(new CustomEvent("codexhost:draft-prewarm-policy-changed"));
23699
+ }
23700
+ };
23701
+ const composerHostId = (composer) => {
23702
+ const hostIds = new Set(dependencies2.composerHostIds(composer).hostIds);
23703
+ const hostId2 = hostIds.size === 1 ? hostIds.values().next().value : null;
23704
+ return typeof hostId2 === "string" && hostId2 ? hostId2 : null;
23705
+ };
23706
+ const routing = {
23707
+ knownHostIds() {
23708
+ const current = read();
23709
+ return current ? dependencies2.hostIds(current) : [];
23710
+ },
23711
+ forHost(hostId2) {
23712
+ return hostId2 && !disposed ? routeFor(hostId2) : null;
23713
+ },
23714
+ hostIdForComposer(composer) {
23715
+ if (disposed)
23716
+ return null;
23717
+ try {
23718
+ return composerHostId(composer);
23719
+ } catch {
23720
+ return null;
23721
+ }
23722
+ },
23723
+ forComposer(composer) {
23724
+ if (disposed)
23725
+ return null;
23726
+ let hostId2;
23727
+ try {
23728
+ hostId2 = composerHostId(composer);
23729
+ } catch {
23730
+ hostId2 = null;
23731
+ }
23732
+ const route = hostId2 ? routeFor(hostId2) : null;
23733
+ if (!composer)
23734
+ publish(route);
23735
+ return route;
23736
+ },
23737
+ dispose() {
23738
+ if (disposed)
23739
+ return;
23740
+ disposed = true;
23741
+ for (const hostId2 of [...routes.keys()])
23742
+ retire(hostId2);
23743
+ discovery = null;
23744
+ externalDrafts.clear();
23745
+ selectedModels.clear();
23746
+ if (port.postMessage === postMessage)
23747
+ port.postMessage = originalPostMessage;
23748
+ if (target.__codexhostHostRoutingV1 === routing) {
23749
+ delete target.__codexhostHostRoutingV1;
23750
+ publish(null);
23751
+ }
23752
+ }
23753
+ };
23754
+ Object.defineProperty(target, "__codexhostHostRoutingV1", { configurable: true, value: routing });
23755
+ return routing;
23756
+ }
23757
+
23291
23758
  // packages/desktop-control/dist/renderer-draft-prewarm-policy.js
23292
23759
  var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
23293
23760
  var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
@@ -23299,14 +23766,41 @@ function directRendererInstaller() {
23299
23766
  const resolveRendererHostManager = ${resolveRendererHostManager.toString()};
23300
23767
  const retainRendererHostResponses = ${retainRendererHostResponses.toString()};
23301
23768
  const createDraftPrewarmPolicyBridge = ${createDraftPrewarmPolicyBridge.toString()};
23302
- const routing = (${installRendererHostRouting.toString()})(
23303
- document, window,
23304
- (root) => discoverRendererHosts(root, committedReactAncestors, requestManagerFromHookState),
23769
+ const isolateRendererPrewarmConsumption = ${isolateRendererPrewarmConsumption.toString()};
23770
+ const discover = (root) =>
23771
+ discoverRendererHosts(root, committedReactAncestors, requestManagerFromHookState);
23772
+ const installNative = () => (${installRendererHostRouting.toString()})(
23773
+ document, window, discover,
23305
23774
  (discovery, hostId) => resolveRendererHostManager(discovery, hostId, requestManagerFromHookState),
23306
23775
  (manager, bridge, hostId, target, prewarmed, isCurrent) => createDraftPrewarmPolicyBridge(
23307
23776
  manager, bridge, hostId, target, prewarmed, isCurrent, retainRendererHostResponses,
23777
+ isolateRendererPrewarmConsumption,
23308
23778
  ),
23309
23779
  );
23780
+ const installRpc = () => typeof MessagePort !== 'function' ? null : (${installRendererHostRpcRouting.toString()})(document, window, {
23781
+ findStore: ${findRendererAppScopeStore.toString()},
23782
+ findFamily: ${findRendererHostRpcFamily.toString()},
23783
+ resolve: ${resolveRendererHostRpc.toString()},
23784
+ hostIds: ${rendererHostRpcHostIds.toString()},
23785
+ composerHostIds: (composer) => {
23786
+ const source = composer?.matches?.('[data-codex-composer], [contenteditable="true"][role="textbox"]')
23787
+ ? { querySelectorAll: () => [composer] }
23788
+ : (composer ?? document);
23789
+ return discover(source);
23790
+ },
23791
+ portPrototype: MessagePort.prototype,
23792
+ });
23793
+ // Desktop 26.1027 moved AppServerManagers to the main process. Older builds
23794
+ // expose native managers in Renderer hook state; the main-process mode only
23795
+ // applies when none is visible and its per-Host RPC store is identified.
23796
+ const routing = (() => {
23797
+ if (window.__codexhostHostRoutingV1) return window.__codexhostHostRoutingV1;
23798
+ const native = discover(document);
23799
+ if (native.managers.length || native.registries.length) return installNative();
23800
+ const rpc = installRpc();
23801
+ if (rpc) return rpc;
23802
+ throw new Error('Renderer Host request manager is unavailable');
23803
+ })();
23310
23804
  // Publish a default draft policy only when its Host is unambiguous. Host
23311
23805
  // connections can be ready even when multiple Composers coexist.
23312
23806
  const composerRoute = routing.forComposer();
@@ -23341,6 +23835,119 @@ function installRendererDraftPrewarmPolicyDirect(renderer) {
23341
23835
  // packages/desktop-control/dist/renderer-control-session.js
23342
23836
  var startupTraceStartedAt = Date.now();
23343
23837
 
23838
+ // packages/desktop-control/dist/renderer-loaded-modules.js
23839
+ var record3 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
23840
+ var MAX_MODULES = 4096;
23841
+ function nativeModuleCatalogExpression(urls, complete, owner) {
23842
+ return `Object.defineProperty(globalThis, '__codexhostLoadedModulesV1', {
23843
+ configurable: true,
23844
+ value: Object.freeze({ owner: ${JSON.stringify(owner)}, documentUrl: location.href, complete: ${complete}, urls: Object.freeze(${JSON.stringify(urls)}) })
23845
+ }); void 0`;
23846
+ }
23847
+ async function installRendererLoadedModules(renderer) {
23848
+ const owner = crypto.randomUUID();
23849
+ const contexts = /* @__PURE__ */ new Map();
23850
+ const contextIds = /* @__PURE__ */ new Map();
23851
+ const dirty = /* @__PURE__ */ new Set();
23852
+ let ready = false;
23853
+ let disposed = false;
23854
+ let timer;
23855
+ let publishing = Promise.resolve();
23856
+ const flush = () => {
23857
+ clearTimeout(timer);
23858
+ timer = void 0;
23859
+ const pending = [...dirty];
23860
+ dirty.clear();
23861
+ publishing = publishing.catch(() => void 0).then(async () => {
23862
+ for (const uniqueId of pending) {
23863
+ const context = contexts.get(uniqueId);
23864
+ if (!context || disposed)
23865
+ continue;
23866
+ const response = await renderer.command("Runtime.evaluate", {
23867
+ expression: nativeModuleCatalogExpression([...context.urls], context.complete, owner),
23868
+ uniqueContextId: uniqueId
23869
+ });
23870
+ if (record3(response) && record3(response.exceptionDetails))
23871
+ throw new Error("Loaded Renderer module catalog publication failed");
23872
+ }
23873
+ });
23874
+ return publishing;
23875
+ };
23876
+ const schedule = (uniqueId) => {
23877
+ dirty.add(uniqueId);
23878
+ if (ready && timer === void 0)
23879
+ timer = setTimeout(() => {
23880
+ void flush().catch((error51) => {
23881
+ console.error("Could not publish loaded Renderer modules", error51);
23882
+ });
23883
+ }, 10);
23884
+ };
23885
+ const remove = (id2) => {
23886
+ const uniqueId = contextIds.get(id2);
23887
+ contextIds.delete(id2);
23888
+ if (uniqueId) {
23889
+ contexts.delete(uniqueId);
23890
+ dirty.delete(uniqueId);
23891
+ }
23892
+ };
23893
+ const listeners = [
23894
+ renderer.on("Runtime.executionContextCreated", (params) => {
23895
+ const context = record3(params) ? params.context : null;
23896
+ if (!record3(context) || typeof context.id !== "number" || typeof context.uniqueId !== "string" || !record3(context.auxData) || context.auxData.isDefault !== true)
23897
+ return;
23898
+ contextIds.set(context.id, context.uniqueId);
23899
+ contexts.set(context.uniqueId, { urls: /* @__PURE__ */ new Set(), complete: true });
23900
+ schedule(context.uniqueId);
23901
+ }),
23902
+ renderer.on("Runtime.executionContextDestroyed", (params) => {
23903
+ if (record3(params) && typeof params.executionContextId === "number")
23904
+ remove(params.executionContextId);
23905
+ }),
23906
+ renderer.on("Runtime.executionContextsCleared", () => {
23907
+ contextIds.clear();
23908
+ contexts.clear();
23909
+ dirty.clear();
23910
+ }),
23911
+ renderer.on("Debugger.scriptParsed", (params) => {
23912
+ if (!record3(params) || params.isModule !== true || params.hasSourceURL === true || typeof params.url !== "string" || typeof params.executionContextId !== "number")
23913
+ return;
23914
+ const uniqueId = contextIds.get(params.executionContextId);
23915
+ const context = uniqueId ? contexts.get(uniqueId) : null;
23916
+ if (!context || !uniqueId || context.urls.has(params.url))
23917
+ return;
23918
+ if (context.urls.size >= MAX_MODULES)
23919
+ context.complete = false;
23920
+ else
23921
+ context.urls.add(params.url);
23922
+ schedule(uniqueId);
23923
+ })
23924
+ ];
23925
+ const dispose = () => {
23926
+ disposed = true;
23927
+ clearTimeout(timer);
23928
+ for (const unsubscribe of listeners)
23929
+ unsubscribe();
23930
+ for (const uniqueId of contexts.keys())
23931
+ void renderer.command("Runtime.evaluate", {
23932
+ expression: `if (globalThis.__codexhostLoadedModulesV1 === undefined || globalThis.__codexhostLoadedModulesV1?.owner === ${JSON.stringify(owner)}) { ${nativeModuleCatalogExpression([], false, owner)} }`,
23933
+ uniqueContextId: uniqueId
23934
+ }).catch(() => void 0);
23935
+ contexts.clear();
23936
+ contextIds.clear();
23937
+ dirty.clear();
23938
+ };
23939
+ try {
23940
+ await renderer.command("Runtime.enable");
23941
+ await renderer.command("Debugger.enable");
23942
+ ready = true;
23943
+ await flush();
23944
+ return dispose;
23945
+ } catch (error51) {
23946
+ dispose();
23947
+ throw error51;
23948
+ }
23949
+ }
23950
+
23344
23951
  // packages/desktop-control/dist/renderer-cdp-control-session.js
23345
23952
  function isRecord2(value2) {
23346
23953
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
@@ -23475,15 +24082,17 @@ async function waitForBinding(renderer, enabledAgents, timeoutMs, pollIntervalMs
23475
24082
  }
23476
24083
  async function installTarget(target, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations) {
23477
24084
  const renderer = await operations.connect(target.webSocketDebuggerUrl);
24085
+ let disposeModules;
23478
24086
  try {
23479
- await renderer.command("Runtime.enable");
24087
+ disposeModules = await installRendererLoadedModules(renderer);
23480
24088
  await renderer.command("Page.enable");
23481
24089
  await renderer.command("Page.addScriptToEvaluateOnNewDocument", { source: rendererSource });
23482
24090
  await evaluateSource(renderer, rendererSource);
23483
24091
  const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(renderer);
23484
24092
  const binding = await waitForBinding(renderer, enabledAgents, timeoutMs, pollIntervalMs);
23485
- return { renderer, snapshot: { target, draftPrewarmPolicy, binding } };
24093
+ return { renderer, snapshot: { target, draftPrewarmPolicy, binding }, disposeModules };
23486
24094
  } catch (error51) {
24095
+ disposeModules?.();
23487
24096
  renderer.close();
23488
24097
  throw error51;
23489
24098
  }
@@ -23497,8 +24106,9 @@ var InstalledRendererCdpControlSession = class {
23497
24106
  pollIntervalMs;
23498
24107
  operations;
23499
24108
  currentSnapshot;
24109
+ disposeModules;
23500
24110
  #closed = false;
23501
- constructor(renderer, rendererCdpEndpoint, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, currentSnapshot) {
24111
+ constructor(renderer, rendererCdpEndpoint, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, currentSnapshot, disposeModules) {
23502
24112
  this.renderer = renderer;
23503
24113
  this.rendererCdpEndpoint = rendererCdpEndpoint;
23504
24114
  this.rendererSource = rendererSource;
@@ -23507,6 +24117,7 @@ var InstalledRendererCdpControlSession = class {
23507
24117
  this.pollIntervalMs = pollIntervalMs;
23508
24118
  this.operations = operations;
23509
24119
  this.currentSnapshot = currentSnapshot;
24120
+ this.disposeModules = disposeModules;
23510
24121
  }
23511
24122
  get snapshot() {
23512
24123
  return this.currentSnapshot;
@@ -23517,8 +24128,10 @@ var InstalledRendererCdpControlSession = class {
23517
24128
  const target = await waitForPrimaryTarget(this.rendererCdpEndpoint, this.operations, this.timeoutMs, this.pollIntervalMs, this.currentSnapshot.target.id);
23518
24129
  if (target.id !== this.currentSnapshot.target.id) {
23519
24130
  const replacement = await installTarget(target, this.rendererSource, this.enabledAgents, this.timeoutMs, this.pollIntervalMs, this.operations);
24131
+ this.disposeModules();
23520
24132
  this.renderer.close();
23521
24133
  this.renderer = replacement.renderer;
24134
+ this.disposeModules = replacement.disposeModules;
23522
24135
  this.currentSnapshot = replacement.snapshot;
23523
24136
  return this.currentSnapshot;
23524
24137
  }
@@ -23532,8 +24145,10 @@ var InstalledRendererCdpControlSession = class {
23532
24145
  return this.currentSnapshot;
23533
24146
  } catch {
23534
24147
  const replacement = await installTarget(target, this.rendererSource, this.enabledAgents, this.timeoutMs, this.pollIntervalMs, this.operations);
24148
+ this.disposeModules();
23535
24149
  this.renderer.close();
23536
24150
  this.renderer = replacement.renderer;
24151
+ this.disposeModules = replacement.disposeModules;
23537
24152
  this.currentSnapshot = replacement.snapshot;
23538
24153
  return this.currentSnapshot;
23539
24154
  }
@@ -23553,6 +24168,7 @@ var InstalledRendererCdpControlSession = class {
23553
24168
  if (this.#closed)
23554
24169
  return;
23555
24170
  this.#closed = true;
24171
+ this.disposeModules();
23556
24172
  this.renderer.close();
23557
24173
  }
23558
24174
  };
@@ -23568,7 +24184,7 @@ async function createRendererCdpControlSession(options2) {
23568
24184
  const operations = options2.operations ?? defaultOperations;
23569
24185
  const target = await waitForPrimaryTarget(options2.rendererCdpEndpoint, operations, timeoutMs, pollIntervalMs, void 0, options2.signal);
23570
24186
  const installed = await installTarget(target, options2.rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations);
23571
- return new InstalledRendererCdpControlSession(installed.renderer, options2.rendererCdpEndpoint, options2.rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, installed.snapshot);
24187
+ return new InstalledRendererCdpControlSession(installed.renderer, options2.rendererCdpEndpoint, options2.rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, installed.snapshot, installed.disposeModules);
23572
24188
  }
23573
24189
  function installRendererCdpControlSession(options2) {
23574
24190
  return createRendererCdpControlSession(options2);
@@ -25653,15 +26269,15 @@ var storedThreadMetadataV1Schema = external_exports.object({
25653
26269
  hostThreadId: storedHostThreadIdSchema,
25654
26270
  ...storedThreadMetadataFieldsShape
25655
26271
  }).passthrough();
25656
- function refineThreadRecord(record4, context) {
25657
- if (record4.state === "ready" && !record4.nativeSessionRef) {
26272
+ function refineThreadRecord(record5, context) {
26273
+ if (record5.state === "ready" && !record5.nativeSessionRef) {
25658
26274
  context.addIssue({
25659
26275
  code: "custom",
25660
26276
  path: ["nativeSessionRef"],
25661
26277
  message: "Ready Thread must have a Native Session Ref"
25662
26278
  });
25663
26279
  }
25664
- if (record4.nativeSessionRef && record4.nativeSessionRef.harnessId !== record4.harnessId) {
26280
+ if (record5.nativeSessionRef && record5.nativeSessionRef.harnessId !== record5.harnessId) {
25665
26281
  context.addIssue({
25666
26282
  code: "custom",
25667
26283
  path: ["nativeSessionRef", "harnessId"],
@@ -25670,7 +26286,7 @@ function refineThreadRecord(record4, context) {
25670
26286
  }
25671
26287
  const hostTurnIds = /* @__PURE__ */ new Set();
25672
26288
  const nativeTurnKeys = /* @__PURE__ */ new Set();
25673
- for (const [index, mapping] of record4.turnMappings.entries()) {
26289
+ for (const [index, mapping] of record5.turnMappings.entries()) {
25674
26290
  if (hostTurnIds.has(mapping.hostTurnId)) {
25675
26291
  context.addIssue({
25676
26292
  code: "custom",
@@ -25694,14 +26310,14 @@ function refineThreadRecord(record4, context) {
25694
26310
  ]) {
25695
26311
  if (!ref)
25696
26312
  continue;
25697
- if (ref.harnessId !== record4.harnessId) {
26313
+ if (ref.harnessId !== record5.harnessId) {
25698
26314
  context.addIssue({
25699
26315
  code: "custom",
25700
26316
  path: ["turnMappings", index, name, "harnessId"],
25701
26317
  message: "Turn Ref Harness must match the Thread Harness"
25702
26318
  });
25703
26319
  }
25704
- if (record4.nativeSessionRef && ref.nativeSessionId !== record4.nativeSessionRef.nativeSessionId) {
26320
+ if (record5.nativeSessionRef && ref.nativeSessionId !== record5.nativeSessionRef.nativeSessionId) {
25705
26321
  context.addIssue({
25706
26322
  code: "custom",
25707
26323
  path: ["turnMappings", index, name, "nativeSessionId"],
@@ -25733,7 +26349,7 @@ var storedDelegationRecordV1Schema = external_exports.object({
25733
26349
  taskDigest: external_exports.string().regex(/^[a-f0-9]{64}$/u),
25734
26350
  createdAt: isoDateSchema,
25735
26351
  updatedAt: isoDateSchema
25736
- }).strict().refine((record4) => record4.parentHostThreadId !== record4.childHostThreadId, {
26352
+ }).strict().refine((record5) => record5.parentHostThreadId !== record5.childHostThreadId, {
25737
26353
  path: ["childHostThreadId"],
25738
26354
  message: "Delegation child Thread must differ from its parent"
25739
26355
  });
@@ -25873,8 +26489,8 @@ var MappingStoreError = class extends Error {
25873
26489
  this.name = "MappingStoreError";
25874
26490
  }
25875
26491
  };
25876
- function cloneRecord(record4) {
25877
- return JSON.parse(JSON.stringify(record4));
26492
+ function cloneRecord(record5) {
26493
+ return JSON.parse(JSON.stringify(record5));
25878
26494
  }
25879
26495
  function nativeSessionKey(ref) {
25880
26496
  return `${ref.harnessId}\0${ref.nativeSessionId}`;
@@ -25917,22 +26533,22 @@ function withoutUnparsedUrlCredentials(value2) {
25917
26533
  const kept = keepUser && !userInfo.includes(":") ? `${userInfo}@` : "";
25918
26534
  return value2.slice(0, authorityStart) + kept + value2.slice(authorityStart + at + 1);
25919
26535
  }
25920
- function threadMetadataOf(record4) {
25921
- const fields = Object.fromEntries(THREAD_METADATA_FIELDS.filter((name) => record4[name] !== void 0).map((name) => [
26536
+ function threadMetadataOf(record5) {
26537
+ const fields = Object.fromEntries(THREAD_METADATA_FIELDS.filter((name) => record5[name] !== void 0).map((name) => [
25922
26538
  name,
25923
- record4[name]
26539
+ record5[name]
25924
26540
  ]));
25925
26541
  if (Object.keys(fields).length === 0)
25926
26542
  return null;
25927
- return { formatVersion: 1, hostThreadId: record4.hostThreadId, ...fields };
26543
+ return { formatVersion: 1, hostThreadId: record5.hostThreadId, ...fields };
25928
26544
  }
25929
- function withoutThreadMetadata(record4) {
25930
- const { projectId, daybreakEnabled, gitInfo, ...core } = record4;
26545
+ function withoutThreadMetadata(record5) {
26546
+ const { projectId, daybreakEnabled, gitInfo, ...core } = record5;
25931
26547
  void [projectId, daybreakEnabled, gitInfo];
25932
26548
  return core;
25933
26549
  }
25934
- function withThreadMetadata(record4, metadata) {
25935
- const core = withoutThreadMetadata(record4);
26550
+ function withThreadMetadata(record5, metadata) {
26551
+ const core = withoutThreadMetadata(record5);
25936
26552
  for (const name of THREAD_METADATA_FIELDS) {
25937
26553
  if (metadata[name] !== void 0)
25938
26554
  Object.assign(core, { [name]: metadata[name] });
@@ -26117,13 +26733,13 @@ var MappingStore = class {
26117
26733
  for (const name of names) {
26118
26734
  const primary = path18.join(this.#threadsDirectory, name);
26119
26735
  const backup = path18.join(this.#backupsDirectory, name);
26120
- let record4 = null;
26736
+ let record5 = null;
26121
26737
  try {
26122
- record4 = await this.#readRecord(primary, name);
26738
+ record5 = await this.#readRecord(primary, name);
26123
26739
  } catch (primaryError) {
26124
26740
  try {
26125
- record4 = await this.#readRecord(backup, name);
26126
- await this.#replaceFile(primary, record4, false);
26741
+ record5 = await this.#readRecord(backup, name);
26742
+ await this.#replaceFile(primary, record5, false);
26127
26743
  } catch (backupError) {
26128
26744
  const quarantine = path18.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid`);
26129
26745
  await rename10(primary, quarantine).catch(() => void 0);
@@ -26132,20 +26748,20 @@ var MappingStore = class {
26132
26748
  continue;
26133
26749
  }
26134
26750
  }
26135
- if (record4.state === "creating" && !record4.nativeSessionRef) {
26751
+ if (record5.state === "creating" && !record5.nativeSessionRef) {
26136
26752
  await rm10(primary, { force: true });
26137
26753
  await rm10(backup, { force: true });
26138
- await rm10(this.#metadataPath(record4.hostThreadId), { force: true });
26754
+ await rm10(this.#metadataPath(record5.hostThreadId), { force: true });
26139
26755
  continue;
26140
26756
  }
26141
- const metadata = await this.#readMetadata(record4.hostThreadId);
26757
+ const metadata = await this.#readMetadata(record5.hostThreadId);
26142
26758
  if (metadata) {
26143
- record4 = withThreadMetadata(record4, metadata);
26144
- } else if (threadMetadataOf(record4)) {
26145
- await this.#writeMetadataFile(record4.hostThreadId, threadMetadataOf(record4));
26146
- await this.#replaceFile(primary, record4, false);
26759
+ record5 = withThreadMetadata(record5, metadata);
26760
+ } else if (threadMetadataOf(record5)) {
26761
+ await this.#writeMetadataFile(record5.hostThreadId, threadMetadataOf(record5));
26762
+ await this.#replaceFile(primary, record5, false);
26147
26763
  }
26148
- this.#records.set(record4.hostThreadId, record4);
26764
+ this.#records.set(record5.hostThreadId, record5);
26149
26765
  }
26150
26766
  await Promise.all((await readdir4(this.#metadataDirectory)).filter((name) => name.endsWith(".json") && !this.#records.has(name.slice(0, -5))).map((name) => rm10(path18.join(this.#metadataDirectory, name), { force: true })));
26151
26767
  const delegationNames = (await readdir4(this.#delegationsDirectory)).filter((name) => name.endsWith(".json"));
@@ -26182,8 +26798,8 @@ var MappingStore = class {
26182
26798
  }
26183
26799
  async getThread(hostThreadId) {
26184
26800
  this.#requireInitialized();
26185
- const record4 = this.#records.get(hostThreadId);
26186
- return record4 ? cloneRecord(record4) : null;
26801
+ const record5 = this.#records.get(hostThreadId);
26802
+ return record5 ? cloneRecord(record5) : null;
26187
26803
  }
26188
26804
  async listThreads() {
26189
26805
  this.#requireInitialized();
@@ -26196,8 +26812,8 @@ var MappingStore = class {
26196
26812
  }
26197
26813
  async getDelegation(delegationId) {
26198
26814
  this.#requireInitialized();
26199
- const record4 = this.#delegations.get(delegationId);
26200
- return record4 ? cloneRecord(record4) : null;
26815
+ const record5 = this.#delegations.get(delegationId);
26816
+ return record5 ? cloneRecord(record5) : null;
26201
26817
  }
26202
26818
  async getDelegationByChild(childHostThreadId) {
26203
26819
  this.#requireInitialized();
@@ -26211,12 +26827,12 @@ var MappingStore = class {
26211
26827
  }
26212
26828
  async listDelegations(parentHostThreadId) {
26213
26829
  this.#requireInitialized();
26214
- return [...this.#delegations.values()].filter((record4) => !parentHostThreadId || record4.parentHostThreadId === parentHostThreadId).map(cloneRecord);
26830
+ return [...this.#delegations.values()].filter((record5) => !parentHostThreadId || record5.parentHostThreadId === parentHostThreadId).map(cloneRecord);
26215
26831
  }
26216
26832
  async findRecentDelegation(input) {
26217
26833
  this.#requireInitialized();
26218
26834
  const threshold = input.since.getTime();
26219
- const found = [...this.#delegations.values()].filter((record4) => record4.parentHostThreadId === input.parentHostThreadId && record4.targetHarnessId === input.targetHarnessId && record4.taskDigest === input.taskDigest && Date.parse(record4.createdAt) >= threshold).toSorted((left, right) => Date.parse(right.createdAt) - Date.parse(left.createdAt))[0];
26835
+ const found = [...this.#delegations.values()].filter((record5) => record5.parentHostThreadId === input.parentHostThreadId && record5.targetHarnessId === input.targetHarnessId && record5.taskDigest === input.taskDigest && Date.parse(record5.createdAt) >= threshold).toSorted((left, right) => Date.parse(right.createdAt) - Date.parse(left.createdAt))[0];
26220
26836
  return found ? cloneRecord(found) : null;
26221
26837
  }
26222
26838
  async createDelegation(input) {
@@ -26231,7 +26847,7 @@ var MappingStore = class {
26231
26847
  throw new MappingStoreError("DUPLICATE_CREATE_REQUEST", "Delegation Request ID already exists");
26232
26848
  }
26233
26849
  const timestamp = this.#now().toISOString();
26234
- const record4 = storedDelegationRecordV1Schema.parse({
26850
+ const record5 = storedDelegationRecordV1Schema.parse({
26235
26851
  formatVersion: 1,
26236
26852
  revision: 1,
26237
26853
  ...input,
@@ -26239,10 +26855,10 @@ var MappingStore = class {
26239
26855
  createdAt: timestamp,
26240
26856
  updatedAt: timestamp
26241
26857
  });
26242
- await this.#replaceDelegationFile(record4);
26243
- this.#delegations.set(record4.delegationId, record4);
26858
+ await this.#replaceDelegationFile(record5);
26859
+ this.#delegations.set(record5.delegationId, record5);
26244
26860
  this.#rebuildIndexes();
26245
- return cloneRecord(record4);
26861
+ return cloneRecord(record5);
26246
26862
  }
26247
26863
  async setDelegationStatus(delegationId, status2) {
26248
26864
  this.#requireInitialized();
@@ -26293,7 +26909,7 @@ var MappingStore = class {
26293
26909
  throw new MappingStoreError("DUPLICATE_THREAD_ID", "Host Thread ID already exists");
26294
26910
  }
26295
26911
  const timestamp = this.#now().toISOString();
26296
- const record4 = storedThreadRecordV1Schema.parse({
26912
+ const record5 = storedThreadRecordV1Schema.parse({
26297
26913
  formatVersion: 1,
26298
26914
  revision: 1,
26299
26915
  hostThreadId: input.hostThreadId,
@@ -26312,8 +26928,8 @@ var MappingStore = class {
26312
26928
  createdAt: timestamp,
26313
26929
  updatedAt: timestamp
26314
26930
  });
26315
- await this.#writeNew(record4);
26316
- result = cloneRecord(record4);
26931
+ await this.#writeNew(record5);
26932
+ result = cloneRecord(record5);
26317
26933
  });
26318
26934
  if (!result)
26319
26935
  throw new MappingStoreError("IO_ERROR", "Provisional create produced no result");
@@ -26484,8 +27100,8 @@ var MappingStore = class {
26484
27100
  async removeProvisional(hostThreadId) {
26485
27101
  this.#requireInitialized();
26486
27102
  await this.#enqueue(async () => {
26487
- const record4 = this.#records.get(hostThreadId);
26488
- if (record4?.state === "ready") {
27103
+ const record5 = this.#records.get(hostThreadId);
27104
+ if (record5?.state === "ready") {
26489
27105
  throw new MappingStoreError("MAPPING_CONFLICT", "Ready Thread cannot be removed as provisional");
26490
27106
  }
26491
27107
  await this.#remove(hostThreadId);
@@ -26523,13 +27139,17 @@ var MappingStore = class {
26523
27139
  await this.#enqueue(() => this.#remove(hostThreadId));
26524
27140
  }
26525
27141
  async #remove(hostThreadId) {
26526
- if (!this.#records.has(hostThreadId))
27142
+ const current = this.#records.get(hostThreadId);
27143
+ if (!current)
26527
27144
  return;
26528
- await Promise.all([
26529
- rm10(this.#recordPath(hostThreadId), { force: true }),
26530
- rm10(this.#backupPath(hostThreadId), { force: true }),
26531
- rm10(this.#metadataPath(hostThreadId), { force: true })
26532
- ]);
27145
+ await rm10(this.#recordPath(hostThreadId), { force: true });
27146
+ try {
27147
+ await rm10(this.#backupPath(hostThreadId), { force: true });
27148
+ await rm10(this.#metadataPath(hostThreadId), { force: true });
27149
+ } catch (error51) {
27150
+ await this.#replaceFile(this.#recordPath(hostThreadId), current, false);
27151
+ throw error51;
27152
+ }
26533
27153
  this.#records.delete(hostThreadId);
26534
27154
  this.#rebuildIndexes();
26535
27155
  }
@@ -26612,25 +27232,25 @@ var MappingStore = class {
26612
27232
  }
26613
27233
  return merged;
26614
27234
  }
26615
- async #writeNew(record4) {
26616
- this.#validateGlobal(record4, null);
26617
- await this.#replaceFile(this.#recordPath(record4.hostThreadId), record4, false);
26618
- this.#records.set(record4.hostThreadId, record4);
27235
+ async #writeNew(record5) {
27236
+ this.#validateGlobal(record5, null);
27237
+ await this.#replaceFile(this.#recordPath(record5.hostThreadId), record5, false);
27238
+ this.#records.set(record5.hostThreadId, record5);
26619
27239
  this.#rebuildIndexes();
26620
27240
  }
26621
- async #replaceFile(target, record4, preserveBackup) {
27241
+ async #replaceFile(target, record5, preserveBackup) {
26622
27242
  const temp = `${target}.tmp-${randomUUID9()}`;
26623
27243
  let handle = null;
26624
27244
  try {
26625
- await this.#beforeReplace?.(cloneRecord(record4));
27245
+ await this.#beforeReplace?.(cloneRecord(record5));
26626
27246
  handle = await open7(temp, "wx", constants3.S_IRUSR | constants3.S_IWUSR);
26627
- await handle.writeFile(`${JSON.stringify(withoutThreadMetadata(record4), null, 2)}
27247
+ await handle.writeFile(`${JSON.stringify(withoutThreadMetadata(record5), null, 2)}
26628
27248
  `, "utf8");
26629
27249
  await handle.sync();
26630
27250
  await handle.close();
26631
27251
  handle = null;
26632
27252
  if (preserveBackup && await exists(target)) {
26633
- await copyFile3(target, this.#backupPath(record4.hostThreadId));
27253
+ await copyFile3(target, this.#backupPath(record5.hostThreadId));
26634
27254
  }
26635
27255
  await rename10(temp, target);
26636
27256
  } catch (error51) {
@@ -26691,13 +27311,13 @@ var MappingStore = class {
26691
27311
  return null;
26692
27312
  }
26693
27313
  }
26694
- async #replaceDelegationFile(record4) {
26695
- const target = this.#delegationPath(record4.delegationId);
27314
+ async #replaceDelegationFile(record5) {
27315
+ const target = this.#delegationPath(record5.delegationId);
26696
27316
  const temp = `${target}.tmp-${randomUUID9()}`;
26697
27317
  let handle = null;
26698
27318
  try {
26699
27319
  handle = await open7(temp, "wx", constants3.S_IRUSR | constants3.S_IWUSR);
26700
- await handle.writeFile(`${JSON.stringify(record4, null, 2)}
27320
+ await handle.writeFile(`${JSON.stringify(record5, null, 2)}
26701
27321
  `, "utf8");
26702
27322
  await handle.sync();
26703
27323
  await handle.close();
@@ -26781,18 +27401,18 @@ var MappingStore = class {
26781
27401
  });
26782
27402
  }
26783
27403
  }
26784
- #validateGlobal(record4, replacing) {
26785
- const duplicateCreate = this.#createRequests.get(record4.createRequestId);
27404
+ #validateGlobal(record5, replacing) {
27405
+ const duplicateCreate = this.#createRequests.get(record5.createRequestId);
26786
27406
  if (duplicateCreate && duplicateCreate !== replacing) {
26787
27407
  throw new MappingStoreError("DUPLICATE_CREATE_REQUEST", "Create request is already stored");
26788
27408
  }
26789
- if (record4.nativeSessionRef && !record4.subagent) {
26790
- const duplicateSession = this.#nativeSessions.get(nativeSessionKey(record4.nativeSessionRef));
27409
+ if (record5.nativeSessionRef && !record5.subagent) {
27410
+ const duplicateSession = this.#nativeSessions.get(nativeSessionKey(record5.nativeSessionRef));
26791
27411
  if (duplicateSession && duplicateSession !== replacing) {
26792
27412
  throw new MappingStoreError("DUPLICATE_NATIVE_SESSION", "Native Session is already mapped");
26793
27413
  }
26794
27414
  }
26795
- for (const mapping of record4.turnMappings) {
27415
+ for (const mapping of record5.turnMappings) {
26796
27416
  const duplicateHostTurn = this.#hostTurns.get(mapping.hostTurnId);
26797
27417
  if (duplicateHostTurn && duplicateHostTurn !== replacing) {
26798
27418
  throw new MappingStoreError("MAPPING_CONFLICT", "Host Turn is already mapped");
@@ -26822,14 +27442,14 @@ var MappingStore = class {
26822
27442
  this.#delegationRequests.set(delegation.requestId, delegation.delegationId);
26823
27443
  }
26824
27444
  }
26825
- for (const record4 of this.#records.values()) {
26826
- this.#validateGlobal(record4, record4.hostThreadId);
26827
- this.#createRequests.set(record4.createRequestId, record4.hostThreadId);
26828
- if (record4.nativeSessionRef && !record4.subagent) {
26829
- this.#nativeSessions.set(nativeSessionKey(record4.nativeSessionRef), record4.hostThreadId);
27445
+ for (const record5 of this.#records.values()) {
27446
+ this.#validateGlobal(record5, record5.hostThreadId);
27447
+ this.#createRequests.set(record5.createRequestId, record5.hostThreadId);
27448
+ if (record5.nativeSessionRef && !record5.subagent) {
27449
+ this.#nativeSessions.set(nativeSessionKey(record5.nativeSessionRef), record5.hostThreadId);
26830
27450
  }
26831
- for (const mapping of record4.turnMappings) {
26832
- this.#hostTurns.set(mapping.hostTurnId, record4.hostThreadId);
27451
+ for (const mapping of record5.turnMappings) {
27452
+ this.#hostTurns.set(mapping.hostTurnId, record5.hostThreadId);
26833
27453
  this.#nativeTurns.set(nativeTurnKey(mapping), mapping.hostTurnId);
26834
27454
  }
26835
27455
  }
@@ -28260,16 +28880,16 @@ function planFromTodoValue(value2) {
28260
28880
  return fromText;
28261
28881
  }
28262
28882
  }
28263
- const record4 = unwrapToolRecord(value2);
28264
- if (!record4)
28883
+ const record5 = unwrapToolRecord(value2);
28884
+ if (!record5)
28265
28885
  return planFromChecklistText(typeof value2 === "string" ? value2 : null);
28266
- if (isRecord10(record4.TodosUpdated)) {
28267
- const nested = planFromTodoValue(record4.TodosUpdated);
28886
+ if (isRecord10(record5.TodosUpdated)) {
28887
+ const nested = planFromTodoValue(record5.TodosUpdated);
28268
28888
  if (nested)
28269
28889
  return nested;
28270
28890
  }
28271
- const explanation = nestedString(record4, ["explanation", "message", "summary"]) ?? null;
28272
- const list = coerceTodoList(record4.todos ?? record4.items ?? record4.plan ?? record4.tasks ?? record4.entries);
28891
+ const explanation = nestedString(record5, ["explanation", "message", "summary"]) ?? null;
28892
+ const list = coerceTodoList(record5.todos ?? record5.items ?? record5.plan ?? record5.tasks ?? record5.entries);
28273
28893
  if (!list || list.length === 0)
28274
28894
  return planFromChecklistText(explanation);
28275
28895
  const plan = [];
@@ -28299,8 +28919,8 @@ function coerceTodoList(value2) {
28299
28919
  const parsed2 = JSON.parse(trimmed);
28300
28920
  if (Array.isArray(parsed2))
28301
28921
  return parsed2;
28302
- const record4 = unwrapToolRecord(parsed2);
28303
- return record4 ? coerceTodoList(record4.todos ?? record4.items ?? record4.plan ?? record4.tasks ?? record4.entries) : null;
28922
+ const record5 = unwrapToolRecord(parsed2);
28923
+ return record5 ? coerceTodoList(record5.todos ?? record5.items ?? record5.plan ?? record5.tasks ?? record5.entries) : null;
28304
28924
  } catch {
28305
28925
  return planFromChecklistText(trimmed)?.plan.map(({ step, status: status2 }) => ({ content: step, status: status2 })) ?? null;
28306
28926
  }
@@ -30065,10 +30685,12 @@ function decodeCreateRoute(request) {
30065
30685
  return null;
30066
30686
  const pluginRoute = decodeHarnessPluginRoute(request.params.model);
30067
30687
  if (pluginRoute) {
30688
+ const { prewarm, ...selection } = pluginRoute;
30068
30689
  return {
30069
30690
  harnessId: pluginRoute.harnessId,
30070
30691
  routeMode: "native",
30071
- transportModelId: request.params.model,
30692
+ transportModelId: prewarm ? encodeHarnessPluginRoute(selection) : request.params.model,
30693
+ ...prewarm ? { prewarm } : {},
30072
30694
  ...pluginRoute.model ? { model: pluginRoute.model } : {},
30073
30695
  ...pluginRoute.thinkingOptionId ? { thinkingOptionId: pluginRoute.thinkingOptionId } : {},
30074
30696
  ...pluginRoute.permissionModeId ? { permissionModeId: pluginRoute.permissionModeId } : {}
@@ -30385,7 +31007,7 @@ import { open as open8, realpath as realpath4 } from "node:fs/promises";
30385
31007
  import path21 from "node:path";
30386
31008
  var MAX_METADATA_BYTES = 1024 * 1024;
30387
31009
  var REFERENCE_READ_TIMEOUT_MS = 2e3;
30388
- var record3 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
31010
+ var record4 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
30389
31011
  async function nativeThreadSupportsReferences(input) {
30390
31012
  try {
30391
31013
  let timer;
@@ -30395,8 +31017,8 @@ async function nativeThreadSupportsReferences(input) {
30395
31017
  timer = setTimeout(() => resolve(null), REFERENCE_READ_TIMEOUT_MS);
30396
31018
  })
30397
31019
  ]).finally(() => clearTimeout(timer));
30398
- const result = record3(response) && record3(response.result) ? response.result : null;
30399
- const thread = result && record3(result.thread) ? result.thread : null;
31020
+ const result = record4(response) && record4(response.result) ? response.result : null;
31021
+ const thread = result && record4(result.thread) ? result.thread : null;
30400
31022
  if (thread?.id !== input.threadId || typeof thread.path !== "string") return false;
30401
31023
  const rollout = await realpath4(thread.path);
30402
31024
  let allowed = false;
@@ -30418,13 +31040,13 @@ async function nativeThreadSupportsReferences(input) {
30418
31040
  const newline2 = bytes.subarray(0, bytesRead).indexOf(10);
30419
31041
  if (newline2 < 0) return false;
30420
31042
  const line = JSON.parse(bytes.subarray(0, newline2).toString("utf8"));
30421
- if (!record3(line) || line.type !== "session_meta" || !record3(line.payload)) return false;
31043
+ if (!record4(line) || line.type !== "session_meta" || !record4(line.payload)) return false;
30422
31044
  const metadata = line.payload;
30423
31045
  if (metadata.id !== input.threadId || !Array.isArray(metadata.dynamic_tools)) return false;
30424
31046
  return metadata.dynamic_tools.some((tool) => {
30425
- if (!record3(tool)) return false;
31047
+ if (!record4(tool)) return false;
30426
31048
  if (tool.type === "namespace") {
30427
- return tool.name === "codex_app" && Array.isArray(tool.tools) && tool.tools.some((item) => record3(item) && item.name === "read_thread");
31049
+ return tool.name === "codex_app" && Array.isArray(tool.tools) && tool.tools.some((item) => record4(item) && item.name === "read_thread");
30428
31050
  }
30429
31051
  return tool.name === "read_thread";
30430
31052
  });
@@ -30536,7 +31158,7 @@ var HarnessAccountInspectionCache = class {
30536
31158
  };
30537
31159
 
30538
31160
  // packages/host-runtime/src/app-server-host.ts
30539
- import { createHash as createHash9, randomUUID as randomUUID16 } from "node:crypto";
31161
+ import { createHash as createHash9, randomUUID as randomUUID17 } from "node:crypto";
30540
31162
  import os8 from "node:os";
30541
31163
  import path25 from "node:path";
30542
31164
 
@@ -30563,21 +31185,21 @@ function subagentMaterializer(store, parent, previousParent) {
30563
31185
  const legacyRecords = () => legacy ??= store.listThreads().then((records) => {
30564
31186
  const byRequest = /* @__PURE__ */ new Map();
30565
31187
  const children = /* @__PURE__ */ new Map();
30566
- for (const record4 of records) {
30567
- if (!record4.subagent || record4.harnessId !== parent.harnessId || !record4.nativeSessionRef)
31188
+ for (const record5 of records) {
31189
+ if (!record5.subagent || record5.harnessId !== parent.harnessId || !record5.nativeSessionRef)
30568
31190
  continue;
30569
31191
  const owner = {
30570
- hostThreadId: record4.subagent.parentHostThreadId,
30571
- harnessId: record4.harnessId
31192
+ hostThreadId: record5.subagent.parentHostThreadId,
31193
+ harnessId: record5.harnessId
30572
31194
  };
30573
31195
  const key = childCreateRequest(
30574
31196
  owner,
30575
- record4.nativeSessionRef,
30576
- record4.subagent.nativeSubagentId
31197
+ record5.nativeSessionRef,
31198
+ record5.subagent.nativeSubagentId
30577
31199
  );
30578
- if (!byRequest.has(key) || record4.state === "ready") byRequest.set(key, record4);
31200
+ if (!byRequest.has(key) || record5.state === "ready") byRequest.set(key, record5);
30579
31201
  const siblings = children.get(owner.hostThreadId) ?? [];
30580
- siblings.push(record4);
31202
+ siblings.push(record5);
30581
31203
  children.set(owner.hostThreadId, siblings);
30582
31204
  }
30583
31205
  return { byRequest, children };
@@ -30647,11 +31269,11 @@ function subagentMaterializer(store, parent, previousParent) {
30647
31269
  async function materializeExternalSubagent(store, parent, child) {
30648
31270
  return subagentMaterializer(store, parent)(child);
30649
31271
  }
30650
- async function projectExternalSnapshot(store, record4, snapshot2, previousParent) {
30651
- const materialize = subagentMaterializer(store, record4, previousParent);
31272
+ async function projectExternalSnapshot(store, record5, snapshot2, previousParent) {
31273
+ const materialize = subagentMaterializer(store, record5, previousParent);
30652
31274
  const turns = [];
30653
31275
  for (const [index, turn] of snapshot2.turns.entries()) {
30654
- const mapping = record4.turnMappings[index];
31276
+ const mapping = record5.turnMappings[index];
30655
31277
  if (!mapping) throw new Error("External Snapshot mapping is incomplete");
30656
31278
  const items = await Promise.all(
30657
31279
  turn.items.map(async (entry) => {
@@ -30667,9 +31289,9 @@ async function projectExternalSnapshot(store, record4, snapshot2, previousParent
30667
31289
  );
30668
31290
  turns.push(
30669
31291
  projectHistoricalTurn({
30670
- threadId: record4.hostThreadId,
31292
+ threadId: record5.hostThreadId,
30671
31293
  turnId: mapping.hostTurnId,
30672
- cwd: record4.cwd,
31294
+ cwd: record5.cwd,
30673
31295
  snapshot: { ...turn, items }
30674
31296
  })
30675
31297
  );
@@ -30776,11 +31398,11 @@ var ExternalThreadRepository = class {
30776
31398
  removeThread(hostThreadId) {
30777
31399
  return this.store.removeThread(hostThreadId);
30778
31400
  }
30779
- async persistTurn(record4, hostTurnId, nativeTurnRef, nativeCheckpointRef) {
30780
- if (record4.state !== "ready" || !record4.nativeSessionRef || nativeTurnRef.harnessId !== record4.harnessId || nativeTurnRef.nativeSessionId !== record4.nativeSessionRef.nativeSessionId || nativeCheckpointRef && (nativeCheckpointRef.harnessId !== record4.harnessId || nativeCheckpointRef.nativeSessionId !== record4.nativeSessionRef.nativeSessionId)) {
31401
+ async persistTurn(record5, hostTurnId, nativeTurnRef, nativeCheckpointRef) {
31402
+ if (record5.state !== "ready" || !record5.nativeSessionRef || nativeTurnRef.harnessId !== record5.harnessId || nativeTurnRef.nativeSessionId !== record5.nativeSessionRef.nativeSessionId || nativeCheckpointRef && (nativeCheckpointRef.harnessId !== record5.harnessId || nativeCheckpointRef.nativeSessionId !== record5.nativeSessionRef.nativeSessionId)) {
30781
31403
  throw new Error("Live Turn identity does not belong to the stored Thread");
30782
31404
  }
30783
- return this.store.upsertTurnMappings(record4.hostThreadId, [
31405
+ return this.store.upsertTurnMappings(record5.hostThreadId, [
30784
31406
  {
30785
31407
  hostTurnId,
30786
31408
  nativeTurnRef,
@@ -30788,12 +31410,12 @@ var ExternalThreadRepository = class {
30788
31410
  }
30789
31411
  ]);
30790
31412
  }
30791
- async commitDerivedSnapshot(record4, nativeSessionRef, snapshot2) {
30792
- if (record4.state !== "creating" || record4.turnMappings.length !== 0) {
31413
+ async commitDerivedSnapshot(record5, nativeSessionRef, snapshot2) {
31414
+ if (record5.state !== "creating" || record5.turnMappings.length !== 0) {
30793
31415
  throw new Error("Derived Thread must be provisional before Snapshot commit");
30794
31416
  }
30795
31417
  const mappings = snapshot2.turns.map((turn) => {
30796
- if (turn.nativeTurnRef.harnessId !== record4.harnessId || turn.nativeTurnRef.nativeSessionId !== nativeSessionRef.nativeSessionId || turn.checkpoint && (turn.checkpoint.harnessId !== record4.harnessId || turn.checkpoint.nativeSessionId !== nativeSessionRef.nativeSessionId)) {
31418
+ if (turn.nativeTurnRef.harnessId !== record5.harnessId || turn.nativeTurnRef.nativeSessionId !== nativeSessionRef.nativeSessionId || turn.checkpoint && (turn.checkpoint.harnessId !== record5.harnessId || turn.checkpoint.nativeSessionId !== nativeSessionRef.nativeSessionId)) {
30797
31419
  throw new Error("Derived Snapshot identity does not belong to its Native Session");
30798
31420
  }
30799
31421
  return {
@@ -30803,7 +31425,7 @@ var ExternalThreadRepository = class {
30803
31425
  };
30804
31426
  });
30805
31427
  const nextRecord = await this.store.commitReady({
30806
- hostThreadId: record4.hostThreadId,
31428
+ hostThreadId: record5.hostThreadId,
30807
31429
  nativeSessionRef,
30808
31430
  turnMappings: mappings
30809
31431
  });
@@ -30884,8 +31506,8 @@ var ExternalThreadRepository = class {
30884
31506
  turns: await projectExternalSnapshot(this.store, nextRecord, snapshot2, current)
30885
31507
  };
30886
31508
  }
30887
- async sessionTreeId(record4) {
30888
- let current = record4;
31509
+ async sessionTreeId(record5) {
31510
+ let current = record5;
30889
31511
  const visited = /* @__PURE__ */ new Set();
30890
31512
  while (current.subagent || current.forkSource) {
30891
31513
  if (visited.has(current.hostThreadId))
@@ -30899,21 +31521,21 @@ var ExternalThreadRepository = class {
30899
31521
  }
30900
31522
  return current.hostThreadId;
30901
31523
  }
30902
- async alignSnapshot(record4, snapshot2) {
30903
- const nativeSessionRef = record4.nativeSessionRef;
30904
- if (record4.state === "creating" && !nativeSessionRef && snapshot2.turns.length === 0) {
30905
- return { record: record4, turns: [] };
31524
+ async alignSnapshot(record5, snapshot2) {
31525
+ const nativeSessionRef = record5.nativeSessionRef;
31526
+ if (record5.state === "creating" && !nativeSessionRef && snapshot2.turns.length === 0) {
31527
+ return { record: record5, turns: [] };
30906
31528
  }
30907
- if (!nativeSessionRef || record4.state !== "ready") {
31529
+ if (!nativeSessionRef || record5.state !== "ready") {
30908
31530
  throw new Error("External Thread has no committed Native Session identity");
30909
31531
  }
30910
31532
  for (const turn of snapshot2.turns) {
30911
- if (turn.nativeTurnRef.harnessId !== record4.harnessId || turn.nativeTurnRef.nativeSessionId !== nativeSessionRef.nativeSessionId || turn.checkpoint && (turn.checkpoint.harnessId !== record4.harnessId || turn.checkpoint.nativeSessionId !== nativeSessionRef.nativeSessionId)) {
31533
+ if (turn.nativeTurnRef.harnessId !== record5.harnessId || turn.nativeTurnRef.nativeSessionId !== nativeSessionRef.nativeSessionId || turn.checkpoint && (turn.checkpoint.harnessId !== record5.harnessId || turn.checkpoint.nativeSessionId !== nativeSessionRef.nativeSessionId)) {
30912
31534
  throw new Error("External Snapshot identity does not belong to the stored Thread");
30913
31535
  }
30914
31536
  }
30915
31537
  const mappingsByNative = new Map(
30916
- record4.turnMappings.map(
31538
+ record5.turnMappings.map(
30917
31539
  (mapping) => [nativeTurnKey2(mapping.nativeTurnRef), mapping]
30918
31540
  )
30919
31541
  );
@@ -30934,11 +31556,11 @@ var ExternalThreadRepository = class {
30934
31556
  };
30935
31557
  });
30936
31558
  const orderedMappings = aligned.map(({ mapping }) => mapping);
30937
- const mappingsChanged = orderedMappings.length !== record4.turnMappings.length || orderedMappings.some((mapping, index) => {
30938
- const persisted = record4.turnMappings[index];
31559
+ const mappingsChanged = orderedMappings.length !== record5.turnMappings.length || orderedMappings.some((mapping, index) => {
31560
+ const persisted = record5.turnMappings[index];
30939
31561
  return !persisted || !sameMapping(mapping, persisted);
30940
31562
  });
30941
- const nextRecord = mappingsChanged ? await this.store.reconcileTurnMappings(record4.hostThreadId, orderedMappings) : record4;
31563
+ const nextRecord = mappingsChanged ? await this.store.reconcileTurnMappings(record5.hostThreadId, orderedMappings) : record5;
30942
31564
  return {
30943
31565
  record: nextRecord,
30944
31566
  turns: await projectExternalSnapshot(this.store, nextRecord, snapshot2)
@@ -30966,9 +31588,9 @@ function threadSectionFields(placement) {
30966
31588
  } : { section: null, sectionEnteredAt: null };
30967
31589
  }
30968
31590
  function externalThreadValue(input) {
30969
- const { record: record4 } = input;
30970
- const createdAt = Math.floor(Date.parse(record4.createdAt) / 1e3);
30971
- const updatedAt = Math.floor(Date.parse(record4.updatedAt) / 1e3);
31591
+ const { record: record5 } = input;
31592
+ const createdAt = Math.floor(Date.parse(record5.createdAt) / 1e3);
31593
+ const updatedAt = Math.floor(Date.parse(record5.updatedAt) / 1e3);
30972
31594
  const preview = input.turns.flatMap((turn) => Array.isArray(turn.items) ? turn.items : []).find(
30973
31595
  (item) => typeof item === "object" && item !== null && !Array.isArray(item) && item.type === "userMessage"
30974
31596
  );
@@ -30977,22 +31599,22 @@ function externalThreadValue(input) {
30977
31599
  (part) => typeof part === "object" && part !== null && !Array.isArray(part) && part.type === "text"
30978
31600
  ).map((part) => typeof part.text === "string" ? part.text : "").join("\n") : "";
30979
31601
  return {
30980
- id: record4.hostThreadId,
31602
+ id: record5.hostThreadId,
30981
31603
  sessionId: input.sessionId,
30982
31604
  path: null,
30983
- cwd: record4.cwd,
30984
- source: record4.subagent ? {
31605
+ cwd: record5.cwd,
31606
+ source: record5.subagent ? {
30985
31607
  subAgent: {
30986
31608
  thread_spawn: {
30987
- parent_thread_id: record4.subagent.parentHostThreadId,
31609
+ parent_thread_id: record5.subagent.parentHostThreadId,
30988
31610
  depth: 1,
30989
31611
  agent_path: null,
30990
- agent_nickname: record4.title || null,
30991
- agent_role: record4.subagent.role ?? null
31612
+ agent_nickname: record5.title || null,
31613
+ agent_role: record5.subagent.role ?? null
30992
31614
  }
30993
31615
  }
30994
31616
  } : "vscode",
30995
- threadSource: record4.subagent ? "subAgentThreadSpawn" : null,
31617
+ threadSource: record5.subagent ? "subAgentThreadSpawn" : null,
30996
31618
  modelProvider: "codexhost",
30997
31619
  cliVersion: "codexhost",
30998
31620
  createdAt,
@@ -31001,23 +31623,23 @@ function externalThreadValue(input) {
31001
31623
  status: input.loaded === false ? { type: "notLoaded" } : input.running ? { type: "active", activeFlags: [] } : { type: "idle" },
31002
31624
  turns: input.turns,
31003
31625
  preview: previewText,
31004
- name: record4.title || null,
31005
- gitInfo: record4.gitInfo ? {
31006
- branch: record4.gitInfo.branch ?? null,
31007
- originUrl: record4.gitInfo.originUrl ?? null,
31008
- sha: record4.gitInfo.sha ?? null
31626
+ name: record5.title || null,
31627
+ gitInfo: record5.gitInfo ? {
31628
+ branch: record5.gitInfo.branch ?? null,
31629
+ originUrl: record5.gitInfo.originUrl ?? null,
31630
+ sha: record5.gitInfo.sha ?? null
31009
31631
  } : null,
31010
- forkedFromId: record4.forkSource?.hostThreadId ?? null,
31011
- parentThreadId: record4.subagent?.parentHostThreadId ?? null,
31012
- ephemeral: record4.ephemeral,
31013
- canAcceptDirectInput: record4.subagent ? false : input.loaded === false ? null : true,
31014
- historyMode: record4.historyMode,
31632
+ forkedFromId: record5.forkSource?.hostThreadId ?? null,
31633
+ parentThreadId: record5.subagent?.parentHostThreadId ?? null,
31634
+ ephemeral: record5.ephemeral,
31635
+ canAcceptDirectInput: record5.subagent ? false : input.loaded === false ? null : true,
31636
+ historyMode: record5.historyMode,
31015
31637
  isPinned: false,
31016
- projectId: record4.projectId ?? null,
31017
- daybreakEnabled: record4.daybreakEnabled ?? null,
31638
+ projectId: record5.projectId ?? null,
31639
+ daybreakEnabled: record5.daybreakEnabled ?? null,
31018
31640
  ...threadSectionFields(input.placement),
31019
- agentNickname: record4.subagent ? record4.title || null : null,
31020
- agentRole: record4.subagent?.role ?? null,
31641
+ agentNickname: record5.subagent ? record5.title || null : null,
31642
+ agentRole: record5.subagent?.role ?? null,
31021
31643
  extra: null
31022
31644
  };
31023
31645
  }
@@ -31256,14 +31878,14 @@ async function settleExternalOutputFailure(thread, error51, project2, diagnose)
31256
31878
  function fixedError(code, message2) {
31257
31879
  return { code, message: message2 };
31258
31880
  }
31259
- function importedThread(record4) {
31881
+ function importedThread(record5) {
31260
31882
  return {
31261
31883
  ok: true,
31262
- threadId: record4.hostThreadId,
31884
+ threadId: record5.hostThreadId,
31263
31885
  thread: externalThreadValue({
31264
- record: record4,
31886
+ record: record5,
31265
31887
  turns: [],
31266
- sessionId: record4.hostThreadId,
31888
+ sessionId: record5.hostThreadId,
31267
31889
  loaded: false
31268
31890
  })
31269
31891
  };
@@ -31284,7 +31906,7 @@ var HarnessSessionImporter = class {
31284
31906
  }
31285
31907
  #mappedRecord(records, nativeSessionId) {
31286
31908
  return records.find(
31287
- (record4) => !record4.subagent && record4.state === "ready" && record4.nativeSessionRef?.harnessId === this.#harnessId && record4.nativeSessionRef.nativeSessionId === nativeSessionId
31909
+ (record5) => !record5.subagent && record5.state === "ready" && record5.nativeSessionRef?.harnessId === this.#harnessId && record5.nativeSessionRef.nativeSessionId === nativeSessionId
31288
31910
  );
31289
31911
  }
31290
31912
  #unavailable() {
@@ -31303,7 +31925,7 @@ var HarnessSessionImporter = class {
31303
31925
  }
31304
31926
  const mapped = new Set(
31305
31927
  (await this.#repository.list()).flatMap(
31306
- (record4) => !record4.subagent && record4.state === "ready" && record4.nativeSessionRef?.harnessId === this.#harnessId ? [record4.nativeSessionRef.nativeSessionId] : []
31928
+ (record5) => !record5.subagent && record5.state === "ready" && record5.nativeSessionRef?.harnessId === this.#harnessId ? [record5.nativeSessionRef.nativeSessionId] : []
31307
31929
  )
31308
31930
  );
31309
31931
  const superseded = this.#repository.supersededNativeSessionIds(this.#harnessId);
@@ -31395,8 +32017,8 @@ var HarnessSessionImporter = class {
31395
32017
  return { ok: false, error: fixedError(-32081, "Session import could not be persisted") };
31396
32018
  }
31397
32019
  try {
31398
- const record4 = await this.#repository.commitNative(provisional.hostThreadId, ref.data, []);
31399
- return importedThread(record4);
32020
+ const record5 = await this.#repository.commitNative(provisional.hostThreadId, ref.data, []);
32021
+ return importedThread(record5);
31400
32022
  } catch (error51) {
31401
32023
  await this.#repository.removeProvisional(provisional.hostThreadId).catch((cleanupError) => this.#diagnose(cleanupError));
31402
32024
  if (error51 instanceof MappingStoreError && error51.code === "DUPLICATE_NATIVE_SESSION") {
@@ -32693,6 +33315,19 @@ var ExternalThreadRuntime = class {
32693
33315
  this.#threads.delete(threadId2);
32694
33316
  this.#steeredTurnIds.delete(threadId2);
32695
33317
  }
33318
+ /** Confirm release before forgetting either the Session owner or its persisted mapping. */
33319
+ async deleteThread(hostThreadId) {
33320
+ await this.#withLifecycle(hostThreadId, async () => {
33321
+ const thread = this.#threads.get(hostThreadId);
33322
+ if (thread) {
33323
+ thread.sessionUnavailable = true;
33324
+ thread.stateObserver.fault(new Error("External Thread is being deleted"));
33325
+ await this.#lifecycle.release(hostThreadId, thread.session, thread.outputTask);
33326
+ }
33327
+ this.remove(hostThreadId);
33328
+ await this.#repository.removeThread(hostThreadId);
33329
+ });
33330
+ }
32696
33331
  clear() {
32697
33332
  this.#threads.clear();
32698
33333
  this.#steeredTurnIds.clear();
@@ -32821,9 +33456,9 @@ var ExternalThreadRuntime = class {
32821
33456
  async #retireSubagents(parent, bestEffort = false) {
32822
33457
  const parentId = parent.id;
32823
33458
  const ancestors = /* @__PURE__ */ new Map();
32824
- const descendant = async (record4) => {
33459
+ const descendant = async (record5) => {
32825
33460
  const visited = /* @__PURE__ */ new Set();
32826
- let ownerId = record4?.subagent?.parentHostThreadId;
33461
+ let ownerId = record5?.subagent?.parentHostThreadId;
32827
33462
  while (ownerId && !visited.has(ownerId)) {
32828
33463
  if (ownerId === parentId) return true;
32829
33464
  visited.add(ownerId);
@@ -32871,23 +33506,23 @@ var ExternalThreadRuntime = class {
32871
33506
  if (failure) return { kind: "error", error: { code: -32075, message: failure } };
32872
33507
  return { kind: "external", record: loaded.record, thread: loaded };
32873
33508
  }
32874
- let record4;
33509
+ let record5;
32875
33510
  try {
32876
- record4 = await this.#repository.find(threadId2);
33511
+ record5 = await this.#repository.find(threadId2);
32877
33512
  } catch {
32878
33513
  return {
32879
33514
  kind: "error",
32880
33515
  error: { code: -32081, message: "External Thread ownership could not be read" }
32881
33516
  };
32882
33517
  }
32883
- if (!record4) return { kind: "official" };
32884
- if (record4.state !== "ready" || !record4.nativeSessionRef) {
33518
+ if (!record5) return { kind: "official" };
33519
+ if (record5.state !== "ready" || !record5.nativeSessionRef) {
32885
33520
  return {
32886
33521
  kind: "error",
32887
33522
  error: { code: -32079, message: "External Native Session is unavailable" }
32888
33523
  };
32889
33524
  }
32890
- return { kind: "external", record: record4, thread: null };
33525
+ return { kind: "external", record: record5, thread: null };
32891
33526
  }
32892
33527
  async resolve(threadId2) {
32893
33528
  try {
@@ -33098,16 +33733,16 @@ var ExternalThreadRuntime = class {
33098
33733
  return failure;
33099
33734
  }
33100
33735
  }
33101
- async #restore(record4) {
33102
- const harnessId = record4.harnessId;
33736
+ async #restore(record5) {
33737
+ const harnessId = record5.harnessId;
33103
33738
  const adapter = this.#adapters.get(harnessId);
33104
- if (!adapter || !record4.nativeSessionRef) {
33739
+ if (!adapter || !record5.nativeSessionRef) {
33105
33740
  throw new ExternalThreadOpenError({
33106
33741
  code: -32077,
33107
33742
  message: "External Harness is unavailable"
33108
33743
  });
33109
33744
  }
33110
- if (record4.subagent) {
33745
+ if (record5.subagent) {
33111
33746
  const subagents = adapter.subagents;
33112
33747
  if (!subagents) {
33113
33748
  throw new ExternalThreadOpenError({
@@ -33115,14 +33750,14 @@ var ExternalThreadRuntime = class {
33115
33750
  message: "External Harness Subagent history is unavailable"
33116
33751
  });
33117
33752
  }
33118
- const subagent = record4.subagent;
33119
- const parent = record4.nativeSessionRef;
33753
+ const subagent = record5.subagent;
33754
+ const parent = record5.nativeSessionRef;
33120
33755
  const snapshot2 = await subagents.readSnapshot({
33121
33756
  parent,
33122
33757
  nativeSubagentId: subagent.nativeSubagentId,
33123
- cwd: record4.cwd
33758
+ cwd: record5.cwd
33124
33759
  });
33125
- const latest = await this.#repository.find(record4.hostThreadId);
33760
+ const latest = await this.#repository.find(record5.hostThreadId);
33126
33761
  if (latest?.state === "ready" && latest.nativeSessionRef && JSON.stringify(latest.nativeSessionRef) !== JSON.stringify(parent)) {
33127
33762
  return this.#restore(latest);
33128
33763
  }
@@ -33130,16 +33765,16 @@ var ExternalThreadRuntime = class {
33130
33765
  throw new ExternalThreadOpenError(mapExternalThreadHarnessError(snapshot2.error, "read"));
33131
33766
  }
33132
33767
  const session2 = new ReadonlySnapshotSession(
33133
- record4.harnessId,
33134
- record4.nativeSessionRef,
33768
+ record5.harnessId,
33769
+ record5.nativeSessionRef,
33135
33770
  snapshot2.value,
33136
33771
  () => subagents.readSnapshot({
33137
33772
  parent,
33138
33773
  nativeSubagentId: subagent.nativeSubagentId,
33139
- cwd: record4.cwd
33774
+ cwd: record5.cwd
33140
33775
  })
33141
33776
  );
33142
- const aligned = await this.#repository.alignSnapshot(record4, snapshot2.value);
33777
+ const aligned = await this.#repository.alignSnapshot(record5, snapshot2.value);
33143
33778
  const sessionId = await this.#repository.sessionTreeId(aligned.record);
33144
33779
  return this.register({
33145
33780
  record: aligned.record,
@@ -33150,13 +33785,13 @@ var ExternalThreadRuntime = class {
33150
33785
  ...snapshot2.value.state ? { restoredState: snapshot2.value.state } : {}
33151
33786
  });
33152
33787
  }
33153
- const restoredSelection = decodeExternalTransportSelection(harnessId, record4.transportModelId);
33788
+ const restoredSelection = decodeExternalTransportSelection(harnessId, record5.transportModelId);
33154
33789
  const opened = await adapter.open({
33155
33790
  kind: "resume",
33156
- cwd: record4.cwd,
33157
- environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: record4.hostThreadId },
33158
- nativeRef: record4.nativeSessionRef,
33159
- knownTurnRefs: record4.turnMappings.map(({ nativeTurnRef }) => nativeTurnRef),
33791
+ cwd: record5.cwd,
33792
+ environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: record5.hostThreadId },
33793
+ nativeRef: record5.nativeSessionRef,
33794
+ knownTurnRefs: record5.turnMappings.map(({ nativeTurnRef }) => nativeTurnRef),
33160
33795
  ...restoredSelection?.model ? { model: restoredSelection.model } : {},
33161
33796
  ...restoredSelection?.thinkingOptionId ? { thinkingOptionId: restoredSelection.thinkingOptionId } : {},
33162
33797
  ...restoredSelection?.permissionModeId ? { permissionModeId: restoredSelection.permissionModeId } : {}
@@ -33170,7 +33805,7 @@ var ExternalThreadRuntime = class {
33170
33805
  if (!snapshot2.ok) {
33171
33806
  throw new ExternalThreadOpenError(mapExternalThreadHarnessError(snapshot2.error, "read"));
33172
33807
  }
33173
- let aligned = await this.#repository.alignSnapshot(record4, snapshot2.value);
33808
+ let aligned = await this.#repository.alignSnapshot(record5, snapshot2.value);
33174
33809
  const restoredState = snapshot2.value.state;
33175
33810
  const effectiveModel = restoredState ? restoredState.effectiveModel : restoredSelection?.model;
33176
33811
  const effectiveThinkingOptionId = restoredState ? restoredState.effectiveThinkingOptionId : restoredSelection?.thinkingOptionId;
@@ -33216,14 +33851,136 @@ var ExternalThreadRuntime = class {
33216
33851
  });
33217
33852
  } catch (error51) {
33218
33853
  if (error51 instanceof ExternalSessionReleaseError) throw error51;
33219
- await this.#lifecycle.release(record4.hostThreadId, session, Promise.resolve());
33854
+ await this.#lifecycle.release(record5.hostThreadId, session, Promise.resolve());
33220
33855
  throw error51;
33221
33856
  }
33222
33857
  }
33223
33858
  };
33224
33859
 
33225
- // packages/host-runtime/src/external-turn-steering.ts
33860
+ // packages/host-runtime/src/external-thread-queue.ts
33226
33861
  import { randomUUID as randomUUID12 } from "node:crypto";
33862
+ var ExternalQueueError = class extends Error {
33863
+ constructor(code, message2) {
33864
+ super(message2);
33865
+ this.code = code;
33866
+ }
33867
+ code;
33868
+ };
33869
+ var publicSubmission = ({
33870
+ id: id2,
33871
+ input,
33872
+ clientUserMessageId
33873
+ }) => ({
33874
+ id: id2,
33875
+ input,
33876
+ clientUserMessageId
33877
+ });
33878
+ var DEFAULT_PAGE_SIZE3 = 50;
33879
+ var ExternalThreadQueue = class {
33880
+ #queues = /* @__PURE__ */ new Map();
33881
+ #notifyChanged;
33882
+ #createId;
33883
+ constructor(options2) {
33884
+ this.#notifyChanged = options2.notifyChanged;
33885
+ this.#createId = options2.createId ?? randomUUID12;
33886
+ }
33887
+ has(threadId2) {
33888
+ return (this.#queues.get(threadId2)?.length ?? 0) > 0;
33889
+ }
33890
+ list(threadId2, params) {
33891
+ const items = this.#queues.get(threadId2) ?? [];
33892
+ const start = params.cursor == null ? 0 : Number(params.cursor);
33893
+ if (!Number.isSafeInteger(start) || start < 0 || start > items.length) {
33894
+ throw new ExternalQueueError(-32602, "Invalid thread/queue/list cursor");
33895
+ }
33896
+ const limit = typeof params.limit === "number" && Number.isSafeInteger(params.limit) && params.limit > 0 ? params.limit : DEFAULT_PAGE_SIZE3;
33897
+ const end = Math.min(items.length, start + limit);
33898
+ return {
33899
+ data: items.slice(start, end).map((item) => publicSubmission(item)),
33900
+ nextCursor: end < items.length ? String(end) : null
33901
+ };
33902
+ }
33903
+ async add(threadId2, input, clientUserMessageId, sourceHostId) {
33904
+ const submission = { id: this.#createId(), input, clientUserMessageId, sourceHostId };
33905
+ this.#items(threadId2).push(submission);
33906
+ await this.#notifyChanged(threadId2);
33907
+ return publicSubmission(submission);
33908
+ }
33909
+ async update(threadId2, id2, input) {
33910
+ const items = this.#queues.get(threadId2) ?? [];
33911
+ const index = items.findIndex((item) => item.id === id2);
33912
+ const current = items[index];
33913
+ if (!current) throw new ExternalQueueError(-32602, "Queued submission was not found");
33914
+ const submission = { ...current, input };
33915
+ items[index] = submission;
33916
+ await this.#notifyChanged(threadId2);
33917
+ return publicSubmission(submission);
33918
+ }
33919
+ async delete(threadId2, id2) {
33920
+ const items = this.#queues.get(threadId2);
33921
+ const index = items?.findIndex((item) => item.id === id2) ?? -1;
33922
+ if (!items || index === -1) return false;
33923
+ items.splice(index, 1);
33924
+ this.#prune(threadId2);
33925
+ await this.#notifyChanged(threadId2);
33926
+ return true;
33927
+ }
33928
+ /** Listed IDs move to the front in the given order; unlisted entries keep their order. */
33929
+ async reorder(threadId2, ids) {
33930
+ const items = this.#queues.get(threadId2);
33931
+ if (!items) return;
33932
+ const byId = new Map(items.map((item) => [item.id, item]));
33933
+ const ordered = ids.flatMap((id2) => {
33934
+ const item = byId.get(id2);
33935
+ byId.delete(id2);
33936
+ return item ? [item] : [];
33937
+ });
33938
+ items.splice(0, items.length, ...ordered, ...byId.values());
33939
+ await this.#notifyChanged(threadId2);
33940
+ }
33941
+ /** Removes the submission a Turn is about to start; `restore` returns it if the start fails. */
33942
+ take(threadId2, id2) {
33943
+ const items = this.#queues.get(threadId2) ?? [];
33944
+ const index = id2 == null ? 0 : items.findIndex((item) => item.id === id2);
33945
+ const submission = index === -1 ? void 0 : items[index];
33946
+ if (!submission) throw new ExternalQueueError(-32602, "Queued submission was not found");
33947
+ items.splice(index, 1);
33948
+ this.#prune(threadId2);
33949
+ return {
33950
+ submission: publicSubmission(submission),
33951
+ sourceHostId: submission.sourceHostId,
33952
+ index
33953
+ };
33954
+ }
33955
+ restore(threadId2, taken) {
33956
+ const items = this.#items(threadId2);
33957
+ if (items.some((item) => item.id === taken.submission.id)) return;
33958
+ items.splice(Math.min(taken.index, items.length), 0, {
33959
+ ...taken.submission,
33960
+ sourceHostId: taken.sourceHostId
33961
+ });
33962
+ }
33963
+ notifyChanged(threadId2) {
33964
+ return this.#notifyChanged(threadId2);
33965
+ }
33966
+ forget(threadId2) {
33967
+ this.#queues.delete(threadId2);
33968
+ }
33969
+ #items(threadId2) {
33970
+ let items = this.#queues.get(threadId2);
33971
+ if (!items) {
33972
+ items = [];
33973
+ this.#queues.set(threadId2, items);
33974
+ }
33975
+ return items;
33976
+ }
33977
+ #prune(threadId2) {
33978
+ if (this.#queues.get(threadId2)?.length === 0) this.#queues.delete(threadId2);
33979
+ }
33980
+ };
33981
+
33982
+ // packages/host-runtime/src/external-turn-steering.ts
33983
+ import { randomUUID as randomUUID13 } from "node:crypto";
33227
33984
 
33228
33985
  // packages/host-runtime/src/external-command-routing.ts
33229
33986
  var ExternalCommandError = class extends Error {
@@ -33344,7 +34101,7 @@ async function insertNativeSteer(thread, input, host) {
33344
34101
  thread.steeredTurnIds.add(input.turnId);
33345
34102
  const item = {
33346
34103
  type: "userMessage",
33347
- itemId: hostItemIdSchema.parse(randomUUID12()),
34104
+ itemId: hostItemIdSchema.parse(randomUUID13()),
33348
34105
  input: displayed
33349
34106
  };
33350
34107
  try {
@@ -33576,7 +34333,7 @@ function sameWorkspace(left, right) {
33576
34333
  }
33577
34334
 
33578
34335
  // packages/host-runtime/src/harness-delegation-coordinator.ts
33579
- import { createHash as createHash8, randomUUID as randomUUID13 } from "node:crypto";
34336
+ import { createHash as createHash8, randomUUID as randomUUID14 } from "node:crypto";
33580
34337
  import path24 from "node:path";
33581
34338
 
33582
34339
  // packages/host-runtime/src/delegation-snapshot.ts
@@ -33880,11 +34637,11 @@ var HarnessDelegationCoordinator = class {
33880
34637
  });
33881
34638
  this.#validateConfiguration(inspected.inspection, input.model, input.thinkingOptionId);
33882
34639
  }
33883
- const delegationId = hostThreadIdSchema.parse(randomUUID13());
33884
- const childThreadId = hostThreadIdSchema.parse(randomUUID13());
33885
- const turnId = hostTurnIdSchema.parse(randomUUID13());
33886
- const createRequestId = input.requestId ? `delegation:${input.requestId}` : randomUUID13();
33887
- let record4 = await this.#repository.createProvisional(
34640
+ const delegationId = hostThreadIdSchema.parse(randomUUID14());
34641
+ const childThreadId = hostThreadIdSchema.parse(randomUUID14());
34642
+ const turnId = hostTurnIdSchema.parse(randomUUID14());
34643
+ const createRequestId = input.requestId ? `delegation:${input.requestId}` : randomUUID14();
34644
+ let record5 = await this.#repository.createProvisional(
33888
34645
  createExternalThreadRecordInput({
33889
34646
  hostThreadId: childThreadId,
33890
34647
  createRequestId,
@@ -33915,7 +34672,7 @@ var HarnessDelegationCoordinator = class {
33915
34672
  });
33916
34673
  const opened = await adapter.open({
33917
34674
  kind: "create",
33918
- cwd: record4.cwd,
34675
+ cwd: record5.cwd,
33919
34676
  environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: childThreadId },
33920
34677
  executionPolicy: "unattended-full-access",
33921
34678
  ...input.model ? { model: input.model } : {},
@@ -33924,21 +34681,21 @@ var HarnessDelegationCoordinator = class {
33924
34681
  if (!opened.ok) throw new DelegationControlError("DELEGATION_FAILED", opened.error.message);
33925
34682
  session = opened.value;
33926
34683
  if (session.initialState.nativeRef) {
33927
- record4 = await this.#repository.commitNative(
33928
- record4.hostThreadId,
34684
+ record5 = await this.#repository.commitNative(
34685
+ record5.hostThreadId,
33929
34686
  session.initialState.nativeRef
33930
34687
  );
33931
34688
  }
33932
34689
  const threadValue = externalThreadValue({
33933
- record: record4,
34690
+ record: record5,
33934
34691
  turns: [],
33935
- sessionId: record4.hostThreadId,
34692
+ sessionId: record5.hostThreadId,
33936
34693
  running: true
33937
34694
  });
33938
34695
  const thread = this.#registerExternalThread({
33939
- record: record4,
34696
+ record: record5,
33940
34697
  session,
33941
- sessionId: record4.hostThreadId,
34698
+ sessionId: record5.hostThreadId,
33942
34699
  thread: threadValue,
33943
34700
  turns: [],
33944
34701
  ...input.model ? { requestedModel: input.model } : {},
@@ -33995,7 +34752,7 @@ var HarnessDelegationCoordinator = class {
33995
34752
  } : {}
33996
34753
  }
33997
34754
  }),
33998
- cwd: record4.cwd,
34755
+ cwd: record5.cwd,
33999
34756
  parentThreadId
34000
34757
  };
34001
34758
  } catch (error51) {
@@ -34037,7 +34794,7 @@ var HarnessDelegationCoordinator = class {
34037
34794
  if (this.#externalThreadBusy(thread) || thread.activeTurnId) {
34038
34795
  throw new DelegationControlError("THREAD_BUSY", "Thread already has an active Turn");
34039
34796
  }
34040
- const turnId = hostTurnIdSchema.parse(randomUUID13());
34797
+ const turnId = hostTurnIdSchema.parse(randomUUID14());
34041
34798
  try {
34042
34799
  await this.#startExternalTurn(thread, input.message, turnId);
34043
34800
  } catch (error51) {
@@ -34144,19 +34901,19 @@ var HarnessDelegationCoordinator = class {
34144
34901
  const parent = hostThreadIdSchema.parse(input.parentThreadId);
34145
34902
  const delegations = await this.#repository.listDelegations(parent);
34146
34903
  const records = await this.#repository.list();
34147
- const byId = new Map(records.map((record4) => [record4.hostThreadId, record4]));
34904
+ const byId = new Map(records.map((record5) => [record5.hostThreadId, record5]));
34148
34905
  const rows = delegations.map((delegation) => {
34149
- const record4 = byId.get(delegation.childHostThreadId);
34906
+ const record5 = byId.get(delegation.childHostThreadId);
34150
34907
  return {
34151
34908
  threadId: delegation.childHostThreadId,
34152
34909
  harnessId: delegation.targetHarnessId,
34153
34910
  deepLink: `codex://threads/${delegation.childHostThreadId}`,
34154
34911
  status: delegation.status,
34155
- ...record4 ? {
34156
- cwd: record4.cwd,
34157
- title: record4.title,
34158
- createdAt: record4.createdAt,
34159
- updatedAt: record4.updatedAt
34912
+ ...record5 ? {
34913
+ cwd: record5.cwd,
34914
+ title: record5.title,
34915
+ createdAt: record5.createdAt,
34916
+ updatedAt: record5.updatedAt
34160
34917
  } : {
34161
34918
  createdAt: delegation.createdAt,
34162
34919
  updatedAt: delegation.updatedAt
@@ -34250,19 +35007,19 @@ var HarnessDelegationCoordinator = class {
34250
35007
  }
34251
35008
  }
34252
35009
  async #parentMetadata(parentThreadId) {
34253
- const record4 = await this.#repository.find(parentThreadId);
34254
- if (record4)
35010
+ const record5 = await this.#repository.find(parentThreadId);
35011
+ if (record5)
34255
35012
  return {
34256
- harnessId: record4.harnessId,
34257
- cwd: record4.cwd,
34258
- title: record4.title
35013
+ harnessId: record5.harnessId,
35014
+ cwd: record5.cwd,
35015
+ title: record5.title
34259
35016
  };
34260
35017
  const metadata = await this.#officialThreadMetadata(parentThreadId).catch(() => ({}));
34261
35018
  return { harnessId: "codex", ...metadata };
34262
35019
  }
34263
35020
  async #existingResult(delegation) {
34264
- const record4 = await this.#repository.find(delegation.childHostThreadId);
34265
- const turnId = record4?.turnMappings.at(-1)?.hostTurnId ?? "pending";
35021
+ const record5 = await this.#repository.find(delegation.childHostThreadId);
35022
+ const turnId = record5?.turnMappings.at(-1)?.hostTurnId ?? "pending";
34266
35023
  return {
34267
35024
  ...this.#result(
34268
35025
  delegation.delegationId,
@@ -34271,7 +35028,7 @@ var HarnessDelegationCoordinator = class {
34271
35028
  delegation.targetHarnessId,
34272
35029
  delegation.status
34273
35030
  ),
34274
- ...record4 ? { cwd: record4.cwd } : {},
35031
+ ...record5 ? { cwd: record5.cwd } : {},
34275
35032
  parentThreadId: delegation.parentHostThreadId
34276
35033
  };
34277
35034
  }
@@ -36687,10 +37444,10 @@ var SingleNativeCodexAccount = class {
36687
37444
  };
36688
37445
 
36689
37446
  // packages/host-runtime/src/codex-runtime/official-runtime-owner.ts
36690
- import { randomUUID as randomUUID15 } from "node:crypto";
37447
+ import { randomUUID as randomUUID16 } from "node:crypto";
36691
37448
 
36692
37449
  // packages/host-runtime/src/official-request-broker.ts
36693
- import { randomUUID as randomUUID14 } from "node:crypto";
37450
+ import { randomUUID as randomUUID15 } from "node:crypto";
36694
37451
  var INTERNAL_REQUEST_PREFIX = "codexhost:official:";
36695
37452
  var MAX_RETIRED_IDS = 1024;
36696
37453
  function isRecord15(value2) {
@@ -36706,7 +37463,7 @@ var OfficialRequestBroker = class {
36706
37463
  constructor(input) {
36707
37464
  this.#send = input.send;
36708
37465
  this.#timeoutMs = input.timeoutMs ?? 3e4;
36709
- this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${randomUUID14()}`);
37466
+ this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${randomUUID15()}`);
36710
37467
  }
36711
37468
  get pendingCount() {
36712
37469
  return this.#pending.size;
@@ -37060,7 +37817,7 @@ var OfficialRuntimeOwner = class {
37060
37817
  }
37061
37818
  #attach(role, output, onBackendStopped) {
37062
37819
  const client = {
37063
- id: randomUUID15(),
37820
+ id: randomUUID16(),
37064
37821
  role,
37065
37822
  output,
37066
37823
  ...onBackendStopped ? { onBackendStopped } : {},
@@ -37218,7 +37975,7 @@ var OfficialRuntimeOwner = class {
37218
37975
  if (!object4(value2)) return client.output(event);
37219
37976
  if (typeof value2.id === "string" || typeof value2.id === "number") {
37220
37977
  if (typeof value2.method === "string") {
37221
- const id2 = `codexhost:server:${client.id}:${event.generation}:${randomUUID15()}`;
37978
+ const id2 = `codexhost:server:${client.id}:${event.generation}:${randomUUID16()}`;
37222
37979
  client.serverRequests.set(id2, value2.id);
37223
37980
  const projected = { ...value2, id: id2 };
37224
37981
  return client.output({
@@ -37606,9 +38363,9 @@ function externalAnchor(entry) {
37606
38363
  if (entry.source !== "external") throw new Error("Expected an External Thread list entry");
37607
38364
  return { timestamp: entry.timestamp, threadId: threadId(entry.thread) };
37608
38365
  }
37609
- function includesExternalRecord(record4, query, byId, sectionId) {
37610
- if (record4.state !== "ready" || !record4.nativeSessionRef) return false;
37611
- let current = record4;
38366
+ function includesExternalRecord(record5, query, byId, sectionId) {
38367
+ if (record5.state !== "ready" || !record5.nativeSessionRef) return false;
38368
+ let current = record5;
37612
38369
  const owners = /* @__PURE__ */ new Set();
37613
38370
  while (current.subagent) {
37614
38371
  if (owners.has(current.hostThreadId)) return false;
@@ -37618,32 +38375,32 @@ function includesExternalRecord(record4, query, byId, sectionId) {
37618
38375
  return false;
37619
38376
  current = parent;
37620
38377
  }
37621
- const sourceKind = record4.subagent ? "subAgentThreadSpawn" : "vscode";
38378
+ const sourceKind = record5.subagent ? "subAgentThreadSpawn" : "vscode";
37622
38379
  const scoped = query.parentThreadId !== null || query.ancestorThreadId !== null;
37623
- if (record4.subagent && !scoped && !query.sourceKinds?.some((kind) => kind === "subAgent" || kind === "subAgentThreadSpawn"))
38380
+ if (record5.subagent && !scoped && !query.sourceKinds?.some((kind) => kind === "subAgent" || kind === "subAgentThreadSpawn"))
37624
38381
  return false;
37625
- if (query.parentThreadId !== null && record4.subagent?.parentHostThreadId !== query.parentThreadId)
38382
+ if (query.parentThreadId !== null && record5.subagent?.parentHostThreadId !== query.parentThreadId)
37626
38383
  return false;
37627
38384
  if (query.ancestorThreadId !== null) {
37628
- let parentId = record4.subagent?.parentHostThreadId;
37629
- const visited = /* @__PURE__ */ new Set([record4.hostThreadId]);
38385
+ let parentId = record5.subagent?.parentHostThreadId;
38386
+ const visited = /* @__PURE__ */ new Set([record5.hostThreadId]);
37630
38387
  while (parentId && parentId !== query.ancestorThreadId && !visited.has(parentId)) {
37631
38388
  visited.add(parentId);
37632
38389
  parentId = byId.get(parentId)?.subagent?.parentHostThreadId;
37633
38390
  }
37634
- if (record4.hostThreadId === query.ancestorThreadId || parentId !== query.ancestorThreadId)
38391
+ if (record5.hostThreadId === query.ancestorThreadId || parentId !== query.ancestorThreadId)
37635
38392
  return false;
37636
38393
  }
37637
- if (record4.archived !== query.archived) return false;
37638
- if (query.projectId !== void 0 && (record4.projectId ?? null) !== query.projectId) return false;
37639
- if (query.cwd !== null && !query.cwd.includes(record4.cwd)) return false;
38394
+ if (record5.archived !== query.archived) return false;
38395
+ if (query.projectId !== void 0 && (record5.projectId ?? null) !== query.projectId) return false;
38396
+ if (query.cwd !== null && !query.cwd.includes(record5.cwd)) return false;
37640
38397
  if (query.modelProviders !== null && query.modelProviders.length > 0 && !query.modelProviders.includes("codexhost")) {
37641
38398
  return false;
37642
38399
  }
37643
- if (query.sourceKinds !== null && query.sourceKinds.length > 0 && !query.sourceKinds.includes(sourceKind) && !(record4.subagent && query.sourceKinds.includes("subAgent"))) {
38400
+ if (query.sourceKinds !== null && query.sourceKinds.length > 0 && !query.sourceKinds.includes(sourceKind) && !(record5.subagent && query.sourceKinds.includes("subAgent"))) {
37644
38401
  return false;
37645
38402
  }
37646
- if (query.searchTerm !== null && !record4.title.toLowerCase().includes(query.searchTerm.toLowerCase())) {
38403
+ if (query.searchTerm !== null && !record5.title.toLowerCase().includes(query.searchTerm.toLowerCase())) {
37647
38404
  return false;
37648
38405
  }
37649
38406
  if (query.isPinned === true) return false;
@@ -37651,7 +38408,7 @@ function includesExternalRecord(record4, query, byId, sectionId) {
37651
38408
  return true;
37652
38409
  }
37653
38410
  function resolveExternalSessionTreeIds(records) {
37654
- const byId = new Map(records.map((record4) => [record4.hostThreadId, record4]));
38411
+ const byId = new Map(records.map((record5) => [record5.hostThreadId, record5]));
37655
38412
  const resolved = /* @__PURE__ */ new Map();
37656
38413
  const resolve = (start) => {
37657
38414
  const cached2 = resolved.get(start.hostThreadId);
@@ -37662,7 +38419,7 @@ function resolveExternalSessionTreeIds(records) {
37662
38419
  while (true) {
37663
38420
  const known = resolved.get(current.hostThreadId);
37664
38421
  if (known) {
37665
- for (const record4 of path43) resolved.set(record4.hostThreadId, known);
38422
+ for (const record5 of path43) resolved.set(record5.hostThreadId, known);
37666
38423
  return known;
37667
38424
  }
37668
38425
  if (visited.has(current.hostThreadId)) {
@@ -37674,32 +38431,32 @@ function resolveExternalSessionTreeIds(records) {
37674
38431
  const source = sourceId ? byId.get(sourceId) : void 0;
37675
38432
  if (!source) {
37676
38433
  const root = current.hostThreadId;
37677
- for (const record4 of path43) resolved.set(record4.hostThreadId, root);
38434
+ for (const record5 of path43) resolved.set(record5.hostThreadId, root);
37678
38435
  return root;
37679
38436
  }
37680
38437
  current = source;
37681
38438
  }
37682
38439
  };
37683
- for (const record4 of records) resolve(record4);
38440
+ for (const record5 of records) resolve(record5);
37684
38441
  return resolved;
37685
38442
  }
37686
38443
  function externalThreadListEntries(input) {
37687
38444
  const sessionIds = resolveExternalSessionTreeIds(input.records);
37688
- const byId = new Map(input.records.map((record4) => [record4.hostThreadId, record4]));
38445
+ const byId = new Map(input.records.map((record5) => [record5.hostThreadId, record5]));
37689
38446
  return input.records.filter(
37690
- (record4) => includesExternalRecord(
37691
- record4,
38447
+ (record5) => includesExternalRecord(
38448
+ record5,
37692
38449
  input.query,
37693
38450
  byId,
37694
- input.placementOf?.(record4.hostThreadId)?.section.id ?? null
38451
+ input.placementOf?.(record5.hostThreadId)?.section.id ?? null
37695
38452
  )
37696
- ).map((record4) => {
37697
- const runtime = input.runtimeFor(record4.hostThreadId);
37698
- const sessionId = sessionIds.get(record4.hostThreadId);
38453
+ ).map((record5) => {
38454
+ const runtime = input.runtimeFor(record5.hostThreadId);
38455
+ const sessionId = sessionIds.get(record5.hostThreadId);
37699
38456
  if (!sessionId) throw new Error("External Thread Session tree could not be resolved");
37700
- const placement = input.placementOf?.(record4.hostThreadId);
38457
+ const placement = input.placementOf?.(record5.hostThreadId);
37701
38458
  const thread = externalThreadValue({
37702
- record: record4,
38459
+ record: record5,
37703
38460
  turns: [],
37704
38461
  sessionId,
37705
38462
  ...runtime ? { running: runtime.running } : { loaded: false },
@@ -37708,7 +38465,7 @@ function externalThreadListEntries(input) {
37708
38465
  return {
37709
38466
  source: "external",
37710
38467
  thread,
37711
- timestamp: input.query.sortKey === "created_at" ? unixTimestamp(record4.createdAt, "createdAt") : unixTimestamp(record4.updatedAt, "updatedAt")
38468
+ timestamp: input.query.sortKey === "created_at" ? unixTimestamp(record5.createdAt, "createdAt") : unixTimestamp(record5.updatedAt, "updatedAt")
37712
38469
  };
37713
38470
  });
37714
38471
  }
@@ -37811,7 +38568,7 @@ async function aggregateThreadList(input) {
37811
38568
  let officialIndex = 0;
37812
38569
  let firstOfficialBackwardsCursor;
37813
38570
  let officialRequestCount = 0;
37814
- const externalIds = new Set(input.records.map((record4) => record4.hostThreadId));
38571
+ const externalIds = new Set(input.records.map((record5) => record5.hostThreadId));
37815
38572
  for (const thread of input.sharedThreads ?? []) externalIds.add(String(thread.id));
37816
38573
  const requestOfficial = async (cursor, limit) => {
37817
38574
  officialRequestCount += 1;
@@ -38153,7 +38910,6 @@ async function moveThreadSection(input) {
38153
38910
  // packages/host-runtime/src/external-thread-official-defaults.ts
38154
38911
  var EMPTY_RESULTS = /* @__PURE__ */ new Map([
38155
38912
  ["thread/attachment/list", () => ({ data: [], nextCursor: null })],
38156
- ["thread/queue/list", () => ({ data: [], nextCursor: null })],
38157
38913
  ["thread/settings/update", () => ({})]
38158
38914
  ]);
38159
38915
  function externalThreadEmptyOfficialResult(method) {
@@ -38503,6 +39259,9 @@ var AppServerHost = class {
38503
39259
  #executionHosts = /* @__PURE__ */ new WeakMap();
38504
39260
  #externalPrewarms = new ExternalThreadPrewarms();
38505
39261
  #externalSteering = new ExternalTurnSteering();
39262
+ #externalQueue = new ExternalThreadQueue({
39263
+ notifyChanged: (threadId2) => this.#writer.json({ method: "thread/queue/changed", params: { threadId: threadId2 } })
39264
+ });
38506
39265
  #liveCommandCache = new LiveCommandCatalogCache();
38507
39266
  #modelPrices;
38508
39267
  #observedSessionUsage;
@@ -38529,7 +39288,7 @@ var AppServerHost = class {
38529
39288
  #sectionMoves = Promise.resolve();
38530
39289
  #writer;
38531
39290
  /** Console requests share Desktop handling; their replies return to the console. */
38532
- #consoleRequestPrefix = `codexhost-console:${randomUUID16()}:`;
39291
+ #consoleRequestPrefix = `codexhost-console:${randomUUID17()}:`;
38533
39292
  #consoleReplies = /* @__PURE__ */ new Map();
38534
39293
  #nextConsoleRequest = 0;
38535
39294
  #subagentThreadStatuses = /* @__PURE__ */ new Map();
@@ -38638,16 +39397,7 @@ var AppServerHost = class {
38638
39397
  hasRunningDescendants: (threadId2) => this.#hasRunningSubagents(threadId2),
38639
39398
  idleRelease: {
38640
39399
  queue: this.#desktopRequests,
38641
- onClosed: async (thread) => {
38642
- for (const pending of [...this.#pendingDesktopApprovals.values()]) {
38643
- if (pending.thread === thread)
38644
- await this.#resolveDesktopApproval(pending.interaction.interactionId);
38645
- }
38646
- for (const pending of [...this.#pendingDesktopQuestions.values()]) {
38647
- if (pending.thread === thread)
38648
- await this.#resolveDesktopQuestion(pending.interaction.interactionId);
38649
- }
38650
- },
39400
+ onClosed: (thread) => this.#resolveThreadInteractions(thread),
38651
39401
  canRelease: (thread) => !this.#hasRunningSubagents(thread.id) && !thread.session.hasBackgroundWork?.() && !this.#externalSteering.hasPending(thread.id) && !this.#pendingExternalCommandRequests.has(thread.id) && ![...this.#pendingDesktopApprovals.values()].some(
38652
39402
  (pending) => pending.thread === thread
38653
39403
  ) && ![...this.#pendingDesktopQuestions.values()].some((pending) => pending.thread === thread)
@@ -38837,12 +39587,12 @@ var AppServerHost = class {
38837
39587
  await this.#closeAdapters();
38838
39588
  await this.#externalRuntime.drain();
38839
39589
  for (const pending of [...this.#pendingDesktopApprovals.values()]) {
38840
- await this.#resolveDesktopApproval(pending.interaction.interactionId).catch(
39590
+ await this.#resolveDesktopApproval(pending.interaction.interactionId, pending.thread).catch(
38841
39591
  () => void 0
38842
39592
  );
38843
39593
  }
38844
39594
  for (const pending of [...this.#pendingDesktopQuestions.values()]) {
38845
- await this.#resolveDesktopQuestion(pending.interaction.interactionId).catch(
39595
+ await this.#resolveDesktopQuestion(pending.interaction.interactionId, pending.thread).catch(
38846
39596
  () => void 0
38847
39597
  );
38848
39598
  }
@@ -39766,6 +40516,18 @@ var AppServerHost = class {
39766
40516
  return;
39767
40517
  }
39768
40518
  }
40519
+ if (request.method.startsWith("thread/queue/") && isRecord18(request.params) && typeof request.params.threadId === "string") {
40520
+ const location = await this.#locateExternalThread(request.params.threadId);
40521
+ if (await this.#writeResolutionError(request, location)) return;
40522
+ if (location.kind === "external") {
40523
+ this.#dispatchDesktopReply(
40524
+ request,
40525
+ () => this.#handleExternalQueueRequest(request, location.record.hostThreadId),
40526
+ location.record.hostThreadId
40527
+ );
40528
+ return;
40529
+ }
40530
+ }
39769
40531
  if (request.method === "thread/backgroundTerminals/clean" && isRecord18(request.params) && typeof request.params.threadId === "string") {
39770
40532
  const location = await this.#locateExternalThread(request.params.threadId);
39771
40533
  if (await this.#writeResolutionError(request, location)) return;
@@ -40176,7 +40938,7 @@ var AppServerHost = class {
40176
40938
  throw error51;
40177
40939
  }
40178
40940
  this.#activeOfficialTurns.set(threadId2, turnId);
40179
- const delegationId = hostThreadIdSchema.parse(randomUUID16());
40941
+ const delegationId = hostThreadIdSchema.parse(randomUUID17());
40180
40942
  try {
40181
40943
  const source = await this.#repository.find(input.parentThreadId);
40182
40944
  const pendingTerminal = this.#pendingOfficialTerminalStatuses.get(threadId2);
@@ -40364,7 +41126,7 @@ var AppServerHost = class {
40364
41126
  async #listDelegationThreads(input) {
40365
41127
  const [sortKey, sortDirection2] = input.sort.split("-");
40366
41128
  const request = {
40367
- id: `codexhost:delegation-list:${randomUUID16()}`,
41129
+ id: `codexhost:delegation-list:${randomUUID17()}`,
40368
41130
  method: "thread/list",
40369
41131
  params: {
40370
41132
  cwd: input.cwd ? [input.cwd] : null,
@@ -40389,12 +41151,12 @@ var AppServerHost = class {
40389
41151
  return {
40390
41152
  threads: result.data.flatMap((entry) => {
40391
41153
  if (typeof entry.id !== "string") return [];
40392
- const record4 = records.find((candidate) => candidate.hostThreadId === entry.id);
41154
+ const record5 = records.find((candidate) => candidate.hostThreadId === entry.id);
40393
41155
  const status2 = isRecord18(entry.status) && entry.status.type === "active" ? "running" : "completed";
40394
41156
  return [
40395
41157
  {
40396
41158
  threadId: entry.id,
40397
- harnessId: record4 ? record4.harnessId : "codex",
41159
+ harnessId: record5 ? record5.harnessId : "codex",
40398
41160
  deepLink: `codex://threads/${entry.id}`,
40399
41161
  status: status2,
40400
41162
  ...typeof entry.cwd === "string" ? { cwd: entry.cwd } : {},
@@ -40501,7 +41263,7 @@ var AppServerHost = class {
40501
41263
  const outcome = await moveThreadSection({
40502
41264
  move,
40503
41265
  movingExternal: location.kind === "external",
40504
- externalThreadIds: new Set(records.map((record4) => record4.hostThreadId)),
41266
+ externalThreadIds: new Set(records.map((record5) => record5.hostThreadId)),
40505
41267
  placements,
40506
41268
  requestOfficial: (method, params) => this.#requestOfficial(method, params),
40507
41269
  savePlacements: (next) => this.#repository.replaceSectionPlacements(next),
@@ -40591,10 +41353,10 @@ var AppServerHost = class {
40591
41353
  /** Clear External assignments to a project official Codex reported as deleted. */
40592
41354
  async #clearDeletedProjectAssignments(projectId) {
40593
41355
  const records = await this.#repository.list();
40594
- for (const record4 of records) {
40595
- if (record4.projectId !== projectId) continue;
41356
+ for (const record5 of records) {
41357
+ if (record5.projectId !== projectId) continue;
40596
41358
  const updated = await this.#repository.updateMetadata(
40597
- record4.hostThreadId,
41359
+ record5.hostThreadId,
40598
41360
  { projectId: null },
40599
41361
  { ifProjectId: projectId }
40600
41362
  );
@@ -40607,14 +41369,14 @@ var AppServerHost = class {
40607
41369
  });
40608
41370
  }
40609
41371
  }
40610
- #syncLoadedExternalThread(thread, record4) {
41372
+ #syncLoadedExternalThread(thread, record5) {
40611
41373
  const projected = externalThreadValue({
40612
- record: record4,
41374
+ record: record5,
40613
41375
  turns: [],
40614
41376
  sessionId: thread.sessionId,
40615
41377
  running: thread.running
40616
41378
  });
40617
- thread.record = record4;
41379
+ thread.record = record5;
40618
41380
  thread.thread = { ...thread.thread, ...projected, turns: thread.thread.turns ?? [] };
40619
41381
  return projected;
40620
41382
  }
@@ -40631,15 +41393,15 @@ var AppServerHost = class {
40631
41393
  );
40632
41394
  return null;
40633
41395
  }
40634
- let record4;
41396
+ let record5;
40635
41397
  try {
40636
- record4 = await write(location.record.hostThreadId);
41398
+ record5 = await write(location.record.hostThreadId);
40637
41399
  } catch {
40638
41400
  await this.#writer.json(rpcError(request, -32081, failureMessage));
40639
41401
  return null;
40640
41402
  }
40641
- const projected = location.thread ? this.#syncLoadedExternalThread(location.thread, record4) : externalThreadValue({ record: record4, turns: [], sessionId, loaded: false });
40642
- return { record: record4, thread: await this.#withExternalSection(projected) };
41403
+ const projected = location.thread ? this.#syncLoadedExternalThread(location.thread, record5) : externalThreadValue({ record: record5, turns: [], sessionId, loaded: false });
41404
+ return { record: record5, thread: await this.#withExternalSection(projected) };
40643
41405
  }
40644
41406
  async #handleConsoleOpen(request) {
40645
41407
  if (!consoleOpenParamsSchema.safeParse(request.params ?? {}).success) {
@@ -40895,8 +41657,8 @@ var AppServerHost = class {
40895
41657
  const sharedHarness = shared?.get(threadId2);
40896
41658
  if (sharedHarness)
40897
41659
  return { threadId: threadId2, owner: "external", harnessId: sharedHarness };
40898
- const record4 = await this.#repository.find(threadId2);
40899
- return record4 ? { threadId: threadId2, owner: "external", harnessId: record4.harnessId } : { threadId: threadId2, owner: "codex" };
41660
+ const record5 = await this.#repository.find(threadId2);
41661
+ return record5 ? { threadId: threadId2, owner: "external", harnessId: record5.harnessId } : { threadId: threadId2, owner: "codex" };
40900
41662
  })
40901
41663
  );
40902
41664
  const result = threadOwnershipListResultSchema.parse({ threads });
@@ -41092,7 +41854,7 @@ var AppServerHost = class {
41092
41854
  if (thread.running || thread.activeTurnId) {
41093
41855
  throw new ExternalCommandError(-32072, "External Thread already has an active operation");
41094
41856
  }
41095
- const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID16());
41857
+ const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID17());
41096
41858
  const projection = {
41097
41859
  projector: new CodexTurnProjector({
41098
41860
  threadId: thread.id,
@@ -41407,6 +42169,7 @@ var AppServerHost = class {
41407
42169
  }
41408
42170
  const params = requestObject(request);
41409
42171
  const route = decodeCreateRoute(request);
42172
+ const prewarm = params[EXTERNAL_THREAD_PREWARM_PARAM] === true || route?.prewarm === true;
41410
42173
  const requestedModel = route && route.harnessId !== "codex" ? route.model : void 0;
41411
42174
  const requestedThinkingOptionId = route && route.harnessId !== "codex" ? route.thinkingOptionId : void 0;
41412
42175
  const requestedPermissionModeId = route && route.harnessId !== "codex" ? route.permissionModeId : void 0;
@@ -41426,9 +42189,9 @@ var AppServerHost = class {
41426
42189
  ephemeral: params.ephemeral === true,
41427
42190
  historyMode: params.historyMode === "paginated" ? "paginated" : "legacy"
41428
42191
  });
41429
- let record4;
42192
+ let record5;
41430
42193
  try {
41431
- record4 = await this.#repository.createProvisional(recordInput);
42194
+ record5 = await this.#repository.createProvisional(recordInput);
41432
42195
  } catch {
41433
42196
  this.#routeObservationTracker.rejectCreate(request.id);
41434
42197
  await this.#writer.json(rpcError(request, -32081, "External Thread could not be persisted"));
@@ -41439,7 +42202,7 @@ var AppServerHost = class {
41439
42202
  cwd,
41440
42203
  environment: {
41441
42204
  ...this.#options.environment ?? process.env,
41442
- [DELEGATION_THREAD_ID_ENV]: record4.hostThreadId
42205
+ [DELEGATION_THREAD_ID_ENV]: record5.hostThreadId
41443
42206
  },
41444
42207
  ...requestedModel ? { model: requestedModel } : {},
41445
42208
  ...requestedThinkingOptionId ? { thinkingOptionId: requestedThinkingOptionId } : {},
@@ -41447,37 +42210,37 @@ var AppServerHost = class {
41447
42210
  });
41448
42211
  if (!sessionResult.ok) {
41449
42212
  this.#routeObservationTracker.rejectCreate(request.id);
41450
- await this.#repository.removeProvisional(record4.hostThreadId).catch(() => void 0);
42213
+ await this.#repository.removeProvisional(record5.hostThreadId).catch(() => void 0);
41451
42214
  const mapped = mapExternalThreadHarnessError(sessionResult.error, "create");
41452
42215
  await this.#writer.json(rpcError(request, mapped.code, mapped.message));
41453
42216
  return;
41454
42217
  }
41455
42218
  const session = sessionResult.value;
41456
- await this.#externalRuntime.idleRelease.runOperation(record4.hostThreadId, async () => {
42219
+ await this.#externalRuntime.idleRelease.runOperation(record5.hostThreadId, async () => {
41457
42220
  try {
41458
- if (session.initialState.nativeRef && params[EXTERNAL_THREAD_PREWARM_PARAM] !== true) {
41459
- record4 = await this.#repository.commitNative(
41460
- record4.hostThreadId,
42221
+ if (session.initialState.nativeRef && !prewarm) {
42222
+ record5 = await this.#repository.commitNative(
42223
+ record5.hostThreadId,
41461
42224
  session.initialState.nativeRef
41462
42225
  );
41463
42226
  }
41464
42227
  const thread = externalThreadValue({
41465
- record: record4,
42228
+ record: record5,
41466
42229
  turns: [],
41467
- sessionId: record4.hostThreadId
42230
+ sessionId: record5.hostThreadId
41468
42231
  });
41469
42232
  const externalThread = this.#registerExternalThread({
41470
- record: record4,
42233
+ record: record5,
41471
42234
  session,
41472
- unsubmittedPrewarm: params[EXTERNAL_THREAD_PREWARM_PARAM] === true,
41473
- sessionId: record4.hostThreadId,
42235
+ unsubmittedPrewarm: prewarm,
42236
+ sessionId: record5.hostThreadId,
41474
42237
  thread,
41475
42238
  turns: [],
41476
42239
  ...requestedModel ? { requestedModel } : {},
41477
42240
  ...requestedThinkingOptionId ? { requestedThinkingOptionId } : {},
41478
42241
  ...requestedPermissionModeId ? { requestedPermissionModeId } : {}
41479
42242
  });
41480
- if (params[EXTERNAL_THREAD_PREWARM_PARAM] === true) {
42243
+ if (prewarm) {
41481
42244
  this.#externalPrewarms.register(externalThread);
41482
42245
  }
41483
42246
  this.#routeObservationTracker.bindCreatedThread(request.id, externalThread.id);
@@ -41500,12 +42263,12 @@ var AppServerHost = class {
41500
42263
  }
41501
42264
  })
41502
42265
  );
41503
- if (record4.state === "ready") await this.#notifyExternalThreadStarted(thread);
42266
+ if (record5.state === "ready") await this.#notifyExternalThreadStarted(thread);
41504
42267
  } catch {
41505
- this.#externalRuntime.remove(record4.hostThreadId);
41506
- this.#routeObservationTracker.forgetThread(record4.hostThreadId);
42268
+ this.#externalRuntime.remove(record5.hostThreadId);
42269
+ this.#routeObservationTracker.forgetThread(record5.hostThreadId);
41507
42270
  await session.close().catch(() => void 0);
41508
- await this.#repository.removeProvisional(record4.hostThreadId).catch(() => void 0);
42271
+ await this.#repository.removeProvisional(record5.hostThreadId).catch(() => void 0);
41509
42272
  await this.#writer.json(
41510
42273
  rpcError(request, -32081, "External Thread could not be persisted")
41511
42274
  );
@@ -41667,9 +42430,9 @@ var AppServerHost = class {
41667
42430
  );
41668
42431
  return;
41669
42432
  }
41670
- let record4;
42433
+ let record5;
41671
42434
  try {
41672
- record4 = await this.#repository.setTitle(location.record.hostThreadId, name);
42435
+ record5 = await this.#repository.setTitle(location.record.hostThreadId, name);
41673
42436
  } catch {
41674
42437
  await this.#writer.json(
41675
42438
  rpcError(request, -32081, "External Thread title could not be persisted")
@@ -41677,7 +42440,7 @@ var AppServerHost = class {
41677
42440
  return;
41678
42441
  }
41679
42442
  if (location.thread) {
41680
- location.thread.record = record4;
42443
+ location.thread.record = record5;
41681
42444
  location.thread.thread.name = name;
41682
42445
  location.thread.thread.updatedAt = unixSeconds();
41683
42446
  }
@@ -41688,29 +42451,24 @@ var AppServerHost = class {
41688
42451
  });
41689
42452
  }
41690
42453
  async #deleteExternalThread(request, location) {
41691
- const thread = location.thread;
41692
42454
  try {
41693
- await this.#repository.removeThread(location.record.hostThreadId);
41694
- } catch {
41695
- await this.#writer.json(rpcError(request, -32081, "External Thread could not be removed"));
41696
- return;
41697
- }
41698
- this.#externalRuntime.remove(location.record.hostThreadId);
41699
- this.#routeObservationTracker.forgetThread(location.record.hostThreadId);
41700
- if (!thread) {
41701
- await this.#writer.json(rpcEnvelope(request, { result: {} }));
41702
- return;
41703
- }
41704
- thread.stateObserver.fault(new Error("External Thread was deleted"));
41705
- try {
41706
- await thread.session.close();
41707
- await thread.outputTask;
41708
- await this.#writer.json(rpcEnvelope(request, { result: {} }));
42455
+ await this.#externalRuntime.deleteThread(location.record.hostThreadId);
41709
42456
  } catch (error51) {
42457
+ if (!(error51 instanceof ExternalSessionReleaseError) && location.thread)
42458
+ await this.#resolveThreadInteractions(location.thread);
41710
42459
  await this.#writer.json(
41711
- rpcError(request, -32075, `External Thread could not close: ${errorMessage4(error51)}`)
42460
+ error51 instanceof ExternalSessionReleaseError ? rpcError(request, -32075, error51.message) : rpcError(request, -32081, "External Thread could not be removed")
41712
42461
  );
42462
+ return;
41713
42463
  }
42464
+ if (location.thread) await this.#resolveThreadInteractions(location.thread);
42465
+ this.#routeObservationTracker.forgetThread(location.record.hostThreadId);
42466
+ this.#externalQueue.forget(location.record.hostThreadId);
42467
+ await this.#writer.json(rpcEnvelope(request, { result: {} }));
42468
+ await this.#writer.json({
42469
+ method: "thread/deleted",
42470
+ params: { threadId: location.record.hostThreadId }
42471
+ });
41714
42472
  }
41715
42473
  async #readExternalThreadMetadata(request, location) {
41716
42474
  try {
@@ -41959,6 +42717,125 @@ var AppServerHost = class {
41959
42717
  );
41960
42718
  }
41961
42719
  }
42720
+ async #handleExternalQueueRequest(request, threadId2) {
42721
+ const queue = this.#externalQueue;
42722
+ try {
42723
+ const params = requestObject(request);
42724
+ const input = () => {
42725
+ requestText(params);
42726
+ return params.input;
42727
+ };
42728
+ const submissionId = () => {
42729
+ if (typeof params.queuedSubmissionId !== "string")
42730
+ throw new ExternalQueueError(-32602, "queuedSubmissionId must be a string");
42731
+ return params.queuedSubmissionId;
42732
+ };
42733
+ let result;
42734
+ switch (request.method) {
42735
+ case "thread/queue/list":
42736
+ result = queue.list(threadId2, params);
42737
+ break;
42738
+ case "thread/queue/add": {
42739
+ if (typeof params.clientUserMessageId !== "string" || !params.clientUserMessageId)
42740
+ throw new ExternalQueueError(-32602, "clientUserMessageId must be a string");
42741
+ const sourceHostId = params[THREAD_REFERENCE_SOURCE_HOST_PARAM];
42742
+ const submission = await queue.add(
42743
+ threadId2,
42744
+ input(),
42745
+ params.clientUserMessageId,
42746
+ typeof sourceHostId === "string" ? sourceHostId : void 0
42747
+ );
42748
+ result = { queuedSubmission: submission };
42749
+ break;
42750
+ }
42751
+ case "thread/queue/update": {
42752
+ const submission = await queue.update(threadId2, submissionId(), input());
42753
+ result = { queuedSubmission: submission };
42754
+ break;
42755
+ }
42756
+ case "thread/queue/delete":
42757
+ result = { deleted: await queue.delete(threadId2, submissionId()) };
42758
+ break;
42759
+ case "thread/queue/reorder": {
42760
+ const ids = params.queuedSubmissionIds;
42761
+ if (!Array.isArray(ids) || !ids.every((id2) => typeof id2 === "string"))
42762
+ throw new ExternalQueueError(-32602, "queuedSubmissionIds must be strings");
42763
+ await queue.reorder(threadId2, ids);
42764
+ result = {};
42765
+ break;
42766
+ }
42767
+ case "thread/queue/start": {
42768
+ const resolution = await this.#resolveExternalThread(threadId2);
42769
+ if (await this.#writeResolutionError(request, resolution)) return;
42770
+ if (resolution.kind !== "external")
42771
+ throw new ExternalQueueError(-32073, "External Thread is no longer available");
42772
+ const started = await this.#startQueuedSubmission(
42773
+ resolution.thread,
42774
+ params.queuedSubmissionId == null ? null : submissionId()
42775
+ );
42776
+ try {
42777
+ await this.#writer.json(rpcEnvelope(request, { result: { turn: started.turn } }));
42778
+ } finally {
42779
+ started.gate.resolve();
42780
+ }
42781
+ return;
42782
+ }
42783
+ default:
42784
+ throw new ExternalQueueError(
42785
+ -32076,
42786
+ `External Thread does not support ${request.method}`
42787
+ );
42788
+ }
42789
+ await this.#writer.json(rpcEnvelope(request, { result }));
42790
+ if (request.method === "thread/queue/add") {
42791
+ const thread = this.#externalRuntime.get(threadId2);
42792
+ const lastTurn = thread?.turns.at(-1);
42793
+ if (thread && thread.projectedTerminalTurnId === lastTurn?.id && lastTurn?.status === "completed" && isRecord18(thread.thread.status) && thread.thread.status.type === "idle") {
42794
+ void this.#drainExternalQueue(thread);
42795
+ }
42796
+ }
42797
+ } catch (error51) {
42798
+ await this.#writer.json(
42799
+ rpcError(
42800
+ request,
42801
+ error51 instanceof ExternalQueueError || error51 instanceof ExternalSteerError || error51 instanceof ExternalCommandError ? error51.code : -32602,
42802
+ errorMessage4(error51)
42803
+ )
42804
+ );
42805
+ }
42806
+ }
42807
+ /** Starts a queued follow-up as a Turn; it returns to its place when the start fails. */
42808
+ async #startQueuedSubmission(thread, submissionId) {
42809
+ if (this.#externalThreadBusy(thread) || this.#pendingExternalCommandRequests.has(thread.id))
42810
+ throw new ExternalSteerError(-32072, "External Thread already has an active Turn");
42811
+ const taken = this.#externalQueue.take(thread.id, submissionId);
42812
+ try {
42813
+ const started = await this.#beginExternalInputTurn(
42814
+ thread,
42815
+ requestText({ input: taken.submission.input }),
42816
+ void 0,
42817
+ taken.submission.clientUserMessageId,
42818
+ taken.sourceHostId,
42819
+ true
42820
+ );
42821
+ await this.#externalQueue.notifyChanged(thread.id);
42822
+ return started;
42823
+ } catch (error51) {
42824
+ this.#externalQueue.restore(thread.id, taken);
42825
+ await this.#externalQueue.notifyChanged(thread.id);
42826
+ throw error51;
42827
+ }
42828
+ }
42829
+ /** Desktop leaves queued follow-ups to the app-server once a Turn completes normally. */
42830
+ async #drainExternalQueue(thread) {
42831
+ if (!this.#externalQueue.has(thread.id) || this.#externalThreadBusy(thread) || this.#pendingExternalCommandRequests.has(thread.id))
42832
+ return;
42833
+ try {
42834
+ (await this.#startQueuedSubmission(thread)).gate.resolve();
42835
+ } catch (error51) {
42836
+ this.#diagnose(error51);
42837
+ }
42838
+ }
41962
42839
  async #steerExternalTurn(request, thread) {
41963
42840
  try {
41964
42841
  const started = await this.#externalSteering.run(
@@ -42023,12 +42900,12 @@ var AppServerHost = class {
42023
42900
  };
42024
42901
  }
42025
42902
  /** Keep command restoration and dispatch identical for start and steer submissions. */
42026
- async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId, sourceHostId) {
42903
+ async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId, sourceHostId, projectInput = false) {
42027
42904
  const text = restoreHarnessCommandMentions(inputText);
42028
42905
  const commands = thread.session.commands;
42029
42906
  if (!commands || !isExternalCommandCandidate(text)) {
42030
42907
  assertActive?.();
42031
- return this.#beginExternalTurn(thread, text, clientUserMessageId, sourceHostId);
42908
+ return this.#beginExternalTurn(thread, text, clientUserMessageId, sourceHostId, projectInput);
42032
42909
  }
42033
42910
  this.#pendingExternalCommandRequests.add(thread.id);
42034
42911
  try {
@@ -42039,7 +42916,13 @@ var AppServerHost = class {
42039
42916
  assertActive?.();
42040
42917
  if (!command) {
42041
42918
  this.#pendingExternalCommandRequests.delete(thread.id);
42042
- return await this.#beginExternalTurn(thread, text, clientUserMessageId, sourceHostId);
42919
+ return await this.#beginExternalTurn(
42920
+ thread,
42921
+ text,
42922
+ clientUserMessageId,
42923
+ sourceHostId,
42924
+ projectInput
42925
+ );
42043
42926
  }
42044
42927
  return await this.#beginExternalCommand(
42045
42928
  thread,
@@ -42072,14 +42955,18 @@ var AppServerHost = class {
42072
42955
  else this.#executionHosts.set(thread, previousHostId);
42073
42956
  };
42074
42957
  }
42075
- async #beginExternalTurn(thread, text, clientUserMessageId, sourceHostId) {
42958
+ /**
42959
+ * Desktop renders the input of its own `turn/start` locally. Other starts (Host-only clients
42960
+ * and queued follow-ups) need the user message projected with the Turn.
42961
+ */
42962
+ async #beginExternalTurn(thread, text, clientUserMessageId, sourceHostId, projectInput = false) {
42076
42963
  if (this.#closeRequested || this.#externalRuntime.get(thread.id) !== thread) {
42077
42964
  throw new ExternalSteerError(-32073, "External Thread is no longer available");
42078
42965
  }
42079
42966
  if (thread.running || thread.activeTurnId || this.#pendingExternalCommandRequests.has(thread.id)) {
42080
42967
  throw new ExternalSteerError(-32072, "External Thread already has an active Turn");
42081
42968
  }
42082
- const turnId = hostTurnIdSchema.parse(randomUUID16());
42969
+ const turnId = hostTurnIdSchema.parse(randomUUID17());
42083
42970
  const startedAtMs = Date.now();
42084
42971
  const projection = {
42085
42972
  projector: new CodexTurnProjector({
@@ -42087,7 +42974,7 @@ var AppServerHost = class {
42087
42974
  turnId,
42088
42975
  cwd: thread.cwd,
42089
42976
  startedAtMs,
42090
- ...this.#options.externalOnly ? {
42977
+ ...this.#options.externalOnly || projectInput ? {
42091
42978
  initialInput: [{ type: "text", text }],
42092
42979
  ...clientUserMessageId ? { clientUserMessageId } : {}
42093
42980
  } : {}
@@ -42318,21 +43205,21 @@ var AppServerHost = class {
42318
43205
  }
42319
43206
  if (event.type === "subagent.transcript.changed") {
42320
43207
  const nativeSubagentId = event.nativeSubagentId;
42321
- const record4 = (await this.#repository.list()).find(
43208
+ const record5 = (await this.#repository.list()).find(
42322
43209
  (candidate) => candidate.subagent?.parentHostThreadId === thread.id && candidate.subagent.nativeSubagentId === nativeSubagentId && candidate.nativeSessionRef?.nativeSessionId === thread.record.nativeSessionRef?.nativeSessionId
42323
43210
  );
42324
- if (record4) await this.#refreshOpenSubagentThread(record4.hostThreadId, false);
43211
+ if (record5) await this.#refreshOpenSubagentThread(record5.hostThreadId, false);
42325
43212
  return;
42326
43213
  }
42327
43214
  if (event.type === "subagent.state.changed") {
42328
43215
  const nativeSubagentId = event.nativeSubagentId;
42329
- const record4 = (await this.#repository.list()).find(
43216
+ const record5 = (await this.#repository.list()).find(
42330
43217
  (candidate) => candidate.subagent?.parentHostThreadId === thread.id && candidate.subagent.nativeSubagentId === nativeSubagentId && candidate.nativeSessionRef?.nativeSessionId === thread.record.nativeSessionRef?.nativeSessionId
42331
43218
  );
42332
- if (!record4) return;
43219
+ if (!record5) return;
42333
43220
  const status2 = event.status === "pending" || event.status === "running" ? "active" : "idle";
42334
- this.#trackRunningSubagent(thread.id, record4.hostThreadId, status2);
42335
- await this.#setSubagentThreadStatus(record4.hostThreadId, status2);
43221
+ this.#trackRunningSubagent(thread.id, record5.hostThreadId, status2);
43222
+ await this.#setSubagentThreadStatus(record5.hostThreadId, status2);
42336
43223
  if (!thread.running && !thread.activeTurnId && !this.#hasRunningSubagents(thread.id)) {
42337
43224
  await this.#setThreadStatus(thread, { type: "idle" });
42338
43225
  }
@@ -42341,7 +43228,7 @@ var AppServerHost = class {
42341
43228
  if (event.type === "session.faulted") {
42342
43229
  for (const pending of [...this.#pendingDesktopQuestions.values()]) {
42343
43230
  if (pending.shared && pending.thread === thread)
42344
- this.#retireDesktopQuestion(pending.interaction.interactionId);
43231
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42345
43232
  }
42346
43233
  this.#externalSteering.fault(thread.id, new Error(event.error.message));
42347
43234
  thread.stateObserver.fault(new Error(event.error.message));
@@ -42389,12 +43276,12 @@ var AppServerHost = class {
42389
43276
  if (event.type === "turn.completed") {
42390
43277
  for (const pending of [...this.#pendingDesktopQuestions.values()]) {
42391
43278
  if (pending.shared && pending.thread === thread && pending.interaction.turnId === event.turnId)
42392
- this.#retireDesktopQuestion(pending.interaction.interactionId);
43279
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42393
43280
  }
42394
43281
  }
42395
43282
  if (event.type === "interaction.closed") {
42396
- await this.#resolveDesktopApproval(event.interactionId);
42397
- await this.#resolveDesktopQuestion(event.interactionId);
43283
+ await this.#resolveDesktopApproval(event.interactionId, thread);
43284
+ await this.#resolveDesktopQuestion(event.interactionId, thread);
42398
43285
  }
42399
43286
  const ephemeralTurn = event.type === "turn.completed" && (event.ephemeral === true || thread.ephemeralTurnIds.has(event.turnId));
42400
43287
  if (event.type === "turn.completed" && !ephemeralTurn) {
@@ -42460,32 +43347,35 @@ var AppServerHost = class {
42460
43347
  this.#hasRunningSubagents(thread.id) ? { type: "active", activeFlags: [] } : { type: "idle" }
42461
43348
  );
42462
43349
  this.#externalSteering.terminal(thread.id, event.turnId, event.outcome);
43350
+ if (!ephemeralTurn && result.completedTurn?.status === "completed" && this.#externalQueue.has(thread.id)) {
43351
+ void this.#drainExternalQueue(thread);
43352
+ }
42463
43353
  }
42464
43354
  }
42465
43355
  async #materializeSubagent(parent, subagent) {
42466
43356
  if (!subagent.nativeSubagentId || !parent.record.nativeSessionRef) return subagent;
42467
43357
  const status2 = subagent.status === "pending" || subagent.status === "running" ? "active" : "idle";
42468
- const record4 = await this.#repository.materializeSubagent(parent.record, subagent);
42469
- if (!record4) return subagent;
42470
- if (this.#subagentThreadStatuses.has(record4.hostThreadId)) {
42471
- this.#trackRunningSubagent(parent.id, record4.hostThreadId, status2);
42472
- await this.#setSubagentThreadStatus(record4.hostThreadId, status2);
42473
- return { ...subagent, subagentId: record4.hostThreadId };
43358
+ const record5 = await this.#repository.materializeSubagent(parent.record, subagent);
43359
+ if (!record5) return subagent;
43360
+ if (this.#subagentThreadStatuses.has(record5.hostThreadId)) {
43361
+ this.#trackRunningSubagent(parent.id, record5.hostThreadId, status2);
43362
+ await this.#setSubagentThreadStatus(record5.hostThreadId, status2);
43363
+ return { ...subagent, subagentId: record5.hostThreadId };
42474
43364
  }
42475
43365
  const thread = externalThreadValue({
42476
- record: record4,
43366
+ record: record5,
42477
43367
  turns: [],
42478
43368
  sessionId: parent.sessionId,
42479
43369
  running: status2 === "active"
42480
43370
  });
42481
- this.#subagentThreadStatuses.set(record4.hostThreadId, status2);
42482
- this.#trackRunningSubagent(parent.id, record4.hostThreadId, status2);
43371
+ this.#subagentThreadStatuses.set(record5.hostThreadId, status2);
43372
+ this.#trackRunningSubagent(parent.id, record5.hostThreadId, status2);
42483
43373
  await this.#writer.json({
42484
43374
  method: "thread/started",
42485
43375
  emittedAtMs: Date.now(),
42486
43376
  params: { thread }
42487
43377
  });
42488
- return { ...subagent, subagentId: record4.hostThreadId };
43378
+ return { ...subagent, subagentId: record5.hostThreadId };
42489
43379
  }
42490
43380
  async #refreshOpenSubagentThread(threadId2, terminal3 = true) {
42491
43381
  await this.#desktopRequests.run(threadId2, async () => {
@@ -42651,7 +43541,7 @@ var AppServerHost = class {
42651
43541
  if (this.#externalRuntime.get(pending.thread.id) !== pending.thread || this.#externalRuntime.idleRelease.failure(pending.thread))
42652
43542
  return true;
42653
43543
  if (this.#options.externalOnly)
42654
- await this.#resolveDesktopApproval(pending.interaction.interactionId);
43544
+ await this.#resolveDesktopApproval(pending.interaction.interactionId, pending.thread);
42655
43545
  else this.#pendingDesktopApprovals.delete(requestId);
42656
43546
  let response;
42657
43547
  try {
@@ -42702,9 +43592,20 @@ var AppServerHost = class {
42702
43592
  }
42703
43593
  return denied.ok;
42704
43594
  }
42705
- async #resolveDesktopApproval(interactionId) {
43595
+ async #resolveThreadInteractions(thread) {
43596
+ for (const pending of [...this.#pendingDesktopApprovals.values()]) {
43597
+ if (pending.thread === thread)
43598
+ await this.#resolveDesktopApproval(pending.interaction.interactionId, thread);
43599
+ }
43600
+ for (const pending of [...this.#pendingDesktopQuestions.values()]) {
43601
+ if (pending.thread === thread)
43602
+ await this.#resolveDesktopQuestion(pending.interaction.interactionId, thread);
43603
+ }
43604
+ }
43605
+ async #resolveDesktopApproval(interactionId, thread) {
42706
43606
  for (const [requestId, pending] of this.#pendingDesktopApprovals) {
42707
- if (pending.interaction.interactionId !== interactionId) continue;
43607
+ if (pending.thread !== thread || pending.interaction.interactionId !== interactionId)
43608
+ continue;
42708
43609
  this.#pendingDesktopApprovals.delete(requestId);
42709
43610
  await this.#writer.json({
42710
43611
  method: "serverRequest/resolved",
@@ -42763,16 +43664,16 @@ var AppServerHost = class {
42763
43664
  response
42764
43665
  });
42765
43666
  } catch (error51) {
42766
- this.#retireDesktopQuestion(pending.interaction.interactionId);
43667
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42767
43668
  throw error51;
42768
43669
  }
42769
43670
  if (!result.ok) {
42770
43671
  pending.responding = false;
42771
43672
  if (result.error.code === "invalidState")
42772
- this.#retireDesktopQuestion(pending.interaction.interactionId);
43673
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42773
43674
  throw new Error(result.error.message);
42774
43675
  }
42775
- this.#retireDesktopQuestion(pending.interaction.interactionId);
43676
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42776
43677
  await this.#writer.json(rpcEnvelope(request, { result: { accepted: true } }));
42777
43678
  });
42778
43679
  } catch (error51) {
@@ -42788,7 +43689,7 @@ var AppServerHost = class {
42788
43689
  if (shared) sharedQuestion(interaction);
42789
43690
  result = projection.projector.projectQuestion(
42790
43691
  interaction,
42791
- hostItemIdSchema.parse(randomUUID16())
43692
+ hostItemIdSchema.parse(randomUUID17())
42792
43693
  );
42793
43694
  } catch (error51) {
42794
43695
  this.#diagnose(error51);
@@ -42826,7 +43727,7 @@ var AppServerHost = class {
42826
43727
  try {
42827
43728
  await this.#writer.json({ id: requestId, ...result.questionRequest.request });
42828
43729
  } catch (error51) {
42829
- this.#retireDesktopQuestion(interaction.interactionId);
43730
+ this.#retireDesktopQuestion(interaction.interactionId, thread);
42830
43731
  await thread.session.execute({
42831
43732
  type: "interaction.respond",
42832
43733
  interactionId: interaction.interactionId,
@@ -42844,7 +43745,7 @@ var AppServerHost = class {
42844
43745
  if (this.#externalRuntime.get(pending.thread.id) !== pending.thread || this.#externalRuntime.idleRelease.failure(pending.thread))
42845
43746
  return true;
42846
43747
  if (this.#options.externalOnly)
42847
- await this.#resolveDesktopQuestion(pending.interaction.interactionId);
43748
+ await this.#resolveDesktopQuestion(pending.interaction.interactionId, pending.thread);
42848
43749
  else this.#pendingDesktopQuestions.delete(requestId);
42849
43750
  if (pending.timeout) clearTimeout(pending.timeout);
42850
43751
  let response;
@@ -42871,7 +43772,7 @@ var AppServerHost = class {
42871
43772
  await this.#externalRuntime.idleRelease.runOperation(pending.thread.id, async () => {
42872
43773
  if (this.#externalRuntime.get(pending.thread.id) !== pending.thread || this.#externalRuntime.idleRelease.failure(pending.thread))
42873
43774
  return;
42874
- await this.#resolveDesktopQuestion(pending.interaction.interactionId);
43775
+ await this.#resolveDesktopQuestion(pending.interaction.interactionId, pending.thread);
42875
43776
  if (pending.responding) return;
42876
43777
  const result = await pending.thread.session.execute({
42877
43778
  type: "interaction.respond",
@@ -42883,16 +43784,18 @@ var AppServerHost = class {
42883
43784
  }
42884
43785
  });
42885
43786
  }
42886
- #retireDesktopQuestion(interactionId) {
43787
+ #retireDesktopQuestion(interactionId, thread) {
42887
43788
  for (const [requestId, pending] of this.#pendingDesktopQuestions) {
42888
- if (pending.interaction.interactionId !== interactionId) continue;
43789
+ if (pending.thread !== thread || pending.interaction.interactionId !== interactionId)
43790
+ continue;
42889
43791
  if (pending.timeout) clearTimeout(pending.timeout);
42890
43792
  this.#pendingDesktopQuestions.delete(requestId);
42891
43793
  }
42892
43794
  }
42893
- async #resolveDesktopQuestion(interactionId) {
43795
+ async #resolveDesktopQuestion(interactionId, thread) {
42894
43796
  for (const [requestId, pending] of this.#pendingDesktopQuestions) {
42895
- if (pending.interaction.interactionId !== interactionId) continue;
43797
+ if (pending.thread !== thread || pending.interaction.interactionId !== interactionId)
43798
+ continue;
42896
43799
  if (pending.timeout) clearTimeout(pending.timeout);
42897
43800
  this.#pendingDesktopQuestions.delete(requestId);
42898
43801
  if (pending.shared) continue;
@@ -43032,7 +43935,7 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
43032
43935
  var wrapper_default = import_websocket.default;
43033
43936
 
43034
43937
  // packages/host-runtime/src/remote-socket-lock.ts
43035
- import { randomUUID as randomUUID17 } from "node:crypto";
43938
+ import { randomUUID as randomUUID18 } from "node:crypto";
43036
43939
  import { chmod as chmod3, lstat as lstat5, mkdir as mkdir12, open as open9, readFile as readFile16, readdir as readdir5, rename as rename11, rm as rm11 } from "node:fs/promises";
43037
43940
  import { uptime } from "node:os";
43038
43941
  import path26 from "node:path";
@@ -43046,18 +43949,18 @@ var LOCK_ENTRY_SUFFIX = ".json";
43046
43949
  function currentBootTimeSeconds() {
43047
43950
  return Math.round(Date.now() / 1e3 - uptime());
43048
43951
  }
43049
- function validOwnerFields(record4) {
43050
- return typeof record4.ownerToken === "string" && record4.ownerToken.length > 0 && typeof record4.pid === "number" && Number.isSafeInteger(record4.pid) && record4.pid > 0 && typeof record4.bootTimeSeconds === "number" && Number.isSafeInteger(record4.bootTimeSeconds);
43952
+ function validOwnerFields(record5) {
43953
+ return typeof record5.ownerToken === "string" && record5.ownerToken.length > 0 && typeof record5.pid === "number" && Number.isSafeInteger(record5.pid) && record5.pid > 0 && typeof record5.bootTimeSeconds === "number" && Number.isSafeInteger(record5.bootTimeSeconds);
43051
43954
  }
43052
43955
  function parseLockRecord(source) {
43053
43956
  try {
43054
43957
  const value2 = JSON.parse(source);
43055
43958
  if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) return null;
43056
- const record4 = value2;
43057
- if (record4.version !== 2 || !validOwnerFields(record4) || typeof record4.choosing !== "boolean" || typeof record4.ticket !== "number" || !Number.isSafeInteger(record4.ticket) || record4.ticket < 0 || (record4.choosing ? record4.ticket !== 0 : record4.ticket === 0)) {
43959
+ const record5 = value2;
43960
+ if (record5.version !== 2 || !validOwnerFields(record5) || typeof record5.choosing !== "boolean" || typeof record5.ticket !== "number" || !Number.isSafeInteger(record5.ticket) || record5.ticket < 0 || (record5.choosing ? record5.ticket !== 0 : record5.ticket === 0)) {
43058
43961
  return null;
43059
43962
  }
43060
- return record4;
43963
+ return record5;
43061
43964
  } catch {
43062
43965
  return null;
43063
43966
  }
@@ -43066,9 +43969,9 @@ function parseLegacyLockRecord(source) {
43066
43969
  try {
43067
43970
  const value2 = JSON.parse(source);
43068
43971
  if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) return null;
43069
- const record4 = value2;
43070
- if (record4.version !== 1 || !validOwnerFields(record4)) return null;
43071
- return record4;
43972
+ const record5 = value2;
43973
+ if (record5.version !== 1 || !validOwnerFields(record5)) return null;
43974
+ return record5;
43072
43975
  } catch {
43073
43976
  return null;
43074
43977
  }
@@ -43081,10 +43984,10 @@ function processIsRunning(pid) {
43081
43984
  return error51.code !== "ESRCH";
43082
43985
  }
43083
43986
  }
43084
- function ownerIsAbandoned(record4, mtimeMs) {
43085
- if (Math.abs(record4.bootTimeSeconds - currentBootTimeSeconds()) > 5) return true;
43987
+ function ownerIsAbandoned(record5, mtimeMs) {
43988
+ if (Math.abs(record5.bootTimeSeconds - currentBootTimeSeconds()) > 5) return true;
43086
43989
  if (Math.max(0, Date.now() - mtimeMs) >= LOCK_MAX_AGE_MS) return true;
43087
- return !processIsRunning(record4.pid);
43990
+ return !processIsRunning(record5.pid);
43088
43991
  }
43089
43992
  function sameUnixFileIdentity(left, right) {
43090
43993
  return left.dev === right.dev && left.ino === right.ino;
@@ -43103,13 +44006,13 @@ async function readLockEntrySnapshot(filePath) {
43103
44006
  throw error51;
43104
44007
  });
43105
44008
  if (source === null) return null;
43106
- const record4 = parseLockRecord(source);
44009
+ const record5 = parseLockRecord(source);
43107
44010
  return {
43108
44011
  filePath,
43109
44012
  source,
43110
44013
  identity: { dev: metadata.dev, ino: metadata.ino },
43111
44014
  mtimeMs: metadata.mtimeMs,
43112
- record: record4 && path26.basename(filePath) === lockEntryName(record4.ownerToken) ? record4 : null
44015
+ record: record5 && path26.basename(filePath) === lockEntryName(record5.ownerToken) ? record5 : null
43113
44016
  };
43114
44017
  }
43115
44018
  function lockEntryIsAbandoned(snapshot2) {
@@ -43157,11 +44060,11 @@ async function preparePrivateLockDirectory(lockDirectory) {
43157
44060
  }
43158
44061
  await chmod3(lockDirectory, 448);
43159
44062
  }
43160
- async function writeLockRecordAtomic(lockDirectory, entryPath, record4) {
43161
- const temporary = path26.join(lockDirectory, `.tmp-${record4.ownerToken}-${randomUUID17()}`);
44063
+ async function writeLockRecordAtomic(lockDirectory, entryPath, record5) {
44064
+ const temporary = path26.join(lockDirectory, `.tmp-${record5.ownerToken}-${randomUUID18()}`);
43162
44065
  const handle = await open9(temporary, "wx", 384);
43163
44066
  try {
43164
- await handle.writeFile(`${JSON.stringify(record4)}
44067
+ await handle.writeFile(`${JSON.stringify(record5)}
43165
44068
  `, "utf8");
43166
44069
  await handle.sync();
43167
44070
  } finally {
@@ -43191,11 +44094,11 @@ async function legacyLockState(legacyPath) {
43191
44094
  });
43192
44095
  if (source === null) return "absent";
43193
44096
  const ageMs = Math.max(0, Date.now() - metadata.mtimeMs);
43194
- const record4 = parseLegacyLockRecord(source);
43195
- if (record4 === null) return ageMs < LOCK_MALFORMED_GRACE_MS ? "blocking" : "abandoned";
43196
- return ownerIsAbandoned(record4, metadata.mtimeMs) ? "abandoned" : "blocking";
44097
+ const record5 = parseLegacyLockRecord(source);
44098
+ if (record5 === null) return ageMs < LOCK_MALFORMED_GRACE_MS ? "blocking" : "abandoned";
44099
+ return ownerIsAbandoned(record5, metadata.mtimeMs) ? "abandoned" : "blocking";
43197
44100
  }
43198
- async function tryAcquireLegacyCompatibilityGuard(legacyPath, record4) {
44101
+ async function tryAcquireLegacyCompatibilityGuard(legacyPath, record5) {
43199
44102
  const handle = await open9(legacyPath, "wx", 384).catch((error51) => {
43200
44103
  if (error51.code === "EEXIST") return null;
43201
44104
  throw error51;
@@ -43204,7 +44107,7 @@ async function tryAcquireLegacyCompatibilityGuard(legacyPath, record4) {
43204
44107
  const metadata = await handle.stat();
43205
44108
  const guard = { handle, identity: { dev: metadata.dev, ino: metadata.ino } };
43206
44109
  try {
43207
- await handle.writeFile(`${JSON.stringify(record4)}
44110
+ await handle.writeFile(`${JSON.stringify(record5)}
43208
44111
  `, "utf8");
43209
44112
  await handle.sync();
43210
44113
  return guard;
@@ -43233,7 +44136,7 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
43233
44136
  const legacyPath = `${socketPath}.initializing`;
43234
44137
  const lockDirectory = `${socketPath}.initializers`;
43235
44138
  await preparePrivateLockDirectory(lockDirectory);
43236
- const ownerToken = randomUUID17();
44139
+ const ownerToken = randomUUID18();
43237
44140
  const entryPath = path26.join(lockDirectory, lockEntryName(ownerToken));
43238
44141
  const baseRecord = {
43239
44142
  version: 2,
@@ -43270,8 +44173,8 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
43270
44173
  throw new Error(`Remote app-server socket lock ownership was lost at ${socketPath}`);
43271
44174
  }
43272
44175
  const blockedByBakery = catalog.entries.some((entry) => {
43273
- const record4 = entry.record;
43274
- return record4 !== null && record4.ownerToken !== ownerToken && (record4.choosing || recordHasPriority(record4, ownRecord));
44176
+ const record5 = entry.record;
44177
+ return record5 !== null && record5.ownerToken !== ownerToken && (record5.choosing || recordHasPriority(record5, ownRecord));
43275
44178
  });
43276
44179
  if (!catalog.unsettled && !blockedByBakery) {
43277
44180
  const legacyGuard = await tryAcquireLegacyCompatibilityGuard(legacyPath, {
@@ -43744,12 +44647,12 @@ function createRemoteAppServerWebSocketListener(input) {
43744
44647
 
43745
44648
  // packages/host-runtime/src/remote-official-app-server.ts
43746
44649
  import { spawn as spawn5 } from "node:child_process";
43747
- import { randomUUID as randomUUID18 } from "node:crypto";
44650
+ import { randomUUID as randomUUID19 } from "node:crypto";
43748
44651
  import { lstat as lstat7, rm as rm13, stat as stat7 } from "node:fs/promises";
43749
44652
  import path28 from "node:path";
43750
44653
  var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
43751
44654
  var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
43752
- function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID18()) {
44655
+ function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID19()) {
43753
44656
  if (!path28.posix.isAbsolute(desktopControlSocketPath)) {
43754
44657
  throw new Error("Desktop control socket path must be absolute");
43755
44658
  }
@@ -44968,11 +45871,11 @@ async function readRemoteDelegationThread(environment, input) {
44968
45871
  }
44969
45872
 
44970
45873
  // packages/host-runtime/src/shared-thread-owner.ts
44971
- import { randomUUID as randomUUID20 } from "node:crypto";
45874
+ import { randomUUID as randomUUID21 } from "node:crypto";
44972
45875
  import { PassThrough as PassThrough3 } from "node:stream";
44973
45876
 
44974
45877
  // packages/host-runtime/src/shared-thread-peer.ts
44975
- import { randomUUID as randomUUID19 } from "node:crypto";
45878
+ import { randomUUID as randomUUID20 } from "node:crypto";
44976
45879
  function object5(value2) {
44977
45880
  return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
44978
45881
  }
@@ -44986,7 +45889,7 @@ var StreamThreadPeer = class {
44986
45889
  input;
44987
45890
  output;
44988
45891
  stop;
44989
- #prefix = `shared:${randomUUID19()}:`;
45892
+ #prefix = `shared:${randomUUID20()}:`;
44990
45893
  #pending = /* @__PURE__ */ new Map();
44991
45894
  #listeners = /* @__PURE__ */ new Set();
44992
45895
  #ended = Promise.withResolvers();
@@ -45064,7 +45967,7 @@ var SharedThreadOwner = class {
45064
45967
  input = new PassThrough3();
45065
45968
  output = new PassThrough3();
45066
45969
  #peer = new StreamThreadPeer(this.output, this.input, () => this.input.end());
45067
- #prefix = `shared-interaction:${randomUUID20()}:`;
45970
+ #prefix = `shared-interaction:${randomUUID21()}:`;
45068
45971
  #interactions = /* @__PURE__ */ new Map();
45069
45972
  #listeners = /* @__PURE__ */ new Set();
45070
45973
  #receipts = /* @__PURE__ */ new Map();
@@ -45374,7 +46277,7 @@ var SharedThreadBridge = class {
45374
46277
  };
45375
46278
 
45376
46279
  // packages/host-runtime/src/remote-control-app-server.ts
45377
- import { randomUUID as randomUUID21 } from "node:crypto";
46280
+ import { randomUUID as randomUUID22 } from "node:crypto";
45378
46281
  import { mkdir as mkdir15, open as open10, rename as rename12, rm as rm14 } from "node:fs/promises";
45379
46282
  import path33 from "node:path";
45380
46283
  var REMOTE_CONTROL_BRIDGE_PIPE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_PIPE";
@@ -45395,7 +46298,7 @@ function nodeCompatibleWindowsPath(value2) {
45395
46298
  if (value2.startsWith("\\\\?\\")) return value2.slice(4);
45396
46299
  return value2;
45397
46300
  }
45398
- function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID21()) {
46301
+ function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID22()) {
45399
46302
  const safeInstance = instanceId.replaceAll(/[^a-zA-Z0-9-]/gu, "");
45400
46303
  if (!safeInstance) throw new Error("Remote Control bridge instance ID is invalid");
45401
46304
  return `\\\\.\\pipe\\codexhost-remote-control-${processId}-${safeInstance}`;
@@ -45410,7 +46313,7 @@ async function publishRemoteControlAppServerDescriptor(plan) {
45410
46313
  await mkdir15(directory, { recursive: true, mode: 448 });
45411
46314
  const temporaryPath = path33.join(
45412
46315
  directory,
45413
- `.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID21()}.tmp`
46316
+ `.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID22()}.tmp`
45414
46317
  );
45415
46318
  const handle = await open10(temporaryPath, "wx", 384);
45416
46319
  try {
@@ -45603,12 +46506,12 @@ async function startConsoleControlServer(options2) {
45603
46506
  reply(response, 400, { error: { code: -32700, message: "Invalid request body" } });
45604
46507
  return;
45605
46508
  }
45606
- const record4 = typeof body === "object" && body !== null ? body : {};
45607
- if (typeof record4.method !== "string") {
46509
+ const record5 = typeof body === "object" && body !== null ? body : {};
46510
+ if (typeof record5.method !== "string") {
45608
46511
  reply(response, 400, { error: { code: -32600, message: "method is required" } });
45609
46512
  return;
45610
46513
  }
45611
- reply(response, 200, await options2.target.handleConsoleRequest(record4.method, record4.params));
46514
+ reply(response, 200, await options2.target.handleConsoleRequest(record5.method, record5.params));
45612
46515
  })().catch((error51) => {
45613
46516
  if (!response.headersSent) {
45614
46517
  reply(response, 500, {
@@ -45903,7 +46806,7 @@ function createHostUpdateCoordinator(options2) {
45903
46806
  onPrepared
45904
46807
  });
45905
46808
  }
45906
- if (platform !== "darwin") await manager.start(prepared2);
46809
+ if (platform !== "darwin" && platform !== "win32") await manager.start(prepared2);
45907
46810
  } catch (error51) {
45908
46811
  await lock.release();
45909
46812
  rejectPrepared(error51);
@@ -45932,7 +46835,7 @@ function createHostUpdateCoordinator(options2) {
45932
46835
  }
45933
46836
 
45934
46837
  // packages/host-runtime/src/usage-statistics.ts
45935
- import { randomUUID as randomUUID22 } from "node:crypto";
46838
+ import { randomUUID as randomUUID23 } from "node:crypto";
45936
46839
  import { mkdir as mkdir17, readFile as readFile17, readdir as readdir6, rename as rename14, rm as rm16, writeFile as writeFile10 } from "node:fs/promises";
45937
46840
  import path36 from "node:path";
45938
46841
  import { setImmediate as yieldToEventLoop } from "node:timers/promises";
@@ -46027,14 +46930,14 @@ function parseHarnessUsageEntry(value2) {
46027
46930
  // packages/host-runtime/src/usage-session-titles.ts
46028
46931
  function withHostSessionTitles(result, records) {
46029
46932
  const titles = /* @__PURE__ */ new Map();
46030
- for (const record4 of records) {
46031
- const ref = record4.nativeSessionRef;
46032
- const title = usageSessionTitle(record4.title);
46033
- if (record4.state !== "ready" || !ref || ref.harnessId !== record4.harnessId || !title) continue;
46034
- const key = `${record4.harnessId}\0${ref.nativeSessionId}`;
46933
+ for (const record5 of records) {
46934
+ const ref = record5.nativeSessionRef;
46935
+ const title = usageSessionTitle(record5.title);
46936
+ if (record5.state !== "ready" || !ref || ref.harnessId !== record5.harnessId || !title) continue;
46937
+ const key = `${record5.harnessId}\0${ref.nativeSessionId}`;
46035
46938
  const previous = titles.get(key);
46036
- if (!previous || record4.updatedAt > previous.updatedAt)
46037
- titles.set(key, { title, updatedAt: record4.updatedAt });
46939
+ if (!previous || record5.updatedAt > previous.updatedAt)
46940
+ titles.set(key, { title, updatedAt: record5.updatedAt });
46038
46941
  }
46039
46942
  const decorate = (sessions) => sessions.map((session) => {
46040
46943
  const title = titles.get(`${session.harness}\0${session.sessionId}`)?.title;
@@ -46205,6 +47108,8 @@ function emptyTotals() {
46205
47108
  cachedInputTokens: 0,
46206
47109
  cacheWriteInputTokens: 0,
46207
47110
  cacheKnownInputTokens: 0,
47111
+ cacheHitCachedInputTokens: 0,
47112
+ cacheHitInputTokens: 0,
46208
47113
  outputTokens: 0,
46209
47114
  reasoningOutputTokens: 0,
46210
47115
  costUsd: 0,
@@ -46221,6 +47126,10 @@ function addEntry(totals2, entry, cost) {
46221
47126
  totals2.inputTokens += entry.inputTokens;
46222
47127
  totals2.outputTokens += entry.outputTokens;
46223
47128
  totals2.reasoningOutputTokens += entry.reasoningOutputTokens ?? 0;
47129
+ if (entry.cachedInputTokens !== void 0) {
47130
+ totals2.cacheHitCachedInputTokens += entry.cachedInputTokens;
47131
+ totals2.cacheHitInputTokens += entry.inputTokens;
47132
+ }
46224
47133
  if (entry.cachedInputTokens !== void 0 && entry.cacheWriteInputTokens !== void 0) {
46225
47134
  totals2.cachedInputTokens += entry.cachedInputTokens;
46226
47135
  totals2.cacheWriteInputTokens += entry.cacheWriteInputTokens;
@@ -46467,7 +47376,7 @@ var UsageStatistics = class {
46467
47376
  async #persist(harness2, cache) {
46468
47377
  if (!cache.dirty || this.#now() - cache.persistedAtMs < PERSIST_INTERVAL_MS) return;
46469
47378
  const file2 = this.#file(harness2);
46470
- const temporary = `${file2}.${randomUUID22()}.tmp`;
47379
+ const temporary = `${file2}.${randomUUID23()}.tmp`;
46471
47380
  try {
46472
47381
  await mkdir17(this.#directory, { recursive: true });
46473
47382
  const sources = [...cache.sources].map(([id2, source]) => [
@@ -47078,7 +47987,7 @@ async function runHostRuntime(input) {
47078
47987
  }
47079
47988
 
47080
47989
  // packages/host-runtime/src/remote-host-install.ts
47081
- import { createHash as createHash11, randomUUID as randomUUID23 } from "node:crypto";
47990
+ import { createHash as createHash11, randomUUID as randomUUID24 } from "node:crypto";
47082
47991
  import { constants as fsConstants } from "node:fs";
47083
47992
  import {
47084
47993
  access as access3,
@@ -47177,7 +48086,7 @@ async function writeAtomic(filePath, contents, mode) {
47177
48086
  await mkdir18(path38.dirname(filePath), { recursive: true, mode: 448 });
47178
48087
  const temporary = path38.join(
47179
48088
  path38.dirname(filePath),
47180
- `.${path38.basename(filePath)}.${process.pid}.${randomUUID23()}.tmp`
48089
+ `.${path38.basename(filePath)}.${process.pid}.${randomUUID24()}.tmp`
47181
48090
  );
47182
48091
  try {
47183
48092
  if (typeof contents === "string") {
@@ -47201,7 +48110,7 @@ async function writeAtomicExecutable(filePath, sourcePath) {
47201
48110
  await mkdir18(path38.dirname(filePath), { recursive: true, mode: 448 });
47202
48111
  const temporary = path38.join(
47203
48112
  path38.dirname(filePath),
47204
- `.${path38.basename(filePath)}.${process.pid}.${randomUUID23()}.tmp`
48113
+ `.${path38.basename(filePath)}.${process.pid}.${randomUUID24()}.tmp`
47205
48114
  );
47206
48115
  try {
47207
48116
  await copyFile4(sourcePath, temporary);
@@ -48209,7 +49118,7 @@ var harnessErrorSchema = external_exports.object({
48209
49118
  var harnessSessionStateSchema = external_exports.custom((value2) => {
48210
49119
  if (!value2 || typeof value2 !== "object" || Array.isArray(value2))
48211
49120
  return false;
48212
- const record4 = value2;
49121
+ const record5 = value2;
48213
49122
  const allowed = /* @__PURE__ */ new Set([
48214
49123
  "nativeRef",
48215
49124
  "effectiveModel",
@@ -48218,12 +49127,12 @@ var harnessSessionStateSchema = external_exports.custom((value2) => {
48218
49127
  "availableThinkingOptions",
48219
49128
  "effectivePermissionModeId"
48220
49129
  ]);
48221
- if (Object.keys(record4).some((key) => !allowed.has(key)))
49130
+ if (Object.keys(record5).some((key) => !allowed.has(key)))
48222
49131
  return false;
48223
- if (record4.nativeRef !== void 0 && !nativeSessionRefSchema.safeParse(record4.nativeRef).success) {
49132
+ if (record5.nativeRef !== void 0 && !nativeSessionRefSchema.safeParse(record5.nativeRef).success) {
48224
49133
  return false;
48225
49134
  }
48226
- const { nativeRef: _nativeRef, ...configuration } = record4;
49135
+ const { nativeRef: _nativeRef, ...configuration } = record5;
48227
49136
  void _nativeRef;
48228
49137
  return harnessConfigurationStateSchema.safeParse(configuration).success;
48229
49138
  });
@@ -48317,7 +49226,7 @@ function defaultHarnessBrokerSocketPath(environment = process.env, harnessId = "
48317
49226
  }
48318
49227
 
48319
49228
  // packages/harness-broker/dist/server.js
48320
- import { randomBytes as randomBytes5, randomUUID as randomUUID24 } from "node:crypto";
49229
+ import { randomBytes as randomBytes5, randomUUID as randomUUID25 } from "node:crypto";
48321
49230
  import { chmod as chmod6, lstat as lstat10, mkdir as mkdir19, open as open11, readFile as readFile19, rename as rename16, rm as rm18 } from "node:fs/promises";
48322
49231
  import net4, {} from "node:net";
48323
49232
  import path41 from "node:path";
@@ -48376,7 +49285,7 @@ async function assertNoLiveDescriptor(descriptorPath) {
48376
49285
  }
48377
49286
  }
48378
49287
  async function publishDescriptor(descriptorPath, descriptor) {
48379
- const temporary = `${descriptorPath}.${process.pid}.${randomUUID24()}.tmp`;
49288
+ const temporary = `${descriptorPath}.${process.pid}.${randomUUID25()}.tmp`;
48380
49289
  const handle = await open11(temporary, "wx", 384);
48381
49290
  try {
48382
49291
  await handle.writeFile(`${JSON.stringify(descriptor)}
@@ -48389,28 +49298,28 @@ async function publishDescriptor(descriptorPath, descriptor) {
48389
49298
  if (process.platform !== "win32")
48390
49299
  await chmod6(descriptorPath, 384);
48391
49300
  }
48392
- function sessionMetadata(record4) {
48393
- const initialState = { ...record4.session.initialState };
48394
- if (record4.selection.model && initialState.effectiveModel?.id !== record4.selection.model.id) {
49301
+ function sessionMetadata(record5) {
49302
+ const initialState = { ...record5.session.initialState };
49303
+ if (record5.selection.model && initialState.effectiveModel?.id !== record5.selection.model.id) {
48395
49304
  delete initialState.resolvedModelLabel;
48396
49305
  }
48397
- if (record4.selection.thinkingOptionId && initialState.effectiveThinkingOptionId !== record4.selection.thinkingOptionId) {
49306
+ if (record5.selection.thinkingOptionId && initialState.effectiveThinkingOptionId !== record5.selection.thinkingOptionId) {
48398
49307
  delete initialState.availableThinkingOptions;
48399
49308
  }
48400
49309
  return {
48401
- sessionId: record4.id,
48402
- sessionGeneration: record4.generation,
48403
- capabilities: record4.session.capabilities,
49310
+ sessionId: record5.id,
49311
+ sessionGeneration: record5.generation,
49312
+ capabilities: record5.session.capabilities,
48404
49313
  readCapabilities: true,
48405
49314
  initialState: {
48406
49315
  ...initialState,
48407
- ...record4.nativeRef ? { nativeRef: record4.nativeRef } : {},
48408
- ...record4.selection.model ? { effectiveModel: record4.selection.model } : {},
48409
- ...record4.selection.thinkingOptionId ? { effectiveThinkingOptionId: record4.selection.thinkingOptionId } : {},
48410
- ...record4.selection.permissionModeId ? { effectivePermissionModeId: record4.selection.permissionModeId } : {}
49316
+ ...record5.nativeRef ? { nativeRef: record5.nativeRef } : {},
49317
+ ...record5.selection.model ? { effectiveModel: record5.selection.model } : {},
49318
+ ...record5.selection.thinkingOptionId ? { effectiveThinkingOptionId: record5.selection.thinkingOptionId } : {},
49319
+ ...record5.selection.permissionModeId ? { effectivePermissionModeId: record5.selection.permissionModeId } : {}
48411
49320
  },
48412
- initialUsage: record4.session.initialUsage,
48413
- commands: record4.session.commands !== void 0
49321
+ initialUsage: record5.session.initialUsage,
49322
+ commands: record5.session.commands !== void 0
48414
49323
  };
48415
49324
  }
48416
49325
  async function socketAcceptsConnections(socketPath) {
@@ -48454,7 +49363,7 @@ async function startHarnessBrokerServer(input) {
48454
49363
  await assertNoLiveDescriptor(input.descriptorPath);
48455
49364
  if (process.platform !== "win32")
48456
49365
  await prepareUnixSocketPath(input.socketPath);
48457
- const generation = input.generation ?? randomUUID24();
49366
+ const generation = input.generation ?? randomUUID25();
48458
49367
  const token = input.token ?? randomBytes5(32).toString("hex");
48459
49368
  const descriptor = {
48460
49369
  schemaVersion: 1,
@@ -48495,7 +49404,7 @@ async function startHarnessBrokerServer(input) {
48495
49404
  };
48496
49405
  const server = net4.createServer((socket) => {
48497
49406
  const state = {
48498
- id: randomUUID24(),
49407
+ id: randomUUID25(),
48499
49408
  socket,
48500
49409
  authenticated: false,
48501
49410
  inputSequence: 0,
@@ -48522,15 +49431,15 @@ async function startHarnessBrokerServer(input) {
48522
49431
  const respond2 = async (request, result) => {
48523
49432
  await send({ kind: "response", id: request.id, ...result });
48524
49433
  };
48525
- const releaseProvisionalWriter = (record4) => {
48526
- if (record4.provisionalWriterLease && provisionalNativeWriter === record4.id) {
49434
+ const releaseProvisionalWriter = (record5) => {
49435
+ if (record5.provisionalWriterLease && provisionalNativeWriter === record5.id) {
48527
49436
  provisionalNativeWriter = void 0;
48528
49437
  }
48529
- record4.provisionalWriterLease = false;
48530
- record4.awaitingNativeIdentity = false;
49438
+ record5.provisionalWriterLease = false;
49439
+ record5.awaitingNativeIdentity = false;
48531
49440
  };
48532
- const forwardOutputs = async (record4, nativeSession, sessionGeneration, forwarderEpoch) => {
48533
- const isCurrent = () => sessions.get(record4.id) === record4 && record4.session === nativeSession && record4.generation === sessionGeneration && record4.forwarderEpoch === forwarderEpoch;
49441
+ const forwardOutputs = async (record5, nativeSession, sessionGeneration, forwarderEpoch) => {
49442
+ const isCurrent = () => sessions.get(record5.id) === record5 && record5.session === nativeSession && record5.generation === sessionGeneration && record5.forwarderEpoch === forwarderEpoch;
48534
49443
  try {
48535
49444
  for await (const output of nativeSession.outputs) {
48536
49445
  if (!isCurrent())
@@ -48538,13 +49447,13 @@ async function startHarnessBrokerServer(input) {
48538
49447
  if (output.kind === "event" && output.event.type === "session.state.changed") {
48539
49448
  const state2 = output.event.state;
48540
49449
  const observedNativeId = state2.nativeRef?.nativeSessionId;
48541
- const expectedRef = record4.nativeWriterRef ?? record4.nativeRef;
49450
+ const expectedRef = record5.nativeWriterRef ?? record5.nativeRef;
48542
49451
  if (state2.nativeRef && (state2.nativeRef.harnessId !== input.adapter.harnessId || expectedRef && (expectedRef.harnessId !== state2.nativeRef.harnessId || expectedRef.nativeSessionId !== state2.nativeRef.nativeSessionId || expectedRef.formatVersion !== state2.nativeRef.formatVersion))) {
48543
- record4.faulted = true;
48544
- releaseProvisionalWriter(record4);
49452
+ record5.faulted = true;
49453
+ releaseProvisionalWriter(record5);
48545
49454
  await send({
48546
49455
  kind: "output",
48547
- sessionId: record4.id,
49456
+ sessionId: record5.id,
48548
49457
  sessionGeneration,
48549
49458
  output: {
48550
49459
  kind: "event",
@@ -48562,15 +49471,15 @@ async function startHarnessBrokerServer(input) {
48562
49471
  await nativeSession.close().catch(() => void 0);
48563
49472
  break;
48564
49473
  }
48565
- if (observedNativeId && !record4.writerKey) {
49474
+ if (observedNativeId && !record5.writerKey) {
48566
49475
  const writerKey = nativeWriterKey(observedNativeId);
48567
49476
  const owner = nativeWriters.get(writerKey);
48568
- if (owner && owner !== record4.id) {
48569
- record4.faulted = true;
48570
- releaseProvisionalWriter(record4);
49477
+ if (owner && owner !== record5.id) {
49478
+ record5.faulted = true;
49479
+ releaseProvisionalWriter(record5);
48571
49480
  await send({
48572
49481
  kind: "output",
48573
- sessionId: record4.id,
49482
+ sessionId: record5.id,
48574
49483
  sessionGeneration,
48575
49484
  output: {
48576
49485
  kind: "event",
@@ -48588,38 +49497,38 @@ async function startHarnessBrokerServer(input) {
48588
49497
  await nativeSession.close().catch(() => void 0);
48589
49498
  break;
48590
49499
  }
48591
- nativeWriters.set(writerKey, record4.id);
48592
- record4.nativeId = observedNativeId;
48593
- record4.nativeRef = state2.nativeRef;
48594
- record4.writerKey = writerKey;
48595
- releaseProvisionalWriter(record4);
49500
+ nativeWriters.set(writerKey, record5.id);
49501
+ record5.nativeId = observedNativeId;
49502
+ record5.nativeRef = state2.nativeRef;
49503
+ record5.writerKey = writerKey;
49504
+ releaseProvisionalWriter(record5);
48596
49505
  }
48597
49506
  if (state2.nativeRef) {
48598
- record4.nativeId = state2.nativeRef.nativeSessionId;
48599
- record4.nativeRef = state2.nativeRef;
48600
- releaseProvisionalWriter(record4);
49507
+ record5.nativeId = state2.nativeRef.nativeSessionId;
49508
+ record5.nativeRef = state2.nativeRef;
49509
+ releaseProvisionalWriter(record5);
48601
49510
  }
48602
49511
  if (state2.effectiveModel)
48603
- record4.selection.model = state2.effectiveModel;
49512
+ record5.selection.model = state2.effectiveModel;
48604
49513
  if (state2.effectiveThinkingOptionId) {
48605
- record4.selection.thinkingOptionId = state2.effectiveThinkingOptionId;
49514
+ record5.selection.thinkingOptionId = state2.effectiveThinkingOptionId;
48606
49515
  }
48607
49516
  if (state2.effectivePermissionModeId) {
48608
- record4.selection.permissionModeId = state2.effectivePermissionModeId;
49517
+ record5.selection.permissionModeId = state2.effectivePermissionModeId;
48609
49518
  }
48610
49519
  }
48611
49520
  const authenticationTerminal = isAuthenticationTerminal(output);
48612
49521
  if (output.kind === "event" && output.event.type === "session.faulted") {
48613
- record4.faulted = true;
48614
- releaseProvisionalWriter(record4);
49522
+ record5.faulted = true;
49523
+ releaseProvisionalWriter(record5);
48615
49524
  }
48616
49525
  if (authenticationTerminal) {
48617
- record4.faulted = true;
48618
- releaseProvisionalWriter(record4);
49526
+ record5.faulted = true;
49527
+ releaseProvisionalWriter(record5);
48619
49528
  }
48620
49529
  await send({
48621
49530
  kind: "output",
48622
- sessionId: record4.id,
49531
+ sessionId: record5.id,
48623
49532
  sessionGeneration,
48624
49533
  output
48625
49534
  });
@@ -48630,26 +49539,26 @@ async function startHarnessBrokerServer(input) {
48630
49539
  }
48631
49540
  } catch {
48632
49541
  if (isCurrent()) {
48633
- record4.faulted = true;
48634
- releaseProvisionalWriter(record4);
49542
+ record5.faulted = true;
49543
+ releaseProvisionalWriter(record5);
48635
49544
  }
48636
49545
  }
48637
49546
  };
48638
- const closeRecord = async (record4) => {
48639
- if (sessions.get(record4.id) !== record4)
49547
+ const closeRecord = async (record5) => {
49548
+ if (sessions.get(record5.id) !== record5)
48640
49549
  return;
48641
- sessions.delete(record4.id);
49550
+ sessions.delete(record5.id);
48642
49551
  scheduleIdle();
48643
- state.sessions.delete(record4.id);
48644
- record4.forwarderEpoch += 1;
48645
- const nativeSession = record4.session;
48646
- const outputTask = record4.outputTask;
49552
+ state.sessions.delete(record5.id);
49553
+ record5.forwarderEpoch += 1;
49554
+ const nativeSession = record5.session;
49555
+ const outputTask = record5.outputTask;
48647
49556
  await nativeSession.close().catch(() => void 0);
48648
49557
  await outputTask.catch(() => void 0);
48649
- if (record4.writerKey && nativeWriters.get(record4.writerKey) === record4.id) {
48650
- nativeWriters.delete(record4.writerKey);
49558
+ if (record5.writerKey && nativeWriters.get(record5.writerKey) === record5.id) {
49559
+ nativeWriters.delete(record5.writerKey);
48651
49560
  }
48652
- releaseProvisionalWriter(record4);
49561
+ releaseProvisionalWriter(record5);
48653
49562
  };
48654
49563
  const requireSession = (params) => {
48655
49564
  const candidate = params;
@@ -48657,13 +49566,13 @@ async function startHarnessBrokerServer(input) {
48657
49566
  sessionId: candidate.sessionId,
48658
49567
  sessionGeneration: candidate.sessionGeneration
48659
49568
  });
48660
- const record4 = sessions.get(parsed2.sessionId);
48661
- if (!record4 || record4.owner !== state.id)
49569
+ const record5 = sessions.get(parsed2.sessionId);
49570
+ if (!record5 || record5.owner !== state.id)
48662
49571
  throw new Error("Harness broker Session is unavailable");
48663
- if (record4.generation !== parsed2.sessionGeneration) {
49572
+ if (record5.generation !== parsed2.sessionGeneration) {
48664
49573
  throw new Error("Harness broker Session generation is stale");
48665
49574
  }
48666
- return record4;
49575
+ return record5;
48667
49576
  };
48668
49577
  const handleRequest = async (request) => {
48669
49578
  if (closed || state.closed)
@@ -48796,7 +49705,7 @@ async function startHarnessBrokerServer(input) {
48796
49705
  }
48797
49706
  };
48798
49707
  }
48799
- const openReservation = randomUUID24();
49708
+ const openReservation = randomUUID25();
48800
49709
  if (sourceKey)
48801
49710
  nativeWriters.set(sourceKey, openReservation);
48802
49711
  const provisionalReservation = openInput.kind === "create" ? openReservation : void 0;
@@ -48876,7 +49785,7 @@ async function startHarnessBrokerServer(input) {
48876
49785
  };
48877
49786
  }
48878
49787
  const delayedCreateIdentity = openInput.kind === "create" && !nativeKey;
48879
- const record5 = {
49788
+ const record6 = {
48880
49789
  id: openReservation,
48881
49790
  generation: 1,
48882
49791
  owner: state.id,
@@ -48897,18 +49806,18 @@ async function startHarnessBrokerServer(input) {
48897
49806
  ...opened.value.initialState.effectivePermissionModeId ? { permissionModeId: opened.value.initialState.effectivePermissionModeId } : {}
48898
49807
  }
48899
49808
  };
48900
- sessions.set(record5.id, record5);
48901
- state.sessions.add(record5.id);
49809
+ sessions.set(record6.id, record6);
49810
+ state.sessions.add(record6.id);
48902
49811
  if (nativeKey)
48903
- nativeWriters.set(nativeKey, record5.id);
48904
- if (sourceKey && sourceKey !== nativeKey && nativeWriters.get(sourceKey) === record5.id) {
49812
+ nativeWriters.set(nativeKey, record6.id);
49813
+ if (sourceKey && sourceKey !== nativeKey && nativeWriters.get(sourceKey) === record6.id) {
48905
49814
  nativeWriters.delete(sourceKey);
48906
49815
  }
48907
- if (!record5.provisionalWriterLease && provisionalNativeWriter === provisionalReservation) {
49816
+ if (!record6.provisionalWriterLease && provisionalNativeWriter === provisionalReservation) {
48908
49817
  provisionalNativeWriter = void 0;
48909
49818
  }
48910
- record5.outputTask = forwardOutputs(record5, opened.value, record5.generation, record5.forwarderEpoch);
48911
- return { ok: true, value: sessionMetadata(record5) };
49819
+ record6.outputTask = forwardOutputs(record6, opened.value, record6.generation, record6.forwarderEpoch);
49820
+ return { ok: true, value: sessionMetadata(record6) };
48912
49821
  } finally {
48913
49822
  if (createSettled) {
48914
49823
  openingCreate = void 0;
@@ -48918,11 +49827,11 @@ async function startHarnessBrokerServer(input) {
48918
49827
  }
48919
49828
  if (request.method === "session.execute") {
48920
49829
  const parsed2 = sessionExecuteParamsSchema.parse(request.params);
48921
- const record5 = requireSession(parsed2);
49830
+ const record6 = requireSession(parsed2);
48922
49831
  const command = brokerHostCommandSchema.parse(parsed2.command);
48923
- if (record5.awaitingNativeIdentity && !record5.writerKey) {
48924
- const isBootstrapTurn = command.type === "turn.start" && record5.provisionalWriterLease && record5.bootstrapTurnId === void 0;
48925
- const isBootstrapTurnContinuation = record5.bootstrapTurnId !== void 0 && (command.type === "turn.cancel" && command.turnId === record5.bootstrapTurnId || command.type === "interaction.respond");
49832
+ if (record6.awaitingNativeIdentity && !record6.writerKey) {
49833
+ const isBootstrapTurn = command.type === "turn.start" && record6.provisionalWriterLease && record6.bootstrapTurnId === void 0;
49834
+ const isBootstrapTurnContinuation = record6.bootstrapTurnId !== void 0 && (command.type === "turn.cancel" && command.turnId === record6.bootstrapTurnId || command.type === "interaction.respond");
48926
49835
  if (!isBootstrapTurn && !isBootstrapTurnContinuation) {
48927
49836
  return {
48928
49837
  ok: false,
@@ -48935,17 +49844,17 @@ async function startHarnessBrokerServer(input) {
48935
49844
  };
48936
49845
  }
48937
49846
  if (command.type === "turn.start")
48938
- record5.bootstrapTurnId = command.turnId;
49847
+ record6.bootstrapTurnId = command.turnId;
48939
49848
  }
48940
49849
  let result;
48941
49850
  if (command.type === "turn.start")
48942
- result = await record5.session.execute(command);
49851
+ result = await record6.session.execute(command);
48943
49852
  else if (command.type === "turn.steer")
48944
- result = await record5.session.execute(command);
49853
+ result = await record6.session.execute(command);
48945
49854
  else if (command.type === "turn.cancel")
48946
- result = await record5.session.execute(command);
49855
+ result = await record6.session.execute(command);
48947
49856
  else if (command.type === "interaction.respond") {
48948
- result = await record5.session.execute({
49857
+ result = await record6.session.execute({
48949
49858
  type: command.type,
48950
49859
  interactionId: command.interactionId,
48951
49860
  response: command.response.type === "question" ? {
@@ -48955,21 +49864,21 @@ async function startHarnessBrokerServer(input) {
48955
49864
  } : command.response
48956
49865
  });
48957
49866
  } else if (command.type === "model.select")
48958
- result = await record5.session.execute(command);
49867
+ result = await record6.session.execute(command);
48959
49868
  else if (command.type === "thinking.select")
48960
- result = await record5.session.execute(command);
49869
+ result = await record6.session.execute(command);
48961
49870
  else
48962
- result = await record5.session.execute(command);
48963
- if (!result.ok && command.type === "turn.start" && record5.awaitingNativeIdentity && record5.bootstrapTurnId === command.turnId) {
48964
- delete record5.bootstrapTurnId;
49871
+ result = await record6.session.execute(command);
49872
+ if (!result.ok && command.type === "turn.start" && record6.awaitingNativeIdentity && record6.bootstrapTurnId === command.turnId) {
49873
+ delete record6.bootstrapTurnId;
48965
49874
  }
48966
49875
  if (result.ok) {
48967
49876
  if (command.type === "model.select")
48968
- record5.selection.model = command.model;
49877
+ record6.selection.model = command.model;
48969
49878
  if (command.type === "thinking.select")
48970
- record5.selection.thinkingOptionId = command.thinkingOptionId;
49879
+ record6.selection.thinkingOptionId = command.thinkingOptionId;
48971
49880
  if (command.type === "permissionMode.select")
48972
- record5.selection.permissionModeId = command.permissionModeId;
49881
+ record6.selection.permissionModeId = command.permissionModeId;
48973
49882
  }
48974
49883
  return result;
48975
49884
  }
@@ -48981,10 +49890,10 @@ async function startHarnessBrokerServer(input) {
48981
49890
  return requireSession(request.params).session.readSnapshot();
48982
49891
  }
48983
49892
  if (request.method === "session.refreshUsage") {
48984
- const record5 = requireSession(request.params);
48985
- const refreshUsage = record5.session.refreshUsage;
49893
+ const record6 = requireSession(request.params);
49894
+ const refreshUsage = record6.session.refreshUsage;
48986
49895
  if (refreshUsage)
48987
- await refreshUsage.call(record5.session);
49896
+ await refreshUsage.call(record6.session);
48988
49897
  return null;
48989
49898
  }
48990
49899
  if (request.method === "session.commands.list") {
@@ -49002,11 +49911,11 @@ async function startHarnessBrokerServer(input) {
49002
49911
  }) : { ok: false, error: harnessError("Commands unavailable", false) };
49003
49912
  }
49004
49913
  if (request.method === "session.reopen") {
49005
- const record5 = requireSession(request.params);
49006
- if (!record5.faulted) {
49007
- return { ok: true, value: sessionMetadata(record5) };
49914
+ const record6 = requireSession(request.params);
49915
+ if (!record6.faulted) {
49916
+ return { ok: true, value: sessionMetadata(record6) };
49008
49917
  }
49009
- if (!record5.nativeRef) {
49918
+ if (!record6.nativeRef) {
49010
49919
  return {
49011
49920
  ok: false,
49012
49921
  error: {
@@ -49017,17 +49926,17 @@ async function startHarnessBrokerServer(input) {
49017
49926
  }
49018
49927
  };
49019
49928
  }
49020
- const nativeRef = record5.nativeRef;
49021
- const oldSession = record5.session;
49022
- const oldOutputTask = record5.outputTask;
49023
- record5.forwarderEpoch += 1;
49929
+ const nativeRef = record6.nativeRef;
49930
+ const oldSession = record6.session;
49931
+ const oldOutputTask = record6.outputTask;
49932
+ record6.forwarderEpoch += 1;
49024
49933
  await oldSession.close().catch(() => void 0);
49025
49934
  await oldOutputTask.catch(() => void 0);
49026
49935
  const reopened = await input.adapter.open({
49027
49936
  kind: "resume",
49028
- cwd: record5.cwd,
49937
+ cwd: record6.cwd,
49029
49938
  nativeRef,
49030
- ...record5.environment ? { environment: record5.environment } : {}
49939
+ ...record6.environment ? { environment: record6.environment } : {}
49031
49940
  });
49032
49941
  if (!reopened.ok)
49033
49942
  return reopened;
@@ -49044,44 +49953,44 @@ async function startHarnessBrokerServer(input) {
49044
49953
  }
49045
49954
  };
49046
49955
  }
49047
- if (record5.selection.model && reopened.value.capabilities.configuration.selectModel) {
49956
+ if (record6.selection.model && reopened.value.capabilities.configuration.selectModel) {
49048
49957
  const selected = await reopened.value.execute({
49049
49958
  type: "model.select",
49050
- model: record5.selection.model
49959
+ model: record6.selection.model
49051
49960
  });
49052
49961
  if (!selected.ok) {
49053
49962
  await reopened.value.close().catch(() => void 0);
49054
49963
  return selected;
49055
49964
  }
49056
49965
  }
49057
- if (record5.selection.thinkingOptionId && reopened.value.capabilities.configuration.selectThinkingOption) {
49966
+ if (record6.selection.thinkingOptionId && reopened.value.capabilities.configuration.selectThinkingOption) {
49058
49967
  const selected = await reopened.value.execute({
49059
49968
  type: "thinking.select",
49060
- thinkingOptionId: record5.selection.thinkingOptionId
49969
+ thinkingOptionId: record6.selection.thinkingOptionId
49061
49970
  });
49062
49971
  if (!selected.ok) {
49063
49972
  await reopened.value.close().catch(() => void 0);
49064
49973
  return selected;
49065
49974
  }
49066
49975
  }
49067
- if (record5.selection.permissionModeId && reopened.value.capabilities.configuration.selectPermissionMode) {
49976
+ if (record6.selection.permissionModeId && reopened.value.capabilities.configuration.selectPermissionMode) {
49068
49977
  const selected = await reopened.value.execute({
49069
49978
  type: "permissionMode.select",
49070
- permissionModeId: record5.selection.permissionModeId
49979
+ permissionModeId: record6.selection.permissionModeId
49071
49980
  });
49072
49981
  if (!selected.ok) {
49073
49982
  await reopened.value.close().catch(() => void 0);
49074
49983
  return selected;
49075
49984
  }
49076
49985
  }
49077
- record5.session = reopened.value;
49078
- record5.generation += 1;
49079
- record5.faulted = false;
49080
- record5.outputTask = forwardOutputs(record5, reopened.value, record5.generation, record5.forwarderEpoch);
49081
- return { ok: true, value: sessionMetadata(record5) };
49986
+ record6.session = reopened.value;
49987
+ record6.generation += 1;
49988
+ record6.faulted = false;
49989
+ record6.outputTask = forwardOutputs(record6, reopened.value, record6.generation, record6.forwarderEpoch);
49990
+ return { ok: true, value: sessionMetadata(record6) };
49082
49991
  }
49083
- const record4 = requireSession(request.params);
49084
- await closeRecord(record4);
49992
+ const record5 = requireSession(request.params);
49993
+ await closeRecord(record5);
49085
49994
  return null;
49086
49995
  };
49087
49996
  consumeBrokerFrames(socket, (raw) => {
@@ -49103,7 +50012,7 @@ async function startHarnessBrokerServer(input) {
49103
50012
  }
49104
50013
  state.authenticated = true;
49105
50014
  state.inputSequence = 1;
49106
- await send({ kind: "response", id: randomUUID24(), ok: true, value: { ready: true } });
50015
+ await send({ kind: "response", id: randomUUID25(), ok: true, value: { ready: true } });
49107
50016
  return;
49108
50017
  }
49109
50018
  const parsed2 = harnessBrokerRequestSchema.safeParse(raw);
@@ -49143,9 +50052,9 @@ async function startHarnessBrokerServer(input) {
49143
50052
  state.closed = true;
49144
50053
  connections.delete(state);
49145
50054
  for (const sessionId of [...state.sessions]) {
49146
- const record4 = sessions.get(sessionId);
49147
- if (record4)
49148
- void closeRecord(record4);
50055
+ const record5 = sessions.get(sessionId);
50056
+ if (record5)
50057
+ void closeRecord(record5);
49149
50058
  }
49150
50059
  scheduleIdle();
49151
50060
  });
@@ -49177,10 +50086,10 @@ async function startHarnessBrokerServer(input) {
49177
50086
  clearTimeout(idleTimer);
49178
50087
  for (const connection of connections)
49179
50088
  connection.socket.destroy();
49180
- for (const record4 of sessions.values())
49181
- record4.forwarderEpoch += 1;
49182
- await Promise.all([...sessions.values()].map((record4) => record4.session.close().catch(() => void 0)));
49183
- await Promise.all([...sessions.values()].map((record4) => record4.outputTask.catch(() => void 0)));
50089
+ for (const record5 of sessions.values())
50090
+ record5.forwarderEpoch += 1;
50091
+ await Promise.all([...sessions.values()].map((record5) => record5.session.close().catch(() => void 0)));
50092
+ await Promise.all([...sessions.values()].map((record5) => record5.outputTask.catch(() => void 0)));
49184
50093
  await input.adapter.close().catch(() => void 0);
49185
50094
  await new Promise((resolve) => server.close(() => resolve()));
49186
50095
  if (process.platform !== "win32")