@openclaw/codex 2026.8.1-beta.2 → 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.
Files changed (59) hide show
  1. package/dist/api.js +147 -0
  2. package/dist/app-server-policy-bg5QPSVP.js +25 -0
  3. package/dist/{attempt-client-cleanup-DMLXUfa8.js → attempt-client-cleanup-URjUlCHg.js} +1 -1
  4. package/dist/{binding-connection-I5Bo-AsX.js → binding-connection-DAvZwp96.js} +15 -3
  5. package/dist/{bounded-turn-qgZmzy_4.js → bounded-turn-4BjrZEwW.js} +22 -16
  6. package/dist/{capabilities-CybGI1oz.js → capabilities-CH3K57v4.js} +1 -1
  7. package/dist/cli-metadata.js +1 -1
  8. package/dist/{command-formatters-B1AEz8ZA.js → command-formatters-D0nZ3qtd.js} +2 -2
  9. package/dist/{command-handlers-Db8pu_ds.js → command-handlers-DC86lgT4.js} +39 -22
  10. package/dist/command-rpc-xUIIonsO.js +90 -0
  11. package/dist/{compact-LspQaGfl.js → compact-COqgBRny.js} +35 -29
  12. package/dist/{session-binding-DPxIvMgE.js → config-CpNeo5AE.js} +28 -888
  13. package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
  14. package/dist/doctor-contract-api.js +15 -14
  15. package/dist/{dynamic-tools-BVdyWkUD.js → dynamic-tools-fJZhl4CE.js} +1284 -651
  16. package/dist/{effective-mcp-catalog-DIIhAtOZ.js → effective-mcp-catalog-4YKn51aG.js} +2 -2
  17. package/dist/elicitation-input-DMkeki8d.js +71 -0
  18. package/dist/{event-projector-usage-e5huIQWu.js → event-projector-usage-CLwNEJqW.js} +16 -16
  19. package/dist/harness-DoKQcF8n.js +258 -0
  20. package/dist/harness.js +2 -226
  21. package/dist/index.js +171 -48
  22. package/dist/{isolated-completion-C58NbL40.js → isolated-completion-DPMtlH9r.js} +3 -3
  23. package/dist/managed-binary-By4FZC6i.js +212 -0
  24. package/dist/media-understanding-provider.js +2 -2
  25. package/dist/model-catalog-CmGoqVKB.js +48 -0
  26. package/dist/{models-BFlpn1Ex.js → models-CZw1wClT.js} +2 -2
  27. package/dist/{native-subagent-monitor-DyTGmTUx.js → native-subagent-monitor-GGq3RnOo.js} +185 -71
  28. package/dist/node-exec-server.runtime-Bsu1LdFZ.js +192 -0
  29. package/dist/{plugin-app-cache-key-C3H2CVp6.js → plugin-app-cache-key-DMNQ8Zi8.js} +15 -3
  30. package/dist/plugin-approval-roundtrip-C75Yiiwc.js +95 -0
  31. package/dist/{plugin-marketplace-discovery-CzrGJdCR.js → plugin-marketplace-discovery-CSWDkMrP.js} +40 -26
  32. package/dist/{plugin-metadata-cache-CNJPj4_b.js → plugin-metadata-cache-BXH5NF-4.js} +8 -5
  33. package/dist/{protocol-validators-B4F7L8Rf.js → protocol-validators-VAVyEnDp.js} +55 -2
  34. package/dist/{rate-limits-DZXmOL8-.js → rate-limits-BI1dMHDG.js} +1 -1
  35. package/dist/{request-BRl5_UfX.js → request-DSK0W6YI.js} +2 -2
  36. package/dist/{run-attempt-P8BdxC1I.js → run-attempt-BV3HzuCf.js} +1098 -666
  37. package/dist/{runtime-artifact-BVSPdd6g.js → runtime-artifact-BvyT1uyd.js} +4 -7
  38. package/dist/{sandbox-guard-Cmwc9eIk.js → sandbox-guard-C1qEeZ5C.js} +25 -19
  39. package/dist/session-binding-BTrLf9Qm.js +874 -0
  40. package/dist/{session-catalog-xwNi_SDM.js → session-catalog-ezP_UcRM.js} +1541 -1296
  41. package/dist/session-catalog-home-id-BNwAJ9D7.js +18 -0
  42. package/dist/{session-cli-7hgXZDV7.js → session-cli-B1hKvfkI.js} +20 -7
  43. package/dist/{session-retirement-DoMMJFKm.js → session-retirement-CE4iMiLh.js} +3 -3
  44. package/dist/{session-upstream-marker-CrIFX06J.js → session-upstream-marker-D_2npHlA.js} +1 -1
  45. package/dist/{settled-turn-finalizer-BRWBO4MO.js → settled-turn-finalizer-Dx1onIqg.js} +23 -19
  46. package/dist/{shared-client-kIBbGjk4.js → shared-client-Dw-rzii0.js} +755 -273
  47. package/dist/{side-question-9HAL26l9.js → side-question-DbXkJZzg.js} +52 -30
  48. package/dist/{thread-lifecycle-Bu1BTDXr.js → thread-lifecycle-DKdrnTMX.js} +310 -92
  49. package/dist/{thread-ownership-6kOQHlyC.js → thread-ownership-i2NBwDUL.js} +2 -2
  50. package/dist/{thread-resume-CPrJNQVM.js → thread-resume-CdJk2Ehf.js} +3 -3
  51. package/dist/{transcript-mirror-B9gGgnJS.js → transcript-mirror-BU0_LKAL.js} +46 -28
  52. package/dist/{transport-stdio-DIImwDVS.js → transport-stdio-DhoGy33Z.js} +2 -2
  53. package/dist/{upstream-prompt-provenance-ClRBije0.js → upstream-prompt-provenance-CFmsKwr9.js} +12 -14
  54. package/dist/{upstream-session-fork-CE-_LdnP.js → upstream-session-fork-BDVJCLAD.js} +12 -6
  55. package/dist/{usage-CHlV0e-o.js → usage-9dKJCgcy.js} +3 -3
  56. package/dist/{web-search-provider.runtime-DRw2Vl42.js → web-search-provider.runtime-DCdx4DGu.js} +3 -3
  57. package/openclaw.plugin.json +31 -1
  58. package/package.json +6 -5
  59. package/dist/app-server-policy-zcBDc1JU.js +0 -49
@@ -0,0 +1,192 @@
1
+ import { z as closeCodexAppServerTransportAndWait } from "./shared-client-Dw-rzii0.js";
2
+ import { t as createStdioTransport } from "./transport-stdio-DhoGy33Z.js";
3
+ import { n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-By4FZC6i.js";
4
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
+ import { mkdir } from "node:fs/promises";
6
+ import path from "node:path";
7
+ import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
8
+ import { killProcessTree } from "openclaw/plugin-sdk/process-runtime";
9
+ import { once } from "node:events";
10
+ import { sanitizeEnvVars } from "openclaw/plugin-sdk/sandbox";
11
+ //#region extensions/codex/src/node-exec-server.runtime.ts
12
+ const MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES = 64 * 1024 * 1024;
13
+ const CODEX_EXEC_SERVER_TERMINATION_GRACE_MS = 1e3;
14
+ const CODEX_EXEC_SERVER_REAP_TIMEOUT_MS = 5e3;
15
+ const NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT = /^(?:SYSTEMROOT|WINDIR|COMSPEC|PATHEXT|TEMP|TMP|TMPDIR)$/iu;
16
+ function validateNodeExecServerMessage(message) {
17
+ if (message.byteLength === 0 || message.byteLength > MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES) throw new Error("Codex exec-server JSON-RPC message exceeds its 64 MiB limit.");
18
+ const encoded = Buffer.from(message.buffer, message.byteOffset, message.byteLength);
19
+ if (encoded.includes(10) || encoded.includes(13)) throw new Error("Codex exec-server JSON-RPC frames must contain exactly one message.");
20
+ let decoded;
21
+ try {
22
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(encoded);
23
+ decoded = JSON.parse(text);
24
+ } catch {
25
+ throw new Error("Codex exec-server received malformed UTF-8 or JSON-RPC.");
26
+ }
27
+ if (!isRecord(decoded) || decoded.jsonrpc !== void 0 && decoded.jsonrpc !== "2.0" || typeof decoded.method !== "string" && !("id" in decoded && ("result" in decoded || "error" in decoded))) throw new Error("Codex exec-server received an invalid JSON-RPC message.");
28
+ return encoded;
29
+ }
30
+ function nodeExecServerAbortError(signal) {
31
+ return signal.reason instanceof Error ? signal.reason : /* @__PURE__ */ new Error("Codex node exec-server connection closed.");
32
+ }
33
+ function writeNodeExecServerMessage(child, message, signal) {
34
+ if (signal.aborted) throw nodeExecServerAbortError(signal);
35
+ const payload = Buffer.concat([message, Buffer.from("\n")]);
36
+ if (!child.stdin.write(payload)) return once(child.stdin, "drain", { signal }).then(() => void 0);
37
+ }
38
+ async function relayNodeExecServerOutput(child, send) {
39
+ let fragments = [];
40
+ let pendingBytes = 0;
41
+ for await (const rawChunk of child.stdout) {
42
+ const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);
43
+ let offset = 0;
44
+ while (offset < chunk.byteLength) {
45
+ const newline = chunk.indexOf(10, offset);
46
+ const fragment = chunk.subarray(offset, newline === -1 ? chunk.byteLength : newline);
47
+ const nextLength = pendingBytes + fragment.byteLength;
48
+ if (nextLength > 67108865) throw new Error("Codex exec-server stdout message exceeds its 64 MiB limit.");
49
+ if (fragment.byteLength > 0) fragments.push(fragment);
50
+ pendingBytes = nextLength;
51
+ if (newline === -1) {
52
+ if (pendingBytes > MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES && fragment[fragment.byteLength - 1] !== 13) throw new Error("Codex exec-server stdout message exceeds its 64 MiB limit.");
53
+ break;
54
+ }
55
+ const trailing = fragments.at(-1);
56
+ if (trailing?.[trailing.byteLength - 1] === 13) {
57
+ pendingBytes -= 1;
58
+ if (trailing.byteLength === 1) fragments.pop();
59
+ else fragments[fragments.length - 1] = trailing.subarray(0, trailing.byteLength - 1);
60
+ }
61
+ const message = validateNodeExecServerMessage(fragments.length === 1 ? fragments[0] : Buffer.concat(fragments, pendingBytes));
62
+ fragments = [];
63
+ pendingBytes = 0;
64
+ await send(message);
65
+ offset = newline + 1;
66
+ }
67
+ }
68
+ if (pendingBytes > 0) throw new Error("Codex exec-server stdout ended with an unterminated JSON-RPC message.");
69
+ }
70
+ function createNodeExecServerProcessOwner(child, closed) {
71
+ let termination;
72
+ return { terminate: () => termination ??= (async () => {
73
+ if (process.platform === "win32" && child.pid) killProcessTree(child.pid, { graceMs: CODEX_EXEC_SERVER_TERMINATION_GRACE_MS });
74
+ if (!await closeCodexAppServerTransportAndWait(child, {
75
+ forceKillDelayMs: CODEX_EXEC_SERVER_TERMINATION_GRACE_MS,
76
+ exitTimeoutMs: CODEX_EXEC_SERVER_REAP_TIMEOUT_MS
77
+ })) throw new Error("Codex node exec-server process tree did not terminate.");
78
+ await closed;
79
+ })() };
80
+ }
81
+ /** Runs the one-connection paired-node exec-server after lightweight command admission. */
82
+ async function runCodexNodeExecServer(params) {
83
+ const { io } = params;
84
+ const frames = io.frames;
85
+ if (!frames) throw new Error("Codex node exec-server requires duplex frames.");
86
+ const cwd = params.workspaceDir;
87
+ let writes;
88
+ let rejectDisconnected;
89
+ const disconnected = new Promise((_resolve, reject) => {
90
+ rejectDisconnected = reject;
91
+ });
92
+ disconnected.catch(() => {});
93
+ const onAbort = () => {
94
+ const error = nodeExecServerAbortError(io.signal);
95
+ rejectDisconnected(error);
96
+ };
97
+ io.signal.addEventListener("abort", onAbort, { once: true });
98
+ try {
99
+ if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
100
+ return await withTempWorkspace({
101
+ rootDir: resolvePreferredOpenClawTmpDir(),
102
+ prefix: "codex-node-exec-server-"
103
+ }, async ({ dir }) => {
104
+ const codexHome = path.join(dir, ".codex");
105
+ await mkdir(codexHome, {
106
+ recursive: true,
107
+ mode: 448
108
+ });
109
+ const resolved = await resolveManagedCodexAppServerStartOptions({
110
+ transport: "stdio",
111
+ command: "codex",
112
+ commandSource: "managed",
113
+ managedCommandOrder: "package-first",
114
+ args: [
115
+ "exec-server",
116
+ "--listen",
117
+ "stdio"
118
+ ],
119
+ headers: {}
120
+ });
121
+ const native = resolveManagedCodexNativeCommand(resolved.command);
122
+ if (!native || isManagedCodexDesktopCommand(resolved.command)) throw new Error("Codex node exec-server requires the pinned managed package binary.");
123
+ const baseEnv = sanitizeEnvVars(process.env, {
124
+ strictMode: true,
125
+ customAllowedPatterns: [NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT]
126
+ }).allowed;
127
+ if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
128
+ const child = createStdioTransport({
129
+ transport: "stdio",
130
+ command: native,
131
+ commandSource: "resolved-managed",
132
+ args: resolved.args,
133
+ headers: {},
134
+ cwd,
135
+ env: {
136
+ HOME: dir,
137
+ CODEX_HOME: codexHome,
138
+ ...process.platform === "win32" ? { USERPROFILE: dir } : {}
139
+ },
140
+ clearEnv: ["NODE_OPTIONS"]
141
+ }, baseEnv);
142
+ child.stdin.on("error", (error) => {
143
+ rejectDisconnected(error);
144
+ });
145
+ let stderr = Buffer.alloc(0);
146
+ child.stderr.on("data", (chunk) => {
147
+ const bounded = (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)).subarray(-4096);
148
+ stderr = Buffer.concat([stderr, bounded]).subarray(-4096);
149
+ });
150
+ const closed = new Promise((resolve) => {
151
+ child.once("close", (code, signal) => resolve({
152
+ code,
153
+ signal
154
+ }));
155
+ });
156
+ child.once("error", (error) => {
157
+ rejectDisconnected(error);
158
+ });
159
+ const owner = createNodeExecServerProcessOwner(child, closed);
160
+ params.activeProcesses.add(owner.terminate);
161
+ const output = relayNodeExecServerOutput(child, frames.send.bind(frames));
162
+ output.catch((error) => {
163
+ rejectDisconnected(error instanceof Error ? error : new Error(String(error)));
164
+ });
165
+ try {
166
+ if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
167
+ params.onFrameReceiver((message) => {
168
+ const encoded = validateNodeExecServerMessage(message);
169
+ const operation = writes ? writes.then(() => writeNodeExecServerMessage(child, encoded, io.signal)) : writeNodeExecServerMessage(child, encoded, io.signal);
170
+ if (!operation) return;
171
+ const observed = operation.catch(() => {});
172
+ writes = observed;
173
+ observed.then(() => {
174
+ if (writes === observed) writes = void 0;
175
+ });
176
+ return operation;
177
+ });
178
+ const outcome = await Promise.race([closed, disconnected]);
179
+ const diagnostic = stderr.toString("utf8").trim();
180
+ throw new Error(`Codex node exec-server exited (code ${outcome.code ?? "none"}, signal ${outcome.signal ?? "none"})${diagnostic ? `: ${diagnostic}` : "."}`);
181
+ } finally {
182
+ await owner.terminate();
183
+ params.activeProcesses.delete(owner.terminate);
184
+ await Promise.allSettled([output, ...writes ? [writes] : []]);
185
+ }
186
+ });
187
+ } finally {
188
+ io.signal.removeEventListener("abort", onAbort);
189
+ }
190
+ }
191
+ //#endregion
192
+ export { runCodexNodeExecServer };
@@ -1,5 +1,5 @@
1
- import { A as resolveCodexAppServerUserHomeDir } from "./session-binding-DPxIvMgE.js";
2
- import { dt as resolveCodexAppServerLocalHomeDir, ut as resolveCodexAppServerHomeDir } from "./shared-client-kIBbGjk4.js";
1
+ import { x as resolveCodexAppServerUserHomeDir } from "./config-CpNeo5AE.js";
2
+ import { ft as resolveCodexAppServerHomeDir, pt as resolveCodexAppServerLocalHomeDir } from "./shared-client-Dw-rzii0.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { readPluginPackageVersion } from "openclaw/plugin-sdk/extension-shared";
@@ -331,6 +331,14 @@ function isSensitiveErrorDataKey(key) {
331
331
  * auth, account, and version inputs without storing secret material.
332
332
  */
333
333
  const CODEX_PLUGIN_VERSION = readPluginPackageVersion({ require: createRequire(import.meta.url) });
334
+ let catalogConnectionHomes = /* @__PURE__ */ new Map();
335
+ function catalogConnectionHomeKey(fingerprint, agentDir) {
336
+ return `${agentDir ?? ""}\0${fingerprint}`;
337
+ }
338
+ /** Replaces the lifecycle-owned catalog connection snapshot used by supervised bindings. */
339
+ function replaceCodexCatalogConnectionHomes(homes) {
340
+ catalogConnectionHomes = new Map(homes.map((home) => [catalogConnectionHomeKey(home.fingerprint, home.agentDir), home.codexHome]));
341
+ }
334
342
  /** Builds the full app inventory cache key for Codex plugin/app discovery. */
335
343
  function buildCodexPluginAppCacheKey(params) {
336
344
  return buildCodexAppInventoryCacheKey({
@@ -364,6 +372,10 @@ function buildCodexAppServerConnectionFingerprint(appServer, agentDir) {
364
372
  cwd: appServer.start.cwd ?? null
365
373
  });
366
374
  }
375
+ /** Looks up a snapshotted catalog store without repeating filesystem discovery on a run. */
376
+ function resolveCodexCatalogConnectionHome(fingerprint, agentDir) {
377
+ return catalogConnectionHomes.get(catalogConnectionHomeKey(fingerprint, agentDir));
378
+ }
367
379
  function resolveCodexAppServerConnectionHome(start, agentDir) {
368
380
  const configured = start.env?.CODEX_HOME?.trim();
369
381
  if (configured) return configured;
@@ -405,4 +417,4 @@ function fingerprintCodexPluginAppCacheCredentials(startOptions) {
405
417
  return `sha256:${hash.digest("hex")}`;
406
418
  }
407
419
  //#endregion
408
- export { serializeCodexAppInventoryError as a, defaultCodexAppInventoryCache as i, buildCodexAppServerRuntimeFingerprint as n, buildCodexPluginAppCacheKey as r, buildCodexAppServerConnectionFingerprint as t };
420
+ export { resolveCodexCatalogConnectionHome as a, replaceCodexCatalogConnectionHomes as i, buildCodexAppServerRuntimeFingerprint as n, defaultCodexAppInventoryCache as o, buildCodexPluginAppCacheKey as r, serializeCodexAppInventoryError as s, buildCodexAppServerConnectionFingerprint as t };
@@ -0,0 +1,95 @@
1
+ import { S as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-Dw-rzii0.js";
2
+ import { isApprovalNotFoundError, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
3
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
4
+ //#region extensions/codex/src/app-server/plugin-approval-roundtrip.ts
5
+ const DEFAULT_CODEX_APPROVAL_TIMEOUT_MS = 12e4;
6
+ const MAX_PLUGIN_APPROVAL_TITLE_LENGTH = 80;
7
+ const MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH = 256;
8
+ const ANSI_OSC_SEQUENCE_RE = new RegExp(String.raw`(?:\u001b]|\u009d)[^\u001b\u009c\u0007]*(?:\u0007|\u001b\\|\u009c)`, "g");
9
+ const ANSI_CONTROL_SEQUENCE_RE = new RegExp(String.raw`(?:\u001b\[[0-?]*[ -/]*[@-~]|\u009b[0-?]*[ -/]*[@-~]|\u001b[@-Z\\-_])`, "g");
10
+ const CONTROL_CHARACTER_RE = new RegExp(String.raw`[\u0000-\u001f\u007f-\u009f]+`, "g");
11
+ const INVISIBLE_FORMATTING_CONTROL_RE = new RegExp(String.raw`[\u00ad\u034f\u061c\u200b-\u200f\u202a-\u202e\u2060-\u206f\ufeff\ufe00-\ufe0f\u{e0100}-\u{e01ef}]`, "gu");
12
+ const DANGLING_TERMINAL_SEQUENCE_SUFFIX_RE = new RegExp(String.raw`(?:\u001b\][^\u001b\u009c\u0007]*|\u009d[^\u001b\u009c\u0007]*|\u001b\[[0-?]*[ -/]*|\u009b[0-?]*[ -/]*|\u001b)$`);
13
+ const CODEX_APPROVAL_TIMEOUT_SUBJECTS = {
14
+ command: "Command approval",
15
+ "file-change": "File change approval",
16
+ permissions: "Permission approval",
17
+ other: "Approval"
18
+ };
19
+ function codexApprovalTimeoutText(kind) {
20
+ return `${CODEX_APPROVAL_TIMEOUT_SUBJECTS[kind]} timed out before an operator responded.`;
21
+ }
22
+ /** Starts a two-phase plugin approval request through the OpenClaw gateway. */
23
+ async function requestPluginApproval(params) {
24
+ const timeoutMs = DEFAULT_CODEX_APPROVAL_TIMEOUT_MS;
25
+ return params.hostCapabilities.requestApproval({
26
+ title: truncateCodexApprovalDisplayText(params.title, MAX_PLUGIN_APPROVAL_TITLE_LENGTH),
27
+ description: truncateCodexApprovalDisplayText(params.description, MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH),
28
+ severity: params.severity,
29
+ toolName: params.toolName,
30
+ toolCallId: params.toolCallId,
31
+ timeoutMs,
32
+ transportTimeoutMs: resolveCodexGatewayTimeoutWithGraceMs(timeoutMs),
33
+ ...params.allowedDecisions ? { allowedDecisions: params.allowedDecisions } : {}
34
+ });
35
+ }
36
+ /** Detects the gateway's explicit null-decision marker for unavailable approvals. */
37
+ function approvalRequestExplicitlyUnavailable(result) {
38
+ if (result === null || result === void 0 || typeof result !== "object") return false;
39
+ let descriptor;
40
+ try {
41
+ descriptor = Object.getOwnPropertyDescriptor(result, "decision");
42
+ } catch {
43
+ return false;
44
+ }
45
+ return descriptor !== void 0 && "value" in descriptor && descriptor.value === null;
46
+ }
47
+ /** Waits for the gateway's final approval decision, respecting turn aborts. */
48
+ async function waitForPluginApprovalDecision(params) {
49
+ const timeoutMs = DEFAULT_CODEX_APPROVAL_TIMEOUT_MS;
50
+ const waitPromise = params.hostCapabilities.waitForApproval({
51
+ approvalId: params.approvalId,
52
+ timeoutMs,
53
+ transportTimeoutMs: resolveCodexGatewayTimeoutWithGraceMs(timeoutMs),
54
+ signal: params.signal
55
+ }).catch((error) => {
56
+ if (isApprovalNotFoundError(error)) return;
57
+ throw error;
58
+ });
59
+ if (!params.signal) return await waitPromise;
60
+ let onAbort;
61
+ const abortPromise = new Promise((_, reject) => {
62
+ if (params.signal.aborted) {
63
+ reject(toErrorObject(params.signal.reason, "Non-Error rejection"));
64
+ return;
65
+ }
66
+ onAbort = () => reject(toErrorObject(params.signal.reason, "Non-Error rejection"));
67
+ params.signal.addEventListener("abort", onAbort, { once: true });
68
+ });
69
+ try {
70
+ return await Promise.race([waitPromise, abortPromise]);
71
+ } finally {
72
+ if (onAbort) params.signal.removeEventListener("abort", onAbort);
73
+ }
74
+ }
75
+ /** Converts a gateway exec approval decision into the app-server approval outcome enum. */
76
+ function mapExecDecisionToOutcome(decision) {
77
+ switch (decision) {
78
+ case "allow-once": return "approved-once";
79
+ case "allow-always": return "approved-session";
80
+ case "deny": return "denied";
81
+ default: return "unavailable";
82
+ }
83
+ }
84
+ function truncateCodexApprovalDisplayText(value, maxLength) {
85
+ return value.length <= maxLength ? value : `${truncateUtf16Safe(value, maxLength - 3)}...`;
86
+ }
87
+ function stripDanglingCodexApprovalTerminalSequence(value) {
88
+ return value.replace(DANGLING_TERMINAL_SEQUENCE_SUFFIX_RE, "");
89
+ }
90
+ function sanitizeCodexApprovalVisibleText(value, options = {}) {
91
+ const terminalSafe = value.replace(ANSI_OSC_SEQUENCE_RE, "").replace(ANSI_CONTROL_SEQUENCE_RE, "");
92
+ return (options.stripDanglingTerminalSequence ? stripDanglingCodexApprovalTerminalSequence(terminalSafe) : terminalSafe).replace(INVISIBLE_FORMATTING_CONTROL_RE, " ").replace(CONTROL_CHARACTER_RE, " ").replace(/\s+/g, " ").trim();
93
+ }
94
+ //#endregion
95
+ export { sanitizeCodexApprovalVisibleText as a, waitForPluginApprovalDecision as c, requestPluginApproval as i, codexApprovalTimeoutText as n, stripDanglingCodexApprovalTerminalSequence as o, mapExecDecisionToOutcome as r, truncateCodexApprovalDisplayText as s, approvalRequestExplicitlyUnavailable as t };
@@ -1,16 +1,21 @@
1
- import { P as isCodexFastServiceTier, o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-DPxIvMgE.js";
2
- import { a as getLeasedSharedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient } from "./shared-client-kIBbGjk4.js";
3
- import { g as resolveCodexAppServerRequestModelSelection, v as resolveCodexBindingModelProviderFallback } from "./thread-lifecycle-Bu1BTDXr.js";
4
- import { r as formatCodexDisplayText } from "./command-formatters-B1AEz8ZA.js";
5
- import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-I5Bo-AsX.js";
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";
6
7
  import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
7
8
  import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
8
- import { patchSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
9
+ import { getSessionEntry, patchSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
9
10
  import { ModelSelectionLockedError, applyModelOverrideWithAuthProfileCompatibility } from "openclaw/plugin-sdk/model-session-runtime";
10
11
  //#region extensions/codex/src/command-authorization.ts
11
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
+ }
12
17
  function canMutateCodexHost(ctx) {
13
- return ctx.senderIsOwner === true || ctx.gatewayClientScopes?.includes("operator.admin") === true;
18
+ return ctx.senderIsOwner === true || hasCodexAdminScope(ctx);
14
19
  }
15
20
  //#endregion
16
21
  //#region extensions/codex/src/conversation-control.ts
@@ -198,13 +203,31 @@ async function setCodexConversationFastMode(params) {
198
203
  return `Codex fast mode ${params.enabled ? "enabled" : "disabled"}.`;
199
204
  }
200
205
  async function setCodexConversationPermissions(params) {
201
- const binding = await requireThreadBinding(params.bindingStore, params.identity);
202
- if (!params.mode) return `Codex permissions: ${formatPermissionsMode(binding)}.`;
203
- const policy = permissionsForMode(params.mode);
204
- await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, {
205
- approvalPolicy: policy.approvalPolicy,
206
- sandbox: policy.sandbox
207
- });
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.");
208
231
  return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "default"}.`;
209
232
  }
210
233
  function parseCodexFastModeArg(arg) {
@@ -219,8 +242,8 @@ function parseCodexPermissionsModeArg(arg) {
219
242
  if (normalized === "yolo" || normalized === "full" || normalized === "full-access") return "yolo";
220
243
  if (normalized === "default" || normalized === "guardian") return "default";
221
244
  }
222
- function formatPermissionsMode(binding) {
223
- return binding.approvalPolicy === "never" && binding.sandbox === "danger-full-access" ? "full access" : "default";
245
+ function formatPermissionsMode(mode) {
246
+ return mode === "full" ? "full access" : "default";
224
247
  }
225
248
  async function requireThreadBinding(bindingStore, identity) {
226
249
  const binding = await bindingStore.read(identity);
@@ -251,15 +274,6 @@ function resolveConversationControlModelProvider(params) {
251
274
  if (isCodexAppServerNativeAuthProfile(params) && modelProvider.toLowerCase() === "openai") return;
252
275
  return modelProvider.toLowerCase() === "openai" ? "openai" : modelProvider;
253
276
  }
254
- function permissionsForMode(mode) {
255
- return mode === "yolo" ? {
256
- approvalPolicy: "never",
257
- sandbox: "danger-full-access"
258
- } : {
259
- approvalPolicy: "on-request",
260
- sandbox: "workspace-write"
261
- };
262
- }
263
277
  //#endregion
264
278
  //#region extensions/codex/src/plugin-marketplace-discovery.ts
265
279
  /** Read-only discovery of Codex-owned local, curated, and remote plugin marketplaces. */
@@ -382,4 +396,4 @@ function boundedCatalogText(value) {
382
396
  return sanitized.replace(/\s+/g, " ").trim().slice(0, MAX_PLUGIN_DESCRIPTION_LENGTH);
383
397
  }
384
398
  //#endregion
385
- export { parseCodexPermissionsModeArg as a, setCodexConversationModel as c, stopCodexConversationTurn as d, trackCodexConversationActiveTurn as f, parseCodexFastModeArg as i, setCodexConversationPermissions as l, canMutateCodexHost as m, parseCodexPluginMarketplaceId as n, readCodexConversationActiveTurn as o, CODEX_NATIVE_EXECUTION_AUTH_ERROR as p, formatPermissionsMode as r, setCodexConversationFastMode as s, discoverCodexMarketplacePlugins as t, steerCodexConversationTurn as u };
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 { 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";
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,
@@ -230,6 +230,7 @@ var definitions = {
230
230
  "usageLimitExceeded",
231
231
  "serverOverloaded",
232
232
  "cyberPolicy",
233
+ "misalignmentPolicyViolation",
233
234
  "internalServerError",
234
235
  "unauthorized",
235
236
  "badRequest",
@@ -448,6 +449,23 @@ var definitions = {
448
449
  ],
449
450
  "type": "string"
450
451
  },
452
+ "ImageGenerationFailure": { "oneOf": [{
453
+ "properties": {
454
+ "limitId": { "type": "string" },
455
+ "resetsAt": {
456
+ "format": "int64",
457
+ "type": ["integer", "null"]
458
+ },
459
+ "type": {
460
+ "enum": ["usageLimitExceeded"],
461
+ "title": "UsageLimitExceededImageGenerationFailureType",
462
+ "type": "string"
463
+ }
464
+ },
465
+ "required": ["limitId", "type"],
466
+ "title": "UsageLimitExceededImageGenerationFailure",
467
+ "type": "object"
468
+ }] },
451
469
  "InputModality": {
452
470
  "description": "Canonical user-input modality tags advertised by a model.",
453
471
  "oneOf": [
@@ -584,6 +602,10 @@ var definitions = {
584
602
  "default": null,
585
603
  "type": ["string", "null"]
586
604
  },
605
+ "multiAgentVersion": {
606
+ "anyOf": [{ "$ref": "#/definitions/MultiAgentVersion" }, { "type": "null" }],
607
+ "description": "Multi-agent runtime declared by this model, when available."
608
+ },
587
609
  "serviceTiers": {
588
610
  "default": [],
589
611
  "items": { "$ref": "#/definitions/ModelServiceTier" },
@@ -635,6 +657,11 @@ var definitions = {
635
657
  "migrationMarkdown": { "type": ["string", "null"] },
636
658
  "model": { "type": "string" },
637
659
  "modelLink": { "type": ["string", "null"] },
660
+ "retirementAt": {
661
+ "description": "Informational Unix timestamp for this upgrade's scheduled retirement, if known.",
662
+ "format": "int64",
663
+ "type": ["integer", "null"]
664
+ },
638
665
  "upgradeCopy": { "type": ["string", "null"] }
639
666
  },
640
667
  "required": ["model"],
@@ -653,6 +680,15 @@ var definitions = {
653
680
  "type": "string"
654
681
  }]
655
682
  },
683
+ "MultiAgentVersion": {
684
+ "description": "Multi-agent runtime supported by a model.",
685
+ "enum": [
686
+ "disabled",
687
+ "v1",
688
+ "v2"
689
+ ],
690
+ "type": "string"
691
+ },
656
692
  "NetworkAccess": {
657
693
  "enum": ["restricted", "enabled"],
658
694
  "type": "string"
@@ -1469,6 +1505,10 @@ var definitions = {
1469
1505
  },
1470
1506
  {
1471
1507
  "properties": {
1508
+ "failure": {
1509
+ "anyOf": [{ "$ref": "#/definitions/ImageGenerationFailure" }, { "type": "null" }],
1510
+ "default": null
1511
+ },
1472
1512
  "id": { "type": "string" },
1473
1513
  "result": { "type": "string" },
1474
1514
  "revisedPrompt": { "type": ["string", "null"] },
@@ -1546,6 +1586,11 @@ var definitions = {
1546
1586
  "ThreadSection": {
1547
1587
  "description": "An independently persisted, user-visible thread section.",
1548
1588
  "properties": {
1589
+ "appearance": {
1590
+ "anyOf": [{ "$ref": "#/definitions/ThreadSectionAppearance" }, { "type": "null" }],
1591
+ "default": null,
1592
+ "description": "Optional appearance synchronized across clients."
1593
+ },
1549
1594
  "id": {
1550
1595
  "description": "Opaque UUIDv7 identity that remains stable when the section is renamed.",
1551
1596
  "type": "string"
@@ -1558,6 +1603,14 @@ var definitions = {
1558
1603
  "required": ["id", "name"],
1559
1604
  "type": "object"
1560
1605
  },
1606
+ "ThreadSectionAppearance": {
1607
+ "description": "Extensible visual presentation for a custom thread section.",
1608
+ "properties": {
1609
+ "color": { "type": ["string", "null"] },
1610
+ "icon": { "type": ["string", "null"] }
1611
+ },
1612
+ "type": "object"
1613
+ },
1561
1614
  "ThreadSource": { "type": "string" },
1562
1615
  "ThreadStatus": { "oneOf": [
1563
1616
  {
@@ -1941,7 +1994,7 @@ var ThreadResumeResponse_default = {
1941
1994
  },
1942
1995
  "itemsBackwardsCursor": {
1943
1996
  "default": null,
1944
- "description": "Opaque head cursor for hydrating paginated items backwards.\n\nPass this as `cursor` to `thread/items/list` with `sortDirection: \"desc\"`. The first page includes the cursor's head item.",
1997
+ "description": "Opaque cursor for hydrating paginated items backwards.\n\nPass this as `cursor` to `thread/items/list` with `sortDirection: \"desc\"`. The first page includes the item identified by the cursor.",
1945
1998
  "type": ["string", "null"]
1946
1999
  },
1947
2000
  "model": { "type": "string" },
@@ -1966,7 +2019,7 @@ var ThreadResumeResponse_default = {
1966
2019
  "thread": { "$ref": "./CodexAppServerProtocolDefinitions.json#/definitions/Thread" },
1967
2020
  "turnsBackwardsCursor": {
1968
2021
  "default": null,
1969
- "description": "Opaque head cursor for hydrating paginated turns backwards.\n\nPass this as `cursor` to `thread/turns/list` with `sortDirection: \"desc\"`. The first page includes the cursor's head turn.",
2022
+ "description": "Opaque cursor for hydrating paginated turns backwards.\n\nPass this as `cursor` to `thread/turns/list` with `sortDirection: \"desc\"`. The first page includes the turn identified by the cursor.",
1970
2023
  "type": ["string", "null"]
1971
2024
  }
1972
2025
  },
@@ -1,4 +1,4 @@
1
- import { ct as isJsonObject } from "./shared-client-kIBbGjk4.js";
1
+ import { ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
2
2
  import { asBoolean, asFiniteNumber, normalizeOptionalString, parseStrictFiniteNumber } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { MAX_DATE_TIMESTAMP_MS, resolveExpiresAtMsFromEpochSeconds } from "openclaw/plugin-sdk/number-runtime";
4
4
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
@@ -1,5 +1,5 @@
1
- import { _ as withTimeout, a as getLeasedSharedCodexAppServerClient, i as createIsolatedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient, p as retireSharedCodexAppServerClientIfCurrent, s as isCodexAppServerStartSelectionChangedError } from "./shared-client-kIBbGjk4.js";
2
- import { t as resolveCodexAppServerDirectSandboxBypassBlock } from "./sandbox-guard-Cmwc9eIk.js";
1
+ import { _ as withTimeout, a as getLeasedSharedCodexAppServerClient, i as createIsolatedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient, p as retireSharedCodexAppServerClientIfCurrent, s as isCodexAppServerStartSelectionChangedError } from "./shared-client-Dw-rzii0.js";
2
+ import { t as resolveCodexAppServerDirectSandboxBypassBlock } from "./sandbox-guard-C1qEeZ5C.js";
3
3
  //#region extensions/codex/src/app-server/request.ts
4
4
  /** Sends one guarded request over a client lease owned by the caller. */
5
5
  async function requestCodexAppServerClientJson(params) {