@openclaw/codex 2026.9.1 → 2026.9.3
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/README.md +2 -0
- package/dist/api.js +18 -23
- package/dist/apply-B6el6hdO.js +357 -0
- package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-D6cR54TV.js} +113 -49
- package/dist/{attempt-context-DmQUNWwT.js → attempt-context-AO4DSjE0.js} +11 -9
- package/dist/{event-projector-usage-C5mcrGjp.js → attempt-notifications--H8zXR5-.js} +3 -89
- package/dist/auth-cache-key-Kq6oerr6.js +498 -0
- package/dist/auth-profile-CwzO4_RG.js +43 -0
- package/dist/auth-profile-selection-DFu9e167.js +45 -0
- package/dist/{binding-connection-E6uDsPlx.js → binding-connection-QqgcPCgk.js} +18 -3
- package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-lRpmZHFv.js} +54 -150
- package/dist/build-state-6RL6qohz.js +19 -0
- package/dist/{capabilities-dIjNVCYH.js → capabilities-BeqLPbtM.js} +2 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-BEKu4yDx.js +3983 -0
- package/dist/command-dispatch-CisT9Jqq.js +21 -0
- package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DeTfrapr.js} +2 -2
- package/dist/{command-handlers-CTGb2csu.js → command-handlers-BfIsJEuA.js} +158 -76
- package/dist/command-rpc-BMqRQOFX.js +226 -0
- package/dist/{compact-_t0HQrUS.js → compact-CGJZ2rlb.js} +89 -49
- package/dist/config-JDfTI4VI.js +106 -0
- package/dist/{config-BhmfC1s6.js → config-options-jnIFvwxD.js} +208 -654
- package/dist/config-runtime-BWf6JLWG.js +11 -0
- package/dist/config-utils-C57JiJrU.js +69 -0
- package/dist/conversation-binding-CxOlHiix.js +889 -0
- package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → conversation-control-CUCrSIQI.js} +36 -155
- package/dist/doctor-contract-api.js +8 -9
- package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-D-JBoaLt.js} +734 -698
- package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-J_5Ep5Um.js} +4 -3
- package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
- package/dist/ephemeral-turn-DSwzP8YY.js +101 -0
- package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-BmBM4qBV.js} +23 -27
- package/dist/event-projector-usage-CIyrYYid.js +102 -0
- package/dist/{harness-DXVZ5II5.js → harness-FR6eQgyO.js} +47 -17
- package/dist/harness.js +1 -1
- package/dist/history-rejection-B4nOXNXF.js +13 -0
- package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
- package/dist/incognito-session-uhrBF6wJ.js +15 -0
- package/dist/index.js +413 -2893
- package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-DHBefrzg.js} +12 -21
- package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DrjjRRUD.js} +17 -84
- package/dist/managed-thread-store-D1t5jh3G.js +66 -0
- package/dist/media-understanding-provider.js +4 -1
- package/dist/{model-catalog-CUM68Hkl.js → model-catalog-B_6M04Wo.js} +6 -5
- package/dist/{models-sYnEc0gd.js → models-P9k2qAof.js} +4 -4
- package/dist/native-execution-policy-umd0tgh4.js +128 -0
- package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-BbCUKRwC.js} +76 -48
- package/dist/node-cli-sessions-rj0ysJwM.js +527 -0
- package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-BY_ctYnT.js} +54 -23
- package/dist/plan-BMJdMOEF.js +711 -0
- package/dist/plugin-activation-BQK-f5sV.js +133 -0
- package/dist/{thread-resume-C7pyVKeW.js → plugin-app-cache-key-CdSQzWyX.js} +5 -53
- package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-DeW95wB5.js} +1 -1
- package/dist/plugin-inventory-CoRCzWW4.js +325 -0
- package/dist/plugin-marketplace-discovery-3akBizzF.js +134 -0
- package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-DgNfRAGA.js} +13 -9
- package/dist/protocol-CAAcVIKF.js +275 -0
- package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-W4tfK5Y5.js} +2 -2
- package/dist/{rate-limits-CawQJfUS.js → rate-limits-Bqnx1N4z.js} +1 -1
- package/dist/request-CGvGOpeR.js +198 -0
- package/dist/{run-attempt-D1hJO4fX.js → run-attempt-DwKds3DN.js} +1498 -1028
- package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-T-NwqeSH.js} +28 -28
- package/dist/sandbox-guard-BcT66fWy.js +165 -0
- package/dist/{session-binding-BHuTCRZQ.js → session-binding-CKSepwIC.js} +118 -324
- package/dist/session-binding-record-CaZjYwNS.js +256 -0
- package/dist/session-catalog-HaDcp7Sv.js +1533 -0
- package/dist/session-catalog-adoption-BKLtSrwi.js +251 -0
- package/dist/session-catalog-archive-D0i2pGj2.js +56 -0
- package/dist/session-catalog-home-id-D7-aLiNt.js +190 -0
- package/dist/session-catalog-node-adoption-BUuDYY8R.js +182 -0
- package/dist/session-catalog-node-continue-CBtc4wkI.js +238 -0
- package/dist/session-catalog-parsing-CdD3JhdM.js +280 -0
- package/dist/session-catalog-provenance-DkJHo735.js +124 -0
- package/dist/{session-cli-CmFEXMAM.js → session-cli-CbgaHh0f.js} +3 -2
- package/dist/session-history-Cz-tOOYj.js +96 -0
- package/dist/{session-upstream-marker-C351-5Qw.js → session-history-import-DFN7sWRU.js} +5 -49
- package/dist/session-history-read-cxPUxyVV.js +50 -0
- package/dist/session-history-worker-runtime.js +60 -0
- package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-CNEvGaU5.js} +75 -69
- package/dist/session-history.worker.js +2 -0
- package/dist/{session-initialization-BeWzjGiR.js → session-initialization-Jo86C60I.js} +2 -1
- package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-B22InTp_.js} +4 -7
- package/dist/{session-retirement-BujDjXVF.js → session-retirement-BSNG_mhf.js} +8 -7
- package/dist/session-upstream-marker-D15C9NHp.js +46 -0
- package/dist/settled-turn-context-Du6gdUDd.js +45 -0
- package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BuLUrZl2.js} +54 -42
- package/dist/shared-client-CVhez2Uo.js +2911 -0
- package/dist/{side-question-BTZAII4l.js → side-question-DLbr2vUU.js} +135 -191
- package/dist/source-Da-h6f7e.js +518 -0
- package/dist/thread-archive-guard-D1bP04Tf.js +53 -0
- package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-D1pzRwHB.js} +467 -977
- package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-D6oASVRu.js} +15 -17
- package/dist/{thread-policy-g4KbJPzp.js → thread-policy-D8kI7yAO.js} +2 -2
- package/dist/thread-resume-T5cveyxA.js +52 -0
- package/dist/timeout-BVw8aaM1.js +33 -0
- package/dist/transcript-mirror-attestation-DibE0krH.js +89 -0
- package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-t5TOccct.js} +111 -379
- package/dist/{transport-stdio-CyPldczm.js → transport-stdio-BGjHoYLr.js} +80 -48
- package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-De-sLJ2r.js} +94 -166
- package/dist/{usage-Bj-rrzkR.js → usage-CPPTmBvZ.js} +4 -3
- package/dist/version-omm6IPI3.js +12 -0
- package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-CSVgQL0w.js} +3 -3
- package/openclaw.plugin.json +22 -1
- package/package.json +6 -6
- package/dist/request-DYAI5FQE.js +0 -475
- package/dist/session-catalog-yyvTWFOw.js +0 -3120
- package/dist/session-history-C5J1AKzG.js +0 -87
- package/dist/shared-client-DxcfF9KX.js +0 -7494
- package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-Co2Vfcf_.js} +1 -1
package/README.md
CHANGED
|
@@ -34,4 +34,6 @@ For a supervised branch, Codex App Server selects the snapshot fork's model and
|
|
|
34
34
|
|
|
35
35
|
The visible-history mirror keeps at most 200 user or assistant messages, 512 KiB total, and 64 KiB per message. Image inputs become `[Image attachment]`; image data and local paths are not copied.
|
|
36
36
|
|
|
37
|
+
When settled-turn recovery rejects history, the `codex settled-turn finalization context capture failed` warning includes a stable `reason`, such as `item_limit`, `byte_limit`, `field_limit`, `unsupported_user_image`, or `snapshot_invalidated`. Unknown failures use `history_read_failed`. The warning excludes transcript content and exception text. Rejected history remains unavailable for finalization, and completed actions are never replayed.
|
|
38
|
+
|
|
37
39
|
See the [Codex harness](https://docs.openclaw.ai/plugins/codex-harness) and [Codex supervision](https://docs.openclaw.ai/plugins/codex-supervision) guides.
|
package/dist/api.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import { a as resolveCodexAppServerStartOptionsForAgent
|
|
2
|
-
import { n as resolveManagedCodexAppServerStartOptions,
|
|
1
|
+
import { a as resolveCodexAppServerStartOptionsForAgent } from "./config-options-jnIFvwxD.js";
|
|
2
|
+
import { n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-DrjjRRUD.js";
|
|
3
|
+
import { t as CODEX_APP_SERVER_VERSION } from "./version-omm6IPI3.js";
|
|
4
|
+
import "./config-JDfTI4VI.js";
|
|
5
|
+
import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-BWf6JLWG.js";
|
|
6
|
+
import { listAgentIds, resolveAgentDir } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
3
7
|
import path from "node:path";
|
|
4
|
-
import { resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
|
|
5
|
-
import { listAgentIds as listAgentIds$1, resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
6
8
|
import { execFile } from "node:child_process";
|
|
7
9
|
import { fileURLToPath } from "node:url";
|
|
10
|
+
import { promisify } from "node:util";
|
|
11
|
+
import { resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
|
|
8
12
|
import { resolveEffectiveAgentRuntime } from "openclaw/plugin-sdk/command-auth-native";
|
|
9
13
|
//#region extensions/codex/src/doctor.ts
|
|
10
14
|
const CODEX_MANAGED_APP_SERVER_CHECK_ID = "codex/managed-app-server";
|
|
11
15
|
const CODEX_VERSION_TIMEOUT_MS = 5e3;
|
|
12
16
|
const CODEX_VERSION_MAX_BUFFER_BYTES = 65536;
|
|
17
|
+
const execFileAsync = promisify(execFile);
|
|
13
18
|
function managedCodexFinding(params) {
|
|
14
19
|
return {
|
|
15
20
|
checkId: CODEX_MANAGED_APP_SERVER_CHECK_ID,
|
|
@@ -28,22 +33,12 @@ function parseCodexVersion(output) {
|
|
|
28
33
|
return /(?:^|\s)(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)(?:\s|$)/u.exec(output)?.[1];
|
|
29
34
|
}
|
|
30
35
|
function runVersionCommand(command) {
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}, (error, stdout, stderr) => {
|
|
38
|
-
if (error) {
|
|
39
|
-
reject(new Error(readErrorMessage(error), { cause: error }));
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
resolve({
|
|
43
|
-
stdout,
|
|
44
|
-
stderr
|
|
45
|
-
});
|
|
46
|
-
});
|
|
36
|
+
return execFileAsync(command, ["--version"], {
|
|
37
|
+
encoding: "utf8",
|
|
38
|
+
maxBuffer: CODEX_VERSION_MAX_BUFFER_BYTES,
|
|
39
|
+
timeout: CODEX_VERSION_TIMEOUT_MS,
|
|
40
|
+
killSignal: "SIGKILL",
|
|
41
|
+
windowsHide: true
|
|
47
42
|
});
|
|
48
43
|
}
|
|
49
44
|
function createCodexManagedAppServerHealthCheck(params) {
|
|
@@ -67,7 +62,7 @@ function createCodexManagedAppServerHealthCheck(params) {
|
|
|
67
62
|
if (start.transport !== "stdio" || start.commandSource !== "managed") return [];
|
|
68
63
|
const env = ctx.env ?? process.env;
|
|
69
64
|
let resolved;
|
|
70
|
-
for (const agentId of listAgentIds
|
|
65
|
+
for (const agentId of listAgentIds(ctx.cfg)) {
|
|
71
66
|
const model = resolveDefaultModelForAgent({
|
|
72
67
|
cfg: ctx.cfg,
|
|
73
68
|
agentId
|
|
@@ -80,7 +75,7 @@ function createCodexManagedAppServerHealthCheck(params) {
|
|
|
80
75
|
}) !== "codex") continue;
|
|
81
76
|
const agentStart = resolveAgentStartOptions({
|
|
82
77
|
startOptions: start,
|
|
83
|
-
agentDir: resolveAgentDir
|
|
78
|
+
agentDir: resolveAgentDir(ctx.cfg, agentId, env),
|
|
84
79
|
env
|
|
85
80
|
});
|
|
86
81
|
try {
|
|
@@ -116,7 +111,7 @@ function createCodexManagedAppServerHealthCheck(params) {
|
|
|
116
111
|
})];
|
|
117
112
|
}
|
|
118
113
|
const detectedVersion = parseCodexVersion(`${output.stdout}\n${output.stderr}`);
|
|
119
|
-
if (detectedVersion !== "0.
|
|
114
|
+
if (detectedVersion !== "0.153.4") return [managedCodexFinding({
|
|
120
115
|
message: detectedVersion ? `Managed Codex app-server version mismatch: expected ${CODEX_APP_SERVER_VERSION}, detected ${detectedVersion}.` : `Managed Codex app-server did not report a parseable version; expected ${CODEX_APP_SERVER_VERSION}.`,
|
|
121
116
|
path: nativeCommand,
|
|
122
117
|
requirement: `the exact OpenClaw-pinned Codex version ${CODEX_APP_SERVER_VERSION}`,
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { m as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-utils-C57JiJrU.js";
|
|
2
|
+
import { x as readCodexPluginConfig } from "./protocol-CAAcVIKF.js";
|
|
3
|
+
import { s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-Kq6oerr6.js";
|
|
4
|
+
import { r as buildCodexPluginAppCacheKey, s as defaultCodexAppInventoryCache } from "./plugin-app-cache-key-CdSQzWyX.js";
|
|
5
|
+
import { i as requestCodexAppServerJson } from "./request-CGvGOpeR.js";
|
|
6
|
+
import "./config-JDfTI4VI.js";
|
|
7
|
+
import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-BWf6JLWG.js";
|
|
8
|
+
import { i as resolveCodexAppServerAuthProfileIdForAgent } from "./auth-profile-CwzO4_RG.js";
|
|
9
|
+
import { X as resolveCodexAppServerAuthAccountCacheKey, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, o as clearSharedCodexAppServerClientIfCurrentAndWait } from "./shared-client-CVhez2Uo.js";
|
|
10
|
+
import { t as ensureCodexPluginActivation } from "./plugin-activation-BQK-f5sV.js";
|
|
11
|
+
import { CODEX_PLUGIN_CONFIG_PATH, buildCodexMigrationPlan, buildCodexPluginsConfigValue, hasCodexPluginConfigConflict, n as applyCodexAuthItems, readCodexPluginMigrationConfigEntry, t as resolveCodexMigrationTargets } from "./plan-BMJdMOEF.js";
|
|
12
|
+
import { uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
13
|
+
import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
16
|
+
import { sleep } from "openclaw/plugin-sdk/runtime-env";
|
|
17
|
+
import { MIGRATION_REASON_TARGET_EXISTS, applyMigrationManualItem, markMigrationItemConflict, markMigrationItemError, markMigrationItemSkipped, resolveMigrationConfigRuntime, summarizeMigrationItems, writeMigrationConfigPath } from "openclaw/plugin-sdk/migration";
|
|
18
|
+
import { archiveMigrationItem, copyMemoryMigrationFileItem, copyMigrationFileItem, withCachedMigrationConfigRuntime, writeMigrationReport } from "openclaw/plugin-sdk/migration-runtime";
|
|
19
|
+
//#region extensions/codex/src/migration/apply-report.ts
|
|
20
|
+
function codexPluginActivationReportState(result) {
|
|
21
|
+
switch (result.reason) {
|
|
22
|
+
case "already_active":
|
|
23
|
+
case "installed": return {
|
|
24
|
+
installed: true,
|
|
25
|
+
enabled: true
|
|
26
|
+
};
|
|
27
|
+
case "auth_required": return {
|
|
28
|
+
installed: true,
|
|
29
|
+
enabled: false
|
|
30
|
+
};
|
|
31
|
+
case "disabled":
|
|
32
|
+
case "install_failed":
|
|
33
|
+
case "marketplace_missing":
|
|
34
|
+
case "plugin_missing": return {
|
|
35
|
+
installed: false,
|
|
36
|
+
enabled: false
|
|
37
|
+
};
|
|
38
|
+
case "refresh_failed": return {
|
|
39
|
+
installed: true,
|
|
40
|
+
enabled: false
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return result.reason;
|
|
44
|
+
}
|
|
45
|
+
function sanitizeAppsNeedingAuth(apps) {
|
|
46
|
+
return apps.map((app) => ({
|
|
47
|
+
id: app.id,
|
|
48
|
+
name: app.name,
|
|
49
|
+
needsAuth: true
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region extensions/codex/src/migration/apply.ts
|
|
54
|
+
const CODEX_PLUGIN_AUTH_REQUIRED_REASON = "auth_required";
|
|
55
|
+
const CODEX_PLUGIN_NOT_SELECTED_REASON = "not selected for migration";
|
|
56
|
+
const CODEX_CONFIG_PATCH_MODE_RETURN = "return";
|
|
57
|
+
const CODEX_PLUGIN_LOAD_WARNING = "Some Codex plugins could not be migrated. Run `openclaw migrate codex` after onboarding.";
|
|
58
|
+
const TARGET_CODEX_MARKETPLACE_DISCOVERY_POLL_MS = 250;
|
|
59
|
+
const TARGET_CODEX_MARKETPLACE_DISCOVERY_TIMEOUT_MS = 3e4;
|
|
60
|
+
const TARGET_CODEX_MARKETPLACE_DISCOVERY_TIMEOUT_ENV = "OPENCLAW_CODEX_MIGRATION_PLUGIN_LIST_TIMEOUT_MS";
|
|
61
|
+
var CodexPluginConfigConflictError = class extends Error {
|
|
62
|
+
constructor(reason) {
|
|
63
|
+
super(reason);
|
|
64
|
+
this.reason = reason;
|
|
65
|
+
this.name = "CodexPluginConfigConflictError";
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function shouldReturnCodexPluginConfigPatch(ctx) {
|
|
69
|
+
return ctx.providerOptions?.configPatchMode === CODEX_CONFIG_PATCH_MODE_RETURN;
|
|
70
|
+
}
|
|
71
|
+
function prepareTargetCodexAppServer(ctx) {
|
|
72
|
+
const appServer = resolveTargetCodexAppServer(ctx);
|
|
73
|
+
const targets = resolveCodexMigrationTargets(ctx);
|
|
74
|
+
let warmedClient;
|
|
75
|
+
const ready = getLeasedSharedCodexAppServerClient({
|
|
76
|
+
startOptions: appServer.start,
|
|
77
|
+
timeoutMs: 6e4,
|
|
78
|
+
agentDir: targets.agentDir,
|
|
79
|
+
config: ctx.config
|
|
80
|
+
}).then((client) => {
|
|
81
|
+
warmedClient = client;
|
|
82
|
+
}, () => void 0);
|
|
83
|
+
return { async dispose() {
|
|
84
|
+
await ready;
|
|
85
|
+
if (warmedClient) releaseLeasedSharedCodexAppServerClient(warmedClient);
|
|
86
|
+
await clearSharedCodexAppServerClientIfCurrentAndWait(warmedClient, {
|
|
87
|
+
exitTimeoutMs: 2e3,
|
|
88
|
+
forceKillDelayMs: 250
|
|
89
|
+
});
|
|
90
|
+
} };
|
|
91
|
+
}
|
|
92
|
+
async function applyCodexMigrationPlan(params) {
|
|
93
|
+
const plan = params.plan ?? await buildCodexMigrationPlan(params.ctx);
|
|
94
|
+
const reportDir = params.ctx.reportDir ?? path.join(params.ctx.stateDir, "migration", "codex");
|
|
95
|
+
const items = [];
|
|
96
|
+
const targets = resolveCodexMigrationTargets(params.ctx);
|
|
97
|
+
const codexHome = typeof plan.metadata?.codexHome === "string" && plan.metadata.codexHome.trim() ? plan.metadata.codexHome : plan.source;
|
|
98
|
+
const authSource = {
|
|
99
|
+
codexHome,
|
|
100
|
+
authPath: path.join(codexHome, "auth.json"),
|
|
101
|
+
modelsCachePath: path.join(codexHome, "models_cache.json")
|
|
102
|
+
};
|
|
103
|
+
const runtime = withCachedMigrationConfigRuntime(params.ctx.runtime ?? params.runtime, params.ctx.config);
|
|
104
|
+
const applyCtx = {
|
|
105
|
+
...params.ctx,
|
|
106
|
+
runtime
|
|
107
|
+
};
|
|
108
|
+
for (const item of plan.items) {
|
|
109
|
+
if (item.status !== "planned") {
|
|
110
|
+
items.push(item);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (item.id === "config:codex-plugins") items.push(await applyCodexPluginConfigItem(applyCtx, item, items));
|
|
114
|
+
else if (item.kind === "auth") items.push(...await applyCodexAuthItems({
|
|
115
|
+
ctx: applyCtx,
|
|
116
|
+
item,
|
|
117
|
+
source: authSource,
|
|
118
|
+
targets
|
|
119
|
+
}));
|
|
120
|
+
else if (item.kind === "plugin" && item.action === "install") items.push(await applyCodexPluginInstallItem(applyCtx, item));
|
|
121
|
+
else if (item.kind === "manual") items.push(applyMigrationManualItem(item));
|
|
122
|
+
else if (item.action === "archive") items.push(await archiveMigrationItem(item, reportDir));
|
|
123
|
+
else if (item.kind === "memory") items.push(await copyMemoryMigrationFileItem(item, reportDir, {
|
|
124
|
+
workspaceDir: targets.workspaceDir,
|
|
125
|
+
overwrite: params.ctx.overwrite
|
|
126
|
+
}));
|
|
127
|
+
else items.push(await copyMigrationFileItem(item, reportDir, { overwrite: params.ctx.overwrite }));
|
|
128
|
+
}
|
|
129
|
+
const result = {
|
|
130
|
+
...plan,
|
|
131
|
+
items,
|
|
132
|
+
summary: summarizeMigrationItems(items),
|
|
133
|
+
backupPath: params.ctx.backupPath,
|
|
134
|
+
reportDir
|
|
135
|
+
};
|
|
136
|
+
if (items.some(isCodexPluginLoadWarningItem)) {
|
|
137
|
+
result.warnings = uniqueStrings([...result.warnings ?? [], CODEX_PLUGIN_LOAD_WARNING]);
|
|
138
|
+
result.nextSteps = uniqueStrings([CODEX_PLUGIN_LOAD_WARNING, ...result.nextSteps ?? []]);
|
|
139
|
+
}
|
|
140
|
+
await writeMigrationReport(result, { title: "Codex Migration Report" });
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
async function applyCodexPluginInstallItem(ctx, item) {
|
|
144
|
+
const policy = readCodexPluginPolicy(item);
|
|
145
|
+
if (!policy) return {
|
|
146
|
+
...markMigrationItemError(item, "invalid Codex plugin migration item"),
|
|
147
|
+
details: {
|
|
148
|
+
...item.details,
|
|
149
|
+
code: "invalid_plugin_item"
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
try {
|
|
153
|
+
const appCacheKey = await buildTargetCodexPluginAppCacheKey(ctx);
|
|
154
|
+
const appServer = resolveTargetCodexAppServer(ctx);
|
|
155
|
+
const result = await ensureCodexPluginActivation({
|
|
156
|
+
identity: policy,
|
|
157
|
+
installEvenIfActive: true,
|
|
158
|
+
request: async (method, requestParams) => await requestTargetCodexAppServerJson({
|
|
159
|
+
method,
|
|
160
|
+
requestParams,
|
|
161
|
+
timeoutMs: 6e4,
|
|
162
|
+
startOptions: appServer.start,
|
|
163
|
+
agentDir: resolveCodexMigrationTargets(ctx).agentDir,
|
|
164
|
+
config: ctx.config,
|
|
165
|
+
isolated: false
|
|
166
|
+
}),
|
|
167
|
+
appCache: defaultCodexAppInventoryCache,
|
|
168
|
+
appCacheKey
|
|
169
|
+
});
|
|
170
|
+
const baseDetails = {
|
|
171
|
+
...item.details,
|
|
172
|
+
code: result.reason,
|
|
173
|
+
activationReason: result.reason,
|
|
174
|
+
...codexPluginActivationReportState(result),
|
|
175
|
+
installAttempted: result.installAttempted,
|
|
176
|
+
diagnostics: result.diagnostics.map((diagnostic) => diagnostic.message)
|
|
177
|
+
};
|
|
178
|
+
if (result.ok) return {
|
|
179
|
+
...item,
|
|
180
|
+
status: "migrated",
|
|
181
|
+
...result.reason === "already_active" ? { reason: "already active" } : {},
|
|
182
|
+
details: baseDetails
|
|
183
|
+
};
|
|
184
|
+
if (result.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON) return {
|
|
185
|
+
...item,
|
|
186
|
+
status: "skipped",
|
|
187
|
+
reason: CODEX_PLUGIN_AUTH_REQUIRED_REASON,
|
|
188
|
+
details: {
|
|
189
|
+
...baseDetails,
|
|
190
|
+
appsNeedingAuth: sanitizeAppsNeedingAuth(result.installResponse?.appsNeedingAuth ?? [])
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
if (result.reason === "plugin_missing" || result.reason === "marketplace_missing") return {
|
|
194
|
+
...item,
|
|
195
|
+
status: "warning",
|
|
196
|
+
reason: result.reason,
|
|
197
|
+
message: `Codex plugin "${policy.pluginName}" could not be migrated automatically`,
|
|
198
|
+
details: {
|
|
199
|
+
...baseDetails,
|
|
200
|
+
warningReason: CODEX_PLUGIN_LOAD_WARNING
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
return {
|
|
204
|
+
...item,
|
|
205
|
+
status: "error",
|
|
206
|
+
reason: result.reason,
|
|
207
|
+
details: baseDetails
|
|
208
|
+
};
|
|
209
|
+
} catch (error) {
|
|
210
|
+
if (isCodexPluginInventoryLoadError(error)) return {
|
|
211
|
+
...item,
|
|
212
|
+
status: "warning",
|
|
213
|
+
reason: "plugin_inventory_unavailable",
|
|
214
|
+
message: `Codex plugin "${policy.pluginName}" could not be migrated automatically`,
|
|
215
|
+
details: {
|
|
216
|
+
...item.details,
|
|
217
|
+
code: "plugin_inventory_unavailable",
|
|
218
|
+
warningReason: CODEX_PLUGIN_LOAD_WARNING,
|
|
219
|
+
diagnostic: coerceErrorMessage(error)
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
return {
|
|
223
|
+
...item,
|
|
224
|
+
status: "error",
|
|
225
|
+
reason: coerceErrorMessage(error),
|
|
226
|
+
details: {
|
|
227
|
+
...item.details,
|
|
228
|
+
code: "plugin_install_failed"
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function isCodexPluginInventoryLoadError(error) {
|
|
234
|
+
return coerceErrorMessage(error).includes("codex app-server plugin/list timed out");
|
|
235
|
+
}
|
|
236
|
+
function resolveTargetCodexAppServer(ctx) {
|
|
237
|
+
return resolveCodexAppServerRuntimeOptions({ pluginConfig: readCodexPluginConfig(ctx.config) });
|
|
238
|
+
}
|
|
239
|
+
async function requestTargetCodexAppServerJson(params) {
|
|
240
|
+
if (params.method !== "plugin/list") return await requestCodexAppServerJson(params);
|
|
241
|
+
const deadline = Date.now() + params.timeoutMs;
|
|
242
|
+
const discoveryTimeoutMs = targetCodexMarketplaceDiscoveryTimeoutMs();
|
|
243
|
+
const discoveryDeadline = Math.min(deadline, Date.now() + discoveryTimeoutMs);
|
|
244
|
+
let lastResponse;
|
|
245
|
+
let attempt = 0;
|
|
246
|
+
do {
|
|
247
|
+
attempt += 1;
|
|
248
|
+
const remainingMs = Math.max(1, discoveryDeadline - Date.now());
|
|
249
|
+
lastResponse = await requestCodexAppServerJson({
|
|
250
|
+
...params,
|
|
251
|
+
timeoutMs: remainingMs
|
|
252
|
+
});
|
|
253
|
+
if (hasOpenAiCuratedMarketplace(lastResponse)) return lastResponse;
|
|
254
|
+
if (Date.now() >= discoveryDeadline) return lastResponse;
|
|
255
|
+
const waitMs = Math.min(TARGET_CODEX_MARKETPLACE_DISCOVERY_POLL_MS, discoveryDeadline - Date.now());
|
|
256
|
+
await sleep(waitMs);
|
|
257
|
+
} while (Date.now() < discoveryDeadline);
|
|
258
|
+
return lastResponse;
|
|
259
|
+
}
|
|
260
|
+
function hasOpenAiCuratedMarketplace(response) {
|
|
261
|
+
if (!response || typeof response !== "object" || !("marketplaces" in response)) return false;
|
|
262
|
+
const marketplaces = response.marketplaces;
|
|
263
|
+
return Array.isArray(marketplaces) && marketplaces.some((marketplace) => marketplace && typeof marketplace === "object" && marketplace.name === "openai-curated");
|
|
264
|
+
}
|
|
265
|
+
function targetCodexMarketplaceDiscoveryTimeoutMs(env = process.env) {
|
|
266
|
+
const configured = parseStrictNonNegativeInteger(env[TARGET_CODEX_MARKETPLACE_DISCOVERY_TIMEOUT_ENV]);
|
|
267
|
+
if (configured !== void 0) return configured;
|
|
268
|
+
return TARGET_CODEX_MARKETPLACE_DISCOVERY_TIMEOUT_MS;
|
|
269
|
+
}
|
|
270
|
+
function isCodexPluginLoadWarningItem(item) {
|
|
271
|
+
return item.kind === "plugin" && item.action === "install" && item.status === "warning" && item.details?.warningReason === CODEX_PLUGIN_LOAD_WARNING;
|
|
272
|
+
}
|
|
273
|
+
async function buildTargetCodexPluginAppCacheKey(ctx) {
|
|
274
|
+
const targets = resolveCodexMigrationTargets(ctx);
|
|
275
|
+
const appServer = resolveTargetCodexAppServer(ctx);
|
|
276
|
+
const authProfileId = resolveCodexAppServerAuthProfileIdForAgent({
|
|
277
|
+
agentDir: targets.agentDir,
|
|
278
|
+
config: ctx.config
|
|
279
|
+
});
|
|
280
|
+
const accountId = await resolveCodexAppServerAuthAccountCacheKey({
|
|
281
|
+
authProfileId,
|
|
282
|
+
agentDir: targets.agentDir,
|
|
283
|
+
config: ctx.config
|
|
284
|
+
});
|
|
285
|
+
const envApiKeyFingerprint = authProfileId ? void 0 : resolveCodexAppServerFallbackApiKeyCacheKey({ startOptions: appServer.start });
|
|
286
|
+
return buildCodexPluginAppCacheKey({
|
|
287
|
+
appServer,
|
|
288
|
+
agentDir: targets.agentDir,
|
|
289
|
+
authProfileId,
|
|
290
|
+
accountId,
|
|
291
|
+
envApiKeyFingerprint
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
|
|
295
|
+
if (appliedItems.filter((candidate) => candidate.kind === "plugin" && candidate.action === "install" && readCodexPluginPolicy(candidate) !== void 0 && !isCodexPluginConfigTerminal(candidate)).length > 0) return {
|
|
296
|
+
...item,
|
|
297
|
+
status: "warning",
|
|
298
|
+
reason: "selected Codex plugin activation is incomplete"
|
|
299
|
+
};
|
|
300
|
+
const entries = appliedItems.map(readAppliedPluginConfigEntry).filter((entry) => entry !== void 0);
|
|
301
|
+
if (entries.length === 0) return {
|
|
302
|
+
...markMigrationItemSkipped(item, "no selected Codex plugins"),
|
|
303
|
+
deferredCompletion: true
|
|
304
|
+
};
|
|
305
|
+
const returnPatch = shouldReturnCodexPluginConfigPatch(ctx);
|
|
306
|
+
const configApi = resolveMigrationConfigRuntime(ctx);
|
|
307
|
+
const currentConfig = returnPatch ? ctx.config : configApi?.current?.();
|
|
308
|
+
if (!currentConfig) return markMigrationItemError(item, "config runtime unavailable");
|
|
309
|
+
const value = buildCodexPluginsConfigValue(entries, currentConfig);
|
|
310
|
+
if (!ctx.overwrite && hasCodexPluginConfigConflict(currentConfig, value)) return markMigrationItemConflict(item, MIGRATION_REASON_TARGET_EXISTS);
|
|
311
|
+
const migratedItem = {
|
|
312
|
+
...item,
|
|
313
|
+
status: "migrated",
|
|
314
|
+
details: {
|
|
315
|
+
...item.details,
|
|
316
|
+
path: [...CODEX_PLUGIN_CONFIG_PATH],
|
|
317
|
+
value
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
if (returnPatch) return migratedItem;
|
|
321
|
+
if (!configApi?.mutateConfigFile) return markMigrationItemError(item, "config runtime unavailable");
|
|
322
|
+
try {
|
|
323
|
+
await configApi.mutateConfigFile({
|
|
324
|
+
base: "runtime",
|
|
325
|
+
afterWrite: { mode: "auto" },
|
|
326
|
+
mutate(draft) {
|
|
327
|
+
if (!ctx.overwrite && hasCodexPluginConfigConflict(draft, value)) throw new CodexPluginConfigConflictError(MIGRATION_REASON_TARGET_EXISTS);
|
|
328
|
+
writeMigrationConfigPath(draft, CODEX_PLUGIN_CONFIG_PATH, value);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
return migratedItem;
|
|
332
|
+
} catch (error) {
|
|
333
|
+
if (error instanceof CodexPluginConfigConflictError) return markMigrationItemConflict(item, error.reason);
|
|
334
|
+
return markMigrationItemError(item, coerceErrorMessage(error));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function isCodexPluginConfigTerminal(item) {
|
|
338
|
+
return item.status === "migrated" || item.status === "skipped" && (item.deferredCompletion === true || item.reason === CODEX_PLUGIN_NOT_SELECTED_REASON || item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON);
|
|
339
|
+
}
|
|
340
|
+
function readAppliedPluginConfigEntry(item) {
|
|
341
|
+
if (item.status === "migrated" || item.deferredCompletion === true) return readCodexPluginMigrationConfigEntry(item, true);
|
|
342
|
+
if (item.status === "skipped" && item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON) return readCodexPluginMigrationConfigEntry(item, false);
|
|
343
|
+
}
|
|
344
|
+
function readCodexPluginPolicy(item) {
|
|
345
|
+
const entry = readCodexPluginMigrationConfigEntry(item, true);
|
|
346
|
+
if (!entry) return;
|
|
347
|
+
return {
|
|
348
|
+
configKey: entry.configKey,
|
|
349
|
+
marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
|
|
350
|
+
pluginName: entry.pluginName,
|
|
351
|
+
enabled: true,
|
|
352
|
+
allowDestructiveActions: true,
|
|
353
|
+
destructiveApprovalMode: "allow"
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
//#endregion
|
|
357
|
+
export { applyCodexMigrationPlan, prepareTargetCodexAppServer };
|