@codexhost/cli-darwin-x64 0.16.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +4 -1
- package/app/console-web.js +4 -1
- package/app/desktop-controller.mjs +499 -24
- package/app/host-runtime.mjs +1292 -504
- package/app/plugins/antigravity/plugin.mjs +4 -1
- package/app/plugins/claude-code/plugin.mjs +4 -1
- package/app/plugins/codebuddy/plugin.mjs +4 -1
- package/app/plugins/codex-usage/plugin.mjs +4 -1
- package/app/plugins/copilot/plugin.mjs +4 -1
- package/app/plugins/cursor-cli/plugin.mjs +4 -1
- package/app/plugins/deepseek-harness/plugin.mjs +4 -1
- package/app/plugins/grok/plugin.mjs +4 -1
- package/app/plugins/hermes/plugin.mjs +4 -1
- package/app/plugins/kimi-code/plugin.mjs +4 -1
- package/app/plugins/kiro-cli/plugin.mjs +4 -1
- package/app/plugins/omp/plugin.mjs +4 -1
- package/app/plugins/opencode/plugin.mjs +4 -1
- package/app/plugins/pi/plugin.mjs +4 -1
- package/app/plugins/qoder/plugin.mjs +4 -1
- package/app/plugins/qoder-cn/plugin.mjs +4 -1
- package/app/plugins/workbuddy/plugin.mjs +4 -1
- package/app/plugins/zcode/plugin.mjs +4 -1
- package/app/renderer-extension.js +348 -60
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
package/app/host-runtime.mjs
CHANGED
|
@@ -21027,7 +21027,10 @@ var harnessPluginRouteSchema = external_exports.object({
|
|
|
21027
21027
|
harnessId: harnessPluginIdSchema,
|
|
21028
21028
|
model: harnessModelRefSchema.optional(),
|
|
21029
21029
|
thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
|
|
21030
|
-
permissionModeId: harnessPermissionModeIdSchema.optional()
|
|
21030
|
+
permissionModeId: harnessPermissionModeIdSchema.optional(),
|
|
21031
|
+
/** A draft prewarm create: stays unsubmitted until the user's first Turn.
|
|
21032
|
+
* Desktop forwards only the Model of a main-process prewarm to thread/start. */
|
|
21033
|
+
prewarm: external_exports.literal(true).optional()
|
|
21031
21034
|
}).strict();
|
|
21032
21035
|
function encodeHarnessPluginRoute(route) {
|
|
21033
21036
|
const parsed2 = harnessPluginRouteSchema.parse(route);
|
|
@@ -22499,22 +22502,22 @@ function retainRendererHostResponses(client, hostId2, target) {
|
|
|
22499
22502
|
|
|
22500
22503
|
// packages/desktop-control/dist/renderer-prewarm-consumption.js
|
|
22501
22504
|
function isolateRendererPrewarmConsumption(manager, discardExternal) {
|
|
22502
|
-
const
|
|
22503
|
-
if (!
|
|
22505
|
+
const record5 = (value2) => value2 !== null && typeof value2 === "object";
|
|
22506
|
+
if (!record5(manager) || !record5(manager.threadCreation))
|
|
22504
22507
|
return null;
|
|
22505
22508
|
const creation = manager.threadCreation;
|
|
22506
22509
|
const originalStart = manager.startConversation;
|
|
22507
22510
|
const original = creation.createConversation;
|
|
22508
22511
|
const params = creation.params;
|
|
22509
|
-
if (typeof originalStart !== "function" || typeof original !== "function" || !
|
|
22512
|
+
if (typeof originalStart !== "function" || typeof original !== "function" || !record5(params))
|
|
22510
22513
|
return null;
|
|
22511
22514
|
const prototype = Object.getPrototypeOf(creation);
|
|
22512
|
-
if (!
|
|
22515
|
+
if (!record5(prototype) || typeof prototype.constructor !== "function")
|
|
22513
22516
|
return null;
|
|
22514
22517
|
if (Object.keys(creation).some((key) => key !== "params" && typeof creation[key] !== "function") || /#[A-Za-z_$]/u.test(Function.prototype.toString.call(prototype.constructor)))
|
|
22515
22518
|
return null;
|
|
22516
22519
|
const pool = params.prewarmedThreadManager;
|
|
22517
|
-
if (!
|
|
22520
|
+
if (!record5(pool) || typeof pool.hasPrewarmedThread !== "function" || typeof pool.consumePrewarmedThread !== "function" || typeof pool.deletePrewarmedThread !== "function")
|
|
22518
22521
|
return null;
|
|
22519
22522
|
const consume = pool.consumePrewarmedThread;
|
|
22520
22523
|
const hasPrewarm = pool.hasPrewarmedThread;
|
|
@@ -22522,15 +22525,15 @@ function isolateRendererPrewarmConsumption(manager, discardExternal) {
|
|
|
22522
22525
|
const draftIdentity = /* @__PURE__ */ Symbol("codexhost draft creation");
|
|
22523
22526
|
const external = (model2) => typeof model2 === "string" && model2.startsWith("codexhost/");
|
|
22524
22527
|
const routedStart = function(input, options2, ...args) {
|
|
22525
|
-
const draftId =
|
|
22526
|
-
const mode =
|
|
22528
|
+
const draftId = record5(options2) ? options2.clientThreadId : null;
|
|
22529
|
+
const mode = record5(input) && record5(input.collaborationMode) ? input.collaborationMode : null;
|
|
22527
22530
|
const origin = mode ? Reflect.get(mode, draftIdentity) : void 0;
|
|
22528
|
-
if (mode &&
|
|
22531
|
+
if (mode && record5(mode.settings) && external(mode.settings.model))
|
|
22529
22532
|
return originalStart.call(this, input, options2, ...args);
|
|
22530
22533
|
const model2 = (typeof draftId === "string" ? draftModels.get(draftId) : void 0) ?? (typeof origin === "string" ? draftModels.get(origin) : void 0);
|
|
22531
22534
|
if (!model2)
|
|
22532
22535
|
return originalStart.call(this, input, options2, ...args);
|
|
22533
|
-
if (!
|
|
22536
|
+
if (!record5(input) || !record5(input.collaborationMode) || !record5(input.collaborationMode.settings))
|
|
22534
22537
|
throw new Error("External draft creation is missing its native Model settings");
|
|
22535
22538
|
const routed = {
|
|
22536
22539
|
...input,
|
|
@@ -22542,20 +22545,20 @@ function isolateRendererPrewarmConsumption(manager, discardExternal) {
|
|
|
22542
22545
|
return originalStart.call(this, routed, options2, ...args);
|
|
22543
22546
|
};
|
|
22544
22547
|
const wrapped = function(input, ...args) {
|
|
22545
|
-
const mode =
|
|
22546
|
-
const expected = mode &&
|
|
22548
|
+
const mode = record5(input) && record5(input.collaborationMode) ? input.collaborationMode : null;
|
|
22549
|
+
const expected = mode && record5(mode.settings) ? mode.settings.model : null;
|
|
22547
22550
|
const scopedPool = Object.create(pool);
|
|
22548
22551
|
scopedPool.hasPrewarmedThread = (...parameters) => hasPrewarm.apply(pool, parameters);
|
|
22549
22552
|
scopedPool.consumePrewarmedThread = async (...consumeArgs) => {
|
|
22550
22553
|
const warmed = await consume.apply(pool, consumeArgs);
|
|
22551
|
-
if (!
|
|
22554
|
+
if (!record5(warmed) || !record5(warmed.response))
|
|
22552
22555
|
return warmed;
|
|
22553
22556
|
const response = warmed.response;
|
|
22554
22557
|
if (!external(expected) && !external(response.model))
|
|
22555
22558
|
return warmed;
|
|
22556
22559
|
if (external(expected) && expected === response.model)
|
|
22557
22560
|
return warmed;
|
|
22558
|
-
if (
|
|
22561
|
+
if (record5(response.thread) && typeof response.thread.id === "string") {
|
|
22559
22562
|
const threadId2 = response.thread.id;
|
|
22560
22563
|
if (external(response.model))
|
|
22561
22564
|
discardExternal(threadId2);
|
|
@@ -23175,14 +23178,14 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
23175
23178
|
|
|
23176
23179
|
// packages/desktop-control/dist/renderer-host-discovery.js
|
|
23177
23180
|
function requestManagerFromHookState(value2, hostId2) {
|
|
23178
|
-
const
|
|
23181
|
+
const record5 = (candidate) => typeof candidate === "object" && candidate !== null;
|
|
23179
23182
|
const manager = (candidate) => {
|
|
23180
|
-
if (!
|
|
23183
|
+
if (!record5(candidate) || !record5(candidate.requestClient) || !record5(candidate.prewarmedThreadManager))
|
|
23181
23184
|
return null;
|
|
23182
23185
|
const bridge = candidate.requestClient;
|
|
23183
23186
|
return typeof candidate.sendRequest === "function" && typeof bridge.sendRequest === "function" && typeof bridge.prewarmThreadStart === "function" && typeof bridge.enqueueRequest === "function" && typeof candidate.prewarmedThreadManager.discardAllPrewarmedThreads === "function" ? candidate : null;
|
|
23184
23187
|
};
|
|
23185
|
-
if (!
|
|
23188
|
+
if (!record5(value2))
|
|
23186
23189
|
return null;
|
|
23187
23190
|
const direct = manager(value2) ?? manager(value2.manager);
|
|
23188
23191
|
if (direct)
|
|
@@ -23386,6 +23389,372 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
|
|
|
23386
23389
|
return routing;
|
|
23387
23390
|
}
|
|
23388
23391
|
|
|
23392
|
+
// packages/desktop-control/dist/renderer-host-rpc-discovery.js
|
|
23393
|
+
function findRendererAppScopeStore(root) {
|
|
23394
|
+
const MAX_VISITED_FIBERS = 5e4;
|
|
23395
|
+
const record5 = (value2) => typeof value2 === "object" && value2 !== null;
|
|
23396
|
+
const container = root.getElementById?.("root");
|
|
23397
|
+
if (!record5(container))
|
|
23398
|
+
return null;
|
|
23399
|
+
const key = Object.getOwnPropertyNames(container).find((name) => name.startsWith("__reactContainer$"));
|
|
23400
|
+
const first = key ? container[key] : null;
|
|
23401
|
+
if (!record5(first))
|
|
23402
|
+
return null;
|
|
23403
|
+
const isScopeHandle = (value2) => record5(value2) && record5(value2.node) && "chain" in value2 && "scope" in value2 && typeof value2.get === "function" && typeof value2.set === "function" && typeof value2.watch === "function";
|
|
23404
|
+
const stack = [first];
|
|
23405
|
+
const seen = /* @__PURE__ */ new Set();
|
|
23406
|
+
while (stack.length && seen.size < MAX_VISITED_FIBERS) {
|
|
23407
|
+
const fiber = stack.pop();
|
|
23408
|
+
if (seen.has(fiber))
|
|
23409
|
+
continue;
|
|
23410
|
+
seen.add(fiber);
|
|
23411
|
+
let hook = fiber.memoizedState;
|
|
23412
|
+
for (let index = 0; record5(hook) && "next" in hook && index < 150; index += 1) {
|
|
23413
|
+
const state = hook.memoizedState;
|
|
23414
|
+
const handle = record5(state) ? state.current : null;
|
|
23415
|
+
if (isScopeHandle(handle)) {
|
|
23416
|
+
let node = handle.node;
|
|
23417
|
+
const nodes = /* @__PURE__ */ new Set();
|
|
23418
|
+
while (record5(node.parent) && !nodes.has(node.parent)) {
|
|
23419
|
+
nodes.add(node);
|
|
23420
|
+
node = node.parent;
|
|
23421
|
+
}
|
|
23422
|
+
const bindings = node.familyBindings;
|
|
23423
|
+
return record5(bindings) && typeof bindings.get === "function" && typeof bindings.entries === "function" ? node : null;
|
|
23424
|
+
}
|
|
23425
|
+
hook = hook.next;
|
|
23426
|
+
}
|
|
23427
|
+
if (record5(fiber.sibling))
|
|
23428
|
+
stack.push(fiber.sibling);
|
|
23429
|
+
if (record5(fiber.child))
|
|
23430
|
+
stack.push(fiber.child);
|
|
23431
|
+
}
|
|
23432
|
+
return null;
|
|
23433
|
+
}
|
|
23434
|
+
function findRendererHostRpcFamily(store) {
|
|
23435
|
+
const record5 = (value2) => typeof value2 === "object" && value2 !== null;
|
|
23436
|
+
const families = /* @__PURE__ */ new Set();
|
|
23437
|
+
for (const [definition, members] of store.familyBindings) {
|
|
23438
|
+
if (!record5(definition) || definition.kind !== "signal-family")
|
|
23439
|
+
continue;
|
|
23440
|
+
if (!record5(members) || typeof members.get !== "function")
|
|
23441
|
+
continue;
|
|
23442
|
+
for (const [hostId2, member] of members) {
|
|
23443
|
+
if (typeof hostId2 !== "string" || !record5(member))
|
|
23444
|
+
continue;
|
|
23445
|
+
const signal = member.value;
|
|
23446
|
+
if (!record5(signal) || typeof signal.get !== "function")
|
|
23447
|
+
continue;
|
|
23448
|
+
let value2;
|
|
23449
|
+
try {
|
|
23450
|
+
value2 = signal.get();
|
|
23451
|
+
} catch {
|
|
23452
|
+
continue;
|
|
23453
|
+
}
|
|
23454
|
+
if (record5(value2) && Object.keys(value2).length === 2 && typeof value2.status === "string" && record5(value2.client) && value2.client.hostId === hostId2 && "rpc" in value2.client) {
|
|
23455
|
+
families.add(members);
|
|
23456
|
+
break;
|
|
23457
|
+
}
|
|
23458
|
+
}
|
|
23459
|
+
}
|
|
23460
|
+
if (families.size !== 1)
|
|
23461
|
+
return null;
|
|
23462
|
+
return { store, family: families.values().next().value };
|
|
23463
|
+
}
|
|
23464
|
+
function resolveRendererHostRpc(discovery, hostId2) {
|
|
23465
|
+
const record5 = (value3) => typeof value3 === "object" && value3 !== null;
|
|
23466
|
+
const signal = discovery.family.get(hostId2)?.value;
|
|
23467
|
+
if (!record5(signal) || typeof signal.get !== "function")
|
|
23468
|
+
return null;
|
|
23469
|
+
let value2;
|
|
23470
|
+
try {
|
|
23471
|
+
value2 = signal.get();
|
|
23472
|
+
} catch {
|
|
23473
|
+
return null;
|
|
23474
|
+
}
|
|
23475
|
+
if (!record5(value2) || value2.status !== "ready" || !record5(value2.client) || value2.client.hostId !== hostId2)
|
|
23476
|
+
return null;
|
|
23477
|
+
const rpc = value2.client.rpc;
|
|
23478
|
+
return typeof rpc === "function" || record5(rpc) ? rpc : null;
|
|
23479
|
+
}
|
|
23480
|
+
function rendererHostRpcHostIds(discovery) {
|
|
23481
|
+
return [...discovery.family.keys()].filter((hostId2) => typeof hostId2 === "string");
|
|
23482
|
+
}
|
|
23483
|
+
|
|
23484
|
+
// packages/desktop-control/dist/renderer-host-rpc-routing.js
|
|
23485
|
+
function installRendererHostRpcRouting(root, target, dependencies2) {
|
|
23486
|
+
const existing = target.__codexhostHostRoutingV1;
|
|
23487
|
+
if (existing)
|
|
23488
|
+
return existing;
|
|
23489
|
+
let disposed = false;
|
|
23490
|
+
let discovery = null;
|
|
23491
|
+
const routes = /* @__PURE__ */ new Map();
|
|
23492
|
+
const read = () => {
|
|
23493
|
+
if (disposed)
|
|
23494
|
+
return null;
|
|
23495
|
+
if (!discovery) {
|
|
23496
|
+
const store = dependencies2.findStore(root);
|
|
23497
|
+
discovery = store ? dependencies2.findFamily(store) : null;
|
|
23498
|
+
}
|
|
23499
|
+
return discovery;
|
|
23500
|
+
};
|
|
23501
|
+
if (!read())
|
|
23502
|
+
return null;
|
|
23503
|
+
const isRecord19 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
23504
|
+
const externalDrafts = /* @__PURE__ */ new Map();
|
|
23505
|
+
const selectedModels = /* @__PURE__ */ new Map();
|
|
23506
|
+
const prewarmCarrier = (carrier) => {
|
|
23507
|
+
const prefix = "codexhost/plugin-v1@";
|
|
23508
|
+
if (!carrier.startsWith(prefix))
|
|
23509
|
+
return null;
|
|
23510
|
+
try {
|
|
23511
|
+
const json2 = carrier.slice(prefix.length).replace(/[a-f0-9]{2}/gu, (byte) => String.fromCharCode(Number.parseInt(byte, 16)));
|
|
23512
|
+
const route = JSON.parse(json2);
|
|
23513
|
+
if (!isRecord19(route))
|
|
23514
|
+
return null;
|
|
23515
|
+
const payload = [...JSON.stringify({ ...route, prewarm: true })].map((character) => character.charCodeAt(0).toString(16).padStart(2, "0")).join("");
|
|
23516
|
+
return `${prefix}${payload}`;
|
|
23517
|
+
} catch {
|
|
23518
|
+
return null;
|
|
23519
|
+
}
|
|
23520
|
+
};
|
|
23521
|
+
const publishDraftWorkspace = (hostId2, cwd) => {
|
|
23522
|
+
if (typeof cwd !== "string" || cwd.length === 0)
|
|
23523
|
+
return;
|
|
23524
|
+
const drafts = isRecord19(target.__codexhostDraftWorkspacesV1) ? target.__codexhostDraftWorkspacesV1 : {};
|
|
23525
|
+
if (drafts[hostId2] === cwd)
|
|
23526
|
+
return;
|
|
23527
|
+
drafts[hostId2] = cwd;
|
|
23528
|
+
Object.defineProperty(target, "__codexhostDraftWorkspacesV1", {
|
|
23529
|
+
configurable: true,
|
|
23530
|
+
value: drafts
|
|
23531
|
+
});
|
|
23532
|
+
if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function") {
|
|
23533
|
+
target.dispatchEvent(new CustomEvent("codexhost:draft-workspace", { detail: { hostId: hostId2, cwd } }));
|
|
23534
|
+
}
|
|
23535
|
+
};
|
|
23536
|
+
const routeCreationCall = (message2) => {
|
|
23537
|
+
if (!Array.isArray(message2) || message2.length !== 2 || message2[0] !== "push")
|
|
23538
|
+
return message2;
|
|
23539
|
+
const expression = message2[1];
|
|
23540
|
+
if (!Array.isArray(expression) || expression.length !== 4 || expression[0] !== "pipeline")
|
|
23541
|
+
return message2;
|
|
23542
|
+
const [, importId, path43, args] = expression;
|
|
23543
|
+
if (!Array.isArray(path43) || path43.length !== 1 || !Array.isArray(args))
|
|
23544
|
+
return message2;
|
|
23545
|
+
const [input, options2] = args;
|
|
23546
|
+
if (!isRecord19(input) || !isRecord19(input.collaborationMode))
|
|
23547
|
+
return message2;
|
|
23548
|
+
const settings = input.collaborationMode.settings;
|
|
23549
|
+
if (!isRecord19(settings))
|
|
23550
|
+
return message2;
|
|
23551
|
+
let model2 = null;
|
|
23552
|
+
if (path43[0] === "startConversation") {
|
|
23553
|
+
const draftId = isRecord19(options2) ? options2.clientThreadId : null;
|
|
23554
|
+
model2 = typeof draftId === "string" ? externalDrafts.get(draftId)?.model ?? null : null;
|
|
23555
|
+
} else if (path43[0] === "prewarmConversation") {
|
|
23556
|
+
if (input.ephemeral !== true)
|
|
23557
|
+
publishDraftWorkspace("local", input.cwd);
|
|
23558
|
+
const selected = selectedModels.get("local");
|
|
23559
|
+
model2 = selected ? prewarmCarrier(selected) : null;
|
|
23560
|
+
}
|
|
23561
|
+
if (!model2)
|
|
23562
|
+
return message2;
|
|
23563
|
+
return [
|
|
23564
|
+
"push",
|
|
23565
|
+
[
|
|
23566
|
+
"pipeline",
|
|
23567
|
+
importId,
|
|
23568
|
+
path43,
|
|
23569
|
+
[
|
|
23570
|
+
{
|
|
23571
|
+
...input,
|
|
23572
|
+
collaborationMode: { ...input.collaborationMode, settings: { ...settings, model: model2 } }
|
|
23573
|
+
},
|
|
23574
|
+
...args.slice(1)
|
|
23575
|
+
]
|
|
23576
|
+
]
|
|
23577
|
+
];
|
|
23578
|
+
};
|
|
23579
|
+
const port = dependencies2.portPrototype;
|
|
23580
|
+
const originalPostMessage = port.postMessage;
|
|
23581
|
+
const postMessage = function(message2, ...rest) {
|
|
23582
|
+
let routed = message2;
|
|
23583
|
+
try {
|
|
23584
|
+
routed = disposed ? message2 : routeCreationCall(message2);
|
|
23585
|
+
} catch {
|
|
23586
|
+
routed = message2;
|
|
23587
|
+
}
|
|
23588
|
+
return originalPostMessage.call(this, routed, ...rest);
|
|
23589
|
+
};
|
|
23590
|
+
port.postMessage = postMessage;
|
|
23591
|
+
const createRoute = (hostId2, rpc) => {
|
|
23592
|
+
let retired = false;
|
|
23593
|
+
const isCurrent = () => !retired && !disposed && routes.get(hostId2)?.rpc === rpc;
|
|
23594
|
+
const manager = Object.freeze({
|
|
23595
|
+
kind: "main-process-rpc",
|
|
23596
|
+
getHostId: () => hostId2,
|
|
23597
|
+
sendRequest(method, params, options2) {
|
|
23598
|
+
if (!isCurrent())
|
|
23599
|
+
return Promise.reject(new Error(`Renderer request manager is retired for ${hostId2}`));
|
|
23600
|
+
return options2 === void 0 ? rpc.sendRequest(method, params) : rpc.sendRequest(method, params, options2);
|
|
23601
|
+
},
|
|
23602
|
+
// The main process broadcasts every app-server notification to its windows,
|
|
23603
|
+
// including codexhost methods Desktop's own notification table drops.
|
|
23604
|
+
addNotificationCallback(methods, listener) {
|
|
23605
|
+
const accepted = new Set(typeof methods === "string" ? [methods] : methods);
|
|
23606
|
+
const onMessage = (event) => {
|
|
23607
|
+
const { source, data } = event;
|
|
23608
|
+
if (source != null && source !== target)
|
|
23609
|
+
return;
|
|
23610
|
+
if (!isRecord19(data) || data.type !== "mcp-notification" || data.hostId !== hostId2 || typeof data.method !== "string" || !accepted.has(data.method) || !isCurrent())
|
|
23611
|
+
return;
|
|
23612
|
+
listener({ method: data.method, params: data.params });
|
|
23613
|
+
};
|
|
23614
|
+
target.addEventListener?.("message", onMessage);
|
|
23615
|
+
return () => target.removeEventListener?.("message", onMessage);
|
|
23616
|
+
}
|
|
23617
|
+
});
|
|
23618
|
+
const clearDrafts = () => {
|
|
23619
|
+
for (const [draftId, draft] of externalDrafts) {
|
|
23620
|
+
if (draft.owner === policy)
|
|
23621
|
+
externalDrafts.delete(draftId);
|
|
23622
|
+
}
|
|
23623
|
+
};
|
|
23624
|
+
const clear = () => isCurrent() ? Promise.resolve(rpc.clearPrewarmedThreads()).then(() => void 0) : Promise.reject(new Error("Renderer request manager is retired"));
|
|
23625
|
+
const policy = Object.freeze({
|
|
23626
|
+
state: "ready",
|
|
23627
|
+
hostId: hostId2,
|
|
23628
|
+
scopedCreation: true,
|
|
23629
|
+
requestTarget: () => {
|
|
23630
|
+
if (!isCurrent())
|
|
23631
|
+
throw new Error("Renderer request manager is retired");
|
|
23632
|
+
return manager;
|
|
23633
|
+
},
|
|
23634
|
+
select(model2, draftId) {
|
|
23635
|
+
if (!isCurrent())
|
|
23636
|
+
throw new Error("Renderer request manager is retired");
|
|
23637
|
+
if (model2 !== null && (typeof model2 !== "string" || !model2.startsWith("codexhost/"))) {
|
|
23638
|
+
throw new Error("Draft route Model must be a codexhost transport carrier");
|
|
23639
|
+
}
|
|
23640
|
+
if (draftId === void 0) {
|
|
23641
|
+
if (model2 === null)
|
|
23642
|
+
clearDrafts();
|
|
23643
|
+
} else if (model2 === null) {
|
|
23644
|
+
if (externalDrafts.get(draftId)?.owner === policy)
|
|
23645
|
+
externalDrafts.delete(draftId);
|
|
23646
|
+
} else {
|
|
23647
|
+
if (!draftId.startsWith("client-new-thread:"))
|
|
23648
|
+
throw new Error("External draft route is missing its client Thread identity");
|
|
23649
|
+
externalDrafts.set(draftId, { model: model2, owner: policy });
|
|
23650
|
+
}
|
|
23651
|
+
if ((selectedModels.get(hostId2) ?? null) === model2)
|
|
23652
|
+
return false;
|
|
23653
|
+
if (model2 === null)
|
|
23654
|
+
selectedModels.delete(hostId2);
|
|
23655
|
+
else
|
|
23656
|
+
selectedModels.set(hostId2, model2);
|
|
23657
|
+
void clear().catch(() => void 0);
|
|
23658
|
+
return true;
|
|
23659
|
+
},
|
|
23660
|
+
clear,
|
|
23661
|
+
dispose() {
|
|
23662
|
+
if (retired)
|
|
23663
|
+
return;
|
|
23664
|
+
retired = true;
|
|
23665
|
+
clearDrafts();
|
|
23666
|
+
selectedModels.delete(hostId2);
|
|
23667
|
+
}
|
|
23668
|
+
});
|
|
23669
|
+
return { hostId: hostId2, manager, policy };
|
|
23670
|
+
};
|
|
23671
|
+
const retire = (hostId2) => {
|
|
23672
|
+
const entry = routes.get(hostId2);
|
|
23673
|
+
routes.delete(hostId2);
|
|
23674
|
+
entry?.route.policy.dispose();
|
|
23675
|
+
};
|
|
23676
|
+
const routeFor = (hostId2) => {
|
|
23677
|
+
const current = read();
|
|
23678
|
+
const rpc = current ? dependencies2.resolve(current, hostId2) : null;
|
|
23679
|
+
const previous = routes.get(hostId2);
|
|
23680
|
+
if (rpc && previous?.rpc === rpc)
|
|
23681
|
+
return previous.route;
|
|
23682
|
+
retire(hostId2);
|
|
23683
|
+
if (!rpc)
|
|
23684
|
+
return null;
|
|
23685
|
+
const route = createRoute(hostId2, rpc);
|
|
23686
|
+
routes.set(hostId2, { route, rpc });
|
|
23687
|
+
return route;
|
|
23688
|
+
};
|
|
23689
|
+
const publish = (route) => {
|
|
23690
|
+
const policy = route?.policy;
|
|
23691
|
+
if (target.__codexhostDraftPrewarmPolicyV1 === policy)
|
|
23692
|
+
return;
|
|
23693
|
+
Object.defineProperty(target, "__codexhostDraftPrewarmPolicyV1", {
|
|
23694
|
+
configurable: true,
|
|
23695
|
+
value: policy
|
|
23696
|
+
});
|
|
23697
|
+
if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function") {
|
|
23698
|
+
target.dispatchEvent(new CustomEvent("codexhost:draft-prewarm-policy-changed"));
|
|
23699
|
+
}
|
|
23700
|
+
};
|
|
23701
|
+
const composerHostId = (composer) => {
|
|
23702
|
+
const hostIds = new Set(dependencies2.composerHostIds(composer).hostIds);
|
|
23703
|
+
const hostId2 = hostIds.size === 1 ? hostIds.values().next().value : null;
|
|
23704
|
+
return typeof hostId2 === "string" && hostId2 ? hostId2 : null;
|
|
23705
|
+
};
|
|
23706
|
+
const routing = {
|
|
23707
|
+
knownHostIds() {
|
|
23708
|
+
const current = read();
|
|
23709
|
+
return current ? dependencies2.hostIds(current) : [];
|
|
23710
|
+
},
|
|
23711
|
+
forHost(hostId2) {
|
|
23712
|
+
return hostId2 && !disposed ? routeFor(hostId2) : null;
|
|
23713
|
+
},
|
|
23714
|
+
hostIdForComposer(composer) {
|
|
23715
|
+
if (disposed)
|
|
23716
|
+
return null;
|
|
23717
|
+
try {
|
|
23718
|
+
return composerHostId(composer);
|
|
23719
|
+
} catch {
|
|
23720
|
+
return null;
|
|
23721
|
+
}
|
|
23722
|
+
},
|
|
23723
|
+
forComposer(composer) {
|
|
23724
|
+
if (disposed)
|
|
23725
|
+
return null;
|
|
23726
|
+
let hostId2;
|
|
23727
|
+
try {
|
|
23728
|
+
hostId2 = composerHostId(composer);
|
|
23729
|
+
} catch {
|
|
23730
|
+
hostId2 = null;
|
|
23731
|
+
}
|
|
23732
|
+
const route = hostId2 ? routeFor(hostId2) : null;
|
|
23733
|
+
if (!composer)
|
|
23734
|
+
publish(route);
|
|
23735
|
+
return route;
|
|
23736
|
+
},
|
|
23737
|
+
dispose() {
|
|
23738
|
+
if (disposed)
|
|
23739
|
+
return;
|
|
23740
|
+
disposed = true;
|
|
23741
|
+
for (const hostId2 of [...routes.keys()])
|
|
23742
|
+
retire(hostId2);
|
|
23743
|
+
discovery = null;
|
|
23744
|
+
externalDrafts.clear();
|
|
23745
|
+
selectedModels.clear();
|
|
23746
|
+
if (port.postMessage === postMessage)
|
|
23747
|
+
port.postMessage = originalPostMessage;
|
|
23748
|
+
if (target.__codexhostHostRoutingV1 === routing) {
|
|
23749
|
+
delete target.__codexhostHostRoutingV1;
|
|
23750
|
+
publish(null);
|
|
23751
|
+
}
|
|
23752
|
+
}
|
|
23753
|
+
};
|
|
23754
|
+
Object.defineProperty(target, "__codexhostHostRoutingV1", { configurable: true, value: routing });
|
|
23755
|
+
return routing;
|
|
23756
|
+
}
|
|
23757
|
+
|
|
23389
23758
|
// packages/desktop-control/dist/renderer-draft-prewarm-policy.js
|
|
23390
23759
|
var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
|
|
23391
23760
|
var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
|
|
@@ -23398,15 +23767,40 @@ function directRendererInstaller() {
|
|
|
23398
23767
|
const retainRendererHostResponses = ${retainRendererHostResponses.toString()};
|
|
23399
23768
|
const createDraftPrewarmPolicyBridge = ${createDraftPrewarmPolicyBridge.toString()};
|
|
23400
23769
|
const isolateRendererPrewarmConsumption = ${isolateRendererPrewarmConsumption.toString()};
|
|
23401
|
-
const
|
|
23402
|
-
|
|
23403
|
-
|
|
23770
|
+
const discover = (root) =>
|
|
23771
|
+
discoverRendererHosts(root, committedReactAncestors, requestManagerFromHookState);
|
|
23772
|
+
const installNative = () => (${installRendererHostRouting.toString()})(
|
|
23773
|
+
document, window, discover,
|
|
23404
23774
|
(discovery, hostId) => resolveRendererHostManager(discovery, hostId, requestManagerFromHookState),
|
|
23405
23775
|
(manager, bridge, hostId, target, prewarmed, isCurrent) => createDraftPrewarmPolicyBridge(
|
|
23406
23776
|
manager, bridge, hostId, target, prewarmed, isCurrent, retainRendererHostResponses,
|
|
23407
23777
|
isolateRendererPrewarmConsumption,
|
|
23408
23778
|
),
|
|
23409
23779
|
);
|
|
23780
|
+
const installRpc = () => typeof MessagePort !== 'function' ? null : (${installRendererHostRpcRouting.toString()})(document, window, {
|
|
23781
|
+
findStore: ${findRendererAppScopeStore.toString()},
|
|
23782
|
+
findFamily: ${findRendererHostRpcFamily.toString()},
|
|
23783
|
+
resolve: ${resolveRendererHostRpc.toString()},
|
|
23784
|
+
hostIds: ${rendererHostRpcHostIds.toString()},
|
|
23785
|
+
composerHostIds: (composer) => {
|
|
23786
|
+
const source = composer?.matches?.('[data-codex-composer], [contenteditable="true"][role="textbox"]')
|
|
23787
|
+
? { querySelectorAll: () => [composer] }
|
|
23788
|
+
: (composer ?? document);
|
|
23789
|
+
return discover(source);
|
|
23790
|
+
},
|
|
23791
|
+
portPrototype: MessagePort.prototype,
|
|
23792
|
+
});
|
|
23793
|
+
// Desktop 26.1027 moved AppServerManagers to the main process. Older builds
|
|
23794
|
+
// expose native managers in Renderer hook state; the main-process mode only
|
|
23795
|
+
// applies when none is visible and its per-Host RPC store is identified.
|
|
23796
|
+
const routing = (() => {
|
|
23797
|
+
if (window.__codexhostHostRoutingV1) return window.__codexhostHostRoutingV1;
|
|
23798
|
+
const native = discover(document);
|
|
23799
|
+
if (native.managers.length || native.registries.length) return installNative();
|
|
23800
|
+
const rpc = installRpc();
|
|
23801
|
+
if (rpc) return rpc;
|
|
23802
|
+
throw new Error('Renderer Host request manager is unavailable');
|
|
23803
|
+
})();
|
|
23410
23804
|
// Publish a default draft policy only when its Host is unambiguous. Host
|
|
23411
23805
|
// connections can be ready even when multiple Composers coexist.
|
|
23412
23806
|
const composerRoute = routing.forComposer();
|
|
@@ -23441,6 +23835,119 @@ function installRendererDraftPrewarmPolicyDirect(renderer) {
|
|
|
23441
23835
|
// packages/desktop-control/dist/renderer-control-session.js
|
|
23442
23836
|
var startupTraceStartedAt = Date.now();
|
|
23443
23837
|
|
|
23838
|
+
// packages/desktop-control/dist/renderer-loaded-modules.js
|
|
23839
|
+
var record3 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
23840
|
+
var MAX_MODULES = 4096;
|
|
23841
|
+
function nativeModuleCatalogExpression(urls, complete, owner) {
|
|
23842
|
+
return `Object.defineProperty(globalThis, '__codexhostLoadedModulesV1', {
|
|
23843
|
+
configurable: true,
|
|
23844
|
+
value: Object.freeze({ owner: ${JSON.stringify(owner)}, documentUrl: location.href, complete: ${complete}, urls: Object.freeze(${JSON.stringify(urls)}) })
|
|
23845
|
+
}); void 0`;
|
|
23846
|
+
}
|
|
23847
|
+
async function installRendererLoadedModules(renderer) {
|
|
23848
|
+
const owner = crypto.randomUUID();
|
|
23849
|
+
const contexts = /* @__PURE__ */ new Map();
|
|
23850
|
+
const contextIds = /* @__PURE__ */ new Map();
|
|
23851
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
23852
|
+
let ready = false;
|
|
23853
|
+
let disposed = false;
|
|
23854
|
+
let timer;
|
|
23855
|
+
let publishing = Promise.resolve();
|
|
23856
|
+
const flush = () => {
|
|
23857
|
+
clearTimeout(timer);
|
|
23858
|
+
timer = void 0;
|
|
23859
|
+
const pending = [...dirty];
|
|
23860
|
+
dirty.clear();
|
|
23861
|
+
publishing = publishing.catch(() => void 0).then(async () => {
|
|
23862
|
+
for (const uniqueId of pending) {
|
|
23863
|
+
const context = contexts.get(uniqueId);
|
|
23864
|
+
if (!context || disposed)
|
|
23865
|
+
continue;
|
|
23866
|
+
const response = await renderer.command("Runtime.evaluate", {
|
|
23867
|
+
expression: nativeModuleCatalogExpression([...context.urls], context.complete, owner),
|
|
23868
|
+
uniqueContextId: uniqueId
|
|
23869
|
+
});
|
|
23870
|
+
if (record3(response) && record3(response.exceptionDetails))
|
|
23871
|
+
throw new Error("Loaded Renderer module catalog publication failed");
|
|
23872
|
+
}
|
|
23873
|
+
});
|
|
23874
|
+
return publishing;
|
|
23875
|
+
};
|
|
23876
|
+
const schedule = (uniqueId) => {
|
|
23877
|
+
dirty.add(uniqueId);
|
|
23878
|
+
if (ready && timer === void 0)
|
|
23879
|
+
timer = setTimeout(() => {
|
|
23880
|
+
void flush().catch((error51) => {
|
|
23881
|
+
console.error("Could not publish loaded Renderer modules", error51);
|
|
23882
|
+
});
|
|
23883
|
+
}, 10);
|
|
23884
|
+
};
|
|
23885
|
+
const remove = (id2) => {
|
|
23886
|
+
const uniqueId = contextIds.get(id2);
|
|
23887
|
+
contextIds.delete(id2);
|
|
23888
|
+
if (uniqueId) {
|
|
23889
|
+
contexts.delete(uniqueId);
|
|
23890
|
+
dirty.delete(uniqueId);
|
|
23891
|
+
}
|
|
23892
|
+
};
|
|
23893
|
+
const listeners = [
|
|
23894
|
+
renderer.on("Runtime.executionContextCreated", (params) => {
|
|
23895
|
+
const context = record3(params) ? params.context : null;
|
|
23896
|
+
if (!record3(context) || typeof context.id !== "number" || typeof context.uniqueId !== "string" || !record3(context.auxData) || context.auxData.isDefault !== true)
|
|
23897
|
+
return;
|
|
23898
|
+
contextIds.set(context.id, context.uniqueId);
|
|
23899
|
+
contexts.set(context.uniqueId, { urls: /* @__PURE__ */ new Set(), complete: true });
|
|
23900
|
+
schedule(context.uniqueId);
|
|
23901
|
+
}),
|
|
23902
|
+
renderer.on("Runtime.executionContextDestroyed", (params) => {
|
|
23903
|
+
if (record3(params) && typeof params.executionContextId === "number")
|
|
23904
|
+
remove(params.executionContextId);
|
|
23905
|
+
}),
|
|
23906
|
+
renderer.on("Runtime.executionContextsCleared", () => {
|
|
23907
|
+
contextIds.clear();
|
|
23908
|
+
contexts.clear();
|
|
23909
|
+
dirty.clear();
|
|
23910
|
+
}),
|
|
23911
|
+
renderer.on("Debugger.scriptParsed", (params) => {
|
|
23912
|
+
if (!record3(params) || params.isModule !== true || params.hasSourceURL === true || typeof params.url !== "string" || typeof params.executionContextId !== "number")
|
|
23913
|
+
return;
|
|
23914
|
+
const uniqueId = contextIds.get(params.executionContextId);
|
|
23915
|
+
const context = uniqueId ? contexts.get(uniqueId) : null;
|
|
23916
|
+
if (!context || !uniqueId || context.urls.has(params.url))
|
|
23917
|
+
return;
|
|
23918
|
+
if (context.urls.size >= MAX_MODULES)
|
|
23919
|
+
context.complete = false;
|
|
23920
|
+
else
|
|
23921
|
+
context.urls.add(params.url);
|
|
23922
|
+
schedule(uniqueId);
|
|
23923
|
+
})
|
|
23924
|
+
];
|
|
23925
|
+
const dispose = () => {
|
|
23926
|
+
disposed = true;
|
|
23927
|
+
clearTimeout(timer);
|
|
23928
|
+
for (const unsubscribe of listeners)
|
|
23929
|
+
unsubscribe();
|
|
23930
|
+
for (const uniqueId of contexts.keys())
|
|
23931
|
+
void renderer.command("Runtime.evaluate", {
|
|
23932
|
+
expression: `if (globalThis.__codexhostLoadedModulesV1 === undefined || globalThis.__codexhostLoadedModulesV1?.owner === ${JSON.stringify(owner)}) { ${nativeModuleCatalogExpression([], false, owner)} }`,
|
|
23933
|
+
uniqueContextId: uniqueId
|
|
23934
|
+
}).catch(() => void 0);
|
|
23935
|
+
contexts.clear();
|
|
23936
|
+
contextIds.clear();
|
|
23937
|
+
dirty.clear();
|
|
23938
|
+
};
|
|
23939
|
+
try {
|
|
23940
|
+
await renderer.command("Runtime.enable");
|
|
23941
|
+
await renderer.command("Debugger.enable");
|
|
23942
|
+
ready = true;
|
|
23943
|
+
await flush();
|
|
23944
|
+
return dispose;
|
|
23945
|
+
} catch (error51) {
|
|
23946
|
+
dispose();
|
|
23947
|
+
throw error51;
|
|
23948
|
+
}
|
|
23949
|
+
}
|
|
23950
|
+
|
|
23444
23951
|
// packages/desktop-control/dist/renderer-cdp-control-session.js
|
|
23445
23952
|
function isRecord2(value2) {
|
|
23446
23953
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
@@ -23575,15 +24082,17 @@ async function waitForBinding(renderer, enabledAgents, timeoutMs, pollIntervalMs
|
|
|
23575
24082
|
}
|
|
23576
24083
|
async function installTarget(target, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations) {
|
|
23577
24084
|
const renderer = await operations.connect(target.webSocketDebuggerUrl);
|
|
24085
|
+
let disposeModules;
|
|
23578
24086
|
try {
|
|
23579
|
-
await renderer
|
|
24087
|
+
disposeModules = await installRendererLoadedModules(renderer);
|
|
23580
24088
|
await renderer.command("Page.enable");
|
|
23581
24089
|
await renderer.command("Page.addScriptToEvaluateOnNewDocument", { source: rendererSource });
|
|
23582
24090
|
await evaluateSource(renderer, rendererSource);
|
|
23583
24091
|
const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(renderer);
|
|
23584
24092
|
const binding = await waitForBinding(renderer, enabledAgents, timeoutMs, pollIntervalMs);
|
|
23585
|
-
return { renderer, snapshot: { target, draftPrewarmPolicy, binding } };
|
|
24093
|
+
return { renderer, snapshot: { target, draftPrewarmPolicy, binding }, disposeModules };
|
|
23586
24094
|
} catch (error51) {
|
|
24095
|
+
disposeModules?.();
|
|
23587
24096
|
renderer.close();
|
|
23588
24097
|
throw error51;
|
|
23589
24098
|
}
|
|
@@ -23597,8 +24106,9 @@ var InstalledRendererCdpControlSession = class {
|
|
|
23597
24106
|
pollIntervalMs;
|
|
23598
24107
|
operations;
|
|
23599
24108
|
currentSnapshot;
|
|
24109
|
+
disposeModules;
|
|
23600
24110
|
#closed = false;
|
|
23601
|
-
constructor(renderer, rendererCdpEndpoint, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, currentSnapshot) {
|
|
24111
|
+
constructor(renderer, rendererCdpEndpoint, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, currentSnapshot, disposeModules) {
|
|
23602
24112
|
this.renderer = renderer;
|
|
23603
24113
|
this.rendererCdpEndpoint = rendererCdpEndpoint;
|
|
23604
24114
|
this.rendererSource = rendererSource;
|
|
@@ -23607,6 +24117,7 @@ var InstalledRendererCdpControlSession = class {
|
|
|
23607
24117
|
this.pollIntervalMs = pollIntervalMs;
|
|
23608
24118
|
this.operations = operations;
|
|
23609
24119
|
this.currentSnapshot = currentSnapshot;
|
|
24120
|
+
this.disposeModules = disposeModules;
|
|
23610
24121
|
}
|
|
23611
24122
|
get snapshot() {
|
|
23612
24123
|
return this.currentSnapshot;
|
|
@@ -23617,8 +24128,10 @@ var InstalledRendererCdpControlSession = class {
|
|
|
23617
24128
|
const target = await waitForPrimaryTarget(this.rendererCdpEndpoint, this.operations, this.timeoutMs, this.pollIntervalMs, this.currentSnapshot.target.id);
|
|
23618
24129
|
if (target.id !== this.currentSnapshot.target.id) {
|
|
23619
24130
|
const replacement = await installTarget(target, this.rendererSource, this.enabledAgents, this.timeoutMs, this.pollIntervalMs, this.operations);
|
|
24131
|
+
this.disposeModules();
|
|
23620
24132
|
this.renderer.close();
|
|
23621
24133
|
this.renderer = replacement.renderer;
|
|
24134
|
+
this.disposeModules = replacement.disposeModules;
|
|
23622
24135
|
this.currentSnapshot = replacement.snapshot;
|
|
23623
24136
|
return this.currentSnapshot;
|
|
23624
24137
|
}
|
|
@@ -23632,8 +24145,10 @@ var InstalledRendererCdpControlSession = class {
|
|
|
23632
24145
|
return this.currentSnapshot;
|
|
23633
24146
|
} catch {
|
|
23634
24147
|
const replacement = await installTarget(target, this.rendererSource, this.enabledAgents, this.timeoutMs, this.pollIntervalMs, this.operations);
|
|
24148
|
+
this.disposeModules();
|
|
23635
24149
|
this.renderer.close();
|
|
23636
24150
|
this.renderer = replacement.renderer;
|
|
24151
|
+
this.disposeModules = replacement.disposeModules;
|
|
23637
24152
|
this.currentSnapshot = replacement.snapshot;
|
|
23638
24153
|
return this.currentSnapshot;
|
|
23639
24154
|
}
|
|
@@ -23653,6 +24168,7 @@ var InstalledRendererCdpControlSession = class {
|
|
|
23653
24168
|
if (this.#closed)
|
|
23654
24169
|
return;
|
|
23655
24170
|
this.#closed = true;
|
|
24171
|
+
this.disposeModules();
|
|
23656
24172
|
this.renderer.close();
|
|
23657
24173
|
}
|
|
23658
24174
|
};
|
|
@@ -23668,7 +24184,7 @@ async function createRendererCdpControlSession(options2) {
|
|
|
23668
24184
|
const operations = options2.operations ?? defaultOperations;
|
|
23669
24185
|
const target = await waitForPrimaryTarget(options2.rendererCdpEndpoint, operations, timeoutMs, pollIntervalMs, void 0, options2.signal);
|
|
23670
24186
|
const installed = await installTarget(target, options2.rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations);
|
|
23671
|
-
return new InstalledRendererCdpControlSession(installed.renderer, options2.rendererCdpEndpoint, options2.rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, installed.snapshot);
|
|
24187
|
+
return new InstalledRendererCdpControlSession(installed.renderer, options2.rendererCdpEndpoint, options2.rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, installed.snapshot, installed.disposeModules);
|
|
23672
24188
|
}
|
|
23673
24189
|
function installRendererCdpControlSession(options2) {
|
|
23674
24190
|
return createRendererCdpControlSession(options2);
|
|
@@ -25753,15 +26269,15 @@ var storedThreadMetadataV1Schema = external_exports.object({
|
|
|
25753
26269
|
hostThreadId: storedHostThreadIdSchema,
|
|
25754
26270
|
...storedThreadMetadataFieldsShape
|
|
25755
26271
|
}).passthrough();
|
|
25756
|
-
function refineThreadRecord(
|
|
25757
|
-
if (
|
|
26272
|
+
function refineThreadRecord(record5, context) {
|
|
26273
|
+
if (record5.state === "ready" && !record5.nativeSessionRef) {
|
|
25758
26274
|
context.addIssue({
|
|
25759
26275
|
code: "custom",
|
|
25760
26276
|
path: ["nativeSessionRef"],
|
|
25761
26277
|
message: "Ready Thread must have a Native Session Ref"
|
|
25762
26278
|
});
|
|
25763
26279
|
}
|
|
25764
|
-
if (
|
|
26280
|
+
if (record5.nativeSessionRef && record5.nativeSessionRef.harnessId !== record5.harnessId) {
|
|
25765
26281
|
context.addIssue({
|
|
25766
26282
|
code: "custom",
|
|
25767
26283
|
path: ["nativeSessionRef", "harnessId"],
|
|
@@ -25770,7 +26286,7 @@ function refineThreadRecord(record4, context) {
|
|
|
25770
26286
|
}
|
|
25771
26287
|
const hostTurnIds = /* @__PURE__ */ new Set();
|
|
25772
26288
|
const nativeTurnKeys = /* @__PURE__ */ new Set();
|
|
25773
|
-
for (const [index, mapping] of
|
|
26289
|
+
for (const [index, mapping] of record5.turnMappings.entries()) {
|
|
25774
26290
|
if (hostTurnIds.has(mapping.hostTurnId)) {
|
|
25775
26291
|
context.addIssue({
|
|
25776
26292
|
code: "custom",
|
|
@@ -25794,14 +26310,14 @@ function refineThreadRecord(record4, context) {
|
|
|
25794
26310
|
]) {
|
|
25795
26311
|
if (!ref)
|
|
25796
26312
|
continue;
|
|
25797
|
-
if (ref.harnessId !==
|
|
26313
|
+
if (ref.harnessId !== record5.harnessId) {
|
|
25798
26314
|
context.addIssue({
|
|
25799
26315
|
code: "custom",
|
|
25800
26316
|
path: ["turnMappings", index, name, "harnessId"],
|
|
25801
26317
|
message: "Turn Ref Harness must match the Thread Harness"
|
|
25802
26318
|
});
|
|
25803
26319
|
}
|
|
25804
|
-
if (
|
|
26320
|
+
if (record5.nativeSessionRef && ref.nativeSessionId !== record5.nativeSessionRef.nativeSessionId) {
|
|
25805
26321
|
context.addIssue({
|
|
25806
26322
|
code: "custom",
|
|
25807
26323
|
path: ["turnMappings", index, name, "nativeSessionId"],
|
|
@@ -25833,7 +26349,7 @@ var storedDelegationRecordV1Schema = external_exports.object({
|
|
|
25833
26349
|
taskDigest: external_exports.string().regex(/^[a-f0-9]{64}$/u),
|
|
25834
26350
|
createdAt: isoDateSchema,
|
|
25835
26351
|
updatedAt: isoDateSchema
|
|
25836
|
-
}).strict().refine((
|
|
26352
|
+
}).strict().refine((record5) => record5.parentHostThreadId !== record5.childHostThreadId, {
|
|
25837
26353
|
path: ["childHostThreadId"],
|
|
25838
26354
|
message: "Delegation child Thread must differ from its parent"
|
|
25839
26355
|
});
|
|
@@ -25973,8 +26489,8 @@ var MappingStoreError = class extends Error {
|
|
|
25973
26489
|
this.name = "MappingStoreError";
|
|
25974
26490
|
}
|
|
25975
26491
|
};
|
|
25976
|
-
function cloneRecord(
|
|
25977
|
-
return JSON.parse(JSON.stringify(
|
|
26492
|
+
function cloneRecord(record5) {
|
|
26493
|
+
return JSON.parse(JSON.stringify(record5));
|
|
25978
26494
|
}
|
|
25979
26495
|
function nativeSessionKey(ref) {
|
|
25980
26496
|
return `${ref.harnessId}\0${ref.nativeSessionId}`;
|
|
@@ -26017,22 +26533,22 @@ function withoutUnparsedUrlCredentials(value2) {
|
|
|
26017
26533
|
const kept = keepUser && !userInfo.includes(":") ? `${userInfo}@` : "";
|
|
26018
26534
|
return value2.slice(0, authorityStart) + kept + value2.slice(authorityStart + at + 1);
|
|
26019
26535
|
}
|
|
26020
|
-
function threadMetadataOf(
|
|
26021
|
-
const fields = Object.fromEntries(THREAD_METADATA_FIELDS.filter((name) =>
|
|
26536
|
+
function threadMetadataOf(record5) {
|
|
26537
|
+
const fields = Object.fromEntries(THREAD_METADATA_FIELDS.filter((name) => record5[name] !== void 0).map((name) => [
|
|
26022
26538
|
name,
|
|
26023
|
-
|
|
26539
|
+
record5[name]
|
|
26024
26540
|
]));
|
|
26025
26541
|
if (Object.keys(fields).length === 0)
|
|
26026
26542
|
return null;
|
|
26027
|
-
return { formatVersion: 1, hostThreadId:
|
|
26543
|
+
return { formatVersion: 1, hostThreadId: record5.hostThreadId, ...fields };
|
|
26028
26544
|
}
|
|
26029
|
-
function withoutThreadMetadata(
|
|
26030
|
-
const { projectId, daybreakEnabled, gitInfo, ...core } =
|
|
26545
|
+
function withoutThreadMetadata(record5) {
|
|
26546
|
+
const { projectId, daybreakEnabled, gitInfo, ...core } = record5;
|
|
26031
26547
|
void [projectId, daybreakEnabled, gitInfo];
|
|
26032
26548
|
return core;
|
|
26033
26549
|
}
|
|
26034
|
-
function withThreadMetadata(
|
|
26035
|
-
const core = withoutThreadMetadata(
|
|
26550
|
+
function withThreadMetadata(record5, metadata) {
|
|
26551
|
+
const core = withoutThreadMetadata(record5);
|
|
26036
26552
|
for (const name of THREAD_METADATA_FIELDS) {
|
|
26037
26553
|
if (metadata[name] !== void 0)
|
|
26038
26554
|
Object.assign(core, { [name]: metadata[name] });
|
|
@@ -26217,13 +26733,13 @@ var MappingStore = class {
|
|
|
26217
26733
|
for (const name of names) {
|
|
26218
26734
|
const primary = path18.join(this.#threadsDirectory, name);
|
|
26219
26735
|
const backup = path18.join(this.#backupsDirectory, name);
|
|
26220
|
-
let
|
|
26736
|
+
let record5 = null;
|
|
26221
26737
|
try {
|
|
26222
|
-
|
|
26738
|
+
record5 = await this.#readRecord(primary, name);
|
|
26223
26739
|
} catch (primaryError) {
|
|
26224
26740
|
try {
|
|
26225
|
-
|
|
26226
|
-
await this.#replaceFile(primary,
|
|
26741
|
+
record5 = await this.#readRecord(backup, name);
|
|
26742
|
+
await this.#replaceFile(primary, record5, false);
|
|
26227
26743
|
} catch (backupError) {
|
|
26228
26744
|
const quarantine = path18.join(this.#quarantineDirectory, `${name}.${this.#now().getTime()}.invalid`);
|
|
26229
26745
|
await rename10(primary, quarantine).catch(() => void 0);
|
|
@@ -26232,20 +26748,20 @@ var MappingStore = class {
|
|
|
26232
26748
|
continue;
|
|
26233
26749
|
}
|
|
26234
26750
|
}
|
|
26235
|
-
if (
|
|
26751
|
+
if (record5.state === "creating" && !record5.nativeSessionRef) {
|
|
26236
26752
|
await rm10(primary, { force: true });
|
|
26237
26753
|
await rm10(backup, { force: true });
|
|
26238
|
-
await rm10(this.#metadataPath(
|
|
26754
|
+
await rm10(this.#metadataPath(record5.hostThreadId), { force: true });
|
|
26239
26755
|
continue;
|
|
26240
26756
|
}
|
|
26241
|
-
const metadata = await this.#readMetadata(
|
|
26757
|
+
const metadata = await this.#readMetadata(record5.hostThreadId);
|
|
26242
26758
|
if (metadata) {
|
|
26243
|
-
|
|
26244
|
-
} else if (threadMetadataOf(
|
|
26245
|
-
await this.#writeMetadataFile(
|
|
26246
|
-
await this.#replaceFile(primary,
|
|
26759
|
+
record5 = withThreadMetadata(record5, metadata);
|
|
26760
|
+
} else if (threadMetadataOf(record5)) {
|
|
26761
|
+
await this.#writeMetadataFile(record5.hostThreadId, threadMetadataOf(record5));
|
|
26762
|
+
await this.#replaceFile(primary, record5, false);
|
|
26247
26763
|
}
|
|
26248
|
-
this.#records.set(
|
|
26764
|
+
this.#records.set(record5.hostThreadId, record5);
|
|
26249
26765
|
}
|
|
26250
26766
|
await Promise.all((await readdir4(this.#metadataDirectory)).filter((name) => name.endsWith(".json") && !this.#records.has(name.slice(0, -5))).map((name) => rm10(path18.join(this.#metadataDirectory, name), { force: true })));
|
|
26251
26767
|
const delegationNames = (await readdir4(this.#delegationsDirectory)).filter((name) => name.endsWith(".json"));
|
|
@@ -26282,8 +26798,8 @@ var MappingStore = class {
|
|
|
26282
26798
|
}
|
|
26283
26799
|
async getThread(hostThreadId) {
|
|
26284
26800
|
this.#requireInitialized();
|
|
26285
|
-
const
|
|
26286
|
-
return
|
|
26801
|
+
const record5 = this.#records.get(hostThreadId);
|
|
26802
|
+
return record5 ? cloneRecord(record5) : null;
|
|
26287
26803
|
}
|
|
26288
26804
|
async listThreads() {
|
|
26289
26805
|
this.#requireInitialized();
|
|
@@ -26296,8 +26812,8 @@ var MappingStore = class {
|
|
|
26296
26812
|
}
|
|
26297
26813
|
async getDelegation(delegationId) {
|
|
26298
26814
|
this.#requireInitialized();
|
|
26299
|
-
const
|
|
26300
|
-
return
|
|
26815
|
+
const record5 = this.#delegations.get(delegationId);
|
|
26816
|
+
return record5 ? cloneRecord(record5) : null;
|
|
26301
26817
|
}
|
|
26302
26818
|
async getDelegationByChild(childHostThreadId) {
|
|
26303
26819
|
this.#requireInitialized();
|
|
@@ -26311,12 +26827,12 @@ var MappingStore = class {
|
|
|
26311
26827
|
}
|
|
26312
26828
|
async listDelegations(parentHostThreadId) {
|
|
26313
26829
|
this.#requireInitialized();
|
|
26314
|
-
return [...this.#delegations.values()].filter((
|
|
26830
|
+
return [...this.#delegations.values()].filter((record5) => !parentHostThreadId || record5.parentHostThreadId === parentHostThreadId).map(cloneRecord);
|
|
26315
26831
|
}
|
|
26316
26832
|
async findRecentDelegation(input) {
|
|
26317
26833
|
this.#requireInitialized();
|
|
26318
26834
|
const threshold = input.since.getTime();
|
|
26319
|
-
const found = [...this.#delegations.values()].filter((
|
|
26835
|
+
const found = [...this.#delegations.values()].filter((record5) => record5.parentHostThreadId === input.parentHostThreadId && record5.targetHarnessId === input.targetHarnessId && record5.taskDigest === input.taskDigest && Date.parse(record5.createdAt) >= threshold).toSorted((left, right) => Date.parse(right.createdAt) - Date.parse(left.createdAt))[0];
|
|
26320
26836
|
return found ? cloneRecord(found) : null;
|
|
26321
26837
|
}
|
|
26322
26838
|
async createDelegation(input) {
|
|
@@ -26331,7 +26847,7 @@ var MappingStore = class {
|
|
|
26331
26847
|
throw new MappingStoreError("DUPLICATE_CREATE_REQUEST", "Delegation Request ID already exists");
|
|
26332
26848
|
}
|
|
26333
26849
|
const timestamp = this.#now().toISOString();
|
|
26334
|
-
const
|
|
26850
|
+
const record5 = storedDelegationRecordV1Schema.parse({
|
|
26335
26851
|
formatVersion: 1,
|
|
26336
26852
|
revision: 1,
|
|
26337
26853
|
...input,
|
|
@@ -26339,10 +26855,10 @@ var MappingStore = class {
|
|
|
26339
26855
|
createdAt: timestamp,
|
|
26340
26856
|
updatedAt: timestamp
|
|
26341
26857
|
});
|
|
26342
|
-
await this.#replaceDelegationFile(
|
|
26343
|
-
this.#delegations.set(
|
|
26858
|
+
await this.#replaceDelegationFile(record5);
|
|
26859
|
+
this.#delegations.set(record5.delegationId, record5);
|
|
26344
26860
|
this.#rebuildIndexes();
|
|
26345
|
-
return cloneRecord(
|
|
26861
|
+
return cloneRecord(record5);
|
|
26346
26862
|
}
|
|
26347
26863
|
async setDelegationStatus(delegationId, status2) {
|
|
26348
26864
|
this.#requireInitialized();
|
|
@@ -26393,7 +26909,7 @@ var MappingStore = class {
|
|
|
26393
26909
|
throw new MappingStoreError("DUPLICATE_THREAD_ID", "Host Thread ID already exists");
|
|
26394
26910
|
}
|
|
26395
26911
|
const timestamp = this.#now().toISOString();
|
|
26396
|
-
const
|
|
26912
|
+
const record5 = storedThreadRecordV1Schema.parse({
|
|
26397
26913
|
formatVersion: 1,
|
|
26398
26914
|
revision: 1,
|
|
26399
26915
|
hostThreadId: input.hostThreadId,
|
|
@@ -26412,8 +26928,8 @@ var MappingStore = class {
|
|
|
26412
26928
|
createdAt: timestamp,
|
|
26413
26929
|
updatedAt: timestamp
|
|
26414
26930
|
});
|
|
26415
|
-
await this.#writeNew(
|
|
26416
|
-
result = cloneRecord(
|
|
26931
|
+
await this.#writeNew(record5);
|
|
26932
|
+
result = cloneRecord(record5);
|
|
26417
26933
|
});
|
|
26418
26934
|
if (!result)
|
|
26419
26935
|
throw new MappingStoreError("IO_ERROR", "Provisional create produced no result");
|
|
@@ -26584,8 +27100,8 @@ var MappingStore = class {
|
|
|
26584
27100
|
async removeProvisional(hostThreadId) {
|
|
26585
27101
|
this.#requireInitialized();
|
|
26586
27102
|
await this.#enqueue(async () => {
|
|
26587
|
-
const
|
|
26588
|
-
if (
|
|
27103
|
+
const record5 = this.#records.get(hostThreadId);
|
|
27104
|
+
if (record5?.state === "ready") {
|
|
26589
27105
|
throw new MappingStoreError("MAPPING_CONFLICT", "Ready Thread cannot be removed as provisional");
|
|
26590
27106
|
}
|
|
26591
27107
|
await this.#remove(hostThreadId);
|
|
@@ -26716,25 +27232,25 @@ var MappingStore = class {
|
|
|
26716
27232
|
}
|
|
26717
27233
|
return merged;
|
|
26718
27234
|
}
|
|
26719
|
-
async #writeNew(
|
|
26720
|
-
this.#validateGlobal(
|
|
26721
|
-
await this.#replaceFile(this.#recordPath(
|
|
26722
|
-
this.#records.set(
|
|
27235
|
+
async #writeNew(record5) {
|
|
27236
|
+
this.#validateGlobal(record5, null);
|
|
27237
|
+
await this.#replaceFile(this.#recordPath(record5.hostThreadId), record5, false);
|
|
27238
|
+
this.#records.set(record5.hostThreadId, record5);
|
|
26723
27239
|
this.#rebuildIndexes();
|
|
26724
27240
|
}
|
|
26725
|
-
async #replaceFile(target,
|
|
27241
|
+
async #replaceFile(target, record5, preserveBackup) {
|
|
26726
27242
|
const temp = `${target}.tmp-${randomUUID9()}`;
|
|
26727
27243
|
let handle = null;
|
|
26728
27244
|
try {
|
|
26729
|
-
await this.#beforeReplace?.(cloneRecord(
|
|
27245
|
+
await this.#beforeReplace?.(cloneRecord(record5));
|
|
26730
27246
|
handle = await open7(temp, "wx", constants3.S_IRUSR | constants3.S_IWUSR);
|
|
26731
|
-
await handle.writeFile(`${JSON.stringify(withoutThreadMetadata(
|
|
27247
|
+
await handle.writeFile(`${JSON.stringify(withoutThreadMetadata(record5), null, 2)}
|
|
26732
27248
|
`, "utf8");
|
|
26733
27249
|
await handle.sync();
|
|
26734
27250
|
await handle.close();
|
|
26735
27251
|
handle = null;
|
|
26736
27252
|
if (preserveBackup && await exists(target)) {
|
|
26737
|
-
await copyFile3(target, this.#backupPath(
|
|
27253
|
+
await copyFile3(target, this.#backupPath(record5.hostThreadId));
|
|
26738
27254
|
}
|
|
26739
27255
|
await rename10(temp, target);
|
|
26740
27256
|
} catch (error51) {
|
|
@@ -26795,13 +27311,13 @@ var MappingStore = class {
|
|
|
26795
27311
|
return null;
|
|
26796
27312
|
}
|
|
26797
27313
|
}
|
|
26798
|
-
async #replaceDelegationFile(
|
|
26799
|
-
const target = this.#delegationPath(
|
|
27314
|
+
async #replaceDelegationFile(record5) {
|
|
27315
|
+
const target = this.#delegationPath(record5.delegationId);
|
|
26800
27316
|
const temp = `${target}.tmp-${randomUUID9()}`;
|
|
26801
27317
|
let handle = null;
|
|
26802
27318
|
try {
|
|
26803
27319
|
handle = await open7(temp, "wx", constants3.S_IRUSR | constants3.S_IWUSR);
|
|
26804
|
-
await handle.writeFile(`${JSON.stringify(
|
|
27320
|
+
await handle.writeFile(`${JSON.stringify(record5, null, 2)}
|
|
26805
27321
|
`, "utf8");
|
|
26806
27322
|
await handle.sync();
|
|
26807
27323
|
await handle.close();
|
|
@@ -26885,18 +27401,18 @@ var MappingStore = class {
|
|
|
26885
27401
|
});
|
|
26886
27402
|
}
|
|
26887
27403
|
}
|
|
26888
|
-
#validateGlobal(
|
|
26889
|
-
const duplicateCreate = this.#createRequests.get(
|
|
27404
|
+
#validateGlobal(record5, replacing) {
|
|
27405
|
+
const duplicateCreate = this.#createRequests.get(record5.createRequestId);
|
|
26890
27406
|
if (duplicateCreate && duplicateCreate !== replacing) {
|
|
26891
27407
|
throw new MappingStoreError("DUPLICATE_CREATE_REQUEST", "Create request is already stored");
|
|
26892
27408
|
}
|
|
26893
|
-
if (
|
|
26894
|
-
const duplicateSession = this.#nativeSessions.get(nativeSessionKey(
|
|
27409
|
+
if (record5.nativeSessionRef && !record5.subagent) {
|
|
27410
|
+
const duplicateSession = this.#nativeSessions.get(nativeSessionKey(record5.nativeSessionRef));
|
|
26895
27411
|
if (duplicateSession && duplicateSession !== replacing) {
|
|
26896
27412
|
throw new MappingStoreError("DUPLICATE_NATIVE_SESSION", "Native Session is already mapped");
|
|
26897
27413
|
}
|
|
26898
27414
|
}
|
|
26899
|
-
for (const mapping of
|
|
27415
|
+
for (const mapping of record5.turnMappings) {
|
|
26900
27416
|
const duplicateHostTurn = this.#hostTurns.get(mapping.hostTurnId);
|
|
26901
27417
|
if (duplicateHostTurn && duplicateHostTurn !== replacing) {
|
|
26902
27418
|
throw new MappingStoreError("MAPPING_CONFLICT", "Host Turn is already mapped");
|
|
@@ -26926,14 +27442,14 @@ var MappingStore = class {
|
|
|
26926
27442
|
this.#delegationRequests.set(delegation.requestId, delegation.delegationId);
|
|
26927
27443
|
}
|
|
26928
27444
|
}
|
|
26929
|
-
for (const
|
|
26930
|
-
this.#validateGlobal(
|
|
26931
|
-
this.#createRequests.set(
|
|
26932
|
-
if (
|
|
26933
|
-
this.#nativeSessions.set(nativeSessionKey(
|
|
27445
|
+
for (const record5 of this.#records.values()) {
|
|
27446
|
+
this.#validateGlobal(record5, record5.hostThreadId);
|
|
27447
|
+
this.#createRequests.set(record5.createRequestId, record5.hostThreadId);
|
|
27448
|
+
if (record5.nativeSessionRef && !record5.subagent) {
|
|
27449
|
+
this.#nativeSessions.set(nativeSessionKey(record5.nativeSessionRef), record5.hostThreadId);
|
|
26934
27450
|
}
|
|
26935
|
-
for (const mapping of
|
|
26936
|
-
this.#hostTurns.set(mapping.hostTurnId,
|
|
27451
|
+
for (const mapping of record5.turnMappings) {
|
|
27452
|
+
this.#hostTurns.set(mapping.hostTurnId, record5.hostThreadId);
|
|
26937
27453
|
this.#nativeTurns.set(nativeTurnKey(mapping), mapping.hostTurnId);
|
|
26938
27454
|
}
|
|
26939
27455
|
}
|
|
@@ -28364,16 +28880,16 @@ function planFromTodoValue(value2) {
|
|
|
28364
28880
|
return fromText;
|
|
28365
28881
|
}
|
|
28366
28882
|
}
|
|
28367
|
-
const
|
|
28368
|
-
if (!
|
|
28883
|
+
const record5 = unwrapToolRecord(value2);
|
|
28884
|
+
if (!record5)
|
|
28369
28885
|
return planFromChecklistText(typeof value2 === "string" ? value2 : null);
|
|
28370
|
-
if (isRecord10(
|
|
28371
|
-
const nested = planFromTodoValue(
|
|
28886
|
+
if (isRecord10(record5.TodosUpdated)) {
|
|
28887
|
+
const nested = planFromTodoValue(record5.TodosUpdated);
|
|
28372
28888
|
if (nested)
|
|
28373
28889
|
return nested;
|
|
28374
28890
|
}
|
|
28375
|
-
const explanation = nestedString(
|
|
28376
|
-
const list = coerceTodoList(
|
|
28891
|
+
const explanation = nestedString(record5, ["explanation", "message", "summary"]) ?? null;
|
|
28892
|
+
const list = coerceTodoList(record5.todos ?? record5.items ?? record5.plan ?? record5.tasks ?? record5.entries);
|
|
28377
28893
|
if (!list || list.length === 0)
|
|
28378
28894
|
return planFromChecklistText(explanation);
|
|
28379
28895
|
const plan = [];
|
|
@@ -28403,8 +28919,8 @@ function coerceTodoList(value2) {
|
|
|
28403
28919
|
const parsed2 = JSON.parse(trimmed);
|
|
28404
28920
|
if (Array.isArray(parsed2))
|
|
28405
28921
|
return parsed2;
|
|
28406
|
-
const
|
|
28407
|
-
return
|
|
28922
|
+
const record5 = unwrapToolRecord(parsed2);
|
|
28923
|
+
return record5 ? coerceTodoList(record5.todos ?? record5.items ?? record5.plan ?? record5.tasks ?? record5.entries) : null;
|
|
28408
28924
|
} catch {
|
|
28409
28925
|
return planFromChecklistText(trimmed)?.plan.map(({ step, status: status2 }) => ({ content: step, status: status2 })) ?? null;
|
|
28410
28926
|
}
|
|
@@ -30169,10 +30685,12 @@ function decodeCreateRoute(request) {
|
|
|
30169
30685
|
return null;
|
|
30170
30686
|
const pluginRoute = decodeHarnessPluginRoute(request.params.model);
|
|
30171
30687
|
if (pluginRoute) {
|
|
30688
|
+
const { prewarm, ...selection } = pluginRoute;
|
|
30172
30689
|
return {
|
|
30173
30690
|
harnessId: pluginRoute.harnessId,
|
|
30174
30691
|
routeMode: "native",
|
|
30175
|
-
transportModelId: request.params.model,
|
|
30692
|
+
transportModelId: prewarm ? encodeHarnessPluginRoute(selection) : request.params.model,
|
|
30693
|
+
...prewarm ? { prewarm } : {},
|
|
30176
30694
|
...pluginRoute.model ? { model: pluginRoute.model } : {},
|
|
30177
30695
|
...pluginRoute.thinkingOptionId ? { thinkingOptionId: pluginRoute.thinkingOptionId } : {},
|
|
30178
30696
|
...pluginRoute.permissionModeId ? { permissionModeId: pluginRoute.permissionModeId } : {}
|
|
@@ -30489,7 +31007,7 @@ import { open as open8, realpath as realpath4 } from "node:fs/promises";
|
|
|
30489
31007
|
import path21 from "node:path";
|
|
30490
31008
|
var MAX_METADATA_BYTES = 1024 * 1024;
|
|
30491
31009
|
var REFERENCE_READ_TIMEOUT_MS = 2e3;
|
|
30492
|
-
var
|
|
31010
|
+
var record4 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
30493
31011
|
async function nativeThreadSupportsReferences(input) {
|
|
30494
31012
|
try {
|
|
30495
31013
|
let timer;
|
|
@@ -30499,8 +31017,8 @@ async function nativeThreadSupportsReferences(input) {
|
|
|
30499
31017
|
timer = setTimeout(() => resolve(null), REFERENCE_READ_TIMEOUT_MS);
|
|
30500
31018
|
})
|
|
30501
31019
|
]).finally(() => clearTimeout(timer));
|
|
30502
|
-
const result =
|
|
30503
|
-
const thread = result &&
|
|
31020
|
+
const result = record4(response) && record4(response.result) ? response.result : null;
|
|
31021
|
+
const thread = result && record4(result.thread) ? result.thread : null;
|
|
30504
31022
|
if (thread?.id !== input.threadId || typeof thread.path !== "string") return false;
|
|
30505
31023
|
const rollout = await realpath4(thread.path);
|
|
30506
31024
|
let allowed = false;
|
|
@@ -30522,13 +31040,13 @@ async function nativeThreadSupportsReferences(input) {
|
|
|
30522
31040
|
const newline2 = bytes.subarray(0, bytesRead).indexOf(10);
|
|
30523
31041
|
if (newline2 < 0) return false;
|
|
30524
31042
|
const line = JSON.parse(bytes.subarray(0, newline2).toString("utf8"));
|
|
30525
|
-
if (!
|
|
31043
|
+
if (!record4(line) || line.type !== "session_meta" || !record4(line.payload)) return false;
|
|
30526
31044
|
const metadata = line.payload;
|
|
30527
31045
|
if (metadata.id !== input.threadId || !Array.isArray(metadata.dynamic_tools)) return false;
|
|
30528
31046
|
return metadata.dynamic_tools.some((tool) => {
|
|
30529
|
-
if (!
|
|
31047
|
+
if (!record4(tool)) return false;
|
|
30530
31048
|
if (tool.type === "namespace") {
|
|
30531
|
-
return tool.name === "codex_app" && Array.isArray(tool.tools) && tool.tools.some((item) =>
|
|
31049
|
+
return tool.name === "codex_app" && Array.isArray(tool.tools) && tool.tools.some((item) => record4(item) && item.name === "read_thread");
|
|
30532
31050
|
}
|
|
30533
31051
|
return tool.name === "read_thread";
|
|
30534
31052
|
});
|
|
@@ -30640,7 +31158,7 @@ var HarnessAccountInspectionCache = class {
|
|
|
30640
31158
|
};
|
|
30641
31159
|
|
|
30642
31160
|
// packages/host-runtime/src/app-server-host.ts
|
|
30643
|
-
import { createHash as createHash9, randomUUID as
|
|
31161
|
+
import { createHash as createHash9, randomUUID as randomUUID17 } from "node:crypto";
|
|
30644
31162
|
import os8 from "node:os";
|
|
30645
31163
|
import path25 from "node:path";
|
|
30646
31164
|
|
|
@@ -30667,21 +31185,21 @@ function subagentMaterializer(store, parent, previousParent) {
|
|
|
30667
31185
|
const legacyRecords = () => legacy ??= store.listThreads().then((records) => {
|
|
30668
31186
|
const byRequest = /* @__PURE__ */ new Map();
|
|
30669
31187
|
const children = /* @__PURE__ */ new Map();
|
|
30670
|
-
for (const
|
|
30671
|
-
if (!
|
|
31188
|
+
for (const record5 of records) {
|
|
31189
|
+
if (!record5.subagent || record5.harnessId !== parent.harnessId || !record5.nativeSessionRef)
|
|
30672
31190
|
continue;
|
|
30673
31191
|
const owner = {
|
|
30674
|
-
hostThreadId:
|
|
30675
|
-
harnessId:
|
|
31192
|
+
hostThreadId: record5.subagent.parentHostThreadId,
|
|
31193
|
+
harnessId: record5.harnessId
|
|
30676
31194
|
};
|
|
30677
31195
|
const key = childCreateRequest(
|
|
30678
31196
|
owner,
|
|
30679
|
-
|
|
30680
|
-
|
|
31197
|
+
record5.nativeSessionRef,
|
|
31198
|
+
record5.subagent.nativeSubagentId
|
|
30681
31199
|
);
|
|
30682
|
-
if (!byRequest.has(key) ||
|
|
31200
|
+
if (!byRequest.has(key) || record5.state === "ready") byRequest.set(key, record5);
|
|
30683
31201
|
const siblings = children.get(owner.hostThreadId) ?? [];
|
|
30684
|
-
siblings.push(
|
|
31202
|
+
siblings.push(record5);
|
|
30685
31203
|
children.set(owner.hostThreadId, siblings);
|
|
30686
31204
|
}
|
|
30687
31205
|
return { byRequest, children };
|
|
@@ -30751,11 +31269,11 @@ function subagentMaterializer(store, parent, previousParent) {
|
|
|
30751
31269
|
async function materializeExternalSubagent(store, parent, child) {
|
|
30752
31270
|
return subagentMaterializer(store, parent)(child);
|
|
30753
31271
|
}
|
|
30754
|
-
async function projectExternalSnapshot(store,
|
|
30755
|
-
const materialize = subagentMaterializer(store,
|
|
31272
|
+
async function projectExternalSnapshot(store, record5, snapshot2, previousParent) {
|
|
31273
|
+
const materialize = subagentMaterializer(store, record5, previousParent);
|
|
30756
31274
|
const turns = [];
|
|
30757
31275
|
for (const [index, turn] of snapshot2.turns.entries()) {
|
|
30758
|
-
const mapping =
|
|
31276
|
+
const mapping = record5.turnMappings[index];
|
|
30759
31277
|
if (!mapping) throw new Error("External Snapshot mapping is incomplete");
|
|
30760
31278
|
const items = await Promise.all(
|
|
30761
31279
|
turn.items.map(async (entry) => {
|
|
@@ -30771,9 +31289,9 @@ async function projectExternalSnapshot(store, record4, snapshot2, previousParent
|
|
|
30771
31289
|
);
|
|
30772
31290
|
turns.push(
|
|
30773
31291
|
projectHistoricalTurn({
|
|
30774
|
-
threadId:
|
|
31292
|
+
threadId: record5.hostThreadId,
|
|
30775
31293
|
turnId: mapping.hostTurnId,
|
|
30776
|
-
cwd:
|
|
31294
|
+
cwd: record5.cwd,
|
|
30777
31295
|
snapshot: { ...turn, items }
|
|
30778
31296
|
})
|
|
30779
31297
|
);
|
|
@@ -30880,11 +31398,11 @@ var ExternalThreadRepository = class {
|
|
|
30880
31398
|
removeThread(hostThreadId) {
|
|
30881
31399
|
return this.store.removeThread(hostThreadId);
|
|
30882
31400
|
}
|
|
30883
|
-
async persistTurn(
|
|
30884
|
-
if (
|
|
31401
|
+
async persistTurn(record5, hostTurnId, nativeTurnRef, nativeCheckpointRef) {
|
|
31402
|
+
if (record5.state !== "ready" || !record5.nativeSessionRef || nativeTurnRef.harnessId !== record5.harnessId || nativeTurnRef.nativeSessionId !== record5.nativeSessionRef.nativeSessionId || nativeCheckpointRef && (nativeCheckpointRef.harnessId !== record5.harnessId || nativeCheckpointRef.nativeSessionId !== record5.nativeSessionRef.nativeSessionId)) {
|
|
30885
31403
|
throw new Error("Live Turn identity does not belong to the stored Thread");
|
|
30886
31404
|
}
|
|
30887
|
-
return this.store.upsertTurnMappings(
|
|
31405
|
+
return this.store.upsertTurnMappings(record5.hostThreadId, [
|
|
30888
31406
|
{
|
|
30889
31407
|
hostTurnId,
|
|
30890
31408
|
nativeTurnRef,
|
|
@@ -30892,12 +31410,12 @@ var ExternalThreadRepository = class {
|
|
|
30892
31410
|
}
|
|
30893
31411
|
]);
|
|
30894
31412
|
}
|
|
30895
|
-
async commitDerivedSnapshot(
|
|
30896
|
-
if (
|
|
31413
|
+
async commitDerivedSnapshot(record5, nativeSessionRef, snapshot2) {
|
|
31414
|
+
if (record5.state !== "creating" || record5.turnMappings.length !== 0) {
|
|
30897
31415
|
throw new Error("Derived Thread must be provisional before Snapshot commit");
|
|
30898
31416
|
}
|
|
30899
31417
|
const mappings = snapshot2.turns.map((turn) => {
|
|
30900
|
-
if (turn.nativeTurnRef.harnessId !==
|
|
31418
|
+
if (turn.nativeTurnRef.harnessId !== record5.harnessId || turn.nativeTurnRef.nativeSessionId !== nativeSessionRef.nativeSessionId || turn.checkpoint && (turn.checkpoint.harnessId !== record5.harnessId || turn.checkpoint.nativeSessionId !== nativeSessionRef.nativeSessionId)) {
|
|
30901
31419
|
throw new Error("Derived Snapshot identity does not belong to its Native Session");
|
|
30902
31420
|
}
|
|
30903
31421
|
return {
|
|
@@ -30907,7 +31425,7 @@ var ExternalThreadRepository = class {
|
|
|
30907
31425
|
};
|
|
30908
31426
|
});
|
|
30909
31427
|
const nextRecord = await this.store.commitReady({
|
|
30910
|
-
hostThreadId:
|
|
31428
|
+
hostThreadId: record5.hostThreadId,
|
|
30911
31429
|
nativeSessionRef,
|
|
30912
31430
|
turnMappings: mappings
|
|
30913
31431
|
});
|
|
@@ -30988,8 +31506,8 @@ var ExternalThreadRepository = class {
|
|
|
30988
31506
|
turns: await projectExternalSnapshot(this.store, nextRecord, snapshot2, current)
|
|
30989
31507
|
};
|
|
30990
31508
|
}
|
|
30991
|
-
async sessionTreeId(
|
|
30992
|
-
let current =
|
|
31509
|
+
async sessionTreeId(record5) {
|
|
31510
|
+
let current = record5;
|
|
30993
31511
|
const visited = /* @__PURE__ */ new Set();
|
|
30994
31512
|
while (current.subagent || current.forkSource) {
|
|
30995
31513
|
if (visited.has(current.hostThreadId))
|
|
@@ -31003,21 +31521,21 @@ var ExternalThreadRepository = class {
|
|
|
31003
31521
|
}
|
|
31004
31522
|
return current.hostThreadId;
|
|
31005
31523
|
}
|
|
31006
|
-
async alignSnapshot(
|
|
31007
|
-
const nativeSessionRef =
|
|
31008
|
-
if (
|
|
31009
|
-
return { record:
|
|
31524
|
+
async alignSnapshot(record5, snapshot2) {
|
|
31525
|
+
const nativeSessionRef = record5.nativeSessionRef;
|
|
31526
|
+
if (record5.state === "creating" && !nativeSessionRef && snapshot2.turns.length === 0) {
|
|
31527
|
+
return { record: record5, turns: [] };
|
|
31010
31528
|
}
|
|
31011
|
-
if (!nativeSessionRef ||
|
|
31529
|
+
if (!nativeSessionRef || record5.state !== "ready") {
|
|
31012
31530
|
throw new Error("External Thread has no committed Native Session identity");
|
|
31013
31531
|
}
|
|
31014
31532
|
for (const turn of snapshot2.turns) {
|
|
31015
|
-
if (turn.nativeTurnRef.harnessId !==
|
|
31533
|
+
if (turn.nativeTurnRef.harnessId !== record5.harnessId || turn.nativeTurnRef.nativeSessionId !== nativeSessionRef.nativeSessionId || turn.checkpoint && (turn.checkpoint.harnessId !== record5.harnessId || turn.checkpoint.nativeSessionId !== nativeSessionRef.nativeSessionId)) {
|
|
31016
31534
|
throw new Error("External Snapshot identity does not belong to the stored Thread");
|
|
31017
31535
|
}
|
|
31018
31536
|
}
|
|
31019
31537
|
const mappingsByNative = new Map(
|
|
31020
|
-
|
|
31538
|
+
record5.turnMappings.map(
|
|
31021
31539
|
(mapping) => [nativeTurnKey2(mapping.nativeTurnRef), mapping]
|
|
31022
31540
|
)
|
|
31023
31541
|
);
|
|
@@ -31038,11 +31556,11 @@ var ExternalThreadRepository = class {
|
|
|
31038
31556
|
};
|
|
31039
31557
|
});
|
|
31040
31558
|
const orderedMappings = aligned.map(({ mapping }) => mapping);
|
|
31041
|
-
const mappingsChanged = orderedMappings.length !==
|
|
31042
|
-
const persisted =
|
|
31559
|
+
const mappingsChanged = orderedMappings.length !== record5.turnMappings.length || orderedMappings.some((mapping, index) => {
|
|
31560
|
+
const persisted = record5.turnMappings[index];
|
|
31043
31561
|
return !persisted || !sameMapping(mapping, persisted);
|
|
31044
31562
|
});
|
|
31045
|
-
const nextRecord = mappingsChanged ? await this.store.reconcileTurnMappings(
|
|
31563
|
+
const nextRecord = mappingsChanged ? await this.store.reconcileTurnMappings(record5.hostThreadId, orderedMappings) : record5;
|
|
31046
31564
|
return {
|
|
31047
31565
|
record: nextRecord,
|
|
31048
31566
|
turns: await projectExternalSnapshot(this.store, nextRecord, snapshot2)
|
|
@@ -31070,9 +31588,9 @@ function threadSectionFields(placement) {
|
|
|
31070
31588
|
} : { section: null, sectionEnteredAt: null };
|
|
31071
31589
|
}
|
|
31072
31590
|
function externalThreadValue(input) {
|
|
31073
|
-
const { record:
|
|
31074
|
-
const createdAt = Math.floor(Date.parse(
|
|
31075
|
-
const updatedAt = Math.floor(Date.parse(
|
|
31591
|
+
const { record: record5 } = input;
|
|
31592
|
+
const createdAt = Math.floor(Date.parse(record5.createdAt) / 1e3);
|
|
31593
|
+
const updatedAt = Math.floor(Date.parse(record5.updatedAt) / 1e3);
|
|
31076
31594
|
const preview = input.turns.flatMap((turn) => Array.isArray(turn.items) ? turn.items : []).find(
|
|
31077
31595
|
(item) => typeof item === "object" && item !== null && !Array.isArray(item) && item.type === "userMessage"
|
|
31078
31596
|
);
|
|
@@ -31081,22 +31599,22 @@ function externalThreadValue(input) {
|
|
|
31081
31599
|
(part) => typeof part === "object" && part !== null && !Array.isArray(part) && part.type === "text"
|
|
31082
31600
|
).map((part) => typeof part.text === "string" ? part.text : "").join("\n") : "";
|
|
31083
31601
|
return {
|
|
31084
|
-
id:
|
|
31602
|
+
id: record5.hostThreadId,
|
|
31085
31603
|
sessionId: input.sessionId,
|
|
31086
31604
|
path: null,
|
|
31087
|
-
cwd:
|
|
31088
|
-
source:
|
|
31605
|
+
cwd: record5.cwd,
|
|
31606
|
+
source: record5.subagent ? {
|
|
31089
31607
|
subAgent: {
|
|
31090
31608
|
thread_spawn: {
|
|
31091
|
-
parent_thread_id:
|
|
31609
|
+
parent_thread_id: record5.subagent.parentHostThreadId,
|
|
31092
31610
|
depth: 1,
|
|
31093
31611
|
agent_path: null,
|
|
31094
|
-
agent_nickname:
|
|
31095
|
-
agent_role:
|
|
31612
|
+
agent_nickname: record5.title || null,
|
|
31613
|
+
agent_role: record5.subagent.role ?? null
|
|
31096
31614
|
}
|
|
31097
31615
|
}
|
|
31098
31616
|
} : "vscode",
|
|
31099
|
-
threadSource:
|
|
31617
|
+
threadSource: record5.subagent ? "subAgentThreadSpawn" : null,
|
|
31100
31618
|
modelProvider: "codexhost",
|
|
31101
31619
|
cliVersion: "codexhost",
|
|
31102
31620
|
createdAt,
|
|
@@ -31105,23 +31623,23 @@ function externalThreadValue(input) {
|
|
|
31105
31623
|
status: input.loaded === false ? { type: "notLoaded" } : input.running ? { type: "active", activeFlags: [] } : { type: "idle" },
|
|
31106
31624
|
turns: input.turns,
|
|
31107
31625
|
preview: previewText,
|
|
31108
|
-
name:
|
|
31109
|
-
gitInfo:
|
|
31110
|
-
branch:
|
|
31111
|
-
originUrl:
|
|
31112
|
-
sha:
|
|
31626
|
+
name: record5.title || null,
|
|
31627
|
+
gitInfo: record5.gitInfo ? {
|
|
31628
|
+
branch: record5.gitInfo.branch ?? null,
|
|
31629
|
+
originUrl: record5.gitInfo.originUrl ?? null,
|
|
31630
|
+
sha: record5.gitInfo.sha ?? null
|
|
31113
31631
|
} : null,
|
|
31114
|
-
forkedFromId:
|
|
31115
|
-
parentThreadId:
|
|
31116
|
-
ephemeral:
|
|
31117
|
-
canAcceptDirectInput:
|
|
31118
|
-
historyMode:
|
|
31632
|
+
forkedFromId: record5.forkSource?.hostThreadId ?? null,
|
|
31633
|
+
parentThreadId: record5.subagent?.parentHostThreadId ?? null,
|
|
31634
|
+
ephemeral: record5.ephemeral,
|
|
31635
|
+
canAcceptDirectInput: record5.subagent ? false : input.loaded === false ? null : true,
|
|
31636
|
+
historyMode: record5.historyMode,
|
|
31119
31637
|
isPinned: false,
|
|
31120
|
-
projectId:
|
|
31121
|
-
daybreakEnabled:
|
|
31638
|
+
projectId: record5.projectId ?? null,
|
|
31639
|
+
daybreakEnabled: record5.daybreakEnabled ?? null,
|
|
31122
31640
|
...threadSectionFields(input.placement),
|
|
31123
|
-
agentNickname:
|
|
31124
|
-
agentRole:
|
|
31641
|
+
agentNickname: record5.subagent ? record5.title || null : null,
|
|
31642
|
+
agentRole: record5.subagent?.role ?? null,
|
|
31125
31643
|
extra: null
|
|
31126
31644
|
};
|
|
31127
31645
|
}
|
|
@@ -31360,14 +31878,14 @@ async function settleExternalOutputFailure(thread, error51, project2, diagnose)
|
|
|
31360
31878
|
function fixedError(code, message2) {
|
|
31361
31879
|
return { code, message: message2 };
|
|
31362
31880
|
}
|
|
31363
|
-
function importedThread(
|
|
31881
|
+
function importedThread(record5) {
|
|
31364
31882
|
return {
|
|
31365
31883
|
ok: true,
|
|
31366
|
-
threadId:
|
|
31884
|
+
threadId: record5.hostThreadId,
|
|
31367
31885
|
thread: externalThreadValue({
|
|
31368
|
-
record:
|
|
31886
|
+
record: record5,
|
|
31369
31887
|
turns: [],
|
|
31370
|
-
sessionId:
|
|
31888
|
+
sessionId: record5.hostThreadId,
|
|
31371
31889
|
loaded: false
|
|
31372
31890
|
})
|
|
31373
31891
|
};
|
|
@@ -31388,7 +31906,7 @@ var HarnessSessionImporter = class {
|
|
|
31388
31906
|
}
|
|
31389
31907
|
#mappedRecord(records, nativeSessionId) {
|
|
31390
31908
|
return records.find(
|
|
31391
|
-
(
|
|
31909
|
+
(record5) => !record5.subagent && record5.state === "ready" && record5.nativeSessionRef?.harnessId === this.#harnessId && record5.nativeSessionRef.nativeSessionId === nativeSessionId
|
|
31392
31910
|
);
|
|
31393
31911
|
}
|
|
31394
31912
|
#unavailable() {
|
|
@@ -31407,7 +31925,7 @@ var HarnessSessionImporter = class {
|
|
|
31407
31925
|
}
|
|
31408
31926
|
const mapped = new Set(
|
|
31409
31927
|
(await this.#repository.list()).flatMap(
|
|
31410
|
-
(
|
|
31928
|
+
(record5) => !record5.subagent && record5.state === "ready" && record5.nativeSessionRef?.harnessId === this.#harnessId ? [record5.nativeSessionRef.nativeSessionId] : []
|
|
31411
31929
|
)
|
|
31412
31930
|
);
|
|
31413
31931
|
const superseded = this.#repository.supersededNativeSessionIds(this.#harnessId);
|
|
@@ -31499,8 +32017,8 @@ var HarnessSessionImporter = class {
|
|
|
31499
32017
|
return { ok: false, error: fixedError(-32081, "Session import could not be persisted") };
|
|
31500
32018
|
}
|
|
31501
32019
|
try {
|
|
31502
|
-
const
|
|
31503
|
-
return importedThread(
|
|
32020
|
+
const record5 = await this.#repository.commitNative(provisional.hostThreadId, ref.data, []);
|
|
32021
|
+
return importedThread(record5);
|
|
31504
32022
|
} catch (error51) {
|
|
31505
32023
|
await this.#repository.removeProvisional(provisional.hostThreadId).catch((cleanupError) => this.#diagnose(cleanupError));
|
|
31506
32024
|
if (error51 instanceof MappingStoreError && error51.code === "DUPLICATE_NATIVE_SESSION") {
|
|
@@ -32938,9 +33456,9 @@ var ExternalThreadRuntime = class {
|
|
|
32938
33456
|
async #retireSubagents(parent, bestEffort = false) {
|
|
32939
33457
|
const parentId = parent.id;
|
|
32940
33458
|
const ancestors = /* @__PURE__ */ new Map();
|
|
32941
|
-
const descendant = async (
|
|
33459
|
+
const descendant = async (record5) => {
|
|
32942
33460
|
const visited = /* @__PURE__ */ new Set();
|
|
32943
|
-
let ownerId =
|
|
33461
|
+
let ownerId = record5?.subagent?.parentHostThreadId;
|
|
32944
33462
|
while (ownerId && !visited.has(ownerId)) {
|
|
32945
33463
|
if (ownerId === parentId) return true;
|
|
32946
33464
|
visited.add(ownerId);
|
|
@@ -32988,23 +33506,23 @@ var ExternalThreadRuntime = class {
|
|
|
32988
33506
|
if (failure) return { kind: "error", error: { code: -32075, message: failure } };
|
|
32989
33507
|
return { kind: "external", record: loaded.record, thread: loaded };
|
|
32990
33508
|
}
|
|
32991
|
-
let
|
|
33509
|
+
let record5;
|
|
32992
33510
|
try {
|
|
32993
|
-
|
|
33511
|
+
record5 = await this.#repository.find(threadId2);
|
|
32994
33512
|
} catch {
|
|
32995
33513
|
return {
|
|
32996
33514
|
kind: "error",
|
|
32997
33515
|
error: { code: -32081, message: "External Thread ownership could not be read" }
|
|
32998
33516
|
};
|
|
32999
33517
|
}
|
|
33000
|
-
if (!
|
|
33001
|
-
if (
|
|
33518
|
+
if (!record5) return { kind: "official" };
|
|
33519
|
+
if (record5.state !== "ready" || !record5.nativeSessionRef) {
|
|
33002
33520
|
return {
|
|
33003
33521
|
kind: "error",
|
|
33004
33522
|
error: { code: -32079, message: "External Native Session is unavailable" }
|
|
33005
33523
|
};
|
|
33006
33524
|
}
|
|
33007
|
-
return { kind: "external", record:
|
|
33525
|
+
return { kind: "external", record: record5, thread: null };
|
|
33008
33526
|
}
|
|
33009
33527
|
async resolve(threadId2) {
|
|
33010
33528
|
try {
|
|
@@ -33215,16 +33733,16 @@ var ExternalThreadRuntime = class {
|
|
|
33215
33733
|
return failure;
|
|
33216
33734
|
}
|
|
33217
33735
|
}
|
|
33218
|
-
async #restore(
|
|
33219
|
-
const harnessId =
|
|
33736
|
+
async #restore(record5) {
|
|
33737
|
+
const harnessId = record5.harnessId;
|
|
33220
33738
|
const adapter = this.#adapters.get(harnessId);
|
|
33221
|
-
if (!adapter || !
|
|
33739
|
+
if (!adapter || !record5.nativeSessionRef) {
|
|
33222
33740
|
throw new ExternalThreadOpenError({
|
|
33223
33741
|
code: -32077,
|
|
33224
33742
|
message: "External Harness is unavailable"
|
|
33225
33743
|
});
|
|
33226
33744
|
}
|
|
33227
|
-
if (
|
|
33745
|
+
if (record5.subagent) {
|
|
33228
33746
|
const subagents = adapter.subagents;
|
|
33229
33747
|
if (!subagents) {
|
|
33230
33748
|
throw new ExternalThreadOpenError({
|
|
@@ -33232,14 +33750,14 @@ var ExternalThreadRuntime = class {
|
|
|
33232
33750
|
message: "External Harness Subagent history is unavailable"
|
|
33233
33751
|
});
|
|
33234
33752
|
}
|
|
33235
|
-
const subagent =
|
|
33236
|
-
const parent =
|
|
33753
|
+
const subagent = record5.subagent;
|
|
33754
|
+
const parent = record5.nativeSessionRef;
|
|
33237
33755
|
const snapshot2 = await subagents.readSnapshot({
|
|
33238
33756
|
parent,
|
|
33239
33757
|
nativeSubagentId: subagent.nativeSubagentId,
|
|
33240
|
-
cwd:
|
|
33758
|
+
cwd: record5.cwd
|
|
33241
33759
|
});
|
|
33242
|
-
const latest = await this.#repository.find(
|
|
33760
|
+
const latest = await this.#repository.find(record5.hostThreadId);
|
|
33243
33761
|
if (latest?.state === "ready" && latest.nativeSessionRef && JSON.stringify(latest.nativeSessionRef) !== JSON.stringify(parent)) {
|
|
33244
33762
|
return this.#restore(latest);
|
|
33245
33763
|
}
|
|
@@ -33247,16 +33765,16 @@ var ExternalThreadRuntime = class {
|
|
|
33247
33765
|
throw new ExternalThreadOpenError(mapExternalThreadHarnessError(snapshot2.error, "read"));
|
|
33248
33766
|
}
|
|
33249
33767
|
const session2 = new ReadonlySnapshotSession(
|
|
33250
|
-
|
|
33251
|
-
|
|
33768
|
+
record5.harnessId,
|
|
33769
|
+
record5.nativeSessionRef,
|
|
33252
33770
|
snapshot2.value,
|
|
33253
33771
|
() => subagents.readSnapshot({
|
|
33254
33772
|
parent,
|
|
33255
33773
|
nativeSubagentId: subagent.nativeSubagentId,
|
|
33256
|
-
cwd:
|
|
33774
|
+
cwd: record5.cwd
|
|
33257
33775
|
})
|
|
33258
33776
|
);
|
|
33259
|
-
const aligned = await this.#repository.alignSnapshot(
|
|
33777
|
+
const aligned = await this.#repository.alignSnapshot(record5, snapshot2.value);
|
|
33260
33778
|
const sessionId = await this.#repository.sessionTreeId(aligned.record);
|
|
33261
33779
|
return this.register({
|
|
33262
33780
|
record: aligned.record,
|
|
@@ -33267,13 +33785,13 @@ var ExternalThreadRuntime = class {
|
|
|
33267
33785
|
...snapshot2.value.state ? { restoredState: snapshot2.value.state } : {}
|
|
33268
33786
|
});
|
|
33269
33787
|
}
|
|
33270
|
-
const restoredSelection = decodeExternalTransportSelection(harnessId,
|
|
33788
|
+
const restoredSelection = decodeExternalTransportSelection(harnessId, record5.transportModelId);
|
|
33271
33789
|
const opened = await adapter.open({
|
|
33272
33790
|
kind: "resume",
|
|
33273
|
-
cwd:
|
|
33274
|
-
environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]:
|
|
33275
|
-
nativeRef:
|
|
33276
|
-
knownTurnRefs:
|
|
33791
|
+
cwd: record5.cwd,
|
|
33792
|
+
environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: record5.hostThreadId },
|
|
33793
|
+
nativeRef: record5.nativeSessionRef,
|
|
33794
|
+
knownTurnRefs: record5.turnMappings.map(({ nativeTurnRef }) => nativeTurnRef),
|
|
33277
33795
|
...restoredSelection?.model ? { model: restoredSelection.model } : {},
|
|
33278
33796
|
...restoredSelection?.thinkingOptionId ? { thinkingOptionId: restoredSelection.thinkingOptionId } : {},
|
|
33279
33797
|
...restoredSelection?.permissionModeId ? { permissionModeId: restoredSelection.permissionModeId } : {}
|
|
@@ -33287,7 +33805,7 @@ var ExternalThreadRuntime = class {
|
|
|
33287
33805
|
if (!snapshot2.ok) {
|
|
33288
33806
|
throw new ExternalThreadOpenError(mapExternalThreadHarnessError(snapshot2.error, "read"));
|
|
33289
33807
|
}
|
|
33290
|
-
let aligned = await this.#repository.alignSnapshot(
|
|
33808
|
+
let aligned = await this.#repository.alignSnapshot(record5, snapshot2.value);
|
|
33291
33809
|
const restoredState = snapshot2.value.state;
|
|
33292
33810
|
const effectiveModel = restoredState ? restoredState.effectiveModel : restoredSelection?.model;
|
|
33293
33811
|
const effectiveThinkingOptionId = restoredState ? restoredState.effectiveThinkingOptionId : restoredSelection?.thinkingOptionId;
|
|
@@ -33333,14 +33851,136 @@ var ExternalThreadRuntime = class {
|
|
|
33333
33851
|
});
|
|
33334
33852
|
} catch (error51) {
|
|
33335
33853
|
if (error51 instanceof ExternalSessionReleaseError) throw error51;
|
|
33336
|
-
await this.#lifecycle.release(
|
|
33854
|
+
await this.#lifecycle.release(record5.hostThreadId, session, Promise.resolve());
|
|
33337
33855
|
throw error51;
|
|
33338
33856
|
}
|
|
33339
33857
|
}
|
|
33340
33858
|
};
|
|
33341
33859
|
|
|
33342
|
-
// packages/host-runtime/src/external-
|
|
33860
|
+
// packages/host-runtime/src/external-thread-queue.ts
|
|
33343
33861
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
33862
|
+
var ExternalQueueError = class extends Error {
|
|
33863
|
+
constructor(code, message2) {
|
|
33864
|
+
super(message2);
|
|
33865
|
+
this.code = code;
|
|
33866
|
+
}
|
|
33867
|
+
code;
|
|
33868
|
+
};
|
|
33869
|
+
var publicSubmission = ({
|
|
33870
|
+
id: id2,
|
|
33871
|
+
input,
|
|
33872
|
+
clientUserMessageId
|
|
33873
|
+
}) => ({
|
|
33874
|
+
id: id2,
|
|
33875
|
+
input,
|
|
33876
|
+
clientUserMessageId
|
|
33877
|
+
});
|
|
33878
|
+
var DEFAULT_PAGE_SIZE3 = 50;
|
|
33879
|
+
var ExternalThreadQueue = class {
|
|
33880
|
+
#queues = /* @__PURE__ */ new Map();
|
|
33881
|
+
#notifyChanged;
|
|
33882
|
+
#createId;
|
|
33883
|
+
constructor(options2) {
|
|
33884
|
+
this.#notifyChanged = options2.notifyChanged;
|
|
33885
|
+
this.#createId = options2.createId ?? randomUUID12;
|
|
33886
|
+
}
|
|
33887
|
+
has(threadId2) {
|
|
33888
|
+
return (this.#queues.get(threadId2)?.length ?? 0) > 0;
|
|
33889
|
+
}
|
|
33890
|
+
list(threadId2, params) {
|
|
33891
|
+
const items = this.#queues.get(threadId2) ?? [];
|
|
33892
|
+
const start = params.cursor == null ? 0 : Number(params.cursor);
|
|
33893
|
+
if (!Number.isSafeInteger(start) || start < 0 || start > items.length) {
|
|
33894
|
+
throw new ExternalQueueError(-32602, "Invalid thread/queue/list cursor");
|
|
33895
|
+
}
|
|
33896
|
+
const limit = typeof params.limit === "number" && Number.isSafeInteger(params.limit) && params.limit > 0 ? params.limit : DEFAULT_PAGE_SIZE3;
|
|
33897
|
+
const end = Math.min(items.length, start + limit);
|
|
33898
|
+
return {
|
|
33899
|
+
data: items.slice(start, end).map((item) => publicSubmission(item)),
|
|
33900
|
+
nextCursor: end < items.length ? String(end) : null
|
|
33901
|
+
};
|
|
33902
|
+
}
|
|
33903
|
+
async add(threadId2, input, clientUserMessageId, sourceHostId) {
|
|
33904
|
+
const submission = { id: this.#createId(), input, clientUserMessageId, sourceHostId };
|
|
33905
|
+
this.#items(threadId2).push(submission);
|
|
33906
|
+
await this.#notifyChanged(threadId2);
|
|
33907
|
+
return publicSubmission(submission);
|
|
33908
|
+
}
|
|
33909
|
+
async update(threadId2, id2, input) {
|
|
33910
|
+
const items = this.#queues.get(threadId2) ?? [];
|
|
33911
|
+
const index = items.findIndex((item) => item.id === id2);
|
|
33912
|
+
const current = items[index];
|
|
33913
|
+
if (!current) throw new ExternalQueueError(-32602, "Queued submission was not found");
|
|
33914
|
+
const submission = { ...current, input };
|
|
33915
|
+
items[index] = submission;
|
|
33916
|
+
await this.#notifyChanged(threadId2);
|
|
33917
|
+
return publicSubmission(submission);
|
|
33918
|
+
}
|
|
33919
|
+
async delete(threadId2, id2) {
|
|
33920
|
+
const items = this.#queues.get(threadId2);
|
|
33921
|
+
const index = items?.findIndex((item) => item.id === id2) ?? -1;
|
|
33922
|
+
if (!items || index === -1) return false;
|
|
33923
|
+
items.splice(index, 1);
|
|
33924
|
+
this.#prune(threadId2);
|
|
33925
|
+
await this.#notifyChanged(threadId2);
|
|
33926
|
+
return true;
|
|
33927
|
+
}
|
|
33928
|
+
/** Listed IDs move to the front in the given order; unlisted entries keep their order. */
|
|
33929
|
+
async reorder(threadId2, ids) {
|
|
33930
|
+
const items = this.#queues.get(threadId2);
|
|
33931
|
+
if (!items) return;
|
|
33932
|
+
const byId = new Map(items.map((item) => [item.id, item]));
|
|
33933
|
+
const ordered = ids.flatMap((id2) => {
|
|
33934
|
+
const item = byId.get(id2);
|
|
33935
|
+
byId.delete(id2);
|
|
33936
|
+
return item ? [item] : [];
|
|
33937
|
+
});
|
|
33938
|
+
items.splice(0, items.length, ...ordered, ...byId.values());
|
|
33939
|
+
await this.#notifyChanged(threadId2);
|
|
33940
|
+
}
|
|
33941
|
+
/** Removes the submission a Turn is about to start; `restore` returns it if the start fails. */
|
|
33942
|
+
take(threadId2, id2) {
|
|
33943
|
+
const items = this.#queues.get(threadId2) ?? [];
|
|
33944
|
+
const index = id2 == null ? 0 : items.findIndex((item) => item.id === id2);
|
|
33945
|
+
const submission = index === -1 ? void 0 : items[index];
|
|
33946
|
+
if (!submission) throw new ExternalQueueError(-32602, "Queued submission was not found");
|
|
33947
|
+
items.splice(index, 1);
|
|
33948
|
+
this.#prune(threadId2);
|
|
33949
|
+
return {
|
|
33950
|
+
submission: publicSubmission(submission),
|
|
33951
|
+
sourceHostId: submission.sourceHostId,
|
|
33952
|
+
index
|
|
33953
|
+
};
|
|
33954
|
+
}
|
|
33955
|
+
restore(threadId2, taken) {
|
|
33956
|
+
const items = this.#items(threadId2);
|
|
33957
|
+
if (items.some((item) => item.id === taken.submission.id)) return;
|
|
33958
|
+
items.splice(Math.min(taken.index, items.length), 0, {
|
|
33959
|
+
...taken.submission,
|
|
33960
|
+
sourceHostId: taken.sourceHostId
|
|
33961
|
+
});
|
|
33962
|
+
}
|
|
33963
|
+
notifyChanged(threadId2) {
|
|
33964
|
+
return this.#notifyChanged(threadId2);
|
|
33965
|
+
}
|
|
33966
|
+
forget(threadId2) {
|
|
33967
|
+
this.#queues.delete(threadId2);
|
|
33968
|
+
}
|
|
33969
|
+
#items(threadId2) {
|
|
33970
|
+
let items = this.#queues.get(threadId2);
|
|
33971
|
+
if (!items) {
|
|
33972
|
+
items = [];
|
|
33973
|
+
this.#queues.set(threadId2, items);
|
|
33974
|
+
}
|
|
33975
|
+
return items;
|
|
33976
|
+
}
|
|
33977
|
+
#prune(threadId2) {
|
|
33978
|
+
if (this.#queues.get(threadId2)?.length === 0) this.#queues.delete(threadId2);
|
|
33979
|
+
}
|
|
33980
|
+
};
|
|
33981
|
+
|
|
33982
|
+
// packages/host-runtime/src/external-turn-steering.ts
|
|
33983
|
+
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
33344
33984
|
|
|
33345
33985
|
// packages/host-runtime/src/external-command-routing.ts
|
|
33346
33986
|
var ExternalCommandError = class extends Error {
|
|
@@ -33461,7 +34101,7 @@ async function insertNativeSteer(thread, input, host) {
|
|
|
33461
34101
|
thread.steeredTurnIds.add(input.turnId);
|
|
33462
34102
|
const item = {
|
|
33463
34103
|
type: "userMessage",
|
|
33464
|
-
itemId: hostItemIdSchema.parse(
|
|
34104
|
+
itemId: hostItemIdSchema.parse(randomUUID13()),
|
|
33465
34105
|
input: displayed
|
|
33466
34106
|
};
|
|
33467
34107
|
try {
|
|
@@ -33693,7 +34333,7 @@ function sameWorkspace(left, right) {
|
|
|
33693
34333
|
}
|
|
33694
34334
|
|
|
33695
34335
|
// packages/host-runtime/src/harness-delegation-coordinator.ts
|
|
33696
|
-
import { createHash as createHash8, randomUUID as
|
|
34336
|
+
import { createHash as createHash8, randomUUID as randomUUID14 } from "node:crypto";
|
|
33697
34337
|
import path24 from "node:path";
|
|
33698
34338
|
|
|
33699
34339
|
// packages/host-runtime/src/delegation-snapshot.ts
|
|
@@ -33997,11 +34637,11 @@ var HarnessDelegationCoordinator = class {
|
|
|
33997
34637
|
});
|
|
33998
34638
|
this.#validateConfiguration(inspected.inspection, input.model, input.thinkingOptionId);
|
|
33999
34639
|
}
|
|
34000
|
-
const delegationId = hostThreadIdSchema.parse(
|
|
34001
|
-
const childThreadId = hostThreadIdSchema.parse(
|
|
34002
|
-
const turnId = hostTurnIdSchema.parse(
|
|
34003
|
-
const createRequestId = input.requestId ? `delegation:${input.requestId}` :
|
|
34004
|
-
let
|
|
34640
|
+
const delegationId = hostThreadIdSchema.parse(randomUUID14());
|
|
34641
|
+
const childThreadId = hostThreadIdSchema.parse(randomUUID14());
|
|
34642
|
+
const turnId = hostTurnIdSchema.parse(randomUUID14());
|
|
34643
|
+
const createRequestId = input.requestId ? `delegation:${input.requestId}` : randomUUID14();
|
|
34644
|
+
let record5 = await this.#repository.createProvisional(
|
|
34005
34645
|
createExternalThreadRecordInput({
|
|
34006
34646
|
hostThreadId: childThreadId,
|
|
34007
34647
|
createRequestId,
|
|
@@ -34032,7 +34672,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
34032
34672
|
});
|
|
34033
34673
|
const opened = await adapter.open({
|
|
34034
34674
|
kind: "create",
|
|
34035
|
-
cwd:
|
|
34675
|
+
cwd: record5.cwd,
|
|
34036
34676
|
environment: { ...this.#environment, [DELEGATION_THREAD_ID_ENV]: childThreadId },
|
|
34037
34677
|
executionPolicy: "unattended-full-access",
|
|
34038
34678
|
...input.model ? { model: input.model } : {},
|
|
@@ -34041,21 +34681,21 @@ var HarnessDelegationCoordinator = class {
|
|
|
34041
34681
|
if (!opened.ok) throw new DelegationControlError("DELEGATION_FAILED", opened.error.message);
|
|
34042
34682
|
session = opened.value;
|
|
34043
34683
|
if (session.initialState.nativeRef) {
|
|
34044
|
-
|
|
34045
|
-
|
|
34684
|
+
record5 = await this.#repository.commitNative(
|
|
34685
|
+
record5.hostThreadId,
|
|
34046
34686
|
session.initialState.nativeRef
|
|
34047
34687
|
);
|
|
34048
34688
|
}
|
|
34049
34689
|
const threadValue = externalThreadValue({
|
|
34050
|
-
record:
|
|
34690
|
+
record: record5,
|
|
34051
34691
|
turns: [],
|
|
34052
|
-
sessionId:
|
|
34692
|
+
sessionId: record5.hostThreadId,
|
|
34053
34693
|
running: true
|
|
34054
34694
|
});
|
|
34055
34695
|
const thread = this.#registerExternalThread({
|
|
34056
|
-
record:
|
|
34696
|
+
record: record5,
|
|
34057
34697
|
session,
|
|
34058
|
-
sessionId:
|
|
34698
|
+
sessionId: record5.hostThreadId,
|
|
34059
34699
|
thread: threadValue,
|
|
34060
34700
|
turns: [],
|
|
34061
34701
|
...input.model ? { requestedModel: input.model } : {},
|
|
@@ -34112,7 +34752,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
34112
34752
|
} : {}
|
|
34113
34753
|
}
|
|
34114
34754
|
}),
|
|
34115
|
-
cwd:
|
|
34755
|
+
cwd: record5.cwd,
|
|
34116
34756
|
parentThreadId
|
|
34117
34757
|
};
|
|
34118
34758
|
} catch (error51) {
|
|
@@ -34154,7 +34794,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
34154
34794
|
if (this.#externalThreadBusy(thread) || thread.activeTurnId) {
|
|
34155
34795
|
throw new DelegationControlError("THREAD_BUSY", "Thread already has an active Turn");
|
|
34156
34796
|
}
|
|
34157
|
-
const turnId = hostTurnIdSchema.parse(
|
|
34797
|
+
const turnId = hostTurnIdSchema.parse(randomUUID14());
|
|
34158
34798
|
try {
|
|
34159
34799
|
await this.#startExternalTurn(thread, input.message, turnId);
|
|
34160
34800
|
} catch (error51) {
|
|
@@ -34261,19 +34901,19 @@ var HarnessDelegationCoordinator = class {
|
|
|
34261
34901
|
const parent = hostThreadIdSchema.parse(input.parentThreadId);
|
|
34262
34902
|
const delegations = await this.#repository.listDelegations(parent);
|
|
34263
34903
|
const records = await this.#repository.list();
|
|
34264
|
-
const byId = new Map(records.map((
|
|
34904
|
+
const byId = new Map(records.map((record5) => [record5.hostThreadId, record5]));
|
|
34265
34905
|
const rows = delegations.map((delegation) => {
|
|
34266
|
-
const
|
|
34906
|
+
const record5 = byId.get(delegation.childHostThreadId);
|
|
34267
34907
|
return {
|
|
34268
34908
|
threadId: delegation.childHostThreadId,
|
|
34269
34909
|
harnessId: delegation.targetHarnessId,
|
|
34270
34910
|
deepLink: `codex://threads/${delegation.childHostThreadId}`,
|
|
34271
34911
|
status: delegation.status,
|
|
34272
|
-
...
|
|
34273
|
-
cwd:
|
|
34274
|
-
title:
|
|
34275
|
-
createdAt:
|
|
34276
|
-
updatedAt:
|
|
34912
|
+
...record5 ? {
|
|
34913
|
+
cwd: record5.cwd,
|
|
34914
|
+
title: record5.title,
|
|
34915
|
+
createdAt: record5.createdAt,
|
|
34916
|
+
updatedAt: record5.updatedAt
|
|
34277
34917
|
} : {
|
|
34278
34918
|
createdAt: delegation.createdAt,
|
|
34279
34919
|
updatedAt: delegation.updatedAt
|
|
@@ -34367,19 +35007,19 @@ var HarnessDelegationCoordinator = class {
|
|
|
34367
35007
|
}
|
|
34368
35008
|
}
|
|
34369
35009
|
async #parentMetadata(parentThreadId) {
|
|
34370
|
-
const
|
|
34371
|
-
if (
|
|
35010
|
+
const record5 = await this.#repository.find(parentThreadId);
|
|
35011
|
+
if (record5)
|
|
34372
35012
|
return {
|
|
34373
|
-
harnessId:
|
|
34374
|
-
cwd:
|
|
34375
|
-
title:
|
|
35013
|
+
harnessId: record5.harnessId,
|
|
35014
|
+
cwd: record5.cwd,
|
|
35015
|
+
title: record5.title
|
|
34376
35016
|
};
|
|
34377
35017
|
const metadata = await this.#officialThreadMetadata(parentThreadId).catch(() => ({}));
|
|
34378
35018
|
return { harnessId: "codex", ...metadata };
|
|
34379
35019
|
}
|
|
34380
35020
|
async #existingResult(delegation) {
|
|
34381
|
-
const
|
|
34382
|
-
const turnId =
|
|
35021
|
+
const record5 = await this.#repository.find(delegation.childHostThreadId);
|
|
35022
|
+
const turnId = record5?.turnMappings.at(-1)?.hostTurnId ?? "pending";
|
|
34383
35023
|
return {
|
|
34384
35024
|
...this.#result(
|
|
34385
35025
|
delegation.delegationId,
|
|
@@ -34388,7 +35028,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
34388
35028
|
delegation.targetHarnessId,
|
|
34389
35029
|
delegation.status
|
|
34390
35030
|
),
|
|
34391
|
-
...
|
|
35031
|
+
...record5 ? { cwd: record5.cwd } : {},
|
|
34392
35032
|
parentThreadId: delegation.parentHostThreadId
|
|
34393
35033
|
};
|
|
34394
35034
|
}
|
|
@@ -36804,10 +37444,10 @@ var SingleNativeCodexAccount = class {
|
|
|
36804
37444
|
};
|
|
36805
37445
|
|
|
36806
37446
|
// packages/host-runtime/src/codex-runtime/official-runtime-owner.ts
|
|
36807
|
-
import { randomUUID as
|
|
37447
|
+
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
36808
37448
|
|
|
36809
37449
|
// packages/host-runtime/src/official-request-broker.ts
|
|
36810
|
-
import { randomUUID as
|
|
37450
|
+
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
36811
37451
|
var INTERNAL_REQUEST_PREFIX = "codexhost:official:";
|
|
36812
37452
|
var MAX_RETIRED_IDS = 1024;
|
|
36813
37453
|
function isRecord15(value2) {
|
|
@@ -36823,7 +37463,7 @@ var OfficialRequestBroker = class {
|
|
|
36823
37463
|
constructor(input) {
|
|
36824
37464
|
this.#send = input.send;
|
|
36825
37465
|
this.#timeoutMs = input.timeoutMs ?? 3e4;
|
|
36826
|
-
this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${
|
|
37466
|
+
this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${randomUUID15()}`);
|
|
36827
37467
|
}
|
|
36828
37468
|
get pendingCount() {
|
|
36829
37469
|
return this.#pending.size;
|
|
@@ -37177,7 +37817,7 @@ var OfficialRuntimeOwner = class {
|
|
|
37177
37817
|
}
|
|
37178
37818
|
#attach(role, output, onBackendStopped) {
|
|
37179
37819
|
const client = {
|
|
37180
|
-
id:
|
|
37820
|
+
id: randomUUID16(),
|
|
37181
37821
|
role,
|
|
37182
37822
|
output,
|
|
37183
37823
|
...onBackendStopped ? { onBackendStopped } : {},
|
|
@@ -37335,7 +37975,7 @@ var OfficialRuntimeOwner = class {
|
|
|
37335
37975
|
if (!object4(value2)) return client.output(event);
|
|
37336
37976
|
if (typeof value2.id === "string" || typeof value2.id === "number") {
|
|
37337
37977
|
if (typeof value2.method === "string") {
|
|
37338
|
-
const id2 = `codexhost:server:${client.id}:${event.generation}:${
|
|
37978
|
+
const id2 = `codexhost:server:${client.id}:${event.generation}:${randomUUID16()}`;
|
|
37339
37979
|
client.serverRequests.set(id2, value2.id);
|
|
37340
37980
|
const projected = { ...value2, id: id2 };
|
|
37341
37981
|
return client.output({
|
|
@@ -37723,9 +38363,9 @@ function externalAnchor(entry) {
|
|
|
37723
38363
|
if (entry.source !== "external") throw new Error("Expected an External Thread list entry");
|
|
37724
38364
|
return { timestamp: entry.timestamp, threadId: threadId(entry.thread) };
|
|
37725
38365
|
}
|
|
37726
|
-
function includesExternalRecord(
|
|
37727
|
-
if (
|
|
37728
|
-
let current =
|
|
38366
|
+
function includesExternalRecord(record5, query, byId, sectionId) {
|
|
38367
|
+
if (record5.state !== "ready" || !record5.nativeSessionRef) return false;
|
|
38368
|
+
let current = record5;
|
|
37729
38369
|
const owners = /* @__PURE__ */ new Set();
|
|
37730
38370
|
while (current.subagent) {
|
|
37731
38371
|
if (owners.has(current.hostThreadId)) return false;
|
|
@@ -37735,32 +38375,32 @@ function includesExternalRecord(record4, query, byId, sectionId) {
|
|
|
37735
38375
|
return false;
|
|
37736
38376
|
current = parent;
|
|
37737
38377
|
}
|
|
37738
|
-
const sourceKind =
|
|
38378
|
+
const sourceKind = record5.subagent ? "subAgentThreadSpawn" : "vscode";
|
|
37739
38379
|
const scoped = query.parentThreadId !== null || query.ancestorThreadId !== null;
|
|
37740
|
-
if (
|
|
38380
|
+
if (record5.subagent && !scoped && !query.sourceKinds?.some((kind) => kind === "subAgent" || kind === "subAgentThreadSpawn"))
|
|
37741
38381
|
return false;
|
|
37742
|
-
if (query.parentThreadId !== null &&
|
|
38382
|
+
if (query.parentThreadId !== null && record5.subagent?.parentHostThreadId !== query.parentThreadId)
|
|
37743
38383
|
return false;
|
|
37744
38384
|
if (query.ancestorThreadId !== null) {
|
|
37745
|
-
let parentId =
|
|
37746
|
-
const visited = /* @__PURE__ */ new Set([
|
|
38385
|
+
let parentId = record5.subagent?.parentHostThreadId;
|
|
38386
|
+
const visited = /* @__PURE__ */ new Set([record5.hostThreadId]);
|
|
37747
38387
|
while (parentId && parentId !== query.ancestorThreadId && !visited.has(parentId)) {
|
|
37748
38388
|
visited.add(parentId);
|
|
37749
38389
|
parentId = byId.get(parentId)?.subagent?.parentHostThreadId;
|
|
37750
38390
|
}
|
|
37751
|
-
if (
|
|
38391
|
+
if (record5.hostThreadId === query.ancestorThreadId || parentId !== query.ancestorThreadId)
|
|
37752
38392
|
return false;
|
|
37753
38393
|
}
|
|
37754
|
-
if (
|
|
37755
|
-
if (query.projectId !== void 0 && (
|
|
37756
|
-
if (query.cwd !== null && !query.cwd.includes(
|
|
38394
|
+
if (record5.archived !== query.archived) return false;
|
|
38395
|
+
if (query.projectId !== void 0 && (record5.projectId ?? null) !== query.projectId) return false;
|
|
38396
|
+
if (query.cwd !== null && !query.cwd.includes(record5.cwd)) return false;
|
|
37757
38397
|
if (query.modelProviders !== null && query.modelProviders.length > 0 && !query.modelProviders.includes("codexhost")) {
|
|
37758
38398
|
return false;
|
|
37759
38399
|
}
|
|
37760
|
-
if (query.sourceKinds !== null && query.sourceKinds.length > 0 && !query.sourceKinds.includes(sourceKind) && !(
|
|
38400
|
+
if (query.sourceKinds !== null && query.sourceKinds.length > 0 && !query.sourceKinds.includes(sourceKind) && !(record5.subagent && query.sourceKinds.includes("subAgent"))) {
|
|
37761
38401
|
return false;
|
|
37762
38402
|
}
|
|
37763
|
-
if (query.searchTerm !== null && !
|
|
38403
|
+
if (query.searchTerm !== null && !record5.title.toLowerCase().includes(query.searchTerm.toLowerCase())) {
|
|
37764
38404
|
return false;
|
|
37765
38405
|
}
|
|
37766
38406
|
if (query.isPinned === true) return false;
|
|
@@ -37768,7 +38408,7 @@ function includesExternalRecord(record4, query, byId, sectionId) {
|
|
|
37768
38408
|
return true;
|
|
37769
38409
|
}
|
|
37770
38410
|
function resolveExternalSessionTreeIds(records) {
|
|
37771
|
-
const byId = new Map(records.map((
|
|
38411
|
+
const byId = new Map(records.map((record5) => [record5.hostThreadId, record5]));
|
|
37772
38412
|
const resolved = /* @__PURE__ */ new Map();
|
|
37773
38413
|
const resolve = (start) => {
|
|
37774
38414
|
const cached2 = resolved.get(start.hostThreadId);
|
|
@@ -37779,7 +38419,7 @@ function resolveExternalSessionTreeIds(records) {
|
|
|
37779
38419
|
while (true) {
|
|
37780
38420
|
const known = resolved.get(current.hostThreadId);
|
|
37781
38421
|
if (known) {
|
|
37782
|
-
for (const
|
|
38422
|
+
for (const record5 of path43) resolved.set(record5.hostThreadId, known);
|
|
37783
38423
|
return known;
|
|
37784
38424
|
}
|
|
37785
38425
|
if (visited.has(current.hostThreadId)) {
|
|
@@ -37791,32 +38431,32 @@ function resolveExternalSessionTreeIds(records) {
|
|
|
37791
38431
|
const source = sourceId ? byId.get(sourceId) : void 0;
|
|
37792
38432
|
if (!source) {
|
|
37793
38433
|
const root = current.hostThreadId;
|
|
37794
|
-
for (const
|
|
38434
|
+
for (const record5 of path43) resolved.set(record5.hostThreadId, root);
|
|
37795
38435
|
return root;
|
|
37796
38436
|
}
|
|
37797
38437
|
current = source;
|
|
37798
38438
|
}
|
|
37799
38439
|
};
|
|
37800
|
-
for (const
|
|
38440
|
+
for (const record5 of records) resolve(record5);
|
|
37801
38441
|
return resolved;
|
|
37802
38442
|
}
|
|
37803
38443
|
function externalThreadListEntries(input) {
|
|
37804
38444
|
const sessionIds = resolveExternalSessionTreeIds(input.records);
|
|
37805
|
-
const byId = new Map(input.records.map((
|
|
38445
|
+
const byId = new Map(input.records.map((record5) => [record5.hostThreadId, record5]));
|
|
37806
38446
|
return input.records.filter(
|
|
37807
|
-
(
|
|
37808
|
-
|
|
38447
|
+
(record5) => includesExternalRecord(
|
|
38448
|
+
record5,
|
|
37809
38449
|
input.query,
|
|
37810
38450
|
byId,
|
|
37811
|
-
input.placementOf?.(
|
|
38451
|
+
input.placementOf?.(record5.hostThreadId)?.section.id ?? null
|
|
37812
38452
|
)
|
|
37813
|
-
).map((
|
|
37814
|
-
const runtime = input.runtimeFor(
|
|
37815
|
-
const sessionId = sessionIds.get(
|
|
38453
|
+
).map((record5) => {
|
|
38454
|
+
const runtime = input.runtimeFor(record5.hostThreadId);
|
|
38455
|
+
const sessionId = sessionIds.get(record5.hostThreadId);
|
|
37816
38456
|
if (!sessionId) throw new Error("External Thread Session tree could not be resolved");
|
|
37817
|
-
const placement = input.placementOf?.(
|
|
38457
|
+
const placement = input.placementOf?.(record5.hostThreadId);
|
|
37818
38458
|
const thread = externalThreadValue({
|
|
37819
|
-
record:
|
|
38459
|
+
record: record5,
|
|
37820
38460
|
turns: [],
|
|
37821
38461
|
sessionId,
|
|
37822
38462
|
...runtime ? { running: runtime.running } : { loaded: false },
|
|
@@ -37825,7 +38465,7 @@ function externalThreadListEntries(input) {
|
|
|
37825
38465
|
return {
|
|
37826
38466
|
source: "external",
|
|
37827
38467
|
thread,
|
|
37828
|
-
timestamp: input.query.sortKey === "created_at" ? unixTimestamp(
|
|
38468
|
+
timestamp: input.query.sortKey === "created_at" ? unixTimestamp(record5.createdAt, "createdAt") : unixTimestamp(record5.updatedAt, "updatedAt")
|
|
37829
38469
|
};
|
|
37830
38470
|
});
|
|
37831
38471
|
}
|
|
@@ -37928,7 +38568,7 @@ async function aggregateThreadList(input) {
|
|
|
37928
38568
|
let officialIndex = 0;
|
|
37929
38569
|
let firstOfficialBackwardsCursor;
|
|
37930
38570
|
let officialRequestCount = 0;
|
|
37931
|
-
const externalIds = new Set(input.records.map((
|
|
38571
|
+
const externalIds = new Set(input.records.map((record5) => record5.hostThreadId));
|
|
37932
38572
|
for (const thread of input.sharedThreads ?? []) externalIds.add(String(thread.id));
|
|
37933
38573
|
const requestOfficial = async (cursor, limit) => {
|
|
37934
38574
|
officialRequestCount += 1;
|
|
@@ -38270,7 +38910,6 @@ async function moveThreadSection(input) {
|
|
|
38270
38910
|
// packages/host-runtime/src/external-thread-official-defaults.ts
|
|
38271
38911
|
var EMPTY_RESULTS = /* @__PURE__ */ new Map([
|
|
38272
38912
|
["thread/attachment/list", () => ({ data: [], nextCursor: null })],
|
|
38273
|
-
["thread/queue/list", () => ({ data: [], nextCursor: null })],
|
|
38274
38913
|
["thread/settings/update", () => ({})]
|
|
38275
38914
|
]);
|
|
38276
38915
|
function externalThreadEmptyOfficialResult(method) {
|
|
@@ -38620,6 +39259,9 @@ var AppServerHost = class {
|
|
|
38620
39259
|
#executionHosts = /* @__PURE__ */ new WeakMap();
|
|
38621
39260
|
#externalPrewarms = new ExternalThreadPrewarms();
|
|
38622
39261
|
#externalSteering = new ExternalTurnSteering();
|
|
39262
|
+
#externalQueue = new ExternalThreadQueue({
|
|
39263
|
+
notifyChanged: (threadId2) => this.#writer.json({ method: "thread/queue/changed", params: { threadId: threadId2 } })
|
|
39264
|
+
});
|
|
38623
39265
|
#liveCommandCache = new LiveCommandCatalogCache();
|
|
38624
39266
|
#modelPrices;
|
|
38625
39267
|
#observedSessionUsage;
|
|
@@ -38646,7 +39288,7 @@ var AppServerHost = class {
|
|
|
38646
39288
|
#sectionMoves = Promise.resolve();
|
|
38647
39289
|
#writer;
|
|
38648
39290
|
/** Console requests share Desktop handling; their replies return to the console. */
|
|
38649
|
-
#consoleRequestPrefix = `codexhost-console:${
|
|
39291
|
+
#consoleRequestPrefix = `codexhost-console:${randomUUID17()}:`;
|
|
38650
39292
|
#consoleReplies = /* @__PURE__ */ new Map();
|
|
38651
39293
|
#nextConsoleRequest = 0;
|
|
38652
39294
|
#subagentThreadStatuses = /* @__PURE__ */ new Map();
|
|
@@ -39874,6 +40516,18 @@ var AppServerHost = class {
|
|
|
39874
40516
|
return;
|
|
39875
40517
|
}
|
|
39876
40518
|
}
|
|
40519
|
+
if (request.method.startsWith("thread/queue/") && isRecord18(request.params) && typeof request.params.threadId === "string") {
|
|
40520
|
+
const location = await this.#locateExternalThread(request.params.threadId);
|
|
40521
|
+
if (await this.#writeResolutionError(request, location)) return;
|
|
40522
|
+
if (location.kind === "external") {
|
|
40523
|
+
this.#dispatchDesktopReply(
|
|
40524
|
+
request,
|
|
40525
|
+
() => this.#handleExternalQueueRequest(request, location.record.hostThreadId),
|
|
40526
|
+
location.record.hostThreadId
|
|
40527
|
+
);
|
|
40528
|
+
return;
|
|
40529
|
+
}
|
|
40530
|
+
}
|
|
39877
40531
|
if (request.method === "thread/backgroundTerminals/clean" && isRecord18(request.params) && typeof request.params.threadId === "string") {
|
|
39878
40532
|
const location = await this.#locateExternalThread(request.params.threadId);
|
|
39879
40533
|
if (await this.#writeResolutionError(request, location)) return;
|
|
@@ -40284,7 +40938,7 @@ var AppServerHost = class {
|
|
|
40284
40938
|
throw error51;
|
|
40285
40939
|
}
|
|
40286
40940
|
this.#activeOfficialTurns.set(threadId2, turnId);
|
|
40287
|
-
const delegationId = hostThreadIdSchema.parse(
|
|
40941
|
+
const delegationId = hostThreadIdSchema.parse(randomUUID17());
|
|
40288
40942
|
try {
|
|
40289
40943
|
const source = await this.#repository.find(input.parentThreadId);
|
|
40290
40944
|
const pendingTerminal = this.#pendingOfficialTerminalStatuses.get(threadId2);
|
|
@@ -40472,7 +41126,7 @@ var AppServerHost = class {
|
|
|
40472
41126
|
async #listDelegationThreads(input) {
|
|
40473
41127
|
const [sortKey, sortDirection2] = input.sort.split("-");
|
|
40474
41128
|
const request = {
|
|
40475
|
-
id: `codexhost:delegation-list:${
|
|
41129
|
+
id: `codexhost:delegation-list:${randomUUID17()}`,
|
|
40476
41130
|
method: "thread/list",
|
|
40477
41131
|
params: {
|
|
40478
41132
|
cwd: input.cwd ? [input.cwd] : null,
|
|
@@ -40497,12 +41151,12 @@ var AppServerHost = class {
|
|
|
40497
41151
|
return {
|
|
40498
41152
|
threads: result.data.flatMap((entry) => {
|
|
40499
41153
|
if (typeof entry.id !== "string") return [];
|
|
40500
|
-
const
|
|
41154
|
+
const record5 = records.find((candidate) => candidate.hostThreadId === entry.id);
|
|
40501
41155
|
const status2 = isRecord18(entry.status) && entry.status.type === "active" ? "running" : "completed";
|
|
40502
41156
|
return [
|
|
40503
41157
|
{
|
|
40504
41158
|
threadId: entry.id,
|
|
40505
|
-
harnessId:
|
|
41159
|
+
harnessId: record5 ? record5.harnessId : "codex",
|
|
40506
41160
|
deepLink: `codex://threads/${entry.id}`,
|
|
40507
41161
|
status: status2,
|
|
40508
41162
|
...typeof entry.cwd === "string" ? { cwd: entry.cwd } : {},
|
|
@@ -40609,7 +41263,7 @@ var AppServerHost = class {
|
|
|
40609
41263
|
const outcome = await moveThreadSection({
|
|
40610
41264
|
move,
|
|
40611
41265
|
movingExternal: location.kind === "external",
|
|
40612
|
-
externalThreadIds: new Set(records.map((
|
|
41266
|
+
externalThreadIds: new Set(records.map((record5) => record5.hostThreadId)),
|
|
40613
41267
|
placements,
|
|
40614
41268
|
requestOfficial: (method, params) => this.#requestOfficial(method, params),
|
|
40615
41269
|
savePlacements: (next) => this.#repository.replaceSectionPlacements(next),
|
|
@@ -40699,10 +41353,10 @@ var AppServerHost = class {
|
|
|
40699
41353
|
/** Clear External assignments to a project official Codex reported as deleted. */
|
|
40700
41354
|
async #clearDeletedProjectAssignments(projectId) {
|
|
40701
41355
|
const records = await this.#repository.list();
|
|
40702
|
-
for (const
|
|
40703
|
-
if (
|
|
41356
|
+
for (const record5 of records) {
|
|
41357
|
+
if (record5.projectId !== projectId) continue;
|
|
40704
41358
|
const updated = await this.#repository.updateMetadata(
|
|
40705
|
-
|
|
41359
|
+
record5.hostThreadId,
|
|
40706
41360
|
{ projectId: null },
|
|
40707
41361
|
{ ifProjectId: projectId }
|
|
40708
41362
|
);
|
|
@@ -40715,14 +41369,14 @@ var AppServerHost = class {
|
|
|
40715
41369
|
});
|
|
40716
41370
|
}
|
|
40717
41371
|
}
|
|
40718
|
-
#syncLoadedExternalThread(thread,
|
|
41372
|
+
#syncLoadedExternalThread(thread, record5) {
|
|
40719
41373
|
const projected = externalThreadValue({
|
|
40720
|
-
record:
|
|
41374
|
+
record: record5,
|
|
40721
41375
|
turns: [],
|
|
40722
41376
|
sessionId: thread.sessionId,
|
|
40723
41377
|
running: thread.running
|
|
40724
41378
|
});
|
|
40725
|
-
thread.record =
|
|
41379
|
+
thread.record = record5;
|
|
40726
41380
|
thread.thread = { ...thread.thread, ...projected, turns: thread.thread.turns ?? [] };
|
|
40727
41381
|
return projected;
|
|
40728
41382
|
}
|
|
@@ -40739,15 +41393,15 @@ var AppServerHost = class {
|
|
|
40739
41393
|
);
|
|
40740
41394
|
return null;
|
|
40741
41395
|
}
|
|
40742
|
-
let
|
|
41396
|
+
let record5;
|
|
40743
41397
|
try {
|
|
40744
|
-
|
|
41398
|
+
record5 = await write(location.record.hostThreadId);
|
|
40745
41399
|
} catch {
|
|
40746
41400
|
await this.#writer.json(rpcError(request, -32081, failureMessage));
|
|
40747
41401
|
return null;
|
|
40748
41402
|
}
|
|
40749
|
-
const projected = location.thread ? this.#syncLoadedExternalThread(location.thread,
|
|
40750
|
-
return { record:
|
|
41403
|
+
const projected = location.thread ? this.#syncLoadedExternalThread(location.thread, record5) : externalThreadValue({ record: record5, turns: [], sessionId, loaded: false });
|
|
41404
|
+
return { record: record5, thread: await this.#withExternalSection(projected) };
|
|
40751
41405
|
}
|
|
40752
41406
|
async #handleConsoleOpen(request) {
|
|
40753
41407
|
if (!consoleOpenParamsSchema.safeParse(request.params ?? {}).success) {
|
|
@@ -41003,8 +41657,8 @@ var AppServerHost = class {
|
|
|
41003
41657
|
const sharedHarness = shared?.get(threadId2);
|
|
41004
41658
|
if (sharedHarness)
|
|
41005
41659
|
return { threadId: threadId2, owner: "external", harnessId: sharedHarness };
|
|
41006
|
-
const
|
|
41007
|
-
return
|
|
41660
|
+
const record5 = await this.#repository.find(threadId2);
|
|
41661
|
+
return record5 ? { threadId: threadId2, owner: "external", harnessId: record5.harnessId } : { threadId: threadId2, owner: "codex" };
|
|
41008
41662
|
})
|
|
41009
41663
|
);
|
|
41010
41664
|
const result = threadOwnershipListResultSchema.parse({ threads });
|
|
@@ -41200,7 +41854,7 @@ var AppServerHost = class {
|
|
|
41200
41854
|
if (thread.running || thread.activeTurnId) {
|
|
41201
41855
|
throw new ExternalCommandError(-32072, "External Thread already has an active operation");
|
|
41202
41856
|
}
|
|
41203
|
-
const turnId = requestedTurnId ?? hostTurnIdSchema.parse(
|
|
41857
|
+
const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID17());
|
|
41204
41858
|
const projection = {
|
|
41205
41859
|
projector: new CodexTurnProjector({
|
|
41206
41860
|
threadId: thread.id,
|
|
@@ -41515,6 +42169,7 @@ var AppServerHost = class {
|
|
|
41515
42169
|
}
|
|
41516
42170
|
const params = requestObject(request);
|
|
41517
42171
|
const route = decodeCreateRoute(request);
|
|
42172
|
+
const prewarm = params[EXTERNAL_THREAD_PREWARM_PARAM] === true || route?.prewarm === true;
|
|
41518
42173
|
const requestedModel = route && route.harnessId !== "codex" ? route.model : void 0;
|
|
41519
42174
|
const requestedThinkingOptionId = route && route.harnessId !== "codex" ? route.thinkingOptionId : void 0;
|
|
41520
42175
|
const requestedPermissionModeId = route && route.harnessId !== "codex" ? route.permissionModeId : void 0;
|
|
@@ -41534,9 +42189,9 @@ var AppServerHost = class {
|
|
|
41534
42189
|
ephemeral: params.ephemeral === true,
|
|
41535
42190
|
historyMode: params.historyMode === "paginated" ? "paginated" : "legacy"
|
|
41536
42191
|
});
|
|
41537
|
-
let
|
|
42192
|
+
let record5;
|
|
41538
42193
|
try {
|
|
41539
|
-
|
|
42194
|
+
record5 = await this.#repository.createProvisional(recordInput);
|
|
41540
42195
|
} catch {
|
|
41541
42196
|
this.#routeObservationTracker.rejectCreate(request.id);
|
|
41542
42197
|
await this.#writer.json(rpcError(request, -32081, "External Thread could not be persisted"));
|
|
@@ -41547,7 +42202,7 @@ var AppServerHost = class {
|
|
|
41547
42202
|
cwd,
|
|
41548
42203
|
environment: {
|
|
41549
42204
|
...this.#options.environment ?? process.env,
|
|
41550
|
-
[DELEGATION_THREAD_ID_ENV]:
|
|
42205
|
+
[DELEGATION_THREAD_ID_ENV]: record5.hostThreadId
|
|
41551
42206
|
},
|
|
41552
42207
|
...requestedModel ? { model: requestedModel } : {},
|
|
41553
42208
|
...requestedThinkingOptionId ? { thinkingOptionId: requestedThinkingOptionId } : {},
|
|
@@ -41555,37 +42210,37 @@ var AppServerHost = class {
|
|
|
41555
42210
|
});
|
|
41556
42211
|
if (!sessionResult.ok) {
|
|
41557
42212
|
this.#routeObservationTracker.rejectCreate(request.id);
|
|
41558
|
-
await this.#repository.removeProvisional(
|
|
42213
|
+
await this.#repository.removeProvisional(record5.hostThreadId).catch(() => void 0);
|
|
41559
42214
|
const mapped = mapExternalThreadHarnessError(sessionResult.error, "create");
|
|
41560
42215
|
await this.#writer.json(rpcError(request, mapped.code, mapped.message));
|
|
41561
42216
|
return;
|
|
41562
42217
|
}
|
|
41563
42218
|
const session = sessionResult.value;
|
|
41564
|
-
await this.#externalRuntime.idleRelease.runOperation(
|
|
42219
|
+
await this.#externalRuntime.idleRelease.runOperation(record5.hostThreadId, async () => {
|
|
41565
42220
|
try {
|
|
41566
|
-
if (session.initialState.nativeRef &&
|
|
41567
|
-
|
|
41568
|
-
|
|
42221
|
+
if (session.initialState.nativeRef && !prewarm) {
|
|
42222
|
+
record5 = await this.#repository.commitNative(
|
|
42223
|
+
record5.hostThreadId,
|
|
41569
42224
|
session.initialState.nativeRef
|
|
41570
42225
|
);
|
|
41571
42226
|
}
|
|
41572
42227
|
const thread = externalThreadValue({
|
|
41573
|
-
record:
|
|
42228
|
+
record: record5,
|
|
41574
42229
|
turns: [],
|
|
41575
|
-
sessionId:
|
|
42230
|
+
sessionId: record5.hostThreadId
|
|
41576
42231
|
});
|
|
41577
42232
|
const externalThread = this.#registerExternalThread({
|
|
41578
|
-
record:
|
|
42233
|
+
record: record5,
|
|
41579
42234
|
session,
|
|
41580
|
-
unsubmittedPrewarm:
|
|
41581
|
-
sessionId:
|
|
42235
|
+
unsubmittedPrewarm: prewarm,
|
|
42236
|
+
sessionId: record5.hostThreadId,
|
|
41582
42237
|
thread,
|
|
41583
42238
|
turns: [],
|
|
41584
42239
|
...requestedModel ? { requestedModel } : {},
|
|
41585
42240
|
...requestedThinkingOptionId ? { requestedThinkingOptionId } : {},
|
|
41586
42241
|
...requestedPermissionModeId ? { requestedPermissionModeId } : {}
|
|
41587
42242
|
});
|
|
41588
|
-
if (
|
|
42243
|
+
if (prewarm) {
|
|
41589
42244
|
this.#externalPrewarms.register(externalThread);
|
|
41590
42245
|
}
|
|
41591
42246
|
this.#routeObservationTracker.bindCreatedThread(request.id, externalThread.id);
|
|
@@ -41608,12 +42263,12 @@ var AppServerHost = class {
|
|
|
41608
42263
|
}
|
|
41609
42264
|
})
|
|
41610
42265
|
);
|
|
41611
|
-
if (
|
|
42266
|
+
if (record5.state === "ready") await this.#notifyExternalThreadStarted(thread);
|
|
41612
42267
|
} catch {
|
|
41613
|
-
this.#externalRuntime.remove(
|
|
41614
|
-
this.#routeObservationTracker.forgetThread(
|
|
42268
|
+
this.#externalRuntime.remove(record5.hostThreadId);
|
|
42269
|
+
this.#routeObservationTracker.forgetThread(record5.hostThreadId);
|
|
41615
42270
|
await session.close().catch(() => void 0);
|
|
41616
|
-
await this.#repository.removeProvisional(
|
|
42271
|
+
await this.#repository.removeProvisional(record5.hostThreadId).catch(() => void 0);
|
|
41617
42272
|
await this.#writer.json(
|
|
41618
42273
|
rpcError(request, -32081, "External Thread could not be persisted")
|
|
41619
42274
|
);
|
|
@@ -41775,9 +42430,9 @@ var AppServerHost = class {
|
|
|
41775
42430
|
);
|
|
41776
42431
|
return;
|
|
41777
42432
|
}
|
|
41778
|
-
let
|
|
42433
|
+
let record5;
|
|
41779
42434
|
try {
|
|
41780
|
-
|
|
42435
|
+
record5 = await this.#repository.setTitle(location.record.hostThreadId, name);
|
|
41781
42436
|
} catch {
|
|
41782
42437
|
await this.#writer.json(
|
|
41783
42438
|
rpcError(request, -32081, "External Thread title could not be persisted")
|
|
@@ -41785,7 +42440,7 @@ var AppServerHost = class {
|
|
|
41785
42440
|
return;
|
|
41786
42441
|
}
|
|
41787
42442
|
if (location.thread) {
|
|
41788
|
-
location.thread.record =
|
|
42443
|
+
location.thread.record = record5;
|
|
41789
42444
|
location.thread.thread.name = name;
|
|
41790
42445
|
location.thread.thread.updatedAt = unixSeconds();
|
|
41791
42446
|
}
|
|
@@ -41808,6 +42463,7 @@ var AppServerHost = class {
|
|
|
41808
42463
|
}
|
|
41809
42464
|
if (location.thread) await this.#resolveThreadInteractions(location.thread);
|
|
41810
42465
|
this.#routeObservationTracker.forgetThread(location.record.hostThreadId);
|
|
42466
|
+
this.#externalQueue.forget(location.record.hostThreadId);
|
|
41811
42467
|
await this.#writer.json(rpcEnvelope(request, { result: {} }));
|
|
41812
42468
|
await this.#writer.json({
|
|
41813
42469
|
method: "thread/deleted",
|
|
@@ -42061,6 +42717,125 @@ var AppServerHost = class {
|
|
|
42061
42717
|
);
|
|
42062
42718
|
}
|
|
42063
42719
|
}
|
|
42720
|
+
async #handleExternalQueueRequest(request, threadId2) {
|
|
42721
|
+
const queue = this.#externalQueue;
|
|
42722
|
+
try {
|
|
42723
|
+
const params = requestObject(request);
|
|
42724
|
+
const input = () => {
|
|
42725
|
+
requestText(params);
|
|
42726
|
+
return params.input;
|
|
42727
|
+
};
|
|
42728
|
+
const submissionId = () => {
|
|
42729
|
+
if (typeof params.queuedSubmissionId !== "string")
|
|
42730
|
+
throw new ExternalQueueError(-32602, "queuedSubmissionId must be a string");
|
|
42731
|
+
return params.queuedSubmissionId;
|
|
42732
|
+
};
|
|
42733
|
+
let result;
|
|
42734
|
+
switch (request.method) {
|
|
42735
|
+
case "thread/queue/list":
|
|
42736
|
+
result = queue.list(threadId2, params);
|
|
42737
|
+
break;
|
|
42738
|
+
case "thread/queue/add": {
|
|
42739
|
+
if (typeof params.clientUserMessageId !== "string" || !params.clientUserMessageId)
|
|
42740
|
+
throw new ExternalQueueError(-32602, "clientUserMessageId must be a string");
|
|
42741
|
+
const sourceHostId = params[THREAD_REFERENCE_SOURCE_HOST_PARAM];
|
|
42742
|
+
const submission = await queue.add(
|
|
42743
|
+
threadId2,
|
|
42744
|
+
input(),
|
|
42745
|
+
params.clientUserMessageId,
|
|
42746
|
+
typeof sourceHostId === "string" ? sourceHostId : void 0
|
|
42747
|
+
);
|
|
42748
|
+
result = { queuedSubmission: submission };
|
|
42749
|
+
break;
|
|
42750
|
+
}
|
|
42751
|
+
case "thread/queue/update": {
|
|
42752
|
+
const submission = await queue.update(threadId2, submissionId(), input());
|
|
42753
|
+
result = { queuedSubmission: submission };
|
|
42754
|
+
break;
|
|
42755
|
+
}
|
|
42756
|
+
case "thread/queue/delete":
|
|
42757
|
+
result = { deleted: await queue.delete(threadId2, submissionId()) };
|
|
42758
|
+
break;
|
|
42759
|
+
case "thread/queue/reorder": {
|
|
42760
|
+
const ids = params.queuedSubmissionIds;
|
|
42761
|
+
if (!Array.isArray(ids) || !ids.every((id2) => typeof id2 === "string"))
|
|
42762
|
+
throw new ExternalQueueError(-32602, "queuedSubmissionIds must be strings");
|
|
42763
|
+
await queue.reorder(threadId2, ids);
|
|
42764
|
+
result = {};
|
|
42765
|
+
break;
|
|
42766
|
+
}
|
|
42767
|
+
case "thread/queue/start": {
|
|
42768
|
+
const resolution = await this.#resolveExternalThread(threadId2);
|
|
42769
|
+
if (await this.#writeResolutionError(request, resolution)) return;
|
|
42770
|
+
if (resolution.kind !== "external")
|
|
42771
|
+
throw new ExternalQueueError(-32073, "External Thread is no longer available");
|
|
42772
|
+
const started = await this.#startQueuedSubmission(
|
|
42773
|
+
resolution.thread,
|
|
42774
|
+
params.queuedSubmissionId == null ? null : submissionId()
|
|
42775
|
+
);
|
|
42776
|
+
try {
|
|
42777
|
+
await this.#writer.json(rpcEnvelope(request, { result: { turn: started.turn } }));
|
|
42778
|
+
} finally {
|
|
42779
|
+
started.gate.resolve();
|
|
42780
|
+
}
|
|
42781
|
+
return;
|
|
42782
|
+
}
|
|
42783
|
+
default:
|
|
42784
|
+
throw new ExternalQueueError(
|
|
42785
|
+
-32076,
|
|
42786
|
+
`External Thread does not support ${request.method}`
|
|
42787
|
+
);
|
|
42788
|
+
}
|
|
42789
|
+
await this.#writer.json(rpcEnvelope(request, { result }));
|
|
42790
|
+
if (request.method === "thread/queue/add") {
|
|
42791
|
+
const thread = this.#externalRuntime.get(threadId2);
|
|
42792
|
+
const lastTurn = thread?.turns.at(-1);
|
|
42793
|
+
if (thread && thread.projectedTerminalTurnId === lastTurn?.id && lastTurn?.status === "completed" && isRecord18(thread.thread.status) && thread.thread.status.type === "idle") {
|
|
42794
|
+
void this.#drainExternalQueue(thread);
|
|
42795
|
+
}
|
|
42796
|
+
}
|
|
42797
|
+
} catch (error51) {
|
|
42798
|
+
await this.#writer.json(
|
|
42799
|
+
rpcError(
|
|
42800
|
+
request,
|
|
42801
|
+
error51 instanceof ExternalQueueError || error51 instanceof ExternalSteerError || error51 instanceof ExternalCommandError ? error51.code : -32602,
|
|
42802
|
+
errorMessage4(error51)
|
|
42803
|
+
)
|
|
42804
|
+
);
|
|
42805
|
+
}
|
|
42806
|
+
}
|
|
42807
|
+
/** Starts a queued follow-up as a Turn; it returns to its place when the start fails. */
|
|
42808
|
+
async #startQueuedSubmission(thread, submissionId) {
|
|
42809
|
+
if (this.#externalThreadBusy(thread) || this.#pendingExternalCommandRequests.has(thread.id))
|
|
42810
|
+
throw new ExternalSteerError(-32072, "External Thread already has an active Turn");
|
|
42811
|
+
const taken = this.#externalQueue.take(thread.id, submissionId);
|
|
42812
|
+
try {
|
|
42813
|
+
const started = await this.#beginExternalInputTurn(
|
|
42814
|
+
thread,
|
|
42815
|
+
requestText({ input: taken.submission.input }),
|
|
42816
|
+
void 0,
|
|
42817
|
+
taken.submission.clientUserMessageId,
|
|
42818
|
+
taken.sourceHostId,
|
|
42819
|
+
true
|
|
42820
|
+
);
|
|
42821
|
+
await this.#externalQueue.notifyChanged(thread.id);
|
|
42822
|
+
return started;
|
|
42823
|
+
} catch (error51) {
|
|
42824
|
+
this.#externalQueue.restore(thread.id, taken);
|
|
42825
|
+
await this.#externalQueue.notifyChanged(thread.id);
|
|
42826
|
+
throw error51;
|
|
42827
|
+
}
|
|
42828
|
+
}
|
|
42829
|
+
/** Desktop leaves queued follow-ups to the app-server once a Turn completes normally. */
|
|
42830
|
+
async #drainExternalQueue(thread) {
|
|
42831
|
+
if (!this.#externalQueue.has(thread.id) || this.#externalThreadBusy(thread) || this.#pendingExternalCommandRequests.has(thread.id))
|
|
42832
|
+
return;
|
|
42833
|
+
try {
|
|
42834
|
+
(await this.#startQueuedSubmission(thread)).gate.resolve();
|
|
42835
|
+
} catch (error51) {
|
|
42836
|
+
this.#diagnose(error51);
|
|
42837
|
+
}
|
|
42838
|
+
}
|
|
42064
42839
|
async #steerExternalTurn(request, thread) {
|
|
42065
42840
|
try {
|
|
42066
42841
|
const started = await this.#externalSteering.run(
|
|
@@ -42125,12 +42900,12 @@ var AppServerHost = class {
|
|
|
42125
42900
|
};
|
|
42126
42901
|
}
|
|
42127
42902
|
/** Keep command restoration and dispatch identical for start and steer submissions. */
|
|
42128
|
-
async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId, sourceHostId) {
|
|
42903
|
+
async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId, sourceHostId, projectInput = false) {
|
|
42129
42904
|
const text = restoreHarnessCommandMentions(inputText);
|
|
42130
42905
|
const commands = thread.session.commands;
|
|
42131
42906
|
if (!commands || !isExternalCommandCandidate(text)) {
|
|
42132
42907
|
assertActive?.();
|
|
42133
|
-
return this.#beginExternalTurn(thread, text, clientUserMessageId, sourceHostId);
|
|
42908
|
+
return this.#beginExternalTurn(thread, text, clientUserMessageId, sourceHostId, projectInput);
|
|
42134
42909
|
}
|
|
42135
42910
|
this.#pendingExternalCommandRequests.add(thread.id);
|
|
42136
42911
|
try {
|
|
@@ -42141,7 +42916,13 @@ var AppServerHost = class {
|
|
|
42141
42916
|
assertActive?.();
|
|
42142
42917
|
if (!command) {
|
|
42143
42918
|
this.#pendingExternalCommandRequests.delete(thread.id);
|
|
42144
|
-
return await this.#beginExternalTurn(
|
|
42919
|
+
return await this.#beginExternalTurn(
|
|
42920
|
+
thread,
|
|
42921
|
+
text,
|
|
42922
|
+
clientUserMessageId,
|
|
42923
|
+
sourceHostId,
|
|
42924
|
+
projectInput
|
|
42925
|
+
);
|
|
42145
42926
|
}
|
|
42146
42927
|
return await this.#beginExternalCommand(
|
|
42147
42928
|
thread,
|
|
@@ -42174,14 +42955,18 @@ var AppServerHost = class {
|
|
|
42174
42955
|
else this.#executionHosts.set(thread, previousHostId);
|
|
42175
42956
|
};
|
|
42176
42957
|
}
|
|
42177
|
-
|
|
42958
|
+
/**
|
|
42959
|
+
* Desktop renders the input of its own `turn/start` locally. Other starts (Host-only clients
|
|
42960
|
+
* and queued follow-ups) need the user message projected with the Turn.
|
|
42961
|
+
*/
|
|
42962
|
+
async #beginExternalTurn(thread, text, clientUserMessageId, sourceHostId, projectInput = false) {
|
|
42178
42963
|
if (this.#closeRequested || this.#externalRuntime.get(thread.id) !== thread) {
|
|
42179
42964
|
throw new ExternalSteerError(-32073, "External Thread is no longer available");
|
|
42180
42965
|
}
|
|
42181
42966
|
if (thread.running || thread.activeTurnId || this.#pendingExternalCommandRequests.has(thread.id)) {
|
|
42182
42967
|
throw new ExternalSteerError(-32072, "External Thread already has an active Turn");
|
|
42183
42968
|
}
|
|
42184
|
-
const turnId = hostTurnIdSchema.parse(
|
|
42969
|
+
const turnId = hostTurnIdSchema.parse(randomUUID17());
|
|
42185
42970
|
const startedAtMs = Date.now();
|
|
42186
42971
|
const projection = {
|
|
42187
42972
|
projector: new CodexTurnProjector({
|
|
@@ -42189,7 +42974,7 @@ var AppServerHost = class {
|
|
|
42189
42974
|
turnId,
|
|
42190
42975
|
cwd: thread.cwd,
|
|
42191
42976
|
startedAtMs,
|
|
42192
|
-
...this.#options.externalOnly ? {
|
|
42977
|
+
...this.#options.externalOnly || projectInput ? {
|
|
42193
42978
|
initialInput: [{ type: "text", text }],
|
|
42194
42979
|
...clientUserMessageId ? { clientUserMessageId } : {}
|
|
42195
42980
|
} : {}
|
|
@@ -42420,21 +43205,21 @@ var AppServerHost = class {
|
|
|
42420
43205
|
}
|
|
42421
43206
|
if (event.type === "subagent.transcript.changed") {
|
|
42422
43207
|
const nativeSubagentId = event.nativeSubagentId;
|
|
42423
|
-
const
|
|
43208
|
+
const record5 = (await this.#repository.list()).find(
|
|
42424
43209
|
(candidate) => candidate.subagent?.parentHostThreadId === thread.id && candidate.subagent.nativeSubagentId === nativeSubagentId && candidate.nativeSessionRef?.nativeSessionId === thread.record.nativeSessionRef?.nativeSessionId
|
|
42425
43210
|
);
|
|
42426
|
-
if (
|
|
43211
|
+
if (record5) await this.#refreshOpenSubagentThread(record5.hostThreadId, false);
|
|
42427
43212
|
return;
|
|
42428
43213
|
}
|
|
42429
43214
|
if (event.type === "subagent.state.changed") {
|
|
42430
43215
|
const nativeSubagentId = event.nativeSubagentId;
|
|
42431
|
-
const
|
|
43216
|
+
const record5 = (await this.#repository.list()).find(
|
|
42432
43217
|
(candidate) => candidate.subagent?.parentHostThreadId === thread.id && candidate.subagent.nativeSubagentId === nativeSubagentId && candidate.nativeSessionRef?.nativeSessionId === thread.record.nativeSessionRef?.nativeSessionId
|
|
42433
43218
|
);
|
|
42434
|
-
if (!
|
|
43219
|
+
if (!record5) return;
|
|
42435
43220
|
const status2 = event.status === "pending" || event.status === "running" ? "active" : "idle";
|
|
42436
|
-
this.#trackRunningSubagent(thread.id,
|
|
42437
|
-
await this.#setSubagentThreadStatus(
|
|
43221
|
+
this.#trackRunningSubagent(thread.id, record5.hostThreadId, status2);
|
|
43222
|
+
await this.#setSubagentThreadStatus(record5.hostThreadId, status2);
|
|
42438
43223
|
if (!thread.running && !thread.activeTurnId && !this.#hasRunningSubagents(thread.id)) {
|
|
42439
43224
|
await this.#setThreadStatus(thread, { type: "idle" });
|
|
42440
43225
|
}
|
|
@@ -42562,32 +43347,35 @@ var AppServerHost = class {
|
|
|
42562
43347
|
this.#hasRunningSubagents(thread.id) ? { type: "active", activeFlags: [] } : { type: "idle" }
|
|
42563
43348
|
);
|
|
42564
43349
|
this.#externalSteering.terminal(thread.id, event.turnId, event.outcome);
|
|
43350
|
+
if (!ephemeralTurn && result.completedTurn?.status === "completed" && this.#externalQueue.has(thread.id)) {
|
|
43351
|
+
void this.#drainExternalQueue(thread);
|
|
43352
|
+
}
|
|
42565
43353
|
}
|
|
42566
43354
|
}
|
|
42567
43355
|
async #materializeSubagent(parent, subagent) {
|
|
42568
43356
|
if (!subagent.nativeSubagentId || !parent.record.nativeSessionRef) return subagent;
|
|
42569
43357
|
const status2 = subagent.status === "pending" || subagent.status === "running" ? "active" : "idle";
|
|
42570
|
-
const
|
|
42571
|
-
if (!
|
|
42572
|
-
if (this.#subagentThreadStatuses.has(
|
|
42573
|
-
this.#trackRunningSubagent(parent.id,
|
|
42574
|
-
await this.#setSubagentThreadStatus(
|
|
42575
|
-
return { ...subagent, subagentId:
|
|
43358
|
+
const record5 = await this.#repository.materializeSubagent(parent.record, subagent);
|
|
43359
|
+
if (!record5) return subagent;
|
|
43360
|
+
if (this.#subagentThreadStatuses.has(record5.hostThreadId)) {
|
|
43361
|
+
this.#trackRunningSubagent(parent.id, record5.hostThreadId, status2);
|
|
43362
|
+
await this.#setSubagentThreadStatus(record5.hostThreadId, status2);
|
|
43363
|
+
return { ...subagent, subagentId: record5.hostThreadId };
|
|
42576
43364
|
}
|
|
42577
43365
|
const thread = externalThreadValue({
|
|
42578
|
-
record:
|
|
43366
|
+
record: record5,
|
|
42579
43367
|
turns: [],
|
|
42580
43368
|
sessionId: parent.sessionId,
|
|
42581
43369
|
running: status2 === "active"
|
|
42582
43370
|
});
|
|
42583
|
-
this.#subagentThreadStatuses.set(
|
|
42584
|
-
this.#trackRunningSubagent(parent.id,
|
|
43371
|
+
this.#subagentThreadStatuses.set(record5.hostThreadId, status2);
|
|
43372
|
+
this.#trackRunningSubagent(parent.id, record5.hostThreadId, status2);
|
|
42585
43373
|
await this.#writer.json({
|
|
42586
43374
|
method: "thread/started",
|
|
42587
43375
|
emittedAtMs: Date.now(),
|
|
42588
43376
|
params: { thread }
|
|
42589
43377
|
});
|
|
42590
|
-
return { ...subagent, subagentId:
|
|
43378
|
+
return { ...subagent, subagentId: record5.hostThreadId };
|
|
42591
43379
|
}
|
|
42592
43380
|
async #refreshOpenSubagentThread(threadId2, terminal3 = true) {
|
|
42593
43381
|
await this.#desktopRequests.run(threadId2, async () => {
|
|
@@ -42901,7 +43689,7 @@ var AppServerHost = class {
|
|
|
42901
43689
|
if (shared) sharedQuestion(interaction);
|
|
42902
43690
|
result = projection.projector.projectQuestion(
|
|
42903
43691
|
interaction,
|
|
42904
|
-
hostItemIdSchema.parse(
|
|
43692
|
+
hostItemIdSchema.parse(randomUUID17())
|
|
42905
43693
|
);
|
|
42906
43694
|
} catch (error51) {
|
|
42907
43695
|
this.#diagnose(error51);
|
|
@@ -43147,7 +43935,7 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
|
43147
43935
|
var wrapper_default = import_websocket.default;
|
|
43148
43936
|
|
|
43149
43937
|
// packages/host-runtime/src/remote-socket-lock.ts
|
|
43150
|
-
import { randomUUID as
|
|
43938
|
+
import { randomUUID as randomUUID18 } from "node:crypto";
|
|
43151
43939
|
import { chmod as chmod3, lstat as lstat5, mkdir as mkdir12, open as open9, readFile as readFile16, readdir as readdir5, rename as rename11, rm as rm11 } from "node:fs/promises";
|
|
43152
43940
|
import { uptime } from "node:os";
|
|
43153
43941
|
import path26 from "node:path";
|
|
@@ -43161,18 +43949,18 @@ var LOCK_ENTRY_SUFFIX = ".json";
|
|
|
43161
43949
|
function currentBootTimeSeconds() {
|
|
43162
43950
|
return Math.round(Date.now() / 1e3 - uptime());
|
|
43163
43951
|
}
|
|
43164
|
-
function validOwnerFields(
|
|
43165
|
-
return typeof
|
|
43952
|
+
function validOwnerFields(record5) {
|
|
43953
|
+
return typeof record5.ownerToken === "string" && record5.ownerToken.length > 0 && typeof record5.pid === "number" && Number.isSafeInteger(record5.pid) && record5.pid > 0 && typeof record5.bootTimeSeconds === "number" && Number.isSafeInteger(record5.bootTimeSeconds);
|
|
43166
43954
|
}
|
|
43167
43955
|
function parseLockRecord(source) {
|
|
43168
43956
|
try {
|
|
43169
43957
|
const value2 = JSON.parse(source);
|
|
43170
43958
|
if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) return null;
|
|
43171
|
-
const
|
|
43172
|
-
if (
|
|
43959
|
+
const record5 = value2;
|
|
43960
|
+
if (record5.version !== 2 || !validOwnerFields(record5) || typeof record5.choosing !== "boolean" || typeof record5.ticket !== "number" || !Number.isSafeInteger(record5.ticket) || record5.ticket < 0 || (record5.choosing ? record5.ticket !== 0 : record5.ticket === 0)) {
|
|
43173
43961
|
return null;
|
|
43174
43962
|
}
|
|
43175
|
-
return
|
|
43963
|
+
return record5;
|
|
43176
43964
|
} catch {
|
|
43177
43965
|
return null;
|
|
43178
43966
|
}
|
|
@@ -43181,9 +43969,9 @@ function parseLegacyLockRecord(source) {
|
|
|
43181
43969
|
try {
|
|
43182
43970
|
const value2 = JSON.parse(source);
|
|
43183
43971
|
if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) return null;
|
|
43184
|
-
const
|
|
43185
|
-
if (
|
|
43186
|
-
return
|
|
43972
|
+
const record5 = value2;
|
|
43973
|
+
if (record5.version !== 1 || !validOwnerFields(record5)) return null;
|
|
43974
|
+
return record5;
|
|
43187
43975
|
} catch {
|
|
43188
43976
|
return null;
|
|
43189
43977
|
}
|
|
@@ -43196,10 +43984,10 @@ function processIsRunning(pid) {
|
|
|
43196
43984
|
return error51.code !== "ESRCH";
|
|
43197
43985
|
}
|
|
43198
43986
|
}
|
|
43199
|
-
function ownerIsAbandoned(
|
|
43200
|
-
if (Math.abs(
|
|
43987
|
+
function ownerIsAbandoned(record5, mtimeMs) {
|
|
43988
|
+
if (Math.abs(record5.bootTimeSeconds - currentBootTimeSeconds()) > 5) return true;
|
|
43201
43989
|
if (Math.max(0, Date.now() - mtimeMs) >= LOCK_MAX_AGE_MS) return true;
|
|
43202
|
-
return !processIsRunning(
|
|
43990
|
+
return !processIsRunning(record5.pid);
|
|
43203
43991
|
}
|
|
43204
43992
|
function sameUnixFileIdentity(left, right) {
|
|
43205
43993
|
return left.dev === right.dev && left.ino === right.ino;
|
|
@@ -43218,13 +44006,13 @@ async function readLockEntrySnapshot(filePath) {
|
|
|
43218
44006
|
throw error51;
|
|
43219
44007
|
});
|
|
43220
44008
|
if (source === null) return null;
|
|
43221
|
-
const
|
|
44009
|
+
const record5 = parseLockRecord(source);
|
|
43222
44010
|
return {
|
|
43223
44011
|
filePath,
|
|
43224
44012
|
source,
|
|
43225
44013
|
identity: { dev: metadata.dev, ino: metadata.ino },
|
|
43226
44014
|
mtimeMs: metadata.mtimeMs,
|
|
43227
|
-
record:
|
|
44015
|
+
record: record5 && path26.basename(filePath) === lockEntryName(record5.ownerToken) ? record5 : null
|
|
43228
44016
|
};
|
|
43229
44017
|
}
|
|
43230
44018
|
function lockEntryIsAbandoned(snapshot2) {
|
|
@@ -43272,11 +44060,11 @@ async function preparePrivateLockDirectory(lockDirectory) {
|
|
|
43272
44060
|
}
|
|
43273
44061
|
await chmod3(lockDirectory, 448);
|
|
43274
44062
|
}
|
|
43275
|
-
async function writeLockRecordAtomic(lockDirectory, entryPath,
|
|
43276
|
-
const temporary = path26.join(lockDirectory, `.tmp-${
|
|
44063
|
+
async function writeLockRecordAtomic(lockDirectory, entryPath, record5) {
|
|
44064
|
+
const temporary = path26.join(lockDirectory, `.tmp-${record5.ownerToken}-${randomUUID18()}`);
|
|
43277
44065
|
const handle = await open9(temporary, "wx", 384);
|
|
43278
44066
|
try {
|
|
43279
|
-
await handle.writeFile(`${JSON.stringify(
|
|
44067
|
+
await handle.writeFile(`${JSON.stringify(record5)}
|
|
43280
44068
|
`, "utf8");
|
|
43281
44069
|
await handle.sync();
|
|
43282
44070
|
} finally {
|
|
@@ -43306,11 +44094,11 @@ async function legacyLockState(legacyPath) {
|
|
|
43306
44094
|
});
|
|
43307
44095
|
if (source === null) return "absent";
|
|
43308
44096
|
const ageMs = Math.max(0, Date.now() - metadata.mtimeMs);
|
|
43309
|
-
const
|
|
43310
|
-
if (
|
|
43311
|
-
return ownerIsAbandoned(
|
|
44097
|
+
const record5 = parseLegacyLockRecord(source);
|
|
44098
|
+
if (record5 === null) return ageMs < LOCK_MALFORMED_GRACE_MS ? "blocking" : "abandoned";
|
|
44099
|
+
return ownerIsAbandoned(record5, metadata.mtimeMs) ? "abandoned" : "blocking";
|
|
43312
44100
|
}
|
|
43313
|
-
async function tryAcquireLegacyCompatibilityGuard(legacyPath,
|
|
44101
|
+
async function tryAcquireLegacyCompatibilityGuard(legacyPath, record5) {
|
|
43314
44102
|
const handle = await open9(legacyPath, "wx", 384).catch((error51) => {
|
|
43315
44103
|
if (error51.code === "EEXIST") return null;
|
|
43316
44104
|
throw error51;
|
|
@@ -43319,7 +44107,7 @@ async function tryAcquireLegacyCompatibilityGuard(legacyPath, record4) {
|
|
|
43319
44107
|
const metadata = await handle.stat();
|
|
43320
44108
|
const guard = { handle, identity: { dev: metadata.dev, ino: metadata.ino } };
|
|
43321
44109
|
try {
|
|
43322
|
-
await handle.writeFile(`${JSON.stringify(
|
|
44110
|
+
await handle.writeFile(`${JSON.stringify(record5)}
|
|
43323
44111
|
`, "utf8");
|
|
43324
44112
|
await handle.sync();
|
|
43325
44113
|
return guard;
|
|
@@ -43348,7 +44136,7 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
|
|
|
43348
44136
|
const legacyPath = `${socketPath}.initializing`;
|
|
43349
44137
|
const lockDirectory = `${socketPath}.initializers`;
|
|
43350
44138
|
await preparePrivateLockDirectory(lockDirectory);
|
|
43351
|
-
const ownerToken =
|
|
44139
|
+
const ownerToken = randomUUID18();
|
|
43352
44140
|
const entryPath = path26.join(lockDirectory, lockEntryName(ownerToken));
|
|
43353
44141
|
const baseRecord = {
|
|
43354
44142
|
version: 2,
|
|
@@ -43385,8 +44173,8 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
|
|
|
43385
44173
|
throw new Error(`Remote app-server socket lock ownership was lost at ${socketPath}`);
|
|
43386
44174
|
}
|
|
43387
44175
|
const blockedByBakery = catalog.entries.some((entry) => {
|
|
43388
|
-
const
|
|
43389
|
-
return
|
|
44176
|
+
const record5 = entry.record;
|
|
44177
|
+
return record5 !== null && record5.ownerToken !== ownerToken && (record5.choosing || recordHasPriority(record5, ownRecord));
|
|
43390
44178
|
});
|
|
43391
44179
|
if (!catalog.unsettled && !blockedByBakery) {
|
|
43392
44180
|
const legacyGuard = await tryAcquireLegacyCompatibilityGuard(legacyPath, {
|
|
@@ -43859,12 +44647,12 @@ function createRemoteAppServerWebSocketListener(input) {
|
|
|
43859
44647
|
|
|
43860
44648
|
// packages/host-runtime/src/remote-official-app-server.ts
|
|
43861
44649
|
import { spawn as spawn5 } from "node:child_process";
|
|
43862
|
-
import { randomUUID as
|
|
44650
|
+
import { randomUUID as randomUUID19 } from "node:crypto";
|
|
43863
44651
|
import { lstat as lstat7, rm as rm13, stat as stat7 } from "node:fs/promises";
|
|
43864
44652
|
import path28 from "node:path";
|
|
43865
44653
|
var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
|
|
43866
44654
|
var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
|
|
43867
|
-
function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token =
|
|
44655
|
+
function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID19()) {
|
|
43868
44656
|
if (!path28.posix.isAbsolute(desktopControlSocketPath)) {
|
|
43869
44657
|
throw new Error("Desktop control socket path must be absolute");
|
|
43870
44658
|
}
|
|
@@ -45083,11 +45871,11 @@ async function readRemoteDelegationThread(environment, input) {
|
|
|
45083
45871
|
}
|
|
45084
45872
|
|
|
45085
45873
|
// packages/host-runtime/src/shared-thread-owner.ts
|
|
45086
|
-
import { randomUUID as
|
|
45874
|
+
import { randomUUID as randomUUID21 } from "node:crypto";
|
|
45087
45875
|
import { PassThrough as PassThrough3 } from "node:stream";
|
|
45088
45876
|
|
|
45089
45877
|
// packages/host-runtime/src/shared-thread-peer.ts
|
|
45090
|
-
import { randomUUID as
|
|
45878
|
+
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
45091
45879
|
function object5(value2) {
|
|
45092
45880
|
return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
|
|
45093
45881
|
}
|
|
@@ -45101,7 +45889,7 @@ var StreamThreadPeer = class {
|
|
|
45101
45889
|
input;
|
|
45102
45890
|
output;
|
|
45103
45891
|
stop;
|
|
45104
|
-
#prefix = `shared:${
|
|
45892
|
+
#prefix = `shared:${randomUUID20()}:`;
|
|
45105
45893
|
#pending = /* @__PURE__ */ new Map();
|
|
45106
45894
|
#listeners = /* @__PURE__ */ new Set();
|
|
45107
45895
|
#ended = Promise.withResolvers();
|
|
@@ -45179,7 +45967,7 @@ var SharedThreadOwner = class {
|
|
|
45179
45967
|
input = new PassThrough3();
|
|
45180
45968
|
output = new PassThrough3();
|
|
45181
45969
|
#peer = new StreamThreadPeer(this.output, this.input, () => this.input.end());
|
|
45182
|
-
#prefix = `shared-interaction:${
|
|
45970
|
+
#prefix = `shared-interaction:${randomUUID21()}:`;
|
|
45183
45971
|
#interactions = /* @__PURE__ */ new Map();
|
|
45184
45972
|
#listeners = /* @__PURE__ */ new Set();
|
|
45185
45973
|
#receipts = /* @__PURE__ */ new Map();
|
|
@@ -45489,7 +46277,7 @@ var SharedThreadBridge = class {
|
|
|
45489
46277
|
};
|
|
45490
46278
|
|
|
45491
46279
|
// packages/host-runtime/src/remote-control-app-server.ts
|
|
45492
|
-
import { randomUUID as
|
|
46280
|
+
import { randomUUID as randomUUID22 } from "node:crypto";
|
|
45493
46281
|
import { mkdir as mkdir15, open as open10, rename as rename12, rm as rm14 } from "node:fs/promises";
|
|
45494
46282
|
import path33 from "node:path";
|
|
45495
46283
|
var REMOTE_CONTROL_BRIDGE_PIPE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_PIPE";
|
|
@@ -45510,7 +46298,7 @@ function nodeCompatibleWindowsPath(value2) {
|
|
|
45510
46298
|
if (value2.startsWith("\\\\?\\")) return value2.slice(4);
|
|
45511
46299
|
return value2;
|
|
45512
46300
|
}
|
|
45513
|
-
function remoteControlBridgePipePath(processId = process.pid, instanceId =
|
|
46301
|
+
function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID22()) {
|
|
45514
46302
|
const safeInstance = instanceId.replaceAll(/[^a-zA-Z0-9-]/gu, "");
|
|
45515
46303
|
if (!safeInstance) throw new Error("Remote Control bridge instance ID is invalid");
|
|
45516
46304
|
return `\\\\.\\pipe\\codexhost-remote-control-${processId}-${safeInstance}`;
|
|
@@ -45525,7 +46313,7 @@ async function publishRemoteControlAppServerDescriptor(plan) {
|
|
|
45525
46313
|
await mkdir15(directory, { recursive: true, mode: 448 });
|
|
45526
46314
|
const temporaryPath = path33.join(
|
|
45527
46315
|
directory,
|
|
45528
|
-
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${
|
|
46316
|
+
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID22()}.tmp`
|
|
45529
46317
|
);
|
|
45530
46318
|
const handle = await open10(temporaryPath, "wx", 384);
|
|
45531
46319
|
try {
|
|
@@ -45718,12 +46506,12 @@ async function startConsoleControlServer(options2) {
|
|
|
45718
46506
|
reply(response, 400, { error: { code: -32700, message: "Invalid request body" } });
|
|
45719
46507
|
return;
|
|
45720
46508
|
}
|
|
45721
|
-
const
|
|
45722
|
-
if (typeof
|
|
46509
|
+
const record5 = typeof body === "object" && body !== null ? body : {};
|
|
46510
|
+
if (typeof record5.method !== "string") {
|
|
45723
46511
|
reply(response, 400, { error: { code: -32600, message: "method is required" } });
|
|
45724
46512
|
return;
|
|
45725
46513
|
}
|
|
45726
|
-
reply(response, 200, await options2.target.handleConsoleRequest(
|
|
46514
|
+
reply(response, 200, await options2.target.handleConsoleRequest(record5.method, record5.params));
|
|
45727
46515
|
})().catch((error51) => {
|
|
45728
46516
|
if (!response.headersSent) {
|
|
45729
46517
|
reply(response, 500, {
|
|
@@ -46047,7 +46835,7 @@ function createHostUpdateCoordinator(options2) {
|
|
|
46047
46835
|
}
|
|
46048
46836
|
|
|
46049
46837
|
// packages/host-runtime/src/usage-statistics.ts
|
|
46050
|
-
import { randomUUID as
|
|
46838
|
+
import { randomUUID as randomUUID23 } from "node:crypto";
|
|
46051
46839
|
import { mkdir as mkdir17, readFile as readFile17, readdir as readdir6, rename as rename14, rm as rm16, writeFile as writeFile10 } from "node:fs/promises";
|
|
46052
46840
|
import path36 from "node:path";
|
|
46053
46841
|
import { setImmediate as yieldToEventLoop } from "node:timers/promises";
|
|
@@ -46142,14 +46930,14 @@ function parseHarnessUsageEntry(value2) {
|
|
|
46142
46930
|
// packages/host-runtime/src/usage-session-titles.ts
|
|
46143
46931
|
function withHostSessionTitles(result, records) {
|
|
46144
46932
|
const titles = /* @__PURE__ */ new Map();
|
|
46145
|
-
for (const
|
|
46146
|
-
const ref =
|
|
46147
|
-
const title = usageSessionTitle(
|
|
46148
|
-
if (
|
|
46149
|
-
const key = `${
|
|
46933
|
+
for (const record5 of records) {
|
|
46934
|
+
const ref = record5.nativeSessionRef;
|
|
46935
|
+
const title = usageSessionTitle(record5.title);
|
|
46936
|
+
if (record5.state !== "ready" || !ref || ref.harnessId !== record5.harnessId || !title) continue;
|
|
46937
|
+
const key = `${record5.harnessId}\0${ref.nativeSessionId}`;
|
|
46150
46938
|
const previous = titles.get(key);
|
|
46151
|
-
if (!previous ||
|
|
46152
|
-
titles.set(key, { title, updatedAt:
|
|
46939
|
+
if (!previous || record5.updatedAt > previous.updatedAt)
|
|
46940
|
+
titles.set(key, { title, updatedAt: record5.updatedAt });
|
|
46153
46941
|
}
|
|
46154
46942
|
const decorate = (sessions) => sessions.map((session) => {
|
|
46155
46943
|
const title = titles.get(`${session.harness}\0${session.sessionId}`)?.title;
|
|
@@ -46588,7 +47376,7 @@ var UsageStatistics = class {
|
|
|
46588
47376
|
async #persist(harness2, cache) {
|
|
46589
47377
|
if (!cache.dirty || this.#now() - cache.persistedAtMs < PERSIST_INTERVAL_MS) return;
|
|
46590
47378
|
const file2 = this.#file(harness2);
|
|
46591
|
-
const temporary = `${file2}.${
|
|
47379
|
+
const temporary = `${file2}.${randomUUID23()}.tmp`;
|
|
46592
47380
|
try {
|
|
46593
47381
|
await mkdir17(this.#directory, { recursive: true });
|
|
46594
47382
|
const sources = [...cache.sources].map(([id2, source]) => [
|
|
@@ -47199,7 +47987,7 @@ async function runHostRuntime(input) {
|
|
|
47199
47987
|
}
|
|
47200
47988
|
|
|
47201
47989
|
// packages/host-runtime/src/remote-host-install.ts
|
|
47202
|
-
import { createHash as createHash11, randomUUID as
|
|
47990
|
+
import { createHash as createHash11, randomUUID as randomUUID24 } from "node:crypto";
|
|
47203
47991
|
import { constants as fsConstants } from "node:fs";
|
|
47204
47992
|
import {
|
|
47205
47993
|
access as access3,
|
|
@@ -47298,7 +48086,7 @@ async function writeAtomic(filePath, contents, mode) {
|
|
|
47298
48086
|
await mkdir18(path38.dirname(filePath), { recursive: true, mode: 448 });
|
|
47299
48087
|
const temporary = path38.join(
|
|
47300
48088
|
path38.dirname(filePath),
|
|
47301
|
-
`.${path38.basename(filePath)}.${process.pid}.${
|
|
48089
|
+
`.${path38.basename(filePath)}.${process.pid}.${randomUUID24()}.tmp`
|
|
47302
48090
|
);
|
|
47303
48091
|
try {
|
|
47304
48092
|
if (typeof contents === "string") {
|
|
@@ -47322,7 +48110,7 @@ async function writeAtomicExecutable(filePath, sourcePath) {
|
|
|
47322
48110
|
await mkdir18(path38.dirname(filePath), { recursive: true, mode: 448 });
|
|
47323
48111
|
const temporary = path38.join(
|
|
47324
48112
|
path38.dirname(filePath),
|
|
47325
|
-
`.${path38.basename(filePath)}.${process.pid}.${
|
|
48113
|
+
`.${path38.basename(filePath)}.${process.pid}.${randomUUID24()}.tmp`
|
|
47326
48114
|
);
|
|
47327
48115
|
try {
|
|
47328
48116
|
await copyFile4(sourcePath, temporary);
|
|
@@ -48330,7 +49118,7 @@ var harnessErrorSchema = external_exports.object({
|
|
|
48330
49118
|
var harnessSessionStateSchema = external_exports.custom((value2) => {
|
|
48331
49119
|
if (!value2 || typeof value2 !== "object" || Array.isArray(value2))
|
|
48332
49120
|
return false;
|
|
48333
|
-
const
|
|
49121
|
+
const record5 = value2;
|
|
48334
49122
|
const allowed = /* @__PURE__ */ new Set([
|
|
48335
49123
|
"nativeRef",
|
|
48336
49124
|
"effectiveModel",
|
|
@@ -48339,12 +49127,12 @@ var harnessSessionStateSchema = external_exports.custom((value2) => {
|
|
|
48339
49127
|
"availableThinkingOptions",
|
|
48340
49128
|
"effectivePermissionModeId"
|
|
48341
49129
|
]);
|
|
48342
|
-
if (Object.keys(
|
|
49130
|
+
if (Object.keys(record5).some((key) => !allowed.has(key)))
|
|
48343
49131
|
return false;
|
|
48344
|
-
if (
|
|
49132
|
+
if (record5.nativeRef !== void 0 && !nativeSessionRefSchema.safeParse(record5.nativeRef).success) {
|
|
48345
49133
|
return false;
|
|
48346
49134
|
}
|
|
48347
|
-
const { nativeRef: _nativeRef, ...configuration } =
|
|
49135
|
+
const { nativeRef: _nativeRef, ...configuration } = record5;
|
|
48348
49136
|
void _nativeRef;
|
|
48349
49137
|
return harnessConfigurationStateSchema.safeParse(configuration).success;
|
|
48350
49138
|
});
|
|
@@ -48438,7 +49226,7 @@ function defaultHarnessBrokerSocketPath(environment = process.env, harnessId = "
|
|
|
48438
49226
|
}
|
|
48439
49227
|
|
|
48440
49228
|
// packages/harness-broker/dist/server.js
|
|
48441
|
-
import { randomBytes as randomBytes5, randomUUID as
|
|
49229
|
+
import { randomBytes as randomBytes5, randomUUID as randomUUID25 } from "node:crypto";
|
|
48442
49230
|
import { chmod as chmod6, lstat as lstat10, mkdir as mkdir19, open as open11, readFile as readFile19, rename as rename16, rm as rm18 } from "node:fs/promises";
|
|
48443
49231
|
import net4, {} from "node:net";
|
|
48444
49232
|
import path41 from "node:path";
|
|
@@ -48497,7 +49285,7 @@ async function assertNoLiveDescriptor(descriptorPath) {
|
|
|
48497
49285
|
}
|
|
48498
49286
|
}
|
|
48499
49287
|
async function publishDescriptor(descriptorPath, descriptor) {
|
|
48500
|
-
const temporary = `${descriptorPath}.${process.pid}.${
|
|
49288
|
+
const temporary = `${descriptorPath}.${process.pid}.${randomUUID25()}.tmp`;
|
|
48501
49289
|
const handle = await open11(temporary, "wx", 384);
|
|
48502
49290
|
try {
|
|
48503
49291
|
await handle.writeFile(`${JSON.stringify(descriptor)}
|
|
@@ -48510,28 +49298,28 @@ async function publishDescriptor(descriptorPath, descriptor) {
|
|
|
48510
49298
|
if (process.platform !== "win32")
|
|
48511
49299
|
await chmod6(descriptorPath, 384);
|
|
48512
49300
|
}
|
|
48513
|
-
function sessionMetadata(
|
|
48514
|
-
const initialState = { ...
|
|
48515
|
-
if (
|
|
49301
|
+
function sessionMetadata(record5) {
|
|
49302
|
+
const initialState = { ...record5.session.initialState };
|
|
49303
|
+
if (record5.selection.model && initialState.effectiveModel?.id !== record5.selection.model.id) {
|
|
48516
49304
|
delete initialState.resolvedModelLabel;
|
|
48517
49305
|
}
|
|
48518
|
-
if (
|
|
49306
|
+
if (record5.selection.thinkingOptionId && initialState.effectiveThinkingOptionId !== record5.selection.thinkingOptionId) {
|
|
48519
49307
|
delete initialState.availableThinkingOptions;
|
|
48520
49308
|
}
|
|
48521
49309
|
return {
|
|
48522
|
-
sessionId:
|
|
48523
|
-
sessionGeneration:
|
|
48524
|
-
capabilities:
|
|
49310
|
+
sessionId: record5.id,
|
|
49311
|
+
sessionGeneration: record5.generation,
|
|
49312
|
+
capabilities: record5.session.capabilities,
|
|
48525
49313
|
readCapabilities: true,
|
|
48526
49314
|
initialState: {
|
|
48527
49315
|
...initialState,
|
|
48528
|
-
...
|
|
48529
|
-
...
|
|
48530
|
-
...
|
|
48531
|
-
...
|
|
49316
|
+
...record5.nativeRef ? { nativeRef: record5.nativeRef } : {},
|
|
49317
|
+
...record5.selection.model ? { effectiveModel: record5.selection.model } : {},
|
|
49318
|
+
...record5.selection.thinkingOptionId ? { effectiveThinkingOptionId: record5.selection.thinkingOptionId } : {},
|
|
49319
|
+
...record5.selection.permissionModeId ? { effectivePermissionModeId: record5.selection.permissionModeId } : {}
|
|
48532
49320
|
},
|
|
48533
|
-
initialUsage:
|
|
48534
|
-
commands:
|
|
49321
|
+
initialUsage: record5.session.initialUsage,
|
|
49322
|
+
commands: record5.session.commands !== void 0
|
|
48535
49323
|
};
|
|
48536
49324
|
}
|
|
48537
49325
|
async function socketAcceptsConnections(socketPath) {
|
|
@@ -48575,7 +49363,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
48575
49363
|
await assertNoLiveDescriptor(input.descriptorPath);
|
|
48576
49364
|
if (process.platform !== "win32")
|
|
48577
49365
|
await prepareUnixSocketPath(input.socketPath);
|
|
48578
|
-
const generation = input.generation ??
|
|
49366
|
+
const generation = input.generation ?? randomUUID25();
|
|
48579
49367
|
const token = input.token ?? randomBytes5(32).toString("hex");
|
|
48580
49368
|
const descriptor = {
|
|
48581
49369
|
schemaVersion: 1,
|
|
@@ -48616,7 +49404,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
48616
49404
|
};
|
|
48617
49405
|
const server = net4.createServer((socket) => {
|
|
48618
49406
|
const state = {
|
|
48619
|
-
id:
|
|
49407
|
+
id: randomUUID25(),
|
|
48620
49408
|
socket,
|
|
48621
49409
|
authenticated: false,
|
|
48622
49410
|
inputSequence: 0,
|
|
@@ -48643,15 +49431,15 @@ async function startHarnessBrokerServer(input) {
|
|
|
48643
49431
|
const respond2 = async (request, result) => {
|
|
48644
49432
|
await send({ kind: "response", id: request.id, ...result });
|
|
48645
49433
|
};
|
|
48646
|
-
const releaseProvisionalWriter = (
|
|
48647
|
-
if (
|
|
49434
|
+
const releaseProvisionalWriter = (record5) => {
|
|
49435
|
+
if (record5.provisionalWriterLease && provisionalNativeWriter === record5.id) {
|
|
48648
49436
|
provisionalNativeWriter = void 0;
|
|
48649
49437
|
}
|
|
48650
|
-
|
|
48651
|
-
|
|
49438
|
+
record5.provisionalWriterLease = false;
|
|
49439
|
+
record5.awaitingNativeIdentity = false;
|
|
48652
49440
|
};
|
|
48653
|
-
const forwardOutputs = async (
|
|
48654
|
-
const isCurrent = () => sessions.get(
|
|
49441
|
+
const forwardOutputs = async (record5, nativeSession, sessionGeneration, forwarderEpoch) => {
|
|
49442
|
+
const isCurrent = () => sessions.get(record5.id) === record5 && record5.session === nativeSession && record5.generation === sessionGeneration && record5.forwarderEpoch === forwarderEpoch;
|
|
48655
49443
|
try {
|
|
48656
49444
|
for await (const output of nativeSession.outputs) {
|
|
48657
49445
|
if (!isCurrent())
|
|
@@ -48659,13 +49447,13 @@ async function startHarnessBrokerServer(input) {
|
|
|
48659
49447
|
if (output.kind === "event" && output.event.type === "session.state.changed") {
|
|
48660
49448
|
const state2 = output.event.state;
|
|
48661
49449
|
const observedNativeId = state2.nativeRef?.nativeSessionId;
|
|
48662
|
-
const expectedRef =
|
|
49450
|
+
const expectedRef = record5.nativeWriterRef ?? record5.nativeRef;
|
|
48663
49451
|
if (state2.nativeRef && (state2.nativeRef.harnessId !== input.adapter.harnessId || expectedRef && (expectedRef.harnessId !== state2.nativeRef.harnessId || expectedRef.nativeSessionId !== state2.nativeRef.nativeSessionId || expectedRef.formatVersion !== state2.nativeRef.formatVersion))) {
|
|
48664
|
-
|
|
48665
|
-
releaseProvisionalWriter(
|
|
49452
|
+
record5.faulted = true;
|
|
49453
|
+
releaseProvisionalWriter(record5);
|
|
48666
49454
|
await send({
|
|
48667
49455
|
kind: "output",
|
|
48668
|
-
sessionId:
|
|
49456
|
+
sessionId: record5.id,
|
|
48669
49457
|
sessionGeneration,
|
|
48670
49458
|
output: {
|
|
48671
49459
|
kind: "event",
|
|
@@ -48683,15 +49471,15 @@ async function startHarnessBrokerServer(input) {
|
|
|
48683
49471
|
await nativeSession.close().catch(() => void 0);
|
|
48684
49472
|
break;
|
|
48685
49473
|
}
|
|
48686
|
-
if (observedNativeId && !
|
|
49474
|
+
if (observedNativeId && !record5.writerKey) {
|
|
48687
49475
|
const writerKey = nativeWriterKey(observedNativeId);
|
|
48688
49476
|
const owner = nativeWriters.get(writerKey);
|
|
48689
|
-
if (owner && owner !==
|
|
48690
|
-
|
|
48691
|
-
releaseProvisionalWriter(
|
|
49477
|
+
if (owner && owner !== record5.id) {
|
|
49478
|
+
record5.faulted = true;
|
|
49479
|
+
releaseProvisionalWriter(record5);
|
|
48692
49480
|
await send({
|
|
48693
49481
|
kind: "output",
|
|
48694
|
-
sessionId:
|
|
49482
|
+
sessionId: record5.id,
|
|
48695
49483
|
sessionGeneration,
|
|
48696
49484
|
output: {
|
|
48697
49485
|
kind: "event",
|
|
@@ -48709,38 +49497,38 @@ async function startHarnessBrokerServer(input) {
|
|
|
48709
49497
|
await nativeSession.close().catch(() => void 0);
|
|
48710
49498
|
break;
|
|
48711
49499
|
}
|
|
48712
|
-
nativeWriters.set(writerKey,
|
|
48713
|
-
|
|
48714
|
-
|
|
48715
|
-
|
|
48716
|
-
releaseProvisionalWriter(
|
|
49500
|
+
nativeWriters.set(writerKey, record5.id);
|
|
49501
|
+
record5.nativeId = observedNativeId;
|
|
49502
|
+
record5.nativeRef = state2.nativeRef;
|
|
49503
|
+
record5.writerKey = writerKey;
|
|
49504
|
+
releaseProvisionalWriter(record5);
|
|
48717
49505
|
}
|
|
48718
49506
|
if (state2.nativeRef) {
|
|
48719
|
-
|
|
48720
|
-
|
|
48721
|
-
releaseProvisionalWriter(
|
|
49507
|
+
record5.nativeId = state2.nativeRef.nativeSessionId;
|
|
49508
|
+
record5.nativeRef = state2.nativeRef;
|
|
49509
|
+
releaseProvisionalWriter(record5);
|
|
48722
49510
|
}
|
|
48723
49511
|
if (state2.effectiveModel)
|
|
48724
|
-
|
|
49512
|
+
record5.selection.model = state2.effectiveModel;
|
|
48725
49513
|
if (state2.effectiveThinkingOptionId) {
|
|
48726
|
-
|
|
49514
|
+
record5.selection.thinkingOptionId = state2.effectiveThinkingOptionId;
|
|
48727
49515
|
}
|
|
48728
49516
|
if (state2.effectivePermissionModeId) {
|
|
48729
|
-
|
|
49517
|
+
record5.selection.permissionModeId = state2.effectivePermissionModeId;
|
|
48730
49518
|
}
|
|
48731
49519
|
}
|
|
48732
49520
|
const authenticationTerminal = isAuthenticationTerminal(output);
|
|
48733
49521
|
if (output.kind === "event" && output.event.type === "session.faulted") {
|
|
48734
|
-
|
|
48735
|
-
releaseProvisionalWriter(
|
|
49522
|
+
record5.faulted = true;
|
|
49523
|
+
releaseProvisionalWriter(record5);
|
|
48736
49524
|
}
|
|
48737
49525
|
if (authenticationTerminal) {
|
|
48738
|
-
|
|
48739
|
-
releaseProvisionalWriter(
|
|
49526
|
+
record5.faulted = true;
|
|
49527
|
+
releaseProvisionalWriter(record5);
|
|
48740
49528
|
}
|
|
48741
49529
|
await send({
|
|
48742
49530
|
kind: "output",
|
|
48743
|
-
sessionId:
|
|
49531
|
+
sessionId: record5.id,
|
|
48744
49532
|
sessionGeneration,
|
|
48745
49533
|
output
|
|
48746
49534
|
});
|
|
@@ -48751,26 +49539,26 @@ async function startHarnessBrokerServer(input) {
|
|
|
48751
49539
|
}
|
|
48752
49540
|
} catch {
|
|
48753
49541
|
if (isCurrent()) {
|
|
48754
|
-
|
|
48755
|
-
releaseProvisionalWriter(
|
|
49542
|
+
record5.faulted = true;
|
|
49543
|
+
releaseProvisionalWriter(record5);
|
|
48756
49544
|
}
|
|
48757
49545
|
}
|
|
48758
49546
|
};
|
|
48759
|
-
const closeRecord = async (
|
|
48760
|
-
if (sessions.get(
|
|
49547
|
+
const closeRecord = async (record5) => {
|
|
49548
|
+
if (sessions.get(record5.id) !== record5)
|
|
48761
49549
|
return;
|
|
48762
|
-
sessions.delete(
|
|
49550
|
+
sessions.delete(record5.id);
|
|
48763
49551
|
scheduleIdle();
|
|
48764
|
-
state.sessions.delete(
|
|
48765
|
-
|
|
48766
|
-
const nativeSession =
|
|
48767
|
-
const outputTask =
|
|
49552
|
+
state.sessions.delete(record5.id);
|
|
49553
|
+
record5.forwarderEpoch += 1;
|
|
49554
|
+
const nativeSession = record5.session;
|
|
49555
|
+
const outputTask = record5.outputTask;
|
|
48768
49556
|
await nativeSession.close().catch(() => void 0);
|
|
48769
49557
|
await outputTask.catch(() => void 0);
|
|
48770
|
-
if (
|
|
48771
|
-
nativeWriters.delete(
|
|
49558
|
+
if (record5.writerKey && nativeWriters.get(record5.writerKey) === record5.id) {
|
|
49559
|
+
nativeWriters.delete(record5.writerKey);
|
|
48772
49560
|
}
|
|
48773
|
-
releaseProvisionalWriter(
|
|
49561
|
+
releaseProvisionalWriter(record5);
|
|
48774
49562
|
};
|
|
48775
49563
|
const requireSession = (params) => {
|
|
48776
49564
|
const candidate = params;
|
|
@@ -48778,13 +49566,13 @@ async function startHarnessBrokerServer(input) {
|
|
|
48778
49566
|
sessionId: candidate.sessionId,
|
|
48779
49567
|
sessionGeneration: candidate.sessionGeneration
|
|
48780
49568
|
});
|
|
48781
|
-
const
|
|
48782
|
-
if (!
|
|
49569
|
+
const record5 = sessions.get(parsed2.sessionId);
|
|
49570
|
+
if (!record5 || record5.owner !== state.id)
|
|
48783
49571
|
throw new Error("Harness broker Session is unavailable");
|
|
48784
|
-
if (
|
|
49572
|
+
if (record5.generation !== parsed2.sessionGeneration) {
|
|
48785
49573
|
throw new Error("Harness broker Session generation is stale");
|
|
48786
49574
|
}
|
|
48787
|
-
return
|
|
49575
|
+
return record5;
|
|
48788
49576
|
};
|
|
48789
49577
|
const handleRequest = async (request) => {
|
|
48790
49578
|
if (closed || state.closed)
|
|
@@ -48917,7 +49705,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
48917
49705
|
}
|
|
48918
49706
|
};
|
|
48919
49707
|
}
|
|
48920
|
-
const openReservation =
|
|
49708
|
+
const openReservation = randomUUID25();
|
|
48921
49709
|
if (sourceKey)
|
|
48922
49710
|
nativeWriters.set(sourceKey, openReservation);
|
|
48923
49711
|
const provisionalReservation = openInput.kind === "create" ? openReservation : void 0;
|
|
@@ -48997,7 +49785,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
48997
49785
|
};
|
|
48998
49786
|
}
|
|
48999
49787
|
const delayedCreateIdentity = openInput.kind === "create" && !nativeKey;
|
|
49000
|
-
const
|
|
49788
|
+
const record6 = {
|
|
49001
49789
|
id: openReservation,
|
|
49002
49790
|
generation: 1,
|
|
49003
49791
|
owner: state.id,
|
|
@@ -49018,18 +49806,18 @@ async function startHarnessBrokerServer(input) {
|
|
|
49018
49806
|
...opened.value.initialState.effectivePermissionModeId ? { permissionModeId: opened.value.initialState.effectivePermissionModeId } : {}
|
|
49019
49807
|
}
|
|
49020
49808
|
};
|
|
49021
|
-
sessions.set(
|
|
49022
|
-
state.sessions.add(
|
|
49809
|
+
sessions.set(record6.id, record6);
|
|
49810
|
+
state.sessions.add(record6.id);
|
|
49023
49811
|
if (nativeKey)
|
|
49024
|
-
nativeWriters.set(nativeKey,
|
|
49025
|
-
if (sourceKey && sourceKey !== nativeKey && nativeWriters.get(sourceKey) ===
|
|
49812
|
+
nativeWriters.set(nativeKey, record6.id);
|
|
49813
|
+
if (sourceKey && sourceKey !== nativeKey && nativeWriters.get(sourceKey) === record6.id) {
|
|
49026
49814
|
nativeWriters.delete(sourceKey);
|
|
49027
49815
|
}
|
|
49028
|
-
if (!
|
|
49816
|
+
if (!record6.provisionalWriterLease && provisionalNativeWriter === provisionalReservation) {
|
|
49029
49817
|
provisionalNativeWriter = void 0;
|
|
49030
49818
|
}
|
|
49031
|
-
|
|
49032
|
-
return { ok: true, value: sessionMetadata(
|
|
49819
|
+
record6.outputTask = forwardOutputs(record6, opened.value, record6.generation, record6.forwarderEpoch);
|
|
49820
|
+
return { ok: true, value: sessionMetadata(record6) };
|
|
49033
49821
|
} finally {
|
|
49034
49822
|
if (createSettled) {
|
|
49035
49823
|
openingCreate = void 0;
|
|
@@ -49039,11 +49827,11 @@ async function startHarnessBrokerServer(input) {
|
|
|
49039
49827
|
}
|
|
49040
49828
|
if (request.method === "session.execute") {
|
|
49041
49829
|
const parsed2 = sessionExecuteParamsSchema.parse(request.params);
|
|
49042
|
-
const
|
|
49830
|
+
const record6 = requireSession(parsed2);
|
|
49043
49831
|
const command = brokerHostCommandSchema.parse(parsed2.command);
|
|
49044
|
-
if (
|
|
49045
|
-
const isBootstrapTurn = command.type === "turn.start" &&
|
|
49046
|
-
const isBootstrapTurnContinuation =
|
|
49832
|
+
if (record6.awaitingNativeIdentity && !record6.writerKey) {
|
|
49833
|
+
const isBootstrapTurn = command.type === "turn.start" && record6.provisionalWriterLease && record6.bootstrapTurnId === void 0;
|
|
49834
|
+
const isBootstrapTurnContinuation = record6.bootstrapTurnId !== void 0 && (command.type === "turn.cancel" && command.turnId === record6.bootstrapTurnId || command.type === "interaction.respond");
|
|
49047
49835
|
if (!isBootstrapTurn && !isBootstrapTurnContinuation) {
|
|
49048
49836
|
return {
|
|
49049
49837
|
ok: false,
|
|
@@ -49056,17 +49844,17 @@ async function startHarnessBrokerServer(input) {
|
|
|
49056
49844
|
};
|
|
49057
49845
|
}
|
|
49058
49846
|
if (command.type === "turn.start")
|
|
49059
|
-
|
|
49847
|
+
record6.bootstrapTurnId = command.turnId;
|
|
49060
49848
|
}
|
|
49061
49849
|
let result;
|
|
49062
49850
|
if (command.type === "turn.start")
|
|
49063
|
-
result = await
|
|
49851
|
+
result = await record6.session.execute(command);
|
|
49064
49852
|
else if (command.type === "turn.steer")
|
|
49065
|
-
result = await
|
|
49853
|
+
result = await record6.session.execute(command);
|
|
49066
49854
|
else if (command.type === "turn.cancel")
|
|
49067
|
-
result = await
|
|
49855
|
+
result = await record6.session.execute(command);
|
|
49068
49856
|
else if (command.type === "interaction.respond") {
|
|
49069
|
-
result = await
|
|
49857
|
+
result = await record6.session.execute({
|
|
49070
49858
|
type: command.type,
|
|
49071
49859
|
interactionId: command.interactionId,
|
|
49072
49860
|
response: command.response.type === "question" ? {
|
|
@@ -49076,21 +49864,21 @@ async function startHarnessBrokerServer(input) {
|
|
|
49076
49864
|
} : command.response
|
|
49077
49865
|
});
|
|
49078
49866
|
} else if (command.type === "model.select")
|
|
49079
|
-
result = await
|
|
49867
|
+
result = await record6.session.execute(command);
|
|
49080
49868
|
else if (command.type === "thinking.select")
|
|
49081
|
-
result = await
|
|
49869
|
+
result = await record6.session.execute(command);
|
|
49082
49870
|
else
|
|
49083
|
-
result = await
|
|
49084
|
-
if (!result.ok && command.type === "turn.start" &&
|
|
49085
|
-
delete
|
|
49871
|
+
result = await record6.session.execute(command);
|
|
49872
|
+
if (!result.ok && command.type === "turn.start" && record6.awaitingNativeIdentity && record6.bootstrapTurnId === command.turnId) {
|
|
49873
|
+
delete record6.bootstrapTurnId;
|
|
49086
49874
|
}
|
|
49087
49875
|
if (result.ok) {
|
|
49088
49876
|
if (command.type === "model.select")
|
|
49089
|
-
|
|
49877
|
+
record6.selection.model = command.model;
|
|
49090
49878
|
if (command.type === "thinking.select")
|
|
49091
|
-
|
|
49879
|
+
record6.selection.thinkingOptionId = command.thinkingOptionId;
|
|
49092
49880
|
if (command.type === "permissionMode.select")
|
|
49093
|
-
|
|
49881
|
+
record6.selection.permissionModeId = command.permissionModeId;
|
|
49094
49882
|
}
|
|
49095
49883
|
return result;
|
|
49096
49884
|
}
|
|
@@ -49102,10 +49890,10 @@ async function startHarnessBrokerServer(input) {
|
|
|
49102
49890
|
return requireSession(request.params).session.readSnapshot();
|
|
49103
49891
|
}
|
|
49104
49892
|
if (request.method === "session.refreshUsage") {
|
|
49105
|
-
const
|
|
49106
|
-
const refreshUsage =
|
|
49893
|
+
const record6 = requireSession(request.params);
|
|
49894
|
+
const refreshUsage = record6.session.refreshUsage;
|
|
49107
49895
|
if (refreshUsage)
|
|
49108
|
-
await refreshUsage.call(
|
|
49896
|
+
await refreshUsage.call(record6.session);
|
|
49109
49897
|
return null;
|
|
49110
49898
|
}
|
|
49111
49899
|
if (request.method === "session.commands.list") {
|
|
@@ -49123,11 +49911,11 @@ async function startHarnessBrokerServer(input) {
|
|
|
49123
49911
|
}) : { ok: false, error: harnessError("Commands unavailable", false) };
|
|
49124
49912
|
}
|
|
49125
49913
|
if (request.method === "session.reopen") {
|
|
49126
|
-
const
|
|
49127
|
-
if (!
|
|
49128
|
-
return { ok: true, value: sessionMetadata(
|
|
49914
|
+
const record6 = requireSession(request.params);
|
|
49915
|
+
if (!record6.faulted) {
|
|
49916
|
+
return { ok: true, value: sessionMetadata(record6) };
|
|
49129
49917
|
}
|
|
49130
|
-
if (!
|
|
49918
|
+
if (!record6.nativeRef) {
|
|
49131
49919
|
return {
|
|
49132
49920
|
ok: false,
|
|
49133
49921
|
error: {
|
|
@@ -49138,17 +49926,17 @@ async function startHarnessBrokerServer(input) {
|
|
|
49138
49926
|
}
|
|
49139
49927
|
};
|
|
49140
49928
|
}
|
|
49141
|
-
const nativeRef =
|
|
49142
|
-
const oldSession =
|
|
49143
|
-
const oldOutputTask =
|
|
49144
|
-
|
|
49929
|
+
const nativeRef = record6.nativeRef;
|
|
49930
|
+
const oldSession = record6.session;
|
|
49931
|
+
const oldOutputTask = record6.outputTask;
|
|
49932
|
+
record6.forwarderEpoch += 1;
|
|
49145
49933
|
await oldSession.close().catch(() => void 0);
|
|
49146
49934
|
await oldOutputTask.catch(() => void 0);
|
|
49147
49935
|
const reopened = await input.adapter.open({
|
|
49148
49936
|
kind: "resume",
|
|
49149
|
-
cwd:
|
|
49937
|
+
cwd: record6.cwd,
|
|
49150
49938
|
nativeRef,
|
|
49151
|
-
...
|
|
49939
|
+
...record6.environment ? { environment: record6.environment } : {}
|
|
49152
49940
|
});
|
|
49153
49941
|
if (!reopened.ok)
|
|
49154
49942
|
return reopened;
|
|
@@ -49165,44 +49953,44 @@ async function startHarnessBrokerServer(input) {
|
|
|
49165
49953
|
}
|
|
49166
49954
|
};
|
|
49167
49955
|
}
|
|
49168
|
-
if (
|
|
49956
|
+
if (record6.selection.model && reopened.value.capabilities.configuration.selectModel) {
|
|
49169
49957
|
const selected = await reopened.value.execute({
|
|
49170
49958
|
type: "model.select",
|
|
49171
|
-
model:
|
|
49959
|
+
model: record6.selection.model
|
|
49172
49960
|
});
|
|
49173
49961
|
if (!selected.ok) {
|
|
49174
49962
|
await reopened.value.close().catch(() => void 0);
|
|
49175
49963
|
return selected;
|
|
49176
49964
|
}
|
|
49177
49965
|
}
|
|
49178
|
-
if (
|
|
49966
|
+
if (record6.selection.thinkingOptionId && reopened.value.capabilities.configuration.selectThinkingOption) {
|
|
49179
49967
|
const selected = await reopened.value.execute({
|
|
49180
49968
|
type: "thinking.select",
|
|
49181
|
-
thinkingOptionId:
|
|
49969
|
+
thinkingOptionId: record6.selection.thinkingOptionId
|
|
49182
49970
|
});
|
|
49183
49971
|
if (!selected.ok) {
|
|
49184
49972
|
await reopened.value.close().catch(() => void 0);
|
|
49185
49973
|
return selected;
|
|
49186
49974
|
}
|
|
49187
49975
|
}
|
|
49188
|
-
if (
|
|
49976
|
+
if (record6.selection.permissionModeId && reopened.value.capabilities.configuration.selectPermissionMode) {
|
|
49189
49977
|
const selected = await reopened.value.execute({
|
|
49190
49978
|
type: "permissionMode.select",
|
|
49191
|
-
permissionModeId:
|
|
49979
|
+
permissionModeId: record6.selection.permissionModeId
|
|
49192
49980
|
});
|
|
49193
49981
|
if (!selected.ok) {
|
|
49194
49982
|
await reopened.value.close().catch(() => void 0);
|
|
49195
49983
|
return selected;
|
|
49196
49984
|
}
|
|
49197
49985
|
}
|
|
49198
|
-
|
|
49199
|
-
|
|
49200
|
-
|
|
49201
|
-
|
|
49202
|
-
return { ok: true, value: sessionMetadata(
|
|
49986
|
+
record6.session = reopened.value;
|
|
49987
|
+
record6.generation += 1;
|
|
49988
|
+
record6.faulted = false;
|
|
49989
|
+
record6.outputTask = forwardOutputs(record6, reopened.value, record6.generation, record6.forwarderEpoch);
|
|
49990
|
+
return { ok: true, value: sessionMetadata(record6) };
|
|
49203
49991
|
}
|
|
49204
|
-
const
|
|
49205
|
-
await closeRecord(
|
|
49992
|
+
const record5 = requireSession(request.params);
|
|
49993
|
+
await closeRecord(record5);
|
|
49206
49994
|
return null;
|
|
49207
49995
|
};
|
|
49208
49996
|
consumeBrokerFrames(socket, (raw) => {
|
|
@@ -49224,7 +50012,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
49224
50012
|
}
|
|
49225
50013
|
state.authenticated = true;
|
|
49226
50014
|
state.inputSequence = 1;
|
|
49227
|
-
await send({ kind: "response", id:
|
|
50015
|
+
await send({ kind: "response", id: randomUUID25(), ok: true, value: { ready: true } });
|
|
49228
50016
|
return;
|
|
49229
50017
|
}
|
|
49230
50018
|
const parsed2 = harnessBrokerRequestSchema.safeParse(raw);
|
|
@@ -49264,9 +50052,9 @@ async function startHarnessBrokerServer(input) {
|
|
|
49264
50052
|
state.closed = true;
|
|
49265
50053
|
connections.delete(state);
|
|
49266
50054
|
for (const sessionId of [...state.sessions]) {
|
|
49267
|
-
const
|
|
49268
|
-
if (
|
|
49269
|
-
void closeRecord(
|
|
50055
|
+
const record5 = sessions.get(sessionId);
|
|
50056
|
+
if (record5)
|
|
50057
|
+
void closeRecord(record5);
|
|
49270
50058
|
}
|
|
49271
50059
|
scheduleIdle();
|
|
49272
50060
|
});
|
|
@@ -49298,10 +50086,10 @@ async function startHarnessBrokerServer(input) {
|
|
|
49298
50086
|
clearTimeout(idleTimer);
|
|
49299
50087
|
for (const connection of connections)
|
|
49300
50088
|
connection.socket.destroy();
|
|
49301
|
-
for (const
|
|
49302
|
-
|
|
49303
|
-
await Promise.all([...sessions.values()].map((
|
|
49304
|
-
await Promise.all([...sessions.values()].map((
|
|
50089
|
+
for (const record5 of sessions.values())
|
|
50090
|
+
record5.forwarderEpoch += 1;
|
|
50091
|
+
await Promise.all([...sessions.values()].map((record5) => record5.session.close().catch(() => void 0)));
|
|
50092
|
+
await Promise.all([...sessions.values()].map((record5) => record5.outputTask.catch(() => void 0)));
|
|
49305
50093
|
await input.adapter.close().catch(() => void 0);
|
|
49306
50094
|
await new Promise((resolve) => server.close(() => resolve()));
|
|
49307
50095
|
if (process.platform !== "win32")
|