sneakoscope 7.0.3 → 7.0.5

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 (187) hide show
  1. package/README.md +3 -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 +1 -2
  6. package/dist/cli/command-registry.js +0 -2
  7. package/dist/cli/global-mode-router.js +5 -12
  8. package/dist/cli/install-helpers-codex-lb-config.js +10 -18
  9. package/dist/cli/install-helpers-install-support.js +1 -2
  10. package/dist/cli/install-helpers.js +2 -3
  11. package/dist/cli/router.js +22 -9
  12. package/dist/commands/codex-app.js +20 -2
  13. package/dist/commands/conflicts.js +26 -3
  14. package/dist/commands/doctor.js +22 -17
  15. package/dist/config/skills-manifest.json +52 -52
  16. package/dist/core/agents/agent-effort-policy.js +7 -7
  17. package/dist/core/agents/agent-roster.js +6 -5
  18. package/dist/core/agents/agent-scheduler.js +7 -5
  19. package/dist/core/agents/agent-schema.js +3 -1
  20. package/dist/core/agents/agent-task-graph.js +4 -1
  21. package/dist/core/agents/agent-work-partition.js +4 -2
  22. package/dist/core/auto-review.js +8 -1
  23. package/dist/core/codex/codex-startup-config-postcheck.js +5 -0
  24. package/dist/core/codex-app/codex-agent-type-probe.js +31 -24
  25. package/dist/core/codex-app/glm-model-profile.js +1 -1
  26. package/dist/core/codex-app/glm-profile-installer.js +40 -41
  27. package/dist/core/codex-app/glm-profile-schema.js +7 -11
  28. package/dist/core/codex-app/menubar/constants.js +1 -0
  29. package/dist/core/codex-app/menubar/launch-agent.js +37 -1
  30. package/dist/core/codex-app/openrouter-activate.js +152 -0
  31. package/dist/core/codex-app/openrouter-provider.js +82 -0
  32. package/dist/core/codex-app.js +14 -23
  33. package/dist/core/codex-compat/codex-capability-matrix.js +208 -0
  34. package/dist/core/codex-compat/codex-release-manifest.js +15 -8
  35. package/dist/core/codex-compat/codex-version-policy.js +77 -15
  36. package/dist/core/codex-control/codex-0144-capability.js +1 -1
  37. package/dist/core/codex-lb/codex-lb-env.js +15 -4
  38. package/dist/core/codex-runtime/codex-desktop-config-policy.js +3 -1
  39. package/dist/core/commands/basic-cli.js +22 -16
  40. package/dist/core/commands/mad-sks-command.js +55 -170
  41. package/dist/core/commands/naruto-command.js +9 -9
  42. package/dist/core/doctor/command-alias-cleanup.js +37 -9
  43. package/dist/core/doctor/current-project-guidance.js +6 -3
  44. package/dist/core/doctor/doctor-dirty-planner.js +1 -1
  45. package/dist/core/doctor/retired-auto-review-config.js +9 -1
  46. package/dist/core/doctor/retired-managed-residue-private.js +5 -3
  47. package/dist/core/doctor/retired-managed-residue-runtime.js +9 -1
  48. package/dist/core/doctor/skill-legacy-surface.js +351 -0
  49. package/dist/core/evaluation.js +3 -0
  50. package/dist/core/feature-fixtures.js +0 -1
  51. package/dist/core/harness-conflicts.js +177 -18
  52. package/dist/core/hooks-runtime/official-subagent-lifecycle.js +1 -2
  53. package/dist/core/hooks-runtime.js +16 -5
  54. package/dist/core/init/skills.js +1 -1
  55. package/dist/core/init.js +4 -5
  56. package/dist/core/managed-assets/managed-assets-manifest.js +1 -1
  57. package/dist/core/naruto/naruto-concurrency-governor.js +18 -10
  58. package/dist/core/pipeline-internals/runtime-gates.js +7 -7
  59. package/dist/core/preflight/parallel-preflight-engine.js +1 -1
  60. package/dist/core/providers/openrouter/openrouter-client.js +2 -2
  61. package/dist/core/providers/openrouter/openrouter-provider-health.js +1 -1
  62. package/dist/core/providers/{glm/glm-request-cache.js → openrouter/openrouter-request-cache.js} +5 -3
  63. package/dist/core/providers/openrouter/openrouter-stream.js +2 -2
  64. package/dist/core/release/package-size-budget.js +2 -2
  65. package/dist/core/release/release-gate-contract.js +0 -7
  66. package/dist/core/release/release-pack-receipt.js +1 -0
  67. package/dist/core/routes/model-mode-router.js +10 -19
  68. package/dist/core/routes.js +2 -2
  69. package/dist/core/subagents/naruto-help-contract.js +2 -1
  70. package/dist/core/subagents/official-subagent-config.js +256 -32
  71. package/dist/core/subagents/official-subagent-preparation.js +5 -2
  72. package/dist/core/subagents/official-subagent-runner.js +36 -2
  73. package/dist/core/subagents/terminology.js +11 -6
  74. package/dist/core/subagents/thread-budget.js +1 -1
  75. package/dist/core/update/update-migration-state.js +92 -22
  76. package/dist/core/version-manager.js +41 -4
  77. package/dist/core/version.js +1 -1
  78. package/dist/core/zellij/zellij-fake-adapter.js +16 -0
  79. package/dist/core/zellij/zellij-launcher.js +35 -9
  80. package/dist/core/zellij/zellij-pane-proof.js +3 -3
  81. package/dist/core/zellij/zellij-slot-telemetry.js +6 -4
  82. package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +61 -2
  83. package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +10 -3
  84. package/dist/native/sks-menubar/Sources/OverviewViewController.swift +55 -3
  85. package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +76 -0
  86. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +62 -29
  87. package/dist/native/sks-menubar/Sources/RemoteTelegramViewController.swift +5 -1
  88. package/dist/native/sks-menubar/Sources/SettingsViewController.swift +2 -2
  89. package/dist/native/sks-menubar/Sources/StatusItemController.swift +28 -2
  90. package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +1 -1
  91. package/dist/scripts/codex-0144-app-server-v2-check.js +5 -5
  92. package/dist/scripts/current-command-surface-check.js +1 -1
  93. package/dist/scripts/current-surface-update-e2e-check.js +2 -0
  94. package/dist/scripts/docs-truthfulness-check.js +4 -4
  95. package/dist/scripts/doctor-fix-production-blackbox.js +1 -1
  96. package/dist/scripts/doctor-startup-config-repair-blackbox.js +1 -1
  97. package/dist/scripts/official-subagent-workflow-check.js +1 -1
  98. package/dist/scripts/release-metadata-1-19-check.js +0 -1
  99. package/dist/scripts/sizecheck.js +2 -2
  100. package/package.json +6 -7
  101. package/release-gates.v2.json +426 -93
  102. package/schemas/codex/app-server-0.145/codex_app_server_protocol.v2.schemas.json +19611 -0
  103. package/dist/core/commands/glm-command.js +0 -93
  104. package/dist/core/providers/glm/bench/glm-bench-comparison.js +0 -47
  105. package/dist/core/providers/glm/bench/glm-bench-fixture.js +0 -64
  106. package/dist/core/providers/glm/bench/glm-bench-model-lock-proof.js +0 -52
  107. package/dist/core/providers/glm/bench/glm-bench-report.js +0 -74
  108. package/dist/core/providers/glm/bench/glm-benchmark-runner.js +0 -241
  109. package/dist/core/providers/glm/bench/glm-benchmark-types.js +0 -1
  110. package/dist/core/providers/glm/bench/glm-direct-bench-runner.js +0 -72
  111. package/dist/core/providers/glm/glm-52-profile.js +0 -82
  112. package/dist/core/providers/glm/glm-52-request.js +0 -73
  113. package/dist/core/providers/glm/glm-52-response-guard.js +0 -32
  114. package/dist/core/providers/glm/glm-52-settings.js +0 -67
  115. package/dist/core/providers/glm/glm-context-budget.js +0 -14
  116. package/dist/core/providers/glm/glm-context-cache.js +0 -8
  117. package/dist/core/providers/glm/glm-direct-run.js +0 -140
  118. package/dist/core/providers/glm/glm-interactive-launch.js +0 -4
  119. package/dist/core/providers/glm/glm-latency-trace.js +0 -39
  120. package/dist/core/providers/glm/glm-loop-guard.js +0 -30
  121. package/dist/core/providers/glm/glm-mad-launch.js +0 -128
  122. package/dist/core/providers/glm/glm-mad-mode.js +0 -269
  123. package/dist/core/providers/glm/glm-model-meta-cache.js +0 -18
  124. package/dist/core/providers/glm/glm-patch-apply.js +0 -72
  125. package/dist/core/providers/glm/glm-patch-parser.js +0 -18
  126. package/dist/core/providers/glm/glm-profile-resolver.js +0 -168
  127. package/dist/core/providers/glm/glm-readiness.js +0 -4
  128. package/dist/core/providers/glm/glm-reasoning-policy.js +0 -14
  129. package/dist/core/providers/glm/glm-run-controller.js +0 -65
  130. package/dist/core/providers/glm/glm-run-state.js +0 -10
  131. package/dist/core/providers/glm/glm-run-timeout.js +0 -30
  132. package/dist/core/providers/glm/glm-speed-context.js +0 -81
  133. package/dist/core/providers/glm/glm-speed-gate.js +0 -39
  134. package/dist/core/providers/glm/glm-speed-output-parser.js +0 -39
  135. package/dist/core/providers/glm/glm-tool-schema-cache.js +0 -18
  136. package/dist/core/providers/glm/naruto/glm-naruto-apply-transaction.js +0 -135
  137. package/dist/core/providers/glm/naruto/glm-naruto-artifacts.js +0 -1
  138. package/dist/core/providers/glm/naruto/glm-naruto-bench.js +0 -6
  139. package/dist/core/providers/glm/naruto/glm-naruto-budget.js +0 -44
  140. package/dist/core/providers/glm/naruto/glm-naruto-combined-patch.js +0 -48
  141. package/dist/core/providers/glm/naruto/glm-naruto-command.js +0 -100
  142. package/dist/core/providers/glm/naruto/glm-naruto-concurrency-governor.js +0 -37
  143. package/dist/core/providers/glm/naruto/glm-naruto-conflict-graph.js +0 -79
  144. package/dist/core/providers/glm/naruto/glm-naruto-critical-path.js +0 -50
  145. package/dist/core/providers/glm/naruto/glm-naruto-decomposer.js +0 -147
  146. package/dist/core/providers/glm/naruto/glm-naruto-file-lease.js +0 -22
  147. package/dist/core/providers/glm/naruto/glm-naruto-final-seal.js +0 -81
  148. package/dist/core/providers/glm/naruto/glm-naruto-finalizer.js +0 -22
  149. package/dist/core/providers/glm/naruto/glm-naruto-hunk-conflict.js +0 -15
  150. package/dist/core/providers/glm/naruto/glm-naruto-hunk-parser.js +0 -35
  151. package/dist/core/providers/glm/naruto/glm-naruto-isolation-policy.js +0 -37
  152. package/dist/core/providers/glm/naruto/glm-naruto-judge.js +0 -83
  153. package/dist/core/providers/glm/naruto/glm-naruto-merge-planner.js +0 -61
  154. package/dist/core/providers/glm/naruto/glm-naruto-metrics.js +0 -33
  155. package/dist/core/providers/glm/naruto/glm-naruto-orchestrator.js +0 -480
  156. package/dist/core/providers/glm/naruto/glm-naruto-parallelism-summary.js +0 -54
  157. package/dist/core/providers/glm/naruto/glm-naruto-patch-candidate-gate.js +0 -41
  158. package/dist/core/providers/glm/naruto/glm-naruto-patch-candidate-parser.js +0 -61
  159. package/dist/core/providers/glm/naruto/glm-naruto-patch-envelope.js +0 -54
  160. package/dist/core/providers/glm/naruto/glm-naruto-quorum.js +0 -36
  161. package/dist/core/providers/glm/naruto/glm-naruto-rate-limiter.js +0 -17
  162. package/dist/core/providers/glm/naruto/glm-naruto-repair-wave.js +0 -20
  163. package/dist/core/providers/glm/naruto/glm-naruto-requirement-coverage.js +0 -108
  164. package/dist/core/providers/glm/naruto/glm-naruto-requirement-ledger.js +0 -57
  165. package/dist/core/providers/glm/naruto/glm-naruto-scoreboard.js +0 -74
  166. package/dist/core/providers/glm/naruto/glm-naruto-secret-audit.js +0 -90
  167. package/dist/core/providers/glm/naruto/glm-naruto-session-id.js +0 -9
  168. package/dist/core/providers/glm/naruto/glm-naruto-shard-planner.js +0 -31
  169. package/dist/core/providers/glm/naruto/glm-naruto-stage-scheduler.js +0 -84
  170. package/dist/core/providers/glm/naruto/glm-naruto-targeted-checks.js +0 -75
  171. package/dist/core/providers/glm/naruto/glm-naruto-task-size-classifier.js +0 -11
  172. package/dist/core/providers/glm/naruto/glm-naruto-terminal.js +0 -43
  173. package/dist/core/providers/glm/naruto/glm-naruto-trace.js +0 -172
  174. package/dist/core/providers/glm/naruto/glm-naruto-types.js +0 -36
  175. package/dist/core/providers/glm/naruto/glm-naruto-usage-extractor.js +0 -30
  176. package/dist/core/providers/glm/naruto/glm-naruto-verifier-output.js +0 -30
  177. package/dist/core/providers/glm/naruto/glm-naruto-work-graph.js +0 -1
  178. package/dist/core/providers/glm/naruto/glm-naruto-worker-artifacts.js +0 -55
  179. package/dist/core/providers/glm/naruto/glm-naruto-worker-pool.js +0 -274
  180. package/dist/core/providers/glm/naruto/glm-naruto-worker-runtime.js +0 -421
  181. package/dist/core/providers/glm/naruto/glm-naruto-worker-scheduler.js +0 -177
  182. package/dist/core/providers/glm/naruto/glm-naruto-worker.js +0 -1
  183. package/dist/core/providers/glm/naruto/glm-naruto-worktree-cleanup.js +0 -19
  184. package/dist/core/providers/glm/naruto/glm-naruto-worktree-manager.js +0 -71
  185. package/dist/core/providers/glm/naruto/glm-naruto-worktree-worker.js +0 -73
  186. package/dist/core/providers/glm/naruto/glm-naruto-worktree.js +0 -61
  187. package/schemas/codex/app-server-0.144/codex_app_server_protocol.v2.schemas.json +0 -1
package/README.md CHANGED
@@ -18,7 +18,7 @@ Proof-first orchestration for Codex CLI, ChatGPT Desktop, AI coding agents, mult
18
18
  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
19
  <!-- END SKS SEARCH VISIBILITY MARKETING -->
20
20
 
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).
21
+ Current release: **SKS 7.0.5**, 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
22
 
23
23
  ## What 7.0.0 Ships
24
24
 
@@ -66,13 +66,13 @@ The SKS menu bar shows the installed Codex CLI version and latest known version.
66
66
 
67
67
  `$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
68
 
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.
69
+ 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
70
 
71
71
  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
72
 
73
73
  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
74
 
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.
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.145.0, plus `running`, `verifying`, and trustworthy parent-verdict completion/failure states. Rollout activity is display-only and never completion proof.
76
76
 
77
77
  Official subagent requests use `--agents`; removed scheduler, pool, backend, and model flags fail closed.
78
78
 
@@ -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.0.5"
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.0.5"
4
4
  edition = "2021"
5
5
 
6
6
  [dependencies]
@@ -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 },
@@ -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,8 @@
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_DEFAULT_PROFILE_ID, RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS } from '../core/codex-app/openrouter-provider.js';
5
+ import { reconcileRetiredSksConfigText } from '../core/auto-review.js';
6
6
  import { removeTopLevelTomlKeyIfValue, safeWriteCodexConfigToml, upsertTopLevelTomlString, upsertTomlTable } from '../core/codex-runtime/codex-desktop-config-policy.js';
7
7
  import { codexLbConfigPath, normalizeCodexLbBaseUrl } from './install-helpers-codex-lb-shared.js';
8
8
  export function upsertCodexLbConfig(text = '', baseUrl, selectDefault = true) {
@@ -69,17 +69,7 @@ export function upsertCodexAppGlmConfig(text = '') {
69
69
  'requires_openai_auth = false'
70
70
  ].join('\n');
71
71
  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
- }
72
+ next = reconcileRetiredSksConfigText(next).text;
83
73
  return `${next.trim()}\n`;
84
74
  }
85
75
  export async function ensureGlobalCodexAppGlmProfile(opts = {}) {
@@ -92,14 +82,15 @@ export async function ensureGlobalCodexAppGlmProfile(opts = {}) {
92
82
  await ensureDir(path.dirname(configPath));
93
83
  const current = await readText(configPath, '');
94
84
  const next = upsertCodexAppGlmConfig(current);
95
- const safeWrite = await safeWriteCodexConfigToml(configPath, current, next, 'glm-profile');
85
+ const safeWrite = await safeWriteCodexConfigToml(configPath, current, next, 'openrouter-provider');
96
86
  return {
97
87
  ...safeWrite,
98
88
  status: safeWrite.status === 'written' ? 'updated' : safeWrite.status,
99
89
  provider: GLM_CODEX_CONFIG_PROVIDER_ID,
100
90
  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)
91
+ codex_config_profile: OPENROUTER_DEFAULT_PROFILE_ID,
92
+ reasoning_profiles: [],
93
+ retired_glm_profiles: [...RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS]
103
94
  };
104
95
  }
105
96
  catch (err) {
@@ -110,8 +101,9 @@ export async function ensureGlobalCodexAppGlmProfile(opts = {}) {
110
101
  error: err.message,
111
102
  provider: GLM_CODEX_CONFIG_PROVIDER_ID,
112
103
  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)
104
+ codex_config_profile: OPENROUTER_DEFAULT_PROFILE_ID,
105
+ reasoning_profiles: [],
106
+ retired_glm_profiles: [...RETIRED_GLM_DESKTOP_CONFIG_PROFILE_IDS]
115
107
  };
116
108
  }
117
109
  }
@@ -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';
@@ -259,7 +258,7 @@ async function reportPostinstallCodexLbAuth(snapshot = null) {
259
258
  async function postinstallHarnessConflictNotice(conflictScan) {
260
259
  console.log('\nSneakoscope Codex package installed, but SKS setup is blocked.');
261
260
  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.');
261
+ console.log('\nWhat this means: npm can finish installing the package. Conflicting OMX/DCodex markers are quarantined automatically by `sks setup`, `sks doctor --fix`, `sks update`, or `sks conflicts cleanup --yes`.');
263
262
  console.log('No files were removed by postinstall.');
264
263
  console.log('Cleanup requires a human-approved Codex App session. Keep the model selected in Codex and use high reasoning effort.');
265
264
  if (shouldAskPostinstallQuestion()) {
@@ -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,6 +11,8 @@ 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';
15
17
  import { restartCodexApp } from '../core/codex-app/codex-app-restart.js';
16
18
  export async function run(_command, args = []) {
@@ -36,7 +38,7 @@ export async function run(_command, args = []) {
36
38
  if (action === 'glm-profile') {
37
39
  const subcommand = args[1] || 'doctor';
38
40
  const root = await sksRoot();
39
- const result = subcommand === 'install' || subcommand === 'repair'
41
+ const result = subcommand === 'install' || subcommand === 'repair' || subcommand === 'remove'
40
42
  ? await installCodexAppGlmProfile({ root, apply: true })
41
43
  : await doctorCodexAppGlmProfile({ root });
42
44
  return printCodexAppResult(args, result);
@@ -58,6 +60,7 @@ export async function run(_command, args = []) {
58
60
  key_preview: record.key_preview,
59
61
  raw_key_recorded: false,
60
62
  secret_store: 'sks-openrouter-secret-store',
63
+ selected: false,
61
64
  glm_profile: profile,
62
65
  restart_app: restart,
63
66
  blockers: [...(profile.blockers || []), ...(restart.blockers || [])],
@@ -65,6 +68,20 @@ export async function run(_command, args = []) {
65
68
  };
66
69
  return printCodexAppResult(args, result);
67
70
  }
71
+ if (action === 'use-openrouter' || action === 'use-or') {
72
+ const root = await sksRoot();
73
+ const model = readOption(args, '--model', OPENROUTER_DEFAULT_MODEL);
74
+ const result = await useOpenRouter({
75
+ root,
76
+ model,
77
+ restartApp: flag(args, '--restart-app') || flag(args, '--restart') || !flag(args, '--no-restart-app')
78
+ });
79
+ return printCodexAppResult(args, result);
80
+ }
81
+ if (action === 'openrouter-status') {
82
+ const result = await openRouterStatus({});
83
+ return printCodexAppResult(args, result);
84
+ }
68
85
  if (action === 'product-design' || action === 'design-product' || action === 'ensure-product-design') {
69
86
  const checkOnly = flag(args, '--check-only') || flag(args, '--no-install');
70
87
  const status = await codexProductDesignPluginStatus({
@@ -125,7 +142,8 @@ export async function run(_command, args = []) {
125
142
  process.exitCode = 1;
126
143
  return;
127
144
  }
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]');
145
+ 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|product-design [--check-only]|ensure-product-design|chrome-extension|pat status|remote-control [--json]');
146
+ console.error('Note: glm-profile is retired (strips leftover Desktop GLM profiles); use set-openrouter-key / use-openrouter.');
129
147
  process.exitCode = 1;
130
148
  }
131
149
  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
  }
@@ -35,27 +35,32 @@ export async function run(_command, args = [], deps = {}) {
35
35
  const doctorFix = flag(args, '--fix');
36
36
  const globalOnly = doctorFix && flag(args, '--global-only');
37
37
  if (doctorFix) {
38
+ const { cleanupOtherHarnessConflicts } = await import('../core/harness-conflicts.js');
38
39
  const conflictScan = await scanHarnessConflicts(root);
39
40
  if (conflictScan.hard_block) {
40
- const blocked = {
41
- schema: 'sks.doctor-status.v3',
42
- ok: false,
43
- status: 'blocked_harness_conflict',
44
- diagnostic_depth: 'fix',
45
- root,
46
- blockers: conflictScan.hard.map((item) => `${item.name || 'harness'}:${item.path}`),
47
- conflicts: conflictScan.conflicts,
48
- cleanup_prompt_command: 'sks conflicts prompt',
49
- no_fix_writes_performed: true
50
- };
51
- process.exitCode = 1;
52
- if (flag(args, '--json')) {
53
- printJson(blocked);
41
+ const cleanup = await cleanupOtherHarnessConflicts(root);
42
+ if (!cleanup.ok) {
43
+ const blocked = {
44
+ schema: 'sks.doctor-status.v3',
45
+ ok: false,
46
+ status: 'blocked_harness_conflict',
47
+ diagnostic_depth: 'fix',
48
+ root,
49
+ blockers: (cleanup.remaining || conflictScan.hard).map((item) => `${item.name || 'harness'}:${item.path}`),
50
+ conflicts: cleanup.after?.conflicts || conflictScan.conflicts,
51
+ other_harness_cleanup: cleanup,
52
+ cleanup_prompt_command: 'sks conflicts cleanup --yes',
53
+ no_fix_writes_performed: cleanup.cleaned.length === 0
54
+ };
55
+ process.exitCode = 1;
56
+ if (flag(args, '--json')) {
57
+ printJson(blocked);
58
+ return blocked;
59
+ }
60
+ console.error(formatHarnessConflictReport(cleanup.after || conflictScan, { includePrompt: false }));
61
+ console.error('Automatic OMX/DCodex removal did not clear every conflict. Live markers must be removed; inspect backup under .sneakoscope/quarantine/other-harness/.');
54
62
  return blocked;
55
63
  }
56
- console.error(formatHarnessConflictReport(conflictScan, { includePrompt: false }));
57
- console.error('Run `sks conflicts prompt` and obtain explicit human approval before cleanup.');
58
- return blocked;
59
64
  }
60
65
  }
61
66
  const doctorProfile = doctorProfileFromArgs(args, doctorFix);