@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
@@ -1,28 +1,27 @@
1
- // The revive primitive — restores a node to active status under a fresh tmux
2
- // window. Used by both the supervisor daemon (on crash/refresh detection) and
3
- // the explicit `crtr canvas revive` command.
1
+ // The revive primitive — restores a node to active status by relaunching its
2
+ // broker engine. Used by both the supervisor daemon (on crash/refresh
3
+ // detection) and the explicit `crtr canvas revive` command.
4
4
  //
5
5
  // A revive replays the node's persisted LaunchSpec + cwd (the canonical recipe)
6
- // and routes PLACEMENT through reviveIntoPlacement (§1.4): a non-focused node
7
- // opens a fresh background window in its home_session (the backstage `crtr` for
8
- // a child NEVER a user session); a node that occupies a LIVE focus resumes IN
9
- // PLACE in that focus pane (respawn-pane -k, no new window). reviveNode never
10
- // targets meta.tmux_session, so a background revive can no longer open an
11
- // unbidden window in the user's session.
6
+ // and launches the headless broker host (the only host after the
7
+ // broker-is-the-host cut). It opens NO viewer it relaunches the engine only;
8
+ // existing viewer panes reconnect to the fresh broker on their own (attach
9
+ // auto-reconnect), and a node with no viewer is brought on screen by the next
10
+ // `focus`.
12
11
  //
13
12
  // resume=true → `pi --session <path|id>` — wakes the saved conversation,
14
13
  // preferring the absolute session-file path (cwd-immune) over
15
14
  // the bare session id.
16
15
  // resume=false → fresh pi invocation — the node re-reads its roadmap/context dir.
17
- import { getNode, updateNode, setPresence, clearPid, fullName, cancelDeadlinesFor, } from '../canvas/index.js';
16
+ //
17
+ // reviveNode remains the ONLY sanctioned launcher of the node engine.
18
+ import { getNode, updateNode, clearPid, fullName, cancelDeadlinesFor, } from '../canvas/index.js';
18
19
  import { transition } from './lifecycle.js';
19
20
  import { buildPiArgv } from './launch.js';
20
21
  import { buildReviveKickoff, drainBearings } from './kickoff.js';
21
- import { FRONT_DOOR_ENV } from './front-door.js';
22
- import { reconcile, piCommand, respawnPane, } from './placement.js';
23
- import { hostFor } from './host.js';
24
- import { nodeSession, childBackstageOf, rootOfSpine } from './nodes.js';
22
+ import { headlessBrokerHost } from './host.js';
25
23
  import { isPidAlive } from '../canvas/pid.js';
24
+ import { clearInjectedDocs } from '../substrate/injected-store.js';
26
25
  // ---------------------------------------------------------------------------
27
26
  // resumeArgs — which session source a revive resumes from
28
27
  // ---------------------------------------------------------------------------
@@ -43,29 +42,33 @@ export function resumeArgs(meta, resume) {
43
42
  // ---------------------------------------------------------------------------
44
43
  // reviveNode
45
44
  // ---------------------------------------------------------------------------
46
- /** Open a fresh background tmux window for `nodeId` and update canvas meta.
45
+ /** Relaunch `nodeId`'s broker engine from its persisted recipe and update canvas
46
+ * meta. Opens no viewer (engine-only).
47
47
  *
48
- * Throws if the node does not exist. All other failures (e.g. tmux not
49
- * available) propagate as-is — callers (daemon, command) decide how to handle.
48
+ * Throws if the node does not exist. All other failures propagate as-is
49
+ * callers (daemon, command) decide how to handle.
50
50
  */
51
51
  export function reviveNode(nodeId, opts) {
52
52
  const meta = getNode(nodeId);
53
53
  if (meta === null) {
54
54
  throw new Error(`reviveNode: unknown node ${nodeId}`);
55
55
  }
56
- // Double-revive guard (pane-keyed, §2.4): reconcile FIRST so a user-moved pane
57
- // isn't misread as "not yet revived", then probe pane-existence. A node whose
58
- // pane is alive AND whose pi is still RUNNING was already revived by another
59
- // path; re-launching would put a SECOND pi on the same session file — no-op.
60
- // A FROZEN focus pane (remain-on-exit, F3) is pane-alive but pi-DEAD: that is
61
- // the resume-into-focus case and MUST proceed (respawn-pane -k back into the
62
- // frozen pane), so the guard gates on pi liveness too, not pane-existence alone.
63
- reconcile(nodeId);
56
+ // Lazy host_kind coerce C): a pre-cut row carries host_kind null or 'tmux'.
57
+ // Every launcher now uses the broker host regardless, loading the same
58
+ // host-agnostic session.jsonl; persist 'broker' so inspect/history read honest
59
+ // values and the daemon never branches it back. Mutate the in-memory meta too.
60
+ if (meta.host_kind !== 'broker') {
61
+ updateNode(nodeId, { host_kind: 'broker' });
62
+ meta.host_kind = 'broker';
63
+ }
64
+ // Double-revive guard: the broker's isAlive IS isPidAlive(pi_pid), so a node
65
+ // whose broker pid is still running was already revived by another path —
66
+ // re-launching would put a SECOND broker on the same session file. No-op.
64
67
  const live = getNode(nodeId) ?? meta;
65
- if (hostFor(live).isAlive(nodeId) && isPidAlive(live.pi_pid)) {
68
+ if (isPidAlive(live.pi_pid)) {
66
69
  return {
67
- window: live.window ?? null,
68
- session: live.tmux_session ?? nodeSession(),
70
+ window: null,
71
+ session: live.tmux_session ?? null,
69
72
  resumed: false,
70
73
  };
71
74
  }
@@ -93,122 +96,29 @@ export function reviveNode(nodeId, opts) {
93
96
  // woke you"); every other reviveNode caller passes nothing → no block.
94
97
  const bearings = drainBearings(meta);
95
98
  inv = buildPiArgv(meta, { prompt: buildReviveKickoff(meta, bearings, opts.wakeReason) });
99
+ // Fresh (no-resume) revive starts a NEW transcript — reset the on-read doc
100
+ // dedup so the new conversation surfaces docs from scratch (a resume below
101
+ // would instead KEEP the persisted set, continuing the same transcript).
102
+ clearInjectedDocs(nodeId);
96
103
  }
97
- // Placement owns WHERE this revive lands (§1.4): resume into a live focus pane
98
- // if the node occupies one, else a fresh window in its home_session (the
99
- // backstage `crtr` for a child NEVER a user session). reviveIntoPlacement
100
- // performs the one atomic setPresence; reviveNode keeps transition+clearPid
101
- // around it (the crash-safety ordering, unchanged). THIS is the bug-kill: a
102
- // non-focused background revive can no longer new-window into a user session.
104
+ // The broker host launches the detached engine. reviveNode keeps
105
+ // transition+clearPid around it (the crash-safety ordering, unchanged). It
106
+ // opens NO viewer engine-only; existing viewers reconnect, and a viewer-less
107
+ // node is brought on screen by the next `focus`.
103
108
  transition(nodeId, 'revive');
104
109
  // Cancel-on-wake (design §6.4, AC-E1): every revive-for-any-reason (an inbox
105
110
  // event, a different wake, a manual focus) drops this node's pending deadline,
106
111
  // so the deadline always belongs to the dormancy being left. Writes only the
107
- // wakeups table, after the atomic transition above. (reviveInPlace's
108
- // transition('boot') needs NO hook — a refresh is the same node continuing,
109
- // not leaving a dormancy.)
112
+ // wakeups table, after the atomic transition above.
110
113
  cancelDeadlinesFor(nodeId);
111
- const placed = hostFor(meta).launch(nodeId, inv, {
114
+ headlessBrokerHost.launch(nodeId, inv, {
112
115
  cwd: meta.cwd,
113
116
  name: fullName(meta),
114
117
  resuming,
115
118
  });
116
- // Window-backed launch: clear the stale pid so the daemon won't re-fire on
117
- // it during the new pi's boot. The fresh pi re-records its pid on
118
- // session_start; if it never boots, this window closes and the window-gone
119
- // pass reaps it.
119
+ // Clear the stale pid so the daemon won't re-fire on it during the new
120
+ // broker's boot. The fresh broker re-records its pid during extension bind; if
121
+ // it never boots, the daemon's boot-grace + surfaceBootFailure own that case.
120
122
  clearPid(nodeId);
121
- return { window: placed.window, session: placed.session, resumed: resuming };
122
- }
123
- // ---------------------------------------------------------------------------
124
- // reviveInPlace — refresh-yield without churning the window
125
- // ---------------------------------------------------------------------------
126
- /** Re-exec a node's pi FRESH in its EXISTING tmux pane (the refresh-yield
127
- * path). Unlike `reviveNode`, this opens no new window: the pane's current pi
128
- * is replaced in place via `respawn-pane -k`, so a foreground/interactive
129
- * session keeps its terminal and a background node keeps its window. Always
130
- * fresh (no resume) — the node re-reads its roadmap/context dir.
131
- *
132
- * `pane` is the target pane id (the yielding node reads it from $TMUX_PANE).
133
- * Throws on unknown node or when the respawn could not be dispatched, so the
134
- * caller can fall back to a plain shutdown (daemon revives in a new window). */
135
- export function reviveInPlace(nodeId, pane, respawn = respawnPane) {
136
- const meta = getNode(nodeId);
137
- if (meta === null) {
138
- throw new Error(`reviveInPlace: unknown node ${nodeId}`);
139
- }
140
- // A refresh-yield is a cycle too — advance the label's trailing N.
141
- meta.cycles = (meta.cycles ?? 0) + 1;
142
- updateNode(nodeId, { cycles: meta.cycles });
143
- // The node's LOCATION — the session its pane physically lives in. The re-exec
144
- // is IN PLACE (the pane never moves), so this is preserved unchanged below.
145
- const session = meta.tmux_session ?? nodeSession();
146
- // Fresh re-exec: same recipe as a no-resume reviveNode, with the kickoff so
147
- // the node rebuilds its bearings from disk. Drain the one-shot bearings first,
148
- // then build purely.
149
- const bearings = drainBearings(meta);
150
- const inv = buildPiArgv(meta, { prompt: buildReviveKickoff(meta, bearings) });
151
- // CRTR_ROOT_SESSION is the backstage this node's CHILDREN spawn into — NOT the
152
- // pane's live `session`. A FOCUSED child's pane is in a USER session (focus
153
- // taints meta.tmux_session), so sourcing it from `session` would land any
154
- // child it spawns in the user's session, re-tainting that child's
155
- // home_session (A-MAJOR-1). childBackstageOf is the taint-immune backstage:
156
- // home_session for a managed child, but `nodeSession()` for a ROOT (whose
157
- // home_session may itself be a user session it adopted via the inline front
158
- // door — sourcing children from it would re-point the root's whole subtree
159
- // into the user's session on every refresh-yield).
160
- const env = { ...inv.env, CRTR_ROOT_SESSION: childBackstageOf(nodeId), CRTR_SUBTREE: rootOfSpine(nodeId) };
161
- const ok = respawn({ pane, cwd: meta.cwd, env, command: piCommand(inv.argv) });
162
- if (!ok) {
163
- throw new Error(`reviveInPlace: respawn-pane dispatch failed for ${nodeId}`);
164
- }
165
- // Deliberately DO NOT clear intent here, and DO NOT touch pi_pid. The detached
166
- // respawn-pane can't confirm it actually replaced the pi (it kills this very
167
- // process mid-flight), so clearing intent optimistically is how a failed
168
- // refresh became a silent death: the fresh pi never boots, yet meta says the
169
- // refresh completed. Instead we leave intent='refresh' (the fresh pi clears it
170
- // on boot — the only proof the respawn worked) and leave pi_pid as the OLD
171
- // pid. If the respawn succeeds, the old pi dies and the fresh one overwrites
172
- // pid+intent within the daemon's grace window; if it fails, the old pid stays
173
- // dead and the daemon's pi-liveness pass revives the node.
174
- transition(nodeId, 'boot');
175
- // tmux_session may have resolved to the shared session; window is unchanged
176
- // (we re-execed in place), so preserve it explicitly.
177
- setPresence(nodeId, { tmux_session: session, window: meta.window ?? null });
178
- // Window is unchanged (we re-execed in place); report the existing one.
179
- return { window: meta.window ?? null, session, resumed: false };
180
- }
181
- // ---------------------------------------------------------------------------
182
- // relaunchRootInPane — boot a CLEAN fresh root in the current pane (option C)
183
- // ---------------------------------------------------------------------------
184
- /** Re-exec a FRESH pi for `nodeId` in EXISTING `pane` (respawn-pane -k), with
185
- * NO prompt and NO resume — a clean root conversation (goal-capture /
186
- * context-intro handle the first message + bearings, exactly like bare
187
- * `crtr`). Unlike reviveInPlace: no buildReviveKickoff prompt, no cycles bump,
188
- * and it sets CRTR_FRONT_DOOR=1 (REQUIRED — src/core/runtime/CLAUDE.md: any
189
- * path that boots a pi must guard against a removed/renamed subcommand
190
- * fork-bombing). Throws if the respawn could not be dispatched.
191
- *
192
- * Used by relaunchRoot (reset.ts) for the `/new`-in-a-root relaunch. Kept
193
- * SEPARATE from reviveInPlace so the refresh-yield path's exact semantics
194
- * (kickoff + cycle bump) are untouched. */
195
- export function relaunchRootInPane(nodeId, pane) {
196
- const meta = getNode(nodeId);
197
- if (meta === null) {
198
- throw new Error(`relaunchRootInPane: unknown node ${nodeId}`);
199
- }
200
- // No prompt, no resume → a brand-new root conversation at cycle 0.
201
- const inv = buildPiArgv(meta, {});
202
- // Source CRTR_ROOT_SESSION from childBackstageOf, the same backstage rule as
203
- // reviveInPlace. relaunchRootInPane runs only on a root, whose children must
204
- // flow to the shared backstage `nodeSession()` — never the root's own adopted
205
- // user session — so both in-pane revive paths stay sourced identically.
206
- const env = { ...inv.env, CRTR_ROOT_SESSION: childBackstageOf(nodeId), CRTR_SUBTREE: rootOfSpine(nodeId), [FRONT_DOOR_ENV]: '1' };
207
- const ok = respawnPane({ pane, cwd: meta.cwd, env, command: piCommand(inv.argv) });
208
- if (!ok) {
209
- throw new Error(`relaunchRootInPane: respawn-pane dispatch failed for ${nodeId}`);
210
- }
211
- // Do NOT clear intent/pi_pid here — the fresh pi clears intent='refresh' on
212
- // its session_start boot (the only proof the respawn worked), same dance as
213
- // reviveInPlace.
123
+ return { window: null, session: meta.tmux_session ?? null, resumed: resuming };
214
124
  }
@@ -7,8 +7,10 @@ export interface BootRootOpts {
7
7
  /** Optional starter prompt (bare `crtr` requires none). */
8
8
  prompt?: string;
9
9
  }
10
- /** Create a root node and bring up its pi. Returns the node; for 'inline' this
11
- * only returns after pi exits (it took over the terminal). */
10
+ /** Create the front-door root: launch its broker engine, then exec `crtr attach`
11
+ * inline so THIS terminal becomes the broker's controller-viewer. Does not
12
+ * return — it process.exit()s when the inline attach exits (detach leaves the
13
+ * resident broker running, to be reconnected later). */
12
14
  export declare function bootRoot(opts: BootRootOpts): NodeMeta;
13
15
  export interface SpawnChildOpts {
14
16
  kind: string;
@@ -35,24 +37,26 @@ export interface SpawnChildOpts {
35
37
  * a <crtr-wake> block is prepended to the kickoff so the newborn knows a clock
36
38
  * birthed it. */
37
39
  wakeOrigin?: WakeOrigin;
38
- /** Which HOST launches + supervises this node: a tmux pane (default) or the
39
- * headless broker. Persisted as `host_kind` at birth (resolved from
40
- * `--headless` / the `headless` config default by the caller). */
41
- hostKind?: 'tmux' | 'broker';
42
40
  /** Pin the node to a model TIER (ultra/strong/medium/light), overriding the
43
41
  * persona's declared default. Persisted to `meta.model_override` so it
44
42
  * survives polymorphs. Omit to use the persona default. */
45
43
  model?: string;
46
44
  }
47
- /** Resolve a `--fork-from` value to the source pi gets as `--fork <path|id>`.
48
- * A live node id resolves to its captured session FILE (absolute, cwd-immune),
49
- * falling back to its bare session id; a path or partial uuid passes straight
50
- * through to pi. Throws when a known node has no session to fork yet. */
45
+ /** Resolve a `--fork-from` value to an ABSOLUTE `.jsonl` source path for the
46
+ * broker fork (`SessionManager.forkFrom`, which loads a file never a bare id).
47
+ * A live node id resolves to its captured session FILE (absolute, cwd-immune); a
48
+ * relative path is made absolute; a bare/partial uuid is resolved against pi's
49
+ * sessions store. Throws when a known node has no captured session file, or when
50
+ * a uuid resolves to zero or multiple sessions. */
51
51
  export declare function resolveForkSource(value: string): string;
52
52
  export interface SpawnChildResult {
53
53
  node: NodeMeta;
54
+ /** The viewer window opened for a --root in tmux; null otherwise (a managed
55
+ * child opens no viewer, and a --root spawned outside tmux opens none). */
54
56
  window: string | null;
55
- session: string;
57
+ /** The session the --root's viewer opened into (the caller's current session);
58
+ * null when no viewer was opened. */
59
+ session: string | null;
56
60
  }
57
61
  /** Resolve who a spawn is attributed to. A managed child needs a spine parent
58
62
  * (explicit `--parent` or the calling node's CRTR_NODE_ID). A --root spawn