sneakoscope 8.0.0 → 8.0.2
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 +13 -2
- package/config/skills-hash-ledger.v1.json +63 -0
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +14 -3
- package/dist/bin/sks-dispatch.js +1 -1
- package/dist/cli/codex-lb-setup-warning-output.js +17 -0
- package/dist/cli/command-manifest-lite.js +2 -13
- package/dist/cli/install-helpers-codex-lb-config.js +475 -8
- package/dist/cli/install-helpers-install-support.js +1 -1
- package/dist/cli/install-helpers.js +764 -68
- package/dist/cli/router.js +5 -2
- package/dist/commands/codex-lb.js +77 -47
- package/dist/commands/doctor-profile.js +1 -0
- package/dist/commands/doctor.js +165 -58
- package/dist/config/skills-manifest.json +193 -97
- package/dist/core/codex/codex-config-guard.js +70 -16
- package/dist/core/codex/oauth-callback-port-diagnostic.js +121 -0
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -2
- package/dist/core/codex-app/menubar/constants.js +3 -0
- package/dist/core/codex-app/menubar/installer.js +32 -9
- package/dist/core/codex-app/menubar/launch-agent.js +58 -6
- package/dist/core/codex-app/menubar/migration.js +17 -6
- package/dist/core/codex-app/menubar/status.js +15 -3
- package/dist/core/codex-app.js +15 -20
- package/dist/core/codex-control/codex-lb-launch-recovery.js +26 -0
- package/dist/core/codex-lb/capability-runner.js +1 -0
- package/dist/core/codex-lb/codex-lb-env.js +52 -41
- package/dist/core/codex-lb/codex-lb-setup.js +85 -8
- package/dist/core/codex-lb/desktop-center-credentials.js +474 -39
- package/dist/core/codex-lb/desktop-controller.js +118 -4
- package/dist/core/codex-lb/legacy-migration.js +6 -3
- package/dist/core/codex-native/codex-native-feature-broker.js +5 -1
- package/dist/core/codex-native/core-skill-manifest.js +1 -1
- package/dist/core/codex-native/managed-skill-generation-lock.js +13 -0
- package/dist/core/codex-native/sks-skill-paths.js +97 -10
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +1 -0
- package/dist/core/commands/basic-cli.js +54 -4
- package/dist/core/commands/mad-sks-command.js +1 -1
- package/dist/core/commands/menubar-command.js +24 -8
- package/dist/core/commands/naruto-command.js +42 -217
- package/dist/core/doctor/codex-config-syntax-repair.js +368 -0
- package/dist/core/doctor/doctor-native-capability-repair.js +12 -5
- package/dist/core/doctor/doctor-readiness-matrix.js +51 -4
- package/dist/core/doctor/skill-legacy-surface.js +0 -1
- package/dist/core/doctor/sks-menubar-doctor.js +21 -0
- package/dist/core/fsx.js +7 -14
- package/dist/core/hooks-runtime/hook-context.js +30 -16
- package/dist/core/hooks-runtime/managed-skill-admission.js +17 -0
- package/dist/core/hooks-runtime/managed-skill-generation-heal.js +891 -30
- package/dist/core/hooks-runtime/official-subagent-lifecycle.js +99 -6
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +3 -1
- package/dist/core/hooks-runtime/subagent-skill-availability-evidence.js +1 -1
- package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +4 -4
- package/dist/core/hooks-runtime/subagent-skill-availability.js +9 -7
- package/dist/core/hooks-runtime/subagent-stop-hook.js +19 -0
- package/dist/core/hooks-runtime.js +41 -14
- package/dist/core/init/skills.js +270 -11
- package/dist/core/mission.js +20 -0
- package/dist/core/naruto/hardware-capacity-probe.js +3 -1
- package/dist/core/naruto/naruto-concurrency-governor.js +9 -3
- package/dist/core/pipeline-internals/runtime-core.js +68 -9
- package/dist/core/pipeline-internals/runtime-gates.js +10 -2
- package/dist/core/preflight/parallel-preflight-engine.js +18 -4
- package/dist/core/release/package-dist-snapshot.js +50 -8
- package/dist/core/routes.js +1 -1
- package/dist/core/safety/command-contract/contracts.js +10 -13
- package/dist/core/safety/command-contract/json-schema.js +38 -1
- package/dist/core/subagents/agent-catalog.js +37 -13
- package/dist/core/subagents/model-policy.js +14 -9
- package/dist/core/subagents/naruto-command-args.js +237 -0
- package/dist/core/subagents/naruto-command-input-contract.js +123 -0
- package/dist/core/subagents/naruto-help-contract.js +35 -2
- package/dist/core/subagents/naruto-launch-diagnostics.js +35 -0
- package/dist/core/subagents/official-subagent-config.js +30 -3
- package/dist/core/subagents/official-subagent-preparation.js +30 -5
- package/dist/core/subagents/official-subagent-prompt.js +4 -3
- package/dist/core/subagents/official-subagent-runner.js +12 -0
- package/dist/core/subagents/subagent-evidence.js +10 -0
- package/dist/core/subagents/thread-budget.js +1 -1
- package/dist/core/subagents/wave-lifecycle.js +41 -11
- package/dist/core/subagents/wave-parent-guidance.js +10 -3
- package/dist/core/update/update-migration-state.js +694 -63
- package/dist/core/update/update-operation.js +498 -32
- package/dist/core/update-check.js +990 -509
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/AppDelegate.swift +1 -0
- package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +1 -1
- package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +1 -1
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +127 -12
- package/dist/native/sks-menubar/Sources/OverviewViewController.swift +7 -2
- package/dist/native/sks-menubar/Sources/ProcessClient.swift +287 -84
- package/dist/native/sks-menubar/Sources/ProcessExecutionState.swift +45 -0
- package/dist/native/sks-menubar/Sources/ProcessIdentityGuard.swift +196 -0
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +169 -0
- package/dist/native/sks-menubar/Sources/StatusItemController.swift +23 -5
- package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +113 -24
- package/dist/native/sks-menubar/Sources/main.swift +12 -0
- package/dist/native/sks-menubar/Tests/AppRuntimeTestSupport.swift +14 -0
- package/dist/native/sks-menubar/Tests/OperationCoordinatorTests.swift +174 -0
- package/dist/native/sks-menubar/Tests/ProcessClientTests.swift +4 -0
- package/dist/scripts/current-surface-update-e2e-check.js +24 -5
- package/dist/scripts/lib/ensure-dist-fresh.js +12 -8
- package/dist/scripts/mutation-callsite-analysis.js +381 -0
- package/dist/scripts/mutation-callsite-coverage-check.js +127 -62
- package/dist/scripts/official-subagent-workflow-check.js +1 -1
- package/dist/scripts/skills-manifest-continuity-check.js +19 -1
- package/package.json +5 -3
- package/runtime-required-scripts.json +5 -0
- package/scripts/build-clean-atomic.mjs +323 -0
package/dist/commands/doctor.js
CHANGED
|
@@ -12,6 +12,7 @@ import { codexLbStatus } from '../cli/install-helpers.js';
|
|
|
12
12
|
import { codexLbToolOutputRecoveryOverrideAcknowledged } from '../core/codex-lb/codex-lb-tool-output-recovery.js';
|
|
13
13
|
import { normalizeInstallScope } from '../core/init.js';
|
|
14
14
|
import { inspectCodexConfigReadability } from '../core/codex/codex-config-readability.js';
|
|
15
|
+
import { inspectOAuthCallbackPortConflict, oauthCallbackDoctorGuidance } from '../core/codex/oauth-callback-port-diagnostic.js';
|
|
15
16
|
import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
|
|
16
17
|
import { inventoryCodexPermissionProfiles } from '../core/codex/codex-permission-profiles.js';
|
|
17
18
|
import { appendMigrationEvents, hashConfigText } from '../core/migration/migration-transaction-journal.js';
|
|
@@ -24,6 +25,7 @@ import { buildCodexAppHarnessMatrix } from '../core/codex-app/codex-app-harness-
|
|
|
24
25
|
import { buildCodexNativeFeatureMatrix } from '../core/codex-native/codex-native-feature-broker.js';
|
|
25
26
|
import { withSecretPreservationGuard } from '../core/config/config-migration-journal.js';
|
|
26
27
|
import { reconcileDoctorSkills } from '../core/doctor/doctor-skill-reconcile.js';
|
|
28
|
+
import { buildSksMenuBarDoctorPostcheck } from '../core/doctor/sks-menubar-doctor.js';
|
|
27
29
|
import { isUpdateMigrationReceiptCurrent, projectUpdateMigrationReceiptPath, writeProjectUpdateMigrationReceipt } from '../core/update/update-migration-state.js';
|
|
28
30
|
import { inspectSksMenuBarStatus, installSksMenuBar, sksMenuBarRestartDeferred } from '../core/codex-app/menubar/index.js';
|
|
29
31
|
import { sweepSksTempDirs } from '../core/retention.js';
|
|
@@ -32,6 +34,25 @@ import { CURRENT_CODEX_RELEASE_MANIFEST } from '../core/codex-compat/codex-relea
|
|
|
32
34
|
import { formatHarnessConflictReport, scanHarnessConflicts } from '../core/harness-conflicts.js';
|
|
33
35
|
import { doctorArgWarnings, doctorMenuBarInstallPolicy, doctorPhaseIdsForProfile, doctorProfileFromArgs } from './doctor-profile.js';
|
|
34
36
|
export { doctorArgWarnings, doctorMenuBarInstallPolicy, doctorProfileFromArgs } from './doctor-profile.js';
|
|
37
|
+
export function deferCommandAliasCleanupToMigrationReceipt(result) {
|
|
38
|
+
const observedBlockers = Array.isArray(result?.blockers)
|
|
39
|
+
? result.blockers.map(String).filter(Boolean)
|
|
40
|
+
: [];
|
|
41
|
+
return {
|
|
42
|
+
...result,
|
|
43
|
+
ok: true,
|
|
44
|
+
status: 'deferred_to_project_migration_receipt',
|
|
45
|
+
fix: false,
|
|
46
|
+
repair_owner: 'project_migration_receipt',
|
|
47
|
+
pre_migration_blockers: observedBlockers,
|
|
48
|
+
actions: [],
|
|
49
|
+
blockers: [],
|
|
50
|
+
warnings: [
|
|
51
|
+
...(Array.isArray(result?.warnings) ? result.warnings.map(String).filter(Boolean) : []),
|
|
52
|
+
...(observedBlockers.length ? [`pre_migration_public_surface_findings_deferred:${observedBlockers.length}`] : [])
|
|
53
|
+
]
|
|
54
|
+
};
|
|
55
|
+
}
|
|
35
56
|
export async function run(_command, args = [], deps = {}) {
|
|
36
57
|
const root = await projectRoot();
|
|
37
58
|
if (flag(args, '--search')) {
|
|
@@ -268,7 +289,7 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
268
289
|
requireActualCodex: false,
|
|
269
290
|
codexBin: codexBin || undefined
|
|
270
291
|
};
|
|
271
|
-
const [codex, rust, codexConfig, sneakoscopeExists] = await Promise.all([
|
|
292
|
+
const [codex, rust, codexConfig, sneakoscopeExists, oauthCallbackPortDiagnostic] = await Promise.all([
|
|
272
293
|
codexBin
|
|
273
294
|
? Promise.resolve({ bin: codexBin, version: 'fixture-or-explicit', available: true })
|
|
274
295
|
: getCodexInfo().catch(() => ({ bin: null, version: null, available: false })),
|
|
@@ -279,8 +300,10 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
279
300
|
operator_actions: [],
|
|
280
301
|
blockers: [err?.message || String(err)]
|
|
281
302
|
})),
|
|
282
|
-
exists(`${root}/.sneakoscope`)
|
|
303
|
+
exists(`${root}/.sneakoscope`),
|
|
304
|
+
inspectOAuthCallbackPortConflict()
|
|
283
305
|
]);
|
|
306
|
+
const oauthCallbackOperatorActions = oauthCallbackDoctorGuidance(oauthCallbackPortDiagnostic);
|
|
284
307
|
const ready = {
|
|
285
308
|
schema: 'sks.doctor-readiness-matrix.v2',
|
|
286
309
|
generated_at: nowIso(),
|
|
@@ -322,8 +345,11 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
322
345
|
fast_path: true,
|
|
323
346
|
no_fix_write_policy: reportFile ? 'report_file_only' : 'no_writes_performed',
|
|
324
347
|
arg_warnings: doctorArgWarnings(args),
|
|
348
|
+
warnings: [...oauthCallbackPortDiagnostic.warnings],
|
|
349
|
+
operator_actions: oauthCallbackOperatorActions,
|
|
325
350
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
326
351
|
codex,
|
|
352
|
+
oauth_callback_port_diagnostic: oauthCallbackPortDiagnostic,
|
|
327
353
|
codex_config: codexConfig,
|
|
328
354
|
rust,
|
|
329
355
|
codex_app: { ok: false, skipped: true, warnings: ['codex_app_optional_diagnostic_skipped'] },
|
|
@@ -428,6 +454,8 @@ async function runDoctorJsonFastPath(args = [], root) {
|
|
|
428
454
|
}
|
|
429
455
|
async function runDoctor(args = [], root, doctorFix) {
|
|
430
456
|
const startedAtMs = Date.now();
|
|
457
|
+
const oauthCallbackPortDiagnostic = await inspectOAuthCallbackPortConflict();
|
|
458
|
+
const oauthCallbackOperatorActions = oauthCallbackDoctorGuidance(oauthCallbackPortDiagnostic);
|
|
431
459
|
const sksTempSweep = doctorFix ? await sweepSksTempDirs(root, { maxAgeHours: 24 }).catch((err) => ({
|
|
432
460
|
ok: false,
|
|
433
461
|
error: err?.message || String(err),
|
|
@@ -445,6 +473,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
445
473
|
const shouldEvaluateCodexAppUiRepair = doctorFix || deepDiagnostics || flag(args, '--repair-codex-app-ui');
|
|
446
474
|
const shouldRunZellijRepair = deepDiagnostics || flag(args, '--repair-zellij') || flag(args, '--install-homebrew') || process.env.SKS_REQUIRE_ZELLIJ === '1';
|
|
447
475
|
const nativeCapabilityDiagnosticsRequested = deepDiagnostics || flag(args, '--repair-native-capabilities');
|
|
476
|
+
const requireLegacyGlobalHookCleanup = doctorFix && doctorProfile === 'migration';
|
|
477
|
+
const migrationReceiptOwnsReconcile = doctorFix && doctorProfile === 'migration';
|
|
448
478
|
const doctorPhaseIds = doctorPhaseIdsForProfile(doctorProfile);
|
|
449
479
|
const { runDoctorCommandAliasCleanup } = await import('../core/doctor/command-alias-cleanup.js');
|
|
450
480
|
const { runDoctorNativeCapabilityRepair } = await import('../core/doctor/doctor-native-capability-repair.js');
|
|
@@ -490,16 +520,16 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
490
520
|
openrouter_provider: openRouterProviderRepair
|
|
491
521
|
};
|
|
492
522
|
}
|
|
493
|
-
const skillsReconcile = await reconcileDoctorSkills(root, doctorFix);
|
|
494
|
-
const
|
|
523
|
+
const skillsReconcile = await reconcileDoctorSkills(root, doctorFix && !migrationReceiptOwnsReconcile);
|
|
524
|
+
const inspectCommandAliasCleanup = (fix) => runDoctorCommandAliasCleanup({
|
|
495
525
|
root,
|
|
496
|
-
fix
|
|
526
|
+
fix
|
|
497
527
|
}).catch((err) => ({
|
|
498
528
|
schema: 'sks.command-alias-cleanup.v1',
|
|
499
529
|
ok: false,
|
|
500
530
|
status: 'blocked',
|
|
501
531
|
root,
|
|
502
|
-
fix
|
|
532
|
+
fix,
|
|
503
533
|
report_path: `${root}/.sneakoscope/reports/command-alias-cleanup.json`,
|
|
504
534
|
canonical_command_count: 0,
|
|
505
535
|
current_alias_count: 0,
|
|
@@ -507,12 +537,17 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
507
537
|
actions: [],
|
|
508
538
|
blockers: [err?.message || String(err)]
|
|
509
539
|
}));
|
|
540
|
+
let commandAliasCleanup = await inspectCommandAliasCleanup(doctorFix && !migrationReceiptOwnsReconcile);
|
|
541
|
+
const commandAliasCleanupBeforeReceipt = migrationReceiptOwnsReconcile
|
|
542
|
+
? deferCommandAliasCleanupToMigrationReceipt(commandAliasCleanup)
|
|
543
|
+
: commandAliasCleanup;
|
|
510
544
|
const doctorNativeCapabilityRepair = await runDoctorNativeCapabilityRepair({
|
|
511
545
|
root,
|
|
512
546
|
fix: nativeCapabilityDiagnosticsRequested && doctorFix,
|
|
513
547
|
yes: flag(args, '--yes') || flag(args, '-y'),
|
|
514
548
|
flags: args.map((arg) => String(arg)),
|
|
515
|
-
skipNativeCapabilities: !nativeCapabilityDiagnosticsRequested
|
|
549
|
+
skipNativeCapabilities: !nativeCapabilityDiagnosticsRequested,
|
|
550
|
+
requireLegacyGlobalHookCleanup
|
|
516
551
|
}).catch((err) => ({
|
|
517
552
|
schema: 'sks.doctor-native-capability-repair.v1',
|
|
518
553
|
ok: false,
|
|
@@ -522,11 +557,19 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
522
557
|
core_skills: null,
|
|
523
558
|
skill_dedupe: null,
|
|
524
559
|
native_capabilities: null,
|
|
560
|
+
legacy_global_hooks: {
|
|
561
|
+
ok: false,
|
|
562
|
+
blockers: [`cleanup_failed_before_report:${err?.message || String(err)}`],
|
|
563
|
+
warnings: []
|
|
564
|
+
},
|
|
525
565
|
secret_preservation_guard: '.sneakoscope/reports/secret-preservation-guard.json',
|
|
526
566
|
core_blockers: [err?.message || String(err)],
|
|
527
567
|
route_blockers: {},
|
|
528
568
|
optional_manual_required: [],
|
|
529
569
|
optional_warnings: [],
|
|
570
|
+
required_blockers: requireLegacyGlobalHookCleanup
|
|
571
|
+
? [`legacy_global_hooks:cleanup_failed_before_report:${err?.message || String(err)}`]
|
|
572
|
+
: [],
|
|
530
573
|
blockers: [err?.message || String(err)]
|
|
531
574
|
}));
|
|
532
575
|
const configProbeOpts = {
|
|
@@ -559,6 +602,20 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
559
602
|
: null;
|
|
560
603
|
const codexDoctorDiff = compareCodexDoctorBridge(codexDoctorBefore, preRepairCodexDoctor);
|
|
561
604
|
codexStartupRepair = mergeObservedCodexStartupWarnings(codexStartupRepair, preRepairCodexDoctor);
|
|
605
|
+
const codexConfigSyntaxRepair = doctorPhaseIds.includes('codex_config_syntax_repair')
|
|
606
|
+
? await (await import('../core/doctor/codex-config-syntax-repair.js')).runCodexConfigSyntaxRepair({ root, fix: doctorFix }).catch((err) => ({
|
|
607
|
+
schema: 'sks.codex-config-syntax-repair.v1',
|
|
608
|
+
ok: false,
|
|
609
|
+
generated_at: new Date().toISOString(),
|
|
610
|
+
fix: doctorFix,
|
|
611
|
+
configs: [],
|
|
612
|
+
actions: [],
|
|
613
|
+
manual_actions: [],
|
|
614
|
+
blockers: [err?.message || String(err)],
|
|
615
|
+
warnings: [],
|
|
616
|
+
report_path: `${root}/.sneakoscope/reports/codex-config-syntax-repair.json`
|
|
617
|
+
}))
|
|
618
|
+
: null;
|
|
562
619
|
const codex = codexBin
|
|
563
620
|
? { bin: codexBin, version: 'fixture-or-explicit', available: true }
|
|
564
621
|
: await getCodexInfo().catch(() => ({ bin: null, version: null, available: false }));
|
|
@@ -641,19 +698,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
641
698
|
? await repairCodexAppFastUi(root, {
|
|
642
699
|
apply: false,
|
|
643
700
|
reportPath: `${root}/.sneakoscope/reports/codex-app-fast-ui-repair-plan.json`
|
|
644
|
-
}).catch((err) => (
|
|
645
|
-
schema: 'sks.codex-app-fast-ui-repair.v1',
|
|
646
|
-
ok: false,
|
|
647
|
-
apply: false,
|
|
648
|
-
safe_auto_apply: false,
|
|
649
|
-
requires_confirmation: true,
|
|
650
|
-
fast_selector: 'manual_action_required',
|
|
651
|
-
provider_selector: 'ok',
|
|
652
|
-
host_owned_config: 'diagnostic_failed',
|
|
653
|
-
next_action: 'Review Codex App UI config manually.',
|
|
654
|
-
actions: [],
|
|
655
|
-
blockers: [err?.message || String(err)]
|
|
656
|
-
}))
|
|
701
|
+
}).catch((err) => buildCodexAppUiDiagnosticFailure(false, err))
|
|
657
702
|
: {
|
|
658
703
|
schema: 'sks.codex-app-fast-ui-repair.v1',
|
|
659
704
|
ok: true,
|
|
@@ -676,19 +721,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
676
721
|
apply: true,
|
|
677
722
|
force: explicitCodexAppUiRepair,
|
|
678
723
|
reportPath: `${root}/.sneakoscope/reports/codex-app-fast-ui-repair.json`
|
|
679
|
-
}).catch((err) => (
|
|
680
|
-
schema: 'sks.codex-app-fast-ui-repair.v1',
|
|
681
|
-
ok: false,
|
|
682
|
-
apply: true,
|
|
683
|
-
safe_auto_apply: false,
|
|
684
|
-
requires_confirmation: true,
|
|
685
|
-
fast_selector: 'manual_action_required',
|
|
686
|
-
provider_selector: 'ok',
|
|
687
|
-
host_owned_config: 'diagnostic_failed',
|
|
688
|
-
next_action: 'Review Codex App UI config manually.',
|
|
689
|
-
actions: [],
|
|
690
|
-
blockers: [err?.message || String(err)]
|
|
691
|
-
}))
|
|
724
|
+
}).catch((err) => buildCodexAppUiDiagnosticFailure(true, err))
|
|
692
725
|
: codexAppUiPlan;
|
|
693
726
|
const menuBarPolicy = doctorMenuBarInstallPolicy(args, doctorFix, process.env);
|
|
694
727
|
const menuBarLaunchRequested = menuBarPolicy.launch;
|
|
@@ -810,7 +843,9 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
810
843
|
raw_secret_values_recorded: false
|
|
811
844
|
}))
|
|
812
845
|
: null;
|
|
813
|
-
const hookTrustRepair = doctorFix
|
|
846
|
+
const hookTrustRepair = doctorFix
|
|
847
|
+
&& !migrationReceiptOwnsReconcile
|
|
848
|
+
&& doctorPhaseIds.includes('hook_trust_repair')
|
|
814
849
|
? await (await import('../core/codex-hooks/codex-hook-trust-doctor.js')).codexHookTrustDoctor(root, { fix: true, managed: true, actual: true }).catch((err) => ({
|
|
815
850
|
schema: 'sks.codex-hook-trust-doctor.v2',
|
|
816
851
|
ok: false,
|
|
@@ -858,6 +893,17 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
858
893
|
rollback_evidence: startupConfigRepair?.backup_path || 'startup_config_repair_idempotent_report'
|
|
859
894
|
})
|
|
860
895
|
},
|
|
896
|
+
{
|
|
897
|
+
id: 'codex_config_syntax_repair',
|
|
898
|
+
run: async () => ({
|
|
899
|
+
id: 'codex_config_syntax_repair',
|
|
900
|
+
ok: codexConfigSyntaxRepair?.ok !== false,
|
|
901
|
+
repaired: doctorFix && (codexConfigSyntaxRepair?.configs || []).some((entry) => entry.changed),
|
|
902
|
+
blockers: codexConfigSyntaxRepair?.blockers || [],
|
|
903
|
+
warnings: codexConfigSyntaxRepair?.warnings || [],
|
|
904
|
+
rollback_evidence: codexConfigSyntaxRepair?.report_path || 'codex_config_syntax_repair_report'
|
|
905
|
+
})
|
|
906
|
+
},
|
|
861
907
|
{
|
|
862
908
|
id: 'context7_repair',
|
|
863
909
|
run: async () => ({
|
|
@@ -900,10 +946,12 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
900
946
|
run: async () => ({
|
|
901
947
|
id: 'hook_trust_repair',
|
|
902
948
|
ok: hookTrustRepair?.ok !== false,
|
|
903
|
-
repaired: doctorFix,
|
|
949
|
+
repaired: doctorFix && !migrationReceiptOwnsReconcile,
|
|
904
950
|
blockers: hookTrustRepair?.blockers || [],
|
|
905
951
|
warnings: hookTrustRepair?.warnings || [],
|
|
906
|
-
rollback_evidence:
|
|
952
|
+
rollback_evidence: migrationReceiptOwnsReconcile
|
|
953
|
+
? 'project_migration_receipt_owns_hook_trust_refresh'
|
|
954
|
+
: hookTrustRepair?.fixed?.managed_hook_file || 'codex_hook_trust_repair_idempotent'
|
|
907
955
|
})
|
|
908
956
|
},
|
|
909
957
|
{
|
|
@@ -927,29 +975,18 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
927
975
|
blockers: [err?.message || String(err)],
|
|
928
976
|
warnings: []
|
|
929
977
|
}));
|
|
930
|
-
|
|
931
|
-
...(status.launchd?.ok === true ? [] : [`launchd_not_running:${status.launchd?.error || status.launchd?.state || 'unknown'}`]),
|
|
932
|
-
...(status.action_target?.ok === true ? [] : [`action_script_smoke_failed:${status.action_target?.smoke_code ?? 'no_code'}`]),
|
|
933
|
-
...(status.ok === true ? [] : (status.blockers || ['menubar_status_not_ok']))
|
|
934
|
-
];
|
|
935
|
-
return {
|
|
936
|
-
ok: blockers.length === 0,
|
|
937
|
-
blockers,
|
|
938
|
-
warnings: [
|
|
939
|
-
...(status.warnings || []),
|
|
940
|
-
blockers.length === 0 ? 'menubar_postcheck_passed' : 'menubar_postcheck_failed'
|
|
941
|
-
]
|
|
942
|
-
};
|
|
978
|
+
return buildSksMenuBarDoctorPostcheck(status);
|
|
943
979
|
}
|
|
944
980
|
},
|
|
945
981
|
{
|
|
946
982
|
id: 'command_alias_cleanup',
|
|
947
983
|
run: async () => ({
|
|
948
984
|
id: 'command_alias_cleanup',
|
|
949
|
-
ok:
|
|
950
|
-
repaired: Array.isArray(
|
|
951
|
-
blockers:
|
|
952
|
-
|
|
985
|
+
ok: commandAliasCleanupBeforeReceipt?.ok !== false,
|
|
986
|
+
repaired: Array.isArray(commandAliasCleanupBeforeReceipt?.actions) && commandAliasCleanupBeforeReceipt.actions.length > 0,
|
|
987
|
+
blockers: commandAliasCleanupBeforeReceipt?.blockers || [],
|
|
988
|
+
warnings: commandAliasCleanupBeforeReceipt?.warnings || [],
|
|
989
|
+
rollback_evidence: commandAliasCleanupBeforeReceipt?.report_path || 'command_alias_cleanup_report'
|
|
953
990
|
})
|
|
954
991
|
},
|
|
955
992
|
{
|
|
@@ -1219,7 +1256,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1219
1256
|
const authoritativeCodexDoctor = postRepairCodexDoctor;
|
|
1220
1257
|
const codexDoctorAuthoritativeDiff = compareCodexDoctorBridge(codexDoctorBefore, authoritativeCodexDoctor);
|
|
1221
1258
|
const pkgBytes = 0;
|
|
1222
|
-
const
|
|
1259
|
+
const doctorReadinessInput = {
|
|
1223
1260
|
codex,
|
|
1224
1261
|
codex_config: codexConfig,
|
|
1225
1262
|
codex_app: codexApp,
|
|
@@ -1232,12 +1269,15 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1232
1269
|
context7_repair: context7Repair,
|
|
1233
1270
|
codex_startup_repair: codexStartupRepair,
|
|
1234
1271
|
startup_config_repair: startupConfigRepair,
|
|
1272
|
+
codex_config_syntax_repair: codexConfigSyntaxRepair,
|
|
1235
1273
|
context7_mcp_repair: context7McpRepair,
|
|
1236
1274
|
supabase_mcp_repair: supabaseMcpRepair,
|
|
1237
1275
|
doctor_fix_transaction: doctorFixTransaction,
|
|
1238
1276
|
doctor_dirty_plan: doctorDirtyPlan,
|
|
1239
1277
|
doctor_fix_postcheck: doctorFixPostcheck,
|
|
1278
|
+
command_aliases: migrationReceiptOwnsReconcile ? commandAliasCleanupBeforeReceipt : undefined,
|
|
1240
1279
|
doctor_native_capability: doctorNativeCapabilityRepair,
|
|
1280
|
+
require_legacy_global_hook_cleanup: requireLegacyGlobalHookCleanup,
|
|
1241
1281
|
skills: skillsReconcile,
|
|
1242
1282
|
local_model: localModel,
|
|
1243
1283
|
agent_role_config: agentRoleConfigRepair,
|
|
@@ -1254,28 +1294,45 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1254
1294
|
...(configRepair?.operator_actions || []),
|
|
1255
1295
|
...(zellijRepair && !zellijRepair.ok && zellijRepair.command ? [`Run: ${zellijRepair.command}`] : []),
|
|
1256
1296
|
...(codexStartupRepair.manual_actions || []),
|
|
1297
|
+
...(codexConfigSyntaxRepair?.manual_actions || []),
|
|
1257
1298
|
...(pluginPolicy?.doctor_warnings || [])
|
|
1258
1299
|
]
|
|
1259
|
-
}
|
|
1300
|
+
};
|
|
1301
|
+
let ready = await writeDoctorReadinessMatrix(root, doctorReadinessInput);
|
|
1260
1302
|
if (doctorFix) {
|
|
1303
|
+
if (migrationReceiptOwnsReconcile) {
|
|
1304
|
+
commandAliasCleanup = await inspectCommandAliasCleanup(false);
|
|
1305
|
+
doctorReadinessInput.command_aliases = commandAliasCleanup;
|
|
1306
|
+
ready = await writeDoctorReadinessMatrix(root, doctorReadinessInput);
|
|
1307
|
+
}
|
|
1261
1308
|
const readinessBlockers = [
|
|
1262
1309
|
...(Array.isArray(ready.blockers) ? ready.blockers.map(String).filter(Boolean) : []),
|
|
1263
1310
|
...(openRouterProviderRepair?.ok === false
|
|
1264
1311
|
? ((openRouterProviderRepair?.blockers || ['openrouter_provider_repair_failed']).map(String))
|
|
1265
1312
|
: [])
|
|
1266
1313
|
];
|
|
1314
|
+
const preservedUserOwnedConfig = doctorProfile === 'migration'
|
|
1315
|
+
&& readinessBlockers.length > 0
|
|
1316
|
+
&& readinessBlockers.every(isMigrationUserOwnedProjectConfigBlocker);
|
|
1317
|
+
const receiptBlockers = preservedUserOwnedConfig ? [] : readinessBlockers;
|
|
1267
1318
|
const migrationWarnings = [
|
|
1268
1319
|
...(doctorNativeCapabilityRepair?.optional_warnings || []),
|
|
1269
|
-
...(doctorFixPostcheck?.optional_warnings || [])
|
|
1320
|
+
...(doctorFixPostcheck?.optional_warnings || []),
|
|
1321
|
+
...(preservedUserOwnedConfig
|
|
1322
|
+
? [
|
|
1323
|
+
'migration_doctor_preserved_user_owned_project_config',
|
|
1324
|
+
...readinessBlockers.map((blocker) => `migration_optional_blocker:${blocker}`)
|
|
1325
|
+
]
|
|
1326
|
+
: [])
|
|
1270
1327
|
];
|
|
1271
1328
|
try {
|
|
1272
1329
|
const receiptInput = {
|
|
1273
1330
|
root,
|
|
1274
1331
|
source: `doctor-${doctorProfile}`,
|
|
1275
|
-
blockers:
|
|
1332
|
+
blockers: receiptBlockers,
|
|
1276
1333
|
warnings: migrationWarnings
|
|
1277
1334
|
};
|
|
1278
|
-
if (
|
|
1335
|
+
if (receiptBlockers.length)
|
|
1279
1336
|
receiptInput.status = 'blocked';
|
|
1280
1337
|
const receipt = await writeProjectUpdateMigrationReceipt(receiptInput);
|
|
1281
1338
|
sksUpdate = {
|
|
@@ -1310,6 +1367,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1310
1367
|
&& (!sksUpdate || sksUpdate.ok !== false)
|
|
1311
1368
|
&& commandAliasCleanup.ok !== false
|
|
1312
1369
|
&& codexStartupRepair.ok !== false
|
|
1370
|
+
&& codexConfigSyntaxRepair?.ok !== false
|
|
1313
1371
|
&& agentRoleConfigRepair.ok !== false
|
|
1314
1372
|
&& openRouterProviderRepair.ok !== false
|
|
1315
1373
|
&& (officialSubagentConfig.blockers || []).length === 0
|
|
@@ -1319,14 +1377,20 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1319
1377
|
elapsed_ms: Date.now() - startedAtMs,
|
|
1320
1378
|
ok: resultOk,
|
|
1321
1379
|
status: resultOk ? (doctorFix ? 'fix_ok' : deepDiagnostics ? 'full_ok' : 'fast_ok') : 'blocked',
|
|
1380
|
+
core_ready: ready.core_ready === true,
|
|
1381
|
+
center_ready: ready.center_ready === true,
|
|
1382
|
+
center_attempted: ready.center_attempted === true,
|
|
1322
1383
|
diagnostic_depth: deepDiagnostics ? 'full' : doctorFix ? 'fix' : 'fast',
|
|
1323
1384
|
deep_diagnostics_skipped: !deepDiagnostics,
|
|
1324
1385
|
deep_ok: deepDiagnostics ? resultOk : null,
|
|
1325
1386
|
not_counted_as_full_doctor: !deepDiagnostics,
|
|
1326
1387
|
root,
|
|
1327
1388
|
arg_warnings: argWarnings,
|
|
1389
|
+
warnings: [...oauthCallbackPortDiagnostic.warnings],
|
|
1390
|
+
operator_actions: oauthCallbackOperatorActions,
|
|
1328
1391
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
1329
1392
|
codex,
|
|
1393
|
+
oauth_callback_port_diagnostic: oauthCallbackPortDiagnostic,
|
|
1330
1394
|
codex_config: codexConfig,
|
|
1331
1395
|
rust,
|
|
1332
1396
|
codex_app: codexApp,
|
|
@@ -1345,6 +1409,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1345
1409
|
context7_repair: context7Repair,
|
|
1346
1410
|
codex_startup_repair: codexStartupRepair,
|
|
1347
1411
|
startup_config_repair: startupConfigRepair,
|
|
1412
|
+
codex_config_syntax_repair: codexConfigSyntaxRepair,
|
|
1348
1413
|
context7_mcp_repair: context7McpRepair,
|
|
1349
1414
|
supabase_mcp_repair: supabaseMcpRepair,
|
|
1350
1415
|
doctor_fix_transaction: doctorFixTransaction,
|
|
@@ -1415,6 +1480,14 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1415
1480
|
console.log(`Root: ${root}`);
|
|
1416
1481
|
console.log(`Node: ${result.node.ok ? 'ok' : 'fail'} ${result.node.version}`);
|
|
1417
1482
|
console.log(`Codex: ${codex.bin ? 'ok' : 'missing'} ${codex.version || ''}`);
|
|
1483
|
+
if (oauthCallbackPortDiagnostic.conflict) {
|
|
1484
|
+
const listeners = oauthCallbackPortDiagnostic.listeners
|
|
1485
|
+
.map((listener) => `${listener.command} pid ${listener.pid} ${listener.address}`)
|
|
1486
|
+
.join(', ');
|
|
1487
|
+
console.log(`OAuth callback port 1455: warning (${listeners})`);
|
|
1488
|
+
for (const action of oauthCallbackOperatorActions)
|
|
1489
|
+
console.log(` action: ${action}`);
|
|
1490
|
+
}
|
|
1418
1491
|
const actual = (codexConfig.checks || []).find((check) => check.name === 'actual_codex_cli_config_load');
|
|
1419
1492
|
console.log('Project config:');
|
|
1420
1493
|
console.log(` node read: ${ready.codex_config_readable_by_node ? 'ok' : 'failed'}`);
|
|
@@ -1443,6 +1516,16 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1443
1516
|
console.log(` manual: ${action}`);
|
|
1444
1517
|
for (const warning of codexStartupRepair.warnings || [])
|
|
1445
1518
|
console.log(` warning: ${warning}`);
|
|
1519
|
+
if (codexConfigSyntaxRepair) {
|
|
1520
|
+
console.log('Codex config syntax:');
|
|
1521
|
+
console.log(` repair: ${codexConfigSyntaxRepair.ok ? 'ok' : 'blocked'}`);
|
|
1522
|
+
for (const action of codexConfigSyntaxRepair.actions || [])
|
|
1523
|
+
console.log(` - ${action}`);
|
|
1524
|
+
for (const action of codexConfigSyntaxRepair.manual_actions || [])
|
|
1525
|
+
console.log(` manual: ${action}`);
|
|
1526
|
+
for (const warning of codexConfigSyntaxRepair.warnings || [])
|
|
1527
|
+
console.log(` warning: ${warning}`);
|
|
1528
|
+
}
|
|
1446
1529
|
console.log(` codex doctor: ${formatCodexDoctorConsoleStatus(authoritativeCodexDoctor)}`);
|
|
1447
1530
|
console.log(`Rust acc.: ${rust.mode || (rust.available ? 'rust_accelerated' : 'js_fallback')} ${rust.version || rust.status || ''}`);
|
|
1448
1531
|
console.log(`Codex App: ${ready.codex_app_ready ? 'ok' : 'optional_missing'}`);
|
|
@@ -1613,6 +1696,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
1613
1696
|
console.log(` cli_ready: ${ready.cli_ready ? 'yes' : 'no'}`);
|
|
1614
1697
|
console.log(` mad_ready: ${ready.mad_ready ? 'yes' : 'no'}`);
|
|
1615
1698
|
console.log(` managed_state_current: ${ready.managed_state_current ? 'yes' : 'no'}`);
|
|
1699
|
+
console.log(` core_ready: ${ready.core_ready ? 'yes' : 'no'}`);
|
|
1700
|
+
console.log(` center_ready: ${ready.center_ready ? 'yes' : 'no'}${ready.center_attempted ? ' (repair attempted)' : ' (not attempted)'}`);
|
|
1616
1701
|
console.log(` ready: ${ready.ready ? 'yes' : 'no'}`);
|
|
1617
1702
|
if (!ready.ready) {
|
|
1618
1703
|
console.log('Primary blocker:');
|
|
@@ -1895,10 +1980,32 @@ function installScopeFromArgs(args = []) {
|
|
|
1895
1980
|
const index = args.indexOf('--install-scope');
|
|
1896
1981
|
return normalizeInstallScope(index >= 0 && args[index + 1] ? args[index + 1] : 'global');
|
|
1897
1982
|
}
|
|
1983
|
+
function isMigrationUserOwnedProjectConfigBlocker(blocker) {
|
|
1984
|
+
const value = String(blocker || '').trim();
|
|
1985
|
+
return value === 'user_owned_file_without_sks_marker'
|
|
1986
|
+
|| value.endsWith(':user_owned_file_without_sks_marker')
|
|
1987
|
+
|| value === 'config_write_guard:blocked_unmanaged_project_config'
|
|
1988
|
+
|| value.endsWith(':config_write_guard:blocked_unmanaged_project_config');
|
|
1989
|
+
}
|
|
1898
1990
|
function readOption(args = [], name, fallback = null) {
|
|
1899
1991
|
const index = args.indexOf(name);
|
|
1900
1992
|
return index >= 0 && args[index + 1] ? args[index + 1] : fallback;
|
|
1901
1993
|
}
|
|
1994
|
+
export function buildCodexAppUiDiagnosticFailure(apply, error) {
|
|
1995
|
+
return {
|
|
1996
|
+
schema: 'sks.codex-app-fast-ui-repair.v1',
|
|
1997
|
+
ok: false,
|
|
1998
|
+
apply,
|
|
1999
|
+
safe_auto_apply: false,
|
|
2000
|
+
requires_confirmation: true,
|
|
2001
|
+
fast_selector: 'manual_action_required',
|
|
2002
|
+
provider_selector: 'manual_action_required',
|
|
2003
|
+
host_owned_config: 'diagnostic_failed',
|
|
2004
|
+
next_action: 'Review Codex App UI config manually.',
|
|
2005
|
+
actions: [],
|
|
2006
|
+
blockers: [error instanceof Error ? error.message : String(error)]
|
|
2007
|
+
};
|
|
2008
|
+
}
|
|
1902
2009
|
export function formatCodexDoctorConsoleStatus(report) {
|
|
1903
2010
|
if (!report || report.available !== true)
|
|
1904
2011
|
return 'unavailable';
|