@codexhost/cli-darwin-x64 0.15.0 → 0.16.0

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. */
@@ -22494,8 +22497,110 @@ function retainRendererHostResponses(client, hostId2, target) {
22494
22497
  };
22495
22498
  }
22496
22499
 
22500
+ // packages/desktop-control/dist/renderer-prewarm-consumption.js
22501
+ function isolateRendererPrewarmConsumption(manager, discardExternal) {
22502
+ const record4 = (value2) => value2 !== null && typeof value2 === "object";
22503
+ if (!record4(manager) || !record4(manager.threadCreation))
22504
+ return null;
22505
+ const creation = manager.threadCreation;
22506
+ const originalStart = manager.startConversation;
22507
+ const original = creation.createConversation;
22508
+ const params = creation.params;
22509
+ if (typeof originalStart !== "function" || typeof original !== "function" || !record4(params))
22510
+ return null;
22511
+ const prototype = Object.getPrototypeOf(creation);
22512
+ if (!record4(prototype) || typeof prototype.constructor !== "function")
22513
+ return null;
22514
+ if (Object.keys(creation).some((key) => key !== "params" && typeof creation[key] !== "function") || /#[A-Za-z_$]/u.test(Function.prototype.toString.call(prototype.constructor)))
22515
+ return null;
22516
+ const pool = params.prewarmedThreadManager;
22517
+ if (!record4(pool) || typeof pool.hasPrewarmedThread !== "function" || typeof pool.consumePrewarmedThread !== "function" || typeof pool.deletePrewarmedThread !== "function")
22518
+ return null;
22519
+ const consume = pool.consumePrewarmedThread;
22520
+ const hasPrewarm = pool.hasPrewarmedThread;
22521
+ const draftModels = /* @__PURE__ */ new Map();
22522
+ const draftIdentity = /* @__PURE__ */ Symbol("codexhost draft creation");
22523
+ const external = (model2) => typeof model2 === "string" && model2.startsWith("codexhost/");
22524
+ const routedStart = function(input, options2, ...args) {
22525
+ const draftId = record4(options2) ? options2.clientThreadId : null;
22526
+ const mode = record4(input) && record4(input.collaborationMode) ? input.collaborationMode : null;
22527
+ const origin = mode ? Reflect.get(mode, draftIdentity) : void 0;
22528
+ if (mode && record4(mode.settings) && external(mode.settings.model))
22529
+ return originalStart.call(this, input, options2, ...args);
22530
+ const model2 = (typeof draftId === "string" ? draftModels.get(draftId) : void 0) ?? (typeof origin === "string" ? draftModels.get(origin) : void 0);
22531
+ if (!model2)
22532
+ return originalStart.call(this, input, options2, ...args);
22533
+ if (!record4(input) || !record4(input.collaborationMode) || !record4(input.collaborationMode.settings))
22534
+ throw new Error("External draft creation is missing its native Model settings");
22535
+ const routed = {
22536
+ ...input,
22537
+ collaborationMode: {
22538
+ ...input.collaborationMode,
22539
+ settings: { ...input.collaborationMode.settings, model: model2 }
22540
+ }
22541
+ };
22542
+ return originalStart.call(this, routed, options2, ...args);
22543
+ };
22544
+ const wrapped = function(input, ...args) {
22545
+ const mode = record4(input) && record4(input.collaborationMode) ? input.collaborationMode : null;
22546
+ const expected = mode && record4(mode.settings) ? mode.settings.model : null;
22547
+ const scopedPool = Object.create(pool);
22548
+ scopedPool.hasPrewarmedThread = (...parameters) => hasPrewarm.apply(pool, parameters);
22549
+ scopedPool.consumePrewarmedThread = async (...consumeArgs) => {
22550
+ const warmed = await consume.apply(pool, consumeArgs);
22551
+ if (!record4(warmed) || !record4(warmed.response))
22552
+ return warmed;
22553
+ const response = warmed.response;
22554
+ if (!external(expected) && !external(response.model))
22555
+ return warmed;
22556
+ if (external(expected) && expected === response.model)
22557
+ return warmed;
22558
+ if (record4(response.thread) && typeof response.thread.id === "string") {
22559
+ const threadId2 = response.thread.id;
22560
+ if (external(response.model))
22561
+ discardExternal(threadId2);
22562
+ else
22563
+ void Promise.resolve().then(() => pool.deletePrewarmedThread(threadId2)).catch(() => void 0);
22564
+ }
22565
+ return null;
22566
+ };
22567
+ const invocation = Object.create(creation);
22568
+ invocation.params = { ...params, prewarmedThreadManager: scopedPool };
22569
+ return original.call(invocation, input, ...args);
22570
+ };
22571
+ creation.createConversation = wrapped;
22572
+ manager.startConversation = routedStart;
22573
+ return {
22574
+ selectDraft(draftId, model2, creationModes = []) {
22575
+ if (draftId === void 0) {
22576
+ if (model2 === null)
22577
+ draftModels.clear();
22578
+ } else if (model2 === null)
22579
+ draftModels.delete(draftId);
22580
+ else {
22581
+ if (!draftId.startsWith("client-new-thread:") || !external(model2))
22582
+ throw new Error("External draft route is missing its client Thread identity");
22583
+ draftModels.set(draftId, model2);
22584
+ for (const mode of creationModes)
22585
+ Object.defineProperty(mode, draftIdentity, {
22586
+ configurable: true,
22587
+ enumerable: true,
22588
+ value: draftId
22589
+ });
22590
+ }
22591
+ },
22592
+ dispose() {
22593
+ draftModels.clear();
22594
+ if (manager.startConversation === routedStart)
22595
+ manager.startConversation = originalStart;
22596
+ if (creation.createConversation === wrapped)
22597
+ creation.createConversation = original;
22598
+ }
22599
+ };
22600
+ }
22601
+
22497
22602
  // packages/desktop-control/dist/renderer-draft-prewarm-runtime.js
22498
- function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewarmedThreadManager, isCurrentManager, retainResponses = retainRendererHostResponses) {
22603
+ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewarmedThreadManager, isCurrentManager, retainResponses = retainRendererHostResponses, isolateConsumption = isolateRendererPrewarmConsumption) {
22499
22604
  let disposed = false;
22500
22605
  const originalSend = bridge.sendRequest;
22501
22606
  const originalPrewarm = bridge.prewarmThreadStart;
@@ -22885,25 +22990,15 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
22885
22990
  return false;
22886
22991
  return selectedModel !== null && (method.startsWith("thread/") || method.startsWith("turn/") || method.startsWith("review/"));
22887
22992
  };
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
22993
  const routedSend = (method, parameters, options2) => {
22898
22994
  if (method === "turn/start" || method === "thread/resume" || method === "codexhost/thread/command/execute") {
22899
22995
  const threadId2 = threadIdFromParameters(parameters);
22900
22996
  if (threadId2)
22901
22997
  externalPrewarms.delete(threadId2);
22902
22998
  }
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);
22999
+ const sendBridged = () => initializeBridge().then(() => enqueueBridgeRequest(method, parameters, options2));
23000
+ const sendDirect = () => options2 === void 0 ? originalSend.call(bridge, method, parameters) : originalSend.call(bridge, method, parameters, options2);
23001
+ const unresolvedThreadId = shouldResolveThreadOwnership(method, parameters);
22907
23002
  if (unresolvedThreadId) {
22908
23003
  return resolveThreadOwnership(unresolvedThreadId).then((owner) => owner === "external" ? sendBridged() : sendDirect(), (error51) => {
22909
23004
  if ((method === "thread/read" || method === "thread/resume") && isUnsupportedPosixBridgeSpawn(error51)) {
@@ -22916,7 +23011,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
22916
23011
  throw error51;
22917
23012
  });
22918
23013
  }
22919
- return shouldUseBridge(method, routedParameters) ? sendBridged() : sendDirect();
23014
+ return shouldUseBridge(method, parameters) ? sendBridged() : sendDirect();
22920
23015
  };
22921
23016
  const publishDraftWorkspace = (parameters) => {
22922
23017
  if (!isRecord19(parameters) || parameters.ephemeral === true)
@@ -22945,10 +23040,10 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
22945
23040
  for (const threadId2 of externalPrewarms)
22946
23041
  discardExternalPrewarm(threadId2);
22947
23042
  };
23043
+ const restoreConsumption = isolateConsumption(manager, discardExternalPrewarm);
22948
23044
  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;
23045
+ const external = isRecord19(parameters) && parameters.ephemeral !== true && typeof parameters.model === "string" && parameters.model.startsWith("codexhost/");
23046
+ const routedParameters = external ? { ...parameters, codexhostPrewarm: true } : parameters;
22952
23047
  const generation = prewarmGeneration;
22953
23048
  publishDraftWorkspace(routedParameters);
22954
23049
  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 +23099,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23004
23099
  const policy = Object.freeze({
23005
23100
  state: "ready",
23006
23101
  hostId: hostId2,
23102
+ scopedCreation: restoreConsumption !== null,
23007
23103
  owns(candidateManager, candidate, candidateHostId, candidatePrewarmedThreadManager, requiresCurrentManager) {
23008
23104
  return !disposed && candidateManager === manager && candidate === bridge && candidateHostId === hostId2 && candidatePrewarmedThreadManager === prewarmedThreadManager && requiresCurrentManager === !!isCurrentManager;
23009
23105
  },
@@ -23012,12 +23108,13 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23012
23108
  throw new Error("Renderer request manager is retired");
23013
23109
  return manager;
23014
23110
  },
23015
- select(model2) {
23111
+ select(model2, draftId, creationModes) {
23016
23112
  if (disposed || isCurrentManager && !isCurrentManager())
23017
23113
  throw new Error("Renderer request manager is retired");
23018
23114
  if (model2 !== null && (typeof model2 !== "string" || !model2.startsWith("codexhost/"))) {
23019
23115
  throw new Error("Draft route Model must be a codexhost transport carrier");
23020
23116
  }
23117
+ restoreConsumption?.selectDraft(draftId, model2, creationModes);
23021
23118
  if (selectedModel === model2)
23022
23119
  return false;
23023
23120
  selectedModel = model2;
@@ -23040,6 +23137,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23040
23137
  disposed = true;
23041
23138
  prewarmGeneration += 1;
23042
23139
  retireResponses();
23140
+ restoreConsumption?.dispose();
23043
23141
  if (bridge.sendRequest === routedSend)
23044
23142
  bridge.sendRequest = originalSend;
23045
23143
  if (bridge.prewarmThreadStart === routedPrewarm) {
@@ -23299,12 +23397,14 @@ function directRendererInstaller() {
23299
23397
  const resolveRendererHostManager = ${resolveRendererHostManager.toString()};
23300
23398
  const retainRendererHostResponses = ${retainRendererHostResponses.toString()};
23301
23399
  const createDraftPrewarmPolicyBridge = ${createDraftPrewarmPolicyBridge.toString()};
23400
+ const isolateRendererPrewarmConsumption = ${isolateRendererPrewarmConsumption.toString()};
23302
23401
  const routing = (${installRendererHostRouting.toString()})(
23303
23402
  document, window,
23304
23403
  (root) => discoverRendererHosts(root, committedReactAncestors, requestManagerFromHookState),
23305
23404
  (discovery, hostId) => resolveRendererHostManager(discovery, hostId, requestManagerFromHookState),
23306
23405
  (manager, bridge, hostId, target, prewarmed, isCurrent) => createDraftPrewarmPolicyBridge(
23307
23406
  manager, bridge, hostId, target, prewarmed, isCurrent, retainRendererHostResponses,
23407
+ isolateRendererPrewarmConsumption,
23308
23408
  ),
23309
23409
  );
23310
23410
  // Publish a default draft policy only when its Host is unambiguous. Host
@@ -26523,13 +26623,17 @@ var MappingStore = class {
26523
26623
  await this.#enqueue(() => this.#remove(hostThreadId));
26524
26624
  }
26525
26625
  async #remove(hostThreadId) {
26526
- if (!this.#records.has(hostThreadId))
26626
+ const current = this.#records.get(hostThreadId);
26627
+ if (!current)
26527
26628
  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
- ]);
26629
+ await rm10(this.#recordPath(hostThreadId), { force: true });
26630
+ try {
26631
+ await rm10(this.#backupPath(hostThreadId), { force: true });
26632
+ await rm10(this.#metadataPath(hostThreadId), { force: true });
26633
+ } catch (error51) {
26634
+ await this.#replaceFile(this.#recordPath(hostThreadId), current, false);
26635
+ throw error51;
26636
+ }
26533
26637
  this.#records.delete(hostThreadId);
26534
26638
  this.#rebuildIndexes();
26535
26639
  }
@@ -32693,6 +32797,19 @@ var ExternalThreadRuntime = class {
32693
32797
  this.#threads.delete(threadId2);
32694
32798
  this.#steeredTurnIds.delete(threadId2);
32695
32799
  }
32800
+ /** Confirm release before forgetting either the Session owner or its persisted mapping. */
32801
+ async deleteThread(hostThreadId) {
32802
+ await this.#withLifecycle(hostThreadId, async () => {
32803
+ const thread = this.#threads.get(hostThreadId);
32804
+ if (thread) {
32805
+ thread.sessionUnavailable = true;
32806
+ thread.stateObserver.fault(new Error("External Thread is being deleted"));
32807
+ await this.#lifecycle.release(hostThreadId, thread.session, thread.outputTask);
32808
+ }
32809
+ this.remove(hostThreadId);
32810
+ await this.#repository.removeThread(hostThreadId);
32811
+ });
32812
+ }
32696
32813
  clear() {
32697
32814
  this.#threads.clear();
32698
32815
  this.#steeredTurnIds.clear();
@@ -38638,16 +38755,7 @@ var AppServerHost = class {
38638
38755
  hasRunningDescendants: (threadId2) => this.#hasRunningSubagents(threadId2),
38639
38756
  idleRelease: {
38640
38757
  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
- },
38758
+ onClosed: (thread) => this.#resolveThreadInteractions(thread),
38651
38759
  canRelease: (thread) => !this.#hasRunningSubagents(thread.id) && !thread.session.hasBackgroundWork?.() && !this.#externalSteering.hasPending(thread.id) && !this.#pendingExternalCommandRequests.has(thread.id) && ![...this.#pendingDesktopApprovals.values()].some(
38652
38760
  (pending) => pending.thread === thread
38653
38761
  ) && ![...this.#pendingDesktopQuestions.values()].some((pending) => pending.thread === thread)
@@ -38837,12 +38945,12 @@ var AppServerHost = class {
38837
38945
  await this.#closeAdapters();
38838
38946
  await this.#externalRuntime.drain();
38839
38947
  for (const pending of [...this.#pendingDesktopApprovals.values()]) {
38840
- await this.#resolveDesktopApproval(pending.interaction.interactionId).catch(
38948
+ await this.#resolveDesktopApproval(pending.interaction.interactionId, pending.thread).catch(
38841
38949
  () => void 0
38842
38950
  );
38843
38951
  }
38844
38952
  for (const pending of [...this.#pendingDesktopQuestions.values()]) {
38845
- await this.#resolveDesktopQuestion(pending.interaction.interactionId).catch(
38953
+ await this.#resolveDesktopQuestion(pending.interaction.interactionId, pending.thread).catch(
38846
38954
  () => void 0
38847
38955
  );
38848
38956
  }
@@ -41688,29 +41796,23 @@ var AppServerHost = class {
41688
41796
  });
41689
41797
  }
41690
41798
  async #deleteExternalThread(request, location) {
41691
- const thread = location.thread;
41692
- 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
41799
  try {
41706
- await thread.session.close();
41707
- await thread.outputTask;
41708
- await this.#writer.json(rpcEnvelope(request, { result: {} }));
41800
+ await this.#externalRuntime.deleteThread(location.record.hostThreadId);
41709
41801
  } catch (error51) {
41802
+ if (!(error51 instanceof ExternalSessionReleaseError) && location.thread)
41803
+ await this.#resolveThreadInteractions(location.thread);
41710
41804
  await this.#writer.json(
41711
- rpcError(request, -32075, `External Thread could not close: ${errorMessage4(error51)}`)
41805
+ error51 instanceof ExternalSessionReleaseError ? rpcError(request, -32075, error51.message) : rpcError(request, -32081, "External Thread could not be removed")
41712
41806
  );
41807
+ return;
41713
41808
  }
41809
+ if (location.thread) await this.#resolveThreadInteractions(location.thread);
41810
+ this.#routeObservationTracker.forgetThread(location.record.hostThreadId);
41811
+ await this.#writer.json(rpcEnvelope(request, { result: {} }));
41812
+ await this.#writer.json({
41813
+ method: "thread/deleted",
41814
+ params: { threadId: location.record.hostThreadId }
41815
+ });
41714
41816
  }
41715
41817
  async #readExternalThreadMetadata(request, location) {
41716
41818
  try {
@@ -42341,7 +42443,7 @@ var AppServerHost = class {
42341
42443
  if (event.type === "session.faulted") {
42342
42444
  for (const pending of [...this.#pendingDesktopQuestions.values()]) {
42343
42445
  if (pending.shared && pending.thread === thread)
42344
- this.#retireDesktopQuestion(pending.interaction.interactionId);
42446
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42345
42447
  }
42346
42448
  this.#externalSteering.fault(thread.id, new Error(event.error.message));
42347
42449
  thread.stateObserver.fault(new Error(event.error.message));
@@ -42389,12 +42491,12 @@ var AppServerHost = class {
42389
42491
  if (event.type === "turn.completed") {
42390
42492
  for (const pending of [...this.#pendingDesktopQuestions.values()]) {
42391
42493
  if (pending.shared && pending.thread === thread && pending.interaction.turnId === event.turnId)
42392
- this.#retireDesktopQuestion(pending.interaction.interactionId);
42494
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42393
42495
  }
42394
42496
  }
42395
42497
  if (event.type === "interaction.closed") {
42396
- await this.#resolveDesktopApproval(event.interactionId);
42397
- await this.#resolveDesktopQuestion(event.interactionId);
42498
+ await this.#resolveDesktopApproval(event.interactionId, thread);
42499
+ await this.#resolveDesktopQuestion(event.interactionId, thread);
42398
42500
  }
42399
42501
  const ephemeralTurn = event.type === "turn.completed" && (event.ephemeral === true || thread.ephemeralTurnIds.has(event.turnId));
42400
42502
  if (event.type === "turn.completed" && !ephemeralTurn) {
@@ -42651,7 +42753,7 @@ var AppServerHost = class {
42651
42753
  if (this.#externalRuntime.get(pending.thread.id) !== pending.thread || this.#externalRuntime.idleRelease.failure(pending.thread))
42652
42754
  return true;
42653
42755
  if (this.#options.externalOnly)
42654
- await this.#resolveDesktopApproval(pending.interaction.interactionId);
42756
+ await this.#resolveDesktopApproval(pending.interaction.interactionId, pending.thread);
42655
42757
  else this.#pendingDesktopApprovals.delete(requestId);
42656
42758
  let response;
42657
42759
  try {
@@ -42702,9 +42804,20 @@ var AppServerHost = class {
42702
42804
  }
42703
42805
  return denied.ok;
42704
42806
  }
42705
- async #resolveDesktopApproval(interactionId) {
42807
+ async #resolveThreadInteractions(thread) {
42808
+ for (const pending of [...this.#pendingDesktopApprovals.values()]) {
42809
+ if (pending.thread === thread)
42810
+ await this.#resolveDesktopApproval(pending.interaction.interactionId, thread);
42811
+ }
42812
+ for (const pending of [...this.#pendingDesktopQuestions.values()]) {
42813
+ if (pending.thread === thread)
42814
+ await this.#resolveDesktopQuestion(pending.interaction.interactionId, thread);
42815
+ }
42816
+ }
42817
+ async #resolveDesktopApproval(interactionId, thread) {
42706
42818
  for (const [requestId, pending] of this.#pendingDesktopApprovals) {
42707
- if (pending.interaction.interactionId !== interactionId) continue;
42819
+ if (pending.thread !== thread || pending.interaction.interactionId !== interactionId)
42820
+ continue;
42708
42821
  this.#pendingDesktopApprovals.delete(requestId);
42709
42822
  await this.#writer.json({
42710
42823
  method: "serverRequest/resolved",
@@ -42763,16 +42876,16 @@ var AppServerHost = class {
42763
42876
  response
42764
42877
  });
42765
42878
  } catch (error51) {
42766
- this.#retireDesktopQuestion(pending.interaction.interactionId);
42879
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42767
42880
  throw error51;
42768
42881
  }
42769
42882
  if (!result.ok) {
42770
42883
  pending.responding = false;
42771
42884
  if (result.error.code === "invalidState")
42772
- this.#retireDesktopQuestion(pending.interaction.interactionId);
42885
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42773
42886
  throw new Error(result.error.message);
42774
42887
  }
42775
- this.#retireDesktopQuestion(pending.interaction.interactionId);
42888
+ this.#retireDesktopQuestion(pending.interaction.interactionId, thread);
42776
42889
  await this.#writer.json(rpcEnvelope(request, { result: { accepted: true } }));
42777
42890
  });
42778
42891
  } catch (error51) {
@@ -42826,7 +42939,7 @@ var AppServerHost = class {
42826
42939
  try {
42827
42940
  await this.#writer.json({ id: requestId, ...result.questionRequest.request });
42828
42941
  } catch (error51) {
42829
- this.#retireDesktopQuestion(interaction.interactionId);
42942
+ this.#retireDesktopQuestion(interaction.interactionId, thread);
42830
42943
  await thread.session.execute({
42831
42944
  type: "interaction.respond",
42832
42945
  interactionId: interaction.interactionId,
@@ -42844,7 +42957,7 @@ var AppServerHost = class {
42844
42957
  if (this.#externalRuntime.get(pending.thread.id) !== pending.thread || this.#externalRuntime.idleRelease.failure(pending.thread))
42845
42958
  return true;
42846
42959
  if (this.#options.externalOnly)
42847
- await this.#resolveDesktopQuestion(pending.interaction.interactionId);
42960
+ await this.#resolveDesktopQuestion(pending.interaction.interactionId, pending.thread);
42848
42961
  else this.#pendingDesktopQuestions.delete(requestId);
42849
42962
  if (pending.timeout) clearTimeout(pending.timeout);
42850
42963
  let response;
@@ -42871,7 +42984,7 @@ var AppServerHost = class {
42871
42984
  await this.#externalRuntime.idleRelease.runOperation(pending.thread.id, async () => {
42872
42985
  if (this.#externalRuntime.get(pending.thread.id) !== pending.thread || this.#externalRuntime.idleRelease.failure(pending.thread))
42873
42986
  return;
42874
- await this.#resolveDesktopQuestion(pending.interaction.interactionId);
42987
+ await this.#resolveDesktopQuestion(pending.interaction.interactionId, pending.thread);
42875
42988
  if (pending.responding) return;
42876
42989
  const result = await pending.thread.session.execute({
42877
42990
  type: "interaction.respond",
@@ -42883,16 +42996,18 @@ var AppServerHost = class {
42883
42996
  }
42884
42997
  });
42885
42998
  }
42886
- #retireDesktopQuestion(interactionId) {
42999
+ #retireDesktopQuestion(interactionId, thread) {
42887
43000
  for (const [requestId, pending] of this.#pendingDesktopQuestions) {
42888
- if (pending.interaction.interactionId !== interactionId) continue;
43001
+ if (pending.thread !== thread || pending.interaction.interactionId !== interactionId)
43002
+ continue;
42889
43003
  if (pending.timeout) clearTimeout(pending.timeout);
42890
43004
  this.#pendingDesktopQuestions.delete(requestId);
42891
43005
  }
42892
43006
  }
42893
- async #resolveDesktopQuestion(interactionId) {
43007
+ async #resolveDesktopQuestion(interactionId, thread) {
42894
43008
  for (const [requestId, pending] of this.#pendingDesktopQuestions) {
42895
- if (pending.interaction.interactionId !== interactionId) continue;
43009
+ if (pending.thread !== thread || pending.interaction.interactionId !== interactionId)
43010
+ continue;
42896
43011
  if (pending.timeout) clearTimeout(pending.timeout);
42897
43012
  this.#pendingDesktopQuestions.delete(requestId);
42898
43013
  if (pending.shared) continue;
@@ -45903,7 +46018,7 @@ function createHostUpdateCoordinator(options2) {
45903
46018
  onPrepared
45904
46019
  });
45905
46020
  }
45906
- if (platform !== "darwin") await manager.start(prepared2);
46021
+ if (platform !== "darwin" && platform !== "win32") await manager.start(prepared2);
45907
46022
  } catch (error51) {
45908
46023
  await lock.release();
45909
46024
  rejectPrepared(error51);
@@ -46205,6 +46320,8 @@ function emptyTotals() {
46205
46320
  cachedInputTokens: 0,
46206
46321
  cacheWriteInputTokens: 0,
46207
46322
  cacheKnownInputTokens: 0,
46323
+ cacheHitCachedInputTokens: 0,
46324
+ cacheHitInputTokens: 0,
46208
46325
  outputTokens: 0,
46209
46326
  reasoningOutputTokens: 0,
46210
46327
  costUsd: 0,
@@ -46221,6 +46338,10 @@ function addEntry(totals2, entry, cost) {
46221
46338
  totals2.inputTokens += entry.inputTokens;
46222
46339
  totals2.outputTokens += entry.outputTokens;
46223
46340
  totals2.reasoningOutputTokens += entry.reasoningOutputTokens ?? 0;
46341
+ if (entry.cachedInputTokens !== void 0) {
46342
+ totals2.cacheHitCachedInputTokens += entry.cachedInputTokens;
46343
+ totals2.cacheHitInputTokens += entry.inputTokens;
46344
+ }
46224
46345
  if (entry.cachedInputTokens !== void 0 && entry.cacheWriteInputTokens !== void 0) {
46225
46346
  totals2.cachedInputTokens += entry.cachedInputTokens;
46226
46347
  totals2.cacheWriteInputTokens += entry.cacheWriteInputTokens;
@@ -15089,6 +15089,8 @@ var usageStatisticsTotalsSchema = external_exports.strictObject({
15089
15089
  cachedInputTokens: count,
15090
15090
  cacheWriteInputTokens: count,
15091
15091
  cacheKnownInputTokens: count,
15092
+ cacheHitCachedInputTokens: count,
15093
+ cacheHitInputTokens: count,
15092
15094
  outputTokens: count,
15093
15095
  reasoningOutputTokens: count,
15094
15096
  /** USD at the public price, summed over the priced requests only. */
@@ -14683,6 +14683,8 @@ var usageStatisticsTotalsSchema = external_exports.strictObject({
14683
14683
  cachedInputTokens: count,
14684
14684
  cacheWriteInputTokens: count,
14685
14685
  cacheKnownInputTokens: count,
14686
+ cacheHitCachedInputTokens: count,
14687
+ cacheHitInputTokens: count,
14686
14688
  outputTokens: count,
14687
14689
  reasoningOutputTokens: count,
14688
14690
  /** USD at the public price, summed over the priced requests only. */
@@ -57290,11 +57292,11 @@ var ClaudeSdkTransport = class {
57290
57292
  this.#slashCommands = parseClaudeSlashCommands(message.commands);
57291
57293
  }
57292
57294
  }
57293
- async getContextUsage() {
57295
+ async getContextUsage(detail = "full") {
57294
57296
  const activeQuery = this.#query;
57295
57297
  if (!this.#started || !activeQuery)
57296
57298
  return null;
57297
- return parseContextUsage(await activeQuery.getContextUsage());
57299
+ return parseContextUsage(await activeQuery.getContextUsage({ detail }));
57298
57300
  }
57299
57301
  getPermissionMode() {
57300
57302
  if (!this.#started || !this.#query)
@@ -59153,7 +59155,6 @@ var ClaudeHarnessSession = class {
59153
59155
  #lastAssistantResponseAtUnix;
59154
59156
  #accountCreditsSupported;
59155
59157
  #minimumContextUsedTokens = null;
59156
- #latestRequestModel = null;
59157
59158
  #calibratedInputTokens = 0;
59158
59159
  #calibratedOutputTokens = 0;
59159
59160
  #calibratedCostUsd = 0;
@@ -59660,15 +59661,16 @@ var ClaudeHarnessSession = class {
59660
59661
  };
59661
59662
  }
59662
59663
  }
59663
- refreshUsage() {
59664
+ async refreshUsage() {
59665
+ await this.#contextRefreshInFlight;
59664
59666
  if (this.#phase !== "open" || !this.#transport)
59665
- return Promise.resolve();
59667
+ return;
59666
59668
  const now = Date.now();
59667
59669
  if (now < this.#contextUsageFreshUntilMs || now < this.#contextUsageCooldownUntilMs) {
59668
- return Promise.resolve();
59670
+ return;
59669
59671
  }
59670
59672
  this.#requestContextUsage(this.#transport, this.#active?.command.turnId, CONTEXT_USAGE_RETRY_DELAYS_MS);
59671
- return this.#contextRefreshInFlight ?? Promise.resolve();
59673
+ await this.#contextRefreshInFlight;
59672
59674
  }
59673
59675
  blocksRollback(sessionId) {
59674
59676
  return this.#sessionId === sessionId && (this.#phase !== "open" || this.#active !== null || this.#acceptingTurn || this.#configurationTask !== null || this.#readingHistory);
@@ -60802,7 +60804,7 @@ var ClaudeHarnessSession = class {
60802
60804
  this.#finishFailed(active, transportFailure(result.kind));
60803
60805
  }
60804
60806
  }
60805
- #requestContextUsage(transport, turnId, retryDelaysMs) {
60807
+ #requestContextUsage(transport, turnId, retryDelaysMs, detail = "full") {
60806
60808
  if (this.#phase !== "open" || this.#transport !== transport)
60807
60809
  return;
60808
60810
  if (this.#contextRefreshInFlight)
@@ -60811,7 +60813,8 @@ var ClaudeHarnessSession = class {
60811
60813
  transport,
60812
60814
  ...turnId !== void 0 ? { turnId } : {},
60813
60815
  generation: this.#usageGeneration,
60814
- retryDelaysMs
60816
+ retryDelaysMs,
60817
+ detail
60815
60818
  };
60816
60819
  this.#contextRefreshInFlight = this.#drainContextUsage();
60817
60820
  }
@@ -60837,14 +60840,16 @@ var ClaudeHarnessSession = class {
60837
60840
  return;
60838
60841
  }
60839
60842
  try {
60840
- const context = await request.transport.getContextUsage();
60843
+ const context = await request.transport.getContextUsage(request.detail);
60841
60844
  if (this.#phase !== "open" || this.#transport !== request.transport || this.#usageGeneration !== request.generation || this.#contextRefreshPending !== null) {
60842
60845
  return;
60843
60846
  }
60844
60847
  if (context === null)
60845
60848
  continue;
60846
- this.#contextUsageFreshUntilMs = Date.now() + CONTEXT_USAGE_TTL_MS;
60847
- this.#contextUsageCooldownUntilMs = 0;
60849
+ if (request.detail === "full") {
60850
+ this.#contextUsageFreshUntilMs = Date.now() + CONTEXT_USAGE_TTL_MS;
60851
+ this.#contextUsageCooldownUntilMs = 0;
60852
+ }
60848
60853
  this.#mergeAndPublishUsage({
60849
60854
  contextUsedTokens: Math.max(context.usedTokens, this.#minimumContextUsedTokens ?? 0),
60850
60855
  contextWindowTokens: context.maxTokens
@@ -60853,7 +60858,7 @@ var ClaudeHarnessSession = class {
60853
60858
  } catch {
60854
60859
  }
60855
60860
  }
60856
- if (this.#phase === "open" && this.#transport === request.transport && this.#usageGeneration === request.generation) {
60861
+ if (request.detail === "full" && this.#phase === "open" && this.#transport === request.transport && this.#usageGeneration === request.generation) {
60857
60862
  this.#contextUsageCooldownUntilMs = Date.now() + CONTEXT_USAGE_FAILURE_COOLDOWN_MS;
60858
60863
  }
60859
60864
  }
@@ -60919,8 +60924,6 @@ var ClaudeHarnessSession = class {
60919
60924
  const promptTokens = usage.inputTokens + usage.cacheCreationInputTokens + usage.cacheReadInputTokens;
60920
60925
  if (promptTokens > 0)
60921
60926
  this.#minimumContextUsedTokens = promptTokens;
60922
- if (usage.model)
60923
- this.#latestRequestModel = usage.model;
60924
60927
  const cacheHitRatePercent = claudeCacheHitRatePercent(usage);
60925
60928
  const contextWindowTokens = this.#latestUsage?.contextWindowTokens;
60926
60929
  this.#mergeAndPublishUsage({
@@ -60962,24 +60965,11 @@ var ClaudeHarnessSession = class {
60962
60965
  if (cacheHitRatePercent !== void 0)
60963
60966
  delta.cacheHitRatePercent = cacheHitRatePercent;
60964
60967
  }
60965
- if (this.#latestUsage?.contextWindowTokens === void 0 && this.#minimumContextUsedTokens !== null) {
60966
- const contextWindowTokens = this.#resultContextWindow(event.modelUsage);
60967
- if (contextWindowTokens !== void 0) {
60968
- delta.contextUsedTokens = this.#minimumContextUsedTokens;
60969
- delta.contextWindowTokens = contextWindowTokens;
60970
- }
60968
+ if (this.#transport && this.#minimumContextUsedTokens !== null && event.modelUsage?.some(({ contextWindowTokens }) => contextWindowTokens !== void 0)) {
60969
+ this.#requestContextUsage(this.#transport, active.command.turnId, [0], "summary");
60971
60970
  }
60972
60971
  this.#mergeAndPublishUsage(delta, active.command.turnId);
60973
60972
  }
60974
- /** The latest request's Model, else the Model that carried the most prompt tokens. */
60975
- #resultContextWindow(modelUsage) {
60976
- if (!modelUsage?.length)
60977
- return void 0;
60978
- const latest = this.#latestRequestModel;
60979
- const matched = latest ? modelUsage.find(({ model: model2 }) => model2 === latest) : void 0;
60980
- const main = matched ?? modelUsage.reduce((best, entry) => (entry.promptTokens ?? entry.inputTokens) > (best.promptTokens ?? best.inputTokens) ? entry : best);
60981
- return main.contextWindowTokens;
60982
- }
60983
60973
  /**
60984
60974
  * Plan usage is account-wide, not Thread-scoped, so every observation is
60985
60975
  * offered to the Adapter's shared cache regardless of this Session's own