sneakoscope 5.8.0 → 5.9.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/sks.js +61 -1
- package/dist/cli/command-registry.js +1 -1
- package/dist/cli/commands-fast.js +20 -0
- package/dist/cli/root-fast.js +48 -0
- package/dist/cli/router.js +3 -0
- package/dist/cli/super-search-command.js +3 -18
- package/dist/commands/doctor.js +56 -24
- package/dist/config/skills-manifest.json +57 -57
- package/dist/core/agents/parallel-write-fixture.js +301 -0
- 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 +1 -1
- package/dist/core/install/installed-package-smoke.js +121 -0
- package/dist/core/naruto/naruto-active-pool.js +6 -2
- package/dist/core/perf/perf-budget.js +145 -0
- package/dist/core/quality/competitor-scorecard.js +116 -0
- package/dist/core/release/gate-timing.js +103 -0
- package/dist/core/retention/retention-budget.js +62 -0
- package/dist/core/routes.js +7 -3
- package/dist/core/super-search/doctor.js +63 -0
- package/dist/core/super-search/runtime.js +11 -0
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-fast-mode-default-check.js +10 -1
- package/dist/scripts/competitor-scorecard-check.js +25 -0
- package/dist/scripts/doctor-idempotence-check.js +8 -0
- package/dist/scripts/gate-timing-check.js +8 -0
- package/dist/scripts/hook-latency-quantum-check.js +122 -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/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/quantum-baseline-report.js +38 -0
- package/dist/scripts/release-check-stamp.js +117 -16
- package/dist/scripts/retention-budget-check.js +8 -0
- package/dist/scripts/route-intent-regression-check.js +44 -0
- package/dist/scripts/super-search-live-smoke-check.js +70 -0
- package/dist/scripts/super-search-offline-contract-check.js +45 -0
- package/package.json +19 -7
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
Sneakoscope Codex (`sks`) is a Codex CLI and Codex App harness for people who want parallel AI coding without losing proof. It gives Codex a simple front door, a dynamic worker swarm, a local dashboard, TriWiki project memory, and release gates that separate machine evidence from LLM opinion.
|
|
16
16
|
|
|
17
|
-
Current release: SKS **5.
|
|
17
|
+
Current release: SKS **5.9.0**. New in this release: installed-package smoke checks, quantum performance budgets, Super-Search usable/degraded/blocked readiness, production parallel-write smoke, doctor idempotence proof, retention budgets, and an artifact-driven competitor scorecard. See [CHANGELOG.md](CHANGELOG.md).
|
|
18
18
|
|
|
19
19
|
## Install
|
|
20
20
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "sks.competitor-scorecard-baseline.v1",
|
|
3
|
+
"target": {
|
|
4
|
+
"total_min": 94,
|
|
5
|
+
"each_min": 90
|
|
6
|
+
},
|
|
7
|
+
"categories": {
|
|
8
|
+
"code_stability": [
|
|
9
|
+
{
|
|
10
|
+
"id": "doctor-idempotence",
|
|
11
|
+
"path": ".sneakoscope/reports/doctor-idempotence.json"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "super-search-offline-contract",
|
|
15
|
+
"path": ".sneakoscope/reports/super-search-offline-contract.json"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "route-regression",
|
|
19
|
+
"path": ".sneakoscope/reports/route-regression.json"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"test_release_gates": [
|
|
23
|
+
{
|
|
24
|
+
"id": "release-readiness",
|
|
25
|
+
"path": ".sneakoscope/reports/release-readiness-5.9.0.json"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "installed-package-smoke",
|
|
29
|
+
"path": ".sneakoscope/reports/installed-package-smoke.json"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "release-gate-timing",
|
|
33
|
+
"path": ".sneakoscope/reports/gate-timing.json"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"parallel_isolation": [
|
|
37
|
+
{
|
|
38
|
+
"id": "parallel-runtime-proof",
|
|
39
|
+
"path": ".sneakoscope/reports/parallel-production-smoke.json"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "worktree-runtime",
|
|
43
|
+
"path": ".sneakoscope/reports/parallel-production-smoke.json"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "patch-merge-proof",
|
|
47
|
+
"path": ".sneakoscope/reports/parallel-production-smoke.json"
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"speed_performance": [
|
|
51
|
+
{
|
|
52
|
+
"id": "perf-budget",
|
|
53
|
+
"path": ".sneakoscope/reports/perf-budget.json"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "hook-latency-quantum",
|
|
57
|
+
"path": ".sneakoscope/reports/hook-latency-quantum.json"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": "gate-timing",
|
|
61
|
+
"path": ".sneakoscope/reports/gate-timing.json"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"install_operations": [
|
|
65
|
+
{
|
|
66
|
+
"id": "installed-package-smoke",
|
|
67
|
+
"path": ".sneakoscope/reports/installed-package-smoke.json"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "doctor-idempotence",
|
|
71
|
+
"path": ".sneakoscope/reports/doctor-idempotence.json"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"id": "package-surface-budget",
|
|
75
|
+
"path": ".sneakoscope/reports/package-surface-budget.json"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"maintainability": [
|
|
79
|
+
{
|
|
80
|
+
"id": "architecture-check",
|
|
81
|
+
"command": "architecture:check"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "route-modularity-check",
|
|
85
|
+
"command": "route-modularity:check"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "command-budget-check",
|
|
89
|
+
"command": "command-budget:check"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "package-surface-budget",
|
|
93
|
+
"path": ".sneakoscope/reports/package-surface-budget.json"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "sks.perf-budgets.v1",
|
|
3
|
+
"commands": [
|
|
4
|
+
{ "name": "version", "argv": ["node", "./dist/bin/sks.js", "--version"], "budget_p50_ms": 170, "budget_p95_ms": 180 },
|
|
5
|
+
{ "name": "commands-json", "argv": ["node", "./dist/bin/sks.js", "commands", "--json"], "budget_p50_ms": 260, "budget_p95_ms": 320 },
|
|
6
|
+
{ "name": "root-json", "argv": ["node", "./dist/bin/sks.js", "root", "--json"], "budget_p50_ms": 170, "budget_p95_ms": 220 },
|
|
7
|
+
{ "name": "doctor-json", "argv": ["node", "./dist/bin/sks.js", "doctor", "--json"], "budget_p50_ms": 2000, "budget_p95_ms": 2500 },
|
|
8
|
+
{ "name": "super-search-doctor-json", "argv": ["node", "./dist/bin/sks.js", "super-search", "doctor", "--json"], "budget_p50_ms": 180, "budget_p95_ms": 240 }
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
|
|
|
4
4
|
fn main() {
|
|
5
5
|
let mut args = std::env::args().skip(1);
|
|
6
6
|
match args.next().as_deref() {
|
|
7
|
-
Some("--version") => println!("sks-rs 5.
|
|
7
|
+
Some("--version") => println!("sks-rs 5.9.0"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
package/dist/bin/sks.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const FAST_PACKAGE_VERSION = '5.
|
|
2
|
+
const FAST_PACKAGE_VERSION = '5.9.0';
|
|
3
3
|
const args = process.argv.slice(2);
|
|
4
4
|
try {
|
|
5
5
|
if (args[0] === '--agent' && args[1] === 'worker') {
|
|
@@ -9,6 +9,20 @@ try {
|
|
|
9
9
|
else if (args[0] === '--version' || args[0] === '-v' || args[0] === 'version') {
|
|
10
10
|
console.log(`sneakoscope ${FAST_PACKAGE_VERSION}`);
|
|
11
11
|
}
|
|
12
|
+
else if (args[0] === 'commands' && args.includes('--json')) {
|
|
13
|
+
const { commandsJsonFast } = await import('../cli/commands-fast.js');
|
|
14
|
+
commandsJsonFast();
|
|
15
|
+
}
|
|
16
|
+
else if (args[0] === 'root' && args.includes('--json')) {
|
|
17
|
+
const getBuiltinModule = process.getBuiltinModule;
|
|
18
|
+
const fs = typeof getBuiltinModule === 'function' ? getBuiltinModule('node:fs') : await import('node:fs');
|
|
19
|
+
rootJsonFastInline(fs);
|
|
20
|
+
}
|
|
21
|
+
else if (args[0] === 'super-search' && args[1] === 'doctor') {
|
|
22
|
+
const { buildSuperSearchDoctorReport, printSuperSearchDoctorReport } = await import('../core/super-search/doctor.js');
|
|
23
|
+
const doctorArgs = args.slice(2);
|
|
24
|
+
printSuperSearchDoctorReport(buildSuperSearchDoctorReport(doctorArgs), doctorArgs.includes('--json'));
|
|
25
|
+
}
|
|
12
26
|
else if (args[0] === 'help' || args[0] === '--help' || args[0] === '-h') {
|
|
13
27
|
if (args.length > 1) {
|
|
14
28
|
const { helpCommand } = await import('../core/commands/basic-cli.js');
|
|
@@ -29,5 +43,51 @@ catch (err) {
|
|
|
29
43
|
console.error(message);
|
|
30
44
|
process.exitCode = 1;
|
|
31
45
|
}
|
|
46
|
+
function rootJsonFastInline(fs, cwd = process.cwd()) {
|
|
47
|
+
const project = findProjectRootSync(fs, cwd);
|
|
48
|
+
const global = joinPath(process.env.HOME || process.env.USERPROFILE || cwd, '.sneakoscope');
|
|
49
|
+
const active = project || global;
|
|
50
|
+
process.stdout.write(`${JSON.stringify({
|
|
51
|
+
cwd,
|
|
52
|
+
mode: project ? 'project' : 'global',
|
|
53
|
+
active_root: active,
|
|
54
|
+
project_root: project,
|
|
55
|
+
global_root: global,
|
|
56
|
+
using_global_root: !project
|
|
57
|
+
})}\n`);
|
|
58
|
+
}
|
|
59
|
+
function findProjectRootSync(fs, start) {
|
|
60
|
+
let dir = normalizeStart(start);
|
|
61
|
+
for (;;) {
|
|
62
|
+
if (fs.existsSync(joinPath(dir, '.sneakoscope')))
|
|
63
|
+
return dir;
|
|
64
|
+
if (fs.existsSync(joinPath(dir, 'AGENTS.md')) && fs.existsSync(joinPath(dir, 'package.json')))
|
|
65
|
+
return dir;
|
|
66
|
+
const parent = parentDir(dir);
|
|
67
|
+
if (parent === dir)
|
|
68
|
+
return null;
|
|
69
|
+
dir = parent;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function normalizeStart(start) {
|
|
73
|
+
const value = stripTrailingSlash(start || process.cwd());
|
|
74
|
+
if (value.startsWith('/'))
|
|
75
|
+
return value || '/';
|
|
76
|
+
return joinPath(process.cwd(), value);
|
|
77
|
+
}
|
|
78
|
+
function joinPath(left, right) {
|
|
79
|
+
const base = stripTrailingSlash(left || '/');
|
|
80
|
+
return `${base === '/' ? '' : base}/${right}`;
|
|
81
|
+
}
|
|
82
|
+
function parentDir(value) {
|
|
83
|
+
const dir = stripTrailingSlash(value);
|
|
84
|
+
if (dir === '/')
|
|
85
|
+
return dir;
|
|
86
|
+
const index = dir.lastIndexOf('/');
|
|
87
|
+
return index <= 0 ? '/' : dir.slice(0, index);
|
|
88
|
+
}
|
|
89
|
+
function stripTrailingSlash(value) {
|
|
90
|
+
return value.replace(/\/+$/, '') || '/';
|
|
91
|
+
}
|
|
32
92
|
export {};
|
|
33
93
|
//# sourceMappingURL=sks.js.map
|
|
@@ -173,7 +173,7 @@ export const COMMANDS = {
|
|
|
173
173
|
selftest: entry('stable', 'Run local mock selftest', 'dist/core/commands/basic-cli.js', basicArgs('selftestCommand')),
|
|
174
174
|
goal: routeStateMutator(entry('beta', 'Manage Goal bridge workflow', 'dist/core/commands/goal-command.js', subcommand(() => import('../core/commands/goal-command.js'), 'goalCommand', 'dist/core/commands/goal-command.js')), ['loop-graph-proof.json']),
|
|
175
175
|
'seo-geo-optimizer': entry('beta', 'Run unified SEO/GEO optimizer audit/plan/apply/verify on the search-visibility kernel', 'dist/core/commands/seo-command.js', argsCommand(() => import('../core/commands/seo-command.js'), 'seoGeoOptimizerCommand', 'dist/core/commands/seo-command.js')),
|
|
176
|
-
hook: entry('beta', 'Codex hook entrypoint', 'dist/commands/hook.js', directCommand(() => import('../commands/hook.js'), 'dist/commands/hook.js')),
|
|
176
|
+
hook: skipMigrationGate(entry('beta', 'Codex hook entrypoint', 'dist/commands/hook.js', directCommand(() => import('../commands/hook.js'), 'dist/commands/hook.js'))),
|
|
177
177
|
profile: entry('labs', 'Inspect/set profile', 'dist/commands/profile.js', directCommand(() => import('../commands/profile.js'), 'dist/commands/profile.js')),
|
|
178
178
|
hproof: entry('beta', 'Evaluate H-Proof gate', 'dist/commands/hproof.js', directCommand(() => import('../commands/hproof.js'), 'dist/commands/hproof.js')),
|
|
179
179
|
'validate-artifacts': entry('beta', 'Validate mission artifacts', 'dist/core/commands/validate-artifacts-command.js', argsCommand(() => import('../core/commands/validate-artifacts-command.js'), 'validateArtifactsCommand', 'dist/core/commands/validate-artifacts-command.js')),
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { COMMANDS } from './command-registry.js';
|
|
2
|
+
export function commandsJsonFast() {
|
|
3
|
+
const commands = Object.entries(COMMANDS)
|
|
4
|
+
.map(([name, entry]) => fastCommandRow(name, entry))
|
|
5
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
6
|
+
console.log(JSON.stringify({
|
|
7
|
+
schema: 'sks.command-registry.v1',
|
|
8
|
+
aliases: ['sks', 'sneakoscope'],
|
|
9
|
+
commands
|
|
10
|
+
}, null, 2));
|
|
11
|
+
}
|
|
12
|
+
function fastCommandRow(name, entry) {
|
|
13
|
+
return {
|
|
14
|
+
name,
|
|
15
|
+
usage: `sks ${name}`,
|
|
16
|
+
description: entry.summary,
|
|
17
|
+
maturity: entry.maturity
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=commands-fast.js.map
|
|
@@ -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
|
@@ -119,6 +119,9 @@ 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
|
+
}
|
|
122
125
|
const root = await projectRoot(process.cwd()).catch(() => process.cwd());
|
|
123
126
|
const state = await readJson(stateFile(root), {}).catch(() => ({}));
|
|
124
127
|
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 = []) {
|
|
@@ -61,24 +62,8 @@ async function runCommand(args) {
|
|
|
61
62
|
}
|
|
62
63
|
async function doctorCommand(args) {
|
|
63
64
|
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.');
|
|
65
|
+
const report = buildSuperSearchDoctorReport(args);
|
|
66
|
+
printSuperSearchDoctorReport(report, json);
|
|
82
67
|
return report;
|
|
83
68
|
}
|
|
84
69
|
async function inspectCommand(action, args) {
|
package/dist/commands/doctor.js
CHANGED
|
@@ -620,6 +620,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
620
620
|
const globalSksInstallCleanup = flag(args, '--fix') && !flag(args, '--local-only')
|
|
621
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'] }))
|
|
622
622
|
: null;
|
|
623
|
+
const shouldProbeNativeCapabilityRepairs = doctorFix || deepDiagnostics || nativeCapabilityDiagnosticsRequested;
|
|
623
624
|
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
625
|
const imagegenRepair = imagegen.core_ready === true
|
|
625
626
|
? {
|
|
@@ -635,33 +636,47 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
635
636
|
manual_actions: [],
|
|
636
637
|
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
638
|
}
|
|
638
|
-
:
|
|
639
|
-
|
|
639
|
+
: shouldProbeNativeCapabilityRepairs
|
|
640
|
+
? await repairCodexImagegen({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
|
|
641
|
+
schema: 'sks.doctor-imagegen-repair.v1',
|
|
642
|
+
ok: false,
|
|
643
|
+
attempted: true,
|
|
644
|
+
apply: doctorFix,
|
|
645
|
+
recovered: false,
|
|
646
|
+
blockers: [err?.message || String(err)],
|
|
647
|
+
manual_actions: ['Run `sks doctor --fix --json` after enabling Codex App image_generation.']
|
|
648
|
+
}))
|
|
649
|
+
: deferredNativeRepair('sks.doctor-imagegen-repair.v1', doctorFix, [
|
|
650
|
+
'Run `sks doctor --fix --repair-native-capabilities --json` after enabling Codex App image_generation.'
|
|
651
|
+
]);
|
|
652
|
+
const computerUseRepair = shouldProbeNativeCapabilityRepairs
|
|
653
|
+
? await repairComputerUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
|
|
654
|
+
schema: 'sks.doctor-computer-use-repair.v1',
|
|
640
655
|
ok: false,
|
|
641
|
-
attempted:
|
|
656
|
+
attempted: false,
|
|
642
657
|
apply: doctorFix,
|
|
643
658
|
recovered: false,
|
|
644
659
|
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
|
-
|
|
660
|
+
next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Computer Use.']
|
|
661
|
+
}))
|
|
662
|
+
: deferredNativeRepair('sks.doctor-computer-use-repair.v1', doctorFix, [
|
|
663
|
+
'Computer Use route needs manual OS/App permission verification before use.',
|
|
664
|
+
'Run `sks doctor --fix --repair-native-capabilities --json` for an explicit Computer Use repair probe.'
|
|
665
|
+
]);
|
|
666
|
+
const browserUseRepair = shouldProbeNativeCapabilityRepairs
|
|
667
|
+
? await repairBrowserUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
|
|
668
|
+
schema: 'sks.doctor-browser-use-repair.v1',
|
|
669
|
+
ok: false,
|
|
670
|
+
attempted: false,
|
|
671
|
+
apply: doctorFix,
|
|
672
|
+
recovered: false,
|
|
673
|
+
blockers: [err?.message || String(err)],
|
|
674
|
+
next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Browser Use / Chrome extension.']
|
|
675
|
+
}))
|
|
676
|
+
: deferredNativeRepair('sks.doctor-browser-use-repair.v1', doctorFix, [
|
|
677
|
+
'Chrome/web review route needs the Codex Chrome Extension enabled before use.',
|
|
678
|
+
'Run `sks doctor --fix --repair-native-capabilities --json` for an explicit Browser Use repair probe.'
|
|
679
|
+
]);
|
|
665
680
|
const mcpTransportCollisionRepair = doctorFix
|
|
666
681
|
? await detectAndRepairMcpTransportCollisions({ root, apply: true }).catch((err) => ({
|
|
667
682
|
schema: 'sks.mcp-transport-collision-repair.v1',
|
|
@@ -675,7 +690,9 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
675
690
|
raw_secret_values_recorded: false
|
|
676
691
|
}))
|
|
677
692
|
: null;
|
|
678
|
-
const nativeCapabilityReadinessStatus = (repair) =>
|
|
693
|
+
const nativeCapabilityReadinessStatus = (repair) => repair?.skipped === true
|
|
694
|
+
? (repair.status || 'deferred')
|
|
695
|
+
: (repair?.recovered === true || repair?.ok === true ? 'ok' : repair?.attempted ? 'blocked' : 'not-needed');
|
|
679
696
|
const nativeCapabilityReadiness = {
|
|
680
697
|
schema: 'sks.native-capability-readiness.v1',
|
|
681
698
|
generated_at: nowIso(),
|
|
@@ -1211,6 +1228,21 @@ function buildRuntimeReadiness(zellijReadiness, matrix) {
|
|
|
1211
1228
|
repair_actions: [...new Set(repairActions)]
|
|
1212
1229
|
};
|
|
1213
1230
|
}
|
|
1231
|
+
function deferredNativeRepair(schema, doctorFix, nextActions) {
|
|
1232
|
+
return {
|
|
1233
|
+
schema,
|
|
1234
|
+
generated_at: nowIso(),
|
|
1235
|
+
ok: true,
|
|
1236
|
+
skipped: true,
|
|
1237
|
+
status: 'deferred_to_explicit_native_capability_probe',
|
|
1238
|
+
attempted: false,
|
|
1239
|
+
apply: doctorFix,
|
|
1240
|
+
recovered: false,
|
|
1241
|
+
blockers: [],
|
|
1242
|
+
next_actions: nextActions,
|
|
1243
|
+
manual_actions: nextActions
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1214
1246
|
function fallbackCodexNativeFeatureMatrix(codex, blockers = [], warnings = []) {
|
|
1215
1247
|
return {
|
|
1216
1248
|
schema: 'sks.codex-native-feature-matrix.v1',
|