@karlorz/codexhost-cli-win32-x64 0.13.3-7 → 0.14.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +1 -1
  2. package/app/codexhost-distribution.json +1 -1
  3. package/app/console-server.mjs +55 -4
  4. package/app/console-web.js +344 -54
  5. package/app/cpa-live-voice-hook.js +55 -4
  6. package/app/desktop-controller.mjs +69 -8
  7. package/app/host-runtime.mjs +743 -230
  8. package/app/plugins/antigravity/plugin.mjs +88 -12
  9. package/app/plugins/claude-code/plugin.mjs +397 -21
  10. package/app/plugins/codebuddy/plugin.mjs +107 -17
  11. package/app/plugins/codex-usage/plugin.mjs +67 -7
  12. package/app/plugins/copilot/assets/icon.png +0 -0
  13. package/app/plugins/copilot/manifest.json +26 -0
  14. package/app/plugins/copilot/plugin.mjs +34645 -0
  15. package/app/plugins/cursor-cli/plugin.mjs +88 -6
  16. package/app/plugins/deepseek-harness/plugin.mjs +73 -6
  17. package/app/plugins/enabled.json +1 -0
  18. package/app/plugins/grok/plugin.mjs +272 -60
  19. package/app/plugins/hermes/plugin.mjs +70 -4
  20. package/app/plugins/kimi-code/plugin.mjs +73 -6
  21. package/app/plugins/kiro-cli/plugin.mjs +73 -6
  22. package/app/plugins/omp/plugin.mjs +73 -112
  23. package/app/plugins/opencode/plugin.mjs +75 -6
  24. package/app/plugins/pi/plugin.mjs +204 -44
  25. package/app/plugins/qoder/plugin.mjs +73 -6
  26. package/app/plugins/qoder-cn/plugin.mjs +73 -6
  27. package/app/plugins/workbuddy/plugin.mjs +368 -41
  28. package/app/plugins/zcode/plugin.mjs +74 -6
  29. package/app/renderer-extension.js +749 -157
  30. package/bin/codexhost.exe +0 -0
  31. package/libexec/codexhost-node-repl.exe +0 -0
  32. package/libexec/codexhost-shim.exe +0 -0
  33. package/libexec/codexhost-updater.exe +0 -0
  34. package/package.json +1 -1
@@ -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);
@@ -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 randomUUID18 } 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
  }
@@ -40075,6 +40399,7 @@ var AppServerHost = class {
40075
40399
  #plugins;
40076
40400
  #launchSettings;
40077
40401
  #accountInspections = new HarnessAccountInspectionCache();
40402
+ #installationTasks = new HarnessInstallationTasks();
40078
40403
  #externalRuntime;
40079
40404
  #executionHosts = /* @__PURE__ */ new WeakMap();
40080
40405
  #externalPrewarms = new ExternalThreadPrewarms();
@@ -40110,7 +40435,7 @@ var AppServerHost = class {
40110
40435
  #sectionMoves = Promise.resolve();
40111
40436
  #writer;
40112
40437
  /** Console requests share Desktop handling; their replies return to the console. */
40113
- #consoleRequestPrefix = `codexhost-console:${randomUUID16()}:`;
40438
+ #consoleRequestPrefix = `codexhost-console:${randomUUID18()}:`;
40114
40439
  #consoleReplies = /* @__PURE__ */ new Map();
40115
40440
  #nextConsoleRequest = 0;
40116
40441
  #subagentThreadStatuses = /* @__PURE__ */ new Map();
@@ -40948,11 +41273,11 @@ var AppServerHost = class {
40948
41273
  this.#dispatchDesktopReply(request, () => this.#inspectHarness(request));
40949
41274
  return;
40950
41275
  }
40951
- if (request.method === HARNESS_INSTALLATION_METHOD) {
41276
+ if (request.method === HARNESS_INSTALLATION_METHOD || request.method === HARNESS_INSTALLATION_START_METHOD || request.method === HARNESS_INSTALLATION_STATUS_METHOD) {
40952
41277
  this.#dispatchDesktopReply(request, async () => {
40953
- await this.#waitForPlugins();
40954
41278
  try {
40955
- const result = await handleHarnessInstallation(request.params, this.#externalAdapters);
41279
+ if (request.method !== HARNESS_INSTALLATION_STATUS_METHOD) await this.#waitForPlugins();
41280
+ 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
41281
  await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
40957
41282
  } catch (error51) {
40958
41283
  await this.#writer.json(
@@ -41057,6 +41382,10 @@ var AppServerHost = class {
41057
41382
  await this.#listThreadOwnership(request);
41058
41383
  return;
41059
41384
  }
41385
+ if (request.method === "codexhost/thread/steering/inspect") {
41386
+ await this.#inspectThreadSteering(request);
41387
+ return;
41388
+ }
41060
41389
  if (request.method === "codexhost/thread/model/select") {
41061
41390
  await this.#selectThreadModel(request);
41062
41391
  return;
@@ -41830,7 +42159,7 @@ var AppServerHost = class {
41830
42159
  throw error51;
41831
42160
  }
41832
42161
  this.#activeOfficialTurns.set(threadId2, turnId);
41833
- const delegationId = hostThreadIdSchema.parse(randomUUID16());
42162
+ const delegationId = hostThreadIdSchema.parse(randomUUID18());
41834
42163
  try {
41835
42164
  const source = await this.#repository.find(input.parentThreadId);
41836
42165
  const pendingTerminal = this.#pendingOfficialTerminalStatuses.get(threadId2);
@@ -42018,7 +42347,7 @@ var AppServerHost = class {
42018
42347
  async #listDelegationThreads(input) {
42019
42348
  const [sortKey, sortDirection2] = input.sort.split("-");
42020
42349
  const request = {
42021
- id: `codexhost:delegation-list:${randomUUID16()}`,
42350
+ id: `codexhost:delegation-list:${randomUUID18()}`,
42022
42351
  method: "thread/list",
42023
42352
  params: {
42024
42353
  cwd: input.cwd ? [input.cwd] : null,
@@ -42561,6 +42890,28 @@ var AppServerHost = class {
42561
42890
  );
42562
42891
  }
42563
42892
  }
42893
+ /** Read the same delivery decision that Desktop `turn/steer` will follow. */
42894
+ async #inspectThreadSteering(request) {
42895
+ const params = threadSteeringInspectParamsSchema.safeParse(request.params);
42896
+ if (!params.success) {
42897
+ await this.#writer.json(rpcError(request, -32602, "Invalid Thread steering params"));
42898
+ return;
42899
+ }
42900
+ let delivery;
42901
+ try {
42902
+ const location = await this.#locateExternalThread(params.data.threadId);
42903
+ if (await this.#writeResolutionError(request, location)) return;
42904
+ const thread = location.kind === "external" ? this.#externalRuntime.get(params.data.threadId) : void 0;
42905
+ delivery = location.kind !== "external" ? "official" : thread ? await externalSteeringDelivery(thread, params.data.text) : "newTurn";
42906
+ } catch {
42907
+ await this.#writer.json(
42908
+ rpcError(request, -32081, "Thread steering metadata could not be read")
42909
+ );
42910
+ return;
42911
+ }
42912
+ const result = threadSteeringInspectResultSchema.parse({ delivery });
42913
+ await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
42914
+ }
42564
42915
  async #inspectThreadCommands(request) {
42565
42916
  const params = threadCommandsInspectParamsSchema.safeParse(request.params);
42566
42917
  if (!params.success) {
@@ -42724,7 +43075,7 @@ var AppServerHost = class {
42724
43075
  if (thread.running || thread.activeTurnId) {
42725
43076
  throw new ExternalCommandError(-32072, "External Thread already has an active operation");
42726
43077
  }
42727
- const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID16());
43078
+ const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID18());
42728
43079
  const projection = {
42729
43080
  projector: new CodexTurnProjector({
42730
43081
  threadId: thread.id,
@@ -43161,9 +43512,20 @@ var AppServerHost = class {
43161
43512
  await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
43162
43513
  return true;
43163
43514
  }
43515
+ /** Refresh history before Desktop acts on native Turn boundaries. */
43164
43516
  #refreshExternalThread(thread) {
43165
43517
  return this.#externalRuntime.refresh(thread);
43166
43518
  }
43519
+ #markExternalHistoryRead(thread, turns) {
43520
+ if (!thread.historyHydrated) return;
43521
+ for (const turnId of thread.steeredTurnIds) {
43522
+ if (turnId !== thread.activeTurnId && turns.some(
43523
+ (turn) => turn.id === turnId && (turn.status === "completed" || turn.status === "failed" || turn.status === "interrupted")
43524
+ )) {
43525
+ thread.steeredTurnIds.delete(turnId);
43526
+ }
43527
+ }
43528
+ }
43167
43529
  #persistTerminalIdentity(thread, event) {
43168
43530
  return this.#externalRuntime.persistTerminalIdentity(thread, event);
43169
43531
  }
@@ -43363,17 +43725,19 @@ var AppServerHost = class {
43363
43725
  return;
43364
43726
  }
43365
43727
  }
43728
+ const readTurns = includeTurns ? [...this.#externalHistoryTurns(thread)] : [];
43366
43729
  await this.#writer.json(
43367
43730
  rpcEnvelope(request, {
43368
43731
  result: {
43369
43732
  thread: {
43370
43733
  ...thread.thread,
43371
43734
  ...await this.#externalSectionFields(thread.record.hostThreadId),
43372
- turns: includeTurns ? this.#externalHistoryTurns(thread) : []
43735
+ turns: readTurns
43373
43736
  }
43374
43737
  }
43375
43738
  })
43376
43739
  );
43740
+ if (includeTurns) this.#markExternalHistoryRead(thread, readTurns);
43377
43741
  await this.#replayExternalUsage(thread);
43378
43742
  }
43379
43743
  async #listExternalHistory(request, thread, params, historyFresh) {
@@ -43390,6 +43754,9 @@ var AppServerHost = class {
43390
43754
  const turns = this.#externalHistoryTurns(thread);
43391
43755
  const result = request.method === "thread/turns/list" ? listExternalTurns(turns, params) : listExternalItems(turns, params);
43392
43756
  await this.#writer.json(rpcEnvelope(request, { result }));
43757
+ if (request.method === "thread/turns/list") {
43758
+ this.#markExternalHistoryRead(thread, result.data);
43759
+ }
43393
43760
  } catch (error51) {
43394
43761
  await this.#writer.json(
43395
43762
  rpcError(
@@ -43408,7 +43775,7 @@ var AppServerHost = class {
43408
43775
  return;
43409
43776
  }
43410
43777
  }
43411
- const turns = this.#externalHistoryTurns(thread);
43778
+ const turns = [...this.#externalHistoryTurns(thread)];
43412
43779
  const responseThread = {
43413
43780
  ...await this.#withExternalSection(thread.thread),
43414
43781
  turns: params.excludeTurns === true ? [] : turns
@@ -43442,6 +43809,8 @@ var AppServerHost = class {
43442
43809
  }
43443
43810
  })
43444
43811
  );
43812
+ if (params.excludeTurns !== true) this.#markExternalHistoryRead(thread, turns);
43813
+ else if (initialTurnsPage) this.#markExternalHistoryRead(thread, initialTurnsPage.data);
43445
43814
  } catch (error51) {
43446
43815
  await this.#writer.json(
43447
43816
  rpcError(
@@ -43630,10 +43999,15 @@ var AppServerHost = class {
43630
43999
  assertActive,
43631
44000
  typeof requestObject(request).clientUserMessageId === "string" ? requestObject(request).clientUserMessageId : void 0,
43632
44001
  requestObject(request)[THREAD_REFERENCE_SOURCE_HOST_PARAM]
43633
- )
44002
+ ),
44003
+ (input) => this.#insertExternalInput(thread, input)
43634
44004
  );
43635
44005
  try {
43636
- await this.#writer.json(rpcEnvelope(request, { result: { turnId: started.turnId } }));
44006
+ await this.#writer.json(
44007
+ rpcEnvelope(request, {
44008
+ result: { turnId: started.turnId, delivery: started.delivery }
44009
+ })
44010
+ );
43637
44011
  } finally {
43638
44012
  started.gate.resolve();
43639
44013
  }
@@ -43649,6 +44023,34 @@ var AppServerHost = class {
43649
44023
  this.#signalActiveWorkChanged();
43650
44024
  }
43651
44025
  }
44026
+ /** Native same-Turn input; `insertNativeSteer` owns the delivery and its fallback signal. */
44027
+ async #insertExternalInput(thread, input) {
44028
+ await insertNativeSteer(thread, input, {
44029
+ project: async (turnId, item, clientUserMessageId) => {
44030
+ const projection = this.#projectedTurn(thread, turnId);
44031
+ if (clientUserMessageId) {
44032
+ projection.projector.bindUserMessageClientId(item.itemId, clientUserMessageId);
44033
+ }
44034
+ await this.#projectHarnessOutput(thread, {
44035
+ kind: "event",
44036
+ event: { type: "item.started", turnId, item }
44037
+ });
44038
+ await this.#projectHarnessOutput(thread, {
44039
+ kind: "event",
44040
+ event: {
44041
+ type: "item.completed",
44042
+ turnId,
44043
+ snapshot: { item, outcome: { status: "succeeded" } }
44044
+ }
44045
+ });
44046
+ },
44047
+ diagnose: (error51) => this.#diagnose(error51)
44048
+ });
44049
+ return {
44050
+ turnId: input.turnId,
44051
+ gate: { promise: Promise.resolve(), resolve: () => void 0 }
44052
+ };
44053
+ }
43652
44054
  /** Keep command restoration and dispatch identical for start and steer submissions. */
43653
44055
  async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId, sourceHostId) {
43654
44056
  const text = restoreHarnessCommandMentions(inputText);
@@ -43706,7 +44108,7 @@ var AppServerHost = class {
43706
44108
  if (thread.running || thread.activeTurnId || this.#pendingExternalCommandRequests.has(thread.id)) {
43707
44109
  throw new ExternalSteerError(-32072, "External Thread already has an active Turn");
43708
44110
  }
43709
- const turnId = hostTurnIdSchema.parse(randomUUID16());
44111
+ const turnId = hostTurnIdSchema.parse(randomUUID18());
43710
44112
  const startedAtMs = Date.now();
43711
44113
  const projection = {
43712
44114
  projector: new CodexTurnProjector({
@@ -44000,8 +44402,14 @@ var AppServerHost = class {
44000
44402
  }
44001
44403
  return;
44002
44404
  }
44405
+ if (event.type === "turn.completed" && thread.pendingSteerProjections.size > 0) {
44406
+ await Promise.allSettled([...thread.pendingSteerProjections]);
44407
+ }
44003
44408
  const projection = this.#projectedTurn(thread, event.turnId);
44004
44409
  await this.#waitForTurnResponse(thread, event.turnId);
44410
+ if (event.type === "item.completed" && event.snapshot.item.type === "agentMessage" && this.#externalVoice.has(thread.id)) {
44411
+ projection.realtimeInline = true;
44412
+ }
44005
44413
  if (event.type === "interaction.closed" && thread.ignoredInteractionIds.delete(event.interactionId)) {
44006
44414
  return;
44007
44415
  }
@@ -44041,7 +44449,9 @@ var AppServerHost = class {
44041
44449
  thread.ephemeralTurnIds.delete(event.turnId);
44042
44450
  this.#manualCompactionTurns.delete(thread);
44043
44451
  } else {
44044
- thread.turns.push(result.completedTurn);
44452
+ thread.turns.push(
44453
+ projection.realtimeInline ? presentExternalVoiceTurn(result.completedTurn) : result.completedTurn
44454
+ );
44045
44455
  thread.projectedTerminalTurnId = event.turnId;
44046
44456
  thread.thread.updatedAt = completedAt;
44047
44457
  thread.thread.recencyAt = completedAt;
@@ -44051,6 +44461,7 @@ var AppServerHost = class {
44051
44461
  thread.activeTurnId = null;
44052
44462
  if (!projection.projector.hasOpenDetachedItems) thread.projectedTurns.delete(event.turnId);
44053
44463
  thread.responseGates.delete(event.turnId);
44464
+ thread.pendingSteerProjections.clear();
44054
44465
  this.#signalActiveWorkChanged();
44055
44466
  const delegation = await this.#repository.getDelegationByChild(thread.record.hostThreadId);
44056
44467
  if (delegation) {
@@ -44067,7 +44478,11 @@ var AppServerHost = class {
44067
44478
  if (event.type === "item.completed" && projection.projector.completed && !projection.projector.hasOpenDetachedItems) {
44068
44479
  thread.projectedTurns.delete(event.turnId);
44069
44480
  }
44070
- for (const message2 of result.messages) await this.#writer.json(message2);
44481
+ for (const message2 of result.messages) {
44482
+ await this.#writer.json(
44483
+ projection.realtimeInline ? presentExternalVoiceMessage(message2) : message2
44484
+ );
44485
+ }
44071
44486
  this.#externalVoiceResults.observe(
44072
44487
  thread.id,
44073
44488
  event,
@@ -44355,7 +44770,7 @@ var AppServerHost = class {
44355
44770
  try {
44356
44771
  result = projection.projector.projectQuestion(
44357
44772
  interaction,
44358
- hostItemIdSchema.parse(randomUUID16())
44773
+ hostItemIdSchema.parse(randomUUID18())
44359
44774
  );
44360
44775
  } catch (error51) {
44361
44776
  this.#diagnose(error51);
@@ -44583,7 +44998,7 @@ import path30 from "node:path";
44583
44998
  import { PassThrough } from "node:stream";
44584
44999
 
44585
45000
  // packages/host-runtime/src/remote-socket-lock.ts
44586
- import { randomUUID as randomUUID17 } from "node:crypto";
45001
+ import { randomUUID as randomUUID19 } from "node:crypto";
44587
45002
  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
45003
  import { uptime } from "node:os";
44589
45004
  import path29 from "node:path";
@@ -44709,7 +45124,7 @@ async function preparePrivateLockDirectory(lockDirectory) {
44709
45124
  await chmod3(lockDirectory, 448);
44710
45125
  }
44711
45126
  async function writeLockRecordAtomic(lockDirectory, entryPath, record4) {
44712
- const temporary = path29.join(lockDirectory, `.tmp-${record4.ownerToken}-${randomUUID17()}`);
45127
+ const temporary = path29.join(lockDirectory, `.tmp-${record4.ownerToken}-${randomUUID19()}`);
44713
45128
  const handle = await open9(temporary, "wx", 384);
44714
45129
  try {
44715
45130
  await handle.writeFile(`${JSON.stringify(record4)}
@@ -44784,7 +45199,7 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
44784
45199
  const legacyPath = `${socketPath}.initializing`;
44785
45200
  const lockDirectory = `${socketPath}.initializers`;
44786
45201
  await preparePrivateLockDirectory(lockDirectory);
44787
- const ownerToken = randomUUID17();
45202
+ const ownerToken = randomUUID19();
44788
45203
  const entryPath = path29.join(lockDirectory, lockEntryName(ownerToken));
44789
45204
  const baseRecord = {
44790
45205
  version: 2,
@@ -45295,12 +45710,12 @@ function createRemoteAppServerWebSocketListener(input) {
45295
45710
 
45296
45711
  // packages/host-runtime/src/remote-official-app-server.ts
45297
45712
  import { spawn as spawn5 } from "node:child_process";
45298
- import { randomUUID as randomUUID18 } from "node:crypto";
45713
+ import { randomUUID as randomUUID20 } from "node:crypto";
45299
45714
  import { lstat as lstat7, rm as rm15, stat as stat7 } from "node:fs/promises";
45300
45715
  import path31 from "node:path";
45301
45716
  var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
45302
45717
  var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
45303
- function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID18()) {
45718
+ function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID20()) {
45304
45719
  if (!path31.posix.isAbsolute(desktopControlSocketPath)) {
45305
45720
  throw new Error("Desktop control socket path must be absolute");
45306
45721
  }
@@ -46586,12 +47001,12 @@ async function readRemoteDelegationThread(environment, input) {
46586
47001
  }
46587
47002
 
46588
47003
  // packages/host-runtime/src/shared-thread-owner.ts
46589
- import { randomUUID as randomUUID20 } from "node:crypto";
47004
+ import { randomUUID as randomUUID22 } from "node:crypto";
46590
47005
  import { PassThrough as PassThrough3 } from "node:stream";
46591
47006
 
46592
47007
  // packages/host-runtime/src/shared-thread-peer.ts
46593
- import { randomUUID as randomUUID19 } from "node:crypto";
46594
- function object8(value2) {
47008
+ import { randomUUID as randomUUID21 } from "node:crypto";
47009
+ function object9(value2) {
46595
47010
  return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
46596
47011
  }
46597
47012
  var StreamThreadPeer = class {
@@ -46604,7 +47019,7 @@ var StreamThreadPeer = class {
46604
47019
  input;
46605
47020
  output;
46606
47021
  stop;
46607
- #prefix = `shared:${randomUUID19()}:`;
47022
+ #prefix = `shared:${randomUUID21()}:`;
46608
47023
  #pending = /* @__PURE__ */ new Map();
46609
47024
  #listeners = /* @__PURE__ */ new Set();
46610
47025
  #ended = Promise.withResolvers();
@@ -46647,7 +47062,7 @@ var StreamThreadPeer = class {
46647
47062
  async #read() {
46648
47063
  for await (const frame of readLfFrames(this.input)) {
46649
47064
  const message2 = parseJsonFrame(frame);
46650
- if (!object8(message2)) throw new Error("Invalid shared Thread response");
47065
+ if (!object9(message2)) throw new Error("Invalid shared Thread response");
46651
47066
  if (typeof message2.method !== "string") {
46652
47067
  const pending = typeof message2.id === "string" ? this.#pending.get(message2.id) : void 0;
46653
47068
  if (pending) {
@@ -46682,7 +47097,7 @@ var SharedThreadOwner = class {
46682
47097
  input = new PassThrough3();
46683
47098
  output = new PassThrough3();
46684
47099
  #peer = new StreamThreadPeer(this.output, this.input, () => this.input.end());
46685
- #prefix = `shared-interaction:${randomUUID20()}:`;
47100
+ #prefix = `shared-interaction:${randomUUID22()}:`;
46686
47101
  #interactions = /* @__PURE__ */ new Map();
46687
47102
  #listeners = /* @__PURE__ */ new Set();
46688
47103
  #receipts = /* @__PURE__ */ new Map();
@@ -46693,7 +47108,7 @@ var SharedThreadOwner = class {
46693
47108
  const id2 = `${this.#prefix}${message2.id}`;
46694
47109
  event = { ...message2, id: id2 };
46695
47110
  this.#interactions.set(id2, { nativeId: message2.id, message: event });
46696
- } else if (message2.method === "serverRequest/resolved" && object8(message2.params)) {
47111
+ } else if (message2.method === "serverRequest/resolved" && object9(message2.params)) {
46697
47112
  const id2 = `${this.#prefix}${message2.params.requestId}`;
46698
47113
  this.#interactions.delete(id2);
46699
47114
  event = { ...message2, params: { ...message2.params, requestId: id2 } };
@@ -46788,7 +47203,7 @@ var SharedThreadOwner = class {
46788
47203
  const parsed2 = jsonRpcRequestSchema.safeParse(message2);
46789
47204
  if (parsed2.success) {
46790
47205
  const request = parsed2.data;
46791
- void peer.request(request.method, object8(request.params) ? request.params : {}).then(
47206
+ void peer.request(request.method, object9(request.params) ? request.params : {}).then(
46792
47207
  (reply2) => send({ ...reply2, id: request.id }),
46793
47208
  () => send({
46794
47209
  id: request.id,
@@ -46798,7 +47213,7 @@ var SharedThreadOwner = class {
46798
47213
  }
46799
47214
  })
46800
47215
  );
46801
- } else if (object8(message2) && rpcId(message2.id)) {
47216
+ } else if (object9(message2) && rpcId(message2.id)) {
46802
47217
  await peer.respond(message2);
46803
47218
  }
46804
47219
  }
@@ -46883,8 +47298,8 @@ var SharedThreadBridge = class {
46883
47298
  }
46884
47299
  this.#peer = peer;
46885
47300
  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") {
47301
+ const params = object9(message2.params) ? message2.params : {};
47302
+ if (object9(params.thread) && params.thread.modelProvider === "codexhost" && typeof params.thread.id === "string") {
46888
47303
  this.#known.add(params.thread.id);
46889
47304
  }
46890
47305
  this.#publish(message2);
@@ -46928,7 +47343,7 @@ var SharedThreadBridge = class {
46928
47343
  return owners;
46929
47344
  }
46930
47345
  async route(request) {
46931
- const params = object8(request.params) ? request.params : {};
47346
+ const params = object9(request.params) ? request.params : {};
46932
47347
  const create = this.options.delegateCreates ? classifyCreateRequestRoute(request) : null;
46933
47348
  let shared = create !== null && create.selectedHarness !== "codex";
46934
47349
  if (!shared && typeof params.threadId === "string") {
@@ -46945,10 +47360,10 @@ var SharedThreadBridge = class {
46945
47360
  const seen = /* @__PURE__ */ new Set();
46946
47361
  do {
46947
47362
  const reply2 = await peer.request("thread/list", { ...params, cursor, limit: 200 });
46948
- if (!object8(reply2.result) || !Array.isArray(reply2.result.data))
47363
+ if (!object9(reply2.result) || !Array.isArray(reply2.result.data))
46949
47364
  throw new Error("Shared Thread list failed");
46950
47365
  for (const row of reply2.result.data) {
46951
- if (!object8(row) || typeof row.id !== "string")
47366
+ if (!object9(row) || typeof row.id !== "string")
46952
47367
  throw new Error("Invalid shared Thread row");
46953
47368
  rows.push(row);
46954
47369
  this.#known.add(row.id);
@@ -46977,7 +47392,7 @@ var SharedThreadBridge = class {
46977
47392
  return storedSectionPlacementV1Schema.array().parse(reply2.result);
46978
47393
  }
46979
47394
  async respond(message2) {
46980
- if (!object8(message2) || typeof message2.method === "string" || typeof message2.id !== "string" || !message2.id.startsWith("shared-interaction:"))
47395
+ if (!object9(message2) || typeof message2.method === "string" || typeof message2.id !== "string" || !message2.id.startsWith("shared-interaction:"))
46981
47396
  return false;
46982
47397
  if (!this.#peer) throw new Error("Shared Thread Host is disconnected");
46983
47398
  await this.#peer.respond(message2);
@@ -46992,7 +47407,7 @@ var SharedThreadBridge = class {
46992
47407
  };
46993
47408
 
46994
47409
  // packages/host-runtime/src/remote-control-app-server.ts
46995
- import { randomUUID as randomUUID21 } from "node:crypto";
47410
+ import { randomUUID as randomUUID23 } from "node:crypto";
46996
47411
  import { mkdir as mkdir17, open as open10, rename as rename13, rm as rm17 } from "node:fs/promises";
46997
47412
  import path37 from "node:path";
46998
47413
  var REMOTE_CONTROL_BRIDGE_PIPE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_PIPE";
@@ -47013,7 +47428,7 @@ function nodeCompatibleWindowsPath(value2) {
47013
47428
  if (value2.startsWith("\\\\?\\")) return value2.slice(4);
47014
47429
  return value2;
47015
47430
  }
47016
- function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID21()) {
47431
+ function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID23()) {
47017
47432
  const safeInstance = instanceId.replaceAll(/[^a-zA-Z0-9-]/gu, "");
47018
47433
  if (!safeInstance) throw new Error("Remote Control bridge instance ID is invalid");
47019
47434
  return `\\\\.\\pipe\\codexhost-remote-control-${processId}-${safeInstance}`;
@@ -47028,7 +47443,7 @@ async function publishRemoteControlAppServerDescriptor(plan) {
47028
47443
  await mkdir17(directory, { recursive: true, mode: 448 });
47029
47444
  const temporaryPath = path37.join(
47030
47445
  directory,
47031
- `.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID21()}.tmp`
47446
+ `.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID23()}.tmp`
47032
47447
  );
47033
47448
  const handle = await open10(temporaryPath, "wx", 384);
47034
47449
  try {
@@ -47569,12 +47984,19 @@ function createHostUpdateCoordinator(options2) {
47569
47984
  }
47570
47985
 
47571
47986
  // packages/host-runtime/src/usage-statistics.ts
47572
- import { randomUUID as randomUUID22 } from "node:crypto";
47987
+ import { randomUUID as randomUUID24 } from "node:crypto";
47573
47988
  import { mkdir as mkdir19, readFile as readFile20, readdir as readdir6, rename as rename15, rm as rm19, writeFile as writeFile11 } from "node:fs/promises";
47574
47989
  import path40 from "node:path";
47575
47990
  import { setImmediate as yieldToEventLoop } from "node:timers/promises";
47576
47991
 
47577
47992
  // packages/harness-adapter/dist/usage-statistics.js
47993
+ var HarnessUsageSourceChangedError = class extends Error {
47994
+ code = "HARNESS_USAGE_SOURCE_CHANGED";
47995
+ /** Plugins may bundle their own copy of this contract, so instanceof is insufficient. */
47996
+ static is(error51) {
47997
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "HARNESS_USAGE_SOURCE_CHANGED";
47998
+ }
47999
+ };
47578
48000
  var MAX_SESSION_ID_LENGTH = 512;
47579
48001
  var MAX_CWD_LENGTH = 4096;
47580
48002
  var MAX_SESSION_TITLE_LENGTH = 200;
@@ -47677,6 +48099,95 @@ function withHostSessionTitles(result, records) {
47677
48099
  };
47678
48100
  }
47679
48101
 
48102
+ // packages/host-runtime/src/usage-statistics-sources.ts
48103
+ import { setTimeout as delay7 } from "node:timers/promises";
48104
+ async function* readUsageStatisticsSources(capability, sources, signal) {
48105
+ let pending = sources;
48106
+ for (let attempt = 0; ; attempt++) {
48107
+ const changed = [];
48108
+ for (const source of pending) {
48109
+ signal.throwIfAborted();
48110
+ try {
48111
+ const entries = (await capability.readSource(source.id, signal)).map(parseHarnessUsageEntry).filter((entry) => entry !== null);
48112
+ yield { source, entries };
48113
+ } catch (error51) {
48114
+ signal.throwIfAborted();
48115
+ if (HarnessUsageSourceChangedError.is(error51) && attempt < 2) changed.push(source);
48116
+ else yield { source, error: error51 };
48117
+ }
48118
+ }
48119
+ if (!changed.length) return;
48120
+ await delay7(50 * (attempt + 1), void 0, { signal });
48121
+ let current;
48122
+ try {
48123
+ current = new Map(
48124
+ (await capability.listSources(signal)).map((source) => [source.id, source])
48125
+ );
48126
+ } catch (error51) {
48127
+ signal.throwIfAborted();
48128
+ for (const source of changed) yield { source, error: error51 };
48129
+ return;
48130
+ }
48131
+ const next = [];
48132
+ for (const source of changed) {
48133
+ const fresh = current.get(source.id);
48134
+ if (fresh) next.push(fresh);
48135
+ else yield { source, removed: true };
48136
+ }
48137
+ pending = next;
48138
+ }
48139
+ }
48140
+
48141
+ // packages/host-runtime/src/usage-statistics-calendar.ts
48142
+ function dateKey(year, month, day) {
48143
+ return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
48144
+ }
48145
+ function createUsageStatisticsCalendar(timeZone) {
48146
+ const localZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
48147
+ const zone = timeZone ?? localZone;
48148
+ if (zone === localZone) {
48149
+ return {
48150
+ timeZone: zone,
48151
+ at(ms) {
48152
+ const date5 = new Date(ms);
48153
+ return {
48154
+ date: dateKey(date5.getFullYear(), date5.getMonth() + 1, date5.getDate()),
48155
+ weekday: date5.getDay(),
48156
+ hour: date5.getHours()
48157
+ };
48158
+ }
48159
+ };
48160
+ }
48161
+ const format = new Intl.DateTimeFormat("en-US", {
48162
+ timeZone: zone,
48163
+ calendar: "gregory",
48164
+ numberingSystem: "latn",
48165
+ year: "numeric",
48166
+ month: "2-digit",
48167
+ day: "2-digit",
48168
+ hour: "2-digit",
48169
+ hourCycle: "h23"
48170
+ });
48171
+ return {
48172
+ timeZone: zone,
48173
+ at(ms) {
48174
+ const parts = format.formatToParts(ms);
48175
+ const part = (type) => Number(parts.find((value2) => value2.type === type)?.value);
48176
+ const year = part("year"), month = part("month"), day = part("day");
48177
+ return {
48178
+ date: dateKey(year, month, day),
48179
+ weekday: new Date(Date.UTC(year, month - 1, day)).getUTCDay(),
48180
+ hour: part("hour")
48181
+ };
48182
+ }
48183
+ };
48184
+ }
48185
+ function shiftUsageDate(date5, days) {
48186
+ const value2 = /* @__PURE__ */ new Date(`${date5}T12:00:00Z`);
48187
+ value2.setUTCDate(value2.getUTCDate() + days);
48188
+ return dateKey(value2.getUTCFullYear(), value2.getUTCMonth() + 1, value2.getUTCDate());
48189
+ }
48190
+
47680
48191
  // packages/host-runtime/src/usage-statistics.ts
47681
48192
  var CACHE_VERSION = 7;
47682
48193
  var STALE_AFTER_MS = 1e4;
@@ -47737,17 +48248,6 @@ function expand(value2, intern) {
47737
48248
  function message(error51) {
47738
48249
  return error51 instanceof Error ? error51.message : String(error51);
47739
48250
  }
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
48251
  var SESSIONS_PER_MEASURE = 50;
47752
48252
  var MODELS_PER_SESSION = 16;
47753
48253
  function emptyTotals() {
@@ -47934,23 +48434,27 @@ var UsageStatistics = class {
47934
48434
  }
47935
48435
  for (const { harness: harness2, capability, ids } of listed) {
47936
48436
  const cache = this.#cache(harness2);
47937
- const present = /* @__PURE__ */ new Set();
48437
+ const present = new Set(ids.map(({ id: id2 }) => id2));
47938
48438
  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 });
48439
+ const pending = ids.filter(
48440
+ ({ id: id2, fingerprint }) => cache.sources.get(id2)?.fingerprint !== fingerprint
48441
+ );
48442
+ this.#progress.read += ids.length - pending.length;
48443
+ try {
48444
+ for await (const result of readUsageStatisticsSources(capability, pending, signal)) {
48445
+ const { id: id2, fingerprint } = result.source;
48446
+ if ("entries" in result) {
48447
+ cache.sources.set(id2, { fingerprint, entries: result.entries });
47945
48448
  cache.dirty = true;
47946
48449
  this.#generation += 1;
47947
- } catch (error51) {
47948
- if (signal.aborted) return;
47949
- failed ??= message(error51);
47950
- }
48450
+ } else if ("error" in result) failed ??= message(result.error);
48451
+ else present.delete(id2);
48452
+ this.#progress.read += 1;
47951
48453
  await yieldToEventLoop();
47952
48454
  }
47953
- this.#progress.read += 1;
48455
+ } catch (error51) {
48456
+ if (signal.aborted) return;
48457
+ throw error51;
47954
48458
  }
47955
48459
  for (const id2 of cache.sources.keys()) {
47956
48460
  if (!present.has(id2)) {
@@ -48015,7 +48519,7 @@ var UsageStatistics = class {
48015
48519
  async #persist(harness2, cache) {
48016
48520
  if (!cache.dirty || this.#now() - cache.persistedAtMs < PERSIST_INTERVAL_MS) return;
48017
48521
  const file2 = this.#file(harness2);
48018
- const temporary = `${file2}.${randomUUID22()}.tmp`;
48522
+ const temporary = `${file2}.${randomUUID24()}.tmp`;
48019
48523
  try {
48020
48524
  await mkdir19(this.#directory, { recursive: true });
48021
48525
  const sources = [...cache.sources].map(([id2, source]) => [
@@ -48033,9 +48537,10 @@ var UsageStatistics = class {
48033
48537
  await rm19(temporary, { force: true });
48034
48538
  }
48035
48539
  }
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;
48540
+ /** Every request once, per Harness in source order, in the requested calendar. */
48541
+ #indexed(calendar) {
48542
+ if (this.#index?.generation === this.#generation && this.#index.timeZone === calendar.timeZone)
48543
+ return this.#index.entries;
48039
48544
  const entries = [];
48040
48545
  for (const [harness2, cache] of this.#caches) {
48041
48546
  const seen = /* @__PURE__ */ new Set();
@@ -48043,26 +48548,20 @@ var UsageStatistics = class {
48043
48548
  for (const entry of parsed2) {
48044
48549
  if (seen.has(entry.id)) continue;
48045
48550
  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
- });
48551
+ entries.push({ harness: harness2, entry, ...calendar.at(entry.occurredAtMs) });
48054
48552
  }
48055
48553
  }
48056
48554
  }
48057
- this.#index = { generation: this.#generation, entries };
48555
+ this.#index = { generation: this.#generation, timeZone: calendar.timeZone, entries };
48058
48556
  return entries;
48059
48557
  }
48060
48558
  #aggregate(params, now, lookup) {
48061
48559
  const { range } = params;
48062
48560
  const days = RANGE_DAYS[range];
48063
- const to = localDate2(now);
48561
+ const calendar = createUsageStatisticsCalendar(params.timeZone);
48562
+ const to = calendar.at(now).date;
48064
48563
  let from = null;
48065
- if (days !== null) from = shiftDate(to, -days + 1);
48564
+ if (days !== null) from = shiftUsageDate(to, -days + 1);
48066
48565
  const inRange = (date5) => (from === null || date5 >= from) && date5 <= to;
48067
48566
  const day = params.date !== void 0 && inRange(params.date) ? params.date : null;
48068
48567
  const harnessFilter = params.harness ?? null;
@@ -48103,7 +48602,7 @@ var UsageStatistics = class {
48103
48602
  const harnessPriced = /* @__PURE__ */ new Map();
48104
48603
  const byProject = /* @__PURE__ */ new Map();
48105
48604
  const sessions = /* @__PURE__ */ new Map();
48106
- for (const indexed of this.#indexed()) {
48605
+ for (const indexed of this.#indexed(calendar)) {
48107
48606
  const { harness: harness2, entry, date: date5 } = indexed;
48108
48607
  if (!inRange(date5)) continue;
48109
48608
  const model2 = entry.model ?? null;
@@ -48636,7 +49135,7 @@ async function runHostRuntime(input) {
48636
49135
  }
48637
49136
 
48638
49137
  // packages/host-runtime/src/remote-host-install.ts
48639
- import { createHash as createHash12, randomUUID as randomUUID23 } from "node:crypto";
49138
+ import { createHash as createHash12, randomUUID as randomUUID25 } from "node:crypto";
48640
49139
  import { constants as fsConstants } from "node:fs";
48641
49140
  import {
48642
49141
  access as access4,
@@ -48735,7 +49234,7 @@ async function writeAtomic(filePath, contents, mode) {
48735
49234
  await mkdir20(path42.dirname(filePath), { recursive: true, mode: 448 });
48736
49235
  const temporary = path42.join(
48737
49236
  path42.dirname(filePath),
48738
- `.${path42.basename(filePath)}.${process.pid}.${randomUUID23()}.tmp`
49237
+ `.${path42.basename(filePath)}.${process.pid}.${randomUUID25()}.tmp`
48739
49238
  );
48740
49239
  try {
48741
49240
  if (typeof contents === "string") {
@@ -48759,7 +49258,7 @@ async function writeAtomicExecutable(filePath, sourcePath) {
48759
49258
  await mkdir20(path42.dirname(filePath), { recursive: true, mode: 448 });
48760
49259
  const temporary = path42.join(
48761
49260
  path42.dirname(filePath),
48762
- `.${path42.basename(filePath)}.${process.pid}.${randomUUID23()}.tmp`
49261
+ `.${path42.basename(filePath)}.${process.pid}.${randomUUID25()}.tmp`
48763
49262
  );
48764
49263
  try {
48765
49264
  await copyFile4(sourcePath, temporary);
@@ -49500,6 +49999,7 @@ var harnessBrokerMethodSchema = external_exports.enum([
49500
49999
  "adapter.open",
49501
50000
  "adapter.subagent.readSnapshot",
49502
50001
  "session.readSnapshot",
50002
+ "session.readCapabilities",
49503
50003
  "session.refreshUsage",
49504
50004
  "session.execute",
49505
50005
  "session.commands.list",
@@ -49682,6 +50182,11 @@ var turnStartSchema = external_exports.object({
49682
50182
  turnId: hostTurnIdSchema,
49683
50183
  input: external_exports.array(textInputSchema)
49684
50184
  }).strict();
50185
+ var turnSteerSchema = external_exports.object({
50186
+ type: external_exports.literal("turn.steer"),
50187
+ turnId: hostTurnIdSchema,
50188
+ input: external_exports.array(textInputSchema)
50189
+ }).strict();
49685
50190
  var turnCancelSchema = external_exports.object({ type: external_exports.literal("turn.cancel"), turnId: hostTurnIdSchema }).strict();
49686
50191
  var interactionResponseSchema = external_exports.union([
49687
50192
  external_exports.object({
@@ -49707,6 +50212,7 @@ var permissionSelectSchema = external_exports.object({
49707
50212
  }).strict();
49708
50213
  var brokerHostCommandSchema = external_exports.discriminatedUnion("type", [
49709
50214
  turnStartSchema,
50215
+ turnSteerSchema,
49710
50216
  turnCancelSchema,
49711
50217
  interactionRespondSchema,
49712
50218
  modelSelectSchema,
@@ -49841,7 +50347,7 @@ var harnessOutputSchema = external_exports.custom((value2) => {
49841
50347
  });
49842
50348
 
49843
50349
  // packages/harness-broker/dist/server.js
49844
- import { randomBytes as randomBytes5, randomUUID as randomUUID24 } from "node:crypto";
50350
+ import { randomBytes as randomBytes5, randomUUID as randomUUID26 } from "node:crypto";
49845
50351
  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
50352
  import net4, {} from "node:net";
49847
50353
  import path45 from "node:path";
@@ -49900,7 +50406,7 @@ async function assertNoLiveDescriptor(descriptorPath) {
49900
50406
  }
49901
50407
  }
49902
50408
  async function publishDescriptor(descriptorPath, descriptor) {
49903
- const temporary = `${descriptorPath}.${process.pid}.${randomUUID24()}.tmp`;
50409
+ const temporary = `${descriptorPath}.${process.pid}.${randomUUID26()}.tmp`;
49904
50410
  const handle = await open11(temporary, "wx", 384);
49905
50411
  try {
49906
50412
  await handle.writeFile(`${JSON.stringify(descriptor)}
@@ -49925,6 +50431,7 @@ function sessionMetadata(record4) {
49925
50431
  sessionId: record4.id,
49926
50432
  sessionGeneration: record4.generation,
49927
50433
  capabilities: record4.session.capabilities,
50434
+ readCapabilities: true,
49928
50435
  initialState: {
49929
50436
  ...initialState,
49930
50437
  ...record4.nativeRef ? { nativeRef: record4.nativeRef } : {},
@@ -49977,7 +50484,7 @@ async function startHarnessBrokerServer(input) {
49977
50484
  await assertNoLiveDescriptor(input.descriptorPath);
49978
50485
  if (process.platform !== "win32")
49979
50486
  await prepareUnixSocketPath(input.socketPath);
49980
- const generation = input.generation ?? randomUUID24();
50487
+ const generation = input.generation ?? randomUUID26();
49981
50488
  const token = input.token ?? randomBytes5(32).toString("hex");
49982
50489
  const descriptor = {
49983
50490
  schemaVersion: 1,
@@ -50018,7 +50525,7 @@ async function startHarnessBrokerServer(input) {
50018
50525
  };
50019
50526
  const server = net4.createServer((socket) => {
50020
50527
  const state = {
50021
- id: randomUUID24(),
50528
+ id: randomUUID26(),
50022
50529
  socket,
50023
50530
  authenticated: false,
50024
50531
  inputSequence: 0,
@@ -50256,7 +50763,7 @@ async function startHarnessBrokerServer(input) {
50256
50763
  }
50257
50764
  };
50258
50765
  }
50259
- const openReservation = randomUUID24();
50766
+ const openReservation = randomUUID26();
50260
50767
  if (sourceKey)
50261
50768
  nativeWriters.set(sourceKey, openReservation);
50262
50769
  const provisionalReservation = openInput.kind === "create" ? openReservation : void 0;
@@ -50400,6 +50907,8 @@ async function startHarnessBrokerServer(input) {
50400
50907
  let result;
50401
50908
  if (command.type === "turn.start")
50402
50909
  result = await record5.session.execute(command);
50910
+ else if (command.type === "turn.steer")
50911
+ result = await record5.session.execute(command);
50403
50912
  else if (command.type === "turn.cancel")
50404
50913
  result = await record5.session.execute(command);
50405
50914
  else if (command.type === "interaction.respond") {
@@ -50431,6 +50940,10 @@ async function startHarnessBrokerServer(input) {
50431
50940
  }
50432
50941
  return result;
50433
50942
  }
50943
+ if (request.method === "session.readCapabilities") {
50944
+ const session = requireSession(request.params).session;
50945
+ return session.readCapabilities ? session.readCapabilities() : session.capabilities;
50946
+ }
50434
50947
  if (request.method === "session.readSnapshot") {
50435
50948
  return requireSession(request.params).session.readSnapshot();
50436
50949
  }
@@ -50557,7 +51070,7 @@ async function startHarnessBrokerServer(input) {
50557
51070
  }
50558
51071
  state.authenticated = true;
50559
51072
  state.inputSequence = 1;
50560
- await send({ kind: "response", id: randomUUID24(), ok: true, value: { ready: true } });
51073
+ await send({ kind: "response", id: randomUUID26(), ok: true, value: { ready: true } });
50561
51074
  return;
50562
51075
  }
50563
51076
  const parsed2 = harnessBrokerRequestSchema.safeParse(raw);