@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.
- package/dist/{app-server-policy-BO3jYBkv.js → app-server-policy-BmDgseo_.js} +1 -1
- package/dist/attempt-client-cleanup-Ia52yRWc.js +127 -0
- package/dist/{attempt-notifications-DdmnBMUp.js → attempt-notifications-CMR2_fmR.js} +1 -1
- package/dist/{bounded-turn-CaQL96kg.js → bounded-turn-FEbUXoYT.js} +36 -13
- package/dist/{capabilities-CLICvTxf.js → capabilities-BHRSI6Cn.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-DgADqnHa.js → command-formatters-ico4ZFnk.js} +2 -2
- package/dist/{command-handlers-l_lVPNlB.js → command-handlers-CRmnwI2N.js} +1232 -1221
- package/dist/{compact-CC5KhBzX.js → compact-dEN49UH6.js} +7 -7
- package/dist/{computer-use-Ip1-QGa-.js → computer-use-BjGylO-E.js} +16 -6
- package/dist/{conversation-control-sNPsbTCP.js → conversation-control-DE7d9DOj.js} +6 -6
- package/dist/doctor-contract-api.js +24 -86
- package/dist/{dynamic-tools-CQI3UwqY.js → dynamic-tools-LIt9ojep.js} +50 -46
- package/dist/{event-projector-usage-D6tE7_qD.js → event-projector-usage-tvgb1NCX.js} +2 -2
- package/dist/harness.js +14 -13
- package/dist/index.js +208 -267
- package/dist/media-understanding-provider.js +6 -1
- package/dist/{models-BNeMlHgg.js → models-BA01NEez.js} +2 -2
- package/dist/{notification-correlation-BGLixv5_.js → notification-correlation-Bj_Ak_jI.js} +3 -3
- package/dist/{plugin-app-cache-key-CvzvmBRz.js → plugin-app-cache-key-DSXX-rXO.js} +5 -5
- package/dist/{transcript-mirror-2p7kl6e4.js → protocol-validators-Dm4eXZmt.js} +2 -550
- package/dist/{rate-limits-D0IJT-a6.js → rate-limits-S_PXs0ul.js} +1 -1
- package/dist/realtime-voice-api-BPcA1uN9.js +494 -0
- package/dist/realtime-voice-api.js +2 -0
- package/dist/{request-BTccUTD3.js → request-CXpPennK.js} +1 -1
- package/dist/{run-attempt--858NXDl.js → run-attempt-C5GTPJOE.js} +417 -237
- package/dist/{session-binding-ZSMX1omP.js → session-binding-DlVQ-Pxs.js} +952 -890
- package/dist/{session-catalog-DsKaezgR.js → session-catalog-CP2oCcEb.js} +32 -23
- package/dist/{session-cli-CYJTfRLG.js → session-cli-CqZ0Fp2a.js} +2 -2
- package/dist/{session-upstream-marker-D7XlI9us.js → session-upstream-marker-QE-m5QFG.js} +1 -1
- package/dist/{settled-turn-finalizer-DHltNgtF.js → settled-turn-finalizer-CA_2QXIE.js} +2 -2
- package/dist/{shared-client-wmgNFNYp.js → shared-client-BVKE40c-.js} +1863 -1707
- package/dist/{side-question-BfFZCsJ-.js → side-question-CO12sHxo.js} +11 -9
- package/dist/{thread-lifecycle-cqrOlJkq.js → thread-lifecycle-DRg_FdzC.js} +12 -132
- package/dist/transcript-mirror-uKA-A4tB.js +550 -0
- package/dist/{upstream-session-fork-vPjwkT1i.js → upstream-session-fork-_Vrz4WJr.js} +3 -3
- package/dist/{usage-DM_I3mPT.js → usage-UpVbdX5G.js} +3 -3
- package/dist/{web-search-provider.runtime-Bx6HAc_k.js → web-search-provider.runtime-CaQMYDbp.js} +3 -3
- package/package.json +4 -5
- 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,24 @@
|
|
|
1
1
|
import { registerCodexCliMetadata } from "./cli-metadata.js";
|
|
2
2
|
import { createCodexAppServerAgentHarness } from "./harness.js";
|
|
3
|
-
import {
|
|
4
|
-
import { D as
|
|
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
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
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-
|
|
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-
|
|
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-
|
|
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 {
|
|
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-
|
|
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-
|
|
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 =
|
|
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
|
|
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
|
-
...
|
|
1315
|
-
...
|
|
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
|
|
1348
|
-
const profile =
|
|
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) =>
|
|
1320
|
+
return applyCodexAuthProfileConfig(ctx, profile, (config) => applyCredentialConfig(config, credential, profileId));
|
|
1351
1321
|
}
|
|
1352
|
-
|
|
1353
|
-
return
|
|
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
|
|
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" :
|
|
1428
|
-
if (configResult === "conflict") return markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS);
|
|
1429
|
-
|
|
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
|
-
|
|
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);
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
2044
|
-
|
|
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
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
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 =
|
|
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: {
|
|
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,
|
|
2114
|
+
function buildCodexPluginsConfigValue(entries, config) {
|
|
2188
2115
|
const plugins = {
|
|
2189
|
-
...readExistingPluginPolicyRepairs(
|
|
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:
|
|
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,
|
|
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
|
-
|
|
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));
|
|
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,
|
|
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
|
|
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
|
|
2616
|
-
|
|
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: "
|
|
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-
|
|
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:
|
|
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-
|
|
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-
|
|
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 } : {},
|