@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.
Files changed (68) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +147 -0
  3. package/dist/app-server-policy-bg5QPSVP.js +25 -0
  4. package/dist/attempt-client-cleanup-URjUlCHg.js +735 -0
  5. package/dist/binding-connection-DAvZwp96.js +45 -0
  6. package/dist/{bounded-turn-D2ZAgZVz.js → bounded-turn-4BjrZEwW.js} +63 -56
  7. package/dist/{capabilities-BFDTVYr4.js → capabilities-CH3K57v4.js} +8 -2
  8. package/dist/cli-metadata.js +1 -1
  9. package/dist/{command-formatters-C336eRVS.js → command-formatters-D0nZ3qtd.js} +18 -18
  10. package/dist/{command-handlers-DAHUSry9.js → command-handlers-DC86lgT4.js} +507 -101
  11. package/dist/command-rpc-xUIIonsO.js +90 -0
  12. package/dist/{compact-D_uvHurS.js → compact-COqgBRny.js} +234 -214
  13. package/dist/{session-binding-BXpo9ymA.js → config-CpNeo5AE.js} +284 -1163
  14. package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
  15. package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
  16. package/dist/doctor-contract-api.js +48 -50
  17. package/dist/{dynamic-tools-D2gYkSBO.js → dynamic-tools-fJZhl4CE.js} +3442 -1433
  18. package/dist/{effective-mcp-catalog-Bbd98Inw.js → effective-mcp-catalog-4YKn51aG.js} +20 -15
  19. package/dist/elicitation-input-DMkeki8d.js +71 -0
  20. package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
  21. package/dist/{attempt-notifications-AP-a-Q5k.js → event-projector-usage-CLwNEJqW.js} +113 -29
  22. package/dist/harness-DoKQcF8n.js +258 -0
  23. package/dist/harness.js +2 -160
  24. package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
  25. package/dist/index.js +730 -256
  26. package/dist/isolated-completion-DPMtlH9r.js +75 -0
  27. package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
  28. package/dist/managed-binary-By4FZC6i.js +212 -0
  29. package/dist/media-understanding-provider.js +5 -5
  30. package/dist/model-catalog-CmGoqVKB.js +48 -0
  31. package/dist/{models-BBMKU4jA.js → models-CZw1wClT.js} +12 -17
  32. package/dist/native-subagent-monitor-GGq3RnOo.js +3225 -0
  33. package/dist/node-exec-server.runtime-Bsu1LdFZ.js +192 -0
  34. package/dist/{plugin-app-cache-key-DztPafOA.js → plugin-app-cache-key-DMNQ8Zi8.js} +18 -6
  35. package/dist/plugin-approval-roundtrip-C75Yiiwc.js +95 -0
  36. package/dist/plugin-marketplace-discovery-CSWDkMrP.js +399 -0
  37. package/dist/{computer-use-CYEc8U3w.js → plugin-metadata-cache-BXH5NF-4.js} +109 -6
  38. package/dist/protocol-validators-VAVyEnDp.js +2399 -0
  39. package/dist/{rate-limits-CU-gVCCS.js → rate-limits-BI1dMHDG.js} +17 -35
  40. package/dist/{request-qKh331yu.js → request-DSK0W6YI.js} +3 -3
  41. package/dist/{run-attempt-CY9WlDLc.js → run-attempt-BV3HzuCf.js} +3416 -7194
  42. package/dist/{runtime-artifact-CmtG_t1L.js → runtime-artifact-BvyT1uyd.js} +11 -29
  43. package/dist/{sandbox-guard-NuhpXmPB.js → sandbox-guard-C1qEeZ5C.js} +29 -30
  44. package/dist/session-binding-BTrLf9Qm.js +874 -0
  45. package/dist/{session-catalog-DyOgR4WH.js → session-catalog-ezP_UcRM.js} +1584 -1289
  46. package/dist/session-catalog-home-id-BNwAJ9D7.js +18 -0
  47. package/dist/{session-cli-2PZaFLRh.js → session-cli-B1hKvfkI.js} +20 -7
  48. package/dist/session-retirement-CE4iMiLh.js +36 -0
  49. package/dist/{session-upstream-marker-B6U7tLw5.js → session-upstream-marker-D_2npHlA.js} +1 -1
  50. package/dist/{settled-turn-finalizer-CXY2Z9dT.js → settled-turn-finalizer-Dx1onIqg.js} +40 -28
  51. package/dist/{shared-client-DTbvH-XV.js → shared-client-Dw-rzii0.js} +1315 -469
  52. package/dist/{side-question-_ulBk1AL.js → side-question-DbXkJZzg.js} +140 -69
  53. package/dist/{thread-lifecycle-DF53ogiA.js → thread-lifecycle-DKdrnTMX.js} +927 -768
  54. package/dist/thread-ownership-i2NBwDUL.js +92 -0
  55. package/dist/thread-resume-CdJk2Ehf.js +30 -0
  56. package/dist/transcript-mirror-BU0_LKAL.js +588 -0
  57. package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DhoGy33Z.js} +13 -2
  58. package/dist/upstream-prompt-provenance-CFmsKwr9.js +39 -0
  59. package/dist/{upstream-session-fork-Dy4Xvuoj.js → upstream-session-fork-BDVJCLAD.js} +14 -8
  60. package/dist/{usage-CQ6GhD5-.js → usage-9dKJCgcy.js} +3 -3
  61. package/dist/{web-search-provider.runtime-CCFhg2z5.js → web-search-provider.runtime-DCdx4DGu.js} +8 -9
  62. package/openclaw.plugin.json +49 -4
  63. package/package.json +6 -5
  64. package/dist/app-server-policy-BSaO2JIT.js +0 -49
  65. package/dist/conversation-control-xsIeXbo4.js +0 -287
  66. package/dist/event-projector-usage-Xp4AlR2k.js +0 -86
  67. package/dist/notification-correlation-CU6_AnOb.js +0 -67
  68. package/dist/transcript-mirror-DzsdNCf5.js +0 -6924
@@ -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,11 +1,11 @@
1
- import { K as resolveCodexAppServerHomeDir } from "./shared-client-DTbvH-XV.js";
2
- import { w as resolveCodexAppServerUserHomeDir } from "./session-binding-BXpo9ymA.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
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
+ import { readPluginPackageVersion } from "openclaw/plugin-sdk/extension-shared";
4
6
  import { isFutureDateTimestampMs, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
5
7
  import { OPENCLAW_VERSION, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
6
8
  import { createHash } from "node:crypto";
7
- import { readPluginPackageVersion } from "openclaw/plugin-sdk/extension-shared";
8
- import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
10
10
  //#region extensions/codex/src/app-server/app-inventory-cache.ts
11
11
  /**
@@ -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,13 +372,17 @@ 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;
370
382
  if (start.transport === "unix" && (!start.url || start.url === "unix://")) return resolveCodexAppServerUserHomeDir(start.env ?? process.env);
371
383
  if (start.transport !== "stdio") return null;
372
384
  if (start.homeScope === "user") return resolveCodexAppServerUserHomeDir(process.env);
373
- return agentDir ? resolveCodexAppServerHomeDir(agentDir) : null;
385
+ return agentDir ? resolveCodexAppServerLocalHomeDir(start, agentDir) : null;
374
386
  }
375
387
  /** Serializes app-server endpoint identity, including credential fingerprints. */
376
388
  function resolveCodexPluginAppCacheEndpoint(appServer) {
@@ -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 };