@north-light/crouter 0.3.349 → 0.3.351

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 (629) hide show
  1. package/bin/crtr-launcher +4 -0
  2. package/bin/runtime-generation-manifest.mjs +12 -2
  3. package/dist/api/client.d.ts +50 -7
  4. package/dist/api/client.js +2 -2
  5. package/dist/api/dto/analytics.d.ts +184 -0
  6. package/dist/api/dto/analytics.js +0 -0
  7. package/dist/api/dto/broker-ops.d.ts +43 -1
  8. package/dist/api/dto/config.d.ts +11 -0
  9. package/dist/api/dto/grants.d.ts +14 -0
  10. package/dist/api/dto/grants.js +0 -0
  11. package/dist/api/dto/human-requests.d.ts +14 -0
  12. package/dist/api/dto/memory.d.ts +6 -0
  13. package/dist/api/dto/modelauth.d.ts +35 -0
  14. package/dist/api/dto/node-records.d.ts +35 -0
  15. package/dist/api/dto/node-records.js +0 -0
  16. package/dist/api/dto/nodes.d.ts +5 -0
  17. package/dist/api/dto/profiles.d.ts +38 -3
  18. package/dist/api/dto/worktree.d.ts +11 -0
  19. package/dist/api/errors.d.ts +23 -1
  20. package/dist/api/errors.js +1 -1
  21. package/dist/api/index.d.ts +2 -0
  22. package/dist/api/index.js +1 -1
  23. package/dist/api/node-transport.js +1 -1
  24. package/dist/api/routes.d.ts +22 -0
  25. package/dist/api/routes.js +1 -1
  26. package/dist/build-root.d.ts +6 -1
  27. package/dist/build-root.js +1 -1
  28. package/dist/builtin-memory/crouter-sdk/client.md +34 -0
  29. package/dist/builtin-memory/crouter-sdk/errors.md +2 -0
  30. package/dist/builtin-memory/crouter-sdk/memory.md +2 -2
  31. package/dist/builtin-memory/crouter-sdk/streaming.md +21 -0
  32. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +8 -4
  33. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +39 -118
  34. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -1
  35. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +41 -27
  36. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +52 -29
  37. package/dist/cli.js +9 -8
  38. package/dist/clients/attach/chrome/inbox-strip.js +1 -1
  39. package/dist/clients/attach/chrome/roster.js +1 -1
  40. package/dist/clients/attach/config.js +1 -1
  41. package/dist/clients/attach/overlays/auth.js +2 -2
  42. package/dist/clients/attach/overlays/graph.js +1 -1
  43. package/dist/clients/attach/render/tool-calls.js +3 -3
  44. package/dist/clients/attach/session/connection.js +1 -1
  45. package/dist/clients/attach/session/profile-files.js +1 -1
  46. package/dist/clients/attach/viewer.js +1569 -816
  47. package/dist/commands/api-client.js +3 -3
  48. package/dist/commands/broker-permissions.d.ts +2 -0
  49. package/dist/commands/broker-permissions.js +1 -0
  50. package/dist/commands/canvas-analytics/chart.d.ts +52 -0
  51. package/dist/commands/canvas-analytics/chart.js +1 -0
  52. package/dist/commands/canvas-analytics/drilldown.d.ts +34 -0
  53. package/dist/commands/canvas-analytics/drilldown.js +1 -0
  54. package/dist/commands/canvas-analytics/format.d.ts +29 -0
  55. package/dist/commands/canvas-analytics/format.js +1 -0
  56. package/dist/commands/canvas-analytics/graph-detail.d.ts +2 -0
  57. package/dist/commands/canvas-analytics/graph-detail.js +2 -0
  58. package/dist/commands/canvas-analytics/graphs.d.ts +9 -0
  59. package/dist/commands/canvas-analytics/graphs.js +1 -0
  60. package/dist/commands/canvas-analytics/memory.d.ts +2 -0
  61. package/dist/commands/canvas-analytics/memory.js +1 -0
  62. package/dist/commands/canvas-analytics/overview.d.ts +2 -0
  63. package/dist/commands/canvas-analytics/overview.js +1 -0
  64. package/dist/commands/canvas-analytics/shell.d.ts +60 -0
  65. package/dist/commands/canvas-analytics/shell.js +2 -0
  66. package/dist/commands/canvas-analytics/time.d.ts +2 -0
  67. package/dist/commands/canvas-analytics/time.js +1 -0
  68. package/dist/commands/canvas-analytics/usage.d.ts +2 -0
  69. package/dist/commands/canvas-analytics/usage.js +1 -0
  70. package/dist/commands/canvas-analytics/view.d.ts +85 -0
  71. package/dist/commands/canvas-analytics/view.js +1 -0
  72. package/dist/commands/canvas-analytics.d.ts +2 -0
  73. package/dist/commands/canvas-analytics.js +1 -0
  74. package/dist/commands/canvas-prune.js +1 -1
  75. package/dist/commands/canvas.js +1 -1
  76. package/dist/commands/cron.js +5 -5
  77. package/dist/commands/human/components.d.ts +2 -0
  78. package/dist/commands/human/components.js +2 -2
  79. package/dist/commands/human/prompts.js +1 -1
  80. package/dist/commands/human/queue.js +1 -1
  81. package/dist/commands/memory/client.d.ts +11 -0
  82. package/dist/commands/memory/client.js +1 -0
  83. package/dist/commands/memory/delete.js +1 -1
  84. package/dist/commands/memory/edit.js +3 -3
  85. package/dist/commands/memory/find.js +1 -1
  86. package/dist/commands/memory/history.js +4 -4
  87. package/dist/commands/memory/lint.js +1 -1
  88. package/dist/commands/memory/list.d.ts +0 -2
  89. package/dist/commands/memory/list.js +1 -1
  90. package/dist/commands/memory/move.js +1 -1
  91. package/dist/commands/memory/origin.js +1 -1
  92. package/dist/commands/memory/read.d.ts +0 -5
  93. package/dist/commands/memory/read.js +3 -3
  94. package/dist/commands/memory/shared.d.ts +0 -178
  95. package/dist/commands/memory/shared.js +1 -12
  96. package/dist/commands/memory/write.js +5 -5
  97. package/dist/commands/node/bash.js +5 -5
  98. package/dist/commands/node/create.d.ts +0 -17
  99. package/dist/commands/node/create.js +2 -3
  100. package/dist/commands/node/inspect.js +6 -6
  101. package/dist/commands/node/lifecycle.js +2 -2
  102. package/dist/commands/node-context.js +2 -2
  103. package/dist/commands/node-inspect-artifacts.js +6 -6
  104. package/dist/commands/pkg/browse/catalog.js +1 -1
  105. package/dist/commands/pkg/browse/model.d.ts +1 -1
  106. package/dist/commands/pkg/market-manage.js +1 -1
  107. package/dist/commands/pkg/plugin-manage.js +10 -10
  108. package/dist/commands/profile/daemon-profiles.d.ts +13 -0
  109. package/dist/commands/profile/daemon-profiles.js +4 -0
  110. package/dist/commands/profile/delete.js +1 -1
  111. package/dist/commands/profile/env.d.ts +6 -0
  112. package/dist/commands/profile/env.js +2 -2
  113. package/dist/commands/profile/kind.js +1 -2
  114. package/dist/commands/profile/list.js +1 -1
  115. package/dist/commands/profile/meta.js +1 -1
  116. package/dist/commands/profile/new.js +1 -1
  117. package/dist/commands/profile/pause.js +1 -1
  118. package/dist/commands/profile/project.js +1 -1
  119. package/dist/commands/profile/rename.js +1 -1
  120. package/dist/commands/profile/show.js +1 -1
  121. package/dist/commands/profile.js +1 -1
  122. package/dist/commands/push.js +3 -3
  123. package/dist/commands/surface-inspect.js +1 -1
  124. package/dist/commands/sys/branch.js +1 -1
  125. package/dist/commands/sys/config.js +1 -1
  126. package/dist/commands/sys/connect.js +3 -3
  127. package/dist/commands/sys/context/admin/actions.js +1 -1
  128. package/dist/commands/sys/context/admin/model.d.ts +1 -0
  129. package/dist/commands/sys/context/admin/model.js +1 -1
  130. package/dist/commands/sys/context/admin.js +1 -1
  131. package/dist/commands/sys/context/expose.js +2 -1
  132. package/dist/commands/sys/context/prompt-review.js +2 -2
  133. package/dist/commands/sys/context/resolve.js +7 -7
  134. package/dist/commands/sys/context/sysprompt.js +1 -1
  135. package/dist/commands/sys/join.d.ts +1 -0
  136. package/dist/commands/sys/join.js +1 -0
  137. package/dist/commands/sys/migrate.js +1 -1
  138. package/dist/commands/sys/panels/models-panel.js +1 -1
  139. package/dist/commands/sys/panels/profiles-panel.d.ts +0 -1
  140. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  141. package/dist/commands/sys/provider-login.js +6 -6
  142. package/dist/commands/sys/setup-core.d.ts +1 -1
  143. package/dist/commands/sys/setup-core.js +6 -6
  144. package/dist/commands/sys/setup-settings-runner.js +1 -1
  145. package/dist/commands/sys/setup.js +1 -1
  146. package/dist/commands/sys/spaces.d.ts +1 -0
  147. package/dist/commands/sys/spaces.js +2 -0
  148. package/dist/commands/sys/sync-deps.js +2 -2
  149. package/dist/commands/sys/sync-project-guidance.js +4 -4
  150. package/dist/commands/sys/sync-skills.js +2 -2
  151. package/dist/commands/sys/worktrees.d.ts +1 -0
  152. package/dist/commands/sys/worktrees.js +1 -1
  153. package/dist/commands/sys.js +1 -1
  154. package/dist/core/auth-file.js +2 -2
  155. package/dist/core/bash-job-supervisor.d.ts +6 -0
  156. package/dist/core/bash-job-supervisor.js +4 -0
  157. package/dist/core/bash-jobs.d.ts +13 -6
  158. package/dist/core/bash-jobs.js +8 -7
  159. package/dist/core/broker-client/transport-relay.d.ts +6 -3
  160. package/dist/core/broker-client/transport-relay.js +1 -1
  161. package/dist/core/broker-client/transport-socket.d.ts +6 -1
  162. package/dist/core/broker-client/transport-socket.js +1 -1
  163. package/dist/core/canvas/canvas.d.ts +39 -18
  164. package/dist/core/canvas/canvas.js +21 -20
  165. package/dist/core/canvas/context-strip.d.ts +20 -0
  166. package/dist/core/canvas/context-strip.js +5 -0
  167. package/dist/core/canvas/crons.d.ts +12 -20
  168. package/dist/core/canvas/crons.js +15 -13
  169. package/dist/core/canvas/db.js +2 -2
  170. package/dist/core/canvas/deliveries.d.ts +4 -1
  171. package/dist/core/canvas/deliveries.js +1 -1
  172. package/dist/core/canvas/executions.js +1 -1
  173. package/dist/core/canvas/history.d.ts +2 -1
  174. package/dist/core/canvas/history.js +17 -18
  175. package/dist/core/canvas/memory-reads.d.ts +19 -0
  176. package/dist/core/canvas/memory-reads.js +1 -0
  177. package/dist/core/canvas/migrations.d.ts +0 -4
  178. package/dist/core/canvas/migrations.js +99 -32
  179. package/dist/core/canvas/nav-render.js +1 -1
  180. package/dist/core/canvas/node-agent-paths.d.ts +8 -0
  181. package/dist/core/canvas/node-agent-paths.js +1 -0
  182. package/dist/core/canvas/node-recap.d.ts +2 -2
  183. package/dist/core/canvas/node-recap.js +2 -2
  184. package/dist/core/canvas/node-tokens.d.ts +24 -0
  185. package/dist/core/canvas/node-tokens.js +5 -0
  186. package/dist/core/canvas/paths.d.ts +16 -19
  187. package/dist/core/canvas/paths.js +1 -1
  188. package/dist/core/canvas/render-source.d.ts +2 -2
  189. package/dist/core/canvas/render-source.js +6 -9
  190. package/dist/core/canvas/sessions.d.ts +18 -0
  191. package/dist/core/canvas/sessions.js +4 -1
  192. package/dist/core/canvas/types.d.ts +22 -6
  193. package/dist/core/command-hooks/compose.js +1 -1
  194. package/dist/core/command-hooks/discovery.d.ts +15 -1
  195. package/dist/core/command-hooks/discovery.js +1 -1
  196. package/dist/core/command-hooks/help.d.ts +2 -2
  197. package/dist/core/command-hooks/lifecycle-create.d.ts +1 -1
  198. package/dist/core/command-hooks/lifecycle-create.js +1 -1
  199. package/dist/core/command-hooks/transport/exec-invoke.d.ts +2 -0
  200. package/dist/core/command-hooks/transport/exec-invoke.js +1 -1
  201. package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +1 -0
  202. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  203. package/dist/core/command-hooks/transport/plan.d.ts +3 -0
  204. package/dist/core/command-hooks/transport/plan.js +1 -0
  205. package/dist/core/command-plugins/discovery.js +1 -1
  206. package/dist/core/command.d.ts +6 -2
  207. package/dist/core/command.js +6 -6
  208. package/dist/core/config.d.ts +8 -5
  209. package/dist/core/config.js +1 -1
  210. package/dist/core/conversation-store/client-worker.d.ts +1 -0
  211. package/dist/core/conversation-store/client-worker.js +1 -0
  212. package/dist/core/conversation-store/client.d.ts +2 -0
  213. package/dist/core/conversation-store/client.js +2 -0
  214. package/dist/core/conversation-store/file-store.d.ts +37 -0
  215. package/dist/core/conversation-store/file-store.js +9 -0
  216. package/dist/core/conversation-store/index.d.ts +50 -0
  217. package/dist/core/conversation-store/index.js +1 -0
  218. package/dist/core/conversation-store/listener.d.ts +4 -0
  219. package/dist/core/conversation-store/listener.js +3 -0
  220. package/dist/core/conversation-store/patch.d.ts +1 -0
  221. package/dist/core/conversation-store/patch.js +1 -0
  222. package/dist/core/directory/join.d.ts +27 -0
  223. package/dist/core/directory/join.js +1 -0
  224. package/dist/core/disk-usage.d.ts +4 -0
  225. package/dist/core/disk-usage.js +1 -0
  226. package/dist/core/events/emit.d.ts +2 -0
  227. package/dist/core/events/emit.js +3 -1
  228. package/dist/core/feed/feed.js +4 -4
  229. package/dist/core/feed/messages.d.ts +3 -0
  230. package/dist/core/feed/messages.js +6 -6
  231. package/dist/core/fs-utils.d.ts +2 -0
  232. package/dist/core/fs-utils.js +3 -3
  233. package/dist/core/grants/local.d.ts +4 -0
  234. package/dist/core/grants/local.js +1 -0
  235. package/dist/core/grants/mirror.d.ts +44 -0
  236. package/dist/core/grants/mirror.js +4 -0
  237. package/dist/core/grants/on-sync.d.ts +22 -0
  238. package/dist/core/grants/on-sync.js +1 -0
  239. package/dist/core/grants/remove.d.ts +7 -0
  240. package/dist/core/grants/remove.js +1 -0
  241. package/dist/core/grants/sandboxes.d.ts +7 -0
  242. package/dist/core/grants/sandboxes.js +1 -0
  243. package/dist/core/grants/sync.d.ts +12 -0
  244. package/dist/core/grants/sync.js +1 -0
  245. package/dist/core/help/memory-extensions.d.ts +3 -0
  246. package/dist/core/help/memory-extensions.js +2 -0
  247. package/dist/core/help.d.ts +14 -0
  248. package/dist/core/help.js +7 -7
  249. package/dist/core/host-exports/builtins.js +3 -3
  250. package/dist/core/host-exports/export.js +3 -3
  251. package/dist/core/human/action-binding.d.ts +2 -0
  252. package/dist/core/human/action-binding.js +1 -1
  253. package/dist/core/human/feedback-companion.d.ts +0 -1
  254. package/dist/core/human/feedback-companion.js +1 -1
  255. package/dist/core/human/page-schema.d.ts +1 -1
  256. package/dist/core/inspector/core.d.ts +2 -0
  257. package/dist/core/inspector/core.js +1 -1
  258. package/dist/core/inspector/tui.js +2 -2
  259. package/dist/core/installed-plugins.js +1 -1
  260. package/dist/core/io.js +6 -6
  261. package/dist/core/keybindings/catalog.d.ts +1 -1
  262. package/dist/core/keybindings/catalog.js +1 -1
  263. package/dist/core/layout-migrate/index.d.ts +15 -0
  264. package/dist/core/layout-migrate/index.js +4 -0
  265. package/dist/core/layout-migrate/paths.d.ts +26 -0
  266. package/dist/core/layout-migrate/paths.js +1 -0
  267. package/dist/core/layout-migrate/stored-paths.d.ts +2 -0
  268. package/dist/core/layout-migrate/stored-paths.js +11 -0
  269. package/dist/core/layout-migrate/stores.d.ts +17 -0
  270. package/dist/core/layout-migrate/stores.js +4 -0
  271. package/dist/core/layout.d.ts +26 -0
  272. package/dist/core/layout.js +2 -0
  273. package/dist/core/llm/run.d.ts +60 -0
  274. package/dist/core/llm/run.js +4 -0
  275. package/dist/core/memory/cli-selector.d.ts +13 -0
  276. package/dist/core/memory/cli-selector.js +1 -0
  277. package/dist/core/memory/history.d.ts +5 -4
  278. package/dist/core/memory/history.js +6 -6
  279. package/dist/core/memory/inline-ref-inventory.d.ts +2 -1
  280. package/dist/core/memory/inline-ref-inventory.js +1 -1
  281. package/dist/core/memory/lint.js +2 -2
  282. package/dist/core/memory/mutation-domain.d.ts +2 -2
  283. package/dist/core/memory/mutation-domain.js +8 -7
  284. package/dist/core/memory/mutations.js +1 -1
  285. package/dist/core/memory/service.d.ts +5 -0
  286. package/dist/core/memory/service.js +2 -2
  287. package/dist/core/memory-resolver.d.ts +11 -7
  288. package/dist/core/memory-resolver.js +2 -2
  289. package/dist/core/model-auth/daemon-login.d.ts +13 -0
  290. package/dist/core/model-auth/daemon-login.js +1 -0
  291. package/dist/core/model-auth/flows.d.ts +45 -0
  292. package/dist/core/model-auth/flows.js +1 -0
  293. package/dist/core/model-auth/handoff-jti.d.ts +4 -0
  294. package/dist/core/model-auth/handoff-jti.js +1 -0
  295. package/dist/core/model-routes.js +1 -1
  296. package/dist/core/nested-stores.d.ts +2 -1
  297. package/dist/core/nested-stores.js +1 -2
  298. package/dist/core/preview-registry.js +2 -2
  299. package/dist/core/profiles/env-store.js +2 -2
  300. package/dist/core/profiles/manifest.d.ts +16 -5
  301. package/dist/core/profiles/manifest.js +1 -1
  302. package/dist/core/provider-management.js +1 -1
  303. package/dist/core/review/birth.js +1 -1
  304. package/dist/core/review/companion.d.ts +0 -2
  305. package/dist/core/review/companion.js +1 -1
  306. package/dist/core/review/fork.js +2 -2
  307. package/dist/core/review/realize.js +1 -1
  308. package/dist/core/review/stage.d.ts +1 -1
  309. package/dist/core/review/stage.js +1 -1
  310. package/dist/core/review/types.d.ts +1 -1
  311. package/dist/core/runs/events.d.ts +34 -0
  312. package/dist/core/runs/events.js +1 -0
  313. package/dist/core/runs/operations.d.ts +43 -0
  314. package/dist/core/runs/operations.js +12 -0
  315. package/dist/core/runtime/bearings-render.d.ts +2 -2
  316. package/dist/core/runtime/bearings-render.js +11 -11
  317. package/dist/core/runtime/bearings.js +2 -2
  318. package/dist/core/runtime/broker/cli-relay.d.ts +5 -0
  319. package/dist/core/runtime/broker/cli-relay.js +1 -0
  320. package/dist/core/runtime/broker/client-registry.d.ts +0 -5
  321. package/dist/core/runtime/broker/client-registry.js +1 -1
  322. package/dist/core/runtime/broker/daemon-ops.d.ts +28 -1
  323. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  324. package/dist/core/runtime/broker/engine-drive.d.ts +0 -2
  325. package/dist/core/runtime/broker/engine-drive.js +1 -1
  326. package/dist/core/runtime/broker/fault-retry.d.ts +9 -0
  327. package/dist/core/runtime/broker/fault-retry.js +1 -1
  328. package/dist/core/runtime/broker/frame-dispatch.d.ts +5 -9
  329. package/dist/core/runtime/broker/frame-dispatch.js +1 -1
  330. package/dist/core/runtime/broker/frame-engine-control.d.ts +3 -2
  331. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  332. package/dist/core/runtime/broker/frame-memory-refs.d.ts +4 -3
  333. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  334. package/dist/core/runtime/broker/frame-read.js +1 -1
  335. package/dist/core/runtime/broker/frame-session.js +1 -1
  336. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -1
  337. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  338. package/dist/core/runtime/broker/inbox.d.ts +1 -2
  339. package/dist/core/runtime/broker/inbox.js +7 -10
  340. package/dist/core/runtime/broker/model-adapter.d.ts +9 -0
  341. package/dist/core/runtime/broker/model-adapter.js +2 -0
  342. package/dist/core/runtime/broker/node-token.d.ts +3 -0
  343. package/dist/core/runtime/broker/node-token.js +1 -0
  344. package/dist/core/runtime/broker/read-ops.js +1 -1
  345. package/dist/core/runtime/broker/rebind.d.ts +2 -0
  346. package/dist/core/runtime/broker/rebind.js +1 -1
  347. package/dist/core/runtime/broker/tool-groups.js +1 -1
  348. package/dist/core/runtime/broker/turn-ignition.d.ts +3 -3
  349. package/dist/core/runtime/broker/turn-ignition.js +1 -1
  350. package/dist/core/runtime/broker-cli.js +3 -3
  351. package/dist/core/runtime/broker-extension-render.d.ts +2 -5
  352. package/dist/core/runtime/broker-extension-render.js +4 -4
  353. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  354. package/dist/core/runtime/broker-protocol.d.ts +7 -8
  355. package/dist/core/runtime/broker.js +1 -1
  356. package/dist/core/runtime/canvas-extensions.d.ts +1 -0
  357. package/dist/core/runtime/canvas-extensions.js +1 -1
  358. package/dist/core/runtime/close.d.ts +9 -0
  359. package/dist/core/runtime/close.js +1 -1
  360. package/dist/core/runtime/deliver-live.js +1 -1
  361. package/dist/core/runtime/fleet.d.ts +1 -1
  362. package/dist/core/runtime/front-door-login.js +1 -1
  363. package/dist/core/runtime/front-door.js +2 -2
  364. package/dist/core/runtime/headless-pi.d.ts +1 -1
  365. package/dist/core/runtime/headless-pi.js +1 -1
  366. package/dist/core/runtime/host.d.ts +1 -1
  367. package/dist/core/runtime/host.js +3 -1
  368. package/dist/core/runtime/invocation.d.ts +3 -0
  369. package/dist/core/runtime/kickoff.d.ts +1 -0
  370. package/dist/core/runtime/kickoff.js +16 -16
  371. package/dist/core/runtime/launch-target.d.ts +1 -1
  372. package/dist/core/runtime/launch-target.js +1 -1
  373. package/dist/core/runtime/launch.d.ts +10 -35
  374. package/dist/core/runtime/launch.js +1 -1
  375. package/dist/core/runtime/lifecycle.js +2 -2
  376. package/dist/core/runtime/memory.d.ts +1 -1
  377. package/dist/core/runtime/memory.js +1 -1
  378. package/dist/core/runtime/model-registry.js +1 -1
  379. package/dist/core/runtime/model-swap.d.ts +17 -19
  380. package/dist/core/runtime/model-swap.js +1 -1
  381. package/dist/core/runtime/node-read.js +3 -2
  382. package/dist/core/runtime/nodes.d.ts +7 -0
  383. package/dist/core/runtime/nodes.js +1 -1
  384. package/dist/core/runtime/outcome-document.js +1 -1
  385. package/dist/core/runtime/package-health.js +2 -2
  386. package/dist/core/runtime/persona.js +2 -2
  387. package/dist/core/runtime/pi-vendored.js +1 -1
  388. package/dist/core/runtime/placement-tmux.d.ts +1 -1
  389. package/dist/core/runtime/placement-tmux.js +1 -1
  390. package/dist/core/runtime/placement.js +1 -1
  391. package/dist/core/runtime/promote.js +1 -1
  392. package/dist/core/runtime/provider-credential-gate.js +2 -2
  393. package/dist/core/runtime/recovery-hold.d.ts +2 -0
  394. package/dist/core/runtime/recovery-hold.js +1 -0
  395. package/dist/core/runtime/recycle.js +1 -1
  396. package/dist/core/runtime/reopen.js +1 -1
  397. package/dist/core/runtime/reset.js +1 -1
  398. package/dist/core/runtime/revive.d.ts +1 -1
  399. package/dist/core/runtime/revive.js +2 -3
  400. package/dist/core/runtime/roadmap.js +4 -4
  401. package/dist/core/runtime/run-command.d.ts +6 -0
  402. package/dist/core/runtime/run-command.js +1 -1
  403. package/dist/core/runtime/session-branch.d.ts +2 -8
  404. package/dist/core/runtime/session-branch.js +1 -1
  405. package/dist/core/runtime/session-list-cache.d.ts +6 -22
  406. package/dist/core/runtime/session-list-cache.js +1 -1
  407. package/dist/core/runtime/situational-context.js +2 -2
  408. package/dist/core/runtime/spawn-env.d.ts +6 -6
  409. package/dist/core/runtime/spawn-env.js +1 -1
  410. package/dist/core/runtime/spawn.d.ts +5 -0
  411. package/dist/core/runtime/spawn.js +2 -2
  412. package/dist/core/runtime/stop-guard.js +2 -2
  413. package/dist/core/runtime/stop-signals.d.ts +2 -2
  414. package/dist/core/runtime/stop-signals.js +1 -1
  415. package/dist/core/runtime/structured-output.d.ts +10 -4
  416. package/dist/core/runtime/structured-output.js +4 -4
  417. package/dist/core/runtime/tmux-bindings.js +3 -3
  418. package/dist/core/runtime/tmux-driver.d.ts +4 -0
  419. package/dist/core/runtime/tmux-driver.js +7 -7
  420. package/dist/core/runtime/view-socket.d.ts +9 -2
  421. package/dist/core/runtime/view-socket.js +1 -1
  422. package/dist/core/runtime/warm-pool.js +1 -1
  423. package/dist/core/scope.d.ts +3 -2
  424. package/dist/core/scope.js +1 -1
  425. package/dist/core/scoped-state/db.js +1 -1
  426. package/dist/core/scoped-state/migrate.js +3 -3
  427. package/dist/core/scoped-state/profiles.d.ts +2 -1
  428. package/dist/core/scoped-state/profiles.js +1 -1
  429. package/dist/core/scoped-state/schema.d.ts +2 -1
  430. package/dist/core/scoped-state/schema.js +4 -4
  431. package/dist/core/scopes.d.ts +2 -2
  432. package/dist/core/scopes.js +1 -1
  433. package/dist/core/secrets.d.ts +1 -0
  434. package/dist/core/secrets.js +2 -2
  435. package/dist/core/spaces/mounts.d.ts +32 -0
  436. package/dist/core/spaces/mounts.js +1 -0
  437. package/dist/core/spaces/open-beneath.d.ts +71 -0
  438. package/dist/core/spaces/open-beneath.js +1 -0
  439. package/dist/core/spaces/permissions.d.ts +46 -0
  440. package/dist/core/spaces/permissions.js +1 -0
  441. package/dist/core/spaces/process.d.ts +27 -0
  442. package/dist/core/spaces/process.js +1 -0
  443. package/dist/core/spaces/space.d.ts +8 -0
  444. package/dist/core/spaces/space.js +2 -0
  445. package/dist/core/spaces/stop.d.ts +8 -0
  446. package/dist/core/spaces/stop.js +2 -0
  447. package/dist/core/spaces/users.d.ts +19 -0
  448. package/dist/core/spaces/users.js +1 -0
  449. package/dist/core/subscription-state.d.ts +2 -0
  450. package/dist/core/subscription-state.js +3 -3
  451. package/dist/core/substrate/frontmatter-validation.js +1 -1
  452. package/dist/core/substrate/injected-store.d.ts +28 -3
  453. package/dist/core/substrate/injected-store.js +2 -1
  454. package/dist/core/substrate/listings.js +1 -1
  455. package/dist/core/substrate/memory-events.d.ts +6 -0
  456. package/dist/core/substrate/memory-events.js +1 -0
  457. package/dist/core/substrate/on-read-node.js +1 -1
  458. package/dist/core/substrate/on-read.d.ts +6 -6
  459. package/dist/core/substrate/on-read.js +5 -5
  460. package/dist/core/substrate/plan.js +1 -1
  461. package/dist/core/substrate/render-node.js +1 -1
  462. package/dist/core/substrate/render.d.ts +4 -3
  463. package/dist/core/substrate/render.js +38 -38
  464. package/dist/core/substrate/schema.d.ts +6 -0
  465. package/dist/core/substrate/schema.js +1 -1
  466. package/dist/core/tui/panel.js +1 -1
  467. package/dist/core/user-settings.d.ts +12 -0
  468. package/dist/core/user-settings.js +1 -1
  469. package/dist/core/worktree-mutation-async.js +5 -5
  470. package/dist/core/worktree-quarantine.js +1 -1
  471. package/dist/core/worktree-remove.d.ts +15 -0
  472. package/dist/core/worktree-remove.js +1 -0
  473. package/dist/core/worktree-sweep.js +6 -6
  474. package/dist/daemon/analytics/compute.d.ts +37 -0
  475. package/dist/daemon/analytics/compute.js +1 -0
  476. package/dist/daemon/analytics/scan-worker.d.ts +1 -0
  477. package/dist/daemon/analytics/scan-worker.js +2 -0
  478. package/dist/daemon/analytics/scan.d.ts +37 -0
  479. package/dist/daemon/analytics/scan.js +1 -0
  480. package/dist/daemon/api/app-listener.d.ts +11 -0
  481. package/dist/daemon/api/app-listener.js +21 -0
  482. package/dist/daemon/api/bridge.js +5 -5
  483. package/dist/daemon/api/handlers/analytics.d.ts +2 -0
  484. package/dist/daemon/api/handlers/analytics.js +1 -0
  485. package/dist/daemon/api/handlers/attach.js +1 -1
  486. package/dist/daemon/api/handlers/bash-jobs.js +2 -2
  487. package/dist/daemon/api/handlers/bash.js +1 -1
  488. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  489. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  490. package/dist/daemon/api/handlers/canvas.js +6 -6
  491. package/dist/daemon/api/handlers/crons.js +1 -1
  492. package/dist/daemon/api/handlers/files.d.ts +1 -1
  493. package/dist/daemon/api/handlers/files.js +1 -1
  494. package/dist/daemon/api/handlers/health.js +2 -2
  495. package/dist/daemon/api/handlers/hook-exec.d.ts +2 -0
  496. package/dist/daemon/api/handlers/hook-exec.js +1 -0
  497. package/dist/daemon/api/handlers/human-requests.js +1 -1
  498. package/dist/daemon/api/handlers/inbox.js +1 -1
  499. package/dist/daemon/api/handlers/llm.d.ts +2 -0
  500. package/dist/daemon/api/handlers/llm.js +3 -0
  501. package/dist/daemon/api/handlers/memory-reads.d.ts +4 -0
  502. package/dist/daemon/api/handlers/memory-reads.js +1 -0
  503. package/dist/daemon/api/handlers/memory.js +5 -1
  504. package/dist/daemon/api/handlers/messages.js +2 -2
  505. package/dist/daemon/api/handlers/modelauth.js +1 -1
  506. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  507. package/dist/daemon/api/handlers/node-records.d.ts +2 -0
  508. package/dist/daemon/api/handlers/node-records.js +3 -0
  509. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  510. package/dist/daemon/api/handlers/nodes.js +1 -1
  511. package/dist/daemon/api/handlers/profiles.d.ts +4 -1
  512. package/dist/daemon/api/handlers/profiles.js +1 -1
  513. package/dist/daemon/api/handlers/reports.js +5 -3
  514. package/dist/daemon/api/handlers/reviews.d.ts +1 -1
  515. package/dist/daemon/api/handlers/reviews.js +1 -1
  516. package/dist/daemon/api/handlers/run-routes.d.ts +2 -0
  517. package/dist/daemon/api/handlers/run-routes.js +1 -0
  518. package/dist/daemon/api/handlers/runs.d.ts +9 -0
  519. package/dist/daemon/api/handlers/runs.js +1 -0
  520. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  521. package/dist/daemon/api/handlers/worktree.js +1 -1
  522. package/dist/daemon/api/map.d.ts +10 -4
  523. package/dist/daemon/api/map.js +2 -2
  524. package/dist/daemon/api/operations.d.ts +18 -0
  525. package/dist/daemon/api/operations.js +1 -0
  526. package/dist/daemon/api/principal.d.ts +42 -0
  527. package/dist/daemon/api/principal.js +1 -0
  528. package/dist/daemon/api/router.d.ts +27 -3
  529. package/dist/daemon/api/router.js +1 -1
  530. package/dist/daemon/api/server.d.ts +4 -0
  531. package/dist/daemon/api/server.js +1 -1
  532. package/dist/daemon/api/vendor-signin.d.ts +7 -0
  533. package/dist/daemon/api/vendor-signin.js +77 -0
  534. package/dist/daemon/api/viewer-presence.d.ts +3 -0
  535. package/dist/daemon/api/viewer-presence.js +1 -0
  536. package/dist/daemon/cron/armed-context.d.ts +4 -0
  537. package/dist/daemon/cron/armed-context.js +1 -1
  538. package/dist/daemon/cron/escalation.js +3 -3
  539. package/dist/daemon/cron/lease-recovery.js +1 -1
  540. package/dist/daemon/cron/sinks.js +2 -2
  541. package/dist/daemon/cron-run.d.ts +5 -5
  542. package/dist/daemon/cron-run.js +1 -1
  543. package/dist/daemon/crtrd.js +8 -7
  544. package/dist/daemon/delivery/run-delivery.d.ts +4 -0
  545. package/dist/daemon/delivery/run-delivery.js +1 -1
  546. package/dist/daemon/fleet.d.ts +1 -1
  547. package/dist/daemon/fleet.js +6 -6
  548. package/dist/daemon/human/finish.js +7 -7
  549. package/dist/daemon/joined-owner.d.ts +5 -0
  550. package/dist/daemon/joined-owner.js +1 -0
  551. package/dist/daemon/manage.js +2 -2
  552. package/dist/daemon/messaging/node-message.js +1 -1
  553. package/dist/daemon/park-activity.js +1 -1
  554. package/dist/daemon/reconcilers/bash-deadline.js +1 -1
  555. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  556. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  557. package/dist/daemon/reconcilers/delivery-lane.js +1 -1
  558. package/dist/daemon/reconcilers/live-obligation.d.ts +7 -0
  559. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  560. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  561. package/dist/daemon/reconcilers/storage-maintenance.d.ts +20 -1
  562. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  563. package/dist/daemon/runs/append-section.d.ts +6 -0
  564. package/dist/daemon/runs/append-section.js +2 -0
  565. package/dist/daemon/runs/observer.d.ts +5 -0
  566. package/dist/daemon/runs/observer.js +4 -0
  567. package/dist/launcher/bwrap.d.ts +4 -0
  568. package/dist/launcher/bwrap.js +2 -0
  569. package/dist/launcher/client.d.ts +2 -0
  570. package/dist/launcher/client.js +3 -0
  571. package/dist/launcher/main.d.ts +1 -0
  572. package/dist/launcher/main.js +3 -0
  573. package/dist/launcher/netrule.d.ts +1 -0
  574. package/dist/launcher/netrule.js +1 -0
  575. package/dist/launcher/seccomp.d.ts +1 -0
  576. package/dist/launcher/seccomp.js +1 -0
  577. package/dist/launcher/spec.d.ts +88 -0
  578. package/dist/launcher/spec.js +1 -0
  579. package/dist/launcher/users.d.ts +18 -0
  580. package/dist/launcher/users.js +7 -0
  581. package/dist/launcher/validate.d.ts +22 -0
  582. package/dist/launcher/validate.js +1 -0
  583. package/dist/migrations/corpus.js +3 -3
  584. package/dist/migrations/runner.js +1 -1
  585. package/dist/native/linux/addon.node +0 -0
  586. package/dist/native/linux.d.ts +29 -0
  587. package/dist/native/linux.js +1 -0
  588. package/dist/pi-extensions/broker-local.js +2 -2
  589. package/dist/pi-extensions/canvas-bash-valve.d.ts +1 -3
  590. package/dist/pi-extensions/canvas-bash-valve.js +4 -7
  591. package/dist/pi-extensions/canvas-context-intro.d.ts +1 -2
  592. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  593. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  594. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +2 -1
  595. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -1
  596. package/dist/pi-extensions/canvas-passive-context.d.ts +1 -1
  597. package/dist/pi-extensions/canvas-passive-context.js +11 -11
  598. package/dist/pi-extensions/canvas-recap.js +6 -6
  599. package/dist/pi-extensions/canvas-stophook.js +1 -1
  600. package/dist/pi-extensions/canvas-structured-output.js +4 -4
  601. package/dist/pi-extensions/canvas-tool-guide.js +1 -1
  602. package/dist/pi-extensions/system-prompt-entry.d.ts +15 -0
  603. package/dist/pi-extensions/system-prompt-entry.js +1 -0
  604. package/dist/shared/env.d.ts +5 -1
  605. package/dist/shared/env.js +1 -1
  606. package/dist/shared/strip-cd-prefix.d.ts +1 -0
  607. package/dist/shared/strip-cd-prefix.js +1 -0
  608. package/dist/types.d.ts +31 -15
  609. package/docs/cli/memory-and-preferences.md +3 -1
  610. package/docs/sdk/client.md +34 -0
  611. package/docs/sdk/errors.md +2 -0
  612. package/docs/sdk/memory.md +2 -2
  613. package/docs/sdk/streaming.md +21 -0
  614. package/package.json +18 -4
  615. package/packages/crouter-identity/dist/index.d.ts +54 -0
  616. package/packages/crouter-identity/dist/index.js +166 -0
  617. package/packages/crouter-identity/package.json +33 -0
  618. package/runtime.lock.json +34 -8
  619. package/scripts/build-native-linux.mjs +16 -0
  620. package/scripts/install-runtime.mjs +9 -7
  621. package/scripts/lib/isolation-env.mjs +42 -0
  622. package/scripts/runtime-smoke.mjs +49 -0
  623. package/src/native/linux/addon.c +249 -0
  624. package/dist/core/profiles/state-block.d.ts +0 -4
  625. package/dist/core/profiles/state-block.js +0 -3
  626. package/dist/core/runtime/broker/auth-reload.d.ts +0 -41
  627. package/dist/core/runtime/broker/auth-reload.js +0 -1
  628. package/dist/core/substrate/cli-context-delivery.d.ts +0 -22
  629. package/dist/core/substrate/cli-context-delivery.js +0 -1
@@ -1 +1 @@
1
- var w=Object.defineProperty;var s=(e,n)=>w(e,"name",{value:n,configurable:!0});import{envHomeOverride as u}from"../../shared/env.js";import{paneLocation as m,ensureSession as P,openNodeWindow as T,splitWindow as f,selectLayout as _}from"./tmux-driver.js";import{BROKER_VIEW_SOCKET_WAIT_MS as S}from"./view-socket.js";import{paneExists as x,paneLocation as h,paneOfNode as V,paneCurrentPath as g,paneSize as y,paneRunning as B,ensureSession as H,openNodeWindow as L,splitWindow as M,closePane as k,currentTmux as N,switchClient as K,selectWindow as b,selectLayout as z,selectPane as F,getPaneOption as Q,setPaneOption as $,breakPane as j,inTmux as q,piCommand as D,shellQuote as G,renameWindow as J,displayPopup as U,windowOfPane as X,respawnPaneSync as Y,respawnPaneInBackground as Z,respawnPaneInPlace as ee,paneStartCommand as ne,panePid as oe,windowAlive as ie,listLivePanes as te,VIEWER_STAMP_OPTION as re,stampViewerPaneAsync as ae,liveViewerPanes as se,sendAttachControl as ce,displayClientMessage as le}from"./tmux-driver.js";import{installTmuxBindings as de}from"./tmux-bindings.js";import{BROKER_VIEW_SOCKET_WAIT_MS as ue,waitForBrokerViewSocket as me}from"./view-socket.js";function W(){const e=u();return e!==void 0?{CRTR_HOME:e}:{}}s(W,"viewerSplitEnv");function R(e,n,o={}){const c=`crtr surface attach to ${e}`,l={...W(),...o.waitForBroker===!0?{CRTR_ATTACH_WAIT_MS:String(S)}:{},...o.initialWhip===!0?{CRTR_ATTACH_INITIAL_WHIP:"1"}:{}},i=o.cwd??process.cwd();if(o.besidePane!==void 0){const r=f(o.besidePane,{cwd:i,env:l,command:c});if(r===null)return null;const p=m(r),d=p?.session??n,a=p?.window??null;return a!==null&&_(a,"even-horizontal"),{pane:r,session:d,window:a}}P(n,i);const t=T({session:n,name:o.name??e,cwd:i,env:l,command:c});return t===null?null:{pane:t.pane,session:n,window:t.window}}s(R,"openViewerPane");export{ue as BROKER_VIEW_SOCKET_WAIT_MS,re as VIEWER_STAMP_OPTION,j as breakPane,k as closePane,N as currentTmux,le as displayClientMessage,U as displayPopup,H as ensureSession,Q as getPaneOption,q as inTmux,de as installTmuxBindings,te as listLivePanes,se as liveViewerPanes,L as openNodeWindow,R as openViewerPane,g as paneCurrentPath,x as paneExists,h as paneLocation,V as paneOfNode,oe as panePid,B as paneRunning,y as paneSize,ne as paneStartCommand,D as piCommand,J as renameWindow,Z as respawnPaneInBackground,ee as respawnPaneInPlace,Y as respawnPaneSync,z as selectLayout,F as selectPane,b as selectWindow,ce as sendAttachControl,$ as setPaneOption,G as shellQuote,M as splitWindow,ae as stampViewerPaneAsync,K as switchClient,W as viewerSplitEnv,me as waitForBrokerViewSocket,ie as windowAlive,X as windowOfPane};
1
+ var u=Object.defineProperty;var s=(e,n)=>u(e,"name",{value:n,configurable:!0});import{envHomeOverride as w}from"../../shared/env.js";import{paneLocation as m,ensureSession as P,openNodeWindow as T,splitWindow as f,selectLayout as _}from"./tmux-driver.js";import{BROKER_VIEW_SOCKET_WAIT_MS as S}from"./view-socket.js";import{paneExists as x,paneLocation as h,paneOfNode as g,paneCurrentPath as B,paneSize as V,paneRunning as k,ensureSession as y,openNodeWindow as H,splitWindow as L,closePane as M,currentTmux as N,switchClient as K,selectWindow as b,selectLayout as z,selectPane as F,getPaneOption as Q,setPaneOption as $,breakPane as j,inTmux as q,piCommand as D,shellQuote as G,renameWindow as J,displayPopup as U,windowOfPane as X,respawnPaneSync as Y,respawnPaneInBackground as Z,respawnPaneInPlace as ee,runShellInBackground as ne,paneStartCommand as oe,panePid as ie,windowAlive as te,listLivePanes as re,VIEWER_STAMP_OPTION as ae,stampViewerPaneAsync as se,liveViewerPanes as le,sendAttachControl as ce,displayClientMessage as pe}from"./tmux-driver.js";import{installTmuxBindings as ue}from"./tmux-bindings.js";import{BROKER_VIEW_SOCKET_WAIT_MS as me,waitForBrokerViewSocket as Pe}from"./view-socket.js";function W(){const e=w();return e!==void 0?{CRTR_HOME:e}:{}}s(W,"viewerSplitEnv");function R(e,n,o={}){const l=`crtr surface attach to ${e}`,c={...W(),...o.waitForBroker===!0?{CRTR_ATTACH_WAIT_MS:String(S)}:{},...o.initialWhip===!0?{CRTR_ATTACH_INITIAL_WHIP:"1"}:{}},i=o.cwd??process.cwd();if(o.besidePane!==void 0){const r=f(o.besidePane,{cwd:i,env:c,command:l});if(r===null)return null;const p=m(r),d=p?.session??n,a=p?.window??null;return a!==null&&_(a,"even-horizontal"),{pane:r,session:d,window:a}}P(n,i);const t=T({session:n,name:o.name??e,cwd:i,env:c,command:l});return t===null?null:{pane:t.pane,session:n,window:t.window}}s(R,"openViewerPane");export{me as BROKER_VIEW_SOCKET_WAIT_MS,ae as VIEWER_STAMP_OPTION,j as breakPane,M as closePane,N as currentTmux,pe as displayClientMessage,U as displayPopup,y as ensureSession,Q as getPaneOption,q as inTmux,ue as installTmuxBindings,re as listLivePanes,le as liveViewerPanes,H as openNodeWindow,R as openViewerPane,B as paneCurrentPath,x as paneExists,h as paneLocation,g as paneOfNode,ie as panePid,k as paneRunning,V as paneSize,oe as paneStartCommand,D as piCommand,J as renameWindow,Z as respawnPaneInBackground,ee as respawnPaneInPlace,Y as respawnPaneSync,ne as runShellInBackground,z as selectLayout,F as selectPane,b as selectWindow,ce as sendAttachControl,$ as setPaneOption,G as shellQuote,L as splitWindow,se as stampViewerPaneAsync,K as switchClient,W as viewerSplitEnv,Pe as waitForBrokerViewSocket,te as windowAlive,X as windowOfPane};
@@ -1 +1 @@
1
- var V=Object.defineProperty;var r=(e,n)=>V(e,"name",{value:n,configurable:!0});import{envNodeId as $}from"../../shared/env.js";import{getNode as P,fullName as H,deleteNode as O,listNodes as D,subscribersOf as M,openFocusRow as z,closeFocusRow as a,getFocusByNode as b,getFocusByPane as x,getFocusById as J,listFocuses as Q}from"../canvas/index.js";import{nodeHasAssistantMessage as U}from"../canvas/render-source.js";import{headlessBrokerHost as k}from"./host.js";import{fanDoctrineWake as X}from"./close.js";import{paneExists as w,paneLocation as y,closePane as v,currentTmux as j,switchClient as q,selectWindow as G,selectLayout as K,selectPane as R,getPaneOption as Y,setPaneOption as Z,respawnPaneSync as I,windowOfPane as ee,renameWindow as ne}from"./tmux-driver.js";import{openViewerPane as se,viewerSplitEnv as T,waitForBrokerViewSocket as oe}from"./placement-tmux.js";import{newJobId as ie}from"./nodes.js";import{isPidAlive as W}from"../canvas/pid.js";import{splitWindow as be,breakPane as ke,selectLayout as Re,selectPane as Te,focusWindow as We,selectWindow as Se,switchClient as Ae,openNodeWindow as Be,ensureSession as Ee,paneLocation as Ce,paneExists as Le,paneRunning as Ve,paneCurrentPath as $e,currentTmux as He,inTmux as De,paneOfNode as Me,setPaneOption as ze,getPaneOption as Je,piCommand as Qe,shellQuote as Ue,respawnPaneSync as Xe,closePane as je,displayPopup as qe,windowOfPane as Ge,renameWindow as Ke,paneOfWindow as Ye,windowAlive as Ze,listLivePanes as Ie,listLivePanesAsync as en}from"./tmux-driver.js";import{installTmuxBindings as sn}from"./tmux-bindings.js";function h(e){return e===null?null:e.pane!==null&&!w(e.pane)?(a(e.focus_id),null):e}r(h,"liveOrPrune");function p(e){return h(b(e))}r(p,"focusOf");function xe(e){return p(e)!==null}r(xe,"isFocused");function te(e){return h(x(e))}r(te,"focusByPane");function ye(){return new Set(re().map(e=>e.node_id))}r(ye,"focusedNodes");function re(){const e=[];for(const n of Q())h(n)!==null&&e.push(n);return e}r(re,"listFocuses");function le(){return`f-${ie()}`}r(le,"newFocusId");function S(e,n,s,o){const u=x(n);if(u!==null)return u;const t=b(e);if(t!==null)return t;const l=le();return z(l,n,s,e),J(l)}r(S,"registerViewerFocus");function A(e,n,s={}){const o=se(e,n,s);return o===null?null:S(e,o.pane,o.session,o.window)}r(A,"openViewerWindow");function B(e){const n=y(e)?.window??null;n!==null&&K(n,"even-horizontal"),R(e)}r(B,"surfaceNewPane");async function he(e,n){const s=P(e);if(s===null)return{focused:!1,session:null,inPlace:!1,revived:!1};const o=n.pane??process.env.TMUX_PANE??j()?.pane;if(o===void 0||o==="")return{focused:!1,session:null,inPlace:!1,revived:!1};const u=W(s.pi_pid??null),t=n.revive(e),l=!u;if(!await oe(e,t?.launch?.exited))return{focused:!1,session:null,inPlace:!1,revived:l};const d=y(o)?.session??null,g=d??"";if(n.inPlace===!0){const i=p(e);i!==null&&(i.pane!==null&&i.pane!==o&&w(i.pane)&&v(i.pane),a(i.focus_id));const c=x(o);c!==null&&c.node_id!==e&&a(c.focus_id);try{Z(o,"@crtr_node","")}catch{}const _=ee(o),N=c?.node_id,L=N===void 0?T():{...T(),CRTR_ATTACH_ROSTER:N},F=I({pane:o,cwd:s.cwd,env:L,command:`crtr surface attach to ${e}`});return F&&(_!==null&&ne(_,H(s)),S(e,o,d,_)),{focused:F,session:d,inPlace:!0,revived:l}}if(n.newPane===!0){const i=p(e);i!==null&&(i.pane!==null&&w(i.pane)&&v(i.pane),a(i.focus_id));const c=A(e,g,{cwd:s.cwd,besidePane:o});return c===null?{focused:!1,session:null,inPlace:!1,revived:l}:(c.pane!==null&&B(c.pane),{focused:!0,session:c.session,inPlace:!1,revived:l})}const f=p(e);if(f!==null&&f.pane!==null)if(Y(f.pane,"@crtr_node")===e){const i=y(f.pane);if(i!==null)return q(i.session),G(i.session,i.window),R(f.pane),{focused:!0,session:i.session,inPlace:!0,revived:l};a(f.focus_id)}else a(f.focus_id);const m=A(e,g,{cwd:s.cwd,besidePane:o});return m===null?{focused:!1,session:null,inPlace:!1,revived:l}:(m.pane!==null&&B(m.pane),{focused:!0,session:m.session,inPlace:!1,revived:l})}r(he,"focus");function E(e,n){const s=p(e);s!==null&&(s.pane!==null&&s.pane!==n&&w(s.pane)&&v(s.pane),a(s.focus_id))}r(E,"tearDownNode");function ge(e,n){const s=n??p(e)?.pane??null;if(s===null||!w(s))return!1;const o=te(s);o!==null&&a(o.focus_id);const u=v(s);return ue(e),u}r(ge,"detachToBackground");function C(e){const n=P(e);return n===null||n.streaming===!0?!1:!U(n.pi_session_file)}r(C,"isEmptyNode");function ue(e,n,s=!0){return P(e)?.managed_worktree?.state==="open"||!C(e)?!1:(s&&k.teardown(e),E(e,n),O(e).deleted)}r(ue,"reapIfEmpty");function Ne(e={}){const n=e.dryRun??!1,s=$()??"",o=[];for(const u of D()){const t=u.node_id,l=P(t);if(t===s||u.status==="dead"||W(u.pi_pid)||l?.managed_worktree?.state==="open"||!C(t))continue;const d=M(t);!n&&(X(t,d,`Child closed \u2014 ${l?.name??t} (${t}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:t}),k.teardown(t),E(t),!O(t).deleted)||o.push(t)}return o}r(Ne,"reapEmptyNodes");export{ke as breakPane,je as closePane,He as currentTmux,ge as detachToBackground,qe as displayPopup,Ee as ensureSession,he as focus,te as focusByPane,p as focusOf,We as focusWindow,ye as focusedNodes,Je as getPaneOption,De as inTmux,sn as installTmuxBindings,xe as isFocused,re as listFocuses,Ie as listLivePanes,en as listLivePanesAsync,Be as openNodeWindow,A as openViewerWindow,$e as paneCurrentPath,Le as paneExists,Ce as paneLocation,Me as paneOfNode,Ye as paneOfWindow,Ve as paneRunning,Qe as piCommand,Ne as reapEmptyNodes,ue as reapIfEmpty,S as registerViewerFocus,Ke as renameWindow,Xe as respawnPaneSync,Re as selectLayout,Te as selectPane,Se as selectWindow,ze as setPaneOption,Ue as shellQuote,be as splitWindow,Ae as switchClient,E as tearDownNode,Ze as windowAlive,Ge as windowOfPane};
1
+ var V=Object.defineProperty;var r=(e,n)=>V(e,"name",{value:n,configurable:!0});import{envNodeId as $}from"../../shared/env.js";import{getNode as P,fullName as H,deleteNode as b,listNodes as D,subscribersOf as M,openFocusRow as z,closeFocusRow as a,getFocusByNode as k,getFocusByPane as x,getFocusById as J,listFocuses as Q}from"../canvas/index.js";import{nodeHasAssistantMessage as U}from"../canvas/render-source.js";import{headlessBrokerHost as R}from"./host.js";import{fanDoctrineWake as X}from"./close.js";import{paneExists as w,paneLocation as y,closePane as v,currentTmux as j,switchClient as q,selectWindow as G,selectLayout as K,selectPane as T,getPaneOption as Y,setPaneOption as Z,respawnPaneSync as I,windowOfPane as ee,renameWindow as ne}from"./tmux-driver.js";import{openViewerPane as se,viewerSplitEnv as W,waitForBrokerViewSocket as oe}from"./placement-tmux.js";import{newJobId as ie}from"./nodes.js";import{isPidAlive as h}from"../canvas/pid.js";import{splitWindow as be,breakPane as ke,selectLayout as Re,selectPane as Te,focusWindow as We,selectWindow as Se,switchClient as Ae,openNodeWindow as Be,ensureSession as Ee,paneLocation as Ce,paneExists as Le,paneRunning as Ve,paneCurrentPath as $e,currentTmux as He,inTmux as De,paneOfNode as Me,setPaneOption as ze,getPaneOption as Je,piCommand as Qe,shellQuote as Ue,respawnPaneSync as Xe,closePane as je,displayPopup as qe,windowOfPane as Ge,renameWindow as Ke,paneOfWindow as Ye,windowAlive as Ze,listLivePanes as Ie,listLivePanesAsync as en}from"./tmux-driver.js";import{installTmuxBindings as sn}from"./tmux-bindings.js";function g(e){return e===null?null:e.pane!==null&&!w(e.pane)?(a(e.focus_id),null):e}r(g,"liveOrPrune");function p(e){return g(k(e))}r(p,"focusOf");function xe(e){return p(e)!==null}r(xe,"isFocused");function te(e){return g(x(e))}r(te,"focusByPane");function ye(){return new Set(re().map(e=>e.node_id))}r(ye,"focusedNodes");function re(){const e=[];for(const n of Q())g(n)!==null&&e.push(n);return e}r(re,"listFocuses");function le(){return`f-${ie()}`}r(le,"newFocusId");function S(e,n,s,o){const u=x(n);if(u!==null)return u;const t=k(e);if(t!==null)return t;const l=le();return z(l,n,s,e),J(l)}r(S,"registerViewerFocus");function A(e,n,s={}){const o=se(e,n,s);return o===null?null:S(e,o.pane,o.session,o.window)}r(A,"openViewerWindow");function B(e){const n=y(e)?.window??null;n!==null&&K(n,"even-horizontal"),T(e)}r(B,"surfaceNewPane");async function he(e,n){const s=P(e);if(s===null)return{focused:!1,session:null,inPlace:!1,revived:!1};const o=n.pane??process.env.TMUX_PANE??j()?.pane;if(o===void 0||o==="")return{focused:!1,session:null,inPlace:!1,revived:!1};const u=h(s.pi_pid??null),t=n.revive(e),l=!u;if(!await oe(e,t?.launch?.exited))return{focused:!1,session:null,inPlace:!1,revived:l};const d=y(o)?.session??null,N=d??"";if(n.inPlace===!0){const i=p(e);i!==null&&(i.pane!==null&&i.pane!==o&&w(i.pane)&&v(i.pane),a(i.focus_id));const c=x(o);c!==null&&c.node_id!==e&&a(c.focus_id);try{Z(o,"@crtr_node","")}catch{}const _=ee(o),F=c?.node_id,L=F===void 0?W():{...W(),CRTR_ATTACH_ROSTER:F},O=I({pane:o,cwd:s.cwd,env:L,command:`crtr surface attach to ${e}`});return O&&(_!==null&&ne(_,H(s)),S(e,o,d,_)),{focused:O,session:d,inPlace:!0,revived:l}}if(n.newPane===!0){const i=p(e);i!==null&&(i.pane!==null&&w(i.pane)&&v(i.pane),a(i.focus_id));const c=A(e,N,{cwd:s.cwd,besidePane:o});return c===null?{focused:!1,session:null,inPlace:!1,revived:l}:(c.pane!==null&&B(c.pane),{focused:!0,session:c.session,inPlace:!1,revived:l})}const f=p(e);if(f!==null&&f.pane!==null)if(Y(f.pane,"@crtr_node")===e){const i=y(f.pane);if(i!==null)return q(i.session),G(i.session,i.window),T(f.pane),{focused:!0,session:i.session,inPlace:!0,revived:l};a(f.focus_id)}else a(f.focus_id);const m=A(e,N,{cwd:s.cwd,besidePane:o});return m===null?{focused:!1,session:null,inPlace:!1,revived:l}:(m.pane!==null&&B(m.pane),{focused:!0,session:m.session,inPlace:!1,revived:l})}r(he,"focus");function E(e,n){const s=p(e);s!==null&&(s.pane!==null&&s.pane!==n&&w(s.pane)&&v(s.pane),a(s.focus_id))}r(E,"tearDownNode");function ge(e,n){const s=n??p(e)?.pane??null;if(s===null||!w(s))return!1;const o=te(s);o!==null&&a(o.focus_id);const u=v(s);return ue(e),u}r(ge,"detachToBackground");function C(e){const n=P(e);return n===null||n.streaming===!0&&h(n.pi_pid)?!1:!U(n.pi_session_file)}r(C,"isEmptyNode");function ue(e,n,s=!0){return P(e)?.managed_worktree?.state==="open"||!C(e)?!1:(s&&R.teardown(e),E(e,n),b(e).deleted)}r(ue,"reapIfEmpty");function Ne(e={}){const n=e.dryRun??!1,s=$()??"",o=[];for(const u of D()){const t=u.node_id,l=P(t);if(t===s||u.status==="dead"||h(u.pi_pid)||l?.managed_worktree?.state==="open"||!C(t))continue;const d=M(t);!n&&(X(t,d,`Child closed \u2014 ${l?.name??t} (${t}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:t}),R.teardown(t),E(t),!b(t).deleted)||o.push(t)}return o}r(Ne,"reapEmptyNodes");export{ke as breakPane,je as closePane,He as currentTmux,ge as detachToBackground,qe as displayPopup,Ee as ensureSession,he as focus,te as focusByPane,p as focusOf,We as focusWindow,ye as focusedNodes,Je as getPaneOption,De as inTmux,sn as installTmuxBindings,xe as isFocused,re as listFocuses,Ie as listLivePanes,en as listLivePanesAsync,Be as openNodeWindow,A as openViewerWindow,$e as paneCurrentPath,Le as paneExists,Ce as paneLocation,Me as paneOfNode,Ye as paneOfWindow,Ve as paneRunning,Qe as piCommand,Ne as reapEmptyNodes,ue as reapIfEmpty,S as registerViewerFocus,Ke as renameWindow,Xe as respawnPaneSync,Re as selectLayout,Te as selectPane,Se as selectWindow,ze as setPaneOption,Ue as shellQuote,be as splitWindow,Ae as switchClient,E as tearDownNode,Ze as windowAlive,Ge as windowOfPane};
@@ -1 +1 @@
1
- var g=Object.defineProperty;var l=(n,e)=>g(n,"name",{value:e,configurable:!0});import{getNode as m,updateNode as P}from"../canvas/index.js";import{transition as x}from"./lifecycle.js";import{ensureDaemon as E}from"../../daemon/manage.js";import{buildLaunchSpec as v,buildLaunchSpecAsync as $}from"./launch.js";import{hasRoadmap as u,seedRoadmap as t,roadmapPath as c}from"./roadmap.js";import{readGoal as f,goalPath as k}from"./kickoff.js";function h(n,e){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);const i=e.kind??d.kind,o=e.mode??d.mode,r=e.lifecycle??d.lifecycle,a=e.profileId===void 0?d.profile_id??null:e.profileId;return{node:d,kind:i,mode:o,lifecycle:r,profileId:a,launchOpts:{lifecycle:r,hasManager:d.parent!==null,model:e.model??d.model_override??void 0,modelOverride:e.model!==void 0,modelProviderPinned:e.model===void 0?d.launch?.modelProviderPinned:void 0,modelIntent:e.model===void 0?d.launch?.modelIntent:void 0,modelExact:e.model===void 0?d.launch?.modelExact:void 0,cwd:d.cwd,profileId:a}}}l(h,"reshapeInputs");function w(n,e,d,i,o){o?.();const r=d.node.name===d.node.kind&&d.kind!==d.node.kind;return P(n,{kind:d.kind,mode:d.mode,lifecycle:d.lifecycle,profile_id:d.profileId,launch:i,...r?{name:d.kind}:{},...e.model!==void 0?{model_override:i?.model??e.model}:{}})}l(w,"persistReshape");function s(n,e={},d){const i=h(n,e);return w(n,e,i,v(i.kind,i.mode,i.launchOpts).launch,d)}l(s,"reshapeNode");async function y(n,e={},d){const i=h(n,e),{launch:o}=await $(i.kind,i.mode,i.launchOpts);return w(n,e,i,o,d)}l(y,"reshapeNodeAsync");function A(n,e={}){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);let i=!1;return{meta:s(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{},mode:"orchestrator",lifecycle:e.resident===!0?"resident":d.lifecycle},()=>{if(!u(n)){const r=f(n);t(n,r!==null&&r.trim()!==""?{goal:r.trim()}:{}),i=!0}}),roadmapWritten:i,roadmapPath:c(n),goalPath:k(n)}}l(A,"promote");async function N(n,e={}){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);let i=!1;return{meta:await y(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{},mode:"orchestrator",lifecycle:e.resident===!0?"resident":d.lifecycle},()=>{if(!u(n)){const r=f(n);t(n,r!==null&&r.trim()!==""?{goal:r.trim()}:{}),i=!0}}),roadmapWritten:i,roadmapPath:c(n),goalPath:k(n)}}l(N,"promoteAsync");async function Y(n,e={},d={}){if(m(n)===null)throw new Error(`unknown node: ${n}`);return e.promote===!0?await N(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}):(e.kind!==void 0||e.model!==void 0)&&await y(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),{...O(n,{},d),promoted:e.promote===!0}}l(Y,"requestYieldAsync");function O(n,e={},d={}){const i=d.ensure??E;if(m(n)===null)throw new Error(`unknown node: ${n}`);const r=e.kind!==void 0||e.model!==void 0;let a=!1;return e.promote===!0?(A(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),a=!0):r&&s(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),i(),x(n,"yield"),{meta:m(n),promoted:a,willRefresh:!0}}l(O,"requestYield");export{A as promote,N as promoteAsync,O as requestYield,Y as requestYieldAsync,s as reshapeNode,y as reshapeNodeAsync};
1
+ var g=Object.defineProperty;var l=(n,e)=>g(n,"name",{value:e,configurable:!0});import{getNode as m,updateNode as x}from"../canvas/index.js";import{transition as E}from"./lifecycle.js";import{ensureDaemon as P}from"../../daemon/manage.js";import{buildLaunchSpec as $,buildLaunchSpecAsync as A}from"./launch.js";import{hasRoadmap as t,seedRoadmap as u,roadmapPath as c}from"./roadmap.js";import{readGoal as f,goalPath as k}from"./kickoff.js";function h(n,e){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);const r=e.kind??d.kind,o=e.mode??d.mode,i=e.lifecycle??d.lifecycle,a=e.profileId===void 0?d.profile_id??null:e.profileId;return{node:d,kind:r,mode:o,lifecycle:i,profileId:a,launchOpts:{lifecycle:i,hasManager:d.parent!==null,model:e.model??d.model_override??void 0,modelOverride:e.model!==void 0,modelIntent:e.model===void 0?d.launch?.modelIntent:void 0,modelExact:e.model===void 0?d.launch?.modelExact:void 0,cwd:d.cwd,profileId:a}}}l(h,"reshapeInputs");function w(n,e,d,r,o){o?.();const i=d.node.name===d.node.kind&&d.kind!==d.node.kind;return x(n,{kind:d.kind,mode:d.mode,lifecycle:d.lifecycle,profile_id:d.profileId,launch:r,...i?{name:d.kind}:{},...e.model!==void 0?{model_override:r?.model??e.model}:{}})}l(w,"persistReshape");function s(n,e={},d){const r=h(n,e);return w(n,e,r,$(r.kind,r.mode,r.launchOpts).launch,d)}l(s,"reshapeNode");async function y(n,e={},d){const r=h(n,e),{launch:o}=await A(r.kind,r.mode,r.launchOpts);return w(n,e,r,o,d)}l(y,"reshapeNodeAsync");function N(n,e={}){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);let r=!1;return{meta:s(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{},mode:"orchestrator",lifecycle:e.resident===!0?"resident":d.lifecycle},()=>{if(!t(n)){const i=f(n);u(n,i!==null&&i.trim()!==""?{goal:i.trim()}:{}),r=!0}}),roadmapWritten:r,roadmapPath:c(n),goalPath:k(n)}}l(N,"promote");async function O(n,e={}){const d=m(n);if(d===null)throw new Error(`unknown node: ${n}`);let r=!1;return{meta:await y(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{},mode:"orchestrator",lifecycle:e.resident===!0?"resident":d.lifecycle},()=>{if(!t(n)){const i=f(n);u(n,i!==null&&i.trim()!==""?{goal:i.trim()}:{}),r=!0}}),roadmapWritten:r,roadmapPath:c(n),goalPath:k(n)}}l(O,"promoteAsync");async function Y(n,e={},d={}){if(m(n)===null)throw new Error(`unknown node: ${n}`);return e.promote===!0?await O(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}):(e.kind!==void 0||e.model!==void 0)&&await y(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),{...R(n,{},d),promoted:e.promote===!0}}l(Y,"requestYieldAsync");function R(n,e={},d={}){const r=d.ensure??P;if(m(n)===null)throw new Error(`unknown node: ${n}`);const i=e.kind!==void 0||e.model!==void 0;let a=!1;return e.promote===!0?(N(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),a=!0):i&&s(n,{...e.kind!==void 0?{kind:e.kind}:{},...e.model!==void 0?{model:e.model}:{}}),r(),E(n,"yield"),{meta:m(n),promoted:a,willRefresh:!0}}l(R,"requestYield");export{N as promote,O as promoteAsync,R as requestYield,Y as requestYieldAsync,s as reshapeNode,y as reshapeNodeAsync};
@@ -1,2 +1,2 @@
1
- var m=Object.defineProperty;var o=(r,e)=>m(r,"name",{value:e,configurable:!0});import{ModelRegistry as a,ModelRuntime as d}from"@earendil-works/pi-coding-agent";import{join as s}from"node:path";import{PoolCredentialStore as l}from"../pool-credential-store.js";import{readProfileEnvVars as p}from"../profiles/env-store.js";import{hasProviderCredential as c}from"../provider-credential.js";import{piAgentDir as f}from"./package-health.js";import{PROVIDER_ENV_KEYS as u}from"./spawn-env.js";const E="crtr: no provider credential; run `crtr sys setup` to log in.";async function h(r=null){const e=p(r);if(Object.values(u).some(n=>(e[n]??process.env[n])?.trim()))return!0;const t=f(),i=await d.create({credentials:new l(s(t,"auth.json")),modelsPath:s(t,"models.json")});return c(i,new a(i))}o(h,"hasConfiguredProviderCredential");function j(){process.stderr.write(`${E}
2
- `),process.exit(1)}o(j,"exitForMissingProviderCredential");export{E as NO_PROVIDER_CREDENTIAL_MESSAGE,j as exitForMissingProviderCredential,h as hasConfiguredProviderCredential};
1
+ var m=Object.defineProperty;var o=(r,e)=>m(r,"name",{value:e,configurable:!0});import{ModelRegistry as p,ModelRuntime as a}from"@earendil-works/pi-coding-agent";import{join as n}from"node:path";import{PoolCredentialStore as c}from"../pool-credential-store.js";import{readProfileEnvVars as d}from"../profiles/env-store.js";import{hasProviderCredential as l}from"../provider-credential.js";import{piAgentDir as f}from"./package-health.js";import{secretsDir as u}from"../layout.js";import{PROVIDER_ENV_KEYS as E}from"./spawn-env.js";const v="crtr: no provider credential; run `crtr sys setup` to log in.";async function w(r=null){const e=d(r);if(Object.values(E).some(i=>(e[i]??process.env[i])?.trim()))return!0;const s=f(),t=await a.create({credentials:new c(n(u(),"auth.json")),modelsPath:n(s,"models.json")});return l(t,new p(t))}o(w,"hasConfiguredProviderCredential");function M(){process.stderr.write(`${v}
2
+ `),process.exit(1)}o(M,"exitForMissingProviderCredential");export{v as NO_PROVIDER_CREDENTIAL_MESSAGE,M as exitForMissingProviderCredential,w as hasConfiguredProviderCredential};
@@ -0,0 +1,2 @@
1
+ export declare function holdRecovery(nodeId: string): () => void;
2
+ export declare function isRecoveryHeld(nodeId: string): boolean;
@@ -0,0 +1 @@
1
+ var o=Object.defineProperty;var t=(e,n)=>o(e,"name",{value:n,configurable:!0});const r=new Set;function d(e){return r.add(e),()=>{r.delete(e)}}t(d,"holdRecovery");function l(e){return r.has(e)}t(l,"isRecoveryHeld");export{d as holdRecovery,l as isRecoveryHeld};
@@ -1 +1 @@
1
- var y=Object.defineProperty;var i=(e,t)=>y(e,"name",{value:t,configurable:!0});import{readdirSync as h,readFileSync as _,statSync as v}from"node:fs";import{join as w}from"node:path";import{abortExecution as R,beginExecution as b,getNode as m,setPresence as E,setFocusOccupant as S,fullName as g,recordExecutionPid as k,recordLaunch as x}from"../canvas/index.js";import{reportsDir as T}from"../canvas/paths.js";import{pushFinal as B}from"../feed/feed.js";import{spawnNode as N,rootOfSpine as O}from"./nodes.js";import{buildLaunchSpecAsync as P,buildPiArgv as C}from"./launch.js";import{focusOf as D,respawnPaneSync as F,setPaneOption as M}from"./placement.js";import{waitForBrokerViewSocket as z,viewerSplitEnv as A}from"./placement-tmux.js";import{headlessBrokerHost as p}from"./host.js";import{boundFleet as L}from"./fleet.js";import{transition as U}from"./lifecycle.js";import{ensureDaemon as H}from"../../daemon/manage.js";import{invokeBirthLifecycleHooks as V}from"./spawn.js";function X(e){try{const t=T(e),n=h(t).filter(o=>o.endsWith(".md"));if(n.length===0)return"";let r="",a=-1;for(const o of n){const c=v(w(t,o)).mtimeMs;c>a&&(a=c,r=o)}const l=_(w(t,r),"utf8"),s=/^---\n[\s\S]*?\n---\n/.exec(l);return(s!==null?l.slice(s[0].length):l).trim()}catch{return""}}i(X,"lastReportBody");async function de(e,t){const n=m(e);if(n===null)return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const r=t??process.env.TMUX_PANE;if(r===void 0||r==="")return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const a=D(e);try{H()}catch{}const{launch:l}=await P("general","base",{lifecycle:"resident",hasManager:!1,cwd:n.cwd,profileId:n.profile_id}),s=X(e)||`Closed via recycle \u2014 no final summary was authored by ${n.name}.`;let o=[],c=!1;const d=await N({kind:"general",mode:"base",lifecycle:"resident",cwd:n.cwd,name:"general",parent:null,replaces:e,profile_id:n.profile_id,launch:l,beforeCreate:i(async()=>{try{o=(await B(e,s)).deliveredTo,c=!0}catch{}},"beforeCreate")}),u=m(d.node_id);await V(u);const f=C(u);if(f.env={...f.env,CRTR_SUBTREE:O(d.node_id)},!await $(u,f))return{recycled:!1,finalized:c,newRoot:d.node_id,delivered:o};try{p.teardown(e)}catch{}try{E(e,{pane:null,window:null,tmux_session:null})}catch{}if(a!==null)try{S(a.focus_id,d.node_id)}catch{}return{recycled:W(u,r),finalized:c,newRoot:d.node_id,delivered:o}}i(de,"recycleNode");async function $(e,t){const n=b(e.node_id,{daemonEpoch:L().epoch()});t.env={...t.env,CRTR_EXECUTION_ID:n};let r;try{if(r=p.launch(e.node_id,t,{cwd:e.cwd,name:g(e),resuming:!1}),r.pid===null)throw new Error("broker host returned no pid");if(x(e.node_id,new Date().toISOString()),k(n,e.node_id,r.pid)==="shutdown")throw new Error("broker execution was superseded");if(await z(e.node_id,r.exited))return!0}catch{R(n,{reason:"launch_failed"})}try{j(e.node_id)}catch{}try{p.teardown(e.node_id)}catch{}return!1}i($,"launchRecycledBroker");function j(e){const t=m(e);(t?.status==="active"||t?.status==="idle")&&U(e,"crash")}i(j,"transitionReplacementToDead");function W(e,t){try{M(t,"@crtr_node","")}catch{}return F({pane:t,cwd:e.cwd,env:A(),command:`crtr surface attach to ${e.node_id}`})}i(W,"respawnRecycledViewer");export{de as recycleNode};
1
+ var y=Object.defineProperty;var c=(e,t)=>y(e,"name",{value:t,configurable:!0});import{readdirBeneath as h,readFileBeneath as _,statBeneath as v}from"../spaces/open-beneath.js";import{join as w}from"node:path";import{abortExecution as g,beginExecution as R,getNode as m,setPresence as b,setFocusOccupant as E,fullName as k,recordExecutionPid as S,recordLaunch as x}from"../canvas/index.js";import{nodeAgentDir as B,reportsDir as T}from"../canvas/node-agent-paths.js";import{pushFinal as D}from"../feed/feed.js";import{spawnNode as F,rootOfSpine as N}from"./nodes.js";import{buildLaunchSpecAsync as O,buildPiArgv as P}from"./launch.js";import{focusOf as C,respawnPaneSync as A,setPaneOption as M}from"./placement.js";import{waitForBrokerViewSocket as z,viewerSplitEnv as L}from"./placement-tmux.js";import{headlessBrokerHost as p}from"./host.js";import{boundFleet as U}from"./fleet.js";import{transition as H}from"./lifecycle.js";import{ensureDaemon as V}from"../../daemon/manage.js";import{invokeBirthLifecycleHooks as X}from"./spawn.js";function $(e){try{const t=B(e),n=T(e),o=h(t,n).filter(r=>r.isFile()).map(r=>r.name).filter(r=>r.endsWith(".md"));if(o.length===0)return"";let l="",s=-1;for(const r of o){const i=v(t,w(n,r)).mtimeMs;i>s&&(s=i,l=r)}const d=_(t,w(n,l)).toString("utf8"),a=/^---\n[\s\S]*?\n---\n/.exec(d);return(a!==null?d.slice(a[0].length):d).trim()}catch{return""}}c($,"lastReportBody");async function se(e,t){const n=m(e);if(n===null)return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const o=t??process.env.TMUX_PANE;if(o===void 0||o==="")return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const l=C(e);try{V()}catch{}const{launch:s}=await O("general","base",{lifecycle:"resident",hasManager:!1,cwd:n.cwd,profileId:n.profile_id}),d=$(e)||`Closed via recycle \u2014 no final summary was authored by ${n.name}.`;let a=[],r=!1;const i=await F({kind:"general",mode:"base",lifecycle:"resident",cwd:n.cwd,name:"general",parent:null,replaces:e,profile_id:n.profile_id,launch:s,beforeCreate:c(async()=>{try{a=(await D(e,d)).deliveredTo,r=!0}catch{}},"beforeCreate")}),u=m(i.node_id);await X(u);const f=P(u);if(f.env={...f.env,CRTR_SUBTREE:N(i.node_id)},!await j(u,f))return{recycled:!1,finalized:r,newRoot:i.node_id,delivered:a};try{p.teardown(e)}catch{}try{b(e,{pane:null,window:null,tmux_session:null})}catch{}if(l!==null)try{E(l.focus_id,i.node_id)}catch{}return{recycled:q(u,o),finalized:r,newRoot:i.node_id,delivered:a}}c(se,"recycleNode");async function j(e,t){const n=R(e.node_id,{daemonEpoch:U().epoch()});t.env={...t.env,CRTR_EXECUTION_ID:n};let o;try{if(o=await p.launch(e.node_id,t,{cwd:e.cwd,name:k(e),resuming:!1}),o.pid===null)throw new Error("broker host returned no pid");if(x(e.node_id,new Date().toISOString()),S(n,e.node_id,o.pid)==="shutdown")throw new Error("broker execution was superseded");if(await z(e.node_id,o.exited))return!0}catch{g(n,{reason:"launch_failed"})}try{W(e.node_id)}catch{}try{p.teardown(e.node_id)}catch{}return!1}c(j,"launchRecycledBroker");function W(e){const t=m(e);(t?.status==="active"||t?.status==="idle")&&H(e,"crash")}c(W,"transitionReplacementToDead");function q(e,t){try{M(t,"@crtr_node","")}catch{}return A({pane:t,cwd:e.cwd,env:L(),command:`crtr surface attach to ${e.node_id}`})}c(q,"respawnRecycledViewer");export{se as recycleNode};
@@ -1 +1 @@
1
- var s=Object.defineProperty;var n=(e,t)=>s(e,"name",{value:t,configurable:!0});import{join as c}from"node:path";import{clearFinalReportIfMatches as l,getFinalReport as p,getNode as f,reportsDir as u,updateNode as h}from"../canvas/index.js";import{InputError as a}from"../io.js";import{transition as m}from"./lifecycle.js";function o(e){return p(e)}n(o,"currentFinalReport");function d(e,t){const r=c(u(e),t);throw new a({error:"node_finalized",message:`${e} already submitted its canonical final result (${r}) \u2014 reviving it now would hand it a mandate it can never finish, since a second \`push final\` always errors against an already-latched node.`,next:`Re-run this exact command with --reopen to clear ${e}'s spent latch and re-task it in place.`})}n(d,"throwNodeFinalized");function w(e){throw new a({error:"not_finalized",message:`${e} is not finalized \u2014 --reopen has nothing to clear.`,next:"Drop --reopen."})}n(w,"throwNotFinalized");function R(e){const t=o(e);t!==null&&d(e,t)}n(R,"assertNotFinalized");function g(e){const t=o(e);return t===null&&w(e),t}n(g,"assertFinalizedForReopen");function x(e,t){if(!l(e,t))throw new a({error:"reopen_latch_changed",message:`${e}'s finalization latch changed since it was last inspected \u2014 a concurrent --reopen (or a fresh push final) already moved it, so clearing it now would risk erasing a newer canonical result.`,next:"Re-run this exact command \u2014 it will re-inspect the current state before acting."})}n(x,"commitReopen");function F(e,t){const r=o(e);h(e,{lifecycle:"resident"});const i=f(e);return i!==null&&(i.status==="done"||i.status==="canceled"||i.status==="dead")&&m(e,"revive"),r!==null&&x(e,t??r),r}n(F,"commitReopenResident");function _(e,t){if(t){const r=g(e);F(e,r);return}R(e)}n(_,"assertReopenGate");export{g as assertFinalizedForReopen,R as assertNotFinalized,_ as assertReopenGate,x as commitReopen,F as commitReopenResident};
1
+ var s=Object.defineProperty;var n=(e,t)=>s(e,"name",{value:t,configurable:!0});import{join as c}from"node:path";import{clearFinalReportIfMatches as l,getFinalReport as p,getNode as f,updateNode as u}from"../canvas/index.js";import{reportsDir as m}from"../canvas/node-agent-paths.js";import{InputError as a}from"../io.js";import{transition as h}from"./lifecycle.js";function o(e){return p(e)}n(o,"currentFinalReport");function d(e,t){const r=c(m(e),t);throw new a({error:"node_finalized",message:`${e} already submitted its canonical final result (${r}) \u2014 reviving it now would hand it a mandate it can never finish, since a second \`push final\` always errors against an already-latched node.`,next:`Re-run this exact command with --reopen to clear ${e}'s spent latch and re-task it in place.`})}n(d,"throwNodeFinalized");function w(e){throw new a({error:"not_finalized",message:`${e} is not finalized \u2014 --reopen has nothing to clear.`,next:"Drop --reopen."})}n(w,"throwNotFinalized");function R(e){const t=o(e);t!==null&&d(e,t)}n(R,"assertNotFinalized");function g(e){const t=o(e);return t===null&&w(e),t}n(g,"assertFinalizedForReopen");function x(e,t){if(!l(e,t))throw new a({error:"reopen_latch_changed",message:`${e}'s finalization latch changed since it was last inspected \u2014 a concurrent --reopen (or a fresh push final) already moved it, so clearing it now would risk erasing a newer canonical result.`,next:"Re-run this exact command \u2014 it will re-inspect the current state before acting."})}n(x,"commitReopen");function F(e,t){const r=o(e);u(e,{lifecycle:"resident"});const i=f(e);return i!==null&&(i.status==="done"||i.status==="canceled"||i.status==="dead")&&h(e,"revive"),r!==null&&x(e,t??r),r}n(F,"commitReopenResident");function b(e,t){if(t){const r=g(e);F(e,r);return}R(e)}n(b,"assertReopenGate");export{g as assertFinalizedForReopen,R as assertNotFinalized,b as assertReopenGate,x as commitReopen,F as commitReopenResident};
@@ -1 +1 @@
1
- var y=Object.defineProperty;var l=(e,t)=>y(e,"name",{value:t,configurable:!0});import{getNode as p,beginExecution as E,recordExecutionPid as S,abortExecution as h,bindSession as B,recordLaunch as P,fullName as v,liveExecutionForNode as b,closeFocusRow as F,view as N}from"../canvas/index.js";import{transition as a}from"./lifecycle.js";import{headlessBrokerHost as k,requestBrokerTeardown as R}from"./host.js";import{boundFleet as g}from"./fleet.js";import{tearDownNode as O,focusOf as V,registerViewerFocus as D,respawnPaneSync as T,windowOfPane as C,renameWindow as L}from"./placement.js";import{viewerSplitEnv as q,waitForBrokerViewSocket as A}from"./placement-tmux.js";import{buildLaunchSpecAsync as H,buildPiArgv as M}from"./launch.js";import{spawnNode as U,rootOfSpine as I}from"./nodes.js";import{invokeBirthLifecycleHooks as W}from"./spawn.js";function X(e){const t=[];for(const o of N(e))try{a(o,"cancel",{reason:"closed"}),R(o),O(o),t.push(o)}catch{}return t}l(X,"reapDescendants");async function re(e,t={}){const o=t.launchBroker??k.launch,s=t.waitForViewSocket??A,m=t.respawnViewer??T,c=t.teardownBroker??k.teardown,r=p(e);if(r===null||r.parent!=null||r.status==="done")return null;const d=V(e),{launch:x}=await H(r.kind,"base",{lifecycle:"resident",hasManager:!1,model:r.model_override??void 0,modelProviderPinned:r.launch?.modelProviderPinned,modelIntent:r.launch?.modelIntent,modelExact:r.launch?.modelExact,cwd:r.cwd,profileId:r.profile_id}),n=await U({kind:r.kind,mode:"base",lifecycle:"resident",cwd:r.cwd,name:r.kind,parent:null,replaces:e,profile_id:r.profile_id,launch:x,modelOverride:r.model_override??void 0});await W(n);const u=M(n,{});u.env={...u.env,CRTR_SUBTREE:I(n.node_id)};const f=E(n.node_id,{daemonEpoch:g().epoch()});u.env={...u.env,CRTR_EXECUTION_ID:f};let w;try{w=o(n.node_id,u,{cwd:r.cwd,name:v(n),resuming:!1})}catch(i){throw h(f,{reason:"launch_failed"}),a(n.node_id,"crash"),i}if(w.pid==null)return h(f,{reason:"launch_failed"}),a(n.node_id,"crash"),null;if(P(n.node_id,new Date().toISOString()),S(f,n.node_id,w.pid)==="shutdown"){h(f,{reason:"superseded"});try{c(n.node_id)}catch{}return a(n.node_id,"crash"),null}let _=!1;try{_=await s(n.node_id,w.exited)}catch{}if(!_){const i=p(n.node_id);(i?.status==="active"||i?.status==="idle")&&a(n.node_id,"crash");try{c(n.node_id)}catch{}return null}if(X(e),a(e,"finish"),d?.pane!=null){F(d.focus_id),m({pane:d.pane,cwd:r.cwd,env:q(),command:`crtr surface attach to ${n.node_id}`});const i=C(d.pane);i!==null&&L(i,v(n)),D(n.node_id,d.pane,d.session,i)}return c(e),{newNodeId:n.node_id}}l(re,"relaunchRoot");function $(e,t,o){const s=p(e),m={reaped:[],detached:[],reset:!1};if(s===null||s.parent==null)return m;if(t!==void 0){const c=b(e);c!==null&&B(e,{executionId:c.executionId,sessionId:t,transcriptPath:o??null})}return m}l($,"resetRoot");function te(e,t,o){return p(e)===null?{path:"noop"}:($(e,t,o),{path:"reset-child"})}l(te,"handleNewSession");function oe(e,t){if(t!=="quit")return!1;const o=p(e);return o===null||o.status!=="active"&&o.status!=="idle"||o.intent!=null?!1:(a(e,"finish"),!0)}l(oe,"markCleanExitDone");export{te as handleNewSession,oe as markCleanExitDone,X as reapDescendants,re as relaunchRoot,$ as resetRoot};
1
+ var y=Object.defineProperty;var l=(e,t)=>y(e,"name",{value:t,configurable:!0});import{getNode as p,beginExecution as E,recordExecutionPid as S,abortExecution as h,bindSession as B,recordLaunch as b,fullName as k,liveExecutionForNode as F,closeFocusRow as N,view as R}from"../canvas/index.js";import{transition as a}from"./lifecycle.js";import{headlessBrokerHost as v,requestBrokerTeardown as g}from"./host.js";import{boundFleet as O}from"./fleet.js";import{tearDownNode as V,focusOf as D,registerViewerFocus as P,respawnPaneSync as T,windowOfPane as C,renameWindow as L}from"./placement.js";import{viewerSplitEnv as q,waitForBrokerViewSocket as A}from"./placement-tmux.js";import{buildLaunchSpecAsync as H,buildPiArgv as M}from"./launch.js";import{spawnNode as U,rootOfSpine as I}from"./nodes.js";import{invokeBirthLifecycleHooks as W}from"./spawn.js";function X(e){const t=[];for(const o of R(e))try{a(o,"cancel",{reason:"closed"}),g(o),V(o),t.push(o)}catch{}return t}l(X,"reapDescendants");async function te(e,t={}){const o=t.launchBroker??v.launch,s=t.waitForViewSocket??A,w=t.respawnViewer??T,c=t.teardownBroker??v.teardown,r=p(e);if(r===null||r.parent!=null||r.status==="done")return null;const d=D(e),{launch:x}=await H(r.kind,"base",{lifecycle:"resident",hasManager:!1,model:r.model_override??void 0,modelIntent:r.launch?.modelIntent,modelExact:r.launch?.modelExact,cwd:r.cwd,profileId:r.profile_id}),n=await U({kind:r.kind,mode:"base",lifecycle:"resident",cwd:r.cwd,name:r.kind,parent:null,replaces:e,profile_id:r.profile_id,launch:x,modelOverride:r.model_override??void 0});await W(n);const u=M(n,{});u.env={...u.env,CRTR_SUBTREE:I(n.node_id)};const f=E(n.node_id,{daemonEpoch:O().epoch()});u.env={...u.env,CRTR_EXECUTION_ID:f};let m;try{m=await o(n.node_id,u,{cwd:r.cwd,name:k(n),resuming:!1})}catch(i){throw h(f,{reason:"launch_failed"}),a(n.node_id,"crash"),i}if(m.pid==null)return h(f,{reason:"launch_failed"}),a(n.node_id,"crash"),null;if(b(n.node_id,new Date().toISOString()),S(f,n.node_id,m.pid)==="shutdown"){h(f,{reason:"superseded"});try{c(n.node_id)}catch{}return a(n.node_id,"crash"),null}let _=!1;try{_=await s(n.node_id,m.exited)}catch{}if(!_){const i=p(n.node_id);(i?.status==="active"||i?.status==="idle")&&a(n.node_id,"crash");try{c(n.node_id)}catch{}return null}if(X(e),a(e,"finish"),d?.pane!=null){N(d.focus_id),w({pane:d.pane,cwd:r.cwd,env:q(),command:`crtr surface attach to ${n.node_id}`});const i=C(d.pane);i!==null&&L(i,k(n)),P(n.node_id,d.pane,d.session,i)}return c(e),{newNodeId:n.node_id}}l(te,"relaunchRoot");function $(e,t,o){const s=p(e),w={reaped:[],detached:[],reset:!1};if(s===null||s.parent==null)return w;if(t!==void 0){const c=F(e);c!==null&&B(e,{executionId:c.executionId,sessionId:t,transcriptPath:o??null})}return w}l($,"resetRoot");function re(e,t,o){return p(e)===null?{path:"noop"}:($(e,t,o),{path:"reset-child"})}l(re,"handleNewSession");function oe(e,t){if(t!=="quit")return!1;const o=p(e);return o===null||o.status!=="active"&&o.status!=="idle"||o.intent!=null?!1:(a(e,"finish"),!0)}l(oe,"markCleanExitDone");export{re as handleNewSession,oe as markCleanExitDone,X as reapDescendants,te as relaunchRoot,$ as resetRoot};
@@ -45,7 +45,7 @@ export interface ReviveResult {
45
45
  resumed: boolean;
46
46
  /** Launch handle for the detached broker, so callers can fail fast on its real
47
47
  * exit before the socket appears. */
48
- launch?: ReturnType<typeof headlessBrokerHost.launch>;
48
+ launch?: Awaited<ReturnType<typeof headlessBrokerHost.launch>>;
49
49
  /** Reads a fatal launch fault recorded by THIS revive attempt, scoped via
50
50
  * `beginBootFaultAttempt` at the exact clear-then-launch boundary below.
51
51
  * Present only when a fresh launch actually happened (absent on the
@@ -1,4 +1,3 @@
1
- var G=Object.defineProperty;var s=(e,r)=>G(e,"name",{value:r,configurable:!0});import{existsSync as p,readFileSync as j}from"node:fs";import{isAbsolute as M}from"node:path";import{findNodeBySessionFile as C,getNode as N,updateNode as _,beginExecution as W,recordExecutionPid as J,abortExecution as y,endLiveExecution as V,unbindSession as F,recordLaunch as X,setFrozen as Y,clearFrozen as q,fullName as D,subscribersOf as Q}from"../canvas/index.js";import{emitEvent as Z}from"../events/emit.js";import{cancelCronsOnWake as I}from"../canvas/crons.js";import{isParked as ee,transition as g}from"./lifecycle.js";import{fanDoctrineWake as re}from"./close.js";import{InputError as b}from"../io.js";import{buildPiArgv as m}from"./launch.js";import{buildReviveKickoff as ie,drainBearings as ne,hasRetainedReports as oe,readGoal as R,readYieldMessage as te,RUNTIME_RESTART_CONTINUATION as se}from"./kickoff.js";import{readRoadmap as O}from"./roadmap.js";import{encodeKickoffOrigin as le,KICKOFF_ORIGIN_ENV as ce}from"./stamp/protocol.js";import{headlessBrokerHost as P}from"./host.js";import{boundFleet as A,brokerCapReached as ue,brokerThresholdsForDaemon as B}from"./fleet.js";import{beginBootFaultAttempt as ae,clearFault as fe}from"../canvas/recovery.js";import{clearContextExposureState as T,initializeForkContextExposure as pe}from"../substrate/injected-store.js";import{rootOfSpine as he}from"./nodes.js";import{isReviewCompanionBound as ve}from"../review/companion.js";import{assertProfileActive as we}from"../profiles/manifest.js";import{isPidAlive as de}from"../canvas/pid.js";import{crtrHome as me,contextDir as ke,ensureNodeDirs as _e,jobDir as ye,nodeDir as ge,reportsDir as be}from"../canvas/paths.js";import{discoverLifecycleHookRegistry as Re}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as xe}from"../command-hooks/transport/exec-lifecycle.js";function Ee(e,r){const i=e.pi_session_file;return i==null||i===""||!p(i)?{}:r?{resumeSessionPath:i}:{resumeSessionPath:i,newCycle:!0}}s(Ee,"resumeArgs");function $e(e){try{for(const r of j(e,"utf8").split(`
2
- `)){if(r.trim()==="")continue;const i=JSON.parse(r);if(i.type==="session")return typeof i.cwd!="string"||p(i.cwd)}}catch{}return!0}s($e,"sessionCwdExists");function Se(e,r,i){const n=r.pi_session_file;if(n==null||n===""||!p(n))return{};const t=C(n);return t!==null&&t.node_id!==e&&de(t.pi_pid)?{}:$e(n)?Ee(r,i):{}}s(Se,"resumableSessionArgs");function Ce(e){return O(e)===null&&te(e)===null&&!oe(e)}s(Ce,"isUnstartedBirth");function er(e){const r=R(e);if(r!==null&&r.trim()!=="")return!0;const i=O(e);return i!==null&&i.trim()!==""}s(er,"hasFreshGroundState");async function rr(e,r){const i=await z(e,r,!0);if(i.parked)throw new Error(`reviveNode: internal parked decision for activating revive ${e}`);return i.result}s(rr,"reviveNode");async function ir(e,r,i){return z(e,r,i)}s(ir,"decideAttachRevive");async function z(e,r,i){let n=N(e);if(n===null)throw new Error(`reviveNode: unknown node ${e}`);if(n=N(e)??n,n.final_report!==null)throw new Error(`reviveNode: refusing to revive ${e} \u2014 its finalization latch is set (final_report=${n.final_report}). A final landed between the caller's reopen-gate check and this revive; re-run with --reopen if this retask is still wanted.`);we(n.profile_id);const t=A();if(t.has(e))return g(e,n.intent==="refresh"?"refresh-launch":"revive"),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(t.isClaimed(e))return{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(!i&&n.lifecycle==="resident"&&ee(n))return{parked:!0};if(!t.reserveSlot(e)){if(r.capacity==="refuse")throw ue(B().automaticReviveCap,t.size());return n.frozen_at==null&&(Y(e,new Date().toISOString()),V(e,{reason:"frozen"}),Z({level:"info",event:"broker.frozen",node_id:e,fields:{live_count:t.size(),hard_cap:B().automaticReviveCap}})),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"frozen"}}}try{return{parked:!1,result:await Ne(e,n,r)}}finally{t.releaseReservation(e)}}s(z,"decideRevive");async function Ne(e,r,i){if(!p(r.cwd)){const h=r.fork_from!=null?`Restore ${r.cwd}, then revive the fork normally with \`crtr node lifecycle revive ${e}\`.`:r.managed_worktree?.state==="open"?"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon recovery.":`Recreate ${r.cwd}, or repair it with \`crtr node config --cwd <path> --node ${e}\`; durable node work resumes in a fresh conversation. Then retry \`crtr node lifecycle revive ${e}\`.`;throw new b({error:"cwd_missing",message:`${e} cannot be revived \u2014 its recorded cwd no longer exists: ${r.cwd}`,next:h})}r.host_kind!=="broker"&&(_(e,{host_kind:"broker"}),r.host_kind="broker"),r.review_binding!=null&&!ve(e)&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(F(e),r.pi_session_id=null,r.pi_session_file=null);const t=r.fork_from!=null&&r.pi_session_id==null,c=r.fork_source_file;if(t&&(typeof c!="string"||!M(c)))throw new b({error:"fork_source_invalid",message:`${e} cannot be revived \u2014 its resolved fork source file is missing or invalid.`,next:`Restore the node's fork source metadata, then retry \`crtr node lifecycle revive ${e}\`.`});const f=t&&typeof c=="string";if(f&&!p(c))throw new b({error:"fork_from_missing",message:`${e} cannot be revived \u2014 its fork source no longer exists: ${c}`,next:`Restore ${c}, or update the node's fork source, then retry \`crtr node lifecycle revive ${e}\`.`});const u=W(e,{daemonEpoch:A().epoch()});try{r.cycles=(r.cycles??0)+1,_(e,{cycles:r.cycles});const U=r.intent==="refresh"||r.cycle_pending===!0?!1:i.resume,v=f?{}:Se(e,r,U),w=v.resumeSessionPath!==void 0,x=w&&v.newCycle===!0,k=w&&!x,E=!w&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&Ce(e),H=f||E,$=r.cycle_pending===!0||x;_(e,{cycle_pending:$}),r.cycle_pending=$,!f&&!w&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(F(e),r.pi_session_id=null,r.pi_session_file=null);let l,a=null;const S=s(()=>({type:"runtime",kind:"kickoff",...r.spawned_by!=null&&r.spawned_by!==""?{spawnedBy:r.spawned_by}:{}}),"birthOrigin");if(f){const o=R(e);l=m(r,{forkFrom:c,...o!=null&&o!==""?{prompt:o}:{}}),o!=null&&o!==""&&(a=S()),pe(e,C(c)?.node_id??null)}else if(k)l=m(r,{...v,...i.wakeReason==="runtime-restart-abort"?{prompt:se}:{}}),i.wakeReason==="runtime-restart-abort"&&(a={type:"runtime",kind:"restart-continuation"});else if(E){const o=R(e)?.trim();l=m(r,o!==void 0&&o!==""?{prompt:o}:{}),o!==void 0&&o!==""&&(a=S()),T(e)}else{const o=ne(r,u);l=m(r,{...v,prompt:ie(r,o,i.wakeReason==="runtime-restart-abort"?void 0:i.wakeReason)}),a=i.wakeReason!==void 0&&i.wakeReason!=="runtime-restart-abort"?{type:"runtime",kind:"wake",wake:i.wakeReason}:{type:"runtime",kind:"revive",cycle:r.cycles??0},T(e)}l.env={...l.env,CRTR_SUBTREE:he(e)},a!==null&&(l.env[ce]=le(a)),g(e,r.intent==="refresh"?"refresh-launch":"revive"),fe(e,{preserveEpisode:!0});const K=ae(e);i.recovery!==!0&&I(e),_e(e);const L=Re(r.cwd,r.profile_id).plans.get("node:start")??[];await xe(L,{node:{id:e,name:r.name,kind:r.kind,mode:r.mode,lifecycle:r.lifecycle,cwd:r.cwd,nodeDir:ge(e),contextDir:ke(e),jobDir:ye(e),reportsDir:be(e)},runtime:{isBirth:H,canvasHome:me(),profile:r.profile_id??null}}),l.env={...l.env,CRTR_EXECUTION_ID:u};let d;try{if(d=P.launch(e,l,{cwd:r.cwd,name:D(r),resuming:k}),d.pid===null)throw new Error(`broker host returned no pid for ${e}`)}catch(o){try{g(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:o instanceof Error?o.message:String(o)}}}),re(e,Q(e),`Child crashed \u2014 ${D(r)} (${e}) failed to relaunch and is now dead: ${o.message}
1
+ var W=Object.defineProperty;var s=(e,r)=>W(e,"name",{value:r,configurable:!0});import{existsSync as F}from"node:fs";import{conversationIdFromPath as _,conversationStore as k,ConversationNotFoundError as D}from"../conversation-store/index.js";import{isAbsolute as J}from"node:path";import{findNodeBySessionFile as V,getNode as g,updateNode as y,beginExecution as X,recordExecutionPid as Y,abortExecution as b,endLiveExecution as q,unbindSession as O,recordLaunch as Q,setFrozen as Z,clearFrozen as I,fullName as P,subscribersOf as ee}from"../canvas/index.js";import{emitEvent as re}from"../events/emit.js";import{cancelCronsOnWake as ie}from"../canvas/crons.js";import{isParked as ne,transition as R}from"./lifecycle.js";import{fanDoctrineWake as oe}from"./close.js";import{InputError as E}from"../io.js";import{buildPiArgv as w}from"./launch.js";import{buildReviveKickoff as te,drainBearings as se,hasRetainedReports as le,readGoal as x,readYieldMessage as ce,RUNTIME_RESTART_CONTINUATION as ae}from"./kickoff.js";import{readRoadmap as A}from"./roadmap.js";import{encodeKickoffOrigin as ue,KICKOFF_ORIGIN_ENV as fe}from"./stamp/protocol.js";import{headlessBrokerHost as T}from"./host.js";import{boundFleet as B,brokerCapReached as pe,brokerThresholdsForDaemon as z}from"./fleet.js";import{beginBootFaultAttempt as he,clearFault as de}from"../canvas/recovery.js";import{clearContextExposureState as U,initializeForkContextExposure as ve}from"../substrate/injected-store.js";import{forkSourceNode as we,rootOfSpine as me}from"./nodes.js";import{isReviewCompanionBound as _e}from"../review/companion.js";import{assertProfileActive as ke}from"../profiles/manifest.js";import{isPidAlive as ge}from"../canvas/pid.js";import{crtrHome as ye,jobDir as be}from"../canvas/paths.js";import{contextDir as Re,ensureNodeDirs as Ee,nodeAgentDir as xe,reportsDir as Se}from"../canvas/node-agent-paths.js";import{discoverLifecycleHookRegistry as $e}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as Ce}from"../command-hooks/transport/exec-lifecycle.js";function Ne(e,r){const i=e.pi_session_file,n=i?_(i):null;if(n===null)return{};try{const t=k().header(n);return r?{resumeSessionPath:t.path}:{resumeSessionPath:t.path,newCycle:!0}}catch(t){if(t instanceof D)return{};throw t}}s(Ne,"resumeArgs");function H(e){const r=_(e);if(r===null)return!1;try{return k().header(r),!0}catch(i){if(i instanceof D)return!1;throw i}}s(H,"conversationExists");function Fe(e){const r=_(e);if(r===null)return!0;const i=k().header(r).header.cwd;return typeof i!="string"||F(i)}s(Fe,"sessionCwdExists");function De(e,r,i){const n=r.pi_session_file;if(!n||!H(n))return{};const t=V(n);return t!==null&&t.node_id!==e&&ge(t.pi_pid)?{}:Fe(n)?Ne(r,i):{}}s(De,"resumableSessionArgs");function Oe(e){return A(e)===null&&ce(e)===null&&!le(e)}s(Oe,"isUnstartedBirth");function sr(e){const r=x(e);if(r!==null&&r.trim()!=="")return!0;const i=A(e);return i!==null&&i.trim()!==""}s(sr,"hasFreshGroundState");async function lr(e,r){const i=await K(e,r,!0);if(i.parked)throw new Error(`reviveNode: internal parked decision for activating revive ${e}`);return i.result}s(lr,"reviveNode");async function cr(e,r,i){return K(e,r,i)}s(cr,"decideAttachRevive");async function K(e,r,i){let n=g(e);if(n===null)throw new Error(`reviveNode: unknown node ${e}`);if(n=g(e)??n,n.run_id&&g(n.run_id)?.deleting_at)throw new Error("run is deleting");if(n.final_report!==null)throw new Error(`reviveNode: refusing to revive ${e} \u2014 its finalization latch is set (final_report=${n.final_report}). A final landed between the caller's reopen-gate check and this revive; re-run with --reopen if this retask is still wanted.`);ke(n.profile_id);const t=B();if(t.has(e))return R(e,n.intent==="refresh"?"refresh-launch":"revive"),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(t.isClaimed(e))return{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"already-live"}};if(!i&&n.lifecycle==="resident"&&ne(n))return{parked:!0};if(!t.reserveSlot(e)){if(r.capacity==="refuse")throw pe(z().automaticReviveCap,t.size());return n.frozen_at==null&&(Z(e,new Date().toISOString()),q(e,{reason:"frozen"}),re({level:"info",event:"broker.frozen",node_id:e,fields:{live_count:t.size(),hard_cap:z().automaticReviveCap}})),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"frozen"}}}try{return{parked:!1,result:await Pe(e,n,r)}}finally{t.releaseReservation(e)}}s(K,"decideRevive");async function Pe(e,r,i){if(!F(r.cwd)){const p=r.fork_from!=null?`Restore ${r.cwd}, then revive the fork normally with \`crtr node lifecycle revive ${e}\`.`:r.managed_worktree?.state==="open"?"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon recovery.":`Recreate ${r.cwd}, or repair it with \`crtr node config --cwd <path> --node ${e}\`; durable node work resumes in a fresh conversation. Then retry \`crtr node lifecycle revive ${e}\`.`;throw new E({error:"cwd_missing",message:`${e} cannot be revived \u2014 its recorded cwd no longer exists: ${r.cwd}`,next:p})}r.host_kind!=="broker"&&(y(e,{host_kind:"broker"}),r.host_kind="broker"),r.review_binding!=null&&!_e(e)&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(O(e),r.pi_session_id=null,r.pi_session_file=null);const t=r.fork_from!=null&&r.pi_session_id==null,c=r.fork_source_file;if(t&&(typeof c!="string"||!J(c)))throw new E({error:"fork_source_invalid",message:`${e} cannot be revived \u2014 its resolved fork source file is missing or invalid.`,next:`Restore the node's fork source metadata, then retry \`crtr node lifecycle revive ${e}\`.`});const f=t&&typeof c=="string";if(f&&!H(c))throw new E({error:"fork_from_missing",message:`${e} cannot be revived \u2014 its fork source no longer exists: ${c}`,next:`Restore ${c}, or update the node's fork source, then retry \`crtr node lifecycle revive ${e}\`.`});const a=X(e,{daemonEpoch:B().epoch()});try{r.cycles=(r.cycles??0)+1,y(e,{cycles:r.cycles});const M=r.intent==="refresh"||r.cycle_pending===!0?!1:i.resume,h=f?{}:De(e,r,M),d=h.resumeSessionPath!==void 0,S=d&&h.newCycle===!0,m=d&&!S,$=!d&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&Oe(e),G=f||$,C=r.cycle_pending===!0||S;y(e,{cycle_pending:C}),r.cycle_pending=C,!f&&!d&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(O(e),r.pi_session_id=null,r.pi_session_file=null);let l,u=null;const N=s(()=>({type:"runtime",kind:"kickoff",...r.spawned_by!=null&&r.spawned_by!==""?{spawnedBy:r.spawned_by}:{}}),"birthOrigin");if(f){const o=x(e);l=w(r,{forkFrom:c,...o!=null&&o!==""?{prompt:o}:{}}),o!=null&&o!==""&&(u=N()),ve(e,we(c)?.node_id??null)}else if(m)l=w(r,{...h,...i.wakeReason==="runtime-restart-abort"?{prompt:ae}:{}}),i.wakeReason==="runtime-restart-abort"&&(u={type:"runtime",kind:"restart-continuation"});else if($){const o=x(e)?.trim();l=w(r,o!==void 0&&o!==""?{prompt:o}:{}),o!==void 0&&o!==""&&(u=N()),U(e)}else{const o=se(r,a);l=w(r,{...h,prompt:te(r,o,i.wakeReason==="runtime-restart-abort"?void 0:i.wakeReason)}),r.run_id&&o.unreadMessageIds?.length&&(l.env.CRTR_KICKOFF_MESSAGE_IDS=JSON.stringify(o.unreadMessageIds)),u=i.wakeReason!==void 0&&i.wakeReason!=="runtime-restart-abort"?{type:"runtime",kind:"wake",wake:i.wakeReason}:{type:"runtime",kind:"revive",cycle:r.cycles??0},U(e)}l.env={...l.env,CRTR_SUBTREE:me(e)},u!==null&&(l.env[fe]=ue(u)),R(e,r.intent==="refresh"?"refresh-launch":"revive"),de(e,{preserveEpisode:!0});const L=he(e);i.recovery!==!0&&ie(e),Ee(e,r.grantee);const j=$e(r.cwd,r.profile_id).plans.get("node:start")??[];await Ce(j,{node:{id:e,name:r.name,kind:r.kind,mode:r.mode,lifecycle:r.lifecycle,cwd:r.cwd,nodeDir:xe(e),contextDir:Re(e),jobDir:be(e),reportsDir:Se(e)},runtime:{isBirth:G,canvasHome:ye(),profile:r.profile_id??null}}),l.env={...l.env,CRTR_EXECUTION_ID:a};let v;try{if(v=await T.launch(e,l,{cwd:r.cwd,name:P(r),resuming:m}),v.pid===null)throw new Error(`broker host returned no pid for ${e}`)}catch(o){try{R(e,"crash",{reason:"launch_failed",outcome:{detail:{schema:"crtr.node-outcome-detail/v1",message:o instanceof Error?o.message:String(o)}}}),oe(e,ee(e),`Child crashed \u2014 ${P(r)} (${e}) failed to relaunch and is now dead: ${o.message}
3
2
 
4
- It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,{reason:"child-crashed",child:e})}catch{}throw y(u,{reason:"launch_failed"}),new Error(`[broker] refusing to revive ${e}: ${o.message}`)}if(X(e,new Date().toISOString()),J(u,e,d.pid)==="shutdown")throw y(u,{reason:"superseded"}),P.teardown(e),new Error(`[broker] refusing to revive ${e}: execution was superseded during launch`);return q(e),{window:null,session:r.tmux_session??null,resumed:k,launch:d,faultExplanation:K.explanation,outcome:"launched"}}catch(h){throw y(u,{reason:"launch_failed"}),h}}s(Ne,"launchRevive");export{ir as decideAttachRevive,er as hasFreshGroundState,Ee as resumeArgs,rr as reviveNode};
3
+ It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,{reason:"child-crashed",child:e})}catch{}throw b(a,{reason:"launch_failed"}),new Error(`[broker] refusing to revive ${e}: ${o.message}`)}if(Q(e,new Date().toISOString()),Y(a,e,v.pid)==="shutdown")throw b(a,{reason:"superseded"}),T.teardown(e),new Error(`[broker] refusing to revive ${e}: execution was superseded during launch`);return I(e),{window:null,session:r.tmux_session??null,resumed:m,launch:v,faultExplanation:L.explanation,outcome:"launched"}}catch(p){throw b(a,{reason:"launch_failed"}),p}}s(Pe,"launchRevive");export{cr as decideAttachRevive,sr as hasFreshGroundState,Ne as resumeArgs,lr as reviveNode};
@@ -1,11 +1,11 @@
1
- var c=Object.defineProperty;var e=(r,o)=>c(r,"name",{value:o,configurable:!0});import{existsSync as a,readFileSync as d,writeFileSync as s,mkdirSync as u}from"node:fs";import{join as p}from"node:path";import{contextDir as i}from"../canvas/paths.js";function t(r){return p(i(r),"roadmap.md")}e(t,"roadmapPath");function y(r){return a(t(r))}e(y,"hasRoadmap");function w(r){const o=t(r);return a(o)?d(o,"utf8"):null}e(w,"readRoadmap");function R(r,o={}){const m=i(r);u(m,{recursive:!0});const n=`# Roadmap
1
+ var n=Object.defineProperty;var r=(e,t)=>n(e,"name",{value:t,configurable:!0});import{join as m}from"node:path";import{contextDir as s,nodeAgentDir as o}from"../canvas/node-agent-paths.js";import{existsBeneath as p,readTextBeneathIfExists as h,writeFileBeneath as u}from"../spaces/open-beneath.js";function a(e){return m(s(e),"roadmap.md")}r(a,"roadmapPath");function l(e){return p(o(e),a(e))}r(l,"hasRoadmap");function w(e){return h(o(e),a(e))}r(w,"readRoadmap");function R(e,t={}){const i=`# Roadmap
2
2
 
3
3
  ## Goal
4
- ${o.goal?.trim()??"(the goal you now own)"}
4
+ ${t.goal?.trim()??"(the goal you now own)"}
5
5
 
6
6
  ## Exit criteria
7
- ${o.exitCriteria?.trim()??'(what "done" looks like)'}
7
+ ${t.exitCriteria?.trim()??'(what "done" looks like)'}
8
8
 
9
9
  ## Phases
10
10
  (ordered phases from here to done; the current one carries a one-line status)
11
- `;return s(t(r),n),n}e(R,"seedRoadmap");export{y as hasRoadmap,w as readRoadmap,t as roadmapPath,R as seedRoadmap};
11
+ `;return u(o(e),a(e),i),i}r(R,"seedRoadmap");export{l as hasRoadmap,w as readRoadmap,a as roadmapPath,R as seedRoadmap};
@@ -22,6 +22,12 @@ export interface RunningCommand {
22
22
  completion: Promise<RunCommandOnceResult>;
23
23
  terminate(): void;
24
24
  }
25
+ /** App commands use the broker's mount compiler and the root launcher on Linux.
26
+ * The Mac runs through the existing direct-spawn implementation. */
27
+ export declare function runAppCommand(options: RunCommandOnceOptions & {
28
+ nodeId?: string;
29
+ app: string;
30
+ }): Promise<RunningCommand>;
25
31
  /** Start one admitted-PATH bash command in its own process group. The returned
26
32
  * handle exposes the pid immediately for callers that must record ownership
27
33
  * before waiting for completion; `completion` resolves after the process group
@@ -1 +1 @@
1
- var R=Object.defineProperty;var u=(a,s)=>R(a,"name",{value:s,configurable:!0});import{spawn as x}from"node:child_process";import{createHash as G}from"node:crypto";import{captureTeardownSnapshot as v,isAnyPidAlive as C,killProcessTreePids as g}from"../canvas/pid.js";import{CRON_DEATH_POLL_MS as K,CRON_KILL_GRACE_MS as N,newHeadCapture as k}from"../../daemon/cron/capture.js";import{resolveAdmittedHostCommand as b}from"./spawn-env.js";function Q({command:a,cwd:s,env:w,timeoutMs:D,headBytes:S}){const E=Date.now(),r=x(b("bash",w,s),["-c",a],{cwd:s,env:w,detached:!0,stdio:["ignore","pipe","pipe"]}),i=r.pid??null,f=k(S),c=k(S),A=G("sha256");r.stdout?.on("data",t=>{A.update(t),f.take(t)}),r.stderr?.on("data",t=>c.take(t));let L=!1,m=null,o,_=null,d=!1,H=!1,n,l,p,e,O;const I=new Promise(t=>{O=t}),T=u(()=>{d||o===void 0||(d=!0,n!==void 0&&clearTimeout(n),l!==void 0&&clearTimeout(l),p!==void 0&&clearTimeout(p),O({exitCode:o,signal:_,stdout:f.decode(),stdoutTruncated:f.truncated(),stderr:c.decode(),stderrTruncated:c.truncated(),timedOut:L,durationMs:Date.now()-E,stdoutSha256:A.digest("hex"),processError:m}))},"finish"),h=u(()=>{if(e===void 0||!C(e.tree)){T();return}p=setTimeout(h,K)},"awaitTeardownDeath"),P=u(()=>{i===null||d||(e??=v(i,null),g(e.tree,"SIGTERM",e.identities),l===void 0&&(l=setTimeout(()=>{C(e.tree)&&g(e.tree,"SIGKILL",e.identities),H=!0,o!==void 0&&h()},N),l.unref?.()))},"terminate");return r.on("error",t=>{m===null&&(m=t),i===null&&(o=null,T())}),r.on("close",(t,M)=>{if(!d){if(o=t,_=M,n!==void 0&&clearTimeout(n),e!==void 0&&C(e.tree)){H&&h();return}T()}}),i!==null&&(n=setTimeout(()=>{d||(L=!0,P())},D),n.unref?.()),{pid:i,completion:I,terminate:P}}u(Q,"runCommandOnce");export{Q as runCommandOnce};
1
+ var H=Object.defineProperty;var a=(e,s)=>H(e,"name",{value:s,configurable:!0});import{spawn as b}from"node:child_process";import{createHash as k}from"node:crypto";import{captureTeardownSnapshot as R,isAnyPidAlive as x,killProcessTreePids as L}from"../canvas/pid.js";import{CRON_DEATH_POLL_MS as B,CRON_KILL_GRACE_MS as G,newHeadCapture as M}from"../../daemon/cron/capture.js";import{resolveAdmittedHostCommand as O}from"./spawn-env.js";import{appProcessSandboxed as K,launchAppProcess as N}from"../spaces/process.js";async function V(e){if(!K())return $(e);const s=Date.now(),d=await N({nodeId:e.nodeId,app:e.app,command:[O("bash",e.env,e.cwd),"-c",e.command],cwd:e.cwd,env:e.env,stdoutBytes:e.headBytes,stderrBytes:e.headBytes});let f=!1,o;const p=a(()=>{d.stop().catch(t=>{console.error(`app command ${d.pid} could not be stopped:`,t)})},"terminate");o=setTimeout(()=>{f=!0,p()},e.timeoutMs),o.unref?.();const i=d.completion.then(t=>({exitCode:t.exitCode,signal:t.signal,stdout:t.stdout,stderr:t.stderr,stdoutTruncated:t.stdoutTruncated,stderrTruncated:t.stderrTruncated,stdoutSha256:t.stdoutSha256,timedOut:f,durationMs:Date.now()-s,processError:null})).finally(()=>{o&&clearTimeout(o)});return{pid:d.pid,completion:i,terminate:p}}a(V,"runAppCommand");function $({command:e,cwd:s,env:d,timeoutMs:f,headBytes:o}){const p=Date.now(),i=b(O("bash",d,s),["-c",e],{cwd:s,env:d,detached:!0,stdio:["ignore","pipe","pipe"]}),t=i.pid??null,T=M(o),h=M(o),P=k("sha256");i.stdout?.on("data",n=>{P.update(n),T.take(n)}),i.stderr?.on("data",n=>h.take(n));let g=!1,w=null,l,v=null,c=!1,y=!1,u,m,C,r,D;const _=new Promise(n=>{D=n}),S=a(()=>{c||l===void 0||(c=!0,u!==void 0&&clearTimeout(u),m!==void 0&&clearTimeout(m),C!==void 0&&clearTimeout(C),D({exitCode:l,signal:v,stdout:T.decode(),stdoutTruncated:T.truncated(),stderr:h.decode(),stderrTruncated:h.truncated(),timedOut:g,durationMs:Date.now()-p,stdoutSha256:P.digest("hex"),processError:w}))},"finish"),A=a(()=>{if(r===void 0||!x(r.tree)){S();return}C=setTimeout(A,B)},"awaitTeardownDeath"),I=a(()=>{t===null||c||(r??=R(t,null),L(r.tree,"SIGTERM",r.identities),m===void 0&&(m=setTimeout(()=>{x(r.tree)&&L(r.tree,"SIGKILL",r.identities),y=!0,l!==void 0&&A()},G),m.unref?.()))},"terminate");return i.on("error",n=>{w===null&&(w=n),t===null&&(l=null,S())}),i.on("close",(n,E)=>{if(!c){if(l=n,v=E,u!==void 0&&clearTimeout(u),r!==void 0&&x(r.tree)){y&&A();return}S()}}),t!==null&&(u=setTimeout(()=>{c||(g=!0,I())},f),u.unref?.()),{pid:t,completion:_,terminate:I}}a($,"runCommandOnce");export{V as runAppCommand,$ as runCommandOnce};
@@ -3,11 +3,5 @@ export interface HumanForkCoordinates {
3
3
  sourceSessionId: string;
4
4
  leafId: string;
5
5
  }
6
- /**
7
- * Materialize one immutable root-to-leaf Pi session branch without touching the
8
- * source broker's manager. The SDK creates its branch in the supplied session
9
- * directory, so opening the source through a detached manager directs the staged
10
- * file straight into the ticket directory. Publication is an exclusive hard link:
11
- * an existing destination is never read or replaced.
12
- */
13
- export declare function materializeSessionBranchAt(coordinates: HumanForkCoordinates, destination: string): void;
6
+ /** Fork the captured root-to-leaf branch without opening or mutating its live source. */
7
+ export declare function materializeSessionBranch(coordinates: HumanForkCoordinates): string;
@@ -1 +1 @@
1
- var f=Object.defineProperty;var a=(s,o)=>f(s,"name",{value:o,configurable:!0});import{chmodSync as l,linkSync as u,statSync as w,unlinkSync as m}from"node:fs";import{dirname as n,isAbsolute as d,resolve as c}from"node:path";import{SessionManager as h}from"./broker-sdk.js";function y(s,o){if(!d(s.sourceFile)||!d(o))throw new Error("session branch paths must be absolute");if(s.sourceSessionId===""||s.leafId==="")throw new Error("session branch coordinates require source session and leaf ids");const r=c(o),i=h.open(s.sourceFile,n(r));if(i.getSessionId()!==s.sourceSessionId)throw new Error("source session id does not match captured coordinates");let e;try{if(e=i.createBranchedSession(s.leafId),e===void 0)throw new Error("Pi did not persist the selected session branch");if(e=c(e),n(e)!==n(r))throw new Error("Pi staged the session branch outside the destination directory");if(l(e,384),(w(e).mode&511)!==384)throw new Error("staged session branch does not have mode 0600");const t=h.open(e);if(t.getSessionFile()!==e||t.getSessionId()==="")throw new Error("Pi produced an invalid session branch");u(e,r)}finally{e!==void 0&&m(e)}}a(y,"materializeSessionBranchAt");export{y as materializeSessionBranchAt};
1
+ var n=Object.defineProperty;var s=(e,r)=>n(e,"name",{value:r,configurable:!0});import{conversationIdFromPath as i,conversationStore as t}from"../conversation-store/index.js";function c(e){if(e.sourceSessionId===""||e.leafId==="")throw new Error("session branch coordinates require source session and leaf ids");const r=i(e.sourceFile);if(r===null||r!==e.sourceSessionId)throw new Error("source session id does not match captured coordinates");const o=t();if(o.header(r).header.id!==e.sourceSessionId)throw new Error("source session id does not match captured coordinates");return o.header(o.fork(r,void 0,e.leafId)).path}s(c,"materializeSessionBranch");export{c as materializeSessionBranch};
@@ -7,10 +7,7 @@ export declare function compactSessionSearchText(text: string): string;
7
7
  export declare class SessionListCache {
8
8
  private readonly cacheFile;
9
9
  private cache;
10
- /** In-flight cwd scans keyed by normalized session dir, so an immediate
11
- * /resume that races the background prewarm (or a second identical open)
12
- * shares the one running jsonlFiles/stat/build pass instead of queueing a
13
- * redundant one behind it. */
10
+ /** Share concurrent scans for the same cwd. */
14
11
  private inflightDir;
15
12
  private loadPromise;
16
13
  private buildChain;
@@ -18,25 +15,12 @@ export declare class SessionListCache {
18
15
  private persistAgain;
19
16
  private persistTimer;
20
17
  constructor(cacheFile: string);
21
- /** Fire-and-forget warm of the cwd scope at broker start, so the first
22
- * `/resume` open after this broker launches is already warm. The cold scan
23
- * streams each file via readline (yields per chunk), so it never blocks the
24
- * broker loop — pre-warming beats worker threads here. Errors are swallowed
25
- * by the same paths that guard a normal open. */
26
- prewarm(sessionDir: string): void;
27
- /** Sessions for one cwd's session dir (the picker's default `cwd` scope).
28
- * Single-flight: an identical concurrent cwd open (prewarm ⇄ immediate
29
- * /resume) shares the in-flight promise rather than repeating the scan.
30
- * Incompatible cwd/all builds still serialize through the build chain. */
31
- listDir(sessionDir: string): Promise<WireSessionInfo[]>;
18
+ /** Sessions in the picker's current cwd. */
19
+ listDir(cwd: string): Promise<WireSessionInfo[]>;
32
20
  private buildDir;
33
- /** Sessions across every cwd's dir under the sessions root (`all` scope). */
34
- listAll(sessionsRoot: string): Promise<WireSessionInfo[]>;
35
- /** Serialize builds through a single chain: they mutate the shared cache map
36
- * and, cold, scan the same large corpus. Identical cwd opens are already
37
- * collapsed upstream by `listDir`'s in-flight sharing; chaining serializes
38
- * the remaining incompatible builds (a cwd scan vs an `all` scan) so they
39
- * never race map mutation or launch overlapping cold scans. */
21
+ /** Sessions across every cwd (`all` scope). */
22
+ listAll(): Promise<WireSessionInfo[]>;
23
+ /** Serialize cwd and all-scope cache mutations. */
40
24
  private build;
41
25
  private buildLocked;
42
26
  /** Load the persisted cache exactly once, single-flight. Returns a shared
@@ -1 +1 @@
1
- var O=Object.defineProperty;var a=(e,t)=>O(e,"name",{value:t,configurable:!0});import{createReadStream as E}from"node:fs";import{readFile as _,readdir as b,rename as x,stat as D,unlink as I,writeFile as j}from"node:fs/promises";import{createInterface as k}from"node:readline";import{dirname as w,join as N,normalize as P}from"node:path";const M=1024;function L(e){if(e.length<=M)return e;const t=M/2;return`${e.slice(0,t)} \u2026 ${e.slice(-t)}`}a(L,"compactSessionSearchText");const z=10,A=1,R=2e3;function S(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0}a(S,"isFiniteNonNeg");function C(e){return e===void 0||typeof e=="string"}a(C,"isOptionalString");function v(e){if(typeof e!="object"||e===null)return!1;const t=e;return typeof t.path=="string"&&typeof t.id=="string"&&typeof t.cwd=="string"&&typeof t.created=="string"&&typeof t.modified=="string"&&S(t.messageCount)&&typeof t.firstMessage=="string"&&typeof t.allMessagesText=="string"&&C(t.name)&&C(t.parentSessionPath)}a(v,"isValidWireInfo");function H(e){if(typeof e!="object"||e===null)return!1;const t=e;return S(t.mtimeMs)&&S(t.size)&&v(t.info)}a(H,"isValidEntry");function $(e){if(!e.trim())return null;try{return JSON.parse(e)}catch{return null}}a($,"parseLine");function J(e){const t=e.content;return typeof t=="string"?t:Array.isArray(t)?t.filter(i=>i.type==="text").map(i=>i.text).join(" "):""}a(J,"extractTextContent");function V(e){const t=e.message;if(!t||!("content"in t))return;const i=t.role;if(i!=="user"&&i!=="assistant")return;const s=t.timestamp;if(typeof s=="number")return s;const n=new Date(e.timestamp).getTime();return Number.isNaN(n)?void 0:n}a(V,"messageActivityTime");async function W(e){try{const t=await D(e);let i=null,s=0,n="";const f=[];let m,l;const d=k({input:E(e,{encoding:"utf8"}),crlfDelay:1/0});for await(const h of d){const c=$(h);if(!c)continue;if(!i){if(c.type!=="session")return null;i=c;continue}if(c.type==="session_info"&&(m=c.name?.trim()||void 0),c.type!=="message")continue;s++;const T=V(c);typeof T=="number"&&(l=Math.max(l??0,T));const p=c.message;if(!p||!("content"in p))continue;const g=p.role;if(g!=="user"&&g!=="assistant")continue;const y=J(p);y&&(f.push(y),!n&&g==="user"&&(n=y))}if(!i)return null;const r=typeof i.cwd=="string"?i.cwd:"",o=typeof i.timestamp=="string"?new Date(i.timestamp).getTime():NaN,u=typeof l=="number"&&l>0?new Date(l):Number.isNaN(o)?t.mtime:new Date(o);return{path:e,id:i.id,cwd:r,name:m,parentSessionPath:i.parentSession,created:new Date(i.timestamp).toISOString(),modified:u.toISOString(),messageCount:s,firstMessage:n||"(no messages)",allMessagesText:L(f.join(" "))}}catch{return null}}a(W,"buildWireSessionInfo");class K{static{a(this,"SessionListCache")}cacheFile;cache=new Map;inflightDir=new Map;loadPromise=null;buildChain=Promise.resolve();persisting=!1;persistAgain=!1;persistTimer=null;constructor(t){this.cacheFile=t}prewarm(t){this.listDir(t)}listDir(t){const i=P(t),s=this.inflightDir.get(i);if(s)return s;const n=this.buildDir(i);this.inflightDir.set(i,n);const f=a(()=>{this.inflightDir.get(i)===n&&this.inflightDir.delete(i)},"clear");return n.then(f,f),n}buildDir(t){return F(t).then(i=>this.build(i,s=>w(s)===t))}async listAll(t){let i;try{i=(await b(t,{withFileTypes:!0})).filter(n=>n.isDirectory()).map(n=>N(t,n.name))}catch{return[]}const s=[];for(const n of i)s.push(...await F(n));return this.build(s,n=>w(w(n))===t)}build(t,i){const s=this.buildChain.then(()=>this.buildLocked(t,i));return this.buildChain=s.then(()=>{},()=>{}),s}async buildLocked(t,i){await this.ensureLoaded();const s=new Set(t);let n=!1;for(const r of this.cache.keys())!s.has(r)&&i(r)&&(this.cache.delete(r),n=!0);const f=new Array(t.length);let m=0;const l=a(async()=>{for(;;){const r=m++;if(r>=t.length)return;const o=t[r];if(o===void 0)return;const u=await D(o).catch(()=>null);if(!u){this.cache.delete(o)&&(n=!0);continue}const h=this.cache.get(o);if(h&&h.mtimeMs===u.mtimeMs&&h.size===u.size){f[r]=h.info;continue}const c=await W(o);if(n=!0,!c){this.cache.delete(o);continue}this.cache.set(o,{mtimeMs:u.mtimeMs,size:u.size,info:c}),f[r]=c}},"worker");await Promise.all(Array.from({length:Math.min(z,t.length)},()=>l())),n&&this.schedulePersist();const d=f.filter(r=>r!==void 0);return d.sort((r,o)=>new Date(o.modified).getTime()-new Date(r.modified).getTime()),d}ensureLoaded(){return this.loadPromise||(this.loadPromise=this.loadFromDisk()),this.loadPromise}async loadFromDisk(){try{const t=JSON.parse(await _(this.cacheFile,"utf8"));if(t?.version!==A||typeof t.entries!="object")return;for(const[i,s]of Object.entries(t.entries)){if(!H(s)){this.cache.clear();return}this.cache.set(i,s)}}catch{this.cache.clear()}}schedulePersist(){this.persistTimer||(this.persistTimer=setTimeout(()=>{this.persistTimer=null,this.persist()},R),this.persistTimer.unref?.())}async persist(){if(this.persisting){this.persistAgain=!0;return}this.persisting=!0;const t=`${this.cacheFile}.${process.pid}.tmp`;try{const i={};for(const[n,f]of this.cache)i[n]=f;await j(t,JSON.stringify({version:A,entries:i})),await x(t,this.cacheFile)}catch{await I(t).catch(()=>{})}finally{this.persisting=!1,this.persistAgain&&(this.persistAgain=!1,this.persist())}}}async function F(e){try{return(await b(e)).filter(t=>t.endsWith(".jsonl")).map(t=>N(e,t))}catch{return[]}}a(F,"jsonlFiles");export{K as SessionListCache,L as compactSessionSearchText};
1
+ var T=Object.defineProperty;var c=(t,e)=>T(t,"name",{value:e,configurable:!0});import{readFile as D,rename as N,unlink as C,writeFile as A}from"node:fs/promises";import{resolve as M}from"node:path";import{conversationStore as p,ConversationNotFoundError as F}from"../conversation-store/index.js";const S=1024;function E(t){if(t.length<=S)return t;const e=S/2;return`${t.slice(0,e)} \u2026 ${t.slice(-e)}`}c(E,"compactSessionSearchText");const w=1,P=2e3;function g(t){return typeof t=="number"&&Number.isFinite(t)&&t>=0}c(g,"isFiniteNonNeg");function b(t){return t===void 0||typeof t=="string"}c(b,"isOptionalString");function x(t){if(typeof t!="object"||t===null)return!1;const e=t;return typeof e.path=="string"&&typeof e.id=="string"&&typeof e.cwd=="string"&&typeof e.created=="string"&&typeof e.modified=="string"&&g(e.messageCount)&&typeof e.firstMessage=="string"&&typeof e.allMessagesText=="string"&&b(e.name)&&b(e.parentSessionPath)}c(x,"isValidWireInfo");function O(t){if(typeof t!="object"||t===null)return!1;const e=t;return g(e.mtimeMs)&&g(e.size)&&x(e.info)}c(O,"isValidEntry");function _(t){const e=t.content;return typeof e=="string"?e:Array.isArray(e)?e.filter(i=>i.type==="text").map(i=>i.text).join(" "):""}c(_,"extractTextContent");function k(t){const e=t.message;if(!e||!("content"in e))return;const i=e.role;if(i!=="user"&&i!=="assistant")return;const s=e.timestamp;if(typeof s=="number")return s;const n=new Date(t.timestamp).getTime();return Number.isNaN(n)?void 0:n}c(k,"messageActivityTime");function v(t){try{const e=t.header;let i=0,s="";const n=[];let a,h;for(const f of p().read(t.conversation_id).entries){if(f.type==="session_info"&&(a=f.name?.trim()||void 0),f.type!=="message")continue;i++;const y=k(f);typeof y=="number"&&(h=Math.max(h??0,y));const u=f.message;if(!u||!("content"in u))continue;const m=u.role;if(m!=="user"&&m!=="assistant")continue;const d=_(u);d&&(n.push(d),!s&&m==="user"&&(s=d))}const r=typeof e.cwd=="string"?e.cwd:"",o=typeof e.timestamp=="string"?new Date(e.timestamp).getTime():NaN,l=typeof h=="number"&&h>0?new Date(h):Number.isNaN(o)?new Date(t.mtime):new Date(o);return{path:t.path,id:e.id,cwd:r,name:a,parentSessionPath:e.parentSession,created:new Date(e.timestamp).toISOString(),modified:l.toISOString(),messageCount:i,firstMessage:s||"(no messages)",allMessagesText:E(n.join(" "))}}catch(e){if(e instanceof F)return null;throw e}}c(v,"buildWireSessionInfo");class H{static{c(this,"SessionListCache")}cacheFile;cache=new Map;inflightDir=new Map;loadPromise=null;buildChain=Promise.resolve();persisting=!1;persistAgain=!1;persistTimer=null;constructor(e){this.cacheFile=e}listDir(e){const i=M(e),s=this.inflightDir.get(i);if(s)return s;const n=Promise.resolve().then(()=>this.buildDir(i));this.inflightDir.set(i,n);const a=c(()=>{this.inflightDir.get(i)===n&&this.inflightDir.delete(i)},"clear");return n.then(a,a),n}buildDir(e){const i=p().list().filter(s=>s.header.cwd===e);return this.build(i,s=>this.cache.get(s)?.info.cwd===e)}async listAll(){return this.build(p().list(),()=>!0)}build(e,i){const s=this.buildChain.then(()=>this.buildLocked(e,i));return this.buildChain=s.then(()=>{},()=>{}),s}async buildLocked(e,i){await this.ensureLoaded();const s=new Set(e.map(({path:r})=>r));let n=!1;for(const r of this.cache.keys())!s.has(r)&&i(r)&&(this.cache.delete(r),n=!0);const a=new Array(e.length);for(const[r,o]of e.entries()){const l=this.cache.get(o.path);if(l&&l.mtimeMs===o.mtime&&l.size===o.size){a[r]=l.info;continue}const f=v(o);if(n=!0,!f){this.cache.delete(o.path);continue}this.cache.set(o.path,{mtimeMs:o.mtime,size:o.size,info:f}),a[r]=f}n&&this.schedulePersist();const h=a.filter(r=>r!==void 0);return h.sort((r,o)=>new Date(o.modified).getTime()-new Date(r.modified).getTime()),h}ensureLoaded(){return this.loadPromise||(this.loadPromise=this.loadFromDisk()),this.loadPromise}async loadFromDisk(){try{const e=JSON.parse(await D(this.cacheFile,"utf8"));if(e?.version!==w||typeof e.entries!="object")return;for(const[i,s]of Object.entries(e.entries)){if(!O(s)){this.cache.clear();return}this.cache.set(i,s)}}catch{this.cache.clear()}}schedulePersist(){this.persistTimer||(this.persistTimer=setTimeout(()=>{this.persistTimer=null,this.persist()},P),this.persistTimer.unref?.())}async persist(){if(this.persisting){this.persistAgain=!0;return}this.persisting=!0;const e=`${this.cacheFile}.${process.pid}.tmp`;try{const i={};for(const[n,a]of this.cache)i[n]=a;await A(e,JSON.stringify({version:w,entries:i})),await N(e,this.cacheFile)}catch{await C(e).catch(()=>{})}finally{this.persisting=!1,this.persistAgain&&(this.persistAgain=!1,this.persist())}}}export{H as SessionListCache,E as compactSessionSearchText};
@@ -1,2 +1,2 @@
1
- var e=Object.defineProperty;var o=(t,n)=>e(t,"name",{value:n,configurable:!0});import{existsSync as u,readFileSync as a,writeFileSync as l,mkdirSync as f}from"node:fs";import{situationalContextPath as i,nodeDir as c}from"../canvas/paths.js";import{formatCard as m,parseCard as p}from"../../shared/generated-context.js";import{SITUATIONAL_CONTEXT_CUSTOM_TYPE as _}from"../../shared/generated-context.js";function s(t){return t.trim()===""?"":m("situational",{},t)}o(s,"formatSituationalProse");function T(t,n){const r=n.trim();r!==""&&(f(c(t),{recursive:!0}),l(i(t),r+`
2
- `,"utf8"))}o(T,"appendSituationalContext");function x(t){const n=i(t);if(!u(n))return null;const r=a(n,"utf8").trim();return r!==""?r:null}o(x,"readSituationalContext");function E(t){const n=x(t);return n===null?null:p({content:n})===null?s(n):n}o(E,"situationalContextEnvelope");export{_ as SITUATIONAL_CONTEXT_CUSTOM_TYPE,T as appendSituationalContext,s as formatSituationalProse,E as situationalContextEnvelope};
1
+ var a=Object.defineProperty;var n=(t,r)=>a(t,"name",{value:r,configurable:!0});import{mkdirSync as u}from"node:fs";import{readTextBeneathIfExists as l,writeFileBeneath as m}from"../spaces/open-beneath.js";import{situationalContextPath as e,nodeRunDir as o}from"../canvas/paths.js";import{formatCard as f,parseCard as c}from"../../shared/generated-context.js";import{SITUATIONAL_CONTEXT_CUSTOM_TYPE as P}from"../../shared/generated-context.js";function p(t){return t.trim()===""?"":f("situational",{},t)}n(p,"formatSituationalProse");function d(t,r){const i=r.trim();i!==""&&(u(o(t),{recursive:!0}),m(o(t),e(t),i+`
2
+ `,{atomic:!0}))}n(d,"appendSituationalContext");function x(t){const r=l(o(t),e(t))?.trim()??"";return r!==""?r:null}n(x,"readSituationalContext");function h(t){const r=x(t);return r===null?null:c({content:r})===null?p(r):r}n(h,"situationalContextEnvelope");export{P as SITUATIONAL_CONTEXT_CUSTOM_TYPE,d as appendSituationalContext,p as formatSituationalProse,h as situationalContextEnvelope};
@@ -8,11 +8,8 @@ export declare const ADMITTED_HOST_PATH_ENV = "CRTR_ADMITTED_HOST_PATH";
8
8
  * The result is absolute, or null when no PATH entry supplies the command. */
9
9
  export declare function resolvePathExecutable(name: string, env: NodeJS.ProcessEnv, cwd: string): string | null;
10
10
  export declare function resolveAdmittedHostCommand(name: string, env: NodeJS.ProcessEnv, cwd: string): string;
11
- /** B — the exact env-var name of each crtr-configured model provider's API
12
- * key. Deliberately an explicit provider→env-key mapping, NOT inferred from
13
- * `MODEL_PROVIDER_KEYS` in launch.ts (that constant is a provider-ID list —
14
- * `['anthropic', 'openai']` — not env-var names; conflating the two would
15
- * silently admit the wrong names the moment either list changes). */
11
+ /** Vendor keys stay with the daemon, even when an explicit profile or host
12
+ * allowlist names one of them. The front-door credential check uses this map. */
16
13
  export declare const PROVIDER_ENV_KEYS: Record<ModelProvider, string>;
17
14
  /** Sources A–C: the operational base shared by the broker boundary (this
18
15
  * module's `buildBrokerEnv`) and cron executor — the single shared definition
@@ -28,6 +25,8 @@ export declare function buildOperationalEnvBase(opts: {
28
25
  * `CRTR_PROFILE_ID`. `null`/`''` for no profile. */
29
26
  targetProfileId: string | null;
30
27
  host?: NodeJS.ProcessEnv;
28
+ /** App runs do not inherit the owner project's explicit host-env allowlist. */
29
+ skipSpawnAllow?: boolean;
31
30
  }): NodeJS.ProcessEnv;
32
31
  /** Source F — the TARGET profile's manifest `metadata`, each entry surfaced
33
32
  * as `CRTR_PROFILE_META_<KEY>` (key uppercased, every non-alphanumeric run
@@ -41,7 +40,7 @@ export declare function profileMetadataEnv(profileId: string | null): NodeJS.Pro
41
40
  * `process.cwd()`/`CRTR_PROFILE_ID`, which may be a launcher's or the
42
41
  * daemon's own and belong to an unrelated scope), E — the TARGET profile's
43
42
  * own `profile env` store (`readProfileEnvVars`, `core/profiles/env-store.ts`)
44
- * read directly off disk and injected regardless of the host env or any
43
+ * read directly off disk only when the profile belongs to the launched app, regardless of the host env or any
45
44
  * `spawnEnv.allow` entry (setting a value there IS the consent to cross this
46
45
  * boundary), F — the TARGET profile's manifest metadata as
47
46
  * `CRTR_PROFILE_META_*` (`profileMetadataEnv` above), plus D — the trusted,
@@ -51,4 +50,5 @@ export declare function profileMetadataEnv(profileId: string | null): NodeJS.Pro
51
50
  * value. Every broker launch (front-door root, managed child, `--root`,
52
51
  * every revive/daemon relaunch) funnels through `headlessBrokerHost.launch()`,
53
52
  * which calls this. */
53
+ export declare function buildAppProcessEnv(targetCwd: string, targetProfileId: string | null, app: string): NodeJS.ProcessEnv;
54
54
  export declare function buildBrokerEnv(inv: PiInvocation): NodeJS.ProcessEnv;
@@ -1 +1 @@
1
- var u=Object.defineProperty;var a=(e,t)=>u(e,"name",{value:t,configurable:!0});import{statSync as d}from"node:fs";import{delimiter as P,resolve as E}from"node:path";import{readMergedLaunchConfig as p}from"../config.js";import{readProfileEnvVars as T}from"../profiles/env-store.js";import{metadataEnvName as _,readProfileMetadata as m}from"../profiles/manifest.js";import{binShimDirFor as A}from"./bin-contributions.js";import{FRONT_DOOR_ENV as O}from"./front-door-env.js";const R=new Set(["HOME","PATH","SHELL","USER","LOGNAME","PWD","TMPDIR","TERM","TERMINFO","COLORTERM","LANG","LANGUAGE","TZ","NO_PROXY","no_proxy","SSH_AUTH_SOCK","CRTR_BASH_VALVE_MS"]),h=["LC_","XDG_","PI_"],f="CRTR_ADMITTED_HOST_PATH";function H(e,t,o){const n=t.PATH;if(n===void 0||n==="")return null;for(const s of n.split(P)){const c=E(o,s===""?".":s,e);try{const r=d(c);if(r.isFile()&&(r.mode&73)!==0)return c}catch{}}return null}a(H,"resolvePathExecutable");function $(e,t,o){const n=t[f]??t.PATH;if(n===void 0||n==="")throw new Error(`cannot resolve crouter-owned ${e}: the admitted host PATH is empty`);const s=H(e,{PATH:n},o);if(s!==null)return s;throw new Error(`cannot resolve crouter-owned ${e} from the admitted host PATH`)}a($,"resolveAdmittedHostCommand");const v=["HTTP_PROXY","HTTPS_PROXY","http_proxy","https_proxy"],I={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY"};function w(e){let t;try{t=new URL(e)}catch{return!1}return!(t.protocol!=="http:"&&t.protocol!=="https:"||t.hostname===""||t.username!==""||t.password!=="")}a(w,"isCredentialFreeProxyValue");function N(e,t){if(!t.includes("*"))return e===t;const o=t.split("*").map(n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${o}$`).test(e)}a(N,"matchesAllowPattern");function S(e){const t=e.host??process.env,o={};for(const[r,i]of Object.entries(t))i!==void 0&&(R.has(r)||h.some(l=>r.startsWith(l)))&&(o[r]=i);for(const r of v){const i=t[r];i!==void 0&&w(i)&&(o[r]=i)}for(const r of Object.values(I)){const i=t[r];i!==void 0&&(o[r]=i)}const n=p(e.targetCwd,e.targetProfileId).spawnEnv.allow;if(n.length>0)for(const[r,i]of Object.entries(t))i!==void 0&&n.some(l=>N(r,l))&&(o[r]=i);const s=t[f]??o.PATH;s!==void 0&&s!==""&&(o[f]=s);const c=A(e.targetCwd,e.targetProfileId);if(c!==null){const r=o.PATH;o.PATH=r===void 0||r===""?c:`${c}:${r}`}return o}a(S,"buildOperationalEnvBase");function C(e){const t={};for(const[o,n]of Object.entries(m(e)))t[_(o)]=n;return t}a(C,"profileMetadataEnv");function F(e){const t=e.env.CRTR_NODE_CWD??process.cwd(),o=e.env.CRTR_PROFILE_ID||null,n=S({targetCwd:t,targetProfileId:o});return{...n,...C(o),...T(o),...e.env,[f]:n[f],[O]:"1"}}a(F,"buildBrokerEnv");export{f as ADMITTED_HOST_PATH_ENV,I as PROVIDER_ENV_KEYS,F as buildBrokerEnv,S as buildOperationalEnvBase,C as profileMetadataEnv,$ as resolveAdmittedHostCommand,H as resolvePathExecutable};
1
+ var d=Object.defineProperty;var c=(t,e)=>d(t,"name",{value:e,configurable:!0});import{statSync as p}from"node:fs";import{appSpace as E}from"../layout.js";import{delimiter as _,join as T,resolve as m}from"node:path";import{readMergedLaunchConfig as R}from"../config.js";import{readProfileEnvVars as P}from"../profiles/env-store.js";import{loadProfileManifest as A,metadataEnvName as O,readProfileMetadata as h}from"../profiles/manifest.js";import{binShimDirFor as H}from"./bin-contributions.js";import{FRONT_DOOR_ENV as I}from"./front-door-env.js";const N=new Set(["HOME","PATH","SHELL","USER","LOGNAME","TMPDIR","TERM","TERMINFO","COLORTERM","LANG","LANGUAGE","TZ","NO_PROXY","no_proxy","SSH_AUTH_SOCK","CRTR_BASH_VALVE_MS"]),w=["LC_","XDG_","PI_"],l="CRTR_ADMITTED_HOST_PATH";function C(t,e,o){const r=e.PATH;if(r===void 0||r==="")return null;for(const s of r.split(_)){const i=m(o,s===""?".":s,t);try{const n=p(i);if(n.isFile()&&(n.mode&73)!==0)return i}catch{}}return null}c(C,"resolvePathExecutable");function Y(t,e,o){const r=e[l]??e.PATH;if(r===void 0||r==="")throw new Error(`cannot resolve crouter-owned ${t}: the admitted host PATH is empty`);const s=C(t,{PATH:r},o);if(s!==null)return s;throw new Error(`cannot resolve crouter-owned ${t} from the admitted host PATH`)}c(Y,"resolveAdmittedHostCommand");const M=["HTTP_PROXY","HTTPS_PROXY","http_proxy","https_proxy"],u={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY"};function v(t){let e;try{e=new URL(t)}catch{return!1}return!(e.protocol!=="http:"&&e.protocol!=="https:"||e.hostname===""||e.username!==""||e.password!=="")}c(v,"isCredentialFreeProxyValue");function D(t,e){if(!e.includes("*"))return t===e;const o=e.split("*").map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${o}$`).test(t)}c(D,"matchesAllowPattern");function S(t){const e=t.host??process.env,o={};for(const[n,a]of Object.entries(e))a!==void 0&&(N.has(n)||w.some(f=>n.startsWith(f)))&&(o[n]=a);o.PWD=t.targetCwd;for(const n of M){const a=e[n];a!==void 0&&v(a)&&(o[n]=a)}const r=t.skipSpawnAllow?[]:R(t.targetCwd,t.targetProfileId).spawnEnv.allow;if(r.length>0)for(const[n,a]of Object.entries(e))a!==void 0&&r.some(f=>D(n,f))&&(o[n]=a);const s=e[l]??o.PATH;s!==void 0&&s!==""&&(o[l]=s);const i=H(t.targetCwd,t.targetProfileId);if(i!==null){const n=o.PATH;o.PATH=n===void 0||n===""?i:`${i}:${n}`}return o}c(S,"buildOperationalEnvBase");function x(t){const e={};for(const[o,r]of Object.entries(h(t)))e[O(o)]=r;return e}c(x,"profileMetadataEnv");function y(t,e,o){const r=e===null?null:A(e).manifest,s=r!==null&&(r.grantee??"app:terminal")===o,i=S({targetCwd:t,targetProfileId:e,skipSpawnAllow:o!=="app:terminal"}),n=E(o).home,a={...i,...r===null?{}:x(e),...s?P(e):{},HOME:n,PI_CODING_AGENT_DIR:T(n,".pi","agent"),[l]:i[l]};process.platform==="linux"&&delete a.CRTR_RUNTIME_HOME;for(const f of Object.values(u))delete a[f];return a}c(y,"buildAppProcessEnv");function U(t){const e=t.env.CRTR_NODE_CWD??process.cwd(),o=t.env.CRTR_PROFILE_ID||null,r=t.env.CRTR_GRANTEE??"app:terminal",s=y(e,o,r),i={...s,...t.env,HOME:s.HOME,PI_CODING_AGENT_DIR:s.PI_CODING_AGENT_DIR,[l]:s[l],[I]:"1"};process.platform==="linux"&&delete i.CRTR_RUNTIME_HOME;for(const n of Object.values(u))delete i[n];return i}c(U,"buildBrokerEnv");export{l as ADMITTED_HOST_PATH_ENV,u as PROVIDER_ENV_KEYS,y as buildAppProcessEnv,U as buildBrokerEnv,S as buildOperationalEnvBase,x as profileMetadataEnv,Y as resolveAdmittedHostCommand,C as resolvePathExecutable};
@@ -1,3 +1,4 @@
1
+ import { type SpawnNodeOpts } from './nodes.js';
1
2
  import { type WakeOrigin } from './bearings.js';
2
3
  import { type NodeMeta, type Mode, type Lifecycle, type OutcomeDeliveryBinding, type ReviewBinding } from '../canvas/index.js';
3
4
  import { type ModelRegistryLike, type ModelRequest } from '../model-routes.js';
@@ -50,6 +51,10 @@ export interface SpawnChildOpts {
50
51
  model?: string;
51
52
  /** Per-run scope allow-list. Omit to inherit the spawner's list. */
52
53
  scopes?: string[];
54
+ /** App run identity set at birth; children inherit from the spawner. */
55
+ run?: SpawnNodeOpts['run'];
56
+ /** Commit run rows inside the same transaction as the newborn node. */
57
+ withinCreate?: SpawnNodeOpts['withinCreate'];
53
58
  /** Select the profile this node runs under — an exact profile id or a unique
54
59
  * manifest name (or the closest match to one), resolved through
55
60
  * `resolveProfileOperand`. Omit to INHERIT the
@@ -1,3 +1,3 @@
1
- var Q=Object.defineProperty;var c=(e,o)=>Q(e,"name",{value:o,configurable:!0});import{accessSync as W,constants as A,cpSync as Y,readdirSync as D,existsSync as Z,rmSync as ee}from"node:fs";import{isAbsolute as ne,resolve as oe,join as g}from"node:path";import{spawnNode as re,currentNodeContext as ie,rootOfSpine as te,newNodeId as de,preflightNodeId as ae}from"./nodes.js";import{resolveProfileOperand as se}from"../profiles/manifest.js";import{selectProfileForCwd as ce,selectProfileForCwdReadOnly as le}from"../profiles/select.js";import{buildLaunchSpecAsync as M,buildPiArgv as fe}from"./launch.js";import{createManagedWorktreeAsync as ue,rollbackManagedWorktreeAsync as me}from"../worktree-mutation-async.js";import{usage as f,brokerLaunchFailed as E}from"../errors.js";import{writeGoal as he}from"./kickoff.js";import{appendSituationalContext as we,formatSituationalProse as pe}from"./situational-context.js";import{hasRoadmap as ke,seedRoadmap as _e}from"./roadmap.js";import{buildWakeBearings as ye}from"./bearings.js";import{encodeKickoffOrigin as ve,KICKOFF_ORIGIN_ENV as ge}from"./stamp/protocol.js";import{beginExecution as be,canonicalSessionFile as I,contextDir as B,crtrHome as xe,findNodeBySessionFile as Fe,getNode as w,fullName as H,jobDir as Oe,nodeDir as Ce,recordExecutionPid as Se,abortExecution as P,reportsDir as $e,setFrozen as Ee}from"../canvas/index.js";import{boundFleet as Re,brokerThresholdsForDaemon as De}from"./fleet.js";import{emitEvent as Ie}from"../events/emit.js";import{openViewerWindow as Be,focusOf as Pe,windowOfPane as je}from"./placement.js";import{waitForBrokerViewSocket as Ne}from"./placement-tmux.js";import{transition as b}from"./lifecycle.js";import{beginBootFaultAttempt as Te}from"../canvas/recovery.js";import{piSessionsRoot as Le}from"./pi-vendored.js";import{headlessBrokerHost as j}from"./host.js";import{ensureDaemon as We}from"../../daemon/manage.js";import{readConfig as Ae}from"../config.js";import{modelRequestFromConfig as Me,unregisteredConcreteModel as He}from"../model-routes.js";import{openModelRegistry as Ke}from"./model-registry.js";import{MODEL_SPEC_NEXT as ze}from"./model-selection.js";import{initializeForkContextExposure as qe}from"../substrate/injected-store.js";import{discoverLifecycleHookRegistry as Ue}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as Ve}from"../command-hooks/transport/exec-lifecycle.js";function x(e){return{detail:{schema:"crtr.node-outcome-detail/v1",message:e instanceof Error?e.message:String(e)}}}c(x,"launchFailureOutcome");function Xe(e,o,r){try{return j.launch(e,o,r)}catch(i){try{b(e,"crash",{reason:"launch_failed",outcome:x(i)})}catch{}const d=i.message;throw E(d.startsWith("[broker]")?d:`[broker] refusing to launch ${e}: ${d}`,"Inspect the cause above, fix the launch recipe or environment, then retry.")}}c(Xe,"launchBrokerOrCrash");function Ge(e,o){try{b(e,"crash",{reason:"launch_failed",outcome:x(o)})}catch{}try{j.teardown(e)}catch{}}c(Ge,"crashAndTearDown");function Je(e){const o=Le();if(!Z(o))throw f(`--fork-from '${e}': no pi sessions store at ${o} to resolve it from \u2014 pass a node id or an absolute .jsonl path.`,{next:"Pass a live node id, an absolute .jsonl session path, or drop --fork-from."});const r=[];for(const a of D(o,{withFileTypes:!0})){if(!a.isDirectory())continue;const l=g(o,a.name);for(const s of D(l)){if(!s.endsWith(".jsonl"))continue;const F=s.slice(0,-6),u=F.slice(F.lastIndexOf("_")+1);r.push({id:u,path:g(l,s)})}}const i=r.filter(a=>a.id===e),d=i.length>0?i:r.filter(a=>a.id.startsWith(e));if(d.length===0)throw f(`--fork-from '${e}': no pi session with that id found.`,{next:"Pass a live node id, a real session uuid/prefix, or an absolute .jsonl session path."});if(d.length>1)throw f(`--fork-from '${e}': ambiguous \u2014 ${d.length} sessions match that id prefix; pass the full id or the .jsonl path.`,{next:"Pass the full session uuid or an absolute .jsonl path to disambiguate."});return I(d[0].path)}c(Je,"resolveSessionUuid");function K(e){const o=e.trim();if(o==="")throw f("--fork-from requires a node id, session file, or session uuid.",{next:"Pass a live node id, an absolute .jsonl session path, or a session uuid/prefix."});if(o.includes("/")||o.endsWith(".jsonl"))return I(ne(o)?o:oe(process.cwd(),o));const r=w(o);if(r!==null){const i=r.pi_session_file;if(i==null||i==="")throw f(`node ${o} has no pi session yet \u2014 it has not captured a session FILE to fork from (the broker forks a .jsonl path, not a bare id).`,{next:"Pick a node that has captured a session, or drop --fork-from."});return I(i)}return Je(o)}c(K,"resolveForkSource");async function Qe(e,o,r,i={}){return e===null?null:e!==void 0&&e!==""?se(e).profileId:o!==null?w(o)?.profile_id??null:i.readOnlySelection===!0?le(r):ce(r)}c(Qe,"resolveProfileId");function z(e){const o=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Me(e.model,o,e.modelExact===!0)}c(z,"requestFromLaunch");async function q(e,o,r){if(e===void 0||e.kind==="logical")return;const i=He(e,r??await Ke(),o);if(i!==void 0)throw f(`model '${i.request.spec}' is not registered in this daemon.`,{received:i.request.spec,next:ze})}c(q,"assertLaunchModelRegistered");function Ye(e,o,r){const i=e??o??null;if(!r&&i===null)throw new Error("spawnChild requires a calling node (CRTR_NODE_ID) or an explicit parent");return i}c(Ye,"resolveSpawner");async function U(e,o,r){try{We()}catch{}const i=ie(),d=e.root===!0,a=Ye(e.parent,i.nodeId??null,d),l=e.mode??"base",s=e.rootLifecycle??(d?"resident":"terminal"),F=d&&s==="resident",u=e.worktree===!0,p=u?e.nodeId??de():e.nodeId;e.nodeId!==void 0&&ae(e.nodeId);const k=await Qe(e.profile,a,e.cwd),N=(await M(e.kind,l,{lifecycle:s,hasManager:!d,model:e.model,modelOverride:e.model!==void 0,cwd:e.cwd,profileId:k})).launch;await q(z(N),{cwd:e.cwd,profileId:k});const O=e.forkFrom!==void 0?K(e.forkFrom):void 0,X=O===void 0?null:Fe(O)?.node_id??null;let m,C=e.cwd;try{u&&(m=await ue(e.worktreeCwd??e.cwd,p,e.worktreeBase),C=m.path);const _=u?(await M(e.kind,l,{lifecycle:s,hasManager:!d,model:e.model,modelOverride:e.model!==void 0,cwd:C,profileId:k})).launch:N;u&&await q(z(_),{cwd:C,profileId:k});const n=await re({kind:e.kind,mode:l,lifecycle:s,cwd:C,name:e.name??e.kind,description:e.description,parent:d?null:a,creator:e.creator,spawnedBy:d?a??void 0:void 0,profile_id:k,...e.scopes===void 0?{}:{scopes:e.scopes},forkFrom:e.forkFrom,forkSourceFile:O,modelOverride:e.model===void 0?void 0:_.model,...m!==void 0?{managedWorktree:m}:{},...p!==void 0?{nodeId:p}:{},...e.reviewBinding===void 0?{}:{reviewBinding:e.reviewBinding},...e.deadlineAt===void 0?{}:{deadlineAt:e.deadlineAt},...e.outcomeDelivery===void 0?{}:{outcomeDelivery:e.outcomeDelivery},launch:_});if(r?.(n.node_id),e.forkFrom!==void 0)try{qe(n.node_id,X)}catch(t){throw b(n.node_id,"crash",{reason:"launch_failed",outcome:x(t)}),t}if(he(n.node_id,e.prompt),e.situationalContext!==void 0&&we(n.node_id,pe(e.situationalContext)),o!==void 0)try{o(n.node_id)}catch(t){throw b(n.node_id,"crash",{reason:"launch_failed",outcome:x(t)}),t}const R=e.prompt!=="",G=`${R&&e.wakeOrigin!==void 0?`${ye(e.wakeOrigin)}
1
+ var G=Object.defineProperty;var a=(e,o)=>G(e,"name",{value:o,configurable:!0});import{accessSync as J,constants as Q}from"node:fs";import{isAbsolute as Y,resolve as Z}from"node:path";import{spawnNode as ee,forkSourceNode as ne,currentNodeContext as oe,rootOfSpine as re,newNodeId as ie,preflightNodeId as te}from"./nodes.js";import{resolveProfileOperand as de}from"../profiles/manifest.js";import{selectProfileForCwd as ae,selectProfileForCwdReadOnly as se}from"../profiles/select.js";import{buildLaunchSpecAsync as j,buildPiArgv as ce}from"./launch.js";import{createManagedWorktreeAsync as le,rollbackManagedWorktreeAsync as fe}from"../worktree-mutation-async.js";import{usage as c,brokerLaunchFailed as O}from"../errors.js";import{writeGoal as ue}from"./kickoff.js";import{appendSituationalContext as me,formatSituationalProse as he}from"./situational-context.js";import{hasRoadmap as we,seedRoadmap as pe}from"./roadmap.js";import{buildWakeBearings as ke}from"./bearings.js";import{encodeKickoffOrigin as _e,KICKOFF_ORIGIN_ENV as ve}from"./stamp/protocol.js";import{beginExecution as ge,crtrHome as ye,getNode as w,fullName as W,jobDir as be,recordExecutionPid as xe,abortExecution as D,setFrozen as Ce}from"../canvas/index.js";import{contextDir as P,nodeAgentDir as I,reportsDir as Fe}from"../canvas/node-agent-paths.js";import{copyTreeBeneath as $e}from"../spaces/open-beneath.js";import{conversationIdFromPath as S,conversationStore as p}from"../conversation-store/index.js";import{boundFleet as Ee,brokerThresholdsForDaemon as Oe}from"./fleet.js";import{emitEvent as Se}from"../events/emit.js";import{openViewerWindow as Re,focusOf as De,windowOfPane as Pe}from"./placement.js";import{waitForBrokerViewSocket as Ie}from"./placement-tmux.js";import{transition as k}from"./lifecycle.js";import{beginBootFaultAttempt as Be}from"../canvas/recovery.js";import{headlessBrokerHost as B}from"./host.js";import{ensureDaemon as Ne}from"../../daemon/manage.js";import{readConfig as Le}from"../config.js";import{modelRequestFromConfig as Te,unregisteredConcreteModel as Ae}from"../model-routes.js";import{openModelRegistry as je}from"./model-registry.js";import{MODEL_SPEC_NEXT as We}from"./model-selection.js";import{initializeForkContextExposure as Me}from"../substrate/injected-store.js";import{discoverLifecycleHookRegistry as He}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as ze}from"../command-hooks/transport/exec-lifecycle.js";function _(e){return{detail:{schema:"crtr.node-outcome-detail/v1",message:e instanceof Error?e.message:String(e)}}}a(_,"launchFailureOutcome");async function Ke(e,o,d){try{return await B.launch(e,o,d)}catch(r){try{k(e,"crash",{reason:"launch_failed",outcome:_(r)})}catch{}const t=r.message;throw O(t.startsWith("[broker]")?t:`[broker] refusing to launch ${e}: ${t}`,"Inspect the cause above, fix the launch recipe or environment, then retry.")}}a(Ke,"launchBrokerOrCrash");function qe(e,o){try{k(e,"crash",{reason:"launch_failed",outcome:_(o)})}catch{}try{B.teardown(e)}catch{}}a(qe,"crashAndTearDown");function Ue(e){const o=p().list().map(({conversation_id:t,path:s})=>({id:t,path:s})),d=o.filter(t=>t.id===e),r=d.length>0?d:o.filter(t=>t.id.startsWith(e));if(r.length===0)throw c(`--fork-from '${e}': no pi session with that id found.`,{next:"Pass a live node id, a real session uuid/prefix, or an absolute .jsonl session path."});if(r.length>1)throw c(`--fork-from '${e}': ambiguous \u2014 ${r.length} sessions match that id prefix; pass the full id or the .jsonl path.`,{next:"Pass the full session uuid or an absolute .jsonl path to disambiguate."});return r[0].path}a(Ue,"resolveSessionUuid");function M(e){const o=e.trim();if(o==="")throw c("--fork-from requires a node id, session file, or session uuid.",{next:"Pass a live node id, an absolute .jsonl session path, or a session uuid/prefix."});if(o.includes("/")||o.endsWith(".jsonl")){const r=S(Y(o)?o:Z(process.cwd(),o));if(r===null)throw c(`--fork-from '${o}': invalid conversation path.`,{next:"Pass a conversation file path or id."});return p().header(r).path}const d=w(o);if(d!==null){const r=d.pi_session_file;if(r==null||r==="")throw c(`node ${o} has no pi session yet \u2014 it has not captured a session FILE to fork from (the broker forks a .jsonl path, not a bare id).`,{next:"Pick a node that has captured a session, or drop --fork-from."});const t=S(r);if(t===null)throw c(`node ${o} has no valid conversation id.`,{next:"Pick a node with a captured conversation."});return p().header(t).path}return Ue(o)}a(M,"resolveForkSource");async function Ve(e,o,d,r={}){return e===null?null:e!==void 0&&e!==""?de(e).profileId:o!==null?w(o)?.profile_id??null:r.readOnlySelection===!0?se(d):ae(d)}a(Ve,"resolveProfileId");function H(e){const o=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Te(e.model,o,e.modelExact===!0)}a(H,"requestFromLaunch");async function z(e,o,d){if(e===void 0||e.kind==="logical")return;const r=Ae(e,d??await je(),o);if(r!==void 0)throw c(`model '${r.request.spec}' is not registered in this daemon.`,{received:r.request.spec,next:We})}a(z,"assertLaunchModelRegistered");function Xe(e,o,d){const r=e??o??null;if(!d&&r===null)throw new Error("spawnChild requires a calling node (CRTR_NODE_ID) or an explicit parent");return r}a(Xe,"resolveSpawner");async function K(e,o,d){try{Ne()}catch{}const r=oe(),t=e.root===!0,s=Xe(e.parent,r.nodeId??null,t),f=e.mode??"base",x=e.rootLifecycle??(t?"resident":"terminal"),q=t&&x==="resident",C=e.worktree===!0,v=C?e.nodeId??ie():e.nodeId;e.nodeId!==void 0&&te(e.nodeId);const g=await Ve(e.profile,s,e.cwd),N=(await j(e.kind,f,{lifecycle:x,hasManager:!t,model:e.model,modelOverride:e.model!==void 0,cwd:e.cwd,profileId:g})).launch;await z(H(N),{cwd:e.cwd,profileId:g});const u=e.forkFrom!==void 0?M(e.forkFrom):void 0,U=u===void 0?null:ne(u)?.node_id??null;let m,F=e.cwd;try{C&&(m=await le(e.worktreeCwd??e.cwd,v,e.worktreeBase),F=m.path);const y=C?(await j(e.kind,f,{lifecycle:x,hasManager:!t,model:e.model,modelOverride:e.model!==void 0,cwd:F,profileId:g})).launch:N;C&&await z(H(y),{cwd:F,profileId:g});const n=await ee({kind:e.kind,mode:f,lifecycle:x,cwd:F,name:e.name??e.kind,description:e.description,parent:t?null:s,creator:e.creator,spawnedBy:t?s??void 0:void 0,profile_id:g,...e.scopes===void 0?{}:{scopes:e.scopes},...e.run===void 0?{}:{run:e.run},...e.withinCreate===void 0?{}:{withinCreate:e.withinCreate},forkFrom:e.forkFrom,forkSourceFile:u,modelOverride:e.model===void 0?void 0:y.model,...m!==void 0?{managedWorktree:m}:{},...v!==void 0?{nodeId:v}:{},...e.reviewBinding===void 0?{}:{reviewBinding:e.reviewBinding},...e.deadlineAt===void 0?{}:{deadlineAt:e.deadlineAt},...e.outcomeDelivery===void 0?{}:{outcomeDelivery:e.outcomeDelivery},launch:y});if(d?.(n.node_id),e.forkFrom!==void 0)try{Me(n.node_id,U)}catch(i){throw k(n.node_id,"crash",{reason:"launch_failed",outcome:_(i)}),i}if(ue(n.node_id,e.prompt),e.situationalContext!==void 0&&me(n.node_id,he(e.situationalContext)),o!==void 0)try{o(n.node_id)}catch(i){throw k(n.node_id,"crash",{reason:"launch_failed",outcome:_(i)}),i}const R=e.prompt!=="",V=`${R&&e.wakeOrigin!==void 0?`${ke(e.wakeOrigin)}
2
2
 
3
- `:""}${e.prompt}`;l==="orchestrator"&&!ke(n.node_id)&&_e(n.node_id,{goal:e.prompt.trim()}),await Ze(n);const h=fe(n,{prompt:G,forkFrom:O});if(h.env={...h.env,CRTR_SUBTREE:te(n.node_id)},R){const t=e.wakeOrigin!==void 0?{type:"runtime",kind:"wake",wake:e.wakeOrigin}:{type:"runtime",kind:"kickoff",...n.spawned_by!=null&&n.spawned_by!==""?{spawnedBy:n.spawned_by}:{}};h.env[ge]=ve(t)}const S=Re();if(!S.reserveSlot(n.node_id))return Ee(n.node_id,new Date().toISOString()),Ie({level:"info",event:"broker.frozen",node_id:n.node_id,fields:{live_count:S.size(),hard_cap:De().automaticReviveCap}}),{node:w(n.node_id),frozen:!0,window:null,session:null};const J=Te(n.node_id),y=be(n.node_id,{daemonEpoch:S.epoch()});h.env={...h.env,CRTR_EXECUTION_ID:y};let $;try{$=Xe(n.node_id,h,{cwd:n.cwd,name:H(n),resuming:!1})}catch(t){throw P(y,{reason:"launch_failed"}),t}finally{S.releaseReservation(n.node_id)}if($.pid===null){const t=new Error(`broker host returned no pid for ${n.node_id}`);throw P(y,{reason:"launch_failed"}),b(n.node_id,"crash",{reason:"launch_failed",outcome:x(t)}),E(`failed to launch the broker engine for ${n.node_id} (${n.name}) \u2014 the node was not started.`,`Inspect canonical event diagnostics with \`crtr sys logs --node ${n.node_id}\`, then verify the pi engine can start in this environment.`)}if(Se(y,n.node_id,$.pid)==="shutdown")throw P(y,{reason:"superseded"}),j.teardown(n.node_id),E(`broker execution was superseded for ${n.node_id}`,"Retry spawning the node.");if(F&&e.readiness==="await"&&!await Ne(n.node_id,$.exited)){const t=J.explanation();throw Ge(n.node_id,new Error(t??`broker view socket never bound for ${n.node_id}`)),E(t!==null?`the root broker ${n.node_id} could not start \u2014 ${t}`:`the root broker ${n.node_id} never bound its view socket \u2014 it was not started.`,t!==null?"Resolve the cause named above, then retry.":`The broker engine exited before binding its view socket. Inspect canonical event diagnostics with \`crtr sys logs --node ${n.node_id}\`, then retry.`)}let T=null,L=null;if(!d&&a!==null&&Ae("user").auto_open_child_viewers)try{const t=Pe(a);if(t!==null&&t.pane!==null&&t.pane!==""){const v=Be(n.node_id,t.session??"",{name:H(n),cwd:e.cwd,besidePane:t.pane,waitForBroker:!0,initialWhip:R});v!==null&&v.pane!==null&&v.pane!==""&&(L=v.session,T=je(v.pane))}}catch{}return{node:w(n.node_id),frozen:!1,window:T,session:L}}catch(_){throw m!==void 0&&p!==void 0&&w(p)===null&&await me(m),_}}c(U,"spawnChildPrepared");async function Pn(e){return U(e)}c(Pn,"spawnChild");async function Ze(e){const o=Ue(e.cwd,e.profile_id).plans.get("node:start")??[];await Ve(o,{node:{id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,cwd:e.cwd,nodeDir:Ce(e.node_id),contextDir:B(e.node_id),jobDir:Oe(e.node_id),reportsDir:$e(e.node_id)},runtime:{isBirth:!0,canvasHome:xe(),profile:e.profile_id??null}})}c(Ze,"invokeBirthLifecycleHooks");const V=new Set(["initial-prompt.md","yield-message.md","result.json"]);async function jn(e,o){const r=w(e);if(r===null)throw f(`unknown node: ${e}`,{received:e,next:"List nodes and pass the id of a node with a captured pi session."});const i=K(e),d=B(e);try{W(i,A.R_OK),W(d,A.R_OK)}catch(a){throw new Error(`cannot fork ${e}: its conversation or context is unreadable \u2014 ${a.message}`)}return U({kind:r.kind,mode:"base",cwd:r.cwd,prompt:"",root:!0,readiness:"await",forkFrom:e,profile:r.profile_id,model:r.model_override??void 0,...o===void 0?{}:{scopes:o}},a=>{const l=B(a);for(const s of D(d,{withFileTypes:!0}))V.has(s.name)||Y(g(d,s.name),g(l,s.name),{recursive:!0,dereference:!1,force:!0});for(const s of V)ee(g(l,s),{recursive:!0,force:!0})})}c(jn,"forkNode");export{q as assertLaunchModelRegistered,jn as forkNode,Ze as invokeBirthLifecycleHooks,K as resolveForkSource,Qe as resolveProfileId,Ye as resolveSpawner,Pn as spawnChild,U as spawnChildPrepared};
3
+ `:""}${e.prompt}`;f==="orchestrator"&&!we(n.node_id)&&pe(n.node_id,{goal:e.prompt.trim()}),await Ge(n);let L;if(u!==void 0)try{const i=S(u);if(i===null)throw new Error(`invalid fork source ${u}`);const l=p().fork(i,n.node_id);L=p().header(l).path}catch(i){throw k(n.node_id,"crash",{reason:"launch_failed",outcome:_(i)}),i}const h=ce(n,{prompt:V,resumeSessionPath:L});if(h.env={...h.env,CRTR_SUBTREE:re(n.node_id)},R){const i=e.wakeOrigin!==void 0?{type:"runtime",kind:"wake",wake:e.wakeOrigin}:{type:"runtime",kind:"kickoff",...n.spawned_by!=null&&n.spawned_by!==""?{spawnedBy:n.spawned_by}:{}};h.env[ve]=_e(i)}const $=Ee();if(!$.reserveSlot(n.node_id))return Ce(n.node_id,new Date().toISOString()),Se({level:"info",event:"broker.frozen",node_id:n.node_id,fields:{live_count:$.size(),hard_cap:Oe().automaticReviveCap}}),{node:w(n.node_id),frozen:!0,window:null,session:null};const X=Be(n.node_id),b=ge(n.node_id,{daemonEpoch:$.epoch()});h.env={...h.env,CRTR_EXECUTION_ID:b};let E;try{E=await Ke(n.node_id,h,{cwd:n.cwd,name:W(n),resuming:!1})}catch(i){throw D(b,{reason:"launch_failed"}),i}finally{$.releaseReservation(n.node_id)}if(E.pid===null){const i=new Error(`broker host returned no pid for ${n.node_id}`);throw D(b,{reason:"launch_failed"}),k(n.node_id,"crash",{reason:"launch_failed",outcome:_(i)}),O(`failed to launch the broker engine for ${n.node_id} (${n.name}) \u2014 the node was not started.`,`Inspect canonical event diagnostics with \`crtr sys logs --node ${n.node_id}\`, then verify the pi engine can start in this environment.`)}if(xe(b,n.node_id,E.pid)==="shutdown")throw D(b,{reason:"superseded"}),B.teardown(n.node_id),O(`broker execution was superseded for ${n.node_id}`,"Retry spawning the node.");if(q&&e.readiness==="await"&&!await Ie(n.node_id,E.exited)){const i=X.explanation();throw qe(n.node_id,new Error(i??`broker view socket never bound for ${n.node_id}`)),O(i!==null?`the root broker ${n.node_id} could not start \u2014 ${i}`:`the root broker ${n.node_id} never bound its view socket \u2014 it was not started.`,i!==null?"Resolve the cause named above, then retry.":`The broker engine exited before binding its view socket. Inspect canonical event diagnostics with \`crtr sys logs --node ${n.node_id}\`, then retry.`)}let T=null,A=null;if(!t&&s!==null&&Le("user").auto_open_child_viewers)try{const i=De(s);if(i!==null&&i.pane!==null&&i.pane!==""){const l=Re(n.node_id,i.session??"",{name:W(n),cwd:e.cwd,besidePane:i.pane,waitForBroker:!0,initialWhip:R});l!==null&&l.pane!==null&&l.pane!==""&&(A=l.session,T=Pe(l.pane))}}catch{}return{node:w(n.node_id),frozen:!1,window:T,session:A}}catch(y){throw m!==void 0&&v!==void 0&&w(v)===null&&await fe(m),y}}a(K,"spawnChildPrepared");async function In(e){return K(e)}a(In,"spawnChild");async function Ge(e){const o=He(e.cwd,e.profile_id).plans.get("node:start")??[];await ze(o,{node:{id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,cwd:e.cwd,nodeDir:I(e.node_id),contextDir:P(e.node_id),jobDir:be(e.node_id),reportsDir:Fe(e.node_id)},runtime:{isBirth:!0,canvasHome:ye(),profile:e.profile_id??null}})}a(Ge,"invokeBirthLifecycleHooks");const Je=new Set(["initial-prompt.md","yield-message.md","result.json","jobs"]);async function Bn(e,o){const d=w(e);if(d===null)throw c(`unknown node: ${e}`,{received:e,next:"List nodes and pass the id of a node with a captured pi session."});const r=M(e),t=P(e);try{p().header(S(r)),J(t,Q.R_OK)}catch(s){throw new Error(`cannot fork ${e}: its conversation or context is unreadable \u2014 ${s.message}`)}return K({kind:d.kind,mode:"base",cwd:d.cwd,prompt:"",root:!0,readiness:"await",forkFrom:e,profile:d.profile_id,model:d.model_override??void 0,...o===void 0?{}:{scopes:o}},s=>{const f=P(s);$e(I(e),t,I(s),f,Je)})}a(Bn,"forkNode");export{z as assertLaunchModelRegistered,Bn as forkNode,Ge as invokeBirthLifecycleHooks,M as resolveForkSource,Ve as resolveProfileId,Xe as resolveSpawner,In as spawnChild,K as spawnChildPrepared};