sneakoscope 8.0.2 → 8.0.4

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 (376) hide show
  1. package/README.md +150 -37
  2. package/config/skills-hash-ledger.v1.json +1 -1
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/dist/bin/fast-inline.js +55 -27
  6. package/dist/bin/install.js +6 -32
  7. package/dist/bin/sks-dispatch.js +1 -1
  8. package/dist/cli/args.js +0 -2
  9. package/dist/cli/cli-theme.js +18 -9
  10. package/dist/cli/command-manifest-lite.js +6 -6
  11. package/dist/cli/command-registry.js +6 -6
  12. package/dist/cli/feature-commands.js +9 -7
  13. package/dist/cli/install-helpers-codex-lb-chain.js +198 -7
  14. package/dist/cli/install-helpers-codex-lb-config.js +78 -10
  15. package/dist/cli/install-helpers-install-support.js +9 -6
  16. package/dist/cli/install-helpers.js +101 -49
  17. package/dist/cli/install-tool-helpers.js +2 -82
  18. package/dist/cli/output.js +6 -1
  19. package/dist/cli/router.js +101 -2
  20. package/dist/commands/codex-lb.js +119 -19
  21. package/dist/commands/doctor-profile.js +1 -1
  22. package/dist/commands/doctor.js +727 -144
  23. package/dist/commands/mad-sks.js +1 -5
  24. package/dist/config/skills-manifest.json +4 -2
  25. package/dist/core/agents/agent-codex-cockpit.js +0 -3
  26. package/dist/core/agents/agent-effort-policy.js +5 -5
  27. package/dist/core/agents/agent-janitor.js +0 -20
  28. package/dist/core/agents/agent-orchestrator.js +9 -56
  29. package/dist/core/agents/agent-output-validator.js +2 -3
  30. package/dist/core/agents/agent-patch-schema.js +2 -2
  31. package/dist/core/agents/agent-proof-evidence.js +0 -65
  32. package/dist/core/agents/agent-recursion-guard.js +1 -1
  33. package/dist/core/agents/agent-runner-codex-exec.js +5 -3
  34. package/dist/core/agents/agent-scheduler.js +327 -85
  35. package/dist/core/agents/agent-schema.js +1 -1
  36. package/dist/core/agents/agent-trust-report.js +0 -36
  37. package/dist/core/agents/agent-worker-pipeline.js +0 -1
  38. package/dist/core/agents/fast-mode-policy.js +1 -3
  39. package/dist/core/agents/native-cli-worker-runtime-proof.js +1 -1
  40. package/dist/core/agents/native-cli-worker-runtime.js +69 -647
  41. package/dist/core/agents/native-cli-worker.js +6 -7
  42. package/dist/core/agents/native-worker-backend-router.js +2 -32
  43. package/dist/core/agents/no-subagent-scaling-policy.js +1 -1
  44. package/dist/core/agents/parallel-runtime-proof.js +1 -6
  45. package/dist/core/agents/runtime-proof-summary.js +1 -35
  46. package/dist/core/architecture-hardening/contracts/contracts.js +193 -0
  47. package/dist/core/architecture-hardening/migration/migration.js +111 -0
  48. package/dist/core/architecture-hardening/state/state-service.js +155 -0
  49. package/dist/core/artifact-schemas.js +0 -3
  50. package/dist/core/codex/codex-config-guard.js +238 -52
  51. package/dist/core/codex-adapter.js +5 -3
  52. package/dist/core/codex-app/auxiliary-oauth-policy.js +36 -0
  53. package/dist/core/codex-app/catalog-compat/catalog-service.js +104 -0
  54. package/dist/core/codex-app/child-policy/child-policy.js +35 -0
  55. package/dist/core/codex-app/codex-app-handoff.js +0 -1
  56. package/dist/core/codex-app/codex-hook-lifecycle.js +1 -1
  57. package/dist/core/codex-app/codex-init-deep.js +1 -1
  58. package/dist/core/codex-app/menubar/app-bundle.js +2 -0
  59. package/dist/core/codex-app/menubar/constants.js +14 -1
  60. package/dist/core/codex-app/menubar/global-install.js +288 -0
  61. package/dist/core/codex-app/menubar/installer.js +79 -14
  62. package/dist/core/codex-app/menubar/launch-agent.js +267 -45
  63. package/dist/core/codex-app/menubar/paths.js +3 -0
  64. package/dist/core/codex-app/menubar/rollback.js +55 -7
  65. package/dist/core/codex-app/menubar/status.js +75 -4
  66. package/dist/core/codex-app/provider-child-policy.js +64 -0
  67. package/dist/core/codex-app/provider-mode.js +91 -0
  68. package/dist/core/codex-app/provider-operation-stages.js +20 -0
  69. package/dist/core/codex-app/provider-session-policy.js +85 -0
  70. package/dist/core/codex-app/session-policy/session-pinning.js +68 -0
  71. package/dist/core/codex-app.js +3 -2
  72. package/dist/core/codex-control/codex-0139-image-path-real-probe.js +3 -1
  73. package/dist/core/codex-control/codex-0139-web-search-probe.js +3 -1
  74. package/dist/core/codex-control/codex-app-server-runtime-env.js +13 -4
  75. package/dist/core/codex-control/codex-app-server-v2-client.js +3 -3
  76. package/dist/core/codex-control/codex-control-proof.js +0 -1
  77. package/dist/core/codex-control/codex-task-runner.js +1 -4
  78. package/dist/core/codex-exec-output-schema.js +4 -1
  79. package/dist/core/codex-lb/codex-lb-env.js +63 -72
  80. package/dist/core/codex-lb/codex-lb-setup.js +15 -2
  81. package/dist/core/codex-lb/desktop-bridge/header-policy.js +6 -0
  82. package/dist/core/codex-lb/desktop-bridge/http-forward.js +48 -6
  83. package/dist/core/codex-lb/desktop-bridge/security.js +134 -0
  84. package/dist/core/codex-lb/desktop-bridge/server.js +9 -3
  85. package/dist/core/codex-lb/desktop-bridge/state.js +26 -6
  86. package/dist/core/codex-lb/desktop-bridge/types.js +1 -0
  87. package/dist/core/codex-lb/desktop-center-credentials.js +517 -58
  88. package/dist/core/codex-lb/desktop-controller.js +177 -56
  89. package/dist/core/codex-lb/desktop-service.js +179 -40
  90. package/dist/core/codex-lb/legacy-migration.js +1 -3
  91. package/dist/core/codex-lb/native-openai-transport/transport.js +68 -0
  92. package/dist/core/codex-lb/probes/cli-image-tool-probe.js +1 -1
  93. package/dist/core/codex-lb/provider-routing/provider-router.js +58 -0
  94. package/dist/core/codex-lb/routing-truth.js +327 -0
  95. package/dist/core/codex-native/codex-native-feature-broker.js +4 -0
  96. package/dist/core/codex-native/codex-native-pattern-analysis.js +1 -2
  97. package/dist/core/codex-native/core-skill-manifest.js +1 -1
  98. package/dist/core/codex-plugins/codex-plugin-json.js +26 -6
  99. package/dist/core/codex-plugins/codex-plugin-repair.js +32 -6
  100. package/dist/core/commands/basic-cli.js +9 -7
  101. package/dist/core/commands/computer-use-command.js +1 -1
  102. package/dist/core/commands/image-ux-review-command.js +16 -9
  103. package/dist/core/commands/install-package-command.js +105 -0
  104. package/dist/core/commands/intent-normalization/normalizer.js +96 -0
  105. package/dist/core/commands/mad-sks-command.js +23 -274
  106. package/dist/core/commands/mad-sks-headless.js +11 -30
  107. package/dist/core/commands/naruto-command.js +0 -25
  108. package/dist/core/commands/qa-loop-command.js +104 -22
  109. package/dist/core/commands/remote-command.js +2 -2
  110. package/dist/core/commands/research-command.js +10 -5
  111. package/dist/core/commands/telegram-command.js +407 -0
  112. package/dist/core/config-adopt/config-adopt-command.js +35 -0
  113. package/dist/core/config-adopt/config-adopt.js +346 -0
  114. package/dist/core/config-adopt/index.js +3 -0
  115. package/dist/core/doctor/command-alias-cleanup.js +4 -1
  116. package/dist/core/doctor/current-project-guidance-nested.js +37 -6
  117. package/dist/core/doctor/current-project-guidance.js +15 -9
  118. package/dist/core/doctor/doctor-dirty-planner.js +1 -4
  119. package/dist/core/doctor/doctor-readiness-matrix.js +15 -18
  120. package/dist/core/doctor/retired-managed-residue-private.js +4 -3
  121. package/dist/core/doctor/retired-managed-residue-runtime.js +2 -2
  122. package/dist/core/doctor/skill-legacy-surface.js +11 -10
  123. package/dist/core/doctor/sks-menubar-doctor.js +4 -0
  124. package/dist/core/evaluation.js +0 -19
  125. package/dist/core/evidence/v2/evidence-key.js +105 -0
  126. package/dist/core/feature-fixtures.js +12 -7
  127. package/dist/core/feature-registry.js +52 -21
  128. package/dist/core/hooks-runtime/hook-context.js +9 -0
  129. package/dist/core/hooks-runtime/managed-skill-admission.js +54 -4
  130. package/dist/core/hooks-runtime/official-subagent-lifecycle.js +69 -52
  131. package/dist/core/hooks-runtime/stop-finalization.js +226 -0
  132. package/dist/core/hooks-runtime/stop-repeat-guard.js +21 -2
  133. package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +2 -2
  134. package/dist/core/hooks-runtime/subagent-skill-availability-evidence.js +3 -3
  135. package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +43 -5
  136. package/dist/core/hooks-runtime/subagent-skill-availability.js +64 -30
  137. package/dist/core/hooks-runtime/subagent-stop-hook.js +15 -2
  138. package/dist/core/hooks-runtime.js +179 -212
  139. package/dist/core/image/reference-evidence/reference-registry.js +145 -0
  140. package/dist/core/image-ux-review/imagegen-adapter.js +21 -9
  141. package/dist/core/image-ux-review/reference-policy/reference-policy.js +9 -0
  142. package/dist/core/imagegen/codex-lb-imagegen-target.js +8 -0
  143. package/dist/core/imagegen/imagegen-capability.js +59 -2
  144. package/dist/core/imagegen/require-imagegen.js +2 -2
  145. package/dist/core/init/skills.js +17 -3
  146. package/dist/core/init.js +3 -3
  147. package/dist/core/install/installed-package-smoke.js +23 -5
  148. package/dist/core/json/canonical.js +9 -0
  149. package/dist/core/locks/file-lock.js +0 -1
  150. package/dist/core/loops/loop-continuation-enforcer.js +65 -7
  151. package/dist/core/loops/loop-decomposer.js +0 -1
  152. package/dist/core/loops/loop-gate-runner.js +65 -4
  153. package/dist/core/loops/loop-gate-selector.js +0 -2
  154. package/dist/core/loops/loop-proof-validation.js +38 -0
  155. package/dist/core/loops/loop-risk-classifier.js +1 -1
  156. package/dist/core/loops/loop-runtime.js +14 -2
  157. package/dist/core/loops/loop-scheduler.js +7 -2
  158. package/dist/core/loops/loop-worker-runtime.js +0 -15
  159. package/dist/core/loops/loop-worktree-runtime.js +52 -4
  160. package/dist/core/managed-assets/managed-assets-manifest.js +14 -14
  161. package/dist/core/naruto/hardware-capacity-probe.js +9 -6
  162. package/dist/core/naruto/naruto-active-pool.js +2 -14
  163. package/dist/core/naruto/naruto-concurrency-governor.js +71 -31
  164. package/dist/core/naruto/naruto-loop-worker-router.js +0 -2
  165. package/dist/core/naruto/naruto-verification-dag.js +0 -1
  166. package/dist/core/naruto/naruto-write-e2e.js +1 -2
  167. package/dist/core/naruto/resource-pressure-monitor.js +0 -4
  168. package/dist/core/observability/architecture-hardening/safe-projection.js +65 -0
  169. package/dist/core/perf/import-graph-budget.js +0 -1
  170. package/dist/core/perf/release-latency-slo.js +3 -2
  171. package/dist/core/preflight/parallel-preflight-engine.js +2 -15
  172. package/dist/core/product-design-app-server.js +13 -1
  173. package/dist/core/proof/fake-real-proof-policy.js +2 -17
  174. package/dist/core/proof/route-proof-gate.js +2 -10
  175. package/dist/core/proof/route-proof-policy.js +1 -1
  176. package/dist/core/proof/runtime-evidence-policy.js +185 -0
  177. package/dist/core/proof/runtime-truth-matrix.js +64 -39
  178. package/dist/core/proof/validation.js +27 -11
  179. package/dist/core/provider/provider-context.js +18 -2
  180. package/dist/core/providers/openrouter/openrouter-account.js +3 -2
  181. package/dist/core/python-tools/python-tool-runner.js +1 -1
  182. package/dist/core/qa-loop/qa-execution-control.js +57 -0
  183. package/dist/core/questions.js +1 -1
  184. package/dist/core/release/extreme-parallel-scheduler.js +0 -3
  185. package/dist/core/release/gate-manifest.js +3 -7
  186. package/dist/core/release/gate-pack-manifest.js +3 -7
  187. package/dist/core/release/package-size-budget.js +2 -2
  188. package/dist/core/release/physical-release-gates.js +189 -0
  189. package/dist/core/release/publish-preflight.js +113 -0
  190. package/dist/core/release/release-gate-affected-selector.js +0 -2
  191. package/dist/core/release/release-gate-batch-runner.js +1 -1
  192. package/dist/core/release/release-gate-node.js +0 -1
  193. package/dist/core/release/release-gate-resource-governor.js +0 -1
  194. package/dist/core/release/release-pack-receipt.js +5 -8
  195. package/dist/core/release/release-real-contract.js +0 -6
  196. package/dist/core/release/resource-class-budget.js +0 -1
  197. package/dist/core/release/stage-publish.js +178 -36
  198. package/dist/core/research/research-adversarial-review.js +103 -9
  199. package/dist/core/research.js +1 -1
  200. package/dist/core/retention.js +0 -1
  201. package/dist/core/routes/constants.js +1 -1
  202. package/dist/core/routes/diagnostic-allowlist.js +0 -1
  203. package/dist/core/routes/dollar-manifest-lite.js +1 -1
  204. package/dist/core/routes.js +46 -15
  205. package/dist/core/runtime/execution-control.js +226 -0
  206. package/dist/core/runtime/progress-recovery/progress-recovery.js +89 -0
  207. package/dist/core/runtime/task-profile.js +10 -4
  208. package/dist/core/runtime/verification-budget.js +10 -1
  209. package/dist/core/safety/intent-contract/intent-contract.js +94 -0
  210. package/dist/core/safety/mutation-guard.js +0 -2
  211. package/dist/core/safety/mutation-ledger.js +0 -2
  212. package/dist/core/safety/requested-scope-contract.js +0 -0
  213. package/dist/core/search-visibility/discovery.js +1 -1
  214. package/dist/core/search-visibility/index.js +12 -0
  215. package/dist/core/search-visibility/verifier.js +112 -3
  216. package/dist/core/security/private-credential-file.js +209 -0
  217. package/dist/core/session/project-namespace.js +0 -5
  218. package/dist/core/skills/skill-agent-metadata.js +1 -3
  219. package/dist/core/strategy/adhd-orchestrating-gate.js +0 -1
  220. package/dist/core/subagents/agent-catalog.js +19 -34
  221. package/dist/core/subagents/model-policy.js +65 -24
  222. package/dist/core/subagents/naruto-help-contract.js +8 -8
  223. package/dist/core/subagents/naruto-host-credentials.js +13 -0
  224. package/dist/core/subagents/official-subagent-config.js +16 -6
  225. package/dist/core/subagents/official-subagent-preparation.js +35 -16
  226. package/dist/core/subagents/official-subagent-prompt.js +7 -7
  227. package/dist/core/subagents/official-subagent-runner.js +27 -4
  228. package/dist/core/subagents/role-model-preferences.js +1 -1
  229. package/dist/core/subagents/thread-budget.js +19 -12
  230. package/dist/core/subagents/wave-lifecycle.js +18 -6
  231. package/dist/core/telegram/access.js +58 -0
  232. package/dist/core/telegram/client.js +157 -0
  233. package/dist/core/telegram/confirmation.js +37 -0
  234. package/dist/core/telegram/doctor.js +154 -0
  235. package/dist/core/telegram/index.js +9 -0
  236. package/dist/core/telegram/keychain.js +317 -0
  237. package/dist/core/telegram/liveness.js +118 -0
  238. package/dist/core/telegram/poller.js +90 -0
  239. package/dist/core/telegram/redaction.js +15 -0
  240. package/dist/core/telegram/state-lock.js +416 -0
  241. package/dist/core/telegram/types.js +1 -0
  242. package/dist/core/text/strings.js +3 -0
  243. package/dist/core/triwiki/context-graph/store/evidence-write-lock.js +29 -0
  244. package/dist/core/triwiki/context-graph/store/fragment-cache.js +24 -0
  245. package/dist/core/triwiki/context-graph/store/snapshot-store.js +69 -21
  246. package/dist/core/triwiki/triwiki-gate-impact-map.js +2 -2
  247. package/dist/core/triwiki/triwiki-module-card.js +1 -2
  248. package/dist/core/update/installed-cli-resolution.js +170 -0
  249. package/dist/core/update/update-diagnostics.js +52 -0
  250. package/dist/core/update/update-migration-state.js +30 -12
  251. package/dist/core/update/update-operation.js +2 -1
  252. package/dist/core/update/update-stage-diagnostics.js +38 -0
  253. package/dist/core/update/update-status.js +2 -9
  254. package/dist/core/update-check.js +279 -91
  255. package/dist/core/version.js +1 -1
  256. package/dist/native/sks-menubar/Sources/AppDelegate.swift +19 -1
  257. package/dist/native/sks-menubar/Sources/AppIdentity.swift +7 -0
  258. package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +6 -2
  259. package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +159 -92
  260. package/dist/native/sks-menubar/Sources/OperationModels.swift +389 -0
  261. package/dist/native/sks-menubar/Sources/OverviewViewController.swift +57 -0
  262. package/dist/native/sks-menubar/Sources/ProcessClient.swift +3 -1
  263. package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +115 -0
  264. package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +17 -0
  265. package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +3 -0
  266. package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +58 -17
  267. package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +302 -0
  268. package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +5 -0
  269. package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +190 -0
  270. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +158 -126
  271. package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +462 -26
  272. package/dist/native/sks-menubar/Sources/SKSKeychainStore.swift +344 -0
  273. package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +27 -0
  274. package/dist/native/sks-menubar/Sources/SingletonInstanceGuard.swift +328 -0
  275. package/dist/native/sks-menubar/Sources/StatusItemController.swift +10 -2
  276. package/dist/native/sks-menubar/Sources/TelegramPrivateFileStore.swift +498 -0
  277. package/dist/native/sks-menubar/Sources/TelegramPrivateFileSupport.swift +236 -0
  278. package/dist/native/sks-menubar/Sources/TelegramProcessGateway.swift +454 -0
  279. package/dist/native/sks-menubar/Sources/TelegramRuntimeSupport.swift +56 -0
  280. package/dist/native/sks-menubar/Sources/TelegramStateLock.swift +448 -0
  281. package/dist/native/sks-menubar/Sources/TelegramSupport.swift +187 -0
  282. package/dist/native/sks-menubar/Sources/TelegramTransport.swift +499 -0
  283. package/dist/native/sks-menubar/Sources/main.swift +15 -1
  284. package/dist/scripts/all-feature-deep-completion-check.js +5 -1
  285. package/dist/scripts/check-publish-tag.js +56 -0
  286. package/dist/scripts/codex-lb-fast-mode-truth-check.js +10 -3
  287. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +12 -3
  288. package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +4 -2
  289. package/dist/scripts/codex-native-agent-role-content-check.js +3 -3
  290. package/dist/scripts/codex-native-gate-lib.js +14 -7
  291. package/dist/scripts/current-command-surface-check.js +7 -7
  292. package/dist/scripts/current-surface-update-e2e-check.js +4 -3
  293. package/dist/scripts/current-upgrade-matrix-check.js +5 -24
  294. package/dist/scripts/docs-truthfulness-check.js +17 -13
  295. package/dist/scripts/gate-lib.js +0 -2
  296. package/dist/scripts/gate-policy-audit-check.js +3 -2
  297. package/dist/scripts/harness-benchmark-check.js +1 -1
  298. package/dist/scripts/init-deep-backup-retention-check.js +1 -1
  299. package/dist/scripts/lib/codex-sdk-gate-lib.js +1 -2
  300. package/dist/scripts/loop-directive-check-lib.js +28 -38
  301. package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +14 -180
  302. package/dist/scripts/mad-sks-launch-sql-plane-boundary-check.js +2 -11
  303. package/dist/scripts/official-subagent-workflow-check.js +1 -1
  304. package/dist/scripts/packlist-performance-check.js +1 -2
  305. package/dist/scripts/prepublish-release-check-or-fast.js +32 -0
  306. package/dist/scripts/publish-preflight.js +12 -0
  307. package/dist/scripts/release-affected-selector-check.js +2 -2
  308. package/dist/scripts/release-gate-batch-runner-check.js +2 -2
  309. package/dist/scripts/release-metadata-check.js +8 -12
  310. package/dist/scripts/release-real-check.js +2 -54
  311. package/dist/scripts/runtime-domain-gate-lib.js +2 -96
  312. package/dist/scripts/runtime-proof-summary-check.js +2 -6
  313. package/dist/scripts/search-visibility-gate-lib.js +0 -1
  314. package/dist/scripts/sks-cli-gate-lib.js +1 -1
  315. package/dist/scripts/typed-routing-gate-lib.js +7 -59
  316. package/docs/demo.tape +1 -1
  317. package/infra-harness-gates.json +1 -1456
  318. package/package.json +10 -7
  319. package/release-gates.v2.json +0 -1
  320. package/schemas/agents/parallel-runtime-proof.schema.json +0 -2
  321. package/schemas/codex/agent-result.schema.json +0 -6
  322. package/schemas/naruto/naruto-concurrency-governor.schema.json +1 -3
  323. package/schemas/release/release-gate-node.schema.json +1 -1
  324. package/dist/commands/zellij-lane.js +0 -22
  325. package/dist/commands/zellij-monitor-pane.js +0 -26
  326. package/dist/commands/zellij-slot-column-anchor.js +0 -22
  327. package/dist/commands/zellij-slot-pane.js +0 -80
  328. package/dist/commands/zellij-viewport-pane.js +0 -57
  329. package/dist/commands/zellij.js +0 -422
  330. package/dist/core/agents/agent-runner-zellij.js +0 -164
  331. package/dist/core/agents/agent-slot-pane-binding-proof.js +0 -96
  332. package/dist/core/agents/parallel-write-fixture.js +0 -305
  333. package/dist/core/agents/worker-pane-communication-contract.js +0 -100
  334. package/dist/core/agents/zellij-lane-supervisor.js +0 -428
  335. package/dist/core/agents/zellij-right-lane-cockpit.js +0 -66
  336. package/dist/core/doctor/doctor-zellij-repair.js +0 -40
  337. package/dist/core/ops/upgrade-migration-fixtures.js +0 -119
  338. package/dist/core/proof/route-finalizer-fixtures.js +0 -21
  339. package/dist/core/zellij/homebrew-policy.js +0 -43
  340. package/dist/core/zellij/zellij-capability.js +0 -126
  341. package/dist/core/zellij/zellij-clipboard-config.js +0 -52
  342. package/dist/core/zellij/zellij-command.js +0 -149
  343. package/dist/core/zellij/zellij-fake-adapter.js +0 -186
  344. package/dist/core/zellij/zellij-lane-renderer.js +0 -706
  345. package/dist/core/zellij/zellij-lane-runtime.js +0 -189
  346. package/dist/core/zellij/zellij-launcher.js +0 -268
  347. package/dist/core/zellij/zellij-layout-builder.js +0 -191
  348. package/dist/core/zellij/zellij-monitor-renderer.js +0 -52
  349. package/dist/core/zellij/zellij-official-subagent-activity.js +0 -526
  350. package/dist/core/zellij/zellij-official-subagent-telemetry.js +0 -258
  351. package/dist/core/zellij/zellij-pane-proof.js +0 -226
  352. package/dist/core/zellij/zellij-right-column-manager.js +0 -308
  353. package/dist/core/zellij/zellij-screen-proof.js +0 -120
  354. package/dist/core/zellij/zellij-self-heal-types.js +0 -44
  355. package/dist/core/zellij/zellij-self-heal.js +0 -408
  356. package/dist/core/zellij/zellij-slot-column-anchor.js +0 -304
  357. package/dist/core/zellij/zellij-slot-pane-renderer.js +0 -521
  358. package/dist/core/zellij/zellij-slot-telemetry.js +0 -384
  359. package/dist/core/zellij/zellij-theme.js +0 -66
  360. package/dist/core/zellij/zellij-ui-mode.js +0 -34
  361. package/dist/core/zellij/zellij-update.js +0 -348
  362. package/dist/core/zellij/zellij-viewport-binder.js +0 -61
  363. package/dist/core/zellij/zellij-worker-pane-manager.js +0 -881
  364. package/dist/core/zellij/zellij-worker-pane-summary.js +0 -64
  365. package/dist/native/sks-menubar/Tests/AppRuntimeTestSupport.swift +0 -26
  366. package/dist/native/sks-menubar/Tests/OperationCoordinatorTests.swift +0 -174
  367. package/dist/native/sks-menubar/Tests/ProcessClientTests.swift +0 -20
  368. package/dist/native/sks-menubar/Tests/ProvidersViewControllerTests.swift +0 -142
  369. package/dist/scripts/zellij-pane-proof-check.js +0 -88
  370. package/dist/scripts/zellij-real-session-cleanup-check.js +0 -139
  371. package/dist/scripts/zellij-real-session-launch-check.js +0 -126
  372. package/dist/scripts/zellij-screen-proof-check.js +0 -43
  373. package/schemas/zellij/zellij-right-column-state.schema.json +0 -40
  374. package/schemas/zellij/zellij-slot-telemetry.schema.json +0 -89
  375. package/schemas/zellij/zellij-worker-pane.schema.json +0 -53
  376. package/scripts/build-clean-atomic.mjs +0 -323
@@ -1,6 +1,7 @@
1
1
  import os from 'node:os';
2
2
  import path from 'node:path';
3
- import { projectRoot, exists, formatBytes, nowIso, writeJsonAtomic } from '../core/fsx.js';
3
+ import { createHash } from 'node:crypto';
4
+ import { projectRoot, exists, formatBytes, nowIso, readText, writeJsonAtomic } from '../core/fsx.js';
4
5
  import { flag } from '../cli/args.js';
5
6
  import { printJson } from '../cli/output.js';
6
7
  import { ui as cliUi } from '../cli/cli-theme.js';
@@ -10,10 +11,18 @@ import { codexAppIntegrationStatus } from '../core/codex-app.js';
10
11
  import { codexLbMetrics, readCodexLbCircuit } from '../core/codex-lb-circuit.js';
11
12
  import { codexLbStatus } from '../cli/install-helpers.js';
12
13
  import { codexLbToolOutputRecoveryOverrideAcknowledged } from '../core/codex-lb/codex-lb-tool-output-recovery.js';
14
+ import { codexLbEnvPath, loadCodexLbEnv } from '../core/codex-lb/codex-lb-env.js';
15
+ import { codexLbLegacyKeychainMigrationStampPath, inspectDesktopCenterLaunchCredentials, inspectCodexLbLegacyKeychainMigration, repairCodexLbLegacyKeychainMigration, syncDesktopCenterLaunchCredentials } from '../core/codex-lb/desktop-center-credentials.js';
16
+ import { codexLbRoutingTruthIsActive, measureAndWriteCodexLbRoutingTruth, readCodexLbRoutingTruthReceipt } from '../core/codex-lb/routing-truth.js';
17
+ import { removeCodexLbOrphanManagedMarkers } from '../cli/install-helpers-codex-lb-config.js';
18
+ import { safeWriteCodexConfigToml } from '../core/codex-runtime/codex-desktop-config-policy.js';
19
+ import { probeTelegram, telegramSelfHealAction } from '../core/telegram/doctor.js';
20
+ import { TelegramClient } from '../core/telegram/client.js';
21
+ import { resolveTelegramBotToken } from '../core/telegram/keychain.js';
22
+ import { telegramLivenessPath } from '../core/telegram/liveness.js';
13
23
  import { normalizeInstallScope } from '../core/init.js';
14
24
  import { inspectCodexConfigReadability } from '../core/codex/codex-config-readability.js';
15
25
  import { inspectOAuthCallbackPortConflict, oauthCallbackDoctorGuidance } from '../core/codex/oauth-callback-port-diagnostic.js';
16
- import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
17
26
  import { inventoryCodexPermissionProfiles } from '../core/codex/codex-permission-profiles.js';
18
27
  import { appendMigrationEvents, hashConfigText } from '../core/migration/migration-transaction-journal.js';
19
28
  import { resolveProviderContext } from '../core/provider/provider-context.js';
@@ -27,13 +36,18 @@ import { withSecretPreservationGuard } from '../core/config/config-migration-jou
27
36
  import { reconcileDoctorSkills } from '../core/doctor/doctor-skill-reconcile.js';
28
37
  import { buildSksMenuBarDoctorPostcheck } from '../core/doctor/sks-menubar-doctor.js';
29
38
  import { isUpdateMigrationReceiptCurrent, projectUpdateMigrationReceiptPath, writeProjectUpdateMigrationReceipt } from '../core/update/update-migration-state.js';
30
- import { inspectSksMenuBarStatus, installSksMenuBar, sksMenuBarRestartDeferred } from '../core/codex-app/menubar/index.js';
39
+ import { inspectSksMenuBarStatus, installSksMenuBar, sksMenuBarPaths, sksMenuBarRestartDeferred } from '../core/codex-app/menubar/index.js';
40
+ import { restartLaunchAgent } from '../core/codex-app/menubar/launch-agent.js';
31
41
  import { sweepSksTempDirs } from '../core/retention.js';
32
42
  import { detectImagegenCapability } from '../core/imagegen/imagegen-capability.js';
33
43
  import { CURRENT_CODEX_RELEASE_MANIFEST } from '../core/codex-compat/codex-release-manifest.js';
34
44
  import { formatHarnessConflictReport, scanHarnessConflicts } from '../core/harness-conflicts.js';
35
- import { doctorArgWarnings, doctorMenuBarInstallPolicy, doctorPhaseIdsForProfile, doctorProfileFromArgs } from './doctor-profile.js';
36
- export { doctorArgWarnings, doctorMenuBarInstallPolicy, doctorProfileFromArgs } from './doctor-profile.js';
45
+ import { doctorArgWarnings as baseDoctorArgWarnings, doctorMenuBarInstallPolicy, doctorPhaseIdsForProfile, doctorProfileFromArgs } from './doctor-profile.js';
46
+ export { doctorMenuBarInstallPolicy, doctorProfileFromArgs } from './doctor-profile.js';
47
+ const CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG = '--retry-codex-lb-keychain-migration';
48
+ export function doctorArgWarnings(args = []) {
49
+ return baseDoctorArgWarnings(args.filter((arg) => arg !== CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG));
50
+ }
37
51
  export function deferCommandAliasCleanupToMigrationReceipt(result) {
38
52
  const observedBlockers = Array.isArray(result?.blockers)
39
53
  ? result.blockers.map(String).filter(Boolean)
@@ -53,6 +67,196 @@ export function deferCommandAliasCleanupToMigrationReceipt(result) {
53
67
  ]
54
68
  };
55
69
  }
70
+ export async function inspectDoctorCodexLbSecretResolution(input = {}, deps = {}) {
71
+ const processEnv = input.processEnv || process.env;
72
+ const home = path.resolve(input.home || processEnv.HOME || os.homedir());
73
+ const suppliedMigrationOptions = input.migrationOptions || {};
74
+ const migrationOptions = {
75
+ ...suppliedMigrationOptions,
76
+ home,
77
+ env: suppliedMigrationOptions.env || processEnv,
78
+ processEnv: suppliedMigrationOptions.processEnv || processEnv,
79
+ ...(input.baseUrl ? { baseUrl: input.baseUrl } : {}),
80
+ ...(input.forceRetry === true ? { forceRetry: true } : {})
81
+ };
82
+ if (processEnv.SKS_TEST_FORBID_REAL_HOME === '1' && suppliedMigrationOptions.platform === undefined) {
83
+ migrationOptions.platform = 'linux';
84
+ }
85
+ const mode = input.fix === true ? 'repair' : 'inspect';
86
+ const reconcile = mode === 'repair'
87
+ ? deps.repairImpl || repairCodexLbLegacyKeychainMigration
88
+ : deps.inspectImpl || inspectCodexLbLegacyKeychainMigration;
89
+ let migration;
90
+ try {
91
+ migration = await reconcile(migrationOptions);
92
+ }
93
+ catch (error) {
94
+ migration = {
95
+ schema: 'sks.codex-lb-legacy-keychain-reconciliation.v1',
96
+ ok: false,
97
+ status: `${mode}_failed`,
98
+ mode,
99
+ env_key_valid: false,
100
+ keychain_item_present: null,
101
+ prompt_risk: 'none',
102
+ attempted: false,
103
+ stamp_path: codexLbLegacyKeychainMigrationStampPath(home),
104
+ stamp_outcome: null,
105
+ keychain_deleted: false,
106
+ keychain_cleared: [],
107
+ blockers: [`codex_lb_legacy_keychain_${mode}_failed:${error instanceof Error ? error.message : String(error)}`]
108
+ };
109
+ }
110
+ const envPath = String(suppliedMigrationOptions.envPath || codexLbEnvPath(home));
111
+ let loaded = null;
112
+ let resolutionError = null;
113
+ try {
114
+ loaded = await (deps.loadEnvImpl || loadCodexLbEnv)({
115
+ home,
116
+ processEnv,
117
+ envPath,
118
+ ...(suppliedMigrationOptions.metadataPath ? { metadataPath: suppliedMigrationOptions.metadataPath } : {})
119
+ });
120
+ }
121
+ catch (error) {
122
+ resolutionError = error instanceof Error ? error.message : String(error);
123
+ }
124
+ const source = String(loaded?.source || 'missing');
125
+ const unsafeEnvFile = Array.isArray(loaded?.blockers)
126
+ && loaded.blockers.some((blocker) => String(blocker).startsWith('codex_lb_env_file_'));
127
+ const resolutionPath = source === 'env-file' || unsafeEnvFile
128
+ ? String(loaded?.env_paths?.[0] || envPath)
129
+ : null;
130
+ const operatorActions = [];
131
+ if (mode === 'inspect' && migration.prompt_risk === 'one_time_on_repair') {
132
+ operatorActions.push('Run `sks doctor --fix` to perform the one-time legacy Keychain transfer.');
133
+ }
134
+ if (mode === 'repair'
135
+ && migration.ok === false
136
+ && (migration.attempted === true || migration.status === 'already_attempted')) {
137
+ operatorActions.push(`Run \`sks doctor --fix ${CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG}\` to explicitly retry the one-time Keychain transfer.`);
138
+ }
139
+ return {
140
+ ok: migration.ok !== false && resolutionError === null,
141
+ secret_resolution: {
142
+ source,
143
+ path: resolutionPath,
144
+ prompt_risk: migration.prompt_risk || 'none'
145
+ },
146
+ legacy_keychain_migration: {
147
+ ...migration,
148
+ operator_actions: operatorActions,
149
+ ...(resolutionError ? { resolution_error: resolutionError } : {})
150
+ }
151
+ };
152
+ }
153
+ export async function inspectDoctorCodexLbDivergence(input = {}, deps = {}) {
154
+ const processEnv = input.processEnv || process.env;
155
+ const home = path.resolve(input.home || processEnv.HOME || os.homedir());
156
+ const status = input.providerStatus || {};
157
+ const configPath = String(status.config_path || path.join(home, '.codex', 'config.toml'));
158
+ const configText = await (deps.readTextImpl || readText)(configPath, '');
159
+ const orphan = removeCodexLbOrphanManagedMarkers(configText);
160
+ let orphanRepair = {
161
+ schema: 'sks.codex-lb-orphan-managed-marker-repair.v1',
162
+ attempted: false,
163
+ changed: false,
164
+ markers: orphan.orphan_markers,
165
+ receipt: null
166
+ };
167
+ if (input.fix === true && orphan.changed) {
168
+ const write = deps.writeConfigImpl || safeWriteCodexConfigToml;
169
+ const receipt = await write(configPath, configText, orphan.text, 'doctor-codex-lb-orphan-marker');
170
+ orphanRepair = {
171
+ ...orphanRepair,
172
+ attempted: true,
173
+ changed: receipt?.ok !== false,
174
+ receipt
175
+ };
176
+ }
177
+ const load = deps.loadEnvImpl || loadCodexLbEnv;
178
+ const canonical = await load({
179
+ home,
180
+ processEnv: {},
181
+ envPath: String(status.env_path || codexLbEnvPath(home))
182
+ }).catch(() => null);
183
+ const ambientKey = String(processEnv.CODEX_LB_API_KEY || '').trim();
184
+ const canonicalKey = String(canonical?.secret_api_key || '').trim();
185
+ const sha256 = (value) => value
186
+ ? createHash('sha256').update(value).digest('hex')
187
+ : null;
188
+ const ambientHash = sha256(ambientKey);
189
+ const canonicalHash = sha256(canonicalKey);
190
+ const staleAmbient = Boolean(ambientHash && canonicalHash && ambientHash !== canonicalHash);
191
+ const bridgeActive = status.desktop_mode === 'desktop-native-bridge';
192
+ const definedButNotSelected = status.provider_configured === true
193
+ && status.selected !== true
194
+ && !bridgeActive
195
+ && status.desktop_mode !== 'desktop-dual-auth-compat';
196
+ const mode = status.selected === true
197
+ ? 'cli-provider'
198
+ : bridgeActive
199
+ ? 'desktop-native-bridge'
200
+ : 'disabled';
201
+ const inspectLaunch = deps.inspectLaunchImpl || inspectDesktopCenterLaunchCredentials;
202
+ const syncLaunch = deps.syncLaunchImpl || syncDesktopCenterLaunchCredentials;
203
+ const launchOptions = {
204
+ mode,
205
+ home,
206
+ ...(input.launchctlBin ? { launchctlBin: input.launchctlBin } : {}),
207
+ ...(input.platform ? { platform: input.platform } : {}),
208
+ ...(input.forceLaunchctl ? { force: true } : {}),
209
+ ...(input.runProcessImpl ? { runProcessImpl: input.runProcessImpl } : {})
210
+ };
211
+ const launchBefore = await inspectLaunch(launchOptions);
212
+ const launchRepair = input.fix === true && launchBefore.ok === false
213
+ ? await syncLaunch({ ...launchOptions, skipPurge: true })
214
+ : null;
215
+ const launchAfter = launchRepair ? await inspectLaunch(launchOptions) : launchBefore;
216
+ const warnings = [
217
+ ...(definedButNotSelected
218
+ ? ['codex_lb_defined_but_not_selected']
219
+ : []),
220
+ ...(staleAmbient ? ['codex_lb_stale_ambient_key'] : []),
221
+ ...(orphan.orphan_markers.length > 0
222
+ ? [`codex_lb_orphan_managed_markers:${orphan.orphan_markers.join(',')}`]
223
+ : [])
224
+ ];
225
+ const blockers = [
226
+ ...(launchAfter.ok === false ? launchAfter.blockers || ['codex_lb_launchd_selection_state_mismatch'] : []),
227
+ ...(input.fix === true && orphan.changed && orphanRepair.changed !== true
228
+ ? ['codex_lb_orphan_marker_repair_failed']
229
+ : [])
230
+ ];
231
+ return {
232
+ schema: 'sks.doctor-codex-lb-divergence.v1',
233
+ ok: blockers.length === 0,
234
+ warnings,
235
+ blockers,
236
+ operator_actions: [
237
+ ...(definedButNotSelected
238
+ ? ['Run `sks codex-lb use-cli` to select the stored provider.']
239
+ : []),
240
+ ...(staleAmbient
241
+ ? ['Remove or update the stale shell export: `unset CODEX_LB_API_KEY`; the canonical key remains in ~/.codex/sks-codex-lb.env.']
242
+ : []),
243
+ ...(launchAfter.operator_actions || [])
244
+ ],
245
+ ambient_key: {
246
+ present: Boolean(ambientKey),
247
+ sha256: ambientHash,
248
+ matches_canonical: ambientHash && canonicalHash ? ambientHash === canonicalHash : null
249
+ },
250
+ canonical_key: {
251
+ present: Boolean(canonicalKey),
252
+ sha256: canonicalHash,
253
+ path: String(status.env_path || codexLbEnvPath(home))
254
+ },
255
+ orphan_markers: orphan.orphan_markers,
256
+ orphan_marker_repair: orphanRepair,
257
+ launchd: { before: launchBefore, repair: launchRepair, after: launchAfter }
258
+ };
259
+ }
56
260
  export async function run(_command, args = [], deps = {}) {
57
261
  const root = await projectRoot();
58
262
  if (flag(args, '--search')) {
@@ -102,9 +306,9 @@ export async function run(_command, args = [], deps = {}) {
102
306
  : root;
103
307
  return withSecretPreservationGuard(guardRoot, 'doctor-fix', async () => (globalOnly
104
308
  ? runDoctorGlobalOnlyFix(args, root, deps)
105
- : runDoctor(args, root, doctorFix)));
309
+ : runDoctor(args, root, doctorFix, deps)));
106
310
  }
107
- return runDoctor(args, root, doctorFix);
311
+ return runDoctor(args, root, doctorFix, deps);
108
312
  }
109
313
  export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
110
314
  const startedAtMs = Date.now();
@@ -122,7 +326,29 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
122
326
  const doctorEnv = deps.env || (deps.home
123
327
  ? { ...process.env, HOME: home }
124
328
  : process.env);
329
+ const statusOptions = {
330
+ home,
331
+ env: doctorEnv,
332
+ processEnv: doctorEnv
333
+ };
334
+ const preRepairProviderStatus = await codexLbStatusImpl({
335
+ ...statusOptions,
336
+ probeToolOutputRecovery: false
337
+ }).catch(() => null);
338
+ const codexLbSecretProbeImpl = deps.codexLbSecretProbeImpl || inspectDoctorCodexLbSecretResolution;
339
+ const codexLbSecretProbe = await codexLbSecretProbeImpl({
340
+ home,
341
+ processEnv: doctorEnv,
342
+ fix: true,
343
+ forceRetry: flag(args, CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG),
344
+ baseUrl: preRepairProviderStatus?.base_url || preRepairProviderStatus?.provider_base_url || null,
345
+ migrationOptions: {
346
+ ...(deps.codexLbMigrationOptions || {}),
347
+ ...(!deps.codexLbMigrationOptions && deps.codexLbStatusImpl ? { platform: 'linux' } : {})
348
+ }
349
+ });
125
350
  const providerStatus = await codexLbStatusImpl({
351
+ ...statusOptions,
126
352
  probeToolOutputRecovery: true,
127
353
  allowUnverifiedToolOutputRecovery: codexLbToolOutputRecoveryOverrideAcknowledged({ args })
128
354
  }).catch((err) => ({
@@ -188,6 +414,25 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
188
414
  blockers: [err?.message || String(err)],
189
415
  warnings: []
190
416
  }));
417
+ const codexLbRoutingTruth = await codexLbRoutingTruthForStatus(providerStatus, { home, remeasure: true });
418
+ const codexLbRoutingReady = !doctorCodexLbRouteExpected(providerStatus)
419
+ || codexLbRoutingTruthIsActive(codexLbRoutingTruth);
420
+ const codexLbDivergence = await inspectDoctorCodexLbDivergence({
421
+ home,
422
+ processEnv: doctorEnv,
423
+ providerStatus,
424
+ fix: true,
425
+ ...(deps.codexLbLaunchctlBin ? { launchctlBin: deps.codexLbLaunchctlBin } : {}),
426
+ ...(deps.codexLbLaunchPlatform ? { platform: deps.codexLbLaunchPlatform } : {}),
427
+ ...(deps.codexLbLaunchRunProcessImpl ? { runProcessImpl: deps.codexLbLaunchRunProcessImpl } : {})
428
+ }, deps.codexLbDivergenceDeps || {});
429
+ const telegramRemote = await inspectTelegramRemote({
430
+ live: true,
431
+ fix: true,
432
+ root,
433
+ home,
434
+ env: doctorEnv
435
+ }, deps);
191
436
  const recoveryReady = codexLbRecoveryStatusReady(providerStatus, true);
192
437
  const globalSkillsReady = !globalSkills?.error
193
438
  && globalSkills?.ok !== false
@@ -202,7 +447,12 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
202
447
  ...(!globalFastModeReady ? [`global_fast_mode_repair_failed:${globalFastMode?.error || globalFastMode?.status || 'unknown'}`] : []),
203
448
  ...(!openRouterProviderReady ? (openRouterProvider?.blockers || ['openrouter_provider_repair_failed']) : []),
204
449
  ...(!menuBarReady ? (menuBar?.blockers || ['sks_menubar_repair_failed']) : []),
205
- ...(!recoveryReady ? (providerStatus?.tool_output_recovery?.blockers || ['codex_lb_tool_output_recovery_unverified']) : [])
450
+ ...(codexLbSecretProbe.ok === false
451
+ ? (codexLbSecretProbe.legacy_keychain_migration?.blockers || ['codex_lb_secret_resolution_failed'])
452
+ : []),
453
+ ...(!recoveryReady ? (providerStatus?.tool_output_recovery?.blockers || ['codex_lb_tool_output_recovery_unverified']) : []),
454
+ ...(!codexLbRoutingReady ? (codexLbRoutingTruth?.blockers || ['codex_lb_routing_truth_unverified']) : []),
455
+ ...(codexLbDivergence.blockers || [])
206
456
  ].map(String).filter(Boolean))];
207
457
  const ok = blockers.length === 0;
208
458
  return {
@@ -231,14 +481,23 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
231
481
  codex_app_fast_mode: globalFastMode,
232
482
  openrouter_provider: openRouterProvider,
233
483
  sks_menubar: menuBar,
484
+ telegram_remote: telegramRemote,
234
485
  codex_lb: {
235
486
  provider_status: providerStatus,
236
487
  tool_output_recovery: providerStatus?.tool_output_recovery || null,
237
- recovery_ok: recoveryReady
488
+ recovery_ok: recoveryReady,
489
+ routing_truth: codexLbRoutingTruth,
490
+ routing_ok: codexLbRoutingReady,
491
+ secret_resolution: codexLbSecretProbe.secret_resolution,
492
+ legacy_keychain_migration: codexLbSecretProbe.legacy_keychain_migration,
493
+ divergence: codexLbDivergence
238
494
  },
239
495
  blockers,
240
496
  next_actions: [
241
497
  ...(recoveryReady ? [] : (providerStatus?.tool_output_recovery?.operator_actions || [])),
498
+ ...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
499
+ ...(codexLbDivergence.operator_actions || []),
500
+ ...telegramDoctorOperatorActions(telegramRemote),
242
501
  ...(!openRouterProviderReady ? ['Run `sks codex-app set-openrouter-key` to repair the stored-key provider configuration without switching models.'] : []),
243
502
  'Run `sks doctor --fix --json` from a specific project directory when project-scoped repair is required.'
244
503
  ]
@@ -261,6 +520,15 @@ async function runDoctorGlobalOnlyFix(args = [], root, deps = {}) {
261
520
  console.log(`SKS Doctor global repair: ${result.ok ? 'ok' : 'blocked'}`);
262
521
  console.log(`Global skills: ${result.skills.global?.error ? 'blocked' : 'reconciled'}`);
263
522
  console.log(`SKS menu bar: ${result.sks_menubar?.status || (result.sks_menubar?.ok ? 'ok' : 'blocked')}`);
523
+ const telegramOutcome = result.telegram_remote?.self_heal_outcome;
524
+ const telegramAction = telegramOutcome?.attempted
525
+ ? telegramOutcome.action
526
+ : result.telegram_remote?.self_heal_action || 'none';
527
+ console.log(`Telegram Remote: ${result.telegram_remote?.status || 'unknown'} (self-heal ${telegramAction}${telegramOutcome?.attempted ? `, ${telegramOutcome.recovered ? 'recovered' : 'still degraded'}` : ''})`);
528
+ const telegramCheckedLine = telegramDoctorCheckedLine(result.telegram_remote);
529
+ if (telegramCheckedLine)
530
+ console.log(telegramCheckedLine);
531
+ console.log(`codex-lb key: ${result.codex_lb.secret_resolution.source} (prompt risk ${result.codex_lb.secret_resolution.prompt_risk})`);
264
532
  for (const blocker of result.blockers)
265
533
  console.log(`- blocker: ${blocker}`);
266
534
  for (const action of result.next_actions)
@@ -277,8 +545,203 @@ function codexLbRecoveryStatusReady(status, probeRequired = false) {
277
545
  return false;
278
546
  if (status.selected === false)
279
547
  return true;
548
+ if (!probeRequired)
549
+ return true;
280
550
  return status.selected === true && status.tool_output_recovery?.ok === true;
281
551
  }
552
+ export async function codexLbRoutingTruthForStatus(status, deps = {}) {
553
+ if (!status)
554
+ return null;
555
+ const statusEnvPath = typeof status.env_path === 'string' && status.env_path
556
+ ? status.env_path
557
+ : null;
558
+ const resolvedHome = deps.home
559
+ ? path.resolve(deps.home)
560
+ : statusEnvPath
561
+ ? path.dirname(path.dirname(statusEnvPath))
562
+ : undefined;
563
+ const envOptions = {
564
+ ...(resolvedHome ? { home: resolvedHome } : {}),
565
+ ...(statusEnvPath ? { envPath: statusEnvPath } : {})
566
+ };
567
+ const routeSelected = doctorCodexLbRouteExpected(status);
568
+ const mode = status.desktop_mode === 'desktop-native-bridge' ? 'bridge' : 'cli-provider';
569
+ const receiptOptions = {
570
+ ...(resolvedHome ? { home: resolvedHome } : {}),
571
+ ...(deps.receiptPath ? { receiptPath: deps.receiptPath } : {}),
572
+ expectedMode: mode,
573
+ expectedSelected: routeSelected
574
+ };
575
+ const receipt = await readCodexLbRoutingTruthReceipt(receiptOptions).catch(() => null);
576
+ if (deps.remeasure !== true && receipt?.fresh === true)
577
+ return receipt;
578
+ try {
579
+ const loaded = await loadCodexLbEnv({ ...envOptions, processEnv: {} });
580
+ const baseUrl = loaded.base_url || status.base_url || null;
581
+ const configuredHost = publicUrlHost(baseUrl);
582
+ const authTransport = mode === 'cli-provider'
583
+ ? 'x-codex-lb-api-key'
584
+ : doctorBridgeRoutingTransport(status, receipt);
585
+ const contextReceipt = await readCodexLbRoutingTruthReceipt({
586
+ ...receiptOptions,
587
+ expectedConfiguredHost: configuredHost,
588
+ expectedAuthTransport: authTransport
589
+ }).catch(() => null);
590
+ if (deps.remeasure !== true && contextReceipt?.fresh === true)
591
+ return contextReceipt;
592
+ return measureAndWriteCodexLbRoutingTruth({
593
+ mode,
594
+ selected: routeSelected,
595
+ baseUrl,
596
+ apiKey: loaded.secret_api_key,
597
+ authTransport,
598
+ measure: routeSelected,
599
+ ...(deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {})
600
+ }, {
601
+ ...envOptions,
602
+ ...(deps.receiptPath ? { receiptPath: deps.receiptPath } : {})
603
+ });
604
+ }
605
+ catch {
606
+ return measureAndWriteCodexLbRoutingTruth({
607
+ mode,
608
+ selected: routeSelected,
609
+ baseUrl: status.base_url || null,
610
+ apiKey: null,
611
+ authTransport: mode === 'cli-provider'
612
+ ? 'x-codex-lb-api-key'
613
+ : doctorBridgeRoutingTransport(status, receipt),
614
+ measure: false
615
+ }, {
616
+ ...envOptions,
617
+ ...(deps.receiptPath ? { receiptPath: deps.receiptPath } : {})
618
+ });
619
+ }
620
+ }
621
+ function doctorCodexLbRouteExpected(status) {
622
+ return status?.selected === true || status?.desktop_mode === 'desktop-native-bridge';
623
+ }
624
+ function doctorBridgeRoutingTransport(status, receipt) {
625
+ if (receipt?.mode === 'bridge'
626
+ && (receipt.auth_transport === 'authorization-bearer'
627
+ || receipt.auth_transport === 'x-codex-lb-api-key')) {
628
+ return receipt.auth_transport;
629
+ }
630
+ return status?.gateway_auth_transport === 'authorization-bearer-compat'
631
+ ? 'authorization-bearer'
632
+ : 'x-codex-lb-api-key';
633
+ }
634
+ function publicUrlHost(value) {
635
+ try {
636
+ return value ? new URL(String(value)).host : null;
637
+ }
638
+ catch {
639
+ return null;
640
+ }
641
+ }
642
+ export async function inspectTelegramRemote(input = {}, deps = {}) {
643
+ const env = input.env || process.env;
644
+ const home = path.resolve(input.home || env.HOME || os.homedir());
645
+ const receiptPath = input.receiptPath || telegramLivenessPath(home);
646
+ const probeImpl = deps.probeTelegramImpl || probeTelegram;
647
+ let tokenProvider = deps.telegramTokenProvider;
648
+ let client = deps.telegramClient;
649
+ if (input.live && (!tokenProvider || !client)) {
650
+ const resolveImpl = deps.resolveTelegramBotTokenImpl || resolveTelegramBotToken;
651
+ let resolvedToken = null;
652
+ tokenProvider ||= {
653
+ loadToken: () => {
654
+ resolvedToken ||= Promise.resolve(resolveImpl({ env })).then((result) => result.token);
655
+ return resolvedToken;
656
+ }
657
+ };
658
+ client ||= new TelegramClient({ tokenProvider });
659
+ }
660
+ const runProbe = () => {
661
+ if (!input.live)
662
+ return probeImpl({ receiptPath });
663
+ if (!client || !tokenProvider)
664
+ throw new Error('telegram_live_probe_dependencies_missing');
665
+ return probeImpl({ client, tokenProvider, receiptPath });
666
+ };
667
+ const before = await runProbe();
668
+ const action = telegramSelfHealAction(before);
669
+ if (!input.fix || action !== 'restart_poll' || !before.token_configured || before.paired_chat_count < 1) {
670
+ return {
671
+ ...before,
672
+ self_heal_action: action,
673
+ self_heal_outcome: {
674
+ requested: input.fix === true,
675
+ attempted: false,
676
+ action,
677
+ reason: input.fix !== true
678
+ ? 'report_only'
679
+ : action !== 'restart_poll'
680
+ ? 'action_not_restart_poll'
681
+ : 'telegram_not_configured_or_paired'
682
+ }
683
+ };
684
+ }
685
+ const restartImpl = deps.restartLaunchAgentImpl || restartLaunchAgent;
686
+ const restart = await restartImpl(sksMenuBarPaths(home, input.root), env).catch((error) => ({
687
+ ok: false,
688
+ error: error instanceof Error ? error.message : String(error)
689
+ }));
690
+ const maximumReprobes = Math.max(1, Math.min(deps.telegramReprobeAttempts ?? 3, 5));
691
+ const reprobeDelayMs = Math.max(0, Math.min(deps.telegramReprobeDelayMs ?? 500, 5_000));
692
+ const sleepImpl = deps.telegramSleepImpl || ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
693
+ let reprobeAttempts = 1;
694
+ let after = await runProbe();
695
+ let afterAction = telegramSelfHealAction(after);
696
+ while (restart?.ok === true && afterAction === 'restart_poll' && reprobeAttempts < maximumReprobes) {
697
+ await sleepImpl(reprobeDelayMs);
698
+ after = await runProbe();
699
+ afterAction = telegramSelfHealAction(after);
700
+ reprobeAttempts += 1;
701
+ }
702
+ return {
703
+ ...after,
704
+ self_heal_action: afterAction,
705
+ self_heal_attempted_action: action,
706
+ self_heal_before: before,
707
+ self_heal_outcome: {
708
+ requested: true,
709
+ attempted: true,
710
+ action,
711
+ after_action: afterAction,
712
+ restart_ok: restart?.ok === true,
713
+ reprobe_ok: after.ok,
714
+ reprobe_attempts: reprobeAttempts,
715
+ recovered: restart?.ok === true && after.ok && afterAction === 'none',
716
+ error: restart?.error || null,
717
+ restart
718
+ }
719
+ };
720
+ }
721
+ export function telegramDoctorCheckedLine(probe, indent = '') {
722
+ if (!probe?.getme_checked_at)
723
+ return null;
724
+ return `${indent}checked: ${probe.getme_checked_at} (${probe.getme_latency_ms ?? 'unknown'} ms, ${probe.getme_check_kind || 'receipt'})`;
725
+ }
726
+ function telegramDoctorOperatorActions(probe) {
727
+ if (!probe || probe.status === 'not_configured')
728
+ return [];
729
+ if (probe.self_heal_action === 'restart_poll') {
730
+ if (probe.self_heal_outcome?.recovered === true)
731
+ return [];
732
+ return ['Run `sks menubar restart` to restart the resident Telegram long poller.'];
733
+ }
734
+ if (probe.self_heal_action === 'revalidate_token') {
735
+ return ['Run `sks telegram setup --token-stdin`, then `sks menubar restart`, to revalidate the bot identity.'];
736
+ }
737
+ if (probe.self_heal_action === 'operator_remove_webhook') {
738
+ return ['Remove the Telegram bot webhook through the Bot API, then run `sks menubar restart`; getUpdates and webhooks cannot be active together.'];
739
+ }
740
+ if (probe.self_heal_action === 'operator_repair_audit') {
741
+ return ['Restore owner-only write access to `~/.codex/sks-menubar/logs/telegram-audit.jsonl`, then run `sks menubar restart`.'];
742
+ }
743
+ return [];
744
+ }
282
745
  async function runDoctorJsonFastPath(args = [], root) {
283
746
  const startedAtMs = Date.now();
284
747
  const reportFile = readOption(args, '--report-file', null);
@@ -289,7 +752,7 @@ async function runDoctorJsonFastPath(args = [], root) {
289
752
  requireActualCodex: false,
290
753
  codexBin: codexBin || undefined
291
754
  };
292
- const [codex, rust, codexConfig, sneakoscopeExists, oauthCallbackPortDiagnostic] = await Promise.all([
755
+ const [codex, rust, codexConfig, sneakoscopeExists, oauthCallbackPortDiagnostic, codexLbSecretProbe] = await Promise.all([
293
756
  codexBin
294
757
  ? Promise.resolve({ bin: codexBin, version: 'fixture-or-explicit', available: true })
295
758
  : getCodexInfo().catch(() => ({ bin: null, version: null, available: false })),
@@ -301,9 +764,11 @@ async function runDoctorJsonFastPath(args = [], root) {
301
764
  blockers: [err?.message || String(err)]
302
765
  })),
303
766
  exists(`${root}/.sneakoscope`),
304
- inspectOAuthCallbackPortConflict()
767
+ inspectOAuthCallbackPortConflict(),
768
+ inspectDoctorCodexLbSecretResolution({ processEnv: process.env, fix: false })
305
769
  ]);
306
770
  const oauthCallbackOperatorActions = oauthCallbackDoctorGuidance(oauthCallbackPortDiagnostic);
771
+ const telegramRemote = await inspectTelegramRemote();
307
772
  const ready = {
308
773
  schema: 'sks.doctor-readiness-matrix.v2',
309
774
  generated_at: nowIso(),
@@ -313,15 +778,13 @@ async function runDoctorJsonFastPath(args = [], root) {
313
778
  managed_state_current: sneakoscopeExists,
314
779
  codex_config_readable_by_node: Boolean(codexConfig?.ok),
315
780
  codex_config_readable_by_codex_cli: false,
316
- codex_config_readable_in_zellij_context: false,
317
781
  codex_app_ready: false,
318
782
  primary_blocker: codexConfig?.ok ? null : 'codex_config_unreadable',
319
783
  blockers: codexConfig?.ok ? [] : ['codex_config_unreadable'],
320
784
  next_actions: codexConfig?.ok ? [] : ['Run `sks doctor --fix --json` to repair managed config.']
321
785
  };
322
786
  const codexNativeFeatureMatrix = fallbackCodexNativeFeatureMatrix(codex, [], ['native_feature_matrix_deferred_to_full_doctor_or_route_gate']);
323
- const zellijReadiness = buildZellijReadiness(root, { status: 'skipped', required_for: ['sks --mad', 'interactive lane UI'] }, ready);
324
- const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
787
+ const runtimeReadiness = buildRuntimeReadiness(codexNativeFeatureMatrix);
325
788
  const deferredImagegen = deferredNativeRepair('sks.doctor-imagegen-repair.v1', false, [
326
789
  'Run `sks doctor --fix --repair-native-capabilities --json` after enabling Codex App image_generation.'
327
790
  ]);
@@ -340,13 +803,20 @@ async function runDoctorJsonFastPath(args = [], root) {
340
803
  deep_diagnostics_skipped: true,
341
804
  deep_ok: null,
342
805
  not_counted_as_full_doctor: true,
343
- next_actions: ['Run sks doctor --full --json for deep diagnostics.'],
806
+ next_actions: [
807
+ 'Run sks doctor --full --json for deep diagnostics.',
808
+ ...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
809
+ ...telegramDoctorOperatorActions(telegramRemote)
810
+ ],
344
811
  root,
345
812
  fast_path: true,
346
813
  no_fix_write_policy: reportFile ? 'report_file_only' : 'no_writes_performed',
347
814
  arg_warnings: doctorArgWarnings(args),
348
815
  warnings: [...oauthCallbackPortDiagnostic.warnings],
349
- operator_actions: oauthCallbackOperatorActions,
816
+ operator_actions: [
817
+ ...oauthCallbackOperatorActions,
818
+ ...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || [])
819
+ ],
350
820
  node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
351
821
  codex,
352
822
  oauth_callback_port_diagnostic: oauthCallbackPortDiagnostic,
@@ -371,6 +841,7 @@ async function runDoctorJsonFastPath(args = [], root) {
371
841
  blockers: [],
372
842
  warnings: ['menubar_install_deferred_to_fix_or_full_doctor']
373
843
  },
844
+ telegram_remote: telegramRemote,
374
845
  provider_context: {
375
846
  schema: 'sks.provider-context.v1',
376
847
  generated_at: nowIso(),
@@ -384,14 +855,18 @@ async function runDoctorJsonFastPath(args = [], root) {
384
855
  warnings: ['provider_context_optional_diagnostic_skipped'],
385
856
  signals: {}
386
857
  },
387
- codex_lb: codexLbMetrics(await readCodexLbCircuit(root).catch(() => ({}))),
858
+ codex_lb: {
859
+ ...codexLbMetrics(await readCodexLbCircuit(root).catch(() => ({}))),
860
+ routing_truth: null,
861
+ routing_measurement_deferred: true,
862
+ secret_resolution: codexLbSecretProbe.secret_resolution,
863
+ legacy_keychain_migration: codexLbSecretProbe.legacy_keychain_migration
864
+ },
388
865
  codex_doctor: null,
389
866
  pre_repair_codex_doctor: null,
390
867
  post_repair_codex_doctor: null,
391
868
  codex_doctor_diff: null,
392
869
  observational_codex_doctor_diff: null,
393
- zellij: { ok: true, skipped: true, status: 'skipped_fast_path', required_for: ['sks --mad', 'interactive lane UI'] },
394
- zellij_repair: { schema: 'sks.zellij-self-heal.v1', ok: true, skipped: true, blockers: [], warnings: ['zellij_repair_deferred_to_full_doctor_or_route_gate'] },
395
870
  context7_repair: { schema: 'sks.doctor-context7-repair.v1', ok: true, fix: false, skipped: true, actions: [], blockers: [], warnings: ['context7_repair_deferred_to_fix'] },
396
871
  codex_startup_repair: { schema: 'sks.doctor-codex-startup-repair.v1', ok: true, fix: false, skipped: true, actions: [], blockers: [], warnings: ['codex_startup_repair_deferred_to_fix'] },
397
872
  startup_config_repair: null,
@@ -402,7 +877,6 @@ async function runDoctorJsonFastPath(args = [], root) {
402
877
  postcheck: null,
403
878
  local_model: null,
404
879
  agent_role_config: { schema: 'sks.agent-role-config-repair.v1', ok: true, apply: false, skipped: true, blockers: [] },
405
- zellij_readiness: zellijReadiness,
406
880
  codex_permission_profiles: { skipped: true, reason: 'doctor_json_fast_path_optional_diagnostics_skipped' },
407
881
  command_aliases: { schema: 'sks.command-alias-cleanup.v1', ok: true, skipped: true, reason: 'doctor_json_fast_path_no_write' },
408
882
  sks_temp_sweep: { ok: true, skipped: true, action_count: 0, reason: 'doctor_without_fix', error: null },
@@ -423,7 +897,6 @@ async function runDoctorJsonFastPath(args = [], root) {
423
897
  migration_journal: null,
424
898
  global_sks_installs: null,
425
899
  agent_role_config: null,
426
- zellij: null,
427
900
  context7: null,
428
901
  codex_startup: null,
429
902
  startup_config: null,
@@ -452,7 +925,7 @@ async function runDoctorJsonFastPath(args = [], root) {
452
925
  process.exitCode = 1;
453
926
  return result;
454
927
  }
455
- async function runDoctor(args = [], root, doctorFix) {
928
+ async function runDoctor(args = [], root, doctorFix, deps = {}) {
456
929
  const startedAtMs = Date.now();
457
930
  const oauthCallbackPortDiagnostic = await inspectOAuthCallbackPortConflict();
458
931
  const oauthCallbackOperatorActions = oauthCallbackDoctorGuidance(oauthCallbackPortDiagnostic);
@@ -471,7 +944,6 @@ async function runDoctor(args = [], root, doctorFix) {
471
944
  const actualCodexProbeEnabled = deepDiagnostics || actualCodexProbeRequested;
472
945
  const requireActualCodexProbe = flag(args, '--require-actual-codex') || (deepDiagnostics && doctorFix);
473
946
  const shouldEvaluateCodexAppUiRepair = doctorFix || deepDiagnostics || flag(args, '--repair-codex-app-ui');
474
- const shouldRunZellijRepair = deepDiagnostics || flag(args, '--repair-zellij') || flag(args, '--install-homebrew') || process.env.SKS_REQUIRE_ZELLIJ === '1';
475
947
  const nativeCapabilityDiagnosticsRequested = deepDiagnostics || flag(args, '--repair-native-capabilities');
476
948
  const requireLegacyGlobalHookCleanup = doctorFix && doctorProfile === 'migration';
477
949
  const migrationReceiptOwnsReconcile = doctorFix && doctorProfile === 'migration';
@@ -482,7 +954,6 @@ async function runDoctor(args = [], root, doctorFix) {
482
954
  const { runDoctorContext7Repair } = await import('../core/doctor/doctor-context7-repair.js');
483
955
  const { compareCodexDoctorBridge, runCodexDoctorBridge } = await import('../core/doctor/codex-doctor-bridge.js');
484
956
  const { repairCodexAppFastUi } = await import('../core/codex-app/codex-app-fast-ui-repair.js');
485
- const { runDoctorZellijRepair, doctorZellijRepairConsoleLine } = await import('../core/doctor/doctor-zellij-repair.js');
486
957
  const { repairAgentRoleConfigs } = await import('../core/agents/agent-role-config.js');
487
958
  const { runCodex0138Doctor } = await import('../core/doctor/codex-0138-doctor.js');
488
959
  const { writeDoctorReadinessMatrix } = await import('../core/doctor/doctor-readiness-matrix.js');
@@ -630,29 +1101,54 @@ async function runDoctor(args = [], root, doctorFix) {
630
1101
  ? await codexAppIntegrationStatus({ codex }).catch((err) => ({ ok: false, error: err.message }))
631
1102
  : { ok: false, skipped: true, warnings: ['codex_app_optional_diagnostic_skipped'] };
632
1103
  const codexLbCircuit = codexLbMetrics(await readCodexLbCircuit(root).catch(() => ({})));
633
- const codexLbProviderStatus = deepDiagnostics || doctorFix
634
- ? await codexLbStatus({
635
- probeToolOutputRecovery: true,
636
- allowUnverifiedToolOutputRecovery: codexLbToolOutputRecoveryOverrideAcknowledged({ args })
637
- }).catch((err) => ({
638
- selected: null,
639
- provider_ready: false,
640
- recovery_probe_failed: true,
641
- tool_output_recovery: {
642
- ok: false,
643
- status: 'probe_failed',
644
- blockers: ['codex_lb_tool_output_recovery_status_probe_failed'],
645
- operator_actions: []
646
- },
647
- error: err?.message || String(err)
648
- }))
1104
+ const codexLbPreRepairStatus = doctorFix
1105
+ ? await codexLbStatus({ probeToolOutputRecovery: false }).catch(() => null)
649
1106
  : null;
1107
+ const codexLbSecretProbe = await inspectDoctorCodexLbSecretResolution({
1108
+ processEnv: process.env,
1109
+ fix: doctorFix,
1110
+ forceRetry: flag(args, CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG),
1111
+ baseUrl: codexLbPreRepairStatus?.base_url || codexLbPreRepairStatus?.provider_base_url || null
1112
+ });
1113
+ const codexLbProviderStatus = await codexLbStatus({
1114
+ probeToolOutputRecovery: deepDiagnostics || doctorFix,
1115
+ allowUnverifiedToolOutputRecovery: codexLbToolOutputRecoveryOverrideAcknowledged({ args })
1116
+ }).catch((err) => ({
1117
+ selected: null,
1118
+ provider_ready: false,
1119
+ recovery_probe_failed: deepDiagnostics || doctorFix,
1120
+ tool_output_recovery: {
1121
+ ok: false,
1122
+ status: deepDiagnostics || doctorFix ? 'probe_failed' : 'not_checked',
1123
+ blockers: deepDiagnostics || doctorFix ? ['codex_lb_tool_output_recovery_status_probe_failed'] : [],
1124
+ operator_actions: []
1125
+ },
1126
+ error: err?.message || String(err)
1127
+ }));
650
1128
  const codexLbRecoveryReady = codexLbRecoveryStatusReady(codexLbProviderStatus, deepDiagnostics || doctorFix);
1129
+ const codexLbRoutingTruth = await codexLbRoutingTruthForStatus(codexLbProviderStatus, {
1130
+ remeasure: deepDiagnostics || doctorFix
1131
+ });
1132
+ const codexLbRoutingReady = !doctorCodexLbRouteExpected(codexLbProviderStatus)
1133
+ || codexLbRoutingTruthIsActive(codexLbRoutingTruth);
1134
+ const codexLbDivergence = await inspectDoctorCodexLbDivergence({
1135
+ processEnv: process.env,
1136
+ providerStatus: codexLbProviderStatus,
1137
+ fix: doctorFix,
1138
+ ...(deps.codexLbLaunchctlBin ? { launchctlBin: deps.codexLbLaunchctlBin } : {}),
1139
+ ...(deps.codexLbLaunchPlatform ? { platform: deps.codexLbLaunchPlatform } : {}),
1140
+ ...(deps.codexLbLaunchRunProcessImpl ? { runProcessImpl: deps.codexLbLaunchRunProcessImpl } : {})
1141
+ }, deps.codexLbDivergenceDeps || {});
651
1142
  const codexLb = {
652
1143
  ...codexLbCircuit,
653
1144
  provider_status: codexLbProviderStatus,
654
1145
  tool_output_recovery: codexLbProviderStatus?.tool_output_recovery || null,
655
- recovery_ok: codexLbRecoveryReady
1146
+ recovery_ok: codexLbRecoveryReady,
1147
+ routing_truth: codexLbRoutingTruth,
1148
+ routing_ok: codexLbRoutingReady,
1149
+ secret_resolution: codexLbSecretProbe.secret_resolution,
1150
+ legacy_keychain_migration: codexLbSecretProbe.legacy_keychain_migration,
1151
+ divergence: codexLbDivergence
656
1152
  };
657
1153
  const providerContext = deepDiagnostics
658
1154
  ? await resolveProviderContext({ root, route: '$Doctor', serviceTier: process.env.SKS_SERVICE_TIER || 'fast' }).catch((err) => ({
@@ -756,42 +1252,12 @@ async function runDoctor(args = [], root, doctorFix) {
756
1252
  blockers: [err?.message || String(err)],
757
1253
  warnings: []
758
1254
  }));
759
- const zellijRepair = shouldRunZellijRepair
760
- ? await runDoctorZellijRepair({ root, args, doctorFix }).catch((err) => ({
761
- schema: 'sks.zellij-self-heal.v1',
762
- ok: false,
763
- requested_by: 'doctor --fix',
764
- fix_requested: doctorFix,
765
- auto_approved: flag(args, '--yes') || flag(args, '-y'),
766
- install_homebrew_allowed: false,
767
- before: { status: 'unknown', version: null, bin: null },
768
- latest_version: null,
769
- strategy: 'failed',
770
- command: 'sks doctor --fix --yes',
771
- after: { status: 'unknown', version: null, bin: null },
772
- mutation_guard_artifact: null,
773
- homebrew: { present: false, bin: null, install_attempted: false, install_allowed: false },
774
- blockers: [err?.message || String(err)],
775
- warnings: []
776
- }))
777
- : {
778
- schema: 'sks.zellij-self-heal.v1',
779
- ok: true,
780
- skipped: true,
781
- requested_by: 'doctor --fix',
782
- fix_requested: doctorFix,
783
- auto_approved: false,
784
- install_homebrew_allowed: false,
785
- before: { status: 'skipped', version: null, bin: null },
786
- latest_version: null,
787
- strategy: 'deferred',
788
- command: 'sks doctor --fix --full --yes',
789
- after: { status: 'skipped', version: null, bin: null },
790
- mutation_guard_artifact: null,
791
- homebrew: { present: false, bin: null, install_attempted: false, install_allowed: false },
792
- blockers: [],
793
- warnings: ['zellij_repair_deferred_to_full_doctor_or_route_gate']
794
- };
1255
+ const telegramRemote = await inspectTelegramRemote({
1256
+ live: deepDiagnostics || doctorFix,
1257
+ fix: doctorFix,
1258
+ root,
1259
+ env: process.env
1260
+ }, deps);
795
1261
  const context7Repair = await runDoctorContext7Repair({ root, fix: doctorFix }).catch((err) => ({
796
1262
  schema: 'sks.doctor-context7-repair.v1',
797
1263
  ok: false,
@@ -968,14 +1434,34 @@ async function runDoctor(args = [], root, doctorFix) {
968
1434
  rollback_evidence: sksMenuBar?.launch_agent_path || sksMenuBar?.report_path || 'sks_menubar_optional_no_core_mutation'
969
1435
  }),
970
1436
  postcheck: async () => {
971
- const status = await inspectSksMenuBarStatus({ root }).catch((err) => ({
1437
+ const inspectMenuBarStatusImpl = deps.inspectSksMenuBarStatusImpl || inspectSksMenuBarStatus;
1438
+ const status = await inspectMenuBarStatusImpl({ root }).catch((err) => ({
972
1439
  ok: false,
973
1440
  launchd: { ok: false, state: null, pid: null, error: err?.message || String(err) },
974
1441
  action_target: { ok: false, smoke_code: null, smoke_output: null },
975
1442
  blockers: [err?.message || String(err)],
976
1443
  warnings: []
977
1444
  }));
978
- return buildSksMenuBarDoctorPostcheck(status);
1445
+ const launchdRepair = await rebootstrapSksMenuBarLaunchdForDoctorFix({
1446
+ fix: doctorFix,
1447
+ root,
1448
+ env: process.env,
1449
+ status
1450
+ }, {
1451
+ inspectSksMenuBarStatusImpl: inspectMenuBarStatusImpl,
1452
+ restartLaunchAgentImpl: deps.restartLaunchAgentImpl
1453
+ });
1454
+ const postcheck = buildSksMenuBarDoctorPostcheck(launchdRepair.status);
1455
+ return launchdRepair.attempted
1456
+ ? {
1457
+ ...postcheck,
1458
+ repaired: launchdRepair.ok,
1459
+ warnings: [
1460
+ ...(postcheck.warnings || []),
1461
+ launchdRepair.ok ? 'launchd_rebootstrap_recovered' : 'launchd_rebootstrap_failed'
1462
+ ]
1463
+ }
1464
+ : postcheck;
979
1465
  }
980
1466
  },
981
1467
  {
@@ -1029,7 +1515,6 @@ async function runDoctor(args = [], root, doctorFix) {
1029
1515
  }))
1030
1516
  : null;
1031
1517
  const doctorFixPostcheck = doctorFix ? (await import('../core/doctor/doctor-repair-postcheck.js')).doctorRepairPostcheck(doctorFixTransaction) : null;
1032
- const zellij = await checkZellijCapability({ root, require: process.env.SKS_REQUIRE_ZELLIJ === '1' });
1033
1518
  const localModel = await readLocalModelConfig().catch(() => null);
1034
1519
  const permissionProfiles = await inventoryCodexPermissionProfiles(root, { writeReport: true });
1035
1520
  const startupRoleRepair = startupConfigRepair?.role_repair;
@@ -1265,7 +1750,6 @@ async function runDoctor(args = [], root, doctorFix) {
1265
1750
  pre_repair_codex_doctor: preRepairCodexDoctor,
1266
1751
  post_repair_codex_doctor: postRepairCodexDoctor,
1267
1752
  require_codex_doctor: deepDiagnostics || flag(args, '--require-actual-codex'),
1268
- zellij,
1269
1753
  context7_repair: context7Repair,
1270
1754
  codex_startup_repair: codexStartupRepair,
1271
1755
  startup_config_repair: startupConfigRepair,
@@ -1284,6 +1768,7 @@ async function runDoctor(args = [], root, doctorFix) {
1284
1768
  repair: configRepair,
1285
1769
  codex_app_ui: codexAppUi,
1286
1770
  sks_menubar: sksMenuBar,
1771
+ telegram_remote: telegramRemote,
1287
1772
  codex_0138_doctor: codex0138Doctor,
1288
1773
  codex_plugin_inventory: pluginInventory?.report || null,
1289
1774
  codex_plugin_app_template_policy: pluginPolicy,
@@ -1292,19 +1777,15 @@ async function runDoctor(args = [], root, doctorFix) {
1292
1777
  operator_actions: [
1293
1778
  ...(codexConfig.operator_actions || []),
1294
1779
  ...(configRepair?.operator_actions || []),
1295
- ...(zellijRepair && !zellijRepair.ok && zellijRepair.command ? [`Run: ${zellijRepair.command}`] : []),
1296
1780
  ...(codexStartupRepair.manual_actions || []),
1297
1781
  ...(codexConfigSyntaxRepair?.manual_actions || []),
1298
- ...(pluginPolicy?.doctor_warnings || [])
1782
+ ...(pluginPolicy?.doctor_warnings || []),
1783
+ ...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
1784
+ ...telegramDoctorOperatorActions(telegramRemote)
1299
1785
  ]
1300
1786
  };
1301
1787
  let ready = await writeDoctorReadinessMatrix(root, doctorReadinessInput);
1302
1788
  if (doctorFix) {
1303
- if (migrationReceiptOwnsReconcile) {
1304
- commandAliasCleanup = await inspectCommandAliasCleanup(false);
1305
- doctorReadinessInput.command_aliases = commandAliasCleanup;
1306
- ready = await writeDoctorReadinessMatrix(root, doctorReadinessInput);
1307
- }
1308
1789
  const readinessBlockers = [
1309
1790
  ...(Array.isArray(ready.blockers) ? ready.blockers.map(String).filter(Boolean) : []),
1310
1791
  ...(openRouterProviderRepair?.ok === false
@@ -1316,6 +1797,7 @@ async function runDoctor(args = [], root, doctorFix) {
1316
1797
  && readinessBlockers.every(isMigrationUserOwnedProjectConfigBlocker);
1317
1798
  const receiptBlockers = preservedUserOwnedConfig ? [] : readinessBlockers;
1318
1799
  const migrationWarnings = [
1800
+ ...(commandAliasCleanup?.warnings || []),
1319
1801
  ...(doctorNativeCapabilityRepair?.optional_warnings || []),
1320
1802
  ...(doctorFixPostcheck?.optional_warnings || []),
1321
1803
  ...(preservedUserOwnedConfig
@@ -1334,6 +1816,21 @@ async function runDoctor(args = [], root, doctorFix) {
1334
1816
  };
1335
1817
  if (receiptBlockers.length)
1336
1818
  receiptInput.status = 'blocked';
1819
+ if (migrationReceiptOwnsReconcile) {
1820
+ receiptInput.postMigrationStageCheck = async () => {
1821
+ commandAliasCleanup = await inspectCommandAliasCleanup(false);
1822
+ doctorReadinessInput.command_aliases = commandAliasCleanup;
1823
+ ready = await writeDoctorReadinessMatrix(root, doctorReadinessInput);
1824
+ return {
1825
+ blockers: Array.isArray(commandAliasCleanup?.blockers)
1826
+ ? commandAliasCleanup.blockers.map(String).filter(Boolean)
1827
+ : [],
1828
+ warnings: Array.isArray(commandAliasCleanup?.warnings)
1829
+ ? commandAliasCleanup.warnings.map(String).filter(Boolean)
1830
+ : []
1831
+ };
1832
+ };
1833
+ }
1337
1834
  const receipt = await writeProjectUpdateMigrationReceipt(receiptInput);
1338
1835
  sksUpdate = {
1339
1836
  schema: 'sks.update-now.v2',
@@ -1361,8 +1858,7 @@ async function runDoctor(args = [], root, doctorFix) {
1361
1858
  };
1362
1859
  }
1363
1860
  }
1364
- const zellijReadiness = buildZellijReadiness(root, zellij, ready);
1365
- const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
1861
+ const runtimeReadiness = buildRuntimeReadiness(codexNativeFeatureMatrix);
1366
1862
  const resultOk = ready.ready
1367
1863
  && (!sksUpdate || sksUpdate.ok !== false)
1368
1864
  && commandAliasCleanup.ok !== false
@@ -1371,7 +1867,10 @@ async function runDoctor(args = [], root, doctorFix) {
1371
1867
  && agentRoleConfigRepair.ok !== false
1372
1868
  && openRouterProviderRepair.ok !== false
1373
1869
  && (officialSubagentConfig.blockers || []).length === 0
1374
- && codexLbRecoveryReady;
1870
+ && codexLbSecretProbe.ok !== false
1871
+ && codexLbDivergence.ok !== false
1872
+ && codexLbRecoveryReady
1873
+ && codexLbRoutingReady;
1375
1874
  const result = {
1376
1875
  schema: 'sks.doctor-status.v3',
1377
1876
  elapsed_ms: Date.now() - startedAtMs,
@@ -1386,8 +1885,12 @@ async function runDoctor(args = [], root, doctorFix) {
1386
1885
  not_counted_as_full_doctor: !deepDiagnostics,
1387
1886
  root,
1388
1887
  arg_warnings: argWarnings,
1389
- warnings: [...oauthCallbackPortDiagnostic.warnings],
1390
- operator_actions: oauthCallbackOperatorActions,
1888
+ warnings: [...oauthCallbackPortDiagnostic.warnings, ...(codexLbDivergence.warnings || [])],
1889
+ operator_actions: [
1890
+ ...oauthCallbackOperatorActions,
1891
+ ...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
1892
+ ...(codexLbDivergence.operator_actions || [])
1893
+ ],
1391
1894
  node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
1392
1895
  codex,
1393
1896
  oauth_callback_port_diagnostic: oauthCallbackPortDiagnostic,
@@ -1397,6 +1900,7 @@ async function runDoctor(args = [], root, doctorFix) {
1397
1900
  codex_app_ui: codexAppUi,
1398
1901
  openrouter_provider: openRouterProviderRepair,
1399
1902
  sks_menubar: sksMenuBar,
1903
+ telegram_remote: telegramRemote,
1400
1904
  provider_context: providerContext,
1401
1905
  codex_lb: codexLb,
1402
1906
  codex_doctor: authoritativeCodexDoctor,
@@ -1404,8 +1908,6 @@ async function runDoctor(args = [], root, doctorFix) {
1404
1908
  post_repair_codex_doctor: postRepairCodexDoctor,
1405
1909
  codex_doctor_diff: codexDoctorAuthoritativeDiff,
1406
1910
  observational_codex_doctor_diff: codexDoctorDiff,
1407
- zellij,
1408
- zellij_repair: zellijRepair,
1409
1911
  context7_repair: context7Repair,
1410
1912
  codex_startup_repair: codexStartupRepair,
1411
1913
  startup_config_repair: startupConfigRepair,
@@ -1423,7 +1925,6 @@ async function runDoctor(args = [], root, doctorFix) {
1423
1925
  local_model: localModel,
1424
1926
  agent_role_config: agentRoleConfigRepair,
1425
1927
  official_subagent_config: officialSubagentConfig,
1426
- zellij_readiness: zellijReadiness,
1427
1928
  codex_permission_profiles: permissionProfiles,
1428
1929
  command_aliases: commandAliasCleanup,
1429
1930
  sks_temp_sweep: {
@@ -1457,7 +1958,7 @@ async function runDoctor(args = [], root, doctorFix) {
1457
1958
  sneakoscope: { ok: await exists(`${root}/.sneakoscope`) },
1458
1959
  package: { bytes: pkgBytes, human: formatBytes(pkgBytes) },
1459
1960
  skills: skillsReconcile,
1460
- repair: { sks_update: sksUpdate, setup: setupRepair, openrouter_provider: openRouterProviderRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup, agent_role_config: agentRoleConfigRepair, zellij: zellijRepair, context7: context7Repair, codex_startup: codexStartupRepair, startup_config: startupConfigRepair, context7_mcp: context7McpRepair, supabase_mcp: supabaseMcpRepair, mcp_transport_collision: mcpTransportCollisionRepair, imagegen: imagegenRepair, computer_use: computerUseRepair, browser_use: browserUseRepair, hook_trust: hookTrustRepair, sks_menubar: sksMenuBar, doctor_transaction: doctorFixTransaction, doctor_dirty_plan: doctorDirtyPlan, doctor_postcheck: doctorFixPostcheck, codex_native: codexNativeRepair, doctor_native_capability: doctorNativeCapabilityRepair, command_aliases: commandAliasCleanup, skills: skillsReconcile, sks_temp_sweep: sksTempSweep }
1961
+ repair: { sks_update: sksUpdate, setup: setupRepair, openrouter_provider: openRouterProviderRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup, agent_role_config: agentRoleConfigRepair, context7: context7Repair, codex_startup: codexStartupRepair, startup_config: startupConfigRepair, context7_mcp: context7McpRepair, supabase_mcp: supabaseMcpRepair, mcp_transport_collision: mcpTransportCollisionRepair, imagegen: imagegenRepair, computer_use: computerUseRepair, browser_use: browserUseRepair, hook_trust: hookTrustRepair, sks_menubar: sksMenuBar, doctor_transaction: doctorFixTransaction, doctor_dirty_plan: doctorDirtyPlan, doctor_postcheck: doctorFixPostcheck, codex_native: codexNativeRepair, doctor_native_capability: doctorNativeCapabilityRepair, command_aliases: commandAliasCleanup, skills: skillsReconcile, sks_temp_sweep: sksTempSweep }
1461
1962
  };
1462
1963
  if (reportFile)
1463
1964
  await writeJsonReportFile(reportFile, result);
@@ -1492,15 +1993,6 @@ async function runDoctor(args = [], root, doctorFix) {
1492
1993
  console.log('Project config:');
1493
1994
  console.log(` node read: ${ready.codex_config_readable_by_node ? 'ok' : 'failed'}`);
1494
1995
  console.log(` codex cli read: ${ready.codex_config_readable_by_codex_cli ? 'ok' : (actual?.status || 'failed')}`);
1495
- console.log('Zellij:');
1496
- console.log(` binary: ${zellijReadiness.binary} ${zellijReadiness.version || ''} ${zellijReadiness.status === 'ok' ? 'ok' : zellijReadiness.status}`);
1497
- console.log(` required_for: ${zellijReadiness.required_for.join(', ')}`);
1498
- console.log(` layout: ${zellijReadiness.layout_proof}`);
1499
- console.log(` pane proof: ${zellijReadiness.pane_proof}`);
1500
- console.log(` screen proof:${zellijReadiness.screen_proof}`);
1501
- const zellijRepairLine = doctorZellijRepairConsoleLine(zellijRepair);
1502
- if (zellijRepairLine)
1503
- console.log(zellijRepairLine);
1504
1996
  console.log('Context7 MCP:');
1505
1997
  console.log(` transport: ${context7Repair.preferred_transport || 'remote'}`);
1506
1998
  console.log(` repair: ${context7Repair.ok ? 'ok' : 'blocked'}`);
@@ -1530,7 +2022,6 @@ async function runDoctor(args = [], root, doctorFix) {
1530
2022
  console.log(`Rust acc.: ${rust.mode || (rust.available ? 'rust_accelerated' : 'js_fallback')} ${rust.version || rust.status || ''}`);
1531
2023
  console.log(`Codex App: ${ready.codex_app_ready ? 'ok' : 'optional_missing'}`);
1532
2024
  console.log('SKS Runtime Readiness:');
1533
- console.log(` Zellij: ${runtimeReadiness.zellij}`);
1534
2025
  console.log(` Codex Native: ${runtimeReadiness.codex_native}`);
1535
2026
  console.log(` Loop Mesh: ${runtimeReadiness.loop_mesh}`);
1536
2027
  console.log(` QA Visual: ${runtimeReadiness.qa_visual}`);
@@ -1607,6 +2098,8 @@ async function runDoctor(args = [], root, doctorFix) {
1607
2098
  console.log(` next action: ${codexAppUi.next_action}`);
1608
2099
  console.log('SKS Menu Bar:');
1609
2100
  console.log(` status: ${sksMenuBar.status || (sksMenuBar.ok ? 'ok' : 'blocked')}`);
2101
+ for (const line of sksMenuBarRunningVersionConsoleLines(sksMenuBar))
2102
+ console.log(line);
1610
2103
  const menubarPhase = doctorFixTransaction?.phases?.find((phase) => phase?.id === 'sks_menubar');
1611
2104
  if (menubarPhase) {
1612
2105
  const menubarSummary = menubarPhase.ok
@@ -1622,6 +2115,21 @@ async function runDoctor(args = [], root, doctorFix) {
1622
2115
  console.log(` blockers: ${sksMenuBar.blockers.join(', ')}`);
1623
2116
  if (Array.isArray(sksMenuBar.warnings) && sksMenuBar.warnings.length)
1624
2117
  console.log(` warnings: ${sksMenuBar.warnings.join(', ')}`);
2118
+ console.log('Telegram Remote:');
2119
+ console.log(` status: ${telegramRemote.status || 'unknown'}`);
2120
+ console.log(` getMe: ${telegramRemote.bot_identity_valid ? 'verified' : telegramRemote.token_configured ? 'invalid' : 'not configured'}`);
2121
+ console.log(` audit: ${telegramRemote.audit_healthy ? 'healthy' : 'unavailable'}`);
2122
+ const telegramCheckedLine = telegramDoctorCheckedLine(telegramRemote, ' ');
2123
+ if (telegramCheckedLine)
2124
+ console.log(telegramCheckedLine);
2125
+ console.log(` long poll: ${telegramRemote.poller?.running ? 'running' : 'stopped'}`);
2126
+ const telegramSelfHealOutcome = telegramRemote.self_heal_outcome;
2127
+ const telegramDisplayedAction = telegramSelfHealOutcome?.attempted
2128
+ ? telegramSelfHealOutcome.action
2129
+ : telegramRemote.self_heal_action;
2130
+ if (telegramDisplayedAction && telegramDisplayedAction !== 'none') {
2131
+ console.log(` self-heal: ${telegramDisplayedAction}${telegramSelfHealOutcome?.attempted ? ` (${telegramSelfHealOutcome.recovered ? 'recovered' : 'attempted, still degraded'})` : ''}`);
2132
+ }
1625
2133
  console.log(`Provider: ${providerContext.provider || 'unknown'} ${providerContext.service_tier || ''} (${providerContext.source || 'unknown'}, ${providerContext.confidence || 'low'})`);
1626
2134
  const imagegenReady = imagegen.auth_readiness;
1627
2135
  if (imagegenReady) {
@@ -1674,6 +2182,17 @@ async function runDoctor(args = [], root, doctorFix) {
1674
2182
  if (codex0138Doctor?.fixed?.length)
1675
2183
  console.log(` doctor --fix repaired: ${codex0138Doctor.fixed.join(', ')}`);
1676
2184
  console.log(`codex-lb: ${codexLb.ok ? 'ok' : `warning ${codexLb.circuit?.state || 'unknown'}`}`);
2185
+ console.log(` key source: ${codexLb.secret_resolution.source}${codexLb.secret_resolution.path ? ` (${codexLb.secret_resolution.path})` : ''}; prompt risk: ${codexLb.secret_resolution.prompt_risk}`);
2186
+ for (const action of codexLb.legacy_keychain_migration?.operator_actions || [])
2187
+ console.log(` action: ${action}`);
2188
+ for (const warning of codexLb.divergence?.warnings || [])
2189
+ console.log(` warning: ${warning}`);
2190
+ for (const action of codexLb.divergence?.operator_actions || [])
2191
+ console.log(` action: ${action}`);
2192
+ if (codexLb.routing_truth) {
2193
+ const routingTruth = codexLb.routing_truth;
2194
+ console.log(` routing truth: ${codexLb.routing_ok ? 'verified' : 'blocked'} (${routingTruth.actual_host || routingTruth.configured_host || 'host unavailable'}, ${routingTruth.auth_outcome}, ${routingTruth.latency_ms ?? 'unmeasured'} ms at ${routingTruth.checked_at})`);
2195
+ }
1677
2196
  if (codexLb.tool_output_recovery) {
1678
2197
  const recovery = codexLb.tool_output_recovery;
1679
2198
  console.log(` interrupted tool-output recovery: ${recovery.ok ? 'ready' : 'blocked'} (${recovery.observed_version || recovery.status}; minimum ${recovery.minimum_version})`);
@@ -1727,31 +2246,27 @@ async function runDoctor(args = [], root, doctorFix) {
1727
2246
  if (!result.ok)
1728
2247
  process.exitCode = 1;
1729
2248
  }
1730
- function buildRuntimeReadiness(zellijReadiness, matrix) {
2249
+ export function buildRuntimeReadiness(matrix) {
1731
2250
  const defaults = matrix?.invocation_defaults || {};
1732
2251
  const hookPolicy = defaults.hook_evidence_policy || 'unknown-do-not-count';
1733
2252
  const agentStrategy = defaults.loop_worker_role_strategy || 'message-role';
1734
2253
  const multiAgentMode = defaults.multi_agent_mode || 'none';
1735
2254
  const rolloutBudget = defaults.rollout_budget_strategy || 'sks-local-only';
1736
2255
  const researchSource = defaults.research_source_strategy || 'local-files';
1737
- const zellijStatus = zellijReadiness?.status === 'ok'
1738
- ? 'ok'
1739
- : zellijReadiness?.cli_ready ? 'headless_available' : 'repair_required';
1740
- const codexNative = matrix?.ok === true
1741
- ? 'ok'
1742
- : matrix?.codex_cli?.available ? 'degraded' : 'blocked';
2256
+ const codexNative = matrix?.ok === true ? 'ok' : matrix?.codex_cli?.available ? 'degraded' : 'blocked';
1743
2257
  const repairActions = [];
1744
- if (zellijStatus !== 'ok') {
1745
- repairActions.push('Zellij: sks doctor --fix --yes');
1746
- repairActions.push('Homebrew + Zellij: sks doctor --fix --install-homebrew --yes');
2258
+ if (codexNative !== 'ok') {
2259
+ repairActions.push([
2260
+ 'Codex Native managed assets: sks doctor',
2261
+ '--fix',
2262
+ '--repair-codex-native',
2263
+ '--yes'
2264
+ ].join(' '));
1747
2265
  }
1748
- if (codexNative !== 'ok')
1749
- repairActions.push('Codex Native managed assets: sks doctor --fix --repair-codex-native --yes');
1750
2266
  if (matrix?.features?.project_memory?.ok !== true)
1751
2267
  repairActions.push('Project memory: sks codex-native init-deep --apply --directory-local');
1752
2268
  return {
1753
2269
  schema: 'sks.runtime-readiness-story.v1',
1754
- zellij: zellijStatus,
1755
2270
  codex_native: codexNative,
1756
2271
  loop_mesh: agentStrategy === 'agent_type' ? 'ok' : 'fallback',
1757
2272
  qa_visual: defaults.qa_visual_review_strategy || 'blocked',
@@ -1764,12 +2279,11 @@ function buildRuntimeReadiness(zellijReadiness, matrix) {
1764
2279
  current_time_source: defaults.current_time_source || 'external-clock',
1765
2280
  overload_retry_policy: defaults.overload_retry_policy || 'generic',
1766
2281
  notes: [
1767
- ...(zellijStatus === 'headless_available' ? ['MAD can run with --headless; live panes require repair'] : []),
1768
2282
  ...(hookPolicy !== 'approved-only' ? ['hook-derived evidence will not count'] : []),
1769
2283
  ...(agentStrategy !== 'agent_type' ? ['message-role fallback active'] : []),
1770
- ...(multiAgentMode === 'proactive' ? [`Codex ${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion} multi-agent proactive mode available for Naruto-style routes`] : []),
1771
- ...(rolloutBudget === 'codex-0144-shared' ? [`Codex ${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion} rollout budget can be recorded in route proof`] : []),
1772
- ...(researchSource === 'indexed-web-search' ? [`Codex ${CURRENT_CODEX_RELEASE_MANIFEST.requiredCliVersion} indexed web search selected for source-intelligence routes`] : [])
2284
+ ...(multiAgentMode === 'proactive' ? ['Proactive multi-agent mode is available for Naruto-style routes'] : []),
2285
+ ...(rolloutBudget === 'codex-0144-shared' ? ['Shared rollout budgeting is available for route proof'] : []),
2286
+ ...(researchSource === 'indexed-web-search' ? ['Indexed web search is selected for source-intelligence routes'] : [])
1773
2287
  ],
1774
2288
  repair_actions: [...new Set(repairActions)]
1775
2289
  };
@@ -1865,26 +2379,6 @@ function doctorDedupeStatus(skillDedupe) {
1865
2379
  return 'manual_required';
1866
2380
  return 'none';
1867
2381
  }
1868
- function buildZellijReadiness(root, zellij, ready) {
1869
- const status = String(zellij?.status || 'missing');
1870
- const usable = status === 'ok';
1871
- const proofStatus = usable ? 'optional' : 'unavailable';
1872
- const readiness = {
1873
- schema: 'sks.zellij-readiness.v1',
1874
- binary: zellij?.bin || 'zellij',
1875
- status,
1876
- min_version: zellij?.min_version || '0.41.0',
1877
- version: zellij?.version || null,
1878
- required_for: zellij?.required_for || ['sks --mad', 'interactive lane UI'],
1879
- layout_proof: proofStatus,
1880
- pane_proof: proofStatus,
1881
- screen_proof: proofStatus,
1882
- mad_ready: ready?.mad_ready === true,
1883
- cli_ready: ready?.cli_ready === true,
1884
- ready_for_interactive_runtime: ready?.codex_config_readable_in_zellij_context === true
1885
- };
1886
- return readiness;
1887
- }
1888
2382
  async function codexHomeConfigPath() {
1889
2383
  const path = await import('node:path');
1890
2384
  const os = await import('node:os');
@@ -2011,6 +2505,95 @@ export function formatCodexDoctorConsoleStatus(report) {
2011
2505
  return 'unavailable';
2012
2506
  return report.disposition || (report.exit_code === 0 ? 'pass' : 'warn');
2013
2507
  }
2508
+ export function sksMenuBarRunningVersionConsoleLines(status) {
2509
+ const runningVersion = status?.running_process?.package_version
2510
+ || status?.menubar_version_probe?.running_version
2511
+ || null;
2512
+ const runningPid = status?.running_process?.pid ?? status?.menubar_version_probe?.pid ?? null;
2513
+ if (typeof runningVersion !== 'string' || !runningVersion || !Number.isInteger(runningPid) || runningPid <= 0) {
2514
+ return [];
2515
+ }
2516
+ const expectedVersion = status?.menubar_version_probe?.expected_version
2517
+ || status?.action_target?.expected_version
2518
+ || status?.package_version
2519
+ || null;
2520
+ const installedVersion = status?.installed_version || status?.build_stamp?.package_version || null;
2521
+ return [
2522
+ ` RUNNING: version ${runningVersion} (PID ${runningPid})`,
2523
+ ...(typeof expectedVersion === 'string' && expectedVersion && expectedVersion !== runningVersion
2524
+ ? [` expected: version ${expectedVersion}`]
2525
+ : []),
2526
+ ...(typeof installedVersion === 'string' && installedVersion && installedVersion !== runningVersion
2527
+ ? [` installed: version ${installedVersion}`]
2528
+ : [])
2529
+ ];
2530
+ }
2531
+ export async function rebootstrapSksMenuBarLaunchdForDoctorFix(input, deps = {}) {
2532
+ const env = input.env || process.env;
2533
+ const status = input.status;
2534
+ const expectedVersion = status?.menubar_version_probe?.expected_version
2535
+ || status?.action_target?.expected_version
2536
+ || status?.installed_version
2537
+ || null;
2538
+ const warningOnlyVerifiedProcess = input.fix
2539
+ && !sksMenuBarRestartDeferred(env)
2540
+ && status?.launchd?.checked === true
2541
+ && status?.launchd?.ok === false
2542
+ && Array.isArray(status?.warnings)
2543
+ && status.warnings.includes('launchd_not_running_process_active')
2544
+ && !(Array.isArray(status?.blockers) && status.blockers.includes('launchd_not_running'))
2545
+ && status?.running_process?.ok === true
2546
+ && typeof expectedVersion === 'string'
2547
+ && status.running_process.package_version === expectedVersion;
2548
+ if (!warningOnlyVerifiedProcess) {
2549
+ return { attempted: false, ok: true, status, restart: null };
2550
+ }
2551
+ const paths = sksMenuBarPaths(input.home || env.HOME, input.root);
2552
+ const restartImpl = deps.restartLaunchAgentImpl || restartLaunchAgent;
2553
+ const inspectImpl = deps.inspectSksMenuBarStatusImpl || inspectSksMenuBarStatus;
2554
+ const restart = await restartImpl(paths, env).catch((error) => ({
2555
+ ok: false,
2556
+ error: error instanceof Error ? error.message : String(error)
2557
+ }));
2558
+ if (restart?.ok !== true) {
2559
+ const detail = restart?.error ? `:${restart.error}` : '';
2560
+ return {
2561
+ attempted: true,
2562
+ ok: false,
2563
+ restart,
2564
+ status: {
2565
+ ...status,
2566
+ ok: false,
2567
+ blockers: [...new Set([...(status?.blockers || []), `launchd_rebootstrap_failed${detail}`])]
2568
+ }
2569
+ };
2570
+ }
2571
+ const refreshed = await inspectImpl({
2572
+ root: input.root,
2573
+ ...(input.home ? { home: input.home } : {}),
2574
+ ...(input.env ? { env: input.env } : {})
2575
+ }).catch((error) => ({
2576
+ ...status,
2577
+ ok: false,
2578
+ blockers: [...new Set([
2579
+ ...(status?.blockers || []),
2580
+ `launchd_rebootstrap_status_failed:${error instanceof Error ? error.message : String(error)}`
2581
+ ])]
2582
+ }));
2583
+ if (refreshed?.launchd?.checked !== true || refreshed?.launchd?.ok !== true) {
2584
+ return {
2585
+ attempted: true,
2586
+ ok: false,
2587
+ restart,
2588
+ status: {
2589
+ ...refreshed,
2590
+ ok: false,
2591
+ blockers: [...new Set([...(refreshed?.blockers || []), 'launchd_rebootstrap_not_confirmed'])]
2592
+ }
2593
+ };
2594
+ }
2595
+ return { attempted: true, ok: true, status: refreshed, restart };
2596
+ }
2014
2597
  function mergeObservedCodexStartupWarnings(startupRepair, codexDoctor) {
2015
2598
  const text = `${codexDoctor?.stdout_tail || ''}\n${codexDoctor?.stderr_tail || ''}`;
2016
2599
  const manual = new Set(Array.isArray(startupRepair?.manual_actions) ? startupRepair.manual_actions : []);