sneakoscope 3.1.13 → 3.1.14
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 +3 -3
- 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/core/agents/agent-cleanup-executor.js +75 -1
- package/dist/core/agents/agent-command-surface.js +29 -4
- package/dist/core/agents/agent-orchestrator.js +25 -6
- package/dist/core/agents/native-cli-session-swarm.js +1 -1
- package/dist/core/commands/local-model-command.js +1 -1
- package/dist/core/commands/naruto-command.js +14 -5
- package/dist/core/doctor/doctor-codex-startup-repair.js +3 -2
- package/dist/core/fsx.js +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-worker-pane-manager.js +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,16 +35,16 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
|
|
|
35
35
|
|
|
36
36
|
## 🚀 Current Release
|
|
37
37
|
|
|
38
|
-
SKS **3.1.
|
|
38
|
+
SKS **3.1.14** is a production-hardening release for Codex 0.140 evidence, transactional `sks doctor --fix` repair, MCP readiness, native capability proof, and protected-secret rollback.
|
|
39
39
|
|
|
40
|
-
What changed in 3.1.
|
|
40
|
+
What changed in 3.1.14:
|
|
41
41
|
|
|
42
42
|
- **Codex 0.140 readiness carries evidence.** Capability reports now expose per-feature state and certainty, real usage parsing, goal attachment roundtrip proof, and usage-budget provenance for loop/Naruto runtime decisions.
|
|
43
43
|
- **Doctor repair is phase-based.** `sks doctor --fix` records phase durations, postchecks, optional manual readiness, and rollback evidence instead of collapsing repair work into a summary writer.
|
|
44
44
|
- **Startup and MCP repair are safer.** Managed agent TOML blocks are repaired without touching unrelated config, missing role files are regenerated from real managed templates, Context7 disabled servers stay disabled, and Supabase write scope is separated from read-only readiness.
|
|
45
45
|
- **Secret rollback is line-level when possible.** Protected key changes are restored without discarding unrelated operator edits, nested guard operations are recorded, and backup artifacts remain ignored.
|
|
46
46
|
- **Native capability proof is stricter.** Computer Use and Chrome/web review no longer become verified from environment variables outside explicit fixture/test modes.
|
|
47
|
-
- **Release metadata is aligned for 3.1.
|
|
47
|
+
- **Release metadata is aligned for 3.1.14.** Package, lockfile, CLI version constants, Rust helper metadata, README, changelog, docs, built output, and release stamp all point at the same release.
|
|
48
48
|
|
|
49
49
|
SKS 3.0.0 was the parallel-runtime stabilization release. The whole live-swarm experience — what you actually *see* while 5, 20, or 100 workers run — was rebuilt and proven end-to-end.
|
|
50
50
|
|
|
@@ -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 3.1.
|
|
7
|
+
Some("--version") => println!("sks-rs 3.1.14"),
|
|
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,8 +1,9 @@
|
|
|
1
1
|
import fsp from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { appendJsonl, exists, nowIso, readJson, writeJsonAtomic } from '../fsx.js';
|
|
3
|
+
import { appendJsonl, exists, nowIso, packageRoot, readJson, writeJsonAtomic } from '../fsx.js';
|
|
4
4
|
import { drainZellijLaneSupervisor } from './zellij-lane-supervisor.js';
|
|
5
5
|
import { normalizeAgentSessionRows } from './agent-session-rows.js';
|
|
6
|
+
import { closeZellijPaneById } from '../zellij/zellij-worker-pane-manager.js';
|
|
6
7
|
export const AGENT_CLEANUP_PROOF_SCHEMA = 'sks.agent-cleanup-proof.v2';
|
|
7
8
|
export const AGENT_CLEANUP_ACTION_LEDGER_SCHEMA = 'sks.agent-cleanup-action-ledger.v1';
|
|
8
9
|
const TERMINAL_STATUSES = new Set(['closed', 'completed', 'done', 'failed', 'blocked', 'killed', 'timed_out']);
|
|
@@ -50,6 +51,7 @@ export async function runAgentCleanupExecutor(opts) {
|
|
|
50
51
|
killEscalation
|
|
51
52
|
}));
|
|
52
53
|
}
|
|
54
|
+
const seenZellijPaneIds = new Set();
|
|
53
55
|
const zellijReports = await listNamedFiles(path.join(agentRoot, 'sessions'), 'agent-zellij-report.json');
|
|
54
56
|
for (const file of zellijReports) {
|
|
55
57
|
const report = await readJson(file, null);
|
|
@@ -57,6 +59,7 @@ export async function runAgentCleanupExecutor(opts) {
|
|
|
57
59
|
const sessionId = String(report?.session_id || '');
|
|
58
60
|
if (!paneId)
|
|
59
61
|
continue;
|
|
62
|
+
seenZellijPaneIds.add(paneId);
|
|
60
63
|
if (!processReportInNamespace(report, projectHash)) {
|
|
61
64
|
actions.push({ kind: 'skip_foreign_namespace', target: paneId, status: 'skipped', reason: 'zellij_pane_outside_project_namespace' });
|
|
62
65
|
continue;
|
|
@@ -77,6 +80,77 @@ export async function runAgentCleanupExecutor(opts) {
|
|
|
77
80
|
}
|
|
78
81
|
}));
|
|
79
82
|
}
|
|
83
|
+
const workerPaneReports = await listNamedFiles(path.join(agentRoot, 'sessions'), 'zellij-worker-pane.json');
|
|
84
|
+
for (const file of workerPaneReports) {
|
|
85
|
+
const report = await readJson(file, null);
|
|
86
|
+
const paneId = String(report?.pane_id || '');
|
|
87
|
+
const sessionName = String(report?.session_name || '');
|
|
88
|
+
const sessionId = String(report?.session_id || '');
|
|
89
|
+
const status = String(report?.status || '');
|
|
90
|
+
if (!paneId || !sessionName || seenZellijPaneIds.has(paneId))
|
|
91
|
+
continue;
|
|
92
|
+
seenZellijPaneIds.add(paneId);
|
|
93
|
+
if (opts.missionId && report?.mission_id && String(report.mission_id) !== String(opts.missionId)) {
|
|
94
|
+
actions.push({ kind: 'skip_foreign_namespace', target: paneId, status: 'skipped', reason: 'zellij_pane_wrong_mission' });
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const terminal = TERMINAL_STATUSES.has(status) || Boolean(report?.closed_at);
|
|
98
|
+
if (activeSessionIds.has(sessionId) && !terminal && opts.drain !== true) {
|
|
99
|
+
actions.push({ kind: 'skip_active_session', target: sessionId || paneId, status: 'skipped', reason: 'managed_zellij_worker_active' });
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
actions.push(await applyAction({
|
|
103
|
+
kind: 'close_zellij_pane',
|
|
104
|
+
target: paneId,
|
|
105
|
+
reason: terminal ? 'managed_worker_zellij_pane_terminal' : 'managed_worker_zellij_pane_stale',
|
|
106
|
+
apply,
|
|
107
|
+
before: async () => ({ listed: true, pane_id: paneId, session_name: sessionName, source: path.relative(agentRoot, file), status }),
|
|
108
|
+
after: async () => ({ listed: false, pane_id: paneId, session_name: sessionName }),
|
|
109
|
+
run: async () => {
|
|
110
|
+
const close = await closeZellijPaneById(sessionName, paneId, packageRoot());
|
|
111
|
+
if (close && close.ok !== true)
|
|
112
|
+
throw new Error(close.blockers.join(',') || close.stderr_tail || 'zellij_pane_close_failed');
|
|
113
|
+
}
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
const rightColumnReports = await listNamedFiles(opts.missionDir, 'zellij-right-column-state.json');
|
|
117
|
+
for (const file of rightColumnReports) {
|
|
118
|
+
const report = await readJson(file, null);
|
|
119
|
+
const sessionName = String(report?.session_name || '');
|
|
120
|
+
if (!sessionName)
|
|
121
|
+
continue;
|
|
122
|
+
const visibleActive = (Array.isArray(report?.visible_worker_panes) ? report.visible_worker_panes : [])
|
|
123
|
+
.some((pane) => pane?.status === 'launching' || pane?.status === 'running');
|
|
124
|
+
const headlessActive = (Array.isArray(report?.headless_workers) ? report.headless_workers : [])
|
|
125
|
+
.some((row) => !row?.status || row.status === 'running');
|
|
126
|
+
const anchorPaneIds = [...new Set([
|
|
127
|
+
report?.slot_column_anchor_pane_id,
|
|
128
|
+
report?.right_anchor_pane_id,
|
|
129
|
+
report?.dashboard_pane_id
|
|
130
|
+
].map(String).filter((paneId) => paneId && paneId !== 'null' && paneId !== 'undefined'))];
|
|
131
|
+
for (const paneId of anchorPaneIds) {
|
|
132
|
+
if (seenZellijPaneIds.has(paneId))
|
|
133
|
+
continue;
|
|
134
|
+
seenZellijPaneIds.add(paneId);
|
|
135
|
+
if ((visibleActive || headlessActive) && opts.drain !== true) {
|
|
136
|
+
actions.push({ kind: 'skip_active_session', target: paneId, status: 'skipped', reason: 'zellij_right_column_anchor_active' });
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
actions.push(await applyAction({
|
|
140
|
+
kind: 'close_zellij_pane',
|
|
141
|
+
target: paneId,
|
|
142
|
+
reason: 'zellij_right_column_anchor_terminal',
|
|
143
|
+
apply,
|
|
144
|
+
before: async () => ({ listed: true, pane_id: paneId, session_name: sessionName, source: path.relative(opts.missionDir, file), visible_active: visibleActive, headless_active: headlessActive }),
|
|
145
|
+
after: async () => ({ listed: false, pane_id: paneId, session_name: sessionName }),
|
|
146
|
+
run: async () => {
|
|
147
|
+
const close = await closeZellijPaneById(sessionName, paneId, packageRoot());
|
|
148
|
+
if (close && close.ok !== true)
|
|
149
|
+
throw new Error(close.blockers.join(',') || close.stderr_tail || 'zellij_anchor_close_failed');
|
|
150
|
+
}
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
80
154
|
for (const dir of Array.isArray(namespace?.orphan_temp_dirs) ? namespace.orphan_temp_dirs.map(String) : []) {
|
|
81
155
|
if (!namespaceOwnsPath(dir, projectHash)) {
|
|
82
156
|
actions.push({ kind: 'skip_foreign_namespace', target: dir, status: 'skipped', reason: 'path_outside_project_namespace' });
|
|
@@ -12,10 +12,19 @@ export function parseAgentCommandArgs(command, args = []) {
|
|
|
12
12
|
const minimumWorkItems = Number(readOption(args, '--minimum-work-items', targetActiveSlots));
|
|
13
13
|
const maxQueueExpansion = Number(readOption(args, '--max-queue-expansion', 10));
|
|
14
14
|
const concurrency = Number(readOption(args, '--concurrency', Math.min(agents, 5)));
|
|
15
|
-
const
|
|
15
|
+
const useOllamaProtocol = hasFlag(args, '--ollama');
|
|
16
|
+
const useLocalModel = hasFlag(args, '--local-model');
|
|
17
|
+
const useOllama = useOllamaProtocol || useLocalModel;
|
|
16
18
|
const noOllama = hasFlag(args, '--no-ollama') || hasFlag(args, '--no-local-model');
|
|
17
|
-
const backendExplicit = hasOption(args, '--backend');
|
|
18
|
-
const
|
|
19
|
+
const backendExplicit = hasOption(args, '--backend') || useOllamaProtocol || useLocalModel || noOllama;
|
|
20
|
+
const defaultBackend = hasFlag(args, '--mock')
|
|
21
|
+
? 'fake'
|
|
22
|
+
: useLocalModel && !noOllama
|
|
23
|
+
? 'local-llm'
|
|
24
|
+
: useOllamaProtocol && !noOllama
|
|
25
|
+
? 'ollama'
|
|
26
|
+
: 'codex-sdk';
|
|
27
|
+
const backend = String(readOption(args, '--backend', defaultBackend));
|
|
19
28
|
const route = String(readOption(args, '--route', '$Agent'));
|
|
20
29
|
const mock = hasFlag(args, '--mock') || backend === 'fake';
|
|
21
30
|
const real = hasFlag(args, '--real');
|
|
@@ -34,7 +43,7 @@ export function parseAgentCommandArgs(command, args = []) {
|
|
|
34
43
|
const zellijSessionName = String(readOption(args, '--zellij-session-name', '') || '') || null;
|
|
35
44
|
const zellijPaneWorker = hasFlag(args, '--no-zellij-pane-worker') ? false : hasFlag(args, '--zellij-pane-worker') ? true : undefined;
|
|
36
45
|
const workerPlacement = String(readOption(args, '--worker-placement', zellijPaneWorker === true ? 'zellij-pane' : '') || '') || undefined;
|
|
37
|
-
const zellijVisiblePaneCap =
|
|
46
|
+
const zellijVisiblePaneCap = resolveZellijVisiblePaneCap(readOption(args, '--zellij-visible-pane-cap', process.env.SKS_ZELLIJ_VISIBLE_PANE_CAP || ''), hasOption(args, '--zellij-visible-pane-cap') || Boolean(process.env.SKS_ZELLIJ_VISIBLE_PANE_CAP));
|
|
38
47
|
const apply = hasFlag(args, '--apply');
|
|
39
48
|
const dryRun = hasFlag(args, '--dry-run') || hasFlag(args, '--dryrun');
|
|
40
49
|
const drain = hasFlag(args, '--drain');
|
|
@@ -52,6 +61,22 @@ export function parseAgentCommandArgs(command, args = []) {
|
|
|
52
61
|
const prompt = promptPositionals.join(' ').trim() || 'Native agent run';
|
|
53
62
|
return { command, action, prompt, route, agents, targetActiveSlots, desiredWorkItemCount, minimumWorkItems, maxQueueExpansion, concurrency, backend, backendExplicit, mock, real, readonly, profile, writeMode, applyPatches, dryRunPatches, maxWriteAgents, fastMode, serviceTier, noFast, ollamaEnabled: useOllama && !noOllama, noOllama, ollamaModel, ollamaBaseUrl, zellijSessionName, zellijPaneWorker, workerPlacement, zellijVisiblePaneCap, apply, dryRun, drain, staleMs, graceMs, killEscalation, json, missionId, lane, codexApp, patchEntryId };
|
|
54
63
|
}
|
|
64
|
+
export function resolveZellijVisiblePaneCap(value = '', explicit = false) {
|
|
65
|
+
const requested = Number(value);
|
|
66
|
+
if (explicit && Number.isFinite(requested) && requested >= 1)
|
|
67
|
+
return Math.max(1, Math.floor(requested));
|
|
68
|
+
const columns = Number(process.env.SKS_ZELLIJ_TERMINAL_COLUMNS || process.env.COLUMNS || process.stdout?.columns || 0);
|
|
69
|
+
const unknownFallback = Number(process.env.SKS_ZELLIJ_UNKNOWN_VISIBLE_PANE_CAP || 3);
|
|
70
|
+
if (!Number.isFinite(columns) || columns < 120) {
|
|
71
|
+
return Math.max(1, Math.floor(Number.isFinite(unknownFallback) ? unknownFallback : 3));
|
|
72
|
+
}
|
|
73
|
+
const reservedColumns = Number(process.env.SKS_ZELLIJ_RESERVED_COLUMNS || 108);
|
|
74
|
+
const minWorkerColumns = Number(process.env.SKS_ZELLIJ_MIN_WORKER_PANE_COLUMNS || 72);
|
|
75
|
+
const maxAutoVisible = Number(process.env.SKS_ZELLIJ_MAX_AUTO_VISIBLE_PANES || 8);
|
|
76
|
+
const available = Math.max(0, columns - Math.max(80, reservedColumns));
|
|
77
|
+
const computed = Math.floor(available / Math.max(40, minWorkerColumns));
|
|
78
|
+
return Math.max(1, Math.min(Math.max(1, Math.floor(maxAutoVisible || 8)), computed || Math.floor(unknownFallback) || 3));
|
|
79
|
+
}
|
|
55
80
|
function hasFlag(args, flag) {
|
|
56
81
|
return args.includes(flag);
|
|
57
82
|
}
|
|
@@ -1676,7 +1676,8 @@ async function runAgentByBackend(backend, agent, slice, opts) {
|
|
|
1676
1676
|
return runProcessAgent(agent, slice, opts);
|
|
1677
1677
|
if (backend === 'ollama')
|
|
1678
1678
|
return runOllamaAgent(agent, slice, opts);
|
|
1679
|
-
if (backend === 'codex-sdk' || backend === 'zellij') {
|
|
1679
|
+
if (backend === 'codex-sdk' || backend === 'zellij' || backend === 'local-llm') {
|
|
1680
|
+
const localPreferred = backend === 'local-llm';
|
|
1680
1681
|
const ledgerRoot = path.resolve(opts.agentRoot || opts.cwd || process.cwd());
|
|
1681
1682
|
const workerDir = path.join(ledgerRoot, 'codex-sdk-workers', String(agent.session_id || agent.id || 'agent'), String(slice?.id || 'slice'));
|
|
1682
1683
|
const writePaths = sdkWritePaths(slice, opts);
|
|
@@ -1703,6 +1704,9 @@ async function runAgentByBackend(backend, agent, slice, opts) {
|
|
|
1703
1704
|
user_confirmed_full_access: false,
|
|
1704
1705
|
mad_sks_authorized: opts.madSksAuthorized === true || process.env.SKS_MAD_SKS_ACTIVE === '1'
|
|
1705
1706
|
},
|
|
1707
|
+
backendPreference: localPreferred ? ['local-llm', 'codex-sdk'] : ['codex-sdk'],
|
|
1708
|
+
allowLocalLlm: localPreferred,
|
|
1709
|
+
...(localPreferred ? { localLlmPolicy: { mode: 'local_preferred', requiresGptFinal: true } } : {}),
|
|
1706
1710
|
mutationLedgerRoot: workerDir,
|
|
1707
1711
|
zellijPaneId: null
|
|
1708
1712
|
});
|
|
@@ -1710,9 +1714,11 @@ async function runAgentByBackend(backend, agent, slice, opts) {
|
|
|
1710
1714
|
const patchEnvelopes = normalizeDirectSdkPatchEnvelopes(sdkWorkerResult?.patch_envelopes || [], agent, opts, sdkTask.sdkThreadId);
|
|
1711
1715
|
const sdkReport = {
|
|
1712
1716
|
schema: 'sks.codex-sdk-worker-adapter.v1',
|
|
1713
|
-
backend: 'codex-sdk',
|
|
1717
|
+
backend: sdkTask.backend === 'local-llm' ? 'local-llm' : 'codex-sdk',
|
|
1718
|
+
backend_family: sdkTask.backend_family,
|
|
1714
1719
|
sdk_thread_id: sdkTask.sdkThreadId,
|
|
1715
1720
|
sdk_run_id: sdkTask.sdkRunId,
|
|
1721
|
+
local_llm_proof_path: sdkTask.localLlmProofPath || null,
|
|
1716
1722
|
stream_event_count: sdkTask.streamEventCount,
|
|
1717
1723
|
structured_output_valid: sdkTask.structuredOutputValid,
|
|
1718
1724
|
worker_result_path: path.relative(ledgerRoot, sdkTask.workerResultPath),
|
|
@@ -1723,18 +1729,31 @@ async function runAgentByBackend(backend, agent, slice, opts) {
|
|
|
1723
1729
|
};
|
|
1724
1730
|
return validateAgentWorkerResult({
|
|
1725
1731
|
...sdkWorkerResult,
|
|
1726
|
-
backend: 'codex-sdk',
|
|
1732
|
+
backend: sdkTask.backend === 'local-llm' ? 'local-llm' : 'codex-sdk',
|
|
1727
1733
|
patch_envelopes: patchEnvelopes,
|
|
1728
1734
|
...(patchEnvelopes.length ? {} : { no_patch_reason: buildDirectNoPatchReason(slice, opts) }),
|
|
1729
1735
|
codex_child_report: sdkReport,
|
|
1730
1736
|
codex_sdk_thread: sdkReport,
|
|
1731
1737
|
model_authored_patch_envelopes: patchEnvelopes.length > 0,
|
|
1732
1738
|
fixture_patch_envelopes: false,
|
|
1733
|
-
artifacts: [...new Set([
|
|
1739
|
+
artifacts: [...new Set([
|
|
1740
|
+
...(sdkWorkerResult?.artifacts || []),
|
|
1741
|
+
path.relative(ledgerRoot, sdkTask.workerResultPath),
|
|
1742
|
+
path.join(path.relative(ledgerRoot, workerDir), 'codex-control-proof.json'),
|
|
1743
|
+
path.join(path.relative(ledgerRoot, workerDir), 'codex-thread-registry.json'),
|
|
1744
|
+
path.join(path.relative(ledgerRoot, workerDir), sdkTask.backend === 'local-llm' ? 'local-llm-events.jsonl' : 'codex-sdk-events.jsonl'),
|
|
1745
|
+
...(sdkTask.localLlmProofPath ? [path.relative(ledgerRoot, sdkTask.localLlmProofPath)] : [])
|
|
1746
|
+
])],
|
|
1734
1747
|
blockers: [...(sdkWorkerResult?.blockers || []), ...sdkTask.blockers],
|
|
1735
1748
|
verification: {
|
|
1736
1749
|
status: sdkTask.ok ? 'passed' : 'failed',
|
|
1737
|
-
checks: [
|
|
1750
|
+
checks: [
|
|
1751
|
+
...(sdkWorkerResult?.verification?.checks || []),
|
|
1752
|
+
sdkTask.backend === 'local-llm' ? 'local-llm-control-plane' : 'codex-sdk-control-plane',
|
|
1753
|
+
sdkTask.backend === 'local-llm' ? 'local-llm-event-stream' : 'codex-sdk-event-stream',
|
|
1754
|
+
sdkTask.backend === 'local-llm' ? 'local-llm-structured-output' : 'codex-sdk-structured-output',
|
|
1755
|
+
...(sdkTask.backend === 'local-llm' ? ['gpt-final-required-before-acceptance'] : [])
|
|
1756
|
+
]
|
|
1738
1757
|
}
|
|
1739
1758
|
});
|
|
1740
1759
|
}
|
|
@@ -1753,7 +1772,7 @@ async function maybeSelectOllamaBackend(backend, agent, slice, opts) {
|
|
|
1753
1772
|
if (!config?.ok || config.enabled !== true)
|
|
1754
1773
|
return backend;
|
|
1755
1774
|
const policy = classifyOllamaWorkerSlice(slice, { route: opts.route, agent });
|
|
1756
|
-
return policy.ok ? '
|
|
1775
|
+
return policy.ok ? 'local-llm' : backend;
|
|
1757
1776
|
}
|
|
1758
1777
|
function buildDirectSdkWorkerPrompt(slice) {
|
|
1759
1778
|
const write = sdkWritePaths(slice, {});
|
|
@@ -66,7 +66,7 @@ class NativeCliSessionSwarmRecorder {
|
|
|
66
66
|
patch_envelope_path: patchRel,
|
|
67
67
|
service_tier: this.input.fastModePolicy.service_tier,
|
|
68
68
|
fast_mode: this.input.fastModePolicy.fast_mode,
|
|
69
|
-
ollama_enabled: ctx.opts.ollamaEnabled === true || this.input.backend === 'ollama',
|
|
69
|
+
ollama_enabled: ctx.opts.ollamaEnabled === true || this.input.backend === 'ollama' || this.input.backend === 'local-llm',
|
|
70
70
|
ollama_model: ctx.opts.ollamaModel || null,
|
|
71
71
|
ollama_base_url: ctx.opts.ollamaBaseUrl || null,
|
|
72
72
|
source_intelligence_refs: ctx.agent.source_intelligence_refs || null,
|
|
@@ -72,7 +72,7 @@ async function enable(args) {
|
|
|
72
72
|
: await runLocalLlmGenerationSmoke(config, {
|
|
73
73
|
prompt: 'Return strict JSON: {"status":"ok","summary":"local smoke passed"}',
|
|
74
74
|
schema: localLlmSmokeSchema,
|
|
75
|
-
timeoutMs:
|
|
75
|
+
timeoutMs: Math.max(60_000, Number(config.timeout_ms || 0) || 0)
|
|
76
76
|
});
|
|
77
77
|
const next = await writeLocalModelConfig(applyLocalLlmSmokeResult(config, smoke));
|
|
78
78
|
if (!skipSmoke && smoke.ok !== true)
|
|
@@ -108,7 +108,7 @@ async function narutoRun(parsed) {
|
|
|
108
108
|
// system-safe number so naruto never spawns the whole count at once unless an
|
|
109
109
|
// explicit operator override asks for a higher target.
|
|
110
110
|
const localWorker = await resolveNarutoLocalWorkerMode(parsed);
|
|
111
|
-
const schedulerBackend = localWorker.auto_select_eligible ? '
|
|
111
|
+
const schedulerBackend = localWorker.auto_select_eligible ? 'local-llm' : parsed.backend;
|
|
112
112
|
const safe = systemSafeNarutoConcurrency({ backend: schedulerBackend });
|
|
113
113
|
const baseWorkGraph = buildNarutoWorkGraph({
|
|
114
114
|
prompt: parsed.prompt,
|
|
@@ -658,7 +658,7 @@ function summarizeNarutoLocalWorkerResult(localWorker, result) {
|
|
|
658
658
|
}
|
|
659
659
|
return {
|
|
660
660
|
...localWorker,
|
|
661
|
-
selected_worker_count: backendCounts.ollama || 0,
|
|
661
|
+
selected_worker_count: (backendCounts['local-llm'] || 0) + (backendCounts.ollama || 0),
|
|
662
662
|
backend_counts: backendCounts
|
|
663
663
|
};
|
|
664
664
|
}
|
|
@@ -770,7 +770,7 @@ async function narutoHelp(parsed) {
|
|
|
770
770
|
mode: 'NARUTO',
|
|
771
771
|
description: 'Shadow Clone Swarm: fan out up to ' + MAX_NARUTO_AGENT_COUNT + ' parallel clone sessions.',
|
|
772
772
|
usage: [
|
|
773
|
-
'sks naruto run "<task>" [--clones N] [--backend codex-sdk|fake|ollama] [--local-model|--no-ollama] [--work-items N] [--write-mode parallel|serial|off] [--apply-patches] [--dry-run-patches] [--real] [--readonly] [--json]',
|
|
773
|
+
'sks naruto run "<task>" [--clones N] [--backend codex-sdk|fake|ollama|local-llm] [--local-model|--ollama|--no-ollama] [--work-items N] [--write-mode parallel|serial|off] [--apply-patches] [--dry-run-patches] [--real] [--readonly] [--json]',
|
|
774
774
|
'sks naruto status [--mission <id>] [--json]',
|
|
775
775
|
'sks naruto proof latest [--messages 20] [--json]'
|
|
776
776
|
],
|
|
@@ -796,10 +796,19 @@ function parseNarutoArgs(args = []) {
|
|
|
796
796
|
const workItemsExplicit = hasOption(args, '--work-items');
|
|
797
797
|
const workItems = clampWorkItems(Number(readOption(args, '--work-items', clones * 2)), clones);
|
|
798
798
|
const concurrency = normalizeConcurrency(readOption(args, '--concurrency', readOption(args, '--target-active-slots', null)), clones);
|
|
799
|
-
const
|
|
799
|
+
const useOllamaProtocol = hasFlag(args, '--ollama');
|
|
800
|
+
const useLocalModel = hasFlag(args, '--local-model');
|
|
801
|
+
const useOllama = useOllamaProtocol || useLocalModel;
|
|
800
802
|
const noOllama = hasFlag(args, '--no-ollama') || hasFlag(args, '--no-local-model');
|
|
801
803
|
const backendExplicit = hasOption(args, '--backend') || useOllama || noOllama;
|
|
802
|
-
const
|
|
804
|
+
const defaultBackend = hasFlag(args, '--mock')
|
|
805
|
+
? 'fake'
|
|
806
|
+
: useLocalModel && !noOllama
|
|
807
|
+
? 'local-llm'
|
|
808
|
+
: useOllamaProtocol && !noOllama
|
|
809
|
+
? 'ollama'
|
|
810
|
+
: 'codex-sdk';
|
|
811
|
+
const backend = String(readOption(args, '--backend', defaultBackend));
|
|
803
812
|
const mock = hasFlag(args, '--mock') || backend === 'fake';
|
|
804
813
|
const real = hasFlag(args, '--real');
|
|
805
814
|
const readonly = hasFlag(args, '--readonly') || hasFlag(args, '--read-only');
|
|
@@ -104,9 +104,10 @@ async function inspectOrRepairConfig(candidate, fix, nodeReplCommandCandidates,
|
|
|
104
104
|
const currentValid = Boolean(current && path.isAbsolute(current) && await exists(current));
|
|
105
105
|
if (currentValid && current === target)
|
|
106
106
|
continue;
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
if (!fix) {
|
|
108
|
+
warnings.push(`agent_config_file_stale:${tableName}`);
|
|
109
109
|
continue;
|
|
110
|
+
}
|
|
110
111
|
if (!targetExists) {
|
|
111
112
|
await ensureDir(path.dirname(target));
|
|
112
113
|
await writeTextAtomic(target, roleConfigToml(tableName, role.description, role.sandbox));
|
package/dist/core/fsx.js
CHANGED
|
@@ -5,7 +5,7 @@ import os from 'node:os';
|
|
|
5
5
|
import crypto from 'node:crypto';
|
|
6
6
|
import { spawn } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
|
-
export const PACKAGE_VERSION = '3.1.
|
|
8
|
+
export const PACKAGE_VERSION = '3.1.14';
|
|
9
9
|
export const DEFAULT_PROCESS_TAIL_BYTES = 256 * 1024;
|
|
10
10
|
export const DEFAULT_PROCESS_TIMEOUT_MS = 30 * 60 * 1000;
|
|
11
11
|
export function nowIso() {
|
package/dist/core/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '3.1.
|
|
1
|
+
export const PACKAGE_VERSION = '3.1.14';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -459,7 +459,8 @@ export async function closeWorkerPane(input) {
|
|
|
459
459
|
const root = path.resolve(input.root);
|
|
460
460
|
const success = (input.status || 'closed') === 'closed' && !(input.blockers || []).length;
|
|
461
461
|
const closeSuccess = process.env.SKS_ZELLIJ_CLOSE_WORKER_PANE !== '0';
|
|
462
|
-
const
|
|
462
|
+
const keepFailed = process.env.SKS_ZELLIJ_KEEP_FAILED_PANE === '1';
|
|
463
|
+
const closeFailed = !keepFailed && process.env.SKS_ZELLIJ_CLOSE_FAILED_PANE !== '0';
|
|
463
464
|
const paneId = input.paneRecord.pane_id;
|
|
464
465
|
const shouldClose = Boolean(paneId) && (success ? closeSuccess : closeFailed);
|
|
465
466
|
const close = shouldClose
|
|
@@ -700,7 +701,7 @@ async function focusZellijPaneById(sessionName, paneId, cwd) {
|
|
|
700
701
|
}
|
|
701
702
|
return last;
|
|
702
703
|
}
|
|
703
|
-
async function closeZellijPaneById(sessionName, paneId, cwd) {
|
|
704
|
+
export async function closeZellijPaneById(sessionName, paneId, cwd) {
|
|
704
705
|
const candidates = zellijPaneIdCandidates(paneId);
|
|
705
706
|
let last = null;
|
|
706
707
|
for (const candidate of candidates) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.14",
|
|
5
5
|
"description": "Sneakoscope Codex: fast proof-first Codex trust layer with image-based Voxel TriWiki.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|