sneakoscope 1.20.4 → 1.21.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 +2 -0
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +3 -3
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +3 -3
- package/dist/commands/mad-sks.d.ts +11 -1
- package/dist/core/agents/agent-codex-cockpit.d.ts +1 -1
- package/dist/core/agents/agent-command-surface.d.ts +1 -1
- package/dist/core/agents/agent-command-surface.js +2 -1
- package/dist/core/agents/agent-orchestrator.js +2 -2
- package/dist/core/agents/agent-plan.d.ts +1 -1
- package/dist/core/agents/agent-plan.js +1 -1
- package/dist/core/agents/fast-mode-policy.d.ts +5 -0
- package/dist/core/agents/fast-mode-policy.js +12 -1
- package/dist/core/codex/codex-cli-syntax-builder.d.ts +1 -1
- package/dist/core/codex/codex-cli-syntax-builder.js +11 -2
- package/dist/core/commands/fast-mode-command.js +4 -4
- package/dist/core/commands/mad-sks-command.d.ts +11 -1
- package/dist/core/commands/mad-sks-command.js +41 -3
- package/dist/core/commands/naruto-command.js +27 -2
- package/dist/core/commands/research-command.js +6 -3
- package/dist/core/commands/run-command.js +3 -3
- package/dist/core/commands/team-command.d.ts +7 -6
- package/dist/core/commands/team-command.js +60 -13
- package/dist/core/fsx.d.ts +1 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/hooks-runtime.js +4 -4
- package/dist/core/perf-bench.d.ts +3 -2
- package/dist/core/pipeline-internals/runtime-core.d.ts +6 -4
- package/dist/core/pipeline-internals/runtime-core.js +22 -21
- package/dist/core/pipeline-internals/runtime-gates.js +3 -3
- package/dist/core/routes.js +7 -7
- package/dist/core/team-dag.js +1 -1
- package/dist/core/team-live.js +4 -4
- package/dist/core/version-manager.js +32 -11
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-launcher.d.ts +57 -4
- package/dist/core/zellij/zellij-launcher.js +57 -13
- package/dist/core/zellij/zellij-layout-builder.d.ts +6 -0
- package/dist/core/zellij/zellij-layout-builder.js +34 -2
- package/dist/core/zellij/zellij-pane-proof.d.ts +6 -0
- package/dist/core/zellij/zellij-pane-proof.js +20 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,8 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
|
|
|
16
16
|
|
|
17
17
|
## Current Release
|
|
18
18
|
|
|
19
|
+
SKS **1.21.0** carries forward the `sks --mad` Zellij auto-attach fix and aligns the release metadata gates with explicit version bumps. Previous releases only *created* a detached background session and printed an `Attach with: ...` hint, so nothing opened in the operator's terminal. SKS now performs the follow-up foreground attach automatically when launched in an interactive TTY (using the same `ZELLIJ_SOCKET_DIR` namespace as the background session), and falls back to printing the manual attach command if attach fails. Auto-attach is skipped for `--json`, non-TTY/piped launches, when already inside a Zellij session, or with `--no-attach` / `SKS_NO_ZELLIJ_ATTACH=1`; `--attach` forces it.
|
|
20
|
+
|
|
19
21
|
SKS **1.20.4** is a targeted `sks --mad` / codex-lb Zellij usability patch: when a background MAD Zellij session launches successfully, SKS now prints the exact `Attach with: ZELLIJ_SOCKET_DIR=... zellij attach ...` command so operators can enter the fresh session without manually reconstructing the socket namespace.
|
|
20
22
|
|
|
21
23
|
SKS **1.20.3** added the macOS Zellij launch fallback and project-local Fast mode control. SKS supplies a short per-user `ZELLIJ_SOCKET_DIR` by default, caps generated session names safely, records `*_command_with_env` attach commands, and classifies `IPC socket path is too long` as `zellij_socket_path_too_long` instead of a generic launch failure. It also adds `sks fast-mode on|off|status|clear`, `$Fast-On`, `$Fast-Off`, and `$Fast-Mode`; saved project preferences are used only when no explicit `--fast`, `--no-fast`, or `--service-tier` flag is present.
|
|
@@ -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 1.
|
|
7
|
+
Some("--version") => println!("sks-rs 1.21.0"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build-stamp.v1",
|
|
3
3
|
"package_name": "sneakoscope",
|
|
4
|
-
"package_version": "1.
|
|
5
|
-
"source_digest": "
|
|
4
|
+
"package_version": "1.21.0",
|
|
5
|
+
"source_digest": "666db83626c95b8a8eae20389e647a2db96c4e22802cdf18ce0f7c142c9dbcaa",
|
|
6
6
|
"source_file_count": 1750,
|
|
7
|
-
"built_at_source_time":
|
|
7
|
+
"built_at_source_time": 1780297266324
|
|
8
8
|
}
|
package/dist/bin/sks.js
CHANGED
package/dist/build-manifest.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build.v2",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"package_version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
|
+
"package_version": "1.21.0",
|
|
5
5
|
"typescript": true,
|
|
6
6
|
"mjs_runtime_files": 0,
|
|
7
7
|
"compiled_file_count": 1020,
|
|
8
8
|
"compiled_js_count": 510,
|
|
9
9
|
"compiled_dts_count": 510,
|
|
10
|
-
"source_digest": "
|
|
10
|
+
"source_digest": "666db83626c95b8a8eae20389e647a2db96c4e22802cdf18ce0f7c142c9dbcaa",
|
|
11
11
|
"source_file_count": 1750,
|
|
12
12
|
"source_files_hash": "de93b15a72352d00481b958333ed964bf083563809e3beddfe4e64046720df75",
|
|
13
13
|
"source_list_hash": "de93b15a72352d00481b958333ed964bf083563809e3beddfe4e64046720df75",
|
|
@@ -2,7 +2,7 @@ export declare function run(_command: any, args?: any): Promise<void | {
|
|
|
2
2
|
schema: string;
|
|
3
3
|
generated_at: string;
|
|
4
4
|
ok: boolean;
|
|
5
|
-
kind: "agent" | "team" | "mad";
|
|
5
|
+
kind: "agent" | "team" | "mad" | "naruto";
|
|
6
6
|
mission_id: string;
|
|
7
7
|
session_name: string;
|
|
8
8
|
root: string;
|
|
@@ -10,6 +10,13 @@ export declare function run(_command: any, args?: any): Promise<void | {
|
|
|
10
10
|
ledger_root: string;
|
|
11
11
|
layout_path: string;
|
|
12
12
|
layout_artifact: string;
|
|
13
|
+
main_pane_kind: "codex_interactive" | "status_shell";
|
|
14
|
+
codex_pane: {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
args: string[];
|
|
17
|
+
launch_env_keys: string[];
|
|
18
|
+
bin: string;
|
|
19
|
+
};
|
|
13
20
|
command: string[];
|
|
14
21
|
launch_command: string[];
|
|
15
22
|
launch_command_with_env: string;
|
|
@@ -17,6 +24,7 @@ export declare function run(_command: any, args?: any): Promise<void | {
|
|
|
17
24
|
background_command_with_env: string;
|
|
18
25
|
attach_command: string;
|
|
19
26
|
attach_command_with_env: string;
|
|
27
|
+
attach_requested: boolean;
|
|
20
28
|
zellij_socket_dir: string | null;
|
|
21
29
|
zellij_socket_dir_source: import("../core/zellij/zellij-command.js").ZellijSocketDirSource;
|
|
22
30
|
pane_proof_path: string;
|
|
@@ -32,6 +40,8 @@ export declare function run(_command: any, args?: any): Promise<void | {
|
|
|
32
40
|
main_pane: any;
|
|
33
41
|
lane_panes: any[];
|
|
34
42
|
expected_lane_count: number;
|
|
43
|
+
expected_main_command_includes: string | null;
|
|
44
|
+
main_command_ok: boolean;
|
|
35
45
|
lane_count_ok: boolean;
|
|
36
46
|
geometry_distinct: boolean | null;
|
|
37
47
|
panes: any[];
|
|
@@ -5,7 +5,7 @@ export declare const AGENT_LIVE_SUMMARY_JSON = "agent-live-summary.json";
|
|
|
5
5
|
export declare const AGENT_PROGRESS_TIMELINE_MD = "agent-progress-timeline.md";
|
|
6
6
|
export declare const AGENT_CODEX_COCKPIT_EVENTS = "agent-codex-cockpit-events.jsonl";
|
|
7
7
|
export type CodexCockpitHookPayload = {
|
|
8
|
-
hook_event_name: 'SubagentStart' | 'SubagentStop';
|
|
8
|
+
hook_event_name: 'NativeSessionStart' | 'NativeSessionStop' | 'SubagentStart' | 'SubagentStop';
|
|
9
9
|
agent_id?: string;
|
|
10
10
|
agent_type?: string;
|
|
11
11
|
session_id?: string;
|
|
@@ -19,7 +19,7 @@ export declare function parseAgentCommandArgs(command: string, args?: string[]):
|
|
|
19
19
|
dryRunPatches: boolean;
|
|
20
20
|
maxWriteAgents: number;
|
|
21
21
|
fastMode: boolean | undefined;
|
|
22
|
-
serviceTier:
|
|
22
|
+
serviceTier: import("./fast-mode-policy.js").AgentServiceTier | undefined;
|
|
23
23
|
noFast: boolean;
|
|
24
24
|
apply: boolean;
|
|
25
25
|
dryRun: boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_AGENT_COUNT } from './agent-schema.js';
|
|
2
|
+
import { normalizeServiceTier } from './fast-mode-policy.js';
|
|
2
3
|
export function parseAgentCommandArgs(command, args = []) {
|
|
3
4
|
const first = args[0] && !String(args[0]).startsWith('--') ? String(args[0]) : '';
|
|
4
5
|
const actions = new Set(['run', 'worker', 'status', 'plan', 'spawn', 'watch', 'dashboard', 'cockpit', 'lane', 'board', 'ledger', 'collect', 'consensus', 'close', 'cleanup', 'proof', 'explain', 'rollback-patches']);
|
|
@@ -22,7 +23,7 @@ export function parseAgentCommandArgs(command, args = []) {
|
|
|
22
23
|
const dryRunPatches = hasFlag(args, '--dry-run-patches') || hasFlag(args, '--dryrun-patches');
|
|
23
24
|
const maxWriteAgents = Number(readOption(args, '--max-write-agents', Math.max(1, Math.min(concurrency, agents))));
|
|
24
25
|
const explicitServiceTier = String(readOption(args, '--service-tier', '') || '');
|
|
25
|
-
const serviceTier = explicitServiceTier
|
|
26
|
+
const serviceTier = normalizeServiceTier(explicitServiceTier, null) || undefined;
|
|
26
27
|
const fastMode = hasFlag(args, '--no-fast') || serviceTier === 'standard' ? false : hasFlag(args, '--fast') ? true : undefined;
|
|
27
28
|
const noFast = hasFlag(args, '--no-fast');
|
|
28
29
|
const apply = hasFlag(args, '--apply');
|
|
@@ -264,7 +264,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
264
264
|
await openAgentSession(ledgerRoot, agent);
|
|
265
265
|
await heartbeatAgentSession(ledgerRoot, agent);
|
|
266
266
|
await appendAgentCodexCockpitHookEvent(dir, {
|
|
267
|
-
hook_event_name: '
|
|
267
|
+
hook_event_name: 'NativeSessionStart',
|
|
268
268
|
agent_id: agent.id,
|
|
269
269
|
agent_type: agent.role || agent.persona_id || 'agent',
|
|
270
270
|
session_id: agent.session_id,
|
|
@@ -310,7 +310,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
310
310
|
await completeAgentSession(ledgerRoot, agent);
|
|
311
311
|
await closeAgentSession(ledgerRoot, agent, result.status === 'done' ? 'closed' : result.status);
|
|
312
312
|
await appendAgentCodexCockpitHookEvent(dir, {
|
|
313
|
-
hook_event_name: '
|
|
313
|
+
hook_event_name: 'NativeSessionStop',
|
|
314
314
|
agent_id: agent.id,
|
|
315
315
|
agent_type: agent.role || agent.persona_id || 'agent',
|
|
316
316
|
session_id: agent.session_id,
|
|
@@ -33,7 +33,7 @@ export function agentPipelineStage(policy = {}) {
|
|
|
33
33
|
id: AGENT_INTAKE_STAGE_ID,
|
|
34
34
|
goal: 'Run native multi-session agent intake with non-overlapping leases and proof evidence.',
|
|
35
35
|
agent_count: required ? Number(policy.agent_count || DEFAULT_AGENT_COUNT) : 0,
|
|
36
|
-
|
|
36
|
+
max_parallel_native_sessions: Number(policy.agent_count || DEFAULT_AGENT_COUNT),
|
|
37
37
|
backend: 'native-agent-kernel',
|
|
38
38
|
read_only: true,
|
|
39
39
|
write_policy: 'read-only analysis; parent-owned integration',
|
|
@@ -2,12 +2,14 @@ export declare const FAST_MODE_POLICY_SCHEMA = "sks.fast-mode-policy.v1";
|
|
|
2
2
|
export declare const FAST_MODE_PROPAGATION_PROOF_SCHEMA = "sks.fast-mode-propagation-proof.v1";
|
|
3
3
|
export declare const FAST_MODE_PREFERENCE_SCHEMA = "sks.fast-mode-preference.v1";
|
|
4
4
|
export type AgentServiceTier = 'fast' | 'standard';
|
|
5
|
+
export type CodexDesktopServiceTier = 'priority' | 'default';
|
|
5
6
|
export type FastModePreferenceMode = AgentServiceTier;
|
|
6
7
|
export interface FastModePolicy {
|
|
7
8
|
schema: typeof FAST_MODE_POLICY_SCHEMA;
|
|
8
9
|
generated_at: string;
|
|
9
10
|
fast_mode: boolean;
|
|
10
11
|
service_tier: AgentServiceTier;
|
|
12
|
+
codex_desktop_service_tier: CodexDesktopServiceTier;
|
|
11
13
|
default_fast_mode: true;
|
|
12
14
|
disabled_by: 'none' | 'no-fast' | 'service-tier-standard' | 'preference-standard';
|
|
13
15
|
explicit_fast: boolean;
|
|
@@ -23,6 +25,7 @@ export interface FastModePreference {
|
|
|
23
25
|
mode: FastModePreferenceMode;
|
|
24
26
|
fast_mode: boolean;
|
|
25
27
|
service_tier: AgentServiceTier;
|
|
28
|
+
codex_desktop_service_tier: CodexDesktopServiceTier;
|
|
26
29
|
source: string;
|
|
27
30
|
}
|
|
28
31
|
export declare function resolveFastModePolicy(input?: any): FastModePolicy;
|
|
@@ -65,4 +68,6 @@ export declare function writeFastModePropagationProof(root: string, input?: {
|
|
|
65
68
|
artifacts: string[];
|
|
66
69
|
blockers: string[];
|
|
67
70
|
}>;
|
|
71
|
+
export declare function normalizeServiceTier(value: unknown, fallback?: AgentServiceTier | null): AgentServiceTier | null;
|
|
72
|
+
export declare function codexDesktopServiceTier(tier: AgentServiceTier): CodexDesktopServiceTier;
|
|
68
73
|
//# sourceMappingURL=fast-mode-policy.d.ts.map
|
|
@@ -24,6 +24,7 @@ export function resolveFastModePolicy(input = {}) {
|
|
|
24
24
|
generated_at: nowIso(),
|
|
25
25
|
fast_mode: serviceTier === 'fast',
|
|
26
26
|
service_tier: serviceTier,
|
|
27
|
+
codex_desktop_service_tier: codexDesktopServiceTier(serviceTier),
|
|
27
28
|
default_fast_mode: true,
|
|
28
29
|
disabled_by: explicitNoFast ? 'no-fast' : explicitTier === 'standard' ? 'service-tier-standard' : preference?.mode === 'standard' ? 'preference-standard' : 'none',
|
|
29
30
|
explicit_fast: explicitFast,
|
|
@@ -69,6 +70,7 @@ export async function writeFastModePreference(root = process.cwd(), mode, source
|
|
|
69
70
|
mode: normalized,
|
|
70
71
|
fast_mode: normalized === 'fast',
|
|
71
72
|
service_tier: normalized,
|
|
73
|
+
codex_desktop_service_tier: codexDesktopServiceTier(normalized),
|
|
72
74
|
source
|
|
73
75
|
};
|
|
74
76
|
await writeJsonAtomic(file, preference);
|
|
@@ -84,6 +86,7 @@ export function fastModeEnv(policy) {
|
|
|
84
86
|
return {
|
|
85
87
|
SKS_FAST_MODE: policy.fast_mode ? '1' : '0',
|
|
86
88
|
SKS_SERVICE_TIER: policy.service_tier,
|
|
89
|
+
SKS_CODEX_DESKTOP_SERVICE_TIER: policy.codex_desktop_service_tier,
|
|
87
90
|
SKS_REASONING_PROFILE_SUFFIX: policy.fast_mode ? 'fast' : 'standard'
|
|
88
91
|
};
|
|
89
92
|
}
|
|
@@ -164,12 +167,19 @@ export async function writeFastModePropagationProof(root, input = { policy: reso
|
|
|
164
167
|
await writeJsonAtomic(path.join(root, 'fast-mode-propagation-proof.json'), report);
|
|
165
168
|
return report;
|
|
166
169
|
}
|
|
167
|
-
function normalizeServiceTier(value, fallback = 'fast') {
|
|
170
|
+
export function normalizeServiceTier(value, fallback = 'fast') {
|
|
168
171
|
const text = String(value || '').toLowerCase();
|
|
169
172
|
if (text === 'fast' || text === 'standard')
|
|
170
173
|
return text;
|
|
174
|
+
if (text === 'priority')
|
|
175
|
+
return 'fast';
|
|
176
|
+
if (text === 'default')
|
|
177
|
+
return 'standard';
|
|
171
178
|
return fallback;
|
|
172
179
|
}
|
|
180
|
+
export function codexDesktopServiceTier(tier) {
|
|
181
|
+
return tier === 'fast' ? 'priority' : 'default';
|
|
182
|
+
}
|
|
173
183
|
function normalizeFastModePreference(parsed, file) {
|
|
174
184
|
const mode = normalizeServiceTier(parsed?.mode ?? parsed?.service_tier, 'fast') || 'fast';
|
|
175
185
|
return {
|
|
@@ -178,6 +188,7 @@ function normalizeFastModePreference(parsed, file) {
|
|
|
178
188
|
mode,
|
|
179
189
|
fast_mode: mode === 'fast',
|
|
180
190
|
service_tier: mode,
|
|
191
|
+
codex_desktop_service_tier: codexDesktopServiceTier(mode),
|
|
181
192
|
source: typeof parsed?.source === 'string' ? parsed.source : 'unknown',
|
|
182
193
|
path: file
|
|
183
194
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type CodexSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
2
|
-
export type CodexServiceTier = 'fast' | 'standard'
|
|
2
|
+
export type CodexServiceTier = 'fast' | 'standard';
|
|
3
3
|
export type BuildCodexExecArgsOptions = {
|
|
4
4
|
json?: boolean;
|
|
5
5
|
outputSchema?: string | null;
|
|
@@ -34,9 +34,18 @@ export function buildCodexExecArgs(opts) {
|
|
|
34
34
|
args.push('--dangerously-bypass-approvals-and-sandbox');
|
|
35
35
|
else if (opts.sandbox)
|
|
36
36
|
args.push('--sandbox', opts.sandbox);
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
const serviceTier = normalizeCodexServiceTier(opts.serviceTier);
|
|
38
|
+
if (serviceTier)
|
|
39
|
+
args.push('-c', `service_tier=${serviceTier}`);
|
|
39
40
|
args.push(opts.prompt);
|
|
40
41
|
return args;
|
|
41
42
|
}
|
|
43
|
+
function normalizeCodexServiceTier(value) {
|
|
44
|
+
const text = String(value || '').toLowerCase();
|
|
45
|
+
if (text === 'fast' || text === 'priority')
|
|
46
|
+
return 'fast';
|
|
47
|
+
if (text === 'standard' || text === 'default')
|
|
48
|
+
return 'standard';
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
42
51
|
//# sourceMappingURL=codex-cli-syntax-builder.js.map
|
|
@@ -57,17 +57,17 @@ export async function fastModeCommand(args = []) {
|
|
|
57
57
|
else if (action === 'clear')
|
|
58
58
|
console.log(`Cleared: ${removed ? 'yes' : 'already default'}`);
|
|
59
59
|
else if (!preference)
|
|
60
|
-
console.log('Preference:
|
|
60
|
+
console.log('Preference: implicit fast');
|
|
61
61
|
console.log('Dollar: $Fast-On | $Fast-Off | $Fast-Mode');
|
|
62
62
|
return result;
|
|
63
63
|
}
|
|
64
64
|
function normalizeFastModeAction(value) {
|
|
65
65
|
const text = String(value || 'status').toLowerCase();
|
|
66
|
-
if (['on', 'enable', 'enabled', 'fast'].includes(text))
|
|
66
|
+
if (['on', 'enable', 'enabled', 'fast', 'priority'].includes(text))
|
|
67
67
|
return 'on';
|
|
68
|
-
if (['off', 'disable', 'disabled', 'standard', 'slow'].includes(text))
|
|
68
|
+
if (['off', 'disable', 'disabled', 'standard', 'slow', 'default'].includes(text))
|
|
69
69
|
return 'off';
|
|
70
|
-
if (['clear', '
|
|
70
|
+
if (['clear', 'reset'].includes(text))
|
|
71
71
|
return 'clear';
|
|
72
72
|
return 'status';
|
|
73
73
|
}
|
|
@@ -2,7 +2,7 @@ export declare function madHighCommand(args?: any, deps?: any): Promise<void | {
|
|
|
2
2
|
schema: string;
|
|
3
3
|
generated_at: string;
|
|
4
4
|
ok: boolean;
|
|
5
|
-
kind: "agent" | "team" | "mad";
|
|
5
|
+
kind: "agent" | "team" | "mad" | "naruto";
|
|
6
6
|
mission_id: string;
|
|
7
7
|
session_name: string;
|
|
8
8
|
root: string;
|
|
@@ -10,6 +10,13 @@ export declare function madHighCommand(args?: any, deps?: any): Promise<void | {
|
|
|
10
10
|
ledger_root: string;
|
|
11
11
|
layout_path: string;
|
|
12
12
|
layout_artifact: string;
|
|
13
|
+
main_pane_kind: "codex_interactive" | "status_shell";
|
|
14
|
+
codex_pane: {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
args: string[];
|
|
17
|
+
launch_env_keys: string[];
|
|
18
|
+
bin: string;
|
|
19
|
+
};
|
|
13
20
|
command: string[];
|
|
14
21
|
launch_command: string[];
|
|
15
22
|
launch_command_with_env: string;
|
|
@@ -17,6 +24,7 @@ export declare function madHighCommand(args?: any, deps?: any): Promise<void | {
|
|
|
17
24
|
background_command_with_env: string;
|
|
18
25
|
attach_command: string;
|
|
19
26
|
attach_command_with_env: string;
|
|
27
|
+
attach_requested: boolean;
|
|
20
28
|
zellij_socket_dir: string | null;
|
|
21
29
|
zellij_socket_dir_source: import("../zellij/zellij-command.js").ZellijSocketDirSource;
|
|
22
30
|
pane_proof_path: string;
|
|
@@ -32,6 +40,8 @@ export declare function madHighCommand(args?: any, deps?: any): Promise<void | {
|
|
|
32
40
|
main_pane: any;
|
|
33
41
|
lane_panes: any[];
|
|
34
42
|
expected_lane_count: number;
|
|
43
|
+
expected_main_command_includes: string | null;
|
|
44
|
+
main_command_ok: boolean;
|
|
35
45
|
lane_count_ok: boolean;
|
|
36
46
|
geometry_distinct: boolean | null;
|
|
37
47
|
panes: any[];
|
|
@@ -4,7 +4,7 @@ import { initProject } from '../init.js';
|
|
|
4
4
|
import { createMission, setCurrent } from '../mission.js';
|
|
5
5
|
import { enableMadHighProfile, madHighProfileName } from '../auto-review.js';
|
|
6
6
|
import { permissionGateSummary } from '../permission-gates.js';
|
|
7
|
-
import { launchMadZellijUi, sanitizeZellijSessionName } from '../zellij/zellij-launcher.js';
|
|
7
|
+
import { attachZellijSessionInteractive, launchMadZellijUi, sanitizeZellijSessionName } from '../zellij/zellij-launcher.js';
|
|
8
8
|
import { createMadSksAuthorizationManifest, validateMadSksAuthorizationManifest } from '../mad-sks/authorization-manifest.js';
|
|
9
9
|
import { createMadSksAuditLedger, madSksAuditAction, writeMadSksAuditLedger } from '../mad-sks/audit-ledger.js';
|
|
10
10
|
import { compareProtectedCoreSnapshots, evaluateMadSksWrite, resolveProtectedCore, snapshotProtectedCore } from '../mad-sks/immutable-harness-guard.js';
|
|
@@ -79,12 +79,48 @@ export async function madHighCommand(args = [], deps = {}) {
|
|
|
79
79
|
const launchOpts = codexLbImmediateLaunchOpts(cleanArgs, launchLb, { codexArgs: profile.launch_args, conciseBlockers: true, madSksEnv, launchEnv: madSksEnv });
|
|
80
80
|
const workspace = readOption(cleanArgs, '--workspace', readOption(cleanArgs, '--session', launchOpts.session || `sks-mad-${sanitizeZellijSessionName(process.cwd())}`));
|
|
81
81
|
const launch = await launchMadZellijUi([...cleanArgs, '--workspace', workspace], { ...launchOpts, missionId: madLaunch.mission_id, root: madLaunch.root, cwd: process.cwd(), ledgerRoot: path.join(madLaunch.dir, 'agents'), requireZellij: process.env.SKS_REQUIRE_ZELLIJ === '1' });
|
|
82
|
-
if (!launch.ok)
|
|
82
|
+
if (!launch.ok) {
|
|
83
83
|
console.log(`MAD Zellij action: ${formatMadZellijAction(launch)}`);
|
|
84
|
-
|
|
84
|
+
return launch;
|
|
85
|
+
}
|
|
86
|
+
// The launcher only creates a detached background session. In an interactive
|
|
87
|
+
// terminal, immediately attach so the session actually opens for the user
|
|
88
|
+
// instead of leaving them to copy/paste the attach command by hand.
|
|
89
|
+
if (shouldAutoAttachZellij(args)) {
|
|
90
|
+
console.log(`Opening Zellij session: ${launch.session_name} (detach with Ctrl+q, re-attach later with: ${launch.attach_command_with_env})`);
|
|
91
|
+
const attached = attachZellijSessionInteractive(launch.session_name, { cwd: process.cwd() });
|
|
92
|
+
if (!attached.ok) {
|
|
93
|
+
console.log(`Could not open the Zellij session automatically${attached.error ? ` (${attached.error})` : ''}.`);
|
|
94
|
+
if (launch.attach_command_with_env)
|
|
95
|
+
console.log(`Attach with: ${launch.attach_command_with_env}`);
|
|
96
|
+
}
|
|
97
|
+
return launch;
|
|
98
|
+
}
|
|
99
|
+
if (launch.attach_command_with_env)
|
|
85
100
|
console.log(`Attach with: ${launch.attach_command_with_env}`);
|
|
86
101
|
return launch;
|
|
87
102
|
}
|
|
103
|
+
// Decide whether to take over the current terminal with a foreground Zellij
|
|
104
|
+
// attach. We only do this for genuinely interactive launches; piped, JSON,
|
|
105
|
+
// non-TTY, or already-inside-Zellij invocations keep the previous behaviour of
|
|
106
|
+
// printing a manual "Attach with:" hint. Use --no-attach (or
|
|
107
|
+
// SKS_NO_ZELLIJ_ATTACH=1) to force the background-only behaviour, and --attach
|
|
108
|
+
// to force attaching even without a detected TTY.
|
|
109
|
+
function shouldAutoAttachZellij(args) {
|
|
110
|
+
const list = (args || []).map((arg) => String(arg));
|
|
111
|
+
if (list.includes('--no-attach'))
|
|
112
|
+
return false;
|
|
113
|
+
if (list.includes('--json'))
|
|
114
|
+
return false;
|
|
115
|
+
if (process.env.SKS_NO_ZELLIJ_ATTACH === '1')
|
|
116
|
+
return false;
|
|
117
|
+
// Nested attach is rejected by Zellij when already inside a session.
|
|
118
|
+
if (process.env.ZELLIJ)
|
|
119
|
+
return false;
|
|
120
|
+
if (list.includes('--attach'))
|
|
121
|
+
return true;
|
|
122
|
+
return Boolean(process.stdout.isTTY && process.stdin.isTTY);
|
|
123
|
+
}
|
|
88
124
|
function formatMadZellijAction(launch) {
|
|
89
125
|
const blockers = launch.blockers?.join(', ') || launch.warnings?.join(', ') || 'check Zellij installation';
|
|
90
126
|
const details = [
|
|
@@ -189,6 +225,8 @@ function madLaunchOnlyFlags() {
|
|
|
189
225
|
'--MAD',
|
|
190
226
|
'--mad-sks',
|
|
191
227
|
'--high',
|
|
228
|
+
'--attach',
|
|
229
|
+
'--no-attach',
|
|
192
230
|
'--no-auto-install-zellij',
|
|
193
231
|
'--allow-system',
|
|
194
232
|
'--allow-db-write',
|
|
@@ -4,6 +4,7 @@ import { readJson, sksRoot } from '../fsx.js';
|
|
|
4
4
|
import { runNativeAgentOrchestrator } from '../agents/agent-orchestrator.js';
|
|
5
5
|
import { buildNarutoCloneRoster, systemSafeNarutoConcurrency } from '../agents/agent-roster.js';
|
|
6
6
|
import { DEFAULT_NARUTO_CLONES, MAX_NARUTO_AGENT_COUNT } from '../agents/agent-schema.js';
|
|
7
|
+
import { attachZellijSessionInteractive, launchZellijLayout } from '../zellij/zellij-launcher.js';
|
|
7
8
|
const NARUTO_RESULT_SCHEMA = 'sks.naruto-command-result.v1';
|
|
8
9
|
const NARUTO_ROUTE = '$Naruto';
|
|
9
10
|
// $Naruto — Shadow Clone Swarm (影分身 / Kage Bunshin no Jutsu).
|
|
@@ -21,6 +22,7 @@ export async function narutoCommand(commandOrArgs = 'naruto', maybeArgs = []) {
|
|
|
21
22
|
return narutoRun(parsed);
|
|
22
23
|
}
|
|
23
24
|
async function narutoRun(parsed) {
|
|
25
|
+
const root = await sksRoot();
|
|
24
26
|
const roster = buildNarutoCloneRoster({
|
|
25
27
|
clones: parsed.clones,
|
|
26
28
|
prompt: parsed.prompt,
|
|
@@ -70,14 +72,35 @@ async function narutoRun(parsed) {
|
|
|
70
72
|
concurrency_capped: clones > (result.target_active_slots ?? activeSlots),
|
|
71
73
|
system: { cores: safe.cores, free_gb: safe.free_gb, safe_concurrency: safe.cap, heavy_backend: safe.heavy },
|
|
72
74
|
proof: result.proof?.status || 'missing',
|
|
73
|
-
run: result
|
|
75
|
+
run: result,
|
|
76
|
+
zellij: null
|
|
74
77
|
};
|
|
78
|
+
if (!parsed.json && !parsed.mock && !parsed.noOpenZellij) {
|
|
79
|
+
const ledgerRoot = result.ledger_root
|
|
80
|
+
? path.join(root, result.ledger_root)
|
|
81
|
+
: path.join(root, '.sneakoscope', 'missions', result.mission_id, 'agents');
|
|
82
|
+
summary.zellij = await launchZellijLayout({
|
|
83
|
+
root,
|
|
84
|
+
missionId: result.mission_id,
|
|
85
|
+
ledgerRoot,
|
|
86
|
+
kind: 'naruto',
|
|
87
|
+
slotCount: summary.target_active_slots,
|
|
88
|
+
dryRun: false,
|
|
89
|
+
attach: false
|
|
90
|
+
});
|
|
91
|
+
if (summary.zellij?.ok && summary.zellij.capability?.status === 'ok' && parsed.attach)
|
|
92
|
+
attachZellijSessionInteractive(summary.zellij.session_name, { cwd: process.cwd() });
|
|
93
|
+
}
|
|
75
94
|
return emit(parsed, summary, () => {
|
|
76
95
|
console.log('🍥 Shadow Clone Jutsu — Kage Bunshin no Jutsu');
|
|
77
96
|
console.log('Mission: ' + result.mission_id);
|
|
78
97
|
console.log('Clones: ' + summary.clones + ' / max ' + MAX_NARUTO_AGENT_COUNT + ', running ' + summary.target_active_slots + ' at a time' + (summary.concurrency_capped ? ` (throttled to host capacity: ${safe.cores} cores, ${safe.free_gb} GB free)` : ''));
|
|
79
98
|
console.log('Backend: ' + result.backend);
|
|
80
99
|
console.log('Proof: ' + summary.proof);
|
|
100
|
+
if (summary.zellij?.ok && summary.zellij.capability?.status === 'ok')
|
|
101
|
+
console.log('Zellij: prepared ' + summary.target_active_slots + ' native session lane(s) in ' + summary.zellij.session_name);
|
|
102
|
+
else if (summary.zellij?.ok)
|
|
103
|
+
console.log('Zellij: optional live panes unavailable (' + ((summary.zellij.warnings || []).join('; ') || summary.zellij.capability?.status || 'unknown') + ')');
|
|
81
104
|
});
|
|
82
105
|
}
|
|
83
106
|
async function narutoStatus(parsed) {
|
|
@@ -141,9 +164,11 @@ function parseNarutoArgs(args = []) {
|
|
|
141
164
|
const writeModeRaw = String(readOption(args, '--write-mode', hasFlag(args, '--parallel-write') ? 'parallel' : '') || '');
|
|
142
165
|
const writeMode = (['proof-safe', 'parallel', 'serial', 'off'].includes(writeModeRaw) ? writeModeRaw : null);
|
|
143
166
|
const missionId = String(readOption(args, '--mission', readOption(args, '--mission-id', 'latest')));
|
|
167
|
+
const noOpenZellij = hasFlag(args, '--no-open-zellij') || hasFlag(args, '--no-zellij');
|
|
168
|
+
const attach = hasFlag(args, '--attach');
|
|
144
169
|
const valueFlags = new Set(['--clones', '--agents', '--work-items', '--backend', '--write-mode', '--mission', '--mission-id']);
|
|
145
170
|
const prompt = positionalArgs(rest, valueFlags).join(' ').trim() || 'Naruto shadow clone swarm run';
|
|
146
|
-
return { action, prompt, clones, workItems, backend, mock, real, readonly, writeMode, json, missionId };
|
|
171
|
+
return { action, prompt, clones, workItems, backend, mock, real, readonly, writeMode, json, missionId, noOpenZellij, attach };
|
|
147
172
|
}
|
|
148
173
|
function clampClones(value) {
|
|
149
174
|
if (!Number.isFinite(value) || value < 1)
|
|
@@ -53,7 +53,8 @@ async function researchPrepare(args) {
|
|
|
53
53
|
task: prompt,
|
|
54
54
|
required_skills: route.requiredSkills,
|
|
55
55
|
context7_required: context7Required,
|
|
56
|
-
subagents_required:
|
|
56
|
+
subagents_required: false,
|
|
57
|
+
native_sessions_required: routeRequiresSubagents(route, prompt),
|
|
57
58
|
reflection_required: reflectionRequiredForRoute(route),
|
|
58
59
|
original_stop_gate: route.stopGate,
|
|
59
60
|
stop_gate: route.stopGate,
|
|
@@ -72,8 +73,10 @@ async function researchPrepare(args) {
|
|
|
72
73
|
implementation_allowed: false,
|
|
73
74
|
context7_required: context7Required,
|
|
74
75
|
context7_verified: false,
|
|
75
|
-
subagents_required:
|
|
76
|
-
subagents_verified:
|
|
76
|
+
subagents_required: false,
|
|
77
|
+
subagents_verified: true,
|
|
78
|
+
native_sessions_required: routeRequiresSubagents(route, prompt),
|
|
79
|
+
native_sessions_verified: false,
|
|
77
80
|
reflection_required: reflectionRequiredForRoute(route),
|
|
78
81
|
visible_progress_required: true,
|
|
79
82
|
context_tracking: 'triwiki',
|
|
@@ -364,11 +364,11 @@ function fastModeActionFromPrompt(prompt = '') {
|
|
|
364
364
|
.trimStart()
|
|
365
365
|
.toLowerCase();
|
|
366
366
|
const token = afterRoute.match(/^[^\s?!.,;:()"'`]+/)?.[0] || '';
|
|
367
|
-
if (['off', 'disable', 'disabled', 'standard', 'slow', '끄기', '꺼', '꺼줘'].includes(token) || token.startsWith('끄') || token.startsWith('꺼'))
|
|
367
|
+
if (['off', 'disable', 'disabled', 'standard', 'default', 'slow', '끄기', '꺼', '꺼줘'].includes(token) || token.startsWith('끄') || token.startsWith('꺼'))
|
|
368
368
|
return 'off';
|
|
369
|
-
if (['on', 'enable', 'enabled', 'fast', '켜기', '켜', '켜줘'].includes(token) || token.startsWith('켜'))
|
|
369
|
+
if (['on', 'enable', 'enabled', 'fast', 'priority', '켜기', '켜', '켜줘'].includes(token) || token.startsWith('켜'))
|
|
370
370
|
return 'on';
|
|
371
|
-
if (['clear', 'reset', '
|
|
371
|
+
if (['clear', 'reset', '초기화', '기본'].includes(token) || token.startsWith('초기화'))
|
|
372
372
|
return 'clear';
|
|
373
373
|
return 'status';
|
|
374
374
|
}
|
|
@@ -20,6 +20,7 @@ export declare function buildTeamPlan(id: any, prompt: any, opts?: any): {
|
|
|
20
20
|
prompt: any;
|
|
21
21
|
agent_session_count: number;
|
|
22
22
|
default_agent_session_count: number;
|
|
23
|
+
target_active_slots: any;
|
|
23
24
|
role_counts: Record<string, number>;
|
|
24
25
|
session_policy: string;
|
|
25
26
|
review_policy: {
|
|
@@ -119,7 +120,7 @@ export declare function buildTeamPlan(id: any, prompt: any, opts?: any): {
|
|
|
119
120
|
goal: string;
|
|
120
121
|
agents: string[];
|
|
121
122
|
output: string;
|
|
122
|
-
|
|
123
|
+
max_parallel_native_sessions?: never;
|
|
123
124
|
write_policy?: never;
|
|
124
125
|
commands?: never;
|
|
125
126
|
min_reviewer_lanes?: never;
|
|
@@ -127,7 +128,7 @@ export declare function buildTeamPlan(id: any, prompt: any, opts?: any): {
|
|
|
127
128
|
id: string;
|
|
128
129
|
goal: string;
|
|
129
130
|
agents: any[];
|
|
130
|
-
|
|
131
|
+
max_parallel_native_sessions: any;
|
|
131
132
|
write_policy: string;
|
|
132
133
|
output: string;
|
|
133
134
|
commands?: never;
|
|
@@ -138,14 +139,14 @@ export declare function buildTeamPlan(id: any, prompt: any, opts?: any): {
|
|
|
138
139
|
agents: string[];
|
|
139
140
|
commands: string[];
|
|
140
141
|
output: string;
|
|
141
|
-
|
|
142
|
+
max_parallel_native_sessions?: never;
|
|
142
143
|
write_policy?: never;
|
|
143
144
|
min_reviewer_lanes?: never;
|
|
144
145
|
} | {
|
|
145
146
|
id: string;
|
|
146
147
|
goal: string;
|
|
147
148
|
agents: any[];
|
|
148
|
-
|
|
149
|
+
max_parallel_native_sessions: any;
|
|
149
150
|
write_policy: string;
|
|
150
151
|
output?: never;
|
|
151
152
|
commands?: never;
|
|
@@ -155,7 +156,7 @@ export declare function buildTeamPlan(id: any, prompt: any, opts?: any): {
|
|
|
155
156
|
goal: string;
|
|
156
157
|
agents: string[];
|
|
157
158
|
output?: never;
|
|
158
|
-
|
|
159
|
+
max_parallel_native_sessions?: never;
|
|
159
160
|
write_policy?: never;
|
|
160
161
|
commands?: never;
|
|
161
162
|
min_reviewer_lanes?: never;
|
|
@@ -165,7 +166,7 @@ export declare function buildTeamPlan(id: any, prompt: any, opts?: any): {
|
|
|
165
166
|
agents: any[];
|
|
166
167
|
min_reviewer_lanes: number;
|
|
167
168
|
output?: never;
|
|
168
|
-
|
|
169
|
+
max_parallel_native_sessions?: never;
|
|
169
170
|
write_policy?: never;
|
|
170
171
|
commands?: never;
|
|
171
172
|
})[];
|