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

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 (41) hide show
  1. package/dist/{app-server-policy-BO3jYBkv.js → app-server-policy-BmDgseo_.js} +1 -1
  2. package/dist/attempt-client-cleanup-Ia52yRWc.js +127 -0
  3. package/dist/{attempt-notifications-DdmnBMUp.js → attempt-notifications-CMR2_fmR.js} +1 -1
  4. package/dist/{bounded-turn-CaQL96kg.js → bounded-turn-FEbUXoYT.js} +36 -13
  5. package/dist/{capabilities-CLICvTxf.js → capabilities-BHRSI6Cn.js} +1 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-DgADqnHa.js → command-formatters-ico4ZFnk.js} +2 -2
  8. package/dist/{command-handlers-l_lVPNlB.js → command-handlers-CRmnwI2N.js} +1232 -1221
  9. package/dist/{compact-CC5KhBzX.js → compact-dEN49UH6.js} +7 -7
  10. package/dist/{computer-use-Ip1-QGa-.js → computer-use-BjGylO-E.js} +16 -6
  11. package/dist/{conversation-control-sNPsbTCP.js → conversation-control-DE7d9DOj.js} +6 -6
  12. package/dist/doctor-contract-api.js +24 -86
  13. package/dist/{dynamic-tools-CQI3UwqY.js → dynamic-tools-LIt9ojep.js} +50 -46
  14. package/dist/{event-projector-usage-D6tE7_qD.js → event-projector-usage-tvgb1NCX.js} +2 -2
  15. package/dist/harness.js +14 -13
  16. package/dist/index.js +208 -267
  17. package/dist/media-understanding-provider.js +6 -1
  18. package/dist/{models-BNeMlHgg.js → models-BA01NEez.js} +2 -2
  19. package/dist/{notification-correlation-BGLixv5_.js → notification-correlation-Bj_Ak_jI.js} +3 -3
  20. package/dist/{plugin-app-cache-key-CvzvmBRz.js → plugin-app-cache-key-DSXX-rXO.js} +5 -5
  21. package/dist/{transcript-mirror-2p7kl6e4.js → protocol-validators-Dm4eXZmt.js} +2 -550
  22. package/dist/{rate-limits-D0IJT-a6.js → rate-limits-S_PXs0ul.js} +1 -1
  23. package/dist/realtime-voice-api-BPcA1uN9.js +494 -0
  24. package/dist/realtime-voice-api.js +2 -0
  25. package/dist/{request-BTccUTD3.js → request-CXpPennK.js} +1 -1
  26. package/dist/{run-attempt--858NXDl.js → run-attempt-C5GTPJOE.js} +417 -237
  27. package/dist/{session-binding-ZSMX1omP.js → session-binding-DlVQ-Pxs.js} +952 -890
  28. package/dist/{session-catalog-DsKaezgR.js → session-catalog-CP2oCcEb.js} +32 -23
  29. package/dist/{session-cli-CYJTfRLG.js → session-cli-CqZ0Fp2a.js} +2 -2
  30. package/dist/{session-upstream-marker-D7XlI9us.js → session-upstream-marker-QE-m5QFG.js} +1 -1
  31. package/dist/{settled-turn-finalizer-DHltNgtF.js → settled-turn-finalizer-CA_2QXIE.js} +2 -2
  32. package/dist/{shared-client-wmgNFNYp.js → shared-client-BVKE40c-.js} +1863 -1707
  33. package/dist/{side-question-BfFZCsJ-.js → side-question-CO12sHxo.js} +11 -9
  34. package/dist/{thread-lifecycle-cqrOlJkq.js → thread-lifecycle-DRg_FdzC.js} +12 -132
  35. package/dist/transcript-mirror-uKA-A4tB.js +550 -0
  36. package/dist/{upstream-session-fork-vPjwkT1i.js → upstream-session-fork-_Vrz4WJr.js} +3 -3
  37. package/dist/{usage-DM_I3mPT.js → usage-UpVbdX5G.js} +3 -3
  38. package/dist/{web-search-provider.runtime-Bx6HAc_k.js → web-search-provider.runtime-CaQMYDbp.js} +3 -3
  39. package/package.json +4 -5
  40. package/npm-shrinkwrap.json +0 -202
  41. package/dist/{auth-binding-C1czuHPA.js → auth-binding-B4FfbcCg.js} +1 -1
package/dist/index.js CHANGED
@@ -1,22 +1,24 @@
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 { N as resolveCodexAppServerAuthProfileIdForAgent, P as resolveCodexAppServerFallbackApiKeyCacheKey, R as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, V as isJsonObject, a as getLeasedSharedCodexAppServerClient, c as releaseCodexAppServerClientLease, j as resolveCodexAppServerAuthAccountCacheKey, l as releaseLeasedSharedCodexAppServerClient, m as withLeasedCodexAppServerClientStartSelectionRetry, r as clearSharedCodexAppServerClientIfCurrentAndWait } from "./shared-client-BVKE40c-.js";
4
+ import { D as resolveOpenClawExecPolicyForCodexAppServer, T as readCodexPluginConfig, _ as assertCodexAppServerConnectionSecurity, b as canUseCodexModelBackedApprovalsReviewerForModel, d as codexAppServerStartOptionsKey, f as codexSandboxPolicyForTurn, g as resolveCodexSupervisionAppServerRuntimeOptions, k as CODEX_PLUGINS_MARKETPLACE_NAME, l as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, p as resolveCodexAppServerRuntimeOptions, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-DlVQ-Pxs.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 { n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, u as unsubscribeCodexThreadBestEffort } from "./attempt-client-cleanup-Ia52yRWc.js";
7
+ import { J as pluginReadParams, _ as CODEX_NATIVE_PERSONALITY_NONE, c as resumeCodexAppServerThread, q as ensureCodexPluginActivation, y as resolveCodexAppServerRequestModelSelection } from "./thread-lifecycle-DRg_FdzC.js";
8
+ import { i as assertCodexThreadStartResponse } from "./protocol-validators-Dm4eXZmt.js";
9
+ import { i as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DSXX-rXO.js";
9
10
  import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
10
11
  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";
12
+ import { n as CODEX_REALTIME_OFFER_PATH, t as configureCodexRealtimeBrowserSession } from "./realtime-voice-api-BPcA1uN9.js";
13
+ import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-BHRSI6Cn.js";
14
+ import { r as formatCodexDisplayText } from "./command-formatters-ico4ZFnk.js";
15
+ import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-BmDgseo_.js";
14
16
  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";
17
+ import { d as CODEX_NATIVE_EXECUTION_AUTH_ERROR, f as canMutateCodexHost, u as trackCodexConversationActiveTurn } from "./conversation-control-DE7d9DOj.js";
16
18
  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";
19
+ import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-Bj_Ak_jI.js";
20
+ 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-CP2oCcEb.js";
21
+ import { r as requestCodexAppServerJson } from "./request-CXpPennK.js";
20
22
  import { t as createCodexWebSearchProviderBase } from "./web-search-provider.shared-BrZmlqyR.js";
21
23
  import { mutateConfigFile } from "openclaw/plugin-sdk/config-mutation";
22
24
  import { normalizePluginsConfig, resolveEffectiveEnableState, resolveLivePluginConfigObject, resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
@@ -24,19 +26,19 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
24
26
  import fs from "node:fs/promises";
25
27
  import path from "node:path";
26
28
  import { parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
29
+ import { formatErrorMessage, resolveSandboxContext } from "openclaw/plugin-sdk/agent-harness-runtime";
30
+ import { loadAuthProfileStoreWithoutExternalProfiles, resolveAgentConfig, resolveAgentWorkspaceDir, resolveDefaultAgentDir, resolveDefaultAgentId, resolveSessionAgentIds as resolveSessionAgentIds$1 } from "openclaw/plugin-sdk/agent-runtime";
27
31
  import os from "node:os";
28
- import { loadAuthProfileStoreWithoutExternalProfiles, resolveAgentConfig, resolveAgentWorkspaceDir, resolveDefaultAgentDir, resolveDefaultAgentId, resolveSessionAgentIds } from "openclaw/plugin-sdk/agent-runtime";
32
+ import { applyAuthProfileConfig, buildApiKeyCredential, buildOauthProviderAuthResult, buildOpenAICodexCredentialExtra, readCodexCliCredentialsCached, resolveOpenAICodexAuthIdentity, resolveOpenAICodexImportProfileName, updateAuthProfileStoreWithLock } from "openclaw/plugin-sdk/provider-auth";
29
33
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
30
34
  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
35
  import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
34
36
  import { fileURLToPath } from "node:url";
35
37
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
36
- import { canonicalPathFromExistingAncestor, isPathInside, pathExists } from "openclaw/plugin-sdk/security-runtime";
38
+ import { canonicalPathFromExistingAncestor, extractErrorCode, isPathInside, pathExists } from "openclaw/plugin-sdk/security-runtime";
37
39
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
38
40
  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";
41
+ import { MIGRATION_REASON_TARGET_EXISTS, applyMigrationManualItem, createMigrationItem, createMigrationManualItem, hasMigrationConfigPatchConflict, markMigrationItemConflict, markMigrationItemError, markMigrationItemSkipped, mergeMigrationConfigValue, readMigrationConfigPath, resolveMigrationConfigRuntime, summarizeMigrationItems, writeMigrationConfigPath } from "openclaw/plugin-sdk/migration";
40
42
  import { archiveMigrationItem, copyMemoryMigrationFileItem, copyMigrationFileItem, withCachedMigrationConfigRuntime, writeMigrationReport } from "openclaw/plugin-sdk/migration-runtime";
41
43
  import { sleep } from "openclaw/plugin-sdk/runtime-env";
42
44
  import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
@@ -47,13 +49,14 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
47
49
  /** Defers schema compilation and auth loading until the first binding operation. */
48
50
  function createLazyCodexAppServerBindingStore(state) {
49
51
  let resolved;
50
- const store = () => resolved ??= import("./session-binding-ZSMX1omP.js").then((n) => n.u).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
52
+ const store = () => resolved ??= import("./session-binding-DlVQ-Pxs.js").then((n) => n.u).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
51
53
  return {
52
54
  read: async (identity) => (await store()).read(identity),
53
55
  hasOtherThreadOwner: async (threadId, currentIdentity) => (await store()).hasOtherThreadOwner(threadId, currentIdentity),
54
56
  mutate: async (identity, mutation) => (await store()).mutate(identity, mutation),
55
57
  prepareSessionGenerationReclaim: async (identity) => (await store()).prepareSessionGenerationReclaim(identity),
56
58
  adoptSessionGeneration: async (identity, previousSessionId) => (await store()).adoptSessionGeneration(identity, previousSessionId),
59
+ resetSessionGeneration: async (identity) => (await store()).resetSessionGeneration(identity),
57
60
  retireSessionGeneration: async (identity) => (await store()).retireSessionGeneration(identity),
58
61
  withThreadArchiveFence: async (run) => (await store()).withThreadArchiveFence(run),
59
62
  withLease: async (identity, run) => (await store()).withLease(identity, run)
@@ -74,7 +77,7 @@ async function handleCodexCommand(ctx, options) {
74
77
  }
75
78
  }
76
79
  async function loadDefaultCodexSubcommandHandler() {
77
- const { handleCodexSubcommand } = await import("./command-handlers-l_lVPNlB.js");
80
+ const { handleCodexSubcommand } = await import("./command-handlers-CRmnwI2N.js");
78
81
  return handleCodexSubcommand;
79
82
  }
80
83
  //#endregion
@@ -937,7 +940,7 @@ async function prepareConversationBinding(params, options = {}) {
937
940
  });
938
941
  }
939
942
  function resolveConversationExecPolicy(params) {
940
- const agentId = params.agentId ?? (params.config ? resolveSessionAgentIds({
943
+ const agentId = params.agentId ?? (params.config ? resolveSessionAgentIds$1({
941
944
  sessionKey: params.sessionKey,
942
945
  config: params.config
943
946
  }).sessionAgentId : void 0);
@@ -1138,11 +1141,6 @@ async function readModelRefs(source) {
1138
1141
  refs.add(OPENAI_CODEX_DEFAULT_MODEL);
1139
1142
  return [...refs].toSorted();
1140
1143
  }
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
1144
  async function buildCodexOAuthCredential(source) {
1147
1145
  const credential = readCodexCliCredentialsCached({
1148
1146
  codexHome: source.codexHome,
@@ -1177,8 +1175,7 @@ async function buildCodexOAuthCredential(source) {
1177
1175
  kind: "oauth",
1178
1176
  provider: OPENAI_PROVIDER_ID,
1179
1177
  profileId: profile.profileId,
1180
- result,
1181
- modelConfigs: readProviderAuthModelConfigs(result)
1178
+ result
1182
1179
  } : null;
1183
1180
  }
1184
1181
  async function buildCodexApiKeyCredential(source) {
@@ -1257,30 +1254,8 @@ function applyDefaultModelIfMissing(cfg) {
1257
1254
  }
1258
1255
  };
1259
1256
  }
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
1257
  function applyOAuthConfigToConfig(cfg, credential, profileId) {
1283
- let next = applyOAuthModelConfigsToConfig(cfg, credential);
1258
+ let next = mergeMigrationConfigValue(cfg, credential.result.configPatch);
1284
1259
  const profile = credential.result.profiles[0];
1285
1260
  if (profile) next = applyAuthProfileConfig(next, {
1286
1261
  profileId,
@@ -1304,28 +1279,23 @@ function applyApiKeyConfigToConfig(cfg, credential, profileId) {
1304
1279
  function shouldReturnAuthConfigPatch(ctx) {
1305
1280
  return ctx.providerOptions?.configPatchMode === CODEX_CONFIG_PATCH_MODE_RETURN$1;
1306
1281
  }
1307
- function oauthAuthProfileConfig(credential, profileId) {
1282
+ function authProfileConfigForCredential(credential, profileId) {
1283
+ if (credential.kind === "api_key") return {
1284
+ profileId,
1285
+ provider: credential.provider,
1286
+ mode: "api_key",
1287
+ displayName: CODEX_IMPORT_DISPLAY_NAME
1288
+ };
1308
1289
  const profile = credential.result.profiles[0];
1309
1290
  if (!profile || profile.credential.type !== "oauth") return null;
1310
1291
  return {
1311
1292
  profileId,
1312
1293
  provider: profile.credential.provider,
1313
1294
  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 } : {}
1295
+ ...profile.credential.email ? { email: profile.credential.email } : {},
1296
+ ...profile.credential.displayName ? { displayName: profile.credential.displayName } : {}
1316
1297
  };
1317
1298
  }
1318
- function apiKeyAuthProfileConfig(credential, profileId) {
1319
- return {
1320
- profileId,
1321
- provider: credential.provider,
1322
- mode: "api_key",
1323
- displayName: CODEX_IMPORT_DISPLAY_NAME
1324
- };
1325
- }
1326
- function authProfileConfigForCredential(credential, profileId) {
1327
- return credential.kind === "oauth" ? oauthAuthProfileConfig(credential, profileId) : apiKeyAuthProfileConfig(credential, profileId);
1328
- }
1329
1299
  async function applyCodexAuthProfileConfig(ctx, profile, applyConfig) {
1330
1300
  const configApi = resolveMigrationConfigRuntime(ctx);
1331
1301
  if (!configApi?.current || !configApi.mutateConfigFile) return "unavailable";
@@ -1344,13 +1314,13 @@ async function applyCodexAuthProfileConfig(ctx, profile, applyConfig) {
1344
1314
  return error instanceof CodexAuthConfigConflict ? "conflict" : "unavailable";
1345
1315
  }
1346
1316
  }
1347
- async function applyOAuthConfig(ctx, credential, profileId) {
1348
- const profile = oauthAuthProfileConfig(credential, profileId);
1317
+ async function applyCodexAuthConfig(ctx, credential, profileId) {
1318
+ const profile = authProfileConfigForCredential(credential, profileId);
1349
1319
  if (!profile) return "unavailable";
1350
- return applyCodexAuthProfileConfig(ctx, profile, (config) => applyOAuthConfigToConfig(config, credential, profileId));
1320
+ return applyCodexAuthProfileConfig(ctx, profile, (config) => applyCredentialConfig(config, credential, profileId));
1351
1321
  }
1352
- async function applyApiKeyConfig(ctx, credential, profileId) {
1353
- return applyCodexAuthProfileConfig(ctx, apiKeyAuthProfileConfig(credential, profileId), (config) => applyApiKeyConfigToConfig(config, credential, profileId));
1322
+ function applyCredentialConfig(config, credential, profileId) {
1323
+ return credential.kind === "oauth" ? applyOAuthConfigToConfig(config, credential, profileId) : applyApiKeyConfigToConfig(config, credential, profileId);
1354
1324
  }
1355
1325
  async function buildCodexAuthItems(params) {
1356
1326
  const credentials = await readCodexAuthCredentials(params.source);
@@ -1383,22 +1353,22 @@ async function buildCodexAuthItems(params) {
1383
1353
  });
1384
1354
  });
1385
1355
  }
1386
- async function applyCodexAuthItem(params) {
1356
+ async function applyCodexAuthItems(params) {
1387
1357
  const { ctx, item, source, targets } = params;
1388
- if (item.status !== "planned") return item;
1358
+ if (item.status !== "planned") return [item];
1389
1359
  const profileId = typeof item.details?.profileId === "string" ? item.details.profileId : "";
1390
1360
  const provider = typeof item.details?.provider === "string" ? item.details.provider : "";
1391
1361
  const sourceProfileId = typeof item.details?.sourceProfileId === "string" ? item.details.sourceProfileId : void 0;
1392
- if (!profileId || !provider) return markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA);
1362
+ if (!profileId || !provider) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
1393
1363
  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);
1364
+ if (!credential) return [markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT)];
1365
+ if (credential.kind === "oauth" && sourceProfileId && credential.profileId !== sourceProfileId) return [markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT)];
1396
1366
  const oauthProfile = credential.kind === "oauth" ? credential.result.profiles[0] : void 0;
1397
1367
  const oauthCredential = oauthProfile?.credential.type === "oauth" ? oauthProfile.credential : void 0;
1398
- if (credential.kind === "oauth" && !oauthCredential) return markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA);
1368
+ if (credential.kind === "oauth" && !oauthCredential) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
1399
1369
  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);
1370
+ if (!configProfile) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
1371
+ if (hasCurrentAuthProfileConfigConflict(ctx, configProfile)) return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
1402
1372
  let conflicted = false;
1403
1373
  let wrote = false;
1404
1374
  const store = await updateAuthProfileStoreWithLock({
@@ -1422,11 +1392,11 @@ async function applyCodexAuthItem(params) {
1422
1392
  return true;
1423
1393
  }
1424
1394
  });
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 {
1395
+ if (conflicted) return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
1396
+ if (!store?.profiles[profileId]) return [markMigrationItemError(item, CODEX_REASON_AUTH_PROFILE_WRITE_FAILED)];
1397
+ const configResult = shouldReturnAuthConfigPatch(ctx) ? "unavailable" : await applyCodexAuthConfig(ctx, credential, profileId);
1398
+ if (configResult === "conflict") return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
1399
+ const migratedItem = {
1430
1400
  ...item,
1431
1401
  status: "migrated",
1432
1402
  details: {
@@ -1436,18 +1406,10 @@ async function applyCodexAuthItem(params) {
1436
1406
  ...shouldReturnAuthConfigPatch(ctx) ? { configPatchReturned: true } : {}
1437
1407
  }
1438
1408
  };
1409
+ return [migratedItem, ...shouldReturnAuthConfigPatch(ctx) ? buildCodexAuthConfigPatchItems(ctx, migratedItem, credential, profileId) : []];
1439
1410
  }
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);
1411
+ function buildCodexAuthConfigPatchItems(ctx, item, credential, profileId) {
1412
+ const next = applyCredentialConfig(ctx.config, credential, profileId);
1451
1413
  const items = [];
1452
1414
  if (next.auth) items.push(createMigrationItem({
1453
1415
  id: `${item.id}:config:auth`,
@@ -1476,108 +1438,6 @@ async function buildCodexAuthConfigPatchItems(params) {
1476
1438
  return items;
1477
1439
  }
1478
1440
  //#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
1441
  //#region extensions/codex/src/migration/source-files.ts
1582
1442
  const SKILL_FILENAME = "SKILL.md";
1583
1443
  const MAX_SCAN_DEPTH = 6;
@@ -1618,8 +1478,6 @@ async function discoverPluginDirs(codexHome) {
1618
1478
  discovered.set(dir, {
1619
1479
  name: manifestName || path.basename(dir),
1620
1480
  source: dir,
1621
- manifestPath,
1622
- sourceKind: "cache",
1623
1481
  migratable: false,
1624
1482
  message: "Cached Codex plugin bundle found. Review manually unless the plugin is also installed in the source Codex app-server inventory"
1625
1483
  });
@@ -1643,7 +1501,7 @@ async function discoverCodexMemoryFile(candidate) {
1643
1501
  }
1644
1502
  async function discoverCodexMemorySources(codexHome) {
1645
1503
  const memoriesDir = path.join(codexHome, "memories");
1646
- const memoryFiles = (await Promise.all([{
1504
+ return (await Promise.all([{
1647
1505
  id: "memory:codex:MEMORY.md",
1648
1506
  label: "Codex consolidated memory",
1649
1507
  name: "MEMORY.md"
@@ -1656,10 +1514,6 @@ async function discoverCodexMemorySources(codexHome) {
1656
1514
  label: candidate.label,
1657
1515
  path: path.join(memoriesDir, candidate.name)
1658
1516
  })))).filter((entry) => entry !== void 0);
1659
- return {
1660
- ...await isDirectory(memoriesDir) ? { memoriesDir } : {},
1661
- memoryFiles
1662
- };
1663
1517
  }
1664
1518
  //#endregion
1665
1519
  //#region extensions/codex/src/migration/source.ts
@@ -1731,7 +1585,6 @@ 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
@@ -1938,8 +1791,7 @@ function pluginNameFromSummary(summary) {
1938
1791
  if (normalized) return normalized;
1939
1792
  }
1940
1793
  }
1941
- async function discoverCodexSource(inputOrOptions) {
1942
- const options = typeof inputOrOptions === "string" || inputOrOptions === void 0 ? { input: inputOrOptions } : inputOrOptions;
1794
+ async function discoverCodexSource(options = {}) {
1943
1795
  const codexHome = resolveHomePath(options.input?.trim() || defaultCodexHome());
1944
1796
  const codexSkillsDir = path.join(codexHome, "skills");
1945
1797
  const agentsSkillsDir = personalAgentsSkillsDir();
@@ -1947,7 +1799,7 @@ async function discoverCodexSource(inputOrOptions) {
1947
1799
  const authPath = path.join(codexHome, "auth.json");
1948
1800
  const modelsCachePath = path.join(codexHome, "models_cache.json");
1949
1801
  const hooksPath = path.join(codexHome, "hooks", "hooks.json");
1950
- const { memoriesDir, memoryFiles } = await discoverCodexMemorySources(codexHome);
1802
+ const memoryFiles = await discoverCodexMemorySources(codexHome);
1951
1803
  const codexSkills = options.memoryOnly ? [] : await discoverSkillDirs({
1952
1804
  root: codexSkillsDir,
1953
1805
  sourceLabel: "Codex skill",
@@ -1987,11 +1839,8 @@ async function discoverCodexSource(inputOrOptions) {
1987
1839
  codexHome,
1988
1840
  ...await isDirectory(codexSkillsDir) ? { codexSkillsDir } : {},
1989
1841
  ...await isDirectory(agentsSkillsDir) ? { personalAgentsSkillsDir: agentsSkillsDir } : {},
1990
- ...await exists(configPath) ? { configPath } : {},
1991
1842
  ...hasAuth ? { authPath } : {},
1992
1843
  ...await exists(modelsCachePath) ? { modelsCachePath } : {},
1993
- ...await exists(hooksPath) ? { hooksPath } : {},
1994
- ...memoriesDir ? { memoriesDir } : {},
1995
1844
  memoryFiles,
1996
1845
  skills,
1997
1846
  plugins,
@@ -2040,12 +1889,98 @@ const CODEX_PLUGIN_NATIVE_CONFIG_PATH = [
2040
1889
  ];
2041
1890
  const MIGRATION_REASON_PLUGIN_EXISTS = "plugin exists";
2042
1891
  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";
1892
+ const MIGRATION_REASON_TARGET_NOT_REGULAR = "target is not a regular file";
1893
+ async function lstatIfExists(filePath) {
1894
+ try {
1895
+ return await fs.lstat(filePath);
1896
+ } catch (error) {
1897
+ const code = extractErrorCode(error);
1898
+ if (code === "ENOENT" || code === "ENOTDIR") return;
1899
+ throw error;
1900
+ }
1901
+ }
1902
+ async function buildCodexMemoryItems(params) {
1903
+ const items = [];
1904
+ for (const memory of params.memoryFiles) {
1905
+ const target = path.join(params.workspaceDir, "memory", "imports", "codex", path.basename(memory.path));
1906
+ const targetStat = await lstatIfExists(target);
1907
+ const targetNotRegular = targetStat !== void 0 && !targetStat.isFile();
1908
+ if (!targetNotRegular) {
1909
+ const [source, workspace, destination] = await Promise.all([
1910
+ fs.realpath(path.dirname(memory.path)),
1911
+ canonicalPathFromExistingAncestor(params.workspaceDir),
1912
+ canonicalPathFromExistingAncestor(target)
1913
+ ]);
1914
+ if (!isPathInside(workspace, destination)) throw new Error("Codex memory import destination must stay in the selected workspace.");
1915
+ if (isPathInside(source, destination) || isPathInside(destination, source)) throw new Error("Codex memory source and OpenClaw import destination must be separate paths.");
1916
+ }
1917
+ const targetConflict = targetStat !== void 0 && !params.overwrite;
1918
+ items.push(createMigrationItem({
1919
+ id: memory.id,
1920
+ kind: "memory",
1921
+ action: "copy",
1922
+ source: memory.path,
1923
+ target,
1924
+ status: targetNotRegular || targetConflict ? "conflict" : "planned",
1925
+ reason: targetNotRegular ? MIGRATION_REASON_TARGET_NOT_REGULAR : targetConflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
1926
+ message: "Copy consolidated Codex memory into the OpenClaw memory index.",
1927
+ details: {
1928
+ sourceType: "codex-memory",
1929
+ sourceLabel: memory.label,
1930
+ collectionId: "codex",
1931
+ collectionLabel: "Codex",
1932
+ relativePath: path.basename(memory.path)
1933
+ }
1934
+ }));
1935
+ }
1936
+ return items;
1937
+ }
1938
+ function uniqueSkillName(skill, counts) {
1939
+ const base = sanitizeName(skill.name) || "codex-skill";
2045
1940
  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;
1941
+ return sanitizeName([
1942
+ "codex",
1943
+ sanitizeName(path.basename(path.dirname(skill.source))),
1944
+ base
1945
+ ].filter(Boolean).join("-")) || base;
1946
+ }
1947
+ async function buildCodexSkillItems(params) {
1948
+ const counts = /* @__PURE__ */ new Map();
1949
+ for (const skill of params.skills) {
1950
+ const base = sanitizeName(skill.name) || "codex-skill";
1951
+ counts.set(base, (counts.get(base) ?? 0) + 1);
1952
+ }
1953
+ const planned = params.skills.map((skill) => {
1954
+ const name = uniqueSkillName(skill, counts);
1955
+ return {
1956
+ skill,
1957
+ name,
1958
+ target: path.join(params.workspaceDir, "skills", name)
1959
+ };
1960
+ });
1961
+ const resolvedCounts = planned.reduce((resolved, item) => {
1962
+ resolved.set(item.name, (resolved.get(item.name) ?? 0) + 1);
1963
+ return resolved;
1964
+ }, /* @__PURE__ */ new Map());
1965
+ return await Promise.all(planned.map(async (item) => {
1966
+ const collision = (resolvedCounts.get(item.name) ?? 0) > 1;
1967
+ const targetExists = await exists(item.target);
1968
+ const conflict = collision || targetExists && !params.overwrite;
1969
+ return createMigrationItem({
1970
+ id: `skill:${item.name}`,
1971
+ kind: "skill",
1972
+ action: "copy",
1973
+ source: item.skill.source,
1974
+ target: item.target,
1975
+ status: conflict ? "conflict" : "planned",
1976
+ reason: collision ? `multiple Codex skills normalize to "${item.name}"` : conflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
1977
+ message: `Copy ${item.skill.sourceLabel} into this OpenClaw agent workspace.`,
1978
+ details: {
1979
+ skillName: item.name,
1980
+ sourceLabel: item.skill.sourceLabel
1981
+ }
1982
+ });
1983
+ }));
2049
1984
  }
2050
1985
  function readExistingCodexPluginEntries(config) {
2051
1986
  const entries = readMigrationConfigPath(config, [...CODEX_PLUGIN_NATIVE_CONFIG_PATH, "plugins"]);
@@ -2076,18 +2011,12 @@ function readExistingPluginAllowDestructiveActions(existing, pluginName) {
2076
2011
  return normalized === "auto" || normalized === "ask" ? normalized : void 0;
2077
2012
  }
2078
2013
  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
2014
  const existingPluginEntries = readExistingCodexPluginEntries(ctx.config);
2085
- const usedCounts = /* @__PURE__ */ new Map();
2086
2015
  let manualIndex = 0;
2087
2016
  const items = [];
2088
2017
  for (const plugin of plugins) {
2089
2018
  if (plugin.migratable && plugin.marketplaceName === "openai-curated" && plugin.pluginName) {
2090
- const configKey = uniquePluginConfigKey(plugin, baseCounts, usedCounts);
2019
+ const configKey = plugin.pluginName;
2091
2020
  const plannedEntry = {
2092
2021
  enabled: true,
2093
2022
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
@@ -2122,12 +2051,6 @@ function buildPluginItems(ctx, plugins) {
2122
2051
  }
2123
2052
  manualIndex += 1;
2124
2053
  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
2054
  items.push(createMigrationItem({
2132
2055
  id: `plugin:${sanitizeName(plugin.name) || sanitizeName(path.basename(plugin.source))}:${manualIndex}`,
2133
2056
  kind: "manual",
@@ -2136,7 +2059,12 @@ function buildPluginItems(ctx, plugins) {
2136
2059
  status: "skipped",
2137
2060
  reason: plugin.migrationBlock.code,
2138
2061
  message: plugin.message ?? `Codex native plugin "${plugin.name}" was found but not activated automatically.`,
2139
- details: { ...details }
2062
+ details: {
2063
+ pluginName: plugin.pluginName,
2064
+ marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
2065
+ ...plugin.migrationBlock.apps ? { apps: plugin.migrationBlock.apps } : {},
2066
+ ...plugin.migrationBlock.error ? { error: plugin.migrationBlock.error } : {}
2067
+ }
2140
2068
  }));
2141
2069
  continue;
2142
2070
  }
@@ -2174,7 +2102,6 @@ function normalizeExistingAllowDestructiveActions(value) {
2174
2102
  return asBoolean(value);
2175
2103
  }
2176
2104
  function readExistingPluginPolicyRepairs(config) {
2177
- if (config === void 0) return {};
2178
2105
  return Object.fromEntries(Object.entries(readExistingCodexPluginEntries(config)).flatMap(([configKey, entry]) => {
2179
2106
  const pluginEntry = isRecord(entry) ? entry : void 0;
2180
2107
  if (pluginEntry?.allow_destructive_actions !== "on-request") return [];
@@ -2184,9 +2111,9 @@ function readExistingPluginPolicyRepairs(config) {
2184
2111
  }]];
2185
2112
  }));
2186
2113
  }
2187
- function buildCodexPluginsConfigValue(entries, params = {}) {
2114
+ function buildCodexPluginsConfigValue(entries, config) {
2188
2115
  const plugins = {
2189
- ...readExistingPluginPolicyRepairs(params.config),
2116
+ ...readExistingPluginPolicyRepairs(config),
2190
2117
  ...Object.fromEntries(entries.toSorted((a, b) => a.configKey.localeCompare(b.configKey)).map((entry) => [entry.configKey, {
2191
2118
  enabled: entry.enabled,
2192
2119
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
@@ -2198,7 +2125,7 @@ function buildCodexPluginsConfigValue(entries, params = {}) {
2198
2125
  enabled: true,
2199
2126
  config: { codexPlugins: {
2200
2127
  enabled: true,
2201
- allow_destructive_actions: params.config === void 0 ? true : readExistingAllowDestructiveActions(params.config) ?? true,
2128
+ allow_destructive_actions: readExistingAllowDestructiveActions(config) ?? true,
2202
2129
  plugins
2203
2130
  } }
2204
2131
  };
@@ -2225,7 +2152,7 @@ function hasCodexPluginConfigConflict(config, value) {
2225
2152
  function buildPluginConfigItem(ctx, pluginItems) {
2226
2153
  const entries = pluginItems.filter((item) => item.status === "planned").map((item) => readCodexPluginMigrationConfigEntry(item, true)).filter((entry) => entry !== void 0);
2227
2154
  if (entries.length === 0) return;
2228
- const value = buildCodexPluginsConfigValue(entries, { config: ctx.config });
2155
+ const value = buildCodexPluginsConfigValue(entries, ctx.config);
2229
2156
  const conflict = !ctx.overwrite && hasCodexPluginConfigConflict(ctx.config, value);
2230
2157
  return createMigrationItem({
2231
2158
  id: CODEX_PLUGIN_CONFIG_ITEM_ID,
@@ -2351,15 +2278,9 @@ async function applyCodexMigrationPlan(params) {
2351
2278
  const targets = resolveCodexMigrationTargets(params.ctx);
2352
2279
  const codexHome = typeof plan.metadata?.codexHome === "string" && plan.metadata.codexHome.trim() ? plan.metadata.codexHome : plan.source;
2353
2280
  const authSource = {
2354
- root: plan.source,
2355
- confidence: "high",
2356
2281
  codexHome,
2357
2282
  authPath: path.join(codexHome, "auth.json"),
2358
- modelsCachePath: path.join(codexHome, "models_cache.json"),
2359
- memoryFiles: [],
2360
- skills: [],
2361
- plugins: [],
2362
- archivePaths: []
2283
+ modelsCachePath: path.join(codexHome, "models_cache.json")
2363
2284
  };
2364
2285
  const runtime = withCachedMigrationConfigRuntime(params.ctx.runtime ?? params.runtime, params.ctx.config);
2365
2286
  const applyCtx = {
@@ -2372,20 +2293,13 @@ async function applyCodexMigrationPlan(params) {
2372
2293
  continue;
2373
2294
  }
2374
2295
  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));
2296
+ else if (item.kind === "auth") items.push(...await applyCodexAuthItems({
2297
+ ctx: applyCtx,
2298
+ item,
2299
+ source: authSource,
2300
+ targets
2301
+ }));
2302
+ else if (item.kind === "plugin" && item.action === "install") items.push(await applyCodexPluginInstallItem(applyCtx, item));
2389
2303
  else if (item.kind === "manual") items.push(applyMigrationManualItem(item));
2390
2304
  else if (item.action === "archive") items.push(await archiveMigrationItem(item, reportDir));
2391
2305
  else if (item.kind === "memory") items.push(await copyMemoryMigrationFileItem(item, reportDir, {
@@ -2576,7 +2490,7 @@ async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
2576
2490
  const configApi = resolveMigrationConfigRuntime(ctx);
2577
2491
  const currentConfig = returnPatch ? ctx.config : configApi?.current?.();
2578
2492
  if (!currentConfig) return markMigrationItemError(item, "config runtime unavailable");
2579
- const value = buildCodexPluginsConfigValue(entries, { config: currentConfig });
2493
+ const value = buildCodexPluginsConfigValue(entries, currentConfig);
2580
2494
  if (!ctx.overwrite && hasCodexPluginConfigConflict(currentConfig, value)) return markMigrationItemConflict(item, MIGRATION_REASON_TARGET_EXISTS);
2581
2495
  const migratedItem = {
2582
2496
  ...item,
@@ -2609,17 +2523,15 @@ function isCodexPluginConfigTerminal(item) {
2609
2523
  }
2610
2524
  function readAppliedPluginConfigEntry(item) {
2611
2525
  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);
2526
+ if (item.status === "skipped" && item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON) return readCodexPluginMigrationConfigEntry(item, false);
2613
2527
  }
2614
2528
  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;
2529
+ const entry = readCodexPluginMigrationConfigEntry(item, true);
2530
+ if (!entry) return;
2619
2531
  return {
2620
- configKey,
2532
+ configKey: entry.configKey,
2621
2533
  marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
2622
- pluginName,
2534
+ pluginName: entry.pluginName,
2623
2535
  enabled: true,
2624
2536
  allowDestructiveActions: true,
2625
2537
  destructiveApprovalMode: "allow"
@@ -2833,7 +2745,7 @@ function createCodexThreadsTool(options) {
2833
2745
  return {
2834
2746
  name: "codex_threads",
2835
2747
  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.",
2748
+ 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
2749
  parameters: CodexThreadsParamsSchema,
2838
2750
  async execute(_toolCallId, rawParams) {
2839
2751
  const params = asRecord$1(rawParams);
@@ -3758,7 +3670,7 @@ function createCodexSupervisionTools(options) {
3758
3670
  }
3759
3671
  //#endregion
3760
3672
  //#region extensions/codex/src/web-search-provider.ts
3761
- const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-Bx6HAc_k.js"));
3673
+ const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-CaQMYDbp.js"));
3762
3674
  const CodexWebSearchSchema = {
3763
3675
  type: "object",
3764
3676
  properties: { query: {
@@ -3812,11 +3724,39 @@ var codex_default = definePluginEntry({
3812
3724
  origin: "bundled",
3813
3725
  config: normalizePluginsConfig(liveConfig.plugins),
3814
3726
  rootConfig: liveConfig,
3815
- enabledByDefault: readCodexPluginConfig(livePluginConfig).supervision?.enabled === true
3727
+ enabledByDefault: livePluginConfig !== void 0
3816
3728
  }).enabled) return;
3817
3729
  return livePluginConfig;
3818
3730
  };
3819
3731
  const resolveCurrentPluginConfig = () => resolvePluginConfig(resolveCurrentConfig);
3732
+ if (api.registrationMode === "full") {
3733
+ const realtimeBrowserSession = configureCodexRealtimeBrowserSession({
3734
+ getConfig: resolveCurrentConfig,
3735
+ getPluginConfig: resolveCurrentPluginConfig
3736
+ });
3737
+ api.registerHttpRoute({
3738
+ path: CODEX_REALTIME_OFFER_PATH,
3739
+ auth: "plugin",
3740
+ match: "exact",
3741
+ handler: realtimeBrowserSession.handler
3742
+ });
3743
+ api.registerService({
3744
+ id: "codex-oauth-realtime-browser-session-warmup",
3745
+ start: () => {
3746
+ realtimeBrowserSession.warmup().catch((error) => {
3747
+ api.logger.debug?.(`Codex OAuth realtime warmup unavailable: ${error instanceof Error ? error.message : String(error)}`);
3748
+ });
3749
+ }
3750
+ });
3751
+ api.lifecycle.registerRuntimeLifecycle({
3752
+ id: "codex-oauth-realtime-browser-session",
3753
+ description: "Release Codex OAuth realtime browser sessions when the plugin stops",
3754
+ cleanup: async ({ reason }) => {
3755
+ if (reason === "reset" || reason === "delete") return;
3756
+ await realtimeBrowserSession.cleanup();
3757
+ }
3758
+ });
3759
+ }
3820
3760
  let bindingStateStore;
3821
3761
  const openBindingStateStore = () => bindingStateStore ??= api.runtime.state.openSyncKeyedStore({
3822
3762
  namespace: CODEX_APP_SERVER_BINDING_NAMESPACE,
@@ -3948,7 +3888,7 @@ var codex_default = definePluginEntry({
3948
3888
  if (!previousSessionId || !sessionId || previousSessionId === sessionId) return;
3949
3889
  const config = resolveCurrentConfig();
3950
3890
  const sessionKey = ctx.sessionKey?.trim();
3951
- const { sessionBindingIdentity } = await import("./session-binding-ZSMX1omP.js").then((n) => n.u);
3891
+ const { sessionBindingIdentity } = await import("./session-binding-DlVQ-Pxs.js").then((n) => n.u);
3952
3892
  const identity = sessionBindingIdentity({
3953
3893
  sessionId,
3954
3894
  ...sessionKey ? { sessionKey } : {},
@@ -3964,8 +3904,9 @@ var codex_default = definePluginEntry({
3964
3904
  const endedSessionKey = sessionKey?.trim();
3965
3905
  const nextSessionKey = event.nextSessionKey?.trim();
3966
3906
  if (endedSessionKey && nextSessionKey && nextSessionKey !== endedSessionKey) return;
3907
+ if (event.nextSessionId?.trim() === event.sessionId.trim()) return;
3967
3908
  const config = resolveCurrentConfig();
3968
- const { sessionBindingIdentity } = await import("./session-binding-ZSMX1omP.js").then((n) => n.u);
3909
+ const { sessionBindingIdentity } = await import("./session-binding-DlVQ-Pxs.js").then((n) => n.u);
3969
3910
  await bindingStore.retireSessionGeneration(sessionBindingIdentity({
3970
3911
  sessionId: event.sessionId,
3971
3912
  ...sessionKey ? { sessionKey } : {},