@codexhost/cli-darwin-arm64 0.17.1 → 0.17.2

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.
package/README.md CHANGED
@@ -7,7 +7,7 @@ Run Pi and Claude Code as first-class external harnesses inside Codex Desktop.
7
7
  ## Install
8
8
 
9
9
  ```bash
10
- npm install -g @codexhost/cli@0.17.1
10
+ npm install -g @codexhost/cli@0.17.2
11
11
  ```
12
12
 
13
13
  Do not install this package directly. npm selects it through the optional dependencies of `@codexhost/cli`.
@@ -1 +1 @@
1
- {"schemaVersion":1,"version":"0.17.1","distribution":"npm","target":"macos-arm64"}
1
+ {"schemaVersion":1,"version":"0.17.2","distribution":"npm","target":"macos-arm64"}
@@ -16381,6 +16381,21 @@ var threadSteeringInspectParamsSchema = external_exports.object({
16381
16381
  /** The text about to be steered; a Harness command always stops and restarts. */
16382
16382
  text: external_exports.string().optional()
16383
16383
  }).strict();
16384
+ var threadSteeringContextSchema = external_exports.object({
16385
+ kind: external_exports.literal("application"),
16386
+ value: external_exports.string().transform((text, context) => {
16387
+ try {
16388
+ return JSON.parse(text);
16389
+ } catch {
16390
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
16391
+ return external_exports.NEVER;
16392
+ }
16393
+ }).pipe(external_exports.object({
16394
+ expectedTurnId: hostTurnIdSchema,
16395
+ clientUserMessageId: external_exports.string().min(1),
16396
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
16397
+ }).strict())
16398
+ }).strict().transform((context) => context.value);
16384
16399
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
16385
16400
  var threadSteeringInspectResultSchema = external_exports.object({
16386
16401
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
@@ -15602,6 +15602,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15602
15602
  /** The text about to be steered; a Harness command always stops and restarts. */
15603
15603
  text: external_exports.string().optional()
15604
15604
  }).strict();
15605
+ var threadSteeringContextSchema = external_exports.object({
15606
+ kind: external_exports.literal("application"),
15607
+ value: external_exports.string().transform((text, context) => {
15608
+ try {
15609
+ return JSON.parse(text);
15610
+ } catch {
15611
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
15612
+ return external_exports.NEVER;
15613
+ }
15614
+ }).pipe(external_exports.object({
15615
+ expectedTurnId: hostTurnIdSchema,
15616
+ clientUserMessageId: external_exports.string().min(1),
15617
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
15618
+ }).strict())
15619
+ }).strict().transform((context) => context.value);
15605
15620
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15606
15621
  var threadSteeringInspectResultSchema = external_exports.object({
15607
15622
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
@@ -15780,6 +15780,21 @@ var threadSteeringInspectParamsSchema = external_exports.object({
15780
15780
  /** The text about to be steered; a Harness command always stops and restarts. */
15781
15781
  text: external_exports.string().optional()
15782
15782
  }).strict();
15783
+ var threadSteeringContextSchema = external_exports.object({
15784
+ kind: external_exports.literal("application"),
15785
+ value: external_exports.string().transform((text, context) => {
15786
+ try {
15787
+ return JSON.parse(text);
15788
+ } catch {
15789
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
15790
+ return external_exports.NEVER;
15791
+ }
15792
+ }).pipe(external_exports.object({
15793
+ expectedTurnId: hostTurnIdSchema,
15794
+ clientUserMessageId: external_exports.string().min(1),
15795
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
15796
+ }).strict())
15797
+ }).strict().transform((context) => context.value);
15783
15798
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15784
15799
  var threadSteeringInspectResultSchema = external_exports.object({
15785
15800
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
@@ -17663,7 +17678,8 @@ function findRendererHostRpcFamily(store) {
17663
17678
  if (!record3(definition) || definition.kind !== "signal-family") continue;
17664
17679
  if (!record3(members) || typeof members.get !== "function") continue;
17665
17680
  for (const [hostId2, member] of members) {
17666
- if (typeof hostId2 !== "string" || !record3(member)) continue;
17681
+ if (typeof hostId2 !== "string" || !/^(?:local$|durable$|remote[-:])/u.test(hostId2)) continue;
17682
+ if (!record3(member)) continue;
17667
17683
  const signal = member.value;
17668
17684
  if (!record3(signal) || typeof signal.get !== "function") continue;
17669
17685
  let value;
@@ -17714,7 +17730,8 @@ function installRendererHostRpcRouting(root, target, dependencies) {
17714
17730
  if (disposed) return null;
17715
17731
  try {
17716
17732
  const store = dependencies.findStore(root);
17717
- discovery = store ? dependencies.findFamily(store) : null;
17733
+ const bound = store && discovery?.store === store ? [...store.familyBindings.values()].includes(discovery.family) : false;
17734
+ if (!bound) discovery = store ? dependencies.findFamily(store) : null;
17718
17735
  } catch {
17719
17736
  discovery = null;
17720
17737
  }
@@ -19019,6 +19036,117 @@ async function installNativeRpcRemoteControlDirect(renderer) {
19019
19036
  }
19020
19037
  }
19021
19038
 
19039
+ // packages/desktop-control/src/renderer-rpc-steering.ts
19040
+ var RETRY_BASE_MS = 5e3;
19041
+ var RETRY_MAX_MS = 3e5;
19042
+ var retries = /* @__PURE__ */ new WeakMap();
19043
+ async function installRendererRpcSteeringDirect(client, now = Date.now) {
19044
+ try {
19045
+ const needed = await client.evaluate(`(() => {
19046
+ const steering = window.__codexhostRpcSteeringV1;
19047
+ if (steering && steering.controller.forHost === steering.forHost) return false;
19048
+ steering?.release();
19049
+ const routing=window.__codexhostHostRoutingV1;
19050
+ return ['local', ...(routing?.knownHostIds?.() ?? [])].some(id => routing?.forHost(id)?.manager.kind === 'main-process-rpc');
19051
+ })()`);
19052
+ if (!needed) return false;
19053
+ const retry = retries.get(client);
19054
+ if (retry && now() < retry.nextAt) return false;
19055
+ try {
19056
+ await discoverAndInstall(client);
19057
+ retries.delete(client);
19058
+ return true;
19059
+ } catch (error51) {
19060
+ const attempts = (retry?.attempts ?? 0) + 1;
19061
+ const delay = Math.min(RETRY_BASE_MS * 2 ** (attempts - 1), RETRY_MAX_MS);
19062
+ retries.set(client, { attempts, nextAt: now() + delay });
19063
+ console.error(
19064
+ `codexhost native steering discovery failed (attempt ${attempts}):`,
19065
+ error51 instanceof Error ? error51.message : String(error51)
19066
+ );
19067
+ return false;
19068
+ }
19069
+ } catch {
19070
+ return false;
19071
+ }
19072
+ }
19073
+ async function discoverAndInstall(client) {
19074
+ const group = `codexhost-rpc-steering-${crypto.randomUUID()}`;
19075
+ const command = (method, params) => client.command(method, params);
19076
+ const properties = (objectId) => command("Runtime.getProperties", { objectId, ownProperties: true });
19077
+ const call = (objectId, functionDeclaration, args = []) => command("Runtime.callFunctionOn", {
19078
+ objectId,
19079
+ functionDeclaration,
19080
+ arguments: args,
19081
+ objectGroup: group,
19082
+ returnByValue: true
19083
+ });
19084
+ try {
19085
+ const proto = await command("Runtime.evaluate", {
19086
+ expression: "Object.getPrototypeOf(async function(){})",
19087
+ objectGroup: group
19088
+ });
19089
+ if (!proto.result.objectId) throw new Error("Native RPC steering discovery is unavailable");
19090
+ const objects = await command("Runtime.queryObjects", {
19091
+ prototypeObjectId: proto.result.objectId,
19092
+ objectGroup: group
19093
+ });
19094
+ if (!objects.objects.objectId) throw new Error("Native RPC steering discovery is unavailable");
19095
+ const filtered = await command("Runtime.callFunctionOn", {
19096
+ objectId: objects.objects.objectId,
19097
+ functionDeclaration: 'function(){return this.filter(fn=>fn.name==="collectAppStateSnapshot"&&String(fn).includes("collectSnapshot")).slice(0,9)}',
19098
+ objectGroup: group
19099
+ });
19100
+ if (!filtered.result.objectId) throw new Error("Native RPC Controller is unavailable");
19101
+ const snapshots = (await properties(filtered.result.objectId)).result.flatMap(
19102
+ (entry) => entry.value?.type === "function" && entry.value.objectId ? [entry.value.objectId] : []
19103
+ );
19104
+ if (snapshots.length > 8) throw new Error("Native RPC Controller is ambiguous");
19105
+ const controllers = [];
19106
+ for (const snapshot of snapshots) {
19107
+ const scopes = (await properties(snapshot)).internalProperties?.find(
19108
+ (entry) => entry.name === "[[Scopes]]"
19109
+ )?.value?.objectId;
19110
+ if (!scopes) continue;
19111
+ for (const scope of (await properties(scopes)).result) {
19112
+ if (!scope.value?.objectId || !scope.value.description?.startsWith("Closure")) continue;
19113
+ const bindings = (await properties(scope.value.objectId)).result;
19114
+ const owners = [];
19115
+ let rootScope;
19116
+ for (const binding of bindings) {
19117
+ if (binding.value?.type !== "object" || !binding.value.objectId) continue;
19118
+ const id = binding.value.objectId;
19119
+ const result2 = await call(
19120
+ id,
19121
+ `function(){return (${nativeRpcObjectShape.toString()})(this)}`
19122
+ );
19123
+ const shape = result2.result.value;
19124
+ if (shape?.scope) rootScope = id;
19125
+ if (shape?.controller && (await call(id, "function(fn){return this.collectAppStateSnapshot===fn}", [
19126
+ { objectId: snapshot }
19127
+ ])).result.value === true)
19128
+ owners.push(id);
19129
+ }
19130
+ if (owners.length !== 1 || !rootScope) continue;
19131
+ const root = await call(
19132
+ rootScope,
19133
+ `function(){let node=this.node;const seen=new Set();while(node?.parent&&!seen.has(node.parent)&&seen.size<100){seen.add(node);node=node.parent}return (${findRendererAppScopeStore.toString()})(document)===node}`
19134
+ );
19135
+ if (root.result.value === true) controllers.push(owners[0]);
19136
+ }
19137
+ }
19138
+ if (controllers.length !== 1) throw new Error("Native RPC Controller is missing or ambiguous");
19139
+ const result = await call(
19140
+ controllers[0],
19141
+ "function(){return window.__codexhostInstallRpcSteeringV1?.(this) === true}"
19142
+ );
19143
+ if (result.exceptionDetails || result.result.value !== true)
19144
+ throw new Error("Native RPC steering installation failed");
19145
+ } finally {
19146
+ await client.command("Runtime.releaseObjectGroup", { objectGroup: group }).catch(() => void 0);
19147
+ }
19148
+ }
19149
+
19022
19150
  // packages/desktop-control/src/renderer-cdp-control-session.ts
19023
19151
  function isRecord2(value) {
19024
19152
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -19279,6 +19407,7 @@ var defaultOperations = {
19279
19407
  async installDraftPrewarmPolicy(renderer) {
19280
19408
  const status = await installRendererDraftPrewarmPolicyDirect(renderer);
19281
19409
  await installNativeRpcRemoteControlDirect(renderer);
19410
+ await installRendererRpcSteeringDirect(renderer);
19282
19411
  return status;
19283
19412
  }
19284
19413
  };
@@ -21005,6 +21005,22 @@ var threadSteeringInspectParamsSchema = external_exports.object({
21005
21005
  text: external_exports.string().optional()
21006
21006
  }).strict();
21007
21007
  var THREAD_STEER_DELIVERY_PARAM = "codexhostSteerDelivery";
21008
+ var THREAD_STEERING_CONTEXT_PARAM = "codexhost_external_steering";
21009
+ var threadSteeringContextSchema = external_exports.object({
21010
+ kind: external_exports.literal("application"),
21011
+ value: external_exports.string().transform((text, context) => {
21012
+ try {
21013
+ return JSON.parse(text);
21014
+ } catch {
21015
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
21016
+ return external_exports.NEVER;
21017
+ }
21018
+ }).pipe(external_exports.object({
21019
+ expectedTurnId: hostTurnIdSchema,
21020
+ clientUserMessageId: external_exports.string().min(1),
21021
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
21022
+ }).strict())
21023
+ }).strict().transform((context) => context.value);
21008
21024
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
21009
21025
  var threadSteeringInspectResultSchema = external_exports.object({
21010
21026
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
@@ -23541,7 +23557,9 @@ function findRendererHostRpcFamily(store) {
23541
23557
  if (!record6(members) || typeof members.get !== "function")
23542
23558
  continue;
23543
23559
  for (const [hostId2, member] of members) {
23544
- if (typeof hostId2 !== "string" || !record6(member))
23560
+ if (typeof hostId2 !== "string" || !/^(?:local$|durable$|remote[-:])/u.test(hostId2))
23561
+ continue;
23562
+ if (!record6(member))
23545
23563
  continue;
23546
23564
  const signal = member.value;
23547
23565
  if (!record6(signal) || typeof signal.get !== "function")
@@ -23596,7 +23614,9 @@ function installRendererHostRpcRouting(root, target, dependencies2) {
23596
23614
  return null;
23597
23615
  try {
23598
23616
  const store = dependencies2.findStore(root);
23599
- discovery = store ? dependencies2.findFamily(store) : null;
23617
+ const bound = store && discovery?.store === store ? [...store.familyBindings.values()].includes(discovery.family) : false;
23618
+ if (!bound)
23619
+ discovery = store ? dependencies2.findFamily(store) : null;
23600
23620
  } catch {
23601
23621
  discovery = null;
23602
23622
  }
@@ -24930,6 +24950,114 @@ async function installNativeRpcRemoteControlDirect(renderer) {
24930
24950
  }
24931
24951
  }
24932
24952
 
24953
+ // packages/desktop-control/dist/renderer-rpc-steering.js
24954
+ var RETRY_BASE_MS = 5e3;
24955
+ var RETRY_MAX_MS = 3e5;
24956
+ var retries = /* @__PURE__ */ new WeakMap();
24957
+ async function installRendererRpcSteeringDirect(client, now = Date.now) {
24958
+ try {
24959
+ const needed = await client.evaluate(`(() => {
24960
+ const steering = window.__codexhostRpcSteeringV1;
24961
+ if (steering && steering.controller.forHost === steering.forHost) return false;
24962
+ steering?.release();
24963
+ const routing=window.__codexhostHostRoutingV1;
24964
+ return ['local', ...(routing?.knownHostIds?.() ?? [])].some(id => routing?.forHost(id)?.manager.kind === 'main-process-rpc');
24965
+ })()`);
24966
+ if (!needed)
24967
+ return false;
24968
+ const retry = retries.get(client);
24969
+ if (retry && now() < retry.nextAt)
24970
+ return false;
24971
+ try {
24972
+ await discoverAndInstall(client);
24973
+ retries.delete(client);
24974
+ return true;
24975
+ } catch (error51) {
24976
+ const attempts = (retry?.attempts ?? 0) + 1;
24977
+ const delay7 = Math.min(RETRY_BASE_MS * 2 ** (attempts - 1), RETRY_MAX_MS);
24978
+ retries.set(client, { attempts, nextAt: now() + delay7 });
24979
+ console.error(`codexhost native steering discovery failed (attempt ${attempts}):`, error51 instanceof Error ? error51.message : String(error51));
24980
+ return false;
24981
+ }
24982
+ } catch {
24983
+ return false;
24984
+ }
24985
+ }
24986
+ async function discoverAndInstall(client) {
24987
+ const group = `codexhost-rpc-steering-${crypto.randomUUID()}`;
24988
+ const command = (method, params) => client.command(method, params);
24989
+ const properties = (objectId) => command("Runtime.getProperties", { objectId, ownProperties: true });
24990
+ const call = (objectId, functionDeclaration, args = []) => command("Runtime.callFunctionOn", {
24991
+ objectId,
24992
+ functionDeclaration,
24993
+ arguments: args,
24994
+ objectGroup: group,
24995
+ returnByValue: true
24996
+ });
24997
+ try {
24998
+ const proto = await command("Runtime.evaluate", {
24999
+ expression: "Object.getPrototypeOf(async function(){})",
25000
+ objectGroup: group
25001
+ });
25002
+ if (!proto.result.objectId)
25003
+ throw new Error("Native RPC steering discovery is unavailable");
25004
+ const objects = await command("Runtime.queryObjects", {
25005
+ prototypeObjectId: proto.result.objectId,
25006
+ objectGroup: group
25007
+ });
25008
+ if (!objects.objects.objectId)
25009
+ throw new Error("Native RPC steering discovery is unavailable");
25010
+ const filtered = await command("Runtime.callFunctionOn", {
25011
+ objectId: objects.objects.objectId,
25012
+ functionDeclaration: 'function(){return this.filter(fn=>fn.name==="collectAppStateSnapshot"&&String(fn).includes("collectSnapshot")).slice(0,9)}',
25013
+ objectGroup: group
25014
+ });
25015
+ if (!filtered.result.objectId)
25016
+ throw new Error("Native RPC Controller is unavailable");
25017
+ const snapshots = (await properties(filtered.result.objectId)).result.flatMap((entry) => entry.value?.type === "function" && entry.value.objectId ? [entry.value.objectId] : []);
25018
+ if (snapshots.length > 8)
25019
+ throw new Error("Native RPC Controller is ambiguous");
25020
+ const controllers = [];
25021
+ for (const snapshot2 of snapshots) {
25022
+ const scopes = (await properties(snapshot2)).internalProperties?.find((entry) => entry.name === "[[Scopes]]")?.value?.objectId;
25023
+ if (!scopes)
25024
+ continue;
25025
+ for (const scope of (await properties(scopes)).result) {
25026
+ if (!scope.value?.objectId || !scope.value.description?.startsWith("Closure"))
25027
+ continue;
25028
+ const bindings = (await properties(scope.value.objectId)).result;
25029
+ const owners = [];
25030
+ let rootScope;
25031
+ for (const binding of bindings) {
25032
+ if (binding.value?.type !== "object" || !binding.value.objectId)
25033
+ continue;
25034
+ const id2 = binding.value.objectId;
25035
+ const result2 = await call(id2, `function(){return (${nativeRpcObjectShape.toString()})(this)}`);
25036
+ const shape = result2.result.value;
25037
+ if (shape?.scope)
25038
+ rootScope = id2;
25039
+ if (shape?.controller && (await call(id2, "function(fn){return this.collectAppStateSnapshot===fn}", [
25040
+ { objectId: snapshot2 }
25041
+ ])).result.value === true)
25042
+ owners.push(id2);
25043
+ }
25044
+ if (owners.length !== 1 || !rootScope)
25045
+ continue;
25046
+ const root = await call(rootScope, `function(){let node=this.node;const seen=new Set();while(node?.parent&&!seen.has(node.parent)&&seen.size<100){seen.add(node);node=node.parent}return (${findRendererAppScopeStore.toString()})(document)===node}`);
25047
+ if (root.result.value === true)
25048
+ controllers.push(owners[0]);
25049
+ }
25050
+ }
25051
+ if (controllers.length !== 1)
25052
+ throw new Error("Native RPC Controller is missing or ambiguous");
25053
+ const result = await call(controllers[0], "function(){return window.__codexhostInstallRpcSteeringV1?.(this) === true}");
25054
+ if (result.exceptionDetails || result.result.value !== true)
25055
+ throw new Error("Native RPC steering installation failed");
25056
+ } finally {
25057
+ await client.command("Runtime.releaseObjectGroup", { objectGroup: group }).catch(() => void 0);
25058
+ }
25059
+ }
25060
+
24933
25061
  // packages/desktop-control/dist/renderer-cdp-control-session.js
24934
25062
  function isRecord2(value2) {
24935
25063
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
@@ -25160,6 +25288,7 @@ var defaultOperations = {
25160
25288
  async installDraftPrewarmPolicy(renderer) {
25161
25289
  const status2 = await installRendererDraftPrewarmPolicyDirect(renderer);
25162
25290
  await installNativeRpcRemoteControlDirect(renderer);
25291
+ await installRendererRpcSteeringDirect(renderer);
25163
25292
  return status2;
25164
25293
  }
25165
25294
  };
@@ -35432,6 +35561,7 @@ var publicSubmission = ({
35432
35561
  var DEFAULT_PAGE_SIZE3 = 50;
35433
35562
  var ExternalThreadQueue = class {
35434
35563
  #queues = /* @__PURE__ */ new Map();
35564
+ #acceptedSteers = /* @__PURE__ */ new Map();
35435
35565
  #notifyChanged;
35436
35566
  #createId;
35437
35567
  constructor(options) {
@@ -35473,7 +35603,7 @@ var ExternalThreadQueue = class {
35473
35603
  async delete(threadId2, id2) {
35474
35604
  const items = this.#queues.get(threadId2);
35475
35605
  const index = items?.findIndex((item) => item.id === id2) ?? -1;
35476
- if (!items || index === -1) return false;
35606
+ if (!items || index === -1) return this.#acceptedSteers.get(id2) === threadId2;
35477
35607
  items.splice(index, 1);
35478
35608
  this.#prune(threadId2);
35479
35609
  await this.#notifyChanged(threadId2);
@@ -35506,6 +35636,26 @@ var ExternalThreadQueue = class {
35506
35636
  index
35507
35637
  };
35508
35638
  }
35639
+ /** Reserve the exact queued input before steering can finish a replacement Turn.
35640
+ * Otherwise automatic queue advancement can deliver that input a second time. */
35641
+ takeSteered(threadId2, clientUserMessageId, input) {
35642
+ if (typeof clientUserMessageId !== "string") return;
35643
+ const matches = (this.#queues.get(threadId2) ?? []).filter(
35644
+ (item2) => item2.clientUserMessageId === clientUserMessageId
35645
+ );
35646
+ if (matches.length === 0) return;
35647
+ const item = matches[0];
35648
+ if (matches.length !== 1 || externalTurnInputText(item.input) !== externalTurnInputText(input))
35649
+ throw new ExternalQueueError(-32602, "Queued steering input changed before delivery");
35650
+ return this.take(threadId2, item.id);
35651
+ }
35652
+ async acceptSteered(threadId2, taken) {
35653
+ this.#acceptedSteers.set(taken.submission.id, threadId2);
35654
+ while (this.#acceptedSteers.size > 128) {
35655
+ this.#acceptedSteers.delete(this.#acceptedSteers.keys().next().value);
35656
+ }
35657
+ await this.#notifyChanged(threadId2);
35658
+ }
35509
35659
  restore(threadId2, taken) {
35510
35660
  const items = this.#items(threadId2);
35511
35661
  if (items.some((item) => item.id === taken.submission.id)) return;
@@ -35519,6 +35669,9 @@ var ExternalThreadQueue = class {
35519
35669
  }
35520
35670
  forget(threadId2) {
35521
35671
  this.#queues.delete(threadId2);
35672
+ for (const [id2, owner] of this.#acceptedSteers) {
35673
+ if (owner === threadId2) this.#acceptedSteers.delete(id2);
35674
+ }
35522
35675
  }
35523
35676
  #items(threadId2) {
35524
35677
  let items = this.#queues.get(threadId2);
@@ -43524,7 +43677,7 @@ var AppServerHost = class {
43524
43677
  ...arguments_2 ? { arguments: arguments_2 } : {}
43525
43678
  });
43526
43679
  if (!result.ok) throw new ExternalCommandError(-32073, result.error.message);
43527
- return { turnId: result.value.turnId, turn: projection.projector.pendingTurn(), gate };
43680
+ return { turnId, turn: projection.projector.pendingTurn(), gate };
43528
43681
  } catch (error51) {
43529
43682
  restoreExecutionHost();
43530
43683
  thread.running = false;
@@ -44306,6 +44459,11 @@ var AppServerHost = class {
44306
44459
  }
44307
44460
  }
44308
44461
  async #startExternalTurn(request, thread) {
44462
+ const context = routingParams(request).additionalContext;
44463
+ if (isRecord18(context) && Object.hasOwn(context, THREAD_STEERING_CONTEXT_PARAM)) {
44464
+ await this.#steerExternalTurn(request, thread, true);
44465
+ return;
44466
+ }
44309
44467
  if (this.#externalThreadBusy(thread) || this.#pendingExternalCommandRequests.has(thread.id)) {
44310
44468
  await this.#writer.json(
44311
44469
  rpcError(request, -32072, "External Thread already has an active Turn")
@@ -44477,34 +44635,61 @@ var AppServerHost = class {
44477
44635
  this.#diagnose(error51);
44478
44636
  }
44479
44637
  }
44480
- async #steerExternalTurn(request, thread) {
44638
+ async #steerExternalTurn(request, thread, asStart = false) {
44639
+ let queued;
44640
+ let accepted = false;
44481
44641
  try {
44642
+ let params = requestObject(request);
44643
+ const context = params.additionalContext;
44644
+ if (isRecord18(context) && Object.hasOwn(context, THREAD_STEERING_CONTEXT_PARAM)) {
44645
+ const marker = threadSteeringContextSchema.safeParse(
44646
+ context[THREAD_STEERING_CONTEXT_PARAM]
44647
+ );
44648
+ if (!marker.success || marker.data.clientUserMessageId !== params.clientUserMessageId || asStart && marker.data.delivery !== "newTurn")
44649
+ throw new ExternalSteerError(-32602, "Invalid native steering preparation context");
44650
+ if (!asStart && params.expectedTurnId !== marker.data.expectedTurnId)
44651
+ throw new ExternalSteerError(-32074, "Native steering target changed before submission");
44652
+ params = {
44653
+ ...params,
44654
+ expectedTurnId: marker.data.expectedTurnId,
44655
+ [THREAD_STEER_DELIVERY_PARAM]: marker.data.delivery
44656
+ };
44657
+ }
44658
+ queued = this.#externalQueue.takeSteered(thread.id, params.clientUserMessageId, params.input);
44482
44659
  const started = await this.#externalSteering.run(
44483
44660
  thread,
44484
- requestObject(request),
44661
+ params,
44485
44662
  (text, assertActive) => this.#beginExternalInputTurn(
44486
44663
  thread,
44487
44664
  text,
44488
44665
  assertActive,
44489
44666
  typeof requestObject(request).clientUserMessageId === "string" ? requestObject(request).clientUserMessageId : void 0,
44490
- requestObject(request)[THREAD_REFERENCE_SOURCE_HOST_PARAM]
44667
+ queued ? queued.sourceHostId : requestObject(request)[THREAD_REFERENCE_SOURCE_HOST_PARAM]
44491
44668
  ),
44492
44669
  (input) => this.#insertExternalInput(thread, input)
44493
44670
  );
44671
+ accepted = true;
44672
+ if (queued) {
44673
+ await this.#externalQueue.acceptSteered(thread.id, queued).catch((error51) => this.#diagnose(error51));
44674
+ }
44494
44675
  try {
44495
44676
  await this.#writer.json(
44496
44677
  rpcEnvelope(request, {
44497
- result: { turnId: started.turnId, delivery: started.delivery }
44678
+ result: asStart ? { turn: this.#projectedTurn(thread, started.turnId).projector.pendingTurn() } : { turnId: started.turnId, delivery: started.delivery }
44498
44679
  })
44499
44680
  );
44500
44681
  } finally {
44501
44682
  started.gate.resolve();
44502
44683
  }
44503
44684
  } catch (error51) {
44685
+ if (queued && !accepted) {
44686
+ this.#externalQueue.restore(thread.id, queued);
44687
+ await this.#externalQueue.notifyChanged(thread.id).catch((failure) => this.#diagnose(failure));
44688
+ }
44504
44689
  await this.#writer.json(
44505
44690
  rpcError(
44506
44691
  request,
44507
- error51 instanceof ExternalSteerError || error51 instanceof ExternalCommandError ? error51.code : -32074,
44692
+ error51 instanceof ExternalSteerError || error51 instanceof ExternalCommandError || error51 instanceof ExternalQueueError ? error51.code : -32074,
44508
44693
  errorMessage4(error51)
44509
44694
  )
44510
44695
  );
@@ -15898,6 +15898,21 @@ var threadSteeringInspectParamsSchema = external_exports.object({
15898
15898
  /** The text about to be steered; a Harness command always stops and restarts. */
15899
15899
  text: external_exports.string().optional()
15900
15900
  }).strict();
15901
+ var threadSteeringContextSchema = external_exports.object({
15902
+ kind: external_exports.literal("application"),
15903
+ value: external_exports.string().transform((text, context) => {
15904
+ try {
15905
+ return JSON.parse(text);
15906
+ } catch {
15907
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
15908
+ return external_exports.NEVER;
15909
+ }
15910
+ }).pipe(external_exports.object({
15911
+ expectedTurnId: hostTurnIdSchema,
15912
+ clientUserMessageId: external_exports.string().min(1),
15913
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
15914
+ }).strict())
15915
+ }).strict().transform((context) => context.value);
15901
15916
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15902
15917
  var threadSteeringInspectResultSchema = external_exports.object({
15903
15918
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
@@ -15492,6 +15492,21 @@ var threadSteeringInspectParamsSchema = external_exports.object({
15492
15492
  /** The text about to be steered; a Harness command always stops and restarts. */
15493
15493
  text: external_exports.string().optional()
15494
15494
  }).strict();
15495
+ var threadSteeringContextSchema = external_exports.object({
15496
+ kind: external_exports.literal("application"),
15497
+ value: external_exports.string().transform((text2, context) => {
15498
+ try {
15499
+ return JSON.parse(text2);
15500
+ } catch {
15501
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
15502
+ return external_exports.NEVER;
15503
+ }
15504
+ }).pipe(external_exports.object({
15505
+ expectedTurnId: hostTurnIdSchema,
15506
+ clientUserMessageId: external_exports.string().min(1),
15507
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
15508
+ }).strict())
15509
+ }).strict().transform((context) => context.value);
15495
15510
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15496
15511
  var threadSteeringInspectResultSchema = external_exports.object({
15497
15512
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
@@ -15968,6 +15968,21 @@ var threadSteeringInspectParamsSchema = external_exports.object({
15968
15968
  /** The text about to be steered; a Harness command always stops and restarts. */
15969
15969
  text: external_exports.string().optional()
15970
15970
  }).strict();
15971
+ var threadSteeringContextSchema = external_exports.object({
15972
+ kind: external_exports.literal("application"),
15973
+ value: external_exports.string().transform((text2, context) => {
15974
+ try {
15975
+ return JSON.parse(text2);
15976
+ } catch {
15977
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
15978
+ return external_exports.NEVER;
15979
+ }
15980
+ }).pipe(external_exports.object({
15981
+ expectedTurnId: hostTurnIdSchema,
15982
+ clientUserMessageId: external_exports.string().min(1),
15983
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
15984
+ }).strict())
15985
+ }).strict().transform((context) => context.value);
15971
15986
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15972
15987
  var threadSteeringInspectResultSchema = external_exports.object({
15973
15988
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
@@ -15486,6 +15486,21 @@ var threadSteeringInspectParamsSchema = external_exports.object({
15486
15486
  /** The text about to be steered; a Harness command always stops and restarts. */
15487
15487
  text: external_exports.string().optional()
15488
15488
  }).strict();
15489
+ var threadSteeringContextSchema = external_exports.object({
15490
+ kind: external_exports.literal("application"),
15491
+ value: external_exports.string().transform((text2, context) => {
15492
+ try {
15493
+ return JSON.parse(text2);
15494
+ } catch {
15495
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
15496
+ return external_exports.NEVER;
15497
+ }
15498
+ }).pipe(external_exports.object({
15499
+ expectedTurnId: hostTurnIdSchema,
15500
+ clientUserMessageId: external_exports.string().min(1),
15501
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
15502
+ }).strict())
15503
+ }).strict().transform((context) => context.value);
15489
15504
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15490
15505
  var threadSteeringInspectResultSchema = external_exports.object({
15491
15506
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
@@ -19543,6 +19543,21 @@ var threadSteeringInspectParamsSchema = external_exports.object({
19543
19543
  /** The text about to be steered; a Harness command always stops and restarts. */
19544
19544
  text: external_exports.string().optional()
19545
19545
  }).strict();
19546
+ var threadSteeringContextSchema = external_exports.object({
19547
+ kind: external_exports.literal("application"),
19548
+ value: external_exports.string().transform((text, context) => {
19549
+ try {
19550
+ return JSON.parse(text);
19551
+ } catch {
19552
+ context.addIssue({ code: "custom", message: "Invalid steering context JSON" });
19553
+ return external_exports.NEVER;
19554
+ }
19555
+ }).pipe(external_exports.object({
19556
+ expectedTurnId: hostTurnIdSchema,
19557
+ clientUserMessageId: external_exports.string().min(1),
19558
+ delivery: external_exports.enum(["newTurn", "activeTurn"])
19559
+ }).strict())
19560
+ }).strict().transform((context) => context.value);
19546
19561
  var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
19547
19562
  var threadSteeringInspectResultSchema = external_exports.object({
19548
19563
  delivery: external_exports.enum(["official", "activeTurn", "newTurn"])