@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,231 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { CrtrClient, ApiError } from '../../api/index.js';
3
- import { BrokerClient, BrokerUnavailableError } from '../broker-client/index.js';
4
- function makeInvalidTargetError(target) {
5
- return {
6
- kind: 'invalid-target',
7
- display: {
8
- headline: `invalid stream target: ${target}`,
9
- explanation: 'Stream targets must be plain node ids.',
10
- nextStep: 'Use a node id without /, \\, or .., then reconnect.',
11
- level: 'error',
12
- blocking: false,
13
- },
14
- };
15
- }
16
- function makeNoNodeError(target) {
17
- return {
18
- kind: 'no-node',
19
- display: {
20
- headline: `node ${target} does not exist`,
21
- explanation: 'No node with that id was found in the canvas.',
22
- nextStep: 'Check the node id and try again.',
23
- level: 'error',
24
- blocking: false,
25
- },
26
- };
27
- }
28
- function makeNoBrokerError(target) {
29
- return {
30
- kind: 'broker-unavailable',
31
- display: {
32
- headline: `node ${target} has no running broker`,
33
- explanation: 'The stream transport connects only to an already-running broker.',
34
- nextStep: `Run crtr surface node focus ${target} or crtr node lifecycle revive ${target}, then reconnect.`,
35
- level: 'error',
36
- blocking: false,
37
- },
38
- };
39
- }
40
- function isValidTarget(target) {
41
- return target.length > 0 && !target.includes('/') && !target.includes('\\') && !target.includes('..');
42
- }
43
- // A local view stream is a pure broker-IPC consumer (view.sock), so the ONE
44
- // canvas-state fact it needs — does the node exist, and has it reached a terminal
45
- // status — goes through crtrd's /v1 API (CrtrClient over the local socket), never
46
- // a direct canvas-db read: a CLI/view leaf must not open the store (V-1). One
47
- // lazy client; `autostart: false` because merely observing a node must not boot
48
- // the daemon.
49
- let sharedApiClient = null;
50
- function apiClient() {
51
- sharedApiClient ??= CrtrClient.forLocalSocket({ autostart: false });
52
- return sharedApiClient;
53
- }
54
- /** Node presence for the two facts this stream needs, resolved through the API.
55
- * `live` = exists and not terminal (proceed / keep reconnecting); `terminal` =
56
- * done|dead|canceled (give up); `gone` = definitively absent, a 404 (no-node);
57
- * `unknown` = the daemon was unreachable or errored — we can't tell, so we NEVER
58
- * falsely claim absence: the existence check proceeds to the broker path (which
59
- * reports no-broker), and reconnect KEEPS RETRYING (only a confirmed
60
- * `terminal`/`gone` gives up), so a transient daemon blip can't kill a
61
- * recoverable stream. */
62
- async function nodePresence(target) {
63
- try {
64
- const status = (await apiClient().getNode(target)).status;
65
- if (status === 'done' || status === 'dead' || status === 'canceled')
66
- return 'terminal';
67
- return 'live';
68
- }
69
- catch (err) {
70
- if (err instanceof ApiError && err.status === 404)
71
- return 'gone';
72
- return 'unknown';
73
- }
74
- }
75
- export function openLocalStream(req, handlers) {
76
- const channelId = randomUUID();
77
- const role = req.role ?? 'controller';
78
- let client = null;
79
- let closedByView = false;
80
- let closeReported = false;
81
- let reconnecting = false;
82
- let everConnected = false;
83
- let initialBrokerUnavailableReported = false;
84
- const channel = {
85
- id: channelId,
86
- send(frame) {
87
- client?.send(frame);
88
- },
89
- close() {
90
- closedByView = true;
91
- try {
92
- client?.close();
93
- }
94
- catch {
95
- /* best-effort */
96
- }
97
- },
98
- };
99
- const terminalClose = (reason) => {
100
- if (closeReported || closedByView)
101
- return;
102
- closeReported = true;
103
- try {
104
- client?.close();
105
- }
106
- catch {
107
- /* best-effort */
108
- }
109
- try {
110
- handlers.onClose(reason);
111
- }
112
- catch {
113
- /* best-effort */
114
- }
115
- };
116
- const reportError = (err) => {
117
- if (closeReported || closedByView)
118
- return;
119
- try {
120
- handlers.onError(err);
121
- }
122
- catch {
123
- /* best-effort */
124
- }
125
- };
126
- const deferTerminalFailure = (reason, err) => {
127
- queueMicrotask(() => {
128
- reportError(err);
129
- terminalClose(reason);
130
- });
131
- };
132
- if (!isValidTarget(req.target)) {
133
- deferTerminalFailure('invalid stream target', makeInvalidTargetError(req.target));
134
- return channel;
135
- }
136
- const sendHello = () => {
137
- client?.send({ type: 'hello', role, client_id: channelId });
138
- };
139
- const reconnect = async () => {
140
- // reconnect only runs after begin() sets `client` and a first connect, so
141
- // `client` is non-null here; the guard keeps that a hard invariant.
142
- if (closedByView || closeReported || reconnecting || client === null)
143
- return;
144
- reconnecting = true;
145
- let delay = 200;
146
- try {
147
- while (!closedByView && !closeReported) {
148
- try {
149
- await client.redial();
150
- // Reconnected: the broker is serving frames again. Do NOT re-check
151
- // presence here — a slow or `unknown` status call must never tear
152
- // down a stream that has just successfully reconnected.
153
- return;
154
- }
155
- catch {
156
- if (closedByView || closeReported)
157
- return;
158
- // Redial failed. Give up ONLY when the node is confirmed no longer
159
- // reachable: a terminal status (done|dead|canceled) or a definitive
160
- // 404. `live` and `unknown` (daemon slow/restarting under load) both
161
- // keep retrying — a transient blip must not kill a recoverable stream.
162
- const presence = await nodePresence(req.target);
163
- if (presence === 'terminal' || presence === 'gone') {
164
- terminalClose('broker connection closed');
165
- return;
166
- }
167
- await new Promise((resolve) => setTimeout(resolve, delay));
168
- delay = Math.min(delay * 2, 1000);
169
- }
170
- }
171
- }
172
- finally {
173
- reconnecting = false;
174
- }
175
- };
176
- // The existence check is a canvas-state read routed through the API, so it is
177
- // async: the channel is returned synchronously (callers rely on that) while the
178
- // node lookup settles on a later tick. A definitively-absent node (404) reports
179
- // no-node then closes; a present or indeterminate node proceeds to open the
180
- // broker socket (a missing broker then reports no-broker via the error path).
181
- const begin = async () => {
182
- if (closedByView || closeReported)
183
- return;
184
- if ((await nodePresence(req.target)) === 'gone') {
185
- reportError(makeNoNodeError(req.target));
186
- terminalClose('no node');
187
- return;
188
- }
189
- if (closedByView || closeReported)
190
- return;
191
- client = new BrokerClient(req.target, { emitUnmatchedDataFrames: true });
192
- client.on('connect', () => {
193
- if (closedByView || closeReported)
194
- return;
195
- everConnected = true;
196
- sendHello();
197
- });
198
- client.on('frame', (frame) => {
199
- if (closedByView || closeReported)
200
- return;
201
- try {
202
- handlers.onFrame(frame);
203
- }
204
- catch {
205
- /* best-effort */
206
- }
207
- });
208
- client.on('error', (err) => {
209
- if (closedByView || closeReported)
210
- return;
211
- if (err instanceof BrokerUnavailableError && !everConnected && !initialBrokerUnavailableReported) {
212
- initialBrokerUnavailableReported = true;
213
- reportError(makeNoBrokerError(req.target));
214
- }
215
- });
216
- client.on('close', () => {
217
- if (closedByView || closeReported)
218
- return;
219
- if (reconnecting)
220
- return;
221
- if (!everConnected) {
222
- terminalClose('node has no running broker');
223
- return;
224
- }
225
- void reconnect();
226
- });
227
- client.connect();
228
- };
229
- void begin();
230
- return channel;
231
- }
@@ -1,8 +0,0 @@
1
- import type { SourceRequest } from './contract.js';
2
- import type { Transport } from './transport.js';
3
- export interface BurstCoalescingOptions {
4
- ttlMs: number;
5
- shouldCache(req: SourceRequest): boolean;
6
- now?: () => number;
7
- }
8
- export declare function createBurstCoalescingTransport(inner: Transport, opts: BurstCoalescingOptions): Transport;
@@ -1,38 +0,0 @@
1
- // transport-cache.ts — small host-side burst coalescing for expensive reads.
2
- //
3
- // The SourceRequest/Transport contract stays unchanged: callers still send the
4
- // same request and receive the same RawResponse. This decorator only changes the
5
- // host's scheduling for requests the host explicitly marks cacheable.
6
- export function createBurstCoalescingTransport(inner, opts) {
7
- const now = opts.now ?? Date.now;
8
- const inflight = new Map();
9
- const cache = new Map();
10
- const send = async (req) => {
11
- if (!opts.shouldCache(req))
12
- return inner.send(req);
13
- const key = JSON.stringify(req);
14
- const cached = cache.get(key);
15
- if (cached !== undefined) {
16
- if (cached.expiresAt > now())
17
- return cached.response;
18
- cache.delete(key);
19
- }
20
- const pending = inflight.get(key);
21
- if (pending !== undefined)
22
- return pending;
23
- const run = inner.send(req).then((response) => {
24
- cache.set(key, { expiresAt: now() + opts.ttlMs, response });
25
- return response;
26
- }).finally(() => {
27
- inflight.delete(key);
28
- });
29
- inflight.set(key, run);
30
- return run;
31
- };
32
- return {
33
- send,
34
- open(req, handlers) {
35
- return inner.open(req, handlers);
36
- },
37
- };
38
- }
@@ -1,7 +0,0 @@
1
- import type { Transport } from './transport.js';
2
- export interface LocalTransportOptions {
3
- /** Working directory for `exec` requests that don't carry their own cwd.
4
- * Defaults to process.cwd(). */
5
- cwd?: string;
6
- }
7
- export declare function createLocalTransport(opts?: LocalTransportOptions): Transport;
@@ -1,83 +0,0 @@
1
- // transport-local.ts — the BUILT local transport: fulfills SourceRequests on
2
- // this machine. exec→execFile (cwd = the view's cwd unless the request says
3
- // otherwise), file→readFile, http→fetch.
4
- //
5
- // Never throws. Transport-level failure (binary missing, file unreadable,
6
- // network down) ⇒ { ok:false, stderr }. A spawned process exiting non-zero is
7
- // transport-level SUCCESS (ok:true + exitCode) — classifying that is the
8
- // source's parse() job.
9
- import { execFile } from 'node:child_process';
10
- import { readFile } from 'node:fs/promises';
11
- import { openLocalStream } from './stream-local.js';
12
- const MAX_BUFFER = 10 * 1024 * 1024;
13
- export function createLocalTransport(opts = {}) {
14
- const baseCwd = opts.cwd ?? process.cwd();
15
- return {
16
- async send(req) {
17
- switch (req.kind) {
18
- case 'exec': return sendExec(req, baseCwd);
19
- case 'file': return sendFile(req);
20
- case 'http': return sendHttp(req);
21
- }
22
- },
23
- open(req, handlers) {
24
- return openLocalStream(req, handlers);
25
- },
26
- };
27
- }
28
- function sendExec(req, baseCwd) {
29
- return new Promise((resolve) => {
30
- const child = execFile(req.bin, req.args, { cwd: req.cwd ?? baseCwd, maxBuffer: MAX_BUFFER, encoding: 'utf8' }, (err, stdout, stderr) => {
31
- if (!err) {
32
- resolve({ ok: true, exitCode: 0, stdout, stderr });
33
- return;
34
- }
35
- const code = err.code;
36
- if (typeof code === 'number') {
37
- // Ran but exited non-zero: transport-level success; parse() classifies.
38
- resolve({ ok: true, exitCode: code, stdout: stdout ?? '', stderr: stderr ?? '' });
39
- return;
40
- }
41
- const signal = err.signal;
42
- if (signal) {
43
- // Killed by signal: it ran; surface as a non-zero exit. A SIGKILL with
44
- // no stderr at all (the live-incident shape: a guest OOM killer takes
45
- // out the child before it ever writes anything) used to come back as
46
- // a bare `failed (1)` with nothing to explain it — the signal itself
47
- // IS the useful diagnostic here, so surface it when stderr is empty
48
- // rather than discarding it.
49
- const detail = stderr && stderr.trim() !== ''
50
- ? stderr
51
- : `killed by signal ${signal}${signal === 'SIGKILL' ? ' (often out-of-memory)' : ''}`;
52
- resolve({ ok: true, exitCode: 1, stdout: stdout ?? '', stderr: detail });
53
- return;
54
- }
55
- // Spawn-level failure (ENOENT/EACCES/maxBuffer): transport failure.
56
- const msg = code === 'ENOENT' ? `${req.bin}: command not found` : err.message;
57
- resolve({ ok: false, stdout: stdout ?? '', stderr: msg });
58
- });
59
- if (req.stdin != null && child.stdin) {
60
- child.stdin.write(req.stdin);
61
- child.stdin.end();
62
- }
63
- });
64
- }
65
- async function sendFile(req) {
66
- try {
67
- const text = await readFile(req.path, 'utf8');
68
- return { ok: true, stdout: text, stderr: '' };
69
- }
70
- catch (e) {
71
- return { ok: false, stdout: '', stderr: e instanceof Error ? e.message : String(e) };
72
- }
73
- }
74
- async function sendHttp(req) {
75
- try {
76
- const res = await fetch(req.url, { method: req.method, headers: req.headers, body: req.body });
77
- const body = await res.text();
78
- return { ok: true, status: res.status, stdout: body, stderr: res.ok ? '' : res.statusText };
79
- }
80
- catch (e) {
81
- return { ok: false, stdout: '', stderr: e instanceof Error ? e.message : String(e) };
82
- }
83
- }
@@ -1,2 +0,0 @@
1
- import type { RawResponse } from './contract.js';
2
- export declare function createRemoteExec(previewEndpoint: string, relayToken: string, timeoutMs?: number): (bin: string, args: string[]) => Promise<RawResponse>;
@@ -1,10 +0,0 @@
1
- import type { SourceRequest, RawResponse, StreamRequest, StreamChannel, SourceError } from './contract.js';
2
- export interface StreamHandlers {
3
- onFrame(frame: unknown): void;
4
- onClose(reason: string): void;
5
- onError(err: SourceError): void;
6
- }
7
- export interface Transport {
8
- send(req: SourceRequest): Promise<RawResponse>;
9
- open(req: StreamRequest, handlers: StreamHandlers): StreamChannel;
10
- }
@@ -1,15 +0,0 @@
1
- // transport.ts — the transport seam between a view's declarative SourceRequests
2
- // and whatever fulfills them.
3
- //
4
- // The core is transport-blind: it only ever calls ctx.resolve(source, args) /
5
- // ctx.execute(command, args); the host threads Transport.send → source.parse.
6
- // Implementations:
7
- // • transport-local.ts (BUILT) — Node-side: exec→execFile, file→readFile,
8
- // http→fetch. Used directly by the TUI host and by the `view serve` bridge
9
- // server on behalf of the browser bundle.
10
- // • src/web/transport-http.ts (BUILT) — browser-side: POSTs the SourceRequest
11
- // to the local bridge (`/__crtr/source`).
12
- // • cloud (SEAM ONLY, not built) — same interface; send() POSTs the request
13
- // to an endpoint that runs it server-side, or maps it to a real API call.
14
- // Wiring a different Transport is the entire cloud migration.
15
- export {};
@@ -1,24 +0,0 @@
1
- interface PiLike {
2
- registerTool: (definition: Record<string, unknown>) => void;
3
- }
4
- /** The naming schema — the ONE definition of what a generated session name is.
5
- * Both fields are required: a name without an icon renders a bare label, and
6
- * an icon without a name is useless, so the model is made to decide both in a
7
- * single constrained emission. */
8
- export declare const NAME_SESSION_SCHEMA: {
9
- readonly type: "object";
10
- readonly properties: {
11
- readonly name: {
12
- readonly type: "string";
13
- readonly description: "A 3-8 word kebab-case session name: lowercase words joined by single hyphens, e.g. refactor-auth-token-flow. No punctuation, quotes, or prose.";
14
- };
15
- readonly icon: {
16
- readonly type: "string";
17
- readonly description: "The Nerd Font glyph depicting this session, as a codepoint in U+XXXX form (e.g. U+F188).";
18
- };
19
- };
20
- readonly required: readonly ["name", "icon"];
21
- readonly additionalProperties: false;
22
- };
23
- export declare function registerNamingTool(pi: PiLike): void;
24
- export default registerNamingTool;
@@ -1,67 +0,0 @@
1
- // naming-tool.ts — the structured-output seam for session naming.
2
- //
3
- // Loaded ONLY by the headless namer subprocess (`runtime/naming.ts` passes it
4
- // with `-e` alongside `--no-extensions`), never by a canvas node. It registers a
5
- // single `name_session` tool whose parameters ARE the naming schema, with
6
- // pi's constrained sampling turned on, so the light model emits a real typed
7
- // object instead of prose we have to parse out of a text reply.
8
- //
9
- // The result travels back to the parent over a file: the parent creates a temp
10
- // path, passes it as CRTR_NAME_RESULT_FILE, and reads it after the subprocess
11
- // exits. stdout is unusable for this — pi print-mode writes its own chatter
12
- // there.
13
- //
14
- // Inert (registers nothing) when CRTR_NAME_RESULT_FILE is absent, so an
15
- // accidental load in any other context is a no-op.
16
- import { mkdirSync, writeFileSync } from 'node:fs';
17
- import { dirname } from 'node:path';
18
- /** The naming schema — the ONE definition of what a generated session name is.
19
- * Both fields are required: a name without an icon renders a bare label, and
20
- * an icon without a name is useless, so the model is made to decide both in a
21
- * single constrained emission. */
22
- export const NAME_SESSION_SCHEMA = {
23
- type: 'object',
24
- properties: {
25
- name: {
26
- type: 'string',
27
- description: 'A 3-8 word kebab-case session name: lowercase words joined by single hyphens, e.g. refactor-auth-token-flow. No punctuation, quotes, or prose.',
28
- },
29
- icon: {
30
- type: 'string',
31
- description: 'The Nerd Font glyph depicting this session, as a codepoint in U+XXXX form (e.g. U+F188).',
32
- },
33
- },
34
- required: ['name', 'icon'],
35
- additionalProperties: false,
36
- };
37
- export function registerNamingTool(pi) {
38
- const out = process.env['CRTR_NAME_RESULT_FILE'];
39
- if (out === undefined || out.trim() === '')
40
- return;
41
- pi.registerTool({
42
- name: 'name_session',
43
- label: 'Name session',
44
- description: 'Record the name and icon for this coding session. Call exactly once, then stop.',
45
- parameters: NAME_SESSION_SCHEMA,
46
- // Ask the provider to constrain sampling to the schema. `prefer` degrades
47
- // silently on a model without strict tool support (`require` would fail the
48
- // whole request); the parent validates and falls back to a local slug
49
- // either way, so this only makes a malformed emission rarer.
50
- constrainedSampling: { type: 'json_schema', strict: 'prefer' },
51
- execute(_id, params) {
52
- try {
53
- mkdirSync(dirname(out), { recursive: true });
54
- writeFileSync(out, JSON.stringify(params ?? {}), 'utf8');
55
- }
56
- catch {
57
- // The parent falls back to a local slug when the file never lands.
58
- }
59
- return {
60
- content: [{ type: 'text', text: 'Recorded.' }],
61
- details: { recorded: true },
62
- terminate: true,
63
- };
64
- },
65
- });
66
- }
67
- export default registerNamingTool;
@@ -1,7 +0,0 @@
1
- export interface ViewScaffoldVars {
2
- id: string;
3
- title: string;
4
- description: string;
5
- }
6
- /** Build every file of a freshly scaffolded dual-target view, keyed by filename. */
7
- export declare function viewScaffold(v: ViewScaffoldVars): Record<string, string>;
@@ -1,172 +0,0 @@
1
- // Scaffold stubs for surface-view authoring. Returns the four files of a dual-target
2
- // view directory — a portable `core.mjs` plus the TUI / web / text presenters —
3
- // that runs as-is via the surface view host (TUI/static snapshot) and the surface
4
- // web server (browser).
5
- //
6
- // Authoring guidance lives INSIDE each stub (the comment block at the top of the
7
- // generated file), so a view author reads the contract right where they edit.
8
- /** Escape a value for embedding inside a single-quoted JS string literal. */
9
- function jsStr(s) {
10
- return s.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
11
- }
12
- /** The portable core: manifest · init · sources · intents. Runs in BOTH Node
13
- * (the TUI host) and the browser (the web bundle) — imports NOTHING. */
14
- function coreStub(v) {
15
- const id = jsStr(v.id);
16
- const title = jsStr(v.title);
17
- const description = jsStr(v.description);
18
- return `// ${v.title} — portable core (manifest · init · sources · intents).
19
- //
20
- // Runs in BOTH Node (the TUI host) and the browser (the web bundle), so it
21
- // imports NOTHING — no \`node:*\`, no crtr. ALL state + behavior live here;
22
- // presenters (tui.mjs / web.jsx) are pure reads that dispatch named intents.
23
- //
24
- // Run it through the surface view host for TUI/static snapshots, or through
25
- // the surface web server for the React + Tailwind browser page.
26
- //
27
- // THE CONTRACT:
28
- // manifest { id, title, description, refreshMs? } — id MUST equal
29
- // this view's directory name.
30
- // init(opts) cheap, SYNCHRONOUS initial state — NO fetch, NO screen.
31
- // CLI flags arrive in \`opts\` (for example port/target options).
32
- // sources { request, parse } READ descriptors. The host's transport
33
- // runs request() (exec/file/http) and hands parse() the bytes
34
- // — your parse is pure, runs in Node AND the browser.
35
- // intents semantic actions both targets dispatch. State updates are
36
- // IMMUTABLE via ctx.set; async effects (ctx.resolve a source)
37
- // live in the same handler. ctx.signal raises chrome signals.
38
-
39
- /** A READ source: a transport-agnostic request + a pure parse. */
40
- export const clockSource = {
41
- id: 'clock',
42
- request: () => ({ kind: 'exec', bin: 'date', args: [] }),
43
- parse: (raw) =>
44
- raw.ok && raw.exitCode === 0
45
- ? { ok: true, data: raw.stdout.trim() }
46
- : { ok: false, error: { kind: 'clock-failed', display: {
47
- headline: 'Could not read the clock',
48
- explanation: raw.stderr || 'the date command failed',
49
- nextStep: 'Check the \`date\` binary is on PATH.',
50
- level: 'error', blocking: true } } },
51
- };
52
-
53
- /** @type {import('@north-light/crouter/dist/core/view/contract.js').ViewCore} */
54
- const core = {
55
- manifest: {
56
- id: '${id}',
57
- title: '${title}',
58
- description: '${description}',
59
- // refreshMs: 30000, // uncomment to auto-poll; omit ⇒ on-demand (g) only
60
- },
61
-
62
- // Cheap, synchronous setup. Stash CLI flags off \`opts\` here.
63
- init: (opts) => ({ count: 0, clock: null, port: opts.port ?? null }),
64
-
65
- sources: { clockSource },
66
-
67
- intents: {
68
- // Async intent: ctx.set updates state immutably; ctx.resolve runs a source
69
- // through the host transport. The host runs 'refresh' on launch, every
70
- // manifest.refreshMs (if set), and on the \`g\` key (see tui.mjs).
71
- async refresh(ctx) {
72
- ctx.signal.setStatus('Reading clock…');
73
- const r = await ctx.resolve(clockSource);
74
- if (!r.ok) { ctx.signal.setBanner(r.error.display.headline, r.error.display.level); ctx.signal.setStatus(null); return; }
75
- ctx.set((s) => ({ ...s, count: s.count + 1, clock: r.data }));
76
- ctx.signal.clearBanner();
77
- ctx.signal.setStatus(\`refreshed \${ctx.state.count}×\`);
78
- },
79
- quit: (ctx) => ctx.signal.quit(),
80
- },
81
- };
82
-
83
- export default core;
84
- `;
85
- }
86
- /** The TUI presenter: render(state, draw, content) + keymap. Node only. */
87
- function tuiStub(v) {
88
- const title = jsStr(v.title);
89
- return `// ${v.title} — TUI presenter: render(state, draw, content) + keymap.
90
- //
91
- // A pure read of state — paint via draw.*; NEVER write ANSI. Keys map to the
92
- // core's intents (no logic here; the keymap names an intent, the host dispatches).
93
- //
94
- // draw API (all absolute cells inside \`content\`):
95
- // draw.text(row,col,text,style?) · draw.spans(row,col,spans,maxWidth?)
96
- // draw.hline(row,fromCol?,toCol?) · draw.box(rect,title?)
97
- // draw.columns(rect,[1,2]) -> Rect[] · draw.list(rect,items,cursor,scroll)
98
- // style: { fg, bg, bold, dim, reverse } (fg/bg honored only when color is on)
99
-
100
- export const keymap = [
101
- { keys: ['g'], intent: 'refresh', hint: { keys: 'g', label: 'refresh' } },
102
- { keys: ['q'], intent: 'quit', hint: { keys: 'q', label: 'quit' } },
103
- ];
104
-
105
- export function render(state, draw, content) {
106
- draw.text(content.row, content.col, '${title}', { bold: true });
107
- draw.text(content.row + 2, content.col, \`clock: \${state.clock ?? '(loading…)'}\`);
108
- draw.text(content.row + 3, content.col, \`refreshed \${state.count} time(s)\`, { dim: true });
109
- draw.text(content.row + 4, content.col, \`port option: \${state.port ?? '(none)'}\`, { dim: true });
110
- draw.text(content.row + 6, content.col, 'Edit core.mjs + tui.mjs to build your view — g refreshes, q quits.', { dim: true });
111
- }
112
- `;
113
- }
114
- /** The web presenter: a React + Tailwind component. Browser only (Vite owns the
115
- * JSX + Tailwind transpile; this file is NEVER Node-imported). */
116
- function webStub(v) {
117
- const title = jsStr(v.title);
118
- return `// ${v.title} — web presenter: a React + Tailwind component.
119
- //
120
- // A pure function of \`state\`; DOM events call \`dispatch(intent)\`. Consumed ONLY
121
- // by the surface web host (Vite owns JSX + Tailwind) — never Node-imported. The
122
- // SAME state + intents the TUI reads; zero shared render code (an intentional fork).
123
-
124
- export default function View({ state, dispatch }) {
125
- return (
126
- <div
127
- className="font-mono text-sm p-4 outline-none"
128
- tabIndex={0}
129
- onKeyDown={(e) => { if (e.key === 'g') dispatch('refresh'); }}
130
- >
131
- <h1 className="text-lg font-bold">${title}</h1>
132
- <p className="mt-2">clock: {state.clock ?? '(loading…)'}</p>
133
- <p className="text-gray-500">refreshed {state.count} time(s)</p>
134
- <button
135
- className="mt-3 rounded bg-blue-600 px-2 py-1 text-white hover:bg-blue-500"
136
- onClick={() => dispatch('refresh')}
137
- >
138
- Refresh
139
- </button>
140
- </div>
141
- );
142
- }
143
- `;
144
- }
145
- /** The text presenter: the piped / non-TTY snapshot. Node only. Optional — omit
146
- * it and the host synthesizes a generic one-line dump. */
147
- function textStub(v) {
148
- const title = jsStr(v.title);
149
- return `// ${v.title} — text presenter: the piped / non-TTY snapshot (exits 0).
150
- //
151
- // A pure read of current state. Omit this file and the host synthesizes a
152
- // one-line dump (\`<title> — <n> items\`).
153
-
154
- export function dump(state) {
155
- return [
156
- '${title}',
157
- '',
158
- \`clock: \${state.clock ?? '(none)'}\`,
159
- \`refreshed \${state.count} time(s)\`,
160
- ].join('\\n');
161
- }
162
- `;
163
- }
164
- /** Build every file of a freshly scaffolded dual-target view, keyed by filename. */
165
- export function viewScaffold(v) {
166
- return {
167
- 'core.mjs': coreStub(v),
168
- 'tui.mjs': tuiStub(v),
169
- 'web.jsx': webStub(v),
170
- 'text.mjs': textStub(v),
171
- };
172
- }