sneakoscope 7.1.0 → 7.3.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.
- package/README.md +9 -1
- package/config/architecture-budgets.v1.json +1 -8
- package/crates/sks-core/Cargo.lock +225 -1
- package/crates/sks-core/Cargo.toml +8 -1
- package/crates/sks-core/src/main.rs +7 -1
- package/crates/sks-core/src/search/files.rs +114 -0
- package/crates/sks-core/src/search/mod.rs +274 -0
- package/crates/sks-core/src/search/text.rs +175 -0
- package/dist/bin/sks-dispatch.js +4 -3
- package/dist/cli/command-manifest-lite.js +177 -6
- package/dist/cli/command-registry.js +42 -8
- package/dist/cli/help.js +30 -0
- package/dist/cli/install-helpers-codex-lb-config.js +9 -6
- package/dist/cli/install-helpers-codex-lb-selftest-chain.js +1 -1
- package/dist/cli/install-helpers-install-support.js +1 -1
- package/dist/cli/install-helpers.js +19 -9
- package/dist/cli/router.js +16 -3
- package/dist/commands/codex-app.js +40 -5
- package/dist/commands/doctor-profile.js +78 -0
- package/dist/commands/doctor.js +29 -69
- package/dist/commands/search.js +4 -0
- package/dist/config/skills-manifest.json +53 -60
- package/dist/core/agent-bridge/agent-manifest.js +22 -26
- package/dist/core/agent-bridge/host-capability-policy.js +109 -8
- package/dist/core/agent-bridge/host-capability-runtime.js +178 -50
- package/dist/core/agent-guidance/directive-registry.js +123 -0
- package/dist/core/agents/agent-effort-policy.js +45 -6
- package/dist/core/agents/agent-worker-pipeline.js +1 -3
- package/dist/core/agents/native-worker-backend-router.js +43 -19
- package/dist/core/auto-review.js +1 -3
- package/dist/core/code-structure.js +282 -19
- package/dist/core/codex/codex-config-guard.js +14 -4
- package/dist/core/codex/codex-config-toml.js +1 -3
- package/dist/core/codex-app/codex-agent-role-sync.js +1 -3
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +14 -1
- package/dist/core/codex-app/codex-app-types.js +2 -3
- package/dist/core/codex-app/codex-desktop-routing-ownership.js +91 -0
- package/dist/core/codex-app/codex-hook-approval-probe.js +1 -3
- package/dist/core/codex-app/codex-hook-lifecycle.js +1 -3
- package/dist/core/codex-app/codex-init-deep.js +22 -10
- package/dist/core/codex-app/codex-model-catalog.js +384 -0
- package/dist/core/codex-app/codex-models-cache.js +160 -0
- package/dist/core/codex-app/desktop-routing-snapshot.js +233 -0
- package/dist/core/codex-app/glm-profile-installer.js +1 -3
- package/dist/core/codex-app/mcp-manager.js +1 -3
- package/dist/core/codex-app/menubar/constants.js +3 -0
- package/dist/core/codex-app/menubar/installer.js +11 -1
- package/dist/core/codex-app/multi-provider-router-support.js +202 -0
- package/dist/core/codex-app/multi-provider-router.js +379 -0
- package/dist/core/codex-app/openrouter-activate.js +189 -26
- package/dist/core/codex-app/openrouter-base-instructions.js +1 -0
- package/dist/core/codex-app/openrouter-model-catalog.js +217 -0
- package/dist/core/codex-app/role-model-catalog-priority.js +61 -0
- package/dist/core/codex-app.js +30 -6
- package/dist/core/codex-compat/codex-hook-semantic-validator.js +1 -3
- package/dist/core/codex-control/codex-app-server-v2-client.js +39 -2
- package/dist/core/codex-lb/codex-lb-env.js +1 -3
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +6 -1
- package/dist/core/codex-native/codex-native-feature-broker.js +2 -6
- package/dist/core/codex-native/codex-native-interop-policy.js +1 -3
- package/dist/core/codex-native/codex-native-reference-cache.js +1 -3
- package/dist/core/codex-native/codex-native-reference-source.js +1 -3
- package/dist/core/codex-native/codex-native-repair-transaction.js +1 -3
- package/dist/core/codex-native/core-skill-manifest.js +3 -2
- package/dist/core/codex-native/native-capability-repair-matrix.js +1 -3
- package/dist/core/codex-plugins/codex-plugin-repair.js +1 -3
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +4 -4
- package/dist/core/commands/agent-bridge-command.js +24 -3
- package/dist/core/commands/image-ux-review-command.js +5 -11
- package/dist/core/commands/menubar-command.js +1 -1
- package/dist/core/commands/naruto-command.js +40 -13
- package/dist/core/commands/pipeline-command.js +5 -2
- package/dist/core/commands/release-command.js +63 -1
- package/dist/core/commands/remote-command.js +18 -0
- package/dist/core/commands/search-command.js +151 -0
- package/dist/core/commands/telegram-command.js +251 -108
- package/dist/core/commands/uninstall-command.js +1 -1
- package/dist/core/config/secret-preservation.js +1 -3
- package/dist/core/context7-client.js +2 -1
- package/dist/core/db-review.js +704 -0
- package/dist/core/db-safety.js +17 -23
- package/dist/core/doctor/browser-use-repair.js +1 -3
- package/dist/core/doctor/codex-startup-config-repair.js +1 -3
- package/dist/core/doctor/computer-use-repair.js +1 -3
- package/dist/core/doctor/context7-mcp-repair.js +1 -3
- package/dist/core/doctor/current-project-guidance.js +1 -3
- package/dist/core/doctor/doctor-codex-startup-repair.js +1 -3
- package/dist/core/doctor/doctor-dirty-planner.js +2 -2
- package/dist/core/doctor/doctor-native-capability-repair.js +1 -3
- package/dist/core/doctor/doctor-transaction.js +1 -3
- package/dist/core/doctor/imagegen-repair.js +1 -3
- package/dist/core/doctor/legacy-global-hook-cleanup.js +1 -3
- package/dist/core/doctor/mcp-transport-collision-repair.js +1 -3
- package/dist/core/doctor/retired-managed-residue-private.js +1 -3
- package/dist/core/doctor/supabase-mcp-repair.js +1 -3
- package/dist/core/engineering-sanity-review.js +186 -0
- package/dist/core/errors/message.js +3 -0
- package/dist/core/evidence/evidence-schema.js +1 -3
- package/dist/core/feature-fixtures.js +1 -0
- package/dist/core/feature-registry.js +1 -3
- package/dist/core/fsx.js +13 -0
- package/dist/core/git-hygiene/shared-memory-publish.js +1 -3
- package/dist/core/git-hygiene/validators.js +1 -3
- package/dist/core/harness-guard.js +21 -3
- package/dist/core/hooks-runtime/hook-context.js +2 -2
- package/dist/core/image-ux-review/imagegen-adapter.js +52 -56
- package/dist/core/image-ux-review/real-callout-extractor.js +6 -1
- package/dist/core/image-ux-review.js +3 -5
- package/dist/core/imagegen/codex-lb-imagegen-target.js +70 -0
- package/dist/core/imagegen/imagegen-capability.js +11 -11
- package/dist/core/imagegen/imagegen-evidence.js +32 -0
- package/dist/core/init/skills.js +9 -11
- package/dist/core/init.js +4 -6
- package/dist/core/json/records.js +9 -0
- package/dist/core/json-schema-validator.js +1 -3
- package/dist/core/lean-engineering-policy.js +54 -0
- package/dist/core/loops/loop-continuation-enforcer.js +1 -3
- package/dist/core/mad-sks/sql-plane/mcp-executor.js +2 -1
- package/dist/core/mad-sks/sql-plane/policy.js +2 -1
- package/dist/core/managed-assets/managed-assets-manifest.js +4 -3
- package/dist/core/mcp-config/codex-cli-adapter.js +1 -3
- package/dist/core/mcp-config/config-reader.js +2 -3
- package/dist/core/mcp-config/guarded-patch.js +1 -1
- package/dist/core/mcp-config/health-check.js +2 -1
- package/dist/core/mcp-config/mutation.js +1 -1
- package/dist/core/mcp-config/restore.js +1 -1
- package/dist/core/mcp-config/secret-policy.js +1 -3
- package/dist/core/migration/migration-transaction-journal.js +3 -3
- package/dist/core/naruto/naruto-concurrency-governor.js +2 -2
- package/dist/core/perf/import-graph-budget.js +91 -1
- package/dist/core/pipeline/pipeline-plan-writer.js +1 -1
- package/dist/core/pipeline-internals/runtime-core.js +121 -23
- package/dist/core/pipeline-internals/runtime-gates.js +193 -4
- package/dist/core/pipeline.js +1 -1
- package/dist/core/ppt-review/slide-imagegen-review.js +7 -7
- package/dist/core/ppt.js +3 -3
- package/dist/core/product-design-app-server.js +2 -1
- package/dist/core/proof/fake-real-proof-policy.js +1 -3
- package/dist/core/proof/root-cause-policy.js +1 -3
- package/dist/core/proof/validation.js +1 -3
- package/dist/core/provider/model-router.js +4 -0
- package/dist/core/provider/provider-context.js +1 -3
- package/dist/core/providers/openrouter/openrouter-account.js +1 -3
- package/dist/core/quality/helper-dedup.js +0 -0
- package/dist/core/recallpulse.js +1 -1
- package/dist/core/release/file-ownership.js +26 -17
- package/dist/core/release/macos-menubar-proof.js +59 -1
- package/dist/core/release/main-push-guard.js +288 -24
- package/dist/core/release/main-push-receipt.js +10 -45
- package/dist/core/release/package-size-budget.js +1 -1
- package/dist/core/release/release-gate-contract.js +2 -0
- package/dist/core/release/release-pack-receipt.js +1 -1
- package/dist/core/release/release-proof-io.js +33 -0
- package/dist/core/release/release-upgrade-baseline.js +9 -0
- package/dist/core/release/runtime-script-pack-closure.js +153 -4
- package/dist/core/release/stage-publish.js +194 -0
- package/dist/core/remote/index.js +2 -0
- package/dist/core/remote/local-worker-client.js +35 -0
- package/dist/core/remote/machine-registry.js +18 -13
- package/dist/core/remote/owner-proof.js +1 -3
- package/dist/core/remote/protocol.js +1 -3
- package/dist/core/remote/readiness.js +1 -3
- package/dist/core/remote/session-binding.js +153 -0
- package/dist/core/remote/session-index.js +1 -3
- package/dist/core/remote/types.js +1 -0
- package/dist/core/remote/worker.js +228 -14
- package/dist/core/responses-stream.js +151 -0
- package/dist/core/routes/dollar-manifest-lite.js +1 -1
- package/dist/core/routes.js +8 -8
- package/dist/core/rust-accelerator.js +12 -2
- package/dist/core/safety/ssot-guard.js +1 -3
- package/dist/core/search/benchmark.js +358 -0
- package/dist/core/search/cache.js +65 -0
- package/dist/core/search/context.js +144 -0
- package/dist/core/search/doctor.js +74 -0
- package/dist/core/search/files.js +192 -0
- package/dist/core/search/index.js +5 -0
- package/dist/core/search/ipc.js +64 -0
- package/dist/core/search/provider.js +142 -0
- package/dist/core/search/rust-bridge.js +24 -0
- package/dist/core/search/structure.js +230 -0
- package/dist/core/search/symbol.js +272 -0
- package/dist/core/search/text.js +146 -0
- package/dist/core/search/types.js +22 -0
- package/dist/core/search/typescript-ls.js +215 -0
- package/dist/core/search-visibility/discovery.js +1 -3
- package/dist/core/skill-forge.js +1 -1
- package/dist/core/stop-gate/gate-evaluator.js +3 -3
- package/dist/core/stop-gate/stop-gate-check.js +1 -3
- package/dist/core/structured-output-adapter.js +62 -2
- package/dist/core/subagents/agent-catalog.js +56 -43
- package/dist/core/subagents/model-policy.js +17 -7
- package/dist/core/subagents/naruto-proof-projection.js +2 -6
- package/dist/core/subagents/official-subagent-config.js +1 -3
- package/dist/core/subagents/official-subagent-preparation.js +73 -10
- package/dist/core/subagents/official-subagent-prompt.js +85 -18
- package/dist/core/subagents/official-subagent-runner.js +10 -5
- package/dist/core/subagents/role-model-preferences.js +202 -44
- package/dist/core/subagents/subagent-evidence.js +1 -3
- package/dist/core/subagents/thread-budget.js +1 -1
- package/dist/core/subagents/triwiki-attention.js +1 -5
- package/dist/core/telegram/config.js +29 -12
- package/dist/core/telegram/hub.js +8 -2
- package/dist/core/telegram/index.js +2 -0
- package/dist/core/telegram/messages.js +8 -2
- package/dist/core/telegram/runtime-projection.js +8 -5
- package/dist/core/telegram/runtime.js +19 -9
- package/dist/core/telegram/service.js +181 -0
- package/dist/core/telegram/setup.js +220 -0
- package/dist/core/text/regex.js +3 -0
- package/dist/core/text/strings.js +6 -0
- package/dist/core/triwiki-wrongness/image-wrongness.js +1 -3
- package/dist/core/triwiki-wrongness/wrongness-ledger.js +1 -3
- package/dist/core/triwiki-wrongness/wrongness-proof-linker.js +1 -3
- package/dist/core/triwiki-wrongness/wrongness-retrieval.js +1 -3
- package/dist/core/triwiki-wrongness/wrongness-schema.js +1 -3
- package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +1 -3
- package/dist/core/trust-kernel/completion-contract.js +1 -3
- package/dist/core/trust-kernel/route-contract.js +1 -3
- package/dist/core/update/update-migration-state.js +1 -3
- package/dist/core/update-check.js +20 -6
- package/dist/core/verification/diff-quality.js +3 -4
- package/dist/core/verification/impact-scan.js +36 -89
- package/dist/core/verification/mistake-rule-compiler.js +17 -4
- package/dist/core/version-manager.js +3 -20
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +23 -3
- package/dist/native/sks-menubar/Sources/ControlKit.swift +102 -0
- package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +23 -11
- package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +7 -3
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +17 -1
- package/dist/native/sks-menubar/Sources/OverviewViewController.swift +22 -15
- package/dist/native/sks-menubar/Sources/ProcessClient.swift +15 -5
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +324 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +154 -214
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +252 -0
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +77 -71
- package/dist/native/sks-menubar/Sources/RemoteTelegramViewController.swift +167 -51
- package/dist/native/sks-menubar/Sources/SettingsViewController.swift +14 -5
- package/dist/native/sks-menubar/Sources/SidebarItem.swift +15 -1
- package/dist/native/sks-menubar/Sources/StatusItemController.swift +2 -2
- package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +16 -12
- package/dist/scripts/agent-guidance-dedup-check.js +23 -0
- package/dist/scripts/agent-message-bus-reader-check.js +1 -1
- package/dist/scripts/all-feature-deep-completion-check.js +1 -1
- package/dist/scripts/appshots-thread-attachment-discovery-check.js +1 -1
- package/dist/scripts/architecture-guard-check.js +1 -2
- package/dist/scripts/certificate-sla-check.js +1 -1
- package/dist/scripts/cli-output-consistency-check.js +1 -1
- package/dist/scripts/codex-0-134-runner-truth-check.js +1 -1
- package/dist/scripts/codex-0138-capability-artifact-check.js +1 -1
- package/dist/scripts/codex-0138-capability-check.js +1 -1
- package/dist/scripts/codex-0138-doctor-check.js +1 -1
- package/dist/scripts/codex-0138-feature-probes-check.js +1 -1
- package/dist/scripts/codex-0144-app-server-v2-check.js +1 -1
- package/dist/scripts/codex-0144-binary-identity-check.js +1 -1
- package/dist/scripts/codex-0144-capability-check.js +1 -1
- package/dist/scripts/codex-0144-core-real-probes-check.js +1 -1
- package/dist/scripts/codex-0144-manifest-check.js +1 -1
- package/dist/scripts/codex-0144-policy-check.js +1 -1
- package/dist/scripts/codex-0144-thread-store-check.js +1 -1
- package/dist/scripts/codex-agent-role-rich-content-check.js +2 -2
- package/dist/scripts/codex-agent-role-sync-check.js +2 -2
- package/dist/scripts/codex-agent-type-routing-check.js +2 -2
- package/dist/scripts/codex-app-execution-profile-check.js +2 -2
- package/dist/scripts/codex-app-handoff-check.js +1 -1
- package/dist/scripts/codex-app-handoff-launch-check.js +1 -1
- package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +1 -1
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +1 -3
- package/dist/scripts/codex-native-feature-broker-blackbox.js +2 -2
- package/dist/scripts/codex-native-feature-broker-check.js +2 -2
- package/dist/scripts/{sks-3-1-6-directive-check-lib.js → codex-native-gate-lib.js} +5 -5
- package/dist/scripts/codex-native-harness-compat-check.js +2 -2
- package/dist/scripts/codex-native-hook-lifecycle-proof-check.js +2 -2
- package/dist/scripts/codex-plugin-app-template-policy-check.js +1 -1
- package/dist/scripts/codex-sdk-backend-router-check.js +1 -1
- package/dist/scripts/codex-sdk-capability-check.js +1 -1
- package/dist/scripts/context7-evidence-dedupe-check.js +1 -1
- package/dist/scripts/core-skill-card-schema-check.js +1 -1
- package/dist/scripts/core-skill-deployment-snapshot-check.js +1 -1
- package/dist/scripts/core-skill-heldout-validation-check.js +1 -1
- package/dist/scripts/core-skill-no-inference-optimizer-check.js +1 -1
- package/dist/scripts/core-skill-patch-check.js +1 -1
- package/dist/scripts/core-skill-route-runtime-integration-check.js +1 -1
- package/dist/scripts/current-command-surface-check.js +1 -1
- package/dist/scripts/current-surface-update-e2e-check.js +4 -1
- package/dist/scripts/current-upgrade-matrix-check.js +1 -1
- package/dist/scripts/dfix-fixture-check.js +1 -1
- package/dist/scripts/dfix-patch-handoff-check.js +1 -1
- package/dist/scripts/dfix-verification-check.js +1 -1
- package/dist/scripts/dfix-verification-recommendation-check.js +1 -1
- package/dist/scripts/docs-truthfulness-check.js +16 -3
- package/dist/scripts/doctor-codex-app-harness-check.js +2 -2
- package/dist/scripts/evidence-flagship-coverage-check.js +1 -1
- package/dist/scripts/{sks-1-18-gate-lib.js → gate-lib.js} +1 -1
- package/dist/scripts/gate-policy-audit-check.js +4 -1
- package/dist/scripts/git-worktree-checkpoint-check.js +1 -1
- package/dist/scripts/git-worktree-cross-rebase-check.js +1 -1
- package/dist/scripts/git-worktree-diff-envelope-check.js +1 -1
- package/dist/scripts/git-worktree-dirty-lock-check.js +1 -1
- package/dist/scripts/git-worktree-dirty-main-detection-check.js +1 -1
- package/dist/scripts/git-worktree-integration-primary-check.js +1 -1
- package/dist/scripts/git-worktree-manifest-append-check.js +1 -1
- package/dist/scripts/git-worktree-untracked-diff-check.js +1 -1
- package/dist/scripts/harness-benchmark-check.js +1 -1
- package/dist/scripts/helper-dedup-check.js +62 -0
- package/dist/scripts/hook-latency-budget-check.js +1 -1
- package/dist/scripts/image-artifact-path-contract-check.js +1 -1
- package/dist/scripts/imagegen-real-smoke-check.js +2 -5
- package/dist/scripts/installed-package-smoke-check.js +1 -1
- package/dist/scripts/legacy-gate-inventory-check.js +1 -1
- package/dist/scripts/legacy-gate-purge-check.js +1 -1
- package/dist/scripts/legacy-strong-inventory-check.js +1 -1
- package/dist/scripts/lib/codex-sdk-gate-lib.js +1 -1
- package/dist/scripts/mad-sks-launch-sql-plane-boundary-check.js +1 -1
- package/dist/scripts/mad-sks-sql-plane-capability-check.js +1 -1
- package/dist/scripts/mad-sks-sql-plane-lifecycle-hook-decision-check.js +1 -1
- package/dist/scripts/mad-sks-sql-plane-result-lifecycle-check.js +1 -1
- package/dist/scripts/managed-config-merge-check.js +1 -1
- package/dist/scripts/mcp-plugin-inventory-check.js +1 -1
- package/dist/scripts/model-call-concurrency-check.js +1 -1
- package/dist/scripts/mutation-callsite-coverage-check.js +1 -1
- package/dist/scripts/naruto-ssot-gate-aliases-check.js +1 -1
- package/dist/scripts/naruto-ssot-pipeline-default-check.js +1 -1
- package/dist/scripts/naruto-ssot-route-normalization-check.js +1 -1
- package/dist/scripts/naruto-ssot-routing-check.js +1 -1
- package/dist/scripts/naruto-worktree-coding-blackbox.js +1 -1
- package/dist/scripts/native-capability-repair-matrix-check.js +1 -1
- package/dist/scripts/native-image-generation-repair-check.js +1 -1
- package/dist/scripts/official-subagent-workflow-check.js +3 -3
- package/dist/scripts/package-published-contract-check.js +37 -4
- package/dist/scripts/packlist-performance-check.js +17 -1
- package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +1 -3
- package/dist/scripts/ppt-real-export-adapter-check.js +1 -1
- package/dist/scripts/ppt-real-imagegen-wiring-check.js +1 -1
- package/dist/scripts/ppt-reexport-rereview-check.js +1 -1
- package/dist/scripts/prepublish-fast-check.js +1 -1
- package/dist/scripts/probe-memoization-check.js +2 -2
- package/dist/scripts/prompt-placeholder-guard-check.js +1 -1
- package/dist/scripts/qa-loop-app-handoff-capability-check.js +1 -1
- package/dist/scripts/qa-loop-app-handoff-check.js +1 -1
- package/dist/scripts/qa-loop-app-handoff-cli-check.js +1 -1
- package/dist/scripts/qa-loop-app-handoff-confirmation-check.js +1 -1
- package/dist/scripts/qa-loop-app-handoff-gate-lifecycle-check.js +1 -1
- package/dist/scripts/qa-loop-app-handoff-launch-check.js +1 -1
- package/dist/scripts/qa-loop-app-handoff-status-lifecycle-check.js +1 -1
- package/dist/scripts/qa-loop-budget-policy-check.js +1 -1
- package/dist/scripts/qa-loop-effort-escalation-check.js +1 -1
- package/dist/scripts/qa-loop-execution-profile-routing-check.js +2 -2
- package/dist/scripts/qa-loop-image-path-exposure-check.js +1 -1
- package/dist/scripts/qa-loop-image-path-prompt-injection-check.js +1 -1
- package/dist/scripts/{sks-1-12-real-execution-check-lib.js → real-execution-check-lib.js} +1 -1
- package/dist/scripts/release-affected-selector-check.js +1 -1
- package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
- package/dist/scripts/release-cache-glob-hashing-check.js +1 -1
- package/dist/scripts/release-cache-input-classifier-check.js +1 -1
- package/dist/scripts/release-cache-neutralization-report-check.js +1 -1
- package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -1
- package/dist/scripts/release-dynamic-presets-check.js +2 -2
- package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
- package/dist/scripts/release-gate-batch-runner-check.js +1 -1
- package/dist/scripts/release-gate-budget-check.js +1 -1
- package/dist/scripts/release-gate-dag-runner-check.js +1 -1
- package/dist/scripts/release-latency-slo-check.js +1 -1
- package/dist/scripts/release-metadata-check.js +256 -2
- package/dist/scripts/release-parallel-speed-budget-check.js +1 -1
- package/dist/scripts/release-proof-truth-check.js +1 -1
- package/dist/scripts/release-provenance-check.js +4 -2
- package/dist/scripts/release-runtime-truth-matrix-check.js +1 -1
- package/dist/scripts/research-blueprint-densifier-check.js +1 -1
- package/dist/scripts/research-claim-builder-check.js +1 -1
- package/dist/scripts/research-complete-package-fixture-check.js +1 -1
- package/dist/scripts/research-execution-profile-routing-check.js +2 -2
- package/dist/scripts/research-final-reviewer-blackbox.js +1 -1
- package/dist/scripts/{sks-3-1-4-directive-check-lib.js → runtime-domain-gate-lib.js} +2 -2
- package/dist/scripts/runtime-proof-summary-check.js +1 -1
- package/dist/scripts/runtime-script-pack-closure-check.js +7 -1
- package/dist/scripts/scheduler-batch-dispatch-check.js +1 -1
- package/dist/scripts/scheduler-parallel-proof-consistency-check.js +1 -1
- package/dist/scripts/scheduler-utilization-integral-check.js +1 -1
- package/dist/scripts/search-visibility-gate-lib.js +1 -1
- package/dist/scripts/secret-preservation-check.js +1 -1
- package/dist/scripts/seo-geo-geo-disambiguation-check.js +1 -1
- package/dist/scripts/seo-geo-skill-rich-content-check.js +1 -1
- package/dist/scripts/side-effect-runtime-report-check.js +1 -1
- package/dist/scripts/{sks-3-1-8-check-lib.js → skill-fixture-check-lib.js} +1 -1
- package/dist/scripts/skill-name-canonicalizer-check.js +1 -1
- package/dist/scripts/skills-manifest-continuity-check.js +1 -1
- package/dist/scripts/sks-uninstall-regression-check.js +1 -1
- package/dist/scripts/sksd-daemon-check.js +1 -1
- package/dist/scripts/super-search-provider-interface-check.js +1 -1
- package/dist/scripts/triwiki-cache-key-check.js +1 -1
- package/dist/scripts/triwiki-proof-bank-blackbox.js +2 -2
- package/dist/scripts/triwiki-proof-bank-check.js +1 -1
- package/dist/scripts/triwiki-proof-card-check.js +1 -1
- package/dist/scripts/type-surface-codex-app-check.js +2 -2
- package/dist/scripts/{sks-3-1-5-directive-check-lib.js → typed-routing-gate-lib.js} +2 -2
- package/dist/scripts/ultra-router-auto-router-check.js +1 -1
- package/dist/scripts/ux-review-extract-wires-real-extractor-check.js +1 -1
- package/dist/scripts/ux-review-patch-diff-recheck-check.js +1 -1
- package/dist/scripts/ux-review-run-wires-imagegen-check.js +9 -2
- package/package.json +5 -7
- package/release-gates.v2.json +66 -11
- package/runtime-required-scripts.json +138 -14
- package/config/bench-baseline.json +0 -7
- package/dist/core/codex-app/sks-menubar.js +0 -1
- package/dist/core/release/release-closure-contract.js +0 -30
- package/dist/core/release/release-closure-helpers.js +0 -293
- package/dist/core/release/release-closure-validation.js +0 -284
- package/dist/core/release/release-closure.js +0 -163
- package/dist/scripts/build-dist.js +0 -124
- package/dist/scripts/build-once-runner-check.js +0 -6
- package/dist/scripts/canonical-test-runner.js +0 -234
- package/dist/scripts/changelog-check.js +0 -45
- package/dist/scripts/check-architecture.js +0 -295
- package/dist/scripts/check-cli-entrypoint.js +0 -41
- package/dist/scripts/check-command-module-budget.js +0 -77
- package/dist/scripts/check-feature-quality.js +0 -51
- package/dist/scripts/check-legacy-free.js +0 -64
- package/dist/scripts/check-pipeline-budget.js +0 -49
- package/dist/scripts/check-pipeline-runtime.js +0 -16
- package/dist/scripts/check-publish-tag.js +0 -56
- package/dist/scripts/check-route-modularity.js +0 -72
- package/dist/scripts/codex-0140-capability-check.js +0 -14
- package/dist/scripts/codex-0140-feature-probes-check.js +0 -23
- package/dist/scripts/codex-permission-profiles-check.js +0 -34
- package/dist/scripts/codex-project-config-policy-splitter-check.js +0 -49
- package/dist/scripts/competitor-scorecard-check.js +0 -24
- package/dist/scripts/core-skill-no-drift-check.js +0 -23
- package/dist/scripts/db-route-materialization-check.js +0 -32
- package/dist/scripts/doctor-context7-mcp-repair-blackbox.js +0 -15
- package/dist/scripts/doctor-fastpath-check.js +0 -25
- package/dist/scripts/doctor-fix-production-blackbox.js +0 -35
- package/dist/scripts/doctor-idempotence-check.js +0 -6
- package/dist/scripts/doctor-ops-semantics-check.js +0 -83
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +0 -18
- package/dist/scripts/doctor-supabase-mcp-repair-blackbox.js +0 -13
- package/dist/scripts/ensure-bin-executable.js +0 -16
- package/dist/scripts/fsx-hotpath-check.js +0 -9
- package/dist/scripts/high-risk-contracts-check.js +0 -183
- package/dist/scripts/hook-latency-quantum-check.js +0 -120
- package/dist/scripts/import-graph-budget-check.js +0 -9
- package/dist/scripts/mcp-tool-naming-parity-check.js +0 -14
- package/dist/scripts/naruto-codex-e2e-check.js +0 -105
- package/dist/scripts/naruto-write-e2e-check.js +0 -31
- package/dist/scripts/native-capability-postcheck-check.js +0 -16
- package/dist/scripts/ops-diagnostics-bundle-check.js +0 -11
- package/dist/scripts/parallel-production-smoke-check.js +0 -20
- package/dist/scripts/perf-budget-check.js +0 -12
- package/dist/scripts/project-skill-dedupe-blackbox.js +0 -62
- package/dist/scripts/release-dag-full-coverage-check.js +0 -98
- package/dist/scripts/release-dist-freshness-check.js +0 -6
- package/dist/scripts/release-file-ownership-check.js +0 -35
- package/dist/scripts/release-gate-script-parity-check.js +0 -148
- package/dist/scripts/release-macos-menubar-proof.js +0 -167
- package/dist/scripts/release-main-push-guard.js +0 -37
- package/dist/scripts/release-main-push-receipt.js +0 -43
- package/dist/scripts/release-metadata-1-19-check.js +0 -257
- package/dist/scripts/release-version-truth-check.js +0 -138
- package/dist/scripts/retention-apply-smoke-check.js +0 -19
- package/dist/scripts/retention-budget-check.js +0 -6
- package/dist/scripts/retention-dry-run-check.js +0 -8
- package/dist/scripts/rollback-recovery-smoke-check.js +0 -70
- package/dist/scripts/route-intent-regression-check.js +0 -42
- package/dist/scripts/runtime-current-terminal-check.js +0 -108
- package/dist/scripts/runtime-dist-parity-check.js +0 -76
- package/dist/scripts/runtime-no-src-mjs-check.js +0 -30
- package/dist/scripts/runtime-ts-rust-boundary-check.js +0 -58
- package/dist/scripts/runtime-ts-source-of-truth-check.js +0 -53
- package/dist/scripts/secret-preservation-guard-check.js +0 -36
- package/dist/scripts/seo-marketing-truthfulness-check.js +0 -98
- package/dist/scripts/seo-metadata-sync-check.js +0 -60
- package/dist/scripts/sizecheck.js +0 -148
- package/dist/scripts/sks-menubar-install-check.js +0 -333
- package/dist/scripts/supabase-secret-preservation-blackbox.js +0 -28
- package/dist/scripts/super-search-live-smoke-check.js +0 -115
- package/dist/scripts/super-search-local-http-smoke-check.js +0 -16
- package/dist/scripts/super-search-offline-contract-check.js +0 -43
- package/dist/scripts/update-fastpath-check.js +0 -28
- package/dist/scripts/update-preserves-supabase-keys-blackbox.js +0 -26
- package/dist/scripts/upgrade-migration-matrix-check.js +0 -351
- package/dist/scripts/write-build-manifest.js +0 -70
- package/dist/scripts/zellij-capability-check.js +0 -13
- package/dist/scripts/zellij-developer-controls-check.js +0 -16
- package/dist/scripts/zellij-doctor-readiness-check.js +0 -49
- package/dist/scripts/zellij-dynamic-pane-lifecycle-check.js +0 -19
- package/dist/scripts/zellij-fake-adapter-check.js +0 -31
- package/dist/scripts/zellij-first-slot-down-stack-check.js +0 -20
- package/dist/scripts/zellij-first-slot-down-stack-real-check.js +0 -348
- package/dist/scripts/zellij-homebrew-policy-check.js +0 -3
- package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -21
- package/dist/scripts/zellij-lane-renderer-check.js +0 -78
- package/dist/scripts/zellij-launch-command-truth-check.js +0 -62
- package/dist/scripts/zellij-layout-valid-check.js +0 -120
- package/dist/scripts/zellij-pane-creation-lock-metrics-check.js +0 -10
- package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -78
- package/dist/scripts/zellij-pane-lock-does-not-block-worker-check.js +0 -12
- package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -134
- package/dist/scripts/zellij-qa-app-handoff-status-check.js +0 -7
- package/dist/scripts/zellij-right-column-geometry-proof.js +0 -158
- package/dist/scripts/zellij-right-column-headless-overflow-check.js +0 -20
- package/dist/scripts/zellij-right-column-manager-check.js +0 -24
- package/dist/scripts/zellij-self-heal-check.js +0 -3
- package/dist/scripts/zellij-self-heal-dry-run-check.js +0 -3
- package/dist/scripts/zellij-self-heal-status-contract-check.js +0 -3
- package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -3
- package/dist/scripts/zellij-slot-column-anchor-check.js +0 -65
- package/dist/scripts/zellij-slot-column-anchor-telemetry-check.js +0 -8
- package/dist/scripts/zellij-slot-only-ui-check.js +0 -29
- package/dist/scripts/zellij-slot-pane-renderer-check.js +0 -149
- package/dist/scripts/zellij-slot-pane-stale-detection-check.js +0 -65
- package/dist/scripts/zellij-slot-pane-telemetry-renderer-check.js +0 -11
- package/dist/scripts/zellij-slot-renderer-proof-semantics-check.js +0 -58
- package/dist/scripts/zellij-slot-telemetry-check.js +0 -38
- package/dist/scripts/zellij-slot-telemetry-incremental-check.js +0 -46
- package/dist/scripts/zellij-slot-telemetry-live-flush-check.js +0 -55
- package/dist/scripts/zellij-slot-telemetry-performance-check.js +0 -32
- package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -19
- package/dist/scripts/zellij-slot-telemetry-renderer-check.js +0 -11
- package/dist/scripts/zellij-slot-telemetry-runtime-check.js +0 -23
- package/dist/scripts/zellij-spawn-on-demand-layout-check.js +0 -45
- package/dist/scripts/zellij-stacked-capability-routing-check.js +0 -9
- package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -78
- package/dist/scripts/zellij-stacked-version-matrix-check.js +0 -29
- package/dist/scripts/zellij-stacked-version-parser-check.js +0 -19
- package/dist/scripts/zellij-ui-design-check.js +0 -92
- package/dist/scripts/zellij-update-missing-self-heal-check.js +0 -3
- package/dist/scripts/zellij-update-prompt-matrix-check.js +0 -16
- package/dist/scripts/zellij-update-prompt-mode-check.js +0 -18
- package/dist/scripts/zellij-update-prompt-safety-check.js +0 -8
- package/dist/scripts/zellij-worker-pane-manager-check.js +0 -108
- package/dist/scripts/zellij-worker-pane-manager-single-owner-check.js +0 -47
- package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -199
- /package/dist/scripts/{sks-1-11-gate-lib.js → sks-cli-gate-lib.js} +0 -0
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
import Cocoa
|
|
2
2
|
|
|
3
3
|
extension ProvidersViewController {
|
|
4
|
+
func makeActiveProviderCard() -> NSBox {
|
|
5
|
+
NativeView.card(
|
|
6
|
+
title: "Active Provider",
|
|
7
|
+
subtitle: "The provider Codex Desktop is using right now. Activation buttons below switch it explicitly.",
|
|
8
|
+
views: [activeProviderBadge]
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/// One-line truth for "what is Codex using right now", fed by the three
|
|
13
|
+
/// independent status probes as their responses arrive.
|
|
14
|
+
func renderActiveProviderSummary() {
|
|
15
|
+
if openRouterSelectedNow {
|
|
16
|
+
let model = openRouterActiveModel.isEmpty || openRouterActiveModel == "unset" ? "model unset" : openRouterActiveModel
|
|
17
|
+
ControlKit.setBadge(activeProviderBadge, text: "OpenRouter · \(model)", tone: .ok)
|
|
18
|
+
} else if routerSelectedNow {
|
|
19
|
+
let model = routerActiveModel.isEmpty ? "model unset" : routerActiveModel
|
|
20
|
+
ControlKit.setBadge(activeProviderBadge, text: "Multi-Provider Router · \(model)", tone: .ok)
|
|
21
|
+
} else if codexLbSelectedNow {
|
|
22
|
+
ControlKit.setBadge(activeProviderBadge, text: "codex-lb (GPT-5.6 via load balancer)", tone: .ok)
|
|
23
|
+
} else {
|
|
24
|
+
ControlKit.setBadge(activeProviderBadge, text: "ChatGPT OAuth · built-in OpenAI models", tone: .neutral)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
4
28
|
func makeOpenRouterCard() -> NSBox {
|
|
29
|
+
openRouterModelField.delegate = self
|
|
5
30
|
openRouterModelPopup.addItem(withTitle: "Choose from catalog…")
|
|
6
31
|
openRouterModelPopup.target = self
|
|
7
32
|
openRouterModelPopup.action = #selector(selectOpenRouterModel(_:))
|
|
@@ -12,10 +37,18 @@ extension ProvidersViewController {
|
|
|
12
37
|
let refreshModels = NativeView.button("Refresh Models", target: self, action: #selector(refreshOpenRouterModelsAction(_:)))
|
|
13
38
|
openRouterRefreshButton = refreshModels
|
|
14
39
|
let saveKey = NativeView.button("Save OpenRouter key…", target: self, action: #selector(saveOpenRouterKey))
|
|
15
|
-
let test = NativeView.button("Test
|
|
16
|
-
|
|
40
|
+
let test = NativeView.button("Test Model", target: self, action: #selector(testOpenRouterConnection))
|
|
41
|
+
test.setAccessibilityLabel("Test the selected OpenRouter model")
|
|
42
|
+
let activate = ControlKit.primaryButton("Activate Selected Model", target: self, action: #selector(useOpenRouter))
|
|
17
43
|
activate.setAccessibilityLabel("Activate selected OpenRouter model and restart Codex App")
|
|
18
|
-
|
|
44
|
+
let restorePrevious = NativeView.button("Restore previous provider", target: self, action: #selector(restorePreviousDesktopRouting))
|
|
45
|
+
restorePrevious.setAccessibilityLabel("Restore the previous Codex provider so hidden chats and picker state return")
|
|
46
|
+
// Stays disabled until openrouter-status reports a restorable
|
|
47
|
+
// cross-provider snapshot, so the button never promises a restore the
|
|
48
|
+
// CLI would reject with snapshot_missing.
|
|
49
|
+
restorePrevious.isEnabled = false
|
|
50
|
+
openRouterRestoreButton = restorePrevious
|
|
51
|
+
actionButtons += [refreshModels, saveKey, test, activate, restorePrevious]
|
|
19
52
|
|
|
20
53
|
let catalogLabel = NSTextField(labelWithString: "Catalog")
|
|
21
54
|
catalogLabel.setContentHuggingPriority(.required, for: .horizontal)
|
|
@@ -23,7 +56,7 @@ extension ProvidersViewController {
|
|
|
23
56
|
manualLabel.setContentHuggingPriority(.required, for: .horizontal)
|
|
24
57
|
return NativeView.card(
|
|
25
58
|
title: "OpenRouter",
|
|
26
|
-
subtitle: "Saving the key prepares OpenRouter but does not switch providers.
|
|
59
|
+
subtitle: "Saving the key prepares OpenRouter but does not switch providers. Activate switches Desktop routing; SKS remaps the local thread sidebar so prior provider chats stay visible, and keeps a one-click restore snapshot.",
|
|
27
60
|
views: [
|
|
28
61
|
openRouterCredentialStatus,
|
|
29
62
|
openRouterActiveStatus,
|
|
@@ -31,64 +64,12 @@ extension ProvidersViewController {
|
|
|
31
64
|
openRouterCatalogStatus,
|
|
32
65
|
NativeView.row([manualLabel, openRouterModelField]),
|
|
33
66
|
NativeView.row([saveKey, test, activate]),
|
|
67
|
+
NativeView.row([restorePrevious]),
|
|
34
68
|
openRouterStatus
|
|
35
69
|
]
|
|
36
70
|
)
|
|
37
71
|
}
|
|
38
72
|
|
|
39
|
-
func makeRoleModelsCard() -> NSBox {
|
|
40
|
-
let definitions = [
|
|
41
|
-
("ui_implementer", "UI implementation"),
|
|
42
|
-
("native_app_specialist", "Native app"),
|
|
43
|
-
("implementation_specialist", "Implementation"),
|
|
44
|
-
("test_engineer", "Testing")
|
|
45
|
-
]
|
|
46
|
-
var views: [NSView] = [roleStatus]
|
|
47
|
-
for (role, title) in definitions {
|
|
48
|
-
let controls = RoleModelControls(role: role, target: self)
|
|
49
|
-
controls.model.addItem(withTitle: "Loading profiles…")
|
|
50
|
-
controls.model.setAccessibilityLabel("\(title) model")
|
|
51
|
-
controls.model.widthAnchor.constraint(greaterThanOrEqualToConstant: 210).isActive = true
|
|
52
|
-
controls.model.identifier = NSUserInterfaceItemIdentifier(role)
|
|
53
|
-
controls.model.target = self
|
|
54
|
-
controls.model.action = #selector(roleModelSelectionChanged(_:))
|
|
55
|
-
controls.reasoning.addItem(withTitle: "Loading…")
|
|
56
|
-
controls.reasoning.setAccessibilityLabel("\(title) reasoning effort")
|
|
57
|
-
controls.current.setAccessibilityLabel("\(title) current and effective model")
|
|
58
|
-
controls.save.setAccessibilityLabel("Save \(title) model override")
|
|
59
|
-
controls.reset.setAccessibilityLabel("Reset \(title) model override")
|
|
60
|
-
controls.model.isEnabled = false
|
|
61
|
-
controls.reasoning.isEnabled = false
|
|
62
|
-
controls.save.isEnabled = false
|
|
63
|
-
controls.reset.isEnabled = false
|
|
64
|
-
roleRows[role] = controls
|
|
65
|
-
actionButtons += [controls.save, controls.reset]
|
|
66
|
-
|
|
67
|
-
let heading = NativeView.sectionTitle(title)
|
|
68
|
-
let roleId = NativeView.detail(role)
|
|
69
|
-
let modelLabel = NSTextField(labelWithString: "Model")
|
|
70
|
-
let reasoningLabel = NSTextField(labelWithString: "Reasoning")
|
|
71
|
-
views.append(NativeView.row([heading, roleId]))
|
|
72
|
-
views.append(controls.current)
|
|
73
|
-
views.append(NativeView.row([modelLabel, controls.model, reasoningLabel, controls.reasoning]))
|
|
74
|
-
views.append(NativeView.row([controls.save, controls.reset]))
|
|
75
|
-
if role != definitions.last?.0 {
|
|
76
|
-
let separator = NSBox()
|
|
77
|
-
separator.boxType = .separator
|
|
78
|
-
views.append(separator)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
let refresh = NativeView.button("Refresh Role Settings", target: self, action: #selector(refreshRoleModelsAction(_:)))
|
|
82
|
-
roleRefreshButton = refresh
|
|
83
|
-
actionButtons.append(refresh)
|
|
84
|
-
views.append(refresh)
|
|
85
|
-
return NativeView.card(
|
|
86
|
-
title: "Models by Work Type",
|
|
87
|
-
subtitle: "Overrides apply only to the selected agent role. Reset removes the override and restores the effective project/global default.",
|
|
88
|
-
views: views
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
73
|
func refreshOpenRouterStatus() {
|
|
93
74
|
processClient.run(["codex-app", "openrouter-status", "--json"], timeout: NativeView.statusTimeout) { [weak self] result in
|
|
94
75
|
guard let self = self else { return }
|
|
@@ -97,6 +78,11 @@ extension ProvidersViewController {
|
|
|
97
78
|
self.openRouterCredentialStatus.stringValue = "Credential: status unavailable — no saved key was assumed."
|
|
98
79
|
self.openRouterActiveStatus.stringValue = "Active provider: status unavailable — no active provider was assumed."
|
|
99
80
|
}
|
|
81
|
+
// An unreadable status cannot vouch for a restore point, so the
|
|
82
|
+
// button must not keep an enabled state from an earlier reply.
|
|
83
|
+
self.openRouterRestoreAvailable = false
|
|
84
|
+
self.openRouterRestoreButton?.isEnabled = false
|
|
85
|
+
self.openRouterRestoreButton?.toolTip = "Restore availability is unknown — refresh the OpenRouter status first."
|
|
100
86
|
return
|
|
101
87
|
}
|
|
102
88
|
let keyPresent = json["key_present"] as? Bool == true
|
|
@@ -104,16 +90,20 @@ extension ProvidersViewController {
|
|
|
104
90
|
let selected = json["selected"] as? Bool == true
|
|
105
91
|
let activeModel = json["model"] as? String ?? "unset"
|
|
106
92
|
let current = self.openRouterModelField.stringValue.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
107
|
-
if selected, activeModel != "unset",
|
|
93
|
+
if selected, activeModel != "unset", !self.openRouterModelSelectionPending, current.isEmpty {
|
|
108
94
|
self.openRouterModelField.stringValue = activeModel
|
|
109
95
|
}
|
|
96
|
+
self.synchronizeOpenRouterPopupSelection()
|
|
97
|
+
self.openRouterSelectedNow = selected
|
|
98
|
+
self.openRouterActiveModel = activeModel
|
|
99
|
+
self.renderActiveProviderSummary()
|
|
110
100
|
self.openRouterCredentialStatus.stringValue = keyPresent
|
|
111
101
|
? "Credential: saved securely\(providerPresent ? " · provider block ready" : " · provider setup needs repair")"
|
|
112
102
|
: "Credential: missing · save a key before testing or activation"
|
|
113
103
|
self.openRouterActiveStatus.stringValue = selected
|
|
114
104
|
? "Active provider: OpenRouter · main model \(activeModel)"
|
|
115
105
|
: "Active provider: not OpenRouter · saved credentials remain available"
|
|
116
|
-
if self.
|
|
106
|
+
if !self.openRouterActionRan {
|
|
117
107
|
let summary = self.describeOpenRouterStatus(json)
|
|
118
108
|
self.openRouterStatus.stringValue = result.code == 0
|
|
119
109
|
? summary
|
|
@@ -121,6 +111,11 @@ extension ProvidersViewController {
|
|
|
121
111
|
}
|
|
122
112
|
self.openRouterCredentialStatus.textColor = keyPresent ? .secondaryLabelColor : .systemOrange
|
|
123
113
|
self.openRouterActiveStatus.textColor = selected ? .systemGreen : .secondaryLabelColor
|
|
114
|
+
self.openRouterRestoreAvailable = json["previous_routing_restore_available"] as? Bool == true
|
|
115
|
+
self.openRouterRestoreButton?.isEnabled = !self.busy && self.openRouterRestoreAvailable
|
|
116
|
+
self.openRouterRestoreButton?.toolTip = self.openRouterRestoreAvailable
|
|
117
|
+
? "Restore the snapshotted pre-OpenRouter provider, model, and catalog."
|
|
118
|
+
: "No previous provider snapshot to restore."
|
|
124
119
|
}
|
|
125
120
|
}
|
|
126
121
|
|
|
@@ -135,9 +130,7 @@ extension ProvidersViewController {
|
|
|
135
130
|
return "OpenRouter: key stored · activation model \(selectedOpenRouterModel()) · not selected. Next: test, then activate the selected model."
|
|
136
131
|
}
|
|
137
132
|
|
|
138
|
-
@objc func refreshOpenRouterModelsAction(_ sender: NSButton) {
|
|
139
|
-
refreshOpenRouterModels()
|
|
140
|
-
}
|
|
133
|
+
@objc func refreshOpenRouterModelsAction(_ sender: NSButton) { refreshOpenRouterModels() }
|
|
141
134
|
|
|
142
135
|
func refreshOpenRouterModels() {
|
|
143
136
|
guard !catalogRefreshInFlight else { return }
|
|
@@ -165,7 +158,7 @@ extension ProvidersViewController {
|
|
|
165
158
|
self.openRouterModelPopup.removeAllItems()
|
|
166
159
|
self.openRouterModelPopup.addItem(withTitle: "Choose from \(models.count) models…")
|
|
167
160
|
self.openRouterModelPopup.addItems(withTitles: models)
|
|
168
|
-
self.
|
|
161
|
+
self.synchronizeOpenRouterPopupSelection()
|
|
169
162
|
self.openRouterModelPopup.isEnabled = !self.busy
|
|
170
163
|
let authenticated = json["authenticated"] as? Bool == true
|
|
171
164
|
self.openRouterCatalogStatus.stringValue = authenticated
|
|
@@ -189,12 +182,39 @@ extension ProvidersViewController {
|
|
|
189
182
|
|
|
190
183
|
@objc private func selectOpenRouterModel(_ sender: NSPopUpButton) {
|
|
191
184
|
guard sender.indexOfSelectedItem > 0, let model = sender.titleOfSelectedItem else { return }
|
|
185
|
+
openRouterModelSelectionPending = true
|
|
186
|
+
openRouterActionRan = true
|
|
192
187
|
openRouterModelField.stringValue = model
|
|
193
188
|
openRouterStatus.stringValue = "Selected \(model) from the catalog. Next: test the connection; activation remains unchanged."
|
|
194
189
|
}
|
|
195
190
|
|
|
191
|
+
func controlTextDidChange(_ notification: Notification) {
|
|
192
|
+
guard let field = notification.object as? NSTextField else { return }
|
|
193
|
+
if field === openRouterModelField {
|
|
194
|
+
openRouterModelSelectionPending = true
|
|
195
|
+
openRouterActionRan = true
|
|
196
|
+
synchronizeOpenRouterPopupSelection()
|
|
197
|
+
openRouterStatus.stringValue = "Manual model selection changed. Next: test the connection; activation remains unchanged."
|
|
198
|
+
} else if field === multiProvider.model {
|
|
199
|
+
multiProvider.modelSelectionPending = true
|
|
200
|
+
synchronizeMultiProviderPopupSelection()
|
|
201
|
+
multiProvider.status.stringValue = "Manual routed model selection changed. Check the router before activation."
|
|
202
|
+
multiProvider.status.textColor = .secondaryLabelColor
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private func synchronizeOpenRouterPopupSelection() {
|
|
207
|
+
let current = selectedOpenRouterModel()
|
|
208
|
+
if let index = openRouterModels.firstIndex(of: current) {
|
|
209
|
+
openRouterModelPopup.selectItem(at: index + 1)
|
|
210
|
+
} else {
|
|
211
|
+
openRouterModelPopup.selectItem(at: 0)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
196
215
|
@objc func saveOpenRouterKey() {
|
|
197
216
|
guard let window = view.window else { return }
|
|
217
|
+
openRouterActionRan = true
|
|
198
218
|
promptForSecretKey(
|
|
199
219
|
window: window,
|
|
200
220
|
sheetTitle: "OpenRouter API Key",
|
|
@@ -211,6 +231,7 @@ extension ProvidersViewController {
|
|
|
211
231
|
|
|
212
232
|
@objc private func testOpenRouterConnection() {
|
|
213
233
|
let model = selectedOpenRouterModel()
|
|
234
|
+
openRouterActionRan = true
|
|
214
235
|
guard !model.isEmpty else {
|
|
215
236
|
openRouterStatus.stringValue = "Connection test blocked · model id is empty. Next: choose or enter a model."
|
|
216
237
|
return
|
|
@@ -240,11 +261,69 @@ extension ProvidersViewController {
|
|
|
240
261
|
|
|
241
262
|
@objc func useOpenRouter() {
|
|
242
263
|
let model = selectedOpenRouterModel()
|
|
264
|
+
openRouterActionRan = true
|
|
243
265
|
guard !model.isEmpty else {
|
|
244
266
|
openRouterStatus.stringValue = "Enter an OpenRouter model id, then click Activate Selected Model."
|
|
245
267
|
return
|
|
246
268
|
}
|
|
247
269
|
guard !busy else { openRouterStatus.stringValue = "Another provider action is already running."; return }
|
|
270
|
+
guard let window = view.window else { return }
|
|
271
|
+
AlertFactory.confirmSheet(
|
|
272
|
+
window: window,
|
|
273
|
+
title: "Activate OpenRouter?",
|
|
274
|
+
message: "\(model) becomes the Codex main model and Codex App restarts. SKS remaps the Desktop thread sidebar so prior provider chats stay listed, snapshots the previous provider for Restore, and merges the model cache instead of wiping it. Codex Desktop may still label third-party models as Custom.",
|
|
275
|
+
destructive: false
|
|
276
|
+
) { [weak self] approved in
|
|
277
|
+
guard let self = self, approved else { return }
|
|
278
|
+
self.performUseOpenRouter(model: model)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
@objc func restorePreviousDesktopRouting() {
|
|
283
|
+
openRouterActionRan = true
|
|
284
|
+
guard !busy else { openRouterStatus.stringValue = "Another provider action is already running."; return }
|
|
285
|
+
guard let window = view.window else { return }
|
|
286
|
+
AlertFactory.confirmSheet(
|
|
287
|
+
window: window,
|
|
288
|
+
title: "Restore previous provider?",
|
|
289
|
+
message: "Restores the last pre-OpenRouter Desktop provider/model/catalog snapshot, reverses sidebar remap when present, and restarts Codex App.",
|
|
290
|
+
destructive: false
|
|
291
|
+
) { [weak self] approved in
|
|
292
|
+
guard let self = self, approved else { return }
|
|
293
|
+
self.performRestorePreviousDesktopRouting()
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
private func performRestorePreviousDesktopRouting() {
|
|
298
|
+
guard let snapshot = operations.begin(kind: "desktop-routing-restore", mutationGroup: "codex-config", summary: "Restore previous Desktop provider") else {
|
|
299
|
+
openRouterStatus.stringValue = "Another guarded mutation is already running. Wait or open Diagnostics."
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
setBusy(true)
|
|
303
|
+
openRouterStatus.stringValue = "Restoring previous Desktop provider and restarting Codex App…"
|
|
304
|
+
_ = operations.update(snapshot, state: .running, stage: "restoring", progress: nil, summary: "Restore previous Desktop provider")
|
|
305
|
+
processClient.run(["codex-app", "restore-desktop-routing", "--restart-app", "--json"], timeout: NativeView.mutationTimeout) { [weak self] result in
|
|
306
|
+
guard let self = self else { return }
|
|
307
|
+
self.setBusy(false)
|
|
308
|
+
let json = self.json(result.output)
|
|
309
|
+
let ok = result.code == 0 && json?["ok"] as? Bool == true
|
|
310
|
+
let status = json?["status"] as? String ?? (ok ? "restored" : "failed")
|
|
311
|
+
let detail = self.structuredPublicDetail(json, fallback: result.output)
|
|
312
|
+
// Routing rolls back before the sidebar retag, so a blocked retag is
|
|
313
|
+
// partial success: the snapshot is kept and re-running finishes it.
|
|
314
|
+
let sidebarBlocked = status.hasPrefix("restored_sidebar")
|
|
315
|
+
_ = self.operations.update(snapshot, state: ok ? .succeeded : .failed, stage: "complete", progress: 1, summary: ok ? "Previous Desktop provider restored" : sidebarBlocked ? "Desktop provider restored; sidebar retag pending" : "Desktop provider restore needs action")
|
|
316
|
+
self.openRouterStatus.stringValue = ok
|
|
317
|
+
? "Previous provider restored · \(status). Fully quit and reopen Codex App if chats or the picker still look stale."
|
|
318
|
+
: sidebarBlocked
|
|
319
|
+
? "Provider restored, but prior-provider chats stay hidden · fully quit Codex App, then run Restore previous provider again."
|
|
320
|
+
: "Restore failed · \(status) · \(detail)"
|
|
321
|
+
self.refreshOpenRouterStatus()
|
|
322
|
+
self.refresh()
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
private func performUseOpenRouter(model: String) {
|
|
248
327
|
guard let snapshot = operations.begin(kind: "openrouter-use", mutationGroup: "codex-config", summary: "Use OpenRouter") else {
|
|
249
328
|
openRouterStatus.stringValue = "Another guarded mutation is already running. Wait or open Diagnostics."
|
|
250
329
|
return
|
|
@@ -266,11 +345,20 @@ extension ProvidersViewController {
|
|
|
266
345
|
&& activationJson?["config_applied"] as? Bool == true
|
|
267
346
|
&& selected
|
|
268
347
|
&& activeModel == model
|
|
348
|
+
if configApplied {
|
|
349
|
+
self.openRouterModelSelectionPending = false
|
|
350
|
+
}
|
|
269
351
|
let restartOK = activationJson?["restart_ok"] as? Bool == true
|
|
352
|
+
let remapped = (activationJson?["thread_sidebar_remap"] as? [String: Any])?["remapped"] as? Int ?? 0
|
|
353
|
+
let restoreAvailable = activationJson?["previous_routing_restore_available"] as? Bool == true
|
|
270
354
|
let complete = configApplied && restartOK
|
|
271
355
|
_ = self.operations.update(snapshot, state: complete ? .succeeded : .failed, stage: "complete", progress: 1, summary: complete ? "OpenRouter main model active" : configApplied ? "OpenRouter saved; restart required" : "OpenRouter activation needs action")
|
|
272
356
|
if complete {
|
|
273
|
-
|
|
357
|
+
var parts = ["Activation complete · OpenRouter is active · main model \(model)"]
|
|
358
|
+
if remapped > 0 { parts.append("sidebar kept \(remapped) prior-provider chats visible") }
|
|
359
|
+
if restoreAvailable { parts.append("Restore previous provider is available") }
|
|
360
|
+
parts.append("Desktop may still show Custom for third-party models")
|
|
361
|
+
self.openRouterStatus.stringValue = parts.joined(separator: " · ") + "."
|
|
274
362
|
} else if configApplied {
|
|
275
363
|
self.openRouterStatus.stringValue = "Configuration saved · main model \(model) is selected, but Codex App did not restart. Next: reopen Codex App, then verify status."
|
|
276
364
|
} else {
|
|
@@ -285,7 +373,7 @@ extension ProvidersViewController {
|
|
|
285
373
|
openRouterModelField.stringValue.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
286
374
|
}
|
|
287
375
|
|
|
288
|
-
|
|
376
|
+
func structuredPublicDetail(_ json: [String: Any]?, fallback: String) -> String {
|
|
289
377
|
if let blockers = json?["blockers"] as? [String], !blockers.isEmpty {
|
|
290
378
|
let error = publicError(json).map { " · \($0)" } ?? ""
|
|
291
379
|
return "Reason: \(blockers.joined(separator: ", ").replacingOccurrences(of: "_", with: " "))\(error). Next: \((json?["hint"] as? String) ?? "review the key, model id, and network, then retry")."
|
|
@@ -295,7 +383,7 @@ extension ProvidersViewController {
|
|
|
295
383
|
return "Next: \(NativeView.redactPreview(fallback))"
|
|
296
384
|
}
|
|
297
385
|
|
|
298
|
-
|
|
386
|
+
func publicError(_ json: [String: Any]?) -> String? {
|
|
299
387
|
if let value = json?["error"] as? String { return value }
|
|
300
388
|
guard let value = json?["error"] as? [String: Any] else { return nil }
|
|
301
389
|
let code = value["code"] as? String
|
|
@@ -303,152 +391,4 @@ extension ProvidersViewController {
|
|
|
303
391
|
return [code, message].compactMap { $0 }.joined(separator: ": ")
|
|
304
392
|
}
|
|
305
393
|
|
|
306
|
-
@objc func refreshRoleModelsAction(_ sender: NSButton) {
|
|
307
|
-
refreshRoleModels()
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
func refreshRoleModels() {
|
|
311
|
-
guard !roleRefreshInFlight else { return }
|
|
312
|
-
roleRefreshInFlight = true
|
|
313
|
-
roleRefreshButton?.isEnabled = false
|
|
314
|
-
roleStatus.stringValue = "Loading role model settings…"
|
|
315
|
-
processClient.run(["codex-app", "role-models", "--json"], timeout: NativeView.statusTimeout) { [weak self] result in
|
|
316
|
-
guard let self = self else { return }
|
|
317
|
-
self.roleRefreshInFlight = false
|
|
318
|
-
self.roleRefreshButton?.isEnabled = !self.busy
|
|
319
|
-
guard result.code == 0, let json = self.json(result.output) else {
|
|
320
|
-
self.roleProfilesLoaded = false
|
|
321
|
-
self.updateRoleControlAvailability()
|
|
322
|
-
self.roleStatus.stringValue = "Role settings unavailable · existing configuration was not changed."
|
|
323
|
-
return
|
|
324
|
-
}
|
|
325
|
-
self.configureSupportedRoleProfiles(json)
|
|
326
|
-
var loaded = 0
|
|
327
|
-
for (role, controls) in self.roleRows {
|
|
328
|
-
guard let payload = self.rolePayload(json, role: role) else {
|
|
329
|
-
controls.current.stringValue = "Current: unavailable · Effective: unavailable"
|
|
330
|
-
continue
|
|
331
|
-
}
|
|
332
|
-
let configured = (payload["configured"] as? [String: Any]) ?? (payload["override"] as? [String: Any])
|
|
333
|
-
let effective = (payload["effective"] as? [String: Any]) ?? payload
|
|
334
|
-
let configuredModel = (configured?["model"] as? String) ?? (payload["configured_model"] as? String)
|
|
335
|
-
let configuredReasoning = self.reasoningValue(configured) ?? (payload["configured_reasoning"] as? String)
|
|
336
|
-
let effectiveModel = (effective["model"] as? String) ?? (payload["effective_model"] as? String) ?? "unavailable"
|
|
337
|
-
let effectiveReasoning = self.reasoningValue(effective)
|
|
338
|
-
?? (payload["effective_reasoning_effort"] as? String)
|
|
339
|
-
?? (payload["effective_reasoning"] as? String)
|
|
340
|
-
?? "unavailable"
|
|
341
|
-
self.selectRoleProfile(model: configuredModel ?? effectiveModel, reasoning: configuredReasoning ?? effectiveReasoning, controls: controls)
|
|
342
|
-
let current = configuredModel.map { "\($0) / \(configuredReasoning ?? "default")" } ?? "default (no override)"
|
|
343
|
-
controls.current.stringValue = "Current: \(current) · Effective: \(effectiveModel) / \(effectiveReasoning)"
|
|
344
|
-
loaded += 1
|
|
345
|
-
}
|
|
346
|
-
self.roleProfilesLoaded = !self.supportedRoleProfiles.isEmpty
|
|
347
|
-
self.updateRoleControlAvailability()
|
|
348
|
-
self.roleStatus.stringValue = "Loaded \(loaded) of \(self.roleRows.count) role settings. Save creates an override; Reset removes it."
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
func updateRoleControlAvailability() {
|
|
353
|
-
let enabled = !busy && roleProfilesLoaded
|
|
354
|
-
for controls in roleRows.values {
|
|
355
|
-
controls.model.isEnabled = enabled
|
|
356
|
-
controls.reasoning.isEnabled = enabled
|
|
357
|
-
controls.save.isEnabled = enabled
|
|
358
|
-
controls.reset.isEnabled = enabled
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
private func configureSupportedRoleProfiles(_ json: [String: Any]) {
|
|
363
|
-
let rows = json["supported_profiles"] as? [[String: Any]] ?? []
|
|
364
|
-
supportedRoleProfiles = rows.compactMap { row in
|
|
365
|
-
guard let model = row["model"] as? String,
|
|
366
|
-
let reasoning = row["reasoning_effort"] as? String,
|
|
367
|
-
!model.isEmpty, !reasoning.isEmpty else { return nil }
|
|
368
|
-
return (model, reasoning)
|
|
369
|
-
}
|
|
370
|
-
let models = Array(Set(supportedRoleProfiles.map(\.model))).sorted()
|
|
371
|
-
for controls in roleRows.values {
|
|
372
|
-
controls.model.removeAllItems()
|
|
373
|
-
controls.model.addItems(withTitles: models)
|
|
374
|
-
controls.reasoning.removeAllItems()
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
private func rolePayload(_ json: [String: Any], role: String) -> [String: Any]? {
|
|
379
|
-
if let roles = json["roles"] as? [String: Any], let payload = roles[role] as? [String: Any] { return payload }
|
|
380
|
-
if let payload = json[role] as? [String: Any] { return payload }
|
|
381
|
-
if let roles = json["roles"] as? [[String: Any]] {
|
|
382
|
-
return roles.first { ($0["role"] as? String) == role || ($0["id"] as? String) == role }
|
|
383
|
-
}
|
|
384
|
-
return nil
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
private func reasoningValue(_ json: [String: Any]?) -> String? {
|
|
388
|
-
(json?["reasoning"] as? String) ?? (json?["reasoning_effort"] as? String) ?? (json?["model_reasoning_effort"] as? String)
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
private func selectRoleProfile(model: String, reasoning: String, controls: RoleModelControls) {
|
|
392
|
-
let selectedModel = controls.model.itemTitles.contains(model) ? model : (controls.model.itemTitles.first ?? "")
|
|
393
|
-
controls.model.selectItem(withTitle: selectedModel)
|
|
394
|
-
updateReasoningChoices(controls, preferred: reasoning)
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
@objc private func roleModelSelectionChanged(_ sender: NSPopUpButton) {
|
|
398
|
-
guard let role = sender.identifier?.rawValue, let controls = roleRows[role] else { return }
|
|
399
|
-
updateReasoningChoices(controls, preferred: nil)
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
private func updateReasoningChoices(_ controls: RoleModelControls, preferred: String?) {
|
|
403
|
-
let model = controls.model.titleOfSelectedItem ?? ""
|
|
404
|
-
let efforts = supportedRoleProfiles.filter { $0.model == model }.map(\.reasoning)
|
|
405
|
-
controls.reasoning.removeAllItems()
|
|
406
|
-
controls.reasoning.addItems(withTitles: efforts)
|
|
407
|
-
if let preferred = preferred, efforts.contains(preferred) { controls.reasoning.selectItem(withTitle: preferred) }
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
@objc func saveRoleModel(_ sender: NSButton) {
|
|
411
|
-
guard let role = sender.identifier?.rawValue, let controls = roleRows[role] else { return }
|
|
412
|
-
let model = controls.model.titleOfSelectedItem ?? ""
|
|
413
|
-
let reasoning = controls.reasoning.titleOfSelectedItem ?? "medium"
|
|
414
|
-
guard !model.isEmpty else { roleStatus.stringValue = "Save blocked for \(role) · enter a model id."; return }
|
|
415
|
-
runRoleMutation(
|
|
416
|
-
["codex-app", "set-role-model", "--role", role, "--model", model, "--reasoning", reasoning, "--json"],
|
|
417
|
-
role: role,
|
|
418
|
-
kind: "role-model-set",
|
|
419
|
-
running: "Saving \(role) override…",
|
|
420
|
-
success: "Saved \(role) · \(model) / \(reasoning). Next: new tasks for this role use the effective override."
|
|
421
|
-
)
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
@objc func resetRoleModel(_ sender: NSButton) {
|
|
425
|
-
guard let role = sender.identifier?.rawValue else { return }
|
|
426
|
-
runRoleMutation(
|
|
427
|
-
["codex-app", "reset-role-model", "--role", role, "--json"],
|
|
428
|
-
role: role,
|
|
429
|
-
kind: "role-model-reset",
|
|
430
|
-
running: "Resetting \(role) override…",
|
|
431
|
-
success: "Reset \(role). Next: new tasks use the effective default shown below."
|
|
432
|
-
)
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
private func runRoleMutation(_ args: [String], role: String, kind: String, running: String, success: String) {
|
|
436
|
-
guard !busy else { roleStatus.stringValue = "Another provider action is already running."; return }
|
|
437
|
-
guard let snapshot = operations.begin(kind: kind, mutationGroup: "codex-config", summary: running) else {
|
|
438
|
-
roleStatus.stringValue = "Another guarded mutation is already running. Wait or open Diagnostics."
|
|
439
|
-
return
|
|
440
|
-
}
|
|
441
|
-
setBusy(true)
|
|
442
|
-
roleStatus.stringValue = running
|
|
443
|
-
_ = operations.update(snapshot, state: .running, stage: "saving", progress: nil, summary: running)
|
|
444
|
-
processClient.run(args, timeout: NativeView.mutationTimeout) { [weak self] result in
|
|
445
|
-
guard let self = self else { return }
|
|
446
|
-
self.setBusy(false)
|
|
447
|
-
let json = self.json(result.output)
|
|
448
|
-
let ok = result.code == 0 && json?["ok"] as? Bool == true
|
|
449
|
-
_ = self.operations.update(snapshot, state: ok ? .succeeded : .failed, stage: "complete", progress: 1, summary: ok ? "Role model setting saved" : "Role model setting needs action")
|
|
450
|
-
self.roleStatus.stringValue = ok ? success : "\(role) change failed · \(self.structuredPublicDetail(json, fallback: result.output))"
|
|
451
|
-
self.refreshRoleModels()
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
394
|
}
|