@north-light/crouter 0.3.170 → 0.3.172

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 (670) hide show
  1. package/dist/api/client.d.ts +37 -11
  2. package/dist/api/client.js +84 -15
  3. package/dist/api/dto/human.d.ts +53 -39
  4. package/dist/api/dto/human.js +2 -3
  5. package/dist/api/dto/inbox.d.ts +0 -1
  6. package/dist/api/dto/nodes.d.ts +12 -0
  7. package/dist/api/dto/review-comments.d.ts +137 -0
  8. package/dist/api/dto/review-comments.js +5 -0
  9. package/dist/api/dto/reviews.d.ts +109 -0
  10. package/dist/api/dto/reviews.js +5 -0
  11. package/dist/api/index.d.ts +2 -0
  12. package/dist/api/index.js +2 -0
  13. package/dist/api/routes.d.ts +17 -4
  14. package/dist/api/routes.js +21 -5
  15. package/dist/build-root.d.ts +1 -16
  16. package/dist/build-root.js +1 -25
  17. package/dist/builtin-memory/00-runtime-base.md +7 -5
  18. package/dist/builtin-memory/04-base-worker.md +1 -1
  19. package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
  20. package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
  21. package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +1 -1
  22. package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -1
  23. package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -1
  24. package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -1
  25. package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -1
  26. package/dist/builtin-memory/05-kinds/review/00-base.md +1 -1
  27. package/dist/builtin-memory/05-kinds/review/companion/00-base.md +20 -0
  28. package/dist/builtin-memory/05-kinds/spec/00-base.md +3 -7
  29. package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +3 -3
  30. package/dist/builtin-memory/05-kinds/spec/requirements.md +3 -3
  31. package/dist/builtin-memory/design.md +2 -2
  32. package/dist/builtin-memory/insights/capture.md +50 -0
  33. package/dist/builtin-memory/insights/init.md +45 -0
  34. package/dist/builtin-memory/insights/listen.md +9 -0
  35. package/dist/builtin-memory/internal/agent-shaping.md +2 -2
  36. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  37. package/dist/builtin-memory/internal/plugins.md +12 -11
  38. package/dist/builtin-memory/internal/storage-tiers.md +2 -2
  39. package/dist/builtin-memory/{planning.md → plan/roadmap.md} +3 -3
  40. package/dist/builtin-memory/plan.md +19 -0
  41. package/dist/builtin-memory/spec/guide.md +38 -0
  42. package/dist/builtin-memory/spec/requirements.md +31 -0
  43. package/dist/builtin-memory/spec/roadmap.md +35 -0
  44. package/dist/builtin-memory/spec.md +10 -86
  45. package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +3 -4
  46. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +49 -5
  47. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +56 -0
  48. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +920 -0
  49. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +221 -156
  50. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +4 -5
  51. package/dist/cli.js +2 -6
  52. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +7 -35
  53. package/dist/clients/attach/__tests__/attach-keybindings.test.js +32 -16
  54. package/dist/clients/attach/__tests__/context-message.test.js +142 -6
  55. package/dist/clients/attach/__tests__/crtr-output.test.js +29 -45
  56. package/dist/clients/attach/__tests__/diagram.test.js +1 -1
  57. package/dist/clients/attach/__tests__/file-review-focus.test.js +48 -0
  58. package/dist/clients/attach/__tests__/group-activity.test.js +266 -0
  59. package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +32 -0
  60. package/dist/clients/attach/__tests__/session-identity-refresh.test.js +32 -0
  61. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +1 -2
  62. package/dist/clients/attach/chrome/header.d.ts +10 -0
  63. package/dist/clients/attach/chrome/header.js +30 -0
  64. package/dist/clients/attach/chrome/recap.d.ts +7 -0
  65. package/dist/clients/attach/chrome/recap.js +19 -0
  66. package/dist/clients/attach/chrome/status-line.d.ts +3 -0
  67. package/dist/clients/attach/chrome/status-line.js +5 -0
  68. package/dist/clients/attach/chrome/widgets.js +11 -21
  69. package/dist/clients/attach/command.js +11 -7
  70. package/dist/clients/attach/config.d.ts +4 -0
  71. package/dist/clients/attach/config.js +3 -0
  72. package/dist/clients/attach/input/controller.d.ts +19 -0
  73. package/dist/clients/attach/input/controller.js +62 -28
  74. package/dist/clients/attach/input/titled-editor.d.ts +0 -4
  75. package/dist/clients/attach/input/titled-editor.js +2 -10
  76. package/dist/clients/attach/overlays/file-review.d.ts +9 -5
  77. package/dist/clients/attach/overlays/file-review.js +9 -70
  78. package/dist/clients/attach/overlays/help.d.ts +33 -0
  79. package/dist/clients/attach/overlays/help.js +204 -0
  80. package/dist/clients/attach/render/activity-slot.d.ts +4 -0
  81. package/dist/clients/attach/render/activity-slot.js +13 -0
  82. package/dist/clients/attach/render/chat-view.d.ts +117 -12
  83. package/dist/clients/attach/render/chat-view.js +604 -135
  84. package/dist/clients/attach/render/context-message.d.ts +2 -1
  85. package/dist/clients/attach/render/context-message.js +17 -13
  86. package/dist/clients/attach/render/crtr-output.js +1 -3
  87. package/dist/clients/attach/render/diagram.js +2 -2
  88. package/dist/clients/attach/render/edit-diff.d.ts +4 -1
  89. package/dist/clients/attach/render/edit-diff.js +7 -11
  90. package/dist/clients/attach/render/group-activity.d.ts +32 -0
  91. package/dist/clients/attach/render/group-activity.js +206 -0
  92. package/dist/clients/attach/render/group-recap.d.ts +10 -0
  93. package/dist/clients/attach/render/group-recap.js +93 -0
  94. package/dist/clients/attach/render/html-markdown.d.ts +17 -0
  95. package/dist/clients/attach/render/html-markdown.js +228 -0
  96. package/dist/clients/attach/render/measured-container.d.ts +96 -0
  97. package/dist/clients/attach/render/measured-container.js +322 -0
  98. package/dist/clients/attach/render/scroll-animation.d.ts +8 -0
  99. package/dist/clients/attach/render/scroll-animation.js +80 -0
  100. package/dist/clients/attach/render/tool-calls.js +6 -6
  101. package/dist/clients/attach/render/transcript-copy.d.ts +9 -0
  102. package/dist/clients/attach/render/transcript-copy.js +81 -0
  103. package/dist/clients/attach/render/viewport.d.ts +29 -0
  104. package/dist/clients/attach/render/viewport.js +159 -0
  105. package/dist/clients/attach/session/bindings.d.ts +10 -7
  106. package/dist/clients/attach/session/bindings.js +23 -8
  107. package/dist/clients/attach/session/connection.js +4 -5
  108. package/dist/clients/attach/session/context.d.ts +6 -4
  109. package/dist/clients/attach/session/frame.d.ts +34 -0
  110. package/dist/clients/attach/session/frame.js +176 -0
  111. package/dist/clients/attach/session/frames.d.ts +4 -1
  112. package/dist/clients/attach/session/frames.js +14 -1
  113. package/dist/clients/attach/session/identity.js +4 -3
  114. package/dist/clients/attach/session/input-wiring.d.ts +14 -4
  115. package/dist/clients/attach/session/input-wiring.js +15 -13
  116. package/dist/clients/attach/session/invariant.d.ts +9 -0
  117. package/dist/clients/attach/session/invariant.js +15 -0
  118. package/dist/clients/attach/session/keys.d.ts +10 -2
  119. package/dist/clients/attach/session/keys.js +13 -5
  120. package/dist/clients/attach/session/layout.d.ts +10 -8
  121. package/dist/clients/attach/session/layout.js +33 -34
  122. package/dist/clients/attach/session/mouse.d.ts +18 -0
  123. package/dist/clients/attach/session/mouse.js +64 -0
  124. package/dist/clients/attach/session/pane-tag.d.ts +3 -0
  125. package/dist/clients/attach/session/pane-tag.js +51 -8
  126. package/dist/clients/attach/session/reconnect.d.ts +3 -0
  127. package/dist/clients/attach/session/reconnect.js +42 -5
  128. package/dist/clients/attach/session/surface-frame.d.ts +20 -0
  129. package/dist/clients/attach/session/surface-frame.js +73 -0
  130. package/dist/clients/attach/session/surface-host.d.ts +64 -0
  131. package/dist/clients/attach/session/surface-host.js +255 -0
  132. package/dist/clients/attach/session/whip.d.ts +17 -0
  133. package/dist/clients/attach/session/whip.js +334 -0
  134. package/dist/clients/attach/slash/dispatch.d.ts +13 -1
  135. package/dist/clients/attach/slash/dispatch.js +51 -29
  136. package/dist/clients/attach/viewer.js +907 -819
  137. package/dist/clients/conversation/conversation.d.ts +65 -0
  138. package/dist/clients/conversation/conversation.js +318 -0
  139. package/dist/clients/conversation/frames.d.ts +30 -0
  140. package/dist/clients/conversation/frames.js +52 -0
  141. package/dist/clients/conversation/region.d.ts +51 -0
  142. package/dist/clients/conversation/region.js +265 -0
  143. package/dist/clients/conversation/submit.d.ts +38 -0
  144. package/dist/clients/conversation/submit.js +51 -0
  145. package/dist/clients/inbox/__tests__/inbox-controller.test.js +247 -0
  146. package/dist/clients/inbox/__tests__/mount-panel.test.js +776 -0
  147. package/dist/clients/inbox/controller.d.ts +79 -0
  148. package/dist/clients/inbox/controller.js +448 -0
  149. package/dist/clients/inbox/deck-adapter.d.ts +29 -0
  150. package/dist/clients/inbox/deck-adapter.js +62 -0
  151. package/dist/clients/inbox/layout.d.ts +8 -0
  152. package/dist/clients/inbox/layout.js +9 -0
  153. package/dist/clients/inbox/resolve.d.ts +10 -0
  154. package/dist/clients/inbox/resolve.js +34 -0
  155. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +29 -0
  156. package/dist/clients/inbox/review/__tests__/remap.test.js +196 -0
  157. package/dist/clients/inbox/review/__tests__/review-core.test.js +341 -0
  158. package/dist/clients/inbox/review/anchors.d.ts +41 -0
  159. package/dist/clients/inbox/review/anchors.js +89 -0
  160. package/dist/clients/inbox/review/columns.d.ts +22 -0
  161. package/dist/clients/inbox/review/columns.js +40 -0
  162. package/dist/clients/inbox/review/comments-client.d.ts +66 -0
  163. package/dist/clients/inbox/review/comments-client.js +98 -0
  164. package/dist/clients/inbox/review/composition.d.ts +60 -0
  165. package/dist/clients/inbox/review/composition.js +278 -0
  166. package/dist/clients/inbox/review/document-region.d.ts +120 -0
  167. package/dist/clients/inbox/review/document-region.js +902 -0
  168. package/dist/clients/inbox/review/frame.d.ts +45 -0
  169. package/dist/clients/inbox/review/frame.js +215 -0
  170. package/dist/clients/inbox/review/keys.d.ts +67 -0
  171. package/dist/clients/inbox/review/keys.js +130 -0
  172. package/dist/clients/inbox/review/launch.d.ts +10 -0
  173. package/dist/clients/inbox/review/launch.js +129 -0
  174. package/dist/clients/inbox/review/live-source.d.ts +24 -0
  175. package/dist/clients/inbox/review/live-source.js +160 -0
  176. package/dist/clients/inbox/review/nvim.d.ts +13 -0
  177. package/dist/clients/inbox/review/nvim.js +42 -0
  178. package/dist/clients/inbox/review/remap.d.ts +51 -0
  179. package/dist/clients/inbox/review/remap.js +157 -0
  180. package/dist/clients/inbox/review/review-client.d.ts +30 -0
  181. package/dist/clients/inbox/review/review-client.js +107 -0
  182. package/dist/clients/inbox/review/roundtrip.d.ts +5 -0
  183. package/dist/clients/inbox/review/roundtrip.js +36 -0
  184. package/dist/clients/inbox/review/state.d.ts +143 -0
  185. package/dist/clients/inbox/review/state.js +282 -0
  186. package/dist/clients/inbox/review-adapter.d.ts +29 -0
  187. package/dist/clients/inbox/review-adapter.js +92 -0
  188. package/dist/clients/inbox/review-visibility.d.ts +5 -0
  189. package/dist/clients/inbox/review-visibility.js +19 -0
  190. package/dist/clients/inbox/surface.d.ts +19 -0
  191. package/dist/clients/inbox/surface.js +128 -0
  192. package/dist/clients/inbox/tui/ansi.d.ts +66 -0
  193. package/dist/clients/inbox/tui/ansi.js +317 -0
  194. package/dist/clients/inbox/tui/clipboard.d.ts +2 -0
  195. package/dist/clients/inbox/tui/clipboard.js +26 -0
  196. package/dist/clients/inbox/tui/input.d.ts +7 -0
  197. package/dist/clients/inbox/tui/input.js +653 -0
  198. package/dist/clients/inbox/tui/keys.d.ts +28 -0
  199. package/dist/clients/inbox/tui/keys.js +111 -0
  200. package/dist/clients/inbox/tui/panel.d.ts +2 -0
  201. package/dist/clients/inbox/tui/panel.js +217 -0
  202. package/dist/clients/inbox/tui/render.d.ts +37 -0
  203. package/dist/clients/inbox/tui/render.js +476 -0
  204. package/dist/clients/inbox/tui/types.d.ts +57 -0
  205. package/dist/clients/inbox/tui/types.js +1 -0
  206. package/dist/clients/inbox/tui.d.ts +6 -0
  207. package/dist/clients/inbox/tui.js +74 -0
  208. package/dist/clients/surfaces/host.d.ts +66 -0
  209. package/dist/clients/surfaces/host.js +1 -0
  210. package/dist/clients/surfaces/region.d.ts +16 -0
  211. package/dist/clients/surfaces/region.js +1 -0
  212. package/dist/clients/web/__tests__/push-engine.test.js +14 -158
  213. package/dist/clients/web/dev-server.d.ts +3 -3
  214. package/dist/clients/web/dev-server.js +9 -23
  215. package/dist/clients/web/events.js +4 -6
  216. package/dist/clients/web/push-engine.d.ts +2 -66
  217. package/dist/clients/web/push-engine.js +30 -161
  218. package/dist/clients/web/push-registry.d.ts +0 -4
  219. package/dist/clients/web/push-registry.js +2 -7
  220. package/dist/clients/web/server.js +3 -35
  221. package/dist/clients/web/web-client/shared/protocol.d.ts +0 -108
  222. package/dist/clients/web/web-cmd.js +2 -2
  223. package/dist/commands/__tests__/human.test.js +27 -15
  224. package/dist/commands/api-client.js +3 -3
  225. package/dist/commands/canvas-browse.js +1 -1
  226. package/dist/commands/canvas-issue.js +1 -1
  227. package/dist/commands/canvas-use.js +1 -1
  228. package/dist/commands/human/doc.d.ts +2 -0
  229. package/dist/commands/human/doc.js +98 -0
  230. package/dist/commands/human/inbox.d.ts +2 -0
  231. package/dist/commands/human/inbox.js +101 -0
  232. package/dist/commands/human/prompts.d.ts +2 -3
  233. package/dist/commands/human/prompts.js +27 -180
  234. package/dist/commands/human/queue.d.ts +1 -5
  235. package/dist/commands/human/queue.js +54 -216
  236. package/dist/commands/human/review.d.ts +2 -0
  237. package/dist/commands/human/review.js +298 -0
  238. package/dist/commands/human/shared.d.ts +2 -69
  239. package/dist/commands/human/shared.js +1 -181
  240. package/dist/commands/human.js +15 -20
  241. package/dist/commands/memory/__tests__/lint.test.d.ts +1 -0
  242. package/dist/commands/memory/__tests__/lint.test.js +15 -0
  243. package/dist/commands/memory/delete.js +2 -2
  244. package/dist/commands/memory/lint.d.ts +1 -0
  245. package/dist/commands/memory/lint.js +21 -3
  246. package/dist/commands/memory/read.js +4 -4
  247. package/dist/commands/node.js +8 -7
  248. package/dist/commands/pkg/plugin-manage.js +143 -68
  249. package/dist/commands/surface-inspect.js +2 -2
  250. package/dist/commands/surface.js +6 -12
  251. package/dist/commands/sys/__tests__/setup-core.test.js +9 -5
  252. package/dist/commands/sys/__tests__/setup-front-door.test.js +7 -42
  253. package/dist/commands/sys/config.js +29 -3
  254. package/dist/commands/sys/feedback.js +1 -1
  255. package/dist/commands/sys/setup-core.d.ts +12 -11
  256. package/dist/commands/sys/setup-core.js +55 -46
  257. package/dist/commands/sys/setup-wizard.d.ts +4 -1
  258. package/dist/commands/sys/setup-wizard.js +50 -9
  259. package/dist/commands/sys/sync-deps.js +1 -1
  260. package/dist/commands/sys.js +4 -6
  261. package/dist/core/__tests__/broker-sdk-wiring.test.js +6 -1
  262. package/dist/core/__tests__/broker-snapshot-history.test.js +9 -1
  263. package/dist/core/__tests__/dead-node-policy-table.test.js +3 -4
  264. package/dist/core/__tests__/fixtures/fake-engine.d.ts +8 -5
  265. package/dist/core/__tests__/fixtures/fake-engine.js +28 -2
  266. package/dist/core/__tests__/full/broker-provider-retry.test.js +87 -2
  267. package/dist/core/__tests__/full/broker-whip-interrupt.test.d.ts +1 -0
  268. package/dist/core/__tests__/full/broker-whip-interrupt.test.js +39 -0
  269. package/dist/core/__tests__/full/detach-focus.test.js +1 -1
  270. package/dist/core/__tests__/human-deliver-e2e.test.js +64 -64
  271. package/dist/core/__tests__/human-deliver.test.js +71 -345
  272. package/dist/core/__tests__/inline-memory-refs.test.js +2 -12
  273. package/dist/core/__tests__/memory-resolver-precedence.test.js +12 -15
  274. package/dist/core/__tests__/migration.test.js +10 -0
  275. package/dist/core/__tests__/model-pin-durability.test.js +14 -0
  276. package/dist/core/__tests__/phase4-review-migration.test.d.ts +1 -0
  277. package/dist/core/__tests__/phase4-review-migration.test.js +100 -0
  278. package/dist/core/__tests__/phase4-review-store.test.d.ts +1 -0
  279. package/dist/core/__tests__/phase4-review-store.test.js +143 -0
  280. package/dist/core/__tests__/remote-canvas-target.test.js +2 -2
  281. package/dist/core/__tests__/revive.test.js +22 -53
  282. package/dist/core/__tests__/session-cycles.test.js +48 -18
  283. package/dist/core/__tests__/spawn-no-kickoff.test.js +8 -12
  284. package/dist/core/__tests__/stop-guard.test.js +16 -1
  285. package/dist/core/__tests__/tmux-surface.test.js +21 -25
  286. package/dist/core/asset-root.d.ts +7 -0
  287. package/dist/core/asset-root.js +18 -0
  288. package/dist/core/broker-client/client.d.ts +0 -7
  289. package/dist/core/broker-client/client.js +4 -10
  290. package/dist/core/broker-client/transport-relay.d.ts +3 -4
  291. package/dist/core/broker-client/transport-relay.js +3 -4
  292. package/dist/core/canvas/__tests__/attention.test.js +1 -1
  293. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
  294. package/dist/core/canvas/__tests__/remote-transport.test.d.ts +1 -0
  295. package/dist/core/{view/__tests__/transport-remote.test.js → canvas/__tests__/remote-transport.test.js} +2 -2
  296. package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
  297. package/dist/core/canvas/attention.js +4 -4
  298. package/dist/core/canvas/canvas.d.ts +6 -11
  299. package/dist/core/canvas/canvas.js +11 -33
  300. package/dist/core/canvas/db.js +207 -38
  301. package/dist/core/canvas/extensions.d.ts +1 -1
  302. package/dist/core/canvas/extensions.js +8 -1
  303. package/dist/core/canvas/index.d.ts +0 -1
  304. package/dist/core/canvas/index.js +0 -1
  305. package/dist/core/canvas/nav-model.d.ts +1 -1
  306. package/dist/core/canvas/nav-model.js +1 -1
  307. package/dist/core/canvas/paths.d.ts +5 -0
  308. package/dist/core/canvas/paths.js +16 -0
  309. package/dist/core/canvas/remote-canvas-source.js +2 -2
  310. package/dist/core/canvas/remote-transport.d.ts +7 -0
  311. package/dist/core/{view/transport-remote.js → canvas/remote-transport.js} +3 -4
  312. package/dist/core/canvas/source.js +1 -1
  313. package/dist/core/canvas/status-glyph.js +4 -12
  314. package/dist/core/canvas/types.d.ts +10 -35
  315. package/dist/core/clipboard-text.d.ts +8 -0
  316. package/dist/core/clipboard-text.js +18 -0
  317. package/dist/core/command-manifests/registry.d.ts +1 -3
  318. package/dist/core/command-plugins/bundle.d.ts +29 -0
  319. package/dist/core/command-plugins/bundle.js +198 -0
  320. package/dist/core/command-plugins/discovery.d.ts +0 -8
  321. package/dist/core/command-plugins/discovery.js +2 -39
  322. package/dist/core/command-plugins/transport/http-fetch.d.ts +4 -30
  323. package/dist/core/command-plugins/transport/http-fetch.js +17 -95
  324. package/dist/core/command.d.ts +1 -13
  325. package/dist/core/command.js +1 -16
  326. package/dist/core/config.d.ts +4 -0
  327. package/dist/core/config.js +28 -3
  328. package/dist/core/document-lines.d.ts +4 -0
  329. package/dist/core/document-lines.js +6 -0
  330. package/dist/core/feed/feed.d.ts +2 -0
  331. package/dist/core/feed/feed.js +11 -7
  332. package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +1 -0
  333. package/dist/core/human/__tests__/inbox-cancel-worker.js +7 -0
  334. package/dist/core/human/__tests__/inbox-claim-worker.d.ts +1 -0
  335. package/dist/core/human/__tests__/inbox-claim-worker.js +17 -0
  336. package/dist/core/human/__tests__/inbox-core.test.d.ts +1 -0
  337. package/dist/core/human/__tests__/inbox-core.test.js +144 -0
  338. package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +1 -0
  339. package/dist/core/human/__tests__/inbox-stale-claim-worker.js +8 -0
  340. package/dist/core/human/__tests__/visible-paths.test.d.ts +1 -0
  341. package/dist/{clients/attach → core/human}/__tests__/visible-paths.test.js +9 -0
  342. package/dist/core/human/claim.d.ts +23 -0
  343. package/dist/core/human/claim.js +67 -0
  344. package/dist/core/human/convention.d.ts +30 -0
  345. package/dist/core/human/convention.js +202 -0
  346. package/dist/core/human/deck-factories.d.ts +8 -0
  347. package/dist/core/human/deck-factories.js +15 -0
  348. package/dist/core/human/deck-schema.d.ts +70 -0
  349. package/dist/core/human/deck-schema.js +92 -0
  350. package/dist/core/human/root.d.ts +7 -0
  351. package/dist/core/human/root.js +37 -0
  352. package/dist/core/human/scan.d.ts +3 -0
  353. package/dist/core/human/scan.js +76 -0
  354. package/dist/core/human/summary.d.ts +8 -0
  355. package/dist/core/human/summary.js +44 -0
  356. package/dist/core/human/tickets.d.ts +49 -0
  357. package/dist/core/human/tickets.js +190 -0
  358. package/dist/core/human/types.d.ts +136 -0
  359. package/dist/core/human/types.js +5 -0
  360. package/dist/{clients/attach → core/human}/visible-paths.d.ts +1 -1
  361. package/dist/{clients/attach → core/human}/visible-paths.js +3 -2
  362. package/dist/core/inspector/chrome.d.ts +6 -0
  363. package/dist/core/inspector/chrome.js +14 -0
  364. package/dist/core/inspector/contract.d.ts +105 -0
  365. package/dist/core/inspector/contract.js +1 -0
  366. package/dist/core/inspector/core.d.ts +4 -5
  367. package/dist/core/inspector/core.js +3 -5
  368. package/dist/core/inspector/host.d.ts +46 -0
  369. package/dist/core/{tui → inspector}/host.js +42 -208
  370. package/dist/core/inspector/text.d.ts +2 -2
  371. package/dist/core/inspector/transport.d.ts +6 -0
  372. package/dist/core/inspector/transport.js +36 -0
  373. package/dist/core/inspector/tui.d.ts +2 -2
  374. package/dist/core/inspector/tui.js +15 -15
  375. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +11 -11
  376. package/dist/core/keybindings/__tests__/resolve.test.js +10 -19
  377. package/dist/core/keybindings/attach-control.d.ts +9 -3
  378. package/dist/core/keybindings/attach-control.js +3 -1
  379. package/dist/core/keybindings/catalog.d.ts +6 -5
  380. package/dist/core/keybindings/catalog.js +61 -133
  381. package/dist/core/keybindings/inbox.d.ts +5 -6
  382. package/dist/core/keybindings/inbox.js +9 -10
  383. package/dist/core/keybindings/index.d.ts +3 -3
  384. package/dist/core/keybindings/index.js +3 -3
  385. package/dist/core/keybindings/persistence.d.ts +5 -1
  386. package/dist/core/keybindings/persistence.js +24 -6
  387. package/dist/core/keybindings/resolve.d.ts +6 -0
  388. package/dist/core/keybindings/resolve.js +10 -3
  389. package/dist/core/memory/inline-ref-grammar.js +2 -3
  390. package/dist/core/memory-resolver.d.ts +27 -29
  391. package/dist/core/memory-resolver.js +45 -39
  392. package/dist/core/model-routes.d.ts +33 -0
  393. package/dist/core/model-routes.js +42 -3
  394. package/dist/core/preview-registry.js +17 -55
  395. package/dist/core/profiles/select.js +3 -3
  396. package/dist/core/{view/remote-canvas-target.d.ts → remote-canvas-target.d.ts} +2 -2
  397. package/dist/core/{view/remote-canvas-target.js → remote-canvas-target.js} +4 -4
  398. package/dist/core/review/__tests__/capture-origin.test.d.ts +1 -0
  399. package/dist/core/review/__tests__/capture-origin.test.js +139 -0
  400. package/dist/core/review/__tests__/comments.test.d.ts +1 -0
  401. package/dist/core/review/__tests__/comments.test.js +98 -0
  402. package/dist/core/review/__tests__/project.test.d.ts +1 -0
  403. package/dist/core/review/__tests__/project.test.js +71 -0
  404. package/dist/core/review/__tests__/remap.test.d.ts +1 -0
  405. package/dist/core/review/__tests__/remap.test.js +159 -0
  406. package/dist/core/review/__tests__/stage-identity.test.d.ts +1 -0
  407. package/dist/core/review/__tests__/stage-identity.test.js +140 -0
  408. package/dist/core/review/birth.d.ts +7 -0
  409. package/dist/core/review/birth.js +23 -0
  410. package/dist/core/review/comments.d.ts +69 -0
  411. package/dist/core/review/comments.js +295 -0
  412. package/dist/core/review/companion.d.ts +35 -0
  413. package/dist/core/review/companion.js +205 -0
  414. package/dist/core/review/document.d.ts +27 -0
  415. package/dist/core/review/document.js +138 -0
  416. package/dist/core/review/project.d.ts +13 -0
  417. package/dist/core/review/project.js +58 -0
  418. package/dist/core/review/realize.d.ts +19 -0
  419. package/dist/core/review/realize.js +217 -0
  420. package/dist/core/review/remap.d.ts +24 -0
  421. package/dist/core/review/remap.js +156 -0
  422. package/dist/core/review/signal.d.ts +5 -0
  423. package/dist/core/review/signal.js +31 -0
  424. package/dist/core/review/stage.d.ts +26 -0
  425. package/dist/core/review/stage.js +184 -0
  426. package/dist/core/review/store.d.ts +46 -0
  427. package/dist/core/review/store.js +163 -0
  428. package/dist/core/review/ticket-filter.d.ts +17 -0
  429. package/dist/core/review/ticket-filter.js +32 -0
  430. package/dist/core/review/types.d.ts +130 -0
  431. package/dist/core/review/types.js +23 -0
  432. package/dist/core/runtime/__tests__/session-visibility.test.d.ts +1 -0
  433. package/dist/core/runtime/__tests__/session-visibility.test.js +119 -0
  434. package/dist/core/runtime/bearings.d.ts +5 -17
  435. package/dist/core/runtime/bearings.js +88 -71
  436. package/dist/core/runtime/broker-protocol.d.ts +31 -8
  437. package/dist/core/runtime/broker.d.ts +15 -1
  438. package/dist/core/runtime/broker.js +573 -141
  439. package/dist/core/runtime/canvas-extensions.d.ts +4 -5
  440. package/dist/core/runtime/canvas-extensions.js +5 -5
  441. package/dist/core/runtime/front-door.js +4 -4
  442. package/dist/core/runtime/headless-pi.d.ts +24 -0
  443. package/dist/core/runtime/headless-pi.js +152 -0
  444. package/dist/core/runtime/kickoff.d.ts +1 -5
  445. package/dist/core/runtime/kickoff.js +1 -5
  446. package/dist/core/runtime/model-registry.d.ts +3 -0
  447. package/dist/core/runtime/model-registry.js +13 -0
  448. package/dist/core/runtime/naming-persist.d.ts +4 -0
  449. package/dist/core/runtime/naming-persist.js +27 -1
  450. package/dist/core/runtime/naming.d.ts +17 -12
  451. package/dist/core/runtime/naming.js +91 -140
  452. package/dist/core/runtime/node-read.js +19 -10
  453. package/dist/core/runtime/nodes.d.ts +9 -14
  454. package/dist/core/runtime/nodes.js +3 -53
  455. package/dist/core/runtime/package-health.d.ts +6 -21
  456. package/dist/core/runtime/package-health.js +12 -123
  457. package/dist/core/runtime/placement-tmux.d.ts +2 -1
  458. package/dist/core/runtime/placement-tmux.js +6 -4
  459. package/dist/core/runtime/placement.d.ts +1 -0
  460. package/dist/core/runtime/placement.js +4 -8
  461. package/dist/core/runtime/promote.js +3 -0
  462. package/dist/core/runtime/recap.d.ts +2 -7
  463. package/dist/core/runtime/recap.js +35 -69
  464. package/dist/core/runtime/revive.js +34 -77
  465. package/dist/core/runtime/session-cycles.d.ts +4 -0
  466. package/dist/core/runtime/session-cycles.js +14 -1
  467. package/dist/core/runtime/session-visibility.d.ts +37 -0
  468. package/dist/core/runtime/session-visibility.js +83 -0
  469. package/dist/core/runtime/spawn.js +10 -22
  470. package/dist/core/runtime/stop-guard.d.ts +1 -1
  471. package/dist/core/runtime/stop-guard.js +18 -13
  472. package/dist/core/runtime/surface-bg.js +1 -1
  473. package/dist/core/runtime/tmux-chrome.d.ts +1 -1
  474. package/dist/core/runtime/tmux-chrome.js +1 -1
  475. package/dist/core/runtime/tmux.d.ts +35 -7
  476. package/dist/core/runtime/tmux.js +439 -62
  477. package/dist/core/runtime/tool-group-summary.d.ts +19 -0
  478. package/dist/core/runtime/tool-group-summary.js +88 -0
  479. package/dist/core/scope.d.ts +2 -7
  480. package/dist/core/scope.js +9 -35
  481. package/dist/core/substrate/schema.d.ts +2 -2
  482. package/dist/core/termrender/code-doc.d.ts +12 -0
  483. package/dist/core/termrender/code-doc.js +92 -0
  484. package/dist/core/termrender/display.d.ts +12 -0
  485. package/dist/core/termrender/display.js +19 -0
  486. package/dist/core/termrender/termrender.d.ts +73 -0
  487. package/dist/core/termrender/termrender.js +795 -0
  488. package/dist/core/termrender/version.d.ts +1 -0
  489. package/dist/core/termrender/version.js +1 -0
  490. package/dist/core/tui/terminal.js +1 -2
  491. package/dist/core/user-settings.d.ts +71 -3
  492. package/dist/core/user-settings.js +83 -1
  493. package/dist/daemon/api/__tests__/inbox.test.js +44 -133
  494. package/dist/daemon/api/handlers/human.d.ts +0 -10
  495. package/dist/daemon/api/handlers/human.js +104 -702
  496. package/dist/daemon/api/handlers/inbox.js +113 -142
  497. package/dist/daemon/api/handlers/review-comments.d.ts +2 -0
  498. package/dist/daemon/api/handlers/review-comments.js +500 -0
  499. package/dist/daemon/api/handlers/reviews.d.ts +2 -0
  500. package/dist/daemon/api/handlers/reviews.js +287 -0
  501. package/dist/daemon/api/map.d.ts +22 -7
  502. package/dist/daemon/api/map.js +159 -11
  503. package/dist/daemon/api/server.js +4 -0
  504. package/dist/daemon/cron-run.js +6 -9
  505. package/dist/daemon/crtrd.js +17 -33
  506. package/dist/daemon/fleet.d.ts +1 -8
  507. package/dist/daemon/fleet.js +4 -30
  508. package/dist/daemon/human/finish.d.ts +14 -0
  509. package/dist/daemon/human/finish.js +115 -0
  510. package/dist/daemon/human/sweep.d.ts +6 -0
  511. package/dist/daemon/human/sweep.js +49 -0
  512. package/dist/daemon/messaging/node-message.d.ts +18 -0
  513. package/dist/daemon/messaging/node-message.js +70 -0
  514. package/dist/daemon/review/comment-notify.d.ts +26 -0
  515. package/dist/daemon/review/comment-notify.js +107 -0
  516. package/dist/daemon/review/deliver.d.ts +7 -0
  517. package/dist/daemon/review/deliver.js +56 -0
  518. package/dist/daemon/review/finish.d.ts +22 -0
  519. package/dist/daemon/review/finish.js +254 -0
  520. package/dist/daemon/review/sweep.d.ts +11 -0
  521. package/dist/daemon/review/sweep.js +120 -0
  522. package/dist/index.d.ts +2 -0
  523. package/dist/index.js +2 -2
  524. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +42 -64
  525. package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +1 -0
  526. package/dist/pi-extensions/__tests__/canvas-recap.test.js +159 -0
  527. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +16 -38
  528. package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +1 -0
  529. package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +63 -0
  530. package/dist/pi-extensions/canvas-context-intro.d.ts +8 -11
  531. package/dist/pi-extensions/canvas-context-intro.js +50 -104
  532. package/dist/pi-extensions/canvas-recap.d.ts +15 -2
  533. package/dist/pi-extensions/canvas-recap.js +192 -69
  534. package/dist/pi-extensions/canvas-review-boundary.d.ts +59 -0
  535. package/dist/pi-extensions/canvas-review-boundary.js +81 -0
  536. package/dist/pi-extensions/canvas-stophook.d.ts +3 -3
  537. package/dist/pi-extensions/canvas-stophook.js +78 -128
  538. package/dist/pi-extensions/canvas-structured-output.js +52 -8
  539. package/dist/shared/generated-context.d.ts +29 -4
  540. package/dist/shared/generated-context.js +122 -7
  541. package/dist/shared/tool-groups.d.ts +23 -0
  542. package/dist/shared/tool-groups.js +60 -0
  543. package/dist/shared/working-activity.d.ts +8 -0
  544. package/dist/shared/working-activity.js +26 -0
  545. package/dist/types.d.ts +36 -2
  546. package/dist/types.js +51 -0
  547. package/dist/web-client/assets/index-CCPaLeW7.css +2 -0
  548. package/dist/web-client/assets/index-kyOWsnZK.js +86 -0
  549. package/dist/web-client/index.html +2 -2
  550. package/dist/web-client/sw.js +1 -1
  551. package/docs/compat/hearth-crtr-v4.md +2 -2
  552. package/docs/compat/hearth-crtr-v5.md +4 -2
  553. package/docs/public-api.md +3 -3
  554. package/package.json +21 -14
  555. package/runtime.lock.json +4661 -1453
  556. package/scripts/postinstall.mjs +15 -2
  557. package/dist/builtin-pi-packages/pi-mode-switch/README.md +0 -36
  558. package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +0 -36
  559. package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +0 -449
  560. package/dist/builtin-pi-packages/pi-mode-switch/package.json +0 -14
  561. package/dist/builtin-pi-packages/pi-mode-switch/tsconfig.json +0 -9
  562. package/dist/builtin-views/_lib/states.mjs +0 -161
  563. package/dist/builtin-views/canvas/core.mjs +0 -657
  564. package/dist/builtin-views/canvas/text.mjs +0 -58
  565. package/dist/builtin-views/canvas/tui.mjs +0 -168
  566. package/dist/builtin-views/canvas/web.jsx +0 -121
  567. package/dist/builtin-views/chat/core.mjs +0 -684
  568. package/dist/builtin-views/chat/text.mjs +0 -101
  569. package/dist/builtin-views/chat/tui.mjs +0 -360
  570. package/dist/builtin-views/chat/web.jsx +0 -362
  571. package/dist/builtin-views/git-pr/core.mjs +0 -673
  572. package/dist/builtin-views/git-pr/text.mjs +0 -84
  573. package/dist/builtin-views/git-pr/tui.mjs +0 -301
  574. package/dist/builtin-views/git-pr/web.jsx +0 -216
  575. package/dist/builtin-views/inbox/_lib/render.mjs +0 -175
  576. package/dist/builtin-views/inbox/core.mjs +0 -1273
  577. package/dist/builtin-views/inbox/text.mjs +0 -73
  578. package/dist/builtin-views/inbox/tui.mjs +0 -314
  579. package/dist/builtin-views/inbox/web.jsx +0 -188
  580. package/dist/builtin-views/linkedin/core.mjs +0 -906
  581. package/dist/builtin-views/linkedin/text.mjs +0 -69
  582. package/dist/builtin-views/linkedin/tui.mjs +0 -413
  583. package/dist/builtin-views/linkedin/web.jsx +0 -206
  584. package/dist/builtin-views/prompt-review/core.mjs +0 -735
  585. package/dist/builtin-views/prompt-review/text.mjs +0 -15
  586. package/dist/builtin-views/prompt-review/tui.mjs +0 -196
  587. package/dist/builtin-views/prompt-review/web.jsx +0 -484
  588. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.js +0 -50
  589. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.ts +0 -53
  590. package/dist/builtin-views/workspace-sidebar/core.mjs +0 -670
  591. package/dist/builtin-views/workspace-sidebar/text.mjs +0 -53
  592. package/dist/builtin-views/workspace-sidebar/tui.mjs +0 -141
  593. package/dist/builtin-views/workspace-sidebar/web.jsx +0 -109
  594. package/dist/clients/attach/session/mode.d.ts +0 -25
  595. package/dist/clients/attach/session/mode.js +0 -97
  596. package/dist/commands/sys/promptstudio.d.ts +0 -2
  597. package/dist/commands/sys/promptstudio.js +0 -65
  598. package/dist/commands/view-cycle.d.ts +0 -2
  599. package/dist/commands/view-cycle.js +0 -130
  600. package/dist/commands/view-list.d.ts +0 -2
  601. package/dist/commands/view-list.js +0 -66
  602. package/dist/commands/view-new.d.ts +0 -2
  603. package/dist/commands/view-new.js +0 -74
  604. package/dist/commands/view-pick.d.ts +0 -6
  605. package/dist/commands/view-pick.js +0 -129
  606. package/dist/commands/view-run.d.ts +0 -2
  607. package/dist/commands/view-run.js +0 -214
  608. package/dist/commands/view.d.ts +0 -2
  609. package/dist/commands/view.js +0 -31
  610. package/dist/commands/workspace.d.ts +0 -2
  611. package/dist/commands/workspace.js +0 -165
  612. package/dist/core/__tests__/chat-view-reconnect.test.js +0 -105
  613. package/dist/core/__tests__/full/consult-startup-failure.test.js +0 -124
  614. package/dist/core/canvas/__tests__/human-work-outbox.test.js +0 -123
  615. package/dist/core/canvas/human-work-outbox.d.ts +0 -73
  616. package/dist/core/canvas/human-work-outbox.js +0 -261
  617. package/dist/core/command-plugins/store.d.ts +0 -16
  618. package/dist/core/command-plugins/store.js +0 -64
  619. package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +0 -40
  620. package/dist/core/runtime/fault-recovery-nudge.d.ts +0 -3
  621. package/dist/core/runtime/fault-recovery-nudge.js +0 -3
  622. package/dist/core/tui/__tests__/host-keybindings.test.js +0 -113
  623. package/dist/core/tui/host.d.ts +0 -66
  624. package/dist/core/view/__tests__/transport-cache.test.js +0 -62
  625. package/dist/core/view/bridge.d.ts +0 -10
  626. package/dist/core/view/bridge.js +0 -31
  627. package/dist/core/view/chrome.d.ts +0 -9
  628. package/dist/core/view/chrome.js +0 -22
  629. package/dist/core/view/contract.d.ts +0 -205
  630. package/dist/core/view/contract.js +0 -23
  631. package/dist/core/view/loader.d.ts +0 -31
  632. package/dist/core/view/loader.js +0 -188
  633. package/dist/core/view/stream-local.d.ts +0 -3
  634. package/dist/core/view/stream-local.js +0 -231
  635. package/dist/core/view/transport-cache.d.ts +0 -8
  636. package/dist/core/view/transport-cache.js +0 -38
  637. package/dist/core/view/transport-local.d.ts +0 -7
  638. package/dist/core/view/transport-local.js +0 -83
  639. package/dist/core/view/transport-remote.d.ts +0 -2
  640. package/dist/core/view/transport.d.ts +0 -10
  641. package/dist/core/view/transport.js +0 -15
  642. package/dist/pi-extensions/naming-tool.d.ts +0 -24
  643. package/dist/pi-extensions/naming-tool.js +0 -67
  644. package/dist/prompts/view.d.ts +0 -7
  645. package/dist/prompts/view.js +0 -172
  646. package/dist/web/ViewChrome.d.ts +0 -7
  647. package/dist/web/ViewChrome.js +0 -28
  648. package/dist/web/ViewPane.d.ts +0 -39
  649. package/dist/web/ViewPane.js +0 -48
  650. package/dist/web/index.d.ts +0 -8
  651. package/dist/web/index.js +0 -22
  652. package/dist/web/runtime.d.ts +0 -39
  653. package/dist/web/runtime.js +0 -232
  654. package/dist/web/states.d.ts +0 -24
  655. package/dist/web/states.js +0 -24
  656. package/dist/web/transport-http.d.ts +0 -5
  657. package/dist/web/transport-http.js +0 -34
  658. package/dist/web/transport-stream.d.ts +0 -3
  659. package/dist/web/transport-stream.js +0 -204
  660. package/dist/web-client/assets/index-U_NZ66VE.js +0 -79
  661. package/dist/web-client/assets/index-aaeu4adv.css +0 -2
  662. /package/dist/{builtin-views/workspace-sidebar/__tests__/core.test.d.ts → clients/attach/__tests__/file-review-focus.test.d.ts} +0 -0
  663. /package/dist/clients/attach/__tests__/{visible-paths.test.d.ts → group-activity.test.d.ts} +0 -0
  664. /package/dist/{core/__tests__/chat-view-reconnect.test.d.ts → clients/attach/__tests__/input-controller-extension-command.test.d.ts} +0 -0
  665. /package/dist/{core/__tests__/full/consult-startup-failure.test.d.ts → clients/attach/__tests__/session-identity-refresh.test.d.ts} +0 -0
  666. /package/dist/{core/canvas/__tests__/human-work-outbox.test.d.ts → clients/inbox/__tests__/inbox-controller.test.d.ts} +0 -0
  667. /package/dist/{core/keybindings/__tests__/bespoke-consumers.test.d.ts → clients/inbox/__tests__/mount-panel.test.d.ts} +0 -0
  668. /package/dist/{core/tui/__tests__/host-keybindings.test.d.ts → clients/inbox/review/__tests__/editor-roundtrip.test.d.ts} +0 -0
  669. /package/dist/{core/view/__tests__/transport-cache.test.d.ts → clients/inbox/review/__tests__/remap.test.d.ts} +0 -0
  670. /package/dist/{core/view/__tests__/transport-remote.test.d.ts → clients/inbox/review/__tests__/review-core.test.d.ts} +0 -0
@@ -1,32 +1,15 @@
1
- // host.ts — the alt-screen loop that hosts a dual-target ViewCore + TuiPresenter
2
- // (src/core/view/contract.ts).
1
+ // host.ts — the native Inspector's alt-screen runtime.
3
2
  //
4
- // Models browse/app.ts's loop, generalized: the host owns the screen, input,
5
- // chrome, and the single-flight async lane. State is immutable (the core's
6
- // intents update it via `ctx.set`); presenters are pure reads. A keystroke maps
7
- // through the TuiPresenter's keymap to a named intent the host dispatches.
8
- //
9
- // • TTY gate: non-interactive stdin OR stdout → text.dump(state) (or a synthesized
10
- // one-line dump) to stdout, exit 0.
11
- // • setup/restore terminal (alt-screen, raw); restore exactly once, however we
12
- // leave (quit / Ctrl-C / crash / process exit).
13
- // • single-flight async lane: at most ONE async intent in flight; a busy
14
- // indicator shows in the chrome; keystrokes that arrive mid-flight are
15
- // DROPPED (this paces fetches/sends).
16
- // • chrome: title row + separator on top; an error banner + a footer (status
17
- // left, keymap hints right) on the bottom; the presenter gets the content Rect.
18
- // • loop: parseKeypress → keymap → dispatch(intent) → render; refreshMs polling;
19
- // resize → render (NOT refresh) so a resize mid-fetch repaints from current
20
- // state without re-entering the in-flight intent.
21
- import { setupTerminal, restoreTerminal, getTerminalSize, parseKeypress, } from './terminal.js';
22
- import { createDraw, detectColorCaps } from './draw.js';
23
- import { initialChrome, deriveState } from '../view/chrome.js';
24
- import { createLocalTransport } from '../view/transport-local.js';
3
+ // The host owns the terminal, chrome, subprocess transport, and single-flight
4
+ // intent lane. Inspector state is immutable; keybindings dispatch named intents.
5
+ import { setupTerminal, restoreTerminal, getTerminalSize, parseKeypress, } from '../tui/terminal.js';
6
+ import { createDraw, detectColorCaps } from '../tui/draw.js';
7
+ import { initialChrome, deriveState } from './chrome.js';
8
+ import { createInspectorTransport } from './transport.js';
25
9
  import { formatBinding, matchesTerminalInput, resolveUserKeybindings, } from '../keybindings/index.js';
26
10
  // Numeric SGR codes only (a color NAME emits a broken CSI — see draw.ts guard).
27
11
  const FG = { cyan: '36', green: '32', yellow: '33', red: '31', grey: '90' };
28
- /** The persistent state signal: word + glyph + hue, derived from host signals so
29
- * every view gets it for free. Each pairs hue with a glyph/word — mono-safe. */
12
+ /** The persistent state signal. Each hue is paired with a glyph and word. */
30
13
  const CHIP = {
31
14
  working: { word: 'working', glyph: '⟳', fg: FG.cyan },
32
15
  blocked: { word: 'blocked', glyph: '⚠', fg: FG.red },
@@ -117,7 +100,7 @@ function keymapSpans(hints, avail) {
117
100
  * Three zones: title row (state rail + title/subtitle + state chip + liveness),
118
101
  * a hairline, and a footer (status left, keymap right) with a severity banner
119
102
  * on the row above it when set. */
120
- function drawChrome(draw, size, manifest, c, now = Date.now()) {
103
+ function drawInspectorChrome(draw, size, manifest, c, now = Date.now()) {
121
104
  const { cols, rows } = size;
122
105
  const st = deriveState(c);
123
106
  // Chip selection. An explicit interaction mode (compose/react) WINS the chip
@@ -179,7 +162,7 @@ function drawChrome(draw, size, manifest, c, now = Date.now()) {
179
162
  const height = Math.max(1, rows - top - bottomRows);
180
163
  return { row: top, col: 0, width: cols, height };
181
164
  }
182
- export { drawChrome };
165
+ export { drawInspectorChrome };
183
166
  /** True when some effective binding claims the `ctrl+h` gesture — used to decide
184
167
  * whether the ambiguous 0x08 byte is a Ctrl-H remap or a plain Backspace. */
185
168
  function bindingSetClaimsCtrlH(bindings) {
@@ -196,11 +179,8 @@ function summarizeKeybindingDiagnostics(diags) {
196
179
  const extra = diags.length > 1 ? ` (+${diags.length - 1} more)` : '';
197
180
  return `keybindings: ${diags[0].message}${extra}`;
198
181
  }
199
- /** Extend the shared legacy parser with the terminal gestures the catalog can
200
- * express. The raw shape goes only to the catalog matcher; custom literals keep
201
- * their established Key-based matching. When `bindings` is supplied the ambiguous
202
- * 0x08 byte resolves to Ctrl-H only if an effective binding claims it. */
203
- export function parseViewKeypress(data, bindings) {
182
+ /** Decode terminal bytes into the shared keybinding catalog's input shape. */
183
+ export function parseInspectorInput(data, bindings) {
204
184
  const parsed = parseKeypress(data);
205
185
  const raw = { ...parsed.key, input: parsed.input };
206
186
  const sequence = data.toString('utf8');
@@ -233,24 +213,14 @@ export function parseViewKeypress(data, bindings) {
233
213
  raw[modifiedHomeEnd[2] === 'H' ? 'home' : 'end'] = true;
234
214
  setModifiers(modifiedHomeEnd[1]);
235
215
  }
236
- // Alt+<char> gestures (ESC-prefixed printables/control letters) that the
237
- // legacy parser leaves as a raw two-byte `input`. Only the raw catalog shape
238
- // gains the alt modifier; `parsed` keeps its Key-based shape so custom literals
239
- // still match exactly as before (Alt+<letter> must NOT match a bare literal).
240
- // Special keys the legacy parser already decoded (Alt+Backspace, arrows, …)
241
- // return `input: ''`, so `parsed.input === sequence` skips them here.
216
+ // Alt+<char> gestures arrive as an escape-prefixed byte pair.
242
217
  if (sequence.length === 2 && sequence.startsWith('\x1b') && parsed.input === sequence) {
243
218
  const code = sequence.charCodeAt(1);
244
219
  raw.input = code < 32 ? String.fromCharCode(code + 64).toLowerCase() : sequence[1];
245
220
  raw.meta = true;
246
221
  raw.ctrl = code < 32;
247
222
  }
248
- // Backspace family. \x7f, \b, and their Alt-prefixed forms all mean "delete one
249
- // char" and canonicalize to plain backspace (there is no alt+backspace catalog
250
- // action, so Alt+Backspace deletes exactly like Backspace, as before). The 0x08
251
- // byte is ALSO Ctrl-H: honor a Ctrl-H remap only when an effective binding
252
- // actually claims `ctrl+h`, otherwise it stays backspace so default deletion
253
- // keeps working on ^H-erase terminals.
223
+ // The 0x08 byte is either Backspace or an explicit Ctrl-H remap.
254
224
  if (raw.backspace) {
255
225
  const ctrlHByte = sequence === '\b' || sequence === '\x1b\b';
256
226
  if (ctrlHByte && bindings && bindingSetClaimsCtrlH(bindings)) {
@@ -266,126 +236,46 @@ export function parseViewKeypress(data, bindings) {
266
236
  raw.backspace = true;
267
237
  }
268
238
  }
269
- return { ...parsed, raw };
270
- }
271
- function keyTokens(input, key) {
272
- const t = [];
273
- if (key.upArrow)
274
- t.push('up');
275
- if (key.downArrow)
276
- t.push('down');
277
- if (key.leftArrow)
278
- t.push('left');
279
- if (key.rightArrow)
280
- t.push('right');
281
- if (key.return)
282
- t.push('return', 'enter');
283
- if (key.escape)
284
- t.push('escape', 'esc');
285
- if (key.tab)
286
- t.push('tab');
287
- if (key.shiftTab)
288
- t.push('shifttab');
289
- if (key.backspace)
290
- t.push('backspace');
291
- if (key.ctrl && input)
292
- t.push(`ctrl+${input}`, `c-${input}`);
293
- if (!key.ctrl && !key.escape && input.length === 1)
294
- t.push(input);
295
- if (input === ' ')
296
- t.push('space');
297
- return t;
298
- }
299
- /** A printable text edit (for the capture line-editor): a non-empty input with
300
- * no special-key flag set. */
301
- function isPrintable(input, key) {
302
- if (key.ctrl || key.meta || key.escape || key.return || key.tab || key.backspace
303
- || key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.shiftTab)
304
- return false;
305
- return input.length >= 1;
306
- }
307
- /** Strip control chars so a paste can't smuggle ANSI into the draft buffer. */
308
- function sanitizePrintable(s) {
309
- return Array.from(s).filter((ch) => ch.charCodeAt(0) >= 32).join('');
239
+ return raw;
310
240
  }
311
- /** Resolve footer hints for the CURRENT state: only bindings whose `when(state)`
312
- * passes contribute, so mode-gated affordances (compose/react send/cancel/pick)
313
- * appear exactly while active. Catalog bindings render the effective key label
314
- * (omitted entirely when disabled); custom-view literal hints stay verbatim. */
315
- export function resolveViewKeyHints(keymap, bindings, state) {
241
+ /** Resolve footer hints from the Inspector's current mode and user bindings. */
242
+ export function resolveInspectorKeyHints(keymap, bindings, state) {
316
243
  const hints = [];
317
244
  for (const binding of keymap) {
318
- if (!binding.hint)
245
+ if (!binding.hint || (binding.when && !binding.when(state)))
319
246
  continue;
320
- if (binding.when && !binding.when(state))
247
+ if (bindings.gestures(binding.bindingId).length === 0)
321
248
  continue;
322
- if ('bindingId' in binding) {
323
- if (bindings.gestures(binding.bindingId).length === 0)
324
- continue; // disabled: no hint
325
- hints.push({ keys: formatBinding(bindings, binding.bindingId), label: binding.hint.label });
326
- }
327
- else if ('capture' in binding) {
328
- hints.push('keys' in binding.hint ? binding.hint : { keys: 'type', label: binding.hint.label });
329
- }
330
- else {
331
- hints.push(binding.hint);
332
- }
249
+ hints.push({ keys: formatBinding(bindings, binding.bindingId), label: binding.hint.label });
333
250
  }
334
251
  return hints;
335
252
  }
336
- /** The first non-capture binding whose key matches and whose `when` (if any)
337
- * passes — catalog IDs use the terminal matcher; custom literals retain their
338
- * presenter-authored matching. */
339
- export function matchViewBinding(keymap, bindings, input, key, state, raw = { ...key, input }) {
340
- const tokens = keyTokens(input, key);
253
+ /** Match the first active Inspector action claimed by the input. */
254
+ export function matchInspectorBinding(keymap, bindings, state, raw) {
341
255
  for (const binding of keymap) {
342
- if ('capture' in binding)
343
- continue;
344
256
  if (binding.when && !binding.when(state))
345
257
  continue;
346
- const matches = 'bindingId' in binding
347
- ? matchesTerminalInput(bindings, binding.bindingId, raw)
348
- : binding.keys.some((literal) => tokens.includes(literal));
349
- if (matches)
258
+ if (matchesTerminalInput(bindings, binding.bindingId, raw)) {
350
259
  return { intent: binding.intent, payload: binding.payload ? binding.payload(state) : undefined };
260
+ }
351
261
  }
352
262
  return null;
353
263
  }
354
- /** Match a host-owned generic-view action through the same catalog snapshot. */
355
- export function matchesViewHostBinding(bindings, id, raw) {
356
- return matchesTerminalInput(bindings, id, raw);
357
- }
358
- /** The active text-capture binding for this state, if any (compose-mode entry). */
359
- function activeCapture(keymap, state) {
360
- for (const b of keymap) {
361
- if ('capture' in b && b.when(state))
362
- return b;
363
- }
364
- return null;
365
- }
366
- /** Synthesize a one-line dump for a view that ships no text.mjs: `<title>` plus
367
- * ` — <n> items` if state has an obvious top-level list. */
368
- function synthDump(title, state) {
369
- if (state && typeof state === 'object') {
370
- for (const v of Object.values(state)) {
371
- if (Array.isArray(v))
372
- return `${title} — ${v.length} items`;
373
- }
374
- }
375
- return title;
264
+ /** Match the Inspector host's exit action through the catalog snapshot. */
265
+ export function matchesInspectorHostBinding(bindings, raw) {
266
+ return matchesTerminalInput(bindings, 'crtr.inspector.force-quit', raw);
376
267
  }
377
268
  /** Run a READ source / WRITE command through a transport → typed Result. */
378
269
  async function runRequest(transport, src, args) {
379
270
  const raw = await transport.send(src.request(args));
380
271
  return src.parse(raw);
381
272
  }
382
- /** Host a dual-target ViewCore + TuiPresenter in the alt screen until it quits
383
- * (or Ctrl-C). `text` is the optional text presenter for the piped path. */
384
- export async function runCoreView(core, tui, text, opts = {}) {
273
+ /** Host the Inspector until it quits, or emit its static text snapshot. */
274
+ export async function runInspector(core, tui, text, opts = {}) {
385
275
  const options = Object.freeze({ ...(opts.options ?? {}) });
386
276
  const bindings = resolveUserKeybindings();
387
277
  const keybindingNotice = summarizeKeybindingDiagnostics(bindings.diagnostics);
388
- const transport = createLocalTransport({ cwd: process.cwd() });
278
+ const transport = createInspectorTransport({ cwd: process.cwd() });
389
279
  // ── Non-TTY / piped path: init, best-effort refresh, dump, exit 0. ──
390
280
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
391
281
  if (keybindingNotice)
@@ -402,7 +292,6 @@ export async function runCoreView(core, tui, text, opts = {}) {
402
292
  resolve: (s, a) => runRequest(transport, s, a),
403
293
  execute: (c, a) => runRequest(transport, c, a),
404
294
  signal: dsignal,
405
- connect() { throw new Error('stream sources require an interactive view host'); },
406
295
  dispatch: async (name, payload) => { const it = core.intents[name]; if (it)
407
296
  await it(dctx, payload); },
408
297
  };
@@ -413,7 +302,7 @@ export async function runCoreView(core, tui, text, opts = {}) {
413
302
  }
414
303
  catch { /* dump current state regardless */ }
415
304
  }
416
- let out = text ? text.dump(dstate, { banner: dchrome.banner }) : synthDump(core.manifest.title, dstate);
305
+ let out = text.dump(dstate, { banner: dchrome.banner });
417
306
  if (!out.endsWith('\n'))
418
307
  out += '\n';
419
308
  process.stdout.write(out);
@@ -441,11 +330,9 @@ export async function runCoreView(core, tui, text, opts = {}) {
441
330
  const render = () => {
442
331
  const size = getTerminalSize();
443
332
  const { draw, frame } = createDraw(size, caps);
444
- // Footer hints are re-derived per draw so they track the active mode
445
- // (compose/react affordances appear only while their `when(state)` holds).
446
- const chromeManifest = { ...core.manifest, keymap: resolveViewKeyHints(tui.keymap, bindings, state) };
333
+ const chromeManifest = { ...core.manifest, keymap: resolveInspectorKeyHints(tui.keymap, bindings, state) };
447
334
  const tickChrome = { ...chrome, tick };
448
- const content = drawChrome(draw, size, chromeManifest, tickChrome);
335
+ const content = drawInspectorChrome(draw, size, chromeManifest, tickChrome);
449
336
  try {
450
337
  tui.render(state, draw, content);
451
338
  }
@@ -482,13 +369,6 @@ export async function runCoreView(core, tui, text, opts = {}) {
482
369
  while (dispatchQueue.length > 0) {
483
370
  dispatchQueue.shift().resolve();
484
371
  }
485
- for (const channel of streams) {
486
- try {
487
- channel.close();
488
- }
489
- catch { /* best-effort */ }
490
- }
491
- streams.clear();
492
372
  stopBusyTick();
493
373
  cleanup();
494
374
  resolveLoop();
@@ -504,10 +384,8 @@ export async function runCoreView(core, tui, text, opts = {}) {
504
384
  // The single-flight busy lane lives in the external FIFO. Refresh timers skip
505
385
  // while busy; ctx.dispatch from inside an intent runs inline so chained intents
506
386
  // do not deadlock. Keystrokes QUEUE behind an in-flight intent (up to a small
507
- // depth) rather than vanishing: a view whose auto-refresh shells out is busy a
508
- // real fraction of the time, and silently swallowing a `y` confirmation or a
509
- // cursor move is the difference between a live surface and a deaf one.
510
- const streams = new Set();
387
+ // depth) rather than vanishing: Inspector auto-refresh shells out, and silently
388
+ // swallowing a confirmation or cursor move would make the screen feel deaf.
511
389
  let busy = false;
512
390
  let dispatching = false;
513
391
  const dispatchQueue = [];
@@ -523,26 +401,6 @@ export async function runCoreView(core, tui, text, opts = {}) {
523
401
  set(next) { state = typeof next === 'function' ? next(state) : next; render(); },
524
402
  resolve: (s, a) => runRequest(transport, s, a),
525
403
  execute: (c, a) => runRequest(transport, c, a),
526
- connect(source, args) {
527
- let channel;
528
- channel = transport.open(source.request(args), {
529
- onFrame(frame) {
530
- void enqueueDispatch(source.onFrame, frame);
531
- },
532
- onClose(reason) {
533
- streams.delete(channel);
534
- if (source.onClose)
535
- void enqueueDispatch(source.onClose, { reason, channelId: channel.id });
536
- },
537
- onError(err) {
538
- signal.setBanner(err.display.headline, err.display.level);
539
- },
540
- });
541
- streams.add(channel);
542
- if (source.onOpen)
543
- void enqueueDispatch(source.onOpen, channel);
544
- return channel;
545
- },
546
404
  signal,
547
405
  dispatch: (name, payload) => runIntentInline(name, payload),
548
406
  };
@@ -625,7 +483,7 @@ export async function runCoreView(core, tui, text, opts = {}) {
625
483
  void drainDispatchQueue();
626
484
  });
627
485
  }
628
- // ── Mount: init → loading frame → first refresh (if the view has one). ──
486
+ // ── Mount: init → loading frame → first refresh. ──
629
487
  setupTerminal();
630
488
  render();
631
489
  if (core.intents['refresh'])
@@ -633,9 +491,6 @@ export async function runCoreView(core, tui, text, opts = {}) {
633
491
  // Keystroke-dispatch backlog depth (see onData).
634
492
  const MAX_QUEUED_KEYS = 2;
635
493
  let queuedKeys = 0;
636
- // Capture-mode buffer: the host's line-editor draft while a `capture` binding's
637
- // when(state) is true; reset to '' whenever no capture binding is active.
638
- let captureBuf = '';
639
494
  if (typeof core.manifest.refreshMs === 'number' && core.manifest.refreshMs > 0) {
640
495
  loopTimer = setInterval(() => { if (!busy)
641
496
  void enqueueDispatch('refresh'); }, core.manifest.refreshMs);
@@ -643,44 +498,23 @@ export async function runCoreView(core, tui, text, opts = {}) {
643
498
  const onData = async (data) => {
644
499
  if (done)
645
500
  return;
646
- let parsed;
501
+ let raw;
647
502
  try {
648
- parsed = parseViewKeypress(data, bindings);
503
+ raw = parseInspectorInput(data, bindings);
649
504
  }
650
505
  catch {
651
506
  return;
652
507
  }
653
- const { input, key, raw } = parsed;
654
508
  // The catalog-backed escape hatch works even mid-flight.
655
- if (matchesViewHostBinding(bindings, 'crtr.view.host.force-quit', raw)) {
509
+ if (matchesInspectorHostBinding(bindings, raw)) {
656
510
  finish();
657
511
  return;
658
512
  }
659
- // Queue behind an in-flight intent, but shallowly: past a couple of pending
660
- // keys the user is hammering a stuck view, and replaying the backlog later
661
- // would act on a screen they never saw.
513
+ // Keep the input backlog shallow so delayed actions never replay against a
514
+ // substantially newer Inspector frame.
662
515
  if (busy && queuedKeys >= MAX_QUEUED_KEYS)
663
516
  return;
664
- // Text-capture: while a capture binding is active, printable/backspace edit
665
- // the host buffer and dispatch capture(nextDraft); other keys (return/escape)
666
- // fall through to the keymap so submit/cancel can be bound.
667
- const cap = activeCapture(tui.keymap, state);
668
- if (cap) {
669
- if (matchesViewHostBinding(bindings, 'crtr.view.host.editor.backspace', raw)) {
670
- captureBuf = captureBuf.slice(0, -1);
671
- await enqueueDispatch(cap.capture, captureBuf);
672
- return;
673
- }
674
- if (isPrintable(input, key)) {
675
- captureBuf += sanitizePrintable(input);
676
- await enqueueDispatch(cap.capture, captureBuf);
677
- return;
678
- }
679
- }
680
- else {
681
- captureBuf = '';
682
- }
683
- const m = matchViewBinding(tui.keymap, bindings, input, key, state, raw);
517
+ const m = matchInspectorBinding(tui.keymap, bindings, state, raw);
684
518
  if (!m)
685
519
  return;
686
520
  queuedKeys += 1;
@@ -1,5 +1,5 @@
1
- import type { TextPresenter } from '../view/contract.js';
1
+ import type { InspectorText } from './contract.js';
2
2
  import type { InspectorState } from './core.js';
3
3
  /** The piped path: same information and grouping as the TUI, minus the glyphs
4
4
  * and hue a pipe cannot carry. */
5
- export declare const inspectorText: TextPresenter<InspectorState>;
5
+ export declare const inspectorText: InspectorText<InspectorState>;
@@ -0,0 +1,6 @@
1
+ import type { RawResponse, SourceRequest } from './contract.js';
2
+ export declare function createInspectorTransport(options?: {
3
+ cwd?: string;
4
+ }): {
5
+ send(request: SourceRequest): Promise<RawResponse>;
6
+ };
@@ -0,0 +1,36 @@
1
+ import { execFile } from 'node:child_process';
2
+ const MAX_BUFFER = 10 * 1024 * 1024;
3
+ export function createInspectorTransport(options = {}) {
4
+ const baseCwd = options.cwd ?? process.cwd();
5
+ return {
6
+ send(request) {
7
+ return new Promise((resolve) => {
8
+ const child = execFile(request.bin, request.args, { cwd: request.cwd ?? baseCwd, maxBuffer: MAX_BUFFER, encoding: 'utf8' }, (error, stdout, stderr) => {
9
+ if (!error) {
10
+ resolve({ ok: true, exitCode: 0, stdout, stderr });
11
+ return;
12
+ }
13
+ const code = error.code;
14
+ if (typeof code === 'number') {
15
+ resolve({ ok: true, exitCode: code, stdout: stdout ?? '', stderr: stderr ?? '' });
16
+ return;
17
+ }
18
+ const signal = error.signal;
19
+ if (signal) {
20
+ const detail = stderr && stderr.trim() !== ''
21
+ ? stderr
22
+ : `killed by signal ${signal}${signal === 'SIGKILL' ? ' (often out-of-memory)' : ''}`;
23
+ resolve({ ok: true, exitCode: 1, stdout: stdout ?? '', stderr: detail });
24
+ return;
25
+ }
26
+ const message = code === 'ENOENT' ? `${request.bin}: command not found` : error.message;
27
+ resolve({ ok: false, stdout: stdout ?? '', stderr: message });
28
+ });
29
+ if (request.stdin !== undefined && child.stdin) {
30
+ child.stdin.write(request.stdin);
31
+ child.stdin.end();
32
+ }
33
+ });
34
+ },
35
+ };
36
+ }
@@ -1,3 +1,3 @@
1
- import type { TuiPresenter } from '../view/contract.js';
1
+ import type { InspectorTui } from './contract.js';
2
2
  import type { InspectorState } from './core.js';
3
- export declare const inspectorTui: TuiPresenter<InspectorState>;
3
+ export declare const inspectorTui: InspectorTui<InspectorState>;
@@ -269,20 +269,20 @@ export const inspectorTui = {
269
269
  draw.list({ ...content, row: content.row + 2, height: Math.max(0, content.height - 2) }, rows, cursor, state.scroll.schedule);
270
270
  },
271
271
  keymap: [
272
- { bindingId: 'crtr.view.inspector.down', intent: 'down', hint: { label: 'move' } },
273
- { bindingId: 'crtr.view.inspector.up', intent: 'up' },
274
- { bindingId: 'crtr.view.inspector.section-next', intent: 'sectionNext', hint: { label: 'section' } },
275
- { bindingId: 'crtr.view.inspector.section-prev', intent: 'sectionPrev' },
276
- { bindingId: 'crtr.view.inspector.page-down', intent: 'pageDown' },
277
- { bindingId: 'crtr.view.inspector.page-up', intent: 'pageUp' },
278
- { bindingId: 'crtr.view.inspector.toggle-detail', intent: 'toggleDetail', when: (state) => (state.section === 'schedule' && state.selectedCronId !== null) || (state.section === 'jobs' && state.selectedJobId !== null), hint: { label: 'details' } },
279
- { bindingId: 'crtr.view.inspector.cancel-item', intent: 'cancelItem', when: (state) => state.section === 'schedule' && state.selectedCronId !== null, hint: { label: 'cancel' } },
280
- { bindingId: 'crtr.view.inspector.cancel-item', intent: 'cancelItem', when: (state) => state.section === 'jobs' && state.selectedJobId !== null, hint: { label: 'stop job' } },
281
- { bindingId: 'crtr.view.inspector.open-log', intent: 'openLog', when: (state) => state.section === 'jobs' && state.selectedJobId !== null, hint: { label: 'open log' } },
282
- { bindingId: 'crtr.view.inspector.confirm', intent: 'confirm', when: (state) => state.pendingCancel !== null, hint: { label: 'confirm' } },
283
- { bindingId: 'crtr.view.inspector.dismiss', intent: 'dismiss', hint: { label: 'dismiss' } },
284
- { bindingId: 'crtr.view.inspector.retarget', intent: 'retarget', when: (state) => state.section === 'schedule' && state.selectedCronId !== null, hint: { label: 'retarget' } },
285
- { bindingId: 'crtr.view.inspector.refresh', intent: 'refresh', hint: { label: 'refresh' } },
286
- { bindingId: 'crtr.view.inspector.quit', intent: 'quit', hint: { label: 'quit' } },
272
+ { bindingId: 'crtr.inspector.down', intent: 'down', hint: { label: 'move' } },
273
+ { bindingId: 'crtr.inspector.up', intent: 'up' },
274
+ { bindingId: 'crtr.inspector.section-next', intent: 'sectionNext', hint: { label: 'section' } },
275
+ { bindingId: 'crtr.inspector.section-prev', intent: 'sectionPrev' },
276
+ { bindingId: 'crtr.inspector.page-down', intent: 'pageDown' },
277
+ { bindingId: 'crtr.inspector.page-up', intent: 'pageUp' },
278
+ { bindingId: 'crtr.inspector.toggle-detail', intent: 'toggleDetail', when: (state) => (state.section === 'schedule' && state.selectedCronId !== null) || (state.section === 'jobs' && state.selectedJobId !== null), hint: { label: 'details' } },
279
+ { bindingId: 'crtr.inspector.cancel-item', intent: 'cancelItem', when: (state) => state.section === 'schedule' && state.selectedCronId !== null, hint: { label: 'cancel' } },
280
+ { bindingId: 'crtr.inspector.cancel-item', intent: 'cancelItem', when: (state) => state.section === 'jobs' && state.selectedJobId !== null, hint: { label: 'stop job' } },
281
+ { bindingId: 'crtr.inspector.open-log', intent: 'openLog', when: (state) => state.section === 'jobs' && state.selectedJobId !== null, hint: { label: 'open log' } },
282
+ { bindingId: 'crtr.inspector.confirm', intent: 'confirm', when: (state) => state.pendingCancel !== null, hint: { label: 'confirm' } },
283
+ { bindingId: 'crtr.inspector.dismiss', intent: 'dismiss', hint: { label: 'dismiss' } },
284
+ { bindingId: 'crtr.inspector.retarget', intent: 'retarget', when: (state) => state.section === 'schedule' && state.selectedCronId !== null, hint: { label: 'retarget' } },
285
+ { bindingId: 'crtr.inspector.refresh', intent: 'refresh', hint: { label: 'refresh' } },
286
+ { bindingId: 'crtr.inspector.quit', intent: 'quit', hint: { label: 'quit' } },
287
287
  ],
288
288
  };
@@ -8,7 +8,7 @@
8
8
  import { test } from 'node:test';
9
9
  import assert from 'node:assert/strict';
10
10
  import { resolveKeybindings } from '../index.js';
11
- import { inboxOpenHint, inboxOpenInstruction, inboxPopupHint, inboxShortcut, } from '../inbox.js';
11
+ import { inboxOpenHint, inboxHint, inboxOpenInstruction, inboxShortcut, } from '../inbox.js';
12
12
  const custom = () => resolveKeybindings({ 'crtr.tmux.inbox.toggle': ['alt+j'] });
13
13
  const multi = () => resolveKeybindings({ 'crtr.tmux.inbox.toggle': ['alt+i', 'alt+j'] });
14
14
  const disabled = () => resolveKeybindings({ 'crtr.tmux.inbox.toggle': [] });
@@ -22,17 +22,17 @@ test('inboxOpenHint mirrors the attach footer contract', () => {
22
22
  assert.equal(inboxOpenHint(resolveKeybindings()), 'Alt+I inbox');
23
23
  assert.equal(inboxOpenHint(custom()), 'Alt+J inbox');
24
24
  assert.equal(inboxOpenHint(multi()), 'Alt+I / Alt+J inbox');
25
- assert.equal(inboxOpenHint(disabled()), 'hl inbox open');
25
+ assert.equal(inboxOpenHint(disabled()), 'crtr human list');
26
26
  });
27
- test('inboxPopupHint is a bare parenthetical token, CLI form when disabled', () => {
28
- assert.equal(inboxPopupHint(resolveKeybindings()), 'Alt+I');
29
- assert.equal(inboxPopupHint(custom()), 'Alt+J');
30
- assert.equal(inboxPopupHint(multi()), 'Alt+I / Alt+J');
31
- assert.equal(inboxPopupHint(disabled()), '`hl inbox open`');
27
+ test('inboxHint is a bare parenthetical token, CLI form when disabled', () => {
28
+ assert.equal(inboxHint(resolveKeybindings()), 'Alt+I');
29
+ assert.equal(inboxHint(custom()), 'Alt+J');
30
+ assert.equal(inboxHint(multi()), 'Alt+I / Alt+J');
31
+ assert.equal(inboxHint(disabled()), '`crtr human list`');
32
32
  });
33
33
  test('inboxOpenInstruction is an imperative clause, CLI-only when disabled', () => {
34
- assert.equal(inboxOpenInstruction(resolveKeybindings()), 'press Alt+I (or run `hl inbox open` at a terminal)');
35
- assert.equal(inboxOpenInstruction(custom()), 'press Alt+J (or run `hl inbox open` at a terminal)');
36
- assert.equal(inboxOpenInstruction(multi()), 'press Alt+I / Alt+J (or run `hl inbox open` at a terminal)');
37
- assert.equal(inboxOpenInstruction(disabled()), 'run `hl inbox open` at a terminal');
34
+ assert.equal(inboxOpenInstruction(resolveKeybindings()), 'press Alt+I in a node viewer (or run `crtr human list` for the queue)');
35
+ assert.equal(inboxOpenInstruction(custom()), 'press Alt+J in a node viewer (or run `crtr human list` for the queue)');
36
+ assert.equal(inboxOpenInstruction(multi()), 'press Alt+I / Alt+J in a node viewer (or run `crtr human list` for the queue)');
37
+ assert.equal(inboxOpenInstruction(disabled()), 'run `crtr human list` for the queue');
38
38
  });
@@ -25,33 +25,28 @@ function pairedAttachIds(pairs) {
25
25
  const REQUIRED_IDS = [
26
26
  'crtr.tmux.menu.open',
27
27
  'crtr.tmux.menu.attach',
28
- ...pairedMenuIds(['promote', 'resume', 'fork', 'demote', 'detach', 'close-subtree', 'background-bash', 'file-review', 'pin', 'show', 'view-settings', 'fold-tools', 'metadata', 'context', 'providers', 'graph', 'focus-manager', 'copy-id', 'reload-viewer', 'issues', 'issue.idea', 'issue.bug']),
28
+ ...pairedMenuIds(['promote', 'resume', 'fork', 'demote', 'detach', 'close-subtree', 'background-bash', 'file-review', 'pin', 'show', 'view-settings', 'fold-tools', 'metadata', 'context', 'providers', 'graph', 'focus-manager', 'copy-id', 'reload-viewer', 'recap', 'issues', 'issue.idea', 'issue.bug']),
29
29
  ...ids('crtr.tmux.node', ['next', 'previous']),
30
30
  'crtr.tmux.inbox.toggle',
31
- ...ids('crtr.tmux.view', ['next', 'previous']),
32
31
  ...pairedAttachIds([
33
32
  ['detach', 'crtr.attach.detach'],
34
33
  ['clear-or-detach', 'crtr.attach.clear-or-detach'],
35
- ['mode-cycle', 'crtr.mode.cycle'],
36
34
  ['graph.toggle', 'crtr.attach.graph.toggle'],
35
+ ['help.toggle', 'crtr.attach.help.toggle'],
36
+ ['inbox.toggle', 'crtr.attach.inbox.toggle'],
37
37
  ['model-ladder.next', 'crtr.attach.model-ladder.next'],
38
38
  ['model-ladder.previous', 'crtr.attach.model-ladder.previous'],
39
39
  ['command.inspect', 'crtr.attach.command.inspect'],
40
40
  ['file-review', 'crtr.attach.file-review'],
41
41
  ['profile-files', 'crtr.attach.profile-files'],
42
+ ['whip', 'crtr.attach.whip'],
42
43
  ]),
44
+ ...ids('crtr.attach.scroll', ['up', 'down', 'page-up', 'page-down', 'live']),
45
+ 'crtr.attach.mouse.toggle',
46
+ 'crtr.attach.copy.message',
43
47
  ...ids('crtr.graph', ['down', 'up', 'first', 'last', 'collapse-or-manager', 'expand-or-child', 'focus', 'revive', 'focus-manager', 'close-subtree', 'dismiss']),
44
48
  ...ids('crtr.graph.confirm', ['accept', 'cancel']),
45
- ...ids('crtr.view.host', ['force-quit', 'editor.backspace']),
46
- ...ids('crtr.view.canvas', ['down', 'up', 'refresh', 'quit']),
47
- ...ids('crtr.view.chat', ['submit', 'contextual-cancel', 'reconnect', 'quit']),
48
- ...ids('crtr.view.git-pr', ['down', 'up', 'refresh', 'quit']),
49
- ...ids('crtr.view.inbox', ['down', 'up', 'open', 'reply', 'react', 'filter', 'refresh', 'connect-linkedin', 'connect-gmail', 'quit', 'submit-reply', 'cancel', 'reaction-previous', 'reaction-next', 'submit-reaction']),
50
- ...ids('crtr.view.linkedin', ['down', 'up', 'open', 'reply', 'react', 'refresh', 'quit', 'submit-reply', 'cancel', 'reaction-previous', 'reaction-next', 'submit-reaction']),
51
- ...ids('crtr.view.prompt-review', ['down', 'up', 'compare-previous', 'compare-next', 'toggle-mode', 'expand', 'export', 'refresh', 'quit']),
52
- ...ids('crtr.view.workspace-sidebar', ['down', 'up', 'open', 'refresh', 'quit']),
53
- ...ids('crtr.view.inspector', ['down', 'up', 'section-next', 'section-prev', 'page-down', 'page-up', 'toggle-detail', 'cancel-item', 'open-log', 'confirm', 'dismiss', 'retarget', 'refresh', 'quit']),
54
- ...ids('crtr.view-picker', ['down', 'up', 'run', 'quit']),
49
+ ...ids('crtr.inspector', ['force-quit', 'down', 'up', 'section-next', 'section-prev', 'page-down', 'page-up', 'toggle-detail', 'cancel-item', 'open-log', 'confirm', 'dismiss', 'retarget', 'refresh', 'quit']),
55
50
  ...ids('crtr.browse', ['quit', 'down', 'up', 'first', 'last', 'expand-or-child', 'collapse-or-parent', 'toggle-fold', 'tab-next', 'tab-previous', 'tab.1', 'tab.2', 'tab.3', 'tab.4', 'tab.5', 'close-subtree', 'confirm-close', 'sort', 'scope', 'profile', 'residents', 'preview', 'search', 'revive-now', 'focus', 'focus-background']),
56
51
  ...ids('crtr.browse.search', ['cancel', 'commit', 'delete', 'quit']),
57
52
  ...ids('crtr.profile.menu', ['up', 'down', 'select', 'accept-default', 'abort', 'slot.1', 'slot.2', 'slot.3', 'slot.4', 'slot.5', 'slot.6', 'slot.7', 'slot.8', 'slot.9', 'create', 'search-existing', 'use-root', 'set-default', 'add-directory', 'unpin']),
@@ -128,11 +123,9 @@ test('normalizes aliases, modifier order, uppercase printables, sequences, and d
128
123
  assert.equal(canonicalTerminalStroke({ input: '+', ctrl: true }), 'ctrl++');
129
124
  const resolved = resolveKeybindings({
130
125
  'crtr.attach.graph.toggle': ['M-X', 'alt+x'],
131
- 'crtr.tmux.view.next': ['M-V > ]', 'alt+v > ]'],
132
126
  'crtr.tmux.menu.promote': ['space'],
133
127
  });
134
128
  assert.deepEqual(resolved.gestures('crtr.attach.graph.toggle'), ['alt+shift+x', 'alt+x']);
135
- assert.deepEqual(resolved.gestures('crtr.tmux.view.next'), ['alt+shift+v > ]', 'alt+v > ]']);
136
129
  assert.deepEqual(resolved.gestures('crtr.tmux.menu.promote'), ['space']);
137
130
  });
138
131
  test('terminal literal space matches named space bindings', () => {
@@ -145,23 +138,21 @@ test('invalid values and unknown IDs diagnose precisely while valid overrides st
145
138
  'crtr.unknown': ['x'],
146
139
  'crtr.graph.down': 'down',
147
140
  'crtr.attach.graph.toggle': ['alt+x'],
148
- 'crtr.tmux.view.next': ['alt+v'],
149
141
  });
150
142
  assert.equal(resolved.gestures('crtr.graph.down')[0], 'j');
151
143
  assert.deepEqual(resolved.gestures('crtr.attach.graph.toggle'), ['alt+x']);
152
- assert.equal(resolved.gestures('crtr.tmux.view.next')[0], 'alt+v > ]');
153
144
  assert.deepEqual(new Set(resolved.diagnostics.map((item) => item.code)), new Set(['unknown-binding', 'invalid-override']));
154
145
  });
155
146
  test('colliding overrides fall back without affecting unrelated contexts', () => {
156
147
  const resolved = resolveKeybindings({
157
148
  'crtr.graph.down': ['k'],
158
- 'crtr.view.canvas.quit': ['x'],
149
+ 'crtr.inspector.quit': ['z'],
159
150
  'crtr.attach.graph.toggle': ['alt+c'],
160
151
  'crtr.attach.detach': ['j'],
161
152
  'crtr.setup.list-down': ['space'],
162
153
  });
163
154
  assert.equal(resolved.gestures('crtr.graph.down')[0], 'j');
164
- assert.deepEqual(resolved.gestures('crtr.view.canvas.quit'), ['x']);
155
+ assert.deepEqual(resolved.gestures('crtr.inspector.quit'), ['z']);
165
156
  assert.deepEqual(resolved.gestures('crtr.attach.graph.toggle'), ['alt+g']);
166
157
  assert.deepEqual(resolved.gestures('crtr.attach.detach'), ['ctrl+d']);
167
158
  assert.deepEqual(resolved.gestures('crtr.setup.list-down'), ['j', 'down']);