sneakoscope 7.0.3 → 7.1.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 (203) hide show
  1. package/README.md +7 -3
  2. package/config/codex-releases/{rust-v0.144.5.json → rust-v0.145.0.json} +14 -8
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/dist/cli/command-manifest-lite.js +2 -3
  6. package/dist/cli/command-registry.js +1 -3
  7. package/dist/cli/global-mode-router.js +5 -12
  8. package/dist/cli/install-helpers-codex-lb-config.js +63 -23
  9. package/dist/cli/install-helpers-install-support.js +1 -2
  10. package/dist/cli/install-helpers.js +13 -5
  11. package/dist/cli/router.js +22 -9
  12. package/dist/commands/codex-app.js +46 -2
  13. package/dist/commands/conflicts.js +26 -3
  14. package/dist/commands/doctor.js +39 -5
  15. package/dist/config/skills-manifest.json +52 -52
  16. package/dist/core/agent-bridge/agent-manifest.js +8 -2
  17. package/dist/core/agent-bridge/host-capability-runtime.js +86 -30
  18. package/dist/core/agents/agent-effort-policy.js +7 -7
  19. package/dist/core/agents/agent-roster.js +6 -5
  20. package/dist/core/agents/agent-scheduler.js +7 -5
  21. package/dist/core/agents/agent-schema.js +3 -1
  22. package/dist/core/agents/agent-task-graph.js +4 -1
  23. package/dist/core/agents/agent-work-partition.js +4 -2
  24. package/dist/core/auto-review.js +8 -1
  25. package/dist/core/codex/codex-config-toml.js +16 -2
  26. package/dist/core/codex/codex-startup-config-postcheck.js +5 -0
  27. package/dist/core/codex-app/codex-agent-type-probe.js +31 -24
  28. package/dist/core/codex-app/glm-model-profile.js +1 -1
  29. package/dist/core/codex-app/glm-profile-installer.js +75 -46
  30. package/dist/core/codex-app/glm-profile-schema.js +7 -11
  31. package/dist/core/codex-app/menubar/constants.js +1 -0
  32. package/dist/core/codex-app/menubar/launch-agent.js +37 -1
  33. package/dist/core/codex-app/openrouter-activate.js +217 -0
  34. package/dist/core/codex-app/openrouter-provider.js +89 -0
  35. package/dist/core/codex-app.js +14 -23
  36. package/dist/core/codex-compat/codex-capability-matrix.js +208 -0
  37. package/dist/core/codex-compat/codex-release-manifest.js +15 -8
  38. package/dist/core/codex-compat/codex-version-policy.js +77 -15
  39. package/dist/core/codex-control/codex-0144-capability.js +1 -1
  40. package/dist/core/codex-lb/codex-lb-env.js +15 -4
  41. package/dist/core/codex-runtime/codex-desktop-config-policy.js +3 -1
  42. package/dist/core/commands/basic-cli.js +2 -2
  43. package/dist/core/commands/mad-sks-command.js +55 -170
  44. package/dist/core/commands/naruto-command.js +9 -9
  45. package/dist/core/doctor/command-alias-cleanup.js +37 -9
  46. package/dist/core/doctor/current-project-guidance.js +6 -3
  47. package/dist/core/doctor/doctor-dirty-planner.js +1 -1
  48. package/dist/core/doctor/retired-auto-review-config.js +9 -1
  49. package/dist/core/doctor/retired-managed-residue-private.js +5 -3
  50. package/dist/core/doctor/retired-managed-residue-runtime.js +9 -1
  51. package/dist/core/doctor/skill-legacy-surface.js +351 -0
  52. package/dist/core/evaluation.js +3 -0
  53. package/dist/core/feature-fixtures.js +0 -1
  54. package/dist/core/harness-conflicts.js +191 -18
  55. package/dist/core/hooks-runtime/hook-context.js +47 -2
  56. package/dist/core/hooks-runtime/naruto-terminal-finalization.js +114 -1
  57. package/dist/core/hooks-runtime/official-subagent-lifecycle.js +1 -2
  58. package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +64 -4
  59. package/dist/core/hooks-runtime/subagent-skill-availability.js +101 -2
  60. package/dist/core/hooks-runtime.js +37 -10
  61. package/dist/core/init/skills.js +13 -4
  62. package/dist/core/init.js +6 -5
  63. package/dist/core/managed-assets/managed-assets-manifest.js +1 -1
  64. package/dist/core/naruto/naruto-concurrency-governor.js +18 -10
  65. package/dist/core/pipeline-internals/runtime-gates.js +7 -7
  66. package/dist/core/preflight/parallel-preflight-engine.js +1 -1
  67. package/dist/core/providers/openrouter/openrouter-account.js +306 -0
  68. package/dist/core/providers/openrouter/openrouter-client.js +2 -2
  69. package/dist/core/providers/openrouter/openrouter-error.js +7 -7
  70. package/dist/core/providers/openrouter/openrouter-provider-health.js +1 -1
  71. package/dist/core/providers/{glm/glm-request-cache.js → openrouter/openrouter-request-cache.js} +5 -3
  72. package/dist/core/providers/openrouter/openrouter-stream.js +2 -2
  73. package/dist/core/release/package-size-budget.js +2 -2
  74. package/dist/core/release/release-gate-affected-selector.js +3 -2
  75. package/dist/core/release/release-gate-contract.js +0 -7
  76. package/dist/core/release/release-pack-receipt.js +1 -0
  77. package/dist/core/routes/model-mode-router.js +10 -19
  78. package/dist/core/routes.js +2 -2
  79. package/dist/core/subagents/naruto-help-contract.js +2 -1
  80. package/dist/core/subagents/official-subagent-config.js +256 -32
  81. package/dist/core/subagents/official-subagent-preparation.js +22 -7
  82. package/dist/core/subagents/official-subagent-prompt.js +21 -0
  83. package/dist/core/subagents/official-subagent-runner.js +36 -2
  84. package/dist/core/subagents/role-model-preferences.js +179 -0
  85. package/dist/core/subagents/terminology.js +11 -6
  86. package/dist/core/subagents/thread-budget.js +1 -1
  87. package/dist/core/update/update-migration-state.js +100 -22
  88. package/dist/core/update/update-status.js +31 -3
  89. package/dist/core/version-manager.js +41 -4
  90. package/dist/core/version.js +1 -1
  91. package/dist/core/zellij/zellij-fake-adapter.js +16 -0
  92. package/dist/core/zellij/zellij-launcher.js +35 -9
  93. package/dist/core/zellij/zellij-pane-proof.js +3 -3
  94. package/dist/core/zellij/zellij-slot-telemetry.js +6 -4
  95. package/dist/native/sks-menubar/Resources/AppIcon.icns +0 -0
  96. package/dist/native/sks-menubar/Resources/SKSStatusTemplate.pdf +0 -0
  97. package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +61 -2
  98. package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +10 -3
  99. package/dist/native/sks-menubar/Sources/OverviewViewController.swift +140 -7
  100. package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +454 -0
  101. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +111 -36
  102. package/dist/native/sks-menubar/Sources/RemoteTelegramViewController.swift +5 -1
  103. package/dist/native/sks-menubar/Sources/SettingsViewController.swift +2 -2
  104. package/dist/native/sks-menubar/Sources/StatusItemController.swift +31 -6
  105. package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +1 -1
  106. package/dist/scripts/codex-0144-app-server-v2-check.js +5 -5
  107. package/dist/scripts/current-command-surface-check.js +1 -1
  108. package/dist/scripts/current-surface-update-e2e-check.js +2 -0
  109. package/dist/scripts/docs-truthfulness-check.js +4 -4
  110. package/dist/scripts/doctor-fix-production-blackbox.js +1 -1
  111. package/dist/scripts/doctor-startup-config-repair-blackbox.js +1 -1
  112. package/dist/scripts/official-subagent-workflow-check.js +1 -1
  113. package/dist/scripts/release-metadata-1-19-check.js +0 -1
  114. package/dist/scripts/sizecheck.js +2 -2
  115. package/dist/scripts/sks-menubar-install-check.js +1 -1
  116. package/package.json +6 -7
  117. package/release-gates.v2.json +439 -101
  118. package/schemas/codex/app-server-0.145/codex_app_server_protocol.v2.schemas.json +19611 -0
  119. package/dist/core/commands/glm-command.js +0 -93
  120. package/dist/core/providers/glm/bench/glm-bench-comparison.js +0 -47
  121. package/dist/core/providers/glm/bench/glm-bench-fixture.js +0 -64
  122. package/dist/core/providers/glm/bench/glm-bench-model-lock-proof.js +0 -52
  123. package/dist/core/providers/glm/bench/glm-bench-report.js +0 -74
  124. package/dist/core/providers/glm/bench/glm-benchmark-runner.js +0 -241
  125. package/dist/core/providers/glm/bench/glm-benchmark-types.js +0 -1
  126. package/dist/core/providers/glm/bench/glm-direct-bench-runner.js +0 -72
  127. package/dist/core/providers/glm/glm-52-profile.js +0 -82
  128. package/dist/core/providers/glm/glm-52-request.js +0 -73
  129. package/dist/core/providers/glm/glm-52-response-guard.js +0 -32
  130. package/dist/core/providers/glm/glm-52-settings.js +0 -67
  131. package/dist/core/providers/glm/glm-context-budget.js +0 -14
  132. package/dist/core/providers/glm/glm-context-cache.js +0 -8
  133. package/dist/core/providers/glm/glm-direct-run.js +0 -140
  134. package/dist/core/providers/glm/glm-interactive-launch.js +0 -4
  135. package/dist/core/providers/glm/glm-latency-trace.js +0 -39
  136. package/dist/core/providers/glm/glm-loop-guard.js +0 -30
  137. package/dist/core/providers/glm/glm-mad-launch.js +0 -128
  138. package/dist/core/providers/glm/glm-mad-mode.js +0 -269
  139. package/dist/core/providers/glm/glm-model-meta-cache.js +0 -18
  140. package/dist/core/providers/glm/glm-patch-apply.js +0 -72
  141. package/dist/core/providers/glm/glm-patch-parser.js +0 -18
  142. package/dist/core/providers/glm/glm-profile-resolver.js +0 -168
  143. package/dist/core/providers/glm/glm-readiness.js +0 -4
  144. package/dist/core/providers/glm/glm-reasoning-policy.js +0 -14
  145. package/dist/core/providers/glm/glm-run-controller.js +0 -65
  146. package/dist/core/providers/glm/glm-run-state.js +0 -10
  147. package/dist/core/providers/glm/glm-run-timeout.js +0 -30
  148. package/dist/core/providers/glm/glm-speed-context.js +0 -81
  149. package/dist/core/providers/glm/glm-speed-gate.js +0 -39
  150. package/dist/core/providers/glm/glm-speed-output-parser.js +0 -39
  151. package/dist/core/providers/glm/glm-tool-schema-cache.js +0 -18
  152. package/dist/core/providers/glm/naruto/glm-naruto-apply-transaction.js +0 -135
  153. package/dist/core/providers/glm/naruto/glm-naruto-artifacts.js +0 -1
  154. package/dist/core/providers/glm/naruto/glm-naruto-bench.js +0 -6
  155. package/dist/core/providers/glm/naruto/glm-naruto-budget.js +0 -44
  156. package/dist/core/providers/glm/naruto/glm-naruto-combined-patch.js +0 -48
  157. package/dist/core/providers/glm/naruto/glm-naruto-command.js +0 -100
  158. package/dist/core/providers/glm/naruto/glm-naruto-concurrency-governor.js +0 -37
  159. package/dist/core/providers/glm/naruto/glm-naruto-conflict-graph.js +0 -79
  160. package/dist/core/providers/glm/naruto/glm-naruto-critical-path.js +0 -50
  161. package/dist/core/providers/glm/naruto/glm-naruto-decomposer.js +0 -147
  162. package/dist/core/providers/glm/naruto/glm-naruto-file-lease.js +0 -22
  163. package/dist/core/providers/glm/naruto/glm-naruto-final-seal.js +0 -81
  164. package/dist/core/providers/glm/naruto/glm-naruto-finalizer.js +0 -22
  165. package/dist/core/providers/glm/naruto/glm-naruto-hunk-conflict.js +0 -15
  166. package/dist/core/providers/glm/naruto/glm-naruto-hunk-parser.js +0 -35
  167. package/dist/core/providers/glm/naruto/glm-naruto-isolation-policy.js +0 -37
  168. package/dist/core/providers/glm/naruto/glm-naruto-judge.js +0 -83
  169. package/dist/core/providers/glm/naruto/glm-naruto-merge-planner.js +0 -61
  170. package/dist/core/providers/glm/naruto/glm-naruto-metrics.js +0 -33
  171. package/dist/core/providers/glm/naruto/glm-naruto-orchestrator.js +0 -480
  172. package/dist/core/providers/glm/naruto/glm-naruto-parallelism-summary.js +0 -54
  173. package/dist/core/providers/glm/naruto/glm-naruto-patch-candidate-gate.js +0 -41
  174. package/dist/core/providers/glm/naruto/glm-naruto-patch-candidate-parser.js +0 -61
  175. package/dist/core/providers/glm/naruto/glm-naruto-patch-envelope.js +0 -54
  176. package/dist/core/providers/glm/naruto/glm-naruto-quorum.js +0 -36
  177. package/dist/core/providers/glm/naruto/glm-naruto-rate-limiter.js +0 -17
  178. package/dist/core/providers/glm/naruto/glm-naruto-repair-wave.js +0 -20
  179. package/dist/core/providers/glm/naruto/glm-naruto-requirement-coverage.js +0 -108
  180. package/dist/core/providers/glm/naruto/glm-naruto-requirement-ledger.js +0 -57
  181. package/dist/core/providers/glm/naruto/glm-naruto-scoreboard.js +0 -74
  182. package/dist/core/providers/glm/naruto/glm-naruto-secret-audit.js +0 -90
  183. package/dist/core/providers/glm/naruto/glm-naruto-session-id.js +0 -9
  184. package/dist/core/providers/glm/naruto/glm-naruto-shard-planner.js +0 -31
  185. package/dist/core/providers/glm/naruto/glm-naruto-stage-scheduler.js +0 -84
  186. package/dist/core/providers/glm/naruto/glm-naruto-targeted-checks.js +0 -75
  187. package/dist/core/providers/glm/naruto/glm-naruto-task-size-classifier.js +0 -11
  188. package/dist/core/providers/glm/naruto/glm-naruto-terminal.js +0 -43
  189. package/dist/core/providers/glm/naruto/glm-naruto-trace.js +0 -172
  190. package/dist/core/providers/glm/naruto/glm-naruto-types.js +0 -36
  191. package/dist/core/providers/glm/naruto/glm-naruto-usage-extractor.js +0 -30
  192. package/dist/core/providers/glm/naruto/glm-naruto-verifier-output.js +0 -30
  193. package/dist/core/providers/glm/naruto/glm-naruto-work-graph.js +0 -1
  194. package/dist/core/providers/glm/naruto/glm-naruto-worker-artifacts.js +0 -55
  195. package/dist/core/providers/glm/naruto/glm-naruto-worker-pool.js +0 -274
  196. package/dist/core/providers/glm/naruto/glm-naruto-worker-runtime.js +0 -421
  197. package/dist/core/providers/glm/naruto/glm-naruto-worker-scheduler.js +0 -177
  198. package/dist/core/providers/glm/naruto/glm-naruto-worker.js +0 -1
  199. package/dist/core/providers/glm/naruto/glm-naruto-worktree-cleanup.js +0 -19
  200. package/dist/core/providers/glm/naruto/glm-naruto-worktree-manager.js +0 -71
  201. package/dist/core/providers/glm/naruto/glm-naruto-worktree-worker.js +0 -73
  202. package/dist/core/providers/glm/naruto/glm-naruto-worktree.js +0 -61
  203. package/schemas/codex/app-server-0.144/codex_app_server_protocol.v2.schemas.json +0 -1
package/README.md CHANGED
@@ -6,6 +6,10 @@
6
6
 
7
7
  Proof-first orchestration for Codex CLI, ChatGPT Desktop, AI coding agents, multi-agent workflows, release verification, and the macOS menu bar.
8
8
 
9
+ <p align="center">
10
+ <img src="docs/assets/sks-logo.svg" alt="Sneakoscope Codex logo" width="160" height="160" />
11
+ </p>
12
+
9
13
  [![npm version](https://img.shields.io/npm/v/sneakoscope?color=cb3837&logo=npm)](https://www.npmjs.com/package/sneakoscope)
10
14
  [![node](https://img.shields.io/badge/node-%3E%3D20.11-339933?logo=node.js&logoColor=white)](#requirements)
11
15
  [![license](https://img.shields.io/badge/license-MIT-blue)](#license)
@@ -18,7 +22,7 @@ Proof-first orchestration for Codex CLI, ChatGPT Desktop, AI coding agents, mult
18
22
  Sneakoscope Codex (`sks`) is an open-source trust layer for Codex CLI and ChatGPT Desktop. It coordinates bounded AI coding agents, records machine-verifiable evidence, preserves project memory, and blocks release claims that are not supported by current tests or artifacts. Search visibility outcomes are measured separately; SKS does not promise rankings or traffic.
19
23
  <!-- END SKS SEARCH VISIBILITY MARKETING -->
20
24
 
21
- Current release: **SKS 7.0.3**, with the package compatibility baseline pinned to **Codex CLI 0.144.5**. It fixes codex-lb readiness, preserves provider/auth/model state across `sks update`, restores explicit Chat/Pro OAuth recovery, and adds a guarded Codex CLI updater that discovers newer stable operator releases independently. Prerelease `0.145.0-alpha` artifacts remain excluded from the pinned release contract. See [CHANGELOG.md](CHANGELOG.md).
25
+ Current release: **SKS 7.1.0**, with the package preferred Codex channel at **CLI 0.145.0**. SKS stays version-agnostic: older hosts keep working where capabilities allow, while Menu Bar / Center induce updates to the preferred latest. It resolves managed SKS skills from the authoritative global install, preserves a runnable Naruto child slot when `max_threads=2`, and keeps current-version Menu Bar repair transactional so stamped generations remain verifiable. Naruto uses stable opt-in multi-agent V2 when the host exposes it. See [CHANGELOG.md](CHANGELOG.md).
22
26
 
23
27
  ## What 7.0.0 Ships
24
28
 
@@ -66,13 +70,13 @@ The SKS menu bar shows the installed Codex CLI version and latest known version.
66
70
 
67
71
  `$sks-naruto` and `sks naruto run "task" --agents 8 --max-threads 12` use Codex official subagents. Standalone and Codex App tasks that request project-host database, spreadsheet, or render tools require the non-persistent `--trusted-project` flag after the operator reviews the checkout; an App session ID scopes evidence but does not grant trust. The parent is GPT-5.6 Sol Max. Tiny mechanical `worker` slices use Luna Max; ordinary UI, logic, backend, and native coding uses Sol High; review, testing, debugging, architecture, integration, security, database, research, release, and other judgment-sensitive work uses Sol Max; long-context scans and direct Computer Use, Browser/Chrome, or image-generation execution uses Terra Medium. Mixed execution/judgment work is split when possible, and unsplittable judgment defaults to Sol Max.
68
72
 
69
- Fresh SKS-owned project config uses `max_threads = 12`, `max_depth = 1`, `job_max_runtime_seconds = 1200`, and `interrupt_message = true`. `max_depth = 1` means subagents cannot spawn nested subagents. Explicit user limits are preserved, and larger requests run in waves.
73
+ Fresh SKS-owned project config enables Codex 0.145+ multi-agent V2 with `agents.max_concurrent_threads_per_session = 12`, `features.multi_agent_v2.max_concurrent_threads_per_session = 13`, `max_depth = 1`, and `interrupt_message = true`. Nested delegation remains forbidden. Explicit user limits are preserved, and larger requests run in waves.
70
74
 
71
75
  Gates are task-profile aware: greetings and answer-only turns create no mission gate; tiny work gets minimal verification; parallel work gets scoped ownership and verification; high-risk work keeps the full safety gates. `SubagentStart`/`SubagentStop` prove lifecycle only. Completion also requires `subagent-parent-summary.json` with one trustworthy structured outcome per thread, correlated with `subagent-events.jsonl` and `subagent-evidence.json`.
72
76
 
73
77
  Every installed Codex hook runs one common Naruto decision gate. The gate records `none`, `generic_naruto`, or `route_owned`: Answer, DFix, Wiki, Computer Use, Goal, and simple Git/control turns stay lightweight; ordinary non-trivial work defaults to two independent official subagents; critical work spanning at least three risk domains may use three. Research, AutoResearch, and QA-Loop retain their own exact orchestration contracts instead of receiving a second generic fan-out. Explicit `--agents N` remains authoritative.
74
78
 
75
- SKS installs twenty-five narrow project custom agents, including native AppKit, toolchain, protocol, runtime-reliability, TriWiki-evidence, long-context, Computer Use, Browser/Chrome, and image-generation specialists. Delegation prompts inject at most the three roles recommended for the current goal rather than serializing the full catalog, so expanding role coverage does not serialize the full inventory into every prompt. TriWiki context is also bounded and query-aware: ordinary work receives up to four trust/hydration anchors and complex, parallel, or high-risk work receives up to six, with source hydration required before relying on lower-trust hints. In CLI Zellij mode, the right side is a live observability surface rather than a static lane reservation: one monitor plus one viewport by default (maximum three) shows official thread role/model, redacted live phase/task/file updates from rollout-compatible Codex 0.144.1+ sessions while the current release baseline remains 0.144.5, plus `running`, `verifying`, and trustworthy parent-verdict completion/failure states. Rollout activity is display-only and never completion proof.
79
+ SKS installs twenty-five narrow project custom agents, including native AppKit, toolchain, protocol, runtime-reliability, TriWiki-evidence, long-context, Computer Use, Browser/Chrome, and image-generation specialists. Delegation prompts inject at most the three roles recommended for the current goal rather than serializing the full catalog, so expanding role coverage does not serialize the full inventory into every prompt. TriWiki context is also bounded and query-aware: ordinary work receives up to four trust/hydration anchors and complex, parallel, or high-risk work receives up to six, with source hydration required before relying on lower-trust hints. In CLI Zellij mode, the right side is a live observability surface rather than a static lane reservation: one monitor plus one viewport by default (maximum three) shows official thread role/model, redacted live phase/task/file updates from rollout-compatible Codex 0.144.1+ sessions while the current release baseline remains 0.145.0, plus `running`, `verifying`, and trustworthy parent-verdict completion/failure states. Rollout activity is display-only and never completion proof.
76
80
 
77
81
  Official subagent requests use `--agents`; removed scheduler, pool, backend, and model flags fail closed.
78
82
 
@@ -1,14 +1,18 @@
1
1
  {
2
2
  "schema": "sks.codex-release-manifest.v1",
3
- "targetTag": "rust-v0.144.5",
4
- "requiredCliVersion": "0.144.5",
5
- "sdkVersion": "0.144.5",
6
- "minimumSupportedVersion": "0.144.5",
3
+ "targetTag": "rust-v0.145.0",
4
+ "requiredCliVersion": "0.145.0",
5
+ "preferredCliVersion": "0.145.0",
6
+ "sdkVersion": "0.145.0",
7
+ "minimumSupportedVersion": "0.133.0",
8
+ "narutoCapabilityFloorVersion": "0.145.0",
7
9
  "protocolMode": "app-server-v2",
8
- "generatedSchemaSha256": "2b3f14fa2e728f77a16385ff39f3a1d85ab255c1020498a85c1c0fb24f3d2f3c",
9
- "upstreamCommit": "rust-v0.144.5",
10
+ "generatedSchemaSha256": "57b4a85429300c37f2f2e5fc8662c3dbeb88d51419e25becb8501c46348e1ecf",
11
+ "upstreamCommit": "rust-v0.145.0",
10
12
  "featurePolicies": {
11
- "multiAgentMode": "probe",
13
+ "multiAgentMode": "delegate",
14
+ "multiAgentV2": "delegate",
15
+ "agentsMaxConcurrentThreads": "delegate",
12
16
  "indexedWebSearch": "probe",
13
17
  "currentTimeRead": "wrap",
14
18
  "threadListSearchRead": "probe",
@@ -16,7 +20,9 @@
16
20
  "terminalSubagentErrorPropagation": "probe",
17
21
  "execMcpTransientRecovery": "probe",
18
22
  "remoteNativeEnvironment": "probe",
19
- "rolloutTokenBudget": "probe"
23
+ "rolloutTokenBudget": "probe",
24
+ "mcpStartupToolTimeouts": "wrap",
25
+ "gpt56TerraLunaSolRouting": "delegate"
20
26
  },
21
27
  "requiredRealProbes": [
22
28
  "runtime_identity",
@@ -76,7 +76,7 @@ dependencies = [
76
76
 
77
77
  [[package]]
78
78
  name = "sks-core"
79
- version = "7.0.3"
79
+ version = "7.1.0"
80
80
  dependencies = [
81
81
  "serde_json",
82
82
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sks-core"
3
- version = "7.0.3"
3
+ version = "7.1.0"
4
4
  edition = "2021"
5
5
 
6
6
  [dependencies]
@@ -16,7 +16,7 @@ export const COMMAND_MANIFEST_LITE = [
16
16
  { name: 'update', summary: 'Inspect, review, apply, or roll back the global SKS update', maturity: 'stable' },
17
17
  { name: 'uninstall', summary: 'Uninstall SKS global skills, hooks, config, menu bar, and optional project residue', maturity: 'stable', allowedDuringActiveRoute: true },
18
18
  { name: 'update-check', summary: 'Show the shared SKS, Codex CLI, and Menu Bar update status', maturity: 'stable', readonly: true, skipMigrationGate: true, allowedDuringActiveRoute: true, diagnostic: true },
19
- { name: 'mcp', summary: 'Manage scoped Codex MCP configuration', maturity: 'beta' },
19
+ { name: 'mcp', summary: 'Manage scoped Codex MCP configuration', maturity: 'beta', skipMigrationGate: true },
20
20
  { name: 'wizard', summary: 'Open setup wizard help', maturity: 'stable' },
21
21
  { name: 'usage', summary: 'Show focused usage topic', maturity: 'stable', readonly: true, allowedDuringActiveRoute: true, diagnostic: true },
22
22
  { name: 'quickstart', summary: 'Show quickstart flow', maturity: 'stable' },
@@ -34,7 +34,7 @@ export const COMMAND_MANIFEST_LITE = [
34
34
  { name: 'codex-app', summary: 'Check Codex App readiness', maturity: 'beta' },
35
35
  { name: 'codex-native', summary: 'Inspect Codex Native broker and routing readiness', maturity: 'beta' },
36
36
  { name: 'codex-lb', summary: 'Inspect codex-lb status and circuit health', maturity: 'beta' },
37
- { name: 'menubar', summary: 'Inspect/install/restart/uninstall SKS menu bar', maturity: 'beta', allowedDuringActiveRoute: true, diagnostic: true },
37
+ { name: 'menubar', summary: 'Inspect/install/restart/uninstall SKS menu bar', maturity: 'beta', skipMigrationGate: true, allowedDuringActiveRoute: true, diagnostic: true },
38
38
  { name: 'remote', summary: 'Inspect official Remote readiness and run the proof-aware SSH stdio worker', maturity: 'beta' },
39
39
  { name: 'telegram', summary: 'Inspect and run the private proof-aware Telegram Hub', maturity: 'beta' },
40
40
  { name: 'hooks', summary: 'Explain and inspect Codex hooks', maturity: 'beta', skipMigrationGate: true },
@@ -45,7 +45,6 @@ export const COMMAND_MANIFEST_LITE = [
45
45
  { name: 'zellij-slot-column-anchor', summary: 'Render the compact SLOTS anchor pane for first-slot-down Zellij stacks', maturity: 'beta' },
46
46
  { name: 'zellij', summary: 'Inspect Zellij runtime status and explain repair (no auto-install)', maturity: 'beta', skipMigrationGate: true, allowedDuringActiveRoute: true, diagnostic: true },
47
47
  { name: 'mad-sks', summary: 'MAD-SKS scoped permission modifier + SQL-plane execution', maturity: 'beta', mutatesRouteState: true },
48
- { name: 'glm', summary: 'Run GLM 5.2 MAD mode through OpenRouter', maturity: 'beta' },
49
48
  { name: 'auto-review', summary: 'Manage auto-review profile', maturity: 'beta' },
50
49
  { name: 'dollar-commands', summary: 'List Codex App dollar commands', maturity: 'stable', readonly: true, skipMigrationGate: true, allowedDuringActiveRoute: true, diagnostic: true },
51
50
  { name: 'fast-mode', summary: 'Toggle SKS Fast mode default for dollar-command routes', maturity: 'stable', skipMigrationGate: true },
@@ -135,7 +135,7 @@ const COMMAND_DEFINITIONS = {
135
135
  activeRoutePolicy: 'always'
136
136
  }),
137
137
  'update-check': readOnly(entry('stable', 'Show the shared SKS, Codex CLI, and Menu Bar update status', 'dist/core/commands/basic-cli.js', basicArgs('updateCheckCommand'))),
138
- mcp: entry('beta', 'Manage scoped Codex MCP configuration', 'dist/core/commands/mcp-config-command.js', argsCommand(() => import('../core/commands/mcp-config-command.js'), 'mcpConfigCommand', 'dist/core/commands/mcp-config-command.js')),
138
+ mcp: skipMigrationGate(entry('beta', 'Manage scoped Codex MCP configuration', 'dist/core/commands/mcp-config-command.js', argsCommand(() => import('../core/commands/mcp-config-command.js'), 'mcpConfigCommand', 'dist/core/commands/mcp-config-command.js'))),
139
139
  wizard: entry('stable', 'Open setup wizard help', 'dist/core/commands/basic-cli.js', basicNoArgs('quickstartCommand')),
140
140
  usage: readOnly(entry('stable', 'Show focused usage topic', 'dist/core/commands/basic-cli.js', basicArgs('usageCommand'))),
141
141
  quickstart: entry('stable', 'Show quickstart flow', 'dist/core/commands/basic-cli.js', basicNoArgs('quickstartCommand')),
@@ -164,7 +164,6 @@ const COMMAND_DEFINITIONS = {
164
164
  'zellij-slot-column-anchor': entry('beta', 'Render the compact SLOTS anchor pane for first-slot-down Zellij stacks', 'dist/commands/zellij-slot-column-anchor.js', directCommand(() => import('../commands/zellij-slot-column-anchor.js'), 'dist/commands/zellij-slot-column-anchor.js')),
165
165
  zellij: activeRouteDiagnostic(entry('beta', 'Inspect Zellij runtime status and explain repair (no auto-install)', 'dist/commands/zellij.js', directCommand(() => import('../commands/zellij.js'), 'dist/commands/zellij.js'))),
166
166
  'mad-sks': routeStateMutator(entry('beta', 'MAD-SKS scoped permission modifier + SQL-plane execution', 'dist/commands/mad-sks.js', directCommand(() => import('../commands/mad-sks.js'), 'dist/commands/mad-sks.js')), ['mad-sks-gate.json']),
167
- glm: entry('beta', 'Run GLM 5.2 MAD mode through OpenRouter', 'dist/core/commands/glm-command.js', argsCommand(() => import('../core/commands/glm-command.js'), 'glmCommand', 'dist/core/commands/glm-command.js')),
168
167
  'auto-review': entry('beta', 'Manage auto-review profile', 'dist/commands/auto-review.js', directCommand(() => import('../commands/auto-review.js'), 'dist/commands/auto-review.js')),
169
168
  'dollar-commands': entry('stable', 'List Codex App dollar commands', 'dist/core/commands/basic-cli.js', basicArgs('dollarCommandsCommand')),
170
169
  'fast-mode': skipMigrationGate(entry('stable', 'Toggle SKS Fast mode default for dollar-command routes', 'dist/core/commands/fast-mode-command.js', argsCommand(() => import('../core/commands/fast-mode-command.js'), 'fastModeCommand', 'dist/core/commands/fast-mode-command.js'))),
@@ -235,7 +234,6 @@ export const COMMANDS = applyCommandContractOverrides(COMMAND_DEFINITIONS, {
235
234
  risk: 'R1', latency: 'long', supportsJson: true, remoteAllowed: true, telegramAllowed: true,
236
235
  inputProfile: 'gates', requiredCapabilities: ['project.git', 'proof.gates']
237
236
  },
238
- glm: { latency: 'long' },
239
237
  harness: { latency: 'long' },
240
238
  'image-ux-review': { latency: 'long' },
241
239
  loop: { latency: 'long' },
@@ -17,18 +17,11 @@ const RETIRED_GLOBAL_EXECUTION_OPTION_NAMES = new Set([
17
17
  '--mad-swarm-backend',
18
18
  '--mad-swarm-prompt',
19
19
  '--tmux-smoke',
20
- '--require-tmux-smoke'
20
+ '--require-tmux-smoke',
21
+ '--glm'
21
22
  ]);
22
23
  export function detectGlobalMode(args = []) {
23
- if (!args.length || RESERVED_COMMANDS.has(String(args[0])))
24
- return null;
25
- const hasMad = args.includes('--mad');
26
- const hasGlm = args.includes('--glm');
27
- if (hasMad && hasGlm)
28
- return { kind: 'mad-glm', args: stripGlobalModeFlags(args) };
29
- if (hasGlm && !hasMad && String(args[0]).startsWith('-')) {
30
- return { kind: 'glm-without-mad', args: stripGlobalModeFlags(args) };
31
- }
24
+ void args;
32
25
  return null;
33
26
  }
34
27
  export function stripGlobalModeFlags(args) {
@@ -50,7 +43,7 @@ export function glmWithoutMadResult() {
50
43
  ok: false,
51
44
  status: 'blocked',
52
45
  mode: 'glm',
53
- reason: 'glm_requires_mad',
54
- hint: 'use sks --mad --glm'
46
+ reason: 'glm_mad_removed',
47
+ hint: 'use SKS Center Providers or sks codex-app use-openrouter --model <id>'
55
48
  };
56
49
  }
@@ -1,8 +1,9 @@
1
1
  import path from 'node:path';
2
2
  import os from 'node:os';
3
3
  import { ensureDir, readText } from '../core/fsx.js';
4
- import { GLM_CODEX_CONFIG_PROFILE_ID, GLM_CODEX_CONFIG_PROVIDER_ID, GLM_CODEX_CONFIG_REASONING_PROFILES } from '../core/providers/glm/glm-52-profile.js';
5
- import { GLM_52_OPENROUTER_MODEL } from '../core/providers/glm/glm-52-settings.js';
4
+ import { GLM_CODEX_CONFIG_PROVIDER_ID, GLM_52_OPENROUTER_MODEL, OPENROUTER_AUTH_COMMAND, OPENROUTER_AUTH_REFRESH_INTERVAL_MS, OPENROUTER_AUTH_TIMEOUT_MS, openRouterAuthCommandArgs, OPENROUTER_DEFAULT_PROFILE_ID, RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS } from '../core/codex-app/openrouter-provider.js';
5
+ import { openRouterSecretPaths, resolveOpenRouterApiKey } from '../core/providers/openrouter/openrouter-secret-store.js';
6
+ import { reconcileRetiredSksConfigText } from '../core/auto-review.js';
6
7
  import { removeTopLevelTomlKeyIfValue, safeWriteCodexConfigToml, upsertTopLevelTomlString, upsertTomlTable } from '../core/codex-runtime/codex-desktop-config-policy.js';
7
8
  import { codexLbConfigPath, normalizeCodexLbBaseUrl } from './install-helpers-codex-lb-shared.js';
8
9
  export function upsertCodexLbConfig(text = '', baseUrl, selectDefault = true) {
@@ -58,48 +59,50 @@ export function removeCodexLbSharedOpenAiRouting(text = '', baseUrl = '') {
58
59
  text: removeTopLevelLine(withoutValue, CODEX_LB_SHARED_OPENAI_ROUTING_MARKER)
59
60
  };
60
61
  }
61
- export function upsertCodexAppGlmConfig(text = '') {
62
+ export function upsertCodexAppGlmConfig(text = '', input = {}) {
62
63
  let next = String(text || '');
64
+ const authEnv = { ...(input.env || process.env), ...(input.home ? { HOME: input.home } : {}) };
65
+ const authArgs = openRouterAuthCommandArgs(openRouterSecretPaths(authEnv).keyPath);
63
66
  const providerBlock = [
64
67
  `[model_providers.${GLM_CODEX_CONFIG_PROVIDER_ID}]`,
65
68
  'name = "OpenRouter"',
66
69
  'base_url = "https://openrouter.ai/api/v1"',
67
70
  'wire_api = "responses"',
68
- 'env_key = "OPENROUTER_API_KEY"',
69
71
  'requires_openai_auth = false'
70
72
  ].join('\n');
71
73
  next = upsertTomlTable(next, `model_providers.${GLM_CODEX_CONFIG_PROVIDER_ID}`, providerBlock);
72
- for (const profile of GLM_CODEX_CONFIG_REASONING_PROFILES) {
73
- const profileBlock = [
74
- `[profiles.${profile.id}]`,
75
- `model_provider = "${GLM_CODEX_CONFIG_PROVIDER_ID}"`,
76
- `model = "${GLM_52_OPENROUTER_MODEL}"`,
77
- `model_reasoning_effort = "${profile.reasoning_effort}"`,
78
- 'service_tier = "default"',
79
- 'approval_policy = "on-request"'
80
- ].join('\n');
81
- next = upsertTomlTable(next, `profiles.${profile.id}`, profileBlock);
82
- }
74
+ const authBlock = [
75
+ `[model_providers.${GLM_CODEX_CONFIG_PROVIDER_ID}.auth]`,
76
+ `command = ${JSON.stringify(OPENROUTER_AUTH_COMMAND)}`,
77
+ `args = [${authArgs.map((value) => JSON.stringify(value)).join(', ')}]`,
78
+ `timeout_ms = ${OPENROUTER_AUTH_TIMEOUT_MS}`,
79
+ `refresh_interval_ms = ${OPENROUTER_AUTH_REFRESH_INTERVAL_MS}`
80
+ ].join('\n');
81
+ next = upsertTomlTable(next, `model_providers.${GLM_CODEX_CONFIG_PROVIDER_ID}.auth`, authBlock);
82
+ next = next.replace(new RegExp(`\\n+\\[model_providers\\.${GLM_CODEX_CONFIG_PROVIDER_ID}\\.auth\\]`), `\n\n[model_providers.${GLM_CODEX_CONFIG_PROVIDER_ID}.auth]`);
83
+ next = reconcileRetiredSksConfigText(next).text;
83
84
  return `${next.trim()}\n`;
84
85
  }
85
86
  export async function ensureGlobalCodexAppGlmProfile(opts = {}) {
86
- if (process.env.SKS_SKIP_CODEX_GLM_PROFILE_REPAIR === '1' && opts.force !== true) {
87
+ const env = opts.env || process.env;
88
+ if (env.SKS_SKIP_CODEX_GLM_PROFILE_REPAIR === '1' && opts.force !== true) {
87
89
  return { ok: true, status: 'skipped', reason: 'SKS_SKIP_CODEX_GLM_PROFILE_REPAIR=1' };
88
90
  }
89
- const home = opts.home || process.env.HOME || os.homedir();
91
+ const home = opts.home || env.HOME || os.homedir();
90
92
  const configPath = opts.configPath || codexLbConfigPath(home);
91
93
  try {
92
94
  await ensureDir(path.dirname(configPath));
93
95
  const current = await readText(configPath, '');
94
- const next = upsertCodexAppGlmConfig(current);
95
- const safeWrite = await safeWriteCodexConfigToml(configPath, current, next, 'glm-profile');
96
+ const next = upsertCodexAppGlmConfig(current, { home, env: opts.env });
97
+ const safeWrite = await safeWriteCodexConfigToml(configPath, current, next, 'openrouter-provider');
96
98
  return {
97
99
  ...safeWrite,
98
100
  status: safeWrite.status === 'written' ? 'updated' : safeWrite.status,
99
101
  provider: GLM_CODEX_CONFIG_PROVIDER_ID,
100
102
  model: GLM_52_OPENROUTER_MODEL,
101
- codex_config_profile: GLM_CODEX_CONFIG_PROFILE_ID,
102
- reasoning_profiles: GLM_CODEX_CONFIG_REASONING_PROFILES.map((profile) => profile.id)
103
+ codex_config_profile: OPENROUTER_DEFAULT_PROFILE_ID,
104
+ reasoning_profiles: [],
105
+ retired_glm_profiles: [...RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS]
103
106
  };
104
107
  }
105
108
  catch (err) {
@@ -110,10 +113,47 @@ export async function ensureGlobalCodexAppGlmProfile(opts = {}) {
110
113
  error: err.message,
111
114
  provider: GLM_CODEX_CONFIG_PROVIDER_ID,
112
115
  model: GLM_52_OPENROUTER_MODEL,
113
- codex_config_profile: GLM_CODEX_CONFIG_PROFILE_ID,
114
- reasoning_profiles: GLM_CODEX_CONFIG_REASONING_PROFILES.map((profile) => profile.id)
116
+ codex_config_profile: OPENROUTER_DEFAULT_PROFILE_ID,
117
+ reasoning_profiles: [],
118
+ retired_glm_profiles: [...RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS]
119
+ };
120
+ }
121
+ }
122
+ export async function ensureStoredOpenRouterProviderDuringInstall(opts = {}) {
123
+ const home = opts.home || opts.env?.HOME || process.env.HOME || os.homedir();
124
+ const env = { ...(opts.env || process.env), HOME: home };
125
+ const key = await resolveOpenRouterApiKey({ env });
126
+ if (!key.key) {
127
+ return {
128
+ schema: 'sks.openrouter-provider-upgrade-repair.v1',
129
+ ok: true,
130
+ status: 'skipped',
131
+ reason: 'openrouter_key_missing',
132
+ key_present: false,
133
+ key_source: null,
134
+ blockers: [],
135
+ warnings: key.warnings
115
136
  };
116
137
  }
138
+ const repair = await ensureGlobalCodexAppGlmProfile({
139
+ ...opts,
140
+ home,
141
+ env
142
+ });
143
+ const ok = repair?.ok !== false;
144
+ return {
145
+ schema: 'sks.openrouter-provider-upgrade-repair.v1',
146
+ ok,
147
+ status: ok ? repair?.status || 'present' : 'failed',
148
+ reason: ok ? 'stored_openrouter_key_provider_reconciled' : 'stored_openrouter_key_provider_repair_failed',
149
+ key_present: true,
150
+ key_source: key.source,
151
+ config_path: repair?.config_path || opts.configPath || codexLbConfigPath(home),
152
+ provider: GLM_CODEX_CONFIG_PROVIDER_ID,
153
+ blockers: ok ? [] : ['openrouter_provider_repair_failed'],
154
+ warnings: key.warnings,
155
+ repair
156
+ };
117
157
  }
118
158
  export function detectCodexLbSetupDrift(state = {}) {
119
159
  const drift = [];
@@ -18,8 +18,7 @@ import { recordCodexLbHealthEvent } from '../core/codex-lb-circuit.js';
18
18
  import { loadCodexLbEnv, writeCodexLbKeychain, codexLbMetadataPath } from '../core/codex-lb/codex-lb-env.js';
19
19
  import { codexLbToolCatalogPath, ensureCodexLbToolCatalog } from '../core/codex-lb/codex-lb-tool-catalog.js';
20
20
  import { codexLbToolOutputRecoveryNotChecked, codexLbToolOutputRecoveryNotSelected, codexLbToolOutputRecoveryOverrideAcknowledged, probeCodexLbToolOutputRecovery } from '../core/codex-lb/codex-lb-tool-output-recovery.js';
21
- import { GLM_CODEX_CONFIG_PROFILE_ID, GLM_CODEX_CONFIG_PROVIDER_ID, GLM_CODEX_CONFIG_REASONING_PROFILES } from '../core/providers/glm/glm-52-profile.js';
22
- import { GLM_52_OPENROUTER_MODEL } from '../core/providers/glm/glm-52-settings.js';
21
+ import { GLM_CODEX_CONFIG_PROFILE_ID, GLM_CODEX_CONFIG_PROVIDER_ID, GLM_CODEX_CONFIG_REASONING_PROFILES, GLM_52_OPENROUTER_MODEL } from '../core/codex-app/openrouter-provider.js';
23
22
  import { buildCodexLbSetupPlan, codexLbPersistenceSummary, installCodexLbShellProfileSnippet, selectedCodexLbPersistenceModes } from '../core/codex-lb/codex-lb-setup.js';
24
23
  import { extractTomlTable, writeCodexConfigGuarded } from '../core/codex/codex-config-guard.js';
25
24
  import { ensureGlobalCodexFastModeDuringInstall, ensureTrailingNewline, normalizeCodexFastModeUiConfig, removeTopLevelTomlKeyIfValue, safeWriteCodexConfigToml, upsertTopLevelTomlString, upsertTomlTable } from '../core/codex-runtime/codex-desktop-config-policy.js';
@@ -18,8 +18,7 @@ import { recordCodexLbHealthEvent } from '../core/codex-lb-circuit.js';
18
18
  import { loadCodexLbEnv, writeCodexLbKeychain, codexLbMetadataPath } from '../core/codex-lb/codex-lb-env.js';
19
19
  import { codexLbToolCatalogPath, ensureCodexLbToolCatalog } from '../core/codex-lb/codex-lb-tool-catalog.js';
20
20
  import { codexLbToolOutputRecoveryNotChecked, codexLbToolOutputRecoveryNotSelected, codexLbToolOutputRecoveryOverrideAcknowledged, probeCodexLbToolOutputRecovery } from '../core/codex-lb/codex-lb-tool-output-recovery.js';
21
- import { GLM_CODEX_CONFIG_PROFILE_ID, GLM_CODEX_CONFIG_PROVIDER_ID, GLM_CODEX_CONFIG_REASONING_PROFILES } from '../core/providers/glm/glm-52-profile.js';
22
- import { GLM_52_OPENROUTER_MODEL } from '../core/providers/glm/glm-52-settings.js';
21
+ import { GLM_CODEX_CONFIG_PROFILE_ID, GLM_CODEX_CONFIG_PROVIDER_ID, GLM_CODEX_CONFIG_REASONING_PROFILES, GLM_52_OPENROUTER_MODEL } from '../core/codex-app/openrouter-provider.js';
23
22
  import { buildCodexLbSetupPlan, codexLbPersistenceSummary, installCodexLbShellProfileSnippet, selectedCodexLbPersistenceModes } from '../core/codex-lb/codex-lb-setup.js';
24
23
  import { extractTomlTable, writeCodexConfigGuarded } from '../core/codex/codex-config-guard.js';
25
24
  import { ensureGlobalCodexFastModeDuringInstall, ensureTrailingNewline, normalizeCodexFastModeUiConfig, removeTopLevelTomlKeyIfValue, safeWriteCodexConfigToml, upsertTopLevelTomlString, upsertTomlTable } from '../core/codex-runtime/codex-desktop-config-policy.js';
@@ -28,7 +27,7 @@ import { repairCodexImagegen } from '../core/doctor/imagegen-repair.js';
28
27
  import { canAskYesNo, compareVersions, hasCodexUnstableFeatureWarningSuppression, hasDeprecatedCodexHooksFeatureFlag, hasTopLevelCodexModeLock, isProjectSetupCandidate } from './install-tool-helpers.js';
29
28
  import { checkCodexLbResponseChain } from './install-helpers-codex-lb-chain.js';
30
29
  import { CODEX_LB_CANONICAL_FAST_SERVICE_TIER, CODEX_LB_PROVIDER_ENV_KEY, CODEX_LB_PROVIDER_NAME, askPostinstallQuestion, codexAuthChatgptBackupPath, codexAuthPath, codexLbConfigPath, codexLbEnvPath, hasTopLevelCodexLbSelected, normalizeCodexLbBaseUrl, parseCodexLbEnvKey, redactSecretText } from './install-helpers-codex-lb-shared.js';
31
- import { appliedCodexLbPersistenceModes, captureCodexLbSetupWriteState, codexLbSharedOpenAiRoutingState, detectCodexLbSetupDrift, ensureGlobalCodexAppGlmProfile, parseCodexLbEnvBaseUrl, parseCodexSharedLoginApiKey, removeCodexLbSharedOpenAiRouting, sha256Text, shellSingleQuote, upsertCodexAppGlmConfig, upsertCodexLbConfig, upsertCodexLbSharedOpenAiRouting } from './install-helpers-codex-lb-config.js';
30
+ import { appliedCodexLbPersistenceModes, captureCodexLbSetupWriteState, codexLbSharedOpenAiRoutingState, detectCodexLbSetupDrift, ensureGlobalCodexAppGlmProfile, ensureStoredOpenRouterProviderDuringInstall, parseCodexLbEnvBaseUrl, parseCodexSharedLoginApiKey, removeCodexLbSharedOpenAiRouting, sha256Text, shellSingleQuote, upsertCodexAppGlmConfig, upsertCodexLbConfig, upsertCodexLbSharedOpenAiRouting } from './install-helpers-codex-lb-config.js';
32
31
  import { ensureCodexImagegenDuringInstall, ensureGlobalCodexSkillsDuringInstall, ensureGlobalContext7DuringInstall, ensureGlobalGetdesignSkillDuringInstall, ensureSksCommandDuringInstall } from './install-helpers-install-support.js';
33
32
  function packagedSksEntrypoint() {
34
33
  return path.join(packageRoot(), 'dist', 'bin', 'sks.js');
@@ -90,6 +89,15 @@ export async function postinstall({ bootstrap, args = [] }) {
90
89
  console.log(`Codex App Fast mode: skipped (${fastModeRepair.reason}).`);
91
90
  else if (fastModeRepair.status === 'failed')
92
91
  console.log(`Codex App Fast mode: auto repair failed. Run \`sks setup\`. ${fastModeRepair.error || ''}`.trim());
92
+ const openRouterProviderRepair = await ensureStoredOpenRouterProviderDuringInstall();
93
+ if (openRouterProviderRepair.status === 'updated')
94
+ console.log('OpenRouter provider: repaired for the stored key (credentials and active model were preserved).');
95
+ else if (openRouterProviderRepair.status === 'present')
96
+ console.log('OpenRouter provider: stored-key configuration already compatible.');
97
+ else if (openRouterProviderRepair.status === 'skipped')
98
+ console.log('OpenRouter provider: no stored key; no provider configuration was added.');
99
+ else if (openRouterProviderRepair.status === 'failed')
100
+ console.log('OpenRouter provider: stored key was preserved, but provider repair failed. Run `sks doctor --fix`.');
93
101
  const imagegenRepair = await ensureCodexImagegenDuringInstall();
94
102
  if (imagegenRepair.status === 'ready')
95
103
  console.log('Codex App Image Gen: ready ($imagegen/gpt-image-2 detected).');
@@ -259,7 +267,7 @@ async function reportPostinstallCodexLbAuth(snapshot = null) {
259
267
  async function postinstallHarnessConflictNotice(conflictScan) {
260
268
  console.log('\nSneakoscope Codex package installed, but SKS setup is blocked.');
261
269
  console.log(formatHarnessConflictReport(conflictScan, { includePrompt: false }));
262
- console.log('\nWhat this means: npm can finish installing the package, but `sks setup` and `sks doctor --fix` will refuse to activate SKS until the conflicting harness is removed with human approval.');
270
+ console.log('\nWhat this means: npm can finish installing the package. Conflicting OMX/DCodex markers must be removed explicitly with `sks conflicts cleanup --yes` before `sks setup`, `sks doctor --fix`, or `sks update` can proceed.');
263
271
  console.log('No files were removed by postinstall.');
264
272
  console.log('Cleanup requires a human-approved Codex App session. Keep the model selected in Codex and use high reasoning effort.');
265
273
  if (shouldAskPostinstallQuestion()) {
@@ -1925,7 +1933,7 @@ export { checkContext7, ensureCodexCliTool, ensureMadLaunchDependencies, ensureR
1925
1933
  export { codexFastModeDesktopStatus, ensureGlobalCodexFastModeDuringInstall, normalizeCodexFastModeUiConfig, safeWriteCodexConfigToml } from '../core/codex-runtime/codex-desktop-config-policy.js';
1926
1934
  export { checkRequiredSkills, context7GlobalMcpStatus, ensureCodexImagegenDuringInstall, ensureGlobalCodexSkillsDuringInstall, ensureProjectContext7Config, ensureSksCommandDuringInstall, globalCodexSkillsRoot, selftestSksShimRepair } from './install-helpers-install-support.js';
1927
1935
  export { askPostinstallQuestion, codexLbConfigPath, codexLbEnvPath, normalizeCodexLbBaseUrl } from './install-helpers-codex-lb-shared.js';
1928
- export { ensureGlobalCodexAppGlmProfile, upsertCodexAppGlmConfig, upsertCodexLbConfig } from './install-helpers-codex-lb-config.js';
1936
+ export { ensureGlobalCodexAppGlmProfile, ensureStoredOpenRouterProviderDuringInstall, upsertCodexAppGlmConfig, upsertCodexLbConfig } from './install-helpers-codex-lb-config.js';
1929
1937
  export { checkCodexLbResponseChain } from './install-helpers-codex-lb-chain.js';
1930
1938
  export { selftestCodexLb } from './install-helpers-codex-lb-selftest.js';
1931
1939
  function escapeRegExp(value) {
@@ -1,5 +1,5 @@
1
1
  import { COMMAND_ALIASES_LITE, COMMAND_MANIFEST_BY_NAME, COMMAND_NAME_SET, } from './command-manifest-lite.js';
2
- import { detectGlobalMode, glmWithoutMadResult } from './global-mode-router.js';
2
+ import { findRetiredGlobalExecutionArgumentErrors } from './global-mode-router.js';
3
3
  export function isCommandName(value) {
4
4
  return COMMAND_NAME_SET.has(value);
5
5
  }
@@ -36,15 +36,21 @@ export async function dispatch(args) {
36
36
  }
37
37
  }
38
38
  async function dispatchInner(argv) {
39
- const globalMode = detectGlobalMode(argv);
40
- if (globalMode?.kind === 'mad-glm') {
41
- const mod = await import('../core/commands/glm-command.js');
42
- return mod.glmCommand(globalMode.args);
43
- }
44
- if (globalMode?.kind === 'glm-without-mad') {
45
- const result = glmWithoutMadResult();
46
- console.error(`GLM mode requires MAD: ${result.hint}`);
39
+ const retiredGlm = findRetiredGlobalExecutionArgumentErrors(argv).filter((item) => item.includes('--glm'));
40
+ if (retiredGlm.length && argv.some((arg) => arg === '--glm' || String(arg).startsWith('--glm='))) {
41
+ const hint = 'GLM MAD CLI was removed. Use SKS Center Providers or: sks codex-app use-openrouter --model <id>';
42
+ console.error(hint);
47
43
  process.exitCode = 1;
44
+ const result = {
45
+ ok: false,
46
+ status: 'blocked',
47
+ mode: 'glm',
48
+ reason: 'glm_mad_removed',
49
+ hint,
50
+ blockers: retiredGlm
51
+ };
52
+ if (argv.includes('--json'))
53
+ console.log(JSON.stringify(result, null, 2));
48
54
  return result;
49
55
  }
50
56
  const { command, rawCommand, args: rest } = normalizeCommand(argv);
@@ -186,9 +192,16 @@ function printHandledCommandBlock(result) {
186
192
  }
187
193
  export function safeReadOnlySubcommand(command, args) {
188
194
  const sub = String(args[0] || '').toLowerCase();
195
+ const nested = String(args[1] || '').toLowerCase();
189
196
  if (command === 'naruto' && ['status', 'subagents', 'proof'].includes(sub)) {
190
197
  return !args.some((arg) => ['--fix', '--yes', '-y', '--write', '--apply', '--execute', '--force', '--real'].includes(String(arg)));
191
198
  }
199
+ if (command === 'mcp' && sub === 'config' && ['list', 'test', 'backups', 'show'].includes(nested)) {
200
+ return !args.some((arg) => ['--fix', '--yes', '-y', '--write', '--apply', '--execute', '--force', '--real'].includes(String(arg)));
201
+ }
202
+ if (command === 'remote' && ['readiness', 'status', 'show'].includes(sub)) {
203
+ return !args.some((arg) => ['--fix', '--yes', '-y', '--write', '--apply', '--execute', '--force', '--real'].includes(String(arg)));
204
+ }
192
205
  if (!['status', 'show', 'list', 'observe', 'watch', 'doctor', 'help'].includes(sub))
193
206
  return false;
194
207
  return !args.some((arg) => ['--fix', '--yes', '-y', '--write', '--apply', '--execute', '--force', '--real'].includes(String(arg)));
@@ -11,8 +11,12 @@ import { buildCodexHookLifecycle } from '../core/codex-app/codex-hook-lifecycle.
11
11
  import { resolveCodexAppExecutionProfile } from '../core/codex-app/codex-app-execution-profile.js';
12
12
  import { repairCodexNativeManagedAssets } from '../core/codex-native/codex-native-repair-transaction.js';
13
13
  import { doctorCodexAppGlmProfile, installCodexAppGlmProfile } from '../core/codex-app/glm-profile-installer.js';
14
+ import { openRouterStatus, useOpenRouter } from '../core/codex-app/openrouter-activate.js';
15
+ import { OPENROUTER_DEFAULT_MODEL } from '../core/codex-app/openrouter-provider.js';
14
16
  import { promptForOpenRouterKeyHidden, writeStoredOpenRouterKey } from '../core/providers/openrouter/openrouter-secret-store.js';
17
+ import { compactOpenRouterModelsResult, listOpenRouterModels, testOpenRouterConnection } from '../core/providers/openrouter/openrouter-account.js';
15
18
  import { restartCodexApp } from '../core/codex-app/codex-app-restart.js';
19
+ import { resetRoleModelPreference, roleModelPreferencesStatus, setRoleModelPreference } from '../core/subagents/role-model-preferences.js';
16
20
  export async function run(_command, args = []) {
17
21
  const action = args[0] || 'check';
18
22
  if (action === 'restart')
@@ -36,7 +40,7 @@ export async function run(_command, args = []) {
36
40
  if (action === 'glm-profile') {
37
41
  const subcommand = args[1] || 'doctor';
38
42
  const root = await sksRoot();
39
- const result = subcommand === 'install' || subcommand === 'repair'
43
+ const result = subcommand === 'install' || subcommand === 'repair' || subcommand === 'remove'
40
44
  ? await installCodexAppGlmProfile({ root, apply: true })
41
45
  : await doctorCodexAppGlmProfile({ root });
42
46
  return printCodexAppResult(args, result);
@@ -58,6 +62,7 @@ export async function run(_command, args = []) {
58
62
  key_preview: record.key_preview,
59
63
  raw_key_recorded: false,
60
64
  secret_store: 'sks-openrouter-secret-store',
65
+ selected: false,
61
66
  glm_profile: profile,
62
67
  restart_app: restart,
63
68
  blockers: [...(profile.blockers || []), ...(restart.blockers || [])],
@@ -65,6 +70,44 @@ export async function run(_command, args = []) {
65
70
  };
66
71
  return printCodexAppResult(args, result);
67
72
  }
73
+ if (action === 'use-openrouter' || action === 'use-or') {
74
+ const root = await sksRoot();
75
+ const model = readOption(args, '--model', OPENROUTER_DEFAULT_MODEL);
76
+ const result = await useOpenRouter({
77
+ root,
78
+ model,
79
+ restartApp: flag(args, '--restart-app') || flag(args, '--restart') || !flag(args, '--no-restart-app')
80
+ });
81
+ return printCodexAppResult(args, result);
82
+ }
83
+ if (action === 'openrouter-status') {
84
+ const result = await openRouterStatus({});
85
+ return printCodexAppResult(args, result);
86
+ }
87
+ if (action === 'openrouter-models') {
88
+ const models = await listOpenRouterModels({});
89
+ const result = flag(args, '--ids-only') ? compactOpenRouterModelsResult(models) : models;
90
+ return printCodexAppResult(args, result);
91
+ }
92
+ if (action === 'openrouter-test') {
93
+ const result = await testOpenRouterConnection({ model: readOption(args, '--model', '') });
94
+ return printCodexAppResult(args, result);
95
+ }
96
+ if (action === 'role-models') {
97
+ return printCodexAppResult(args, await roleModelPreferencesStatus());
98
+ }
99
+ if (action === 'set-role-model') {
100
+ const result = await setRoleModelPreference({
101
+ role: readOption(args, '--role', ''),
102
+ model: readOption(args, '--model', ''),
103
+ reasoning: readOption(args, '--reasoning', '')
104
+ });
105
+ return printCodexAppResult(args, result);
106
+ }
107
+ if (action === 'reset-role-model') {
108
+ const result = await resetRoleModelPreference({ role: readOption(args, '--role', '') });
109
+ return printCodexAppResult(args, result);
110
+ }
68
111
  if (action === 'product-design' || action === 'design-product' || action === 'ensure-product-design') {
69
112
  const checkOnly = flag(args, '--check-only') || flag(args, '--no-install');
70
113
  const status = await codexProductDesignPluginStatus({
@@ -125,7 +168,8 @@ export async function run(_command, args = []) {
125
168
  process.exitCode = 1;
126
169
  return;
127
170
  }
128
- console.error('Usage: sks codex-app check|status|harness-matrix|skill-sync|agent-role-sync|init-deep|hook-lifecycle|execution-profile|glm-profile [install|doctor]|set-openrouter-key [--api-key-stdin]|product-design [--check-only]|ensure-product-design|chrome-extension|pat status|remote-control [--json]');
171
+ console.error('Usage: sks codex-app check|status|harness-matrix|skill-sync|agent-role-sync|init-deep|hook-lifecycle|execution-profile|set-openrouter-key [--api-key-stdin]|use-openrouter --model <id>|openrouter-status|openrouter-models [--ids-only]|openrouter-test [--model <id>]|role-models|set-role-model --role <name> --model <id> --reasoning <effort>|reset-role-model --role <name>|product-design [--check-only]|ensure-product-design|chrome-extension|pat status|remote-control [--json]');
172
+ console.error('Note: glm-profile is retired (strips leftover Desktop GLM profiles); use set-openrouter-key / use-openrouter.');
129
173
  process.exitCode = 1;
130
174
  }
131
175
  async function readOpenRouterKeyFromArgs(args = []) {
@@ -1,16 +1,39 @@
1
1
  import { projectRoot } from '../core/fsx.js';
2
- import { formatHarnessConflictReport, llmHarnessCleanupPrompt, scanHarnessConflicts } from '../core/harness-conflicts.js';
2
+ import { cleanupOtherHarnessConflicts, formatHarnessConflictReport, llmHarnessCleanupPrompt, scanHarnessConflicts } from '../core/harness-conflicts.js';
3
3
  import { flag } from '../cli/args.js';
4
4
  import { printJson } from '../cli/output.js';
5
5
  export async function run(_command, args = []) {
6
6
  const action = args[0] || 'check';
7
- const scan = await scanHarnessConflicts(await projectRoot());
7
+ const root = await projectRoot();
8
+ if (action === 'cleanup') {
9
+ if (!flag(args, '--yes') && !flag(args, '--json')) {
10
+ process.exitCode = 1;
11
+ console.error('Refusing cleanup without --yes. Re-run: sks conflicts cleanup --yes');
12
+ return { ok: false, status: 'confirmation_required' };
13
+ }
14
+ const cleanup = await cleanupOtherHarnessConflicts(root);
15
+ if (flag(args, '--json'))
16
+ return printJson(cleanup);
17
+ console.log(cleanup.ok
18
+ ? `Quarantined ${cleanup.cleaned.length} OMX/DCodex conflict(s).`
19
+ : `Cleanup incomplete: ${cleanup.remaining.length} conflict(s) remain.`);
20
+ for (const row of cleanup.cleaned)
21
+ console.log(`- ${row.action}: ${row.path}`);
22
+ for (const row of cleanup.errors)
23
+ console.error(`- error: ${row.path}: ${row.error}`);
24
+ if (!cleanup.ok)
25
+ process.exitCode = 1;
26
+ return cleanup;
27
+ }
28
+ const scan = await scanHarnessConflicts(root);
8
29
  const result = { ...scan, cleanup_prompt: scan.hard_block ? llmHarnessCleanupPrompt(scan) : null };
9
30
  if (flag(args, '--json'))
10
31
  return printJson(result);
11
32
  if (action === 'prompt')
12
33
  return console.log(result.cleanup_prompt || '');
13
34
  console.log(formatHarnessConflictReport(scan));
14
- if (scan.hard_block)
35
+ if (scan.hard_block) {
36
+ console.log('\nAutomatic cleanup: sks conflicts cleanup --yes');
15
37
  process.exitCode = 1;
38
+ }
16
39
  }