sneakoscope 7.0.2 → 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.
- package/README.md +9 -7
- package/config/codex-releases/{rust-v0.144.5.json → rust-v0.145.0.json} +14 -8
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/sks-dispatch.js +0 -3
- package/dist/cli/command-manifest-lite.js +1 -2
- package/dist/cli/command-registry.js +0 -4
- package/dist/cli/global-mode-router.js +5 -12
- package/dist/cli/install-helpers-codex-lb-chain.js +24 -2
- package/dist/cli/install-helpers-codex-lb-config.js +10 -25
- package/dist/cli/install-helpers-codex-lb-selftest-chain.js +0 -3
- package/dist/cli/install-helpers-codex-lb-selftest.js +0 -17
- package/dist/cli/install-helpers-install-support.js +1 -2
- package/dist/cli/install-helpers.js +83 -99
- package/dist/cli/router.js +22 -31
- package/dist/commands/codex-app.js +20 -2
- package/dist/commands/codex-lb.js +176 -22
- package/dist/commands/codex.js +3 -8
- package/dist/commands/conflicts.js +26 -3
- package/dist/commands/doctor.js +26 -31
- package/dist/commands/perf.js +5 -1
- package/dist/commands/zellij-slot-column-anchor.js +0 -2
- package/dist/commands/zellij-slot-pane.js +0 -7
- package/dist/commands/zellij.js +0 -2
- package/dist/config/skills-manifest.json +52 -52
- package/dist/core/agent-bridge/agent-manifest.js +192 -1
- package/dist/core/agent-bridge/agent-mode.js +0 -5
- package/dist/core/agent-bridge/host-capability-policy.js +189 -0
- package/dist/core/agent-bridge/host-capability-runtime.js +1395 -0
- package/dist/core/agent-bridge/mcp-server.js +1 -11
- package/dist/core/agents/agent-effort-policy.js +7 -10
- package/dist/core/agents/agent-orchestrator.js +0 -4
- package/dist/core/agents/agent-proof-evidence.js +0 -2
- package/dist/core/agents/agent-roster.js +6 -5
- package/dist/core/agents/agent-runner-ollama.js +0 -3
- package/dist/core/agents/agent-scheduler.js +7 -10
- package/dist/core/agents/agent-schema.js +3 -1
- package/dist/core/agents/agent-task-graph.js +4 -1
- package/dist/core/agents/agent-work-partition.js +4 -2
- package/dist/core/agents/native-cli-worker-runtime.js +5 -17
- package/dist/core/agents/work-partition/repo-inventory.js +0 -2
- package/dist/core/auto-review.js +8 -14
- package/dist/core/bench.js +0 -14
- package/dist/core/code-structure.js +0 -3
- package/dist/core/codex/agent-config-file-repair.js +0 -8
- package/dist/core/codex/codex-cli-update.js +122 -20
- package/dist/core/codex/codex-config-eperm-repair.js +0 -4
- package/dist/core/codex/codex-config-guard.js +0 -3
- package/dist/core/codex/codex-config-readability.js +0 -13
- package/dist/core/codex/codex-project-config-policy.js +0 -33
- package/dist/core/codex/codex-startup-config-postcheck.js +5 -0
- package/dist/core/codex/official-goal-mode.js +0 -2
- package/dist/core/codex-app/codex-agent-type-probe.js +31 -24
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +5 -7
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +44 -7
- package/dist/core/codex-app/glm-model-profile.js +1 -1
- package/dist/core/codex-app/glm-profile-installer.js +40 -41
- package/dist/core/codex-app/glm-profile-schema.js +7 -11
- package/dist/core/codex-app/menubar/constants.js +1 -0
- package/dist/core/codex-app/menubar/launch-agent.js +37 -1
- package/dist/core/codex-app/openrouter-activate.js +152 -0
- package/dist/core/codex-app/openrouter-provider.js +82 -0
- package/dist/core/codex-app/sks-menubar.js +0 -1
- package/dist/core/codex-app.js +14 -32
- package/dist/core/codex-compat/codex-capability-matrix.js +208 -0
- package/dist/core/codex-compat/codex-hook-output-builders.js +9 -1
- package/dist/core/codex-compat/codex-hook-output-normalizer.js +1 -1
- package/dist/core/codex-compat/codex-hook-semantic-validator.js +3 -2
- package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -2
- package/dist/core/codex-compat/codex-release-manifest.js +15 -8
- package/dist/core/codex-compat/codex-version-policy.js +77 -15
- package/dist/core/codex-control/codex-0144-capability.js +1 -1
- package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -3
- package/dist/core/codex-control/codex-reliability-shield.js +0 -8
- package/dist/core/codex-control/codex-sdk-adapter.js +0 -3
- package/dist/core/codex-control/codex-sdk-config-policy.js +0 -2
- package/dist/core/codex-control/codex-sdk-env-policy.js +61 -16
- package/dist/core/codex-control/codex-task-runner.js +0 -7
- package/dist/core/codex-control/codex-thread-registry.js +0 -4
- package/dist/core/codex-lb/codex-lb-env.js +133 -24
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -4
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +1 -1
- package/dist/core/codex-model-guard.js +0 -14
- package/dist/core/codex-native/codex-native-feature-broker.js +67 -22
- package/dist/core/codex-native/codex-native-interop-policy.js +81 -9
- package/dist/core/codex-native/confined-report-writer.js +21 -0
- package/dist/core/codex-native/core-skill-integrity.js +169 -20
- package/dist/core/codex-native/project-skill-dedupe.js +55 -13
- package/dist/core/codex-native/skill-registry-ledger.js +137 -16
- package/dist/core/codex-native/sks-skill-paths.js +185 -0
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +3 -3
- package/dist/core/commands/agent-bridge-command.js +28 -8
- package/dist/core/commands/basic-cli.js +89 -42
- package/dist/core/commands/bench-command.js +5 -1
- package/dist/core/commands/command-utils.js +0 -5
- package/dist/core/commands/image-ux-review-command.js +0 -9
- package/dist/core/commands/mad-sks-command.js +55 -208
- package/dist/core/commands/naruto-command.js +55 -21
- package/dist/core/commands/ppt-command.js +0 -9
- package/dist/core/commands/run-command.js +8 -2
- package/dist/core/commands/seo-command.js +0 -6
- package/dist/core/commands/wiki-command.js +0 -14
- package/dist/core/computer-use-live-evidence.js +0 -5
- package/dist/core/config/secret-preservation.js +0 -11
- package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +0 -2
- package/dist/core/daemon/sksd-hook-daemon.js +1 -29
- package/dist/core/daemon/sksd-hook-dispatch.js +0 -17
- package/dist/core/db-safety.js +0 -7
- package/dist/core/doctor/browser-use-repair.js +0 -2
- package/dist/core/doctor/command-alias-cleanup.js +37 -9
- package/dist/core/doctor/current-project-guidance.js +6 -3
- package/dist/core/doctor/doctor-codex-startup-repair.js +0 -3
- package/dist/core/doctor/doctor-dirty-planner.js +1 -1
- package/dist/core/doctor/doctor-readiness-matrix.js +12 -0
- package/dist/core/doctor/doctor-skill-reconcile.js +32 -0
- package/dist/core/doctor/imagegen-repair.js +0 -2
- package/dist/core/doctor/mcp-transport-collision-repair.js +0 -3
- package/dist/core/doctor/retired-auto-review-config.js +9 -1
- package/dist/core/doctor/retired-managed-residue-private.js +5 -4
- package/dist/core/doctor/retired-managed-residue-runtime.js +9 -1
- package/dist/core/doctor/skill-legacy-surface.js +351 -0
- package/dist/core/doctor/supabase-mcp-repair.js +0 -11
- package/dist/core/evaluation.js +3 -0
- package/dist/core/feature-fixture-executor.js +0 -48
- package/dist/core/feature-fixtures.js +0 -6
- package/dist/core/fsx.js +11 -12
- package/dist/core/harness-conflicts.js +177 -18
- package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +0 -5
- package/dist/core/hooks-runtime/hook-context.js +202 -0
- package/dist/core/hooks-runtime/hook-io.js +1 -12
- package/dist/core/hooks-runtime/light-turn.js +0 -2
- package/dist/core/hooks-runtime/naruto-decision-gate.js +4 -1
- package/dist/core/hooks-runtime/naruto-terminal-finalization.js +91 -0
- package/dist/core/hooks-runtime/official-subagent-lifecycle.js +369 -0
- package/dist/core/hooks-runtime/standalone-parent-host-capability.js +98 -0
- package/dist/core/hooks-runtime/subagent-context.js +59 -0
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +29 -0
- package/dist/core/hooks-runtime/subagent-skill-availability-evidence.js +195 -0
- package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +316 -0
- package/dist/core/hooks-runtime/subagent-skill-availability.js +217 -0
- package/dist/core/hooks-runtime.js +275 -540
- package/dist/core/image-ux-review/codex-app-generated-image-discovery.js +0 -17
- package/dist/core/image-ux-review/imagegen-adapter.js +0 -14
- package/dist/core/imagegen/imagegen-auth-readiness.js +0 -9
- package/dist/core/imagegen/imagegen-capability.js +0 -3
- package/dist/core/init/managed-skill-install.js +42 -0
- package/dist/core/init/skills.js +248 -75
- package/dist/core/init.js +19 -45
- package/dist/core/lean-engineering-policy.js +0 -2
- package/dist/core/locks/file-lock.js +0 -21
- package/dist/core/loops/loop-planner.js +0 -6
- package/dist/core/loops/loop-runtime.js +0 -1
- package/dist/core/loops/loop-worker-runtime.js +0 -19
- package/dist/core/mad-sks/executors/db-write-executor.js +0 -4
- package/dist/core/mad-sks/executors/executor-base.js +0 -10
- package/dist/core/mad-sks/immutable-harness-guard.js +0 -5
- package/dist/core/mad-sks/sql-plane/coordinator.js +0 -5
- package/dist/core/mad-sks/sql-plane/ledger.js +0 -4
- package/dist/core/mad-sks/sql-plane/lock.js +0 -4
- package/dist/core/mad-sks/sql-plane/mcp-executor.js +0 -9
- package/dist/core/mad-sks/sql-plane/policy-resolver.js +0 -2
- package/dist/core/mad-sks/sql-plane/postconditions.js +0 -4
- package/dist/core/mad-sks/sql-plane/recovery.js +0 -2
- package/dist/core/mad-sks/sql-plane/runtime-profile.js +0 -8
- package/dist/core/managed-assets/managed-assets-manifest.js +1 -7
- package/dist/core/mcp-config/health-check.js +10 -3
- package/dist/core/migration/migration-transaction-journal.js +0 -8
- package/dist/core/mission.js +0 -2
- package/dist/core/naruto/naruto-active-pool.js +0 -2
- package/dist/core/naruto/naruto-concurrency-governor.js +18 -11
- package/dist/core/naruto/naruto-real-write-proof.js +0 -4
- package/dist/core/naruto/naruto-write-e2e.js +0 -1
- package/dist/core/perf/perf-budget.js +0 -5
- package/dist/core/permission-gates.js +0 -2
- package/dist/core/pipeline-internals/runtime-core.js +15 -5
- package/dist/core/pipeline-internals/runtime-gates.js +7 -19
- package/dist/core/preflight/parallel-preflight-engine.js +1 -12
- package/dist/core/proof/evidence-collector.js +0 -2
- package/dist/core/proof/route-finalizer.js +0 -1
- package/dist/core/proof/selftest-proof-fixtures.js +0 -5
- package/dist/core/providers/openrouter/openrouter-client.js +2 -2
- package/dist/core/providers/openrouter/openrouter-provider-health.js +1 -1
- package/dist/core/providers/{glm/glm-request-cache.js → openrouter/openrouter-request-cache.js} +5 -6
- package/dist/core/providers/openrouter/openrouter-secret-store.js +0 -1
- package/dist/core/providers/openrouter/openrouter-stream.js +2 -4
- package/dist/core/questions.js +3 -3
- package/dist/core/release/gate-manifest.js +0 -5
- package/dist/core/release/package-size-budget.js +2 -2
- package/dist/core/release/release-gate-batch-runner.js +11 -2
- package/dist/core/release/release-gate-cache-v2.js +0 -4
- package/dist/core/release/release-gate-contract.js +0 -7
- package/dist/core/release/release-gate-hermetic-env.js +0 -5
- package/dist/core/release/release-pack-receipt.js +1 -0
- package/dist/core/release-parallel-full-coverage.js +0 -2
- package/dist/core/remote/ssh-worker-client.js +0 -3
- package/dist/core/research/research-adversarial-review.js +6 -2
- package/dist/core/responses-retry-policy.js +0 -10
- package/dist/core/retention.js +0 -7
- package/dist/core/routes/constants.js +0 -3
- package/dist/core/routes/model-mode-router.js +10 -19
- package/dist/core/routes.js +91 -17
- package/dist/core/safety/command-contract/contracts.js +2 -0
- package/dist/core/safety/mutation-guard.js +0 -25
- package/dist/core/safety/mutation-ledger.js +0 -9
- package/dist/core/safety/requested-scope-contract.js +0 -0
- package/dist/core/security/high-risk-contracts.js +0 -1
- package/dist/core/skills/core-skill-card.js +0 -0
- package/dist/core/skills/core-skill-deployment.js +0 -13
- package/dist/core/skills/core-skill-epoch.js +0 -11
- package/dist/core/skills/core-skill-meta-update.js +0 -6
- package/dist/core/skills/core-skill-patch-apply.js +0 -7
- package/dist/core/skills/core-skill-patch.js +0 -8
- package/dist/core/skills/core-skill-reflection.js +0 -16
- package/dist/core/skills/core-skill-runtime.js +0 -6
- package/dist/core/skills/core-skill-scorer.js +0 -7
- package/dist/core/skills/core-skill-trainer.js +0 -11
- package/dist/core/skills/core-skill-types.js +0 -9
- package/dist/core/skills/core-skill-validation.js +0 -5
- package/dist/core/skills/rejected-skill-patch-buffer.js +0 -2
- package/dist/core/stop-gate/stop-gate-check.js +0 -8
- package/dist/core/stop-gate/stop-gate-resolver.js +0 -7
- package/dist/core/stop-gate/stop-gate-writer.js +0 -5
- package/dist/core/subagents/model-policy.js +0 -7
- package/dist/core/subagents/naruto-help-contract.js +3 -2
- package/dist/core/subagents/naruto-proof-projection.js +580 -12
- package/dist/core/subagents/official-subagent-config.js +256 -40
- package/dist/core/subagents/official-subagent-preparation.js +11 -7
- package/dist/core/subagents/official-subagent-prompt.js +29 -0
- package/dist/core/subagents/official-subagent-runner.js +379 -39
- package/dist/core/subagents/subagent-evidence.js +378 -9
- package/dist/core/subagents/terminology.js +11 -6
- package/dist/core/subagents/thread-budget.js +6 -3
- package/dist/core/subagents/triwiki-attention.js +0 -4
- package/dist/core/subagents/wave-parent-guidance.js +54 -9
- package/dist/core/telegram/runtime.js +0 -1
- package/dist/core/triwiki/code-index-scanner.js +0 -3
- package/dist/core/triwiki/code-pack-head-freshness.js +0 -10
- package/dist/core/triwiki/code-pack.js +0 -2
- package/dist/core/triwiki/triwiki-cache-key.js +0 -1
- package/dist/core/triwiki/triwiki-proof-bank.js +0 -1
- package/dist/core/triwiki-attention.js +0 -10
- package/dist/core/triwiki-provenance.js +0 -5
- package/dist/core/triwiki-runtime.js +0 -12
- package/dist/core/triwiki-wrongness/wrongness-ledger.js +0 -7
- package/dist/core/triwiki-wrongness/wrongness-schema.js +0 -3
- package/dist/core/trust-kernel/trust-report.js +0 -7
- package/dist/core/update/update-migration-state.js +113 -61
- package/dist/core/update-check.js +2 -14
- package/dist/core/version-manager.js +43 -4
- package/dist/core/version.js +1 -1
- package/dist/core/work-order-ledger.js +0 -17
- package/dist/core/zellij/zellij-clipboard-config.js +0 -18
- package/dist/core/zellij/zellij-fake-adapter.js +16 -0
- package/dist/core/zellij/zellij-lane-renderer.js +5 -46
- package/dist/core/zellij/zellij-lane-runtime.js +0 -1
- package/dist/core/zellij/zellij-launcher.js +35 -35
- package/dist/core/zellij/zellij-official-subagent-activity.js +0 -5
- package/dist/core/zellij/zellij-official-subagent-telemetry.js +0 -5
- package/dist/core/zellij/zellij-pane-proof.js +3 -3
- package/dist/core/zellij/zellij-screen-proof.js +0 -7
- package/dist/core/zellij/zellij-slot-column-anchor.js +0 -1
- package/dist/core/zellij/zellij-slot-pane-renderer.js +0 -9
- package/dist/core/zellij/zellij-slot-telemetry.js +6 -16
- package/dist/core/zellij/zellij-ui-mode.js +0 -7
- package/dist/core/zellij/zellij-update.js +0 -29
- package/dist/core/zellij/zellij-worker-pane-manager.js +0 -39
- package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +61 -2
- package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +10 -3
- package/dist/native/sks-menubar/Sources/OverviewViewController.swift +55 -3
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +76 -0
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +273 -54
- package/dist/native/sks-menubar/Sources/RemoteTelegramViewController.swift +5 -1
- package/dist/native/sks-menubar/Sources/SettingsViewController.swift +2 -2
- package/dist/native/sks-menubar/Sources/StatusItemController.swift +28 -2
- package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +96 -13
- package/dist/scripts/agent-message-bus-reader-check.js +0 -1
- package/dist/scripts/all-feature-deep-completion-check.js +0 -1
- package/dist/scripts/appshots-thread-attachment-discovery-check.js +0 -1
- package/dist/scripts/architecture-guard-check.js +0 -1
- package/dist/scripts/build-dist.js +0 -1
- package/dist/scripts/build-once-runner-check.js +0 -1
- package/dist/scripts/canonical-test-runner.js +0 -2
- package/dist/scripts/certificate-sla-check.js +0 -1
- package/dist/scripts/changelog-check.js +0 -1
- package/dist/scripts/check-cli-entrypoint.js +0 -1
- package/dist/scripts/check-command-module-budget.js +0 -7
- package/dist/scripts/check-feature-quality.js +0 -1
- package/dist/scripts/check-legacy-free.js +0 -1
- package/dist/scripts/check-pipeline-runtime.js +0 -1
- package/dist/scripts/check-runtime-schemas.js +0 -1
- package/dist/scripts/codex-0-134-runner-truth-check.js +0 -1
- package/dist/scripts/codex-0-137-compat-check.js +0 -1
- package/dist/scripts/codex-0138-capability-artifact-check.js +0 -1
- package/dist/scripts/codex-0138-capability-check.js +0 -1
- package/dist/scripts/codex-0138-doctor-check.js +0 -1
- package/dist/scripts/codex-0138-feature-probes-check.js +0 -1
- package/dist/scripts/codex-0144-app-server-v2-check.js +5 -5
- package/dist/scripts/codex-0144-core-real-probes-check.js +0 -1
- package/dist/scripts/codex-app-handoff-check.js +0 -1
- package/dist/scripts/codex-app-handoff-launch-check.js +0 -1
- package/dist/scripts/codex-config-load-probe.js +0 -5
- package/dist/scripts/codex-control-all-pipelines-check.js +0 -1
- package/dist/scripts/codex-control-event-stream-ledger-check.js +0 -1
- package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +0 -1
- package/dist/scripts/codex-permission-profiles-check.js +0 -1
- package/dist/scripts/codex-plugin-app-template-policy-check.js +0 -1
- package/dist/scripts/codex-project-config-policy-splitter-check.js +0 -1
- package/dist/scripts/codex-sdk-all-pipelines-check.js +0 -1
- package/dist/scripts/codex-sdk-backend-router-check.js +0 -1
- package/dist/scripts/codex-sdk-capability-check.js +0 -1
- package/dist/scripts/codex-sdk-event-stream-ledger-check.js +0 -1
- package/dist/scripts/codex-sdk-real-smoke-check.js +0 -1
- package/dist/scripts/concurrent-session-collision-check.js +9 -0
- package/dist/scripts/context7-evidence-dedupe-check.js +0 -1
- package/dist/scripts/core-skill-card-schema-check.js +0 -11
- package/dist/scripts/core-skill-deployment-snapshot-check.js +0 -10
- package/dist/scripts/core-skill-heldout-validation-check.js +0 -11
- package/dist/scripts/core-skill-no-inference-optimizer-check.js +0 -11
- package/dist/scripts/core-skill-patch-check.js +0 -11
- package/dist/scripts/core-skill-route-runtime-integration-check.js +0 -11
- package/dist/scripts/current-command-surface-check.js +1 -1
- package/dist/scripts/current-surface-update-e2e-check.js +2 -4
- package/dist/scripts/current-upgrade-matrix-check.js +0 -1
- package/dist/scripts/dfix-fixture-check.js +0 -1
- package/dist/scripts/dfix-patch-handoff-check.js +0 -1
- package/dist/scripts/dfix-verification-check.js +0 -1
- package/dist/scripts/dfix-verification-recommendation-check.js +0 -1
- package/dist/scripts/docs-truthfulness-check.js +7 -7
- package/dist/scripts/doctor-fastpath-check.js +0 -1
- package/dist/scripts/doctor-fix-production-blackbox.js +1 -1
- package/dist/scripts/doctor-fix-proves-codex-read-check.js +0 -11
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +0 -4
- package/dist/scripts/doctor-idempotence-check.js +0 -1
- package/dist/scripts/doctor-ops-semantics-check.js +0 -1
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +1 -1
- package/dist/scripts/ensure-bin-executable.js +0 -1
- package/dist/scripts/evidence-flagship-coverage-check.js +0 -1
- package/dist/scripts/fast-codex-service-tier-proof-check.js +0 -1
- package/dist/scripts/fixtures/fake-codex-config-loader.js +0 -5
- package/dist/scripts/fsx-hotpath-check.js +0 -1
- package/dist/scripts/gate-policy-audit-check.js +1 -1
- package/dist/scripts/geo-claim-evidence-check.js +0 -1
- package/dist/scripts/geo-cli-blackbox-check.js +0 -1
- package/dist/scripts/geo-crawler-policy-check.js +0 -1
- package/dist/scripts/git-worktree-diff-envelope-check.js +0 -1
- package/dist/scripts/git-worktree-dirty-lock-check.js +0 -1
- package/dist/scripts/git-worktree-dirty-main-detection-check.js +0 -1
- package/dist/scripts/git-worktree-integration-primary-check.js +0 -1
- package/dist/scripts/git-worktree-manifest-append-check.js +0 -1
- package/dist/scripts/git-worktree-untracked-diff-check.js +0 -1
- package/dist/scripts/high-risk-contracts-check.js +0 -1
- package/dist/scripts/hook-latency-budget-check.js +0 -1
- package/dist/scripts/hook-latency-quantum-check.js +0 -1
- package/dist/scripts/image-artifact-path-contract-check.js +0 -1
- package/dist/scripts/imagegen-real-smoke-check.js +0 -1
- package/dist/scripts/import-graph-budget-check.js +0 -1
- package/dist/scripts/installed-package-smoke-check.js +0 -1
- package/dist/scripts/legacy-gate-purge-check.js +0 -1
- package/dist/scripts/lib/codex-sdk-gate-lib.js +0 -3
- package/dist/scripts/lib/ensure-dist-fresh.js +0 -1
- package/dist/scripts/lib/valid-png-fixture.js +0 -1
- package/dist/scripts/local-collab-all-pipelines-final-gpt-check.js +0 -1
- package/dist/scripts/loop-directive-check-lib.js +0 -1
- package/dist/scripts/loop-worker-fixture-child.js +0 -1
- package/dist/scripts/mad-preflight-blocks-unreadable-config-check.js +0 -10
- package/dist/scripts/mad-sks-sql-plane-lifecycle-hook-decision-check.js +0 -1
- package/dist/scripts/mad-sks-sql-plane-result-lifecycle-check.js +0 -1
- package/dist/scripts/mcp-plugin-inventory-check.js +0 -1
- package/dist/scripts/mcp-tool-naming-parity-check.js +0 -1
- package/dist/scripts/model-call-concurrency-check.js +0 -1
- package/dist/scripts/mutation-callsite-coverage-check.js +0 -5
- package/dist/scripts/naruto-codex-e2e-check.js +0 -1
- package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -1
- package/dist/scripts/official-subagent-workflow-check.js +4 -2
- package/dist/scripts/ops-diagnostics-bundle-check.js +0 -1
- package/dist/scripts/packlist-performance-check.js +1 -3
- package/dist/scripts/perf-budget-check.js +0 -1
- package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -1
- package/dist/scripts/ppt-real-export-adapter-check.js +0 -1
- package/dist/scripts/ppt-real-imagegen-smoke-check.js +0 -1
- package/dist/scripts/ppt-real-imagegen-wiring-check.js +0 -1
- package/dist/scripts/ppt-reexport-rereview-check.js +0 -1
- package/dist/scripts/prepublish-fast-check.js +0 -23
- package/dist/scripts/prepublish-release-check-or-fast.js +0 -7
- package/dist/scripts/probe-memoization-check.js +0 -1
- package/dist/scripts/product-design-plugin-routing-check.js +0 -1
- package/dist/scripts/project-skill-dedupe-blackbox.js +36 -9
- package/dist/scripts/prompt-placeholder-guard-check.js +0 -1
- package/dist/scripts/python-codex-sdk-all-pipelines-check.js +0 -3
- package/dist/scripts/qa-loop-app-handoff-capability-check.js +0 -1
- package/dist/scripts/qa-loop-app-handoff-check.js +0 -1
- package/dist/scripts/qa-loop-app-handoff-cli-check.js +0 -1
- package/dist/scripts/qa-loop-app-handoff-confirmation-check.js +0 -1
- package/dist/scripts/qa-loop-app-handoff-gate-lifecycle-check.js +0 -1
- package/dist/scripts/qa-loop-app-handoff-launch-check.js +0 -1
- package/dist/scripts/qa-loop-app-handoff-status-lifecycle-check.js +0 -1
- package/dist/scripts/qa-loop-budget-policy-check.js +0 -1
- package/dist/scripts/qa-loop-effort-escalation-check.js +0 -1
- package/dist/scripts/qa-loop-image-path-exposure-check.js +0 -1
- package/dist/scripts/qa-loop-image-path-prompt-injection-check.js +0 -1
- package/dist/scripts/release-cache-glob-hashing-check.js +0 -1
- package/dist/scripts/release-cache-input-classifier-check.js +0 -1
- package/dist/scripts/release-cache-neutralization-report-check.js +0 -1
- package/dist/scripts/release-cache-version-neutral-fixture-check.js +0 -1
- package/dist/scripts/release-check-stamp.js +0 -4
- package/dist/scripts/release-dist-freshness-check.js +0 -1
- package/dist/scripts/release-full-parallelism-blackbox.js +3 -3
- package/dist/scripts/release-gate-batch-runner-check.js +22 -0
- package/dist/scripts/release-gate-budget-check.js +0 -6
- package/dist/scripts/release-gate-dag-runner-check.js +0 -1
- package/dist/scripts/release-latency-slo-check.js +0 -1
- package/dist/scripts/release-metadata-1-19-check.js +0 -2
- package/dist/scripts/release-metadata-check.js +0 -3
- package/dist/scripts/release-parallel-speed-budget-check.js +0 -5
- package/dist/scripts/release-proof-truth-check.js +0 -1
- package/dist/scripts/release-provenance-check.js +0 -1
- package/dist/scripts/release-real-check.js +0 -1
- package/dist/scripts/release-runtime-truth-matrix-check.js +0 -1
- package/dist/scripts/release-version-truth-check.js +0 -1
- package/dist/scripts/research-blueprint-densifier-check.js +0 -1
- package/dist/scripts/research-claim-builder-check.js +0 -1
- package/dist/scripts/research-complete-package-fixture-check.js +0 -1
- package/dist/scripts/research-final-reviewer-blackbox.js +0 -1
- package/dist/scripts/responses-retry-policy-centralized-check.js +0 -1
- package/dist/scripts/retention-apply-smoke-check.js +0 -1
- package/dist/scripts/retention-budget-check.js +0 -1
- package/dist/scripts/retention-dry-run-check.js +0 -1
- package/dist/scripts/rollback-recovery-smoke-check.js +0 -1
- package/dist/scripts/route-intent-regression-check.js +0 -1
- package/dist/scripts/runtime-current-terminal-check.js +0 -1
- package/dist/scripts/runtime-dist-parity-check.js +0 -1
- package/dist/scripts/runtime-no-src-mjs-check.js +0 -1
- package/dist/scripts/runtime-proof-summary-check.js +0 -1
- package/dist/scripts/runtime-ts-rust-boundary-check.js +0 -15
- package/dist/scripts/runtime-ts-source-of-truth-check.js +0 -1
- package/dist/scripts/scheduler-batch-dispatch-check.js +0 -1
- package/dist/scripts/scheduler-parallel-proof-consistency-check.js +0 -1
- package/dist/scripts/scheduler-utilization-integral-check.js +0 -1
- package/dist/scripts/search-visibility-gate-lib.js +0 -1
- package/dist/scripts/seo-audit-fixture-check.js +0 -1
- package/dist/scripts/seo-cli-blackbox-check.js +0 -1
- package/dist/scripts/seo-geo-geo-disambiguation-check.js +0 -1
- package/dist/scripts/seo-geo-route-identity-check.js +0 -1
- package/dist/scripts/seo-geo-skill-rich-content-check.js +0 -1
- package/dist/scripts/seo-marketing-truthfulness-check.js +0 -1
- package/dist/scripts/seo-metadata-sync-check.js +0 -1
- package/dist/scripts/seo-no-mutation-by-default-check.js +0 -1
- package/dist/scripts/shared-memory-fixture-check.js +0 -1
- package/dist/scripts/side-effect-runtime-report-check.js +0 -1
- package/dist/scripts/sizecheck.js +2 -3
- package/dist/scripts/sks-1-11-gate-lib.js +0 -1
- package/dist/scripts/sks-1-12-real-execution-check-lib.js +0 -1
- package/dist/scripts/sks-1-18-gate-lib.js +0 -1
- package/dist/scripts/sks-menubar-install-check.js +0 -3
- package/dist/scripts/sksd-daemon-check.js +0 -1
- package/dist/scripts/super-search-live-smoke-check.js +0 -1
- package/dist/scripts/super-search-local-http-smoke-check.js +0 -1
- package/dist/scripts/super-search-offline-contract-check.js +0 -1
- package/dist/scripts/super-search-provider-interface-check.js +0 -1
- package/dist/scripts/triwiki-cache-key-check.js +0 -1
- package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -1
- package/dist/scripts/triwiki-proof-bank-check.js +0 -1
- package/dist/scripts/triwiki-proof-card-check.js +0 -1
- package/dist/scripts/trust-fixture-check.js +0 -1
- package/dist/scripts/ultra-router-auto-router-check.js +0 -1
- package/dist/scripts/update-fastpath-check.js +0 -1
- package/dist/scripts/upgrade-migration-matrix-check.js +0 -1
- package/dist/scripts/ux-review-extract-wires-real-extractor-check.js +0 -1
- package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -1
- package/dist/scripts/ux-review-patch-diff-recheck-check.js +0 -1
- package/dist/scripts/ux-review-real-imagegen-smoke-check.js +0 -1
- package/dist/scripts/ux-review-run-wires-imagegen-check.js +0 -1
- package/dist/scripts/write-build-manifest.js +0 -1
- package/dist/scripts/wrongness-fixture-check.js +0 -1
- package/dist/scripts/zellij-capability-check.js +0 -1
- package/dist/scripts/zellij-developer-controls-check.js +0 -1
- package/dist/scripts/zellij-doctor-readiness-check.js +0 -13
- package/dist/scripts/zellij-dynamic-pane-lifecycle-check.js +0 -1
- package/dist/scripts/zellij-fake-adapter-check.js +0 -1
- package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -1
- package/dist/scripts/zellij-lane-renderer-check.js +0 -1
- package/dist/scripts/zellij-launch-command-truth-check.js +0 -12
- package/dist/scripts/zellij-layout-valid-check.js +0 -1
- package/dist/scripts/zellij-pane-creation-lock-metrics-check.js +0 -1
- package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -1
- package/dist/scripts/zellij-pane-lock-does-not-block-worker-check.js +0 -1
- package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -1
- package/dist/scripts/zellij-pane-proof-check.js +0 -1
- package/dist/scripts/zellij-qa-app-handoff-status-check.js +0 -1
- package/dist/scripts/zellij-real-session-cleanup-check.js +0 -1
- package/dist/scripts/zellij-real-session-launch-check.js +0 -1
- package/dist/scripts/zellij-right-column-geometry-proof.js +0 -1
- package/dist/scripts/zellij-right-column-headless-overflow-check.js +0 -1
- package/dist/scripts/zellij-right-column-manager-check.js +0 -1
- package/dist/scripts/zellij-screen-proof-check.js +0 -1
- package/dist/scripts/zellij-slot-only-ui-check.js +0 -1
- package/dist/scripts/zellij-slot-pane-renderer-check.js +0 -1
- package/dist/scripts/zellij-slot-pane-stale-detection-check.js +0 -7
- package/dist/scripts/zellij-slot-telemetry-incremental-check.js +0 -1
- package/dist/scripts/zellij-slot-telemetry-live-flush-check.js +0 -1
- package/dist/scripts/zellij-slot-telemetry-performance-check.js +0 -1
- package/dist/scripts/zellij-stacked-capability-routing-check.js +0 -1
- package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -1
- package/dist/scripts/zellij-stacked-version-matrix-check.js +0 -1
- package/dist/scripts/zellij-stacked-version-parser-check.js +0 -1
- package/dist/scripts/zellij-ui-design-check.js +0 -12
- package/dist/scripts/zellij-update-prompt-matrix-check.js +0 -1
- package/dist/scripts/zellij-update-prompt-mode-check.js +0 -1
- package/dist/scripts/zellij-update-prompt-safety-check.js +0 -1
- package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -2
- package/package.json +6 -7
- package/release-gates.v2.json +426 -93
- package/schemas/codex/app-server-0.145/codex_app_server_protocol.v2.schemas.json +19611 -0
- package/dist/core/commands/glm-command.js +0 -93
- package/dist/core/providers/glm/bench/glm-bench-comparison.js +0 -47
- package/dist/core/providers/glm/bench/glm-bench-fixture.js +0 -64
- package/dist/core/providers/glm/bench/glm-bench-model-lock-proof.js +0 -52
- package/dist/core/providers/glm/bench/glm-bench-report.js +0 -74
- package/dist/core/providers/glm/bench/glm-benchmark-runner.js +0 -243
- package/dist/core/providers/glm/bench/glm-benchmark-types.js +0 -1
- package/dist/core/providers/glm/bench/glm-direct-bench-runner.js +0 -72
- package/dist/core/providers/glm/glm-52-profile.js +0 -82
- package/dist/core/providers/glm/glm-52-request.js +0 -73
- package/dist/core/providers/glm/glm-52-response-guard.js +0 -32
- package/dist/core/providers/glm/glm-52-settings.js +0 -67
- package/dist/core/providers/glm/glm-context-budget.js +0 -14
- package/dist/core/providers/glm/glm-context-cache.js +0 -8
- package/dist/core/providers/glm/glm-direct-run.js +0 -140
- package/dist/core/providers/glm/glm-interactive-launch.js +0 -4
- package/dist/core/providers/glm/glm-latency-trace.js +0 -39
- package/dist/core/providers/glm/glm-loop-guard.js +0 -30
- package/dist/core/providers/glm/glm-mad-launch.js +0 -128
- package/dist/core/providers/glm/glm-mad-mode.js +0 -269
- package/dist/core/providers/glm/glm-model-meta-cache.js +0 -18
- package/dist/core/providers/glm/glm-patch-apply.js +0 -72
- package/dist/core/providers/glm/glm-patch-parser.js +0 -18
- package/dist/core/providers/glm/glm-profile-resolver.js +0 -168
- package/dist/core/providers/glm/glm-readiness.js +0 -4
- package/dist/core/providers/glm/glm-reasoning-policy.js +0 -14
- package/dist/core/providers/glm/glm-run-controller.js +0 -65
- package/dist/core/providers/glm/glm-run-state.js +0 -10
- package/dist/core/providers/glm/glm-run-timeout.js +0 -30
- package/dist/core/providers/glm/glm-speed-context.js +0 -81
- package/dist/core/providers/glm/glm-speed-gate.js +0 -39
- package/dist/core/providers/glm/glm-speed-output-parser.js +0 -39
- package/dist/core/providers/glm/glm-tool-schema-cache.js +0 -18
- package/dist/core/providers/glm/naruto/glm-naruto-apply-transaction.js +0 -135
- package/dist/core/providers/glm/naruto/glm-naruto-artifacts.js +0 -1
- package/dist/core/providers/glm/naruto/glm-naruto-bench.js +0 -6
- package/dist/core/providers/glm/naruto/glm-naruto-budget.js +0 -44
- package/dist/core/providers/glm/naruto/glm-naruto-combined-patch.js +0 -48
- package/dist/core/providers/glm/naruto/glm-naruto-command.js +0 -101
- package/dist/core/providers/glm/naruto/glm-naruto-concurrency-governor.js +0 -37
- package/dist/core/providers/glm/naruto/glm-naruto-conflict-graph.js +0 -79
- package/dist/core/providers/glm/naruto/glm-naruto-critical-path.js +0 -50
- package/dist/core/providers/glm/naruto/glm-naruto-decomposer.js +0 -148
- package/dist/core/providers/glm/naruto/glm-naruto-file-lease.js +0 -22
- package/dist/core/providers/glm/naruto/glm-naruto-final-seal.js +0 -81
- package/dist/core/providers/glm/naruto/glm-naruto-finalizer.js +0 -22
- package/dist/core/providers/glm/naruto/glm-naruto-hunk-conflict.js +0 -15
- package/dist/core/providers/glm/naruto/glm-naruto-hunk-parser.js +0 -35
- package/dist/core/providers/glm/naruto/glm-naruto-isolation-policy.js +0 -37
- package/dist/core/providers/glm/naruto/glm-naruto-judge.js +0 -83
- package/dist/core/providers/glm/naruto/glm-naruto-merge-planner.js +0 -61
- package/dist/core/providers/glm/naruto/glm-naruto-metrics.js +0 -33
- package/dist/core/providers/glm/naruto/glm-naruto-orchestrator.js +0 -486
- package/dist/core/providers/glm/naruto/glm-naruto-parallelism-summary.js +0 -54
- package/dist/core/providers/glm/naruto/glm-naruto-patch-candidate-gate.js +0 -41
- package/dist/core/providers/glm/naruto/glm-naruto-patch-candidate-parser.js +0 -61
- package/dist/core/providers/glm/naruto/glm-naruto-patch-envelope.js +0 -54
- package/dist/core/providers/glm/naruto/glm-naruto-quorum.js +0 -36
- package/dist/core/providers/glm/naruto/glm-naruto-rate-limiter.js +0 -17
- package/dist/core/providers/glm/naruto/glm-naruto-repair-wave.js +0 -20
- package/dist/core/providers/glm/naruto/glm-naruto-requirement-coverage.js +0 -108
- package/dist/core/providers/glm/naruto/glm-naruto-requirement-ledger.js +0 -57
- package/dist/core/providers/glm/naruto/glm-naruto-scoreboard.js +0 -74
- package/dist/core/providers/glm/naruto/glm-naruto-secret-audit.js +0 -90
- package/dist/core/providers/glm/naruto/glm-naruto-session-id.js +0 -9
- package/dist/core/providers/glm/naruto/glm-naruto-shard-planner.js +0 -31
- package/dist/core/providers/glm/naruto/glm-naruto-stage-scheduler.js +0 -84
- package/dist/core/providers/glm/naruto/glm-naruto-targeted-checks.js +0 -75
- package/dist/core/providers/glm/naruto/glm-naruto-task-size-classifier.js +0 -11
- package/dist/core/providers/glm/naruto/glm-naruto-terminal.js +0 -43
- package/dist/core/providers/glm/naruto/glm-naruto-trace.js +0 -173
- package/dist/core/providers/glm/naruto/glm-naruto-types.js +0 -36
- package/dist/core/providers/glm/naruto/glm-naruto-usage-extractor.js +0 -30
- package/dist/core/providers/glm/naruto/glm-naruto-verifier-output.js +0 -30
- package/dist/core/providers/glm/naruto/glm-naruto-work-graph.js +0 -1
- package/dist/core/providers/glm/naruto/glm-naruto-worker-artifacts.js +0 -55
- package/dist/core/providers/glm/naruto/glm-naruto-worker-pool.js +0 -275
- package/dist/core/providers/glm/naruto/glm-naruto-worker-runtime.js +0 -421
- package/dist/core/providers/glm/naruto/glm-naruto-worker-scheduler.js +0 -177
- package/dist/core/providers/glm/naruto/glm-naruto-worker.js +0 -1
- package/dist/core/providers/glm/naruto/glm-naruto-worktree-cleanup.js +0 -19
- package/dist/core/providers/glm/naruto/glm-naruto-worktree-manager.js +0 -71
- package/dist/core/providers/glm/naruto/glm-naruto-worktree-worker.js +0 -73
- package/dist/core/providers/glm/naruto/glm-naruto-worktree.js +0 -62
- package/schemas/codex/app-server-0.144/codex_app_server_protocol.v2.schemas.json +0 -1
|
@@ -4,6 +4,8 @@ import { appendJsonlBounded, ensureDir, nowIso, readJson, readText, writeTextAto
|
|
|
4
4
|
import { withFileLock } from '../locks/file-lock.js';
|
|
5
5
|
export const ZELLIJ_SLOT_TELEMETRY_EVENT_SCHEMA = 'sks.zellij-slot-telemetry-event.v1';
|
|
6
6
|
export const ZELLIJ_SLOT_TELEMETRY_SNAPSHOT_SCHEMA = 'sks.zellij-slot-telemetry-snapshot.v1';
|
|
7
|
+
export const ZELLIJ_SLOT_TELEMETRY_LOCK_TIMEOUT_MS = 2_000;
|
|
8
|
+
export const ZELLIJ_SLOT_TELEMETRY_LOCK_STALE_MS = 15_000;
|
|
7
9
|
const telemetrySnapshotCache = new Map();
|
|
8
10
|
const telemetrySnapshotWriteCounts = new Map();
|
|
9
11
|
const telemetrySnapshotFlushCounts = new Map();
|
|
@@ -24,8 +26,8 @@ export async function appendZellijSlotTelemetry(root, event) {
|
|
|
24
26
|
await ensureDir(path.dirname(file));
|
|
25
27
|
await withFileLock({
|
|
26
28
|
lockPath: `${file}.append.lock`,
|
|
27
|
-
timeoutMs:
|
|
28
|
-
staleMs:
|
|
29
|
+
timeoutMs: ZELLIJ_SLOT_TELEMETRY_LOCK_TIMEOUT_MS,
|
|
30
|
+
staleMs: ZELLIJ_SLOT_TELEMETRY_LOCK_STALE_MS
|
|
29
31
|
}, async () => appendJsonlBounded(file, normalized));
|
|
30
32
|
const previous = await readZellijSlotTelemetrySnapshotNoRebuild(root, missionId);
|
|
31
33
|
if (previous) {
|
|
@@ -50,10 +52,6 @@ export async function readZellijSlotTelemetrySnapshotNoRebuild(root, missionId)
|
|
|
50
52
|
const stat = await statTelemetryFile(snapshotPath);
|
|
51
53
|
const recorded = telemetrySnapshotDiskStat.get(snapshotPath);
|
|
52
54
|
const diskChanged = Boolean(stat) && (!recorded || recorded.mtimeMs !== stat.mtimeMs || recorded.size !== stat.size);
|
|
53
|
-
// CRITICAL: never serve a process-local cache forever. Long-lived reader
|
|
54
|
-
// processes (zellij slot pane renderers in --watch mode) must observe
|
|
55
|
-
// snapshot flushes performed by the orchestrator and worker processes,
|
|
56
|
-
// otherwise the pane renders the same frame for the entire mission.
|
|
57
55
|
if (!diskChanged && cached?.schema === ZELLIJ_SLOT_TELEMETRY_SNAPSHOT_SCHEMA)
|
|
58
56
|
return cached;
|
|
59
57
|
const existing = await readJson(snapshotPath, null);
|
|
@@ -63,11 +61,6 @@ export async function readZellijSlotTelemetrySnapshotNoRebuild(root, missionId)
|
|
|
63
61
|
return cached?.schema === ZELLIJ_SLOT_TELEMETRY_SNAPSHOT_SCHEMA ? cached : null;
|
|
64
62
|
}
|
|
65
63
|
const disk = existing;
|
|
66
|
-
// Merge with any locally cached (possibly not-yet-flushed) slot state so a
|
|
67
|
-
// writer process does not lose its pending events when another process
|
|
68
|
-
// flushed the snapshot file in the meantime. The DISK updated_at stays
|
|
69
|
-
// authoritative on the read path: it reflects the last real flush, which is
|
|
70
|
-
// what stale-telemetry detection must measure.
|
|
71
64
|
const merged = cached?.schema === ZELLIJ_SLOT_TELEMETRY_SNAPSHOT_SCHEMA ? mergeTelemetrySnapshots(disk, cached, { updatedAt: 'base' }) : disk;
|
|
72
65
|
telemetrySnapshotCache.set(snapshotPath, merged);
|
|
73
66
|
return merged;
|
|
@@ -328,15 +321,12 @@ async function writeTelemetrySnapshotFast(file, snapshot) {
|
|
|
328
321
|
await ensureDir(path.dirname(file));
|
|
329
322
|
await withFileLock({
|
|
330
323
|
lockPath: `${file}.lock`,
|
|
331
|
-
timeoutMs:
|
|
332
|
-
staleMs:
|
|
324
|
+
timeoutMs: ZELLIJ_SLOT_TELEMETRY_LOCK_TIMEOUT_MS,
|
|
325
|
+
staleMs: ZELLIJ_SLOT_TELEMETRY_LOCK_STALE_MS
|
|
333
326
|
}, async () => {
|
|
334
327
|
const flushCount = Number(telemetrySnapshotFlushCounts.get(file) || 0) + 1;
|
|
335
328
|
telemetrySnapshotFlushCounts.set(file, flushCount);
|
|
336
329
|
telemetrySnapshotLastFlushMs.set(file, Date.now());
|
|
337
|
-
// Multiple processes (orchestrator + worker children) flush this file.
|
|
338
|
-
// Serialize the read/merge/write critical section so a slower writer
|
|
339
|
-
// cannot overwrite a newer slot observed by a different process.
|
|
340
330
|
const disk = await readJson(file, null);
|
|
341
331
|
const merged = disk?.schema === ZELLIJ_SLOT_TELEMETRY_SNAPSHOT_SCHEMA ? mergeTelemetrySnapshots(disk, snapshot) : snapshot;
|
|
342
332
|
const next = { ...merged, flush_count: Math.max(flushCount, Number(merged.flush_count || 0)) };
|
|
@@ -13,13 +13,6 @@ export function resolveZellijUiMode(args = [], env = process.env) {
|
|
|
13
13
|
return resolveExplicitZellijUiMode(args, env) || 'compact-slots';
|
|
14
14
|
}
|
|
15
15
|
export function resolveZellijWorkerPaneUiMode(args = [], env = process.env) {
|
|
16
|
-
// Default worker panes to the live slot renderer (compact-slots). In
|
|
17
|
-
// 'full-debug' the pane runs the worker process itself, but the worker is
|
|
18
|
-
// invoked with --json and the codex SDK streams events to JSONL files — so
|
|
19
|
-
// the pane stays blank until the worker exits. The slot renderer re-reads
|
|
20
|
-
// heartbeat/event/stdout artifacts every second and actually shows what each
|
|
21
|
-
// parallel worker is doing in real time. 'full-debug' remains available via
|
|
22
|
-
// --zellij-full-debug or SKS_ZELLIJ_UI_MODE=full-debug.
|
|
23
16
|
return resolveExplicitZellijUiMode(args, env) || 'compact-slots';
|
|
24
17
|
}
|
|
25
18
|
function resolveExplicitZellijUiMode(args = [], env = process.env) {
|
|
@@ -28,13 +28,6 @@ export function zellijUpgradeCommandHint(missing = false) {
|
|
|
28
28
|
return 'cargo install --locked zellij # or your distro package manager';
|
|
29
29
|
return 'See https://zellij.dev/documentation/installation';
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Resolve the latest STABLE zellij version. GitHub's /releases/latest endpoint
|
|
33
|
-
* already excludes prereleases and drafts. Results are cached on disk
|
|
34
|
-
* (default TTL 6h, override with SKS_ZELLIJ_UPDATE_TTL_MS) so command launches
|
|
35
|
-
* stay fast and offline-safe. SKS_ZELLIJ_LATEST_VERSION pins the value for
|
|
36
|
-
* tests and air-gapped environments.
|
|
37
|
-
*/
|
|
38
31
|
export async function fetchLatestZellijVersion(input = {}) {
|
|
39
32
|
const env = input.env || process.env;
|
|
40
33
|
const pinned = stripVersionPrefix(String(env.SKS_ZELLIJ_LATEST_VERSION || '').trim());
|
|
@@ -48,8 +41,6 @@ export async function fetchLatestZellijVersion(input = {}) {
|
|
|
48
41
|
}
|
|
49
42
|
try {
|
|
50
43
|
const tag = await githubLatestTag(input.timeoutMs || normalizePositiveInt(env.SKS_ZELLIJ_UPDATE_TIMEOUT_MS, 2500));
|
|
51
|
-
// GitHub release tags carry a leading "v" (v0.44.3); \b-based version
|
|
52
|
-
// parsing cannot start inside "v0", so strip the prefix first.
|
|
53
44
|
const version = parseZellijVersionText(stripVersionPrefix(tag));
|
|
54
45
|
if (!version)
|
|
55
46
|
throw new Error(`zellij_latest_tag_unparsed:${tag}`);
|
|
@@ -111,11 +102,6 @@ export async function checkZellijUpdateNotice(input = {}) {
|
|
|
111
102
|
}
|
|
112
103
|
return persistNotice(input.missionDir, notice);
|
|
113
104
|
}
|
|
114
|
-
/**
|
|
115
|
-
* Upgrade zellij to the latest stable release. Only Homebrew automation is
|
|
116
|
-
* attempted (macOS / Linuxbrew); everything else returns manual_required with
|
|
117
|
-
* the exact operator command, mirroring how the Codex CLI update flow behaves.
|
|
118
|
-
*/
|
|
119
105
|
export async function upgradeZellijToLatest(input = {}) {
|
|
120
106
|
const before = await checkZellijCapability({ require: false, writeReport: false, env: input.env || process.env }).catch(() => null);
|
|
121
107
|
const beforeVersion = before?.version || null;
|
|
@@ -133,11 +119,6 @@ export async function upgradeZellijToLatest(input = {}) {
|
|
|
133
119
|
};
|
|
134
120
|
}
|
|
135
121
|
const upgradeArgs = missing ? ['install', 'zellij'] : ['upgrade', 'zellij'];
|
|
136
|
-
// Package installs go through the mutation guard with an explicit
|
|
137
|
-
// zellij_install scope contract (same path ensureZellijCliTool uses), so the
|
|
138
|
-
// mutation ledger records the install and safety gates can audit it. The
|
|
139
|
-
// upgrade only runs after the operator confirmed the [Y/n] prompt or passed
|
|
140
|
-
// --yes / `sks zellij update --yes`.
|
|
141
122
|
const guardRoot = globalSksRoot();
|
|
142
123
|
const guardCommand = `brew ${upgradeArgs.join(' ')}`;
|
|
143
124
|
const contract = createRequestedScopeContract({
|
|
@@ -155,8 +136,6 @@ export async function upgradeZellijToLatest(input = {}) {
|
|
|
155
136
|
maxOutputBytes: 256 * 1024
|
|
156
137
|
}).catch((err) => ({ code: 1, stdout: '', stderr: String(err?.message || err) }));
|
|
157
138
|
if (run.code !== 0 && !missing && /No such keg|No available formula|not installed/i.test(`${run.stderr}\n${run.stdout}`)) {
|
|
158
|
-
// zellij exists on PATH but was not installed through Homebrew (e.g. cargo
|
|
159
|
-
// or a manual binary). Installing the brew formula gives a managed copy.
|
|
160
139
|
run = await guardedPackageInstall(guardCtx, 'zellij', {
|
|
161
140
|
confirmed: true,
|
|
162
141
|
command: 'brew',
|
|
@@ -195,14 +174,6 @@ export async function upgradeZellijToLatest(input = {}) {
|
|
|
195
174
|
error: null
|
|
196
175
|
};
|
|
197
176
|
}
|
|
198
|
-
/**
|
|
199
|
-
* Launch-time prompt, mirroring maybePromptCodexUpdateForLaunch: check the
|
|
200
|
-
* installed zellij version against the latest stable release and offer an
|
|
201
|
-
* upgrade before opening the live session. Never blocks the launch.
|
|
202
|
-
*
|
|
203
|
-
* Skips: --json, --skip-cli-tools, --skip-zellij-update, SKS_SKIP_ZELLIJ_UPDATE=1.
|
|
204
|
-
* Auto-approves: --yes / -y.
|
|
205
|
-
*/
|
|
206
177
|
export async function maybePromptZellijUpdateForLaunch(args = [], opts = {}) {
|
|
207
178
|
const env = opts.env || process.env;
|
|
208
179
|
const list = (args || []).map((arg) => String(arg));
|
|
@@ -15,11 +15,6 @@ export function buildWorkerPaneName(slotId, generationIndex) {
|
|
|
15
15
|
return `${slotId}/gen-${Math.max(1, Math.floor(Number(generationIndex) || 1))}`;
|
|
16
16
|
}
|
|
17
17
|
export function buildWorkerPaneTitle(slotId, generationIndex, context, serviceTier, backend, status, worktree, taskTitle) {
|
|
18
|
-
// When a task label is available, the pane title is JUST the label + status:
|
|
19
|
-
// users identify panes by what they are doing, not by slot ids. Slot/gen,
|
|
20
|
-
// backend, provider, and worktree details stay inside the pane body and the
|
|
21
|
-
// SLOTS anchor rows. The verbose format remains the fallback for callers
|
|
22
|
-
// that have no task context.
|
|
23
18
|
const task = shortWorkerTaskLabel(taskTitle);
|
|
24
19
|
if (task)
|
|
25
20
|
return `${task} · ${workerBackendTag(backend, context?.provider)} · ${status || 'launching'}`;
|
|
@@ -28,9 +23,6 @@ export function buildWorkerPaneTitle(slotId, generationIndex, context, serviceTi
|
|
|
28
23
|
const wt = worktree ? ` · WT:${worktree.id} · branch:${worktree.branch}` : '';
|
|
29
24
|
return `${base}${wt} · ${backend || 'codex-sdk'} · ${providerPaneLabel(normalized)} · ${status || 'launching'}`;
|
|
30
25
|
}
|
|
31
|
-
// Local-LLM workers must be visually distinguishable from GPT/codex workers:
|
|
32
|
-
// only trivial long-running edits belong on local models, while web research
|
|
33
|
-
// and code review must run on GPT. The tag makes a misrouted task obvious.
|
|
34
26
|
export function workerBackendTag(backend, provider) {
|
|
35
27
|
const text = `${String(backend || '')} ${String(provider || '')}`.toLowerCase();
|
|
36
28
|
if (/ollama|local/.test(text))
|
|
@@ -39,8 +31,6 @@ export function workerBackendTag(backend, provider) {
|
|
|
39
31
|
return 'fixture';
|
|
40
32
|
return 'GPT';
|
|
41
33
|
}
|
|
42
|
-
// Lead the pane title with a 1-3 word task label so users can tell WHAT each
|
|
43
|
-
// slot is doing at a glance instead of an anonymous "slot-002/gen-1".
|
|
44
34
|
export function shortWorkerTaskLabel(value, maxChars = 24) {
|
|
45
35
|
const text = String(value || '').replace(/\s+/g, ' ').trim();
|
|
46
36
|
if (!text)
|
|
@@ -233,15 +223,7 @@ export async function openWorkerPane(input) {
|
|
|
233
223
|
return record;
|
|
234
224
|
}
|
|
235
225
|
const paneName = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.statusLabel || 'running', input.worktree || null, input.taskTitle || null);
|
|
236
|
-
// CRITICAL: serialize anchor + worker pane creation per session. Workers
|
|
237
|
-
// launch concurrently, and without this lock every worker raced past the
|
|
238
|
-
// "does the SLOTS anchor exist yet?" check and created its OWN anchor with
|
|
239
|
-
// --direction right — splitting the screen into N side-by-side columns
|
|
240
|
-
// (observed in agent-zellij-pane-launch-ledger: terminal_1..terminal_5 all
|
|
241
|
-
// recorded as separate slot_column_anchor_pane_id values in one mission).
|
|
242
226
|
return withZellijPaneCreationLock(input, async () => {
|
|
243
|
-
// Re-read the right-column state now that we hold the lock: a previously
|
|
244
|
-
// serialized worker may have created the anchor and/or its own pane.
|
|
245
227
|
const freshState = rightColumn
|
|
246
228
|
? await readRightColumnState(root, input.missionId, input.projectRoot).catch(() => null)
|
|
247
229
|
: null;
|
|
@@ -259,18 +241,10 @@ export async function openWorkerPane(input) {
|
|
|
259
241
|
let columnCreationDirectionRequested = null;
|
|
260
242
|
let columnCreationDirectionApplied = null;
|
|
261
243
|
if (rightColumn && !freshFocusCandidate) {
|
|
262
|
-
// Single right-column invariant: if this zellij session was reused (stable
|
|
263
|
-
// per-cwd name) and already carries a SLOTS anchor from a prior mission, adopt
|
|
264
|
-
// it and stack workers underneath instead of splitting ANOTHER `--direction
|
|
265
|
-
// right` column — repeated right-splits are exactly what fragments the screen
|
|
266
|
-
// into side-by-side columns. A fresh column is only split when none exists yet.
|
|
267
244
|
const adoptedAnchorPaneId = createSession.ok
|
|
268
245
|
? await findExistingSlotsAnchorPaneId(input.sessionName, cwd).catch(() => null)
|
|
269
246
|
: null;
|
|
270
247
|
if (adoptedAnchorPaneId) {
|
|
271
|
-
// Adopted an existing column: no creation was requested, so leave the
|
|
272
|
-
// column-creation direction fields null (avoids a false
|
|
273
|
-
// `zellij_worker_slot_column_anchor_not_created` blocker).
|
|
274
248
|
slotColumnAnchorPaneId = adoptedAnchorPaneId;
|
|
275
249
|
await recordSlotColumnAnchorInRightColumn({
|
|
276
250
|
root,
|
|
@@ -314,11 +288,6 @@ export async function openWorkerPane(input) {
|
|
|
314
288
|
const focus = focusPaneId
|
|
315
289
|
? await focusZellijPaneById(input.sessionName, focusPaneId, cwd)
|
|
316
290
|
: null;
|
|
317
|
-
// Vertical stack policy: the first worker splits DOWN from the SLOTS anchor;
|
|
318
|
-
// every following worker joins a zellij stacked-pane group with the previous
|
|
319
|
-
// worker (`new-pane --stacked`, zellij >= 0.43) so the right column stays a
|
|
320
|
-
// clean vertical stack instead of fragmenting the screen. Opt out with
|
|
321
|
-
// SKS_ZELLIJ_WORKER_STACKED=0.
|
|
322
291
|
const stackIntent = process.env.SKS_ZELLIJ_WORKER_STACKED !== '0'
|
|
323
292
|
&& Boolean(lastVisibleWorkerPaneId)
|
|
324
293
|
&& focus?.ok === true;
|
|
@@ -651,9 +620,6 @@ async function reconcileZellijWorkerPaneId(sessionName, paneName, resultPath, cw
|
|
|
651
620
|
blockers: paneId == null ? ['zellij_worker_pane_id_not_reconciled'] : []
|
|
652
621
|
};
|
|
653
622
|
}
|
|
654
|
-
// Look up an already-open SLOTS anchor pane in a (possibly reused) session so a
|
|
655
|
-
// new mission can stack its workers under the existing right column instead of
|
|
656
|
-
// splitting another one. Returns the live pane id (terminal_<n>) or null.
|
|
657
623
|
async function findExistingSlotsAnchorPaneId(sessionName, cwd) {
|
|
658
624
|
const listed = await runZellij(['--session', sessionName, 'action', 'list-panes', '--json', '--all'], {
|
|
659
625
|
cwd,
|
|
@@ -775,11 +741,6 @@ async function focusZellijPaneById(sessionName, paneId, cwd) {
|
|
|
775
741
|
last = focus;
|
|
776
742
|
if (focus.ok)
|
|
777
743
|
return focus;
|
|
778
|
-
// zellij exits non-zero with "Pane Terminal(N) is already focused" when the
|
|
779
|
-
// target pane already holds focus (common: new-pane auto-focuses the pane
|
|
780
|
-
// it created, so the previous worker pane is usually still focused). That
|
|
781
|
-
// is a success for our purposes — without this, stacked placement would
|
|
782
|
-
// silently fall back to a plain down-split on every consecutive worker.
|
|
783
744
|
if (/already focused/i.test(`${focus.stdout_tail || ''} ${focus.stderr_tail || ''}`)) {
|
|
784
745
|
return { ...focus, ok: true, blockers: [], warnings: [...focus.warnings, 'zellij_pane_already_focused'] };
|
|
785
746
|
}
|
|
@@ -4,6 +4,7 @@ final class DiagnosticsViewController: NSViewController, ControlCenterPage {
|
|
|
4
4
|
private let processClient: ProcessClient
|
|
5
5
|
private let operations: OperationCoordinator
|
|
6
6
|
private let status = NativeView.detail("Diagnostics are idle.")
|
|
7
|
+
private let codexGuidance = NativeView.detail("Codex CLI: prefer the latest channel. Use Updates → Update Codex CLI when status reports an update.")
|
|
7
8
|
private var busy = false
|
|
8
9
|
|
|
9
10
|
init(processClient: ProcessClient, operations: OperationCoordinator) {
|
|
@@ -16,14 +17,15 @@ final class DiagnosticsViewController: NSViewController, ControlCenterPage {
|
|
|
16
17
|
override func loadView() {
|
|
17
18
|
let buttons = NSStackView(views: [
|
|
18
19
|
NativeView.button("Run Doctor", target: self, action: #selector(doctor)),
|
|
20
|
+
NativeView.button("Update Codex CLI", target: self, action: #selector(updateCodexCLI)),
|
|
19
21
|
NativeView.button("Open Last Log", target: self, action: #selector(openLog)),
|
|
20
22
|
NativeView.button("Restart Menu Bar", target: self, action: #selector(restart))
|
|
21
23
|
])
|
|
22
24
|
buttons.orientation = .horizontal; buttons.spacing = 8
|
|
23
25
|
view = NativeView.stack([
|
|
24
26
|
NativeView.title("Diagnostics"),
|
|
25
|
-
NativeView.detail("Diagnostic output is bounded, redacted, and written with owner-only permissions. Use this page when another Center action reports a blocker."),
|
|
26
|
-
status, buttons
|
|
27
|
+
NativeView.detail("Diagnostic output is bounded, redacted, and written with owner-only permissions. Use this page when another Center action reports a blocker. Feature routes that need newer Codex fail with an update CTA instead of locking all of SKS."),
|
|
28
|
+
status, codexGuidance, buttons
|
|
27
29
|
])
|
|
28
30
|
refreshOnAppear()
|
|
29
31
|
}
|
|
@@ -37,6 +39,22 @@ final class DiagnosticsViewController: NSViewController, ControlCenterPage {
|
|
|
37
39
|
} else {
|
|
38
40
|
status.stringValue = "Diagnostics are idle. No operation log exists yet."
|
|
39
41
|
}
|
|
42
|
+
refreshCodexGuidance()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private func refreshCodexGuidance() {
|
|
46
|
+
let update = readJson(path: FileManager.default.homeDirectoryForCurrentUser
|
|
47
|
+
.appendingPathComponent(".sneakoscope-global/cache/update-status.json").path)
|
|
48
|
+
let codex = update?["codex_cli"] as? [String: Any]
|
|
49
|
+
if codex?["update_available"] as? Bool == true {
|
|
50
|
+
let current = codex?["current"] as? String ?? "installed"
|
|
51
|
+
let latest = codex?["latest"] as? String ?? "preferred latest"
|
|
52
|
+
codexGuidance.stringValue = "Codex CLI update available: \(current) → \(latest). Prefer latest via Update Codex CLI, or run sks codex update."
|
|
53
|
+
} else if let current = codex?["current"] as? String {
|
|
54
|
+
codexGuidance.stringValue = "Codex CLI \(current) looks current in the shared snapshot. Prefer latest continuously; Naruto and other capability routes still probe features before use."
|
|
55
|
+
} else {
|
|
56
|
+
codexGuidance.stringValue = "Codex CLI: prefer the latest channel. Use Updates → Update Codex CLI when status reports an update, or run sks codex update."
|
|
57
|
+
}
|
|
40
58
|
}
|
|
41
59
|
|
|
42
60
|
@objc private func doctor() {
|
|
@@ -47,6 +65,7 @@ final class DiagnosticsViewController: NSViewController, ControlCenterPage {
|
|
|
47
65
|
self.busy = false
|
|
48
66
|
if result.code == 0 {
|
|
49
67
|
self.status.stringValue = "Doctor completed with no blocking issue."
|
|
68
|
+
self.refreshCodexGuidance()
|
|
50
69
|
return
|
|
51
70
|
}
|
|
52
71
|
if let json = self.json(result.output) {
|
|
@@ -54,14 +73,49 @@ final class DiagnosticsViewController: NSViewController, ControlCenterPage {
|
|
|
54
73
|
let blockers = (json["blockers"] as? [String])?.count ?? (json["issues"] as? [Any])?.count
|
|
55
74
|
if let blockers = blockers {
|
|
56
75
|
self.status.stringValue = "Doctor reported \(blockers) issue\(blockers == 1 ? "" : "s"). Open Last Log for redacted detail."
|
|
76
|
+
self.refreshCodexGuidance()
|
|
57
77
|
return
|
|
58
78
|
}
|
|
59
79
|
if ok == false {
|
|
60
80
|
self.status.stringValue = "Doctor reported a blocker. Open Last Log for redacted detail."
|
|
81
|
+
self.refreshCodexGuidance()
|
|
61
82
|
return
|
|
62
83
|
}
|
|
63
84
|
}
|
|
64
85
|
self.status.stringValue = "Doctor reported a blocker · \(NativeView.redactPreview(result.output))"
|
|
86
|
+
self.refreshCodexGuidance()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@objc private func updateCodexCLI() {
|
|
91
|
+
guard let operation = operations.begin(kind: "codex-cli-update", mutationGroup: "update", summary: "Update Codex CLI") else {
|
|
92
|
+
status.stringValue = "Another update or MCP mutation is already running."
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
busy = true
|
|
96
|
+
status.stringValue = "Updating Codex CLI…"
|
|
97
|
+
_ = operations.update(operation, state: .running, stage: "running", progress: nil, summary: status.stringValue)
|
|
98
|
+
processClient.run(["codex", "update", "--json"], timeout: nil) { [weak self] result in
|
|
99
|
+
guard let self = self else { return }
|
|
100
|
+
self.busy = false
|
|
101
|
+
let payload = self.json(result.output)
|
|
102
|
+
let ok = result.code == 0
|
|
103
|
+
&& !result.truncated
|
|
104
|
+
&& payload?["schema"] as? String == "sks.codex-cli-update-result.v1"
|
|
105
|
+
&& payload?["ok"] as? Bool == true
|
|
106
|
+
_ = self.operations.update(
|
|
107
|
+
operation,
|
|
108
|
+
state: ok ? .succeeded : .failed,
|
|
109
|
+
stage: "complete",
|
|
110
|
+
progress: 1,
|
|
111
|
+
summary: ok ? "Codex CLI update completed" : "Codex CLI update failed"
|
|
112
|
+
)
|
|
113
|
+
if ok {
|
|
114
|
+
self.status.stringValue = "Codex CLI update completed. Shared update status will refresh on the next Overview/Updates load."
|
|
115
|
+
} else {
|
|
116
|
+
self.status.stringValue = "Codex CLI update needs attention. Open Updates for structured guidance, or run sks codex update."
|
|
117
|
+
}
|
|
118
|
+
self.refreshCodexGuidance()
|
|
65
119
|
}
|
|
66
120
|
}
|
|
67
121
|
|
|
@@ -90,4 +144,9 @@ final class DiagnosticsViewController: NSViewController, ControlCenterPage {
|
|
|
90
144
|
guard let data = text.data(using: .utf8) else { return nil }
|
|
91
145
|
return try? JSONSerialization.jsonObject(with: data) as? [String: Any]
|
|
92
146
|
}
|
|
147
|
+
|
|
148
|
+
private func readJson(path: String) -> [String: Any]? {
|
|
149
|
+
guard let data = FileManager.default.contents(atPath: path) else { return nil }
|
|
150
|
+
return try? JSONSerialization.jsonObject(with: data) as? [String: Any]
|
|
151
|
+
}
|
|
93
152
|
}
|
|
@@ -140,7 +140,7 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
140
140
|
|
|
141
141
|
@objc private func refresh() {
|
|
142
142
|
let scope = selectedScope(); status.stringValue = "Loading \(scope) MCP configuration…"
|
|
143
|
-
processClient.run(["mcp", "config", "list", "--scope", scope] + scopeContext(scope, mutation: false) + ["--json"]) { [weak self] result in
|
|
143
|
+
processClient.run(["mcp", "config", "list", "--scope", scope] + scopeContext(scope, mutation: false) + ["--json"], timeout: NativeView.statusTimeout) { [weak self] result in
|
|
144
144
|
guard let self = self else { return }
|
|
145
145
|
guard let json = self.json(result.output), let servers = json["servers"] as? [[String: Any]] else {
|
|
146
146
|
self.rows = []; self.table.reloadData(); self.status.stringValue = "MCP inventory unavailable. No configuration was changed."
|
|
@@ -293,7 +293,7 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
293
293
|
private func mutate(_ args: [String], stdin: String? = nil) {
|
|
294
294
|
guard !mutating, let operation = operations.begin(kind: "mcp-config", mutationGroup: "mcp", summary: "MCP configuration change") else { status.stringValue = "An update or MCP mutation is already running."; return }
|
|
295
295
|
mutating = true; updateButtons(); _ = operations.update(operation, state: .running, stage: "apply", progress: nil, summary: "Applying scoped MCP change")
|
|
296
|
-
processClient.run(args, stdin: stdin) { [weak self] result in
|
|
296
|
+
processClient.run(args, stdin: stdin, timeout: NativeView.mutationTimeout) { [weak self] result in
|
|
297
297
|
guard let self = self else { return }
|
|
298
298
|
self.mutating = false
|
|
299
299
|
_ = self.operations.update(operation, state: result.code == 0 ? .succeeded : .failed, stage: "complete", progress: 1, summary: result.code == 0 ? "MCP change complete" : "MCP change failed")
|
|
@@ -310,7 +310,14 @@ final class MCPServersViewController: NSViewController, NSTableViewDataSource, N
|
|
|
310
310
|
private func writableScopeForBackup() -> String? { let scope = selectedScope(); return scope == "global" || scope == "project" ? scope : nil }
|
|
311
311
|
private func scopeContext(_ scope: String, mutation: Bool) -> [String] { scope == "project" ? projectContext(mutation: mutation) : [] }
|
|
312
312
|
private func projectContext(mutation: Bool) -> [String] { var args = ["--project-root", AppRuntime.projectRoot, "--trusted-project"]; if mutation { args.append("--confirm-project") }; return args }
|
|
313
|
-
private func json(_ text: String) -> [String: Any]? {
|
|
313
|
+
private func json(_ text: String) -> [String: Any]? {
|
|
314
|
+
guard let data = text.data(using: .utf8) else { return nil }
|
|
315
|
+
if let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any] { return object }
|
|
316
|
+
guard let start = text.range(of: "{", options: [.backwards])?.lowerBound else { return nil }
|
|
317
|
+
let slice = String(text[start...])
|
|
318
|
+
guard let sliced = slice.data(using: .utf8) else { return nil }
|
|
319
|
+
return try? JSONSerialization.jsonObject(with: sliced) as? [String: Any]
|
|
320
|
+
}
|
|
314
321
|
private func jsonText(_ payload: [String: Any]) -> String? { guard let data = try? JSONSerialization.data(withJSONObject: payload) else { return nil }; return String(data: data, encoding: .utf8).map { $0 + "\n" } }
|
|
315
322
|
private func actionButton(_ title: String, _ action: Selector) -> NSButton { NativeView.button(title, target: self, action: action) }
|
|
316
323
|
private func updateButtons() {
|
|
@@ -89,6 +89,9 @@ enum OverviewSummary {
|
|
|
89
89
|
let menu = update["menubar"] as? [String: Any]
|
|
90
90
|
lines.append("SKS install: \(versionSummary(sks))")
|
|
91
91
|
lines.append("Codex CLI: \(versionSummary(codex)) · Codex app: \(codexAppState)")
|
|
92
|
+
if let inducement = codexUpdateInducement(codex) {
|
|
93
|
+
lines.append(inducement)
|
|
94
|
+
}
|
|
92
95
|
|
|
93
96
|
var menuParts = ["running build \(menuBarBuild)"]
|
|
94
97
|
if let expected = menu?["expected_version"] as? String { menuParts.append("expected \(expected)") }
|
|
@@ -185,6 +188,13 @@ enum OverviewSummary {
|
|
|
185
188
|
return "\(current) · latest \(latest)"
|
|
186
189
|
}
|
|
187
190
|
|
|
191
|
+
private static func codexUpdateInducement(_ value: [String: Any]?) -> String? {
|
|
192
|
+
guard value?["update_available"] as? Bool == true else { return nil }
|
|
193
|
+
let current = nonEmpty(value?["current"] as? String) ?? "installed"
|
|
194
|
+
let latest = nonEmpty(value?["latest"] as? String) ?? "preferred latest"
|
|
195
|
+
return "Action: update Codex CLI (\(current) → \(latest)) from Updates, or choose Update Codex CLI Now in the menu bar."
|
|
196
|
+
}
|
|
197
|
+
|
|
188
198
|
private static func verificationState(_ value: Any?) -> String {
|
|
189
199
|
guard let value = value as? Bool else { return "unknown" }
|
|
190
200
|
return value ? "verified" : "needs attention"
|
|
@@ -227,6 +237,7 @@ final class OverviewViewController: NSViewController, ControlCenterPage {
|
|
|
227
237
|
private var generation = 0
|
|
228
238
|
private var doctorButton: NSButton!
|
|
229
239
|
private var refreshButton: NSButton!
|
|
240
|
+
private var updateCodexButton: NSButton!
|
|
230
241
|
|
|
231
242
|
init(processClient: ProcessClient, operations: OperationCoordinator) {
|
|
232
243
|
self.processClient = processClient
|
|
@@ -238,12 +249,14 @@ final class OverviewViewController: NSViewController, ControlCenterPage {
|
|
|
238
249
|
override func loadView() {
|
|
239
250
|
doctorButton = NativeView.button("Run Doctor", target: self, action: #selector(doctor))
|
|
240
251
|
refreshButton = NativeView.button("Refresh", target: self, action: #selector(refreshStatus))
|
|
241
|
-
|
|
252
|
+
updateCodexButton = NativeView.button("Update Codex CLI", target: self, action: #selector(updateCodexCLI))
|
|
253
|
+
updateCodexButton.setAccessibilityHelp("Update the operator Codex CLI to the preferred latest channel.")
|
|
254
|
+
let buttons = NSStackView(views: [doctorButton, refreshButton, updateCodexButton])
|
|
242
255
|
buttons.orientation = .horizontal
|
|
243
256
|
buttons.spacing = 8
|
|
244
257
|
view = NativeView.stack([
|
|
245
258
|
NativeView.title("Overview"),
|
|
246
|
-
NativeView.detail("Menu Bar build \(AppRuntime.packageVersion) · Local health for SKS, Codex CLI, MCP, Remote, and operations."),
|
|
259
|
+
NativeView.detail("Menu Bar build \(AppRuntime.packageVersion) · Local health for SKS, Codex CLI, MCP, Remote, and operations. Prefer the latest Codex CLI; SKS stays version-agnostic and capability-gates features."),
|
|
247
260
|
status,
|
|
248
261
|
notificationInbox,
|
|
249
262
|
buttons
|
|
@@ -265,6 +278,39 @@ final class OverviewViewController: NSViewController, ControlCenterPage {
|
|
|
265
278
|
loadStatus(forceUpdateRefresh: true)
|
|
266
279
|
}
|
|
267
280
|
|
|
281
|
+
@objc private func updateCodexCLI() {
|
|
282
|
+
guard let operation = operations.begin(kind: "codex-cli-update", mutationGroup: "update", summary: "Update Codex CLI") else {
|
|
283
|
+
status.stringValue = "Another update or MCP mutation is already running. Open Updates to review it."
|
|
284
|
+
return
|
|
285
|
+
}
|
|
286
|
+
updateCodexButton?.isEnabled = false
|
|
287
|
+
doctorButton?.isEnabled = false
|
|
288
|
+
refreshButton?.isEnabled = false
|
|
289
|
+
status.stringValue = "Updating Codex CLI to the preferred latest…"
|
|
290
|
+
_ = operations.update(operation, state: .running, stage: "running", progress: nil, summary: status.stringValue)
|
|
291
|
+
processClient.run(["codex", "update", "--json"], timeout: nil) { [weak self] result in
|
|
292
|
+
guard let self = self else { return }
|
|
293
|
+
let ok = result.code == 0
|
|
294
|
+
&& !result.truncated
|
|
295
|
+
&& (self.json(result.output)?["ok"] as? Bool == true)
|
|
296
|
+
&& (self.json(result.output)?["schema"] as? String == "sks.codex-cli-update-result.v1")
|
|
297
|
+
_ = self.operations.update(
|
|
298
|
+
operation,
|
|
299
|
+
state: ok ? .succeeded : .failed,
|
|
300
|
+
stage: "complete",
|
|
301
|
+
progress: 1,
|
|
302
|
+
summary: ok ? "Codex CLI update completed" : "Codex CLI update failed"
|
|
303
|
+
)
|
|
304
|
+
self.updateCodexButton?.isEnabled = true
|
|
305
|
+
self.doctorButton?.isEnabled = true
|
|
306
|
+
self.refreshButton?.isEnabled = true
|
|
307
|
+
self.status.stringValue = ok
|
|
308
|
+
? "Codex CLI update completed. Refreshing shared update status…"
|
|
309
|
+
: "Codex CLI update needs attention. Open Updates or Diagnostics for structured guidance."
|
|
310
|
+
self.loadStatus(forceUpdateRefresh: true)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
268
314
|
private func loadStatus(forceUpdateRefresh: Bool) {
|
|
269
315
|
generation += 1
|
|
270
316
|
let requestGeneration = generation
|
|
@@ -353,6 +399,12 @@ final class OverviewViewController: NSViewController, ControlCenterPage {
|
|
|
353
399
|
|
|
354
400
|
private func json(_ text: String) -> [String: Any]? {
|
|
355
401
|
guard let data = text.data(using: .utf8) else { return nil }
|
|
356
|
-
|
|
402
|
+
if let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any] { return object }
|
|
403
|
+
// Child processes may print banner lines before JSON (for example a
|
|
404
|
+
// migration gate message). Prefer the last top-level object payload.
|
|
405
|
+
guard let start = text.range(of: "{", options: [.backwards])?.lowerBound else { return nil }
|
|
406
|
+
let slice = String(text[start...])
|
|
407
|
+
guard let sliced = slice.data(using: .utf8) else { return nil }
|
|
408
|
+
return try? JSONSerialization.jsonObject(with: sliced) as? [String: Any]
|
|
357
409
|
}
|
|
358
410
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import Cocoa
|
|
2
|
+
|
|
3
|
+
extension ProvidersViewController {
|
|
4
|
+
func refreshOpenRouterStatus() {
|
|
5
|
+
processClient.run(["codex-app", "openrouter-status", "--json"], timeout: NativeView.statusTimeout) { [weak self] result in
|
|
6
|
+
guard let self = self else { return }
|
|
7
|
+
guard result.code == 0, let json = self.json(result.output) else {
|
|
8
|
+
if !self.busy { self.openRouterStatus.stringValue = "OpenRouter: status unavailable." }
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
let current = self.openRouterModelField.stringValue.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
12
|
+
if let model = json["model"] as? String, !model.isEmpty, current.isEmpty || current == "z-ai/glm-5.2" {
|
|
13
|
+
self.openRouterModelField.stringValue = model
|
|
14
|
+
}
|
|
15
|
+
if !self.busy { self.openRouterStatus.stringValue = self.describeOpenRouterStatus(json) }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
func describeOpenRouterStatus(_ json: [String: Any]) -> String {
|
|
20
|
+
let keyPresent = json["key_present"] as? Bool == true
|
|
21
|
+
let providerPresent = json["provider_present"] as? Bool == true
|
|
22
|
+
let selected = json["selected"] as? Bool == true
|
|
23
|
+
let model = json["model"] as? String ?? "unset"
|
|
24
|
+
if !keyPresent { return "OpenRouter: key missing. Save OpenRouter key, then Use OpenRouter." }
|
|
25
|
+
if !providerPresent { return "OpenRouter: provider missing. Save OpenRouter key to install the provider block." }
|
|
26
|
+
if selected { return "OpenRouter: active · model \(model). Restore Chat / Pro or Use codex-lb to switch away." }
|
|
27
|
+
return "OpenRouter: key stored · model \(model) · not selected. Click Use OpenRouter."
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@objc func saveOpenRouterKey() {
|
|
31
|
+
guard let window = view.window else { return }
|
|
32
|
+
promptForSecretKey(
|
|
33
|
+
window: window,
|
|
34
|
+
sheetTitle: "OpenRouter API Key",
|
|
35
|
+
sheetMessage: "Paste your OpenRouter API key. It is sent through stdin and never logged. Saving does not switch the active provider.",
|
|
36
|
+
placeholder: "sk-or-…",
|
|
37
|
+
args: ["codex-app", "set-openrouter-key", "--api-key-stdin", "--json"],
|
|
38
|
+
kind: "openrouter-set-key",
|
|
39
|
+
title: "Save OpenRouter key",
|
|
40
|
+
statusLabel: openRouterStatus,
|
|
41
|
+
successSummary: "OpenRouter key saved",
|
|
42
|
+
failSummary: "OpenRouter key save failed"
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@objc func useOpenRouter() {
|
|
47
|
+
let model = openRouterModelField.stringValue.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
48
|
+
guard !model.isEmpty else {
|
|
49
|
+
openRouterStatus.stringValue = "Enter an OpenRouter model id, then click Use OpenRouter."
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
guard !busy else {
|
|
53
|
+
openRouterStatus.stringValue = "Another provider action is already running."
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
guard let snapshot = operations.begin(kind: "openrouter-use", mutationGroup: "codex-config", summary: "Use OpenRouter") else {
|
|
57
|
+
openRouterStatus.stringValue = "Another guarded mutation is already running. Wait or open Diagnostics."
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
setBusy(true)
|
|
61
|
+
openRouterStatus.stringValue = "Activating OpenRouter (\(model)) and restarting Codex App…"
|
|
62
|
+
_ = operations.update(snapshot, state: .running, stage: "activating", progress: nil, summary: "Use OpenRouter")
|
|
63
|
+
processClient.run(["codex-app", "use-openrouter", "--model", model, "--restart-app", "--json"], timeout: NativeView.mutationTimeout) { [weak self] result in
|
|
64
|
+
guard let self = self else { return }
|
|
65
|
+
self.setBusy(false)
|
|
66
|
+
let json = self.json(result.output)
|
|
67
|
+
let ok = result.code == 0 && json?["ok"] as? Bool == true
|
|
68
|
+
let activeModel = (json?["model"] as? String) ?? model
|
|
69
|
+
_ = self.operations.update(snapshot, state: ok ? .succeeded : .failed, stage: "complete", progress: 1, summary: ok ? "OpenRouter active after restart" : "OpenRouter activation needs action")
|
|
70
|
+
self.openRouterStatus.stringValue = ok
|
|
71
|
+
? "OpenRouter: active · model \(activeModel)."
|
|
72
|
+
: "Use OpenRouter failed · \(NativeView.redactPreview(result.output))"
|
|
73
|
+
self.refresh()
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|