@openclaw/codex 2026.8.2 → 2026.9.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 (61) hide show
  1. package/dist/api.js +3 -3
  2. package/dist/{attempt-client-cleanup-CpVfwctT.js → attempt-client-cleanup-DYHcRQAa.js} +6 -43
  3. package/dist/attempt-context-DmQUNWwT.js +634 -0
  4. package/dist/{binding-connection-CF7BmrDk.js → binding-connection-E6uDsPlx.js} +2 -2
  5. package/dist/{bounded-turn-DRC3hcjm.js → bounded-turn-wzJrwKKe.js} +8 -9
  6. package/dist/{capabilities-D6m_TdVy.js → capabilities-dIjNVCYH.js} +1 -1
  7. package/dist/cli-metadata.js +1 -1
  8. package/dist/{command-formatters--UToCokS.js → command-formatters-CLHhEB1Q.js} +3 -3
  9. package/dist/{command-handlers-CLFx2Ypa.js → command-handlers-CTGb2csu.js} +54 -55
  10. package/dist/{compact-5xqW1oCh.js → compact-_t0HQrUS.js} +33 -25
  11. package/dist/{config-CcYL77O6.js → config-BhmfC1s6.js} +12 -8
  12. package/dist/{context-compaction-activity-BOeJf7yo.js → context-compaction-activity-CMla5FPJ.js} +4 -1
  13. package/dist/doctor-contract-api.js +31 -4
  14. package/dist/{dynamic-tools-BmeXjwNZ.js → dynamic-tools-BU9tmlYm.js} +448 -457
  15. package/dist/{effective-mcp-catalog-XXQKgK1U.js → effective-mcp-catalog-DzYBW4h1.js} +2 -2
  16. package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-DHRFXKbS.js} +4 -4
  17. package/dist/{event-projector-usage-B2r5vhWH.js → event-projector-usage-C5mcrGjp.js} +9 -137
  18. package/dist/{harness-BgeB7LnD.js → harness-DXVZ5II5.js} +13 -13
  19. package/dist/harness.js +1 -1
  20. package/dist/index.js +323 -313
  21. package/dist/{isolated-completion-CxTus3vZ.js → isolated-completion-kg9kv4iH.js} +4 -4
  22. package/dist/{launch-args-sXOAg0SX.js → launch-args-RXQwn8zV.js} +7 -1
  23. package/dist/{managed-binary-ZkGodW19.js → managed-binary-4-Vjz5GH.js} +14 -9
  24. package/dist/media-understanding-provider.js +1 -1
  25. package/dist/{model-catalog-DULBcniB.js → model-catalog-CUM68Hkl.js} +11 -11
  26. package/dist/{models-DaWfETQk.js → models-sYnEc0gd.js} +3 -3
  27. package/dist/{native-subagent-monitor-vXYUZH37.js → native-subagent-monitor-CnH147jH.js} +3 -3
  28. package/dist/{node-exec-server.runtime-DirKVZ5h.js → node-exec-server.runtime-CstNHCmC.js} +2 -2
  29. package/dist/{plugin-approval-roundtrip-CCWQGlAI.js → plugin-approval-roundtrip-CNe-Xrjx.js} +29 -3
  30. package/dist/{plugin-marketplace-discovery-BXjIFEiw.js → plugin-marketplace-discovery-CfFlKqDl.js} +6 -6
  31. package/dist/{plugin-metadata-cache-DQQm4gWT.js → plugin-metadata-cache-BFrPhb2c.js} +5 -5
  32. package/dist/provider-capabilities-DW5p4k9w.js +101 -0
  33. package/dist/{rate-limits-BqHEHXQJ.js → rate-limits-CawQJfUS.js} +1 -1
  34. package/dist/{request-BWxweEdK.js → request-DYAI5FQE.js} +18 -6
  35. package/dist/{run-attempt-BVLE4Gbi.js → run-attempt-D1hJO4fX.js} +483 -1865
  36. package/dist/{runtime-artifact-D9pYp4zL.js → runtime-artifact-C3jVimFn.js} +19 -12
  37. package/dist/{session-binding-D0zinCP1.js → session-binding-BHuTCRZQ.js} +8 -10
  38. package/dist/{session-catalog-eMhVm0Ql.js → session-catalog-yyvTWFOw.js} +138 -116
  39. package/dist/{session-cli-B2lyjJA0.js → session-cli-CmFEXMAM.js} +1 -1
  40. package/dist/session-initialization-BeWzjGiR.js +74 -0
  41. package/dist/{session-permission-policy-ScnAyG90.js → session-permission-policy-DeWVTCMj.js} +2 -2
  42. package/dist/{session-retirement-CtUtUTr9.js → session-retirement-BujDjXVF.js} +16 -9
  43. package/dist/{session-upstream-marker-gqrYIRHk.js → session-upstream-marker-C351-5Qw.js} +18 -2
  44. package/dist/{settled-turn-context-Bk3IUwod.js → settled-turn-context-D3SNWtUn.js} +6 -28
  45. package/dist/{settled-turn-finalizer-BXLN9PfJ.js → settled-turn-finalizer-BVJx4yoc.js} +5 -5
  46. package/dist/{shared-client-B1tT5U6r.js → shared-client-DxcfF9KX.js} +2748 -101
  47. package/dist/{side-question-CZ-mCw-t.js → side-question-BTZAII4l.js} +97 -63
  48. package/dist/{thread-lifecycle-CGGKP720.js → thread-lifecycle-DAcEJ_Om.js} +2039 -1487
  49. package/dist/{thread-ownership-RkaoZCmQ.js → thread-ownership-zGokd8i1.js} +10 -9
  50. package/dist/thread-policy-g4KbJPzp.js +54 -0
  51. package/dist/{thread-resume-BFt1-ZDa.js → thread-resume-C7pyVKeW.js} +15 -7
  52. package/dist/{transcript-mirror-1ep4XjzF.js → transcript-mirror-DTUxFWa_.js} +47 -10
  53. package/dist/{transport-stdio-NT_Dpd9V.js → transport-stdio-CyPldczm.js} +3 -1
  54. package/dist/upstream-session-fork-CYlBIGVt.js +966 -0
  55. package/dist/{usage-DUhd58gI.js → usage-Bj-rrzkR.js} +3 -3
  56. package/dist/{web-search-provider.runtime-BEmlE7ov.js → web-search-provider.runtime-D2FWSK4w.js} +3 -3
  57. package/openclaw.plugin.json +0 -30
  58. package/package.json +5 -5
  59. package/dist/protocol-validators-Bg5rpNxk.js +0 -2542
  60. package/dist/session-catalog-home-id-Dt2GiG5o.js +0 -112
  61. package/dist/upstream-session-fork-Dc8BFExw.js +0 -312
@@ -1,7 +1,7 @@
1
- import { T as readCodexPluginConfig, r as resolveCodexAppServerHomeScope } from "./config-CcYL77O6.js";
2
- import { Ht as isJsonObject, Lt as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-B1tT5U6r.js";
3
- import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-DRC3hcjm.js";
4
- import { a as createAttributedCodexAssistantMessage } from "./event-projector-assistant-message-C5-Ds8mA.js";
1
+ import { $t as isJsonObject, Wt as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-DxcfF9KX.js";
2
+ import { E as readCodexPluginConfig, r as resolveCodexAppServerHomeScope } from "./config-BhmfC1s6.js";
3
+ import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-wzJrwKKe.js";
4
+ import { a as createAttributedCodexAssistantMessage } from "./event-projector-assistant-message-DHRFXKbS.js";
5
5
  //#region extensions/codex/src/app-server/isolated-completion.ts
6
6
  const ISOLATED_PASSIVE_ITEM_TYPES = /* @__PURE__ */ new Set(["agentMessage", "reasoning"]);
7
7
  function assertIsolatedCompletionItems(items, prompt) {
@@ -58,6 +58,12 @@ function readCodexArgs(args) {
58
58
  function readCodexAppServerConfigOptions(args) {
59
59
  return readCodexArgs(args).filter(({ name }) => name === "-c" || name === "--config" || name === "-p" || name === "--profile");
60
60
  }
61
+ /** The stdio proxy forwards to an external server; it does not own that runtime. */
62
+ function isCodexAppServerProxyLaunch(args) {
63
+ const tokens = readCodexArgs(args);
64
+ const server = tokens.findLastIndex(({ name }) => name === "app-server");
65
+ return server >= 0 && tokens.slice(server + 1).find(({ name }) => !name.startsWith("-"))?.name === "proxy";
66
+ }
61
67
  /** Keeps Codex overrides in one CLI scope without rewriting raw TOML or wrapper prefixes. */
62
68
  function normalizeCodexAppServerArgs(rawArgs, enforcedOverride) {
63
69
  const tokens = readCodexArgs(rawArgs);
@@ -81,4 +87,4 @@ function normalizeCodexAppServerArgs(rawArgs, enforcedOverride) {
81
87
  return normalized.length === rawArgs.length && normalized.every((arg, index) => arg === rawArgs[index]) ? rawArgs : normalized;
82
88
  }
83
89
  //#endregion
84
- export { readCodexAppServerConfigOptions as n, normalizeCodexAppServerArgs as t };
90
+ export { normalizeCodexAppServerArgs as n, readCodexAppServerConfigOptions as r, isCodexAppServerProxyLaunch as t };
@@ -46,7 +46,7 @@ function resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath(params = {}
46
46
  * Version and package pins for the managed Codex app-server runtime.
47
47
  */
48
48
  /** Exact Codex app-server version shipped by the OpenClaw Codex bridge. */
49
- const CODEX_APP_SERVER_VERSION = "0.151.0";
49
+ const CODEX_APP_SERVER_VERSION = "0.152.1";
50
50
  /** Inclusive runtime compatibility floor for external app-server binaries. */
51
51
  const MIN_SUPPORTED_CODEX_APP_SERVER_VERSION = "0.149.0";
52
52
  /** npm package name for the managed Codex app-server binary. */
@@ -91,12 +91,16 @@ function resolveManagedCodexNativeCommand(command, options = {}) {
91
91
  if (!packageRoot) return;
92
92
  const resolvePackageJson = options.resolvePackageJson ?? resolvePackageJsonFromRoot;
93
93
  const pathExists = options.pathExists ?? existsSync;
94
- for (const packageName of [target.packageName, MANAGED_CODEX_APP_SERVER_PACKAGE]) {
95
- const packageJsonPath = resolvePackageJson(packageName, packageRoot);
96
- if (!packageJsonPath) continue;
97
- const candidate = path.join(path.dirname(packageJsonPath), "vendor", target.triple, "bin", platform === "win32" ? "codex.exe" : "codex");
98
- if (pathExists(candidate)) return candidate;
99
- }
94
+ const packageJsonPath = resolvePackageJson(target.packageName, packageRoot) ?? resolvePackageJson("@openai/codex", packageRoot);
95
+ if (!packageJsonPath) return;
96
+ const candidate = path.join(path.dirname(packageJsonPath), "vendor", target.triple, "bin", platform === "win32" ? "codex.exe" : "codex");
97
+ return pathExists(candidate) ? candidate : void 0;
98
+ }
99
+ /** Recognizes only the official npm entrypoint, not arbitrary configured wrappers. */
100
+ function resolvePackagedCodexNativeCommand(entrypoint) {
101
+ const packageRoot = path.dirname(path.dirname(entrypoint));
102
+ if (path.basename(packageRoot) !== "codex" || path.basename(path.dirname(packageRoot)) !== "@openai" || path.relative(packageRoot, entrypoint) !== path.join("bin", "codex.js")) return;
103
+ return resolveManagedCodexNativeCommand(entrypoint);
100
104
  }
101
105
  /** Returns whether a command is one of the standard macOS desktop app executables. */
102
106
  function isManagedCodexDesktopCommand(command, platform = process.platform) {
@@ -147,7 +151,8 @@ function resolveCodexNativeTarget(platform, arch) {
147
151
  }
148
152
  function resolvePackageJsonFromRoot(packageName, root) {
149
153
  try {
150
- return createRequire(path.join(root, "package.json")).resolve(`${packageName}/package.json`);
154
+ const manifestPath = realpathSync(path.join(root, "package.json"));
155
+ return createRequire(manifestPath).resolve(`${packageName}/package.json`);
151
156
  } catch {
152
157
  return;
153
158
  }
@@ -245,4 +250,4 @@ async function commandPathExists(filePath, platform) {
245
250
  }
246
251
  }
247
252
  //#endregion
248
- export { CODEX_APP_SERVER_VERSION as a, resolveMacOSDesktopCodexAppPathCandidates as c, setManagedCodexPluginRoot as i, resolveMacOSDesktopCodexBundledMarketplaceCandidates as l, resolveManagedCodexAppServerStartOptions as n, MIN_SUPPORTED_CODEX_APP_SERVER_VERSION as o, resolveManagedCodexNativeCommand as r, resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath as s, isManagedCodexDesktopCommand as t, resolveMacOSDesktopCodexComputerUseServiceAppCandidates as u };
253
+ export { setManagedCodexPluginRoot as a, resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath as c, resolveMacOSDesktopCodexComputerUseServiceAppCandidates as d, resolvePackagedCodexNativeCommand as i, resolveMacOSDesktopCodexAppPathCandidates as l, resolveManagedCodexAppServerStartOptions as n, CODEX_APP_SERVER_VERSION as o, resolveManagedCodexNativeCommand as r, MIN_SUPPORTED_CODEX_APP_SERVER_VERSION as s, isManagedCodexDesktopCommand as t, resolveMacOSDesktopCodexBundledMarketplaceCandidates as u };
@@ -1,4 +1,4 @@
1
- import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-DRC3hcjm.js";
1
+ import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-wzJrwKKe.js";
2
2
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { validateJsonSchemaValue } from "openclaw/plugin-sdk/json-schema-runtime";
4
4
  //#region extensions/codex/media-understanding-provider.ts
@@ -1,8 +1,8 @@
1
- import { r as buildCodexRuntimeModelParams } from "./harness-BgeB7LnD.js";
2
- import { T as readCodexPluginConfig, i as resolveCodexAppServerRuntimeOptions } from "./config-CcYL77O6.js";
3
- import { Ht as isJsonObject, r as captureSharedCodexAppServerCatalogLifetime } from "./shared-client-B1tT5U6r.js";
4
- import { t as listAllCodexAppServerModels } from "./models-DaWfETQk.js";
5
- import { o as withCodexAppServerJsonClient } from "./request-BWxweEdK.js";
1
+ import { r as buildCodexRuntimeModelParams } from "./harness-DXVZ5II5.js";
2
+ import { $t as isJsonObject, r as captureSharedCodexAppServerCatalogLifetime } from "./shared-client-DxcfF9KX.js";
3
+ import { E as readCodexPluginConfig, i as resolveCodexAppServerRuntimeOptions } from "./config-BhmfC1s6.js";
4
+ import { t as listAllCodexAppServerModels } from "./models-sYnEc0gd.js";
5
+ import { o as withCodexAppServerJsonClient } from "./request-DYAI5FQE.js";
6
6
  //#region extensions/codex/src/app-server/model-catalog.ts
7
7
  const DEFAULT_MODEL_DISCOVERY_TIMEOUT_MS = 2500;
8
8
  const INPUT_TYPES = /* @__PURE__ */ new Set([
@@ -73,20 +73,20 @@ function createCodexAppServerModelCatalog(runtime) {
73
73
  timeoutMs
74
74
  }, async (request, client) => {
75
75
  const isCurrent = captureSharedCodexAppServerCatalogLifetime(client);
76
- const listed = await listAllCodexAppServerModels({
76
+ const models = (await listAllCodexAppServerModels({
77
77
  request,
78
- limit: 100
79
- });
78
+ limit: 100,
79
+ includeHidden: true
80
+ })).models.filter((model) => !model.hidden || params.configuredModelRefs?.some((ref) => ref.provider === "openai" && ref.model === model.id));
80
81
  const account = await request({
81
82
  method: "account/read",
82
83
  requestParams: { refreshToken: false }
83
84
  });
84
85
  const observedType = isJsonObject(account.account) ? account.account.type : void 0;
85
- const accountType = account.requiresOpenaiAuth === true ? observedType === "apiKey" || observedType === "chatgpt" ? observedType : void 0 : void 0;
86
86
  return {
87
- models: listed.models,
87
+ models,
88
88
  isCurrent,
89
- accountType
89
+ accountType: account.requiresOpenaiAuth === true ? observedType === "apiKey" || observedType === "chatgpt" ? observedType : void 0 : void 0
90
90
  };
91
91
  });
92
92
  if (disposed || observations.get(key) !== observation || !result.isCurrent()) return [];
@@ -1,4 +1,4 @@
1
- import { n as assertCodexModelListResponse } from "./protocol-validators-Bg5rpNxk.js";
1
+ import { Y as assertCodexModelListResponse } from "./shared-client-DxcfF9KX.js";
2
2
  import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  //#region extensions/codex/src/app-server/models.ts
4
4
  /**
@@ -37,8 +37,8 @@ async function withCodexAppServerModelRequest(options, run) {
37
37
  if (options.request) return await run(options.request);
38
38
  const timeoutMs = options.timeoutMs ?? 2500;
39
39
  const useSharedClient = options.sharedClient !== false;
40
- const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./shared-client-B1tT5U6r.js").then((n) => n.x);
41
- const { requestCodexAppServerClientJson } = await import("./request-BWxweEdK.js").then((n) => n.a);
40
+ const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./shared-client-DxcfF9KX.js").then((n) => n.x);
41
+ const { requestCodexAppServerClientJson } = await import("./request-DYAI5FQE.js").then((n) => n.a);
42
42
  const client = await (useSharedClient ? getLeasedSharedCodexAppServerClient : createIsolatedCodexAppServerClient)({
43
43
  startOptions: options.startOptions,
44
44
  timeoutMs,
@@ -1,8 +1,8 @@
1
- import { Ct as retainCodexAppServerLiveThread, Ht as isJsonObject, St as releaseCodexAppServerLiveThread, ht as claimCodexAppServerLiveThread } from "./shared-client-B1tT5U6r.js";
2
- import { A as shouldRecordNativeToolTranscript, C as isNonSuccessItemStatus, D as itemStatus, E as itemName, F as readHookOutputEntries, I as readItem, N as normalizeOptionalString$1, O as itemTitle, R as readNonEmptyString, S as isMutatingNativeToolItem, T as itemKind, V as readNullableString$1, b as auditNativeToolTerminalStatus, j as shouldSynthesizeToolProgressForItem, w as isSideEffectingNativeToolItem, z as readNonEmptyStringArray } from "./attempt-client-cleanup-CpVfwctT.js";
1
+ import { $t as isJsonObject, At as retainCodexAppServerLiveThread, kt as releaseCodexAppServerLiveThread, xt as claimCodexAppServerLiveThread } from "./shared-client-DxcfF9KX.js";
2
+ import { A as shouldRecordNativeToolTranscript, C as isSideEffectingNativeToolItem, D as itemTitle, E as itemStatus, F as readHookOutputEntries, I as readItem, N as normalizeOptionalString$1, R as readNonEmptyString, S as isNonSuccessItemStatus, T as itemName, V as readNullableString$1, j as shouldSynthesizeToolProgressForItem, w as itemKind, x as isMutatingNativeToolItem, y as auditNativeToolTerminalStatus, z as readNonEmptyStringArray } from "./attempt-client-cleanup-DYHcRQAa.js";
3
3
  import { t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
4
4
  import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-B_2mnqhb.js";
5
- import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-CCWQGlAI.js";
5
+ import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-CNe-Xrjx.js";
6
6
  import { n as readCodexMirroredSessionHistoryMessages } from "./session-history-C5J1AKzG.js";
7
7
  import { asFiniteNumber, asNonArrayRecord, normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import path from "node:path";
@@ -1,5 +1,5 @@
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-NT_Dpd9V.js";
1
+ import { n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-4-Vjz5GH.js";
2
+ import { i as closeCodexAppServerTransportAndWait, t as createStdioTransport } from "./transport-stdio-CyPldczm.js";
3
3
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { mkdir } from "node:fs/promises";
5
5
  import path from "node:path";
@@ -1,10 +1,10 @@
1
- import { F as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-B1tT5U6r.js";
1
+ import { N as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-DxcfF9KX.js";
2
2
  import { isApprovalNotFoundError, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
3
3
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
4
4
  //#region extensions/codex/src/app-server/plugin-approval-roundtrip.ts
5
5
  const DEFAULT_CODEX_APPROVAL_TIMEOUT_MS = 12e4;
6
6
  const MAX_PLUGIN_APPROVAL_TITLE_LENGTH = 80;
7
- const MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH = 256;
7
+ const MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH = 512;
8
8
  const ANSI_OSC_SEQUENCE_RE = new RegExp(String.raw`(?:\u001b]|\u009d)[^\u001b\u009c\u0007]*(?:\u0007|\u001b\\|\u009c)`, "g");
9
9
  const ANSI_CONTROL_SEQUENCE_RE = new RegExp(String.raw`(?:\u001b\[[0-?]*[ -/]*[@-~]|\u009b[0-?]*[ -/]*[@-~]|\u001b[@-Z\\-_])`, "g");
10
10
  const CONTROL_CHARACTER_RE = new RegExp(String.raw`[\u0000-\u001f\u007f-\u009f]+`, "g");
@@ -29,6 +29,10 @@ async function requestPluginApproval(params) {
29
29
  severity: params.severity,
30
30
  toolName: params.toolName,
31
31
  toolCallId: params.toolCallId,
32
+ ...params.mcpTool ? {
33
+ mcpTool: params.mcpTool,
34
+ isMcpToolApprovalActive: params.isMcpToolApprovalActive
35
+ } : {},
32
36
  timeoutMs,
33
37
  transportTimeoutMs: resolveCodexGatewayTimeoutWithGraceMs(timeoutMs),
34
38
  ...params.allowedDecisions ? { allowedDecisions: params.allowedDecisions } : {}
@@ -82,6 +86,28 @@ function mapExecDecisionToOutcome(decision) {
82
86
  default: return "unavailable";
83
87
  }
84
88
  }
89
+ /** Runs one complete host approval request and maps transport failures to a closed outcome. */
90
+ async function requestPluginApprovalOutcome(params) {
91
+ try {
92
+ const requestResult = await requestPluginApproval({
93
+ ...params,
94
+ severity: "warning"
95
+ });
96
+ const approvalId = requestResult?.id;
97
+ if (!approvalId) return "unavailable";
98
+ const approvalResult = approvalRequestExplicitlyUnavailable(requestResult) ? void 0 : await waitForPluginApprovalDecision({
99
+ hostCapabilities: params.hostCapabilities,
100
+ approvalId,
101
+ signal: params.signal
102
+ });
103
+ if (params.signal?.aborted) return "cancelled";
104
+ if (approvalResult?.terminalReason === "timeout") return "timed-out";
105
+ const decision = approvalResult?.decision;
106
+ return mapExecDecisionToOutcome(decision === "allow-always" && params.allowedDecisions?.includes("allow-always") === false ? "allow-once" : decision);
107
+ } catch {
108
+ return params.signal?.aborted ? "cancelled" : "denied";
109
+ }
110
+ }
85
111
  function truncateCodexApprovalDisplayText(value, maxLength) {
86
112
  return value.length <= maxLength ? value : `${truncateUtf16Safe(value, maxLength - 3)}...`;
87
113
  }
@@ -93,4 +119,4 @@ function sanitizeCodexApprovalVisibleText(value, options = {}) {
93
119
  return (options.stripDanglingTerminalSequence ? stripDanglingCodexApprovalTerminalSequence(terminalSafe) : terminalSafe).replace(INVISIBLE_FORMATTING_CONTROL_RE, " ").replace(CONTROL_CHARACTER_RE, " ").replace(/\s+/g, " ").trim();
94
120
  }
95
121
  //#endregion
96
- 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 };
122
+ export { requestPluginApprovalOutcome as a, truncateCodexApprovalDisplayText as c, requestPluginApproval as i, waitForPluginApprovalDecision as l, codexApprovalTimeoutText as n, sanitizeCodexApprovalVisibleText as o, mapExecDecisionToOutcome as r, stripDanglingCodexApprovalTerminalSequence as s, approvalRequestExplicitlyUnavailable as t };
@@ -1,9 +1,9 @@
1
- import { k as isCodexFastServiceTier } from "./config-CcYL77O6.js";
2
- import { c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-B1tT5U6r.js";
3
- import { o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-D0zinCP1.js";
4
- import { E as resolveCodexAppServerRequestModelSelection, O as resolveCodexBindingModelProviderFallback } from "./thread-lifecycle-CGGKP720.js";
5
- import { r as formatCodexDisplayText } from "./command-formatters--UToCokS.js";
6
- import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-CF7BmrDk.js";
1
+ import { c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-DxcfF9KX.js";
2
+ import { A as isCodexFastServiceTier } from "./config-BhmfC1s6.js";
3
+ import { o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-BHuTCRZQ.js";
4
+ import { E as resolveCodexAppServerRequestModelSelection, O as resolveCodexBindingModelProviderFallback } from "./thread-lifecycle-DAcEJ_Om.js";
5
+ import { a as formatCodexDisplayText } from "./command-formatters-CLHhEB1Q.js";
6
+ import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-E6uDsPlx.js";
7
7
  import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
9
9
  import { getSessionEntry, patchSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
@@ -1,8 +1,8 @@
1
- import { P as resolveCodexAppServerHomeDir, i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig } from "./config-CcYL77O6.js";
2
- import { At as reconcileCodexComputerUseStartArtifacts, G as isCodexAppServerConnectionClosedError, K as isCodexAppServerIndeterminateRequestCancellationError, O as acquireCodexNativeConfigFence, S as waitForCodexAppServerClientDesktopGenerationDrain, Ut as resolveCodexManagedBundledMarketplacePath, Wt as assertNotSymlink, c as getLeasedSharedCodexAppServerClient, d as readCodexAppServerClientDesktopGeneration, g as resolveCodexNativeConfigFenceKey, h as releaseLeasedSharedCodexAppServerClient, p as readCodexAppServerClientProcessIdentity, q as isCodexAppServerIndeterminateTransportError, t as assertCodexAppServerClientStartSelectionCurrent, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-B1tT5U6r.js";
3
- import { l as resolveMacOSDesktopCodexBundledMarketplaceCandidates, s as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, t as isManagedCodexDesktopCommand } from "./managed-binary-ZkGodW19.js";
4
- import { i as requestCodexAppServerJson } from "./request-BWxweEdK.js";
5
- import { n as describeControlFailure } from "./capabilities-D6m_TdVy.js";
1
+ import { B as isCodexAppServerIndeterminateRequestCancellationError, D as acquireCodexNativeConfigFence, Gt as resolveCodexManagedBundledMarketplacePath, Kt as assertNotSymlink, Lt as reconcileCodexComputerUseStartArtifacts, S as waitForCodexAppServerClientDesktopGenerationDrain, V as isCodexAppServerIndeterminateTransportError, c as getLeasedSharedCodexAppServerClient, d as readCodexAppServerClientDesktopGeneration, g as resolveCodexNativeConfigFenceKey, h as releaseLeasedSharedCodexAppServerClient, p as readCodexAppServerClientProcessIdentity, t as assertCodexAppServerClientStartSelectionCurrent, u as isCodexAppServerStartSelectionChangedError, z as isCodexAppServerConnectionClosedError } from "./shared-client-DxcfF9KX.js";
2
+ import { F as resolveCodexAppServerHomeDir, i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig } from "./config-BhmfC1s6.js";
3
+ import { c as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, t as isManagedCodexDesktopCommand, u as resolveMacOSDesktopCodexBundledMarketplaceCandidates } from "./managed-binary-4-Vjz5GH.js";
4
+ import { i as requestCodexAppServerJson } from "./request-DYAI5FQE.js";
5
+ import { n as describeControlFailure } from "./capabilities-dIjNVCYH.js";
6
6
  import fs from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import { existsSync } from "node:fs";
@@ -0,0 +1,101 @@
1
+ import { h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-DxcfF9KX.js";
2
+ import { ut as normalizeCodexDynamicToolName } from "./thread-lifecycle-DAcEJ_Om.js";
3
+ import { pinExecToolTarget } from "openclaw/plugin-sdk/codex-mcp-projection";
4
+ import { loadNodeExecAvailability } from "openclaw/plugin-sdk/node-selection-runtime";
5
+ //#region extensions/codex/src/app-server/shell-dynamic-tools.ts
6
+ const CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME = "node_exec";
7
+ const CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME = "gateway_exec";
8
+ const CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME = "gateway_process";
9
+ const PROCESS_FOLLOWUP_TEXT = "Use process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.";
10
+ /** Returns true when plugin config explicitly removes any named dynamic tool. */
11
+ function isCodexDynamicToolExcluded(config, names) {
12
+ const normalizedNames = new Set(names.map((name) => normalizeCodexDynamicToolName(name)));
13
+ return (config.codexDynamicToolsExclude ?? []).some((name) => normalizedNames.has(normalizeCodexDynamicToolName(name)));
14
+ }
15
+ async function createNodeExecAliasDynamicTool(execTool, node, discoverySignal, availabilityRef) {
16
+ const pinnedNode = node?.trim();
17
+ const availability = await (availabilityRef ? availabilityRef.current ??= loadNodeExecAvailability(discoverySignal) : loadNodeExecAvailability(discoverySignal));
18
+ discoverySignal?.throwIfAborted();
19
+ if (!availability.isAvailable(pinnedNode)) return;
20
+ const pinnedTool = pinExecToolTarget(execTool, {
21
+ host: "node",
22
+ ...pinnedNode ? { node: pinnedNode } : {}
23
+ });
24
+ const execute = async (toolCallId, args, signal, onUpdate) => {
25
+ const result = await pinnedTool.execute(toolCallId, args, signal, onUpdate);
26
+ return {
27
+ ...result,
28
+ content: result.content.map((item) => item.type === "text" ? Object.assign({}, item, { text: item.text.replace(PROCESS_FOLLOWUP_TEXT, "Remote-node background follow-up is unavailable. Wait for the command to complete.") }) : item)
29
+ };
30
+ };
31
+ return {
32
+ ...pinnedTool,
33
+ name: CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME,
34
+ description: pinnedNode ? "Run a shell command to completion on the OpenClaw configured remote node for this session. This tool always uses OpenClaw host=node internally and follows the existing node exec approval and allowlist policy. Remote-node background follow-up is unavailable. Use Codex's native shell for local app-server work when it is available." : "Run a shell command to completion on an OpenClaw remote node. The sole connected node that can execute commands is selected automatically; select by name or id when several can. This tool always uses OpenClaw host=node internally and follows the existing node exec approval and allowlist policy. Remote-node background follow-up is unavailable. Use Codex's native shell for local app-server work when it is available.",
35
+ execute
36
+ };
37
+ }
38
+ function createGatewayExecProjection(createProjection, execTool, params) {
39
+ return createProjection(execTool, {
40
+ kind: "exec",
41
+ name: CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME,
42
+ description: "Run a shell command through OpenClaw on the Gateway host for OpenClaw-managed Gateway environment access, including Secret Store agent-readable environment values and protected egress sentinels. Native Codex shell remains preferred for ordinary local work. This tool always uses OpenClaw host=gateway internally and follows Gateway exec approval and allowlist policy.",
43
+ followupText: params.processAliasAvailable ? "Use gateway_process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up." : "Background session follow-up is unavailable because gateway_process is not exposed. Rerun without background=true and set yieldMs high enough to wait for completion.",
44
+ ...params.ask ? { ask: params.ask } : {}
45
+ });
46
+ }
47
+ function createGatewayProcessProjection(createProjection, processTool) {
48
+ return createProjection(processTool, {
49
+ kind: "process",
50
+ name: CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME,
51
+ description: "Manage background shell sessions in the existing per-session OpenClaw process scope: list, poll, log, write, send-keys, submit, paste, kill, clear, or remove. Use for gateway_exec follow-up; use native Codex shell session handling for ordinary local work."
52
+ });
53
+ }
54
+ //#endregion
55
+ //#region extensions/codex/src/app-server/provider-capabilities.ts
56
+ function resolveOverriddenProviderWebSearchSupport(modelProviderOverride) {
57
+ const provider = modelProviderOverride?.trim().toLowerCase();
58
+ if (!provider) return;
59
+ return provider === "openai" ? "supported" : "unsupported";
60
+ }
61
+ async function readConfiguredProviderWebSearchSupport(params) {
62
+ return (await params.client.request("modelProvider/capabilities/read", {}, {
63
+ timeoutMs: params.timeoutMs,
64
+ signal: params.signal
65
+ })).webSearch ? "supported" : "unsupported";
66
+ }
67
+ async function resolveCodexProviderWebSearchSupportForClient(params) {
68
+ const overrideSupport = resolveOverriddenProviderWebSearchSupport(params.modelProviderOverride);
69
+ if (overrideSupport) return overrideSupport;
70
+ try {
71
+ return await readConfiguredProviderWebSearchSupport(params);
72
+ } catch {
73
+ return "unknown";
74
+ }
75
+ }
76
+ async function resolveCodexProviderWebSearchSupport(params) {
77
+ const overrideSupport = resolveOverriddenProviderWebSearchSupport(params.modelProviderOverride);
78
+ if (overrideSupport) return overrideSupport;
79
+ let client;
80
+ try {
81
+ client = await params.clientFactory({
82
+ startOptions: params.appServer.start,
83
+ ...params.preparedAuth ? { preparedAuth: params.preparedAuth } : { authProfileId: params.authProfileId },
84
+ agentDir: params.agentDir,
85
+ config: params.config,
86
+ timeoutMs: params.appServer.requestTimeoutMs
87
+ });
88
+ return await resolveCodexProviderWebSearchSupportForClient({
89
+ client,
90
+ timeoutMs: params.appServer.requestTimeoutMs,
91
+ modelProviderOverride: params.modelProviderOverride,
92
+ signal: params.signal
93
+ });
94
+ } catch {
95
+ return "unknown";
96
+ } finally {
97
+ if (client) releaseLeasedSharedCodexAppServerClient(client);
98
+ }
99
+ }
100
+ //#endregion
101
+ export { CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME as a, createNodeExecAliasDynamicTool as c, CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME as i, isCodexDynamicToolExcluded as l, resolveCodexProviderWebSearchSupportForClient as n, createGatewayExecProjection as o, CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME as r, createGatewayProcessProjection as s, resolveCodexProviderWebSearchSupport as t };
@@ -1,4 +1,4 @@
1
- import { Ht as isJsonObject } from "./shared-client-B1tT5U6r.js";
1
+ import { $t as isJsonObject } from "./shared-client-DxcfF9KX.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,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { C as isCodexRemoteExecPlacementSandbox } from "./config-CcYL77O6.js";
3
- import { Et as withTimeout, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, s as createIsolatedCodexAppServerClient, u as isCodexAppServerStartSelectionChangedError, y as retireSharedCodexAppServerClientIfCurrent } from "./shared-client-B1tT5U6r.js";
2
+ import { Nt as withTimeout, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, s as createIsolatedCodexAppServerClient, u as isCodexAppServerStartSelectionChangedError, y as retireSharedCodexAppServerClientIfCurrent } from "./shared-client-DxcfF9KX.js";
3
+ import { w as isCodexRemoteExecPlacementSandbox } from "./config-BhmfC1s6.js";
4
4
  import { resolveAgentConfig, tryResolveDefaultAgentId } from "openclaw/plugin-sdk/agent-scope-runtime";
5
5
  import { getSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
6
6
  import { normalizeAgentId, parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
@@ -300,7 +300,11 @@ async function requestCodexAppServerClientJson(params) {
300
300
  });
301
301
  if (sandboxBlock) throw new Error(sandboxBlock);
302
302
  const timeoutMs = params.timeoutMs ?? 6e4;
303
- return await withTimeout(params.client.request(params.method, params.requestParams, { timeoutMs }), timeoutMs, `codex app-server ${params.method} timed out`);
303
+ return await withTimeout(params.client.request(params.method, params.requestParams, {
304
+ timeoutMs,
305
+ signal: params.signal,
306
+ ...params.assertCurrent ? { assertCurrent: () => assertRequestOwnerCurrent(params.assertCurrent) } : {}
307
+ }), timeoutMs, `codex app-server ${params.method} timed out`);
304
308
  }
305
309
  async function requestCodexAppServerJson(params) {
306
310
  const sandboxBlock = resolveCodexAppServerDirectSandboxBypassBlock({
@@ -319,13 +323,20 @@ async function requestCodexAppServerJson(params) {
319
323
  requestParams: params.requestParams
320
324
  }));
321
325
  }
322
- /** A scoped guard rejected the request before it reached the physical client. */
326
+ /** A scoped guard rejected the request before a physical write. */
323
327
  var CodexAppServerScopedRequestRejectedError = class extends Error {
324
- constructor(message) {
325
- super(message);
328
+ constructor(message, options) {
329
+ super(message, options);
326
330
  this.name = "CodexAppServerScopedRequestRejectedError";
327
331
  }
328
332
  };
333
+ function assertRequestOwnerCurrent(assertCurrent) {
334
+ try {
335
+ assertCurrent?.();
336
+ } catch (cause) {
337
+ throw new CodexAppServerScopedRequestRejectedError(cause instanceof Error ? cause.message : String(cause), { cause });
338
+ }
339
+ }
329
340
  const CODEX_USAGE_ISOLATED_SHUTDOWN = {
330
341
  forceKillDelayMs: 200,
331
342
  exitTimeoutMs: 300
@@ -417,6 +428,7 @@ async function withCodexAppServerJsonClient(params, run) {
417
428
  const assertCurrent = () => {
418
429
  throwIfAbandoned();
419
430
  if (!scopeActive) throw new CodexAppServerScopedRequestRejectedError("Codex app-server request scope is closed");
431
+ assertRequestOwnerCurrent(params.assertCurrent);
420
432
  };
421
433
  try {
422
434
  assertCurrent();