@north-light/cli 0.3.530 → 0.3.532

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 (495) hide show
  1. package/dist/clients/attach/session/connection.js +1 -1
  2. package/dist/clients/attach/session/reconnect.js +1 -1
  3. package/dist/clients/attach/viewer.js +508 -508
  4. package/dist/core/async-array.d.ts +7 -0
  5. package/dist/core/async-array.js +1 -0
  6. package/dist/core/audit.d.ts +1 -1
  7. package/dist/core/audit.js +2 -2
  8. package/dist/core/canvas/attention.d.ts +4 -4
  9. package/dist/core/canvas/attention.js +1 -1
  10. package/dist/core/canvas/boot.d.ts +4 -4
  11. package/dist/core/canvas/boot.js +1 -1
  12. package/dist/core/canvas/canvas.d.ts +59 -59
  13. package/dist/core/canvas/canvas.js +19 -19
  14. package/dist/core/canvas/context-strip.js +2 -2
  15. package/dist/core/canvas/crons.d.ts +27 -27
  16. package/dist/core/canvas/crons.js +11 -11
  17. package/dist/core/canvas/daemon-actions.d.ts +10 -10
  18. package/dist/core/canvas/daemon-actions.js +8 -8
  19. package/dist/core/canvas/daemon-owner.d.ts +3 -3
  20. package/dist/core/canvas/daemon-owner.js +2 -2
  21. package/dist/core/canvas/db.d.ts +19 -30
  22. package/dist/core/canvas/db.js +3 -2
  23. package/dist/core/canvas/deliveries.d.ts +16 -16
  24. package/dist/core/canvas/deliveries.js +24 -24
  25. package/dist/core/canvas/executions.d.ts +8 -8
  26. package/dist/core/canvas/executions.js +1 -1
  27. package/dist/core/canvas/focuses.d.ts +8 -8
  28. package/dist/core/canvas/focuses.js +1 -1
  29. package/dist/core/canvas/history.d.ts +3 -3
  30. package/dist/core/canvas/history.js +9 -9
  31. package/dist/core/canvas/install-id.d.ts +1 -1
  32. package/dist/core/canvas/install-id.js +1 -1
  33. package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +1 -1
  34. package/dist/core/canvas/managed-worktree-sweep-candidates.js +2 -2
  35. package/dist/core/canvas/memory-reads.d.ts +6 -6
  36. package/dist/core/canvas/memory-reads.js +1 -1
  37. package/dist/core/canvas/nav-model.d.ts +13 -13
  38. package/dist/core/canvas/nav-model.js +1 -1
  39. package/dist/core/canvas/node-agent-paths.d.ts +6 -6
  40. package/dist/core/canvas/node-agent-paths.js +1 -1
  41. package/dist/core/canvas/node-tokens.d.ts +7 -7
  42. package/dist/core/canvas/node-tokens.js +3 -3
  43. package/dist/core/canvas/outcome-actions.d.ts +5 -5
  44. package/dist/core/canvas/outcome-actions.js +3 -3
  45. package/dist/core/canvas/recovery.d.ts +26 -26
  46. package/dist/core/canvas/recovery.js +2 -2
  47. package/dist/core/canvas/render-source.d.ts +1 -1
  48. package/dist/core/canvas/render-source.js +1 -1
  49. package/dist/core/canvas/sessions.d.ts +10 -10
  50. package/dist/core/canvas/sessions.js +4 -4
  51. package/dist/core/canvas/source.js +1 -1
  52. package/dist/core/canvas/structured-requests.d.ts +15 -15
  53. package/dist/core/canvas/structured-requests.js +5 -5
  54. package/dist/core/canvas/tree.d.ts +9 -9
  55. package/dist/core/canvas/tree.js +5 -5
  56. package/dist/core/canvas/waits.d.ts +13 -13
  57. package/dist/core/canvas/waits.js +6 -6
  58. package/dist/core/canvas/worktrees.d.ts +15 -15
  59. package/dist/core/canvas/worktrees.js +1 -1
  60. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  61. package/dist/core/conversation-store/file-store.d.ts +7 -7
  62. package/dist/core/conversation-store/file-store.js +9 -9
  63. package/dist/core/conversation-store/index.d.ts +16 -14
  64. package/dist/core/conversation-store/index.js +1 -1
  65. package/dist/core/conversation-store/listener.js +5 -5
  66. package/dist/core/conversation-store/patch.d.ts +3 -1
  67. package/dist/core/conversation-store/patch.js +1 -1
  68. package/dist/core/feed/feed.js +3 -3
  69. package/dist/core/feed/inbox.d.ts +2 -2
  70. package/dist/core/feed/inbox.js +1 -1
  71. package/dist/core/feed/messages.d.ts +11 -12
  72. package/dist/core/feed/messages.js +5 -5
  73. package/dist/core/feed/reports.d.ts +4 -4
  74. package/dist/core/feed/reports.js +2 -2
  75. package/dist/core/grants/cover.d.ts +1 -1
  76. package/dist/core/grants/cover.js +1 -1
  77. package/dist/core/grants/local.d.ts +1 -1
  78. package/dist/core/grants/local.js +1 -1
  79. package/dist/core/grants/mirror.d.ts +19 -19
  80. package/dist/core/grants/mirror.js +2 -2
  81. package/dist/core/grants/on-sync.d.ts +1 -1
  82. package/dist/core/grants/on-sync.js +1 -1
  83. package/dist/core/grants/remove.js +1 -1
  84. package/dist/core/grants/sync.js +1 -1
  85. package/dist/core/graph/access.d.ts +17 -17
  86. package/dist/core/graph/access.js +3 -3
  87. package/dist/core/graph/custom.d.ts +16 -16
  88. package/dist/core/graph/custom.js +9 -9
  89. package/dist/core/graph/deletion.d.ts +3 -7
  90. package/dist/core/graph/deletion.js +4 -4
  91. package/dist/core/graph/documents.d.ts +24 -27
  92. package/dist/core/graph/documents.js +7 -7
  93. package/dist/core/graph/edges.d.ts +13 -13
  94. package/dist/core/graph/edges.js +1 -1
  95. package/dist/core/graph/events.d.ts +7 -9
  96. package/dist/core/graph/events.js +8 -8
  97. package/dist/core/graph/exposures.d.ts +6 -6
  98. package/dist/core/graph/exposures.js +4 -4
  99. package/dist/core/graph/jobs.d.ts +6 -8
  100. package/dist/core/graph/jobs.js +2 -2
  101. package/dist/core/graph/kinds/action.js +1 -1
  102. package/dist/core/graph/kinds/custom.js +2 -2
  103. package/dist/core/graph/kinds/document.d.ts +1 -0
  104. package/dist/core/graph/kinds/document.js +4 -4
  105. package/dist/core/graph/kinds/dto.d.ts +2 -2
  106. package/dist/core/graph/kinds/dto.js +1 -1
  107. package/dist/core/graph/kinds/job.js +2 -2
  108. package/dist/core/graph/kinds/kind.d.ts +6 -8
  109. package/dist/core/graph/kinds/kind.js +1 -1
  110. package/dist/core/graph/kinds/node.js +5 -5
  111. package/dist/core/graph/kinds/owner.js +2 -2
  112. package/dist/core/graph/kinds/registry.d.ts +6 -9
  113. package/dist/core/graph/kinds/registry.js +1 -1
  114. package/dist/core/graph/names.d.ts +6 -6
  115. package/dist/core/graph/names.js +3 -3
  116. package/dist/core/graph/object-waits.d.ts +4 -7
  117. package/dist/core/graph/object-waits.js +1 -1
  118. package/dist/core/graph/objects.d.ts +14 -14
  119. package/dist/core/graph/objects.js +9 -9
  120. package/dist/core/graph/package-docs.d.ts +2 -7
  121. package/dist/core/graph/package-docs.js +5 -5
  122. package/dist/core/graph/package-kinds.d.ts +2 -5
  123. package/dist/core/graph/package-kinds.js +1 -1
  124. package/dist/core/graph/package-reconcile.d.ts +2 -5
  125. package/dist/core/graph/package-reconcile.js +1 -1
  126. package/dist/core/graph/reader.d.ts +18 -18
  127. package/dist/core/graph/reader.js +3 -3
  128. package/dist/core/graph/receivers.d.ts +4 -4
  129. package/dist/core/graph/receivers.js +5 -5
  130. package/dist/core/graph/repo-sync/exchange.d.ts +3 -7
  131. package/dist/core/graph/repo-sync/exchange.js +2 -2
  132. package/dist/core/graph/repo-sync/repos.d.ts +7 -5
  133. package/dist/core/graph/repo-sync/repos.js +3 -3
  134. package/dist/core/graph/repo-sync/sync.d.ts +3 -6
  135. package/dist/core/graph/repo-sync/sync.js +2 -2
  136. package/dist/core/graph/rules.d.ts +5 -5
  137. package/dist/core/graph/rules.js +3 -3
  138. package/dist/core/graph/spaces/app.js +1 -1
  139. package/dist/core/graph/spaces/index.d.ts +4 -5
  140. package/dist/core/graph/spaces/index.js +1 -1
  141. package/dist/core/graph/spaces/own-memory.d.ts +4 -4
  142. package/dist/core/graph/spaces/own-memory.js +1 -1
  143. package/dist/core/graph/spaces/person.js +3 -3
  144. package/dist/core/graph/spaces/repo.d.ts +1 -1
  145. package/dist/core/graph/spaces/repo.js +1 -1
  146. package/dist/core/graph/watches.d.ts +15 -15
  147. package/dist/core/graph/watches.js +10 -10
  148. package/dist/core/human/feedback-companion.d.ts +2 -2
  149. package/dist/core/human/feedback-companion.js +1 -1
  150. package/dist/core/human/feedback.d.ts +3 -3
  151. package/dist/core/human/feedback.js +1 -1
  152. package/dist/core/human/requests.d.ts +34 -33
  153. package/dist/core/human/requests.js +20 -20
  154. package/dist/core/human/scan.d.ts +2 -2
  155. package/dist/core/human/scan.js +1 -1
  156. package/dist/core/human/tickets.d.ts +9 -9
  157. package/dist/core/human/tickets.js +1 -1
  158. package/dist/core/llm/app-rungs.d.ts +1 -1
  159. package/dist/core/llm/app-rungs.js +1 -1
  160. package/dist/core/llm/run.js +2 -2
  161. package/dist/core/peer/directory.d.ts +1 -1
  162. package/dist/core/peer/directory.js +1 -1
  163. package/dist/core/peer/envelope.d.ts +3 -3
  164. package/dist/core/peer/envelope.js +1 -1
  165. package/dist/core/peer/home.d.ts +13 -7
  166. package/dist/core/peer/home.js +2 -2
  167. package/dist/core/peer/ingest.d.ts +6 -6
  168. package/dist/core/peer/ingest.js +1 -1
  169. package/dist/core/peer/outbox-store.d.ts +14 -14
  170. package/dist/core/peer/outbox-store.js +5 -5
  171. package/dist/core/peer/receiver.d.ts +2 -2
  172. package/dist/core/peer/receiver.js +1 -1
  173. package/dist/core/peer/stubs.d.ts +10 -10
  174. package/dist/core/peer/stubs.js +1 -1
  175. package/dist/core/providers/approval.d.ts +2 -2
  176. package/dist/core/providers/approval.js +2 -2
  177. package/dist/core/providers/audit.d.ts +3 -3
  178. package/dist/core/providers/audit.js +2 -2
  179. package/dist/core/providers/bundles.js +2 -2
  180. package/dist/core/providers/call.d.ts +2 -2
  181. package/dist/core/providers/call.js +1 -1
  182. package/dist/core/providers/files.d.ts +1 -1
  183. package/dist/core/providers/files.js +1 -1
  184. package/dist/core/providers/mint.js +1 -1
  185. package/dist/core/providers/receipts.d.ts +1 -1
  186. package/dist/core/providers/receipts.js +2 -2
  187. package/dist/core/review/birth.js +1 -1
  188. package/dist/core/review/comments.d.ts +19 -19
  189. package/dist/core/review/comments.js +5 -5
  190. package/dist/core/review/companion.d.ts +1 -1
  191. package/dist/core/review/companion.js +1 -1
  192. package/dist/core/review/document.d.ts +3 -3
  193. package/dist/core/review/document.js +2 -2
  194. package/dist/core/review/fork.js +2 -2
  195. package/dist/core/review/realize.js +1 -1
  196. package/dist/core/review/remap.d.ts +2 -2
  197. package/dist/core/review/remap.js +4 -4
  198. package/dist/core/review/stage.d.ts +1 -1
  199. package/dist/core/review/stage.js +1 -1
  200. package/dist/core/review/store.d.ts +21 -21
  201. package/dist/core/review/store.js +1 -1
  202. package/dist/core/runs/activity.d.ts +1 -1
  203. package/dist/core/runs/activity.js +5 -5
  204. package/dist/core/runs/confinement.d.ts +7 -7
  205. package/dist/core/runs/confinement.js +2 -2
  206. package/dist/core/runs/events.d.ts +12 -12
  207. package/dist/core/runs/events.js +4 -4
  208. package/dist/core/runs/operations.d.ts +11 -11
  209. package/dist/core/runs/operations.js +5 -5
  210. package/dist/core/runs/questions.d.ts +10 -10
  211. package/dist/core/runs/questions.js +3 -3
  212. package/dist/core/runtime/auth-reload.js +1 -1
  213. package/dist/core/runtime/bearings.d.ts +5 -5
  214. package/dist/core/runtime/bearings.js +6 -6
  215. package/dist/core/runtime/broker-inventory.js +1 -1
  216. package/dist/core/runtime/broker-request.js +1 -1
  217. package/dist/core/runtime/broker.js +1 -1
  218. package/dist/core/runtime/close.d.ts +3 -3
  219. package/dist/core/runtime/close.js +1 -1
  220. package/dist/core/runtime/deliver-live.js +1 -1
  221. package/dist/core/runtime/fleet.d.ts +2 -2
  222. package/dist/core/runtime/host.d.ts +3 -3
  223. package/dist/core/runtime/host.js +3 -3
  224. package/dist/core/runtime/kickoff.d.ts +12 -12
  225. package/dist/core/runtime/kickoff.js +17 -17
  226. package/dist/core/runtime/launch-target.d.ts +1 -1
  227. package/dist/core/runtime/launch-target.js +1 -1
  228. package/dist/core/runtime/ledger.d.ts +3 -3
  229. package/dist/core/runtime/ledger.js +3 -3
  230. package/dist/core/runtime/lifecycle.d.ts +1 -1
  231. package/dist/core/runtime/lifecycle.js +2 -2
  232. package/dist/core/runtime/memory-admission.js +1 -1
  233. package/dist/core/runtime/model-swap.d.ts +2 -2
  234. package/dist/core/runtime/model-swap.js +1 -1
  235. package/dist/core/runtime/node-read.d.ts +1 -1
  236. package/dist/core/runtime/node-read.js +2 -2
  237. package/dist/core/runtime/nodes.d.ts +6 -6
  238. package/dist/core/runtime/nodes.js +1 -1
  239. package/dist/core/runtime/outcome-document.d.ts +1 -1
  240. package/dist/core/runtime/outcome-document.js +1 -1
  241. package/dist/core/runtime/persona.d.ts +3 -3
  242. package/dist/core/runtime/persona.js +2 -2
  243. package/dist/core/runtime/placement.d.ts +11 -11
  244. package/dist/core/runtime/placement.js +1 -1
  245. package/dist/core/runtime/promote.d.ts +3 -3
  246. package/dist/core/runtime/promote.js +1 -1
  247. package/dist/core/runtime/recycle.js +1 -1
  248. package/dist/core/runtime/reopen.d.ts +5 -5
  249. package/dist/core/runtime/reopen.js +1 -1
  250. package/dist/core/runtime/reset.d.ts +4 -4
  251. package/dist/core/runtime/reset.js +1 -1
  252. package/dist/core/runtime/revive-all.d.ts +2 -2
  253. package/dist/core/runtime/revive-all.js +1 -1
  254. package/dist/core/runtime/revive.d.ts +4 -4
  255. package/dist/core/runtime/revive.js +2 -2
  256. package/dist/core/runtime/roadmap.d.ts +6 -6
  257. package/dist/core/runtime/roadmap.js +5 -5
  258. package/dist/core/runtime/session-branch.d.ts +1 -1
  259. package/dist/core/runtime/session-branch.js +1 -1
  260. package/dist/core/runtime/session-list-cache.js +1 -1
  261. package/dist/core/runtime/situational-live.js +1 -1
  262. package/dist/core/runtime/spawn.d.ts +2 -2
  263. package/dist/core/runtime/spawn.js +2 -2
  264. package/dist/core/runtime/stop-guard.d.ts +2 -2
  265. package/dist/core/runtime/stop-guard.js +3 -3
  266. package/dist/core/runtime/warm-pool.d.ts +2 -2
  267. package/dist/core/runtime/warm-pool.js +1 -1
  268. package/dist/core/spaces/mounts.d.ts +2 -2
  269. package/dist/core/spaces/mounts.js +1 -1
  270. package/dist/core/spaces/permissions.d.ts +1 -1
  271. package/dist/core/spaces/permissions.js +1 -1
  272. package/dist/core/spaces/process.d.ts +1 -1
  273. package/dist/core/spaces/process.js +1 -1
  274. package/dist/core/spaces/space.js +1 -1
  275. package/dist/core/spaces/stop.d.ts +3 -3
  276. package/dist/core/spaces/stop.js +2 -2
  277. package/dist/core/spaces/users.d.ts +6 -6
  278. package/dist/core/spaces/users.js +1 -1
  279. package/dist/core/storage/attachments.d.ts +2 -2
  280. package/dist/core/storage/attachments.js +1 -1
  281. package/dist/core/storage/shares.d.ts +2 -2
  282. package/dist/core/storage/shares.js +1 -1
  283. package/dist/core/storage/tables.d.ts +21 -21
  284. package/dist/core/storage/tables.js +3 -3
  285. package/dist/core/substrate/delivery/corpus.d.ts +5 -8
  286. package/dist/core/substrate/delivery/corpus.js +3 -3
  287. package/dist/core/substrate/delivery/deliver.d.ts +10 -15
  288. package/dist/core/substrate/delivery/deliver.js +3 -3
  289. package/dist/core/substrate/delivery/plan.d.ts +2 -12
  290. package/dist/core/substrate/delivery/plan.js +3 -3
  291. package/dist/core/substrate/delivery/render-boot.d.ts +4 -4
  292. package/dist/core/substrate/delivery/render-boot.js +18 -18
  293. package/dist/core/substrate/delivery/render-event.d.ts +7 -14
  294. package/dist/core/substrate/delivery/render-event.js +4 -4
  295. package/dist/core/substrate/subject.d.ts +2 -2
  296. package/dist/core/substrate/subject.js +1 -1
  297. package/dist/core/usage/ledger.d.ts +6 -6
  298. package/dist/core/usage/ledger.js +4 -4
  299. package/dist/core/worktree-close.js +4 -4
  300. package/dist/core/worktree-mutation-async.js +7 -7
  301. package/dist/core/worktree-quarantine.js +1 -1
  302. package/dist/core/worktree-sweep.d.ts +1 -1
  303. package/dist/core/worktree-sweep.js +6 -6
  304. package/dist/core/worktree.d.ts +5 -5
  305. package/dist/core/worktree.js +13 -13
  306. package/dist/daemon/analytics/compute.d.ts +2 -2
  307. package/dist/daemon/analytics/compute.js +1 -1
  308. package/dist/daemon/api/app-listener.d.ts +4 -4
  309. package/dist/daemon/api/app-listener.js +13 -13
  310. package/dist/daemon/api/bridge.js +5 -5
  311. package/dist/daemon/api/document-listener.js +6 -6
  312. package/dist/daemon/api/handlers/analytics.js +1 -1
  313. package/dist/daemon/api/handlers/attach.js +1 -1
  314. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  315. package/dist/daemon/api/handlers/bash.js +1 -1
  316. package/dist/daemon/api/handlers/broker-ops.d.ts +1 -1
  317. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  318. package/dist/daemon/api/handlers/broker-recovery.d.ts +1 -1
  319. package/dist/daemon/api/handlers/broker-recovery.js +1 -1
  320. package/dist/daemon/api/handlers/broker-signals.d.ts +2 -2
  321. package/dist/daemon/api/handlers/broker-signals.js +2 -2
  322. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  323. package/dist/daemon/api/handlers/canvas.js +4 -4
  324. package/dist/daemon/api/handlers/chat-inventory.js +1 -1
  325. package/dist/daemon/api/handlers/crons.js +1 -1
  326. package/dist/daemon/api/handlers/custom-objects.d.ts +4 -4
  327. package/dist/daemon/api/handlers/custom-objects.js +3 -3
  328. package/dist/daemon/api/handlers/delivery-retry.js +1 -1
  329. package/dist/daemon/api/handlers/delivery.js +1 -1
  330. package/dist/daemon/api/handlers/docs.d.ts +4 -4
  331. package/dist/daemon/api/handlers/docs.js +1 -1
  332. package/dist/daemon/api/handlers/feedback-comments.js +3 -3
  333. package/dist/daemon/api/handlers/files.js +1 -1
  334. package/dist/daemon/api/handlers/focus.js +1 -1
  335. package/dist/daemon/api/handlers/health.js +3 -3
  336. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  337. package/dist/daemon/api/handlers/human-requests.js +1 -1
  338. package/dist/daemon/api/handlers/inbox-page.d.ts +1 -1
  339. package/dist/daemon/api/handlers/inbox-page.js +1 -1
  340. package/dist/daemon/api/handlers/inbox.d.ts +1 -1
  341. package/dist/daemon/api/handlers/inbox.js +1 -1
  342. package/dist/daemon/api/handlers/llm.d.ts +1 -1
  343. package/dist/daemon/api/handlers/llm.js +3 -3
  344. package/dist/daemon/api/handlers/memory-reads.js +1 -1
  345. package/dist/daemon/api/handlers/memory.d.ts +5 -5
  346. package/dist/daemon/api/handlers/memory.js +5 -5
  347. package/dist/daemon/api/handlers/messages.js +2 -2
  348. package/dist/daemon/api/handlers/node-events.d.ts +2 -2
  349. package/dist/daemon/api/handlers/node-events.js +3 -3
  350. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  351. package/dist/daemon/api/handlers/node-records.js +2 -2
  352. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  353. package/dist/daemon/api/handlers/nodes.js +1 -1
  354. package/dist/daemon/api/handlers/objects.js +3 -3
  355. package/dist/daemon/api/handlers/package-docs.js +1 -1
  356. package/dist/daemon/api/handlers/plugin-app-token.d.ts +1 -1
  357. package/dist/daemon/api/handlers/plugin-app-token.js +1 -1
  358. package/dist/daemon/api/handlers/profiles.d.ts +3 -3
  359. package/dist/daemon/api/handlers/profiles.js +1 -1
  360. package/dist/daemon/api/handlers/providers.d.ts +1 -1
  361. package/dist/daemon/api/handlers/providers.js +1 -1
  362. package/dist/daemon/api/handlers/questions.js +1 -1
  363. package/dist/daemon/api/handlers/reports.d.ts +1 -1
  364. package/dist/daemon/api/handlers/reports.js +5 -5
  365. package/dist/daemon/api/handlers/review-comments.js +1 -1
  366. package/dist/daemon/api/handlers/reviews.js +1 -1
  367. package/dist/daemon/api/handlers/runs.js +1 -1
  368. package/dist/daemon/api/handlers/structured-requests.js +1 -1
  369. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  370. package/dist/daemon/api/handlers/transfer.js +1 -1
  371. package/dist/daemon/api/map.d.ts +3 -3
  372. package/dist/daemon/api/map.js +1 -1
  373. package/dist/daemon/api/principal.d.ts +1 -1
  374. package/dist/daemon/api/principal.js +1 -1
  375. package/dist/daemon/api/reader.d.ts +5 -5
  376. package/dist/daemon/api/reader.js +1 -1
  377. package/dist/daemon/api/router.d.ts +5 -5
  378. package/dist/daemon/api/router.js +1 -1
  379. package/dist/daemon/api/server.js +1 -1
  380. package/dist/daemon/broker-signals/bus.d.ts +1 -1
  381. package/dist/daemon/broker-signals/bus.js +1 -1
  382. package/dist/daemon/companion-retire.js +1 -1
  383. package/dist/daemon/cron/armed-context.d.ts +2 -2
  384. package/dist/daemon/cron/armed-context.js +1 -1
  385. package/dist/daemon/cron/authority.d.ts +2 -2
  386. package/dist/daemon/cron/authority.js +1 -1
  387. package/dist/daemon/cron/disposition.js +1 -1
  388. package/dist/daemon/cron/ended.d.ts +1 -1
  389. package/dist/daemon/cron/ended.js +2 -2
  390. package/dist/daemon/cron/escalation.js +3 -3
  391. package/dist/daemon/cron/folders.d.ts +1 -1
  392. package/dist/daemon/cron/folders.js +1 -1
  393. package/dist/daemon/cron/held.d.ts +1 -1
  394. package/dist/daemon/cron/held.js +1 -1
  395. package/dist/daemon/cron/lease-recovery.d.ts +1 -1
  396. package/dist/daemon/cron/lease-recovery.js +1 -1
  397. package/dist/daemon/cron/passes.d.ts +2 -2
  398. package/dist/daemon/cron/passes.js +1 -1
  399. package/dist/daemon/cron/run-socket.d.ts +1 -1
  400. package/dist/daemon/cron/run-socket.js +1 -1
  401. package/dist/daemon/cron/settle.js +1 -1
  402. package/dist/daemon/cron/sinks.d.ts +1 -1
  403. package/dist/daemon/cron/sinks.js +2 -2
  404. package/dist/daemon/cron-run.d.ts +12 -3
  405. package/dist/daemon/cron-run.js +2 -2
  406. package/dist/daemon/crtrd.js +6 -6
  407. package/dist/daemon/delivery/run-delivery.js +1 -1
  408. package/dist/daemon/due-sources.d.ts +3 -3
  409. package/dist/daemon/due-sources.js +1 -1
  410. package/dist/daemon/due.d.ts +3 -3
  411. package/dist/daemon/due.js +7 -7
  412. package/dist/daemon/fleet.d.ts +2 -2
  413. package/dist/daemon/fleet.js +11 -11
  414. package/dist/daemon/human/finish.js +3 -3
  415. package/dist/daemon/human/settle.d.ts +1 -1
  416. package/dist/daemon/human/settle.js +1 -1
  417. package/dist/daemon/human/sweep.js +1 -1
  418. package/dist/daemon/joined-owner.d.ts +2 -2
  419. package/dist/daemon/joined-owner.js +1 -1
  420. package/dist/daemon/messaging/node-message.js +1 -1
  421. package/dist/daemon/park-activity.d.ts +2 -2
  422. package/dist/daemon/park-activity.js +1 -1
  423. package/dist/daemon/peer/authority.js +1 -1
  424. package/dist/daemon/peer/forward.d.ts +13 -6
  425. package/dist/daemon/peer/forward.js +1 -1
  426. package/dist/daemon/peer/handlers.js +1 -1
  427. package/dist/daemon/peer/ingress.d.ts +4 -4
  428. package/dist/daemon/peer/ingress.js +1 -1
  429. package/dist/daemon/peer/outbox.d.ts +2 -2
  430. package/dist/daemon/peer/outbox.js +1 -1
  431. package/dist/daemon/peer/relay-service.js +1 -1
  432. package/dist/daemon/plugin-objects/read-leaf.d.ts +2 -2
  433. package/dist/daemon/plugin-objects/read-leaf.js +2 -2
  434. package/dist/daemon/profile-delete.js +1 -1
  435. package/dist/daemon/readiness.d.ts +2 -2
  436. package/dist/daemon/readiness.js +1 -1
  437. package/dist/daemon/reconcilers/action-lane.d.ts +1 -1
  438. package/dist/daemon/reconcilers/action-lane.js +1 -1
  439. package/dist/daemon/reconcilers/bash-deadline.js +2 -2
  440. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  441. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  442. package/dist/daemon/reconcilers/controller-death.d.ts +1 -1
  443. package/dist/daemon/reconcilers/controller-death.js +1 -1
  444. package/dist/daemon/reconcilers/cron-lane.d.ts +1 -1
  445. package/dist/daemon/reconcilers/cron-lane.js +1 -1
  446. package/dist/daemon/reconcilers/delivery-lane.d.ts +1 -1
  447. package/dist/daemon/reconcilers/delivery-lane.js +2 -2
  448. package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +3 -3
  449. package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
  450. package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +2 -2
  451. package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
  452. package/dist/daemon/reconcilers/live-obligation.d.ts +6 -6
  453. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  454. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
  455. package/dist/daemon/reconcilers/node-deadline.d.ts +1 -1
  456. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  457. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  458. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.d.ts +3 -3
  459. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -1
  460. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -1
  461. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  462. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.d.ts +1 -1
  463. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
  464. package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
  465. package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
  466. package/dist/daemon/reconcilers/storage-due-work.js +1 -1
  467. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -1
  468. package/dist/daemon/reconcilers/storage-maintenance.js +2 -2
  469. package/dist/daemon/reconcilers/structured-request-lane.d.ts +1 -1
  470. package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
  471. package/dist/daemon/review/comment-notify.js +2 -2
  472. package/dist/daemon/review/companion.d.ts +3 -3
  473. package/dist/daemon/review/companion.js +1 -1
  474. package/dist/daemon/review/finish.js +1 -1
  475. package/dist/daemon/review/sweep.js +1 -1
  476. package/dist/daemon/run-notices.d.ts +4 -4
  477. package/dist/daemon/run-notices.js +1 -1
  478. package/dist/daemon/runs/append-section.d.ts +2 -2
  479. package/dist/daemon/runs/append-section.js +2 -2
  480. package/dist/daemon/runs/observer.d.ts +2 -2
  481. package/dist/daemon/runs/observer.js +2 -2
  482. package/dist/daemon/structured-requests/boot.d.ts +1 -1
  483. package/dist/daemon/structured-requests/boot.js +1 -1
  484. package/dist/daemon/structured-requests/effects.js +1 -1
  485. package/dist/daemon/structured-requests/sidecar.d.ts +1 -1
  486. package/dist/daemon/structured-requests/sidecar.js +1 -1
  487. package/dist/migrations/004-canvas-documents/apply.d.ts +3 -3
  488. package/dist/migrations/004-canvas-documents/apply.js +1 -1
  489. package/dist/migrations/004-canvas-documents/index.d.ts +2 -2
  490. package/dist/migrations/004-canvas-documents/index.js +2 -2
  491. package/dist/migrations/activation.js +2 -2
  492. package/docs/public-api.md +11 -0
  493. package/package.json +3 -2
  494. package/packages/crouter-identity/package.json +1 -1
  495. package/runtime.lock.json +12 -12
@@ -13,11 +13,11 @@ export { buildProjectContextBlock, contextDirNote, orchestratorContextNote };
13
13
  * `assembleNodeSubject`'s profile resolution). This absolute-path disclosure
14
14
  * is intentional (spec-approved): the agent must know its full purview, not a
15
15
  * redacted count. */
16
- export declare function profileNote(nodeId: string): string;
16
+ export declare function profileNote(nodeId: string): Promise<string>;
17
17
  /** The graph mini-map: the ancestry trunk (root first), then this node marked
18
18
  * `● you`, then its immediate children. Returns '' for a lone root with no
19
19
  * children (nothing to map). Exported for testing. */
20
- export declare function buildGraphMap(nodeId: string): string;
20
+ export declare function buildGraphMap(nodeId: string): Promise<string>;
21
21
  /** Why a node was born or woken, as carried from the fired cron to the
22
22
  * injection seam. `ownerName` is the armer's resolved display name when it
23
23
  * still exists (a reaped cron's armer renders as a bare id, never crashes). */
@@ -36,7 +36,7 @@ export interface WakeOrigin {
36
36
  }
37
37
  /** Build the provenance a fired cron carries to its injection seam, resolving
38
38
  * the armer's display name if that node still exists. */
39
- export declare function cronWakeOrigin(c: Cron, kind: WakeOrigin['kind']): WakeOrigin;
39
+ export declare function cronWakeOrigin(c: Cron, kind: WakeOrigin['kind']): Promise<WakeOrigin>;
40
40
  /** Render the cron provenance block. The BIRTH variant names the ARMER
41
41
  * explicitly ("armed by node X") so a newborn never reads that id as its own;
42
42
  * the REVIVE variant drops armer attribution — a cron can revive a node it did
@@ -50,7 +50,7 @@ export declare function buildWakeBearings(origin: WakeOrigin): string;
50
50
  /** The bearings on the row-backed delivery engine: the knowledge catalog and
51
51
  * the workspace-open documents render against `ctx`'s ledger; `delivered`
52
52
  * lists what they delivered, for the caller to record. */
53
- export declare function buildContextBearings(nodeId: string, ctx: RenderContext): {
53
+ export declare function buildContextBearings(nodeId: string, ctx: RenderContext): Promise<{
54
54
  content: string;
55
55
  delivered: DeliveredDoc[];
56
- };
56
+ }>;
@@ -1,7 +1,7 @@
1
- var k=Object.defineProperty;var a=(e,n)=>k(e,"name",{value:n,configurable:!0});import{getNode as s,fullName as d,isSafeNodeId as y,subscriptionsOf as g}from"../canvas/index.js";import{cadenceDisplay as N}from"../wake.js";import{renderKnowledge as v,renderWorkspaceOpen as x}from"../substrate/delivery/render-boot.js";import{situationalContextEnvelope as _}from"./situational-context.js";import{statusRank as l}from"../canvas/node-order.js";import{buildProjectContextBlock as f,contextDirNote as p,orchestratorContextNote as h,profileNote as $,renderGraphMap as C,buildIdentityAssertion as S,worktreeNote as O}from"./bearings-render.js";import{CONTEXT_INTRO_CUSTOM_TYPE as J}from"../../shared/generated-context.js";function Y(e){const n=s(e);return n===null?"":$(n.cwd,n.profile_id)}a(Y,"profileNote");function E(e){const n=[],r=new Set([e]);let o=s(e)?.parent??null;for(;o!==null&&o!==""&&!r.has(o);){r.add(o);const t=s(o);if(t===null)break;n.unshift(t),o=t.parent??null}return n}a(E,"ancestorTrunk");const X=5;function j(e){return g(e).map(n=>s(n.node_id)).filter(n=>n!==null&&n.kind!=="human").sort((n,r)=>l(n.status)-l(r.status))}a(j,"childNodes");function A(e){const n=s(e);if(n===null)return"";const r=E(e),o=j(e);return C(e,n.kind,n.mode,r,o)}a(A,"buildGraphMap");function B(e){const n=s(e),r=n?.fork_from,o=r!=null&&r!==""&&y(r)?s(r):null,t=o!==null?`${r} ("${d(o)}")`:r??"";return S(e,n?.kind??"general",n?.mode??"base",r,t)}a(B,"buildIdentityAssertion");function R(e){return e.ownerId===null||e.ownerId===""?"an unknown node":e.ownerName!==void 0?`node ${e.ownerId} ("${e.ownerName}")`:`node ${e.ownerId} (now gone)`}a(R,"armerPhrase");function F(e,n){const r=e.created_by!=null?s(e.created_by):null;return{kind:n,ownerId:e.created_by,...r!==null?{ownerName:d(r)}:{},armedAt:e.created,recur:e.recur}}a(F,"cronWakeOrigin");function I(e){const n=e.recur!==null&&e.recur!==void 0&&e.recur!=="",r=n?N(e.recur):null;if(e.kind==="schedule_revive")return`<crtr-wake>
1
+ var b=Object.defineProperty;var a=(e,n)=>b(e,"name",{value:n,configurable:!0});import{getNode as i,fullName as d,isSafeNodeId as k,subscriptionsOf as g}from"../canvas/index.js";import{cadenceDisplay as N}from"../wake.js";import{renderKnowledge as v,renderWorkspaceOpen as x}from"../substrate/delivery/render-boot.js";import{situationalContextEnvelope as _}from"./situational-context.js";import{statusRank as l}from"../canvas/node-order.js";import{buildProjectContextBlock as w,contextDirNote as f,orchestratorContextNote as p,profileNote as $,renderGraphMap as C,buildIdentityAssertion as S,worktreeNote as O}from"./bearings-render.js";import{mapAsync as Y}from"../async-array.js";import{CONTEXT_INTRO_CUSTOM_TYPE as V}from"../../shared/generated-context.js";async function A(e){const n=await i(e);return n===null?"":$(n.cwd,n.profile_id)}a(A,"profileNote");async function E(e){const n=[],r=new Set([e]);let t=(await i(e))?.parent??null;for(;t!==null&&t!==""&&!r.has(t);){r.add(t);const o=await i(t);if(o===null)break;n.unshift(o),t=o.parent??null}return n}a(E,"ancestorTrunk");const I=5;async function j(e){return(await Y(await g(e),async n=>await i(n.node_id))).filter(n=>n!==null&&n.kind!=="human").sort((n,r)=>l(n.status)-l(r.status))}a(j,"childNodes");async function B(e){const n=await i(e);if(n===null)return"";const r=await E(e),t=await j(e);return C(e,n.kind,n.mode,r,t)}a(B,"buildGraphMap");async function R(e){const n=await i(e),r=n?.fork_from,t=r!=null&&r!==""&&k(r)?await i(r):null,o=t!==null?`${r} ("${d(t)}")`:r??"";return S(e,n?.kind??"general",n?.mode??"base",r,o)}a(R,"buildIdentityAssertion");function T(e){return e.ownerId===null||e.ownerId===""?"an unknown node":e.ownerName!==void 0?`node ${e.ownerId} ("${e.ownerName}")`:`node ${e.ownerId} (now gone)`}a(T,"armerPhrase");async function K(e,n){const r=e.created_by!=null?await i(e.created_by):null;return{kind:n,ownerId:e.created_by,...r!==null?{ownerName:d(r)}:{},armedAt:e.created,recur:e.recur}}a(K,"cronWakeOrigin");function q(e){const n=e.recur!==null&&e.recur!==void 0&&e.recur!=="",r=n?N(e.recur):null;if(e.kind==="schedule_revive")return`<crtr-wake>
2
2
  ${n?`A SCHEDULE woke you, not a message \u2014 a recurring cron firing ${r} revived you fresh. Nothing new happened on the canvas and nobody is waiting on a reply: the clock came round. Re-read your bearings below, do this cycle's pass of the standing job, and stop.`:"A SCHEDULE woke you, not a message \u2014 a one-shot cron armed to fire now revived you fresh. Nothing new happened on the canvas and nobody is waiting on a reply: the time you were waiting for arrived. Re-read your bearings below and continue from there."}
3
- </crtr-wake>`;const o=R(e);return`<crtr-wake>
4
- ${n?`You were BORN by a scheduled wake, not spawned on demand \u2014 a recurring spawn-cron armed by ${o}, firing ${r}. The runtime re-births a fresh node like you on this cadence whether or not earlier runs survived: you are one run of a standing job, not a one-off, and you inherit nothing from prior runs but this task. Your task follows.`:`You were BORN by a scheduled wake, not spawned on demand \u2014 a one-shot deferred birth armed by ${o} to fire now. You are its only run, not a recurring job. Your task follows.`}
5
- </crtr-wake>`}a(I,"buildWakeBearings");function T(e){return O(e?.managed_worktree)}a(T,"managedWorktreeNote");function D(e,n,r){const o=s(e),t=["<crtr-bearings>",B(e)],u=A(e);u!==""&&t.push("","## Your place in the canvas",u),t.push("","## Your documents and context directory",p(e,o?.grantee));const i=Y(e);i!==""&&t.push("",i);const c=T(o);c!==""&&t.push("","## Your managed worktree",c),o?.mode==="orchestrator"&&t.push("",h()),t.push("</crtr-bearings>");const w=_(e)??"",m=o?.cwd!==void 0?f(o.cwd):"";return[t.join(`
6
- `),n,r,w,m].filter(b=>b!=="").join(`
7
- `)}a(D,"bearingsShell");function K(e,n){const r=v(n),o=x(n);return{content:D(e,r.content,o.content),delivered:[...r.delivered,...o.delivered]}}a(K,"buildContextBearings");export{J as CONTEXT_INTRO_CUSTOM_TYPE,K as buildContextBearings,A as buildGraphMap,f as buildProjectContextBlock,I as buildWakeBearings,p as contextDirNote,F as cronWakeOrigin,h as orchestratorContextNote,Y as profileNote};
3
+ </crtr-wake>`;const t=T(e);return`<crtr-wake>
4
+ ${n?`You were BORN by a scheduled wake, not spawned on demand \u2014 a recurring spawn-cron armed by ${t}, firing ${r}. The runtime re-births a fresh node like you on this cadence whether or not earlier runs survived: you are one run of a standing job, not a one-off, and you inherit nothing from prior runs but this task. Your task follows.`:`You were BORN by a scheduled wake, not spawned on demand \u2014 a one-shot deferred birth armed by ${t} to fire now. You are its only run, not a recurring job. Your task follows.`}
5
+ </crtr-wake>`}a(q,"buildWakeBearings");function D(e){return O(e?.managed_worktree)}a(D,"managedWorktreeNote");async function W(e,n,r){const t=await i(e),o=["<crtr-bearings>",await R(e)],s=await B(e);s!==""&&o.push("","## Your place in the canvas",s),o.push("","## Your documents and context directory",f(e,t?.grantee));const u=await A(e);u!==""&&o.push("",u);const c=D(t);c!==""&&o.push("","## Your managed worktree",c),t?.mode==="orchestrator"&&o.push("",p()),o.push("</crtr-bearings>");const h=_(e)??"",m=t?.cwd!==void 0?w(t.cwd):"";return[o.join(`
6
+ `),n,r,h,m].filter(y=>y!=="").join(`
7
+ `)}a(W,"bearingsShell");async function z(e,n){const r=await v(n),t=await x(n);return{content:await W(e,r.content,t.content),delivered:[...r.delivered,...t.delivered]}}a(z,"buildContextBearings");export{V as CONTEXT_INTRO_CUSTOM_TYPE,z as buildContextBearings,B as buildGraphMap,w as buildProjectContextBlock,q as buildWakeBearings,f as contextDirNote,K as cronWakeOrigin,p as orchestratorContextNote,A as profileNote};
@@ -1 +1 @@
1
- var _=Object.defineProperty;var n=(o,r)=>_(o,"name",{value:r,configurable:!0});import{randomUUID as y}from"node:crypto";import{getNode as p}from"../canvas/canvas.js";import{BrokerClient as h}from"../broker-client/index.js";import{gatewayCommandRowsFromDetail as k,gatewayMemoryRows as v}from"./chat-inventory-rows.js";import{isBrokerLive as w}from"./model-swap.js";const T=15e3,g=1,C=n(o=>({node_id:o,broker_live:!1,commands:[],memory_refs:[]}),"empty");function S(o){const r=p(o);return r===null||!w(r)?Promise.resolve(C(o)):new Promise(a=>{const e=new h(o),u=y();let f=!1,d=!1,i,s;const l=setTimeout(()=>m(),T);typeof l.unref=="function"&&l.unref();function m(){if(!f){f=!0,clearTimeout(l);try{e.close()}catch{}a({node_id:o,broker_live:d,commands:i??[],memory_refs:s??[]})}}n(m,"finish");function c(){i!==void 0&&s!==void 0&&m()}n(c,"settleWhenComplete"),e.on("error",()=>m()),e.on("close",()=>m()),e.on("connect",()=>{d=!0,e.send({type:"hello",role:"observer",client_id:u,snapshot_tail:g}),e.send({type:"get_commands"}),e.request({type:"list_memory_refs"}).then(t=>{s=t.kind==="list_memory_refs"?v(t.refs):[],c()},()=>{s=[],c()})}),e.on("frame",t=>{if(t.type==="ack"&&t.for==="get_commands"){i=t.ok?k(t.detail):[],c();return}t.type==="error"&&t.id===void 0&&(i??=[],c())}),e.connect()})}n(S,"readChatInventory");export{S as readChatInventory};
1
+ var y=Object.defineProperty;var n=(o,r)=>y(o,"name",{value:r,configurable:!0});import{randomUUID as _}from"node:crypto";import{getNode as p}from"../canvas/canvas.js";import{BrokerClient as h}from"../broker-client/index.js";import{gatewayCommandRowsFromDetail as k,gatewayMemoryRows as w}from"./chat-inventory-rows.js";import{isBrokerLive as v}from"./model-swap.js";const T=15e3,g=1,C=n(o=>({node_id:o,broker_live:!1,commands:[],memory_refs:[]}),"empty");async function S(o){const r=await p(o);return r===null||!v(r)?Promise.resolve(C(o)):new Promise(async d=>{const e=new h(o),u=_();let f=!1,a=!1,i,s;const l=setTimeout(()=>m(),T);typeof l.unref=="function"&&l.unref();function m(){if(!f){f=!0,clearTimeout(l);try{e.close()}catch{}d({node_id:o,broker_live:a,commands:i??[],memory_refs:s??[]})}}n(m,"finish");function c(){i!==void 0&&s!==void 0&&m()}n(c,"settleWhenComplete"),e.on("error",()=>m()),e.on("close",()=>m()),e.on("connect",()=>{a=!0,e.send({type:"hello",role:"observer",client_id:u,snapshot_tail:g}),e.send({type:"get_commands"}),e.request({type:"list_memory_refs"}).then(t=>{s=t.kind==="list_memory_refs"?w(t.refs):[],c()},()=>{s=[],c()})}),e.on("frame",t=>{if(t.type==="ack"&&t.for==="get_commands"){i=t.ok?k(t.detail):[],c();return}t.type==="error"&&t.id===void 0&&(i??=[],c())}),e.connect()})}n(S,"readChatInventory");export{S as readChatInventory};
@@ -1 +1 @@
1
- var b=Object.defineProperty;var c=(r,t)=>b(r,"name",{value:t,configurable:!0});import{randomUUID as f}from"node:crypto";import{BrokerClient as h}from"../broker-client/index.js";const u=15e3;class k extends Error{static{c(this,"BrokerUnreachableError")}constructor(t){super(t),this.name="BrokerUnreachableError"}}function y(r){return new Promise((t,i)=>{const o=new h(r.nodeId),w=f(),d=f();let a=!1,l=!1;const s=setTimeout(()=>n(()=>i(new Error(`timed out after ${u}ms waiting for the broker to ack ${r.what}`))),u);typeof s.unref=="function"&&s.unref();function n(e){if(!a){a=!0,clearTimeout(s);try{o.close()}catch{}e()}}c(n,"finish"),o.on("error",e=>n(()=>i(l?e:new k(`broker connection refused mid-revive: ${e.message}`)))),o.on("close",()=>n(()=>i(l?new Error(`broker connection closed before it acked ${r.what}`):new k("broker connection closed before it was established (mid-revive)")))),o.on("connect",()=>{l=!0,o.send({type:"hello",role:"controller",client_id:w}),o.send(r.frame(d))}),o.on("frame",e=>{e.type==="ack"&&e.for===r.ackFor&&(r.correlated!==!0||e.id===d)?e.ok?n(()=>t(r.result(e.detail))):n(()=>i(new Error(e.detail??`broker rejected ${r.what}`))):e.type==="error"?n(()=>i(new Error(e.message))):r.observe!==void 0&&r.observe(e)}),o.connect()})}c(y,"oneShotControllerRequest");export{k as BrokerUnreachableError,y as oneShotControllerRequest};
1
+ var b=Object.defineProperty;var c=(r,t)=>b(r,"name",{value:t,configurable:!0});import{randomUUID as f}from"node:crypto";import{BrokerClient as h}from"../broker-client/index.js";const u=15e3;class k extends Error{static{c(this,"BrokerUnreachableError")}constructor(t){super(t),this.name="BrokerUnreachableError"}}function y(r){return new Promise(async(t,i)=>{const o=new h(r.nodeId),w=f(),d=f();let a=!1,l=!1;const s=setTimeout(()=>n(()=>i(new Error(`timed out after ${u}ms waiting for the broker to ack ${r.what}`))),u);typeof s.unref=="function"&&s.unref();function n(e){if(!a){a=!0,clearTimeout(s);try{o.close()}catch{}e()}}c(n,"finish"),o.on("error",e=>n(()=>i(l?e:new k(`broker connection refused mid-revive: ${e.message}`)))),o.on("close",()=>n(()=>i(l?new Error(`broker connection closed before it acked ${r.what}`):new k("broker connection closed before it was established (mid-revive)")))),o.on("connect",()=>{l=!0,o.send({type:"hello",role:"controller",client_id:w}),o.send(r.frame(d))}),o.on("frame",e=>{e.type==="ack"&&e.for===r.ackFor&&(r.correlated!==!0||e.id===d)?e.ok?n(()=>t(r.result(e.detail))):n(()=>i(new Error(e.detail??`broker rejected ${r.what}`))):e.type==="error"?n(()=>i(new Error(e.message))):r.observe!==void 0&&r.observe(e)}),o.connect()})}c(y,"oneShotControllerRequest");export{k as BrokerUnreachableError,y as oneShotControllerRequest};
@@ -1 +1 @@
1
- var Pe=Object.defineProperty;var n=(t,o)=>Pe(t,"name",{value:o,configurable:!0});import{envInboxBetweenTurns as Oe,envModelIntent as Ie,envNodeCwd as De,envNodeId as Ne,envProfileId as Fe,envScopes as Le,isSandboxedNode as $e,scopeAllowed as Be}from"../../shared/env.js";import{createServer as Ue}from"node:net";import{existsSync as ye,readFileSync as Ge,unlinkSync as be}from"node:fs";import{join as Te}from"node:path";import{randomUUID as x}from"node:crypto";import{mark as Ke}from"../timing.js";import{SUBMIT_RESULT_TOOL as je}from"./structured-output.js";import{installSessionManagerStorePatch as We}from"../conversation-store/index.js";import{getAgentDir as Y,ModelRegistry as qe,ModelRuntime as Ve}from"@earendil-works/pi-coding-agent";import{nodeRunDir as Xe,viewSocketPath as He}from"../canvas/paths.js";import{bindBrokerEventSource as Ye}from"../events/source.js";import{emitEvent as T,flushBrokerLog as ze}from"../events/emit.js";import{operationIdContext as Je}from"../events/operation-id.js";import{findMissingPackagePaths as Qe}from"./package-health.js";import{installBrokerConfigSnapshot as Ze}from"../config.js";import{FRONT_DOOR_ENV as en}from"./front-door.js";import{CANVAS_EXTENSIONS as re,piInvocationToSdkConfig as nn}from"./launch.js";import{assertEngineVersion as tn,loadBrokerEngine as rn}from"./broker-sdk.js";import{initCrtrTheme as on}from"./crtr-theme.js";import{resolveBundledPiPackageDir as sn}from"./pi-cli.js";import{captureSessionChatCapabilities as an}from"./command-surface.js";import{InMemoryCredentialStore as dn}from"@earendil-works/pi-ai";import{configureBrokerModelRuntime as ln}from"./broker/model-adapter.js";import{mutateBrokerFault as z,recordBrokerTurn as Re}from"./broker/daemon-ops.js";import{modelRequestFromConfig as cn,expandModelCandidates as mn,parseModelSpec as un,unregisteredConcreteModel as fn}from"../model-routes.js";import{KNOWN_STREAM_WAIT_UI as pn}from"./stream-watchdog.js";import{probeOnline as gn}from"./connectivity.js";import{CRTR_CYCLE_CUSTOM_TYPE as vn,cycleAwareMessages as hn,endedByAbort as Sn}from"./session-cycles.js";import{turnErrorOf as _n}from"../llm/refusal.js";import{projectTranscript as wn}from"./session-visibility.js";import{currentTurnVisibility as yn}from"./turn-visibility.js";import{isUnknownModel as oe}from"./model-selection.js";import{BrokerClientRegistry as bn}from"./broker/client-registry.js";import{ToolGroupTracker as Tn}from"./broker/tool-groups.js";import{TurnReplyTracker as Rn}from"./broker/turn-replies.js";import{onNodeNamed as kn}from"./broker/node-named.js";import{FaultRetry as En,willDaemonRetry as Mn}from"./broker/fault-retry.js";import{RunTurnEnds as xn}from"./broker/run-turn-end.js";import{createTurnAdmissionGate as Cn}from"./broker/turn-admission.js";import{BROKER_IDLE_TURN_START as An,BROKER_RUN_TURN_BUSY as Pn}from"./broker/held-deferred-inbox.js";import{prependRunDeferredMail as On,settleRunDeferredMail as In}from"./broker/run-deferred-mail.js";import{createRunTurnQueue as Dn}from"./broker/run-turn-queue.js";import{EventProjection as Nn}from"./broker/event-projection.js";import{createFrameDispatchContext as Fn,handleFrame as Ln}from"./broker/frame-dispatch.js";import{hydratePersistedAdvertisedCommandMessages as $n,installAdvertisedCommandInvocationContract as Bn}from"./advertised-command-invocation.js";import{RebindDriver as Un}from"./broker/rebind.js";import{beginRuntimeTeardown as Gn}from"./broker/extension-abort.js";import{receiveNodeToken as Kn}from"./broker/node-token.js";import{serveCliRelay as jn}from"./broker/cli-relay.js";import{decodeKickoffOrigin as Wn,KICKOFF_ORIGIN_ENV as qn}from"./stamp/protocol.js";import{announceMessageOrigin as Vn}from"./stamp/channel.js";import{brokerExtensionState as Xn,commitBrokerModel as Hn}from"./broker/daemon-ops.js";import{composerNames as Yn}from"./broker/frame-memory-refs.js";import{FrameOverflowError as zn,normalizeSnapshotTail as Jn}from"./broker-protocol.js";import{ReviewBoundaryNavigationError as ur,REVIEW_BOUNDARY_NAVIGATION_CODE as fr}from"./broker/frame-replies.js";function se(t){return new qe(t.modelRuntime)}n(se,"registryOf");function B(t,o){if(t==null||oe(t))return null;const i=o!==void 0&&o!==""&&o!=="off"?`:${o}`:"";return`${t.provider}/${t.id}${i}`}n(B,"formatModelSpec");function Qn(t,o){const i=B(t,void 0);return i===null?null:`${i}:${o===void 0||o===""?"off":o}`}n(Qn,"formatExactModelSpec");const Zn=12e4;let J=null;import{brokerSignalClient as Q}from"./broker/signal-stream.js";function et(){Q().stop();const t=J;if(J=null,t!==null)try{t.dispose()}catch{}}n(et,"disposeActiveSession");function nt(t,o){const i=Be(o,"crtr:act")?void 0:["bash"],m=t!==void 0&&t.length>0?[...new Set([...t,je])]:t===void 0?void 0:[...t];return{...m!==void 0?{tools:m}:{},...i!==void 0?{excludeTools:i}:{}}}n(nt,"brokerToolOptions");async function lr(t,o=process.hrtime.bigint(),i=new Date().toISOString()){Ye(t);const m=await Kn(),s=await jn(t,m);process.env.CRTR_API_SOCKET=s.path,Je.fresh(()=>{T({level:"info",event:"broker.startup.cli_entry",ts:i,duration_ms:0,fields:{runtime_version:process.version,engine_version:null,model:null}}),T({level:"info",event:"broker.startup.module_loaded",duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{runtime_version:process.version,engine_version:null,model:null}})});const a=new Set;let l=null;const d=n((e,r=null)=>{a.has(e)||(a.add(e),Ke(e,{duration_ms:Number(process.hrtime.bigint()-o)/1e6}),T({level:"info",event:e,duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{runtime_version:process.version,engine_version:l,model:r}}))},"emitStartupMilestone");process.env[en]="1",process.env.CRTR_BROKER_PID=String(process.pid),delete process.env.TMUX_PANE,delete process.env.TMUX,We(t);const p=await rn();tn(p.VERSION),l=p.VERSION;const _=Xe(t),k=Te(_,"broker-launch.json"),w=JSON.parse(Ge(k,"utf8"));if($e()){if(!w.configSnapshot)throw new Error("broker launch is missing its config snapshot");Ze(w.configSnapshot)}const f=nn(w);f.modelExact===!0?process.env.CRTR_MODEL_EXACT="1":delete process.env.CRTR_MODEL_EXACT;const y=await Yn(t);let b,C;const V=n(e=>{b!==void 0?b(e):C??=e},"onSignal");process.on("SIGTERM",()=>V("SIGTERM")),process.on("SIGINT",()=>V("SIGINT"));let{session:U,services:A,resuming:ae,runtime:G}=await st(p,f);d("broker.startup.session_built");const E=(await Xn(t)).node.review_binding?.review_id,R=Oe();J=U;const D=gn;try{process.env.PI_PACKAGE_DIR=sn(),on(A.settingsManager.getTheme(),Y(),!1)}catch(e){T({level:"error",event:"broker.theme.initialization_failed",error:e})}try{for(const e of Qe(Y()))T({level:"warn",event:"broker.startup.warning",fields:{stage:"package_health",source:e.source,resolved_path:e.resolved}})}catch{}const K=He(t),g=new bn(t),X=new Map,O=new Tn(t,e=>g.broadcast(e)),j=new Rn(t,e=>g.broadcast(e));kn(e=>g.broadcast({type:"node_named",...e}));let N=!1,de=!1,H,le,u,W;const Z=new xn;let F,ce=n(()=>{},"notifyTurnAccepted"),me=n(()=>{},"resetFrameState");const ee=Cn();let ue=n(()=>0,"pendingPromptDispatches"),fe;const L=Dn({runNode:R,session:n(()=>u.session(),"session"),isReplacing:n(()=>u.isReplacing(),"isReplacing"),pendingRebind:n(()=>u.pendingRebind(),"pendingRebind"),isAgentRunActive:n(()=>u.isAgentRunActive(),"isAgentRunActive"),pendingDispatches:n(()=>ue(),"pendingDispatches"),turnAdmission:ee,prependDeferred:n(e=>On(t,e),"prependDeferred"),onError:n(e=>T({level:"error",event:"broker.inbox.idle_prompt_failed",error:e}),"onError")}),pe=L.drain;f.firstPrompt!==void 0&&f.firstPrompt!==""&&L.holdForKickoff(),globalThis[An]=L.start,globalThis[Pn]=L.busy,u=new Un({nodeId:t,cfg:f,session:U,services:A,runtime:G,registry:g,toolGroups:O,turnReplies:j,transcriptMessages:n(e=>ie(e,E)?.map(({message:r})=>r)??e.sessionManager.buildSessionContext().messages,"transcriptMessages"),uiContext:n(()=>le,"uiContext"),faultRetry:n(()=>W,"faultRetry"),projection:n(()=>F,"projection"),setActiveSession:n(e=>{if(J=e,fe?.(),R){let r="stop",c,v=!1;fe=e.subscribe(h=>{if(h.type==="agent_start"&&(r="stop",c=void 0,v=!1,Z.started()),h.type==="agent_end"){const S=[...h.messages??[]].reverse().find($=>$.role==="assistant");S&&(r=S.stopReason,c=Sn(S)?void 0:_n(S),v=S.role==="assistant"&&Mn(S,e.model?.contextWindow))}h.type==="agent_settled"&&(Z.settled(e.sessionManager,{stop_reason:r,...c?{error:c}:{}},v),In(t,e).catch(S=>{T({level:"error",event:"broker.run_deferred_mail.settle_failed",error:S})}),queueMicrotask(()=>{u.session()===e&&pe()}))})}},"setActiveSession"),disposeAndExit:n((e,r)=>q(e,r),"disposeAndExit"),onSessionRebind:n(()=>{me()},"onSessionRebind"),onReplacementIdle:n(()=>{R&&pe()},"onReplacementIdle"),reWelcomeAll:n(()=>ne(),"reWelcomeAll")});const ge=n(async(e,r=!1)=>{const c=u.session(),v=B(c.model,c.thinkingLevel);if(v===null)return null;const h=await Hn(t,{spec:v,...e!==void 0?{intent:e}:{},userSelected:r});return r&&(f.model=h.modelOverride,e!==void 0?(process.env.CRTR_MODEL_INTENT=`${e.family}/${e.strength}`,delete process.env.CRTR_MODEL_EXACT,f.modelExact=void 0):(delete process.env.CRTR_MODEL_INTENT,process.env.CRTR_MODEL_EXACT="1",f.modelExact=!0)),h.modelOverride},"persistModelChoice"),ve=n(async(e=!0,r,c=!1)=>{const v=u.session(),h=B(v.model,v.thinkingLevel),S=e?await ge(r,c):h;g.broadcast({type:"model_changed",model:oe(v.model)?void 0:v.model,spec:S})},"broadcastModelChanged");W=new En({nodeId:t,cfg:f,retryProbe:D,currentSession:n(()=>u.session(),"currentSession"),currentServices:n(()=>u.services(),"currentServices"),installedGeneration:n(()=>u.installedGeneration(),"installedGeneration"),registryOf:se,formatModelSpec:B,broadcastModelChanged:ve,turnAdmission:ee,reWelcomeAll:n(()=>ne(),"reWelcomeAll"),...R?{turnEnds:Z}:{}});const he=n(()=>{W.rearmIfStranded().catch(e=>{T({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`fault retry re-arm failed: ${e instanceof Error?e.message:String(e)}`}})})},"rearmStrandedRetry");Q().subscribe("resync",he),Q().subscribe("fault-retry",he),F=new Nn({registry:g,faultRetry:W,installedGeneration:n(()=>u.installedGeneration(),"installedGeneration"),currentSession:n(()=>u.session(),"currentSession"),notifyTurnAccepted:n(()=>ce(),"notifyTurnAccepted"),emitStartupMilestone:d,formatModelSpec:B});const Ee=n(e=>{const r=u.session(),c=ie(r,E),v=Jn(e.snapshotTail),h=c===void 0||v===void 0?c:c.slice(-v),S=h?.map(({message:I})=>I)??r.sessionManager.buildSessionContext().messages,$=O.summaries(),we=h!==void 0&&v!==void 0?tt(S):void 0,Ae=we===void 0?$:Object.fromEntries(Object.entries($).filter(([I])=>we.has(I)));return{messages:S,...h===void 0?{}:{messageIds:h.map(({id:I})=>I)},messageVisibility:h?.map(({visibility:I})=>I)??S.map(()=>"visible"),turnVisibility:yn(),stats:r.getSessionStats(),state:{model:oe(r.model)?void 0:r.model,thinkingLevel:r.thinkingLevel,isStreaming:r.isStreaming,isCompacting:r.isCompacting,steeringMode:r.steeringMode,followUpMode:r.followUpMode,sessionFile:r.sessionFile,sessionId:r.sessionId,sessionName:r.sessionName,autoCompactionEnabled:r.autoCompactionEnabled,messageCount:r.messages.length,pendingMessageCount:r.pendingMessageCount},display:{...g.displaySnapshot()},toolGroupSummaries:Ae,turnReplies:j.snapshot(),workingActivity:F.currentWorkingActivity(),queued:{steering:[...r.getSteeringMessages()],followUp:[...r.getFollowUpMessages()]}}},"buildSnapshot"),Se=n(e=>{const r=e.role==="controller"?X.values().next().value:void 0;g.sendFrame(e,{type:"welcome",snapshot:Ee(e),role:e.role,pending_dialog:r!==void 0?r.request:null,agentDir:Y()},!0)},"sendWelcome"),Me=n(e=>{const r=[...X.values()];for(let c=1;c<r.length;c++)g.sendFrame(e,r[c].request)},"replayExtraPendingDialogsTo"),ne=n(()=>{try{const e=u.session();j.seed(ie(e,E)?.map(({message:r})=>r)??e.sessionManager.buildSessionContext().messages)}catch(e){T({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`turn reply reseed failed: ${String(e)}`}})}g.forEachHelloed(Se)},"reWelcomeAll"),_e=n(async e=>{if(!N){N=!0,Q().stop(),O.persistPendingSummary(),F.dispose(),et();try{H?.close()}catch{}s.close(),g.dispose();try{ye(K)&&be(K)}catch{}g.clearAttachState(),await ze(),process.exit(e)}},"completeExit"),q=n((e,r=0)=>{if(N)return;const c=e==="shutdown-hook"||e==="shutdown-after-settle";if(c&&O.finishOpenToolGroup(!0),c&&(O.hasSummaryTasks()||j.hasTasks())){if(de)return;de=!0,Promise.allSettled([O.waitForSummaryTasks(),j.waitForTasks()]).finally(()=>_e(r));return}_e(r)},"disposeAndExit");le=it({writable:n(()=>g.writableClients(),"writable"),forward:n((e,r)=>g.sendFrame(e,r),"forward"),pending:X,broadcast:n(e=>g.broadcastUi(e),"broadcast"),onKnownStreamWait:n(e=>F.knownStreamWait(e),"onKnownStreamWait")}),u.setRebindSession(),await u.enqueueRebind(U,A),d("broker.startup.extensions_bound");const M=Fn({nodeId:t,registry:g,toolGroups:O,projection:F,rebind:u,boundaryReviewId:E,pendingDialogs:X,sendWelcome:Se,replayExtraPendingDialogsTo:Me,reWelcomeAll:ne,disposeAndExit:q,persistModelChoice:ge,broadcastModelChanged:ve,registryOf:se,formatModelSpec:B,formatExactModelSpec:Qn,turnAdmission:ee,memoryInventory:y,runNode:R,onKickoffAdmitted:L.releaseKickoff});ce=M.notifyTurnAccepted,me=M.resetForSession,ue=M.pendingPromptDispatches;const xe=2500;let te=!1;const Ce=n(async e=>{if(N||te)return;if(te=!0,u.isAgentRunActive()||u.session().isStreaming||M.pendingPromptDispatches()>0){const c=Date.now()+xe;for(;M.pendingPromptDispatches()>0&&!u.session().isStreaming&&Date.now()<c;)await new Promise(v=>setTimeout(v,25));if(u.session().isStreaming){const v=c-Date.now();if(v>0){let h;try{Gn(),await Promise.race([u.session().abort().then(()=>!0,()=>!1),new Promise($=>{h=setTimeout(()=>$(!1),v)})])&&await Re(t,{event:"closed",end_reason:"teardown-aborted"})}finally{h!==void 0&&clearTimeout(h)}}}else(M.pendingPromptDispatches()>0||u.isAgentRunActive())&&await Re(t,{event:"interrupted"})}q(e)},"abortAndExit");if(b=n(e=>{Ce(e)},"signalTeardown"),C!==void 0){b(C);return}try{ye(K)&&be(K)}catch{}H=Ue(e=>{const r=g.create(e);e.on("data",v=>{let h;try{h=r.decoder.push(v)}catch(S){S instanceof zn?(g.sendFrame(r,{type:"error",code:"frame_overflow",message:S.message}),g.dropClient(r,`frame overflow: ${S.message}`)):g.dropClient(r,`decoder error: ${String(S)}`);return}for(const S of h)try{Ln(M,r,S)}catch{}});const c=n(()=>{g.removeClient(r)},"drop");e.on("close",c),e.on("error",()=>{})}),H.on("error",e=>{N||(T({level:"error",event:"broker.socket.failed",error:e}),q("socket-error",1))}),H.listen(K,async()=>{Promise.all([z(t,{op:"clear",link:"viewer\u2194broker"}),z(t,{op:"clear",link:"relay\u2194broker"})]).catch(r=>T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"broker_socket_bound_fault_clear"}}));let e;try{e=await W.recoverOnStartup()}catch(r){T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"recovery_startup"}}),q("recovery-startup-failed",1);return}if(!(N||te))if(e!=="retry-armed"&&f.firstPrompt!==void 0&&f.firstPrompt!==""){const r=Wn(process.env[qn]);r!==null&&Vn(f.firstPrompt,r);const c=process.env.CRTR_KICKOFF_MESSAGE_IDS;M.kickoff(f.firstPrompt,c?JSON.parse(c):[])}else L.releaseKickoff()}),g.persistAttachState()}n(lr,"runBroker");function tt(t){const o=new Set;for(const i of t)if(!(i.role!=="assistant"||!Array.isArray(i.content)))for(const m of i.content)m!==null&&typeof m=="object"&&m.type==="toolCall"&&typeof m.id=="string"&&o.add(m.id);return o}n(tt,"toolCallIds");function ie(t,o){const i=t.sessionManager,m=hn(i);return m!==void 0&&$n(m.map(({message:s})=>s)),m===void 0?void 0:wn(m,{boundaryReviewId:o,sessionEntries:i.getEntries?.()})}n(ie,"snapshotMessages");function ke(){const t=Ne();if(t===void 0||t==="")throw new Error("broker launch is missing CRTR_NODE_ID");return t}n(ke,"currentBrokerNodeId");async function rt(t,o){const i=cn(o.model,Ie(),o.modelExact===!0);if(i===void 0)return;const m=se(t),s={cwd:De()??o.cwd,profileId:Fe()},a=fn(i,m,s);if(a!==void 0)throw await z(ke(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`model '${a.request.spec}' is not registered in the serving model registry`}}),new Error(`[broker] FATAL: model '${a.request.spec}' is not registered in the serving model registry`);const l=mn(i,s.cwd,s.profileId),d=un(i.spec);for(const p of l){const _=m.find(p.providerId,p.modelId);if(_===void 0)continue;const w=d?.providerId===p.providerId&&d.modelId===p.modelId?d.thinkingLevel??(p.thinkingLevel===void 0?void 0:"off"):p.thinkingLevel;return{model:_,thinkingLevel:w}}if(o.modelExact===!0){const p=l.map(_=>`'${_.providerId}/${_.modelId}' unregistered`).join("; ");throw await z(ke(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`exact-consult model '${o.model}' is unavailable \u2014 refusing to substitute (${p})`}}),new Error(`[broker] FATAL: exact-consult model '${o.model}' is unavailable`)}T({level:"warn",event:"broker.model.none_viable",fields:{rejected_candidates:l.map(p=>({provider:p.providerId,model:p.modelId,reason:"unregistered"})).slice(0,16)}})}n(rt,"resolveLaunchModel");function ot(t){let o=!0;return{runtime:new Proxy(t,{get(m,s,a){return o&&s==="getAvailableSnapshot"?()=>[]:o&&s==="getAvailable"?async()=>[]:o&&s==="getModel"?()=>{}:Reflect.get(m,s,a)}}),reveal:n(()=>{o=!1},"reveal")}}n(ot,"modelLessRegistry");async function st(t,o){const i=Y(),m=n(async w=>{const f=await Ve.create({credentials:new dn,modelsPath:Te(w.agentDir,"models.json")});ln(f);const y=await t.createAgentSessionServices({cwd:w.cwd,agentDir:w.agentDir,modelRuntime:f,resourceLoaderOptions:{additionalExtensionPaths:o.extensionPaths,appendSystemPrompt:o.appendSystemPromptPath!==void 0?[o.appendSystemPromptPath]:void 0,noContextFiles:!0,extensionsOverride:n(P=>({...P,extensions:P.extensions.filter(E=>!/[/\\]provider-rotation\.(?:ts|js)$/.test(E.path))}),"extensionsOverride")}}),b=y.resourceLoader.getExtensions();if(o.extensionPaths.some(P=>re.includes(P))){const P=new Set(b.extensions.map(R=>R.path)),E=re.filter(R=>!P.has(R));if(E.length>0){const R=b.errors.filter(D=>re.includes(D.path)).map(D=>`${D.path}: ${D.error}`).join("; ");throw new Error(`[broker] FATAL: mandatory canvas extensions failed to load: ${E.join(", ")}${R===""?"":` (${R})`}`)}}y.settingsManager.getRetryEnabled=()=>!1;const C=await rt(y,o),V=C?.model,U=C?.thinkingLevel,A=C===void 0?ot(y.modelRuntime):void 0,ae=A!==void 0?{...y,modelRuntime:A.runtime}:y,G=await t.createAgentSessionFromServices({services:ae,sessionManager:w.sessionManager,model:V,thinkingLevel:U,...nt(o.tools,Le()),sessionStartEvent:w.sessionStartEvent});return Bn(G.session),an(G.session),A?.reveal(),{...G,services:y}},"buildForManager"),s=o.resumeSessionPath,a=o.forkFrom!==void 0&&o.forkFrom!=="";if(!a&&(s===void 0||s==="")&&o.resumeSessionId!==void 0&&o.resumeSessionId!=="")throw new Error(`[broker] resume requires a session .jsonl PATH; got only a bare id '${o.resumeSessionId}' (pi_session_file was never captured for this node)`);const l=!a&&s!==void 0&&s!=="",d=l&&o.newCycle===!0,p=l&&!d;let _;if(a)_=t.SessionManager.forkFrom(o.forkFrom,o.cwd);else if(p||d){if(_=t.SessionManager.open(s),d){const w=_.getLeafId();_.resetLeaf(),_.appendCustomEntry(vn,{cycle:Number(process.env.CRTR_CYCLES),fromLeaf:w})}}else _=t.SessionManager.create(o.cwd);if(t.createAgentSessionRuntime!==void 0){const w=n(async y=>{const b=await m({cwd:y.cwd,agentDir:y.agentDir,sessionManager:y.sessionManager,sessionStartEvent:y.sessionStartEvent});return{...b,diagnostics:b.services.diagnostics??[]}},"factory"),f=await t.createAgentSessionRuntime(w,{cwd:o.cwd,agentDir:i,sessionManager:_});return{session:f.session,services:f.services,resuming:p,runtime:f}}const k=await m({cwd:o.cwd,agentDir:i,sessionManager:_});return{session:k.session,services:k.services,resuming:p,runtime:void 0}}n(st,"buildBrokerSession");function it(t){const o=n((s,a,l,d)=>{if(d?.signal?.aborted)return Promise.resolve(s);const p=t.writable();return p.length===0?Promise.resolve(s):new Promise(_=>{let k;const w=n(()=>{k!==void 0&&clearTimeout(k),d?.signal?.removeEventListener("abort",f),t.pending.delete(a.id)},"cleanup"),f=n(()=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(s)},"onAbort");d?.signal?.addEventListener("abort",f,{once:!0});const y=d?.timeout!==void 0?d.timeout:Zn;k=setTimeout(()=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(s)},y),typeof k.unref=="function"&&k.unref(),t.pending.set(a.id,{request:a,resolve:n(b=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(l(b))},"resolve")});for(const b of p)t.forward(b,a)})},"dialogPromise"),i=n(()=>{},"noop");return{[pn]:t.onKnownStreamWait??(s=>()=>{}),get theme(){const s=globalThis[Symbol.for("@earendil-works/pi-coding-agent:theme")];if(s==null)throw new Error("Theme not initialized. Call initTheme() first.");return s},select:n((s,a,l)=>o(void 0,{type:"extension_ui_request",id:x(),method:"select",title:s,options:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0,l),"select"),confirm:n((s,a,l)=>o(!1,{type:"extension_ui_request",id:x(),method:"confirm",title:s,message:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?!1:"confirmed"in d?d.confirmed:!1,l),"confirm"),input:n((s,a,l)=>o(void 0,{type:"extension_ui_request",id:x(),method:"input",title:s,placeholder:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0,l),"input"),editor:n((s,a)=>o(void 0,{type:"extension_ui_request",id:x(),method:"editor",title:s,prefill:a},l=>"cancelled"in l&&l.cancelled?void 0:"value"in l?l.value:void 0),"editor"),setStatus:n((s,a)=>t.broadcast({type:"extension_ui_request",id:x(),method:"setStatus",statusKey:s,statusText:a}),"setStatus"),setWidget:n((s,a,l)=>{typeof a!="function"&&t.broadcast({type:"extension_ui_request",id:x(),method:"setWidget",widgetKey:s,widgetLines:a,widgetPlacement:l?.placement})},"setWidget"),setTitle:n(s=>t.broadcast({type:"extension_ui_request",id:x(),method:"setTitle",title:s}),"setTitle"),notify:n((s,a)=>{const l=a==="warn"?"warning":a;t.broadcast({type:"extension_ui_request",id:x(),method:"notify",message:s,notifyType:l})},"notify"),onTerminalInput:n(()=>i,"onTerminalInput"),setWorkingMessage:i,setWorkingVisible:i,setWorkingIndicator:i,setHiddenThinkingLabel:i,setFooter:i,setHeader:i,custom:n(()=>Promise.resolve(void 0),"custom"),pasteToEditor:i,setEditorText:i,getEditorText:n(()=>"","getEditorText"),addAutocompleteProvider:i,setEditorComponent:i,getEditorComponent:n(()=>{},"getEditorComponent"),getAllThemes:n(()=>[],"getAllThemes"),getTheme:n(()=>{},"getTheme"),setTheme:i,getToolsExpanded:n(()=>!1,"getToolsExpanded"),setToolsExpanded:i}}n(it,"makeBrokerUiContext");export{fr as REVIEW_BOUNDARY_NAVIGATION_CODE,ur as ReviewBoundaryNavigationError,nt as brokerToolOptions,st as buildBrokerSession,et as disposeActiveSession,it as makeBrokerUiContext,lr as runBroker,ie as snapshotMessages};
1
+ var Pe=Object.defineProperty;var n=(t,o)=>Pe(t,"name",{value:o,configurable:!0});import{envInboxBetweenTurns as Oe,envModelIntent as Ie,envNodeCwd as De,envNodeId as Ne,envProfileId as Fe,envScopes as Le,isSandboxedNode as $e,scopeAllowed as Be}from"../../shared/env.js";import{createServer as Ue}from"node:net";import{existsSync as ye,readFileSync as Ge,unlinkSync as be}from"node:fs";import{join as Te}from"node:path";import{randomUUID as x}from"node:crypto";import{mark as Ke}from"../timing.js";import{SUBMIT_RESULT_TOOL as je}from"./structured-output.js";import{installSessionManagerStorePatch as We}from"../conversation-store/index.js";import{getAgentDir as Y,ModelRegistry as qe,ModelRuntime as Ve}from"@earendil-works/pi-coding-agent";import{nodeRunDir as Xe,viewSocketPath as He}from"../canvas/paths.js";import{bindBrokerEventSource as Ye}from"../events/source.js";import{emitEvent as T,flushBrokerLog as ze}from"../events/emit.js";import{operationIdContext as Je}from"../events/operation-id.js";import{findMissingPackagePaths as Qe}from"./package-health.js";import{installBrokerConfigSnapshot as Ze}from"../config.js";import{FRONT_DOOR_ENV as en}from"./front-door.js";import{CANVAS_EXTENSIONS as re,piInvocationToSdkConfig as nn}from"./launch.js";import{assertEngineVersion as tn,loadBrokerEngine as rn}from"./broker-sdk.js";import{initCrtrTheme as on}from"./crtr-theme.js";import{resolveBundledPiPackageDir as sn}from"./pi-cli.js";import{captureSessionChatCapabilities as an}from"./command-surface.js";import{InMemoryCredentialStore as dn}from"@earendil-works/pi-ai";import{configureBrokerModelRuntime as ln}from"./broker/model-adapter.js";import{mutateBrokerFault as z,recordBrokerTurn as Re}from"./broker/daemon-ops.js";import{modelRequestFromConfig as cn,expandModelCandidates as mn,parseModelSpec as un,unregisteredConcreteModel as fn}from"../model-routes.js";import{KNOWN_STREAM_WAIT_UI as pn}from"./stream-watchdog.js";import{probeOnline as gn}from"./connectivity.js";import{CRTR_CYCLE_CUSTOM_TYPE as vn,cycleAwareMessages as hn,endedByAbort as wn}from"./session-cycles.js";import{turnErrorOf as Sn}from"../llm/refusal.js";import{projectTranscript as _n}from"./session-visibility.js";import{currentTurnVisibility as yn}from"./turn-visibility.js";import{isUnknownModel as oe}from"./model-selection.js";import{BrokerClientRegistry as bn}from"./broker/client-registry.js";import{ToolGroupTracker as Tn}from"./broker/tool-groups.js";import{TurnReplyTracker as Rn}from"./broker/turn-replies.js";import{onNodeNamed as kn}from"./broker/node-named.js";import{FaultRetry as En,willDaemonRetry as Mn}from"./broker/fault-retry.js";import{RunTurnEnds as xn}from"./broker/run-turn-end.js";import{createTurnAdmissionGate as Cn}from"./broker/turn-admission.js";import{BROKER_IDLE_TURN_START as An,BROKER_RUN_TURN_BUSY as Pn}from"./broker/held-deferred-inbox.js";import{prependRunDeferredMail as On,settleRunDeferredMail as In}from"./broker/run-deferred-mail.js";import{createRunTurnQueue as Dn}from"./broker/run-turn-queue.js";import{EventProjection as Nn}from"./broker/event-projection.js";import{createFrameDispatchContext as Fn,handleFrame as Ln}from"./broker/frame-dispatch.js";import{hydratePersistedAdvertisedCommandMessages as $n,installAdvertisedCommandInvocationContract as Bn}from"./advertised-command-invocation.js";import{RebindDriver as Un}from"./broker/rebind.js";import{beginRuntimeTeardown as Gn}from"./broker/extension-abort.js";import{receiveNodeToken as Kn}from"./broker/node-token.js";import{serveCliRelay as jn}from"./broker/cli-relay.js";import{decodeKickoffOrigin as Wn,KICKOFF_ORIGIN_ENV as qn}from"./stamp/protocol.js";import{announceMessageOrigin as Vn}from"./stamp/channel.js";import{brokerExtensionState as Xn,commitBrokerModel as Hn}from"./broker/daemon-ops.js";import{composerNames as Yn}from"./broker/frame-memory-refs.js";import{FrameOverflowError as zn,normalizeSnapshotTail as Jn}from"./broker-protocol.js";import{ReviewBoundaryNavigationError as ur,REVIEW_BOUNDARY_NAVIGATION_CODE as fr}from"./broker/frame-replies.js";function ie(t){return new qe(t.modelRuntime)}n(ie,"registryOf");function B(t,o){if(t==null||oe(t))return null;const s=o!==void 0&&o!==""&&o!=="off"?`:${o}`:"";return`${t.provider}/${t.id}${s}`}n(B,"formatModelSpec");function Qn(t,o){const s=B(t,void 0);return s===null?null:`${s}:${o===void 0||o===""?"off":o}`}n(Qn,"formatExactModelSpec");const Zn=12e4;let J=null;import{brokerSignalClient as Q}from"./broker/signal-stream.js";function et(){Q().stop();const t=J;if(J=null,t!==null)try{t.dispose()}catch{}}n(et,"disposeActiveSession");function nt(t,o){const s=Be(o,"crtr:act")?void 0:["bash"],m=t!==void 0&&t.length>0?[...new Set([...t,je])]:t===void 0?void 0:[...t];return{...m!==void 0?{tools:m}:{},...s!==void 0?{excludeTools:s}:{}}}n(nt,"brokerToolOptions");async function lr(t,o=process.hrtime.bigint(),s=new Date().toISOString()){Ye(t);const m=await Kn(),i=await jn(t,m);process.env.CRTR_API_SOCKET=i.path,Je.fresh(()=>{T({level:"info",event:"broker.startup.cli_entry",ts:s,duration_ms:0,fields:{runtime_version:process.version,engine_version:null,model:null}}),T({level:"info",event:"broker.startup.module_loaded",duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{runtime_version:process.version,engine_version:null,model:null}})});const a=new Set;let l=null;const d=n((e,r=null)=>{a.has(e)||(a.add(e),Ke(e,{duration_ms:Number(process.hrtime.bigint()-o)/1e6}),T({level:"info",event:e,duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{runtime_version:process.version,engine_version:l,model:r}}))},"emitStartupMilestone");process.env[en]="1",process.env.CRTR_BROKER_PID=String(process.pid),delete process.env.TMUX_PANE,delete process.env.TMUX,We(t);const p=await rn();tn(p.VERSION),l=p.VERSION;const S=Xe(t),k=Te(S,"broker-launch.json"),_=JSON.parse(Ge(k,"utf8"));if($e()){if(!_.configSnapshot)throw new Error("broker launch is missing its config snapshot");Ze(_.configSnapshot)}const f=nn(_);f.modelExact===!0?process.env.CRTR_MODEL_EXACT="1":delete process.env.CRTR_MODEL_EXACT;const y=await Yn(t);let b,C;const V=n(e=>{b!==void 0?b(e):C??=e},"onSignal");process.on("SIGTERM",()=>V("SIGTERM")),process.on("SIGINT",()=>V("SIGINT"));let{session:U,services:A,resuming:ae,runtime:G}=await it(p,f);d("broker.startup.session_built");const E=(await Xn(t)).node.review_binding?.review_id,R=Oe();J=U;const D=gn;try{process.env.PI_PACKAGE_DIR=sn(),on(A.settingsManager.getTheme(),Y(),!1)}catch(e){T({level:"error",event:"broker.theme.initialization_failed",error:e})}try{for(const e of Qe(Y()))T({level:"warn",event:"broker.startup.warning",fields:{stage:"package_health",source:e.source,resolved_path:e.resolved}})}catch{}const K=He(t),g=new bn(t),X=new Map,O=new Tn(t,e=>g.broadcast(e)),j=new Rn(t,e=>g.broadcast(e));kn(e=>g.broadcast({type:"node_named",...e}));let N=!1,de=!1,H,le,u,W;const Z=new xn;let F,ce=n(()=>{},"notifyTurnAccepted"),me=n(()=>{},"resetFrameState");const ee=Cn();let ue=n(()=>0,"pendingPromptDispatches"),fe;const L=Dn({runNode:R,session:n(()=>u.session(),"session"),isReplacing:n(()=>u.isReplacing(),"isReplacing"),pendingRebind:n(()=>u.pendingRebind(),"pendingRebind"),isAgentRunActive:n(()=>u.isAgentRunActive(),"isAgentRunActive"),pendingDispatches:n(()=>ue(),"pendingDispatches"),turnAdmission:ee,prependDeferred:n(e=>On(t,e),"prependDeferred"),onError:n(e=>T({level:"error",event:"broker.inbox.idle_prompt_failed",error:e}),"onError")}),pe=L.drain;f.firstPrompt!==void 0&&f.firstPrompt!==""&&L.holdForKickoff(),globalThis[An]=L.start,globalThis[Pn]=L.busy,u=new Un({nodeId:t,cfg:f,session:U,services:A,runtime:G,registry:g,toolGroups:O,turnReplies:j,transcriptMessages:n(e=>se(e,E)?.map(({message:r})=>r)??e.sessionManager.buildSessionContext().messages,"transcriptMessages"),uiContext:n(()=>le,"uiContext"),faultRetry:n(()=>W,"faultRetry"),projection:n(()=>F,"projection"),setActiveSession:n(e=>{if(J=e,fe?.(),R){let r="stop",c,v=!1;fe=e.subscribe(h=>{if(h.type==="agent_start"&&(r="stop",c=void 0,v=!1,Z.started()),h.type==="agent_end"){const w=[...h.messages??[]].reverse().find($=>$.role==="assistant");w&&(r=w.stopReason,c=wn(w)?void 0:Sn(w),v=w.role==="assistant"&&Mn(w,e.model?.contextWindow))}h.type==="agent_settled"&&(Z.settled(e.sessionManager,{stop_reason:r,...c?{error:c}:{}},v),In(t,e).catch(w=>{T({level:"error",event:"broker.run_deferred_mail.settle_failed",error:w})}),queueMicrotask(()=>{u.session()===e&&pe()}))})}},"setActiveSession"),disposeAndExit:n((e,r)=>q(e,r),"disposeAndExit"),onSessionRebind:n(()=>{me()},"onSessionRebind"),onReplacementIdle:n(()=>{R&&pe()},"onReplacementIdle"),reWelcomeAll:n(()=>ne(),"reWelcomeAll")});const ge=n(async(e,r=!1)=>{const c=u.session(),v=B(c.model,c.thinkingLevel);if(v===null)return null;const h=await Hn(t,{spec:v,...e!==void 0?{intent:e}:{},userSelected:r});return r&&(f.model=h.modelOverride,e!==void 0?(process.env.CRTR_MODEL_INTENT=`${e.family}/${e.strength}`,delete process.env.CRTR_MODEL_EXACT,f.modelExact=void 0):(delete process.env.CRTR_MODEL_INTENT,process.env.CRTR_MODEL_EXACT="1",f.modelExact=!0)),h.modelOverride},"persistModelChoice"),ve=n(async(e=!0,r,c=!1)=>{const v=u.session(),h=B(v.model,v.thinkingLevel),w=e?await ge(r,c):h;g.broadcast({type:"model_changed",model:oe(v.model)?void 0:v.model,spec:w})},"broadcastModelChanged");W=new En({nodeId:t,cfg:f,retryProbe:D,currentSession:n(()=>u.session(),"currentSession"),currentServices:n(()=>u.services(),"currentServices"),installedGeneration:n(()=>u.installedGeneration(),"installedGeneration"),registryOf:ie,formatModelSpec:B,broadcastModelChanged:ve,turnAdmission:ee,reWelcomeAll:n(()=>ne(),"reWelcomeAll"),...R?{turnEnds:Z}:{}});const he=n(()=>{W.rearmIfStranded().catch(e=>{T({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`fault retry re-arm failed: ${e instanceof Error?e.message:String(e)}`}})})},"rearmStrandedRetry");Q().subscribe("resync",he),Q().subscribe("fault-retry",he),F=new Nn({registry:g,faultRetry:W,installedGeneration:n(()=>u.installedGeneration(),"installedGeneration"),currentSession:n(()=>u.session(),"currentSession"),notifyTurnAccepted:n(()=>ce(),"notifyTurnAccepted"),emitStartupMilestone:d,formatModelSpec:B});const Ee=n(e=>{const r=u.session(),c=se(r,E),v=Jn(e.snapshotTail),h=c===void 0||v===void 0?c:c.slice(-v),w=h?.map(({message:I})=>I)??r.sessionManager.buildSessionContext().messages,$=O.summaries(),_e=h!==void 0&&v!==void 0?tt(w):void 0,Ae=_e===void 0?$:Object.fromEntries(Object.entries($).filter(([I])=>_e.has(I)));return{messages:w,...h===void 0?{}:{messageIds:h.map(({id:I})=>I)},messageVisibility:h?.map(({visibility:I})=>I)??w.map(()=>"visible"),turnVisibility:yn(),stats:r.getSessionStats(),state:{model:oe(r.model)?void 0:r.model,thinkingLevel:r.thinkingLevel,isStreaming:r.isStreaming,isCompacting:r.isCompacting,steeringMode:r.steeringMode,followUpMode:r.followUpMode,sessionFile:r.sessionFile,sessionId:r.sessionId,sessionName:r.sessionName,autoCompactionEnabled:r.autoCompactionEnabled,messageCount:r.messages.length,pendingMessageCount:r.pendingMessageCount},display:{...g.displaySnapshot()},toolGroupSummaries:Ae,turnReplies:j.snapshot(),workingActivity:F.currentWorkingActivity(),queued:{steering:[...r.getSteeringMessages()],followUp:[...r.getFollowUpMessages()]}}},"buildSnapshot"),we=n(e=>{const r=e.role==="controller"?X.values().next().value:void 0;g.sendFrame(e,{type:"welcome",snapshot:Ee(e),role:e.role,pending_dialog:r!==void 0?r.request:null,agentDir:Y()},!0)},"sendWelcome"),Me=n(e=>{const r=[...X.values()];for(let c=1;c<r.length;c++)g.sendFrame(e,r[c].request)},"replayExtraPendingDialogsTo"),ne=n(()=>{try{const e=u.session();j.seed(se(e,E)?.map(({message:r})=>r)??e.sessionManager.buildSessionContext().messages)}catch(e){T({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`turn reply reseed failed: ${String(e)}`}})}g.forEachHelloed(we)},"reWelcomeAll"),Se=n(async e=>{if(!N){N=!0,Q().stop(),O.persistPendingSummary(),F.dispose(),et();try{H?.close()}catch{}i.close(),g.dispose();try{ye(K)&&be(K)}catch{}g.clearAttachState(),await ze(),process.exit(e)}},"completeExit"),q=n((e,r=0)=>{if(N)return;const c=e==="shutdown-hook"||e==="shutdown-after-settle";if(c&&O.finishOpenToolGroup(!0),c&&(O.hasSummaryTasks()||j.hasTasks())){if(de)return;de=!0,Promise.allSettled([O.waitForSummaryTasks(),j.waitForTasks()]).finally(()=>Se(r));return}Se(r)},"disposeAndExit");le=st({writable:n(()=>g.writableClients(),"writable"),forward:n((e,r)=>g.sendFrame(e,r),"forward"),pending:X,broadcast:n(e=>g.broadcastUi(e),"broadcast"),onKnownStreamWait:n(e=>F.knownStreamWait(e),"onKnownStreamWait")}),u.setRebindSession(),await u.enqueueRebind(U,A),d("broker.startup.extensions_bound");const M=Fn({nodeId:t,registry:g,toolGroups:O,projection:F,rebind:u,boundaryReviewId:E,pendingDialogs:X,sendWelcome:we,replayExtraPendingDialogsTo:Me,reWelcomeAll:ne,disposeAndExit:q,persistModelChoice:ge,broadcastModelChanged:ve,registryOf:ie,formatModelSpec:B,formatExactModelSpec:Qn,turnAdmission:ee,memoryInventory:y,runNode:R,onKickoffAdmitted:L.releaseKickoff});ce=M.notifyTurnAccepted,me=M.resetForSession,ue=M.pendingPromptDispatches;const xe=2500;let te=!1;const Ce=n(async e=>{if(N||te)return;if(te=!0,u.isAgentRunActive()||u.session().isStreaming||M.pendingPromptDispatches()>0){const c=Date.now()+xe;for(;M.pendingPromptDispatches()>0&&!u.session().isStreaming&&Date.now()<c;)await new Promise(v=>setTimeout(v,25));if(u.session().isStreaming){const v=c-Date.now();if(v>0){let h;try{Gn(),await Promise.race([u.session().abort().then(()=>!0,()=>!1),new Promise($=>{h=setTimeout(()=>$(!1),v)})])&&await Re(t,{event:"closed",end_reason:"teardown-aborted"})}finally{h!==void 0&&clearTimeout(h)}}}else(M.pendingPromptDispatches()>0||u.isAgentRunActive())&&await Re(t,{event:"interrupted"})}q(e)},"abortAndExit");if(b=n(e=>{Ce(e)},"signalTeardown"),C!==void 0){b(C);return}try{ye(K)&&be(K)}catch{}H=Ue(e=>{const r=g.create(e);e.on("data",v=>{let h;try{h=r.decoder.push(v)}catch(w){w instanceof zn?(g.sendFrame(r,{type:"error",code:"frame_overflow",message:w.message}),g.dropClient(r,`frame overflow: ${w.message}`)):g.dropClient(r,`decoder error: ${String(w)}`);return}for(const w of h)try{Ln(M,r,w)}catch{}});const c=n(()=>{g.removeClient(r)},"drop");e.on("close",c),e.on("error",()=>{})}),H.on("error",e=>{N||(T({level:"error",event:"broker.socket.failed",error:e}),q("socket-error",1))}),H.listen(K,async()=>{Promise.all([z(t,{op:"clear",link:"viewer\u2194broker"}),z(t,{op:"clear",link:"relay\u2194broker"})]).catch(r=>T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"broker_socket_bound_fault_clear"}}));let e;try{e=await W.recoverOnStartup()}catch(r){T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"recovery_startup"}}),q("recovery-startup-failed",1);return}if(!(N||te))if(e!=="retry-armed"&&f.firstPrompt!==void 0&&f.firstPrompt!==""){const r=Wn(process.env[qn]);r!==null&&Vn(f.firstPrompt,r);const c=process.env.CRTR_KICKOFF_MESSAGE_IDS;M.kickoff(f.firstPrompt,c?JSON.parse(c):[])}else L.releaseKickoff()}),g.persistAttachState()}n(lr,"runBroker");function tt(t){const o=new Set;for(const s of t)if(!(s.role!=="assistant"||!Array.isArray(s.content)))for(const m of s.content)m!==null&&typeof m=="object"&&m.type==="toolCall"&&typeof m.id=="string"&&o.add(m.id);return o}n(tt,"toolCallIds");function se(t,o){const s=t.sessionManager,m=hn(s);return m!==void 0&&$n(m.map(({message:i})=>i)),m===void 0?void 0:_n(m,{boundaryReviewId:o,sessionEntries:s.getEntries?.()})}n(se,"snapshotMessages");function ke(){const t=Ne();if(t===void 0||t==="")throw new Error("broker launch is missing CRTR_NODE_ID");return t}n(ke,"currentBrokerNodeId");async function rt(t,o){const s=cn(o.model,Ie(),o.modelExact===!0);if(s===void 0)return;const m=ie(t),i={cwd:De()??o.cwd,profileId:Fe()},a=fn(s,m,i);if(a!==void 0)throw await z(ke(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`model '${a.request.spec}' is not registered in the serving model registry`}}),new Error(`[broker] FATAL: model '${a.request.spec}' is not registered in the serving model registry`);const l=mn(s,i.cwd,i.profileId),d=un(s.spec);for(const p of l){const S=m.find(p.providerId,p.modelId);if(S===void 0)continue;const _=d?.providerId===p.providerId&&d.modelId===p.modelId?d.thinkingLevel??(p.thinkingLevel===void 0?void 0:"off"):p.thinkingLevel;return{model:S,thinkingLevel:_}}if(o.modelExact===!0){const p=l.map(S=>`'${S.providerId}/${S.modelId}' unregistered`).join("; ");throw await z(ke(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`exact-consult model '${o.model}' is unavailable \u2014 refusing to substitute (${p})`}}),new Error(`[broker] FATAL: exact-consult model '${o.model}' is unavailable`)}T({level:"warn",event:"broker.model.none_viable",fields:{rejected_candidates:l.map(p=>({provider:p.providerId,model:p.modelId,reason:"unregistered"})).slice(0,16)}})}n(rt,"resolveLaunchModel");function ot(t){let o=!0;return{runtime:new Proxy(t,{get(m,i,a){return o&&i==="getAvailableSnapshot"?()=>[]:o&&i==="getAvailable"?async()=>[]:o&&i==="getModel"?()=>{}:Reflect.get(m,i,a)}}),reveal:n(()=>{o=!1},"reveal")}}n(ot,"modelLessRegistry");async function it(t,o){const s=Y(),m=n(async _=>{const f=await Ve.create({credentials:new dn,modelsPath:Te(_.agentDir,"models.json")});ln(f);const y=await t.createAgentSessionServices({cwd:_.cwd,agentDir:_.agentDir,modelRuntime:f,resourceLoaderOptions:{additionalExtensionPaths:o.extensionPaths,appendSystemPrompt:o.appendSystemPromptPath!==void 0?[o.appendSystemPromptPath]:void 0,noContextFiles:!0,extensionsOverride:n(P=>({...P,extensions:P.extensions.filter(E=>!/[/\\]provider-rotation\.(?:ts|js)$/.test(E.path))}),"extensionsOverride")}}),b=y.resourceLoader.getExtensions();if(o.extensionPaths.some(P=>re.includes(P))){const P=new Set(b.extensions.map(R=>R.path)),E=re.filter(R=>!P.has(R));if(E.length>0){const R=b.errors.filter(D=>re.includes(D.path)).map(D=>`${D.path}: ${D.error}`).join("; ");throw new Error(`[broker] FATAL: mandatory canvas extensions failed to load: ${E.join(", ")}${R===""?"":` (${R})`}`)}}y.settingsManager.getRetryEnabled=()=>!1;const C=await rt(y,o),V=C?.model,U=C?.thinkingLevel,A=C===void 0?ot(y.modelRuntime):void 0,ae=A!==void 0?{...y,modelRuntime:A.runtime}:y,G=await t.createAgentSessionFromServices({services:ae,sessionManager:_.sessionManager,model:V,thinkingLevel:U,...nt(o.tools,Le()),sessionStartEvent:_.sessionStartEvent});return Bn(G.session),an(G.session),A?.reveal(),{...G,services:y}},"buildForManager"),i=o.resumeSessionPath,a=o.forkFrom!==void 0&&o.forkFrom!=="";if(!a&&(i===void 0||i==="")&&o.resumeSessionId!==void 0&&o.resumeSessionId!=="")throw new Error(`[broker] resume requires a session .jsonl PATH; got only a bare id '${o.resumeSessionId}' (pi_session_file was never captured for this node)`);const l=!a&&i!==void 0&&i!=="",d=l&&o.newCycle===!0,p=l&&!d;let S;if(a)S=await t.SessionManager.forkFrom(o.forkFrom,o.cwd);else if(p||d){if(S=await t.SessionManager.open(i),d){const _=S.getLeafId();S.resetLeaf(),S.appendCustomEntry(vn,{cycle:Number(process.env.CRTR_CYCLES),fromLeaf:_})}}else S=await t.SessionManager.create(o.cwd);if(t.createAgentSessionRuntime!==void 0){const _=n(async y=>{const b=await m({cwd:y.cwd,agentDir:y.agentDir,sessionManager:y.sessionManager,sessionStartEvent:y.sessionStartEvent});return{...b,diagnostics:b.services.diagnostics??[]}},"factory"),f=await t.createAgentSessionRuntime(_,{cwd:o.cwd,agentDir:s,sessionManager:S});return{session:f.session,services:f.services,resuming:p,runtime:f}}const k=await m({cwd:o.cwd,agentDir:s,sessionManager:S});return{session:k.session,services:k.services,resuming:p,runtime:void 0}}n(it,"buildBrokerSession");function st(t){const o=n((i,a,l,d)=>{if(d?.signal?.aborted)return Promise.resolve(i);const p=t.writable();return p.length===0?Promise.resolve(i):new Promise(S=>{let k;const _=n(()=>{k!==void 0&&clearTimeout(k),d?.signal?.removeEventListener("abort",f),t.pending.delete(a.id)},"cleanup"),f=n(()=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),S(i)},"onAbort");d?.signal?.addEventListener("abort",f,{once:!0});const y=d?.timeout!==void 0?d.timeout:Zn;k=setTimeout(()=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),S(i)},y),typeof k.unref=="function"&&k.unref(),t.pending.set(a.id,{request:a,resolve:n(b=>{_(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),S(l(b))},"resolve")});for(const b of p)t.forward(b,a)})},"dialogPromise"),s=n(()=>{},"noop");return{[pn]:t.onKnownStreamWait??(i=>()=>{}),get theme(){const i=globalThis[Symbol.for("@earendil-works/pi-coding-agent:theme")];if(i==null)throw new Error("Theme not initialized. Call initTheme() first.");return i},select:n((i,a,l)=>o(void 0,{type:"extension_ui_request",id:x(),method:"select",title:i,options:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0,l),"select"),confirm:n((i,a,l)=>o(!1,{type:"extension_ui_request",id:x(),method:"confirm",title:i,message:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?!1:"confirmed"in d?d.confirmed:!1,l),"confirm"),input:n((i,a,l)=>o(void 0,{type:"extension_ui_request",id:x(),method:"input",title:i,placeholder:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0,l),"input"),editor:n((i,a)=>o(void 0,{type:"extension_ui_request",id:x(),method:"editor",title:i,prefill:a},l=>"cancelled"in l&&l.cancelled?void 0:"value"in l?l.value:void 0),"editor"),setStatus:n((i,a)=>t.broadcast({type:"extension_ui_request",id:x(),method:"setStatus",statusKey:i,statusText:a}),"setStatus"),setWidget:n((i,a,l)=>{typeof a!="function"&&t.broadcast({type:"extension_ui_request",id:x(),method:"setWidget",widgetKey:i,widgetLines:a,widgetPlacement:l?.placement})},"setWidget"),setTitle:n(i=>t.broadcast({type:"extension_ui_request",id:x(),method:"setTitle",title:i}),"setTitle"),notify:n((i,a)=>{const l=a==="warn"?"warning":a;t.broadcast({type:"extension_ui_request",id:x(),method:"notify",message:i,notifyType:l})},"notify"),onTerminalInput:n(()=>s,"onTerminalInput"),setWorkingMessage:s,setWorkingVisible:s,setWorkingIndicator:s,setHiddenThinkingLabel:s,setFooter:s,setHeader:s,custom:n(()=>Promise.resolve(void 0),"custom"),pasteToEditor:s,setEditorText:s,getEditorText:n(()=>"","getEditorText"),addAutocompleteProvider:s,setEditorComponent:s,getEditorComponent:n(()=>{},"getEditorComponent"),getAllThemes:n(()=>[],"getAllThemes"),getTheme:n(()=>{},"getTheme"),setTheme:s,getToolsExpanded:n(()=>!1,"getToolsExpanded"),setToolsExpanded:s}}n(st,"makeBrokerUiContext");export{fr as REVIEW_BOUNDARY_NAVIGATION_CODE,ur as ReviewBoundaryNavigationError,nt as brokerToolOptions,it as buildBrokerSession,et as disposeActiveSession,st as makeBrokerUiContext,lr as runBroker,se as snapshotMessages};
@@ -5,7 +5,7 @@ export type NoticeEvent = 'notice.crash' | 'notice.deadline' | 'notice.close';
5
5
  * is open. The message body carries today's sentence (as `body`, which the inbox card shows)
6
6
  * and data; `publish` picks the recipients, their tier and wake from each watch. A node whose
7
7
  * object is already gone publishes nothing. `onlyWatchers` narrows the recipients to those watchers. */
8
- export declare function publishNotice(nodeId: string, event: NoticeEvent, label: string, data: Record<string, unknown>, tier?: InboxTier, actor?: ObjectRow | null, onlyWatchers?: readonly string[]): void;
8
+ export declare function publishNotice(nodeId: string, event: NoticeEvent, label: string, data: Record<string, unknown>, tier?: InboxTier, actor?: ObjectRow | null, onlyWatchers?: readonly string[]): Promise<void>;
9
9
  export interface CloseNodeResult {
10
10
  /** The focused node that was closed — the cascade root. */
11
11
  root: string;
@@ -20,7 +20,7 @@ export interface CloseNodeResult {
20
20
  * subscriptions spine, all of whose managers are themselves in the set. Grown
21
21
  * to a fixpoint — a node added this pass can qualify its own children next
22
22
  * pass. Cycle-safe via the membership skip. */
23
- export declare function closingSet(root: string): Set<string>;
23
+ export declare function closingSet(root: string): Promise<Set<string>>;
24
24
  /** Close `rootId` and its exclusive subtree. Best-effort throughout: a tmux/db
25
25
  * failure on one node never aborts the cascade. Throws only on an unknown root
26
26
  * so the command can surface a clean not-found error.
@@ -43,4 +43,4 @@ export declare function closeNode(rootId: string, opts?: {
43
43
  stopReason?: string;
44
44
  /** The node that asked for the close; absent means the local person. */
45
45
  closer?: string;
46
- }): CloseNodeResult;
46
+ }): Promise<CloseNodeResult>;
@@ -1 +1 @@
1
- var k=Object.defineProperty;var a=(r,o)=>k(r,"name",{value:o,configurable:!0});import{getNode as h,subscriptionsOf as u,subscribersOf as E}from"../canvas/index.js";import{transition as w}from"./lifecycle.js";import{stopNodeSandboxes as $}from"../spaces/stop.js";import{tearDownNode as D,reapIfEmpty as N}from"./placement.js";import{crtrHome as L,jobDir as O}from"../canvas/paths.js";import{contextDir as x,nodeAgentDir as S}from"../canvas/node-agent-paths.js";import{readLiveSession as j}from"../canvas/sessions.js";import{discoverLifecycleHookRegistry as H}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as A}from"../command-hooks/transport/exec-lifecycle.js";import{emitEvent as p}from"../events/emit.js";import{enqueueNodeMail as B}from"../feed/messages.js";import{withCanvasWrite as v}from"../canvas/db.js";import{recordActedOn as C}from"../graph/edges.js";import{publish as R}from"../graph/events.js";import{getById as y,nodeObject as T,ownerForGrantee as Y}from"../graph/objects.js";const q={deferred:3,normal:5,urgent:7,critical:7};function P(r,o,l,s,d="normal",i=null,c){v(e=>{const n=y(e,r);n===null||n.type!=="node"||R(e,{event:o,object:n,actor:i,level:q[d],attrs:{},messageBody:{...s,body:l},...c===void 0?{}:{onlyWatchers:c}})})}a(P,"publishNotice");function z(r){const o=new Set([r]);let l=!0;for(;l;){l=!1;for(const s of[...o])for(const d of u(s)){const i=d.node_id;o.has(i)||E(i).every(c=>o.has(c.node_id))&&(o.add(i),l=!0)}}return o}a(z,"closingSet");function F(r,o){const l=[],s=new Set([r]),d=[r];for(;d.length>0;){const i=d.shift();l.push(i);for(const c of u(i))o.has(c.node_id)&&!s.has(c.node_id)&&(s.add(c.node_id),d.push(c.node_id))}for(const i of o)s.has(i)||l.push(i);return l.reverse()}a(F,"killOrder");function G(r,o){const l=r?"You were CLOSED by the user from the canvas":"You were CANCELED \u2014 an ancestor of yours was closed from the canvas";if(o.length===0)return`${l}. Your pi session is preserved; this resume reopened it.`;const s=o.slice(0,4).map(i=>{const c=h(i);return c!==null?`${c.name} (${i})`:i}),d=o.length>s.length?` +${o.length-s.length} more`:"";return`${l}. ${o.length} child node(s) you subscribe to were canceled with you and are no longer running: ${s.join(", ")}${d}. Resuming will NOT restore them \u2014 re-spawn if you still need that work.`}a(G,"cancellationLabel");function se(r,o={}){if(h(r)===null)throw new Error(`closeNode: unknown node ${r}`);const l=o.rootEvent??"cancel",s=z(r),d=F(r,s),i=[];for(const e of s)for(const n of u(e))!s.has(n.node_id)&&!i.includes(n.node_id)&&i.push(n.node_id);const c=[];for(const e of d)try{const n=h(e);if(n===null)continue;const _=u(e).map(t=>t.node_id).filter(t=>s.has(t));let m;try{const t=H(n.cwd,n.profile_id).plans.get("node:close")??[];if(t.length>0){const f={node:{id:e,name:n.name,kind:n.kind,mode:n.mode,lifecycle:n.lifecycle,cwd:n.cwd,nodeDir:S(e),contextDir:x(e),jobDir:O(e)},runtime:{isBirth:!1,canvasHome:L(),profile:n.profile_id??null}};m=a(()=>A(t,f),"afterTeardown")}}catch(t){p({level:"error",event:"node.close_hook.discovery_failed",node_id:e,error:t})}const b=$(e,o.stopReason??"node_closed",{...e===r?{excludePid:o.callerPid}:{},...m?{after:m}:{}});try{o.registerDetached?.(b.then(()=>{}))}catch(t){p({level:"error",event:"node.close_hook.detached_registration_failed",node_id:e,error:t})}if(v(t=>{const f=y(t,e);if(f===null||f.type!=="node")return;const g=o.closer!==void 0?T(t,o.closer):Y(t,"user:local");C(t,g,f),P(e,"notice.close",`Child closed \u2014 ${n.name} (${e}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:e},"normal",g)}),o.preserveEmpty||n.run_id!==null&&n.pi_pid!==null&&j(e)?.sessionId!=null||!N(e,void 0,!1)){const t=n.final_report!==null&&n.final_report!==void 0;e===r&&l==="finish"||t?(n.status==="active"||n.status==="idle")&&w(e,"finish"):w(e,"cancel",{reason:"closed"}),D(e),B(e,{kind:"message",label:G(e===r,_),bodyJson:{reason:"user-close",cascade_root:r,canceled_children:_},urgency:"normal",wake:1})}c.push(e)}catch(n){p({level:"error",event:"node.close.failed",node_id:e,error:n})}return{root:r,closed:c,spared:i}}a(se,"closeNode");export{se as closeNode,z as closingSet,P as publishNotice};
1
+ var k=Object.defineProperty;var d=(i,o)=>k(i,"name",{value:o,configurable:!0});import{getNode as w,subscriptionsOf as u,subscribersOf as E}from"../canvas/index.js";import{transition as _}from"./lifecycle.js";import{stopNodeSandboxes as $}from"../spaces/stop.js";import{tearDownNode as D,reapIfEmpty as N}from"./placement.js";import{crtrHome as L,jobDir as O}from"../canvas/paths.js";import{contextDir as x,nodeAgentDir as S}from"../canvas/node-agent-paths.js";import{readLiveSession as j}from"../canvas/sessions.js";import{discoverLifecycleHookRegistry as A}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as H}from"../command-hooks/transport/exec-lifecycle.js";import{emitEvent as h}from"../events/emit.js";import{enqueueNodeMail as B}from"../feed/messages.js";import{withCanvasWrite as g}from"../canvas/db.js";import{recordActedOn as C}from"../graph/edges.js";import{publish as R}from"../graph/events.js";import{getById as v,nodeObject as T,ownerForGrantee as Y}from"../graph/objects.js";import{mapAsync as q}from"../async-array.js";const P={deferred:3,normal:5,urgent:7,critical:7};async function z(i,o,c,a,l="normal",t=null,s){await g(async e=>{const n=await v(e,i);n===null||n.type!=="node"||await R(e,{event:o,object:n,actor:t,level:P[l],attrs:{},messageBody:{...a,body:c},...s===void 0?{}:{onlyWatchers:s}})})}d(z,"publishNotice");async function F(i){const o=new Set([i]);let c=!0;for(;c;){c=!1;for(const a of[...o])for(const l of await u(a)){const t=l.node_id;o.has(t)||(await E(t)).every(s=>o.has(s.node_id))&&(o.add(t),c=!0)}}return o}d(F,"closingSet");async function G(i,o){const c=[],a=new Set([i]),l=[i];for(;l.length>0;){const t=l.shift();c.push(t);for(const s of await u(t))o.has(s.node_id)&&!a.has(s.node_id)&&(a.add(s.node_id),l.push(s.node_id))}for(const t of o)a.has(t)||c.push(t);return c.reverse()}d(G,"killOrder");async function J(i,o){const c=i?"You were CLOSED by the user from the canvas":"You were CANCELED \u2014 an ancestor of yours was closed from the canvas";if(o.length===0)return`${c}. Your pi session is preserved; this resume reopened it.`;const a=await q(o.slice(0,4),async t=>{const s=await w(t);return s!==null?`${s.name} (${t})`:t}),l=o.length>a.length?` +${o.length-a.length} more`:"";return`${c}. ${o.length} child node(s) you subscribe to were canceled with you and are no longer running: ${a.join(", ")}${l}. Resuming will NOT restore them \u2014 re-spawn if you still need that work.`}d(J,"cancellationLabel");async function ce(i,o={}){if(await w(i)===null)throw new Error(`closeNode: unknown node ${i}`);const c=o.rootEvent??"cancel",a=await F(i),l=await G(i,a),t=[];for(const e of a)for(const n of await u(e))!a.has(n.node_id)&&!t.includes(n.node_id)&&t.push(n.node_id);const s=[];for(const e of l)try{const n=await w(e);if(n===null)continue;const p=(await u(e)).map(r=>r.node_id).filter(r=>a.has(r));let m;try{const r=A(n.cwd,n.profile_id).plans.get("node:close")??[];if(r.length>0){const f={node:{id:e,name:n.name,kind:n.kind,mode:n.mode,lifecycle:n.lifecycle,cwd:n.cwd,nodeDir:await S(e),contextDir:await x(e),jobDir:O(e)},runtime:{isBirth:!1,canvasHome:L(),profile:n.profile_id??null}};m=d(()=>H(r,f),"afterTeardown")}}catch(r){h({level:"error",event:"node.close_hook.discovery_failed",node_id:e,error:r})}const b=$(e,o.stopReason??"node_closed",{...e===i?{excludePid:o.callerPid}:{},...m?{after:m}:{}});try{o.registerDetached?.(b.then(()=>{}))}catch(r){h({level:"error",event:"node.close_hook.detached_registration_failed",node_id:e,error:r})}if(await g(async r=>{const f=await v(r,e);if(f===null||f.type!=="node")return;const y=o.closer!==void 0?await T(r,o.closer):await Y(r,"user:local");await C(r,y,f),await z(e,"notice.close",`Child closed \u2014 ${n.name} (${e}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:e},"normal",y)}),o.preserveEmpty||n.run_id!==null&&n.pi_pid!==null&&(await j(e))?.sessionId!=null||!await N(e,void 0,!1)){const r=n.final_report!==null&&n.final_report!==void 0;e===i&&c==="finish"||r?(n.status==="active"||n.status==="idle")&&await _(e,"finish"):await _(e,"cancel",{reason:"closed"}),await D(e),await B(e,{kind:"message",label:await J(e===i,p),bodyJson:{reason:"user-close",cascade_root:i,canceled_children:p},urgency:"normal",wake:1})}s.push(e)}catch(n){h({level:"error",event:"node.close.failed",node_id:e,error:n})}return{root:i,closed:s,spared:t}}d(ce,"closeNode");export{ce as closeNode,F as closingSet,z as publishNotice};
@@ -1 +1 @@
1
- var n=Object.defineProperty;var r=(t,e)=>n(t,"name",{value:e,configurable:!0});import{getNode as m}from"../canvas/index.js";import{withCanvasWrite as a}from"../canvas/db.js";import{readerForNode as s}from"../graph/reader.js";import{noteNodeBooting as c}from"../graph/repo-sync/index.js";import{checkoutsForCwd as f}from"../graph/repo-sync/repos.js";import{deliver as l}from"../substrate/delivery/deliver.js";import{oneShotControllerRequest as u}from"./broker-request.js";import{isBrokerLive as p}from"./model-swap.js";import{CONTEXT_INTRO_CUSTOM_TYPE as v}from"./bearings.js";import{formatCard as d}from"../../shared/generated-context.js";async function w(t,e){const o=m(t);if(o===null)throw new Error(`deliverCustomMessageLive: unknown node ${t}`);p(o)&&await u({nodeId:t,what:`the ${e.customType} delivery`,ackFor:"deliver_custom_message",frame:r(()=>({type:"deliver_custom_message",customType:e.customType,content:e.content,...e.deliverAs!==void 0?{deliverAs:e.deliverAs}:{},...e.details!==void 0?{details:e.details}:{}}),"frame"),result:r(()=>{},"result")})}r(w,"deliverCustomMessageLive");async function F(t){await c(t);const{content:e}=a(o=>l(o,s(o,t,i=>f(o,i)),{activity:"boot"}));await w(t,{customType:v,content:d("bearings",{},e),details:{nodeId:t}})}r(F,"deliverBearingsLive");export{F as deliverBearingsLive,w as deliverCustomMessageLive};
1
+ var a=Object.defineProperty;var r=(e,t)=>a(e,"name",{value:t,configurable:!0});import{getNode as n}from"../canvas/index.js";import{withCanvasWrite as m}from"../canvas/db.js";import{readerForNode as s}from"../graph/reader.js";import{noteNodeBooting as c}from"../graph/repo-sync/index.js";import{checkoutsForCwd as f}from"../graph/repo-sync/repos.js";import{deliver as l}from"../substrate/delivery/deliver.js";import{oneShotControllerRequest as u}from"./broker-request.js";import{isBrokerLive as p}from"./model-swap.js";import{CONTEXT_INTRO_CUSTOM_TYPE as v}from"./bearings.js";import{formatCard as d}from"../../shared/generated-context.js";async function w(e,t){const o=await n(e);if(o===null)throw new Error(`deliverCustomMessageLive: unknown node ${e}`);p(o)&&await u({nodeId:e,what:`the ${t.customType} delivery`,ackFor:"deliver_custom_message",frame:r(()=>({type:"deliver_custom_message",customType:t.customType,content:t.content,...t.deliverAs!==void 0?{deliverAs:t.deliverAs}:{},...t.details!==void 0?{details:t.details}:{}}),"frame"),result:r(()=>{},"result")})}r(w,"deliverCustomMessageLive");async function F(e){await c(e);const{content:t}=await m(async o=>await l(o,await s(o,e,async i=>await f(o,i)),{activity:"boot"}));await w(e,{customType:v,content:d("bearings",{},t),details:{nodeId:e}})}r(F,"deliverBearingsLive");export{F as deliverBearingsLive,w as deliverCustomMessageLive};
@@ -85,10 +85,10 @@ export interface FleetRegistry {
85
85
  * Removes the entry (freeing the capacity slot), then enqueues its
86
86
  * observation on the daemon's serial work lane — it never runs inline on
87
87
  * the Node event callback (design D-3). */
88
- onChildExit(nodeId: string, status: FleetExitStatus, executionId?: string): void;
88
+ onChildExit(nodeId: string, status: FleetExitStatus, executionId?: string): Promise<void>;
89
89
  /** Test seam — delivers a synthetic exit through the SAME path as
90
90
  * onChildExit, so fabricated-row tests drive policy without a process. */
91
- deliverExit(nodeId: string, status: FleetExitStatus): void;
91
+ deliverExit(nodeId: string, status: FleetExitStatus): Promise<void>;
92
92
  /** The node-lifecycle tick's enactment entry: classify a row known to have no
93
93
  * live engine and enact through the SAME policy table exit events use, so
94
94
  * tick recovery and exit recovery can never diverge. */
@@ -39,18 +39,18 @@ export interface Host {
39
39
  /** Is this node's engine alive? PURE / non-mutating. `string | NodeRow` so
40
40
  * both call sites — the revive guard (passes the id) and the daemon (passes a
41
41
  * row) — share one selector. For the broker this IS isPidAlive(pi_pid). */
42
- isAlive(node: string | NodeRow): boolean;
42
+ isAlive(node: string | NodeRow): Promise<boolean>;
43
43
  /** Tear the engine down (close/cancel teardown). Resolves only after the
44
44
  * fixed process snapshot is confirmed dead, or with a diagnostic failure. */
45
45
  teardown(nodeId: string, opts?: TeardownOptions): Promise<TeardownResult>;
46
46
  /** Deliver an OS signal to the engine container — present so the daemon never
47
47
  * reaches around the abstraction. */
48
- signal(nodeId: string, sig: NodeJS.Signals): void;
48
+ signal(nodeId: string, sig: NodeJS.Signals): Promise<void>;
49
49
  }
50
50
  /** Validate the broker launch recipe before we detach a child process. This is
51
51
  * the fast-fail seam for known module/path errors: a bad engine resolve or a
52
52
  * missing plain session path throws here, before spawn(). */
53
- export declare function preflightBrokerLaunch(nodeId: string, inv: PiInvocation, cwd: string): void;
53
+ export declare function preflightBrokerLaunch(nodeId: string, inv: PiInvocation, cwd: string): Promise<void>;
54
54
  /** Queue broker teardown after the close response settles. Completion includes
55
55
  * any post-teardown work, which lets the daemon drain it during shutdown. */
56
56
  export declare function requestBrokerTeardown(nodeId: string, opts?: TeardownOptions, after?: () => Promise<void>): Promise<TeardownResult>;
@@ -1,3 +1,3 @@
1
- var ye=Object.defineProperty;var u=(e,t)=>ye(e,"name",{value:t,configurable:!0});import{assertGranteeRunsHere as Pe}from"./unsandboxed.js";import{spawn as Re}from"node:child_process";import{mkdirSync as ue,existsSync as j,unlinkSync as fe,openSync as F,closeSync as N,writeSync as xe,chmodSync as Oe,lstatSync as Te}from"node:fs";import{ensureAppSpace as De}from"../spaces/space.js";import{sandboxCacheEnv as Ne}from"../spaces/cache-env.js";import{compileLaunch as Ce,launchStillGranted as Ae}from"../spaces/mounts.js";import{grantsGeneration as de}from"../grants/mirror.js";import{LAUNCHER_SOCKET as z}from"../../launcher/spec.js";import{launcherRequest as M}from"../../launcher/client.js";import{piAgentDir as Le}from"./package-health.js";import{existsBeneath as V,readFileBeneath as Be,readTextBeneathIfExists as $e,setModeBeneath as P,withDirBeneath as X,writeFileBeneath as G}from"../spaces/open-beneath.js";import{dirname as Q,join as h,resolve as je,isAbsolute as Fe}from"node:path";import{fileURLToPath as me}from"node:url";import{connectViewSocket as Me}from"./view-socket.js";import{appSpace as K}from"../layout.js";import{readConfig as Ge,readMergedLaunchConfig as Ke}from"../config.js";import{readRotationConfig as He}from"../subscription-state.js";import{getNode as v}from"../canvas/index.js";import{scopesFilePath as Y,crtrHome as pe,nodeRunDir as Z,nodeRunJobDir as Je,jobDir as qe,viewSocketPath as Ue,nodeAgentDir as We,contextDir as ze,nodeHome as Ve}from"../canvas/paths.js";import{encodeFrame as Xe}from"./broker-protocol.js";import{buildBrokerEnv as Qe}from"./spawn-env.js";import{hostExecPathFresh as Ye}from"./branded-host.js";import{isPidAlive as I,killProcessTreePids as he,isAnyPidAlive as Ze,captureTeardownSnapshot as Ie}from"../canvas/pid.js";import{assertMandatoryCanvasExtensions as er}from"./canvas-extensions.js";import{appMemoryFull as rr,appMemoryTooSmall as tr,boundFleet as nr,brokerCapReached as or,brokerThresholdsForDaemon as ir}from"./fleet.js";import{admitBrokerMemory as sr}from"./memory-admission.js";import{emitEvent as g}from"../events/emit.js";import{bindBrokerEventSource as ar,eventSource as cr}from"../events/source.js";import{envBrokerEngine as lr}from"../../shared/env.js";import{conversationIdFromPath as ur,conversationStore as fr,ConversationNotFoundError as we,storeAddress as dr}from"../conversation-store/index.js";import{takeNodeToken as mr}from"../canvas/node-tokens.js";function H(){const e=Q(me(import.meta.url));return h(e,"broker-cli.js")}u(H,"resolveBrokerEntry");const pr="@earendil-works/pi-coding-agent";function hr(e,t){const n=h(Le(),"models.json"),r=h(t,"models.json"),o=$e(Q(n),n);if(o===null)return;const f=JSON.parse(o),a=u(i=>Array.isArray(i)?i.map(a):i===null||typeof i!="object"?i:Object.fromEntries(Object.entries(i).filter(([s])=>!/^(apiKey|authorization|headers|token|secret)$/i.test(s)).map(([s,_])=>[s,a(_)])),"scrub"),l=`${JSON.stringify(a(f),null,2)}
2
- `;if(n===r&&o!==l){if(JSON.stringify(f)!==JSON.stringify(a(f)))throw new Error("terminal models.json contains credentials; move them into daemon secrets");P(e,r,432);return}G(e,r,l,{atomic:!0,mode:432}),P(e,r,432)}u(hr,"writeBrokerModels");function ge(e){return e.env.CRTR_BROKER_ENGINE??lr()}u(ge,"resolveEngineSpec");function Ee(e){return e.includes("/")||e.endsWith(".jsonl")}u(Ee,"isPlainLaunchSessionPath");function wr(e,t){return Fe(e)?e:je(t,e)}u(wr,"resolvePlainLaunchPath");function gr(e,t,n,r){if(n==="--session"&&!Ee(r))throw new Error(`[broker] refusing to launch ${e}: launch recipe passes bare --session id '${r}' \u2014 the broker fatally rejects bare ids; pass the .jsonl path instead.`);if(!Ee(r))return;const o=wr(r,t),f=ur(o);try{if(f===null)throw new we(o);fr().header(f)}catch(a){if(!(a instanceof we))throw a;const l=n==="--session"?"session file":"fork source";throw new Error(`[broker] refusing to launch ${e}: launch recipe references missing ${l} '${r}' (${o})`)}}u(gr,"preflightLaunchSessionArg");function Er(e,t,n){const r=Z(e);ue(r,{recursive:!0}),process.platform==="linux"&&j(z)&&Te(r).uid===process.getuid()&&Oe(r,504);const o=h(r,"broker-launch.json"),f={user:Ge("user"),launch:Ke(n,t.env.CRTR_PROFILE_ID||null),rotation:He()};G(r,o,JSON.stringify({...t,configSnapshot:f}),{atomic:!0}),t.env.CRTR_SCOPES_FILE!==void 0&&G(r,Y(e),JSON.stringify(v(e)?.scopes??[]),{atomic:!0});const a=Be(r,o).toString("utf8"),l=JSON.parse(a);if(!Array.isArray(l.argv))throw new Error(`[broker] refusing to launch ${e}: broker-launch.json is missing the argv array`);const i=ge(t);try{const d=import.meta.resolve(i);if(d.startsWith("file:")&&!j(me(d)))throw new Error(`resolved to missing file ${d}`)}catch(d){throw new Error(`[broker] refusing to launch ${e}: cannot resolve broker engine '${i}' from ${H()} \u2014 ${d.message}`)}const s=l.argv,_=[];for(let d=0;d<s.length;d++){const R=s[d];if(R==="-e"){const C=s[++d];C!==void 0&&_.push(C);continue}if(R!=="--session"&&R!=="--fork")continue;const O=s[++d];O!==void 0&&gr(e,n,R,O)}try{er(_)}catch(d){throw new Error(`[broker] refusing to launch ${e}: ${d.message}`)}}u(Er,"preflightBrokerLaunch");const kr=2e3,vr=2e3,_r=150;async function J(e,t){const n=Date.now()+t;for(;Ze(e);){const r=n-Date.now();if(r<=0)return!1;await new Promise(o=>setTimeout(o,Math.min(_r,r)))}return!0}u(J,"waitForTreeExit");async function Sr(e,t,n){return e.length===0?{confirmed:!0}:n&&await J(e,kr)?{confirmed:!0}:(he(e,"SIGTERM",t),await J(e,vr)?{confirmed:!0}:(he(e,"SIGKILL",t),await J(e,5e3)?{confirmed:!0}:{confirmed:!1,error:new Error(`broker process tree for ${e.join(", ")} remained alive after SIGKILL`)}))}u(Sr,"terminateBrokerTree");function ke(e,t){const n=v(e),r=n?.pi_pid,o=r!=null?Ie(r,n?.pi_pid_identity??null,t.excludePid):null;return o?.reused===!0&&g({level:"warn",event:"broker.teardown.pid_reuse_refused",node_id:e,fields:{recorded_pid:r,expected_identity:n?.pi_pid_identity??null}}),{tree:o?.tree??[],identities:o?.identities??null,nodeId:e,launcherPid:j(z)&&o?.tree.includes(r)?r:null}}u(ke,"prepareBrokerTeardown");async function ve(e){if(e.launcherPid!==null){try{await M({operation:"stop",pid:e.launcherPid})}catch(t){return I(e.launcherPid)?{confirmed:!1,error:t instanceof Error?t:new Error(String(t))}:{confirmed:!0}}return await J([e.launcherPid],5e3)?{confirmed:!0}:{confirmed:!1,error:new Error(`launcher pid ${e.launcherPid} remained alive`)}}return new Promise(t=>{let n=!1,r=!1;const o=u(i=>{r||(r=!0,t(i))},"settle"),f=u(()=>{try{fe(Ue(e.nodeId))}catch{}},"cleanupSocket"),a=u(i=>{Sr(e.tree,e.identities,i).then(o,s=>o({confirmed:!1,error:s instanceof Error?s:new Error(String(s))}))},"finish"),l=Me(e.nodeId);l.once("error",()=>{n||(f(),a(!1))}),l.once("connect",()=>{n=!0;try{l.write(Xe({type:"shutdown"}))}catch{}l.end(),f(),a(!0)})})}u(ve,"runPreparedBrokerTeardown");const q=new Map;function rt(e,t={},n){const r=q.get(e);if(r!==void 0)return n!==void 0&&r.after.push(n),r.completion;let o;const f=new Promise(i=>{o=i}),a={completion:f,resolve:o,after:n===void 0?[]:[n]};q.set(e,a);let l;try{l=ke(e,t)}catch(i){const s={confirmed:!1,error:i instanceof Error?i:new Error(String(i))};return q.delete(e),g({level:"error",event:"broker.teardown.unconfirmed",node_id:e,error:s.error}),a.resolve(s),f}return setImmediate(()=>{q.delete(e),ve(l).then(async i=>{if(i.confirmed)for(const s of a.after)try{await s()}catch(_){g({level:"error",event:"broker.teardown.after_failed",node_id:e,error:_})}else g({level:"error",event:"broker.teardown.unconfirmed",node_id:e,error:i.error});a.resolve(i)},i=>{const s={confirmed:!1,error:i instanceof Error?i:new Error(String(i))};g({level:"error",event:"broker.teardown.unconfirmed",node_id:e,error:s.error}),a.resolve(s)})}),f}u(rt,"requestBrokerTeardown");function _e(){return process.platform==="linux"&&j(z)}u(_e,"isolatedBrokerLauncherAvailable");const tt={async launch(e,t,n){if(Pe(v(e)?.grantee),v(e)?.isolated===!0&&!_e())throw new Error("isolated broker requires the Linux root launcher");Er(e,t,n.cwd);const r=nr();if(!r.reserveSlot(e))throw or(ir().automaticReviveCap,r.size());let o=null,f,a=!1;try{const l=qe(e);ue(l,{recursive:!0}),o=F(h(l,"broker.log"),"a");const i=ge(t),s={...Qe(t),CRTR_BROKER_ENGINE:i,CRTR_STORE_ADDRESS:dr()};if(i!==pr){const c=t.env.NODE_OPTIONS??process.env.NODE_OPTIONS;c!==void 0&&(s.NODE_OPTIONS=c)}cr()===void 0&&ar(e);const _=v(e)?.run_id;if(_){const c=v(_);if(!c||c.deleting_at)throw new Error("run is deleting")}const d=t.env.CRTR_EXECUTION_ID;if(!d)throw new Error("broker launch has no execution id");const R=mr(d),O=_e();if(v(e)?.isolated===!0&&!O)throw new Error("isolated broker requires the Linux root launcher");if(process.platform==="linux"&&process.env.CRTR_LAUNCHER_SOCKET&&!O)throw new Error("root launcher socket is unavailable; refusing an unsandboxed broker");if(O){const c=v(e);if(!c)throw new Error(`missing node ${e}`);const p=c.grantee??"app:terminal",x=await sr(e,{useMemo:!1});if(x.verdict==="denied")throw rr(x);if(x.verdict==="too_small")throw tr(x);const S=await De(p);Object.assign(s,Ne(p));const b={uid:process.getuid(),gid:S.gid},w=Z(e);for(const[m,E]of[[K(p).nodes,We(e,p)],[K(p).nodes,ze(e,p)],[w,Je(e)]])X(m,E,()=>{},!0),P(m,E,1528,b);P(w,h(w,"broker-launch.json"),416,b),V(w,Y(e))&&P(w,Y(e),416,b);const te=h(w,"system-prompt.md");V(w,te)&&P(w,te,432,b);for(const m of["output-schema.json","situational-context.md"]){const E=h(w,m);V(w,E)&&P(w,E,432,b)}const ne=c.isolated===!0,y=Ve(e,p,ne);ne&&(X(K(p).nodes,y,()=>{},!0),P(K(p).nodes,y,1528,b),s.HOME=y,s.PI_CODING_AGENT_DIR=h(y,".pi","agent"));const W=h(y,".pi","agent");X(y,W,()=>{},!0),hr(y,W);const oe=h(W,"settings.json"),Se=h(Q(H()),"../../builtin-pi-packages/pi-crtr-extensions");G(y,oe,`${JSON.stringify({packages:[Se]})}
3
- `,{atomic:!0,mode:432}),P(y,oe,432);const ie=h(Z(e),`token-${d}`),L=F(ie,"wx+",384);fe(ie),xe(L,R);const se=[F(`/proc/self/fd/${L}`,"r"),F(`/proc/self/fd/${L}`,"r")];N(L);const ae={nodeId:e,app:p,sub:c.sub??"user:local",grantId:c.grant_id??null,scopes:c.scopes??null,isolated:c.isolated===!0,...c.isolated===!0?{cwd:c.cwd}:{},command:[process.execPath,H(),"--canvas-home",pe(),"--epoch",r.epoch(),e],env:Object.fromEntries(Object.entries({...s,...c.isolated===!0?{PWD:c.cwd}:{}}).filter(m=>m[1]!==void 0)),auditMissing:u(m=>g({level:"warn",event:"broker.mount.missing",node_id:e,fields:{source:m}}),"auditMissing")};try{let m;for(const D of se){const B=de(),k=Ce(ae);k.broker=!0;const $=await M({operation:"launch",spec:k},[D]);if(!("pid"in $))throw new Error("launcher did not return a pid");if(de()===B||Ae(ae,k)){m=$.pid;break}g({level:"info",event:"broker.launch.regranted",node_id:e,fields:{pid:$.pid}}),await M({operation:"stop",pid:$.pid,signal:"SIGKILL"}).catch(()=>{})}if(m===void 0)throw new Error("grant changed during every launch attempt");const E=m,be=Date.now(),ce=new Promise(D=>{const B=setInterval(()=>{I(E)||(clearInterval(B),M({operation:"exit.status",pid:E}).then(k=>"oomKilled"in k&&k.oomKilled,()=>!1).then(k=>{g({level:k?"warn":"info",event:"broker.exited",node_id:e,fields:{pid:E,uptime_ms:Date.now()-be,oom_killed:k}}),D({code:null,signal:null,...k?{oomKilled:!0}:{}})}))},250);B.unref()});N(o),o=null;const le={pid:E,exited:ce};return r.register(e,le),a=!0,ce.then(D=>r.onChildExit(e,D,d)),le}finally{for(const m of se)N(m)}}const C=await Ye(),T=Re(C,[H(),"--canvas-home",pe(),"--epoch",r.epoch(),e],{cwd:n.cwd,detached:!0,stdio:["ignore",o,o,"pipe"],env:s});f=T;const A=T.stdio[3];if(!A||!("end"in A))throw new Error("broker token pipe did not open");A.on("error",c=>g({event:"broker.token_pipe.failed",level:"error",node_id:e,error:c})),A.end(R),N(o),o=null;const ee=Date.now(),re=new Promise(c=>{let p=!1;const x=u(S=>{p||(p=!0,c(S))},"finish");T.once("exit",(S,b)=>{g({level:S===0?"info":"warn",event:"broker.exited",node_id:e,fields:{code:S,signal:b,uptime_ms:Date.now()-ee}}),x({code:S,signal:b})}),T.once("error",S=>{g({level:"error",event:"broker.launch.failed",node_id:e,error:S,fields:{uptime_ms:Date.now()-ee}}),x({code:null,signal:null})})});T.unref();const U={pid:T.pid??null,exited:re};return U.pid!==null&&(r.register(e,U),a=!0,re.then(c=>r.onChildExit(e,c,d))),U}catch(l){if(!a&&f?.pid!=null)try{f.kill("SIGTERM")}catch{}throw l}finally{a||r.releaseReservation(e),o!==null&&N(o)}},isAlive(e){return I((typeof e=="string"?v(e):e)?.pi_pid)},teardown(e,t={}){try{return ve(ke(e,t))}catch(n){return Promise.resolve({confirmed:!1,error:n instanceof Error?n:new Error(String(n))})}},signal(e,t){const n=v(e)?.pi_pid;if(n!=null)try{process.kill(n,t)}catch{}}};export{tt as headlessBrokerHost,_e as isolatedBrokerLauncherAvailable,Er as preflightBrokerLaunch,rt as requestBrokerTeardown};
1
+ var be=Object.defineProperty;var u=(e,t)=>be(e,"name",{value:t,configurable:!0});import{assertGranteeRunsHere as Pe}from"./unsandboxed.js";import{spawn as Re}from"node:child_process";import{mkdirSync as ue,existsSync as j,unlinkSync as fe,openSync as F,closeSync as N,writeSync as xe,chmodSync as Oe,lstatSync as Te}from"node:fs";import{ensureAppSpace as De}from"../spaces/space.js";import{sandboxCacheEnv as Ne}from"../spaces/cache-env.js";import{compileLaunch as Ce,launchStillGranted as Ae}from"../spaces/mounts.js";import{grantsGeneration as de}from"../grants/mirror.js";import{LAUNCHER_SOCKET as z}from"../../launcher/spec.js";import{launcherRequest as M}from"../../launcher/client.js";import{piAgentDir as Le}from"./package-health.js";import{existsBeneath as V,readFileBeneath as Be,readTextBeneathIfExists as $e,setModeBeneath as P,withDirBeneath as X,writeFileBeneath as G}from"../spaces/open-beneath.js";import{dirname as Q,join as h,resolve as je,isAbsolute as Fe}from"node:path";import{fileURLToPath as me}from"node:url";import{connectViewSocket as Me}from"./view-socket.js";import{appSpace as K}from"../layout.js";import{readConfig as Ge,readMergedLaunchConfig as Ke}from"../config.js";import{readRotationConfig as He}from"../subscription-state.js";import{getNode as v}from"../canvas/index.js";import{scopesFilePath as Y,crtrHome as pe,nodeRunDir as Z,nodeRunJobDir as Je,jobDir as qe,viewSocketPath as Ue,nodeAgentDir as We,contextDir as ze,nodeHome as Ve}from"../canvas/paths.js";import{encodeFrame as Xe}from"./broker-protocol.js";import{buildBrokerEnv as Qe}from"./spawn-env.js";import{hostExecPathFresh as Ye}from"./branded-host.js";import{isPidAlive as I,killProcessTreePids as he,isAnyPidAlive as Ze,captureTeardownSnapshot as Ie}from"../canvas/pid.js";import{assertMandatoryCanvasExtensions as er}from"./canvas-extensions.js";import{appMemoryFull as rr,appMemoryTooSmall as tr,boundFleet as nr,brokerCapReached as or,brokerThresholdsForDaemon as ir}from"./fleet.js";import{admitBrokerMemory as sr}from"./memory-admission.js";import{emitEvent as g}from"../events/emit.js";import{bindBrokerEventSource as ar,eventSource as cr}from"../events/source.js";import{envBrokerEngine as lr}from"../../shared/env.js";import{conversationIdFromPath as ur,conversationStore as fr,ConversationNotFoundError as we,storeAddress as dr}from"../conversation-store/index.js";import{takeNodeToken as mr}from"../canvas/node-tokens.js";function H(){const e=Q(me(import.meta.url));return h(e,"broker-cli.js")}u(H,"resolveBrokerEntry");const pr="@earendil-works/pi-coding-agent";function hr(e,t){const n=h(Le(),"models.json"),r=h(t,"models.json"),o=$e(Q(n),n);if(o===null)return;const f=JSON.parse(o),a=u(i=>Array.isArray(i)?i.map(a):i===null||typeof i!="object"?i:Object.fromEntries(Object.entries(i).filter(([s])=>!/^(apiKey|authorization|headers|token|secret)$/i.test(s)).map(([s,_])=>[s,a(_)])),"scrub"),l=`${JSON.stringify(a(f),null,2)}
2
+ `;if(n===r&&o!==l){if(JSON.stringify(f)!==JSON.stringify(a(f)))throw new Error("terminal models.json contains credentials; move them into daemon secrets");P(e,r,432);return}G(e,r,l,{atomic:!0,mode:432}),P(e,r,432)}u(hr,"writeBrokerModels");function ge(e){return e.env.CRTR_BROKER_ENGINE??lr()}u(ge,"resolveEngineSpec");function Ee(e){return e.includes("/")||e.endsWith(".jsonl")}u(Ee,"isPlainLaunchSessionPath");function wr(e,t){return Fe(e)?e:je(t,e)}u(wr,"resolvePlainLaunchPath");async function gr(e,t,n,r){if(n==="--session"&&!Ee(r))throw new Error(`[broker] refusing to launch ${e}: launch recipe passes bare --session id '${r}' \u2014 the broker fatally rejects bare ids; pass the .jsonl path instead.`);if(!Ee(r))return;const o=wr(r,t),f=ur(o);try{if(f===null)throw new we(o);await fr().header(f)}catch(a){if(!(a instanceof we))throw a;const l=n==="--session"?"session file":"fork source";throw new Error(`[broker] refusing to launch ${e}: launch recipe references missing ${l} '${r}' (${o})`)}}u(gr,"preflightLaunchSessionArg");async function Er(e,t,n){const r=Z(e);ue(r,{recursive:!0}),process.platform==="linux"&&j(z)&&Te(r).uid===process.getuid()&&Oe(r,504);const o=h(r,"broker-launch.json"),f={user:Ge("user"),launch:Ke(n,t.env.CRTR_PROFILE_ID||null),rotation:He()};G(r,o,JSON.stringify({...t,configSnapshot:f}),{atomic:!0}),t.env.CRTR_SCOPES_FILE!==void 0&&G(r,Y(e),JSON.stringify((await v(e))?.scopes??[]),{atomic:!0});const a=Be(r,o).toString("utf8"),l=JSON.parse(a);if(!Array.isArray(l.argv))throw new Error(`[broker] refusing to launch ${e}: broker-launch.json is missing the argv array`);const i=ge(t);try{const d=import.meta.resolve(i);if(d.startsWith("file:")&&!j(me(d)))throw new Error(`resolved to missing file ${d}`)}catch(d){throw new Error(`[broker] refusing to launch ${e}: cannot resolve broker engine '${i}' from ${H()} \u2014 ${d.message}`)}const s=l.argv,_=[];for(let d=0;d<s.length;d++){const R=s[d];if(R==="-e"){const C=s[++d];C!==void 0&&_.push(C);continue}if(R!=="--session"&&R!=="--fork")continue;const O=s[++d];O!==void 0&&await gr(e,n,R,O)}try{er(_)}catch(d){throw new Error(`[broker] refusing to launch ${e}: ${d.message}`)}}u(Er,"preflightBrokerLaunch");const kr=2e3,vr=2e3,_r=150;async function J(e,t){const n=Date.now()+t;for(;Ze(e);){const r=n-Date.now();if(r<=0)return!1;await new Promise(o=>setTimeout(o,Math.min(_r,r)))}return!0}u(J,"waitForTreeExit");async function yr(e,t,n){return e.length===0?{confirmed:!0}:n&&await J(e,kr)?{confirmed:!0}:(he(e,"SIGTERM",t),await J(e,vr)?{confirmed:!0}:(he(e,"SIGKILL",t),await J(e,5e3)?{confirmed:!0}:{confirmed:!1,error:new Error(`broker process tree for ${e.join(", ")} remained alive after SIGKILL`)}))}u(yr,"terminateBrokerTree");async function ke(e,t){const n=await v(e),r=n?.pi_pid,o=r!=null?Ie(r,n?.pi_pid_identity??null,t.excludePid):null;return o?.reused===!0&&g({level:"warn",event:"broker.teardown.pid_reuse_refused",node_id:e,fields:{recorded_pid:r,expected_identity:n?.pi_pid_identity??null}}),{tree:o?.tree??[],identities:o?.identities??null,nodeId:e,launcherPid:j(z)&&o?.tree.includes(r)?r:null}}u(ke,"prepareBrokerTeardown");async function ve(e){if(e.launcherPid!==null){try{await M({operation:"stop",pid:e.launcherPid})}catch(t){return I(e.launcherPid)?{confirmed:!1,error:t instanceof Error?t:new Error(String(t))}:{confirmed:!0}}return await J([e.launcherPid],5e3)?{confirmed:!0}:{confirmed:!1,error:new Error(`launcher pid ${e.launcherPid} remained alive`)}}return new Promise(t=>{let n=!1,r=!1;const o=u(i=>{r||(r=!0,t(i))},"settle"),f=u(()=>{try{fe(Ue(e.nodeId))}catch{}},"cleanupSocket"),a=u(i=>{yr(e.tree,e.identities,i).then(o,s=>o({confirmed:!1,error:s instanceof Error?s:new Error(String(s))}))},"finish"),l=Me(e.nodeId);l.once("error",()=>{n||(f(),a(!1))}),l.once("connect",()=>{n=!0;try{l.write(Xe({type:"shutdown"}))}catch{}l.end(),f(),a(!0)})})}u(ve,"runPreparedBrokerTeardown");const q=new Map;async function rt(e,t={},n){const r=q.get(e);if(r!==void 0)return n!==void 0&&r.after.push(n),r.completion;let o;const f=new Promise(i=>{o=i}),a={completion:f,resolve:o,after:n===void 0?[]:[n]};q.set(e,a);let l;try{l=await ke(e,t)}catch(i){const s={confirmed:!1,error:i instanceof Error?i:new Error(String(i))};return q.delete(e),g({level:"error",event:"broker.teardown.unconfirmed",node_id:e,error:s.error}),a.resolve(s),f}return setImmediate(()=>{q.delete(e),ve(l).then(async i=>{if(i.confirmed)for(const s of a.after)try{await s()}catch(_){g({level:"error",event:"broker.teardown.after_failed",node_id:e,error:_})}else g({level:"error",event:"broker.teardown.unconfirmed",node_id:e,error:i.error});a.resolve(i)},i=>{const s={confirmed:!1,error:i instanceof Error?i:new Error(String(i))};g({level:"error",event:"broker.teardown.unconfirmed",node_id:e,error:s.error}),a.resolve(s)})}),f}u(rt,"requestBrokerTeardown");function _e(){return process.platform==="linux"&&j(z)}u(_e,"isolatedBrokerLauncherAvailable");const tt={async launch(e,t,n){if(Pe((await v(e))?.grantee),(await v(e))?.isolated===!0&&!_e())throw new Error("isolated broker requires the Linux root launcher");await Er(e,t,n.cwd);const r=nr();if(!r.reserveSlot(e))throw or(ir().automaticReviveCap,r.size());let o=null,f,a=!1;try{const l=qe(e);ue(l,{recursive:!0}),o=F(h(l,"broker.log"),"a");const i=ge(t),s={...Qe(t),CRTR_BROKER_ENGINE:i,CRTR_STORE_ADDRESS:dr()};if(i!==pr){const c=t.env.NODE_OPTIONS??process.env.NODE_OPTIONS;c!==void 0&&(s.NODE_OPTIONS=c)}cr()===void 0&&ar(e);const _=(await v(e))?.run_id;if(_){const c=await v(_);if(!c||c.deleting_at)throw new Error("run is deleting")}const d=t.env.CRTR_EXECUTION_ID;if(!d)throw new Error("broker launch has no execution id");const R=mr(d),O=_e();if((await v(e))?.isolated===!0&&!O)throw new Error("isolated broker requires the Linux root launcher");if(process.platform==="linux"&&process.env.CRTR_LAUNCHER_SOCKET&&!O)throw new Error("root launcher socket is unavailable; refusing an unsandboxed broker");if(O){const c=await v(e);if(!c)throw new Error(`missing node ${e}`);const p=c.grantee??"app:terminal",x=await sr(e,{useMemo:!1});if(x.verdict==="denied")throw rr(x);if(x.verdict==="too_small")throw tr(x);const y=await De(p);Object.assign(s,Ne(p));const S={uid:process.getuid(),gid:y.gid},w=Z(e);for(const[m,E]of[[K(p).nodes,We(e,p)],[K(p).nodes,ze(e,p)],[w,Je(e)]])X(m,E,()=>{},!0),P(m,E,1528,S);P(w,h(w,"broker-launch.json"),416,S),V(w,Y(e))&&P(w,Y(e),416,S);const te=h(w,"system-prompt.md");V(w,te)&&P(w,te,432,S);for(const m of["output-schema.json","situational-context.md"]){const E=h(w,m);V(w,E)&&P(w,E,432,S)}const ne=c.isolated===!0,b=Ve(e,p,ne);ne&&(X(K(p).nodes,b,()=>{},!0),P(K(p).nodes,b,1528,S),s.HOME=b,s.PI_CODING_AGENT_DIR=h(b,".pi","agent"));const W=h(b,".pi","agent");X(b,W,()=>{},!0),hr(b,W);const oe=h(W,"settings.json"),ye=h(Q(H()),"../../builtin-pi-packages/pi-crtr-extensions");G(b,oe,`${JSON.stringify({packages:[ye]})}
3
+ `,{atomic:!0,mode:432}),P(b,oe,432);const ie=h(Z(e),`token-${d}`),L=F(ie,"wx+",384);fe(ie),xe(L,R);const se=[F(`/proc/self/fd/${L}`,"r"),F(`/proc/self/fd/${L}`,"r")];N(L);const ae={nodeId:e,app:p,sub:c.sub??"user:local",grantId:c.grant_id??null,scopes:c.scopes??null,isolated:c.isolated===!0,...c.isolated===!0?{cwd:c.cwd}:{},command:[process.execPath,H(),"--canvas-home",pe(),"--epoch",r.epoch(),e],env:Object.fromEntries(Object.entries({...s,...c.isolated===!0?{PWD:c.cwd}:{}}).filter(m=>m[1]!==void 0)),auditMissing:u(m=>g({level:"warn",event:"broker.mount.missing",node_id:e,fields:{source:m}}),"auditMissing")};try{let m;for(const D of se){const B=await de(),k=await Ce(ae);k.broker=!0;const $=await M({operation:"launch",spec:k},[D]);if(!("pid"in $))throw new Error("launcher did not return a pid");if(await de()===B||await Ae(ae,k)){m=$.pid;break}g({level:"info",event:"broker.launch.regranted",node_id:e,fields:{pid:$.pid}}),await M({operation:"stop",pid:$.pid,signal:"SIGKILL"}).catch(()=>{})}if(m===void 0)throw new Error("grant changed during every launch attempt");const E=m,Se=Date.now(),ce=new Promise(D=>{const B=setInterval(()=>{I(E)||(clearInterval(B),M({operation:"exit.status",pid:E}).then(k=>"oomKilled"in k&&k.oomKilled,()=>!1).then(k=>{g({level:k?"warn":"info",event:"broker.exited",node_id:e,fields:{pid:E,uptime_ms:Date.now()-Se,oom_killed:k}}),D({code:null,signal:null,...k?{oomKilled:!0}:{}})}))},250);B.unref()});N(o),o=null;const le={pid:E,exited:ce};return r.register(e,le),a=!0,ce.then(async D=>await r.onChildExit(e,D,d)),le}finally{for(const m of se)N(m)}}const C=await Ye(),T=Re(C,[H(),"--canvas-home",pe(),"--epoch",r.epoch(),e],{cwd:n.cwd,detached:!0,stdio:["ignore",o,o,"pipe"],env:s});f=T;const A=T.stdio[3];if(!A||!("end"in A))throw new Error("broker token pipe did not open");A.on("error",c=>g({event:"broker.token_pipe.failed",level:"error",node_id:e,error:c})),A.end(R),N(o),o=null;const ee=Date.now(),re=new Promise(c=>{let p=!1;const x=u(y=>{p||(p=!0,c(y))},"finish");T.once("exit",(y,S)=>{g({level:y===0?"info":"warn",event:"broker.exited",node_id:e,fields:{code:y,signal:S,uptime_ms:Date.now()-ee}}),x({code:y,signal:S})}),T.once("error",y=>{g({level:"error",event:"broker.launch.failed",node_id:e,error:y,fields:{uptime_ms:Date.now()-ee}}),x({code:null,signal:null})})});T.unref();const U={pid:T.pid??null,exited:re};return U.pid!==null&&(r.register(e,U),a=!0,re.then(async c=>await r.onChildExit(e,c,d))),U}catch(l){if(!a&&f?.pid!=null)try{f.kill("SIGTERM")}catch{}throw l}finally{a||r.releaseReservation(e),o!==null&&N(o)}},async isAlive(e){return I((typeof e=="string"?await v(e):e)?.pi_pid)},async teardown(e,t={}){try{return ve(await ke(e,t))}catch(n){return Promise.resolve({confirmed:!1,error:n instanceof Error?n:new Error(String(n))})}},async signal(e,t){const n=(await v(e))?.pi_pid;if(n!=null)try{process.kill(n,t)}catch{}}};export{tt as headlessBrokerHost,_e as isolatedBrokerLauncherAvailable,Er as preflightBrokerLaunch,rt as requestBrokerTeardown};
@@ -5,30 +5,30 @@ import { type WakeOrigin } from './bearings.js';
5
5
  export declare const RUNTIME_RESTART_CONTINUATION: string;
6
6
  /** The goal file — the prompt/task a node was spawned with, persisted at birth
7
7
  * so a fresh revive can re-read its mandate. */
8
- export declare function goalPath(nodeId: string): string;
9
- export declare function readGoal(nodeId: string): string | null;
8
+ export declare function goalPath(nodeId: string): Promise<string>;
9
+ export declare function readGoal(nodeId: string): Promise<string | null>;
10
10
  /** Persist the spawning prompt as the node's goal. No-op for an empty prompt
11
11
  * (e.g. a bare root). Idempotent enough — call once at spawn/boot. */
12
- export declare function writeGoal(nodeId: string, text: string): void;
12
+ export declare function writeGoal(nodeId: string, text: string): Promise<void>;
13
13
  /** Write the goal ONLY if the node has none yet. This is how a bare root (no
14
14
  * spawn prompt) acquires its mandate: the first real user message becomes the
15
15
  * goal. Returns true when it wrote one, false when a goal already existed or
16
16
  * the text was empty. Guarded so a later message never clobbers the mandate. */
17
- export declare function captureGoalIfAbsent(nodeId: string, text: string): boolean;
17
+ export declare function captureGoalIfAbsent(nodeId: string, text: string): Promise<boolean>;
18
18
  /** The yield-message file — a short note `crtr node yield` records for the next
19
19
  * fresh/cycling revive ("on wake, do X"). It remains durable through failed
20
20
  * launch attempts and is cleared only when session_start confirms a boot. */
21
- export declare function yieldMessagePath(nodeId: string): string;
22
- export declare function writeYieldMessage(nodeId: string, text: string): void;
21
+ export declare function yieldMessagePath(nodeId: string): Promise<string>;
22
+ export declare function writeYieldMessage(nodeId: string, text: string): Promise<void>;
23
23
  /** Read the pending yield message without mutating its confirmation state. */
24
- export declare function readYieldMessage(nodeId: string): string | null;
24
+ export declare function readYieldMessage(nodeId: string): Promise<string | null>;
25
25
  /** Idempotently commit delivery of the yield message after a confirmed boot. */
26
- export declare function clearYieldMessage(nodeId: string): void;
26
+ export declare function clearYieldMessage(nodeId: string): Promise<void>;
27
27
  /** List the node's context/ dir (filenames, sorted). Empty when absent. */
28
- export declare function listContextDir(nodeId: string): string[];
28
+ export declare function listContextDir(nodeId: string): Promise<string[]>;
29
29
  /** A retained report proves this node has already done work. It must restart
30
30
  * from current context, never by replaying its birth mandate. */
31
- export declare function hasRetainedReports(nodeId: string): boolean;
31
+ export declare function hasRetainedReports(nodeId: string): Promise<boolean>;
32
32
  export interface ReviveBearings {
33
33
  /** The one-shot yield note left by the prior self, pending boot confirmation. */
34
34
  yieldMsg: string | null;
@@ -40,10 +40,10 @@ export interface ReviveBearings {
40
40
  driftGuidance: string | null;
41
41
  }
42
42
  /** Claim wake mail for this launch without acknowledging it before a turn. */
43
- export declare function drainBearings(meta: NodeMeta, executionId: string): ReviveBearings;
43
+ export declare function drainBearings(meta: NodeMeta, executionId: string): Promise<ReviveBearings>;
44
44
  /** Assemble the auto-injected first message for a FRESH revive of `meta` from its
45
45
  * already-drained `bearings` (see drainBearings) plus pure on-disk reads of the
46
46
  * node's goal, roadmap, and context dir, framed so the revived node can rebuild
47
47
  * its bearings in one turn. PURE: no state mutation, so calling it twice yields
48
48
  * the same string and consumes nothing — drainBearings owns the one-shot reads. */
49
- export declare function buildReviveKickoff(meta: NodeMeta, bearings: ReviveBearings, wakeReason?: WakeOrigin): string;
49
+ export declare function buildReviveKickoff(meta: NodeMeta, bearings: ReviveBearings, wakeReason?: WakeOrigin): Promise<string>;
@@ -1,28 +1,28 @@
1
- var B=Object.defineProperty;var i=(t,e)=>B(t,"name",{value:e,configurable:!0});import{join as w}from"node:path";import{getNode as M,subscriptionsOf as R,subscribersOf as N}from"../canvas/index.js";import{contextDir as h,nodeAgentDir as l}from"../canvas/node-agent-paths.js";import{hasReportDocuments as A}from"../feed/reports.js";import{readdirBeneath as E,readTextBeneathIfExists as x,unlinkBeneath as T,writeFileBeneath as $}from"../spaces/open-beneath.js";import{activeBackgroundBashJobs as D,bashJobCommandLine as I,formatBashElapsed as G}from"../bash-jobs.js";import{readRoadmap as O}from"./roadmap.js";import{buildWakeBearings as _}from"./bearings.js";import{personaDrift as Y}from"./persona.js";import{coalesce as C,nodeMailEntry as L}from"../feed/inbox.js";import{claimKickoffMail as U}from"../canvas/deliveries.js";import{formatCard as k}from"../../shared/generated-context.js";const ut=k("restart-continuation",{},"continue");function y(t){return w(h(t),"initial-prompt.md")}i(y,"goalPath");function j(t){return x(l(t),y(t))}i(j,"readGoal");function J(t,e){const n=e.trim();n!==""&&$(l(t),y(t),n+`
2
- `)}i(J,"writeGoal");function dt(t,e){const n=j(t);if(n!==null&&n.trim()!=="")return!1;const r=e.trim();return r===""?!1:(J(t,r),!0)}i(dt,"captureGoalIfAbsent");function b(t){return w(h(t),"yield-message.md")}i(b,"yieldMessagePath");function ct(t,e){const n=e.trim();n!==""&&$(l(t),b(t),n+`
3
- `)}i(ct,"writeYieldMessage");function P(t){const e=x(l(t),b(t))?.trim()??"";return e!==""?e:null}i(P,"readYieldMessage");function lt(t){try{T(l(t),b(t))}catch{}}i(lt,"clearYieldMessage");function F(t){return S(t,h(t)).sort()}i(F,"listContextDir");function K(t){return A(t)}i(K,"hasRetainedReports");function S(t,e){try{return E(l(t),e).map(n=>n.name)}catch(n){if(n.code==="ENOENT")return[];throw n}}i(S,"agentDirNames");function ft(t,e){const n=t.node_id,r=P(n),o=t.run_id?[]:U(n,e),s=o.map(a=>a.message.messageId),f=o.map(L);let u=null;if(f.length>0){const a=i(d=>{const m=d.data?.cards;return Array.isArray(m)?m.filter(v=>typeof v=="string"):[]},"cardsFor"),p=[];for(const d of f)(a(d).length>0||p.length===0)&&p.push([]),p.at(-1).push(d);u=p.map(d=>[...a(d[0]),C(d).map(m=>m.text).join(`
1
+ var M=Object.defineProperty;var r=(t,n)=>M(t,"name",{value:n,configurable:!0});import{join as b}from"node:path";import{getNode as R,subscriptionsOf as A,subscribersOf as N}from"../canvas/index.js";import{contextDir as h,nodeAgentDir as l}from"../canvas/node-agent-paths.js";import{hasReportDocuments as E}from"../feed/reports.js";import{readdirBeneath as T,readTextBeneathIfExists as x,unlinkBeneath as D,writeFileBeneath as $}from"../spaces/open-beneath.js";import{activeBackgroundBashJobs as I,bashJobCommandLine as G,formatBashElapsed as O}from"../bash-jobs.js";import{readRoadmap as _}from"./roadmap.js";import{buildWakeBearings as Y}from"./bearings.js";import{personaDrift as C}from"./persona.js";import{coalesce as L,nodeMailEntry as U}from"../feed/inbox.js";import{claimKickoffMail as J}from"../canvas/deliveries.js";import{formatCard as k}from"../../shared/generated-context.js";import{mapAsync as j}from"../async-array.js";const dt=k("restart-continuation",{},"continue");async function y(t){return b(await h(t),"initial-prompt.md")}r(y,"goalPath");async function v(t){return x(await l(t),await y(t))}r(v,"readGoal");async function P(t,n){const e=n.trim();e!==""&&$(await l(t),await y(t),e+`
2
+ `)}r(P,"writeGoal");async function lt(t,n){const e=await v(t);if(e!==null&&e.trim()!=="")return!1;const o=n.trim();return o===""?!1:(await P(t,o),!0)}r(lt,"captureGoalIfAbsent");async function g(t){return b(await h(t),"yield-message.md")}r(g,"yieldMessagePath");async function ft(t,n){const e=n.trim();e!==""&&$(await l(t),await g(t),e+`
3
+ `)}r(ft,"writeYieldMessage");async function F(t){const n=x(await l(t),await g(t))?.trim()??"";return n!==""?n:null}r(F,"readYieldMessage");async function ht(t){try{D(await l(t),await g(t))}catch{}}r(ht,"clearYieldMessage");async function K(t){return(await q(t,await h(t))).sort()}r(K,"listContextDir");async function S(t){return await E(t)}r(S,"hasRetainedReports");async function q(t,n){try{return T(await l(t),n).map(e=>e.name)}catch(e){if(e.code==="ENOENT")return[];throw e}}r(q,"agentDirNames");async function mt(t,n){const e=t.node_id,o=await F(e),a=t.run_id?[]:await J(e,n),i=a.map(s=>s.message.messageId),f=a.map(U);let u=null;if(f.length>0){const s=r(c=>{const p=c.data?.cards;return Array.isArray(p)?p.filter(B=>typeof B=="string"):[]},"cardsFor"),m=[];for(const c of f)(s(c).length>0||m.length===0)&&m.push([]),m.at(-1).push(c);u=(await j(m,async c=>[...s(c[0]),(await L(c)).map(p=>p.text).join(`
4
4
 
5
5
  `)].join(`
6
6
 
7
- `)).join(`
7
+ `))).join(`
8
8
 
9
- `)}const c=Y(n),g=c?.guidance===void 0||c.guidance===""?null:c.guidance;return{yieldMsg:r,unreadDigest:u,unreadMessageIds:s,driftGuidance:g}}i(ft,"drainBearings");function q(t,e){const n=R(t).filter(o=>o.active).map(o=>M(o.node_id)).filter(o=>o!==null&&(o.status==="active"||o.status==="idle")),r=[];if(n.length>0){const o=n.length,s=o===1?"it has":"they have",f=o===1?"Its":"Their";r.push(`Awaiting ${o} node${o===1?"":"s"} \u2014 ${s} not finished. ${f} reports will wake you.`);for(const u of n)r.push(` - ${u.name} (${u.node_id}) \u2014 ${u.status}`);r.push("",e??"(no unread reports)")}else r.push("Awaiting 0 nodes."),r.push("",e??"(no unread reports)");return`<feed>
10
- ${r.join(`
11
- `)}
12
- </feed>`}i(q,"feedBlock");function W(t,e){const n=(t??I(e)).trim()||"(no command)";return n.length>120?`${n.slice(0,117)}\u2026`:n}i(W,"jobLabel");function z(t){const e=D(h(t));if(e.length===0)return null;const n=Date.now(),r=e.length===1,o=[`${e.length} background bash job${r?"":"s"} you started ${r?"is":"are"} STILL RUNNING, detached from any turn and unaffected by your refresh. Each one sends you a message when it exits \u2014 that wake is automatic, so do not poll it and do not relaunch the same command.`];for(const s of e)o.push(` - ${s.jobId} \u2014 ${W(s.purpose,s.command)} \xB7 running ${G(n-s.startedAtMs)} \xB7 log ${s.logPath}`);return o.push("","Read output so far: `tail -n 50 <log>` (or `crtr node bash list --tail 20`). Abandon one: `crtr node bash kill <job-id>`."),`<background-jobs>
9
+ `)}const d=await C(e),w=d?.guidance===void 0||d.guidance===""?null:d.guidance;return{yieldMsg:o,unreadDigest:u,unreadMessageIds:i,driftGuidance:w}}r(mt,"drainBearings");async function W(t,n){const e=(await j((await A(t)).filter(a=>a.active),async a=>await R(a.node_id))).filter(a=>a!==null&&(a.status==="active"||a.status==="idle")),o=[];if(e.length>0){const a=e.length,i=a===1?"it has":"they have",f=a===1?"Its":"Their";o.push(`Awaiting ${a} node${a===1?"":"s"} \u2014 ${i} not finished. ${f} reports will wake you.`);for(const u of e)o.push(` - ${u.name} (${u.node_id}) \u2014 ${u.status}`);o.push("",n??"(no unread reports)")}else o.push("Awaiting 0 nodes."),o.push("",n??"(no unread reports)");return`<feed>
13
10
  ${o.join(`
14
11
  `)}
15
- </background-jobs>`}i(z,"backgroundJobsBlock");function ht(t,e,n){const r=t.node_id,o=["You have been revived fresh after a context refresh \u2014 your previous in-memory context is gone, by design. Everything below was just read from disk; it is your full bearings. Rebuild from it and continue toward your goal."];n!==void 0&&o.push(_(n));const s=O(r);if(!(s!==null&&s.trim()!=="")&&!K(r)){const a=j(r);a!==null&&a.trim()!==""&&o.push(`<goal file="${y(r)}">
16
- ${a.trim()}
17
- </goal>`)}const u=F(r).filter(a=>a!=="yield-message.md");o.push(`<context-dir path="${h(r)}">
12
+ </feed>`}r(W,"feedBlock");function z(t,n){const e=(t??G(n)).trim()||"(no command)";return e.length>120?`${e.slice(0,117)}\u2026`:e}r(z,"jobLabel");async function H(t){const n=I(await h(t));if(n.length===0)return null;const e=Date.now(),o=n.length===1,a=[`${n.length} background bash job${o?"":"s"} you started ${o?"is":"are"} STILL RUNNING, detached from any turn and unaffected by your refresh. Each one sends you a message when it exits \u2014 that wake is automatic, so do not poll it and do not relaunch the same command.`];for(const i of n)a.push(` - ${i.jobId} \u2014 ${z(i.purpose,i.command)} \xB7 running ${O(e-i.startedAtMs)} \xB7 log ${i.logPath}`);return a.push("","Read output so far: `tail -n 50 <log>` (or `crtr node bash list --tail 20`). Abandon one: `crtr node bash kill <job-id>`."),`<background-jobs>
13
+ ${a.join(`
14
+ `)}
15
+ </background-jobs>`}r(H,"backgroundJobsBlock");async function pt(t,n,e){const o=t.node_id,a=["You have been revived fresh after a context refresh \u2014 your previous in-memory context is gone, by design. Everything below was just read from disk; it is your full bearings. Rebuild from it and continue toward your goal."];e!==void 0&&a.push(Y(e));const i=await _(o);if(!(i!==null&&i.trim()!=="")&&!await S(o)){const s=await v(o);s!==null&&s.trim()!==""&&a.push(`<goal file="${await y(o)}">
16
+ ${s.trim()}
17
+ </goal>`)}const u=(await K(o)).filter(s=>s!=="yield-message.md");a.push(`<context-dir path="${await h(o)}">
18
18
  ${u.length>0?u.join(`
19
19
  `):"(empty)"}
20
- </context-dir>`);const c=z(r);c!==null&&o.push(c),o.push(q(r,e.unreadDigest)),o.push(e.yieldMsg!==null?`<yield-message>
21
- ${e.yieldMsg.trim()}
22
- </yield-message>`:"<yield-message/>");const g=N(r).length>0;return o.push(g?"If there is work to do, perform it. Otherwise stop \u2014 pipe the result to `crtr push final` through a single-quoted heredoc if the goal is met, or end your turn without a message to stay dormant awaiting your workers.":"If there is work to do, perform it. Otherwise end your turn without writing a message \u2014 the user already has your last reply, and a status recap would only bury it. You are working directly with the user, so stay available and continue when they write back."),e.driftGuidance!==null&&o.push(`<persona-transition>
23
- Your role was changed while you were away. ${e.driftGuidance}
20
+ </context-dir>`);const d=await H(o);d!==null&&a.push(d),a.push(await W(o,n.unreadDigest)),a.push(n.yieldMsg!==null?`<yield-message>
21
+ ${n.yieldMsg.trim()}
22
+ </yield-message>`:"<yield-message/>");const w=(await N(o)).length>0;return a.push(w?"If there is work to do, perform it. Otherwise stop \u2014 pipe the result to `crtr push final` through a single-quoted heredoc if the goal is met, or end your turn without a message to stay dormant awaiting your workers.":"If there is work to do, perform it. Otherwise end your turn without writing a message \u2014 the user already has your last reply, and a status recap would only bury it. You are working directly with the user, so stay available and continue when they write back."),n.driftGuidance!==null&&a.push(`<persona-transition>
23
+ Your role was changed while you were away. ${n.driftGuidance}
24
24
  </persona-transition>`),k("revive",{},`
25
- ${o.join(`
25
+ ${a.join(`
26
26
 
27
27
  `)}
28
- `)}i(ht,"buildReviveKickoff");export{ut as RUNTIME_RESTART_CONTINUATION,ht as buildReviveKickoff,dt as captureGoalIfAbsent,lt as clearYieldMessage,ft as drainBearings,y as goalPath,K as hasRetainedReports,F as listContextDir,j as readGoal,P as readYieldMessage,J as writeGoal,ct as writeYieldMessage,b as yieldMessagePath};
28
+ `)}r(pt,"buildReviveKickoff");export{dt as RUNTIME_RESTART_CONTINUATION,pt as buildReviveKickoff,lt as captureGoalIfAbsent,ht as clearYieldMessage,mt as drainBearings,y as goalPath,S as hasRetainedReports,K as listContextDir,v as readGoal,F as readYieldMessage,P as writeGoal,ft as writeYieldMessage,g as yieldMessagePath};
@@ -31,4 +31,4 @@ export declare function resolveLaunchTarget(req: CreateNodeRequest, options?: {
31
31
  validateKind?: (kind: string) => void | Promise<void>;
32
32
  }): Promise<ResolvedLaunchTarget>;
33
33
  /** The directory a new node is pinned to. */
34
- export declare function resolveNodeCwd(req: CreateNodeRequest, parent: string | undefined, _profileId: string | null, contextCwd: string): string;
34
+ export declare function resolveNodeCwd(req: CreateNodeRequest, parent: string | undefined, _profileId: string | null, contextCwd: string): Promise<string>;
@@ -1 +1 @@
1
- var u=Object.defineProperty;var i=(e,n)=>u(e,"name",{value:n,configurable:!0});import{appSpace as p}from"../layout.js";import{envProfileId as m}from"../../shared/env.js";import{resolve as s}from"node:path";import{getNode as w}from"../canvas/canvas.js";import{usage as v}from"../errors.js";import{assertProfileActive as h}from"../profiles/manifest.js";import{buildLaunchSpecAsync as _,readMergedLaunchConfigAsync as x}from"./launch.js";import{resolveProfileId as y}from"./spawn.js";function k(e,n){return e??n?.manifest.default_kind??"general"}i(k,"resolveCreateKind");const K="developer";function j(e){return e.manifest.default_kind??K}i(j,"resolveRunKind");const N=new Set(["human"]);function M(e){return!N.has(e)}i(M,"isLaunchKind");async function g(e,n=process.cwd(),r=m()||null){const t=Object.keys((await x(n,r)).kinds);if(!t.includes(e))throw v(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}i(g,"assertLaunchKind");async function R(e,n={}){const r=e.parent??void 0,t=e.cwd??process.cwd(),o=await y(e.profile,r??null,t,{readOnlySelection:n.readOnlyProfileSelection}),a=h(o),d=k(e.kind,a);await n.validateKind?.(d);const c=L({...e,kind:d},r,o,t);n.validateKind===void 0&&await g(d,c,o);const l=e.mode??"base",f=(await _(d,l,{lifecycle:e.root_lifecycle??(e.root===!0?"resident":"terminal"),hasManager:e.root!==!0,...e.model!==void 0?{model:e.model,modelOverride:!0}:{},cwd:c,profileId:o})).launch;return{profileId:o,profile:a,kind:d,mode:l,cwd:c,launch:f}}i(R,"resolveLaunchTarget");function L(e,n,r,t){if(e.pin_cwd!==void 0&&e.pin_cwd!=="")return s(e.pin_cwd);if(n!=null){const o=w(n);if(o!==null)return o.cwd}return e.cwd!==void 0&&e.cwd!==""?s(e.cwd):process.platform==="linux"?p("terminal").files:t}i(L,"resolveNodeCwd");export{K as RUN_DEFAULT_KIND,g as assertLaunchKind,M as isLaunchKind,k as resolveCreateKind,R as resolveLaunchTarget,L as resolveNodeCwd,j as resolveRunKind};
1
+ var u=Object.defineProperty;var i=(e,n)=>u(e,"name",{value:n,configurable:!0});import{appSpace as p}from"../layout.js";import{envProfileId as m}from"../../shared/env.js";import{resolve as s}from"node:path";import{getNode as w}from"../canvas/canvas.js";import{usage as v}from"../errors.js";import{assertProfileActive as h}from"../profiles/manifest.js";import{buildLaunchSpecAsync as _,readMergedLaunchConfigAsync as x}from"./launch.js";import{resolveProfileId as y}from"./spawn.js";function k(e,n){return e??n?.manifest.default_kind??"general"}i(k,"resolveCreateKind");const K="developer";function j(e){return e.manifest.default_kind??K}i(j,"resolveRunKind");const N=new Set(["human"]);function M(e){return!N.has(e)}i(M,"isLaunchKind");async function g(e,n=process.cwd(),r=m()||null){const t=Object.keys((await x(n,r)).kinds);if(!t.includes(e))throw v(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}i(g,"assertLaunchKind");async function R(e,n={}){const r=e.parent??void 0,t=e.cwd??process.cwd(),o=await y(e.profile,r??null,t,{readOnlySelection:n.readOnlyProfileSelection}),a=h(o),d=k(e.kind,a);await n.validateKind?.(d);const c=await L({...e,kind:d},r,o,t);n.validateKind===void 0&&await g(d,c,o);const l=e.mode??"base",f=(await _(d,l,{lifecycle:e.root_lifecycle??(e.root===!0?"resident":"terminal"),hasManager:e.root!==!0,...e.model!==void 0?{model:e.model,modelOverride:!0}:{},cwd:c,profileId:o})).launch;return{profileId:o,profile:a,kind:d,mode:l,cwd:c,launch:f}}i(R,"resolveLaunchTarget");async function L(e,n,r,t){if(e.pin_cwd!==void 0&&e.pin_cwd!=="")return s(e.pin_cwd);if(n!=null){const o=await w(n);if(o!==null)return o.cwd}return e.cwd!==void 0&&e.cwd!==""?s(e.cwd):process.platform==="linux"?p("terminal").files:t}i(L,"resolveNodeCwd");export{K as RUN_DEFAULT_KIND,g as assertLaunchKind,M as isLaunchKind,k as resolveCreateKind,R as resolveLaunchTarget,L as resolveNodeCwd,j as resolveRunKind};
@@ -1,10 +1,10 @@
1
1
  /** End the node's context session: its ledger holds nothing. */
2
- export declare function clearNodeLedger(nodeId: string): void;
2
+ export declare function clearNodeLedger(nodeId: string): Promise<void>;
3
3
  /** Seed a fork's ledger once with the transcript rows its source holds; no
4
4
  * source → empty. A fork already seeded (at spawn, or by an earlier birth
5
5
  * attempt) keeps its ledger, so a retry after the source is deleted loses nothing. */
6
- export declare function forkNodeLedger(forkId: string, sourceId: string | null): void;
6
+ export declare function forkNodeLedger(forkId: string, sourceId: string | null): Promise<void>;
7
7
  /** Queue one inbox entry for a node revived from done listing the watched
8
8
  * documents that got a newer revision (by someone else) since `since`.
9
9
  * Returns whether a notice was queued. */
10
- export declare function noticeChangedWhileDone(nodeId: string, since: string): boolean;
10
+ export declare function noticeChangedWhileDone(nodeId: string, since: string): Promise<boolean>;