@north-light/crouter 0.3.353 → 0.3.355

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 (626) hide show
  1. package/dist/api/client.d.ts +35 -25
  2. package/dist/api/client.js +2 -2
  3. package/dist/api/dto/broker-ops.d.ts +2 -36
  4. package/dist/api/dto/canvas.d.ts +8 -13
  5. package/dist/api/dto/config.d.ts +4 -0
  6. package/dist/api/dto/delivery.d.ts +61 -0
  7. package/dist/api/dto/docs.d.ts +135 -0
  8. package/dist/api/dto/docs.js +1 -0
  9. package/dist/api/dto/health.d.ts +26 -79
  10. package/dist/api/dto/node-outcomes.d.ts +1 -3
  11. package/dist/api/dto/nodes.d.ts +5 -26
  12. package/dist/api/dto/objects.d.ts +168 -0
  13. package/dist/api/dto/objects.js +1 -0
  14. package/dist/api/dto/profiles.d.ts +14 -8
  15. package/dist/api/dto/reports.d.ts +9 -7
  16. package/dist/api/dto/reviews.d.ts +11 -3
  17. package/dist/api/dto/worktree.d.ts +1 -1
  18. package/dist/api/index.d.ts +0 -1
  19. package/dist/api/index.js +1 -1
  20. package/dist/api/routes.d.ts +14 -12
  21. package/dist/api/routes.js +1 -1
  22. package/dist/build-root.js +1 -1
  23. package/dist/builtin-memory/00-runtime-base/00-authoring.md +10 -5
  24. package/dist/builtin-memory/02-turn-lifecycle/02-resident.md +1 -0
  25. package/dist/builtin-memory/04-orchestration-kernel.md +10 -31
  26. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +1 -1
  27. package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
  28. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +2 -2
  29. package/dist/builtin-memory/crouter-concepts/INDEX.md +2 -2
  30. package/dist/builtin-memory/crouter-concepts/lifecycle-and-wakes.md +1 -1
  31. package/dist/builtin-memory/crouter-concepts/memory.md +15 -15
  32. package/dist/builtin-memory/crouter-concepts/nodes-and-the-canvas.md +1 -1
  33. package/dist/builtin-memory/crouter-concepts/profiles-kinds-and-modes.md +5 -5
  34. package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +1 -1
  35. package/dist/builtin-memory/crouter-concepts/why-a-daemon.md +1 -1
  36. package/dist/builtin-memory/crouter-sdk/INDEX.md +2 -2
  37. package/dist/builtin-memory/crouter-sdk/README.md +5 -6
  38. package/dist/builtin-memory/crouter-sdk/errors.md +0 -13
  39. package/dist/builtin-memory/crouter-sdk/guides/README.md +0 -1
  40. package/dist/builtin-memory/crouter-sdk/guides/event-driven-assistant.md +2 -2
  41. package/dist/builtin-memory/crouter-sdk/nodes.md +0 -2
  42. package/dist/builtin-memory/crouter-sdk/resources.md +0 -1
  43. package/dist/builtin-memory/explore/exploration-doc.md +4 -4
  44. package/dist/builtin-memory/insights/capture.md +6 -6
  45. package/dist/builtin-memory/insights/init.md +14 -14
  46. package/dist/builtin-memory/internal/INDEX.md +4 -4
  47. package/dist/builtin-memory/internal/agent-shaping.md +20 -20
  48. package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
  49. package/dist/builtin-memory/internal/marketplaces.md +2 -2
  50. package/dist/builtin-memory/internal/memory-loading.md +31 -30
  51. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  52. package/dist/builtin-memory/internal/plugins.md +16 -14
  53. package/dist/builtin-memory/internal/storage-tiers.md +4 -4
  54. package/dist/builtin-memory/memory-read-orientation.md +1 -1
  55. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +32 -40
  56. package/dist/clients/attach/input/controller.js +1 -1
  57. package/dist/clients/attach/input/ref-autocomplete.js +1 -1
  58. package/dist/clients/attach/input/titled-editor.js +1 -1
  59. package/dist/clients/attach/overlays/file-review.d.ts +1 -0
  60. package/dist/clients/attach/overlays/file-review.js +2 -2
  61. package/dist/clients/attach/render/chat-view.d.ts +6 -0
  62. package/dist/clients/attach/render/chat-view.js +2 -2
  63. package/dist/clients/attach/render/crtr-output.d.ts +1 -2
  64. package/dist/clients/attach/render/crtr-output.js +17 -17
  65. package/dist/clients/attach/render/doc-links.d.ts +34 -0
  66. package/dist/clients/attach/render/doc-links.js +1 -0
  67. package/dist/clients/attach/render/group-activity.d.ts +8 -8
  68. package/dist/clients/attach/render/group-activity.js +2 -2
  69. package/dist/clients/attach/render/group-recap.js +1 -1
  70. package/dist/clients/attach/render/markdown-source.js +5 -5
  71. package/dist/clients/attach/render/tool-calls.d.ts +1 -1
  72. package/dist/clients/attach/session/doc-materialize.d.ts +53 -0
  73. package/dist/clients/attach/session/doc-materialize.js +3 -0
  74. package/dist/clients/attach/session/document-links.d.ts +21 -0
  75. package/dist/clients/attach/session/document-links.js +1 -0
  76. package/dist/clients/attach/session/file-links.d.ts +2 -0
  77. package/dist/clients/attach/session/file-links.js +1 -1
  78. package/dist/clients/attach/session/profile-files.js +1 -1
  79. package/dist/clients/attach/slash/dispatch.js +1 -1
  80. package/dist/clients/attach/viewer.js +816 -1561
  81. package/dist/clients/inbox/review/review-client.d.ts +5 -1
  82. package/dist/clients/inbox/review/review-client.js +1 -1
  83. package/dist/commands/api-client.d.ts +2 -0
  84. package/dist/commands/api-client.js +3 -3
  85. package/dist/commands/canvas/edges.d.ts +2 -0
  86. package/dist/commands/canvas/edges.js +2 -0
  87. package/dist/commands/canvas/list.d.ts +4 -0
  88. package/dist/commands/canvas/list.js +3 -0
  89. package/dist/commands/canvas/read.d.ts +8 -0
  90. package/dist/commands/canvas/read.js +5 -0
  91. package/dist/commands/canvas/search.d.ts +2 -0
  92. package/dist/commands/canvas/search.js +3 -0
  93. package/dist/commands/canvas/unwatch.d.ts +2 -0
  94. package/dist/commands/canvas/unwatch.js +1 -0
  95. package/dist/commands/canvas/watch.d.ts +3 -0
  96. package/dist/commands/canvas/watch.js +1 -0
  97. package/dist/commands/canvas-analytics.js +1 -1
  98. package/dist/commands/canvas-history/grep.js +4 -4
  99. package/dist/commands/canvas-history/read.js +2 -2
  100. package/dist/commands/canvas-history/search.js +7 -7
  101. package/dist/commands/canvas-history/shared.d.ts +0 -1
  102. package/dist/commands/canvas-history/shared.js +1 -1
  103. package/dist/commands/canvas-history/stats.js +2 -2
  104. package/dist/commands/canvas-history.js +1 -1
  105. package/dist/commands/canvas.js +1 -1
  106. package/dist/commands/doc/delete.d.ts +2 -0
  107. package/dist/commands/doc/delete.js +1 -0
  108. package/dist/commands/doc/edit.d.ts +2 -0
  109. package/dist/commands/doc/edit.js +1 -0
  110. package/dist/commands/doc/history.d.ts +2 -0
  111. package/dist/commands/doc/history.js +2 -0
  112. package/dist/commands/doc/lint.d.ts +2 -0
  113. package/dist/commands/doc/lint.js +2 -0
  114. package/dist/commands/doc/list.d.ts +2 -0
  115. package/dist/commands/doc/list.js +1 -0
  116. package/dist/commands/doc/move.d.ts +2 -0
  117. package/dist/commands/doc/move.js +1 -0
  118. package/dist/commands/doc/read.d.ts +2 -0
  119. package/dist/commands/doc/read.js +1 -0
  120. package/dist/commands/doc/shared.d.ts +25 -0
  121. package/dist/commands/doc/shared.js +2 -0
  122. package/dist/commands/doc/write.d.ts +2 -0
  123. package/dist/commands/doc/write.js +1 -0
  124. package/dist/commands/{memory.d.ts → doc.d.ts} +1 -1
  125. package/dist/commands/doc.js +1 -0
  126. package/dist/commands/human/review.js +1 -1
  127. package/dist/commands/node/bash.js +2 -2
  128. package/dist/commands/node/create.js +1 -1
  129. package/dist/commands/node/inspect.js +10 -10
  130. package/dist/commands/node/lifecycle.js +2 -2
  131. package/dist/commands/node/outcome.js +1 -1
  132. package/dist/commands/node/subscription.js +1 -1
  133. package/dist/commands/node-context.js +2 -2
  134. package/dist/commands/pkg/browse/catalog.js +1 -1
  135. package/dist/commands/pkg/browse/doc-view.js +1 -1
  136. package/dist/commands/pkg/browse/model.d.ts +9 -17
  137. package/dist/commands/pkg/plugin-inspect.js +1 -1
  138. package/dist/commands/pkg/plugin-manage.d.ts +4 -8
  139. package/dist/commands/pkg/plugin-manage.js +15 -17
  140. package/dist/commands/profile/list.js +1 -1
  141. package/dist/commands/profile/new.js +1 -1
  142. package/dist/commands/profile/project.js +1 -1
  143. package/dist/commands/profile/show.js +1 -1
  144. package/dist/commands/push.js +3 -3
  145. package/dist/commands/sys/config.js +1 -1
  146. package/dist/commands/sys/context/admin/actions.d.ts +18 -43
  147. package/dist/commands/sys/context/admin/actions.js +1 -2
  148. package/dist/commands/sys/context/admin/detail-panel.d.ts +17 -25
  149. package/dist/commands/sys/context/admin/detail-panel.js +2 -1
  150. package/dist/commands/sys/context/admin/docs-panel.d.ts +7 -6
  151. package/dist/commands/sys/context/admin/docs-panel.js +1 -1
  152. package/dist/commands/sys/context/admin/list-view.d.ts +12 -12
  153. package/dist/commands/sys/context/admin/list-view.js +1 -1
  154. package/dist/commands/sys/context/admin/model.d.ts +96 -69
  155. package/dist/commands/sys/context/admin/model.js +1 -1
  156. package/dist/commands/sys/context/admin/rail-panel.d.ts +7 -5
  157. package/dist/commands/sys/context/admin/rail-panel.js +1 -1
  158. package/dist/commands/sys/context/admin/read-view.d.ts +10 -14
  159. package/dist/commands/sys/context/admin/read-view.js +1 -2
  160. package/dist/commands/sys/context/admin/shell.d.ts +26 -31
  161. package/dist/commands/sys/context/admin/shell.js +1 -1
  162. package/dist/commands/sys/context/admin.js +2 -2
  163. package/dist/commands/sys/context/doc.js +2 -3
  164. package/dist/commands/sys/context/expose.js +2 -2
  165. package/dist/commands/sys/context/prompt-review.js +4 -4
  166. package/dist/commands/sys/context/resolve.d.ts +92 -65
  167. package/dist/commands/sys/context/resolve.js +7 -9
  168. package/dist/commands/sys/context.js +1 -1
  169. package/dist/commands/sys/doctor.js +1 -1
  170. package/dist/commands/sys/migrate.js +1 -1
  171. package/dist/commands/sys/panels/profiles-panel.d.ts +3 -1
  172. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  173. package/dist/commands/sys/sync-deps.d.ts +6 -11
  174. package/dist/commands/sys/sync-deps.js +7 -8
  175. package/dist/commands/sys/sync-project-guidance.js +5 -4
  176. package/dist/commands/sys/sync-shared.d.ts +41 -4
  177. package/dist/commands/sys/sync-shared.js +1 -1
  178. package/dist/commands/sys/sync-skills.js +2 -2
  179. package/dist/commands/sys/sync.js +1 -1
  180. package/dist/core/bash-job-supervisor.d.ts +2 -3
  181. package/dist/core/bash-job-supervisor.js +3 -3
  182. package/dist/core/bash-jobs.d.ts +0 -5
  183. package/dist/core/bash-jobs.js +7 -7
  184. package/dist/core/bootstrap.js +2 -2
  185. package/dist/core/canvas/canvas.d.ts +6 -50
  186. package/dist/core/canvas/canvas.js +16 -21
  187. package/dist/core/canvas/db.d.ts +4 -1
  188. package/dist/core/canvas/db.js +2 -2
  189. package/dist/core/canvas/history.d.ts +11 -39
  190. package/dist/core/canvas/history.js +9 -20
  191. package/dist/core/canvas/install-id.d.ts +2 -2
  192. package/dist/core/canvas/install-id.js +1 -1
  193. package/dist/core/canvas/memory-reads.d.ts +5 -0
  194. package/dist/core/canvas/memory-reads.js +1 -1
  195. package/dist/core/canvas/migrations.js +215 -41
  196. package/dist/core/canvas/node-agent-paths.js +1 -1
  197. package/dist/core/canvas/node-tokens.js +1 -1
  198. package/dist/core/canvas/paths.d.ts +0 -4
  199. package/dist/core/canvas/paths.js +1 -1
  200. package/dist/core/canvas/remote-canvas-source.d.ts +0 -1
  201. package/dist/core/canvas/remote-canvas-source.js +1 -1
  202. package/dist/core/canvas/render-source.d.ts +9 -6
  203. package/dist/core/canvas/render-source.js +6 -6
  204. package/dist/core/canvas/sessions.js +2 -2
  205. package/dist/core/canvas/source.d.ts +6 -0
  206. package/dist/core/canvas/tree.d.ts +29 -0
  207. package/dist/core/canvas/tree.js +12 -0
  208. package/dist/core/canvas/types.d.ts +0 -20
  209. package/dist/core/command-plugins/bundle.js +1 -1
  210. package/dist/core/config.d.ts +1 -1
  211. package/dist/core/conversation-store/listener.js +4 -2
  212. package/dist/core/feed/feed.d.ts +9 -7
  213. package/dist/core/feed/feed.js +3 -7
  214. package/dist/core/feed/inbox.d.ts +3 -5
  215. package/dist/core/feed/inbox.js +1 -10
  216. package/dist/core/feed/messages.d.ts +33 -6
  217. package/dist/core/feed/messages.js +10 -7
  218. package/dist/core/feed/reports.d.ts +10 -0
  219. package/dist/core/feed/reports.js +2 -0
  220. package/dist/core/grants/remove.js +1 -1
  221. package/dist/core/graph/access.d.ts +24 -0
  222. package/dist/core/graph/access.js +8 -0
  223. package/dist/core/graph/bodies.d.ts +6 -0
  224. package/dist/core/graph/bodies.js +1 -0
  225. package/dist/core/graph/deletion.d.ts +10 -0
  226. package/dist/core/graph/deletion.js +5 -0
  227. package/dist/core/graph/diff.d.ts +4 -0
  228. package/dist/core/graph/diff.js +4 -0
  229. package/dist/core/graph/documents.d.ts +167 -0
  230. package/dist/core/graph/documents.js +10 -0
  231. package/dist/core/graph/edges.d.ts +25 -0
  232. package/dist/core/graph/edges.js +1 -0
  233. package/dist/core/graph/events.d.ts +26 -0
  234. package/dist/core/graph/events.js +7 -0
  235. package/dist/core/graph/exposures.d.ts +53 -0
  236. package/dist/core/graph/exposures.js +4 -0
  237. package/dist/core/graph/jobs.d.ts +31 -0
  238. package/dist/core/graph/jobs.js +2 -0
  239. package/dist/core/graph/names.d.ts +30 -0
  240. package/dist/core/graph/names.js +3 -0
  241. package/dist/core/graph/objects.d.ts +55 -0
  242. package/dist/core/graph/objects.js +9 -0
  243. package/dist/core/graph/package-docs.d.ts +31 -0
  244. package/dist/core/graph/package-docs.js +5 -0
  245. package/dist/core/graph/package-files.d.ts +20 -0
  246. package/dist/core/graph/package-files.js +2 -0
  247. package/dist/core/graph/reader.d.ts +21 -0
  248. package/dist/core/graph/reader.js +3 -0
  249. package/dist/core/graph/repo-sync/exchange.d.ts +34 -0
  250. package/dist/core/graph/repo-sync/exchange.js +2 -0
  251. package/dist/core/graph/repo-sync/identity.d.ts +30 -0
  252. package/dist/core/graph/repo-sync/identity.js +1 -0
  253. package/dist/core/graph/repo-sync/index.d.ts +4 -0
  254. package/dist/core/graph/repo-sync/index.js +1 -0
  255. package/dist/core/graph/repo-sync/mirror.d.ts +30 -0
  256. package/dist/core/graph/repo-sync/mirror.js +6 -0
  257. package/dist/core/graph/repo-sync/ref-format.d.ts +76 -0
  258. package/dist/core/graph/repo-sync/ref-format.js +2 -0
  259. package/dist/core/graph/repo-sync/repos.d.ts +17 -0
  260. package/dist/core/graph/repo-sync/repos.js +3 -0
  261. package/dist/core/graph/repo-sync/sync.d.ts +42 -0
  262. package/dist/core/graph/repo-sync/sync.js +2 -0
  263. package/dist/core/graph/rules.d.ts +26 -0
  264. package/dist/core/graph/rules.js +3 -0
  265. package/dist/core/graph/spaces/app.d.ts +3 -0
  266. package/dist/core/graph/spaces/app.js +1 -0
  267. package/dist/core/graph/spaces/index.d.ts +19 -0
  268. package/dist/core/graph/spaces/index.js +1 -0
  269. package/dist/core/graph/spaces/person.d.ts +5 -0
  270. package/dist/core/graph/spaces/person.js +2 -0
  271. package/dist/core/graph/spaces/repo.d.ts +4 -0
  272. package/dist/core/graph/spaces/repo.js +1 -0
  273. package/dist/core/graph/types.d.ts +75 -0
  274. package/dist/core/graph/types.js +1 -0
  275. package/dist/core/graph/watches.d.ts +62 -0
  276. package/dist/core/graph/watches.js +18 -0
  277. package/dist/core/human/feedback-companion.js +1 -1
  278. package/dist/core/human/requests.d.ts +3 -1
  279. package/dist/core/human/requests.js +6 -6
  280. package/dist/core/inspector/model.js +2 -2
  281. package/dist/core/io.js +5 -5
  282. package/dist/core/layout-migrate/index.d.ts +24 -1
  283. package/dist/core/layout-migrate/index.js +4 -4
  284. package/dist/core/layout-migrate/paths.d.ts +4 -0
  285. package/dist/core/layout-migrate/paths.js +1 -1
  286. package/dist/core/layout-migrate/stored-paths.d.ts +7 -0
  287. package/dist/core/layout-migrate/stored-paths.js +11 -11
  288. package/dist/core/layout-migrate/stores.d.ts +19 -6
  289. package/dist/core/layout-migrate/stores.js +3 -4
  290. package/dist/core/manifest.d.ts +0 -2
  291. package/dist/core/manifest.js +1 -1
  292. package/dist/core/{memory/extensions.d.ts → plugin-extensions.d.ts} +9 -10
  293. package/dist/core/plugin-extensions.js +1 -0
  294. package/dist/core/preview-registry.d.ts +1 -1
  295. package/dist/core/preview-registry.js +3 -2
  296. package/dist/core/profiles/manifest.d.ts +7 -7
  297. package/dist/core/profiles/manifest.js +1 -1
  298. package/dist/core/profiles/select.js +3 -3
  299. package/dist/core/review/birth.js +1 -1
  300. package/dist/core/review/companion.js +1 -1
  301. package/dist/core/review/stage.d.ts +12 -1
  302. package/dist/core/review/stage.js +1 -1
  303. package/dist/core/review/store.d.ts +2 -0
  304. package/dist/core/review/store.js +1 -1
  305. package/dist/core/review/types.d.ts +7 -1
  306. package/dist/core/runs/events.js +1 -1
  307. package/dist/core/runs/operations.js +5 -5
  308. package/dist/core/runs/questions.js +2 -2
  309. package/dist/core/runtime/bearings-render.d.ts +13 -7
  310. package/dist/core/runtime/bearings-render.js +12 -12
  311. package/dist/core/runtime/bearings.d.ts +8 -18
  312. package/dist/core/runtime/bearings.js +7 -7
  313. package/dist/core/runtime/broker/daemon-ops.d.ts +7 -12
  314. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  315. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  316. package/dist/core/runtime/broker/fault-retry.js +1 -1
  317. package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
  318. package/dist/core/runtime/broker/frame-memory-refs.d.ts +7 -2
  319. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  320. package/dist/core/runtime/broker/inbox.d.ts +1 -4
  321. package/dist/core/runtime/broker/inbox.js +1 -10
  322. package/dist/core/runtime/broker/rebind.js +1 -1
  323. package/dist/core/runtime/broker/retry-card-elision.d.ts +7 -0
  324. package/dist/core/runtime/broker/retry-card-elision.js +1 -0
  325. package/dist/core/runtime/broker-extension-render.d.ts +0 -13
  326. package/dist/core/runtime/broker-extension-render.js +2 -4
  327. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  328. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  329. package/dist/core/runtime/broker.js +1 -1
  330. package/dist/core/runtime/close.d.ts +9 -4
  331. package/dist/core/runtime/close.js +1 -1
  332. package/dist/core/runtime/deliver-live.js +1 -1
  333. package/dist/core/runtime/kickoff.js +17 -19
  334. package/dist/core/runtime/launch-target.d.ts +7 -0
  335. package/dist/core/runtime/launch-target.js +1 -1
  336. package/dist/core/runtime/ledger.d.ts +10 -0
  337. package/dist/core/runtime/ledger.js +3 -0
  338. package/dist/core/runtime/lifecycle.js +2 -2
  339. package/dist/core/runtime/nodes.d.ts +10 -2
  340. package/dist/core/runtime/nodes.js +1 -1
  341. package/dist/core/runtime/outcome-document.d.ts +2 -2
  342. package/dist/core/runtime/outcome-document.js +1 -1
  343. package/dist/core/runtime/persona.js +2 -2
  344. package/dist/core/runtime/placement.js +1 -1
  345. package/dist/core/runtime/promote.d.ts +2 -2
  346. package/dist/core/runtime/promote.js +1 -1
  347. package/dist/core/runtime/prospective-inventory-cli.js +2 -2
  348. package/dist/core/runtime/recycle.js +1 -1
  349. package/dist/core/runtime/reopen.js +1 -1
  350. package/dist/core/runtime/revive.js +2 -2
  351. package/dist/core/runtime/roadmap.d.ts +20 -9
  352. package/dist/core/runtime/roadmap.js +10 -6
  353. package/dist/core/runtime/spawn-env.js +1 -1
  354. package/dist/core/runtime/spawn.d.ts +5 -3
  355. package/dist/core/runtime/spawn.js +2 -2
  356. package/dist/core/runtime/structured-output.d.ts +3 -1
  357. package/dist/core/runtime/structured-output.js +4 -4
  358. package/dist/core/scope.d.ts +1 -32
  359. package/dist/core/scope.js +1 -1
  360. package/dist/core/scoped-state/db.js +2 -1
  361. package/dist/core/scoped-state/migrate.js +2 -2
  362. package/dist/core/scoped-state/profiles.d.ts +11 -0
  363. package/dist/core/scoped-state/profiles.js +1 -1
  364. package/dist/core/scoped-state/schema.d.ts +1 -1
  365. package/dist/core/scoped-state/schema.js +7 -5
  366. package/dist/core/spaces/permissions.d.ts +0 -14
  367. package/dist/core/spaces/permissions.js +1 -1
  368. package/dist/core/spaces/stop.d.ts +13 -0
  369. package/dist/core/spaces/stop.js +2 -2
  370. package/dist/core/storage/tables.d.ts +1 -1
  371. package/dist/core/substrate/delivery/corpus.d.ts +21 -0
  372. package/dist/core/substrate/delivery/corpus.js +3 -0
  373. package/dist/core/substrate/delivery/deliver.d.ts +76 -0
  374. package/dist/core/substrate/delivery/deliver.js +6 -0
  375. package/dist/core/substrate/delivery/listings.d.ts +30 -0
  376. package/dist/core/substrate/delivery/listings.js +7 -0
  377. package/dist/core/substrate/delivery/match.d.ts +28 -0
  378. package/dist/core/substrate/delivery/match.js +1 -0
  379. package/dist/core/substrate/delivery/plan.d.ts +67 -0
  380. package/dist/core/substrate/delivery/plan.js +3 -0
  381. package/dist/core/substrate/delivery/render-boot.d.ts +20 -0
  382. package/dist/core/substrate/delivery/render-boot.js +54 -0
  383. package/dist/core/substrate/delivery/render-event.d.ts +54 -0
  384. package/dist/core/substrate/delivery/render-event.js +8 -0
  385. package/dist/core/substrate/delivery/sub-persona-menu.d.ts +2 -0
  386. package/dist/core/substrate/delivery/sub-persona-menu.js +6 -0
  387. package/dist/core/substrate/delivery/types.d.ts +30 -0
  388. package/dist/core/substrate/delivery/types.js +0 -0
  389. package/dist/core/substrate/gate-explain.d.ts +0 -13
  390. package/dist/core/substrate/gate-explain.js +1 -1
  391. package/dist/core/substrate/schema.d.ts +11 -139
  392. package/dist/core/substrate/schema.js +1 -1
  393. package/dist/core/substrate/subject-fields.d.ts +3 -0
  394. package/dist/core/substrate/subject.d.ts +2 -1
  395. package/dist/core/substrate/subject.js +1 -1
  396. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  397. package/dist/daemon/api/handlers/bash-jobs.js +1 -2
  398. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  399. package/dist/daemon/api/handlers/canvas.js +5 -5
  400. package/dist/daemon/api/handlers/daemon.js +1 -1
  401. package/dist/daemon/api/handlers/delivery.d.ts +2 -0
  402. package/dist/daemon/api/handlers/delivery.js +1 -0
  403. package/dist/daemon/api/handlers/{memory.d.ts → docs.d.ts} +1 -1
  404. package/dist/daemon/api/handlers/docs.js +1 -0
  405. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  406. package/dist/daemon/api/handlers/messages.js +2 -2
  407. package/dist/daemon/api/handlers/node-records.js +2 -2
  408. package/dist/daemon/api/handlers/nodes.js +1 -1
  409. package/dist/daemon/api/handlers/objects.d.ts +2 -0
  410. package/dist/daemon/api/handlers/objects.js +5 -0
  411. package/dist/daemon/api/handlers/package-docs.d.ts +2 -0
  412. package/dist/daemon/api/handlers/package-docs.js +1 -0
  413. package/dist/daemon/api/handlers/profiles.js +1 -1
  414. package/dist/daemon/api/handlers/reports.d.ts +2 -2
  415. package/dist/daemon/api/handlers/reports.js +4 -4
  416. package/dist/daemon/api/handlers/reviews.d.ts +4 -1
  417. package/dist/daemon/api/handlers/reviews.js +1 -1
  418. package/dist/daemon/api/map.d.ts +2 -2
  419. package/dist/daemon/api/map.js +2 -2
  420. package/dist/daemon/api/operations.d.ts +1 -1
  421. package/dist/daemon/api/operations.js +1 -1
  422. package/dist/daemon/api/reader.d.ts +17 -0
  423. package/dist/daemon/api/reader.js +1 -0
  424. package/dist/daemon/api/server.js +1 -1
  425. package/dist/daemon/control.d.ts +2 -3
  426. package/dist/daemon/crtrd.js +8 -6
  427. package/dist/daemon/fleet.js +4 -4
  428. package/dist/daemon/reconcilers/bash-deadline.d.ts +11 -1
  429. package/dist/daemon/reconcilers/bash-deadline.js +2 -1
  430. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  431. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  432. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  433. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  434. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -0
  435. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  436. package/dist/daemon/review/deliver.js +2 -2
  437. package/dist/daemon/review/finish.js +1 -1
  438. package/dist/hook-authoring.d.ts +0 -1
  439. package/dist/hook-authoring.js +3 -3
  440. package/dist/migrations/004-canvas-documents/apply.d.ts +10 -0
  441. package/dist/migrations/004-canvas-documents/apply.js +1 -0
  442. package/dist/migrations/004-canvas-documents/fields.d.ts +24 -0
  443. package/dist/migrations/004-canvas-documents/fields.js +2 -0
  444. package/dist/migrations/004-canvas-documents/index.d.ts +16 -0
  445. package/dist/migrations/004-canvas-documents/index.js +2 -0
  446. package/dist/migrations/004-canvas-documents/legacy/discover.d.ts +16 -0
  447. package/dist/migrations/004-canvas-documents/legacy/discover.js +1 -0
  448. package/dist/migrations/004-canvas-documents/legacy/history.d.ts +5 -0
  449. package/dist/migrations/004-canvas-documents/legacy/history.js +2 -0
  450. package/dist/migrations/004-canvas-documents/legacy/nested.d.ts +7 -0
  451. package/dist/migrations/004-canvas-documents/legacy/nested.js +1 -0
  452. package/dist/migrations/004-canvas-documents/legacy/parse.d.ts +14 -0
  453. package/dist/migrations/004-canvas-documents/legacy/parse.js +1 -0
  454. package/dist/migrations/004-canvas-documents/legacy/types.d.ts +91 -0
  455. package/dist/migrations/004-canvas-documents/legacy/types.js +0 -0
  456. package/dist/migrations/004-canvas-documents/legacy-edges.d.ts +6 -0
  457. package/dist/migrations/004-canvas-documents/legacy-edges.js +18 -0
  458. package/dist/migrations/004-canvas-documents/plan.d.ts +102 -0
  459. package/dist/migrations/004-canvas-documents/plan.js +3 -0
  460. package/dist/migrations/004-canvas-documents/pointers.d.ts +23 -0
  461. package/dist/migrations/004-canvas-documents/pointers.js +4 -0
  462. package/dist/migrations/activation.d.ts +9 -18
  463. package/dist/migrations/activation.js +2 -2
  464. package/dist/pi-extensions/broker-local.d.ts +2 -2
  465. package/dist/pi-extensions/broker-local.js +2 -2
  466. package/dist/pi-extensions/canvas-bash-valve.js +5 -4
  467. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  468. package/dist/pi-extensions/canvas-doc-substrate.d.ts +0 -1
  469. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  470. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  471. package/dist/pi-extensions/canvas-passive-context.js +1 -1
  472. package/dist/pi-extensions/canvas-recap.js +2 -2
  473. package/dist/pi-extensions/canvas-stophook.d.ts +1 -1
  474. package/dist/pi-extensions/canvas-stophook.js +1 -1
  475. package/dist/prompts/review.js +3 -3
  476. package/dist/shared/env.d.ts +5 -0
  477. package/dist/shared/env.js +1 -1
  478. package/dist/shared/generated-context.js +2 -10
  479. package/dist/shared/inbox-entry-body.d.ts +22 -0
  480. package/dist/shared/inbox-entry-body.js +10 -0
  481. package/dist/{core/memory → shared}/inline-ref-guidance.d.ts +2 -2
  482. package/dist/shared/inline-ref-guidance.js +2 -0
  483. package/dist/types.d.ts +3 -1
  484. package/docs/cli/memory-and-preferences.md +12 -14
  485. package/docs/concepts/README.md +1 -1
  486. package/docs/concepts/lifecycle-and-wakes.md +1 -1
  487. package/docs/concepts/memory.md +15 -15
  488. package/docs/concepts/nodes-and-the-canvas.md +1 -1
  489. package/docs/concepts/profiles-kinds-and-modes.md +5 -5
  490. package/docs/concepts/scopes-and-trust.md +1 -1
  491. package/docs/concepts/why-a-daemon.md +1 -1
  492. package/docs/sdk/README.md +5 -6
  493. package/docs/sdk/errors.md +0 -13
  494. package/docs/sdk/guides/README.md +0 -1
  495. package/docs/sdk/nodes.md +0 -2
  496. package/docs/sdk/resources.md +0 -1
  497. package/package.json +2 -2
  498. package/packages/crouter-identity/package.json +1 -1
  499. package/runtime.lock.json +11 -11
  500. package/scripts/lib/isolation-env.mjs +8 -2
  501. package/dist/api/dto/memory.d.ts +0 -171
  502. package/dist/api/dto/memory.js +0 -1
  503. package/dist/builtin-memory/crouter-sdk/guides/app-memory.md +0 -73
  504. package/dist/builtin-memory/crouter-sdk/memory.md +0 -87
  505. package/dist/commands/broker-permissions.d.ts +0 -2
  506. package/dist/commands/broker-permissions.js +0 -1
  507. package/dist/commands/memory/client.d.ts +0 -11
  508. package/dist/commands/memory/client.js +0 -1
  509. package/dist/commands/memory/delete.d.ts +0 -1
  510. package/dist/commands/memory/delete.js +0 -1
  511. package/dist/commands/memory/edit.d.ts +0 -1
  512. package/dist/commands/memory/edit.js +0 -21
  513. package/dist/commands/memory/find.d.ts +0 -1
  514. package/dist/commands/memory/find.js +0 -1
  515. package/dist/commands/memory/history.d.ts +0 -1
  516. package/dist/commands/memory/history.js +0 -5
  517. package/dist/commands/memory/lint.d.ts +0 -1
  518. package/dist/commands/memory/lint.js +0 -1
  519. package/dist/commands/memory/list.d.ts +0 -1
  520. package/dist/commands/memory/list.js +0 -1
  521. package/dist/commands/memory/move.d.ts +0 -1
  522. package/dist/commands/memory/move.js +0 -1
  523. package/dist/commands/memory/origin.d.ts +0 -1
  524. package/dist/commands/memory/origin.js +0 -1
  525. package/dist/commands/memory/read.d.ts +0 -1
  526. package/dist/commands/memory/read.js +0 -6
  527. package/dist/commands/memory/shared.d.ts +0 -22
  528. package/dist/commands/memory/shared.js +0 -1
  529. package/dist/commands/memory/write.d.ts +0 -1
  530. package/dist/commands/memory/write.js +0 -13
  531. package/dist/commands/memory.js +0 -1
  532. package/dist/commands/node-inspect-artifacts.d.ts +0 -1
  533. package/dist/commands/node-inspect-artifacts.js +0 -8
  534. package/dist/core/help/memory-extensions.d.ts +0 -3
  535. package/dist/core/help/memory-extensions.js +0 -2
  536. package/dist/core/memory/cli-selector.d.ts +0 -13
  537. package/dist/core/memory/cli-selector.js +0 -1
  538. package/dist/core/memory/doc-link-grammar.d.ts +0 -20
  539. package/dist/core/memory/doc-link-grammar.js +0 -2
  540. package/dist/core/memory/extensions.js +0 -1
  541. package/dist/core/memory/history.d.ts +0 -87
  542. package/dist/core/memory/history.js +0 -6
  543. package/dist/core/memory/identity.d.ts +0 -65
  544. package/dist/core/memory/identity.js +0 -1
  545. package/dist/core/memory/inline-ref-guidance.js +0 -2
  546. package/dist/core/memory/inline-ref-inventory.d.ts +0 -9
  547. package/dist/core/memory/inline-ref-inventory.js +0 -1
  548. package/dist/core/memory/lint.d.ts +0 -163
  549. package/dist/core/memory/lint.js +0 -2
  550. package/dist/core/memory/mutation-domain.d.ts +0 -113
  551. package/dist/core/memory/mutation-domain.js +0 -12
  552. package/dist/core/memory/mutations.d.ts +0 -74
  553. package/dist/core/memory/mutations.js +0 -1
  554. package/dist/core/memory/project-namespace.d.ts +0 -31
  555. package/dist/core/memory/project-namespace.js +0 -2
  556. package/dist/core/memory/repository-association.d.ts +0 -31
  557. package/dist/core/memory/repository-association.js +0 -1
  558. package/dist/core/memory/service.d.ts +0 -145
  559. package/dist/core/memory/service.js +0 -2
  560. package/dist/core/memory/tree.d.ts +0 -39
  561. package/dist/core/memory/tree.js +0 -1
  562. package/dist/core/memory-resolver.d.ts +0 -280
  563. package/dist/core/memory-resolver.js +0 -2
  564. package/dist/core/nested-stores.d.ts +0 -18
  565. package/dist/core/nested-stores.js +0 -1
  566. package/dist/core/runtime/memory.d.ts +0 -3
  567. package/dist/core/runtime/memory.js +0 -1
  568. package/dist/core/substrate/frontmatter-validation.d.ts +0 -11
  569. package/dist/core/substrate/frontmatter-validation.js +0 -1
  570. package/dist/core/substrate/gate.d.ts +0 -16
  571. package/dist/core/substrate/gate.js +0 -1
  572. package/dist/core/substrate/index.d.ts +0 -18
  573. package/dist/core/substrate/index.js +0 -1
  574. package/dist/core/substrate/injected-store.d.ts +0 -75
  575. package/dist/core/substrate/injected-store.js +0 -2
  576. package/dist/core/substrate/listings.d.ts +0 -28
  577. package/dist/core/substrate/listings.js +0 -1
  578. package/dist/core/substrate/memory-events.d.ts +0 -6
  579. package/dist/core/substrate/memory-events.js +0 -1
  580. package/dist/core/substrate/on-read-node.d.ts +0 -6
  581. package/dist/core/substrate/on-read-node.js +0 -1
  582. package/dist/core/substrate/on-read.d.ts +0 -101
  583. package/dist/core/substrate/on-read.js +0 -9
  584. package/dist/core/substrate/plan.d.ts +0 -94
  585. package/dist/core/substrate/plan.js +0 -1
  586. package/dist/core/substrate/render-node.d.ts +0 -12
  587. package/dist/core/substrate/render-node.js +0 -1
  588. package/dist/core/substrate/render.d.ts +0 -41
  589. package/dist/core/substrate/render.js +0 -65
  590. package/dist/core/substrate/session-cache.d.ts +0 -27
  591. package/dist/core/substrate/session-cache.js +0 -1
  592. package/dist/core/substrate/surface-match.d.ts +0 -73
  593. package/dist/core/substrate/surface-match.js +0 -1
  594. package/dist/daemon/api/handlers/memory.js +0 -5
  595. package/dist/migrations/001-surfaces-frontmatter.d.ts +0 -2
  596. package/dist/migrations/001-surfaces-frontmatter.js +0 -1
  597. package/dist/migrations/002-profile-project-memory.d.ts +0 -2
  598. package/dist/migrations/002-profile-project-memory.js +0 -1
  599. package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +0 -26
  600. package/dist/migrations/003-repository-root-memory-identity/front-door.js +0 -11
  601. package/dist/migrations/003-repository-root-memory-identity/index.d.ts +0 -2
  602. package/dist/migrations/003-repository-root-memory-identity/index.js +0 -5
  603. package/dist/migrations/003-repository-root-memory-identity/references.d.ts +0 -95
  604. package/dist/migrations/003-repository-root-memory-identity/references.js +0 -5
  605. package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +0 -39
  606. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +0 -3
  607. package/dist/migrations/convergent.d.ts +0 -43
  608. package/dist/migrations/convergent.js +0 -2
  609. package/dist/migrations/corpus.d.ts +0 -75
  610. package/dist/migrations/corpus.js +0 -3
  611. package/dist/migrations/frontmatter-splice.d.ts +0 -15
  612. package/dist/migrations/frontmatter-splice.js +0 -8
  613. package/dist/migrations/profile-manifests.d.ts +0 -30
  614. package/dist/migrations/profile-manifests.js +0 -2
  615. package/dist/migrations/registry.d.ts +0 -7
  616. package/dist/migrations/registry.js +0 -1
  617. package/dist/migrations/runner.d.ts +0 -43
  618. package/dist/migrations/runner.js +0 -1
  619. package/dist/migrations/types.d.ts +0 -211
  620. package/dist/shared/birth-announcement.d.ts +0 -12
  621. package/dist/shared/birth-announcement.js +0 -1
  622. package/docs/sdk/guides/app-memory.md +0 -22
  623. package/docs/sdk/memory.md +0 -85
  624. /package/dist/{migrations/types.js → api/dto/delivery.js} +0 -0
  625. /package/dist/{core/memory → shared}/inline-ref-grammar.d.ts +0 -0
  626. /package/dist/{core/memory → shared}/inline-ref-grammar.js +0 -0
@@ -1,3 +1,3 @@
1
- var d=Object.defineProperty;var o=(e,t)=>d(e,"name",{value:t,configurable:!0});import{readFileSync as u,writeFileSync as f}from"node:fs";import{DefaultResourceLoader as g,ExtensionRunner as l,getAgentDir as w}from"@earendil-works/pi-coding-agent";import{buildRefInventory as y}from"../memory/inline-ref-inventory.js";import{gatewayCommandRows as x,gatewayMemoryRows as h}from"./chat-inventory-rows.js";import{captureChatCapabilities as C,registrationChatSurface as S,templateChatSurface as b}from"./command-surface.js";function E(){const e=JSON.parse(u(0,"utf8"));if(typeof e!="object"||e===null)throw new Error("preflight input must be an object");const t=e.extensions;if(!Array.isArray(t)||!t.every(s=>typeof s=="string"))throw new Error("preflight input extensions must be strings");return{extensions:t}}o(E,"parseInput");async function R(){const{extensions:e}=E(),t=process.cwd(),s=new g({cwd:t,agentDir:w(),additionalExtensionPaths:e,noContextFiles:!0});await s.reload();const r=s.getExtensions(),i=s.getPrompts().prompts,a=new l(r.extensions,r.runtime,t,void 0,void 0).getRegisteredCommands();C({commands:a,templates:i});const m=[...a.map(n=>{const c=n.expansion;return{name:n.invocationName,description:n.description??"",source:"command",...c!==void 0?{expansion:c}:{},...S(n)}}),...i.map(n=>({name:n.name,description:n.description,source:"template",template:n.content,...b(n)}))],p=y();f(3,`${JSON.stringify({commands:x(m),memory_refs:h(p.refs)})}
2
- `)}o(R,"main"),R().catch(e=>{process.stderr.write(`${e instanceof Error?e.stack??e.message:String(e)}
1
+ var m=Object.defineProperty;var o=(e,t)=>m(e,"name",{value:t,configurable:!0});import{readFileSync as d,writeFileSync as u}from"node:fs";import{DefaultResourceLoader as f,ExtensionRunner as g,getAgentDir as l}from"@earendil-works/pi-coding-agent";import{gatewayCommandRows as w}from"./chat-inventory-rows.js";import{captureChatCapabilities as x,registrationChatSurface as y,templateChatSurface as h}from"./command-surface.js";function C(){const e=JSON.parse(d(0,"utf8"));if(typeof e!="object"||e===null)throw new Error("preflight input must be an object");const t=e.extensions;if(!Array.isArray(t)||!t.every(s=>typeof s=="string"))throw new Error("preflight input extensions must be strings");return{extensions:t}}o(C,"parseInput");async function S(){const{extensions:e}=C(),t=process.cwd(),s=new f({cwd:t,agentDir:l(),additionalExtensionPaths:e,noContextFiles:!0});await s.reload();const r=s.getExtensions(),i=s.getPrompts().prompts,a=new g(r.extensions,r.runtime,t,void 0,void 0).getRegisteredCommands();x({commands:a,templates:i});const p=[...a.map(n=>{const c=n.expansion;return{name:n.invocationName,description:n.description??"",source:"command",...c!==void 0?{expansion:c}:{},...y(n)}}),...i.map(n=>({name:n.name,description:n.description,source:"template",template:n.content,...h(n)}))];u(3,`${JSON.stringify({commands:w(p),memory_refs:[]})}
2
+ `)}o(S,"main"),S().catch(e=>{process.stderr.write(`${e instanceof Error?e.stack??e.message:String(e)}
3
3
  `),process.exitCode=1});
@@ -1 +1 @@
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
+ var w=Object.defineProperty;var r=(e,t)=>w(e,"name",{value:t,configurable:!0});import{abortExecution as y,beginExecution as _,getNode as s,setPresence as h,setFocusOccupant as v,fullName as R,recordExecutionPid as b,recordLaunch as E}from"../canvas/index.js";import{pushFinal as k}from"../feed/feed.js";import{newestReportBody as g}from"../feed/reports.js";import{spawnNode as x,rootOfSpine as S}from"./nodes.js";import{buildLaunchSpecAsync as T,buildPiArgv as B}from"./launch.js";import{focusOf as N,respawnPaneSync as O,setPaneOption as P}from"./placement.js";import{waitForBrokerViewSocket as C,viewerSplitEnv as D}from"./placement-tmux.js";import{headlessBrokerHost as u}from"./host.js";import{boundFleet as F}from"./fleet.js";import{transition as z}from"./lifecycle.js";import{ensureDaemon as A}from"../../daemon/manage.js";import{invokeBirthLifecycleHooks as L}from"./spawn.js";async function ne(e,t){const n=s(e);if(n===null)return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const o=t??process.env.TMUX_PANE;if(o===void 0||o==="")return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const f=N(e);try{A()}catch{}const{launch:m}=await T("general","base",{lifecycle:"resident",hasManager:!1,cwd:n.cwd,profileId:n.profile_id}),p=g(e)||`Closed via recycle \u2014 no final summary was authored by ${n.name}.`;let a=[],d=!1;const i=await x({kind:"general",mode:"base",lifecycle:"resident",cwd:n.cwd,name:"general",parent:null,replaces:e,profile_id:n.profile_id,launch:m,beforeCreate:r(async()=>{try{a=(await k(e,p)).deliveredTo,d=!0}catch{}},"beforeCreate")}),c=s(i.node_id);await L(c);const l=B(c);if(l.env={...l.env,CRTR_SUBTREE:S(i.node_id)},!await U(c,l))return{recycled:!1,finalized:d,newRoot:i.node_id,delivered:a};try{u.teardown(e)}catch{}try{h(e,{pane:null,window:null,tmux_session:null})}catch{}if(f!==null)try{v(f.focus_id,i.node_id)}catch{}return{recycled:M(c,o),finalized:d,newRoot:i.node_id,delivered:a}}r(ne,"recycleNode");async function U(e,t){const n=_(e.node_id,{daemonEpoch:F().epoch()});t.env={...t.env,CRTR_EXECUTION_ID:n};let o;try{if(o=await u.launch(e.node_id,t,{cwd:e.cwd,name:R(e),resuming:!1}),o.pid===null)throw new Error("broker host returned no pid");if(E(e.node_id,new Date().toISOString()),b(n,e.node_id,o.pid)==="shutdown")throw new Error("broker execution was superseded");if(await C(e.node_id,o.exited))return!0}catch{y(n,{reason:"launch_failed"})}try{H(e.node_id)}catch{}try{u.teardown(e.node_id)}catch{}return!1}r(U,"launchRecycledBroker");function H(e){const t=s(e);(t?.status==="active"||t?.status==="idle")&&z(e,"crash")}r(H,"transitionReplacementToDead");function M(e,t){try{P(t,"@crtr_node","")}catch{}return O({pane:t,cwd:e.cwd,env:D(),command:`crtr surface attach to ${e.node_id}`})}r(M,"respawnRecycledViewer");export{ne as recycleNode};
@@ -1 +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,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
+ var s=Object.defineProperty;var n=(e,t)=>s(e,"name",{value:t,configurable:!0});import{clearFinalReportIfMatches as l,getFinalReport as c,getNode as p,updateNode as u}from"../canvas/index.js";import{InputError as i}from"../io.js";import{transition as f}from"./lifecycle.js";import{noticeChangedWhileDone as h}from"./ledger.js";function o(e){return c(e)}n(o,"currentFinalReport");function m(e,t){throw new i({error:"node_finalized",message:`${e} already submitted its canonical final result (\`crtr canvas read ${e}/${t}\`) \u2014 reviving it now would hand it a mandate it can never finish, since a second \`push final\` always errors against an already-latched node.`,next:`Re-run this exact command with --reopen to clear ${e}'s spent latch and re-task it in place.`})}n(m,"throwNodeFinalized");function d(e){throw new i({error:"not_finalized",message:`${e} is not finalized \u2014 --reopen has nothing to clear.`,next:"Drop --reopen."})}n(d,"throwNotFinalized");function w(e){const t=o(e);t!==null&&m(e,t)}n(w,"assertNotFinalized");function g(e){const t=o(e);return t===null&&d(e),t}n(g,"assertFinalizedForReopen");function R(e,t){if(!l(e,t))throw new i({error:"reopen_latch_changed",message:`${e}'s finalization latch changed since it was last inspected \u2014 a concurrent --reopen (or a fresh push final) already moved it, so clearing it now would risk erasing a newer canonical result.`,next:"Re-run this exact command \u2014 it will re-inspect the current state before acting."})}n(R,"commitReopen");function x(e,t){const r=o(e);u(e,{lifecycle:"resident"});const a=p(e);return a!==null&&(a.status==="done"||a.status==="canceled"||a.status==="dead")&&(a.status==="done"&&a.last_settled_at!=null&&h(e,a.last_settled_at),f(e,"revive")),r!==null&&R(e,t??r),r}n(x,"commitReopenResident");function y(e,t){if(t){const r=g(e);x(e,r);return}w(e)}n(y,"assertReopenGate");export{g as assertFinalizedForReopen,w as assertNotFinalized,y as assertReopenGate,R as commitReopen,x as commitReopenResident};
@@ -1,3 +1,3 @@
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}
1
+ var V=Object.defineProperty;var s=(e,r)=>V(e,"name",{value:r,configurable:!0});import{existsSync as P}from"node:fs";import{conversationIdFromPath as _,conversationStore as h,ConversationNotFoundError as O}from"../conversation-store/index.js";import{isAbsolute as X}from"node:path";import{findNodeBySessionFile as Y,getNode as g,updateNode as y,beginExecution as q,recordExecutionPid as Q,abortExecution as b,endLiveExecution as Z,unbindSession as A,recordLaunch as I,setFrozen as ee,clearFrozen as re,fullName as D}from"../canvas/index.js";import{emitEvent as ie}from"../events/emit.js";import{cancelCronsOnWake as ne}from"../canvas/crons.js";import{isParked as oe,transition as R}from"./lifecycle.js";import{publishNotice as te}from"./close.js";import{InputError as E}from"../io.js";import{buildPiArgv as m}from"./launch.js";import{buildReviveKickoff as se,drainBearings as le,hasRetainedReports as ce,readGoal as S,readYieldMessage as ae,RUNTIME_RESTART_CONTINUATION as ue}from"./kickoff.js";import{readRoadmap as T}from"./roadmap.js";import{encodeKickoffOrigin as fe,KICKOFF_ORIGIN_ENV as he}from"./stamp/protocol.js";import{headlessBrokerHost as B}from"./host.js";import{boundFleet as z,brokerCapReached as de,brokerThresholdsForDaemon as U}from"./fleet.js";import{beginBootFaultAttempt as pe,clearFault as ve}from"../canvas/recovery.js";import{clearNodeLedger as H,forkNodeLedger as we,noticeChangedWhileDone as _e}from"./ledger.js";import{forkSourceNode as me,rootOfSpine as ke}from"./nodes.js";import{isReviewCompanionBound as ge}from"../review/companion.js";import{assertProfileActive as ye}from"../profiles/manifest.js";import{isPidAlive as be}from"../canvas/pid.js";import{crtrHome as Re,jobDir as Ee}from"../canvas/paths.js";import{contextDir as Se,ensureNodeDirs as xe,nodeAgentDir as $e}from"../canvas/node-agent-paths.js";import{discoverLifecycleHookRegistry as Ne}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as Ce}from"../command-hooks/transport/exec-lifecycle.js";function Fe(e,r){const i=e.pi_session_file,n=i?_(i):null;if(n===null)return{};try{const t=h().header(n);return r?{resumeSessionPath:t.path}:{resumeSessionPath:t.path,newCycle:!0}}catch(t){if(t instanceof O)return{};throw t}}s(Fe,"resumeArgs");function K(e){const r=_(e);if(r===null)return!1;try{return h().header(r),!0}catch(i){if(i instanceof O)return!1;throw i}}s(K,"conversationExists");function Pe(e){const r=_(e);if(r===null)return!0;const i=h().header(r).header.cwd;return typeof i!="string"||P(i)}s(Pe,"sessionCwdExists");function Oe(e,r,i){const n=r.pi_session_file;if(!n||!K(n))return{};const t=Y(n);return t!==null&&t.node_id!==e&&be(t.pi_pid)?{}:Pe(n)?Fe(r,i):{}}s(Oe,"resumableSessionArgs");function Ae(e){return T(e)===null&&ae(e)===null&&!ce(e)}s(Ae,"isUnstartedBirth");function lr(e){const r=S(e);if(r!==null&&r.trim()!=="")return!0;const i=T(e);return i!==null&&i.trim()!==""}s(lr,"hasFreshGroundState");async function cr(e,r){const i=await L(e,r,!0);if(i.parked)throw new Error(`reviveNode: internal parked decision for activating revive ${e}`);return i.result}s(cr,"reviveNode");async function ar(e,r,i){return L(e,r,i)}s(ar,"decideAttachRevive");async function L(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.`);ye(n.profile_id);const t=z();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"&&oe(n))return{parked:!0};if(!t.reserveSlot(e)){if(r.capacity==="refuse")throw de(U().automaticReviveCap,t.size());return n.frozen_at==null&&(ee(e,new Date().toISOString()),Z(e,{reason:"frozen"}),ie({level:"info",event:"broker.frozen",node_id:e,fields:{live_count:t.size(),hard_cap:U().automaticReviveCap}})),{parked:!1,result:{window:null,session:n.tmux_session??null,resumed:!1,outcome:"frozen"}}}try{return{parked:!1,result:await De(e,n,r)}}finally{t.releaseReservation(e)}}s(L,"decideRevive");async function De(e,r,i){if(!P(r.cwd)){const d=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:d})}r.host_kind!=="broker"&&(y(e,{host_kind:"broker"}),r.host_kind="broker"),r.review_binding!=null&&!ge(e)&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(A(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"||!X(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&&!K(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=q(e,{daemonEpoch:z().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,p=f?{}:Oe(e,r,M),v=p.resumeSessionPath!==void 0,x=v&&p.newCycle===!0,k=v&&!x,$=!v&&(i.wakeReason===void 0||i.wakeReason==="runtime-restart-abort")&&Ae(e),G=f||$,N=r.cycle_pending===!0||x;y(e,{cycle_pending:N}),r.cycle_pending=N,!f&&!v&&(r.pi_session_id!=null||r.pi_session_file!=null)&&(A(e),r.pi_session_id=null,r.pi_session_file=null);let l,u=null;const C=s(()=>({type:"runtime",kind:"kickoff",...r.spawned_by!=null&&r.spawned_by!==""?{spawnedBy:r.spawned_by}:{}}),"birthOrigin");if(f){const o=S(e),F=_(c);if(F===null)throw new Error(`invalid fork source ${c}`);const J=h().header(h().fork(F,e)).path;l=m(r,{resumeSessionPath:J,...o!=null&&o!==""?{prompt:o}:{}}),o!=null&&o!==""&&(u=C()),we(e,me(c)?.node_id??null)}else if(k)l=m(r,{...p,...i.wakeReason==="runtime-restart-abort"?{prompt:ue}:{}}),i.wakeReason==="runtime-restart-abort"&&(u={type:"runtime",kind:"restart-continuation"});else if($){const o=S(e)?.trim();l=m(r,o!==void 0&&o!==""?{prompt:o}:{}),o!==void 0&&o!==""&&(u=C()),H(e)}else{const o=le(r,a);l=m(r,{...p,prompt:se(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},H(e)}l.env={...l.env,CRTR_SUBTREE:ke(e)},u!==null&&(l.env[he]=fe(u)),r.status==="done"&&r.last_settled_at!=null&&_e(e,r.last_settled_at),R(e,r.intent==="refresh"?"refresh-launch":"revive"),ve(e,{preserveEpisode:!0});const j=pe(e);i.recovery!==!0&&ne(e),xe(e,r.grantee);const W=Ne(r.cwd,r.profile_id).plans.get("node:start")??[];await Ce(W,{node:{id:e,name:r.name,kind:r.kind,mode:r.mode,lifecycle:r.lifecycle,cwd:r.cwd,nodeDir:$e(e),contextDir:Se(e),jobDir:Ee(e)},runtime:{isBirth:G,canvasHome:Re(),profile:r.profile_id??null}}),l.env={...l.env,CRTR_EXECUTION_ID:a};let w;try{if(w=await B.launch(e,l,{cwd:r.cwd,name:D(r),resuming:k}),w.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)}}}),te(e,"notice.crash",`Child crashed \u2014 ${D(r)} (${e}) failed to relaunch and is now dead: ${o.message}
2
2
 
3
- It stays dead until you revive it \u2014 \`crtr node lifecycle revive ${e}\`.`,{reason:"child-crashed",child:e})}catch{}throw 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};
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(I(e,new Date().toISOString()),Q(a,e,w.pid)==="shutdown")throw b(a,{reason:"superseded"}),B.teardown(e),new Error(`[broker] refusing to revive ${e}: execution was superseded during launch`);return re(e),{window:null,session:r.tmux_session??null,resumed:k,launch:w,faultExplanation:j.explanation,outcome:"launched"}}catch(d){throw b(a,{reason:"launch_failed"}),d}}s(De,"launchRevive");export{ar as decideAttachRevive,lr as hasFreshGroundState,Fe as resumeArgs,cr as reviveNode};
@@ -1,13 +1,24 @@
1
- export declare function roadmapPath(nodeId: string): string;
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ export declare const ROADMAP_NAME = "roadmap";
3
+ /** Fallback preview when the roadmap is seeded without a goal. */
4
+ export declare const ROADMAP_PREVIEW = "To understand this node's long-term task and current plan, read this.";
5
+ /** A roadmap's preview is its goal's first line; the fallback covers a goal-less seed. */
6
+ export declare function roadmapPreview(goal?: string): string;
7
+ /** How a node addresses its own roadmap in `crtr canvas read` / `crtr doc edit`. */
8
+ export declare function roadmapRef(nodeId: string): string;
2
9
  export declare function hasRoadmap(nodeId: string): boolean;
10
+ /** The roadmap's newest head body, or null when the node has none. */
3
11
  export declare function readRoadmap(nodeId: string): string | null;
4
- /** Seed a fresh, EXTREMELY BAREBONES roadmap scaffold — just the section
5
- * skeleton with one-line prompts. Promotion lays this down so the file exists
6
- * for a refresh; the owner fleshes it out as its next act (guided by its
7
- * roadmap memory doc). `goal`/`exitCriteria` pre-fill those sections when
8
- * known (e.g. from the node's goal doc). Idempotent only if you intend it —
9
- * call sites guard on hasRoadmap to avoid clobbering an evolved map. */
10
- export declare function seedRoadmap(nodeId: string, opts?: {
12
+ /** Seed a fresh, EXTREMELY BAREBONES roadmap document — the section skeleton
13
+ * with one-line prompts — authored by the node. The owner fleshes it out as
14
+ * its next act with `crtr doc edit roadmap`. Leaves an existing roadmap
15
+ * untouched and returns null; otherwise returns the seeded body. */
16
+ export declare function seedRoadmap(db: DatabaseSync, nodeId: string, opts?: {
11
17
  goal?: string;
12
18
  exitCriteria?: string;
13
- }): string;
19
+ }): string | null;
20
+ /** `seedRoadmap` in its own canvas write; true when it wrote one. */
21
+ export declare function ensureRoadmap(nodeId: string, opts?: {
22
+ goal?: string;
23
+ exitCriteria?: string;
24
+ }): boolean;
@@ -1,11 +1,15 @@
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
1
+ var l=Object.defineProperty;var r=(e,t)=>l(e,"name",{value:t,configurable:!0});import{openDb as u,withCanvasWrite as d}from"../canvas/db.js";import{get as s}from"../graph/bodies.js";import{heads as p,writeDocument as c}from"../graph/documents.js";import{getById as m,liveDocumentNamed as f,nodeObject as h}from"../graph/objects.js";import{readerForNode as g}from"../graph/reader.js";const i="roadmap",w="To understand this node's long-term task and current plan, read this.";function x(e){return e?.split(`
2
+ `).map(n=>n.trim()).find(n=>n!=="")??w}r(x,"roadmapPreview");function O(e){return`${e}/${i}`}r(O,"roadmapRef");function a(e,t){const n=m(e,t);return n===null||n.type!=="node"?null:f(e,n.rowid,i)}r(a,"roadmapObject");function P(e){return a(u(),e)!==null}r(P,"hasRoadmap");function W(e){const t=u(),n=a(t,e);if(n===null)return null;const o=p(t,n)[0];if(o===void 0)return null;try{return s(o.body_hash)}catch{return null}}r(W,"readRoadmap");function y(e){return`# Roadmap
2
3
 
3
4
  ## Goal
4
- ${t.goal?.trim()??"(the goal you now own)"}
5
+ ${e.goal?.trim()||"(the goal you now own)"}
5
6
 
6
7
  ## Exit criteria
7
- ${t.exitCriteria?.trim()??'(what "done" looks like)'}
8
+ ${e.exitCriteria?.trim()||'(what "done" looks like)'}
8
9
 
9
- ## Phases
10
- (ordered phases from here to done; the current one carries a one-line status)
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};
10
+ ## Where things stand
11
+ (present state at your level: settled, in flight, remaining)
12
+
13
+ ## Working set
14
+ (links to the documents the work depends on now, one per line)
15
+ `}r(y,"scaffold");function R(e,t,n={}){if(a(e,t)!==null)return null;const o=y(n);return c(e,g(e,t,()=>[]),{owner:h(e,t),name:i,kind:"knowledge",preview:x(n.goal),privacy:"public",rules:[{on:"boot",deliver:"content"}]},o),o}r(R,"seedRoadmap");function $(e,t={}){return d(n=>R(n,e,t)!==null)}r($,"ensureRoadmap");export{i as ROADMAP_NAME,w as ROADMAP_PREVIEW,$ as ensureRoadmap,P as hasRoadmap,W as readRoadmap,x as roadmapPreview,O as roadmapRef,R as seedRoadmap};
@@ -1 +1 @@
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
+ var p=Object.defineProperty;var l=(t,e)=>p(t,"name",{value:e,configurable:!0});import{statSync as E}from"node:fs";import{appSpace as d,layoutRoot as _,runtimeRoot as R}from"../layout.js";import{delimiter as T,join as m,resolve as O}from"node:path";import{readMergedLaunchConfig as P}from"../config.js";import{readProfileEnvVars as A}from"../profiles/env-store.js";import{loadProfileManifest as h,metadataEnvName as H,readProfileMetadata as I}from"../profiles/manifest.js";import{binShimDirFor as N}from"./bin-contributions.js";import{FRONT_DOOR_ENV as M}from"./front-door-env.js";const C=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_"],c="CRTR_ADMITTED_HOST_PATH";function v(t,e,o){const r=e.PATH;if(r===void 0||r==="")return null;for(const s of r.split(T)){const i=O(o,s===""?".":s,t);try{const n=E(i);if(n.isFile()&&(n.mode&73)!==0)return i}catch{}}return null}l(v,"resolvePathExecutable");function X(t,e,o){const r=e[c]??e.PATH;if(r===void 0||r==="")throw new Error(`cannot resolve crouter-owned ${t}: the admitted host PATH is empty`);const s=v(t,{PATH:r},o);if(s!==null)return s;throw new Error(`cannot resolve crouter-owned ${t} from the admitted host PATH`)}l(X,"resolveAdmittedHostCommand");const D=["HTTP_PROXY","HTTPS_PROXY","http_proxy","https_proxy"],u={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY"};function S(t){let e;try{e=new URL(t)}catch{return!1}return!(e.protocol!=="http:"&&e.protocol!=="https:"||e.hostname===""||e.username!==""||e.password!=="")}l(S,"isCredentialFreeProxyValue");function x(t,e){if(!e.includes("*"))return t===e;const o=e.split("*").map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${o}$`).test(t)}l(x,"matchesAllowPattern");function y(t){const e=t.host??process.env,o={};for(const[n,a]of Object.entries(e))a!==void 0&&(C.has(n)||w.some(f=>n.startsWith(f)))&&(o[n]=a);o.PWD=t.targetCwd;for(const n of D){const a=e[n];a!==void 0&&S(a)&&(o[n]=a)}const r=t.skipSpawnAllow?[]:P(t.targetCwd,t.targetProfileId).spawnEnv.allow;if(r.length>0)for(const[n,a]of Object.entries(e))a!==void 0&&r.some(f=>x(n,f))&&(o[n]=a);const s=e[c]??o.PATH;s!==void 0&&s!==""&&(o[c]=s);const i=N(t.targetCwd,t.targetProfileId);if(i!==null){const n=o.PATH;o.PATH=n===void 0||n===""?i:`${i}:${n}`}return o}l(y,"buildOperationalEnvBase");function L(t){const e={};for(const[o,r]of Object.entries(I(t)))e[H(o)]=r;return e}l(L,"profileMetadataEnv");function b(t,e,o){const r=e===null?null:h(e).manifest,s=r!==null&&(r.grantee??"app:terminal")===o,i=y({targetCwd:t,targetProfileId:e,skipSpawnAllow:o!=="app:terminal"}),n=d(o).home,a={...i,...r===null?{}:L(e),...s?A(e):{},HOME:n,PI_CODING_AGENT_DIR:m(n,".pi","agent"),[c]:i[c],...process.platform==="linux"?{}:{CRTR_HOME:_(),CRTR_RUNTIME_HOME:process.env.CRTR_RUNTIME_HOME??R()}};process.platform==="linux"&&delete a.CRTR_RUNTIME_HOME;for(const f of Object.values(u))delete a[f];return a}l(b,"buildAppProcessEnv");function K(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=b(e,o,r),i={...s,...t.env,HOME:s.HOME,PI_CODING_AGENT_DIR:s.PI_CODING_AGENT_DIR,[c]:s[c],[M]:"1"};process.platform==="linux"&&delete i.CRTR_RUNTIME_HOME;for(const n of Object.values(u))delete i[n];return i}l(K,"buildBrokerEnv");export{c as ADMITTED_HOST_PATH_ENV,u as PROVIDER_ENV_KEYS,b as buildAppProcessEnv,K as buildBrokerEnv,y as buildOperationalEnvBase,L as profileMetadataEnv,X as resolveAdmittedHostCommand,v as resolvePathExecutable};
@@ -12,9 +12,11 @@ export interface SpawnChildOpts {
12
12
  prompt: string;
13
13
  /** Override the parent (defaults to the calling node from env). */
14
14
  parent?: string;
15
- /** Actor that created this node. Unlike parent (manager) and spawned_by
16
- * (provenance), it controls the parent's birth announcement. */
15
+ /** Node that created this node. Unlike parent (manager) and spawned_by
16
+ * (provenance), it is the actor of the `created` push. */
17
17
  creator?: string | null;
18
+ /** Node acting when neither creator nor parent is (a node forking another). */
19
+ actor?: string | null;
18
20
  /** Spawn an INDEPENDENT root instead of a managed child: parent=null, no
19
21
  * subscription back to the spawner, spawned_by=spawner. Resident and brought
20
22
  * forefront by default — see `rootLifecycle` for the unattended variant. */
@@ -147,5 +149,5 @@ export declare function invokeBirthLifecycleHooks(meta: NodeMeta): Promise<void>
147
149
  * context. Runtime/graph state is intentionally not inherited. */
148
150
  /** Fork `sourceId` into a fresh root. `scopes` is the fork's allow-list; omit
149
151
  * for a root with no ceiling. */
150
- export declare function forkNode(sourceId: string, scopes?: string[]): Promise<SpawnChildResult>;
152
+ export declare function forkNode(sourceId: string, scopes?: string[], forker?: string): Promise<SpawnChildResult>;
151
153
  export {};
@@ -1,3 +1,3 @@
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)}
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 W,buildPiArgv as ce}from"./launch.js";import{createManagedWorktreeAsync as le,rollbackManagedWorktreeAsync as fe}from"../worktree-mutation-async.js";import{usage as l,brokerLaunchFailed as E}from"../errors.js";import{writeGoal as ue}from"./kickoff.js";import{appendSituationalContext as me,formatSituationalProse as he}from"./situational-context.js";import{ensureRoadmap as we}from"./roadmap.js";import{buildWakeBearings as pe}from"./bearings.js";import{encodeKickoffOrigin as ke,KICKOFF_ORIGIN_ENV as _e}from"./stamp/protocol.js";import{beginExecution as ve,crtrHome as ge,getNode as p,fullName as M,jobDir as ye,recordExecutionPid as be,abortExecution as P,setFrozen as xe}from"../canvas/index.js";import{contextDir as I,nodeAgentDir as D}from"../canvas/node-agent-paths.js";import{copyTreeBeneath as Ce}from"../spaces/open-beneath.js";import{conversationIdFromPath as S,conversationStore as k}from"../conversation-store/index.js";import{boundFleet as Fe,brokerThresholdsForDaemon as $e}from"./fleet.js";import{emitEvent as Oe}from"../events/emit.js";import{openViewerWindow as Ee,focusOf as Se,windowOfPane as Re}from"./placement.js";import{waitForBrokerViewSocket as Pe}from"./placement-tmux.js";import{transition as _}from"./lifecycle.js";import{beginBootFaultAttempt as Ie}from"../canvas/recovery.js";import{headlessBrokerHost as B}from"./host.js";import{ensureDaemon as De}from"../../daemon/manage.js";import{readConfig as Be}from"../config.js";import{modelRequestFromConfig as Ne,unregisteredConcreteModel as Le}from"../model-routes.js";import{openModelRegistry as Te}from"./model-registry.js";import{MODEL_SPEC_NEXT as Ae}from"./model-selection.js";import{forkNodeLedger as je}from"./ledger.js";import{discoverLifecycleHookRegistry as We}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as Me}from"../command-hooks/transport/exec-lifecycle.js";function v(e){return{detail:{schema:"crtr.node-outcome-detail/v1",message:e instanceof Error?e.message:String(e)}}}a(v,"launchFailureOutcome");async function He(e,o,d){try{return await B.launch(e,o,d)}catch(r){try{_(e,"crash",{reason:"launch_failed",outcome:v(r)})}catch{}const t=r.message;throw E(t.startsWith("[broker]")?t:`[broker] refusing to launch ${e}: ${t}`,"Inspect the cause above, fix the launch recipe or environment, then retry.")}}a(He,"launchBrokerOrCrash");function Ke(e,o){try{_(e,"crash",{reason:"launch_failed",outcome:v(o)})}catch{}try{B.teardown(e)}catch{}}a(Ke,"crashAndTearDown");function ze(e){const o=k().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 l(`--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 l(`--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(ze,"resolveSessionUuid");function H(e){const o=e.trim();if(o==="")throw l("--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 l(`--fork-from '${o}': invalid conversation path.`,{next:"Pass a conversation file path or id."});return k().header(r).path}const d=p(o);if(d!==null){const r=d.pi_session_file;if(r==null||r==="")throw l(`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 l(`node ${o} has no valid conversation id.`,{next:"Pick a node with a captured conversation."});return k().header(t).path}return ze(o)}a(H,"resolveForkSource");async function qe(e,o,d,r={}){return e===null?null:e!==void 0&&e!==""?de(e).profileId:o!==null?p(o)?.profile_id??null:r.readOnlySelection===!0?se(d):ae(d)}a(qe,"resolveProfileId");function K(e){const o=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Ne(e.model,o,e.modelExact===!0)}a(K,"requestFromLaunch");async function z(e,o,d){if(e===void 0||e.kind==="logical")return;const r=Le(e,d??await Te(),o);if(r!==void 0)throw l(`model '${r.request.spec}' is not registered in this daemon.`,{received:r.request.spec,next:Ae})}a(z,"assertLaunchModelRegistered");function Ue(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(Ue,"resolveSpawner");async function q(e,o,d){try{De()}catch{}const r=oe(),t=e.root===!0,s=Ue(e.parent,r.nodeId??null,t),c=e.mode??"base",u=e.rootLifecycle??(t?"resident":"terminal"),U=t&&u==="resident",C=e.worktree===!0,g=C?e.nodeId??ie():e.nodeId;e.nodeId!==void 0&&te(e.nodeId);const y=await qe(e.profile,s,e.cwd),N=(await W(e.kind,c,{lifecycle:u,hasManager:!t,model:e.model,modelOverride:e.model!==void 0,cwd:e.cwd,profileId:y})).launch;await z(K(N),{cwd:e.cwd,profileId:y});const m=e.forkFrom!==void 0?H(e.forkFrom):void 0,L=m===void 0?null:ne(m)?.node_id??null;let h,F=e.cwd;try{C&&(h=await le(e.worktreeCwd??e.cwd,g,e.worktreeBase),F=h.path);const b=C?(await W(e.kind,c,{lifecycle:u,hasManager:!t,model:e.model,modelOverride:e.model!==void 0,cwd:F,profileId:y})).launch:N;C&&await z(K(b),{cwd:F,profileId:y});const n=await ee({kind:e.kind,mode:c,lifecycle:u,cwd:F,name:e.name??e.kind,description:e.description,parent:t?null:s,creator:e.creator,...e.actor===void 0?{}:{actor:e.actor},forkSourceNode:L,spawnedBy:t?s??void 0:void 0,profile_id:y,...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:m,modelOverride:e.model===void 0?void 0:b.model,...h!==void 0?{managedWorktree:h}:{},...g!==void 0?{nodeId:g}:{},...e.reviewBinding===void 0?{}:{reviewBinding:e.reviewBinding},...e.deadlineAt===void 0?{}:{deadlineAt:e.deadlineAt},...e.outcomeDelivery===void 0?{}:{outcomeDelivery:e.outcomeDelivery},launch:b});if(d?.(n.node_id),e.forkFrom!==void 0)try{je(n.node_id,L??null)}catch(i){throw _(n.node_id,"crash",{reason:"launch_failed",outcome:v(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 _(n.node_id,"crash",{reason:"launch_failed",outcome:v(i)}),i}const R=e.prompt!=="",V=`${R&&e.wakeOrigin!==void 0?`${pe(e.wakeOrigin)}
2
2
 
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};
3
+ `:""}${e.prompt}`;c==="orchestrator"&&we(n.node_id,{goal:e.prompt.trim()}),await Ve(n);let T;if(m!==void 0)try{const i=S(m);if(i===null)throw new Error(`invalid fork source ${m}`);const f=k().fork(i,n.node_id);T=k().header(f).path}catch(i){throw _(n.node_id,"crash",{reason:"launch_failed",outcome:v(i)}),i}const w=ce(n,{prompt:V,resumeSessionPath:T});if(w.env={...w.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}:{}};w.env[_e]=ke(i)}const $=Fe();if(!$.reserveSlot(n.node_id))return xe(n.node_id,new Date().toISOString()),Oe({level:"info",event:"broker.frozen",node_id:n.node_id,fields:{live_count:$.size(),hard_cap:$e().automaticReviveCap}}),{node:p(n.node_id),frozen:!0,window:null,session:null};const X=Ie(n.node_id),x=ve(n.node_id,{daemonEpoch:$.epoch()});w.env={...w.env,CRTR_EXECUTION_ID:x};let O;try{O=await He(n.node_id,w,{cwd:n.cwd,name:M(n),resuming:!1})}catch(i){throw P(x,{reason:"launch_failed"}),i}finally{$.releaseReservation(n.node_id)}if(O.pid===null){const i=new Error(`broker host returned no pid for ${n.node_id}`);throw P(x,{reason:"launch_failed"}),_(n.node_id,"crash",{reason:"launch_failed",outcome:v(i)}),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(be(x,n.node_id,O.pid)==="shutdown")throw P(x,{reason:"superseded"}),B.teardown(n.node_id),E(`broker execution was superseded for ${n.node_id}`,"Retry spawning the node.");if(U&&e.readiness==="await"&&!await Pe(n.node_id,O.exited)){const i=X.explanation();throw Ke(n.node_id,new Error(i??`broker view socket never bound for ${n.node_id}`)),E(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 A=null,j=null;if(!t&&s!==null&&Be("user").auto_open_child_viewers)try{const i=Se(s);if(i!==null&&i.pane!==null&&i.pane!==""){const f=Ee(n.node_id,i.session??"",{name:M(n),cwd:e.cwd,besidePane:i.pane,waitForBroker:!0,initialWhip:R});f!==null&&f.pane!==null&&f.pane!==""&&(j=f.session,A=Re(f.pane))}}catch{}return{node:p(n.node_id),frozen:!1,window:A,session:j}}catch(b){throw h!==void 0&&g!==void 0&&p(g)===null&&await fe(h),b}}a(q,"spawnChildPrepared");async function Pn(e){return q(e)}a(Pn,"spawnChild");async function Ve(e){const o=We(e.cwd,e.profile_id).plans.get("node:start")??[];await Me(o,{node:{id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,cwd:e.cwd,nodeDir:D(e.node_id),contextDir:I(e.node_id),jobDir:ye(e.node_id)},runtime:{isBirth:!0,canvasHome:ge(),profile:e.profile_id??null}})}a(Ve,"invokeBirthLifecycleHooks");const Xe=new Set(["initial-prompt.md","yield-message.md","result.json","jobs"]);async function In(e,o,d){const r=p(e);if(r===null)throw l(`unknown node: ${e}`,{received:e,next:"List nodes and pass the id of a node with a captured pi session."});const t=H(e),s=I(e);try{k().header(S(t)),J(s,Q.R_OK)}catch(c){throw new Error(`cannot fork ${e}: its conversation or context is unreadable \u2014 ${c.message}`)}return q({kind:r.kind,mode:"base",cwd:r.cwd,prompt:"",root:!0,readiness:"await",forkFrom:e,...d===void 0?{}:{actor:d},profile:r.profile_id,model:r.model_override??void 0,...o===void 0?{}:{scopes:o}},c=>{const u=I(c);Ce(D(e),s,D(c),u,Xe)})}a(In,"forkNode");export{z as assertLaunchModelRegistered,In as forkNode,Ve as invokeBirthLifecycleHooks,H as resolveForkSource,qe as resolveProfileId,Ue as resolveSpawner,Pn as spawnChild,q as spawnChildPrepared};
@@ -3,6 +3,8 @@ export type StructuredOutputMode = 'terminal' | 'oneoff';
3
3
  export interface StructuredOutputRequest {
4
4
  mode: StructuredOutputMode;
5
5
  schema: Record<string, unknown>;
6
+ /** The one-off request's message id; its answer ends the requester's message watch. */
7
+ requestMessageId?: string;
6
8
  }
7
9
  /** Tri-state result of reading a structured-output request file. */
8
10
  export type StructuredOutputState = {
@@ -36,7 +38,7 @@ export interface OutputDeclined extends DeclinedResult {
36
38
  }
37
39
  export declare function parseOutputSchemaValue(value: string | undefined): Record<string, unknown> | null;
38
40
  /** Write a structured-output request atomically using temp-file-plus-rename. */
39
- export declare function writeOutputSchema(nodeId: string, mode: StructuredOutputMode, schema: Record<string, unknown>): string;
41
+ export declare function writeOutputSchema(nodeId: string, mode: StructuredOutputMode, schema: Record<string, unknown>, requestMessageId?: string): string;
40
42
  /** Read a structured-output request with full validation and error reporting.
41
43
  * Returns a tri-state: absent (file doesn't exist), valid (parsed successfully),
42
44
  * or invalid (file exists but is malformed). */
@@ -1,4 +1,4 @@
1
- var w=Object.defineProperty;var o=(t,e)=>w(t,"name",{value:e,configurable:!0});import{existsSync as d,mkdirSync as N,readFileSync as c,unlinkSync as S,writeFileSync as v,renameSync as $}from"node:fs";import{dirname as J,resolve as j}from"node:path";import{randomUUID as P}from"node:crypto";import{nodeDir as R,nodeRunDir as O,contextDir as b,nodeAgentDir as l}from"../canvas/paths.js";import{readTextBeneathIfExists as T,unlinkBeneath as _,writeFileBeneath as m}from"../spaces/open-beneath.js";import{InputError as p}from"../io.js";import{isRecord as h}from"../../shared/predicates.js";const H="A .json file path, or inline JSON beginning with `{`.",M='The full schema (including enum, pattern, and numeric bounds) is enforced when the target submits its result with `crtr push result`; a mismatch rejects with the field errors and records nothing, so an over-constrained schema costs the target retries. A target that cannot honestly satisfy the schema declines with `crtr push result --decline "<reason>" --code <token> [--retryable]`, which records a failure outcome with reason `declined` carrying the reason, code, and retryable flag instead of a value.';function i(t){return`${R(t)}/output-schema.json`}o(i,"outputSchemaPath");function f(t){return`${O(t)}/output-schema.json`}o(f,"brokerOutputSchemaPath");function q(t){const e=i(t),r=f(t);d(e)&&m(O(t),r,c(e),{atomic:!0})}o(q,"projectOutputSchema");function x(t,e){return`${b(t,e)}/result.json`}o(x,"outputResultPath");function V(t,e){const r=T(l(t,e),x(t,e));return r===null?void 0:JSON.parse(r)}o(V,"readOutputResult");function y(t,e){return`${b(t,e)}/declined.json`}o(y,"outputDeclinedPath");function W(t){const e=t?.trim();if(e===void 0||e==="")return null;let r,n;if(e.startsWith("{"))r=e,n="inline JSON";else{const u=j(e);n=u;try{r=c(u,"utf8")}catch(s){throw new p({error:"bad_output_schema",message:`could not read output schema from ${u}: ${s.message}`,field:"output-schema",next:"Pass a readable JSON Schema file path, or inline JSON beginning with `{`."})}}let a;try{a=JSON.parse(r)}catch(u){throw new p({error:"bad_output_schema",message:`output schema from ${n} is not valid JSON: ${u.message}`,field:"output-schema",next:"Pass valid JSON whose top-level value is an object."})}if(!h(a))throw new p({error:"bad_output_schema",message:`output schema from ${n} must be a JSON object`,field:"output-schema",next:"Pass a JSON Schema object, not an array, string, number, boolean, or null."});return a}o(W,"parseOutputSchemaValue");function z(t,e,r){const n=i(t);N(J(n),{recursive:!0});const u=`${JSON.stringify({mode:e,schema:r},null,2)}
2
- `,s=`${n}.${P()}.tmp`;return v(s,u,"utf8"),$(s,n),q(t),n}o(z,"writeOutputSchema");function G(t){return g(i(t))}o(G,"readOutputRequest");function K(t){return g(f(t))}o(K,"readBrokerOutputRequest");function g(t){if(!d(t))return{state:"absent"};let e;try{e=c(t,"utf8")}catch(u){return{state:"invalid",error:`could not read request file: ${u.message}`}}let r;try{r=JSON.parse(e)}catch(u){return{state:"invalid",error:`request file is not valid JSON: ${u.message}`}}if(!h(r))return{state:"invalid",error:"request file top-level value must be an object"};const n=r.mode,a=r.schema;return n!=="terminal"&&n!=="oneoff"?{state:"invalid",error:`mode must be 'terminal' or 'oneoff', got ${JSON.stringify(n)}`}:h(a)?{state:"valid",request:{mode:n,schema:a}}:{state:"invalid",error:`schema must be an object, got ${typeof a}`}}o(g,"readOutputRequestAt");async function L(t,e){const{validateToolArguments:r}=await import("@earendil-works/pi-ai");return r({name:"submit",description:"",parameters:t},{type:"toolCall",id:"structured-output",name:"submit",arguments:e})}o(L,"validateStructuredResult");function Q(t,e,r){const n=l(t,r),a=x(t,r);m(n,a,`${JSON.stringify(e,null,2)}
3
- `,{atomic:!0});try{_(n,y(t,r))}catch(u){if(u.code!=="ENOENT")throw u}return a}o(Q,"writeOutputResult");function X(t,e,r){const n=y(t,r);return m(l(t,r),n,`${JSON.stringify(e,null,2)}
4
- `,{atomic:!0}),n}o(X,"writeOutputDeclined");function Y(t){const e=i(t);try{S(e)}catch{}const r=f(t);try{S(r)}catch{}}o(Y,"removeOutputSchema");export{M as OUTPUT_SCHEMA_CONSTRAINTS,H as OUTPUT_SCHEMA_TRANSPORT,f as brokerOutputSchemaPath,y as outputDeclinedPath,x as outputResultPath,i as outputSchemaPath,W as parseOutputSchemaValue,q as projectOutputSchema,K as readBrokerOutputRequest,G as readOutputRequest,V as readOutputResult,Y as removeOutputSchema,L as validateStructuredResult,X as writeOutputDeclined,Q as writeOutputResult,z as writeOutputSchema};
1
+ var v=Object.defineProperty;var u=(t,e)=>v(t,"name",{value:e,configurable:!0});import{existsSync as S,mkdirSync as N,readFileSync as c,unlinkSync as O,writeFileSync as $,renameSync as J}from"node:fs";import{dirname as j,resolve as P}from"node:path";import{randomUUID as R}from"node:crypto";import{nodeDir as T,nodeRunDir as g,contextDir as y,nodeAgentDir as l}from"../canvas/paths.js";import{readTextBeneathIfExists as q,unlinkBeneath as _,writeFileBeneath as m}from"../spaces/open-beneath.js";import{InputError as p}from"../io.js";import{isRecord as h}from"../../shared/predicates.js";const H="A .json file path, or inline JSON beginning with `{`.",V='The full schema (including enum, pattern, and numeric bounds) is enforced when the target submits its result with `crtr push result`; a mismatch rejects with the field errors and records nothing, so an over-constrained schema costs the target retries. A target that cannot honestly satisfy the schema declines with `crtr push result --decline "<reason>" --code <token> [--retryable]`, which records a failure outcome with reason `declined` carrying the reason, code, and retryable flag instead of a value.';function i(t){return`${T(t)}/output-schema.json`}u(i,"outputSchemaPath");function f(t){return`${g(t)}/output-schema.json`}u(f,"brokerOutputSchemaPath");function A(t){const e=i(t),r=f(t);S(e)&&m(g(t),r,c(e),{atomic:!0})}u(A,"projectOutputSchema");function b(t,e){return`${y(t,e)}/result.json`}u(b,"outputResultPath");function W(t,e){const r=q(l(t,e),b(t,e));return r===null?void 0:JSON.parse(r)}u(W,"readOutputResult");function x(t,e){return`${y(t,e)}/declined.json`}u(x,"outputDeclinedPath");function z(t){const e=t?.trim();if(e===void 0||e==="")return null;let r,n;if(e.startsWith("{"))r=e,n="inline JSON";else{const o=P(e);n=o;try{r=c(o,"utf8")}catch(a){throw new p({error:"bad_output_schema",message:`could not read output schema from ${o}: ${a.message}`,field:"output-schema",next:"Pass a readable JSON Schema file path, or inline JSON beginning with `{`."})}}let s;try{s=JSON.parse(r)}catch(o){throw new p({error:"bad_output_schema",message:`output schema from ${n} is not valid JSON: ${o.message}`,field:"output-schema",next:"Pass valid JSON whose top-level value is an object."})}if(!h(s))throw new p({error:"bad_output_schema",message:`output schema from ${n} must be a JSON object`,field:"output-schema",next:"Pass a JSON Schema object, not an array, string, number, boolean, or null."});return s}u(z,"parseOutputSchemaValue");function G(t,e,r,n){const s=i(t);N(j(s),{recursive:!0});const o={mode:e,schema:r,...n===void 0?{}:{requestMessageId:n}},a=`${JSON.stringify(o,null,2)}
2
+ `,d=`${s}.${R()}.tmp`;return $(d,a,"utf8"),J(d,s),A(t),s}u(G,"writeOutputSchema");function K(t){return w(i(t))}u(K,"readOutputRequest");function L(t){return w(f(t))}u(L,"readBrokerOutputRequest");function w(t){if(!S(t))return{state:"absent"};let e;try{e=c(t,"utf8")}catch(a){return{state:"invalid",error:`could not read request file: ${a.message}`}}let r;try{r=JSON.parse(e)}catch(a){return{state:"invalid",error:`request file is not valid JSON: ${a.message}`}}if(!h(r))return{state:"invalid",error:"request file top-level value must be an object"};const n=r.mode,s=r.schema;if(n!=="terminal"&&n!=="oneoff")return{state:"invalid",error:`mode must be 'terminal' or 'oneoff', got ${JSON.stringify(n)}`};if(!h(s))return{state:"invalid",error:`schema must be an object, got ${typeof s}`};const o=r.requestMessageId;return o!==void 0&&typeof o!="string"?{state:"invalid",error:`requestMessageId must be a string, got ${typeof o}`}:{state:"valid",request:{mode:n,schema:s,...o===void 0?{}:{requestMessageId:o}}}}u(w,"readOutputRequestAt");async function Q(t,e){const{validateToolArguments:r}=await import("@earendil-works/pi-ai");return r({name:"submit",description:"",parameters:t},{type:"toolCall",id:"structured-output",name:"submit",arguments:e})}u(Q,"validateStructuredResult");function X(t,e,r){const n=l(t,r),s=b(t,r);m(n,s,`${JSON.stringify(e,null,2)}
3
+ `,{atomic:!0});try{_(n,x(t,r))}catch(o){if(o.code!=="ENOENT")throw o}return s}u(X,"writeOutputResult");function Y(t,e,r){const n=x(t,r);return m(l(t,r),n,`${JSON.stringify(e,null,2)}
4
+ `,{atomic:!0}),n}u(Y,"writeOutputDeclined");function Z(t){const e=i(t);try{O(e)}catch{}const r=f(t);try{O(r)}catch{}}u(Z,"removeOutputSchema");export{V as OUTPUT_SCHEMA_CONSTRAINTS,H as OUTPUT_SCHEMA_TRANSPORT,f as brokerOutputSchemaPath,x as outputDeclinedPath,b as outputResultPath,i as outputSchemaPath,z as parseOutputSchemaValue,A as projectOutputSchema,L as readBrokerOutputRequest,K as readOutputRequest,W as readOutputResult,Z as removeOutputSchema,Q as validateStructuredResult,Y as writeOutputDeclined,X as writeOutputResult,G as writeOutputSchema};
@@ -1,17 +1,4 @@
1
1
  import type { InstalledPlugin, Scope } from '../types.js';
2
- import type { ProfileProjectMemory } from '../api/dto/profiles.js';
3
- /** The ceiling a project root carries when no profile relationship contributes
4
- * it — the top rung, i.e. no cap at all. */
5
- export declare const NEUTRAL_PROJECT_MEMORY: ProfileProjectMemory;
6
- /** One resolved project scope root plus the selected profile relationship's
7
- * memory ceiling for it. The ceiling is INDEPENDENT of how the root was
8
- * discovered: a root reached by both cwd and a profile entry still takes that
9
- * entry's value (first entry in manifest order wins). */
10
- export interface ProjectScopeRoot {
11
- /** Absolute path of the `.crouter/` dir. */
12
- root: string;
13
- memory: ProfileProjectMemory;
14
- }
15
2
  export declare function builtinMemoryRoot(): string;
16
3
  export declare function builtinPiPackagesDir(): string;
17
4
  export declare function builtinPiPackageDir(name: string): string;
@@ -29,35 +16,17 @@ export declare function findProjectScopeRoot(startDir?: string): string | null;
29
16
  * to the single `[startDir]` pointer, reproducing today's behavior exactly.
30
17
  * Outside a Linux node sandbox, roots are discovered on each call so profile
31
18
  * edits and deleted project directories do not leave a stale pointer. A node
32
- * sandbox has no profile store to read and uses only its cwd pointer.
33
- *
34
- * Each root also carries the selected profile relationship's memory ceiling
35
- * (`findProjectScopeRootsWithMemory`), a projection layered onto this order
36
- * rather than part of it: discovery provenance decides precedence, the
37
- * relationship decides the ceiling, and the two never influence each other. */
19
+ * sandbox has no profile store to read and uses only its cwd pointer. */
38
20
  export declare function findProjectScopeRoots(startDir?: string, profileId?: string | null): string[];
39
- /** `findProjectScopeRoots` with each root's profile memory ceiling attached —
40
- * same roots, same order. A root contributed by a profile entry's ancestor
41
- * walk takes that entry's `memory` (first entry in manifest order wins, even
42
- * when cwd also reaches the root); every other root takes the neutral
43
- * `content` ceiling. */
44
- export declare function findProjectScopeRootsWithMemory(startDir?: string, profileId?: string | null): ProjectScopeRoot[];
45
21
  export declare function projectScopeRoot(startDir?: string): string | null;
46
22
  export declare function projectScopeRoots(startDir?: string, profileId?: string | null): string[];
47
- export declare function projectScopeRootsWithMemory(startDir?: string, profileId?: string | null): ProjectScopeRoot[];
48
23
  export declare function scopeRoot(scope: Scope): string | null;
49
24
  export declare function requireScopeRoot(scope: Scope): string;
50
25
  export declare function ensureProjectScopeRoot(startDir?: string): string;
51
26
  export declare function pluginsDir(scope: Scope): string | null;
52
27
  export declare function marketplacesDir(scope: Scope): string | null;
53
- /** Where substrate memory documents live per scope. Builtin memory is the
54
- * special case — its own package dir (builtinMemoryRoot), since the builtin
55
- * scope has no scopeRoot. User and project memory live at
56
- * scopeRoot(scope)/memory. */
57
- export declare function scopeMemoryDir(scope: Scope): string | null;
58
28
  /** Where a plugin's substrate memory documents live: `<plugin.root>/memory`.
59
29
  * The resolver mounts these under the virtual `<pluginName>/` namespace. */
60
30
  export declare function pluginMemoryDir(plugin: InstalledPlugin): string;
61
31
  export declare function resolveScopeArg(scopeArg: string | undefined): Scope | 'all';
62
32
  export declare function listScopes(scopeArg: string | undefined): Scope[];
63
- export declare function resetScopeCache(): void;
@@ -1 +1 @@
1
- var g=Object.defineProperty;var r=(o,t)=>g(o,"name",{value:t,configurable:!0});import{envProfileId as h,isSandboxedNode as y}from"../shared/env.js";import{homedir as k}from"node:os";import{existsSync as C,statSync as E}from"node:fs";import{join as e,resolve as a,dirname as _}from"node:path";import{CRTR_DIR_NAME as S}from"../types.js";import{assetRoot as j}from"./asset-root.js";import{usage as P}from"./errors.js";import{loadProfileManifest as A}from"./profiles/manifest.js";import{realpathOrSelf as p}from"./fs-utils.js";import{resetRepositoryAssociationCache as N}from"./memory/repository-association.js";import{layoutRoot as O,runtimeRoot as R,userRoot as T}from"./layout.js";const L="content";function W(){return e(j(),"builtin-memory")}r(W,"builtinMemoryRoot");function $(){return e(j(),"builtin-pi-packages")}r($,"builtinPiPackagesDir");function to(o){return e($(),o)}r(to,"builtinPiPackageDir");function b(){return e(R(),"scope")}r(b,"userScopeRoot");function q(o,t){if(!C(o)||!y()&&(p(o)===p(t)||p(o)===p(O())))return!1;try{return E(o).isDirectory()}catch{return!1}}r(q,"isProjectScopeDir");function w(o=process.cwd()){return M(o)[0]??null}r(w,"findProjectScopeRoot");function J(o,t){const n=[],l=p(k());let i=a(o);for(;;){const f=e(i,S);if(q(f,t)&&n.push(f),p(i)===l)return n;const s=_(i);if(s===i)return n;i=s}}r(J,"collectAncestorScopeRoots");function M(o=process.cwd(),t=h()||null){return v(o,t).roots}r(M,"findProjectScopeRoots");function U(o=process.cwd(),t=h()||null){return v(o,t).annotated}r(U,"findProjectScopeRootsWithMemory");function v(o,t){const n=a(o),l=b(),i=[{dir:n,memory:null}];if(!y()&&t!==null&&t!=="")try{const{manifest:u}=A(t);for(const c of u.projects)i.push({dir:c.path,memory:c.memory})}catch{}const f=new Set,s=[],m=new Map;for(const u of i)for(const c of J(u.dir,l))f.has(c)||(f.add(c),s.push(c)),u.memory!==null&&!m.has(c)&&m.set(c,u.memory);const D=s.map(u=>({root:u,memory:m.get(u)??L}));return{roots:s,annotated:D}}r(v,"resolveProjectScopeRoots");function x(o){return w(o)}r(x,"projectScopeRoot");function ro(o,t){return M(o,t)}r(ro,"projectScopeRoots");function eo(o,t){return U(o,t)}r(eo,"projectScopeRootsWithMemory");function d(o){return o==="builtin"?null:o==="user"?b():x()}r(d,"scopeRoot");function no(o){const t=d(o);if(!t)throw P(`no ${o} scope available \u2014 run \`crtr init\` here or use --scope user`);return t}r(no,"requireScopeRoot");function io(o=process.cwd()){const t=w(o);return t||e(a(o),S)}r(io,"ensureProjectScopeRoot");function uo(o){const t=o==="user"?R():d(o);return t?e(t,"plugins"):null}r(uo,"pluginsDir");function co(o){const t=o==="user"?R():d(o);return t?e(t,"marketplaces"):null}r(co,"marketplacesDir");function so(o){if(o==="builtin")return W();if(o==="user")return e(T(),"memory");const t=x();return t?e(t,"memory"):null}r(so,"scopeMemoryDir");function po(o){return e(o.root,"memory")}r(po,"pluginMemoryDir");function Y(o){if(o===void 0)return"all";const t=o.toLowerCase();if(t==="user"||t==="project"||t==="builtin"||t==="all")return t;throw P(`invalid --scope: ${o} (expected user|project|builtin|all)`)}r(Y,"resolveScopeArg");function fo(o){const t=Y(o);if(t==="all"){const n=[];return x()&&n.push("project"),n.push("user"),n.push("builtin"),n}return[t]}r(fo,"listScopes");function lo(){N()}r(lo,"resetScopeCache");export{L as NEUTRAL_PROJECT_MEMORY,W as builtinMemoryRoot,to as builtinPiPackageDir,$ as builtinPiPackagesDir,io as ensureProjectScopeRoot,w as findProjectScopeRoot,M as findProjectScopeRoots,U as findProjectScopeRootsWithMemory,fo as listScopes,co as marketplacesDir,po as pluginMemoryDir,uo as pluginsDir,x as projectScopeRoot,ro as projectScopeRoots,eo as projectScopeRootsWithMemory,no as requireScopeRoot,lo as resetScopeCache,Y as resolveScopeArg,so as scopeMemoryDir,d as scopeRoot,b as userScopeRoot};
1
+ var v=Object.defineProperty;var r=(o,t)=>v(o,"name",{value:t,configurable:!0});import{envProfileId as w,isSandboxedNode as R}from"../shared/env.js";import{homedir as D}from"node:os";import{existsSync as g,statSync as k}from"node:fs";import{join as n,resolve as a,dirname as M}from"node:path";import{CRTR_DIR_NAME as S}from"../types.js";import{assetRoot as h}from"./asset-root.js";import{usage as d}from"./errors.js";import{loadProfileManifest as C}from"./profiles/manifest.js";import{realpathOrSelf as u}from"./fs-utils.js";import{layoutRoot as N,runtimeRoot as m}from"./layout.js";function Q(){return n(h(),"builtin-memory")}r(Q,"builtinMemoryRoot");function _(){return n(h(),"builtin-pi-packages")}r(_,"builtinPiPackagesDir");function U(o){return n(_(),o)}r(U,"builtinPiPackageDir");function j(){return n(m(),"scope")}r(j,"userScopeRoot");function $(o,t){if(!g(o)||!R()&&(u(o)===u(t)||u(o)===u(N())))return!1;try{return k(o).isDirectory()}catch{return!1}}r($,"isProjectScopeDir");function b(o=process.cwd()){return P(o)[0]??null}r(b,"findProjectScopeRoot");function q(o,t){const e=[],f=u(D());let i=a(o);for(;;){const c=n(i,S);if($(c,t)&&e.push(c),u(i)===f)return e;const s=M(i);if(s===i)return e;i=s}}r(q,"collectAncestorScopeRoots");function P(o=process.cwd(),t=w()||null){return A(o,t)}r(P,"findProjectScopeRoots");function A(o,t){const e=a(o),f=j(),i=[e];if(!R()&&t!==null&&t!=="")try{const{manifest:l}=C(t);for(const p of l.projects)i.push(p.path)}catch{}const c=new Set,s=[];for(const l of i)for(const p of q(l,f))c.has(p)||(c.add(p),s.push(p));return s}r(A,"resolveProjectScopeRoots");function y(o){return b(o)}r(y,"projectScopeRoot");function V(o,t){return P(o,t)}r(V,"projectScopeRoots");function x(o){return o==="builtin"?null:o==="user"?j():y()}r(x,"scopeRoot");function W(o){const t=x(o);if(!t)throw d(`no ${o} scope available \u2014 run \`crtr init\` here or use --scope user`);return t}r(W,"requireScopeRoot");function X(o=process.cwd()){const t=b(o);return t||n(a(o),S)}r(X,"ensureProjectScopeRoot");function Y(o){const t=o==="user"?m():x(o);return t?n(t,"plugins"):null}r(Y,"pluginsDir");function Z(o){const t=o==="user"?m():x(o);return t?n(t,"marketplaces"):null}r(Z,"marketplacesDir");function oo(o){return n(o.root,"memory")}r(oo,"pluginMemoryDir");function E(o){if(o===void 0)return"all";const t=o.toLowerCase();if(t==="user"||t==="project"||t==="builtin"||t==="all")return t;throw d(`invalid --scope: ${o} (expected user|project|builtin|all)`)}r(E,"resolveScopeArg");function to(o){const t=E(o);if(t==="all"){const e=[];return y()&&e.push("project"),e.push("user"),e.push("builtin"),e}return[t]}r(to,"listScopes");export{Q as builtinMemoryRoot,U as builtinPiPackageDir,_ as builtinPiPackagesDir,X as ensureProjectScopeRoot,b as findProjectScopeRoot,P as findProjectScopeRoots,to as listScopes,Z as marketplacesDir,oo as pluginMemoryDir,Y as pluginsDir,y as projectScopeRoot,V as projectScopeRoots,W as requireScopeRoot,E as resolveScopeArg,x as scopeRoot,j as userScopeRoot};
@@ -1 +1,2 @@
1
- var R=Object.defineProperty;var n=(e,o)=>R(e,"name",{value:o,configurable:!0});import{DatabaseSync as p}from"node:sqlite";import{chmodSync as d,existsSync as a,mkdirSync as w,readdirSync as L,rmSync as k,statSync as I,writeFileSync as P}from"node:fs";import{join as i}from"node:path";import v from"proper-lockfile";import{CONFIG_FILE as A,PROFILE_DIR as O,STATE_FILE as f}from"../../types.js";import{withExclusiveDirectoryLock as E}from"../exclusive-lock.js";import{layoutNeedsMigration as j}from"../layout.js";import{providerStore as D,projectStore as T,userStore as G}from"./paths.js";import{createScopedSchema as $,PROVIDER_SCHEMA_VERSION as g,SCOPED_SCHEMA_VERSION as h}from"./schema.js";const u=new Map,C=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/;function N(e,o,r){e.prepare("UPDATE scope_owners SET root=? WHERE owner_key=?").run(r,o)}n(N,"writeOwnerRoot");function s(e){return Number(e.prepare("PRAGMA user_version").get().user_version)}n(s,"version");function x(e,o){const r=s(e);if(r===0)throw new Error(`scoped SQL store is uninitialized: ${o.path}; crtr was updated and \`crtr sys daemon restart\` converts local state`);const t=o.kind==="provider"?g:h;if(r>t)throw new Error(`scoped SQL store ${o.path} uses unsupported schema version ${r}`);if(r!==t)throw new Error(`scoped SQL store ${o.path} requires an explicit conversion`)}n(x,"assertVersion");function M(e,o){if(!(o.kind==="provider"||s(e)>=h)){e.exec("PRAGMA busy_timeout = 5000; BEGIN IMMEDIATE");try{s(e)===1&&(e.prepare("PRAGMA table_info(profiles)").all().some(({name:t})=>t==="grantee")||e.exec("ALTER TABLE profiles ADD COLUMN grantee TEXT"),e.exec("PRAGMA user_version = 2")),s(e)===2&&(e.prepare("PRAGMA table_info(profiles)").all().some(({name:t})=>t==="home")&&e.exec("ALTER TABLE profiles DROP COLUMN home"),e.exec(`PRAGMA user_version = ${h}`)),e.exec("COMMIT")}catch(r){throw e.exec("ROLLBACK"),r}}}n(M,"upgradeScopedStore");function oe(e){const o=new p(e.path);try{M(o,e),x(o,e)}finally{o.close()}}n(oe,"assertScopedStoreReady");function B(e){if(!_(e))return;const o=new p(e.path,{readOnly:!0});let r;try{r=s(o)}finally{o.close()}if(r===0)for(const t of[e.path,`${e.path}-wal`,`${e.path}-shm`])k(t,{force:!0})}n(B,"discardIncompleteScopedStore");function F(e,o){return E(i(e,".init.lock"),()=>{const r=i(e,f),t=Date.now()+5e3;let c=10;for(;;){let y;try{y=v.lockSync(r,{realpath:!1,retries:0,stale:3e4,update:1e4})}catch(l){if(l.code!=="ELOCKED")throw l;const S=t-Date.now();if(S<=0)throw new Error(`timed out waiting for project state conversion lock: ${r}`,{cause:l});Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,Math.min(c,S)),c=Math.min(c*2,250);continue}try{return o()}finally{y()}}})}n(F,"withProjectStateLock");function m(e){a(e)&&d(e,384);for(const o of["-wal","-shm"])a(`${e}${o}`)&&d(`${e}${o}`,384)}n(m,"secure");function _(e){return a(e.path)}n(_,"scopedStoreExists");function z(e){if(e.kind==="project")return[i(e.root,f)];if(e.kind==="provider")return[i(e.root,"anthropic-subscriptions.json"),i(e.root,"openai-codex-subscriptions.json"),i(e.root,"provider-rotation.json")];const o=[i(e.root,A),i(e.root,f),i(e.root,"profile-defaults.json")],r=i(e.root,O);if(a(r))for(const t of L(r,{withFileTypes:!0}))t.isDirectory()&&C.test(t.name)&&o.push(i(r,t.name,"profile.json"),i(r,t.name,A),i(r,t.name,f));return o}n(z,"legacyScopedStorePaths");function Q(e){const o=e.kind==="user"?G(e.root):e.kind==="project"?T(e.root):D(e.root);o.kind!=="project"&&w(o.root,{recursive:!0,mode:448});const r=n(()=>{if(o.kind==="project"&&B(o),_(o))return;const t=z(o).find(a);if(t!==void 0)throw new Error(`legacy scoped state exists at ${t}; crtr was updated and \`crtr sys daemon restart\` converts local state`);K(o,c=>{$(c,o.kind),o.kind!=="provider"&&N(c,o.kind,o.root)})},"initialize");o.kind==="project"?F(o.root,r):E(i(o.root,".init.lock"),r)}n(Q,"initializeFreshScopedStore");function H(e){if(j())throw new Error("layout_migration_required");const o=u.get(e.path);if(o!==void 0)return o;Q(e);const r=new p(e.path);try{return r.exec("PRAGMA busy_timeout = 5000; PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;"),M(r,e),x(r,e),m(e.path),u.set(e.path,r),r}catch(t){throw r.close(),t}}n(H,"openScopedStore");function K(e,o){if(a(e.path))throw new Error(`scoped SQL store already exists: ${e.path}`);if(e.kind!=="project"&&w(e.root,{recursive:!0,mode:448}),!I(e.root).isDirectory())throw new Error(`scoped SQL root is not a directory: ${e.root}`);(e.kind!=="project"||process.platform!=="linux")&&d(e.root,448),P(e.path,"",{mode:384});const r=new p(e.path);try{r.exec("PRAGMA busy_timeout = 5000; PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON; BEGIN IMMEDIATE;"),o(r),r.exec("COMMIT")}catch(t){try{r.exec("ROLLBACK")}catch{}throw t}finally{m(e.path),r.close()}}n(K,"createScopedStore");function re(e,o){const r=H(e);if(r.isTransaction)return o(r);r.exec("BEGIN IMMEDIATE");try{const t=o(r);return r.exec("COMMIT"),m(e.path),t}catch(t){try{r.exec("ROLLBACK")}catch{}throw t}}n(re,"withScopedWrite");function te(){for(const e of u.values())e.close();u.clear()}n(te,"closeScopedStores");export{C as PROFILE_ID_SHAPE,oe as assertScopedStoreReady,te as closeScopedStores,K as createScopedStore,B as discardIncompleteScopedStore,Q as initializeFreshScopedStore,z as legacyScopedStorePaths,H as openScopedStore,_ as scopedStoreExists,F as withProjectStateLock,re as withScopedWrite,N as writeOwnerRoot};
1
+ var x=Object.defineProperty;var n=(e,o)=>x(e,"name",{value:o,configurable:!0});import{DatabaseSync as p}from"node:sqlite";import{chmodSync as d,existsSync as s,mkdirSync as y,readdirSync as M,rmSync as R,statSync as O,writeFileSync as I}from"node:fs";import{join as i}from"node:path";import v from"proper-lockfile";import{CONFIG_FILE as S,PROFILE_DIR as P,STATE_FILE as f}from"../../types.js";import{withExclusiveDirectoryLock as _}from"../exclusive-lock.js";import{layoutNeedsMigration as j}from"../layout.js";import{providerStore as N,projectStore as k,userStore as D}from"./paths.js";import{createScopedSchema as C,PROVIDER_SCHEMA_VERSION as G,SCOPED_SCHEMA_VERSION as m}from"./schema.js";const l=new Map,g=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/;function $(e,o,r){e.prepare("UPDATE scope_owners SET root=? WHERE owner_key=?").run(r,o)}n($,"writeOwnerRoot");function c(e){return Number(e.prepare("PRAGMA user_version").get().user_version)}n(c,"version");function w(e,o){const r=c(e);if(r===0)throw new Error(`scoped SQL store is uninitialized: ${o.path}; crtr was updated and \`crtr sys daemon restart\` converts local state`);const t=o.kind==="provider"?G:m;if(r>t)throw new Error(`scoped SQL store ${o.path} uses unsupported schema version ${r}`);if(r!==t)throw new Error(`scoped SQL store ${o.path} requires an explicit conversion`)}n(w,"assertVersion");function L(e,o){if(!(o.kind==="provider"||c(e)>=m)){e.exec("PRAGMA busy_timeout = 5000; BEGIN IMMEDIATE");try{c(e)===1&&(e.prepare("PRAGMA table_info(profiles)").all().some(({name:t})=>t==="grantee")||e.exec("ALTER TABLE profiles ADD COLUMN grantee TEXT"),e.exec("PRAGMA user_version = 2")),c(e)===2&&(e.prepare("PRAGMA table_info(profiles)").all().some(({name:t})=>t==="home")&&e.exec("ALTER TABLE profiles DROP COLUMN home"),e.exec("PRAGMA user_version = 3")),c(e)===3&&(e.exec("ALTER TABLE profiles ADD COLUMN delivery_limits_json TEXT NOT NULL DEFAULT '{}' CHECK(json_valid(delivery_limits_json))"),e.exec("PRAGMA user_version = 4")),c(e)===4&&(e.exec("CREATE TABLE IF NOT EXISTS legacy_project_caps (profile_id TEXT NOT NULL, path TEXT NOT NULL, memory TEXT NOT NULL CHECK(memory IN ('none','name','preview')), PRIMARY KEY(profile_id,path))"),e.prepare("PRAGMA table_info(profile_projects)").all().some(({name:t})=>t==="memory")&&e.exec(`INSERT INTO legacy_project_caps SELECT profile_id, path, memory FROM profile_projects WHERE memory != 'content';
2
+ ALTER TABLE profile_projects DROP COLUMN memory;`),e.exec(`PRAGMA user_version = ${m}`)),e.exec("COMMIT")}catch(r){throw e.exec("ROLLBACK"),r}}}n(L,"upgradeScopedStore");function oe(e){const o=new p(e.path);try{L(o,e),w(o,e)}finally{o.close()}}n(oe,"assertScopedStoreReady");function B(e){if(!T(e))return;const o=new p(e.path,{readOnly:!0});let r;try{r=c(o)}finally{o.close()}if(r===0)for(const t of[e.path,`${e.path}-wal`,`${e.path}-shm`])R(t,{force:!0})}n(B,"discardIncompleteScopedStore");function F(e,o){return _(i(e,".init.lock"),()=>{const r=i(e,f),t=Date.now()+5e3;let a=10;for(;;){let E;try{E=v.lockSync(r,{realpath:!1,retries:0,stale:3e4,update:1e4})}catch(u){if(u.code!=="ELOCKED")throw u;const A=t-Date.now();if(A<=0)throw new Error(`timed out waiting for project state conversion lock: ${r}`,{cause:u});Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,Math.min(a,A)),a=Math.min(a*2,250);continue}try{return o()}finally{E()}}})}n(F,"withProjectStateLock");function h(e){s(e)&&d(e,384);for(const o of["-wal","-shm"])s(`${e}${o}`)&&d(`${e}${o}`,384)}n(h,"secure");function T(e){return s(e.path)}n(T,"scopedStoreExists");function U(e){if(e.kind==="project")return[i(e.root,f)];if(e.kind==="provider")return[i(e.root,"anthropic-subscriptions.json"),i(e.root,"openai-codex-subscriptions.json"),i(e.root,"provider-rotation.json")];const o=[i(e.root,S),i(e.root,f),i(e.root,"profile-defaults.json")],r=i(e.root,P);if(s(r))for(const t of M(r,{withFileTypes:!0}))t.isDirectory()&&g.test(t.name)&&o.push(i(r,t.name,"profile.json"),i(r,t.name,S),i(r,t.name,f));return o}n(U,"legacyScopedStorePaths");function H(e){const o=e.kind==="user"?D(e.root):e.kind==="project"?k(e.root):N(e.root);o.kind!=="project"&&y(o.root,{recursive:!0,mode:448});const r=n(()=>{if(o.kind==="project"&&B(o),T(o))return;const t=U(o).find(s);if(t!==void 0)throw new Error(`legacy scoped state exists at ${t}; crtr was updated and \`crtr sys daemon restart\` converts local state`);X(o,a=>{C(a,o.kind),o.kind!=="provider"&&$(a,o.kind,o.root)})},"initialize");o.kind==="project"?F(o.root,r):_(i(o.root,".init.lock"),r)}n(H,"initializeFreshScopedStore");function K(e){if(j())throw new Error("layout_migration_required");const o=l.get(e.path);if(o!==void 0)return o;H(e);const r=new p(e.path);try{return r.exec("PRAGMA busy_timeout = 5000; PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;"),L(r,e),w(r,e),h(e.path),l.set(e.path,r),r}catch(t){throw r.close(),t}}n(K,"openScopedStore");function X(e,o){if(s(e.path))throw new Error(`scoped SQL store already exists: ${e.path}`);if(e.kind!=="project"&&y(e.root,{recursive:!0,mode:448}),!O(e.root).isDirectory())throw new Error(`scoped SQL root is not a directory: ${e.root}`);(e.kind!=="project"||process.platform!=="linux")&&d(e.root,448),I(e.path,"",{mode:384});const r=new p(e.path);try{r.exec("PRAGMA busy_timeout = 5000; PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON; BEGIN IMMEDIATE;"),o(r),r.exec("COMMIT")}catch(t){try{r.exec("ROLLBACK")}catch{}throw t}finally{h(e.path),r.close()}}n(X,"createScopedStore");function re(e,o){const r=K(e);if(r.isTransaction)return o(r);r.exec("BEGIN IMMEDIATE");try{const t=o(r);return r.exec("COMMIT"),h(e.path),t}catch(t){try{r.exec("ROLLBACK")}catch{}throw t}}n(re,"withScopedWrite");function te(){for(const e of l.values())e.close();l.clear()}n(te,"closeScopedStores");export{g as PROFILE_ID_SHAPE,oe as assertScopedStoreReady,te as closeScopedStores,X as createScopedStore,B as discardIncompleteScopedStore,H as initializeFreshScopedStore,U as legacyScopedStorePaths,K as openScopedStore,T as scopedStoreExists,F as withProjectStateLock,re as withScopedWrite,$ as writeOwnerRoot};
@@ -1,3 +1,3 @@
1
- var $=Object.defineProperty;var f=(e,r)=>$(e,"name",{value:r,configurable:!0});import{randomUUID as U}from"node:crypto";import{chmodSync as A,copyFileSync as x,existsSync as d,mkdirSync as h,readFileSync as S,readdirSync as P,statSync as I}from"node:fs";import{dirname as b,join as u,relative as V}from"node:path";import J from"proper-lockfile";import{CONFIG_FILE as L,PROFILE_DIR as W,STATE_FILE as w}from"../../types.js";import{LockedJsonFile as D}from"../locked-file.js";import{assertScopedStoreReady as C,createScopedStore as N,discardIncompleteScopedStore as q,legacyScopedStorePaths as j,PROFILE_ID_SHAPE as z,scopedStoreExists as _,withProjectStateLock as G,writeOwnerRoot as H}from"./db.js";import{canonicalRoot as K,providerStore as O,projectStore as M,userStore as X}from"./paths.js";import{profileSpace as B}from"../layout.js";import{createScopedSchema as F}from"./schema.js";function g(e){return JSON.parse(S(e,"utf8"))}f(g,"json");function T(e){return e.some(d)}f(T,"existsLegacy");function v(e,r){const o=u(e,".legacy-scoped-state");try{h(o,{mode:448})}catch(a){if(a.code!=="EEXIST"||!I(o).isDirectory())throw a}A(o,448);for(const a of r)if(d(a)&&I(a).isFile()){const n=V(e,a);if(n===""||n.startsWith(".."))throw new Error(`legacy state is outside its owning root: ${a}`);const t=u(o,n);b(t)!==o&&h(b(t),{recursive:!0,mode:448}),x(a,t),A(t,384)}}f(v,"preserve");import{initializeFreshScopedStore as Se}from"./db.js";function ue(e){const r=e.kind==="user"?X(e.root):e.kind==="project"?M(e.root):O(e.root);if(e.kind!=="project"&&_(r))return;if(e.kind==="provider")throw new Error("provider conversion requires convertLegacyProviderStore() under coordinated shared-agent-dir activation");const o=j(r),a=f(()=>{e.kind==="project"&&q(r),!_(r)&&(e.kind==="project"&&T(o)&&v(r.root,o),N(r,n=>{F(n,e.kind);const t=e.kind==="user"?"user":"project";H(n,t,r.root),e.kind==="user"?ee(n,r.root):k(n,t,u(r.root,w))}),e.kind==="user"&&T(o)&&v(r.root,o))},"convert");e.kind==="project"?G(r.root,()=>{a(),C(r)}):a()}f(ue,"convertLegacyScopedStore");function Q(e){if(!d(e))return[];const r=JSON.parse(S(e,"utf8"));if(!Array.isArray(r))throw new Error(`legacy subscription pool is malformed: ${e}`);const o=new Set;return r.map((a,n)=>{if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy subscription pool entry ${n+1} is malformed: ${e}`);const t=a,s=typeof t.label=="string"?t.label.trim():"",c=typeof t.refresh=="string"?t.refresh.trim():"",i=typeof t.access=="string"?t.access.trim():"",p=Number(t.expires);if(!s||!c||!i||!Number.isFinite(p))throw new Error(`legacy subscription pool entry ${n+1} is incomplete: ${e}`);const m=s.toLowerCase();if(o.has(m))throw new Error(`legacy subscription pool has duplicate label "${s}": ${e}`);o.add(m);const l=f(E=>Number.isFinite(Number(t[E]))?Number(t[E]):0,"timing"),y=typeof t.accountId=="string"&&t.accountId.trim()!==""?t.accountId.trim():void 0;return{label:s,refresh:c,access:i,expires:p,rateLimitedUntil:l("rateLimitedUntil"),lastAttemptAt:l("lastAttemptAt"),lastRateLimitedAt:l("lastRateLimitedAt"),...t.authFailure==="invalid_grant"?{authFailure:"invalid_grant"}:{},...y?{accountId:y}:{}}})}f(Q,"parseLegacyProviderPool");function Y(e){if(!d(e))return{};const r=JSON.parse(S(e,"utf8"));if(r===null||typeof r!="object"||Array.isArray(r))throw new Error(`legacy provider rotation settings are malformed: ${e}`);const o=r;return{...o.defaultFallbackStrength==="ultra"||o.defaultFallbackStrength==="strong"||o.defaultFallbackStrength==="medium"||o.defaultFallbackStrength==="light"?{defaultFallbackStrength:o.defaultFallbackStrength}:{},...typeof o.revertWhenAvailable=="boolean"?{revertWhenAvailable:o.revertWhenAvailable}:{}}}f(Y,"parseLegacyRotation");async function Z(e,r){const o=[];try{for(const a of e)d(a)&&o.push(await J.lock(a,{realpath:!1,retries:0,stale:3e4,update:1e4}));return await r()}finally{await Promise.allSettled(o.reverse().map(a=>a()))}}f(Z,"withLegacyProviderLocks");async function de(e){const r=O(e);if(_(r))return;const o=j(r);await Z(o,async()=>{if(_(r))return;const a=new Map(o.slice(0,2).map((t,s)=>[s===0?"anthropic":"openai-codex",Q(t)])),n=Y(o[2]);h(r.root,{recursive:!0,mode:448}),v(r.root,o);for(const[t,s]of a){const c=Object.fromEntries(s.map(p=>[U(),{refresh:p.refresh,access:p.access,expires:p.expires,...p.accountId?{accountId:p.accountId}:{}}]));await new D(u(r.root,`${t}-credentials.json`),!0,`{"version":1,"accounts":{}}
1
+ var $=Object.defineProperty;var f=(e,r)=>$(e,"name",{value:r,configurable:!0});import{randomUUID as U}from"node:crypto";import{chmodSync as A,copyFileSync as x,existsSync as d,mkdirSync as h,readFileSync as S,readdirSync as P,statSync as I}from"node:fs";import{dirname as N,join as u,relative as V}from"node:path";import J from"proper-lockfile";import{CONFIG_FILE as L,PROFILE_DIR as W,STATE_FILE as w}from"../../types.js";import{LockedJsonFile as D}from"../locked-file.js";import{assertScopedStoreReady as C,createScopedStore as b,discardIncompleteScopedStore as q,legacyScopedStorePaths as j,PROFILE_ID_SHAPE as z,scopedStoreExists as _,withProjectStateLock as G,writeOwnerRoot as H}from"./db.js";import{canonicalRoot as K,providerStore as O,projectStore as M,userStore as X}from"./paths.js";import{profileSpace as B}from"../layout.js";import{createScopedSchema as T}from"./schema.js";function g(e){return JSON.parse(S(e,"utf8"))}f(g,"json");function F(e){return e.some(d)}f(F,"existsLegacy");function v(e,r){const o=u(e,".legacy-scoped-state");try{h(o,{mode:448})}catch(a){if(a.code!=="EEXIST"||!I(o).isDirectory())throw a}A(o,448);for(const a of r)if(d(a)&&I(a).isFile()){const n=V(e,a);if(n===""||n.startsWith(".."))throw new Error(`legacy state is outside its owning root: ${a}`);const t=u(o,n);N(t)!==o&&h(N(t),{recursive:!0,mode:448}),x(a,t),A(t,384)}}f(v,"preserve");import{initializeFreshScopedStore as Se}from"./db.js";function ue(e){const r=e.kind==="user"?X(e.root):e.kind==="project"?M(e.root):O(e.root);if(e.kind!=="project"&&_(r))return;if(e.kind==="provider")throw new Error("provider conversion requires convertLegacyProviderStore() under coordinated shared-agent-dir activation");const o=j(r),a=f(()=>{e.kind==="project"&&q(r),!_(r)&&(e.kind==="project"&&F(o)&&v(r.root,o),b(r,n=>{T(n,e.kind);const t=e.kind==="user"?"user":"project";H(n,t,r.root),e.kind==="user"?ee(n,r.root):E(n,t,u(r.root,w))}),e.kind==="user"&&F(o)&&v(r.root,o))},"convert");e.kind==="project"?G(r.root,()=>{a(),C(r)}):a()}f(ue,"convertLegacyScopedStore");function Q(e){if(!d(e))return[];const r=JSON.parse(S(e,"utf8"));if(!Array.isArray(r))throw new Error(`legacy subscription pool is malformed: ${e}`);const o=new Set;return r.map((a,n)=>{if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy subscription pool entry ${n+1} is malformed: ${e}`);const t=a,s=typeof t.label=="string"?t.label.trim():"",c=typeof t.refresh=="string"?t.refresh.trim():"",i=typeof t.access=="string"?t.access.trim():"",p=Number(t.expires);if(!s||!c||!i||!Number.isFinite(p))throw new Error(`legacy subscription pool entry ${n+1} is incomplete: ${e}`);const m=s.toLowerCase();if(o.has(m))throw new Error(`legacy subscription pool has duplicate label "${s}": ${e}`);o.add(m);const l=f(k=>Number.isFinite(Number(t[k]))?Number(t[k]):0,"timing"),y=typeof t.accountId=="string"&&t.accountId.trim()!==""?t.accountId.trim():void 0;return{label:s,refresh:c,access:i,expires:p,rateLimitedUntil:l("rateLimitedUntil"),lastAttemptAt:l("lastAttemptAt"),lastRateLimitedAt:l("lastRateLimitedAt"),...t.authFailure==="invalid_grant"?{authFailure:"invalid_grant"}:{},...y?{accountId:y}:{}}})}f(Q,"parseLegacyProviderPool");function Y(e){if(!d(e))return{};const r=JSON.parse(S(e,"utf8"));if(r===null||typeof r!="object"||Array.isArray(r))throw new Error(`legacy provider rotation settings are malformed: ${e}`);const o=r;return{...o.defaultFallbackStrength==="ultra"||o.defaultFallbackStrength==="strong"||o.defaultFallbackStrength==="medium"||o.defaultFallbackStrength==="light"?{defaultFallbackStrength:o.defaultFallbackStrength}:{},...typeof o.revertWhenAvailable=="boolean"?{revertWhenAvailable:o.revertWhenAvailable}:{}}}f(Y,"parseLegacyRotation");async function Z(e,r){const o=[];try{for(const a of e)d(a)&&o.push(await J.lock(a,{realpath:!1,retries:0,stale:3e4,update:1e4}));return await r()}finally{await Promise.allSettled(o.reverse().map(a=>a()))}}f(Z,"withLegacyProviderLocks");async function de(e){const r=O(e);if(_(r))return;const o=j(r);await Z(o,async()=>{if(_(r))return;const a=new Map(o.slice(0,2).map((t,s)=>[s===0?"anthropic":"openai-codex",Q(t)])),n=Y(o[2]);h(r.root,{recursive:!0,mode:448}),v(r.root,o);for(const[t,s]of a){const c=Object.fromEntries(s.map(p=>[U(),{refresh:p.refresh,access:p.access,expires:p.expires,...p.accountId?{accountId:p.accountId}:{}}]));await new D(u(r.root,`${t}-credentials.json`),!0,`{"version":1,"accounts":{}}
2
2
  `).withLockAsync(async(p,m,l)=>(l(`${JSON.stringify({version:1,accounts:c})}
3
- `),{result:void 0}))}N(r,t=>{F(t,"provider");for(const[s,c]of a){const i=JSON.parse(S(u(r.root,`${s}-credentials.json`),"utf8")),p=Object.keys(i.accounts),m=t.prepare("INSERT INTO managed_accounts(provider_id,id,label,label_key,position,last_attempt_at,last_rate_limited_at,rate_limited_until,auth_failure) VALUES(?,?,?,?,?,?,?,?,?)");c.forEach((l,y)=>m.run(s,p[y],l.label,l.label.toLowerCase(),y,l.lastAttemptAt,l.lastRateLimitedAt,l.rateLimitedUntil,l.authFailure??null))}(n.defaultFallbackStrength!==void 0||n.revertWhenAvailable!==void 0)&&t.prepare("INSERT INTO rotation_settings(singleton,default_fallback_strength,revert_when_available) VALUES(1,?,?)").run(n.defaultFallbackStrength??null,n.revertWhenAvailable===void 0?null:n.revertWhenAvailable?1:0)})})}f(de,"convertLegacyProviderStore");function R(e,r,o){if(!d(o))return;const a=g(o);if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy config is malformed: ${o}`);e.prepare("INSERT INTO scope_settings(owner_key,raw_json) VALUES(?,?)").run(r,JSON.stringify(a))}f(R,"importSettings");function k(e,r,o){if(!d(o))return;const a=g(o);if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy state is malformed: ${o}`);const n=a;e.prepare("INSERT INTO scope_bookkeeping(owner_key,last_self_check,active_canvas) VALUES(?,?,?)").run(r,n.last_self_check??null,n.activeCanvas??null);const t=e.prepare("INSERT INTO scope_marketplaces(owner_key,name,last_updated) VALUES(?,?,?)");for(const[c,i]of Object.entries(n.marketplaces??{}))t.run(r,c,i.last_updated??null);const s=e.prepare("INSERT INTO scope_plugins(owner_key,name,last_updated,etag,checked_at) VALUES(?,?,?,?,?)");for(const[c,i]of Object.entries(n.plugins??{}))s.run(r,c,i.last_updated??null,i.etag??null,i.checked_at??null)}f(k,"importState");function ee(e,r){R(e,"user",u(r,L)),k(e,"user",u(r,w));const o=u(r,W);if(d(o))for(const n of P(o,{withFileTypes:!0})){if(!n.isDirectory()||!z.test(n.name))continue;const t=n.name,s=u(o,t),c=u(s,"profile.json");if(!d(c))throw new Error(`legacy profile manifest is missing: ${c}`);const i=g(c);if(!i||typeof i!="object"||!Array.isArray(i.projects)||typeof i.name!="string"||typeof i.created_at!="string")throw new Error(`legacy profile manifest is malformed: ${c}`);e.prepare("INSERT INTO profiles(id,name,created_at,last_used_at,paused_at,default_kind,grantee,metadata_json) VALUES(?,?,?,?,?,?,?,?)").run(t,i.name,i.created_at,i.last_used_at??null,i.paused_at??null,i.default_kind??null,i.grantee??null,JSON.stringify(i.metadata??{})),e.prepare("INSERT INTO scope_owners(owner_key,kind,root,profile_id) VALUES(?,?,?,?)").run(`profile:${t}`,"profile",K(B(i.grantee??"app:terminal",t).memory),t);const p=e.prepare("INSERT INTO profile_projects(profile_id,path,position,memory) VALUES(?,?,?,?)");i.projects.forEach((m,l)=>p.run(t,m.path,l,m.memory)),R(e,`profile:${t}`,u(s,L)),k(e,`profile:${t}`,u(s,w))}const a=u(r,"profile-defaults.json");if(d(a)){const n=g(a);if(n===null||typeof n!="object"||Array.isArray(n))throw new Error(`legacy profile defaults are malformed: ${a}`);const t=e.prepare("INSERT INTO profile_defaults(directory,profile_id) VALUES(?,?)");for(const[s,c]of Object.entries(n)){if(typeof c!="string")throw new Error(`legacy profile default is malformed: ${a}`);t.run(s,c)}}}f(ee,"importUser");export{de as convertLegacyProviderStore,ue as convertLegacyScopedStore,Se as initializeFreshScopedStore};
3
+ `),{result:void 0}))}b(r,t=>{T(t,"provider");for(const[s,c]of a){const i=JSON.parse(S(u(r.root,`${s}-credentials.json`),"utf8")),p=Object.keys(i.accounts),m=t.prepare("INSERT INTO managed_accounts(provider_id,id,label,label_key,position,last_attempt_at,last_rate_limited_at,rate_limited_until,auth_failure) VALUES(?,?,?,?,?,?,?,?,?)");c.forEach((l,y)=>m.run(s,p[y],l.label,l.label.toLowerCase(),y,l.lastAttemptAt,l.lastRateLimitedAt,l.rateLimitedUntil,l.authFailure??null))}(n.defaultFallbackStrength!==void 0||n.revertWhenAvailable!==void 0)&&t.prepare("INSERT INTO rotation_settings(singleton,default_fallback_strength,revert_when_available) VALUES(1,?,?)").run(n.defaultFallbackStrength??null,n.revertWhenAvailable===void 0?null:n.revertWhenAvailable?1:0)})})}f(de,"convertLegacyProviderStore");function R(e,r,o){if(!d(o))return;const a=g(o);if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy config is malformed: ${o}`);e.prepare("INSERT INTO scope_settings(owner_key,raw_json) VALUES(?,?)").run(r,JSON.stringify(a))}f(R,"importSettings");function E(e,r,o){if(!d(o))return;const a=g(o);if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy state is malformed: ${o}`);const n=a;e.prepare("INSERT INTO scope_bookkeeping(owner_key,last_self_check,active_canvas) VALUES(?,?,?)").run(r,n.last_self_check??null,n.activeCanvas??null);const t=e.prepare("INSERT INTO scope_marketplaces(owner_key,name,last_updated) VALUES(?,?,?)");for(const[c,i]of Object.entries(n.marketplaces??{}))t.run(r,c,i.last_updated??null);const s=e.prepare("INSERT INTO scope_plugins(owner_key,name,last_updated,etag,checked_at) VALUES(?,?,?,?,?)");for(const[c,i]of Object.entries(n.plugins??{}))s.run(r,c,i.last_updated??null,i.etag??null,i.checked_at??null)}f(E,"importState");function ee(e,r){R(e,"user",u(r,L)),E(e,"user",u(r,w));const o=u(r,W);if(d(o))for(const n of P(o,{withFileTypes:!0})){if(!n.isDirectory()||!z.test(n.name))continue;const t=n.name,s=u(o,t),c=u(s,"profile.json");if(!d(c))throw new Error(`legacy profile manifest is missing: ${c}`);const i=g(c);if(!i||typeof i!="object"||!Array.isArray(i.projects)||typeof i.name!="string"||typeof i.created_at!="string")throw new Error(`legacy profile manifest is malformed: ${c}`);e.prepare("INSERT INTO profiles(id,name,created_at,last_used_at,paused_at,default_kind,grantee,metadata_json) VALUES(?,?,?,?,?,?,?,?)").run(t,i.name,i.created_at,i.last_used_at??null,i.paused_at??null,i.default_kind??null,i.grantee??null,JSON.stringify(i.metadata??{})),e.prepare("INSERT INTO scope_owners(owner_key,kind,root,profile_id) VALUES(?,?,?,?)").run(`profile:${t}`,"profile",K(B(i.grantee??"app:terminal",t).memory),t);const p=e.prepare("INSERT INTO profile_projects(profile_id,path,position) VALUES(?,?,?)"),m=e.prepare("INSERT INTO legacy_project_caps(profile_id,path,memory) VALUES(?,?,?)");i.projects.forEach((l,y)=>{p.run(t,l.path,y),l.memory!==void 0&&l.memory!=="content"&&m.run(t,l.path,l.memory)}),R(e,`profile:${t}`,u(s,L)),E(e,`profile:${t}`,u(s,w))}const a=u(r,"profile-defaults.json");if(d(a)){const n=g(a);if(n===null||typeof n!="object"||Array.isArray(n))throw new Error(`legacy profile defaults are malformed: ${a}`);const t=e.prepare("INSERT INTO profile_defaults(directory,profile_id) VALUES(?,?)");for(const[s,c]of Object.entries(n)){if(typeof c!="string")throw new Error(`legacy profile default is malformed: ${a}`);t.run(s,c)}}}f(ee,"importUser");export{de as convertLegacyProviderStore,ue as convertLegacyScopedStore,Se as initializeFreshScopedStore};
@@ -11,3 +11,14 @@ export declare function deleteStoredProfile(root: string, id: string): boolean;
11
11
  export declare function rewriteLocalProfileGrantees(root: string): void;
12
12
  export declare function readStoredDefaults(root: string): Record<string, string>;
13
13
  export declare function mutateStoredDefaults(root: string, mutate: (current: Record<string, string>) => Record<string, string>): Record<string, string>;
14
+ /** Pre-canvas per-project memory caps (`none|name|preview`) the canvas import has not converted yet. */
15
+ export declare function listLegacyProjectCaps(root: string): Array<{
16
+ profileId: string;
17
+ path: string;
18
+ memory: string;
19
+ }>;
20
+ /** Store each converted profile's delivery limits and delete every legacy cap row, in one write. */
21
+ export declare function commitConvertedProjectCaps(root: string, limits: ReadonlyArray<{
22
+ profileId: string;
23
+ deliveryLimits: Record<string, string>;
24
+ }>): void;
@@ -1 +1 @@
1
- var _=Object.defineProperty;var o=(r,e)=>_(r,"name",{value:e,configurable:!0});import{canonicalRoot as c,userStore as m}from"./paths.js";import{profileSpace as R}from"../layout.js";import{openScopedStore as E,withScopedWrite as l}from"./db.js";function p(r){return m(r)}o(p,"store");function S(r,e){return{profileId:r.id,manifest:{schema_version:1,name:r.name,projects:e,paused_at:r.paused_at,...r.default_kind===null?{}:{default_kind:r.default_kind},...r.grantee===null?{}:{grantee:r.grantee},...Object.keys(JSON.parse(r.metadata_json)).length===0?{}:{metadata:JSON.parse(r.metadata_json)},created_at:r.created_at,last_used_at:r.last_used_at}}}o(S,"rowToProfile");function f(r,e){const t=r.prepare("SELECT id, name, created_at, last_used_at, paused_at, default_kind, grantee, metadata_json FROM profiles WHERE id=?").get(e);if(!t)return null;const a=r.prepare("SELECT path, memory FROM profile_projects WHERE profile_id=? ORDER BY position").all(e);return S(t,a)}o(f,"get");function k(r){const e=E(p(r));return e.prepare("SELECT id FROM profiles ORDER BY rowid").all().map(({id:a})=>f(e,a)).filter(Boolean)}o(k,"listStoredProfiles");function L(r,e){return f(E(p(r)),e)}o(L,"getStoredProfile");function I(r,e){l(p(r),t=>{t.prepare("INSERT INTO profiles(id,name,created_at,last_used_at,paused_at,default_kind,grantee,metadata_json) VALUES(?,?,?,?,?,?,?,?)").run(e.profileId,e.manifest.name,e.manifest.created_at,e.manifest.last_used_at,e.manifest.paused_at,e.manifest.default_kind??null,e.manifest.grantee??null,JSON.stringify(e.manifest.metadata??{})),t.prepare("INSERT INTO scope_owners(owner_key,kind,root,profile_id) VALUES(?,?,?,?)").run(`profile:${e.profileId}`,"profile",c(R(e.manifest.grantee??"app:terminal",e.profileId).memory),e.profileId);const a=t.prepare("INSERT INTO profile_projects(profile_id,path,position,memory) VALUES(?,?,?,?)");e.manifest.projects.forEach((i,n)=>a.run(e.profileId,i.path,n,i.memory))})}o(I,"insertStoredProfile");function j(r,e,t){return l(p(r),a=>{const i=f(a,e);if(!i)return null;const n=t(i.manifest);a.prepare("UPDATE profiles SET name=?, last_used_at=?, paused_at=?, default_kind=?, grantee=?, metadata_json=? WHERE id=?").run(n.name,n.last_used_at,n.paused_at,n.default_kind??null,n.grantee??null,JSON.stringify(n.metadata??{}),e),a.prepare("DELETE FROM profile_projects WHERE profile_id=?").run(e);const s=a.prepare("INSERT INTO profile_projects(profile_id,path,position,memory) VALUES(?,?,?,?)");return n.projects.forEach((u,d)=>s.run(e,u.path,d,u.memory)),{profileId:e,manifest:n}})}o(j,"updateStoredProfile");function D(r,e){return l(p(r),t=>{if(!f(t,e))return!1;const a=`profile:${e}`;return t.prepare("DELETE FROM scope_settings WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_bookkeeping WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_marketplaces WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_plugins WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_owners WHERE owner_key=?").run(a),t.prepare("DELETE FROM profiles WHERE id=?").run(e),!0})}o(D,"deleteStoredProfile");function N(r){l(p(r),e=>{e.prepare("UPDATE profiles SET grantee = 'app:terminal' WHERE grantee = 'user:local'").run()})}o(N,"rewriteLocalProfileGrantees");function F(r){const e=E(p(r));return Object.fromEntries(e.prepare("SELECT directory,profile_id FROM profile_defaults").all().map(t=>[t.directory,t.profile_id]))}o(F,"readStoredDefaults");function M(r,e){return l(p(r),t=>{const a=Object.fromEntries(t.prepare("SELECT directory,profile_id FROM profile_defaults").all().map(s=>[s.directory,s.profile_id])),i=e(a);t.prepare("DELETE FROM profile_defaults").run();const n=t.prepare("INSERT INTO profile_defaults(directory,profile_id) VALUES(?,?)");for(const[s,u]of Object.entries(i))n.run(s,u);return i})}o(M,"mutateStoredDefaults");export{D as deleteStoredProfile,L as getStoredProfile,I as insertStoredProfile,k as listStoredProfiles,M as mutateStoredDefaults,F as readStoredDefaults,N as rewriteLocalProfileGrantees,j as updateStoredProfile};
1
+ var E=Object.defineProperty;var n=(r,e)=>E(r,"name",{value:e,configurable:!0});import{canonicalRoot as c,userStore as m}from"./paths.js";import{profileSpace as R}from"../layout.js";import{openScopedStore as f,withScopedWrite as l}from"./db.js";function p(r){return m(r)}n(p,"store");function S(r,e){return{profileId:r.id,manifest:{schema_version:1,name:r.name,projects:e,paused_at:r.paused_at,...r.default_kind===null?{}:{default_kind:r.default_kind},...r.grantee===null?{}:{grantee:r.grantee},...r.delivery_limits_json==="{}"?{}:{delivery_limits:JSON.parse(r.delivery_limits_json)},...Object.keys(JSON.parse(r.metadata_json)).length===0?{}:{metadata:JSON.parse(r.metadata_json)},created_at:r.created_at,last_used_at:r.last_used_at}}}n(S,"rowToProfile");function d(r,e){const t=r.prepare("SELECT id, name, created_at, last_used_at, paused_at, default_kind, grantee, metadata_json, delivery_limits_json FROM profiles WHERE id=?").get(e);if(!t)return null;const a=r.prepare("SELECT path FROM profile_projects WHERE profile_id=? ORDER BY position").all(e);return S(t,a)}n(d,"get");function j(r){const e=f(p(r));return e.prepare("SELECT id FROM profiles ORDER BY rowid").all().map(({id:a})=>d(e,a)).filter(Boolean)}n(j,"listStoredProfiles");function L(r,e){return d(f(p(r)),e)}n(L,"getStoredProfile");function I(r,e){l(p(r),t=>{t.prepare("INSERT INTO profiles(id,name,created_at,last_used_at,paused_at,default_kind,grantee,metadata_json,delivery_limits_json) VALUES(?,?,?,?,?,?,?,?,?)").run(e.profileId,e.manifest.name,e.manifest.created_at,e.manifest.last_used_at,e.manifest.paused_at,e.manifest.default_kind??null,e.manifest.grantee??null,JSON.stringify(e.manifest.metadata??{}),JSON.stringify(e.manifest.delivery_limits??{})),t.prepare("INSERT INTO scope_owners(owner_key,kind,root,profile_id) VALUES(?,?,?,?)").run(`profile:${e.profileId}`,"profile",c(R(e.manifest.grantee??"app:terminal",e.profileId).memory),e.profileId);const a=t.prepare("INSERT INTO profile_projects(profile_id,path,position) VALUES(?,?,?)");e.manifest.projects.forEach((o,i)=>a.run(e.profileId,o.path,i))})}n(I,"insertStoredProfile");function k(r,e,t){return l(p(r),a=>{const o=d(a,e);if(!o)return null;const i=t(o.manifest);a.prepare("UPDATE profiles SET name=?, last_used_at=?, paused_at=?, default_kind=?, grantee=?, metadata_json=?, delivery_limits_json=? WHERE id=?").run(i.name,i.last_used_at,i.paused_at,i.default_kind??null,i.grantee??null,JSON.stringify(i.metadata??{}),JSON.stringify(i.delivery_limits??{}),e),a.prepare("DELETE FROM profile_projects WHERE profile_id=?").run(e);const s=a.prepare("INSERT INTO profile_projects(profile_id,path,position) VALUES(?,?,?)");return i.projects.forEach((_,u)=>s.run(e,_.path,u)),{profileId:e,manifest:i}})}n(k,"updateStoredProfile");function N(r,e){return l(p(r),t=>{if(!d(t,e))return!1;const a=`profile:${e}`;return t.prepare("DELETE FROM scope_settings WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_bookkeeping WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_marketplaces WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_plugins WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_owners WHERE owner_key=?").run(a),t.prepare("DELETE FROM profiles WHERE id=?").run(e),!0})}n(N,"deleteStoredProfile");function D(r){l(p(r),e=>{e.prepare("UPDATE profiles SET grantee = 'app:terminal' WHERE grantee = 'user:local'").run()})}n(D,"rewriteLocalProfileGrantees");function h(r){const e=f(p(r));return Object.fromEntries(e.prepare("SELECT directory,profile_id FROM profile_defaults").all().map(t=>[t.directory,t.profile_id]))}n(h,"readStoredDefaults");function F(r,e){return l(p(r),t=>{const a=Object.fromEntries(t.prepare("SELECT directory,profile_id FROM profile_defaults").all().map(s=>[s.directory,s.profile_id])),o=e(a);t.prepare("DELETE FROM profile_defaults").run();const i=t.prepare("INSERT INTO profile_defaults(directory,profile_id) VALUES(?,?)");for(const[s,_]of Object.entries(o))i.run(s,_);return o})}n(F,"mutateStoredDefaults");function M(r){return f(p(r)).prepare("SELECT profile_id, path, memory FROM legacy_project_caps ORDER BY profile_id, path").all().map(e=>({profileId:e.profile_id,path:e.path,memory:e.memory}))}n(M,"listLegacyProjectCaps");function W(r,e){l(p(r),t=>{const a=t.prepare("UPDATE profiles SET delivery_limits_json=? WHERE id=?");for(const o of e)if(a.run(JSON.stringify(o.deliveryLimits),o.profileId).changes!==1)throw new Error(`no stored profile ${o.profileId}`);t.prepare("DELETE FROM legacy_project_caps").run()})}n(W,"commitConvertedProjectCaps");export{W as commitConvertedProjectCaps,N as deleteStoredProfile,L as getStoredProfile,I as insertStoredProfile,M as listLegacyProjectCaps,j as listStoredProfiles,F as mutateStoredDefaults,h as readStoredDefaults,D as rewriteLocalProfileGrantees,k as updateStoredProfile};
@@ -1,4 +1,4 @@
1
1
  import type { DatabaseSync } from 'node:sqlite';
2
- export declare const SCOPED_SCHEMA_VERSION = 3;
2
+ export declare const SCOPED_SCHEMA_VERSION = 5;
3
3
  export declare const PROVIDER_SCHEMA_VERSION = 1;
4
4
  export declare function createScopedSchema(db: DatabaseSync, kind: 'user' | 'project' | 'provider'): void;