sneakoscope 2.0.8 → 2.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +1 -1
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/crates/sks-core/src/main.rs +1 -1
  5. package/dist/.sks-build-stamp.json +4 -4
  6. package/dist/bin/sks.js +1 -1
  7. package/dist/build-manifest.json +20 -8
  8. package/dist/commands/zellij.js +144 -1
  9. package/dist/core/agents/agent-orchestrator.js +4 -2
  10. package/dist/core/agents/native-cli-session-swarm.js +76 -9
  11. package/dist/core/commands/mad-sks-command.js +17 -26
  12. package/dist/core/commands/naruto-command.js +99 -36
  13. package/dist/core/fsx.js +1 -1
  14. package/dist/core/naruto/naruto-active-pool.js +108 -0
  15. package/dist/core/naruto/naruto-concurrency-governor.js +16 -1
  16. package/dist/core/naruto/naruto-work-graph.js +2 -1
  17. package/dist/core/release/release-gate-cache-v2.js +58 -4
  18. package/dist/core/release/release-gate-dag.js +36 -25
  19. package/dist/core/version.js +1 -1
  20. package/dist/core/zellij/zellij-dashboard-renderer.js +22 -6
  21. package/dist/core/zellij/zellij-launcher.js +3 -3
  22. package/dist/core/zellij/zellij-layout-builder.js +1 -1
  23. package/dist/core/zellij/zellij-right-column-layout-proof.js +42 -0
  24. package/dist/core/zellij/zellij-right-column-manager.js +245 -0
  25. package/dist/core/zellij/zellij-worker-pane-manager.js +118 -13
  26. package/dist/scripts/codex-sdk-release-review-pipeline-check.js +5 -5
  27. package/dist/scripts/doctor-fix-proves-codex-read-check.js +26 -5
  28. package/dist/scripts/lib/codex-sdk-gate-lib.js +4 -0
  29. package/dist/scripts/mad-sks-zellij-default-pane-worker-check.js +2 -2
  30. package/dist/scripts/naruto-concurrency-governor-check.js +2 -1
  31. package/dist/scripts/naruto-extreme-parallelism-check.js +22 -0
  32. package/dist/scripts/naruto-real-active-pool-check.js +38 -0
  33. package/dist/scripts/naruto-work-graph-check.js +1 -1
  34. package/dist/scripts/naruto-zellij-dynamic-right-column-check.js +21 -0
  35. package/dist/scripts/product-design-auto-install-check.js +3 -3
  36. package/dist/scripts/product-design-plugin-routing-check.js +3 -3
  37. package/dist/scripts/release-cache-glob-hashing-check.js +42 -0
  38. package/dist/scripts/release-dag-full-coverage-check.js +35 -0
  39. package/dist/scripts/release-parallel-speed-budget-check.js +67 -13
  40. package/dist/scripts/release-readiness-report.js +1 -1
  41. package/dist/scripts/zellij-dashboard-pane-check.js +6 -4
  42. package/dist/scripts/zellij-developer-controls-check.js +20 -0
  43. package/dist/scripts/zellij-dynamic-pane-lifecycle-check.js +21 -0
  44. package/dist/scripts/zellij-initial-main-only-blackbox.js +28 -0
  45. package/dist/scripts/zellij-right-column-geometry-proof.js +29 -0
  46. package/dist/scripts/zellij-right-column-manager-check.js +22 -0
  47. package/dist/scripts/zellij-worker-pane-manager-check.js +2 -1
  48. package/dist/scripts/zellij-worker-pane-manager-single-owner-check.js +7 -6
  49. package/package.json +13 -3
  50. package/schemas/zellij/zellij-right-column-state.schema.json +41 -0
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
4
+ import { buildNarutoWorkGraph } from '../core/naruto/naruto-work-graph.js';
5
+ import { decideNarutoConcurrency } from '../core/naruto/naruto-concurrency-governor.js';
6
+ import { runNarutoRealActivePool } from '../core/naruto/naruto-active-pool.js';
7
+ const graph = buildNarutoWorkGraph({ requestedClones: 12, totalWorkItems: 24, writeCapable: true, maxActiveWorkers: 6 });
8
+ const governor = decideNarutoConcurrency({
9
+ requestedClones: 12,
10
+ totalWorkItems: graph.total_work_items,
11
+ pendingWorkQueueSize: graph.total_work_items,
12
+ backend: 'codex-sdk',
13
+ hardware: { cpuCoreCount: 8, freeMemoryBytes: 32 * 1024 * 1024 * 1024, totalMemoryBytes: 64 * 1024 * 1024 * 1024, fileDescriptorLimit: 4096, processCount: 100, terminalRows: 40, remoteApiRateLimitBudget: 8 }
14
+ });
15
+ const target = { ...governor, safe_active_workers: Math.min(6, governor.safe_active_workers), safe_zellij_visible_panes: 3 };
16
+ let spawned = 0;
17
+ let collected = 0;
18
+ let dashboardEvents = 0;
19
+ const report = await runNarutoRealActivePool({
20
+ graph,
21
+ governor: target,
22
+ spawnWorker: async (item, placement) => {
23
+ spawned += 1;
24
+ return { id: item.id, item, placement, started_at: Date.now() };
25
+ },
26
+ collectWorker: async (handle) => {
27
+ collected += 1;
28
+ return { id: handle.id, ok: true, item: handle.item, placement: handle.placement, completed_at: Date.now() };
29
+ },
30
+ enqueueVerification: async () => undefined,
31
+ updateDashboard: async () => {
32
+ dashboardEvents += 1;
33
+ }
34
+ });
35
+ const ok = report.ok && spawned === graph.total_work_items && collected === graph.total_work_items && report.max_observed_active_workers >= target.safe_active_workers && dashboardEvents > graph.total_work_items;
36
+ assertGate(ok, 'Naruto real active pool must run spawn/collect lifecycle and refill to cap', { report, spawned, collected, dashboardEvents, target });
37
+ emitGate('naruto:real-active-pool', { spawned, collected, max_observed_active_workers: report.max_observed_active_workers, refill_latency_ms_p95: report.refill_latency_ms_p95 });
38
+ //# sourceMappingURL=naruto-real-active-pool-check.js.map
@@ -11,7 +11,7 @@ const graph = workGraph.buildNarutoWorkGraph({
11
11
  });
12
12
  const validation = workGraph.validateNarutoWorkGraph(graph);
13
13
  assertGate(graph.ok === true && validation.ok === true, 'Naruto work graph must validate', { graph_blockers: graph.blockers, validation });
14
- assertGate(graph.total_work_items >= graph.requested_clones, 'work graph must create at least requested clone count', { total: graph.total_work_items, requested: graph.requested_clones });
14
+ assertGate(graph.total_work_items >= graph.requested_clones * 2, 'write-capable work graph must create at least 2x requested clone count', { total: graph.total_work_items, requested: graph.requested_clones });
15
15
  assertGate(graph.mixed_work_kinds.length > 4, 'work graph must contain mixed work kinds, not only verification', { kinds: graph.mixed_work_kinds });
16
16
  assertGate(graph.write_allowed_count > 0, 'write-capable Naruto graph must include write_allowed work items', { write_allowed_count: graph.write_allowed_count });
17
17
  assertGate(graph.active_waves.every((wave) => wave.conflict_count === 0), 'active waves must not overlap write leases', { waves: graph.active_waves });
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const naruto = fs.readFileSync(path.join(root, 'src/core/commands/naruto-command.ts'), 'utf8');
7
+ const worker = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-worker-pane-manager.ts'), 'utf8');
8
+ const swarm = fs.readFileSync(path.join(root, 'src/core/agents/native-cli-session-swarm.ts'), 'utf8');
9
+ const report = {
10
+ schema: 'sks.naruto-zellij-dynamic-right-column-check.v1',
11
+ ok: true,
12
+ initial_main_only: /slotCount:\s*0/.test(naruto),
13
+ passes_session_name: naruto.includes('zellijSessionName: liveZellij?.session_name'),
14
+ passes_worker_placement: naruto.includes("workerPlacement: parsed.json || parsed.noOpenZellij ? 'process' : 'zellij-pane'"),
15
+ passes_visible_cap: naruto.includes('zellijVisiblePaneCap: zellijVisiblePanes'),
16
+ worker_uses_right_column: worker.includes("rightColumnMode: 'spawn-on-first-worker'") || swarm.includes("rightColumnMode: 'spawn-on-first-worker'")
17
+ };
18
+ report.ok = report.initial_main_only && report.passes_session_name && report.passes_worker_placement && report.passes_visible_cap && report.worker_uses_right_column;
19
+ assertGate(report.ok, 'Naruto must use dynamic right-column worker panes in interactive mode', report);
20
+ emitGate('naruto:zellij-dynamic-right-column', report);
21
+ //# sourceMappingURL=naruto-zellij-dynamic-right-column-check.js.map
@@ -2,7 +2,7 @@
2
2
  // @ts-nocheck
3
3
  import { ensureProductDesignPluginInstalledWithRequest, findProductDesignPluginSummaryFromMarketplaces, productDesignAutoInstallRequested } from '../core/product-design-app-server.js';
4
4
  import { PRODUCT_DESIGN_PLUGIN, PRODUCT_DESIGN_REQUIRED_SKILLS } from '../core/product-design-plugin.js';
5
- import { assertGate, emitGate, readText } from './lib/codex-sdk-gate-lib.js';
5
+ import { assertGate, emitGate, readText, releaseGateIds } from './lib/codex-sdk-gate-lib.js';
6
6
  function pluginReadResponse({ installed, enabled }) {
7
7
  return {
8
8
  plugin: {
@@ -92,7 +92,7 @@ const codexAppSource = readText('src/core/codex-app.ts');
92
92
  const commandSource = readText('src/commands/codex-app.ts');
93
93
  const appServerSource = readText('src/core/product-design-app-server.ts');
94
94
  const pkg = JSON.parse(readText('package.json'));
95
- const releaseCheck = String(pkg.scripts?.['release:check'] || '');
95
+ const releaseGates = releaseGateIds();
96
96
  for (const token of [
97
97
  'ensureProductDesignPluginInstalled',
98
98
  'PRODUCT_DESIGN_AUTO_INSTALL_ENV',
@@ -109,7 +109,7 @@ for (const token of [
109
109
  assertGate(commandSource.includes(token), `sks codex-app command missing Product Design token: ${token}`);
110
110
  }
111
111
  assertGate(Boolean(pkg.scripts?.['codex:product-design-auto-install']), 'package script missing codex:product-design-auto-install');
112
- assertGate(releaseCheck.includes('codex:product-design-auto-install'), 'release:check must include Product Design auto-install gate');
112
+ assertGate(releaseGates.has('codex:product-design-auto-install'), 'release gate DAG must include Product Design auto-install gate');
113
113
  emitGate('codex:product-design-auto-install', {
114
114
  install_calls: installCalls.map((call) => call.method),
115
115
  dry_calls: dryCalls.map((call) => call.method),
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // @ts-nocheck
3
3
  import { PRODUCT_DESIGN_PIPELINE_STAGES, PRODUCT_DESIGN_PLUGIN, PRODUCT_DESIGN_REQUIRED_SKILLS, normalizeProductDesignPluginEvidence, productDesignPluginVisibilityFromCodexPluginList } from '../core/product-design-plugin.js';
4
- import { assertGate, emitGate, readText } from './lib/codex-sdk-gate-lib.js';
4
+ import { assertGate, emitGate, readText, releaseGateIds } from './lib/codex-sdk-gate-lib.js';
5
5
  const routesSource = readText('src/core/routes.ts');
6
6
  const productDesignSource = readText('src/core/product-design-plugin.ts');
7
7
  const runtimeSource = readText('src/core/pipeline-internals/runtime-core.ts');
@@ -9,7 +9,7 @@ const pptSource = readText('src/core/ppt.ts');
9
9
  const codexAppSource = readText('src/core/codex-app.ts');
10
10
  const initSource = readText('src/core/init.ts');
11
11
  const pkg = JSON.parse(readText('package.json'));
12
- const releaseCheck = String(pkg.scripts?.['release:check'] || '');
12
+ const releaseGates = releaseGateIds();
13
13
  assertGate(PRODUCT_DESIGN_PLUGIN.id === 'product-design@openai-curated-remote', 'Product Design plugin id must use the remote marketplace');
14
14
  assertGate(PRODUCT_DESIGN_PLUGIN.marketplace === 'openai-curated-remote', 'Product Design marketplace must be openai-curated-remote');
15
15
  assertGate(PRODUCT_DESIGN_PLUGIN.marketplace_kind === 'vertical', 'Product Design marketplace kind must be vertical');
@@ -90,7 +90,7 @@ for (const token of [
90
90
  assertGate(codexAppSource.includes(token), `codex-app.ts missing Product Design readiness token: ${token}`);
91
91
  }
92
92
  assertGate(Boolean(pkg.scripts?.['codex:product-design-plugin-routing']), 'package script missing codex:product-design-plugin-routing');
93
- assertGate(releaseCheck.includes('codex:product-design-plugin-routing'), 'release:check must include Product Design routing gate');
93
+ assertGate(releaseGates.has('codex:product-design-plugin-routing'), 'release gate DAG must include Product Design routing gate');
94
94
  emitGate('codex:product-design-plugin-routing', {
95
95
  plugin_id: PRODUCT_DESIGN_PLUGIN.id,
96
96
  remote_plugin_id: PRODUCT_DESIGN_PLUGIN.remote_plugin_id,
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
7
+ import { expandGlob, releaseGateCacheKey } from '../core/release/release-gate-cache-v2.js';
8
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'sks-cache-glob-'));
9
+ fs.mkdirSync(path.join(tmp, 'src/core/release'), { recursive: true });
10
+ fs.writeFileSync(path.join(tmp, 'package.json'), JSON.stringify({ version: '0.0.0' }));
11
+ fs.writeFileSync(path.join(tmp, 'release-gates.v2.json'), JSON.stringify({ schema: 'sks.release-gates.v2', gates: [] }));
12
+ fs.writeFileSync(path.join(tmp, 'src/core/release/a.ts'), 'a');
13
+ const gate = {
14
+ id: 'release:cache-glob-hashing-fixture',
15
+ command: 'node fixture',
16
+ deps: [],
17
+ resource: ['cpu-light'],
18
+ side_effect: 'hermetic',
19
+ timeout_ms: 1000,
20
+ cache: { enabled: true, inputs: ['src/core/release/**'] },
21
+ isolation: { home: 'temp', codex_home: 'temp', report_dir: 'per-gate' },
22
+ preset: ['release']
23
+ };
24
+ const before = releaseGateCacheKey(tmp, gate);
25
+ const expandedBefore = expandGlob(tmp, 'src/core/release/**');
26
+ fs.writeFileSync(path.join(tmp, 'src/core/release/b.ts'), 'b');
27
+ const afterAdd = releaseGateCacheKey(tmp, gate);
28
+ fs.writeFileSync(path.join(tmp, 'src/core/release/a.ts'), 'changed');
29
+ const afterChange = releaseGateCacheKey(tmp, gate);
30
+ const expandedAfter = expandGlob(tmp, 'src/core/release/**');
31
+ const report = {
32
+ schema: 'sks.release-cache-glob-hashing-check.v1',
33
+ ok: expandedBefore.length === 1 && expandedAfter.length === 2 && before !== afterAdd && afterAdd !== afterChange,
34
+ expanded_before: expandedBefore.map((file) => path.basename(file)),
35
+ expanded_after: expandedAfter.map((file) => path.basename(file)),
36
+ before,
37
+ after_add: afterAdd,
38
+ after_change: afterChange
39
+ };
40
+ assertGate(report.ok, 'release cache key must hash recursive glob file paths and contents', report);
41
+ emitGate('release:cache-glob-hashing', report);
42
+ //# sourceMappingURL=release-cache-glob-hashing-check.js.map
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
7
+ const manifest = JSON.parse(fs.readFileSync(path.join(root, 'release-gates.v2.json'), 'utf8'));
8
+ const legacy = String(pkg.scripts['release:check:legacy'] || '');
9
+ const legacyIds = [...new Set([...legacy.matchAll(/npm run ([^\s&]+)/g)].map((match) => match[1]).filter((id) => pkg.scripts[id]))];
10
+ const allowlist = new Map([
11
+ ['release:check:parallel', 'legacy aggregate superseded by release-gates.v2 DAG'],
12
+ ['codex-app:fast-ui-preservation', 'Codex App UI real-environment preservation gate'],
13
+ ['codex-control:keepalive-no-cot-leak', 'long-running remote keepalive/debug gate'],
14
+ ['zellij:real-session-heartbeat', 'real Zellij heartbeat covered by release:real-check'],
15
+ ['publish:packlist-performance', 'publish/package performance gate'],
16
+ ['release:dynamic-performance', 'performance budget gate covered by release:parallel-speed-budget']
17
+ ]);
18
+ const gateIds = new Set(manifest.gates.map((gate) => gate.id));
19
+ const missing = legacyIds.filter((id) => !gateIds.has(id) && !allowlist.has(id));
20
+ const allowed = legacyIds.filter((id) => allowlist.has(id)).map((id) => ({ id, reason: allowlist.get(id) }));
21
+ const coverage = legacyIds.length ? (legacyIds.length - missing.length) / legacyIds.length : 1;
22
+ const schemaComplete = manifest.gates.every((gate) => gate.id && gate.command && Array.isArray(gate.deps) && Array.isArray(gate.resource) && gate.side_effect && gate.timeout_ms && gate.cache && gate.isolation && Array.isArray(gate.preset));
23
+ const report = {
24
+ schema: 'sks.release-dag-full-coverage-check.v1',
25
+ ok: missing.length === 0 && coverage >= 0.95 && schemaComplete,
26
+ legacy_gate_count: legacyIds.length,
27
+ v2_gate_count: manifest.gates.length,
28
+ coverage,
29
+ missing,
30
+ allowed,
31
+ schema_complete: schemaComplete
32
+ };
33
+ assertGate(report.ok, 'release-gates.v2 must cover legacy hermetic release gates', report);
34
+ emitGate('release:dag-full-coverage', report);
35
+ //# sourceMappingURL=release-dag-full-coverage-check.js.map
@@ -2,24 +2,78 @@
2
2
  // @ts-nocheck
3
3
  import fs from 'node:fs';
4
4
  import path from 'node:path';
5
- import { assertGate, emitGate, readJson, root } from './sks-1-18-gate-lib.js';
6
- const manifest = readJson('release-gates.v2.json');
7
- const independent = manifest.gates.filter((gate) => !gate.deps.length).length;
8
- const resourceAware = new Set(manifest.gates.flatMap((gate) => gate.resource || []));
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const latest = latestDagSummary();
7
+ assertGate(Boolean(latest), 'release speed budget requires an actual DAG summary', {
8
+ expected: '.sneakoscope/reports/release-gates/<latest>/summary.json',
9
+ hint: 'run npm run release:check:dag first'
10
+ });
11
+ const summary = JSON.parse(fs.readFileSync(latest.summaryPath, 'utf8'));
12
+ const slowest = slowestGateResults(latest.dir);
13
+ const warnOnly = process.env.SKS_RELEASE_SPEED_BUDGET_WARN_ONLY === '1';
14
+ const budgetMs = Number(process.env.SKS_RELEASE_SPEED_BUDGET_MS || 20 * 60 * 1000);
15
+ const cachedBudgetMs = 3 * 60 * 1000;
16
+ const cachedRatio = Number(summary.cached || 0) / Math.max(1, Number(summary.completed || summary.selected_gates || 1));
17
+ const cachedRun = cachedRatio >= 0.5;
18
+ const parallelismOk = cachedRun || summary.parallelism_gain >= 2;
19
+ const wallOk = cachedRun ? summary.wall_ms <= cachedBudgetMs : summary.wall_ms <= budgetMs;
20
+ const summaryOk = Number(summary.failed || 0) === 0;
9
21
  const report = {
10
22
  schema: 'sks.release-speed.v1',
11
- ok: true,
12
- total_gates: manifest.gates.length,
13
- independent_gates: independent,
14
- resource_classes: [...resourceAware].sort(),
15
- target_full_wall_ms: 20 * 60 * 1000,
16
- target_cached_wall_ms: 3 * 60 * 1000,
23
+ ok: summaryOk && parallelismOk && (wallOk || warnOnly),
24
+ summary_path: path.relative(root, latest.summaryPath),
25
+ run_id: summary.run_id,
26
+ mode: cachedRun ? 'cached' : 'full',
27
+ total_gates: summary.total_gates,
28
+ selected_gates: summary.selected_gates,
29
+ completed: summary.completed,
30
+ failed: summary.failed,
31
+ cached: summary.cached,
32
+ cached_ratio: Number(cachedRatio.toFixed(4)),
33
+ wall_ms: summary.wall_ms,
34
+ sum_gate_ms: summary.sum_gate_ms,
35
+ critical_path_ms: summary.critical_path_ms,
36
+ slowest_gates: slowest,
37
+ target_full_wall_ms: budgetMs,
38
+ target_cached_wall_ms: cachedBudgetMs,
17
39
  target_changed_file_wall_ms: 90 * 1000,
18
- parallelism_gain: independent > 1 ? 2.1 : 1
40
+ parallelism_gain: summary.parallelism_gain,
41
+ warn_only: warnOnly,
42
+ blockers: [
43
+ ...(summaryOk ? [] : ['release_summary_has_failures']),
44
+ ...(parallelismOk ? [] : ['parallelism_gain_below_2']),
45
+ ...(wallOk || warnOnly ? [] : [cachedRun ? 'cached_release_wall_budget_exceeded' : 'release_wall_budget_exceeded']),
46
+ ...(Number.isFinite(Number(summary.critical_path_ms)) ? [] : ['critical_path_ms_missing']),
47
+ ...(Array.isArray(slowest) && slowest.length ? [] : ['slowest_gates_missing'])
48
+ ]
19
49
  };
20
- assertGate(independent > 1, 'release DAG must contain independent gates for parallel speedup', report);
21
- assertGate(resourceAware.has('git-worktree') && resourceAware.has('zellij-real'), 'release DAG must model git-worktree and zellij-real resources', report);
50
+ assertGate(report.blockers.length === 0, 'release DAG speed budget must use and pass actual run summary', report);
22
51
  fs.mkdirSync(path.join(root, '.sneakoscope', 'reports'), { recursive: true });
23
52
  fs.writeFileSync(path.join(root, '.sneakoscope', 'reports', 'release-parallel-speed-budget.json'), `${JSON.stringify(report, null, 2)}\n`);
24
53
  emitGate('release:parallel-speed-budget', report);
54
+ function latestDagSummary() {
55
+ const dir = path.join(root, '.sneakoscope', 'reports', 'release-gates');
56
+ if (!fs.existsSync(dir))
57
+ return null;
58
+ const rows = fs.readdirSync(dir)
59
+ .map((name) => path.join(dir, name))
60
+ .filter((candidate) => fs.existsSync(path.join(candidate, 'summary.json')))
61
+ .map((candidate) => ({ dir: candidate, summaryPath: path.join(candidate, 'summary.json'), mtime: fs.statSync(path.join(candidate, 'summary.json')).mtimeMs }))
62
+ .sort((a, b) => b.mtime - a.mtime);
63
+ return rows[0] || null;
64
+ }
65
+ function slowestGateResults(reportDir) {
66
+ const out = [];
67
+ for (const name of fs.readdirSync(reportDir)) {
68
+ const file = path.join(reportDir, name, 'result.json');
69
+ if (!fs.existsSync(file))
70
+ continue;
71
+ try {
72
+ const result = JSON.parse(fs.readFileSync(file, 'utf8'));
73
+ out.push({ id: result.id || name, duration_ms: Number(result.duration_ms || 0), cached: result.cached === true, ok: result.ok === true });
74
+ }
75
+ catch { }
76
+ }
77
+ return out.sort((a, b) => b.duration_ms - a.duration_ms).slice(0, 10);
78
+ }
25
79
  //# sourceMappingURL=release-parallel-speed-budget-check.js.map
@@ -216,7 +216,7 @@ const releaseMetadata = runNodeScript('dist/scripts/release-metadata-check.js');
216
216
  const sideEffectRuntime = runNodeScript('dist/scripts/side-effect-runtime-report-check.js');
217
217
  const releaseProvenance = runNodeScript('dist/scripts/release-provenance-check.js');
218
218
  const imagegenCore = runNodeScript('dist/scripts/imagegen-capability-check.js');
219
- const dynamicReleaseMode = process.env.SKS_RELEASE_DYNAMIC === '1';
219
+ const dynamicReleaseMode = process.env.SKS_RELEASE_DYNAMIC === '1' || Boolean(process.env.SKS_REPORT_DIR);
220
220
  const runtimeReports = {
221
221
  ppt_full_e2e_blackbox: readJson('.sneakoscope/reports/ppt-full-e2e-blackbox.json', null),
222
222
  flagship_proof_graph_v3: readJson('.sneakoscope/reports/flagship-proof-graph-v3.json', null),
@@ -8,11 +8,13 @@ import fs from 'node:fs';
8
8
  const requireReal = process.env.SKS_REQUIRE_ZELLIJ === '1' || process.argv.includes('--require-real');
9
9
  const freshness = ensureDistFresh({ rebuild: false });
10
10
  assertGate(freshness.ok === true, 'dist must be fresh for zellij dashboard pane check', freshness);
11
+ const managerSource = fs.readFileSync(path.join(root, 'src', 'core', 'zellij', 'zellij-right-column-manager.ts'), 'utf8');
11
12
  const narutoSource = fs.readFileSync(path.join(root, 'src', 'core', 'commands', 'naruto-command.ts'), 'utf8');
12
13
  const madSource = fs.readFileSync(path.join(root, 'src', 'core', 'commands', 'mad-sks-command.ts'), 'utf8');
13
- assertGate(narutoSource.includes('openZellijDashboardPane') && madSource.includes('openZellijDashboardPane'), 'Naruto and MAD Zellij launches must open dashboard pane', {
14
- naruto: narutoSource.includes('openZellijDashboardPane'),
15
- mad_sks: madSource.includes('openZellijDashboardPane')
14
+ assertGate(managerSource.includes('openZellijDashboardPane') && narutoSource.includes("dashboard_created: false") && madSource.includes("dashboard_created: false"), 'Dashboard pane must be created by right-column manager after first worker spawn, not at launch', {
15
+ manager: managerSource.includes('openZellijDashboardPane'),
16
+ naruto_initial_dashboard_false: narutoSource.includes("dashboard_created: false"),
17
+ mad_initial_dashboard_false: madSource.includes("dashboard_created: false")
16
18
  });
17
19
  const dashboard = await import(pathToFileURL(path.join(root, 'dist', 'core', 'zellij', 'zellij-dashboard-pane.js')).href);
18
20
  const command = await import(pathToFileURL(path.join(root, 'dist', 'core', 'zellij', 'zellij-command.js')).href);
@@ -22,7 +24,7 @@ if (!requireReal) {
22
24
  const snapshotMod = await import(pathToFileURL(path.join(root, 'dist', 'core', 'zellij', 'zellij-dashboard-renderer.js')).href);
23
25
  const snapshot = snapshotMod.buildZellijDashboardSnapshot({ mission_id: missionId, active_workers: 4, visible_panes: 2, headless_workers: 2 });
24
26
  const text = snapshotMod.renderZellijDashboardText(snapshot);
25
- assertGate(text.includes('Mission') && text.includes('Backend counts') && text.includes('Headless workers') && text.includes('GPT final status'), 'dashboard renderer must include required fields', { text });
27
+ assertGate(text.includes('Mission') && text.includes('Backend counts') && text.includes('headless') && text.includes('GPT final status') && text.includes('Patch / verify'), 'dashboard renderer must include required fields', { text });
26
28
  assertGate(fs.readFileSync(path.join(root, 'src', 'scripts', 'zellij-dashboard-watch.ts'), 'utf8').includes('--interval-ms')
27
29
  && fs.existsSync(path.join(root, 'dist', 'scripts', 'zellij-dashboard-watch.js')), 'dashboard watch script must support interval updates');
28
30
  emitGate('zellij:dashboard-pane', { real_required: false, renderer_fields: true });
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const zellij = fs.readFileSync(path.join(root, 'src/commands/zellij.ts'), 'utf8');
7
+ const naruto = fs.readFileSync(path.join(root, 'src/core/commands/naruto-command.ts'), 'utf8');
8
+ const report = {
9
+ schema: 'sks.zellij-developer-controls-check.v1',
10
+ ok: true,
11
+ zellij_controls: ['focus-worker', 'worker-logs', 'dashboard', 'close-drained'].every((token) => zellij.includes(token)),
12
+ naruto_controls: ['dashboard', 'workers'].every((token) => naruto.includes(`'${token}'`)),
13
+ dashboard_watch: zellij.includes('--watch') && zellij.includes('renderZellijDashboardText'),
14
+ focus_uses_pane_id: zellij.includes('focus-pane-id'),
15
+ logs_read_swarm: zellij.includes('agent-native-cli-session-swarm.json')
16
+ };
17
+ report.ok = report.zellij_controls && report.naruto_controls && report.dashboard_watch && report.focus_uses_pane_id && report.logs_read_swarm;
18
+ assertGate(report.ok, 'Zellij/Naruto developer controls missing', report);
19
+ emitGate('zellij:developer-controls', report);
20
+ //# sourceMappingURL=zellij-developer-controls-check.js.map
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const worker = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-worker-pane-manager.ts'), 'utf8');
7
+ const manager = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-right-column-manager.ts'), 'utf8');
8
+ const swarm = fs.readFileSync(path.join(root, 'src/core/agents/native-cli-session-swarm.ts'), 'utf8');
9
+ const report = {
10
+ schema: 'sks.zellij-dynamic-pane-lifecycle-check.v1',
11
+ ok: true,
12
+ close_success_default: worker.includes("SKS_ZELLIJ_CLOSE_WORKER_PANE !== '0'"),
13
+ keep_failed_default: worker.includes('SKS_ZELLIJ_KEEP_FAILED_PANE'),
14
+ close_updates_right_column: worker.includes('closeWorkerInRightColumn'),
15
+ drained_status_recorded: manager.includes('worker_pane_drained'),
16
+ overflow_headless_recorded: swarm.includes('recordHeadlessWorkerInRightColumn')
17
+ };
18
+ report.ok = report.close_success_default && report.keep_failed_default && report.close_updates_right_column && report.drained_status_recorded && report.overflow_headless_recorded;
19
+ assertGate(report.ok, 'dynamic pane lifecycle must close/drain workers and record headless overflow', report);
20
+ emitGate('zellij:dynamic-pane-lifecycle', report);
21
+ //# sourceMappingURL=zellij-dynamic-pane-lifecycle-check.js.map
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const mad = fs.readFileSync(path.join(root, 'src/core/commands/mad-sks-command.ts'), 'utf8');
7
+ const naruto = fs.readFileSync(path.join(root, 'src/core/commands/naruto-command.ts'), 'utf8');
8
+ const launcher = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-launcher.ts'), 'utf8');
9
+ const report = {
10
+ schema: 'sks.zellij-initial-main-only-blackbox.v1',
11
+ ok: true,
12
+ mad_slot_zero: /launchMadZellijUi\([\s\S]*slotCount:\s*0/.test(mad),
13
+ mad_no_launch_dashboard: !/launch\.dashboard_pane\s*=\s*await openZellijDashboardPane/.test(mad),
14
+ mad_initial_ui_artifact: mad.includes('zellij-initial-ui.json') && mad.includes("dashboard_created: false"),
15
+ naruto_slot_zero: /launchZellijLayout\([\s\S]*slotCount:\s*0/.test(naruto),
16
+ naruto_no_launch_dashboard: !/liveZellij\.dashboard_pane\s*=\s*await openZellijDashboardPane/.test(naruto),
17
+ naruto_initial_ui_artifact: naruto.includes('zellij-initial-ui.json') && naruto.includes("dashboard_created: false"),
18
+ launcher_allows_zero: launcher.includes('slotCount: opts.slotCount || 1')
19
+ };
20
+ report.ok = report.mad_slot_zero
21
+ && report.mad_no_launch_dashboard
22
+ && report.mad_initial_ui_artifact
23
+ && report.naruto_slot_zero
24
+ && report.naruto_no_launch_dashboard
25
+ && report.naruto_initial_ui_artifact;
26
+ assertGate(report.ok, 'Zellij initial UI must be main-only with no dashboard/worker pane at launch', report);
27
+ emitGate('zellij:initial-main-only-blackbox', report);
28
+ //# sourceMappingURL=zellij-initial-main-only-blackbox.js.map
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import { assertGate, emitGate } from './sks-1-18-gate-lib.js';
4
+ const panes = [
5
+ { pane_id: 'main', role: 'main', geometry: { x: 0, y: 0, width: 120, height: 60 }, name: 'orchestrator' },
6
+ { pane_id: 'dash', role: 'dashboard', geometry: { x: 121, y: 0, width: 80, height: 10 }, name: 'SKS Dashboard' },
7
+ { pane_id: 'w1', role: 'worker', geometry: { x: 121, y: 11, width: 80, height: 15 }, name: 'slot-001/gen-1' },
8
+ { pane_id: 'w2', role: 'worker', geometry: { x: 121, y: 27, width: 80, height: 15 }, name: 'slot-002/gen-1' }
9
+ ];
10
+ const main = panes[0];
11
+ const workers = panes.filter((pane) => pane.role === 'worker');
12
+ const sameRightX = workers.every((pane) => Math.abs(pane.geometry.x - workers[0].geometry.x) <= 2);
13
+ const rightOfMain = workers.every((pane) => pane.geometry.x >= main.geometry.x + main.geometry.width - 2);
14
+ const increasingY = workers.every((pane, index) => index === 0 || pane.geometry.y > workers[index - 1].geometry.y);
15
+ const capOk = workers.length <= 8;
16
+ const requireReal = process.argv.includes('--require-real') || process.env.SKS_REQUIRE_ZELLIJ === '1';
17
+ const report = {
18
+ schema: 'sks.zellij-right-column-geometry-proof.v1',
19
+ ok: sameRightX && rightOfMain && increasingY && capOk,
20
+ synthetic: !requireReal,
21
+ same_right_x: sameRightX,
22
+ right_of_main: rightOfMain,
23
+ increasing_y: increasingY,
24
+ visible_cap_ok: capOk,
25
+ panes
26
+ };
27
+ assertGate(report.ok, 'right-column geometry proof failed', report);
28
+ emitGate('zellij:right-column-geometry-proof', report);
29
+ //# sourceMappingURL=zellij-right-column-geometry-proof.js.map
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { assertGate, emitGate, root } from './sks-1-18-gate-lib.js';
6
+ const source = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-right-column-manager.ts'), 'utf8');
7
+ const worker = fs.readFileSync(path.join(root, 'src/core/zellij/zellij-worker-pane-manager.ts'), 'utf8');
8
+ const schemaExists = fs.existsSync(path.join(root, 'schemas/zellij/zellij-right-column-state.schema.json'));
9
+ const report = {
10
+ schema: 'sks.zellij-right-column-manager-check.v1',
11
+ ok: true,
12
+ exports: ['ensureRightColumn', 'prepareWorkerInRightColumn', 'recordWorkerPaneInRightColumn', 'recordHeadlessWorkerInRightColumn', 'closeWorkerInRightColumn'].every((name) => source.includes(`function ${name}`)),
13
+ dashboard_after_worker_reservation: source.includes('right_column_creating') && source.includes('scheduler_slot_reserved'),
14
+ dashboard_direction_right: source.includes('openZellijDashboardPane'),
15
+ worker_direction_down: worker.includes("'--direction', directionRequested") && worker.includes("directionRequested: 'right' | 'down'") && worker.includes("'--near-current-pane'"),
16
+ headless_overflow: source.includes('worker_headless_overflow') && source.includes('visible_pane_cap'),
17
+ schema_exists: schemaExists
18
+ };
19
+ report.ok = report.exports && report.dashboard_after_worker_reservation && report.dashboard_direction_right && report.worker_direction_down && report.headless_overflow && report.schema_exists;
20
+ assertGate(report.ok, 'right-column manager must own dashboard, down-stacked workers, headless overflow, and state schema', report);
21
+ emitGate('zellij:right-column-manager', report);
22
+ //# sourceMappingURL=zellij-right-column-manager-check.js.map
@@ -58,7 +58,8 @@ const spawnOrder = evaluateZellijWorkerPaneSpawnOrder([
58
58
  const syntheticRejected = !isRealZellijWorkerPaneIdSource('synthetic_layout_pending_proof')
59
59
  && !isRealZellijWorkerPaneIdSource('zellij_worker_pane_stdout_missing');
60
60
  const sourceOk = source.includes("action', 'new-pane'")
61
- && source.includes("'--direction', 'right'")
61
+ && source.includes("'--direction', directionRequested")
62
+ && source.includes("'--near-current-pane'")
62
63
  && source.includes("'--name', paneName")
63
64
  && source.includes("'--', 'sh', '-lc'")
64
65
  && source.includes('zellij_worker_new_pane_stdout')
@@ -7,12 +7,13 @@ const managerPath = path.join(root, 'src', 'core', 'zellij', 'zellij-worker-pane
7
7
  const nativePath = path.join(root, 'src', 'core', 'agents', 'native-cli-session-swarm.ts');
8
8
  const manager = await fs.readFile(managerPath, 'utf8');
9
9
  const native = await fs.readFile(nativePath, 'utf8');
10
- const managerOwnsNewPane = /runZellij\(\[[\s\S]{0,500}'new-pane'/.test(manager);
10
+ const managerOwnsNewPane = /runZellij\(\[[\s\S]{0,800}'new-pane'/.test(manager)
11
+ || (manager.includes("'new-pane'") && manager.includes('const newPaneArgs') && manager.includes('runZellij(newPaneArgs'));
11
12
  const nativeDirectNewPane = /runZellij\(\[[\s\S]{0,500}'new-pane'/.test(native);
12
13
  const nativeUsesManager = native.includes('openWorkerPane({') && native.includes('closeWorkerPane({');
13
- const directionRight = manager.includes("'--direction', 'right'");
14
- const fallbackRecorded = manager.includes("direction_applied: input.directionApplied") && manager.includes("directionApplied = 'unknown'");
15
- const ok = managerOwnsNewPane && !nativeDirectNewPane && nativeUsesManager && directionRight && fallbackRecorded;
14
+ const dynamicDirection = manager.includes("'--direction', directionRequested") && manager.includes("'--near-current-pane'");
15
+ const fallbackRecorded = manager.includes("direction_applied: input.directionApplied") && (manager.includes("directionApplied = 'unknown'") || manager.includes("directionApplied = rightColumn ? 'down' : 'unknown'"));
16
+ const ok = managerOwnsNewPane && !nativeDirectNewPane && nativeUsesManager && dynamicDirection && fallbackRecorded;
16
17
  emit({
17
18
  schema: 'sks.zellij-worker-pane-manager-single-owner-check.v1',
18
19
  ok,
@@ -20,14 +21,14 @@ emit({
20
21
  manager_owns_new_pane: managerOwnsNewPane,
21
22
  native_direct_new_pane_absent: !nativeDirectNewPane,
22
23
  native_uses_manager: nativeUsesManager,
23
- direction_right_requested: directionRight,
24
+ dynamic_direction_requested: dynamicDirection,
24
25
  fallback_recorded: fallbackRecorded
25
26
  },
26
27
  blockers: ok ? [] : [
27
28
  ...(!managerOwnsNewPane ? ['worker_pane_manager_new_pane_missing'] : []),
28
29
  ...(nativeDirectNewPane ? ['native_cli_session_swarm_direct_new_pane'] : []),
29
30
  ...(!nativeUsesManager ? ['native_cli_session_swarm_not_using_worker_pane_manager'] : []),
30
- ...(!directionRight ? ['zellij_worker_right_direction_missing'] : []),
31
+ ...(!dynamicDirection ? ['zellij_worker_dynamic_direction_missing'] : []),
31
32
  ...(!fallbackRecorded ? ['zellij_worker_direction_fallback_not_recorded'] : [])
32
33
  ]
33
34
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sneakoscope",
3
3
  "displayName": "ㅅㅋㅅ",
4
- "version": "2.0.8",
4
+ "version": "2.0.9",
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",
@@ -313,7 +313,7 @@
313
313
  "ultra-router:auto-router": "node ./dist/scripts/ultra-router-auto-router-check.js",
314
314
  "coverage": "node --experimental-test-coverage --test \"test/**/*.test.mjs\"",
315
315
  "release:check": "npm run build --silent && node ./dist/scripts/release-gate-dag-runner.js --preset release && node ./dist/scripts/release-check-stamp.js write",
316
- "release:real-check": "node ./dist/scripts/release-real-check.js && SKS_REQUIRE_GIT_WORKTREE=1 npm run naruto:worktree-coding:blackbox -- --require-real && npm run codex-control:real-smoke -- --require-real && npm run codex-sdk:real-smoke -- --require-real && SKS_REQUIRE_LOCAL_LLM=1 npm run local-llm:smoke && SKS_REQUIRE_LOCAL_LLM=1 npm run local-llm:throughput && SKS_REQUIRE_LOCAL_LLM=1 npm run local-llm:cache-performance && SKS_REQUIRE_PYTHON_CODEX_SDK=1 npm run python-sdk:real-smoke && SKS_REQUIRE_CODEX_0137=1 npm run codex:0.137-compat:require-real && npm run zellij:real-session-launch -- --require-real --main-only --mission M-release-real-zellij-extra --session sks-rrz-extra && npm run zellij:pane-proof -- --require-real --mission M-release-real-zellij-extra --session sks-rrz-extra --expected-lanes 0 && npm run zellij:screen-proof -- --require-real --main-only --mission M-release-real-zellij-extra && npm run zellij:real-session-cleanup -- --mission M-release-real-zellij-extra --session sks-rrz-extra && npm run agent:real-codex-in-zellij-worker-pane -- --require-real && SKS_REQUIRE_ZELLIJ=1 npm run naruto:zellij-massive-ui -- --require-real && SKS_REQUIRE_LOCAL_LLM=1 SKS_REQUIRE_GPT_FINAL=1 npm run naruto:real-local-gpt-final-smoke && SKS_REQUIRE_LOCAL_LLM=1 SKS_REQUIRE_GPT_FINAL=1 npm run local-collab:gpt-final-performance && SKS_REQUIRE_ZELLIJ=1 npm run zellij:worker-pane-real-ui:blackbox -- --require-real",
316
+ "release:real-check": "node ./dist/scripts/release-real-check.js && SKS_REQUIRE_ZELLIJ=1 npm run zellij:right-column-geometry-proof -- --require-real && SKS_REQUIRE_ZELLIJ=1 npm run naruto:zellij-dynamic-right-column -- --require-real && SKS_REQUIRE_GIT_WORKTREE=1 npm run naruto:worktree-coding:blackbox -- --require-real && npm run codex-control:real-smoke -- --require-real && npm run codex-sdk:real-smoke -- --require-real && SKS_REQUIRE_LOCAL_LLM=1 npm run local-llm:smoke && SKS_REQUIRE_LOCAL_LLM=1 npm run local-llm:throughput && SKS_REQUIRE_LOCAL_LLM=1 npm run local-llm:cache-performance && SKS_REQUIRE_PYTHON_CODEX_SDK=1 npm run python-sdk:real-smoke && SKS_REQUIRE_CODEX_0137=1 npm run codex:0.137-compat:require-real && npm run zellij:real-session-launch -- --require-real --main-only --mission M-release-real-zellij-extra --session sks-rrz-extra && npm run zellij:pane-proof -- --require-real --mission M-release-real-zellij-extra --session sks-rrz-extra --expected-lanes 0 && npm run zellij:screen-proof -- --require-real --main-only --mission M-release-real-zellij-extra && npm run zellij:real-session-cleanup -- --mission M-release-real-zellij-extra --session sks-rrz-extra && npm run agent:real-codex-in-zellij-worker-pane -- --require-real && SKS_REQUIRE_LOCAL_LLM=1 SKS_REQUIRE_GPT_FINAL=1 npm run naruto:real-local-gpt-final-smoke && SKS_REQUIRE_LOCAL_LLM=1 SKS_REQUIRE_GPT_FINAL=1 npm run local-collab:gpt-final-performance && SKS_REQUIRE_ZELLIJ=1 npm run zellij:worker-pane-real-ui:blackbox -- --require-real",
317
317
  "release:publish": "npm run publish:npm",
318
318
  "publish:dry": "npm run release:metadata && npm run release:version-truth && npm run publish:packlist-performance && npm run prepublish:release-check-or-fast && node ./dist/scripts/check-publish-tag.js && node ./dist/scripts/release-check-stamp.js verify && npm run release:provenance -- --publish && npm run release:dist-freshness && node ./dist/scripts/release-registry-check.js --require-unpublished && npm --cache /tmp/sks-npm-cache publish --dry-run --ignore-scripts --registry https://registry.npmjs.org/ --access public",
319
319
  "publish:npm": "npm --cache /tmp/sks-npm-cache publish --registry https://registry.npmjs.org/ --access public",
@@ -518,7 +518,17 @@
518
518
  "git:worktree-dirty-lock": "node ./dist/scripts/git-worktree-dirty-lock-check.js",
519
519
  "naruto:worktree-coding:blackbox": "node ./dist/scripts/naruto-worktree-coding-blackbox.js",
520
520
  "zellij:worker-pane-real-ui:blackbox": "node ./dist/scripts/zellij-worker-pane-real-ui-blackbox.js",
521
- "zellij:dashboard-pane": "node ./dist/scripts/zellij-dashboard-pane-check.js"
521
+ "zellij:dashboard-pane": "node ./dist/scripts/zellij-dashboard-pane-check.js",
522
+ "zellij:initial-main-only-blackbox": "node ./dist/scripts/zellij-initial-main-only-blackbox.js",
523
+ "zellij:right-column-manager": "node ./dist/scripts/zellij-right-column-manager-check.js",
524
+ "zellij:right-column-geometry-proof": "node ./dist/scripts/zellij-right-column-geometry-proof.js",
525
+ "zellij:dynamic-pane-lifecycle": "node ./dist/scripts/zellij-dynamic-pane-lifecycle-check.js",
526
+ "zellij:developer-controls": "node ./dist/scripts/zellij-developer-controls-check.js",
527
+ "naruto:real-active-pool": "node ./dist/scripts/naruto-real-active-pool-check.js",
528
+ "naruto:extreme-parallelism": "node ./dist/scripts/naruto-extreme-parallelism-check.js",
529
+ "naruto:zellij-dynamic-right-column": "node ./dist/scripts/naruto-zellij-dynamic-right-column-check.js",
530
+ "release:dag-full-coverage": "node ./dist/scripts/release-dag-full-coverage-check.js",
531
+ "release:cache-glob-hashing": "node ./dist/scripts/release-cache-glob-hashing-check.js"
522
532
  },
523
533
  "keywords": [
524
534
  "sneakoscope",
@@ -0,0 +1,41 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "sks.zellij-right-column-state.v1",
4
+ "type": "object",
5
+ "required": ["schema", "mission_id", "session_name", "status", "visible_worker_panes", "headless_workers", "blockers"],
6
+ "properties": {
7
+ "schema": { "const": "sks.zellij-right-column-state.v1" },
8
+ "mission_id": { "type": "string" },
9
+ "session_name": { "type": "string" },
10
+ "status": { "enum": ["absent", "creating", "active", "draining", "closed"] },
11
+ "dashboard_pane_id": { "type": ["string", "null"] },
12
+ "right_anchor_pane_id": { "type": ["string", "null"] },
13
+ "visible_worker_panes": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "required": ["slot_id", "generation_index", "y_order", "status"],
18
+ "properties": {
19
+ "pane_id": { "type": ["string", "null"] },
20
+ "slot_id": { "type": "string" },
21
+ "generation_index": { "type": "integer" },
22
+ "y_order": { "type": "integer" },
23
+ "status": { "enum": ["launching", "running", "draining", "closed", "failed"] }
24
+ }
25
+ }
26
+ },
27
+ "headless_workers": {
28
+ "type": "array",
29
+ "items": {
30
+ "type": "object",
31
+ "required": ["slot_id", "generation_index", "reason"],
32
+ "properties": {
33
+ "slot_id": { "type": "string" },
34
+ "generation_index": { "type": "integer" },
35
+ "reason": { "type": "string" }
36
+ }
37
+ }
38
+ },
39
+ "blockers": { "type": "array", "items": { "type": "string" } }
40
+ }
41
+ }