@north-light/cli 0.3.529 → 0.3.531

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 (509) hide show
  1. package/dist/api/dto/lifecycle.d.ts +3 -1
  2. package/dist/api/dto/messages.d.ts +5 -3
  3. package/dist/builtin-memory/crouter-plugin/bundles-and-memory.md +1 -1
  4. package/dist/builtin-memory/crouter-plugin/commands.md +1 -1
  5. package/dist/clients/attach/session/connection.js +1 -1
  6. package/dist/clients/attach/session/reconnect.js +1 -1
  7. package/dist/clients/attach/viewer.js +508 -508
  8. package/dist/commands/node/message.js +1 -1
  9. package/dist/commands/sys/join.js +1 -1
  10. package/dist/core/async-array.d.ts +7 -0
  11. package/dist/core/async-array.js +1 -0
  12. package/dist/core/audit.d.ts +1 -1
  13. package/dist/core/audit.js +2 -2
  14. package/dist/core/canvas/attention.d.ts +4 -4
  15. package/dist/core/canvas/attention.js +1 -1
  16. package/dist/core/canvas/boot.d.ts +4 -4
  17. package/dist/core/canvas/boot.js +1 -1
  18. package/dist/core/canvas/canvas.d.ts +59 -59
  19. package/dist/core/canvas/canvas.js +19 -19
  20. package/dist/core/canvas/context-strip.js +2 -2
  21. package/dist/core/canvas/crons.d.ts +27 -27
  22. package/dist/core/canvas/crons.js +11 -11
  23. package/dist/core/canvas/daemon-actions.d.ts +10 -10
  24. package/dist/core/canvas/daemon-actions.js +8 -8
  25. package/dist/core/canvas/daemon-owner.d.ts +3 -3
  26. package/dist/core/canvas/daemon-owner.js +2 -2
  27. package/dist/core/canvas/db.d.ts +19 -30
  28. package/dist/core/canvas/db.js +3 -2
  29. package/dist/core/canvas/deliveries.d.ts +16 -16
  30. package/dist/core/canvas/deliveries.js +24 -24
  31. package/dist/core/canvas/executions.d.ts +8 -8
  32. package/dist/core/canvas/executions.js +1 -1
  33. package/dist/core/canvas/focuses.d.ts +8 -8
  34. package/dist/core/canvas/focuses.js +1 -1
  35. package/dist/core/canvas/history.d.ts +3 -3
  36. package/dist/core/canvas/history.js +9 -9
  37. package/dist/core/canvas/install-id.d.ts +1 -1
  38. package/dist/core/canvas/install-id.js +1 -1
  39. package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +1 -1
  40. package/dist/core/canvas/managed-worktree-sweep-candidates.js +2 -2
  41. package/dist/core/canvas/memory-reads.d.ts +6 -6
  42. package/dist/core/canvas/memory-reads.js +1 -1
  43. package/dist/core/canvas/nav-model.d.ts +13 -13
  44. package/dist/core/canvas/nav-model.js +1 -1
  45. package/dist/core/canvas/node-agent-paths.d.ts +6 -6
  46. package/dist/core/canvas/node-agent-paths.js +1 -1
  47. package/dist/core/canvas/node-tokens.d.ts +7 -7
  48. package/dist/core/canvas/node-tokens.js +3 -3
  49. package/dist/core/canvas/outcome-actions.d.ts +5 -5
  50. package/dist/core/canvas/outcome-actions.js +3 -3
  51. package/dist/core/canvas/recovery.d.ts +26 -26
  52. package/dist/core/canvas/recovery.js +2 -2
  53. package/dist/core/canvas/render-source.d.ts +1 -1
  54. package/dist/core/canvas/render-source.js +1 -1
  55. package/dist/core/canvas/sessions.d.ts +10 -10
  56. package/dist/core/canvas/sessions.js +4 -4
  57. package/dist/core/canvas/source.js +1 -1
  58. package/dist/core/canvas/structured-requests.d.ts +15 -15
  59. package/dist/core/canvas/structured-requests.js +5 -5
  60. package/dist/core/canvas/tree.d.ts +9 -9
  61. package/dist/core/canvas/tree.js +5 -5
  62. package/dist/core/canvas/waits.d.ts +13 -13
  63. package/dist/core/canvas/waits.js +6 -6
  64. package/dist/core/canvas/worktrees.d.ts +15 -15
  65. package/dist/core/canvas/worktrees.js +1 -1
  66. package/dist/core/command-hooks/lifecycle-catalog.d.ts +4 -4
  67. package/dist/core/command-hooks/lifecycle-catalog.js +1 -1
  68. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  69. package/dist/core/command-plugins/bundle.d.ts +1 -1
  70. package/dist/core/command-plugins/bundle.js +1 -1
  71. package/dist/core/conversation-store/file-store.d.ts +7 -7
  72. package/dist/core/conversation-store/file-store.js +9 -9
  73. package/dist/core/conversation-store/index.d.ts +16 -14
  74. package/dist/core/conversation-store/index.js +1 -1
  75. package/dist/core/conversation-store/listener.js +5 -5
  76. package/dist/core/conversation-store/patch.d.ts +3 -1
  77. package/dist/core/conversation-store/patch.js +1 -1
  78. package/dist/core/directory/join.d.ts +1 -1
  79. package/dist/core/feed/feed.js +3 -3
  80. package/dist/core/feed/inbox.d.ts +2 -2
  81. package/dist/core/feed/inbox.js +1 -1
  82. package/dist/core/feed/messages.d.ts +11 -12
  83. package/dist/core/feed/messages.js +5 -5
  84. package/dist/core/feed/reports.d.ts +4 -4
  85. package/dist/core/feed/reports.js +2 -2
  86. package/dist/core/grants/cover.d.ts +1 -1
  87. package/dist/core/grants/cover.js +1 -1
  88. package/dist/core/grants/local.d.ts +1 -1
  89. package/dist/core/grants/local.js +1 -1
  90. package/dist/core/grants/mirror.d.ts +19 -19
  91. package/dist/core/grants/mirror.js +2 -2
  92. package/dist/core/grants/on-sync.d.ts +1 -1
  93. package/dist/core/grants/on-sync.js +1 -1
  94. package/dist/core/grants/remove.js +1 -1
  95. package/dist/core/grants/sync.js +1 -1
  96. package/dist/core/graph/access.d.ts +17 -17
  97. package/dist/core/graph/access.js +3 -3
  98. package/dist/core/graph/custom.d.ts +16 -16
  99. package/dist/core/graph/custom.js +9 -9
  100. package/dist/core/graph/deletion.d.ts +3 -7
  101. package/dist/core/graph/deletion.js +4 -4
  102. package/dist/core/graph/documents.d.ts +24 -27
  103. package/dist/core/graph/documents.js +7 -7
  104. package/dist/core/graph/edges.d.ts +13 -13
  105. package/dist/core/graph/edges.js +1 -1
  106. package/dist/core/graph/events.d.ts +7 -9
  107. package/dist/core/graph/events.js +8 -8
  108. package/dist/core/graph/exposures.d.ts +6 -6
  109. package/dist/core/graph/exposures.js +4 -4
  110. package/dist/core/graph/jobs.d.ts +6 -8
  111. package/dist/core/graph/jobs.js +2 -2
  112. package/dist/core/graph/kinds/action.js +1 -1
  113. package/dist/core/graph/kinds/custom.js +2 -2
  114. package/dist/core/graph/kinds/document.d.ts +1 -0
  115. package/dist/core/graph/kinds/document.js +4 -4
  116. package/dist/core/graph/kinds/dto.d.ts +2 -2
  117. package/dist/core/graph/kinds/dto.js +1 -1
  118. package/dist/core/graph/kinds/job.js +2 -2
  119. package/dist/core/graph/kinds/kind.d.ts +6 -8
  120. package/dist/core/graph/kinds/kind.js +1 -1
  121. package/dist/core/graph/kinds/node.js +5 -5
  122. package/dist/core/graph/kinds/owner.js +2 -2
  123. package/dist/core/graph/kinds/registry.d.ts +6 -9
  124. package/dist/core/graph/kinds/registry.js +1 -1
  125. package/dist/core/graph/names.d.ts +6 -6
  126. package/dist/core/graph/names.js +3 -3
  127. package/dist/core/graph/object-waits.d.ts +4 -7
  128. package/dist/core/graph/object-waits.js +1 -1
  129. package/dist/core/graph/objects.d.ts +14 -14
  130. package/dist/core/graph/objects.js +9 -9
  131. package/dist/core/graph/package-docs.d.ts +2 -7
  132. package/dist/core/graph/package-docs.js +5 -5
  133. package/dist/core/graph/package-kinds.d.ts +2 -5
  134. package/dist/core/graph/package-kinds.js +1 -1
  135. package/dist/core/graph/package-reconcile.d.ts +2 -5
  136. package/dist/core/graph/package-reconcile.js +1 -1
  137. package/dist/core/graph/reader.d.ts +18 -18
  138. package/dist/core/graph/reader.js +3 -3
  139. package/dist/core/graph/receivers.d.ts +4 -4
  140. package/dist/core/graph/receivers.js +5 -5
  141. package/dist/core/graph/repo-sync/exchange.d.ts +3 -7
  142. package/dist/core/graph/repo-sync/exchange.js +2 -2
  143. package/dist/core/graph/repo-sync/repos.d.ts +7 -5
  144. package/dist/core/graph/repo-sync/repos.js +3 -3
  145. package/dist/core/graph/repo-sync/sync.d.ts +3 -6
  146. package/dist/core/graph/repo-sync/sync.js +2 -2
  147. package/dist/core/graph/rules.d.ts +5 -5
  148. package/dist/core/graph/rules.js +3 -3
  149. package/dist/core/graph/spaces/app.js +1 -1
  150. package/dist/core/graph/spaces/index.d.ts +4 -5
  151. package/dist/core/graph/spaces/index.js +1 -1
  152. package/dist/core/graph/spaces/own-memory.d.ts +4 -4
  153. package/dist/core/graph/spaces/own-memory.js +1 -1
  154. package/dist/core/graph/spaces/person.js +3 -3
  155. package/dist/core/graph/spaces/repo.d.ts +1 -1
  156. package/dist/core/graph/spaces/repo.js +1 -1
  157. package/dist/core/graph/watches.d.ts +15 -15
  158. package/dist/core/graph/watches.js +10 -10
  159. package/dist/core/human/feedback-companion.d.ts +2 -2
  160. package/dist/core/human/feedback-companion.js +1 -1
  161. package/dist/core/human/feedback.d.ts +3 -3
  162. package/dist/core/human/feedback.js +1 -1
  163. package/dist/core/human/requests.d.ts +34 -33
  164. package/dist/core/human/requests.js +20 -20
  165. package/dist/core/human/scan.d.ts +2 -2
  166. package/dist/core/human/scan.js +1 -1
  167. package/dist/core/human/tickets.d.ts +9 -9
  168. package/dist/core/human/tickets.js +1 -1
  169. package/dist/core/llm/app-rungs.d.ts +1 -1
  170. package/dist/core/llm/app-rungs.js +1 -1
  171. package/dist/core/llm/run.js +1 -1
  172. package/dist/core/peer/directory.d.ts +1 -1
  173. package/dist/core/peer/directory.js +1 -1
  174. package/dist/core/peer/envelope.d.ts +3 -3
  175. package/dist/core/peer/envelope.js +1 -1
  176. package/dist/core/peer/home.d.ts +7 -7
  177. package/dist/core/peer/home.js +2 -2
  178. package/dist/core/peer/ingest.d.ts +6 -6
  179. package/dist/core/peer/ingest.js +1 -1
  180. package/dist/core/peer/outbox-store.d.ts +14 -14
  181. package/dist/core/peer/outbox-store.js +5 -5
  182. package/dist/core/peer/receiver.d.ts +2 -2
  183. package/dist/core/peer/receiver.js +1 -1
  184. package/dist/core/peer/stubs.d.ts +10 -10
  185. package/dist/core/peer/stubs.js +1 -1
  186. package/dist/core/providers/approval.d.ts +2 -2
  187. package/dist/core/providers/approval.js +2 -2
  188. package/dist/core/providers/audit.d.ts +3 -3
  189. package/dist/core/providers/audit.js +2 -2
  190. package/dist/core/providers/bundles.js +2 -2
  191. package/dist/core/providers/call.d.ts +2 -2
  192. package/dist/core/providers/call.js +1 -1
  193. package/dist/core/providers/files.d.ts +1 -1
  194. package/dist/core/providers/files.js +1 -1
  195. package/dist/core/providers/mint.js +1 -1
  196. package/dist/core/providers/receipts.d.ts +1 -1
  197. package/dist/core/providers/receipts.js +2 -2
  198. package/dist/core/review/birth.js +1 -1
  199. package/dist/core/review/comments.d.ts +19 -19
  200. package/dist/core/review/comments.js +5 -5
  201. package/dist/core/review/companion.d.ts +1 -1
  202. package/dist/core/review/companion.js +1 -1
  203. package/dist/core/review/document.d.ts +3 -3
  204. package/dist/core/review/document.js +2 -2
  205. package/dist/core/review/fork.js +2 -2
  206. package/dist/core/review/realize.js +1 -1
  207. package/dist/core/review/remap.d.ts +2 -2
  208. package/dist/core/review/remap.js +4 -4
  209. package/dist/core/review/stage.d.ts +1 -1
  210. package/dist/core/review/stage.js +1 -1
  211. package/dist/core/review/store.d.ts +21 -21
  212. package/dist/core/review/store.js +1 -1
  213. package/dist/core/runs/activity.d.ts +1 -1
  214. package/dist/core/runs/activity.js +5 -5
  215. package/dist/core/runs/confinement.d.ts +7 -7
  216. package/dist/core/runs/confinement.js +2 -2
  217. package/dist/core/runs/events.d.ts +12 -12
  218. package/dist/core/runs/events.js +4 -4
  219. package/dist/core/runs/operations.d.ts +11 -11
  220. package/dist/core/runs/operations.js +5 -5
  221. package/dist/core/runs/questions.d.ts +10 -10
  222. package/dist/core/runs/questions.js +3 -3
  223. package/dist/core/runtime/auth-reload.js +1 -1
  224. package/dist/core/runtime/bearings.d.ts +5 -5
  225. package/dist/core/runtime/bearings.js +6 -6
  226. package/dist/core/runtime/broker-inventory.js +1 -1
  227. package/dist/core/runtime/broker-request.js +1 -1
  228. package/dist/core/runtime/broker.js +1 -1
  229. package/dist/core/runtime/close.d.ts +3 -3
  230. package/dist/core/runtime/close.js +1 -1
  231. package/dist/core/runtime/deliver-live.js +1 -1
  232. package/dist/core/runtime/fleet.d.ts +2 -2
  233. package/dist/core/runtime/host.d.ts +3 -3
  234. package/dist/core/runtime/host.js +3 -3
  235. package/dist/core/runtime/kickoff.d.ts +12 -12
  236. package/dist/core/runtime/kickoff.js +17 -17
  237. package/dist/core/runtime/launch-target.d.ts +1 -1
  238. package/dist/core/runtime/launch-target.js +1 -1
  239. package/dist/core/runtime/ledger.d.ts +3 -3
  240. package/dist/core/runtime/ledger.js +3 -3
  241. package/dist/core/runtime/lifecycle.d.ts +1 -1
  242. package/dist/core/runtime/lifecycle.js +2 -2
  243. package/dist/core/runtime/memory-admission.js +1 -1
  244. package/dist/core/runtime/model-swap.d.ts +2 -2
  245. package/dist/core/runtime/model-swap.js +1 -1
  246. package/dist/core/runtime/node-read.d.ts +1 -1
  247. package/dist/core/runtime/node-read.js +2 -2
  248. package/dist/core/runtime/nodes.d.ts +6 -6
  249. package/dist/core/runtime/nodes.js +1 -1
  250. package/dist/core/runtime/outcome-document.d.ts +1 -1
  251. package/dist/core/runtime/outcome-document.js +1 -1
  252. package/dist/core/runtime/persona.d.ts +3 -3
  253. package/dist/core/runtime/persona.js +2 -2
  254. package/dist/core/runtime/placement.d.ts +11 -11
  255. package/dist/core/runtime/placement.js +1 -1
  256. package/dist/core/runtime/promote.d.ts +3 -3
  257. package/dist/core/runtime/promote.js +1 -1
  258. package/dist/core/runtime/recycle.js +1 -1
  259. package/dist/core/runtime/reopen.d.ts +21 -10
  260. package/dist/core/runtime/reopen.js +1 -1
  261. package/dist/core/runtime/reset.d.ts +4 -4
  262. package/dist/core/runtime/reset.js +1 -1
  263. package/dist/core/runtime/revive-all.d.ts +2 -2
  264. package/dist/core/runtime/revive-all.js +1 -1
  265. package/dist/core/runtime/revive.d.ts +4 -4
  266. package/dist/core/runtime/revive.js +2 -2
  267. package/dist/core/runtime/roadmap.d.ts +6 -6
  268. package/dist/core/runtime/roadmap.js +5 -5
  269. package/dist/core/runtime/session-branch.d.ts +1 -1
  270. package/dist/core/runtime/session-branch.js +1 -1
  271. package/dist/core/runtime/session-list-cache.js +1 -1
  272. package/dist/core/runtime/situational-live.js +1 -1
  273. package/dist/core/runtime/spawn.d.ts +2 -2
  274. package/dist/core/runtime/spawn.js +2 -2
  275. package/dist/core/runtime/stop-guard.d.ts +2 -2
  276. package/dist/core/runtime/stop-guard.js +3 -3
  277. package/dist/core/runtime/warm-pool.d.ts +2 -2
  278. package/dist/core/runtime/warm-pool.js +1 -1
  279. package/dist/core/spaces/mounts.d.ts +2 -2
  280. package/dist/core/spaces/mounts.js +1 -1
  281. package/dist/core/spaces/permissions.d.ts +1 -1
  282. package/dist/core/spaces/permissions.js +1 -1
  283. package/dist/core/spaces/process.d.ts +1 -1
  284. package/dist/core/spaces/process.js +1 -1
  285. package/dist/core/spaces/space.js +1 -1
  286. package/dist/core/spaces/stop.d.ts +3 -3
  287. package/dist/core/spaces/stop.js +2 -2
  288. package/dist/core/spaces/users.d.ts +6 -6
  289. package/dist/core/spaces/users.js +1 -1
  290. package/dist/core/storage/attachments.d.ts +2 -2
  291. package/dist/core/storage/attachments.js +1 -1
  292. package/dist/core/storage/shares.d.ts +2 -2
  293. package/dist/core/storage/shares.js +1 -1
  294. package/dist/core/storage/tables.d.ts +21 -21
  295. package/dist/core/storage/tables.js +3 -3
  296. package/dist/core/substrate/delivery/corpus.d.ts +5 -8
  297. package/dist/core/substrate/delivery/corpus.js +3 -3
  298. package/dist/core/substrate/delivery/deliver.d.ts +10 -15
  299. package/dist/core/substrate/delivery/deliver.js +3 -3
  300. package/dist/core/substrate/delivery/plan.d.ts +2 -12
  301. package/dist/core/substrate/delivery/plan.js +3 -3
  302. package/dist/core/substrate/delivery/render-boot.d.ts +4 -4
  303. package/dist/core/substrate/delivery/render-boot.js +18 -18
  304. package/dist/core/substrate/delivery/render-event.d.ts +7 -14
  305. package/dist/core/substrate/delivery/render-event.js +4 -4
  306. package/dist/core/substrate/subject.d.ts +2 -2
  307. package/dist/core/substrate/subject.js +1 -1
  308. package/dist/core/usage/ledger.d.ts +6 -6
  309. package/dist/core/usage/ledger.js +4 -4
  310. package/dist/core/worktree-close.js +4 -4
  311. package/dist/core/worktree-mutation-async.js +7 -7
  312. package/dist/core/worktree-quarantine.js +1 -1
  313. package/dist/core/worktree-sweep.d.ts +1 -1
  314. package/dist/core/worktree-sweep.js +6 -6
  315. package/dist/core/worktree.d.ts +5 -5
  316. package/dist/core/worktree.js +13 -13
  317. package/dist/daemon/analytics/compute.d.ts +2 -2
  318. package/dist/daemon/analytics/compute.js +1 -1
  319. package/dist/daemon/api/app-listener.d.ts +4 -4
  320. package/dist/daemon/api/app-listener.js +13 -13
  321. package/dist/daemon/api/bridge.js +5 -5
  322. package/dist/daemon/api/document-listener.js +6 -6
  323. package/dist/daemon/api/handlers/analytics.js +1 -1
  324. package/dist/daemon/api/handlers/attach.js +1 -1
  325. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  326. package/dist/daemon/api/handlers/bash.js +1 -1
  327. package/dist/daemon/api/handlers/broker-ops.d.ts +1 -1
  328. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  329. package/dist/daemon/api/handlers/broker-recovery.d.ts +1 -1
  330. package/dist/daemon/api/handlers/broker-recovery.js +1 -1
  331. package/dist/daemon/api/handlers/broker-signals.d.ts +2 -2
  332. package/dist/daemon/api/handlers/broker-signals.js +2 -2
  333. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  334. package/dist/daemon/api/handlers/canvas.js +4 -4
  335. package/dist/daemon/api/handlers/chat-inventory.js +1 -1
  336. package/dist/daemon/api/handlers/crons.js +1 -1
  337. package/dist/daemon/api/handlers/custom-objects.d.ts +4 -4
  338. package/dist/daemon/api/handlers/custom-objects.js +3 -3
  339. package/dist/daemon/api/handlers/delivery-retry.js +1 -1
  340. package/dist/daemon/api/handlers/delivery.js +1 -1
  341. package/dist/daemon/api/handlers/docs.d.ts +4 -4
  342. package/dist/daemon/api/handlers/docs.js +1 -1
  343. package/dist/daemon/api/handlers/feedback-comments.js +3 -3
  344. package/dist/daemon/api/handlers/files.js +1 -1
  345. package/dist/daemon/api/handlers/focus.js +1 -1
  346. package/dist/daemon/api/handlers/health.js +3 -3
  347. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  348. package/dist/daemon/api/handlers/human-requests.js +1 -1
  349. package/dist/daemon/api/handlers/inbox-page.d.ts +1 -1
  350. package/dist/daemon/api/handlers/inbox-page.js +1 -1
  351. package/dist/daemon/api/handlers/inbox.d.ts +1 -1
  352. package/dist/daemon/api/handlers/inbox.js +1 -1
  353. package/dist/daemon/api/handlers/llm.d.ts +1 -1
  354. package/dist/daemon/api/handlers/llm.js +3 -3
  355. package/dist/daemon/api/handlers/memory-reads.js +1 -1
  356. package/dist/daemon/api/handlers/memory.d.ts +5 -5
  357. package/dist/daemon/api/handlers/memory.js +5 -5
  358. package/dist/daemon/api/handlers/messages.js +2 -2
  359. package/dist/daemon/api/handlers/node-events.d.ts +2 -2
  360. package/dist/daemon/api/handlers/node-events.js +3 -3
  361. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  362. package/dist/daemon/api/handlers/node-records.js +2 -2
  363. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  364. package/dist/daemon/api/handlers/nodes.js +1 -1
  365. package/dist/daemon/api/handlers/objects.js +3 -3
  366. package/dist/daemon/api/handlers/package-docs.js +1 -1
  367. package/dist/daemon/api/handlers/plugin-app-token.d.ts +1 -1
  368. package/dist/daemon/api/handlers/plugin-app-token.js +1 -1
  369. package/dist/daemon/api/handlers/profiles.d.ts +3 -3
  370. package/dist/daemon/api/handlers/profiles.js +1 -1
  371. package/dist/daemon/api/handlers/providers.d.ts +1 -1
  372. package/dist/daemon/api/handlers/providers.js +1 -1
  373. package/dist/daemon/api/handlers/questions.js +1 -1
  374. package/dist/daemon/api/handlers/reports.d.ts +1 -1
  375. package/dist/daemon/api/handlers/reports.js +5 -5
  376. package/dist/daemon/api/handlers/review-comments.js +1 -1
  377. package/dist/daemon/api/handlers/reviews.js +1 -1
  378. package/dist/daemon/api/handlers/runs.js +1 -1
  379. package/dist/daemon/api/handlers/structured-requests.js +1 -1
  380. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  381. package/dist/daemon/api/handlers/transfer.js +1 -1
  382. package/dist/daemon/api/map.d.ts +3 -3
  383. package/dist/daemon/api/map.js +1 -1
  384. package/dist/daemon/api/principal.d.ts +1 -1
  385. package/dist/daemon/api/principal.js +1 -1
  386. package/dist/daemon/api/reader.d.ts +5 -5
  387. package/dist/daemon/api/reader.js +1 -1
  388. package/dist/daemon/api/router.d.ts +5 -5
  389. package/dist/daemon/api/router.js +1 -1
  390. package/dist/daemon/api/server.js +1 -1
  391. package/dist/daemon/broker-signals/bus.d.ts +1 -1
  392. package/dist/daemon/broker-signals/bus.js +1 -1
  393. package/dist/daemon/companion-retire.js +1 -1
  394. package/dist/daemon/cron/armed-context.d.ts +2 -2
  395. package/dist/daemon/cron/armed-context.js +1 -1
  396. package/dist/daemon/cron/authority.d.ts +2 -2
  397. package/dist/daemon/cron/authority.js +1 -1
  398. package/dist/daemon/cron/disposition.js +1 -1
  399. package/dist/daemon/cron/ended.d.ts +1 -1
  400. package/dist/daemon/cron/ended.js +2 -2
  401. package/dist/daemon/cron/escalation.js +3 -3
  402. package/dist/daemon/cron/folders.d.ts +1 -1
  403. package/dist/daemon/cron/folders.js +1 -1
  404. package/dist/daemon/cron/held.d.ts +1 -1
  405. package/dist/daemon/cron/held.js +1 -1
  406. package/dist/daemon/cron/lease-recovery.d.ts +1 -1
  407. package/dist/daemon/cron/lease-recovery.js +1 -1
  408. package/dist/daemon/cron/passes.d.ts +2 -2
  409. package/dist/daemon/cron/passes.js +1 -1
  410. package/dist/daemon/cron/run-socket.d.ts +1 -1
  411. package/dist/daemon/cron/run-socket.js +1 -1
  412. package/dist/daemon/cron/settle.js +1 -1
  413. package/dist/daemon/cron/sinks.d.ts +1 -1
  414. package/dist/daemon/cron/sinks.js +2 -2
  415. package/dist/daemon/cron-run.d.ts +12 -3
  416. package/dist/daemon/cron-run.js +2 -2
  417. package/dist/daemon/crtrd.js +6 -6
  418. package/dist/daemon/delivery/run-delivery.js +1 -1
  419. package/dist/daemon/due-sources.d.ts +3 -3
  420. package/dist/daemon/due-sources.js +1 -1
  421. package/dist/daemon/due.d.ts +3 -3
  422. package/dist/daemon/due.js +7 -7
  423. package/dist/daemon/fleet.d.ts +2 -2
  424. package/dist/daemon/fleet.js +11 -11
  425. package/dist/daemon/human/finish.js +3 -3
  426. package/dist/daemon/human/settle.d.ts +1 -1
  427. package/dist/daemon/human/settle.js +1 -1
  428. package/dist/daemon/human/sweep.js +1 -1
  429. package/dist/daemon/joined-owner.d.ts +3 -3
  430. package/dist/daemon/joined-owner.js +1 -1
  431. package/dist/daemon/messaging/node-message.js +1 -1
  432. package/dist/daemon/park-activity.d.ts +2 -2
  433. package/dist/daemon/park-activity.js +1 -1
  434. package/dist/daemon/peer/authority.js +1 -1
  435. package/dist/daemon/peer/forward.d.ts +6 -6
  436. package/dist/daemon/peer/forward.js +1 -1
  437. package/dist/daemon/peer/handlers.js +1 -1
  438. package/dist/daemon/peer/ingress.d.ts +4 -4
  439. package/dist/daemon/peer/ingress.js +1 -1
  440. package/dist/daemon/peer/outbox.d.ts +2 -2
  441. package/dist/daemon/peer/outbox.js +1 -1
  442. package/dist/daemon/peer/relay-service.js +1 -1
  443. package/dist/daemon/plugin-objects/read-leaf.d.ts +2 -2
  444. package/dist/daemon/plugin-objects/read-leaf.js +2 -2
  445. package/dist/daemon/profile-delete.js +1 -1
  446. package/dist/daemon/readiness.d.ts +2 -2
  447. package/dist/daemon/readiness.js +1 -1
  448. package/dist/daemon/reconcilers/action-lane.d.ts +1 -1
  449. package/dist/daemon/reconcilers/action-lane.js +1 -1
  450. package/dist/daemon/reconcilers/bash-deadline.js +2 -2
  451. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  452. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  453. package/dist/daemon/reconcilers/controller-death.d.ts +1 -1
  454. package/dist/daemon/reconcilers/controller-death.js +1 -1
  455. package/dist/daemon/reconcilers/cron-lane.d.ts +1 -1
  456. package/dist/daemon/reconcilers/cron-lane.js +1 -1
  457. package/dist/daemon/reconcilers/delivery-lane.d.ts +1 -1
  458. package/dist/daemon/reconcilers/delivery-lane.js +2 -2
  459. package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +3 -3
  460. package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
  461. package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +2 -2
  462. package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
  463. package/dist/daemon/reconcilers/live-obligation.d.ts +6 -6
  464. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  465. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
  466. package/dist/daemon/reconcilers/node-deadline.d.ts +1 -1
  467. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  468. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  469. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.d.ts +3 -3
  470. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -1
  471. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -1
  472. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  473. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.d.ts +1 -1
  474. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
  475. package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
  476. package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
  477. package/dist/daemon/reconcilers/storage-due-work.js +1 -1
  478. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -1
  479. package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
  480. package/dist/daemon/reconcilers/structured-request-lane.d.ts +1 -1
  481. package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
  482. package/dist/daemon/review/comment-notify.js +2 -2
  483. package/dist/daemon/review/companion.d.ts +3 -3
  484. package/dist/daemon/review/companion.js +1 -1
  485. package/dist/daemon/review/finish.js +1 -1
  486. package/dist/daemon/review/sweep.js +1 -1
  487. package/dist/daemon/run-notices.d.ts +4 -4
  488. package/dist/daemon/run-notices.js +1 -1
  489. package/dist/daemon/runs/append-section.d.ts +2 -2
  490. package/dist/daemon/runs/append-section.js +2 -2
  491. package/dist/daemon/runs/observer.d.ts +2 -2
  492. package/dist/daemon/runs/observer.js +2 -2
  493. package/dist/daemon/structured-requests/boot.d.ts +1 -1
  494. package/dist/daemon/structured-requests/boot.js +1 -1
  495. package/dist/daemon/structured-requests/effects.js +1 -1
  496. package/dist/daemon/structured-requests/sidecar.d.ts +1 -1
  497. package/dist/daemon/structured-requests/sidecar.js +1 -1
  498. package/dist/launcher/run.js +1 -1
  499. package/dist/migrations/004-canvas-documents/apply.d.ts +3 -3
  500. package/dist/migrations/004-canvas-documents/apply.js +1 -1
  501. package/dist/migrations/004-canvas-documents/index.d.ts +2 -2
  502. package/dist/migrations/004-canvas-documents/index.js +2 -2
  503. package/dist/migrations/activation.js +2 -2
  504. package/docs/plugin/bundles-and-memory.md +1 -1
  505. package/docs/plugin/commands.md +1 -1
  506. package/docs/public-api.md +11 -0
  507. package/package.json +4 -3
  508. package/packages/crouter-identity/package.json +1 -1
  509. package/runtime.lock.json +12 -12
@@ -1,2 +1,2 @@
1
- var s=Object.defineProperty;var n=(o,e)=>s(o,"name",{value:e,configurable:!0});import{getNode as i,updateNode as d}from"../canvas/index.js";import{readRoadmap as c}from"./roadmap.js";import{orchestratorContextNote as u}from"./bearings.js";function l(o,e){const r=c(o)??"(no roadmap yet)",t=[`You are now a ${e.toUpperCase()} ORCHESTRATOR. Your scarce resource is your own context window.`,"Your job is to manage context and delegate \u2014 not to do the goal yourself."];return t.push("","Your roadmap is your document `roadmap`; it loads at every new session of yours. Author it now with `crtr doc edit roadmap`: state the goal and exit criteria, and set the preview to the goal\u2019s first line, using your orchestration protocol. Current contents:","",r,"",u(),"","What promotion changes is how long your documents matter: you now persist across refresh cycles, so the documents you own (`crtr doc write`) carry what this goal needs between your refreshes, and a lesson that should outlive this node gets another owner (`--owner user|repo|profile`).","","Then delegate each unit with `crtr node new --kind <kind>`. When your context fills, run `crtr node yield` to refresh against this roadmap."),t.join(`
2
- `)}n(l,"orchestrationGuidance");function m(){return"You are HANDS-ON again \u2014 base mode. Do the work yourself in THIS window and finish it here; stop delegating by default. You no longer drive a roadmap, so `crtr node yield` is not your exit. Spawn a child only for a cleanly separable unit, never as your first move."}n(m,"baseModeGuidance");function f(o,e,r){if(e.mode===r.mode)return"";if(r.mode==="base")return m();const t=i(o);return l(o,t?.kind??"general")}n(f,"transitionGuidance");function g(o){const e=i(o);if(e===null)return null;const r={kind:e.kind,mode:e.mode,lifecycle:e.lifecycle},t=e.persona_ack,a=t===void 0?r:{kind:t.kind??e.kind,mode:t.mode,lifecycle:t.lifecycle};return a.kind===r.kind&&a.mode===r.mode&&a.lifecycle===r.lifecycle?null:{from:a,to:r,guidance:f(o,a,r)}}n(g,"personaDrift");function k(o,e){d(o,{persona_ack:e})}n(k,"commitPersonaAck");export{k as commitPersonaAck,g as personaDrift,f as transitionGuidance};
1
+ var s=Object.defineProperty;var r=(o,e)=>s(o,"name",{value:e,configurable:!0});import{getNode as i,updateNode as c}from"../canvas/index.js";import{readRoadmap as d}from"./roadmap.js";import{orchestratorContextNote as u}from"./bearings.js";async function l(o,e){const t=await d(o)??"(no roadmap yet)",n=[`You are now a ${e.toUpperCase()} ORCHESTRATOR. Your scarce resource is your own context window.`,"Your job is to manage context and delegate \u2014 not to do the goal yourself."];return n.push("","Your roadmap is your document `roadmap`; it loads at every new session of yours. Author it now with `crtr doc edit roadmap`: state the goal and exit criteria, and set the preview to the goal\u2019s first line, using your orchestration protocol. Current contents:","",t,"",u(),"","What promotion changes is how long your documents matter: you now persist across refresh cycles, so the documents you own (`crtr doc write`) carry what this goal needs between your refreshes, and a lesson that should outlive this node gets another owner (`--owner user|repo|profile`).","","Then delegate each unit with `crtr node new --kind <kind>`. When your context fills, run `crtr node yield` to refresh against this roadmap."),n.join(`
2
+ `)}r(l,"orchestrationGuidance");function m(){return"You are HANDS-ON again \u2014 base mode. Do the work yourself in THIS window and finish it here; stop delegating by default. You no longer drive a roadmap, so `crtr node yield` is not your exit. Spawn a child only for a cleanly separable unit, never as your first move."}r(m,"baseModeGuidance");async function f(o,e,t){if(e.mode===t.mode)return"";if(t.mode==="base")return m();const n=await i(o);return await l(o,n?.kind??"general")}r(f,"transitionGuidance");async function g(o){const e=await i(o);if(e===null)return null;const t={kind:e.kind,mode:e.mode,lifecycle:e.lifecycle},n=e.persona_ack,a=n===void 0?t:{kind:n.kind??e.kind,mode:n.mode,lifecycle:n.lifecycle};return a.kind===t.kind&&a.mode===t.mode&&a.lifecycle===t.lifecycle?null:{from:a,to:t,guidance:await f(o,a,t)}}r(g,"personaDrift");async function k(o,e){await c(o,{persona_ack:e})}r(k,"commitPersonaAck");export{k as commitPersonaAck,g as personaDrift,f as transitionGuidance};
@@ -5,15 +5,15 @@ export type { RespawnPaneOpts } from './tmux-driver.js';
5
5
  export { installTmuxBindings } from './tmux-bindings.js';
6
6
  export type { TmuxInstalledPair, TmuxInstallDiagnostic, TmuxInstallResult } from './tmux-bindings.js';
7
7
  /** The viewer a node has on screen, or null. UNIQUE(node_id) ⇒ at most one. */
8
- export declare function focusOf(nodeId: string): FocusRow | null;
8
+ export declare function focusOf(nodeId: string): Promise<FocusRow | null>;
9
9
  /** Does this node have a live viewer on screen? */
10
- export declare function isFocused(nodeId: string): boolean;
10
+ export declare function isFocused(nodeId: string): Promise<boolean>;
11
11
  /** The viewer realized by a given pane (`%id`), or null. */
12
- export declare function focusByPane(pane: string): FocusRow | null;
12
+ export declare function focusByPane(pane: string): Promise<FocusRow | null>;
13
13
  /** The set of node ids that currently have a live viewer. */
14
- export declare function focusedNodes(): Set<string>;
14
+ export declare function focusedNodes(): Promise<Set<string>>;
15
15
  /** Every live viewer row (GC'ing any whose pane has gone). */
16
- export declare function listFocuses(): FocusRow[];
16
+ export declare function listFocuses(): Promise<FocusRow[]>;
17
17
  /** A reviver: ensure a node's broker ENGINE is alive (idempotent → reviveNode →
18
18
  * headlessBrokerHost.launch). Injected so placement.ts need not import revive.ts
19
19
  * (which imports placement.ts — a cycle). */
@@ -40,7 +40,7 @@ export interface FocusResult {
40
40
  * `window` is accepted for the call contract (spawn passes it) but not stored —
41
41
  * the focuses table keys on pane + session only. The attach client self-tags the
42
42
  * pane `@crtr_node` on connect, so `nodeInPane` resolves it either way. */
43
- export declare function registerViewerFocus(nodeId: string, pane: string, session: string | null, window: string | null): FocusRow | null;
43
+ export declare function registerViewerFocus(nodeId: string, pane: string, session: string | null, window: string | null): Promise<FocusRow | null>;
44
44
  /** Open a surface-attach viewer for `nodeId` and register its viewer focus row —
45
45
  * the shared opener used by `focus` (a split beside the caller) and by a --root
46
46
  * spawn (a fresh window in the caller's current session). Wraps `ensureSession`
@@ -58,7 +58,7 @@ export declare function openViewerWindow(nodeId: string, session: string, opts?:
58
58
  besidePane?: string;
59
59
  waitForBroker?: boolean;
60
60
  initialWhip?: boolean;
61
- }): FocusRow | null;
61
+ }): Promise<FocusRow | null>;
62
62
  export declare function focus(nodeId: string, opts: {
63
63
  pane?: string;
64
64
  newPane?: boolean;
@@ -70,7 +70,7 @@ export declare function focus(nodeId: string, opts: {
70
70
  * on-screen viewer: kill its pane (the window collapses once its last pane goes)
71
71
  * and drop its registry row. Best-effort tmux; the DB write always lands. No-op
72
72
  * when the node has no viewer. */
73
- export declare function tearDownNode(nodeId: string, keepPane?: string): void;
73
+ export declare function tearDownNode(nodeId: string, keepPane?: string): Promise<void>;
74
74
  /** Detach a node from the foreground (the `node lifecycle demote --detach` / Alt+C → D
75
75
  * half). Every node is a headless broker — the only thing on screen is its
76
76
  * surface-attach viewer pane — so "detach" means STOP FOREGROUNDING it: close the
@@ -78,7 +78,7 @@ export declare function tearDownNode(nodeId: string, keepPane?: string): void;
78
78
  * reconnectable by a later `focus`. `pane` is the authoritative pane the caller
79
79
  * acts on (the Alt+C menu's `#{pane_id}`); falls back to the node's registered
80
80
  * viewer pane. No-op (false) when there is no live viewer pane to close. */
81
- export declare function detachToBackground(nodeId: string, pane?: string): boolean;
81
+ export declare function detachToBackground(nodeId: string, pane?: string): Promise<boolean>;
82
82
  /** Reap `nodeId` IFF it is an empty shell (see {@link isEmptyNode}): tear down its
83
83
  * broker engine, close any viewer, and hard-delete its row (edges cascade) + dir.
84
84
  * The user closing or detaching from a node that never said anything wants it
@@ -86,7 +86,7 @@ export declare function detachToBackground(nodeId: string, pane?: string): boole
86
86
  * its node identity so the worktree remains owned and can later be closed.
87
87
  * Returns true when it reaped. No-op (false) on a node that produced output,
88
88
  * is mid-first-turn, owns an open managed worktree, or no longer exists. */
89
- export declare function reapIfEmpty(nodeId: string, keepPane?: string, teardown?: boolean): boolean;
89
+ export declare function reapIfEmpty(nodeId: string, keepPane?: string, teardown?: boolean): Promise<boolean>;
90
90
  /** Sweep the whole canvas for empty shells and reap them — the bulk cleanup
91
91
  * behind `crtr canvas prune --empty`, for the husks that accumulated before
92
92
  * close/detach learned to reap. Skips: the caller ($CRTR_NODE_ID), dead rows,
@@ -97,4 +97,4 @@ export declare function reapIfEmpty(nodeId: string, keepPane?: string, teardown?
97
97
  * without deleting. Returns the reaped (or, under dryRun, reapable) node ids. */
98
98
  export declare function reapEmptyNodes(opts?: {
99
99
  dryRun?: boolean;
100
- }): string[];
100
+ }): Promise<string[]>;
@@ -1 +1 @@
1
- var V=Object.defineProperty;var t=(e,n)=>V(e,"name",{value:n,configurable:!0});import{envNodeId as $}from"../../shared/env.js";import{getNode as m,fullName as H,deleteNode as R,listNodes as M,openFocusRow as z,closeFocusRow as a,getFocusByNode as T,getFocusByPane as x,getFocusById as D,listFocuses as J}from"../canvas/index.js";import{nodeHasAssistantMessage as Q}from"../canvas/render-source.js";import{headlessBrokerHost as k}from"./host.js";import{publishNotice as U}from"./close.js";import{paneExists as d,paneLocation as h,closePane as P,currentTmux as X,switchClient as j,selectWindow as q,selectLayout as G,selectPane as S,getPaneOption as K,setPaneOption as Y,respawnPaneSync as Z,windowOfPane as I,renameWindow as ee}from"./tmux-driver.js";import{openViewerPane as ne,viewerSplitEnv as W,waitForBrokerViewSocket as oe}from"./placement-tmux.js";import{newJobId as se}from"./nodes.js";import{isPidAlive as y}from"../canvas/pid.js";import{splitWindow as Oe,breakPane as Re,selectLayout as Te,selectPane as ke,focusWindow as Se,selectWindow as We,switchClient as be,openNodeWindow as Ae,ensureSession as Be,paneLocation as Ee,paneExists as Ce,paneRunning as Le,paneCurrentPath as Ve,currentTmux as $e,inTmux as He,paneOfNode as Me,setPaneOption as ze,getPaneOption as De,piCommand as Je,shellQuote as Qe,respawnPaneSync as Ue,closePane as Xe,displayPopup as je,windowOfPane as qe,renameWindow as Ge,paneOfWindow as Ke,windowAlive as Ye,listLivePanes as Ze,listLivePanesAsync as Ie}from"./tmux-driver.js";import{installTmuxBindings as nn}from"./tmux-bindings.js";function g(e){return e===null?null:e.pane!==null&&!d(e.pane)?(a(e.focus_id),null):e}t(g,"liveOrPrune");function p(e){return g(T(e))}t(p,"focusOf");function _e(e){return p(e)!==null}t(_e,"isFocused");function ie(e){return g(x(e))}t(ie,"focusByPane");function xe(){return new Set(te().map(e=>e.node_id))}t(xe,"focusedNodes");function te(){const e=[];for(const n of J())g(n)!==null&&e.push(n);return e}t(te,"listFocuses");function re(){return`f-${se()}`}t(re,"newFocusId");function b(e,n,o,s){const u=x(n);if(u!==null)return u;const r=T(e);if(r!==null)return r;const l=re();return z(l,n,o,e),D(l)}t(b,"registerViewerFocus");function A(e,n,o={}){const s=ne(e,n,o);return s===null?null:b(e,s.pane,s.session,s.window)}t(A,"openViewerWindow");function B(e){const n=h(e)?.window??null;n!==null&&G(n,"even-horizontal"),S(e)}t(B,"surfaceNewPane");async function he(e,n){const o=m(e);if(o===null)return{focused:!1,session:null,inPlace:!1,revived:!1};const s=n.pane??process.env.TMUX_PANE??X()?.pane;if(s===void 0||s==="")return{focused:!1,session:null,inPlace:!1,revived:!1};const u=y(o.pi_pid??null),r=n.revive(e),l=!u;if(!await oe(e,r?.launch?.exited))return{focused:!1,session:null,inPlace:!1,revived:l};const v=h(s)?.session??null,N=v??"";if(n.inPlace===!0){const i=p(e);i!==null&&(i.pane!==null&&i.pane!==s&&d(i.pane)&&P(i.pane),a(i.focus_id));const c=x(s);c!==null&&c.node_id!==e&&a(c.focus_id);try{Y(s,"@crtr_node","")}catch{}const _=I(s),F=c?.node_id,L=F===void 0?W():{...W(),CRTR_ATTACH_ROSTER:F},O=Z({pane:s,cwd:o.cwd,env:L,command:`crtr surface attach to ${e}`});return O&&(_!==null&&ee(_,H(o)),b(e,s,v,_)),{focused:O,session:v,inPlace:!0,revived:l}}if(n.newPane===!0){const i=p(e);i!==null&&(i.pane!==null&&d(i.pane)&&P(i.pane),a(i.focus_id));const c=A(e,N,{cwd:o.cwd,besidePane:s});return c===null?{focused:!1,session:null,inPlace:!1,revived:l}:(c.pane!==null&&B(c.pane),{focused:!0,session:c.session,inPlace:!1,revived:l})}const f=p(e);if(f!==null&&f.pane!==null)if(K(f.pane,"@crtr_node")===e){const i=h(f.pane);if(i!==null)return j(i.session),q(i.session,i.window),S(f.pane),{focused:!0,session:i.session,inPlace:!0,revived:l};a(f.focus_id)}else a(f.focus_id);const w=A(e,N,{cwd:o.cwd,besidePane:s});return w===null?{focused:!1,session:null,inPlace:!1,revived:l}:(w.pane!==null&&B(w.pane),{focused:!0,session:w.session,inPlace:!1,revived:l})}t(he,"focus");function E(e,n){const o=p(e);o!==null&&(o.pane!==null&&o.pane!==n&&d(o.pane)&&P(o.pane),a(o.focus_id))}t(E,"tearDownNode");function ye(e,n){const o=n??p(e)?.pane??null;if(o===null||!d(o))return!1;const s=ie(o);s!==null&&a(s.focus_id);const u=P(o);return le(e),u}t(ye,"detachToBackground");function C(e){const n=m(e);return n===null||n.streaming===!0&&y(n.pi_pid)?!1:!Q(n.pi_session_file)}t(C,"isEmptyNode");function le(e,n,o=!0){return m(e)?.managed_worktree?.state==="open"||!C(e)?!1:(o&&k.teardown(e),E(e,n),R(e).deleted)}t(le,"reapIfEmpty");function ge(e={}){const n=e.dryRun??!1,o=$()??"",s=[];for(const u of M()){const r=u.node_id,l=m(r);r===o||u.status==="dead"||y(u.pi_pid)||l?.managed_worktree?.state==="open"||!C(r)||!n&&(U(r,"notice.close",`Child closed \u2014 ${l?.name??r} (${r}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:r}),k.teardown(r),E(r),!R(r).deleted)||s.push(r)}return s}t(ge,"reapEmptyNodes");export{Re as breakPane,Xe as closePane,$e as currentTmux,ye as detachToBackground,je as displayPopup,Be as ensureSession,he as focus,ie as focusByPane,p as focusOf,Se as focusWindow,xe as focusedNodes,De as getPaneOption,He as inTmux,nn as installTmuxBindings,_e as isFocused,te as listFocuses,Ze as listLivePanes,Ie as listLivePanesAsync,Ae as openNodeWindow,A as openViewerWindow,Ve as paneCurrentPath,Ce as paneExists,Ee as paneLocation,Me as paneOfNode,Ke as paneOfWindow,Le as paneRunning,Je as piCommand,ge as reapEmptyNodes,le as reapIfEmpty,b as registerViewerFocus,Ge as renameWindow,Ue as respawnPaneSync,Te as selectLayout,ke as selectPane,We as selectWindow,ze as setPaneOption,Qe as shellQuote,Oe as splitWindow,be as switchClient,E as tearDownNode,Ye as windowAlive,qe as windowOfPane};
1
+ var V=Object.defineProperty;var s=(e,n)=>V(e,"name",{value:n,configurable:!0});import{envNodeId as $}from"../../shared/env.js";import{getNode as m,fullName as H,deleteNode as R,listNodes as M,openFocusRow as z,closeFocusRow as u,getFocusByNode as T,getFocusByPane as _,getFocusById as D,listFocuses as J}from"../canvas/index.js";import{nodeHasAssistantMessage as Q}from"../canvas/render-source.js";import{headlessBrokerHost as k}from"./host.js";import{publishNotice as U}from"./close.js";import{paneExists as p,paneLocation as x,closePane as P,currentTmux as X,switchClient as j,selectWindow as q,selectLayout as G,selectPane as S,getPaneOption as K,setPaneOption as Y,respawnPaneSync as Z,windowOfPane as I,renameWindow as ee}from"./tmux-driver.js";import{openViewerPane as ne,viewerSplitEnv as W,waitForBrokerViewSocket as ae}from"./placement-tmux.js";import{newJobId as ie}from"./nodes.js";import{isPidAlive as h}from"../canvas/pid.js";import{splitWindow as Oe,breakPane as Re,selectLayout as Te,selectPane as ke,focusWindow as Se,selectWindow as We,switchClient as be,openNodeWindow as Ae,ensureSession as Be,paneLocation as Ee,paneExists as Ce,paneRunning as Le,paneCurrentPath as Ve,currentTmux as $e,inTmux as He,paneOfNode as Me,setPaneOption as ze,getPaneOption as De,piCommand as Je,shellQuote as Qe,respawnPaneSync as Ue,closePane as Xe,displayPopup as je,windowOfPane as qe,renameWindow as Ge,paneOfWindow as Ke,windowAlive as Ye,listLivePanes as Ze,listLivePanesAsync as Ie}from"./tmux-driver.js";import{installTmuxBindings as nn}from"./tmux-bindings.js";async function g(e){return e===null?null:e.pane!==null&&!p(e.pane)?(await u(e.focus_id),null):e}s(g,"liveOrPrune");async function w(e){return await g(await T(e))}s(w,"focusOf");async function ve(e){return await w(e)!==null}s(ve,"isFocused");async function te(e){return await g(await _(e))}s(te,"focusByPane");async function _e(){return new Set((await se()).map(e=>e.node_id))}s(_e,"focusedNodes");async function se(){const e=[];for(const n of await J())await g(n)!==null&&e.push(n);return e}s(se,"listFocuses");function oe(){return`f-${ie()}`}s(oe,"newFocusId");async function b(e,n,a,i){const c=await _(n);if(c!==null)return c;const o=await T(e);if(o!==null)return o;const r=oe();return await z(r,n,a,e),await D(r)}s(b,"registerViewerFocus");async function A(e,n,a={}){const i=ne(e,n,a);return i===null?null:await b(e,i.pane,i.session,i.window)}s(A,"openViewerWindow");function B(e){const n=x(e)?.window??null;n!==null&&G(n,"even-horizontal"),S(e)}s(B,"surfaceNewPane");async function xe(e,n){const a=await m(e);if(a===null)return{focused:!1,session:null,inPlace:!1,revived:!1};const i=n.pane??process.env.TMUX_PANE??X()?.pane;if(i===void 0||i==="")return{focused:!1,session:null,inPlace:!1,revived:!1};const c=h(a.pi_pid??null),o=n.revive(e),r=!c;if(!await ae(e,o?.launch?.exited))return{focused:!1,session:null,inPlace:!1,revived:r};const y=x(i)?.session??null,N=y??"";if(n.inPlace===!0){const t=await w(e);t!==null&&(t.pane!==null&&t.pane!==i&&p(t.pane)&&P(t.pane),await u(t.focus_id));const l=await _(i);l!==null&&l.node_id!==e&&await u(l.focus_id);try{Y(i,"@crtr_node","")}catch{}const v=I(i),F=l?.node_id,L=F===void 0?W():{...W(),CRTR_ATTACH_ROSTER:F},O=Z({pane:i,cwd:a.cwd,env:L,command:`crtr surface attach to ${e}`});return O&&(v!==null&&ee(v,H(a)),await b(e,i,y,v)),{focused:O,session:y,inPlace:!0,revived:r}}if(n.newPane===!0){const t=await w(e);t!==null&&(t.pane!==null&&p(t.pane)&&P(t.pane),await u(t.focus_id));const l=await A(e,N,{cwd:a.cwd,besidePane:i});return l===null?{focused:!1,session:null,inPlace:!1,revived:r}:(l.pane!==null&&B(l.pane),{focused:!0,session:l.session,inPlace:!1,revived:r})}const f=await w(e);if(f!==null&&f.pane!==null)if(K(f.pane,"@crtr_node")===e){const t=x(f.pane);if(t!==null)return j(t.session),q(t.session,t.window),S(f.pane),{focused:!0,session:t.session,inPlace:!0,revived:r};await u(f.focus_id)}else await u(f.focus_id);const d=await A(e,N,{cwd:a.cwd,besidePane:i});return d===null?{focused:!1,session:null,inPlace:!1,revived:r}:(d.pane!==null&&B(d.pane),{focused:!0,session:d.session,inPlace:!1,revived:r})}s(xe,"focus");async function E(e,n){const a=await w(e);a!==null&&(a.pane!==null&&a.pane!==n&&p(a.pane)&&P(a.pane),await u(a.focus_id))}s(E,"tearDownNode");async function he(e,n){const a=n??(await w(e))?.pane??null;if(a===null||!p(a))return!1;const i=await te(a);i!==null&&await u(i.focus_id);const c=P(a);return await re(e),c}s(he,"detachToBackground");async function C(e){const n=await m(e);return n===null||n.streaming===!0&&h(n.pi_pid)?!1:!await Q(n.pi_session_file)}s(C,"isEmptyNode");async function re(e,n,a=!0){return(await m(e))?.managed_worktree?.state==="open"||!await C(e)?!1:(a&&k.teardown(e),await E(e,n),(await R(e)).deleted)}s(re,"reapIfEmpty");async function ge(e={}){const n=e.dryRun??!1,a=$()??"",i=[];for(const c of await M()){const o=c.node_id,r=await m(o);o===a||c.status==="dead"||h(c.pi_pid)||r?.managed_worktree?.state==="open"||!await C(o)||!n&&(await U(o,"notice.close",`Child closed \u2014 ${r?.name??o} (${o}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:o}),k.teardown(o),await E(o),!(await R(o)).deleted)||i.push(o)}return i}s(ge,"reapEmptyNodes");export{Re as breakPane,Xe as closePane,$e as currentTmux,he as detachToBackground,je as displayPopup,Be as ensureSession,xe as focus,te as focusByPane,w as focusOf,Se as focusWindow,_e as focusedNodes,De as getPaneOption,He as inTmux,nn as installTmuxBindings,ve as isFocused,se as listFocuses,Ze as listLivePanes,Ie as listLivePanesAsync,Ae as openNodeWindow,A as openViewerWindow,Ve as paneCurrentPath,Ce as paneExists,Ee as paneLocation,Me as paneOfNode,Ke as paneOfWindow,Le as paneRunning,Je as piCommand,ge as reapEmptyNodes,re as reapIfEmpty,b as registerViewerFocus,Ge as renameWindow,Ue as respawnPaneSync,Te as selectLayout,ke as selectPane,We as selectWindow,ze as setPaneOption,Qe as shellQuote,Oe as splitWindow,be as switchClient,E as tearDownNode,Ye as windowAlive,qe as windowOfPane};
@@ -22,7 +22,7 @@ type ReshapeOptions = {
22
22
  profileId?: string | null;
23
23
  };
24
24
  /** Synchronous reshape for CLI callers outside the daemon. */
25
- export declare function reshapeNode(nodeId: string, opts?: ReshapeOptions, beforePersist?: () => void): NodeMeta;
25
+ export declare function reshapeNode(nodeId: string, opts?: ReshapeOptions, beforePersist?: () => void): Promise<NodeMeta>;
26
26
  /** Daemon-safe reshape: network-backed config resolution happens off its event loop. */
27
27
  export declare function reshapeNodeAsync(nodeId: string, opts?: ReshapeOptions, beforePersist?: () => void): Promise<NodeMeta>;
28
28
  /** Promote a node to an orchestrator (mode→orchestrator), optionally
@@ -36,7 +36,7 @@ export declare function promote(nodeId: string, opts?: {
36
36
  kind?: string;
37
37
  resident?: boolean;
38
38
  model?: string;
39
- }): PromoteResult;
39
+ }): Promise<PromoteResult>;
40
40
  /** Daemon-safe promotion variant; preserves the same validation/seed ordering. */
41
41
  export declare function promoteAsync(nodeId: string, opts?: {
42
42
  kind?: string;
@@ -72,5 +72,5 @@ export declare function requestYield(nodeId: string, opts?: {
72
72
  promote?: boolean;
73
73
  }, deps?: {
74
74
  ensure?: () => void;
75
- }): YieldResult;
75
+ }): Promise<YieldResult>;
76
76
  export {};
@@ -1 +1 @@
1
- var g=Object.defineProperty;var l=(n,e)=>g(n,"name",{value:e,configurable:!0});import{getNode as m,updateNode as x}from"../canvas/index.js";import{transition as E}from"./lifecycle.js";import{ensureDaemon as R}from"../../daemon/manage.js";import{buildLaunchSpec as $,buildLaunchSpecAsync as A}from"./launch.js";import{ensureRoadmap as u,hasRoadmap as f,roadmapRef as t}from"./roadmap.js";import{readGoal as c,goalPath as k}from"./kickoff.js";function h(n,e){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);const i=e.kind??d.kind,o=e.mode??d.mode,r=e.lifecycle??d.lifecycle,a=e.profileId===void 0?d.profile_id??null:e.profileId;return{node:d,kind:i,mode:o,lifecycle:r,profileId:a,launchOpts:{lifecycle:r,hasManager:d.parent!==null,model:e.model??d.model_override??void 0,modelOverride:e.model!==void 0,modelIntent:e.model===void 0?d.launch?.modelIntent:void 0,modelExact:e.model===void 0?d.launch?.modelExact:void 0,cwd:d.cwd,profileId:a}}}l(h,"reshapeInputs");function w(n,e,d,i,o){o?.();const r=d.node.name===d.node.kind&&d.kind!==d.node.kind;return x(n,{kind:d.kind,mode:d.mode,lifecycle:d.lifecycle,profile_id:d.profileId,launch:i,...r?{name:d.kind}:{},...e.model!==void 0?{model_override:i?.model??e.model}:{}})}l(w,"persistReshape");function s(n,e={},d){const i=h(n,e);return w(n,e,i,$(i.kind,i.mode,i.launchOpts).launch,d)}l(s,"reshapeNode");async function y(n,e={},d){const i=h(n,e),{launch:o}=await A(i.kind,i.mode,i.launchOpts);return w(n,e,i,o,d)}l(y,"reshapeNodeAsync");function N(n,e={}){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);let i=!1;return{meta:s(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{},mode:"orchestrator",lifecycle:e.resident===!0?"resident":d.lifecycle},()=>{if(!f(n)){const r=c(n);i=u(n,r!==null&&r.trim()!==""?{goal:r.trim()}:{})}}),roadmapWritten:i,roadmapRef:t(n),goalPath:k(n)}}l(N,"promote");async function O(n,e={}){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);let i=!1;return{meta:await y(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{},mode:"orchestrator",lifecycle:e.resident===!0?"resident":d.lifecycle},()=>{if(!f(n)){const r=c(n);i=u(n,r!==null&&r.trim()!==""?{goal:r.trim()}:{})}}),roadmapWritten:i,roadmapRef:t(n),goalPath:k(n)}}l(O,"promoteAsync");async function Y(n,e={},d={}){if(m(n)===null)throw new Error(`unknown node: ${n}`);return e.promote===!0?await O(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}):(e.kind!==void 0||e.model!==void 0)&&await y(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),{..._(n,{},d),promoted:e.promote===!0}}l(Y,"requestYieldAsync");function _(n,e={},d={}){const i=d.ensure??R;if(m(n)===null)throw new Error(`unknown node: ${n}`);const r=e.kind!==void 0||e.model!==void 0;let a=!1;return e.promote===!0?(N(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),a=!0):r&&s(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),i(),E(n,"yield"),{meta:m(n),promoted:a,willRefresh:!0}}l(_,"requestYield");export{N as promote,O as promoteAsync,_ as requestYield,Y as requestYieldAsync,s as reshapeNode,y as reshapeNodeAsync};
1
+ var g=Object.defineProperty;var r=(n,e)=>g(n,"name",{value:e,configurable:!0});import{getNode as o,updateNode as x}from"../canvas/index.js";import{transition as E}from"./lifecycle.js";import{ensureDaemon as R}from"../../daemon/manage.js";import{buildLaunchSpec as $,buildLaunchSpecAsync as A}from"./launch.js";import{ensureRoadmap as m,hasRoadmap as c,roadmapRef as u}from"./roadmap.js";import{readGoal as f,goalPath as w}from"./kickoff.js";async function k(n,e){const i=await o(n);if(i===null)throw new Error(`unknown node: ${n}`);const a=e.kind??i.kind,l=e.mode??i.mode,d=e.lifecycle??i.lifecycle,t=e.profileId===void 0?i.profile_id??null:e.profileId;return{node:i,kind:a,mode:l,lifecycle:d,profileId:t,launchOpts:{lifecycle:d,hasManager:i.parent!==null,model:e.model??i.model_override??void 0,modelOverride:e.model!==void 0,modelIntent:e.model===void 0?i.launch?.modelIntent:void 0,modelExact:e.model===void 0?i.launch?.modelExact:void 0,cwd:i.cwd,profileId:t}}}r(k,"reshapeInputs");async function s(n,e,i,a,l){l?.();const d=i.node.name===i.node.kind&&i.kind!==i.node.kind;return await x(n,{kind:i.kind,mode:i.mode,lifecycle:i.lifecycle,profile_id:i.profileId,launch:a,...d?{name:i.kind}:{},...e.model!==void 0?{model_override:a?.model??e.model}:{}})}r(s,"persistReshape");async function h(n,e={},i){const a=await k(n,e);return await s(n,e,a,$(a.kind,a.mode,a.launchOpts).launch,i)}r(h,"reshapeNode");async function y(n,e={},i){const a=await k(n,e),{launch:l}=await A(a.kind,a.mode,a.launchOpts);return await s(n,e,a,l,i)}r(y,"reshapeNodeAsync");async function N(n,e={}){const i=await o(n);if(i===null)throw new Error(`unknown node: ${n}`);let a=!1;return{meta:await h(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{},mode:"orchestrator",lifecycle:e.resident===!0?"resident":i.lifecycle},async()=>{if(!await c(n)){const d=await f(n);a=await m(n,d!==null&&d.trim()!==""?{goal:d.trim()}:{})}}),roadmapWritten:a,roadmapRef:u(n),goalPath:await w(n)}}r(N,"promote");async function O(n,e={}){const i=await o(n);if(i===null)throw new Error(`unknown node: ${n}`);let a=!1;return{meta:await y(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{},mode:"orchestrator",lifecycle:e.resident===!0?"resident":i.lifecycle},async()=>{if(!await c(n)){const d=await f(n);a=await m(n,d!==null&&d.trim()!==""?{goal:d.trim()}:{})}}),roadmapWritten:a,roadmapRef:u(n),goalPath:await w(n)}}r(O,"promoteAsync");async function Y(n,e={},i={}){if(await o(n)===null)throw new Error(`unknown node: ${n}`);return e.promote===!0?await O(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}):(e.kind!==void 0||e.model!==void 0)&&await y(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),{...await _(n,{},i),promoted:e.promote===!0}}r(Y,"requestYieldAsync");async function _(n,e={},i={}){const a=i.ensure??R;if(await o(n)===null)throw new Error(`unknown node: ${n}`);const d=e.kind!==void 0||e.model!==void 0;let t=!1;return e.promote===!0?(await N(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),t=!0):d&&await h(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),a(),await E(n,"yield"),{meta:await o(n),promoted:t,willRefresh:!0}}r(_,"requestYield");export{N as promote,O as promoteAsync,_ as requestYield,Y as requestYieldAsync,h as reshapeNode,y as reshapeNodeAsync};
@@ -1 +1 @@
1
- var w=Object.defineProperty;var r=(e,t)=>w(e,"name",{value:t,configurable:!0});import{abortExecution as y,beginExecution as _,getNode as s,setPresence as h,setFocusOccupant as v,fullName as R,recordExecutionPid as b,recordLaunch as E}from"../canvas/index.js";import{pushFinal as k}from"../feed/feed.js";import{newestReportBody as g}from"../feed/reports.js";import{spawnNode as x,rootOfSpine as S}from"./nodes.js";import{buildLaunchSpecAsync as T,buildPiArgv as B}from"./launch.js";import{focusOf as N,respawnPaneSync as O,setPaneOption as P}from"./placement.js";import{waitForBrokerViewSocket as C,viewerSplitEnv as D}from"./placement-tmux.js";import{headlessBrokerHost as u}from"./host.js";import{boundFleet as F}from"./fleet.js";import{transition as z}from"./lifecycle.js";import{ensureDaemon as A}from"../../daemon/manage.js";import{invokeBirthLifecycleHooks as L}from"./spawn.js";async function ne(e,t){const n=s(e);if(n===null)return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const o=t??process.env.TMUX_PANE;if(o===void 0||o==="")return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const f=N(e);try{A()}catch{}const{launch:m}=await T("general","base",{lifecycle:"resident",hasManager:!1,cwd:n.cwd,profileId:n.profile_id}),p=g(e)||`Closed via recycle \u2014 no final summary was authored by ${n.name}.`;let a=[],d=!1;const i=await x({kind:"general",mode:"base",lifecycle:"resident",cwd:n.cwd,name:"general",parent:null,replaces:e,profile_id:n.profile_id,launch:m,beforeCreate:r(async()=>{try{a=(await k(e,p)).deliveredTo,d=!0}catch{}},"beforeCreate")}),c=s(i.node_id);await L(c);const l=B(c);if(l.env={...l.env,CRTR_SUBTREE:S(i.node_id)},!await U(c,l))return{recycled:!1,finalized:d,newRoot:i.node_id,delivered:a};try{u.teardown(e)}catch{}try{h(e,{pane:null,window:null,tmux_session:null})}catch{}if(f!==null)try{v(f.focus_id,i.node_id)}catch{}return{recycled:M(c,o),finalized:d,newRoot:i.node_id,delivered:a}}r(ne,"recycleNode");async function U(e,t){const n=_(e.node_id,{daemonEpoch:F().epoch()});t.env={...t.env,CRTR_EXECUTION_ID:n};let o;try{if(o=await u.launch(e.node_id,t,{cwd:e.cwd,name:R(e),resuming:!1}),o.pid===null)throw new Error("broker host returned no pid");if(E(e.node_id,new Date().toISOString()),b(n,e.node_id,o.pid)==="shutdown")throw new Error("broker execution was superseded");if(await C(e.node_id,o.exited))return!0}catch{y(n,{reason:"launch_failed"})}try{H(e.node_id)}catch{}try{u.teardown(e.node_id)}catch{}return!1}r(U,"launchRecycledBroker");function H(e){const t=s(e);(t?.status==="active"||t?.status==="idle")&&z(e,"crash")}r(H,"transitionReplacementToDead");function M(e,t){try{P(t,"@crtr_node","")}catch{}return O({pane:t,cwd:e.cwd,env:D(),command:`crtr surface attach to ${e.node_id}`})}r(M,"respawnRecycledViewer");export{ne as recycleNode};
1
+ var p=Object.defineProperty;var n=(e,t)=>p(e,"name",{value:t,configurable:!0});import{abortExecution as y,beginExecution as _,getNode as s,setPresence as h,setFocusOccupant as v,fullName as R,recordExecutionPid as b,recordLaunch as E}from"../canvas/index.js";import{pushFinal as k}from"../feed/feed.js";import{newestReportBody as g}from"../feed/reports.js";import{spawnNode as x,rootOfSpine as S}from"./nodes.js";import{buildLaunchSpecAsync as T,buildPiArgv as B}from"./launch.js";import{focusOf as N,respawnPaneSync as O,setPaneOption as P}from"./placement.js";import{waitForBrokerViewSocket as C,viewerSplitEnv as D}from"./placement-tmux.js";import{headlessBrokerHost as u}from"./host.js";import{boundFleet as F}from"./fleet.js";import{transition as z}from"./lifecycle.js";import{ensureDaemon as A}from"../../daemon/manage.js";import{invokeBirthLifecycleHooks as L}from"./spawn.js";async function ae(e,t){const a=await s(e);if(a===null)return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const o=t??process.env.TMUX_PANE;if(o===void 0||o==="")return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const w=await N(e);try{A()}catch{}const{launch:f}=await T("general","base",{lifecycle:"resident",hasManager:!1,cwd:a.cwd,profileId:a.profile_id}),m=await g(e)||`Closed via recycle \u2014 no final summary was authored by ${a.name}.`;let c=[],d=!1;const r=await x({kind:"general",mode:"base",lifecycle:"resident",cwd:a.cwd,name:"general",parent:null,replaces:e,profile_id:a.profile_id,launch:f,beforeCreate:n(async()=>{try{c=(await k(e,m)).deliveredTo,d=!0}catch{}},"beforeCreate")}),i=await s(r.node_id);await L(i);const l=B(i);if(l.env={...l.env,CRTR_SUBTREE:await S(r.node_id)},!await U(i,l))return{recycled:!1,finalized:d,newRoot:r.node_id,delivered:c};try{u.teardown(e)}catch{}try{await h(e,{pane:null,window:null,tmux_session:null})}catch{}if(w!==null)try{await v(w.focus_id,r.node_id)}catch{}return{recycled:M(i,o),finalized:d,newRoot:r.node_id,delivered:c}}n(ae,"recycleNode");async function U(e,t){const a=await _(e.node_id,{daemonEpoch:F().epoch()});t.env={...t.env,CRTR_EXECUTION_ID:a};let o;try{if(o=await u.launch(e.node_id,t,{cwd:e.cwd,name:R(e),resuming:!1}),o.pid===null)throw new Error("broker host returned no pid");if(await E(e.node_id,new Date().toISOString()),await b(a,e.node_id,o.pid)==="shutdown")throw new Error("broker execution was superseded");if(await C(e.node_id,o.exited))return!0}catch{await y(a,{reason:"launch_failed"})}try{await H(e.node_id)}catch{}try{u.teardown(e.node_id)}catch{}return!1}n(U,"launchRecycledBroker");async function H(e){const t=await s(e);(t?.status==="active"||t?.status==="idle")&&await z(e,"crash")}n(H,"transitionReplacementToDead");function M(e,t){try{P(t,"@crtr_node","")}catch{}return O({pane:t,cwd:e.cwd,env:D(),command:`crtr surface attach to ${e.node_id}`})}n(M,"respawnRecycledViewer");export{ae as recycleNode};
@@ -2,14 +2,14 @@
2
2
  * `final_report` fresh — never a caller-supplied snapshot. Throws
3
3
  * `node_finalized` when latched; otherwise a no-op (the common case). No
4
4
  * side effect either way. */
5
- export declare function assertNotFinalized(nodeId: string): void;
5
+ export declare function assertNotFinalized(nodeId: string): Promise<void>;
6
6
  /** Validate a target IS latched (the `--reopen` doorway) and return the exact
7
7
  * `final_report` value observed, so the caller can CAS-clear it later via
8
8
  * `commitReopen` — once every OTHER fallible precondition the requested
9
9
  * operation needs has already passed (e.g. `--fresh`'s recoverable-state
10
10
  * check). Throws `not_finalized` when the target has nothing to clear. Pure
11
11
  * read — never mutates. */
12
- export declare function assertFinalizedForReopen(nodeId: string): string;
12
+ export declare function assertFinalizedForReopen(nodeId: string): Promise<string>;
13
13
  /** Clear `nodeId`'s finalization latch — retract-pointer-only (only
14
14
  * `final_report`/`finalized_at`; the report file and every delivered feed
15
15
  * event are untouched). CAS'd against `expectedFinalReport` (the value the
@@ -19,20 +19,31 @@ export declare function assertFinalizedForReopen(nodeId: string): string;
19
19
  * this throws `reopen_latch_changed` instead of silently clobbering a newer
20
20
  * canonical result. Callers MUST NOT proceed to revive/deliver when this
21
21
  * throws. */
22
- export declare function commitReopen(nodeId: string, expectedFinalReport: string): void;
23
- /** Commit the wider message-delivery reopen: make the node resident, then
22
+ export declare function commitReopen(nodeId: string, expectedFinalReport: string): Promise<void>;
23
+ /** Commit the wider message-delivery reopen: settle the node's lifecycle, then
24
24
  * retract a final latch when one exists. Unlike the revive/fresh gate, an
25
- * unlatched node is valid here — it still becomes resident. Writing lifecycle
26
- * first leaves a failed latch CAS with the canonical-final pointer intact.
27
- * Both writes finish before either delivery channel begins. */
28
- export declare function commitReopenResident(nodeId: string, expectedFinalReport?: string): string | null;
25
+ * unlatched node is valid here.
26
+ *
27
+ * Lifecycle rule: resident is for a node with no manager to report to (an app
28
+ * or person conversation, e.g. a hosted SMS thread reopened by a new text), so
29
+ * a reopen by a person, an app run, or a node that is not the target's manager
30
+ * makes the target resident. When `callerNodeId` is a node that is a tree
31
+ * subscriber of the target (its parent/manager re-tasking its own child), the
32
+ * target keeps its current lifecycle: a terminal child stays terminal and keeps
33
+ * owing a final report, which is what wakes the manager. Either way the final
34
+ * latch is cleared and a done/canceled/dead row returns to active.
35
+ *
36
+ * Writing lifecycle first leaves a failed latch CAS with the canonical-final
37
+ * pointer intact. Both writes finish before either delivery channel begins. */
38
+ export declare function commitReopenResident(nodeId: string, expectedFinalReport?: string, callerNodeId?: string | null): Promise<string | null>;
29
39
  /** Convenience wrapper for a doorway with NO intervening fallible step between
30
40
  * the gate check and the reopen clear (`node lifecycle revive` has nothing
31
41
  * fallible between the gate and `reviveNode`). Validates and, when `reopen`,
32
42
  * clears in one call.
33
43
  *
34
44
  * - `reopen` false + latched → throws `node_finalized`.
35
- * - `reopen` true + latched → makes the node resident and CAS-clears the latch (side effect) and returns.
45
+ * - `reopen` true + latched → settles lifecycle per `commitReopenResident` (resident, unless `callerNodeId` is the target's manager),
46
+ * CAS-clears the latch (side effect) and returns.
36
47
  * - `reopen` true + not latched → throws `not_finalized`.
37
48
  * - `reopen` false + not latched → no-op (the common case). */
38
- export declare function assertReopenGate(nodeId: string, reopen: boolean): void;
49
+ export declare function assertReopenGate(nodeId: string, reopen: boolean, callerNodeId?: string | null): Promise<void>;
@@ -1 +1 @@
1
- var s=Object.defineProperty;var n=(e,t)=>s(e,"name",{value:t,configurable:!0});import{clearFinalReportIfMatches as l,getFinalReport as c,getNode as p,updateNode as u}from"../canvas/index.js";import{InputError as i}from"../io.js";import{transition as f}from"./lifecycle.js";import{noticeChangedWhileDone as h}from"./ledger.js";function o(e){return c(e)}n(o,"currentFinalReport");function m(e,t){throw new i({error:"node_finalized",message:`${e} already submitted its canonical final result (\`crtr canvas read ${e}/${t}\`) \u2014 reviving it now would hand it a mandate it can never finish, since a second \`push final\` always errors against an already-latched node.`,next:`Re-run this exact command with --reopen to clear ${e}'s spent latch and re-task it in place.`})}n(m,"throwNodeFinalized");function d(e){throw new i({error:"not_finalized",message:`${e} is not finalized \u2014 --reopen has nothing to clear.`,next:"Drop --reopen."})}n(d,"throwNotFinalized");function w(e){const t=o(e);t!==null&&m(e,t)}n(w,"assertNotFinalized");function g(e){const t=o(e);return t===null&&d(e),t}n(g,"assertFinalizedForReopen");function R(e,t){if(!l(e,t))throw new i({error:"reopen_latch_changed",message:`${e}'s finalization latch changed since it was last inspected \u2014 a concurrent --reopen (or a fresh push final) already moved it, so clearing it now would risk erasing a newer canonical result.`,next:"Re-run this exact command \u2014 it will re-inspect the current state before acting."})}n(R,"commitReopen");function x(e,t){const r=o(e);u(e,{lifecycle:"resident"});const a=p(e);return a!==null&&(a.status==="done"||a.status==="canceled"||a.status==="dead")&&(a.status==="done"&&a.last_settled_at!=null&&h(e,a.last_settled_at),f(e,"revive")),r!==null&&R(e,t??r),r}n(x,"commitReopenResident");function y(e,t){if(t){const r=g(e);x(e,r);return}w(e)}n(y,"assertReopenGate");export{g as assertFinalizedForReopen,w as assertNotFinalized,y as assertReopenGate,R as commitReopen,x as commitReopenResident};
1
+ var c=Object.defineProperty;var a=(t,e)=>c(t,"name",{value:e,configurable:!0});import{clearFinalReportIfMatches as l,getFinalReport as f,getNode as u,updateNode as p}from"../canvas/index.js";import{subscribersOf as w}from"../canvas/tree.js";import{InputError as o}from"../io.js";import{transition as m}from"./lifecycle.js";import{noticeChangedWhileDone as h}from"./ledger.js";async function s(t){return await f(t)}a(s,"currentFinalReport");function d(t,e){throw new o({error:"node_finalized",message:`${t} already submitted its canonical final result (\`crtr canvas read ${t}/${e}\`) \u2014 reviving it now would hand it a mandate it can never finish, since a second \`push final\` always errors against an already-latched node.`,next:`Re-run this exact command with --reopen to clear ${t}'s spent latch and re-task it in place.`})}a(d,"throwNodeFinalized");function g(t){throw new o({error:"not_finalized",message:`${t} is not finalized \u2014 --reopen has nothing to clear.`,next:"Drop --reopen."})}a(g,"throwNotFinalized");async function R(t){const e=await s(t);e!==null&&d(t,e)}a(R,"assertNotFinalized");async function y(t){const e=await s(t);return e===null&&g(t),e}a(y,"assertFinalizedForReopen");async function x(t,e){if(!await l(t,e))throw new o({error:"reopen_latch_changed",message:`${t}'s finalization latch changed since it was last inspected \u2014 a concurrent --reopen (or a fresh push final) already moved it, so clearing it now would risk erasing a newer canonical result.`,next:"Re-run this exact command \u2014 it will re-inspect the current state before acting."})}a(x,"commitReopen");async function F(t,e){return t==null?!1:(await w(e)).some(i=>i.node_id===t)}a(F,"isManagerOf");async function _(t,e,i){const r=await s(t);await F(i,t)||await p(t,{lifecycle:"resident"});const n=await u(t);return n!==null&&(n.status==="done"||n.status==="canceled"||n.status==="dead")&&(n.status==="done"&&n.last_settled_at!=null&&await h(t,n.last_settled_at),await m(t,"revive")),r!==null&&await x(t,e??r),r}a(_,"commitReopenResident");async function D(t,e,i){if(e){const r=await y(t);await _(t,r,i);return}await R(t)}a(D,"assertReopenGate");export{y as assertFinalizedForReopen,R as assertNotFinalized,D as assertReopenGate,x as commitReopen,_ as commitReopenResident};
@@ -11,7 +11,7 @@ import { respawnPaneSync } from './placement.js';
11
11
  * explicit: an abrupt broker teardown fires NO clean `session_shutdown`, so the
12
12
  * general quit→done rule does NOT auto-resolve a force-killed descendant — we
13
13
  * mark it `canceled` here via the same `cancel` event the close cascade uses. */
14
- export declare function reapDescendants(rootId: string): string[];
14
+ export declare function reapDescendants(rootId: string): Promise<string[]>;
15
15
  /** Injectable host/viewer seam, so the ordinary source test drives relaunchRoot's pure
16
16
  * DB transitions without a real broker or tmux. Each field defaults to its
17
17
  * production verb. */
@@ -51,7 +51,7 @@ export interface ResetRootResult {
51
51
  * `--session <id>` wakes the right conversation. A `/new` on a child is NOT a
52
52
  * graph reset — a root's `/new` is handled by relaunchRoot, never here; a root
53
53
  * that reaches this is a no-op. */
54
- export declare function resetRoot(nodeId: string, newSessionId?: string, newSessionFile?: string | null): ResetRootResult;
54
+ export declare function resetRoot(nodeId: string, newSessionId?: string, newSessionFile?: string | null): Promise<ResetRootResult>;
55
55
  export type HandleNewSessionPath = 'reset-child' | 'noop';
56
56
  export interface HandleNewSessionResult {
57
57
  path: HandleNewSessionPath;
@@ -59,10 +59,10 @@ export interface HandleNewSessionResult {
59
59
  /** The child-side `/new` entry the stophook calls (the root side goes to
60
60
  * relaunchRoot directly). The broker already drove the engine-side new_session;
61
61
  * this only refreshes the child's session id on the SAME node id. */
62
- export declare function handleNewSession(nodeId: string, newSessionId: string, newSessionFile?: string | null): HandleNewSessionResult;
62
+ export declare function handleNewSession(nodeId: string, newSessionId: string, newSessionFile?: string | null): Promise<HandleNewSessionResult>;
63
63
  /** Resolve a cleanly-exiting node to `done`. Returns true iff it transitioned.
64
64
  * Guard: only a real quit, and only a node still active|idle with no pending
65
65
  * intent — so it never clobbers a node already routed by agent_end to done
66
66
  * (push final), refresh (yield), or idle-release. Pure/DB-only (no pi/tmux) so
67
67
  * the guard is unit-testable without a live pi. */
68
- export declare function markCleanExitDone(nodeId: string, reason: unknown): boolean;
68
+ export declare function markCleanExitDone(nodeId: string, reason: unknown): Promise<boolean>;
@@ -1 +1 @@
1
- var S=Object.defineProperty;var l=(e,t)=>S(e,"name",{value:t,configurable:!0});import{getNode as p,beginExecution as B,recordExecutionPid as N,abortExecution as k,bindSession as b,recordLaunch as g,fullName as x,liveExecutionForNode as F,closeFocusRow as R,view as O}from"../canvas/index.js";import{transition as a}from"./lifecycle.js";import{headlessBrokerHost as y,requestBrokerTeardown as V}from"./host.js";import{boundFleet as C}from"./fleet.js";import{tearDownNode as D,focusOf as P,registerViewerFocus as T,respawnPaneSync as I,windowOfPane as L,renameWindow as q}from"./placement.js";import{viewerSplitEnv as A,waitForBrokerViewSocket as H}from"./placement-tmux.js";import{buildLaunchSpecAsync as M,buildPiArgv as U}from"./launch.js";import{newNodeId as j,spawnNode as W,rootOfSpine as X}from"./nodes.js";import{appSpace as $}from"../layout.js";import{join as z}from"node:path";import{invokeBirthLifecycleHooks as G}from"./spawn.js";function J(e){const t=[];for(const r of O(e))try{a(r,"cancel",{reason:"closed"}),V(r),D(r),t.push(r)}catch{}return t}l(J,"reapDescendants");async function le(e,t={}){const r=t.launchBroker??y.launch,s=t.waitForViewSocket??H,m=t.respawnViewer??I,c=t.teardownBroker??y.teardown,o=p(e);if(o===null||o.parent!=null||o.status==="done")return null;const d=P(e),h=o.isolated?j():void 0,_=h?z($(o.grantee??"app:terminal").nodes,h):o.cwd,{launch:E}=await M(o.kind,"base",{lifecycle:"resident",hasManager:!1,model:o.model_override??void 0,modelIntent:o.launch?.modelIntent,modelExact:o.launch?.modelExact,cwd:_,profileId:o.profile_id}),n=await W({nodeId:h,kind:o.kind,mode:"base",lifecycle:"resident",cwd:_,name:o.kind,parent:null,replaces:e,profile_id:o.profile_id,launch:E,modelOverride:o.model_override??void 0});await G(n);const u=U(n,{});u.env={...u.env,CRTR_SUBTREE:X(n.node_id)};const f=B(n.node_id,{daemonEpoch:C().epoch()});u.env={...u.env,CRTR_EXECUTION_ID:f};let w;try{w=await r(n.node_id,u,{cwd:_,name:x(n),resuming:!1})}catch(i){throw k(f,{reason:"launch_failed"}),a(n.node_id,"crash"),i}if(w.pid==null)return k(f,{reason:"launch_failed"}),a(n.node_id,"crash"),null;if(g(n.node_id,new Date().toISOString()),N(f,n.node_id,w.pid)==="shutdown"){k(f,{reason:"superseded"});try{c(n.node_id)}catch{}return a(n.node_id,"crash"),null}let v=!1;try{v=await s(n.node_id,w.exited)}catch{}if(!v){const i=p(n.node_id);(i?.status==="active"||i?.status==="idle")&&a(n.node_id,"crash");try{c(n.node_id)}catch{}return null}if(J(e),a(e,"finish"),d?.pane!=null){R(d.focus_id),m({pane:d.pane,cwd:o.cwd,env:A(),command:`crtr surface attach to ${n.node_id}`});const i=L(d.pane);i!==null&&q(i,x(n)),T(n.node_id,d.pane,d.session,i)}return c(e),{newNodeId:n.node_id}}l(le,"relaunchRoot");function K(e,t,r){const s=p(e),m={reaped:[],detached:[],reset:!1};if(s===null||s.parent==null)return m;if(t!==void 0){const c=F(e);c!==null&&b(e,{executionId:c.executionId,sessionId:t,transcriptPath:r??null})}return m}l(K,"resetRoot");function se(e,t,r){return p(e)===null?{path:"noop"}:(K(e,t,r),{path:"reset-child"})}l(se,"handleNewSession");function ue(e,t){if(t!=="quit")return!1;const r=p(e);return r===null||r.status!=="active"&&r.status!=="idle"||r.intent!=null?!1:(a(e,"finish"),!0)}l(ue,"markCleanExitDone");export{se as handleNewSession,ue as markCleanExitDone,J as reapDescendants,le as relaunchRoot,K as resetRoot};
1
+ var S=Object.defineProperty;var s=(e,t)=>S(e,"name",{value:t,configurable:!0});import{getNode as f,beginExecution as B,recordExecutionPid as N,abortExecution as v,bindSession as b,recordLaunch as g,fullName as x,liveExecutionForNode as F,closeFocusRow as R,view as O}from"../canvas/index.js";import{transition as r}from"./lifecycle.js";import{headlessBrokerHost as y,requestBrokerTeardown as V}from"./host.js";import{boundFleet as C}from"./fleet.js";import{tearDownNode as D,focusOf as P,registerViewerFocus as T,respawnPaneSync as I,windowOfPane as L,renameWindow as q}from"./placement.js";import{viewerSplitEnv as A,waitForBrokerViewSocket as H}from"./placement-tmux.js";import{buildLaunchSpecAsync as M,buildPiArgv as U}from"./launch.js";import{newNodeId as j,spawnNode as W,rootOfSpine as X}from"./nodes.js";import{appSpace as $}from"../layout.js";import{join as z}from"node:path";import{invokeBirthLifecycleHooks as G}from"./spawn.js";async function J(e){const t=[];for(const i of await O(e))try{await r(i,"cancel",{reason:"closed"}),V(i),await D(i),t.push(i)}catch{}return t}s(J,"reapDescendants");async function se(e,t={}){const i=t.launchBroker??y.launch,l=t.waitForViewSocket??H,p=t.respawnViewer??I,c=t.teardownBroker??y.teardown,a=await f(e);if(a===null||a.parent!=null||a.status==="done")return null;const d=await P(e),h=a.isolated?await j():void 0,_=h?z($(a.grantee??"app:terminal").nodes,h):a.cwd,{launch:E}=await M(a.kind,"base",{lifecycle:"resident",hasManager:!1,model:a.model_override??void 0,modelIntent:a.launch?.modelIntent,modelExact:a.launch?.modelExact,cwd:_,profileId:a.profile_id}),n=await W({nodeId:h,kind:a.kind,mode:"base",lifecycle:"resident",cwd:_,name:a.kind,parent:null,replaces:e,profile_id:a.profile_id,launch:E,modelOverride:a.model_override??void 0});await G(n);const u=U(n,{});u.env={...u.env,CRTR_SUBTREE:await X(n.node_id)};const w=await B(n.node_id,{daemonEpoch:C().epoch()});u.env={...u.env,CRTR_EXECUTION_ID:w};let m;try{m=await i(n.node_id,u,{cwd:_,name:x(n),resuming:!1})}catch(o){throw await v(w,{reason:"launch_failed"}),await r(n.node_id,"crash"),o}if(m.pid==null)return await v(w,{reason:"launch_failed"}),await r(n.node_id,"crash"),null;if(await g(n.node_id,new Date().toISOString()),await N(w,n.node_id,m.pid)==="shutdown"){await v(w,{reason:"superseded"});try{c(n.node_id)}catch{}return await r(n.node_id,"crash"),null}let k=!1;try{k=await l(n.node_id,m.exited)}catch{}if(!k){const o=await f(n.node_id);(o?.status==="active"||o?.status==="idle")&&await r(n.node_id,"crash");try{c(n.node_id)}catch{}return null}if(await J(e),await r(e,"finish"),d?.pane!=null){await R(d.focus_id),p({pane:d.pane,cwd:a.cwd,env:A(),command:`crtr surface attach to ${n.node_id}`});const o=L(d.pane);o!==null&&q(o,x(n)),await T(n.node_id,d.pane,d.session,o)}return c(e),{newNodeId:n.node_id}}s(se,"relaunchRoot");async function K(e,t,i){const l=await f(e),p={reaped:[],detached:[],reset:!1};if(l===null||l.parent==null)return p;if(t!==void 0){const c=await F(e);c!==null&&await b(e,{executionId:c.executionId,sessionId:t,transcriptPath:i??null})}return p}s(K,"resetRoot");async function le(e,t,i){return await f(e)===null?{path:"noop"}:(await K(e,t,i),{path:"reset-child"})}s(le,"handleNewSession");async function ue(e,t){if(t!=="quit")return!1;const i=await f(e);return i===null||i.status!=="active"&&i.status!=="idle"||i.intent!=null?!1:(await r(e,"finish"),!0)}s(ue,"markCleanExitDone");export{le as handleNewSession,ue as markCleanExitDone,J as reapDescendants,se as relaunchRoot,K as resetRoot};
@@ -35,7 +35,7 @@ export declare function isDisconnected(meta: NodeMeta, isAlive: (pid: number | n
35
35
  /** Every disconnected node on the canvas — the set a revive-all WOULD relaunch.
36
36
  * This is the PREVIEW: it has no side effects, so the command can list the
37
37
  * candidates and gate on confirmation before any engine is launched. */
38
- export declare function listDisconnected(): NodeMeta[];
38
+ export declare function listDisconnected(): Promise<NodeMeta[]>;
39
39
  export interface ReviveAllResult {
40
40
  /** Node ids whose broker engine reviveAll relaunched (RESUME). */
41
41
  revived: string[];
@@ -54,4 +54,4 @@ export interface ReviveAllResult {
54
54
  * no-op), so this is a thin orchestrator over `listDisconnected`: revive each
55
55
  * with resume:true. One failing node never aborts the sweep — its error is
56
56
  * collected and the rest proceed. */
57
- export declare function reviveAll(include?: (meta: NodeMeta) => boolean): Promise<ReviveAllResult>;
57
+ export declare function reviveAll(include?: (meta: NodeMeta) => Promise<boolean>): Promise<ReviveAllResult>;
@@ -1 +1 @@
1
- var t=Object.defineProperty;var n=(e,r)=>t(e,"name",{value:r,configurable:!0});import{listNodes as s,getNode as u}from"../canvas/index.js";import{recordedPidLiveness as d}from"../canvas/pid.js";import{reviveNode as f}from"./revive.js";const l=["done","canceled"];function c(e){return e.frozen_at==null&&(e.final_report!=null||l.includes(e.status))}n(c,"hasNoNaturalCycle");function p(e,r){return!(e.kind==="human"||r(e.pi_pid)||e.pi_session_id==null&&e.pi_session_file==null||c(e))}n(p,"isDisconnected");function a(){const e=[];for(const r of s()){const o=u(r.node_id);o!==null&&p(o,i=>d(i,o.pi_pid_identity)==="alive")&&e.push(o)}return e}n(a,"listDisconnected");async function y(e=()=>!0){const r={revived:[],failed:[],frozen:[]};for(const o of a().filter(e))try{(await f(o.node_id,{resume:!0,recovery:!0,capacity:"freeze"})).outcome==="frozen"?r.frozen.push(o.node_id):r.revived.push(o.node_id)}catch(i){r.failed.push({node_id:o.node_id,error:i.message})}return r}n(y,"reviveAll");export{l as TERMINAL_BY_CHOICE,c as hasNoNaturalCycle,p as isDisconnected,a as listDisconnected,y as reviveAll};
1
+ var t=Object.defineProperty;var i=(e,r)=>t(e,"name",{value:r,configurable:!0});import{listNodes as s,getNode as u}from"../canvas/index.js";import{recordedPidLiveness as c}from"../canvas/pid.js";import{reviveNode as d}from"./revive.js";import{filterAsync as f}from"../async-array.js";const l=["done","canceled"];function a(e){return e.frozen_at==null&&(e.final_report!=null||l.includes(e.status))}i(a,"hasNoNaturalCycle");function p(e,r){return!(e.kind==="human"||r(e.pi_pid)||e.pi_session_id==null&&e.pi_session_file==null||a(e))}i(p,"isDisconnected");async function _(){const e=[];for(const r of await s()){const o=await u(r.node_id);o!==null&&p(o,n=>c(n,o.pi_pid_identity)==="alive")&&e.push(o)}return e}i(_,"listDisconnected");async function N(e=async()=>!0){const r={revived:[],failed:[],frozen:[]};for(const o of await f(await _(),e))try{(await d(o.node_id,{resume:!0,recovery:!0,capacity:"freeze"})).outcome==="frozen"?r.frozen.push(o.node_id):r.revived.push(o.node_id)}catch(n){r.failed.push({node_id:o.node_id,error:n.message})}return r}i(N,"reviveAll");export{l as TERMINAL_BY_CHOICE,a as hasNoNaturalCycle,p as isDisconnected,_ as listDisconnected,N as reviveAll};
@@ -21,16 +21,16 @@ import { headlessBrokerHost } from './host.js';
21
21
  * branch (`--crtr-new-cycle`) rather than continuing the existing leaf. Pure
22
22
  * so the decision is unit-testable without tmux or a real filesystem fixture
23
23
  * beyond a temp file. */
24
- export declare function resumeArgs(meta: NodeMeta, resume: boolean): {
24
+ export declare function resumeArgs(meta: NodeMeta, resume: boolean): Promise<{
25
25
  resumeSessionPath?: string;
26
26
  newCycle?: boolean;
27
- };
27
+ }>;
28
28
  /** Whether a fresh context window would have anything on disk to stand on: a
29
29
  * goal, a roadmap, or both. The negative is what makes a fresh cycle worse
30
30
  * than a resume — the new window would wake amnesiac, with no statement of
31
31
  * what it is for. Read by the parked-resident veto below and by the message
32
32
  * handler's explicit fresh-revive gate. */
33
- export declare function hasFreshGroundState(nodeId: string): boolean;
33
+ export declare function hasFreshGroundState(nodeId: string): Promise<boolean>;
34
34
  export interface ReviveResult {
35
35
  /** Always null — the broker engine is never placed in a tmux window. Kept on
36
36
  * the result for caller back-compat. */
@@ -50,7 +50,7 @@ export interface ReviveResult {
50
50
  * `beginBootFaultAttempt` at the exact clear-then-launch boundary below.
51
51
  * Present only when a fresh launch actually happened (absent on the
52
52
  * double-revive no-op, where nothing was cleared or relaunched). */
53
- faultExplanation?: () => string | null;
53
+ faultExplanation?: () => Promise<string | null>;
54
54
  /** What this call actually did. `already-live` means a broker was already
55
55
  * running for the node and nothing was launched; `frozen` means no slot was
56
56
  * free and the row is now waiting for one — the tick thaws it. */
@@ -1,3 +1,3 @@
1
- var Y=Object.defineProperty;var l=(e,r)=>Y(e,"name",{value:r,configurable:!0});import{assertGranteeRunsHere as q}from"./unsandboxed.js";import{existsSync as B}from"node:fs";import{conversationIdFromPath as p,conversationStore as h,ConversationNotFoundError as O}from"../conversation-store/index.js";import{isAbsolute as Q}from"node:path";import{findNodeBySessionFile as Z,getNode as R,updateNode as E,beginExecution as I,recordExecutionPid as ee,abortExecution as S,endLiveExecution as re,unbindSession as T,recordLaunch as ie,setFrozen as ne,clearFrozen as te,fullName as D}from"../canvas/index.js";import{emitEvent as oe}from"../events/emit.js";import{cancelCronsOnWake as se}from"../canvas/crons.js";import{isParked as le,transition as x}from"./lifecycle.js";import{publishNotice as ce}from"./close.js";import{InputError as $}from"../io.js";import{buildPiArgv as v}from"./launch.js";import{buildReviveKickoff as ae,drainBearings as ue,hasRetainedReports as fe,readGoal as y,readYieldMessage as de,RUNTIME_RESTART_CONTINUATION as he}from"./kickoff.js";import{readRoadmap as z}from"./roadmap.js";import{encodeKickoffOrigin as pe,KICKOFF_ORIGIN_ENV as ve}from"./stamp/protocol.js";import{headlessBrokerHost as H}from"./host.js";import{appMemoryFull as me,appMemoryTooSmall as we,boundFleet as M,brokerCapReached as _e,brokerThresholdsForDaemon as U}from"./fleet.js";import{admitBrokerMemory as ke}from"./memory-admission.js";import{beginBootFaultAttempt as ye,clearFault as ge,hasAdmittedTurn as be}from"../canvas/recovery.js";import{clearNodeLedger as K,forkNodeLedger as Re,noticeChangedWhileDone as Ee}from"./ledger.js";import{forkSourceNode as Se,rootOfSpine as xe}from"./nodes.js";import{isReviewCompanionBound as $e}from"../review/companion.js";import{assertProfileActive as Ce}from"../profiles/manifest.js";import{isPidAlive as Ne}from"../canvas/pid.js";import{crtrHome as Fe,jobDir as Pe}from"../canvas/paths.js";import{contextDir as Ae,ensureNodeDirs as Be,nodeAgentDir as Oe}from"../canvas/node-agent-paths.js";import{discoverLifecycleHookRegistry as Te}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as De}from"../command-hooks/transport/exec-lifecycle.js";function ze(e,r){const i=e.pi_session_file,n=i?p(i):null;if(n===null)return{};try{const t=h().header(n);return r?{resumeSessionPath:t.path}:{resumeSessionPath:t.path,newCycle:!0}}catch(t){if(t instanceof O)return{};throw t}}l(ze,"resumeArgs");function G(e){const r=p(e);if(r===null)return!1;try{return h().header(r),!0}catch(i){if(i instanceof O)return!1;throw i}}l(G,"conversationExists");function He(e){const r=p(e);return r===null?!0:h().read(r).entries.some(i=>i.type==="message")}l(He,"sessionHasConversation");function Me(e){const r=p(e);if(r===null)return!0;const i=h().header(r).header.cwd;return typeof i!="string"||B(i)}l(Me,"sessionCwdExists");function Ue(e,r,i){const n=r.pi_session_file;if(!n||!G(n))return{};const t=Z(n);return t!==null&&t.node_id!==e&&Ne(t.pi_pid)?{}:Me(n)?ze(r,i):{}}l(Ue,"resumableSessionArgs");function Ke(e){return z(e)===null&&de(e)===null&&!fe(e)}l(Ke,"isUnstartedBirth");function _r(e){const r=y(e);if(r!==null&&r.trim()!=="")return!0;const i=z(e);return i!==null&&i.trim()!==""}l(_r,"hasFreshGroundState");async function kr(e,r){const i=await L(e,r,!0);if(i.parked)throw new Error(`reviveNode: internal parked decision for activating revive ${e}`);return i.result}l(kr,"reviveNode");async function yr(e,r,i){return L(e,{...r,viewerAttach:!0},i)}l(yr,"decideAttachRevive");async function L(e,r,i){let n=R(e);if(n===null)throw new Error(`reviveNode: unknown node ${e}`);if(n=R(e)??n,n.run_id&&R(n.run_id)?.deleting_at)throw new Error("run is deleting");if(n.final_report!==null)throw new Error(`reviveNode: refusing to revive ${e} \u2014 its finalization latch is set (final_report=${n.final_report}). A final landed between the caller's reopen-gate check and this revive; re-run with --reopen if this retask is still wanted.`);Ce(n.profile_id),q(n.grantee);const t=M();if(t.has(e))return x(e,n.intent==="refresh"?"refresh-launch":"revive"),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(t.isClaimed(e))return{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(!i&&n.lifecycle==="resident"&&le(n))return{parked:!0};const c=t.reserveSlot(e);let s=null;if(c){try{s=await ke(e)}catch(u){throw t.releaseReservation(e),u}s.verdict!=="admitted"&&t.releaseReservation(e)}if(s?.verdict==="too_small")throw we(s);if(!c||s?.verdict==="denied"){if(r.capacity==="refuse")throw s?.verdict==="denied"?me(s):_e(U().automaticReviveCap,t.size());return n.frozen_at==null&&(ne(e,new Date().toISOString()),re(e,{reason:"frozen"}),oe({level:"info",event:"broker.frozen",node_id:e,fields:s?.verdict==="denied"?{reason:"app_memory",free_bytes:s.free_bytes,needed_bytes:s.needed_bytes}:{reason:"broker_cap",live_count:t.size(),hard_cap:U().automaticReviveCap}})),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"frozen"}}}try{return{parked:!1,result:await Ge(e,n,r)}}finally{t.releaseReservation(e)}}l(L,"decideRevive");async function Ge(e,r,i){if(!B(r.cwd)){const m=r.fork_from!=null?`Restore ${r.cwd}, then revive the fork normally with \`crtr node lifecycle revive ${e}\`.`:r.managed_worktree?.state==="open"?"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon recovery.":`Recreate ${r.cwd}, or repair it with \`crtr node config --cwd <path> --node ${e}\`; durable node work resumes in a fresh conversation. Then retry \`crtr node lifecycle revive ${e}\`.`;throw new $({error:"cwd_missing",message:`${e} cannot be revived \u2014 its recorded cwd no longer exists: ${r.cwd}`,next:m})}r.host_kind!=="broker"&&(E(e,{host_kind:"broker"}),r.host_kind="broker"),r.review_binding!=null&&!$e(e)&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(T(e),r.pi_session_id=null,r.pi_session_file=null);const t=r.fork_from!=null&&r.pi_session_id==null,c=r.fork_source_file;if(t&&(typeof c!="string"||!Q(c)))throw new $({error:"fork_source_invalid",message:`${e} cannot be revived \u2014 its resolved fork source file is missing or invalid.`,next:`Restore the node's fork source metadata, then retry \`crtr node lifecycle revive ${e}\`.`});const s=t&&typeof c=="string";if(s&&!G(c))throw new $({error:"fork_from_missing",message:`${e} cannot be revived \u2014 its fork source no longer exists: ${c}`,next:`Restore ${c}, or update the node's fork source, then retry \`crtr node lifecycle revive ${e}\`.`});const u=I(e,{daemonEpoch:M().epoch()});try{r.cycles=(r.cycles??0)+1,E(e,{cycles:r.cycles});const j=r.intent==="refresh"||r.cycle_pending===!0?!1:i.resume,d=s?{}:Ue(e,r,j),w=d.resumeSessionPath!==void 0,C=w&&d.newCycle===!0,_=w&&!C,N=!w&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&Ke(e),g=_&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&!be(e)&&!He(d.resumeSessionPath)?y(e)?.trim():void 0,F=g!==void 0&&g!=="",W=s||N||F,P=r.cycle_pending===!0||C;E(e,{cycle_pending:P}),r.cycle_pending=P,!s&&!w&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(T(e),r.pi_session_id=null,r.pi_session_file=null);let a,f=null;const b=l(()=>({type:"runtime",kind:"kickoff",...r.spawned_by!=null&&r.spawned_by!==""?{spawnedBy:r.spawned_by}:{}}),"birthOrigin");if(s){const o=y(e),A=p(c);if(A===null)throw new Error(`invalid fork source ${c}`);const X=h().header(h().fork(A,e)).path;a=v(r,{resumeSessionPath:X,...o!=null&&o!==""?{prompt:o}:{}}),o!=null&&o!==""&&(f=b()),Re(e,Se(c)?.node_id??null)}else if(F)a=v(r,{...d,prompt:g}),f=b();else if(_)a=v(r,{...d,...i.wakeReason==="runtime-restart-abort"?{prompt:he}:{}}),i.wakeReason==="runtime-restart-abort"&&(f={type:"runtime",kind:"restart-continuation"});else if(N){const o=y(e)?.trim();a=v(r,o!==void 0&&o!==""?{prompt:o}:{}),o!==void 0&&o!==""&&(f=b()),K(e)}else{const o=ue(r,u);a=v(r,{...d,prompt:ae(r,o,i.wakeReason==="runtime-restart-abort"?void 0:i.wakeReason)}),r.run_id&&o.unreadMessageIds?.length&&(a.env.CRTR_KICKOFF_MESSAGE_IDS=JSON.stringify(o.unreadMessageIds)),f=i.wakeReason!==void 0&&i.wakeReason!=="runtime-restart-abort"?{type:"runtime",kind:"wake",wake:i.wakeReason}:{type:"runtime",kind:"revive",cycle:r.cycles??0},K(e)}a.env={...a.env,CRTR_SUBTREE:xe(e)},f!==null&&(a.env[ve]=pe(f)),r.status==="done"&&r.last_settled_at!=null&&Ee(e,r.last_settled_at),x(e,r.intent==="refresh"?"refresh-launch":"revive"),ge(e,{preserveEpisode:!0});const J=ye(e);i.recovery!==!0&&i.viewerAttach!==!0&&se(e),Be(e,r.grantee);const V=Te(r.cwd,r.profile_id).plans.get("node:start")??[];await De(V,{node:{id:e,name:r.name,kind:r.kind,mode:r.mode,lifecycle:r.lifecycle,cwd:r.cwd,nodeDir:Oe(e),contextDir:Ae(e),jobDir:Pe(e)},runtime:{isBirth:W,canvasHome:Fe(),profile:r.profile_id??null}}),a.env={...a.env,CRTR_EXECUTION_ID:u};let k;try{if(k=await H.launch(e,a,{cwd:r.cwd,name:D(r),resuming:_}),k.pid===null)throw new Error(`broker host returned no pid for ${e}`)}catch(o){try{x(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:o instanceof Error?o.message:String(o)}}}),ce(e,"notice.crash",`Child crashed \u2014 ${D(r)} (${e}) failed to relaunch and is now dead: ${o.message}
1
+ var Y=Object.defineProperty;var a=(e,r)=>Y(e,"name",{value:r,configurable:!0});import{assertGranteeRunsHere as q}from"./unsandboxed.js";import{existsSync as B}from"node:fs";import{conversationIdFromPath as h,conversationStore as d,ConversationNotFoundError as O}from"../conversation-store/index.js";import{isAbsolute as Q}from"node:path";import{findNodeBySessionFile as Z,getNode as R,updateNode as E,beginExecution as I,recordExecutionPid as ee,abortExecution as S,endLiveExecution as re,unbindSession as T,recordLaunch as ie,setFrozen as te,clearFrozen as ne,fullName as D}from"../canvas/index.js";import{emitEvent as oe}from"../events/emit.js";import{cancelCronsOnWake as se}from"../canvas/crons.js";import{isParked as ae,transition as x}from"./lifecycle.js";import{publishNotice as le}from"./close.js";import{InputError as $}from"../io.js";import{buildPiArgv as p}from"./launch.js";import{buildReviveKickoff as ce,drainBearings as ue,hasRetainedReports as fe,readGoal as k,readYieldMessage as we,RUNTIME_RESTART_CONTINUATION as de}from"./kickoff.js";import{readRoadmap as z}from"./roadmap.js";import{encodeKickoffOrigin as he,KICKOFF_ORIGIN_ENV as pe}from"./stamp/protocol.js";import{headlessBrokerHost as H}from"./host.js";import{appMemoryFull as ve,appMemoryTooSmall as me,boundFleet as M,brokerCapReached as _e,brokerThresholdsForDaemon as U}from"./fleet.js";import{admitBrokerMemory as ye}from"./memory-admission.js";import{beginBootFaultAttempt as ke,clearFault as ge,hasAdmittedTurn as be}from"../canvas/recovery.js";import{clearNodeLedger as K,forkNodeLedger as Re,noticeChangedWhileDone as Ee}from"./ledger.js";import{forkSourceNode as Se,rootOfSpine as xe}from"./nodes.js";import{isReviewCompanionBound as $e}from"../review/companion.js";import{assertProfileActive as Ce}from"../profiles/manifest.js";import{isPidAlive as Ne}from"../canvas/pid.js";import{crtrHome as Fe,jobDir as Pe}from"../canvas/paths.js";import{contextDir as Ae,ensureNodeDirs as Be,nodeAgentDir as Oe}from"../canvas/node-agent-paths.js";import{discoverLifecycleHookRegistry as Te}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as De}from"../command-hooks/transport/exec-lifecycle.js";async function ze(e,r){const i=e.pi_session_file,t=i?h(i):null;if(t===null)return{};try{const n=await d().header(t);return r?{resumeSessionPath:n.path}:{resumeSessionPath:n.path,newCycle:!0}}catch(n){if(n instanceof O)return{};throw n}}a(ze,"resumeArgs");async function G(e){const r=h(e);if(r===null)return!1;try{return await d().header(r),!0}catch(i){if(i instanceof O)return!1;throw i}}a(G,"conversationExists");async function He(e){const r=h(e);return r===null?!0:(await d().read(r)).entries.some(i=>i.type==="message")}a(He,"sessionHasConversation");async function Me(e){const r=h(e);if(r===null)return!0;const i=(await d().header(r)).header.cwd;return typeof i!="string"||B(i)}a(Me,"sessionCwdExists");async function Ue(e,r,i){const t=r.pi_session_file;if(!t||!await G(t))return{};const n=await Z(t);return n!==null&&n.node_id!==e&&Ne(n.pi_pid)?{}:await Me(t)?await ze(r,i):{}}a(Ue,"resumableSessionArgs");async function Ke(e){return await z(e)===null&&await we(e)===null&&!await fe(e)}a(Ke,"isUnstartedBirth");async function _r(e){const r=await k(e);if(r!==null&&r.trim()!=="")return!0;const i=await z(e);return i!==null&&i.trim()!==""}a(_r,"hasFreshGroundState");async function yr(e,r){const i=await L(e,r,!0);if(i.parked)throw new Error(`reviveNode: internal parked decision for activating revive ${e}`);return i.result}a(yr,"reviveNode");async function kr(e,r,i){return L(e,{...r,viewerAttach:!0},i)}a(kr,"decideAttachRevive");async function L(e,r,i){let t=await R(e);if(t===null)throw new Error(`reviveNode: unknown node ${e}`);if(t=await R(e)??t,t.run_id&&(await R(t.run_id))?.deleting_at)throw new Error("run is deleting");if(t.final_report!==null)throw new Error(`reviveNode: refusing to revive ${e} \u2014 its finalization latch is set (final_report=${t.final_report}). A final landed between the caller's reopen-gate check and this revive; re-run with --reopen if this retask is still wanted.`);Ce(t.profile_id),q(t.grantee);const n=M();if(n.has(e))return await x(e,t.intent==="refresh"?"refresh-launch":"revive"),{parked:!1,result:{window:null,session:t.tmux_session??null,resumed:!1,outcome:"already-live"}};if(n.isClaimed(e))return{parked:!1,result:{window:null,session:t.tmux_session??null,resumed:!1,outcome:"already-live"}};if(!i&&t.lifecycle==="resident"&&ae(t))return{parked:!0};const l=n.reserveSlot(e);let s=null;if(l){try{s=await ye(e)}catch(u){throw n.releaseReservation(e),u}s.verdict!=="admitted"&&n.releaseReservation(e)}if(s?.verdict==="too_small")throw me(s);if(!l||s?.verdict==="denied"){if(r.capacity==="refuse")throw s?.verdict==="denied"?ve(s):_e(U().automaticReviveCap,n.size());return t.frozen_at==null&&(await te(e,new Date().toISOString()),await re(e,{reason:"frozen"}),oe({level:"info",event:"broker.frozen",node_id:e,fields:s?.verdict==="denied"?{reason:"app_memory",free_bytes:s.free_bytes,needed_bytes:s.needed_bytes}:{reason:"broker_cap",live_count:n.size(),hard_cap:U().automaticReviveCap}})),{parked:!1,result:{window:null,session:t.tmux_session??null,resumed:!1,outcome:"frozen"}}}try{return{parked:!1,result:await Ge(e,t,r)}}finally{n.releaseReservation(e)}}a(L,"decideRevive");async function Ge(e,r,i){if(!B(r.cwd)){const v=r.fork_from!=null?`Restore ${r.cwd}, then revive the fork normally with \`crtr node lifecycle revive ${e}\`.`:r.managed_worktree?.state==="open"?"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon recovery.":`Recreate ${r.cwd}, or repair it with \`crtr node config --cwd <path> --node ${e}\`; durable node work resumes in a fresh conversation. Then retry \`crtr node lifecycle revive ${e}\`.`;throw new $({error:"cwd_missing",message:`${e} cannot be revived \u2014 its recorded cwd no longer exists: ${r.cwd}`,next:v})}r.host_kind!=="broker"&&(await E(e,{host_kind:"broker"}),r.host_kind="broker"),r.review_binding!=null&&!await $e(e)&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(await T(e),r.pi_session_id=null,r.pi_session_file=null);const n=r.fork_from!=null&&r.pi_session_id==null,l=r.fork_source_file;if(n&&(typeof l!="string"||!Q(l)))throw new $({error:"fork_source_invalid",message:`${e} cannot be revived \u2014 its resolved fork source file is missing or invalid.`,next:`Restore the node's fork source metadata, then retry \`crtr node lifecycle revive ${e}\`.`});const s=n&&typeof l=="string";if(s&&!await G(l))throw new $({error:"fork_from_missing",message:`${e} cannot be revived \u2014 its fork source no longer exists: ${l}`,next:`Restore ${l}, or update the node's fork source, then retry \`crtr node lifecycle revive ${e}\`.`});const u=await I(e,{daemonEpoch:M().epoch()});try{r.cycles=(r.cycles??0)+1,await E(e,{cycles:r.cycles});const j=r.intent==="refresh"||r.cycle_pending===!0?!1:i.resume,w=s?{}:await Ue(e,r,j),m=w.resumeSessionPath!==void 0,C=m&&w.newCycle===!0,_=m&&!C,N=!m&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&await Ke(e),g=_&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&!await be(e)&&!await He(w.resumeSessionPath)?(await k(e))?.trim():void 0,F=g!==void 0&&g!=="",W=s||N||F,P=r.cycle_pending===!0||C;await E(e,{cycle_pending:P}),r.cycle_pending=P,!s&&!m&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(await T(e),r.pi_session_id=null,r.pi_session_file=null);let c,f=null;const b=a(()=>({type:"runtime",kind:"kickoff",...r.spawned_by!=null&&r.spawned_by!==""?{spawnedBy:r.spawned_by}:{}}),"birthOrigin");if(s){const o=await k(e),A=h(l);if(A===null)throw new Error(`invalid fork source ${l}`);const X=(await d().header(await d().fork(A,e))).path;c=p(r,{resumeSessionPath:X,...o!=null&&o!==""?{prompt:o}:{}}),o!=null&&o!==""&&(f=b()),await Re(e,(await Se(l))?.node_id??null)}else if(F)c=p(r,{...w,prompt:g}),f=b();else if(_)c=p(r,{...w,...i.wakeReason==="runtime-restart-abort"?{prompt:de}:{}}),i.wakeReason==="runtime-restart-abort"&&(f={type:"runtime",kind:"restart-continuation"});else if(N){const o=(await k(e))?.trim();c=p(r,o!==void 0&&o!==""?{prompt:o}:{}),o!==void 0&&o!==""&&(f=b()),await K(e)}else{const o=await ue(r,u);c=p(r,{...w,prompt:await ce(r,o,i.wakeReason==="runtime-restart-abort"?void 0:i.wakeReason)}),r.run_id&&o.unreadMessageIds?.length&&(c.env.CRTR_KICKOFF_MESSAGE_IDS=JSON.stringify(o.unreadMessageIds)),f=i.wakeReason!==void 0&&i.wakeReason!=="runtime-restart-abort"?{type:"runtime",kind:"wake",wake:i.wakeReason}:{type:"runtime",kind:"revive",cycle:r.cycles??0},await K(e)}c.env={...c.env,CRTR_SUBTREE:await xe(e)},f!==null&&(c.env[pe]=he(f)),r.status==="done"&&r.last_settled_at!=null&&await Ee(e,r.last_settled_at),await x(e,r.intent==="refresh"?"refresh-launch":"revive"),await ge(e,{preserveEpisode:!0});const J=await ke(e);i.recovery!==!0&&i.viewerAttach!==!0&&await se(e),await Be(e,r.grantee);const V=Te(r.cwd,r.profile_id).plans.get("node:start")??[];await De(V,{node:{id:e,name:r.name,kind:r.kind,mode:r.mode,lifecycle:r.lifecycle,cwd:r.cwd,nodeDir:await Oe(e),contextDir:await Ae(e),jobDir:Pe(e)},runtime:{isBirth:W,canvasHome:Fe(),profile:r.profile_id??null}}),c.env={...c.env,CRTR_EXECUTION_ID:u};let y;try{if(y=await H.launch(e,c,{cwd:r.cwd,name:D(r),resuming:_}),y.pid===null)throw new Error(`broker host returned no pid for ${e}`)}catch(o){try{await x(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:o instanceof Error?o.message:String(o)}}}),await le(e,"notice.crash",`Child crashed \u2014 ${D(r)} (${e}) failed to relaunch and is now dead: ${o.message}
2
2
 
3
- It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,{reason:"child-crashed",child:e})}catch{}throw S(u,{reason:"launch_failed"}),new Error(`[broker] refusing to revive ${e}: ${o.message}`)}if(ie(e,new Date().toISOString()),ee(u,e,k.pid)==="shutdown")throw S(u,{reason:"superseded"}),H.teardown(e),new Error(`[broker] refusing to revive ${e}: execution was superseded during launch`);return te(e),{window:null,session:r.tmux_session??null,resumed:_,launch:k,faultExplanation:J.explanation,outcome:"launched"}}catch(m){throw S(u,{reason:"launch_failed"}),m}}l(Ge,"launchRevive");export{yr as decideAttachRevive,_r as hasFreshGroundState,ze as resumeArgs,kr as reviveNode};
3
+ It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,{reason:"child-crashed",child:e})}catch{}throw await S(u,{reason:"launch_failed"}),new Error(`[broker] refusing to revive ${e}: ${o.message}`)}if(await ie(e,new Date().toISOString()),await ee(u,e,y.pid)==="shutdown")throw await S(u,{reason:"superseded"}),H.teardown(e),new Error(`[broker] refusing to revive ${e}: execution was superseded during launch`);return await ne(e),{window:null,session:r.tmux_session??null,resumed:_,launch:y,faultExplanation:J.explanation,outcome:"launched"}}catch(v){throw await S(u,{reason:"launch_failed"}),v}}a(Ge,"launchRevive");export{kr as decideAttachRevive,_r as hasFreshGroundState,ze as resumeArgs,yr as reviveNode};
@@ -1,4 +1,4 @@
1
- import type { DatabaseSync } from 'node:sqlite';
1
+ import { type CanvasDb } from '../canvas/db.js';
2
2
  export declare const ROADMAP_NAME = "roadmap";
3
3
  /** Fallback preview when the roadmap is seeded without a goal. */
4
4
  export declare const ROADMAP_PREVIEW = "To understand this node's long-term task and current plan, read this.";
@@ -6,19 +6,19 @@ export declare const ROADMAP_PREVIEW = "To understand this node's long-term task
6
6
  export declare function roadmapPreview(goal?: string): string;
7
7
  /** How a node addresses its own roadmap in `crtr canvas read` / `crtr doc edit`. */
8
8
  export declare function roadmapRef(nodeId: string): string;
9
- export declare function hasRoadmap(nodeId: string): boolean;
9
+ export declare function hasRoadmap(nodeId: string): Promise<boolean>;
10
10
  /** The roadmap's newest head body, or null when the node has none. */
11
- export declare function readRoadmap(nodeId: string): string | null;
11
+ export declare function readRoadmap(nodeId: string): Promise<string | null>;
12
12
  /** Seed a fresh, EXTREMELY BAREBONES roadmap document — the section skeleton
13
13
  * with one-line prompts — authored by the node. The owner fleshes it out as
14
14
  * its next act with `crtr doc edit roadmap`. Leaves an existing roadmap
15
15
  * untouched and returns null; otherwise returns the seeded body. */
16
- export declare function seedRoadmap(db: DatabaseSync, nodeId: string, opts?: {
16
+ export declare function seedRoadmap(db: CanvasDb, nodeId: string, opts?: {
17
17
  goal?: string;
18
18
  exitCriteria?: string;
19
- }): string | null;
19
+ }): Promise<string | null>;
20
20
  /** `seedRoadmap` in its own canvas write; true when it wrote one. */
21
21
  export declare function ensureRoadmap(nodeId: string, opts?: {
22
22
  goal?: string;
23
23
  exitCriteria?: string;
24
- }): boolean;
24
+ }): Promise<boolean>;
@@ -1,15 +1,15 @@
1
- var l=Object.defineProperty;var r=(e,n)=>l(e,"name",{value:n,configurable:!0});import{openDb as u,withCanvasWrite as d}from"../canvas/db.js";import{get as s}from"../graph/bodies.js";import{heads as m,writeDocument as p}from"../graph/documents.js";import{asRuntimeWriter as c}from"../graph/spaces/own-memory.js";import{getById as f,liveDocumentNamed as h,nodeObject as g}from"../graph/objects.js";import{readerForNode as w}from"../graph/reader.js";const i="roadmap",x="To understand this node's long-term task and current plan, read this.";function R(e){return e?.split(`
2
- `).map(t=>t.trim()).find(t=>t!=="")??x}r(R,"roadmapPreview");function P(e){return`${e}/${i}`}r(P,"roadmapRef");function a(e,n){const t=f(e,n);return t===null||t.type!=="node"?null:h(e,t.rowid,i)}r(a,"roadmapObject");function $(e){return a(u(),e)!==null}r($,"hasRoadmap");function M(e){const n=u(),t=a(n,e);if(t===null)return null;const o=m(n,t)[0];if(o===void 0)return null;try{return s(o.body_hash)}catch{return null}}r(M,"readRoadmap");function y(e){return`# Roadmap
1
+ var l=Object.defineProperty;var r=(t,e)=>l(t,"name",{value:e,configurable:!0});import{openDb as u,withCanvasWrite as s}from"../canvas/db.js";import{get as c}from"../graph/bodies.js";import{heads as d,writeDocument as m}from"../graph/documents.js";import{asRuntimeWriter as p}from"../graph/spaces/own-memory.js";import{getById as f,liveDocumentNamed as w,nodeObject as h}from"../graph/objects.js";import{readerForNode as y}from"../graph/reader.js";const o="roadmap",g="To understand this node's long-term task and current plan, read this.";function x(t){return t?.split(`
2
+ `).map(n=>n.trim()).find(n=>n!=="")??g}r(x,"roadmapPreview");function P(t){return`${t}/${o}`}r(P,"roadmapRef");async function i(t,e){const n=await f(t,e);return n===null||n.type!=="node"?null:await w(t,n.rowid,o)}r(i,"roadmapObject");async function $(t){return await i(await u(),t)!==null}r($,"hasRoadmap");async function M(t){const e=await u(),n=await i(e,t);if(n===null)return null;const a=(await d(e,n))[0];if(a===void 0)return null;try{return c(a.body_hash)}catch{return null}}r(M,"readRoadmap");function R(t){return`# Roadmap
3
3
 
4
4
  ## Goal
5
- ${e.goal?.trim()||"(the goal you now own)"}
5
+ ${t.goal?.trim()||"(the goal you now own)"}
6
6
 
7
7
  ## Exit criteria
8
- ${e.exitCriteria?.trim()||'(what "done" looks like)'}
8
+ ${t.exitCriteria?.trim()||'(what "done" looks like)'}
9
9
 
10
10
  ## Where things stand
11
11
  (present state at your level: settled, in flight, remaining)
12
12
 
13
13
  ## Working set
14
14
  (links to the documents the work depends on now, one per line)
15
- `}r(y,"scaffold");function k(e,n,t={}){if(a(e,n)!==null)return null;const o=y(t);return p(e,c(w(e,n,()=>[])),{owner:g(e,n),name:i,kind:"knowledge",preview:R(t.goal),privacy:"public",rules:[{on:"boot",deliver:"content"}]},o),o}r(k,"seedRoadmap");function N(e,n={}){return d(t=>k(t,e,n)!==null)}r(N,"ensureRoadmap");export{i as ROADMAP_NAME,x as ROADMAP_PREVIEW,N as ensureRoadmap,$ as hasRoadmap,M as readRoadmap,R as roadmapPreview,P as roadmapRef,k as seedRoadmap};
15
+ `}r(R,"scaffold");async function k(t,e,n={}){if(await i(t,e)!==null)return null;const a=R(n);return await m(t,p(await y(t,e,async()=>[])),{owner:await h(t,e),name:o,kind:"knowledge",preview:x(n.goal),privacy:"public",rules:[{on:"boot",deliver:"content"}]},a),a}r(k,"seedRoadmap");async function N(t,e={}){return await s(async n=>await k(n,t,e)!==null)}r(N,"ensureRoadmap");export{o as ROADMAP_NAME,g as ROADMAP_PREVIEW,N as ensureRoadmap,$ as hasRoadmap,M as readRoadmap,x as roadmapPreview,P as roadmapRef,k as seedRoadmap};
@@ -4,4 +4,4 @@ export interface HumanForkCoordinates {
4
4
  leafId: string;
5
5
  }
6
6
  /** Fork the captured root-to-leaf branch without opening or mutating its live source. */
7
- export declare function materializeSessionBranch(coordinates: HumanForkCoordinates): string;
7
+ export declare function materializeSessionBranch(coordinates: HumanForkCoordinates): Promise<string>;
@@ -1 +1 @@
1
- var n=Object.defineProperty;var s=(e,r)=>n(e,"name",{value:r,configurable:!0});import{conversationIdFromPath as i,conversationStore as t}from"../conversation-store/index.js";function c(e){if(e.sourceSessionId===""||e.leafId==="")throw new Error("session branch coordinates require source session and leaf ids");const r=i(e.sourceFile);if(r===null||r!==e.sourceSessionId)throw new Error("source session id does not match captured coordinates");const o=t();if(o.header(r).header.id!==e.sourceSessionId)throw new Error("source session id does not match captured coordinates");return o.header(o.fork(r,void 0,e.leafId)).path}s(c,"materializeSessionBranch");export{c as materializeSessionBranch};
1
+ var n=Object.defineProperty;var s=(e,r)=>n(e,"name",{value:r,configurable:!0});import{conversationIdFromPath as i,conversationStore as a}from"../conversation-store/index.js";async function c(e){if(e.sourceSessionId===""||e.leafId==="")throw new Error("session branch coordinates require source session and leaf ids");const r=i(e.sourceFile);if(r===null||r!==e.sourceSessionId)throw new Error("source session id does not match captured coordinates");const o=a();if((await o.header(r)).header.id!==e.sourceSessionId)throw new Error("source session id does not match captured coordinates");return(await o.header(await o.fork(r,void 0,e.leafId))).path}s(c,"materializeSessionBranch");export{c as materializeSessionBranch};
@@ -1 +1 @@
1
- var T=Object.defineProperty;var c=(t,e)=>T(t,"name",{value:e,configurable:!0});import{readFile as D,rename as N,unlink as C,writeFile as A}from"node:fs/promises";import{resolve as M}from"node:path";import{conversationStore as p,ConversationNotFoundError as F}from"../conversation-store/index.js";const S=1024;function E(t){if(t.length<=S)return t;const e=S/2;return`${t.slice(0,e)} \u2026 ${t.slice(-e)}`}c(E,"compactSessionSearchText");const w=1,P=2e3;function g(t){return typeof t=="number"&&Number.isFinite(t)&&t>=0}c(g,"isFiniteNonNeg");function b(t){return t===void 0||typeof t=="string"}c(b,"isOptionalString");function x(t){if(typeof t!="object"||t===null)return!1;const e=t;return typeof e.path=="string"&&typeof e.id=="string"&&typeof e.cwd=="string"&&typeof e.created=="string"&&typeof e.modified=="string"&&g(e.messageCount)&&typeof e.firstMessage=="string"&&typeof e.allMessagesText=="string"&&b(e.name)&&b(e.parentSessionPath)}c(x,"isValidWireInfo");function O(t){if(typeof t!="object"||t===null)return!1;const e=t;return g(e.mtimeMs)&&g(e.size)&&x(e.info)}c(O,"isValidEntry");function _(t){const e=t.content;return typeof e=="string"?e:Array.isArray(e)?e.filter(i=>i.type==="text").map(i=>i.text).join(" "):""}c(_,"extractTextContent");function k(t){const e=t.message;if(!e||!("content"in e))return;const i=e.role;if(i!=="user"&&i!=="assistant")return;const s=e.timestamp;if(typeof s=="number")return s;const n=new Date(t.timestamp).getTime();return Number.isNaN(n)?void 0:n}c(k,"messageActivityTime");function v(t){try{const e=t.header;let i=0,s="";const n=[];let a,h;for(const f of p().read(t.conversation_id).entries){if(f.type==="session_info"&&(a=f.name?.trim()||void 0),f.type!=="message")continue;i++;const y=k(f);typeof y=="number"&&(h=Math.max(h??0,y));const u=f.message;if(!u||!("content"in u))continue;const m=u.role;if(m!=="user"&&m!=="assistant")continue;const d=_(u);d&&(n.push(d),!s&&m==="user"&&(s=d))}const r=typeof e.cwd=="string"?e.cwd:"",o=typeof e.timestamp=="string"?new Date(e.timestamp).getTime():NaN,l=typeof h=="number"&&h>0?new Date(h):Number.isNaN(o)?new Date(t.mtime):new Date(o);return{path:t.path,id:e.id,cwd:r,name:a,parentSessionPath:e.parentSession,created:new Date(e.timestamp).toISOString(),modified:l.toISOString(),messageCount:i,firstMessage:s||"(no messages)",allMessagesText:E(n.join(" "))}}catch(e){if(e instanceof F)return null;throw e}}c(v,"buildWireSessionInfo");class H{static{c(this,"SessionListCache")}cacheFile;cache=new Map;inflightDir=new Map;loadPromise=null;buildChain=Promise.resolve();persisting=!1;persistAgain=!1;persistTimer=null;constructor(e){this.cacheFile=e}listDir(e){const i=M(e),s=this.inflightDir.get(i);if(s)return s;const n=Promise.resolve().then(()=>this.buildDir(i));this.inflightDir.set(i,n);const a=c(()=>{this.inflightDir.get(i)===n&&this.inflightDir.delete(i)},"clear");return n.then(a,a),n}buildDir(e){const i=p().list().filter(s=>s.header.cwd===e);return this.build(i,s=>this.cache.get(s)?.info.cwd===e)}async listAll(){return this.build(p().list(),()=>!0)}build(e,i){const s=this.buildChain.then(()=>this.buildLocked(e,i));return this.buildChain=s.then(()=>{},()=>{}),s}async buildLocked(e,i){await this.ensureLoaded();const s=new Set(e.map(({path:r})=>r));let n=!1;for(const r of this.cache.keys())!s.has(r)&&i(r)&&(this.cache.delete(r),n=!0);const a=new Array(e.length);for(const[r,o]of e.entries()){const l=this.cache.get(o.path);if(l&&l.mtimeMs===o.mtime&&l.size===o.size){a[r]=l.info;continue}const f=v(o);if(n=!0,!f){this.cache.delete(o.path);continue}this.cache.set(o.path,{mtimeMs:o.mtime,size:o.size,info:f}),a[r]=f}n&&this.schedulePersist();const h=a.filter(r=>r!==void 0);return h.sort((r,o)=>new Date(o.modified).getTime()-new Date(r.modified).getTime()),h}ensureLoaded(){return this.loadPromise||(this.loadPromise=this.loadFromDisk()),this.loadPromise}async loadFromDisk(){try{const e=JSON.parse(await D(this.cacheFile,"utf8"));if(e?.version!==w||typeof e.entries!="object")return;for(const[i,s]of Object.entries(e.entries)){if(!O(s)){this.cache.clear();return}this.cache.set(i,s)}}catch{this.cache.clear()}}schedulePersist(){this.persistTimer||(this.persistTimer=setTimeout(()=>{this.persistTimer=null,this.persist()},P),this.persistTimer.unref?.())}async persist(){if(this.persisting){this.persistAgain=!0;return}this.persisting=!0;const e=`${this.cacheFile}.${process.pid}.tmp`;try{const i={};for(const[n,a]of this.cache)i[n]=a;await A(e,JSON.stringify({version:w,entries:i})),await N(e,this.cacheFile)}catch{await C(e).catch(()=>{})}finally{this.persisting=!1,this.persistAgain&&(this.persistAgain=!1,this.persist())}}}export{H as SessionListCache,E as compactSessionSearchText};
1
+ var T=Object.defineProperty;var c=(t,e)=>T(t,"name",{value:e,configurable:!0});import{readFile as D,rename as N,unlink as C,writeFile as A}from"node:fs/promises";import{resolve as M}from"node:path";import{conversationStore as p,ConversationNotFoundError as F}from"../conversation-store/index.js";const w=1024;function E(t){if(t.length<=w)return t;const e=w/2;return`${t.slice(0,e)} \u2026 ${t.slice(-e)}`}c(E,"compactSessionSearchText");const S=1,P=2e3;function g(t){return typeof t=="number"&&Number.isFinite(t)&&t>=0}c(g,"isFiniteNonNeg");function b(t){return t===void 0||typeof t=="string"}c(b,"isOptionalString");function x(t){if(typeof t!="object"||t===null)return!1;const e=t;return typeof e.path=="string"&&typeof e.id=="string"&&typeof e.cwd=="string"&&typeof e.created=="string"&&typeof e.modified=="string"&&g(e.messageCount)&&typeof e.firstMessage=="string"&&typeof e.allMessagesText=="string"&&b(e.name)&&b(e.parentSessionPath)}c(x,"isValidWireInfo");function O(t){if(typeof t!="object"||t===null)return!1;const e=t;return g(e.mtimeMs)&&g(e.size)&&x(e.info)}c(O,"isValidEntry");function _(t){const e=t.content;return typeof e=="string"?e:Array.isArray(e)?e.filter(i=>i.type==="text").map(i=>i.text).join(" "):""}c(_,"extractTextContent");function k(t){const e=t.message;if(!e||!("content"in e))return;const i=e.role;if(i!=="user"&&i!=="assistant")return;const s=e.timestamp;if(typeof s=="number")return s;const n=new Date(t.timestamp).getTime();return Number.isNaN(n)?void 0:n}c(k,"messageActivityTime");async function v(t){try{const e=t.header;let i=0,s="";const n=[];let a,h;for(const f of(await p().read(t.conversation_id)).entries){if(f.type==="session_info"&&(a=f.name?.trim()||void 0),f.type!=="message")continue;i++;const y=k(f);typeof y=="number"&&(h=Math.max(h??0,y));const u=f.message;if(!u||!("content"in u))continue;const m=u.role;if(m!=="user"&&m!=="assistant")continue;const d=_(u);d&&(n.push(d),!s&&m==="user"&&(s=d))}const r=typeof e.cwd=="string"?e.cwd:"",o=typeof e.timestamp=="string"?new Date(e.timestamp).getTime():NaN,l=typeof h=="number"&&h>0?new Date(h):Number.isNaN(o)?new Date(t.mtime):new Date(o);return{path:t.path,id:e.id,cwd:r,name:a,parentSessionPath:e.parentSession,created:new Date(e.timestamp).toISOString(),modified:l.toISOString(),messageCount:i,firstMessage:s||"(no messages)",allMessagesText:E(n.join(" "))}}catch(e){if(e instanceof F)return null;throw e}}c(v,"buildWireSessionInfo");class H{static{c(this,"SessionListCache")}cacheFile;cache=new Map;inflightDir=new Map;loadPromise=null;buildChain=Promise.resolve();persisting=!1;persistAgain=!1;persistTimer=null;constructor(e){this.cacheFile=e}listDir(e){const i=M(e),s=this.inflightDir.get(i);if(s)return s;const n=Promise.resolve().then(()=>this.buildDir(i));this.inflightDir.set(i,n);const a=c(()=>{this.inflightDir.get(i)===n&&this.inflightDir.delete(i)},"clear");return n.then(a,a),n}async buildDir(e){const i=(await p().list()).filter(s=>s.header.cwd===e);return this.build(i,s=>this.cache.get(s)?.info.cwd===e)}async listAll(){return this.build(await p().list(),()=>!0)}build(e,i){const s=this.buildChain.then(()=>this.buildLocked(e,i));return this.buildChain=s.then(()=>{},()=>{}),s}async buildLocked(e,i){await this.ensureLoaded();const s=new Set(e.map(({path:r})=>r));let n=!1;for(const r of this.cache.keys())!s.has(r)&&i(r)&&(this.cache.delete(r),n=!0);const a=new Array(e.length);for(const[r,o]of e.entries()){const l=this.cache.get(o.path);if(l&&l.mtimeMs===o.mtime&&l.size===o.size){a[r]=l.info;continue}const f=await v(o);if(n=!0,!f){this.cache.delete(o.path);continue}this.cache.set(o.path,{mtimeMs:o.mtime,size:o.size,info:f}),a[r]=f}n&&this.schedulePersist();const h=a.filter(r=>r!==void 0);return h.sort((r,o)=>new Date(o.modified).getTime()-new Date(r.modified).getTime()),h}ensureLoaded(){return this.loadPromise||(this.loadPromise=this.loadFromDisk()),this.loadPromise}async loadFromDisk(){try{const e=JSON.parse(await D(this.cacheFile,"utf8"));if(e?.version!==S||typeof e.entries!="object")return;for(const[i,s]of Object.entries(e.entries)){if(!O(s)){this.cache.clear();return}this.cache.set(i,s)}}catch{this.cache.clear()}}schedulePersist(){this.persistTimer||(this.persistTimer=setTimeout(()=>{this.persistTimer=null,this.persist()},P),this.persistTimer.unref?.())}async persist(){if(this.persisting){this.persistAgain=!0;return}this.persisting=!0;const e=`${this.cacheFile}.${process.pid}.tmp`;try{const i={};for(const[n,a]of this.cache)i[n]=a;await A(e,JSON.stringify({version:S,entries:i})),await N(e,this.cacheFile)}catch{await C(e).catch(()=>{})}finally{this.persisting=!1,this.persistAgain&&(this.persistAgain=!1,this.persist())}}}export{H as SessionListCache,E as compactSessionSearchText};
@@ -1 +1 @@
1
- var i=Object.defineProperty;var n=(t,e)=>i(t,"name",{value:e,configurable:!0});import{getNode as r}from"../canvas/index.js";import{deliverCustomMessageLive as a}from"./deliver-live.js";import{appendSituationalContext as l,formatSituationalProse as u,situationalContextEnvelope as s,SITUATIONAL_CONTEXT_CUSTOM_TYPE as m}from"./situational-context.js";async function C(t,e){if(l(t,u(e)),r(t)===null)throw new Error(`setSituationalContextLive: unknown node ${t}`);const o=s(t);o!==null&&await a(t,{customType:m,content:o,deliverAs:"nextTurn"})}n(C,"setSituationalContextLive");export{C as setSituationalContextLive};
1
+ var i=Object.defineProperty;var n=(t,e)=>i(t,"name",{value:e,configurable:!0});import{getNode as a}from"../canvas/index.js";import{deliverCustomMessageLive as r}from"./deliver-live.js";import{appendSituationalContext as l,formatSituationalProse as u,situationalContextEnvelope as s,SITUATIONAL_CONTEXT_CUSTOM_TYPE as m}from"./situational-context.js";async function C(t,e){if(l(t,u(e)),await a(t)===null)throw new Error(`setSituationalContextLive: unknown node ${t}`);const o=s(t);o!==null&&await r(t,{customType:m,content:o,deliverAs:"nextTurn"})}n(C,"setSituationalContextLive");export{C as setSituationalContextLive};