@openclaw/codex 2026.5.10-beta.5 → 2026.5.12-beta.2

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 (25) hide show
  1. package/dist/{client-factory-D2P0KD6r.js → client-factory-Bw7M3rdW.js} +1 -1
  2. package/dist/{client-CpksBQ9l.js → client-kySkmL1r.js} +1 -1
  3. package/dist/{command-handlers-iLF1EI-b.js → command-handlers-D9CzemFF.js} +7 -7
  4. package/dist/{compact-BJ1UYEyA.js → compact-DfmGNV9J.js} +3 -3
  5. package/dist/{computer-use-CVLaKaW3.js → computer-use-Br-1hHIR.js} +2 -2
  6. package/dist/{config-C7xdbzrp.js → config-0rd3LnKg.js} +1 -1
  7. package/dist/{conversation-binding-D4XZ-tvV.js → conversation-binding-Dn66MHqg.js} +4 -4
  8. package/dist/harness.js +5 -5
  9. package/dist/index.js +324 -50
  10. package/dist/media-understanding-provider.js +3 -3
  11. package/dist/{models-Bg-Qf5s-.js → models-DqfYggBz.js} +1 -1
  12. package/dist/{plugin-activation-C0soz2YD.js → plugin-activation-PXGqUjwY.js} +2 -2
  13. package/dist/plugin-app-cache-key-DjrZp49q.js +46 -0
  14. package/dist/provider.js +2 -2
  15. package/dist/{request-BCAfJvSg.js → request-DSOsuqmX.js} +3 -2
  16. package/dist/{run-attempt-DZvighJE.js → run-attempt-y4QDhBHf.js} +494 -67
  17. package/dist/{session-binding-UFKjHkKJ.js → session-binding-CDN-Pf8K.js} +1 -1
  18. package/dist/{shared-client-K13b0L1X.js → shared-client-DSSqFqHM.js} +17 -11
  19. package/dist/{side-question-Dh_g53P9.js → side-question-BcATx0hX.js} +7 -7
  20. package/dist/test-api.js +2 -2
  21. package/dist/{thread-lifecycle-i42nWiSS.js → thread-lifecycle-DW0z5zYm.js} +4 -4
  22. package/dist/{vision-tools-Bo0P6gwM.js → vision-tools-DHyuabWn.js} +21 -0
  23. package/openclaw.plugin.json +2 -2
  24. package/package.json +7 -7
  25. /package/dist/{rate-limit-cache-dvhq-4pi.js → rate-limit-cache-BFi-50LG.js} +0 -0
@@ -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-K13b0L1X.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,4 +1,4 @@
1
- import { s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
1
+ import { s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.js";
2
2
  import { n as isRpcResponse } from "./protocol-C9UWI98H.js";
3
3
  import { createInterface } from "node:readline";
4
4
  import { OPENCLAW_VERSION, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -1,12 +1,12 @@
1
- import { i as isCodexFastServiceTier, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
- import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-Bg-Qf5s-.js";
1
+ import { i as isCodexFastServiceTier, s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.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-BCAfJvSg.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
- import { i as readCodexAppServerBinding, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-UFKjHkKJ.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-D4XZ-tvV.js";
8
- import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-CVLaKaW3.js";
9
- import { n as rememberCodexRateLimits } from "./rate-limit-cache-dvhq-4pi.js";
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-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
- import { s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
1
+ import { s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
- import { i as readCodexAppServerBinding } from "./session-binding-UFKjHkKJ.js";
4
- import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-D2P0KD6r.js";
3
+ import { i as readCodexAppServerBinding } from "./session-binding-CDN-Pf8K.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
- import { c as resolveCodexComputerUseConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
- import { r as describeControlFailure, t as requestCodexAppServerJson } from "./request-BCAfJvSg.js";
1
+ import { c as resolveCodexComputerUseConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-0rd3LnKg.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 {
@@ -92,7 +92,7 @@ function resolveCodexPluginsPolicy(pluginConfig) {
92
92
  const config = readCodexPluginConfig(pluginConfig).codexPlugins;
93
93
  const configured = config !== void 0;
94
94
  const enabled = config?.enabled === true;
95
- const allowDestructiveActions = config?.allow_destructive_actions ?? false;
95
+ const allowDestructiveActions = config?.allow_destructive_actions ?? true;
96
96
  return {
97
97
  configured,
98
98
  enabled,
@@ -1,9 +1,9 @@
1
- import { i as isCodexFastServiceTier, r as codexSandboxPolicyForTurn, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
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-BCAfJvSg.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-K13b0L1X.js";
6
- import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, r as normalizeCodexAppServerBindingModelProvider, t as clearCodexAppServerBinding } from "./session-binding-UFKjHkKJ.js";
5
+ import { l as resolveCodexAppServerAuthProfileIdForAgent, r as getSharedCodexAppServerClient } from "./shared-client-DSSqFqHM.js";
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";
9
9
  import { fileURLToPath } from "node:url";
package/dist/harness.js CHANGED
@@ -18,25 +18,25 @@ function createCodexAppServerAgentHarness(options) {
18
18
  };
19
19
  },
20
20
  runAttempt: async (params) => {
21
- const { runCodexAppServerAttempt } = await import("./run-attempt-DZvighJE.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-Dh_g53P9.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-BJ1UYEyA.js");
29
+ const { maybeCompactCodexAppServerSession } = await import("./compact-DfmGNV9J.js");
30
30
  return maybeCompactCodexAppServerSession(params, { pluginConfig: options?.pluginConfig });
31
31
  },
32
32
  reset: async (params) => {
33
33
  if (params.sessionFile) {
34
- const { clearCodexAppServerBinding } = await import("./session-binding-UFKjHkKJ.js").then((n) => n.a);
34
+ const { clearCodexAppServerBinding } = await import("./session-binding-CDN-Pf8K.js").then((n) => n.a);
35
35
  await clearCodexAppServerBinding(params.sessionFile);
36
36
  }
37
37
  },
38
38
  dispose: async () => {
39
- const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-K13b0L1X.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-C7xdbzrp.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-BCAfJvSg.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-D4XZ-tvV.js";
8
- import { i as defaultCodexAppInventoryCache, t as ensureCodexPluginActivation } from "./plugin-activation-C0soz2YD.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-iLF1EI-b.js");
42
+ const { handleCodexSubcommand } = await import("./command-handlers-D9CzemFF.js");
41
43
  return handleCodexSubcommand;
42
44
  }
43
45
  //#endregion
@@ -134,46 +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
- startOptions: {
144
- transport: "stdio",
145
- command: "codex",
146
- commandSource: "config",
147
- args: [
148
- "app-server",
149
- "--listen",
150
- "stdio://"
151
- ],
152
- headers: {},
153
- env: {
154
- CODEX_HOME: codexHome,
155
- HOME: path.dirname(codexHome)
156
- }
157
- }
144
+ requestParams: { cwds: [] }
158
145
  })).marketplaces.find((entry) => entry.name === CODEX_PLUGINS_MARKETPLACE_NAME);
159
146
  if (!marketplace) return {
160
147
  plugins: [],
161
148
  error: `Codex marketplace ${CODEX_PLUGINS_MARKETPLACE_NAME} was not found in source plugin inventory.`
162
149
  };
163
- return { plugins: marketplace.plugins.filter((plugin) => plugin.installed).map((plugin) => {
164
- const pluginName = pluginNameFromSummary(plugin);
165
- if (!pluginName) return;
166
- return {
167
- name: plugin.name,
168
- pluginName,
169
- marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
170
- source: `${CODEX_PLUGINS_MARKETPLACE_NAME}/${pluginName}`,
171
- sourceKind: "app-server",
172
- migratable: true,
173
- installed: plugin.installed,
174
- enabled: plugin.enabled
175
- };
176
- }).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)) };
177
157
  } catch (error) {
178
158
  return {
179
159
  plugins: [],
@@ -181,6 +161,239 @@ async function discoverInstalledCuratedPlugins(codexHome) {
181
161
  };
182
162
  }
183
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
+ }
184
397
  function pluginNameFromSummary(summary) {
185
398
  const candidates = [summary.id, summary.name];
186
399
  for (const candidate of candidates) {
@@ -190,8 +403,9 @@ function pluginNameFromSummary(summary) {
190
403
  if (normalized) return normalized;
191
404
  }
192
405
  }
193
- async function discoverCodexSource(input) {
194
- 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());
195
409
  const codexSkillsDir = path.join(codexHome, "skills");
196
410
  const agentsSkillsDir = personalAgentsSkillsDir();
197
411
  const configPath = path.join(codexHome, "config.toml");
@@ -205,7 +419,7 @@ async function discoverCodexSource(input) {
205
419
  root: agentsSkillsDir,
206
420
  sourceLabel: "personal AgentSkill"
207
421
  });
208
- const sourcePluginDiscovery = await discoverInstalledCuratedPlugins(codexHome);
422
+ const sourcePluginDiscovery = await discoverInstalledCuratedPlugins(codexHome, options);
209
423
  const sourcePluginNames = new Set(sourcePluginDiscovery.plugins.flatMap((plugin) => plugin.pluginName ? [plugin.pluginName] : []));
210
424
  const cachedPlugins = (await discoverPluginDirs(codexHome)).filter((plugin) => {
211
425
  const normalizedName = sanitizePluginName(plugin.name);
@@ -282,6 +496,7 @@ const CODEX_PLUGIN_NATIVE_CONFIG_PATH = [
282
496
  "codexPlugins"
283
497
  ];
284
498
  const MIGRATION_REASON_PLUGIN_EXISTS = "plugin exists";
499
+ const CODEX_PLUGIN_SOURCE_APP_VERIFICATION_UNVERIFIED = "not_run";
285
500
  function uniqueSkillName(skill, counts) {
286
501
  const base = sanitizeName(skill.name) || "codex-skill";
287
502
  if ((counts.get(base) ?? 0) <= 1) return base;
@@ -374,12 +589,32 @@ function buildPluginItems(ctx, plugins) {
374
589
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
375
590
  pluginName: plugin.pluginName,
376
591
  sourceInstalled: plugin.installed === true,
377
- 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 } : {}
378
594
  }
379
595
  }));
380
596
  continue;
381
597
  }
382
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
+ }
383
618
  items.push(createMigrationManualItem({
384
619
  id: `plugin:${sanitizeName(plugin.name) || sanitizeName(path.basename(plugin.source))}:${manualIndex}`,
385
620
  source: plugin.source,
@@ -389,6 +624,9 @@ function buildPluginItems(ctx, plugins) {
389
624
  }
390
625
  return items;
391
626
  }
627
+ function shouldVerifyPluginApps(ctx) {
628
+ return ctx.providerOptions?.verifyPluginApps === true;
629
+ }
392
630
  function readCodexPluginMigrationConfigEntry(item, enabled) {
393
631
  const configKey = item.details?.configKey;
394
632
  const marketplaceName = item.details?.marketplaceName;
@@ -417,7 +655,7 @@ function buildCodexPluginsConfigValue(entries, params = {}) {
417
655
  enabled: true,
418
656
  config: { codexPlugins: {
419
657
  enabled: true,
420
- allow_destructive_actions: params.config === void 0 ? false : readExistingAllowDestructiveActions(params.config) ?? false,
658
+ allow_destructive_actions: params.config === void 0 ? true : readExistingAllowDestructiveActions(params.config) ?? true,
421
659
  plugins
422
660
  } }
423
661
  };
@@ -460,9 +698,13 @@ function buildPluginConfigItem(ctx, pluginItems) {
460
698
  });
461
699
  }
462
700
  async function buildCodexMigrationPlan(ctx) {
463
- const source = await discoverCodexSource(ctx.source);
464
- if (!hasCodexSource(source)) throw new Error(`Codex state was not found at ${source.root}. Pass --from <path> if it lives elsewhere.`);
465
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.`);
466
708
  const items = [];
467
709
  items.push(...await buildSkillItems({
468
710
  skills: source.skills,
@@ -483,8 +725,11 @@ async function buildCodexMigrationPlan(ctx) {
483
725
  }));
484
726
  const warnings = [
485
727
  ...items.some((item) => item.status === "conflict") ? ["Conflicts were found. Re-run with --overwrite to replace conflicting migration targets after item-level backups."] : [],
486
- ...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."] : [],
487
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()] : [],
488
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."] : []
489
734
  ];
490
735
  return {
@@ -554,6 +799,8 @@ async function applyCodexPluginInstallItem(ctx, item) {
554
799
  }
555
800
  };
556
801
  try {
802
+ const appCacheKey = await buildTargetCodexPluginAppCacheKey(ctx);
803
+ const appServer = resolveTargetCodexAppServer(ctx);
557
804
  const result = await ensureCodexPluginActivation({
558
805
  identity: policy,
559
806
  installEvenIfActive: true,
@@ -561,10 +808,13 @@ async function applyCodexPluginInstallItem(ctx, item) {
561
808
  method,
562
809
  requestParams,
563
810
  timeoutMs: 6e4,
811
+ startOptions: appServer.start,
812
+ agentDir: resolveCodexMigrationTargets(ctx).agentDir,
564
813
  config: ctx.config
565
- })
814
+ }),
815
+ appCache: defaultCodexAppInventoryCache,
816
+ appCacheKey
566
817
  });
567
- defaultCodexAppInventoryCache.clear();
568
818
  const baseDetails = {
569
819
  ...item.details,
570
820
  code: result.reason,
@@ -606,6 +856,30 @@ async function applyCodexPluginInstallItem(ctx, item) {
606
856
  };
607
857
  }
608
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
+ }
609
883
  async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
610
884
  const entries = appliedItems.map(readAppliedPluginConfigEntry).filter((entry) => entry !== void 0);
611
885
  if (entries.length === 0) return markMigrationItemSkipped(item, "no selected Codex plugins");
@@ -651,7 +925,7 @@ function readCodexPluginPolicy(item) {
651
925
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
652
926
  pluginName,
653
927
  enabled: true,
654
- allowDestructiveActions: false
928
+ allowDestructiveActions: true
655
929
  };
656
930
  }
657
931
  function codexPluginActivationReportState(result) {
@@ -693,7 +967,7 @@ function buildCodexMigrationProvider(params = {}) {
693
967
  label: "Codex",
694
968
  description: "Inventory and promote Codex CLI skills while keeping Codex native plugins and hooks explicit.",
695
969
  async detect(ctx) {
696
- const source = await discoverCodexSource(ctx.source);
970
+ const source = await discoverCodexSource({ input: ctx.source });
697
971
  const found = hasCodexSource(source);
698
972
  return {
699
973
  found,
@@ -1,7 +1,7 @@
1
1
  import { CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS } from "./provider-catalog.js";
2
- import { s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
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-Bg-Qf5s-.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-K13b0L1X.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-K13b0L1X.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,