sneakoscope 1.20.4 → 1.20.5

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 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.20.5** makes `sks --mad` actually open the Zellij session. 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.
@@ -76,7 +76,7 @@ dependencies = [
76
76
 
77
77
  [[package]]
78
78
  name = "sks-core"
79
- version = "1.20.4"
79
+ version = "1.20.5"
80
80
  dependencies = [
81
81
  "serde_json",
82
82
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sks-core"
3
- version = "1.20.4"
3
+ version = "1.20.5"
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 1.20.4"),
7
+ Some("--version") => println!("sks-rs 1.20.5"),
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.20.4",
5
- "source_digest": "491c4c03f8a989f3ea78aa47b16a937edbd54e653b71ef79b5ce767916df7395",
4
+ "package_version": "1.20.5",
5
+ "source_digest": "4ba5f14a828460ed0146c7109f59e53e148d6b1ffb42e8c01b00e64086da827e",
6
6
  "source_file_count": 1750,
7
- "built_at_source_time": 1780281006481
7
+ "built_at_source_time": 1780287464818
8
8
  }
package/dist/bin/sks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const FAST_PACKAGE_VERSION = '1.20.4';
2
+ const FAST_PACKAGE_VERSION = '1.20.5';
3
3
  const args = process.argv.slice(2);
4
4
  try {
5
5
  if (args[0] === '--agent' && args[1] === 'worker') {
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schema": "sks.dist-build.v2",
3
- "version": "1.20.4",
4
- "package_version": "1.20.4",
3
+ "version": "1.20.5",
4
+ "package_version": "1.20.5",
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": "491c4c03f8a989f3ea78aa47b16a937edbd54e653b71ef79b5ce767916df7395",
10
+ "source_digest": "4ba5f14a828460ed0146c7109f59e53e148d6b1ffb42e8c01b00e64086da827e",
11
11
  "source_file_count": 1750,
12
12
  "source_files_hash": "de93b15a72352d00481b958333ed964bf083563809e3beddfe4e64046720df75",
13
13
  "source_list_hash": "de93b15a72352d00481b958333ed964bf083563809e3beddfe4e64046720df75",
@@ -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
- else if (launch.attach_command_with_env)
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',
@@ -1,4 +1,4 @@
1
- export declare const PACKAGE_VERSION = "1.20.4";
1
+ export declare const PACKAGE_VERSION = "1.20.5";
2
2
  export declare const DEFAULT_PROCESS_TAIL_BYTES: number;
3
3
  export declare const DEFAULT_PROCESS_TIMEOUT_MS: number;
4
4
  export interface RunProcessOptions {
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 = '1.20.4';
8
+ export const PACKAGE_VERSION = '1.20.5';
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() {
@@ -1,2 +1,2 @@
1
- export declare const PACKAGE_VERSION = "1.20.4";
1
+ export declare const PACKAGE_VERSION = "1.20.5";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,2 +1,2 @@
1
- export const PACKAGE_VERSION = '1.20.4';
1
+ export const PACKAGE_VERSION = '1.20.5';
2
2
  //# sourceMappingURL=version.js.map
@@ -165,5 +165,25 @@ export declare function launchTeamZellijView(opts?: ZellijLaunchOptions): Promis
165
165
  blockers: any[];
166
166
  warnings: string[];
167
167
  }>;
168
+ export interface ZellijAttachResult {
169
+ ok: boolean;
170
+ status: number | null;
171
+ signal: NodeJS.Signals | null;
172
+ error?: string;
173
+ }
174
+ /**
175
+ * Attach the current terminal to an existing Zellij session in the foreground.
176
+ *
177
+ * `launchZellijLayout` only ever *creates* a detached background session, which
178
+ * is correct for proof/automation but means an interactive launch (e.g.
179
+ * `sks --mad`) never actually opens anything. This helper performs the
180
+ * follow-up foreground attach, inheriting stdio so the session takes over the
181
+ * user's terminal until they detach. It is a no-op-style failure (never throws)
182
+ * when Zellij is missing or attach fails, so callers can fall back to printing a
183
+ * manual attach hint.
184
+ */
185
+ export declare function attachZellijSessionInteractive(sessionName: string, opts?: {
186
+ cwd?: string;
187
+ }): ZellijAttachResult;
168
188
  export declare function sanitizeZellijSessionName(value: unknown): string;
169
189
  //# sourceMappingURL=zellij-launcher.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import path from 'node:path';
2
+ import { spawnSync } from 'node:child_process';
2
3
  import { appendJsonl, nowIso, sha256, writeJsonAtomic } from '../fsx.js';
3
4
  import { checkZellijCapability } from './zellij-capability.js';
4
5
  import { formatZellijCommand, resolveZellijProcessEnvMeta, runZellij } from './zellij-command.js';
@@ -116,6 +117,38 @@ export async function launchTeamZellijView(opts = {}) {
116
117
  slotCount: opts.slotCount || 5
117
118
  });
118
119
  }
120
+ /**
121
+ * Attach the current terminal to an existing Zellij session in the foreground.
122
+ *
123
+ * `launchZellijLayout` only ever *creates* a detached background session, which
124
+ * is correct for proof/automation but means an interactive launch (e.g.
125
+ * `sks --mad`) never actually opens anything. This helper performs the
126
+ * follow-up foreground attach, inheriting stdio so the session takes over the
127
+ * user's terminal until they detach. It is a no-op-style failure (never throws)
128
+ * when Zellij is missing or attach fails, so callers can fall back to printing a
129
+ * manual attach hint.
130
+ */
131
+ export function attachZellijSessionInteractive(sessionName, opts = {}) {
132
+ if (!sessionName)
133
+ return { ok: false, status: null, signal: null, error: 'missing_session_name' };
134
+ const meta = resolveZellijProcessEnvMeta();
135
+ const env = { ...process.env };
136
+ if (meta.zellij_socket_dir && !env.ZELLIJ_SOCKET_DIR)
137
+ env.ZELLIJ_SOCKET_DIR = meta.zellij_socket_dir;
138
+ try {
139
+ const result = spawnSync('zellij', ['attach', sessionName], {
140
+ cwd: opts.cwd || process.cwd(),
141
+ env,
142
+ stdio: 'inherit'
143
+ });
144
+ if (result.error)
145
+ return { ok: false, status: null, signal: null, error: result.error.message };
146
+ return { ok: result.status === 0, status: result.status ?? null, signal: result.signal ?? null };
147
+ }
148
+ catch (err) {
149
+ return { ok: false, status: null, signal: null, error: err?.message || String(err) };
150
+ }
151
+ }
119
152
  export function sanitizeZellijSessionName(value) {
120
153
  const cleaned = String(value || 'sks-session').replace(/[^A-Za-z0-9_.:-]+/g, '-').replace(/^-+|-+$/g, '');
121
154
  if (!cleaned)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sneakoscope",
3
3
  "displayName": "ㅅㅋㅅ",
4
- "version": "1.20.4",
4
+ "version": "1.20.5",
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",