@openclaw/codex 2026.5.12-beta.1 → 2026.5.12-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.
@@ -1,5 +1,5 @@
1
1
  //#region extensions/codex/src/app-server/client-factory.ts
2
- const defaultCodexAppServerClientFactory = (startOptions, authProfileId, agentDir, config) => import("./shared-client-2q_uX6dM.js").then((n) => n.i).then(({ getSharedCodexAppServerClient }) => getSharedCodexAppServerClient({
2
+ const defaultCodexAppServerClientFactory = (startOptions, authProfileId, agentDir, config) => import("./shared-client-DSSqFqHM.js").then((n) => n.i).then(({ getSharedCodexAppServerClient }) => getSharedCodexAppServerClient({
3
3
  startOptions,
4
4
  authProfileId,
5
5
  agentDir,
@@ -1,12 +1,12 @@
1
1
  import { i as isCodexFastServiceTier, s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.js";
2
- import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-CupVdk6Y.js";
2
+ import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-DqfYggBz.js";
3
3
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
4
- import { n as CODEX_CONTROL_METHODS, r as describeControlFailure, t as requestCodexAppServerJson } from "./request-dv8xEOeW.js";
4
+ import { n as CODEX_CONTROL_METHODS, r as describeControlFailure, t as requestCodexAppServerJson } from "./request-DSOsuqmX.js";
5
5
  import { a as formatComputerUseStatus, c as formatThreads, i as formatCodexStatus, l as readString$1, n as formatAccount, o as formatList, p as summarizeCodexAccountUsage, r as formatCodexDisplayText, s as formatModels, t as buildHelp } from "./command-formatters-Ttwc_kgX.js";
6
6
  import { i as readCodexAppServerBinding, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-CDN-Pf8K.js";
7
- import { a as parseCodexFastModeArg, c as setCodexConversationFastMode, d as steerCodexConversationTurn, f as stopCodexConversationTurn, i as formatPermissionsMode, l as setCodexConversationModel, m as resolveCodexDefaultWorkspaceDir, o as parseCodexPermissionsModeArg, p as readCodexConversationBindingData, r as startCodexConversationThread, s as readCodexConversationActiveTurn, u as setCodexConversationPermissions } from "./conversation-binding-BSqeZQnB.js";
8
- import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-DbjvOEWr.js";
9
- import { n as rememberCodexRateLimits } from "./rate-limit-cache-dvhq-4pi.js";
7
+ import { a as parseCodexFastModeArg, c as setCodexConversationFastMode, d as steerCodexConversationTurn, f as stopCodexConversationTurn, i as formatPermissionsMode, l as setCodexConversationModel, m as resolveCodexDefaultWorkspaceDir, o as parseCodexPermissionsModeArg, p as readCodexConversationBindingData, r as startCodexConversationThread, s as readCodexConversationActiveTurn, u as setCodexConversationPermissions } from "./conversation-binding-Dn66MHqg.js";
8
+ import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-Br-1hHIR.js";
9
+ import { n as rememberCodexRateLimits } from "./rate-limit-cache-BFi-50LG.js";
10
10
  import crypto from "node:crypto";
11
11
  import { ensureAuthProfileStore, findNormalizedProviderValue, resolveAuthProfileEligibility, resolveAuthProfileOrder, resolveDefaultAgentDir, resolveProfileUnusableUntilForDisplay } from "openclaw/plugin-sdk/agent-runtime";
12
12
  //#region extensions/codex/src/command-account.ts
@@ -1,7 +1,7 @@
1
1
  import { s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
3
  import { i as readCodexAppServerBinding } from "./session-binding-CDN-Pf8K.js";
4
- import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-B_0hRLx5.js";
4
+ import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-Bw7M3rdW.js";
5
5
  import { embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine, runHarnessContextEngineMaintenance } from "openclaw/plugin-sdk/agent-harness-runtime";
6
6
  //#region extensions/codex/src/app-server/compact.ts
7
7
  const DEFAULT_CODEX_COMPACTION_WAIT_TIMEOUT_MS = 300 * 1e3;
@@ -1,5 +1,5 @@
1
1
  import { c as resolveCodexComputerUseConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.js";
2
- import { r as describeControlFailure, t as requestCodexAppServerJson } from "./request-dv8xEOeW.js";
2
+ import { r as describeControlFailure, t as requestCodexAppServerJson } from "./request-DSOsuqmX.js";
3
3
  import { existsSync } from "node:fs";
4
4
  //#region extensions/codex/src/app-server/computer-use.ts
5
5
  var CodexComputerUseSetupError = class extends Error {
@@ -1,8 +1,8 @@
1
1
  import { i as isCodexFastServiceTier, r as codexSandboxPolicyForTurn, s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
- import { n as CODEX_CONTROL_METHODS } from "./request-dv8xEOeW.js";
3
+ import { n as CODEX_CONTROL_METHODS } from "./request-DSOsuqmX.js";
4
4
  import { r as formatCodexDisplayText } from "./command-formatters-Ttwc_kgX.js";
5
- import { l as resolveCodexAppServerAuthProfileIdForAgent, r as getSharedCodexAppServerClient } from "./shared-client-2q_uX6dM.js";
5
+ import { l as resolveCodexAppServerAuthProfileIdForAgent, r as getSharedCodexAppServerClient } from "./shared-client-DSSqFqHM.js";
6
6
  import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, r as normalizeCodexAppServerBindingModelProvider, t as clearCodexAppServerBinding } from "./session-binding-CDN-Pf8K.js";
7
7
  import { formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
8
8
  import path from "node:path";
package/dist/harness.js CHANGED
@@ -18,15 +18,15 @@ function createCodexAppServerAgentHarness(options) {
18
18
  };
19
19
  },
20
20
  runAttempt: async (params) => {
21
- const { runCodexAppServerAttempt } = await import("./run-attempt-DIEWRVGH.js");
21
+ const { runCodexAppServerAttempt } = await import("./run-attempt-y4QDhBHf.js");
22
22
  return runCodexAppServerAttempt(params, { pluginConfig: options?.pluginConfig });
23
23
  },
24
24
  runSideQuestion: async (params) => {
25
- const { runCodexAppServerSideQuestion } = await import("./side-question-oO_-Jet5.js");
25
+ const { runCodexAppServerSideQuestion } = await import("./side-question-BcATx0hX.js");
26
26
  return runCodexAppServerSideQuestion(params, { pluginConfig: options?.pluginConfig });
27
27
  },
28
28
  compact: async (params) => {
29
- const { maybeCompactCodexAppServerSession } = await import("./compact-C5KQFyRe.js");
29
+ const { maybeCompactCodexAppServerSession } = await import("./compact-DfmGNV9J.js");
30
30
  return maybeCompactCodexAppServerSession(params, { pluginConfig: options?.pluginConfig });
31
31
  },
32
32
  reset: async (params) => {
@@ -36,7 +36,7 @@ function createCodexAppServerAgentHarness(options) {
36
36
  }
37
37
  },
38
38
  dispose: async () => {
39
- const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-2q_uX6dM.js").then((n) => n.i);
39
+ const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-DSSqFqHM.js").then((n) => n.i);
40
40
  await clearSharedCodexAppServerClientAndWait();
41
41
  }
42
42
  };
package/dist/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import { createCodexAppServerAgentHarness } from "./harness.js";
2
- import { t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-0rd3LnKg.js";
2
+ import { o as readCodexPluginConfig, s as resolveCodexAppServerRuntimeOptions, t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-0rd3LnKg.js";
3
3
  import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
4
4
  import { buildCodexProvider } from "./provider.js";
5
- import { r as describeControlFailure, t as requestCodexAppServerJson } from "./request-dv8xEOeW.js";
5
+ import { r as describeControlFailure, t as requestCodexAppServerJson } from "./request-DSOsuqmX.js";
6
6
  import { r as formatCodexDisplayText } from "./command-formatters-Ttwc_kgX.js";
7
- import { n as handleCodexConversationInboundClaim, t as handleCodexConversationBindingResolved } from "./conversation-binding-BSqeZQnB.js";
8
- import { i as defaultCodexAppInventoryCache, t as ensureCodexPluginActivation } from "./plugin-activation-lmfBoCiu.js";
7
+ import { l as resolveCodexAppServerAuthProfileIdForAgent, s as resolveCodexAppServerAuthAccountCacheKey, u as resolveCodexAppServerEnvApiKeyCacheKey } from "./shared-client-DSSqFqHM.js";
8
+ import { n as handleCodexConversationInboundClaim, t as handleCodexConversationBindingResolved } from "./conversation-binding-Dn66MHqg.js";
9
+ import { a as defaultCodexAppInventoryCache, n as pluginReadParams, t as ensureCodexPluginActivation } from "./plugin-activation-PXGqUjwY.js";
10
+ import { t as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DjrZp49q.js";
9
11
  import { resolveLivePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
10
12
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
11
13
  import os from "node:os";
@@ -37,7 +39,7 @@ async function handleCodexCommand(ctx, options = {}) {
37
39
  }
38
40
  }
39
41
  async function loadDefaultCodexSubcommandHandler() {
40
- const { handleCodexSubcommand } = await import("./command-handlers-DBtb-11U.js");
42
+ const { handleCodexSubcommand } = await import("./command-handlers-D9CzemFF.js");
41
43
  return handleCodexSubcommand;
42
44
  }
43
45
  //#endregion
@@ -134,47 +136,24 @@ async function discoverPluginDirs(codexHome) {
134
136
  await visit(root, 0);
135
137
  return [...discovered.values()].toSorted((a, b) => a.source.localeCompare(b.source));
136
138
  }
137
- async function discoverInstalledCuratedPlugins(codexHome) {
139
+ async function discoverInstalledCuratedPlugins(codexHome, options = {}) {
140
+ const requestOptions = { startOptions: sourceCodexAppServerStartOptions(codexHome) };
138
141
  try {
139
- const marketplace = (await requestCodexAppServerJson({
142
+ const marketplace = (await requestSourceCodexAppServerJson(requestOptions, {
140
143
  method: "plugin/list",
141
- requestParams: { cwds: [] },
142
- timeoutMs: 6e4,
143
- isolated: true,
144
- startOptions: {
145
- transport: "stdio",
146
- command: "codex",
147
- commandSource: "config",
148
- args: [
149
- "app-server",
150
- "--listen",
151
- "stdio://"
152
- ],
153
- headers: {},
154
- env: {
155
- CODEX_HOME: codexHome,
156
- HOME: path.dirname(codexHome)
157
- }
158
- }
144
+ requestParams: { cwds: [] }
159
145
  })).marketplaces.find((entry) => entry.name === CODEX_PLUGINS_MARKETPLACE_NAME);
160
146
  if (!marketplace) return {
161
147
  plugins: [],
162
148
  error: `Codex marketplace ${CODEX_PLUGINS_MARKETPLACE_NAME} was not found in source plugin inventory.`
163
149
  };
164
- return { plugins: marketplace.plugins.filter((plugin) => plugin.installed).map((plugin) => {
165
- const pluginName = pluginNameFromSummary(plugin);
166
- if (!pluginName) return;
167
- return {
168
- name: plugin.name,
169
- pluginName,
170
- marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
171
- source: `${CODEX_PLUGINS_MARKETPLACE_NAME}/${pluginName}`,
172
- sourceKind: "app-server",
173
- migratable: true,
174
- installed: plugin.installed,
175
- enabled: plugin.enabled
176
- };
177
- }).filter((plugin) => plugin !== void 0).toSorted((a, b) => (a.pluginName ?? a.name).localeCompare(b.pluginName ?? b.name)) };
150
+ const plugins = marketplace.plugins.filter((plugin) => plugin.installed).map((plugin) => buildInstalledPluginSource(plugin)).filter((plugin) => plugin !== void 0);
151
+ return { plugins: (options.evaluatePluginMigrationEligibility === true ? await withPluginMigrationEligibility({
152
+ plugins,
153
+ marketplace: marketplaceRef(marketplace),
154
+ requestOptions,
155
+ verifyPluginApps: options.verifyPluginApps === true
156
+ }) : plugins).toSorted((a, b) => (a.pluginName ?? a.name).localeCompare(b.pluginName ?? b.name)) };
178
157
  } catch (error) {
179
158
  return {
180
159
  plugins: [],
@@ -182,6 +161,239 @@ async function discoverInstalledCuratedPlugins(codexHome) {
182
161
  };
183
162
  }
184
163
  }
164
+ function sourceCodexAppServerStartOptions(codexHome) {
165
+ return {
166
+ transport: "stdio",
167
+ command: "codex",
168
+ commandSource: "config",
169
+ args: [
170
+ "app-server",
171
+ "--listen",
172
+ "stdio://"
173
+ ],
174
+ headers: {},
175
+ env: {
176
+ CODEX_HOME: codexHome,
177
+ HOME: path.dirname(codexHome)
178
+ }
179
+ };
180
+ }
181
+ async function requestSourceCodexAppServerJson(options, params) {
182
+ return await requestCodexAppServerJson({
183
+ method: params.method,
184
+ requestParams: params.requestParams,
185
+ timeoutMs: 6e4,
186
+ startOptions: options.startOptions,
187
+ authProfileId: null,
188
+ isolated: true
189
+ });
190
+ }
191
+ function buildInstalledPluginSource(plugin) {
192
+ const pluginName = pluginNameFromSummary(plugin);
193
+ if (!pluginName) return;
194
+ return {
195
+ name: plugin.name,
196
+ pluginName,
197
+ marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
198
+ source: `${CODEX_PLUGINS_MARKETPLACE_NAME}/${pluginName}`,
199
+ sourceKind: "app-server",
200
+ migratable: true,
201
+ installed: plugin.installed,
202
+ enabled: plugin.enabled
203
+ };
204
+ }
205
+ function marketplaceRef(marketplace) {
206
+ return {
207
+ name: CODEX_PLUGINS_MARKETPLACE_NAME,
208
+ ...marketplace.path ? { path: marketplace.path } : {},
209
+ ...!marketplace.path ? { remoteMarketplaceName: marketplace.name } : {}
210
+ };
211
+ }
212
+ async function withPluginMigrationEligibility(params) {
213
+ const pending = [];
214
+ const evaluated = [];
215
+ for (const plugin of params.plugins) {
216
+ if (plugin.enabled !== true) {
217
+ evaluated.push({
218
+ ...plugin,
219
+ migratable: false,
220
+ migrationBlock: { code: "plugin_disabled" },
221
+ message: `Codex plugin "${plugin.pluginName ?? plugin.name}" is installed in Codex but disabled; enable it in Codex before migrating it to OpenClaw.`
222
+ });
223
+ continue;
224
+ }
225
+ const detail = await readPluginDetail(params.requestOptions, params.marketplace, plugin);
226
+ if (!detail.ok) {
227
+ evaluated.push({
228
+ ...plugin,
229
+ migratable: false,
230
+ migrationBlock: {
231
+ code: "plugin_read_unavailable",
232
+ error: detail.error
233
+ },
234
+ message: `Codex plugin "${plugin.pluginName ?? plugin.name}" detail could not be read: ${detail.error}`
235
+ });
236
+ continue;
237
+ }
238
+ if (detail.detail.apps.length === 0) {
239
+ evaluated.push({
240
+ ...plugin,
241
+ migratable: true
242
+ });
243
+ continue;
244
+ }
245
+ const apps = detail.detail.apps.map(sourcePluginAppFact).toSorted((left, right) => left.id.localeCompare(right.id));
246
+ pending.push({
247
+ plugin,
248
+ apps
249
+ });
250
+ }
251
+ if (pending.length === 0) return evaluated;
252
+ let sourceAccount;
253
+ try {
254
+ sourceAccount = await readSourceCodexAccount(params.requestOptions);
255
+ } catch (error) {
256
+ if (!params.verifyPluginApps) {
257
+ const message = error instanceof Error ? error.message : String(error);
258
+ for (const { plugin, apps } of pending) evaluated.push({
259
+ ...plugin,
260
+ migratable: false,
261
+ migrationBlock: {
262
+ code: "codex_account_unavailable",
263
+ apps,
264
+ error: message
265
+ },
266
+ message: `Codex plugin "${plugin.pluginName ?? plugin.name}" owns apps, but the source Codex app-server account could not be read: ${message}`
267
+ });
268
+ return evaluated;
269
+ }
270
+ }
271
+ if (sourceAccount && sourceAccount !== "chatgpt") {
272
+ for (const { plugin, apps } of pending) evaluated.push({
273
+ ...plugin,
274
+ migratable: false,
275
+ migrationBlock: {
276
+ code: "codex_subscription_required",
277
+ apps
278
+ },
279
+ message: codexSubscriptionRequiredMessage(plugin)
280
+ });
281
+ return evaluated;
282
+ }
283
+ if (!params.verifyPluginApps) {
284
+ for (const { plugin, apps } of pending) evaluated.push({
285
+ ...plugin,
286
+ apps,
287
+ migratable: true
288
+ });
289
+ return evaluated;
290
+ }
291
+ const snapshot = await refreshSourceAppInventory(params.requestOptions).catch((error) => {
292
+ const message = error instanceof Error ? error.message : String(error);
293
+ for (const { plugin, apps } of pending) evaluated.push({
294
+ ...plugin,
295
+ migratable: false,
296
+ migrationBlock: {
297
+ code: "app_inventory_unavailable",
298
+ apps,
299
+ error: message
300
+ },
301
+ message: `Codex plugin "${plugin.pluginName ?? plugin.name}" owns apps, but source app inventory could not be read: ${message}`
302
+ });
303
+ });
304
+ if (!snapshot) return evaluated;
305
+ const appInfoById = new Map(snapshot.apps.map((app) => [app.id, app]));
306
+ for (const { plugin, apps: declaredApps } of pending) {
307
+ const apps = declaredApps.map((app) => sourcePluginAppFactWithInventory(app, appInfoById.get(app.id))).toSorted((left, right) => left.id.localeCompare(right.id));
308
+ const blockCode = migrationBlockCodeForApps(apps);
309
+ if (!blockCode) {
310
+ evaluated.push({
311
+ ...plugin,
312
+ apps,
313
+ migratable: true
314
+ });
315
+ continue;
316
+ }
317
+ evaluated.push({
318
+ ...plugin,
319
+ migratable: false,
320
+ migrationBlock: {
321
+ code: blockCode,
322
+ apps
323
+ },
324
+ message: appInventoryBlockMessage(plugin, apps, blockCode)
325
+ });
326
+ }
327
+ return evaluated;
328
+ }
329
+ async function readSourceCodexAccount(options) {
330
+ const response = await requestSourceCodexAppServerJson(options, {
331
+ method: "account/read",
332
+ requestParams: { refreshToken: false }
333
+ });
334
+ if (!response.account || typeof response.account !== "object" || Array.isArray(response.account)) return "missing";
335
+ return response.account.type === "chatgpt" ? "chatgpt" : "non_chatgpt";
336
+ }
337
+ async function readPluginDetail(options, marketplace, plugin) {
338
+ try {
339
+ return {
340
+ ok: true,
341
+ detail: (await requestSourceCodexAppServerJson(options, {
342
+ method: "plugin/read",
343
+ requestParams: pluginReadParams(marketplace, plugin.pluginName ?? plugin.name)
344
+ })).plugin
345
+ };
346
+ } catch (error) {
347
+ return {
348
+ ok: false,
349
+ error: error instanceof Error ? error.message : String(error)
350
+ };
351
+ }
352
+ }
353
+ async function refreshSourceAppInventory(options) {
354
+ const key = buildCodexPluginAppCacheKey({ appServer: { start: options.startOptions } });
355
+ const request = async (method, requestParams) => await requestSourceCodexAppServerJson(options, {
356
+ method,
357
+ requestParams
358
+ });
359
+ return await defaultCodexAppInventoryCache.refreshNow({
360
+ key,
361
+ request,
362
+ forceRefetch: true
363
+ });
364
+ }
365
+ function sourcePluginAppFact(app) {
366
+ return {
367
+ id: app.id,
368
+ name: app.name,
369
+ needsAuth: app.needsAuth
370
+ };
371
+ }
372
+ function sourcePluginAppFactWithInventory(app, info) {
373
+ if (!info) return app;
374
+ return {
375
+ ...app,
376
+ isAccessible: info.isAccessible,
377
+ isEnabled: info.isEnabled
378
+ };
379
+ }
380
+ function migrationBlockCodeForApps(apps) {
381
+ if (apps.some((app) => app.isAccessible === false)) return "app_inaccessible";
382
+ if (apps.some((app) => app.isEnabled === false)) return "app_disabled";
383
+ if (apps.some((app) => app.isAccessible === void 0 || app.isEnabled === void 0)) return "app_missing";
384
+ }
385
+ function appInventoryBlockMessage(plugin, apps, code) {
386
+ const status = code === "app_inaccessible" ? "inaccessible" : code === "app_disabled" ? "disabled" : "missing";
387
+ const blocking = apps.find((app) => code === "app_inaccessible" ? app.isAccessible === false : code === "app_disabled" ? app.isEnabled === false : app.isAccessible === void 0 || app.isEnabled === void 0) ?? apps[0];
388
+ const appLabel = blocking ? ` app "${blocking.name}"` : " an owned app";
389
+ return `Codex plugin "${plugin.pluginName ?? plugin.name}" owns${appLabel} but the source app inventory reports it is ${status}; authenticate or enable the app in Codex before migrating it to OpenClaw.`;
390
+ }
391
+ function codexPluginMigrationSubscriptionWarning() {
392
+ return "Codex app-backed plugin migration requires the Codex app-server source account to be logged in with a ChatGPT subscription account. Log in to the Codex app with subscription auth; OpenClaw auth or API-key auth does not satisfy Codex app connector access.";
393
+ }
394
+ function codexSubscriptionRequiredMessage(plugin) {
395
+ return `Codex plugin "${plugin.pluginName ?? plugin.name}" owns apps, but ${codexPluginMigrationSubscriptionWarning()}`;
396
+ }
185
397
  function pluginNameFromSummary(summary) {
186
398
  const candidates = [summary.id, summary.name];
187
399
  for (const candidate of candidates) {
@@ -191,8 +403,9 @@ function pluginNameFromSummary(summary) {
191
403
  if (normalized) return normalized;
192
404
  }
193
405
  }
194
- async function discoverCodexSource(input) {
195
- const codexHome = resolveHomePath(input?.trim() || defaultCodexHome());
406
+ async function discoverCodexSource(inputOrOptions) {
407
+ const options = typeof inputOrOptions === "string" || inputOrOptions === void 0 ? { input: inputOrOptions } : inputOrOptions;
408
+ const codexHome = resolveHomePath(options.input?.trim() || defaultCodexHome());
196
409
  const codexSkillsDir = path.join(codexHome, "skills");
197
410
  const agentsSkillsDir = personalAgentsSkillsDir();
198
411
  const configPath = path.join(codexHome, "config.toml");
@@ -206,7 +419,7 @@ async function discoverCodexSource(input) {
206
419
  root: agentsSkillsDir,
207
420
  sourceLabel: "personal AgentSkill"
208
421
  });
209
- const sourcePluginDiscovery = await discoverInstalledCuratedPlugins(codexHome);
422
+ const sourcePluginDiscovery = await discoverInstalledCuratedPlugins(codexHome, options);
210
423
  const sourcePluginNames = new Set(sourcePluginDiscovery.plugins.flatMap((plugin) => plugin.pluginName ? [plugin.pluginName] : []));
211
424
  const cachedPlugins = (await discoverPluginDirs(codexHome)).filter((plugin) => {
212
425
  const normalizedName = sanitizePluginName(plugin.name);
@@ -283,6 +496,7 @@ const CODEX_PLUGIN_NATIVE_CONFIG_PATH = [
283
496
  "codexPlugins"
284
497
  ];
285
498
  const MIGRATION_REASON_PLUGIN_EXISTS = "plugin exists";
499
+ const CODEX_PLUGIN_SOURCE_APP_VERIFICATION_UNVERIFIED = "not_run";
286
500
  function uniqueSkillName(skill, counts) {
287
501
  const base = sanitizeName(skill.name) || "codex-skill";
288
502
  if ((counts.get(base) ?? 0) <= 1) return base;
@@ -375,12 +589,32 @@ function buildPluginItems(ctx, plugins) {
375
589
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
376
590
  pluginName: plugin.pluginName,
377
591
  sourceInstalled: plugin.installed === true,
378
- sourceEnabled: plugin.enabled === true
592
+ sourceEnabled: plugin.enabled === true,
593
+ ...plugin.apps && plugin.apps.length > 0 && !shouldVerifyPluginApps(ctx) ? { sourceAppVerification: CODEX_PLUGIN_SOURCE_APP_VERIFICATION_UNVERIFIED } : {}
379
594
  }
380
595
  }));
381
596
  continue;
382
597
  }
383
598
  manualIndex += 1;
599
+ if (plugin.migrationBlock && plugin.pluginName) {
600
+ const details = {
601
+ pluginName: plugin.pluginName,
602
+ marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
603
+ ...plugin.migrationBlock.apps ? { apps: plugin.migrationBlock.apps } : {},
604
+ ...plugin.migrationBlock.error ? { error: plugin.migrationBlock.error } : {}
605
+ };
606
+ items.push(createMigrationItem({
607
+ id: `plugin:${sanitizeName(plugin.name) || sanitizeName(path.basename(plugin.source))}:${manualIndex}`,
608
+ kind: "manual",
609
+ action: "manual",
610
+ source: plugin.source,
611
+ status: "skipped",
612
+ reason: plugin.migrationBlock.code,
613
+ message: plugin.message ?? `Codex native plugin "${plugin.name}" was found but not activated automatically.`,
614
+ details: { ...details }
615
+ }));
616
+ continue;
617
+ }
384
618
  items.push(createMigrationManualItem({
385
619
  id: `plugin:${sanitizeName(plugin.name) || sanitizeName(path.basename(plugin.source))}:${manualIndex}`,
386
620
  source: plugin.source,
@@ -390,6 +624,9 @@ function buildPluginItems(ctx, plugins) {
390
624
  }
391
625
  return items;
392
626
  }
627
+ function shouldVerifyPluginApps(ctx) {
628
+ return ctx.providerOptions?.verifyPluginApps === true;
629
+ }
393
630
  function readCodexPluginMigrationConfigEntry(item, enabled) {
394
631
  const configKey = item.details?.configKey;
395
632
  const marketplaceName = item.details?.marketplaceName;
@@ -461,9 +698,13 @@ function buildPluginConfigItem(ctx, pluginItems) {
461
698
  });
462
699
  }
463
700
  async function buildCodexMigrationPlan(ctx) {
464
- const source = await discoverCodexSource(ctx.source);
465
- if (!hasCodexSource(source)) throw new Error(`Codex state was not found at ${source.root}. Pass --from <path> if it lives elsewhere.`);
466
701
  const targets = resolveCodexMigrationTargets(ctx);
702
+ const source = await discoverCodexSource({
703
+ input: ctx.source,
704
+ evaluatePluginMigrationEligibility: true,
705
+ verifyPluginApps: shouldVerifyPluginApps(ctx)
706
+ });
707
+ if (!hasCodexSource(source)) throw new Error(`Codex state was not found at ${source.root}. Pass --from <path> if it lives elsewhere.`);
467
708
  const items = [];
468
709
  items.push(...await buildSkillItems({
469
710
  skills: source.skills,
@@ -484,8 +725,11 @@ async function buildCodexMigrationPlan(ctx) {
484
725
  }));
485
726
  const warnings = [
486
727
  ...items.some((item) => item.status === "conflict") ? ["Conflicts were found. Re-run with --overwrite to replace conflicting migration targets after item-level backups."] : [],
487
- ...source.plugins.length > 0 ? ["Codex source-installed openai-curated plugins are planned for native activation; cached plugin bundles remain manual-review only."] : [],
728
+ ...source.plugins.some((plugin) => plugin.migratable) ? ["Codex source-installed openai-curated plugins are planned for native activation; cached plugin bundles remain manual-review only."] : [],
729
+ ...source.plugins.some((plugin) => plugin.migratable && plugin.apps && plugin.apps.length > 0) && !shouldVerifyPluginApps(ctx) ? ["Codex app-backed plugins were planned without source app accessibility verification. Re-run with --verify-plugin-apps to force a fresh source app/list check before planning native plugin activation."] : [],
730
+ ...source.plugins.some((plugin) => plugin.sourceKind === "cache") ? ["Codex cached plugin bundles remain manual-review only."] : [],
488
731
  ...source.pluginDiscoveryError ? [`Codex app-server plugin inventory discovery failed: ${source.pluginDiscoveryError}. Cached plugin bundles, if any, are advisory only.`] : [],
732
+ ...source.plugins.some((plugin) => plugin.migrationBlock?.code === "codex_subscription_required") ? [codexPluginMigrationSubscriptionWarning()] : [],
489
733
  ...source.archivePaths.length > 0 ? ["Codex config and hook files are archive-only. They are preserved in the migration report, not loaded into OpenClaw automatically."] : []
490
734
  ];
491
735
  return {
@@ -555,6 +799,8 @@ async function applyCodexPluginInstallItem(ctx, item) {
555
799
  }
556
800
  };
557
801
  try {
802
+ const appCacheKey = await buildTargetCodexPluginAppCacheKey(ctx);
803
+ const appServer = resolveTargetCodexAppServer(ctx);
558
804
  const result = await ensureCodexPluginActivation({
559
805
  identity: policy,
560
806
  installEvenIfActive: true,
@@ -562,10 +808,13 @@ async function applyCodexPluginInstallItem(ctx, item) {
562
808
  method,
563
809
  requestParams,
564
810
  timeoutMs: 6e4,
811
+ startOptions: appServer.start,
812
+ agentDir: resolveCodexMigrationTargets(ctx).agentDir,
565
813
  config: ctx.config
566
- })
814
+ }),
815
+ appCache: defaultCodexAppInventoryCache,
816
+ appCacheKey
567
817
  });
568
- defaultCodexAppInventoryCache.clear();
569
818
  const baseDetails = {
570
819
  ...item.details,
571
820
  code: result.reason,
@@ -607,6 +856,30 @@ async function applyCodexPluginInstallItem(ctx, item) {
607
856
  };
608
857
  }
609
858
  }
859
+ function resolveTargetCodexAppServer(ctx) {
860
+ return resolveCodexAppServerRuntimeOptions({ pluginConfig: readCodexPluginConfig(ctx.config) });
861
+ }
862
+ async function buildTargetCodexPluginAppCacheKey(ctx) {
863
+ const targets = resolveCodexMigrationTargets(ctx);
864
+ const appServer = resolveTargetCodexAppServer(ctx);
865
+ const authProfileId = resolveCodexAppServerAuthProfileIdForAgent({
866
+ agentDir: targets.agentDir,
867
+ config: ctx.config
868
+ });
869
+ const accountId = await resolveCodexAppServerAuthAccountCacheKey({
870
+ authProfileId,
871
+ agentDir: targets.agentDir,
872
+ config: ctx.config
873
+ });
874
+ const envApiKeyFingerprint = authProfileId ? void 0 : resolveCodexAppServerEnvApiKeyCacheKey({ startOptions: appServer.start });
875
+ return buildCodexPluginAppCacheKey({
876
+ appServer,
877
+ agentDir: targets.agentDir,
878
+ authProfileId,
879
+ accountId,
880
+ envApiKeyFingerprint
881
+ });
882
+ }
610
883
  async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
611
884
  const entries = appliedItems.map(readAppliedPluginConfigEntry).filter((entry) => entry !== void 0);
612
885
  if (entries.length === 0) return markMigrationItemSkipped(item, "no selected Codex plugins");
@@ -694,7 +967,7 @@ function buildCodexMigrationProvider(params = {}) {
694
967
  label: "Codex",
695
968
  description: "Inventory and promote Codex CLI skills while keeping Codex native plugins and hooks explicit.",
696
969
  async detect(ctx) {
697
- const source = await discoverCodexSource(ctx.source);
970
+ const source = await discoverCodexSource({ input: ctx.source });
698
971
  const found = hasCodexSource(source);
699
972
  return {
700
973
  found,
@@ -1,7 +1,7 @@
1
1
  import { CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS } from "./provider-catalog.js";
2
2
  import { s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.js";
3
3
  import { i as assertCodexTurnStartResponse, l as readCodexTurnCompletedNotification, o as readCodexErrorNotification, r as assertCodexThreadStartResponse } from "./protocol-validators-CSY0BFBo.js";
4
- import { i as readModelListResult } from "./models-CupVdk6Y.js";
4
+ import { i as readModelListResult } from "./models-DqfYggBz.js";
5
5
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
6
6
  import { validateJsonSchemaValue } from "openclaw/plugin-sdk/json-schema-runtime";
7
7
  //#region extensions/codex/media-understanding-provider.ts
@@ -62,7 +62,7 @@ async function runBoundedCodexVisionTurn(params) {
62
62
  const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: params.options.pluginConfig });
63
63
  const timeoutMs = Math.max(100, params.timeoutMs);
64
64
  const ownsClient = !params.options.clientFactory;
65
- const client = params.options.clientFactory ? await params.options.clientFactory(appServer.start, params.profile) : await import("./shared-client-2q_uX6dM.js").then((n) => n.i).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
65
+ const client = params.options.clientFactory ? await params.options.clientFactory(appServer.start, params.profile) : await import("./shared-client-DSSqFqHM.js").then((n) => n.i).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
66
66
  startOptions: appServer.start,
67
67
  timeoutMs,
68
68
  authProfileId: params.profile
@@ -39,7 +39,7 @@ async function listAllCodexAppServerModels(options = {}) {
39
39
  async function withCodexAppServerModelClient(options, run) {
40
40
  const timeoutMs = options.timeoutMs ?? 2500;
41
41
  const useSharedClient = options.sharedClient !== false;
42
- const { createIsolatedCodexAppServerClient, getSharedCodexAppServerClient } = await import("./shared-client-2q_uX6dM.js").then((n) => n.i);
42
+ const { createIsolatedCodexAppServerClient, getSharedCodexAppServerClient } = await import("./shared-client-DSSqFqHM.js").then((n) => n.i);
43
43
  const client = useSharedClient ? await getSharedCodexAppServerClient({
44
44
  startOptions: options.startOptions,
45
45
  timeoutMs,
@@ -386,4 +386,4 @@ function activationFailure(identity, reason, diagnostic) {
386
386
  };
387
387
  }
388
388
  //#endregion
389
- export { defaultCodexAppInventoryCache as i, readCodexPluginInventory as n, buildCodexAppInventoryCacheKey as r, ensureCodexPluginActivation as t };
389
+ export { defaultCodexAppInventoryCache as a, buildCodexAppInventoryCacheKey as i, pluginReadParams as n, readCodexPluginInventory as r, ensureCodexPluginActivation as t };
@@ -0,0 +1,46 @@
1
+ import { d as resolveCodexAppServerHomeDir } from "./shared-client-DSSqFqHM.js";
2
+ import { i as buildCodexAppInventoryCacheKey } from "./plugin-activation-PXGqUjwY.js";
3
+ import { createHash } from "node:crypto";
4
+ //#region extensions/codex/src/app-server/plugin-app-cache-key.ts
5
+ function buildCodexPluginAppCacheKey(params) {
6
+ return buildCodexAppInventoryCacheKey({
7
+ codexHome: resolveCodexPluginAppCacheCodexHome(params.appServer, params.agentDir),
8
+ endpoint: resolveCodexPluginAppCacheEndpoint(params.appServer),
9
+ authProfileId: params.authProfileId,
10
+ accountId: params.accountId,
11
+ envApiKeyFingerprint: params.envApiKeyFingerprint,
12
+ appServerVersion: params.appServerVersion
13
+ });
14
+ }
15
+ function resolveCodexPluginAppCacheEndpoint(appServer) {
16
+ return JSON.stringify({
17
+ transport: appServer.start.transport,
18
+ command: appServer.start.command,
19
+ args: appServer.start.args,
20
+ url: appServer.start.url ?? null,
21
+ credentialFingerprint: fingerprintCodexPluginAppCacheCredentials(appServer.start)
22
+ });
23
+ }
24
+ function resolveCodexPluginAppCacheCodexHome(appServer, agentDir) {
25
+ const configuredCodexHome = appServer.start.env?.CODEX_HOME?.trim();
26
+ if (configuredCodexHome) return configuredCodexHome;
27
+ return appServer.start.transport === "stdio" && agentDir ? resolveCodexAppServerHomeDir(agentDir) : void 0;
28
+ }
29
+ function fingerprintCodexPluginAppCacheCredentials(startOptions) {
30
+ const authToken = startOptions.authToken ?? "";
31
+ const headers = Object.entries(startOptions.headers).map(([key, value]) => [key.toLowerCase(), value]).toSorted(([left], [right]) => left.localeCompare(right));
32
+ if (!authToken && headers.length === 0) return null;
33
+ const hash = createHash("sha256");
34
+ hash.update("openclaw:codex:plugin-app-cache-credentials:v1");
35
+ hash.update("\0");
36
+ hash.update(authToken);
37
+ for (const [key, value] of headers) {
38
+ hash.update("\0");
39
+ hash.update(key);
40
+ hash.update("\0");
41
+ hash.update(value);
42
+ }
43
+ return `sha256:${hash.digest("hex")}`;
44
+ }
45
+ //#endregion
46
+ export { buildCodexPluginAppCacheKey as t };
package/dist/provider.js CHANGED
@@ -123,7 +123,7 @@ async function listModelsBestEffort(params) {
123
123
  }
124
124
  }
125
125
  async function listCodexAppServerModelsLazy(options) {
126
- const { listCodexAppServerModels } = await import("./models-CupVdk6Y.js").then((n) => n.r);
126
+ const { listCodexAppServerModels } = await import("./models-DqfYggBz.js").then((n) => n.r);
127
127
  return listCodexAppServerModels(options);
128
128
  }
129
129
  function normalizeTimeoutMs(value) {
@@ -1,5 +1,5 @@
1
1
  import { n as CodexAppServerRpcError } from "./client-kySkmL1r.js";
2
- import { a as withTimeout, n as createIsolatedCodexAppServerClient, r as getSharedCodexAppServerClient } from "./shared-client-2q_uX6dM.js";
2
+ import { a as withTimeout, n as createIsolatedCodexAppServerClient, r as getSharedCodexAppServerClient } from "./shared-client-DSSqFqHM.js";
3
3
  //#region extensions/codex/src/app-server/capabilities.ts
4
4
  const CODEX_CONTROL_METHODS = {
5
5
  account: "account/read",
@@ -28,6 +28,7 @@ async function requestCodexAppServerJson(params) {
28
28
  startOptions: params.startOptions,
29
29
  timeoutMs,
30
30
  authProfileId: params.authProfileId,
31
+ agentDir: params.agentDir,
31
32
  config: params.config
32
33
  });
33
34
  try {
@@ -2,16 +2,17 @@ import { l as resolveCodexPluginsPolicy, o as readCodexPluginConfig, s as resolv
2
2
  import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-CSY0BFBo.js";
3
3
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
4
4
  import { i as isCodexAppServerConnectionClosedError, r as isCodexAppServerApprovalRequest } from "./client-kySkmL1r.js";
5
- import { n as CODEX_CONTROL_METHODS } from "./request-dv8xEOeW.js";
5
+ import { n as CODEX_CONTROL_METHODS } from "./request-DSOsuqmX.js";
6
6
  import { d as resolveCodexUsageLimitResetAtMs, f as shouldRefreshCodexRateLimitsForUsageLimitMessage, r as formatCodexDisplayText, u as formatCodexUsageLimitErrorMessage } from "./command-formatters-Ttwc_kgX.js";
7
- import { c as resolveCodexAppServerAuthProfileId, d as resolveCodexAppServerHomeDir, l as resolveCodexAppServerAuthProfileIdForAgent, o as refreshCodexAppServerAuthTokens, s as resolveCodexAppServerAuthAccountCacheKey, t as clearSharedCodexAppServerClientIfCurrent, u as resolveCodexAppServerEnvApiKeyCacheKey } from "./shared-client-2q_uX6dM.js";
7
+ import { c as resolveCodexAppServerAuthProfileId, l as resolveCodexAppServerAuthProfileIdForAgent, o as refreshCodexAppServerAuthTokens, s as resolveCodexAppServerAuthAccountCacheKey, t as clearSharedCodexAppServerClientIfCurrent, u as resolveCodexAppServerEnvApiKeyCacheKey } from "./shared-client-DSSqFqHM.js";
8
8
  import { i as readCodexAppServerBinding } from "./session-binding-CDN-Pf8K.js";
9
- import { i as defaultCodexAppInventoryCache, r as buildCodexAppInventoryCacheKey } from "./plugin-activation-lmfBoCiu.js";
10
- import { d as buildCodexPluginThreadConfig, f as buildCodexPluginThreadConfigInputFingerprint, g as normalizeCodexDynamicToolName, h as filterCodexDynamicTools, m as createCodexDynamicToolBridge, o as buildTurnStartParams, p as shouldBuildCodexPluginThreadConfig, r as buildDeveloperInstructions, s as codexDynamicToolsFingerprint, t as areCodexDynamicToolFingerprintsCompatible, u as startOrResumeThread } from "./thread-lifecycle-CSf1t3iN.js";
11
- import { n as defaultCodexAppServerClientFactory } from "./client-factory-B_0hRLx5.js";
12
- import { n as handleCodexAppServerElicitationRequest, r as handleCodexAppServerApprovalRequest, t as filterToolsForVisionInputs } from "./vision-tools-DY2xcYUU.js";
13
- import { t as ensureCodexComputerUse } from "./computer-use-DbjvOEWr.js";
14
- import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-dvhq-4pi.js";
9
+ import { a as defaultCodexAppInventoryCache } from "./plugin-activation-PXGqUjwY.js";
10
+ import { t as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DjrZp49q.js";
11
+ import { d as buildCodexPluginThreadConfig, f as buildCodexPluginThreadConfigInputFingerprint, g as normalizeCodexDynamicToolName, h as filterCodexDynamicTools, m as createCodexDynamicToolBridge, o as buildTurnStartParams, p as shouldBuildCodexPluginThreadConfig, r as buildDeveloperInstructions, s as codexDynamicToolsFingerprint, t as areCodexDynamicToolFingerprintsCompatible, u as startOrResumeThread } from "./thread-lifecycle-DW0z5zYm.js";
12
+ import { n as defaultCodexAppServerClientFactory } from "./client-factory-Bw7M3rdW.js";
13
+ import { n as handleCodexAppServerElicitationRequest, r as handleCodexAppServerApprovalRequest, t as filterToolsForVisionInputs } from "./vision-tools-DHyuabWn.js";
14
+ import { t as ensureCodexComputerUse } from "./computer-use-Br-1hHIR.js";
15
+ import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-BFi-50LG.js";
15
16
  import { createHash } from "node:crypto";
16
17
  import nodeFs from "node:fs";
17
18
  import { TOOL_PROGRESS_OUTPUT_MAX_CHARS, acquireSessionWriteLock, appendSessionTranscriptMessage, assembleHarnessContextEngine, bootstrapHarnessContextEngine, buildEmbeddedAttemptToolRunContext, buildHarnessContextEngineRuntimeContext, buildHarnessContextEngineRuntimeContextFromUsage, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, embeddedAgentLog, emitAgentEvent, emitSessionTranscriptUpdate, finalizeHarnessContextEngineTurn, formatErrorMessage, formatToolAggregate, formatToolProgressOutput, inferToolMetaFromArgs, isActiveHarnessContextEngine, isSubagentSessionKey, normalizeAgentRuntimeTools, normalizeUsage, registerNativeHookRelay, resolveAgentHarnessBeforePromptBuildResult, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveSessionWriteLockAcquireTimeoutMs, resolveUserPath, runAgentCleanupStep, runAgentHarnessAfterCompactionHook, runAgentHarnessAfterToolCallHook, runAgentHarnessAgentEndHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessBeforeMessageWriteHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -2353,36 +2354,6 @@ function toCodexTextInput(text) {
2353
2354
  text_elements: []
2354
2355
  };
2355
2356
  }
2356
- function resolveCodexPluginAppCacheEndpoint(appServer) {
2357
- return JSON.stringify({
2358
- transport: appServer.start.transport,
2359
- command: appServer.start.command,
2360
- args: appServer.start.args,
2361
- url: appServer.start.url ?? null,
2362
- credentialFingerprint: fingerprintCodexPluginAppCacheCredentials(appServer.start)
2363
- });
2364
- }
2365
- function fingerprintCodexPluginAppCacheCredentials(startOptions) {
2366
- const authToken = startOptions.authToken ?? "";
2367
- const headers = Object.entries(startOptions.headers).map(([key, value]) => [key.toLowerCase(), value]).toSorted(([left], [right]) => left.localeCompare(right));
2368
- if (!authToken && headers.length === 0) return null;
2369
- const hash = createHash("sha256");
2370
- hash.update("openclaw:codex:plugin-app-cache-credentials:v1");
2371
- hash.update("\0");
2372
- hash.update(authToken);
2373
- for (const [key, value] of headers) {
2374
- hash.update("\0");
2375
- hash.update(key);
2376
- hash.update("\0");
2377
- hash.update(value);
2378
- }
2379
- return `sha256:${hash.digest("hex")}`;
2380
- }
2381
- function resolveCodexPluginAppCacheCodexHome(appServer, agentDir) {
2382
- const configuredCodexHome = appServer.start.env?.CODEX_HOME?.trim();
2383
- if (configuredCodexHome) return configuredCodexHome;
2384
- return appServer.start.transport === "stdio" ? resolveCodexAppServerHomeDir(agentDir) : void 0;
2385
- }
2386
2357
  function restrictCodexAppServerSandboxForOpenClawSandbox(appServer, sandbox) {
2387
2358
  if (!sandbox?.enabled || appServer.sandbox !== "danger-full-access") return appServer;
2388
2359
  return {
@@ -2613,9 +2584,9 @@ async function runCodexAppServerAttempt(params, options = {}) {
2613
2584
  hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec
2614
2585
  }) : options.nativeHookRelay?.enabled === false ? buildCodexNativeHookRelayDisabledConfig() : void 0;
2615
2586
  const pluginThreadConfigEnabled = shouldBuildCodexPluginThreadConfig(pluginConfig);
2616
- const pluginAppCacheKey = buildCodexAppInventoryCacheKey({
2617
- codexHome: resolveCodexPluginAppCacheCodexHome(appServer, agentDir),
2618
- endpoint: resolveCodexPluginAppCacheEndpoint(appServer),
2587
+ const pluginAppCacheKey = buildCodexPluginAppCacheKey({
2588
+ appServer,
2589
+ agentDir,
2619
2590
  authProfileId: startupAuthProfileId,
2620
2591
  accountId: startupAuthAccountCacheKey,
2621
2592
  envApiKeyFingerprint: startupEnvApiKeyCacheKey
@@ -3742,6 +3713,7 @@ async function buildDynamicTools(input) {
3742
3713
  resolvedWorkspace: input.resolvedWorkspace
3743
3714
  }),
3744
3715
  config: params.config,
3716
+ authProfileStore: params.authProfileStore,
3745
3717
  abortSignal: input.runAbortController.signal,
3746
3718
  modelProvider: params.model.provider,
3747
3719
  modelId: params.modelId,
@@ -22,6 +22,7 @@ const CODEX_APP_SERVER_ISOLATION_ENV_VARS = [CODEX_HOME_ENV_VAR, HOME_ENV_VAR];
22
22
  async function bridgeCodexAppServerStartOptions(params) {
23
23
  if (params.startOptions.transport !== "stdio") return params.startOptions;
24
24
  const isolatedStartOptions = await withAgentCodexHomeEnvironment(params.startOptions, params.agentDir);
25
+ if (params.authProfileId === null) return isolatedStartOptions;
25
26
  const store = ensureCodexAppServerAuthProfileStore({
26
27
  agentDir: params.agentDir,
27
28
  authProfileId: params.authProfileId,
@@ -174,6 +175,7 @@ function withoutClearedCodexIsolationEnv(clearEnv) {
174
175
  return filtered.length === clearEnv.length ? clearEnv : filtered;
175
176
  }
176
177
  async function applyCodexAppServerAuthProfile(params) {
178
+ if (params.authProfileId === null) return;
177
179
  const loginParams = await resolveCodexAppServerAuthProfileLoginParams({
178
180
  agentDir: params.agentDir,
179
181
  authProfileId: params.authProfileId,
@@ -488,20 +490,22 @@ function getSharedCodexAppServerClientState() {
488
490
  async function getSharedCodexAppServerClient(options) {
489
491
  const state = getSharedCodexAppServerClientState();
490
492
  const agentDir = options?.agentDir ?? resolveDefaultAgentDir(options?.config ?? {});
491
- const authProfileId = resolveCodexAppServerAuthProfileIdForAgent({
492
- authProfileId: options?.authProfileId,
493
+ const usesNativeAuth = options?.authProfileId === null;
494
+ const requestedAuthProfileId = options?.authProfileId === null ? void 0 : options?.authProfileId;
495
+ const authProfileId = usesNativeAuth ? void 0 : resolveCodexAppServerAuthProfileIdForAgent({
496
+ authProfileId: requestedAuthProfileId,
493
497
  agentDir,
494
498
  config: options?.config
495
499
  });
496
500
  const startOptions = await bridgeCodexAppServerStartOptions({
497
501
  startOptions: await resolveManagedCodexAppServerStartOptions(options?.startOptions ?? resolveCodexAppServerRuntimeOptions().start),
498
502
  agentDir,
499
- authProfileId,
503
+ authProfileId: usesNativeAuth ? null : authProfileId,
500
504
  config: options?.config
501
505
  });
502
506
  const key = codexAppServerStartOptionsKey(startOptions, {
503
507
  authProfileId,
504
- agentDir
508
+ agentDir: usesNativeAuth ? void 0 : agentDir
505
509
  });
506
510
  if (state.key && state.key !== key) clearSharedCodexAppServerClient();
507
511
  state.key = key;
@@ -514,7 +518,7 @@ async function getSharedCodexAppServerClient(options) {
514
518
  await applyCodexAppServerAuthProfile({
515
519
  client,
516
520
  agentDir,
517
- authProfileId,
521
+ authProfileId: usesNativeAuth ? null : authProfileId,
518
522
  startOptions,
519
523
  config: options?.config
520
524
  });
@@ -533,15 +537,17 @@ async function getSharedCodexAppServerClient(options) {
533
537
  }
534
538
  async function createIsolatedCodexAppServerClient(options) {
535
539
  const agentDir = options?.agentDir ?? resolveDefaultAgentDir(options?.config ?? {});
536
- const authProfileId = resolveCodexAppServerAuthProfileIdForAgent({
537
- authProfileId: options?.authProfileId,
540
+ const usesNativeAuth = options?.authProfileId === null;
541
+ const requestedAuthProfileId = options?.authProfileId === null ? void 0 : options?.authProfileId;
542
+ const authProfileId = usesNativeAuth ? void 0 : resolveCodexAppServerAuthProfileIdForAgent({
543
+ authProfileId: requestedAuthProfileId,
538
544
  agentDir,
539
545
  config: options?.config
540
546
  });
541
547
  const startOptions = await bridgeCodexAppServerStartOptions({
542
548
  startOptions: await resolveManagedCodexAppServerStartOptions(options?.startOptions ?? resolveCodexAppServerRuntimeOptions().start),
543
549
  agentDir,
544
- authProfileId,
550
+ authProfileId: usesNativeAuth ? null : authProfileId,
545
551
  config: options?.config
546
552
  });
547
553
  const client = CodexAppServerClient.start(startOptions);
@@ -551,7 +557,7 @@ async function createIsolatedCodexAppServerClient(options) {
551
557
  await applyCodexAppServerAuthProfile({
552
558
  client,
553
559
  agentDir,
554
- authProfileId,
560
+ authProfileId: usesNativeAuth ? null : authProfileId,
555
561
  startOptions,
556
562
  config: options?.config
557
563
  });
@@ -3,11 +3,11 @@ import { a as readCodexDynamicToolCallParams, i as assertCodexTurnStartResponse,
3
3
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
4
4
  import { r as isCodexAppServerApprovalRequest } from "./client-kySkmL1r.js";
5
5
  import { u as formatCodexUsageLimitErrorMessage } from "./command-formatters-Ttwc_kgX.js";
6
- import { o as refreshCodexAppServerAuthTokens, r as getSharedCodexAppServerClient } from "./shared-client-2q_uX6dM.js";
6
+ import { o as refreshCodexAppServerAuthTokens, r as getSharedCodexAppServerClient } from "./shared-client-DSSqFqHM.js";
7
7
  import { i as readCodexAppServerBinding } from "./session-binding-CDN-Pf8K.js";
8
- import { c as resolveCodexAppServerModelProvider, h as filterCodexDynamicTools, l as resolveReasoningEffort, m as createCodexDynamicToolBridge, n as buildCodexRuntimeThreadConfig } from "./thread-lifecycle-CSf1t3iN.js";
9
- import { n as handleCodexAppServerElicitationRequest, r as handleCodexAppServerApprovalRequest, t as filterToolsForVisionInputs } from "./vision-tools-DY2xcYUU.js";
10
- import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-dvhq-4pi.js";
8
+ import { c as resolveCodexAppServerModelProvider, h as filterCodexDynamicTools, l as resolveReasoningEffort, m as createCodexDynamicToolBridge, n as buildCodexRuntimeThreadConfig } from "./thread-lifecycle-DW0z5zYm.js";
9
+ import { n as handleCodexAppServerElicitationRequest, r as handleCodexAppServerApprovalRequest, t as filterToolsForVisionInputs } from "./vision-tools-DHyuabWn.js";
10
+ import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-BFi-50LG.js";
11
11
  import { embeddedAgentLog, formatErrorMessage, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
12
12
  //#region extensions/codex/src/app-server/side-question.ts
13
13
  const CODEX_SIDE_DYNAMIC_TOOL_TIMEOUT_MS = 3e4;
package/dist/test-api.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.js";
2
- import { a as buildThreadStartParams, h as filterCodexDynamicTools, i as buildThreadResumeParams, m as createCodexDynamicToolBridge, o as buildTurnStartParams, r as buildDeveloperInstructions } from "./thread-lifecycle-CSf1t3iN.js";
2
+ import { a as buildThreadStartParams, h as filterCodexDynamicTools, i as buildThreadResumeParams, m as createCodexDynamicToolBridge, o as buildTurnStartParams, r as buildDeveloperInstructions } from "./thread-lifecycle-DW0z5zYm.js";
3
3
  //#region extensions/codex/test-api.ts
4
4
  function resolveCodexPromptSnapshotAppServerOptions(pluginConfig) {
5
5
  return resolveCodexAppServerRuntimeOptions({
@@ -5,7 +5,7 @@ import { CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY, renderCodexPromptOverlay } from ".
5
5
  import { isModernCodexModel } from "./provider.js";
6
6
  import { i as isCodexAppServerConnectionClosedError } from "./client-kySkmL1r.js";
7
7
  import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-CDN-Pf8K.js";
8
- import { i as defaultCodexAppInventoryCache, n as readCodexPluginInventory, t as ensureCodexPluginActivation } from "./plugin-activation-lmfBoCiu.js";
8
+ import { a as defaultCodexAppInventoryCache, r as readCodexPluginInventory, t as ensureCodexPluginActivation } from "./plugin-activation-PXGqUjwY.js";
9
9
  import crypto from "node:crypto";
10
10
  import { HEARTBEAT_RESPONSE_TOOL_NAME, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, extractToolResultMediaArtifact, filterToolResultMediaUrls, isMessagingTool, isMessagingToolSendAction, isToolWrappedWithBeforeToolCallHook, normalizeHeartbeatToolResponse, runAgentHarnessAfterToolCallHook, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
11
11
  //#region extensions/codex/src/app-server/dynamic-tool-profile.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.5.12-beta.1",
3
+ "version": "2026.5.12-beta.3",
4
4
  "description": "OpenClaw Codex harness and model provider plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,10 +27,10 @@
27
27
  "minHostVersion": ">=2026.5.1-beta.1"
28
28
  },
29
29
  "compat": {
30
- "pluginApi": ">=2026.5.12-beta.1"
30
+ "pluginApi": ">=2026.5.12-beta.3"
31
31
  },
32
32
  "build": {
33
- "openclawVersion": "2026.5.12-beta.1"
33
+ "openclawVersion": "2026.5.12-beta.3"
34
34
  },
35
35
  "release": {
36
36
  "publishToClawHub": true,
@@ -45,7 +45,7 @@
45
45
  "openclaw.plugin.json"
46
46
  ],
47
47
  "peerDependencies": {
48
- "openclaw": ">=2026.5.12-beta.1"
48
+ "openclaw": ">=2026.5.12-beta.3"
49
49
  },
50
50
  "peerDependenciesMeta": {
51
51
  "openclaw": {