@openclaw/codex 2026.8.1-beta.2 → 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.
Files changed (64) hide show
  1. package/dist/api.js +146 -0
  2. package/dist/{attempt-client-cleanup-DMLXUfa8.js → attempt-client-cleanup-CVPvp9dL.js} +47 -5
  3. package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
  4. package/dist/{binding-connection-I5Bo-AsX.js → binding-connection-CCQFs8lf.js} +15 -3
  5. package/dist/{bounded-turn-qgZmzy_4.js → bounded-turn-rq5tiSXk.js} +27 -26
  6. package/dist/{capabilities-CybGI1oz.js → capabilities-CGm_94eL.js} +1 -1
  7. package/dist/cli-metadata.js +1 -1
  8. package/dist/{command-formatters-B1AEz8ZA.js → command-formatters-C54Yg3eA.js} +2 -2
  9. package/dist/{command-handlers-Db8pu_ds.js → command-handlers-BvOAHTrA.js} +111 -67
  10. package/dist/{compact-LspQaGfl.js → compact-Hd7SAc0N.js} +35 -30
  11. package/dist/{session-binding-DPxIvMgE.js → config-Cxw3Cl3k.js} +361 -1161
  12. package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
  13. package/dist/doctor-contract-api.js +128 -26
  14. package/dist/{dynamic-tools-BVdyWkUD.js → dynamic-tools-BFoUcRdx.js} +1341 -1464
  15. package/dist/{effective-mcp-catalog-DIIhAtOZ.js → effective-mcp-catalog-BTJHnDSx.js} +2 -2
  16. package/dist/elicitation-input-DMkeki8d.js +71 -0
  17. package/dist/{event-projector-assistant-message-BwxV4d6N.js → event-projector-assistant-message-C5-Ds8mA.js} +18 -1
  18. package/dist/{event-projector-usage-e5huIQWu.js → event-projector-usage-D3PHFFXh.js} +18 -18
  19. package/dist/harness-DVfUQBlQ.js +248 -0
  20. package/dist/harness.js +2 -226
  21. package/dist/index.js +405 -299
  22. package/dist/{isolated-completion-C58NbL40.js → isolated-completion-Cbbx_5Ed.js} +4 -4
  23. package/dist/launch-args-sXOAg0SX.js +84 -0
  24. package/dist/managed-binary-ZkGodW19.js +248 -0
  25. package/dist/media-understanding-provider.js +2 -2
  26. package/dist/model-catalog-o6Cgjoss.js +101 -0
  27. package/dist/{models-BFlpn1Ex.js → models-DgFWSuxA.js} +25 -28
  28. package/dist/{native-subagent-monitor-DyTGmTUx.js → native-subagent-monitor-CwFyoylz.js} +385 -94
  29. package/dist/node-exec-server.runtime-DXrqpw1c.js +195 -0
  30. package/dist/plugin-approval-roundtrip-D80UZiJ_.js +95 -0
  31. package/dist/{plugin-marketplace-discovery-CzrGJdCR.js → plugin-marketplace-discovery-mdmScYOj.js} +60 -55
  32. package/dist/{plugin-metadata-cache-CNJPj4_b.js → plugin-metadata-cache-CulOABwu.js} +164 -134
  33. package/dist/{protocol-validators-B4F7L8Rf.js → protocol-validators-Bg5rpNxk.js} +203 -7
  34. package/dist/{rate-limits-DZXmOL8-.js → rate-limits-hFtzt2Up.js} +1 -1
  35. package/dist/{sandbox-guard-Cmwc9eIk.js → request-CCm4LaED.js} +207 -20
  36. package/dist/{run-attempt-P8BdxC1I.js → run-attempt-BwNQDH2u.js} +1506 -836
  37. package/dist/{runtime-artifact-BVSPdd6g.js → runtime-artifact-DeBvleJw.js} +4 -7
  38. package/dist/session-binding-q2WSTVmC.js +947 -0
  39. package/dist/{session-catalog-xwNi_SDM.js → session-catalog-C2Tae4rI.js} +1698 -1346
  40. package/dist/session-catalog-home-id-DAKUrm3C.js +112 -0
  41. package/dist/{session-cli-7hgXZDV7.js → session-cli-BuDjm5Ou.js} +20 -7
  42. package/dist/session-permission-policy-gLm40Vtq.js +160 -0
  43. package/dist/session-retirement-CdkI0bvb.js +90 -0
  44. package/dist/{session-upstream-marker-CrIFX06J.js → session-upstream-marker-Bcy33kam.js} +2 -3
  45. package/dist/{settled-turn-finalizer-BRWBO4MO.js → settled-turn-finalizer-B8JJcxCi.js} +27 -22
  46. package/dist/{shared-client-kIBbGjk4.js → shared-client-kNkljY-R.js} +2023 -607
  47. package/dist/{side-question-9HAL26l9.js → side-question-GwD73tX6.js} +109 -57
  48. package/dist/{thread-lifecycle-Bu1BTDXr.js → thread-lifecycle-Ss-uwnC4.js} +1208 -497
  49. package/dist/{thread-ownership-6kOQHlyC.js → thread-ownership-CeYBqg_4.js} +18 -8
  50. package/dist/{plugin-app-cache-key-C3H2CVp6.js → thread-resume-DF54hagX.js} +64 -6
  51. package/dist/{transcript-mirror-B9gGgnJS.js → transcript-mirror-CkEQIna-.js} +158 -41
  52. package/dist/transport-stdio-C7-s9TLG.js +708 -0
  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-BACGlOFa.js} +86 -88
  55. package/dist/{usage-CHlV0e-o.js → usage-C2l8Mils.js} +3 -3
  56. package/dist/{web-search-provider.runtime-DRw2Vl42.js → web-search-provider.runtime-B2XgRdFv.js} +3 -3
  57. package/openclaw.plugin.json +50 -2
  58. package/package.json +9 -8
  59. package/dist/app-server-policy-zcBDc1JU.js +0 -49
  60. package/dist/incognito-session-ET_ufDH-.js +0 -2
  61. package/dist/request-BRl5_UfX.js +0 -157
  62. package/dist/session-retirement-DoMMJFKm.js +0 -36
  63. package/dist/thread-resume-CPrJNQVM.js +0 -30
  64. package/dist/transport-stdio-DIImwDVS.js +0 -99
@@ -0,0 +1,195 @@
1
+ import { n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-ZkGodW19.js";
2
+ import { i as closeCodexAppServerTransportAndWait, t as createStdioTransport } from "./transport-stdio-C7-s9TLG.js";
3
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { mkdir } from "node:fs/promises";
5
+ import path from "node:path";
6
+ import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
7
+ import { killProcessTree } from "openclaw/plugin-sdk/process-runtime";
8
+ import { once } from "node:events";
9
+ import { sanitizeEnvVars } from "openclaw/plugin-sdk/sandbox";
10
+ //#region extensions/codex/src/node-exec-server.runtime.ts
11
+ const MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES = 64 * 1024 * 1024;
12
+ const CODEX_EXEC_SERVER_TERMINATION_GRACE_MS = 1e3;
13
+ const CODEX_EXEC_SERVER_REAP_TIMEOUT_MS = 5e3;
14
+ const NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT = /^(?:SYSTEMROOT|WINDIR|COMSPEC|PATHEXT|TEMP|TMP|TMPDIR)$/iu;
15
+ function validateNodeExecServerMessage(message) {
16
+ 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.");
17
+ const encoded = Buffer.from(message.buffer, message.byteOffset, message.byteLength);
18
+ if (encoded.includes(10) || encoded.includes(13)) throw new Error("Codex exec-server JSON-RPC frames must contain exactly one message.");
19
+ let decoded;
20
+ try {
21
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(encoded);
22
+ decoded = JSON.parse(text);
23
+ } catch {
24
+ throw new Error("Codex exec-server received malformed UTF-8 or JSON-RPC.");
25
+ }
26
+ 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.");
27
+ return encoded;
28
+ }
29
+ function nodeExecServerAbortError(signal) {
30
+ return signal.reason instanceof Error ? signal.reason : /* @__PURE__ */ new Error("Codex node exec-server connection closed.");
31
+ }
32
+ function writeNodeExecServerMessage(child, message, signal) {
33
+ if (signal.aborted) throw nodeExecServerAbortError(signal);
34
+ const payload = Buffer.concat([message, Buffer.from("\n")]);
35
+ if (!child.stdin.write(payload)) return once(child.stdin, "drain", { signal }).then(() => void 0);
36
+ }
37
+ async function relayNodeExecServerOutput(child, send) {
38
+ let fragments = [];
39
+ let pendingBytes = 0;
40
+ for await (const rawChunk of child.stdout) {
41
+ const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);
42
+ let offset = 0;
43
+ while (offset < chunk.byteLength) {
44
+ const newline = chunk.indexOf(10, offset);
45
+ const fragment = chunk.subarray(offset, newline === -1 ? chunk.byteLength : newline);
46
+ const nextLength = pendingBytes + fragment.byteLength;
47
+ if (nextLength > 67108865) throw new Error("Codex exec-server stdout message exceeds its 64 MiB limit.");
48
+ if (fragment.byteLength > 0) fragments.push(fragment);
49
+ pendingBytes = nextLength;
50
+ if (newline === -1) {
51
+ 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.");
52
+ break;
53
+ }
54
+ const trailing = fragments.at(-1);
55
+ if (trailing?.[trailing.byteLength - 1] === 13) {
56
+ pendingBytes -= 1;
57
+ if (trailing.byteLength === 1) fragments.pop();
58
+ else fragments[fragments.length - 1] = trailing.subarray(0, trailing.byteLength - 1);
59
+ }
60
+ const message = validateNodeExecServerMessage(fragments.length === 1 ? fragments[0] : Buffer.concat(fragments, pendingBytes));
61
+ fragments = [];
62
+ pendingBytes = 0;
63
+ await send(message);
64
+ offset = newline + 1;
65
+ }
66
+ }
67
+ if (pendingBytes > 0) throw new Error("Codex exec-server stdout ended with an unterminated JSON-RPC message.");
68
+ }
69
+ function createNodeExecServerProcessOwner(child, closed) {
70
+ let termination;
71
+ return { terminate: () => termination ??= (async () => {
72
+ if (process.platform === "win32" && child.pid) killProcessTree(child.pid, { graceMs: CODEX_EXEC_SERVER_TERMINATION_GRACE_MS });
73
+ if (!await closeCodexAppServerTransportAndWait(child, {
74
+ forceKillDelayMs: CODEX_EXEC_SERVER_TERMINATION_GRACE_MS,
75
+ exitTimeoutMs: CODEX_EXEC_SERVER_REAP_TIMEOUT_MS
76
+ })) throw new Error("Codex node exec-server process tree did not terminate.");
77
+ await closed;
78
+ })() };
79
+ }
80
+ /** Runs the one-connection paired-node exec-server after lightweight command admission. */
81
+ async function runCodexNodeExecServer(params) {
82
+ const { io } = params;
83
+ const frames = io.frames;
84
+ if (!frames) throw new Error("Codex node exec-server requires duplex frames.");
85
+ const cwd = params.workspaceDir;
86
+ let writes;
87
+ let rejectDisconnected;
88
+ const disconnected = new Promise((_resolve, reject) => {
89
+ rejectDisconnected = reject;
90
+ });
91
+ disconnected.catch(() => {});
92
+ const onAbort = () => {
93
+ const error = nodeExecServerAbortError(io.signal);
94
+ rejectDisconnected(error);
95
+ };
96
+ io.signal.addEventListener("abort", onAbort, { once: true });
97
+ try {
98
+ if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
99
+ return await withTempWorkspace({
100
+ rootDir: resolvePreferredOpenClawTmpDir(),
101
+ prefix: "codex-node-exec-server-"
102
+ }, async ({ dir }) => {
103
+ const codexHome = path.join(dir, ".codex");
104
+ await mkdir(codexHome, {
105
+ recursive: true,
106
+ mode: 448
107
+ });
108
+ const resolved = await resolveManagedCodexAppServerStartOptions({
109
+ transport: "stdio",
110
+ command: "codex",
111
+ commandSource: "managed",
112
+ managedCommandOrder: "package-first",
113
+ args: [
114
+ "exec-server",
115
+ "--listen",
116
+ "stdio"
117
+ ],
118
+ headers: {}
119
+ });
120
+ const native = resolveManagedCodexNativeCommand(resolved.command);
121
+ if (!native || isManagedCodexDesktopCommand(resolved.command)) throw new Error("Codex node exec-server requires the pinned managed package binary.");
122
+ const baseEnv = sanitizeEnvVars(process.env, {
123
+ strictMode: true,
124
+ customAllowedPatterns: [NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT]
125
+ }).allowed;
126
+ if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
127
+ params.assertExecAuthorized();
128
+ const child = await 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
+ if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
143
+ params.assertExecAuthorized();
144
+ });
145
+ child.stdin.on("error", (error) => {
146
+ rejectDisconnected(error);
147
+ });
148
+ let stderr = Buffer.alloc(0);
149
+ child.stderr.on("data", (chunk) => {
150
+ const bounded = (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)).subarray(-4096);
151
+ stderr = Buffer.concat([stderr, bounded]).subarray(-4096);
152
+ });
153
+ const closed = new Promise((resolve) => {
154
+ child.once("close", (code, signal) => resolve({
155
+ code,
156
+ signal
157
+ }));
158
+ });
159
+ child.once("error", (error) => {
160
+ rejectDisconnected(error);
161
+ });
162
+ const owner = createNodeExecServerProcessOwner(child, closed);
163
+ params.activeProcesses.add(owner.terminate);
164
+ const output = relayNodeExecServerOutput(child, frames.send.bind(frames));
165
+ output.catch((error) => {
166
+ rejectDisconnected(error instanceof Error ? error : new Error(String(error)));
167
+ });
168
+ try {
169
+ if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
170
+ params.onFrameReceiver((message) => {
171
+ const encoded = validateNodeExecServerMessage(message);
172
+ const operation = writes ? writes.then(() => writeNodeExecServerMessage(child, encoded, io.signal)) : writeNodeExecServerMessage(child, encoded, io.signal);
173
+ if (!operation) return;
174
+ const observed = operation.catch(() => {});
175
+ writes = observed;
176
+ observed.then(() => {
177
+ if (writes === observed) writes = void 0;
178
+ });
179
+ return operation;
180
+ });
181
+ const outcome = await Promise.race([closed, disconnected]);
182
+ const diagnostic = stderr.toString("utf8").trim();
183
+ throw new Error(`Codex node exec-server exited (code ${outcome.code ?? "none"}, signal ${outcome.signal ?? "none"})${diagnostic ? `: ${diagnostic}` : "."}`);
184
+ } finally {
185
+ await owner.terminate();
186
+ params.activeProcesses.delete(owner.terminate);
187
+ await Promise.allSettled([output, ...writes ? [writes] : []]);
188
+ }
189
+ });
190
+ } finally {
191
+ io.signal.removeEventListener("abort", onAbort);
192
+ }
193
+ }
194
+ //#endregion
195
+ export { runCodexNodeExecServer };
@@ -0,0 +1,95 @@
1
+ import { F as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-kNkljY-R.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,22 @@
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 { 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";
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_HOST_INSPECTION_AUTH_ERROR = "Only an owner or operator.admin can inspect Codex host state.";
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.";
15
+ function hasCodexAdminScope(ctx) {
16
+ return ctx.gatewayClientScopes?.includes("operator.admin") === true;
17
+ }
12
18
  function canMutateCodexHost(ctx) {
13
- return ctx.senderIsOwner === true || ctx.gatewayClientScopes?.includes("operator.admin") === true;
19
+ return ctx.senderIsOwner === true || hasCodexAdminScope(ctx);
14
20
  }
15
21
  //#endregion
16
22
  //#region extensions/codex/src/conversation-control.ts
@@ -140,23 +146,23 @@ async function setCodexConversationModel(params) {
140
146
  });
141
147
  const nextModel = modelSelection.model;
142
148
  const modelChanged = nextModel !== binding.model || nextModelProvider !== binding.modelProvider;
143
- const session = params.session ?? (params.identity.kind === "session" && params.identity.sessionKey ? {
144
- agentId: params.identity.agentId,
145
- sessionId: params.identity.sessionId,
146
- sessionKey: params.identity.sessionKey
147
- } : void 0);
148
- 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) {
149
155
  if (!await patchSessionEntry({
150
- agentId: session.agentId,
151
- storePath: resolveStorePath(params.config?.session?.store, { agentId: session.agentId }),
152
- sessionKey: session.sessionKey,
156
+ agentId: identity.agentId,
157
+ storePath: resolveStorePath(params.config?.session?.store, { agentId: identity.agentId }),
158
+ sessionKey: identity.sessionKey,
153
159
  requireWriteSuccess: true,
154
160
  replaceEntry: true,
155
161
  update: (entry) => {
156
- if (entry.sessionId !== session.sessionId) throw new Error("Codex session changed while applying the model selection.");
162
+ if (entry.sessionId !== identity.sessionId) throw new Error("Codex session changed while applying the model selection.");
157
163
  applyModelOverrideWithAuthProfileCompatibility({
158
164
  cfg: params.config ?? {},
159
- agentDir: params.agentDir ?? resolveAgentDir(params.config ?? {}, session.agentId),
165
+ agentDir: params.agentDir ?? resolveAgentDir(params.config ?? {}, identity.agentId),
160
166
  entry,
161
167
  currentProvider: binding.modelProvider ?? "openai",
162
168
  selection: {
@@ -168,25 +174,11 @@ async function setCodexConversationModel(params) {
168
174
  return entry;
169
175
  }
170
176
  })) throw new Error("Codex session changed while applying the model selection.");
171
- if (params.identity.kind === "conversation") await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, {
172
- model: nextModel,
173
- modelProvider: nextModelProvider,
174
- ...modelChanged && binding.contextEngine?.projection ? { contextEngine: {
175
- ...binding.contextEngine,
176
- projection: void 0
177
- } } : {}
178
- });
179
- else if (modelChanged && binding.contextEngine?.projection) await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, { contextEngine: {
180
- ...binding.contextEngine,
181
- projection: void 0
182
- } });
177
+ if (modelChanged && binding.contextEngine?.projection) await patchThreadBinding(params.bindingStore, identity, binding.threadId, projectionPatch);
183
178
  } else await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, {
184
179
  model: nextModel,
185
180
  modelProvider: nextModelProvider,
186
- ...modelChanged && binding.contextEngine?.projection ? { contextEngine: {
187
- ...binding.contextEngine,
188
- projection: void 0
189
- } } : {}
181
+ ...projectionPatch
190
182
  });
191
183
  return `Codex model set to ${formatCodexDisplayText(nextModel)}.`;
192
184
  }
@@ -198,14 +190,31 @@ async function setCodexConversationFastMode(params) {
198
190
  return `Codex fast mode ${params.enabled ? "enabled" : "disabled"}.`;
199
191
  }
200
192
  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
- });
208
- return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "default"}.`;
193
+ const storePath = resolveStorePath(params.config?.session?.store, { agentId: params.session.agentId });
194
+ if (!params.mode) {
195
+ const entry = getSessionEntry({
196
+ agentId: params.session.agentId,
197
+ hydrateSkillPromptRefs: false,
198
+ readConsistency: "latest",
199
+ sessionKey: params.session.sessionKey,
200
+ storePath
201
+ });
202
+ if (entry?.sessionId !== params.session.sessionId) throw new Error("Codex session changed while reading the permission mode.");
203
+ return `Codex permissions: ${formatPermissionsMode(entry.permissionMode)}.`;
204
+ }
205
+ if (!await patchSessionEntry({
206
+ agentId: params.session.agentId,
207
+ storePath,
208
+ sessionKey: params.session.sessionKey,
209
+ requireWriteSuccess: true,
210
+ replaceEntry: true,
211
+ update: (entry) => {
212
+ if (entry.sessionId !== params.session.sessionId) throw new Error("Codex session changed while applying the permission mode.");
213
+ entry.permissionMode = params.mode === "yolo" ? "full" : "guarded";
214
+ return entry;
215
+ }
216
+ })) throw new Error("Codex session changed while applying the permission mode.");
217
+ return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "guarded"}.`;
209
218
  }
210
219
  function parseCodexFastModeArg(arg) {
211
220
  const normalized = arg?.trim().toLowerCase();
@@ -217,10 +226,15 @@ function parseCodexPermissionsModeArg(arg) {
217
226
  const normalized = arg?.trim().toLowerCase();
218
227
  if (!normalized || normalized === "status") return;
219
228
  if (normalized === "yolo" || normalized === "full" || normalized === "full-access") return "yolo";
220
- if (normalized === "default" || normalized === "guardian") return "default";
229
+ if ([
230
+ "default",
231
+ "guardian",
232
+ "guarded",
233
+ "approve"
234
+ ].includes(normalized)) return "default";
221
235
  }
222
- function formatPermissionsMode(binding) {
223
- return binding.approvalPolicy === "never" && binding.sandbox === "danger-full-access" ? "full access" : "default";
236
+ function formatPermissionsMode(mode) {
237
+ return mode === "full" ? "full access" : mode ?? "default";
224
238
  }
225
239
  async function requireThreadBinding(bindingStore, identity) {
226
240
  const binding = await bindingStore.read(identity);
@@ -251,15 +265,6 @@ function resolveConversationControlModelProvider(params) {
251
265
  if (isCodexAppServerNativeAuthProfile(params) && modelProvider.toLowerCase() === "openai") return;
252
266
  return modelProvider.toLowerCase() === "openai" ? "openai" : modelProvider;
253
267
  }
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
268
  //#endregion
264
269
  //#region extensions/codex/src/plugin-marketplace-discovery.ts
265
270
  /** Read-only discovery of Codex-owned local, curated, and remote plugin marketplaces. */
@@ -382,4 +387,4 @@ function boundedCatalogText(value) {
382
387
  return sanitized.replace(/\s+/g, " ").trim().slice(0, MAX_PLUGIN_DESCRIPTION_LENGTH);
383
388
  }
384
389
  //#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 };
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 };