@openclaw/codex 2026.7.2-beta.4 → 2026.7.2-beta.7

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 (40) hide show
  1. package/dist/{app-server-policy-BO3jYBkv.js → app-server-policy-BSaO2JIT.js} +1 -1
  2. package/dist/{attempt-notifications-DdmnBMUp.js → attempt-notifications-AP-a-Q5k.js} +1 -1
  3. package/dist/{bounded-turn-CaQL96kg.js → bounded-turn-D2ZAgZVz.js} +54 -24
  4. package/dist/{capabilities-CLICvTxf.js → capabilities-BFDTVYr4.js} +1 -1
  5. package/dist/cli-metadata.js +1 -1
  6. package/dist/{command-formatters-DgADqnHa.js → command-formatters-C336eRVS.js} +2 -2
  7. package/dist/{command-handlers-l_lVPNlB.js → command-handlers-DAHUSry9.js} +1233 -1222
  8. package/dist/{compact-CC5KhBzX.js → compact-D_uvHurS.js} +8 -8
  9. package/dist/{computer-use-Ip1-QGa-.js → computer-use-CYEc8U3w.js} +123 -115
  10. package/dist/{conversation-control-sNPsbTCP.js → conversation-control-xsIeXbo4.js} +6 -6
  11. package/dist/doctor-contract-api.js +24 -86
  12. package/dist/{dynamic-tools-CQI3UwqY.js → dynamic-tools-D2gYkSBO.js} +482 -91
  13. package/dist/effective-mcp-catalog-Bbd98Inw.js +114 -0
  14. package/dist/{event-projector-usage-D6tE7_qD.js → event-projector-usage-Xp4AlR2k.js} +20 -3
  15. package/dist/harness.js +19 -14
  16. package/dist/index.js +292 -328
  17. package/dist/media-understanding-provider.js +6 -1
  18. package/dist/{models-BNeMlHgg.js → models-BBMKU4jA.js} +2 -2
  19. package/dist/{notification-correlation-BGLixv5_.js → notification-correlation-CU6_AnOb.js} +3 -3
  20. package/dist/{plugin-app-cache-key-CvzvmBRz.js → plugin-app-cache-key-DztPafOA.js} +135 -42
  21. package/dist/{rate-limits-D0IJT-a6.js → rate-limits-CU-gVCCS.js} +1 -1
  22. package/dist/{request-BTccUTD3.js → request-qKh331yu.js} +3 -3
  23. package/dist/{run-attempt--858NXDl.js → run-attempt-CY9WlDLc.js} +1060 -402
  24. package/dist/{runtime-artifact-C2ITXdhM.js → runtime-artifact-CmtG_t1L.js} +90 -24
  25. package/dist/{sandbox-guard-D1Wky__S.js → sandbox-guard-NuhpXmPB.js} +4 -0
  26. package/dist/{session-binding-ZSMX1omP.js → session-binding-BXpo9ymA.js} +1006 -891
  27. package/dist/{session-catalog-DsKaezgR.js → session-catalog-DyOgR4WH.js} +289 -56
  28. package/dist/{session-cli-CYJTfRLG.js → session-cli-2PZaFLRh.js} +2 -2
  29. package/dist/{session-upstream-marker-D7XlI9us.js → session-upstream-marker-B6U7tLw5.js} +1 -1
  30. package/dist/{settled-turn-finalizer-DHltNgtF.js → settled-turn-finalizer-CXY2Z9dT.js} +19 -6
  31. package/dist/{shared-client-wmgNFNYp.js → shared-client-DTbvH-XV.js} +1993 -1720
  32. package/dist/{side-question-BfFZCsJ-.js → side-question-_ulBk1AL.js} +12 -10
  33. package/dist/{thread-lifecycle-cqrOlJkq.js → thread-lifecycle-DF53ogiA.js} +980 -346
  34. package/dist/{transcript-mirror-2p7kl6e4.js → transcript-mirror-DzsdNCf5.js} +80 -41
  35. package/dist/{upstream-session-fork-vPjwkT1i.js → upstream-session-fork-Dy4Xvuoj.js} +3 -3
  36. package/dist/{usage-DM_I3mPT.js → usage-CQ6GhD5-.js} +3 -3
  37. package/dist/{web-search-provider.runtime-Bx6HAc_k.js → web-search-provider.runtime-CCFhg2z5.js} +3 -3
  38. package/package.json +6 -8
  39. package/npm-shrinkwrap.json +0 -202
  40. package/dist/{auth-binding-C1czuHPA.js → auth-binding-B4FfbcCg.js} +1 -1
package/dist/index.js CHANGED
@@ -1,22 +1,22 @@
1
1
  import { registerCodexCliMetadata } from "./cli-metadata.js";
2
2
  import { createCodexAppServerAgentHarness } from "./harness.js";
3
- import { C as resolveCodexAppServerFallbackApiKeyCacheKey, Q as isJsonObject, S as resolveCodexAppServerAuthProfileIdForAgent, Y as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, a as getLeasedSharedCodexAppServerClient, b as resolveCodexAppServerAuthAccountCacheKey, c as releaseLeasedSharedCodexAppServerClient, p as withLeasedCodexAppServerClientStartSelectionRetry, r as clearSharedCodexAppServerClientIfCurrentAndWait, s as releaseCodexAppServerClientLease } from "./shared-client-wmgNFNYp.js";
4
- import { D as resolveCodexSupervisionAppServerRuntimeOptions, O as resolveOpenClawExecPolicyForCodexAppServer, b as readCodexPluginConfig, d as CODEX_PLUGINS_MARKETPLACE_NAME, g as codexSandboxPolicyForTurn, h as codexAppServerStartOptionsKey, l as sessionBindingIdentity, m as canUseCodexModelBackedApprovalsReviewerForModel, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, p as assertCodexAppServerConnectionSecurity, s as normalizeCodexAppServerBindingModelProvider, x as resolveCodexAppServerRuntimeOptions } from "./session-binding-ZSMX1omP.js";
5
- import { N as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, R as unsubscribeCodexThreadBestEffort, _ as CODEX_NATIVE_PERSONALITY_NONE, c as resumeCodexAppServerThread, et as ensureCodexPluginActivation, tt as pluginReadParams, y as resolveCodexAppServerRequestModelSelection } from "./thread-lifecycle-cqrOlJkq.js";
6
- import { _ as assertCodexThreadStartResponse } from "./transcript-mirror-2p7kl6e4.js";
7
- import { i as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-CvzvmBRz.js";
3
+ import { I as resolveCodexAppServerAuthProfileIdForAgent, L as resolveCodexAppServerFallbackApiKeyCacheKey, P as resolveCodexAppServerAuthAccountCacheKey, V as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, W as isJsonObject, a as getLeasedSharedCodexAppServerClient, c as releaseCodexAppServerClientLease, h as withLeasedCodexAppServerClientStartSelectionRetry, l as releaseLeasedSharedCodexAppServerClient, r as clearSharedCodexAppServerClientIfCurrentAndWait } from "./shared-client-DTbvH-XV.js";
4
+ import { A as resolveOpenClawExecPolicyForCodexAppServer, C as canUseCodexModelBackedApprovalsReviewerForModel, M as CODEX_PLUGINS_MARKETPLACE_NAME, O as readCodexPluginConfig, b as assertCodexAppServerConnectionSecurity, d as sessionBindingIdentity, g as resolveCodexAppServerRuntimeOptions, m as codexSandboxPolicyForTurn, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, p as codexAppServerStartOptionsKey, s as normalizeCodexAppServerBindingModelProvider, y as resolveCodexSupervisionAppServerRuntimeOptions } from "./session-binding-BXpo9ymA.js";
8
5
  import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./session-binding-meta-B7aEMU7g.js";
6
+ import { J as isOpenAiCuratedMarketplace, Y as pluginReadParams, _t as unsubscribeCodexThreadBestEffort, b as resolveCodexAppServerRequestModelSelection, dt as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, l as resumeCodexAppServerThread, q as ensureCodexPluginActivation, v as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-lifecycle-DF53ogiA.js";
7
+ import { _ as assertCodexThreadStartResponse } from "./transcript-mirror-DzsdNCf5.js";
8
+ import { i as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DztPafOA.js";
9
9
  import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
10
10
  import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
11
- import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-CLICvTxf.js";
12
- import { r as formatCodexDisplayText } from "./command-formatters-DgADqnHa.js";
13
- import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-BO3jYBkv.js";
14
- import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-D1Wky__S.js";
15
- import { d as CODEX_NATIVE_EXECUTION_AUTH_ERROR, f as canMutateCodexHost, u as trackCodexConversationActiveTurn } from "./conversation-control-sNPsbTCP.js";
11
+ import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-BFDTVYr4.js";
12
+ import { r as formatCodexDisplayText } from "./command-formatters-C336eRVS.js";
13
+ import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-BSaO2JIT.js";
14
+ import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-NuhpXmPB.js";
15
+ import { d as CODEX_NATIVE_EXECUTION_AUTH_ERROR, f as canMutateCodexHost, u as trackCodexConversationActiveTurn } from "./conversation-control-xsIeXbo4.js";
16
16
  import { a as readCodexConversationBindingDataRecord, i as readCodexConversationBindingData, o as resolveCodexDefaultWorkspaceDir, r as createCodexConversationBindingData } from "./conversation-binding-data-BHRpYbX3.js";
17
- import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-BGLixv5_.js";
18
- import { d as createCodexCliSessionNodeHostCommands, f as createCodexCliSessionNodeInvokePolicies, g as resumeCodexCliSessionOnNode, h as resolveCodexCliSessionForBindingOnNode, i as createCodexSessionCatalogNodeInvokePolicies, m as listCodexCliSessionsOnNode, n as createCodexSessionCatalogControl, o as codexControlRequest, r as createCodexSessionCatalogNodeHostCommands, t as codexSessionCatalogRuntime, u as assertCodexArchiveDescendantsUnowned } from "./session-catalog-DsKaezgR.js";
19
- import { r as requestCodexAppServerJson } from "./request-BTccUTD3.js";
17
+ import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-CU6_AnOb.js";
18
+ import { d as createCodexCliSessionNodeHostCommands, f as createCodexCliSessionNodeInvokePolicies, g as resumeCodexCliSessionOnNode, h as resolveCodexCliSessionForBindingOnNode, i as createCodexSessionCatalogNodeInvokePolicies, m as listCodexCliSessionsOnNode, n as createCodexSessionCatalogControl, o as codexControlRequest, r as createCodexSessionCatalogNodeHostCommands, t as codexSessionCatalogRuntime, u as assertCodexArchiveDescendantsUnowned } from "./session-catalog-DyOgR4WH.js";
19
+ import { i as withCodexAppServerJsonClient, r as requestCodexAppServerJson } from "./request-qKh331yu.js";
20
20
  import { t as createCodexWebSearchProviderBase } from "./web-search-provider.shared-BrZmlqyR.js";
21
21
  import { mutateConfigFile } from "openclaw/plugin-sdk/config-mutation";
22
22
  import { normalizePluginsConfig, resolveEffectiveEnableState, resolveLivePluginConfigObject, resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
@@ -24,19 +24,19 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
24
24
  import fs from "node:fs/promises";
25
25
  import path from "node:path";
26
26
  import { parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
27
+ import { formatErrorMessage, resolveSandboxContext } from "openclaw/plugin-sdk/agent-harness-runtime";
28
+ import { loadAuthProfileStoreWithoutExternalProfiles, resolveAgentConfig, resolveAgentWorkspaceDir, resolveDefaultAgentDir, resolveDefaultAgentId, resolveSessionAgentIds as resolveSessionAgentIds$1 } from "openclaw/plugin-sdk/agent-runtime";
27
29
  import os from "node:os";
28
- import { loadAuthProfileStoreWithoutExternalProfiles, resolveAgentConfig, resolveAgentWorkspaceDir, resolveDefaultAgentDir, resolveDefaultAgentId, resolveSessionAgentIds } from "openclaw/plugin-sdk/agent-runtime";
30
+ import { applyAuthProfileConfig, buildApiKeyCredential, buildOauthProviderAuthResult, buildOpenAICodexCredentialExtra, readCodexCliCredentialsCached, resolveOpenAICodexAuthIdentity, resolveOpenAICodexImportProfileName, updateAuthProfileStoreWithLock } from "openclaw/plugin-sdk/provider-auth";
29
31
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
30
32
  import { asBoolean, asOptionalRecord, isRecord, normalizeOptionalString, normalizeSingleOrTrimmedStringList, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
31
- import { formatErrorMessage, resolveSandboxContext } from "openclaw/plugin-sdk/agent-harness-runtime";
32
- import { applyAuthProfileConfig, buildApiKeyCredential, buildOauthProviderAuthResult, buildOpenAICodexCredentialExtra, readCodexCliCredentialsCached, resolveOpenAICodexAuthIdentity, resolveOpenAICodexImportProfileName, updateAuthProfileStoreWithLock } from "openclaw/plugin-sdk/provider-auth";
33
33
  import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
34
34
  import { fileURLToPath } from "node:url";
35
35
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
36
- import { canonicalPathFromExistingAncestor, isPathInside, pathExists } from "openclaw/plugin-sdk/security-runtime";
36
+ import { canonicalPathFromExistingAncestor, extractErrorCode, isPathInside, pathExists } from "openclaw/plugin-sdk/security-runtime";
37
37
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
38
38
  import { ModelSelectionLockedError, isModelSelectionLocked } from "openclaw/plugin-sdk/model-session-runtime";
39
- import { MIGRATION_REASON_TARGET_EXISTS, applyMigrationManualItem, createMigrationItem, createMigrationManualItem, hasMigrationConfigPatchConflict, markMigrationItemConflict, markMigrationItemError, markMigrationItemSkipped, readMigrationConfigPath, resolveMigrationConfigRuntime, summarizeMigrationItems, writeMigrationConfigPath } from "openclaw/plugin-sdk/migration";
39
+ import { MIGRATION_REASON_TARGET_EXISTS, applyMigrationManualItem, createMigrationItem, createMigrationManualItem, hasMigrationConfigPatchConflict, markMigrationItemConflict, markMigrationItemError, markMigrationItemSkipped, mergeMigrationConfigValue, readMigrationConfigPath, resolveMigrationConfigRuntime, summarizeMigrationItems, writeMigrationConfigPath } from "openclaw/plugin-sdk/migration";
40
40
  import { archiveMigrationItem, copyMemoryMigrationFileItem, copyMigrationFileItem, withCachedMigrationConfigRuntime, writeMigrationReport } from "openclaw/plugin-sdk/migration-runtime";
41
41
  import { sleep } from "openclaw/plugin-sdk/runtime-env";
42
42
  import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
@@ -47,13 +47,14 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
47
47
  /** Defers schema compilation and auth loading until the first binding operation. */
48
48
  function createLazyCodexAppServerBindingStore(state) {
49
49
  let resolved;
50
- const store = () => resolved ??= import("./session-binding-ZSMX1omP.js").then((n) => n.u).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
50
+ const store = () => resolved ??= import("./session-binding-BXpo9ymA.js").then((n) => n.f).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
51
51
  return {
52
52
  read: async (identity) => (await store()).read(identity),
53
53
  hasOtherThreadOwner: async (threadId, currentIdentity) => (await store()).hasOtherThreadOwner(threadId, currentIdentity),
54
54
  mutate: async (identity, mutation) => (await store()).mutate(identity, mutation),
55
55
  prepareSessionGenerationReclaim: async (identity) => (await store()).prepareSessionGenerationReclaim(identity),
56
56
  adoptSessionGeneration: async (identity, previousSessionId) => (await store()).adoptSessionGeneration(identity, previousSessionId),
57
+ resetSessionGeneration: async (identity) => (await store()).resetSessionGeneration(identity),
57
58
  retireSessionGeneration: async (identity) => (await store()).retireSessionGeneration(identity),
58
59
  withThreadArchiveFence: async (run) => (await store()).withThreadArchiveFence(run),
59
60
  withLease: async (identity, run) => (await store()).withLease(identity, run)
@@ -74,7 +75,7 @@ async function handleCodexCommand(ctx, options) {
74
75
  }
75
76
  }
76
77
  async function loadDefaultCodexSubcommandHandler() {
77
- const { handleCodexSubcommand } = await import("./command-handlers-l_lVPNlB.js");
78
+ const { handleCodexSubcommand } = await import("./command-handlers-DAHUSry9.js");
78
79
  return handleCodexSubcommand;
79
80
  }
80
81
  //#endregion
@@ -937,7 +938,7 @@ async function prepareConversationBinding(params, options = {}) {
937
938
  });
938
939
  }
939
940
  function resolveConversationExecPolicy(params) {
940
- const agentId = params.agentId ?? (params.config ? resolveSessionAgentIds({
941
+ const agentId = params.agentId ?? (params.config ? resolveSessionAgentIds$1({
941
942
  sessionKey: params.sessionKey,
942
943
  config: params.config
943
944
  }).sessionAgentId : void 0);
@@ -1082,7 +1083,7 @@ function sanitizeAppsNeedingAuth(apps) {
1082
1083
  return apps.map((app) => ({
1083
1084
  id: app.id,
1084
1085
  name: app.name,
1085
- needsAuth: app.needsAuth
1086
+ needsAuth: true
1086
1087
  }));
1087
1088
  }
1088
1089
  //#endregion
@@ -1138,11 +1139,6 @@ async function readModelRefs(source) {
1138
1139
  refs.add(OPENAI_CODEX_DEFAULT_MODEL);
1139
1140
  return [...refs].toSorted();
1140
1141
  }
1141
- function readProviderAuthModelConfigs(result) {
1142
- const models = result.configPatch?.agents?.defaults?.models;
1143
- if (isRecord(models)) return { ...models };
1144
- return { [normalizeOptionalString(result.defaultModel) ?? OPENAI_CODEX_DEFAULT_MODEL]: {} };
1145
- }
1146
1142
  async function buildCodexOAuthCredential(source) {
1147
1143
  const credential = readCodexCliCredentialsCached({
1148
1144
  codexHome: source.codexHome,
@@ -1177,8 +1173,7 @@ async function buildCodexOAuthCredential(source) {
1177
1173
  kind: "oauth",
1178
1174
  provider: OPENAI_PROVIDER_ID,
1179
1175
  profileId: profile.profileId,
1180
- result,
1181
- modelConfigs: readProviderAuthModelConfigs(result)
1176
+ result
1182
1177
  } : null;
1183
1178
  }
1184
1179
  async function buildCodexApiKeyCredential(source) {
@@ -1257,30 +1252,8 @@ function applyDefaultModelIfMissing(cfg) {
1257
1252
  }
1258
1253
  };
1259
1254
  }
1260
- function mergeModelConfigEntry(existing, patch) {
1261
- if (existing && isRecord(existing) && isRecord(patch)) return {
1262
- ...existing,
1263
- ...patch
1264
- };
1265
- return existing ?? patch;
1266
- }
1267
- function applyOAuthModelConfigsToConfig(cfg, credential) {
1268
- const existingModels = cfg.agents?.defaults?.models ?? {};
1269
- const models = credential.result.replaceDefaultModels ? { ...credential.modelConfigs } : { ...existingModels };
1270
- if (!credential.result.replaceDefaultModels) for (const [modelRef, modelConfig] of Object.entries(credential.modelConfigs)) models[modelRef] = mergeModelConfigEntry(models[modelRef], modelConfig);
1271
- return {
1272
- ...cfg,
1273
- agents: {
1274
- ...cfg.agents,
1275
- defaults: {
1276
- ...cfg.agents?.defaults,
1277
- models
1278
- }
1279
- }
1280
- };
1281
- }
1282
1255
  function applyOAuthConfigToConfig(cfg, credential, profileId) {
1283
- let next = applyOAuthModelConfigsToConfig(cfg, credential);
1256
+ let next = mergeMigrationConfigValue(cfg, credential.result.configPatch);
1284
1257
  const profile = credential.result.profiles[0];
1285
1258
  if (profile) next = applyAuthProfileConfig(next, {
1286
1259
  profileId,
@@ -1304,28 +1277,23 @@ function applyApiKeyConfigToConfig(cfg, credential, profileId) {
1304
1277
  function shouldReturnAuthConfigPatch(ctx) {
1305
1278
  return ctx.providerOptions?.configPatchMode === CODEX_CONFIG_PATCH_MODE_RETURN$1;
1306
1279
  }
1307
- function oauthAuthProfileConfig(credential, profileId) {
1280
+ function authProfileConfigForCredential(credential, profileId) {
1281
+ if (credential.kind === "api_key") return {
1282
+ profileId,
1283
+ provider: credential.provider,
1284
+ mode: "api_key",
1285
+ displayName: CODEX_IMPORT_DISPLAY_NAME
1286
+ };
1308
1287
  const profile = credential.result.profiles[0];
1309
1288
  if (!profile || profile.credential.type !== "oauth") return null;
1310
1289
  return {
1311
1290
  profileId,
1312
1291
  provider: profile.credential.provider,
1313
1292
  mode: "oauth",
1314
- ..."email" in profile.credential && profile.credential.email ? { email: profile.credential.email } : {},
1315
- ..."displayName" in profile.credential && profile.credential.displayName ? { displayName: profile.credential.displayName } : {}
1316
- };
1317
- }
1318
- function apiKeyAuthProfileConfig(credential, profileId) {
1319
- return {
1320
- profileId,
1321
- provider: credential.provider,
1322
- mode: "api_key",
1323
- displayName: CODEX_IMPORT_DISPLAY_NAME
1293
+ ...profile.credential.email ? { email: profile.credential.email } : {},
1294
+ ...profile.credential.displayName ? { displayName: profile.credential.displayName } : {}
1324
1295
  };
1325
1296
  }
1326
- function authProfileConfigForCredential(credential, profileId) {
1327
- return credential.kind === "oauth" ? oauthAuthProfileConfig(credential, profileId) : apiKeyAuthProfileConfig(credential, profileId);
1328
- }
1329
1297
  async function applyCodexAuthProfileConfig(ctx, profile, applyConfig) {
1330
1298
  const configApi = resolveMigrationConfigRuntime(ctx);
1331
1299
  if (!configApi?.current || !configApi.mutateConfigFile) return "unavailable";
@@ -1344,13 +1312,13 @@ async function applyCodexAuthProfileConfig(ctx, profile, applyConfig) {
1344
1312
  return error instanceof CodexAuthConfigConflict ? "conflict" : "unavailable";
1345
1313
  }
1346
1314
  }
1347
- async function applyOAuthConfig(ctx, credential, profileId) {
1348
- const profile = oauthAuthProfileConfig(credential, profileId);
1315
+ async function applyCodexAuthConfig(ctx, credential, profileId) {
1316
+ const profile = authProfileConfigForCredential(credential, profileId);
1349
1317
  if (!profile) return "unavailable";
1350
- return applyCodexAuthProfileConfig(ctx, profile, (config) => applyOAuthConfigToConfig(config, credential, profileId));
1318
+ return applyCodexAuthProfileConfig(ctx, profile, (config) => applyCredentialConfig(config, credential, profileId));
1351
1319
  }
1352
- async function applyApiKeyConfig(ctx, credential, profileId) {
1353
- return applyCodexAuthProfileConfig(ctx, apiKeyAuthProfileConfig(credential, profileId), (config) => applyApiKeyConfigToConfig(config, credential, profileId));
1320
+ function applyCredentialConfig(config, credential, profileId) {
1321
+ return credential.kind === "oauth" ? applyOAuthConfigToConfig(config, credential, profileId) : applyApiKeyConfigToConfig(config, credential, profileId);
1354
1322
  }
1355
1323
  async function buildCodexAuthItems(params) {
1356
1324
  const credentials = await readCodexAuthCredentials(params.source);
@@ -1383,22 +1351,22 @@ async function buildCodexAuthItems(params) {
1383
1351
  });
1384
1352
  });
1385
1353
  }
1386
- async function applyCodexAuthItem(params) {
1354
+ async function applyCodexAuthItems(params) {
1387
1355
  const { ctx, item, source, targets } = params;
1388
- if (item.status !== "planned") return item;
1356
+ if (item.status !== "planned") return [item];
1389
1357
  const profileId = typeof item.details?.profileId === "string" ? item.details.profileId : "";
1390
1358
  const provider = typeof item.details?.provider === "string" ? item.details.provider : "";
1391
1359
  const sourceProfileId = typeof item.details?.sourceProfileId === "string" ? item.details.sourceProfileId : void 0;
1392
- if (!profileId || !provider) return markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA);
1360
+ if (!profileId || !provider) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
1393
1361
  const credential = (await readCodexAuthCredentials(source)).find((candidate) => candidate.provider === provider);
1394
- if (!credential) return markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT);
1395
- if (credential.kind === "oauth" && sourceProfileId && credential.profileId !== sourceProfileId) return markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT);
1362
+ if (!credential) return [markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT)];
1363
+ if (credential.kind === "oauth" && sourceProfileId && credential.profileId !== sourceProfileId) return [markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT)];
1396
1364
  const oauthProfile = credential.kind === "oauth" ? credential.result.profiles[0] : void 0;
1397
1365
  const oauthCredential = oauthProfile?.credential.type === "oauth" ? oauthProfile.credential : void 0;
1398
- if (credential.kind === "oauth" && !oauthCredential) return markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA);
1366
+ if (credential.kind === "oauth" && !oauthCredential) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
1399
1367
  const configProfile = authProfileConfigForCredential(credential, profileId);
1400
- if (!configProfile) return markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA);
1401
- if (hasCurrentAuthProfileConfigConflict(ctx, configProfile)) return markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS);
1368
+ if (!configProfile) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
1369
+ if (hasCurrentAuthProfileConfigConflict(ctx, configProfile)) return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
1402
1370
  let conflicted = false;
1403
1371
  let wrote = false;
1404
1372
  const store = await updateAuthProfileStoreWithLock({
@@ -1422,11 +1390,11 @@ async function applyCodexAuthItem(params) {
1422
1390
  return true;
1423
1391
  }
1424
1392
  });
1425
- if (conflicted) return markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS);
1426
- if (!store?.profiles[profileId]) return markMigrationItemError(item, CODEX_REASON_AUTH_PROFILE_WRITE_FAILED);
1427
- const configResult = shouldReturnAuthConfigPatch(ctx) ? "unavailable" : credential.kind === "oauth" ? await applyOAuthConfig(ctx, credential, profileId) : await applyApiKeyConfig(ctx, credential, profileId);
1428
- if (configResult === "conflict") return markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS);
1429
- return {
1393
+ if (conflicted) return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
1394
+ if (!store?.profiles[profileId]) return [markMigrationItemError(item, CODEX_REASON_AUTH_PROFILE_WRITE_FAILED)];
1395
+ const configResult = shouldReturnAuthConfigPatch(ctx) ? "unavailable" : await applyCodexAuthConfig(ctx, credential, profileId);
1396
+ if (configResult === "conflict") return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
1397
+ const migratedItem = {
1430
1398
  ...item,
1431
1399
  status: "migrated",
1432
1400
  details: {
@@ -1436,18 +1404,10 @@ async function applyCodexAuthItem(params) {
1436
1404
  ...shouldReturnAuthConfigPatch(ctx) ? { configPatchReturned: true } : {}
1437
1405
  }
1438
1406
  };
1407
+ return [migratedItem, ...shouldReturnAuthConfigPatch(ctx) ? buildCodexAuthConfigPatchItems(ctx, migratedItem, credential, profileId) : []];
1439
1408
  }
1440
- async function buildCodexAuthConfigPatchItems(params) {
1441
- const { ctx, item, source } = params;
1442
- if (item.status !== "migrated" || !shouldReturnAuthConfigPatch(ctx)) return [];
1443
- const profileId = typeof item.details?.profileId === "string" ? item.details.profileId : "";
1444
- const provider = typeof item.details?.provider === "string" ? item.details.provider : "";
1445
- const sourceProfileId = typeof item.details?.sourceProfileId === "string" ? item.details.sourceProfileId : void 0;
1446
- if (!profileId || !provider) return [];
1447
- const credential = (await readCodexAuthCredentials(source)).find((candidate) => candidate.provider === provider);
1448
- if (!credential) return [];
1449
- if (credential.kind === "oauth" && sourceProfileId && credential.profileId !== sourceProfileId) return [];
1450
- const next = credential.kind === "oauth" ? applyOAuthConfigToConfig(ctx.config, credential, profileId) : applyApiKeyConfigToConfig(ctx.config, credential, profileId);
1409
+ function buildCodexAuthConfigPatchItems(ctx, item, credential, profileId) {
1410
+ const next = applyCredentialConfig(ctx.config, credential, profileId);
1451
1411
  const items = [];
1452
1412
  if (next.auth) items.push(createMigrationItem({
1453
1413
  id: `${item.id}:config:auth`,
@@ -1476,108 +1436,6 @@ async function buildCodexAuthConfigPatchItems(params) {
1476
1436
  return items;
1477
1437
  }
1478
1438
  //#endregion
1479
- //#region extensions/codex/src/migration/memory-plan.ts
1480
- const MIGRATION_REASON_TARGET_NOT_REGULAR = "target is not a regular file";
1481
- async function lstatIfExists(filePath) {
1482
- try {
1483
- return await fs.lstat(filePath);
1484
- } catch (error) {
1485
- const code = error && typeof error === "object" && "code" in error ? String(error.code) : void 0;
1486
- if (code === "ENOENT" || code === "ENOTDIR") return;
1487
- throw error;
1488
- }
1489
- }
1490
- async function assertSafeMemoryDestination(params) {
1491
- const [canonicalSource, canonicalWorkspace, canonicalTarget] = await Promise.all([
1492
- fs.realpath(path.dirname(params.source)),
1493
- canonicalPathFromExistingAncestor(params.workspaceDir),
1494
- canonicalPathFromExistingAncestor(params.target)
1495
- ]);
1496
- if (!isPathInside(canonicalWorkspace, canonicalTarget)) throw new Error("Codex memory import destination must stay in the selected workspace.");
1497
- if (isPathInside(canonicalSource, canonicalTarget) || isPathInside(canonicalTarget, canonicalSource)) throw new Error("Codex memory source and OpenClaw import destination must be separate paths.");
1498
- }
1499
- async function buildCodexMemoryItems(params) {
1500
- const items = [];
1501
- for (const memory of params.memoryFiles) {
1502
- const target = path.join(params.workspaceDir, "memory", "imports", "codex", path.basename(memory.path));
1503
- const targetStat = await lstatIfExists(target);
1504
- const targetExists = targetStat !== void 0;
1505
- const targetNotRegular = targetExists && !targetStat.isFile();
1506
- if (!targetNotRegular) await assertSafeMemoryDestination({
1507
- source: memory.path,
1508
- workspaceDir: params.workspaceDir,
1509
- target
1510
- });
1511
- const targetConflict = targetNotRegular || targetExists && !params.overwrite;
1512
- items.push(createMigrationItem({
1513
- id: memory.id,
1514
- kind: "memory",
1515
- action: "copy",
1516
- source: memory.path,
1517
- target,
1518
- status: targetConflict ? "conflict" : "planned",
1519
- reason: targetNotRegular ? MIGRATION_REASON_TARGET_NOT_REGULAR : targetConflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
1520
- message: "Copy consolidated Codex memory into the OpenClaw memory index.",
1521
- details: {
1522
- sourceType: "codex-memory",
1523
- sourceLabel: memory.label,
1524
- collectionId: "codex",
1525
- collectionLabel: "Codex",
1526
- relativePath: path.basename(memory.path)
1527
- }
1528
- }));
1529
- }
1530
- return items;
1531
- }
1532
- //#endregion
1533
- //#region extensions/codex/src/migration/skill-plan.ts
1534
- function uniqueSkillName(skill, counts) {
1535
- const base = sanitizeName(skill.name) || "codex-skill";
1536
- if ((counts.get(base) ?? 0) <= 1) return base;
1537
- return sanitizeName([
1538
- "codex",
1539
- sanitizeName(path.basename(path.dirname(skill.source))),
1540
- base
1541
- ].filter(Boolean).join("-")) || base;
1542
- }
1543
- async function buildCodexSkillItems(params) {
1544
- const baseCounts = /* @__PURE__ */ new Map();
1545
- for (const skill of params.skills) {
1546
- const base = sanitizeName(skill.name) || "codex-skill";
1547
- baseCounts.set(base, (baseCounts.get(base) ?? 0) + 1);
1548
- }
1549
- const resolvedCounts = /* @__PURE__ */ new Map();
1550
- const planned = params.skills.map((skill) => {
1551
- const name = uniqueSkillName(skill, baseCounts);
1552
- resolvedCounts.set(name, (resolvedCounts.get(name) ?? 0) + 1);
1553
- return {
1554
- skill,
1555
- name,
1556
- target: path.join(params.workspaceDir, "skills", name)
1557
- };
1558
- });
1559
- const items = [];
1560
- for (const item of planned) {
1561
- const collides = (resolvedCounts.get(item.name) ?? 0) > 1;
1562
- const targetExists = await exists(item.target);
1563
- items.push(createMigrationItem({
1564
- id: `skill:${item.name}`,
1565
- kind: "skill",
1566
- action: "copy",
1567
- source: item.skill.source,
1568
- target: item.target,
1569
- status: collides ? "conflict" : targetExists && !params.overwrite ? "conflict" : "planned",
1570
- reason: collides ? `multiple Codex skills normalize to "${item.name}"` : targetExists && !params.overwrite ? MIGRATION_REASON_TARGET_EXISTS : void 0,
1571
- message: `Copy ${item.skill.sourceLabel} into this OpenClaw agent workspace.`,
1572
- details: {
1573
- skillName: item.name,
1574
- sourceLabel: item.skill.sourceLabel
1575
- }
1576
- }));
1577
- }
1578
- return items;
1579
- }
1580
- //#endregion
1581
1439
  //#region extensions/codex/src/migration/source-files.ts
1582
1440
  const SKILL_FILENAME = "SKILL.md";
1583
1441
  const MAX_SCAN_DEPTH = 6;
@@ -1618,8 +1476,6 @@ async function discoverPluginDirs(codexHome) {
1618
1476
  discovered.set(dir, {
1619
1477
  name: manifestName || path.basename(dir),
1620
1478
  source: dir,
1621
- manifestPath,
1622
- sourceKind: "cache",
1623
1479
  migratable: false,
1624
1480
  message: "Cached Codex plugin bundle found. Review manually unless the plugin is also installed in the source Codex app-server inventory"
1625
1481
  });
@@ -1643,7 +1499,7 @@ async function discoverCodexMemoryFile(candidate) {
1643
1499
  }
1644
1500
  async function discoverCodexMemorySources(codexHome) {
1645
1501
  const memoriesDir = path.join(codexHome, "memories");
1646
- const memoryFiles = (await Promise.all([{
1502
+ return (await Promise.all([{
1647
1503
  id: "memory:codex:MEMORY.md",
1648
1504
  label: "Codex consolidated memory",
1649
1505
  name: "MEMORY.md"
@@ -1656,10 +1512,6 @@ async function discoverCodexMemorySources(codexHome) {
1656
1512
  label: candidate.label,
1657
1513
  path: path.join(memoriesDir, candidate.name)
1658
1514
  })))).filter((entry) => entry !== void 0);
1659
- return {
1660
- ...await isDirectory(memoriesDir) ? { memoriesDir } : {},
1661
- memoryFiles
1662
- };
1663
1515
  }
1664
1516
  //#endregion
1665
1517
  //#region extensions/codex/src/migration/source.ts
@@ -1671,23 +1523,35 @@ function personalAgentsSkillsDir() {
1671
1523
  return path.join(resolveUserHomeDir(), ".agents", "skills");
1672
1524
  }
1673
1525
  async function discoverInstalledCuratedPlugins(codexHome, options = {}) {
1674
- const requestOptions = { startOptions: sourceCodexAppServerStartOptions(codexHome) };
1526
+ const startOptions = sourceCodexAppServerStartOptions(codexHome);
1675
1527
  try {
1676
- const marketplace = (await requestSourceCodexAppServerJson(requestOptions, {
1677
- method: "plugin/list",
1678
- requestParams: { cwds: [] }
1679
- })).marketplaces.find((entry) => entry.name === CODEX_PLUGINS_MARKETPLACE_NAME);
1680
- if (!marketplace) return {
1681
- plugins: [],
1682
- error: `Codex marketplace ${CODEX_PLUGINS_MARKETPLACE_NAME} was not found in source plugin inventory.`
1683
- };
1684
- const plugins = marketplace.plugins.filter((plugin) => plugin.installed).map((plugin) => buildInstalledPluginSource(plugin)).filter((plugin) => plugin !== void 0);
1685
- return { plugins: (options.evaluatePluginMigrationEligibility === true ? await withPluginMigrationEligibility({
1686
- plugins,
1687
- marketplace: marketplaceRef(marketplace),
1688
- requestOptions,
1689
- verifyPluginApps: options.verifyPluginApps === true
1690
- }) : plugins).toSorted((a, b) => (a.pluginName ?? a.name).localeCompare(b.pluginName ?? b.name)) };
1528
+ return await withCodexAppServerJsonClient({
1529
+ timeoutMs: 6e4,
1530
+ startOptions,
1531
+ authProfileId: null,
1532
+ isolated: true
1533
+ }, async (request) => {
1534
+ const requestOptions = {
1535
+ startOptions,
1536
+ request
1537
+ };
1538
+ const response = await request({
1539
+ method: "plugin/installed",
1540
+ requestParams: { cwds: [] }
1541
+ });
1542
+ const curatedSyncRoot = path.join(codexHome, ".tmp", "plugins");
1543
+ const curatedMarketplaceErrors = response.marketplaceLoadErrors.filter((error) => isPathInside(curatedSyncRoot, error.marketplacePath));
1544
+ if (curatedMarketplaceErrors.length > 0) return {
1545
+ plugins: [],
1546
+ error: curatedMarketplaceErrors.map((error) => error.message).join("; ")
1547
+ };
1548
+ const installed = discoverInstalledCuratedPluginSources(response);
1549
+ return { plugins: (options.evaluatePluginMigrationEligibility === true ? await withPluginMigrationEligibility({
1550
+ plugins: installed,
1551
+ requestOptions,
1552
+ verifyPluginApps: options.verifyPluginApps === true
1553
+ }) : installed.map(({ plugin }) => plugin)).toSorted((left, right) => (left.pluginName ?? left.name).localeCompare(right.pluginName ?? right.name)) };
1554
+ });
1691
1555
  } catch (error) {
1692
1556
  return {
1693
1557
  plugins: [],
@@ -1713,16 +1577,6 @@ function sourceCodexAppServerStartOptions(codexHome) {
1713
1577
  }
1714
1578
  };
1715
1579
  }
1716
- async function requestSourceCodexAppServerJson(options, params) {
1717
- return await requestCodexAppServerJson({
1718
- method: params.method,
1719
- requestParams: params.requestParams,
1720
- timeoutMs: 6e4,
1721
- startOptions: options.startOptions,
1722
- authProfileId: null,
1723
- isolated: true
1724
- });
1725
- }
1726
1580
  function buildInstalledPluginSource(plugin) {
1727
1581
  const pluginName = pluginNameFromSummary(plugin);
1728
1582
  if (!pluginName) return;
@@ -1731,12 +1585,32 @@ function buildInstalledPluginSource(plugin) {
1731
1585
  pluginName,
1732
1586
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
1733
1587
  source: `${CODEX_PLUGINS_MARKETPLACE_NAME}/${pluginName}`,
1734
- sourceKind: "app-server",
1735
1588
  migratable: true,
1736
1589
  installed: plugin.installed,
1737
1590
  enabled: plugin.enabled
1738
1591
  };
1739
1592
  }
1593
+ function discoverInstalledCuratedPluginSources(response) {
1594
+ const installedByName = /* @__PURE__ */ new Map();
1595
+ for (const marketplace of response.marketplaces) {
1596
+ if (!isOpenAiCuratedMarketplace(marketplace)) continue;
1597
+ const remote = !marketplace.path;
1598
+ for (const summary of marketplace.plugins) {
1599
+ if (!summary.installed) continue;
1600
+ const plugin = buildInstalledPluginSource(summary);
1601
+ if (!plugin?.pluginName) continue;
1602
+ const existing = installedByName.get(plugin.pluginName);
1603
+ if (existing && (!remote || existing.remote)) continue;
1604
+ installedByName.set(plugin.pluginName, {
1605
+ plugin,
1606
+ marketplace: marketplaceRef(marketplace),
1607
+ ...remote ? { readPluginName: summary.remotePluginId?.trim() || void 0 } : { readPluginName: plugin.pluginName },
1608
+ remote
1609
+ });
1610
+ }
1611
+ }
1612
+ return Array.from(installedByName.values());
1613
+ }
1740
1614
  function marketplaceRef(marketplace) {
1741
1615
  return {
1742
1616
  name: CODEX_PLUGINS_MARKETPLACE_NAME,
@@ -1747,7 +1621,7 @@ function marketplaceRef(marketplace) {
1747
1621
  async function withPluginMigrationEligibility(params) {
1748
1622
  const pending = [];
1749
1623
  const evaluated = [];
1750
- for (const plugin of params.plugins) {
1624
+ for (const { plugin, marketplace, readPluginName } of params.plugins) {
1751
1625
  if (plugin.enabled !== true) {
1752
1626
  evaluated.push({
1753
1627
  ...plugin,
@@ -1757,7 +1631,7 @@ async function withPluginMigrationEligibility(params) {
1757
1631
  });
1758
1632
  continue;
1759
1633
  }
1760
- const detail = await readPluginDetail(params.requestOptions, params.marketplace, plugin);
1634
+ const detail = await readPluginDetail(params.requestOptions, marketplace, plugin, readPluginName);
1761
1635
  if (!detail.ok) {
1762
1636
  evaluated.push({
1763
1637
  ...plugin,
@@ -1785,25 +1659,27 @@ async function withPluginMigrationEligibility(params) {
1785
1659
  }
1786
1660
  if (pending.length === 0) return evaluated;
1787
1661
  let sourceAccount;
1662
+ let sourceAccountError;
1788
1663
  try {
1789
1664
  sourceAccount = await readSourceCodexAccount(params.requestOptions);
1665
+ if (sourceAccount === "missing") sourceAccountError = "Codex app-server did not report an authenticated source account.";
1790
1666
  } catch (error) {
1791
- if (!params.verifyPluginApps) {
1792
- const message = error instanceof Error ? error.message : String(error);
1793
- for (const { plugin, apps } of pending) evaluated.push({
1794
- ...plugin,
1795
- migratable: false,
1796
- migrationBlock: {
1797
- code: "codex_account_unavailable",
1798
- apps,
1799
- error: message
1800
- },
1801
- message: `Codex plugin "${plugin.pluginName ?? plugin.name}" owns apps, but the source Codex app-server account could not be read: ${message}`
1802
- });
1803
- return evaluated;
1804
- }
1667
+ sourceAccountError = error instanceof Error ? error.message : String(error);
1805
1668
  }
1806
- if (sourceAccount && sourceAccount !== "chatgpt") {
1669
+ if (sourceAccountError && !params.verifyPluginApps) {
1670
+ for (const { plugin, apps } of pending) evaluated.push({
1671
+ ...plugin,
1672
+ migratable: false,
1673
+ migrationBlock: {
1674
+ code: "codex_account_unavailable",
1675
+ apps,
1676
+ error: sourceAccountError
1677
+ },
1678
+ message: `Codex plugin "${plugin.pluginName ?? plugin.name}" owns apps, but the source Codex app-server account could not be read: ${sourceAccountError}`
1679
+ });
1680
+ return evaluated;
1681
+ }
1682
+ if (sourceAccount === "non_chatgpt") {
1807
1683
  for (const { plugin, apps } of pending) evaluated.push({
1808
1684
  ...plugin,
1809
1685
  migratable: false,
@@ -1838,8 +1714,9 @@ async function withPluginMigrationEligibility(params) {
1838
1714
  });
1839
1715
  if (!snapshot) return evaluated;
1840
1716
  const appInfoById = new Map(snapshot.apps.map((app) => [app.id, app]));
1717
+ const installedAppsById = new Map(snapshot.installedApps.map((app) => [app.id, app]));
1841
1718
  for (const { plugin, apps: declaredApps } of pending) {
1842
- const apps = declaredApps.map((app) => sourcePluginAppFactWithInventory(app, appInfoById.get(app.id))).toSorted((left, right) => left.id.localeCompare(right.id));
1719
+ const apps = declaredApps.map((app) => sourcePluginAppFactWithInventory(app, appInfoById.get(app.id), installedAppsById.get(app.id))).toSorted((left, right) => left.id.localeCompare(right.id));
1843
1720
  const blockCode = migrationBlockCodeForApps(apps);
1844
1721
  if (!blockCode) {
1845
1722
  evaluated.push({
@@ -1862,20 +1739,29 @@ async function withPluginMigrationEligibility(params) {
1862
1739
  return evaluated;
1863
1740
  }
1864
1741
  async function readSourceCodexAccount(options) {
1865
- const response = await requestSourceCodexAppServerJson(options, {
1742
+ const response = await options.request({
1866
1743
  method: "account/read",
1867
1744
  requestParams: { refreshToken: false }
1868
1745
  });
1869
1746
  if (!response.account || typeof response.account !== "object" || Array.isArray(response.account)) return "missing";
1870
- return response.account.type === "chatgpt" ? "chatgpt" : "non_chatgpt";
1747
+ switch (response.account.type) {
1748
+ case "chatgpt": return "chatgpt";
1749
+ case "apiKey":
1750
+ case "amazonBedrock": return "non_chatgpt";
1751
+ default: return "missing";
1752
+ }
1871
1753
  }
1872
- async function readPluginDetail(options, marketplace, plugin) {
1754
+ async function readPluginDetail(options, marketplace, plugin, readPluginName) {
1755
+ if (!readPluginName) return {
1756
+ ok: false,
1757
+ error: `Codex remote plugin "${plugin.pluginName ?? plugin.name}" has no readable remote plugin id.`
1758
+ };
1873
1759
  try {
1874
1760
  return {
1875
1761
  ok: true,
1876
- detail: (await requestSourceCodexAppServerJson(options, {
1762
+ detail: (await options.request({
1877
1763
  method: "plugin/read",
1878
- requestParams: pluginReadParams(marketplace, plugin.pluginName ?? plugin.name)
1764
+ requestParams: pluginReadParams(marketplace, readPluginName)
1879
1765
  })).plugin
1880
1766
  };
1881
1767
  } catch (error) {
@@ -1887,7 +1773,7 @@ async function readPluginDetail(options, marketplace, plugin) {
1887
1773
  }
1888
1774
  async function refreshSourceAppInventory(options) {
1889
1775
  const key = buildCodexPluginAppCacheKey({ appServer: { start: options.startOptions } });
1890
- const request = async (method, requestParams) => await requestSourceCodexAppServerJson(options, {
1776
+ const request = async (method, requestParams) => await options.request({
1891
1777
  method,
1892
1778
  requestParams
1893
1779
  });
@@ -1900,16 +1786,29 @@ async function refreshSourceAppInventory(options) {
1900
1786
  function sourcePluginAppFact(app) {
1901
1787
  return {
1902
1788
  id: app.id,
1903
- name: app.name,
1904
- needsAuth: app.needsAuth
1789
+ name: app.name
1905
1790
  };
1906
1791
  }
1907
- function sourcePluginAppFactWithInventory(app, info) {
1908
- if (!info) return app;
1909
- return {
1792
+ function sourcePluginAppFactWithInventory(app, info, installedApp) {
1793
+ if (!installedApp) return app;
1794
+ if (!info) return installedApp.enabled ? {
1795
+ ...app,
1796
+ isAccessible: false,
1797
+ isEnabled: true
1798
+ } : {
1799
+ ...app,
1800
+ isEnabled: false
1801
+ };
1802
+ if (!installedApp.enabled) return {
1910
1803
  ...app,
1911
1804
  isAccessible: info.isAccessible,
1912
- isEnabled: info.isEnabled
1805
+ isEnabled: false
1806
+ };
1807
+ return {
1808
+ ...app,
1809
+ isAccessible: info.isAccessible && installedApp.callable,
1810
+ isEnabled: info.isEnabled,
1811
+ ...!installedApp.callable ? { isCallable: false } : {}
1913
1812
  };
1914
1813
  }
1915
1814
  function migrationBlockCodeForApps(apps) {
@@ -1918,7 +1817,7 @@ function migrationBlockCodeForApps(apps) {
1918
1817
  if (apps.some((app) => app.isAccessible === void 0 || app.isEnabled === void 0)) return "app_missing";
1919
1818
  }
1920
1819
  function appInventoryBlockMessage(plugin, apps, code) {
1921
- const status = code === "app_inaccessible" ? "inaccessible" : code === "app_disabled" ? "disabled" : "missing";
1820
+ const status = code === "app_inaccessible" ? apps.some((app) => app.isCallable === false) ? "not callable" : "inaccessible" : code === "app_disabled" ? "disabled" : "missing";
1922
1821
  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];
1923
1822
  const appLabel = blocking ? ` app "${blocking.name}"` : " an owned app";
1924
1823
  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.`;
@@ -1930,16 +1829,20 @@ function codexSubscriptionRequiredMessage(plugin) {
1930
1829
  return `Codex plugin "${plugin.pluginName ?? plugin.name}" owns apps, but ${codexPluginMigrationSubscriptionWarning()}`;
1931
1830
  }
1932
1831
  function pluginNameFromSummary(summary) {
1933
- const candidates = [summary.id, summary.name];
1832
+ const candidates = [summary.name, summary.id];
1934
1833
  for (const candidate of candidates) {
1935
1834
  const trimmed = candidate.trim();
1936
1835
  if (!trimmed) continue;
1937
- const normalized = ((trimmed.endsWith(`@openai-curated`) ? trimmed.slice(0, -`@${CODEX_PLUGINS_MARKETPLACE_NAME}`.length) : trimmed).split("/").at(-1)?.trim())?.toLowerCase().replaceAll(/\s+/gu, "-");
1836
+ const marketplaceSuffix = [
1837
+ `@${CODEX_PLUGINS_MARKETPLACE_NAME}-remote`,
1838
+ `@openai-api-curated`,
1839
+ `@${CODEX_PLUGINS_MARKETPLACE_NAME}`
1840
+ ].find((suffix) => trimmed.endsWith(suffix));
1841
+ const normalized = ((marketplaceSuffix ? trimmed.slice(0, -marketplaceSuffix.length) : trimmed).split("/").at(-1)?.trim())?.toLowerCase().replaceAll(/\s+/gu, "-");
1938
1842
  if (normalized) return normalized;
1939
1843
  }
1940
1844
  }
1941
- async function discoverCodexSource(inputOrOptions) {
1942
- const options = typeof inputOrOptions === "string" || inputOrOptions === void 0 ? { input: inputOrOptions } : inputOrOptions;
1845
+ async function discoverCodexSource(options = {}) {
1943
1846
  const codexHome = resolveHomePath(options.input?.trim() || defaultCodexHome());
1944
1847
  const codexSkillsDir = path.join(codexHome, "skills");
1945
1848
  const agentsSkillsDir = personalAgentsSkillsDir();
@@ -1947,7 +1850,7 @@ async function discoverCodexSource(inputOrOptions) {
1947
1850
  const authPath = path.join(codexHome, "auth.json");
1948
1851
  const modelsCachePath = path.join(codexHome, "models_cache.json");
1949
1852
  const hooksPath = path.join(codexHome, "hooks", "hooks.json");
1950
- const { memoriesDir, memoryFiles } = await discoverCodexMemorySources(codexHome);
1853
+ const memoryFiles = await discoverCodexMemorySources(codexHome);
1951
1854
  const codexSkills = options.memoryOnly ? [] : await discoverSkillDirs({
1952
1855
  root: codexSkillsDir,
1953
1856
  sourceLabel: "Codex skill",
@@ -1987,11 +1890,8 @@ async function discoverCodexSource(inputOrOptions) {
1987
1890
  codexHome,
1988
1891
  ...await isDirectory(codexSkillsDir) ? { codexSkillsDir } : {},
1989
1892
  ...await isDirectory(agentsSkillsDir) ? { personalAgentsSkillsDir: agentsSkillsDir } : {},
1990
- ...await exists(configPath) ? { configPath } : {},
1991
1893
  ...hasAuth ? { authPath } : {},
1992
1894
  ...await exists(modelsCachePath) ? { modelsCachePath } : {},
1993
- ...await exists(hooksPath) ? { hooksPath } : {},
1994
- ...memoriesDir ? { memoriesDir } : {},
1995
1895
  memoryFiles,
1996
1896
  skills,
1997
1897
  plugins,
@@ -2040,12 +1940,98 @@ const CODEX_PLUGIN_NATIVE_CONFIG_PATH = [
2040
1940
  ];
2041
1941
  const MIGRATION_REASON_PLUGIN_EXISTS = "plugin exists";
2042
1942
  const CODEX_PLUGIN_SOURCE_APP_VERIFICATION_UNVERIFIED = "not_run";
2043
- function uniquePluginConfigKey(plugin, counts, usedCounts) {
2044
- const base = sanitizeName(plugin.pluginName ?? plugin.name) || "codex-plugin";
1943
+ const MIGRATION_REASON_TARGET_NOT_REGULAR = "target is not a regular file";
1944
+ async function lstatIfExists(filePath) {
1945
+ try {
1946
+ return await fs.lstat(filePath);
1947
+ } catch (error) {
1948
+ const code = extractErrorCode(error);
1949
+ if (code === "ENOENT" || code === "ENOTDIR") return;
1950
+ throw error;
1951
+ }
1952
+ }
1953
+ async function buildCodexMemoryItems(params) {
1954
+ const items = [];
1955
+ for (const memory of params.memoryFiles) {
1956
+ const target = path.join(params.workspaceDir, "memory", "imports", "codex", path.basename(memory.path));
1957
+ const targetStat = await lstatIfExists(target);
1958
+ const targetNotRegular = targetStat !== void 0 && !targetStat.isFile();
1959
+ if (!targetNotRegular) {
1960
+ const [source, workspace, destination] = await Promise.all([
1961
+ fs.realpath(path.dirname(memory.path)),
1962
+ canonicalPathFromExistingAncestor(params.workspaceDir),
1963
+ canonicalPathFromExistingAncestor(target)
1964
+ ]);
1965
+ if (!isPathInside(workspace, destination)) throw new Error("Codex memory import destination must stay in the selected workspace.");
1966
+ if (isPathInside(source, destination) || isPathInside(destination, source)) throw new Error("Codex memory source and OpenClaw import destination must be separate paths.");
1967
+ }
1968
+ const targetConflict = targetStat !== void 0 && !params.overwrite;
1969
+ items.push(createMigrationItem({
1970
+ id: memory.id,
1971
+ kind: "memory",
1972
+ action: "copy",
1973
+ source: memory.path,
1974
+ target,
1975
+ status: targetNotRegular || targetConflict ? "conflict" : "planned",
1976
+ reason: targetNotRegular ? MIGRATION_REASON_TARGET_NOT_REGULAR : targetConflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
1977
+ message: "Copy consolidated Codex memory into the OpenClaw memory index.",
1978
+ details: {
1979
+ sourceType: "codex-memory",
1980
+ sourceLabel: memory.label,
1981
+ collectionId: "codex",
1982
+ collectionLabel: "Codex",
1983
+ relativePath: path.basename(memory.path)
1984
+ }
1985
+ }));
1986
+ }
1987
+ return items;
1988
+ }
1989
+ function uniqueSkillName(skill, counts) {
1990
+ const base = sanitizeName(skill.name) || "codex-skill";
2045
1991
  if ((counts.get(base) ?? 0) <= 1) return base;
2046
- const next = (usedCounts.get(base) ?? 0) + 1;
2047
- usedCounts.set(base, next);
2048
- return sanitizeName(`${base}-${next}`) || base;
1992
+ return sanitizeName([
1993
+ "codex",
1994
+ sanitizeName(path.basename(path.dirname(skill.source))),
1995
+ base
1996
+ ].filter(Boolean).join("-")) || base;
1997
+ }
1998
+ async function buildCodexSkillItems(params) {
1999
+ const counts = /* @__PURE__ */ new Map();
2000
+ for (const skill of params.skills) {
2001
+ const base = sanitizeName(skill.name) || "codex-skill";
2002
+ counts.set(base, (counts.get(base) ?? 0) + 1);
2003
+ }
2004
+ const planned = params.skills.map((skill) => {
2005
+ const name = uniqueSkillName(skill, counts);
2006
+ return {
2007
+ skill,
2008
+ name,
2009
+ target: path.join(params.workspaceDir, "skills", name)
2010
+ };
2011
+ });
2012
+ const resolvedCounts = planned.reduce((resolved, item) => {
2013
+ resolved.set(item.name, (resolved.get(item.name) ?? 0) + 1);
2014
+ return resolved;
2015
+ }, /* @__PURE__ */ new Map());
2016
+ return await Promise.all(planned.map(async (item) => {
2017
+ const collision = (resolvedCounts.get(item.name) ?? 0) > 1;
2018
+ const targetExists = await exists(item.target);
2019
+ const conflict = collision || targetExists && !params.overwrite;
2020
+ return createMigrationItem({
2021
+ id: `skill:${item.name}`,
2022
+ kind: "skill",
2023
+ action: "copy",
2024
+ source: item.skill.source,
2025
+ target: item.target,
2026
+ status: conflict ? "conflict" : "planned",
2027
+ reason: collision ? `multiple Codex skills normalize to "${item.name}"` : conflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
2028
+ message: `Copy ${item.skill.sourceLabel} into this OpenClaw agent workspace.`,
2029
+ details: {
2030
+ skillName: item.name,
2031
+ sourceLabel: item.skill.sourceLabel
2032
+ }
2033
+ });
2034
+ }));
2049
2035
  }
2050
2036
  function readExistingCodexPluginEntries(config) {
2051
2037
  const entries = readMigrationConfigPath(config, [...CODEX_PLUGIN_NATIVE_CONFIG_PATH, "plugins"]);
@@ -2076,18 +2062,12 @@ function readExistingPluginAllowDestructiveActions(existing, pluginName) {
2076
2062
  return normalized === "auto" || normalized === "ask" ? normalized : void 0;
2077
2063
  }
2078
2064
  function buildPluginItems(ctx, plugins) {
2079
- const baseCounts = /* @__PURE__ */ new Map();
2080
- for (const plugin of plugins.filter((entry) => entry.migratable)) {
2081
- const base = sanitizeName(plugin.pluginName ?? plugin.name) || "codex-plugin";
2082
- baseCounts.set(base, (baseCounts.get(base) ?? 0) + 1);
2083
- }
2084
2065
  const existingPluginEntries = readExistingCodexPluginEntries(ctx.config);
2085
- const usedCounts = /* @__PURE__ */ new Map();
2086
2066
  let manualIndex = 0;
2087
2067
  const items = [];
2088
2068
  for (const plugin of plugins) {
2089
2069
  if (plugin.migratable && plugin.marketplaceName === "openai-curated" && plugin.pluginName) {
2090
- const configKey = uniquePluginConfigKey(plugin, baseCounts, usedCounts);
2070
+ const configKey = plugin.pluginName;
2091
2071
  const plannedEntry = {
2092
2072
  enabled: true,
2093
2073
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
@@ -2122,12 +2102,6 @@ function buildPluginItems(ctx, plugins) {
2122
2102
  }
2123
2103
  manualIndex += 1;
2124
2104
  if (plugin.migrationBlock && plugin.pluginName) {
2125
- const details = {
2126
- pluginName: plugin.pluginName,
2127
- marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
2128
- ...plugin.migrationBlock.apps ? { apps: plugin.migrationBlock.apps } : {},
2129
- ...plugin.migrationBlock.error ? { error: plugin.migrationBlock.error } : {}
2130
- };
2131
2105
  items.push(createMigrationItem({
2132
2106
  id: `plugin:${sanitizeName(plugin.name) || sanitizeName(path.basename(plugin.source))}:${manualIndex}`,
2133
2107
  kind: "manual",
@@ -2136,7 +2110,12 @@ function buildPluginItems(ctx, plugins) {
2136
2110
  status: "skipped",
2137
2111
  reason: plugin.migrationBlock.code,
2138
2112
  message: plugin.message ?? `Codex native plugin "${plugin.name}" was found but not activated automatically.`,
2139
- details: { ...details }
2113
+ details: {
2114
+ pluginName: plugin.pluginName,
2115
+ marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
2116
+ ...plugin.migrationBlock.apps ? { apps: plugin.migrationBlock.apps } : {},
2117
+ ...plugin.migrationBlock.error ? { error: plugin.migrationBlock.error } : {}
2118
+ }
2140
2119
  }));
2141
2120
  continue;
2142
2121
  }
@@ -2174,7 +2153,6 @@ function normalizeExistingAllowDestructiveActions(value) {
2174
2153
  return asBoolean(value);
2175
2154
  }
2176
2155
  function readExistingPluginPolicyRepairs(config) {
2177
- if (config === void 0) return {};
2178
2156
  return Object.fromEntries(Object.entries(readExistingCodexPluginEntries(config)).flatMap(([configKey, entry]) => {
2179
2157
  const pluginEntry = isRecord(entry) ? entry : void 0;
2180
2158
  if (pluginEntry?.allow_destructive_actions !== "on-request") return [];
@@ -2184,9 +2162,9 @@ function readExistingPluginPolicyRepairs(config) {
2184
2162
  }]];
2185
2163
  }));
2186
2164
  }
2187
- function buildCodexPluginsConfigValue(entries, params = {}) {
2165
+ function buildCodexPluginsConfigValue(entries, config) {
2188
2166
  const plugins = {
2189
- ...readExistingPluginPolicyRepairs(params.config),
2167
+ ...readExistingPluginPolicyRepairs(config),
2190
2168
  ...Object.fromEntries(entries.toSorted((a, b) => a.configKey.localeCompare(b.configKey)).map((entry) => [entry.configKey, {
2191
2169
  enabled: entry.enabled,
2192
2170
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
@@ -2198,7 +2176,7 @@ function buildCodexPluginsConfigValue(entries, params = {}) {
2198
2176
  enabled: true,
2199
2177
  config: { codexPlugins: {
2200
2178
  enabled: true,
2201
- allow_destructive_actions: params.config === void 0 ? true : readExistingAllowDestructiveActions(params.config) ?? true,
2179
+ allow_destructive_actions: readExistingAllowDestructiveActions(config) ?? true,
2202
2180
  plugins
2203
2181
  } }
2204
2182
  };
@@ -2225,7 +2203,7 @@ function hasCodexPluginConfigConflict(config, value) {
2225
2203
  function buildPluginConfigItem(ctx, pluginItems) {
2226
2204
  const entries = pluginItems.filter((item) => item.status === "planned").map((item) => readCodexPluginMigrationConfigEntry(item, true)).filter((entry) => entry !== void 0);
2227
2205
  if (entries.length === 0) return;
2228
- const value = buildCodexPluginsConfigValue(entries, { config: ctx.config });
2206
+ const value = buildCodexPluginsConfigValue(entries, ctx.config);
2229
2207
  const conflict = !ctx.overwrite && hasCodexPluginConfigConflict(ctx.config, value);
2230
2208
  return createMigrationItem({
2231
2209
  id: CODEX_PLUGIN_CONFIG_ITEM_ID,
@@ -2351,15 +2329,9 @@ async function applyCodexMigrationPlan(params) {
2351
2329
  const targets = resolveCodexMigrationTargets(params.ctx);
2352
2330
  const codexHome = typeof plan.metadata?.codexHome === "string" && plan.metadata.codexHome.trim() ? plan.metadata.codexHome : plan.source;
2353
2331
  const authSource = {
2354
- root: plan.source,
2355
- confidence: "high",
2356
2332
  codexHome,
2357
2333
  authPath: path.join(codexHome, "auth.json"),
2358
- modelsCachePath: path.join(codexHome, "models_cache.json"),
2359
- memoryFiles: [],
2360
- skills: [],
2361
- plugins: [],
2362
- archivePaths: []
2334
+ modelsCachePath: path.join(codexHome, "models_cache.json")
2363
2335
  };
2364
2336
  const runtime = withCachedMigrationConfigRuntime(params.ctx.runtime ?? params.runtime, params.ctx.config);
2365
2337
  const applyCtx = {
@@ -2372,20 +2344,13 @@ async function applyCodexMigrationPlan(params) {
2372
2344
  continue;
2373
2345
  }
2374
2346
  if (item.id === "config:codex-plugins") items.push(await applyCodexPluginConfigItem(applyCtx, item, items));
2375
- else if (item.kind === "auth") {
2376
- const authItem = await applyCodexAuthItem({
2377
- ctx: applyCtx,
2378
- item,
2379
- source: authSource,
2380
- targets
2381
- });
2382
- items.push(authItem);
2383
- items.push(...await buildCodexAuthConfigPatchItems({
2384
- ctx: applyCtx,
2385
- item: authItem,
2386
- source: authSource
2387
- }));
2388
- } else if (item.kind === "plugin" && item.action === "install") items.push(await applyCodexPluginInstallItem(applyCtx, item));
2347
+ else if (item.kind === "auth") items.push(...await applyCodexAuthItems({
2348
+ ctx: applyCtx,
2349
+ item,
2350
+ source: authSource,
2351
+ targets
2352
+ }));
2353
+ else if (item.kind === "plugin" && item.action === "install") items.push(await applyCodexPluginInstallItem(applyCtx, item));
2389
2354
  else if (item.kind === "manual") items.push(applyMigrationManualItem(item));
2390
2355
  else if (item.action === "archive") items.push(await archiveMigrationItem(item, reportDir));
2391
2356
  else if (item.kind === "memory") items.push(await copyMemoryMigrationFileItem(item, reportDir, {
@@ -2576,7 +2541,7 @@ async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
2576
2541
  const configApi = resolveMigrationConfigRuntime(ctx);
2577
2542
  const currentConfig = returnPatch ? ctx.config : configApi?.current?.();
2578
2543
  if (!currentConfig) return markMigrationItemError(item, "config runtime unavailable");
2579
- const value = buildCodexPluginsConfigValue(entries, { config: currentConfig });
2544
+ const value = buildCodexPluginsConfigValue(entries, currentConfig);
2580
2545
  if (!ctx.overwrite && hasCodexPluginConfigConflict(currentConfig, value)) return markMigrationItemConflict(item, MIGRATION_REASON_TARGET_EXISTS);
2581
2546
  const migratedItem = {
2582
2547
  ...item,
@@ -2609,17 +2574,15 @@ function isCodexPluginConfigTerminal(item) {
2609
2574
  }
2610
2575
  function readAppliedPluginConfigEntry(item) {
2611
2576
  if (item.status === "migrated" || item.deferredCompletion === true) return readCodexPluginMigrationConfigEntry(item, true);
2612
- if (item.status === "skipped" && item.reason !== CODEX_PLUGIN_NOT_SELECTED_REASON && item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON) return readCodexPluginMigrationConfigEntry(item, false);
2577
+ if (item.status === "skipped" && item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON) return readCodexPluginMigrationConfigEntry(item, false);
2613
2578
  }
2614
2579
  function readCodexPluginPolicy(item) {
2615
- const configKey = item.details?.configKey;
2616
- const marketplaceName = item.details?.marketplaceName;
2617
- const pluginName = item.details?.pluginName;
2618
- if (typeof configKey !== "string" || marketplaceName !== "openai-curated" || typeof pluginName !== "string") return;
2580
+ const entry = readCodexPluginMigrationConfigEntry(item, true);
2581
+ if (!entry) return;
2619
2582
  return {
2620
- configKey,
2583
+ configKey: entry.configKey,
2621
2584
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
2622
- pluginName,
2585
+ pluginName: entry.pluginName,
2623
2586
  enabled: true,
2624
2587
  allowDestructiveActions: true,
2625
2588
  destructiveApprovalMode: "allow"
@@ -2833,7 +2796,7 @@ function createCodexThreadsTool(options) {
2833
2796
  return {
2834
2797
  name: "codex_threads",
2835
2798
  label: "Codex Threads",
2836
- description: "List and inspect native Codex threads. When supervision is enabled, raw transcript reads and every mutation require their matching supervision policy option.",
2799
+ description: "Manage native Codex threads: list, read, fork, rename, archive (confirm:true), unarchive. When supervision is enabled, raw transcript reads and every mutation require their matching supervision policy option.",
2837
2800
  parameters: CodexThreadsParamsSchema,
2838
2801
  async execute(_toolCallId, rawParams) {
2839
2802
  const params = asRecord$1(rawParams);
@@ -3758,7 +3721,7 @@ function createCodexSupervisionTools(options) {
3758
3721
  }
3759
3722
  //#endregion
3760
3723
  //#region extensions/codex/src/web-search-provider.ts
3761
- const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-Bx6HAc_k.js"));
3724
+ const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-CCFhg2z5.js"));
3762
3725
  const CodexWebSearchSchema = {
3763
3726
  type: "object",
3764
3727
  properties: { query: {
@@ -3812,7 +3775,7 @@ var codex_default = definePluginEntry({
3812
3775
  origin: "bundled",
3813
3776
  config: normalizePluginsConfig(liveConfig.plugins),
3814
3777
  rootConfig: liveConfig,
3815
- enabledByDefault: readCodexPluginConfig(livePluginConfig).supervision?.enabled === true
3778
+ enabledByDefault: livePluginConfig !== void 0
3816
3779
  }).enabled) return;
3817
3780
  return livePluginConfig;
3818
3781
  };
@@ -3948,7 +3911,7 @@ var codex_default = definePluginEntry({
3948
3911
  if (!previousSessionId || !sessionId || previousSessionId === sessionId) return;
3949
3912
  const config = resolveCurrentConfig();
3950
3913
  const sessionKey = ctx.sessionKey?.trim();
3951
- const { sessionBindingIdentity } = await import("./session-binding-ZSMX1omP.js").then((n) => n.u);
3914
+ const { sessionBindingIdentity } = await import("./session-binding-BXpo9ymA.js").then((n) => n.f);
3952
3915
  const identity = sessionBindingIdentity({
3953
3916
  sessionId,
3954
3917
  ...sessionKey ? { sessionKey } : {},
@@ -3964,8 +3927,9 @@ var codex_default = definePluginEntry({
3964
3927
  const endedSessionKey = sessionKey?.trim();
3965
3928
  const nextSessionKey = event.nextSessionKey?.trim();
3966
3929
  if (endedSessionKey && nextSessionKey && nextSessionKey !== endedSessionKey) return;
3930
+ if (event.nextSessionId?.trim() === event.sessionId.trim()) return;
3967
3931
  const config = resolveCurrentConfig();
3968
- const { sessionBindingIdentity } = await import("./session-binding-ZSMX1omP.js").then((n) => n.u);
3932
+ const { sessionBindingIdentity } = await import("./session-binding-BXpo9ymA.js").then((n) => n.f);
3969
3933
  await bindingStore.retireSessionGeneration(sessionBindingIdentity({
3970
3934
  sessionId: event.sessionId,
3971
3935
  ...sessionKey ? { sessionKey } : {},