sneakoscope 5.8.0 → 5.10.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 +1 -1
- package/config/competitor-scorecard-baseline.json +97 -0
- package/config/perf-budgets.v1.json +10 -0
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/bin/fast-inline.js +147 -0
- package/dist/bin/install.js +1 -2
- package/dist/bin/package.json +1 -0
- package/dist/bin/sks-dispatch.js +55 -0
- package/dist/bin/sks.js +10 -30
- package/dist/cli/command-manifest-lite.js +129 -0
- package/dist/cli/command-registry.js +1 -1
- package/dist/cli/commands-fast.js +29 -0
- package/dist/cli/help-fast.js +7 -9
- package/dist/cli/root-fast.js +48 -0
- package/dist/cli/router.js +16 -9
- package/dist/cli/super-search-command.js +5 -19
- package/dist/commands/doctor.js +243 -65
- package/dist/config/skills-manifest.json +57 -57
- package/dist/core/agents/agent-orchestrator.js +10 -3
- package/dist/core/agents/agent-worker-pipeline.js +9 -6
- package/dist/core/agents/parallel-runtime-proof.js +30 -3
- package/dist/core/agents/parallel-write-fixture.js +301 -0
- package/dist/core/codex-control/codex-fake-sdk-adapter.js +11 -1
- package/dist/core/codex-control/codex-reliability-shield.js +13 -1
- package/dist/core/codex-control/codex-sdk-adapter.js +49 -8
- package/dist/core/codex-control/codex-sdk-config-policy.js +1 -1
- package/dist/core/codex-control/codex-sdk-env-policy.js +10 -0
- package/dist/core/codex-control/codex-task-runner.js +1 -0
- package/dist/core/codex-control/schemas/agent-worker-result.schema.js +66 -11
- package/dist/core/commands/basic-cli.js +16 -7
- package/dist/core/commands/gc-command.js +45 -1
- package/dist/core/doctor/doctor-idempotence.js +93 -0
- package/dist/core/errors/blocker-humanizer.js +13 -0
- package/dist/core/errors/next-action-map.js +56 -0
- package/dist/core/fsx.js +7 -4
- package/dist/core/git/git-worktree-cleanup.js +27 -0
- package/dist/core/git/git-worktree-merge-queue.js +120 -37
- package/dist/core/install/installed-package-smoke.js +121 -0
- package/dist/core/naruto/naruto-active-pool.js +6 -2
- package/dist/core/naruto/naruto-real-worker-child.js +2 -2
- package/dist/core/perf/fsx-hotpath.js +63 -0
- package/dist/core/perf/import-graph-budget.js +111 -0
- package/dist/core/perf/perf-budget.js +192 -0
- package/dist/core/perf/performance-profiler.js +109 -0
- package/dist/core/provider/provider-self-heal.js +152 -0
- package/dist/core/quality/competitor-scorecard.js +116 -0
- package/dist/core/release/gate-timing.js +105 -0
- package/dist/core/release/release-gate-hermetic-env.js +2 -0
- package/dist/core/retention/retention-budget.js +62 -0
- package/dist/core/retention.js +160 -2
- package/dist/core/routes/diagnostic-allowlist.js +2 -2
- package/dist/core/routes/dollar-manifest-lite.js +85 -0
- package/dist/core/routes.js +31 -24
- package/dist/core/structured-output-adapter.js +1 -1
- package/dist/core/super-search/doctor.js +97 -0
- package/dist/core/super-search/local-http-smoke.js +98 -0
- package/dist/core/super-search/runtime-helpers.js +120 -8
- package/dist/core/super-search/runtime.js +43 -2
- package/dist/core/update-check.js +44 -2
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-fast-mode-default-check.js +10 -1
- package/dist/scripts/build-dist.js +32 -0
- package/dist/scripts/codex-control-stream-idle-watchdog-check.js +17 -1
- package/dist/scripts/command-performance-scorecard-check.js +86 -0
- package/dist/scripts/competitor-scorecard-check.js +25 -0
- package/dist/scripts/doctor-fastpath-check.js +19 -0
- package/dist/scripts/doctor-idempotence-check.js +8 -0
- package/dist/scripts/dollar-performance-scorecard-check.js +60 -0
- package/dist/scripts/fsx-hotpath-check.js +11 -0
- package/dist/scripts/gate-timing-check.js +16 -0
- package/dist/scripts/high-risk-contracts-check.js +24 -0
- package/dist/scripts/hook-latency-quantum-check.js +122 -0
- package/dist/scripts/import-graph-budget-check.js +11 -0
- package/dist/scripts/installed-package-smoke-check.js +12 -0
- package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +2 -0
- package/dist/scripts/naruto-codex-e2e-check.js +100 -0
- package/dist/scripts/package-published-contract-check.js +7 -0
- package/dist/scripts/packlist-performance-check.js +31 -3
- package/dist/scripts/parallel-production-smoke-check.js +21 -0
- package/dist/scripts/perf-budget-check.js +14 -0
- package/dist/scripts/performance-baseline-check.js +12 -0
- package/dist/scripts/performance-improvement-report-check.js +58 -0
- package/dist/scripts/quantum-baseline-report.js +38 -0
- package/dist/scripts/release-check-stamp.js +117 -16
- package/dist/scripts/release-gate-dag-runner-check.js +5 -0
- package/dist/scripts/release-gate-dag-runner.js +15 -0
- package/dist/scripts/release-runner-efficiency-check.js +15 -0
- package/dist/scripts/retention-apply-smoke-check.js +21 -0
- package/dist/scripts/retention-budget-check.js +8 -0
- package/dist/scripts/retention-dry-run-check.js +10 -0
- package/dist/scripts/route-intent-regression-check.js +44 -0
- package/dist/scripts/super-search-live-smoke-check.js +117 -0
- package/dist/scripts/super-search-local-http-smoke-check.js +18 -0
- package/dist/scripts/super-search-offline-contract-check.js +45 -0
- package/dist/scripts/update-fastpath-check.js +30 -0
- package/dist/scripts/update-first-command-migration-check.js +2 -3
- package/package.json +51 -30
- package/dist/scripts/check-source-runtime.js +0 -4
- package/dist/scripts/codex-0-134-official-compat-report.js +0 -110
- package/dist/scripts/gpt-image-2-real-file-smoke.js +0 -448
- package/dist/scripts/loop-artifact-paths-check.js +0 -3
- package/dist/scripts/loop-blocker-check.js +0 -15
- package/dist/scripts/loop-cli-check.js +0 -3
- package/dist/scripts/loop-cli-registry-check.js +0 -3
- package/dist/scripts/loop-concurrency-budget-check.js +0 -3
- package/dist/scripts/loop-concurrency-budget-runtime-check.js +0 -3
- package/dist/scripts/loop-continuation-enforcer-check.js +0 -4
- package/dist/scripts/loop-decomposer-check.js +0 -3
- package/dist/scripts/loop-execution-profile-routing-check.js +0 -4
- package/dist/scripts/loop-final-arbiter-contract-check.js +0 -3
- package/dist/scripts/loop-fixture-policy-check.js +0 -3
- package/dist/scripts/loop-fixture-safety-check.js +0 -3
- package/dist/scripts/loop-gate-fixture-guard-check.js +0 -3
- package/dist/scripts/loop-gate-ladder-check.js +0 -3
- package/dist/scripts/loop-gate-runner-check.js +0 -3
- package/dist/scripts/loop-gate-selector-check.js +0 -3
- package/dist/scripts/loop-gpt-final-contract-crossref-check.js +0 -3
- package/dist/scripts/loop-gpt-final-fixture-guard-check.js +0 -3
- package/dist/scripts/loop-gpt-final-gate-contract-check.js +0 -3
- package/dist/scripts/loop-integration-finalizer-check.js +0 -3
- package/dist/scripts/loop-integration-merge-strategy-check.js +0 -3
- package/dist/scripts/loop-interrupt-registry-check.js +0 -3
- package/dist/scripts/loop-lease-check.js +0 -3
- package/dist/scripts/loop-merge-strategy-check.js +0 -3
- package/dist/scripts/loop-mutation-ledger-check.js +0 -3
- package/dist/scripts/loop-observability-check.js +0 -3
- package/dist/scripts/loop-owner-inference-check.js +0 -3
- package/dist/scripts/loop-planner-check.js +0 -3
- package/dist/scripts/loop-planner-project-memory-check.js +0 -4
- package/dist/scripts/loop-planner-project-memory-deep-check.js +0 -4
- package/dist/scripts/loop-proof-check.js +0 -3
- package/dist/scripts/loop-proof-summary-cli-check.js +0 -3
- package/dist/scripts/loop-risk-classifier-check.js +0 -3
- package/dist/scripts/loop-runtime-check.js +0 -3
- package/dist/scripts/loop-scheduler-check.js +0 -3
- package/dist/scripts/loop-schema-check.js +0 -3
- package/dist/scripts/loop-side-effect-final-arbiter-check.js +0 -3
- package/dist/scripts/loop-side-effect-scanner-check.js +0 -3
- package/dist/scripts/loop-state-check.js +0 -3
- package/dist/scripts/loop-status-proof-ux-check.js +0 -3
- package/dist/scripts/loop-worker-fixture-guard-check.js +0 -3
- package/dist/scripts/loop-worker-handle-registration-check.js +0 -3
- package/dist/scripts/loop-worker-interrupt-check.js +0 -3
- package/dist/scripts/loop-worktree-policy-check.js +0 -3
- package/dist/scripts/loop-zellij-ui-check.js +0 -3
- package/dist/scripts/official-docs-compat-report.js +0 -304
- package/dist/scripts/readme-architecture-imagegen-official-check.js +0 -448
- package/dist/scripts/release-metadata-1-16-check.js +0 -81
- package/dist/scripts/release-metadata-1-17-check.js +0 -51
- package/dist/scripts/release-metadata-1-19-check.js +0 -479
- package/dist/scripts/uninstall-inventory-check.js +0 -3
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
export function rootJsonFast(cwd = process.cwd()) {
|
|
3
|
+
const project = findProjectRootSync(cwd);
|
|
4
|
+
const global = joinPath(process.env.HOME || process.env.USERPROFILE || cwd, '.sneakoscope');
|
|
5
|
+
const active = project || global;
|
|
6
|
+
console.log(JSON.stringify({
|
|
7
|
+
cwd,
|
|
8
|
+
mode: project ? 'project' : 'global',
|
|
9
|
+
active_root: active,
|
|
10
|
+
project_root: project,
|
|
11
|
+
global_root: global,
|
|
12
|
+
using_global_root: !project
|
|
13
|
+
}, null, 2));
|
|
14
|
+
}
|
|
15
|
+
function findProjectRootSync(start) {
|
|
16
|
+
let dir = normalizeStart(start);
|
|
17
|
+
for (;;) {
|
|
18
|
+
if (fs.existsSync(joinPath(dir, '.sneakoscope')))
|
|
19
|
+
return dir;
|
|
20
|
+
if (fs.existsSync(joinPath(dir, 'AGENTS.md')) && fs.existsSync(joinPath(dir, 'package.json')))
|
|
21
|
+
return dir;
|
|
22
|
+
const parent = parentDir(dir);
|
|
23
|
+
if (parent === dir)
|
|
24
|
+
return null;
|
|
25
|
+
dir = parent;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function normalizeStart(start) {
|
|
29
|
+
const value = stripTrailingSlash(start || process.cwd());
|
|
30
|
+
if (value.startsWith('/'))
|
|
31
|
+
return value || '/';
|
|
32
|
+
return joinPath(process.cwd(), value);
|
|
33
|
+
}
|
|
34
|
+
function joinPath(left, right) {
|
|
35
|
+
const base = stripTrailingSlash(left || '/');
|
|
36
|
+
return `${base === '/' ? '' : base}/${right}`;
|
|
37
|
+
}
|
|
38
|
+
function parentDir(value) {
|
|
39
|
+
const dir = stripTrailingSlash(value);
|
|
40
|
+
if (dir === '/')
|
|
41
|
+
return dir;
|
|
42
|
+
const index = dir.lastIndexOf('/');
|
|
43
|
+
return index <= 0 ? '/' : dir.slice(0, index);
|
|
44
|
+
}
|
|
45
|
+
function stripTrailingSlash(value) {
|
|
46
|
+
return value.replace(/\/+$/, '') || '/';
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=root-fast.js.map
|
package/dist/cli/router.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { COMMAND_ALIASES_LITE, COMMAND_MANIFEST_BY_NAME, COMMAND_NAME_SET, } from './command-manifest-lite.js';
|
|
2
2
|
import { detectGlobalMode, glmWithoutMadResult } from './global-mode-router.js';
|
|
3
|
-
import { ensureCurrentMigrationBeforeCommand } from '../core/update/update-migration-state.js';
|
|
4
|
-
import { projectRoot, readJson } from '../core/fsx.js';
|
|
5
|
-
import { stateFile } from '../core/mission.js';
|
|
6
3
|
export function isCommandName(value) {
|
|
7
|
-
return
|
|
4
|
+
return COMMAND_NAME_SET.has(value);
|
|
8
5
|
}
|
|
9
6
|
export function normalizeCommand(args = []) {
|
|
10
7
|
const cmd = args[0];
|
|
11
8
|
if (!cmd)
|
|
12
9
|
return { command: null, rawCommand: null, aliasTarget: null, args: [...args] };
|
|
13
|
-
const mapped = cmd in
|
|
10
|
+
const mapped = cmd in COMMAND_ALIASES_LITE ? COMMAND_ALIASES_LITE[cmd] : cmd;
|
|
14
11
|
const rest = args.slice(1);
|
|
15
12
|
const command = isCommandName(mapped) ? mapped : null;
|
|
16
13
|
return {
|
|
@@ -78,13 +75,14 @@ async function dispatchInner(argv) {
|
|
|
78
75
|
};
|
|
79
76
|
return result;
|
|
80
77
|
}
|
|
81
|
-
const entry =
|
|
78
|
+
const entry = COMMAND_MANIFEST_BY_NAME[command];
|
|
82
79
|
const commandGate = await ensureActiveRouteCommandGate(command, rest);
|
|
83
80
|
if (!commandGate.ok) {
|
|
84
81
|
console.error(commandGate.message);
|
|
85
82
|
process.exitCode = 1;
|
|
86
83
|
return commandGate;
|
|
87
84
|
}
|
|
85
|
+
const { ensureCurrentMigrationBeforeCommand } = await import('../core/update/update-migration-state.js');
|
|
88
86
|
const migrationGate = await ensureCurrentMigrationBeforeCommand({
|
|
89
87
|
command,
|
|
90
88
|
args: rest,
|
|
@@ -105,13 +103,15 @@ async function dispatchInner(argv) {
|
|
|
105
103
|
process.exitCode = 1;
|
|
106
104
|
return migrationGate;
|
|
107
105
|
}
|
|
108
|
-
const
|
|
106
|
+
const { COMMANDS } = await import('./command-registry.js');
|
|
107
|
+
const commandEntry = COMMANDS[command];
|
|
108
|
+
const mod = await commandEntry.lazy();
|
|
109
109
|
if (typeof mod.run !== 'function')
|
|
110
110
|
throw new Error(`Command ${command} must export run(command, args)`);
|
|
111
111
|
return mod.run(rawCommand || command, rest);
|
|
112
112
|
}
|
|
113
113
|
async function ensureActiveRouteCommandGate(command, args) {
|
|
114
|
-
const entry =
|
|
114
|
+
const entry = COMMAND_MANIFEST_BY_NAME[command];
|
|
115
115
|
if (command === 'route' || entry.readonly === true || entry.allowedDuringActiveRoute === true && entry.mutatesRouteState !== true) {
|
|
116
116
|
return { ok: true, status: 'allowed' };
|
|
117
117
|
}
|
|
@@ -119,6 +119,13 @@ async function ensureActiveRouteCommandGate(command, args) {
|
|
|
119
119
|
return { ok: true, status: 'allowed' };
|
|
120
120
|
if (safeReadOnlySubcommand(args))
|
|
121
121
|
return { ok: true, status: 'allowed_status_subcommand' };
|
|
122
|
+
if (process.env.SKS_TEST_ISOLATION === '1' && process.env.SKS_RELEASE_FIXTURE_ACTIVE_ROUTE_BYPASS === '1') {
|
|
123
|
+
return { ok: true, status: 'allowed_release_fixture_isolation' };
|
|
124
|
+
}
|
|
125
|
+
const [{ projectRoot, readJson }, { stateFile }] = await Promise.all([
|
|
126
|
+
import('../core/fsx.js'),
|
|
127
|
+
import('../core/mission.js')
|
|
128
|
+
]);
|
|
122
129
|
const root = await projectRoot(process.cwd()).catch(() => process.cwd());
|
|
123
130
|
const state = await readJson(stateFile(root), {}).catch(() => ({}));
|
|
124
131
|
if (!activeRouteStateBlocksCommand(state))
|
|
@@ -3,6 +3,7 @@ import os from 'node:os';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
import { runSuperSearch } from '../core/super-search/index.js';
|
|
6
|
+
import { buildSuperSearchDoctorReport, printSuperSearchDoctorReport } from '../core/super-search/doctor.js';
|
|
6
7
|
import { evaluateLocalGate } from '../core/commands/route-success-helpers.js';
|
|
7
8
|
import { evaluateRealEvidencePolicy } from '../core/verification/real-evidence-policy.js';
|
|
8
9
|
export async function superSearchCommand(sub = 'help', args = []) {
|
|
@@ -37,6 +38,7 @@ async function runCommand(args) {
|
|
|
37
38
|
const result = await runSuperSearch({
|
|
38
39
|
missionDir,
|
|
39
40
|
query,
|
|
41
|
+
allowLocalFetch: args.includes('--allow-local'),
|
|
40
42
|
...(mode ? { mode } : {})
|
|
41
43
|
});
|
|
42
44
|
const gate = await evaluateSuperSearchGate(missionDir);
|
|
@@ -61,24 +63,8 @@ async function runCommand(args) {
|
|
|
61
63
|
}
|
|
62
64
|
async function doctorCommand(args) {
|
|
63
65
|
const json = args.includes('--json');
|
|
64
|
-
const report =
|
|
65
|
-
|
|
66
|
-
ok: true,
|
|
67
|
-
core_ready: true,
|
|
68
|
-
xai_required: false,
|
|
69
|
-
optional: {
|
|
70
|
-
context7: 'external_runtime_optional_by_intent',
|
|
71
|
-
codex_web: process.env.SKS_CODEX_WEB_SEARCH_AVAILABLE === '1' || process.env.CODEX_WEB_SEARCH_AVAILABLE === '1' ? 'available' : 'not_bound',
|
|
72
|
-
authenticated_chrome: 'operator_consented_optional',
|
|
73
|
-
official_x_api: 'credentials_optional_not_required'
|
|
74
|
-
},
|
|
75
|
-
blockers: [],
|
|
76
|
-
warnings: []
|
|
77
|
-
};
|
|
78
|
-
if (json)
|
|
79
|
-
console.log(JSON.stringify(report, null, 2));
|
|
80
|
-
else
|
|
81
|
-
console.log('Super-Search doctor: core ready; xAI/Grok is not required.');
|
|
66
|
+
const report = await buildSuperSearchDoctorReport(args);
|
|
67
|
+
printSuperSearchDoctorReport(report, json);
|
|
82
68
|
return report;
|
|
83
69
|
}
|
|
84
70
|
async function inspectCommand(action, args) {
|
|
@@ -153,7 +139,7 @@ function positional(args) {
|
|
|
153
139
|
if (!value)
|
|
154
140
|
continue;
|
|
155
141
|
if (value.startsWith('--')) {
|
|
156
|
-
if (value !== '--json')
|
|
142
|
+
if (value !== '--json' && value !== '--allow-local')
|
|
157
143
|
i++;
|
|
158
144
|
continue;
|
|
159
145
|
}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -8,60 +8,196 @@ import { getCodexInfo } from '../core/codex-adapter.js';
|
|
|
8
8
|
import { rustInfo } from '../core/rust-accelerator.js';
|
|
9
9
|
import { codexAppIntegrationStatus } from '../core/codex-app.js';
|
|
10
10
|
import { codexLbMetrics, readCodexLbCircuit } from '../core/codex-lb-circuit.js';
|
|
11
|
-
import { ensureGlobalCodexSkillsDuringInstall, ensureGlobalCodexFastModeDuringInstall } from '../cli/install-helpers.js';
|
|
12
11
|
import { normalizeInstallScope } from '../core/init.js';
|
|
13
12
|
import { inspectCodexConfigReadability } from '../core/codex/codex-config-readability.js';
|
|
14
|
-
import { repairCodexConfigEperm } from '../core/codex/codex-config-eperm-repair.js';
|
|
15
|
-
import { writeDoctorReadinessMatrix } from '../core/doctor/doctor-readiness-matrix.js';
|
|
16
|
-
import { runCodexDoctorBridge, compareCodexDoctorBridge } from '../core/doctor/codex-doctor-bridge.js';
|
|
17
|
-
import { cleanDuplicateGlobalSksInstalls } from '../core/doctor/global-sks-install-cleanup.js';
|
|
18
13
|
import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
|
|
19
14
|
import { inventoryCodexPermissionProfiles } from '../core/codex/codex-permission-profiles.js';
|
|
20
15
|
import { appendMigrationEvents, hashConfigText } from '../core/migration/migration-transaction-journal.js';
|
|
21
|
-
import { repairCodexAppFastUi } from '../core/codex-app/codex-app-fast-ui-repair.js';
|
|
22
16
|
import { resolveProviderContext } from '../core/provider/provider-context.js';
|
|
23
17
|
import { readLocalModelConfig } from '../core/agents/ollama-worker-config.js';
|
|
24
|
-
import { repairAgentRoleConfigs } from '../core/agents/agent-role-config.js';
|
|
25
18
|
import { writeCodex0138CapabilityArtifacts } from '../core/codex-control/codex-0138-capability.js';
|
|
26
|
-
import { runCodex0138Doctor } from '../core/doctor/codex-0138-doctor.js';
|
|
27
19
|
import { writeCodexPluginInventoryArtifacts, pluginAppTemplatePolicy } from '../core/codex-plugins/codex-plugin-json.js';
|
|
28
20
|
import { writeMcpPluginInventoryArtifacts } from '../core/mcp/mcp-plugin-inventory.js';
|
|
29
|
-
import { runDoctorZellijRepair, doctorZellijRepairConsoleLine } from '../core/doctor/doctor-zellij-repair.js';
|
|
30
|
-
import { runDoctorContext7Repair } from '../core/doctor/doctor-context7-repair.js';
|
|
31
|
-
import { runDoctorCodexStartupRepair } from '../core/doctor/doctor-codex-startup-repair.js';
|
|
32
21
|
import { buildCodexAppHarnessMatrix } from '../core/codex-app/codex-app-harness-matrix.js';
|
|
33
22
|
import { buildCodexNativeFeatureMatrix } from '../core/codex-native/codex-native-feature-broker.js';
|
|
34
|
-
import { repairCodexNativeManagedAssets } from '../core/codex-native/codex-native-repair-transaction.js';
|
|
35
|
-
import { runDoctorNativeCapabilityRepair } from '../core/doctor/doctor-native-capability-repair.js';
|
|
36
|
-
import { runDoctorCommandAliasCleanup } from '../core/doctor/command-alias-cleanup.js';
|
|
37
|
-
import { repairCodexStartupConfig } from '../core/doctor/codex-startup-config-repair.js';
|
|
38
|
-
import { repairContext7Mcp } from '../core/doctor/context7-mcp-repair.js';
|
|
39
|
-
import { repairSupabaseMcp } from '../core/doctor/supabase-mcp-repair.js';
|
|
40
|
-
import { runDoctorFixTransaction } from '../core/doctor/doctor-transaction.js';
|
|
41
|
-
import { planDoctorDirtyRepair } from '../core/doctor/doctor-dirty-planner.js';
|
|
42
|
-
import { doctorRepairPostcheck } from '../core/doctor/doctor-repair-postcheck.js';
|
|
43
23
|
import { withSecretPreservationGuard } from '../core/config/config-migration-journal.js';
|
|
44
24
|
import { isUpdateMigrationReceiptCurrent, projectUpdateMigrationReceiptPath, writeProjectUpdateMigrationReceipt } from '../core/update/update-migration-state.js';
|
|
45
25
|
import { inspectSksMenuBarStatus, installSksMenuBar } from '../core/codex-app/sks-menubar.js';
|
|
46
26
|
import { sweepSksTempDirs } from '../core/retention.js';
|
|
47
|
-
import { reconcileSkills } from '../core/init/skills.js';
|
|
48
|
-
import { codexHookTrustDoctor } from '../core/codex-hooks/codex-hook-trust-doctor.js';
|
|
49
27
|
import { detectImagegenCapability } from '../core/imagegen/imagegen-capability.js';
|
|
50
|
-
import { repairCodexImagegen } from '../core/doctor/imagegen-repair.js';
|
|
51
|
-
import { repairComputerUse } from '../core/doctor/computer-use-repair.js';
|
|
52
|
-
import { repairBrowserUse } from '../core/doctor/browser-use-repair.js';
|
|
53
|
-
import { detectAndRepairMcpTransportCollisions } from '../core/doctor/mcp-transport-collision-repair.js';
|
|
54
28
|
export async function run(_command, args = []) {
|
|
55
29
|
const root = await projectRoot();
|
|
56
30
|
const doctorFix = flag(args, '--fix');
|
|
31
|
+
const doctorProfile = doctorProfileFromArgs(args, doctorFix);
|
|
57
32
|
if (!flag(args, '--json')) {
|
|
58
33
|
cliUi.banner('doctor');
|
|
59
34
|
cliUi.step(doctorFix ? 'repairing and validating' : 'validating');
|
|
60
35
|
}
|
|
36
|
+
if (!doctorFix && flag(args, '--json') && doctorProfile === 'fast')
|
|
37
|
+
return runDoctorJsonFastPath(args, root);
|
|
61
38
|
if (doctorFix)
|
|
62
39
|
return withSecretPreservationGuard(root, 'doctor-fix', () => runDoctor(args, root, doctorFix));
|
|
63
40
|
return runDoctor(args, root, doctorFix);
|
|
64
41
|
}
|
|
42
|
+
async function runDoctorJsonFastPath(args = [], root) {
|
|
43
|
+
const startedAtMs = Date.now();
|
|
44
|
+
const codexBin = readOption(args, '--codex-bin', process.env.SKS_DOCTOR_CODEX_BIN || '');
|
|
45
|
+
const configProbeOpts = {
|
|
46
|
+
codexProbe: false,
|
|
47
|
+
actualCodex: false,
|
|
48
|
+
requireActualCodex: false,
|
|
49
|
+
codexBin: codexBin || undefined
|
|
50
|
+
};
|
|
51
|
+
const [codex, rust, codexConfig, sneakoscopeExists] = await Promise.all([
|
|
52
|
+
codexBin
|
|
53
|
+
? Promise.resolve({ bin: codexBin, version: 'fixture-or-explicit', available: true })
|
|
54
|
+
: getCodexInfo().catch(() => ({ bin: null, version: null, available: false })),
|
|
55
|
+
rustInfo().catch((err) => ({ available: false, mode: 'js_fallback', status: 'error', version: null, error: err.message })),
|
|
56
|
+
inspectCodexConfigReadability(root, configProbeOpts).catch((err) => ({
|
|
57
|
+
ok: false,
|
|
58
|
+
checks: [],
|
|
59
|
+
operator_actions: [],
|
|
60
|
+
blockers: [err?.message || String(err)]
|
|
61
|
+
})),
|
|
62
|
+
exists(`${root}/.sneakoscope`)
|
|
63
|
+
]);
|
|
64
|
+
const ready = {
|
|
65
|
+
schema: 'sks.doctor-readiness-matrix.v2',
|
|
66
|
+
generated_at: nowIso(),
|
|
67
|
+
ready: Boolean(codexConfig?.ok),
|
|
68
|
+
cli_ready: Boolean(codexConfig?.ok),
|
|
69
|
+
mad_ready: false,
|
|
70
|
+
managed_state_current: sneakoscopeExists,
|
|
71
|
+
codex_config_readable_by_node: Boolean(codexConfig?.ok),
|
|
72
|
+
codex_config_readable_by_codex_cli: false,
|
|
73
|
+
codex_config_readable_in_zellij_context: false,
|
|
74
|
+
codex_app_ready: false,
|
|
75
|
+
primary_blocker: codexConfig?.ok ? null : 'codex_config_unreadable',
|
|
76
|
+
blockers: codexConfig?.ok ? [] : ['codex_config_unreadable'],
|
|
77
|
+
next_actions: codexConfig?.ok ? [] : ['Run `sks doctor --fix --json` to repair managed config.']
|
|
78
|
+
};
|
|
79
|
+
const codexNativeFeatureMatrix = fallbackCodexNativeFeatureMatrix(codex, [], ['native_feature_matrix_deferred_to_full_doctor_or_route_gate']);
|
|
80
|
+
const zellijReadiness = buildZellijReadiness(root, { status: 'skipped', required_for: ['sks --mad', 'interactive lane UI'] }, ready);
|
|
81
|
+
const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
|
|
82
|
+
const deferredImagegen = deferredNativeRepair('sks.doctor-imagegen-repair.v1', false, [
|
|
83
|
+
'Run `sks doctor --fix --repair-native-capabilities --json` after enabling Codex App image_generation.'
|
|
84
|
+
]);
|
|
85
|
+
const deferredComputerUse = deferredNativeRepair('sks.doctor-computer-use-repair.v1', false, [
|
|
86
|
+
'Computer Use route needs manual OS/App permission verification before use.'
|
|
87
|
+
]);
|
|
88
|
+
const deferredBrowserUse = deferredNativeRepair('sks.doctor-browser-use-repair.v1', false, [
|
|
89
|
+
'Chrome/web review route needs the Codex Chrome Extension enabled before use.'
|
|
90
|
+
]);
|
|
91
|
+
const result = {
|
|
92
|
+
schema: 'sks.doctor-status.v2',
|
|
93
|
+
elapsed_ms: Date.now() - startedAtMs,
|
|
94
|
+
ok: ready.ready,
|
|
95
|
+
root,
|
|
96
|
+
fast_path: true,
|
|
97
|
+
no_fix_write_policy: 'no_writes_performed',
|
|
98
|
+
arg_warnings: doctorArgWarnings(args),
|
|
99
|
+
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
100
|
+
codex,
|
|
101
|
+
codex_config: codexConfig,
|
|
102
|
+
rust,
|
|
103
|
+
codex_app: { ok: false, skipped: true, warnings: ['codex_app_optional_diagnostic_skipped'] },
|
|
104
|
+
codex_app_ui: {
|
|
105
|
+
schema: 'sks.codex-app-fast-ui-repair.v1',
|
|
106
|
+
ok: true,
|
|
107
|
+
apply: false,
|
|
108
|
+
skipped: true,
|
|
109
|
+
actions: [],
|
|
110
|
+
blockers: [],
|
|
111
|
+
warnings: ['codex_app_ui_repair_deferred']
|
|
112
|
+
},
|
|
113
|
+
sks_menubar: {
|
|
114
|
+
schema: 'sks.codex-app-sks-menubar.v1',
|
|
115
|
+
ok: true,
|
|
116
|
+
apply: false,
|
|
117
|
+
status: 'skipped_fast_path',
|
|
118
|
+
actions: [],
|
|
119
|
+
blockers: [],
|
|
120
|
+
warnings: ['menubar_install_deferred_to_fix_or_full_doctor']
|
|
121
|
+
},
|
|
122
|
+
provider_context: {
|
|
123
|
+
schema: 'sks.provider-context.v1',
|
|
124
|
+
generated_at: nowIso(),
|
|
125
|
+
provider: 'unknown',
|
|
126
|
+
auth_mode: 'unknown',
|
|
127
|
+
route: '$Doctor',
|
|
128
|
+
service_tier: process.env.SKS_SERVICE_TIER || 'fast',
|
|
129
|
+
source: 'skipped',
|
|
130
|
+
confidence: 'low',
|
|
131
|
+
conflict: false,
|
|
132
|
+
warnings: ['provider_context_optional_diagnostic_skipped'],
|
|
133
|
+
signals: {}
|
|
134
|
+
},
|
|
135
|
+
codex_lb: codexLbMetrics(await readCodexLbCircuit(root).catch(() => ({}))),
|
|
136
|
+
codex_doctor: null,
|
|
137
|
+
pre_repair_codex_doctor: null,
|
|
138
|
+
post_repair_codex_doctor: null,
|
|
139
|
+
codex_doctor_diff: null,
|
|
140
|
+
observational_codex_doctor_diff: null,
|
|
141
|
+
zellij: { ok: true, skipped: true, status: 'skipped_fast_path', required_for: ['sks --mad', 'interactive lane UI'] },
|
|
142
|
+
zellij_repair: { schema: 'sks.zellij-self-heal.v1', ok: true, skipped: true, blockers: [], warnings: ['zellij_repair_deferred_to_full_doctor_or_route_gate'] },
|
|
143
|
+
context7_repair: { schema: 'sks.doctor-context7-repair.v1', ok: true, fix: false, skipped: true, actions: [], blockers: [], warnings: ['context7_repair_deferred_to_fix'] },
|
|
144
|
+
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'] },
|
|
145
|
+
startup_config_repair: null,
|
|
146
|
+
context7_mcp_repair: null,
|
|
147
|
+
supabase_mcp_repair: null,
|
|
148
|
+
doctor_fix_transaction: null,
|
|
149
|
+
doctor_fix_postcheck: null,
|
|
150
|
+
postcheck: null,
|
|
151
|
+
local_model: null,
|
|
152
|
+
agent_role_config: { schema: 'sks.agent-role-config-repair.v1', ok: true, apply: false, skipped: true, blockers: [] },
|
|
153
|
+
zellij_readiness: zellijReadiness,
|
|
154
|
+
codex_permission_profiles: { skipped: true, reason: 'doctor_json_fast_path_no_report_write' },
|
|
155
|
+
command_aliases: { schema: 'sks.command-alias-cleanup.v1', ok: true, skipped: true, reason: 'doctor_json_fast_path_no_write' },
|
|
156
|
+
sks_temp_sweep: { ok: true, skipped: true, action_count: 0, reason: 'doctor_without_fix', error: null },
|
|
157
|
+
imagegen: { ok: false, auth_readiness: null, codex_app_builtin_available: false },
|
|
158
|
+
imagegen_repair: deferredImagegen,
|
|
159
|
+
codex_0138: { capability: null, doctor: { schema: 'sks.codex-0138-doctor.v1', ok: true, skipped: true, blockers: [], warnings: ['historical_codex_0138_doctor_skipped'] }, plugins: null, plugin_app_template_policy: null, mcp_plugin_inventory: null },
|
|
160
|
+
codex_app_harness_matrix: { schema: 'sks.codex-app-harness-matrix.v1', ok: true, skipped: true, app_features: {}, sks_integrations: {}, blockers: [], warnings: ['codex_app_harness_optional_diagnostic_skipped'] },
|
|
161
|
+
codex_native_feature_matrix: codexNativeFeatureMatrix,
|
|
162
|
+
runtime_readiness: runtimeReadiness,
|
|
163
|
+
ready,
|
|
164
|
+
sneakoscope: { ok: sneakoscopeExists },
|
|
165
|
+
package: { bytes: 0, human: formatBytes(0) },
|
|
166
|
+
skills: { skipped: true, reason: 'doctor_without_fix' },
|
|
167
|
+
repair: {
|
|
168
|
+
sks_update: null,
|
|
169
|
+
setup: null,
|
|
170
|
+
codex_config: null,
|
|
171
|
+
migration_journal: null,
|
|
172
|
+
global_sks_installs: null,
|
|
173
|
+
agent_role_config: null,
|
|
174
|
+
zellij: null,
|
|
175
|
+
context7: null,
|
|
176
|
+
codex_startup: null,
|
|
177
|
+
startup_config: null,
|
|
178
|
+
context7_mcp: null,
|
|
179
|
+
supabase_mcp: null,
|
|
180
|
+
mcp_transport_collision: null,
|
|
181
|
+
imagegen: deferredImagegen,
|
|
182
|
+
computer_use: deferredComputerUse,
|
|
183
|
+
browser_use: deferredBrowserUse,
|
|
184
|
+
hook_trust: null,
|
|
185
|
+
sks_menubar: null,
|
|
186
|
+
doctor_transaction: null,
|
|
187
|
+
doctor_dirty_plan: null,
|
|
188
|
+
doctor_postcheck: null,
|
|
189
|
+
codex_native: null,
|
|
190
|
+
doctor_native_capability: null,
|
|
191
|
+
command_aliases: null,
|
|
192
|
+
skills: { skipped: true, reason: 'doctor_without_fix' },
|
|
193
|
+
sks_temp_sweep: { ok: true, skipped: true, reason: 'doctor_without_fix', actions: [] }
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
printJson(result);
|
|
197
|
+
if (!result.ok)
|
|
198
|
+
process.exitCode = 1;
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
65
201
|
async function runDoctor(args = [], root, doctorFix) {
|
|
66
202
|
const startedAtMs = Date.now();
|
|
67
203
|
const sksTempSweep = doctorFix ? await sweepSksTempDirs(root, { maxAgeHours: 24 }).catch((err) => ({
|
|
@@ -82,7 +218,17 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
82
218
|
const shouldRunZellijRepair = deepDiagnostics || flag(args, '--repair-zellij') || flag(args, '--install-homebrew') || process.env.SKS_REQUIRE_ZELLIJ === '1';
|
|
83
219
|
const nativeCapabilityDiagnosticsRequested = deepDiagnostics || flag(args, '--repair-native-capabilities');
|
|
84
220
|
const doctorPhaseIds = doctorPhaseIdsForProfile(doctorProfile);
|
|
85
|
-
const
|
|
221
|
+
const { runDoctorCommandAliasCleanup } = await import('../core/doctor/command-alias-cleanup.js');
|
|
222
|
+
const { runDoctorNativeCapabilityRepair } = await import('../core/doctor/doctor-native-capability-repair.js');
|
|
223
|
+
const { runDoctorCodexStartupRepair } = await import('../core/doctor/doctor-codex-startup-repair.js');
|
|
224
|
+
const { runDoctorContext7Repair } = await import('../core/doctor/doctor-context7-repair.js');
|
|
225
|
+
const { compareCodexDoctorBridge, runCodexDoctorBridge } = await import('../core/doctor/codex-doctor-bridge.js');
|
|
226
|
+
const { repairCodexAppFastUi } = await import('../core/codex-app/codex-app-fast-ui-repair.js');
|
|
227
|
+
const { runDoctorZellijRepair, doctorZellijRepairConsoleLine } = await import('../core/doctor/doctor-zellij-repair.js');
|
|
228
|
+
const { repairAgentRoleConfigs } = await import('../core/agents/agent-role-config.js');
|
|
229
|
+
const { runCodex0138Doctor } = await import('../core/doctor/codex-0138-doctor.js');
|
|
230
|
+
const { writeDoctorReadinessMatrix } = await import('../core/doctor/doctor-readiness-matrix.js');
|
|
231
|
+
const doctorDirtyPlan = doctorFix ? (await import('../core/doctor/doctor-dirty-planner.js')).planDoctorDirtyRepair(root, doctorPhaseIds) : null;
|
|
86
232
|
let setupRepair = null;
|
|
87
233
|
let sksUpdate = null;
|
|
88
234
|
let migrationPreFix = null;
|
|
@@ -100,7 +246,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
100
246
|
install_scope: installScope,
|
|
101
247
|
config_backup_path: null,
|
|
102
248
|
global_skills: installScope === 'global' && !flag(args, '--local-only')
|
|
103
|
-
? deepDiagnostics ? await ensureGlobalCodexSkillsDuringInstall({ force: true }) : { status: 'skipped', reason: 'default_doctor_no_global_skill_regeneration' }
|
|
249
|
+
? deepDiagnostics ? await (await import('../cli/install-helpers.js')).ensureGlobalCodexSkillsDuringInstall({ force: true }) : { status: 'skipped', reason: 'default_doctor_no_global_skill_regeneration' }
|
|
104
250
|
: { status: 'skipped', reason: 'project or local-only repair' },
|
|
105
251
|
// Re-seed the Codex App Fast-mode UI table ([user.fast_mode] visible/enabled/
|
|
106
252
|
// default_profile) in the global ~/.codex/config.toml so existing installs whose
|
|
@@ -108,17 +254,17 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
108
254
|
// backs up + parse-validates before writing, no-op when already present.
|
|
109
255
|
codex_app_fast_mode: flag(args, '--local-only')
|
|
110
256
|
? { status: 'skipped', reason: 'local-only repair' }
|
|
111
|
-
: await ensureGlobalCodexFastModeDuringInstall().catch((err) => ({ status: 'failed', error: err?.message || String(err) }))
|
|
257
|
+
: await (await import('../cli/install-helpers.js')).ensureGlobalCodexFastModeDuringInstall().catch((err) => ({ status: 'failed', error: err?.message || String(err) }))
|
|
112
258
|
};
|
|
113
259
|
}
|
|
114
260
|
const skillsReconcile = doctorFix
|
|
115
261
|
? {
|
|
116
|
-
global: await reconcileSkills({
|
|
262
|
+
global: await (await import('../core/init/skills.js')).reconcileSkills({
|
|
117
263
|
targetDir: path.join(os.homedir(), '.agents', 'skills'),
|
|
118
264
|
scope: 'global',
|
|
119
265
|
fix: true
|
|
120
266
|
}).catch((err) => ({ ok: false, error: err?.message || String(err) })),
|
|
121
|
-
project: await reconcileSkills({
|
|
267
|
+
project: await (await import('../core/init/skills.js')).reconcileSkills({
|
|
122
268
|
targetDir: path.join(root, '.agents', 'skills'),
|
|
123
269
|
scope: 'project',
|
|
124
270
|
fix: true
|
|
@@ -184,7 +330,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
184
330
|
report_path: `${root}/.sneakoscope/reports/doctor-codex-startup-repair.json`
|
|
185
331
|
}));
|
|
186
332
|
const codexDoctorBefore = flag(args, '--fix') && deepDiagnostics ? await runCodexDoctorBridge({ codexBin: codexBin || null, cwd: root, required: flag(args, '--require-actual-codex') }).catch(() => null) : null;
|
|
187
|
-
const configRepair = flag(args, '--fix') ? await repairCodexConfigEperm(root, { fix: true, ...configProbeOpts }) : null;
|
|
333
|
+
const configRepair = flag(args, '--fix') ? await (await import('../core/codex/codex-config-eperm-repair.js')).repairCodexConfigEperm(root, { fix: true, ...configProbeOpts }) : null;
|
|
188
334
|
const migrationJournal = flag(args, '--fix')
|
|
189
335
|
? await writeFixMigrationJournal(root, migrationPreFix, configRepair, setupRepair).catch(() => null)
|
|
190
336
|
: null;
|
|
@@ -380,7 +526,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
380
526
|
report_path: `${root}/.sneakoscope/reports/doctor-context7-repair.json`
|
|
381
527
|
}));
|
|
382
528
|
const startupConfigRepair = doctorFix
|
|
383
|
-
? await repairCodexStartupConfig({ root, apply: true }).catch((err) => ({
|
|
529
|
+
? await (await import('../core/doctor/codex-startup-config-repair.js')).repairCodexStartupConfig({ root, apply: true }).catch((err) => ({
|
|
384
530
|
schema: 'sks.codex-startup-config-repair.v1',
|
|
385
531
|
ok: false,
|
|
386
532
|
apply: true,
|
|
@@ -388,7 +534,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
388
534
|
}))
|
|
389
535
|
: null;
|
|
390
536
|
const context7McpRepair = doctorFix
|
|
391
|
-
? await repairContext7Mcp({ root, apply: true }).catch((err) => ({
|
|
537
|
+
? await (await import('../core/doctor/context7-mcp-repair.js')).repairContext7Mcp({ root, apply: true }).catch((err) => ({
|
|
392
538
|
schema: 'sks.doctor-context7-mcp-repair.v1',
|
|
393
539
|
ok: false,
|
|
394
540
|
apply: true,
|
|
@@ -399,7 +545,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
399
545
|
}))
|
|
400
546
|
: null;
|
|
401
547
|
const supabaseMcpRepair = doctorFix && doctorPhaseIds.includes('supabase_mcp_repair')
|
|
402
|
-
? await repairSupabaseMcp({ root, apply: true }).catch((err) => ({
|
|
548
|
+
? await (await import('../core/doctor/supabase-mcp-repair.js')).repairSupabaseMcp({ root, apply: true }).catch((err) => ({
|
|
403
549
|
schema: 'sks.doctor-supabase-mcp-repair.v1',
|
|
404
550
|
ok: false,
|
|
405
551
|
apply: true,
|
|
@@ -419,7 +565,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
419
565
|
}))
|
|
420
566
|
: null;
|
|
421
567
|
const hookTrustRepair = doctorFix && doctorPhaseIds.includes('hook_trust_repair')
|
|
422
|
-
? await codexHookTrustDoctor(root, { fix: true, managed: true, actual: true }).catch((err) => ({
|
|
568
|
+
? await (await import('../core/codex-hooks/codex-hook-trust-doctor.js')).codexHookTrustDoctor(root, { fix: true, managed: true, actual: true }).catch((err) => ({
|
|
423
569
|
schema: 'sks.codex-hook-trust-doctor.v2',
|
|
424
570
|
ok: false,
|
|
425
571
|
actual: true,
|
|
@@ -429,7 +575,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
429
575
|
}))
|
|
430
576
|
: null;
|
|
431
577
|
const doctorFixTransaction = doctorFix
|
|
432
|
-
? await runDoctorFixTransaction({
|
|
578
|
+
? await (await import('../core/doctor/doctor-transaction.js')).runDoctorFixTransaction({
|
|
433
579
|
root,
|
|
434
580
|
dirtyPlan: doctorDirtyPlan,
|
|
435
581
|
json: flag(args, '--json'),
|
|
@@ -599,7 +745,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
599
745
|
raw_secret_values_recorded: false
|
|
600
746
|
}))
|
|
601
747
|
: null;
|
|
602
|
-
const doctorFixPostcheck = doctorFix ? doctorRepairPostcheck(doctorFixTransaction) : null;
|
|
748
|
+
const doctorFixPostcheck = doctorFix ? (await import('../core/doctor/doctor-repair-postcheck.js')).doctorRepairPostcheck(doctorFixTransaction) : null;
|
|
603
749
|
const zellij = await checkZellijCapability({ root, require: process.env.SKS_REQUIRE_ZELLIJ === '1' });
|
|
604
750
|
const localModel = await readLocalModelConfig().catch(() => null);
|
|
605
751
|
const permissionProfiles = await inventoryCodexPermissionProfiles(root, { writeReport: true });
|
|
@@ -618,8 +764,9 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
618
764
|
blockers: [err?.message || String(err)]
|
|
619
765
|
}));
|
|
620
766
|
const globalSksInstallCleanup = flag(args, '--fix') && !flag(args, '--local-only')
|
|
621
|
-
? await cleanDuplicateGlobalSksInstalls({ root, fix: true }).catch((err) => ({ schema: 'sks.global-sks-install-cleanup.v1', ok: false, fix: true, error: err?.message || String(err), blockers: ['global_sks_install_cleanup_exception'] }))
|
|
767
|
+
? await (await import('../core/doctor/global-sks-install-cleanup.js')).cleanDuplicateGlobalSksInstalls({ root, fix: true }).catch((err) => ({ schema: 'sks.global-sks-install-cleanup.v1', ok: false, fix: true, error: err?.message || String(err), blockers: ['global_sks_install_cleanup_exception'] }))
|
|
622
768
|
: null;
|
|
769
|
+
const shouldProbeNativeCapabilityRepairs = doctorFix || deepDiagnostics || nativeCapabilityDiagnosticsRequested;
|
|
623
770
|
const imagegen = await detectImagegenCapability({ codexBin: codexBin || undefined }).catch((err) => ({ ok: false, error: err.message, auth_readiness: null, core_ready: false, blockers: ['imagegen_detection_exception'] }));
|
|
624
771
|
const imagegenRepair = imagegen.core_ready === true
|
|
625
772
|
? {
|
|
@@ -635,35 +782,49 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
635
782
|
manual_actions: [],
|
|
636
783
|
communication_test: { level: 'flag_level', ok: true, checked: 'codex features list --json (feature-flag/plugin metadata only)', real_generation_round_trip_performed: false, blocker: null }
|
|
637
784
|
}
|
|
638
|
-
:
|
|
639
|
-
|
|
785
|
+
: shouldProbeNativeCapabilityRepairs
|
|
786
|
+
? await (await import('../core/doctor/imagegen-repair.js')).repairCodexImagegen({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
|
|
787
|
+
schema: 'sks.doctor-imagegen-repair.v1',
|
|
788
|
+
ok: false,
|
|
789
|
+
attempted: true,
|
|
790
|
+
apply: doctorFix,
|
|
791
|
+
recovered: false,
|
|
792
|
+
blockers: [err?.message || String(err)],
|
|
793
|
+
manual_actions: ['Run `sks doctor --fix --json` after enabling Codex App image_generation.']
|
|
794
|
+
}))
|
|
795
|
+
: deferredNativeRepair('sks.doctor-imagegen-repair.v1', doctorFix, [
|
|
796
|
+
'Run `sks doctor --fix --repair-native-capabilities --json` after enabling Codex App image_generation.'
|
|
797
|
+
]);
|
|
798
|
+
const computerUseRepair = shouldProbeNativeCapabilityRepairs
|
|
799
|
+
? await (await import('../core/doctor/computer-use-repair.js')).repairComputerUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
|
|
800
|
+
schema: 'sks.doctor-computer-use-repair.v1',
|
|
640
801
|
ok: false,
|
|
641
|
-
attempted:
|
|
802
|
+
attempted: false,
|
|
642
803
|
apply: doctorFix,
|
|
643
804
|
recovered: false,
|
|
644
805
|
blockers: [err?.message || String(err)],
|
|
645
|
-
|
|
646
|
-
}))
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
806
|
+
next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Computer Use.']
|
|
807
|
+
}))
|
|
808
|
+
: deferredNativeRepair('sks.doctor-computer-use-repair.v1', doctorFix, [
|
|
809
|
+
'Computer Use route needs manual OS/App permission verification before use.',
|
|
810
|
+
'Run `sks doctor --fix --repair-native-capabilities --json` for an explicit Computer Use repair probe.'
|
|
811
|
+
]);
|
|
812
|
+
const browserUseRepair = shouldProbeNativeCapabilityRepairs
|
|
813
|
+
? await (await import('../core/doctor/browser-use-repair.js')).repairBrowserUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
|
|
814
|
+
schema: 'sks.doctor-browser-use-repair.v1',
|
|
815
|
+
ok: false,
|
|
816
|
+
attempted: false,
|
|
817
|
+
apply: doctorFix,
|
|
818
|
+
recovered: false,
|
|
819
|
+
blockers: [err?.message || String(err)],
|
|
820
|
+
next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Browser Use / Chrome extension.']
|
|
821
|
+
}))
|
|
822
|
+
: deferredNativeRepair('sks.doctor-browser-use-repair.v1', doctorFix, [
|
|
823
|
+
'Chrome/web review route needs the Codex Chrome Extension enabled before use.',
|
|
824
|
+
'Run `sks doctor --fix --repair-native-capabilities --json` for an explicit Browser Use repair probe.'
|
|
825
|
+
]);
|
|
665
826
|
const mcpTransportCollisionRepair = doctorFix
|
|
666
|
-
? await detectAndRepairMcpTransportCollisions({ root, apply: true }).catch((err) => ({
|
|
827
|
+
? await (await import('../core/doctor/mcp-transport-collision-repair.js')).detectAndRepairMcpTransportCollisions({ root, apply: true }).catch((err) => ({
|
|
667
828
|
schema: 'sks.mcp-transport-collision-repair.v1',
|
|
668
829
|
ok: false,
|
|
669
830
|
apply: true,
|
|
@@ -675,7 +836,9 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
675
836
|
raw_secret_values_recorded: false
|
|
676
837
|
}))
|
|
677
838
|
: null;
|
|
678
|
-
const nativeCapabilityReadinessStatus = (repair) =>
|
|
839
|
+
const nativeCapabilityReadinessStatus = (repair) => repair?.skipped === true
|
|
840
|
+
? (repair.status || 'deferred')
|
|
841
|
+
: (repair?.recovered === true || repair?.ok === true ? 'ok' : repair?.attempted ? 'blocked' : 'not-needed');
|
|
679
842
|
const nativeCapabilityReadiness = {
|
|
680
843
|
schema: 'sks.native-capability-readiness.v1',
|
|
681
844
|
generated_at: nowIso(),
|
|
@@ -702,7 +865,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
702
865
|
: null;
|
|
703
866
|
const repairCodexNative = doctorFix && doctorPhaseIds.includes('native_capability_repair');
|
|
704
867
|
const codexNativeRepair = repairCodexNative
|
|
705
|
-
? await repairCodexNativeManagedAssets({
|
|
868
|
+
? await (await import('../core/codex-native/codex-native-repair-transaction.js')).repairCodexNativeManagedAssets({
|
|
706
869
|
root,
|
|
707
870
|
requestedBy: 'doctor --fix',
|
|
708
871
|
yes: flag(args, '--yes') || flag(args, '-y')
|
|
@@ -1211,6 +1374,21 @@ function buildRuntimeReadiness(zellijReadiness, matrix) {
|
|
|
1211
1374
|
repair_actions: [...new Set(repairActions)]
|
|
1212
1375
|
};
|
|
1213
1376
|
}
|
|
1377
|
+
function deferredNativeRepair(schema, doctorFix, nextActions) {
|
|
1378
|
+
return {
|
|
1379
|
+
schema,
|
|
1380
|
+
generated_at: nowIso(),
|
|
1381
|
+
ok: true,
|
|
1382
|
+
skipped: true,
|
|
1383
|
+
status: 'deferred_to_explicit_native_capability_probe',
|
|
1384
|
+
attempted: false,
|
|
1385
|
+
apply: doctorFix,
|
|
1386
|
+
recovered: false,
|
|
1387
|
+
blockers: [],
|
|
1388
|
+
next_actions: nextActions,
|
|
1389
|
+
manual_actions: nextActions
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1214
1392
|
function fallbackCodexNativeFeatureMatrix(codex, blockers = [], warnings = []) {
|
|
1215
1393
|
return {
|
|
1216
1394
|
schema: 'sks.codex-native-feature-matrix.v1',
|