sneakoscope 5.5.3 → 5.6.1

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.
Files changed (49) hide show
  1. package/README.md +4 -1
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/crates/sks-core/src/main.rs +1 -1
  5. package/dist/bin/sks.js +1 -1
  6. package/dist/cli/command-registry.js +7 -1
  7. package/dist/cli/router.js +28 -0
  8. package/dist/commands/doctor.js +65 -3
  9. package/dist/config/skills-manifest.json +58 -58
  10. package/dist/core/agent-bridge/agent-manifest.js +64 -0
  11. package/dist/core/agent-bridge/agent-mode.js +29 -0
  12. package/dist/core/agent-bridge/mcp-server.js +156 -0
  13. package/dist/core/agents/agent-orchestrator.js +1 -11
  14. package/dist/core/codex-app/sks-menubar.js +47 -2
  15. package/dist/core/commands/agent-bridge-command.js +86 -0
  16. package/dist/core/commands/image-ux-review-command.js +6 -6
  17. package/dist/core/commands/loop-command.js +2 -6
  18. package/dist/core/commands/mad-sks-command.js +3 -3
  19. package/dist/core/commands/mcp-server-command.js +13 -0
  20. package/dist/core/commands/naruto-command.js +4 -4
  21. package/dist/core/commands/ppt-command.js +6 -3
  22. package/dist/core/commands/qa-loop-command.js +64 -26
  23. package/dist/core/commands/team-command.js +1 -1
  24. package/dist/core/commands/wiki-command.js +89 -3
  25. package/dist/core/config/secret-preservation.js +43 -1
  26. package/dist/core/doctor/browser-use-repair.js +149 -0
  27. package/dist/core/doctor/computer-use-repair.js +166 -0
  28. package/dist/core/doctor/imagegen-repair.js +9 -0
  29. package/dist/core/doctor/mcp-transport-collision-repair.js +129 -0
  30. package/dist/core/feature-fixtures.js +19 -11
  31. package/dist/core/feature-registry.js +21 -0
  32. package/dist/core/fsx.js +1 -1
  33. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +48 -0
  34. package/dist/core/hooks-runtime.js +4 -0
  35. package/dist/core/mad-db/mad-db-capability.js +1 -1
  36. package/dist/core/mission.js +19 -3
  37. package/dist/core/naruto/naruto-real-worker-child.js +5 -4
  38. package/dist/core/naruto/naruto-real-worker-runtime.js +5 -4
  39. package/dist/core/naruto/normalize-worker-prompt-text.js +12 -0
  40. package/dist/core/routes.js +3 -1
  41. package/dist/core/triwiki/code-index-scanner.js +313 -0
  42. package/dist/core/triwiki/code-pack.js +169 -0
  43. package/dist/core/triwiki/triwiki-cache-key.js +24 -2
  44. package/dist/core/triwiki-attention.js +42 -5
  45. package/dist/core/triwiki-wrongness/wrongness-schema.js +18 -1
  46. package/dist/core/update-check.js +50 -0
  47. package/dist/core/version.js +1 -1
  48. package/dist/scripts/doctor-imagegen-repair-check.js +6 -1
  49. package/package.json +2 -2
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: `5.3.0`.
17
+ Current release: `5.6.0`. New in this release: a source-cited TriWiki code index/pack (`sks wiki refresh --code`) so LLMs use fewer tokens navigating a codebase, native repair for Codex Desktop's Computer Use and Browser Use features, and an agent bridge (`sks mcp-server`, `SKS_AGENT_MODE`, NDJSON `--stream`) so any agent system — not a specific one — can drive SKS's full command surface. See [docs/AGENT-BRIDGE.md](docs/AGENT-BRIDGE.md) and [CHANGELOG.md](CHANGELOG.md).
18
18
 
19
19
  ## Install
20
20
 
@@ -81,6 +81,9 @@ It shows the v5 flow: one-line install, `$Plan`, `$Work`/`$Swarm`, `sks review`,
81
81
  - Review report: `.sneakoscope/reports/review-report.json`
82
82
  - Harness benchmark: `.sneakoscope/reports/harness-benchmark.json`
83
83
  - Project memory: `sks memory build`
84
+ - Codebase index/pack for LLM context: `sks wiki refresh --code`, `sks wiki validate --json` (code-pack freshness)
85
+ - Native capability repair: `sks doctor --fix` (imagegen/Computer Use/Browser Use), `.sneakoscope/reports/native-capability-readiness.json`
86
+ - Agent bridge for any agent system: `sks mcp-server`, `sks agent-bridge setup`, `SKS_AGENT_MODE=1` — see [docs/AGENT-BRIDGE.md](docs/AGENT-BRIDGE.md)
84
87
  - Release gates: `node ./dist/scripts/release-gate-dag-runner.js --preset release --full`
85
88
  - Release readiness notes: [docs/release-readiness.md](docs/release-readiness.md) and [CHANGELOG.md](CHANGELOG.md)
86
89
  - Image generation review routes require Codex App `$imagegen`/`gpt-image-2` evidence with recorded output hashes; direct API fallback and mock fixtures do not satisfy full route gates.
@@ -76,7 +76,7 @@ dependencies = [
76
76
 
77
77
  [[package]]
78
78
  name = "sks-core"
79
- version = "5.5.3"
79
+ version = "5.6.1"
80
80
  dependencies = [
81
81
  "serde_json",
82
82
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sks-core"
3
- version = "5.5.3"
3
+ version = "5.6.1"
4
4
  edition = "2021"
5
5
 
6
6
  [dependencies]
@@ -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.5.3"),
7
+ Some("--version") => println!("sks-rs 5.6.1"),
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.5.3';
2
+ const FAST_PACKAGE_VERSION = '5.6.1';
3
3
  const args = process.argv.slice(2);
4
4
  try {
5
5
  if (args[0] === '--agent' && args[1] === 'worker') {
@@ -196,7 +196,13 @@ export const COMMANDS = {
196
196
  features: entry('beta', 'Validate feature registry', 'dist/commands/features.js', directCommand(() => import('../commands/features.js'), 'dist/commands/features.js')),
197
197
  'all-features': entry('beta', 'Run all-features selftest', 'dist/commands/all-features.js', directCommand(() => import('../commands/all-features.js'), 'dist/commands/all-features.js')),
198
198
  perf: entry('beta', 'Run performance checks', 'dist/commands/perf.js', directCommand(() => import('../commands/perf.js'), 'dist/commands/perf.js')),
199
- bench: entry('beta', 'Run core trust-kernel benchmark budgets', 'dist/core/commands/bench-command.js', argsCommand(() => import('../core/commands/bench-command.js'), 'benchCommand', 'dist/core/commands/bench-command.js'))
199
+ bench: entry('beta', 'Run core trust-kernel benchmark budgets', 'dist/core/commands/bench-command.js', argsCommand(() => import('../core/commands/bench-command.js'), 'benchCommand', 'dist/core/commands/bench-command.js')),
200
+ 'mcp-server': entry('beta', 'Run a stdio MCP server exposing SKS commands as tools for any MCP-capable agent host', 'dist/core/commands/mcp-server-command.js', argsCommand(() => import('../core/commands/mcp-server-command.js'), 'mcpServerCommand', 'dist/core/commands/mcp-server-command.js'), {
201
+ skipMigrationGate: true,
202
+ allowedDuringActiveRoute: true,
203
+ activeRoutePolicy: 'always'
204
+ }),
205
+ 'agent-bridge': readOnly(entry('beta', 'Publish the agent-bridge manifest and print host registration snippets for external agent systems', 'dist/core/commands/agent-bridge-command.js', subcommand(() => import('../core/commands/agent-bridge-command.js'), 'agentBridgeCommand', 'dist/core/commands/agent-bridge-command.js', 'setup')))
200
206
  };
201
207
  export const TYPED_COMMANDS = COMMANDS;
202
208
  export const LEGACY_COMMAND_ALIASES = {};
@@ -22,6 +22,34 @@ export function normalizeCommand(args = []) {
22
22
  }
23
23
  export async function dispatch(args) {
24
24
  const argv = args ?? process.argv.slice(2);
25
+ try {
26
+ return await dispatchInner(argv);
27
+ }
28
+ catch (err) {
29
+ // Final choke point: any uncaught bug anywhere in the dispatch chain (gate
30
+ // checks, lazy command import, command run()) must never leak a raw stack
31
+ // dump to the user as their "answer" — convert it to a structured, honest
32
+ // failure instead. Every existing explicit error path above already sets
33
+ // process.exitCode and returns normally (never throws), so this only ever
34
+ // catches genuinely unexpected exceptions; it changes nothing about those
35
+ // paths' exit codes or messages.
36
+ const message = err instanceof Error ? err.message : String(err);
37
+ if (err instanceof Error && err.stack)
38
+ process.stderr.write(`${err.stack}\n`);
39
+ else
40
+ process.stderr.write(`${message}\n`);
41
+ process.exitCode = 1;
42
+ const result = { ok: false, error: message, command: normalizeCommand(argv).rawCommand };
43
+ // A --json caller depends on stdout always being exactly one JSON result
44
+ // (this is the same non-interactive contract SKS_AGENT_MODE promises) — an
45
+ // uncaught crash must not leave stdout empty, or a JSON.parse on the
46
+ // consuming end breaks with no diagnosable output at all.
47
+ if (argv.includes('--json'))
48
+ console.log(JSON.stringify(result, null, 2));
49
+ return result;
50
+ }
51
+ }
52
+ async function dispatchInner(argv) {
25
53
  const globalMode = detectGlobalMode(argv);
26
54
  if (globalMode?.kind === 'mad-glm') {
27
55
  const mod = await import('../core/commands/glm-command.js');
@@ -1,6 +1,6 @@
1
1
  import os from 'node:os';
2
2
  import path from 'node:path';
3
- import { projectRoot, exists, formatBytes } from '../core/fsx.js';
3
+ import { projectRoot, exists, formatBytes, nowIso, writeJsonAtomic } from '../core/fsx.js';
4
4
  import { flag } from '../cli/args.js';
5
5
  import { printJson } from '../cli/output.js';
6
6
  import { ui as cliUi } from '../cli/cli-theme.js';
@@ -48,6 +48,9 @@ import { reconcileSkills } from '../core/init/skills.js';
48
48
  import { codexHookTrustDoctor } from '../core/codex-hooks/codex-hook-trust-doctor.js';
49
49
  import { detectImagegenCapability } from '../core/imagegen/imagegen-capability.js';
50
50
  import { repairCodexImagegen } from '../core/doctor/imagegen-repair.js';
51
+ import { repairComputerUse } from '../core/doctor/computer-use-repair.js';
52
+ import { repairBrowserUse } from '../core/doctor/browser-use-repair.js';
53
+ import { detectAndRepairMcpTransportCollisions } from '../core/doctor/mcp-transport-collision-repair.js';
51
54
  export async function run(_command, args = []) {
52
55
  const root = await projectRoot();
53
56
  const doctorFix = flag(args, '--fix');
@@ -638,7 +641,8 @@ async function runDoctor(args = [], root, doctorFix) {
638
641
  after: imagegen,
639
642
  steps: [],
640
643
  blockers: [],
641
- manual_actions: []
644
+ manual_actions: [],
645
+ 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 }
642
646
  }
643
647
  : await repairCodexImagegen({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
644
648
  schema: 'sks.doctor-imagegen-repair.v1',
@@ -649,6 +653,49 @@ async function runDoctor(args = [], root, doctorFix) {
649
653
  blockers: [err?.message || String(err)],
650
654
  manual_actions: ['Run `sks doctor --fix --json` after enabling Codex App image_generation.']
651
655
  }));
656
+ const computerUseRepair = await repairComputerUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
657
+ schema: 'sks.doctor-computer-use-repair.v1',
658
+ ok: false,
659
+ attempted: false,
660
+ apply: doctorFix,
661
+ recovered: false,
662
+ blockers: [err?.message || String(err)],
663
+ next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Computer Use.']
664
+ }));
665
+ const browserUseRepair = await repairBrowserUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
666
+ schema: 'sks.doctor-browser-use-repair.v1',
667
+ ok: false,
668
+ attempted: false,
669
+ apply: doctorFix,
670
+ recovered: false,
671
+ blockers: [err?.message || String(err)],
672
+ next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Browser Use / Chrome extension.']
673
+ }));
674
+ const mcpTransportCollisionRepair = doctorFix
675
+ ? await detectAndRepairMcpTransportCollisions({ root, apply: true }).catch((err) => ({
676
+ schema: 'sks.mcp-transport-collision-repair.v1',
677
+ ok: false,
678
+ apply: true,
679
+ project_config_path: null,
680
+ global_config_path: null,
681
+ servers: [],
682
+ blockers: [err?.message || String(err)],
683
+ warnings: [],
684
+ raw_secret_values_recorded: false
685
+ }))
686
+ : null;
687
+ const nativeCapabilityReadinessStatus = (repair) => (repair?.recovered === true || repair?.ok === true ? 'ok' : repair?.attempted ? 'blocked' : 'not-needed');
688
+ const nativeCapabilityReadiness = {
689
+ schema: 'sks.native-capability-readiness.v1',
690
+ generated_at: nowIso(),
691
+ apply: doctorFix,
692
+ imagegen: { status: nativeCapabilityReadinessStatus(imagegenRepair), communication_test: imagegenRepair?.communication_test || null, blockers: imagegenRepair?.blockers || [] },
693
+ computer_use: { status: nativeCapabilityReadinessStatus(computerUseRepair), blockers: computerUseRepair?.blockers || [], next_actions: computerUseRepair?.next_actions || [] },
694
+ browser_use: { status: nativeCapabilityReadinessStatus(browserUseRepair), blockers: browserUseRepair?.blockers || [], next_actions: browserUseRepair?.next_actions || [] }
695
+ };
696
+ if (doctorFix) {
697
+ await writeJsonAtomic(path.join(root, '.sneakoscope', 'reports', 'native-capability-readiness.json'), nativeCapabilityReadiness).catch(() => undefined);
698
+ }
652
699
  const codex0138Capability = deepDiagnostics
653
700
  ? await writeCodex0138CapabilityArtifacts(root, { codexBin: codexBin || null }).catch((err) => ({ error: err?.message || String(err), report: null }))
654
701
  : { skipped: true, report: null };
@@ -856,7 +903,7 @@ async function runDoctor(args = [], root, doctorFix) {
856
903
  sneakoscope: { ok: await exists(`${root}/.sneakoscope`) },
857
904
  package: { bytes: pkgBytes, human: formatBytes(pkgBytes) },
858
905
  skills: skillsReconcile,
859
- repair: { sks_update: sksUpdate, setup: setupRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup, agent_role_config: agentRoleConfigRepair, zellij: zellijRepair, context7: context7Repair, codex_startup: codexStartupRepair, startup_config: startupConfigRepair, context7_mcp: context7McpRepair, supabase_mcp: supabaseMcpRepair, imagegen: imagegenRepair, hook_trust: hookTrustRepair, sks_menubar: sksMenuBar, doctor_transaction: doctorFixTransaction, doctor_dirty_plan: doctorDirtyPlan, doctor_postcheck: doctorFixPostcheck, codex_native: codexNativeRepair, doctor_native_capability: doctorNativeCapabilityRepair, command_aliases: commandAliasCleanup, skills: skillsReconcile, sks_temp_sweep: sksTempSweep }
906
+ repair: { sks_update: sksUpdate, setup: setupRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup, agent_role_config: agentRoleConfigRepair, zellij: zellijRepair, context7: context7Repair, codex_startup: codexStartupRepair, startup_config: startupConfigRepair, context7_mcp: context7McpRepair, supabase_mcp: supabaseMcpRepair, mcp_transport_collision: mcpTransportCollisionRepair, imagegen: imagegenRepair, computer_use: computerUseRepair, browser_use: browserUseRepair, hook_trust: hookTrustRepair, sks_menubar: sksMenuBar, doctor_transaction: doctorFixTransaction, doctor_dirty_plan: doctorDirtyPlan, doctor_postcheck: doctorFixPostcheck, codex_native: codexNativeRepair, doctor_native_capability: doctorNativeCapabilityRepair, command_aliases: commandAliasCleanup, skills: skillsReconcile, sks_temp_sweep: sksTempSweep }
860
907
  };
861
908
  if (reportFile)
862
909
  await writeJsonReportFile(reportFile, result);
@@ -1012,6 +1059,21 @@ async function runDoctor(args = [], root, doctorFix) {
1012
1059
  console.log(`Image Gen repair: ${imagegenRepair.recovered ? 'ok' : imagegenRepair.attempted ? 'blocked' : 'not-needed'}`);
1013
1060
  for (const action of imagegenRepair.manual_actions || [])
1014
1061
  console.log(` - ${action}`);
1062
+ console.log(`Computer Use repair: ${computerUseRepair.recovered ? 'ok' : computerUseRepair.attempted ? 'blocked' : 'not-needed'}`);
1063
+ for (const action of computerUseRepair.next_actions || [])
1064
+ console.log(` - ${action}`);
1065
+ console.log(`Browser Use repair: ${browserUseRepair.recovered ? 'ok' : browserUseRepair.attempted ? 'blocked' : 'not-needed'}`);
1066
+ for (const action of browserUseRepair.next_actions || [])
1067
+ console.log(` - ${action}`);
1068
+ if (mcpTransportCollisionRepair) {
1069
+ const collisionCount = (mcpTransportCollisionRepair.servers || []).filter((s) => s.status === 'collision_resolved').length;
1070
+ console.log(`MCP transport collision repair: ${mcpTransportCollisionRepair.ok ? 'ok' : 'blocked'}${collisionCount ? ` (${collisionCount} resolved)` : ''}`);
1071
+ }
1072
+ {
1073
+ const manifestPath = path.join(root, '.sneakoscope', 'agent-bridge', 'manifest.json');
1074
+ const manifestExists = await exists(manifestPath);
1075
+ console.log(`Agent bridge: ${manifestExists ? 'manifest present' : 'not set up'}${manifestExists ? '' : ' — run `sks agent-bridge setup` to publish the manifest and register with an MCP host'}`);
1076
+ }
1015
1077
  const codex0138 = codex0138Capability.report || {};
1016
1078
  console.log('Codex current compatibility:');
1017
1079
  console.log(` target: rust-v0.142.0`);