sneakoscope 6.1.0 → 6.2.0

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 (246) hide show
  1. package/README.md +35 -11
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/bin/fast-inline.js +18 -9
  5. package/dist/bin/sks-dispatch.js +2 -2
  6. package/dist/cli/args.js +2 -0
  7. package/dist/cli/command-manifest-lite.js +2 -3
  8. package/dist/cli/command-registry.js +3 -4
  9. package/dist/cli/help-fast.js +1 -1
  10. package/dist/cli/install-helpers.js +116 -306
  11. package/dist/cli/install-tool-helpers.js +287 -0
  12. package/dist/cli/router.js +40 -4
  13. package/dist/commands/codex-lb.js +51 -20
  14. package/dist/commands/codex.js +39 -1
  15. package/dist/commands/doctor.js +242 -20
  16. package/dist/commands/tmux.js +5 -1
  17. package/dist/commands/zellij-monitor-pane.js +2 -0
  18. package/dist/commands/zellij-viewport-pane.js +3 -1
  19. package/dist/commands/zellij.js +1 -1
  20. package/dist/config/skills-manifest.json +59 -59
  21. package/dist/core/agent-bridge/agent-manifest.js +48 -0
  22. package/dist/core/agents/agent-command-surface.js +2 -1
  23. package/dist/core/agents/agent-effort-policy.js +38 -35
  24. package/dist/core/agents/agent-plan.js +100 -21
  25. package/dist/core/agents/agent-role-config.js +43 -46
  26. package/dist/core/agents/agent-runner-codex-exec.js +16 -3
  27. package/dist/core/agents/agent-schema.js +3 -2
  28. package/dist/core/agents/native-cli-session-swarm.js +1 -1
  29. package/dist/core/agents/zellij-right-lane-cockpit.js +2 -2
  30. package/dist/core/codex/agent-config-file-repair.js +94 -193
  31. package/dist/core/codex/codex-cli-update.js +723 -0
  32. package/dist/core/codex/codex-config-guard.js +185 -9
  33. package/dist/core/codex/codex-config-readability.js +21 -8
  34. package/dist/core/codex/codex-config-toml.js +14 -11
  35. package/dist/core/codex/codex-project-config-policy.js +3 -6
  36. package/dist/core/codex/codex-startup-config-postcheck.js +52 -42
  37. package/dist/core/codex-adapter.js +35 -22
  38. package/dist/core/codex-app/codex-agent-role-sync.js +13 -54
  39. package/dist/core/codex-app/codex-app-launcher.js +48 -17
  40. package/dist/core/codex-app/codex-app-restart.js +23 -2
  41. package/dist/core/codex-app/mcp-manager.js +679 -0
  42. package/dist/core/codex-app/sks-menubar.js +533 -8
  43. package/dist/core/codex-control/codex-0139-image-path-real-probe.js +15 -4
  44. package/dist/core/codex-control/codex-0139-web-search-probe.js +17 -6
  45. package/dist/core/codex-control/codex-lb-launch-recovery.js +293 -0
  46. package/dist/core/codex-control/codex-reliability-shield.js +89 -29
  47. package/dist/core/codex-control/codex-sdk-adapter.js +44 -8
  48. package/dist/core/codex-control/codex-task-runner.js +62 -9
  49. package/dist/core/codex-control/python-codex-sdk-adapter.js +30 -3
  50. package/dist/core/codex-exec-output-schema.js +35 -6
  51. package/dist/core/codex-lb/codex-lb-env.js +1 -1
  52. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +291 -0
  53. package/dist/core/codex-native/codex-native-feature-broker.js +9 -16
  54. package/dist/core/codex-native/codex-native-repair-transaction.js +1 -1
  55. package/dist/core/codex-native/core-skill-manifest.js +8 -4
  56. package/dist/core/codex-runtime/codex-desktop-config-policy.js +2 -3
  57. package/dist/core/commands/agent-bridge-command.js +23 -2
  58. package/dist/core/commands/agent-command.js +19 -5
  59. package/dist/core/commands/basic-cli.js +47 -6
  60. package/dist/core/commands/command-utils.js +1 -1
  61. package/dist/core/commands/mad-sks-command.js +76 -10
  62. package/dist/core/commands/menubar-command.js +94 -0
  63. package/dist/core/commands/naruto-command.js +645 -1156
  64. package/dist/core/commands/research-command.js +293 -231
  65. package/dist/core/commands/run-command.js +100 -23
  66. package/dist/core/commands/team-command.js +2 -3
  67. package/dist/core/commands/team-legacy-observe-command.js +94 -359
  68. package/dist/core/commands/wiki-command.js +11 -5
  69. package/dist/core/db-safety.js +2 -2
  70. package/dist/core/decision-lattice.js +6 -6
  71. package/dist/core/doctor/codex-startup-config-repair.js +8 -3
  72. package/dist/core/doctor/doctor-codex-startup-repair.js +6 -141
  73. package/dist/core/feature-fixture-executor.js +71 -7
  74. package/dist/core/feature-fixture-runner.js +53 -12
  75. package/dist/core/feature-fixtures.js +47 -14
  76. package/dist/core/feature-registry.js +28 -27
  77. package/dist/core/fsx.js +1 -0
  78. package/dist/core/harness-conflicts.js +18 -9
  79. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +14 -8
  80. package/dist/core/hooks-runtime/hook-io.js +8 -4
  81. package/dist/core/hooks-runtime/light-turn.js +70 -0
  82. package/dist/core/hooks-runtime/naruto-decision-gate.js +184 -0
  83. package/dist/core/hooks-runtime/payload-signals.js +270 -0
  84. package/dist/core/hooks-runtime/stop-repeat-guard.js +89 -0
  85. package/dist/core/hooks-runtime/team-digest.js +0 -1
  86. package/dist/core/hooks-runtime/tool-output-quarantine.js +93 -0
  87. package/dist/core/hooks-runtime.js +438 -354
  88. package/dist/core/init/skills.js +16 -30
  89. package/dist/core/init.js +144 -36
  90. package/dist/core/managed-assets/managed-assets-manifest.js +566 -10
  91. package/dist/core/mission.js +24 -1
  92. package/dist/core/pipeline-internals/runtime-core.js +570 -177
  93. package/dist/core/pipeline-internals/runtime-gates.js +174 -48
  94. package/dist/core/preflight/parallel-preflight-engine.js +66 -4
  95. package/dist/core/proof/route-adapter.js +1 -1
  96. package/dist/core/proof/route-proof-gate.js +7 -2
  97. package/dist/core/proof/selftest-proof-fixtures.js +3 -5
  98. package/dist/core/proof-field.js +1 -1
  99. package/dist/core/provider/model-router.js +42 -31
  100. package/dist/core/recallpulse/policy.js +12 -28
  101. package/dist/core/recallpulse.js +11 -6
  102. package/dist/core/release/npm-pack-proof.js +247 -0
  103. package/dist/core/release/package-dist-snapshot.js +151 -0
  104. package/dist/core/release/package-size-budget.js +4 -1
  105. package/dist/core/release/release-authorization-snapshot.js +115 -0
  106. package/dist/core/release/release-gate-affected-selector.js +14 -2
  107. package/dist/core/release/release-gate-cache-v2.js +30 -0
  108. package/dist/core/release/release-gate-contract.js +161 -0
  109. package/dist/core/release/release-gate-dag.js +1 -0
  110. package/dist/core/release/release-real-contract.js +90 -10
  111. package/dist/core/release-parallel-full-coverage.js +31 -143
  112. package/dist/core/research/claim-evidence-matrix.js +41 -6
  113. package/dist/core/research/experiment-plan.js +14 -10
  114. package/dist/core/research/falsification.js +9 -2
  115. package/dist/core/research/implementation-blueprint-densifier.js +82 -60
  116. package/dist/core/research/implementation-blueprint.js +32 -26
  117. package/dist/core/research/mock-result.js +122 -11
  118. package/dist/core/research/replication-pack.js +15 -8
  119. package/dist/core/research/research-adversarial-review.js +1068 -0
  120. package/dist/core/research/research-claim-builder.js +69 -17
  121. package/dist/core/research/research-claim-synthesizer.js +343 -0
  122. package/dist/core/research/research-cycle-runner.js +53 -3
  123. package/dist/core/research/research-falsification-runner.js +176 -0
  124. package/dist/core/research/research-final-reviewer.js +44 -125
  125. package/dist/core/research/research-plan-markdown.js +123 -0
  126. package/dist/core/research/research-realistic-report.js +14 -6
  127. package/dist/core/research/research-review-artifact-digest.js +66 -0
  128. package/dist/core/research/research-source-evidence.js +144 -0
  129. package/dist/core/research/research-source-layer-catalog.js +68 -0
  130. package/dist/core/research/research-source-ledger-merge.js +250 -12
  131. package/dist/core/research/research-source-shards.js +26 -70
  132. package/dist/core/research/research-stage-runner.js +237 -247
  133. package/dist/core/research/research-super-search.js +188 -0
  134. package/dist/core/research/research-synthesis-prompt.js +20 -1
  135. package/dist/core/research/research-synthesis-writer.js +86 -5
  136. package/dist/core/research/research-work-graph.js +25 -18
  137. package/dist/core/research/source-quality-report.js +21 -0
  138. package/dist/core/research.js +424 -390
  139. package/dist/core/retention.js +70 -2
  140. package/dist/core/routes/constants.js +1 -1
  141. package/dist/core/routes/dollar-manifest-lite.js +11 -11
  142. package/dist/core/routes.js +149 -69
  143. package/dist/core/runtime/task-profile.js +66 -0
  144. package/dist/core/runtime/verification-budget.js +12 -0
  145. package/dist/core/security/high-risk-contracts.js +6 -6
  146. package/dist/core/stop-gate/stop-gate-check.js +49 -12
  147. package/dist/core/subagents/agent-catalog.js +287 -0
  148. package/dist/core/subagents/model-policy.js +259 -0
  149. package/dist/core/subagents/naruto-help-contract.js +47 -0
  150. package/dist/core/subagents/official-subagent-config.js +488 -0
  151. package/dist/core/subagents/official-subagent-preparation.js +297 -0
  152. package/dist/core/subagents/official-subagent-prompt.js +159 -0
  153. package/dist/core/subagents/official-subagent-runner.js +129 -0
  154. package/dist/core/subagents/subagent-evidence.js +663 -0
  155. package/dist/core/subagents/terminology.js +16 -0
  156. package/dist/core/subagents/thread-budget.js +21 -0
  157. package/dist/core/subagents/triwiki-attention.js +168 -0
  158. package/dist/core/super-search/runtime-helpers.js +173 -19
  159. package/dist/core/super-search/runtime.js +140 -15
  160. package/dist/core/super-search/source-records.js +49 -8
  161. package/dist/core/team-review-policy.js +15 -0
  162. package/dist/core/triwiki/code-pack-head-freshness.js +291 -0
  163. package/dist/core/triwiki/triwiki-module-card.js +1 -1
  164. package/dist/core/triwiki-wrongness/wrongness-ledger.js +9 -2
  165. package/dist/core/version-manager.js +51 -1
  166. package/dist/core/version.js +1 -1
  167. package/dist/core/work-order-ledger.js +40 -1
  168. package/dist/core/zellij/zellij-fake-adapter.js +3 -1
  169. package/dist/core/zellij/zellij-launcher.js +49 -10
  170. package/dist/core/zellij/zellij-layout-builder.js +14 -5
  171. package/dist/core/zellij/zellij-official-subagent-activity.js +477 -0
  172. package/dist/core/zellij/zellij-official-subagent-telemetry.js +264 -0
  173. package/dist/core/zellij/zellij-pane-proof.js +9 -1
  174. package/dist/core/zellij/zellij-slot-pane-renderer.js +17 -5
  175. package/dist/core/zellij/zellij-slot-telemetry.js +15 -3
  176. package/dist/core/zellij/zellij-ui-mode.js +1 -1
  177. package/dist/core/zellij/zellij-update.js +14 -1
  178. package/dist/core/zellij/zellij-viewport-binder.js +3 -0
  179. package/dist/scripts/agent-role-config-repair-check.js +14 -16
  180. package/dist/scripts/architecture-guard-check.js +8 -1
  181. package/dist/scripts/canonical-test-runner.js +7 -1
  182. package/dist/scripts/check-route-modularity.js +0 -1
  183. package/dist/scripts/check-ts-contracts.js +1 -1
  184. package/dist/scripts/codex-control-all-pipelines-check.js +7 -3
  185. package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +27 -0
  186. package/dist/scripts/codex-lb-fast-mode-truth-check.js +11 -1
  187. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +9 -2
  188. package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +13 -2
  189. package/dist/scripts/codex-native-agent-role-content-check.js +27 -7
  190. package/dist/scripts/codex-native-repair-transaction-check.js +3 -1
  191. package/dist/scripts/codex-sdk-all-pipelines-check.js +7 -4
  192. package/dist/scripts/codex-sdk-backend-router-check.js +2 -0
  193. package/dist/scripts/codex-sdk-research-pipeline-check.js +30 -8
  194. package/dist/scripts/db-route-materialization-check.js +33 -0
  195. package/dist/scripts/docs-truthfulness-check.js +3 -1
  196. package/dist/scripts/doctor-codex-startup-repair-check.js +12 -15
  197. package/dist/scripts/doctor-fix-production-blackbox.js +12 -2
  198. package/dist/scripts/doctor-startup-config-repair-blackbox.js +8 -2
  199. package/dist/scripts/doctor-startup-config-repair-check.js +12 -2
  200. package/dist/scripts/install-update-preserves-config-check.js +6 -1
  201. package/dist/scripts/lib/codex-sdk-gate-lib.js +4 -0
  202. package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +0 -1
  203. package/dist/scripts/managed-role-manifest-parity-check.js +5 -4
  204. package/dist/scripts/naruto-codex-e2e-check.js +14 -7
  205. package/dist/scripts/naruto-shadow-clone-swarm-check.js +4 -201
  206. package/dist/scripts/npm-publish-performance-check.js +20 -12
  207. package/dist/scripts/official-subagent-workflow-check.js +145 -0
  208. package/dist/scripts/package-published-contract-check.js +6 -29
  209. package/dist/scripts/packlist-performance-check.js +18 -21
  210. package/dist/scripts/parallel-verification-engine-check.js +2 -2
  211. package/dist/scripts/prepublish-release-check-or-fast.js +23 -86
  212. package/dist/scripts/python-codex-sdk-all-pipelines-check.js +8 -0
  213. package/dist/scripts/release-affected-selector-check.js +74 -1
  214. package/dist/scripts/release-check-stamp.js +153 -248
  215. package/dist/scripts/release-dag-full-coverage-check.js +7 -15
  216. package/dist/scripts/release-dynamic-presets-check.js +2 -1
  217. package/dist/scripts/release-gate-dag-runner-check.js +0 -1
  218. package/dist/scripts/release-gate-dag-runner.js +12 -1
  219. package/dist/scripts/release-gate-existence-audit.js +1 -2
  220. package/dist/scripts/release-parallel-full-coverage-check.js +12 -6
  221. package/dist/scripts/release-parallel-speed-budget-check.js +18 -2
  222. package/dist/scripts/release-real-check.js +26 -4
  223. package/dist/scripts/release-registry-check.js +61 -16
  224. package/dist/scripts/research-blueprint-densifier-check.js +2 -2
  225. package/dist/scripts/research-real-cycle-no-legacy-final-md-check.js +11 -7
  226. package/dist/scripts/sizecheck.js +2 -2
  227. package/dist/scripts/sks-3-1-4-directive-check-lib.js +8 -2
  228. package/dist/scripts/sks-3-1-5-directive-check-lib.js +3 -2
  229. package/dist/scripts/sks-3-1-6-directive-check-lib.js +5 -3
  230. package/dist/scripts/sks-menubar-install-check.js +14 -1
  231. package/dist/scripts/super-search-provider-interface-check.js +31 -18
  232. package/dist/scripts/trust-fixture-check.js +32 -10
  233. package/dist/scripts/wrongness-fixture-check.js +1 -1
  234. package/dist/scripts/zellij-layout-valid-check.js +5 -5
  235. package/dist/scripts/zellij-spawn-on-demand-layout-check.js +3 -3
  236. package/docs/demo.tape +1 -1
  237. package/infra-harness-gates.json +1486 -0
  238. package/package.json +15 -10
  239. package/release-gates.v2.json +4060 -0
  240. package/runtime-required-scripts.json +9 -0
  241. package/dist/commands/db.js +0 -6
  242. package/dist/core/commands/db-command.js +0 -146
  243. package/dist/core/research/prompt.js +0 -15
  244. package/dist/scripts/codex-0139-feature-probes-check.js +0 -30
  245. package/dist/scripts/codex-0139-marketplace-source-check.js +0 -13
  246. package/dist/scripts/codex-control-tool-call-sequence-repair-check.js +0 -14
@@ -0,0 +1,723 @@
1
+ import fsp from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { ensureDir, exists, packageRoot, readJson, runProcess, writeJsonAtomic } from '../fsx.js';
5
+ export const CODEX_CLI_UPDATE_STATUS_SCHEMA = 'sks.codex-cli-update-status.v1';
6
+ export const CODEX_CLI_UPDATE_RESULT_SCHEMA = 'sks.codex-cli-update-result.v1';
7
+ const DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000;
8
+ const CODEX_STANDALONE_INSTALLER_URL = 'https://chatgpt.com/codex/install.sh';
9
+ const CODEX_STANDALONE_INSTALLER_PS1_URL = 'https://chatgpt.com/codex/install.ps1';
10
+ export function codexCliUpdateCachePath(home = process.env.HOME || os.homedir()) {
11
+ return path.join(String(home || os.homedir()), '.sneakoscope', 'cache', 'codex-cli-update.json');
12
+ }
13
+ /**
14
+ * Resolve the operator's Codex CLI for menu status/self-update operations.
15
+ *
16
+ * This is intentionally separate from resolveCodexRuntime/getCodexInfo. Runtime
17
+ * execution may use the @openai/codex dependency bundled under Sneakoscope, but
18
+ * self-update must never mutate that package-owned dependency. Explicit operator
19
+ * overrides are considered first, followed by every executable on PATH; any
20
+ * candidate owned by this Sneakoscope package is rejected and resolution continues.
21
+ */
22
+ export async function resolveOperatorCodexCli(opts = {}) {
23
+ const env = opts.env || process.env;
24
+ const run = opts.deps?.runProcessImpl || runProcess;
25
+ const candidates = await operatorCodexCandidates(opts.codexBin, env);
26
+ const warnings = [];
27
+ for (const candidate of candidates) {
28
+ if (!await exists(candidate.path)) {
29
+ if (candidate.source === 'explicit')
30
+ warnings.push(`codex_cli_explicit_override_missing:${candidate.path}`);
31
+ continue;
32
+ }
33
+ const realPath = await fsp.realpath(candidate.path).catch(() => candidate.path);
34
+ const rejectedReason = await nonOperatorCodexReason(candidate.path, realPath);
35
+ if (rejectedReason) {
36
+ warnings.push(`codex_cli_${rejectedReason}_candidate_rejected:${candidate.path}`);
37
+ continue;
38
+ }
39
+ const result = await run(candidate.path, ['--version'], {
40
+ timeoutMs: 10_000,
41
+ maxOutputBytes: 16 * 1024,
42
+ env
43
+ }).catch((err) => failedProcessResult(err));
44
+ const rawVersion = `${result.stdout || ''}${result.stderr || ''}`.trim();
45
+ const version = result.code === 0 ? officialCodexCliVersionNumber(rawVersion) : null;
46
+ if (!version) {
47
+ warnings.push(`codex_cli_candidate_identity_or_version_unavailable:${candidate.path}`);
48
+ continue;
49
+ }
50
+ return {
51
+ ok: true,
52
+ source: candidate.source,
53
+ path: candidate.path,
54
+ version,
55
+ raw_version: rawVersion,
56
+ warnings,
57
+ blockers: []
58
+ };
59
+ }
60
+ return {
61
+ ok: false,
62
+ source: 'unavailable',
63
+ path: null,
64
+ version: null,
65
+ raw_version: null,
66
+ warnings,
67
+ blockers: ['operator_codex_cli_missing']
68
+ };
69
+ }
70
+ export async function inspectCodexCliUpdate(opts = {}) {
71
+ const deps = opts.deps || {};
72
+ const now = deps.now ? deps.now() : new Date();
73
+ const home = opts.home || opts.env?.HOME || process.env.HOME || os.homedir();
74
+ const cachePath = codexCliUpdateCachePath(home);
75
+ const codex = await resolveOperatorCodexCli({
76
+ ...(opts.codexBin ? { codexBin: opts.codexBin } : {}),
77
+ ...(opts.env ? { env: opts.env } : {}),
78
+ deps
79
+ });
80
+ if (!codex.ok || !codex.path || !codex.version) {
81
+ return {
82
+ schema: CODEX_CLI_UPDATE_STATUS_SCHEMA,
83
+ ok: false,
84
+ status: 'missing',
85
+ installed: false,
86
+ bin: null,
87
+ cli_path: null,
88
+ cli_source: 'unavailable',
89
+ current_version: null,
90
+ raw_version: null,
91
+ latest_version: null,
92
+ update_available: null,
93
+ update_command: 'sks codex update',
94
+ source: 'unavailable',
95
+ checked_at: now.toISOString(),
96
+ cache_path: cachePath,
97
+ warnings: codex.warnings,
98
+ blockers: ['codex_cli_missing', ...codex.blockers],
99
+ guidance: ['Install a release build of Codex CLI on the operator PATH, then reopen the SKS menu bar.']
100
+ };
101
+ }
102
+ const ttlMs = Math.max(0, Number(opts.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS));
103
+ const cached = await readJson(cachePath, null).catch(() => null);
104
+ const cachedAt = Date.parse(String(cached?.checked_at || ''));
105
+ const cachedFresh = opts.force !== true
106
+ && cached?.schema === CODEX_CLI_UPDATE_STATUS_SCHEMA
107
+ && typeof cached?.latest_version === 'string'
108
+ && Number.isFinite(cachedAt)
109
+ && now.getTime() - cachedAt < ttlMs;
110
+ if (cachedFresh) {
111
+ return buildStatus({
112
+ codex,
113
+ latestVersion: cached.latest_version,
114
+ source: 'cache',
115
+ checkedAt: String(cached.checked_at),
116
+ cachePath
117
+ });
118
+ }
119
+ const env = opts.env || process.env;
120
+ const npm = deps.whichImpl
121
+ ? await deps.whichImpl('npm').catch(() => null)
122
+ : await resolveOperatorExecutable('npm', env);
123
+ if (!npm)
124
+ return unavailableStatus(codex, now, cachePath, 'npm_not_found');
125
+ const run = deps.runProcessImpl || runProcess;
126
+ const result = await run(npm, ['view', '@openai/codex', 'version'], {
127
+ timeoutMs: 8_000,
128
+ maxOutputBytes: 8 * 1024,
129
+ env: opts.env || process.env
130
+ }).catch((err) => failedProcessResult(err));
131
+ const latestVersion = result.code === 0
132
+ ? codexCliVersionNumber(String(result.stdout || '').trim().split(/\s+/).pop() || '')
133
+ : null;
134
+ if (!latestVersion) {
135
+ return unavailableStatus(codex, now, cachePath, String(result.stderr || result.stdout || 'codex_cli_latest_version_unavailable').trim());
136
+ }
137
+ const status = buildStatus({
138
+ codex,
139
+ latestVersion,
140
+ source: 'npm',
141
+ checkedAt: now.toISOString(),
142
+ cachePath
143
+ });
144
+ await ensureDir(path.dirname(cachePath));
145
+ await writeJsonAtomic(cachePath, status).catch(() => null);
146
+ return status;
147
+ }
148
+ export async function updateCodexCliNow(opts = {}) {
149
+ const deps = opts.deps || {};
150
+ const before = await resolveOperatorCodexCli({
151
+ ...(opts.codexBin ? { codexBin: opts.codexBin } : {}),
152
+ ...(opts.env ? { env: opts.env } : {}),
153
+ deps
154
+ });
155
+ if (!before.ok || !before.path || !before.version) {
156
+ return updateResult({
157
+ ok: false,
158
+ status: 'missing',
159
+ before,
160
+ after: null,
161
+ rawOutput: '',
162
+ updateStatus: null,
163
+ command: null,
164
+ updateMethod: 'unknown',
165
+ blockers: ['codex_cli_missing', ...before.blockers],
166
+ guidance: ['Install a release build of Codex CLI on the operator PATH first; SKS does not invent a package-manager fallback.']
167
+ });
168
+ }
169
+ const env = opts.env || process.env;
170
+ const run = deps.runProcessImpl || runProcess;
171
+ const capability = await run(before.path, ['update', '--help'], {
172
+ timeoutMs: 10_000,
173
+ maxOutputBytes: 32 * 1024,
174
+ env
175
+ }).catch((err) => failedProcessResult(err));
176
+ const capabilityOutput = `${capability.stdout || ''}${capability.stderr || ''}`.trim();
177
+ const nativeSelfUpdateSupported = capability.code === 0
178
+ && /Usage:\s+codex\s+update\b/i.test(capabilityOutput);
179
+ const updatePlan = nativeSelfUpdateSupported
180
+ ? {
181
+ method: 'native-self-update',
182
+ command: 'codex update',
183
+ executable: before.path,
184
+ args: ['update']
185
+ }
186
+ : await detectCodexCliUpdatePlan({ before, env, deps, run });
187
+ if (!updatePlan) {
188
+ return updateResult({
189
+ ok: false,
190
+ status: 'failed',
191
+ before,
192
+ after: null,
193
+ rawOutput: capabilityOutput,
194
+ updateStatus: null,
195
+ command: null,
196
+ updateMethod: 'unknown',
197
+ blockers: ['codex_cli_update_method_unverified'],
198
+ guidance: [
199
+ 'The selected Codex CLI neither advertises native self-update nor maps safely to the official standalone installer, npm global package, or Homebrew cask.',
200
+ 'Reinstall Codex with an official supported method, then retry.'
201
+ ]
202
+ });
203
+ }
204
+ const result = updatePlan.method === 'standalone-installer'
205
+ ? await runStandaloneInstallerUpdate({ before, env, deps, run })
206
+ : await run(updatePlan.executable, updatePlan.args, {
207
+ timeoutMs: 180_000,
208
+ maxOutputBytes: 128 * 1024,
209
+ env
210
+ }).catch((err) => failedProcessResult(err));
211
+ const rawOutput = `${result.stdout || ''}${result.stderr || ''}`.trim();
212
+ if (result.code !== 0) {
213
+ return updateResult({
214
+ ok: false,
215
+ status: 'failed',
216
+ before,
217
+ after: null,
218
+ rawOutput,
219
+ updateStatus: null,
220
+ command: updatePlan.command,
221
+ updateMethod: updatePlan.method,
222
+ blockers: [updateFailureBlocker(updatePlan.method)],
223
+ guidance: [`Run the detected updater in a terminal to review its output: ${updatePlan.command}`]
224
+ });
225
+ }
226
+ const after = await resolveOperatorCodexCli({
227
+ ...(opts.codexBin ? { codexBin: opts.codexBin } : {}),
228
+ ...(opts.env ? { env: opts.env } : {}),
229
+ deps
230
+ });
231
+ if (!after.ok || !after.path || !after.version) {
232
+ return updateResult({
233
+ ok: false,
234
+ status: 'failed',
235
+ before,
236
+ after,
237
+ rawOutput,
238
+ updateStatus: null,
239
+ command: updatePlan.command,
240
+ updateMethod: updatePlan.method,
241
+ blockers: ['codex_cli_post_update_missing', ...after.blockers],
242
+ guidance: ['The updater exited successfully, but the operator Codex CLI or its version disappeared. Reinstall Codex CLI and retry the status check.']
243
+ });
244
+ }
245
+ if (after.path !== before.path) {
246
+ return updateResult({
247
+ ok: false,
248
+ status: 'failed',
249
+ before,
250
+ after,
251
+ rawOutput,
252
+ updateStatus: null,
253
+ command: updatePlan.command,
254
+ updateMethod: updatePlan.method,
255
+ blockers: ['codex_cli_post_update_target_changed'],
256
+ guidance: ['The updated Codex CLI path disappeared and resolution fell through to a different installation. Restore or reinstall the original operator CLI before retrying.']
257
+ });
258
+ }
259
+ const versionComparison = compareCodexCliVersions(after.version, before.version);
260
+ if (versionComparison < 0) {
261
+ return updateResult({
262
+ ok: false,
263
+ status: 'failed',
264
+ before,
265
+ after,
266
+ rawOutput,
267
+ updateStatus: null,
268
+ command: updatePlan.command,
269
+ updateMethod: updatePlan.method,
270
+ blockers: ['codex_cli_post_update_version_regressed'],
271
+ guidance: ['The Codex updater returned an older operator CLI version. Restore or reinstall the expected release before retrying.']
272
+ });
273
+ }
274
+ const inspect = deps.inspectCodexCliUpdateImpl || inspectCodexCliUpdate;
275
+ const updateStatus = await inspect({
276
+ ...(opts.home ? { home: opts.home } : {}),
277
+ force: true,
278
+ ...(opts.codexBin ? { codexBin: opts.codexBin } : {}),
279
+ ...(opts.env ? { env: opts.env } : {}),
280
+ deps
281
+ }).catch(() => null);
282
+ const statusName = String(updateStatus?.status || 'missing');
283
+ const statusTrusted = updateStatus?.ok === true
284
+ && updateStatus.installed === true
285
+ && Boolean(updateStatus.cli_path)
286
+ && Boolean(updateStatus.current_version)
287
+ && statusName !== 'missing'
288
+ && statusName !== 'failed';
289
+ if (!statusTrusted) {
290
+ return updateResult({
291
+ ok: false,
292
+ status: 'failed',
293
+ before,
294
+ after,
295
+ rawOutput,
296
+ updateStatus,
297
+ command: updatePlan.command,
298
+ updateMethod: updatePlan.method,
299
+ blockers: ['codex_cli_post_update_status_untrusted'],
300
+ guidance: ['The updater exited successfully, but the refreshed operator CLI status was missing or failed. Verify `codex --version` before retrying.']
301
+ });
302
+ }
303
+ if (updateStatus.cli_path !== after.path || updateStatus.current_version !== after.version) {
304
+ return updateResult({
305
+ ok: false,
306
+ status: 'failed',
307
+ before,
308
+ after,
309
+ rawOutput,
310
+ updateStatus,
311
+ command: updatePlan.command,
312
+ updateMethod: updatePlan.method,
313
+ blockers: ['codex_cli_post_update_status_target_mismatch'],
314
+ guidance: ['The refreshed status described a different Codex CLI path or version. Fix PATH/override precedence before retrying the update.']
315
+ });
316
+ }
317
+ return updateResult({
318
+ ok: true,
319
+ status: versionComparison > 0 ? 'updated' : 'already_current',
320
+ before,
321
+ after,
322
+ rawOutput,
323
+ updateStatus,
324
+ command: updatePlan.command,
325
+ updateMethod: updatePlan.method,
326
+ blockers: [],
327
+ guidance: updateStatus.update_available === true
328
+ ? [`The updater completed, but a newer registry version is still reported. Reopen the menu or rerun: ${updatePlan.command}`]
329
+ : []
330
+ });
331
+ }
332
+ export function codexCliVersionNumber(value) {
333
+ const match = String(value || '').match(/(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/);
334
+ return match?.[1] || null;
335
+ }
336
+ export function officialCodexCliVersionNumber(value) {
337
+ const firstLine = String(value || '').trim().split(/\r?\n/).find((line) => line.trim())?.trim() || '';
338
+ if (!/^codex-cli\s+\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?\s*$/i.test(firstLine))
339
+ return null;
340
+ return codexCliVersionNumber(firstLine);
341
+ }
342
+ export function compareCodexCliVersions(left, right) {
343
+ const a = codexCliVersionNumber(left);
344
+ const b = codexCliVersionNumber(right);
345
+ if (!a || !b)
346
+ return 0;
347
+ const [aCore = '', aPre = ''] = a.split('-', 2);
348
+ const [bCore = '', bPre = ''] = b.split('-', 2);
349
+ const aParts = aCore.split('.').map(Number);
350
+ const bParts = bCore.split('.').map(Number);
351
+ for (let index = 0; index < 3; index += 1) {
352
+ const delta = (aParts[index] || 0) - (bParts[index] || 0);
353
+ if (delta !== 0)
354
+ return delta > 0 ? 1 : -1;
355
+ }
356
+ if (!aPre && !bPre)
357
+ return 0;
358
+ if (!aPre)
359
+ return 1;
360
+ if (!bPre)
361
+ return -1;
362
+ return aPre.localeCompare(bPre, undefined, { numeric: true });
363
+ }
364
+ async function detectCodexCliUpdatePlan(input) {
365
+ const selectedPath = path.resolve(input.before.path);
366
+ const selectedRealPath = await realPathOrResolved(selectedPath);
367
+ const codexHome = await realPathOrResolved(input.env.CODEX_HOME || path.join(input.env.HOME || os.homedir(), '.codex'));
368
+ const standaloneRoot = await realPathOrResolved(path.join(codexHome, 'packages', 'standalone'));
369
+ if (isWithin(selectedRealPath, standaloneRoot)) {
370
+ return {
371
+ method: 'standalone-installer',
372
+ command: process.platform === 'win32'
373
+ ? `powershell -NoProfile -Command "irm ${CODEX_STANDALONE_INSTALLER_PS1_URL} | iex"`
374
+ : `curl -fsSL ${CODEX_STANDALONE_INSTALLER_URL} | CODEX_NON_INTERACTIVE=1 sh`,
375
+ executable: '',
376
+ args: []
377
+ };
378
+ }
379
+ const brew = await resolveUpdateExecutable('brew', input.env, input.deps);
380
+ if (brew) {
381
+ const caskPrefixResult = await input.run(brew, ['--prefix', '--cask', 'codex'], {
382
+ timeoutMs: 10_000,
383
+ maxOutputBytes: 16 * 1024,
384
+ env: input.env
385
+ }).catch((err) => failedProcessResult(err));
386
+ const caskPrefix = caskPrefixResult.code === 0
387
+ ? String(caskPrefixResult.stdout || '').trim().split(/\r?\n/).find(Boolean) || ''
388
+ : '';
389
+ if (caskPrefix && isWithin(selectedRealPath, await realPathOrResolved(caskPrefix))) {
390
+ return {
391
+ method: 'homebrew-cask',
392
+ command: 'brew upgrade --cask codex',
393
+ executable: brew,
394
+ args: ['upgrade', '--cask', 'codex']
395
+ };
396
+ }
397
+ }
398
+ const npm = await resolveUpdateExecutable('npm', input.env, input.deps);
399
+ if (npm) {
400
+ const [rootResult, prefixResult] = await Promise.all([
401
+ input.run(npm, ['root', '-g'], {
402
+ timeoutMs: 10_000,
403
+ maxOutputBytes: 16 * 1024,
404
+ env: input.env
405
+ }).catch((err) => failedProcessResult(err)),
406
+ input.run(npm, ['prefix', '-g'], {
407
+ timeoutMs: 10_000,
408
+ maxOutputBytes: 16 * 1024,
409
+ env: input.env
410
+ }).catch((err) => failedProcessResult(err))
411
+ ]);
412
+ const npmRoot = rootResult.code === 0
413
+ ? String(rootResult.stdout || '').trim().split(/\r?\n/).find(Boolean) || ''
414
+ : '';
415
+ const npmPrefix = prefixResult.code === 0
416
+ ? String(prefixResult.stdout || '').trim().split(/\r?\n/).find(Boolean) || ''
417
+ : '';
418
+ const packageDir = npmRoot ? await realPathOrResolved(path.resolve(npmRoot, '@openai', 'codex')) : '';
419
+ const npmBinCandidates = npmPrefix
420
+ ? process.platform === 'win32'
421
+ ? ['codex.cmd', 'codex.exe', 'codex'].map((name) => path.resolve(npmPrefix, name))
422
+ : [path.resolve(npmPrefix, 'bin', 'codex')]
423
+ : [];
424
+ const packageInstalled = Boolean(packageDir) && await exists(packageDir);
425
+ if (packageInstalled && (isWithin(selectedRealPath, packageDir)
426
+ || npmBinCandidates.includes(selectedPath))) {
427
+ return {
428
+ method: 'npm-global',
429
+ command: 'npm install -g @openai/codex@latest',
430
+ executable: npm,
431
+ args: ['install', '-g', '@openai/codex@latest']
432
+ };
433
+ }
434
+ }
435
+ return null;
436
+ }
437
+ async function runStandaloneInstallerUpdate(input) {
438
+ if (process.platform === 'win32') {
439
+ const powershell = await resolveUpdateExecutable('pwsh', input.env, input.deps)
440
+ || await resolveUpdateExecutable('powershell', input.env, input.deps);
441
+ if (!powershell)
442
+ return failedProcessResult(new Error('codex_cli_standalone_update_prerequisite_missing'));
443
+ const codexHome = path.resolve(input.env.CODEX_HOME || path.join(input.env.HOME || os.homedir(), '.codex'));
444
+ return input.run(powershell, [
445
+ '-NoProfile',
446
+ '-NonInteractive',
447
+ '-ExecutionPolicy',
448
+ 'Bypass',
449
+ '-Command',
450
+ `$ErrorActionPreference='Stop'; Invoke-RestMethod '${CODEX_STANDALONE_INSTALLER_PS1_URL}' | Invoke-Expression`
451
+ ], {
452
+ timeoutMs: 180_000,
453
+ maxOutputBytes: 128 * 1024,
454
+ env: {
455
+ ...input.env,
456
+ CODEX_HOME: codexHome,
457
+ CODEX_INSTALL_DIR: path.dirname(input.before.path),
458
+ CODEX_NON_INTERACTIVE: '1'
459
+ }
460
+ }).catch((err) => failedProcessResult(err));
461
+ }
462
+ const curl = await resolveUpdateExecutable('curl', input.env, input.deps);
463
+ const shell = await resolveUpdateExecutable('sh', input.env, input.deps);
464
+ if (!curl || !shell) {
465
+ return failedProcessResult(new Error('codex_cli_standalone_update_prerequisite_missing'));
466
+ }
467
+ const download = await input.run(curl, ['-fsSL', CODEX_STANDALONE_INSTALLER_URL], {
468
+ timeoutMs: 30_000,
469
+ maxOutputBytes: 512 * 1024,
470
+ env: input.env
471
+ }).catch((err) => failedProcessResult(err));
472
+ const installer = String(download.stdout || '');
473
+ if (download.code !== 0 || !/^#!\/bin\/sh\s*$/m.test(installer) || !installer.includes('CODEX_NON_INTERACTIVE')) {
474
+ return {
475
+ ...download,
476
+ code: download.code === 0 ? 1 : download.code,
477
+ stderr: String(download.stderr || 'codex_cli_standalone_installer_download_untrusted')
478
+ };
479
+ }
480
+ const codexHome = path.resolve(input.env.CODEX_HOME || path.join(input.env.HOME || os.homedir(), '.codex'));
481
+ return input.run(shell, ['-s', '--'], {
482
+ timeoutMs: 180_000,
483
+ maxOutputBytes: 128 * 1024,
484
+ input: installer,
485
+ env: {
486
+ ...input.env,
487
+ CODEX_HOME: codexHome,
488
+ CODEX_INSTALL_DIR: path.dirname(input.before.path),
489
+ CODEX_NON_INTERACTIVE: '1'
490
+ }
491
+ }).catch((err) => failedProcessResult(err));
492
+ }
493
+ async function resolveUpdateExecutable(command, env, deps) {
494
+ return deps.whichImpl
495
+ ? deps.whichImpl(command).catch(() => null)
496
+ : resolveOperatorExecutable(command, env);
497
+ }
498
+ function updateFailureBlocker(method) {
499
+ if (method === 'native-self-update')
500
+ return 'codex_cli_self_update_failed';
501
+ if (method === 'standalone-installer')
502
+ return 'codex_cli_standalone_update_failed';
503
+ if (method === 'homebrew-cask')
504
+ return 'codex_cli_homebrew_cask_update_failed';
505
+ return 'codex_cli_npm_global_update_failed';
506
+ }
507
+ async function realPathOrResolved(value) {
508
+ const resolved = path.resolve(value);
509
+ return fsp.realpath(resolved).catch(() => resolved);
510
+ }
511
+ async function operatorCodexCandidates(explicitBin, env) {
512
+ const candidates = [];
513
+ const seen = new Set();
514
+ const add = (source, candidate) => {
515
+ const value = String(candidate || '').trim();
516
+ if (!value)
517
+ return;
518
+ const normalized = path.resolve(value);
519
+ if (seen.has(normalized))
520
+ return;
521
+ seen.add(normalized);
522
+ candidates.push({ source, path: normalized });
523
+ };
524
+ const explicitValues = [
525
+ explicitBin,
526
+ env.SKS_CODEX_UPDATE_BIN,
527
+ env.SKS_CODEX_BIN,
528
+ env.CODEX_BIN,
529
+ env.DCODEX_CODEX_BIN
530
+ ];
531
+ for (const value of explicitValues) {
532
+ const raw = String(value || '').trim();
533
+ if (!raw)
534
+ continue;
535
+ if (path.isAbsolute(raw) || raw.includes('/') || raw.includes('\\')) {
536
+ add('explicit', raw);
537
+ }
538
+ else {
539
+ const matches = executablePathsOnPath(raw, env);
540
+ if (matches.length)
541
+ for (const match of matches)
542
+ add('explicit', match);
543
+ else
544
+ add('explicit', raw);
545
+ }
546
+ }
547
+ for (const match of executablePathsOnPath('codex', env))
548
+ add('path', match);
549
+ for (const match of await homeOperatorExecutablePaths('codex', env))
550
+ add('path', match);
551
+ return candidates;
552
+ }
553
+ async function resolveOperatorExecutable(command, env) {
554
+ const candidates = [
555
+ ...executablePathsOnPath(command, env),
556
+ ...await homeOperatorExecutablePaths(command, env)
557
+ ];
558
+ for (const candidate of candidates) {
559
+ if (await exists(candidate))
560
+ return candidate;
561
+ }
562
+ return null;
563
+ }
564
+ async function homeOperatorExecutablePaths(command, env) {
565
+ const home = path.resolve(env.HOME || os.homedir());
566
+ const names = process.platform === 'win32'
567
+ ? executableNamesForWindows(command, env.PATHEXT)
568
+ : [command];
569
+ const dirs = [
570
+ path.join(home, '.local', 'bin'),
571
+ path.join(home, '.npm-global', 'bin'),
572
+ path.join(home, '.volta', 'bin'),
573
+ path.join(home, 'Library', 'pnpm'),
574
+ path.join(home, '.local', 'share', 'pnpm')
575
+ ];
576
+ const nvmVersionsDir = path.join(home, '.nvm', 'versions', 'node');
577
+ const nvmVersions = await fsp.readdir(nvmVersionsDir, { withFileTypes: true })
578
+ .then((entries) => entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeInstallNames).reverse())
579
+ .catch(() => []);
580
+ dirs.unshift(...nvmVersions.map((version) => path.join(nvmVersionsDir, version, 'bin')));
581
+ return dirs.flatMap((dir) => names.map((name) => path.join(dir, name)));
582
+ }
583
+ function compareNodeInstallNames(left, right) {
584
+ const parse = (value) => value.replace(/^v/i, '').split('.').map((part) => Number(part) || 0);
585
+ const a = parse(left);
586
+ const b = parse(right);
587
+ for (let index = 0; index < Math.max(a.length, b.length); index += 1) {
588
+ const delta = (a[index] || 0) - (b[index] || 0);
589
+ if (delta !== 0)
590
+ return delta;
591
+ }
592
+ return left.localeCompare(right);
593
+ }
594
+ function executablePathsOnPath(command, env) {
595
+ const names = process.platform === 'win32'
596
+ ? executableNamesForWindows(command, env.PATHEXT)
597
+ : [command];
598
+ const matches = [];
599
+ for (const dir of String(env.PATH || '').split(path.delimiter)) {
600
+ if (!dir)
601
+ continue;
602
+ for (const name of names)
603
+ matches.push(path.join(dir, name));
604
+ }
605
+ return matches;
606
+ }
607
+ function executableNamesForWindows(command, pathExt) {
608
+ if (path.extname(command))
609
+ return [command];
610
+ const extensions = String(pathExt || '.COM;.EXE;.BAT;.CMD')
611
+ .split(';')
612
+ .map((extension) => extension.trim().toLowerCase())
613
+ .filter(Boolean);
614
+ return [command, ...extensions.map((extension) => `${command}${extension}`)];
615
+ }
616
+ async function nonOperatorCodexReason(candidatePath, realPath) {
617
+ const root = packageRoot();
618
+ const ownedRoots = [
619
+ path.join(root, 'node_modules'),
620
+ path.join(root, 'dist', 'vendor', 'openai-codex'),
621
+ path.join(root, 'vendor', 'openai-codex')
622
+ ];
623
+ if (ownedRoots.some((ownedRoot) => isWithin(candidatePath, ownedRoot) || isWithin(realPath, ownedRoot))) {
624
+ return 'sneakoscope_bundled';
625
+ }
626
+ const normalizedPaths = [candidatePath, realPath].map((value) => path.resolve(value).replaceAll('\\', '/'));
627
+ if (normalizedPaths.some((value) => /(?:^|\/)node_modules\/sneakoscope(?:\/|$)/.test(value))) {
628
+ return 'sneakoscope_bundled';
629
+ }
630
+ for (const value of normalizedPaths) {
631
+ if (/(?:^|\/)node_modules\/\.bin(?:\/|$)/.test(value))
632
+ return 'project_local';
633
+ const marker = '/node_modules/';
634
+ const index = value.indexOf(marker);
635
+ if (index <= 0)
636
+ continue;
637
+ const ownerRoot = value.slice(0, index);
638
+ if (await exists(path.join(ownerRoot, 'package.json')))
639
+ return 'project_local';
640
+ }
641
+ return null;
642
+ }
643
+ function isWithin(candidate, parent) {
644
+ const relative = path.relative(path.resolve(parent), path.resolve(candidate));
645
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
646
+ }
647
+ function buildStatus(input) {
648
+ const updateAvailable = compareCodexCliVersions(input.latestVersion, input.codex.version) > 0;
649
+ return {
650
+ schema: CODEX_CLI_UPDATE_STATUS_SCHEMA,
651
+ ok: true,
652
+ status: updateAvailable ? 'update_available' : 'current',
653
+ installed: true,
654
+ bin: input.codex.path,
655
+ cli_path: input.codex.path,
656
+ cli_source: input.codex.source,
657
+ current_version: input.codex.version,
658
+ raw_version: input.codex.raw_version,
659
+ latest_version: input.latestVersion,
660
+ update_available: updateAvailable,
661
+ update_command: 'sks codex update',
662
+ source: input.source,
663
+ checked_at: input.checkedAt,
664
+ cache_path: input.cachePath,
665
+ warnings: input.codex.warnings,
666
+ blockers: [],
667
+ guidance: updateAvailable ? ['Run `sks codex update` or choose Update Codex CLI Now in the SKS menu bar.'] : []
668
+ };
669
+ }
670
+ function unavailableStatus(codex, now, cachePath, warning) {
671
+ return {
672
+ schema: CODEX_CLI_UPDATE_STATUS_SCHEMA,
673
+ ok: true,
674
+ status: 'update_check_unavailable',
675
+ installed: true,
676
+ bin: codex.path,
677
+ cli_path: codex.path,
678
+ cli_source: codex.source,
679
+ current_version: codex.version,
680
+ raw_version: codex.raw_version,
681
+ latest_version: null,
682
+ update_available: null,
683
+ update_command: 'sks codex update',
684
+ source: 'unavailable',
685
+ checked_at: now.toISOString(),
686
+ cache_path: cachePath,
687
+ warnings: [...codex.warnings, warning],
688
+ blockers: [],
689
+ guidance: ['Current Codex CLI version is shown, but the latest-version check could not be completed.']
690
+ };
691
+ }
692
+ function updateResult(input) {
693
+ return {
694
+ schema: CODEX_CLI_UPDATE_RESULT_SCHEMA,
695
+ ok: input.ok,
696
+ status: input.status,
697
+ command: input.command,
698
+ update_method: input.updateMethod,
699
+ bin: input.before.path,
700
+ cli_path: input.before.path,
701
+ cli_source: input.before.source,
702
+ post_update_cli_path: input.after?.path || null,
703
+ post_update_cli_source: input.after?.source || 'unavailable',
704
+ before_version: input.before.version,
705
+ after_version: input.after?.version || null,
706
+ raw_output: input.rawOutput,
707
+ update_status: input.updateStatus,
708
+ blockers: input.blockers,
709
+ guidance: input.guidance
710
+ };
711
+ }
712
+ function failedProcessResult(err) {
713
+ return {
714
+ code: 1,
715
+ stdout: '',
716
+ stderr: err instanceof Error ? err.message : String(err),
717
+ stdoutBytes: 0,
718
+ stderrBytes: 0,
719
+ truncated: false,
720
+ timedOut: false
721
+ };
722
+ }
723
+ //# sourceMappingURL=codex-cli-update.js.map