sneakoscope 8.0.2 → 8.0.4
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 +150 -37
- package/config/skills-hash-ledger.v1.json +1 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +55 -27
- package/dist/bin/install.js +6 -32
- package/dist/bin/sks-dispatch.js +1 -1
- package/dist/cli/args.js +0 -2
- package/dist/cli/cli-theme.js +18 -9
- package/dist/cli/command-manifest-lite.js +6 -6
- package/dist/cli/command-registry.js +6 -6
- package/dist/cli/feature-commands.js +9 -7
- package/dist/cli/install-helpers-codex-lb-chain.js +198 -7
- package/dist/cli/install-helpers-codex-lb-config.js +78 -10
- package/dist/cli/install-helpers-install-support.js +9 -6
- package/dist/cli/install-helpers.js +101 -49
- package/dist/cli/install-tool-helpers.js +2 -82
- package/dist/cli/output.js +6 -1
- package/dist/cli/router.js +101 -2
- package/dist/commands/codex-lb.js +119 -19
- package/dist/commands/doctor-profile.js +1 -1
- package/dist/commands/doctor.js +727 -144
- package/dist/commands/mad-sks.js +1 -5
- package/dist/config/skills-manifest.json +4 -2
- package/dist/core/agents/agent-codex-cockpit.js +0 -3
- package/dist/core/agents/agent-effort-policy.js +5 -5
- package/dist/core/agents/agent-janitor.js +0 -20
- package/dist/core/agents/agent-orchestrator.js +9 -56
- package/dist/core/agents/agent-output-validator.js +2 -3
- package/dist/core/agents/agent-patch-schema.js +2 -2
- package/dist/core/agents/agent-proof-evidence.js +0 -65
- package/dist/core/agents/agent-recursion-guard.js +1 -1
- package/dist/core/agents/agent-runner-codex-exec.js +5 -3
- package/dist/core/agents/agent-scheduler.js +327 -85
- package/dist/core/agents/agent-schema.js +1 -1
- package/dist/core/agents/agent-trust-report.js +0 -36
- package/dist/core/agents/agent-worker-pipeline.js +0 -1
- package/dist/core/agents/fast-mode-policy.js +1 -3
- package/dist/core/agents/native-cli-worker-runtime-proof.js +1 -1
- package/dist/core/agents/native-cli-worker-runtime.js +69 -647
- package/dist/core/agents/native-cli-worker.js +6 -7
- package/dist/core/agents/native-worker-backend-router.js +2 -32
- package/dist/core/agents/no-subagent-scaling-policy.js +1 -1
- package/dist/core/agents/parallel-runtime-proof.js +1 -6
- package/dist/core/agents/runtime-proof-summary.js +1 -35
- package/dist/core/architecture-hardening/contracts/contracts.js +193 -0
- package/dist/core/architecture-hardening/migration/migration.js +111 -0
- package/dist/core/architecture-hardening/state/state-service.js +155 -0
- package/dist/core/artifact-schemas.js +0 -3
- package/dist/core/codex/codex-config-guard.js +238 -52
- package/dist/core/codex-adapter.js +5 -3
- package/dist/core/codex-app/auxiliary-oauth-policy.js +36 -0
- package/dist/core/codex-app/catalog-compat/catalog-service.js +104 -0
- package/dist/core/codex-app/child-policy/child-policy.js +35 -0
- package/dist/core/codex-app/codex-app-handoff.js +0 -1
- package/dist/core/codex-app/codex-hook-lifecycle.js +1 -1
- package/dist/core/codex-app/codex-init-deep.js +1 -1
- package/dist/core/codex-app/menubar/app-bundle.js +2 -0
- package/dist/core/codex-app/menubar/constants.js +14 -1
- package/dist/core/codex-app/menubar/global-install.js +288 -0
- package/dist/core/codex-app/menubar/installer.js +79 -14
- package/dist/core/codex-app/menubar/launch-agent.js +267 -45
- package/dist/core/codex-app/menubar/paths.js +3 -0
- package/dist/core/codex-app/menubar/rollback.js +55 -7
- package/dist/core/codex-app/menubar/status.js +75 -4
- package/dist/core/codex-app/provider-child-policy.js +64 -0
- package/dist/core/codex-app/provider-mode.js +91 -0
- package/dist/core/codex-app/provider-operation-stages.js +20 -0
- package/dist/core/codex-app/provider-session-policy.js +85 -0
- package/dist/core/codex-app/session-policy/session-pinning.js +68 -0
- package/dist/core/codex-app.js +3 -2
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +3 -1
- package/dist/core/codex-control/codex-0139-web-search-probe.js +3 -1
- package/dist/core/codex-control/codex-app-server-runtime-env.js +13 -4
- package/dist/core/codex-control/codex-app-server-v2-client.js +3 -3
- package/dist/core/codex-control/codex-control-proof.js +0 -1
- package/dist/core/codex-control/codex-task-runner.js +1 -4
- package/dist/core/codex-exec-output-schema.js +4 -1
- package/dist/core/codex-lb/codex-lb-env.js +63 -72
- package/dist/core/codex-lb/codex-lb-setup.js +15 -2
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +6 -0
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +48 -6
- package/dist/core/codex-lb/desktop-bridge/security.js +134 -0
- package/dist/core/codex-lb/desktop-bridge/server.js +9 -3
- package/dist/core/codex-lb/desktop-bridge/state.js +26 -6
- package/dist/core/codex-lb/desktop-bridge/types.js +1 -0
- package/dist/core/codex-lb/desktop-center-credentials.js +517 -58
- package/dist/core/codex-lb/desktop-controller.js +177 -56
- package/dist/core/codex-lb/desktop-service.js +179 -40
- package/dist/core/codex-lb/legacy-migration.js +1 -3
- package/dist/core/codex-lb/native-openai-transport/transport.js +68 -0
- package/dist/core/codex-lb/probes/cli-image-tool-probe.js +1 -1
- package/dist/core/codex-lb/provider-routing/provider-router.js +58 -0
- package/dist/core/codex-lb/routing-truth.js +327 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +4 -0
- package/dist/core/codex-native/codex-native-pattern-analysis.js +1 -2
- package/dist/core/codex-native/core-skill-manifest.js +1 -1
- package/dist/core/codex-plugins/codex-plugin-json.js +26 -6
- package/dist/core/codex-plugins/codex-plugin-repair.js +32 -6
- package/dist/core/commands/basic-cli.js +9 -7
- package/dist/core/commands/computer-use-command.js +1 -1
- package/dist/core/commands/image-ux-review-command.js +16 -9
- package/dist/core/commands/install-package-command.js +105 -0
- package/dist/core/commands/intent-normalization/normalizer.js +96 -0
- package/dist/core/commands/mad-sks-command.js +23 -274
- package/dist/core/commands/mad-sks-headless.js +11 -30
- package/dist/core/commands/naruto-command.js +0 -25
- package/dist/core/commands/qa-loop-command.js +104 -22
- package/dist/core/commands/remote-command.js +2 -2
- package/dist/core/commands/research-command.js +10 -5
- package/dist/core/commands/telegram-command.js +407 -0
- package/dist/core/config-adopt/config-adopt-command.js +35 -0
- package/dist/core/config-adopt/config-adopt.js +346 -0
- package/dist/core/config-adopt/index.js +3 -0
- package/dist/core/doctor/command-alias-cleanup.js +4 -1
- package/dist/core/doctor/current-project-guidance-nested.js +37 -6
- package/dist/core/doctor/current-project-guidance.js +15 -9
- package/dist/core/doctor/doctor-dirty-planner.js +1 -4
- package/dist/core/doctor/doctor-readiness-matrix.js +15 -18
- package/dist/core/doctor/retired-managed-residue-private.js +4 -3
- package/dist/core/doctor/retired-managed-residue-runtime.js +2 -2
- package/dist/core/doctor/skill-legacy-surface.js +11 -10
- package/dist/core/doctor/sks-menubar-doctor.js +4 -0
- package/dist/core/evaluation.js +0 -19
- package/dist/core/evidence/v2/evidence-key.js +105 -0
- package/dist/core/feature-fixtures.js +12 -7
- package/dist/core/feature-registry.js +52 -21
- package/dist/core/hooks-runtime/hook-context.js +9 -0
- package/dist/core/hooks-runtime/managed-skill-admission.js +54 -4
- package/dist/core/hooks-runtime/official-subagent-lifecycle.js +69 -52
- package/dist/core/hooks-runtime/stop-finalization.js +226 -0
- package/dist/core/hooks-runtime/stop-repeat-guard.js +21 -2
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +2 -2
- package/dist/core/hooks-runtime/subagent-skill-availability-evidence.js +3 -3
- package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +43 -5
- package/dist/core/hooks-runtime/subagent-skill-availability.js +64 -30
- package/dist/core/hooks-runtime/subagent-stop-hook.js +15 -2
- package/dist/core/hooks-runtime.js +179 -212
- package/dist/core/image/reference-evidence/reference-registry.js +145 -0
- package/dist/core/image-ux-review/imagegen-adapter.js +21 -9
- package/dist/core/image-ux-review/reference-policy/reference-policy.js +9 -0
- package/dist/core/imagegen/codex-lb-imagegen-target.js +8 -0
- package/dist/core/imagegen/imagegen-capability.js +59 -2
- package/dist/core/imagegen/require-imagegen.js +2 -2
- package/dist/core/init/skills.js +17 -3
- package/dist/core/init.js +3 -3
- package/dist/core/install/installed-package-smoke.js +23 -5
- package/dist/core/json/canonical.js +9 -0
- package/dist/core/locks/file-lock.js +0 -1
- package/dist/core/loops/loop-continuation-enforcer.js +65 -7
- package/dist/core/loops/loop-decomposer.js +0 -1
- package/dist/core/loops/loop-gate-runner.js +65 -4
- package/dist/core/loops/loop-gate-selector.js +0 -2
- package/dist/core/loops/loop-proof-validation.js +38 -0
- package/dist/core/loops/loop-risk-classifier.js +1 -1
- package/dist/core/loops/loop-runtime.js +14 -2
- package/dist/core/loops/loop-scheduler.js +7 -2
- package/dist/core/loops/loop-worker-runtime.js +0 -15
- package/dist/core/loops/loop-worktree-runtime.js +52 -4
- package/dist/core/managed-assets/managed-assets-manifest.js +14 -14
- package/dist/core/naruto/hardware-capacity-probe.js +9 -6
- package/dist/core/naruto/naruto-active-pool.js +2 -14
- package/dist/core/naruto/naruto-concurrency-governor.js +71 -31
- package/dist/core/naruto/naruto-loop-worker-router.js +0 -2
- package/dist/core/naruto/naruto-verification-dag.js +0 -1
- package/dist/core/naruto/naruto-write-e2e.js +1 -2
- package/dist/core/naruto/resource-pressure-monitor.js +0 -4
- package/dist/core/observability/architecture-hardening/safe-projection.js +65 -0
- package/dist/core/perf/import-graph-budget.js +0 -1
- package/dist/core/perf/release-latency-slo.js +3 -2
- package/dist/core/preflight/parallel-preflight-engine.js +2 -15
- package/dist/core/product-design-app-server.js +13 -1
- package/dist/core/proof/fake-real-proof-policy.js +2 -17
- package/dist/core/proof/route-proof-gate.js +2 -10
- package/dist/core/proof/route-proof-policy.js +1 -1
- package/dist/core/proof/runtime-evidence-policy.js +185 -0
- package/dist/core/proof/runtime-truth-matrix.js +64 -39
- package/dist/core/proof/validation.js +27 -11
- package/dist/core/provider/provider-context.js +18 -2
- package/dist/core/providers/openrouter/openrouter-account.js +3 -2
- package/dist/core/python-tools/python-tool-runner.js +1 -1
- package/dist/core/qa-loop/qa-execution-control.js +57 -0
- package/dist/core/questions.js +1 -1
- package/dist/core/release/extreme-parallel-scheduler.js +0 -3
- package/dist/core/release/gate-manifest.js +3 -7
- package/dist/core/release/gate-pack-manifest.js +3 -7
- package/dist/core/release/package-size-budget.js +2 -2
- package/dist/core/release/physical-release-gates.js +189 -0
- package/dist/core/release/publish-preflight.js +113 -0
- package/dist/core/release/release-gate-affected-selector.js +0 -2
- package/dist/core/release/release-gate-batch-runner.js +1 -1
- package/dist/core/release/release-gate-node.js +0 -1
- package/dist/core/release/release-gate-resource-governor.js +0 -1
- package/dist/core/release/release-pack-receipt.js +5 -8
- package/dist/core/release/release-real-contract.js +0 -6
- package/dist/core/release/resource-class-budget.js +0 -1
- package/dist/core/release/stage-publish.js +178 -36
- package/dist/core/research/research-adversarial-review.js +103 -9
- package/dist/core/research.js +1 -1
- package/dist/core/retention.js +0 -1
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/diagnostic-allowlist.js +0 -1
- package/dist/core/routes/dollar-manifest-lite.js +1 -1
- package/dist/core/routes.js +46 -15
- package/dist/core/runtime/execution-control.js +226 -0
- package/dist/core/runtime/progress-recovery/progress-recovery.js +89 -0
- package/dist/core/runtime/task-profile.js +10 -4
- package/dist/core/runtime/verification-budget.js +10 -1
- package/dist/core/safety/intent-contract/intent-contract.js +94 -0
- package/dist/core/safety/mutation-guard.js +0 -2
- package/dist/core/safety/mutation-ledger.js +0 -2
- package/dist/core/safety/requested-scope-contract.js +0 -0
- package/dist/core/search-visibility/discovery.js +1 -1
- package/dist/core/search-visibility/index.js +12 -0
- package/dist/core/search-visibility/verifier.js +112 -3
- package/dist/core/security/private-credential-file.js +209 -0
- package/dist/core/session/project-namespace.js +0 -5
- package/dist/core/skills/skill-agent-metadata.js +1 -3
- package/dist/core/strategy/adhd-orchestrating-gate.js +0 -1
- package/dist/core/subagents/agent-catalog.js +19 -34
- package/dist/core/subagents/model-policy.js +65 -24
- package/dist/core/subagents/naruto-help-contract.js +8 -8
- package/dist/core/subagents/naruto-host-credentials.js +13 -0
- package/dist/core/subagents/official-subagent-config.js +16 -6
- package/dist/core/subagents/official-subagent-preparation.js +35 -16
- package/dist/core/subagents/official-subagent-prompt.js +7 -7
- package/dist/core/subagents/official-subagent-runner.js +27 -4
- package/dist/core/subagents/role-model-preferences.js +1 -1
- package/dist/core/subagents/thread-budget.js +19 -12
- package/dist/core/subagents/wave-lifecycle.js +18 -6
- package/dist/core/telegram/access.js +58 -0
- package/dist/core/telegram/client.js +157 -0
- package/dist/core/telegram/confirmation.js +37 -0
- package/dist/core/telegram/doctor.js +154 -0
- package/dist/core/telegram/index.js +9 -0
- package/dist/core/telegram/keychain.js +317 -0
- package/dist/core/telegram/liveness.js +118 -0
- package/dist/core/telegram/poller.js +90 -0
- package/dist/core/telegram/redaction.js +15 -0
- package/dist/core/telegram/state-lock.js +416 -0
- package/dist/core/telegram/types.js +1 -0
- package/dist/core/text/strings.js +3 -0
- package/dist/core/triwiki/context-graph/store/evidence-write-lock.js +29 -0
- package/dist/core/triwiki/context-graph/store/fragment-cache.js +24 -0
- package/dist/core/triwiki/context-graph/store/snapshot-store.js +69 -21
- package/dist/core/triwiki/triwiki-gate-impact-map.js +2 -2
- package/dist/core/triwiki/triwiki-module-card.js +1 -2
- package/dist/core/update/installed-cli-resolution.js +170 -0
- package/dist/core/update/update-diagnostics.js +52 -0
- package/dist/core/update/update-migration-state.js +30 -12
- package/dist/core/update/update-operation.js +2 -1
- package/dist/core/update/update-stage-diagnostics.js +38 -0
- package/dist/core/update/update-status.js +2 -9
- package/dist/core/update-check.js +279 -91
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/AppDelegate.swift +19 -1
- package/dist/native/sks-menubar/Sources/AppIdentity.swift +7 -0
- package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +6 -2
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +159 -92
- package/dist/native/sks-menubar/Sources/OperationModels.swift +389 -0
- package/dist/native/sks-menubar/Sources/OverviewViewController.swift +57 -0
- package/dist/native/sks-menubar/Sources/ProcessClient.swift +3 -1
- package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +115 -0
- package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +17 -0
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +3 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +58 -17
- package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +302 -0
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +5 -0
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +190 -0
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +158 -126
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +462 -26
- package/dist/native/sks-menubar/Sources/SKSKeychainStore.swift +344 -0
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +27 -0
- package/dist/native/sks-menubar/Sources/SingletonInstanceGuard.swift +328 -0
- package/dist/native/sks-menubar/Sources/StatusItemController.swift +10 -2
- package/dist/native/sks-menubar/Sources/TelegramPrivateFileStore.swift +498 -0
- package/dist/native/sks-menubar/Sources/TelegramPrivateFileSupport.swift +236 -0
- package/dist/native/sks-menubar/Sources/TelegramProcessGateway.swift +454 -0
- package/dist/native/sks-menubar/Sources/TelegramRuntimeSupport.swift +56 -0
- package/dist/native/sks-menubar/Sources/TelegramStateLock.swift +448 -0
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +187 -0
- package/dist/native/sks-menubar/Sources/TelegramTransport.swift +499 -0
- package/dist/native/sks-menubar/Sources/main.swift +15 -1
- package/dist/scripts/all-feature-deep-completion-check.js +5 -1
- package/dist/scripts/check-publish-tag.js +56 -0
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +10 -3
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +12 -3
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +4 -2
- package/dist/scripts/codex-native-agent-role-content-check.js +3 -3
- package/dist/scripts/codex-native-gate-lib.js +14 -7
- package/dist/scripts/current-command-surface-check.js +7 -7
- package/dist/scripts/current-surface-update-e2e-check.js +4 -3
- package/dist/scripts/current-upgrade-matrix-check.js +5 -24
- package/dist/scripts/docs-truthfulness-check.js +17 -13
- package/dist/scripts/gate-lib.js +0 -2
- package/dist/scripts/gate-policy-audit-check.js +3 -2
- package/dist/scripts/harness-benchmark-check.js +1 -1
- package/dist/scripts/init-deep-backup-retention-check.js +1 -1
- package/dist/scripts/lib/codex-sdk-gate-lib.js +1 -2
- package/dist/scripts/loop-directive-check-lib.js +28 -38
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +14 -180
- package/dist/scripts/mad-sks-launch-sql-plane-boundary-check.js +2 -11
- package/dist/scripts/official-subagent-workflow-check.js +1 -1
- package/dist/scripts/packlist-performance-check.js +1 -2
- package/dist/scripts/prepublish-release-check-or-fast.js +32 -0
- package/dist/scripts/publish-preflight.js +12 -0
- package/dist/scripts/release-affected-selector-check.js +2 -2
- package/dist/scripts/release-gate-batch-runner-check.js +2 -2
- package/dist/scripts/release-metadata-check.js +8 -12
- package/dist/scripts/release-real-check.js +2 -54
- package/dist/scripts/runtime-domain-gate-lib.js +2 -96
- package/dist/scripts/runtime-proof-summary-check.js +2 -6
- package/dist/scripts/search-visibility-gate-lib.js +0 -1
- package/dist/scripts/sks-cli-gate-lib.js +1 -1
- package/dist/scripts/typed-routing-gate-lib.js +7 -59
- package/docs/demo.tape +1 -1
- package/infra-harness-gates.json +1 -1456
- package/package.json +10 -7
- package/release-gates.v2.json +0 -1
- package/schemas/agents/parallel-runtime-proof.schema.json +0 -2
- package/schemas/codex/agent-result.schema.json +0 -6
- package/schemas/naruto/naruto-concurrency-governor.schema.json +1 -3
- package/schemas/release/release-gate-node.schema.json +1 -1
- package/dist/commands/zellij-lane.js +0 -22
- package/dist/commands/zellij-monitor-pane.js +0 -26
- package/dist/commands/zellij-slot-column-anchor.js +0 -22
- package/dist/commands/zellij-slot-pane.js +0 -80
- package/dist/commands/zellij-viewport-pane.js +0 -57
- package/dist/commands/zellij.js +0 -422
- package/dist/core/agents/agent-runner-zellij.js +0 -164
- package/dist/core/agents/agent-slot-pane-binding-proof.js +0 -96
- package/dist/core/agents/parallel-write-fixture.js +0 -305
- package/dist/core/agents/worker-pane-communication-contract.js +0 -100
- package/dist/core/agents/zellij-lane-supervisor.js +0 -428
- package/dist/core/agents/zellij-right-lane-cockpit.js +0 -66
- package/dist/core/doctor/doctor-zellij-repair.js +0 -40
- package/dist/core/ops/upgrade-migration-fixtures.js +0 -119
- package/dist/core/proof/route-finalizer-fixtures.js +0 -21
- package/dist/core/zellij/homebrew-policy.js +0 -43
- package/dist/core/zellij/zellij-capability.js +0 -126
- package/dist/core/zellij/zellij-clipboard-config.js +0 -52
- package/dist/core/zellij/zellij-command.js +0 -149
- package/dist/core/zellij/zellij-fake-adapter.js +0 -186
- package/dist/core/zellij/zellij-lane-renderer.js +0 -706
- package/dist/core/zellij/zellij-lane-runtime.js +0 -189
- package/dist/core/zellij/zellij-launcher.js +0 -268
- package/dist/core/zellij/zellij-layout-builder.js +0 -191
- package/dist/core/zellij/zellij-monitor-renderer.js +0 -52
- package/dist/core/zellij/zellij-official-subagent-activity.js +0 -526
- package/dist/core/zellij/zellij-official-subagent-telemetry.js +0 -258
- package/dist/core/zellij/zellij-pane-proof.js +0 -226
- package/dist/core/zellij/zellij-right-column-manager.js +0 -308
- package/dist/core/zellij/zellij-screen-proof.js +0 -120
- package/dist/core/zellij/zellij-self-heal-types.js +0 -44
- package/dist/core/zellij/zellij-self-heal.js +0 -408
- package/dist/core/zellij/zellij-slot-column-anchor.js +0 -304
- package/dist/core/zellij/zellij-slot-pane-renderer.js +0 -521
- package/dist/core/zellij/zellij-slot-telemetry.js +0 -384
- package/dist/core/zellij/zellij-theme.js +0 -66
- package/dist/core/zellij/zellij-ui-mode.js +0 -34
- package/dist/core/zellij/zellij-update.js +0 -348
- package/dist/core/zellij/zellij-viewport-binder.js +0 -61
- package/dist/core/zellij/zellij-worker-pane-manager.js +0 -881
- package/dist/core/zellij/zellij-worker-pane-summary.js +0 -64
- package/dist/native/sks-menubar/Tests/AppRuntimeTestSupport.swift +0 -26
- package/dist/native/sks-menubar/Tests/OperationCoordinatorTests.swift +0 -174
- package/dist/native/sks-menubar/Tests/ProcessClientTests.swift +0 -20
- package/dist/native/sks-menubar/Tests/ProvidersViewControllerTests.swift +0 -142
- package/dist/scripts/zellij-pane-proof-check.js +0 -88
- package/dist/scripts/zellij-real-session-cleanup-check.js +0 -139
- package/dist/scripts/zellij-real-session-launch-check.js +0 -126
- package/dist/scripts/zellij-screen-proof-check.js +0 -43
- package/schemas/zellij/zellij-right-column-state.schema.json +0 -40
- package/schemas/zellij/zellij-slot-telemetry.schema.json +0 -89
- package/schemas/zellij/zellij-worker-pane.schema.json +0 -53
- package/scripts/build-clean-atomic.mjs +0 -323
package/dist/commands/doctor.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { projectRoot, exists, formatBytes, nowIso, readText, writeJsonAtomic } from '../core/fsx.js';
|
|
4
5
|
import { flag } from '../cli/args.js';
|
|
5
6
|
import { printJson } from '../cli/output.js';
|
|
6
7
|
import { ui as cliUi } from '../cli/cli-theme.js';
|
|
@@ -10,10 +11,18 @@ import { codexAppIntegrationStatus } from '../core/codex-app.js';
|
|
|
10
11
|
import { codexLbMetrics, readCodexLbCircuit } from '../core/codex-lb-circuit.js';
|
|
11
12
|
import { codexLbStatus } from '../cli/install-helpers.js';
|
|
12
13
|
import { codexLbToolOutputRecoveryOverrideAcknowledged } from '../core/codex-lb/codex-lb-tool-output-recovery.js';
|
|
14
|
+
import { codexLbEnvPath, loadCodexLbEnv } from '../core/codex-lb/codex-lb-env.js';
|
|
15
|
+
import { codexLbLegacyKeychainMigrationStampPath, inspectDesktopCenterLaunchCredentials, inspectCodexLbLegacyKeychainMigration, repairCodexLbLegacyKeychainMigration, syncDesktopCenterLaunchCredentials } from '../core/codex-lb/desktop-center-credentials.js';
|
|
16
|
+
import { codexLbRoutingTruthIsActive, measureAndWriteCodexLbRoutingTruth, readCodexLbRoutingTruthReceipt } from '../core/codex-lb/routing-truth.js';
|
|
17
|
+
import { removeCodexLbOrphanManagedMarkers } from '../cli/install-helpers-codex-lb-config.js';
|
|
18
|
+
import { safeWriteCodexConfigToml } from '../core/codex-runtime/codex-desktop-config-policy.js';
|
|
19
|
+
import { probeTelegram, telegramSelfHealAction } from '../core/telegram/doctor.js';
|
|
20
|
+
import { TelegramClient } from '../core/telegram/client.js';
|
|
21
|
+
import { resolveTelegramBotToken } from '../core/telegram/keychain.js';
|
|
22
|
+
import { telegramLivenessPath } from '../core/telegram/liveness.js';
|
|
13
23
|
import { normalizeInstallScope } from '../core/init.js';
|
|
14
24
|
import { inspectCodexConfigReadability } from '../core/codex/codex-config-readability.js';
|
|
15
25
|
import { inspectOAuthCallbackPortConflict, oauthCallbackDoctorGuidance } from '../core/codex/oauth-callback-port-diagnostic.js';
|
|
16
|
-
import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
|
|
17
26
|
import { inventoryCodexPermissionProfiles } from '../core/codex/codex-permission-profiles.js';
|
|
18
27
|
import { appendMigrationEvents, hashConfigText } from '../core/migration/migration-transaction-journal.js';
|
|
19
28
|
import { resolveProviderContext } from '../core/provider/provider-context.js';
|
|
@@ -27,13 +36,18 @@ import { withSecretPreservationGuard } from '../core/config/config-migration-jou
|
|
|
27
36
|
import { reconcileDoctorSkills } from '../core/doctor/doctor-skill-reconcile.js';
|
|
28
37
|
import { buildSksMenuBarDoctorPostcheck } from '../core/doctor/sks-menubar-doctor.js';
|
|
29
38
|
import { isUpdateMigrationReceiptCurrent, projectUpdateMigrationReceiptPath, writeProjectUpdateMigrationReceipt } from '../core/update/update-migration-state.js';
|
|
30
|
-
import { inspectSksMenuBarStatus, installSksMenuBar, sksMenuBarRestartDeferred } from '../core/codex-app/menubar/index.js';
|
|
39
|
+
import { inspectSksMenuBarStatus, installSksMenuBar, sksMenuBarPaths, sksMenuBarRestartDeferred } from '../core/codex-app/menubar/index.js';
|
|
40
|
+
import { restartLaunchAgent } from '../core/codex-app/menubar/launch-agent.js';
|
|
31
41
|
import { sweepSksTempDirs } from '../core/retention.js';
|
|
32
42
|
import { detectImagegenCapability } from '../core/imagegen/imagegen-capability.js';
|
|
33
43
|
import { CURRENT_CODEX_RELEASE_MANIFEST } from '../core/codex-compat/codex-release-manifest.js';
|
|
34
44
|
import { formatHarnessConflictReport, scanHarnessConflicts } from '../core/harness-conflicts.js';
|
|
35
|
-
import { doctorArgWarnings, doctorMenuBarInstallPolicy, doctorPhaseIdsForProfile, doctorProfileFromArgs } from './doctor-profile.js';
|
|
36
|
-
export {
|
|
45
|
+
import { doctorArgWarnings as baseDoctorArgWarnings, doctorMenuBarInstallPolicy, doctorPhaseIdsForProfile, doctorProfileFromArgs } from './doctor-profile.js';
|
|
46
|
+
export { doctorMenuBarInstallPolicy, doctorProfileFromArgs } from './doctor-profile.js';
|
|
47
|
+
const CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG = '--retry-codex-lb-keychain-migration';
|
|
48
|
+
export function doctorArgWarnings(args = []) {
|
|
49
|
+
return baseDoctorArgWarnings(args.filter((arg) => arg !== CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG));
|
|
50
|
+
}
|
|
37
51
|
export function deferCommandAliasCleanupToMigrationReceipt(result) {
|
|
38
52
|
const observedBlockers = Array.isArray(result?.blockers)
|
|
39
53
|
? result.blockers.map(String).filter(Boolean)
|
|
@@ -53,6 +67,196 @@ export function deferCommandAliasCleanupToMigrationReceipt(result) {
|
|
|
53
67
|
]
|
|
54
68
|
};
|
|
55
69
|
}
|
|
70
|
+
export async function inspectDoctorCodexLbSecretResolution(input = {}, deps = {}) {
|
|
71
|
+
const processEnv = input.processEnv || process.env;
|
|
72
|
+
const home = path.resolve(input.home || processEnv.HOME || os.homedir());
|
|
73
|
+
const suppliedMigrationOptions = input.migrationOptions || {};
|
|
74
|
+
const migrationOptions = {
|
|
75
|
+
...suppliedMigrationOptions,
|
|
76
|
+
home,
|
|
77
|
+
env: suppliedMigrationOptions.env || processEnv,
|
|
78
|
+
processEnv: suppliedMigrationOptions.processEnv || processEnv,
|
|
79
|
+
...(input.baseUrl ? { baseUrl: input.baseUrl } : {}),
|
|
80
|
+
...(input.forceRetry === true ? { forceRetry: true } : {})
|
|
81
|
+
};
|
|
82
|
+
if (processEnv.SKS_TEST_FORBID_REAL_HOME === '1' && suppliedMigrationOptions.platform === undefined) {
|
|
83
|
+
migrationOptions.platform = 'linux';
|
|
84
|
+
}
|
|
85
|
+
const mode = input.fix === true ? 'repair' : 'inspect';
|
|
86
|
+
const reconcile = mode === 'repair'
|
|
87
|
+
? deps.repairImpl || repairCodexLbLegacyKeychainMigration
|
|
88
|
+
: deps.inspectImpl || inspectCodexLbLegacyKeychainMigration;
|
|
89
|
+
let migration;
|
|
90
|
+
try {
|
|
91
|
+
migration = await reconcile(migrationOptions);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
migration = {
|
|
95
|
+
schema: 'sks.codex-lb-legacy-keychain-reconciliation.v1',
|
|
96
|
+
ok: false,
|
|
97
|
+
status: `${mode}_failed`,
|
|
98
|
+
mode,
|
|
99
|
+
env_key_valid: false,
|
|
100
|
+
keychain_item_present: null,
|
|
101
|
+
prompt_risk: 'none',
|
|
102
|
+
attempted: false,
|
|
103
|
+
stamp_path: codexLbLegacyKeychainMigrationStampPath(home),
|
|
104
|
+
stamp_outcome: null,
|
|
105
|
+
keychain_deleted: false,
|
|
106
|
+
keychain_cleared: [],
|
|
107
|
+
blockers: [`codex_lb_legacy_keychain_${mode}_failed:${error instanceof Error ? error.message : String(error)}`]
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const envPath = String(suppliedMigrationOptions.envPath || codexLbEnvPath(home));
|
|
111
|
+
let loaded = null;
|
|
112
|
+
let resolutionError = null;
|
|
113
|
+
try {
|
|
114
|
+
loaded = await (deps.loadEnvImpl || loadCodexLbEnv)({
|
|
115
|
+
home,
|
|
116
|
+
processEnv,
|
|
117
|
+
envPath,
|
|
118
|
+
...(suppliedMigrationOptions.metadataPath ? { metadataPath: suppliedMigrationOptions.metadataPath } : {})
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
resolutionError = error instanceof Error ? error.message : String(error);
|
|
123
|
+
}
|
|
124
|
+
const source = String(loaded?.source || 'missing');
|
|
125
|
+
const unsafeEnvFile = Array.isArray(loaded?.blockers)
|
|
126
|
+
&& loaded.blockers.some((blocker) => String(blocker).startsWith('codex_lb_env_file_'));
|
|
127
|
+
const resolutionPath = source === 'env-file' || unsafeEnvFile
|
|
128
|
+
? String(loaded?.env_paths?.[0] || envPath)
|
|
129
|
+
: null;
|
|
130
|
+
const operatorActions = [];
|
|
131
|
+
if (mode === 'inspect' && migration.prompt_risk === 'one_time_on_repair') {
|
|
132
|
+
operatorActions.push('Run `sks doctor --fix` to perform the one-time legacy Keychain transfer.');
|
|
133
|
+
}
|
|
134
|
+
if (mode === 'repair'
|
|
135
|
+
&& migration.ok === false
|
|
136
|
+
&& (migration.attempted === true || migration.status === 'already_attempted')) {
|
|
137
|
+
operatorActions.push(`Run \`sks doctor --fix ${CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG}\` to explicitly retry the one-time Keychain transfer.`);
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
ok: migration.ok !== false && resolutionError === null,
|
|
141
|
+
secret_resolution: {
|
|
142
|
+
source,
|
|
143
|
+
path: resolutionPath,
|
|
144
|
+
prompt_risk: migration.prompt_risk || 'none'
|
|
145
|
+
},
|
|
146
|
+
legacy_keychain_migration: {
|
|
147
|
+
...migration,
|
|
148
|
+
operator_actions: operatorActions,
|
|
149
|
+
...(resolutionError ? { resolution_error: resolutionError } : {})
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export async function inspectDoctorCodexLbDivergence(input = {}, deps = {}) {
|
|
154
|
+
const processEnv = input.processEnv || process.env;
|
|
155
|
+
const home = path.resolve(input.home || processEnv.HOME || os.homedir());
|
|
156
|
+
const status = input.providerStatus || {};
|
|
157
|
+
const configPath = String(status.config_path || path.join(home, '.codex', 'config.toml'));
|
|
158
|
+
const configText = await (deps.readTextImpl || readText)(configPath, '');
|
|
159
|
+
const orphan = removeCodexLbOrphanManagedMarkers(configText);
|
|
160
|
+
let orphanRepair = {
|
|
161
|
+
schema: 'sks.codex-lb-orphan-managed-marker-repair.v1',
|
|
162
|
+
attempted: false,
|
|
163
|
+
changed: false,
|
|
164
|
+
markers: orphan.orphan_markers,
|
|
165
|
+
receipt: null
|
|
166
|
+
};
|
|
167
|
+
if (input.fix === true && orphan.changed) {
|
|
168
|
+
const write = deps.writeConfigImpl || safeWriteCodexConfigToml;
|
|
169
|
+
const receipt = await write(configPath, configText, orphan.text, 'doctor-codex-lb-orphan-marker');
|
|
170
|
+
orphanRepair = {
|
|
171
|
+
...orphanRepair,
|
|
172
|
+
attempted: true,
|
|
173
|
+
changed: receipt?.ok !== false,
|
|
174
|
+
receipt
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const load = deps.loadEnvImpl || loadCodexLbEnv;
|
|
178
|
+
const canonical = await load({
|
|
179
|
+
home,
|
|
180
|
+
processEnv: {},
|
|
181
|
+
envPath: String(status.env_path || codexLbEnvPath(home))
|
|
182
|
+
}).catch(() => null);
|
|
183
|
+
const ambientKey = String(processEnv.CODEX_LB_API_KEY || '').trim();
|
|
184
|
+
const canonicalKey = String(canonical?.secret_api_key || '').trim();
|
|
185
|
+
const sha256 = (value) => value
|
|
186
|
+
? createHash('sha256').update(value).digest('hex')
|
|
187
|
+
: null;
|
|
188
|
+
const ambientHash = sha256(ambientKey);
|
|
189
|
+
const canonicalHash = sha256(canonicalKey);
|
|
190
|
+
const staleAmbient = Boolean(ambientHash && canonicalHash && ambientHash !== canonicalHash);
|
|
191
|
+
const bridgeActive = status.desktop_mode === 'desktop-native-bridge';
|
|
192
|
+
const definedButNotSelected = status.provider_configured === true
|
|
193
|
+
&& status.selected !== true
|
|
194
|
+
&& !bridgeActive
|
|
195
|
+
&& status.desktop_mode !== 'desktop-dual-auth-compat';
|
|
196
|
+
const mode = status.selected === true
|
|
197
|
+
? 'cli-provider'
|
|
198
|
+
: bridgeActive
|
|
199
|
+
? 'desktop-native-bridge'
|
|
200
|
+
: 'disabled';
|
|
201
|
+
const inspectLaunch = deps.inspectLaunchImpl || inspectDesktopCenterLaunchCredentials;
|
|
202
|
+
const syncLaunch = deps.syncLaunchImpl || syncDesktopCenterLaunchCredentials;
|
|
203
|
+
const launchOptions = {
|
|
204
|
+
mode,
|
|
205
|
+
home,
|
|
206
|
+
...(input.launchctlBin ? { launchctlBin: input.launchctlBin } : {}),
|
|
207
|
+
...(input.platform ? { platform: input.platform } : {}),
|
|
208
|
+
...(input.forceLaunchctl ? { force: true } : {}),
|
|
209
|
+
...(input.runProcessImpl ? { runProcessImpl: input.runProcessImpl } : {})
|
|
210
|
+
};
|
|
211
|
+
const launchBefore = await inspectLaunch(launchOptions);
|
|
212
|
+
const launchRepair = input.fix === true && launchBefore.ok === false
|
|
213
|
+
? await syncLaunch({ ...launchOptions, skipPurge: true })
|
|
214
|
+
: null;
|
|
215
|
+
const launchAfter = launchRepair ? await inspectLaunch(launchOptions) : launchBefore;
|
|
216
|
+
const warnings = [
|
|
217
|
+
...(definedButNotSelected
|
|
218
|
+
? ['codex_lb_defined_but_not_selected']
|
|
219
|
+
: []),
|
|
220
|
+
...(staleAmbient ? ['codex_lb_stale_ambient_key'] : []),
|
|
221
|
+
...(orphan.orphan_markers.length > 0
|
|
222
|
+
? [`codex_lb_orphan_managed_markers:${orphan.orphan_markers.join(',')}`]
|
|
223
|
+
: [])
|
|
224
|
+
];
|
|
225
|
+
const blockers = [
|
|
226
|
+
...(launchAfter.ok === false ? launchAfter.blockers || ['codex_lb_launchd_selection_state_mismatch'] : []),
|
|
227
|
+
...(input.fix === true && orphan.changed && orphanRepair.changed !== true
|
|
228
|
+
? ['codex_lb_orphan_marker_repair_failed']
|
|
229
|
+
: [])
|
|
230
|
+
];
|
|
231
|
+
return {
|
|
232
|
+
schema: 'sks.doctor-codex-lb-divergence.v1',
|
|
233
|
+
ok: blockers.length === 0,
|
|
234
|
+
warnings,
|
|
235
|
+
blockers,
|
|
236
|
+
operator_actions: [
|
|
237
|
+
...(definedButNotSelected
|
|
238
|
+
? ['Run `sks codex-lb use-cli` to select the stored provider.']
|
|
239
|
+
: []),
|
|
240
|
+
...(staleAmbient
|
|
241
|
+
? ['Remove or update the stale shell export: `unset CODEX_LB_API_KEY`; the canonical key remains in ~/.codex/sks-codex-lb.env.']
|
|
242
|
+
: []),
|
|
243
|
+
...(launchAfter.operator_actions || [])
|
|
244
|
+
],
|
|
245
|
+
ambient_key: {
|
|
246
|
+
present: Boolean(ambientKey),
|
|
247
|
+
sha256: ambientHash,
|
|
248
|
+
matches_canonical: ambientHash && canonicalHash ? ambientHash === canonicalHash : null
|
|
249
|
+
},
|
|
250
|
+
canonical_key: {
|
|
251
|
+
present: Boolean(canonicalKey),
|
|
252
|
+
sha256: canonicalHash,
|
|
253
|
+
path: String(status.env_path || codexLbEnvPath(home))
|
|
254
|
+
},
|
|
255
|
+
orphan_markers: orphan.orphan_markers,
|
|
256
|
+
orphan_marker_repair: orphanRepair,
|
|
257
|
+
launchd: { before: launchBefore, repair: launchRepair, after: launchAfter }
|
|
258
|
+
};
|
|
259
|
+
}
|
|
56
260
|
export async function run(_command, args = [], deps = {}) {
|
|
57
261
|
const root = await projectRoot();
|
|
58
262
|
if (flag(args, '--search')) {
|
|
@@ -102,9 +306,9 @@ export async function run(_command, args = [], deps = {}) {
|
|
|
102
306
|
: root;
|
|
103
307
|
return withSecretPreservationGuard(guardRoot, 'doctor-fix', async () => (globalOnly
|
|
104
308
|
? runDoctorGlobalOnlyFix(args, root, deps)
|
|
105
|
-
: runDoctor(args, root, doctorFix)));
|
|
309
|
+
: runDoctor(args, root, doctorFix, deps)));
|
|
106
310
|
}
|
|
107
|
-
return runDoctor(args, root, doctorFix);
|
|
311
|
+
return runDoctor(args, root, doctorFix, deps);
|
|
108
312
|
}
|
|
109
313
|
export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
110
314
|
const startedAtMs = Date.now();
|
|
@@ -122,7 +326,29 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
122
326
|
const doctorEnv = deps.env || (deps.home
|
|
123
327
|
? { ...process.env, HOME: home }
|
|
124
328
|
: process.env);
|
|
329
|
+
const statusOptions = {
|
|
330
|
+
home,
|
|
331
|
+
env: doctorEnv,
|
|
332
|
+
processEnv: doctorEnv
|
|
333
|
+
};
|
|
334
|
+
const preRepairProviderStatus = await codexLbStatusImpl({
|
|
335
|
+
...statusOptions,
|
|
336
|
+
probeToolOutputRecovery: false
|
|
337
|
+
}).catch(() => null);
|
|
338
|
+
const codexLbSecretProbeImpl = deps.codexLbSecretProbeImpl || inspectDoctorCodexLbSecretResolution;
|
|
339
|
+
const codexLbSecretProbe = await codexLbSecretProbeImpl({
|
|
340
|
+
home,
|
|
341
|
+
processEnv: doctorEnv,
|
|
342
|
+
fix: true,
|
|
343
|
+
forceRetry: flag(args, CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG),
|
|
344
|
+
baseUrl: preRepairProviderStatus?.base_url || preRepairProviderStatus?.provider_base_url || null,
|
|
345
|
+
migrationOptions: {
|
|
346
|
+
...(deps.codexLbMigrationOptions || {}),
|
|
347
|
+
...(!deps.codexLbMigrationOptions && deps.codexLbStatusImpl ? { platform: 'linux' } : {})
|
|
348
|
+
}
|
|
349
|
+
});
|
|
125
350
|
const providerStatus = await codexLbStatusImpl({
|
|
351
|
+
...statusOptions,
|
|
126
352
|
probeToolOutputRecovery: true,
|
|
127
353
|
allowUnverifiedToolOutputRecovery: codexLbToolOutputRecoveryOverrideAcknowledged({ args })
|
|
128
354
|
}).catch((err) => ({
|
|
@@ -188,6 +414,25 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
188
414
|
blockers: [err?.message || String(err)],
|
|
189
415
|
warnings: []
|
|
190
416
|
}));
|
|
417
|
+
const codexLbRoutingTruth = await codexLbRoutingTruthForStatus(providerStatus, { home, remeasure: true });
|
|
418
|
+
const codexLbRoutingReady = !doctorCodexLbRouteExpected(providerStatus)
|
|
419
|
+
|| codexLbRoutingTruthIsActive(codexLbRoutingTruth);
|
|
420
|
+
const codexLbDivergence = await inspectDoctorCodexLbDivergence({
|
|
421
|
+
home,
|
|
422
|
+
processEnv: doctorEnv,
|
|
423
|
+
providerStatus,
|
|
424
|
+
fix: true,
|
|
425
|
+
...(deps.codexLbLaunchctlBin ? { launchctlBin: deps.codexLbLaunchctlBin } : {}),
|
|
426
|
+
...(deps.codexLbLaunchPlatform ? { platform: deps.codexLbLaunchPlatform } : {}),
|
|
427
|
+
...(deps.codexLbLaunchRunProcessImpl ? { runProcessImpl: deps.codexLbLaunchRunProcessImpl } : {})
|
|
428
|
+
}, deps.codexLbDivergenceDeps || {});
|
|
429
|
+
const telegramRemote = await inspectTelegramRemote({
|
|
430
|
+
live: true,
|
|
431
|
+
fix: true,
|
|
432
|
+
root,
|
|
433
|
+
home,
|
|
434
|
+
env: doctorEnv
|
|
435
|
+
}, deps);
|
|
191
436
|
const recoveryReady = codexLbRecoveryStatusReady(providerStatus, true);
|
|
192
437
|
const globalSkillsReady = !globalSkills?.error
|
|
193
438
|
&& globalSkills?.ok !== false
|
|
@@ -202,7 +447,12 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
202
447
|
...(!globalFastModeReady ? [`global_fast_mode_repair_failed:${globalFastMode?.error || globalFastMode?.status || 'unknown'}`] : []),
|
|
203
448
|
...(!openRouterProviderReady ? (openRouterProvider?.blockers || ['openrouter_provider_repair_failed']) : []),
|
|
204
449
|
...(!menuBarReady ? (menuBar?.blockers || ['sks_menubar_repair_failed']) : []),
|
|
205
|
-
...(
|
|
450
|
+
...(codexLbSecretProbe.ok === false
|
|
451
|
+
? (codexLbSecretProbe.legacy_keychain_migration?.blockers || ['codex_lb_secret_resolution_failed'])
|
|
452
|
+
: []),
|
|
453
|
+
...(!recoveryReady ? (providerStatus?.tool_output_recovery?.blockers || ['codex_lb_tool_output_recovery_unverified']) : []),
|
|
454
|
+
...(!codexLbRoutingReady ? (codexLbRoutingTruth?.blockers || ['codex_lb_routing_truth_unverified']) : []),
|
|
455
|
+
...(codexLbDivergence.blockers || [])
|
|
206
456
|
].map(String).filter(Boolean))];
|
|
207
457
|
const ok = blockers.length === 0;
|
|
208
458
|
return {
|
|
@@ -231,14 +481,23 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
231
481
|
codex_app_fast_mode: globalFastMode,
|
|
232
482
|
openrouter_provider: openRouterProvider,
|
|
233
483
|
sks_menubar: menuBar,
|
|
484
|
+
telegram_remote: telegramRemote,
|
|
234
485
|
codex_lb: {
|
|
235
486
|
provider_status: providerStatus,
|
|
236
487
|
tool_output_recovery: providerStatus?.tool_output_recovery || null,
|
|
237
|
-
recovery_ok: recoveryReady
|
|
488
|
+
recovery_ok: recoveryReady,
|
|
489
|
+
routing_truth: codexLbRoutingTruth,
|
|
490
|
+
routing_ok: codexLbRoutingReady,
|
|
491
|
+
secret_resolution: codexLbSecretProbe.secret_resolution,
|
|
492
|
+
legacy_keychain_migration: codexLbSecretProbe.legacy_keychain_migration,
|
|
493
|
+
divergence: codexLbDivergence
|
|
238
494
|
},
|
|
239
495
|
blockers,
|
|
240
496
|
next_actions: [
|
|
241
497
|
...(recoveryReady ? [] : (providerStatus?.tool_output_recovery?.operator_actions || [])),
|
|
498
|
+
...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
|
|
499
|
+
...(codexLbDivergence.operator_actions || []),
|
|
500
|
+
...telegramDoctorOperatorActions(telegramRemote),
|
|
242
501
|
...(!openRouterProviderReady ? ['Run `sks codex-app set-openrouter-key` to repair the stored-key provider configuration without switching models.'] : []),
|
|
243
502
|
'Run `sks doctor --fix --json` from a specific project directory when project-scoped repair is required.'
|
|
244
503
|
]
|
|
@@ -261,6 +520,15 @@ async function runDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
261
520
|
console.log(`SKS Doctor global repair: ${result.ok ? 'ok' : 'blocked'}`);
|
|
262
521
|
console.log(`Global skills: ${result.skills.global?.error ? 'blocked' : 'reconciled'}`);
|
|
263
522
|
console.log(`SKS menu bar: ${result.sks_menubar?.status || (result.sks_menubar?.ok ? 'ok' : 'blocked')}`);
|
|
523
|
+
const telegramOutcome = result.telegram_remote?.self_heal_outcome;
|
|
524
|
+
const telegramAction = telegramOutcome?.attempted
|
|
525
|
+
? telegramOutcome.action
|
|
526
|
+
: result.telegram_remote?.self_heal_action || 'none';
|
|
527
|
+
console.log(`Telegram Remote: ${result.telegram_remote?.status || 'unknown'} (self-heal ${telegramAction}${telegramOutcome?.attempted ? `, ${telegramOutcome.recovered ? 'recovered' : 'still degraded'}` : ''})`);
|
|
528
|
+
const telegramCheckedLine = telegramDoctorCheckedLine(result.telegram_remote);
|
|
529
|
+
if (telegramCheckedLine)
|
|
530
|
+
console.log(telegramCheckedLine);
|
|
531
|
+
console.log(`codex-lb key: ${result.codex_lb.secret_resolution.source} (prompt risk ${result.codex_lb.secret_resolution.prompt_risk})`);
|
|
264
532
|
for (const blocker of result.blockers)
|
|
265
533
|
console.log(`- blocker: ${blocker}`);
|
|
266
534
|
for (const action of result.next_actions)
|
|
@@ -277,8 +545,203 @@ function codexLbRecoveryStatusReady(status, probeRequired = false) {
|
|
|
277
545
|
return false;
|
|
278
546
|
if (status.selected === false)
|
|
279
547
|
return true;
|
|
548
|
+
if (!probeRequired)
|
|
549
|
+
return true;
|
|
280
550
|
return status.selected === true && status.tool_output_recovery?.ok === true;
|
|
281
551
|
}
|
|
552
|
+
export async function codexLbRoutingTruthForStatus(status, deps = {}) {
|
|
553
|
+
if (!status)
|
|
554
|
+
return null;
|
|
555
|
+
const statusEnvPath = typeof status.env_path === 'string' && status.env_path
|
|
556
|
+
? status.env_path
|
|
557
|
+
: null;
|
|
558
|
+
const resolvedHome = deps.home
|
|
559
|
+
? path.resolve(deps.home)
|
|
560
|
+
: statusEnvPath
|
|
561
|
+
? path.dirname(path.dirname(statusEnvPath))
|
|
562
|
+
: undefined;
|
|
563
|
+
const envOptions = {
|
|
564
|
+
...(resolvedHome ? { home: resolvedHome } : {}),
|
|
565
|
+
...(statusEnvPath ? { envPath: statusEnvPath } : {})
|
|
566
|
+
};
|
|
567
|
+
const routeSelected = doctorCodexLbRouteExpected(status);
|
|
568
|
+
const mode = status.desktop_mode === 'desktop-native-bridge' ? 'bridge' : 'cli-provider';
|
|
569
|
+
const receiptOptions = {
|
|
570
|
+
...(resolvedHome ? { home: resolvedHome } : {}),
|
|
571
|
+
...(deps.receiptPath ? { receiptPath: deps.receiptPath } : {}),
|
|
572
|
+
expectedMode: mode,
|
|
573
|
+
expectedSelected: routeSelected
|
|
574
|
+
};
|
|
575
|
+
const receipt = await readCodexLbRoutingTruthReceipt(receiptOptions).catch(() => null);
|
|
576
|
+
if (deps.remeasure !== true && receipt?.fresh === true)
|
|
577
|
+
return receipt;
|
|
578
|
+
try {
|
|
579
|
+
const loaded = await loadCodexLbEnv({ ...envOptions, processEnv: {} });
|
|
580
|
+
const baseUrl = loaded.base_url || status.base_url || null;
|
|
581
|
+
const configuredHost = publicUrlHost(baseUrl);
|
|
582
|
+
const authTransport = mode === 'cli-provider'
|
|
583
|
+
? 'x-codex-lb-api-key'
|
|
584
|
+
: doctorBridgeRoutingTransport(status, receipt);
|
|
585
|
+
const contextReceipt = await readCodexLbRoutingTruthReceipt({
|
|
586
|
+
...receiptOptions,
|
|
587
|
+
expectedConfiguredHost: configuredHost,
|
|
588
|
+
expectedAuthTransport: authTransport
|
|
589
|
+
}).catch(() => null);
|
|
590
|
+
if (deps.remeasure !== true && contextReceipt?.fresh === true)
|
|
591
|
+
return contextReceipt;
|
|
592
|
+
return measureAndWriteCodexLbRoutingTruth({
|
|
593
|
+
mode,
|
|
594
|
+
selected: routeSelected,
|
|
595
|
+
baseUrl,
|
|
596
|
+
apiKey: loaded.secret_api_key,
|
|
597
|
+
authTransport,
|
|
598
|
+
measure: routeSelected,
|
|
599
|
+
...(deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {})
|
|
600
|
+
}, {
|
|
601
|
+
...envOptions,
|
|
602
|
+
...(deps.receiptPath ? { receiptPath: deps.receiptPath } : {})
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
catch {
|
|
606
|
+
return measureAndWriteCodexLbRoutingTruth({
|
|
607
|
+
mode,
|
|
608
|
+
selected: routeSelected,
|
|
609
|
+
baseUrl: status.base_url || null,
|
|
610
|
+
apiKey: null,
|
|
611
|
+
authTransport: mode === 'cli-provider'
|
|
612
|
+
? 'x-codex-lb-api-key'
|
|
613
|
+
: doctorBridgeRoutingTransport(status, receipt),
|
|
614
|
+
measure: false
|
|
615
|
+
}, {
|
|
616
|
+
...envOptions,
|
|
617
|
+
...(deps.receiptPath ? { receiptPath: deps.receiptPath } : {})
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
function doctorCodexLbRouteExpected(status) {
|
|
622
|
+
return status?.selected === true || status?.desktop_mode === 'desktop-native-bridge';
|
|
623
|
+
}
|
|
624
|
+
function doctorBridgeRoutingTransport(status, receipt) {
|
|
625
|
+
if (receipt?.mode === 'bridge'
|
|
626
|
+
&& (receipt.auth_transport === 'authorization-bearer'
|
|
627
|
+
|| receipt.auth_transport === 'x-codex-lb-api-key')) {
|
|
628
|
+
return receipt.auth_transport;
|
|
629
|
+
}
|
|
630
|
+
return status?.gateway_auth_transport === 'authorization-bearer-compat'
|
|
631
|
+
? 'authorization-bearer'
|
|
632
|
+
: 'x-codex-lb-api-key';
|
|
633
|
+
}
|
|
634
|
+
function publicUrlHost(value) {
|
|
635
|
+
try {
|
|
636
|
+
return value ? new URL(String(value)).host : null;
|
|
637
|
+
}
|
|
638
|
+
catch {
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
export async function inspectTelegramRemote(input = {}, deps = {}) {
|
|
643
|
+
const env = input.env || process.env;
|
|
644
|
+
const home = path.resolve(input.home || env.HOME || os.homedir());
|
|
645
|
+
const receiptPath = input.receiptPath || telegramLivenessPath(home);
|
|
646
|
+
const probeImpl = deps.probeTelegramImpl || probeTelegram;
|
|
647
|
+
let tokenProvider = deps.telegramTokenProvider;
|
|
648
|
+
let client = deps.telegramClient;
|
|
649
|
+
if (input.live && (!tokenProvider || !client)) {
|
|
650
|
+
const resolveImpl = deps.resolveTelegramBotTokenImpl || resolveTelegramBotToken;
|
|
651
|
+
let resolvedToken = null;
|
|
652
|
+
tokenProvider ||= {
|
|
653
|
+
loadToken: () => {
|
|
654
|
+
resolvedToken ||= Promise.resolve(resolveImpl({ env })).then((result) => result.token);
|
|
655
|
+
return resolvedToken;
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
client ||= new TelegramClient({ tokenProvider });
|
|
659
|
+
}
|
|
660
|
+
const runProbe = () => {
|
|
661
|
+
if (!input.live)
|
|
662
|
+
return probeImpl({ receiptPath });
|
|
663
|
+
if (!client || !tokenProvider)
|
|
664
|
+
throw new Error('telegram_live_probe_dependencies_missing');
|
|
665
|
+
return probeImpl({ client, tokenProvider, receiptPath });
|
|
666
|
+
};
|
|
667
|
+
const before = await runProbe();
|
|
668
|
+
const action = telegramSelfHealAction(before);
|
|
669
|
+
if (!input.fix || action !== 'restart_poll' || !before.token_configured || before.paired_chat_count < 1) {
|
|
670
|
+
return {
|
|
671
|
+
...before,
|
|
672
|
+
self_heal_action: action,
|
|
673
|
+
self_heal_outcome: {
|
|
674
|
+
requested: input.fix === true,
|
|
675
|
+
attempted: false,
|
|
676
|
+
action,
|
|
677
|
+
reason: input.fix !== true
|
|
678
|
+
? 'report_only'
|
|
679
|
+
: action !== 'restart_poll'
|
|
680
|
+
? 'action_not_restart_poll'
|
|
681
|
+
: 'telegram_not_configured_or_paired'
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
const restartImpl = deps.restartLaunchAgentImpl || restartLaunchAgent;
|
|
686
|
+
const restart = await restartImpl(sksMenuBarPaths(home, input.root), env).catch((error) => ({
|
|
687
|
+
ok: false,
|
|
688
|
+
error: error instanceof Error ? error.message : String(error)
|
|
689
|
+
}));
|
|
690
|
+
const maximumReprobes = Math.max(1, Math.min(deps.telegramReprobeAttempts ?? 3, 5));
|
|
691
|
+
const reprobeDelayMs = Math.max(0, Math.min(deps.telegramReprobeDelayMs ?? 500, 5_000));
|
|
692
|
+
const sleepImpl = deps.telegramSleepImpl || ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
693
|
+
let reprobeAttempts = 1;
|
|
694
|
+
let after = await runProbe();
|
|
695
|
+
let afterAction = telegramSelfHealAction(after);
|
|
696
|
+
while (restart?.ok === true && afterAction === 'restart_poll' && reprobeAttempts < maximumReprobes) {
|
|
697
|
+
await sleepImpl(reprobeDelayMs);
|
|
698
|
+
after = await runProbe();
|
|
699
|
+
afterAction = telegramSelfHealAction(after);
|
|
700
|
+
reprobeAttempts += 1;
|
|
701
|
+
}
|
|
702
|
+
return {
|
|
703
|
+
...after,
|
|
704
|
+
self_heal_action: afterAction,
|
|
705
|
+
self_heal_attempted_action: action,
|
|
706
|
+
self_heal_before: before,
|
|
707
|
+
self_heal_outcome: {
|
|
708
|
+
requested: true,
|
|
709
|
+
attempted: true,
|
|
710
|
+
action,
|
|
711
|
+
after_action: afterAction,
|
|
712
|
+
restart_ok: restart?.ok === true,
|
|
713
|
+
reprobe_ok: after.ok,
|
|
714
|
+
reprobe_attempts: reprobeAttempts,
|
|
715
|
+
recovered: restart?.ok === true && after.ok && afterAction === 'none',
|
|
716
|
+
error: restart?.error || null,
|
|
717
|
+
restart
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
export function telegramDoctorCheckedLine(probe, indent = '') {
|
|
722
|
+
if (!probe?.getme_checked_at)
|
|
723
|
+
return null;
|
|
724
|
+
return `${indent}checked: ${probe.getme_checked_at} (${probe.getme_latency_ms ?? 'unknown'} ms, ${probe.getme_check_kind || 'receipt'})`;
|
|
725
|
+
}
|
|
726
|
+
function telegramDoctorOperatorActions(probe) {
|
|
727
|
+
if (!probe || probe.status === 'not_configured')
|
|
728
|
+
return [];
|
|
729
|
+
if (probe.self_heal_action === 'restart_poll') {
|
|
730
|
+
if (probe.self_heal_outcome?.recovered === true)
|
|
731
|
+
return [];
|
|
732
|
+
return ['Run `sks menubar restart` to restart the resident Telegram long poller.'];
|
|
733
|
+
}
|
|
734
|
+
if (probe.self_heal_action === 'revalidate_token') {
|
|
735
|
+
return ['Run `sks telegram setup --token-stdin`, then `sks menubar restart`, to revalidate the bot identity.'];
|
|
736
|
+
}
|
|
737
|
+
if (probe.self_heal_action === 'operator_remove_webhook') {
|
|
738
|
+
return ['Remove the Telegram bot webhook through the Bot API, then run `sks menubar restart`; getUpdates and webhooks cannot be active together.'];
|
|
739
|
+
}
|
|
740
|
+
if (probe.self_heal_action === 'operator_repair_audit') {
|
|
741
|
+
return ['Restore owner-only write access to `~/.codex/sks-menubar/logs/telegram-audit.jsonl`, then run `sks menubar restart`.'];
|
|
742
|
+
}
|
|
743
|
+
return [];
|
|
744
|
+
}
|
|
282
745
|
async function runDoctorJsonFastPath(args = [], root) {
|
|
283
746
|
const startedAtMs = Date.now();
|
|
284
747
|
const reportFile = readOption(args, '--report-file', null);
|
|
@@ -289,7 +752,7 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
289
752
|
requireActualCodex: false,
|
|
290
753
|
codexBin: codexBin || undefined
|
|
291
754
|
};
|
|
292
|
-
const [codex, rust, codexConfig, sneakoscopeExists, oauthCallbackPortDiagnostic] = await Promise.all([
|
|
755
|
+
const [codex, rust, codexConfig, sneakoscopeExists, oauthCallbackPortDiagnostic, codexLbSecretProbe] = await Promise.all([
|
|
293
756
|
codexBin
|
|
294
757
|
? Promise.resolve({ bin: codexBin, version: 'fixture-or-explicit', available: true })
|
|
295
758
|
: getCodexInfo().catch(() => ({ bin: null, version: null, available: false })),
|
|
@@ -301,9 +764,11 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
301
764
|
blockers: [err?.message || String(err)]
|
|
302
765
|
})),
|
|
303
766
|
exists(`${root}/.sneakoscope`),
|
|
304
|
-
inspectOAuthCallbackPortConflict()
|
|
767
|
+
inspectOAuthCallbackPortConflict(),
|
|
768
|
+
inspectDoctorCodexLbSecretResolution({ processEnv: process.env, fix: false })
|
|
305
769
|
]);
|
|
306
770
|
const oauthCallbackOperatorActions = oauthCallbackDoctorGuidance(oauthCallbackPortDiagnostic);
|
|
771
|
+
const telegramRemote = await inspectTelegramRemote();
|
|
307
772
|
const ready = {
|
|
308
773
|
schema: 'sks.doctor-readiness-matrix.v2',
|
|
309
774
|
generated_at: nowIso(),
|
|
@@ -313,15 +778,13 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
313
778
|
managed_state_current: sneakoscopeExists,
|
|
314
779
|
codex_config_readable_by_node: Boolean(codexConfig?.ok),
|
|
315
780
|
codex_config_readable_by_codex_cli: false,
|
|
316
|
-
codex_config_readable_in_zellij_context: false,
|
|
317
781
|
codex_app_ready: false,
|
|
318
782
|
primary_blocker: codexConfig?.ok ? null : 'codex_config_unreadable',
|
|
319
783
|
blockers: codexConfig?.ok ? [] : ['codex_config_unreadable'],
|
|
320
784
|
next_actions: codexConfig?.ok ? [] : ['Run `sks doctor --fix --json` to repair managed config.']
|
|
321
785
|
};
|
|
322
786
|
const codexNativeFeatureMatrix = fallbackCodexNativeFeatureMatrix(codex, [], ['native_feature_matrix_deferred_to_full_doctor_or_route_gate']);
|
|
323
|
-
const
|
|
324
|
-
const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
|
|
787
|
+
const runtimeReadiness = buildRuntimeReadiness(codexNativeFeatureMatrix);
|
|
325
788
|
const deferredImagegen = deferredNativeRepair('sks.doctor-imagegen-repair.v1', false, [
|
|
326
789
|
'Run `sks doctor --fix --repair-native-capabilities --json` after enabling Codex App image_generation.'
|
|
327
790
|
]);
|
|
@@ -340,13 +803,20 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
340
803
|
deep_diagnostics_skipped: true,
|
|
341
804
|
deep_ok: null,
|
|
342
805
|
not_counted_as_full_doctor: true,
|
|
343
|
-
next_actions: [
|
|
806
|
+
next_actions: [
|
|
807
|
+
'Run sks doctor --full --json for deep diagnostics.',
|
|
808
|
+
...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
|
|
809
|
+
...telegramDoctorOperatorActions(telegramRemote)
|
|
810
|
+
],
|
|
344
811
|
root,
|
|
345
812
|
fast_path: true,
|
|
346
813
|
no_fix_write_policy: reportFile ? 'report_file_only' : 'no_writes_performed',
|
|
347
814
|
arg_warnings: doctorArgWarnings(args),
|
|
348
815
|
warnings: [...oauthCallbackPortDiagnostic.warnings],
|
|
349
|
-
operator_actions:
|
|
816
|
+
operator_actions: [
|
|
817
|
+
...oauthCallbackOperatorActions,
|
|
818
|
+
...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || [])
|
|
819
|
+
],
|
|
350
820
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
351
821
|
codex,
|
|
352
822
|
oauth_callback_port_diagnostic: oauthCallbackPortDiagnostic,
|
|
@@ -371,6 +841,7 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
371
841
|
blockers: [],
|
|
372
842
|
warnings: ['menubar_install_deferred_to_fix_or_full_doctor']
|
|
373
843
|
},
|
|
844
|
+
telegram_remote: telegramRemote,
|
|
374
845
|
provider_context: {
|
|
375
846
|
schema: 'sks.provider-context.v1',
|
|
376
847
|
generated_at: nowIso(),
|
|
@@ -384,14 +855,18 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
384
855
|
warnings: ['provider_context_optional_diagnostic_skipped'],
|
|
385
856
|
signals: {}
|
|
386
857
|
},
|
|
387
|
-
codex_lb:
|
|
858
|
+
codex_lb: {
|
|
859
|
+
...codexLbMetrics(await readCodexLbCircuit(root).catch(() => ({}))),
|
|
860
|
+
routing_truth: null,
|
|
861
|
+
routing_measurement_deferred: true,
|
|
862
|
+
secret_resolution: codexLbSecretProbe.secret_resolution,
|
|
863
|
+
legacy_keychain_migration: codexLbSecretProbe.legacy_keychain_migration
|
|
864
|
+
},
|
|
388
865
|
codex_doctor: null,
|
|
389
866
|
pre_repair_codex_doctor: null,
|
|
390
867
|
post_repair_codex_doctor: null,
|
|
391
868
|
codex_doctor_diff: null,
|
|
392
869
|
observational_codex_doctor_diff: null,
|
|
393
|
-
zellij: { ok: true, skipped: true, status: 'skipped_fast_path', required_for: ['sks --mad', 'interactive lane UI'] },
|
|
394
|
-
zellij_repair: { schema: 'sks.zellij-self-heal.v1', ok: true, skipped: true, blockers: [], warnings: ['zellij_repair_deferred_to_full_doctor_or_route_gate'] },
|
|
395
870
|
context7_repair: { schema: 'sks.doctor-context7-repair.v1', ok: true, fix: false, skipped: true, actions: [], blockers: [], warnings: ['context7_repair_deferred_to_fix'] },
|
|
396
871
|
codex_startup_repair: { schema: 'sks.doctor-codex-startup-repair.v1', ok: true, fix: false, skipped: true, actions: [], blockers: [], warnings: ['codex_startup_repair_deferred_to_fix'] },
|
|
397
872
|
startup_config_repair: null,
|
|
@@ -402,7 +877,6 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
402
877
|
postcheck: null,
|
|
403
878
|
local_model: null,
|
|
404
879
|
agent_role_config: { schema: 'sks.agent-role-config-repair.v1', ok: true, apply: false, skipped: true, blockers: [] },
|
|
405
|
-
zellij_readiness: zellijReadiness,
|
|
406
880
|
codex_permission_profiles: { skipped: true, reason: 'doctor_json_fast_path_optional_diagnostics_skipped' },
|
|
407
881
|
command_aliases: { schema: 'sks.command-alias-cleanup.v1', ok: true, skipped: true, reason: 'doctor_json_fast_path_no_write' },
|
|
408
882
|
sks_temp_sweep: { ok: true, skipped: true, action_count: 0, reason: 'doctor_without_fix', error: null },
|
|
@@ -423,7 +897,6 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
423
897
|
migration_journal: null,
|
|
424
898
|
global_sks_installs: null,
|
|
425
899
|
agent_role_config: null,
|
|
426
|
-
zellij: null,
|
|
427
900
|
context7: null,
|
|
428
901
|
codex_startup: null,
|
|
429
902
|
startup_config: null,
|
|
@@ -452,7 +925,7 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
452
925
|
process.exitCode = 1;
|
|
453
926
|
return result;
|
|
454
927
|
}
|
|
455
|
-
async function runDoctor(args = [], root, doctorFix) {
|
|
928
|
+
async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
456
929
|
const startedAtMs = Date.now();
|
|
457
930
|
const oauthCallbackPortDiagnostic = await inspectOAuthCallbackPortConflict();
|
|
458
931
|
const oauthCallbackOperatorActions = oauthCallbackDoctorGuidance(oauthCallbackPortDiagnostic);
|
|
@@ -471,7 +944,6 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
471
944
|
const actualCodexProbeEnabled = deepDiagnostics || actualCodexProbeRequested;
|
|
472
945
|
const requireActualCodexProbe = flag(args, '--require-actual-codex') || (deepDiagnostics && doctorFix);
|
|
473
946
|
const shouldEvaluateCodexAppUiRepair = doctorFix || deepDiagnostics || flag(args, '--repair-codex-app-ui');
|
|
474
|
-
const shouldRunZellijRepair = deepDiagnostics || flag(args, '--repair-zellij') || flag(args, '--install-homebrew') || process.env.SKS_REQUIRE_ZELLIJ === '1';
|
|
475
947
|
const nativeCapabilityDiagnosticsRequested = deepDiagnostics || flag(args, '--repair-native-capabilities');
|
|
476
948
|
const requireLegacyGlobalHookCleanup = doctorFix && doctorProfile === 'migration';
|
|
477
949
|
const migrationReceiptOwnsReconcile = doctorFix && doctorProfile === 'migration';
|
|
@@ -482,7 +954,6 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
482
954
|
const { runDoctorContext7Repair } = await import('../core/doctor/doctor-context7-repair.js');
|
|
483
955
|
const { compareCodexDoctorBridge, runCodexDoctorBridge } = await import('../core/doctor/codex-doctor-bridge.js');
|
|
484
956
|
const { repairCodexAppFastUi } = await import('../core/codex-app/codex-app-fast-ui-repair.js');
|
|
485
|
-
const { runDoctorZellijRepair, doctorZellijRepairConsoleLine } = await import('../core/doctor/doctor-zellij-repair.js');
|
|
486
957
|
const { repairAgentRoleConfigs } = await import('../core/agents/agent-role-config.js');
|
|
487
958
|
const { runCodex0138Doctor } = await import('../core/doctor/codex-0138-doctor.js');
|
|
488
959
|
const { writeDoctorReadinessMatrix } = await import('../core/doctor/doctor-readiness-matrix.js');
|
|
@@ -630,29 +1101,54 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
630
1101
|
? await codexAppIntegrationStatus({ codex }).catch((err) => ({ ok: false, error: err.message }))
|
|
631
1102
|
: { ok: false, skipped: true, warnings: ['codex_app_optional_diagnostic_skipped'] };
|
|
632
1103
|
const codexLbCircuit = codexLbMetrics(await readCodexLbCircuit(root).catch(() => ({})));
|
|
633
|
-
const
|
|
634
|
-
? await codexLbStatus({
|
|
635
|
-
probeToolOutputRecovery: true,
|
|
636
|
-
allowUnverifiedToolOutputRecovery: codexLbToolOutputRecoveryOverrideAcknowledged({ args })
|
|
637
|
-
}).catch((err) => ({
|
|
638
|
-
selected: null,
|
|
639
|
-
provider_ready: false,
|
|
640
|
-
recovery_probe_failed: true,
|
|
641
|
-
tool_output_recovery: {
|
|
642
|
-
ok: false,
|
|
643
|
-
status: 'probe_failed',
|
|
644
|
-
blockers: ['codex_lb_tool_output_recovery_status_probe_failed'],
|
|
645
|
-
operator_actions: []
|
|
646
|
-
},
|
|
647
|
-
error: err?.message || String(err)
|
|
648
|
-
}))
|
|
1104
|
+
const codexLbPreRepairStatus = doctorFix
|
|
1105
|
+
? await codexLbStatus({ probeToolOutputRecovery: false }).catch(() => null)
|
|
649
1106
|
: null;
|
|
1107
|
+
const codexLbSecretProbe = await inspectDoctorCodexLbSecretResolution({
|
|
1108
|
+
processEnv: process.env,
|
|
1109
|
+
fix: doctorFix,
|
|
1110
|
+
forceRetry: flag(args, CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG),
|
|
1111
|
+
baseUrl: codexLbPreRepairStatus?.base_url || codexLbPreRepairStatus?.provider_base_url || null
|
|
1112
|
+
});
|
|
1113
|
+
const codexLbProviderStatus = await codexLbStatus({
|
|
1114
|
+
probeToolOutputRecovery: deepDiagnostics || doctorFix,
|
|
1115
|
+
allowUnverifiedToolOutputRecovery: codexLbToolOutputRecoveryOverrideAcknowledged({ args })
|
|
1116
|
+
}).catch((err) => ({
|
|
1117
|
+
selected: null,
|
|
1118
|
+
provider_ready: false,
|
|
1119
|
+
recovery_probe_failed: deepDiagnostics || doctorFix,
|
|
1120
|
+
tool_output_recovery: {
|
|
1121
|
+
ok: false,
|
|
1122
|
+
status: deepDiagnostics || doctorFix ? 'probe_failed' : 'not_checked',
|
|
1123
|
+
blockers: deepDiagnostics || doctorFix ? ['codex_lb_tool_output_recovery_status_probe_failed'] : [],
|
|
1124
|
+
operator_actions: []
|
|
1125
|
+
},
|
|
1126
|
+
error: err?.message || String(err)
|
|
1127
|
+
}));
|
|
650
1128
|
const codexLbRecoveryReady = codexLbRecoveryStatusReady(codexLbProviderStatus, deepDiagnostics || doctorFix);
|
|
1129
|
+
const codexLbRoutingTruth = await codexLbRoutingTruthForStatus(codexLbProviderStatus, {
|
|
1130
|
+
remeasure: deepDiagnostics || doctorFix
|
|
1131
|
+
});
|
|
1132
|
+
const codexLbRoutingReady = !doctorCodexLbRouteExpected(codexLbProviderStatus)
|
|
1133
|
+
|| codexLbRoutingTruthIsActive(codexLbRoutingTruth);
|
|
1134
|
+
const codexLbDivergence = await inspectDoctorCodexLbDivergence({
|
|
1135
|
+
processEnv: process.env,
|
|
1136
|
+
providerStatus: codexLbProviderStatus,
|
|
1137
|
+
fix: doctorFix,
|
|
1138
|
+
...(deps.codexLbLaunchctlBin ? { launchctlBin: deps.codexLbLaunchctlBin } : {}),
|
|
1139
|
+
...(deps.codexLbLaunchPlatform ? { platform: deps.codexLbLaunchPlatform } : {}),
|
|
1140
|
+
...(deps.codexLbLaunchRunProcessImpl ? { runProcessImpl: deps.codexLbLaunchRunProcessImpl } : {})
|
|
1141
|
+
}, deps.codexLbDivergenceDeps || {});
|
|
651
1142
|
const codexLb = {
|
|
652
1143
|
...codexLbCircuit,
|
|
653
1144
|
provider_status: codexLbProviderStatus,
|
|
654
1145
|
tool_output_recovery: codexLbProviderStatus?.tool_output_recovery || null,
|
|
655
|
-
recovery_ok: codexLbRecoveryReady
|
|
1146
|
+
recovery_ok: codexLbRecoveryReady,
|
|
1147
|
+
routing_truth: codexLbRoutingTruth,
|
|
1148
|
+
routing_ok: codexLbRoutingReady,
|
|
1149
|
+
secret_resolution: codexLbSecretProbe.secret_resolution,
|
|
1150
|
+
legacy_keychain_migration: codexLbSecretProbe.legacy_keychain_migration,
|
|
1151
|
+
divergence: codexLbDivergence
|
|
656
1152
|
};
|
|
657
1153
|
const providerContext = deepDiagnostics
|
|
658
1154
|
? await resolveProviderContext({ root, route: '$Doctor', serviceTier: process.env.SKS_SERVICE_TIER || 'fast' }).catch((err) => ({
|
|
@@ -756,42 +1252,12 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
756
1252
|
blockers: [err?.message || String(err)],
|
|
757
1253
|
warnings: []
|
|
758
1254
|
}));
|
|
759
|
-
const
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
auto_approved: flag(args, '--yes') || flag(args, '-y'),
|
|
766
|
-
install_homebrew_allowed: false,
|
|
767
|
-
before: { status: 'unknown', version: null, bin: null },
|
|
768
|
-
latest_version: null,
|
|
769
|
-
strategy: 'failed',
|
|
770
|
-
command: 'sks doctor --fix --yes',
|
|
771
|
-
after: { status: 'unknown', version: null, bin: null },
|
|
772
|
-
mutation_guard_artifact: null,
|
|
773
|
-
homebrew: { present: false, bin: null, install_attempted: false, install_allowed: false },
|
|
774
|
-
blockers: [err?.message || String(err)],
|
|
775
|
-
warnings: []
|
|
776
|
-
}))
|
|
777
|
-
: {
|
|
778
|
-
schema: 'sks.zellij-self-heal.v1',
|
|
779
|
-
ok: true,
|
|
780
|
-
skipped: true,
|
|
781
|
-
requested_by: 'doctor --fix',
|
|
782
|
-
fix_requested: doctorFix,
|
|
783
|
-
auto_approved: false,
|
|
784
|
-
install_homebrew_allowed: false,
|
|
785
|
-
before: { status: 'skipped', version: null, bin: null },
|
|
786
|
-
latest_version: null,
|
|
787
|
-
strategy: 'deferred',
|
|
788
|
-
command: 'sks doctor --fix --full --yes',
|
|
789
|
-
after: { status: 'skipped', version: null, bin: null },
|
|
790
|
-
mutation_guard_artifact: null,
|
|
791
|
-
homebrew: { present: false, bin: null, install_attempted: false, install_allowed: false },
|
|
792
|
-
blockers: [],
|
|
793
|
-
warnings: ['zellij_repair_deferred_to_full_doctor_or_route_gate']
|
|
794
|
-
};
|
|
1255
|
+
const telegramRemote = await inspectTelegramRemote({
|
|
1256
|
+
live: deepDiagnostics || doctorFix,
|
|
1257
|
+
fix: doctorFix,
|
|
1258
|
+
root,
|
|
1259
|
+
env: process.env
|
|
1260
|
+
}, deps);
|
|
795
1261
|
const context7Repair = await runDoctorContext7Repair({ root, fix: doctorFix }).catch((err) => ({
|
|
796
1262
|
schema: 'sks.doctor-context7-repair.v1',
|
|
797
1263
|
ok: false,
|
|
@@ -968,14 +1434,34 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
968
1434
|
rollback_evidence: sksMenuBar?.launch_agent_path || sksMenuBar?.report_path || 'sks_menubar_optional_no_core_mutation'
|
|
969
1435
|
}),
|
|
970
1436
|
postcheck: async () => {
|
|
971
|
-
const
|
|
1437
|
+
const inspectMenuBarStatusImpl = deps.inspectSksMenuBarStatusImpl || inspectSksMenuBarStatus;
|
|
1438
|
+
const status = await inspectMenuBarStatusImpl({ root }).catch((err) => ({
|
|
972
1439
|
ok: false,
|
|
973
1440
|
launchd: { ok: false, state: null, pid: null, error: err?.message || String(err) },
|
|
974
1441
|
action_target: { ok: false, smoke_code: null, smoke_output: null },
|
|
975
1442
|
blockers: [err?.message || String(err)],
|
|
976
1443
|
warnings: []
|
|
977
1444
|
}));
|
|
978
|
-
|
|
1445
|
+
const launchdRepair = await rebootstrapSksMenuBarLaunchdForDoctorFix({
|
|
1446
|
+
fix: doctorFix,
|
|
1447
|
+
root,
|
|
1448
|
+
env: process.env,
|
|
1449
|
+
status
|
|
1450
|
+
}, {
|
|
1451
|
+
inspectSksMenuBarStatusImpl: inspectMenuBarStatusImpl,
|
|
1452
|
+
restartLaunchAgentImpl: deps.restartLaunchAgentImpl
|
|
1453
|
+
});
|
|
1454
|
+
const postcheck = buildSksMenuBarDoctorPostcheck(launchdRepair.status);
|
|
1455
|
+
return launchdRepair.attempted
|
|
1456
|
+
? {
|
|
1457
|
+
...postcheck,
|
|
1458
|
+
repaired: launchdRepair.ok,
|
|
1459
|
+
warnings: [
|
|
1460
|
+
...(postcheck.warnings || []),
|
|
1461
|
+
launchdRepair.ok ? 'launchd_rebootstrap_recovered' : 'launchd_rebootstrap_failed'
|
|
1462
|
+
]
|
|
1463
|
+
}
|
|
1464
|
+
: postcheck;
|
|
979
1465
|
}
|
|
980
1466
|
},
|
|
981
1467
|
{
|
|
@@ -1029,7 +1515,6 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1029
1515
|
}))
|
|
1030
1516
|
: null;
|
|
1031
1517
|
const doctorFixPostcheck = doctorFix ? (await import('../core/doctor/doctor-repair-postcheck.js')).doctorRepairPostcheck(doctorFixTransaction) : null;
|
|
1032
|
-
const zellij = await checkZellijCapability({ root, require: process.env.SKS_REQUIRE_ZELLIJ === '1' });
|
|
1033
1518
|
const localModel = await readLocalModelConfig().catch(() => null);
|
|
1034
1519
|
const permissionProfiles = await inventoryCodexPermissionProfiles(root, { writeReport: true });
|
|
1035
1520
|
const startupRoleRepair = startupConfigRepair?.role_repair;
|
|
@@ -1265,7 +1750,6 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1265
1750
|
pre_repair_codex_doctor: preRepairCodexDoctor,
|
|
1266
1751
|
post_repair_codex_doctor: postRepairCodexDoctor,
|
|
1267
1752
|
require_codex_doctor: deepDiagnostics || flag(args, '--require-actual-codex'),
|
|
1268
|
-
zellij,
|
|
1269
1753
|
context7_repair: context7Repair,
|
|
1270
1754
|
codex_startup_repair: codexStartupRepair,
|
|
1271
1755
|
startup_config_repair: startupConfigRepair,
|
|
@@ -1284,6 +1768,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1284
1768
|
repair: configRepair,
|
|
1285
1769
|
codex_app_ui: codexAppUi,
|
|
1286
1770
|
sks_menubar: sksMenuBar,
|
|
1771
|
+
telegram_remote: telegramRemote,
|
|
1287
1772
|
codex_0138_doctor: codex0138Doctor,
|
|
1288
1773
|
codex_plugin_inventory: pluginInventory?.report || null,
|
|
1289
1774
|
codex_plugin_app_template_policy: pluginPolicy,
|
|
@@ -1292,19 +1777,15 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1292
1777
|
operator_actions: [
|
|
1293
1778
|
...(codexConfig.operator_actions || []),
|
|
1294
1779
|
...(configRepair?.operator_actions || []),
|
|
1295
|
-
...(zellijRepair && !zellijRepair.ok && zellijRepair.command ? [`Run: ${zellijRepair.command}`] : []),
|
|
1296
1780
|
...(codexStartupRepair.manual_actions || []),
|
|
1297
1781
|
...(codexConfigSyntaxRepair?.manual_actions || []),
|
|
1298
|
-
...(pluginPolicy?.doctor_warnings || [])
|
|
1782
|
+
...(pluginPolicy?.doctor_warnings || []),
|
|
1783
|
+
...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
|
|
1784
|
+
...telegramDoctorOperatorActions(telegramRemote)
|
|
1299
1785
|
]
|
|
1300
1786
|
};
|
|
1301
1787
|
let ready = await writeDoctorReadinessMatrix(root, doctorReadinessInput);
|
|
1302
1788
|
if (doctorFix) {
|
|
1303
|
-
if (migrationReceiptOwnsReconcile) {
|
|
1304
|
-
commandAliasCleanup = await inspectCommandAliasCleanup(false);
|
|
1305
|
-
doctorReadinessInput.command_aliases = commandAliasCleanup;
|
|
1306
|
-
ready = await writeDoctorReadinessMatrix(root, doctorReadinessInput);
|
|
1307
|
-
}
|
|
1308
1789
|
const readinessBlockers = [
|
|
1309
1790
|
...(Array.isArray(ready.blockers) ? ready.blockers.map(String).filter(Boolean) : []),
|
|
1310
1791
|
...(openRouterProviderRepair?.ok === false
|
|
@@ -1316,6 +1797,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1316
1797
|
&& readinessBlockers.every(isMigrationUserOwnedProjectConfigBlocker);
|
|
1317
1798
|
const receiptBlockers = preservedUserOwnedConfig ? [] : readinessBlockers;
|
|
1318
1799
|
const migrationWarnings = [
|
|
1800
|
+
...(commandAliasCleanup?.warnings || []),
|
|
1319
1801
|
...(doctorNativeCapabilityRepair?.optional_warnings || []),
|
|
1320
1802
|
...(doctorFixPostcheck?.optional_warnings || []),
|
|
1321
1803
|
...(preservedUserOwnedConfig
|
|
@@ -1334,6 +1816,21 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1334
1816
|
};
|
|
1335
1817
|
if (receiptBlockers.length)
|
|
1336
1818
|
receiptInput.status = 'blocked';
|
|
1819
|
+
if (migrationReceiptOwnsReconcile) {
|
|
1820
|
+
receiptInput.postMigrationStageCheck = async () => {
|
|
1821
|
+
commandAliasCleanup = await inspectCommandAliasCleanup(false);
|
|
1822
|
+
doctorReadinessInput.command_aliases = commandAliasCleanup;
|
|
1823
|
+
ready = await writeDoctorReadinessMatrix(root, doctorReadinessInput);
|
|
1824
|
+
return {
|
|
1825
|
+
blockers: Array.isArray(commandAliasCleanup?.blockers)
|
|
1826
|
+
? commandAliasCleanup.blockers.map(String).filter(Boolean)
|
|
1827
|
+
: [],
|
|
1828
|
+
warnings: Array.isArray(commandAliasCleanup?.warnings)
|
|
1829
|
+
? commandAliasCleanup.warnings.map(String).filter(Boolean)
|
|
1830
|
+
: []
|
|
1831
|
+
};
|
|
1832
|
+
};
|
|
1833
|
+
}
|
|
1337
1834
|
const receipt = await writeProjectUpdateMigrationReceipt(receiptInput);
|
|
1338
1835
|
sksUpdate = {
|
|
1339
1836
|
schema: 'sks.update-now.v2',
|
|
@@ -1361,8 +1858,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1361
1858
|
};
|
|
1362
1859
|
}
|
|
1363
1860
|
}
|
|
1364
|
-
const
|
|
1365
|
-
const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
|
|
1861
|
+
const runtimeReadiness = buildRuntimeReadiness(codexNativeFeatureMatrix);
|
|
1366
1862
|
const resultOk = ready.ready
|
|
1367
1863
|
&& (!sksUpdate || sksUpdate.ok !== false)
|
|
1368
1864
|
&& commandAliasCleanup.ok !== false
|
|
@@ -1371,7 +1867,10 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1371
1867
|
&& agentRoleConfigRepair.ok !== false
|
|
1372
1868
|
&& openRouterProviderRepair.ok !== false
|
|
1373
1869
|
&& (officialSubagentConfig.blockers || []).length === 0
|
|
1374
|
-
&&
|
|
1870
|
+
&& codexLbSecretProbe.ok !== false
|
|
1871
|
+
&& codexLbDivergence.ok !== false
|
|
1872
|
+
&& codexLbRecoveryReady
|
|
1873
|
+
&& codexLbRoutingReady;
|
|
1375
1874
|
const result = {
|
|
1376
1875
|
schema: 'sks.doctor-status.v3',
|
|
1377
1876
|
elapsed_ms: Date.now() - startedAtMs,
|
|
@@ -1386,8 +1885,12 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1386
1885
|
not_counted_as_full_doctor: !deepDiagnostics,
|
|
1387
1886
|
root,
|
|
1388
1887
|
arg_warnings: argWarnings,
|
|
1389
|
-
warnings: [...oauthCallbackPortDiagnostic.warnings],
|
|
1390
|
-
operator_actions:
|
|
1888
|
+
warnings: [...oauthCallbackPortDiagnostic.warnings, ...(codexLbDivergence.warnings || [])],
|
|
1889
|
+
operator_actions: [
|
|
1890
|
+
...oauthCallbackOperatorActions,
|
|
1891
|
+
...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
|
|
1892
|
+
...(codexLbDivergence.operator_actions || [])
|
|
1893
|
+
],
|
|
1391
1894
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
1392
1895
|
codex,
|
|
1393
1896
|
oauth_callback_port_diagnostic: oauthCallbackPortDiagnostic,
|
|
@@ -1397,6 +1900,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1397
1900
|
codex_app_ui: codexAppUi,
|
|
1398
1901
|
openrouter_provider: openRouterProviderRepair,
|
|
1399
1902
|
sks_menubar: sksMenuBar,
|
|
1903
|
+
telegram_remote: telegramRemote,
|
|
1400
1904
|
provider_context: providerContext,
|
|
1401
1905
|
codex_lb: codexLb,
|
|
1402
1906
|
codex_doctor: authoritativeCodexDoctor,
|
|
@@ -1404,8 +1908,6 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1404
1908
|
post_repair_codex_doctor: postRepairCodexDoctor,
|
|
1405
1909
|
codex_doctor_diff: codexDoctorAuthoritativeDiff,
|
|
1406
1910
|
observational_codex_doctor_diff: codexDoctorDiff,
|
|
1407
|
-
zellij,
|
|
1408
|
-
zellij_repair: zellijRepair,
|
|
1409
1911
|
context7_repair: context7Repair,
|
|
1410
1912
|
codex_startup_repair: codexStartupRepair,
|
|
1411
1913
|
startup_config_repair: startupConfigRepair,
|
|
@@ -1423,7 +1925,6 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1423
1925
|
local_model: localModel,
|
|
1424
1926
|
agent_role_config: agentRoleConfigRepair,
|
|
1425
1927
|
official_subagent_config: officialSubagentConfig,
|
|
1426
|
-
zellij_readiness: zellijReadiness,
|
|
1427
1928
|
codex_permission_profiles: permissionProfiles,
|
|
1428
1929
|
command_aliases: commandAliasCleanup,
|
|
1429
1930
|
sks_temp_sweep: {
|
|
@@ -1457,7 +1958,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1457
1958
|
sneakoscope: { ok: await exists(`${root}/.sneakoscope`) },
|
|
1458
1959
|
package: { bytes: pkgBytes, human: formatBytes(pkgBytes) },
|
|
1459
1960
|
skills: skillsReconcile,
|
|
1460
|
-
repair: { sks_update: sksUpdate, setup: setupRepair, openrouter_provider: openRouterProviderRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup, agent_role_config: agentRoleConfigRepair,
|
|
1961
|
+
repair: { sks_update: sksUpdate, setup: setupRepair, openrouter_provider: openRouterProviderRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup, agent_role_config: agentRoleConfigRepair, context7: context7Repair, codex_startup: codexStartupRepair, startup_config: startupConfigRepair, context7_mcp: context7McpRepair, supabase_mcp: supabaseMcpRepair, mcp_transport_collision: mcpTransportCollisionRepair, imagegen: imagegenRepair, computer_use: computerUseRepair, browser_use: browserUseRepair, hook_trust: hookTrustRepair, sks_menubar: sksMenuBar, doctor_transaction: doctorFixTransaction, doctor_dirty_plan: doctorDirtyPlan, doctor_postcheck: doctorFixPostcheck, codex_native: codexNativeRepair, doctor_native_capability: doctorNativeCapabilityRepair, command_aliases: commandAliasCleanup, skills: skillsReconcile, sks_temp_sweep: sksTempSweep }
|
|
1461
1962
|
};
|
|
1462
1963
|
if (reportFile)
|
|
1463
1964
|
await writeJsonReportFile(reportFile, result);
|
|
@@ -1492,15 +1993,6 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1492
1993
|
console.log('Project config:');
|
|
1493
1994
|
console.log(` node read: ${ready.codex_config_readable_by_node ? 'ok' : 'failed'}`);
|
|
1494
1995
|
console.log(` codex cli read: ${ready.codex_config_readable_by_codex_cli ? 'ok' : (actual?.status || 'failed')}`);
|
|
1495
|
-
console.log('Zellij:');
|
|
1496
|
-
console.log(` binary: ${zellijReadiness.binary} ${zellijReadiness.version || ''} ${zellijReadiness.status === 'ok' ? 'ok' : zellijReadiness.status}`);
|
|
1497
|
-
console.log(` required_for: ${zellijReadiness.required_for.join(', ')}`);
|
|
1498
|
-
console.log(` layout: ${zellijReadiness.layout_proof}`);
|
|
1499
|
-
console.log(` pane proof: ${zellijReadiness.pane_proof}`);
|
|
1500
|
-
console.log(` screen proof:${zellijReadiness.screen_proof}`);
|
|
1501
|
-
const zellijRepairLine = doctorZellijRepairConsoleLine(zellijRepair);
|
|
1502
|
-
if (zellijRepairLine)
|
|
1503
|
-
console.log(zellijRepairLine);
|
|
1504
1996
|
console.log('Context7 MCP:');
|
|
1505
1997
|
console.log(` transport: ${context7Repair.preferred_transport || 'remote'}`);
|
|
1506
1998
|
console.log(` repair: ${context7Repair.ok ? 'ok' : 'blocked'}`);
|
|
@@ -1530,7 +2022,6 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1530
2022
|
console.log(`Rust acc.: ${rust.mode || (rust.available ? 'rust_accelerated' : 'js_fallback')} ${rust.version || rust.status || ''}`);
|
|
1531
2023
|
console.log(`Codex App: ${ready.codex_app_ready ? 'ok' : 'optional_missing'}`);
|
|
1532
2024
|
console.log('SKS Runtime Readiness:');
|
|
1533
|
-
console.log(` Zellij: ${runtimeReadiness.zellij}`);
|
|
1534
2025
|
console.log(` Codex Native: ${runtimeReadiness.codex_native}`);
|
|
1535
2026
|
console.log(` Loop Mesh: ${runtimeReadiness.loop_mesh}`);
|
|
1536
2027
|
console.log(` QA Visual: ${runtimeReadiness.qa_visual}`);
|
|
@@ -1607,6 +2098,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1607
2098
|
console.log(` next action: ${codexAppUi.next_action}`);
|
|
1608
2099
|
console.log('SKS Menu Bar:');
|
|
1609
2100
|
console.log(` status: ${sksMenuBar.status || (sksMenuBar.ok ? 'ok' : 'blocked')}`);
|
|
2101
|
+
for (const line of sksMenuBarRunningVersionConsoleLines(sksMenuBar))
|
|
2102
|
+
console.log(line);
|
|
1610
2103
|
const menubarPhase = doctorFixTransaction?.phases?.find((phase) => phase?.id === 'sks_menubar');
|
|
1611
2104
|
if (menubarPhase) {
|
|
1612
2105
|
const menubarSummary = menubarPhase.ok
|
|
@@ -1622,6 +2115,21 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1622
2115
|
console.log(` blockers: ${sksMenuBar.blockers.join(', ')}`);
|
|
1623
2116
|
if (Array.isArray(sksMenuBar.warnings) && sksMenuBar.warnings.length)
|
|
1624
2117
|
console.log(` warnings: ${sksMenuBar.warnings.join(', ')}`);
|
|
2118
|
+
console.log('Telegram Remote:');
|
|
2119
|
+
console.log(` status: ${telegramRemote.status || 'unknown'}`);
|
|
2120
|
+
console.log(` getMe: ${telegramRemote.bot_identity_valid ? 'verified' : telegramRemote.token_configured ? 'invalid' : 'not configured'}`);
|
|
2121
|
+
console.log(` audit: ${telegramRemote.audit_healthy ? 'healthy' : 'unavailable'}`);
|
|
2122
|
+
const telegramCheckedLine = telegramDoctorCheckedLine(telegramRemote, ' ');
|
|
2123
|
+
if (telegramCheckedLine)
|
|
2124
|
+
console.log(telegramCheckedLine);
|
|
2125
|
+
console.log(` long poll: ${telegramRemote.poller?.running ? 'running' : 'stopped'}`);
|
|
2126
|
+
const telegramSelfHealOutcome = telegramRemote.self_heal_outcome;
|
|
2127
|
+
const telegramDisplayedAction = telegramSelfHealOutcome?.attempted
|
|
2128
|
+
? telegramSelfHealOutcome.action
|
|
2129
|
+
: telegramRemote.self_heal_action;
|
|
2130
|
+
if (telegramDisplayedAction && telegramDisplayedAction !== 'none') {
|
|
2131
|
+
console.log(` self-heal: ${telegramDisplayedAction}${telegramSelfHealOutcome?.attempted ? ` (${telegramSelfHealOutcome.recovered ? 'recovered' : 'attempted, still degraded'})` : ''}`);
|
|
2132
|
+
}
|
|
1625
2133
|
console.log(`Provider: ${providerContext.provider || 'unknown'} ${providerContext.service_tier || ''} (${providerContext.source || 'unknown'}, ${providerContext.confidence || 'low'})`);
|
|
1626
2134
|
const imagegenReady = imagegen.auth_readiness;
|
|
1627
2135
|
if (imagegenReady) {
|
|
@@ -1674,6 +2182,17 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1674
2182
|
if (codex0138Doctor?.fixed?.length)
|
|
1675
2183
|
console.log(` doctor --fix repaired: ${codex0138Doctor.fixed.join(', ')}`);
|
|
1676
2184
|
console.log(`codex-lb: ${codexLb.ok ? 'ok' : `warning ${codexLb.circuit?.state || 'unknown'}`}`);
|
|
2185
|
+
console.log(` key source: ${codexLb.secret_resolution.source}${codexLb.secret_resolution.path ? ` (${codexLb.secret_resolution.path})` : ''}; prompt risk: ${codexLb.secret_resolution.prompt_risk}`);
|
|
2186
|
+
for (const action of codexLb.legacy_keychain_migration?.operator_actions || [])
|
|
2187
|
+
console.log(` action: ${action}`);
|
|
2188
|
+
for (const warning of codexLb.divergence?.warnings || [])
|
|
2189
|
+
console.log(` warning: ${warning}`);
|
|
2190
|
+
for (const action of codexLb.divergence?.operator_actions || [])
|
|
2191
|
+
console.log(` action: ${action}`);
|
|
2192
|
+
if (codexLb.routing_truth) {
|
|
2193
|
+
const routingTruth = codexLb.routing_truth;
|
|
2194
|
+
console.log(` routing truth: ${codexLb.routing_ok ? 'verified' : 'blocked'} (${routingTruth.actual_host || routingTruth.configured_host || 'host unavailable'}, ${routingTruth.auth_outcome}, ${routingTruth.latency_ms ?? 'unmeasured'} ms at ${routingTruth.checked_at})`);
|
|
2195
|
+
}
|
|
1677
2196
|
if (codexLb.tool_output_recovery) {
|
|
1678
2197
|
const recovery = codexLb.tool_output_recovery;
|
|
1679
2198
|
console.log(` interrupted tool-output recovery: ${recovery.ok ? 'ready' : 'blocked'} (${recovery.observed_version || recovery.status}; minimum ${recovery.minimum_version})`);
|
|
@@ -1727,31 +2246,27 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1727
2246
|
if (!result.ok)
|
|
1728
2247
|
process.exitCode = 1;
|
|
1729
2248
|
}
|
|
1730
|
-
function buildRuntimeReadiness(
|
|
2249
|
+
export function buildRuntimeReadiness(matrix) {
|
|
1731
2250
|
const defaults = matrix?.invocation_defaults || {};
|
|
1732
2251
|
const hookPolicy = defaults.hook_evidence_policy || 'unknown-do-not-count';
|
|
1733
2252
|
const agentStrategy = defaults.loop_worker_role_strategy || 'message-role';
|
|
1734
2253
|
const multiAgentMode = defaults.multi_agent_mode || 'none';
|
|
1735
2254
|
const rolloutBudget = defaults.rollout_budget_strategy || 'sks-local-only';
|
|
1736
2255
|
const researchSource = defaults.research_source_strategy || 'local-files';
|
|
1737
|
-
const
|
|
1738
|
-
? 'ok'
|
|
1739
|
-
: zellijReadiness?.cli_ready ? 'headless_available' : 'repair_required';
|
|
1740
|
-
const codexNative = matrix?.ok === true
|
|
1741
|
-
? 'ok'
|
|
1742
|
-
: matrix?.codex_cli?.available ? 'degraded' : 'blocked';
|
|
2256
|
+
const codexNative = matrix?.ok === true ? 'ok' : matrix?.codex_cli?.available ? 'degraded' : 'blocked';
|
|
1743
2257
|
const repairActions = [];
|
|
1744
|
-
if (
|
|
1745
|
-
repairActions.push(
|
|
1746
|
-
|
|
2258
|
+
if (codexNative !== 'ok') {
|
|
2259
|
+
repairActions.push([
|
|
2260
|
+
'Codex Native managed assets: sks doctor',
|
|
2261
|
+
'--fix',
|
|
2262
|
+
'--repair-codex-native',
|
|
2263
|
+
'--yes'
|
|
2264
|
+
].join(' '));
|
|
1747
2265
|
}
|
|
1748
|
-
if (codexNative !== 'ok')
|
|
1749
|
-
repairActions.push('Codex Native managed assets: sks doctor --fix --repair-codex-native --yes');
|
|
1750
2266
|
if (matrix?.features?.project_memory?.ok !== true)
|
|
1751
2267
|
repairActions.push('Project memory: sks codex-native init-deep --apply --directory-local');
|
|
1752
2268
|
return {
|
|
1753
2269
|
schema: 'sks.runtime-readiness-story.v1',
|
|
1754
|
-
zellij: zellijStatus,
|
|
1755
2270
|
codex_native: codexNative,
|
|
1756
2271
|
loop_mesh: agentStrategy === 'agent_type' ? 'ok' : 'fallback',
|
|
1757
2272
|
qa_visual: defaults.qa_visual_review_strategy || 'blocked',
|
|
@@ -1764,12 +2279,11 @@ function buildRuntimeReadiness(zellijReadiness, matrix) {
|
|
|
1764
2279
|
current_time_source: defaults.current_time_source || 'external-clock',
|
|
1765
2280
|
overload_retry_policy: defaults.overload_retry_policy || 'generic',
|
|
1766
2281
|
notes: [
|
|
1767
|
-
...(zellijStatus === 'headless_available' ? ['MAD can run with --headless; live panes require repair'] : []),
|
|
1768
2282
|
...(hookPolicy !== 'approved-only' ? ['hook-derived evidence will not count'] : []),
|
|
1769
2283
|
...(agentStrategy !== 'agent_type' ? ['message-role fallback active'] : []),
|
|
1770
|
-
...(multiAgentMode === 'proactive' ? [
|
|
1771
|
-
...(rolloutBudget === 'codex-0144-shared' ? [
|
|
1772
|
-
...(researchSource === 'indexed-web-search' ? [
|
|
2284
|
+
...(multiAgentMode === 'proactive' ? ['Proactive multi-agent mode is available for Naruto-style routes'] : []),
|
|
2285
|
+
...(rolloutBudget === 'codex-0144-shared' ? ['Shared rollout budgeting is available for route proof'] : []),
|
|
2286
|
+
...(researchSource === 'indexed-web-search' ? ['Indexed web search is selected for source-intelligence routes'] : [])
|
|
1773
2287
|
],
|
|
1774
2288
|
repair_actions: [...new Set(repairActions)]
|
|
1775
2289
|
};
|
|
@@ -1865,26 +2379,6 @@ function doctorDedupeStatus(skillDedupe) {
|
|
|
1865
2379
|
return 'manual_required';
|
|
1866
2380
|
return 'none';
|
|
1867
2381
|
}
|
|
1868
|
-
function buildZellijReadiness(root, zellij, ready) {
|
|
1869
|
-
const status = String(zellij?.status || 'missing');
|
|
1870
|
-
const usable = status === 'ok';
|
|
1871
|
-
const proofStatus = usable ? 'optional' : 'unavailable';
|
|
1872
|
-
const readiness = {
|
|
1873
|
-
schema: 'sks.zellij-readiness.v1',
|
|
1874
|
-
binary: zellij?.bin || 'zellij',
|
|
1875
|
-
status,
|
|
1876
|
-
min_version: zellij?.min_version || '0.41.0',
|
|
1877
|
-
version: zellij?.version || null,
|
|
1878
|
-
required_for: zellij?.required_for || ['sks --mad', 'interactive lane UI'],
|
|
1879
|
-
layout_proof: proofStatus,
|
|
1880
|
-
pane_proof: proofStatus,
|
|
1881
|
-
screen_proof: proofStatus,
|
|
1882
|
-
mad_ready: ready?.mad_ready === true,
|
|
1883
|
-
cli_ready: ready?.cli_ready === true,
|
|
1884
|
-
ready_for_interactive_runtime: ready?.codex_config_readable_in_zellij_context === true
|
|
1885
|
-
};
|
|
1886
|
-
return readiness;
|
|
1887
|
-
}
|
|
1888
2382
|
async function codexHomeConfigPath() {
|
|
1889
2383
|
const path = await import('node:path');
|
|
1890
2384
|
const os = await import('node:os');
|
|
@@ -2011,6 +2505,95 @@ export function formatCodexDoctorConsoleStatus(report) {
|
|
|
2011
2505
|
return 'unavailable';
|
|
2012
2506
|
return report.disposition || (report.exit_code === 0 ? 'pass' : 'warn');
|
|
2013
2507
|
}
|
|
2508
|
+
export function sksMenuBarRunningVersionConsoleLines(status) {
|
|
2509
|
+
const runningVersion = status?.running_process?.package_version
|
|
2510
|
+
|| status?.menubar_version_probe?.running_version
|
|
2511
|
+
|| null;
|
|
2512
|
+
const runningPid = status?.running_process?.pid ?? status?.menubar_version_probe?.pid ?? null;
|
|
2513
|
+
if (typeof runningVersion !== 'string' || !runningVersion || !Number.isInteger(runningPid) || runningPid <= 0) {
|
|
2514
|
+
return [];
|
|
2515
|
+
}
|
|
2516
|
+
const expectedVersion = status?.menubar_version_probe?.expected_version
|
|
2517
|
+
|| status?.action_target?.expected_version
|
|
2518
|
+
|| status?.package_version
|
|
2519
|
+
|| null;
|
|
2520
|
+
const installedVersion = status?.installed_version || status?.build_stamp?.package_version || null;
|
|
2521
|
+
return [
|
|
2522
|
+
` RUNNING: version ${runningVersion} (PID ${runningPid})`,
|
|
2523
|
+
...(typeof expectedVersion === 'string' && expectedVersion && expectedVersion !== runningVersion
|
|
2524
|
+
? [` expected: version ${expectedVersion}`]
|
|
2525
|
+
: []),
|
|
2526
|
+
...(typeof installedVersion === 'string' && installedVersion && installedVersion !== runningVersion
|
|
2527
|
+
? [` installed: version ${installedVersion}`]
|
|
2528
|
+
: [])
|
|
2529
|
+
];
|
|
2530
|
+
}
|
|
2531
|
+
export async function rebootstrapSksMenuBarLaunchdForDoctorFix(input, deps = {}) {
|
|
2532
|
+
const env = input.env || process.env;
|
|
2533
|
+
const status = input.status;
|
|
2534
|
+
const expectedVersion = status?.menubar_version_probe?.expected_version
|
|
2535
|
+
|| status?.action_target?.expected_version
|
|
2536
|
+
|| status?.installed_version
|
|
2537
|
+
|| null;
|
|
2538
|
+
const warningOnlyVerifiedProcess = input.fix
|
|
2539
|
+
&& !sksMenuBarRestartDeferred(env)
|
|
2540
|
+
&& status?.launchd?.checked === true
|
|
2541
|
+
&& status?.launchd?.ok === false
|
|
2542
|
+
&& Array.isArray(status?.warnings)
|
|
2543
|
+
&& status.warnings.includes('launchd_not_running_process_active')
|
|
2544
|
+
&& !(Array.isArray(status?.blockers) && status.blockers.includes('launchd_not_running'))
|
|
2545
|
+
&& status?.running_process?.ok === true
|
|
2546
|
+
&& typeof expectedVersion === 'string'
|
|
2547
|
+
&& status.running_process.package_version === expectedVersion;
|
|
2548
|
+
if (!warningOnlyVerifiedProcess) {
|
|
2549
|
+
return { attempted: false, ok: true, status, restart: null };
|
|
2550
|
+
}
|
|
2551
|
+
const paths = sksMenuBarPaths(input.home || env.HOME, input.root);
|
|
2552
|
+
const restartImpl = deps.restartLaunchAgentImpl || restartLaunchAgent;
|
|
2553
|
+
const inspectImpl = deps.inspectSksMenuBarStatusImpl || inspectSksMenuBarStatus;
|
|
2554
|
+
const restart = await restartImpl(paths, env).catch((error) => ({
|
|
2555
|
+
ok: false,
|
|
2556
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2557
|
+
}));
|
|
2558
|
+
if (restart?.ok !== true) {
|
|
2559
|
+
const detail = restart?.error ? `:${restart.error}` : '';
|
|
2560
|
+
return {
|
|
2561
|
+
attempted: true,
|
|
2562
|
+
ok: false,
|
|
2563
|
+
restart,
|
|
2564
|
+
status: {
|
|
2565
|
+
...status,
|
|
2566
|
+
ok: false,
|
|
2567
|
+
blockers: [...new Set([...(status?.blockers || []), `launchd_rebootstrap_failed${detail}`])]
|
|
2568
|
+
}
|
|
2569
|
+
};
|
|
2570
|
+
}
|
|
2571
|
+
const refreshed = await inspectImpl({
|
|
2572
|
+
root: input.root,
|
|
2573
|
+
...(input.home ? { home: input.home } : {}),
|
|
2574
|
+
...(input.env ? { env: input.env } : {})
|
|
2575
|
+
}).catch((error) => ({
|
|
2576
|
+
...status,
|
|
2577
|
+
ok: false,
|
|
2578
|
+
blockers: [...new Set([
|
|
2579
|
+
...(status?.blockers || []),
|
|
2580
|
+
`launchd_rebootstrap_status_failed:${error instanceof Error ? error.message : String(error)}`
|
|
2581
|
+
])]
|
|
2582
|
+
}));
|
|
2583
|
+
if (refreshed?.launchd?.checked !== true || refreshed?.launchd?.ok !== true) {
|
|
2584
|
+
return {
|
|
2585
|
+
attempted: true,
|
|
2586
|
+
ok: false,
|
|
2587
|
+
restart,
|
|
2588
|
+
status: {
|
|
2589
|
+
...refreshed,
|
|
2590
|
+
ok: false,
|
|
2591
|
+
blockers: [...new Set([...(refreshed?.blockers || []), 'launchd_rebootstrap_not_confirmed'])]
|
|
2592
|
+
}
|
|
2593
|
+
};
|
|
2594
|
+
}
|
|
2595
|
+
return { attempted: true, ok: true, status: refreshed, restart };
|
|
2596
|
+
}
|
|
2014
2597
|
function mergeObservedCodexStartupWarnings(startupRepair, codexDoctor) {
|
|
2015
2598
|
const text = `${codexDoctor?.stdout_tail || ''}\n${codexDoctor?.stderr_tail || ''}`;
|
|
2016
2599
|
const manual = new Set(Array.isArray(startupRepair?.manual_actions) ? startupRepair.manual_actions : []);
|