sneakoscope 8.1.2 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/README.md +96 -58
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/bin/fast-inline.js +5 -51
  5. package/dist/cli/command-manifest-lite.js +2 -1
  6. package/dist/cli/command-registry.js +2 -1
  7. package/dist/cli/global-mode-router.js +1 -1
  8. package/dist/cli/install-helpers-codex-lb-config.js +112 -914
  9. package/dist/cli/install-helpers-codex-lb-shared.js +3 -44
  10. package/dist/cli/install-helpers-install-support.js +4 -20
  11. package/dist/cli/install-helpers.js +36 -2716
  12. package/dist/cli/router.js +9 -9
  13. package/dist/commands/bridge-command-output.js +111 -0
  14. package/dist/commands/bridge.js +320 -0
  15. package/dist/commands/codex-app.js +39 -123
  16. package/dist/commands/doctor-helpers.js +380 -0
  17. package/dist/commands/doctor-profile.js +3 -0
  18. package/dist/commands/doctor.js +114 -873
  19. package/dist/commands/mad-sks.js +0 -4
  20. package/dist/config/skills-manifest.json +1 -1
  21. package/dist/core/agents/agent-effort-policy.js +11 -21
  22. package/dist/core/agents/agent-recursion-guard.js +26 -0
  23. package/dist/core/agents/agent-runner-codex-exec.js +7 -9
  24. package/dist/core/architecture-hardening/contracts/contracts.js +225 -161
  25. package/dist/core/architecture-hardening/state/state-service.js +49 -13
  26. package/dist/core/auto-review.js +15 -9
  27. package/dist/core/codex/codex-config-guard.js +8 -0
  28. package/dist/core/codex-adapter.js +8 -10
  29. package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -29
  30. package/dist/core/codex-app/codex-app-launcher.js +10 -12
  31. package/dist/core/codex-app/codex-app-restart.js +10 -12
  32. package/dist/core/codex-app/menubar/constants.js +2 -5
  33. package/dist/core/codex-app/menubar/global-install.js +3 -2
  34. package/dist/core/codex-app/menubar/installer/result.js +23 -0
  35. package/dist/core/codex-app/menubar/installer/runtime.js +28 -0
  36. package/dist/core/codex-app/menubar/installer.js +5 -96
  37. package/dist/core/codex-app/menubar/migration.js +1 -42
  38. package/dist/core/codex-app/openrouter-provider.js +0 -78
  39. package/dist/core/codex-app.js +97 -360
  40. package/dist/core/codex-control/codex-app-server-runtime-env.js +8 -28
  41. package/dist/core/codex-control/codex-current-image-path-real-probe.js +2 -3
  42. package/dist/core/codex-control/codex-current-web-search-probe.js +2 -3
  43. package/dist/core/codex-control/codex-sdk-adapter.js +5 -48
  44. package/dist/core/codex-control/codex-task-runner.js +16 -60
  45. package/dist/core/codex-control/desktop-bridge-launch-guard.js +227 -0
  46. package/dist/core/codex-exec-output-schema.js +11 -13
  47. package/dist/core/codex-lb/bridge-contracts.js +2 -0
  48. package/dist/core/codex-lb/bridge-runtime-validation/capability.js +104 -0
  49. package/dist/core/codex-lb/bridge-runtime-validation/catalog.js +52 -0
  50. package/dist/core/codex-lb/bridge-runtime-validation/shared.js +109 -0
  51. package/dist/core/codex-lb/bridge-runtime-validation/status.js +250 -0
  52. package/dist/core/codex-lb/bridge-runtime-validation.js +106 -0
  53. package/dist/core/codex-lb/capability-runner.js +505 -201
  54. package/dist/core/codex-lb/codex-lb-env.js +179 -12
  55. package/dist/core/codex-lb/combined-catalog/builder.js +86 -0
  56. package/dist/core/codex-lb/combined-catalog/contracts.js +5 -0
  57. package/dist/core/codex-lb/combined-catalog/normalize.js +170 -0
  58. package/dist/core/codex-lb/combined-catalog/persistence.js +207 -0
  59. package/dist/core/codex-lb/combined-catalog/shared.js +12 -0
  60. package/dist/core/codex-lb/combined-catalog/storage.js +171 -0
  61. package/dist/core/codex-lb/combined-catalog.js +12 -0
  62. package/dist/core/codex-lb/desktop-bridge/client.js +4 -1
  63. package/dist/core/codex-lb/desktop-bridge/header-policy.js +48 -63
  64. package/dist/core/codex-lb/desktop-bridge/http-forward.js +115 -83
  65. package/dist/core/codex-lb/desktop-bridge/launchd.js +20 -13
  66. package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +4 -1
  67. package/dist/core/codex-lb/desktop-bridge/security.js +381 -267
  68. package/dist/core/codex-lb/desktop-bridge/server.js +148 -19
  69. package/dist/core/codex-lb/desktop-bridge/state.js +56 -70
  70. package/dist/core/codex-lb/desktop-bridge/types.js +6 -1
  71. package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +281 -106
  72. package/dist/core/codex-lb/desktop-bridge-migration/historical-config.js +245 -0
  73. package/dist/core/codex-lb/desktop-bridge-migration/historical-toml.js +56 -0
  74. package/dist/core/codex-lb/desktop-bridge-migration/metadata.js +73 -0
  75. package/dist/core/codex-lb/desktop-bridge-migration/receipt.js +52 -0
  76. package/dist/core/codex-lb/desktop-bridge-migration/retired-runtime-cleanup.js +106 -0
  77. package/dist/core/codex-lb/desktop-bridge-migration/types.js +1 -0
  78. package/dist/core/codex-lb/desktop-bridge-migration.js +238 -0
  79. package/dist/core/codex-lb/desktop-controller-v3/catalog.js +257 -0
  80. package/dist/core/codex-lb/desktop-controller-v3/diagnostics.js +62 -0
  81. package/dist/core/codex-lb/desktop-controller-v3/lifecycle-commands.js +203 -0
  82. package/dist/core/codex-lb/desktop-controller-v3/live-probes.js +293 -0
  83. package/dist/core/codex-lb/desktop-controller-v3/preflight-probes.js +144 -0
  84. package/dist/core/codex-lb/desktop-controller-v3/provider-commands.js +182 -0
  85. package/dist/core/codex-lb/desktop-controller-v3/shared.js +279 -0
  86. package/dist/core/codex-lb/desktop-controller-v3/status.js +269 -0
  87. package/dist/core/codex-lb/desktop-controller-v3/types.js +1 -0
  88. package/dist/core/codex-lb/desktop-controller-v3/verification.js +89 -0
  89. package/dist/core/codex-lb/desktop-controller-v3.js +67 -0
  90. package/dist/core/codex-lb/desktop-controller.js +2 -1730
  91. package/dist/core/codex-lb/desktop-service.js +462 -627
  92. package/dist/core/codex-lb/migration-receipt.js +560 -118
  93. package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +37 -53
  94. package/dist/core/codex-lb/probes/bridge-probe.js +125 -64
  95. package/dist/core/codex-lb/probes/catalog-probe.js +36 -136
  96. package/dist/core/codex-lb/probes/computer-use-probe.js +63 -39
  97. package/dist/core/codex-lb/probes/image-generation-probe.js +98 -41
  98. package/dist/core/codex-lb/probes/probe-evidence.js +32 -33
  99. package/dist/core/codex-lb/probes/voice-realtime-probe.js +69 -43
  100. package/dist/core/codex-lb/provider-credentials/configuration.js +127 -0
  101. package/dist/core/codex-lb/provider-credentials/locks.js +11 -0
  102. package/dist/core/codex-lb/provider-credentials/private-snapshot.js +28 -0
  103. package/dist/core/codex-lb/provider-credentials/removal.js +33 -0
  104. package/dist/core/codex-lb/provider-credentials/resolution.js +59 -0
  105. package/dist/core/codex-lb/provider-credentials/runtime.js +55 -0
  106. package/dist/core/codex-lb/provider-credentials/types.js +1 -0
  107. package/dist/core/codex-lb/provider-credentials/validation-store.js +137 -0
  108. package/dist/core/codex-lb/provider-credentials.js +5 -0
  109. package/dist/core/codex-lb/provider-registry.js +323 -0
  110. package/dist/core/codex-lb/provider-route-policy.js +118 -0
  111. package/dist/core/codex-lb/request-route-resolver.js +172 -0
  112. package/dist/core/codex-lb/route-index.js +148 -0
  113. package/dist/core/codex-lb/trusted-deep-evidence.js +158 -286
  114. package/dist/core/commands/basic-cli.js +1 -1
  115. package/dist/core/commands/check-command.js +3 -10
  116. package/dist/core/commands/gate-result-contract.js +10 -14
  117. package/dist/core/commands/intent-normalization/normalizer.js +1 -1
  118. package/dist/core/commands/mad-sks-command.js +2 -6
  119. package/dist/core/commands/release-command.js +11 -1
  120. package/dist/core/commands/telegram-command.js +46 -6
  121. package/dist/core/doctor/doctor-readiness-matrix.js +9 -7
  122. package/dist/core/doctor/skill-legacy-surface.js +5 -5
  123. package/dist/core/evidence/v2/evidence-key.js +30 -3
  124. package/dist/core/feature-fixtures.js +8 -1
  125. package/dist/core/feature-registry.js +3 -2
  126. package/dist/core/hooks-runtime/stop-finalization.js +11 -1
  127. package/dist/core/hooks-runtime/subagent-context.js +15 -1
  128. package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +1 -1
  129. package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
  130. package/dist/core/hooks-runtime.js +73 -87
  131. package/dist/core/image-ux-review/imagegen-adapter.js +108 -94
  132. package/dist/core/image-ux-review/real-callout-extractor.js +144 -14
  133. package/dist/core/imagegen/desktop-bridge-imagegen-target.js +77 -0
  134. package/dist/core/imagegen/imagegen-capability.js +43 -151
  135. package/dist/core/init/skills/filesystem.js +89 -0
  136. package/dist/core/init/skills/inventory.js +97 -0
  137. package/dist/core/init/skills/manifest.js +151 -0
  138. package/dist/core/init/skills.js +5 -325
  139. package/dist/core/init.js +0 -63
  140. package/dist/core/install/installed-package-smoke.js +1 -1
  141. package/dist/core/managed-assets/managed-assets-manifest.js +0 -1
  142. package/dist/core/policy/latest-version-guidance.js +15 -2
  143. package/dist/core/preflight/parallel-preflight-engine.js +27 -51
  144. package/dist/core/provider/provider-badge.js +9 -4
  145. package/dist/core/provider/provider-context.js +57 -107
  146. package/dist/core/providers/openrouter/openrouter-account.js +3 -1
  147. package/dist/core/providers/openrouter/openrouter-secret-store.js +91 -22
  148. package/dist/core/release/desktop-bridge-release-evidence.js +457 -0
  149. package/dist/core/release/gate-manifest.js +0 -1
  150. package/dist/core/release/main-push-guard.js +13 -0
  151. package/dist/core/release/main-push-receipt.js +11 -0
  152. package/dist/core/release/physical-release-gates.js +664 -61
  153. package/dist/core/release/publish-preflight.js +3 -3
  154. package/dist/core/release/release-gate-batch-runner.js +19 -6
  155. package/dist/core/release/release-gate-dag.js +33 -6
  156. package/dist/core/release/release-gate-node.js +1 -3
  157. package/dist/core/release/release-gate-output-contract.js +55 -0
  158. package/dist/core/release/release-pack-contract.js +1 -1
  159. package/dist/core/release/release-pack-receipt.js +209 -8
  160. package/dist/core/release/release-real-contract.js +1 -1
  161. package/dist/core/release/stage-publish.js +106 -28
  162. package/dist/core/retention/temp-lease.js +204 -0
  163. package/dist/core/retention.js +18 -195
  164. package/dist/core/routes.js +1 -2
  165. package/dist/core/safety/intent-contract/intent-contract.js +3 -3
  166. package/dist/core/subagents/naruto-host-credentials.js +6 -1
  167. package/dist/core/subagents/official-subagent-config.js +27 -9
  168. package/dist/core/subagents/official-subagent-runner.js +14 -31
  169. package/dist/core/subagents/wave-lifecycle.js +36 -8
  170. package/dist/core/subagents/wave-parent-guidance.js +2 -1
  171. package/dist/core/telegram/doctor.js +2 -2
  172. package/dist/core/telegram/liveness.js +10 -4
  173. package/dist/core/triwiki/context-graph/compiler/index.js +18 -18
  174. package/dist/core/update/update-migration-state/fast-mode-config.js +172 -0
  175. package/dist/core/update/update-migration-state/session-state-split.js +247 -0
  176. package/dist/core/update/update-migration-state/simple-stages.js +46 -0
  177. package/dist/core/update/update-migration-state.js +4 -481
  178. package/dist/core/version.js +1 -1
  179. package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +28 -4
  180. package/dist/native/sks-menubar/Sources/OperationModels.swift +112 -2
  181. package/dist/native/sks-menubar/Sources/ProviderRouteExplanation.swift +21 -0
  182. package/dist/native/sks-menubar/Sources/ProvidersBridgeCatalog.swift +140 -0
  183. package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +107 -470
  184. package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +27 -197
  185. package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +335 -269
  186. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +233 -437
  187. package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +16 -7
  188. package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +39 -9
  189. package/dist/native/sks-menubar/Sources/TelegramSupport.swift +56 -0
  190. package/dist/scripts/canonical-test-runner.js +7 -1
  191. package/dist/scripts/check-runtime-schemas.js +7 -2
  192. package/dist/scripts/codex-sdk-real-smoke-check.js +3 -1
  193. package/dist/scripts/desktop-bridge-capabilities-check.js +123 -0
  194. package/dist/scripts/{codex-lb-desktop-bridge-latency-check.js → desktop-bridge-latency-check.js} +61 -16
  195. package/dist/scripts/desktop-bridge-real-evidence-check.js +64 -0
  196. package/dist/scripts/{codex-lb-desktop-bridge-check.js → desktop-bridge-transport-check.js} +92 -155
  197. package/dist/scripts/desktop-bridge-transport-client.js +116 -0
  198. package/dist/scripts/desktop-bridge-unification-check.js +276 -0
  199. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +12 -8
  200. package/dist/scripts/gate-policy-audit-check.js +52 -2
  201. package/dist/scripts/provider-badge-context-check.js +55 -12
  202. package/dist/scripts/publish-preflight.js +1 -2
  203. package/dist/scripts/release-affected-selector-check.js +1 -2
  204. package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
  205. package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
  206. package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -0
  207. package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
  208. package/dist/scripts/release-gate-batch-runner-check.js +9 -0
  209. package/dist/scripts/release-gate-dag-runner-check.js +6 -0
  210. package/dist/scripts/release-gate-dag-runner.js +4 -2
  211. package/dist/scripts/release-metadata-check.js +16 -3
  212. package/dist/scripts/release-pack-receipt.js +29 -6
  213. package/dist/scripts/release-physical-gates-check.js +39 -0
  214. package/dist/scripts/release-real-check.js +7 -5
  215. package/package.json +6 -8
  216. package/release-gates.v2.json +156 -157
  217. package/runtime-required-scripts.json +11 -11
  218. package/schemas/codex/desktop-bridge-status-v3.schema.json +286 -0
  219. package/schemas/codex/desktop-capabilities-v3.schema.json +198 -0
  220. package/schemas/release/release-gate-node.schema.json +2 -3
  221. package/dist/cli/codex-lb-setup-warning-output.js +0 -17
  222. package/dist/cli/install-helpers-codex-lb-chain.js +0 -529
  223. package/dist/commands/codex-lb.js +0 -1232
  224. package/dist/core/architecture-hardening/migration/migration.js +0 -111
  225. package/dist/core/codex-app/auxiliary-oauth-policy.js +0 -36
  226. package/dist/core/codex-app/catalog-compat/catalog-service.js +0 -104
  227. package/dist/core/codex-app/child-policy/child-policy.js +0 -35
  228. package/dist/core/codex-app/desktop-routing-snapshot.js +0 -233
  229. package/dist/core/codex-app/glm-model-profile.js +0 -1
  230. package/dist/core/codex-app/glm-profile-installer.js +0 -191
  231. package/dist/core/codex-app/glm-profile-schema.js +0 -42
  232. package/dist/core/codex-app/multi-provider-router.js +0 -391
  233. package/dist/core/codex-app/openrouter-activate.js +0 -405
  234. package/dist/core/codex-app/openrouter-model-catalog.js +0 -217
  235. package/dist/core/codex-app/provider-child-policy.js +0 -64
  236. package/dist/core/codex-app/provider-mode.js +0 -91
  237. package/dist/core/codex-app/provider-session-policy.js +0 -85
  238. package/dist/core/codex-app/session-policy/session-pinning.js +0 -68
  239. package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -319
  240. package/dist/core/codex-lb/codex-lb-setup.js +0 -293
  241. package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -456
  242. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +0 -290
  243. package/dist/core/codex-lb/desktop-center-credentials.js +0 -1083
  244. package/dist/core/codex-lb/desktop-mode.js +0 -32
  245. package/dist/core/codex-lb/desktop-real-evidence.js +0 -168
  246. package/dist/core/codex-lb/legacy-migration.js +0 -576
  247. package/dist/core/codex-lb/native-openai-transport/transport.js +0 -68
  248. package/dist/core/codex-lb/provider-routing/provider-router.js +0 -58
  249. package/dist/core/codex-lb/routing-truth.js +0 -327
  250. package/dist/core/imagegen/codex-lb-imagegen-target.js +0 -92
  251. package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +0 -118
  252. package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +0 -17
  253. package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +0 -331
  254. package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +0 -260
  255. package/dist/scripts/codex-lb-catalog-passthrough-check.js +0 -120
  256. package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +0 -169
  257. package/dist/scripts/codex-lb-desktop-capabilities-check.js +0 -287
  258. package/dist/scripts/codex-lb-desktop-real-evidence-check.js +0 -123
  259. package/dist/scripts/codex-lb-fast-mode-truth-check.js +0 -114
  260. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +0 -152
  261. package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +0 -231
@@ -9,30 +9,27 @@ struct ProviderActionInventoryItem: Equatable {
9
9
  let recoveryAction: String
10
10
  }
11
11
 
12
+ enum ProviderReconnectLabel {
13
+ static let codexLb = "Reconnect Codex LB credential…"
14
+ static let openRouter = "Reconnect OpenRouter credential…"
15
+ static let codexSignIn = "Open Codex sign-in…"
16
+ }
17
+
12
18
  enum ProviderActionInventory {
13
19
  static let items: [ProviderActionInventoryItem] = [
14
- .init(id: "sks-provider-desktop-bridge-mode", handler: "enableDesktopFull", backend: "sks codex-lb use-desktop-full", loadingState: "routing", successState: "four-stage receipt", recoveryAction: "review provider stages"),
15
- .init(id: "sks-provider-verify-capabilities", handler: "verifyDesktopCapabilities", backend: "sks codex-lb capabilities", loadingState: "verifying", successState: "trusted capability matrix", recoveryAction: "retry verification"),
16
- .init(id: "sks-provider-use-chatgpt-oauth", handler: "disableDesktopRouting", backend: "sks codex-lb disable", loadingState: "routing", successState: "four-stage receipt", recoveryAction: "open provider settings"),
17
- .init(id: "sks-provider-reconnect-codex-lb", handler: "setDomainAndKey", backend: "sks codex-lb setup", loadingState: "saving", successState: "Keychain confirmed", recoveryAction: "repair Keychain and reconnect"),
18
- .init(id: "sks-provider-run-connect-test", handler: "testConnection", backend: "sks codex-lb connect-test", loadingState: "testing", successState: "bounded response proof", recoveryAction: "retry connect test"),
19
- .init(id: "sks-provider-copy-cli-command", handler: "copyCliCommand", backend: "local pasteboard", loadingState: "copying", successState: "command copied", recoveryAction: "copy again"),
20
- .init(id: "sks-provider-activate-codex-lb", handler: "useCliProvider", backend: "sks codex-lb use-cli", loadingState: "applying", successState: "connection proof", recoveryAction: "review Credentials Connection Proof"),
21
- .init(id: "sks-provider-reconnect-openrouter", handler: "saveOpenRouterKey", backend: "sks codex-app set-openrouter-key", loadingState: "saving", successState: "Keychain confirmed", recoveryAction: "repair Keychain and reconnect"),
22
- .init(id: "sks-provider-save-openrouter-key", handler: "saveOpenRouterKey", backend: "sks codex-app set-openrouter-key", loadingState: "saving", successState: "Keychain confirmed", recoveryAction: "repair Keychain and reconnect"),
23
- .init(id: "sks-provider-refresh-openrouter-catalog", handler: "refreshOpenRouterModelsAction", backend: "sks codex-app openrouter-models", loadingState: "refreshing", successState: "validated catalog", recoveryAction: "reconnect then refresh"),
24
- .init(id: "sks-provider-test-openrouter", handler: "testOpenRouterConnection", backend: "sks codex-app openrouter-test", loadingState: "testing", successState: "model verified", recoveryAction: "choose a validated model"),
25
- .init(id: "sks-provider-activate-openrouter", handler: "useOpenRouter", backend: "sks codex-app use-openrouter", loadingState: "applying", successState: "four-stage receipt", recoveryAction: "restore previous provider"),
26
- .init(id: "sks-provider-restore-previous", handler: "restorePreviousDesktopRouting", backend: "sks codex-app restore-desktop-routing", loadingState: "restoring", successState: "snapshot restored", recoveryAction: "review restore blocker"),
27
- .init(id: "sks-provider-open-codex-signin", handler: "openCodexSignInAction", backend: "NSWorkspace Codex launch", loadingState: "opening", successState: "Codex opened", recoveryAction: "install or open Codex manually"),
28
- .init(id: "sks-provider-fast-on", handler: "fastOn", backend: "sks fast-mode on", loadingState: "applying", successState: "service tier verified", recoveryAction: "refresh status"),
29
- .init(id: "sks-provider-fast-off", handler: "fastOff", backend: "sks fast-mode off", loadingState: "applying", successState: "service tier verified", recoveryAction: "refresh status"),
30
- .init(id: "sks-provider-refresh-router", handler: "refreshMultiProviderRouterAction", backend: "sks codex-app router-status", loadingState: "refreshing", successState: "router catalog loaded", recoveryAction: "retry refresh"),
31
- .init(id: "sks-provider-test-router", handler: "testMultiProviderRouter", backend: "sks codex-app router-test", loadingState: "testing", successState: "router verified", recoveryAction: "review router blocker"),
32
- .init(id: "sks-provider-configure-router", handler: "useMultiProviderRouter", backend: "sks codex-app use-router", loadingState: "applying", successState: "router configured", recoveryAction: "restore provider settings"),
33
- .init(id: "sks-provider-refresh-role-models", handler: "refreshRoleModelsAction", backend: "sks codex-app role-models", loadingState: "refreshing", successState: "role settings loaded", recoveryAction: "retry refresh"),
34
- .init(id: "sks-provider-save-role-model", handler: "saveRoleModel", backend: "sks codex-app set-role-model", loadingState: "saving", successState: "role override saved", recoveryAction: "retry or reset"),
35
- .init(id: "sks-provider-reset-role-model", handler: "resetRoleModel", backend: "sks codex-app reset-role-model", loadingState: "resetting", successState: "role override reset", recoveryAction: "retry reset")
20
+ .init(id: "sks-provider-bridge-repair", handler: "repairDesktopBridge", backend: "sks bridge repair --json", loadingState: "repairing", successState: "bridge receipt", recoveryAction: "inspect bridge logs"),
21
+ .init(id: "sks-provider-verify-transport", handler: "verifyTransport", backend: "sks bridge verify --level transport --json", loadingState: "verifying", successState: "v3 report", recoveryAction: "retry transport verification"),
22
+ .init(id: "sks-provider-verify-deep", handler: "verifyDeep", backend: "sks bridge verify --level deep --json", loadingState: "verifying", successState: "v3 report", recoveryAction: "review scoped findings"),
23
+ .init(id: "sks-provider-reconnect-codex-lb", handler: "configureCodexLbProfile", backend: "sks bridge provider configure codex-lb", loadingState: "saving", successState: "profile configured", recoveryAction: "repair Keychain and reconnect"),
24
+ .init(id: "sks-provider-validate-codex-lb", handler: "validateCodexLbProfile", backend: "sks bridge provider validate codex-lb --json", loadingState: "validating", successState: "provider report", recoveryAction: "rotate credential"),
25
+ .init(id: "sks-provider-toggle-codex-lb", handler: "toggleCodexLbProfile", backend: "sks bridge provider enable or disable codex-lb", loadingState: "updating profile", successState: "profile state updated", recoveryAction: "retry provider update"),
26
+ .init(id: "sks-provider-reconnect-openrouter", handler: "configureOpenRouterProfile", backend: "sks bridge provider configure openrouter", loadingState: "saving", successState: "profile configured", recoveryAction: "repair Keychain and reconnect"),
27
+ .init(id: "sks-provider-validate-openrouter", handler: "validateOpenRouterProfile", backend: "sks bridge provider validate openrouter --json", loadingState: "validating", successState: "provider report", recoveryAction: "rotate credential"),
28
+ .init(id: "sks-provider-toggle-openrouter", handler: "toggleOpenRouterProfile", backend: "sks bridge provider enable or disable openrouter", loadingState: "updating profile", successState: "profile state updated", recoveryAction: "retry provider update"),
29
+ .init(id: "sks-provider-open-codex-sign-in", handler: "openCodexSignInAction", backend: "open Codex application", loadingState: "opening Codex", successState: "Codex sign-in opened", recoveryAction: "install or open Codex manually"),
30
+ .init(id: "sks-provider-refresh-catalog", handler: "refreshCombinedCatalog", backend: "sks bridge catalog sync --json", loadingState: "syncing", successState: "combined catalog report", recoveryAction: "retry catalog sync"),
31
+ .init(id: "sks-provider-open-catalog-report", handler: "openCatalogReport", backend: "sks bridge catalog status --json", loadingState: "loading report", successState: "combined catalog report", recoveryAction: "retry catalog status"),
32
+ .init(id: "sks-provider-route-explain", handler: "explainRoute", backend: "sks bridge route explain --json", loadingState: "resolving", successState: "explicit route shown", recoveryAction: "refresh catalog or choose supported model")
36
33
  ]
37
34
 
38
35
  static func item(_ id: String) -> ProviderActionInventoryItem? { items.first { $0.id == id } }
@@ -49,136 +46,6 @@ extension ProvidersViewController {
49
46
  button.setAccessibilityHelp("Loading: \(item.loadingState). Success: \(item.successState). Recovery: \(item.recoveryAction).")
50
47
  }
51
48
 
52
- func renderLatestProviderApply() {
53
- guard let projection = operations.latestSnapshot()?.providerApply else {
54
- providerApplyStatus.stringValue = "Provider apply stages: no operation receipt yet. Existing sessions remain unchanged."
55
- providerApplyStatus.textColor = .secondaryLabelColor
56
- return
57
- }
58
- let rows = projection.stages.map { receipt in
59
- let reason = receipt.reasonCode.map { " · \($0)" } ?? ""
60
- return "\(receipt.stage.rawValue): \(receipt.status.rawValue)\(reason)"
61
- }
62
- let existing = projection.existingSession.map { "\($0.mode) / \($0.model)" } ?? "none"
63
- let next = "\(projection.newSessionDefault.mode) / \(projection.newSessionDefault.model)"
64
- providerApplyStatus.stringValue = rows.joined(separator: " · ") + "\nExisting session: \(existing) · New-session default: \(next)"
65
- providerApplyStatus.textColor = projection.failedStage == nil ? .secondaryLabelColor : .systemOrange
66
- }
67
-
68
- func currentProviderSessionCopy() -> ProviderSessionCopy? {
69
- if openRouterSelectedNow {
70
- return ProviderSessionCopy(mode: "openrouter", model: openRouterActiveModel.isEmpty ? "catalog-selection-required" : openRouterActiveModel, catalogVersion: "last-verified")
71
- }
72
- if desktopFullRoutingNow || codexLbSelectedNow {
73
- return ProviderSessionCopy(mode: "codex-lb", model: routerActiveModel.isEmpty ? "catalog-selection-required" : routerActiveModel, catalogVersion: "last-verified")
74
- }
75
- if chatgptOauthPresentNow {
76
- return ProviderSessionCopy(mode: "chatgpt-oauth", model: "native-catalog-selection", catalogVersion: "native-last-verified")
77
- }
78
- return nil
79
- }
80
-
81
- func beginProviderApply(
82
- kind: String,
83
- summary: String,
84
- mode: String,
85
- model: String,
86
- catalogVersion: String = "pending-verification"
87
- ) -> OperationSnapshot? {
88
- operations.begin(
89
- kind: kind,
90
- mutationGroup: "codex-config",
91
- summary: summary,
92
- providerApply: .initial(
93
- existingSession: currentProviderSessionCopy(),
94
- newSessionDefault: ProviderSessionCopy(mode: mode, model: model, catalogVersion: catalogVersion)
95
- )
96
- )
97
- }
98
-
99
- func recordProviderApplyResult(
100
- _ snapshot: OperationSnapshot,
101
- json: [String: Any]?,
102
- configurationSaved: Bool,
103
- proxyApplied: Bool
104
- ) -> OperationSnapshot {
105
- var current = snapshot
106
- let catalog = (json?["catalog_sync"] as? [String: Any]) ?? (json?["model_catalog_sync"] as? [String: Any])
107
- let catalogReady = catalog?["status"] as? String == "ready" || json?["catalog_refreshed"] as? Bool == true
108
- let restart = json?["restart_performed"] as? Bool == true
109
- || json?["new_session_ready"] as? Bool == true
110
- || (json?["restart_app"] as? [String: Any])?["ok"] as? Bool == true
111
- let outcomes: [(ProviderApplyStageName, Bool, String)] = [
112
- (.configSaved, configurationSaved, "provider_config_not_confirmed"),
113
- (.proxyApplied, proxyApplied, "provider_proxy_not_confirmed"),
114
- (.catalogRefreshed, catalogReady, "provider_catalog_not_verified"),
115
- (.newSessionReady, restart, "provider_new_session_not_verified")
116
- ]
117
- for (stage, succeeded, reason) in outcomes {
118
- do {
119
- current = try operations.recordProviderApplyStage(current, stage: stage, status: .running)
120
- current = try operations.recordProviderApplyStage(
121
- current,
122
- stage: stage,
123
- status: succeeded ? .succeeded : .failed,
124
- reasonCode: succeeded ? nil : reason
125
- )
126
- } catch {
127
- providerApplyStatus.stringValue = "Provider stage receipt rejected · \(stage.rawValue). Recovery: refresh status and retry explicitly."
128
- providerApplyStatus.textColor = .systemRed
129
- break
130
- }
131
- if !succeeded { break }
132
- }
133
- renderLatestProviderApply()
134
- return current
135
- }
136
-
137
- func capabilityCompatibilityDetail(
138
- definition: (label: String, keys: [String]),
139
- payload: [String: Any],
140
- state: String,
141
- trustVerified: Bool
142
- ) -> String {
143
- let evidence = definition.keys.compactMap { payload[$0] as? [String: Any] }.first
144
- let route = (evidence?["route"] as? String) ?? (evidence?["credential_path"] as? String)
145
- let routeText: String
146
- switch route {
147
- case "proxy", "proxy-direct", "direct": routeText = "direct proxy"
148
- case "oauth", "oauth-auxiliary", "oauth_auxiliary": routeText = "OAuth auxiliary"
149
- default: routeText = "route unverified"
150
- }
151
- let oauthRequired = evidence?["oauth_required"] as? Bool
152
- let oauthText = oauthRequired == true
153
- ? (chatgptOauthPresentNow ? "OAuth connected" : "OAuth connection required")
154
- : oauthRequired == false ? "OAuth not required" : "OAuth requirement unverified"
155
- let reason = (evidence?["reason"] as? String)
156
- ?? (evidence?["blocker"] as? String)
157
- ?? (evidence?["error"] as? String)
158
- ?? (trustVerified ? "no reported degradation" : "trusted protocol evidence missing")
159
- let recovery = (evidence?["recovery_action"] as? String)
160
- ?? (oauthRequired == true && !chatgptOauthPresentNow ? "Open Codex sign-in" : "Verify Capabilities")
161
- return "\(state) · \(routeText) · \(oauthText) · reason: \(reason) · recovery: \(recovery)"
162
- }
163
-
164
- func renderCatalogSyncStatus(_ json: [String: Any]) {
165
- let catalog = (json["catalog_sync"] as? [String: Any])
166
- ?? (json["model_catalog_sync"] as? [String: Any])
167
- guard let catalog = catalog else {
168
- catalogSyncStatus.stringValue = "Native Codex catalog sync: state not reported · last verified catalog was not assumed. Retry provider status or Verify Capabilities."
169
- catalogSyncStatus.textColor = .systemOrange
170
- return
171
- }
172
- let state = (catalog["status"] as? String) ?? "unverified"
173
- let updatedAt = (catalog["updated_at"] as? String) ?? "unknown time"
174
- let changed = catalog["changed"] as? Bool
175
- let failure = (catalog["failure_reason"] as? String) ?? (catalog["error"] as? String)
176
- let changeText = changed == true ? "changed" : changed == false ? "unchanged" : "change unknown"
177
- let failureText = failure.map { " · reason: \($0) · recovery: retry catalog sync" } ?? ""
178
- catalogSyncStatus.stringValue = "Native Codex catalog sync: \(state) · \(changeText) · last \(updatedAt)\(failureText)"
179
- catalogSyncStatus.textColor = failure == nil && state == "ready" ? .secondaryLabelColor : .systemOrange
180
- }
181
-
182
49
  func refreshCredentialHealth() {
183
50
  renderCredentialState(keychainStore.statusNonInteractive(.codexLbApiKey), label: codexLbKeychainStatus, name: "Codex LB")
184
51
  renderCredentialState(keychainStore.statusNonInteractive(.openRouterApiKey), label: openRouterKeychainStatus, name: "OpenRouter")
@@ -198,20 +65,24 @@ extension ProvidersViewController {
198
65
  }
199
66
  }
200
67
 
201
- func promptForSecretKey(window: NSWindow, sheetTitle: String, sheetMessage: String, placeholder: String, args: [String], kind: String, title: String, credential: SKSKeychainCredential, statusLabel: NSTextField, successSummary: String, failSummary: String, codePrefix: String = "E-LB") {
68
+ func promptForSecretKey(window: NSWindow, sheetTitle: String, sheetMessage: String, placeholder: String, args: [String], kind: String, title: String, credential: SKSKeychainCredential, statusLabel: NSTextField, successSummary: String, failSummary: String, codePrefix: String = "E-LB", providerId: String? = nil) {
202
69
  AlertFactory.textSheet(window: window, title: sheetTitle, message: sheetMessage, secure: true, placeholder: placeholder) { [weak self] key in
203
70
  guard let self = self, let key = key else { return }
204
- guard !self.busy else { statusLabel.stringValue = "Another provider action is already running."; return }
71
+ if let providerId = providerId, self.providerActionInFlight.contains(providerId) {
72
+ statusLabel.stringValue = "That provider already has an operation in progress."
73
+ return
74
+ }
75
+ guard providerId != nil || !self.busy else { statusLabel.stringValue = "Another provider action is already running."; return }
205
76
  guard let snapshot = self.operations.begin(kind: kind, mutationGroup: "codex-config", summary: title) else {
206
77
  statusLabel.stringValue = "Another guarded mutation is already running. Wait or open Diagnostics."
207
78
  return
208
79
  }
209
- self.setBusy(true)
80
+ if let providerId = providerId { self.setProviderActionBusy(providerId, true) } else { self.setBusy(true) }
210
81
  statusLabel.stringValue = "\(title)…"
211
82
  _ = self.operations.update(snapshot, state: .running, stage: "running", progress: nil, summary: title)
212
83
  self.processClient.run(args, stdin: key + "\n", timeout: NativeView.mutationTimeout) { [weak self] result in
213
84
  guard let self = self else { return }
214
- self.setBusy(false)
85
+ if let providerId = providerId { self.setProviderActionBusy(providerId, false) } else { self.setBusy(false) }
215
86
  let parsed = self.json(result.output)
216
87
  let configurationSaved = result.code == 0 && parsed?["ok"] as? Bool == true
217
88
  let keychainWrite = configurationSaved
@@ -259,45 +130,4 @@ extension ProvidersViewController {
259
130
  }
260
131
  }
261
132
 
262
- func performDesktopRouting(_ args: [String], title: String, kind: String, expectedMode: String) {
263
- guard !busy else { providerStatus.stringValue = "Another provider action is already running."; return }
264
- let targetMode = expectedMode == "disabled" ? "chatgpt-oauth" : "codex-lb"
265
- let targetModel = targetMode == "chatgpt-oauth" ? "native-catalog-selection" : "catalog-selection-required"
266
- guard let snapshot = beginProviderApply(kind: kind, summary: title, mode: targetMode, model: targetModel) else {
267
- providerStatus.stringValue = "Another guarded mutation is already running. Wait or open Diagnostics."
268
- return
269
- }
270
- setBusy(true)
271
- providerStatus.stringValue = "\(title)…"
272
- let running = operations.update(snapshot, state: .running, stage: "routing", progress: nil, summary: title)
273
- processClient.run(args, timeout: NativeView.mutationTimeout) { [weak self] result in
274
- guard let self = self else { return }
275
- self.setBusy(false)
276
- let parsed = self.json(result.output)
277
- let routing = parsed.map(ProviderRoutingTruth.snapshot(from:))
278
- let mode = routing?.mode
279
- let oauthPreserved = routing.flatMap { $0.oauthPreservedFlag }
280
- let routeConfirmed = result.code == 0 && parsed?["ok"] as? Bool == true && mode == expectedMode && oauthPreserved != false
281
- let configSaved = parsed?["config_committed"] as? Bool == true || parsed?["config_applied"] as? Bool == true
282
- let applied = self.recordProviderApplyResult(running, json: parsed, configurationSaved: configSaved, proxyApplied: routeConfirmed)
283
- let fullyApplied = applied.providerApply?.allSucceeded == true
284
- guard routeConfirmed else {
285
- self.providerStatus.stringValue = "\(title) was not confirmed · \(self.structuredPublicDetail(parsed, fallback: result.output)) No routing or OAuth change was assumed."
286
- return
287
- }
288
- let bridgeSelected = expectedMode == "desktop-native-bridge"
289
- self.desktopFullRoutingNow = false
290
- self.codexLbSelectedNow = false
291
- self.codexLbProvedNow = false
292
- self.chatgptOauthPresentNow = routing?.chatgptOauthPresent ?? self.chatgptOauthPresentNow
293
- self.renderActiveProviderSummary()
294
- if bridgeSelected { self.renderMeasuredRoutingBadge(nil, routeExpected: true) }
295
- self.providerStatus.stringValue = fullyApplied
296
- ? (bridgeSelected
297
- ? "Desktop Bridge Mode applied · ChatGPT sign-in preserved · all four local stages confirmed."
298
- : "ChatGPT OAuth mode applied · all four local stages confirmed.")
299
- : "Routing changed, but one or more apply stages remain unverified. Review Provider Apply Stages before starting new sessions."
300
- self.refresh()
301
- }
302
- }
303
133
  }