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,4 +1,5 @@
1
1
  import Cocoa
2
+
2
3
  final class ProvidersViewController: NSViewController, ControlCenterPage, NSTextFieldDelegate {
3
4
  private let capabilityDefinitions: [(label: String, keys: [String])] = [
4
5
  ("OAuth Identity", ["oauth_identity", "provider_identity"]), ("Built-in Provider", ["built_in_provider", "provider_identity"]),
@@ -7,12 +8,33 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
7
8
  ("Voice", ["voice", "voice_mode"]), ("Plugins", ["plugins"])
8
9
  ]
9
10
  private let capabilityStates = Set(["verified", "available_unverified", "blocked", "unsupported", "skipped"])
10
- private let cliLaunchCommand = "codex --config model_provider='\"codex-lb\"'"
11
+ private let cliLaunchCommand = "codex"
11
12
  let processClient: ProcessClient
12
13
  let operations: OperationCoordinator
13
14
  let providerStatus = NativeView.detail("Desktop routing status unchecked.")
14
15
  let cliProviderStatus = NativeView.detail("CLI provider status unchecked.")
16
+ let cliConnectConfigurationStage = NativeView.detail("1. Configuration · waiting")
17
+ let cliConnectRequestStage = NativeView.detail("2. One-request low-token test · waiting")
18
+ let cliConnectResponseStage = NativeView.detail("3. Response · not received")
19
+ let cliConnectResult = NativeView.detail("Connection proof has not run.")
20
+ let cliConnectProgress: NSProgressIndicator = {
21
+ let progress = NSProgressIndicator()
22
+ progress.style = .bar
23
+ progress.isIndeterminate = false
24
+ progress.minValue = 0
25
+ progress.maxValue = 3
26
+ progress.doubleValue = 0
27
+ progress.setAccessibilityLabel("Codex LB connection proof progress")
28
+ progress.setAccessibilityIdentifier("sks-center-codex-lb-connect-progress")
29
+ return progress
30
+ }()
15
31
  let capabilityStatus = NativeView.detail("Capabilities have not been verified.")
32
+ let capabilityLastCheckedStatus = NativeView.detail("Last feature check: never · choose Verify Capabilities.")
33
+ let catalogSyncStatus = NativeView.detail("Native Codex catalog sync: not reported yet.")
34
+ let providerApplyStatus = NativeView.detail("Provider apply stages: no operation receipt yet.")
35
+ let codexLbKeychainStatus = NativeView.detail("Codex LB credential: checking Keychain without UI…")
36
+ let openRouterKeychainStatus = NativeView.detail("OpenRouter credential: checking Keychain without UI…")
37
+ let oauthCredentialStatus = NativeView.detail("ChatGPT OAuth credential: checking Codex-owned auth state…")
16
38
  let openRouterCredentialStatus = NativeView.detail("Credential: checking…")
17
39
  let openRouterActiveStatus = NativeView.detail("Active provider: checking…")
18
40
  let openRouterCatalogStatus = NativeView.detail("Model catalog has not loaded yet.")
@@ -35,6 +57,7 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
35
57
  var codexLbSelectedNow = false
36
58
  var chatgptOauthPresentNow = false
37
59
  var openRouterSelectedNow = false
60
+ var openRouterCredentialValidatedNow = false
38
61
  var openRouterActiveModel = ""
39
62
  var routerSelectedNow = false
40
63
  var routerActiveModel = ""
@@ -51,7 +74,9 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
51
74
  var roleRefreshInFlight = false
52
75
  var openRouterModelSelectionPending = false
53
76
  var openRouterActionRan = false
77
+ var connectTestInFlight = false
54
78
  var busy = false
79
+ let keychainStore = SKSKeychainStore()
55
80
  init(processClient: ProcessClient, operations: OperationCoordinator) {
56
81
  self.processClient = processClient
57
82
  self.operations = operations
@@ -59,32 +84,50 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
59
84
  }
60
85
  required init?(coder: NSCoder) { nil }
61
86
  override func loadView() {
62
- let enableDesktop = ControlKit.primaryButton("Use Codex LB", target: self, action: #selector(enableDesktopFull))
87
+ let enableDesktop = NativeView.button("Desktop Bridge Mode (keeps ChatGPT sign-in)", target: self, action: #selector(enableDesktopFull))
63
88
  let verifyDesktop = NativeView.button("Verify Capabilities", target: self, action: #selector(verifyDesktopCapabilities))
64
89
  let disableDesktop = NativeView.button("Use ChatGPT OAuth Only", target: self, action: #selector(disableDesktopRouting))
65
- enableDesktop.setAccessibilityLabel("Use Codex LB Desktop Full Capability routing while keeping ChatGPT OAuth, then restart Codex App")
90
+ enableDesktop.setAccessibilityLabel("Advanced Desktop Bridge Mode that keeps ChatGPT sign-in, then restarts Codex App")
66
91
  verifyDesktop.setAccessibilityLabel("Verify Desktop transport capabilities")
67
92
  disableDesktop.setAccessibilityLabel("Disable Codex LB Desktop routing and keep ordinary ChatGPT OAuth, then restart Codex App")
68
- // Keep the mode CTAs discoverable: never hide Use Codex LB / Use ChatGPT OAuth Only based on status parsing.
69
- let configureCli = NativeView.button("Configure / Update…", target: self, action: #selector(setDomainAndKey))
70
- let useCli = NativeView.button("Use Saved CLI Provider", target: self, action: #selector(useCliProvider))
71
- let testCli = NativeView.button("Test", target: self, action: #selector(testConnection))
93
+ // Keep the mode CTAs discoverable: never hide the advanced bridge or ChatGPT OAuth actions based on status parsing.
94
+ let configureCli = NativeView.button("Reconnect Codex LB credential…", target: self, action: #selector(setDomainAndKey))
95
+ let useCli = ControlKit.primaryButton("Use Codex LB", target: self, action: #selector(useCliProvider))
96
+ useCli.setAccessibilityLabel("Use Codex LB through the atomic CLI provider path")
97
+ let testCli = NativeView.button("Run Connect Test", target: self, action: #selector(testConnection))
98
+ testCli.setAccessibilityHelp("Send one bounded low-token request through the selected Codex LB provider and show the returned proof.")
72
99
  let copyCli = NativeView.button("Copy CLI Command", target: self, action: #selector(copyCliCommand))
73
100
  let fastOn = NativeView.button("Codex Fast On", target: self, action: #selector(fastOn))
74
101
  let fastOff = NativeView.button("Codex Fast Off", target: self, action: #selector(fastOff))
75
- actionButtons = [enableDesktop, verifyDesktop, disableDesktop, configureCli, useCli, testCli, copyCli, fastOn, fastOff]
102
+ let reconnectOpenRouter = NativeView.button("Reconnect OpenRouter credential…", target: self, action: #selector(saveOpenRouterKey))
103
+ let openCodexSignIn = NativeView.button("Open Codex sign-in…", target: self, action: #selector(openCodexSignInAction))
104
+ registerProviderAction(enableDesktop, id: "sks-provider-use-codex-lb")
105
+ registerProviderAction(verifyDesktop, id: "sks-provider-verify-capabilities")
106
+ registerProviderAction(disableDesktop, id: "sks-provider-use-chatgpt-oauth")
107
+ registerProviderAction(configureCli, id: "sks-provider-reconnect-codex-lb")
108
+ registerProviderAction(testCli, id: "sks-provider-run-connect-test")
109
+ registerProviderAction(copyCli, id: "sks-provider-copy-cli-command")
110
+ registerProviderAction(useCli, id: "sks-provider-activate-codex-lb")
111
+ registerProviderAction(reconnectOpenRouter, id: "sks-provider-reconnect-openrouter")
112
+ registerProviderAction(openCodexSignIn, id: "sks-provider-open-codex-signin")
113
+ registerProviderAction(fastOn, id: "sks-provider-fast-on")
114
+ registerProviderAction(fastOff, id: "sks-provider-fast-off")
115
+ providerApplyStatus.setAccessibilityIdentifier("sks-center-provider-apply-status")
116
+ providerApplyStatus.setAccessibilityLabel("Provider apply stage receipts")
117
+ actionButtons = [enableDesktop, verifyDesktop, disableDesktop, configureCli, reconnectOpenRouter, openCodexSignIn, useCli, testCli, copyCli, fastOn, fastOff]
76
118
  let desktop = NativeView.card(
77
- title: "Codex LB · Desktop Full Capability (Recommended)",
78
- subtitle: "Selectable Codex LB mode: keeps ChatGPT OAuth identity and the built-in OpenAI provider while routing model traffic through the local codex-lb bridge. Use ChatGPT OAuth Only removes LB routing without touching login.",
119
+ title: "Advanced · Desktop Bridge / ChatGPT Identity Mode",
120
+ subtitle: "Optional bridge mode: keeps ChatGPT OAuth identity and the built-in OpenAI provider while routing model traffic through the local codex-lb bridge. Use ChatGPT OAuth Only removes bridge routing without touching login.",
79
121
  views: [providerStatus, ControlKit.actionRow([enableDesktop, verifyDesktop], trailing: [disableDesktop])]
80
122
  )
81
123
  let cli = NativeView.card(
82
- title: "Codex LB · Credentials & CLI Provider",
83
- subtitle: "Saves the official Center Codex LB host and API key (sks-codex-lb store). Desktop routing buttons above consume that same store automatically — no shell source or twin env files.",
124
+ title: "Codex LB · Credentials & Primary Provider",
125
+ subtitle: "Saves the official Center Codex LB host and API key (sks-codex-lb store). Use Codex LB applies the atomic CLI provider path — no shell source or twin env files.",
84
126
  views: [
85
- cliProviderStatus,
127
+ cliProviderStatus, codexLbKeychainStatus,
86
128
  NativeView.detail("One-off command: \(cliLaunchCommand)"),
87
129
  ControlKit.actionRow([configureCli, useCli]),
130
+ makeCliConnectProgressView(),
88
131
  ControlKit.actionRow([testCli, copyCli])
89
132
  ]
90
133
  )
@@ -99,21 +142,30 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
99
142
  )
100
143
  view = NativeView.page([
101
144
  NativeView.row([NativeView.title("Providers & Models"), globalSpinner]),
102
- NativeView.detail("Codex LB and ChatGPT OAuth are explicit Desktop modes below. CLI automation and Fast stay independent. Secrets are sent through stdin and redacted from logs."),
103
- makeActiveProviderCard(), desktop, cli, makeCapabilityMatrixCard(), makeOpenRouterCard(),
104
- makeMultiProviderRouterCard(), makeRoleModelsCard(), fast
145
+ NativeView.detail("Codex always sees its native OpenAI identity through a local loopback proxy. SKS selects exactly one internal mode: Codex LB, OpenRouter, or ChatGPT OAuth. Secrets are sent through stdin and never written to operation logs."),
146
+ NativeView.card(
147
+ title: "Authentication Recovery",
148
+ subtitle: "Background refresh and menu restarts never open authentication UI. Missing, locked, damaged, or inaccessible credentials stay in an Authentication Required state until you choose a reconnect action.",
149
+ views: [codexLbKeychainStatus, openRouterKeychainStatus, oauthCredentialStatus, NativeView.row([configureCli, reconnectOpenRouter, openCodexSignIn])]
150
+ ),
151
+ NativeView.card(
152
+ title: "Provider Apply Stages",
153
+ subtitle: "Configuration, proxy, catalog, and new-session readiness are independent. Existing sessions keep their pinned copy; a partial failure never appears as silent success.",
154
+ views: [providerApplyStatus]
155
+ ),
156
+ makeActiveProviderCard(), cli, desktop, makeCapabilityMatrixCard(), makeOpenRouterCard(),
157
+ makeRoleModelsCard(), fast
105
158
  ])
106
159
  }
107
160
  func refreshOnAppear() { refresh() }
108
161
  func setBusy(_ value: Bool) {
109
162
  busy = value
110
163
  for button in actionButtons { button.isEnabled = !value }
111
- openRouterModelField.isEnabled = !value
112
- openRouterModelPopup.isEnabled = !value && !openRouterModels.isEmpty
164
+ openRouterModelField.isEnabled = !value && openRouterCredentialValidatedNow
165
+ openRouterModelPopup.isEnabled = !value && openRouterCredentialValidatedNow && !openRouterModels.isEmpty
113
166
  openRouterRefreshButton?.isEnabled = !value && !catalogRefreshInFlight
114
167
  openRouterRestoreButton?.isEnabled = !value && openRouterRestoreAvailable
115
168
  roleRefreshButton?.isEnabled = !value && !roleRefreshInFlight
116
- setMultiProviderRouterBusy(value)
117
169
  updateRoleControlAvailability()
118
170
  if value { globalSpinner.startAnimation(nil) }
119
171
  else { globalSpinner.stopAnimation(nil) }
@@ -135,6 +187,8 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
135
187
  }
136
188
  }
137
189
  func refresh() {
190
+ refreshCredentialHealth()
191
+ renderLatestProviderApply()
138
192
  processClient.run(["codex-lb", "status", "--json"], timeout: NativeView.statusTimeout) { [weak self] result in
139
193
  guard let self = self else { return }
140
194
  guard let json = self.json(result.output) else {
@@ -145,30 +199,40 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
145
199
  return
146
200
  }
147
201
  let snapshot = ProviderRoutingTruth.snapshot(from: json)
148
- self.desktopFullRoutingNow = snapshot.desktopFullRouting
149
- self.codexLbSelectedNow = snapshot.legacyCodexLbSelected
202
+ let measuredRoute = ProviderRoutingTruth.measuredRoute(from: json)
203
+ let measuredRoutingOk = measuredRoute?.selected == true
204
+ && measuredRoute?.measured == true
205
+ && measuredRoute?.ok == true
206
+ self.desktopFullRoutingNow = snapshot.desktopFullRouting && measuredRoutingOk
207
+ self.codexLbSelectedNow = snapshot.legacyCodexLbSelected || measuredRoute?.selected == true
150
208
  self.chatgptOauthPresentNow = snapshot.chatgptOauthPresent
209
+ self.oauthCredentialStatus.stringValue = snapshot.chatgptOauthPresent
210
+ ? "ChatGPT OAuth: connected · refresh token remains Codex-owned and is never copied by SKS."
211
+ : "Authentication Required: ChatGPT OAuth is not connected. Choose Open Codex sign-in; no login window was opened automatically."
212
+ self.oauthCredentialStatus.textColor = snapshot.chatgptOauthPresent ? .secondaryLabelColor : .systemOrange
213
+ self.renderCatalogSyncStatus(json)
151
214
  self.renderActiveProviderSummary()
215
+ self.renderMeasuredRoutingBadge(measuredRoute, routeExpected: snapshot.desktopFullRouting || snapshot.legacyCodexLbSelected)
152
216
  if !self.busy {
153
217
  self.providerStatus.stringValue = self.describeDesktopStatus(snapshot)
154
- self.cliProviderStatus.stringValue = self.describeCliStatus(snapshot)
218
+ self.cliProviderStatus.stringValue = self.describeCliStatus(snapshot, measuredRoute: measuredRoute)
155
219
  }
156
220
  }
157
221
  refreshOpenRouterStatus()
158
- refreshMultiProviderRouterStatus()
159
222
  if openRouterModels.isEmpty { refreshOpenRouterModels() }
160
223
  refreshRoleModels()
161
224
  refreshFastStatus()
162
225
  }
226
+
163
227
  private func makeCapabilityMatrixCard() -> NSBox {
164
- var views: [NSView] = [capabilityStatus]
228
+ var views: [NSView] = [capabilityStatus, capabilityLastCheckedStatus, catalogSyncStatus]
165
229
  for definition in capabilityDefinitions {
166
230
  let value = NativeView.detail("skipped")
167
231
  value.setAccessibilityLabel("\(definition.label) capability state")
168
232
  capabilityRows[definition.label] = value
169
233
  views.append(ControlKit.keyValueRow(definition.label, value))
170
234
  }
171
- return NativeView.card(title: "Capability Matrix", subtitle: "States come from capability evidence, not configuration alone: verified, available_unverified, blocked, unsupported, or skipped.", views: views)
235
+ return NativeView.card(title: "Latest Codex Feature Compatibility", subtitle: "Every feature reports availability, direct proxy or OAuth auxiliary path, OAuth requirement, last check, failure reason, and recovery. Missing metadata is shown as unverified; SKS never hides the feature or silently falls back.", views: views)
172
236
  }
173
237
  private func describeDesktopStatus(_ snapshot: ProviderRoutingTruth.Snapshot) -> String {
174
238
  if snapshot.legacyDestructive {
@@ -189,7 +253,19 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
189
253
  ? "ChatGPT OAuth mode: active · Codex LB Desktop routing not enabled. Choose Use Codex LB to switch."
190
254
  : "ChatGPT OAuth mode available · ChatGPT sign-in is missing · run codex login, then Use Codex LB if needed."
191
255
  }
192
- private func describeCliStatus(_ snapshot: ProviderRoutingTruth.Snapshot) -> String {
256
+ private func describeCliStatus(_ snapshot: ProviderRoutingTruth.Snapshot, measuredRoute: ProviderRoutingTruth.MeasuredRoute?) -> String {
257
+ if let route = measuredRoute, route.selected {
258
+ switch route.state {
259
+ case .active:
260
+ return "CLI provider: active · \(describeRoutingTruth(route))"
261
+ case .degraded:
262
+ return "CLI provider: degraded · \(describeRoutingTruth(route))"
263
+ case .unverified:
264
+ return "CLI provider: selected but unverified · \(describeRoutingTruth(route))"
265
+ case .inactive:
266
+ break
267
+ }
268
+ }
193
269
  if snapshot.cliCredentialsConfigured && snapshot.cliProviderStored {
194
270
  return "CLI provider: configured · availability remains unverified until Test succeeds."
195
271
  }
@@ -214,7 +290,12 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
214
290
  let state = states.max { capabilityStateRank($0) < capabilityStateRank($1) } ?? "skipped"
215
291
  rendered.append(state)
216
292
  let label = capabilityRows[definition.label]
217
- label?.stringValue = state
293
+ label?.stringValue = capabilityCompatibilityDetail(
294
+ definition: definition,
295
+ payload: payload,
296
+ state: state,
297
+ trustVerified: trustVerified
298
+ )
218
299
  label?.textColor = capabilityColor(state)
219
300
  }
220
301
  guard recognized else { capabilityStatus.stringValue = "Capability response did not contain recognized evidence. No state was assumed."; return nil }
@@ -226,6 +307,10 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
226
307
  let blockerText = blockers.isEmpty ? "" : " · blockers: \(blockers.prefix(3).joined(separator: ", "))"
227
308
  let trustText = reportedOverall == "verified" && !trustVerified ? " · trusted deep evidence missing" : ""
228
309
  capabilityStatus.stringValue = "Capabilities: \(overall) · \(verifiedCount)/\(rendered.count) verified\(trustText)\(blockerText)."
310
+ let checkedAt = (payload["checked_at"] as? String)
311
+ ?? (payload["updated_at"] as? String)
312
+ ?? ISO8601DateFormatter().string(from: Date())
313
+ capabilityLastCheckedStatus.stringValue = "Last feature check: \(checkedAt) · result \(overall)."
229
314
  return overall
230
315
  }
231
316
  private func capabilityState(_ key: String, payload: [String: Any], allowVerified: Bool) -> String? {
@@ -287,75 +372,19 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
287
372
  ]
288
373
  ) { [weak self] transport in
289
374
  guard let self = self, let transport = transport else { return }
290
- self.promptForKey(window: window, args: ["codex-lb", "setup", "--host", host, "--gateway-auth", transport, "--api-key-stdin", "--yes", "--write-env-file", "--keychain", "--json"], kind: "codex-lb-center-setup", title: "Save Codex LB credentials")
375
+ self.promptForKey(window: window, args: ["codex-lb", "setup", "--host", host, "--gateway-auth", transport, "--api-key-stdin", "--yes", "--write-env-file", "--json"], kind: "codex-lb-center-setup", title: "Save Codex LB credentials")
291
376
  }
292
377
  }
293
378
  }
294
379
  private func promptForKey(window: NSWindow, args: [String], kind: String, title: String) {
295
- promptForSecretKey(window: window, sheetTitle: "Codex LB API Key", sheetMessage: "Paste your Codex LB API key (usually starts with sk-clb-). The field stays masked; the key is sent through stdin and stored as the official SKS Center credential Desktop uses automatically.", placeholder: "sk-clb-…", args: args, kind: kind, title: title, statusLabel: cliProviderStatus, successSummary: "Codex LB credentials saved for Center/Desktop", failSummary: "Codex LB credential save failed")
296
- }
297
- func promptForSecretKey(window: NSWindow, sheetTitle: String, sheetMessage: String, placeholder: String, args: [String], kind: String, title: String, statusLabel: NSTextField, successSummary: String, failSummary: String) {
298
- AlertFactory.textSheet(window: window, title: sheetTitle, message: sheetMessage, secure: true, placeholder: placeholder) { [weak self] key in
299
- guard let self = self, let key = key else { return }
300
- guard !self.busy else { statusLabel.stringValue = "Another provider action is already running."; return }
301
- guard let snapshot = self.operations.begin(kind: kind, mutationGroup: "codex-config", summary: title) else {
302
- statusLabel.stringValue = "Another guarded mutation is already running. Wait or open Diagnostics."
303
- return
304
- }
305
- self.setBusy(true)
306
- statusLabel.stringValue = "\(title)…"
307
- _ = self.operations.update(snapshot, state: .running, stage: "running", progress: nil, summary: title)
308
- self.processClient.run(args, stdin: key + "\n", timeout: NativeView.mutationTimeout) { [weak self] result in
309
- guard let self = self else { return }
310
- self.setBusy(false)
311
- let parsed = self.json(result.output)
312
- let ok = result.code == 0 && parsed?["ok"] as? Bool == true
313
- _ = self.operations.update(snapshot, state: ok ? .succeeded : .failed, stage: "complete", progress: 1, summary: ok ? successSummary : failSummary)
314
- statusLabel.stringValue = ok
315
- ? "\(successSummary). Next: test the saved configuration."
316
- : "\(failSummary) · \(self.structuredPublicDetail(parsed, fallback: result.output))"
317
- self.refresh()
318
- }
319
- }
380
+ promptForSecretKey(window: window, sheetTitle: "Codex LB API Key", sheetMessage: "Paste your Codex LB API key (usually starts with sk-clb-). This explicit reconnect is the only action allowed to update Keychain. The field stays masked and the key is never written to operation logs.", placeholder: "sk-clb-…", args: args, kind: kind, title: title, credential: .codexLbApiKey, statusLabel: cliProviderStatus, successSummary: "Codex LB credentials saved for Center/Desktop", failSummary: "Codex LB credential save failed")
320
381
  }
321
382
  @objc private func enableDesktopFull() {
322
- performDesktopRouting(["codex-lb", "use-desktop-full", "--restart-app", "--json"], title: "Use Codex LB", kind: "codex-lb-use-desktop-full", expectedMode: "desktop-native-bridge")
383
+ performDesktopRouting(["codex-lb", "use-desktop-full", "--restart-app", "--json"], title: "Desktop Bridge Mode (keeps ChatGPT sign-in)", kind: "codex-lb-use-desktop-full", expectedMode: "desktop-native-bridge")
323
384
  }
324
385
  @objc private func disableDesktopRouting() {
325
386
  performDesktopRouting(["codex-lb", "disable", "--restart-app", "--json"], title: "Use ChatGPT OAuth Only", kind: "codex-lb-disable-desktop", expectedMode: "disabled")
326
387
  }
327
- private func performDesktopRouting(_ args: [String], title: String, kind: String, expectedMode: String) {
328
- guard !busy else { providerStatus.stringValue = "Another provider action is already running."; return }
329
- guard let snapshot = operations.begin(kind: kind, mutationGroup: "codex-config", summary: title) else {
330
- providerStatus.stringValue = "Another guarded mutation is already running. Wait or open Diagnostics."
331
- return
332
- }
333
- setBusy(true)
334
- providerStatus.stringValue = "\(title)…"
335
- _ = operations.update(snapshot, state: .running, stage: "routing", progress: nil, summary: title)
336
- processClient.run(args, timeout: NativeView.mutationTimeout) { [weak self] result in
337
- guard let self = self else { return }
338
- self.setBusy(false)
339
- let parsed = self.json(result.output)
340
- let routing = parsed.map(ProviderRoutingTruth.snapshot(from:))
341
- let mode = routing?.mode
342
- let oauthPreserved = routing.flatMap { $0.oauthPreservedFlag }
343
- let ok = result.code == 0 && parsed?["ok"] as? Bool == true && mode == expectedMode && oauthPreserved != false
344
- _ = self.operations.update(snapshot, state: ok ? .succeeded : .failed, stage: "complete", progress: 1, summary: ok ? "\(title) completed" : "\(title) needs action")
345
- guard ok else {
346
- self.providerStatus.stringValue = "\(title) was not confirmed · \(self.structuredPublicDetail(parsed, fallback: result.output)) No routing or OAuth change was assumed."
347
- return
348
- }
349
- self.desktopFullRoutingNow = expectedMode == "desktop-native-bridge"
350
- self.codexLbSelectedNow = false
351
- self.chatgptOauthPresentNow = routing?.chatgptOauthPresent ?? self.chatgptOauthPresentNow
352
- self.renderActiveProviderSummary()
353
- self.providerStatus.stringValue = self.desktopFullRoutingNow
354
- ? "Codex LB mode enabled · OAuth preserved · capability verification still required."
355
- : "ChatGPT OAuth mode active · Codex LB Desktop routing disabled."
356
- self.refresh()
357
- }
358
- }
359
388
  @objc private func verifyDesktopCapabilities() {
360
389
  guard !busy else { capabilityStatus.stringValue = "Another provider action is already running."; return }
361
390
  guard let snapshot = operations.begin(kind: "codex-lb-capabilities", mutationGroup: nil, summary: "Verify Desktop capabilities") else {
@@ -385,7 +414,7 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
385
414
  }
386
415
  }
387
416
  @objc private func useCliProvider() {
388
- performCliCommand(["codex-lb", "use-cli", "--json"], title: "Configure saved CLI provider", kind: "codex-lb-use-cli")
417
+ performDesktopRouting(["codex-lb", "use-desktop-full", "--restart-app", "--json"], title: "Use Codex LB", kind: "codex-lb-use-desktop-full", expectedMode: "desktop-native-bridge")
389
418
  }
390
419
  private func performCliCommand(_ args: [String], title: String, kind: String) {
391
420
  guard !busy else { cliProviderStatus.stringValue = "Another provider action is already running."; return }
@@ -395,42 +424,58 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
395
424
  }
396
425
  setBusy(true)
397
426
  cliProviderStatus.stringValue = "\(title)…"
427
+ renderCliConnectStages(
428
+ progress: 0,
429
+ configuration: "applying CLI provider…",
430
+ request: "waiting for configuration",
431
+ response: "not received",
432
+ result: "Selecting Codex LB mode. Connectivity has not been claimed.",
433
+ tone: .secondaryLabelColor
434
+ )
398
435
  _ = operations.update(snapshot, state: .running, stage: "configuring", progress: nil, summary: title)
399
436
  processClient.run(args, timeout: NativeView.mutationTimeout) { [weak self] result in
400
437
  guard let self = self else { return }
401
- self.setBusy(false)
402
438
  let parsed = self.json(result.output)
403
439
  let routing = parsed.map(ProviderRoutingTruth.snapshot(from:))
404
440
  let mode = routing?.mode
405
441
  let oauthPreserved = routing.flatMap { $0.oauthPreservedFlag }
406
442
  let authMutated = routing.flatMap { $0.authMutated }
407
- let ok = result.code == 0 && parsed?["ok"] as? Bool == true && mode == "cli-provider" && oauthPreserved != false && authMutated != true
443
+ let ok = result.code == 0
444
+ && parsed?["ok"] as? Bool == true
445
+ && mode == "cli-provider"
446
+ && oauthPreserved != false
447
+ && authMutated != true
408
448
  _ = self.operations.update(snapshot, state: ok ? .succeeded : .failed, stage: "complete", progress: 1, summary: ok ? "CLI provider configured" : "CLI provider configuration needs action")
409
- self.cliProviderStatus.stringValue = ok
410
- ? "CLI provider configured · Desktop OAuth and global provider selection unchanged · Test still required."
411
- : "CLI provider was not confirmed · \(self.structuredPublicDetail(parsed, fallback: result.output))"
412
- if ok { self.refresh() }
413
- }
414
- }
415
- @objc private func testConnection() {
416
- guard !busy else { cliProviderStatus.stringValue = "Another provider action is already running."; return }
417
- guard let snapshot = operations.begin(kind: "codex-lb-health", mutationGroup: nil, summary: "Test CLI provider") else {
418
- cliProviderStatus.stringValue = "Another guarded operation is already running. Wait or open Diagnostics."
419
- return
420
- }
421
- setBusy(true)
422
- cliProviderStatus.stringValue = "Testing CLI provider transport…"
423
- _ = operations.update(snapshot, state: .running, stage: "testing", progress: nil, summary: "Test CLI provider")
424
- processClient.run(["codex-lb", "health", "--json"], timeout: NativeView.mutationTimeout) { [weak self] result in
425
- guard let self = self else { return }
449
+ guard ok else {
450
+ self.setBusy(false)
451
+ let detail = self.structuredPublicDetail(parsed, fallback: result.output)
452
+ self.cliProviderStatus.stringValue = "CLI provider was not confirmed · \(detail)"
453
+ self.renderCliConnectStages(
454
+ progress: 1,
455
+ configuration: "failed",
456
+ request: "not run",
457
+ response: "not received",
458
+ result: "Codex LB mode was not confirmed. Connection proof did not run.",
459
+ tone: .systemRed
460
+ )
461
+ return
462
+ }
426
463
  self.setBusy(false)
427
- let parsed = self.json(result.output)
428
- let ok = result.code == 0 && parsed?["ok"] as? Bool == true
429
- let status = parsed?["status"] as? String ?? (ok ? "verified" : "failed")
430
- _ = self.operations.update(snapshot, state: ok ? .succeeded : .failed, stage: "complete", progress: 1, summary: ok ? "CLI provider transport verified" : "CLI provider test needs action")
431
- self.cliProviderStatus.stringValue = ok
432
- ? "CLI provider transport verified (\(status)). Desktop routing and OAuth were not changed."
433
- : "CLI provider test failed (\(status)) · \(self.structuredPublicDetail(parsed, fallback: result.output))"
464
+ self.codexLbSelectedNow = true
465
+ self.desktopFullRoutingNow = false
466
+ self.openRouterSelectedNow = false
467
+ self.routerSelectedNow = false
468
+ ControlKit.setBadge(self.activeProviderBadge, text: "Codex LB · selected · connection proof running", tone: .busy)
469
+ self.cliProviderStatus.stringValue = "Codex LB mode selected · running the required one-request connection proof…"
470
+ self.renderCliConnectStages(
471
+ progress: 1,
472
+ configuration: "CLI provider selected",
473
+ request: "starting…",
474
+ response: "not received",
475
+ result: "Mode is selected. Connectivity remains unproved until a structured response is received.",
476
+ tone: .secondaryLabelColor
477
+ )
478
+ self.runConnectTest()
434
479
  }
435
480
  }
436
481
  @objc private func copyCliCommand() {
@@ -440,19 +485,6 @@ final class ProvidersViewController: NSViewController, ControlCenterPage, NSText
440
485
  ? "Copied CLI command: \(cliLaunchCommand)"
441
486
  : "Could not copy the CLI command. Select it above and copy manually."
442
487
  }
443
- private func refreshFastStatus() {
444
- if !busy { fastStatus.stringValue = "Codex Fast: checking the official service-tier setting…" }
445
- processClient.run(["fast-mode", "status", "--json"], timeout: NativeView.statusTimeout) { [weak self] result in
446
- guard let self = self else { return }
447
- guard result.code == 0, let json = self.json(result.output),
448
- let global = json["global"] as? [String: Any], let on = global["on"] as? Bool else {
449
- self.fastStatus.stringValue = "Codex Fast: unavailable — no state was assumed."
450
- return
451
- }
452
- let tier = global["service_tier"] as? String ?? (on ? "fast" : "default")
453
- self.fastStatus.stringValue = "Codex Fast: \(on ? "On" : "Off") · official service_tier=\(tier) · model and reasoning remain separate."
454
- }
455
- }
456
488
  @objc private func fastOn() { run(["fast-mode", "on", "--json"], title: "Codex Fast On", kind: "fast-mode-on", group: "codex-config", timeout: NativeView.statusTimeout) { [weak self] in self?.refreshFastStatus() } }
457
489
  @objc private func fastOff() { run(["fast-mode", "off", "--json"], title: "Codex Fast Off", kind: "fast-mode-off", group: "codex-config", timeout: NativeView.statusTimeout) { [weak self] in self?.refreshFastStatus() } }
458
490
  }