sneakoscope 5.6.1 → 5.8.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/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 +1 -1
- package/dist/cli/command-registry.js +2 -3
- package/dist/cli/install-helpers.js +21 -15
- package/dist/cli/{insane-search-command.js → super-search-command.js} +96 -55
- package/dist/cli/xai-command.js +7 -7
- package/dist/commands/doctor.js +44 -22
- package/dist/config/skills-manifest.json +63 -70
- package/dist/core/agents/agent-codex-cockpit.js +3 -3
- package/dist/core/agents/agent-orchestrator.js +20 -2
- package/dist/core/agents/agent-wrongness.js +1 -1
- package/dist/core/agents/native-cli-session-swarm.js +14 -1
- package/dist/core/agents/parallel-runtime-proof.js +82 -8
- package/dist/core/codex/agent-config-file-repair.js +2 -1
- package/dist/core/codex/codex-config-guard.js +10 -0
- package/dist/core/codex-app/sks-menubar.js +66 -19
- package/dist/core/commands/gc-command.js +12 -6
- package/dist/core/commands/run-command.js +25 -19
- package/dist/core/feature-fixtures.js +15 -8
- package/dist/core/fsx.js +1 -1
- package/dist/core/init/skills.js +1 -2
- package/dist/core/mission.js +41 -15
- package/dist/core/release-parallel-full-coverage.js +1 -1
- package/dist/core/retention.js +1 -1
- package/dist/core/routes/constants.js +2 -2
- package/dist/core/routes.js +150 -52
- package/dist/core/source-intelligence/source-intelligence-policy.js +5 -5
- package/dist/core/source-intelligence/source-intelligence-proof.js +8 -8
- package/dist/core/source-intelligence/source-intelligence-runner.js +16 -16
- package/dist/core/strategy/strategy-gate.js +2 -1
- package/dist/core/super-search/runtime-helpers.js +289 -0
- package/dist/core/super-search/runtime.js +259 -0
- package/dist/core/super-search/source-records.js +96 -0
- package/dist/core/super-search/types.js +3 -0
- package/dist/core/trust-kernel/trust-report.js +3 -3
- package/dist/core/update/update-migration-state.js +178 -33
- package/dist/core/verification/real-evidence-policy.js +55 -0
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-visual-consistency-check.js +1 -1
- package/dist/scripts/check-architecture.js +0 -1
- package/dist/scripts/codex-lb-gpt55-fast-profile-check.js +3 -2
- package/dist/scripts/mutation-callsite-coverage-check.js +7 -0
- package/dist/scripts/packlist-performance-check.js +4 -2
- package/dist/scripts/release-metadata-1-19-check.js +14 -3
- package/dist/scripts/release-parallel-check.js +2 -2
- package/dist/scripts/release-parallel-full-coverage-check.js +1 -1
- package/dist/scripts/sks-1-18-gate-lib.js +2 -2
- package/dist/scripts/sks-menubar-install-check.js +83 -0
- package/dist/scripts/source-intelligence-all-modes-check.js +2 -2
- package/dist/scripts/source-intelligence-policy-check.js +1 -1
- package/dist/scripts/super-search-name-guard-check.js +98 -0
- package/dist/scripts/{ultra-search-provider-interface-check.js → super-search-provider-interface-check.js} +9 -9
- package/dist/scripts/trust-fixture-check.js +19 -6
- package/package.json +22 -7
- package/schemas/agents/parallel-runtime-proof.schema.json +17 -1
- package/dist/core/ultra-search/runtime.js +0 -502
- package/dist/core/ultra-search/types.js +0 -3
- package/dist/scripts/release-readiness-report.js +0 -1262
- /package/dist/core/{ultra-search → super-search}/index.js +0 -0
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:
|
|
17
|
+
Current release: SKS **5.8.0**. New in this release: intent routing no longer treats every question mark as answer-only, Naruto parallel-write proof now requires real worker/file/timestamp evidence, production gates reject mock-only or source-less success, and the fragmented legacy search surface is replaced by the canonical `sks super-search` / `$Super-Search` path. See [CHANGELOG.md](CHANGELOG.md).
|
|
18
18
|
|
|
19
19
|
## Install
|
|
20
20
|
|
|
@@ -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.8.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
|
@@ -143,7 +143,7 @@ export const COMMANDS = {
|
|
|
143
143
|
'mad-db': routeStateMutator(entry('beta', 'Deprecated alias for MAD-SKS SQL-plane execution; redirects to sks mad-sks sql|apply-migration', 'dist/commands/mad-db.js', directCommand(() => import('../commands/mad-db.js'), 'dist/commands/mad-db.js')), ['mad-sks-gate.json']),
|
|
144
144
|
'auto-review': entry('beta', 'Manage auto-review profile', 'dist/commands/auto-review.js', directCommand(() => import('../commands/auto-review.js'), 'dist/commands/auto-review.js')),
|
|
145
145
|
'dollar-commands': entry('stable', 'List Codex App dollar commands', 'dist/core/commands/basic-cli.js', basicArgs('dollarCommandsCommand')),
|
|
146
|
-
'fast-mode': entry('stable', 'Toggle SKS Fast mode default for dollar-command routes', 'dist/core/commands/fast-mode-command.js', argsCommand(() => import('../core/commands/fast-mode-command.js'), 'fastModeCommand', 'dist/core/commands/fast-mode-command.js')),
|
|
146
|
+
'fast-mode': skipMigrationGate(entry('stable', 'Toggle SKS Fast mode default for dollar-command routes', 'dist/core/commands/fast-mode-command.js', argsCommand(() => import('../core/commands/fast-mode-command.js'), 'fastModeCommand', 'dist/core/commands/fast-mode-command.js'))),
|
|
147
147
|
commit: entry('stable', 'Create a simple git commit', 'dist/commands/commit.js', directCommand(() => import('../commands/commit.js'), 'dist/commands/commit.js')),
|
|
148
148
|
'commit-and-push': entry('stable', 'Create a simple git commit and push', 'dist/commands/commit-and-push.js', directCommand(() => import('../commands/commit-and-push.js'), 'dist/commands/commit-and-push.js')),
|
|
149
149
|
dfix: routeStateMutator(entry('stable', 'Run DFix diagnose/plan/patch/verify loop', 'dist/core/commands/dfix-command.js', commandArgsCommand(() => import('../core/commands/dfix-command.js'), 'dfixCommand', 'dist/core/commands/dfix-command.js')), ['dfix-gate.json']),
|
|
@@ -161,8 +161,7 @@ export const COMMANDS = {
|
|
|
161
161
|
'image-ux-review': routeStateMutator(entry('labs', 'Inspect image UX artifacts', 'dist/core/commands/image-ux-review-command.js', commandArgsCommand(() => import('../core/commands/image-ux-review-command.js'), 'imageUxReviewCommand', 'dist/core/commands/image-ux-review-command.js')), ['image-ux-review-gate.json']),
|
|
162
162
|
'computer-use': routeStateMutator(entry('beta', 'Record native Mac/non-web Computer Use visual evidence', 'dist/core/commands/computer-use-command.js', commandArgsCommand(() => import('../core/commands/computer-use-command.js'), 'computerUseCommand', 'dist/core/commands/computer-use-command.js')), ['computer-use-gate.json']),
|
|
163
163
|
context7: entry('beta', 'Context7 checks and docs', 'dist/cli/context7-command.js', subcommand(() => import('./context7-command.js'), 'context7Command', 'dist/cli/context7-command.js', 'check')),
|
|
164
|
-
'
|
|
165
|
-
'ultra-search': entry('beta', 'Compatibility alias for InsaneSearch source intelligence', 'dist/cli/insane-search-command.js', subcommand(() => import('./insane-search-command.js'), 'ultraSearchCommand', 'dist/cli/insane-search-command.js', 'doctor')),
|
|
164
|
+
'super-search': entry('beta', 'Run Super-Search provider-independent source intelligence', 'dist/cli/super-search-command.js', subcommand(() => import('./super-search-command.js'), 'superSearchCommand', 'dist/cli/super-search-command.js', 'doctor')),
|
|
166
165
|
xai: entry('beta', 'Deprecated compatibility notice for removed xAI/Grok setup', 'dist/cli/xai-command.js', subcommand(() => import('./xai-command.js'), 'xaiCommand', 'dist/cli/xai-command.js', 'check')),
|
|
167
166
|
recallpulse: entry('labs', 'RecallPulse evidence route', 'dist/commands/recallpulse.js', directCommand(() => import('../commands/recallpulse.js'), 'dist/commands/recallpulse.js')),
|
|
168
167
|
pipeline: activeRouteDiagnostic(entry('beta', 'Inspect pipeline missions', 'dist/commands/pipeline.js', directCommand(() => import('../commands/pipeline.js'), 'dist/commands/pipeline.js'))),
|
|
@@ -23,6 +23,7 @@ import { extractTomlTable, writeCodexConfigGuarded } from '../core/codex/codex-c
|
|
|
23
23
|
import { cleanupCodexConfigBackups, validateCodexConfigRoundTrip } from '../core/codex/codex-config-toml.js';
|
|
24
24
|
import { runPostinstallGlobalDoctorAndMarkPending } from '../core/update/update-migration-state.js';
|
|
25
25
|
import { repairCodexImagegen } from '../core/doctor/imagegen-repair.js';
|
|
26
|
+
import { REQUIRED_CODEX_MODEL } from '../core/codex-model-guard.js';
|
|
26
27
|
const CODEX_LB_PROVIDER_NAME = 'openai';
|
|
27
28
|
const CODEX_LB_PROVIDER_ENV_KEY = 'CODEX_LB_API_KEY';
|
|
28
29
|
const CODEX_LB_CANONICAL_FAST_SERVICE_TIER = 'priority';
|
|
@@ -275,7 +276,7 @@ async function postinstallHarnessConflictNotice(conflictScan) {
|
|
|
275
276
|
console.log(formatHarnessConflictReport(conflictScan, { includePrompt: false }));
|
|
276
277
|
console.log('\nWhat this means: npm can finish installing the package, but `sks setup` and `sks doctor --fix` will refuse to activate SKS until the conflicting harness is removed with human approval.');
|
|
277
278
|
console.log('No files were removed by postinstall.');
|
|
278
|
-
console.log(
|
|
279
|
+
console.log(`Cleanup requires a human-approved Codex App session. Recommended model: ${REQUIRED_CODEX_MODEL}, reasoning: high.`);
|
|
279
280
|
if (shouldAskPostinstallQuestion()) {
|
|
280
281
|
const answer = await askPostinstallQuestion('Show the cleanup prompt now? [y/N] ');
|
|
281
282
|
if (/^(y|yes|예|네|응)$/i.test(answer.trim())) {
|
|
@@ -901,7 +902,7 @@ export async function checkCodexLbResponseChain(status = {}, opts = {}) {
|
|
|
901
902
|
const fetchImpl = opts.fetch || globalThis.fetch;
|
|
902
903
|
if (typeof fetchImpl !== 'function')
|
|
903
904
|
return { ok: true, status: 'skipped', skipped: true, reason: 'fetch unavailable' };
|
|
904
|
-
const model = opts.model || env.SKS_CODEX_MODEL ||
|
|
905
|
+
const model = opts.model || env.SKS_CODEX_MODEL || REQUIRED_CODEX_MODEL;
|
|
905
906
|
const timeoutMs = Number(opts.timeoutMs || env.SKS_CODEX_LB_CHAIN_CHECK_TIMEOUT_MS || 8000);
|
|
906
907
|
const serviceTier = opts.fastMode === true || opts.serviceTier === 'fast' || opts.serviceTier === CODEX_LB_CANONICAL_FAST_SERVICE_TIER
|
|
907
908
|
? CODEX_LB_CANONICAL_FAST_SERVICE_TIER
|
|
@@ -1890,8 +1891,9 @@ export function normalizeCodexFastModeUiConfig(text = '', opts = {}) {
|
|
|
1890
1891
|
return normalizeCodexFastModeUiConfigOnce(normalizeCodexFastModeUiConfigOnce(text, opts), opts);
|
|
1891
1892
|
}
|
|
1892
1893
|
function normalizeCodexFastModeUiConfigOnce(text = '', opts = {}) {
|
|
1893
|
-
// Keep model
|
|
1894
|
-
// expose its native
|
|
1894
|
+
// Keep SKS-owned model/reasoning defaults out of top-level config so Codex
|
|
1895
|
+
// Desktop can expose its native selectors, but preserve a user's deliberate
|
|
1896
|
+
// top-level model/service/reasoning choices across install, update, and doctor.
|
|
1895
1897
|
let next = String(text || '');
|
|
1896
1898
|
const misplacedDefaultProfile = tomlTableString(next, 'user.fast_mode', 'default_profile');
|
|
1897
1899
|
next = removeLegacyTopLevelCodexModeLocks(next);
|
|
@@ -1940,7 +1942,7 @@ function normalizeCodexFastModeUiConfigOnce(text = '', opts = {}) {
|
|
|
1940
1942
|
// they are managed as per-file `<name>.config.toml` overlays by
|
|
1941
1943
|
// migrateSksProfilesToPerFile (src/core/auto-review.ts), which also writes the
|
|
1942
1944
|
// sks-fast-high overlay for CLI `--profile` use.
|
|
1943
|
-
next = upsertTomlTableKey(next, 'profiles.sks-fast-high',
|
|
1945
|
+
next = upsertTomlTableKey(next, 'profiles.sks-fast-high', `model = "${REQUIRED_CODEX_MODEL}"`);
|
|
1944
1946
|
next = upsertTomlTableKey(next, 'profiles.sks-fast-high', 'service_tier = "fast"');
|
|
1945
1947
|
next = upsertTomlTableKey(next, 'profiles.sks-fast-high', 'approval_policy = "on-request"');
|
|
1946
1948
|
// Do not force a sandbox from the Codex App fast profile. The App/IDE
|
|
@@ -1966,9 +1968,13 @@ function removeLegacyTopLevelCodexModeLocks(text = '') {
|
|
|
1966
1968
|
const lines = String(text || '').split('\n');
|
|
1967
1969
|
const firstTable = lines.findIndex((x) => /^\s*\[.+\]\s*$/.test(x));
|
|
1968
1970
|
const end = firstTable === -1 ? lines.length : firstTable;
|
|
1971
|
+
const topLevelModel = topLevelTomlString(text, 'model');
|
|
1972
|
+
const removeSksOwnedModeLock = topLevelModel === REQUIRED_CODEX_MODEL;
|
|
1969
1973
|
return lines.filter((line, index) => {
|
|
1970
1974
|
if (index >= end)
|
|
1971
1975
|
return true;
|
|
1976
|
+
if (!removeSksOwnedModeLock)
|
|
1977
|
+
return true;
|
|
1972
1978
|
return !/^\s*(?:model|model_reasoning_effort)\s*=/.test(line);
|
|
1973
1979
|
}).join('\n').replace(/^\n+/, '').replace(/\n{3,}/g, '\n\n');
|
|
1974
1980
|
}
|
|
@@ -2142,7 +2148,7 @@ export function codexFastModeDesktopStatus(text = '') {
|
|
|
2142
2148
|
const profile = validation.parsed?.profiles?.['sks-fast-high'];
|
|
2143
2149
|
const globalOn = validation.ok
|
|
2144
2150
|
&& validation.default_profile === 'sks-fast-high'
|
|
2145
|
-
&& profile?.model ===
|
|
2151
|
+
&& profile?.model === REQUIRED_CODEX_MODEL
|
|
2146
2152
|
&& profile?.service_tier === 'fast';
|
|
2147
2153
|
return {
|
|
2148
2154
|
schema: 'sks.codex-fast-mode-desktop-status.v1',
|
|
@@ -2862,7 +2868,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
2862
2868
|
// escape that dash emits literally and bash collapses to `"`).
|
|
2863
2869
|
await writeTextAtomic(codexLbFakeCodex, "#!/bin/sh\nif [ \"$1\" = \"--version\" ]; then echo \"codex-cli 99.0.0\"; exit 0; fi\nif [ \"$1\" = \"login\" ] && [ \"$2\" = \"status\" ]; then echo \"logged in with browser auth\"; exit 0; fi\nif [ \"$1\" = \"login\" ] && [ \"$2\" = \"--with-api-key\" ]; then read key; mkdir -p \"$HOME/.codex\"; printf '{\"auth_mode\":\"apikey\",\"OPENAI_API_KEY\":\"%s\"}\\n' \"$key\" > \"$HOME/.codex/auth.json\"; printf '%s\\n' \"$key\" >> \"$HOME/.codex/login-calls.log\"; exit 0; fi\necho \"fake codex unsupported\" >&2\nexit 1\n");
|
|
2864
2870
|
await fsp.chmod(codexLbFakeCodex, 0o755);
|
|
2865
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
2871
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `model = "${REQUIRED_CODEX_MODEL}"\nmodel_reasoning_effort = "low"\nservice_tier = "fast"\nsuppress_unstable_features_warning = true\n\n[profiles.custom]\nmodel_reasoning_effort = "low"\n\n[notice]\nfast_default_opt_out = true\n\n[features]\nhooks = true\n`);
|
|
2866
2872
|
const codexLbEnvForSelftest = { HOME: codexLbHome, SKS_GLOBAL_ROOT: path.join(tmp, 'codex-lb-global'), PATH: `${codexLbFakeBin}${path.delimiter}${process.env.PATH || ''}`, SKS_SKIP_CODEX_LB_LAUNCH_ENV: '1' };
|
|
2867
2873
|
const codexLbSetup = await runProcess(process.execPath, [packagedSksEntrypoint(), 'codex-lb', 'setup', '--host', 'lb.example.test', '--api-key', 'sk-test', '--json'], {
|
|
2868
2874
|
cwd: tmp,
|
|
@@ -2967,7 +2973,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
2967
2973
|
await postinstall({
|
|
2968
2974
|
bootstrap: async () => {
|
|
2969
2975
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'auth.json'), '{"auth_mode":"browser"}\n');
|
|
2970
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
2976
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `model = "${REQUIRED_CODEX_MODEL}"\nservice_tier = "fast"\nsuppress_unstable_features_warning = true\n\n[features]\nhooks = true\n`);
|
|
2971
2977
|
}
|
|
2972
2978
|
});
|
|
2973
2979
|
}
|
|
@@ -2993,7 +2999,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
2993
2999
|
await writeTextAtomic(path.join(doctorProject, 'package.json'), '{"name":"codex-lb-doctor-project","version":"0.0.0"}\n');
|
|
2994
3000
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\nexport CODEX_LB_API_KEY='sk-test'\n");
|
|
2995
3001
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'auth.json'), '{"auth_mode":"browser"}\n');
|
|
2996
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
3002
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `model = "${REQUIRED_CODEX_MODEL}"\nservice_tier = "fast"\nsuppress_unstable_features_warning = true\n\n[features]\nhooks = true\n`);
|
|
2997
3003
|
const codexLbDoctorRepair = await runProcess(process.execPath, [packagedSksEntrypoint(), 'doctor', '--fix', '--json'], {
|
|
2998
3004
|
cwd: doctorProject,
|
|
2999
3005
|
env: { ...codexLbEnvForSelftest, SKS_GLOBAL_ROOT: path.join(tmp, 'codex-lb-doctor-global') },
|
|
@@ -3186,7 +3192,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
3186
3192
|
if (!codexLbLegacyDoctorJson.repair?.codex_lb?.ok || !codexLbLegacyDoctorJson.repair.codex_lb.legacy_auth_migrated || !codexLbLegacyDoctorEnv.includes("CODEX_LB_API_KEY='sk-legacy-doctor'") || !codexLbLegacyDoctorAuth.includes('"auth_mode":"apikey"') || !codexLbLegacyDoctorAuth.includes('sk-legacy-doctor') || !hasTopLevelCodexLbSelected(codexLbLegacyDoctorConfig) || !codexLbLegacyDoctorConfig.includes('env_key = "CODEX_LB_API_KEY"'))
|
|
3187
3193
|
throw new Error('selftest: legacy doctor codex-lb restore');
|
|
3188
3194
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\n");
|
|
3189
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
3195
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `model = "${REQUIRED_CODEX_MODEL}"\nservice_tier = "fast"\n`);
|
|
3190
3196
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'auth.json'), '{"auth_mode":"apikey","key":"sk-env-only"}\n');
|
|
3191
3197
|
const codexLbLoginCallsBeforeEnvOnlyPostinstall = await codexLbLoginCallCount(codexLbHome);
|
|
3192
3198
|
const codexLbEnvOnlyPostinstall = await runProcess(process.execPath, [packagedSksEntrypoint(), 'postinstall'], {
|
|
@@ -3204,7 +3210,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
3204
3210
|
if (!String(codexLbEnvOnlyPostinstall.stdout || '').includes('codex-lb auth: restored from existing Codex login cache') || !codexLbEnvOnlyPostinstallEnv.includes("CODEX_LB_API_KEY='sk-env-only'") || !codexLbEnvOnlyPostinstallConfig.includes('env_key = "CODEX_LB_API_KEY"') || !hasTopLevelCodexLbSelected(codexLbEnvOnlyPostinstallConfig) || !codexLbEnvOnlyPostinstallAuth.includes('sk-env-only') || codexLbLoginCallsAfterEnvOnlyPostinstall !== codexLbLoginCallsBeforeEnvOnlyPostinstall)
|
|
3205
3211
|
throw new Error('selftest: env-only codex-lb postinstall restore');
|
|
3206
3212
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\n");
|
|
3207
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
3213
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `model = "${REQUIRED_CODEX_MODEL}"\nservice_tier = "fast"\n`);
|
|
3208
3214
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'auth.json'), '{"auth_mode":"apikey","key":"sk-env-only-doctor"}\n');
|
|
3209
3215
|
const codexLbEnvOnlyDoctorProject = tmpdir();
|
|
3210
3216
|
await ensureDir(path.join(codexLbEnvOnlyDoctorProject, '.git'));
|
|
@@ -3334,7 +3340,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
3334
3340
|
}
|
|
3335
3341
|
if (autobypassLaunch.status !== 'chain_unhealthy' || autobypassLaunch.bypass_codex_lb !== true || autobypassLaunch.chain_health?.status !== 'second_request_failed')
|
|
3336
3342
|
throw new Error('selftest: SKS_CODEX_LB_AUTOBYPASS=1 should bypass codex-lb on hard chain failure');
|
|
3337
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
3343
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `model = "${REQUIRED_CODEX_MODEL}"\nservice_tier = "fast"\n`);
|
|
3338
3344
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\nexport CODEX_LB_API_KEY='sk-test'\n");
|
|
3339
3345
|
const missingProviderLaunchCalls = [];
|
|
3340
3346
|
const missingProviderLaunch = await maybePromptCodexLbSetupForLaunch([], {
|
|
@@ -3395,11 +3401,11 @@ export async function selftestCodexLb(tmp) {
|
|
|
3395
3401
|
throw new Error('selftest: codex-lb setup did not preserve Codex App feature flags, default plugins, profile-scoped reasoning effort, explicit Fast profile, Codex Git commit generation, or migrate the hooks feature flag');
|
|
3396
3402
|
if (!hasCodexUnstableFeatureWarningSuppression(codexLbConfig))
|
|
3397
3403
|
throw new Error('selftest: codex-lb setup did not suppress Codex unstable feature warning');
|
|
3398
|
-
const codexLbLaunch = `source ${path.join(tmp, '.codex', 'sks-codex-lb.env')} && codex '--model' '
|
|
3404
|
+
const codexLbLaunch = `source ${path.join(tmp, '.codex', 'sks-codex-lb.env')} && codex '--model' '${REQUIRED_CODEX_MODEL}'`;
|
|
3399
3405
|
if (!codexLbLaunch.includes('sks-codex-lb.env'))
|
|
3400
3406
|
throw new Error('selftest: Zellij launch command does not source codex-lb env file');
|
|
3401
|
-
if (!codexLbLaunch.includes(
|
|
3402
|
-
throw new Error(
|
|
3407
|
+
if (!codexLbLaunch.includes(`'--model' '${REQUIRED_CODEX_MODEL}'`))
|
|
3408
|
+
throw new Error(`selftest: Zellij launch command without args did not force ${REQUIRED_CODEX_MODEL}`);
|
|
3403
3409
|
const madLaunchSource = await safeReadText(path.join(packageRoot(), 'src', 'core', 'commands', 'mad-sks-command.js'));
|
|
3404
3410
|
if (!madLaunchSource.includes('const lb = await deps.maybePromptCodexLbSetupForLaunch(args)') || !madLaunchSource.includes("const launchLb = lb.status === 'present'") || !madLaunchSource.includes('codexLbImmediateLaunchOpts(cleanArgs, launchLb') || !madLaunchSource.includes('bypass_codex_lb') || !madLaunchSource.includes('model_provider="openai"') || !madLaunchSource.includes('codexLbFreshSession: true'))
|
|
3405
3411
|
throw new Error('selftest: MAD launch does not sync codex-lb auth and fresh-session launch options');
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import {
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { runSuperSearch } from '../core/super-search/index.js';
|
|
5
6
|
import { evaluateLocalGate } from '../core/commands/route-success-helpers.js';
|
|
6
|
-
|
|
7
|
+
import { evaluateRealEvidencePolicy } from '../core/verification/real-evidence-policy.js';
|
|
8
|
+
export async function superSearchCommand(sub = 'help', args = []) {
|
|
7
9
|
const action = sub || 'help';
|
|
8
10
|
if (action === 'run')
|
|
9
11
|
return runCommand(args);
|
|
@@ -19,24 +21,25 @@ export async function insaneSearchCommand(sub = 'help', args = []) {
|
|
|
19
21
|
return cacheCommand(args);
|
|
20
22
|
if (action === 'bench')
|
|
21
23
|
return benchCommand(args);
|
|
22
|
-
if (action === 'migrate-xai')
|
|
23
|
-
return migrateXaiCommand(args);
|
|
24
24
|
return helpCommand();
|
|
25
25
|
}
|
|
26
|
-
export const ultraSearchCommand = insaneSearchCommand;
|
|
27
26
|
async function runCommand(args) {
|
|
28
27
|
const json = args.includes('--json');
|
|
29
28
|
const mode = readOption(args, '--mode');
|
|
30
|
-
const
|
|
29
|
+
const rawQuery = positional(args).join(' ').trim();
|
|
30
|
+
const query = rawQuery || (mode === 'url_acquisition' ? 'fetch' : '');
|
|
31
31
|
if (!query)
|
|
32
|
-
throw new Error('Usage: sks
|
|
32
|
+
throw new Error('Usage: sks super-search run "<query>" [--mode fast|balanced|deep|exhaustive] [--json]');
|
|
33
|
+
if (mode && !['fast', 'balanced', 'deep', 'exhaustive', 'x_search', 'url_acquisition'].includes(mode)) {
|
|
34
|
+
throw new Error('Unsupported Super-Search mode: ' + mode);
|
|
35
|
+
}
|
|
33
36
|
const missionDir = await mkMissionDir();
|
|
34
|
-
const result = await
|
|
37
|
+
const result = await runSuperSearch({
|
|
35
38
|
missionDir,
|
|
36
39
|
query,
|
|
37
40
|
...(mode ? { mode } : {})
|
|
38
41
|
});
|
|
39
|
-
const gate = await
|
|
42
|
+
const gate = await evaluateSuperSearchGate(missionDir);
|
|
40
43
|
const finalResult = {
|
|
41
44
|
...result,
|
|
42
45
|
ok: result.ok === true && gate.ok === true,
|
|
@@ -46,7 +49,7 @@ async function runCommand(args) {
|
|
|
46
49
|
if (json)
|
|
47
50
|
console.log(JSON.stringify(finalResult, null, 2));
|
|
48
51
|
else {
|
|
49
|
-
console.log(`
|
|
52
|
+
console.log(`Super-Search ${finalResult.ok ? 'completed' : 'partial/blocked'}: ${result.mode}`);
|
|
50
53
|
console.log(`Mission: ${missionDir}`);
|
|
51
54
|
console.log(`Sources: ${result.sources.length}, verified: ${result.proof.verified_source_count}`);
|
|
52
55
|
if (finalResult.blockers.length)
|
|
@@ -59,7 +62,7 @@ async function runCommand(args) {
|
|
|
59
62
|
async function doctorCommand(args) {
|
|
60
63
|
const json = args.includes('--json');
|
|
61
64
|
const report = {
|
|
62
|
-
schema: 'sks.
|
|
65
|
+
schema: 'sks.super-search-doctor.v1',
|
|
63
66
|
ok: true,
|
|
64
67
|
core_ready: true,
|
|
65
68
|
xai_required: false,
|
|
@@ -75,18 +78,31 @@ async function doctorCommand(args) {
|
|
|
75
78
|
if (json)
|
|
76
79
|
console.log(JSON.stringify(report, null, 2));
|
|
77
80
|
else
|
|
78
|
-
console.log('
|
|
81
|
+
console.log('Super-Search doctor: core ready; xAI/Grok is not required.');
|
|
79
82
|
return report;
|
|
80
83
|
}
|
|
81
84
|
async function inspectCommand(action, args) {
|
|
82
85
|
const json = args.includes('--json');
|
|
83
86
|
const mission = positional(args)[0] || 'latest';
|
|
84
87
|
const target = mission === 'latest' ? await latestMissionDir() : mission;
|
|
85
|
-
const file = path.join(target, '
|
|
86
|
-
const text = await fs.readFile(file, 'utf8');
|
|
87
|
-
const parsed = JSON.parse(text)
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
const file = path.join(target, 'super-search', action === 'sources' ? 'source-ledger.json' : action === 'claims' ? 'claim-ledger.json' : 'super-search-result.json');
|
|
89
|
+
const text = await fs.readFile(file, 'utf8').catch(() => null);
|
|
90
|
+
const parsed = text ? JSON.parse(text) : {
|
|
91
|
+
schema: 'sks.super-search-inspect-missing.v1',
|
|
92
|
+
ok: false,
|
|
93
|
+
mission: target,
|
|
94
|
+
blockers: ['super_search_mission_artifact_missing:' + path.relative(process.cwd(), file)]
|
|
95
|
+
};
|
|
96
|
+
const gate = await evaluateSuperSearchGate(target);
|
|
97
|
+
const evidence = await evaluateSuperSearchArtifacts(target);
|
|
98
|
+
const parsedOk = parsed.ok === false ? false : true;
|
|
99
|
+
const result = {
|
|
100
|
+
...parsed,
|
|
101
|
+
ok: parsedOk && gate.ok === true && evidence.ok === true,
|
|
102
|
+
gate_evaluation: gate,
|
|
103
|
+
real_evidence_policy: evidence,
|
|
104
|
+
blockers: [...new Set([...(parsed.blockers || []), ...gate.blockers, ...evidence.blockers])]
|
|
105
|
+
};
|
|
90
106
|
if (!result.ok)
|
|
91
107
|
process.exitCode = 1;
|
|
92
108
|
if (json)
|
|
@@ -97,13 +113,13 @@ async function inspectCommand(action, args) {
|
|
|
97
113
|
}
|
|
98
114
|
async function cacheCommand(args) {
|
|
99
115
|
const sub = positional(args)[0] || 'status';
|
|
100
|
-
const report = { schema: 'sks.
|
|
116
|
+
const report = { schema: 'sks.super-search-cache.v1', ok: true, action: sub, local_only: true };
|
|
101
117
|
console.log(JSON.stringify(report, null, 2));
|
|
102
118
|
return report;
|
|
103
119
|
}
|
|
104
120
|
async function benchCommand(args) {
|
|
105
121
|
const report = {
|
|
106
|
-
schema: 'sks.
|
|
122
|
+
schema: 'sks.super-search-bench.v1',
|
|
107
123
|
ok: false,
|
|
108
124
|
suite: readOption(args, '--suite') || 'all',
|
|
109
125
|
status: 'real_benchmark_not_run',
|
|
@@ -112,33 +128,16 @@ async function benchCommand(args) {
|
|
|
112
128
|
console.log(JSON.stringify(report, null, 2));
|
|
113
129
|
return report;
|
|
114
130
|
}
|
|
115
|
-
async function migrateXaiCommand(args) {
|
|
116
|
-
const apply = args.includes('--apply');
|
|
117
|
-
const report = {
|
|
118
|
-
schema: apply ? 'sks.ultra-search-xai-migration-result.v1' : 'sks.ultra-search-xai-migration-plan.v1',
|
|
119
|
-
ok: true,
|
|
120
|
-
applied: false,
|
|
121
|
-
managed_candidates: [],
|
|
122
|
-
unowned_preserved: true,
|
|
123
|
-
note: 'No automatic MCP config deletion is performed without an owned managed marker and explicit --apply.'
|
|
124
|
-
};
|
|
125
|
-
console.log(JSON.stringify(report, null, 2));
|
|
126
|
-
return report;
|
|
127
|
-
}
|
|
128
131
|
function helpCommand() {
|
|
129
132
|
console.log([
|
|
130
133
|
'Usage:',
|
|
131
|
-
' sks
|
|
132
|
-
' sks
|
|
133
|
-
' sks
|
|
134
|
-
' sks
|
|
135
|
-
' sks
|
|
136
|
-
' sks
|
|
137
|
-
' sks
|
|
138
|
-
' sks insane-search migrate-xai [--apply]',
|
|
139
|
-
'',
|
|
140
|
-
'Compatibility:',
|
|
141
|
-
' sks ultra-search ...'
|
|
134
|
+
' sks super-search doctor [--json]',
|
|
135
|
+
' sks super-search run "<query>" [--mode fast|balanced|deep|exhaustive] [--json]',
|
|
136
|
+
' sks super-search x "<query>" [--json]',
|
|
137
|
+
' sks super-search fetch "<url>" [--json]',
|
|
138
|
+
' sks super-search status|inspect|sources|claims <mission|latest> [--json]',
|
|
139
|
+
' sks super-search cache status|prune|clear [--json]',
|
|
140
|
+
' sks super-search bench [--suite all|x|web|docs|blocked] [--json]'
|
|
142
141
|
].join('\n'));
|
|
143
142
|
return { ok: true, status: 'help' };
|
|
144
143
|
}
|
|
@@ -163,7 +162,7 @@ function positional(args) {
|
|
|
163
162
|
return out;
|
|
164
163
|
}
|
|
165
164
|
async function mkMissionDir() {
|
|
166
|
-
const dir = path.join(process.cwd(), '.sneakoscope', 'missions', `
|
|
165
|
+
const dir = path.join(process.cwd(), '.sneakoscope', 'missions', `super-search-${Date.now().toString(36)}-${randomUUID().slice(0, 8)}`);
|
|
167
166
|
await fs.mkdir(dir, { recursive: true });
|
|
168
167
|
return dir;
|
|
169
168
|
}
|
|
@@ -171,25 +170,67 @@ async function latestMissionDir() {
|
|
|
171
170
|
const root = path.join(process.cwd(), '.sneakoscope', 'missions');
|
|
172
171
|
const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
173
172
|
const dirs = entries.filter((entry) => entry.isDirectory()).map((entry) => path.join(root, entry.name)).sort();
|
|
174
|
-
|
|
173
|
+
let latest = null;
|
|
174
|
+
for (const dir of dirs.reverse()) {
|
|
175
|
+
if (await hasSuperSearchArtifactDir(dir)) {
|
|
176
|
+
latest = dir;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
175
180
|
if (!latest)
|
|
176
|
-
return path.join(os.tmpdir(), 'sks-
|
|
181
|
+
return path.join(os.tmpdir(), 'sks-super-search-missing');
|
|
177
182
|
return latest;
|
|
178
183
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
184
|
+
async function hasSuperSearchArtifactDir(dir) {
|
|
185
|
+
try {
|
|
186
|
+
const stat = await fs.stat(path.join(dir, 'super-search'));
|
|
187
|
+
return stat.isDirectory();
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
181
192
|
}
|
|
182
|
-
async function
|
|
193
|
+
async function evaluateSuperSearchGate(missionDir) {
|
|
183
194
|
return evaluateLocalGate({
|
|
184
195
|
root: process.cwd(),
|
|
185
196
|
dir: missionDir,
|
|
186
|
-
gateFile: path.join('
|
|
197
|
+
gateFile: path.join('super-search', 'super-search-gate.json'),
|
|
187
198
|
requiredArtifacts: [
|
|
188
|
-
path.join('
|
|
189
|
-
path.join('
|
|
190
|
-
path.join('
|
|
191
|
-
path.join('
|
|
199
|
+
path.join('super-search', 'source-ledger.json'),
|
|
200
|
+
path.join('super-search', 'claim-ledger.json'),
|
|
201
|
+
path.join('super-search', 'super-search-proof.json'),
|
|
202
|
+
path.join('super-search', 'super-search-result.json')
|
|
192
203
|
]
|
|
193
204
|
});
|
|
194
205
|
}
|
|
195
|
-
|
|
206
|
+
async function evaluateSuperSearchArtifacts(missionDir) {
|
|
207
|
+
const artifactDir = path.join(missionDir, 'super-search');
|
|
208
|
+
const [result, sourceLedger, claimLedger, proof] = await Promise.all([
|
|
209
|
+
readJsonFile(path.join(artifactDir, 'super-search-result.json')),
|
|
210
|
+
readJsonFile(path.join(artifactDir, 'source-ledger.json')),
|
|
211
|
+
readJsonFile(path.join(artifactDir, 'claim-ledger.json')),
|
|
212
|
+
readJsonFile(path.join(artifactDir, 'super-search-proof.json'))
|
|
213
|
+
]);
|
|
214
|
+
const sources = Array.isArray(result?.sources) ? result.sources : Array.isArray(sourceLedger?.sources) ? sourceLedger.sources : [];
|
|
215
|
+
const claims = Array.isArray(result?.claims) ? result.claims : Array.isArray(claimLedger?.claims) ? claimLedger.claims : [];
|
|
216
|
+
const proofData = result?.proof || proof || {};
|
|
217
|
+
return evaluateRealEvidencePolicy({
|
|
218
|
+
productionMode: true,
|
|
219
|
+
mode: result?.mode || proofData?.mode,
|
|
220
|
+
sources,
|
|
221
|
+
claims,
|
|
222
|
+
proof: proofData
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
async function readJsonFile(file) {
|
|
226
|
+
const text = await fs.readFile(file, 'utf8').catch(() => null);
|
|
227
|
+
if (!text)
|
|
228
|
+
return null;
|
|
229
|
+
try {
|
|
230
|
+
return JSON.parse(text);
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=super-search-command.js.map
|
package/dist/cli/xai-command.js
CHANGED
|
@@ -9,19 +9,19 @@ export async function xaiCommand(sub = 'check', args = []) {
|
|
|
9
9
|
setup_performed: false,
|
|
10
10
|
xai_required: false,
|
|
11
11
|
replacement: {
|
|
12
|
-
doctor: 'sks
|
|
13
|
-
x_search: 'sks
|
|
14
|
-
|
|
12
|
+
doctor: 'sks super-search doctor',
|
|
13
|
+
x_search: 'sks super-search x "<query>"',
|
|
14
|
+
fetch: 'sks super-search fetch "<url>"'
|
|
15
15
|
},
|
|
16
|
-
blockers: action === 'setup' ? ['
|
|
16
|
+
blockers: action === 'setup' ? ['xai_setup_removed_use_super_search'] : [],
|
|
17
17
|
warnings: ['sks_xai_is_deprecated_and_does_not_configure_mcp_or_require_XAI_API_KEY']
|
|
18
18
|
};
|
|
19
19
|
if (json)
|
|
20
20
|
console.log(JSON.stringify(result, null, 2));
|
|
21
21
|
else {
|
|
22
|
-
console.log('`sks xai` is deprecated.
|
|
23
|
-
console.log('Use: sks
|
|
24
|
-
console.log('Use: sks
|
|
22
|
+
console.log('`sks xai` is deprecated. Super-Search no longer requires xAI/Grok or XAI_API_KEY.');
|
|
23
|
+
console.log('Use: sks super-search doctor');
|
|
24
|
+
console.log('Use: sks super-search x "<query>"');
|
|
25
25
|
if (action === 'setup') {
|
|
26
26
|
console.log('No MCP setup was performed.');
|
|
27
27
|
process.exitCode = 1;
|
package/dist/commands/doctor.js
CHANGED
|
@@ -41,7 +41,7 @@ import { runDoctorFixTransaction } from '../core/doctor/doctor-transaction.js';
|
|
|
41
41
|
import { planDoctorDirtyRepair } from '../core/doctor/doctor-dirty-planner.js';
|
|
42
42
|
import { doctorRepairPostcheck } from '../core/doctor/doctor-repair-postcheck.js';
|
|
43
43
|
import { withSecretPreservationGuard } from '../core/config/config-migration-journal.js';
|
|
44
|
-
import { writeProjectUpdateMigrationReceipt } from '../core/update/update-migration-state.js';
|
|
44
|
+
import { isUpdateMigrationReceiptCurrent, projectUpdateMigrationReceiptPath, writeProjectUpdateMigrationReceipt } from '../core/update/update-migration-state.js';
|
|
45
45
|
import { inspectSksMenuBarStatus, installSksMenuBar } from '../core/codex-app/sks-menubar.js';
|
|
46
46
|
import { sweepSksTempDirs } from '../core/retention.js';
|
|
47
47
|
import { reconcileSkills } from '../core/init/skills.js';
|
|
@@ -84,16 +84,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
84
84
|
const doctorPhaseIds = doctorPhaseIdsForProfile(doctorProfile);
|
|
85
85
|
const doctorDirtyPlan = doctorFix ? planDoctorDirtyRepair(root, doctorPhaseIds) : null;
|
|
86
86
|
let setupRepair = null;
|
|
87
|
-
|
|
88
|
-
? {
|
|
89
|
-
schema: 'sks.update-now.v2',
|
|
90
|
-
ok: true,
|
|
91
|
-
status: 'skipped',
|
|
92
|
-
reason: 'manual_update_commands_only',
|
|
93
|
-
stages: [],
|
|
94
|
-
migration_current: true
|
|
95
|
-
}
|
|
96
|
-
: null;
|
|
87
|
+
let sksUpdate = null;
|
|
97
88
|
let migrationPreFix = null;
|
|
98
89
|
if (doctorFix) {
|
|
99
90
|
// Snapshot config content before ANY mutation so the migration journal can
|
|
@@ -117,7 +108,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
117
108
|
// backs up + parse-validates before writing, no-op when already present.
|
|
118
109
|
codex_app_fast_mode: flag(args, '--local-only')
|
|
119
110
|
? { status: 'skipped', reason: 'local-only repair' }
|
|
120
|
-
:
|
|
111
|
+
: await ensureGlobalCodexFastModeDuringInstall().catch((err) => ({ status: 'failed', error: err?.message || String(err) }))
|
|
121
112
|
};
|
|
122
113
|
}
|
|
123
114
|
const skillsReconcile = doctorFix
|
|
@@ -823,16 +814,47 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
823
814
|
...(pluginPolicy?.doctor_warnings || [])
|
|
824
815
|
]
|
|
825
816
|
});
|
|
826
|
-
if (doctorFix
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
817
|
+
if (doctorFix) {
|
|
818
|
+
const readinessBlockers = Array.isArray(ready.blockers) ? ready.blockers.map(String).filter(Boolean) : [];
|
|
819
|
+
const migrationWarnings = [
|
|
820
|
+
...(doctorNativeCapabilityRepair?.optional_warnings || []),
|
|
821
|
+
...(doctorFixPostcheck?.optional_warnings || [])
|
|
822
|
+
];
|
|
823
|
+
try {
|
|
824
|
+
const receiptInput = {
|
|
825
|
+
root,
|
|
826
|
+
source: `doctor-${doctorProfile}`,
|
|
827
|
+
blockers: readinessBlockers,
|
|
828
|
+
warnings: migrationWarnings
|
|
829
|
+
};
|
|
830
|
+
if (readinessBlockers.length)
|
|
831
|
+
receiptInput.status = 'blocked';
|
|
832
|
+
const receipt = await writeProjectUpdateMigrationReceipt(receiptInput);
|
|
833
|
+
sksUpdate = {
|
|
834
|
+
schema: 'sks.update-now.v2',
|
|
835
|
+
ok: receipt.status === 'current' && isUpdateMigrationReceiptCurrent(receipt),
|
|
836
|
+
status: receipt.status === 'current' ? 'repaired' : receipt.status,
|
|
837
|
+
reason: receipt.status === 'current' ? 'doctor_fix_wrote_current_project_migration_receipt' : 'doctor_fix_migration_receipt_blocked',
|
|
838
|
+
stages: receipt.legacy_migration_stages || [],
|
|
839
|
+
migration_current: isUpdateMigrationReceiptCurrent(receipt),
|
|
840
|
+
receipt_path: projectUpdateMigrationReceiptPath(root),
|
|
841
|
+
blockers: receipt.blockers || [],
|
|
842
|
+
warnings: receipt.warnings || []
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
catch (err) {
|
|
846
|
+
sksUpdate = {
|
|
847
|
+
schema: 'sks.update-now.v2',
|
|
848
|
+
ok: false,
|
|
849
|
+
status: 'blocked',
|
|
850
|
+
reason: 'doctor_fix_migration_receipt_failed',
|
|
851
|
+
stages: [],
|
|
852
|
+
migration_current: false,
|
|
853
|
+
receipt_path: projectUpdateMigrationReceiptPath(root),
|
|
854
|
+
blockers: [`migration_receipt_failed:${err?.message || String(err)}`],
|
|
855
|
+
warnings: migrationWarnings
|
|
856
|
+
};
|
|
857
|
+
}
|
|
836
858
|
}
|
|
837
859
|
const zellijReadiness = buildZellijReadiness(root, zellij, ready);
|
|
838
860
|
const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
|