@openrig/cli 0.5.8 → 0.5.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 (781) hide show
  1. package/daemon/assets/claude-statusline-context.cjs +1 -0
  2. package/daemon/assets/plugins/openrig-core/README.md +1 -1
  3. package/daemon/assets/plugins/openrig-core/skills/agent-operated-software/SKILL.md +92 -0
  4. package/daemon/assets/plugins/openrig-core/skills/agent-operated-workflows/SKILL.md +79 -0
  5. package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +2 -2
  6. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +4 -2
  7. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +12 -16
  8. package/daemon/assets/plugins/openrig-core/skills/software-for-agents/SKILL.md +11 -179
  9. package/daemon/context-packs/onboarding-width/manifest.yaml +1 -1
  10. package/daemon/context-packs/onboarding-width/public-what-you-can-do.md +63 -19
  11. package/daemon/context-packs/skills/agent-operated-software/SKILL.md +92 -0
  12. package/daemon/context-packs/skills/agent-operated-software/manifest.yaml +10 -0
  13. package/daemon/context-packs/skills/agent-operated-workflows/SKILL.md +79 -0
  14. package/daemon/context-packs/skills/agent-operated-workflows/manifest.yaml +10 -0
  15. package/daemon/context-packs/skills/applying-a-permission-policy/manifest.yaml +1 -1
  16. package/daemon/context-packs/skills/claude-compaction-restore/manifest.yaml +1 -1
  17. package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
  18. package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
  19. package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
  20. package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
  21. package/daemon/context-packs/skills/core/messaging-the-human/manifest.yaml +1 -1
  22. package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
  23. package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
  24. package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
  25. package/daemon/context-packs/skills/core/openrig-skills/SKILL.md +4 -2
  26. package/daemon/context-packs/skills/core/openrig-skills/manifest.yaml +1 -1
  27. package/daemon/context-packs/skills/core/openrig-upgrade/SKILL.md +81 -0
  28. package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +3 -1
  29. package/daemon/context-packs/skills/core/openrig-upgrade/scripts/migrate-telemetry-state-0.5.9.mjs +1419 -0
  30. package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
  31. package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
  32. package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
  33. package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
  34. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
  35. package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
  36. package/daemon/context-packs/skills/delegating-work/manifest.yaml +1 -1
  37. package/daemon/context-packs/skills/forming-an-openrig-mental-model/SKILL.md +2 -2
  38. package/daemon/context-packs/skills/forming-an-openrig-mental-model/manifest.yaml +1 -1
  39. package/daemon/context-packs/skills/loading-addressable-markdown/manifest.yaml +1 -1
  40. package/daemon/context-packs/skills/mission-slice-sop/manifest.yaml +1 -1
  41. package/daemon/context-packs/skills/openrig-operating-model/manifest.yaml +1 -1
  42. package/daemon/context-packs/skills/openrig-user/SKILL.md +12 -16
  43. package/daemon/context-packs/skills/openrig-user/manifest.yaml +1 -1
  44. package/daemon/context-packs/skills/orienting-to-an-inherited-seat/manifest.yaml +1 -1
  45. package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
  46. package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
  47. package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
  48. package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
  49. package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
  50. package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +1 -1
  51. package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
  52. package/daemon/context-packs/skills/pods/development-team/manifest.yaml +1 -1
  53. package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
  54. package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
  55. package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
  56. package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
  57. package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
  58. package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
  59. package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
  60. package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
  61. package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
  62. package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +1 -1
  63. package/daemon/context-packs/skills/queue-handoff/manifest.yaml +1 -1
  64. package/daemon/context-packs/skills/refocusing/manifest.yaml +1 -1
  65. package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/manifest.yaml +1 -1
  66. package/daemon/context-packs/skills/seat-continuity-and-handover/manifest.yaml +1 -1
  67. package/daemon/context-packs/skills/session-compaction-and-restore/manifest.yaml +1 -1
  68. package/daemon/context-packs/skills/software-for-agents/SKILL.md +11 -179
  69. package/daemon/context-packs/skills/software-for-agents/manifest.yaml +3 -3
  70. package/daemon/context-packs/world-example/manifest.yaml +1 -1
  71. package/daemon/context-packs/world-example/your-world.md +1 -1
  72. package/daemon/context-packs/world-public/build-your-world.md +19 -0
  73. package/daemon/context-packs/world-public/claims.yaml +5 -1
  74. package/daemon/context-packs/world-public/manifest.yaml +40 -1
  75. package/daemon/context-packs/world-public/verify-world.sh +25 -9
  76. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  77. package/daemon/dist/adapters/claude-code-adapter.js +4 -2
  78. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  79. package/daemon/dist/build-info.js +3 -3
  80. package/daemon/dist/db/all-migrations.d.ts +1 -1
  81. package/daemon/dist/db/all-migrations.d.ts.map +1 -1
  82. package/daemon/dist/db/all-migrations.js +3 -1
  83. package/daemon/dist/db/all-migrations.js.map +1 -1
  84. package/daemon/dist/db/migrations/046_seat_identity_verdicts.d.ts +8 -5
  85. package/daemon/dist/db/migrations/046_seat_identity_verdicts.d.ts.map +1 -1
  86. package/daemon/dist/db/migrations/046_seat_identity_verdicts.js +8 -5
  87. package/daemon/dist/db/migrations/046_seat_identity_verdicts.js.map +1 -1
  88. package/daemon/dist/db/migrations/079_workflow_lifecycle_parallel.d.ts +8 -0
  89. package/daemon/dist/db/migrations/079_workflow_lifecycle_parallel.d.ts.map +1 -0
  90. package/daemon/dist/db/migrations/079_workflow_lifecycle_parallel.js +50 -0
  91. package/daemon/dist/db/migrations/079_workflow_lifecycle_parallel.js.map +1 -0
  92. package/daemon/dist/domain/active-occupant.d.ts +6 -1
  93. package/daemon/dist/domain/active-occupant.d.ts.map +1 -1
  94. package/daemon/dist/domain/active-occupant.js +47 -0
  95. package/daemon/dist/domain/active-occupant.js.map +1 -1
  96. package/daemon/dist/domain/bootstrap-orchestrator.d.ts.map +1 -1
  97. package/daemon/dist/domain/bootstrap-orchestrator.js +8 -1
  98. package/daemon/dist/domain/bootstrap-orchestrator.js.map +1 -1
  99. package/daemon/dist/domain/bundle-context-packs-router.d.ts +3 -3
  100. package/daemon/dist/domain/bundle-context-packs-router.d.ts.map +1 -1
  101. package/daemon/dist/domain/bundle-skills-router.d.ts +3 -0
  102. package/daemon/dist/domain/bundle-skills-router.d.ts.map +1 -1
  103. package/daemon/dist/domain/bundle-skills-router.js +5 -1
  104. package/daemon/dist/domain/bundle-skills-router.js.map +1 -1
  105. package/daemon/dist/domain/claim-service.d.ts +2 -0
  106. package/daemon/dist/domain/claim-service.d.ts.map +1 -1
  107. package/daemon/dist/domain/claim-service.js +33 -12
  108. package/daemon/dist/domain/claim-service.js.map +1 -1
  109. package/daemon/dist/domain/context-packs/context-pack-library-service.d.ts.map +1 -1
  110. package/daemon/dist/domain/context-packs/context-pack-library-service.js +9 -1
  111. package/daemon/dist/domain/context-packs/context-pack-library-service.js.map +1 -1
  112. package/daemon/dist/domain/context-packs/context-pack-types.d.ts +25 -0
  113. package/daemon/dist/domain/context-packs/context-pack-types.d.ts.map +1 -1
  114. package/daemon/dist/domain/context-packs/context-pack-types.js +3 -1
  115. package/daemon/dist/domain/context-packs/context-pack-types.js.map +1 -1
  116. package/daemon/dist/domain/context-packs/manifest-parser.d.ts.map +1 -1
  117. package/daemon/dist/domain/context-packs/manifest-parser.js +143 -3
  118. package/daemon/dist/domain/context-packs/manifest-parser.js.map +1 -1
  119. package/daemon/dist/domain/context-packs/profile-composer.d.ts +22 -1
  120. package/daemon/dist/domain/context-packs/profile-composer.d.ts.map +1 -1
  121. package/daemon/dist/domain/context-packs/profile-composer.js +105 -40
  122. package/daemon/dist/domain/context-packs/profile-composer.js.map +1 -1
  123. package/daemon/dist/domain/context-usage-store.d.ts +4 -0
  124. package/daemon/dist/domain/context-usage-store.d.ts.map +1 -1
  125. package/daemon/dist/domain/context-usage-store.js +8 -4
  126. package/daemon/dist/domain/context-usage-store.js.map +1 -1
  127. package/daemon/dist/domain/crash-cart-conductor.d.ts +13 -0
  128. package/daemon/dist/domain/crash-cart-conductor.d.ts.map +1 -1
  129. package/daemon/dist/domain/crash-cart-conductor.js +3 -1
  130. package/daemon/dist/domain/crash-cart-conductor.js.map +1 -1
  131. package/daemon/dist/domain/execution-view.d.ts.map +1 -1
  132. package/daemon/dist/domain/execution-view.js +145 -16
  133. package/daemon/dist/domain/execution-view.js.map +1 -1
  134. package/daemon/dist/domain/instance-initialization.d.ts +25 -0
  135. package/daemon/dist/domain/instance-initialization.d.ts.map +1 -0
  136. package/daemon/dist/domain/instance-initialization.js +81 -0
  137. package/daemon/dist/domain/instance-initialization.js.map +1 -0
  138. package/daemon/dist/domain/lifecycle-manifest.d.ts +19 -0
  139. package/daemon/dist/domain/lifecycle-manifest.d.ts.map +1 -0
  140. package/daemon/dist/domain/lifecycle-manifest.js +73 -0
  141. package/daemon/dist/domain/lifecycle-manifest.js.map +1 -0
  142. package/daemon/dist/domain/model-divergence/current-generation-record.d.ts +36 -36
  143. package/daemon/dist/domain/model-divergence/current-generation-record.d.ts.map +1 -1
  144. package/daemon/dist/domain/model-divergence/current-generation-record.js +104 -135
  145. package/daemon/dist/domain/model-divergence/current-generation-record.js.map +1 -1
  146. package/daemon/dist/domain/native-process-lineage.d.ts +10 -0
  147. package/daemon/dist/domain/native-process-lineage.d.ts.map +1 -0
  148. package/daemon/dist/domain/native-process-lineage.js +86 -0
  149. package/daemon/dist/domain/native-process-lineage.js.map +1 -0
  150. package/daemon/dist/domain/native-resume-probe.js +12 -1
  151. package/daemon/dist/domain/native-resume-probe.js.map +1 -1
  152. package/daemon/dist/domain/node-inventory.d.ts +2 -0
  153. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  154. package/daemon/dist/domain/node-inventory.js +3 -1
  155. package/daemon/dist/domain/node-inventory.js.map +1 -1
  156. package/daemon/dist/domain/node-launcher.d.ts +3 -0
  157. package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  158. package/daemon/dist/domain/node-launcher.js +21 -8
  159. package/daemon/dist/domain/node-launcher.js.map +1 -1
  160. package/daemon/dist/domain/pane-binding-observation.d.ts +22 -0
  161. package/daemon/dist/domain/pane-binding-observation.d.ts.map +1 -0
  162. package/daemon/dist/domain/pane-binding-observation.js +54 -0
  163. package/daemon/dist/domain/pane-binding-observation.js.map +1 -0
  164. package/daemon/dist/domain/policies/parked-owner-consumer.js +1 -1
  165. package/daemon/dist/domain/policies/parked-owner-consumer.js.map +1 -1
  166. package/daemon/dist/domain/policies/workflow-keepalive.d.ts.map +1 -1
  167. package/daemon/dist/domain/policies/workflow-keepalive.js +16 -2
  168. package/daemon/dist/domain/policies/workflow-keepalive.js.map +1 -1
  169. package/daemon/dist/domain/profile-resolver.d.ts +12 -0
  170. package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
  171. package/daemon/dist/domain/profile-resolver.js +60 -0
  172. package/daemon/dist/domain/profile-resolver.js.map +1 -1
  173. package/daemon/dist/domain/project-lifecycle-compiler.d.ts +35 -0
  174. package/daemon/dist/domain/project-lifecycle-compiler.d.ts.map +1 -0
  175. package/daemon/dist/domain/project-lifecycle-compiler.js +190 -0
  176. package/daemon/dist/domain/project-lifecycle-compiler.js.map +1 -0
  177. package/daemon/dist/domain/provider/claude-usage-reader.d.ts +1 -1
  178. package/daemon/dist/domain/provider/claude-usage-reader.d.ts.map +1 -1
  179. package/daemon/dist/domain/provider/claude-usage-reader.js +28 -18
  180. package/daemon/dist/domain/provider/claude-usage-reader.js.map +1 -1
  181. package/daemon/dist/domain/queue-repository.d.ts +5 -1
  182. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  183. package/daemon/dist/domain/queue-repository.js +6 -0
  184. package/daemon/dist/domain/queue-repository.js.map +1 -1
  185. package/daemon/dist/domain/queue-retention.d.ts +3 -4
  186. package/daemon/dist/domain/queue-retention.d.ts.map +1 -1
  187. package/daemon/dist/domain/queue-retention.js +5 -8
  188. package/daemon/dist/domain/queue-retention.js.map +1 -1
  189. package/daemon/dist/domain/queue-transition-log.d.ts +28 -0
  190. package/daemon/dist/domain/queue-transition-log.d.ts.map +1 -1
  191. package/daemon/dist/domain/queue-transition-log.js +124 -0
  192. package/daemon/dist/domain/queue-transition-log.js.map +1 -1
  193. package/daemon/dist/domain/restore-attempt-receipt.d.ts +34 -0
  194. package/daemon/dist/domain/restore-attempt-receipt.d.ts.map +1 -0
  195. package/daemon/dist/domain/restore-attempt-receipt.js +59 -0
  196. package/daemon/dist/domain/restore-attempt-receipt.js.map +1 -0
  197. package/daemon/dist/domain/restore-orchestrator.d.ts +57 -24
  198. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  199. package/daemon/dist/domain/restore-orchestrator.js +152 -26
  200. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  201. package/daemon/dist/domain/restore-topology.d.ts +14 -0
  202. package/daemon/dist/domain/restore-topology.d.ts.map +1 -0
  203. package/daemon/dist/domain/restore-topology.js +27 -0
  204. package/daemon/dist/domain/restore-topology.js.map +1 -0
  205. package/daemon/dist/domain/rig-lifecycle-service.d.ts.map +1 -1
  206. package/daemon/dist/domain/rig-lifecycle-service.js +9 -0
  207. package/daemon/dist/domain/rig-lifecycle-service.js.map +1 -1
  208. package/daemon/dist/domain/rigspec-instantiator.d.ts +19 -0
  209. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  210. package/daemon/dist/domain/rigspec-instantiator.js +65 -1
  211. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  212. package/daemon/dist/domain/rigspec-preflight.d.ts +8 -0
  213. package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
  214. package/daemon/dist/domain/rigspec-preflight.js +4 -0
  215. package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
  216. package/daemon/dist/domain/seat-attention-reconciler.d.ts +23 -1
  217. package/daemon/dist/domain/seat-attention-reconciler.d.ts.map +1 -1
  218. package/daemon/dist/domain/seat-attention-reconciler.js +97 -46
  219. package/daemon/dist/domain/seat-attention-reconciler.js.map +1 -1
  220. package/daemon/dist/domain/seat-identity-reconciler.d.ts.map +1 -1
  221. package/daemon/dist/domain/seat-identity-reconciler.js +15 -6
  222. package/daemon/dist/domain/seat-identity-reconciler.js.map +1 -1
  223. package/daemon/dist/domain/seat-lifecycle-service.d.ts +47 -1
  224. package/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -1
  225. package/daemon/dist/domain/seat-lifecycle-service.js +525 -29
  226. package/daemon/dist/domain/seat-lifecycle-service.js.map +1 -1
  227. package/daemon/dist/domain/session-registry.d.ts +8 -1
  228. package/daemon/dist/domain/session-registry.d.ts.map +1 -1
  229. package/daemon/dist/domain/session-registry.js +19 -0
  230. package/daemon/dist/domain/session-registry.js.map +1 -1
  231. package/daemon/dist/domain/skill-catalog.d.ts +81 -0
  232. package/daemon/dist/domain/skill-catalog.d.ts.map +1 -0
  233. package/daemon/dist/domain/skill-catalog.js +827 -0
  234. package/daemon/dist/domain/skill-catalog.js.map +1 -0
  235. package/daemon/dist/domain/skill-discovery.d.ts +3 -0
  236. package/daemon/dist/domain/skill-discovery.d.ts.map +1 -1
  237. package/daemon/dist/domain/skill-discovery.js +1 -1
  238. package/daemon/dist/domain/skill-discovery.js.map +1 -1
  239. package/daemon/dist/domain/snapshot-capture.d.ts +4 -1
  240. package/daemon/dist/domain/snapshot-capture.d.ts.map +1 -1
  241. package/daemon/dist/domain/snapshot-capture.js +38 -2
  242. package/daemon/dist/domain/snapshot-capture.js.map +1 -1
  243. package/daemon/dist/domain/snapshot-repository.d.ts +15 -1
  244. package/daemon/dist/domain/snapshot-repository.d.ts.map +1 -1
  245. package/daemon/dist/domain/snapshot-repository.js +103 -1
  246. package/daemon/dist/domain/snapshot-repository.js.map +1 -1
  247. package/daemon/dist/domain/startup-orchestrator.d.ts +2 -0
  248. package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
  249. package/daemon/dist/domain/startup-orchestrator.js +12 -0
  250. package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  251. package/daemon/dist/domain/system-world.d.ts +45 -0
  252. package/daemon/dist/domain/system-world.d.ts.map +1 -0
  253. package/daemon/dist/domain/system-world.js +123 -0
  254. package/daemon/dist/domain/system-world.js.map +1 -0
  255. package/daemon/dist/domain/telemetry-state-paths.d.ts +7 -0
  256. package/daemon/dist/domain/telemetry-state-paths.d.ts.map +1 -0
  257. package/daemon/dist/domain/telemetry-state-paths.js +20 -0
  258. package/daemon/dist/domain/telemetry-state-paths.js.map +1 -0
  259. package/daemon/dist/domain/types.d.ts +103 -4
  260. package/daemon/dist/domain/types.d.ts.map +1 -1
  261. package/daemon/dist/domain/types.js.map +1 -1
  262. package/daemon/dist/domain/user-settings/settings-store.d.ts +8 -3
  263. package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  264. package/daemon/dist/domain/user-settings/settings-store.js +65 -29
  265. package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  266. package/daemon/dist/domain/watchdog-policy-engine.d.ts +7 -23
  267. package/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -1
  268. package/daemon/dist/domain/watchdog-policy-engine.js +44 -226
  269. package/daemon/dist/domain/watchdog-policy-engine.js.map +1 -1
  270. package/daemon/dist/domain/workflow-boot-sweep.d.ts.map +1 -1
  271. package/daemon/dist/domain/workflow-boot-sweep.js +20 -6
  272. package/daemon/dist/domain/workflow-boot-sweep.js.map +1 -1
  273. package/daemon/dist/domain/workflow-instance-store.d.ts +33 -1
  274. package/daemon/dist/domain/workflow-instance-store.d.ts.map +1 -1
  275. package/daemon/dist/domain/workflow-instance-store.js +127 -2
  276. package/daemon/dist/domain/workflow-instance-store.js.map +1 -1
  277. package/daemon/dist/domain/workflow-keepalive-arming.d.ts +7 -5
  278. package/daemon/dist/domain/workflow-keepalive-arming.d.ts.map +1 -1
  279. package/daemon/dist/domain/workflow-keepalive-arming.js +27 -16
  280. package/daemon/dist/domain/workflow-keepalive-arming.js.map +1 -1
  281. package/daemon/dist/domain/workflow-projector.d.ts +6 -2
  282. package/daemon/dist/domain/workflow-projector.d.ts.map +1 -1
  283. package/daemon/dist/domain/workflow-projector.js +271 -2
  284. package/daemon/dist/domain/workflow-projector.js.map +1 -1
  285. package/daemon/dist/domain/workflow-runtime.d.ts +62 -2
  286. package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
  287. package/daemon/dist/domain/workflow-runtime.js +334 -18
  288. package/daemon/dist/domain/workflow-runtime.js.map +1 -1
  289. package/daemon/dist/domain/workflow-spec-cache.d.ts +9 -1
  290. package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
  291. package/daemon/dist/domain/workflow-spec-cache.js +85 -0
  292. package/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
  293. package/daemon/dist/domain/workflow-types.d.ts +38 -1
  294. package/daemon/dist/domain/workflow-types.d.ts.map +1 -1
  295. package/daemon/dist/domain/workflow-types.js.map +1 -1
  296. package/daemon/dist/domain/workflow-validator.d.ts.map +1 -1
  297. package/daemon/dist/domain/workflow-validator.js +20 -3
  298. package/daemon/dist/domain/workflow-validator.js.map +1 -1
  299. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts +38 -9
  300. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  301. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +93 -347
  302. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  303. package/daemon/dist/index.d.ts.map +1 -1
  304. package/daemon/dist/index.js +13 -0
  305. package/daemon/dist/index.js.map +1 -1
  306. package/daemon/dist/instance-initialization-surface.d.ts +3 -0
  307. package/daemon/dist/instance-initialization-surface.d.ts.map +1 -0
  308. package/daemon/dist/instance-initialization-surface.js +3 -0
  309. package/daemon/dist/instance-initialization-surface.js.map +1 -0
  310. package/daemon/dist/project-lifecycle-surface.d.ts +3 -0
  311. package/daemon/dist/project-lifecycle-surface.d.ts.map +1 -0
  312. package/daemon/dist/project-lifecycle-surface.js +3 -0
  313. package/daemon/dist/project-lifecycle-surface.js.map +1 -0
  314. package/daemon/dist/routes/bundles.js +10 -9
  315. package/daemon/dist/routes/bundles.js.map +1 -1
  316. package/daemon/dist/routes/config.d.ts.map +1 -1
  317. package/daemon/dist/routes/config.js +27 -49
  318. package/daemon/dist/routes/config.js.map +1 -1
  319. package/daemon/dist/routes/context-packs.d.ts.map +1 -1
  320. package/daemon/dist/routes/context-packs.js +114 -16
  321. package/daemon/dist/routes/context-packs.js.map +1 -1
  322. package/daemon/dist/routes/crash-cart.js +3 -0
  323. package/daemon/dist/routes/crash-cart.js.map +1 -1
  324. package/daemon/dist/routes/queue.d.ts.map +1 -1
  325. package/daemon/dist/routes/queue.js +20 -0
  326. package/daemon/dist/routes/queue.js.map +1 -1
  327. package/daemon/dist/routes/rigs.js +12 -1
  328. package/daemon/dist/routes/rigs.js.map +1 -1
  329. package/daemon/dist/routes/rigspec.js +9 -2
  330. package/daemon/dist/routes/rigspec.js.map +1 -1
  331. package/daemon/dist/routes/seat.js +21 -1
  332. package/daemon/dist/routes/seat.js.map +1 -1
  333. package/daemon/dist/routes/sessions.js +16 -6
  334. package/daemon/dist/routes/sessions.js.map +1 -1
  335. package/daemon/dist/routes/snapshots.d.ts.map +1 -1
  336. package/daemon/dist/routes/snapshots.js +41 -3
  337. package/daemon/dist/routes/snapshots.js.map +1 -1
  338. package/daemon/dist/routes/up.js +12 -1
  339. package/daemon/dist/routes/up.js.map +1 -1
  340. package/daemon/dist/routes/watchdog.d.ts.map +1 -1
  341. package/daemon/dist/routes/watchdog.js +7 -6
  342. package/daemon/dist/routes/watchdog.js.map +1 -1
  343. package/daemon/dist/routes/workflow.d.ts.map +1 -1
  344. package/daemon/dist/routes/workflow.js +104 -39
  345. package/daemon/dist/routes/workflow.js.map +1 -1
  346. package/daemon/dist/server.d.ts +2 -0
  347. package/daemon/dist/server.d.ts.map +1 -1
  348. package/daemon/dist/server.js +1 -0
  349. package/daemon/dist/server.js.map +1 -1
  350. package/daemon/dist/skill-loadout-surface.d.ts +3 -0
  351. package/daemon/dist/skill-loadout-surface.d.ts.map +1 -0
  352. package/daemon/dist/skill-loadout-surface.js +2 -0
  353. package/daemon/dist/skill-loadout-surface.js.map +1 -0
  354. package/daemon/dist/startup.d.ts.map +1 -1
  355. package/daemon/dist/startup.js +72 -65
  356. package/daemon/dist/startup.js.map +1 -1
  357. package/daemon/dist/system-world-surface.d.ts +2 -0
  358. package/daemon/dist/system-world-surface.d.ts.map +1 -0
  359. package/daemon/dist/system-world-surface.js +2 -0
  360. package/daemon/dist/system-world-surface.js.map +1 -0
  361. package/daemon/docs/reference/getting-started.md +2 -1
  362. package/daemon/docs/reference/instance-layout.md +106 -0
  363. package/daemon/docs/reference/mission-install.md +12 -2
  364. package/daemon/docs/reference/project-workspace.md +66 -40
  365. package/daemon/specs/agents/shared/skills/core/openrig-skills/SKILL.md +4 -2
  366. package/daemon/specs/agents/shared/skills/core/openrig-upgrade/SKILL.md +81 -0
  367. package/daemon/specs/agents/shared/skills/core/openrig-upgrade/scripts/migrate-telemetry-state-0.5.9.mjs +1419 -0
  368. package/dist/build-info.js +3 -3
  369. package/dist/commands/config-init-workspace.d.ts +4 -23
  370. package/dist/commands/config-init-workspace.d.ts.map +1 -1
  371. package/dist/commands/config-init-workspace.js +14 -576
  372. package/dist/commands/config-init-workspace.js.map +1 -1
  373. package/dist/commands/config.d.ts.map +1 -1
  374. package/dist/commands/config.js +6 -4
  375. package/dist/commands/config.js.map +1 -1
  376. package/dist/commands/context.d.ts.map +1 -1
  377. package/dist/commands/context.js +114 -8
  378. package/dist/commands/context.js.map +1 -1
  379. package/dist/commands/daemon.d.ts.map +1 -1
  380. package/dist/commands/daemon.js +16 -0
  381. package/dist/commands/daemon.js.map +1 -1
  382. package/dist/commands/launch.d.ts.map +1 -1
  383. package/dist/commands/launch.js +51 -4
  384. package/dist/commands/launch.js.map +1 -1
  385. package/dist/commands/restore.d.ts.map +1 -1
  386. package/dist/commands/restore.js +43 -3
  387. package/dist/commands/restore.js.map +1 -1
  388. package/dist/commands/scope.d.ts.map +1 -1
  389. package/dist/commands/scope.js +169 -79
  390. package/dist/commands/scope.js.map +1 -1
  391. package/dist/commands/seat.d.ts.map +1 -1
  392. package/dist/commands/seat.js +30 -0
  393. package/dist/commands/seat.js.map +1 -1
  394. package/dist/commands/skill.d.ts.map +1 -1
  395. package/dist/commands/skill.js +61 -0
  396. package/dist/commands/skill.js.map +1 -1
  397. package/dist/commands/snapshot.d.ts.map +1 -1
  398. package/dist/commands/snapshot.js +4 -2
  399. package/dist/commands/snapshot.js.map +1 -1
  400. package/dist/commands/start.d.ts.map +1 -1
  401. package/dist/commands/start.js +3 -0
  402. package/dist/commands/start.js.map +1 -1
  403. package/dist/commands/up.d.ts.map +1 -1
  404. package/dist/commands/up.js +3 -0
  405. package/dist/commands/up.js.map +1 -1
  406. package/dist/commands/walk.d.ts.map +1 -1
  407. package/dist/commands/walk.js +3 -0
  408. package/dist/commands/walk.js.map +1 -1
  409. package/dist/commands/workflow-render.d.ts +31 -0
  410. package/dist/commands/workflow-render.d.ts.map +1 -1
  411. package/dist/commands/workflow-render.js +84 -6
  412. package/dist/commands/workflow-render.js.map +1 -1
  413. package/dist/commands/workflow.d.ts.map +1 -1
  414. package/dist/commands/workflow.js +96 -8
  415. package/dist/commands/workflow.js.map +1 -1
  416. package/dist/config-store.d.ts +9 -4
  417. package/dist/config-store.d.ts.map +1 -1
  418. package/dist/config-store.js +67 -30
  419. package/dist/config-store.js.map +1 -1
  420. package/dist/daemon-lifecycle.d.ts +8 -15
  421. package/dist/daemon-lifecycle.d.ts.map +1 -1
  422. package/dist/daemon-lifecycle.js +24 -31
  423. package/dist/daemon-lifecycle.js.map +1 -1
  424. package/dist/lib/scope/mission-composition.d.ts +16 -0
  425. package/dist/lib/scope/mission-composition.d.ts.map +1 -0
  426. package/dist/lib/scope/mission-composition.js +110 -0
  427. package/dist/lib/scope/mission-composition.js.map +1 -0
  428. package/dist/lib/scope/scope-fs.d.ts +5 -0
  429. package/dist/lib/scope/scope-fs.d.ts.map +1 -1
  430. package/dist/lib/scope/scope-fs.js +34 -4
  431. package/dist/lib/scope/scope-fs.js.map +1 -1
  432. package/dist/lib/work-install.d.ts +17 -0
  433. package/dist/lib/work-install.d.ts.map +1 -1
  434. package/dist/lib/work-install.js +49 -6
  435. package/dist/lib/work-install.js.map +1 -1
  436. package/node_modules/@openrig/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  437. package/node_modules/@openrig/daemon/dist/adapters/claude-code-adapter.js +4 -2
  438. package/node_modules/@openrig/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  439. package/node_modules/@openrig/daemon/dist/build-info.js +3 -3
  440. package/node_modules/@openrig/daemon/dist/db/all-migrations.d.ts +1 -1
  441. package/node_modules/@openrig/daemon/dist/db/all-migrations.d.ts.map +1 -1
  442. package/node_modules/@openrig/daemon/dist/db/all-migrations.js +3 -1
  443. package/node_modules/@openrig/daemon/dist/db/all-migrations.js.map +1 -1
  444. package/node_modules/@openrig/daemon/dist/db/migrations/046_seat_identity_verdicts.d.ts +8 -5
  445. package/node_modules/@openrig/daemon/dist/db/migrations/046_seat_identity_verdicts.d.ts.map +1 -1
  446. package/node_modules/@openrig/daemon/dist/db/migrations/046_seat_identity_verdicts.js +8 -5
  447. package/node_modules/@openrig/daemon/dist/db/migrations/046_seat_identity_verdicts.js.map +1 -1
  448. package/node_modules/@openrig/daemon/dist/db/migrations/079_workflow_lifecycle_parallel.d.ts +8 -0
  449. package/node_modules/@openrig/daemon/dist/db/migrations/079_workflow_lifecycle_parallel.d.ts.map +1 -0
  450. package/node_modules/@openrig/daemon/dist/db/migrations/079_workflow_lifecycle_parallel.js +50 -0
  451. package/node_modules/@openrig/daemon/dist/db/migrations/079_workflow_lifecycle_parallel.js.map +1 -0
  452. package/node_modules/@openrig/daemon/dist/domain/active-occupant.d.ts +6 -1
  453. package/node_modules/@openrig/daemon/dist/domain/active-occupant.d.ts.map +1 -1
  454. package/node_modules/@openrig/daemon/dist/domain/active-occupant.js +47 -0
  455. package/node_modules/@openrig/daemon/dist/domain/active-occupant.js.map +1 -1
  456. package/node_modules/@openrig/daemon/dist/domain/bootstrap-orchestrator.d.ts.map +1 -1
  457. package/node_modules/@openrig/daemon/dist/domain/bootstrap-orchestrator.js +8 -1
  458. package/node_modules/@openrig/daemon/dist/domain/bootstrap-orchestrator.js.map +1 -1
  459. package/node_modules/@openrig/daemon/dist/domain/bundle-context-packs-router.d.ts +3 -3
  460. package/node_modules/@openrig/daemon/dist/domain/bundle-context-packs-router.d.ts.map +1 -1
  461. package/node_modules/@openrig/daemon/dist/domain/bundle-skills-router.d.ts +3 -0
  462. package/node_modules/@openrig/daemon/dist/domain/bundle-skills-router.d.ts.map +1 -1
  463. package/node_modules/@openrig/daemon/dist/domain/bundle-skills-router.js +5 -1
  464. package/node_modules/@openrig/daemon/dist/domain/bundle-skills-router.js.map +1 -1
  465. package/node_modules/@openrig/daemon/dist/domain/claim-service.d.ts +2 -0
  466. package/node_modules/@openrig/daemon/dist/domain/claim-service.d.ts.map +1 -1
  467. package/node_modules/@openrig/daemon/dist/domain/claim-service.js +33 -12
  468. package/node_modules/@openrig/daemon/dist/domain/claim-service.js.map +1 -1
  469. package/node_modules/@openrig/daemon/dist/domain/context-packs/context-pack-library-service.d.ts.map +1 -1
  470. package/node_modules/@openrig/daemon/dist/domain/context-packs/context-pack-library-service.js +9 -1
  471. package/node_modules/@openrig/daemon/dist/domain/context-packs/context-pack-library-service.js.map +1 -1
  472. package/node_modules/@openrig/daemon/dist/domain/context-packs/context-pack-types.d.ts +25 -0
  473. package/node_modules/@openrig/daemon/dist/domain/context-packs/context-pack-types.d.ts.map +1 -1
  474. package/node_modules/@openrig/daemon/dist/domain/context-packs/context-pack-types.js +3 -1
  475. package/node_modules/@openrig/daemon/dist/domain/context-packs/context-pack-types.js.map +1 -1
  476. package/node_modules/@openrig/daemon/dist/domain/context-packs/manifest-parser.d.ts.map +1 -1
  477. package/node_modules/@openrig/daemon/dist/domain/context-packs/manifest-parser.js +143 -3
  478. package/node_modules/@openrig/daemon/dist/domain/context-packs/manifest-parser.js.map +1 -1
  479. package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-composer.d.ts +22 -1
  480. package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-composer.d.ts.map +1 -1
  481. package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-composer.js +105 -40
  482. package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-composer.js.map +1 -1
  483. package/node_modules/@openrig/daemon/dist/domain/context-usage-store.d.ts +4 -0
  484. package/node_modules/@openrig/daemon/dist/domain/context-usage-store.d.ts.map +1 -1
  485. package/node_modules/@openrig/daemon/dist/domain/context-usage-store.js +8 -4
  486. package/node_modules/@openrig/daemon/dist/domain/context-usage-store.js.map +1 -1
  487. package/node_modules/@openrig/daemon/dist/domain/crash-cart-conductor.d.ts +13 -0
  488. package/node_modules/@openrig/daemon/dist/domain/crash-cart-conductor.d.ts.map +1 -1
  489. package/node_modules/@openrig/daemon/dist/domain/crash-cart-conductor.js +3 -1
  490. package/node_modules/@openrig/daemon/dist/domain/crash-cart-conductor.js.map +1 -1
  491. package/node_modules/@openrig/daemon/dist/domain/execution-view.d.ts.map +1 -1
  492. package/node_modules/@openrig/daemon/dist/domain/execution-view.js +145 -16
  493. package/node_modules/@openrig/daemon/dist/domain/execution-view.js.map +1 -1
  494. package/node_modules/@openrig/daemon/dist/domain/instance-initialization.d.ts +25 -0
  495. package/node_modules/@openrig/daemon/dist/domain/instance-initialization.d.ts.map +1 -0
  496. package/node_modules/@openrig/daemon/dist/domain/instance-initialization.js +81 -0
  497. package/node_modules/@openrig/daemon/dist/domain/instance-initialization.js.map +1 -0
  498. package/node_modules/@openrig/daemon/dist/domain/lifecycle-manifest.d.ts +19 -0
  499. package/node_modules/@openrig/daemon/dist/domain/lifecycle-manifest.d.ts.map +1 -0
  500. package/node_modules/@openrig/daemon/dist/domain/lifecycle-manifest.js +73 -0
  501. package/node_modules/@openrig/daemon/dist/domain/lifecycle-manifest.js.map +1 -0
  502. package/node_modules/@openrig/daemon/dist/domain/model-divergence/current-generation-record.d.ts +36 -36
  503. package/node_modules/@openrig/daemon/dist/domain/model-divergence/current-generation-record.d.ts.map +1 -1
  504. package/node_modules/@openrig/daemon/dist/domain/model-divergence/current-generation-record.js +104 -135
  505. package/node_modules/@openrig/daemon/dist/domain/model-divergence/current-generation-record.js.map +1 -1
  506. package/node_modules/@openrig/daemon/dist/domain/native-process-lineage.d.ts +10 -0
  507. package/node_modules/@openrig/daemon/dist/domain/native-process-lineage.d.ts.map +1 -0
  508. package/node_modules/@openrig/daemon/dist/domain/native-process-lineage.js +86 -0
  509. package/node_modules/@openrig/daemon/dist/domain/native-process-lineage.js.map +1 -0
  510. package/node_modules/@openrig/daemon/dist/domain/native-resume-probe.js +12 -1
  511. package/node_modules/@openrig/daemon/dist/domain/native-resume-probe.js.map +1 -1
  512. package/node_modules/@openrig/daemon/dist/domain/node-inventory.d.ts +2 -0
  513. package/node_modules/@openrig/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  514. package/node_modules/@openrig/daemon/dist/domain/node-inventory.js +3 -1
  515. package/node_modules/@openrig/daemon/dist/domain/node-inventory.js.map +1 -1
  516. package/node_modules/@openrig/daemon/dist/domain/node-launcher.d.ts +3 -0
  517. package/node_modules/@openrig/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  518. package/node_modules/@openrig/daemon/dist/domain/node-launcher.js +21 -8
  519. package/node_modules/@openrig/daemon/dist/domain/node-launcher.js.map +1 -1
  520. package/node_modules/@openrig/daemon/dist/domain/pane-binding-observation.d.ts +22 -0
  521. package/node_modules/@openrig/daemon/dist/domain/pane-binding-observation.d.ts.map +1 -0
  522. package/node_modules/@openrig/daemon/dist/domain/pane-binding-observation.js +54 -0
  523. package/node_modules/@openrig/daemon/dist/domain/pane-binding-observation.js.map +1 -0
  524. package/node_modules/@openrig/daemon/dist/domain/policies/parked-owner-consumer.js +1 -1
  525. package/node_modules/@openrig/daemon/dist/domain/policies/parked-owner-consumer.js.map +1 -1
  526. package/node_modules/@openrig/daemon/dist/domain/policies/workflow-keepalive.d.ts.map +1 -1
  527. package/node_modules/@openrig/daemon/dist/domain/policies/workflow-keepalive.js +16 -2
  528. package/node_modules/@openrig/daemon/dist/domain/policies/workflow-keepalive.js.map +1 -1
  529. package/node_modules/@openrig/daemon/dist/domain/profile-resolver.d.ts +12 -0
  530. package/node_modules/@openrig/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
  531. package/node_modules/@openrig/daemon/dist/domain/profile-resolver.js +60 -0
  532. package/node_modules/@openrig/daemon/dist/domain/profile-resolver.js.map +1 -1
  533. package/node_modules/@openrig/daemon/dist/domain/project-lifecycle-compiler.d.ts +35 -0
  534. package/node_modules/@openrig/daemon/dist/domain/project-lifecycle-compiler.d.ts.map +1 -0
  535. package/node_modules/@openrig/daemon/dist/domain/project-lifecycle-compiler.js +190 -0
  536. package/node_modules/@openrig/daemon/dist/domain/project-lifecycle-compiler.js.map +1 -0
  537. package/node_modules/@openrig/daemon/dist/domain/provider/claude-usage-reader.d.ts +1 -1
  538. package/node_modules/@openrig/daemon/dist/domain/provider/claude-usage-reader.d.ts.map +1 -1
  539. package/node_modules/@openrig/daemon/dist/domain/provider/claude-usage-reader.js +28 -18
  540. package/node_modules/@openrig/daemon/dist/domain/provider/claude-usage-reader.js.map +1 -1
  541. package/node_modules/@openrig/daemon/dist/domain/queue-repository.d.ts +5 -1
  542. package/node_modules/@openrig/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  543. package/node_modules/@openrig/daemon/dist/domain/queue-repository.js +6 -0
  544. package/node_modules/@openrig/daemon/dist/domain/queue-repository.js.map +1 -1
  545. package/node_modules/@openrig/daemon/dist/domain/queue-retention.d.ts +3 -4
  546. package/node_modules/@openrig/daemon/dist/domain/queue-retention.d.ts.map +1 -1
  547. package/node_modules/@openrig/daemon/dist/domain/queue-retention.js +5 -8
  548. package/node_modules/@openrig/daemon/dist/domain/queue-retention.js.map +1 -1
  549. package/node_modules/@openrig/daemon/dist/domain/queue-transition-log.d.ts +28 -0
  550. package/node_modules/@openrig/daemon/dist/domain/queue-transition-log.d.ts.map +1 -1
  551. package/node_modules/@openrig/daemon/dist/domain/queue-transition-log.js +124 -0
  552. package/node_modules/@openrig/daemon/dist/domain/queue-transition-log.js.map +1 -1
  553. package/node_modules/@openrig/daemon/dist/domain/restore-attempt-receipt.d.ts +34 -0
  554. package/node_modules/@openrig/daemon/dist/domain/restore-attempt-receipt.d.ts.map +1 -0
  555. package/node_modules/@openrig/daemon/dist/domain/restore-attempt-receipt.js +59 -0
  556. package/node_modules/@openrig/daemon/dist/domain/restore-attempt-receipt.js.map +1 -0
  557. package/node_modules/@openrig/daemon/dist/domain/restore-orchestrator.d.ts +57 -24
  558. package/node_modules/@openrig/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  559. package/node_modules/@openrig/daemon/dist/domain/restore-orchestrator.js +152 -26
  560. package/node_modules/@openrig/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  561. package/node_modules/@openrig/daemon/dist/domain/restore-topology.d.ts +14 -0
  562. package/node_modules/@openrig/daemon/dist/domain/restore-topology.d.ts.map +1 -0
  563. package/node_modules/@openrig/daemon/dist/domain/restore-topology.js +27 -0
  564. package/node_modules/@openrig/daemon/dist/domain/restore-topology.js.map +1 -0
  565. package/node_modules/@openrig/daemon/dist/domain/rig-lifecycle-service.d.ts.map +1 -1
  566. package/node_modules/@openrig/daemon/dist/domain/rig-lifecycle-service.js +9 -0
  567. package/node_modules/@openrig/daemon/dist/domain/rig-lifecycle-service.js.map +1 -1
  568. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.d.ts +19 -0
  569. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  570. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.js +65 -1
  571. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  572. package/node_modules/@openrig/daemon/dist/domain/rigspec-preflight.d.ts +8 -0
  573. package/node_modules/@openrig/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
  574. package/node_modules/@openrig/daemon/dist/domain/rigspec-preflight.js +4 -0
  575. package/node_modules/@openrig/daemon/dist/domain/rigspec-preflight.js.map +1 -1
  576. package/node_modules/@openrig/daemon/dist/domain/seat-attention-reconciler.d.ts +23 -1
  577. package/node_modules/@openrig/daemon/dist/domain/seat-attention-reconciler.d.ts.map +1 -1
  578. package/node_modules/@openrig/daemon/dist/domain/seat-attention-reconciler.js +97 -46
  579. package/node_modules/@openrig/daemon/dist/domain/seat-attention-reconciler.js.map +1 -1
  580. package/node_modules/@openrig/daemon/dist/domain/seat-identity-reconciler.d.ts.map +1 -1
  581. package/node_modules/@openrig/daemon/dist/domain/seat-identity-reconciler.js +15 -6
  582. package/node_modules/@openrig/daemon/dist/domain/seat-identity-reconciler.js.map +1 -1
  583. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.d.ts +47 -1
  584. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -1
  585. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.js +525 -29
  586. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.js.map +1 -1
  587. package/node_modules/@openrig/daemon/dist/domain/session-registry.d.ts +8 -1
  588. package/node_modules/@openrig/daemon/dist/domain/session-registry.d.ts.map +1 -1
  589. package/node_modules/@openrig/daemon/dist/domain/session-registry.js +19 -0
  590. package/node_modules/@openrig/daemon/dist/domain/session-registry.js.map +1 -1
  591. package/node_modules/@openrig/daemon/dist/domain/skill-catalog.d.ts +81 -0
  592. package/node_modules/@openrig/daemon/dist/domain/skill-catalog.d.ts.map +1 -0
  593. package/node_modules/@openrig/daemon/dist/domain/skill-catalog.js +827 -0
  594. package/node_modules/@openrig/daemon/dist/domain/skill-catalog.js.map +1 -0
  595. package/node_modules/@openrig/daemon/dist/domain/skill-discovery.d.ts +3 -0
  596. package/node_modules/@openrig/daemon/dist/domain/skill-discovery.d.ts.map +1 -1
  597. package/node_modules/@openrig/daemon/dist/domain/skill-discovery.js +1 -1
  598. package/node_modules/@openrig/daemon/dist/domain/skill-discovery.js.map +1 -1
  599. package/node_modules/@openrig/daemon/dist/domain/snapshot-capture.d.ts +4 -1
  600. package/node_modules/@openrig/daemon/dist/domain/snapshot-capture.d.ts.map +1 -1
  601. package/node_modules/@openrig/daemon/dist/domain/snapshot-capture.js +38 -2
  602. package/node_modules/@openrig/daemon/dist/domain/snapshot-capture.js.map +1 -1
  603. package/node_modules/@openrig/daemon/dist/domain/snapshot-repository.d.ts +15 -1
  604. package/node_modules/@openrig/daemon/dist/domain/snapshot-repository.d.ts.map +1 -1
  605. package/node_modules/@openrig/daemon/dist/domain/snapshot-repository.js +103 -1
  606. package/node_modules/@openrig/daemon/dist/domain/snapshot-repository.js.map +1 -1
  607. package/node_modules/@openrig/daemon/dist/domain/startup-orchestrator.d.ts +2 -0
  608. package/node_modules/@openrig/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
  609. package/node_modules/@openrig/daemon/dist/domain/startup-orchestrator.js +12 -0
  610. package/node_modules/@openrig/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  611. package/node_modules/@openrig/daemon/dist/domain/system-world.d.ts +45 -0
  612. package/node_modules/@openrig/daemon/dist/domain/system-world.d.ts.map +1 -0
  613. package/node_modules/@openrig/daemon/dist/domain/system-world.js +123 -0
  614. package/node_modules/@openrig/daemon/dist/domain/system-world.js.map +1 -0
  615. package/node_modules/@openrig/daemon/dist/domain/telemetry-state-paths.d.ts +7 -0
  616. package/node_modules/@openrig/daemon/dist/domain/telemetry-state-paths.d.ts.map +1 -0
  617. package/node_modules/@openrig/daemon/dist/domain/telemetry-state-paths.js +20 -0
  618. package/node_modules/@openrig/daemon/dist/domain/telemetry-state-paths.js.map +1 -0
  619. package/node_modules/@openrig/daemon/dist/domain/types.d.ts +103 -4
  620. package/node_modules/@openrig/daemon/dist/domain/types.d.ts.map +1 -1
  621. package/node_modules/@openrig/daemon/dist/domain/types.js.map +1 -1
  622. package/node_modules/@openrig/daemon/dist/domain/user-settings/settings-store.d.ts +8 -3
  623. package/node_modules/@openrig/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  624. package/node_modules/@openrig/daemon/dist/domain/user-settings/settings-store.js +65 -29
  625. package/node_modules/@openrig/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  626. package/node_modules/@openrig/daemon/dist/domain/watchdog-policy-engine.d.ts +7 -23
  627. package/node_modules/@openrig/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -1
  628. package/node_modules/@openrig/daemon/dist/domain/watchdog-policy-engine.js +44 -226
  629. package/node_modules/@openrig/daemon/dist/domain/watchdog-policy-engine.js.map +1 -1
  630. package/node_modules/@openrig/daemon/dist/domain/workflow-boot-sweep.d.ts.map +1 -1
  631. package/node_modules/@openrig/daemon/dist/domain/workflow-boot-sweep.js +20 -6
  632. package/node_modules/@openrig/daemon/dist/domain/workflow-boot-sweep.js.map +1 -1
  633. package/node_modules/@openrig/daemon/dist/domain/workflow-instance-store.d.ts +33 -1
  634. package/node_modules/@openrig/daemon/dist/domain/workflow-instance-store.d.ts.map +1 -1
  635. package/node_modules/@openrig/daemon/dist/domain/workflow-instance-store.js +127 -2
  636. package/node_modules/@openrig/daemon/dist/domain/workflow-instance-store.js.map +1 -1
  637. package/node_modules/@openrig/daemon/dist/domain/workflow-keepalive-arming.d.ts +7 -5
  638. package/node_modules/@openrig/daemon/dist/domain/workflow-keepalive-arming.d.ts.map +1 -1
  639. package/node_modules/@openrig/daemon/dist/domain/workflow-keepalive-arming.js +27 -16
  640. package/node_modules/@openrig/daemon/dist/domain/workflow-keepalive-arming.js.map +1 -1
  641. package/node_modules/@openrig/daemon/dist/domain/workflow-projector.d.ts +6 -2
  642. package/node_modules/@openrig/daemon/dist/domain/workflow-projector.d.ts.map +1 -1
  643. package/node_modules/@openrig/daemon/dist/domain/workflow-projector.js +271 -2
  644. package/node_modules/@openrig/daemon/dist/domain/workflow-projector.js.map +1 -1
  645. package/node_modules/@openrig/daemon/dist/domain/workflow-runtime.d.ts +62 -2
  646. package/node_modules/@openrig/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
  647. package/node_modules/@openrig/daemon/dist/domain/workflow-runtime.js +334 -18
  648. package/node_modules/@openrig/daemon/dist/domain/workflow-runtime.js.map +1 -1
  649. package/node_modules/@openrig/daemon/dist/domain/workflow-spec-cache.d.ts +9 -1
  650. package/node_modules/@openrig/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
  651. package/node_modules/@openrig/daemon/dist/domain/workflow-spec-cache.js +85 -0
  652. package/node_modules/@openrig/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
  653. package/node_modules/@openrig/daemon/dist/domain/workflow-types.d.ts +38 -1
  654. package/node_modules/@openrig/daemon/dist/domain/workflow-types.d.ts.map +1 -1
  655. package/node_modules/@openrig/daemon/dist/domain/workflow-types.js.map +1 -1
  656. package/node_modules/@openrig/daemon/dist/domain/workflow-validator.d.ts.map +1 -1
  657. package/node_modules/@openrig/daemon/dist/domain/workflow-validator.js +20 -3
  658. package/node_modules/@openrig/daemon/dist/domain/workflow-validator.js.map +1 -1
  659. package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts +38 -9
  660. package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  661. package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.js +93 -347
  662. package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  663. package/node_modules/@openrig/daemon/dist/index.d.ts.map +1 -1
  664. package/node_modules/@openrig/daemon/dist/index.js +13 -0
  665. package/node_modules/@openrig/daemon/dist/index.js.map +1 -1
  666. package/node_modules/@openrig/daemon/dist/instance-initialization-surface.d.ts +3 -0
  667. package/node_modules/@openrig/daemon/dist/instance-initialization-surface.d.ts.map +1 -0
  668. package/node_modules/@openrig/daemon/dist/instance-initialization-surface.js +3 -0
  669. package/node_modules/@openrig/daemon/dist/instance-initialization-surface.js.map +1 -0
  670. package/node_modules/@openrig/daemon/dist/project-lifecycle-surface.d.ts +3 -0
  671. package/node_modules/@openrig/daemon/dist/project-lifecycle-surface.d.ts.map +1 -0
  672. package/node_modules/@openrig/daemon/dist/project-lifecycle-surface.js +3 -0
  673. package/node_modules/@openrig/daemon/dist/project-lifecycle-surface.js.map +1 -0
  674. package/node_modules/@openrig/daemon/dist/routes/bundles.js +10 -9
  675. package/node_modules/@openrig/daemon/dist/routes/bundles.js.map +1 -1
  676. package/node_modules/@openrig/daemon/dist/routes/config.d.ts.map +1 -1
  677. package/node_modules/@openrig/daemon/dist/routes/config.js +27 -49
  678. package/node_modules/@openrig/daemon/dist/routes/config.js.map +1 -1
  679. package/node_modules/@openrig/daemon/dist/routes/context-packs.d.ts.map +1 -1
  680. package/node_modules/@openrig/daemon/dist/routes/context-packs.js +114 -16
  681. package/node_modules/@openrig/daemon/dist/routes/context-packs.js.map +1 -1
  682. package/node_modules/@openrig/daemon/dist/routes/crash-cart.js +3 -0
  683. package/node_modules/@openrig/daemon/dist/routes/crash-cart.js.map +1 -1
  684. package/node_modules/@openrig/daemon/dist/routes/queue.d.ts.map +1 -1
  685. package/node_modules/@openrig/daemon/dist/routes/queue.js +20 -0
  686. package/node_modules/@openrig/daemon/dist/routes/queue.js.map +1 -1
  687. package/node_modules/@openrig/daemon/dist/routes/rigs.js +12 -1
  688. package/node_modules/@openrig/daemon/dist/routes/rigs.js.map +1 -1
  689. package/node_modules/@openrig/daemon/dist/routes/rigspec.js +9 -2
  690. package/node_modules/@openrig/daemon/dist/routes/rigspec.js.map +1 -1
  691. package/node_modules/@openrig/daemon/dist/routes/seat.js +21 -1
  692. package/node_modules/@openrig/daemon/dist/routes/seat.js.map +1 -1
  693. package/node_modules/@openrig/daemon/dist/routes/sessions.js +16 -6
  694. package/node_modules/@openrig/daemon/dist/routes/sessions.js.map +1 -1
  695. package/node_modules/@openrig/daemon/dist/routes/snapshots.d.ts.map +1 -1
  696. package/node_modules/@openrig/daemon/dist/routes/snapshots.js +41 -3
  697. package/node_modules/@openrig/daemon/dist/routes/snapshots.js.map +1 -1
  698. package/node_modules/@openrig/daemon/dist/routes/up.js +12 -1
  699. package/node_modules/@openrig/daemon/dist/routes/up.js.map +1 -1
  700. package/node_modules/@openrig/daemon/dist/routes/watchdog.d.ts.map +1 -1
  701. package/node_modules/@openrig/daemon/dist/routes/watchdog.js +7 -6
  702. package/node_modules/@openrig/daemon/dist/routes/watchdog.js.map +1 -1
  703. package/node_modules/@openrig/daemon/dist/routes/workflow.d.ts.map +1 -1
  704. package/node_modules/@openrig/daemon/dist/routes/workflow.js +104 -39
  705. package/node_modules/@openrig/daemon/dist/routes/workflow.js.map +1 -1
  706. package/node_modules/@openrig/daemon/dist/server.d.ts +2 -0
  707. package/node_modules/@openrig/daemon/dist/server.d.ts.map +1 -1
  708. package/node_modules/@openrig/daemon/dist/server.js +1 -0
  709. package/node_modules/@openrig/daemon/dist/server.js.map +1 -1
  710. package/node_modules/@openrig/daemon/dist/skill-loadout-surface.d.ts +3 -0
  711. package/node_modules/@openrig/daemon/dist/skill-loadout-surface.d.ts.map +1 -0
  712. package/node_modules/@openrig/daemon/dist/skill-loadout-surface.js +2 -0
  713. package/node_modules/@openrig/daemon/dist/skill-loadout-surface.js.map +1 -0
  714. package/node_modules/@openrig/daemon/dist/startup.d.ts.map +1 -1
  715. package/node_modules/@openrig/daemon/dist/startup.js +72 -65
  716. package/node_modules/@openrig/daemon/dist/startup.js.map +1 -1
  717. package/node_modules/@openrig/daemon/dist/system-world-surface.d.ts +2 -0
  718. package/node_modules/@openrig/daemon/dist/system-world-surface.d.ts.map +1 -0
  719. package/node_modules/@openrig/daemon/dist/system-world-surface.js +2 -0
  720. package/node_modules/@openrig/daemon/dist/system-world-surface.js.map +1 -0
  721. package/node_modules/@openrig/daemon/package.json +17 -1
  722. package/package.json +1 -1
  723. package/tui/dist/commands/registry.d.ts.map +1 -1
  724. package/tui/dist/commands/registry.js +10 -1
  725. package/tui/dist/commands/registry.js.map +1 -1
  726. package/tui/dist/daemon-client.d.ts +11 -0
  727. package/tui/dist/daemon-client.d.ts.map +1 -1
  728. package/tui/dist/daemon-client.js +15 -0
  729. package/tui/dist/daemon-client.js.map +1 -1
  730. package/tui/dist/demo-data.d.ts.map +1 -1
  731. package/tui/dist/demo-data.js +65 -9
  732. package/tui/dist/demo-data.js.map +1 -1
  733. package/tui/dist/detail.d.ts +9 -0
  734. package/tui/dist/detail.d.ts.map +1 -1
  735. package/tui/dist/detail.js.map +1 -1
  736. package/tui/dist/execution/execution-model.d.ts +8 -2
  737. package/tui/dist/execution/execution-model.d.ts.map +1 -1
  738. package/tui/dist/execution/execution-model.js +482 -119
  739. package/tui/dist/execution/execution-model.js.map +1 -1
  740. package/tui/dist/hydrate.d.ts +3 -2
  741. package/tui/dist/hydrate.d.ts.map +1 -1
  742. package/tui/dist/hydrate.js +66 -8
  743. package/tui/dist/hydrate.js.map +1 -1
  744. package/tui/dist/input.d.ts +6 -1
  745. package/tui/dist/input.d.ts.map +1 -1
  746. package/tui/dist/input.js +20 -10
  747. package/tui/dist/input.js.map +1 -1
  748. package/tui/dist/main.js +39 -8
  749. package/tui/dist/main.js.map +1 -1
  750. package/tui/dist/navigator.d.ts.map +1 -1
  751. package/tui/dist/navigator.js +10 -6
  752. package/tui/dist/navigator.js.map +1 -1
  753. package/tui/dist/render.d.ts.map +1 -1
  754. package/tui/dist/render.js +596 -155
  755. package/tui/dist/render.js.map +1 -1
  756. package/tui/dist/scopes/scopes-model.d.ts +14 -8
  757. package/tui/dist/scopes/scopes-model.d.ts.map +1 -1
  758. package/tui/dist/scopes/scopes-model.js +218 -46
  759. package/tui/dist/scopes/scopes-model.js.map +1 -1
  760. package/tui/dist/socket-server.d.ts +13 -0
  761. package/tui/dist/socket-server.d.ts.map +1 -1
  762. package/tui/dist/socket-server.js +24 -0
  763. package/tui/dist/socket-server.js.map +1 -1
  764. package/tui/dist/state.d.ts.map +1 -1
  765. package/tui/dist/state.js +20 -6
  766. package/tui/dist/state.js.map +1 -1
  767. package/tui/dist/stylize.d.ts.map +1 -1
  768. package/tui/dist/stylize.js +22 -28
  769. package/tui/dist/stylize.js.map +1 -1
  770. package/tui/dist/theme.d.ts +1 -1
  771. package/tui/dist/theme.d.ts.map +1 -1
  772. package/tui/dist/theme.js +5 -4
  773. package/tui/dist/theme.js.map +1 -1
  774. package/tui/dist/types.d.ts +97 -1
  775. package/tui/dist/types.d.ts.map +1 -1
  776. package/tui/dist/visual-layout.d.ts +6 -0
  777. package/tui/dist/visual-layout.d.ts.map +1 -0
  778. package/tui/dist/visual-layout.js +8 -0
  779. package/tui/dist/visual-layout.js.map +1 -0
  780. package/ui/dist/assets/{index-B_wqzP0D.js → index-wyX378xb.js} +15 -15
  781. package/ui/dist/index.html +1 -1
@@ -17,8 +17,8 @@ import { renderCrashCartView, renderUnverifiedView, renderRestoreLifecycleView,
17
17
  import { buildLedgerExplorer } from "./crash-cart/ledger-explorer.js";
18
18
  import { runtimeMarkSegs } from "./topology/runtime-marks.js";
19
19
  import { barCells, flashActive, reducedMotion, spinnerFrame } from "./motion.js";
20
+ import { explorerWidth, MOTION_FRAME_MS } from "./visual-layout.js";
20
21
  import { detailPage, fieldLine, sectionRule, listItem, alignedRow, LABEL_W } from "./detail.js";
21
- const EXPL_W = 30;
22
22
  function pad(text, width) {
23
23
  const t = String(text ?? "");
24
24
  if (t.length <= width)
@@ -32,43 +32,285 @@ function padLeft(text, width) {
32
32
  return " ".repeat(width - t.length) + t;
33
33
  return t.slice(0, Math.max(width - 1, 0)) + "…";
34
34
  }
35
- const FULL_AGENT_COLS = [
36
- ["rig", "RIG", 18, "left"],
37
- ["pod", "POD", 8, "left"],
38
- ["agent", "AGENT", 16, "left"],
39
- ["runtime", "RUNTIME", 13, "left"],
40
- ["context", "CTX%", 4, "right"],
41
- ["tokens", "TOKENS", 7, "right"],
42
- ["status", "STATUS", 17, "left"],
43
- ["actions", "ACTIONS", 14, "left"],
44
- ];
45
35
  function columnsWidth(columns) {
46
36
  return columns.reduce((total, [, , width]) => total + width + 1, -1);
47
37
  }
48
38
  function agentColumns(contentWidth) {
49
- if (columnsWidth(FULL_AGENT_COLS) <= contentWidth)
50
- return FULL_AGENT_COLS;
51
- // At the 120-column fallback the content pane is 88 cells. Preserve the
52
- // operable identity/status/action path; telemetry cells yield first.
53
- const compactRest = [
54
- ["pod", "POD", 8, "left"],
55
- ["agent", "AGENT", 16, "left"],
56
- ["runtime", "RUNTIME", 13, "left"],
57
- ["status", "STATUS", 17, "left"],
58
- ["actions", "ACTIONS", 14, "left"],
39
+ if (contentWidth >= 110)
40
+ return [
41
+ ["pod", "POD", 8, "left"], ["seat", "SEAT", 15, "left"], ["runtime", "RT", 4, "left"],
42
+ ["model", "MODEL", 12, "left"], ["context", "CTX", 8, "right"], ["status", "STATE", 11, "left"],
43
+ ["queue", "Q", 3, "right"], ["work", "WORK", 15, "left"], ["now", "NOW", 27, "left"],
44
+ ["actions", "ACTIONS", 14, "left"],
45
+ ];
46
+ if (contentWidth >= 88)
47
+ return [
48
+ ["pod", "POD", 6, "left"], ["seat", "SEAT", 12, "left"], ["runtime", "RT", 3, "left"],
49
+ ["model", "MODEL", 8, "left"], ["context", "CTX", 6, "right"], ["status", "STATE", 9, "left"],
50
+ ["queue", "Q", 2, "right"], ["work", "WORK", 8, "left"], ["now", "NOW", 11, "left"],
51
+ ["actions", "ACTIONS", 14, "left"],
52
+ ];
53
+ // At 84x28 the L2 content pane is 58 cells. The three explicitly deferred
54
+ // columns (MODEL/NOW/ACTIONS) move to drill; identity, state and work remain.
55
+ const fixed = 6 + 12 + 3 + 5 + 9 + 2 + 6; // widths + separators, excluding WORK
56
+ return [
57
+ ["pod", "POD", 6, "left"], ["seat", "SEAT", 12, "left"], ["runtime", "RT", 3, "left"],
58
+ ["context", "CTX", 5, "right"], ["status", "STATE", 9, "left"], ["queue", "Q", 2, "right"],
59
+ ["work", "WORK", Math.max(4, contentWidth - fixed), "left"],
60
+ ];
61
+ }
62
+ function instanceAgentColumns(contentWidth) {
63
+ if (contentWidth >= 110)
64
+ return [
65
+ ["rig", "RIG", 13, "left"], ["pod", "POD", 8, "left"], ["seat", "SEAT", 14, "left"],
66
+ ["runtime", "RT", 3, "left"], ["context", "CTX", 7, "right"], ["status", "STATE", 10, "left"],
67
+ ["queue", "Q", 2, "right"], ["work", "WORK", 12, "left"], ["now", "NOW", Math.max(18, contentWidth - 78), "left"],
68
+ ];
69
+ if (contentWidth >= 78)
70
+ return [
71
+ ["rig", "RIG", 10, "left"], ["pod", "POD", 6, "left"], ["seat", "SEAT", 12, "left"],
72
+ ["runtime", "RT", 3, "left"], ["context", "CTX", 5, "right"], ["status", "STATE", 9, "left"],
73
+ ["queue", "Q", 2, "right"], ["work", "WORK", Math.max(8, contentWidth - 54), "left"],
74
+ ];
75
+ const fixed = 8 + 5 + 11 + 2 + 5 + 8 + 2 + 7;
76
+ return [
77
+ ["rig", "RIG", 8, "left"], ["pod", "POD", 5, "left"], ["seat", "SEAT", 11, "left"],
78
+ ["runtime", "RT", 2, "left"], ["context", "CTX", 5, "right"], ["status", "STATE", 8, "left"],
79
+ ["queue", "Q", 2, "right"], ["work", "WORK", Math.max(4, contentWidth - fixed), "left"],
59
80
  ];
60
- const rigWidth = Math.max(6, Math.min(18, contentWidth - columnsWidth(compactRest) - 1));
61
- return [["rig", "RIG", rigWidth, "left"], ...compactRest];
62
81
  }
63
82
  function tableRow(columns, cells) {
64
83
  return columns.map(([key, , width, align]) => align === "right" ? padLeft(cells[key], width) : pad(cells[key], width)).join(" ");
65
84
  }
85
+ function runtimeShort(runtime) {
86
+ if (/claude/i.test(runtime))
87
+ return "cl";
88
+ if (/codex/i.test(runtime))
89
+ return "cx";
90
+ if (/terminal/i.test(runtime))
91
+ return ">_";
92
+ if (/human/i.test(runtime))
93
+ return "hu";
94
+ return runtime.slice(0, 2) || "—";
95
+ }
96
+ /** Tables optimize for glance width; details retain the canonical model id. */
97
+ function tableModel(model) {
98
+ return model?.replace(/^claude-/i, "") || "—";
99
+ }
100
+ function contextCompact(value, narrow) {
101
+ if (value == null)
102
+ return "—";
103
+ if (narrow)
104
+ return `${value}%`;
105
+ const filled = Math.max(0, Math.min(3, Math.round(value / 33.4)));
106
+ return `${value}%${"▪".repeat(filled)}${"▫".repeat(3 - filled)}`;
107
+ }
108
+ function seatName(pod, name) {
109
+ for (const prefix of [`${pod}.`, `${pod}-`])
110
+ if (name.startsWith(prefix))
111
+ return name.slice(prefix.length);
112
+ return name;
113
+ }
114
+ function operationalState(status, motion) {
115
+ const key = status.toLowerCase().replaceAll("_", "-");
116
+ if (key === "active" || key === "working" || key === "running") {
117
+ if (!motion.reduced)
118
+ motion.used = true;
119
+ return { mark: motion.reduced ? "●" : motion.frame, word: "working" };
120
+ }
121
+ if (key === "attention-required" || key === "needs-attention" || key === "needs-input")
122
+ return { mark: "◐", word: "needs you" };
123
+ if (key === "blocked")
124
+ return { mark: "⚑", word: "blocked" };
125
+ if (key === "failed" || key === "down")
126
+ return { mark: "✕", word: "failed" };
127
+ if (key === "idle")
128
+ return { mark: "·", word: "idle" };
129
+ if (key === "detached" || key === "stopped")
130
+ return { mark: "○", word: "detached" };
131
+ return { mark: "?", word: "unknown" };
132
+ }
133
+ function queueFacts(snap, session) {
134
+ if (!session)
135
+ return { count: 0, work: "—", now: "—" };
136
+ const sources = [
137
+ ["needs you", snap.attention], ["blocked", snap.blocked], ["working", snap.inProgress], ["queued", snap.pending],
138
+ ];
139
+ const rows = [];
140
+ const seen = new Set();
141
+ for (const [role, items] of sources)
142
+ for (const row of items) {
143
+ if (row.destinationSession !== session || seen.has(row.qitemId))
144
+ continue;
145
+ seen.add(row.qitemId);
146
+ rows.push({ role, row });
147
+ }
148
+ const primary = rows[0];
149
+ if (!primary)
150
+ return { count: 0, work: "—", now: "—" };
151
+ const slice = primary.row.tags?.find((tag) => tag.startsWith("slice:"))?.slice("slice:".length);
152
+ const work = slice?.match(/^OPR(?:\.\d+){3}\.(\d+)$/)?.[1]
153
+ ? `S${slice.slice(slice.lastIndexOf(".") + 1)}`
154
+ : slice ?? "—";
155
+ const summary = primary.row.summary?.trim() || primary.row.body.split("\n").find((line) => line.trim())?.trim() || primary.row.qitemId;
156
+ const now = primary.role === "working" ? summary : `${primary.role} · ${summary}`;
157
+ return { count: rows.length, work, now };
158
+ }
159
+ function number(value) {
160
+ return value == null ? "—" : value.toLocaleString("en-US");
161
+ }
162
+ function wrapDetailValue(label, value, width) {
163
+ const prefix = ` ${`${label}:`.padEnd(LABEL_W)} `;
164
+ const continuation = " ".repeat(prefix.length);
165
+ const room = Math.max(8, width - prefix.length);
166
+ const words = value.trim().split(/\s+/).filter(Boolean);
167
+ const chunks = [];
168
+ let line = "";
169
+ for (const raw of words) {
170
+ let word = raw;
171
+ while (word.length > room) {
172
+ if (line) {
173
+ chunks.push(line);
174
+ line = "";
175
+ }
176
+ chunks.push(word.slice(0, room));
177
+ word = word.slice(room);
178
+ }
179
+ if (!word)
180
+ continue;
181
+ if (!line)
182
+ line = word;
183
+ else if (line.length + word.length + 1 <= room)
184
+ line += ` ${word}`;
185
+ else {
186
+ chunks.push(line);
187
+ line = word;
188
+ }
189
+ }
190
+ if (line)
191
+ chunks.push(line);
192
+ return (chunks.length ? chunks : [""]).map((chunk, index) => ({ text: `${index === 0 ? prefix : continuation}${chunk}` }));
193
+ }
194
+ function rowsForAgent(snap, session, sources) {
195
+ const rows = [];
196
+ const seen = new Set();
197
+ for (const source of sources)
198
+ for (const row of source) {
199
+ if (row.destinationSession !== session || seen.has(row.qitemId))
200
+ continue;
201
+ seen.add(row.qitemId);
202
+ rows.push(row);
203
+ }
204
+ return rows;
205
+ }
206
+ function workRows(rows, width) {
207
+ if (rows.length === 0)
208
+ return [fieldLine({ label: "rows", value: "none in the served bounded lists" })];
209
+ return rows.flatMap((row) => {
210
+ const summary = row.summary?.trim() || row.body.split("\n").find((line) => line.trim())?.trim() || "no summary served";
211
+ return [
212
+ ...wrapDetailValue("qitem", `${row.qitemId} · ${row.state}`, width),
213
+ ...wrapDetailValue("work", summary, width),
214
+ ...(row.blockedOn ? wrapDetailValue("blocker", `blocked on ${row.blockedOn}`, width) : []),
215
+ ];
216
+ });
217
+ }
218
+ function agentDetailLines(snap, found, contentWidth) {
219
+ const { agent, rig, pod } = found;
220
+ const session = agent.session;
221
+ const specInLibrary = !!agent.spec && !!findSpec(snap, agent.spec);
222
+ const currentRows = session ? rowsForAgent(snap, session, [snap.attention, snap.blocked, snap.inProgress]) : [];
223
+ const pendingRows = session ? rowsForAgent(snap, session, [snap.pending]) : [];
224
+ const recentRows = session ? rowsForAgent(snap, session, [snap.recentlyFinished]) : [];
225
+ const needs = session ? snap.needs.filter((item) => item.target === session) : [];
226
+ const visibleAssigned = currentRows.length + pendingRows.length;
227
+ const assigned = agent.assignedWorkCount ?? visibleAssigned;
228
+ const pending = agent.pendingWorkCount ?? pendingRows.length;
229
+ const inProgress = agent.inProgressWorkCount ?? currentRows.filter((row) => row.state === "in-progress").length;
230
+ const blocked = agent.blockedWorkCount ?? currentRows.filter((row) => row.state === "blocked").length;
231
+ const context = agent.context;
232
+ const meterWidth = Math.max(10, Math.min(36, contentWidth - 24));
233
+ const rtName = agent.runtime ?? "unknown";
234
+ const rtSegs = [
235
+ { text: " " },
236
+ { text: "runtime:", token: "dim" },
237
+ { text: " ".repeat(LABEL_W - "runtime:".length + 1) },
238
+ { text: rtName },
239
+ { text: " " },
240
+ ...runtimeMarkSegs(agent.runtime),
241
+ ];
242
+ const runtimeLine = { text: rtSegs.map((segment) => segment.text).join(""), segs: rtSegs };
243
+ const activityReason = agent.activity?.needsInput?.reason ?? agent.activity?.signalReason ?? null;
244
+ const needsRows = needs.length > 0
245
+ ? needs.flatMap((item) => [
246
+ ...wrapDetailValue("qitem", item.qitemId ?? "no actionable qitem id served", contentWidth),
247
+ ...wrapDetailValue("reason", item.detail, contentWidth),
248
+ ...(item.unblocks ? wrapDetailValue("action", `unblocks ${item.unblocks}`, contentWidth) : []),
249
+ ...(item.evidenceRef ? wrapDetailValue("evidence", item.evidenceRef, contentWidth) : []),
250
+ ])
251
+ : agent.activity?.needsInput && agent.activity.needsInput.count > 0
252
+ ? wrapDetailValue("reason", agent.activity.needsInput.reason ?? "input required; no reason served", contentWidth)
253
+ : [fieldLine({ label: "state", value: "none on the served projections" })];
254
+ return [
255
+ ...detailPage({ text: `agent ${agent.name} · ${agent.status}` }, [
256
+ {
257
+ title: `CONTEXT · ${context == null ? "unknown" : `${context}%`}`,
258
+ lines: [
259
+ fieldLine({ label: "meter", value: context == null ? "— (not yet known)" : `${context}% used ${barCells(context / 100, meterWidth)}` }),
260
+ fieldLine({ label: "tokens", value: `${number(agent.totalInputTokens)} input · ${number(agent.totalOutputTokens)} output · ${number(agent.contextWindowSize)} window` }),
261
+ runtimeLine,
262
+ ...(agent.attach ? [fieldLine({ label: "attach", value: agent.attach })] : []),
263
+ fieldLine({ label: "terminal", value: `term ▸ pod ${pod.name}`, link: { type: "act", act: "open-terminal", view: `pod:${rig.name}/${pod.name}` } }),
264
+ ],
265
+ },
266
+ {
267
+ title: "CURRENT ACTIVITY",
268
+ fields: [
269
+ { label: "activity", value: agent.activity?.activity ?? agent.status },
270
+ ...(activityReason ? [{ label: "reason", value: activityReason }] : []),
271
+ ...(agent.activity?.decidedBy ? [{ label: "decided by", value: agent.activity.decidedBy }] : []),
272
+ ...(agent.activity?.signalSource || agent.activity?.signalReason ? [{ label: "signal", value: `${agent.activity.signalSource ?? "unknown"} · ${agent.activity.signalReason ?? "no reason"}` }] : []),
273
+ ...(agent.activity?.eventAt ? [{ label: "changed", value: agent.activity.eventAt }] : []),
274
+ ],
275
+ },
276
+ { title: `CURRENT WORK · ${currentRows.length}`, lines: workRows(currentRows, contentWidth) },
277
+ {
278
+ title: "QUEUE",
279
+ lines: [
280
+ ...wrapDetailValue("depth", `${assigned} assigned · ${pending} pending · ${inProgress} in progress · ${blocked} blocked`, contentWidth),
281
+ ...(agent.assignedWorkCount == null ? wrapDetailValue("basis", `${visibleAssigned} rows visible in bounded list reads; complete count not served`, contentWidth) : []),
282
+ ],
283
+ },
284
+ { title: `UP NEXT · ${pending}`, lines: workRows(pendingRows, contentWidth) },
285
+ { title: `NEEDS YOU · ${needs.length || agent.activity?.needsInput?.count || 0}`, lines: needsRows },
286
+ ...(recentRows.length ? [{ title: "RECENTLY FINISHED · bounded window", lines: workRows(recentRows, contentWidth) }] : []),
287
+ {
288
+ title: "SEAT",
289
+ fields: [
290
+ { label: "host", value: found.host.name },
291
+ { label: "rig", value: rig.name },
292
+ { label: "pod", value: pod.name },
293
+ ],
294
+ lines: [
295
+ fieldLine({ label: "cwd", value: agent.cwd ?? "— (not served)" }),
296
+ ],
297
+ },
298
+ {
299
+ title: "SPEC",
300
+ fields: [specInLibrary
301
+ ? { label: "spec", value: agent.spec, link: { type: "cross", kind: "spec-of", name: agent.name, target: { host: found.host.name, rig: rig.name, pod: pod.name } } }
302
+ : { label: "spec", value: agent.spec ? `${agent.spec} (not in library)` : "—" }],
303
+ },
304
+ ]),
305
+ ];
306
+ }
66
307
  function tabsLine(state, suffix) {
67
- // slice-17: three tabs, each its own click zone (the first zone starts at
308
+ // S12: four tabs, each its own click zone (the first zone starts at
68
309
  // content col 0, preserving the focus-marker floor); `tab graph` = the
69
310
  // topology graph view (frame-01 hatchet mainline)
70
311
  const labels = [
71
312
  ["table", state.viewTab === "table" ? "[ TABLE ]" : " TABLE "],
313
+ ["recent", state.viewTab === "recent" ? "[ RECENT ]" : " RECENT "],
72
314
  ["overview", state.viewTab === "overview" ? "[ OVERVIEW ]" : " OVERVIEW "],
73
315
  ["graph", state.viewTab === "graph" ? "[ GRAPH ]" : " GRAPH "],
74
316
  ];
@@ -81,6 +323,100 @@ function tabsLine(state, suffix) {
81
323
  }
82
324
  return [{ text, zones }];
83
325
  }
326
+ function localClock(iso) {
327
+ const date = new Date(iso);
328
+ if (Number.isNaN(date.getTime()))
329
+ return "??:??";
330
+ return `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
331
+ }
332
+ function queueRows(snap) {
333
+ return [...snap.attention, ...snap.blocked, ...snap.inProgress, ...snap.pending, ...snap.recentlyFinished];
334
+ }
335
+ function recentWorkText(snap, row) {
336
+ const qitem = queueRows(snap).find((candidate) => candidate.qitemId === row.qitemId);
337
+ const work = qitem?.summary?.trim() || qitem?.body.split("\n").find((line) => line.trim())?.trim();
338
+ return row.summary?.trim() || work || "no work served";
339
+ }
340
+ function agentDrillForSession(snap, session) {
341
+ const found = findAgentBySession(snap, session);
342
+ return found
343
+ ? { type: "drill", resource: "agent", name: found.agent.name, target: { host: found.host.name, rig: found.rig.name, pod: found.pod.name } }
344
+ : undefined;
345
+ }
346
+ function recentTargetAction(snap, row) {
347
+ if (row.targetKind === "mission") {
348
+ if (snap.scopes?.some((mission) => mission.mission === row.target))
349
+ return { type: "scopes-mission-open", mission: row.target };
350
+ }
351
+ if (row.targetKind === "slice") {
352
+ for (const mission of snap.scopes ?? []) {
353
+ const slice = mission.slices.find((candidate) => candidate.id === row.target || candidate.dirName === row.target);
354
+ if (slice)
355
+ return { type: "scopes-open", mission: mission.mission, slice: slice.dirName };
356
+ }
357
+ }
358
+ const qitem = queueRows(snap).find((candidate) => candidate.qitemId === row.qitemId || candidate.qitemId === row.target);
359
+ return (qitem ? agentDrillForSession(snap, qitem.destinationSession) : undefined)
360
+ ?? agentDrillForSession(snap, row.actorSession)
361
+ ?? (row.rig && snap.hosts.some((host) => host.rigs.some((rig) => rig.name === row.rig))
362
+ ? { type: "drill", resource: "rig", name: row.rig }
363
+ : undefined);
364
+ }
365
+ function recentScopeMatches(snap, scope) {
366
+ const served = snap.recentTransitionsScope
367
+ ?? (snap.recentTransitionsRig ? { kind: "rig", rig: snap.recentTransitionsRig } : null);
368
+ if (!served || served.kind !== scope.kind)
369
+ return false;
370
+ return scope.kind === "instance" || (served.kind === "rig" && served.rig === scope.rig);
371
+ }
372
+ function recentLines(snap, scope, width, expanded) {
373
+ if (!recentScopeMatches(snap, scope) || snap.recentTransitions == null)
374
+ return [];
375
+ const timeW = 5;
376
+ const rows = expanded ? snap.recentTransitions : snap.recentTransitions.slice(-5);
377
+ const lines = [
378
+ ...(expanded ? [] : [{ text: "" }]),
379
+ sectionRule(`RECENT · ${scope.kind === "instance" ? "instance" : `rig ${scope.rig}`} · material queue transitions · newest last`, width),
380
+ ];
381
+ if (rows.length === 0)
382
+ return [...lines, { text: " No recorded transitions in the current window." }];
383
+ if (width < 78) {
384
+ const rigW = scope.kind === "instance" ? 9 : 0;
385
+ const changeW = Math.max(16, width - timeW - rigW - 2);
386
+ lines.push({ text: alignedRow([["TIME", timeW], ...(rigW ? [["RIG", rigW]] : []), ["CHANGE", changeW]]) });
387
+ for (const row of rows) {
388
+ const action = recentTargetAction(snap, row);
389
+ lines.push({
390
+ text: alignedRow([[localClock(row.ts), timeW], ...(rigW ? [[pad(row.rig ?? "?", rigW), rigW]] : []), [pad(row.change, changeW), changeW]]).slice(0, width),
391
+ ...(action ? { action } : {}),
392
+ });
393
+ lines.push({ text: ` ${pad(row.actorSession, Math.max(8, width - 8))}`.slice(0, width), ...(action ? { action } : {}) });
394
+ lines.push({ text: ` → ${row.target}`.slice(0, width), ...(action ? { action } : {}) });
395
+ lines.push(...wrapDetailValue("work", recentWorkText(snap, row), width)
396
+ .map((line) => ({ ...line, ...(action ? { action } : {}) })));
397
+ }
398
+ return lines;
399
+ }
400
+ const rigW = scope.kind === "instance" ? Math.min(16, Math.max(9, Math.floor(width * 0.13))) : 0;
401
+ const actorW = Math.min(26, Math.max(16, Math.floor(width * 0.21)));
402
+ const changeW = Math.min(36, Math.max(20, Math.floor(width * 0.28)));
403
+ const targetW = Math.max(10, width - timeW - rigW - actorW - changeW - (scope.kind === "instance" ? 4 : 3));
404
+ lines.push({ text: alignedRow([["TIME", timeW], ...(scope.kind === "instance" ? [["RIG", rigW]] : []), ["ACTOR", actorW], ["CHANGE", changeW], ["TARGET", targetW]]) });
405
+ for (const row of rows) {
406
+ const action = recentTargetAction(snap, row);
407
+ const text = alignedRow([
408
+ [localClock(row.ts), timeW],
409
+ ...(scope.kind === "instance" ? [[pad(row.rig ?? "?", rigW), rigW]] : []),
410
+ [pad(row.actorSession, actorW), actorW],
411
+ [pad(row.change, changeW), changeW],
412
+ [pad(row.target, targetW), targetW],
413
+ ]).slice(0, width);
414
+ lines.push({ text, ...(action ? { action } : {}) });
415
+ lines.push(...wrapDetailValue("work", recentWorkText(snap, row), width)
416
+ .map((line) => ({ ...line, ...(action ? { action } : {}) })));
417
+ }
418
+ return lines;
419
+ }
84
420
  function specTabsLine(state, name) {
85
421
  const active = state.viewTab === "topology" || state.viewTab === "yaml" ? state.viewTab : "configuration";
86
422
  const labels = ["topology", "configuration", "yaml"];
@@ -157,6 +493,124 @@ function fieldWrapped(label, values) {
157
493
  const first = wrapped[0].text.slice(valueCol);
158
494
  return [fieldLine({ label, value: first }), ...wrapped.slice(1)];
159
495
  }
496
+ function instanceContentLines(state, snap, host, contentWidth, motion) {
497
+ const lines = tabsLine(state, `instance ${host.name}`);
498
+ const scope = { kind: "instance" };
499
+ if (state.viewTab === "recent") {
500
+ const recent = recentLines(snap, scope, contentWidth, true);
501
+ return recent.length > 0
502
+ ? [...lines, ...recent]
503
+ : [...lines, { text: "" }, { text: motion.loading ? `${motion.frame} instance RECENT read pending` : "(instance RECENT window not served)" }];
504
+ }
505
+ if (state.viewTab === "overview") {
506
+ return [
507
+ ...lines,
508
+ ...detailPage({ text: `instance ${host.name}` }, [
509
+ {
510
+ title: "instance",
511
+ fields: [
512
+ { label: "identity", value: host.name },
513
+ { label: "transport", value: host.id ?? "local" },
514
+ { label: "shape", value: `${host.rigs.length} rigs · ${host.rigs.reduce((n, rig) => n + rig.pods.reduce((m, pod) => m + pod.agents.length, 0), 0)} seats` },
515
+ ],
516
+ },
517
+ {
518
+ title: "rigs",
519
+ lines: host.rigs.length > 0
520
+ ? host.rigs.map((rig) => listItem(alignedRow([[rig.name, 20], [rig.lifecycleState ?? "unknown", 20], [`${rig.pods.length} pods · ${rig.pods.reduce((n, pod) => n + pod.agents.length, 0)} seats`, 24]]), { type: "drill", resource: "rig", name: rig.name, target: { host: host.name } }))
521
+ : [{ text: " (no local rigs served — proven empty)" }],
522
+ },
523
+ ]),
524
+ ];
525
+ }
526
+ if (state.viewTab === "graph") {
527
+ for (const rig of host.rigs) {
528
+ lines.push({ text: "" }, sectionRule(`rig ${rig.name} · ${rig.lifecycleState ?? "unknown"}`, contentWidth));
529
+ if (!rig.graph) {
530
+ if (motion.loading) {
531
+ if (!motion.reduced)
532
+ motion.used = true;
533
+ lines.push({ text: ` ${motion.frame} topology graph read pending` });
534
+ }
535
+ else if (snap.readErrors.some((error) => error.startsWith(`graph(${rig.name})`))) {
536
+ lines.push({ text: " ✕ topology graph read failed — named in the status line" });
537
+ }
538
+ else {
539
+ lines.push({ text: " (no topology graph served)" });
540
+ }
541
+ continue;
542
+ }
543
+ const canvas = renderGraphStyle(state.graphStyle, rig.graph, { host: host.name, rig: rig.name, selected: null }, contentWidth);
544
+ const plain = canvas.plainLines();
545
+ const segs = canvas.segLines();
546
+ for (let row = 0; row < plain.length; row++)
547
+ lines.push({
548
+ text: plain[row],
549
+ segs: segs[row],
550
+ zones: canvas.zones.filter((zone) => zone.y === row).map((zone) => ({ start: zone.start, end: zone.end, action: zone.action })),
551
+ });
552
+ }
553
+ if (host.rigs.length === 0)
554
+ lines.push({ text: "" }, { text: " (no local rigs served — proven empty)" });
555
+ lines.push({ text: "" }, { text: ` style: ${state.graphStyle} · style hatchet|braille|braille-fallback rides the command bar` });
556
+ return lines;
557
+ }
558
+ lines.push({ text: state.filter ? `/ filter instance rows: ${state.filter} · / replace · esc clear` : "/ filter instance rows…" });
559
+ const columns = instanceAgentColumns(contentWidth);
560
+ lines.push({ text: tableRow(columns, { rig: "RIG", pod: "POD", seat: "SEAT", runtime: "RT", context: "CTX", status: "STATE", queue: "Q", work: "WORK", now: "NOW" }) });
561
+ lines.push({ text: "━".repeat(columnsWidth(columns)) });
562
+ let seatCount = 0;
563
+ let workingCount = 0;
564
+ let attentionCount = 0;
565
+ let openCount = 0;
566
+ for (const rig of host.rigs) {
567
+ const agents = rig.pods.flatMap((pod) => pod.agents.map((agent) => ({ pod: pod.name, agent })))
568
+ .filter(({ pod, agent }) => !state.filter || rig.name.includes(state.filter) || pod.includes(state.filter) || agent.name.includes(state.filter));
569
+ if (state.filter && agents.length === 0 && !rig.name.includes(state.filter))
570
+ continue;
571
+ const rigAction = { type: "drill", resource: "rig", name: rig.name, target: { host: host.name } };
572
+ if (agents.length === 0) {
573
+ lines.push({
574
+ text: tableRow(columns, { rig: rig.name, pod: "—", seat: "(no seats)", status: rig.lifecycleState ?? "unknown" }),
575
+ action: rigAction,
576
+ });
577
+ continue;
578
+ }
579
+ let previousPod = null;
580
+ for (const { pod, agent } of agents) {
581
+ const firstInPod = pod !== previousPod;
582
+ if (firstInPod && previousPod != null)
583
+ lines.push({ text: "┈".repeat(columnsWidth(columns)) });
584
+ previousPod = pod;
585
+ const stateCell = operationalState(agent.status, motion);
586
+ const queue = queueFacts(snap, agent.session);
587
+ seatCount += 1;
588
+ if (["active", "working", "running"].includes(agent.status))
589
+ workingCount += 1;
590
+ if (/attention|needs|blocked|unknown|failed/.test(agent.status))
591
+ attentionCount += 1;
592
+ openCount += queue.count;
593
+ lines.push({
594
+ text: tableRow(columns, {
595
+ rig: rig.name,
596
+ pod: firstInPod ? pod : "",
597
+ seat: `${stateCell.mark} ${seatName(pod, agent.name)}`,
598
+ runtime: runtimeShort(agent.runtime),
599
+ context: contextCompact(agent.context, contentWidth < 110),
600
+ status: stateCell.word,
601
+ queue: queue.count || "·",
602
+ work: queue.work,
603
+ now: queue.now,
604
+ }),
605
+ action: { type: "drill", resource: "agent", name: agent.name, target: { host: host.name, rig: rig.name, pod } },
606
+ zones: [{ start: 0, end: columns[0][2], action: rigAction }],
607
+ });
608
+ }
609
+ }
610
+ lines.push({ text: "" }, { text: `${host.rigs.length} rigs · ${seatCount} seats · ${workingCount} working · ${attentionCount} need attention · ${openCount} open rows` });
611
+ lines.push(...recentLines(snap, scope, contentWidth, false));
612
+ return lines;
613
+ }
160
614
  function contentLines(state, snap, contentWidth, motion) {
161
615
  const contentWidthForGraph = contentWidth;
162
616
  void contentWidthForGraph;
@@ -187,80 +641,13 @@ function contentLines(state, snap, contentWidth, motion) {
187
641
  const found = hostName ? findAgent(snap, leaf.name, { host: hostName, rig: rigName, pod: podName }) : findAgent(snap, leaf.name);
188
642
  if (!found)
189
643
  return [{ text: `agent "${leaf.name}" not in the current snapshot` }];
190
- const { agent, rig, pod } = found;
191
- const specInLibrary = !!agent.spec && !!findSpec(snap, agent.spec);
192
- // a4c9548a — S19 FOLLOW-ON FOUNDER RULING (binding, bounds the S19 marks
193
- // ruling): where there is ROOM, WRITE THE NAME — an icon NEVER replaces text
194
- // as the value. The detail page has room, so the runtime NAME is the VALUE
195
- // (honest placeholder when unserved); the mark's OWN token segments still ride
196
- // the seg channel (ROUND-4: colors/background survive stylization) but only
197
- // ACCOMPANY the name decoratively, never substitute. Topology cards remain
198
- // mark-only by space (layout.ts/hatchet.ts) — the ruling is bounded, not reversed.
199
- // LEG-7 LOW 2 (dead-arm cleanup, wave qitem 79159e6f): the daemon coerces a null runtime to the
200
- // string "unknown" BEFORE the wire (the icon-fix QA at 5a70e200 proved the old "— (not served)"
201
- // arm unreachable), so the defensive fallback matches that coercion — honest, never a misleading
202
- // placeholder. (The cwd field below keeps its own "— (not served)" — a legitimately-servable value.)
203
- const rtName = agent.runtime ?? "unknown";
204
- const rtSegs = [
205
- { text: " " },
206
- { text: "runtime:", token: "dim" },
207
- { text: " ".repeat(LABEL_W - "runtime:".length + 1) },
208
- { text: rtName },
209
- { text: " " },
210
- ...runtimeMarkSegs(agent.runtime),
211
- ];
212
- const runtimeLine = { text: rtSegs.map((g) => g.text).join(""), segs: rtSegs };
213
- return detailPage({ text: `agent ${agent.name}` }, [
214
- {
215
- title: "seat",
216
- fields: [
217
- { label: "state", value: agent.status },
218
- { label: "host", value: found.host.name },
219
- { label: "rig", value: rig.name },
220
- { label: "pod", value: pod.name },
221
- ],
222
- lines: [
223
- runtimeLine,
224
- fieldLine({
225
- label: "context",
226
- // ROUND-3 mr7: a quiet determinate bar rides REAL fractions only
227
- value: agent.context == null
228
- ? "— (not yet known)"
229
- : `${agent.context}% used · ${agent.tokens ?? "—"} tokens ${barCells(agent.context / 100, 10)}`,
230
- }),
231
- // S19 MR4 (§D9, founder: "very important"): the FULL absolute
232
- // working directory, verbatim; honest — when not served
233
- fieldLine({ label: "cwd", value: agent.cwd ?? "— (not served)" }),
234
- ],
235
- },
236
- {
237
- title: "spec",
238
- fields: [
239
- specInLibrary
240
- ? {
241
- label: "spec",
242
- value: agent.spec,
243
- link: { type: "cross", kind: "spec-of", name: agent.name, target: { host: found.host.name, rig: rig.name, pod: pod.name } },
244
- }
245
- : { label: "spec", value: agent.spec ? `${agent.spec} (not in library)` : "—" },
246
- ],
247
- },
248
- {
249
- title: "actions",
250
- fields: [
251
- ...(agent.attach ? [{ label: "attach", value: agent.attach }] : []),
252
- {
253
- label: "terminal",
254
- value: `term ▸ pod ${pod.name}`,
255
- link: { type: "act", act: "open-terminal", view: `pod:${rig.name}/${pod.name}` },
256
- },
257
- ],
258
- },
259
- ]);
644
+ return agentDetailLines(snap, found, contentWidth);
260
645
  }
261
- const rigName = state.drill.find((d) => d.kind === "rig")?.name ?? snap.hosts[0]?.rigs[0]?.name;
262
646
  const hostName = state.drill.find((d) => d.kind === "host")?.name;
263
647
  const host = (hostName ? snap.hosts.find((candidate) => candidate.name === hostName) : snap.hosts[0]);
648
+ if (leaf?.kind === "host" && host)
649
+ return instanceContentLines(state, snap, host, contentWidth, motion);
650
+ const rigName = state.drill.find((d) => d.kind === "rig")?.name ?? snap.hosts[0]?.rigs[0]?.name;
264
651
  const rig = host?.rigs.find((candidate) => candidate.name === rigName);
265
652
  if (!rig || !host) {
266
653
  // round-6 (guard): the ROOT topology branch consumes the OWNER's load
@@ -284,6 +671,12 @@ function contentLines(state, snap, contentWidth, motion) {
284
671
  .filter((a) => !state.filter || a.name.includes(state.filter) || a.pod.includes(state.filter));
285
672
  const suffix = `rig ${rig.name}${podFilter ? ` · pod ${podFilter}` : ""}${state.filter ? ` · filter "${state.filter}"` : ""}`;
286
673
  lines.push(...tabsLine(state, suffix));
674
+ if (state.viewTab === "recent") {
675
+ const recent = recentLines(snap, { kind: "rig", rig: rig.name }, contentWidth, true);
676
+ return recent.length > 0
677
+ ? [...lines, ...recent]
678
+ : [...lines, { text: "" }, { text: motion.loading ? `${motion.frame} rig RECENT read pending` : "(rig RECENT window not served)" }];
679
+ }
287
680
  if (state.viewTab === "graph") {
288
681
  // slice-17 topology view (frame-01): the rig's SERVED /graph projection
289
682
  // rendered by the style registry; honest-empty until the read answers.
@@ -332,7 +725,7 @@ function contentLines(state, snap, contentWidth, motion) {
332
725
  lines.push({ text: ` style: ${state.graphStyle} · style hatchet|braille|braille-fallback rides the command bar` });
333
726
  return lines;
334
727
  }
335
- lines.push({ text: state.filter ? `/ filter agents: ${state.filter}` : "/ filter agents…" });
728
+ lines.push({ text: state.filter ? `/ filter agents: ${state.filter} · / replace · esc clear` : "/ filter agents…" });
336
729
  if (state.viewTab === "overview") {
337
730
  lines.push(...detailPage({ text: `rig ${rig.name}` }, [
338
731
  {
@@ -351,16 +744,24 @@ function contentLines(state, snap, contentWidth, motion) {
351
744
  return lines;
352
745
  }
353
746
  const agentCols = agentColumns(contentWidth);
747
+ const narrowFactory = !agentCols.some(([key]) => key === "model");
748
+ if (narrowFactory)
749
+ lines.push({ text: "MODEL/NOW/ACTIONS on drill (enter)" });
354
750
  lines.push({
355
751
  text: tableRow(agentCols, {
356
- rig: "RIG", pod: "POD", agent: "AGENT", runtime: "RUNTIME",
357
- context: "CTX%", tokens: "TOKENS", status: "STATUS", actions: "ACTIONS",
752
+ pod: "POD", seat: "SEAT", runtime: "RT", model: "MODEL", context: "CTX",
753
+ status: "STATE", queue: "Q", work: "WORK", now: "NOW", actions: "ACTIONS",
358
754
  }),
359
755
  });
360
- lines.push({ text: "─".repeat(columnsWidth(agentCols)) });
756
+ lines.push({ text: "━".repeat(columnsWidth(agentCols)) });
361
757
  const actionsIndex = agentCols.findIndex(([key]) => key === "actions");
362
- const actionsColStart = agentCols.slice(0, actionsIndex).reduce((n, [, , width]) => n + width + 1, 0);
758
+ const actionsColStart = actionsIndex < 0 ? -1 : agentCols.slice(0, actionsIndex).reduce((n, [, , width]) => n + width + 1, 0);
759
+ let previousPod = null;
363
760
  for (const a of rows) {
761
+ const firstInPod = a.pod !== previousPod;
762
+ if (firstInPod && previousPod != null && !narrowFactory)
763
+ lines.push({ text: "┈".repeat(columnsWidth(agentCols)) });
764
+ previousPod = a.pod;
364
765
  // ACTIONS = drive-structure ONLY (BR-9), each mapped to an EXISTING
365
766
  // write contract: `run ▸` = the rig-restore write (rendered only where
366
767
  // it applies — the seat is not running); `term ▸` = the terminal-open
@@ -368,25 +769,31 @@ function contentLines(state, snap, contentWidth, motion) {
368
769
  const canRun = a.canRun ?? !a.live;
369
770
  const actionsCell = canRun ? "run ▸ · term ▸" : "term ▸";
370
771
  const zones = [];
371
- const termOffset = actionsColStart + actionsCell.indexOf("term ▸");
372
- zones.push({ start: termOffset, end: termOffset + "term ▸".length, action: { type: "act", act: "open-terminal", view: `pod:${rig.name}/${a.pod}` } });
373
- if (canRun)
772
+ if (actionsColStart >= 0) {
773
+ const termOffset = actionsColStart + actionsCell.indexOf("term ▸");
774
+ zones.push({ start: termOffset, end: termOffset + "term ▸".length, action: { type: "act", act: "open-terminal", view: `pod:${rig.name}/${a.pod}` } });
775
+ }
776
+ if (canRun && actionsColStart >= 0)
374
777
  zones.push({
375
778
  start: actionsColStart,
376
779
  end: actionsColStart + "run ▸".length,
377
780
  action: { type: "act", act: "run", rigId: rig.id ?? rig.name, agent: a.name },
378
781
  });
782
+ const stateCell = operationalState(a.status, motion);
783
+ const queue = queueFacts(snap, a.session);
379
784
  lines.push({
380
785
  // the WHOLE row is the hit surface (not a testid'd control): clicking
381
786
  // any visible cell opens the agent; the ACTIONS zones override.
382
787
  text: tableRow(agentCols, {
383
- rig: rig.name,
384
- pod: a.pod,
385
- agent: a.name,
386
- runtime: a.runtime,
387
- context: a.context == null ? "—" : `${a.context}%`,
388
- tokens: a.tokens ?? "—",
389
- status: a.status,
788
+ pod: firstInPod ? a.pod : "",
789
+ seat: `${stateCell.mark} ${seatName(a.pod, a.name)}`,
790
+ runtime: runtimeShort(a.runtime),
791
+ model: tableModel(a.model),
792
+ context: contextCompact(a.context, narrowFactory),
793
+ status: stateCell.word,
794
+ queue: queue.count || "·",
795
+ work: queue.work,
796
+ now: queue.now,
390
797
  actions: actionsCell,
391
798
  }),
392
799
  action: { type: "drill", resource: "agent", name: a.name, target: { host: host.name, rig: rig.name, pod: a.pod } },
@@ -394,7 +801,11 @@ function contentLines(state, snap, contentWidth, motion) {
394
801
  });
395
802
  }
396
803
  lines.push({ text: "" });
397
- lines.push({ text: `${rows.length} of ${all.length} / ${rows.filter((agent) => agent.status === "idle").length} idle` });
804
+ const working = rows.filter((agent) => ["active", "working", "running"].includes(agent.status)).length;
805
+ const attention = rows.filter((agent) => /attention|needs|blocked|unknown|failed/.test(agent.status)).length;
806
+ lines.push({ text: `${rows.length} seats · ${working} working · ${attention} need attention · ${rows.reduce((n, agent) => n + queueFacts(snap, agent.session).count, 0)} open rows` });
807
+ if (!podFilter)
808
+ lines.push(...recentLines(snap, { kind: "rig", rig: rig.name }, contentWidth, false));
398
809
  return lines;
399
810
  }
400
811
  if (state.section === "specs") {
@@ -529,7 +940,7 @@ function contentLines(state, snap, contentWidth, motion) {
529
940
  return lines;
530
941
  }
531
942
  lines.push({ text: "SPEC LIBRARY" });
532
- lines.push({ text: state.filter ? `/ filter specs: ${state.filter}` : "/ filter specs…" });
943
+ lines.push({ text: state.filter ? `/ filter specs: ${state.filter} · / replace · esc clear` : "/ filter specs…" });
533
944
  // mirrors the explorer exactly (same grouping, same expansion state, same
534
945
  // filter-overrides-collapse rule) — glance consistency across panes
535
946
  const expandedSet = new Set(state.expanded);
@@ -623,8 +1034,9 @@ function contentLines(state, snap, contentWidth, motion) {
623
1034
  return lines;
624
1035
  }
625
1036
  if (state.section === "scopes") {
626
- // SCOPES owns both levels: mission selection opens the execution story;
627
- // slice selection retains the store-direct detail with a compact execution strip.
1037
+ // SCOPES owns both levels. Both mission-graph and Explorer slice routes land
1038
+ // on the same execution-backed canonical detail; store-direct content is
1039
+ // composed into that page instead of surviving as a competing destination.
628
1040
  const sel = state.scopesSelected;
629
1041
  const missionName = state.scopesMission;
630
1042
  const execution = snap.execution?.mission === missionName ? snap.execution : null;
@@ -632,7 +1044,16 @@ function contentLines(state, snap, contentWidth, motion) {
632
1044
  ? (snap.scopes ?? []).find((m) => m.mission === sel.mission)?.slices.find((sl) => sl.dirName === sel.slice) ?? null
633
1045
  : null;
634
1046
  if (state.executionOpen && execution) {
635
- return executionContentLines(execution, snap.scopes, snap.readErrors, state.executionOpen, contentWidth, false);
1047
+ return executionContentLines(execution, snap.scopes, snap.readErrors, state.executionOpen, contentWidth, false, snap.sliceDetail, {
1048
+ collapseReqs: state.scopesCollapseReqs,
1049
+ narrative: state.scopesNarrative,
1050
+ });
1051
+ }
1052
+ if (detail && execution) {
1053
+ return executionContentLines(execution, snap.scopes, snap.readErrors, `slice:${detail.id ?? detail.dirName}`, contentWidth, false, snap.sliceDetail, {
1054
+ collapseReqs: state.scopesCollapseReqs,
1055
+ narrative: state.scopesNarrative,
1056
+ });
636
1057
  }
637
1058
  if (!detail && missionName) {
638
1059
  const lines = executionContentLines(execution, snap.scopes, snap.readErrors, state.executionOpen, contentWidth, !snap.hydratedAt || snap.executionMission !== missionName);
@@ -642,7 +1063,7 @@ function contentLines(state, snap, contentWidth, motion) {
642
1063
  collapseReqs: state.scopesCollapseReqs,
643
1064
  narrative: state.scopesNarrative,
644
1065
  width: contentWidth,
645
- executionStrip: detail ? executionSliceStripLines(execution, detail.id ?? detail.dirName, detail.dirName, contentWidth, detail.status) : undefined,
1066
+ executionStrip: detail ? executionSliceStripLines(null, detail.id ?? detail.dirName, detail.dirName, contentWidth, detail.status) : undefined,
646
1067
  });
647
1068
  }
648
1069
  return [{ text: `(${state.section})` }];
@@ -670,14 +1091,17 @@ function spliceMarkerIntoSegs(segs, pos) {
670
1091
  }
671
1092
  return out;
672
1093
  }
673
- function paneRule(cols, joint, leftTitle, rightTitle) {
674
- const left = leftTitle ? `─ ${leftTitle} ` : "";
675
- const right = rightTitle ? `─ ${rightTitle} ` : "";
676
- const leftPart = (left + "─".repeat(EXPL_W)).slice(0, EXPL_W);
677
- const rightPart = (right + "─".repeat(cols)).slice(0, Math.max(cols - EXPL_W - 1, 0));
678
- return `${leftPart}${joint}${rightPart}`;
1094
+ function paneRule(cols, explW, joint, leftTitle, rightTitle) {
1095
+ void joint;
1096
+ const left = leftTitle ? `━ ${leftTitle} ` : "";
1097
+ const right = rightTitle ? `━ ${rightTitle} ` : "";
1098
+ const leftPart = (left + "━".repeat(explW)).slice(0, explW);
1099
+ const rightPart = (right + "━".repeat(cols)).slice(0, Math.max(cols - explW - 1, 0));
1100
+ return `${leftPart}╋${rightPart}`;
679
1101
  }
680
1102
  function keybindHints(state) {
1103
+ if (state.copyMode)
1104
+ return "drag to select/copy · v resume mouse · q quit";
681
1105
  // Affordance surfaces on REAL scrollability (contentMaxOffset), never gated
682
1106
  // behind already-being-content-focused — that gate was the catch-22 (the
683
1107
  // hint hid exactly where it was needed). When ↑↓ themselves scroll (a
@@ -686,7 +1110,8 @@ function keybindHints(state) {
686
1110
  const arrowsScroll = specDetailArrowsScroll(state);
687
1111
  const nav = arrowsScroll ? "↑↓ scroll" : "↑↓ move";
688
1112
  const pageScroll = state.contentMaxOffset > 0 && !arrowsScroll ? "⇞⇟ scroll · " : "";
689
- return `${nav} · ←→ pane · ⏎ open · ${pageScroll}: command · / filter · f footer · q quit`;
1113
+ const filter = state.filter ? "/ replace · esc clear" : "/ filter";
1114
+ return `${nav} · ←→ pane · ⏎ open · ${pageScroll}: command · ${filter} · v select/copy · f footer · q quit`;
690
1115
  }
691
1116
  /** The PULSE view renders FULL-WIDTH with NO explorer sidebar (increment 2). A
692
1117
  * minimal self-contained screen: cmd bar + a full-width titled rule + the pulse
@@ -712,8 +1137,19 @@ function truncateSegs(segs, width) {
712
1137
  }
713
1138
  return out;
714
1139
  }
1140
+ /** The disclosure cell is a distinct control from the row body. Hit lookup is
1141
+ * first-match, so register this one-cell target before the row-wide target. */
1142
+ function pushExplorerTargets(hitMap, row, display, y, explorerWidth) {
1143
+ if (row.disclosureAction) {
1144
+ const at = display.search(/[⌄›]/);
1145
+ if (at >= 0)
1146
+ hitMap.push({ y, x1: at + 2, x2: at + 2, action: row.disclosureAction });
1147
+ }
1148
+ hitMap.push({ y, x1: 1, x2: explorerWidth, action: row.action });
1149
+ }
715
1150
  function renderPulseScreen(state, snap, options, inputLine) {
716
1151
  const { cols = 120, rows = 32, nowMs = 0 } = options;
1152
+ const explW = explorerWidth(cols);
717
1153
  // FOUNDER OPTION-B (supersedes the earlier full-width ruling): PULSE renders as
718
1154
  // a content-pane view INSIDE the normal chrome — the EXPLORER sidebar STAYS (it
719
1155
  // is the founder's action path: from a needs-you row, mouse to the sidebar and
@@ -733,7 +1169,7 @@ function renderPulseScreen(state, snap, options, inputLine) {
733
1169
  const reduced = reducedMotion();
734
1170
  const load = options.load ?? { inFlight: false, settled: true };
735
1171
  const loading = load.inFlight || !load.settled;
736
- const frame = spinnerFrame(Math.floor(nowMs / 120), options.colorMode ?? "truecolor", reduced);
1172
+ const frame = spinnerFrame(Math.floor(nowMs / MOTION_FRAME_MS), options.colorMode ?? "truecolor", reduced);
737
1173
  const liveFlashes = (options.rowFlashes ?? []).filter((f) => flashActive(f.at, nowMs, 600, reduced));
738
1174
  const ackFlashes = (options.rowFlashes ?? []).filter((f) => flashActive(f.at, nowMs, 600, false));
739
1175
  const lines = [];
@@ -760,10 +1196,10 @@ function renderPulseScreen(state, snap, options, inputLine) {
760
1196
  lines.push(pad(`${mark} ${label}${alias} ${tail}`, cols));
761
1197
  }
762
1198
  }
763
- const explorerTitle = state.focusedPane === "explorer" ? "[ EXPLORER ]" : "EXPLORER";
764
- const contentTitle = state.focusedPane === "content" ? "[ PULSE ]" : "PULSE";
765
- lines.push(paneRule(cols, "┬", explorerTitle, contentTitle));
766
- const contentWidth = Math.max(cols - EXPL_W - 2, 0);
1199
+ const explorerTitle = state.focusedPane === "explorer" ? "{ EXPLORER }" : "EXPLORER";
1200
+ const contentTitle = state.focusedPane === "content" ? "{ PULSE }" : "PULSE";
1201
+ lines.push(paneRule(cols, explW, "top", explorerTitle, contentTitle));
1202
+ const contentWidth = Math.max(cols - explW - 2, 0);
767
1203
  const model = buildPulseModel(snap, nowMs);
768
1204
  const chromeRows = 3; // bottom rule + hint bar + status line
769
1205
  const bodyRows = Math.max(rows - 2 - chromeRows, 1);
@@ -802,7 +1238,7 @@ function renderPulseScreen(state, snap, options, inputLine) {
802
1238
  const visiblePulse = pulseLines.slice(contentStart, contentStart + bodyRows);
803
1239
  // EXPLORER sidebar = the normal navigator (same helpers as every other view).
804
1240
  const explorer = computeExplorerRows(state, snap);
805
- const { labels: explorerDisplay, metas: explorerMetas } = navigatorDisplay(explorer, snap, EXPL_W - 1);
1241
+ const { labels: explorerDisplay, metas: explorerMetas } = navigatorDisplay(explorer, snap, explW - 1);
806
1242
  const explorerStart = Math.min(Math.max(state.selection - bodyRows + 1, 0), Math.max(explorer.length - bodyRows, 0));
807
1243
  for (let i = 0; i < bodyRows; i++) {
808
1244
  const y = lines.length + 1;
@@ -812,16 +1248,16 @@ function renderPulseScreen(state, snap, options, inputLine) {
812
1248
  const flashed = row?.key != null && ackFlashes.some((f) => f.key === row.key);
813
1249
  if (flashed)
814
1250
  flashAck = true;
815
- const marker = explorerIndex === state.selection && row ? (flashed ? "»" : "›") : flashed ? "≈" : " ";
816
- const left = pad(row ? `${marker}${explorerDisplay[explorerIndex] ?? row.label}` : "", EXPL_W);
1251
+ const marker = explorerIndex === state.selection && row ? (flashed ? "◆" : "▶") : flashed ? "≈" : " ";
1252
+ const left = pad(row ? `${marker}${explorerDisplay[explorerIndex] ?? row.label}` : "", explW);
817
1253
  // CONTENT half = the pulse view, truncated to the content width. Selection is
818
1254
  // the per-cell bg on the segs (mock affordance), so the content marker slot
819
1255
  // stays blank — no "›" chevron (the native affordance the mock overrides).
820
1256
  const citem = visiblePulse[i];
821
1257
  const contentText = (citem?.text ?? "").slice(0, contentWidth);
822
- lines.push(pad(`${left}│ ${contentText}`, cols));
1258
+ lines.push(pad(`${left}┃ ${contentText}`, cols));
823
1259
  if (row) {
824
- hitMap.push({ y, x1: 1, x2: EXPL_W, action: row.action });
1260
+ pushExplorerTargets(hitMap, row, explorerDisplay[explorerIndex] ?? row.label, y, explW);
825
1261
  explorerRows.push({ ...row, y });
826
1262
  const em = explorerMetas[explorerIndex];
827
1263
  if (em && em.length)
@@ -833,16 +1269,16 @@ function renderPulseScreen(state, snap, options, inputLine) {
833
1269
  segRows[y] = truncateSegs(citem.segs, contentWidth);
834
1270
  }
835
1271
  // Lane cells → content targets, x mapped into the content column (origin =
836
- // EXPL_W + 3, matching the normal content zone geometry), clamped to `cols`.
1272
+ // explorer boundary + 3, matching normal content geometry), clamped to `cols`.
837
1273
  for (const t of visibleTargets) {
838
- const x1 = EXPL_W + 2 + t.x1;
1274
+ const x1 = explW + 2 + t.x1;
839
1275
  if (x1 > cols)
840
1276
  continue;
841
- const target = { y: t.lineIndex - contentStart + 3, x1, x2: Math.min(EXPL_W + 2 + t.x2, cols), action: t.action };
1277
+ const target = { y: t.lineIndex - contentStart + 3, x1, x2: Math.min(explW + 2 + t.x2, cols), action: t.action };
842
1278
  contentTargets.push(target);
843
1279
  hitMap.push(target);
844
1280
  }
845
- lines.push(paneRule(cols, "┴"));
1281
+ lines.push(paneRule(cols, explW, "bottom"));
846
1282
  lines.push(pad(keybindHints(state), cols));
847
1283
  const drillPath = state.drill.map((d) => d.name).join(" → ");
848
1284
  const readWarn = snap.readErrors.length > 0 ? ` ⚠ ${snap.readErrors.length} read(s) failed: ${snap.readErrors[0]}` : "";
@@ -858,6 +1294,7 @@ function renderPulseScreen(state, snap, options, inputLine) {
858
1294
  const anyFlash = model.lanes.some((l) => l.rows.some((r) => r.flashed));
859
1295
  return {
860
1296
  lines: lines.slice(0, rows),
1297
+ explorerWidth: explW,
861
1298
  hitMap,
862
1299
  contentTargets,
863
1300
  contentMaxOffset: maxContentOffset,
@@ -905,13 +1342,14 @@ function wrapContentLines(content, width) {
905
1342
  return out;
906
1343
  }
907
1344
  function crashCartShell(content, led, contentTitle, cols, rows, inputLine, opts) {
1345
+ const explW = explorerWidth(cols);
908
1346
  const lines = [];
909
1347
  const segRows = {};
910
1348
  lines.push(pad(`cmd ▸ ${inputLine}▊`, cols));
911
- lines.push(paneRule(cols, "┬", "EXPLORER", contentTitle));
1349
+ lines.push(paneRule(cols, explW, "top", "{ EXPLORER }", contentTitle));
912
1350
  // The ledger-fed explorer column: the honest marker, then one row per rig (name + seat count).
913
1351
  const leftRows = [led.note, "", ...led.rows.map((r) => `${r.label} (${r.seatCount})`)];
914
- const contentWidth = Math.max(cols - EXPL_W - 2, 0);
1352
+ const contentWidth = Math.max(cols - explW - 2, 0);
915
1353
  if (opts?.wrap)
916
1354
  content = wrapContentLines(content, contentWidth);
917
1355
  const bodyRows = Math.max(rows - 2 - 3, 1); // minus cmd bar + top rule + (bottom rule, hints, status)
@@ -922,14 +1360,14 @@ function crashCartShell(content, led, contentTitle, cols, rows, inputLine, opts)
922
1360
  const scroll = Math.max(0, Math.min(contentMaxOffset, opts?.scroll ?? 0));
923
1361
  for (let i = 0; i < bodyRows; i++) {
924
1362
  const y = lines.length + 1;
925
- const left = pad(leftRows[i] ?? "", EXPL_W);
1363
+ const left = pad(leftRows[i] ?? "", explW);
926
1364
  const citem = content[scroll + i];
927
1365
  const contentText = (citem?.text ?? "").slice(0, contentWidth);
928
- lines.push(pad(`${left}│ ${contentText}`, cols));
1366
+ lines.push(pad(`${left}┃ ${contentText}`, cols));
929
1367
  if (citem?.segs)
930
1368
  segRows[y] = truncateSegs(citem.segs, contentWidth);
931
1369
  }
932
- lines.push(paneRule(cols, "┴"));
1370
+ lines.push(paneRule(cols, explW, "bottom"));
933
1371
  lines.push(pad("", cols));
934
1372
  const scrollHint = contentMaxOffset > 0 ? ` · ↑↓ scroll (${scroll}/${contentMaxOffset})` : "";
935
1373
  lines.push(pad(`[crash-cart] daemon down · explorer ${led.note}${scrollHint}`, cols));
@@ -937,6 +1375,7 @@ function crashCartShell(content, led, contentTitle, cols, rows, inputLine, opts)
937
1375
  lines.push("");
938
1376
  return {
939
1377
  lines: lines.slice(0, rows),
1378
+ explorerWidth: explW,
940
1379
  hitMap: [],
941
1380
  contentTargets: [],
942
1381
  contentMaxOffset,
@@ -946,6 +1385,7 @@ function crashCartShell(content, led, contentTitle, cols, rows, inputLine, opts)
946
1385
  }
947
1386
  export function renderScreen(state, snap, options = {}, inputLine = "") {
948
1387
  const { cols = 120, rows = 32, nowMs = 0 } = options;
1388
+ const explW = explorerWidth(cols);
949
1389
  // 5.2 crash-cart (shell-placement rework, ruling 3c6c2be0): daemon-DOWN renders as a CONTENT-PANE
950
1390
  // view inside the standard shell — the explorer sidebar is ALWAYS present, ledger-fed + honestly
951
1391
  // marked (from the SAME one-JSON discovery, never a second read). Content moves into the right pane
@@ -986,7 +1426,7 @@ export function renderScreen(state, snap, options = {}, inputLine = "") {
986
1426
  const reduced = reducedMotion();
987
1427
  const load = options.load ?? { inFlight: false, settled: true };
988
1428
  const motion = {
989
- frame: spinnerFrame(Math.floor(nowMs / 120), options.colorMode ?? "truecolor", reduced),
1429
+ frame: spinnerFrame(Math.floor(nowMs / MOTION_FRAME_MS), options.colorMode ?? "truecolor", reduced),
990
1430
  reduced,
991
1431
  used: false,
992
1432
  loading: load.inFlight || !load.settled,
@@ -1016,14 +1456,14 @@ export function renderScreen(state, snap, options = {}, inputLine = "") {
1016
1456
  }
1017
1457
  const sectionTitle = { topology: "TOPOLOGY", specs: "SPECS", needs: "NEEDS-YOU" }[state.section] ?? state.section.toUpperCase();
1018
1458
  // active-pane emphasis (k9s-class chrome): the focused pane's title is bracketed
1019
- const explorerTitle = state.focusedPane === "explorer" ? "[ EXPLORER ]" : "EXPLORER";
1020
- const contentTitle = state.focusedPane === "content" ? `[ ${sectionTitle} ]` : sectionTitle;
1021
- lines.push(paneRule(cols, "┬", explorerTitle, contentTitle));
1459
+ const explorerTitle = state.focusedPane === "explorer" ? "{ EXPLORER }" : "EXPLORER";
1460
+ const contentTitle = state.focusedPane === "content" ? `{ ${sectionTitle} }` : sectionTitle;
1461
+ lines.push(paneRule(cols, explW, "top", explorerTitle, contentTitle));
1022
1462
  const explorer = computeExplorerRows(state, snap);
1023
1463
  // Slice-17: the file-tree re-skin is a DISPLAY transform only — rows, keys,
1024
1464
  // actions, and the hit-map all keep resolving against the row model above.
1025
- const { labels: explorerDisplay, metas: explorerMetas } = navigatorDisplay(explorer, snap, EXPL_W - 1);
1026
- const content = contentLines(state, snap, Math.max(cols - EXPL_W - 2, 0), motion);
1465
+ const { labels: explorerDisplay, metas: explorerMetas } = navigatorDisplay(explorer, snap, explW - 1);
1466
+ const content = contentLines(state, snap, Math.max(cols - explW - 2, 0), motion);
1027
1467
  const footer = state.footerOn ? snap.stream.at(-1) : undefined;
1028
1468
  // round-5 (guard): the tmux-style ONE-SHOT activity flash targets the
1029
1469
  // flashed agent's EXPLORER row — per-seat pane-output events from the
@@ -1073,8 +1513,8 @@ export function renderScreen(state, snap, options = {}, inputLine = "") {
1073
1513
  const flashed = row?.key != null && ackFlashes.some((f) => f.key === row.key);
1074
1514
  if (flashed)
1075
1515
  flashAck = true;
1076
- const marker = explorerIndex === state.selection && row ? (flashed ? "»" : "›") : flashed ? "≈" : " ";
1077
- const left = pad(row ? `${marker}${explorerDisplay[explorerIndex] ?? row.label}` : "", EXPL_W);
1516
+ const marker = explorerIndex === state.selection && row ? (flashed ? "◆" : "▶") : flashed ? "≈" : " ";
1517
+ const left = pad(row ? `${marker}${explorerDisplay[explorerIndex] ?? row.label}` : "", explW);
1078
1518
  const item = visibleContent[i];
1079
1519
  const targetIndex = contentTargets.length;
1080
1520
  const zones = item?.zones ?? [];
@@ -1095,9 +1535,9 @@ export function renderScreen(state, snap, options = {}, inputLine = "") {
1095
1535
  else
1096
1536
  contentMarker = "›";
1097
1537
  }
1098
- lines.push(pad(`${left}│${contentMarker}${contentText}`, cols));
1538
+ lines.push(pad(`${left}┃${contentMarker}${contentText}`, cols));
1099
1539
  if (row) {
1100
- hitMap.push({ y, x1: 1, x2: EXPL_W, action: row.action });
1540
+ pushExplorerTargets(hitMap, row, explorerDisplay[explorerIndex] ?? row.label, y, explW);
1101
1541
  explorerRows.push({ ...row, y });
1102
1542
  const em = explorerMetas[explorerIndex];
1103
1543
  if (em && em.length)
@@ -1107,12 +1547,12 @@ export function renderScreen(state, snap, options = {}, inputLine = "") {
1107
1547
  }
1108
1548
  // zones first: hit lookup takes the first match, so a zone wins over the row-wide action
1109
1549
  for (const z of zones) {
1110
- const target = { y, x1: EXPL_W + 3 + z.start, x2: EXPL_W + 2 + z.end, action: z.action };
1550
+ const target = { y, x1: explW + 3 + z.start, x2: explW + 2 + z.end, action: z.action };
1111
1551
  hitMap.push(target);
1112
1552
  contentTargets.push(target);
1113
1553
  }
1114
1554
  if (item?.action) {
1115
- const target = { y, x1: EXPL_W + 3, x2: cols, action: item.action };
1555
+ const target = { y, x1: explW + 3, x2: cols, action: item.action };
1116
1556
  hitMap.push(target);
1117
1557
  contentTargets.push(target);
1118
1558
  }
@@ -1123,13 +1563,14 @@ export function renderScreen(state, snap, options = {}, inputLine = "") {
1123
1563
  lines.push(pad(`≋ ${footer.tsEmitted.slice(11, 16)} ${footer.sourceSession}: ${footer.body}`, cols));
1124
1564
  const drillPath = state.drill.map((d) => d.name).join(" → ");
1125
1565
  const readWarn = snap.readErrors.length > 0 ? ` ⚠ ${snap.readErrors.length} read(s) failed: ${snap.readErrors[0]}` : "";
1126
- lines.push(paneRule(cols, "┴"));
1566
+ lines.push(paneRule(cols, explW, "bottom"));
1127
1567
  lines.push(pad(keybindHints(state), cols));
1128
1568
  lines.push(pad(`[${state.instanceId}] ${state.section}${drillPath ? " · " + drillPath : ""}${state.lastError ? " ✗ " + state.lastError : ""}${state.notice ? " ▸ " + state.notice : ""}${readWarn}`, cols));
1129
1569
  while (lines.length < rows)
1130
1570
  lines.push("");
1131
1571
  return {
1132
1572
  lines: lines.slice(0, rows),
1573
+ explorerWidth: explW,
1133
1574
  hitMap,
1134
1575
  contentTargets,
1135
1576
  contentMaxOffset: maxContentOffset,