@openclaw/codex 2026.7.2-beta.7 → 2026.8.1-beta.3
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/api.js +147 -0
- package/dist/app-server-policy-bg5QPSVP.js +25 -0
- package/dist/attempt-client-cleanup-URjUlCHg.js +735 -0
- package/dist/binding-connection-DAvZwp96.js +45 -0
- package/dist/{bounded-turn-D2ZAgZVz.js → bounded-turn-4BjrZEwW.js} +63 -56
- package/dist/{capabilities-BFDTVYr4.js → capabilities-CH3K57v4.js} +8 -2
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-C336eRVS.js → command-formatters-D0nZ3qtd.js} +18 -18
- package/dist/{command-handlers-DAHUSry9.js → command-handlers-DC86lgT4.js} +507 -101
- package/dist/command-rpc-xUIIonsO.js +90 -0
- package/dist/{compact-D_uvHurS.js → compact-COqgBRny.js} +234 -214
- package/dist/{session-binding-BXpo9ymA.js → config-CpNeo5AE.js} +284 -1163
- package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
- package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
- package/dist/doctor-contract-api.js +48 -50
- package/dist/{dynamic-tools-D2gYkSBO.js → dynamic-tools-fJZhl4CE.js} +3442 -1433
- package/dist/{effective-mcp-catalog-Bbd98Inw.js → effective-mcp-catalog-4YKn51aG.js} +20 -15
- package/dist/elicitation-input-DMkeki8d.js +71 -0
- package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
- package/dist/{attempt-notifications-AP-a-Q5k.js → event-projector-usage-CLwNEJqW.js} +113 -29
- package/dist/harness-DoKQcF8n.js +258 -0
- package/dist/harness.js +2 -160
- package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
- package/dist/index.js +730 -256
- package/dist/isolated-completion-DPMtlH9r.js +75 -0
- package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
- package/dist/managed-binary-By4FZC6i.js +212 -0
- package/dist/media-understanding-provider.js +5 -5
- package/dist/model-catalog-CmGoqVKB.js +48 -0
- package/dist/{models-BBMKU4jA.js → models-CZw1wClT.js} +12 -17
- package/dist/native-subagent-monitor-GGq3RnOo.js +3225 -0
- package/dist/node-exec-server.runtime-Bsu1LdFZ.js +192 -0
- package/dist/{plugin-app-cache-key-DztPafOA.js → plugin-app-cache-key-DMNQ8Zi8.js} +18 -6
- package/dist/plugin-approval-roundtrip-C75Yiiwc.js +95 -0
- package/dist/plugin-marketplace-discovery-CSWDkMrP.js +399 -0
- package/dist/{computer-use-CYEc8U3w.js → plugin-metadata-cache-BXH5NF-4.js} +109 -6
- package/dist/protocol-validators-VAVyEnDp.js +2399 -0
- package/dist/{rate-limits-CU-gVCCS.js → rate-limits-BI1dMHDG.js} +17 -35
- package/dist/{request-qKh331yu.js → request-DSK0W6YI.js} +3 -3
- package/dist/{run-attempt-CY9WlDLc.js → run-attempt-BV3HzuCf.js} +3416 -7194
- package/dist/{runtime-artifact-CmtG_t1L.js → runtime-artifact-BvyT1uyd.js} +11 -29
- package/dist/{sandbox-guard-NuhpXmPB.js → sandbox-guard-C1qEeZ5C.js} +29 -30
- package/dist/session-binding-BTrLf9Qm.js +874 -0
- package/dist/{session-catalog-DyOgR4WH.js → session-catalog-ezP_UcRM.js} +1584 -1289
- package/dist/session-catalog-home-id-BNwAJ9D7.js +18 -0
- package/dist/{session-cli-2PZaFLRh.js → session-cli-B1hKvfkI.js} +20 -7
- package/dist/session-retirement-CE4iMiLh.js +36 -0
- package/dist/{session-upstream-marker-B6U7tLw5.js → session-upstream-marker-D_2npHlA.js} +1 -1
- package/dist/{settled-turn-finalizer-CXY2Z9dT.js → settled-turn-finalizer-Dx1onIqg.js} +40 -28
- package/dist/{shared-client-DTbvH-XV.js → shared-client-Dw-rzii0.js} +1315 -469
- package/dist/{side-question-_ulBk1AL.js → side-question-DbXkJZzg.js} +140 -69
- package/dist/{thread-lifecycle-DF53ogiA.js → thread-lifecycle-DKdrnTMX.js} +927 -768
- package/dist/thread-ownership-i2NBwDUL.js +92 -0
- package/dist/thread-resume-CdJk2Ehf.js +30 -0
- package/dist/transcript-mirror-BU0_LKAL.js +588 -0
- package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DhoGy33Z.js} +13 -2
- package/dist/upstream-prompt-provenance-CFmsKwr9.js +39 -0
- package/dist/{upstream-session-fork-Dy4Xvuoj.js → upstream-session-fork-BDVJCLAD.js} +14 -8
- package/dist/{usage-CQ6GhD5-.js → usage-9dKJCgcy.js} +3 -3
- package/dist/{web-search-provider.runtime-CCFhg2z5.js → web-search-provider.runtime-DCdx4DGu.js} +8 -9
- package/openclaw.plugin.json +49 -4
- package/package.json +6 -5
- package/dist/app-server-policy-BSaO2JIT.js +0 -49
- package/dist/conversation-control-xsIeXbo4.js +0 -287
- package/dist/event-projector-usage-Xp4AlR2k.js +0 -86
- package/dist/notification-correlation-CU6_AnOb.js +0 -67
- package/dist/transcript-mirror-DzsdNCf5.js +0 -6924
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import { M as isCodexFastServiceTier } from "./config-CpNeo5AE.js";
|
|
2
|
+
import { a as getLeasedSharedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient } from "./shared-client-Dw-rzii0.js";
|
|
3
|
+
import { o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-BTrLf9Qm.js";
|
|
4
|
+
import { _ as resolveCodexAppServerRequestModelSelection, y as resolveCodexBindingModelProviderFallback } from "./thread-lifecycle-DKdrnTMX.js";
|
|
5
|
+
import { r as formatCodexDisplayText } from "./command-formatters-D0nZ3qtd.js";
|
|
6
|
+
import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-DAvZwp96.js";
|
|
7
|
+
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
8
|
+
import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
|
9
|
+
import { getSessionEntry, patchSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
10
|
+
import { ModelSelectionLockedError, applyModelOverrideWithAuthProfileCompatibility } from "openclaw/plugin-sdk/model-session-runtime";
|
|
11
|
+
//#region extensions/codex/src/command-authorization.ts
|
|
12
|
+
const CODEX_NATIVE_EXECUTION_AUTH_ERROR = "Only an owner or operator.admin can control Codex native execution.";
|
|
13
|
+
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
|
+
function hasCodexAdminScope(ctx) {
|
|
15
|
+
return ctx.gatewayClientScopes?.includes("operator.admin") === true;
|
|
16
|
+
}
|
|
17
|
+
function canMutateCodexHost(ctx) {
|
|
18
|
+
return ctx.senderIsOwner === true || hasCodexAdminScope(ctx);
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region extensions/codex/src/conversation-control.ts
|
|
22
|
+
const CODEX_CONVERSATION_CONTROL_STATE = Symbol.for("openclaw.codex.conversationControl");
|
|
23
|
+
function getActiveTurns() {
|
|
24
|
+
const globalState = globalThis;
|
|
25
|
+
globalState[CODEX_CONVERSATION_CONTROL_STATE] ??= /* @__PURE__ */ new Map();
|
|
26
|
+
return globalState[CODEX_CONVERSATION_CONTROL_STATE];
|
|
27
|
+
}
|
|
28
|
+
function trackCodexConversationActiveTurn(active) {
|
|
29
|
+
const activeTurns = getActiveTurns();
|
|
30
|
+
const key = bindingStoreKey(active.identity);
|
|
31
|
+
activeTurns.set(key, active);
|
|
32
|
+
return () => {
|
|
33
|
+
if (activeTurns.get(key)?.turnId === active.turnId) activeTurns.delete(key);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function readCodexConversationActiveTurn(identity) {
|
|
37
|
+
return getActiveTurns().get(bindingStoreKey(identity));
|
|
38
|
+
}
|
|
39
|
+
async function stopCodexConversationTurn(params) {
|
|
40
|
+
const active = readCodexConversationActiveTurn(params.identity);
|
|
41
|
+
if (!active) return {
|
|
42
|
+
stopped: false,
|
|
43
|
+
message: "No active Codex run to stop."
|
|
44
|
+
};
|
|
45
|
+
const lookup = buildBindingLookup(params);
|
|
46
|
+
const binding = await params.bindingStore.read(params.identity);
|
|
47
|
+
if (binding?.threadId !== active.threadId) return {
|
|
48
|
+
stopped: false,
|
|
49
|
+
message: "The active Codex run no longer matches this session binding."
|
|
50
|
+
};
|
|
51
|
+
const connection = resolveCodexBindingAppServerConnection({
|
|
52
|
+
binding,
|
|
53
|
+
authProfileId: binding?.authProfileId,
|
|
54
|
+
pluginConfig: params.pluginConfig
|
|
55
|
+
});
|
|
56
|
+
const runtime = connection.appServer;
|
|
57
|
+
const client = active.client ?? await getLeasedSharedCodexAppServerClient({
|
|
58
|
+
startOptions: runtime.start,
|
|
59
|
+
timeoutMs: runtime.requestTimeoutMs,
|
|
60
|
+
authProfileId: connection.clientAuthProfileId,
|
|
61
|
+
...lookup
|
|
62
|
+
});
|
|
63
|
+
try {
|
|
64
|
+
await client.request("turn/interrupt", {
|
|
65
|
+
threadId: active.threadId,
|
|
66
|
+
turnId: active.turnId
|
|
67
|
+
}, { timeoutMs: runtime.requestTimeoutMs });
|
|
68
|
+
} finally {
|
|
69
|
+
if (!active.client) releaseLeasedSharedCodexAppServerClient(client);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
stopped: true,
|
|
73
|
+
message: "Codex stop requested."
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function steerCodexConversationTurn(params) {
|
|
77
|
+
const active = readCodexConversationActiveTurn(params.identity);
|
|
78
|
+
const text = params.message.trim();
|
|
79
|
+
if (!text) return {
|
|
80
|
+
steered: false,
|
|
81
|
+
message: "Usage: /codex steer <message>"
|
|
82
|
+
};
|
|
83
|
+
if (!active) return {
|
|
84
|
+
steered: false,
|
|
85
|
+
message: "No active Codex run to steer."
|
|
86
|
+
};
|
|
87
|
+
const lookup = buildBindingLookup(params);
|
|
88
|
+
const binding = await params.bindingStore.read(params.identity);
|
|
89
|
+
if (binding?.threadId !== active.threadId) return {
|
|
90
|
+
steered: false,
|
|
91
|
+
message: "The active Codex run no longer matches this session binding."
|
|
92
|
+
};
|
|
93
|
+
const connection = resolveCodexBindingAppServerConnection({
|
|
94
|
+
binding,
|
|
95
|
+
authProfileId: binding?.authProfileId,
|
|
96
|
+
pluginConfig: params.pluginConfig
|
|
97
|
+
});
|
|
98
|
+
const runtime = connection.appServer;
|
|
99
|
+
const client = active.client ?? await getLeasedSharedCodexAppServerClient({
|
|
100
|
+
startOptions: runtime.start,
|
|
101
|
+
timeoutMs: runtime.requestTimeoutMs,
|
|
102
|
+
authProfileId: connection.clientAuthProfileId,
|
|
103
|
+
...lookup
|
|
104
|
+
});
|
|
105
|
+
try {
|
|
106
|
+
await client.request("turn/steer", {
|
|
107
|
+
threadId: active.threadId,
|
|
108
|
+
expectedTurnId: active.turnId,
|
|
109
|
+
input: [{
|
|
110
|
+
type: "text",
|
|
111
|
+
text,
|
|
112
|
+
text_elements: []
|
|
113
|
+
}]
|
|
114
|
+
}, { timeoutMs: runtime.requestTimeoutMs });
|
|
115
|
+
} finally {
|
|
116
|
+
if (!active.client) releaseLeasedSharedCodexAppServerClient(client);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
steered: true,
|
|
120
|
+
message: "Sent steer message to Codex."
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async function setCodexConversationModel(params) {
|
|
124
|
+
const model = params.model.trim();
|
|
125
|
+
if (!model) return "Usage: /codex model <model>";
|
|
126
|
+
const lookup = buildBindingLookup(params);
|
|
127
|
+
const binding = await requireThreadBinding(params.bindingStore, params.identity);
|
|
128
|
+
if (binding.connectionScope === "supervision") throw new ModelSelectionLockedError();
|
|
129
|
+
const modelSelection = resolveCodexAppServerRequestModelSelection({
|
|
130
|
+
model,
|
|
131
|
+
modelProvider: resolveConversationControlModelProvider({
|
|
132
|
+
authProfileId: binding.authProfileId,
|
|
133
|
+
bindingModel: binding.model,
|
|
134
|
+
bindingModelProvider: binding.modelProvider,
|
|
135
|
+
currentModel: model,
|
|
136
|
+
...lookup
|
|
137
|
+
}),
|
|
138
|
+
authProfileId: binding.authProfileId,
|
|
139
|
+
...lookup
|
|
140
|
+
});
|
|
141
|
+
const nextModelProvider = normalizeCodexAppServerBindingModelProvider({
|
|
142
|
+
authProfileId: binding.authProfileId,
|
|
143
|
+
modelProvider: modelSelection.modelProvider,
|
|
144
|
+
...lookup
|
|
145
|
+
});
|
|
146
|
+
const nextModel = modelSelection.model;
|
|
147
|
+
const modelChanged = nextModel !== binding.model || nextModelProvider !== binding.modelProvider;
|
|
148
|
+
const session = params.session ?? (params.identity.kind === "session" && params.identity.sessionKey ? {
|
|
149
|
+
agentId: params.identity.agentId,
|
|
150
|
+
sessionId: params.identity.sessionId,
|
|
151
|
+
sessionKey: params.identity.sessionKey
|
|
152
|
+
} : void 0);
|
|
153
|
+
if (session) {
|
|
154
|
+
if (!await patchSessionEntry({
|
|
155
|
+
agentId: session.agentId,
|
|
156
|
+
storePath: resolveStorePath(params.config?.session?.store, { agentId: session.agentId }),
|
|
157
|
+
sessionKey: session.sessionKey,
|
|
158
|
+
requireWriteSuccess: true,
|
|
159
|
+
replaceEntry: true,
|
|
160
|
+
update: (entry) => {
|
|
161
|
+
if (entry.sessionId !== session.sessionId) throw new Error("Codex session changed while applying the model selection.");
|
|
162
|
+
applyModelOverrideWithAuthProfileCompatibility({
|
|
163
|
+
cfg: params.config ?? {},
|
|
164
|
+
agentDir: params.agentDir ?? resolveAgentDir(params.config ?? {}, session.agentId),
|
|
165
|
+
entry,
|
|
166
|
+
currentProvider: binding.modelProvider ?? "openai",
|
|
167
|
+
selection: {
|
|
168
|
+
provider: nextModelProvider ?? "openai",
|
|
169
|
+
model: nextModel
|
|
170
|
+
},
|
|
171
|
+
markLiveSwitchPending: true
|
|
172
|
+
});
|
|
173
|
+
return entry;
|
|
174
|
+
}
|
|
175
|
+
})) throw new Error("Codex session changed while applying the model selection.");
|
|
176
|
+
if (params.identity.kind === "conversation") await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, {
|
|
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
|
+
} });
|
|
188
|
+
} else await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, {
|
|
189
|
+
model: nextModel,
|
|
190
|
+
modelProvider: nextModelProvider,
|
|
191
|
+
...modelChanged && binding.contextEngine?.projection ? { contextEngine: {
|
|
192
|
+
...binding.contextEngine,
|
|
193
|
+
projection: void 0
|
|
194
|
+
} } : {}
|
|
195
|
+
});
|
|
196
|
+
return `Codex model set to ${formatCodexDisplayText(nextModel)}.`;
|
|
197
|
+
}
|
|
198
|
+
async function setCodexConversationFastMode(params) {
|
|
199
|
+
const binding = await requireThreadBinding(params.bindingStore, params.identity);
|
|
200
|
+
if (params.enabled == null) return `Codex fast mode: ${isCodexFastServiceTier(binding.serviceTier) ? "on" : "off"}.`;
|
|
201
|
+
const serviceTier = params.enabled ? "priority" : "flex";
|
|
202
|
+
await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, { serviceTier });
|
|
203
|
+
return `Codex fast mode ${params.enabled ? "enabled" : "disabled"}.`;
|
|
204
|
+
}
|
|
205
|
+
async function setCodexConversationPermissions(params) {
|
|
206
|
+
const storePath = resolveStorePath(params.config?.session?.store, { agentId: params.session.agentId });
|
|
207
|
+
if (!params.mode) {
|
|
208
|
+
const entry = getSessionEntry({
|
|
209
|
+
agentId: params.session.agentId,
|
|
210
|
+
hydrateSkillPromptRefs: false,
|
|
211
|
+
readConsistency: "latest",
|
|
212
|
+
sessionKey: params.session.sessionKey,
|
|
213
|
+
storePath
|
|
214
|
+
});
|
|
215
|
+
if (entry?.sessionId !== params.session.sessionId) throw new Error("Codex session changed while reading the permission mode.");
|
|
216
|
+
return `Codex permissions: ${formatPermissionsMode(entry.permissionMode)}.`;
|
|
217
|
+
}
|
|
218
|
+
if (!await patchSessionEntry({
|
|
219
|
+
agentId: params.session.agentId,
|
|
220
|
+
storePath,
|
|
221
|
+
sessionKey: params.session.sessionKey,
|
|
222
|
+
requireWriteSuccess: true,
|
|
223
|
+
replaceEntry: true,
|
|
224
|
+
update: (entry) => {
|
|
225
|
+
if (entry.sessionId !== params.session.sessionId) throw new Error("Codex session changed while applying the permission mode.");
|
|
226
|
+
if (params.mode === "yolo") entry.permissionMode = "full";
|
|
227
|
+
else delete entry.permissionMode;
|
|
228
|
+
return entry;
|
|
229
|
+
}
|
|
230
|
+
})) throw new Error("Codex session changed while applying the permission mode.");
|
|
231
|
+
return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "default"}.`;
|
|
232
|
+
}
|
|
233
|
+
function parseCodexFastModeArg(arg) {
|
|
234
|
+
const normalized = arg?.trim().toLowerCase();
|
|
235
|
+
if (!normalized || normalized === "status") return;
|
|
236
|
+
if (normalized === "on" || normalized === "true" || normalized === "fast") return true;
|
|
237
|
+
if (normalized === "off" || normalized === "false" || normalized === "flex") return false;
|
|
238
|
+
}
|
|
239
|
+
function parseCodexPermissionsModeArg(arg) {
|
|
240
|
+
const normalized = arg?.trim().toLowerCase();
|
|
241
|
+
if (!normalized || normalized === "status") return;
|
|
242
|
+
if (normalized === "yolo" || normalized === "full" || normalized === "full-access") return "yolo";
|
|
243
|
+
if (normalized === "default" || normalized === "guardian") return "default";
|
|
244
|
+
}
|
|
245
|
+
function formatPermissionsMode(mode) {
|
|
246
|
+
return mode === "full" ? "full access" : "default";
|
|
247
|
+
}
|
|
248
|
+
async function requireThreadBinding(bindingStore, identity) {
|
|
249
|
+
const binding = await bindingStore.read(identity);
|
|
250
|
+
if (!binding?.threadId) throw new Error("No Codex thread is attached to this OpenClaw session yet.");
|
|
251
|
+
return binding;
|
|
252
|
+
}
|
|
253
|
+
async function patchThreadBinding(bindingStore, identity, threadId, patch) {
|
|
254
|
+
if (!await bindingStore.mutate(identity, {
|
|
255
|
+
kind: "patch",
|
|
256
|
+
threadId,
|
|
257
|
+
patch
|
|
258
|
+
})) throw new Error("Codex thread binding changed while applying the control update.");
|
|
259
|
+
}
|
|
260
|
+
function buildBindingLookup(params) {
|
|
261
|
+
const agentDir = params.agentDir?.trim();
|
|
262
|
+
return {
|
|
263
|
+
...agentDir ? { agentDir } : {},
|
|
264
|
+
...params.config ? { config: params.config } : {}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function resolveConversationControlModelProvider(params) {
|
|
268
|
+
const modelProvider = resolveCodexBindingModelProviderFallback({
|
|
269
|
+
currentModel: params.currentModel,
|
|
270
|
+
bindingModel: params.bindingModel,
|
|
271
|
+
bindingModelProvider: params.bindingModelProvider
|
|
272
|
+
})?.trim();
|
|
273
|
+
if (!modelProvider || modelProvider.toLowerCase() === "codex") return;
|
|
274
|
+
if (isCodexAppServerNativeAuthProfile(params) && modelProvider.toLowerCase() === "openai") return;
|
|
275
|
+
return modelProvider.toLowerCase() === "openai" ? "openai" : modelProvider;
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region extensions/codex/src/plugin-marketplace-discovery.ts
|
|
279
|
+
/** Read-only discovery of Codex-owned local, curated, and remote plugin marketplaces. */
|
|
280
|
+
const PLUGIN_SEGMENT_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
281
|
+
const MAX_PLUGIN_DESCRIPTION_LENGTH = 160;
|
|
282
|
+
const SUPPLEMENTAL_MARKETPLACE_KINDS = [
|
|
283
|
+
"workspace-directory",
|
|
284
|
+
"shared-with-me",
|
|
285
|
+
"created-by-me-remote",
|
|
286
|
+
"vertical"
|
|
287
|
+
];
|
|
288
|
+
/** Validates the same identifier segments required by Codex's stable PluginId parser. */
|
|
289
|
+
function parseCodexPluginMarketplaceId(value) {
|
|
290
|
+
const separator = value.lastIndexOf("@");
|
|
291
|
+
if (separator <= 0 || separator === value.length - 1) return;
|
|
292
|
+
const pluginName = value.slice(0, separator);
|
|
293
|
+
const marketplaceName = value.slice(separator + 1);
|
|
294
|
+
return PLUGIN_SEGMENT_PATTERN.test(pluginName) && PLUGIN_SEGMENT_PATTERN.test(marketplaceName) ? {
|
|
295
|
+
pluginName,
|
|
296
|
+
marketplaceName
|
|
297
|
+
} : void 0;
|
|
298
|
+
}
|
|
299
|
+
/** Lists local/global first and separately requests workspace, shared, and personal catalogs. */
|
|
300
|
+
async function discoverCodexMarketplacePlugins(params) {
|
|
301
|
+
const requestParams = { cwds: [params.workspaceDir] };
|
|
302
|
+
const primary = await params.request(requestParams);
|
|
303
|
+
const warnings = (primary.marketplaceLoadErrors ?? []).map((error) => boundedCatalogText(error.message));
|
|
304
|
+
const marketplaces = [...primary.marketplaces];
|
|
305
|
+
try {
|
|
306
|
+
const supplemental = await params.request({
|
|
307
|
+
...requestParams,
|
|
308
|
+
marketplaceKinds: [...SUPPLEMENTAL_MARKETPLACE_KINDS]
|
|
309
|
+
});
|
|
310
|
+
marketplaces.push(...supplemental.marketplaces);
|
|
311
|
+
warnings.push(...(supplemental.marketplaceLoadErrors ?? []).map((error) => boundedCatalogText(error.message)));
|
|
312
|
+
} catch (error) {
|
|
313
|
+
let recoveredSupplementalMarketplace = false;
|
|
314
|
+
for (const kind of SUPPLEMENTAL_MARKETPLACE_KINDS) try {
|
|
315
|
+
const supplemental = await params.request({
|
|
316
|
+
...requestParams,
|
|
317
|
+
marketplaceKinds: [kind]
|
|
318
|
+
});
|
|
319
|
+
marketplaces.push(...supplemental.marketplaces);
|
|
320
|
+
recoveredSupplementalMarketplace ||= supplemental.marketplaces.length > 0;
|
|
321
|
+
warnings.push(...(supplemental.marketplaceLoadErrors ?? []).map((loadError) => boundedCatalogText(loadError.message)));
|
|
322
|
+
} catch (kindError) {
|
|
323
|
+
warnings.push(boundedCatalogText(`${kind} marketplace unavailable: ${kindError instanceof Error ? kindError.message : String(kindError)}`));
|
|
324
|
+
}
|
|
325
|
+
if (!recoveredSupplementalMarketplace && warnings.length === 0) warnings.push(boundedCatalogText(`Additional marketplaces could not be listed: ${error instanceof Error ? error.message : String(error)}`));
|
|
326
|
+
}
|
|
327
|
+
const discovered = /* @__PURE__ */ new Map();
|
|
328
|
+
const ambiguous = /* @__PURE__ */ new Set();
|
|
329
|
+
for (const marketplace of marketplaces) {
|
|
330
|
+
if (!PLUGIN_SEGMENT_PATTERN.test(marketplace.name)) continue;
|
|
331
|
+
for (const summary of marketplace.plugins) {
|
|
332
|
+
const pluginName = pluginSlug(summary, marketplace.name);
|
|
333
|
+
if (!pluginName) continue;
|
|
334
|
+
const id = `${pluginName}@${marketplace.name}`;
|
|
335
|
+
if (ambiguous.has(id)) continue;
|
|
336
|
+
const previous = discovered.get(id);
|
|
337
|
+
const next = {
|
|
338
|
+
id,
|
|
339
|
+
pluginName,
|
|
340
|
+
marketplaceName: marketplace.name,
|
|
341
|
+
installed: summary.installed,
|
|
342
|
+
enabled: summary.enabled,
|
|
343
|
+
available: summary.availability !== "DISABLED_BY_ADMIN" && summary.installPolicy !== "NOT_AVAILABLE",
|
|
344
|
+
...summary.installPolicy ? { installPolicy: summary.installPolicy } : {},
|
|
345
|
+
...summary.authPolicy ? { authPolicy: summary.authPolicy } : {},
|
|
346
|
+
...marketplace.path ? { marketplacePath: marketplace.path } : {},
|
|
347
|
+
...summary.remotePluginId?.trim() ? {
|
|
348
|
+
remotePluginId: summary.remotePluginId.trim(),
|
|
349
|
+
mustShowInstallationInterstitial: summary.mustShowInstallationInterstitial ?? null
|
|
350
|
+
} : {},
|
|
351
|
+
summaryId: summary.id
|
|
352
|
+
};
|
|
353
|
+
const description = pluginDescription(summary);
|
|
354
|
+
if (description) next.description = description;
|
|
355
|
+
if (previous && (previous.marketplacePath !== next.marketplacePath || previous.remotePluginId !== next.remotePluginId)) {
|
|
356
|
+
discovered.delete(id);
|
|
357
|
+
ambiguous.add(id);
|
|
358
|
+
warnings.push(`Multiple discovered plugins share ${id}; installation requires a unique identity.`);
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (!previous) discovered.set(id, next);
|
|
362
|
+
else {
|
|
363
|
+
const preferred = !previous.installed && next.installed || !previous.enabled && next.installed && next.enabled ? next : previous;
|
|
364
|
+
discovered.set(id, {
|
|
365
|
+
...preferred,
|
|
366
|
+
available: previous.available && next.available,
|
|
367
|
+
...preferred.remotePluginId ? { mustShowInstallationInterstitial: previous.mustShowInstallationInterstitial === true || next.mustShowInstallationInterstitial === true ? true : previous.mustShowInstallationInterstitial === false && next.mustShowInstallationInterstitial === false ? false : null } : {},
|
|
368
|
+
...previous.installPolicy === "NOT_AVAILABLE" || next.installPolicy === "NOT_AVAILABLE" ? { installPolicy: "NOT_AVAILABLE" } : {}
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
plugins: [...discovered.values()].toSorted((left, right) => left.id.localeCompare(right.id)),
|
|
375
|
+
warnings
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function pluginSlug(summary, marketplaceName) {
|
|
379
|
+
const qualified = parseCodexPluginMarketplaceId(summary.id);
|
|
380
|
+
if (qualified?.marketplaceName === marketplaceName) return qualified.pluginName;
|
|
381
|
+
const identitySegment = summary.id.split("/").at(-1);
|
|
382
|
+
if (identitySegment && PLUGIN_SEGMENT_PATTERN.test(identitySegment)) return identitySegment;
|
|
383
|
+
return PLUGIN_SEGMENT_PATTERN.test(summary.name) ? summary.name : void 0;
|
|
384
|
+
}
|
|
385
|
+
function pluginDescription(summary) {
|
|
386
|
+
const description = asOptionalRecord(summary.interface)?.shortDescription;
|
|
387
|
+
if (typeof description !== "string") return;
|
|
388
|
+
return boundedCatalogText(description) || void 0;
|
|
389
|
+
}
|
|
390
|
+
function boundedCatalogText(value) {
|
|
391
|
+
let sanitized = "";
|
|
392
|
+
for (const character of value) {
|
|
393
|
+
const codePoint = character.codePointAt(0);
|
|
394
|
+
sanitized += codePoint !== void 0 && (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) ? " " : character;
|
|
395
|
+
}
|
|
396
|
+
return sanitized.replace(/\s+/g, " ").trim().slice(0, MAX_PLUGIN_DESCRIPTION_LENGTH);
|
|
397
|
+
}
|
|
398
|
+
//#endregion
|
|
399
|
+
export { parseCodexPermissionsModeArg as a, setCodexConversationModel as c, stopCodexConversationTurn as d, trackCodexConversationActiveTurn as f, hasCodexAdminScope as g, canMutateCodexHost as h, parseCodexFastModeArg as i, setCodexConversationPermissions as l, CODEX_NATIVE_EXECUTION_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,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as describeControlFailure } from "./capabilities-
|
|
4
|
-
import { r as requestCodexAppServerJson } from "./request-
|
|
1
|
+
import { i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig } from "./config-CpNeo5AE.js";
|
|
2
|
+
import { M as isCodexAppServerConnectionClosedError, N as isCodexAppServerIndeterminateRequestCancellationError, P as isCodexAppServerIndeterminateTransportError, a as getLeasedSharedCodexAppServerClient, dt as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, l as releaseLeasedSharedCodexAppServerClient, u as resolveCodexNativeConfigFenceKey, v as acquireCodexNativeConfigFence } from "./shared-client-Dw-rzii0.js";
|
|
3
|
+
import { n as describeControlFailure } from "./capabilities-CH3K57v4.js";
|
|
4
|
+
import { r as requestCodexAppServerJson } from "./request-DSK0W6YI.js";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { runExec } from "openclaw/plugin-sdk/process-runtime";
|
|
7
7
|
//#region extensions/codex/src/app-server/computer-use-process-repair.ts
|
|
@@ -208,6 +208,7 @@ async function inspectCodexComputerUse(params) {
|
|
|
208
208
|
try {
|
|
209
209
|
return await inspectCodexComputerUseWithoutFence({
|
|
210
210
|
...params,
|
|
211
|
+
releaseNativeConfigFence: release,
|
|
211
212
|
...client ? {
|
|
212
213
|
client,
|
|
213
214
|
timeoutMs: params.timeoutMs ?? runtime?.requestTimeoutMs
|
|
@@ -251,7 +252,8 @@ async function inspectCodexComputerUseWithoutFence(params) {
|
|
|
251
252
|
config: params.computerUseConfig,
|
|
252
253
|
plugin: pluginInspection.plugin,
|
|
253
254
|
installPlugin: params.installPlugin,
|
|
254
|
-
repairComputerUseMcpChildren
|
|
255
|
+
repairComputerUseMcpChildren,
|
|
256
|
+
releaseNativeConfigFence: params.releaseNativeConfigFence
|
|
255
257
|
});
|
|
256
258
|
}
|
|
257
259
|
async function ensureComputerUsePlugin(params) {
|
|
@@ -315,6 +317,7 @@ async function readComputerUseTools(params) {
|
|
|
315
317
|
reason: "ready",
|
|
316
318
|
message: "Computer Use is ready."
|
|
317
319
|
});
|
|
320
|
+
params.releaseNativeConfigFence?.();
|
|
318
321
|
const { liveTest, repair } = await runCodexComputerUseLiveTest({
|
|
319
322
|
request: params.request,
|
|
320
323
|
config: params.config,
|
|
@@ -690,4 +693,104 @@ function resolveComputerUseConfig(params) {
|
|
|
690
693
|
});
|
|
691
694
|
}
|
|
692
695
|
//#endregion
|
|
693
|
-
|
|
696
|
+
//#region extensions/codex/src/app-server/plugin-metadata-cache.ts
|
|
697
|
+
const CODEX_PLUGIN_METADATA_CACHE_TTL_MS = 3600 * 1e3;
|
|
698
|
+
/** Process-local plugin metadata cache with coalesced loads per query. */
|
|
699
|
+
var CodexPluginMetadataCache = class {
|
|
700
|
+
constructor(nowMs = Date.now) {
|
|
701
|
+
this.nowMs = nowMs;
|
|
702
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
703
|
+
this.inFlight = /* @__PURE__ */ new Map();
|
|
704
|
+
this.generations = /* @__PURE__ */ new Map();
|
|
705
|
+
this.clearGeneration = 0;
|
|
706
|
+
}
|
|
707
|
+
/** Returns a fresh cached snapshot without issuing a request. */
|
|
708
|
+
read(appCacheKey, queryKind, requestParams, catalogScope) {
|
|
709
|
+
const entryKey = buildMetadataCacheEntryKey(appCacheKey, queryKind, requestParams, catalogScope);
|
|
710
|
+
const entry = this.entries.get(entryKey);
|
|
711
|
+
if (!entry) return;
|
|
712
|
+
if (entry.expiresAtMs <= this.nowMs()) {
|
|
713
|
+
this.entries.delete(entryKey);
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
return entry.snapshot;
|
|
717
|
+
}
|
|
718
|
+
/** Returns a fresh snapshot or coalesces one catalog or installed-plugin request. */
|
|
719
|
+
async load(params) {
|
|
720
|
+
const entryKey = buildMetadataCacheEntryKey(params.appCacheKey, params.queryKind, params.requestParams, params.catalogScope);
|
|
721
|
+
const cached = this.read(params.appCacheKey, params.queryKind, params.requestParams, params.catalogScope);
|
|
722
|
+
if (cached) return cached;
|
|
723
|
+
const pending = this.inFlight.get(entryKey);
|
|
724
|
+
if (pending) try {
|
|
725
|
+
return await pending.promise;
|
|
726
|
+
} catch {
|
|
727
|
+
if (this.inFlight.get(entryKey) === pending) this.inFlight.delete(entryKey);
|
|
728
|
+
return await this.load(params);
|
|
729
|
+
}
|
|
730
|
+
const generation = this.generations.get(params.appCacheKey) ?? 0;
|
|
731
|
+
const clearGeneration = this.clearGeneration;
|
|
732
|
+
const promise = (async () => {
|
|
733
|
+
const method = params.queryKind === "installed" ? "plugin/installed" : "plugin/list";
|
|
734
|
+
const response = await params.request(method, params.requestParams);
|
|
735
|
+
const snapshot = {
|
|
736
|
+
appCacheKey: params.appCacheKey,
|
|
737
|
+
queryKind: params.queryKind,
|
|
738
|
+
response
|
|
739
|
+
};
|
|
740
|
+
if (generation === (this.generations.get(params.appCacheKey) ?? 0) && clearGeneration === this.clearGeneration && !hasMarketplaceLoadErrors(response) && (params.cacheable?.(response) ?? true)) this.entries.set(entryKey, {
|
|
741
|
+
snapshot,
|
|
742
|
+
expiresAtMs: this.nowMs() + CODEX_PLUGIN_METADATA_CACHE_TTL_MS
|
|
743
|
+
});
|
|
744
|
+
return snapshot;
|
|
745
|
+
})();
|
|
746
|
+
this.inFlight.set(entryKey, {
|
|
747
|
+
appCacheKey: params.appCacheKey,
|
|
748
|
+
promise
|
|
749
|
+
});
|
|
750
|
+
try {
|
|
751
|
+
return await promise;
|
|
752
|
+
} finally {
|
|
753
|
+
if (this.inFlight.get(entryKey)?.promise === promise) this.inFlight.delete(entryKey);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
/** Invalidates all plugin metadata queries for one app-server runtime. */
|
|
757
|
+
invalidate(appCacheKey) {
|
|
758
|
+
this.generations.set(appCacheKey, (this.generations.get(appCacheKey) ?? 0) + 1);
|
|
759
|
+
for (const [entryKey, entry] of this.entries) if (entry.snapshot.appCacheKey === appCacheKey) this.entries.delete(entryKey);
|
|
760
|
+
for (const [entryKey, pending] of this.inFlight) if (pending.appCacheKey === appCacheKey) this.inFlight.delete(entryKey);
|
|
761
|
+
}
|
|
762
|
+
/** Clears snapshots and prevents late in-flight loads from repopulating them. */
|
|
763
|
+
clear() {
|
|
764
|
+
this.clearGeneration += 1;
|
|
765
|
+
this.generations.clear();
|
|
766
|
+
this.entries.clear();
|
|
767
|
+
this.inFlight.clear();
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
/** Shared plugin metadata cache used by Codex app-server runtime paths. */
|
|
771
|
+
const defaultCodexPluginMetadataCache = new CodexPluginMetadataCache();
|
|
772
|
+
function hasMarketplaceLoadErrors(response) {
|
|
773
|
+
return response.marketplaceLoadErrors.length > 0;
|
|
774
|
+
}
|
|
775
|
+
function buildMetadataCacheEntryKey(appCacheKey, queryKind, requestParams, catalogScope) {
|
|
776
|
+
if (queryKind !== "installed") {
|
|
777
|
+
const listParams = requestParams;
|
|
778
|
+
const entry = [
|
|
779
|
+
appCacheKey,
|
|
780
|
+
queryKind,
|
|
781
|
+
listParams?.cwds ?? [],
|
|
782
|
+
Array.from(new Set(listParams?.marketplaceKinds ?? [])).toSorted(),
|
|
783
|
+
...catalogScope ? [catalogScope] : []
|
|
784
|
+
];
|
|
785
|
+
return JSON.stringify(entry);
|
|
786
|
+
}
|
|
787
|
+
const installedParams = requestParams;
|
|
788
|
+
return JSON.stringify([
|
|
789
|
+
appCacheKey,
|
|
790
|
+
queryKind,
|
|
791
|
+
installedParams?.cwds ?? [],
|
|
792
|
+
Array.from(new Set(installedParams?.installSuggestionPluginNames ?? [])).toSorted()
|
|
793
|
+
]);
|
|
794
|
+
}
|
|
795
|
+
//#endregion
|
|
796
|
+
export { runCodexComputerUseLiveTest as a, readCodexComputerUseStatus as i, ensureCodexComputerUse as n, killStaleComputerUseMcpChildren as o, installCodexComputerUse as r, defaultCodexPluginMetadataCache as t };
|