sneakoscope 1.20.2 → 1.20.3

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,7 +16,9 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
16
16
 
17
17
  ## Current Release
18
18
 
19
- SKS **1.20.2** is a stabilization patch that closes the enforcement/integration/execution layers on top of the 1.20.1 infrastructure: a **Mutation Guard** routes genuinely-risky global/config/permission/package mutations through the Requested-Scope Contract + Mutation Ledger (`safety:mutation-callsite-coverage` fails any unguarded, unallowlisted risky call site); `release:check:dynamic:execute` turns the change-aware planner into a real **caching gate runner** (schema v2, real/heavy gates deferred to `release:real-check`, dynamic-only cannot authorize publish); the **Core Skill** deployed snapshot is now read by the route runtime and recorded in `agent-proof-evidence.json` (`selected_core_skill`), with promotions written to the mutation ledger; and `sks doctor` exposes an explicit **`zellij_readiness`** block (`zellij:doctor-readiness`). See `docs/dynamic-release-pipeline.md`.
19
+ SKS **1.20.3** is a targeted patch for `sks --mad` / codex-lb sessions on macOS and project-local Fast mode control. SKS now 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.
20
+
21
+ It carries forward the **1.20.2** stabilization layer: **Mutation Guard** routes genuinely-risky global/config/permission/package mutations through the Requested-Scope Contract + Mutation Ledger (`safety:mutation-callsite-coverage` fails any unguarded, unallowlisted risky call site); `release:check:dynamic:execute` is the real **caching gate runner** (schema v2, real/heavy gates deferred to `release:real-check`, dynamic-only cannot authorize publish); the **Core Skill** deployed snapshot is read by the route runtime and recorded in `agent-proof-evidence.json` (`selected_core_skill`), with promotions written to the mutation ledger; and `sks doctor` exposes an explicit **`zellij_readiness`** block (`zellij:doctor-readiness`). See `docs/dynamic-release-pipeline.md`.
20
22
 
21
23
  SKS **1.20.1** introduces the **SKS Core Skill Engine** — a SkillOpt-style self-evolving skill layer — while locking the harness into a deploy-ready stable build. Skills are the agent's *external, versioned state* (Core Skill Cards): an optimizer proposes **bounded** add/delete/replace edits to a single skill document under a **textual edit budget**, edits are accepted **only on strict held-out improvement**, rejected edits are buffered so they are never retried, and the **deployed snapshot is immutable**. Critically, the optimizer runs only in training/evaluation — the **deployment/inference path reads the deployed snapshot and never makes an extra model call**, and a skill patch can never mutate code/config/package/global files.
22
24
 
@@ -140,7 +142,7 @@ The cleanup contract is policy-backed in `.sneakoscope/policy.json`, but the def
140
142
  - Agent patch queue: [docs/agent-patch-queue.md](docs/agent-patch-queue.md)
141
143
  - Native CLI Session Swarm: [docs/native-cli-session-swarm.md](docs/native-cli-session-swarm.md)
142
144
  - No-subagent scaling: [docs/no-subagent-scaling.md](docs/no-subagent-scaling.md)
143
- - Fast mode default: [docs/fast-mode-default.md](docs/fast-mode-default.md)
145
+ - Fast mode default and `$Fast-On`/`$Fast-Off` toggles: [docs/fast-mode-default.md](docs/fast-mode-default.md)
144
146
  - Migration 1.18.7 to 1.18.8: [docs/migration-1.18.7-to-1.18.8.md](docs/migration-1.18.7-to-1.18.8.md)
145
147
  - Codex official Goal mode: [docs/codex-official-goal-mode.md](docs/codex-official-goal-mode.md)
146
148
  - Release parallel full coverage: [docs/release-parallel-full-coverage.md](docs/release-parallel-full-coverage.md)
@@ -731,7 +733,7 @@ npm run release:check
731
733
  npm run publish:dry
732
734
  ```
733
735
 
734
- `release:check` runs the 1.19.0 Zellij dependency-repair closure DAG, writes a source digest stamp under `.sneakoscope/reports/`, then refreshes release readiness so publish commands can verify the same stamp. The DAG preserves the 1.18 baseline gates and adds patch swarm runtime truth, transaction journaling, serial conflict rebase, strict strategy-to-patch proof, rollback command proof, Native CLI Session Swarm 5/10/20-process proof, Real Worker Backend Router proof, Codex child overlap proof, model-authored patch-envelope separation, Zellij layout/pane/screen proof, no-subagent-scaling proof, Fast mode default/worker/Codex/MAD propagation proof, Appshots attachment provenance, MCP runtime overlap evidence, Codex 0.134/0.135 runner truth, task graph expansion, schema-bound follow-up work, actual Agent/Team/Research/QA route blackboxes, scheduler proof hardening, Source Intelligence propagation, and Goal mode propagation checks. Broader live gates remain explicit scripts such as `release:real-check`; real Codex patch smoke, real Codex parallel worker proof, and real Zellij proof are optional unless their `SKS_REQUIRE_REAL_*` or `SKS_REQUIRE_ZELLIJ=1` environment variables are set. Generate the human-readable registry with `sks features inventory --write-docs`. Plain `npm publish` uses the `latest` dist-tag. npm's `prepublishOnly` verifies the fresh release stamp instead of rerunning the full gate, and `prepack` only rebuilds `dist`; publish no longer repeats the expensive release suite during packaging. `npm run publish:dry` remains the explicit dry-run helper.
736
+ `release:check` runs the current 1.20.x release-closure DAG, writes a source digest stamp under `.sneakoscope/reports/`, then refreshes release readiness so publish commands can verify the same stamp. The DAG preserves the 1.18 baseline gates and adds patch swarm runtime truth, transaction journaling, serial conflict rebase, strict strategy-to-patch proof, rollback command proof, Native CLI Session Swarm 5/10/20-process proof, Real Worker Backend Router proof, Codex child overlap proof, model-authored patch-envelope separation, Zellij layout/pane/screen/socket-dir proof, no-subagent-scaling proof, Fast mode default/worker/Codex/MAD propagation proof, Appshots attachment provenance, MCP runtime overlap evidence, Codex 0.134/0.135 runner truth, task graph expansion, schema-bound follow-up work, actual Agent/Team/Research/QA route blackboxes, scheduler proof hardening, Source Intelligence propagation, and Goal mode propagation checks. Broader live gates remain explicit scripts such as `release:real-check`; real Codex patch smoke, real Codex parallel worker proof, and real Zellij proof are optional unless their `SKS_REQUIRE_REAL_*` or `SKS_REQUIRE_ZELLIJ=1` environment variables are set. Generate the human-readable registry with `sks features inventory --write-docs`. Plain `npm publish` uses the `latest` dist-tag. npm's `prepublishOnly` verifies the fresh release stamp instead of rerunning the full gate, and `prepack` only rebuilds `dist`; publish no longer repeats the expensive release suite during packaging. `npm run publish:dry` remains the explicit dry-run helper.
735
737
 
736
738
  Version bumps are manual. Run `sks versioning bump` only when preparing release metadata; SKS will not create `.git/hooks/pre-commit` or auto-bump during ordinary commits.
737
739
 
@@ -76,7 +76,7 @@ dependencies = [
76
76
 
77
77
  [[package]]
78
78
  name = "sks-core"
79
- version = "1.20.2"
79
+ version = "1.20.3"
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.2"
3
+ version = "1.20.3"
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.2"),
7
+ Some("--version") => println!("sks-rs 1.20.3"),
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.2",
5
- "source_digest": "d1ccddca4a2c7be54d3129554ea90f8d07efb093592c1e269399fa0e5b92d3ba",
6
- "source_file_count": 1740,
7
- "built_at_source_time": 1780235613612
4
+ "package_version": "1.20.3",
5
+ "source_digest": "c76562a39aaa8ecf01128ce5cda509ad6f8883d1f8c6203c73ddad1d243e54e5",
6
+ "source_file_count": 1743,
7
+ "built_at_source_time": 1780267464746
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.2';
2
+ const FAST_PACKAGE_VERSION = '1.20.3';
3
3
  const args = process.argv.slice(2);
4
4
  try {
5
5
  if (args[0] === '--agent' && args[1] === 'worker') {
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "schema": "sks.dist-build.v2",
3
- "version": "1.20.2",
4
- "package_version": "1.20.2",
3
+ "version": "1.20.3",
4
+ "package_version": "1.20.3",
5
5
  "typescript": true,
6
6
  "mjs_runtime_files": 0,
7
- "compiled_file_count": 1016,
8
- "compiled_js_count": 508,
9
- "compiled_dts_count": 508,
10
- "source_digest": "d1ccddca4a2c7be54d3129554ea90f8d07efb093592c1e269399fa0e5b92d3ba",
11
- "source_file_count": 1740,
12
- "source_files_hash": "7484278e30e61755c2158548e697943af09e5a59de7c6b60018a0ac57848c6ec",
13
- "source_list_hash": "7484278e30e61755c2158548e697943af09e5a59de7c6b60018a0ac57848c6ec",
7
+ "compiled_file_count": 1018,
8
+ "compiled_js_count": 509,
9
+ "compiled_dts_count": 509,
10
+ "source_digest": "c76562a39aaa8ecf01128ce5cda509ad6f8883d1f8c6203c73ddad1d243e54e5",
11
+ "source_file_count": 1743,
12
+ "source_files_hash": "b1db64d16ef4e7f980de40d7c8c78b3280d95e78c5583092368dd283aeb367af",
13
+ "source_list_hash": "b1db64d16ef4e7f980de40d7c8c78b3280d95e78c5583092368dd283aeb367af",
14
14
  "src_mjs_runtime_files": 0,
15
15
  "dist_stamp_schema": "sks.dist-build-stamp.v1",
16
16
  "files": [
@@ -442,6 +442,8 @@
442
442
  "core/commands/dfix-command.js",
443
443
  "core/commands/eval-command.d.ts",
444
444
  "core/commands/eval-command.js",
445
+ "core/commands/fast-mode-command.d.ts",
446
+ "core/commands/fast-mode-command.js",
445
447
  "core/commands/gc-command.d.ts",
446
448
  "core/commands/gc-command.js",
447
449
  "core/commands/git-command.d.ts",
@@ -58,6 +58,7 @@ export declare const COMMANDS: {
58
58
  'dollar-commands': CommandEntry;
59
59
  dollars: CommandEntry;
60
60
  $: CommandEntry;
61
+ 'fast-mode': CommandEntry;
61
62
  commit: CommandEntry;
62
63
  'commit-and-push': CommandEntry;
63
64
  dfix: CommandEntry;
@@ -146,6 +147,7 @@ export declare const TYPED_COMMANDS: {
146
147
  'dollar-commands': CommandEntry;
147
148
  dollars: CommandEntry;
148
149
  $: CommandEntry;
150
+ 'fast-mode': CommandEntry;
149
151
  commit: CommandEntry;
150
152
  'commit-and-push': CommandEntry;
151
153
  dfix: CommandEntry;
@@ -111,6 +111,7 @@ export const COMMANDS = {
111
111
  'dollar-commands': entry('stable', 'List Codex App dollar commands', 'dist/core/commands/basic-cli.js', basicArgs('dollarCommandsCommand')),
112
112
  dollars: entry('stable', 'Alias for dollar-commands', 'dist/core/commands/basic-cli.js', basicArgs('dollarCommandsCommand')),
113
113
  '$': entry('stable', 'Alias for dollar-commands', 'dist/core/commands/basic-cli.js', basicArgs('dollarCommandsCommand')),
114
+ 'fast-mode': entry('stable', 'Toggle SKS Fast mode default for dollar-command routes', 'dist/core/commands/fast-mode-command.js', argsCommand(() => import('../core/commands/fast-mode-command.js'), 'fastModeCommand', 'dist/core/commands/fast-mode-command.js')),
114
115
  commit: entry('stable', 'Create a simple git commit', 'dist/commands/commit.js', directCommand(() => import('../commands/commit.js'), 'dist/commands/commit.js')),
115
116
  'commit-and-push': entry('stable', 'Create a simple git commit and push', 'dist/commands/commit-and-push.js', directCommand(() => import('../commands/commit-and-push.js'), 'dist/commands/commit-and-push.js')),
116
117
  dfix: entry('stable', 'Run DFix diagnose/plan/patch/verify loop', 'dist/core/commands/dfix-command.js', commandArgsCommand(() => import('../core/commands/dfix-command.js'), 'dfixCommand', 'dist/core/commands/dfix-command.js')),
@@ -12,8 +12,13 @@ export declare function run(_command: any, args?: any): Promise<void | {
12
12
  layout_artifact: string;
13
13
  command: string[];
14
14
  launch_command: string[];
15
+ launch_command_with_env: string;
15
16
  background_command: string[];
17
+ background_command_with_env: string;
16
18
  attach_command: string;
19
+ attach_command_with_env: string;
20
+ zellij_socket_dir: string | null;
21
+ zellij_socket_dir_source: import("../core/zellij/zellij-command.js").ZellijSocketDirSource;
17
22
  pane_proof_path: string;
18
23
  pane_proof: {
19
24
  schema: string;
@@ -51,7 +51,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
51
51
  const route = opts.route || '$Agent';
52
52
  const routeCommand = String(opts.routeCommand || defaultRouteCommand(route));
53
53
  const routeBlackboxKind = String(opts.routeBlackboxKind || defaultRouteBlackboxKind(route));
54
- const fastModePolicy = resolveFastModePolicy(opts);
54
+ const fastModePolicy = resolveFastModePolicy({ ...opts, root });
55
55
  const backend = normalizeAgentBackend(opts.backend || (opts.mock ? 'fake' : 'codex-exec'));
56
56
  const maxAgentCount = Number.isFinite(Number(opts.maxAgentCount)) && Number(opts.maxAgentCount) >= 1 ? Math.floor(Number(opts.maxAgentCount)) : MAX_AGENT_COUNT;
57
57
  const realZellij = backend === 'zellij' && opts.real === true;
@@ -1,18 +1,45 @@
1
1
  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
+ export declare const FAST_MODE_PREFERENCE_SCHEMA = "sks.fast-mode-preference.v1";
3
4
  export type AgentServiceTier = 'fast' | 'standard';
5
+ export type FastModePreferenceMode = AgentServiceTier;
4
6
  export interface FastModePolicy {
5
7
  schema: typeof FAST_MODE_POLICY_SCHEMA;
6
8
  generated_at: string;
7
9
  fast_mode: boolean;
8
10
  service_tier: AgentServiceTier;
9
11
  default_fast_mode: true;
10
- disabled_by: 'none' | 'no-fast' | 'service-tier-standard';
12
+ disabled_by: 'none' | 'no-fast' | 'service-tier-standard' | 'preference-standard';
11
13
  explicit_fast: boolean;
12
14
  explicit_no_fast: boolean;
13
15
  explicit_service_tier: AgentServiceTier | null;
16
+ preference_mode: FastModePreferenceMode | null;
17
+ preference_path: string | null;
18
+ preference_source: 'project-state' | null;
19
+ }
20
+ export interface FastModePreference {
21
+ schema: typeof FAST_MODE_PREFERENCE_SCHEMA;
22
+ updated_at: string;
23
+ mode: FastModePreferenceMode;
24
+ fast_mode: boolean;
25
+ service_tier: AgentServiceTier;
26
+ source: string;
14
27
  }
15
28
  export declare function resolveFastModePolicy(input?: any): FastModePolicy;
29
+ export declare function fastModePreferencePath(root?: string): string;
30
+ export declare function readFastModePreferenceSync(root?: string | null): (FastModePreference & {
31
+ path: string;
32
+ }) | null;
33
+ export declare function readFastModePreference(root?: string): Promise<(FastModePreference & {
34
+ path: string;
35
+ }) | null>;
36
+ export declare function writeFastModePreference(root: string | undefined, mode: FastModePreferenceMode, source?: string): Promise<FastModePreference & {
37
+ path: string;
38
+ }>;
39
+ export declare function clearFastModePreference(root?: string): Promise<{
40
+ path: string;
41
+ removed: boolean;
42
+ }>;
16
43
  export declare function fastModeEnv(policy: FastModePolicy): NodeJS.ProcessEnv;
17
44
  export declare function applyFastModeToRoster<T extends Record<string, any>>(roster: T, policy: FastModePolicy): T;
18
45
  export declare function writeFastModePropagationProof(root: string, input?: {
@@ -1,29 +1,85 @@
1
+ import fsSync from 'node:fs';
1
2
  import fs from 'node:fs/promises';
2
3
  import path from 'node:path';
3
4
  import { nowIso, readJson, writeJsonAtomic } from '../fsx.js';
4
5
  export const FAST_MODE_POLICY_SCHEMA = 'sks.fast-mode-policy.v1';
5
6
  export const FAST_MODE_PROPAGATION_PROOF_SCHEMA = 'sks.fast-mode-propagation-proof.v1';
7
+ export const FAST_MODE_PREFERENCE_SCHEMA = 'sks.fast-mode-preference.v1';
6
8
  export function resolveFastModePolicy(input = {}) {
7
9
  const explicitTier = normalizeServiceTier(input.serviceTier ?? input.service_tier, null);
8
10
  const explicitNoFast = input.fastMode === false || input.fast_mode === false || input.noFast === true || input.no_fast === true;
9
11
  const explicitFast = input.fastMode === true || input.fast_mode === true || input.fast === true;
12
+ const preference = explicitNoFast || explicitFast || explicitTier
13
+ ? null
14
+ : readFastModePreferenceSync(input.preferenceRoot || input.preference_root || input.root);
10
15
  const serviceTier = explicitNoFast
11
16
  ? 'standard'
12
17
  : explicitTier === 'standard'
13
18
  ? 'standard'
14
- : 'fast';
19
+ : preference?.mode === 'standard'
20
+ ? 'standard'
21
+ : 'fast';
15
22
  return {
16
23
  schema: FAST_MODE_POLICY_SCHEMA,
17
24
  generated_at: nowIso(),
18
25
  fast_mode: serviceTier === 'fast',
19
26
  service_tier: serviceTier,
20
27
  default_fast_mode: true,
21
- disabled_by: explicitNoFast ? 'no-fast' : serviceTier === 'standard' ? 'service-tier-standard' : 'none',
28
+ disabled_by: explicitNoFast ? 'no-fast' : explicitTier === 'standard' ? 'service-tier-standard' : preference?.mode === 'standard' ? 'preference-standard' : 'none',
22
29
  explicit_fast: explicitFast,
23
30
  explicit_no_fast: explicitNoFast,
24
- explicit_service_tier: explicitTier
31
+ explicit_service_tier: explicitTier,
32
+ preference_mode: preference?.mode || null,
33
+ preference_path: preference?.path || null,
34
+ preference_source: preference ? 'project-state' : null
25
35
  };
26
36
  }
37
+ export function fastModePreferencePath(root = process.cwd()) {
38
+ return path.join(path.resolve(root), '.sneakoscope', 'state', 'fast-mode.json');
39
+ }
40
+ export function readFastModePreferenceSync(root) {
41
+ if (!root)
42
+ return null;
43
+ const file = fastModePreferencePath(root);
44
+ try {
45
+ const parsed = JSON.parse(fsSync.readFileSync(file, 'utf8'));
46
+ const mode = normalizeServiceTier(parsed?.mode ?? parsed?.service_tier, null);
47
+ if (!mode)
48
+ return null;
49
+ return normalizeFastModePreference({ ...parsed, mode }, file);
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ export async function readFastModePreference(root = process.cwd()) {
56
+ const file = fastModePreferencePath(root);
57
+ const parsed = await readJson(file, null);
58
+ const mode = normalizeServiceTier(parsed?.mode ?? parsed?.service_tier, null);
59
+ if (!mode)
60
+ return null;
61
+ return normalizeFastModePreference({ ...parsed, mode }, file);
62
+ }
63
+ export async function writeFastModePreference(root = process.cwd(), mode, source = 'sks fast-mode') {
64
+ const normalized = normalizeServiceTier(mode, 'fast') || 'fast';
65
+ const file = fastModePreferencePath(root);
66
+ const preference = {
67
+ schema: FAST_MODE_PREFERENCE_SCHEMA,
68
+ updated_at: nowIso(),
69
+ mode: normalized,
70
+ fast_mode: normalized === 'fast',
71
+ service_tier: normalized,
72
+ source
73
+ };
74
+ await writeJsonAtomic(file, preference);
75
+ return { ...preference, path: file };
76
+ }
77
+ export async function clearFastModePreference(root = process.cwd()) {
78
+ const file = fastModePreferencePath(root);
79
+ const existed = fsSync.existsSync(file);
80
+ await fs.rm(file, { force: true }).catch(() => { });
81
+ return { path: file, removed: existed };
82
+ }
27
83
  export function fastModeEnv(policy) {
28
84
  return {
29
85
  SKS_FAST_MODE: policy.fast_mode ? '1' : '0',
@@ -114,6 +170,18 @@ function normalizeServiceTier(value, fallback = 'fast') {
114
170
  return text;
115
171
  return fallback;
116
172
  }
173
+ function normalizeFastModePreference(parsed, file) {
174
+ const mode = normalizeServiceTier(parsed?.mode ?? parsed?.service_tier, 'fast') || 'fast';
175
+ return {
176
+ schema: FAST_MODE_PREFERENCE_SCHEMA,
177
+ updated_at: typeof parsed?.updated_at === 'string' ? parsed.updated_at : nowIso(),
178
+ mode,
179
+ fast_mode: mode === 'fast',
180
+ service_tier: mode,
181
+ source: typeof parsed?.source === 'string' ? parsed.source : 'unknown',
182
+ path: file
183
+ };
184
+ }
117
185
  function normalizeReasoningProfile(value, policy) {
118
186
  const profile = String(value || 'sks-agent-medium-fast');
119
187
  return policy.fast_mode ? profile.replace(/-standard$/, '-fast') : profile.replace(/-fast$/, '-standard');
@@ -0,0 +1,28 @@
1
+ export declare const FAST_MODE_COMMAND_SCHEMA = "sks.fast-mode-command.v1";
2
+ export declare function fastModeCommand(args?: string[]): Promise<void | {
3
+ schema: string;
4
+ ok: boolean;
5
+ action: "off" | "clear" | "on" | "status";
6
+ root: string;
7
+ state_path: string;
8
+ preference: (import("../agents/fast-mode-policy.js").FastModePreference & {
9
+ path: string;
10
+ }) | null;
11
+ removed: boolean | null;
12
+ fast_mode: boolean;
13
+ service_tier: import("../agents/fast-mode-policy.js").AgentServiceTier;
14
+ disabled_by: "none" | "no-fast" | "service-tier-standard" | "preference-standard";
15
+ policy: import("../agents/fast-mode-policy.js").FastModePolicy;
16
+ dollar_commands: {
17
+ on: string;
18
+ off: string;
19
+ status: string;
20
+ };
21
+ cli_commands: {
22
+ on: string;
23
+ off: string;
24
+ clear: string;
25
+ status: string;
26
+ };
27
+ }>;
28
+ //# sourceMappingURL=fast-mode-command.d.ts.map
@@ -0,0 +1,81 @@
1
+ import path from 'node:path';
2
+ import { flag } from '../../cli/args.js';
3
+ import { printJson } from '../../cli/output.js';
4
+ import { projectRoot } from '../fsx.js';
5
+ import { clearFastModePreference, fastModePreferencePath, readFastModePreference, resolveFastModePolicy, writeFastModePreference } from '../agents/fast-mode-policy.js';
6
+ export const FAST_MODE_COMMAND_SCHEMA = 'sks.fast-mode-command.v1';
7
+ export async function fastModeCommand(args = []) {
8
+ const action = normalizeFastModeAction(args[0]);
9
+ const root = path.resolve(String(readOption(args, '--root', '') || await projectRoot()));
10
+ const statePath = fastModePreferencePath(root);
11
+ let preference = await readFastModePreference(root);
12
+ let removed = null;
13
+ if (action === 'on' || action === 'off') {
14
+ const mode = action === 'on' ? 'fast' : 'standard';
15
+ preference = await writeFastModePreference(root, mode, `sks fast-mode ${action}`);
16
+ }
17
+ else if (action === 'clear') {
18
+ const result = await clearFastModePreference(root);
19
+ removed = result.removed;
20
+ preference = null;
21
+ }
22
+ const policy = resolveFastModePolicy({ root });
23
+ const result = {
24
+ schema: FAST_MODE_COMMAND_SCHEMA,
25
+ ok: true,
26
+ action,
27
+ root,
28
+ state_path: statePath,
29
+ preference,
30
+ removed,
31
+ fast_mode: policy.fast_mode,
32
+ service_tier: policy.service_tier,
33
+ disabled_by: policy.disabled_by,
34
+ policy,
35
+ dollar_commands: {
36
+ on: '$Fast-On',
37
+ off: '$Fast-Off',
38
+ status: '$Fast-Mode'
39
+ },
40
+ cli_commands: {
41
+ on: 'sks fast-mode on',
42
+ off: 'sks fast-mode off',
43
+ clear: 'sks fast-mode clear',
44
+ status: 'sks fast-mode status'
45
+ }
46
+ };
47
+ if (flag(args, '--json'))
48
+ return printJson(result);
49
+ console.log('SKS Fast Mode');
50
+ console.log(`Root: ${root}`);
51
+ console.log(`Status: ${result.fast_mode ? 'on' : 'off'} (service_tier=${result.service_tier})`);
52
+ console.log(`State: ${path.relative(root, statePath)}`);
53
+ if (action === 'on')
54
+ console.log('Saved: fast mode on');
55
+ else if (action === 'off')
56
+ console.log('Saved: fast mode off');
57
+ else if (action === 'clear')
58
+ console.log(`Cleared: ${removed ? 'yes' : 'already default'}`);
59
+ else if (!preference)
60
+ console.log('Preference: default fast');
61
+ console.log('Dollar: $Fast-On | $Fast-Off | $Fast-Mode');
62
+ return result;
63
+ }
64
+ function normalizeFastModeAction(value) {
65
+ const text = String(value || 'status').toLowerCase();
66
+ if (['on', 'enable', 'enabled', 'fast'].includes(text))
67
+ return 'on';
68
+ if (['off', 'disable', 'disabled', 'standard', 'slow'].includes(text))
69
+ return 'off';
70
+ if (['clear', 'default', 'reset'].includes(text))
71
+ return 'clear';
72
+ return 'status';
73
+ }
74
+ function readOption(args = [], name, fallback = null) {
75
+ const index = args.indexOf(name);
76
+ if (index >= 0 && args[index + 1] && !String(args[index + 1]).startsWith('--'))
77
+ return args[index + 1];
78
+ const prefixed = args.find((arg) => String(arg).startsWith(name + '='));
79
+ return prefixed ? prefixed.slice(name.length + 1) : fallback;
80
+ }
81
+ //# sourceMappingURL=fast-mode-command.js.map
@@ -12,8 +12,13 @@ export declare function madHighCommand(args?: any, deps?: any): Promise<void | {
12
12
  layout_artifact: string;
13
13
  command: string[];
14
14
  launch_command: string[];
15
+ launch_command_with_env: string;
15
16
  background_command: string[];
17
+ background_command_with_env: string;
16
18
  attach_command: string;
19
+ attach_command_with_env: string;
20
+ zellij_socket_dir: string | null;
21
+ zellij_socket_dir_source: import("../zellij/zellij-command.js").ZellijSocketDirSource;
17
22
  pane_proof_path: string;
18
23
  pane_proof: {
19
24
  schema: string;
@@ -231,7 +231,7 @@ async function executeRouteCommand(root, route, prompt, { auto = false } = {}) {
231
231
  return routeExecutionResult(route, ['sks', ...commandArgs].join(' '), result, {
232
232
  okStatus: 'completed',
233
233
  trustStatus: 'verified_partial',
234
- executionKind: route.command === '$DB' || route.command === '$Wiki' ? 'safe_deterministic' : 'mock_safe',
234
+ executionKind: route.command === '$DB' || route.command === '$Wiki' || route.command === '$Fast-Mode' ? 'safe_deterministic' : 'mock_safe',
235
235
  });
236
236
  }
237
237
  async function runAutoVerification(root, missionId) {
@@ -344,8 +344,34 @@ function safeRouteExecutionArgs(route, prompt, { auto = false } = {}) {
344
344
  return ['db', 'check', '--sql', 'SELECT 1', '--json'];
345
345
  if (route.command === '$Wiki')
346
346
  return ['wiki', 'refresh', '--json'];
347
+ if (route.command === '$Fast-Mode')
348
+ return ['fast-mode', fastModeActionFromPrompt(prompt), '--json'];
347
349
  return ['team', prompt, '--mock', '--json', ...(auto ? ['--no-open-zellij'] : [])];
348
350
  }
351
+ function fastModeActionFromPrompt(prompt = '') {
352
+ const text = String(prompt || '');
353
+ const lower = text.toLowerCase();
354
+ if (/\$fast-off\b/.test(lower))
355
+ return 'off';
356
+ if (/\$fast-on\b/.test(lower))
357
+ return 'on';
358
+ const routeMatch = /\$fast-mode\b/i.exec(text);
359
+ if (!routeMatch)
360
+ return 'status';
361
+ const afterRoute = text
362
+ .slice(routeMatch.index + routeMatch[0].length)
363
+ .replace(/^[\s:=\-]+/, '')
364
+ .trimStart()
365
+ .toLowerCase();
366
+ const token = afterRoute.match(/^[^\s?!.,;:()"'`]+/)?.[0] || '';
367
+ if (['off', 'disable', 'disabled', 'standard', 'slow', '끄기', '꺼', '꺼줘'].includes(token) || token.startsWith('끄') || token.startsWith('꺼'))
368
+ return 'off';
369
+ if (['on', 'enable', 'enabled', 'fast', '켜기', '켜', '켜줘'].includes(token) || token.startsWith('켜'))
370
+ return 'on';
371
+ if (['clear', 'reset', 'default', '초기화', '기본'].includes(token) || token.startsWith('초기화'))
372
+ return 'clear';
373
+ return 'status';
374
+ }
349
375
  function destructiveDbPrompt(prompt = '') {
350
376
  return /\b(drop|truncate|delete\s+from|update\s+\w+\s+set|reset|db\s+push|disable\s+rls)\b/i.test(prompt);
351
377
  }
@@ -54,6 +54,7 @@ const FIXTURES = Object.freeze({
54
54
  'cli-memory': fixture('execute', 'sks memory --dry-run --json', [], 'pass'),
55
55
  'cli-stats': fixture('execute', 'sks stats --json', [], 'pass'),
56
56
  'cli-dollar-commands': fixture('execute', 'sks dollar-commands --json', [], 'pass'),
57
+ 'cli-fast-mode': fixture('execute', 'sks fast-mode status --json', [], 'pass'),
57
58
  'cli-dfix': fixture('execute_and_validate_artifacts', 'sks dfix fixture --json', ['completion-proof.json', 'dfix-gate.json', 'dfix-verification.json'], 'pass'),
58
59
  'cli-wiki': fixture('execute_and_validate_artifacts', 'sks wiki image-ingest test/fixtures/images/one-by-one.png --json', [{ path: '.sneakoscope/wiki/image-voxel-ledger.json', schema: 'sks.image-voxel-ledger.v1', require_anchors: false }], 'pass'),
59
60
  'cli-db': fixture('execute', 'sks db policy', [], 'pass'),
@@ -106,6 +107,9 @@ const FIXTURES = Object.freeze({
106
107
  'route-wiki': fixture('execute_and_validate_artifacts', 'sks wiki image-ingest test/fixtures/images/one-by-one.png --json', [{ path: 'completion-proof.json', schema: 'sks.completion-proof.v1' }, { path: 'image-voxel-ledger.json', schema: 'sks.image-voxel-ledger.v1' }], 'pass'),
107
108
  'route-gx': fixture('execute_and_validate_artifacts', 'sks gx validate fixture --mock --json', ['completion-proof.json', { path: 'image-voxel-ledger.json', schema: 'sks.image-voxel-ledger.v1' }, 'gx-validation.json'], 'pass'),
108
109
  'route-sks': fixture('mock', '$SKS control-surface route', ['completion-proof.json'], 'pass'),
110
+ 'route-fast-mode': fixture('execute', 'sks fast-mode status --json', [], 'pass'),
111
+ 'route-fast-on': fixture('mock', '$Fast-On covered by hermetic fast-mode blackbox toggle test', [], 'pass'),
112
+ 'route-fast-off': fixture('mock', '$Fast-Off covered by hermetic fast-mode blackbox toggle test', [], 'pass'),
109
113
  'route-help': fixture('mock', '$Help lightweight route', [], 'pass'),
110
114
  'route-commit': fixture('mock', '$Commit git route', ['completion-proof.json'], 'pass'),
111
115
  'route-commit-and-push': fixture('mock', '$Commit-And-Push git route', ['completion-proof.json'], 'pass'),
@@ -479,6 +479,7 @@ const SAFE_EXECUTABLE_FIXTURE_ARGS = Object.freeze({
479
479
  'cli-memory': ['memory', '--dry-run', '--json'],
480
480
  'cli-stats': ['stats', '--json'],
481
481
  'cli-dollar-commands': ['dollar-commands', '--json'],
482
+ 'cli-fast-mode': ['fast-mode', 'status', '--json'],
482
483
  'cli-dfix': ['dfix', 'fixture', '--json'],
483
484
  'cli-all-features': ['all-features', 'complete', '--json'],
484
485
  'route-team': ['team', 'fixture', '--mock', '--json'],
@@ -489,6 +490,7 @@ const SAFE_EXECUTABLE_FIXTURE_ARGS = Object.freeze({
489
490
  'route-image-ux-review': ['image-ux-review', 'fixture', '--mock', '--json'],
490
491
  'route-computer-use': ['computer-use', 'import-fixture', '--mock', '--json'],
491
492
  'route-dfix': ['dfix', 'fixture', '--json'],
493
+ 'route-fast-mode': ['fast-mode', 'status', '--json'],
492
494
  'route-db': ['db', 'check', '--sql', 'SELECT 1', '--json'],
493
495
  'route-wiki': ['wiki', 'image-ingest', 'test/fixtures/images/one-by-one.png', '--json'],
494
496
  'route-gx': ['gx', 'validate', 'fixture', '--mock', '--json']
@@ -817,14 +819,14 @@ function commandCategory(name) {
817
819
  return 'core-cli';
818
820
  }
819
821
  function commandMaturity(name) {
820
- if (['help', 'version', 'commands', 'usage', 'root', 'quickstart', 'setup', 'doctor', 'selftest', 'update-check'].includes(name))
822
+ if (['help', 'version', 'commands', 'usage', 'root', 'quickstart', 'setup', 'doctor', 'selftest', 'update-check', 'fast-mode'].includes(name))
821
823
  return 'stable';
822
824
  if (['codex', 'codex-app', 'codex-lb', 'hooks', 'features', 'all-features', 'wiki', 'wrongness', 'team', 'pipeline', 'goal', 'db', 'guard'].includes(name))
823
825
  return 'beta';
824
826
  return 'labs';
825
827
  }
826
828
  function routeMaturity(command) {
827
- if (['$Answer', '$DFix', '$SKS', '$Wiki', '$Help'].includes(command))
829
+ if (['$Answer', '$DFix', '$SKS', '$Fast-Mode', '$Wiki', '$Help'].includes(command))
828
830
  return 'stable';
829
831
  if (['$Team', '$Goal', '$DB', '$Computer-Use', '$CU', '$QA-LOOP', '$MAD-SKS'].includes(command))
830
832
  return 'beta';
@@ -1,4 +1,4 @@
1
- export declare const PACKAGE_VERSION = "1.20.2";
1
+ export declare const PACKAGE_VERSION = "1.20.3";
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.2';
8
+ export const PACKAGE_VERSION = '1.20.3';
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/init.js CHANGED
@@ -1035,6 +1035,9 @@ export async function installSkills(root) {
1035
1035
  'dfix': `---\nname: dfix\ndescription: Direct Fix mode for $DFix or $dfix requests and inferred tiny copy/config/docs/labels/spacing/translation/simple mechanical edits.\n---\n\nUse for tiny copy/config/docs/labels/spacing/translation/simple mechanical edits. List exact micro-edits, inspect only needed files, apply only those edits, and run cheap verification. Keep broad implementation routed to Team; for UI/UX micro-edits read \`design.md\` when present and use imagegen for image/logo/raster assets. Bypass broad SKS routing, mission state, TriWiki/TriFix/reflection/state recording, Goal, Research, eval, redesign, and repeated full-route Honest Mode loops. Start the final answer with \`DFix 완료 요약:\` and include one \`DFix 솔직모드:\` line covering verified, not verified, and remaining issues. ${CODEX_IMAGEGEN_REQUIRED_POLICY}\n`,
1036
1036
  'answer': `---\nname: answer\ndescription: Answer-only research route for ordinary questions that should not start implementation.\n---\n\nUse for explanations, comparisons, status, facts, source-backed research, or docs guidance. Use repo/TriWiki first for project-local facts; hydrate low-trust claims from source. Browse or use Context7 for current external package/API/framework/MCP docs. End with a concise answer summary plus Honest Mode; do not create missions, subagents, or file edits.\n`,
1037
1037
  'sks': `---\nname: sks\ndescription: General Sneakoscope Codex command route for $SKS or $sks usage, setup, status, and workflow help.\n---\n\nUse local SKS commands: bootstrap, deps, commands, quickstart, codex-app, context7, guard, conflicts, reasoning, wiki, pipeline status, pipeline plan, skill-dream. Promote code-changing work to Team unless Answer/DFix/Help/Wiki/safety route fits. Surface route/guard/scope, use TriWiki, do not edit installed harness files outside this engine repo, and require human-approved conflict cleanup. ${skillDreamPolicyText()}\n`,
1038
+ 'fast-mode': `---\nname: fast-mode\ndescription: Dollar-command route for $Fast-Mode, $Fast-On, and $Fast-Off project-local Fast mode toggles.\n---\n\nUse when the user invokes $Fast-Mode, $Fast-On, $Fast-Off, or asks to turn SKS Fast mode on/off for dollar commands. Prefer \`sks fast-mode on|off|status|clear --json\`. The command writes only .sneakoscope/state/fast-mode.json in the active project. Explicit runtime flags still win: \`--fast\`, \`--no-fast\`, and \`--service-tier standard|fast\` override the saved preference for that run. Finish with a short status and Honest Mode; do not start Team or broad implementation for a toggle-only request.\n`,
1039
+ 'fast-on': `---\nname: fast-on\ndescription: Alias for $Fast-On project-local SKS Fast mode enablement.\n---\n\nUse the same rules as fast-mode. Run or instruct \`sks fast-mode on --json\`, then report the active state, state file, and the fact that explicit per-run flags still override the saved preference.\n`,
1040
+ 'fast-off': `---\nname: fast-off\ndescription: Alias for $Fast-Off project-local SKS Fast mode disablement.\n---\n\nUse the same rules as fast-mode. Run or instruct \`sks fast-mode off --json\`, then report the active state, state file, and the fact that explicit per-run flags still override the saved preference.\n`,
1038
1041
  'wiki': `---\nname: wiki\ndescription: Dollar-command route for $Wiki TriWiki refresh, pack, validate, and prune commands.\n---\n\nUse for $Wiki or Korean wiki-refresh requests. Refresh/update/갱신: run sks wiki refresh, then validate .sneakoscope/wiki/context-pack.json. Pack: run sks wiki pack, then validate. Prune/clean/정리: use sks wiki refresh --prune, or sks wiki prune --dry-run for inspection. Report claims, anchors, trust, attention.use_first/hydrate_first, validation, and blockers. Do not start ambiguity-gated implementation, subagents, or unrelated work.\n`,
1039
1042
  'team': `---\nname: team\ndescription: SKS Team orchestration for $Team/code work; $From-Chat-IMG is the explicit chat-image alias.\n---\n\nUse for $Team/code work. Auto-seal the route contract from prompt, TriWiki/current-code defaults, and conservative policy; do not surface a prequestion sheet. Read pipeline-plan.json or run sks pipeline plan to see the runtime lane, kept/skipped stages, and verification before implementation. Write team-roster.json; team-gate.json needs team_roster_confirmed=true. executor:N means N native analysis agents, N debate voices, then fresh N executors. ${MIN_TEAM_REVIEW_POLICY_TEXT} After consensus, compile team-graph.json, team-runtime-tasks.json, team-decomposition-report.json, and team-inbox/ so worker handoff uses concrete runtime task ids with role/path/domain/lane hints. Refresh/validate TriWiki before debate, implementation, review, and final; consume attention.use_first and hydrate attention.hydrate_first before risky decisions. ${outcomeRubricPolicyText()} ${speedLanePolicyText()} ${solutionScoutPolicyText('fix this broken behavior')} ${skillDreamPolicyText()} Log events and use sks team message for bounded inter-agent communication in transcript/lane panes. Color-coded Zellij lanes distinguish overview/native-analysis/planning/execution/review/safety sessions in one Zellij window using split panes when Zellij is available. $Team/$team plus sks --mad uses the MAD-SKS permission gate module: user-authorized target-project scopes such as files, shell, packages, services, network, browser/Computer Use, generated assets, file permissions, migrations, normal DB writes, Supabase MCP writes, direct SQL, and schema cleanup are open only for the active invocation; catastrophic wipe/all-row/project-management, credential exfiltration, persistent security weakening, and unrequested fallback guards remain. End with cleanup-zellij or a cleanup event so follow panes show cleanup and stop; pass team-session-cleanup.json, then reflection and Honest Mode. Parent integrates/verifies.\n\n${chatCaptureIntakeText()}\n`,
1040
1043
  'from-chat-img': `---\nname: from-chat-img\ndescription: Explicit $From-Chat-IMG Team alias for chat screenshot plus attachment analysis.\n---\n\nUse only for From-Chat-IMG/$From-Chat-IMG. It enters the normal Team pipeline. Treat uploads as chat screenshot plus originals. For web/browser/webapp targets use Codex Chrome Extension first; for native Mac/non-web app surfaces use Codex Computer Use visual inspection when available. List requirements first, match regions to attachments with confidence, write ${FROM_CHAT_IMG_COVERAGE_ARTIFACT}, ${FROM_CHAT_IMG_CHECKLIST_ARTIFACT}, ${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT}, and ${FROM_CHAT_IMG_QA_LOOP_ARTIFACT}, then continue Team gates, review, reflection, and Honest Mode. ${CODEX_WEB_VERIFICATION_POLICY} ${CODEX_COMPUTER_USE_ONLY_POLICY} The ledger must account for every visible customer request, screenshot image region, and separate attachment; ${FROM_CHAT_IMG_CHECKLIST_ARTIFACT} must have a checked item for each request, image-region/attachment match, work item, scoped QA-LOOP, and verification step; ${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT} stores temporary TriWiki-backed session context with expires_after_sessions=${FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS}. ${FROM_CHAT_IMG_QA_LOOP_ARTIFACT} must prove QA-LOOP ran over the exact customer-request work-order range after implementation, with every work item covered, post-fix verification complete, and zero unresolved findings. team-gate.json cannot pass From-Chat-IMG completion until unresolved_items is empty, every checklist box is checked, and scoped_qa_loop_completed=true.\n`,
@@ -10,7 +10,7 @@ export declare const FROM_CHAT_IMG_CHECKLIST_ARTIFACT = "from-chat-img-checklist
10
10
  export declare const FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT = "from-chat-img-temp-triwiki.json";
11
11
  export declare const FROM_CHAT_IMG_QA_LOOP_ARTIFACT = "from-chat-img-qa-loop.json";
12
12
  export declare const FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS = 5;
13
- export declare const USAGE_TOPICS = "install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|goal|research|db|git|codex|codex-app|hooks|features|all-features|openclaw|hermes|dfix|commit|commit-and-push|design|imagegen|dollar|context7|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust";
13
+ export declare const USAGE_TOPICS = "install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|goal|fast-mode|research|db|git|codex|codex-app|hooks|features|all-features|openclaw|hermes|dfix|commit|commit-and-push|design|imagegen|dollar|context7|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust";
14
14
  export declare const CODEX_COMPUTER_USE_EVIDENCE_SOURCE = "codex_computer_use";
15
15
  export declare const CODEX_WEB_VERIFICATION_EVIDENCE_SOURCE = "codex_chrome_extension";
16
16
  export declare const CODEX_IMAGEGEN_EVIDENCE_SOURCE = "codex_app_imagegen_gpt_image_2";
@@ -28,7 +28,7 @@ export const FROM_CHAT_IMG_CHECKLIST_ARTIFACT = 'from-chat-img-checklist.md';
28
28
  export const FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT = 'from-chat-img-temp-triwiki.json';
29
29
  export const FROM_CHAT_IMG_QA_LOOP_ARTIFACT = 'from-chat-img-qa-loop.json';
30
30
  export const FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS = 5;
31
- export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|goal|research|db|git|codex|codex-app|hooks|features|all-features|openclaw|hermes|dfix|commit|commit-and-push|design|imagegen|dollar|context7|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust';
31
+ export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|goal|fast-mode|research|db|git|codex|codex-app|hooks|features|all-features|openclaw|hermes|dfix|commit|commit-and-push|design|imagegen|dollar|context7|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust';
32
32
  export const CODEX_COMPUTER_USE_EVIDENCE_SOURCE = 'codex_computer_use';
33
33
  export const CODEX_WEB_VERIFICATION_EVIDENCE_SOURCE = 'codex_chrome_extension';
34
34
  export const CODEX_IMAGEGEN_EVIDENCE_SOURCE = 'codex_app_imagegen_gpt_image_2';
@@ -319,6 +319,22 @@ export const ROUTES = [
319
319
  cliEntrypoint: 'sks commands',
320
320
  examples: ['$SKS show me available workflows']
321
321
  },
322
+ {
323
+ id: 'FastMode',
324
+ command: '$Fast-Mode',
325
+ mode: 'FAST_MODE',
326
+ route: 'fast-mode toggle',
327
+ description: 'Turn the SKS Fast mode default on or off for project-local dollar-command and native-agent routes. Explicit --fast, --no-fast, and --service-tier flags still override it.',
328
+ requiredSkills: ['fast-mode', 'honest-mode'],
329
+ dollarAliases: ['$Fast-On', '$Fast-Off'],
330
+ appSkillAliases: ['fast-on', 'fast-off'],
331
+ lifecycle: ['project_state_toggle', 'policy_status', 'honest_mode'],
332
+ context7Policy: 'not_required',
333
+ reasoningPolicy: 'low',
334
+ stopGate: 'none',
335
+ cliEntrypoint: 'sks fast-mode on|off|status|clear [--json]',
336
+ examples: ['$Fast-On', '$Fast-Off', '$Fast-Mode status']
337
+ },
322
338
  {
323
339
  id: 'Team',
324
340
  command: '$Team',
@@ -604,6 +620,7 @@ export const COMMAND_CATALOG = [
604
620
  { name: 'mad', usage: 'sks --mad [--high]', description: 'Open a one-shot Zellij Codex CLI workspace with the SKS MAD full-access auto-review profile.' },
605
621
  { name: 'auto-review', usage: 'sks auto-review status|enable|start [--high] | sks --Auto-review --high', description: 'Enable Codex automatic approval review and launch SKS Zellij with the auto-review profile.' },
606
622
  { name: 'dollar-commands', usage: 'sks dollar-commands [--json]', description: 'List Codex App $ commands such as $DFix and $Team.' },
623
+ { name: 'fast-mode', usage: 'sks fast-mode on|off|status|clear [--json]', description: 'Toggle the project-local Fast mode default used by $Fast-On, $Fast-Off, and native-agent routes.' },
607
624
  { name: 'commit', usage: 'sks commit [--message "msg"] [--json]', description: 'Stage current changes, summarize them, and create a simple git commit without the full SKS pipeline.' },
608
625
  { name: 'commit-and-push', usage: 'sks commit-and-push [--message "msg"] [--json]', description: 'Stage current changes, create a simple git commit, and push without the full SKS pipeline.' },
609
626
  { name: 'dfix', usage: 'sks dfix', description: 'Explain $DFix ultralight direct-fix mode.' },
@@ -1,2 +1,2 @@
1
- export declare const PACKAGE_VERSION = "1.20.2";
1
+ export declare const PACKAGE_VERSION = "1.20.3";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,2 +1,2 @@
1
- export const PACKAGE_VERSION = '1.20.2';
1
+ export const PACKAGE_VERSION = '1.20.3';
2
2
  //# sourceMappingURL=version.js.map
@@ -1,4 +1,11 @@
1
1
  import { type RunProcessOptions } from '../fsx.js';
2
+ export declare const ZELLIJ_UNIX_SOCKET_PATH_LIMIT = 103;
3
+ export type ZellijSocketDirSource = 'env' | 'sks_env' | 'sks_default' | 'none';
4
+ export interface ZellijProcessEnvMeta {
5
+ zellij_socket_dir: string | null;
6
+ zellij_socket_dir_source: ZellijSocketDirSource;
7
+ zellij_socket_path_limit: number | null;
8
+ }
2
9
  export interface ZellijCommandResult {
3
10
  ok: boolean;
4
11
  command: 'zellij';
@@ -11,6 +18,7 @@ export interface ZellijCommandResult {
11
18
  stderr_bytes: number;
12
19
  timed_out: boolean;
13
20
  duration_ms: number;
21
+ env: ZellijProcessEnvMeta;
14
22
  blockers: string[];
15
23
  warnings: string[];
16
24
  }
@@ -18,6 +26,16 @@ export interface ZellijRunOptions extends Pick<RunProcessOptions, 'cwd' | 'env'
18
26
  optional?: boolean;
19
27
  }
20
28
  export declare function runZellij(args?: readonly string[], opts?: ZellijRunOptions): Promise<ZellijCommandResult>;
29
+ export declare function prepareZellijProcessEnv(envOverrides?: NodeJS.ProcessEnv): Promise<{
30
+ env: NodeJS.ProcessEnv;
31
+ meta: ZellijProcessEnvMeta;
32
+ warnings: string[];
33
+ }>;
34
+ export declare function resolveZellijProcessEnvMeta(env?: NodeJS.ProcessEnv): ZellijProcessEnvMeta;
35
+ export declare function defaultZellijSocketDir(): string;
36
+ export declare function estimateZellijSocketPathLength(socketDir: string, sessionName?: string): number;
37
+ export declare function formatZellijCommand(args?: readonly string[], meta?: ZellijProcessEnvMeta): string;
38
+ export declare function isZellijSocketPathTooLong(text: unknown): boolean;
21
39
  export declare function parseZellijVersionText(text: unknown): string | null;
22
40
  export declare function compareVersionLike(a: unknown, b: unknown): number;
23
41
  //# sourceMappingURL=zellij-command.d.ts.map
@@ -1,13 +1,17 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
1
3
  import { runProcess } from '../fsx.js';
4
+ export const ZELLIJ_UNIX_SOCKET_PATH_LIMIT = 103;
2
5
  export async function runZellij(args = [], opts = {}) {
3
6
  const started = Date.now();
7
+ const preparedEnv = await prepareZellijProcessEnv(opts.env);
4
8
  const runOpts = {
5
9
  cwd: opts.cwd || process.cwd(),
6
10
  timeoutMs: opts.timeoutMs ?? 10000,
7
11
  maxOutputBytes: opts.maxOutputBytes ?? 64 * 1024
8
12
  };
9
- if (opts.env !== undefined)
10
- runOpts.env = opts.env;
13
+ if (Object.keys(preparedEnv.env).length > 0)
14
+ runOpts.env = preparedEnv.env;
11
15
  if (opts.stdoutFile !== undefined)
12
16
  runOpts.stdoutFile = opts.stdoutFile;
13
17
  if (opts.stderrFile !== undefined)
@@ -16,6 +20,7 @@ export async function runZellij(args = [], opts = {}) {
16
20
  const ok = result.code === 0;
17
21
  const stderr = String(result.stderr || '');
18
22
  const missing = result.code === -1 && /ENOENT|not found|spawn zellij/i.test(stderr);
23
+ const socketPathTooLong = isZellijSocketPathTooLong(stderr);
19
24
  return {
20
25
  ok,
21
26
  command: 'zellij',
@@ -28,10 +33,60 @@ export async function runZellij(args = [], opts = {}) {
28
33
  stderr_bytes: result.stderrBytes,
29
34
  timed_out: result.timedOut,
30
35
  duration_ms: Date.now() - started,
31
- blockers: ok ? [] : [missing ? 'zellij_missing' : result.timedOut ? 'zellij_command_timeout' : 'zellij_command_failed'],
32
- warnings: ok || opts.optional !== true ? [] : ['zellij_command_failed_optional']
36
+ env: preparedEnv.meta,
37
+ blockers: ok ? [] : [missing ? 'zellij_missing' : socketPathTooLong ? 'zellij_socket_path_too_long' : result.timedOut ? 'zellij_command_timeout' : 'zellij_command_failed'],
38
+ warnings: [
39
+ ...preparedEnv.warnings,
40
+ ...(ok || opts.optional !== true ? [] : ['zellij_command_failed_optional'])
41
+ ]
33
42
  };
34
43
  }
44
+ export async function prepareZellijProcessEnv(envOverrides = {}) {
45
+ const mergedEnv = { ...process.env, ...envOverrides };
46
+ const meta = resolveZellijProcessEnvMeta(mergedEnv);
47
+ const env = { ...envOverrides };
48
+ const warnings = [];
49
+ if (meta.zellij_socket_dir && !env.ZELLIJ_SOCKET_DIR)
50
+ env.ZELLIJ_SOCKET_DIR = meta.zellij_socket_dir;
51
+ if (meta.zellij_socket_dir) {
52
+ try {
53
+ await fs.mkdir(meta.zellij_socket_dir, { recursive: true, mode: 0o700 });
54
+ await fs.chmod(meta.zellij_socket_dir, 0o700).catch(() => { });
55
+ }
56
+ catch (err) {
57
+ warnings.push(`zellij_socket_dir_prepare_failed:${err?.code || err?.message || String(err)}`);
58
+ }
59
+ }
60
+ return { env, meta, warnings };
61
+ }
62
+ export function resolveZellijProcessEnvMeta(env = process.env) {
63
+ const explicit = nonEmpty(env.ZELLIJ_SOCKET_DIR);
64
+ if (explicit)
65
+ return socketMeta(explicit, 'env');
66
+ const sks = nonEmpty(env.SKS_ZELLIJ_SOCKET_DIR);
67
+ if (sks)
68
+ return socketMeta(sks, 'sks_env');
69
+ if (process.platform === 'win32') {
70
+ return { zellij_socket_dir: null, zellij_socket_dir_source: 'none', zellij_socket_path_limit: null };
71
+ }
72
+ return socketMeta(defaultZellijSocketDir(), 'sks_default');
73
+ }
74
+ export function defaultZellijSocketDir() {
75
+ const uid = typeof process.getuid === 'function' ? String(process.getuid()) : 'user';
76
+ return path.join('/tmp', `zj${uid}`);
77
+ }
78
+ export function estimateZellijSocketPathLength(socketDir, sessionName = '') {
79
+ return path.join(socketDir, 'contract_version_1', sessionName).length;
80
+ }
81
+ export function formatZellijCommand(args = [], meta = resolveZellijProcessEnvMeta()) {
82
+ const command = ['zellij', ...args].map(shellQuote).join(' ');
83
+ if (!meta.zellij_socket_dir)
84
+ return command;
85
+ return `ZELLIJ_SOCKET_DIR=${shellQuote(meta.zellij_socket_dir)} ${command}`;
86
+ }
87
+ export function isZellijSocketPathTooLong(text) {
88
+ return /IPC socket path is too long|socket path is too long/i.test(String(text || ''));
89
+ }
35
90
  export function parseZellijVersionText(text) {
36
91
  const match = String(text || '').match(/\b(\d+\.\d+\.\d+)(?:[-+][0-9A-Za-z.-]+)?\b/);
37
92
  return match?.[1] ?? null;
@@ -53,4 +108,20 @@ function versionParts(value) {
53
108
  const parsed = parseZellijVersionText(value) || String(value || '0.0.0');
54
109
  return parsed.split(/[.-]/).map((part) => Number.parseInt(part, 10) || 0);
55
110
  }
111
+ function socketMeta(socketDir, source) {
112
+ return {
113
+ zellij_socket_dir: socketDir,
114
+ zellij_socket_dir_source: source,
115
+ zellij_socket_path_limit: ZELLIJ_UNIX_SOCKET_PATH_LIMIT
116
+ };
117
+ }
118
+ function nonEmpty(value) {
119
+ const text = String(value || '').trim();
120
+ return text ? text : null;
121
+ }
122
+ function shellQuote(value) {
123
+ if (/^[A-Za-z0-9_./:=@+-]+$/.test(value))
124
+ return value;
125
+ return `'${value.replace(/'/g, `'\\''`)}'`;
126
+ }
56
127
  //# sourceMappingURL=zellij-command.js.map
@@ -1,4 +1,5 @@
1
1
  export declare const ZELLIJ_SESSION_SCHEMA = "sks.zellij-session.v1";
2
+ export declare const ZELLIJ_SESSION_NAME_MAX = 64;
2
3
  export interface ZellijLaunchOptions {
3
4
  root?: string;
4
5
  missionId?: string;
@@ -25,8 +26,13 @@ export declare function launchZellijLayout(opts?: ZellijLaunchOptions): Promise<
25
26
  layout_artifact: string;
26
27
  command: string[];
27
28
  launch_command: string[];
29
+ launch_command_with_env: string;
28
30
  background_command: string[];
31
+ background_command_with_env: string;
29
32
  attach_command: string;
33
+ attach_command_with_env: string;
34
+ zellij_socket_dir: string | null;
35
+ zellij_socket_dir_source: import("./zellij-command.js").ZellijSocketDirSource;
30
36
  pane_proof_path: string;
31
37
  pane_proof: {
32
38
  schema: string;
@@ -71,8 +77,13 @@ export declare function launchMadZellijUi(args?: readonly unknown[], opts?: Zell
71
77
  layout_artifact: string;
72
78
  command: string[];
73
79
  launch_command: string[];
80
+ launch_command_with_env: string;
74
81
  background_command: string[];
82
+ background_command_with_env: string;
75
83
  attach_command: string;
84
+ attach_command_with_env: string;
85
+ zellij_socket_dir: string | null;
86
+ zellij_socket_dir_source: import("./zellij-command.js").ZellijSocketDirSource;
76
87
  pane_proof_path: string;
77
88
  pane_proof: {
78
89
  schema: string;
@@ -117,8 +128,13 @@ export declare function launchTeamZellijView(opts?: ZellijLaunchOptions): Promis
117
128
  layout_artifact: string;
118
129
  command: string[];
119
130
  launch_command: string[];
131
+ launch_command_with_env: string;
120
132
  background_command: string[];
133
+ background_command_with_env: string;
121
134
  attach_command: string;
135
+ attach_command_with_env: string;
136
+ zellij_socket_dir: string | null;
137
+ zellij_socket_dir_source: import("./zellij-command.js").ZellijSocketDirSource;
122
138
  pane_proof_path: string;
123
139
  pane_proof: {
124
140
  schema: string;
@@ -1,10 +1,11 @@
1
1
  import path from 'node:path';
2
- import { appendJsonl, nowIso, writeJsonAtomic } from '../fsx.js';
2
+ import { appendJsonl, nowIso, sha256, writeJsonAtomic } from '../fsx.js';
3
3
  import { checkZellijCapability } from './zellij-capability.js';
4
- import { runZellij } from './zellij-command.js';
4
+ import { formatZellijCommand, resolveZellijProcessEnvMeta, runZellij } from './zellij-command.js';
5
5
  import { writeZellijLayout } from './zellij-layout-builder.js';
6
6
  import { writeZellijPaneProof } from './zellij-pane-proof.js';
7
7
  export const ZELLIJ_SESSION_SCHEMA = 'sks.zellij-session.v1';
8
+ export const ZELLIJ_SESSION_NAME_MAX = 64;
8
9
  export async function launchZellijLayout(opts = {}) {
9
10
  const root = path.resolve(opts.root || process.cwd());
10
11
  const missionId = String(opts.missionId || `M-${Date.now().toString(36)}`);
@@ -24,6 +25,7 @@ export async function launchZellijLayout(opts = {}) {
24
25
  const createCommand = ['attach', '--create-background', sessionName, 'options', '--default-layout', layout.layout_path];
25
26
  const attachCommand = ['attach', sessionName];
26
27
  const command = opts.attach === true ? attachCommand : createCommand;
28
+ const zellijEnv = resolveZellijProcessEnvMeta();
27
29
  const launch = opts.dryRun === true || capability.status !== 'ok'
28
30
  ? null
29
31
  : opts.attach === true
@@ -65,8 +67,13 @@ export async function launchZellijLayout(opts = {}) {
65
67
  layout_artifact: path.relative(root, layout.layout_path),
66
68
  command: ['zellij', ...command],
67
69
  launch_command: ['zellij', ...createCommand],
70
+ launch_command_with_env: formatZellijCommand(createCommand, zellijEnv),
68
71
  background_command: ['zellij', ...createCommand],
72
+ background_command_with_env: formatZellijCommand(createCommand, zellijEnv),
69
73
  attach_command: `zellij attach ${sessionName}`,
74
+ attach_command_with_env: formatZellijCommand(attachCommand, zellijEnv),
75
+ zellij_socket_dir: zellijEnv.zellij_socket_dir,
76
+ zellij_socket_dir_source: zellijEnv.zellij_socket_dir_source,
70
77
  pane_proof_path: path.join(root, '.sneakoscope', 'missions', missionId, 'zellij-pane-proof.json'),
71
78
  pane_proof: paneProof,
72
79
  dry_run: opts.dryRun === true,
@@ -111,7 +118,13 @@ export async function launchTeamZellijView(opts = {}) {
111
118
  }
112
119
  export function sanitizeZellijSessionName(value) {
113
120
  const cleaned = String(value || 'sks-session').replace(/[^A-Za-z0-9_.:-]+/g, '-').replace(/^-+|-+$/g, '');
114
- return cleaned.slice(0, 80) || 'sks-session';
121
+ if (!cleaned)
122
+ return 'sks-session';
123
+ if (cleaned.length <= ZELLIJ_SESSION_NAME_MAX)
124
+ return cleaned;
125
+ const suffix = sha256(cleaned).slice(0, 8);
126
+ const prefix = cleaned.slice(0, ZELLIJ_SESSION_NAME_MAX - suffix.length - 1).replace(/[-_.:]+$/g, '');
127
+ return `${prefix}-${suffix}`.slice(0, ZELLIJ_SESSION_NAME_MAX);
115
128
  }
116
129
  function readOption(args, name, fallback) {
117
130
  const list = args.map((arg) => String(arg));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sneakoscope",
3
3
  "displayName": "ㅅㅋㅅ",
4
- "version": "1.20.2",
4
+ "version": "1.20.3",
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",