sneakoscope 4.8.6 → 5.1.2

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 (390) hide show
  1. package/README.md +51 -726
  2. package/bench/tasks/t01-off-by-one/repo/package.json +9 -0
  3. package/bench/tasks/t01-off-by-one/repo/src/pagination.js +5 -0
  4. package/bench/tasks/t01-off-by-one/repo/test.js +5 -0
  5. package/bench/tasks/t01-off-by-one/task.json +13 -0
  6. package/bench/tasks/t02-signature-cochange/repo/package.json +9 -0
  7. package/bench/tasks/t02-signature-cochange/repo/src/admin.js +5 -0
  8. package/bench/tasks/t02-signature-cochange/repo/src/audit.js +5 -0
  9. package/bench/tasks/t02-signature-cochange/repo/src/labels.js +3 -0
  10. package/bench/tasks/t02-signature-cochange/repo/src/profile.js +5 -0
  11. package/bench/tasks/t02-signature-cochange/repo/test.js +9 -0
  12. package/bench/tasks/t02-signature-cochange/task.json +12 -0
  13. package/bench/tasks/t03-type-puzzle/repo/package.json +9 -0
  14. package/bench/tasks/t03-type-puzzle/repo/src/config.js +4 -0
  15. package/bench/tasks/t03-type-puzzle/repo/test.js +6 -0
  16. package/bench/tasks/t03-type-puzzle/task.json +13 -0
  17. package/bench/tasks/t04-refactor-preserve/repo/package.json +9 -0
  18. package/bench/tasks/t04-refactor-preserve/repo/src/cart.js +8 -0
  19. package/bench/tasks/t04-refactor-preserve/repo/test.js +4 -0
  20. package/bench/tasks/t04-refactor-preserve/task.json +12 -0
  21. package/bench/tasks/t05-performance/repo/package.json +9 -0
  22. package/bench/tasks/t05-performance/repo/src/pairs.js +9 -0
  23. package/bench/tasks/t05-performance/repo/test.js +11 -0
  24. package/bench/tasks/t05-performance/task.json +12 -0
  25. package/bench/tasks/t06-mistake-rule/repo/package.json +9 -0
  26. package/bench/tasks/t06-mistake-rule/repo/src/loader.js +6 -0
  27. package/bench/tasks/t06-mistake-rule/repo/test.js +7 -0
  28. package/bench/tasks/t06-mistake-rule/task.json +12 -0
  29. package/config/bench-baseline.json +7 -0
  30. package/crates/sks-core/Cargo.lock +1 -1
  31. package/crates/sks-core/Cargo.toml +1 -1
  32. package/crates/sks-core/src/main.rs +1 -1
  33. package/dist/bin/install.js +35 -0
  34. package/dist/bin/sks.js +1 -1
  35. package/dist/cli/cli-theme.js +51 -0
  36. package/dist/cli/command-registry.js +75 -42
  37. package/dist/cli/help-fast.js +18 -8
  38. package/dist/cli/insane-search-command.js +36 -8
  39. package/dist/cli/install-helpers.js +147 -47
  40. package/dist/cli/router.js +58 -2
  41. package/dist/commands/codex-lb.js +6 -4
  42. package/dist/commands/doctor.js +146 -8
  43. package/dist/commands/proof.js +6 -3
  44. package/dist/commands/zellij-monitor-pane.js +25 -0
  45. package/dist/commands/zellij-slot-pane.js +39 -2
  46. package/dist/commands/zellij-viewport-pane.js +56 -0
  47. package/dist/commands/zellij.js +55 -2
  48. package/dist/config/skills-manifest.json +493 -0
  49. package/dist/core/agents/agent-conflict-graph.js +5 -0
  50. package/dist/core/agents/agent-lease.js +5 -0
  51. package/dist/core/agents/agent-ledger-schemas.js +1 -0
  52. package/dist/core/agents/agent-lifecycle.js +86 -35
  53. package/dist/core/agents/agent-orchestrator.js +287 -72
  54. package/dist/core/agents/agent-output-validator.js +14 -3
  55. package/dist/core/agents/agent-patch-queue-store.js +108 -4
  56. package/dist/core/agents/agent-patch-queue.js +10 -3
  57. package/dist/core/agents/agent-patch-schema.js +13 -0
  58. package/dist/core/agents/agent-proof-evidence.js +6 -1
  59. package/dist/core/agents/agent-runner-fake.js +40 -0
  60. package/dist/core/agents/agent-scheduler.js +2 -3
  61. package/dist/core/agents/agent-worker-pipeline.js +36 -2
  62. package/dist/core/agents/codex-exec-worker-adapter.js +2 -0
  63. package/dist/core/agents/native-cli-session-swarm.js +30 -13
  64. package/dist/core/agents/native-cli-worker.js +2 -1
  65. package/dist/core/agents/native-worker-backend-router.js +58 -1
  66. package/dist/core/auto-review.js +25 -4
  67. package/dist/core/codex/agent-config-file-repair.js +15 -2
  68. package/dist/core/codex/codex-config-eperm-repair.js +8 -2
  69. package/dist/core/codex/codex-config-guard.js +289 -0
  70. package/dist/core/codex/codex-config-toml.js +122 -0
  71. package/dist/core/codex/codex-project-config-policy.js +59 -7
  72. package/dist/core/codex-app/sks-menubar.js +780 -122
  73. package/dist/core/codex-app.js +1 -0
  74. package/dist/core/codex-control/codex-fake-sdk-adapter.js +6 -4
  75. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  76. package/dist/core/codex-control/codex-sdk-env-policy.js +1 -1
  77. package/dist/core/codex-control/codex-task-runner.js +32 -14
  78. package/dist/core/codex-control/python-codex-sdk-adapter.js +4 -1
  79. package/dist/core/codex-control/schemas/agent-worker-result.schema.js +12 -3
  80. package/dist/core/codex-hooks/codex-hook-managed-install.js +5 -0
  81. package/dist/core/codex-hooks/codex-hook-state-writer.js +70 -11
  82. package/dist/core/codex-hooks/codex-hook-trust-doctor.js +2 -2
  83. package/dist/core/codex-lb/codex-lb-env.js +20 -1
  84. package/dist/core/codex-lb/codex-lb-setup.js +2 -5
  85. package/dist/core/codex-native/skill-registry-ledger.js +24 -5
  86. package/dist/core/commands/basic-cli.js +21 -2
  87. package/dist/core/commands/check-command.js +37 -5
  88. package/dist/core/commands/command-utils.js +22 -2
  89. package/dist/core/commands/computer-use-command.js +62 -7
  90. package/dist/core/commands/db-command.js +31 -5
  91. package/dist/core/commands/fast-mode-command.js +39 -11
  92. package/dist/core/commands/gate-result-contract.js +43 -0
  93. package/dist/core/commands/gates-command.js +6 -1
  94. package/dist/core/commands/gc-command.js +29 -2
  95. package/dist/core/commands/goal-command.js +9 -2
  96. package/dist/core/commands/gx-command.js +79 -7
  97. package/dist/core/commands/image-ux-review-command.js +188 -13
  98. package/dist/core/commands/mad-db-command.js +85 -176
  99. package/dist/core/commands/mad-sks-command.js +248 -34
  100. package/dist/core/commands/menubar-command.js +146 -0
  101. package/dist/core/commands/naruto-command.js +64 -10
  102. package/dist/core/commands/pipeline-command.js +21 -2
  103. package/dist/core/commands/plan-command.js +76 -0
  104. package/dist/core/commands/ppt-command.js +159 -24
  105. package/dist/core/commands/qa-loop-command.js +6 -2
  106. package/dist/core/commands/release-command.js +55 -2
  107. package/dist/core/commands/research-command.js +1 -1
  108. package/dist/core/commands/review-command.js +217 -0
  109. package/dist/core/commands/route-command.js +62 -0
  110. package/dist/core/commands/route-success-helpers.js +59 -0
  111. package/dist/core/commands/run-command.js +19 -7
  112. package/dist/core/commands/seo-command.js +49 -1
  113. package/dist/core/commands/status-command.js +21 -1
  114. package/dist/core/commands/team-legacy-observe-command.js +221 -3
  115. package/dist/core/commands/ui-command.js +161 -0
  116. package/dist/core/commands/uninstall-command.js +312 -0
  117. package/dist/core/db-safety.js +7 -3
  118. package/dist/core/doctor/codex-startup-config-repair.js +14 -3
  119. package/dist/core/doctor/confirm-repair.js +27 -0
  120. package/dist/core/doctor/context7-mcp-repair.js +35 -7
  121. package/dist/core/doctor/doctor-codex-startup-repair.js +10 -3
  122. package/dist/core/doctor/doctor-context7-repair.js +17 -4
  123. package/dist/core/doctor/doctor-dirty-planner.js +27 -9
  124. package/dist/core/doctor/doctor-native-capability-repair.js +12 -2
  125. package/dist/core/doctor/doctor-readiness-matrix.js +27 -2
  126. package/dist/core/doctor/doctor-repair-postcheck.js +4 -0
  127. package/dist/core/doctor/doctor-transaction.js +21 -5
  128. package/dist/core/doctor/doctor-zellij-repair.js +1 -0
  129. package/dist/core/doctor/imagegen-repair.js +161 -0
  130. package/dist/core/doctor/supabase-mcp-repair.js +23 -5
  131. package/dist/core/feature-fixture-runner.js +2 -2
  132. package/dist/core/feature-fixtures.js +65 -37
  133. package/dist/core/feature-registry.js +106 -3
  134. package/dist/core/fsx.js +91 -2
  135. package/dist/core/hooks-runtime/skill-reconcile-preflight.js +43 -0
  136. package/dist/core/hooks-runtime.js +86 -46
  137. package/dist/core/image-ux-review/imagegen-adapter.js +48 -11
  138. package/dist/core/image-ux-review.js +16 -0
  139. package/dist/core/imagegen/imagegen-capability.js +11 -5
  140. package/dist/core/imagegen/require-imagegen.js +57 -0
  141. package/dist/core/init/skills.js +271 -14
  142. package/dist/core/init.js +13 -10
  143. package/dist/core/mad-db/mad-db-coordinator.js +96 -20
  144. package/dist/core/mad-db/mad-db-policy.js +12 -10
  145. package/dist/core/mad-sks/executors/executor-base.js +8 -2
  146. package/dist/core/mad-sks/executors/index.js +4 -0
  147. package/dist/core/mad-sks/executors/sql-plane-executor.js +194 -0
  148. package/dist/core/mission.js +138 -5
  149. package/dist/core/naruto/naruto-active-pool.js +84 -30
  150. package/dist/core/naruto/naruto-backpressure.js +5 -1
  151. package/dist/core/naruto/naruto-real-worker-child.js +10 -0
  152. package/dist/core/naruto/naruto-real-worker-runtime.js +9 -7
  153. package/dist/core/naruto/naruto-role-policy.js +3 -0
  154. package/dist/core/naruto/naruto-task-hints.js +10 -0
  155. package/dist/core/naruto/naruto-work-graph.js +8 -2
  156. package/dist/core/naruto/naruto-work-item.js +6 -0
  157. package/dist/core/naruto/resource-pressure-monitor.js +33 -15
  158. package/dist/core/naruto/solution-tournament.js +101 -0
  159. package/dist/core/permission-gates.js +30 -0
  160. package/dist/core/pipeline-internals/runtime-core.js +72 -222
  161. package/dist/core/pipeline-internals/runtime-gates.js +140 -24
  162. package/dist/core/ppt-review/index.js +6 -1
  163. package/dist/core/ppt-review/slide-imagegen-review.js +75 -10
  164. package/dist/core/ppt.js +70 -2
  165. package/dist/core/proof/auto-finalize.js +70 -11
  166. package/dist/core/proof/proof-schema.js +2 -0
  167. package/dist/core/proof/route-adapter.js +5 -1
  168. package/dist/core/proof/route-finalizer.js +8 -5
  169. package/dist/core/proof/selftest-proof-fixtures.js +18 -5
  170. package/dist/core/proof/validation.js +2 -0
  171. package/dist/core/provider/model-router.js +53 -0
  172. package/dist/core/questions.js +1 -1
  173. package/dist/core/recallpulse.js +1 -1
  174. package/dist/core/release/gate-manifest.js +2 -2
  175. package/dist/core/release/release-gate-affected-selector.js +3 -10
  176. package/dist/core/release/release-gate-batch-runner.js +4 -2
  177. package/dist/core/release/release-gate-cache-v2.js +27 -14
  178. package/dist/core/release/release-gate-dag.js +6 -1
  179. package/dist/core/release/release-gate-hermetic-env.js +10 -0
  180. package/dist/core/release/release-gate-node.js +3 -0
  181. package/dist/core/release/release-gate-resource-governor.js +1 -0
  182. package/dist/core/retention.js +89 -4
  183. package/dist/core/routes/constants.js +1 -1
  184. package/dist/core/routes/diagnostic-allowlist.js +55 -0
  185. package/dist/core/routes.js +83 -33
  186. package/dist/core/safety/mutation-guard.js +5 -1
  187. package/dist/core/skill-forge.js +9 -4
  188. package/dist/core/stop-gate/gate-evaluator.js +102 -0
  189. package/dist/core/stop-gate/stop-gate-check.js +26 -4
  190. package/dist/core/stop-gate/stop-gate-resolver.js +19 -3
  191. package/dist/core/stop-gate/stop-gate-writer.js +20 -1
  192. package/dist/core/team-dag.js +12 -465
  193. package/dist/core/team-dashboard-renderer.js +13 -94
  194. package/dist/core/team-live.js +68 -804
  195. package/dist/core/triwiki/agents-md-projector.js +184 -0
  196. package/dist/core/triwiki-wrongness/wrongness-schema.js +3 -1
  197. package/dist/core/trust-kernel/trust-kernel-schema.js +1 -0
  198. package/dist/core/trust-kernel/trust-report.js +1 -1
  199. package/dist/core/trust-kernel/trust-status.js +2 -0
  200. package/dist/core/ui/dashboard-html.js +111 -0
  201. package/dist/core/update/update-migration-state.js +383 -42
  202. package/dist/core/update-check.js +201 -78
  203. package/dist/core/verification/diff-quality.js +100 -0
  204. package/dist/core/verification/impact-scan.js +164 -0
  205. package/dist/core/verification/machine-feedback.js +146 -0
  206. package/dist/core/verification/mistake-rule-compiler.js +195 -0
  207. package/dist/core/version.js +1 -1
  208. package/dist/core/zellij/zellij-layout-builder.js +44 -16
  209. package/dist/core/zellij/zellij-monitor-renderer.js +53 -0
  210. package/dist/core/zellij/zellij-self-heal.js +27 -32
  211. package/dist/core/zellij/zellij-slot-pane-renderer.js +162 -153
  212. package/dist/core/zellij/zellij-slot-telemetry.js +2 -0
  213. package/dist/core/zellij/zellij-theme.js +67 -0
  214. package/dist/core/zellij/zellij-ui-mode.js +16 -0
  215. package/dist/core/zellij/zellij-viewport-binder.js +59 -0
  216. package/dist/core/zellij/zellij-worker-pane-manager.js +53 -5
  217. package/dist/scripts/agent-patch-swarm-gate-lib.js +2 -2
  218. package/dist/scripts/build-dist.js +8 -0
  219. package/dist/scripts/check-feature-quality.js +2 -2
  220. package/dist/scripts/cli-output-consistency-check.js +57 -0
  221. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +106 -0
  222. package/dist/scripts/codex-lb-gpt55-fast-profile-check.js +105 -0
  223. package/dist/scripts/codex-lb-missing-env-regression.js +2 -3
  224. package/dist/scripts/codex-project-config-policy-merge-regression.js +3 -3
  225. package/dist/scripts/coding-bench-check.js +136 -0
  226. package/dist/scripts/concurrent-session-collision-check.js +67 -0
  227. package/dist/scripts/docs-truthfulness-check.js +1 -1
  228. package/dist/scripts/doctor-imagegen-repair-check.js +62 -0
  229. package/dist/scripts/ensure-bin-executable.js +11 -3
  230. package/dist/scripts/gate-policy-audit-check.js +130 -0
  231. package/dist/scripts/harness-benchmark-check.js +104 -0
  232. package/dist/scripts/hook-latency-budget-check.js +45 -0
  233. package/dist/scripts/legacy-update-e2e-check.js +228 -0
  234. package/dist/scripts/lib/codex-sdk-gate-lib.js +2 -2
  235. package/dist/scripts/lib/real-codex-parallel-gate.js +2 -2
  236. package/dist/scripts/loop-directive-check-lib.js +1 -1
  237. package/dist/scripts/mad-db-command-check.js +11 -8
  238. package/dist/scripts/mad-db-real-supabase-e2e.js +2 -2
  239. package/dist/scripts/mad-db-route-identity-check.js +8 -6
  240. package/dist/scripts/mad-db-safety-conflict-matrix-check.js +31 -8
  241. package/dist/scripts/mad-db-skill-policy-snapshot-check.js +4 -5
  242. package/dist/scripts/mad-sks-zellij-default-pane-worker-check.js +3 -2
  243. package/dist/scripts/mad-sks-zellij-launch-check.js +1 -1
  244. package/dist/scripts/naruto-zellij-dynamic-right-column-check.js +7 -7
  245. package/dist/scripts/parallel-claim-enforcement-check.js +14 -5
  246. package/dist/scripts/ppt-real-imagegen-wiring-check.js +5 -1
  247. package/dist/scripts/project-skill-dedupe-check.js +23 -5
  248. package/dist/scripts/proof-root-cause-policy-check.js +2 -0
  249. package/dist/scripts/release-affected-selector-check.js +2 -2
  250. package/dist/scripts/release-cache-glob-hashing-check.js +1 -0
  251. package/dist/scripts/release-dag-full-coverage-check.js +13 -4
  252. package/dist/scripts/release-gate-dag-runner-check.js +10 -2
  253. package/dist/scripts/release-gate-dag-runner.js +22 -0
  254. package/dist/scripts/release-gate-existence-audit.js +2 -1
  255. package/dist/scripts/release-gate-planner.js +2 -1
  256. package/dist/scripts/release-gate-script-parity-check.js +1 -1
  257. package/dist/scripts/release-metadata-1-19-check.js +2 -1
  258. package/dist/scripts/release-readiness-report.js +38 -7
  259. package/dist/scripts/release-stability-report-check.js +12 -8
  260. package/dist/scripts/search-visibility-gate-lib.js +2 -2
  261. package/dist/scripts/seo-geo-feature-fixture-quality-check.js +1 -1
  262. package/dist/scripts/skills-manifest-continuity-check.js +46 -0
  263. package/dist/scripts/sks-1-11-gate-lib.js +8 -6
  264. package/dist/scripts/sks-menubar-install-check.js +87 -21
  265. package/dist/scripts/sks-uninstall-regression-check.js +54 -0
  266. package/dist/scripts/uninstall-inventory-check.js +3 -0
  267. package/dist/scripts/ux-review-real-loop-fixture-check.js +9 -4
  268. package/dist/scripts/ux-review-run-wires-imagegen-check.js +4 -0
  269. package/dist/scripts/zellij-layout-valid-check.js +18 -11
  270. package/dist/scripts/zellij-right-column-geometry-proof.js +2 -4
  271. package/dist/scripts/zellij-slot-pane-renderer-check.js +9 -9
  272. package/dist/scripts/zellij-slot-pane-stale-detection-check.js +3 -4
  273. package/dist/scripts/zellij-slot-pane-telemetry-renderer-check.js +3 -2
  274. package/dist/scripts/zellij-slot-telemetry-renderer-check.js +4 -2
  275. package/dist/scripts/zellij-spawn-on-demand-layout-check.js +8 -2
  276. package/dist/scripts/zellij-viewport-binder-check.js +9 -0
  277. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
  278. package/docs/demo.tape +28 -0
  279. package/package.json +70 -3
  280. package/schemas/codex/completion-proof.schema.json +3 -2
  281. package/schemas/release/release-gate-node.schema.json +2 -1
  282. package/dist/scripts/agent-backfill-route-blackbox.js +0 -5
  283. package/dist/scripts/agent-dynamic-pool-route-blackbox.js +0 -5
  284. package/dist/scripts/agent-parallel-write-blackbox.js +0 -56
  285. package/dist/scripts/agent-patch-swarm-route-blackbox.js +0 -10
  286. package/dist/scripts/agent-route-blackbox-lib.js +0 -132
  287. package/dist/scripts/blackbox-command-import-smoke.js +0 -143
  288. package/dist/scripts/blackbox-global-shim.js +0 -77
  289. package/dist/scripts/blackbox-matrix.js +0 -70
  290. package/dist/scripts/blackbox-npx-one-shot.js +0 -69
  291. package/dist/scripts/blackbox-pack-install.js +0 -174
  292. package/dist/scripts/brand-neutrality-zero-leakage-blackbox.js +0 -4
  293. package/dist/scripts/build-once-runner-blackbox.js +0 -34
  294. package/dist/scripts/codex-0140-integration-blackbox.js +0 -13
  295. package/dist/scripts/codex-agent-type-blackbox.js +0 -4
  296. package/dist/scripts/codex-app-harness-blackbox.js +0 -4
  297. package/dist/scripts/codex-app-skill-agent-blackbox.js +0 -4
  298. package/dist/scripts/codex-hook-approval-blackbox.js +0 -4
  299. package/dist/scripts/codex-init-deep-directory-local-blackbox.js +0 -4
  300. package/dist/scripts/codex-native-feature-broker-blackbox.js +0 -4
  301. package/dist/scripts/codex-native-pattern-analysis-blackbox.js +0 -4
  302. package/dist/scripts/codex-native-read-repair-split-blackbox.js +0 -55
  303. package/dist/scripts/codex-native-reference-cache-blackbox.js +0 -41
  304. package/dist/scripts/core-skill-integrity-blackbox.js +0 -33
  305. package/dist/scripts/dfix-fast-blackbox-check.js +0 -37
  306. package/dist/scripts/dfix-parallel-write-blackbox.js +0 -48
  307. package/dist/scripts/dfix-patch-swarm-route-blackbox.js +0 -10
  308. package/dist/scripts/doctor-context7-mcp-repair-blackbox.js +0 -16
  309. package/dist/scripts/doctor-dirty-repair-blackbox.js +0 -22
  310. package/dist/scripts/doctor-dirty-semantic-blackbox.js +0 -8
  311. package/dist/scripts/doctor-fix-production-blackbox.js +0 -26
  312. package/dist/scripts/doctor-native-capability-repair-blackbox.js +0 -39
  313. package/dist/scripts/doctor-startup-config-repair-blackbox.js +0 -13
  314. package/dist/scripts/doctor-supabase-mcp-repair-blackbox.js +0 -14
  315. package/dist/scripts/doctor-transaction-engine-blackbox.js +0 -28
  316. package/dist/scripts/doctor-zellij-fix-blackbox.js +0 -4
  317. package/dist/scripts/doctor-zellij-no-homebrew-blackbox.js +0 -4
  318. package/dist/scripts/doctor-zellij-upgrade-blackbox.js +0 -4
  319. package/dist/scripts/gate-pack-runner-blackbox.js +0 -27
  320. package/dist/scripts/gate-pack-v2-blackbox.js +0 -18
  321. package/dist/scripts/geo-cli-blackbox-check.js +0 -18
  322. package/dist/scripts/loop-collision-blackbox.js +0 -3
  323. package/dist/scripts/loop-concurrency-oversubscription-blackbox.js +0 -3
  324. package/dist/scripts/loop-fixture-production-misuse-blackbox.js +0 -3
  325. package/dist/scripts/loop-kill-interrupt-real-blackbox.js +0 -3
  326. package/dist/scripts/loop-merge-strategy-blackbox.js +0 -3
  327. package/dist/scripts/loop-mesh-production-e2e-blackbox.js +0 -3
  328. package/dist/scripts/loop-side-effect-blackbox.js +0 -3
  329. package/dist/scripts/mad-db-operation-lifecycle-blackbox.js +0 -29
  330. package/dist/scripts/mad-sks-actual-executor-blackbox.js +0 -5
  331. package/dist/scripts/mad-zellij-headless-fallback-blackbox.js +0 -4
  332. package/dist/scripts/mad-zellij-self-heal-blackbox.js +0 -4
  333. package/dist/scripts/naruto-loop-mesh-blackbox.js +0 -3
  334. package/dist/scripts/naruto-real-parallelism-blackbox.js +0 -307
  335. package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -29
  336. package/dist/scripts/parallel-runtime-real-blackbox.js +0 -44
  337. package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +0 -77
  338. package/dist/scripts/pipeline-codex-native-e2e-blackbox.js +0 -13
  339. package/dist/scripts/pipeline-codex-native-image-routing-real-blackbox.js +0 -50
  340. package/dist/scripts/pipeline-codex-native-loop-routing-real-blackbox.js +0 -74
  341. package/dist/scripts/pipeline-codex-native-qa-routing-real-blackbox.js +0 -51
  342. package/dist/scripts/pipeline-codex-native-research-routing-real-blackbox.js +0 -45
  343. package/dist/scripts/pipeline-execution-profile-routing-blackbox.js +0 -4
  344. package/dist/scripts/postinstall-global-doctor-blackbox.js +0 -12
  345. package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -109
  346. package/dist/scripts/ppt-imagegen-blackbox-check.js +0 -46
  347. package/dist/scripts/project-skill-dedupe-blackbox.js +0 -36
  348. package/dist/scripts/qa-backfill-route-blackbox.js +0 -5
  349. package/dist/scripts/qa-patch-swarm-route-blackbox.js +0 -10
  350. package/dist/scripts/release-full-parallelism-blackbox.js +0 -41
  351. package/dist/scripts/release-triwiki-first-runner-blackbox.js +0 -48
  352. package/dist/scripts/release-wiring-3110-blackbox.js +0 -27
  353. package/dist/scripts/release-wiring-3112-blackbox.js +0 -17
  354. package/dist/scripts/release-wiring-3113-blackbox.js +0 -17
  355. package/dist/scripts/research-backfill-route-blackbox.js +0 -5
  356. package/dist/scripts/research-final-reviewer-blackbox.js +0 -70
  357. package/dist/scripts/research-stage-cycle-runtime-blackbox.js +0 -40
  358. package/dist/scripts/research-synthesis-writer-blackbox.js +0 -24
  359. package/dist/scripts/route-blackbox-realism-check.js +0 -21
  360. package/dist/scripts/scheduler-resource-claim-blackbox.js +0 -24
  361. package/dist/scripts/seo-cli-blackbox-check.js +0 -18
  362. package/dist/scripts/sks-3110-all-feature-regression-blackbox.js +0 -116
  363. package/dist/scripts/sks-3112-all-feature-regression-blackbox.js +0 -29
  364. package/dist/scripts/sks-3113-all-feature-regression-blackbox.js +0 -17
  365. package/dist/scripts/sks-400-all-feature-regression-blackbox.js +0 -21
  366. package/dist/scripts/sks-400-extreme-parallel-blackbox.js +0 -8
  367. package/dist/scripts/sks-400-five-minute-blackbox.js +0 -9
  368. package/dist/scripts/sks-400-legacy-purge-blackbox.js +0 -8
  369. package/dist/scripts/sks-401-all-feature-regression-blackbox.js +0 -46
  370. package/dist/scripts/sks-401-five-minute-actual-blackbox.js +0 -23
  371. package/dist/scripts/sks-402-all-feature-regression-blackbox.js +0 -9
  372. package/dist/scripts/sks-402-five-minute-real-blackbox.js +0 -22
  373. package/dist/scripts/sksd-warm-cache-blackbox.js +0 -12
  374. package/dist/scripts/supabase-secret-preservation-blackbox.js +0 -29
  375. package/dist/scripts/team-backfill-route-blackbox.js +0 -5
  376. package/dist/scripts/team-parallel-write-blackbox.js +0 -55
  377. package/dist/scripts/team-patch-swarm-route-blackbox.js +0 -10
  378. package/dist/scripts/triwiki-affected-graph-blackbox.js +0 -28
  379. package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -30
  380. package/dist/scripts/triwiki-proof-bank-lock-blackbox.js +0 -7
  381. package/dist/scripts/update-preserves-supabase-keys-blackbox.js +0 -27
  382. package/dist/scripts/ux-patch-swarm-route-blackbox.js +0 -10
  383. package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -67
  384. package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -28
  385. package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -80
  386. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -137
  387. package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -4
  388. package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -20
  389. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -81
  390. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -202
@@ -1,9 +1,11 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { ensureDir, nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
4
+ import { withHeartbeat } from '../../cli/cli-theme.js';
4
5
  import { createRequestedScopeContract } from '../safety/requested-scope-contract.js';
5
6
  import { guardContextForRoute, guardedPackageInstall } from '../safety/mutation-guard.js';
6
7
  import { mutationLedgerPath } from '../safety/mutation-ledger.js';
8
+ import { confirmRepair } from '../doctor/confirm-repair.js';
7
9
  import { checkZellijCapability, ZELLIJ_MIN_VERSION } from './zellij-capability.js';
8
10
  import { compareVersionLike } from './zellij-command.js';
9
11
  import { askHomebrewInstallAllowed, HOMEBREW_INSTALL_COMMAND, resolveHomebrewInstallPolicy } from './homebrew-policy.js';
@@ -44,17 +46,20 @@ export async function repairZellijForSks(input) {
44
46
  if (dryRun) {
45
47
  return dryRunResult(root, input, env, before, latest, brew, mutationArtifact);
46
48
  }
47
- if (!autoApproved && input.interactive !== true) {
48
- return input.allowHeadlessFallback === true
49
- ? headlessResult(root, input, before, latest, brew, 'noninteractive_without_auto_approval')
50
- : manualResult(root, input, env, before, latest, brew, 'noninteractive_without_auto_approval');
51
- }
52
- if (!autoApproved && input.interactive === true) {
53
- const accepted = await askZellijRepairAllowed(before.status === 'missing'
54
- ? 'Zellij is missing. Install it with Homebrew now? [Y/n] '
55
- : `Zellij ${before.version || 'unknown'} needs repair. Upgrade with Homebrew now? [Y/n] `);
56
- if (!accepted)
57
- return manualResult(root, input, env, before, latest, brew, 'operator_declined_zellij_repair');
49
+ if (!autoApproved) {
50
+ const approval = await confirmRepair({
51
+ autoApprove: autoApproved,
52
+ interactive: input.interactive === true,
53
+ question: before.status === 'missing'
54
+ ? 'Zellij is missing. Install it with Homebrew now? [Y/n] '
55
+ : `Zellij ${before.version || 'unknown'} needs repair. Upgrade with Homebrew now? [Y/n] `
56
+ });
57
+ if (!approval.approved) {
58
+ const reason = approval.reason === 'non_interactive_requires_yes' ? approval.reason : 'operator_declined_zellij_repair';
59
+ return input.allowHeadlessFallback === true
60
+ ? headlessResult(root, input, before, latest, brew, reason)
61
+ : manualResult(root, input, env, before, latest, brew, reason, approval.next_actions);
62
+ }
58
63
  }
59
64
  let brewBin = brew.bin;
60
65
  let homebrewInstallAttempted = false;
@@ -76,7 +81,7 @@ export async function repairZellijForSks(input) {
76
81
  : manualResult(root, input, env, before, latest, brew, policy.blockers[0] || 'homebrew_missing');
77
82
  }
78
83
  homebrewInstallAttempted = true;
79
- const homebrewRun = await runHomebrewInstall(root, env);
84
+ const homebrewRun = await runHomebrewInstall(root, env, input.quiet === true);
80
85
  if (homebrewRun.code !== 0) {
81
86
  return persistSelfHeal(root, input.missionDir, {
82
87
  schema: 'sks.zellij-self-heal.v1',
@@ -108,7 +113,7 @@ export async function repairZellijForSks(input) {
108
113
  : install ? 'brew-install-zellij'
109
114
  : 'brew-upgrade-zellij';
110
115
  const command = `brew ${brewArgs.join(' ')}`;
111
- const run = await runZellijBrew(root, env, brewBin, brewArgs, command);
116
+ const run = await runZellijBrew(root, env, brewBin, brewArgs, command, input.quiet === true);
112
117
  if (run.code !== 0 && /already installed|already up-to-date/i.test(`${run.stdout}\n${run.stderr}`)) {
113
118
  const after = await capabilitySnapshot(root, env, 'after-noop');
114
119
  return persistSelfHeal(root, input.missionDir, {
@@ -246,7 +251,7 @@ async function findBrew(env) {
246
251
  return { present: true, bin: 'brew' };
247
252
  return { present: false, bin: null };
248
253
  }
249
- async function runZellijBrew(root, env, brewBin, args, command) {
254
+ async function runZellijBrew(root, env, brewBin, args, command, quiet = false) {
250
255
  if (env.SKS_ZELLIJ_SELF_HEAL_FAKE_RUN === '1') {
251
256
  await appendFakeBrewLog(env, args);
252
257
  return { code: Number(env.SKS_ZELLIJ_SELF_HEAL_FAKE_RUN_CODE || 0), stdout: 'fake brew ok', stderr: '' };
@@ -257,7 +262,7 @@ async function runZellijBrew(root, env, brewBin, args, command) {
257
262
  projectRoot: root,
258
263
  overrides: { package_install: true, zellij_install: true }
259
264
  });
260
- return guardedPackageInstall(guardContextForRoute(root, contract, command), 'zellij', {
265
+ const work = guardedPackageInstall(guardContextForRoute(root, contract, command), 'zellij', {
261
266
  confirmed: true,
262
267
  command: brewBin,
263
268
  args,
@@ -265,8 +270,9 @@ async function runZellijBrew(root, env, brewBin, args, command) {
265
270
  timeoutMs: 180000,
266
271
  maxOutputBytes: 256 * 1024
267
272
  }).catch((err) => ({ code: 1, stdout: '', stderr: errorMessage(err) }));
273
+ return quiet ? await work : await withHeartbeat('brew zellij repair', work, { warnAfterMs: 30_000 });
268
274
  }
269
- async function runHomebrewInstall(root, env) {
275
+ async function runHomebrewInstall(root, env, quiet = false) {
270
276
  if (env.SKS_ZELLIJ_SELF_HEAL_FAKE_RUN === '1') {
271
277
  await appendFakeBrewLog(env, ['install-homebrew']);
272
278
  return { code: Number(env.SKS_ZELLIJ_SELF_HEAL_FAKE_HOMEBREW_CODE || 0), stdout: 'fake homebrew install ok', stderr: '' };
@@ -277,7 +283,7 @@ async function runHomebrewInstall(root, env) {
277
283
  projectRoot: root,
278
284
  overrides: { package_install: true, zellij_install: true }
279
285
  });
280
- return guardedPackageInstall(guardContextForRoute(root, contract, HOMEBREW_INSTALL_COMMAND), 'homebrew', {
286
+ const work = guardedPackageInstall(guardContextForRoute(root, contract, HOMEBREW_INSTALL_COMMAND), 'homebrew', {
281
287
  confirmed: true,
282
288
  command: '/bin/bash',
283
289
  args: ['-c', 'curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | /bin/bash'],
@@ -285,6 +291,7 @@ async function runHomebrewInstall(root, env) {
285
291
  timeoutMs: 600000,
286
292
  maxOutputBytes: 256 * 1024
287
293
  }).catch((err) => ({ code: 1, stdout: '', stderr: errorMessage(err) }));
294
+ return quiet ? await work : await withHeartbeat('Homebrew install', work, { warnAfterMs: 60_000 });
288
295
  }
289
296
  async function appendFakeBrewLog(env, args) {
290
297
  if (!env.SKS_FAKE_BREW_LOG)
@@ -342,7 +349,7 @@ async function dryRunResult(root, input, env, before, latest, brew, mutationArti
342
349
  warnings: ['dry_run_no_mutation_performed']
343
350
  });
344
351
  }
345
- async function manualResult(root, input, env, before, latest, brew, reason) {
352
+ async function manualResult(root, input, env, before, latest, brew, reason, nextActions = []) {
346
353
  const command = brew.present ? 'sks doctor --fix --yes' : 'sks doctor --fix --install-homebrew --yes';
347
354
  return persistSelfHeal(root, input.missionDir, {
348
355
  schema: 'sks.zellij-self-heal.v1',
@@ -359,7 +366,8 @@ async function manualResult(root, input, env, before, latest, brew, reason) {
359
366
  mutation_guard_artifact: null,
360
367
  homebrew: { present: brew.present, bin: brew.bin, install_attempted: false, install_allowed: false },
361
368
  blockers: [reason],
362
- warnings: []
369
+ warnings: [],
370
+ next_actions: nextActions.length ? nextActions : [`Run: ${command}`]
363
371
  });
364
372
  }
365
373
  async function headlessResult(root, input, before, latest, brew, reason) {
@@ -392,19 +400,6 @@ async function persistSelfHeal(root, missionDir, result) {
392
400
  await writeJsonAtomic(path.join(missionDir, 'zellij-self-heal.json'), normalized).catch(() => undefined);
393
401
  return normalized;
394
402
  }
395
- async function askZellijRepairAllowed(question) {
396
- if (!(process.stdin.isTTY && process.stdout.isTTY))
397
- return false;
398
- const rl = (await import('node:readline')).createInterface({ input: process.stdin, output: process.stdout });
399
- try {
400
- const answer = await new Promise((resolve) => rl.question(question, resolve));
401
- const trimmed = String(answer || '').trim();
402
- return trimmed === '' || /^(y|yes|예|네|응)$/i.test(trimmed);
403
- }
404
- finally {
405
- rl.close();
406
- }
407
- }
408
403
  function errorMessage(err) {
409
404
  return err instanceof Error ? err.message : String(err);
410
405
  }
@@ -1,76 +1,158 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { readZellijSlotTelemetrySnapshot } from './zellij-slot-telemetry.js';
4
+ import { resolveZellijTheme, paint, statusBadge, progressBar, elapsed, ANSI_CODES } from './zellij-theme.js';
4
5
  export function renderZellijSlotPane(input) {
6
+ const theme = resolveZellijTheme();
7
+ const W = Math.max(20, theme.width - 4);
8
+ const t = (s, w = W) => trimInline(String(s ?? ''), w);
5
9
  const mode = input.mode || 'compact-slots';
6
- const maxLines = mode === 'compact-slots' ? 17 : mode === 'dashboard-plus-slots' ? 20 : 32;
7
- const task = trimInline(input.currentTask || input.currentFile || 'waiting for worker intake', 78);
8
- const heartbeat = input.heartbeatAgeMs == null
9
- ? 'unknown'
10
- : input.heartbeatAgeMs < 1000
11
- ? 'now'
12
- : `${Math.max(1, Math.round(input.heartbeatAgeMs / 1000))}s ago`;
13
- const files = firstNonEmptyList(input.changedFiles, input.patchFiles, input.plannedFiles, input.currentFile ? [input.currentFile] : []);
10
+ const maxLines = mode === 'compact-slots' ? 14 : mode === 'dashboard-plus-slots' ? 18 : 30;
14
11
  const events = (input.eventLines || []).filter(Boolean).slice(-10);
15
12
  const stdout = (input.stdoutTail || []).filter(Boolean).slice(-6);
16
13
  const stderr = (input.stderrTail || []).filter(Boolean).slice(-1);
14
+ const fullDebug = mode === 'full-debug';
17
15
  const fixtureLoopProof = String(input.backend || '').includes('fixture') || String(input.patchStatus || '').includes('fixture');
16
+ const meta = [input.model || input.provider || '?', input.serviceTier || '?'].filter(Boolean).join('·');
17
+ const head = `${statusBadge(theme, input.status || 'queued')} ${paint(theme, ANSI_CODES.bold, input.slotId)}` +
18
+ ` ${t(input.role || 'worker', 12)} ${paint(theme, ANSI_CODES.dim, t(meta, 28))}`;
19
+ const prog = input.progress && input.progress.total > 0
20
+ ? progressBar(theme, input.progress.done, input.progress.total)
21
+ : paint(theme, ANSI_CODES.dim, `elapsed ${elapsed(input.telemetryTs) || '-'} heartbeat ${formatHeartbeat(input.heartbeatAgeMs)}`);
22
+ const doing = `${paint(theme, ANSI_CODES.bold, '▸ ')}${t(input.currentTask || 'waiting for work item')}`;
23
+ const file = input.currentFile ? paint(theme, ANSI_CODES.dim, `file ${t(input.currentFile)}`) : null;
24
+ const worktree = input.worktreeId ? paint(theme, ANSI_CODES.dim, `worktree ${t(input.worktreeId, 32)}`) : null;
25
+ const patch = ((input.patchStatus && input.patchStatus !== 'queued') || (input.verifyStatus && input.verifyStatus !== 'queued'))
26
+ ? `patch ${t(input.patchStatus || '-', 18)} · verify ${t(input.verifyStatus || '-', 18)}`
27
+ : null;
28
+ const blockers = (input.blockers || []).slice(0, 2).map((b) => paint(theme, ANSI_CODES.red, `! ${t(b)}`));
29
+ const tail = [
30
+ ...stderr.slice(-1).map((line) => paint(theme, ANSI_CODES.red, `err ${t(line)}`)),
31
+ ...stdout.slice(-3).map((line) => paint(theme, ANSI_CODES.dim, ` ${t(line)}`))
32
+ ];
18
33
  const rows = [
19
- input.loopId ? `${trimInline(input.loopId, 28)} · ${trimInline(input.loopRole || input.role || 'worker', 14)} · ${input.slotId}` : null,
20
- `slot: ${input.slotId} / gen-${Math.max(1, Math.floor(Number(input.generationIndex) || 1))} / ${trimInline(input.status || 'running', 18)}`,
21
- `role: ${trimInline(input.role || 'worker', 18)} backend: ${trimInline(input.backend || 'codex-sdk', 20)} worktree: ${trimInline(input.worktreeId || '-', 18)}`,
22
- `runtime: fast ${formatFastMode(input.fastMode, input.serviceTier)} tier: ${trimInline(input.serviceTier || 'unknown', 12)} provider: ${trimInline(input.provider || 'unknown', 18)}`,
23
- `model: ${trimInline(input.model || 'unknown', 28)} reasoning: ${trimInline(input.reasoningEffort || 'unknown', 16)}${input.authMode ? ` auth: ${trimInline(input.authMode, 14)}` : ''}`,
24
- input.sessionId ? `session: ${trimInline(input.sessionId, 62)}` : null,
25
- `heartbeat: ${heartbeat}${input.heartbeatEvent ? ` event: ${trimInline(input.heartbeatEvent, 40)}` : ''}`,
26
- `doing: ${task}`,
27
- input.loopGate ? `gate: ${trimInline(input.loopGate, 68)}${input.verifyStatus ? ` · ${trimInline(input.verifyStatus, 18)}` : ''}` : null,
28
- fixtureLoopProof ? 'fixture loop proof · not production execution' : null,
29
- `files: ${trimInline(files.length ? files.join(', ') : 'no changed file yet', 78)}`,
30
- `patch: ${trimInline(input.patchStatus || 'queued', 24)} verify: ${trimInline(input.verifyStatus || 'queued', 24)}`,
31
- input.qaAppHandoffPending ? `QA app handoff pending: ${trimInline(input.qaAppHandoffArtifact || 'qa-loop/app-handoff.json', 55)}` : null,
32
- ...events.map((event) => `event: ${trimInline(event, 78)}`),
33
- ...stdout.map((line) => `out: ${trimInline(line, 79)}`),
34
- ...stderr.map((line) => `err: ${trimInline(line, 79)}`)
34
+ head,
35
+ prog,
36
+ doing,
37
+ file,
38
+ worktree,
39
+ patch,
40
+ input.qaAppHandoffPending ? `QA app handoff pending: ${t(input.qaAppHandoffArtifact || 'qa-loop/app-handoff.json')}` : null,
41
+ ...blockers,
42
+ ...tail,
43
+ ...(fullDebug ? [
44
+ input.sessionId ? `session ${t(input.sessionId, 62)}` : null,
45
+ input.loopId ? `loop ${t(input.loopId, 28)} · ${t(input.loopRole || input.role || 'worker', 14)}` : null,
46
+ input.loopGate ? `gate ${t(input.loopGate)}` : null,
47
+ fixtureLoopProof ? 'fixture loop proof · not production execution' : null,
48
+ ...events.map((event) => `event ${t(event)}`)
49
+ ] : [])
35
50
  ].filter((row) => Boolean(row));
36
- return frameSlotPane(`LIVE SLOT ${input.slotId}`, rows.slice(0, Math.max(1, maxLines - 2)));
51
+ return frameSlotPane(input.slotId, rows.slice(0, Math.max(1, maxLines - 2)), theme);
37
52
  }
38
53
  export async function renderZellijSlotPaneFromArtifacts(input) {
39
- const artifactRender = await renderZellijSlotPaneFromArtifactDir(input).catch(() => null);
54
+ const detail = await renderInputFromArtifactDir(input).catch(() => null);
40
55
  if (input.missionId && input.missionId !== 'latest') {
41
- const telemetry = await tryRenderTelemetrySlotPane({
42
- artifactRoot: input.artifactRoot || input.artifactDir,
43
- missionId: input.missionId,
56
+ const telemetry = await readZellijSlotTelemetrySnapshot(path.resolve(input.artifactRoot || input.artifactDir), input.missionId).catch(() => null);
57
+ const live = findTelemetrySlot(telemetry, input.slotId, input.generationIndex);
58
+ const merged = mergeRenderInputWithLiveTelemetry({
44
59
  slotId: input.slotId,
45
60
  generationIndex: input.generationIndex,
46
- artifactRender
47
- });
48
- if (telemetry)
49
- return telemetry;
50
- if (artifactRender)
51
- return artifactRender;
52
- return [
53
- `${input.slotId} gen-${Math.max(1, Math.floor(Number(input.generationIndex) || 1))}`,
54
- 'waiting for telemetry...',
55
- `mission ${input.missionId}`
56
- ].join('\n');
61
+ role: input.role ?? null,
62
+ backend: input.backend ?? null,
63
+ provider: input.provider ?? null,
64
+ model: input.model ?? null,
65
+ serviceTier: input.serviceTier ?? null,
66
+ reasoningEffort: input.reasoningEffort ?? null,
67
+ currentTask: input.currentTask ?? null,
68
+ status: 'launching',
69
+ mode: input.mode || 'compact-slots',
70
+ ...(detail || {})
71
+ }, live);
72
+ return renderZellijSlotPane(merged);
57
73
  }
58
- if (artifactRender)
59
- return artifactRender;
60
74
  const fallbackInput = {
61
75
  slotId: input.slotId,
62
76
  generationIndex: input.generationIndex,
63
77
  status: 'launching',
64
- currentTask: 'waiting for worker intake',
78
+ currentTask: input.currentTask || 'waiting for worker intake',
65
79
  mode: input.mode || 'compact-slots'
66
80
  };
67
81
  if (input.role !== undefined)
68
82
  fallbackInput.role = input.role;
69
83
  if (input.backend !== undefined)
70
84
  fallbackInput.backend = input.backend;
71
- return renderZellijSlotPane(fallbackInput);
85
+ if (input.provider !== undefined)
86
+ fallbackInput.provider = input.provider;
87
+ if (input.model !== undefined)
88
+ fallbackInput.model = input.model;
89
+ if (input.serviceTier !== undefined)
90
+ fallbackInput.serviceTier = input.serviceTier;
91
+ if (input.reasoningEffort !== undefined)
92
+ fallbackInput.reasoningEffort = input.reasoningEffort;
93
+ return renderZellijSlotPane(detail || fallbackInput);
94
+ }
95
+ function mergeRenderInputWithLiveTelemetry(detail, live) {
96
+ if (!live)
97
+ return detail;
98
+ return {
99
+ ...detail,
100
+ status: live.status ?? detail.status,
101
+ currentTask: live.task_title || detail.currentTask || null,
102
+ currentFile: live.current_file || detail.currentFile || null,
103
+ role: live.role || detail.role || null,
104
+ backend: live.backend || detail.backend || null,
105
+ provider: live.provider || detail.provider || null,
106
+ serviceTier: live.service_tier || detail.serviceTier || null,
107
+ progress: live.progress ?? null,
108
+ blockers: live.blockers || [],
109
+ telemetryTs: live.latest_ts || null,
110
+ heartbeatAgeMs: live.latest_ts ? Math.max(0, Date.now() - Date.parse(live.latest_ts)) : detail.heartbeatAgeMs ?? null,
111
+ worktreeId: live.worktree_id || detail.worktreeId || null
112
+ };
72
113
  }
73
114
  async function renderZellijSlotPaneFromArtifactDir(input) {
115
+ const detail = await renderInputFromArtifactDir(input);
116
+ if (!detail)
117
+ return null;
118
+ return renderZellijSlotPane(detail);
119
+ }
120
+ async function renderInputFromArtifactDir(input) {
121
+ const envDefaults = {
122
+ provider: (input.provider ?? process.env.SKS_SLOT_PROVIDER) || null,
123
+ model: (input.model ?? process.env.SKS_SLOT_MODEL) || null,
124
+ serviceTier: (input.serviceTier ?? process.env.SKS_SLOT_TIER) || null,
125
+ reasoningEffort: (input.reasoningEffort ?? process.env.SKS_SLOT_REASONING) || null,
126
+ currentTask: (input.currentTask ?? process.env.SKS_SLOT_TASK) || null,
127
+ role: (input.role ?? process.env.SKS_SLOT_ROLE) || null
128
+ };
129
+ const detail = await renderInputFromArtifactDirRaw(input);
130
+ if (!detail) {
131
+ return {
132
+ slotId: input.slotId,
133
+ generationIndex: input.generationIndex,
134
+ role: envDefaults.role,
135
+ backend: input.backend || null,
136
+ provider: envDefaults.provider,
137
+ model: envDefaults.model,
138
+ serviceTier: envDefaults.serviceTier,
139
+ reasoningEffort: envDefaults.reasoningEffort,
140
+ currentTask: envDefaults.currentTask || 'waiting for worker intake',
141
+ status: 'launching',
142
+ mode: input.mode || 'compact-slots'
143
+ };
144
+ }
145
+ return {
146
+ ...detail,
147
+ role: detail.role || envDefaults.role,
148
+ provider: detail.provider || envDefaults.provider,
149
+ model: detail.model || envDefaults.model,
150
+ serviceTier: detail.serviceTier || envDefaults.serviceTier,
151
+ reasoningEffort: detail.reasoningEffort || envDefaults.reasoningEffort,
152
+ currentTask: detail.currentTask || envDefaults.currentTask
153
+ };
154
+ }
155
+ async function renderInputFromArtifactDirRaw(input) {
74
156
  const artifactDir = path.resolve(input.artifactDir);
75
157
  const result = await readJson(path.join(artifactDir, 'worker-result.json'));
76
158
  const intake = await readJson(path.join(artifactDir, 'worker-intake.json'));
@@ -105,7 +187,7 @@ async function renderZellijSlotPaneFromArtifactDir(input) {
105
187
  const qaAppHandoff = await readQaAppHandoffNearArtifactDir(artifactDir);
106
188
  if (!result && !intake && !backendReport && !processReport && !paneReport && !codexProof && !localProof && !heartbeatMtime && !eventRows.length)
107
189
  return null;
108
- return renderZellijSlotPane({
190
+ return {
109
191
  slotId: input.slotId,
110
192
  generationIndex: input.generationIndex,
111
193
  sessionId: result?.session_id || intake?.agent?.session_id || backendReport?.session_id || null,
@@ -164,7 +246,7 @@ async function renderZellijSlotPaneFromArtifactDir(input) {
164
246
  qaAppHandoffPending: ['pending', 'blocked_for_desktop_review'].includes(String(qaAppHandoff?.status || '')),
165
247
  qaAppHandoffArtifact: qaAppHandoff?.artifact_path || null,
166
248
  mode: input.mode || 'compact-slots'
167
- });
249
+ };
168
250
  }
169
251
  async function readQaAppHandoffNearArtifactDir(artifactDir) {
170
252
  let current = path.resolve(artifactDir);
@@ -226,78 +308,25 @@ export function buildZellijSlotPaneCommand(input) {
226
308
  ...(input.role ? ['--role', input.role] : []),
227
309
  ...(input.watch ? ['--watch'] : [])
228
310
  ];
229
- return [input.nodePath || process.execPath, ...args].map(shellQuote).join(' ');
230
- }
231
- async function tryRenderTelemetrySlotPane(input) {
232
- const snapshot = await readZellijSlotTelemetrySnapshot(path.resolve(input.artifactRoot), input.missionId).catch(() => null);
233
- if (!snapshot || !Object.keys(snapshot.slots || {}).length)
234
- return null;
235
- const slot = findTelemetrySlot(snapshot, input.slotId, input.generationIndex);
236
- if (!slot)
237
- return null;
238
- const staleRows = staleTelemetryRows(telemetryStatus(snapshot).telemetry_age_ms);
239
- const fallbackRows = artifactFallbackRows(input.artifactRender);
240
- // Always surface the live artifact rows (current file, tool events, stdout
241
- // tail). Telemetry freshness only tells us the worker is alive — the user
242
- // still needs to see WHAT the worker is doing right now.
243
- const liveRows = fallbackRows;
244
- if (slot.status === 'failed') {
245
- return [
246
- `${slot.slot_id} gen-${slot.generation_index} · FAILED`,
247
- ...staleRows,
248
- ...liveRows,
249
- `blocker: ${trimInline(slot.blockers[0] || 'worker_failed', 78)}`,
250
- `artifact: ${trimInline(slot.artifact_paths[slot.artifact_paths.length - 1] || '-', 78)}`
251
- ].join('\n');
252
- }
253
- if (slot.status === 'completed' || slot.status === 'drained') {
254
- return [
255
- `${slot.slot_id} gen-${slot.generation_index} · done`,
256
- ...staleRows,
257
- ...liveRows,
258
- `artifacts ${slot.artifact_paths.length} · ${slot.latest_event_type === 'verification_passed' ? 'verify passed' : 'verify queued'}`,
259
- 'closing in 3s'
260
- ].join('\n');
261
- }
262
- const backend = [slot.backend, slot.service_tier, slot.worktree_id].filter((value) => value && value !== 'unknown').join(' · ') || 'worker';
263
- const heartbeat = slot.latest_ts ? `${Math.max(0, Math.round((Date.now() - Date.parse(slot.latest_ts)) / 1000))}s` : '?';
264
- return [
265
- `${slot.slot_id} gen-${slot.generation_index} · ${trimInline(slot.role || 'worker', 28)}`,
266
- ...staleRows,
267
- ...liveRows,
268
- trimInline(backend, 78),
269
- `${slot.status}: ${trimInline(slot.task_title || 'worker task', 68)}`,
270
- `${formatTelemetryProgress(slot.progress, slot.started_at || slot.latest_ts)} · latest ${slot.latest_event_type} ${heartbeat}`,
271
- `${slot.latest_event_type === 'patch_candidate' ? 'patch candidate' : 'patch'}: ${slot.latest_event_type === 'patch_candidate' ? 'queued' : trimInline(slot.current_file || '-', 42)}`
272
- ].join('\n');
273
- }
274
- function artifactFallbackRows(text) {
275
- if (!text)
276
- return [];
277
- return String(text)
278
- .split(/\r?\n/)
279
- .map((line) => line.replace(/^\|\s?/, '').replace(/\s?\|$/, '').trim())
280
- .filter((line) => /^(heartbeat|doing|files|event|out|err):\s+/i.test(line))
281
- .filter((line) => !/unknown|waiting for worker intake|no changed file yet/i.test(line))
282
- .slice(-12)
283
- .map((line) => `live: ${trimInline(line, 72)}`);
311
+ const env = {
312
+ SKS_SLOT_PROVIDER: String(input.provider || ''),
313
+ SKS_SLOT_MODEL: String(input.model || ''),
314
+ SKS_SLOT_TIER: String(input.serviceTier || ''),
315
+ SKS_SLOT_REASONING: String(input.reasoningEffort || ''),
316
+ SKS_SLOT_TASK: String(input.currentTask || '').slice(0, 200),
317
+ SKS_SLOT_ROLE: String(input.role || '')
318
+ };
319
+ const envPrefix = Object.entries(env)
320
+ .filter(([, value]) => value)
321
+ .map(([key, value]) => `${key}=${shellQuote(value)}`);
322
+ return [...envPrefix, input.nodePath || process.execPath, ...args].map((part, index) => index < envPrefix.length ? part : shellQuote(part)).join(' ');
284
323
  }
285
324
  function findTelemetrySlot(snapshot, slotId, generationIndex) {
325
+ if (!snapshot)
326
+ return null;
286
327
  const generation = Math.max(1, Math.floor(Number(generationIndex) || 1));
287
328
  return Object.values(snapshot.slots || {}).find((row) => row.slot_id === slotId && Number(row.generation_index) === generation) || null;
288
329
  }
289
- function formatTelemetryProgress(progress, startedAt) {
290
- if (!progress || (progress.total === 0 && progress.done > 0))
291
- return `elapsed ${formatElapsedSince(startedAt)}`;
292
- return `progress ${progress.done}/${progress.total}${progress.label ? ` ${trimInline(progress.label, 24)}` : ''}`;
293
- }
294
- function formatElapsedSince(startedAt) {
295
- const start = Date.parse(String(startedAt || ''));
296
- const seconds = Number.isFinite(start) ? Math.max(0, Math.floor((Date.now() - start) / 1000)) : 0;
297
- const mins = Math.floor(seconds / 60);
298
- const secs = seconds % 60;
299
- return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
300
- }
301
330
  function telemetryStatus(snapshot) {
302
331
  const parsed = snapshot?.updated_at ? Date.parse(snapshot.updated_at) : NaN;
303
332
  const telemetryAgeMs = Number.isFinite(parsed) ? Math.max(0, Date.now() - parsed) : Number.MAX_SAFE_INTEGER;
@@ -309,15 +338,6 @@ function telemetryStatus(snapshot) {
309
338
  telemetry_age_ms: telemetryAgeMs
310
339
  };
311
340
  }
312
- function staleTelemetryRows(ageMs) {
313
- if (!Number.isFinite(ageMs))
314
- return ['telemetry stale; worker may still be running'];
315
- if (ageMs > 60000)
316
- return ['telemetry stale; worker may still be running'];
317
- if (ageMs > 15000)
318
- return [`telemetry stale ${(ageMs / 1000).toFixed(1)}s`];
319
- return [];
320
- }
321
341
  async function readJson(file) {
322
342
  try {
323
343
  return JSON.parse(await fs.promises.readFile(file, 'utf8'));
@@ -463,14 +483,6 @@ function firstDefined(...values) {
463
483
  }
464
484
  return null;
465
485
  }
466
- function firstNonEmptyList(...values) {
467
- for (const value of values) {
468
- const normalized = normalizeList(value || []);
469
- if (normalized.length)
470
- return normalized;
471
- }
472
- return [];
473
- }
474
486
  function normalizeList(values) {
475
487
  return [...new Set((Array.isArray(values) ? values : [values]).map((value) => String(value || '').trim()).filter(Boolean))];
476
488
  }
@@ -478,31 +490,28 @@ function trimInline(value, max) {
478
490
  const text = String(value || '').replace(/\s+/g, ' ').trim();
479
491
  if (text.length <= max)
480
492
  return text;
481
- return text.slice(0, Math.max(1, max - 3)) + '...';
482
- }
483
- function formatFastMode(value, serviceTier) {
484
- const text = String(value ?? '').trim().toLowerCase();
485
- if (value === true || text === 'true' || text === '1' || text === 'on' || text === 'fast')
486
- return 'on';
487
- if (value === false || text === 'false' || text === '0' || text === 'off' || text === 'standard')
488
- return 'off';
489
- const tier = String(serviceTier || '').trim().toLowerCase();
490
- if (tier === 'fast' || tier === 'priority')
491
- return 'on';
492
- if (tier === 'standard' || tier === 'default')
493
- return 'off';
494
- return 'unknown';
495
- }
496
- function frameSlotPane(title, rows) {
497
- const width = Math.min(96, Math.max(44, title.length + 6, ...rows.map((row) => row.length + 4)));
498
- const line = '+' + '-'.repeat(width - 2) + '+';
499
- const label = ` ${trimInline(title, width - 4)} `;
500
- const titleLine = '|' + label.padEnd(width - 2, ' ') + '|';
493
+ return text.slice(0, Math.max(1, max - 1)) + '';
494
+ }
495
+ function formatHeartbeat(value) {
496
+ if (value == null || !Number.isFinite(value))
497
+ return 'unknown';
498
+ if (value < 1000)
499
+ return 'now';
500
+ return `${Math.max(1, Math.round(value / 1000))}s`;
501
+ }
502
+ function frameSlotPane(title, rows, theme) {
503
+ const width = theme.width;
504
+ const strip = (s) => s.replace(/\x1b\[[0-9;]*m/g, '');
505
+ const inner = width - 2;
506
+ const visibleTitle = strip(title);
507
+ const top = `┌─ ${title} ${'─'.repeat(Math.max(0, inner - visibleTitle.length - 4))}┐`;
501
508
  const body = rows.map((row) => {
502
- const text = ` ${trimInline(row, width - 4)} `;
503
- return '|' + text.padEnd(width - 2, ' ') + '|';
509
+ const visible = strip(row);
510
+ const clipped = visible.length > inner - 2 ? trimInline(row, inner - 2) : row;
511
+ const pad = Math.max(0, inner - strip(clipped).length - 1);
512
+ return `│ ${clipped}${' '.repeat(pad)}│`;
504
513
  });
505
- return [line, titleLine, line, ...body, line].join('\n');
514
+ return [paint(theme, ANSI_CODES.gray, top), ...body, paint(theme, ANSI_CODES.gray, `└${'─'.repeat(inner)}┘`)].join('\n');
506
515
  }
507
516
  function shellQuote(value) {
508
517
  return `'${String(value).replace(/'/g, `'\\''`)}'`;
@@ -186,6 +186,7 @@ function normalizeTelemetryEvent(event) {
186
186
  ...(event.task_id ? { task_id: String(event.task_id) } : {}),
187
187
  ...(event.task_title ? { task_title: String(event.task_title) } : {}),
188
188
  current_file: event.current_file == null ? null : String(event.current_file),
189
+ ...(event.spawned_at ? { spawned_at: String(event.spawned_at) } : {}),
189
190
  ...(event.progress ? (() => {
190
191
  const progress = normalizeProgress(event.progress);
191
192
  return progress ? { progress } : {};
@@ -220,6 +221,7 @@ function mergeSlotTelemetry(previous, event) {
220
221
  latest_event_type: stale ? previous.latest_event_type : event.event_type,
221
222
  latest_ts: stale ? previous.latest_ts : event.ts,
222
223
  started_at: previous?.started_at || event.ts,
224
+ spawned_at: event.spawned_at || previous?.spawned_at || event.ts,
223
225
  progress: stale ? previous.progress || (terminalRegression ? null : event.progress || null) : event.progress || previous?.progress || null,
224
226
  artifact_paths: unique([...(previous?.artifact_paths || []), ...(event.artifact_paths || [])]),
225
227
  blockers: unique([...(previous?.blockers || []), ...(event.blockers || [])]),
@@ -0,0 +1,67 @@
1
+ const ANSI = {
2
+ reset: '\x1b[0m',
3
+ dim: '\x1b[2m',
4
+ bold: '\x1b[1m',
5
+ red: '\x1b[31m',
6
+ green: '\x1b[32m',
7
+ yellow: '\x1b[33m',
8
+ cyan: '\x1b[36m',
9
+ magenta: '\x1b[35m',
10
+ gray: '\x1b[90m'
11
+ };
12
+ export function resolveZellijTheme() {
13
+ const noColor = process.env.NO_COLOR === '1' || process.env.SKS_ZELLIJ_COLOR === '0';
14
+ return {
15
+ color: !noColor && process.stdout.isTTY !== false,
16
+ width: Math.min(Math.max(Number(process.stdout.columns) || 100, 60), 140),
17
+ statusIcon: {
18
+ running: '●',
19
+ verifying: '◍',
20
+ queued: '◌',
21
+ launching: '◌',
22
+ done: '✔',
23
+ completed: '✔',
24
+ failed: '✖',
25
+ blocked: '■',
26
+ timed_out: '⏱',
27
+ headless: '·',
28
+ drained: '✔'
29
+ },
30
+ statusColor: {
31
+ running: ANSI.green,
32
+ verifying: ANSI.cyan,
33
+ queued: ANSI.gray,
34
+ launching: ANSI.gray,
35
+ done: ANSI.green,
36
+ completed: ANSI.green,
37
+ failed: ANSI.red,
38
+ blocked: ANSI.yellow,
39
+ timed_out: ANSI.red,
40
+ headless: ANSI.gray,
41
+ drained: ANSI.green
42
+ }
43
+ };
44
+ }
45
+ export function paint(theme, code, text) {
46
+ return theme.color && code ? `${code}${text}${ANSI.reset}` : text;
47
+ }
48
+ export function statusBadge(theme, status) {
49
+ const s = String(status || 'queued').toLowerCase();
50
+ const icon = theme.statusIcon[s] || '●';
51
+ return paint(theme, theme.statusColor[s] || '', `${icon} ${s}`);
52
+ }
53
+ export function progressBar(theme, done, total, width = 10) {
54
+ if (!Number.isFinite(total) || total <= 0)
55
+ return '';
56
+ const filled = Math.max(0, Math.min(width, Math.round((done / total) * width)));
57
+ return `${paint(theme, ANSI.green, '▉'.repeat(filled))}${paint(theme, ANSI.gray, '▁'.repeat(width - filled))} ${done}/${total}`;
58
+ }
59
+ export function elapsed(sinceIso) {
60
+ const t = Date.parse(String(sinceIso || ''));
61
+ if (!Number.isFinite(t))
62
+ return '';
63
+ const s = Math.max(0, Math.floor((Date.now() - t) / 1000));
64
+ return `${String(Math.floor(s / 60)).padStart(2, '0')}:${String(s % 60).padStart(2, '0')}`;
65
+ }
66
+ export const ANSI_CODES = ANSI;
67
+ //# sourceMappingURL=zellij-theme.js.map
@@ -1,3 +1,14 @@
1
+ export function resolveZellijUiConfig(args = [], env = process.env) {
2
+ return {
3
+ mode: resolveZellijUiMode(args, env),
4
+ color: env.SKS_ZELLIJ_COLOR !== '0' && env.NO_COLOR !== '1',
5
+ visiblePanes: Number(env.SKS_ZELLIJ_VISIBLE_PANES) || null,
6
+ viewports: boundedInt(env.SKS_ZELLIJ_VIEWPORTS, 4, 0, 6),
7
+ monitorRows: Math.max(4, Number(env.SKS_ZELLIJ_MONITOR_ROWS || 12)),
8
+ monitor: env.SKS_ZELLIJ_MONITOR_PANE !== '0',
9
+ intervalMs: Math.max(500, Number(env.SKS_ZELLIJ_REFRESH_MS) || 1000)
10
+ };
11
+ }
1
12
  export function resolveZellijUiMode(args = [], env = process.env) {
2
13
  return resolveExplicitZellijUiMode(args, env) || 'compact-slots';
3
14
  }
@@ -30,4 +41,9 @@ function resolveExplicitZellijUiMode(args = [], env = process.env) {
30
41
  export function zellijUiModeCreatesDashboard(mode) {
31
42
  return mode === 'dashboard-plus-slots';
32
43
  }
44
+ function boundedInt(value, fallback, min, max) {
45
+ const parsed = Math.floor(Number(value ?? fallback));
46
+ const n = Number.isFinite(parsed) ? parsed : fallback;
47
+ return Math.max(min, Math.min(n, max));
48
+ }
33
49
  //# sourceMappingURL=zellij-ui-mode.js.map