@openclaw/codex 2026.7.2-beta.5 → 2026.8.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{app-server-policy-BmDgseo_.js → app-server-policy-zcBDc1JU.js} +1 -1
- package/dist/attempt-client-cleanup-DMLXUfa8.js +735 -0
- package/dist/binding-connection-I5Bo-AsX.js +33 -0
- package/dist/{bounded-turn-FEbUXoYT.js → bounded-turn-qgZmzy_4.js} +71 -63
- package/dist/{capabilities-BHRSI6Cn.js → capabilities-CybGI1oz.js} +8 -2
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-ico4ZFnk.js → command-formatters-B1AEz8ZA.js} +18 -18
- package/dist/{command-handlers-CRmnwI2N.js → command-handlers-Db8pu_ds.js} +484 -95
- package/dist/{compact-dEN49UH6.js → compact-LspQaGfl.js} +213 -199
- package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
- package/dist/doctor-contract-api.js +40 -43
- package/dist/{dynamic-tools-LIt9ojep.js → dynamic-tools-BVdyWkUD.js} +2984 -1221
- package/dist/effective-mcp-catalog-DIIhAtOZ.js +119 -0
- package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
- package/dist/{attempt-notifications-CMR2_fmR.js → event-projector-usage-e5huIQWu.js} +113 -29
- package/dist/harness.js +83 -13
- package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
- package/dist/index.js +703 -329
- package/dist/isolated-completion-C58NbL40.js +75 -0
- package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
- package/dist/media-understanding-provider.js +5 -5
- package/dist/{models-BA01NEez.js → models-BFlpn1Ex.js} +12 -17
- package/dist/native-subagent-monitor-DyTGmTUx.js +3111 -0
- package/dist/{plugin-app-cache-key-DSXX-rXO.js → plugin-app-cache-key-C3H2CVp6.js} +135 -42
- package/dist/plugin-marketplace-discovery-CzrGJdCR.js +385 -0
- package/dist/{computer-use-BjGylO-E.js → plugin-metadata-cache-CNJPj4_b.js} +211 -113
- package/dist/protocol-validators-B4F7L8Rf.js +2346 -0
- package/dist/{rate-limits-S_PXs0ul.js → rate-limits-DZXmOL8-.js} +17 -35
- package/dist/{request-CXpPennK.js → request-BRl5_UfX.js} +4 -4
- package/dist/{run-attempt-C5GTPJOE.js → run-attempt-P8BdxC1I.js} +1996 -5728
- package/dist/{runtime-artifact-C2ITXdhM.js → runtime-artifact-BVSPdd6g.js} +91 -40
- package/dist/{sandbox-guard-D1Wky__S.js → sandbox-guard-Cmwc9eIk.js} +10 -13
- package/dist/{session-binding-DlVQ-Pxs.js → session-binding-DPxIvMgE.js} +305 -271
- package/dist/{session-catalog-CP2oCcEb.js → session-catalog-xwNi_SDM.js} +418 -144
- package/dist/{session-cli-CqZ0Fp2a.js → session-cli-7hgXZDV7.js} +1 -1
- package/dist/session-retirement-DoMMJFKm.js +36 -0
- package/dist/{session-upstream-marker-QE-m5QFG.js → session-upstream-marker-CrIFX06J.js} +1 -1
- package/dist/{settled-turn-finalizer-CA_2QXIE.js → settled-turn-finalizer-BRWBO4MO.js} +36 -15
- package/dist/{shared-client-BVKE40c-.js → shared-client-kIBbGjk4.js} +721 -240
- package/dist/{side-question-CO12sHxo.js → side-question-9HAL26l9.js} +102 -53
- package/dist/{thread-lifecycle-DRg_FdzC.js → thread-lifecycle-Bu1BTDXr.js} +1355 -660
- package/dist/thread-ownership-6kOQHlyC.js +92 -0
- package/dist/thread-resume-CPrJNQVM.js +30 -0
- package/dist/{transcript-mirror-uKA-A4tB.js → transcript-mirror-B9gGgnJS.js} +202 -182
- package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DIImwDVS.js} +11 -0
- package/dist/upstream-prompt-provenance-ClRBije0.js +41 -0
- package/dist/{upstream-session-fork-_Vrz4WJr.js → upstream-session-fork-CE-_LdnP.js} +5 -5
- package/dist/{usage-UpVbdX5G.js → usage-CHlV0e-o.js} +3 -3
- package/dist/{web-search-provider.runtime-CaQMYDbp.js → web-search-provider.runtime-DRw2Vl42.js} +8 -9
- package/openclaw.plugin.json +18 -3
- package/package.json +6 -7
- package/dist/attempt-client-cleanup-Ia52yRWc.js +0 -127
- package/dist/conversation-control-DE7d9DOj.js +0 -287
- package/dist/event-projector-usage-tvgb1NCX.js +0 -69
- package/dist/notification-correlation-Bj_Ak_jI.js +0 -67
- package/dist/protocol-validators-Dm4eXZmt.js +0 -6337
- package/dist/realtime-voice-api-BPcA1uN9.js +0 -494
- package/dist/realtime-voice-api.js +0 -2
|
@@ -1,9 +1,91 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as describeControlFailure } from "./capabilities-
|
|
4
|
-
import { r as requestCodexAppServerJson } from "./request-
|
|
1
|
+
import { g as resolveCodexAppServerRuntimeOptions, v as resolveCodexComputerUseConfig } from "./session-binding-DPxIvMgE.js";
|
|
2
|
+
import { M as isCodexAppServerConnectionClosedError, N as isCodexAppServerIndeterminateRequestCancellationError, P as isCodexAppServerIndeterminateTransportError, a as getLeasedSharedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient, lt as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, u as resolveCodexNativeConfigFenceKey, v as acquireCodexNativeConfigFence } from "./shared-client-kIBbGjk4.js";
|
|
3
|
+
import { n as describeControlFailure } from "./capabilities-CybGI1oz.js";
|
|
4
|
+
import { r as requestCodexAppServerJson } from "./request-BRl5_UfX.js";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { runExec } from "openclaw/plugin-sdk/process-runtime";
|
|
7
|
+
//#region extensions/codex/src/app-server/computer-use-process-repair.ts
|
|
8
|
+
const COMPUTER_USE_PROCESS_LIST_TIMEOUT_MS = 2e3;
|
|
9
|
+
const COMPUTER_USE_PROCESS_LIST_MAX_BUFFER_BYTES = 5 * 1024 * 1024;
|
|
10
|
+
function scopedRepairUnavailableStatus() {
|
|
11
|
+
return {
|
|
12
|
+
attempted: false,
|
|
13
|
+
killedPids: [],
|
|
14
|
+
warnings: ["Computer Use auto-repair skipped because no scoped Codex app-server process was available."],
|
|
15
|
+
message: "Computer Use stale child repair requires a scoped local app-server PID."
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
async function killStaleComputerUseMcpChildren(options = {}) {
|
|
19
|
+
if (process.platform !== "darwin") return {
|
|
20
|
+
attempted: true,
|
|
21
|
+
killedPids: [],
|
|
22
|
+
warnings: [`Computer Use stale child repair is currently macOS-only, not ${process.platform}.`],
|
|
23
|
+
message: "Computer Use stale child repair skipped on this platform."
|
|
24
|
+
};
|
|
25
|
+
if (!options.ancestorPid || !Number.isSafeInteger(options.ancestorPid) || options.ancestorPid <= 0) return scopedRepairUnavailableStatus();
|
|
26
|
+
let stdout;
|
|
27
|
+
try {
|
|
28
|
+
stdout = (await runExec("/bin/ps", ["-axo", "pid=,ppid=,command="], {
|
|
29
|
+
logOutput: false,
|
|
30
|
+
maxBuffer: COMPUTER_USE_PROCESS_LIST_MAX_BUFFER_BYTES,
|
|
31
|
+
timeoutMs: COMPUTER_USE_PROCESS_LIST_TIMEOUT_MS
|
|
32
|
+
})).stdout;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return {
|
|
35
|
+
attempted: true,
|
|
36
|
+
killedPids: [],
|
|
37
|
+
warnings: [`Could not list processes for Computer Use repair: ${describeControlFailure(error)}`],
|
|
38
|
+
message: "Computer Use stale child repair could not inspect running processes."
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const killedPids = [];
|
|
42
|
+
const warnings = [];
|
|
43
|
+
const processInfos = parsePsOutput(stdout);
|
|
44
|
+
for (const processInfo of processInfos) {
|
|
45
|
+
if (!isStaleComputerUseMcpChild(processInfo.command)) continue;
|
|
46
|
+
if (!isDescendantOfPid(processInfo.pid, options.ancestorPid, processInfos)) continue;
|
|
47
|
+
try {
|
|
48
|
+
process.kill(processInfo.pid, "SIGTERM");
|
|
49
|
+
killedPids.push(processInfo.pid);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
warnings.push(`Could not terminate stale Computer Use MCP child pid ${processInfo.pid}: ${describeControlFailure(error)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
attempted: true,
|
|
56
|
+
killedPids,
|
|
57
|
+
warnings,
|
|
58
|
+
message: killedPids.length === 0 ? "No stale Computer Use MCP children were found under the scoped Codex app-server process." : `Terminated ${killedPids.length} stale Computer Use MCP child process${killedPids.length === 1 ? "" : "es"} under the scoped Codex app-server process.`
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function parsePsOutput(stdout) {
|
|
62
|
+
return stdout.split(/\r?\n/u).flatMap((line) => {
|
|
63
|
+
const match = /^\s*(\d+)\s+(\d+)\s+(.+)$/u.exec(line);
|
|
64
|
+
if (!match) return [];
|
|
65
|
+
return [{
|
|
66
|
+
pid: Number(match[1]),
|
|
67
|
+
ppid: Number(match[2]),
|
|
68
|
+
command: match[3] ?? ""
|
|
69
|
+
}];
|
|
70
|
+
}).filter((processInfo) => Number.isSafeInteger(processInfo.pid) && processInfo.pid > 0 && Number.isSafeInteger(processInfo.ppid) && processInfo.ppid >= 0);
|
|
71
|
+
}
|
|
72
|
+
function isStaleComputerUseMcpChild(command) {
|
|
73
|
+
return command.includes("SkyComputerUseClient") && /(?:^|\s)mcp(?:\s|$)/u.test(command);
|
|
74
|
+
}
|
|
75
|
+
function isDescendantOfPid(pid, ancestorPid, processInfos) {
|
|
76
|
+
const parents = new Map(processInfos.map((processInfo) => [processInfo.pid, processInfo.ppid]));
|
|
77
|
+
const seen = /* @__PURE__ */ new Set();
|
|
78
|
+
let current = pid;
|
|
79
|
+
while (!seen.has(current)) {
|
|
80
|
+
seen.add(current);
|
|
81
|
+
const parent = parents.get(current);
|
|
82
|
+
if (!parent || parent <= 0) return false;
|
|
83
|
+
if (parent === ancestorPid) return true;
|
|
84
|
+
current = parent;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
7
89
|
//#region extensions/codex/src/app-server/computer-use.ts
|
|
8
90
|
/**
|
|
9
91
|
* Computer Use plugin/MCP readiness checks and optional install flow for Codex
|
|
@@ -20,6 +102,8 @@ const CURATED_MARKETPLACE_POLL_INTERVAL_MS = 2e3;
|
|
|
20
102
|
const COMPUTER_USE_MARKETPLACE_NAME_PRIORITY = [
|
|
21
103
|
"openai-bundled",
|
|
22
104
|
"openai-curated",
|
|
105
|
+
"openai-api-curated",
|
|
106
|
+
"openai-curated-remote",
|
|
23
107
|
"local"
|
|
24
108
|
];
|
|
25
109
|
const COMPUTER_USE_LIVE_TEST_RETRY_COUNT = 1;
|
|
@@ -179,18 +263,8 @@ async function ensureComputerUsePlugin(params) {
|
|
|
179
263
|
config: params.config,
|
|
180
264
|
plugin,
|
|
181
265
|
tools: [],
|
|
182
|
-
reason: pluginSetupReason(plugin
|
|
183
|
-
message: pluginSetupMessage(params.config, plugin
|
|
184
|
-
})
|
|
185
|
-
};
|
|
186
|
-
if (params.marketplace.kind === "remote") return {
|
|
187
|
-
ok: false,
|
|
188
|
-
status: statusFromPlugin({
|
|
189
|
-
config: params.config,
|
|
190
|
-
plugin,
|
|
191
|
-
tools: [],
|
|
192
|
-
reason: "remote_install_unsupported",
|
|
193
|
-
message: remoteInstallUnsupportedMessage(plugin, params.marketplace)
|
|
266
|
+
reason: pluginSetupReason(plugin),
|
|
267
|
+
message: pluginSetupMessage(params.config, plugin)
|
|
194
268
|
})
|
|
195
269
|
};
|
|
196
270
|
await params.request("plugin/install", pluginRequestParams(params.marketplace, params.config.pluginName));
|
|
@@ -203,8 +277,8 @@ async function ensureComputerUsePlugin(params) {
|
|
|
203
277
|
config: params.config,
|
|
204
278
|
plugin,
|
|
205
279
|
tools: [],
|
|
206
|
-
reason: pluginSetupReason(plugin
|
|
207
|
-
message: pluginSetupMessage(params.config, plugin
|
|
280
|
+
reason: pluginSetupReason(plugin),
|
|
281
|
+
message: pluginSetupMessage(params.config, plugin)
|
|
208
282
|
})
|
|
209
283
|
};
|
|
210
284
|
return {
|
|
@@ -326,14 +400,6 @@ async function runCodexComputerUseLiveTest(params) {
|
|
|
326
400
|
async function cleanupComputerUseProbeThread(request, threadId, config) {
|
|
327
401
|
await Promise.allSettled([request("thread/unsubscribe", { threadId }, { timeoutMs: config.liveTestTimeoutMs }), request("thread/archive", { threadId }, { timeoutMs: config.liveTestTimeoutMs })]);
|
|
328
402
|
}
|
|
329
|
-
function scopedRepairUnavailableStatus() {
|
|
330
|
-
return {
|
|
331
|
-
attempted: false,
|
|
332
|
-
killedPids: [],
|
|
333
|
-
warnings: ["Computer Use auto-repair skipped because no scoped Codex app-server process was available."],
|
|
334
|
-
message: "Computer Use stale child repair requires a scoped local app-server PID."
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
403
|
async function resolveMarketplaceRef(params) {
|
|
338
404
|
let preferredMarketplaceName = params.config.marketplaceName;
|
|
339
405
|
if (params.config.marketplaceSource && params.allowAdd) {
|
|
@@ -390,17 +456,22 @@ function resolveBundledComputerUseMarketplacePath(params) {
|
|
|
390
456
|
return resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath({ candidates: params.defaultBundledMarketplacePathCandidates });
|
|
391
457
|
}
|
|
392
458
|
function findComputerUseMarketplaces(listed, pluginName) {
|
|
393
|
-
return listed.marketplaces.
|
|
394
|
-
|
|
459
|
+
return listed.marketplaces.flatMap((marketplace) => {
|
|
460
|
+
const plugin = marketplace.plugins.find((candidate) => candidate.name === pluginName || candidate.id === pluginName || candidate.id === `${pluginName}@${marketplace.name}`);
|
|
461
|
+
if (!plugin) return [];
|
|
462
|
+
if (marketplace.path) return [{
|
|
395
463
|
kind: "local",
|
|
396
464
|
name: marketplace.name,
|
|
397
465
|
path: marketplace.path
|
|
398
|
-
};
|
|
399
|
-
|
|
466
|
+
}];
|
|
467
|
+
const remotePluginId = plugin.remotePluginId?.trim();
|
|
468
|
+
if (!remotePluginId) return [];
|
|
469
|
+
return [{
|
|
400
470
|
kind: "remote",
|
|
401
471
|
name: marketplace.name,
|
|
402
|
-
remoteMarketplaceName: marketplace.name
|
|
403
|
-
|
|
472
|
+
remoteMarketplaceName: marketplace.name,
|
|
473
|
+
remotePluginId
|
|
474
|
+
}];
|
|
404
475
|
});
|
|
405
476
|
}
|
|
406
477
|
function chooseKnownComputerUseMarketplace(candidates) {
|
|
@@ -452,25 +523,21 @@ async function reloadMcpServers(request) {
|
|
|
452
523
|
await request("config/mcpServer/reload", void 0);
|
|
453
524
|
}
|
|
454
525
|
function pluginRequestParams(marketplace, pluginName) {
|
|
455
|
-
return {
|
|
456
|
-
|
|
457
|
-
...marketplace.kind === "remote" ? { remoteMarketplaceName: marketplace.remoteMarketplaceName } : {},
|
|
526
|
+
return marketplace.kind === "local" ? {
|
|
527
|
+
marketplacePath: marketplace.path,
|
|
458
528
|
pluginName
|
|
529
|
+
} : {
|
|
530
|
+
remoteMarketplaceName: marketplace.remoteMarketplaceName,
|
|
531
|
+
pluginName: marketplace.remotePluginId
|
|
459
532
|
};
|
|
460
533
|
}
|
|
461
|
-
function pluginSetupReason(plugin
|
|
462
|
-
if (marketplace.kind === "remote") return "remote_install_unsupported";
|
|
534
|
+
function pluginSetupReason(plugin) {
|
|
463
535
|
return plugin.summary.installed ? "plugin_disabled" : "plugin_not_installed";
|
|
464
536
|
}
|
|
465
|
-
function pluginSetupMessage(config, plugin
|
|
466
|
-
if (marketplace.kind === "remote") return remoteInstallUnsupportedMessage(plugin, marketplace);
|
|
537
|
+
function pluginSetupMessage(config, plugin) {
|
|
467
538
|
if (!plugin.summary.installed) return "Computer Use is available but not installed. Run /codex computer-use install or enable computerUse.autoInstall.";
|
|
468
539
|
return `Computer Use is installed, but the ${config.pluginName} plugin is disabled. Run /codex computer-use install or enable computerUse.autoInstall to re-enable it.`;
|
|
469
540
|
}
|
|
470
|
-
function remoteInstallUnsupportedMessage(plugin, marketplace) {
|
|
471
|
-
const marketplaceName = marketplace.name ?? plugin.marketplaceName;
|
|
472
|
-
return `Computer Use is ${plugin.summary.installed ? "installed but disabled" : "available"} in remote Codex marketplace ${marketplaceName}, but Codex app-server does not support remote plugin install yet. Configure computerUse.marketplaceSource or computerUse.marketplacePath for a local marketplace, then run /codex computer-use install.`;
|
|
473
|
-
}
|
|
474
541
|
function statusFromPlugin(params) {
|
|
475
542
|
return {
|
|
476
543
|
enabled: true,
|
|
@@ -592,75 +659,6 @@ function pluginWarnings(plugin) {
|
|
|
592
659
|
if (source && typeof source === "object" && "type" in source && source.type === "remote") warnings.push("Computer Use plugin is resolved from a remote marketplace; live local bundles are preferred.");
|
|
593
660
|
return warnings;
|
|
594
661
|
}
|
|
595
|
-
async function killStaleComputerUseMcpChildren(options = {}) {
|
|
596
|
-
if (process.platform !== "darwin") return {
|
|
597
|
-
attempted: true,
|
|
598
|
-
killedPids: [],
|
|
599
|
-
warnings: [`Computer Use stale child repair is currently macOS-only, not ${process.platform}.`],
|
|
600
|
-
message: "Computer Use stale child repair skipped on this platform."
|
|
601
|
-
};
|
|
602
|
-
if (!options.ancestorPid || !Number.isSafeInteger(options.ancestorPid) || options.ancestorPid <= 0) return scopedRepairUnavailableStatus();
|
|
603
|
-
let stdout;
|
|
604
|
-
try {
|
|
605
|
-
stdout = (await runExec("/bin/ps", ["-axo", "pid=,ppid=,command="], {
|
|
606
|
-
logOutput: false,
|
|
607
|
-
maxBuffer: 5 * 1024 * 1024
|
|
608
|
-
})).stdout;
|
|
609
|
-
} catch (error) {
|
|
610
|
-
return {
|
|
611
|
-
attempted: true,
|
|
612
|
-
killedPids: [],
|
|
613
|
-
warnings: [`Could not list processes for Computer Use repair: ${describeControlFailure(error)}`],
|
|
614
|
-
message: "Computer Use stale child repair could not inspect running processes."
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
const killedPids = [];
|
|
618
|
-
const warnings = [];
|
|
619
|
-
const processInfos = parsePsOutput(stdout);
|
|
620
|
-
for (const processInfo of processInfos) {
|
|
621
|
-
if (!isStaleComputerUseMcpChild(processInfo.command)) continue;
|
|
622
|
-
if (!isDescendantOfPid(processInfo.pid, options.ancestorPid, processInfos)) continue;
|
|
623
|
-
try {
|
|
624
|
-
process.kill(processInfo.pid, "SIGTERM");
|
|
625
|
-
killedPids.push(processInfo.pid);
|
|
626
|
-
} catch (error) {
|
|
627
|
-
warnings.push(`Could not terminate stale Computer Use MCP child pid ${processInfo.pid}: ${describeControlFailure(error)}`);
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
return {
|
|
631
|
-
attempted: true,
|
|
632
|
-
killedPids,
|
|
633
|
-
warnings,
|
|
634
|
-
message: killedPids.length === 0 ? "No stale Computer Use MCP children were found under the scoped Codex app-server process." : `Terminated ${killedPids.length} stale Computer Use MCP child process${killedPids.length === 1 ? "" : "es"} under the scoped Codex app-server process.`
|
|
635
|
-
};
|
|
636
|
-
}
|
|
637
|
-
function parsePsOutput(stdout) {
|
|
638
|
-
return stdout.split(/\r?\n/u).flatMap((line) => {
|
|
639
|
-
const match = /^\s*(\d+)\s+(\d+)\s+(.+)$/u.exec(line);
|
|
640
|
-
if (!match) return [];
|
|
641
|
-
return [{
|
|
642
|
-
pid: Number(match[1]),
|
|
643
|
-
ppid: Number(match[2]),
|
|
644
|
-
command: match[3] ?? ""
|
|
645
|
-
}];
|
|
646
|
-
}).filter((processInfo) => Number.isSafeInteger(processInfo.pid) && processInfo.pid > 0 && Number.isSafeInteger(processInfo.ppid) && processInfo.ppid >= 0);
|
|
647
|
-
}
|
|
648
|
-
function isStaleComputerUseMcpChild(command) {
|
|
649
|
-
return command.includes("SkyComputerUseClient") && /(?:^|\s)mcp(?:\s|$)/u.test(command);
|
|
650
|
-
}
|
|
651
|
-
function isDescendantOfPid(pid, ancestorPid, processInfos) {
|
|
652
|
-
const parents = new Map(processInfos.map((processInfo) => [processInfo.pid, processInfo.ppid]));
|
|
653
|
-
const seen = /* @__PURE__ */ new Set();
|
|
654
|
-
let current = pid;
|
|
655
|
-
while (!seen.has(current)) {
|
|
656
|
-
seen.add(current);
|
|
657
|
-
const parent = parents.get(current);
|
|
658
|
-
if (!parent || parent <= 0) return false;
|
|
659
|
-
if (parent === ancestorPid) return true;
|
|
660
|
-
current = parent;
|
|
661
|
-
}
|
|
662
|
-
return false;
|
|
663
|
-
}
|
|
664
662
|
function createComputerUseRequest(params) {
|
|
665
663
|
if (params.request) return params.request;
|
|
666
664
|
if (params.client) return async (method, requestParams, options) => await params.client.request(method, requestParams, {
|
|
@@ -692,4 +690,104 @@ function resolveComputerUseConfig(params) {
|
|
|
692
690
|
});
|
|
693
691
|
}
|
|
694
692
|
//#endregion
|
|
695
|
-
|
|
693
|
+
//#region extensions/codex/src/app-server/plugin-metadata-cache.ts
|
|
694
|
+
const CODEX_PLUGIN_METADATA_CACHE_TTL_MS = 3600 * 1e3;
|
|
695
|
+
/** Process-local plugin metadata cache with coalesced loads per query. */
|
|
696
|
+
var CodexPluginMetadataCache = class {
|
|
697
|
+
constructor(nowMs = Date.now) {
|
|
698
|
+
this.nowMs = nowMs;
|
|
699
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
700
|
+
this.inFlight = /* @__PURE__ */ new Map();
|
|
701
|
+
this.generations = /* @__PURE__ */ new Map();
|
|
702
|
+
this.clearGeneration = 0;
|
|
703
|
+
}
|
|
704
|
+
/** Returns a fresh cached snapshot without issuing a request. */
|
|
705
|
+
read(appCacheKey, queryKind, requestParams, catalogScope) {
|
|
706
|
+
const entryKey = buildMetadataCacheEntryKey(appCacheKey, queryKind, requestParams, catalogScope);
|
|
707
|
+
const entry = this.entries.get(entryKey);
|
|
708
|
+
if (!entry) return;
|
|
709
|
+
if (entry.expiresAtMs <= this.nowMs()) {
|
|
710
|
+
this.entries.delete(entryKey);
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
return entry.snapshot;
|
|
714
|
+
}
|
|
715
|
+
/** Returns a fresh snapshot or coalesces one catalog or installed-plugin request. */
|
|
716
|
+
async load(params) {
|
|
717
|
+
const entryKey = buildMetadataCacheEntryKey(params.appCacheKey, params.queryKind, params.requestParams, params.catalogScope);
|
|
718
|
+
const cached = this.read(params.appCacheKey, params.queryKind, params.requestParams, params.catalogScope);
|
|
719
|
+
if (cached) return cached;
|
|
720
|
+
const pending = this.inFlight.get(entryKey);
|
|
721
|
+
if (pending) try {
|
|
722
|
+
return await pending.promise;
|
|
723
|
+
} catch {
|
|
724
|
+
if (this.inFlight.get(entryKey) === pending) this.inFlight.delete(entryKey);
|
|
725
|
+
return await this.load(params);
|
|
726
|
+
}
|
|
727
|
+
const generation = this.generations.get(params.appCacheKey) ?? 0;
|
|
728
|
+
const clearGeneration = this.clearGeneration;
|
|
729
|
+
const promise = (async () => {
|
|
730
|
+
const method = params.queryKind === "installed" ? "plugin/installed" : "plugin/list";
|
|
731
|
+
const response = await params.request(method, params.requestParams);
|
|
732
|
+
const snapshot = {
|
|
733
|
+
appCacheKey: params.appCacheKey,
|
|
734
|
+
queryKind: params.queryKind,
|
|
735
|
+
response
|
|
736
|
+
};
|
|
737
|
+
if (generation === (this.generations.get(params.appCacheKey) ?? 0) && clearGeneration === this.clearGeneration && !hasMarketplaceLoadErrors(response) && (params.cacheable?.(response) ?? true)) this.entries.set(entryKey, {
|
|
738
|
+
snapshot,
|
|
739
|
+
expiresAtMs: this.nowMs() + CODEX_PLUGIN_METADATA_CACHE_TTL_MS
|
|
740
|
+
});
|
|
741
|
+
return snapshot;
|
|
742
|
+
})();
|
|
743
|
+
this.inFlight.set(entryKey, {
|
|
744
|
+
appCacheKey: params.appCacheKey,
|
|
745
|
+
promise
|
|
746
|
+
});
|
|
747
|
+
try {
|
|
748
|
+
return await promise;
|
|
749
|
+
} finally {
|
|
750
|
+
if (this.inFlight.get(entryKey)?.promise === promise) this.inFlight.delete(entryKey);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
/** Invalidates all plugin metadata queries for one app-server runtime. */
|
|
754
|
+
invalidate(appCacheKey) {
|
|
755
|
+
this.generations.set(appCacheKey, (this.generations.get(appCacheKey) ?? 0) + 1);
|
|
756
|
+
for (const [entryKey, entry] of this.entries) if (entry.snapshot.appCacheKey === appCacheKey) this.entries.delete(entryKey);
|
|
757
|
+
for (const [entryKey, pending] of this.inFlight) if (pending.appCacheKey === appCacheKey) this.inFlight.delete(entryKey);
|
|
758
|
+
}
|
|
759
|
+
/** Clears snapshots and prevents late in-flight loads from repopulating them. */
|
|
760
|
+
clear() {
|
|
761
|
+
this.clearGeneration += 1;
|
|
762
|
+
this.generations.clear();
|
|
763
|
+
this.entries.clear();
|
|
764
|
+
this.inFlight.clear();
|
|
765
|
+
}
|
|
766
|
+
};
|
|
767
|
+
/** Shared plugin metadata cache used by Codex app-server runtime paths. */
|
|
768
|
+
const defaultCodexPluginMetadataCache = new CodexPluginMetadataCache();
|
|
769
|
+
function hasMarketplaceLoadErrors(response) {
|
|
770
|
+
return response.marketplaceLoadErrors.length > 0;
|
|
771
|
+
}
|
|
772
|
+
function buildMetadataCacheEntryKey(appCacheKey, queryKind, requestParams, catalogScope) {
|
|
773
|
+
if (queryKind !== "installed") {
|
|
774
|
+
const listParams = requestParams;
|
|
775
|
+
const entry = [
|
|
776
|
+
appCacheKey,
|
|
777
|
+
queryKind,
|
|
778
|
+
listParams?.cwds ?? [],
|
|
779
|
+
Array.from(new Set(listParams?.marketplaceKinds ?? [])).toSorted(),
|
|
780
|
+
...catalogScope ? [catalogScope] : []
|
|
781
|
+
];
|
|
782
|
+
return JSON.stringify(entry);
|
|
783
|
+
}
|
|
784
|
+
const installedParams = requestParams;
|
|
785
|
+
return JSON.stringify([
|
|
786
|
+
appCacheKey,
|
|
787
|
+
queryKind,
|
|
788
|
+
installedParams?.cwds ?? [],
|
|
789
|
+
Array.from(new Set(installedParams?.installSuggestionPluginNames ?? [])).toSorted()
|
|
790
|
+
]);
|
|
791
|
+
}
|
|
792
|
+
//#endregion
|
|
793
|
+
export { runCodexComputerUseLiveTest as a, readCodexComputerUseStatus as i, ensureCodexComputerUse as n, killStaleComputerUseMcpChildren as o, installCodexComputerUse as r, defaultCodexPluginMetadataCache as t };
|