@crouton-kit/crouter 0.3.27 → 0.3.29

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 (343) hide show
  1. package/dist/build-root.js +4 -2
  2. package/dist/builtin-memory/crouter-development/marketplaces.md +7 -6
  3. package/dist/builtin-memory/crouter-development/personas/base-prompt.md +1 -1
  4. package/dist/builtin-memory/crouter-development/personas/orchestrator-prompt.md +1 -1
  5. package/dist/builtin-memory/crouter-development/personas.md +1 -1
  6. package/dist/builtin-memory/crouter-development/plugins.md +20 -18
  7. package/dist/builtin-memory/design.md +1 -1
  8. package/dist/builtin-memory/development.md +1 -1
  9. package/dist/builtin-memory/internal/INDEX.md +1 -1
  10. package/dist/builtin-memory/internal/examples/INDEX.md +1 -1
  11. package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
  12. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  13. package/dist/builtin-memory/internal/storage-tiers.md +1 -1
  14. package/dist/builtin-memory/planning.md +1 -1
  15. package/dist/builtin-memory/spec.md +6 -4
  16. package/dist/builtin-personas/orchestration-kernel.md +4 -5
  17. package/dist/builtin-personas/runtime-base.md +8 -4
  18. package/dist/builtin-personas/spec/PERSONA.md +8 -4
  19. package/dist/builtin-personas/spec/orchestrator.md +5 -3
  20. package/dist/builtin-personas/spec/requirements/PERSONA.md +10 -0
  21. package/dist/builtin-views/canvas/core.mjs +586 -0
  22. package/dist/builtin-views/canvas/text.mjs +58 -0
  23. package/dist/builtin-views/canvas/tui.mjs +165 -0
  24. package/dist/builtin-views/canvas/web.jsx +120 -0
  25. package/dist/builtin-views/git-pr/core.mjs +673 -0
  26. package/dist/builtin-views/git-pr/text.mjs +84 -0
  27. package/dist/builtin-views/git-pr/tui.mjs +302 -0
  28. package/dist/builtin-views/git-pr/web.jsx +216 -0
  29. package/dist/builtin-views/inbox/_lib/render.mjs +1 -3
  30. package/dist/builtin-views/inbox/core.mjs +1273 -0
  31. package/dist/builtin-views/inbox/text.mjs +73 -0
  32. package/dist/builtin-views/inbox/tui.mjs +312 -0
  33. package/dist/builtin-views/inbox/web.jsx +188 -0
  34. package/dist/builtin-views/linkedin/core.mjs +906 -0
  35. package/dist/builtin-views/linkedin/text.mjs +69 -0
  36. package/dist/builtin-views/linkedin/tui.mjs +427 -0
  37. package/dist/builtin-views/linkedin/web.jsx +206 -0
  38. package/dist/builtin-views/workspace-sidebar/core.mjs +621 -0
  39. package/dist/builtin-views/workspace-sidebar/text.mjs +53 -0
  40. package/dist/builtin-views/workspace-sidebar/tui.mjs +142 -0
  41. package/dist/builtin-views/workspace-sidebar/web.jsx +109 -0
  42. package/dist/cli.js +3 -3
  43. package/dist/clients/attach/__tests__/action-parity.test.js +48 -0
  44. package/dist/clients/attach/__tests__/clipboard-image.test.js +76 -0
  45. package/dist/clients/attach/__tests__/editor-newline.test.js +57 -0
  46. package/dist/clients/attach/__tests__/git-info.test.js +31 -0
  47. package/dist/clients/attach/__tests__/onrequest-wired.test.js +20 -0
  48. package/dist/clients/attach/__tests__/reconnect-giveup.test.js +30 -0
  49. package/dist/clients/attach/__tests__/slash-quit-copy.test.js +42 -0
  50. package/dist/clients/attach/__tests__/titled-editor.test.d.ts +1 -0
  51. package/dist/clients/attach/__tests__/titled-editor.test.js +39 -0
  52. package/dist/clients/attach/attach-cmd.js +445 -41
  53. package/dist/clients/attach/auth-pickers.d.ts +9 -0
  54. package/dist/clients/attach/auth-pickers.js +194 -0
  55. package/dist/clients/attach/canvas-panels.d.ts +12 -0
  56. package/dist/clients/attach/canvas-panels.js +78 -0
  57. package/dist/clients/attach/chat-view.d.ts +27 -2
  58. package/dist/clients/attach/chat-view.js +98 -9
  59. package/dist/clients/attach/clipboard-image.d.ts +47 -8
  60. package/dist/clients/attach/clipboard-image.js +150 -26
  61. package/dist/clients/attach/clipboard-text.d.ts +3 -0
  62. package/dist/clients/attach/clipboard-text.js +39 -0
  63. package/dist/clients/attach/config-load.d.ts +54 -7
  64. package/dist/clients/attach/config-load.js +99 -3
  65. package/dist/clients/attach/context-message.d.ts +12 -0
  66. package/dist/clients/attach/context-message.js +72 -0
  67. package/dist/clients/attach/git-info.d.ts +20 -0
  68. package/dist/clients/attach/git-info.js +44 -0
  69. package/dist/clients/attach/graph-overlay.d.ts +43 -0
  70. package/dist/clients/attach/graph-overlay.js +306 -0
  71. package/dist/clients/attach/input-controller.d.ts +81 -13
  72. package/dist/clients/attach/input-controller.js +307 -67
  73. package/dist/clients/attach/pickers.d.ts +58 -0
  74. package/dist/clients/attach/pickers.js +171 -0
  75. package/dist/clients/attach/slash-commands.d.ts +44 -1
  76. package/dist/clients/attach/slash-commands.js +250 -27
  77. package/dist/clients/attach/titled-editor.d.ts +33 -0
  78. package/dist/clients/attach/titled-editor.js +84 -0
  79. package/dist/clients/attach/view-socket.d.ts +37 -2
  80. package/dist/clients/attach/view-socket.js +131 -7
  81. package/dist/clients/web/dev-server.d.ts +7 -0
  82. package/dist/clients/web/dev-server.js +59 -0
  83. package/dist/clients/web/events.d.ts +14 -0
  84. package/dist/clients/web/events.js +151 -0
  85. package/dist/clients/web/server.d.ts +18 -0
  86. package/dist/clients/web/server.js +450 -0
  87. package/dist/clients/web/web-cmd.d.ts +2 -0
  88. package/dist/clients/web/web-cmd.js +120 -0
  89. package/dist/commands/canvas.js +1 -2
  90. package/dist/commands/chord.js +1 -1
  91. package/dist/commands/dashboard.js +5 -1
  92. package/dist/commands/human/prompts.js +3 -3
  93. package/dist/commands/human/queue.d.ts +17 -0
  94. package/dist/commands/human/queue.js +111 -4
  95. package/dist/commands/memory/__tests__/lint-schema.test.js +27 -4
  96. package/dist/commands/memory/lint.d.ts +5 -4
  97. package/dist/commands/memory/lint.js +23 -7
  98. package/dist/commands/memory/read.js +2 -2
  99. package/dist/commands/memory/shared.d.ts +7 -1
  100. package/dist/commands/memory/shared.js +18 -3
  101. package/dist/commands/memory/write.js +20 -7
  102. package/dist/commands/memory.js +4 -4
  103. package/dist/commands/node.d.ts +1 -1
  104. package/dist/commands/node.js +64 -65
  105. package/dist/commands/pkg.js +1 -2
  106. package/dist/commands/revive.js +11 -3
  107. package/dist/commands/sys/feedback.d.ts +1 -0
  108. package/dist/commands/sys/feedback.js +163 -0
  109. package/dist/commands/sys/sync.d.ts +1 -0
  110. package/dist/commands/sys/sync.js +187 -0
  111. package/dist/commands/sys.js +4 -2
  112. package/dist/commands/view-cycle.js +2 -2
  113. package/dist/commands/view-list.js +8 -8
  114. package/dist/commands/view-new.js +21 -17
  115. package/dist/commands/view-pick.js +1 -1
  116. package/dist/commands/view-run.js +35 -14
  117. package/dist/commands/view.js +8 -6
  118. package/dist/commands/workspace.d.ts +2 -0
  119. package/dist/commands/workspace.js +161 -0
  120. package/dist/core/__tests__/broker-double-spawn.test.d.ts +1 -0
  121. package/dist/core/__tests__/broker-double-spawn.test.js +143 -0
  122. package/dist/core/__tests__/broker-fork-seam.test.d.ts +1 -0
  123. package/dist/core/__tests__/broker-fork-seam.test.js +102 -0
  124. package/dist/core/__tests__/broker-sdk-wiring.test.js +2 -0
  125. package/dist/core/__tests__/broker-snapshot-history.test.d.ts +1 -0
  126. package/dist/core/__tests__/broker-snapshot-history.test.js +105 -0
  127. package/dist/core/__tests__/child-death-wake.test.js +56 -111
  128. package/dist/core/__tests__/close.test.js +14 -20
  129. package/dist/core/__tests__/context-intro.test.js +19 -19
  130. package/dist/core/__tests__/daemon-boot.test.js +30 -23
  131. package/dist/core/__tests__/draw-style.test.js +1 -1
  132. package/dist/core/__tests__/error-stall-recycle.test.d.ts +1 -0
  133. package/dist/core/__tests__/error-stall-recycle.test.js +141 -0
  134. package/dist/core/__tests__/fixtures/fake-engine.d.ts +24 -1
  135. package/dist/core/__tests__/fixtures/fake-engine.js +32 -2
  136. package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
  137. package/dist/core/__tests__/focuses.test.js +25 -13
  138. package/dist/core/__tests__/fork.test.js +22 -5
  139. package/dist/core/__tests__/full/broker-control-preempt.test.d.ts +1 -0
  140. package/dist/core/__tests__/full/broker-control-preempt.test.js +61 -0
  141. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +1 -0
  142. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +57 -0
  143. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +1 -0
  144. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +80 -0
  145. package/dist/core/__tests__/full/broker-pane-resolution.test.js +90 -0
  146. package/dist/core/__tests__/full/cascade-close.test.js +22 -8
  147. package/dist/core/__tests__/full/detach-focus.test.js +66 -169
  148. package/dist/core/__tests__/helpers/harness.d.ts +6 -9
  149. package/dist/core/__tests__/helpers/harness.js +19 -36
  150. package/dist/core/__tests__/human-node-not-supervised.test.d.ts +1 -0
  151. package/dist/core/__tests__/human-node-not-supervised.test.js +83 -0
  152. package/dist/core/__tests__/human-stranded-deliver.test.d.ts +1 -0
  153. package/dist/core/__tests__/human-stranded-deliver.test.js +108 -0
  154. package/dist/core/__tests__/lifecycle.test.js +1 -19
  155. package/dist/core/__tests__/live-mutation-verbs.test.js +5 -5
  156. package/dist/core/__tests__/memory-resolver.test.js +1 -1
  157. package/dist/core/__tests__/on-read-dedup-resume.test.d.ts +1 -0
  158. package/dist/core/__tests__/on-read-dedup-resume.test.js +81 -0
  159. package/dist/core/__tests__/refresh-stall-recycle.test.d.ts +1 -0
  160. package/dist/core/__tests__/refresh-stall-recycle.test.js +88 -0
  161. package/dist/core/__tests__/relaunch-root.test.d.ts +1 -0
  162. package/dist/core/__tests__/relaunch-root.test.js +114 -0
  163. package/dist/core/__tests__/reset.test.js +19 -79
  164. package/dist/core/__tests__/steer-note.test.js +9 -7
  165. package/dist/core/__tests__/tmux-surface.test.js +13 -7
  166. package/dist/core/bootstrap.d.ts +0 -3
  167. package/dist/core/bootstrap.js +1 -143
  168. package/dist/core/canvas/browse/__tests__/model.test.js +86 -1
  169. package/dist/core/canvas/browse/__tests__/render.test.js +2 -1
  170. package/dist/core/canvas/browse/app.js +131 -8
  171. package/dist/core/canvas/browse/model.d.ts +23 -5
  172. package/dist/core/canvas/browse/model.js +68 -13
  173. package/dist/core/canvas/browse/render.d.ts +7 -1
  174. package/dist/core/canvas/browse/render.js +178 -47
  175. package/dist/core/canvas/canvas.js +1 -1
  176. package/dist/core/canvas/focuses.d.ts +4 -4
  177. package/dist/core/canvas/focuses.js +7 -7
  178. package/dist/core/canvas/nav-model.d.ts +162 -0
  179. package/dist/core/canvas/nav-model.js +487 -0
  180. package/dist/core/canvas/paths.d.ts +7 -0
  181. package/dist/core/canvas/paths.js +9 -0
  182. package/dist/core/canvas/render.d.ts +68 -9
  183. package/dist/core/canvas/render.js +195 -61
  184. package/dist/core/canvas/types.d.ts +16 -23
  185. package/dist/core/config.js +1 -4
  186. package/dist/core/memory-resolver.js +43 -5
  187. package/dist/core/runtime/bearings.d.ts +1 -1
  188. package/dist/core/runtime/bearings.js +8 -8
  189. package/dist/core/runtime/branded-host.d.ts +16 -0
  190. package/dist/core/runtime/branded-host.js +127 -0
  191. package/dist/core/runtime/broker-protocol.d.ts +212 -6
  192. package/dist/core/runtime/broker-sdk.d.ts +0 -12
  193. package/dist/core/runtime/broker-sdk.js +77 -6
  194. package/dist/core/runtime/broker.d.ts +5 -1
  195. package/dist/core/runtime/broker.js +520 -59
  196. package/dist/core/runtime/close.d.ts +12 -2
  197. package/dist/core/runtime/close.js +37 -16
  198. package/dist/core/runtime/front-door.js +14 -7
  199. package/dist/core/runtime/host.d.ts +14 -34
  200. package/dist/core/runtime/host.js +14 -50
  201. package/dist/core/runtime/launch.d.ts +12 -9
  202. package/dist/core/runtime/launch.js +27 -15
  203. package/dist/core/runtime/lifecycle.d.ts +1 -1
  204. package/dist/core/runtime/lifecycle.js +15 -19
  205. package/dist/core/runtime/nodes.d.ts +0 -55
  206. package/dist/core/runtime/nodes.js +6 -74
  207. package/dist/core/runtime/placement.d.ts +91 -334
  208. package/dist/core/runtime/placement.js +262 -828
  209. package/dist/core/runtime/promote.d.ts +2 -0
  210. package/dist/core/runtime/promote.js +24 -6
  211. package/dist/core/runtime/recap.d.ts +8 -0
  212. package/dist/core/runtime/recap.js +107 -0
  213. package/dist/core/runtime/recycle.js +25 -61
  214. package/dist/core/runtime/reset.d.ts +43 -37
  215. package/dist/core/runtime/reset.js +131 -218
  216. package/dist/core/runtime/revive.d.ts +9 -29
  217. package/dist/core/runtime/revive.js +45 -135
  218. package/dist/core/runtime/spawn.d.ts +15 -11
  219. package/dist/core/runtime/spawn.js +168 -136
  220. package/dist/core/runtime/surface-bg.d.ts +11 -0
  221. package/dist/core/runtime/surface-bg.js +68 -0
  222. package/dist/core/runtime/tmux.d.ts +15 -43
  223. package/dist/core/runtime/tmux.js +38 -80
  224. package/dist/core/scope.d.ts +1 -2
  225. package/dist/core/scope.js +1 -5
  226. package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.d.ts +1 -0
  227. package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.js +57 -0
  228. package/dist/core/skill-sync/builtins.d.ts +42 -0
  229. package/dist/core/skill-sync/builtins.js +112 -0
  230. package/dist/core/skill-sync/claude-plugins.d.ts +23 -0
  231. package/dist/core/skill-sync/claude-plugins.js +71 -0
  232. package/dist/core/skill-sync/engine.d.ts +42 -0
  233. package/dist/core/skill-sync/engine.js +633 -0
  234. package/dist/core/skill-sync/export.d.ts +23 -0
  235. package/dist/core/skill-sync/export.js +86 -0
  236. package/dist/core/skill-sync/manifest.d.ts +64 -0
  237. package/dist/core/skill-sync/manifest.js +181 -0
  238. package/dist/core/skill-sync/profile.d.ts +76 -0
  239. package/dist/core/skill-sync/profile.js +173 -0
  240. package/dist/core/skill-sync/snapshot.d.ts +57 -0
  241. package/dist/core/skill-sync/snapshot.js +120 -0
  242. package/dist/core/spawn.d.ts +14 -0
  243. package/dist/core/spawn.js +29 -9
  244. package/dist/core/substrate/index.d.ts +2 -2
  245. package/dist/core/substrate/index.js +7 -7
  246. package/dist/core/substrate/injected-store.d.ts +10 -0
  247. package/dist/core/substrate/injected-store.js +55 -0
  248. package/dist/core/substrate/on-read.js +68 -6
  249. package/dist/core/substrate/render.d.ts +8 -11
  250. package/dist/core/substrate/render.js +29 -43
  251. package/dist/core/substrate/schema.d.ts +16 -11
  252. package/dist/core/substrate/schema.js +32 -31
  253. package/dist/core/tui/host.d.ts +12 -4
  254. package/dist/core/tui/host.js +280 -149
  255. package/dist/core/view/bridge.d.ts +10 -0
  256. package/dist/core/view/bridge.js +31 -0
  257. package/dist/core/view/chrome.d.ts +9 -0
  258. package/dist/core/view/chrome.js +22 -0
  259. package/dist/core/view/contract.d.ts +171 -0
  260. package/dist/core/view/contract.js +23 -0
  261. package/dist/core/view/loader.d.ts +31 -0
  262. package/dist/core/view/loader.js +188 -0
  263. package/dist/core/view/transport-local.d.ts +7 -0
  264. package/dist/core/view/transport-local.js +70 -0
  265. package/dist/core/view/transport.d.ts +4 -0
  266. package/dist/core/view/transport.js +15 -0
  267. package/dist/daemon/crtrd.d.ts +38 -27
  268. package/dist/daemon/crtrd.js +303 -376
  269. package/dist/daemon/manage.js +6 -1
  270. package/dist/index.js +1 -1
  271. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +28 -20
  272. package/dist/pi-extensions/canvas-context-intro.js +4 -4
  273. package/dist/pi-extensions/canvas-doc-substrate.js +29 -20
  274. package/dist/pi-extensions/canvas-nav.js +35 -385
  275. package/dist/pi-extensions/canvas-recap.d.ts +37 -0
  276. package/dist/pi-extensions/canvas-recap.js +236 -0
  277. package/dist/pi-extensions/canvas-resume.js +2 -1
  278. package/dist/pi-extensions/canvas-stophook.d.ts +15 -13
  279. package/dist/pi-extensions/canvas-stophook.js +119 -103
  280. package/dist/pi-extensions/canvas-view.js +2 -1
  281. package/dist/pi-extensions/widget-order-bus.d.ts +6 -0
  282. package/dist/pi-extensions/widget-order-bus.js +34 -0
  283. package/dist/prompts/view.d.ts +2 -2
  284. package/dist/prompts/view.js +145 -73
  285. package/dist/types.d.ts +1 -6
  286. package/dist/types.js +1 -3
  287. package/dist/web/ViewChrome.d.ts +7 -0
  288. package/dist/web/ViewChrome.js +28 -0
  289. package/dist/web/ViewPane.d.ts +39 -0
  290. package/dist/web/ViewPane.js +48 -0
  291. package/dist/web/index.d.ts +6 -0
  292. package/dist/web/index.js +16 -0
  293. package/dist/web/runtime.d.ts +39 -0
  294. package/dist/web/runtime.js +133 -0
  295. package/dist/web/states.d.ts +24 -0
  296. package/dist/web/states.js +24 -0
  297. package/dist/web/transport-http.d.ts +5 -0
  298. package/dist/web/transport-http.js +28 -0
  299. package/dist/web-client/assets/index-BUvQb4hR.css +2 -0
  300. package/dist/web-client/assets/index-ClLQXYAE.js +10 -0
  301. package/dist/web-client/index.html +13 -0
  302. package/package.json +20 -6
  303. package/dist/builtin-views/canvas/client.mjs +0 -303
  304. package/dist/builtin-views/canvas/view.mjs +0 -576
  305. package/dist/builtin-views/git-pr/client.mjs +0 -440
  306. package/dist/builtin-views/git-pr/view.mjs +0 -675
  307. package/dist/builtin-views/inbox/sources/gmail.mjs +0 -965
  308. package/dist/builtin-views/inbox/sources/linkedin.mjs +0 -427
  309. package/dist/builtin-views/inbox/view.mjs +0 -889
  310. package/dist/builtin-views/linkedin/client.mjs +0 -610
  311. package/dist/builtin-views/linkedin/view.mjs +0 -1171
  312. package/dist/commands/pkg/bridge.d.ts +0 -1
  313. package/dist/commands/pkg/bridge.js +0 -137
  314. package/dist/commands/skill/author.d.ts +0 -3
  315. package/dist/commands/skill/author.js +0 -140
  316. package/dist/commands/skill/shared.d.ts +0 -3
  317. package/dist/commands/skill/shared.js +0 -19
  318. package/dist/commands/skill.d.ts +0 -2
  319. package/dist/commands/skill.js +0 -21
  320. package/dist/commands/tmux-spread.d.ts +0 -2
  321. package/dist/commands/tmux-spread.js +0 -144
  322. package/dist/core/__tests__/full/daemon-liveness-pane.full.test.js +0 -292
  323. package/dist/core/__tests__/full/placement-focus.test.js +0 -309
  324. package/dist/core/__tests__/full/placement-reconcile.test.js +0 -212
  325. package/dist/core/__tests__/full/placement-revive.test.js +0 -238
  326. package/dist/core/__tests__/full/placement-teardown.test.js +0 -221
  327. package/dist/core/__tests__/home-session.test.js +0 -186
  328. package/dist/core/__tests__/relaunch.test.js +0 -335
  329. package/dist/core/bridge-map.d.ts +0 -19
  330. package/dist/core/bridge-map.js +0 -73
  331. package/dist/core/tui/contract.d.ts +0 -83
  332. package/dist/core/tui/contract.js +0 -8
  333. package/dist/core/tui/loader.d.ts +0 -16
  334. package/dist/core/tui/loader.js +0 -94
  335. package/dist/prompts/skill.d.ts +0 -2
  336. package/dist/prompts/skill.js +0 -650
  337. /package/dist/{core/__tests__/full/daemon-liveness-pane.full.test.d.ts → clients/attach/__tests__/action-parity.test.d.ts} +0 -0
  338. /package/dist/{core/__tests__/full/placement-focus.test.d.ts → clients/attach/__tests__/clipboard-image.test.d.ts} +0 -0
  339. /package/dist/{core/__tests__/full/placement-reconcile.test.d.ts → clients/attach/__tests__/editor-newline.test.d.ts} +0 -0
  340. /package/dist/{core/__tests__/full/placement-revive.test.d.ts → clients/attach/__tests__/git-info.test.d.ts} +0 -0
  341. /package/dist/{core/__tests__/full/placement-teardown.test.d.ts → clients/attach/__tests__/onrequest-wired.test.d.ts} +0 -0
  342. /package/dist/{core/__tests__/home-session.test.d.ts → clients/attach/__tests__/reconnect-giveup.test.d.ts} +0 -0
  343. /package/dist/{core/__tests__/relaunch.test.d.ts → clients/attach/__tests__/slash-quit-copy.test.d.ts} +0 -0
@@ -0,0 +1,236 @@
1
+ // canvas-recap.ts — pi extension for pi-native canvas agent nodes.
2
+ //
3
+ // A per-node INACTIVITY RECAP, drawn as the topmost chrome above the editor.
4
+ // When a node has had NO new message (user or assistant) for IDLE_MS (300s by
5
+ // default), it runs Haiku over the literal conversation and pins a terse
6
+ // three-fragment card — goal / doing-now / next — above canvas-nav's manager
7
+ // line. The card disappears the instant the next message arrives, and the idle
8
+ // clock restarts.
9
+ //
10
+ // trigger/clear are keyed off MESSAGES, not turns-of-work:
11
+ // • a user `input` event OR an assistant `turn_end` resets the idle clock
12
+ // and clears any shown recap.
13
+ // • a single low-rate timer (no busy-loop) checks elapsed-since-last-message
14
+ // and, on crossing IDLE_MS, generates + shows the recap once.
15
+ //
16
+ // Haiku input = ALL user + assistant LITERAL text, most-recent within a char
17
+ // budget. Tool calls, tool results, thinking blocks, and extension-injected
18
+ // custom messages are excluded (only `message` entries with role user/assistant,
19
+ // and only their `text` content blocks).
20
+ //
21
+ // Placement: key `crtr-recap`, placement `aboveEditor`, ordered ABOVE
22
+ // `crtr-managers` via the widget-order bus (pi's widget store is insertion-
23
+ // ordered and re-setting moves a key to the bottom; after we paint the recap
24
+ // we ask canvas-nav to re-assert its manager line, which drops it below us).
25
+ //
26
+ // Surface gating: shows in BOTH the in-pane pi TUI (mode 'tui') and the
27
+ // headless broker → attach/web viewers (mode 'print', setWidget broadcasts to
28
+ // all surfaces). It does NOT gate on mode === 'tui' (that would kill the
29
+ // headless+attach path). It NO-OPs only when ui/setWidget is unavailable, and
30
+ // harmlessly in a true one-shot `pi -p` (the unref'd timer never fires before
31
+ // the process exits, and naming-style one-shots load with --no-extensions).
32
+ //
33
+ // INERT when CRTR_NODE_ID is absent (a plain pi session or legacy job agent).
34
+ //
35
+ // Plain TS-with-types — no imports from @earendil-works/* so this compiles
36
+ // inside crouter's own tsc build without a dep on the pi packages.
37
+ import { generateRecap } from '../core/runtime/recap.js';
38
+ import { requestNavRerender } from './widget-order-bus.js';
39
+ // ---------------------------------------------------------------------------
40
+ // Tuning constants
41
+ // ---------------------------------------------------------------------------
42
+ /** No-new-message window before a recap is shown. 300s by default; override with
43
+ * CRTR_RECAP_IDLE_MS (for fast runtime verification). */
44
+ function idleMs() {
45
+ const raw = process.env['CRTR_RECAP_IDLE_MS'];
46
+ const n = raw !== undefined ? parseInt(raw, 10) : NaN;
47
+ return Number.isFinite(n) && n > 0 ? n : 300_000;
48
+ }
49
+ /** How often the (single, low-rate) timer checks elapsed-since-last-message.
50
+ * Mirrors canvas-nav's ASK_POLL_MS — cheap and tmux/crtr-free. */
51
+ const POLL_MS = 7_000;
52
+ /** Char budget on the conversation fed to Haiku — the model only needs the gist,
53
+ * so we keep the MOST-RECENT text within this cap (a recap is about where we
54
+ * left off, not the whole history). */
55
+ const CONVO_CHAR_BUDGET = 12_000;
56
+ const WIDGET_KEY = 'crtr-recap';
57
+ // ---------------------------------------------------------------------------
58
+ // Module-level state — persists across /reload so the timer doesn't stack.
59
+ // ---------------------------------------------------------------------------
60
+ /** The one live poll timer. Cleared and replaced on every re-registration. */
61
+ let liveTimer;
62
+ // ---------------------------------------------------------------------------
63
+ // Conversation extraction — literal user+assistant text ONLY.
64
+ // ---------------------------------------------------------------------------
65
+ /** Pull the literal text out of a message's content (string or text blocks),
66
+ * dropping non-text blocks (thinking, toolCall, image). */
67
+ function messageText(msg) {
68
+ const c = msg.content;
69
+ if (typeof c === 'string')
70
+ return c.trim();
71
+ if (!Array.isArray(c))
72
+ return '';
73
+ return c
74
+ .filter((b) => b !== null && typeof b === 'object' && b.type === 'text' && typeof b.text === 'string')
75
+ .map((b) => (b.text ?? '').trim())
76
+ .filter((t) => t !== '')
77
+ .join('\n')
78
+ .trim();
79
+ }
80
+ /** Concatenate the conversation's user + assistant literal text into a single
81
+ * `User:`/`Agent:` transcript, keeping only the MOST-RECENT CONVO_CHAR_BUDGET
82
+ * characters. Excludes tool calls/results (role toolResult, plus toolCall/
83
+ * thinking content blocks dropped by messageText) and extension-injected
84
+ * custom messages (entry.type !== 'message'). Returns '' when there is nothing
85
+ * to summarize. */
86
+ function buildConversation(sm) {
87
+ let entries;
88
+ try {
89
+ entries = sm.getEntries();
90
+ }
91
+ catch {
92
+ return '';
93
+ }
94
+ const parts = [];
95
+ for (const e of entries) {
96
+ if (e.type !== 'message' || e.message === undefined)
97
+ continue;
98
+ const role = e.message.role;
99
+ if (role !== 'user' && role !== 'assistant')
100
+ continue; // drop toolResult etc.
101
+ const text = messageText(e.message);
102
+ if (text === '')
103
+ continue;
104
+ parts.push(`${role === 'user' ? 'User' : 'Agent'}: ${text}`);
105
+ }
106
+ if (parts.length === 0)
107
+ return '';
108
+ const full = parts.join('\n\n');
109
+ return full.length > CONVO_CHAR_BUDGET ? full.slice(full.length - CONVO_CHAR_BUDGET) : full;
110
+ }
111
+ // ---------------------------------------------------------------------------
112
+ // Extension
113
+ // ---------------------------------------------------------------------------
114
+ /**
115
+ * Register the inactivity-recap chrome on `pi`.
116
+ *
117
+ * Returns immediately (inert) when CRTR_NODE_ID is absent — a plain pi session
118
+ * or legacy job agent loads it as a no-op.
119
+ */
120
+ export function registerCanvasRecap(pi) {
121
+ const nodeId = process.env['CRTR_NODE_ID'];
122
+ if (nodeId === undefined || nodeId.trim() === '')
123
+ return; // not a canvas node
124
+ // Captured on session_start; used by the timer and the message handlers.
125
+ let ui;
126
+ let sessionManager;
127
+ /** Wall-clock of the most recent user/assistant message. The idle clock. */
128
+ let lastMessageAt = Date.now();
129
+ /** True while a recap is currently shown (so we generate at most once per
130
+ * idle window, and know whether a clear is needed on the next message). */
131
+ let recapShown = false;
132
+ /** True while a Haiku generation is in flight (so we don't fire a second). */
133
+ let generating = false;
134
+ const canPaint = () => ui !== undefined && typeof ui.setWidget === 'function';
135
+ const clearRecap = () => {
136
+ if (!canPaint())
137
+ return;
138
+ try {
139
+ ui.setWidget(WIDGET_KEY, undefined, { placement: 'aboveEditor' });
140
+ }
141
+ catch { /* best-effort */ }
142
+ };
143
+ /** Render the three fragments as the topmost above-editor card. */
144
+ const showRecap = (fragments) => {
145
+ if (!canPaint())
146
+ return;
147
+ const labels = ['◷ goal', '· now ', '→ next'];
148
+ const lines = fragments.slice(0, 3).map((f, i) => `${labels[i] ?? ' '} ${f}`);
149
+ if (lines.length === 0)
150
+ return;
151
+ try {
152
+ ui.setWidget(WIDGET_KEY, lines, { placement: 'aboveEditor' });
153
+ }
154
+ catch { /* best-effort */ }
155
+ // Re-assert the manager line BELOW us (pi's widget store is insertion-
156
+ // ordered; re-setting crtr-managers drops it under crtr-recap).
157
+ requestNavRerender();
158
+ };
159
+ /** A user or assistant message landed: reset the idle clock and clear any
160
+ * shown recap (the conversation has moved on). */
161
+ const onMessage = () => {
162
+ lastMessageAt = Date.now();
163
+ if (recapShown) {
164
+ recapShown = false;
165
+ clearRecap();
166
+ requestNavRerender();
167
+ }
168
+ };
169
+ // -------------------------------------------------------------------------
170
+ // Events
171
+ // -------------------------------------------------------------------------
172
+ pi.on('session_start', (_event, ctx) => {
173
+ ui = ctx.ui;
174
+ sessionManager = ctx.sessionManager;
175
+ // Fresh session / hot-swap: start the idle clock now and drop any stale
176
+ // recap that bled through a /reload.
177
+ lastMessageAt = Date.now();
178
+ recapShown = false;
179
+ generating = false;
180
+ clearRecap();
181
+ });
182
+ pi.on('input', (_event, _ctx) => {
183
+ // Every user message (any source) is activity — reset + clear.
184
+ onMessage();
185
+ });
186
+ pi.on('turn_end', (_event, _ctx) => {
187
+ // A completed assistant turn is activity — reset + clear.
188
+ onMessage();
189
+ });
190
+ // -------------------------------------------------------------------------
191
+ // The single low-rate idle poll — no busy-loop, mirrors canvas-nav's timer.
192
+ // -------------------------------------------------------------------------
193
+ if (liveTimer !== undefined)
194
+ clearInterval(liveTimer);
195
+ const timer = setInterval(() => {
196
+ try {
197
+ if (!canPaint() || sessionManager === undefined)
198
+ return;
199
+ if (recapShown || generating)
200
+ return;
201
+ if (Date.now() - lastMessageAt < idleMs())
202
+ return;
203
+ const convo = buildConversation(sessionManager);
204
+ if (convo === '')
205
+ return; // nothing to summarize yet
206
+ // Snapshot the clock: if a message arrives while Haiku runs, discard the
207
+ // (now-stale) result instead of painting over the live conversation.
208
+ const startedAt = lastMessageAt;
209
+ generating = true;
210
+ generateRecap(convo, (fragments) => {
211
+ generating = false;
212
+ if (lastMessageAt !== startedAt)
213
+ return; // a message landed mid-flight
214
+ if (!canPaint())
215
+ return;
216
+ recapShown = true;
217
+ showRecap(fragments);
218
+ });
219
+ // generateRecap is silent on failure (never calls back), so clear the
220
+ // in-flight flag after the timeout window even if no callback fires.
221
+ setTimeout(() => { generating = false; }, 30_000).unref?.();
222
+ }
223
+ catch {
224
+ /* timer is best-effort */
225
+ }
226
+ }, POLL_MS);
227
+ if (typeof timer.unref === 'function')
228
+ timer.unref();
229
+ liveTimer = timer;
230
+ pi.on('session_shutdown', () => {
231
+ clearInterval(timer);
232
+ if (liveTimer === timer)
233
+ liveTimer = undefined;
234
+ });
235
+ }
236
+ export default registerCanvasRecap;
@@ -27,6 +27,7 @@
27
27
  // inside crouter's own tsc build without a dep on the pi packages (mirrors
28
28
  // canvas-nav.ts / canvas-commands.ts).
29
29
  import { execFile } from 'node:child_process';
30
+ import { surfaceTmuxStyleArgs } from '../core/runtime/surface-bg.js';
30
31
  /** Single-quote a string for safe interpolation into a `sh -c` command line —
31
32
  * tmux runs the display-popup trailing string through the shell, so a cwd with
32
33
  * spaces or quotes must be escaped. */
@@ -66,7 +67,7 @@ export function registerCanvasResume(pi) {
66
67
  const cwd = shellQuote(process.cwd());
67
68
  const cmd = `crtr canvas browse --return-pane ${origPane} --cwd ${cwd}`;
68
69
  try {
69
- execFile('tmux', ['display-popup', '-E', '-w', '90%', '-h', '85%', cmd], () => { });
70
+ execFile('tmux', ['display-popup', '-E', '-w', '90%', '-h', '85%', ...surfaceTmuxStyleArgs(), cmd], () => { });
70
71
  }
71
72
  catch { /* best-effort */ }
72
73
  return;
@@ -1,4 +1,4 @@
1
- type PiEvents = 'agent_start' | 'turn_end' | 'agent_end' | 'session_shutdown' | 'session_start';
1
+ type PiEvents = 'agent_start' | 'turn_end' | 'agent_end' | 'session_shutdown' | 'session_start' | 'tool_execution_start';
2
2
  interface PiLike {
3
3
  on: (event: PiEvents, handler: (event: any, ctx: any) => void | Promise<void>) => void;
4
4
  sendUserMessage: (content: string, options?: {
@@ -6,20 +6,22 @@ interface PiLike {
6
6
  }) => void;
7
7
  }
8
8
  /** The nudge text for a crossed band, specialized to the node's (mode,
9
- * lifecycle) persona + how far along the escalation it is.
9
+ * lifecycle) persona + how far along the escalation it is. `crtr node yield` is
10
+ * the single "keep going past this window" verb for every persona: it refreshes
11
+ * the node into a clean window against a roadmap, and for a base node
12
+ * auto-promotes transparently — so no persona is ever steered at a bare `node
13
+ * promote` (which framed promotion as a heavy "become an orchestrator" step and
14
+ * bred yield-avoidance).
10
15
  *
11
- * - orchestrator (terminal OR resident): checkpoint its roadmap and yield
12
- * (gently firmly → pushy). It has a context/roadmap.md to yield against.
13
- * - resident/base (root conversation): never promoted, so NO roadmap exists
14
- * steer it to PROMOTE if the chat is growing into a multi-phase job (which
15
- * seeds a roadmap), else wrap up / start fresh. Never points at roadmap.md or
16
- * a bare `node yield`, which for a roadmap-less root just drops context.
17
- * - terminal/base (worker): PROMOTE itself — become an orchestrator — when
18
- * work remains, with an "ignore if nearly done, finish with push final" once
19
- * it's deeper in.
16
+ * - orchestrator (terminal OR resident): checkpoint context/roadmap.md, then
17
+ * yield (it already has a roadmap to bring current first).
18
+ * - resident/base (root conversation): yield to continue in a fresh window if
19
+ * the chat is growing into a job, else wrap up — a root can simply end.
20
+ * - terminal/base (worker): yield to continue if work remains, or `push final`
21
+ * when close.
20
22
  *
21
- * At/past 185k every persona goes PUSHY: the context is long enough that
22
- * drifting further risks an overflow. */
23
+ * The wording strengthens with depth: gentle < 150k firm < 185k → pushy at/
24
+ * past 185k, where drifting further risks an overflow. */
23
25
  export declare function steerNote(at: number, lifecycle: string, mode: string): string;
24
26
  /**
25
27
  * Register the canvas turn_end / agent_end handlers on `pi`.