@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.
Files changed (109) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +18 -23
  3. package/dist/apply-B6el6hdO.js +357 -0
  4. package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-D6cR54TV.js} +113 -49
  5. package/dist/{attempt-context-DmQUNWwT.js → attempt-context-AO4DSjE0.js} +11 -9
  6. package/dist/{event-projector-usage-C5mcrGjp.js → attempt-notifications--H8zXR5-.js} +3 -89
  7. package/dist/auth-cache-key-Kq6oerr6.js +498 -0
  8. package/dist/auth-profile-CwzO4_RG.js +43 -0
  9. package/dist/auth-profile-selection-DFu9e167.js +45 -0
  10. package/dist/{binding-connection-E6uDsPlx.js → binding-connection-QqgcPCgk.js} +18 -3
  11. package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-lRpmZHFv.js} +54 -150
  12. package/dist/build-state-6RL6qohz.js +19 -0
  13. package/dist/{capabilities-dIjNVCYH.js → capabilities-BeqLPbtM.js} +2 -1
  14. package/dist/cli-metadata.js +1 -1
  15. package/dist/client-BEKu4yDx.js +3983 -0
  16. package/dist/command-dispatch-CisT9Jqq.js +21 -0
  17. package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DeTfrapr.js} +2 -2
  18. package/dist/{command-handlers-CTGb2csu.js → command-handlers-BfIsJEuA.js} +158 -76
  19. package/dist/command-rpc-BMqRQOFX.js +226 -0
  20. package/dist/{compact-_t0HQrUS.js → compact-CGJZ2rlb.js} +89 -49
  21. package/dist/config-JDfTI4VI.js +106 -0
  22. package/dist/{config-BhmfC1s6.js → config-options-jnIFvwxD.js} +208 -654
  23. package/dist/config-runtime-BWf6JLWG.js +11 -0
  24. package/dist/config-utils-C57JiJrU.js +69 -0
  25. package/dist/conversation-binding-CxOlHiix.js +889 -0
  26. package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → conversation-control-CUCrSIQI.js} +36 -155
  27. package/dist/doctor-contract-api.js +8 -9
  28. package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-D-JBoaLt.js} +734 -698
  29. package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-J_5Ep5Um.js} +4 -3
  30. package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
  31. package/dist/ephemeral-turn-DSwzP8YY.js +101 -0
  32. package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-BmBM4qBV.js} +23 -27
  33. package/dist/event-projector-usage-CIyrYYid.js +102 -0
  34. package/dist/{harness-DXVZ5II5.js → harness-FR6eQgyO.js} +47 -17
  35. package/dist/harness.js +1 -1
  36. package/dist/history-rejection-B4nOXNXF.js +13 -0
  37. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  38. package/dist/incognito-session-uhrBF6wJ.js +15 -0
  39. package/dist/index.js +413 -2893
  40. package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-DHBefrzg.js} +12 -21
  41. package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DrjjRRUD.js} +17 -84
  42. package/dist/managed-thread-store-D1t5jh3G.js +66 -0
  43. package/dist/media-understanding-provider.js +4 -1
  44. package/dist/{model-catalog-CUM68Hkl.js → model-catalog-B_6M04Wo.js} +6 -5
  45. package/dist/{models-sYnEc0gd.js → models-P9k2qAof.js} +4 -4
  46. package/dist/native-execution-policy-umd0tgh4.js +128 -0
  47. package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-BbCUKRwC.js} +76 -48
  48. package/dist/node-cli-sessions-rj0ysJwM.js +527 -0
  49. package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-BY_ctYnT.js} +54 -23
  50. package/dist/plan-BMJdMOEF.js +711 -0
  51. package/dist/plugin-activation-BQK-f5sV.js +133 -0
  52. package/dist/{thread-resume-C7pyVKeW.js → plugin-app-cache-key-CdSQzWyX.js} +5 -53
  53. package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-DeW95wB5.js} +1 -1
  54. package/dist/plugin-inventory-CoRCzWW4.js +325 -0
  55. package/dist/plugin-marketplace-discovery-3akBizzF.js +134 -0
  56. package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-DgNfRAGA.js} +13 -9
  57. package/dist/protocol-CAAcVIKF.js +275 -0
  58. package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-W4tfK5Y5.js} +2 -2
  59. package/dist/{rate-limits-CawQJfUS.js → rate-limits-Bqnx1N4z.js} +1 -1
  60. package/dist/request-CGvGOpeR.js +198 -0
  61. package/dist/{run-attempt-D1hJO4fX.js → run-attempt-DwKds3DN.js} +1498 -1028
  62. package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-T-NwqeSH.js} +28 -28
  63. package/dist/sandbox-guard-BcT66fWy.js +165 -0
  64. package/dist/{session-binding-BHuTCRZQ.js → session-binding-CKSepwIC.js} +118 -324
  65. package/dist/session-binding-record-CaZjYwNS.js +256 -0
  66. package/dist/session-catalog-HaDcp7Sv.js +1533 -0
  67. package/dist/session-catalog-adoption-BKLtSrwi.js +251 -0
  68. package/dist/session-catalog-archive-D0i2pGj2.js +56 -0
  69. package/dist/session-catalog-home-id-D7-aLiNt.js +190 -0
  70. package/dist/session-catalog-node-adoption-BUuDYY8R.js +182 -0
  71. package/dist/session-catalog-node-continue-CBtc4wkI.js +238 -0
  72. package/dist/session-catalog-parsing-CdD3JhdM.js +280 -0
  73. package/dist/session-catalog-provenance-DkJHo735.js +124 -0
  74. package/dist/{session-cli-CmFEXMAM.js → session-cli-CbgaHh0f.js} +3 -2
  75. package/dist/session-history-Cz-tOOYj.js +96 -0
  76. package/dist/{session-upstream-marker-C351-5Qw.js → session-history-import-DFN7sWRU.js} +5 -49
  77. package/dist/session-history-read-cxPUxyVV.js +50 -0
  78. package/dist/session-history-worker-runtime.js +60 -0
  79. package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-CNEvGaU5.js} +75 -69
  80. package/dist/session-history.worker.js +2 -0
  81. package/dist/{session-initialization-BeWzjGiR.js → session-initialization-Jo86C60I.js} +2 -1
  82. package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-B22InTp_.js} +4 -7
  83. package/dist/{session-retirement-BujDjXVF.js → session-retirement-BSNG_mhf.js} +8 -7
  84. package/dist/session-upstream-marker-D15C9NHp.js +46 -0
  85. package/dist/settled-turn-context-Du6gdUDd.js +45 -0
  86. package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BuLUrZl2.js} +54 -42
  87. package/dist/shared-client-CVhez2Uo.js +2911 -0
  88. package/dist/{side-question-BTZAII4l.js → side-question-DLbr2vUU.js} +135 -191
  89. package/dist/source-Da-h6f7e.js +518 -0
  90. package/dist/thread-archive-guard-D1bP04Tf.js +53 -0
  91. package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-D1pzRwHB.js} +467 -977
  92. package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-D6oASVRu.js} +15 -17
  93. package/dist/{thread-policy-g4KbJPzp.js → thread-policy-D8kI7yAO.js} +2 -2
  94. package/dist/thread-resume-T5cveyxA.js +52 -0
  95. package/dist/timeout-BVw8aaM1.js +33 -0
  96. package/dist/transcript-mirror-attestation-DibE0krH.js +89 -0
  97. package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-t5TOccct.js} +111 -379
  98. package/dist/{transport-stdio-CyPldczm.js → transport-stdio-BGjHoYLr.js} +80 -48
  99. package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-De-sLJ2r.js} +94 -166
  100. package/dist/{usage-Bj-rrzkR.js → usage-CPPTmBvZ.js} +4 -3
  101. package/dist/version-omm6IPI3.js +12 -0
  102. package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-CSVgQL0w.js} +3 -3
  103. package/openclaw.plugin.json +22 -1
  104. package/package.json +6 -6
  105. package/dist/request-DYAI5FQE.js +0 -475
  106. package/dist/session-catalog-yyvTWFOw.js +0 -3120
  107. package/dist/session-history-C5J1AKzG.js +0 -87
  108. package/dist/shared-client-DxcfF9KX.js +0 -7494
  109. 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, i as resolveCodexAppServerRuntimeOptions } from "./config-BhmfC1s6.js";
2
- import { n as resolveManagedCodexAppServerStartOptions, o as CODEX_APP_SERVER_VERSION, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-4-Vjz5GH.js";
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 new Promise((resolve, reject) => {
32
- execFile(command, ["--version"], {
33
- encoding: "utf8",
34
- maxBuffer: CODEX_VERSION_MAX_BUFFER_BYTES,
35
- timeout: CODEX_VERSION_TIMEOUT_MS,
36
- windowsHide: true
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$1(ctx.cfg)) {
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$1(ctx.cfg, agentId, env),
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.152.1") return [managedCodexFinding({
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 };