sneakoscope 2.0.18 → 3.0.1

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 (41) hide show
  1. package/README.md +127 -71
  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/commands/mad-sks.js +2 -0
  8. package/dist/commands/zellij.js +58 -1
  9. package/dist/core/agents/agent-scheduler.js +32 -24
  10. package/dist/core/agents/native-cli-session-swarm.js +22 -2
  11. package/dist/core/codex-app/codex-app-handoff.js +30 -9
  12. package/dist/core/codex-app/codex-app-launcher.js +103 -0
  13. package/dist/core/codex-control/codex-0138-capability.js +42 -4
  14. package/dist/core/codex-control/codex-0139-capability.js +102 -0
  15. package/dist/core/codex-control/codex-model-capabilities.js +25 -4
  16. package/dist/core/codex-control/codex-model-metadata.js +91 -0
  17. package/dist/core/codex-plugins/codex-plugin-cache.js +38 -0
  18. package/dist/core/codex-plugins/codex-plugin-diff.js +73 -0
  19. package/dist/core/codex-plugins/codex-plugin-json.js +35 -11
  20. package/dist/core/commands/mad-sks-command.js +8 -0
  21. package/dist/core/commands/naruto-command.js +29 -0
  22. package/dist/core/commands/qa-loop-command.js +41 -6
  23. package/dist/core/fsx.js +1 -1
  24. package/dist/core/image/image-artifact-path-contract.js +2 -0
  25. package/dist/core/image/image-artifact-registry.js +33 -0
  26. package/dist/core/image-ux-review/imagegen-adapter.js +27 -16
  27. package/dist/core/pipeline-internals/runtime-core.js +4 -2
  28. package/dist/core/qa-loop/qa-loop-app-handoff-confirmation.js +51 -0
  29. package/dist/core/qa-loop/qa-loop-budget-policy.js +1 -1
  30. package/dist/core/qa-loop.js +44 -3
  31. package/dist/core/release/release-gate-cache-v2.js +47 -5
  32. package/dist/core/usage/codex-account-usage.js +77 -16
  33. package/dist/core/version.js +1 -1
  34. package/dist/core/zellij/zellij-slot-pane-renderer.js +5 -2
  35. package/dist/core/zellij/zellij-slot-telemetry.js +65 -12
  36. package/dist/core/zellij/zellij-ui-mode.js +8 -1
  37. package/dist/core/zellij/zellij-update.js +307 -0
  38. package/dist/core/zellij/zellij-worker-pane-manager.js +211 -145
  39. package/package.json +23 -2
  40. package/dist/core/naruto/naruto-work-stealing.js +0 -11
  41. package/dist/core/zellij/zellij-right-column-layout-proof.js +0 -42
@@ -5,7 +5,7 @@ import { resolveProviderContext } from '../provider/provider-context.js';
5
5
  import { runZellij } from './zellij-command.js';
6
6
  import { extractZellijPaneIdFromOutput } from './zellij-lane-runtime.js';
7
7
  import { buildZellijSlotColumnAnchorCommand } from './zellij-slot-column-anchor.js';
8
- import { closeWorkerInRightColumn, prepareWorkerInRightColumn, recordSlotColumnAnchorInRightColumn, recordWorkerPaneInRightColumn } from './zellij-right-column-manager.js';
8
+ import { closeWorkerInRightColumn, prepareWorkerInRightColumn, readRightColumnState, recordSlotColumnAnchorInRightColumn, recordWorkerPaneInRightColumn } from './zellij-right-column-manager.js';
9
9
  export const ZELLIJ_WORKER_PANE_SCHEMA = 'sks.zellij-worker-pane.v1';
10
10
  export const ZELLIJ_WORKER_PANE_EVENT_SCHEMA = 'sks.zellij-worker-pane-event.v1';
11
11
  export function buildWorkerPaneName(slotId, generationIndex) {
@@ -75,6 +75,8 @@ export function buildWorkerPaneArtifact(input) {
75
75
  column_creation_direction_applied: input.columnCreationDirectionApplied ?? null,
76
76
  worker_direction_requested: input.workerDirectionRequested || 'down',
77
77
  worker_direction_applied: input.workerDirectionApplied || (directionApplied === 'down' ? 'down' : directionApplied === 'unknown' ? 'unknown' : 'not_applied'),
78
+ worker_stacked_requested: input.stackedRequested === true,
79
+ worker_stacked_applied: input.stackedApplied === true,
78
80
  slot_column_anchor_pane_id: input.slotColumnAnchorPaneId || null,
79
81
  right_column: input.rightColumn || null,
80
82
  sdk_thread_id: input.sdkThreadId || null,
@@ -155,163 +157,200 @@ export async function openWorkerPane(input) {
155
157
  return record;
156
158
  }
157
159
  const paneName = buildWorkerPaneTitle(input.slotId, input.generationIndex, providerContext, input.serviceTier, input.backend, input.statusLabel || 'running', input.worktree || null);
158
- let slotColumnAnchorPaneId = rightColumn?.state.slot_column_anchor_pane_id || null;
159
- let anchorLaunch = null;
160
- let columnCreationDirectionRequested = null;
161
- let columnCreationDirectionApplied = null;
162
- if (rightColumn && !rightColumn.focusPaneId && !slotColumnAnchorPaneId) {
163
- columnCreationDirectionRequested = 'right';
164
- const anchorCommand = buildZellijSlotColumnAnchorCommand({
165
- cliPath: path.join(packageRoot(), 'dist', 'bin', 'sks.js'),
166
- missionId: input.missionId,
167
- mode: input.uiMode || 'compact-slots',
168
- artifactRoot: root,
169
- watch: true
170
- });
171
- anchorLaunch = createSession.ok
172
- ? await runZellij(['--session', input.sessionName, 'action', 'new-pane', '--direction', 'right', '--name', 'SLOTS', '--', 'sh', '-lc', anchorCommand], {
160
+ // CRITICAL: serialize anchor + worker pane creation per session. Workers
161
+ // launch concurrently, and without this lock every worker raced past the
162
+ // "does the SLOTS anchor exist yet?" check and created its OWN anchor with
163
+ // --direction right — splitting the screen into N side-by-side columns
164
+ // (observed in agent-zellij-pane-launch-ledger: terminal_1..terminal_5 all
165
+ // recorded as separate slot_column_anchor_pane_id values in one mission).
166
+ return withZellijPaneCreationLock(input.sessionName, async () => {
167
+ // Re-read the right-column state now that we hold the lock: a previously
168
+ // serialized worker may have created the anchor and/or its own pane.
169
+ const freshState = rightColumn
170
+ ? await readRightColumnState(root, input.missionId, input.projectRoot).catch(() => null)
171
+ : null;
172
+ let slotColumnAnchorPaneId = freshState?.slot_column_anchor_pane_id || rightColumn?.state.slot_column_anchor_pane_id || null;
173
+ const lastVisibleWorkerPaneId = [...(freshState?.visible_worker_panes || [])]
174
+ .filter((pane) => pane.pane_id && (pane.status === 'launching' || pane.status === 'running'))
175
+ .map((pane) => String(pane.pane_id))
176
+ .pop() || null;
177
+ const freshFocusCandidate = lastVisibleWorkerPaneId
178
+ || slotColumnAnchorPaneId
179
+ || freshState?.right_anchor_pane_id
180
+ || freshState?.dashboard_pane_id
181
+ || rightColumn?.focusPaneId
182
+ || null;
183
+ let anchorLaunch = null;
184
+ let columnCreationDirectionRequested = null;
185
+ let columnCreationDirectionApplied = null;
186
+ if (rightColumn && !freshFocusCandidate) {
187
+ columnCreationDirectionRequested = 'right';
188
+ const anchorCommand = buildZellijSlotColumnAnchorCommand({
189
+ cliPath: path.join(packageRoot(), 'dist', 'bin', 'sks.js'),
190
+ missionId: input.missionId,
191
+ mode: input.uiMode || 'compact-slots',
192
+ artifactRoot: root,
193
+ watch: true
194
+ });
195
+ anchorLaunch = createSession.ok
196
+ ? await runZellij(['--session', input.sessionName, 'action', 'new-pane', '--direction', 'right', '--name', 'SLOTS', '--', 'sh', '-lc', anchorCommand], {
197
+ cwd,
198
+ timeoutMs: 5000,
199
+ optional: false
200
+ })
201
+ : null;
202
+ slotColumnAnchorPaneId = anchorLaunch?.ok ? extractZellijPaneIdFromOutput(anchorLaunch.stdout_tail) : null;
203
+ columnCreationDirectionApplied = anchorLaunch?.ok ? (slotColumnAnchorPaneId ? 'right' : 'unknown') : 'not_applied';
204
+ if (slotColumnAnchorPaneId) {
205
+ await recordSlotColumnAnchorInRightColumn({
206
+ root,
207
+ ...(input.projectRoot ? { projectRoot: input.projectRoot } : {}),
208
+ missionId: input.missionId,
209
+ sessionName: input.sessionName,
210
+ paneId: slotColumnAnchorPaneId
211
+ });
212
+ }
213
+ }
214
+ const focusPaneId = lastVisibleWorkerPaneId || slotColumnAnchorPaneId || freshFocusCandidate || null;
215
+ const directionRequested = 'down';
216
+ const focus = focusPaneId
217
+ ? await focusZellijPaneById(input.sessionName, focusPaneId, cwd)
218
+ : null;
219
+ // Vertical stack policy: the first worker splits DOWN from the SLOTS anchor;
220
+ // every following worker joins a zellij stacked-pane group with the previous
221
+ // worker (`new-pane --stacked`, zellij >= 0.43) so the right column stays a
222
+ // clean vertical stack instead of fragmenting the screen. Opt out with
223
+ // SKS_ZELLIJ_WORKER_STACKED=0.
224
+ const stackRequested = process.env.SKS_ZELLIJ_WORKER_STACKED !== '0'
225
+ && Boolean(lastVisibleWorkerPaneId)
226
+ && focus?.ok === true;
227
+ const newPaneArgs = stackRequested
228
+ ? ['--session', input.sessionName, 'action', 'new-pane', '--stacked', '--name', paneName, '--', 'sh', '-lc', input.workerCommand]
229
+ : ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, '--near-current-pane', '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
230
+ let launch = createSession.ok
231
+ ? await runZellij(newPaneArgs, {
173
232
  cwd,
174
233
  timeoutMs: 5000,
175
234
  optional: false
176
235
  })
177
236
  : null;
178
- slotColumnAnchorPaneId = anchorLaunch?.ok ? extractZellijPaneIdFromOutput(anchorLaunch.stdout_tail) : null;
179
- columnCreationDirectionApplied = anchorLaunch?.ok ? (slotColumnAnchorPaneId ? 'right' : 'unknown') : 'not_applied';
180
- if (slotColumnAnchorPaneId) {
181
- await recordSlotColumnAnchorInRightColumn({
237
+ let stackApplied = Boolean(stackRequested && launch?.ok);
238
+ let directionApplied = launch?.ok ? directionRequested : 'not_applied';
239
+ if (createSession.ok && launch && !launch.ok) {
240
+ const fallbackArgs = ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
241
+ const fallback = await runZellij(fallbackArgs, {
242
+ cwd,
243
+ timeoutMs: 5000,
244
+ optional: false
245
+ });
246
+ if (fallback.ok) {
247
+ launch = fallback;
248
+ stackApplied = false;
249
+ directionApplied = rightColumn ? 'down' : 'unknown';
250
+ }
251
+ }
252
+ const stdoutPaneId = launch?.ok ? extractZellijPaneIdFromOutput(launch.stdout_tail) : null;
253
+ const reconciledPane = stdoutPaneId ? null : launch?.ok ? await reconcileZellijWorkerPaneId(input.sessionName, paneName, path.join(root, input.resultPath), cwd) : null;
254
+ const paneId = stdoutPaneId || reconciledPane?.pane_id || null;
255
+ const renamePane = paneId ? await renameZellijPaneById(input.sessionName, paneId, paneName, cwd) : null;
256
+ const paneIdSource = stdoutPaneId
257
+ ? 'zellij_worker_new_pane_stdout'
258
+ : reconciledPane?.pane_id
259
+ ? 'zellij_worker_list_panes'
260
+ : launch?.ok
261
+ ? 'zellij_worker_pane_stdout_missing'
262
+ : 'zellij_worker_pane_launch_failed';
263
+ const blockers = [
264
+ ...(createSession.ok ? [] : createSession.blockers.map((blocker) => `zellij_worker_session_${blocker}`)),
265
+ ...(rightColumn && rightColumn.placement !== 'zellij-pane' ? [`zellij_worker_right_column_${rightColumn.placement}`] : []),
266
+ ...(rightColumn && columnCreationDirectionRequested === 'right' && columnCreationDirectionApplied !== 'right' ? ['zellij_worker_slot_column_anchor_not_created'] : []),
267
+ ...(anchorLaunch && !anchorLaunch.ok ? anchorLaunch.blockers.map((blocker) => `zellij_worker_slot_column_anchor_${blocker}`) : []),
268
+ ...(launch && !launch.ok ? launch.blockers.map((blocker) => `zellij_worker_pane_${blocker}`) : []),
269
+ ...(launch?.ok && !isRealZellijWorkerPaneIdSource(paneIdSource) ? ['zellij_worker_pane_id_real_source_missing'] : [])
270
+ ];
271
+ const record = buildWorkerPaneArtifact({
272
+ ...input,
273
+ paneId,
274
+ paneIdSource,
275
+ createSession,
276
+ launch,
277
+ paneReconciliation: {
278
+ ...(reconciledPane || {}),
279
+ focus_pane: focus,
280
+ focus_degraded: focus ? focus.ok !== true : false,
281
+ slot_column_anchor_pane_id: slotColumnAnchorPaneId,
282
+ slot_column_anchor_launch: anchorLaunch,
283
+ rename_pane: renamePane
284
+ },
285
+ directionRequested,
286
+ directionApplied,
287
+ columnCreationDirectionRequested,
288
+ columnCreationDirectionApplied,
289
+ workerDirectionRequested: 'down',
290
+ workerDirectionApplied: directionApplied === 'down' ? 'down' : directionApplied === 'unknown' ? 'unknown' : 'not_applied',
291
+ stackedRequested: stackRequested,
292
+ stackedApplied: stackApplied,
293
+ slotColumnAnchorPaneId,
294
+ rightColumn: rightColumn ? { mode: 'spawn-on-first-worker', focus_pane_id: focusPaneId, y_order: rightColumn.yOrder, slot_column_anchor_pane_id: slotColumnAnchorPaneId } : null,
295
+ status: blockers.length ? 'failed' : 'running',
296
+ providerContext,
297
+ serviceTier: input.serviceTier || providerContext.service_tier,
298
+ blockers
299
+ });
300
+ await writeWorkerPaneArtifact(root, record);
301
+ if (rightColumn) {
302
+ await recordWorkerPaneInRightColumn({
182
303
  root,
183
304
  ...(input.projectRoot ? { projectRoot: input.projectRoot } : {}),
184
305
  missionId: input.missionId,
185
- sessionName: input.sessionName,
186
- paneId: slotColumnAnchorPaneId
306
+ record,
307
+ yOrder: rightColumn.yOrder
187
308
  });
188
309
  }
189
- }
190
- const focusPaneId = rightColumn?.focusPaneId || slotColumnAnchorPaneId || null;
191
- const directionRequested = 'down';
192
- const focus = focusPaneId
193
- ? await focusZellijPaneById(input.sessionName, focusPaneId, cwd)
194
- : null;
195
- const newPaneArgs = ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, ...(directionRequested === 'down' ? ['--near-current-pane'] : []), '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
196
- let launch = createSession.ok
197
- ? await runZellij(newPaneArgs, {
198
- cwd,
199
- timeoutMs: 5000,
200
- optional: false
201
- })
202
- : null;
203
- let directionApplied = launch?.ok ? directionRequested : 'not_applied';
204
- if (createSession.ok && launch && !launch.ok) {
205
- const fallbackArgs = rightColumn && directionRequested === 'down'
206
- ? ['--session', input.sessionName, 'action', 'new-pane', '--direction', 'down', '--name', paneName, '--', 'sh', '-lc', input.workerCommand]
207
- : ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
208
- const fallback = await runZellij(fallbackArgs, {
209
- cwd,
210
- timeoutMs: 5000,
211
- optional: false
310
+ await appendWorkerPaneEvent(root, 'zellij_worker_pane_created', input, {
311
+ ok: record.ok,
312
+ pane_id: record.pane_id,
313
+ pane_id_source: record.pane_id_source,
314
+ blockers
212
315
  });
213
- if (fallback.ok) {
214
- launch = fallback;
215
- directionApplied = rightColumn ? 'down' : 'unknown';
216
- }
217
- }
218
- const stdoutPaneId = launch?.ok ? extractZellijPaneIdFromOutput(launch.stdout_tail) : null;
219
- const reconciledPane = stdoutPaneId ? null : launch?.ok ? await reconcileZellijWorkerPaneId(input.sessionName, paneName, path.join(root, input.resultPath), cwd) : null;
220
- const paneId = stdoutPaneId || reconciledPane?.pane_id || null;
221
- const renamePane = paneId ? await renameZellijPaneById(input.sessionName, paneId, paneName, cwd) : null;
222
- const paneIdSource = stdoutPaneId
223
- ? 'zellij_worker_new_pane_stdout'
224
- : reconciledPane?.pane_id
225
- ? 'zellij_worker_list_panes'
226
- : launch?.ok
227
- ? 'zellij_worker_pane_stdout_missing'
228
- : 'zellij_worker_pane_launch_failed';
229
- const blockers = [
230
- ...(createSession.ok ? [] : createSession.blockers.map((blocker) => `zellij_worker_session_${blocker}`)),
231
- ...(rightColumn && rightColumn.placement !== 'zellij-pane' ? [`zellij_worker_right_column_${rightColumn.placement}`] : []),
232
- ...(rightColumn && columnCreationDirectionRequested === 'right' && columnCreationDirectionApplied !== 'right' ? ['zellij_worker_slot_column_anchor_not_created'] : []),
233
- ...(anchorLaunch && !anchorLaunch.ok ? anchorLaunch.blockers.map((blocker) => `zellij_worker_slot_column_anchor_${blocker}`) : []),
234
- ...(launch && !launch.ok ? launch.blockers.map((blocker) => `zellij_worker_pane_${blocker}`) : []),
235
- ...(launch?.ok && !isRealZellijWorkerPaneIdSource(paneIdSource) ? ['zellij_worker_pane_id_real_source_missing'] : [])
236
- ];
237
- const record = buildWorkerPaneArtifact({
238
- ...input,
239
- paneId,
240
- paneIdSource,
241
- createSession,
242
- launch,
243
- paneReconciliation: {
244
- ...(reconciledPane || {}),
245
- focus_pane: focus,
246
- focus_degraded: focus ? focus.ok !== true : false,
247
- slot_column_anchor_pane_id: slotColumnAnchorPaneId,
248
- slot_column_anchor_launch: anchorLaunch,
249
- rename_pane: renamePane
250
- },
251
- directionRequested,
252
- directionApplied,
253
- columnCreationDirectionRequested,
254
- columnCreationDirectionApplied,
255
- workerDirectionRequested: 'down',
256
- workerDirectionApplied: directionApplied === 'down' ? 'down' : directionApplied === 'unknown' ? 'unknown' : 'not_applied',
257
- slotColumnAnchorPaneId,
258
- rightColumn: rightColumn ? { mode: 'spawn-on-first-worker', focus_pane_id: focusPaneId, y_order: rightColumn.yOrder, slot_column_anchor_pane_id: slotColumnAnchorPaneId } : null,
259
- status: blockers.length ? 'failed' : 'running',
260
- providerContext,
261
- serviceTier: input.serviceTier || providerContext.service_tier,
262
- blockers
263
- });
264
- await writeWorkerPaneArtifact(root, record);
265
- if (rightColumn) {
266
- await recordWorkerPaneInRightColumn({
267
- root,
268
- ...(input.projectRoot ? { projectRoot: input.projectRoot } : {}),
269
- missionId: input.missionId,
270
- record,
271
- yOrder: rightColumn.yOrder
316
+ await appendJsonl(path.join(root, 'agent-zellij-pane-launch-ledger.jsonl'), {
317
+ schema: 'sks.agent-zellij-pane-launch.v1',
318
+ generated_at: nowIso(),
319
+ launch_mode: record.ok ? 'real_zellij_worker_pane_session' : 'real_zellij_worker_pane_failed',
320
+ agent_id: input.slotId,
321
+ slot_id: input.slotId,
322
+ generation_index: input.generationIndex,
323
+ session_id: input.sessionId,
324
+ session_name: input.sessionName,
325
+ pane_name: paneName,
326
+ pane_title: paneName,
327
+ pane_kind: record.pane_kind,
328
+ pane_id: record.pane_id,
329
+ pane_id_source: record.pane_id_source,
330
+ provider: record.provider,
331
+ service_tier: record.service_tier,
332
+ provider_context: record.provider_context,
333
+ direction_requested: record.direction_requested,
334
+ direction_applied: record.direction_applied,
335
+ column_creation_direction_requested: record.column_creation_direction_requested || null,
336
+ column_creation_direction_applied: record.column_creation_direction_applied || null,
337
+ worker_direction_requested: record.worker_direction_requested,
338
+ worker_direction_applied: record.worker_direction_applied,
339
+ worker_stacked_requested: record.worker_stacked_requested === true,
340
+ worker_stacked_applied: record.worker_stacked_applied === true,
341
+ slot_column_anchor_pane_id: record.slot_column_anchor_pane_id || null,
342
+ command: record.command,
343
+ worker_artifact_dir: input.workerArtifactDir,
344
+ worker_result_path: input.resultPath,
345
+ heartbeat_path: input.heartbeatPath,
346
+ patch_envelope_path: input.patchEnvelopePath,
347
+ parent_child_transport: 'worker-result-json-and-heartbeat',
348
+ persistent_slot_lane: false,
349
+ scaling_primitive: record.scaling_primitive,
350
+ blockers
272
351
  });
273
- }
274
- await appendWorkerPaneEvent(root, 'zellij_worker_pane_created', input, {
275
- ok: record.ok,
276
- pane_id: record.pane_id,
277
- pane_id_source: record.pane_id_source,
278
- blockers
279
- });
280
- await appendJsonl(path.join(root, 'agent-zellij-pane-launch-ledger.jsonl'), {
281
- schema: 'sks.agent-zellij-pane-launch.v1',
282
- generated_at: nowIso(),
283
- launch_mode: record.ok ? 'real_zellij_worker_pane_session' : 'real_zellij_worker_pane_failed',
284
- agent_id: input.slotId,
285
- slot_id: input.slotId,
286
- generation_index: input.generationIndex,
287
- session_id: input.sessionId,
288
- session_name: input.sessionName,
289
- pane_name: paneName,
290
- pane_title: paneName,
291
- pane_kind: record.pane_kind,
292
- pane_id: record.pane_id,
293
- pane_id_source: record.pane_id_source,
294
- provider: record.provider,
295
- service_tier: record.service_tier,
296
- provider_context: record.provider_context,
297
- direction_requested: record.direction_requested,
298
- direction_applied: record.direction_applied,
299
- column_creation_direction_requested: record.column_creation_direction_requested || null,
300
- column_creation_direction_applied: record.column_creation_direction_applied || null,
301
- worker_direction_requested: record.worker_direction_requested,
302
- worker_direction_applied: record.worker_direction_applied,
303
- slot_column_anchor_pane_id: record.slot_column_anchor_pane_id || null,
304
- command: record.command,
305
- worker_artifact_dir: input.workerArtifactDir,
306
- worker_result_path: input.resultPath,
307
- heartbeat_path: input.heartbeatPath,
308
- patch_envelope_path: input.patchEnvelopePath,
309
- parent_child_transport: 'worker-result-json-and-heartbeat',
310
- persistent_slot_lane: false,
311
- scaling_primitive: record.scaling_primitive,
312
- blockers
352
+ return record;
313
353
  });
314
- return record;
315
354
  }
316
355
  export async function closeWorkerPane(input) {
317
356
  const root = path.resolve(input.root);
@@ -547,6 +586,14 @@ async function focusZellijPaneById(sessionName, paneId, cwd) {
547
586
  last = focus;
548
587
  if (focus.ok)
549
588
  return focus;
589
+ // zellij exits non-zero with "Pane Terminal(N) is already focused" when the
590
+ // target pane already holds focus (common: new-pane auto-focuses the pane
591
+ // it created, so the previous worker pane is usually still focused). That
592
+ // is a success for our purposes — without this, stacked placement would
593
+ // silently fall back to a plain down-split on every consecutive worker.
594
+ if (/already focused/i.test(`${focus.stdout_tail || ''} ${focus.stderr_tail || ''}`)) {
595
+ return { ...focus, ok: true, blockers: [], warnings: [...focus.warnings, 'zellij_pane_already_focused'] };
596
+ }
550
597
  }
551
598
  return last;
552
599
  }
@@ -579,6 +626,25 @@ function zellijPaneIdCandidates(paneId) {
579
626
  function sleep(ms) {
580
627
  return new Promise((resolve) => setTimeout(resolve, ms));
581
628
  }
629
+ const zellijPaneCreationLocks = new Map();
630
+ async function withZellijPaneCreationLock(sessionName, fn) {
631
+ const key = String(sessionName || 'default');
632
+ const previous = zellijPaneCreationLocks.get(key) || Promise.resolve();
633
+ let release;
634
+ const current = new Promise((resolve) => {
635
+ release = resolve;
636
+ });
637
+ zellijPaneCreationLocks.set(key, previous.then(() => current, () => current));
638
+ await previous.catch(() => undefined);
639
+ try {
640
+ return await fn();
641
+ }
642
+ finally {
643
+ release();
644
+ if (zellijPaneCreationLocks.get(key) === current)
645
+ zellijPaneCreationLocks.delete(key);
646
+ }
647
+ }
582
648
  function normalizeExistingZellijSession(sessionName, result) {
583
649
  if (result.ok)
584
650
  return result;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sneakoscope",
3
3
  "displayName": "ㅅㅋㅅ",
4
- "version": "2.0.18",
4
+ "version": "3.0.1",
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",
@@ -24,6 +24,10 @@
24
24
  "files": [
25
25
  "dist",
26
26
  "!dist/build-manifest.json",
27
+ "!dist/**/*.d.ts",
28
+ "!dist/**/*.d.ts.map",
29
+ "!dist/**/*.js.map",
30
+ "!dist/**/*.tsbuildinfo",
27
31
  "!dist/vendor/openai-codex/rust-v0.131.0",
28
32
  "!dist/scripts/*-blackbox.js",
29
33
  "!dist/scripts/*-check.js",
@@ -558,6 +562,7 @@
558
562
  "release:check:dag:no-cache": "node ./dist/scripts/release-gate-dag-runner.js --preset release --no-cache",
559
563
  "release:check:dag:fail-fast": "node ./dist/scripts/release-gate-dag-runner.js --preset release --fail-fast",
560
564
  "codex:0138-capability": "node ./dist/scripts/codex-0138-capability-check.js",
565
+ "codex:0139-capability": "node ./dist/scripts/codex-0139-capability-check.js",
561
566
  "codex:0138-capability-artifact": "node ./dist/scripts/codex-0138-capability-artifact-check.js",
562
567
  "codex-sdk:version-compat": "node ./dist/scripts/codex-sdk-version-compat-check.js",
563
568
  "codex-app:handoff": "node ./dist/scripts/codex-app-handoff-check.js",
@@ -680,7 +685,23 @@
680
685
  "mad-db:mcp-result-lifecycle": "node ./dist/scripts/mad-db-mcp-result-lifecycle-check.js",
681
686
  "mad-db:operation-lifecycle-blackbox": "node ./dist/scripts/mad-db-operation-lifecycle-blackbox.js",
682
687
  "runtime:proof-summary": "node ./dist/scripts/runtime-proof-summary-check.js",
683
- "runtime:proof-summary-cli": "node ./dist/scripts/runtime-proof-summary-cli-check.js"
688
+ "runtime:proof-summary-cli": "node ./dist/scripts/runtime-proof-summary-cli-check.js",
689
+ "codex-app:launcher": "node ./dist/scripts/codex-app-launcher-check.js",
690
+ "codex-app:handoff-launch": "node ./dist/scripts/codex-app-handoff-launch-check.js",
691
+ "qa-loop:app-handoff-launch": "node ./dist/scripts/qa-loop-app-handoff-launch-check.js",
692
+ "qa-loop:app-handoff-confirmation": "node ./dist/scripts/qa-loop-app-handoff-confirmation-check.js",
693
+ "qa-loop:app-handoff-status-lifecycle": "node ./dist/scripts/qa-loop-app-handoff-status-lifecycle-check.js",
694
+ "qa-loop:app-handoff-gate-lifecycle": "node ./dist/scripts/qa-loop-app-handoff-gate-lifecycle-check.js",
695
+ "codex-plugin:parallel-detail-fetch": "node ./dist/scripts/codex-plugin-parallel-detail-fetch-check.js",
696
+ "codex-plugin:cache": "node ./dist/scripts/codex-plugin-cache-check.js",
697
+ "codex-plugin:diff": "node ./dist/scripts/codex-plugin-diff-check.js",
698
+ "image:artifact-registry": "node ./dist/scripts/image-artifact-registry-check.js",
699
+ "image:global-path-contract": "node ./dist/scripts/image-global-path-contract-check.js",
700
+ "qa-loop:image-path-prompt-injection": "node ./dist/scripts/qa-loop-image-path-prompt-injection-check.js",
701
+ "codex:model-metadata": "node ./dist/scripts/codex-model-metadata-check.js",
702
+ "codex:effort-auto-discovery": "node ./dist/scripts/codex-effort-auto-discovery-check.js",
703
+ "codex:account-usage-autodiscovery": "node ./dist/scripts/codex-account-usage-autodiscovery-check.js",
704
+ "codex:0138-feature-probes": "node ./dist/scripts/codex-0138-feature-probes-check.js"
684
705
  },
685
706
  "keywords": [
686
707
  "sneakoscope",
@@ -1,11 +0,0 @@
1
- export function stealNarutoWork(queue, input = {}) {
2
- const item = queue.shift() || null;
3
- return {
4
- schema: 'sks.naruto-work-stealing.v1',
5
- stolen: Boolean(item),
6
- work_item_id: item?.id || null,
7
- from_queue: input.fromQueue || 'pending',
8
- to_slot: input.toSlot || 'idle-slot'
9
- };
10
- }
11
- //# sourceMappingURL=naruto-work-stealing.js.map
@@ -1,42 +0,0 @@
1
- export function evaluateZellijRightColumnGeometry(input) {
2
- const tolerance = Math.max(0, Number(input.tolerance ?? 2));
3
- const main = input.panes.find((pane) => pane.role === 'main') || null;
4
- const dashboard = input.panes.find((pane) => pane.role === 'dashboard') || null;
5
- const workers = input.panes.filter((pane) => pane.role === 'worker');
6
- const workerGeometries = workers.map((pane) => pane.geometry).filter(Boolean);
7
- const baseX = workerGeometries[0]?.x;
8
- const sameRightX = baseX == null ? null : workerGeometries.every((geometry) => geometry.x != null && Math.abs(geometry.x - baseX) <= tolerance);
9
- const rightOfMain = !main?.geometry ? null : workerGeometries.every((geometry) => {
10
- if (geometry.x == null || main.geometry?.x == null || main.geometry?.width == null)
11
- return false;
12
- return geometry.x >= main.geometry.x + main.geometry.width - tolerance;
13
- });
14
- const increasingY = workerGeometries.every((geometry, index) => {
15
- if (index === 0)
16
- return true;
17
- const previous = workerGeometries[index - 1];
18
- return geometry.y != null && previous?.y != null && geometry.y > previous.y;
19
- });
20
- const visibleCapOk = workers.length <= Math.max(0, Math.floor(Number(input.visiblePaneCap || 0)));
21
- const blockers = [
22
- ...(!main ? ['right_column_main_pane_missing'] : []),
23
- ...(!dashboard ? ['right_column_dashboard_missing'] : []),
24
- ...(sameRightX === false ? ['right_column_worker_x_range_mismatch'] : []),
25
- ...(rightOfMain === false ? ['right_column_workers_not_right_of_main'] : []),
26
- ...(increasingY === false ? ['right_column_workers_not_stacked_down'] : []),
27
- ...(visibleCapOk ? [] : ['right_column_visible_cap_exceeded'])
28
- ];
29
- return {
30
- schema: 'sks.zellij-right-column-layout-proof.v1',
31
- ok: blockers.length === 0,
32
- main_pane_id: main?.pane_id || null,
33
- dashboard_pane_id: dashboard?.pane_id || null,
34
- worker_pane_ids: workers.map((pane) => pane.pane_id),
35
- same_right_x: sameRightX,
36
- right_of_main: rightOfMain,
37
- increasing_y: increasingY,
38
- visible_cap_ok: visibleCapOk,
39
- blockers
40
- };
41
- }
42
- //# sourceMappingURL=zellij-right-column-layout-proof.js.map