@openclaw/codex 2026.8.1-beta.3 → 2026.8.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/dist/api.js +4 -5
- package/dist/{attempt-client-cleanup-URjUlCHg.js → attempt-client-cleanup-CVPvp9dL.js} +47 -5
- package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
- package/dist/{binding-connection-DAvZwp96.js → binding-connection-CCQFs8lf.js} +2 -2
- package/dist/{bounded-turn-4BjrZEwW.js → bounded-turn-rq5tiSXk.js} +13 -18
- package/dist/{capabilities-CH3K57v4.js → capabilities-CGm_94eL.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-D0nZ3qtd.js → command-formatters-C54Yg3eA.js} +2 -2
- package/dist/{command-handlers-DC86lgT4.js → command-handlers-BvOAHTrA.js} +89 -62
- package/dist/{compact-COqgBRny.js → compact-Hd7SAc0N.js} +8 -9
- package/dist/{config-CpNeo5AE.js → config-Cxw3Cl3k.js} +346 -286
- package/dist/doctor-contract-api.js +115 -14
- package/dist/{dynamic-tools-fJZhl4CE.js → dynamic-tools-BFoUcRdx.js} +147 -903
- package/dist/{effective-mcp-catalog-4YKn51aG.js → effective-mcp-catalog-BTJHnDSx.js} +2 -2
- package/dist/{event-projector-assistant-message-BwxV4d6N.js → event-projector-assistant-message-C5-Ds8mA.js} +18 -1
- package/dist/{event-projector-usage-CLwNEJqW.js → event-projector-usage-D3PHFFXh.js} +3 -3
- package/dist/{harness-DoKQcF8n.js → harness-DVfUQBlQ.js} +42 -52
- package/dist/harness.js +1 -1
- package/dist/index.js +278 -295
- package/dist/{isolated-completion-DPMtlH9r.js → isolated-completion-Cbbx_5Ed.js} +4 -4
- package/dist/launch-args-sXOAg0SX.js +84 -0
- package/dist/{managed-binary-By4FZC6i.js → managed-binary-ZkGodW19.js} +43 -7
- package/dist/media-understanding-provider.js +1 -1
- package/dist/model-catalog-o6Cgjoss.js +101 -0
- package/dist/{models-CZw1wClT.js → models-DgFWSuxA.js} +25 -28
- package/dist/{native-subagent-monitor-GGq3RnOo.js → native-subagent-monitor-CwFyoylz.js} +207 -30
- package/dist/{node-exec-server.runtime-Bsu1LdFZ.js → node-exec-server.runtime-DXrqpw1c.js} +8 -5
- package/dist/{plugin-approval-roundtrip-C75Yiiwc.js → plugin-approval-roundtrip-D80UZiJ_.js} +1 -1
- package/dist/{plugin-marketplace-discovery-CSWDkMrP.js → plugin-marketplace-discovery-mdmScYOj.js} +30 -39
- package/dist/{plugin-metadata-cache-BXH5NF-4.js → plugin-metadata-cache-CulOABwu.js} +162 -135
- package/dist/{protocol-validators-VAVyEnDp.js → protocol-validators-Bg5rpNxk.js} +148 -5
- package/dist/{rate-limits-BI1dMHDG.js → rate-limits-hFtzt2Up.js} +1 -1
- package/dist/{sandbox-guard-C1qEeZ5C.js → request-CCm4LaED.js} +183 -2
- package/dist/{run-attempt-BV3HzuCf.js → run-attempt-BwNQDH2u.js} +599 -361
- package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-DeBvleJw.js} +1 -1
- package/dist/{session-binding-BTrLf9Qm.js → session-binding-q2WSTVmC.js} +195 -122
- package/dist/{session-catalog-ezP_UcRM.js → session-catalog-C2Tae4rI.js} +229 -122
- package/dist/session-catalog-home-id-DAKUrm3C.js +112 -0
- package/dist/{session-cli-B1hKvfkI.js → session-cli-BuDjm5Ou.js} +1 -1
- package/dist/session-permission-policy-gLm40Vtq.js +160 -0
- package/dist/session-retirement-CdkI0bvb.js +90 -0
- package/dist/{session-upstream-marker-D_2npHlA.js → session-upstream-marker-Bcy33kam.js} +2 -3
- package/dist/{settled-turn-finalizer-Dx1onIqg.js → settled-turn-finalizer-B8JJcxCi.js} +7 -6
- package/dist/{shared-client-Dw-rzii0.js → shared-client-kNkljY-R.js} +1720 -786
- package/dist/{side-question-DbXkJZzg.js → side-question-GwD73tX6.js} +69 -39
- package/dist/{thread-lifecycle-DKdrnTMX.js → thread-lifecycle-Ss-uwnC4.js} +852 -359
- package/dist/{thread-ownership-i2NBwDUL.js → thread-ownership-CeYBqg_4.js} +18 -8
- package/dist/{plugin-app-cache-key-DMNQ8Zi8.js → thread-resume-DF54hagX.js} +52 -6
- package/dist/{transcript-mirror-BU0_LKAL.js → transcript-mirror-CkEQIna-.js} +112 -13
- package/dist/transport-stdio-C7-s9TLG.js +708 -0
- package/dist/{upstream-session-fork-BDVJCLAD.js → upstream-session-fork-BACGlOFa.js} +78 -86
- package/dist/{usage-9dKJCgcy.js → usage-C2l8Mils.js} +3 -3
- package/dist/{web-search-provider.runtime-DCdx4DGu.js → web-search-provider.runtime-B2XgRdFv.js} +3 -3
- package/openclaw.plugin.json +19 -1
- package/package.json +8 -8
- package/dist/app-server-policy-bg5QPSVP.js +0 -25
- package/dist/command-rpc-xUIIonsO.js +0 -90
- package/dist/incognito-session-ET_ufDH-.js +0 -2
- package/dist/model-catalog-CmGoqVKB.js +0 -48
- package/dist/request-DSK0W6YI.js +0 -157
- package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
- package/dist/session-retirement-CE4iMiLh.js +0 -36
- package/dist/thread-resume-CdJk2Ehf.js +0 -30
- package/dist/transport-stdio-DhoGy33Z.js +0 -99
package/dist/{plugin-marketplace-discovery-CSWDkMrP.js → plugin-marketplace-discovery-mdmScYOj.js}
RENAMED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-
|
|
4
|
-
import {
|
|
5
|
-
import { r as formatCodexDisplayText } from "./command-formatters-
|
|
6
|
-
import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-
|
|
1
|
+
import { k as isCodexFastServiceTier } from "./config-Cxw3Cl3k.js";
|
|
2
|
+
import { c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-kNkljY-R.js";
|
|
3
|
+
import { o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-q2WSTVmC.js";
|
|
4
|
+
import { E as resolveCodexAppServerRequestModelSelection, O as resolveCodexBindingModelProviderFallback } from "./thread-lifecycle-Ss-uwnC4.js";
|
|
5
|
+
import { r as formatCodexDisplayText } from "./command-formatters-C54Yg3eA.js";
|
|
6
|
+
import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-CCQFs8lf.js";
|
|
7
7
|
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
8
8
|
import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
|
9
9
|
import { getSessionEntry, patchSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
10
10
|
import { ModelSelectionLockedError, applyModelOverrideWithAuthProfileCompatibility } from "openclaw/plugin-sdk/model-session-runtime";
|
|
11
11
|
//#region extensions/codex/src/command-authorization.ts
|
|
12
12
|
const CODEX_NATIVE_EXECUTION_AUTH_ERROR = "Only an owner or operator.admin can control Codex native execution.";
|
|
13
|
+
const CODEX_HOST_INSPECTION_AUTH_ERROR = "Only an owner or operator.admin can inspect Codex host state.";
|
|
13
14
|
const CODEX_FULL_PERMISSIONS_AUTH_ERROR = "Full Codex permissions require operator.admin. Choose Admin in the Control UI permission picker, or use an admin-authenticated CLI.";
|
|
14
15
|
function hasCodexAdminScope(ctx) {
|
|
15
16
|
return ctx.gatewayClientScopes?.includes("operator.admin") === true;
|
|
@@ -145,23 +146,23 @@ async function setCodexConversationModel(params) {
|
|
|
145
146
|
});
|
|
146
147
|
const nextModel = modelSelection.model;
|
|
147
148
|
const modelChanged = nextModel !== binding.model || nextModelProvider !== binding.modelProvider;
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (session) {
|
|
149
|
+
const projectionPatch = modelChanged && binding.contextEngine?.projection ? { contextEngine: {
|
|
150
|
+
...binding.contextEngine,
|
|
151
|
+
projection: void 0
|
|
152
|
+
} } : {};
|
|
153
|
+
const identity = params.identity;
|
|
154
|
+
if (identity.kind === "session" && identity.sessionKey) {
|
|
154
155
|
if (!await patchSessionEntry({
|
|
155
|
-
agentId:
|
|
156
|
-
storePath: resolveStorePath(params.config?.session?.store, { agentId:
|
|
157
|
-
sessionKey:
|
|
156
|
+
agentId: identity.agentId,
|
|
157
|
+
storePath: resolveStorePath(params.config?.session?.store, { agentId: identity.agentId }),
|
|
158
|
+
sessionKey: identity.sessionKey,
|
|
158
159
|
requireWriteSuccess: true,
|
|
159
160
|
replaceEntry: true,
|
|
160
161
|
update: (entry) => {
|
|
161
|
-
if (entry.sessionId !==
|
|
162
|
+
if (entry.sessionId !== identity.sessionId) throw new Error("Codex session changed while applying the model selection.");
|
|
162
163
|
applyModelOverrideWithAuthProfileCompatibility({
|
|
163
164
|
cfg: params.config ?? {},
|
|
164
|
-
agentDir: params.agentDir ?? resolveAgentDir(params.config ?? {},
|
|
165
|
+
agentDir: params.agentDir ?? resolveAgentDir(params.config ?? {}, identity.agentId),
|
|
165
166
|
entry,
|
|
166
167
|
currentProvider: binding.modelProvider ?? "openai",
|
|
167
168
|
selection: {
|
|
@@ -173,25 +174,11 @@ async function setCodexConversationModel(params) {
|
|
|
173
174
|
return entry;
|
|
174
175
|
}
|
|
175
176
|
})) throw new Error("Codex session changed while applying the model selection.");
|
|
176
|
-
if (
|
|
177
|
-
model: nextModel,
|
|
178
|
-
modelProvider: nextModelProvider,
|
|
179
|
-
...modelChanged && binding.contextEngine?.projection ? { contextEngine: {
|
|
180
|
-
...binding.contextEngine,
|
|
181
|
-
projection: void 0
|
|
182
|
-
} } : {}
|
|
183
|
-
});
|
|
184
|
-
else if (modelChanged && binding.contextEngine?.projection) await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, { contextEngine: {
|
|
185
|
-
...binding.contextEngine,
|
|
186
|
-
projection: void 0
|
|
187
|
-
} });
|
|
177
|
+
if (modelChanged && binding.contextEngine?.projection) await patchThreadBinding(params.bindingStore, identity, binding.threadId, projectionPatch);
|
|
188
178
|
} else await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, {
|
|
189
179
|
model: nextModel,
|
|
190
180
|
modelProvider: nextModelProvider,
|
|
191
|
-
...
|
|
192
|
-
...binding.contextEngine,
|
|
193
|
-
projection: void 0
|
|
194
|
-
} } : {}
|
|
181
|
+
...projectionPatch
|
|
195
182
|
});
|
|
196
183
|
return `Codex model set to ${formatCodexDisplayText(nextModel)}.`;
|
|
197
184
|
}
|
|
@@ -223,12 +210,11 @@ async function setCodexConversationPermissions(params) {
|
|
|
223
210
|
replaceEntry: true,
|
|
224
211
|
update: (entry) => {
|
|
225
212
|
if (entry.sessionId !== params.session.sessionId) throw new Error("Codex session changed while applying the permission mode.");
|
|
226
|
-
|
|
227
|
-
else delete entry.permissionMode;
|
|
213
|
+
entry.permissionMode = params.mode === "yolo" ? "full" : "guarded";
|
|
228
214
|
return entry;
|
|
229
215
|
}
|
|
230
216
|
})) throw new Error("Codex session changed while applying the permission mode.");
|
|
231
|
-
return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "
|
|
217
|
+
return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "guarded"}.`;
|
|
232
218
|
}
|
|
233
219
|
function parseCodexFastModeArg(arg) {
|
|
234
220
|
const normalized = arg?.trim().toLowerCase();
|
|
@@ -240,10 +226,15 @@ function parseCodexPermissionsModeArg(arg) {
|
|
|
240
226
|
const normalized = arg?.trim().toLowerCase();
|
|
241
227
|
if (!normalized || normalized === "status") return;
|
|
242
228
|
if (normalized === "yolo" || normalized === "full" || normalized === "full-access") return "yolo";
|
|
243
|
-
if (
|
|
229
|
+
if ([
|
|
230
|
+
"default",
|
|
231
|
+
"guardian",
|
|
232
|
+
"guarded",
|
|
233
|
+
"approve"
|
|
234
|
+
].includes(normalized)) return "default";
|
|
244
235
|
}
|
|
245
236
|
function formatPermissionsMode(mode) {
|
|
246
|
-
return mode === "full" ? "full access" : "default";
|
|
237
|
+
return mode === "full" ? "full access" : mode ?? "default";
|
|
247
238
|
}
|
|
248
239
|
async function requireThreadBinding(bindingStore, identity) {
|
|
249
240
|
const binding = await bindingStore.read(identity);
|
|
@@ -396,4 +387,4 @@ function boundedCatalogText(value) {
|
|
|
396
387
|
return sanitized.replace(/\s+/g, " ").trim().slice(0, MAX_PLUGIN_DESCRIPTION_LENGTH);
|
|
397
388
|
}
|
|
398
389
|
//#endregion
|
|
399
|
-
export { parseCodexPermissionsModeArg as a, setCodexConversationModel as c, stopCodexConversationTurn as d, trackCodexConversationActiveTurn as f,
|
|
390
|
+
export { hasCodexAdminScope as _, parseCodexPermissionsModeArg as a, setCodexConversationModel as c, stopCodexConversationTurn as d, trackCodexConversationActiveTurn as f, canMutateCodexHost as g, CODEX_NATIVE_EXECUTION_AUTH_ERROR as h, parseCodexFastModeArg as i, setCodexConversationPermissions as l, CODEX_HOST_INSPECTION_AUTH_ERROR as m, parseCodexPluginMarketplaceId as n, readCodexConversationActiveTurn as o, CODEX_FULL_PERMISSIONS_AUTH_ERROR as p, formatPermissionsMode as r, setCodexConversationFastMode as s, discoverCodexMarketplacePlugins as t, steerCodexConversationTurn as u };
|
|
@@ -1,91 +1,11 @@
|
|
|
1
|
-
import { i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig } from "./config-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { P as resolveCodexAppServerHomeDir, i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig } from "./config-Cxw3Cl3k.js";
|
|
2
|
+
import { At as reconcileCodexComputerUseStartArtifacts, G as isCodexAppServerConnectionClosedError, K as isCodexAppServerIndeterminateRequestCancellationError, O as acquireCodexNativeConfigFence, S as waitForCodexAppServerClientDesktopGenerationDrain, Ut as resolveCodexManagedBundledMarketplacePath, Wt as assertNotSymlink, c as getLeasedSharedCodexAppServerClient, d as readCodexAppServerClientDesktopGeneration, g as resolveCodexNativeConfigFenceKey, h as releaseLeasedSharedCodexAppServerClient, p as readCodexAppServerClientProcessIdentity, q as isCodexAppServerIndeterminateTransportError, t as assertCodexAppServerClientStartSelectionCurrent, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-kNkljY-R.js";
|
|
3
|
+
import { l as resolveMacOSDesktopCodexBundledMarketplaceCandidates, s as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, t as isManagedCodexDesktopCommand } from "./managed-binary-ZkGodW19.js";
|
|
4
|
+
import { i as requestCodexAppServerJson } from "./request-CCm4LaED.js";
|
|
5
|
+
import { n as describeControlFailure } from "./capabilities-CGm_94eL.js";
|
|
6
|
+
import fs from "node:fs/promises";
|
|
7
|
+
import path from "node:path";
|
|
5
8
|
import { existsSync } from "node:fs";
|
|
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
|
|
89
9
|
//#region extensions/codex/src/app-server/computer-use.ts
|
|
90
10
|
/**
|
|
91
11
|
* Computer Use plugin/MCP readiness checks and optional install flow for Codex
|
|
@@ -99,8 +19,9 @@ var CodexComputerUseSetupError = class extends Error {
|
|
|
99
19
|
}
|
|
100
20
|
};
|
|
101
21
|
const CURATED_MARKETPLACE_POLL_INTERVAL_MS = 2e3;
|
|
22
|
+
const BUNDLED_MARKETPLACE_NAME = "openai-bundled";
|
|
102
23
|
const COMPUTER_USE_MARKETPLACE_NAME_PRIORITY = [
|
|
103
|
-
|
|
24
|
+
BUNDLED_MARKETPLACE_NAME,
|
|
104
25
|
"openai-curated",
|
|
105
26
|
"openai-api-curated",
|
|
106
27
|
"openai-curated-remote",
|
|
@@ -172,72 +93,96 @@ async function installCodexComputerUse(params = {}) {
|
|
|
172
93
|
}
|
|
173
94
|
async function inspectCodexComputerUse(params) {
|
|
174
95
|
if (!params.installPlugin) return await inspectCodexComputerUseWithoutFence(params);
|
|
175
|
-
const
|
|
96
|
+
const resolvedRuntime = resolveCodexAppServerRuntimeOptions({
|
|
176
97
|
pluginConfig: params.pluginConfig,
|
|
177
98
|
managedCommandOrder: "desktop-first"
|
|
178
99
|
});
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
agentDir: params.agentDir,
|
|
183
|
-
config: params.config
|
|
184
|
-
});
|
|
185
|
-
if (!fenceKey) return await inspectCodexComputerUseWithoutFence(params);
|
|
186
|
-
const release = await acquireCodexNativeConfigFence(fenceKey, {
|
|
187
|
-
signal: params.signal,
|
|
188
|
-
timeoutMs: params.timeoutMs ?? runtime?.requestTimeoutMs,
|
|
189
|
-
timeoutMessage: "Codex Computer Use install timed out waiting for native config",
|
|
190
|
-
abortMessage: "Codex Computer Use install aborted waiting for native config"
|
|
191
|
-
});
|
|
192
|
-
let releaseFenceOnReturn = true;
|
|
100
|
+
const operationTimeoutMs = params.timeoutMs ?? resolvedRuntime.requestTimeoutMs;
|
|
101
|
+
const deadline = operationTimeoutMs > 0 ? Date.now() + operationTimeoutMs : void 0;
|
|
102
|
+
const remainingTimeoutMs = () => deadline === void 0 ? operationTimeoutMs : Math.max(1, deadline - Date.now());
|
|
193
103
|
let leasedClient;
|
|
194
104
|
try {
|
|
195
105
|
let client = params.client;
|
|
196
106
|
if (!client && !params.request) {
|
|
197
|
-
if (!runtime) throw new Error("Computer Use install could not resolve its app-server runtime");
|
|
198
107
|
client = await getLeasedSharedCodexAppServerClient({
|
|
199
|
-
startOptions:
|
|
108
|
+
startOptions: resolvedRuntime.start,
|
|
200
109
|
pluginConfig: params.pluginConfig,
|
|
201
|
-
timeoutMs:
|
|
110
|
+
timeoutMs: remainingTimeoutMs(),
|
|
202
111
|
config: params.config,
|
|
203
112
|
agentDir: params.agentDir,
|
|
204
113
|
abandonSignal: params.signal
|
|
205
114
|
});
|
|
206
115
|
leasedClient = client;
|
|
207
116
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
117
|
+
const explicitManagedInstall = client && !resolveCodexComputerUseConfig({ pluginConfig: params.pluginConfig }).autoInstall ? await resolveExplicitManagedComputerUseInstallContext({
|
|
118
|
+
...params,
|
|
119
|
+
client
|
|
120
|
+
}) : void 0;
|
|
121
|
+
if (explicitManagedInstall) {
|
|
122
|
+
await waitForCodexAppServerClientDesktopGenerationDrain({
|
|
123
|
+
client: explicitManagedInstall.client,
|
|
124
|
+
timeoutMs: remainingTimeoutMs(),
|
|
125
|
+
...params.signal ? { signal: params.signal } : {}
|
|
216
126
|
});
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
127
|
+
assertCodexAppServerClientStartSelectionCurrent({ client: explicitManagedInstall.client });
|
|
128
|
+
}
|
|
129
|
+
const inspectionParams = {
|
|
130
|
+
...params,
|
|
131
|
+
...client ? { client } : {},
|
|
132
|
+
timeoutMs: remainingTimeoutMs(),
|
|
133
|
+
...explicitManagedInstall ? { explicitManagedInstall } : {}
|
|
134
|
+
};
|
|
135
|
+
const fenceKey = resolveCodexNativeConfigFenceKey({
|
|
136
|
+
client,
|
|
137
|
+
startOptions: resolvedRuntime.start,
|
|
138
|
+
agentDir: params.agentDir,
|
|
139
|
+
config: params.config
|
|
140
|
+
});
|
|
141
|
+
if (!fenceKey) return await inspectCodexComputerUseWithoutFence(inspectionParams);
|
|
142
|
+
const release = await acquireCodexNativeConfigFence(fenceKey, {
|
|
143
|
+
signal: params.signal,
|
|
144
|
+
timeoutMs: remainingTimeoutMs(),
|
|
145
|
+
timeoutMessage: "Codex Computer Use install timed out waiting for native config",
|
|
146
|
+
abortMessage: "Codex Computer Use install aborted waiting for native config"
|
|
147
|
+
});
|
|
148
|
+
let releaseFenceOnReturn = true;
|
|
149
|
+
try {
|
|
150
|
+
try {
|
|
151
|
+
return await inspectCodexComputerUseWithoutFence({
|
|
152
|
+
...inspectionParams,
|
|
153
|
+
releaseNativeConfigFence: release
|
|
154
|
+
});
|
|
155
|
+
} catch (error) {
|
|
156
|
+
if (client && (isCodexAppServerIndeterminateRequestCancellationError(error) || isCodexAppServerIndeterminateTransportError(error) || isCodexAppServerConnectionClosedError(error))) {
|
|
157
|
+
releaseFenceOnReturn = false;
|
|
158
|
+
await client.closeAndRunAfterExit(release, "Computer Use config mutation");
|
|
159
|
+
}
|
|
160
|
+
throw error;
|
|
221
161
|
}
|
|
222
|
-
throw error;
|
|
223
162
|
} finally {
|
|
224
|
-
if (
|
|
163
|
+
if (releaseFenceOnReturn) release();
|
|
225
164
|
}
|
|
226
165
|
} finally {
|
|
227
|
-
if (
|
|
166
|
+
if (leasedClient) releaseLeasedSharedCodexAppServerClient(leasedClient);
|
|
228
167
|
}
|
|
229
168
|
}
|
|
230
169
|
async function inspectCodexComputerUseWithoutFence(params) {
|
|
231
170
|
const request = createComputerUseRequest(params);
|
|
232
|
-
|
|
233
|
-
|
|
171
|
+
if (params.installPlugin) {
|
|
172
|
+
if (!resolveCodexComputerUseConfig({ pluginConfig: params.pluginConfig }).autoInstall) await prepareExplicitManagedComputerUseInstall(params);
|
|
173
|
+
await request("experimentalFeature/enablement/set", { enablement: { plugins: true } });
|
|
174
|
+
}
|
|
175
|
+
const managedMarketplacePath = await resolveClientManagedBundledMarketplacePath(params.client, params.agentDir);
|
|
176
|
+
const managedCodexHome = managedMarketplacePath ? params.client?.getRuntimeIdentity()?.codexHome : void 0;
|
|
177
|
+
if (params.installPlugin && managedCodexHome) await assertNotSymlink(path.join(managedCodexHome, "config.toml"), "Codex config");
|
|
234
178
|
const marketplace = await resolveMarketplaceRef({
|
|
235
179
|
request,
|
|
236
180
|
config: params.computerUseConfig,
|
|
237
181
|
allowAdd: params.installPlugin,
|
|
238
182
|
signal: params.signal,
|
|
239
|
-
defaultBundledMarketplacePath: params.defaultBundledMarketplacePath,
|
|
240
|
-
defaultBundledMarketplacePathCandidates: params.defaultBundledMarketplacePathCandidates
|
|
183
|
+
defaultBundledMarketplacePath: params.defaultBundledMarketplacePath ?? managedMarketplacePath,
|
|
184
|
+
defaultBundledMarketplacePathCandidates: params.defaultBundledMarketplacePathCandidates,
|
|
185
|
+
managedCodexHome
|
|
241
186
|
});
|
|
242
187
|
if (!marketplace.marketplace) return unavailableStatus(params.computerUseConfig, "marketplace_missing", marketplace.message ?? `No Codex marketplace containing ${params.computerUseConfig.pluginName} is registered. Configure computerUse.marketplaceSource or computerUse.marketplacePath, then run /codex computer-use install.`);
|
|
243
188
|
const pluginInspection = await ensureComputerUsePlugin({
|
|
@@ -252,10 +197,59 @@ async function inspectCodexComputerUseWithoutFence(params) {
|
|
|
252
197
|
config: params.computerUseConfig,
|
|
253
198
|
plugin: pluginInspection.plugin,
|
|
254
199
|
installPlugin: params.installPlugin,
|
|
255
|
-
repairComputerUseMcpChildren,
|
|
256
200
|
releaseNativeConfigFence: params.releaseNativeConfigFence
|
|
257
201
|
});
|
|
258
202
|
}
|
|
203
|
+
async function prepareExplicitManagedComputerUseInstall(params) {
|
|
204
|
+
const context = params.explicitManagedInstall;
|
|
205
|
+
if (!context) return;
|
|
206
|
+
await reconcileCodexComputerUseStartArtifacts({
|
|
207
|
+
startOptions: {
|
|
208
|
+
transport: "stdio",
|
|
209
|
+
command: context.command,
|
|
210
|
+
commandSource: "resolved-managed",
|
|
211
|
+
args: ["app-server"],
|
|
212
|
+
headers: {},
|
|
213
|
+
env: { CODEX_HOME: context.codexHome }
|
|
214
|
+
},
|
|
215
|
+
agentDir: context.agentDir,
|
|
216
|
+
pluginConfig: { computerUse: {
|
|
217
|
+
...params.computerUseConfig,
|
|
218
|
+
autoInstall: true
|
|
219
|
+
} },
|
|
220
|
+
ownsIsolatedCodexHome: true,
|
|
221
|
+
desktopGeneration: context.desktopGeneration,
|
|
222
|
+
forceCacheRefresh: true,
|
|
223
|
+
assertCurrent: () => assertCodexAppServerClientStartSelectionCurrent({ client: context.client })
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async function resolveExplicitManagedComputerUseInstallContext(params) {
|
|
227
|
+
if (!params.agentDir) return;
|
|
228
|
+
const codexHome = params.client.getRuntimeIdentity()?.codexHome;
|
|
229
|
+
const processIdentity = readCodexAppServerClientProcessIdentity(params.client);
|
|
230
|
+
const command = processIdentity?.nativeCommand ?? (processIdentity && isManagedCodexDesktopCommand(processIdentity.command, "darwin") ? processIdentity.command : void 0);
|
|
231
|
+
if (!codexHome || !command) return;
|
|
232
|
+
const desktopGeneration = readCodexAppServerClientDesktopGeneration(params.client);
|
|
233
|
+
if (!desktopGeneration) throw new Error("Codex Computer Use install requires a desktop-generation-bound client; reconnect and retry.");
|
|
234
|
+
const expectedHome = resolveCodexAppServerHomeDir(params.agentDir);
|
|
235
|
+
const [actualRealHome, expectedRealHome] = await Promise.all([fs.realpath(codexHome).catch(() => void 0), fs.realpath(expectedHome).catch(() => void 0)]);
|
|
236
|
+
if (!actualRealHome || actualRealHome !== expectedRealHome) return;
|
|
237
|
+
return {
|
|
238
|
+
client: params.client,
|
|
239
|
+
agentDir: params.agentDir,
|
|
240
|
+
codexHome,
|
|
241
|
+
command,
|
|
242
|
+
desktopGeneration
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
async function resolveClientManagedBundledMarketplacePath(client, agentDir) {
|
|
246
|
+
const codexHome = client?.getRuntimeIdentity()?.codexHome;
|
|
247
|
+
if (!codexHome || !agentDir) return;
|
|
248
|
+
const [actualRealHome, expectedRealHome] = await Promise.all([fs.realpath(codexHome).catch(() => void 0), fs.realpath(resolveCodexAppServerHomeDir(agentDir)).catch(() => void 0)]);
|
|
249
|
+
if (!actualRealHome || actualRealHome !== expectedRealHome) return;
|
|
250
|
+
const managedPath = resolveCodexManagedBundledMarketplacePath(codexHome);
|
|
251
|
+
return existsSync(managedPath) ? managedPath : void 0;
|
|
252
|
+
}
|
|
259
253
|
async function ensureComputerUsePlugin(params) {
|
|
260
254
|
let plugin = await readComputerUsePlugin(params.request, params.marketplace, params.config.pluginName);
|
|
261
255
|
if (!plugin.summary.installed || !plugin.summary.enabled) {
|
|
@@ -320,8 +314,7 @@ async function readComputerUseTools(params) {
|
|
|
320
314
|
params.releaseNativeConfigFence?.();
|
|
321
315
|
const { liveTest, repair } = await runCodexComputerUseLiveTest({
|
|
322
316
|
request: params.request,
|
|
323
|
-
config: params.config
|
|
324
|
-
repairComputerUseMcpChildren: params.repairComputerUseMcpChildren
|
|
317
|
+
config: params.config
|
|
325
318
|
});
|
|
326
319
|
const compatibilityStartupAllowed = !liveTest.ok && !params.config.strictReadiness;
|
|
327
320
|
return {
|
|
@@ -351,8 +344,6 @@ async function runCodexComputerUseLiveTest(params) {
|
|
|
351
344
|
threadId = (await params.request("thread/start", {
|
|
352
345
|
input: [],
|
|
353
346
|
developerInstructions: COMPUTER_USE_LIVE_TEST_THREAD_NAME,
|
|
354
|
-
sandbox: "danger-full-access",
|
|
355
|
-
approvalPolicy: "never",
|
|
356
347
|
ephemeral: true
|
|
357
348
|
}, { timeoutMs: params.config.liveTestTimeoutMs })).thread.id;
|
|
358
349
|
await params.request("mcpServer/tool/call", {
|
|
@@ -369,19 +360,19 @@ async function runCodexComputerUseLiveTest(params) {
|
|
|
369
360
|
attempts: attempt + 1,
|
|
370
361
|
timeoutMs: params.config.liveTestTimeoutMs,
|
|
371
362
|
retried: attempt > 0,
|
|
372
|
-
repaired: Boolean(repair?.attempted),
|
|
363
|
+
repaired: Boolean(repair?.attempted && repair.warnings.length === 0),
|
|
373
364
|
durationMs: Math.max(0, Date.now() - startedAt),
|
|
374
365
|
message: "Computer Use live test passed."
|
|
375
366
|
},
|
|
376
367
|
...repair ? { repair } : {}
|
|
377
368
|
};
|
|
378
369
|
} catch (error) {
|
|
370
|
+
if (isCodexAppServerStartSelectionChangedError(error)) throw error;
|
|
379
371
|
lastError = error;
|
|
380
|
-
if (attempt >= COMPUTER_USE_LIVE_TEST_RETRY_COUNT) break;
|
|
381
|
-
if (params.config.autoRepair) repair = params.repairComputerUseMcpChildren ? await params.repairComputerUseMcpChildren() : scopedRepairUnavailableStatus();
|
|
382
372
|
} finally {
|
|
383
373
|
if (threadId) await cleanupComputerUseProbeThread(params.request, threadId, params.config);
|
|
384
374
|
}
|
|
375
|
+
if (attempt < COMPUTER_USE_LIVE_TEST_RETRY_COUNT && params.config.autoRepair) repair = await repairComputerUseMcpRuntime(params.request, params.config);
|
|
385
376
|
}
|
|
386
377
|
const errorMessage = describeControlFailure(lastError);
|
|
387
378
|
return {
|
|
@@ -392,7 +383,7 @@ async function runCodexComputerUseLiveTest(params) {
|
|
|
392
383
|
attempts: 2,
|
|
393
384
|
timeoutMs: params.config.liveTestTimeoutMs,
|
|
394
385
|
retried: true,
|
|
395
|
-
repaired: Boolean(repair?.attempted),
|
|
386
|
+
repaired: Boolean(repair?.attempted && repair.warnings.length === 0),
|
|
396
387
|
durationMs: Math.max(0, Date.now() - startedAt),
|
|
397
388
|
message: `Computer Use live test failed after 2 attempts: ${errorMessage}`,
|
|
398
389
|
error: errorMessage
|
|
@@ -400,6 +391,25 @@ async function runCodexComputerUseLiveTest(params) {
|
|
|
400
391
|
...repair ? { repair } : {}
|
|
401
392
|
};
|
|
402
393
|
}
|
|
394
|
+
async function repairComputerUseMcpRuntime(request, config) {
|
|
395
|
+
try {
|
|
396
|
+
await request("config/mcpServer/reload", void 0, { timeoutMs: config.liveTestTimeoutMs });
|
|
397
|
+
return {
|
|
398
|
+
attempted: true,
|
|
399
|
+
killedPids: [],
|
|
400
|
+
warnings: [],
|
|
401
|
+
message: "Reloaded Computer Use MCP servers through Codex app-server."
|
|
402
|
+
};
|
|
403
|
+
} catch (error) {
|
|
404
|
+
const message = `Could not reload Computer Use MCP servers: ${describeControlFailure(error)}`;
|
|
405
|
+
return {
|
|
406
|
+
attempted: true,
|
|
407
|
+
killedPids: [],
|
|
408
|
+
warnings: [message],
|
|
409
|
+
message
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
}
|
|
403
413
|
async function cleanupComputerUseProbeThread(request, threadId, config) {
|
|
404
414
|
await Promise.allSettled([request("thread/unsubscribe", { threadId }, { timeoutMs: config.liveTestTimeoutMs }), request("thread/archive", { threadId }, { timeoutMs: config.liveTestTimeoutMs })]);
|
|
405
415
|
}
|
|
@@ -420,6 +430,12 @@ async function resolveMarketplaceRef(params) {
|
|
|
420
430
|
let candidates = await listComputerUseMarketplaceCandidates(params.request, params.config);
|
|
421
431
|
const bundledMarketplacePath = resolveBundledComputerUseMarketplacePath(params);
|
|
422
432
|
if (candidates.length === 0 && bundledMarketplacePath && shouldAddBundledComputerUseMarketplace(params)) {
|
|
433
|
+
if (params.managedCodexHome) await migrateLegacyBundledMarketplaceSource({
|
|
434
|
+
request: params.request,
|
|
435
|
+
bundledMarketplacePath,
|
|
436
|
+
legacySources: params.defaultBundledMarketplacePathCandidates,
|
|
437
|
+
userConfigPath: path.join(params.managedCodexHome, "config.toml")
|
|
438
|
+
});
|
|
423
439
|
const added = await params.request("marketplace/add", { source: bundledMarketplacePath });
|
|
424
440
|
preferredMarketplaceName ??= added.marketplaceName;
|
|
425
441
|
candidates = await listComputerUseMarketplaceCandidates(params.request, params.config);
|
|
@@ -444,6 +460,16 @@ async function resolveMarketplaceRef(params) {
|
|
|
444
460
|
const marketplace = candidates[0];
|
|
445
461
|
return marketplace ? { marketplace } : {};
|
|
446
462
|
}
|
|
463
|
+
async function migrateLegacyBundledMarketplaceSource(params) {
|
|
464
|
+
const response = await params.request("config/read", { includeLayers: false });
|
|
465
|
+
const bundled = response.config.marketplaces?.[BUNDLED_MARKETPLACE_NAME];
|
|
466
|
+
const sourceOrigin = response.origins[`marketplaces.${BUNDLED_MARKETPLACE_NAME}.source`];
|
|
467
|
+
if (bundled?.source_type !== "local" || !bundled.source || sourceOrigin?.name.type !== "user" || sourceOrigin.name.profile !== null || path.resolve(sourceOrigin.name.file) !== path.resolve(params.userConfigPath)) return;
|
|
468
|
+
const configuredSource = path.resolve(bundled.source);
|
|
469
|
+
if (configuredSource === path.resolve(params.bundledMarketplacePath)) return;
|
|
470
|
+
if (!(params.legacySources ?? resolveMacOSDesktopCodexBundledMarketplaceCandidates()).some((source) => path.resolve(source) === configuredSource)) return;
|
|
471
|
+
await params.request("marketplace/remove", { marketplaceName: BUNDLED_MARKETPLACE_NAME });
|
|
472
|
+
}
|
|
447
473
|
async function listComputerUseMarketplaceCandidates(request, config) {
|
|
448
474
|
return findComputerUseMarketplaces(await request("plugin/list", { cwds: [] }), config.pluginName);
|
|
449
475
|
}
|
|
@@ -456,6 +482,7 @@ function shouldAddBundledComputerUseMarketplace(params) {
|
|
|
456
482
|
}
|
|
457
483
|
function resolveBundledComputerUseMarketplacePath(params) {
|
|
458
484
|
if (params.defaultBundledMarketplacePath) return existsSync(params.defaultBundledMarketplacePath) ? params.defaultBundledMarketplacePath : void 0;
|
|
485
|
+
if (!params.defaultBundledMarketplacePathCandidates) return;
|
|
459
486
|
return resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath({ candidates: params.defaultBundledMarketplacePathCandidates });
|
|
460
487
|
}
|
|
461
488
|
function findComputerUseMarketplaces(listed, pluginName) {
|
|
@@ -793,4 +820,4 @@ function buildMetadataCacheEntryKey(appCacheKey, queryKind, requestParams, catal
|
|
|
793
820
|
]);
|
|
794
821
|
}
|
|
795
822
|
//#endregion
|
|
796
|
-
export { runCodexComputerUseLiveTest as a, readCodexComputerUseStatus as i, ensureCodexComputerUse as n,
|
|
823
|
+
export { runCodexComputerUseLiveTest as a, readCodexComputerUseStatus as i, ensureCodexComputerUse as n, installCodexComputerUse as r, defaultCodexPluginMetadataCache as t };
|