sneakoscope 8.1.2 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -58
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +5 -51
- package/dist/cli/command-manifest-lite.js +2 -1
- package/dist/cli/command-registry.js +2 -1
- package/dist/cli/global-mode-router.js +1 -1
- package/dist/cli/install-helpers-codex-lb-config.js +112 -914
- package/dist/cli/install-helpers-codex-lb-shared.js +3 -44
- package/dist/cli/install-helpers-install-support.js +4 -20
- package/dist/cli/install-helpers.js +36 -2716
- package/dist/cli/router.js +9 -9
- package/dist/commands/bridge-command-output.js +111 -0
- package/dist/commands/bridge.js +320 -0
- package/dist/commands/codex-app.js +39 -123
- package/dist/commands/doctor-helpers.js +380 -0
- package/dist/commands/doctor-profile.js +3 -0
- package/dist/commands/doctor.js +114 -873
- package/dist/commands/mad-sks.js +0 -4
- package/dist/config/skills-manifest.json +1 -1
- package/dist/core/agents/agent-effort-policy.js +11 -21
- package/dist/core/agents/agent-recursion-guard.js +26 -0
- package/dist/core/agents/agent-runner-codex-exec.js +7 -9
- package/dist/core/architecture-hardening/contracts/contracts.js +225 -161
- package/dist/core/architecture-hardening/state/state-service.js +49 -13
- package/dist/core/auto-review.js +15 -9
- package/dist/core/codex/codex-config-guard.js +8 -0
- package/dist/core/codex-adapter.js +8 -10
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -29
- package/dist/core/codex-app/codex-app-launcher.js +10 -12
- package/dist/core/codex-app/codex-app-restart.js +10 -12
- package/dist/core/codex-app/menubar/constants.js +2 -5
- package/dist/core/codex-app/menubar/global-install.js +3 -2
- package/dist/core/codex-app/menubar/installer/result.js +23 -0
- package/dist/core/codex-app/menubar/installer/runtime.js +28 -0
- package/dist/core/codex-app/menubar/installer.js +5 -96
- package/dist/core/codex-app/menubar/migration.js +1 -42
- package/dist/core/codex-app/openrouter-provider.js +0 -78
- package/dist/core/codex-app.js +97 -360
- package/dist/core/codex-control/codex-app-server-runtime-env.js +8 -28
- package/dist/core/codex-control/codex-current-image-path-real-probe.js +2 -3
- package/dist/core/codex-control/codex-current-web-search-probe.js +2 -3
- package/dist/core/codex-control/codex-sdk-adapter.js +5 -48
- package/dist/core/codex-control/codex-task-runner.js +16 -60
- package/dist/core/codex-control/desktop-bridge-launch-guard.js +227 -0
- package/dist/core/codex-exec-output-schema.js +11 -13
- package/dist/core/codex-lb/bridge-contracts.js +2 -0
- package/dist/core/codex-lb/bridge-runtime-validation/capability.js +104 -0
- package/dist/core/codex-lb/bridge-runtime-validation/catalog.js +52 -0
- package/dist/core/codex-lb/bridge-runtime-validation/shared.js +109 -0
- package/dist/core/codex-lb/bridge-runtime-validation/status.js +250 -0
- package/dist/core/codex-lb/bridge-runtime-validation.js +106 -0
- package/dist/core/codex-lb/capability-runner.js +505 -201
- package/dist/core/codex-lb/codex-lb-env.js +179 -12
- package/dist/core/codex-lb/combined-catalog/builder.js +86 -0
- package/dist/core/codex-lb/combined-catalog/contracts.js +5 -0
- package/dist/core/codex-lb/combined-catalog/normalize.js +170 -0
- package/dist/core/codex-lb/combined-catalog/persistence.js +207 -0
- package/dist/core/codex-lb/combined-catalog/shared.js +12 -0
- package/dist/core/codex-lb/combined-catalog/storage.js +171 -0
- package/dist/core/codex-lb/combined-catalog.js +12 -0
- package/dist/core/codex-lb/desktop-bridge/client.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +48 -63
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +115 -83
- package/dist/core/codex-lb/desktop-bridge/launchd.js +20 -13
- package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +4 -1
- package/dist/core/codex-lb/desktop-bridge/security.js +381 -267
- package/dist/core/codex-lb/desktop-bridge/server.js +148 -19
- package/dist/core/codex-lb/desktop-bridge/state.js +56 -70
- package/dist/core/codex-lb/desktop-bridge/types.js +6 -1
- package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +281 -106
- package/dist/core/codex-lb/desktop-bridge-migration/historical-config.js +245 -0
- package/dist/core/codex-lb/desktop-bridge-migration/historical-toml.js +56 -0
- package/dist/core/codex-lb/desktop-bridge-migration/metadata.js +73 -0
- package/dist/core/codex-lb/desktop-bridge-migration/receipt.js +52 -0
- package/dist/core/codex-lb/desktop-bridge-migration/retired-runtime-cleanup.js +106 -0
- package/dist/core/codex-lb/desktop-bridge-migration/types.js +1 -0
- package/dist/core/codex-lb/desktop-bridge-migration.js +238 -0
- package/dist/core/codex-lb/desktop-controller-v3/catalog.js +257 -0
- package/dist/core/codex-lb/desktop-controller-v3/diagnostics.js +62 -0
- package/dist/core/codex-lb/desktop-controller-v3/lifecycle-commands.js +203 -0
- package/dist/core/codex-lb/desktop-controller-v3/live-probes.js +293 -0
- package/dist/core/codex-lb/desktop-controller-v3/preflight-probes.js +144 -0
- package/dist/core/codex-lb/desktop-controller-v3/provider-commands.js +182 -0
- package/dist/core/codex-lb/desktop-controller-v3/shared.js +279 -0
- package/dist/core/codex-lb/desktop-controller-v3/status.js +269 -0
- package/dist/core/codex-lb/desktop-controller-v3/types.js +1 -0
- package/dist/core/codex-lb/desktop-controller-v3/verification.js +89 -0
- package/dist/core/codex-lb/desktop-controller-v3.js +67 -0
- package/dist/core/codex-lb/desktop-controller.js +2 -1730
- package/dist/core/codex-lb/desktop-service.js +462 -627
- package/dist/core/codex-lb/migration-receipt.js +560 -118
- package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +37 -53
- package/dist/core/codex-lb/probes/bridge-probe.js +125 -64
- package/dist/core/codex-lb/probes/catalog-probe.js +36 -136
- package/dist/core/codex-lb/probes/computer-use-probe.js +63 -39
- package/dist/core/codex-lb/probes/image-generation-probe.js +98 -41
- package/dist/core/codex-lb/probes/probe-evidence.js +32 -33
- package/dist/core/codex-lb/probes/voice-realtime-probe.js +69 -43
- package/dist/core/codex-lb/provider-credentials/configuration.js +127 -0
- package/dist/core/codex-lb/provider-credentials/locks.js +11 -0
- package/dist/core/codex-lb/provider-credentials/private-snapshot.js +28 -0
- package/dist/core/codex-lb/provider-credentials/removal.js +33 -0
- package/dist/core/codex-lb/provider-credentials/resolution.js +59 -0
- package/dist/core/codex-lb/provider-credentials/runtime.js +55 -0
- package/dist/core/codex-lb/provider-credentials/types.js +1 -0
- package/dist/core/codex-lb/provider-credentials/validation-store.js +137 -0
- package/dist/core/codex-lb/provider-credentials.js +5 -0
- package/dist/core/codex-lb/provider-registry.js +323 -0
- package/dist/core/codex-lb/provider-route-policy.js +118 -0
- package/dist/core/codex-lb/request-route-resolver.js +172 -0
- package/dist/core/codex-lb/route-index.js +148 -0
- package/dist/core/codex-lb/trusted-deep-evidence.js +158 -286
- package/dist/core/commands/basic-cli.js +1 -1
- package/dist/core/commands/check-command.js +3 -10
- package/dist/core/commands/gate-result-contract.js +10 -14
- package/dist/core/commands/intent-normalization/normalizer.js +1 -1
- package/dist/core/commands/mad-sks-command.js +2 -6
- package/dist/core/commands/release-command.js +11 -1
- package/dist/core/commands/telegram-command.js +46 -6
- package/dist/core/doctor/doctor-readiness-matrix.js +9 -7
- package/dist/core/doctor/skill-legacy-surface.js +5 -5
- package/dist/core/evidence/v2/evidence-key.js +30 -3
- package/dist/core/feature-fixtures.js +8 -1
- package/dist/core/feature-registry.js +3 -2
- package/dist/core/hooks-runtime/stop-finalization.js +11 -1
- package/dist/core/hooks-runtime/subagent-context.js +15 -1
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +1 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
- package/dist/core/hooks-runtime.js +73 -87
- package/dist/core/image-ux-review/imagegen-adapter.js +108 -94
- package/dist/core/image-ux-review/real-callout-extractor.js +144 -14
- package/dist/core/imagegen/desktop-bridge-imagegen-target.js +77 -0
- package/dist/core/imagegen/imagegen-capability.js +43 -151
- package/dist/core/init/skills/filesystem.js +89 -0
- package/dist/core/init/skills/inventory.js +97 -0
- package/dist/core/init/skills/manifest.js +151 -0
- package/dist/core/init/skills.js +5 -325
- package/dist/core/init.js +0 -63
- package/dist/core/install/installed-package-smoke.js +1 -1
- package/dist/core/managed-assets/managed-assets-manifest.js +0 -1
- package/dist/core/policy/latest-version-guidance.js +15 -2
- package/dist/core/preflight/parallel-preflight-engine.js +27 -51
- package/dist/core/provider/provider-badge.js +9 -4
- package/dist/core/provider/provider-context.js +57 -107
- package/dist/core/providers/openrouter/openrouter-account.js +3 -1
- package/dist/core/providers/openrouter/openrouter-secret-store.js +91 -22
- package/dist/core/release/desktop-bridge-release-evidence.js +457 -0
- package/dist/core/release/gate-manifest.js +0 -1
- package/dist/core/release/main-push-guard.js +13 -0
- package/dist/core/release/main-push-receipt.js +11 -0
- package/dist/core/release/physical-release-gates.js +664 -61
- package/dist/core/release/publish-preflight.js +3 -3
- package/dist/core/release/release-gate-batch-runner.js +19 -6
- package/dist/core/release/release-gate-dag.js +33 -6
- package/dist/core/release/release-gate-node.js +1 -3
- package/dist/core/release/release-gate-output-contract.js +55 -0
- package/dist/core/release/release-pack-contract.js +1 -1
- package/dist/core/release/release-pack-receipt.js +209 -8
- package/dist/core/release/release-real-contract.js +1 -1
- package/dist/core/release/stage-publish.js +106 -28
- package/dist/core/retention/temp-lease.js +204 -0
- package/dist/core/retention.js +18 -195
- package/dist/core/routes.js +1 -2
- package/dist/core/safety/intent-contract/intent-contract.js +3 -3
- package/dist/core/subagents/naruto-host-credentials.js +6 -1
- package/dist/core/subagents/official-subagent-config.js +27 -9
- package/dist/core/subagents/official-subagent-runner.js +14 -31
- package/dist/core/subagents/wave-lifecycle.js +36 -8
- package/dist/core/subagents/wave-parent-guidance.js +2 -1
- package/dist/core/telegram/doctor.js +2 -2
- package/dist/core/telegram/liveness.js +10 -4
- package/dist/core/triwiki/context-graph/compiler/index.js +18 -18
- package/dist/core/update/update-migration-state/fast-mode-config.js +172 -0
- package/dist/core/update/update-migration-state/session-state-split.js +247 -0
- package/dist/core/update/update-migration-state/simple-stages.js +46 -0
- package/dist/core/update/update-migration-state.js +4 -481
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +28 -4
- package/dist/native/sks-menubar/Sources/OperationModels.swift +112 -2
- package/dist/native/sks-menubar/Sources/ProviderRouteExplanation.swift +21 -0
- package/dist/native/sks-menubar/Sources/ProvidersBridgeCatalog.swift +140 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +107 -470
- package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +27 -197
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +335 -269
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +233 -437
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +16 -7
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +39 -9
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +56 -0
- package/dist/scripts/canonical-test-runner.js +7 -1
- package/dist/scripts/check-runtime-schemas.js +7 -2
- package/dist/scripts/codex-sdk-real-smoke-check.js +3 -1
- package/dist/scripts/desktop-bridge-capabilities-check.js +123 -0
- package/dist/scripts/{codex-lb-desktop-bridge-latency-check.js → desktop-bridge-latency-check.js} +61 -16
- package/dist/scripts/desktop-bridge-real-evidence-check.js +64 -0
- package/dist/scripts/{codex-lb-desktop-bridge-check.js → desktop-bridge-transport-check.js} +92 -155
- package/dist/scripts/desktop-bridge-transport-client.js +116 -0
- package/dist/scripts/desktop-bridge-unification-check.js +276 -0
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +12 -8
- package/dist/scripts/gate-policy-audit-check.js +52 -2
- package/dist/scripts/provider-badge-context-check.js +55 -12
- package/dist/scripts/publish-preflight.js +1 -2
- package/dist/scripts/release-affected-selector-check.js +1 -2
- package/dist/scripts/release-aggressive-resource-governor-check.js +1 -1
- package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
- package/dist/scripts/release-cache-version-neutral-fixture-check.js +1 -0
- package/dist/scripts/release-full-parallelism-blackbox.js +1 -1
- package/dist/scripts/release-gate-batch-runner-check.js +9 -0
- package/dist/scripts/release-gate-dag-runner-check.js +6 -0
- package/dist/scripts/release-gate-dag-runner.js +4 -2
- package/dist/scripts/release-metadata-check.js +16 -3
- package/dist/scripts/release-pack-receipt.js +29 -6
- package/dist/scripts/release-physical-gates-check.js +39 -0
- package/dist/scripts/release-real-check.js +7 -5
- package/package.json +6 -8
- package/release-gates.v2.json +156 -157
- package/runtime-required-scripts.json +11 -11
- package/schemas/codex/desktop-bridge-status-v3.schema.json +286 -0
- package/schemas/codex/desktop-capabilities-v3.schema.json +198 -0
- package/schemas/release/release-gate-node.schema.json +2 -3
- package/dist/cli/codex-lb-setup-warning-output.js +0 -17
- package/dist/cli/install-helpers-codex-lb-chain.js +0 -529
- package/dist/commands/codex-lb.js +0 -1232
- package/dist/core/architecture-hardening/migration/migration.js +0 -111
- package/dist/core/codex-app/auxiliary-oauth-policy.js +0 -36
- package/dist/core/codex-app/catalog-compat/catalog-service.js +0 -104
- package/dist/core/codex-app/child-policy/child-policy.js +0 -35
- package/dist/core/codex-app/desktop-routing-snapshot.js +0 -233
- package/dist/core/codex-app/glm-model-profile.js +0 -1
- package/dist/core/codex-app/glm-profile-installer.js +0 -191
- package/dist/core/codex-app/glm-profile-schema.js +0 -42
- package/dist/core/codex-app/multi-provider-router.js +0 -391
- package/dist/core/codex-app/openrouter-activate.js +0 -405
- package/dist/core/codex-app/openrouter-model-catalog.js +0 -217
- package/dist/core/codex-app/provider-child-policy.js +0 -64
- package/dist/core/codex-app/provider-mode.js +0 -91
- package/dist/core/codex-app/provider-session-policy.js +0 -85
- package/dist/core/codex-app/session-policy/session-pinning.js +0 -68
- package/dist/core/codex-control/codex-lb-launch-recovery.js +0 -319
- package/dist/core/codex-lb/codex-lb-setup.js +0 -293
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +0 -456
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +0 -290
- package/dist/core/codex-lb/desktop-center-credentials.js +0 -1083
- package/dist/core/codex-lb/desktop-mode.js +0 -32
- package/dist/core/codex-lb/desktop-real-evidence.js +0 -168
- package/dist/core/codex-lb/legacy-migration.js +0 -576
- package/dist/core/codex-lb/native-openai-transport/transport.js +0 -68
- package/dist/core/codex-lb/provider-routing/provider-router.js +0 -58
- package/dist/core/codex-lb/routing-truth.js +0 -327
- package/dist/core/imagegen/codex-lb-imagegen-target.js +0 -92
- package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +0 -118
- package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +0 -17
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +0 -331
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +0 -260
- package/dist/scripts/codex-lb-catalog-passthrough-check.js +0 -120
- package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +0 -169
- package/dist/scripts/codex-lb-desktop-capabilities-check.js +0 -287
- package/dist/scripts/codex-lb-desktop-real-evidence-check.js +0 -123
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +0 -114
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +0 -152
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +0 -231
package/dist/commands/doctor.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { createHash } from 'node:crypto';
|
|
4
3
|
import { projectRoot, exists, formatBytes, nowIso, readText, writeJsonAtomic } from '../core/fsx.js';
|
|
5
4
|
import { flag } from '../cli/args.js';
|
|
6
5
|
import { printJson } from '../cli/output.js';
|
|
@@ -8,23 +7,14 @@ import { ui as cliUi } from '../cli/cli-theme.js';
|
|
|
8
7
|
import { getCodexInfo } from '../core/codex-adapter.js';
|
|
9
8
|
import { rustInfo } from '../core/rust-accelerator.js';
|
|
10
9
|
import { codexAppIntegrationStatus } from '../core/codex-app.js';
|
|
11
|
-
import {
|
|
12
|
-
import { codexLbStatus } from '../cli/install-helpers.js';
|
|
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';
|
|
10
|
+
import { desktopBridgeStatusV3 } from '../core/codex-lb/desktop-controller-v3.js';
|
|
19
11
|
import { probeTelegram, telegramSelfHealAction } from '../core/telegram/doctor.js';
|
|
20
12
|
import { TelegramClient } from '../core/telegram/client.js';
|
|
21
13
|
import { resolveTelegramBotToken } from '../core/telegram/keychain.js';
|
|
22
14
|
import { telegramLivenessPath } from '../core/telegram/liveness.js';
|
|
23
|
-
import { normalizeInstallScope } from '../core/init.js';
|
|
24
15
|
import { inspectCodexConfigReadability } from '../core/codex/codex-config-readability.js';
|
|
25
16
|
import { inspectOAuthCallbackPortConflict, oauthCallbackDoctorGuidance } from '../core/codex/oauth-callback-port-diagnostic.js';
|
|
26
17
|
import { inventoryCodexPermissionProfiles } from '../core/codex/codex-permission-profiles.js';
|
|
27
|
-
import { appendMigrationEvents, hashConfigText } from '../core/migration/migration-transaction-journal.js';
|
|
28
18
|
import { resolveProviderContext } from '../core/provider/provider-context.js';
|
|
29
19
|
import { readLocalModelConfig } from '../core/agents/ollama-worker-config.js';
|
|
30
20
|
import { writeCodexCurrentAppCapabilityArtifacts } from '../core/codex-control/codex-current-app-capability.js';
|
|
@@ -42,11 +32,12 @@ import { sweepSksTempDirs } from '../core/retention.js';
|
|
|
42
32
|
import { detectImagegenCapability } from '../core/imagegen/imagegen-capability.js';
|
|
43
33
|
import { CURRENT_CODEX_RELEASE_MANIFEST } from '../core/codex-compat/codex-release-manifest.js';
|
|
44
34
|
import { formatHarnessConflictReport, scanHarnessConflicts } from '../core/harness-conflicts.js';
|
|
45
|
-
import { doctorArgWarnings as baseDoctorArgWarnings, doctorMenuBarInstallPolicy, doctorPhaseIdsForProfile, doctorProfileFromArgs } from './doctor-profile.js';
|
|
46
|
-
|
|
47
|
-
|
|
35
|
+
import { doctorArgWarnings as baseDoctorArgWarnings, doctorMenuBarInstallPolicy, doctorPhaseIdsForProfile, doctorProfileFromArgs, doctorProfileRequiresDesktopBridgeReadiness } from './doctor-profile.js';
|
|
36
|
+
import { buildCodexAppUiDiagnosticFailure, buildRuntimeReadiness, captureCodexConfigSnapshot, deferredNativeRepair, doctorDedupeStatus, doctorSkillStatus, fallbackCodexNativeFeatureMatrix, formatCodexDoctorConsoleStatus, installScopeFromArgs, isMigrationUserOwnedProjectConfigBlocker, mergeObservedCodexStartupWarnings, nativeCapabilityStatus, readOption, rebootstrapSksMenuBarLaunchdForDoctorFix, sksMenuBarRunningVersionConsoleLines, uniqueNativeManualActions, writeFixMigrationJournal, writeJsonReportFile } from './doctor-helpers.js';
|
|
37
|
+
export { doctorMenuBarInstallPolicy, doctorProfileFromArgs, doctorProfileRequiresDesktopBridgeReadiness } from './doctor-profile.js';
|
|
38
|
+
export { buildCodexAppUiDiagnosticFailure, buildRuntimeReadiness, formatCodexDoctorConsoleStatus, rebootstrapSksMenuBarLaunchdForDoctorFix, sksMenuBarRunningVersionConsoleLines };
|
|
48
39
|
export function doctorArgWarnings(args = []) {
|
|
49
|
-
return baseDoctorArgWarnings(args
|
|
40
|
+
return baseDoctorArgWarnings(args);
|
|
50
41
|
}
|
|
51
42
|
export function deferCommandAliasCleanupToMigrationReceipt(result) {
|
|
52
43
|
const observedBlockers = Array.isArray(result?.blockers)
|
|
@@ -67,195 +58,50 @@ export function deferCommandAliasCleanupToMigrationReceipt(result) {
|
|
|
67
58
|
]
|
|
68
59
|
};
|
|
69
60
|
}
|
|
70
|
-
export async function
|
|
61
|
+
export async function inspectDoctorDesktopBridgeStatus(input = {}, deps = {}) {
|
|
71
62
|
const processEnv = input.processEnv || process.env;
|
|
72
63
|
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
64
|
try {
|
|
114
|
-
|
|
65
|
+
const status = await (deps.desktopBridgeStatusImpl || desktopBridgeStatusV3)({
|
|
115
66
|
home,
|
|
116
|
-
processEnv
|
|
117
|
-
envPath,
|
|
118
|
-
...(suppliedMigrationOptions.metadataPath ? { metadataPath: suppliedMigrationOptions.metadataPath } : {})
|
|
67
|
+
env: processEnv
|
|
119
68
|
});
|
|
69
|
+
if (!status || typeof status !== 'object' || !status.providers || !status.readiness) {
|
|
70
|
+
throw new Error('invalid Desktop Bridge status response');
|
|
71
|
+
}
|
|
72
|
+
const enabledProviders = Object.values(status.providers)
|
|
73
|
+
.filter((provider) => provider?.enabled === true);
|
|
74
|
+
const expected = enabledProviders.length > 0;
|
|
75
|
+
const blockers = expected && status.readiness.ready !== true
|
|
76
|
+
? (status.readiness.blockers || []).map(String).filter(Boolean)
|
|
77
|
+
: [];
|
|
78
|
+
return {
|
|
79
|
+
schema: 'sks.doctor-desktop-bridge.v1',
|
|
80
|
+
ok: blockers.length === 0,
|
|
81
|
+
read_only: true,
|
|
82
|
+
credentials_mutated: false,
|
|
83
|
+
managed: status.management?.managed === true,
|
|
84
|
+
status,
|
|
85
|
+
providers: status.providers,
|
|
86
|
+
blockers,
|
|
87
|
+
warnings: (status.readiness.warnings || []).map(String).filter(Boolean),
|
|
88
|
+
recovery_actions: (status.recovery_actions || []).map(String).filter(Boolean)
|
|
89
|
+
};
|
|
120
90
|
}
|
|
121
91
|
catch (error) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
|
92
|
+
return {
|
|
93
|
+
schema: 'sks.doctor-desktop-bridge.v1',
|
|
94
|
+
ok: false,
|
|
95
|
+
read_only: true,
|
|
96
|
+
credentials_mutated: false,
|
|
97
|
+
managed: null,
|
|
98
|
+
status: null,
|
|
99
|
+
providers: null,
|
|
100
|
+
blockers: [`desktop_bridge_status_unavailable:${error instanceof Error ? error.message : String(error)}`],
|
|
101
|
+
warnings: [],
|
|
102
|
+
recovery_actions: ['Run `sks bridge status --json` to inspect Desktop Bridge provider readiness.']
|
|
175
103
|
};
|
|
176
104
|
}
|
|
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
105
|
}
|
|
260
106
|
export async function run(_command, args = [], deps = {}) {
|
|
261
107
|
const root = await projectRoot();
|
|
@@ -319,50 +165,10 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
319
165
|
|| (await import('../core/doctor/command-alias-cleanup.js')).runDoctorCommandAliasCleanup;
|
|
320
166
|
const ensureGlobalFastModeImpl = deps.ensureGlobalCodexFastModeDuringInstallImpl
|
|
321
167
|
|| (await import('../cli/install-helpers.js')).ensureGlobalCodexFastModeDuringInstall;
|
|
322
|
-
const ensureStoredOpenRouterProviderImpl = deps.ensureStoredOpenRouterProviderDuringInstallImpl
|
|
323
|
-
|| (await import('../cli/install-helpers.js')).ensureStoredOpenRouterProviderDuringInstall;
|
|
324
168
|
const installMenuBarImpl = deps.installSksMenuBarImpl || installSksMenuBar;
|
|
325
|
-
const codexLbStatusImpl = deps.codexLbStatusImpl || codexLbStatus;
|
|
326
169
|
const doctorEnv = deps.env || (deps.home
|
|
327
170
|
? { ...process.env, HOME: home }
|
|
328
171
|
: 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
|
-
});
|
|
350
|
-
const providerStatus = await codexLbStatusImpl({
|
|
351
|
-
...statusOptions,
|
|
352
|
-
probeToolOutputRecovery: true,
|
|
353
|
-
allowUnverifiedToolOutputRecovery: codexLbToolOutputRecoveryOverrideAcknowledged({ args })
|
|
354
|
-
}).catch((err) => ({
|
|
355
|
-
selected: null,
|
|
356
|
-
provider_ready: false,
|
|
357
|
-
recovery_probe_failed: true,
|
|
358
|
-
tool_output_recovery: {
|
|
359
|
-
ok: false,
|
|
360
|
-
status: 'probe_failed',
|
|
361
|
-
blockers: ['codex_lb_tool_output_recovery_status_probe_failed'],
|
|
362
|
-
operator_actions: []
|
|
363
|
-
},
|
|
364
|
-
error: err?.message || String(err)
|
|
365
|
-
}));
|
|
366
172
|
const globalSkills = await reconcileSkillsImpl({
|
|
367
173
|
targetDir: path.join(home, '.agents', 'skills'),
|
|
368
174
|
scope: 'global',
|
|
@@ -388,18 +194,6 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
388
194
|
status: 'failed',
|
|
389
195
|
error: err?.message || String(err)
|
|
390
196
|
}));
|
|
391
|
-
const openRouterEnv = {
|
|
392
|
-
...doctorEnv,
|
|
393
|
-
HOME: home,
|
|
394
|
-
SKS_HOME: path.join(home, '.sneakoscope')
|
|
395
|
-
};
|
|
396
|
-
const openRouterProvider = await ensureStoredOpenRouterProviderImpl({ home, env: openRouterEnv }).catch((err) => ({
|
|
397
|
-
schema: 'sks.openrouter-provider-upgrade-repair.v1',
|
|
398
|
-
ok: false,
|
|
399
|
-
status: 'failed',
|
|
400
|
-
blockers: ['openrouter_provider_repair_failed'],
|
|
401
|
-
error: err?.message || String(err)
|
|
402
|
-
}));
|
|
403
197
|
const menuBar = await installMenuBarImpl({
|
|
404
198
|
home,
|
|
405
199
|
root: home,
|
|
@@ -414,18 +208,10 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
414
208
|
blockers: [err?.message || String(err)],
|
|
415
209
|
warnings: []
|
|
416
210
|
}));
|
|
417
|
-
const
|
|
418
|
-
const codexLbRoutingReady = !doctorCodexLbRouteExpected(providerStatus)
|
|
419
|
-
|| codexLbRoutingTruthIsActive(codexLbRoutingTruth);
|
|
420
|
-
const codexLbDivergence = await inspectDoctorCodexLbDivergence({
|
|
211
|
+
const desktopBridge = await inspectDoctorDesktopBridgeStatus({
|
|
421
212
|
home,
|
|
422
|
-
processEnv: doctorEnv
|
|
423
|
-
|
|
424
|
-
fix: true,
|
|
425
|
-
...(deps.codexLbLaunchctlBin ? { launchctlBin: deps.codexLbLaunchctlBin } : {}),
|
|
426
|
-
...(deps.codexLbLaunchPlatform ? { platform: deps.codexLbLaunchPlatform } : {}),
|
|
427
|
-
...(deps.codexLbLaunchRunProcessImpl ? { runProcessImpl: deps.codexLbLaunchRunProcessImpl } : {})
|
|
428
|
-
}, deps.codexLbDivergenceDeps || {});
|
|
213
|
+
processEnv: doctorEnv
|
|
214
|
+
}, { desktopBridgeStatusImpl: deps.desktopBridgeStatusImpl });
|
|
429
215
|
const telegramRemote = await inspectTelegramRemote({
|
|
430
216
|
live: true,
|
|
431
217
|
fix: true,
|
|
@@ -433,26 +219,20 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
433
219
|
home,
|
|
434
220
|
env: doctorEnv
|
|
435
221
|
}, deps);
|
|
436
|
-
const recoveryReady = codexLbRecoveryStatusReady(providerStatus, true);
|
|
437
222
|
const globalSkillsReady = !globalSkills?.error
|
|
438
223
|
&& globalSkills?.ok !== false
|
|
439
224
|
&& globalSkills?.core_skill_integrity?.ok !== false;
|
|
440
225
|
const globalFastModeReady = globalFastMode?.status !== 'failed'
|
|
441
226
|
&& globalFastMode?.ok !== false;
|
|
442
227
|
const menuBarReady = menuBar?.ok !== false;
|
|
443
|
-
const openRouterProviderReady = openRouterProvider?.ok !== false;
|
|
444
228
|
const blockers = [...new Set([
|
|
445
229
|
...(!globalSkillsReady ? [`global_skills_reconcile_failed:${globalSkills?.error || 'core_skill_integrity'}`] : []),
|
|
446
230
|
...(currentSurface?.ok !== true ? (currentSurface?.blockers || ['global_current_surface_reconcile_failed']) : []),
|
|
447
231
|
...(!globalFastModeReady ? [`global_fast_mode_repair_failed:${globalFastMode?.error || globalFastMode?.status || 'unknown'}`] : []),
|
|
448
|
-
...(!openRouterProviderReady ? (openRouterProvider?.blockers || ['openrouter_provider_repair_failed']) : []),
|
|
449
232
|
...(!menuBarReady ? (menuBar?.blockers || ['sks_menubar_repair_failed']) : []),
|
|
450
|
-
...(
|
|
451
|
-
? (
|
|
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 || [])
|
|
233
|
+
...(desktopBridge.ok === false
|
|
234
|
+
? (desktopBridge.blockers || ['desktop_bridge_unavailable'])
|
|
235
|
+
: [])
|
|
456
236
|
].map(String).filter(Boolean))];
|
|
457
237
|
const ok = blockers.length === 0;
|
|
458
238
|
return {
|
|
@@ -479,26 +259,14 @@ export async function executeDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
479
259
|
skills: { global: globalSkills, project: { skipped: true, reason: 'global_only_doctor' } },
|
|
480
260
|
current_public_surface: currentSurface,
|
|
481
261
|
codex_app_fast_mode: globalFastMode,
|
|
482
|
-
openrouter_provider:
|
|
262
|
+
openrouter_provider: desktopBridge.providers?.openrouter || null,
|
|
483
263
|
sks_menubar: menuBar,
|
|
484
264
|
telegram_remote: telegramRemote,
|
|
485
|
-
|
|
486
|
-
provider_status: providerStatus,
|
|
487
|
-
tool_output_recovery: providerStatus?.tool_output_recovery || null,
|
|
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
|
|
494
|
-
},
|
|
265
|
+
desktop_bridge: desktopBridge,
|
|
495
266
|
blockers,
|
|
496
267
|
next_actions: [
|
|
497
|
-
...(
|
|
498
|
-
...(codexLbSecretProbe.legacy_keychain_migration?.operator_actions || []),
|
|
499
|
-
...(codexLbDivergence.operator_actions || []),
|
|
268
|
+
...(desktopBridge.ok === false ? desktopBridge.recovery_actions || [] : []),
|
|
500
269
|
...telegramDoctorOperatorActions(telegramRemote),
|
|
501
|
-
...(!openRouterProviderReady ? ['Run `sks codex-app set-openrouter-key` to repair the stored-key provider configuration without switching models.'] : []),
|
|
502
270
|
'Run `sks doctor --fix --json` from a specific project directory when project-scoped repair is required.'
|
|
503
271
|
]
|
|
504
272
|
};
|
|
@@ -528,7 +296,7 @@ async function runDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
528
296
|
const telegramCheckedLine = telegramDoctorCheckedLine(result.telegram_remote);
|
|
529
297
|
if (telegramCheckedLine)
|
|
530
298
|
console.log(telegramCheckedLine);
|
|
531
|
-
console.log(`
|
|
299
|
+
console.log(`Desktop Bridge: ${result.desktop_bridge.ok ? 'ready' : 'blocked'} (${result.desktop_bridge.status?.readiness?.state || 'unavailable'})`);
|
|
532
300
|
for (const blocker of result.blockers)
|
|
533
301
|
console.log(`- blocker: ${blocker}`);
|
|
534
302
|
for (const action of result.next_actions)
|
|
@@ -538,107 +306,6 @@ async function runDoctorGlobalOnlyFix(args = [], root, deps = {}) {
|
|
|
538
306
|
process.exitCode = 1;
|
|
539
307
|
return result;
|
|
540
308
|
}
|
|
541
|
-
function codexLbRecoveryStatusReady(status, probeRequired = false) {
|
|
542
|
-
if (status == null)
|
|
543
|
-
return !probeRequired;
|
|
544
|
-
if (status.recovery_probe_failed === true || status.error)
|
|
545
|
-
return false;
|
|
546
|
-
if (status.selected === false)
|
|
547
|
-
return true;
|
|
548
|
-
if (!probeRequired)
|
|
549
|
-
return true;
|
|
550
|
-
return status.selected === true && status.tool_output_recovery?.ok === true;
|
|
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
|
-
? 'authorization-bearer'
|
|
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
|
-
? 'authorization-bearer'
|
|
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 === 'x-codex-lb-api-key'
|
|
631
|
-
? 'x-codex-lb-api-key'
|
|
632
|
-
: 'authorization-bearer';
|
|
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
309
|
export async function inspectTelegramRemote(input = {}, deps = {}) {
|
|
643
310
|
const env = input.env || process.env;
|
|
644
311
|
const home = path.resolve(input.home || env.HOME || os.homedir());
|
|
@@ -752,7 +419,7 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
752
419
|
requireActualCodex: false,
|
|
753
420
|
codexBin: codexBin || undefined
|
|
754
421
|
};
|
|
755
|
-
const [codex, rust, codexConfig, sneakoscopeExists, oauthCallbackPortDiagnostic,
|
|
422
|
+
const [codex, rust, codexConfig, sneakoscopeExists, oauthCallbackPortDiagnostic, desktopBridge] = await Promise.all([
|
|
756
423
|
codexBin
|
|
757
424
|
? Promise.resolve({ bin: codexBin, version: 'fixture-or-explicit', available: true })
|
|
758
425
|
: getCodexInfo().catch(() => ({ bin: null, version: null, available: false })),
|
|
@@ -765,7 +432,7 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
765
432
|
})),
|
|
766
433
|
exists(`${root}/.sneakoscope`),
|
|
767
434
|
inspectOAuthCallbackPortConflict(),
|
|
768
|
-
|
|
435
|
+
inspectDoctorDesktopBridgeStatus({ processEnv: process.env })
|
|
769
436
|
]);
|
|
770
437
|
const oauthCallbackOperatorActions = oauthCallbackDoctorGuidance(oauthCallbackPortDiagnostic);
|
|
771
438
|
const telegramRemote = await inspectTelegramRemote();
|
|
@@ -794,18 +461,19 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
794
461
|
const deferredBrowserUse = deferredNativeRepair('sks.doctor-browser-use-repair.v1', false, [
|
|
795
462
|
'Chrome/web review route needs the Codex Chrome Extension enabled before use.'
|
|
796
463
|
]);
|
|
464
|
+
const desktopBridgeReady = desktopBridge.ok !== false;
|
|
797
465
|
const result = {
|
|
798
466
|
schema: 'sks.doctor-status.v3',
|
|
799
467
|
elapsed_ms: Date.now() - startedAtMs,
|
|
800
|
-
ok:
|
|
801
|
-
status: 'fast_readonly_ok',
|
|
468
|
+
ok: desktopBridgeReady,
|
|
469
|
+
status: desktopBridgeReady ? 'fast_readonly_ok' : 'blocked',
|
|
802
470
|
diagnostic_depth: 'fast',
|
|
803
471
|
deep_diagnostics_skipped: true,
|
|
804
472
|
deep_ok: null,
|
|
805
473
|
not_counted_as_full_doctor: true,
|
|
806
474
|
next_actions: [
|
|
807
475
|
'Run sks doctor --full --json for deep diagnostics.',
|
|
808
|
-
...(
|
|
476
|
+
...(desktopBridge.ok === false ? desktopBridge.recovery_actions || [] : []),
|
|
809
477
|
...telegramDoctorOperatorActions(telegramRemote)
|
|
810
478
|
],
|
|
811
479
|
root,
|
|
@@ -815,7 +483,7 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
815
483
|
warnings: [...oauthCallbackPortDiagnostic.warnings],
|
|
816
484
|
operator_actions: [
|
|
817
485
|
...oauthCallbackOperatorActions,
|
|
818
|
-
...(
|
|
486
|
+
...(desktopBridge.ok === false ? desktopBridge.recovery_actions || [] : [])
|
|
819
487
|
],
|
|
820
488
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
821
489
|
codex,
|
|
@@ -843,25 +511,28 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
843
511
|
},
|
|
844
512
|
telegram_remote: telegramRemote,
|
|
845
513
|
provider_context: {
|
|
846
|
-
schema: 'sks.provider-context.
|
|
514
|
+
schema: 'sks.provider-context.v2',
|
|
847
515
|
generated_at: nowIso(),
|
|
848
516
|
provider: 'unknown',
|
|
849
517
|
auth_mode: 'unknown',
|
|
850
518
|
route: '$Doctor',
|
|
851
519
|
service_tier: process.env.SKS_SERVICE_TIER || 'fast',
|
|
852
|
-
source: '
|
|
520
|
+
source: 'unknown',
|
|
853
521
|
confidence: 'low',
|
|
854
522
|
conflict: false,
|
|
855
523
|
warnings: ['provider_context_optional_diagnostic_skipped'],
|
|
856
|
-
signals: {
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
524
|
+
signals: {
|
|
525
|
+
openai_api_key_present: false,
|
|
526
|
+
codex_app_auth_present: false,
|
|
527
|
+
desktop_bridge_status_available: false,
|
|
528
|
+
desktop_bridge_managed: false,
|
|
529
|
+
desktop_bridge_ready: false,
|
|
530
|
+
desktop_bridge_provider: null,
|
|
531
|
+
desktop_bridge_native_identity_configured: false,
|
|
532
|
+
desktop_bridge_credential_state: null
|
|
533
|
+
}
|
|
864
534
|
},
|
|
535
|
+
desktop_bridge: desktopBridge,
|
|
865
536
|
codex_doctor: null,
|
|
866
537
|
pre_repair_codex_doctor: null,
|
|
867
538
|
post_repair_codex_doctor: null,
|
|
@@ -960,20 +631,15 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
960
631
|
const doctorDirtyPlan = doctorFix ? (await import('../core/doctor/doctor-dirty-planner.js')).planDoctorDirtyRepair(root, doctorPhaseIds) : null;
|
|
961
632
|
let setupRepair = null;
|
|
962
633
|
let sksUpdate = null;
|
|
963
|
-
|
|
634
|
+
const openRouterProviderRepair = {
|
|
635
|
+
ok: true,
|
|
636
|
+
status: 'read_only',
|
|
637
|
+
reason: 'Desktop Bridge owns provider credentials; Doctor does not migrate them.'
|
|
638
|
+
};
|
|
964
639
|
let migrationPreFix = null;
|
|
965
640
|
if (doctorFix) {
|
|
966
641
|
migrationPreFix = await captureCodexConfigSnapshot();
|
|
967
642
|
const installScope = installScopeFromArgs(args);
|
|
968
|
-
openRouterProviderRepair = flag(args, '--local-only')
|
|
969
|
-
? { ok: true, status: 'skipped', reason: 'local-only repair' }
|
|
970
|
-
: await (await import('../cli/install-helpers.js')).ensureStoredOpenRouterProviderDuringInstall().catch((err) => ({
|
|
971
|
-
schema: 'sks.openrouter-provider-upgrade-repair.v1',
|
|
972
|
-
ok: false,
|
|
973
|
-
status: 'failed',
|
|
974
|
-
blockers: ['openrouter_provider_repair_failed'],
|
|
975
|
-
error: err?.message || String(err)
|
|
976
|
-
}));
|
|
977
643
|
setupRepair = {
|
|
978
644
|
schema: 'sks.doctor-setup-phase.v2',
|
|
979
645
|
ok: true,
|
|
@@ -1105,59 +771,12 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
1105
771
|
const codexApp = deepDiagnostics
|
|
1106
772
|
? await codexAppIntegrationStatus({ codex }).catch((err) => ({ ok: false, error: err.message }))
|
|
1107
773
|
: { ok: false, skipped: true, warnings: ['codex_app_optional_diagnostic_skipped'] };
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
: null;
|
|
1112
|
-
const codexLbSecretProbe = await inspectDoctorCodexLbSecretResolution({
|
|
1113
|
-
processEnv: process.env,
|
|
1114
|
-
fix: doctorFix,
|
|
1115
|
-
forceRetry: flag(args, CODEX_LB_KEYCHAIN_MIGRATION_RETRY_FLAG),
|
|
1116
|
-
baseUrl: codexLbPreRepairStatus?.base_url || codexLbPreRepairStatus?.provider_base_url || null
|
|
1117
|
-
});
|
|
1118
|
-
const codexLbProviderStatus = await codexLbStatus({
|
|
1119
|
-
probeToolOutputRecovery: deepDiagnostics || doctorFix,
|
|
1120
|
-
allowUnverifiedToolOutputRecovery: codexLbToolOutputRecoveryOverrideAcknowledged({ args })
|
|
1121
|
-
}).catch((err) => ({
|
|
1122
|
-
selected: null,
|
|
1123
|
-
provider_ready: false,
|
|
1124
|
-
recovery_probe_failed: deepDiagnostics || doctorFix,
|
|
1125
|
-
tool_output_recovery: {
|
|
1126
|
-
ok: false,
|
|
1127
|
-
status: deepDiagnostics || doctorFix ? 'probe_failed' : 'not_checked',
|
|
1128
|
-
blockers: deepDiagnostics || doctorFix ? ['codex_lb_tool_output_recovery_status_probe_failed'] : [],
|
|
1129
|
-
operator_actions: []
|
|
1130
|
-
},
|
|
1131
|
-
error: err?.message || String(err)
|
|
1132
|
-
}));
|
|
1133
|
-
const codexLbRecoveryReady = codexLbRecoveryStatusReady(codexLbProviderStatus, deepDiagnostics || doctorFix);
|
|
1134
|
-
const codexLbRoutingTruth = await codexLbRoutingTruthForStatus(codexLbProviderStatus, {
|
|
1135
|
-
remeasure: deepDiagnostics || doctorFix
|
|
1136
|
-
});
|
|
1137
|
-
const codexLbRoutingReady = !doctorCodexLbRouteExpected(codexLbProviderStatus)
|
|
1138
|
-
|| codexLbRoutingTruthIsActive(codexLbRoutingTruth);
|
|
1139
|
-
const codexLbDivergence = await inspectDoctorCodexLbDivergence({
|
|
1140
|
-
processEnv: process.env,
|
|
1141
|
-
providerStatus: codexLbProviderStatus,
|
|
1142
|
-
fix: doctorFix,
|
|
1143
|
-
...(deps.codexLbLaunchctlBin ? { launchctlBin: deps.codexLbLaunchctlBin } : {}),
|
|
1144
|
-
...(deps.codexLbLaunchPlatform ? { platform: deps.codexLbLaunchPlatform } : {}),
|
|
1145
|
-
...(deps.codexLbLaunchRunProcessImpl ? { runProcessImpl: deps.codexLbLaunchRunProcessImpl } : {})
|
|
1146
|
-
}, deps.codexLbDivergenceDeps || {});
|
|
1147
|
-
const codexLb = {
|
|
1148
|
-
...codexLbCircuit,
|
|
1149
|
-
provider_status: codexLbProviderStatus,
|
|
1150
|
-
tool_output_recovery: codexLbProviderStatus?.tool_output_recovery || null,
|
|
1151
|
-
recovery_ok: codexLbRecoveryReady,
|
|
1152
|
-
routing_truth: codexLbRoutingTruth,
|
|
1153
|
-
routing_ok: codexLbRoutingReady,
|
|
1154
|
-
secret_resolution: codexLbSecretProbe.secret_resolution,
|
|
1155
|
-
legacy_keychain_migration: codexLbSecretProbe.legacy_keychain_migration,
|
|
1156
|
-
divergence: codexLbDivergence
|
|
1157
|
-
};
|
|
774
|
+
const desktopBridge = await inspectDoctorDesktopBridgeStatus({
|
|
775
|
+
processEnv: process.env
|
|
776
|
+
}, { desktopBridgeStatusImpl: deps.desktopBridgeStatusImpl });
|
|
1158
777
|
const providerContext = deepDiagnostics
|
|
1159
778
|
? await resolveProviderContext({ root, route: '$Doctor', serviceTier: process.env.SKS_SERVICE_TIER || 'fast' }).catch((err) => ({
|
|
1160
|
-
schema: 'sks.provider-context.
|
|
779
|
+
schema: 'sks.provider-context.v2',
|
|
1161
780
|
generated_at: new Date().toISOString(),
|
|
1162
781
|
provider: 'unknown',
|
|
1163
782
|
auth_mode: 'unknown',
|
|
@@ -1169,29 +788,35 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
1169
788
|
warnings: [err?.message || String(err)],
|
|
1170
789
|
signals: {
|
|
1171
790
|
openai_api_key_present: false,
|
|
1172
|
-
codex_lb_key_present: false,
|
|
1173
|
-
codex_lb_explicit: false,
|
|
1174
791
|
codex_app_auth_present: false,
|
|
1175
|
-
|
|
792
|
+
desktop_bridge_status_available: false,
|
|
793
|
+
desktop_bridge_managed: false,
|
|
794
|
+
desktop_bridge_ready: false,
|
|
795
|
+
desktop_bridge_provider: null,
|
|
796
|
+
desktop_bridge_native_identity_configured: false,
|
|
797
|
+
desktop_bridge_credential_state: null
|
|
1176
798
|
}
|
|
1177
799
|
}))
|
|
1178
800
|
: {
|
|
1179
|
-
schema: 'sks.provider-context.
|
|
801
|
+
schema: 'sks.provider-context.v2',
|
|
1180
802
|
generated_at: new Date().toISOString(),
|
|
1181
803
|
provider: 'unknown',
|
|
1182
804
|
auth_mode: 'unknown',
|
|
1183
805
|
route: '$Doctor',
|
|
1184
806
|
service_tier: process.env.SKS_SERVICE_TIER || 'fast',
|
|
1185
|
-
source: '
|
|
807
|
+
source: 'unknown',
|
|
1186
808
|
confidence: 'low',
|
|
1187
809
|
conflict: false,
|
|
1188
810
|
warnings: ['provider_context_optional_diagnostic_skipped'],
|
|
1189
811
|
signals: {
|
|
1190
812
|
openai_api_key_present: false,
|
|
1191
|
-
codex_lb_key_present: false,
|
|
1192
|
-
codex_lb_explicit: false,
|
|
1193
813
|
codex_app_auth_present: false,
|
|
1194
|
-
|
|
814
|
+
desktop_bridge_status_available: false,
|
|
815
|
+
desktop_bridge_managed: false,
|
|
816
|
+
desktop_bridge_ready: false,
|
|
817
|
+
desktop_bridge_provider: null,
|
|
818
|
+
desktop_bridge_native_identity_configured: false,
|
|
819
|
+
desktop_bridge_credential_state: null
|
|
1195
820
|
}
|
|
1196
821
|
};
|
|
1197
822
|
const explicitCodexAppUiRepair = flag(args, '--repair-codex-app-ui');
|
|
@@ -1252,7 +877,6 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
1252
877
|
'Run: sks menubar status',
|
|
1253
878
|
'Run: sks menubar install',
|
|
1254
879
|
'Run: sks menubar restart',
|
|
1255
|
-
'Rotate CODEX_LB_API_KEY and OPENROUTER_API_KEY if they were previously exposed in launchd.'
|
|
1256
880
|
],
|
|
1257
881
|
blockers: [err?.message || String(err)],
|
|
1258
882
|
warnings: []
|
|
@@ -1750,7 +1374,7 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
1750
1374
|
codex,
|
|
1751
1375
|
codex_config: codexConfig,
|
|
1752
1376
|
codex_app: codexApp,
|
|
1753
|
-
|
|
1377
|
+
desktop_bridge: desktopBridge,
|
|
1754
1378
|
codex_doctor: authoritativeCodexDoctor,
|
|
1755
1379
|
pre_repair_codex_doctor: preRepairCodexDoctor,
|
|
1756
1380
|
post_repair_codex_doctor: postRepairCodexDoctor,
|
|
@@ -1786,7 +1410,7 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
1786
1410
|
...(codexStartupRepair.manual_actions || []),
|
|
1787
1411
|
...(codexConfigSyntaxRepair?.manual_actions || []),
|
|
1788
1412
|
...(pluginPolicy?.doctor_warnings || []),
|
|
1789
|
-
...(
|
|
1413
|
+
...(desktopBridge.ok === false ? desktopBridge.recovery_actions || [] : []),
|
|
1790
1414
|
...telegramDoctorOperatorActions(telegramRemote)
|
|
1791
1415
|
]
|
|
1792
1416
|
};
|
|
@@ -1874,10 +1498,7 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
1874
1498
|
&& agentRoleConfigRepair.ok !== false
|
|
1875
1499
|
&& openRouterProviderRepair.ok !== false
|
|
1876
1500
|
&& (officialSubagentConfig.blockers || []).length === 0
|
|
1877
|
-
&&
|
|
1878
|
-
&& codexLbDivergence.ok !== false
|
|
1879
|
-
&& codexLbRecoveryReady
|
|
1880
|
-
&& codexLbRoutingReady;
|
|
1501
|
+
&& (!doctorProfileRequiresDesktopBridgeReadiness(doctorProfile) || desktopBridge.ok !== false);
|
|
1881
1502
|
const result = {
|
|
1882
1503
|
schema: 'sks.doctor-status.v3',
|
|
1883
1504
|
elapsed_ms: Date.now() - startedAtMs,
|
|
@@ -1892,11 +1513,10 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
1892
1513
|
not_counted_as_full_doctor: !deepDiagnostics,
|
|
1893
1514
|
root,
|
|
1894
1515
|
arg_warnings: argWarnings,
|
|
1895
|
-
warnings: [...oauthCallbackPortDiagnostic.warnings, ...(
|
|
1516
|
+
warnings: [...oauthCallbackPortDiagnostic.warnings, ...(desktopBridge.warnings || [])],
|
|
1896
1517
|
operator_actions: [
|
|
1897
1518
|
...oauthCallbackOperatorActions,
|
|
1898
|
-
...(
|
|
1899
|
-
...(codexLbDivergence.operator_actions || [])
|
|
1519
|
+
...(desktopBridge.ok === false ? desktopBridge.recovery_actions || [] : [])
|
|
1900
1520
|
],
|
|
1901
1521
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
1902
1522
|
codex,
|
|
@@ -1905,11 +1525,11 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
1905
1525
|
rust,
|
|
1906
1526
|
codex_app: codexApp,
|
|
1907
1527
|
codex_app_ui: codexAppUi,
|
|
1908
|
-
openrouter_provider:
|
|
1528
|
+
openrouter_provider: desktopBridge.providers?.openrouter || null,
|
|
1909
1529
|
sks_menubar: sksMenuBar,
|
|
1910
1530
|
telegram_remote: telegramRemote,
|
|
1911
1531
|
provider_context: providerContext,
|
|
1912
|
-
|
|
1532
|
+
desktop_bridge: desktopBridge,
|
|
1913
1533
|
codex_doctor: authoritativeCodexDoctor,
|
|
1914
1534
|
pre_repair_codex_doctor: preRepairCodexDoctor,
|
|
1915
1535
|
post_repair_codex_doctor: postRepairCodexDoctor,
|
|
@@ -2188,25 +1808,20 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
2188
1808
|
console.log(` warning: ${warning}`);
|
|
2189
1809
|
if (codexCurrentAppDoctor?.fixed?.length)
|
|
2190
1810
|
console.log(` doctor --fix repaired: ${codexCurrentAppDoctor.fixed.join(', ')}`);
|
|
2191
|
-
console.log(`
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
1811
|
+
console.log(`Desktop Bridge: ${desktopBridge.ok ? 'ready' : 'blocked'} (${desktopBridge.status?.readiness?.state || 'unavailable'})`);
|
|
1812
|
+
for (const providerId of ['codex-lb', 'openrouter']) {
|
|
1813
|
+
const provider = desktopBridge.providers?.[providerId];
|
|
1814
|
+
if (!provider)
|
|
1815
|
+
continue;
|
|
1816
|
+
console.log(` ${providerId}: ${provider.enabled ? 'enabled' : 'disabled'}; credential ${provider.credential?.state || 'unknown'} (${provider.credential?.source || 'none'}); endpoint ${provider.endpoint?.configured ? 'configured' : 'missing'}`);
|
|
1817
|
+
}
|
|
1818
|
+
for (const warning of desktopBridge.warnings || [])
|
|
2196
1819
|
console.log(` warning: ${warning}`);
|
|
2197
|
-
for (const
|
|
2198
|
-
console.log(`
|
|
2199
|
-
if (
|
|
2200
|
-
const
|
|
2201
|
-
|
|
2202
|
-
}
|
|
2203
|
-
if (codexLb.tool_output_recovery) {
|
|
2204
|
-
const recovery = codexLb.tool_output_recovery;
|
|
2205
|
-
console.log(` interrupted tool-output recovery: ${recovery.ok ? 'ready' : 'blocked'} (${recovery.observed_version || recovery.status}; minimum ${recovery.minimum_version})`);
|
|
2206
|
-
if (!recovery.ok)
|
|
2207
|
-
for (const action of recovery.operator_actions || [])
|
|
2208
|
-
console.log(` action: ${action}`);
|
|
2209
|
-
}
|
|
1820
|
+
for (const blocker of desktopBridge.blockers || [])
|
|
1821
|
+
console.log(` blocker: ${blocker}`);
|
|
1822
|
+
if (!desktopBridge.ok)
|
|
1823
|
+
for (const action of desktopBridge.recovery_actions || [])
|
|
1824
|
+
console.log(` action: ${action}`);
|
|
2210
1825
|
if (localModel) {
|
|
2211
1826
|
console.log('Local LLM:');
|
|
2212
1827
|
console.log(` enabled: ${localModel.enabled ? 'yes' : 'no'}`);
|
|
@@ -2253,377 +1868,3 @@ async function runDoctor(args = [], root, doctorFix, deps = {}) {
|
|
|
2253
1868
|
if (!result.ok)
|
|
2254
1869
|
process.exitCode = 1;
|
|
2255
1870
|
}
|
|
2256
|
-
export function buildRuntimeReadiness(matrix) {
|
|
2257
|
-
const defaults = matrix?.invocation_defaults || {};
|
|
2258
|
-
const hookPolicy = defaults.hook_evidence_policy || 'unknown-do-not-count';
|
|
2259
|
-
const agentStrategy = defaults.loop_worker_role_strategy || 'message-role';
|
|
2260
|
-
const multiAgentMode = defaults.multi_agent_mode || 'none';
|
|
2261
|
-
const rolloutBudget = defaults.rollout_budget_strategy || 'sks-local-only';
|
|
2262
|
-
const researchSource = defaults.research_source_strategy || 'local-files';
|
|
2263
|
-
const codexNative = matrix?.ok === true ? 'ok' : matrix?.codex_cli?.available ? 'degraded' : 'blocked';
|
|
2264
|
-
const repairActions = [];
|
|
2265
|
-
if (codexNative !== 'ok') {
|
|
2266
|
-
repairActions.push([
|
|
2267
|
-
'Codex Native managed assets: sks doctor',
|
|
2268
|
-
'--fix',
|
|
2269
|
-
'--repair-codex-native',
|
|
2270
|
-
'--yes'
|
|
2271
|
-
].join(' '));
|
|
2272
|
-
}
|
|
2273
|
-
if (matrix?.features?.project_memory?.ok !== true)
|
|
2274
|
-
repairActions.push('Project memory: sks codex-native init-deep --apply --directory-local');
|
|
2275
|
-
return {
|
|
2276
|
-
schema: 'sks.runtime-readiness-story.v1',
|
|
2277
|
-
codex_native: codexNative,
|
|
2278
|
-
loop_mesh: agentStrategy === 'agent_type' ? 'ok' : 'fallback',
|
|
2279
|
-
qa_visual: defaults.qa_visual_review_strategy || 'blocked',
|
|
2280
|
-
research_sources: researchSource,
|
|
2281
|
-
image_followup: defaults.image_followup_strategy || 'blocked',
|
|
2282
|
-
hook_evidence_policy: hookPolicy,
|
|
2283
|
-
agent_role_strategy: agentStrategy,
|
|
2284
|
-
multi_agent_mode: multiAgentMode,
|
|
2285
|
-
rollout_budget_strategy: rolloutBudget,
|
|
2286
|
-
current_time_source: defaults.current_time_source || 'external-clock',
|
|
2287
|
-
overload_retry_policy: defaults.overload_retry_policy || 'generic',
|
|
2288
|
-
notes: [
|
|
2289
|
-
...(hookPolicy !== 'approved-only' ? ['hook-derived evidence will not count'] : []),
|
|
2290
|
-
...(agentStrategy !== 'agent_type' ? ['message-role fallback active'] : []),
|
|
2291
|
-
...(multiAgentMode === 'proactive' ? ['Proactive multi-agent mode is available for Naruto-style routes'] : []),
|
|
2292
|
-
...(rolloutBudget === 'codex-current-shared' ? ['Shared rollout budgeting is available for route proof'] : []),
|
|
2293
|
-
...(researchSource === 'indexed-web-search' ? ['Indexed web search is selected for source-intelligence routes'] : [])
|
|
2294
|
-
],
|
|
2295
|
-
repair_actions: [...new Set(repairActions)]
|
|
2296
|
-
};
|
|
2297
|
-
}
|
|
2298
|
-
function deferredNativeRepair(schema, doctorFix, nextActions) {
|
|
2299
|
-
return {
|
|
2300
|
-
schema,
|
|
2301
|
-
generated_at: nowIso(),
|
|
2302
|
-
ok: true,
|
|
2303
|
-
skipped: true,
|
|
2304
|
-
status: 'deferred_to_explicit_native_capability_probe',
|
|
2305
|
-
attempted: false,
|
|
2306
|
-
apply: doctorFix,
|
|
2307
|
-
recovered: false,
|
|
2308
|
-
blockers: [],
|
|
2309
|
-
next_actions: nextActions,
|
|
2310
|
-
manual_actions: nextActions
|
|
2311
|
-
};
|
|
2312
|
-
}
|
|
2313
|
-
function fallbackCodexNativeFeatureMatrix(codex, blockers = [], warnings = []) {
|
|
2314
|
-
return {
|
|
2315
|
-
schema: 'sks.codex-native-feature-matrix.v1',
|
|
2316
|
-
ok: blockers.length === 0,
|
|
2317
|
-
skipped: blockers.length === 0,
|
|
2318
|
-
codex_cli: { available: Boolean(codex?.bin || codex?.available), version: codex?.version || null, bin: codex?.bin || null },
|
|
2319
|
-
features: {},
|
|
2320
|
-
invocation_defaults: {
|
|
2321
|
-
loop_worker_role_strategy: 'message-role',
|
|
2322
|
-
multi_agent_mode: 'none',
|
|
2323
|
-
rollout_budget_strategy: 'sks-local-only',
|
|
2324
|
-
qa_visual_review_strategy: 'route-gated',
|
|
2325
|
-
research_source_strategy: 'local-files',
|
|
2326
|
-
image_followup_strategy: 'artifact-path',
|
|
2327
|
-
hook_evidence_policy: 'unknown-do-not-count',
|
|
2328
|
-
skill_bridge_strategy: 'cli-only',
|
|
2329
|
-
current_time_source: 'external-clock',
|
|
2330
|
-
overload_retry_policy: 'generic'
|
|
2331
|
-
},
|
|
2332
|
-
blockers,
|
|
2333
|
-
warnings
|
|
2334
|
-
};
|
|
2335
|
-
}
|
|
2336
|
-
async function writeJsonReportFile(file, value) {
|
|
2337
|
-
const fsp = await import('node:fs/promises');
|
|
2338
|
-
const path = await import('node:path');
|
|
2339
|
-
await fsp.mkdir(path.dirname(file), { recursive: true });
|
|
2340
|
-
await fsp.writeFile(file, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
2341
|
-
}
|
|
2342
|
-
function nativeCapabilityStatus(rows, id, fallback) {
|
|
2343
|
-
const row = rows.find((entry) => entry?.id === id);
|
|
2344
|
-
if (!row)
|
|
2345
|
-
return fallback;
|
|
2346
|
-
if (row.after === 'verified' || row.before === 'verified')
|
|
2347
|
-
return 'verified';
|
|
2348
|
-
if (id === 'image_path_exposure') {
|
|
2349
|
-
if (row.before === 'degraded' || row.after === 'degraded' || row.repairability === 'doctor-fix')
|
|
2350
|
-
return 'fallback';
|
|
2351
|
-
return fallback;
|
|
2352
|
-
}
|
|
2353
|
-
if (id === 'app_handoff')
|
|
2354
|
-
return 'unavailable';
|
|
2355
|
-
if (row.repairability === 'manual-required')
|
|
2356
|
-
return 'manual_required';
|
|
2357
|
-
if (row.before === 'degraded' || row.after === 'degraded')
|
|
2358
|
-
return 'degraded';
|
|
2359
|
-
if (row.repairability === 'doctor-fix')
|
|
2360
|
-
return row.after === 'blocked' ? 'blocked' : 'repair_required';
|
|
2361
|
-
if (row.repairability === 'unavailable')
|
|
2362
|
-
return 'unavailable';
|
|
2363
|
-
return fallback;
|
|
2364
|
-
}
|
|
2365
|
-
function uniqueNativeManualActions(rows) {
|
|
2366
|
-
return [...new Set(rows
|
|
2367
|
-
.filter((row) => row?.repairability === 'manual-required' && row?.after !== 'verified')
|
|
2368
|
-
.flatMap((row) => Array.isArray(row.repair_actions) ? row.repair_actions : [])
|
|
2369
|
-
.filter((action) => typeof action === 'string' && action.trim()))];
|
|
2370
|
-
}
|
|
2371
|
-
function doctorSkillStatus(coreSkills) {
|
|
2372
|
-
if (!coreSkills)
|
|
2373
|
-
return 'drift_detected';
|
|
2374
|
-
if (Array.isArray(coreSkills.restored) && coreSkills.restored.length)
|
|
2375
|
-
return 'repaired';
|
|
2376
|
-
if (Array.isArray(coreSkills.blockers) && coreSkills.blockers.length)
|
|
2377
|
-
return 'drift_detected';
|
|
2378
|
-
return 'current';
|
|
2379
|
-
}
|
|
2380
|
-
function doctorDedupeStatus(skillDedupe) {
|
|
2381
|
-
if (!skillDedupe)
|
|
2382
|
-
return 'manual_required';
|
|
2383
|
-
if (Array.isArray(skillDedupe.actions) && skillDedupe.actions.some((action) => action.action === 'quarantined'))
|
|
2384
|
-
return 'repaired';
|
|
2385
|
-
if (Array.isArray(skillDedupe.blockers) && skillDedupe.blockers.length)
|
|
2386
|
-
return 'manual_required';
|
|
2387
|
-
return 'none';
|
|
2388
|
-
}
|
|
2389
|
-
async function codexHomeConfigPath() {
|
|
2390
|
-
const path = await import('node:path');
|
|
2391
|
-
const os = await import('node:os');
|
|
2392
|
-
const home = process.env.CODEX_HOME || path.join(process.env.HOME || os.homedir(), '.codex');
|
|
2393
|
-
return path.join(home, 'config.toml');
|
|
2394
|
-
}
|
|
2395
|
-
async function captureCodexConfigSnapshot() {
|
|
2396
|
-
const fsp = await import('node:fs/promises');
|
|
2397
|
-
const path = await import('node:path');
|
|
2398
|
-
const read = async (p) => {
|
|
2399
|
-
if (!p)
|
|
2400
|
-
return null;
|
|
2401
|
-
try {
|
|
2402
|
-
return await fsp.readFile(p, 'utf8');
|
|
2403
|
-
}
|
|
2404
|
-
catch {
|
|
2405
|
-
return null;
|
|
2406
|
-
}
|
|
2407
|
-
};
|
|
2408
|
-
const root = await projectRoot();
|
|
2409
|
-
const projectPath = root ? path.join(root, '.codex', 'config.toml') : null;
|
|
2410
|
-
const homePath = await codexHomeConfigPath();
|
|
2411
|
-
return {
|
|
2412
|
-
project_path: projectPath,
|
|
2413
|
-
project_text: await read(projectPath),
|
|
2414
|
-
home_path: homePath,
|
|
2415
|
-
home_text: await read(homePath)
|
|
2416
|
-
};
|
|
2417
|
-
}
|
|
2418
|
-
async function writeFixMigrationJournal(root, preFix, configRepair, setupRepair) {
|
|
2419
|
-
if (!preFix)
|
|
2420
|
-
return null;
|
|
2421
|
-
const fsp = await import('node:fs/promises');
|
|
2422
|
-
const read = async (p) => {
|
|
2423
|
-
if (!p)
|
|
2424
|
-
return null;
|
|
2425
|
-
try {
|
|
2426
|
-
return await fsp.readFile(p, 'utf8');
|
|
2427
|
-
}
|
|
2428
|
-
catch {
|
|
2429
|
-
return null;
|
|
2430
|
-
}
|
|
2431
|
-
};
|
|
2432
|
-
const projectAfter = await read(preFix.project_path);
|
|
2433
|
-
const homeAfter = await read(preFix.home_path);
|
|
2434
|
-
const structureRepairs = Array.isArray(configRepair?.structure_repairs) ? configRepair.structure_repairs : [];
|
|
2435
|
-
const projectStructure = structureRepairs.find((repair) => repair.scope === 'project');
|
|
2436
|
-
const homeStructure = structureRepairs.find((repair) => repair.scope === 'codex_home');
|
|
2437
|
-
const events = [
|
|
2438
|
-
{
|
|
2439
|
-
step: 'doctor_fix_project_config',
|
|
2440
|
-
target: preFix.project_path || '.codex/config.toml',
|
|
2441
|
-
beforeHash: preFix.project_text != null ? hashConfigText(preFix.project_text) : null,
|
|
2442
|
-
afterHash: projectAfter != null ? hashConfigText(projectAfter) : null,
|
|
2443
|
-
backupPath: setupRepair?.config_backup_path || projectStructure?.backup_path || configRepair?.policy?.backup_path || null
|
|
2444
|
-
},
|
|
2445
|
-
{
|
|
2446
|
-
step: 'doctor_fix_codex_home_config',
|
|
2447
|
-
target: preFix.home_path || '~/.codex/config.toml',
|
|
2448
|
-
beforeHash: preFix.home_text != null ? hashConfigText(preFix.home_text) : null,
|
|
2449
|
-
afterHash: homeAfter != null ? hashConfigText(homeAfter) : null,
|
|
2450
|
-
backupPath: homeStructure?.backup_path || null
|
|
2451
|
-
}
|
|
2452
|
-
].filter((event) => event.beforeHash != null || event.afterHash != null);
|
|
2453
|
-
if (!events.length)
|
|
2454
|
-
return null;
|
|
2455
|
-
return appendMigrationEvents(root, events);
|
|
2456
|
-
}
|
|
2457
|
-
async function backupProjectConfigBeforeFix() {
|
|
2458
|
-
try {
|
|
2459
|
-
const fsp = await import('node:fs/promises');
|
|
2460
|
-
const path = await import('node:path');
|
|
2461
|
-
const root = await projectRoot();
|
|
2462
|
-
if (!root)
|
|
2463
|
-
return null;
|
|
2464
|
-
const configPath = path.join(root, '.codex', 'config.toml');
|
|
2465
|
-
if (!(await exists(configPath)))
|
|
2466
|
-
return null;
|
|
2467
|
-
const text = await fsp.readFile(configPath, 'utf8');
|
|
2468
|
-
const backupPath = `${configPath}.doctor-pre-fix-${Date.now().toString(36)}.bak`;
|
|
2469
|
-
await fsp.writeFile(backupPath, text);
|
|
2470
|
-
return backupPath;
|
|
2471
|
-
}
|
|
2472
|
-
catch {
|
|
2473
|
-
return null;
|
|
2474
|
-
}
|
|
2475
|
-
}
|
|
2476
|
-
function installScopeFromArgs(args = []) {
|
|
2477
|
-
if (flag(args, '--project'))
|
|
2478
|
-
return 'project';
|
|
2479
|
-
if (flag(args, '--global'))
|
|
2480
|
-
return 'global';
|
|
2481
|
-
const index = args.indexOf('--install-scope');
|
|
2482
|
-
return normalizeInstallScope(index >= 0 && args[index + 1] ? args[index + 1] : 'global');
|
|
2483
|
-
}
|
|
2484
|
-
function isMigrationUserOwnedProjectConfigBlocker(blocker) {
|
|
2485
|
-
const value = String(blocker || '').trim();
|
|
2486
|
-
return value === 'user_owned_file_without_sks_marker'
|
|
2487
|
-
|| value.endsWith(':user_owned_file_without_sks_marker')
|
|
2488
|
-
|| value === 'config_write_guard:blocked_unmanaged_project_config'
|
|
2489
|
-
|| value.endsWith(':config_write_guard:blocked_unmanaged_project_config');
|
|
2490
|
-
}
|
|
2491
|
-
function readOption(args = [], name, fallback = null) {
|
|
2492
|
-
const index = args.indexOf(name);
|
|
2493
|
-
return index >= 0 && args[index + 1] ? args[index + 1] : fallback;
|
|
2494
|
-
}
|
|
2495
|
-
export function buildCodexAppUiDiagnosticFailure(apply, error) {
|
|
2496
|
-
return {
|
|
2497
|
-
schema: 'sks.codex-app-fast-ui-repair.v1',
|
|
2498
|
-
ok: false,
|
|
2499
|
-
apply,
|
|
2500
|
-
safe_auto_apply: false,
|
|
2501
|
-
requires_confirmation: true,
|
|
2502
|
-
fast_selector: 'manual_action_required',
|
|
2503
|
-
provider_selector: 'manual_action_required',
|
|
2504
|
-
host_owned_config: 'diagnostic_failed',
|
|
2505
|
-
next_action: 'Review Codex App UI config manually.',
|
|
2506
|
-
actions: [],
|
|
2507
|
-
blockers: [error instanceof Error ? error.message : String(error)]
|
|
2508
|
-
};
|
|
2509
|
-
}
|
|
2510
|
-
export function formatCodexDoctorConsoleStatus(report) {
|
|
2511
|
-
if (!report || report.available !== true)
|
|
2512
|
-
return 'unavailable';
|
|
2513
|
-
return report.disposition || (report.exit_code === 0 ? 'pass' : 'warn');
|
|
2514
|
-
}
|
|
2515
|
-
export function sksMenuBarRunningVersionConsoleLines(status) {
|
|
2516
|
-
const runningVersion = status?.running_process?.package_version
|
|
2517
|
-
|| status?.menubar_version_probe?.running_version
|
|
2518
|
-
|| null;
|
|
2519
|
-
const runningPid = status?.running_process?.pid ?? status?.menubar_version_probe?.pid ?? null;
|
|
2520
|
-
if (typeof runningVersion !== 'string' || !runningVersion || !Number.isInteger(runningPid) || runningPid <= 0) {
|
|
2521
|
-
return [];
|
|
2522
|
-
}
|
|
2523
|
-
const expectedVersion = status?.menubar_version_probe?.expected_version
|
|
2524
|
-
|| status?.action_target?.expected_version
|
|
2525
|
-
|| status?.package_version
|
|
2526
|
-
|| null;
|
|
2527
|
-
const installedVersion = status?.installed_version || status?.build_stamp?.package_version || null;
|
|
2528
|
-
return [
|
|
2529
|
-
` RUNNING: version ${runningVersion} (PID ${runningPid})`,
|
|
2530
|
-
...(typeof expectedVersion === 'string' && expectedVersion && expectedVersion !== runningVersion
|
|
2531
|
-
? [` expected: version ${expectedVersion}`]
|
|
2532
|
-
: []),
|
|
2533
|
-
...(typeof installedVersion === 'string' && installedVersion && installedVersion !== runningVersion
|
|
2534
|
-
? [` installed: version ${installedVersion}`]
|
|
2535
|
-
: [])
|
|
2536
|
-
];
|
|
2537
|
-
}
|
|
2538
|
-
export async function rebootstrapSksMenuBarLaunchdForDoctorFix(input, deps = {}) {
|
|
2539
|
-
const env = input.env || process.env;
|
|
2540
|
-
const status = input.status;
|
|
2541
|
-
const expectedVersion = status?.menubar_version_probe?.expected_version
|
|
2542
|
-
|| status?.action_target?.expected_version
|
|
2543
|
-
|| status?.installed_version
|
|
2544
|
-
|| null;
|
|
2545
|
-
const warningOnlyVerifiedProcess = input.fix
|
|
2546
|
-
&& !sksMenuBarRestartDeferred(env)
|
|
2547
|
-
&& status?.launchd?.checked === true
|
|
2548
|
-
&& status?.launchd?.ok === false
|
|
2549
|
-
&& Array.isArray(status?.warnings)
|
|
2550
|
-
&& status.warnings.includes('launchd_not_running_process_active')
|
|
2551
|
-
&& !(Array.isArray(status?.blockers) && status.blockers.includes('launchd_not_running'))
|
|
2552
|
-
&& status?.running_process?.ok === true
|
|
2553
|
-
&& typeof expectedVersion === 'string'
|
|
2554
|
-
&& status.running_process.package_version === expectedVersion;
|
|
2555
|
-
if (!warningOnlyVerifiedProcess) {
|
|
2556
|
-
return { attempted: false, ok: true, status, restart: null };
|
|
2557
|
-
}
|
|
2558
|
-
const paths = sksMenuBarPaths(input.home || env.HOME, input.root);
|
|
2559
|
-
const restartImpl = deps.restartLaunchAgentImpl || restartLaunchAgent;
|
|
2560
|
-
const inspectImpl = deps.inspectSksMenuBarStatusImpl || inspectSksMenuBarStatus;
|
|
2561
|
-
const restart = await restartImpl(paths, env).catch((error) => ({
|
|
2562
|
-
ok: false,
|
|
2563
|
-
error: error instanceof Error ? error.message : String(error)
|
|
2564
|
-
}));
|
|
2565
|
-
if (restart?.ok !== true) {
|
|
2566
|
-
const detail = restart?.error ? `:${restart.error}` : '';
|
|
2567
|
-
return {
|
|
2568
|
-
attempted: true,
|
|
2569
|
-
ok: false,
|
|
2570
|
-
restart,
|
|
2571
|
-
status: {
|
|
2572
|
-
...status,
|
|
2573
|
-
ok: false,
|
|
2574
|
-
blockers: [...new Set([...(status?.blockers || []), `launchd_rebootstrap_failed${detail}`])]
|
|
2575
|
-
}
|
|
2576
|
-
};
|
|
2577
|
-
}
|
|
2578
|
-
const refreshed = await inspectImpl({
|
|
2579
|
-
root: input.root,
|
|
2580
|
-
...(input.home ? { home: input.home } : {}),
|
|
2581
|
-
...(input.env ? { env: input.env } : {})
|
|
2582
|
-
}).catch((error) => ({
|
|
2583
|
-
...status,
|
|
2584
|
-
ok: false,
|
|
2585
|
-
blockers: [...new Set([
|
|
2586
|
-
...(status?.blockers || []),
|
|
2587
|
-
`launchd_rebootstrap_status_failed:${error instanceof Error ? error.message : String(error)}`
|
|
2588
|
-
])]
|
|
2589
|
-
}));
|
|
2590
|
-
if (refreshed?.launchd?.checked !== true || refreshed?.launchd?.ok !== true) {
|
|
2591
|
-
return {
|
|
2592
|
-
attempted: true,
|
|
2593
|
-
ok: false,
|
|
2594
|
-
restart,
|
|
2595
|
-
status: {
|
|
2596
|
-
...refreshed,
|
|
2597
|
-
ok: false,
|
|
2598
|
-
blockers: [...new Set([...(refreshed?.blockers || []), 'launchd_rebootstrap_not_confirmed'])]
|
|
2599
|
-
}
|
|
2600
|
-
};
|
|
2601
|
-
}
|
|
2602
|
-
return { attempted: true, ok: true, status: refreshed, restart };
|
|
2603
|
-
}
|
|
2604
|
-
function mergeObservedCodexStartupWarnings(startupRepair, codexDoctor) {
|
|
2605
|
-
const text = `${codexDoctor?.stdout_tail || ''}\n${codexDoctor?.stderr_tail || ''}`;
|
|
2606
|
-
const manual = new Set(Array.isArray(startupRepair?.manual_actions) ? startupRepair.manual_actions : []);
|
|
2607
|
-
const warnings = new Set(Array.isArray(startupRepair?.warnings) ? startupRepair.warnings : []);
|
|
2608
|
-
const blockers = new Set(Array.isArray(startupRepair?.blockers) ? startupRepair.blockers : []);
|
|
2609
|
-
if (/codex_apps[\s\S]{0,500}token_expired|token_expired[\s\S]{0,500}codex_apps/i.test(text)) {
|
|
2610
|
-
manual.add('Codex Apps MCP token is expired; sign in to Codex App/CLI again so the connector can mint a fresh token.');
|
|
2611
|
-
warnings.add('codex_apps_token_expired_observed');
|
|
2612
|
-
blockers.add('codex_apps_token_expired_manual_reauth_required');
|
|
2613
|
-
}
|
|
2614
|
-
if (/SUPABASE_ACCESS_TOKEN[\s\S]{0,500}mcp server ['"`]?supabase['"`]?|mcp server ['"`]?supabase['"`]?[\s\S]{0,500}SUPABASE_ACCESS_TOKEN/i.test(text)) {
|
|
2615
|
-
manual.add('Supabase MCP uses SUPABASE_ACCESS_TOKEN but the variable is unset; export the token or migrate that server to a read-only remote URL.');
|
|
2616
|
-
warnings.add('supabase_access_token_missing_observed');
|
|
2617
|
-
blockers.add('supabase_access_token_missing_manual_auth_required');
|
|
2618
|
-
}
|
|
2619
|
-
if (/node_repl[\s\S]{0,500}No such file or directory|No such file or directory[\s\S]{0,500}node_repl/i.test(text)) {
|
|
2620
|
-
warnings.add('node_repl_missing_command_observed');
|
|
2621
|
-
}
|
|
2622
|
-
return {
|
|
2623
|
-
...startupRepair,
|
|
2624
|
-
ok: blockers.size === 0 && startupRepair?.ok !== false,
|
|
2625
|
-
manual_actions: [...manual],
|
|
2626
|
-
warnings: [...warnings],
|
|
2627
|
-
blockers: [...blockers]
|
|
2628
|
-
};
|
|
2629
|
-
}
|