ds-harness-remote 0.4.12 → 0.4.13

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 (42) hide show
  1. package/README.md +4 -4
  2. package/dist/client-runtime.d.ts +8 -1
  3. package/dist/client-runtime.d.ts.map +1 -1
  4. package/dist/client-runtime.js +34 -24
  5. package/dist/client-runtime.js.map +1 -1
  6. package/dist/codex/peer-bridge.d.ts.map +1 -1
  7. package/dist/codex/peer-bridge.js +3 -4
  8. package/dist/codex/peer-bridge.js.map +1 -1
  9. package/dist/control-route.d.ts +22 -0
  10. package/dist/control-route.d.ts.map +1 -1
  11. package/dist/control-route.js +120 -0
  12. package/dist/control-route.js.map +1 -1
  13. package/dist/control-runtime.d.ts +2 -1
  14. package/dist/control-runtime.d.ts.map +1 -1
  15. package/dist/control-runtime.js +3 -5
  16. package/dist/control-runtime.js.map +1 -1
  17. package/dist/harness-api-bridge.d.ts.map +1 -1
  18. package/dist/harness-api-bridge.js +3 -3
  19. package/dist/harness-api-bridge.js.map +1 -1
  20. package/dist/harness-remote-bridge.d.ts.map +1 -1
  21. package/dist/harness-remote-bridge.js +3 -4
  22. package/dist/harness-remote-bridge.js.map +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +474 -125
  25. package/dist/index.js.map +4 -4
  26. package/dist/remote-typert-gateway.d.ts +3 -1
  27. package/dist/remote-typert-gateway.d.ts.map +1 -1
  28. package/dist/remote-typert-gateway.js +16 -5
  29. package/dist/remote-typert-gateway.js.map +1 -1
  30. package/dist/service.d.ts.map +1 -1
  31. package/dist/service.js +1 -1
  32. package/dist/service.js.map +1 -1
  33. package/dist/session-format-compat.d.ts +3 -0
  34. package/dist/session-format-compat.d.ts.map +1 -0
  35. package/dist/session-format-compat.js +183 -0
  36. package/dist/session-format-compat.js.map +1 -0
  37. package/dist/tui-command.js +5 -3
  38. package/dist/tui-command.js.map +1 -1
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/dsh-plugin.json +1 -1
  42. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4059,6 +4059,13 @@ var MAX_DEVICE_NAME_LENGTH = 128;
4059
4059
  var MAX_DEVICE_PLATFORM_LENGTH = 64;
4060
4060
  var MAX_DEVICE_VERSION_LENGTH = 64;
4061
4061
  var MAX_AUTH_TOKEN_LENGTH = 8 * 1024;
4062
+ var HOST_REGISTRATION_CODE_TTL_MS = 10 * 6e4;
4063
+ var MAX_ACTIVE_TRANSFERS_PER_DIRECTION = 2;
4064
+ var TRANSFER_IDLE_MS = 2 * 6e4;
4065
+ var MAX_RPC_TEXT_INPUT_BYTES = 64 * 1024;
4066
+ var MAX_FILEVIEWER_RANGE_BYTES = 512 * 1024;
4067
+ var MIN_REPLAY_WINDOW_MS = 15 * 6e4;
4068
+ var MAX_ALPHA_STREAMS_PER_CONNECTION = 16;
4062
4069
  var SECURE_FRAGMENT_MAGIC = new Uint8Array([68, 83, 72, 70]);
4063
4070
  var SECURE_FRAGMENT_VERSION = 1;
4064
4071
  var SECURE_FRAGMENT_HEADER_BYTES = 17;
@@ -4116,6 +4123,52 @@ var rpcMethods = [
4116
4123
  "codex.app.transfer.read",
4117
4124
  "codex.app.transfer.close"
4118
4125
  ];
4126
+ var errorCodes = [
4127
+ // Protocol / Version
4128
+ "INVALID_MESSAGE",
4129
+ "UNSUPPORTED_VERSION",
4130
+ "CAPABILITY_NOT_SUPPORTED",
4131
+ "METHOD_NOT_FOUND",
4132
+ "METHOD_NOT_ALLOWED",
4133
+ "REQUEST_CONFLICT",
4134
+ "FRAME_TOO_LARGE",
4135
+ "RATE_LIMITED",
4136
+ // Auth / Device
4137
+ "AUTH_REQUIRED",
4138
+ "AUTH_INVALID",
4139
+ "ACCOUNT_AUTH_REQUIRED",
4140
+ "TOKEN_EXPIRED",
4141
+ "DEVICE_NOT_FOUND",
4142
+ "DEVICE_REVOKED",
4143
+ "DEVICE_OWNERSHIP_REQUIRED",
4144
+ "MEMBERSHIP_REQUIRED",
4145
+ "PEER_IDENTITY_MISMATCH",
4146
+ "HOST_REGISTRATION_CODE_NOT_FOUND",
4147
+ "HOST_REGISTRATION_CODE_EXPIRED",
4148
+ "HOST_REGISTRATION_CODE_CONSUMED",
4149
+ // Connection / Transport
4150
+ "HOST_OFFLINE",
4151
+ "CONNECTION_NOT_FOUND",
4152
+ "CONNECTION_FAILED",
4153
+ "CONNECTION_REPLACED",
4154
+ "P2P_FAILED",
4155
+ "TURN_UNAVAILABLE",
4156
+ "RELAY_UNAVAILABLE",
4157
+ "SLOW_CONSUMER",
4158
+ "SECURE_CHANNEL_FAILED",
4159
+ // Harness
4160
+ "HARNESS_UNAVAILABLE",
4161
+ "HARNESS_VERSION_INCOMPATIBLE",
4162
+ "RESPONSE_TOO_LARGE",
4163
+ "SESSION_NOT_FOUND",
4164
+ "SESSION_NOT_READY",
4165
+ "AGENT_BUSY",
4166
+ "PERMISSION_DENIED",
4167
+ "PERMISSION_NOT_PENDING",
4168
+ "RPC_TIMEOUT",
4169
+ "FULL_RESYNC_REQUIRED",
4170
+ "INTERNAL_ERROR"
4171
+ ];
4119
4172
  var selectedTransports = ["lan", "p2p", "turn", "relay"];
4120
4173
  function normalizeSdpMLineIndex(value) {
4121
4174
  if (value === void 0)
@@ -4140,6 +4193,7 @@ function acceptNegotiatedCapabilities(offered, negotiated) {
4140
4193
  var rpcMethodSchema = external_exports.enum(rpcMethods);
4141
4194
  var messageTypeSchema = external_exports.enum(messageTypes);
4142
4195
  var controlFrameTypeSchema = external_exports.enum(controlFrameTypes);
4196
+ var errorCodeSchema = external_exports.enum(errorCodes);
4143
4197
  var uniqueStrings = (values) => new Set(values).size === values.length;
4144
4198
  var uniqueNumbers = (values) => new Set(values).size === values.length;
4145
4199
  var utf8Length = (value) => new TextEncoder().encode(value).byteLength;
@@ -4181,6 +4235,10 @@ var hostRegistrationCodeRequestSchema = external_exports.object({
4181
4235
  code: external_exports.string().regex(/^[A-Z0-9]{4}-[A-Z0-9]{4}$/u),
4182
4236
  device: hostDeviceDescriptorSchema
4183
4237
  }).strict();
4238
+ var registerOwnedRoleRequestSchema = external_exports.object({
4239
+ v: external_exports.literal(PROTOCOL_VERSION),
4240
+ device: accountDeviceDescriptorSchema
4241
+ }).strict();
4184
4242
  var deviceRefreshRequestSchema = external_exports.object({
4185
4243
  deviceId: deviceIdSchema,
4186
4244
  refreshToken: authTokenSchema
@@ -13958,6 +14016,120 @@ async function waitForResponder(inner, noise) {
13958
14016
 
13959
14017
  // src/control-route.ts
13960
14018
  var CONTROL_RPC_PREFIX = "/ds-harness-remote";
14019
+ var ENDPOINT_SEGMENT_PATTERN = /^[A-Za-z0-9_$.-]+$/;
14020
+ var INVALID_REQUEST_RPC_ID = "invalid-request";
14021
+ function registerControlRoute(connection, handler, webServer) {
14022
+ if (webServer !== void 0 && connection.requestRejection !== void 0) {
14023
+ const dispose = webServer.register({
14024
+ kind: "prefix",
14025
+ path: CONTROL_RPC_PREFIX,
14026
+ handler: (req, res) => handleControlRequest(connection, handler, req, res)
14027
+ });
14028
+ return async () => {
14029
+ await dispose();
14030
+ };
14031
+ }
14032
+ return connection.rpc.handle(CONTROL_RPC_PREFIX, handler, {
14033
+ authority: "loopback"
14034
+ });
14035
+ }
14036
+ async function handleControlRequest(connection, handler, req, res) {
14037
+ const rejection = connection.requestRejection?.(req);
14038
+ if (rejection !== void 0) {
14039
+ res.writeHead(rejection);
14040
+ res.end(rejection === 401 ? "unauthorized" : "forbidden");
14041
+ return;
14042
+ }
14043
+ const endpoint = endpointFromPath(CONTROL_RPC_PREFIX, new URL(req.url ?? "/", "http://dsh.internal").pathname);
14044
+ if (req.method !== "POST" || endpoint === void 0) {
14045
+ writeText(res, 404, "not found");
14046
+ return;
14047
+ }
14048
+ if (contentType(req.headers) !== "application/json") {
14049
+ writeText(res, 415, "content type must be application/json");
14050
+ return;
14051
+ }
14052
+ let body;
14053
+ try {
14054
+ body = await readJsonBody(req);
14055
+ } catch {
14056
+ writeText(res, 400, "body is not JSON");
14057
+ return;
14058
+ }
14059
+ const message = clientRequest(body);
14060
+ if (message === void 0) {
14061
+ writeJson(res, 200, errorResponse(rpcId(body), {
14062
+ code: "gateway/bad-request",
14063
+ message: "invalid client-request message",
14064
+ details: { issues: [] }
14065
+ }));
14066
+ return;
14067
+ }
14068
+ if (message.method !== endpoint) {
14069
+ writeJson(res, 200, errorResponse(message.rpcId, {
14070
+ code: "gateway/bad-request",
14071
+ message: `method ${JSON.stringify(message.method)} does not match endpoint ${JSON.stringify(endpoint)}`,
14072
+ details: { issues: [] }
14073
+ }));
14074
+ return;
14075
+ }
14076
+ try {
14077
+ const result = await handler(endpoint, message.payload, requestSignal(req));
14078
+ writeJson(res, 200, fullResponse(message.rpcId, result));
14079
+ } catch (error) {
14080
+ writeText(res, 500, `handler failure: ${String(error)}`);
14081
+ }
14082
+ }
14083
+ function endpointFromPath(channel, pathname) {
14084
+ if (!pathname.startsWith(`${channel}/`)) return void 0;
14085
+ const endpoint = pathname.slice(channel.length + 1);
14086
+ if (endpoint.split("/").some((segment) => segment === "" || segment === "." || segment === ".." || !ENDPOINT_SEGMENT_PATTERN.test(segment))) {
14087
+ return void 0;
14088
+ }
14089
+ return endpoint;
14090
+ }
14091
+ function contentType(headers) {
14092
+ const raw = headers["content-type"];
14093
+ const value = Array.isArray(raw) ? raw[0] : raw;
14094
+ return value?.split(";", 1)[0]?.trim().toLowerCase();
14095
+ }
14096
+ async function readJsonBody(req) {
14097
+ const chunks = [];
14098
+ for await (const chunk of req) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
14099
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
14100
+ }
14101
+ function requestSignal(req) {
14102
+ const abort = new AbortController();
14103
+ req.on("close", () => {
14104
+ if (!req.complete) abort.abort();
14105
+ });
14106
+ return abort.signal;
14107
+ }
14108
+ function clientRequest(value) {
14109
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
14110
+ const record6 = value;
14111
+ if (record6.type !== "client-request" || typeof record6.rpcId !== "string" || typeof record6.method !== "string") return void 0;
14112
+ return { type: "client-request", rpcId: record6.rpcId, method: record6.method, payload: record6.payload };
14113
+ }
14114
+ function rpcId(value) {
14115
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return INVALID_REQUEST_RPC_ID;
14116
+ const record6 = value;
14117
+ return typeof record6.rpcId === "string" ? record6.rpcId : INVALID_REQUEST_RPC_ID;
14118
+ }
14119
+ function errorResponse(rpcId2, error) {
14120
+ return fullResponse(rpcId2, { ok: false, error });
14121
+ }
14122
+ function fullResponse(rpcId2, result) {
14123
+ return { type: "server-response", rpcId: rpcId2, result };
14124
+ }
14125
+ function writeJson(res, status2, body) {
14126
+ res.writeHead(status2, { "content-type": "application/json" });
14127
+ res.end(JSON.stringify(body));
14128
+ }
14129
+ function writeText(res, status2, body) {
14130
+ res.writeHead(status2);
14131
+ res.end(body);
14132
+ }
13961
14133
 
13962
14134
  // src/ids.ts
13963
14135
  import { randomBytes as randomBytes6 } from "node:crypto";
@@ -14310,11 +14482,168 @@ function base64ToBytes2(value) {
14310
14482
  return bytes;
14311
14483
  }
14312
14484
 
14485
+ // src/session-format-compat.ts
14486
+ function normalizeLegacySessionGatewayValue(endpoint, value) {
14487
+ if (endpoint === "session/page") return normalizePage(value);
14488
+ if (endpoint === "session/follow") return normalizeFollowFrame(value);
14489
+ return value;
14490
+ }
14491
+ function normalizeFollowFrame(value) {
14492
+ if (!isRecord3(value)) return value;
14493
+ if (value.type === "snapshot") {
14494
+ return {
14495
+ ...value,
14496
+ header: normalizeHeader(value.header),
14497
+ records: normalizeRecords(value.records),
14498
+ ...value.assistantStream === void 0 ? { assistantStream: { revision: 0 } } : {}
14499
+ };
14500
+ }
14501
+ return normalizeEntry(value);
14502
+ }
14503
+ function normalizePage(value) {
14504
+ if (!isRecord3(value)) return value;
14505
+ return { ...value, records: normalizeRecords(value.records) };
14506
+ }
14507
+ function normalizeRecords(value) {
14508
+ if (!Array.isArray(value)) return value;
14509
+ const records = [];
14510
+ let previousSeq;
14511
+ for (const record6 of value) {
14512
+ if (!isEventEntry(record6)) continue;
14513
+ const seq = entrySeq(record6);
14514
+ if (previousSeq !== void 0 && seq !== void 0 && seq > previousSeq + 1) {
14515
+ for (let fillerSeq = previousSeq + 1; fillerSeq < seq; fillerSeq += 1) {
14516
+ records.push(createLegacyGapRecord(fillerSeq, record6));
14517
+ }
14518
+ }
14519
+ records.push(normalizeEntry(record6));
14520
+ if (seq !== void 0) previousSeq = seq;
14521
+ }
14522
+ return records;
14523
+ }
14524
+ function normalizeEntry(value) {
14525
+ if (!isEventEntry(value)) return value;
14526
+ return { ...value, event: normalizeEvent(value.event) };
14527
+ }
14528
+ function entrySeq(value) {
14529
+ if (!isEventEntry(value)) return void 0;
14530
+ return isEventSeq(value.event.seq) ? value.event.seq : void 0;
14531
+ }
14532
+ function createLegacyGapRecord(seq, nextRecord) {
14533
+ return {
14534
+ type: "event",
14535
+ event: {
14536
+ type: "legacy/session-gap",
14537
+ seq,
14538
+ time: eventTime(nextRecord),
14539
+ ignorable: true,
14540
+ data: {}
14541
+ }
14542
+ };
14543
+ }
14544
+ function eventTime(value) {
14545
+ if (!isEventEntry(value)) return 0;
14546
+ return typeof value.event.time === "number" && Number.isSafeInteger(value.event.time) ? value.event.time : 0;
14547
+ }
14548
+ function isEventEntry(value) {
14549
+ return isRecord3(value) && value.type === "event" && isRecord3(value.event);
14550
+ }
14551
+ function normalizeHeader(value) {
14552
+ if (!isRecord3(value)) return value;
14553
+ const next = {
14554
+ ...value,
14555
+ version: 3,
14556
+ ...value.delegationDepth === void 0 ? { delegationDepth: 0 } : {}
14557
+ };
14558
+ return next.agentPreset === "code" ? { ...next, agentPreset: "ptc" } : next;
14559
+ }
14560
+ function normalizeEvent(value) {
14561
+ if (!isRecord3(value)) return value;
14562
+ let next = value;
14563
+ const type = normalizeEventType(value.type);
14564
+ if (type !== value.type) next = { ...next, type };
14565
+ if (type === "assistant/message" && Object.hasOwn(next, "sourceEventSeqs")) {
14566
+ const { sourceEventSeqs: _sourceEventSeqs, ...rest } = next;
14567
+ next = rest;
14568
+ }
14569
+ const data = normalizeEventData(type, next.data);
14570
+ if (data !== next.data) next = { ...next, data };
14571
+ const surfaceOp = normalizeSurfaceOp(next.surfaceOp);
14572
+ if (surfaceOp !== next.surfaceOp) next = { ...next, surfaceOp };
14573
+ return next;
14574
+ }
14575
+ function normalizeEventType(value) {
14576
+ if (value === "tool/code-dispatch-start") return "tool/ptc-dispatch-start";
14577
+ if (value === "tool/code-dispatch") return "tool/ptc-dispatch";
14578
+ return value;
14579
+ }
14580
+ function normalizeEventData(type, value) {
14581
+ if (!isRecord3(value)) return value;
14582
+ if (type === "request/header") return normalizeRequestHeaderData(value);
14583
+ if (type === "agent-preset/selected" && value.agentPreset === "code") return { ...value, agentPreset: "ptc" };
14584
+ if (type === "user/message") return normalizeMessage(value);
14585
+ if (type === "agent/inbox/spliced" && Array.isArray(value.inserted)) {
14586
+ return { ...value, inserted: value.inserted.map((item) => normalizeMessage(item)) };
14587
+ }
14588
+ if (type === "session/title-llm-request" && Array.isArray(value.messages)) {
14589
+ return { ...value, messages: value.messages.map((item) => normalizeMessage(item)) };
14590
+ }
14591
+ return value;
14592
+ }
14593
+ function normalizeRequestHeaderData(value) {
14594
+ if (!isRecord3(value.header)) return value;
14595
+ const header = normalizeRequestHeader(value.header);
14596
+ return header === value.header ? value : { ...value, header };
14597
+ }
14598
+ function normalizeRequestHeader(value) {
14599
+ let changed = false;
14600
+ const next = {};
14601
+ for (const [key, field] of Object.entries(value)) {
14602
+ if (key === "system") {
14603
+ changed = true;
14604
+ continue;
14605
+ }
14606
+ if (key === "tools" && Array.isArray(field) && field.length === 0) {
14607
+ changed = true;
14608
+ continue;
14609
+ }
14610
+ if (key === "adapterDefaults" && isRecord3(field) && Object.keys(field).length === 0) {
14611
+ changed = true;
14612
+ continue;
14613
+ }
14614
+ next[key] = field;
14615
+ }
14616
+ return changed ? next : value;
14617
+ }
14618
+ function normalizeMessage(value) {
14619
+ if (!isRecord3(value) || !isRecord3(value.source)) return value;
14620
+ if (value.source.kind !== "plugin" || value.source.plugin !== "tools-code-mode") return value;
14621
+ return { ...value, source: { ...value.source, plugin: "tools-ptc" } };
14622
+ }
14623
+ function normalizeSurfaceOp(value) {
14624
+ if (!isRecord3(value) || value.op !== "replace") return value;
14625
+ const { start, end, ...rest } = value;
14626
+ if (start === void 0 && end === void 0) return value;
14627
+ return {
14628
+ ...rest,
14629
+ op: "replace",
14630
+ ...start === void 0 ? {} : { startSeq: start },
14631
+ ...end === void 0 ? {} : { endSeq: end }
14632
+ };
14633
+ }
14634
+ function isRecord3(value) {
14635
+ return typeof value === "object" && value !== null && !Array.isArray(value);
14636
+ }
14637
+ function isEventSeq(value) {
14638
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && !Object.is(value, -0);
14639
+ }
14640
+
14313
14641
  // src/remote-typert-gateway.ts
14314
14642
  var DIRECT_REMOTE_CALL_BYTES2 = 2 * 1024 * 1024;
14315
14643
  var RemoteTypertGateway2 = class {
14316
- constructor(client) {
14644
+ constructor(client, compatibility) {
14317
14645
  this.client = client;
14646
+ this.compatibility = compatibility;
14318
14647
  }
14319
14648
  async invoke(request) {
14320
14649
  const result = await this.dispatch(
@@ -14339,7 +14668,11 @@ var RemoteTypertGateway2 = class {
14339
14668
  response = await this.callTransferred(encoded, signal);
14340
14669
  }
14341
14670
  }
14342
- return parseRpcResult(response);
14671
+ const result = parseRpcResult(response);
14672
+ if (result.ok && this.compatibility === "legacy-to-v3") {
14673
+ return { ...result, value: normalizeLegacySessionGatewayValue(endpoint, result.value) };
14674
+ }
14675
+ return result;
14343
14676
  }
14344
14677
  async open(endpoint, payload, signal) {
14345
14678
  const streamId = uuidV7();
@@ -14358,11 +14691,13 @@ var RemoteTypertGateway2 = class {
14358
14691
  unsubscribeClose();
14359
14692
  throw error;
14360
14693
  }
14361
- return this.iterate(streamId, queue, unsubscribe, unsubscribeClose, signal, onAbort);
14694
+ return this.iterate(streamId, endpoint, queue, unsubscribe, unsubscribeClose, signal, onAbort);
14362
14695
  }
14363
- async *iterate(streamId, queue, unsubscribe, unsubscribeClose, signal, onAbort) {
14696
+ async *iterate(streamId, endpoint, queue, unsubscribe, unsubscribeClose, signal, onAbort) {
14364
14697
  try {
14365
- yield* queue;
14698
+ for await (const value of queue) {
14699
+ yield this.compatibility === "legacy-to-v3" ? normalizeLegacySessionGatewayValue(endpoint, value) : value;
14700
+ }
14366
14701
  } finally {
14367
14702
  signal.removeEventListener("abort", onAbort);
14368
14703
  unsubscribe();
@@ -14482,16 +14817,16 @@ function routeStreamEvent2(event, streamId, queue) {
14482
14817
  queue.fail(remoteFailure({
14483
14818
  code: typeof failure2?.code === "string" ? failure2.code : "internal",
14484
14819
  message: typeof failure2?.message === "string" ? failure2.message : "The remote Harness stream failed.",
14485
- details: isRecord3(failure2?.details) ? failure2.details : {}
14820
+ details: isRecord4(failure2?.details) ? failure2.details : {}
14486
14821
  }));
14487
14822
  } else {
14488
14823
  queue.close();
14489
14824
  }
14490
14825
  }
14491
14826
  function parseRpcResult(value) {
14492
- if (!isRecord3(value)) throw new Error("The remote Host returned an invalid Gateway result.");
14827
+ if (!isRecord4(value)) throw new Error("The remote Host returned an invalid Gateway result.");
14493
14828
  if (value.ok === true) return Object.hasOwn(value, "value") ? { ok: true, value: value.value } : { ok: true };
14494
- if (value.ok !== false || !isRecord3(value.error) || typeof value.error.code !== "string" || typeof value.error.message !== "string" || !isRecord3(value.error.details)) {
14829
+ if (value.ok !== false || !isRecord4(value.error) || typeof value.error.code !== "string" || typeof value.error.message !== "string" || !isRecord4(value.error.details)) {
14495
14830
  throw new Error("The remote Host returned an invalid Gateway failure.");
14496
14831
  }
14497
14832
  return {
@@ -14525,7 +14860,7 @@ function base64ToBytes3(value) {
14525
14860
  if (bytesToBase643(bytes) !== value) throw new Error("The remote Host returned non-canonical Harness Remote transfer data.");
14526
14861
  return bytes;
14527
14862
  }
14528
- function isRecord3(value) {
14863
+ function isRecord4(value) {
14529
14864
  return typeof value === "object" && value !== null && !Array.isArray(value);
14530
14865
  }
14531
14866
  function hasErrorCode(error, code) {
@@ -15446,7 +15781,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
15446
15781
  this.broadcastRcHost({ type: "host/session-status", sessionId, running: args[1] });
15447
15782
  } else if (event === "api-session/removed" && sessionId !== void 0) {
15448
15783
  this.broadcastRcHost({ type: "host/session-removed", sessionId });
15449
- } else if (event === "api-session/added" && isRecord4(args[0])) {
15784
+ } else if (event === "api-session/added" && isRecord5(args[0])) {
15450
15785
  const summary = args[0];
15451
15786
  this.broadcastRcHost({
15452
15787
  type: "host/session-added",
@@ -15831,7 +16166,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
15831
16166
  }
15832
16167
  createApiProxy() {
15833
16168
  const call = (endpoint) => async (request, signal) => {
15834
- const payload = endpoint === "session.prompt" && isRecord4(request.payload) ? { ...request.payload, requestId: String(request.rpcId) } : request.payload;
16169
+ const payload = endpoint === "session.prompt" && isRecord5(request.payload) ? { ...request.payload, requestId: String(request.rpcId) } : request.payload;
15835
16170
  const result = await this.dispatch(rcEndpoint(endpoint), { args: { request: payload } }, signal ?? new AbortController().signal);
15836
16171
  return {
15837
16172
  rpcId: request.rpcId,
@@ -15915,8 +16250,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
15915
16250
  queue.close();
15916
16251
  }
15917
16252
  }
15918
- broadcastRcMux(payload, rpcId = `codex-mux:${Date.now()}:${Math.random()}`) {
15919
- for (const queue of this.rcMuxStreams) queue.push({ rpcId, payload });
16253
+ broadcastRcMux(payload, rpcId2 = `codex-mux:${Date.now()}:${Math.random()}`) {
16254
+ for (const queue of this.rcMuxStreams) queue.push({ rpcId: rpcId2, payload });
15920
16255
  }
15921
16256
  broadcastRcHost(payload) {
15922
16257
  const frame = { rpcId: `codex-host:${Date.now()}:${Math.random()}`, payload };
@@ -16356,7 +16691,7 @@ function collectImageBlocks(value, output = []) {
16356
16691
  for (const item of value) collectImageBlocks(item, output);
16357
16692
  return output;
16358
16693
  }
16359
- if (!isRecord4(value)) return output;
16694
+ if (!isRecord5(value)) return output;
16360
16695
  if (value.type === "image") output.push(value);
16361
16696
  for (const [key, child] of Object.entries(value)) {
16362
16697
  if (key === "attachment") continue;
@@ -16686,7 +17021,7 @@ function codexPromptInput(content) {
16686
17021
  if (content.length === 0 || content.length > MAX_CODEX_PROMPT_PARTS) return void 0;
16687
17022
  const input2 = [];
16688
17023
  for (const value of content) {
16689
- if (!isRecord4(value)) return void 0;
17024
+ if (!isRecord5(value)) return void 0;
16690
17025
  if (value.type === "text") {
16691
17026
  if (typeof value.text !== "string" || value.text.length === 0 || value.text.length > MAX_CODEX_PROMPT_TEXT) return void 0;
16692
17027
  input2.push({ type: "text", text: value.text });
@@ -16939,12 +17274,12 @@ function errorCode(error) {
16939
17274
  return "code" in error && typeof error.code === "string" ? error.code : void 0;
16940
17275
  }
16941
17276
  function errorDetails(error) {
16942
- return "details" in error && isRecord4(error.details) ? error.details : {};
17277
+ return "details" in error && isRecord5(error.details) ? error.details : {};
16943
17278
  }
16944
17279
  function record2(value) {
16945
- return isRecord4(value) ? value : {};
17280
+ return isRecord5(value) ? value : {};
16946
17281
  }
16947
- function isRecord4(value) {
17282
+ function isRecord5(value) {
16948
17283
  return typeof value === "object" && value !== null && !Array.isArray(value);
16949
17284
  }
16950
17285
  function array(value) {
@@ -17158,7 +17493,7 @@ function normalizeServerUrl(value) {
17158
17493
  }
17159
17494
 
17160
17495
  // src/version.ts
17161
- var PLUGIN_VERSION = "0.4.12";
17496
+ var PLUGIN_VERSION = "0.4.13";
17162
17497
 
17163
17498
  // src/server-api.ts
17164
17499
  var TERMINAL_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f]/u;
@@ -17677,7 +18012,7 @@ var TypertGatewaySwitch = class {
17677
18012
  if (normalized !== void 0) return normalized;
17678
18013
  const source = error instanceof Error ? error : new Error("The Harness Gateway rejected the request.");
17679
18014
  const code = "code" in source && typeof source.code === "string" ? source.code : "internal";
17680
- const details = "details" in source && isRecord5(source.details) ? source.details : {};
18015
+ const details = "details" in source && isRecord6(source.details) ? source.details : {};
17681
18016
  return { code, message: source.message, details };
17682
18017
  }
17683
18018
  };
@@ -17686,7 +18021,7 @@ function requestFromCarrier(endpoint, payload, signal) {
17686
18021
  if (segments.length !== 2 || segments.some((segment) => segment.length === 0)) {
17687
18022
  throw new Error("The Harness Gateway endpoint is invalid.");
17688
18023
  }
17689
- if (!isRecord5(payload) || !isRecord5(payload.args)) {
18024
+ if (!isRecord6(payload) || !isRecord6(payload.args)) {
17690
18025
  throw new Error("The Harness Gateway payload is invalid.");
17691
18026
  }
17692
18027
  return { namespace: segments[0], method: segments[1], args: payload.args, signal };
@@ -17701,7 +18036,7 @@ function isLocalOnlyEndpoint(endpoint) {
17701
18036
  function isRemoteCommandMethod(method) {
17702
18037
  return REMOTE_COMMAND_METHODS.includes(method);
17703
18038
  }
17704
- function isRecord5(value) {
18039
+ function isRecord6(value) {
17705
18040
  return typeof value === "object" && value !== null && !Array.isArray(value);
17706
18041
  }
17707
18042
 
@@ -18805,10 +19140,8 @@ var ClientModeRuntime = class {
18805
19140
  fingerprint: this.identity.fingerprint
18806
19141
  });
18807
19142
  }
18808
- registerControl(connection) {
18809
- return connection.rpc.handle(CONTROL_RPC_PREFIX, (endpoint, payload, signal) => this.handleControl(endpoint, payload, signal), {
18810
- authority: "loopback"
18811
- });
19143
+ registerControl(connection, webServer) {
19144
+ return registerControlRoute(connection, (endpoint, payload, signal) => this.handleControl(endpoint, payload, signal), webServer);
18812
19145
  }
18813
19146
  status() {
18814
19147
  const targetStatus = this.gatewaySwitch.supportsCarrier() ? this.gatewaySwitch.status() : this.proxySwitch?.status() ?? this.gatewaySwitch.status();
@@ -18989,9 +19322,9 @@ var ClientModeRuntime = class {
18989
19322
  async openRemoteWorkspace(targetDeviceId, path, signal) {
18990
19323
  if (path.trim() === "") throw new ClientModeError("INVALID_MESSAGE", "A remote working directory is required.");
18991
19324
  const remote = await this.ensureConnected(targetDeviceId, signal);
18992
- this.assertRemoteCompatible(remote);
19325
+ const transport = this.selectHarnessRemoteTransport(remote);
18993
19326
  let workspace;
18994
- if (remote.features.remoteGateway) {
19327
+ if (transport === "remoteGateway") {
18995
19328
  workspace = await new RemoteTypertGateway2(remote.client).invoke({
18996
19329
  namespace: "workspace",
18997
19330
  method: "create",
@@ -19007,7 +19340,7 @@ var ClientModeRuntime = class {
19007
19340
  workspace = unwrapNativeResult(response);
19008
19341
  }
19009
19342
  await this.closeCodexVirtual();
19010
- this.selectRemoteTarget(remote);
19343
+ this.selectRemoteTarget(remote, transport);
19011
19344
  const workspaceId = workspaceRecordId(workspace.workspace);
19012
19345
  this.pendingWorkspaceSelection = { targetDeviceId: remote.target.deviceId, workspaceId };
19013
19346
  this.logger.info("Remote workspace opened", { targetDeviceId: shortId(remote.target.deviceId) });
@@ -19027,7 +19360,7 @@ var ClientModeRuntime = class {
19027
19360
  if (!remote.features.codex) {
19028
19361
  throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
19029
19362
  }
19030
- this.assertRemoteCompatible(remote);
19363
+ this.assertLocalHarnessCarrierAvailable();
19031
19364
  const virtual = CodexVirtualHarness.remote(remote.client, {
19032
19365
  deviceId: remote.target.deviceId,
19033
19366
  name: remote.target.name
@@ -19060,7 +19393,7 @@ var ClientModeRuntime = class {
19060
19393
  if (!remote.features.codex) {
19061
19394
  throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
19062
19395
  }
19063
- this.assertRemoteCompatible(remote);
19396
+ this.assertLocalHarnessCarrierAvailable();
19064
19397
  const result = record3(await new CodexRemoteClient(remote.client).request("project/create", {
19065
19398
  name: remoteWorkspaceTitle(trimmedPath),
19066
19399
  roots: [{ path: trimmedPath }],
@@ -19148,10 +19481,10 @@ var ClientModeRuntime = class {
19148
19481
  }
19149
19482
  }
19150
19483
  stream.unsubscribe = remote.client.onEvent((event) => {
19151
- if (event.event === "codex.app.frame" && isRecord6(event.data) && event.data.streamId === value.streamId) {
19484
+ if (event.event === "codex.app.frame" && isRecord7(event.data) && event.data.streamId === value.streamId) {
19152
19485
  this.appendCodexFrame(stream, event.data);
19153
19486
  }
19154
- if (event.event === "codex.app.stream.closed" && isRecord6(event.data) && event.data.streamId === value.streamId) {
19487
+ if (event.event === "codex.app.stream.closed" && isRecord7(event.data) && event.data.streamId === value.streamId) {
19155
19488
  stream.closed = typeof event.data.reason === "string" ? event.data.reason : "closed";
19156
19489
  stream.wake();
19157
19490
  }
@@ -19178,7 +19511,7 @@ var ClientModeRuntime = class {
19178
19511
  stream.wake();
19179
19512
  };
19180
19513
  appendCodexFrame(stream, data) {
19181
- if (!isRecord6(data) || !isRecord6(data.frame) || typeof data.frame.method !== "string") return;
19514
+ if (!isRecord7(data) || !isRecord7(data.frame) || typeof data.frame.method !== "string") return;
19182
19515
  if (stream.frames.length >= 256) {
19183
19516
  stream.closed = "overflow";
19184
19517
  } else {
@@ -19235,18 +19568,25 @@ var ClientModeRuntime = class {
19235
19568
  await stream.close();
19236
19569
  }));
19237
19570
  }
19238
- selectRemoteTarget(remote) {
19571
+ selectRemoteTarget(remote, transport = this.selectHarnessRemoteTransport(remote)) {
19239
19572
  const target = { deviceId: remote.target.deviceId, name: remote.target.name };
19240
- if (this.gatewaySwitch.supportsCarrier()) {
19241
- this.gatewaySwitch.selectRemote(new RemoteTypertGateway2(remote.client), void 0, target);
19573
+ if (transport === "remoteGateway") {
19574
+ this.gatewaySwitch.selectRemote(this.remoteTypertGateway(remote), void 0, target);
19242
19575
  return;
19243
19576
  }
19244
- this.proxySwitch.selectRemote(new RemoteHarnessApiProxy(remote.client).api, target);
19577
+ this.proxySwitch?.selectRemote(new RemoteHarnessApiProxy(remote.client).api, target);
19245
19578
  this.gatewaySwitch.selectRemote((request) => invokeRemoteCommand(remote.client, request), {
19246
19579
  execute: true,
19247
19580
  list: remote.features.commandList
19248
19581
  }, target);
19249
19582
  }
19583
+ remoteTypertGateway(remote) {
19584
+ const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
19585
+ return new RemoteTypertGateway2(
19586
+ remote.client,
19587
+ localSessionGeneration === "v3" && remote.features.sessionFormat !== 3 ? "legacy-to-v3" : void 0
19588
+ );
19589
+ }
19250
19590
  selectCodexTarget(virtual, remote) {
19251
19591
  const target = { deviceId: remote.target.deviceId, name: remote.target.name };
19252
19592
  if (this.gatewaySwitch.supportsCarrier()) {
@@ -19262,20 +19602,29 @@ var ClientModeRuntime = class {
19262
19602
  await virtual?.close();
19263
19603
  }
19264
19604
  assertRemoteCompatible(remote) {
19605
+ this.selectHarnessRemoteTransport(remote);
19606
+ }
19607
+ selectHarnessRemoteTransport(remote) {
19265
19608
  const localRemoteGateway = this.gatewaySwitch.supportsCarrier();
19609
+ const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
19266
19610
  if (localRemoteGateway && remote.features.remoteGateway) {
19267
- const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
19268
- const remoteSessionGeneration = remote.features.sessionFormat === 3 ? "v3" : "legacy";
19269
- if (localSessionGeneration === remoteSessionGeneration) return;
19611
+ if (localSessionGeneration === "v3" || remote.features.sessionFormat !== 3) return "remoteGateway";
19270
19612
  throw new ClientModeError(
19271
19613
  "HARNESS_VERSION_INCOMPATIBLE",
19272
- `The local and remote Harness Session formats differ (${localSessionGeneration} vs ${remoteSessionGeneration}).`
19614
+ "The selected Host uses Harness Session V3, but this Client uses the legacy Typert Remote session format."
19273
19615
  );
19274
19616
  }
19275
- if (!localRemoteGateway && this.proxySwitch !== void 0 && remote.features.apiProxy) return;
19617
+ if (this.proxySwitch !== void 0 && remote.features.apiProxy) return "apiProxy";
19276
19618
  throw new ClientModeError(
19277
19619
  "HARNESS_VERSION_INCOMPATIBLE",
19278
- localRemoteGateway ? "The selected Host does not provide the Harness v0.1.2 Typert Remote Gateway transport." : "The selected Host does not provide the legacy Harness ApiProxy transport."
19620
+ localRemoteGateway ? "The selected Host does not provide a compatible Harness Typert Remote Gateway transport." : "The selected Host does not provide the legacy Harness ApiProxy transport."
19621
+ );
19622
+ }
19623
+ assertLocalHarnessCarrierAvailable() {
19624
+ if (this.gatewaySwitch.supportsCarrier() || this.proxySwitch !== void 0) return;
19625
+ throw new ClientModeError(
19626
+ "HARNESS_VERSION_INCOMPATIBLE",
19627
+ "This Client does not provide a compatible Harness carrier for the selected remote workspace."
19279
19628
  );
19280
19629
  }
19281
19630
  async connect(targetDeviceId, signal) {
@@ -19654,20 +20003,20 @@ function record3(value) {
19654
20003
  }
19655
20004
  return value;
19656
20005
  }
19657
- function isRecord6(value) {
20006
+ function isRecord7(value) {
19658
20007
  return typeof value === "object" && value !== null && !Array.isArray(value);
19659
20008
  }
19660
20009
  function ok2(value) {
19661
20010
  return { ok: true, value };
19662
20011
  }
19663
20012
  async function invokeRemoteCommand(client, request) {
19664
- const rpcId = uuidV7();
20013
+ const rpcId2 = uuidV7();
19665
20014
  const response = await client.rpc("harness.api.call", {
19666
20015
  method: `${request.namespace}.${request.method}`,
19667
- rpcId,
20016
+ rpcId: rpcId2,
19668
20017
  payload: request.args
19669
20018
  }, request.signal);
19670
- if (response.rpcId !== rpcId) {
20019
+ if (response.rpcId !== rpcId2) {
19671
20020
  throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid command response.");
19672
20021
  }
19673
20022
  return unwrapNativeResult(response);
@@ -19679,11 +20028,11 @@ async function readRemoteWorkspaceBaseline(gateway, signal) {
19679
20028
  const iterator = source[Symbol.asyncIterator]();
19680
20029
  try {
19681
20030
  const first = await iterator.next();
19682
- if (first.done || !isRecord6(first.value) || first.value.type !== "baseline" || !isRecord6(first.value.value) || !Array.isArray(first.value.value.items)) {
20031
+ if (first.done || !isRecord7(first.value) || first.value.type !== "baseline" || !isRecord7(first.value.value) || !Array.isArray(first.value.value.items)) {
19683
20032
  throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace baseline.");
19684
20033
  }
19685
20034
  return first.value.value.items.map((item) => {
19686
- if (!isRecord6(item) || typeof item.workspaceId !== "string" || typeof item.path !== "string" || typeof item.title !== "string") {
20035
+ if (!isRecord7(item) || typeof item.workspaceId !== "string" || typeof item.path !== "string" || typeof item.title !== "string") {
19687
20036
  throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace row.");
19688
20037
  }
19689
20038
  return { workspaceId: item.workspaceId, path: item.path, title: item.title };
@@ -19748,19 +20097,20 @@ async function probeRemoteHostFeatures(client, clientVersion) {
19748
20097
  if (error instanceof Error && "code" in error && error.code === "METHOD_NOT_FOUND") return fallback;
19749
20098
  throw error;
19750
20099
  }
19751
- if (!isRecord6(value) || !Array.isArray(value.capabilities) || value.capabilities.some((capability) => typeof capability !== "string")) {
20100
+ if (!isRecord7(value) || !Array.isArray(value.capabilities) || value.capabilities.some((capability) => typeof capability !== "string")) {
19752
20101
  throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned invalid transport capabilities.");
19753
20102
  }
19754
20103
  const capabilities = new Set(value.capabilities);
19755
20104
  const apiProxy = capabilities.has("harness.api.v1");
19756
20105
  const remoteV1 = capabilities.has("harness.remote.v1");
19757
20106
  const remoteV3 = capabilities.has("harness.remote.v3");
20107
+ const codex = capabilities.has("codex.appserver.v1");
19758
20108
  if (remoteV1 && remoteV3) {
19759
20109
  throw new ClientModeError("INVALID_MESSAGE", "The remote Host advertised conflicting Harness Session formats.");
19760
20110
  }
19761
20111
  const sessionFormat = remoteV3 ? 3 : void 0;
19762
20112
  const remoteGateway = remoteV3 || remoteV1;
19763
- if (!apiProxy && !remoteGateway) {
20113
+ if (!apiProxy && !remoteGateway && !codex) {
19764
20114
  throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The remote Host exposes no supported Harness transport.");
19765
20115
  }
19766
20116
  return {
@@ -19769,7 +20119,7 @@ async function probeRemoteHostFeatures(client, clientVersion) {
19769
20119
  apiProxy,
19770
20120
  remoteGateway,
19771
20121
  ...sessionFormat === void 0 ? {} : { sessionFormat },
19772
- codex: capabilities.has("codex.appserver.v1")
20122
+ codex
19773
20123
  };
19774
20124
  }
19775
20125
  async function waitForCodexFrames(stream, signal) {
@@ -20086,10 +20436,8 @@ var PluginControlRuntime = class {
20086
20436
  this.client = client;
20087
20437
  this.host = host;
20088
20438
  }
20089
- register(connection) {
20090
- return connection.rpc.handle(CONTROL_RPC_PREFIX, (endpoint, payload, signal) => this.handle(endpoint, payload, signal), {
20091
- authority: "loopback"
20092
- });
20439
+ register(connection, webServer) {
20440
+ return registerControlRoute(connection, (endpoint, payload, signal) => this.handle(endpoint, payload, signal), webServer);
20093
20441
  }
20094
20442
  async handle(endpoint, payload, signal) {
20095
20443
  try {
@@ -20303,11 +20651,11 @@ function editableConfig(config) {
20303
20651
  }
20304
20652
  };
20305
20653
  }
20306
- function isRecord7(value) {
20654
+ function isRecord8(value) {
20307
20655
  return typeof value === "object" && value !== null && !Array.isArray(value);
20308
20656
  }
20309
20657
  function record4(value) {
20310
- if (!isRecord7(value)) throw new ClientModeError("INVALID_MESSAGE", "The control request payload is invalid.");
20658
+ if (!isRecord8(value)) throw new ClientModeError("INVALID_MESSAGE", "The control request payload is invalid.");
20311
20659
  return value;
20312
20660
  }
20313
20661
  function ok3(value) {
@@ -20628,7 +20976,7 @@ var RpcRouter = class {
20628
20976
  });
20629
20977
  return createRpcResponse(request.id, result);
20630
20978
  } catch (error) {
20631
- const response = errorResponse(request.id, error);
20979
+ const response = errorResponse2(request.id, error);
20632
20980
  this.logger?.warn("host rpc failed", {
20633
20981
  method: request.payload.method,
20634
20982
  durationMs: Math.round(performance.now() - startedAt),
@@ -20727,7 +21075,7 @@ var RpcRouter = class {
20727
21075
  return this.codex;
20728
21076
  }
20729
21077
  };
20730
- function errorResponse(requestId, error) {
21078
+ function errorResponse2(requestId, error) {
20731
21079
  const code = safeErrorCode(error);
20732
21080
  if (error instanceof RpcError) return createRpcError(requestId, code, error.message, error.details, error.retryable);
20733
21081
  return createRpcError(
@@ -21920,8 +22268,8 @@ var HARNESS_API_ALLOWLIST = [
21920
22268
  "credentials.unset"
21921
22269
  ];
21922
22270
  var NATIVE_CALL_TIMEOUT_MS = 3e4;
21923
- var MAX_ACTIVE_API_TRANSFERS = 2;
21924
- var API_TRANSFER_IDLE_MS = 2 * 6e4;
22271
+ var MAX_ACTIVE_API_TRANSFERS = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
22272
+ var API_TRANSFER_IDLE_MS = TRANSFER_IDLE_MS;
21925
22273
  var INLINE_TRANSFER_RESPONSE_BYTES = 2 * 1024 * 1024;
21926
22274
  var SESSION_HISTORY_PAGE_SIZES = [50, 30, 20, 12, 6, 3, 1];
21927
22275
  var HarnessApiBridge = class {
@@ -21998,9 +22346,9 @@ var HarnessApiBridge = class {
21998
22346
  const value = await listRemoteDirectory(payload.path, signal);
21999
22347
  return { rpcId: params.rpcId, result: { ok: true, value } };
22000
22348
  }
22001
- describeFallback(rpcId) {
22349
+ describeFallback(rpcId2) {
22002
22350
  return {
22003
- rpcId,
22351
+ rpcId: rpcId2,
22004
22352
  result: {
22005
22353
  ok: true,
22006
22354
  value: {
@@ -22218,8 +22566,8 @@ var HarnessApiBridge = class {
22218
22566
  }
22219
22567
  }
22220
22568
  deleteRespondable(value) {
22221
- for (const [rpcId, correlation] of this.respondable) {
22222
- if (correlation === value) this.respondable.delete(rpcId);
22569
+ for (const [rpcId2, correlation] of this.respondable) {
22570
+ if (correlation === value) this.respondable.delete(rpcId2);
22223
22571
  }
22224
22572
  }
22225
22573
  };
@@ -22406,9 +22754,9 @@ function sanitizeModelDiscoveryResponse(response, settingsNs) {
22406
22754
  if (typeof result === "object" && result !== null && "ok" in result && result.ok === true) return response;
22407
22755
  return modelDiscoveryFailure(response.rpcId, settingsNs);
22408
22756
  }
22409
- function modelDiscoveryFailure(rpcId, settingsNs) {
22757
+ function modelDiscoveryFailure(rpcId2, settingsNs) {
22410
22758
  return {
22411
- rpcId,
22759
+ rpcId: rpcId2,
22412
22760
  result: {
22413
22761
  ok: false,
22414
22762
  error: {
@@ -22468,15 +22816,15 @@ function frameSessionId(frame) {
22468
22816
  const payload = frame.payload;
22469
22817
  return typeof payload.sessionId === "string" && payload.sessionId.length > 0 ? payload.sessionId : void 0;
22470
22818
  }
22471
- function callSessionHistory(callWithTimeout, payload, rpcId) {
22819
+ function callSessionHistory(callWithTimeout, payload, rpcId2) {
22472
22820
  const fallbackPageSizes = sessionHistoryFallbackPageSizes(payloadMaxMessages(payload));
22473
- return callHistoryWithRetry(callWithTimeout, payload, rpcId, fallbackPageSizes);
22821
+ return callHistoryWithRetry(callWithTimeout, payload, rpcId2, fallbackPageSizes);
22474
22822
  }
22475
- async function callHistoryWithRetry(callWithTimeout, payload, rpcId, pageSizes) {
22823
+ async function callHistoryWithRetry(callWithTimeout, payload, rpcId2, pageSizes) {
22476
22824
  for (const maxMessages of pageSizes) {
22477
22825
  const requestPayload = historyRequestPayload(payload, maxMessages);
22478
22826
  const response = await callWithTimeout(requestPayload);
22479
- const request = createRpcResponse(rpcId, response.result);
22827
+ const request = createRpcResponse(rpcId2, response.result);
22480
22828
  if (encodeMessage(request).byteLength <= MAX_SECURE_MESSAGE_BYTES) return response;
22481
22829
  if (maxMessages === pageSizes[pageSizes.length - 1]) {
22482
22830
  throw new RpcError(
@@ -22582,9 +22930,8 @@ var transferReadSchema2 = external_exports.object({
22582
22930
  var directoryListSchema2 = external_exports.object({
22583
22931
  path: external_exports.string().min(1).max(4096).optional()
22584
22932
  }).strict();
22585
- var MAX_ACTIVE_STREAMS = 16;
22586
- var MAX_ACTIVE_TRANSFERS = 2;
22587
- var TRANSFER_IDLE_MS = 2 * 6e4;
22933
+ var MAX_ACTIVE_STREAMS = MAX_ALPHA_STREAMS_PER_CONNECTION;
22934
+ var MAX_ACTIVE_TRANSFERS = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
22588
22935
  var INLINE_TRANSFER_RESPONSE_BYTES2 = 2 * 1024 * 1024;
22589
22936
  var HARNESS_REMOTE_ALLOWLIST = [
22590
22937
  "$events",
@@ -22884,13 +23231,13 @@ function needsDirectoryFallback(result) {
22884
23231
  }
22885
23232
  function requestArgs(payload) {
22886
23233
  const root = record5(payload);
22887
- const args = isRecord8(root.args) ? root.args : root;
23234
+ const args = isRecord9(root.args) ? root.args : root;
22888
23235
  return record5(args.request ?? args._request ?? args);
22889
23236
  }
22890
23237
  function record5(value) {
22891
- return isRecord8(value) ? value : {};
23238
+ return isRecord9(value) ? value : {};
22892
23239
  }
22893
- function isRecord8(value) {
23240
+ function isRecord9(value) {
22894
23241
  return typeof value === "object" && value !== null && !Array.isArray(value);
22895
23242
  }
22896
23243
 
@@ -23084,7 +23431,7 @@ var CodexAppServerClient = class {
23084
23431
  this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted invalid JSON."));
23085
23432
  return;
23086
23433
  }
23087
- if (!isRecord9(value)) {
23434
+ if (!isRecord10(value)) {
23088
23435
  this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted an invalid message."));
23089
23436
  return;
23090
23437
  }
@@ -23129,12 +23476,12 @@ var CodexAppServerClient = class {
23129
23476
  }
23130
23477
  };
23131
23478
  function safeUpstreamError(value) {
23132
- if (!isRecord9(value) || typeof value.message !== "string") return "Codex App Server rejected the request.";
23479
+ if (!isRecord10(value) || typeof value.message !== "string") return "Codex App Server rejected the request.";
23133
23480
  const message = value.message.toLowerCase();
23134
23481
  if (message.includes("active writer")) return "Codex thread already has an active writer.";
23135
23482
  return message.includes("not initialized") ? "Codex App Server is not initialized." : "Codex App Server rejected the request.";
23136
23483
  }
23137
- function isRecord9(value) {
23484
+ function isRecord10(value) {
23138
23485
  return typeof value === "object" && value !== null && !Array.isArray(value);
23139
23486
  }
23140
23487
 
@@ -23266,9 +23613,8 @@ var transferChunkSchema3 = external_exports.object({
23266
23613
  }).strict();
23267
23614
  var transferIdSchema3 = external_exports.object({ transferId: external_exports.string().uuid() }).strict();
23268
23615
  var transferReadSchema3 = external_exports.object({ transferId: external_exports.string().uuid(), index: external_exports.number().int().nonnegative() }).strict();
23269
- var MAX_ACTIVE_STREAMS2 = 16;
23270
- var MAX_ACTIVE_TRANSFERS2 = 2;
23271
- var TRANSFER_IDLE_MS2 = 2 * 6e4;
23616
+ var MAX_ACTIVE_STREAMS2 = MAX_ALPHA_STREAMS_PER_CONNECTION;
23617
+ var MAX_ACTIVE_TRANSFERS2 = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
23272
23618
  var INLINE_TRANSFER_RESPONSE_BYTES3 = 2 * 1024 * 1024;
23273
23619
  var CodexPeerBridge = class {
23274
23620
  constructor(domain, context, publish, logger) {
@@ -23482,7 +23828,7 @@ var CodexPeerBridge = class {
23482
23828
  await this.domain.detachPeer(this.context.connectionId);
23483
23829
  }
23484
23830
  pruneTransfers() {
23485
- const staleBefore = Date.now() - TRANSFER_IDLE_MS2;
23831
+ const staleBefore = Date.now() - TRANSFER_IDLE_MS;
23486
23832
  for (const [id2, transfer] of this.incomingTransfers) {
23487
23833
  if (transfer.touchedAt < staleBefore) this.incomingTransfers.delete(id2);
23488
23834
  }
@@ -23504,15 +23850,15 @@ function decodeCanonicalBase643(value) {
23504
23850
  }
23505
23851
  return decoded;
23506
23852
  }
23507
- function isRecord10(value) {
23853
+ function isRecord11(value) {
23508
23854
  return typeof value === "object" && value !== null && !Array.isArray(value);
23509
23855
  }
23510
23856
  function safeErrorCode2(error) {
23511
- if (isRecord10(error) && typeof error.code === "string") return error.code;
23857
+ if (isRecord11(error) && typeof error.code === "string") return error.code;
23512
23858
  return "UNKNOWN";
23513
23859
  }
23514
23860
  function safeMethod(input2) {
23515
- return isRecord10(input2) && typeof input2.method === "string" ? input2.method : "invalid";
23861
+ return isRecord11(input2) && typeof input2.method === "string" ? input2.method : "invalid";
23516
23862
  }
23517
23863
  function concatChunks3(chunks, totalBytes) {
23518
23864
  const output = new Uint8Array(totalBytes);
@@ -23929,14 +24275,14 @@ var CodexRemoteDomain = class {
23929
24275
  await this.assertResultThreadAllowed(result);
23930
24276
  if (codexPermissionPresetFromResponse(result) !== params.permissionPreset) {
23931
24277
  await this.callUpstream("thread/settings/update", { threadId, ...settings });
23932
- result = { ...isRecord11(result) ? result : {}, ...settings, sandbox: settings.sandboxPolicy };
24278
+ result = { ...isRecord12(result) ? result : {}, ...settings, sandbox: settings.sandboxPolicy };
23933
24279
  }
23934
24280
  }
23935
24281
  await this.publishPermission(threadId, result);
23936
24282
  return result;
23937
24283
  }
23938
24284
  async publishPermission(threadId, value) {
23939
- const source = isRecord11(value) ? value : {};
24285
+ const source = isRecord12(value) ? value : {};
23940
24286
  const threadSettings = { approvalPolicy: source.approvalPolicy, sandboxPolicy: source.sandboxPolicy ?? source.sandbox };
23941
24287
  await this.handleInbound({ kind: "notification", method: "thread/settings/updated", params: { threadId, threadSettings } });
23942
24288
  }
@@ -24032,9 +24378,9 @@ var CodexRemoteDomain = class {
24032
24378
  itemsView,
24033
24379
  ...cursor2 === void 0 ? {} : { cursor: cursor2 }
24034
24380
  });
24035
- const pageResult = isRecord11(result) ? result : {};
24381
+ const pageResult = isRecord12(result) ? result : {};
24036
24382
  for (const rawTurn of array2(pageResult.data)) {
24037
- if (!isRecord11(rawTurn)) continue;
24383
+ if (!isRecord12(rawTurn)) continue;
24038
24384
  const turnId = typeof rawTurn.id === "string" ? rawTurn.id : void 0;
24039
24385
  const items = rawTurn.itemsView === "full" || turnId === void 0 ? array2(rawTurn.items) : await this.readThreadItems(connectionId, threadId, turnId, array2(rawTurn.items));
24040
24386
  turns.push({ ...rawTurn, items });
@@ -24056,9 +24402,9 @@ var CodexRemoteDomain = class {
24056
24402
  sortDirection: "asc",
24057
24403
  ...cursor2 === void 0 ? {} : { cursor: cursor2 }
24058
24404
  });
24059
- const pageResult = isRecord11(result) ? result : {};
24405
+ const pageResult = isRecord12(result) ? result : {};
24060
24406
  for (const entry of array2(pageResult.data)) {
24061
- if (isRecord11(entry) && entry.item !== void 0) items.push(entry.item);
24407
+ if (isRecord12(entry) && entry.item !== void 0) items.push(entry.item);
24062
24408
  }
24063
24409
  cursor2 = typeof pageResult.nextCursor === "string" && pageResult.nextCursor.length > 0 ? pageResult.nextCursor : void 0;
24064
24410
  if (cursor2 === void 0) break;
@@ -24122,7 +24468,7 @@ var CodexRemoteDomain = class {
24122
24468
  return [...this.peers.values()].some((peer) => peer.hasThreadSubscription(threadId));
24123
24469
  }
24124
24470
  resolveUpstreamApproval(params) {
24125
- if (!isRecord11(params) || typeof params.requestId !== "string" && typeof params.requestId !== "number") return;
24471
+ if (!isRecord12(params) || typeof params.requestId !== "string" && typeof params.requestId !== "number") return;
24126
24472
  for (const [handle, approval] of this.approvals) {
24127
24473
  if (approval.upstreamId === params.requestId) this.approvals.delete(handle);
24128
24474
  }
@@ -24339,24 +24685,24 @@ function codexBinaryCandidates(configured, hostPlatform = process.platform, user
24339
24685
  ])];
24340
24686
  }
24341
24687
  function parseCallEnvelope(input2) {
24342
- if (!isRecord11(input2) || typeof input2.method !== "string" || !("params" in input2) || Object.keys(input2).some((key) => key !== "method" && key !== "params")) {
24688
+ if (!isRecord12(input2) || typeof input2.method !== "string" || !("params" in input2) || Object.keys(input2).some((key) => key !== "method" && key !== "params")) {
24343
24689
  throw new RpcError("INVALID_MESSAGE", "The Codex call envelope is invalid.");
24344
24690
  }
24345
24691
  return { method: input2.method, params: input2.params };
24346
24692
  }
24347
24693
  function parseRespond(input2) {
24348
- if (!isRecord11(input2) || typeof input2.requestHandle !== "string" || !["accept", "decline", "cancel"].includes(String(input2.decision)) || Object.keys(input2).some((key) => key !== "requestHandle" && key !== "decision")) {
24694
+ if (!isRecord12(input2) || typeof input2.requestHandle !== "string" || !["accept", "decline", "cancel"].includes(String(input2.decision)) || Object.keys(input2).some((key) => key !== "requestHandle" && key !== "decision")) {
24349
24695
  throw new RpcError("INVALID_MESSAGE", "The Codex approval response is invalid.");
24350
24696
  }
24351
24697
  return input2;
24352
24698
  }
24353
24699
  function accountCanRun(result) {
24354
- if (!isRecord11(result) || typeof result.requiresOpenaiAuth !== "boolean") return false;
24355
- return result.requiresOpenaiAuth === false || isRecord11(result.account);
24700
+ if (!isRecord12(result) || typeof result.requiresOpenaiAuth !== "boolean") return false;
24701
+ return result.requiresOpenaiAuth === false || isRecord12(result.account);
24356
24702
  }
24357
24703
  function sanitizeAccount(result) {
24358
- if (!isRecord11(result)) throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned invalid account state.");
24359
- const account = isRecord11(result.account) ? result.account : void 0;
24704
+ if (!isRecord12(result)) throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned invalid account state.");
24705
+ const account = isRecord12(result.account) ? result.account : void 0;
24360
24706
  return {
24361
24707
  authenticated: account !== void 0 || result.requiresOpenaiAuth === false,
24362
24708
  requiresOpenaiAuth: result.requiresOpenaiAuth === true,
@@ -24369,11 +24715,11 @@ function sanitizeAccount(result) {
24369
24715
  };
24370
24716
  }
24371
24717
  function sanitizeThreadList(result) {
24372
- if (!isRecord11(result) || !Array.isArray(result.data)) {
24718
+ if (!isRecord12(result) || !Array.isArray(result.data)) {
24373
24719
  throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
24374
24720
  }
24375
24721
  const data = result.data.flatMap((value) => {
24376
- if (!isRecord11(value) || typeof value.id !== "string") return [];
24722
+ if (!isRecord12(value) || typeof value.id !== "string") return [];
24377
24723
  return [{
24378
24724
  id: value.id,
24379
24725
  ...typeof value.sessionId === "string" ? { sessionId: value.sessionId } : {},
@@ -24385,7 +24731,7 @@ function sanitizeThreadList(result) {
24385
24731
  ...typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) ? { updatedAt: value.updatedAt } : {},
24386
24732
  ...typeof value.archived === "boolean" ? { archived: value.archived } : {},
24387
24733
  ...typeof value.isPinned === "boolean" ? { isPinned: value.isPinned } : {},
24388
- ...isRecord11(value.status) ? { status: value.status } : {}
24734
+ ...isRecord12(value.status) ? { status: value.status } : {}
24389
24735
  }];
24390
24736
  });
24391
24737
  return {
@@ -24395,18 +24741,18 @@ function sanitizeThreadList(result) {
24395
24741
  };
24396
24742
  }
24397
24743
  function filterThreadListByWorkspaceAuthority(result, authority) {
24398
- if (!isRecord11(result) || !Array.isArray(result.data)) {
24744
+ if (!isRecord12(result) || !Array.isArray(result.data)) {
24399
24745
  throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
24400
24746
  }
24401
24747
  return {
24402
24748
  ...result,
24403
- data: result.data.map((record6) => isRecord11(record6) ? record6 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
24749
+ data: result.data.map((record6) => isRecord12(record6) ? record6 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
24404
24750
  };
24405
24751
  }
24406
24752
  function sanitizeProject(value) {
24407
- if (!isRecord11(value) || typeof value.id !== "string" || typeof value.name !== "string") return void 0;
24753
+ if (!isRecord12(value) || typeof value.id !== "string" || typeof value.name !== "string") return void 0;
24408
24754
  const roots = Array.isArray(value.roots) ? value.roots.flatMap((root) => {
24409
- const path = isRecord11(root) && typeof root.path === "string" && root.path.length > 0 ? root.path : void 0;
24755
+ const path = isRecord12(root) && typeof root.path === "string" && root.path.length > 0 ? root.path : void 0;
24410
24756
  return path === void 0 || !isAbsolute3(path) ? [] : [{ path }];
24411
24757
  }) : [];
24412
24758
  if (roots.length === 0) return void 0;
@@ -24420,7 +24766,7 @@ function sanitizeProject(value) {
24420
24766
  };
24421
24767
  }
24422
24768
  function sanitizeProjectList(result) {
24423
- if (!isRecord11(result) || !Array.isArray(result.data)) {
24769
+ if (!isRecord12(result) || !Array.isArray(result.data)) {
24424
24770
  throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid project list.");
24425
24771
  }
24426
24772
  const data = result.data.flatMap((value) => sanitizeProject(value) ?? []);
@@ -24430,7 +24776,7 @@ function sanitizeProjectList(result) {
24430
24776
  };
24431
24777
  }
24432
24778
  function sanitizeProjectCreate(result) {
24433
- const project = isRecord11(result) ? sanitizeProject(result.project) : void 0;
24779
+ const project = isRecord12(result) ? sanitizeProject(result.project) : void 0;
24434
24780
  if (project === void 0) {
24435
24781
  throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid created project.");
24436
24782
  }
@@ -24462,19 +24808,19 @@ function codexDirectoryCrumbs(root, path) {
24462
24808
  return crumbs2;
24463
24809
  }
24464
24810
  function extractThread(result) {
24465
- return isRecord11(result) && isRecord11(result.thread) ? result.thread : void 0;
24811
+ return isRecord12(result) && isRecord12(result.thread) ? result.thread : void 0;
24466
24812
  }
24467
24813
  function extractTurnId(result) {
24468
- if (!isRecord11(result)) return void 0;
24814
+ if (!isRecord12(result)) return void 0;
24469
24815
  if (typeof result.turnId === "string" && result.turnId.length > 0) return result.turnId;
24470
- if (isRecord11(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
24816
+ if (isRecord12(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
24471
24817
  return void 0;
24472
24818
  }
24473
24819
  function extractThreadId(params) {
24474
- if (!isRecord11(params)) return void 0;
24820
+ if (!isRecord12(params)) return void 0;
24475
24821
  if (typeof params.threadId === "string") return params.threadId;
24476
- if (isRecord11(params.thread) && typeof params.thread.id === "string") return params.thread.id;
24477
- if (isRecord11(params.turn) && typeof params.turn.threadId === "string") return params.turn.threadId;
24822
+ if (isRecord12(params.thread) && typeof params.thread.id === "string") return params.thread.id;
24823
+ if (isRecord12(params.turn) && typeof params.turn.threadId === "string") return params.turn.threadId;
24478
24824
  return void 0;
24479
24825
  }
24480
24826
  function optionalInteger2(value) {
@@ -24516,13 +24862,13 @@ function mapCodexImageInputs(params) {
24516
24862
  return {
24517
24863
  ...params,
24518
24864
  input: params.input.map((value) => {
24519
- if (!isRecord11(value) || value.type !== "image" || typeof value.mediaType !== "string" || typeof value.data !== "string") return value;
24865
+ if (!isRecord12(value) || value.type !== "image" || typeof value.mediaType !== "string" || typeof value.data !== "string") return value;
24520
24866
  return { type: "image", url: `data:${value.mediaType};base64,${value.data}` };
24521
24867
  })
24522
24868
  };
24523
24869
  }
24524
24870
  function sanitizeApprovalParams(params, requestHandle) {
24525
- if (!isRecord11(params)) return { requestHandle };
24871
+ if (!isRecord12(params)) return { requestHandle };
24526
24872
  const safe = { ...params };
24527
24873
  delete safe.proposedExecpolicyAmendment;
24528
24874
  delete safe.additionalPermissions;
@@ -24553,7 +24899,7 @@ function isProjectListFallbackError(error) {
24553
24899
  function canTryNextBinary(error) {
24554
24900
  return !(error instanceof RpcError) || !["CODEX_AUTH_REQUIRED", "CODEX_CLOSED"].includes(error.code);
24555
24901
  }
24556
- function isRecord11(value) {
24902
+ function isRecord12(value) {
24557
24903
  return typeof value === "object" && value !== null && !Array.isArray(value);
24558
24904
  }
24559
24905
  function array2(value) {
@@ -24838,7 +25184,8 @@ var HostPluginRuntime = class {
24838
25184
  harnessSessionGeneration(this.harnessVersion) === "v3" ? "harness.remote.v3" : "harness.remote.v1",
24839
25185
  "harness.remote.transfer.v1"
24840
25186
  );
24841
- } else if (this.apiProxy !== void 0) {
25187
+ }
25188
+ if (this.apiProxy !== void 0) {
24842
25189
  capabilities.push("harness.api.v1", "harness.api.transfer.v1");
24843
25190
  }
24844
25191
  if (this.fileViewerHost?.() !== void 0) capabilities.push("fileviewer.read.v1");
@@ -25293,7 +25640,7 @@ function remoteStatusLines(target) {
25293
25640
  `Device: ${status2.deviceId ?? "not initialized"}`,
25294
25641
  `Authorization: ${status2.authorized ? status2.account === void 0 ? "logged in" : `logged in (${status2.account})` : "logged out"}`,
25295
25642
  `Server connection: ${connection}`,
25296
- `Harness Remote API: ${capabilities.has("harness.api.v1") ? "available (ApiProxy)" : capabilities.has("harness.remote.v1") ? "available (Typert Remote)" : "unavailable"}`,
25643
+ `Harness Remote API: ${capabilities.has("harness.api.v1") ? "available (ApiProxy)" : capabilities.has("harness.remote.v3") ? "available (Typert Remote Session V3)" : capabilities.has("harness.remote.v1") ? "available (Typert Remote)" : "unavailable"}`,
25297
25644
  `Remote clients: ${diagnostics.activeConnections}`,
25298
25645
  `Codex Remote: ${codex.enabled ? codex.state : "disabled"}`,
25299
25646
  "",
@@ -25566,6 +25913,7 @@ function apply(ctx, input2 = {}) {
25566
25913
  const activateWhenCarrierReady = (runtimeContext) => {
25567
25914
  const gateway = runtimeContext.get("typertGateway");
25568
25915
  const connection = runtimeContext.get("connection");
25916
+ const webServer = runtimeContext.get("webServer");
25569
25917
  let disposePendingControl;
25570
25918
  const installPendingControl = () => {
25571
25919
  if (connection === void 0 || disposePendingControl !== void 0) return;
@@ -25577,7 +25925,7 @@ function apply(ctx, input2 = {}) {
25577
25925
  void 0,
25578
25926
  void 0
25579
25927
  );
25580
- return control.register(connection);
25928
+ return control.register(connection, webServer);
25581
25929
  }, "dsh-remote pending control");
25582
25930
  };
25583
25931
  const startActiveRuntime = async (activeContext) => {
@@ -25611,13 +25959,14 @@ async function activate(ctx, input2, tuiBinding) {
25611
25959
  reportSettingsMigration(ctx, await migration);
25612
25960
  }
25613
25961
  const connection = ctx.get("connection");
25962
+ const webServer = ctx.get("webServer");
25614
25963
  const resolvedConfig = resolveConfig(settingsScope?.get() ?? input2);
25615
25964
  const config = connection === void 0 && resolvedConfig.serverUrl === void 0 ? { ...resolvedConfig, serverUrl: DEFAULT_REMOTE_SERVER_URL } : resolvedConfig;
25616
25965
  const defaultIdentityDirectory = new IdentityStore().directory;
25617
25966
  if (!config.enabled) {
25618
25967
  if (connection !== void 0) {
25619
25968
  const controlRuntime2 = new PluginControlRuntime(config, defaultIdentityDirectory, settingsScope, void 0, void 0);
25620
- ctx.effect(() => controlRuntime2.register(connection), "dsh-remote disabled control");
25969
+ ctx.effect(() => controlRuntime2.register(connection, webServer), "dsh-remote disabled control");
25621
25970
  }
25622
25971
  return;
25623
25972
  }
@@ -25676,7 +26025,7 @@ async function activate(ctx, input2, tuiBinding) {
25676
26025
  if (tuiBinding !== void 0) tuiBinding.target = tuiTarget;
25677
26026
  await disableLegacyLoaderEntries(ctx, logger);
25678
26027
  await ctx.effect(async () => {
25679
- const disposeControl = controlRuntime?.register(connection);
26028
+ const disposeControl = controlRuntime?.register(connection, webServer);
25680
26029
  try {
25681
26030
  await runtime.start();
25682
26031
  if (clientRuntime !== void 0) {