@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.
- package/dist/{app-server-policy-BO3jYBkv.js → app-server-policy-BSaO2JIT.js} +1 -1
- package/dist/{attempt-notifications-DdmnBMUp.js → attempt-notifications-AP-a-Q5k.js} +1 -1
- package/dist/{bounded-turn-CaQL96kg.js → bounded-turn-D2ZAgZVz.js} +54 -24
- package/dist/{capabilities-CLICvTxf.js → capabilities-BFDTVYr4.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-DgADqnHa.js → command-formatters-C336eRVS.js} +2 -2
- package/dist/{command-handlers-l_lVPNlB.js → command-handlers-DAHUSry9.js} +1233 -1222
- package/dist/{compact-CC5KhBzX.js → compact-D_uvHurS.js} +8 -8
- package/dist/{computer-use-Ip1-QGa-.js → computer-use-CYEc8U3w.js} +123 -115
- package/dist/{conversation-control-sNPsbTCP.js → conversation-control-xsIeXbo4.js} +6 -6
- package/dist/doctor-contract-api.js +24 -86
- package/dist/{dynamic-tools-CQI3UwqY.js → dynamic-tools-D2gYkSBO.js} +482 -91
- package/dist/effective-mcp-catalog-Bbd98Inw.js +114 -0
- package/dist/{event-projector-usage-D6tE7_qD.js → event-projector-usage-Xp4AlR2k.js} +20 -3
- package/dist/harness.js +19 -14
- package/dist/index.js +292 -328
- package/dist/media-understanding-provider.js +6 -1
- package/dist/{models-BNeMlHgg.js → models-BBMKU4jA.js} +2 -2
- package/dist/{notification-correlation-BGLixv5_.js → notification-correlation-CU6_AnOb.js} +3 -3
- package/dist/{plugin-app-cache-key-CvzvmBRz.js → plugin-app-cache-key-DztPafOA.js} +135 -42
- package/dist/{rate-limits-D0IJT-a6.js → rate-limits-CU-gVCCS.js} +1 -1
- package/dist/{request-BTccUTD3.js → request-qKh331yu.js} +3 -3
- package/dist/{run-attempt--858NXDl.js → run-attempt-CY9WlDLc.js} +1060 -402
- package/dist/{runtime-artifact-C2ITXdhM.js → runtime-artifact-CmtG_t1L.js} +90 -24
- package/dist/{sandbox-guard-D1Wky__S.js → sandbox-guard-NuhpXmPB.js} +4 -0
- package/dist/{session-binding-ZSMX1omP.js → session-binding-BXpo9ymA.js} +1006 -891
- package/dist/{session-catalog-DsKaezgR.js → session-catalog-DyOgR4WH.js} +289 -56
- package/dist/{session-cli-CYJTfRLG.js → session-cli-2PZaFLRh.js} +2 -2
- package/dist/{session-upstream-marker-D7XlI9us.js → session-upstream-marker-B6U7tLw5.js} +1 -1
- package/dist/{settled-turn-finalizer-DHltNgtF.js → settled-turn-finalizer-CXY2Z9dT.js} +19 -6
- package/dist/{shared-client-wmgNFNYp.js → shared-client-DTbvH-XV.js} +1993 -1720
- package/dist/{side-question-BfFZCsJ-.js → side-question-_ulBk1AL.js} +12 -10
- package/dist/{thread-lifecycle-cqrOlJkq.js → thread-lifecycle-DF53ogiA.js} +980 -346
- package/dist/{transcript-mirror-2p7kl6e4.js → transcript-mirror-DzsdNCf5.js} +80 -41
- package/dist/{upstream-session-fork-vPjwkT1i.js → upstream-session-fork-Dy4Xvuoj.js} +3 -3
- package/dist/{usage-DM_I3mPT.js → usage-CQ6GhD5-.js} +3 -3
- package/dist/{web-search-provider.runtime-Bx6HAc_k.js → web-search-provider.runtime-CCFhg2z5.js} +3 -3
- package/package.json +6 -8
- package/npm-shrinkwrap.json +0 -202
- 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 {
|
|
4
|
-
import {
|
|
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-
|
|
12
|
-
import { r as formatCodexDisplayText } from "./command-formatters-
|
|
13
|
-
import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-
|
|
14
|
-
import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-
|
|
15
|
-
import { d as CODEX_NATIVE_EXECUTION_AUTH_ERROR, f as canMutateCodexHost, u as trackCodexConversationActiveTurn } from "./conversation-control-
|
|
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-
|
|
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-
|
|
19
|
-
import { r as requestCodexAppServerJson } from "./request-
|
|
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 {
|
|
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-
|
|
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-
|
|
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:
|
|
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 =
|
|
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
|
|
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
|
-
...
|
|
1315
|
-
...
|
|
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
|
|
1348
|
-
const profile =
|
|
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) =>
|
|
1318
|
+
return applyCodexAuthProfileConfig(ctx, profile, (config) => applyCredentialConfig(config, credential, profileId));
|
|
1351
1319
|
}
|
|
1352
|
-
|
|
1353
|
-
return
|
|
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
|
|
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" :
|
|
1428
|
-
if (configResult === "conflict") return markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS);
|
|
1429
|
-
|
|
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
|
-
|
|
1441
|
-
const
|
|
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
|
-
|
|
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
|
|
1526
|
+
const startOptions = sourceCodexAppServerStartOptions(codexHome);
|
|
1675
1527
|
try {
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
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,
|
|
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
|
-
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
|
1762
|
+
detail: (await options.request({
|
|
1877
1763
|
method: "plugin/read",
|
|
1878
|
-
requestParams: pluginReadParams(marketplace,
|
|
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
|
|
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 (!
|
|
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:
|
|
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.
|
|
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
|
|
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(
|
|
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
|
|
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
|
-
|
|
2044
|
-
|
|
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
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
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 =
|
|
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: {
|
|
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,
|
|
2165
|
+
function buildCodexPluginsConfigValue(entries, config) {
|
|
2188
2166
|
const plugins = {
|
|
2189
|
-
...readExistingPluginPolicyRepairs(
|
|
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:
|
|
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,
|
|
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
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
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,
|
|
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
|
|
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
|
|
2616
|
-
|
|
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: "
|
|
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-
|
|
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:
|
|
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-
|
|
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-
|
|
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 } : {},
|