sneakoscope 7.0.0 → 7.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. package/README.md +7 -5
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/bin/sks-dispatch.js +0 -3
  5. package/dist/cli/command-registry.js +0 -2
  6. package/dist/cli/install-helpers-codex-lb-chain.js +24 -2
  7. package/dist/cli/install-helpers-codex-lb-config.js +0 -7
  8. package/dist/cli/install-helpers-codex-lb-selftest-chain.js +0 -3
  9. package/dist/cli/install-helpers-codex-lb-selftest.js +0 -17
  10. package/dist/cli/install-helpers.js +81 -96
  11. package/dist/cli/router.js +0 -22
  12. package/dist/commands/codex-lb.js +176 -22
  13. package/dist/commands/codex.js +3 -8
  14. package/dist/commands/doctor.js +4 -14
  15. package/dist/commands/perf.js +5 -1
  16. package/dist/commands/zellij-slot-column-anchor.js +0 -2
  17. package/dist/commands/zellij-slot-pane.js +0 -7
  18. package/dist/commands/zellij.js +0 -2
  19. package/dist/config/skills-manifest.json +52 -52
  20. package/dist/core/agent-bridge/agent-manifest.js +192 -1
  21. package/dist/core/agent-bridge/agent-mode.js +0 -5
  22. package/dist/core/agent-bridge/host-capability-policy.js +189 -0
  23. package/dist/core/agent-bridge/host-capability-runtime.js +1395 -0
  24. package/dist/core/agent-bridge/mcp-server.js +1 -11
  25. package/dist/core/agents/agent-effort-policy.js +0 -3
  26. package/dist/core/agents/agent-orchestrator.js +0 -4
  27. package/dist/core/agents/agent-proof-evidence.js +0 -2
  28. package/dist/core/agents/agent-runner-ollama.js +0 -3
  29. package/dist/core/agents/agent-scheduler.js +0 -5
  30. package/dist/core/agents/native-cli-worker-runtime.js +5 -17
  31. package/dist/core/agents/work-partition/repo-inventory.js +0 -2
  32. package/dist/core/auto-review.js +0 -13
  33. package/dist/core/bench.js +0 -14
  34. package/dist/core/code-structure.js +0 -3
  35. package/dist/core/codex/agent-config-file-repair.js +0 -8
  36. package/dist/core/codex/codex-cli-update.js +122 -20
  37. package/dist/core/codex/codex-config-eperm-repair.js +0 -4
  38. package/dist/core/codex/codex-config-guard.js +0 -3
  39. package/dist/core/codex/codex-config-readability.js +0 -13
  40. package/dist/core/codex/codex-project-config-policy.js +0 -33
  41. package/dist/core/codex/official-goal-mode.js +0 -2
  42. package/dist/core/codex-app/codex-app-fast-ui-repair.js +5 -7
  43. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +44 -7
  44. package/dist/core/codex-app/sks-menubar.js +0 -1
  45. package/dist/core/codex-app.js +0 -9
  46. package/dist/core/codex-compat/codex-hook-output-builders.js +9 -1
  47. package/dist/core/codex-compat/codex-hook-output-normalizer.js +1 -1
  48. package/dist/core/codex-compat/codex-hook-semantic-validator.js +3 -2
  49. package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -2
  50. package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -3
  51. package/dist/core/codex-control/codex-reliability-shield.js +0 -8
  52. package/dist/core/codex-control/codex-sdk-adapter.js +0 -3
  53. package/dist/core/codex-control/codex-sdk-config-policy.js +0 -2
  54. package/dist/core/codex-control/codex-sdk-env-policy.js +61 -16
  55. package/dist/core/codex-control/codex-task-runner.js +0 -7
  56. package/dist/core/codex-control/codex-thread-registry.js +0 -4
  57. package/dist/core/codex-lb/codex-lb-env.js +118 -20
  58. package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -4
  59. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +1 -1
  60. package/dist/core/codex-model-guard.js +0 -14
  61. package/dist/core/codex-native/codex-native-feature-broker.js +67 -22
  62. package/dist/core/codex-native/codex-native-interop-policy.js +81 -9
  63. package/dist/core/codex-native/confined-report-writer.js +21 -0
  64. package/dist/core/codex-native/core-skill-integrity.js +169 -20
  65. package/dist/core/codex-native/project-skill-dedupe.js +55 -13
  66. package/dist/core/codex-native/skill-registry-ledger.js +137 -16
  67. package/dist/core/codex-native/sks-skill-paths.js +185 -0
  68. package/dist/core/codex-runtime/codex-desktop-config-policy.js +0 -2
  69. package/dist/core/commands/agent-bridge-command.js +28 -8
  70. package/dist/core/commands/basic-cli.js +67 -26
  71. package/dist/core/commands/bench-command.js +5 -1
  72. package/dist/core/commands/command-utils.js +0 -5
  73. package/dist/core/commands/image-ux-review-command.js +0 -9
  74. package/dist/core/commands/mad-sks-command.js +0 -38
  75. package/dist/core/commands/naruto-command.js +69 -17
  76. package/dist/core/commands/ppt-command.js +0 -9
  77. package/dist/core/commands/run-command.js +8 -2
  78. package/dist/core/commands/seo-command.js +0 -6
  79. package/dist/core/commands/wiki-command.js +0 -14
  80. package/dist/core/computer-use-live-evidence.js +0 -5
  81. package/dist/core/config/secret-preservation.js +0 -11
  82. package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +0 -2
  83. package/dist/core/daemon/sksd-hook-daemon.js +1 -29
  84. package/dist/core/daemon/sksd-hook-dispatch.js +0 -17
  85. package/dist/core/db-safety.js +0 -7
  86. package/dist/core/doctor/browser-use-repair.js +0 -2
  87. package/dist/core/doctor/doctor-codex-startup-repair.js +0 -3
  88. package/dist/core/doctor/doctor-readiness-matrix.js +12 -0
  89. package/dist/core/doctor/doctor-skill-reconcile.js +32 -0
  90. package/dist/core/doctor/imagegen-repair.js +0 -2
  91. package/dist/core/doctor/mcp-transport-collision-repair.js +0 -3
  92. package/dist/core/doctor/retired-managed-residue-private.js +0 -1
  93. package/dist/core/doctor/supabase-mcp-repair.js +0 -11
  94. package/dist/core/feature-fixture-executor.js +0 -48
  95. package/dist/core/feature-fixtures.js +0 -5
  96. package/dist/core/fsx.js +11 -12
  97. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +0 -5
  98. package/dist/core/hooks-runtime/hook-context.js +202 -0
  99. package/dist/core/hooks-runtime/hook-io.js +1 -12
  100. package/dist/core/hooks-runtime/light-turn.js +0 -2
  101. package/dist/core/hooks-runtime/naruto-decision-gate.js +4 -1
  102. package/dist/core/hooks-runtime/naruto-terminal-finalization.js +91 -0
  103. package/dist/core/hooks-runtime/official-subagent-lifecycle.js +370 -0
  104. package/dist/core/hooks-runtime/standalone-parent-host-capability.js +98 -0
  105. package/dist/core/hooks-runtime/subagent-context.js +59 -0
  106. package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +29 -0
  107. package/dist/core/hooks-runtime/subagent-skill-availability-evidence.js +195 -0
  108. package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +316 -0
  109. package/dist/core/hooks-runtime/subagent-skill-availability.js +217 -0
  110. package/dist/core/hooks-runtime.js +259 -535
  111. package/dist/core/image-ux-review/codex-app-generated-image-discovery.js +0 -17
  112. package/dist/core/image-ux-review/imagegen-adapter.js +0 -14
  113. package/dist/core/imagegen/imagegen-auth-readiness.js +0 -9
  114. package/dist/core/imagegen/imagegen-capability.js +0 -3
  115. package/dist/core/init/managed-skill-install.js +42 -0
  116. package/dist/core/init/skills.js +247 -74
  117. package/dist/core/init.js +15 -40
  118. package/dist/core/lean-engineering-policy.js +0 -2
  119. package/dist/core/locks/file-lock.js +0 -21
  120. package/dist/core/loops/loop-planner.js +0 -6
  121. package/dist/core/loops/loop-runtime.js +0 -1
  122. package/dist/core/loops/loop-worker-runtime.js +0 -19
  123. package/dist/core/mad-sks/executors/db-write-executor.js +0 -4
  124. package/dist/core/mad-sks/executors/executor-base.js +0 -10
  125. package/dist/core/mad-sks/immutable-harness-guard.js +0 -5
  126. package/dist/core/mad-sks/sql-plane/coordinator.js +0 -5
  127. package/dist/core/mad-sks/sql-plane/ledger.js +0 -4
  128. package/dist/core/mad-sks/sql-plane/lock.js +0 -4
  129. package/dist/core/mad-sks/sql-plane/mcp-executor.js +0 -9
  130. package/dist/core/mad-sks/sql-plane/policy-resolver.js +0 -2
  131. package/dist/core/mad-sks/sql-plane/postconditions.js +0 -4
  132. package/dist/core/mad-sks/sql-plane/recovery.js +0 -2
  133. package/dist/core/mad-sks/sql-plane/runtime-profile.js +0 -8
  134. package/dist/core/managed-assets/managed-assets-manifest.js +1 -7
  135. package/dist/core/mcp-config/health-check.js +10 -3
  136. package/dist/core/migration/migration-transaction-journal.js +0 -8
  137. package/dist/core/mission.js +74 -6
  138. package/dist/core/naruto/naruto-active-pool.js +0 -2
  139. package/dist/core/naruto/naruto-concurrency-governor.js +0 -1
  140. package/dist/core/naruto/naruto-real-write-proof.js +0 -4
  141. package/dist/core/naruto/naruto-write-e2e.js +0 -1
  142. package/dist/core/perf/perf-budget.js +0 -5
  143. package/dist/core/permission-gates.js +0 -2
  144. package/dist/core/pipeline-internals/runtime-core.js +15 -5
  145. package/dist/core/pipeline-internals/runtime-gates.js +0 -12
  146. package/dist/core/preflight/parallel-preflight-engine.js +0 -11
  147. package/dist/core/proof/evidence-collector.js +0 -2
  148. package/dist/core/proof/route-finalizer.js +0 -1
  149. package/dist/core/proof/selftest-proof-fixtures.js +0 -5
  150. package/dist/core/providers/glm/bench/glm-benchmark-runner.js +0 -2
  151. package/dist/core/providers/glm/glm-request-cache.js +0 -3
  152. package/dist/core/providers/glm/naruto/glm-naruto-command.js +0 -1
  153. package/dist/core/providers/glm/naruto/glm-naruto-decomposer.js +0 -1
  154. package/dist/core/providers/glm/naruto/glm-naruto-orchestrator.js +0 -6
  155. package/dist/core/providers/glm/naruto/glm-naruto-trace.js +0 -1
  156. package/dist/core/providers/glm/naruto/glm-naruto-worker-pool.js +0 -1
  157. package/dist/core/providers/glm/naruto/glm-naruto-worktree.js +0 -1
  158. package/dist/core/providers/openrouter/openrouter-secret-store.js +0 -1
  159. package/dist/core/providers/openrouter/openrouter-stream.js +0 -2
  160. package/dist/core/questions.js +3 -3
  161. package/dist/core/release/gate-manifest.js +0 -5
  162. package/dist/core/release/package-size-budget.js +1 -1
  163. package/dist/core/release/release-gate-batch-runner.js +11 -2
  164. package/dist/core/release/release-gate-cache-v2.js +0 -4
  165. package/dist/core/release/release-gate-hermetic-env.js +0 -5
  166. package/dist/core/release-parallel-full-coverage.js +0 -2
  167. package/dist/core/remote/ssh-worker-client.js +0 -3
  168. package/dist/core/research/research-adversarial-review.js +6 -2
  169. package/dist/core/responses-retry-policy.js +0 -10
  170. package/dist/core/retention.js +0 -7
  171. package/dist/core/routes/constants.js +0 -3
  172. package/dist/core/routes.js +89 -15
  173. package/dist/core/safety/command-contract/contracts.js +2 -0
  174. package/dist/core/safety/mutation-guard.js +0 -25
  175. package/dist/core/safety/mutation-ledger.js +0 -9
  176. package/dist/core/safety/requested-scope-contract.js +0 -0
  177. package/dist/core/security/high-risk-contracts.js +0 -1
  178. package/dist/core/skills/core-skill-card.js +0 -0
  179. package/dist/core/skills/core-skill-deployment.js +0 -13
  180. package/dist/core/skills/core-skill-epoch.js +0 -11
  181. package/dist/core/skills/core-skill-meta-update.js +0 -6
  182. package/dist/core/skills/core-skill-patch-apply.js +0 -7
  183. package/dist/core/skills/core-skill-patch.js +0 -8
  184. package/dist/core/skills/core-skill-reflection.js +0 -16
  185. package/dist/core/skills/core-skill-runtime.js +0 -6
  186. package/dist/core/skills/core-skill-scorer.js +0 -7
  187. package/dist/core/skills/core-skill-trainer.js +0 -11
  188. package/dist/core/skills/core-skill-types.js +0 -9
  189. package/dist/core/skills/core-skill-validation.js +0 -5
  190. package/dist/core/skills/rejected-skill-patch-buffer.js +0 -2
  191. package/dist/core/stop-gate/stop-gate-check.js +0 -8
  192. package/dist/core/stop-gate/stop-gate-resolver.js +0 -7
  193. package/dist/core/stop-gate/stop-gate-writer.js +0 -5
  194. package/dist/core/subagents/model-policy.js +0 -7
  195. package/dist/core/subagents/naruto-help-contract.js +1 -1
  196. package/dist/core/subagents/naruto-proof-projection.js +582 -14
  197. package/dist/core/subagents/official-subagent-config.js +0 -8
  198. package/dist/core/subagents/official-subagent-preparation.js +6 -5
  199. package/dist/core/subagents/official-subagent-prompt.js +29 -0
  200. package/dist/core/subagents/official-subagent-runner.js +351 -38
  201. package/dist/core/subagents/subagent-evidence.js +378 -9
  202. package/dist/core/subagents/thread-budget.js +5 -2
  203. package/dist/core/subagents/triwiki-attention.js +0 -4
  204. package/dist/core/subagents/wave-parent-guidance.js +54 -9
  205. package/dist/core/telegram/runtime.js +0 -1
  206. package/dist/core/triwiki/code-index-scanner.js +0 -3
  207. package/dist/core/triwiki/code-pack-head-freshness.js +0 -10
  208. package/dist/core/triwiki/code-pack.js +0 -2
  209. package/dist/core/triwiki/triwiki-cache-key.js +0 -1
  210. package/dist/core/triwiki/triwiki-proof-bank.js +0 -1
  211. package/dist/core/triwiki-attention.js +0 -10
  212. package/dist/core/triwiki-provenance.js +0 -5
  213. package/dist/core/triwiki-runtime.js +0 -12
  214. package/dist/core/triwiki-wrongness/wrongness-ledger.js +0 -7
  215. package/dist/core/triwiki-wrongness/wrongness-schema.js +0 -3
  216. package/dist/core/trust-kernel/trust-report.js +0 -7
  217. package/dist/core/update/update-migration-state.js +21 -39
  218. package/dist/core/update-check.js +2 -14
  219. package/dist/core/version-manager.js +2 -0
  220. package/dist/core/version.js +1 -1
  221. package/dist/core/work-order-ledger.js +0 -17
  222. package/dist/core/zellij/zellij-clipboard-config.js +0 -18
  223. package/dist/core/zellij/zellij-lane-renderer.js +5 -46
  224. package/dist/core/zellij/zellij-lane-runtime.js +0 -1
  225. package/dist/core/zellij/zellij-launcher.js +0 -26
  226. package/dist/core/zellij/zellij-official-subagent-activity.js +0 -5
  227. package/dist/core/zellij/zellij-official-subagent-telemetry.js +0 -5
  228. package/dist/core/zellij/zellij-screen-proof.js +0 -7
  229. package/dist/core/zellij/zellij-slot-column-anchor.js +0 -1
  230. package/dist/core/zellij/zellij-slot-pane-renderer.js +0 -9
  231. package/dist/core/zellij/zellij-slot-telemetry.js +0 -12
  232. package/dist/core/zellij/zellij-ui-mode.js +0 -7
  233. package/dist/core/zellij/zellij-update.js +0 -29
  234. package/dist/core/zellij/zellij-worker-pane-manager.js +0 -39
  235. package/dist/native/sks-menubar/Sources/AlertFactory.swift +21 -2
  236. package/dist/native/sks-menubar/Sources/AppDelegate.swift +3 -0
  237. package/dist/native/sks-menubar/Sources/AppIdentity.swift +25 -0
  238. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +254 -21
  239. package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +95 -12
  240. package/dist/scripts/agent-message-bus-reader-check.js +0 -1
  241. package/dist/scripts/all-feature-deep-completion-check.js +0 -1
  242. package/dist/scripts/appshots-thread-attachment-discovery-check.js +0 -1
  243. package/dist/scripts/architecture-guard-check.js +0 -1
  244. package/dist/scripts/build-dist.js +0 -1
  245. package/dist/scripts/build-once-runner-check.js +0 -1
  246. package/dist/scripts/canonical-test-runner.js +0 -2
  247. package/dist/scripts/certificate-sla-check.js +0 -1
  248. package/dist/scripts/changelog-check.js +0 -1
  249. package/dist/scripts/check-cli-entrypoint.js +0 -1
  250. package/dist/scripts/check-command-module-budget.js +0 -7
  251. package/dist/scripts/check-feature-quality.js +0 -1
  252. package/dist/scripts/check-legacy-free.js +0 -1
  253. package/dist/scripts/check-pipeline-runtime.js +0 -1
  254. package/dist/scripts/check-runtime-schemas.js +0 -1
  255. package/dist/scripts/codex-0-134-runner-truth-check.js +0 -1
  256. package/dist/scripts/codex-0-137-compat-check.js +0 -1
  257. package/dist/scripts/codex-0138-capability-artifact-check.js +0 -1
  258. package/dist/scripts/codex-0138-capability-check.js +0 -1
  259. package/dist/scripts/codex-0138-doctor-check.js +0 -1
  260. package/dist/scripts/codex-0138-feature-probes-check.js +0 -1
  261. package/dist/scripts/codex-0144-core-real-probes-check.js +0 -1
  262. package/dist/scripts/codex-app-handoff-check.js +0 -1
  263. package/dist/scripts/codex-app-handoff-launch-check.js +0 -1
  264. package/dist/scripts/codex-config-load-probe.js +0 -5
  265. package/dist/scripts/codex-control-all-pipelines-check.js +0 -1
  266. package/dist/scripts/codex-control-event-stream-ledger-check.js +0 -1
  267. package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +0 -1
  268. package/dist/scripts/codex-permission-profiles-check.js +0 -1
  269. package/dist/scripts/codex-plugin-app-template-policy-check.js +0 -1
  270. package/dist/scripts/codex-project-config-policy-splitter-check.js +0 -1
  271. package/dist/scripts/codex-sdk-all-pipelines-check.js +0 -1
  272. package/dist/scripts/codex-sdk-backend-router-check.js +0 -1
  273. package/dist/scripts/codex-sdk-capability-check.js +0 -1
  274. package/dist/scripts/codex-sdk-event-stream-ledger-check.js +0 -1
  275. package/dist/scripts/codex-sdk-real-smoke-check.js +0 -1
  276. package/dist/scripts/concurrent-session-collision-check.js +9 -0
  277. package/dist/scripts/context7-evidence-dedupe-check.js +0 -1
  278. package/dist/scripts/core-skill-card-schema-check.js +0 -11
  279. package/dist/scripts/core-skill-deployment-snapshot-check.js +0 -10
  280. package/dist/scripts/core-skill-heldout-validation-check.js +0 -11
  281. package/dist/scripts/core-skill-no-inference-optimizer-check.js +0 -11
  282. package/dist/scripts/core-skill-patch-check.js +0 -11
  283. package/dist/scripts/core-skill-route-runtime-integration-check.js +0 -11
  284. package/dist/scripts/current-surface-update-e2e-check.js +0 -4
  285. package/dist/scripts/current-upgrade-matrix-check.js +0 -1
  286. package/dist/scripts/dfix-fixture-check.js +0 -1
  287. package/dist/scripts/dfix-patch-handoff-check.js +0 -1
  288. package/dist/scripts/dfix-verification-check.js +0 -1
  289. package/dist/scripts/dfix-verification-recommendation-check.js +0 -1
  290. package/dist/scripts/docs-truthfulness-check.js +3 -3
  291. package/dist/scripts/doctor-fastpath-check.js +0 -1
  292. package/dist/scripts/doctor-fix-proves-codex-read-check.js +0 -11
  293. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +0 -4
  294. package/dist/scripts/doctor-idempotence-check.js +0 -1
  295. package/dist/scripts/doctor-ops-semantics-check.js +0 -1
  296. package/dist/scripts/ensure-bin-executable.js +0 -1
  297. package/dist/scripts/evidence-flagship-coverage-check.js +0 -1
  298. package/dist/scripts/fast-codex-service-tier-proof-check.js +0 -1
  299. package/dist/scripts/fixtures/fake-codex-config-loader.js +0 -5
  300. package/dist/scripts/fsx-hotpath-check.js +0 -1
  301. package/dist/scripts/gate-policy-audit-check.js +1 -1
  302. package/dist/scripts/geo-claim-evidence-check.js +0 -1
  303. package/dist/scripts/geo-cli-blackbox-check.js +0 -1
  304. package/dist/scripts/geo-crawler-policy-check.js +0 -1
  305. package/dist/scripts/git-worktree-diff-envelope-check.js +0 -1
  306. package/dist/scripts/git-worktree-dirty-lock-check.js +0 -1
  307. package/dist/scripts/git-worktree-dirty-main-detection-check.js +0 -1
  308. package/dist/scripts/git-worktree-integration-primary-check.js +0 -1
  309. package/dist/scripts/git-worktree-manifest-append-check.js +0 -1
  310. package/dist/scripts/git-worktree-untracked-diff-check.js +0 -1
  311. package/dist/scripts/high-risk-contracts-check.js +0 -1
  312. package/dist/scripts/hook-latency-budget-check.js +0 -1
  313. package/dist/scripts/hook-latency-quantum-check.js +0 -1
  314. package/dist/scripts/image-artifact-path-contract-check.js +0 -1
  315. package/dist/scripts/imagegen-real-smoke-check.js +0 -1
  316. package/dist/scripts/import-graph-budget-check.js +0 -1
  317. package/dist/scripts/installed-package-smoke-check.js +0 -1
  318. package/dist/scripts/legacy-gate-purge-check.js +0 -1
  319. package/dist/scripts/lib/codex-sdk-gate-lib.js +0 -3
  320. package/dist/scripts/lib/ensure-dist-fresh.js +0 -1
  321. package/dist/scripts/lib/valid-png-fixture.js +0 -1
  322. package/dist/scripts/local-collab-all-pipelines-final-gpt-check.js +0 -1
  323. package/dist/scripts/loop-directive-check-lib.js +0 -1
  324. package/dist/scripts/loop-worker-fixture-child.js +0 -1
  325. package/dist/scripts/mad-preflight-blocks-unreadable-config-check.js +0 -10
  326. package/dist/scripts/mad-sks-sql-plane-lifecycle-hook-decision-check.js +0 -1
  327. package/dist/scripts/mad-sks-sql-plane-result-lifecycle-check.js +0 -1
  328. package/dist/scripts/mcp-plugin-inventory-check.js +0 -1
  329. package/dist/scripts/mcp-tool-naming-parity-check.js +0 -1
  330. package/dist/scripts/model-call-concurrency-check.js +0 -1
  331. package/dist/scripts/mutation-callsite-coverage-check.js +0 -5
  332. package/dist/scripts/naruto-codex-e2e-check.js +0 -1
  333. package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -1
  334. package/dist/scripts/official-subagent-workflow-check.js +3 -1
  335. package/dist/scripts/ops-diagnostics-bundle-check.js +0 -1
  336. package/dist/scripts/packlist-performance-check.js +1 -3
  337. package/dist/scripts/perf-budget-check.js +0 -1
  338. package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -1
  339. package/dist/scripts/ppt-real-export-adapter-check.js +0 -1
  340. package/dist/scripts/ppt-real-imagegen-smoke-check.js +0 -1
  341. package/dist/scripts/ppt-real-imagegen-wiring-check.js +0 -1
  342. package/dist/scripts/ppt-reexport-rereview-check.js +0 -1
  343. package/dist/scripts/prepublish-fast-check.js +0 -23
  344. package/dist/scripts/prepublish-release-check-or-fast.js +0 -7
  345. package/dist/scripts/probe-memoization-check.js +0 -1
  346. package/dist/scripts/product-design-plugin-routing-check.js +0 -1
  347. package/dist/scripts/project-skill-dedupe-blackbox.js +36 -9
  348. package/dist/scripts/prompt-placeholder-guard-check.js +0 -1
  349. package/dist/scripts/python-codex-sdk-all-pipelines-check.js +0 -3
  350. package/dist/scripts/qa-loop-app-handoff-capability-check.js +0 -1
  351. package/dist/scripts/qa-loop-app-handoff-check.js +0 -1
  352. package/dist/scripts/qa-loop-app-handoff-cli-check.js +0 -1
  353. package/dist/scripts/qa-loop-app-handoff-confirmation-check.js +0 -1
  354. package/dist/scripts/qa-loop-app-handoff-gate-lifecycle-check.js +0 -1
  355. package/dist/scripts/qa-loop-app-handoff-launch-check.js +0 -1
  356. package/dist/scripts/qa-loop-app-handoff-status-lifecycle-check.js +0 -1
  357. package/dist/scripts/qa-loop-budget-policy-check.js +0 -1
  358. package/dist/scripts/qa-loop-effort-escalation-check.js +0 -1
  359. package/dist/scripts/qa-loop-image-path-exposure-check.js +0 -1
  360. package/dist/scripts/qa-loop-image-path-prompt-injection-check.js +0 -1
  361. package/dist/scripts/release-cache-glob-hashing-check.js +0 -1
  362. package/dist/scripts/release-cache-input-classifier-check.js +0 -1
  363. package/dist/scripts/release-cache-neutralization-report-check.js +0 -1
  364. package/dist/scripts/release-cache-version-neutral-fixture-check.js +0 -1
  365. package/dist/scripts/release-check-stamp.js +0 -4
  366. package/dist/scripts/release-dist-freshness-check.js +0 -1
  367. package/dist/scripts/release-full-parallelism-blackbox.js +3 -3
  368. package/dist/scripts/release-gate-batch-runner-check.js +22 -0
  369. package/dist/scripts/release-gate-budget-check.js +0 -6
  370. package/dist/scripts/release-gate-dag-runner-check.js +0 -1
  371. package/dist/scripts/release-latency-slo-check.js +0 -1
  372. package/dist/scripts/release-metadata-1-19-check.js +0 -1
  373. package/dist/scripts/release-metadata-check.js +0 -3
  374. package/dist/scripts/release-parallel-speed-budget-check.js +0 -5
  375. package/dist/scripts/release-proof-truth-check.js +0 -1
  376. package/dist/scripts/release-provenance-check.js +0 -1
  377. package/dist/scripts/release-real-check.js +0 -1
  378. package/dist/scripts/release-runtime-truth-matrix-check.js +0 -1
  379. package/dist/scripts/release-version-truth-check.js +0 -1
  380. package/dist/scripts/research-blueprint-densifier-check.js +0 -1
  381. package/dist/scripts/research-claim-builder-check.js +0 -1
  382. package/dist/scripts/research-complete-package-fixture-check.js +0 -1
  383. package/dist/scripts/research-final-reviewer-blackbox.js +0 -1
  384. package/dist/scripts/responses-retry-policy-centralized-check.js +0 -1
  385. package/dist/scripts/retention-apply-smoke-check.js +0 -1
  386. package/dist/scripts/retention-budget-check.js +0 -1
  387. package/dist/scripts/retention-dry-run-check.js +0 -1
  388. package/dist/scripts/rollback-recovery-smoke-check.js +0 -1
  389. package/dist/scripts/route-intent-regression-check.js +0 -1
  390. package/dist/scripts/runtime-current-terminal-check.js +0 -1
  391. package/dist/scripts/runtime-dist-parity-check.js +0 -1
  392. package/dist/scripts/runtime-no-src-mjs-check.js +0 -1
  393. package/dist/scripts/runtime-proof-summary-check.js +0 -1
  394. package/dist/scripts/runtime-ts-rust-boundary-check.js +0 -15
  395. package/dist/scripts/runtime-ts-source-of-truth-check.js +0 -1
  396. package/dist/scripts/scheduler-batch-dispatch-check.js +0 -1
  397. package/dist/scripts/scheduler-parallel-proof-consistency-check.js +0 -1
  398. package/dist/scripts/scheduler-utilization-integral-check.js +0 -1
  399. package/dist/scripts/search-visibility-gate-lib.js +0 -1
  400. package/dist/scripts/seo-audit-fixture-check.js +0 -1
  401. package/dist/scripts/seo-cli-blackbox-check.js +0 -1
  402. package/dist/scripts/seo-geo-geo-disambiguation-check.js +0 -1
  403. package/dist/scripts/seo-geo-route-identity-check.js +0 -1
  404. package/dist/scripts/seo-geo-skill-rich-content-check.js +0 -1
  405. package/dist/scripts/seo-marketing-truthfulness-check.js +0 -1
  406. package/dist/scripts/seo-metadata-sync-check.js +0 -1
  407. package/dist/scripts/seo-no-mutation-by-default-check.js +0 -1
  408. package/dist/scripts/shared-memory-fixture-check.js +0 -1
  409. package/dist/scripts/side-effect-runtime-report-check.js +0 -1
  410. package/dist/scripts/sizecheck.js +0 -1
  411. package/dist/scripts/sks-1-11-gate-lib.js +0 -1
  412. package/dist/scripts/sks-1-12-real-execution-check-lib.js +0 -1
  413. package/dist/scripts/sks-1-18-gate-lib.js +0 -1
  414. package/dist/scripts/sks-menubar-install-check.js +0 -3
  415. package/dist/scripts/sksd-daemon-check.js +0 -1
  416. package/dist/scripts/super-search-live-smoke-check.js +0 -1
  417. package/dist/scripts/super-search-local-http-smoke-check.js +0 -1
  418. package/dist/scripts/super-search-offline-contract-check.js +0 -1
  419. package/dist/scripts/super-search-provider-interface-check.js +0 -1
  420. package/dist/scripts/triwiki-cache-key-check.js +0 -1
  421. package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -1
  422. package/dist/scripts/triwiki-proof-bank-check.js +0 -1
  423. package/dist/scripts/triwiki-proof-card-check.js +0 -1
  424. package/dist/scripts/trust-fixture-check.js +0 -1
  425. package/dist/scripts/ultra-router-auto-router-check.js +0 -1
  426. package/dist/scripts/update-fastpath-check.js +0 -1
  427. package/dist/scripts/upgrade-migration-matrix-check.js +0 -1
  428. package/dist/scripts/ux-review-extract-wires-real-extractor-check.js +0 -1
  429. package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -1
  430. package/dist/scripts/ux-review-patch-diff-recheck-check.js +0 -1
  431. package/dist/scripts/ux-review-real-imagegen-smoke-check.js +0 -1
  432. package/dist/scripts/ux-review-run-wires-imagegen-check.js +0 -1
  433. package/dist/scripts/write-build-manifest.js +0 -1
  434. package/dist/scripts/wrongness-fixture-check.js +0 -1
  435. package/dist/scripts/zellij-capability-check.js +0 -1
  436. package/dist/scripts/zellij-developer-controls-check.js +0 -1
  437. package/dist/scripts/zellij-doctor-readiness-check.js +0 -13
  438. package/dist/scripts/zellij-dynamic-pane-lifecycle-check.js +0 -1
  439. package/dist/scripts/zellij-fake-adapter-check.js +0 -1
  440. package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -1
  441. package/dist/scripts/zellij-lane-renderer-check.js +0 -1
  442. package/dist/scripts/zellij-launch-command-truth-check.js +0 -12
  443. package/dist/scripts/zellij-layout-valid-check.js +0 -1
  444. package/dist/scripts/zellij-pane-creation-lock-metrics-check.js +0 -1
  445. package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -1
  446. package/dist/scripts/zellij-pane-lock-does-not-block-worker-check.js +0 -1
  447. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -1
  448. package/dist/scripts/zellij-pane-proof-check.js +0 -1
  449. package/dist/scripts/zellij-qa-app-handoff-status-check.js +0 -1
  450. package/dist/scripts/zellij-real-session-cleanup-check.js +0 -1
  451. package/dist/scripts/zellij-real-session-launch-check.js +0 -1
  452. package/dist/scripts/zellij-right-column-geometry-proof.js +0 -1
  453. package/dist/scripts/zellij-right-column-headless-overflow-check.js +0 -1
  454. package/dist/scripts/zellij-right-column-manager-check.js +0 -1
  455. package/dist/scripts/zellij-screen-proof-check.js +0 -1
  456. package/dist/scripts/zellij-slot-only-ui-check.js +0 -1
  457. package/dist/scripts/zellij-slot-pane-renderer-check.js +0 -1
  458. package/dist/scripts/zellij-slot-pane-stale-detection-check.js +0 -7
  459. package/dist/scripts/zellij-slot-telemetry-incremental-check.js +0 -1
  460. package/dist/scripts/zellij-slot-telemetry-live-flush-check.js +0 -1
  461. package/dist/scripts/zellij-slot-telemetry-performance-check.js +0 -1
  462. package/dist/scripts/zellij-stacked-capability-routing-check.js +0 -1
  463. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -1
  464. package/dist/scripts/zellij-stacked-version-matrix-check.js +0 -1
  465. package/dist/scripts/zellij-stacked-version-parser-check.js +0 -1
  466. package/dist/scripts/zellij-ui-design-check.js +0 -12
  467. package/dist/scripts/zellij-update-prompt-matrix-check.js +0 -1
  468. package/dist/scripts/zellij-update-prompt-mode-check.js +0 -1
  469. package/dist/scripts/zellij-update-prompt-safety-check.js +0 -1
  470. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -2
  471. package/package.json +1 -1
@@ -41,17 +41,8 @@ export async function postinstall({ bootstrap, args = [] }) {
41
41
  return;
42
42
  }
43
43
  const codexLbConfigSnapshot = await capturePostinstallCodexLbConfigSnapshot();
44
- // A failed setup side-effect must never fail `npm i`. Wrap the whole flow; always
45
- // restore the codex-lb snapshot in finally (even on the early bootstrap return / on throw).
46
44
  try {
47
45
  console.log('\nSKS installed.');
48
- // The published tarball deliberately excludes dist/.sks-build-stamp.json
49
- // (package.json files: "!dist/.sks-build-stamp.json"), but `sks update`
50
- // self-verification requires a version-matching stamp inside the installed
51
- // package. Regenerate it here so npm installs are verifiable; never
52
- // overwrite an existing stamp (in a dev checkout the build writes the real
53
- // one, and re-stamping against the current source tree would mask a stale
54
- // dist).
55
46
  try {
56
47
  const stampLib = await import('../scripts/lib/ensure-dist-fresh.js');
57
48
  await fsp.access(stampLib.distStampPath).catch(async () => {
@@ -124,7 +115,6 @@ export async function postinstall({ bootstrap, args = [] }) {
124
115
  console.log(`SKS mission cleanup: removed ${postinstallRetention.action_count} disposable runtime artifact(s) from closed missions.`);
125
116
  else if (postinstallRetention.status === 'failed')
126
117
  console.log(`SKS mission cleanup: skipped (${postinstallRetention.error || 'cleanup failed'}).`);
127
- // Terminating a third-party app's processes during `npm i` is unsafe by default; opt-in only.
128
118
  const appProcessRepair = process.env.SKS_POSTINSTALL_RECONCILE_APP_PROCESSES === '1'
129
119
  ? await reconcileCodexAppUpgradeProcesses()
130
120
  : { status: 'skipped', reason: 'opt_in_required', killed: [] };
@@ -179,7 +169,7 @@ export async function postinstall({ bootstrap, args = [] }) {
179
169
  }
180
170
  finally {
181
171
  await restorePostinstallCodexLbConfigSnapshot(codexLbConfigSnapshot).catch(() => { });
182
- await reportPostinstallCodexLbAuth().catch(() => { });
172
+ await reportPostinstallCodexLbAuth(codexLbConfigSnapshot).catch(() => { });
183
173
  }
184
174
  }
185
175
  async function runPostinstallProjectRetentionCleanup(root) {
@@ -212,8 +202,13 @@ async function runPostinstallProjectRetentionCleanup(root) {
212
202
  };
213
203
  }
214
204
  }
215
- async function reportPostinstallCodexLbAuth() {
216
- const codexLbAuth = await ensureCodexLbAuthDuringInstall();
205
+ async function reportPostinstallCodexLbAuth(snapshot = null) {
206
+ const preserveActiveCodexLb = snapshot?.selected === true && snapshot?.codex_lb_key_in_shared_auth === true;
207
+ const codexLbAuth = await ensureCodexLbAuthDuringInstall({
208
+ forceCodexLbApiKeyAuth: preserveActiveCodexLb,
209
+ ...(snapshot?.secret_api_key ? { apiKey: snapshot.secret_api_key } : {}),
210
+ ...(snapshot?.base_url ? { baseUrl: snapshot.base_url } : {})
211
+ });
217
212
  if (codexLbAuth.legacy_auth_migrated)
218
213
  console.log(`codex-lb auth: restored from existing Codex login cache into ${codexLbAuth.env_path}.`);
219
214
  else if (codexLbAuth.status === 'synced' || codexLbAuth.status === 'present' || codexLbAuth.status === 'repaired')
@@ -235,7 +230,7 @@ async function reportPostinstallCodexLbAuth() {
235
230
  console.log(`codex-lb auth: ChatGPT OAuth preserved as backup; run \`sks codex-lb use-codex-lb\` to switch the App to codex-lb API-key auth (backup at ${reconcile.backup_path ?? 'unknown'}).`);
236
231
  }
237
232
  else if (reconcile?.status === 'oauth_restored') {
238
- console.log(`codex-lb auth: restored ChatGPT OAuth from ${reconcile.backup_path ?? 'unknown'} while keeping codex-lb selected.`);
233
+ console.log(`codex-lb auth: restored ChatGPT OAuth from ${reconcile.backup_path ?? 'unknown'} and cleared codex-lb provider selection.`);
239
234
  }
240
235
  else if (reconcile?.status === 'apikey_forced') {
241
236
  console.log(`codex-lb auth: forced API-key auth.json for CLI-only use (OAuth backup at ${reconcile.backup_path ?? 'unknown'}).`);
@@ -297,9 +292,6 @@ export async function postinstallBootstrapDecision(root) {
297
292
  const target = candidate ? installRoot : globalSksRoot();
298
293
  if (process.env.SKS_POSTINSTALL_BOOTSTRAP === '1')
299
294
  return { run: true, target, reason: 'forced by SKS_POSTINSTALL_BOOTSTRAP=1' };
300
- // A global `npm i -g sneakoscope` must NOT initialize whatever project the user's shell
301
- // happened to be in (that would scribble AGENTS.md/.codex/.agents into an unrelated repo).
302
- // Only bootstrap the global runtime root; the user runs `sks setup` inside a project explicitly.
303
295
  if (process.env.npm_config_global === 'true' && candidate) {
304
296
  return { run: true, target: globalSksRoot(), reason: 'global install: bootstrapping global SKS runtime only (run `sks setup` inside a project to initialize it)' };
305
297
  }
@@ -328,10 +320,10 @@ async function capturePostinstallCodexLbConfigSnapshot(home = process.env.HOME |
328
320
  const envText = await readText(envPath, '');
329
321
  const authExisted = await exists(authPath);
330
322
  const authText = authExisted ? await readText(authPath, '') : '';
331
- const envKey = parseCodexLbEnvKey(envText);
323
+ const envLoad = await loadCodexLbEnv({ home, envPath });
324
+ const envKey = envLoad.secret_api_key || '';
332
325
  const providerConfigured = /\[model_providers\.codex-lb\]/.test(config);
333
- const baseUrl = codexLbProviderBaseUrl(config) || parseCodexLbEnvBaseUrl(envText);
334
- // Snapshot any codex-lb-related state so the upgrade-time bootstrap can't silently undo it.
326
+ const baseUrl = envLoad.base_url || codexLbProviderBaseUrl(config) || parseCodexLbEnvBaseUrl(envText);
335
327
  if (!envKey && !providerConfigured && !authExisted)
336
328
  return null;
337
329
  return {
@@ -340,6 +332,12 @@ async function capturePostinstallCodexLbConfigSnapshot(home = process.env.HOME |
340
332
  auth_path: authPath,
341
333
  base_url: baseUrl ? normalizeCodexLbBaseUrl(baseUrl) : null,
342
334
  selected: hasTopLevelCodexLbSelected(config),
335
+ auth_mode: codexAuthModeSummary(authText).mode,
336
+ codex_lb_key_in_shared_auth: Boolean(envKey && parseCodexAuthApiKey(authText) === envKey),
337
+ credential_source: envLoad.source,
338
+ credential_fingerprint: envLoad.api_key.fingerprint,
339
+ credential_binding: envLoad.credential_binding,
340
+ secret_api_key: envKey || null,
343
341
  auth_existed: authExisted,
344
342
  auth_text: authText
345
343
  };
@@ -357,13 +355,15 @@ async function restorePostinstallCodexLbConfigSnapshot(snapshot) {
357
355
  configRestored = safeWrite.ok && safeWrite.changed === true;
358
356
  }
359
357
  }
360
- // Restore auth.json only if bootstrap accidentally wiped or emptied a pre-existing auth.json.
361
- // We do NOT clobber a legitimately rewritten auth.json; we just heal the disappearing-auth regression.
362
358
  let authRestored = false;
363
359
  if (snapshot.auth_existed && snapshot.auth_text && snapshot.auth_text.trim()) {
364
360
  const currentAuthExists = await exists(snapshot.auth_path);
365
361
  const currentAuthText = currentAuthExists ? await readText(snapshot.auth_path, '') : '';
366
- if (!currentAuthExists || !currentAuthText.trim()) {
362
+ const activeCodexLbAuthChanged = snapshot.selected === true
363
+ && snapshot.codex_lb_key_in_shared_auth === true
364
+ && snapshot.secret_api_key
365
+ && parseCodexAuthApiKey(currentAuthText) !== snapshot.secret_api_key;
366
+ if (!currentAuthExists || !currentAuthText.trim() || activeCodexLbAuthChanged) {
367
367
  await ensureDir(path.dirname(snapshot.auth_path));
368
368
  await writeTextAtomic(snapshot.auth_path, snapshot.auth_text, { mode: 0o600 });
369
369
  await fsp.chmod(snapshot.auth_path, 0o600).catch(() => { });
@@ -383,8 +383,6 @@ async function ensureCodexLbToolCatalogSelection(input, opts = {}) {
383
383
  const catalogPath = codexLbToolCatalogPath(codexHome);
384
384
  const current = await readText(input.configPath, '');
385
385
  const selected = hasTopLevelCodexLbSelected(current);
386
- // Setup writes the catalog pointer before selecting the provider so Desktop can
387
- // load GPT-5.6/tool metadata the moment model_provider becomes codex-lb.
388
386
  const canBindCatalog = selected || opts.allowUnselectedCatalogWrite === true;
389
387
  const existingCatalogPath = topLevelTomlString(current, 'model_catalog_json');
390
388
  if (canBindCatalog && existingCatalogPath && path.resolve(existingCatalogPath) !== path.resolve(catalogPath)) {
@@ -514,9 +512,6 @@ export async function configureCodexLb(opts = {}) {
514
512
  const beforeState = await captureCodexLbSetupWriteState({ home, configPath, envPath, shellProfile });
515
513
  const appliedActions = [];
516
514
  await ensureDir(path.dirname(configPath));
517
- // Write the provider table first without selecting it. Desktop model/tool UI
518
- // exposure depends on a validated catalog; selecting before that leaves the App
519
- // on codex-lb with no GPT-5.6 picker surface.
520
515
  const current = await readText(configPath, '');
521
516
  const providerOnly = normalizeCodexFastModeUiConfig(upsertCodexLbConfig(current, baseUrl, false), {
522
517
  forceFastMode: opts.forceFastMode !== false
@@ -559,7 +554,6 @@ export async function configureCodexLb(opts = {}) {
559
554
  }
560
555
  providerSelected = true;
561
556
  appliedActions.push({ type: 'select_default_provider', target: configPath, ok: true, backup_path: selectWrite.backup_path });
562
- // Re-bind after selection so model_catalog_json stays attached to the active provider.
563
557
  toolCatalog = await ensureCodexLbToolCatalogSelection({ home, configPath, baseUrl, apiKey }, opts);
564
558
  if (toolCatalog.config_changed) {
565
559
  appliedActions.push({ type: 'write_model_tool_catalog', target: toolCatalog.path, ok: toolCatalog.ok === true, status: toolCatalog.status });
@@ -595,8 +589,6 @@ export async function configureCodexLb(opts = {}) {
595
589
  if (shellProfile !== 'skip')
596
590
  appliedActions.push({ type: 'install_shell_profile_snippet', target: shellProfileResult.files?.join(', ') || shellProfile, ok: shellProfileResult.ok === true, status: shellProfileResult.status });
597
591
  const codexLb = await codexLbStatus({ ...opts, home, configPath, envPath });
598
- // Never activate shared sk-clb auth while the Desktop picker is still missing a
599
- // ready catalog/selection — that leaves App threads calling api.openai.com.
600
592
  const wantForceCodexLbApiKeyAuth = opts.forceCodexLbApiKeyAuth === true || opts.authMode === 'codex-lb';
601
593
  const forceCodexLbApiKeyAuth = wantForceCodexLbApiKeyAuth && providerSelected;
602
594
  const authReconcile = providerSelected
@@ -688,10 +680,13 @@ export async function codexLbStatus(opts = {}) {
688
680
  const authText = await readText(authPath, '');
689
681
  const authMode = codexAuthModeSummary(authText);
690
682
  const authApiKey = parseCodexAuthApiKey(authText);
691
- const envKeyConfigured = Boolean(envLoad.api_key.present);
683
+ const envKeyConfigured = Boolean(envLoad.secret_api_key);
692
684
  const providerConfigured = /\[model_providers\.codex-lb\]/.test(config);
693
685
  const selected = hasTopLevelCodexLbSelected(config);
694
- const baseUrl = codexLbProviderBaseUrl(config) || envLoad.base_url || null;
686
+ const providerBaseUrl = normalizeCodexLbBaseUrl(codexLbProviderBaseUrl(config));
687
+ const credentialBaseUrl = envLoad.base_url;
688
+ const baseUrl = credentialBaseUrl || providerBaseUrl || null;
689
+ const providerBaseUrlMatchesCredential = Boolean(providerBaseUrl && credentialBaseUrl && providerBaseUrl === credentialBaseUrl);
695
690
  const providerName = codexLbProviderName(config);
696
691
  const providerWireApi = codexLbProviderWireApi(config);
697
692
  const providerSupportsWebsockets = codexLbProviderSupportsWebsockets(config);
@@ -703,13 +698,14 @@ export async function codexLbStatus(opts = {}) {
703
698
  const sharedOpenAiRoutingSafe = !codexLbKeyInSharedAuth || sharedOpenAiRouting.status === 'matched';
704
699
  const authRoutingCoherent = selected === codexLbKeyInSharedAuth && sharedOpenAiRoutingSafe;
705
700
  const providerContractOk = providerConfigured
701
+ && providerBaseUrlMatchesCredential
706
702
  && providerName === CODEX_LB_PROVIDER_NAME
707
703
  && providerWireApi === 'responses'
708
704
  && providerEnvKey === CODEX_LB_PROVIDER_ENV_KEY
709
705
  && providerSupportsWebsockets === true
710
706
  && providerRequiresOpenAiAuth === true;
711
707
  const providerUsesCodexLbEnvAuth = providerConfigured && providerEnvKey === CODEX_LB_PROVIDER_ENV_KEY && providerOpenAiAuthDisabled;
712
- const codexAppUsableWithCodexLb = providerContractOk && envKeyConfigured && Boolean(baseUrl) && authMode.codex_app_usable;
708
+ const codexAppUsableWithCodexLb = providerContractOk && envLoad.configured && Boolean(baseUrl) && authMode.codex_app_usable;
713
709
  const fastMode = codexLbFastModeConfigStatus(config);
714
710
  const launchEnvironment = await inspectCodexLbMacLaunchEnvironment(baseUrl, opts).catch((err) => ({
715
711
  checked: true,
@@ -717,11 +713,11 @@ export async function codexLbStatus(opts = {}) {
717
713
  status: 'inspect_failed',
718
714
  error: err.message
719
715
  }));
720
- const providerReady = providerContractOk && envKeyConfigured && Boolean(baseUrl) && authMode.codex_app_usable && authRoutingCoherent;
716
+ const providerReady = providerContractOk && envLoad.configured && Boolean(baseUrl) && authMode.codex_app_usable && authRoutingCoherent;
721
717
  const probeToolOutputRecovery = opts.probeToolOutputRecovery === true;
722
718
  const toolOutputRecovery = !selected
723
719
  ? codexLbToolOutputRecoveryNotSelected()
724
- : !probeToolOutputRecovery
720
+ : !probeToolOutputRecovery || !providerContractOk || !envLoad.configured
725
721
  ? codexLbToolOutputRecoveryNotChecked(true)
726
722
  : await probeCodexLbToolOutputRecovery({
727
723
  baseUrl,
@@ -736,6 +732,9 @@ export async function codexLbStatus(opts = {}) {
736
732
  config_path: configPath,
737
733
  env_path: envPath,
738
734
  provider_configured: providerConfigured,
735
+ provider_base_url: providerBaseUrl || null,
736
+ credential_base_url: credentialBaseUrl || null,
737
+ provider_base_url_matches_credential: providerBaseUrlMatchesCredential,
739
738
  provider_name: providerName || null,
740
739
  provider_wire_api: providerWireApi || null,
741
740
  provider_supports_websockets: providerSupportsWebsockets,
@@ -754,6 +753,7 @@ export async function codexLbStatus(opts = {}) {
754
753
  source: envLoad.source,
755
754
  source_priority: envLoad.source_priority,
756
755
  api_key: envLoad.api_key,
756
+ credential_binding: envLoad.credential_binding,
757
757
  keychain: envLoad.keychain,
758
758
  env_paths: envLoad.env_paths
759
759
  },
@@ -965,7 +965,12 @@ export async function repairCodexLbAuth(opts = {}) {
965
965
  }
966
966
  await migrateCodexAuthKeyFormat({ home: opts.home });
967
967
  const codexEnvironment = await syncCodexLbProviderEnvironment(status, opts);
968
- const apiKey = parseCodexLbEnvKey(await readText(status.env_path, ''));
968
+ const loadedEnv = await loadCodexLbEnv({
969
+ ...opts,
970
+ home: opts.home || process.env.HOME || os.homedir(),
971
+ envPath: status.env_path
972
+ });
973
+ const apiKey = String(opts.apiKey || loadedEnv.secret_api_key || '').trim();
969
974
  const toolCatalog = await ensureCodexLbToolCatalogSelection({
970
975
  home: opts.home || process.env.HOME || os.homedir(),
971
976
  configPath: status.config_path,
@@ -978,10 +983,17 @@ export async function repairCodexLbAuth(opts = {}) {
978
983
  ? { ok: ['apikey_forced', 'apikey_auth_active'].includes(authReconcile.status), status: authReconcile.status, ...(authReconcile.reason ? { reason: authReconcile.reason } : {}), error: authReconcile.error || null }
979
984
  : await maybeSyncCodexLbSharedLogin(apiKey, { ...opts, home: opts.home || process.env.HOME || os.homedir(), force: true });
980
985
  const finalStatus = await codexLbStatus({ ...opts, probeToolOutputRecovery: true });
981
- const ok = Boolean(codexEnvironment.ok && codexLogin.ok && (toolCatalog.required === false || toolCatalog.ok === true));
986
+ const finalReady = finalStatus.selected === true
987
+ && finalStatus.provider_ready === true
988
+ && finalStatus.auth_routing_coherent === true
989
+ && finalStatus.shared_openai_routing?.safe === true;
990
+ const baseOk = Boolean(codexEnvironment.ok
991
+ && codexLogin.ok
992
+ && (toolCatalog.required === false || toolCatalog.ok === true));
993
+ const ok = baseOk && finalReady;
982
994
  return {
983
995
  ok,
984
- status: ok ? 'repaired' : (codexEnvironment.status || codexLogin.status),
996
+ status: ok ? 'repaired' : baseOk ? 'final_readiness_failed' : (codexEnvironment.status || codexLogin.status),
985
997
  config_path: status.config_path,
986
998
  env_path: status.env_path,
987
999
  base_url: status.base_url,
@@ -999,7 +1011,7 @@ export async function ensureCodexLbAuthDuringInstall(opts = {}) {
999
1011
  if (process.env.SKS_SKIP_POSTINSTALL_CODEX_LB_AUTH === '1' && !opts.force)
1000
1012
  return { status: 'skipped', reason: 'SKS_SKIP_POSTINSTALL_CODEX_LB_AUTH=1' };
1001
1013
  const status = await codexLbStatus(opts);
1002
- if (!status.selected && !status.provider_configured && !status.env_file)
1014
+ if (!status.selected && !status.provider_configured && !status.env_key_configured)
1003
1015
  return { status: 'not_configured', codex_lb: status };
1004
1016
  if (status.ok && !status.selected && status.auth_mode === 'chatgpt_oauth') {
1005
1017
  return {
@@ -1021,7 +1033,12 @@ export async function ensureCodexLbAuthDuringInstall(opts = {}) {
1021
1033
  return { status: status.env_key_configured ? 'missing_base_url' : 'missing_env_key', codex_lb: status, config_path: status.config_path, env_path: status.env_path };
1022
1034
  }
1023
1035
  const codexEnvironment = await syncCodexLbProviderEnvironment(status, opts);
1024
- const apiKey = parseCodexLbEnvKey(await readText(status.env_path, ''));
1036
+ const loadedEnv = await loadCodexLbEnv({
1037
+ ...opts,
1038
+ home: opts.home || process.env.HOME || os.homedir(),
1039
+ envPath: status.env_path
1040
+ });
1041
+ const apiKey = String(opts.apiKey || loadedEnv.secret_api_key || '').trim();
1025
1042
  const toolCatalog = await ensureCodexLbToolCatalogSelection({
1026
1043
  home: opts.home || process.env.HOME || os.homedir(),
1027
1044
  configPath: status.config_path,
@@ -1031,10 +1048,17 @@ export async function ensureCodexLbAuthDuringInstall(opts = {}) {
1031
1048
  const codexLogin = await maybeSyncCodexLbSharedLogin(apiKey, { ...opts, home: opts.home || process.env.HOME || os.homedir(), force: true });
1032
1049
  const authReconcile = await reconcileCodexLbAuthConflict({ ...opts, status }).catch((err) => ({ status: 'failed', reason: 'exception', error: err.message }));
1033
1050
  const finalStatus = await codexLbStatus(opts);
1034
- const ok = Boolean(codexEnvironment.ok && codexLogin.ok && (toolCatalog.required === false || toolCatalog.ok === true));
1051
+ const finalReady = finalStatus.selected === true
1052
+ && finalStatus.provider_ready === true
1053
+ && finalStatus.auth_routing_coherent === true
1054
+ && finalStatus.shared_openai_routing?.safe === true;
1055
+ const baseOk = Boolean(codexEnvironment.ok
1056
+ && codexLogin.ok
1057
+ && (toolCatalog.required === false || toolCatalog.ok === true));
1058
+ const ok = baseOk && finalReady;
1035
1059
  return {
1036
1060
  ok,
1037
- status: ok ? 'present' : (codexEnvironment.status || codexLogin.status),
1061
+ status: ok ? 'present' : baseOk ? 'final_readiness_failed' : (codexEnvironment.status || codexLogin.status),
1038
1062
  config_path: status.config_path,
1039
1063
  env_path: status.env_path,
1040
1064
  base_url: status.base_url,
@@ -1060,10 +1084,17 @@ async function restoreCodexLbEnvFromSharedLogin(status = {}, opts = {}) {
1060
1084
  await ensureDir(path.dirname(envPath));
1061
1085
  await writeTextAtomic(envPath, `export CODEX_LB_BASE_URL=${shellSingleQuote(normalizeCodexLbBaseUrl(baseUrl))}\nexport CODEX_LB_API_KEY=${shellSingleQuote(apiKey)}\n`, { mode: 0o600 });
1062
1086
  await fsp.chmod(envPath, 0o600).catch(() => { });
1087
+ const metadataPath = opts.metadataPath || codexLbMetadataPath(home);
1088
+ await writeTextAtomic(metadataPath, `${JSON.stringify({
1089
+ schema: 'sks.codex-lb-metadata.v1',
1090
+ base_url: normalizeCodexLbBaseUrl(baseUrl),
1091
+ updated_at: new Date().toISOString(),
1092
+ source: 'legacy-login-migration',
1093
+ api_key: { redacted: true, sha256: await sha256Text(apiKey) }
1094
+ }, null, 2)}\n`, { mode: 0o600 });
1095
+ await fsp.chmod(metadataPath, 0o600).catch(() => { });
1063
1096
  return { ok: true, status: 'migrated_login_cache', auth_path: authPath, env_path: envPath, base_url: normalizeCodexLbBaseUrl(baseUrl) };
1064
1097
  }
1065
- // Detects a real ChatGPT OAuth token blob in auth.json.
1066
- // A bare {"auth_mode":"browser"} marker is NOT considered an OAuth token blob — we preserve it.
1067
1098
  function hasChatgptOAuthTokens(text = '') {
1068
1099
  try {
1069
1100
  const parsed = JSON.parse(String(text || ''));
@@ -1076,7 +1107,6 @@ function hasChatgptOAuthTokens(text = '') {
1076
1107
  return true;
1077
1108
  }
1078
1109
  if (authMode && /chatgpt|oauth|browser/.test(authMode)) {
1079
- // Only treat as an OAuth blob when real tokens or a refresh metadata trail are also present.
1080
1110
  if (parsed.last_refresh || parsed.expires_at || parsed.refresh_token || parsed.access_token || parsed.id_token)
1081
1111
  return true;
1082
1112
  }
@@ -1113,8 +1143,6 @@ function codexAuthModeSummary(text = '') {
1113
1143
  catch { }
1114
1144
  return { mode: 'unknown', codex_app_usable: false, summary: 'unrecognized auth.json shape' };
1115
1145
  }
1116
- // Migrate auth.json from legacy {"auth_mode":"apikey","key":"..."} to the codex 0.130.0+
1117
- // format {"auth_mode":"apikey","OPENAI_API_KEY":"..."}. Safe: preserves key value, only renames field.
1118
1146
  async function migrateCodexAuthKeyFormat(opts = {}) {
1119
1147
  const home = opts.home || process.env.HOME || os.homedir();
1120
1148
  const authPath = opts.authPath || codexAuthPath(home);
@@ -1139,11 +1167,6 @@ async function migrateCodexAuthKeyFormat(opts = {}) {
1139
1167
  return { status: 'skipped', reason: 'parse_error' };
1140
1168
  }
1141
1169
  }
1142
- // Codex App uses the shared OpenAI auth store for providers with
1143
- // requires_openai_auth=true. Before putting the codex-lb key in that store, SKS
1144
- // must also guard the built-in `openai` provider with the same LB base URL. This
1145
- // covers stale App threads and explicit CLI overrides that retain `openai`; the
1146
- // config guard is written and verified before auth.json changes.
1147
1170
  export async function reconcileCodexLbAuthConflict(opts = {}) {
1148
1171
  const home = opts.home || process.env.HOME || os.homedir();
1149
1172
  const status = opts.status || await codexLbStatus({ ...opts, home });
@@ -1154,9 +1177,8 @@ export async function reconcileCodexLbAuthConflict(opts = {}) {
1154
1177
  }
1155
1178
  const authExists = await exists(authPath);
1156
1179
  const authText = authExists ? await readText(authPath, '') : '';
1157
- const envText = await readText(status.env_path, '');
1158
- const apiKey = parseCodexLbEnvKey(envText)
1159
- || String(opts.apiKey || (opts.env || process.env).CODEX_LB_API_KEY || '').trim();
1180
+ const envLoad = await loadCodexLbEnv({ ...opts, home, envPath: status.env_path });
1181
+ const apiKey = String(opts.apiKey || envLoad.secret_api_key || '').trim();
1160
1182
  if (!apiKey) {
1161
1183
  return { status: 'skipped', reason: 'missing_env_key', auth_path: authPath };
1162
1184
  }
@@ -1388,12 +1410,9 @@ export async function reconcileCodexLbAuthConflict(opts = {}) {
1388
1410
  }
1389
1411
  return { status: 'no_oauth_conflict', auth_path: authPath };
1390
1412
  }
1391
- // Expose the ChatGPT OAuth backup path so the CLI can surface it in status / release output.
1392
1413
  export function codexLbChatgptBackupPath(home = process.env.HOME || os.homedir()) {
1393
1414
  return codexAuthChatgptBackupPath(home);
1394
1415
  }
1395
- // Remove a top-level TOML key (only above the first table header). Returns the original text
1396
- // unchanged when the key isn't present.
1397
1416
  function removeTopLevelTomlString(text, key) {
1398
1417
  const lines = String(text || '').split('\n');
1399
1418
  const firstTable = lines.findIndex((x) => /^\s*\[.+\]\s*$/.test(x));
@@ -1412,8 +1431,6 @@ function removeTopLevelTomlString(text, key) {
1412
1431
  return text;
1413
1432
  return lines.join('\n').replace(/^\n+/, '').replace(/\n{3,}/g, '\n\n');
1414
1433
  }
1415
- // Unselect codex-lb at the top-level model_provider setting. Leaves [model_providers.codex-lb]
1416
- // and the env file alone so the user can re-engage with `sks codex-lb repair`.
1417
1434
  export async function unselectCodexLbProvider(opts = {}) {
1418
1435
  const home = opts.home || process.env.HOME || os.homedir();
1419
1436
  const configPath = opts.configPath || codexLbConfigPath(home);
@@ -1480,17 +1497,6 @@ function providerDeselectionOutcome(result) {
1480
1497
  provider_error: ok ? null : String(result?.provider_error || result?.error || result?.reason || result?.status || 'unselect_failed')
1481
1498
  };
1482
1499
  }
1483
- // Reverse of reconcileCodexLbAuthConflict: restore the ChatGPT OAuth blob from the backup file
1484
- // so the user can return to the official ChatGPT account login. Also deselects codex-lb at the
1485
- // model_provider level by default so the restored OAuth blob actually wins; pass keepProvider
1486
- // to skip that.
1487
- //
1488
- // Options:
1489
- // home - HOME override (selftest)
1490
- // keepProvider - leave `model_provider = "codex-lb"` selected (default: deselect)
1491
- // deleteBackup - remove ~/.codex/auth.chatgpt-backup.json after a successful restore
1492
- // (default: false; keeping it makes the next reconcile cycle a no-op clobber risk)
1493
- // force - restore even if the current auth.json shape isn't recognized
1494
1500
  export async function releaseCodexLbAuthHold(opts = {}) {
1495
1501
  const home = opts.home || process.env.HOME || os.homedir();
1496
1502
  const authPath = opts.authPath || codexAuthPath(home);
@@ -1514,9 +1520,6 @@ export async function releaseCodexLbAuthHold(opts = {}) {
1514
1520
  };
1515
1521
  }
1516
1522
  }
1517
- // Repeated "Use ChatGPT OAuth" is idempotent. If OAuth/browser auth is
1518
- // already active, a historical backup is unnecessary; only ensure that the
1519
- // codex-lb provider is no longer selected.
1520
1523
  const currentAuthMode = codexAuthModeSummary(currentAuthText);
1521
1524
  if (!opts.force && (currentAuthMode.mode === 'chatgpt_oauth' || currentAuthMode.mode === 'browser_marker')) {
1522
1525
  let provider = { ok: true, provider_unselected: false, provider_status: 'kept', provider_error: null };
@@ -1560,8 +1563,6 @@ export async function releaseCodexLbAuthHold(opts = {}) {
1560
1563
  provider_unselected: false
1561
1564
  };
1562
1565
  }
1563
- // If auth.json already looks like ChatGPT OAuth (user re-logged in some other way), don't
1564
- // clobber it — but still honor the deselect request so the OAuth blob takes effect.
1565
1566
  if (trimmedCurrent && hasChatgptOAuthTokens(currentAuthText) && !opts.force) {
1566
1567
  let provider = { ok: true, provider_unselected: false, provider_status: 'kept', provider_error: null };
1567
1568
  if (!opts.keepProvider) {
@@ -1585,8 +1586,6 @@ export async function releaseCodexLbAuthHold(opts = {}) {
1585
1586
  provider_error: provider.provider_error
1586
1587
  };
1587
1588
  }
1588
- // Refuse to clobber unfamiliar auth.json shapes unless forced. We expect either an empty file,
1589
- // the apikey shape we wrote during reconcile, or a stray `{"auth_mode":"browser"}` marker.
1590
1589
  if (!opts.force && trimmedCurrent) {
1591
1590
  const looksApikey = /"auth_mode"\s*:\s*"apikey"/.test(currentAuthText) && Boolean(parseCodexAuthApiKey(currentAuthText));
1592
1591
  const looksBrowserMarker = /^\{\s*"auth_mode"\s*:\s*"browser"\s*\}\s*$/.test(currentAuthText);
@@ -1618,8 +1617,6 @@ export async function releaseCodexLbAuthHold(opts = {}) {
1618
1617
  }
1619
1618
  let provider = { ok: true, provider_unselected: false, provider_status: 'kept', provider_error: null };
1620
1619
  if (!opts.keepProvider) {
1621
- // Auth was just restored to ChatGPT OAuth. Allow deselection even if a stale
1622
- // shared-key read would otherwise refuse, so release cannot leave OAuth + LB pin.
1623
1620
  const unselected = await unselectCodexLbProvider({
1624
1621
  ...opts,
1625
1622
  home,
@@ -1653,7 +1650,6 @@ export async function releaseCodexLbAuthHold(opts = {}) {
1653
1650
  backupRemoved = true;
1654
1651
  }
1655
1652
  catch {
1656
- // Non-fatal: the restore and provider deselection already landed.
1657
1653
  }
1658
1654
  }
1659
1655
  return {
@@ -1757,16 +1753,10 @@ export async function maybePromptCodexLbSetupForLaunch(args = [], opts = {}) {
1757
1753
  console.log('codex-lb auth synced with Codex CLI login cache.');
1758
1754
  const chainHealth = await checkCodexLbResponseChain(status, opts);
1759
1755
  if (!chainHealth.ok && chainHealth.chain_unhealthy) {
1760
- // `previous_response_not_found` is normal for stateless LB deployments that don't persist
1761
- // Responses across requests. The codex-lb provider still works fine — only the chained
1762
- // health probe fails. Keep codex-lb active and just warn.
1763
1756
  if (chainHealth.status === 'previous_response_not_found') {
1764
1757
  console.log('codex-lb response chain check: previous_response_id not persisted by the load balancer (this is normal for stateless deployments). Keeping codex-lb active.');
1765
1758
  return { status: 'present', ...status, codex_environment: codexEnvironment, codex_login: codexLogin, tool_catalog: toolCatalog, chain_health: chainHealth };
1766
1759
  }
1767
- // Hard chain failure (auth rejected, timeout, missing base URL, etc.). Don't silently
1768
- // demote a configured codex-lb to ChatGPT OAuth — surface the failure and let the user
1769
- // decide. Default keeps codex-lb (just press Enter).
1770
1760
  console.log(`codex-lb response chain check failed (${chainHealth.status}${chainHealth.error ? `: ${chainHealth.error}` : ''}).`);
1771
1761
  if (process.env.SKS_CODEX_LB_AUTOBYPASS === '1') {
1772
1762
  console.log('SKS_CODEX_LB_AUTOBYPASS=1 set; bypassing codex-lb to ChatGPT OAuth for this launch.');
@@ -1781,8 +1771,6 @@ export async function maybePromptCodexLbSetupForLaunch(args = [], opts = {}) {
1781
1771
  console.log('Keeping codex-lb active. To switch back to ChatGPT OAuth: `sks codex-lb release`.');
1782
1772
  return { status: 'present', ...status, codex_environment: codexEnvironment, codex_login: codexLogin, tool_catalog: toolCatalog, chain_health: chainHealth };
1783
1773
  }
1784
- // Non-interactive context with no opt-out env var. The user explicitly configured codex-lb,
1785
- // so default to keeping it active rather than silently swapping providers.
1786
1774
  console.log('Non-interactive launch + chain check failure. Keeping codex-lb active. Set SKS_CODEX_LB_AUTOBYPASS=1 to auto-bypass to ChatGPT OAuth.');
1787
1775
  return { status: 'present', ...status, codex_environment: codexEnvironment, codex_login: codexLogin, tool_catalog: toolCatalog, chain_health: chainHealth };
1788
1776
  }
@@ -1805,11 +1793,11 @@ export async function maybePromptCodexLbSetupForLaunch(args = [], opts = {}) {
1805
1793
  async function syncCodexLbProviderEnvironment(status = {}, opts = {}) {
1806
1794
  const home = opts.home || process.env.HOME || os.homedir();
1807
1795
  const envPath = opts.envPath || status.env_path || codexLbEnvPath(home);
1808
- const envText = await readText(envPath, '');
1809
- const apiKey = String(opts.apiKey || '').trim() || parseCodexLbEnvKey(envText);
1796
+ const envLoad = await loadCodexLbEnv({ ...opts, home, envPath });
1797
+ const apiKey = String(opts.apiKey || envLoad.secret_api_key || '').trim();
1810
1798
  if (!apiKey)
1811
1799
  return { ok: false, status: 'missing_env_key' };
1812
- const baseUrl = status.base_url || opts.baseUrl || parseCodexLbEnvBaseUrl(envText);
1800
+ const baseUrl = envLoad.base_url || opts.baseUrl || status.base_url;
1813
1801
  process.env.CODEX_LB_API_KEY = apiKey;
1814
1802
  if (baseUrl)
1815
1803
  process.env.CODEX_LB_BASE_URL = baseUrl;
@@ -1871,9 +1859,6 @@ async function inspectCodexLbMacLaunchEnvironment(baseUrl = '', opts = {}) {
1871
1859
  const result = await runProcess(launchctl, ['getenv', key], { timeoutMs: 3000, maxOutputBytes: 8192 });
1872
1860
  return result.code === 0 ? String(result.stdout || '').trim() : '';
1873
1861
  };
1874
- // launchctl can stall behind the same launchd/TCC boundary for every key.
1875
- // These reads are independent, so keep the worst case to one timeout window
1876
- // instead of three serial windows on `sks --mad` preflight.
1877
1862
  const [currentBaseUrl, currentApiKey, currentOpenRouterKey] = await Promise.all([
1878
1863
  readVar('CODEX_LB_BASE_URL'),
1879
1864
  readVar('CODEX_LB_API_KEY'),
@@ -23,13 +23,6 @@ export async function dispatch(args) {
23
23
  return await dispatchInner(argv);
24
24
  }
25
25
  catch (err) {
26
- // Final choke point: any uncaught bug anywhere in the dispatch chain (gate
27
- // checks, lazy command import, command run()) must never leak a raw stack
28
- // dump to the user as their "answer" — convert it to a structured, honest
29
- // failure instead. Every existing explicit error path above already sets
30
- // process.exitCode and returns normally (never throws), so this only ever
31
- // catches genuinely unexpected exceptions; it changes nothing about those
32
- // paths' exit codes or messages.
33
26
  const message = err instanceof Error ? err.message : String(err);
34
27
  if (err instanceof Error && err.stack)
35
28
  process.stderr.write(`${err.stack}\n`);
@@ -37,10 +30,6 @@ export async function dispatch(args) {
37
30
  process.stderr.write(`${message}\n`);
38
31
  process.exitCode = 1;
39
32
  const result = { ok: false, error: message, command: normalizeCommand(argv).rawCommand };
40
- // A --json caller depends on stdout always being exactly one JSON result
41
- // (this is the same non-interactive contract SKS_AGENT_MODE promises) — an
42
- // uncaught crash must not leave stdout empty, or a JSON.parse on the
43
- // consuming end breaks with no diagnosable output at all.
44
33
  if (argv.includes('--json'))
45
34
  console.log(JSON.stringify(result, null, 2));
46
35
  return result;
@@ -96,10 +85,6 @@ async function dispatchInner(argv) {
96
85
  process.exitCode = 1;
97
86
  return commandGate;
98
87
  }
99
- // 20차 P2-2: --help/-h/help must never wait on (or be blocked by) the
100
- // migration gate's lock — a stuck/contended migration lock previously
101
- // made `sks <cmd> --help` take the full MIGRATION_LOCK_WAIT_MS (20s) and
102
- // then fail, for a request that only wants usage text.
103
88
  const { ensureCurrentMigrationBeforeCommand } = await import('../core/update/update-migration-state.js');
104
89
  const migrationGate = await ensureCurrentMigrationBeforeCommand({
105
90
  command,
@@ -134,14 +119,7 @@ async function dispatchInner(argv) {
134
119
  throw new Error(`Command ${command} must export run(command, args)`);
135
120
  return mod.run(rawCommand || command, rest);
136
121
  }
137
- // --help/-h/help must skip the active-route and migration gates regardless
138
- // of where it appears in args — a pure usage-text request should never wait
139
- // on (or be blocked by) project state (20차 P2-2).
140
122
  function isHelpRequest(args) {
141
- // --help/-h are unambiguous flags wherever they appear; bare "help" is
142
- // only treated as the request when it's the subcommand position (args[0])
143
- // so an arbitrary value elsewhere (e.g. a commit message of "help") can't
144
- // accidentally bypass the gates.
145
123
  return args.includes('--help') || args.includes('-h') || String(args[0] || '').toLowerCase() === 'help';
146
124
  }
147
125
  async function ensureActiveRouteCommandGate(command, args) {