@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
@@ -0,0 +1,298 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { join, resolve } from 'node:path';
3
+ import { defineBranch, defineLeaf } from '../../core/command.js';
4
+ import { InputError } from '../../core/io.js';
5
+ import { ticketDir } from '../../core/human/root.js';
6
+ import { cliClient } from '../api-client.js';
7
+ function nodeActor() {
8
+ const nodeId = process.env['CRTR_NODE_ID'];
9
+ return nodeId === undefined || nodeId === '' ? null : nodeId;
10
+ }
11
+ function requireOriginNode() {
12
+ const nodeId = nodeActor();
13
+ if (nodeId !== null)
14
+ return nodeId;
15
+ throw new InputError({
16
+ error: 'review_origin_unavailable',
17
+ message: 'a review must be filed from a node with a live or resumable session',
18
+ field: 'CRTR_NODE_ID',
19
+ next: 'Run this from the node whose document context should be forked for the review.',
20
+ });
21
+ }
22
+ function requireSubtitle(value) {
23
+ if (typeof value === 'string' && value.trim() !== '')
24
+ return value.trim();
25
+ throw new InputError({
26
+ error: 'missing_parameter',
27
+ message: 'a non-empty subtitle is required',
28
+ field: 'subtitle',
29
+ next: 'Run `crtr human review new -h` and provide one plain-English sentence explaining the review needed and why it matters.',
30
+ });
31
+ }
32
+ function requireCommentText(value, leaf) {
33
+ if (typeof value === 'string' && value.trim() !== '')
34
+ return value;
35
+ throw new InputError({
36
+ error: 'missing_parameter',
37
+ message: 'non-empty comment text is required on stdin',
38
+ field: 'text',
39
+ next: `Run \`crtr human review comment ${leaf} -h\` and pipe the comment text on stdin.`,
40
+ });
41
+ }
42
+ function explicitDeliver(input, context) {
43
+ const supplied = context?.providedParams.has('deliver') ?? input['deliver'] !== undefined;
44
+ if (!supplied)
45
+ return undefined;
46
+ const deliver = input['deliver'];
47
+ return deliver === 'wake' || deliver === 'quiet' ? deliver : undefined;
48
+ }
49
+ function mutationOutput(result) {
50
+ const { comment } = result;
51
+ return {
52
+ comment_id: comment.comment_id,
53
+ status: comment.status,
54
+ revision: comment.revision,
55
+ anchor: comment.anchor,
56
+ author: comment.author,
57
+ text: comment.text,
58
+ changed: result.changed,
59
+ delivery: result.delivery ?? null,
60
+ };
61
+ }
62
+ function commentPreview(comment) {
63
+ return {
64
+ comment_id: comment.comment_id,
65
+ status: comment.status,
66
+ revision: comment.revision,
67
+ anchor: { line: comment.anchor.line, end_line: comment.anchor.end_line },
68
+ anchor_state: comment.anchor_state,
69
+ author: comment.author,
70
+ updated_by: comment.updated_by,
71
+ created_at: comment.created_at,
72
+ updated_at: comment.updated_at,
73
+ text_preview: comment.text.slice(0, 200),
74
+ };
75
+ }
76
+ const humanReviewNew = defineLeaf({
77
+ name: 'new',
78
+ description: 'queue a document review with a collaborating companion agent',
79
+ whenToUse: 'filing a live document for a person to review alongside a companion agent.',
80
+ help: {
81
+ name: 'human review new',
82
+ summary: 'queue a live document review and return its ticket handle immediately',
83
+ guide: 'The person reviews the live file in the attach viewer alongside a collaborating companion agent. Keep editing the file in place; approval is pushed back as an approval fact, and a changed document instructs the origin to re-read it.',
84
+ params: [
85
+ { kind: 'positional', name: 'file', type: 'path', required: true, constraint: 'Document or source file to review. Resolved to an absolute path; the daemon validates that it is readable reviewable text.' },
86
+ { kind: 'flag', name: 'subtitle', type: 'string', required: true, constraint: 'One plain-English sentence stating the review needed and why it matters.' },
87
+ { kind: 'flag', name: 'output', type: 'path', required: false, constraint: 'Where the immutable approval result JSON is projected. Default: <dir>/feedback.json.' },
88
+ ],
89
+ output: [
90
+ { name: 'job_id', type: 'string', required: true, constraint: 'Ticket bridge node id. The approval is pushed to its origin when the person submits.' },
91
+ { name: 'dir', type: 'string', required: true, constraint: 'Interaction directory holding the ticket projection and default approval result.' },
92
+ { name: 'output', type: 'string', required: true, constraint: 'Path where the immutable approval result JSON is projected.' },
93
+ { name: 'review_id', type: 'string', required: true, constraint: 'Daemon-owned review id for the document, comments, and companion.' },
94
+ { name: 'follow_up', type: 'string', required: true, constraint: 'The review remains live for the person and companion; approval is delivered to the origin inbox.' },
95
+ ],
96
+ outputKind: 'object',
97
+ effects: [
98
+ 'The daemon creates the ticket bridge, durable review, and companion session fork.',
99
+ 'The reviewed file remains live in the attach viewer; this command does not submit an approval.',
100
+ ],
101
+ },
102
+ run: async (input) => {
103
+ const file = resolve(input['file']);
104
+ const subtitle = requireSubtitle(input['subtitle']);
105
+ const outputArg = input['output'];
106
+ const output = typeof outputArg === 'string' ? resolve(outputArg) : undefined;
107
+ const review = await cliClient().createReview({
108
+ origin_kind: 'ticket',
109
+ origin_node_id: requireOriginNode(),
110
+ file,
111
+ idempotency_key: randomUUID(),
112
+ subtitle,
113
+ ...(output === undefined ? {} : { output_path: output }),
114
+ });
115
+ if (review.bridge_node_id === null)
116
+ throw new Error('ticket review was created without a bridge node');
117
+ const dir = ticketDir(review.bridge_node_id);
118
+ return {
119
+ job_id: review.bridge_node_id,
120
+ dir,
121
+ output: output ?? join(dir, 'feedback.json'),
122
+ review_id: review.review_id,
123
+ follow_up: 'The review is live for the person in the attach viewer with its companion agent. Approval is pushed to the origin inbox when submitted.',
124
+ };
125
+ },
126
+ });
127
+ const humanReviewCommentCreate = defineLeaf({
128
+ name: 'create',
129
+ description: 'add an anchored review comment',
130
+ whenToUse: 'recording a new finding or instruction against one or more document lines.',
131
+ help: {
132
+ name: 'human review comment create',
133
+ summary: 'add a daemon-owned comment anchored to document lines',
134
+ guide: 'Without --review, the daemon targets the calling companion node\'s open review. Comment text is supplied on stdin; agent comments use whole-line anchors.',
135
+ params: [
136
+ { kind: 'flag', name: 'review', type: 'string', required: false, constraint: 'Review id. Omit only to target the calling companion node\'s open review.' },
137
+ { kind: 'flag', name: 'line', type: 'int', required: true, constraint: 'First 1-based document line in the anchor.' },
138
+ { kind: 'flag', name: 'end-line', type: 'int', required: false, constraint: 'Last 1-based document line in the anchor. Default: --line.' },
139
+ { kind: 'flag', name: 'deliver', type: 'enum', choices: ['wake', 'quiet'], required: false, constraint: 'wake interrupts the companion now; quiet leaves a durable message for its next turn. Default: wake unless the caller is the companion.' },
140
+ { kind: 'stdin', name: 'text', required: true, constraint: 'Non-empty comment text.' },
141
+ ],
142
+ output: [
143
+ { name: 'comment_id', type: 'string', required: true, constraint: 'Daemon-owned comment id.' },
144
+ { name: 'status', type: 'string', required: true, constraint: 'Current comment status: open, resolved, or deleted.' },
145
+ { name: 'revision', type: 'integer', required: true, constraint: 'Current per-comment revision.' },
146
+ { name: 'anchor', type: 'object', required: true, constraint: 'Current whole-line anchor.' },
147
+ { name: 'author', type: 'object', required: true, constraint: 'Daemon-derived human or node attribution.' },
148
+ { name: 'text', type: 'string', required: true, constraint: 'Stored full comment text.' },
149
+ { name: 'changed', type: 'boolean', required: true, constraint: 'Whether this invocation changed the comment.' },
150
+ { name: 'delivery', type: 'object | null', required: true, constraint: 'Best-effort companion notification outcome, or null when no notification was needed.' },
151
+ ],
152
+ outputKind: 'object',
153
+ effects: ['Creates a daemon-owned comment and audit event, then best-effort notifies the companion.'],
154
+ },
155
+ run: async (input, context) => {
156
+ const reviewId = input['review'];
157
+ const line = input['line'];
158
+ const endLine = input['endLine'];
159
+ const result = await cliClient().createReviewComment(reviewId, {
160
+ text: requireCommentText(input['text'], 'create'),
161
+ anchor: { line, end_line: endLine ?? line },
162
+ actor_node_id: nodeActor(),
163
+ ...(explicitDeliver(input, context) === undefined ? {} : { deliver: explicitDeliver(input, context) }),
164
+ });
165
+ return mutationOutput(result);
166
+ },
167
+ });
168
+ const humanReviewCommentList = defineLeaf({
169
+ name: 'list',
170
+ description: 'list review comments in render order',
171
+ whenToUse: 'choosing a comment to inspect or checking the current anchored comment set.',
172
+ help: {
173
+ name: 'human review comment list',
174
+ summary: 'list render-ordered review comments with short text previews',
175
+ guide: 'Without --review, the daemon targets the calling companion node\'s open review. Use show for full comment text and audit history.',
176
+ params: [
177
+ { kind: 'flag', name: 'review', type: 'string', required: false, constraint: 'Review id. Omit only to target the calling companion node\'s open review.' },
178
+ { kind: 'flag', name: 'status', type: 'enum', choices: ['open', 'resolved', 'deleted', 'all'], required: false, default: 'open', constraint: 'Comment statuses to include. Default: open.' },
179
+ ],
180
+ output: [
181
+ { name: 'review_id', type: 'string', required: true, constraint: 'Resolved daemon-owned review id.' },
182
+ { name: 'comments', type: 'object[]', required: true, constraint: 'Comments in render order with status, anchor, attribution, and a 200-character text_preview.' },
183
+ { name: 'follow_up', type: 'string', required: true, constraint: 'Points to show for full text and per-comment history.' },
184
+ ],
185
+ outputKind: 'object',
186
+ effects: ['None. Read-only.'],
187
+ },
188
+ run: async (input) => {
189
+ const reviewId = input['review'];
190
+ const status = input['status'];
191
+ const result = await cliClient().listReviewComments(reviewId, reviewId === undefined
192
+ ? { status, actor_node_id: nodeActor() }
193
+ : { status });
194
+ return {
195
+ review_id: result.review_id,
196
+ comments: result.comments.map(commentPreview),
197
+ follow_up: 'Use `crtr human review comment show <comment_id>` for full comment text and event history.',
198
+ };
199
+ },
200
+ });
201
+ const humanReviewCommentShow = defineLeaf({
202
+ name: 'show',
203
+ description: 'read one comment and its event history',
204
+ whenToUse: 'you need a comment\'s full text or complete per-comment audit history.',
205
+ help: {
206
+ name: 'human review comment show',
207
+ summary: 'read one full review comment and its event history',
208
+ params: [{ kind: 'positional', name: 'comment_id', type: 'string', required: true, constraint: 'Daemon-owned comment id from comment list.' }],
209
+ output: [
210
+ { name: 'comment', type: 'object', required: true, constraint: 'Full daemon-owned comment projection, including text and attribution.' },
211
+ { name: 'events', type: 'object[]', required: true, constraint: 'Complete append-only event history for this comment, in event sequence order.' },
212
+ ],
213
+ outputKind: 'object',
214
+ effects: ['None. Read-only.'],
215
+ },
216
+ run: async (input) => {
217
+ const result = await cliClient().getReviewComment(input['comment_id']);
218
+ return { comment: result.comment, events: result.events };
219
+ },
220
+ });
221
+ function commentMutationLeaf(verb) {
222
+ const needsText = verb === 'edit';
223
+ return defineLeaf({
224
+ name: verb,
225
+ description: verb === 'edit'
226
+ ? 'replace a comment\'s text'
227
+ : `${verb} one review comment`,
228
+ whenToUse: verb === 'edit'
229
+ ? 'changing the stored text of an existing open or resolved comment.'
230
+ : `${verb === 'resolve' ? 'marking a comment addressed' : verb === 'reopen' ? 'returning a resolved comment to open' : 'retaining a terminal comment tombstone while removing it from active work'}.`,
231
+ help: {
232
+ name: `human review comment ${verb}`,
233
+ summary: verb === 'edit' ? 'replace a review comment\'s full text' : `${verb} a review comment`,
234
+ guide: needsText ? 'Replacement comment text is supplied on stdin.' : undefined,
235
+ params: [
236
+ { kind: 'positional', name: 'comment_id', type: 'string', required: true, constraint: 'Daemon-owned comment id from comment list.' },
237
+ { kind: 'flag', name: 'deliver', type: 'enum', choices: ['wake', 'quiet'], required: false, constraint: `wake interrupts the companion now; quiet leaves a durable message for its next turn. Default: ${verb === 'resolve' || verb === 'delete' ? 'quiet' : 'wake'} unless the caller is the companion.` },
238
+ ...(needsText ? [{ kind: 'stdin', name: 'text', required: true, constraint: 'Non-empty replacement comment text.' }] : []),
239
+ ],
240
+ output: [
241
+ { name: 'comment_id', type: 'string', required: true, constraint: 'Daemon-owned comment id.' },
242
+ { name: 'status', type: 'string', required: true, constraint: 'Current comment status: open, resolved, or deleted.' },
243
+ { name: 'revision', type: 'integer', required: true, constraint: 'Current per-comment revision.' },
244
+ { name: 'anchor', type: 'object', required: true, constraint: 'Current whole-line anchor.' },
245
+ { name: 'author', type: 'object', required: true, constraint: 'Daemon-derived human or node attribution.' },
246
+ { name: 'text', type: 'string', required: true, constraint: 'Stored full comment text.' },
247
+ { name: 'changed', type: 'boolean', required: true, constraint: 'Whether this invocation changed the comment.' },
248
+ { name: 'delivery', type: 'object | null', required: true, constraint: 'Best-effort companion notification outcome, or null when no notification was needed.' },
249
+ ],
250
+ outputKind: 'object',
251
+ effects: [`Mutates the daemon-owned comment and appends an audit event when its state changes; notification is best-effort.`],
252
+ },
253
+ run: async (input, context) => {
254
+ const commentId = input['comment_id'];
255
+ const actor_node_id = nodeActor();
256
+ const deliver = explicitDeliver(input, context);
257
+ const request = { actor_node_id, ...(deliver === undefined ? {} : { deliver }) };
258
+ const result = verb === 'edit'
259
+ ? await cliClient().editReviewComment(commentId, { ...request, text: requireCommentText(input['text'], 'edit') })
260
+ : verb === 'resolve'
261
+ ? await cliClient().resolveReviewComment(commentId, request)
262
+ : verb === 'reopen'
263
+ ? await cliClient().reopenReviewComment(commentId, request)
264
+ : await cliClient().deleteReviewComment(commentId, request);
265
+ return mutationOutput(result);
266
+ },
267
+ });
268
+ }
269
+ const humanReviewComment = defineBranch({
270
+ name: 'comment',
271
+ description: 'create, inspect, and update daemon-owned review comments',
272
+ whenToUse: 'working with the anchored comments on a document review.',
273
+ help: {
274
+ name: 'human review comment',
275
+ summary: 'operate on daemon-owned anchored review comments',
276
+ model: 'create and list address a review; all other verbs address one comment id. Create, edit, and reopen default to wake, while resolve and delete default to quiet.',
277
+ },
278
+ children: [
279
+ humanReviewCommentCreate,
280
+ humanReviewCommentList,
281
+ humanReviewCommentShow,
282
+ commentMutationLeaf('edit'),
283
+ commentMutationLeaf('resolve'),
284
+ commentMutationLeaf('reopen'),
285
+ commentMutationLeaf('delete'),
286
+ ],
287
+ });
288
+ export const humanReviewBranch = defineBranch({
289
+ name: 'review',
290
+ description: 'queue a document review or operate on its anchored comments',
291
+ whenToUse: 'a person and companion agent should collaborate on a live document review, or you need to work with that review\'s anchored comments.',
292
+ help: {
293
+ name: 'human review',
294
+ summary: 'queue live document reviews and manage their daemon-owned comments',
295
+ model: 'new creates the durable review, ticket, and companion. comment contains the operations on the review\'s shared anchored comments.',
296
+ },
297
+ children: [humanReviewNew, humanReviewComment],
298
+ });
@@ -1,81 +1,14 @@
1
- import type { CompletionHandler } from '@crouton-kit/humanloop';
2
1
  export declare const BODY_PATH_CONTRACT: string;
3
2
  export declare const DECK_SCHEMA_HINT: string;
4
3
  /**
5
4
  * Crouter's private per-interaction record. Reduced to the delivery essentials:
6
- * the mode `_deliver` dispatches on and the bridge node id it delivers back to.
7
- * Humanloop owns every public request/result/output path (deck.json,
5
+ * the mode that identifies the ticket and the bridge node id it delivers back to.
6
+ * The ticket store owns every public request/result/output path (deck.json,
8
7
  * response.json, review.json); crouter never records pane ids or output paths.
9
8
  *
10
- * Every ask records an immutable conversation-fork disposition before ticket
11
- * publication. A failed capture never suppresses the primary ask: it records an
12
- * explicit unavailable reason instead of falling back to live-session reads.
13
9
  */
14
- export type ConversationFork = {
15
- status: 'ready';
16
- source_node_id: string;
17
- source_file: string;
18
- source_session_id: string;
19
- leaf_id: string;
20
- model_spec: string;
21
- branch_point: 'branch-point.jsonl';
22
- captured_at: string;
23
- } | {
24
- status: 'unavailable';
25
- reason: 'no_origin' | 'broker_unavailable' | 'invalid_coordinates' | 'invalid_model' | 'materialization_failed';
26
- detail?: string;
27
- captured_at: string;
28
- };
29
10
  export interface RunRecord {
30
11
  mode: 'ask' | 'notify' | 'review';
31
12
  job_id?: string;
32
- conversation_fork?: ConversationFork;
33
13
  }
34
14
  export declare function resolveMaxPanes(): number;
35
- /**
36
- * The direct-exec completion handler humanloop runs when a crouter ticket
37
- * resolves, fed the completion event on stdin. The argv is absolute and
38
- * PATH/cwd-independent — never a `crtr` shell string — and, critically, must
39
- * actually EXECUTE in both crouter contexts:
40
- *
41
- * - Built (`dist/cli.js` present): `node <abs>/dist/cli.js human _deliver`.
42
- * - Dev/tsx (only `src/cli.ts` on disk): plain `node` cannot run the `.ts`
43
- * entry — its mandatory `.js`-extension ESM imports have no `.js` sibling on
44
- * disk, so Node's type-stripping fails at the first relative import. So we
45
- * register tsx's ESM loader first (`node --import <abs tsx/esm> src/cli.ts …`),
46
- * with the tsx entry resolved to an absolute file URL so the handler stays
47
- * cwd-independent when humanloop invokes it. tsx is necessarily present here
48
- * because crouter itself is running under it.
49
- *
50
- * Throws loudly when neither entry exists rather than registering an argv that
51
- * humanloop would retry forever.
52
- */
53
- export declare function crouterDeliverHandler(): CompletionHandler;
54
- /**
55
- * The direct-exec follow-up handler humanloop runs when the human presses `?`
56
- * on a pending crouter ticket (design-followup-consult-v2.md §B.5/§B.7) —
57
- * mirrors `crouterDeliverHandler()` exactly (same dual dist/tsx entry
58
- * resolution) but targets the hidden `human _consult` leaf. Its presence on
59
- * the root registration is the ONLY signal humanloop's UI uses to offer `?`,
60
- * and `human _consult`'s own trust check (M3) requires the registration's
61
- * `followUpHandler` to be this exact argv shape — a `human _consult` entry
62
- * inside some sealed runtime generation — so this must stay the same shape as
63
- * what `registerCrouterRoot` attaches.
64
- */
65
- export declare function crouterConsultHandler(): CompletionHandler;
66
- /** The focus handler invoked when the human asks the inbox popup to return to
67
- * the conversation that created its selected ticket. */
68
- export declare function crouterFocusHandler(): CompletionHandler;
69
- /** The frozen Visual handler. Like the other root handlers, this resolves the
70
- * actual installed or tsx CLI entry rather than depending on PATH. */
71
- export declare function crouterVisualHandler(): CompletionHandler;
72
- /**
73
- * Register the canvas node root with humanloop as owner `crouter`, attaching
74
- * the completion, follow-up, Visual, and focus handlers. Every ticket is a
75
- * direct child named for its bridge node, so node lifetime is ticket lifetime.
76
- * This also completes the hard cut from stale per-cwd registrations — but
77
- * never by stranding live tickets: unresolved tickets in an outgoing root are
78
- * swept into the current root first, and a root that cannot be fully swept
79
- * stays registered so its tickets remain reachable.
80
- */
81
- export declare function registerCrouterRoot(): string;
@@ -1,13 +1,7 @@
1
- import { fileURLToPath, pathToFileURL } from 'node:url';
2
- import { createRequire } from 'node:module';
3
- import { dirname, join } from 'node:path';
4
- import { existsSync, mkdirSync, readdirSync, renameSync, rmdirSync, statSync } from 'node:fs';
5
1
  import { readConfig } from '../../core/config.js';
6
- import { nodesRoot } from '../../core/canvas/paths.js';
7
- import { interactionState, listInboxRoots, registerInboxRoot, unregisterInboxRoot } from '@crouton-kit/humanloop';
8
2
  export const BODY_PATH_CONTRACT = 'bodyPath is a relative path to the body file, resolved from the directory containing the deck JSON; ' +
9
3
  'it must stay inside that directory, and paths escaping with .. or symlinks are rejected; absolute paths are unsupported';
10
- export const DECK_SCHEMA_HINT = 'Deck must match the humanloop deck schema: {title (required short inbox topic), ' +
4
+ export const DECK_SCHEMA_HINT = 'Deck must match the deck schema: {title (required short inbox topic), ' +
11
5
  'source?:{sessionName?,askedBy?,blockedSince?}, interactions:[{id, ' +
12
6
  'title (short ≤~4-word inbox topic that identifies the decision for a cold reader), ' +
13
7
  'subtitle (required ONE plain-English sentence stating the decision, your recommendation, and its stakes), ' +
@@ -21,177 +15,3 @@ export const DECK_SCHEMA_HINT = 'Deck must match the humanloop deck schema: {tit
21
15
  export function resolveMaxPanes() {
22
16
  return readConfig('user').max_panes_per_window;
23
17
  }
24
- /**
25
- * The direct-exec completion handler humanloop runs when a crouter ticket
26
- * resolves, fed the completion event on stdin. The argv is absolute and
27
- * PATH/cwd-independent — never a `crtr` shell string — and, critically, must
28
- * actually EXECUTE in both crouter contexts:
29
- *
30
- * - Built (`dist/cli.js` present): `node <abs>/dist/cli.js human _deliver`.
31
- * - Dev/tsx (only `src/cli.ts` on disk): plain `node` cannot run the `.ts`
32
- * entry — its mandatory `.js`-extension ESM imports have no `.js` sibling on
33
- * disk, so Node's type-stripping fails at the first relative import. So we
34
- * register tsx's ESM loader first (`node --import <abs tsx/esm> src/cli.ts …`),
35
- * with the tsx entry resolved to an absolute file URL so the handler stays
36
- * cwd-independent when humanloop invokes it. tsx is necessarily present here
37
- * because crouter itself is running under it.
38
- *
39
- * Throws loudly when neither entry exists rather than registering an argv that
40
- * humanloop would retry forever.
41
- */
42
- export function crouterDeliverHandler() {
43
- const here = dirname(fileURLToPath(import.meta.url)); // dist/commands/human | src/commands/human
44
- const distEntry = join(here, '..', '..', 'cli.js');
45
- if (existsSync(distEntry)) {
46
- return { command: process.execPath, args: [distEntry, 'human', '_deliver'] };
47
- }
48
- const tsEntry = join(here, '..', '..', 'cli.ts');
49
- if (existsSync(tsEntry)) {
50
- const tsxLoader = pathToFileURL(createRequire(import.meta.url).resolve('tsx/esm')).href;
51
- return { command: process.execPath, args: ['--import', tsxLoader, tsEntry, 'human', '_deliver'] };
52
- }
53
- throw new Error(`crouter completion handler: no runnable CLI entry near ${here} (neither cli.js nor cli.ts exists)`);
54
- }
55
- /**
56
- * The direct-exec follow-up handler humanloop runs when the human presses `?`
57
- * on a pending crouter ticket (design-followup-consult-v2.md §B.5/§B.7) —
58
- * mirrors `crouterDeliverHandler()` exactly (same dual dist/tsx entry
59
- * resolution) but targets the hidden `human _consult` leaf. Its presence on
60
- * the root registration is the ONLY signal humanloop's UI uses to offer `?`,
61
- * and `human _consult`'s own trust check (M3) requires the registration's
62
- * `followUpHandler` to be this exact argv shape — a `human _consult` entry
63
- * inside some sealed runtime generation — so this must stay the same shape as
64
- * what `registerCrouterRoot` attaches.
65
- */
66
- export function crouterConsultHandler() {
67
- const here = dirname(fileURLToPath(import.meta.url)); // dist/commands/human | src/commands/human
68
- const distEntry = join(here, '..', '..', 'cli.js');
69
- if (existsSync(distEntry)) {
70
- return { command: process.execPath, args: [distEntry, 'human', '_consult'] };
71
- }
72
- const tsEntry = join(here, '..', '..', 'cli.ts');
73
- if (existsSync(tsEntry)) {
74
- const tsxLoader = pathToFileURL(createRequire(import.meta.url).resolve('tsx/esm')).href;
75
- return { command: process.execPath, args: ['--import', tsxLoader, tsEntry, 'human', '_consult'] };
76
- }
77
- throw new Error(`crouter follow-up handler: no runnable CLI entry near ${here} (neither cli.js nor cli.ts exists)`);
78
- }
79
- /** The focus handler invoked when the human asks the inbox popup to return to
80
- * the conversation that created its selected ticket. */
81
- export function crouterFocusHandler() {
82
- const here = dirname(fileURLToPath(import.meta.url));
83
- const distEntry = join(here, '..', '..', 'cli.js');
84
- if (existsSync(distEntry))
85
- return { command: process.execPath, args: [distEntry, 'human', '_focus'] };
86
- const tsEntry = join(here, '..', '..', 'cli.ts');
87
- if (existsSync(tsEntry)) {
88
- const tsxLoader = pathToFileURL(createRequire(import.meta.url).resolve('tsx/esm')).href;
89
- return { command: process.execPath, args: ['--import', tsxLoader, tsEntry, 'human', '_focus'] };
90
- }
91
- throw new Error(`crouter focus handler: no runnable CLI entry near ${here} (neither cli.js nor cli.ts exists)`);
92
- }
93
- /** The frozen Visual handler. Like the other root handlers, this resolves the
94
- * actual installed or tsx CLI entry rather than depending on PATH. */
95
- export function crouterVisualHandler() {
96
- const here = dirname(fileURLToPath(import.meta.url));
97
- const distEntry = join(here, '..', '..', 'cli.js');
98
- if (existsSync(distEntry))
99
- return { command: process.execPath, args: [distEntry, 'human', '_visual'] };
100
- const tsEntry = join(here, '..', '..', 'cli.ts');
101
- if (existsSync(tsEntry)) {
102
- const tsxLoader = pathToFileURL(createRequire(import.meta.url).resolve('tsx/esm')).href;
103
- return { command: process.execPath, args: ['--import', tsxLoader, tsEntry, 'human', '_visual'] };
104
- }
105
- throw new Error(`crouter Visual handler: no runnable CLI entry near ${here} (neither cli.js nor cli.ts exists)`);
106
- }
107
- /**
108
- * Move one unresolved ticket directory from an outgoing crouter root into the
109
- * current root, preserving its id (the bridge node id) and every descriptor
110
- * file so `_deliver`/`_consult` still resolve against the same `run.json`.
111
- * The destination may already exist as the bridge node's canvas dir (the new
112
- * convention puts ticket files directly in the node dir), so an existing
113
- * destination is merged file-by-file; a collision on any name aborts this
114
- * ticket's sweep without partial loss of visibility (the caller then keeps the
115
- * old root registered).
116
- */
117
- function sweepTicket(oldDir, newDir) {
118
- if (!existsSync(newDir)) {
119
- renameSync(oldDir, newDir);
120
- return true;
121
- }
122
- const entries = readdirSync(oldDir);
123
- for (const entry of entries)
124
- if (existsSync(join(newDir, entry)))
125
- return false;
126
- for (const entry of entries)
127
- renameSync(join(oldDir, entry), join(newDir, entry));
128
- try {
129
- rmdirSync(oldDir);
130
- }
131
- catch { /* leftover empty dir is harmless */ }
132
- return true;
133
- }
134
- /**
135
- * Sweep every unresolved ticket out of an outgoing crouter root into the
136
- * current one. Returns true only when nothing unresolved remains in the old
137
- * root — the caller must NOT unregister a root this returns false for,
138
- * because unresolved tickets in an unregistered root become invisible to
139
- * every inbox surface (`hl inbox list`, `crtr human list`) and their asking
140
- * agents wait forever.
141
- */
142
- function sweepUnresolvedTickets(oldRoot, newRoot) {
143
- if (!existsSync(oldRoot))
144
- return true;
145
- let entries;
146
- try {
147
- entries = readdirSync(oldRoot);
148
- }
149
- catch {
150
- return false;
151
- }
152
- let clean = true;
153
- for (const entry of entries) {
154
- const oldDir = join(oldRoot, entry);
155
- try {
156
- if (!statSync(oldDir).isDirectory())
157
- continue;
158
- const state = interactionState(oldDir);
159
- if (state === 'missing' || state === 'resolved')
160
- continue;
161
- if (!sweepTicket(oldDir, join(newRoot, entry)))
162
- clean = false;
163
- }
164
- catch {
165
- clean = false;
166
- }
167
- }
168
- return clean;
169
- }
170
- /**
171
- * Register the canvas node root with humanloop as owner `crouter`, attaching
172
- * the completion, follow-up, Visual, and focus handlers. Every ticket is a
173
- * direct child named for its bridge node, so node lifetime is ticket lifetime.
174
- * This also completes the hard cut from stale per-cwd registrations — but
175
- * never by stranding live tickets: unresolved tickets in an outgoing root are
176
- * swept into the current root first, and a root that cannot be fully swept
177
- * stays registered so its tickets remain reachable.
178
- */
179
- export function registerCrouterRoot() {
180
- const root = nodesRoot();
181
- mkdirSync(root, { recursive: true });
182
- for (const registration of listInboxRoots()) {
183
- if (registration.owner === 'crouter' && registration.root !== root) {
184
- if (sweepUnresolvedTickets(registration.root, root)) {
185
- unregisterInboxRoot(registration.root, 'crouter');
186
- }
187
- }
188
- }
189
- return registerInboxRoot({
190
- root,
191
- owner: 'crouter',
192
- handler: crouterDeliverHandler(),
193
- followUpHandler: crouterConsultHandler(),
194
- visualHandler: crouterVisualHandler(),
195
- focusHandler: crouterFocusHandler(),
196
- }).root;
197
- }
@@ -1,44 +1,39 @@
1
- // `crtr human` subtree — humanloop producer + completion bridge.
1
+ // `crtr human` creates bridge nodes and durable tickets for human decisions.
2
2
  //
3
- // Kickoff leaves (ask/review) create a terminal kind:'human' bridge node under
4
- // the asking node, register the one canvas node root with humanloop (owner
5
- // 'crouter', `_deliver` handler), submit the deck/review, and return at once —
6
- // nothing opens on screen. When the human answers from humanloop's inbox popup
7
- // (the inbox-toggle keybinding, or `hl inbox open`), humanloop invokes the
8
- // registered `_deliver` handler, which pushFinals
9
- // the answer as the bridge node's final report, fanning it into the asking
10
- // node's inbox. notify enqueues a durable deck with no node; show is passive
11
- // display. Humanloop owns the queue UI, claims, and atomic finalization.
3
+ // Ask creates a bridge node and submits a ticket to the store. Review creation
4
+ // asks crtrd to create a ticket, daemon-owned review, and companion. notify
5
+ // enqueues a durable deck with no node; show is passive display.
12
6
  import { defineBranch } from '../core/command.js';
13
- import { humanAsk, humanReview, humanNotify, humanShow } from './human/prompts.js';
14
- import { humanList, humanDeck, humanResolve, humanCancel, humanDeliver, humanFocus, humanConsult, humanVisual } from './human/queue.js';
7
+ import { humanAsk, humanNotify, humanShow } from './human/prompts.js';
8
+ import { humanReviewBranch } from './human/review.js';
9
+ import { humanList, humanDeck, humanResolve, humanCancel } from './human/queue.js';
10
+ import { humanInbox } from './human/inbox.js';
11
+ import { humanDoc } from './human/doc.js';
15
12
  import { inboxOpenInstruction } from '../core/keybindings/index.js';
16
13
  export function registerHuman() {
17
14
  return defineBranch({
18
15
  name: 'human',
19
16
  rootEntry: {
20
17
  concept: 'human-in-the-loop decisions, document review, and live display',
21
- desc: 'ask, review, notify, show, cancel, list',
22
- useWhen: 'you have a question for the user, want their feedback, or are presenting them with options or a choice — always reach for human instead of guessing or assuming, or laying a choice out as prose, when a person can decide; and whenever the user wants to review a spec, plan, or requirements document, this is the command for anchored line-by-line comments.'
18
+ desc: 'ask, review new/comment, notify, show, cancel, list',
19
+ useWhen: 'when a person must decide, review a document with you, or receive a live display.'
23
20
  },
24
21
  help: {
25
22
  name: 'human',
26
23
  summary: 'human-in-the-loop decisions, document review, and live display',
27
- model: `Every body and displayed file is directive-flavored markdown rendered by termrender (panels, columns, trees, callouts, mermaid) — see \`termrender doc -h\` for the directive set before authoring one. ask and review are kickoffs: they create a kind:'human' bridge node under you and return instantly, never blocking. Nothing opens on screen — the ticket is queued in the humanloop inbox; the human opens it — ${inboxOpenInstruction()} — on their own time, and their response is pushed to your inbox when they answer, so keep working (or just end your turn) and you'll be woken with it. ask covers everything from a yes/no sign-off gate (two options) to an open-ended judgment call; review queues a .md for anchored comments and the inbox previews the live file, so edit in place rather than canceling and re-presenting. notify enqueues a durable acknowledgement with no node; show is passive live display.`,
24
+ model: `Every body and displayed file is directive-flavored markdown rendered by termrender (panels, columns, trees, callouts, mermaid) — see \`crtr human doc check\` to validate a body before submitting it. ask creates a kind:'human' bridge node under you and returns instantly, never blocking. Nothing opens on screen — the ticket is queued in the human inbox; the human opens it — ${inboxOpenInstruction()} — on their own time, and their response is pushed to your inbox when they answer, so keep working (or just end your turn) and you'll be woken with it. ask covers everything from a yes/no sign-off gate (two options) to an open-ended judgment call. review is a branch: new queues a live document for the human to review in the attach viewer alongside a companion agent, while comment verbs operate on daemon-owned anchored comments; approval is pushed back as an approval fact, and a changed document instructs the origin to re-read it. notify enqueues a durable acknowledgement with no node; show is passive live display. inbox opens or toggles the queue on this screen; doc validates or renders a directive-flavored markdown body.`,
28
25
  },
29
26
  children: [
30
27
  humanAsk,
31
- humanReview,
28
+ humanReviewBranch,
32
29
  humanNotify,
33
30
  humanShow,
34
31
  humanCancel,
35
32
  humanList,
36
33
  humanDeck,
37
34
  humanResolve,
38
- humanDeliver,
39
- humanFocus,
40
- humanConsult,
41
- humanVisual,
35
+ humanInbox,
36
+ humanDoc,
42
37
  ],
43
38
  });
44
39
  }
@@ -0,0 +1 @@
1
+ export {};