@karlorz/codexhost-cli-linux-arm64 0.13.3-7 → 0.14.0-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.
@@ -6155,9 +6155,9 @@ function floatSafeRemainder(val, step) {
6155
6155
  return ratio - roundedRatio;
6156
6156
  }
6157
6157
  var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
6158
- function defineLazy(object9, key, getter) {
6158
+ function defineLazy(object10, key, getter) {
6159
6159
  let value2 = void 0;
6160
- Object.defineProperty(object9, key, {
6160
+ Object.defineProperty(object10, key, {
6161
6161
  get() {
6162
6162
  if (value2 === EVALUATING) {
6163
6163
  return void 0;
@@ -6169,7 +6169,7 @@ function defineLazy(object9, key, getter) {
6169
6169
  return value2;
6170
6170
  },
6171
6171
  set(v) {
6172
- Object.defineProperty(object9, key, {
6172
+ Object.defineProperty(object10, key, {
6173
6173
  value: v
6174
6174
  // configurable: true,
6175
6175
  });
@@ -20094,10 +20094,19 @@ var model = external_exports.string().min(1).max(512);
20094
20094
  var project = external_exports.string().min(1).max(4096);
20095
20095
  var usageStatisticsParamsSchema = external_exports.strictObject({
20096
20096
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
20097
+ /** Display timezone for ranges, dates and hourly buckets; omitted means the Host's local zone. */
20098
+ timeZone: external_exports.string().min(1).max(128).refine((value2) => {
20099
+ try {
20100
+ new Intl.DateTimeFormat("en", { timeZone: value2 });
20101
+ return true;
20102
+ } catch {
20103
+ return false;
20104
+ }
20105
+ }, "Unsupported usage statistics timezone").optional(),
20097
20106
  harness: harness.optional(),
20098
20107
  model: model.nullable().optional(),
20099
20108
  project: project.nullable().optional(),
20100
- /** One local date inside the range. */
20109
+ /** One date in the query timezone inside the range. */
20101
20110
  date: localDate.optional()
20102
20111
  });
20103
20112
  var usageStatisticsTotalsSchema = external_exports.strictObject({
@@ -20133,7 +20142,7 @@ var usageStatisticsSessionSchema = external_exports.strictObject({
20133
20142
  });
20134
20143
  var usageStatisticsResultSchema = external_exports.strictObject({
20135
20144
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
20136
- /** First local date of the range; null for all time. */
20145
+ /** First date in the query timezone (Host local when omitted); null for all time. */
20137
20146
  from: localDate.nullable(),
20138
20147
  to: localDate,
20139
20148
  /** The filters these figures apply, echoed so a late answer to older filters is recognised. */
@@ -20173,7 +20182,7 @@ var usageStatisticsResultSchema = external_exports.strictObject({
20173
20182
  totals: usageStatisticsTotalsSchema,
20174
20183
  /** Each date and Harness of the range: every filter except the day. */
20175
20184
  daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
20176
- /** Local weekday (0 = Sunday) and hour, all filters applied. */
20185
+ /** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
20177
20186
  hourly: external_exports.array(external_exports.strictObject({
20178
20187
  weekday: external_exports.number().int().min(0).max(6),
20179
20188
  hour: external_exports.number().int().min(0).max(23),
@@ -20286,6 +20295,8 @@ var CONSOLE_HOST_METHODS = Object.freeze([
20286
20295
  "codexhost/harness/display-settings/set",
20287
20296
  "codexhost/harness/inspect",
20288
20297
  "codexhost/harness/installation",
20298
+ "codexhost/harness/installation/start",
20299
+ "codexhost/harness/installation/status",
20289
20300
  "codexhost/harness/launch-settings/get",
20290
20301
  "codexhost/harness/launch-settings/set",
20291
20302
  "codexhost/harness/grok-computer-use/get",
@@ -20369,7 +20380,18 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
20369
20380
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
20370
20381
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
20371
20382
  var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
20383
+ var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text) => text.length <= maximum));
20384
+ var composerIndicatorsSchema = external_exports.array(external_exports.object({
20385
+ kind: external_exports.literal("countdown"),
20386
+ id: external_exports.string().min(1).max(64),
20387
+ expiresAtUnix: nonNegativeSafeIntegerSchema,
20388
+ label: indicatorTextSchema(256).optional(),
20389
+ tooltip: indicatorTextSchema(1024).optional()
20390
+ }).strict()).max(2).refine((entries) => new Set(entries.map(({ id: id2 }) => id2)).size === entries.length, {
20391
+ message: "Composer indicator IDs must be unique"
20392
+ });
20372
20393
  var threadUsageSnapshotSchema = external_exports.object({
20394
+ composerIndicators: composerIndicatorsSchema.optional(),
20373
20395
  inputTokens: nonNegativeSafeIntegerSchema.optional(),
20374
20396
  cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
20375
20397
  cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
@@ -20785,7 +20807,9 @@ var harnessSessionCapabilitiesSchema = external_exports.object({
20785
20807
  }).strict().optional(),
20786
20808
  autonomousTurns: external_exports.object({
20787
20809
  observe: external_exports.boolean()
20788
- }).strict().optional()
20810
+ }).strict().optional(),
20811
+ /** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
20812
+ steer: external_exports.boolean().optional()
20789
20813
  }).strict();
20790
20814
  var harnessConfigurationStateSchema = external_exports.object({
20791
20815
  effectiveModel: harnessModelRefSchema.optional(),
@@ -20918,6 +20942,16 @@ var threadOwnershipListResultSchema = external_exports.object({
20918
20942
  seen.add(thread.threadId);
20919
20943
  }
20920
20944
  });
20945
+ var threadSteeringInspectParamsSchema = external_exports.object({
20946
+ threadId: hostThreadIdSchema,
20947
+ /** The text about to be steered; a Harness command always stops and restarts. */
20948
+ text: external_exports.string().optional()
20949
+ }).strict();
20950
+ var THREAD_STEER_DELIVERY_PARAM = "codexhostSteerDelivery";
20951
+ var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
20952
+ var threadSteeringInspectResultSchema = external_exports.object({
20953
+ delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
20954
+ }).strict();
20921
20955
 
20922
20956
  // packages/shared-contracts/dist/harness-plugins.js
20923
20957
  var HARNESS_PLUGIN_API_VERSION = 1;
@@ -21060,6 +21094,8 @@ var grokComputerUseSettingsSchema = external_exports.object({
21060
21094
 
21061
21095
  // packages/shared-contracts/dist/harness-installation.js
21062
21096
  var HARNESS_INSTALLATION_METHOD = "codexhost/harness/installation";
21097
+ var HARNESS_INSTALLATION_START_METHOD = "codexhost/harness/installation/start";
21098
+ var HARNESS_INSTALLATION_STATUS_METHOD = "codexhost/harness/installation/status";
21063
21099
  var harnessInstallationParamsSchema = external_exports.object({
21064
21100
  harnessId: harnessIdSchema,
21065
21101
  action: external_exports.enum(["check", "update", "install"])
@@ -21069,6 +21105,10 @@ var harnessInstallationStateSchema = external_exports.object({
21069
21105
  latestVersion: external_exports.string().min(1).max(128),
21070
21106
  updateAvailable: external_exports.boolean(),
21071
21107
  canUpdate: external_exports.boolean(),
21108
+ /** Defaults to CLI; some Harnesses ship only inside a desktop application. */
21109
+ versionKind: external_exports.enum(["cli", "application"]).optional(),
21110
+ /** Official download opened by the user; does not imply an automatic installation. */
21111
+ manualUpdateUrl: external_exports.url().max(2048).refine((value2) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value2), "Manual updates require a credential-free HTTPS URL").optional(),
21072
21112
  // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
21073
21113
  message: external_exports.string().max(2048).optional(),
21074
21114
  messageCode: external_exports.string().min(1).max(128).optional(),
@@ -21076,6 +21116,20 @@ var harnessInstallationStateSchema = external_exports.object({
21076
21116
  notice: harnessLocalizedTextSchema.optional(),
21077
21117
  latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
21078
21118
  }).strict();
21119
+ var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
21120
+ var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
21121
+ external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
21122
+ external_exports.object({
21123
+ taskId: external_exports.string().uuid(),
21124
+ status: external_exports.literal("succeeded"),
21125
+ result: harnessInstallationStateSchema
21126
+ }).strict(),
21127
+ external_exports.object({
21128
+ taskId: external_exports.string().uuid(),
21129
+ status: external_exports.literal("failed"),
21130
+ error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
21131
+ }).strict()
21132
+ ]);
21079
21133
 
21080
21134
  // packages/shared-contracts/dist/codex-accounts.js
21081
21135
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
@@ -23260,7 +23314,7 @@ function retainRendererHostResponses(client, hostId2, target) {
23260
23314
  if (typeof client.addRequestLifecycleListener !== "function" || typeof target.addEventListener !== "function" || typeof target.removeEventListener !== "function")
23261
23315
  return () => {
23262
23316
  };
23263
- const isRecord21 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
23317
+ const isRecord22 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
23264
23318
  const pending = /* @__PURE__ */ new Set();
23265
23319
  let retired = false;
23266
23320
  let unsubscribe = () => {
@@ -23276,15 +23330,15 @@ function retainRendererHostResponses(client, hostId2, target) {
23276
23330
  const ownOrigin = target.location?.origin;
23277
23331
  if (source === target && ownOrigin && ownOrigin !== "null" && origin !== ownOrigin)
23278
23332
  return;
23279
- if (!isRecord21(data) || data.type !== "mcp-response" || data.hostId !== hostId2)
23333
+ if (!isRecord22(data) || data.type !== "mcp-response" || data.hostId !== hostId2)
23280
23334
  return;
23281
23335
  const message2 = data.message;
23282
- if (!isRecord21(message2))
23336
+ if (!isRecord22(message2))
23283
23337
  return;
23284
23338
  const id2 = message2.id;
23285
23339
  if (typeof id2 !== "string" && typeof id2 !== "number" || !pending.has(id2))
23286
23340
  return;
23287
- const hasError = isRecord21(message2.error);
23341
+ const hasError = isRecord22(message2.error);
23288
23342
  if (!hasError && !Object.prototype.hasOwnProperty.call(message2, "result"))
23289
23343
  return;
23290
23344
  queueMicrotask(() => {
@@ -23298,7 +23352,7 @@ function retainRendererHostResponses(client, hostId2, target) {
23298
23352
  };
23299
23353
  target.addEventListener("message", receive);
23300
23354
  unsubscribe = client.addRequestLifecycleListener((event) => {
23301
- if (!isRecord21(event) || event.hostId !== hostId2)
23355
+ if (!isRecord22(event) || event.hostId !== hostId2)
23302
23356
  return;
23303
23357
  const id2 = event.id;
23304
23358
  if (typeof id2 !== "string" && typeof id2 !== "number")
@@ -23328,13 +23382,13 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23328
23382
  let selectedModel = null;
23329
23383
  let prewarmGeneration = 0;
23330
23384
  const externalPrewarms = /* @__PURE__ */ new Set();
23331
- const isRecord21 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
23385
+ const isRecord22 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
23332
23386
  const isUnsupportedPosixBridgeSpawn = (value2) => {
23333
23387
  const marker = "AbsolutePathBuf deserialized without a base path";
23334
23388
  if (typeof value2 === "string") {
23335
23389
  return value2.startsWith("Invalid request:") && value2.includes(marker);
23336
23390
  }
23337
- if (!isRecord21(value2))
23391
+ if (!isRecord22(value2))
23338
23392
  return false;
23339
23393
  if (typeof value2.message === "string" && value2.message.includes(marker)) {
23340
23394
  if (value2.code === -32600 || value2.message.startsWith("Invalid request:"))
@@ -23427,7 +23481,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23427
23481
  bridgeState = "idle";
23428
23482
  };
23429
23483
  const rememberExternalThread = (value2) => {
23430
- if (!isRecord21(value2) || typeof value2.id !== "string")
23484
+ if (!isRecord22(value2) || typeof value2.id !== "string")
23431
23485
  return;
23432
23486
  if (value2.modelProvider === "codexhost" || value2.cliVersion === "codexhost") {
23433
23487
  knownExternalThreadIds.add(value2.id);
@@ -23435,7 +23489,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23435
23489
  }
23436
23490
  };
23437
23491
  const observeBridgeResult = (request, result) => {
23438
- if (!request || !isRecord21(result))
23492
+ if (!request || !isRecord22(result))
23439
23493
  return;
23440
23494
  if (request.method === "thread/list" && Array.isArray(result.data)) {
23441
23495
  for (const thread of result.data)
@@ -23446,7 +23500,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23446
23500
  rememberExternalThread(result.thread);
23447
23501
  return;
23448
23502
  }
23449
- if (request.method === "codexhost/thread/inspect" && isRecord21(request.parameters) && typeof request.parameters.threadId === "string") {
23503
+ if (request.method === "codexhost/thread/inspect" && isRecord22(request.parameters) && typeof request.parameters.threadId === "string") {
23450
23504
  if (result.owner === "external") {
23451
23505
  knownExternalThreadIds.add(request.parameters.threadId);
23452
23506
  knownOfficialThreadIds.delete(request.parameters.threadId);
@@ -23456,18 +23510,18 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23456
23510
  }
23457
23511
  return;
23458
23512
  }
23459
- if (request.method === "thread/delete" && isRecord21(request.parameters) && typeof request.parameters.threadId === "string") {
23513
+ if (request.method === "thread/delete" && isRecord22(request.parameters) && typeof request.parameters.threadId === "string") {
23460
23514
  knownExternalThreadIds.delete(request.parameters.threadId);
23461
23515
  knownOfficialThreadIds.delete(request.parameters.threadId);
23462
23516
  }
23463
23517
  };
23464
23518
  const handleBridgeFrame = (value2) => {
23465
- if (!isRecord21(value2)) {
23519
+ if (!isRecord22(value2)) {
23466
23520
  failBridge("received a non-object app-server frame");
23467
23521
  return;
23468
23522
  }
23469
23523
  if (value2.method === bridgeReadyMethod && value2.id === void 0) {
23470
- if (isRecord21(value2.params) && value2.params.protocolVersion === 1) {
23524
+ if (isRecord22(value2.params) && value2.params.protocolVersion === 1) {
23471
23525
  bridgeState = "ready";
23472
23526
  if (bridgeReadyTimeout !== null)
23473
23527
  globalThis.clearTimeout(bridgeReadyTimeout);
@@ -23481,7 +23535,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23481
23535
  return;
23482
23536
  }
23483
23537
  if (typeof value2.method === "string" && value2.id === void 0) {
23484
- if (value2.method === "thread/started" && isRecord21(value2.params)) {
23538
+ if (value2.method === "thread/started" && isRecord22(value2.params)) {
23485
23539
  rememberExternalThread(value2.params.thread);
23486
23540
  }
23487
23541
  originalOnNotification.call(manager, value2.method, value2.params);
@@ -23532,13 +23586,13 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23532
23586
  }
23533
23587
  };
23534
23588
  const handleOuterNotification = (method, parameters) => {
23535
- if (method === "process/exited" && isRecord21(parameters) && parameters.processHandle === bridgeProcessHandle) {
23589
+ if (method === "process/exited" && isRecord22(parameters) && parameters.processHandle === bridgeProcessHandle) {
23536
23590
  const exitCode = typeof parameters.exitCode === "number" ? parameters.exitCode : "unknown";
23537
23591
  const stderr = typeof parameters.stderr === "string" ? parameters.stderr.trim() : "";
23538
23592
  failBridge(`process exited unexpectedly with code ${exitCode}${stderr ? `: ${stderr}` : ""}`, false);
23539
23593
  return true;
23540
23594
  }
23541
- if (method !== "process/outputDelta" || !isRecord21(parameters) || parameters.processHandle !== bridgeProcessHandle || parameters.stream !== "stdout" && parameters.stream !== "stderr" || typeof parameters.deltaBase64 !== "string") {
23595
+ if (method !== "process/outputDelta" || !isRecord22(parameters) || parameters.processHandle !== bridgeProcessHandle || parameters.stream !== "stdout" && parameters.stream !== "stderr" || typeof parameters.deltaBase64 !== "string") {
23542
23596
  return false;
23543
23597
  }
23544
23598
  if (parameters.capReached === true) {
@@ -23642,7 +23696,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23642
23696
  return bridgeInitialization;
23643
23697
  };
23644
23698
  const threadIdFromParameters = (parameters) => {
23645
- if (!isRecord21(parameters))
23699
+ if (!isRecord22(parameters))
23646
23700
  return null;
23647
23701
  const value2 = parameters.threadId ?? parameters.conversationId;
23648
23702
  return typeof value2 === "string" ? value2 : null;
@@ -23659,9 +23713,9 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23659
23713
  const resolution = initializeBridge().then(() => enqueueBridgeRequest("codexhost/thread/ownership/list", {
23660
23714
  threadIds: [threadId2]
23661
23715
  })).then((value2) => {
23662
- const ownerships = isRecord21(value2) && Array.isArray(value2.threads) ? value2.threads : null;
23716
+ const ownerships = isRecord22(value2) && Array.isArray(value2.threads) ? value2.threads : null;
23663
23717
  const ownership = ownerships?.[0];
23664
- if (!ownerships || !isRecord21(ownership) || ownerships.length !== 1 || ownership.threadId !== threadId2 || ownership.owner !== "external" && ownership.owner !== "codex") {
23718
+ if (!ownerships || !isRecord22(ownership) || ownerships.length !== 1 || ownership.threadId !== threadId2 || ownership.owner !== "external" && ownership.owner !== "codex") {
23665
23719
  throw transportError("Thread ownership lookup returned an invalid result");
23666
23720
  }
23667
23721
  if (ownership.owner === "external") {
@@ -23700,7 +23754,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23700
23754
  if (method === "thread/list")
23701
23755
  return true;
23702
23756
  if (method === "thread/start") {
23703
- return isRecord21(parameters) && typeof parameters.model === "string" && parameters.model.startsWith("codexhost/");
23757
+ return isRecord22(parameters) && typeof parameters.model === "string" && parameters.model.startsWith("codexhost/");
23704
23758
  }
23705
23759
  const threadId2 = threadIdFromParameters(parameters);
23706
23760
  if (threadId2 && knownExternalThreadIds.has(threadId2))
@@ -23710,7 +23764,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23710
23764
  return selectedModel !== null && (method.startsWith("thread/") || method.startsWith("turn/") || method.startsWith("review/"));
23711
23765
  };
23712
23766
  const routeThreadStart = (parameters) => {
23713
- if (!isRecord21(parameters) || parameters.ephemeral === true) {
23767
+ if (!isRecord22(parameters) || parameters.ephemeral === true) {
23714
23768
  return parameters;
23715
23769
  }
23716
23770
  return {
@@ -23743,12 +23797,12 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23743
23797
  return shouldUseBridge(method, routedParameters) ? sendBridged() : sendDirect();
23744
23798
  };
23745
23799
  const publishDraftWorkspace = (parameters) => {
23746
- if (!isRecord21(parameters) || parameters.ephemeral === true)
23800
+ if (!isRecord22(parameters) || parameters.ephemeral === true)
23747
23801
  return;
23748
23802
  const cwd = parameters.cwd;
23749
23803
  if (typeof cwd !== "string" || cwd.length === 0)
23750
23804
  return;
23751
- const drafts = isRecord21(target.__codexhostDraftWorkspacesV1) ? target.__codexhostDraftWorkspacesV1 : {};
23805
+ const drafts = isRecord22(target.__codexhostDraftWorkspacesV1) ? target.__codexhostDraftWorkspacesV1 : {};
23752
23806
  drafts[hostId2] = cwd;
23753
23807
  Object.defineProperty(target, "__codexhostDraftWorkspacesV1", {
23754
23808
  configurable: true,
@@ -23771,16 +23825,16 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23771
23825
  };
23772
23826
  const routedPrewarm = (parameters, options2) => {
23773
23827
  const routed = routeThreadStart(parameters);
23774
- const external = isRecord21(routed) && routed.ephemeral !== true && typeof routed.model === "string" && routed.model.startsWith("codexhost/");
23828
+ const external = isRecord22(routed) && routed.ephemeral !== true && typeof routed.model === "string" && routed.model.startsWith("codexhost/");
23775
23829
  const routedParameters = external ? { ...routed, codexhostPrewarm: true } : routed;
23776
23830
  const generation = prewarmGeneration;
23777
23831
  publishDraftWorkspace(routedParameters);
23778
23832
  const pending = shouldUseBridge("thread/start", routedParameters) ? routedSend("thread/start", routedParameters, options2) : options2 === void 0 ? originalPrewarm.call(bridge, routedParameters) : originalPrewarm.call(bridge, routedParameters, options2);
23779
- if (isRecord21(parameters) && parameters.ephemeral === true || typeof pending !== "object" && typeof pending !== "function" || pending === null || typeof Reflect.get(pending, "then") !== "function") {
23833
+ if (isRecord22(parameters) && parameters.ephemeral === true || typeof pending !== "object" && typeof pending !== "function" || pending === null || typeof Reflect.get(pending, "then") !== "function") {
23780
23834
  return pending;
23781
23835
  }
23782
23836
  return Promise.resolve(pending).then((result) => {
23783
- const threadId2 = external && isRecord21(result) && isRecord21(result.thread) && typeof result.thread.id === "string" ? result.thread.id : null;
23837
+ const threadId2 = external && isRecord22(result) && isRecord22(result.thread) && typeof result.thread.id === "string" ? result.thread.id : null;
23784
23838
  if (disposed || generation !== prewarmGeneration) {
23785
23839
  if (threadId2)
23786
23840
  discardExternalPrewarm(threadId2);
@@ -23796,7 +23850,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
23796
23850
  bridge.prewarmThreadStart = routedPrewarm;
23797
23851
  const routedWindowMessage = (event) => {
23798
23852
  const message2 = event.data;
23799
- if (!isRecord21(message2) || message2.type !== "mcp-notification" || message2.hostId !== hostId2 || typeof message2.method !== "string") {
23853
+ if (!isRecord22(message2) || message2.type !== "mcp-notification" || message2.hostId !== hostId2 || typeof message2.method !== "string") {
23800
23854
  return;
23801
23855
  }
23802
23856
  handleOuterNotification(message2.method, message2.params);
@@ -23918,9 +23972,13 @@ function requestManagerFromHookState(value2, hostId2) {
23918
23972
  const direct = manager(value2) ?? manager(value2.manager);
23919
23973
  if (direct)
23920
23974
  return direct;
23921
- if (!hostId2 || typeof value2.addManager !== "function" || typeof value2.getForHostId !== "function" || typeof value2.waitForManagerForHostId !== "function")
23975
+ if (!hostId2 || typeof value2.addManager !== "function" || typeof value2.getForHostId !== "function")
23922
23976
  return null;
23923
- return manager(value2.getForHostId(hostId2));
23977
+ try {
23978
+ return manager(value2.getForHostId(hostId2));
23979
+ } catch {
23980
+ return null;
23981
+ }
23924
23982
  }
23925
23983
  function discoverRendererHosts(root, ancestors = committedReactAncestors, managerFrom = requestManagerFromHookState) {
23926
23984
  const editors = [
@@ -23956,7 +24014,7 @@ function discoverRendererHosts(root, ancestors = committedReactAncestors, manage
23956
24014
  const manager = managerFrom(value2);
23957
24015
  if (manager)
23958
24016
  managers.add(manager);
23959
- if (value2 && typeof value2 === "object" && "addManager" in value2 && typeof value2.addManager === "function" && "getForHostId" in value2 && typeof value2.getForHostId === "function" && "waitForManagerForHostId" in value2 && typeof value2.waitForManagerForHostId === "function") {
24017
+ if (value2 && typeof value2 === "object" && "addManager" in value2 && typeof value2.addManager === "function" && "getForHostId" in value2 && typeof value2.getForHostId === "function") {
23960
24018
  registries.add(value2);
23961
24019
  }
23962
24020
  hook = hook.next && typeof hook.next === "object" ? hook.next : null;
@@ -23972,7 +24030,13 @@ function discoverRendererHosts(root, ancestors = committedReactAncestors, manage
23972
24030
  function resolveRendererHostManager(discovery, hostId2, managerFrom = requestManagerFromHookState) {
23973
24031
  if (!hostId2)
23974
24032
  return null;
23975
- const candidates = discovery.registries.length ? discovery.registries.map((registry2) => managerFrom(registry2.getForHostId(hostId2))) : discovery.managers;
24033
+ const candidates = discovery.registries.length ? discovery.registries.flatMap((registry2) => {
24034
+ try {
24035
+ return [managerFrom(registry2.getForHostId(hostId2))];
24036
+ } catch {
24037
+ return [];
24038
+ }
24039
+ }) : discovery.managers;
23976
24040
  const matching = new Set(candidates.filter((manager) => manager && (manager.getHostId?.() ?? manager.requestClient.hostId) === hostId2 && (manager.requestClient.hostId === void 0 || manager.requestClient.hostId === hostId2)));
23977
24041
  return matching.size === 1 ? matching.values().next().value ?? null : null;
23978
24042
  }
@@ -25091,6 +25155,36 @@ var ExternalVoice = class {
25091
25155
  }
25092
25156
  };
25093
25157
 
25158
+ // packages/host-runtime/src/external-voice-presentation.ts
25159
+ var INLINE_MARKDOWN = "::codex-realtime-inline{}\n";
25160
+ var inlineMarker = /^::codex-realtime-inline\{\}\r?\n/u;
25161
+ function externalVoiceContentText(text) {
25162
+ return text.replace(inlineMarker, "");
25163
+ }
25164
+ function object5(value2) {
25165
+ return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
25166
+ }
25167
+ function presentItem(item) {
25168
+ if (!object5(item) || item.type !== "agentMessage" || typeof item.text !== "string") return item;
25169
+ if (!item.text.trim() || inlineMarker.test(item.text)) return item;
25170
+ return { ...item, text: INLINE_MARKDOWN + item.text };
25171
+ }
25172
+ function presentExternalVoiceTurn(turn) {
25173
+ if (!Array.isArray(turn.items)) return turn;
25174
+ return { ...turn, items: turn.items.map(presentItem) };
25175
+ }
25176
+ function presentExternalVoiceMessage(message2) {
25177
+ const params = message2.params;
25178
+ if (!object5(params)) return message2;
25179
+ if ((message2.method === "item/started" || message2.method === "item/completed") && params.item) {
25180
+ return { ...message2, params: { ...params, item: presentItem(params.item) } };
25181
+ }
25182
+ if ((message2.method === "turn/started" || message2.method === "turn/completed") && object5(params.turn)) {
25183
+ return { ...message2, params: { ...params, turn: presentExternalVoiceTurn(params.turn) } };
25184
+ }
25185
+ return message2;
25186
+ }
25187
+
25094
25188
  // packages/host-runtime/src/external-voice-session-input.ts
25095
25189
  var MAX_MESSAGES = 32;
25096
25190
  var MAX_MESSAGE_CHARS = 2e3;
@@ -25129,7 +25223,7 @@ function voiceSessionInputFromTurns(turns) {
25129
25223
  const text = userMessageText(item);
25130
25224
  if (text) messages.push(liveMessage("user", text));
25131
25225
  } else if (item.type === "agentMessage" && item.phase !== "commentary") {
25132
- const text = typeof item.text === "string" ? item.text.trim() : "";
25226
+ const text = typeof item.text === "string" ? externalVoiceContentText(item.text).trim() : "";
25133
25227
  if (text) messages.push(liveMessage("assistant", text));
25134
25228
  }
25135
25229
  }
@@ -25159,7 +25253,7 @@ function speakableFromProjectedTurn(turn) {
25159
25253
  function speakableFromItems(items) {
25160
25254
  const values = [...items];
25161
25255
  const finals = values.filter((item) => item.phase === "final_answer");
25162
- const text = (finals.length ? finals : values.filter((item) => item.phase !== "commentary").slice(-1)).map((item) => item.text).join("\n").trim();
25256
+ const text = (finals.length ? finals : values.filter((item) => item.phase !== "commentary").slice(-1)).map((item) => externalVoiceContentText(item.text)).join("\n").trim();
25163
25257
  return text.length > 0 ? text : void 0;
25164
25258
  }
25165
25259
  var ExternalVoiceResults = class {
@@ -25259,7 +25353,7 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
25259
25353
  var wrapper_default = import_websocket.default;
25260
25354
 
25261
25355
  // packages/host-runtime/src/external-voice-gateway.ts
25262
- function object5(value2) {
25356
+ function object6(value2) {
25263
25357
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
25264
25358
  }
25265
25359
  function configuredExternalVoiceGateway(environment) {
@@ -25342,7 +25436,7 @@ function configuredExternalVoiceGateway(environment) {
25342
25436
  if (closed || input.signal.aborted) return;
25343
25437
  try {
25344
25438
  const event = JSON.parse(String(raw));
25345
- if (object5(event) && typeof event.type === "string")
25439
+ if (object6(event) && typeof event.type === "string")
25346
25440
  input.onEvent(event);
25347
25441
  } catch {
25348
25442
  input.onError();
@@ -25962,6 +26056,64 @@ async function handleHarnessInstallation(params, adapters) {
25962
26056
  }
25963
26057
  }
25964
26058
 
26059
+ // packages/host-runtime/src/harness-installation-tasks.ts
26060
+ import { randomUUID as randomUUID5 } from "node:crypto";
26061
+ var HarnessInstallationTasks = class {
26062
+ #tasks = /* @__PURE__ */ new Map();
26063
+ #active = /* @__PURE__ */ new Map();
26064
+ #prune() {
26065
+ const cutoff = Date.now() - 15 * 6e4;
26066
+ for (const [id2, task] of this.#tasks) {
26067
+ if (task.finishedAt !== void 0 && task.finishedAt < cutoff) this.#tasks.delete(id2);
26068
+ }
26069
+ }
26070
+ start(params, adapters) {
26071
+ const parsed2 = harnessInstallationParamsSchema.safeParse(params);
26072
+ if (!parsed2.success)
26073
+ throw new HarnessInstallationError(-32602, "Invalid Harness installation request");
26074
+ this.#prune();
26075
+ const key = JSON.stringify([parsed2.data.harnessId, parsed2.data.action]);
26076
+ const activeId = this.#active.get(key);
26077
+ const active = activeId ? this.#tasks.get(activeId) : void 0;
26078
+ if (active) return active.state;
26079
+ const taskId = randomUUID5();
26080
+ const task = {
26081
+ state: { taskId, status: "running" }
26082
+ };
26083
+ this.#tasks.set(taskId, task);
26084
+ this.#active.set(key, taskId);
26085
+ void handleHarnessInstallation(parsed2.data, adapters).then(
26086
+ (result) => {
26087
+ task.state = { taskId, status: "succeeded", result };
26088
+ },
26089
+ (error51) => {
26090
+ task.state = {
26091
+ taskId,
26092
+ status: "failed",
26093
+ error: error51 instanceof HarnessInstallationError ? { code: error51.code, message: error51.message } : { code: -32077, message: "Harness version management failed" }
26094
+ };
26095
+ }
26096
+ ).finally(() => {
26097
+ task.finishedAt = Date.now();
26098
+ this.#active.delete(key);
26099
+ });
26100
+ return task.state;
26101
+ }
26102
+ status(params) {
26103
+ const parsed2 = harnessInstallationTaskParamsSchema.safeParse(params);
26104
+ if (!parsed2.success)
26105
+ throw new HarnessInstallationError(-32602, "Invalid Harness installation task request");
26106
+ this.#prune();
26107
+ const task = this.#tasks.get(parsed2.data.taskId);
26108
+ if (!task)
26109
+ throw new HarnessInstallationError(
26110
+ -32079,
26111
+ "Harness installation task is unavailable on this Host"
26112
+ );
26113
+ return task.state;
26114
+ }
26115
+ };
26116
+
25965
26117
  // packages/host-runtime/src/account/codex-credential-export.ts
25966
26118
  import { createHash as createHash3 } from "node:crypto";
25967
26119
  import { readFile as readFile10 } from "node:fs/promises";
@@ -26054,7 +26206,7 @@ async function listOthers(adapter) {
26054
26206
  }
26055
26207
 
26056
26208
  // packages/host-runtime/src/harness-display-settings.ts
26057
- import { randomUUID as randomUUID5 } from "node:crypto";
26209
+ import { randomUUID as randomUUID6 } from "node:crypto";
26058
26210
  import { link, mkdir as mkdir8, readFile as readFile11, rename as rename5, rm as rm7, writeFile as writeFile7 } from "node:fs/promises";
26059
26211
  import os5 from "node:os";
26060
26212
  import path16 from "node:path";
@@ -26079,7 +26231,7 @@ var HarnessDisplaySettingsStore = class {
26079
26231
  async set(input) {
26080
26232
  const entries = harnessDisplayEntriesSchema.parse(input.entries);
26081
26233
  await mkdir8(path16.dirname(this.#file), { recursive: true, mode: 448 });
26082
- const temporary = `${this.#file}.${randomUUID5()}.tmp`;
26234
+ const temporary = `${this.#file}.${randomUUID6()}.tmp`;
26083
26235
  try {
26084
26236
  await writeFile7(temporary, `${JSON.stringify(entries)}
26085
26237
  `, { mode: 384, flag: "wx" });
@@ -26100,7 +26252,7 @@ var HarnessDisplaySettingsStore = class {
26100
26252
  };
26101
26253
 
26102
26254
  // packages/host-runtime/src/model-price-overrides-file.ts
26103
- import { randomUUID as randomUUID6 } from "node:crypto";
26255
+ import { randomUUID as randomUUID7 } from "node:crypto";
26104
26256
  import { mkdir as mkdir10, readFile as readFile13, rename as rename7, rm as rm8, writeFile as writeFile9 } from "node:fs/promises";
26105
26257
  import path18 from "node:path";
26106
26258
 
@@ -26675,7 +26827,7 @@ async function updateModelPriceOverridesFile(file2, change) {
26675
26827
  const updated = { ...document, models: next };
26676
26828
  parseModelPriceOverrides(updated);
26677
26829
  await mkdir10(path18.dirname(file2), { recursive: true });
26678
- const temporary = `${file2}.${randomUUID6()}.tmp`;
26830
+ const temporary = `${file2}.${randomUUID7()}.tmp`;
26679
26831
  try {
26680
26832
  await writeFile9(temporary, `${JSON.stringify(updated, null, 2)}
26681
26833
  `, { flag: "wx" });
@@ -26711,7 +26863,7 @@ async function handleModelPriceOverridesRequest(catalog, method, params) {
26711
26863
  }
26712
26864
 
26713
26865
  // packages/host-runtime/src/delegation-skill.ts
26714
- import { createHash as createHash4, randomUUID as randomUUID7 } from "node:crypto";
26866
+ import { createHash as createHash4, randomUUID as randomUUID8 } from "node:crypto";
26715
26867
  import { mkdir as mkdir11, open as open4, readFile as readFile14, rename as rename8, rm as rm9, stat as stat5 } from "node:fs/promises";
26716
26868
  import os7 from "node:os";
26717
26869
  import path19 from "node:path";
@@ -26811,7 +26963,7 @@ async function readOptional(filePath) {
26811
26963
  }
26812
26964
  async function atomicWrite(filePath, content) {
26813
26965
  await mkdir11(path19.dirname(filePath), { recursive: true, mode: 448 });
26814
- const temporaryPath = path19.join(path19.dirname(filePath), `.SKILL.md.${randomUUID7()}.tmp`);
26966
+ const temporaryPath = path19.join(path19.dirname(filePath), `.SKILL.md.${randomUUID8()}.tmp`);
26815
26967
  const handle = await open4(temporaryPath, "wx", 384);
26816
26968
  try {
26817
26969
  await handle.writeFile(content, "utf8");
@@ -27048,6 +27200,7 @@ var usageFields = /* @__PURE__ */ new Set([
27048
27200
  ...safeIntegerFields,
27049
27201
  ...percentFields,
27050
27202
  "sessionCacheUsage",
27203
+ "composerIndicators",
27051
27204
  "totalCostUsd",
27052
27205
  "totalCredits",
27053
27206
  "contextUsagePercent",
@@ -27070,6 +27223,7 @@ function parseHostUsage(value2) {
27070
27223
  throw new Error(`Harness Usage contains unknown field '${key}'`);
27071
27224
  }
27072
27225
  }
27226
+ const indicators = value2.composerIndicators === void 0 ? {} : { composerIndicators: composerIndicatorsSchema.parse(value2.composerIndicators) };
27073
27227
  for (const field of [
27074
27228
  "totalCredits",
27075
27229
  "contextUsagePercent",
@@ -27140,9 +27294,9 @@ function parseHostUsage(value2) {
27140
27294
  if (value2.costSource !== "publicPrice") {
27141
27295
  throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
27142
27296
  }
27143
- return { ...value2, unpricedModels: [...models] };
27297
+ return { ...value2, ...indicators, unpricedModels: [...models] };
27144
27298
  }
27145
- return { ...value2 };
27299
+ return { ...value2, ...indicators };
27146
27300
  }
27147
27301
  var requestTokenFields = [
27148
27302
  "inputTokens",
@@ -27293,7 +27447,7 @@ var packageMetadata = {
27293
27447
 
27294
27448
  // packages/mapping-store/dist/mapping-store.js
27295
27449
  import { execFileSync } from "node:child_process";
27296
- import { randomUUID as randomUUID10 } from "node:crypto";
27450
+ import { randomUUID as randomUUID11 } from "node:crypto";
27297
27451
  import { constants as constants3 } from "node:fs";
27298
27452
  import { copyFile as copyFile3, mkdir as mkdir13, open as open7, readFile as readFile17, readdir as readdir4, rename as rename11, rm as rm12, stat as stat6 } from "node:fs/promises";
27299
27453
  import path21 from "node:path";
@@ -27309,7 +27463,9 @@ var isoDateSchema = external_exports.string().refine((value2) => !Number.isNaN(D
27309
27463
  var storedTurnMappingV1Schema = external_exports.object({
27310
27464
  hostTurnId: hostTurnIdSchema,
27311
27465
  nativeTurnRef: nativeTurnRefSchema,
27312
- nativeCheckpointRef: nativeCheckpointRefSchema.optional()
27466
+ nativeCheckpointRef: nativeCheckpointRefSchema.optional(),
27467
+ /** Desktop presentation for work completed during an external voice call. */
27468
+ realtimeInline: external_exports.literal(true).optional()
27313
27469
  }).strict();
27314
27470
  var storedGitInfoV1Schema = external_exports.object({
27315
27471
  branch: nonBlankTextSchema6.max(4096).optional(),
@@ -27449,7 +27605,7 @@ var storedDelegationRecordV1Schema = external_exports.object({
27449
27605
  });
27450
27606
 
27451
27607
  // packages/mapping-store/dist/section-placements.js
27452
- import { randomUUID as randomUUID8 } from "node:crypto";
27608
+ import { randomUUID as randomUUID9 } from "node:crypto";
27453
27609
  import { constants } from "node:fs";
27454
27610
  import { open as open5, readFile as readFile15, rename as rename9, rm as rm10 } from "node:fs/promises";
27455
27611
  var threadIdSchema = external_exports.string().min(1).max(1024);
@@ -27501,7 +27657,7 @@ async function readSectionPlacementsFile(file2) {
27501
27657
  }
27502
27658
  async function writeSectionPlacementsFile(file2, placements) {
27503
27659
  const parsed2 = parseSectionPlacements({ formatVersion: 1, placements });
27504
- const temp = `${file2}.tmp-${randomUUID8()}`;
27660
+ const temp = `${file2}.tmp-${randomUUID9()}`;
27505
27661
  let handle = null;
27506
27662
  try {
27507
27663
  handle = await open5(temp, "wx", constants.S_IRUSR | constants.S_IWUSR);
@@ -27520,7 +27676,7 @@ async function writeSectionPlacementsFile(file2, placements) {
27520
27676
  }
27521
27677
 
27522
27678
  // packages/mapping-store/dist/superseded-sessions.js
27523
- import { randomUUID as randomUUID9 } from "node:crypto";
27679
+ import { randomUUID as randomUUID10 } from "node:crypto";
27524
27680
  import { constants as constants2 } from "node:fs";
27525
27681
  import { mkdir as mkdir12, open as open6, readFile as readFile16, rename as rename10, rm as rm11 } from "node:fs/promises";
27526
27682
  import path20 from "node:path";
@@ -27555,7 +27711,7 @@ async function writeSupersededSessionsFile(file2, sessions) {
27555
27711
  formatVersion: 1,
27556
27712
  sessions: sessions.slice(-SUPERSEDED_SESSIONS_MAX)
27557
27713
  }).sessions;
27558
- const temp = `${file2}.tmp-${randomUUID9()}`;
27714
+ const temp = `${file2}.tmp-${randomUUID10()}`;
27559
27715
  let handle = null;
27560
27716
  try {
27561
27717
  await mkdir12(path20.dirname(file2), { recursive: true });
@@ -27810,7 +27966,7 @@ var MappingStore = class {
27810
27966
  this.#sectionsDirectory = path21.join(this.#directory, "sections");
27811
27967
  this.#metadataDirectory = path21.join(this.#directory, "thread-metadata");
27812
27968
  this.#lockPath = path21.join(this.#directory, "store.lock");
27813
- this.#instanceId = options2.instanceId ?? randomUUID10();
27969
+ this.#instanceId = options2.instanceId ?? randomUUID11();
27814
27970
  this.#now = options2.now ?? (() => /* @__PURE__ */ new Date());
27815
27971
  this.#beforeReplace = options2.beforeReplace;
27816
27972
  }
@@ -28318,6 +28474,8 @@ var MappingStore = class {
28318
28474
  if (!hostMatch.nativeCheckpointRef && update.nativeCheckpointRef) {
28319
28475
  hostMatch.nativeCheckpointRef = update.nativeCheckpointRef;
28320
28476
  }
28477
+ if (update.realtimeInline)
28478
+ hostMatch.realtimeInline = true;
28321
28479
  continue;
28322
28480
  }
28323
28481
  const added = { ...update };
@@ -28334,7 +28492,7 @@ var MappingStore = class {
28334
28492
  this.#rebuildIndexes();
28335
28493
  }
28336
28494
  async #replaceFile(target, record4, preserveBackup) {
28337
- const temp = `${target}.tmp-${randomUUID10()}`;
28495
+ const temp = `${target}.tmp-${randomUUID11()}`;
28338
28496
  let handle = null;
28339
28497
  try {
28340
28498
  await this.#beforeReplace?.(cloneRecord(record4));
@@ -28361,7 +28519,7 @@ var MappingStore = class {
28361
28519
  /** Atomically patches owned metadata fields, retaining unknown fields on disk. */
28362
28520
  async #writeMetadataFile(hostThreadId, metadata) {
28363
28521
  const target = this.#metadataPath(hostThreadId);
28364
- const temp = `${target}.tmp-${randomUUID10()}`;
28522
+ const temp = `${target}.tmp-${randomUUID11()}`;
28365
28523
  let handle = null;
28366
28524
  try {
28367
28525
  const retained = Object.fromEntries(Object.entries(await this.#readMetadata(hostThreadId) ?? {}).filter(([name]) => !["formatVersion", "hostThreadId", ...THREAD_METADATA_FIELDS].includes(name)));
@@ -28408,7 +28566,7 @@ var MappingStore = class {
28408
28566
  }
28409
28567
  async #replaceDelegationFile(record4) {
28410
28568
  const target = this.#delegationPath(record4.delegationId);
28411
- const temp = `${target}.tmp-${randomUUID10()}`;
28569
+ const temp = `${target}.tmp-${randomUUID11()}`;
28412
28570
  let handle = null;
28413
28571
  try {
28414
28572
  handle = await open7(temp, "wx", constants3.S_IRUSR | constants3.S_IWUSR);
@@ -30100,8 +30258,18 @@ function projectSubagentActivities(item) {
30100
30258
  ];
30101
30259
  });
30102
30260
  }
30261
+ function projectUserMessage(item, clientId) {
30262
+ return {
30263
+ id: item.itemId,
30264
+ type: "userMessage",
30265
+ clientId,
30266
+ content: item.input.map(({ text }) => ({ type: "text", text, text_elements: [] }))
30267
+ };
30268
+ }
30103
30269
  function projectItem(item, outcome, defaultCwd, includeCommandOutput = true) {
30104
30270
  switch (item.type) {
30271
+ case "userMessage":
30272
+ return projectUserMessage(item, null);
30105
30273
  case "agentMessage":
30106
30274
  return {
30107
30275
  id: item.itemId,
@@ -30307,6 +30475,7 @@ var CodexTurnProjector = class {
30307
30475
  #interactions = /* @__PURE__ */ new Map();
30308
30476
  #items = /* @__PURE__ */ new Map();
30309
30477
  #wireItemOrder = [];
30478
+ #userMessageClientIds = /* @__PURE__ */ new Map();
30310
30479
  #startedAt;
30311
30480
  #startedAtMs;
30312
30481
  #threadId;
@@ -30348,6 +30517,10 @@ var CodexTurnProjector = class {
30348
30517
  }
30349
30518
  return items;
30350
30519
  }
30520
+ /** Associate steered input with the Desktop message that submitted it, before it is published. */
30521
+ bindUserMessageClientId(itemId, clientId) {
30522
+ this.#userMessageClientIds.set(itemId, clientId);
30523
+ }
30351
30524
  pendingTurn(startedAt = null) {
30352
30525
  return {
30353
30526
  id: this.#turnId,
@@ -30358,6 +30531,8 @@ var CodexTurnProjector = class {
30358
30531
  const projected = this.#items.get(itemId);
30359
30532
  if (!projected?.wireStarted)
30360
30533
  return [];
30534
+ if (projected.item.type === "userMessage")
30535
+ return [this.#projectItem(projected.item)];
30361
30536
  if (projected.item.type === "agentMessage") {
30362
30537
  return [projectItem(projected.item, projected.outcome, this.#cwd)];
30363
30538
  }
@@ -30690,7 +30865,7 @@ var CodexTurnProjector = class {
30690
30865
  };
30691
30866
  }
30692
30867
  const messages = [
30693
- completedItem(projectItem(projected.item, projected.outcome, this.#cwd, !projected.streamedCommandOutput))
30868
+ completedItem(this.#projectItem(projected.item, projected.outcome, !projected.streamedCommandOutput))
30694
30869
  ];
30695
30870
  if (projected.item.type === "reasoning") {
30696
30871
  const reasoning = projected.item;
@@ -30755,6 +30930,8 @@ var CodexTurnProjector = class {
30755
30930
  projectReasoningTranscriptItem(reasoning, projected.outcome, this.#cwd, projected.durationMs ?? null)
30756
30931
  ];
30757
30932
  }
30933
+ if (projected.item.type === "userMessage")
30934
+ return [this.#projectItem(projected.item)];
30758
30935
  if (projected.item.type === "agentMessage") {
30759
30936
  return [projectItem(projected.item, projected.outcome, this.#cwd)];
30760
30937
  }
@@ -30853,10 +31030,13 @@ var CodexTurnProjector = class {
30853
31030
  threadId: this.#threadId,
30854
31031
  turnId: this.#turnId,
30855
31032
  startedAtMs,
30856
- item: projectItem(item, null, this.#cwd)
31033
+ item: this.#projectItem(item, null)
30857
31034
  }
30858
31035
  };
30859
31036
  }
31037
+ #projectItem(item, outcome = null, includeCommandOutput = true) {
31038
+ return item.type === "userMessage" ? projectUserMessage(item, this.#userMessageClientIds.get(item.itemId) ?? null) : projectItem(item, outcome, this.#cwd, includeCommandOutput);
31039
+ }
30860
31040
  #startReasoningTranscript(item, startedAtMs) {
30861
31041
  return {
30862
31042
  method: "item/started",
@@ -32008,7 +32188,7 @@ var AccountRateLimits = class {
32008
32188
  };
32009
32189
 
32010
32190
  // packages/host-runtime/src/native-account-observer.ts
32011
- var object6 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
32191
+ var object7 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
32012
32192
  var NativeAccountObserver = class {
32013
32193
  constructor(input) {
32014
32194
  this.input = input;
@@ -32031,7 +32211,7 @@ var NativeAccountObserver = class {
32031
32211
  }
32032
32212
  /** Called after forwarding the native frame. Identity read failure cannot alter its outcome. */
32033
32213
  observe(value2) {
32034
- if (!object6(value2) || value2.method !== "account/updated" && value2.method !== "account/login/completed" || !this.input.control.refresh || !this.#ready())
32214
+ if (!object7(value2) || value2.method !== "account/updated" && value2.method !== "account/login/completed" || !this.input.control.refresh || !this.#ready())
32035
32215
  return;
32036
32216
  this.#collectRequested = true;
32037
32217
  if (this.#collecting) return;
@@ -32070,13 +32250,13 @@ var NativeAccountObserver = class {
32070
32250
  const generation = scope.owner.generation;
32071
32251
  this.#lastGeneration = generation;
32072
32252
  const response = await scope.owner.controlRequest("account/read", { refreshToken: false });
32073
- if (response.error || !object6(response.result))
32253
+ if (response.error || !object7(response.result))
32074
32254
  throw new Error("Invalid native Account response");
32075
32255
  const account = response.result.account;
32076
32256
  let params;
32077
32257
  if (account === null) params = { authMode: null, planType: null };
32078
32258
  else {
32079
- if (!object6(account) || account.type !== "chatgpt")
32259
+ if (!object7(account) || account.type !== "chatgpt")
32080
32260
  throw new Error("Invalid native Account response");
32081
32261
  params = {
32082
32262
  authMode: "chatgpt",
@@ -32248,7 +32428,7 @@ var HarnessAccountInspectionCache = class {
32248
32428
  };
32249
32429
 
32250
32430
  // packages/host-runtime/src/app-server-host.ts
32251
- import { createHash as createHash9, randomUUID as randomUUID16 } from "node:crypto";
32431
+ import { createHash as createHash9, randomUUID as randomUUID19 } from "node:crypto";
32252
32432
  import os9 from "node:os";
32253
32433
  import path28 from "node:path";
32254
32434
 
@@ -32256,12 +32436,12 @@ import path28 from "node:path";
32256
32436
  import nodePath from "node:path";
32257
32437
 
32258
32438
  // packages/host-runtime/src/external-thread-repository.ts
32259
- import { randomUUID as randomUUID12 } from "node:crypto";
32439
+ import { randomUUID as randomUUID13 } from "node:crypto";
32260
32440
  import os8 from "node:os";
32261
32441
  import path25 from "node:path";
32262
32442
 
32263
32443
  // packages/host-runtime/src/external-subagent-threads.ts
32264
- import { createHash as createHash6, randomUUID as randomUUID11 } from "node:crypto";
32444
+ import { createHash as createHash6, randomUUID as randomUUID12 } from "node:crypto";
32265
32445
  function childCreateRequest(parent, nativeRef, id2) {
32266
32446
  const key = createHash6("sha256").update(JSON.stringify([parent.hostThreadId, parent.harnessId, nativeRef.nativeSessionId, id2])).digest("hex");
32267
32447
  return `subagent:${key}`;
@@ -32343,7 +32523,7 @@ function subagentMaterializer(store, parent, previousParent) {
32343
32523
  return configured(await rebind(existing, parent));
32344
32524
  }
32345
32525
  const provisional = existing ?? await store.createProvisional({
32346
- hostThreadId: hostThreadIdSchema.parse(randomUUID11()),
32526
+ hostThreadId: hostThreadIdSchema.parse(randomUUID12()),
32347
32527
  createRequestId,
32348
32528
  harnessId: parent.harnessId,
32349
32529
  cwd: parent.cwd,
@@ -32386,14 +32566,13 @@ async function projectExternalSnapshot(store, record4, snapshot2, previousParent
32386
32566
  return { ...entry, item: { ...entry.item, subagents } };
32387
32567
  })
32388
32568
  );
32389
- turns.push(
32390
- projectHistoricalTurn({
32391
- threadId: record4.hostThreadId,
32392
- turnId: mapping.hostTurnId,
32393
- cwd: record4.cwd,
32394
- snapshot: { ...turn, items }
32395
- })
32396
- );
32569
+ const projected = projectHistoricalTurn({
32570
+ threadId: record4.hostThreadId,
32571
+ turnId: mapping.hostTurnId,
32572
+ cwd: record4.cwd,
32573
+ snapshot: { ...turn, items }
32574
+ });
32575
+ turns.push(mapping.realtimeInline ? presentExternalVoiceTurn(projected) : projected);
32397
32576
  }
32398
32577
  return turns;
32399
32578
  }
@@ -32497,7 +32676,7 @@ var ExternalThreadRepository = class {
32497
32676
  removeThread(hostThreadId) {
32498
32677
  return this.store.removeThread(hostThreadId);
32499
32678
  }
32500
- async persistTurn(record4, hostTurnId, nativeTurnRef, nativeCheckpointRef) {
32679
+ async persistTurn(record4, hostTurnId, nativeTurnRef, nativeCheckpointRef, realtimeInline) {
32501
32680
  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)) {
32502
32681
  throw new Error("Live Turn identity does not belong to the stored Thread");
32503
32682
  }
@@ -32505,7 +32684,8 @@ var ExternalThreadRepository = class {
32505
32684
  {
32506
32685
  hostTurnId,
32507
32686
  nativeTurnRef,
32508
- ...nativeCheckpointRef ? { nativeCheckpointRef } : {}
32687
+ ...nativeCheckpointRef ? { nativeCheckpointRef } : {},
32688
+ ...realtimeInline ? { realtimeInline } : {}
32509
32689
  }
32510
32690
  ]);
32511
32691
  }
@@ -32518,7 +32698,7 @@ var ExternalThreadRepository = class {
32518
32698
  throw new Error("Derived Snapshot identity does not belong to its Native Session");
32519
32699
  }
32520
32700
  return {
32521
- hostTurnId: hostTurnIdSchema.parse(randomUUID12()),
32701
+ hostTurnId: hostTurnIdSchema.parse(randomUUID13()),
32522
32702
  nativeTurnRef: turn.nativeTurnRef,
32523
32703
  ...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
32524
32704
  };
@@ -32558,6 +32738,7 @@ var ExternalThreadRepository = class {
32558
32738
  }
32559
32739
  return {
32560
32740
  hostTurnId: previous.hostTurnId,
32741
+ ...previous.realtimeInline ? { realtimeInline: true } : {},
32561
32742
  nativeTurnRef: turn.nativeTurnRef,
32562
32743
  ...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
32563
32744
  };
@@ -32589,6 +32770,7 @@ var ExternalThreadRepository = class {
32589
32770
  }
32590
32771
  return {
32591
32772
  hostTurnId: previous.hostTurnId,
32773
+ ...previous.realtimeInline ? { realtimeInline: true } : {},
32592
32774
  nativeTurnRef: turn.nativeTurnRef,
32593
32775
  ...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
32594
32776
  };
@@ -32641,14 +32823,15 @@ var ExternalThreadRepository = class {
32641
32823
  const aligned = snapshot2.turns.map((turn) => {
32642
32824
  const existing = mappingsByNative.get(nativeTurnKey2(turn.nativeTurnRef));
32643
32825
  const mapping = existing ?? {
32644
- hostTurnId: hostTurnIdSchema.parse(randomUUID12()),
32826
+ hostTurnId: hostTurnIdSchema.parse(randomUUID13()),
32645
32827
  nativeTurnRef: turn.nativeTurnRef,
32646
32828
  ...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
32647
32829
  };
32648
32830
  return {
32649
32831
  snapshot: turn,
32650
32832
  mapping: {
32651
- ...mapping,
32833
+ hostTurnId: mapping.hostTurnId,
32834
+ ...mapping.realtimeInline ? { realtimeInline: true } : {},
32652
32835
  nativeTurnRef: turn.nativeTurnRef,
32653
32836
  ...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
32654
32837
  }
@@ -32668,8 +32851,8 @@ var ExternalThreadRepository = class {
32668
32851
  };
32669
32852
  function createExternalThreadRecordInput(input) {
32670
32853
  return {
32671
- hostThreadId: input.hostThreadId ?? hostThreadIdSchema.parse(randomUUID12()),
32672
- createRequestId: input.createRequestId ?? randomUUID12(),
32854
+ hostThreadId: input.hostThreadId ?? hostThreadIdSchema.parse(randomUUID13()),
32855
+ createRequestId: input.createRequestId ?? randomUUID13(),
32673
32856
  harnessId: input.harnessId,
32674
32857
  cwd: input.cwd,
32675
32858
  ...input.title ? { title: input.title } : {},
@@ -32791,6 +32974,15 @@ async function executeExternalThreadFork(input) {
32791
32974
  boundaryIndex = mappings.length - 1;
32792
32975
  }
32793
32976
  const boundary = mappings[boundaryIndex];
32977
+ if (boundary && source.steeredTurnIds.has(boundary.hostTurnId)) {
32978
+ return {
32979
+ ok: false,
32980
+ error: {
32981
+ code: -32080,
32982
+ message: "This Turn took steered input; reopen the Thread before forking from it"
32983
+ }
32984
+ };
32985
+ }
32794
32986
  if (boundaryIndex < 0 || !boundary?.nativeCheckpointRef) {
32795
32987
  return {
32796
32988
  ok: false,
@@ -33547,6 +33739,16 @@ async function executeExternalThreadRollback(input) {
33547
33739
  if (derived.running) {
33548
33740
  return { ok: false, error: { code: -32072, message: "External Thread has an active Turn" } };
33549
33741
  }
33742
+ const undone = derived.record.turnMappings.slice(-rollback.numTurns);
33743
+ if (undone.some((mapping) => derived.steeredTurnIds.has(mapping.hostTurnId))) {
33744
+ return {
33745
+ ok: false,
33746
+ error: {
33747
+ code: -32080,
33748
+ message: "A Turn here took steered input; reopen the Thread before undoing Turns"
33749
+ }
33750
+ };
33751
+ }
33550
33752
  const refreshError = await runtime.refresh(derived);
33551
33753
  if (refreshError) return { ok: false, error: refreshError };
33552
33754
  if (expectedLastTurnId !== void 0 && derived.record.turnMappings.at(-1)?.hostTurnId !== expectedLastTurnId) {
@@ -34346,6 +34548,7 @@ var ExternalThreadRuntime = class {
34346
34548
  #repository;
34347
34549
  #lifecycle = new ExternalThreadLifecycle();
34348
34550
  #hasRunningDescendants;
34551
+ #steeredTurnIds = /* @__PURE__ */ new Map();
34349
34552
  #subagentRunning;
34350
34553
  #threads = /* @__PURE__ */ new Map();
34351
34554
  constructor(input) {
@@ -34359,7 +34562,8 @@ var ExternalThreadRuntime = class {
34359
34562
  this.idleRelease = new ExternalThreadIdleRelease({
34360
34563
  threads: () => this.values(),
34361
34564
  get: (id2) => this.get(id2),
34362
- remove: (id2) => this.remove(id2),
34565
+ // Idle release detaches only the Native Session. Host Thread state survives restoration.
34566
+ remove: (id2) => this.#detach(id2),
34363
34567
  queue: input.idleRelease?.queue ?? new DesktopRequestQueue(),
34364
34568
  canRelease: (thread) => !thread.sessionUnavailable && !this.#lifecycle.busy(thread.id) && (input.idleRelease?.canRelease(thread) ?? false),
34365
34569
  ...input.idleRelease?.onClosed ? { onClosed: input.idleRelease.onClosed } : {},
@@ -34369,14 +34573,21 @@ var ExternalThreadRuntime = class {
34369
34573
  get(threadId2) {
34370
34574
  return this.#threads.get(threadId2);
34371
34575
  }
34576
+ #detach(threadId2) {
34577
+ const thread = this.#threads.get(threadId2);
34578
+ this.#threads.delete(threadId2);
34579
+ if (!thread || thread.steeredTurnIds.size === 0) this.#steeredTurnIds.delete(threadId2);
34580
+ }
34372
34581
  values() {
34373
34582
  return [...this.#threads.values()];
34374
34583
  }
34375
34584
  remove(threadId2) {
34376
34585
  this.#threads.delete(threadId2);
34586
+ this.#steeredTurnIds.delete(threadId2);
34377
34587
  }
34378
34588
  clear() {
34379
34589
  this.#threads.clear();
34590
+ this.#steeredTurnIds.clear();
34380
34591
  }
34381
34592
  drain() {
34382
34593
  return this.#lifecycle.drain();
@@ -34433,6 +34644,11 @@ var ExternalThreadRuntime = class {
34433
34644
  ...effectivePermissionModeId ? { effectivePermissionModeId } : {}
34434
34645
  };
34435
34646
  const running = this.#subagentRunning(input.record.hostThreadId);
34647
+ let steeredTurnIds = this.#steeredTurnIds.get(input.record.hostThreadId);
34648
+ if (!steeredTurnIds) {
34649
+ steeredTurnIds = /* @__PURE__ */ new Set();
34650
+ this.#steeredTurnIds.set(input.record.hostThreadId, steeredTurnIds);
34651
+ }
34436
34652
  const externalThread = {
34437
34653
  id: input.record.hostThreadId,
34438
34654
  cwd: input.record.cwd,
@@ -34457,11 +34673,13 @@ var ExternalThreadRuntime = class {
34457
34673
  usageTurnId: null,
34458
34674
  projectedTurns: /* @__PURE__ */ new Map(),
34459
34675
  responseGates: /* @__PURE__ */ new Map(),
34676
+ pendingSteerProjections: /* @__PURE__ */ new Set(),
34460
34677
  ephemeralTurnIds: /* @__PURE__ */ new Set(),
34461
34678
  persistenceError: null,
34462
34679
  projectedTerminalTurnId: null,
34463
34680
  ignoredInteractionIds: /* @__PURE__ */ new Set(),
34464
- sessionUnavailable: false
34681
+ sessionUnavailable: false,
34682
+ steeredTurnIds
34465
34683
  };
34466
34684
  this.idleRelease.touch(externalThread);
34467
34685
  externalThread.outputTask = this.#consumeOutputs(externalThread);
@@ -34518,13 +34736,13 @@ var ExternalThreadRuntime = class {
34518
34736
  const retire = async () => {
34519
34737
  if (this.#threads.get(parentId) !== parent || this.#threads.get(child.id) !== child) return;
34520
34738
  if (bestEffort) {
34521
- this.#threads.delete(child.id);
34739
+ this.remove(child.id);
34522
34740
  await child.session.close();
34523
34741
  await child.outputTask;
34524
34742
  } else {
34525
34743
  child.sessionUnavailable = true;
34526
34744
  await this.#lifecycle.release(child.id, child.session, child.outputTask);
34527
- if (this.#threads.get(child.id) === child) this.#threads.delete(child.id);
34745
+ if (this.#threads.get(child.id) === child) this.remove(child.id);
34528
34746
  }
34529
34747
  };
34530
34748
  if (bestEffort) await retire().catch(this.#diagnose);
@@ -34761,7 +34979,8 @@ var ExternalThreadRuntime = class {
34761
34979
  thread.record,
34762
34980
  event.turnId,
34763
34981
  event.nativeTurnRef,
34764
- event.outcome.checkpoint
34982
+ event.outcome.checkpoint,
34983
+ thread.projectedTurns.get(event.turnId)?.realtimeInline
34765
34984
  );
34766
34985
  return null;
34767
34986
  } catch (error51) {
@@ -34897,6 +35116,71 @@ var ExternalThreadRuntime = class {
34897
35116
  };
34898
35117
 
34899
35118
  // packages/host-runtime/src/external-turn-steering.ts
35119
+ import { randomUUID as randomUUID14 } from "node:crypto";
35120
+
35121
+ // packages/host-runtime/src/external-command-routing.ts
35122
+ var ExternalCommandError = class extends Error {
35123
+ constructor(code, message2) {
35124
+ super(message2);
35125
+ this.code = code;
35126
+ }
35127
+ code;
35128
+ };
35129
+ function isExternalCommandCandidate(text) {
35130
+ return /^\/[^\s/]+(?:\s|$)/u.test(text.trimStart());
35131
+ }
35132
+ async function inspectLiveCommandCatalog(commands, timeoutMs = 1e3) {
35133
+ let timeout;
35134
+ try {
35135
+ const result = await Promise.race([
35136
+ commands.list(),
35137
+ new Promise((resolve) => {
35138
+ timeout = setTimeout(() => resolve(null), timeoutMs);
35139
+ })
35140
+ ]);
35141
+ return result?.ok ? harnessCommandCatalogSchema.parse(result.value) : null;
35142
+ } catch {
35143
+ return null;
35144
+ } finally {
35145
+ if (timeout !== void 0) clearTimeout(timeout);
35146
+ }
35147
+ }
35148
+ async function resolveExternalCommand(commands, text, options2 = {}) {
35149
+ const catalog = await commands.list();
35150
+ if (!catalog.ok) throw new ExternalCommandError(-32073, catalog.error.message);
35151
+ const commandText = text.trim();
35152
+ const matched = catalog.value.commands.toSorted((left, right) => right.invocation.length - left.invocation.length).find((command) => {
35153
+ if (commandText === command.invocation) return true;
35154
+ return command.argumentMode === "text" && commandText.startsWith(`${command.invocation} `);
35155
+ });
35156
+ if (!matched) {
35157
+ const name = /^\/(\S+)/u.exec(commandText)?.[1] ?? "";
35158
+ if (name && !isExcludedLiveCommand(name, "command") && options2.liveCatalogPending?.(catalog.value)) {
35159
+ return null;
35160
+ }
35161
+ throw new ExternalCommandError(
35162
+ -32078,
35163
+ "External Harness does not expose the requested command"
35164
+ );
35165
+ }
35166
+ const argumentText = commandText.slice(matched.invocation.length).trimStart();
35167
+ return {
35168
+ descriptor: matched,
35169
+ ...argumentText.length > 0 ? { arguments: { text: argumentText } } : {}
35170
+ };
35171
+ }
35172
+
35173
+ // packages/host-runtime/src/external-turn-steering.ts
35174
+ function isHarnessCommand(thread, text) {
35175
+ return thread.session.commands !== void 0 && isExternalCommandCandidate(restoreHarnessCommandMentions(text));
35176
+ }
35177
+ function externalSteeringDelivery(thread, text) {
35178
+ if (text !== void 0 && isHarnessCommand(thread, text)) return "newTurn";
35179
+ if (thread.session.readCapabilities) {
35180
+ return thread.session.readCapabilities().then((capabilities) => capabilities.steer === true ? "activeTurn" : "newTurn");
35181
+ }
35182
+ return thread.session.capabilities.steer === true ? "activeTurn" : "newTurn";
35183
+ }
34900
35184
  var ExternalSteerError = class extends Error {
34901
35185
  constructor(code, message2) {
34902
35186
  super(message2);
@@ -34904,6 +35188,11 @@ var ExternalSteerError = class extends Error {
34904
35188
  }
34905
35189
  code;
34906
35190
  };
35191
+ var ExternalSteerNotTakenError = class extends ExternalSteerError {
35192
+ constructor(message2) {
35193
+ super(-32074, message2);
35194
+ }
35195
+ };
34907
35196
  function parseInput(params) {
34908
35197
  if (typeof params.expectedTurnId !== "string" || !params.expectedTurnId.trim()) {
34909
35198
  throw new ExternalSteerError(-32602, "External steering requires expectedTurnId");
@@ -34920,12 +35209,47 @@ function parseInput(params) {
34920
35209
  if (clientUserMessageId != null && (typeof clientUserMessageId !== "string" || !clientUserMessageId.trim())) {
34921
35210
  throw new ExternalSteerError(-32602, "External steering message identity is invalid");
34922
35211
  }
35212
+ const delivery = params[THREAD_STEER_DELIVERY_PARAM];
35213
+ const parsedDelivery = delivery == null ? void 0 : threadSteerDeliverySchema.safeParse(delivery);
35214
+ if (parsedDelivery && !parsedDelivery.success) {
35215
+ throw new ExternalSteerError(-32602, "External steering delivery is invalid");
35216
+ }
34923
35217
  return {
34924
35218
  expectedTurnId: params.expectedTurnId,
34925
35219
  text,
34926
- ...typeof clientUserMessageId === "string" ? { clientUserMessageId } : {}
35220
+ ...typeof clientUserMessageId === "string" ? { clientUserMessageId } : {},
35221
+ ...parsedDelivery ? { delivery: parsedDelivery.data } : {}
34927
35222
  };
34928
35223
  }
35224
+ async function insertNativeSteer(thread, input, host) {
35225
+ const restored = restoreHarnessCommandMentions(input.text);
35226
+ const steered = [{ type: "text", text: rewriteDelegationMentionText(restored) }];
35227
+ const displayed = [{ type: "text", text: restored }];
35228
+ const projectionDone = Promise.withResolvers();
35229
+ thread.pendingSteerProjections.add(projectionDone.promise);
35230
+ try {
35231
+ const result = await thread.session.execute({
35232
+ type: "turn.steer",
35233
+ turnId: input.turnId,
35234
+ input: steered
35235
+ });
35236
+ if (!result.ok) throw new ExternalSteerNotTakenError(result.error.message);
35237
+ thread.steeredTurnIds.add(input.turnId);
35238
+ const item = {
35239
+ type: "userMessage",
35240
+ itemId: hostItemIdSchema.parse(randomUUID14()),
35241
+ input: displayed
35242
+ };
35243
+ try {
35244
+ await host.project(input.turnId, item, input.clientUserMessageId);
35245
+ } catch (error51) {
35246
+ host.diagnose(error51);
35247
+ }
35248
+ } finally {
35249
+ projectionDone.resolve(void 0);
35250
+ thread.pendingSteerProjections.delete(projectionDone.promise);
35251
+ }
35252
+ }
34929
35253
  var ExternalTurnSteering = class {
34930
35254
  constructor(timeoutMs = 2e4) {
34931
35255
  this.timeoutMs = timeoutMs;
@@ -34937,7 +35261,7 @@ var ExternalTurnSteering = class {
34937
35261
  hasPending(threadId2) {
34938
35262
  return threadId2 === void 0 ? this.#pending.size > 0 : this.#pending.has(threadId2);
34939
35263
  }
34940
- run(thread, params, start) {
35264
+ run(thread, params, start, insert) {
34941
35265
  try {
34942
35266
  const input = parseInput(params);
34943
35267
  if (this.#closed)
@@ -34959,7 +35283,7 @@ var ExternalTurnSteering = class {
34959
35283
  if (!thread.running || thread.activeTurnId !== input.expectedTurnId) {
34960
35284
  throw new ExternalSteerError(-32074, "External steering must reference the active Turn");
34961
35285
  }
34962
- const result = this.#replace(thread, input, start);
35286
+ const result = this.#deliver(thread, input, start, insert);
34963
35287
  if (key) {
34964
35288
  const receipt2 = { fingerprint, result, settled: false };
34965
35289
  this.#receipts.set(key, receipt2);
@@ -34982,6 +35306,56 @@ var ExternalTurnSteering = class {
34982
35306
  return Promise.reject(error51);
34983
35307
  }
34984
35308
  }
35309
+ /**
35310
+ * A Renderer that already presented a delivery gets exactly that one. Otherwise native delivery
35311
+ * is tried only when the Session can take the input now, and input the Harness did not take
35312
+ * falls back to stopping and restarting, so no case is worse than the stop-then-start path.
35313
+ */
35314
+ #deliver(thread, input, start, insert) {
35315
+ const delivery = input.delivery === "newTurn" || isHarnessCommand(thread, input.text) ? "newTurn" : input.delivery ?? externalSteeringDelivery(thread);
35316
+ const deliver = (mode) => {
35317
+ if (this.#closed || !thread.running || thread.activeTurnId !== input.expectedTurnId) {
35318
+ throw new ExternalSteerError(-32074, "External steering target is no longer active");
35319
+ }
35320
+ if (this.hasPending(thread.id))
35321
+ throw new ExternalSteerError(-32072, "External Thread is already changing direction");
35322
+ if (mode === "newTurn") return this.#replace(thread, input, start);
35323
+ const native = insert({
35324
+ turnId: thread.activeTurnId,
35325
+ text: input.text,
35326
+ ...input.clientUserMessageId ? { clientUserMessageId: input.clientUserMessageId } : {}
35327
+ }).then((admitted) => ({ ...admitted, delivery: "activeTurn" }));
35328
+ if (input.delivery === "activeTurn") return native;
35329
+ return native.catch(async (error51) => {
35330
+ if (!(error51 instanceof ExternalSteerNotTakenError)) throw error51;
35331
+ if (thread.running || thread.activeTurnId) return deliver("newTurn");
35332
+ const assertActive = () => {
35333
+ if (this.#closed)
35334
+ throw new ExternalSteerError(-32074, "External steering connection is closed");
35335
+ };
35336
+ return { ...await start(input.text, assertActive), delivery: "newTurn" };
35337
+ });
35338
+ };
35339
+ if (typeof delivery === "string") return deliver(delivery);
35340
+ const failure = Promise.withResolvers();
35341
+ let failureReason = null;
35342
+ const pending = {
35343
+ turnId: input.expectedTurnId,
35344
+ resolve: () => void 0,
35345
+ reject(error51) {
35346
+ failureReason ??= error51;
35347
+ failure.reject(error51);
35348
+ }
35349
+ };
35350
+ this.#pending.set(thread.id, pending);
35351
+ return Promise.race([delivery, failure.promise]).then((mode) => {
35352
+ if (failureReason) throw failureReason;
35353
+ if (this.#pending.get(thread.id) === pending) this.#pending.delete(thread.id);
35354
+ return deliver(mode);
35355
+ }).finally(() => {
35356
+ if (this.#pending.get(thread.id) === pending) this.#pending.delete(thread.id);
35357
+ });
35358
+ }
34985
35359
  terminal(threadId2, turnId, outcome) {
34986
35360
  const pending = this.#pending.get(threadId2);
34987
35361
  if (pending?.turnId === turnId) pending.resolve(outcome);
@@ -35036,7 +35410,9 @@ var ExternalTurnSteering = class {
35036
35410
  thread.session.execute({ type: "turn.cancel", turnId }),
35037
35411
  failure.promise
35038
35412
  ]);
35039
- if (!cancelled.ok) throw new ExternalSteerError(-32074, cancelled.error.message);
35413
+ if (!cancelled.ok && cancelled.error.code !== "invalidState") {
35414
+ throw new ExternalSteerError(-32074, cancelled.error.message);
35415
+ }
35040
35416
  const outcome = await Promise.race([terminal3.promise, failure.promise]);
35041
35417
  clearTimeout(timeout);
35042
35418
  const assertActive = () => {
@@ -35054,7 +35430,7 @@ var ExternalTurnSteering = class {
35054
35430
  if (thread.running || thread.activeTurnId) {
35055
35431
  throw new ExternalSteerError(-32072, "Another External Turn started before replacement");
35056
35432
  }
35057
- return await start(input.text, assertActive);
35433
+ return { ...await start(input.text, assertActive), delivery: "newTurn" };
35058
35434
  } finally {
35059
35435
  clearTimeout(timeout);
35060
35436
  if (this.#pending.get(thread.id) === pending) this.#pending.delete(thread.id);
@@ -35062,58 +35438,6 @@ var ExternalTurnSteering = class {
35062
35438
  }
35063
35439
  };
35064
35440
 
35065
- // packages/host-runtime/src/external-command-routing.ts
35066
- var ExternalCommandError = class extends Error {
35067
- constructor(code, message2) {
35068
- super(message2);
35069
- this.code = code;
35070
- }
35071
- code;
35072
- };
35073
- function isExternalCommandCandidate(text) {
35074
- return /^\/[^\s/]+(?:\s|$)/u.test(text.trimStart());
35075
- }
35076
- async function inspectLiveCommandCatalog(commands, timeoutMs = 1e3) {
35077
- let timeout;
35078
- try {
35079
- const result = await Promise.race([
35080
- commands.list(),
35081
- new Promise((resolve) => {
35082
- timeout = setTimeout(() => resolve(null), timeoutMs);
35083
- })
35084
- ]);
35085
- return result?.ok ? harnessCommandCatalogSchema.parse(result.value) : null;
35086
- } catch {
35087
- return null;
35088
- } finally {
35089
- if (timeout !== void 0) clearTimeout(timeout);
35090
- }
35091
- }
35092
- async function resolveExternalCommand(commands, text, options2 = {}) {
35093
- const catalog = await commands.list();
35094
- if (!catalog.ok) throw new ExternalCommandError(-32073, catalog.error.message);
35095
- const commandText = text.trim();
35096
- const matched = catalog.value.commands.toSorted((left, right) => right.invocation.length - left.invocation.length).find((command) => {
35097
- if (commandText === command.invocation) return true;
35098
- return command.argumentMode === "text" && commandText.startsWith(`${command.invocation} `);
35099
- });
35100
- if (!matched) {
35101
- const name = /^\/(\S+)/u.exec(commandText)?.[1] ?? "";
35102
- if (name && !isExcludedLiveCommand(name, "command") && options2.liveCatalogPending?.(catalog.value)) {
35103
- return null;
35104
- }
35105
- throw new ExternalCommandError(
35106
- -32078,
35107
- "External Harness does not expose the requested command"
35108
- );
35109
- }
35110
- const argumentText = commandText.slice(matched.invocation.length).trimStart();
35111
- return {
35112
- descriptor: matched,
35113
- ...argumentText.length > 0 ? { arguments: { text: argumentText } } : {}
35114
- };
35115
- }
35116
-
35117
35441
  // packages/host-runtime/src/live-command-catalog-cache.ts
35118
35442
  import path26 from "node:path";
35119
35443
  var MAX_ENTRIES = 64;
@@ -35145,7 +35469,7 @@ function sameWorkspace(left, right) {
35145
35469
  }
35146
35470
 
35147
35471
  // packages/host-runtime/src/harness-delegation-coordinator.ts
35148
- import { createHash as createHash8, randomUUID as randomUUID13 } from "node:crypto";
35472
+ import { createHash as createHash8, randomUUID as randomUUID15 } from "node:crypto";
35149
35473
  import path27 from "node:path";
35150
35474
 
35151
35475
  // packages/host-runtime/src/delegation-snapshot.ts
@@ -35449,10 +35773,10 @@ var HarnessDelegationCoordinator = class {
35449
35773
  });
35450
35774
  this.#validateConfiguration(inspected.inspection, input.model, input.thinkingOptionId);
35451
35775
  }
35452
- const delegationId = hostThreadIdSchema.parse(randomUUID13());
35453
- const childThreadId = hostThreadIdSchema.parse(randomUUID13());
35454
- const turnId = hostTurnIdSchema.parse(randomUUID13());
35455
- const createRequestId = input.requestId ? `delegation:${input.requestId}` : randomUUID13();
35776
+ const delegationId = hostThreadIdSchema.parse(randomUUID15());
35777
+ const childThreadId = hostThreadIdSchema.parse(randomUUID15());
35778
+ const turnId = hostTurnIdSchema.parse(randomUUID15());
35779
+ const createRequestId = input.requestId ? `delegation:${input.requestId}` : randomUUID15();
35456
35780
  let record4 = await this.#repository.createProvisional(
35457
35781
  createExternalThreadRecordInput({
35458
35782
  hostThreadId: childThreadId,
@@ -35606,7 +35930,7 @@ var HarnessDelegationCoordinator = class {
35606
35930
  if (this.#externalThreadBusy(thread) || thread.activeTurnId) {
35607
35931
  throw new DelegationControlError("THREAD_BUSY", "Thread already has an active Turn");
35608
35932
  }
35609
- const turnId = hostTurnIdSchema.parse(randomUUID13());
35933
+ const turnId = hostTurnIdSchema.parse(randomUUID15());
35610
35934
  try {
35611
35935
  await this.#startExternalTurn(thread, input.message, turnId);
35612
35936
  } catch (error51) {
@@ -35880,8 +36204,8 @@ import { pathToFileURL } from "node:url";
35880
36204
  function isNullable(value2) {
35881
36205
  return value2 === null || value2 === void 0;
35882
36206
  }
35883
- function defineProperty(object9, key, value2) {
35884
- return Object.defineProperty(object9, key, {
36207
+ function defineProperty(object10, key, value2) {
36208
+ return Object.defineProperty(object10, key, {
35885
36209
  writable: true,
35886
36210
  value: value2,
35887
36211
  enumerable: false
@@ -37420,8 +37744,8 @@ var Fiber = class {
37420
37744
  });
37421
37745
  }
37422
37746
  };
37423
- function isApplicable(object9) {
37424
- return object9 && typeof object9 === "object" && typeof object9.apply === "function";
37747
+ function isApplicable(object10) {
37748
+ return object10 && typeof object10 === "object" && typeof object10.apply === "function";
37425
37749
  }
37426
37750
  function Inject(name, config2) {
37427
37751
  return function(value2, decorator) {
@@ -38256,10 +38580,10 @@ var SingleNativeCodexAccount = class {
38256
38580
  };
38257
38581
 
38258
38582
  // packages/host-runtime/src/codex-runtime/official-runtime-owner.ts
38259
- import { randomUUID as randomUUID15 } from "node:crypto";
38583
+ import { randomUUID as randomUUID17 } from "node:crypto";
38260
38584
 
38261
38585
  // packages/host-runtime/src/official-request-broker.ts
38262
- import { randomUUID as randomUUID14 } from "node:crypto";
38586
+ import { randomUUID as randomUUID16 } from "node:crypto";
38263
38587
  var INTERNAL_REQUEST_PREFIX = "codexhost:official:";
38264
38588
  var MAX_RETIRED_IDS = 1024;
38265
38589
  function isRecord17(value2) {
@@ -38275,7 +38599,7 @@ var OfficialRequestBroker = class {
38275
38599
  constructor(input) {
38276
38600
  this.#send = input.send;
38277
38601
  this.#timeoutMs = input.timeoutMs ?? 3e4;
38278
- this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${randomUUID14()}`);
38602
+ this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${randomUUID16()}`);
38279
38603
  }
38280
38604
  get pendingCount() {
38281
38605
  return this.#pending.size;
@@ -38484,7 +38808,7 @@ var OfficialWorkGate = class {
38484
38808
  };
38485
38809
 
38486
38810
  // packages/host-runtime/src/codex-runtime/official-runtime-owner.ts
38487
- var object7 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
38811
+ var object8 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
38488
38812
  var requestKey = (id2) => JSON.stringify([typeof id2, id2]);
38489
38813
  var RESUME_FIELDS = /* @__PURE__ */ new Set([
38490
38814
  "model",
@@ -38629,7 +38953,7 @@ var OfficialRuntimeOwner = class {
38629
38953
  }
38630
38954
  #attach(role, output, onBackendStopped) {
38631
38955
  const client = {
38632
- id: randomUUID15(),
38956
+ id: randomUUID17(),
38633
38957
  role,
38634
38958
  output,
38635
38959
  ...onBackendStopped ? { onBackendStopped } : {},
@@ -38749,7 +39073,7 @@ var OfficialRuntimeOwner = class {
38749
39073
  if (value2.method === "initialized") return;
38750
39074
  if (typeof value2.id !== "string" && typeof value2.id !== "number")
38751
39075
  throw new Error("Official methods require a request ID");
38752
- const params = object7(value2.params) ? value2.params : {};
39076
+ const params = object8(value2.params) ? value2.params : {};
38753
39077
  this.#checkMethod(value2.method);
38754
39078
  const finish = this.gate.admit();
38755
39079
  let pendingKey;
@@ -38784,10 +39108,10 @@ var OfficialRuntimeOwner = class {
38784
39108
  if (!this.#clients.has(client) || event.generation !== this.#generation || !["running", "starting"].includes(this.#phase))
38785
39109
  return;
38786
39110
  const value2 = event.value;
38787
- if (!object7(value2)) return client.output(event);
39111
+ if (!object8(value2)) return client.output(event);
38788
39112
  if (typeof value2.id === "string" || typeof value2.id === "number") {
38789
39113
  if (typeof value2.method === "string") {
38790
- const id2 = `codexhost:server:${client.id}:${event.generation}:${randomUUID15()}`;
39114
+ const id2 = `codexhost:server:${client.id}:${event.generation}:${randomUUID17()}`;
38791
39115
  client.serverRequests.set(id2, value2.id);
38792
39116
  const projected = { ...value2, id: id2 };
38793
39117
  return client.output({
@@ -38810,7 +39134,7 @@ var OfficialRuntimeOwner = class {
38810
39134
  if (response.error) return;
38811
39135
  if (["thread/archive", "thread/unsubscribe"].includes(method) && typeof params.threadId === "string")
38812
39136
  client.threads.delete(params.threadId);
38813
- if (!["thread/start", "thread/resume", "thread/fork"].includes(method) || !object7(response.result) || !object7(response.result.thread))
39137
+ if (!["thread/start", "thread/resume", "thread/fork"].includes(method) || !object8(response.result) || !object8(response.result.thread))
38814
39138
  return;
38815
39139
  const id2 = response.result.thread.id;
38816
39140
  if (typeof id2 !== "string") return;
@@ -38832,7 +39156,7 @@ var OfficialRuntimeOwner = class {
38832
39156
  const restoring = (async () => {
38833
39157
  const resume = subscription.params;
38834
39158
  const response = await runtime.request("thread/resume", resume);
38835
- if (response.error || !object7(response.result) || !object7(response.result.thread) || response.result.thread.id !== params.threadId)
39159
+ if (response.error || !object8(response.result) || !object8(response.result.thread) || response.result.thread.id !== params.threadId)
38836
39160
  throw new Error("Official Thread restoration failed");
38837
39161
  if (client.runtime !== runtime || runtime.generation !== this.#generation)
38838
39162
  throw new OfficialAdmissionError("unavailable");
@@ -38980,16 +39304,16 @@ var OfficialRuntimeScope = class {
38980
39304
  #scheduleRecovery() {
38981
39305
  if (!this.#recovery || this.#closed || this.#recoveryTimer || this.#starting) return;
38982
39306
  const { delaysMs } = this.#recovery;
38983
- const delay7 = delaysMs[Math.min(this.#recoveryAttempt, delaysMs.length - 1)] ?? 0;
39307
+ const delay8 = delaysMs[Math.min(this.#recoveryAttempt, delaysMs.length - 1)] ?? 0;
38984
39308
  this.#recoveryAttempt++;
38985
39309
  this.#diagnosticOutput.write(
38986
- `codexhost: official Codex is unavailable; restarting in ${String(delay7)}ms
39310
+ `codexhost: official Codex is unavailable; restarting in ${String(delay8)}ms
38987
39311
  `
38988
39312
  );
38989
39313
  const timer = setTimeout(() => {
38990
39314
  this.#recoveryTimer = void 0;
38991
39315
  this.start().catch(() => void 0);
38992
- }, delay7);
39316
+ }, delay8);
38993
39317
  timer.unref();
38994
39318
  this.#recoveryTimer = timer;
38995
39319
  }
@@ -39739,13 +40063,106 @@ async function moveThreadSection(input) {
39739
40063
  // packages/host-runtime/src/external-thread-official-defaults.ts
39740
40064
  var EMPTY_RESULTS = /* @__PURE__ */ new Map([
39741
40065
  ["thread/attachment/list", () => ({ data: [], nextCursor: null })],
39742
- ["thread/queue/list", () => ({ data: [], nextCursor: null })],
39743
40066
  ["thread/settings/update", () => ({})]
39744
40067
  ]);
39745
40068
  function externalThreadEmptyOfficialResult(method) {
39746
40069
  return EMPTY_RESULTS.get(method)?.();
39747
40070
  }
39748
40071
 
40072
+ // packages/host-runtime/src/external-thread-follow-up-queue.ts
40073
+ import { randomUUID as randomUUID18 } from "node:crypto";
40074
+ function isRecord20(value2) {
40075
+ return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
40076
+ }
40077
+ function queuedSubmissionText(input) {
40078
+ return input.filter(isRecord20).map((item) => item.text).filter((value2) => typeof value2 === "string" && value2.length > 0).join("\n");
40079
+ }
40080
+ function queuedSubmissionInput(input) {
40081
+ return input.map((entry) => {
40082
+ if (!isRecord20(entry) || typeof entry.text !== "string" || entry.text.length === 0) {
40083
+ return entry;
40084
+ }
40085
+ if (entry.type === "input_text") {
40086
+ return {
40087
+ type: "text",
40088
+ text: entry.text,
40089
+ text_elements: Array.isArray(entry.text_elements) ? entry.text_elements : []
40090
+ };
40091
+ }
40092
+ if (entry.type !== "text" || Array.isArray(entry.text_elements)) return entry;
40093
+ return { ...entry, text_elements: [] };
40094
+ });
40095
+ }
40096
+ var ExternalThreadFollowUpQueue = class {
40097
+ #threads = /* @__PURE__ */ new Map();
40098
+ list(threadId2) {
40099
+ return { data: [...this.#threads.get(threadId2) ?? []], nextCursor: null };
40100
+ }
40101
+ add(threadId2, input, clientUserMessageId) {
40102
+ const item = {
40103
+ id: randomUUID18(),
40104
+ clientUserMessageId: clientUserMessageId?.trim() || randomUUID18(),
40105
+ input: queuedSubmissionInput(input)
40106
+ };
40107
+ const items = this.#threads.get(threadId2) ?? [];
40108
+ items.push(item);
40109
+ this.#threads.set(threadId2, items);
40110
+ return item;
40111
+ }
40112
+ update(threadId2, id2, input) {
40113
+ const item = this.#threads.get(threadId2)?.find((entry) => entry.id === id2);
40114
+ if (!item) return void 0;
40115
+ item.input = queuedSubmissionInput(input);
40116
+ return item;
40117
+ }
40118
+ delete(threadId2, id2) {
40119
+ const items = this.#threads.get(threadId2);
40120
+ if (!items) return false;
40121
+ const next = items.filter((entry) => entry.id !== id2);
40122
+ if (next.length === items.length) return false;
40123
+ if (next.length === 0) this.#threads.delete(threadId2);
40124
+ else this.#threads.set(threadId2, next);
40125
+ return true;
40126
+ }
40127
+ reorder(threadId2, ids) {
40128
+ const items = this.#threads.get(threadId2);
40129
+ if (!items) return false;
40130
+ const remaining = new Map(items.map((entry) => [entry.id, entry]));
40131
+ const next = [];
40132
+ for (const id2 of ids) {
40133
+ const item = remaining.get(id2);
40134
+ if (!item) return false;
40135
+ next.push(item);
40136
+ remaining.delete(id2);
40137
+ }
40138
+ next.push(...remaining.values());
40139
+ this.#threads.set(threadId2, next);
40140
+ return true;
40141
+ }
40142
+ peek(threadId2, id2) {
40143
+ const items = this.#threads.get(threadId2);
40144
+ if (!items?.length) return void 0;
40145
+ return id2 ? items.find((entry) => this.#matches(entry, id2)) : items[0];
40146
+ }
40147
+ take(threadId2, id2) {
40148
+ const items = this.#threads.get(threadId2);
40149
+ if (!items?.length) return void 0;
40150
+ const index = id2 ? items.findIndex((entry) => this.#matches(entry, id2)) : 0;
40151
+ if (index < 0) return void 0;
40152
+ const [item] = items.splice(index, 1);
40153
+ if (items.length === 0) this.#threads.delete(threadId2);
40154
+ return item;
40155
+ }
40156
+ restore(threadId2, item) {
40157
+ const items = this.#threads.get(threadId2) ?? [];
40158
+ items.unshift(item);
40159
+ this.#threads.set(threadId2, items);
40160
+ }
40161
+ #matches(entry, id2) {
40162
+ return entry.id === id2 || entry.clientUserMessageId === id2;
40163
+ }
40164
+ };
40165
+
39749
40166
  // packages/host-runtime/src/observed-session-usage.ts
39750
40167
  var ObservedSessionUsage = class {
39751
40168
  constructor(providers, prices, diagnose) {
@@ -39905,14 +40322,14 @@ var THREAD_USAGE_UPDATED_METHOD = "codexhost/thread/usage/updated";
39905
40322
  function delay5(milliseconds) {
39906
40323
  return new Promise((resolve) => setTimeout(resolve, milliseconds));
39907
40324
  }
39908
- function isRecord20(value2) {
40325
+ function isRecord21(value2) {
39909
40326
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
39910
40327
  }
39911
40328
  function officialThreadBusy(thread) {
39912
- if (thread && isRecord20(thread.status) && thread.status.type === "active") return true;
40329
+ if (thread && isRecord21(thread.status) && thread.status.type === "active") return true;
39913
40330
  const turns = thread && Array.isArray(thread.turns) ? thread.turns : [];
39914
40331
  const latestTurn = turns.at(-1);
39915
- return isRecord20(latestTurn) && (latestTurn.status === "inProgress" || latestTurn.status === "running");
40332
+ return isRecord21(latestTurn) && (latestTurn.status === "inProgress" || latestTurn.status === "running");
39916
40333
  }
39917
40334
  function errorMessage4(error51) {
39918
40335
  return error51 instanceof Error ? error51.message : String(error51);
@@ -40019,15 +40436,15 @@ function classifyCreateRequestRoute(request) {
40019
40436
  };
40020
40437
  }
40021
40438
  function routingParams(request) {
40022
- return isRecord20(request.params) ? request.params : {};
40439
+ return isRecord21(request.params) ? request.params : {};
40023
40440
  }
40024
40441
  function requestObject(request) {
40025
- if (!isRecord20(request.params)) throw new Error(`${request.method} params must be an object`);
40442
+ if (!isRecord21(request.params)) throw new Error(`${request.method} params must be an object`);
40026
40443
  return request.params;
40027
40444
  }
40028
40445
  function requestText(params) {
40029
40446
  if (!Array.isArray(params.input)) throw new Error("turn/start input must be an array");
40030
- const text = params.input.filter((item) => isRecord20(item) && item.type === "text").map((item) => item.text).filter((value2) => typeof value2 === "string").join("\n");
40447
+ const text = queuedSubmissionText(params.input);
40031
40448
  if (!text) throw new Error("turn/start must contain text input");
40032
40449
  return text;
40033
40450
  }
@@ -40075,10 +40492,12 @@ var AppServerHost = class {
40075
40492
  #plugins;
40076
40493
  #launchSettings;
40077
40494
  #accountInspections = new HarnessAccountInspectionCache();
40495
+ #installationTasks = new HarnessInstallationTasks();
40078
40496
  #externalRuntime;
40079
40497
  #executionHosts = /* @__PURE__ */ new WeakMap();
40080
40498
  #externalPrewarms = new ExternalThreadPrewarms();
40081
40499
  #externalSteering = new ExternalTurnSteering();
40500
+ #followUps = new ExternalThreadFollowUpQueue();
40082
40501
  #nativeVoiceGateway;
40083
40502
  #externalVoice;
40084
40503
  #externalVoiceResults = new ExternalVoiceResults(
@@ -40110,7 +40529,7 @@ var AppServerHost = class {
40110
40529
  #sectionMoves = Promise.resolve();
40111
40530
  #writer;
40112
40531
  /** Console requests share Desktop handling; their replies return to the console. */
40113
- #consoleRequestPrefix = `codexhost-console:${randomUUID16()}:`;
40532
+ #consoleRequestPrefix = `codexhost-console:${randomUUID19()}:`;
40114
40533
  #consoleReplies = /* @__PURE__ */ new Map();
40115
40534
  #nextConsoleRequest = 0;
40116
40535
  #subagentThreadStatuses = /* @__PURE__ */ new Map();
@@ -40468,19 +40887,19 @@ var AppServerHost = class {
40468
40887
  for (const resolve of waiters) resolve();
40469
40888
  }
40470
40889
  #observeOfficialTurnStartResponse(value2) {
40471
- if (!isRecord20(value2) || !("id" in value2)) return;
40890
+ if (!isRecord21(value2) || !("id" in value2)) return;
40472
40891
  const threadId2 = this.#pendingOfficialTurnStarts.get(value2.id);
40473
40892
  if (!threadId2) return;
40474
40893
  this.#pendingOfficialTurnStarts.delete(value2.id);
40475
- const result = isRecord20(value2.result) ? value2.result : null;
40476
- const turn = result && isRecord20(result.turn) ? result.turn : null;
40894
+ const result = isRecord21(value2.result) ? value2.result : null;
40895
+ const turn = result && isRecord21(result.turn) ? result.turn : null;
40477
40896
  if (turn && typeof turn.id === "string") {
40478
40897
  this.#activeOfficialTurns.set(threadId2, turn.id);
40479
40898
  }
40480
40899
  this.#signalActiveWorkChanged();
40481
40900
  }
40482
40901
  #takeConsoleReply(value2) {
40483
- if (!isRecord20(value2) || typeof value2.id !== "string") return false;
40902
+ if (!isRecord21(value2) || typeof value2.id !== "string") return false;
40484
40903
  const reply2 = this.#consoleReplies.get(value2.id);
40485
40904
  if (!reply2) return false;
40486
40905
  this.#consoleReplies.delete(value2.id);
@@ -40526,10 +40945,10 @@ var AppServerHost = class {
40526
40945
  );
40527
40946
  try {
40528
40947
  const message2 = await reply2;
40529
- if (isRecord20(message2) && "result" in message2) {
40948
+ if (isRecord21(message2) && "result" in message2) {
40530
40949
  return { result: message2.result ?? null };
40531
40950
  }
40532
- const error51 = isRecord20(message2) && isRecord20(message2.error) ? message2.error : void 0;
40951
+ const error51 = isRecord21(message2) && isRecord21(message2.error) ? message2.error : void 0;
40533
40952
  return {
40534
40953
  error: {
40535
40954
  code: typeof error51?.code === "number" ? error51.code : -32603,
@@ -40555,7 +40974,7 @@ var AppServerHost = class {
40555
40974
  this.#diagnose(error51);
40556
40975
  continue;
40557
40976
  }
40558
- if (isRecord20(parsed2) && parsed2.method === "initialized" && !("id" in parsed2)) {
40977
+ if (isRecord21(parsed2) && parsed2.method === "initialized" && !("id" in parsed2)) {
40559
40978
  continue;
40560
40979
  }
40561
40980
  if (await this.#handleDesktopApprovalResponse(parsed2)) continue;
@@ -40577,7 +40996,7 @@ var AppServerHost = class {
40577
40996
  const options2 = this.#observedSessionUsage.requestOptions("initialize", params);
40578
40997
  const nativeParams = options2 ? { ...params, ...options2 } : params;
40579
40998
  const response = await this.#officialRuntime.initializeProtocol(nativeParams);
40580
- if (!isRecord20(response.error)) this.#observedSessionUsage.initialized(nativeParams);
40999
+ if (!isRecord21(response.error)) this.#observedSessionUsage.initialized(nativeParams);
40581
41000
  await this.#writer.json({ ...response, id: request.id });
40582
41001
  this.#nativeAccountObserver?.initialized(nativeGeneration);
40583
41002
  } catch (error51) {
@@ -40585,7 +41004,7 @@ var AppServerHost = class {
40585
41004
  }
40586
41005
  continue;
40587
41006
  }
40588
- const threadId2 = isRecord20(request.params) && typeof request.params.threadId === "string" ? request.params.threadId : void 0;
41007
+ const threadId2 = isRecord21(request.params) && typeof request.params.threadId === "string" ? request.params.threadId : void 0;
40589
41008
  this.#dispatchDesktopRequest(
40590
41009
  () => this.#desktopRequests.run(
40591
41010
  threadId2,
@@ -40633,7 +41052,7 @@ var AppServerHost = class {
40633
41052
  for (const guard of this.#replyGuards.get(id2) ?? []) guard.answered = true;
40634
41053
  }
40635
41054
  #noteDesktopReply(value2) {
40636
- if (isRecord20(value2) && "id" in value2 && !("method" in value2)) {
41055
+ if (isRecord21(value2) && "id" in value2 && !("method" in value2)) {
40637
41056
  this.#markDesktopRequestAnswered(value2.id);
40638
41057
  }
40639
41058
  }
@@ -40948,11 +41367,11 @@ var AppServerHost = class {
40948
41367
  this.#dispatchDesktopReply(request, () => this.#inspectHarness(request));
40949
41368
  return;
40950
41369
  }
40951
- if (request.method === HARNESS_INSTALLATION_METHOD) {
41370
+ if (request.method === HARNESS_INSTALLATION_METHOD || request.method === HARNESS_INSTALLATION_START_METHOD || request.method === HARNESS_INSTALLATION_STATUS_METHOD) {
40952
41371
  this.#dispatchDesktopReply(request, async () => {
40953
- await this.#waitForPlugins();
40954
41372
  try {
40955
- const result = await handleHarnessInstallation(request.params, this.#externalAdapters);
41373
+ if (request.method !== HARNESS_INSTALLATION_STATUS_METHOD) await this.#waitForPlugins();
41374
+ const result = request.method === HARNESS_INSTALLATION_START_METHOD ? this.#installationTasks.start(request.params, this.#externalAdapters) : request.method === HARNESS_INSTALLATION_STATUS_METHOD ? this.#installationTasks.status(request.params) : await handleHarnessInstallation(request.params, this.#externalAdapters);
40956
41375
  await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
40957
41376
  } catch (error51) {
40958
41377
  await this.#writer.json(
@@ -41057,6 +41476,10 @@ var AppServerHost = class {
41057
41476
  await this.#listThreadOwnership(request);
41058
41477
  return;
41059
41478
  }
41479
+ if (request.method === "codexhost/thread/steering/inspect") {
41480
+ await this.#inspectThreadSteering(request);
41481
+ return;
41482
+ }
41060
41483
  if (request.method === "codexhost/thread/model/select") {
41061
41484
  await this.#selectThreadModel(request);
41062
41485
  return;
@@ -41208,7 +41631,7 @@ var AppServerHost = class {
41208
41631
  return;
41209
41632
  }
41210
41633
  if (request.method === "thread/fork") {
41211
- const params = isRecord20(request.params) ? request.params : {};
41634
+ const params = isRecord21(request.params) ? request.params : {};
41212
41635
  const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
41213
41636
  if (resolution.kind === "error") {
41214
41637
  await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
@@ -41229,7 +41652,7 @@ var AppServerHost = class {
41229
41652
  }
41230
41653
  }
41231
41654
  if (request.method === "thread/revert") {
41232
- const params = isRecord20(request.params) ? request.params : {};
41655
+ const params = isRecord21(request.params) ? request.params : {};
41233
41656
  const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
41234
41657
  if (resolution.kind === "error") {
41235
41658
  await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
@@ -41250,7 +41673,7 @@ var AppServerHost = class {
41250
41673
  }
41251
41674
  }
41252
41675
  if (request.method === "thread/rollback") {
41253
- const params = isRecord20(request.params) ? request.params : {};
41676
+ const params = isRecord21(request.params) ? request.params : {};
41254
41677
  const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
41255
41678
  if (resolution.kind === "error") {
41256
41679
  await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
@@ -41309,6 +41732,24 @@ var AppServerHost = class {
41309
41732
  this.#pendingOfficialTurnStarts.set(request.id, threadId2);
41310
41733
  }
41311
41734
  }
41735
+ if (request.method.startsWith("thread/queue/")) {
41736
+ const params = routingParams(request);
41737
+ const threadId2 = params.threadId;
41738
+ const resolution = typeof threadId2 === "string" ? await this.#resolveExternalThread(threadId2) : { kind: "official" };
41739
+ if (await this.#writeResolutionError(request, resolution)) return;
41740
+ if (resolution.kind === "external") {
41741
+ if (request.method === "thread/queue/start") {
41742
+ this.#dispatchDesktopReply(
41743
+ request,
41744
+ () => this.#startExternalQueuedTurn(request, resolution.thread),
41745
+ resolution.thread.id
41746
+ );
41747
+ return;
41748
+ }
41749
+ await this.#handleExternalQueueMutation(request, resolution.thread);
41750
+ return;
41751
+ }
41752
+ }
41312
41753
  if (request.method === "turn/steer") {
41313
41754
  const params = routingParams(request);
41314
41755
  const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
@@ -41408,7 +41849,7 @@ var AppServerHost = class {
41408
41849
  return;
41409
41850
  }
41410
41851
  }
41411
- if (request.method === "thread/backgroundTerminals/clean" && isRecord20(request.params) && typeof request.params.threadId === "string") {
41852
+ if (request.method === "thread/backgroundTerminals/clean" && isRecord21(request.params) && typeof request.params.threadId === "string") {
41412
41853
  const location = await this.#locateExternalThread(request.params.threadId);
41413
41854
  if (await this.#writeResolutionError(request, location)) return;
41414
41855
  if (location.kind === "external") {
@@ -41416,7 +41857,7 @@ var AppServerHost = class {
41416
41857
  return;
41417
41858
  }
41418
41859
  }
41419
- if (request.method.startsWith("thread/realtime/") && isRecord20(request.params) && typeof request.params.threadId === "string") {
41860
+ if (request.method.startsWith("thread/realtime/") && isRecord21(request.params) && typeof request.params.threadId === "string") {
41420
41861
  const resolution = await this.#resolveExternalThread(request.params.threadId);
41421
41862
  if (await this.#writeResolutionError(request, resolution)) return;
41422
41863
  if (resolution.kind === "external") {
@@ -41428,7 +41869,7 @@ var AppServerHost = class {
41428
41869
  return;
41429
41870
  }
41430
41871
  }
41431
- if (request.method.startsWith("thread/") && !EXPLICIT_EXTERNAL_THREAD_METHODS.has(request.method) && isRecord20(request.params) && typeof request.params.threadId === "string") {
41872
+ if (request.method.startsWith("thread/") && !EXPLICIT_EXTERNAL_THREAD_METHODS.has(request.method) && isRecord21(request.params) && typeof request.params.threadId === "string") {
41432
41873
  const location = await this.#locateExternalThread(request.params.threadId);
41433
41874
  if (await this.#writeResolutionError(request, location)) return;
41434
41875
  if (location.kind === "external") {
@@ -41447,10 +41888,10 @@ var AppServerHost = class {
41447
41888
  /** Native Codex Turns: turn `#` delegation chips into an explicit Skill-backed request. */
41448
41889
  async #rewriteOfficialDelegationMentions(request, frame) {
41449
41890
  if (request.method !== "turn/start" && request.method !== "turn/steer") return frame;
41450
- if (!isRecord20(request.params) || !Array.isArray(request.params.input)) return frame;
41891
+ if (!isRecord21(request.params) || !Array.isArray(request.params.input)) return frame;
41451
41892
  const input = request.params.input;
41452
41893
  if (!input.some(
41453
- (item) => isRecord20(item) && typeof item.text === "string" && item.text.includes(DELEGATION_MENTION_PATH_PREFIX)
41894
+ (item) => isRecord21(item) && typeof item.text === "string" && item.text.includes(DELEGATION_MENTION_PATH_PREFIX)
41454
41895
  )) {
41455
41896
  return frame;
41456
41897
  }
@@ -41463,7 +41904,7 @@ var AppServerHost = class {
41463
41904
  }
41464
41905
  async #forwardOfficialNonRequest(value2, frame) {
41465
41906
  if (this.#options.externalOnly) return;
41466
- const response = isRecord20(value2) ? value2 : null;
41907
+ const response = isRecord21(value2) ? value2 : null;
41467
41908
  const request = response && (typeof response.id === "string" || typeof response.id === "number") ? this.#officialServerRequests.get(response.id) : null;
41468
41909
  if (request !== void 0 && response) {
41469
41910
  this.#officialServerRequests.delete(response.id);
@@ -41483,13 +41924,13 @@ var AppServerHost = class {
41483
41924
  return;
41484
41925
  }
41485
41926
  try {
41486
- const options2 = isRecord20(request.params) ? this.#observedSessionUsage.requestOptions(request.method, request.params) : null;
41927
+ const options2 = isRecord21(request.params) ? this.#observedSessionUsage.requestOptions(request.method, request.params) : null;
41487
41928
  if (options2) {
41488
41929
  const original = parseJsonFrame(frame);
41489
- if (isRecord20(original))
41930
+ if (isRecord21(original))
41490
41931
  frame = encodeJsonFrame({
41491
41932
  ...original,
41492
- params: { ...isRecord20(original.params) ? original.params : {}, ...options2 }
41933
+ params: { ...isRecord21(original.params) ? original.params : {}, ...options2 }
41493
41934
  });
41494
41935
  }
41495
41936
  await this.#officialRuntime.sendFrame(frame);
@@ -41513,7 +41954,7 @@ var AppServerHost = class {
41513
41954
  const observedAtMs = Date.now();
41514
41955
  this.#observeOfficialTurnStartResponse(parsed2);
41515
41956
  let forwarded = parsed2;
41516
- if (isRecord20(parsed2) && typeof parsed2.method === "string" && "id" in parsed2) {
41957
+ if (isRecord21(parsed2) && typeof parsed2.method === "string" && "id" in parsed2) {
41517
41958
  const originalId = parsed2.id;
41518
41959
  if (typeof originalId === "string" || typeof originalId === "number") {
41519
41960
  const forwardedId = `codexhost:official:${++this.#nextOfficialServerRequestId}`;
@@ -41521,7 +41962,7 @@ var AppServerHost = class {
41521
41962
  forwarded = { ...parsed2, id: forwardedId };
41522
41963
  }
41523
41964
  }
41524
- const accountScopedNotification = isRecord20(parsed2) && typeof parsed2.method === "string" && (parsed2.method === "account/updated" || parsed2.method.startsWith("account/rateLimits/"));
41965
+ const accountScopedNotification = isRecord21(parsed2) && typeof parsed2.method === "string" && (parsed2.method === "account/updated" || parsed2.method.startsWith("account/rateLimits/"));
41525
41966
  if (accountScopedNotification) {
41526
41967
  if (parsed2.method === "account/updated") this.#officialRateLimits.reset(input.accountId);
41527
41968
  }
@@ -41533,7 +41974,7 @@ var AppServerHost = class {
41533
41974
  this.#diagnose(error51);
41534
41975
  }
41535
41976
  this.#routeObservationTracker.bindOfficialResponse(parsed2);
41536
- const privateTelemetry = isRecord20(parsed2) && typeof parsed2.method === "string" && !("id" in parsed2) && !this.#observedSessionUsage.shouldForwardNotification(parsed2);
41977
+ const privateTelemetry = isRecord21(parsed2) && typeof parsed2.method === "string" && !("id" in parsed2) && !this.#observedSessionUsage.shouldForwardNotification(parsed2);
41537
41978
  if (!privateTelemetry) {
41538
41979
  if (forwarded === parsed2) await this.#writer.frame(input.frame);
41539
41980
  else await this.#writer.json(forwarded);
@@ -41599,10 +42040,10 @@ var AppServerHost = class {
41599
42040
  }
41600
42041
  }
41601
42042
  async #observeOfficialTurnLifecycle(value2) {
41602
- if (!isRecord20(value2) || !isRecord20(value2.params)) return;
42043
+ if (!isRecord21(value2) || !isRecord21(value2.params)) return;
41603
42044
  const params = value2.params;
41604
42045
  if (value2.method === "turn/started" && typeof params.threadId === "string") {
41605
- const turn = isRecord20(params.turn) ? params.turn : null;
42046
+ const turn = isRecord21(params.turn) ? params.turn : null;
41606
42047
  if (turn && typeof turn.id === "string") {
41607
42048
  this.#forgetPendingOfficialTurnStarts(params.threadId);
41608
42049
  this.#activeOfficialTurns.set(params.threadId, turn.id);
@@ -41615,7 +42056,7 @@ var AppServerHost = class {
41615
42056
  const delegation = await this.#repository.getDelegationByChild(
41616
42057
  hostThreadIdSchema.parse(params.threadId)
41617
42058
  );
41618
- const turn = isRecord20(params.turn) ? params.turn : null;
42059
+ const turn = isRecord21(params.turn) ? params.turn : null;
41619
42060
  const status2 = turn?.status === "failed" ? "failed" : turn?.status === "interrupted" || turn?.status === "cancelled" ? "interrupted" : "completed";
41620
42061
  if (this.#pendingOfficialDelegationThreads.has(params.threadId)) {
41621
42062
  this.#pendingOfficialTerminalStatuses.set(params.threadId, status2);
@@ -41648,9 +42089,9 @@ var AppServerHost = class {
41648
42089
  }
41649
42090
  async #readOfficialThreadMetadata(threadId2) {
41650
42091
  const response = await this.#requestOfficial("thread/read", { threadId: threadId2, includeTurns: false });
41651
- if (isRecord20(response.error)) return {};
41652
- const result = isRecord20(response.result) ? response.result : null;
41653
- const thread = result && isRecord20(result.thread) ? result.thread : null;
42092
+ if (isRecord21(response.error)) return {};
42093
+ const result = isRecord21(response.result) ? response.result : null;
42094
+ const thread = result && isRecord21(result.thread) ? result.thread : null;
41654
42095
  if (!thread) return {};
41655
42096
  const title = typeof thread.name === "string" && thread.name.trim() ? thread.name : thread.preview;
41656
42097
  return {
@@ -41660,21 +42101,21 @@ var AppServerHost = class {
41660
42101
  }
41661
42102
  async #inspectOfficialDelegationTarget(input) {
41662
42103
  const response = await this.#requestOfficial("model/list", {});
41663
- if (isRecord20(response.error)) {
42104
+ if (isRecord21(response.error)) {
41664
42105
  throw new DelegationControlError(
41665
42106
  "DELEGATION_FAILED",
41666
42107
  typeof response.error.message === "string" ? response.error.message : "Official Model catalog could not be read"
41667
42108
  );
41668
42109
  }
41669
- const result = isRecord20(response.result) ? response.result : null;
42110
+ const result = isRecord21(response.result) ? response.result : null;
41670
42111
  const data = result && Array.isArray(result.data) ? result.data : [];
41671
42112
  const thinkingById = /* @__PURE__ */ new Map();
41672
42113
  const models = data.flatMap((candidate) => {
41673
- if (!isRecord20(candidate) || typeof candidate.model !== "string" || !candidate.model.trim()) {
42114
+ if (!isRecord21(candidate) || typeof candidate.model !== "string" || !candidate.model.trim()) {
41674
42115
  return [];
41675
42116
  }
41676
42117
  const supportedThinkingOptionIds = Array.isArray(candidate.supportedReasoningEfforts) ? candidate.supportedReasoningEfforts.flatMap((option) => {
41677
- if (!isRecord20(option) || typeof option.reasoningEffort !== "string" || !option.reasoningEffort.trim()) {
42118
+ if (!isRecord21(option) || typeof option.reasoningEffort !== "string" || !option.reasoningEffort.trim()) {
41678
42119
  return [];
41679
42120
  }
41680
42121
  const id2 = harnessThinkingOptionIdSchema.safeParse(option.reasoningEffort);
@@ -41694,9 +42135,9 @@ var AppServerHost = class {
41694
42135
  ];
41695
42136
  });
41696
42137
  const defaultEntry = data.find(
41697
- (candidate) => isRecord20(candidate) && candidate.isDefault === true
42138
+ (candidate) => isRecord21(candidate) && candidate.isDefault === true
41698
42139
  );
41699
- const defaultModel = isRecord20(defaultEntry) && typeof defaultEntry.model === "string" ? encodeOfficialCodexModelRef(defaultEntry.model) : void 0;
42140
+ const defaultModel = isRecord21(defaultEntry) && typeof defaultEntry.model === "string" ? encodeOfficialCodexModelRef(defaultEntry.model) : void 0;
41700
42141
  return {
41701
42142
  harnessId: input.harnessId,
41702
42143
  inspection: {
@@ -41802,8 +42243,8 @@ var AppServerHost = class {
41802
42243
  ephemeral: false,
41803
42244
  historyMode: "paginated"
41804
42245
  });
41805
- const startedResult = isRecord20(started.result) ? started.result : null;
41806
- const thread = startedResult && isRecord20(startedResult.thread) ? startedResult.thread : null;
42246
+ const startedResult = isRecord21(started.result) ? started.result : null;
42247
+ const thread = startedResult && isRecord21(startedResult.thread) ? startedResult.thread : null;
41807
42248
  const threadId2 = thread && typeof thread.id === "string" ? thread.id : null;
41808
42249
  if (!threadId2) throw new Error("Official thread/start returned no Thread identity");
41809
42250
  this.#pendingOfficialDelegationThreads.add(threadId2);
@@ -41818,8 +42259,8 @@ var AppServerHost = class {
41818
42259
  ...nativeModelId ? { model: nativeModelId } : {},
41819
42260
  ...input.thinkingOptionId ? { effort: input.thinkingOptionId } : {}
41820
42261
  });
41821
- const turnResult = isRecord20(turn.result) ? turn.result : null;
41822
- const turnValue = turnResult && isRecord20(turnResult.turn) ? turnResult.turn : null;
42262
+ const turnResult = isRecord21(turn.result) ? turn.result : null;
42263
+ const turnValue = turnResult && isRecord21(turnResult.turn) ? turnResult.turn : null;
41823
42264
  const parsedTurnId = turnValue && typeof turnValue.id === "string" ? turnValue.id : null;
41824
42265
  if (!parsedTurnId) throw new Error("Official turn/start returned no Turn identity");
41825
42266
  turnId = parsedTurnId;
@@ -41830,7 +42271,7 @@ var AppServerHost = class {
41830
42271
  throw error51;
41831
42272
  }
41832
42273
  this.#activeOfficialTurns.set(threadId2, turnId);
41833
- const delegationId = hostThreadIdSchema.parse(randomUUID16());
42274
+ const delegationId = hostThreadIdSchema.parse(randomUUID19());
41834
42275
  try {
41835
42276
  const source = await this.#repository.find(input.parentThreadId);
41836
42277
  const pendingTerminal = this.#pendingOfficialTerminalStatuses.get(threadId2);
@@ -41889,11 +42330,11 @@ var AppServerHost = class {
41889
42330
  threadId: input.threadId,
41890
42331
  includeTurns: true
41891
42332
  });
41892
- if (isRecord20(current.error)) throw officialThreadReadError(current.error);
41893
- if (!isRecord20(current.result)) {
42333
+ if (isRecord21(current.error)) throw officialThreadReadError(current.error);
42334
+ if (!isRecord21(current.result)) {
41894
42335
  throw new DelegationControlError("INTERNAL_ERROR", "Official Thread read returned no result");
41895
42336
  }
41896
- const currentThread = isRecord20(current.result.thread) ? current.result.thread : null;
42337
+ const currentThread = isRecord21(current.result.thread) ? current.result.thread : null;
41897
42338
  if (officialThreadBusy(currentThread)) {
41898
42339
  throw new DelegationControlError("THREAD_BUSY", "Thread already has an active Turn");
41899
42340
  }
@@ -41901,14 +42342,14 @@ var AppServerHost = class {
41901
42342
  threadId: input.threadId,
41902
42343
  excludeTurns: true
41903
42344
  });
41904
- if (isRecord20(resumed.error) || !isRecord20(resumed.result)) {
42345
+ if (isRecord21(resumed.error) || !isRecord21(resumed.result)) {
41905
42346
  throw new DelegationControlError(
41906
42347
  "DELEGATION_FAILED",
41907
- isRecord20(resumed.error) && typeof resumed.error.message === "string" ? resumed.error.message : "Official Thread resume failed",
42348
+ isRecord21(resumed.error) && typeof resumed.error.message === "string" ? resumed.error.message : "Official Thread resume failed",
41908
42349
  { notStarted: true }
41909
42350
  );
41910
42351
  }
41911
- const resumedThread = isRecord20(resumed.result.thread) ? resumed.result.thread : null;
42352
+ const resumedThread = isRecord21(resumed.result.thread) ? resumed.result.thread : null;
41912
42353
  if (!resumedThread || resumedThread.id !== input.threadId) {
41913
42354
  throw new DelegationControlError(
41914
42355
  "DELEGATION_FAILED",
@@ -41919,7 +42360,7 @@ var AppServerHost = class {
41919
42360
  if (officialThreadBusy(resumedThread)) {
41920
42361
  throw new DelegationControlError("THREAD_BUSY", "Thread already has an active Turn");
41921
42362
  }
41922
- if (!isRecord20(resumedThread.status) || resumedThread.status.type !== "idle") {
42363
+ if (!isRecord21(resumedThread.status) || resumedThread.status.type !== "idle") {
41923
42364
  throw new DelegationControlError(
41924
42365
  "DELEGATION_FAILED",
41925
42366
  "Official Thread is not idle after resume",
@@ -41930,15 +42371,15 @@ var AppServerHost = class {
41930
42371
  threadId: input.threadId,
41931
42372
  input: [{ type: "text", text: input.message }]
41932
42373
  });
41933
- if (isRecord20(response.error)) {
42374
+ if (isRecord21(response.error)) {
41934
42375
  throw new DelegationControlError(
41935
42376
  "DELEGATION_FAILED",
41936
42377
  typeof response.error.message === "string" ? response.error.message : "Turn start failed",
41937
42378
  { notStarted: true }
41938
42379
  );
41939
42380
  }
41940
- const result = isRecord20(response.result) ? response.result : null;
41941
- const turn = result && isRecord20(result.turn) ? result.turn : null;
42381
+ const result = isRecord21(response.result) ? response.result : null;
42382
+ const turn = result && isRecord21(result.turn) ? result.turn : null;
41942
42383
  const turnId = turn && typeof turn.id === "string" ? turn.id : null;
41943
42384
  if (!turnId) throw new Error("Official turn/start returned no Turn identity");
41944
42385
  this.#activeOfficialTurns.set(input.threadId, turnId);
@@ -41960,13 +42401,13 @@ var AppServerHost = class {
41960
42401
  threadId: input.threadId,
41961
42402
  includeTurns: true
41962
42403
  });
41963
- if (isRecord20(current.error) || !isRecord20(current.result)) {
42404
+ if (isRecord21(current.error) || !isRecord21(current.result)) {
41964
42405
  throw new DelegationControlError("THREAD_NOT_FOUND", "Official Thread was not found");
41965
42406
  }
41966
- const currentThread = isRecord20(current.result.thread) ? current.result.thread : null;
42407
+ const currentThread = isRecord21(current.result.thread) ? current.result.thread : null;
41967
42408
  const currentTurns = currentThread && Array.isArray(currentThread.turns) ? currentThread.turns : [];
41968
42409
  const latestTurn = currentTurns.at(-1);
41969
- if (isRecord20(latestTurn) && typeof latestTurn.id === "string" && (latestTurn.status === "inProgress" || latestTurn.status === "running")) {
42410
+ if (isRecord21(latestTurn) && typeof latestTurn.id === "string" && (latestTurn.status === "inProgress" || latestTurn.status === "running")) {
41970
42411
  turnId = latestTurn.id;
41971
42412
  this.#activeOfficialTurns.set(input.threadId, turnId);
41972
42413
  } else {
@@ -41977,7 +42418,7 @@ var AppServerHost = class {
41977
42418
  threadId: input.threadId,
41978
42419
  turnId
41979
42420
  });
41980
- if (isRecord20(response.error)) {
42421
+ if (isRecord21(response.error)) {
41981
42422
  throw new DelegationControlError(
41982
42423
  "DELEGATION_FAILED",
41983
42424
  typeof response.error.message === "string" ? response.error.message : "Turn cancel failed"
@@ -41990,13 +42431,13 @@ var AppServerHost = class {
41990
42431
  threadId: input.threadId,
41991
42432
  includeTurns: true
41992
42433
  });
41993
- if (isRecord20(response.error)) throw officialThreadReadError(response.error);
41994
- const result = isRecord20(response.result) ? response.result : null;
41995
- const thread = result && isRecord20(result.thread) ? result.thread : null;
42434
+ if (isRecord21(response.error)) throw officialThreadReadError(response.error);
42435
+ const result = isRecord21(response.result) ? response.result : null;
42436
+ const thread = result && isRecord21(result.thread) ? result.thread : null;
41996
42437
  if (!thread)
41997
42438
  throw new DelegationControlError("INTERNAL_ERROR", "Official Thread read returned no Thread");
41998
- const turns = Array.isArray(thread.turns) ? thread.turns.filter((turn) => isRecord20(turn)) : [];
41999
- const running = this.#activeOfficialTurns.has(input.threadId) || isRecord20(thread.status) && thread.status.type === "active";
42439
+ const turns = Array.isArray(thread.turns) ? thread.turns.filter((turn) => isRecord21(turn)) : [];
42440
+ const running = this.#activeOfficialTurns.has(input.threadId) || isRecord21(thread.status) && thread.status.type === "active";
42000
42441
  const snapshot2 = projectDelegationThreadSnapshot({
42001
42442
  threadId: input.threadId,
42002
42443
  harnessId: "codex",
@@ -42018,7 +42459,7 @@ var AppServerHost = class {
42018
42459
  async #listDelegationThreads(input) {
42019
42460
  const [sortKey, sortDirection2] = input.sort.split("-");
42020
42461
  const request = {
42021
- id: `codexhost:delegation-list:${randomUUID16()}`,
42462
+ id: `codexhost:delegation-list:${randomUUID19()}`,
42022
42463
  method: "thread/list",
42023
42464
  params: {
42024
42465
  cwd: input.cwd ? [input.cwd] : null,
@@ -42044,7 +42485,7 @@ var AppServerHost = class {
42044
42485
  threads: result.data.flatMap((entry) => {
42045
42486
  if (typeof entry.id !== "string") return [];
42046
42487
  const record4 = records.find((candidate) => candidate.hostThreadId === entry.id);
42047
- const status2 = isRecord20(entry.status) && entry.status.type === "active" ? "running" : "completed";
42488
+ const status2 = isRecord21(entry.status) && entry.status.type === "active" ? "running" : "completed";
42048
42489
  return [
42049
42490
  {
42050
42491
  threadId: entry.id,
@@ -42211,7 +42652,7 @@ var AppServerHost = class {
42211
42652
  const exists2 = await this.#requestOfficial("project/read", {
42212
42653
  projectId: update.projectId
42213
42654
  }).then(
42214
- (response) => !isRecord20(response.error) && isRecord20(response.result) && isRecord20(response.result.project) && response.result.project.id === update.projectId,
42655
+ (response) => !isRecord21(response.error) && isRecord21(response.result) && isRecord21(response.result.project) && response.result.project.id === update.projectId,
42215
42656
  () => false
42216
42657
  );
42217
42658
  if (!exists2) {
@@ -42561,6 +43002,28 @@ var AppServerHost = class {
42561
43002
  );
42562
43003
  }
42563
43004
  }
43005
+ /** Read the same delivery decision that Desktop `turn/steer` will follow. */
43006
+ async #inspectThreadSteering(request) {
43007
+ const params = threadSteeringInspectParamsSchema.safeParse(request.params);
43008
+ if (!params.success) {
43009
+ await this.#writer.json(rpcError(request, -32602, "Invalid Thread steering params"));
43010
+ return;
43011
+ }
43012
+ let delivery;
43013
+ try {
43014
+ const location = await this.#locateExternalThread(params.data.threadId);
43015
+ if (await this.#writeResolutionError(request, location)) return;
43016
+ const thread = location.kind === "external" ? this.#externalRuntime.get(params.data.threadId) : void 0;
43017
+ delivery = location.kind !== "external" ? "official" : thread ? await externalSteeringDelivery(thread, params.data.text) : "newTurn";
43018
+ } catch {
43019
+ await this.#writer.json(
43020
+ rpcError(request, -32081, "Thread steering metadata could not be read")
43021
+ );
43022
+ return;
43023
+ }
43024
+ const result = threadSteeringInspectResultSchema.parse({ delivery });
43025
+ await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
43026
+ }
42564
43027
  async #inspectThreadCommands(request) {
42565
43028
  const params = threadCommandsInspectParamsSchema.safeParse(request.params);
42566
43029
  if (!params.success) {
@@ -42724,7 +43187,7 @@ var AppServerHost = class {
42724
43187
  if (thread.running || thread.activeTurnId) {
42725
43188
  throw new ExternalCommandError(-32072, "External Thread already has an active operation");
42726
43189
  }
42727
- const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID16());
43190
+ const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID19());
42728
43191
  const projection = {
42729
43192
  projector: new CodexTurnProjector({
42730
43193
  threadId: thread.id,
@@ -43161,9 +43624,20 @@ var AppServerHost = class {
43161
43624
  await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
43162
43625
  return true;
43163
43626
  }
43627
+ /** Refresh history before Desktop acts on native Turn boundaries. */
43164
43628
  #refreshExternalThread(thread) {
43165
43629
  return this.#externalRuntime.refresh(thread);
43166
43630
  }
43631
+ #markExternalHistoryRead(thread, turns) {
43632
+ if (!thread.historyHydrated) return;
43633
+ for (const turnId of thread.steeredTurnIds) {
43634
+ if (turnId !== thread.activeTurnId && turns.some(
43635
+ (turn) => turn.id === turnId && (turn.status === "completed" || turn.status === "failed" || turn.status === "interrupted")
43636
+ )) {
43637
+ thread.steeredTurnIds.delete(turnId);
43638
+ }
43639
+ }
43640
+ }
43167
43641
  #persistTerminalIdentity(thread, event) {
43168
43642
  return this.#externalRuntime.persistTerminalIdentity(thread, event);
43169
43643
  }
@@ -43363,17 +43837,19 @@ var AppServerHost = class {
43363
43837
  return;
43364
43838
  }
43365
43839
  }
43840
+ const readTurns = includeTurns ? [...this.#externalHistoryTurns(thread)] : [];
43366
43841
  await this.#writer.json(
43367
43842
  rpcEnvelope(request, {
43368
43843
  result: {
43369
43844
  thread: {
43370
43845
  ...thread.thread,
43371
43846
  ...await this.#externalSectionFields(thread.record.hostThreadId),
43372
- turns: includeTurns ? this.#externalHistoryTurns(thread) : []
43847
+ turns: readTurns
43373
43848
  }
43374
43849
  }
43375
43850
  })
43376
43851
  );
43852
+ if (includeTurns) this.#markExternalHistoryRead(thread, readTurns);
43377
43853
  await this.#replayExternalUsage(thread);
43378
43854
  }
43379
43855
  async #listExternalHistory(request, thread, params, historyFresh) {
@@ -43390,6 +43866,9 @@ var AppServerHost = class {
43390
43866
  const turns = this.#externalHistoryTurns(thread);
43391
43867
  const result = request.method === "thread/turns/list" ? listExternalTurns(turns, params) : listExternalItems(turns, params);
43392
43868
  await this.#writer.json(rpcEnvelope(request, { result }));
43869
+ if (request.method === "thread/turns/list") {
43870
+ this.#markExternalHistoryRead(thread, result.data);
43871
+ }
43393
43872
  } catch (error51) {
43394
43873
  await this.#writer.json(
43395
43874
  rpcError(
@@ -43408,7 +43887,7 @@ var AppServerHost = class {
43408
43887
  return;
43409
43888
  }
43410
43889
  }
43411
- const turns = this.#externalHistoryTurns(thread);
43890
+ const turns = [...this.#externalHistoryTurns(thread)];
43412
43891
  const responseThread = {
43413
43892
  ...await this.#withExternalSection(thread.thread),
43414
43893
  turns: params.excludeTurns === true ? [] : turns
@@ -43424,10 +43903,10 @@ var AppServerHost = class {
43424
43903
  if (thread.record.subagent)
43425
43904
  result.reasoningEffort = thread.record.subagentConfiguration?.reasoningEffort ?? null;
43426
43905
  try {
43427
- if (params.initialTurnsPage !== void 0 && params.initialTurnsPage !== null && !isRecord20(params.initialTurnsPage)) {
43906
+ if (params.initialTurnsPage !== void 0 && params.initialTurnsPage !== null && !isRecord21(params.initialTurnsPage)) {
43428
43907
  throw new ExternalHistoryRequestError("initialTurnsPage must be an object");
43429
43908
  }
43430
- const initialPageParams = isRecord20(params.initialTurnsPage) ? params.initialTurnsPage : null;
43909
+ const initialPageParams = isRecord21(params.initialTurnsPage) ? params.initialTurnsPage : null;
43431
43910
  const initialTurnsPage = initialPageParams ? listExternalTurns(turns, initialPageParams) : null;
43432
43911
  const paginated = thread.record.historyMode === "paginated";
43433
43912
  const turnsBackwardsCursor = paginated ? listExternalTurns(turns, { limit: 1, itemsView: "notLoaded" }).backwardsCursor : null;
@@ -43442,6 +43921,8 @@ var AppServerHost = class {
43442
43921
  }
43443
43922
  })
43444
43923
  );
43924
+ if (params.excludeTurns !== true) this.#markExternalHistoryRead(thread, turns);
43925
+ else if (initialTurnsPage) this.#markExternalHistoryRead(thread, initialTurnsPage.data);
43445
43926
  } catch (error51) {
43446
43927
  await this.#writer.json(
43447
43928
  rpcError(
@@ -43566,6 +44047,117 @@ var AppServerHost = class {
43566
44047
  (signal) => this.#externalVoiceResults.watch(threadId2, turnId, signal)
43567
44048
  );
43568
44049
  }
44050
+ async #notifyFollowUpQueueChanged(threadId2) {
44051
+ await this.#writer.json({
44052
+ method: "thread/queue/changed",
44053
+ params: { threadId: threadId2 }
44054
+ });
44055
+ }
44056
+ async #handleExternalQueueMutation(request, thread) {
44057
+ const params = requestObject(request);
44058
+ try {
44059
+ if (request.method === "thread/queue/list") {
44060
+ await this.#writer.json(rpcEnvelope(request, { result: this.#followUps.list(thread.id) }));
44061
+ return;
44062
+ }
44063
+ if (request.method === "thread/queue/add") {
44064
+ if (!Array.isArray(params.input))
44065
+ throw new Error("thread/queue/add input must be an array");
44066
+ const text = queuedSubmissionText(params.input);
44067
+ if (!text) throw new Error("thread/queue/add must contain text input");
44068
+ const queuedSubmission = this.#followUps.add(
44069
+ thread.id,
44070
+ params.input,
44071
+ typeof params.clientUserMessageId === "string" ? params.clientUserMessageId : void 0
44072
+ );
44073
+ await this.#writer.json(rpcEnvelope(request, { result: { queuedSubmission } }));
44074
+ await this.#notifyFollowUpQueueChanged(thread.id);
44075
+ return;
44076
+ }
44077
+ if (request.method === "thread/queue/update") {
44078
+ if (typeof params.queuedSubmissionId !== "string" || !Array.isArray(params.input)) {
44079
+ throw new Error("thread/queue/update requires queuedSubmissionId and input");
44080
+ }
44081
+ const queuedSubmission = this.#followUps.update(
44082
+ thread.id,
44083
+ params.queuedSubmissionId,
44084
+ params.input
44085
+ );
44086
+ if (!queuedSubmission) throw new Error("Queued follow-up was not found");
44087
+ await this.#writer.json(rpcEnvelope(request, { result: { queuedSubmission } }));
44088
+ await this.#notifyFollowUpQueueChanged(thread.id);
44089
+ return;
44090
+ }
44091
+ if (request.method === "thread/queue/delete") {
44092
+ if (typeof params.queuedSubmissionId !== "string") {
44093
+ throw new Error("thread/queue/delete requires queuedSubmissionId");
44094
+ }
44095
+ const deleted = this.#followUps.delete(thread.id, params.queuedSubmissionId);
44096
+ await this.#writer.json(rpcEnvelope(request, { result: { deleted } }));
44097
+ if (deleted) await this.#notifyFollowUpQueueChanged(thread.id);
44098
+ return;
44099
+ }
44100
+ if (request.method === "thread/queue/reorder") {
44101
+ if (!Array.isArray(params.queuedSubmissionIds) || params.queuedSubmissionIds.some((id2) => typeof id2 !== "string")) {
44102
+ throw new Error("thread/queue/reorder requires queuedSubmissionIds");
44103
+ }
44104
+ if (!this.#followUps.reorder(thread.id, params.queuedSubmissionIds)) {
44105
+ throw new Error("Queued follow-up order could not be applied");
44106
+ }
44107
+ await this.#writer.json(rpcEnvelope(request, { result: {} }));
44108
+ await this.#notifyFollowUpQueueChanged(thread.id);
44109
+ return;
44110
+ }
44111
+ await this.#writer.json(
44112
+ rpcError(request, -32076, `External Thread does not support ${request.method}`)
44113
+ );
44114
+ } catch (error51) {
44115
+ await this.#writer.json(rpcError(request, -32602, errorMessage4(error51)));
44116
+ }
44117
+ }
44118
+ async #startExternalFromFollowUp(request, thread, queued, sourceHostId) {
44119
+ const text = queuedSubmissionText(queued.input);
44120
+ if (!text) {
44121
+ this.#followUps.restore(thread.id, queued);
44122
+ await this.#writer.json(rpcError(request, -32602, "Queued follow-up was not found"));
44123
+ return;
44124
+ }
44125
+ await this.#notifyFollowUpQueueChanged(thread.id);
44126
+ try {
44127
+ const started = await this.#beginExternalInputTurn(
44128
+ thread,
44129
+ text,
44130
+ void 0,
44131
+ queued.clientUserMessageId,
44132
+ sourceHostId
44133
+ );
44134
+ try {
44135
+ await this.#writer.json(rpcEnvelope(request, { result: { turn: started.turn } }));
44136
+ } finally {
44137
+ started.gate.resolve();
44138
+ }
44139
+ } catch (error51) {
44140
+ this.#followUps.restore(thread.id, queued);
44141
+ await this.#notifyFollowUpQueueChanged(thread.id);
44142
+ await this.#writer.json(
44143
+ rpcError(
44144
+ request,
44145
+ error51 instanceof ExternalSteerError || error51 instanceof ExternalCommandError ? error51.code : -32073,
44146
+ errorMessage4(error51)
44147
+ )
44148
+ );
44149
+ }
44150
+ }
44151
+ async #startExternalQueuedTurn(request, thread) {
44152
+ const params = requestObject(request);
44153
+ const queuedSubmissionId = typeof params.queuedSubmissionId === "string" ? params.queuedSubmissionId : void 0;
44154
+ const queued = this.#followUps.take(thread.id, queuedSubmissionId);
44155
+ if (!queued) {
44156
+ await this.#writer.json(rpcError(request, -32602, "Queued follow-up was not found"));
44157
+ return;
44158
+ }
44159
+ await this.#startExternalFromFollowUp(request, thread, queued);
44160
+ }
43569
44161
  async #startExternalTurn(request, thread) {
43570
44162
  if (this.#externalThreadBusy(thread) || this.#pendingExternalCommandRequests.has(thread.id)) {
43571
44163
  await this.#writer.json(
@@ -43590,10 +44182,21 @@ var AppServerHost = class {
43590
44182
  }
43591
44183
  }
43592
44184
  let text;
44185
+ const clientUserMessageId = typeof params.clientUserMessageId === "string" ? params.clientUserMessageId : void 0;
43593
44186
  try {
43594
44187
  text = requestText(params);
43595
44188
  } catch (error51) {
43596
- await this.#writer.json(rpcError(request, -32602, errorMessage4(error51)));
44189
+ const queued = this.#followUps.take(thread.id, clientUserMessageId) ?? this.#followUps.take(thread.id);
44190
+ if (!queued) {
44191
+ await this.#writer.json(rpcError(request, -32602, errorMessage4(error51)));
44192
+ return;
44193
+ }
44194
+ await this.#startExternalFromFollowUp(
44195
+ request,
44196
+ thread,
44197
+ queued,
44198
+ params[THREAD_REFERENCE_SOURCE_HOST_PARAM]
44199
+ );
43597
44200
  return;
43598
44201
  }
43599
44202
  try {
@@ -43601,7 +44204,7 @@ var AppServerHost = class {
43601
44204
  thread,
43602
44205
  text,
43603
44206
  void 0,
43604
- typeof params.clientUserMessageId === "string" ? params.clientUserMessageId : void 0,
44207
+ clientUserMessageId,
43605
44208
  params[THREAD_REFERENCE_SOURCE_HOST_PARAM]
43606
44209
  );
43607
44210
  try {
@@ -43630,10 +44233,15 @@ var AppServerHost = class {
43630
44233
  assertActive,
43631
44234
  typeof requestObject(request).clientUserMessageId === "string" ? requestObject(request).clientUserMessageId : void 0,
43632
44235
  requestObject(request)[THREAD_REFERENCE_SOURCE_HOST_PARAM]
43633
- )
44236
+ ),
44237
+ (input) => this.#insertExternalInput(thread, input)
43634
44238
  );
43635
44239
  try {
43636
- await this.#writer.json(rpcEnvelope(request, { result: { turnId: started.turnId } }));
44240
+ await this.#writer.json(
44241
+ rpcEnvelope(request, {
44242
+ result: { turnId: started.turnId, delivery: started.delivery }
44243
+ })
44244
+ );
43637
44245
  } finally {
43638
44246
  started.gate.resolve();
43639
44247
  }
@@ -43649,6 +44257,34 @@ var AppServerHost = class {
43649
44257
  this.#signalActiveWorkChanged();
43650
44258
  }
43651
44259
  }
44260
+ /** Native same-Turn input; `insertNativeSteer` owns the delivery and its fallback signal. */
44261
+ async #insertExternalInput(thread, input) {
44262
+ await insertNativeSteer(thread, input, {
44263
+ project: async (turnId, item, clientUserMessageId) => {
44264
+ const projection = this.#projectedTurn(thread, turnId);
44265
+ if (clientUserMessageId) {
44266
+ projection.projector.bindUserMessageClientId(item.itemId, clientUserMessageId);
44267
+ }
44268
+ await this.#projectHarnessOutput(thread, {
44269
+ kind: "event",
44270
+ event: { type: "item.started", turnId, item }
44271
+ });
44272
+ await this.#projectHarnessOutput(thread, {
44273
+ kind: "event",
44274
+ event: {
44275
+ type: "item.completed",
44276
+ turnId,
44277
+ snapshot: { item, outcome: { status: "succeeded" } }
44278
+ }
44279
+ });
44280
+ },
44281
+ diagnose: (error51) => this.#diagnose(error51)
44282
+ });
44283
+ return {
44284
+ turnId: input.turnId,
44285
+ gate: { promise: Promise.resolve(), resolve: () => void 0 }
44286
+ };
44287
+ }
43652
44288
  /** Keep command restoration and dispatch identical for start and steer submissions. */
43653
44289
  async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId, sourceHostId) {
43654
44290
  const text = restoreHarnessCommandMentions(inputText);
@@ -43706,7 +44342,7 @@ var AppServerHost = class {
43706
44342
  if (thread.running || thread.activeTurnId || this.#pendingExternalCommandRequests.has(thread.id)) {
43707
44343
  throw new ExternalSteerError(-32072, "External Thread already has an active Turn");
43708
44344
  }
43709
- const turnId = hostTurnIdSchema.parse(randomUUID16());
44345
+ const turnId = hostTurnIdSchema.parse(randomUUID19());
43710
44346
  const startedAtMs = Date.now();
43711
44347
  const projection = {
43712
44348
  projector: new CodexTurnProjector({
@@ -44000,8 +44636,14 @@ var AppServerHost = class {
44000
44636
  }
44001
44637
  return;
44002
44638
  }
44639
+ if (event.type === "turn.completed" && thread.pendingSteerProjections.size > 0) {
44640
+ await Promise.allSettled([...thread.pendingSteerProjections]);
44641
+ }
44003
44642
  const projection = this.#projectedTurn(thread, event.turnId);
44004
44643
  await this.#waitForTurnResponse(thread, event.turnId);
44644
+ if (event.type === "item.completed" && event.snapshot.item.type === "agentMessage" && this.#externalVoice.has(thread.id)) {
44645
+ projection.realtimeInline = true;
44646
+ }
44005
44647
  if (event.type === "interaction.closed" && thread.ignoredInteractionIds.delete(event.interactionId)) {
44006
44648
  return;
44007
44649
  }
@@ -44041,7 +44683,9 @@ var AppServerHost = class {
44041
44683
  thread.ephemeralTurnIds.delete(event.turnId);
44042
44684
  this.#manualCompactionTurns.delete(thread);
44043
44685
  } else {
44044
- thread.turns.push(result.completedTurn);
44686
+ thread.turns.push(
44687
+ projection.realtimeInline ? presentExternalVoiceTurn(result.completedTurn) : result.completedTurn
44688
+ );
44045
44689
  thread.projectedTerminalTurnId = event.turnId;
44046
44690
  thread.thread.updatedAt = completedAt;
44047
44691
  thread.thread.recencyAt = completedAt;
@@ -44051,6 +44695,7 @@ var AppServerHost = class {
44051
44695
  thread.activeTurnId = null;
44052
44696
  if (!projection.projector.hasOpenDetachedItems) thread.projectedTurns.delete(event.turnId);
44053
44697
  thread.responseGates.delete(event.turnId);
44698
+ thread.pendingSteerProjections.clear();
44054
44699
  this.#signalActiveWorkChanged();
44055
44700
  const delegation = await this.#repository.getDelegationByChild(thread.record.hostThreadId);
44056
44701
  if (delegation) {
@@ -44067,7 +44712,11 @@ var AppServerHost = class {
44067
44712
  if (event.type === "item.completed" && projection.projector.completed && !projection.projector.hasOpenDetachedItems) {
44068
44713
  thread.projectedTurns.delete(event.turnId);
44069
44714
  }
44070
- for (const message2 of result.messages) await this.#writer.json(message2);
44715
+ for (const message2 of result.messages) {
44716
+ await this.#writer.json(
44717
+ projection.realtimeInline ? presentExternalVoiceMessage(message2) : message2
44718
+ );
44719
+ }
44071
44720
  this.#externalVoiceResults.observe(
44072
44721
  thread.id,
44073
44722
  event,
@@ -44126,7 +44775,7 @@ var AppServerHost = class {
44126
44775
  const previousItems = new Map(
44127
44776
  child.turns.flatMap(
44128
44777
  (turn) => Array.isArray(turn.items) ? turn.items.flatMap(
44129
- (item) => isRecord20(item) && typeof item.id === "string" ? [[item.id, JSON.stringify(item)]] : []
44778
+ (item) => isRecord21(item) && typeof item.id === "string" ? [[item.id, JSON.stringify(item)]] : []
44130
44779
  ) : []
44131
44780
  )
44132
44781
  );
@@ -44139,7 +44788,7 @@ var AppServerHost = class {
44139
44788
  for (const turn of child.turns) {
44140
44789
  if (typeof turn.id !== "string" || !Array.isArray(turn.items)) continue;
44141
44790
  const changedItems = turn.items.filter(
44142
- (item) => isRecord20(item) && typeof item.id === "string" && previousItems.get(item.id) !== JSON.stringify(item)
44791
+ (item) => isRecord21(item) && typeof item.id === "string" && previousItems.get(item.id) !== JSON.stringify(item)
44143
44792
  );
44144
44793
  if (changedItems.length > 0) {
44145
44794
  await this.#writer.json({
@@ -44271,7 +44920,7 @@ var AppServerHost = class {
44271
44920
  }
44272
44921
  }
44273
44922
  async #handleDesktopApprovalResponse(value2) {
44274
- if (!isRecord20(value2) || !isHostApprovalRequestId(value2.id)) return false;
44923
+ if (!isRecord21(value2) || !isHostApprovalRequestId(value2.id)) return false;
44275
44924
  const requestId2 = value2.id;
44276
44925
  const pending = this.#pendingDesktopApprovals.get(requestId2);
44277
44926
  if (!pending) return true;
@@ -44355,7 +45004,7 @@ var AppServerHost = class {
44355
45004
  try {
44356
45005
  result = projection.projector.projectQuestion(
44357
45006
  interaction,
44358
- hostItemIdSchema.parse(randomUUID16())
45007
+ hostItemIdSchema.parse(randomUUID19())
44359
45008
  );
44360
45009
  } catch (error51) {
44361
45010
  this.#diagnose(error51);
@@ -44400,7 +45049,7 @@ var AppServerHost = class {
44400
45049
  }
44401
45050
  }
44402
45051
  async #handleDesktopQuestionResponse(value2) {
44403
- if (!isRecord20(value2) || !isHostQuestionRequestId(value2.id)) return false;
45052
+ if (!isRecord21(value2) || !isHostQuestionRequestId(value2.id)) return false;
44404
45053
  const requestId2 = value2.id;
44405
45054
  const pending = this.#pendingDesktopQuestions.get(requestId2);
44406
45055
  if (!pending) return true;
@@ -44583,7 +45232,7 @@ import path30 from "node:path";
44583
45232
  import { PassThrough } from "node:stream";
44584
45233
 
44585
45234
  // packages/host-runtime/src/remote-socket-lock.ts
44586
- import { randomUUID as randomUUID17 } from "node:crypto";
45235
+ import { randomUUID as randomUUID20 } from "node:crypto";
44587
45236
  import { chmod as chmod3, lstat as lstat5, mkdir as mkdir14, open as open9, readFile as readFile18, readdir as readdir5, rename as rename12, rm as rm13 } from "node:fs/promises";
44588
45237
  import { uptime } from "node:os";
44589
45238
  import path29 from "node:path";
@@ -44709,7 +45358,7 @@ async function preparePrivateLockDirectory(lockDirectory) {
44709
45358
  await chmod3(lockDirectory, 448);
44710
45359
  }
44711
45360
  async function writeLockRecordAtomic(lockDirectory, entryPath, record4) {
44712
- const temporary = path29.join(lockDirectory, `.tmp-${record4.ownerToken}-${randomUUID17()}`);
45361
+ const temporary = path29.join(lockDirectory, `.tmp-${record4.ownerToken}-${randomUUID20()}`);
44713
45362
  const handle = await open9(temporary, "wx", 384);
44714
45363
  try {
44715
45364
  await handle.writeFile(`${JSON.stringify(record4)}
@@ -44784,7 +45433,7 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
44784
45433
  const legacyPath = `${socketPath}.initializing`;
44785
45434
  const lockDirectory = `${socketPath}.initializers`;
44786
45435
  await preparePrivateLockDirectory(lockDirectory);
44787
- const ownerToken = randomUUID17();
45436
+ const ownerToken = randomUUID20();
44788
45437
  const entryPath = path29.join(lockDirectory, lockEntryName(ownerToken));
44789
45438
  const baseRecord = {
44790
45439
  version: 2,
@@ -45295,12 +45944,12 @@ function createRemoteAppServerWebSocketListener(input) {
45295
45944
 
45296
45945
  // packages/host-runtime/src/remote-official-app-server.ts
45297
45946
  import { spawn as spawn5 } from "node:child_process";
45298
- import { randomUUID as randomUUID18 } from "node:crypto";
45947
+ import { randomUUID as randomUUID21 } from "node:crypto";
45299
45948
  import { lstat as lstat7, rm as rm15, stat as stat7 } from "node:fs/promises";
45300
45949
  import path31 from "node:path";
45301
45950
  var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
45302
45951
  var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
45303
- function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID18()) {
45952
+ function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID21()) {
45304
45953
  if (!path31.posix.isAbsolute(desktopControlSocketPath)) {
45305
45954
  throw new Error("Desktop control socket path must be absolute");
45306
45955
  }
@@ -46586,12 +47235,12 @@ async function readRemoteDelegationThread(environment, input) {
46586
47235
  }
46587
47236
 
46588
47237
  // packages/host-runtime/src/shared-thread-owner.ts
46589
- import { randomUUID as randomUUID20 } from "node:crypto";
47238
+ import { randomUUID as randomUUID23 } from "node:crypto";
46590
47239
  import { PassThrough as PassThrough3 } from "node:stream";
46591
47240
 
46592
47241
  // packages/host-runtime/src/shared-thread-peer.ts
46593
- import { randomUUID as randomUUID19 } from "node:crypto";
46594
- function object8(value2) {
47242
+ import { randomUUID as randomUUID22 } from "node:crypto";
47243
+ function object9(value2) {
46595
47244
  return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
46596
47245
  }
46597
47246
  var StreamThreadPeer = class {
@@ -46604,7 +47253,7 @@ var StreamThreadPeer = class {
46604
47253
  input;
46605
47254
  output;
46606
47255
  stop;
46607
- #prefix = `shared:${randomUUID19()}:`;
47256
+ #prefix = `shared:${randomUUID22()}:`;
46608
47257
  #pending = /* @__PURE__ */ new Map();
46609
47258
  #listeners = /* @__PURE__ */ new Set();
46610
47259
  #ended = Promise.withResolvers();
@@ -46647,7 +47296,7 @@ var StreamThreadPeer = class {
46647
47296
  async #read() {
46648
47297
  for await (const frame of readLfFrames(this.input)) {
46649
47298
  const message2 = parseJsonFrame(frame);
46650
- if (!object8(message2)) throw new Error("Invalid shared Thread response");
47299
+ if (!object9(message2)) throw new Error("Invalid shared Thread response");
46651
47300
  if (typeof message2.method !== "string") {
46652
47301
  const pending = typeof message2.id === "string" ? this.#pending.get(message2.id) : void 0;
46653
47302
  if (pending) {
@@ -46682,7 +47331,7 @@ var SharedThreadOwner = class {
46682
47331
  input = new PassThrough3();
46683
47332
  output = new PassThrough3();
46684
47333
  #peer = new StreamThreadPeer(this.output, this.input, () => this.input.end());
46685
- #prefix = `shared-interaction:${randomUUID20()}:`;
47334
+ #prefix = `shared-interaction:${randomUUID23()}:`;
46686
47335
  #interactions = /* @__PURE__ */ new Map();
46687
47336
  #listeners = /* @__PURE__ */ new Set();
46688
47337
  #receipts = /* @__PURE__ */ new Map();
@@ -46693,7 +47342,7 @@ var SharedThreadOwner = class {
46693
47342
  const id2 = `${this.#prefix}${message2.id}`;
46694
47343
  event = { ...message2, id: id2 };
46695
47344
  this.#interactions.set(id2, { nativeId: message2.id, message: event });
46696
- } else if (message2.method === "serverRequest/resolved" && object8(message2.params)) {
47345
+ } else if (message2.method === "serverRequest/resolved" && object9(message2.params)) {
46697
47346
  const id2 = `${this.#prefix}${message2.params.requestId}`;
46698
47347
  this.#interactions.delete(id2);
46699
47348
  event = { ...message2, params: { ...message2.params, requestId: id2 } };
@@ -46788,7 +47437,7 @@ var SharedThreadOwner = class {
46788
47437
  const parsed2 = jsonRpcRequestSchema.safeParse(message2);
46789
47438
  if (parsed2.success) {
46790
47439
  const request = parsed2.data;
46791
- void peer.request(request.method, object8(request.params) ? request.params : {}).then(
47440
+ void peer.request(request.method, object9(request.params) ? request.params : {}).then(
46792
47441
  (reply2) => send({ ...reply2, id: request.id }),
46793
47442
  () => send({
46794
47443
  id: request.id,
@@ -46798,7 +47447,7 @@ var SharedThreadOwner = class {
46798
47447
  }
46799
47448
  })
46800
47449
  );
46801
- } else if (object8(message2) && rpcId(message2.id)) {
47450
+ } else if (object9(message2) && rpcId(message2.id)) {
46802
47451
  await peer.respond(message2);
46803
47452
  }
46804
47453
  }
@@ -46883,8 +47532,8 @@ var SharedThreadBridge = class {
46883
47532
  }
46884
47533
  this.#peer = peer;
46885
47534
  peer.subscribe((message2) => {
46886
- const params = object8(message2.params) ? message2.params : {};
46887
- if (object8(params.thread) && params.thread.modelProvider === "codexhost" && typeof params.thread.id === "string") {
47535
+ const params = object9(message2.params) ? message2.params : {};
47536
+ if (object9(params.thread) && params.thread.modelProvider === "codexhost" && typeof params.thread.id === "string") {
46888
47537
  this.#known.add(params.thread.id);
46889
47538
  }
46890
47539
  this.#publish(message2);
@@ -46928,7 +47577,7 @@ var SharedThreadBridge = class {
46928
47577
  return owners;
46929
47578
  }
46930
47579
  async route(request) {
46931
- const params = object8(request.params) ? request.params : {};
47580
+ const params = object9(request.params) ? request.params : {};
46932
47581
  const create = this.options.delegateCreates ? classifyCreateRequestRoute(request) : null;
46933
47582
  let shared = create !== null && create.selectedHarness !== "codex";
46934
47583
  if (!shared && typeof params.threadId === "string") {
@@ -46945,10 +47594,10 @@ var SharedThreadBridge = class {
46945
47594
  const seen = /* @__PURE__ */ new Set();
46946
47595
  do {
46947
47596
  const reply2 = await peer.request("thread/list", { ...params, cursor, limit: 200 });
46948
- if (!object8(reply2.result) || !Array.isArray(reply2.result.data))
47597
+ if (!object9(reply2.result) || !Array.isArray(reply2.result.data))
46949
47598
  throw new Error("Shared Thread list failed");
46950
47599
  for (const row of reply2.result.data) {
46951
- if (!object8(row) || typeof row.id !== "string")
47600
+ if (!object9(row) || typeof row.id !== "string")
46952
47601
  throw new Error("Invalid shared Thread row");
46953
47602
  rows.push(row);
46954
47603
  this.#known.add(row.id);
@@ -46977,7 +47626,7 @@ var SharedThreadBridge = class {
46977
47626
  return storedSectionPlacementV1Schema.array().parse(reply2.result);
46978
47627
  }
46979
47628
  async respond(message2) {
46980
- if (!object8(message2) || typeof message2.method === "string" || typeof message2.id !== "string" || !message2.id.startsWith("shared-interaction:"))
47629
+ if (!object9(message2) || typeof message2.method === "string" || typeof message2.id !== "string" || !message2.id.startsWith("shared-interaction:"))
46981
47630
  return false;
46982
47631
  if (!this.#peer) throw new Error("Shared Thread Host is disconnected");
46983
47632
  await this.#peer.respond(message2);
@@ -46992,7 +47641,7 @@ var SharedThreadBridge = class {
46992
47641
  };
46993
47642
 
46994
47643
  // packages/host-runtime/src/remote-control-app-server.ts
46995
- import { randomUUID as randomUUID21 } from "node:crypto";
47644
+ import { randomUUID as randomUUID24 } from "node:crypto";
46996
47645
  import { mkdir as mkdir17, open as open10, rename as rename13, rm as rm17 } from "node:fs/promises";
46997
47646
  import path37 from "node:path";
46998
47647
  var REMOTE_CONTROL_BRIDGE_PIPE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_PIPE";
@@ -47013,7 +47662,7 @@ function nodeCompatibleWindowsPath(value2) {
47013
47662
  if (value2.startsWith("\\\\?\\")) return value2.slice(4);
47014
47663
  return value2;
47015
47664
  }
47016
- function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID21()) {
47665
+ function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID24()) {
47017
47666
  const safeInstance = instanceId.replaceAll(/[^a-zA-Z0-9-]/gu, "");
47018
47667
  if (!safeInstance) throw new Error("Remote Control bridge instance ID is invalid");
47019
47668
  return `\\\\.\\pipe\\codexhost-remote-control-${processId}-${safeInstance}`;
@@ -47028,7 +47677,7 @@ async function publishRemoteControlAppServerDescriptor(plan) {
47028
47677
  await mkdir17(directory, { recursive: true, mode: 448 });
47029
47678
  const temporaryPath = path37.join(
47030
47679
  directory,
47031
- `.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID21()}.tmp`
47680
+ `.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID24()}.tmp`
47032
47681
  );
47033
47682
  const handle = await open10(temporaryPath, "wx", 384);
47034
47683
  try {
@@ -47569,12 +48218,19 @@ function createHostUpdateCoordinator(options2) {
47569
48218
  }
47570
48219
 
47571
48220
  // packages/host-runtime/src/usage-statistics.ts
47572
- import { randomUUID as randomUUID22 } from "node:crypto";
48221
+ import { randomUUID as randomUUID25 } from "node:crypto";
47573
48222
  import { mkdir as mkdir19, readFile as readFile20, readdir as readdir6, rename as rename15, rm as rm19, writeFile as writeFile11 } from "node:fs/promises";
47574
48223
  import path40 from "node:path";
47575
48224
  import { setImmediate as yieldToEventLoop } from "node:timers/promises";
47576
48225
 
47577
48226
  // packages/harness-adapter/dist/usage-statistics.js
48227
+ var HarnessUsageSourceChangedError = class extends Error {
48228
+ code = "HARNESS_USAGE_SOURCE_CHANGED";
48229
+ /** Plugins may bundle their own copy of this contract, so instanceof is insufficient. */
48230
+ static is(error51) {
48231
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "HARNESS_USAGE_SOURCE_CHANGED";
48232
+ }
48233
+ };
47578
48234
  var MAX_SESSION_ID_LENGTH = 512;
47579
48235
  var MAX_CWD_LENGTH = 4096;
47580
48236
  var MAX_SESSION_TITLE_LENGTH = 200;
@@ -47677,6 +48333,95 @@ function withHostSessionTitles(result, records) {
47677
48333
  };
47678
48334
  }
47679
48335
 
48336
+ // packages/host-runtime/src/usage-statistics-sources.ts
48337
+ import { setTimeout as delay7 } from "node:timers/promises";
48338
+ async function* readUsageStatisticsSources(capability, sources, signal) {
48339
+ let pending = sources;
48340
+ for (let attempt = 0; ; attempt++) {
48341
+ const changed = [];
48342
+ for (const source of pending) {
48343
+ signal.throwIfAborted();
48344
+ try {
48345
+ const entries = (await capability.readSource(source.id, signal)).map(parseHarnessUsageEntry).filter((entry) => entry !== null);
48346
+ yield { source, entries };
48347
+ } catch (error51) {
48348
+ signal.throwIfAborted();
48349
+ if (HarnessUsageSourceChangedError.is(error51) && attempt < 2) changed.push(source);
48350
+ else yield { source, error: error51 };
48351
+ }
48352
+ }
48353
+ if (!changed.length) return;
48354
+ await delay7(50 * (attempt + 1), void 0, { signal });
48355
+ let current;
48356
+ try {
48357
+ current = new Map(
48358
+ (await capability.listSources(signal)).map((source) => [source.id, source])
48359
+ );
48360
+ } catch (error51) {
48361
+ signal.throwIfAborted();
48362
+ for (const source of changed) yield { source, error: error51 };
48363
+ return;
48364
+ }
48365
+ const next = [];
48366
+ for (const source of changed) {
48367
+ const fresh = current.get(source.id);
48368
+ if (fresh) next.push(fresh);
48369
+ else yield { source, removed: true };
48370
+ }
48371
+ pending = next;
48372
+ }
48373
+ }
48374
+
48375
+ // packages/host-runtime/src/usage-statistics-calendar.ts
48376
+ function dateKey(year, month, day) {
48377
+ return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
48378
+ }
48379
+ function createUsageStatisticsCalendar(timeZone) {
48380
+ const localZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
48381
+ const zone = timeZone ?? localZone;
48382
+ if (zone === localZone) {
48383
+ return {
48384
+ timeZone: zone,
48385
+ at(ms) {
48386
+ const date5 = new Date(ms);
48387
+ return {
48388
+ date: dateKey(date5.getFullYear(), date5.getMonth() + 1, date5.getDate()),
48389
+ weekday: date5.getDay(),
48390
+ hour: date5.getHours()
48391
+ };
48392
+ }
48393
+ };
48394
+ }
48395
+ const format = new Intl.DateTimeFormat("en-US", {
48396
+ timeZone: zone,
48397
+ calendar: "gregory",
48398
+ numberingSystem: "latn",
48399
+ year: "numeric",
48400
+ month: "2-digit",
48401
+ day: "2-digit",
48402
+ hour: "2-digit",
48403
+ hourCycle: "h23"
48404
+ });
48405
+ return {
48406
+ timeZone: zone,
48407
+ at(ms) {
48408
+ const parts = format.formatToParts(ms);
48409
+ const part = (type) => Number(parts.find((value2) => value2.type === type)?.value);
48410
+ const year = part("year"), month = part("month"), day = part("day");
48411
+ return {
48412
+ date: dateKey(year, month, day),
48413
+ weekday: new Date(Date.UTC(year, month - 1, day)).getUTCDay(),
48414
+ hour: part("hour")
48415
+ };
48416
+ }
48417
+ };
48418
+ }
48419
+ function shiftUsageDate(date5, days) {
48420
+ const value2 = /* @__PURE__ */ new Date(`${date5}T12:00:00Z`);
48421
+ value2.setUTCDate(value2.getUTCDate() + days);
48422
+ return dateKey(value2.getUTCFullYear(), value2.getUTCMonth() + 1, value2.getUTCDate());
48423
+ }
48424
+
47680
48425
  // packages/host-runtime/src/usage-statistics.ts
47681
48426
  var CACHE_VERSION = 7;
47682
48427
  var STALE_AFTER_MS = 1e4;
@@ -47737,17 +48482,6 @@ function expand(value2, intern) {
47737
48482
  function message(error51) {
47738
48483
  return error51 instanceof Error ? error51.message : String(error51);
47739
48484
  }
47740
- function localDate2(ms) {
47741
- const date5 = new Date(ms);
47742
- const month = String(date5.getMonth() + 1).padStart(2, "0");
47743
- const day = String(date5.getDate()).padStart(2, "0");
47744
- return `${date5.getFullYear()}-${month}-${day}`;
47745
- }
47746
- function shiftDate(date5, days) {
47747
- const value2 = /* @__PURE__ */ new Date(`${date5}T12:00:00`);
47748
- value2.setDate(value2.getDate() + days);
47749
- return localDate2(value2.getTime());
47750
- }
47751
48485
  var SESSIONS_PER_MEASURE = 50;
47752
48486
  var MODELS_PER_SESSION = 16;
47753
48487
  function emptyTotals() {
@@ -47934,23 +48668,27 @@ var UsageStatistics = class {
47934
48668
  }
47935
48669
  for (const { harness: harness2, capability, ids } of listed) {
47936
48670
  const cache = this.#cache(harness2);
47937
- const present = /* @__PURE__ */ new Set();
48671
+ const present = new Set(ids.map(({ id: id2 }) => id2));
47938
48672
  let failed = null;
47939
- for (const { id: id2, fingerprint } of ids) {
47940
- present.add(id2);
47941
- if (cache.sources.get(id2)?.fingerprint !== fingerprint) {
47942
- try {
47943
- const entries = (await capability.readSource(id2, signal)).map(parseHarnessUsageEntry).filter((entry) => entry !== null);
47944
- cache.sources.set(id2, { fingerprint, entries });
48673
+ const pending = ids.filter(
48674
+ ({ id: id2, fingerprint }) => cache.sources.get(id2)?.fingerprint !== fingerprint
48675
+ );
48676
+ this.#progress.read += ids.length - pending.length;
48677
+ try {
48678
+ for await (const result of readUsageStatisticsSources(capability, pending, signal)) {
48679
+ const { id: id2, fingerprint } = result.source;
48680
+ if ("entries" in result) {
48681
+ cache.sources.set(id2, { fingerprint, entries: result.entries });
47945
48682
  cache.dirty = true;
47946
48683
  this.#generation += 1;
47947
- } catch (error51) {
47948
- if (signal.aborted) return;
47949
- failed ??= message(error51);
47950
- }
48684
+ } else if ("error" in result) failed ??= message(result.error);
48685
+ else present.delete(id2);
48686
+ this.#progress.read += 1;
47951
48687
  await yieldToEventLoop();
47952
48688
  }
47953
- this.#progress.read += 1;
48689
+ } catch (error51) {
48690
+ if (signal.aborted) return;
48691
+ throw error51;
47954
48692
  }
47955
48693
  for (const id2 of cache.sources.keys()) {
47956
48694
  if (!present.has(id2)) {
@@ -48015,7 +48753,7 @@ var UsageStatistics = class {
48015
48753
  async #persist(harness2, cache) {
48016
48754
  if (!cache.dirty || this.#now() - cache.persistedAtMs < PERSIST_INTERVAL_MS) return;
48017
48755
  const file2 = this.#file(harness2);
48018
- const temporary = `${file2}.${randomUUID22()}.tmp`;
48756
+ const temporary = `${file2}.${randomUUID25()}.tmp`;
48019
48757
  try {
48020
48758
  await mkdir19(this.#directory, { recursive: true });
48021
48759
  const sources = [...cache.sources].map(([id2, source]) => [
@@ -48033,9 +48771,10 @@ var UsageStatistics = class {
48033
48771
  await rm19(temporary, { force: true });
48034
48772
  }
48035
48773
  }
48036
- /** Every request once, per Harness in source order, with its local date and hour. */
48037
- #indexed() {
48038
- if (this.#index?.generation === this.#generation) return this.#index.entries;
48774
+ /** Every request once, per Harness in source order, in the requested calendar. */
48775
+ #indexed(calendar) {
48776
+ if (this.#index?.generation === this.#generation && this.#index.timeZone === calendar.timeZone)
48777
+ return this.#index.entries;
48039
48778
  const entries = [];
48040
48779
  for (const [harness2, cache] of this.#caches) {
48041
48780
  const seen = /* @__PURE__ */ new Set();
@@ -48043,26 +48782,20 @@ var UsageStatistics = class {
48043
48782
  for (const entry of parsed2) {
48044
48783
  if (seen.has(entry.id)) continue;
48045
48784
  seen.add(entry.id);
48046
- const at = new Date(entry.occurredAtMs);
48047
- entries.push({
48048
- harness: harness2,
48049
- entry,
48050
- date: localDate2(entry.occurredAtMs),
48051
- weekday: at.getDay(),
48052
- hour: at.getHours()
48053
- });
48785
+ entries.push({ harness: harness2, entry, ...calendar.at(entry.occurredAtMs) });
48054
48786
  }
48055
48787
  }
48056
48788
  }
48057
- this.#index = { generation: this.#generation, entries };
48789
+ this.#index = { generation: this.#generation, timeZone: calendar.timeZone, entries };
48058
48790
  return entries;
48059
48791
  }
48060
48792
  #aggregate(params, now, lookup) {
48061
48793
  const { range } = params;
48062
48794
  const days = RANGE_DAYS[range];
48063
- const to = localDate2(now);
48795
+ const calendar = createUsageStatisticsCalendar(params.timeZone);
48796
+ const to = calendar.at(now).date;
48064
48797
  let from = null;
48065
- if (days !== null) from = shiftDate(to, -days + 1);
48798
+ if (days !== null) from = shiftUsageDate(to, -days + 1);
48066
48799
  const inRange = (date5) => (from === null || date5 >= from) && date5 <= to;
48067
48800
  const day = params.date !== void 0 && inRange(params.date) ? params.date : null;
48068
48801
  const harnessFilter = params.harness ?? null;
@@ -48103,7 +48836,7 @@ var UsageStatistics = class {
48103
48836
  const harnessPriced = /* @__PURE__ */ new Map();
48104
48837
  const byProject = /* @__PURE__ */ new Map();
48105
48838
  const sessions = /* @__PURE__ */ new Map();
48106
- for (const indexed of this.#indexed()) {
48839
+ for (const indexed of this.#indexed(calendar)) {
48107
48840
  const { harness: harness2, entry, date: date5 } = indexed;
48108
48841
  if (!inRange(date5)) continue;
48109
48842
  const model2 = entry.model ?? null;
@@ -48636,7 +49369,7 @@ async function runHostRuntime(input) {
48636
49369
  }
48637
49370
 
48638
49371
  // packages/host-runtime/src/remote-host-install.ts
48639
- import { createHash as createHash12, randomUUID as randomUUID23 } from "node:crypto";
49372
+ import { createHash as createHash12, randomUUID as randomUUID26 } from "node:crypto";
48640
49373
  import { constants as fsConstants } from "node:fs";
48641
49374
  import {
48642
49375
  access as access4,
@@ -48735,7 +49468,7 @@ async function writeAtomic(filePath, contents, mode) {
48735
49468
  await mkdir20(path42.dirname(filePath), { recursive: true, mode: 448 });
48736
49469
  const temporary = path42.join(
48737
49470
  path42.dirname(filePath),
48738
- `.${path42.basename(filePath)}.${process.pid}.${randomUUID23()}.tmp`
49471
+ `.${path42.basename(filePath)}.${process.pid}.${randomUUID26()}.tmp`
48739
49472
  );
48740
49473
  try {
48741
49474
  if (typeof contents === "string") {
@@ -48759,7 +49492,7 @@ async function writeAtomicExecutable(filePath, sourcePath) {
48759
49492
  await mkdir20(path42.dirname(filePath), { recursive: true, mode: 448 });
48760
49493
  const temporary = path42.join(
48761
49494
  path42.dirname(filePath),
48762
- `.${path42.basename(filePath)}.${process.pid}.${randomUUID23()}.tmp`
49495
+ `.${path42.basename(filePath)}.${process.pid}.${randomUUID26()}.tmp`
48763
49496
  );
48764
49497
  try {
48765
49498
  await copyFile4(sourcePath, temporary);
@@ -49500,6 +50233,7 @@ var harnessBrokerMethodSchema = external_exports.enum([
49500
50233
  "adapter.open",
49501
50234
  "adapter.subagent.readSnapshot",
49502
50235
  "session.readSnapshot",
50236
+ "session.readCapabilities",
49503
50237
  "session.refreshUsage",
49504
50238
  "session.execute",
49505
50239
  "session.commands.list",
@@ -49682,6 +50416,11 @@ var turnStartSchema = external_exports.object({
49682
50416
  turnId: hostTurnIdSchema,
49683
50417
  input: external_exports.array(textInputSchema)
49684
50418
  }).strict();
50419
+ var turnSteerSchema = external_exports.object({
50420
+ type: external_exports.literal("turn.steer"),
50421
+ turnId: hostTurnIdSchema,
50422
+ input: external_exports.array(textInputSchema)
50423
+ }).strict();
49685
50424
  var turnCancelSchema = external_exports.object({ type: external_exports.literal("turn.cancel"), turnId: hostTurnIdSchema }).strict();
49686
50425
  var interactionResponseSchema = external_exports.union([
49687
50426
  external_exports.object({
@@ -49707,6 +50446,7 @@ var permissionSelectSchema = external_exports.object({
49707
50446
  }).strict();
49708
50447
  var brokerHostCommandSchema = external_exports.discriminatedUnion("type", [
49709
50448
  turnStartSchema,
50449
+ turnSteerSchema,
49710
50450
  turnCancelSchema,
49711
50451
  interactionRespondSchema,
49712
50452
  modelSelectSchema,
@@ -49841,7 +50581,7 @@ var harnessOutputSchema = external_exports.custom((value2) => {
49841
50581
  });
49842
50582
 
49843
50583
  // packages/harness-broker/dist/server.js
49844
- import { randomBytes as randomBytes5, randomUUID as randomUUID24 } from "node:crypto";
50584
+ import { randomBytes as randomBytes5, randomUUID as randomUUID27 } from "node:crypto";
49845
50585
  import { chmod as chmod6, lstat as lstat10, mkdir as mkdir21, open as open11, readFile as readFile22, rename as rename17, rm as rm21 } from "node:fs/promises";
49846
50586
  import net4, {} from "node:net";
49847
50587
  import path45 from "node:path";
@@ -49900,7 +50640,7 @@ async function assertNoLiveDescriptor(descriptorPath) {
49900
50640
  }
49901
50641
  }
49902
50642
  async function publishDescriptor(descriptorPath, descriptor) {
49903
- const temporary = `${descriptorPath}.${process.pid}.${randomUUID24()}.tmp`;
50643
+ const temporary = `${descriptorPath}.${process.pid}.${randomUUID27()}.tmp`;
49904
50644
  const handle = await open11(temporary, "wx", 384);
49905
50645
  try {
49906
50646
  await handle.writeFile(`${JSON.stringify(descriptor)}
@@ -49925,6 +50665,7 @@ function sessionMetadata(record4) {
49925
50665
  sessionId: record4.id,
49926
50666
  sessionGeneration: record4.generation,
49927
50667
  capabilities: record4.session.capabilities,
50668
+ readCapabilities: true,
49928
50669
  initialState: {
49929
50670
  ...initialState,
49930
50671
  ...record4.nativeRef ? { nativeRef: record4.nativeRef } : {},
@@ -49977,7 +50718,7 @@ async function startHarnessBrokerServer(input) {
49977
50718
  await assertNoLiveDescriptor(input.descriptorPath);
49978
50719
  if (process.platform !== "win32")
49979
50720
  await prepareUnixSocketPath(input.socketPath);
49980
- const generation = input.generation ?? randomUUID24();
50721
+ const generation = input.generation ?? randomUUID27();
49981
50722
  const token = input.token ?? randomBytes5(32).toString("hex");
49982
50723
  const descriptor = {
49983
50724
  schemaVersion: 1,
@@ -50018,7 +50759,7 @@ async function startHarnessBrokerServer(input) {
50018
50759
  };
50019
50760
  const server = net4.createServer((socket) => {
50020
50761
  const state = {
50021
- id: randomUUID24(),
50762
+ id: randomUUID27(),
50022
50763
  socket,
50023
50764
  authenticated: false,
50024
50765
  inputSequence: 0,
@@ -50256,7 +50997,7 @@ async function startHarnessBrokerServer(input) {
50256
50997
  }
50257
50998
  };
50258
50999
  }
50259
- const openReservation = randomUUID24();
51000
+ const openReservation = randomUUID27();
50260
51001
  if (sourceKey)
50261
51002
  nativeWriters.set(sourceKey, openReservation);
50262
51003
  const provisionalReservation = openInput.kind === "create" ? openReservation : void 0;
@@ -50400,6 +51141,8 @@ async function startHarnessBrokerServer(input) {
50400
51141
  let result;
50401
51142
  if (command.type === "turn.start")
50402
51143
  result = await record5.session.execute(command);
51144
+ else if (command.type === "turn.steer")
51145
+ result = await record5.session.execute(command);
50403
51146
  else if (command.type === "turn.cancel")
50404
51147
  result = await record5.session.execute(command);
50405
51148
  else if (command.type === "interaction.respond") {
@@ -50431,6 +51174,10 @@ async function startHarnessBrokerServer(input) {
50431
51174
  }
50432
51175
  return result;
50433
51176
  }
51177
+ if (request.method === "session.readCapabilities") {
51178
+ const session = requireSession(request.params).session;
51179
+ return session.readCapabilities ? session.readCapabilities() : session.capabilities;
51180
+ }
50434
51181
  if (request.method === "session.readSnapshot") {
50435
51182
  return requireSession(request.params).session.readSnapshot();
50436
51183
  }
@@ -50557,7 +51304,7 @@ async function startHarnessBrokerServer(input) {
50557
51304
  }
50558
51305
  state.authenticated = true;
50559
51306
  state.inputSequence = 1;
50560
- await send({ kind: "response", id: randomUUID24(), ok: true, value: { ready: true } });
51307
+ await send({ kind: "response", id: randomUUID27(), ok: true, value: { ready: true } });
50561
51308
  return;
50562
51309
  }
50563
51310
  const parsed2 = harnessBrokerRequestSchema.safeParse(raw);