@north-light/crouter 0.3.353 → 0.3.354

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 (609) 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 +133 -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 +167 -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 +9 -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/04-orchestration-kernel.md +7 -7
  25. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +1 -1
  26. package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
  27. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +2 -2
  28. package/dist/builtin-memory/crouter-concepts/INDEX.md +2 -2
  29. package/dist/builtin-memory/crouter-concepts/lifecycle-and-wakes.md +1 -1
  30. package/dist/builtin-memory/crouter-concepts/memory.md +15 -15
  31. package/dist/builtin-memory/crouter-concepts/nodes-and-the-canvas.md +1 -1
  32. package/dist/builtin-memory/crouter-concepts/profiles-kinds-and-modes.md +5 -5
  33. package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +1 -1
  34. package/dist/builtin-memory/crouter-concepts/why-a-daemon.md +1 -1
  35. package/dist/builtin-memory/crouter-sdk/INDEX.md +2 -2
  36. package/dist/builtin-memory/crouter-sdk/README.md +5 -6
  37. package/dist/builtin-memory/crouter-sdk/errors.md +0 -13
  38. package/dist/builtin-memory/crouter-sdk/guides/README.md +0 -1
  39. package/dist/builtin-memory/crouter-sdk/guides/event-driven-assistant.md +2 -2
  40. package/dist/builtin-memory/crouter-sdk/nodes.md +0 -2
  41. package/dist/builtin-memory/crouter-sdk/resources.md +0 -1
  42. package/dist/builtin-memory/explore/exploration-doc.md +4 -4
  43. package/dist/builtin-memory/insights/capture.md +6 -6
  44. package/dist/builtin-memory/insights/init.md +14 -14
  45. package/dist/builtin-memory/internal/INDEX.md +4 -4
  46. package/dist/builtin-memory/internal/agent-shaping.md +20 -20
  47. package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
  48. package/dist/builtin-memory/internal/marketplaces.md +2 -2
  49. package/dist/builtin-memory/internal/memory-loading.md +31 -30
  50. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  51. package/dist/builtin-memory/internal/plugins.md +16 -14
  52. package/dist/builtin-memory/internal/storage-tiers.md +4 -4
  53. package/dist/builtin-memory/memory-read-orientation.md +1 -1
  54. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +32 -40
  55. package/dist/clients/attach/input/controller.js +1 -1
  56. package/dist/clients/attach/input/ref-autocomplete.js +1 -1
  57. package/dist/clients/attach/input/titled-editor.js +1 -1
  58. package/dist/clients/attach/render/chat-view.js +1 -1
  59. package/dist/clients/attach/render/crtr-output.d.ts +1 -2
  60. package/dist/clients/attach/render/crtr-output.js +17 -17
  61. package/dist/clients/attach/render/group-activity.d.ts +8 -8
  62. package/dist/clients/attach/render/group-activity.js +2 -2
  63. package/dist/clients/attach/render/group-recap.js +1 -1
  64. package/dist/clients/attach/render/tool-calls.d.ts +1 -1
  65. package/dist/clients/attach/session/profile-files.js +1 -1
  66. package/dist/clients/attach/slash/dispatch.js +1 -1
  67. package/dist/clients/attach/viewer.js +806 -1553
  68. package/dist/commands/api-client.d.ts +2 -0
  69. package/dist/commands/api-client.js +3 -3
  70. package/dist/commands/canvas/edges.d.ts +2 -0
  71. package/dist/commands/canvas/edges.js +2 -0
  72. package/dist/commands/canvas/list.d.ts +4 -0
  73. package/dist/commands/canvas/list.js +3 -0
  74. package/dist/commands/canvas/read.d.ts +8 -0
  75. package/dist/commands/canvas/read.js +5 -0
  76. package/dist/commands/canvas/search.d.ts +2 -0
  77. package/dist/commands/canvas/search.js +3 -0
  78. package/dist/commands/canvas/unwatch.d.ts +2 -0
  79. package/dist/commands/canvas/unwatch.js +1 -0
  80. package/dist/commands/canvas/watch.d.ts +3 -0
  81. package/dist/commands/canvas/watch.js +1 -0
  82. package/dist/commands/canvas-analytics.js +1 -1
  83. package/dist/commands/canvas-history/grep.js +4 -4
  84. package/dist/commands/canvas-history/read.js +2 -2
  85. package/dist/commands/canvas-history/search.js +7 -7
  86. package/dist/commands/canvas-history/shared.d.ts +0 -1
  87. package/dist/commands/canvas-history/shared.js +1 -1
  88. package/dist/commands/canvas-history/stats.js +2 -2
  89. package/dist/commands/canvas-history.js +1 -1
  90. package/dist/commands/canvas.js +1 -1
  91. package/dist/commands/doc/delete.d.ts +2 -0
  92. package/dist/commands/doc/delete.js +1 -0
  93. package/dist/commands/doc/edit.d.ts +2 -0
  94. package/dist/commands/doc/edit.js +1 -0
  95. package/dist/commands/doc/history.d.ts +2 -0
  96. package/dist/commands/doc/history.js +2 -0
  97. package/dist/commands/doc/lint.d.ts +2 -0
  98. package/dist/commands/doc/lint.js +2 -0
  99. package/dist/commands/doc/list.d.ts +2 -0
  100. package/dist/commands/doc/list.js +1 -0
  101. package/dist/commands/doc/move.d.ts +2 -0
  102. package/dist/commands/doc/move.js +1 -0
  103. package/dist/commands/doc/read.d.ts +2 -0
  104. package/dist/commands/doc/read.js +1 -0
  105. package/dist/commands/doc/shared.d.ts +25 -0
  106. package/dist/commands/doc/shared.js +2 -0
  107. package/dist/commands/doc/write.d.ts +2 -0
  108. package/dist/commands/doc/write.js +1 -0
  109. package/dist/commands/{memory.d.ts → doc.d.ts} +1 -1
  110. package/dist/commands/doc.js +1 -0
  111. package/dist/commands/human/review.js +1 -1
  112. package/dist/commands/node/bash.js +2 -2
  113. package/dist/commands/node/create.js +1 -1
  114. package/dist/commands/node/inspect.js +10 -10
  115. package/dist/commands/node/lifecycle.js +2 -2
  116. package/dist/commands/node/outcome.js +1 -1
  117. package/dist/commands/node/subscription.js +1 -1
  118. package/dist/commands/node-context.js +2 -2
  119. package/dist/commands/pkg/browse/catalog.js +1 -1
  120. package/dist/commands/pkg/browse/doc-view.js +1 -1
  121. package/dist/commands/pkg/browse/model.d.ts +9 -17
  122. package/dist/commands/pkg/plugin-inspect.js +1 -1
  123. package/dist/commands/pkg/plugin-manage.d.ts +4 -8
  124. package/dist/commands/pkg/plugin-manage.js +15 -17
  125. package/dist/commands/profile/list.js +1 -1
  126. package/dist/commands/profile/new.js +1 -1
  127. package/dist/commands/profile/project.js +1 -1
  128. package/dist/commands/profile/show.js +1 -1
  129. package/dist/commands/push.js +3 -3
  130. package/dist/commands/sys/config.js +1 -1
  131. package/dist/commands/sys/context/admin/actions.d.ts +18 -43
  132. package/dist/commands/sys/context/admin/actions.js +1 -2
  133. package/dist/commands/sys/context/admin/detail-panel.d.ts +17 -25
  134. package/dist/commands/sys/context/admin/detail-panel.js +2 -1
  135. package/dist/commands/sys/context/admin/docs-panel.d.ts +7 -6
  136. package/dist/commands/sys/context/admin/docs-panel.js +1 -1
  137. package/dist/commands/sys/context/admin/list-view.d.ts +12 -12
  138. package/dist/commands/sys/context/admin/list-view.js +1 -1
  139. package/dist/commands/sys/context/admin/model.d.ts +96 -69
  140. package/dist/commands/sys/context/admin/model.js +1 -1
  141. package/dist/commands/sys/context/admin/rail-panel.d.ts +7 -5
  142. package/dist/commands/sys/context/admin/rail-panel.js +1 -1
  143. package/dist/commands/sys/context/admin/read-view.d.ts +10 -14
  144. package/dist/commands/sys/context/admin/read-view.js +1 -2
  145. package/dist/commands/sys/context/admin/shell.d.ts +26 -31
  146. package/dist/commands/sys/context/admin/shell.js +1 -1
  147. package/dist/commands/sys/context/admin.js +2 -2
  148. package/dist/commands/sys/context/doc.js +2 -3
  149. package/dist/commands/sys/context/expose.js +2 -2
  150. package/dist/commands/sys/context/prompt-review.js +4 -4
  151. package/dist/commands/sys/context/resolve.d.ts +92 -65
  152. package/dist/commands/sys/context/resolve.js +7 -9
  153. package/dist/commands/sys/context.js +1 -1
  154. package/dist/commands/sys/doctor.js +1 -1
  155. package/dist/commands/sys/migrate.js +1 -1
  156. package/dist/commands/sys/panels/profiles-panel.d.ts +3 -1
  157. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  158. package/dist/commands/sys/sync-deps.d.ts +6 -11
  159. package/dist/commands/sys/sync-deps.js +7 -8
  160. package/dist/commands/sys/sync-project-guidance.js +5 -4
  161. package/dist/commands/sys/sync-shared.d.ts +41 -4
  162. package/dist/commands/sys/sync-shared.js +1 -1
  163. package/dist/commands/sys/sync-skills.js +2 -2
  164. package/dist/commands/sys/sync.js +1 -1
  165. package/dist/core/bash-job-supervisor.d.ts +2 -3
  166. package/dist/core/bash-job-supervisor.js +3 -3
  167. package/dist/core/bash-jobs.d.ts +0 -5
  168. package/dist/core/bash-jobs.js +7 -7
  169. package/dist/core/bootstrap.js +2 -2
  170. package/dist/core/canvas/canvas.d.ts +6 -50
  171. package/dist/core/canvas/canvas.js +16 -21
  172. package/dist/core/canvas/db.d.ts +4 -1
  173. package/dist/core/canvas/db.js +2 -2
  174. package/dist/core/canvas/history.d.ts +11 -39
  175. package/dist/core/canvas/history.js +9 -20
  176. package/dist/core/canvas/install-id.d.ts +2 -2
  177. package/dist/core/canvas/install-id.js +1 -1
  178. package/dist/core/canvas/memory-reads.d.ts +5 -0
  179. package/dist/core/canvas/memory-reads.js +1 -1
  180. package/dist/core/canvas/migrations.js +215 -41
  181. package/dist/core/canvas/node-agent-paths.js +1 -1
  182. package/dist/core/canvas/node-tokens.js +1 -1
  183. package/dist/core/canvas/paths.d.ts +0 -4
  184. package/dist/core/canvas/paths.js +1 -1
  185. package/dist/core/canvas/remote-canvas-source.d.ts +0 -1
  186. package/dist/core/canvas/remote-canvas-source.js +1 -1
  187. package/dist/core/canvas/render-source.d.ts +9 -6
  188. package/dist/core/canvas/render-source.js +6 -6
  189. package/dist/core/canvas/sessions.js +2 -2
  190. package/dist/core/canvas/source.d.ts +6 -0
  191. package/dist/core/canvas/tree.d.ts +29 -0
  192. package/dist/core/canvas/tree.js +12 -0
  193. package/dist/core/canvas/types.d.ts +0 -20
  194. package/dist/core/command-plugins/bundle.js +1 -1
  195. package/dist/core/config.d.ts +1 -1
  196. package/dist/core/conversation-store/listener.js +4 -2
  197. package/dist/core/feed/feed.d.ts +9 -7
  198. package/dist/core/feed/feed.js +3 -7
  199. package/dist/core/feed/inbox.d.ts +3 -5
  200. package/dist/core/feed/inbox.js +1 -10
  201. package/dist/core/feed/messages.d.ts +33 -6
  202. package/dist/core/feed/messages.js +10 -7
  203. package/dist/core/feed/reports.d.ts +10 -0
  204. package/dist/core/feed/reports.js +2 -0
  205. package/dist/core/grants/remove.js +1 -1
  206. package/dist/core/graph/access.d.ts +24 -0
  207. package/dist/core/graph/access.js +8 -0
  208. package/dist/core/graph/bodies.d.ts +6 -0
  209. package/dist/core/graph/bodies.js +1 -0
  210. package/dist/core/graph/deletion.d.ts +9 -0
  211. package/dist/core/graph/deletion.js +5 -0
  212. package/dist/core/graph/diff.d.ts +4 -0
  213. package/dist/core/graph/diff.js +4 -0
  214. package/dist/core/graph/documents.d.ts +160 -0
  215. package/dist/core/graph/documents.js +7 -0
  216. package/dist/core/graph/edges.d.ts +24 -0
  217. package/dist/core/graph/edges.js +1 -0
  218. package/dist/core/graph/events.d.ts +26 -0
  219. package/dist/core/graph/events.js +6 -0
  220. package/dist/core/graph/exposures.d.ts +53 -0
  221. package/dist/core/graph/exposures.js +4 -0
  222. package/dist/core/graph/jobs.d.ts +31 -0
  223. package/dist/core/graph/jobs.js +2 -0
  224. package/dist/core/graph/names.d.ts +28 -0
  225. package/dist/core/graph/names.js +3 -0
  226. package/dist/core/graph/objects.d.ts +55 -0
  227. package/dist/core/graph/objects.js +9 -0
  228. package/dist/core/graph/package-docs.d.ts +31 -0
  229. package/dist/core/graph/package-docs.js +5 -0
  230. package/dist/core/graph/package-files.d.ts +20 -0
  231. package/dist/core/graph/package-files.js +2 -0
  232. package/dist/core/graph/reader.d.ts +21 -0
  233. package/dist/core/graph/reader.js +3 -0
  234. package/dist/core/graph/repo-sync/exchange.d.ts +34 -0
  235. package/dist/core/graph/repo-sync/exchange.js +2 -0
  236. package/dist/core/graph/repo-sync/identity.d.ts +30 -0
  237. package/dist/core/graph/repo-sync/identity.js +1 -0
  238. package/dist/core/graph/repo-sync/index.d.ts +4 -0
  239. package/dist/core/graph/repo-sync/index.js +1 -0
  240. package/dist/core/graph/repo-sync/mirror.d.ts +30 -0
  241. package/dist/core/graph/repo-sync/mirror.js +6 -0
  242. package/dist/core/graph/repo-sync/ref-format.d.ts +76 -0
  243. package/dist/core/graph/repo-sync/ref-format.js +2 -0
  244. package/dist/core/graph/repo-sync/repos.d.ts +17 -0
  245. package/dist/core/graph/repo-sync/repos.js +3 -0
  246. package/dist/core/graph/repo-sync/sync.d.ts +42 -0
  247. package/dist/core/graph/repo-sync/sync.js +2 -0
  248. package/dist/core/graph/rules.d.ts +26 -0
  249. package/dist/core/graph/rules.js +3 -0
  250. package/dist/core/graph/spaces/app.d.ts +3 -0
  251. package/dist/core/graph/spaces/app.js +1 -0
  252. package/dist/core/graph/spaces/index.d.ts +19 -0
  253. package/dist/core/graph/spaces/index.js +1 -0
  254. package/dist/core/graph/spaces/person.d.ts +5 -0
  255. package/dist/core/graph/spaces/person.js +2 -0
  256. package/dist/core/graph/spaces/repo.d.ts +4 -0
  257. package/dist/core/graph/spaces/repo.js +1 -0
  258. package/dist/core/graph/types.d.ts +75 -0
  259. package/dist/core/graph/types.js +1 -0
  260. package/dist/core/graph/watches.d.ts +62 -0
  261. package/dist/core/graph/watches.js +18 -0
  262. package/dist/core/human/feedback-companion.js +1 -1
  263. package/dist/core/human/requests.d.ts +3 -1
  264. package/dist/core/human/requests.js +6 -6
  265. package/dist/core/inspector/model.js +2 -2
  266. package/dist/core/io.js +5 -5
  267. package/dist/core/layout-migrate/index.d.ts +24 -1
  268. package/dist/core/layout-migrate/index.js +4 -4
  269. package/dist/core/layout-migrate/paths.d.ts +4 -0
  270. package/dist/core/layout-migrate/paths.js +1 -1
  271. package/dist/core/layout-migrate/stored-paths.d.ts +7 -0
  272. package/dist/core/layout-migrate/stored-paths.js +11 -11
  273. package/dist/core/layout-migrate/stores.d.ts +19 -6
  274. package/dist/core/layout-migrate/stores.js +3 -4
  275. package/dist/core/manifest.d.ts +0 -2
  276. package/dist/core/manifest.js +1 -1
  277. package/dist/core/{memory/extensions.d.ts → plugin-extensions.d.ts} +9 -10
  278. package/dist/core/plugin-extensions.js +1 -0
  279. package/dist/core/preview-registry.d.ts +1 -1
  280. package/dist/core/preview-registry.js +3 -2
  281. package/dist/core/profiles/manifest.d.ts +7 -7
  282. package/dist/core/profiles/manifest.js +1 -1
  283. package/dist/core/profiles/select.js +3 -3
  284. package/dist/core/review/birth.js +1 -1
  285. package/dist/core/review/companion.js +1 -1
  286. package/dist/core/review/stage.d.ts +12 -1
  287. package/dist/core/review/stage.js +1 -1
  288. package/dist/core/review/store.d.ts +2 -0
  289. package/dist/core/review/store.js +1 -1
  290. package/dist/core/review/types.d.ts +7 -1
  291. package/dist/core/runs/events.js +1 -1
  292. package/dist/core/runs/operations.js +5 -5
  293. package/dist/core/runs/questions.js +2 -2
  294. package/dist/core/runtime/bearings-render.d.ts +13 -7
  295. package/dist/core/runtime/bearings-render.js +12 -12
  296. package/dist/core/runtime/bearings.d.ts +8 -18
  297. package/dist/core/runtime/bearings.js +7 -7
  298. package/dist/core/runtime/broker/daemon-ops.d.ts +7 -12
  299. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  300. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  301. package/dist/core/runtime/broker/fault-retry.js +1 -1
  302. package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
  303. package/dist/core/runtime/broker/frame-memory-refs.d.ts +7 -2
  304. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  305. package/dist/core/runtime/broker/inbox.d.ts +1 -4
  306. package/dist/core/runtime/broker/inbox.js +1 -10
  307. package/dist/core/runtime/broker/rebind.js +1 -1
  308. package/dist/core/runtime/broker/retry-card-elision.d.ts +7 -0
  309. package/dist/core/runtime/broker/retry-card-elision.js +1 -0
  310. package/dist/core/runtime/broker-extension-render.d.ts +0 -13
  311. package/dist/core/runtime/broker-extension-render.js +2 -4
  312. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  313. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  314. package/dist/core/runtime/broker.js +1 -1
  315. package/dist/core/runtime/close.d.ts +9 -4
  316. package/dist/core/runtime/close.js +1 -1
  317. package/dist/core/runtime/deliver-live.js +1 -1
  318. package/dist/core/runtime/kickoff.js +17 -19
  319. package/dist/core/runtime/launch-target.d.ts +7 -0
  320. package/dist/core/runtime/launch-target.js +1 -1
  321. package/dist/core/runtime/ledger.d.ts +10 -0
  322. package/dist/core/runtime/ledger.js +3 -0
  323. package/dist/core/runtime/lifecycle.js +2 -2
  324. package/dist/core/runtime/nodes.d.ts +10 -2
  325. package/dist/core/runtime/nodes.js +1 -1
  326. package/dist/core/runtime/outcome-document.d.ts +2 -2
  327. package/dist/core/runtime/outcome-document.js +1 -1
  328. package/dist/core/runtime/persona.js +2 -2
  329. package/dist/core/runtime/placement.js +1 -1
  330. package/dist/core/runtime/promote.d.ts +2 -2
  331. package/dist/core/runtime/promote.js +1 -1
  332. package/dist/core/runtime/prospective-inventory-cli.js +2 -2
  333. package/dist/core/runtime/recycle.js +1 -1
  334. package/dist/core/runtime/reopen.js +1 -1
  335. package/dist/core/runtime/revive.js +2 -2
  336. package/dist/core/runtime/roadmap.d.ts +17 -9
  337. package/dist/core/runtime/roadmap.js +4 -4
  338. package/dist/core/runtime/spawn-env.js +1 -1
  339. package/dist/core/runtime/spawn.d.ts +5 -3
  340. package/dist/core/runtime/spawn.js +2 -2
  341. package/dist/core/runtime/structured-output.d.ts +3 -1
  342. package/dist/core/runtime/structured-output.js +4 -4
  343. package/dist/core/scope.d.ts +1 -32
  344. package/dist/core/scope.js +1 -1
  345. package/dist/core/scoped-state/db.js +2 -1
  346. package/dist/core/scoped-state/migrate.js +2 -2
  347. package/dist/core/scoped-state/profiles.d.ts +11 -0
  348. package/dist/core/scoped-state/profiles.js +1 -1
  349. package/dist/core/scoped-state/schema.d.ts +1 -1
  350. package/dist/core/scoped-state/schema.js +7 -5
  351. package/dist/core/spaces/permissions.d.ts +0 -14
  352. package/dist/core/spaces/permissions.js +1 -1
  353. package/dist/core/spaces/stop.d.ts +13 -0
  354. package/dist/core/spaces/stop.js +2 -2
  355. package/dist/core/storage/tables.d.ts +1 -1
  356. package/dist/core/substrate/delivery/corpus.d.ts +21 -0
  357. package/dist/core/substrate/delivery/corpus.js +3 -0
  358. package/dist/core/substrate/delivery/deliver.d.ts +76 -0
  359. package/dist/core/substrate/delivery/deliver.js +6 -0
  360. package/dist/core/substrate/delivery/listings.d.ts +27 -0
  361. package/dist/core/substrate/delivery/listings.js +4 -0
  362. package/dist/core/substrate/delivery/match.d.ts +28 -0
  363. package/dist/core/substrate/delivery/match.js +1 -0
  364. package/dist/core/substrate/delivery/plan.d.ts +67 -0
  365. package/dist/core/substrate/delivery/plan.js +3 -0
  366. package/dist/core/substrate/delivery/render-boot.d.ts +20 -0
  367. package/dist/core/substrate/delivery/render-boot.js +54 -0
  368. package/dist/core/substrate/delivery/render-event.d.ts +47 -0
  369. package/dist/core/substrate/delivery/render-event.js +6 -0
  370. package/dist/core/substrate/delivery/sub-persona-menu.d.ts +2 -0
  371. package/dist/core/substrate/delivery/sub-persona-menu.js +6 -0
  372. package/dist/core/substrate/delivery/types.d.ts +30 -0
  373. package/dist/core/substrate/delivery/types.js +0 -0
  374. package/dist/core/substrate/gate-explain.d.ts +0 -13
  375. package/dist/core/substrate/gate-explain.js +1 -1
  376. package/dist/core/substrate/schema.d.ts +11 -139
  377. package/dist/core/substrate/schema.js +1 -1
  378. package/dist/core/substrate/subject-fields.d.ts +3 -0
  379. package/dist/core/substrate/subject.d.ts +2 -1
  380. package/dist/core/substrate/subject.js +1 -1
  381. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  382. package/dist/daemon/api/handlers/bash-jobs.js +1 -2
  383. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  384. package/dist/daemon/api/handlers/canvas.js +5 -5
  385. package/dist/daemon/api/handlers/daemon.js +1 -1
  386. package/dist/daemon/api/handlers/delivery.d.ts +2 -0
  387. package/dist/daemon/api/handlers/delivery.js +1 -0
  388. package/dist/daemon/api/handlers/{memory.d.ts → docs.d.ts} +1 -1
  389. package/dist/daemon/api/handlers/docs.js +1 -0
  390. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  391. package/dist/daemon/api/handlers/messages.js +2 -2
  392. package/dist/daemon/api/handlers/node-records.js +2 -2
  393. package/dist/daemon/api/handlers/nodes.js +1 -1
  394. package/dist/daemon/api/handlers/objects.d.ts +2 -0
  395. package/dist/daemon/api/handlers/objects.js +5 -0
  396. package/dist/daemon/api/handlers/package-docs.d.ts +2 -0
  397. package/dist/daemon/api/handlers/package-docs.js +1 -0
  398. package/dist/daemon/api/handlers/profiles.js +1 -1
  399. package/dist/daemon/api/handlers/reports.d.ts +2 -2
  400. package/dist/daemon/api/handlers/reports.js +4 -4
  401. package/dist/daemon/api/handlers/reviews.js +1 -1
  402. package/dist/daemon/api/map.d.ts +2 -2
  403. package/dist/daemon/api/map.js +2 -2
  404. package/dist/daemon/api/operations.d.ts +1 -1
  405. package/dist/daemon/api/operations.js +1 -1
  406. package/dist/daemon/api/reader.d.ts +17 -0
  407. package/dist/daemon/api/reader.js +1 -0
  408. package/dist/daemon/api/server.js +1 -1
  409. package/dist/daemon/control.d.ts +2 -3
  410. package/dist/daemon/crtrd.js +8 -6
  411. package/dist/daemon/fleet.js +4 -4
  412. package/dist/daemon/reconcilers/bash-deadline.d.ts +11 -1
  413. package/dist/daemon/reconcilers/bash-deadline.js +2 -1
  414. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  415. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  416. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  417. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  418. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -0
  419. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  420. package/dist/daemon/review/deliver.js +2 -2
  421. package/dist/daemon/review/finish.js +1 -1
  422. package/dist/hook-authoring.d.ts +0 -1
  423. package/dist/hook-authoring.js +3 -3
  424. package/dist/migrations/004-canvas-documents/apply.d.ts +10 -0
  425. package/dist/migrations/004-canvas-documents/apply.js +1 -0
  426. package/dist/migrations/004-canvas-documents/fields.d.ts +24 -0
  427. package/dist/migrations/004-canvas-documents/fields.js +2 -0
  428. package/dist/migrations/004-canvas-documents/index.d.ts +16 -0
  429. package/dist/migrations/004-canvas-documents/index.js +2 -0
  430. package/dist/migrations/004-canvas-documents/legacy/discover.d.ts +16 -0
  431. package/dist/migrations/004-canvas-documents/legacy/discover.js +1 -0
  432. package/dist/migrations/004-canvas-documents/legacy/history.d.ts +5 -0
  433. package/dist/migrations/004-canvas-documents/legacy/history.js +2 -0
  434. package/dist/migrations/004-canvas-documents/legacy/nested.d.ts +7 -0
  435. package/dist/migrations/004-canvas-documents/legacy/nested.js +1 -0
  436. package/dist/migrations/004-canvas-documents/legacy/parse.d.ts +14 -0
  437. package/dist/migrations/004-canvas-documents/legacy/parse.js +1 -0
  438. package/dist/migrations/004-canvas-documents/legacy/types.d.ts +91 -0
  439. package/dist/migrations/004-canvas-documents/legacy/types.js +0 -0
  440. package/dist/migrations/004-canvas-documents/legacy-edges.d.ts +6 -0
  441. package/dist/migrations/004-canvas-documents/legacy-edges.js +18 -0
  442. package/dist/migrations/004-canvas-documents/plan.d.ts +102 -0
  443. package/dist/migrations/004-canvas-documents/plan.js +3 -0
  444. package/dist/migrations/004-canvas-documents/pointers.d.ts +23 -0
  445. package/dist/migrations/004-canvas-documents/pointers.js +4 -0
  446. package/dist/migrations/activation.d.ts +9 -18
  447. package/dist/migrations/activation.js +2 -2
  448. package/dist/pi-extensions/broker-local.d.ts +2 -2
  449. package/dist/pi-extensions/broker-local.js +2 -2
  450. package/dist/pi-extensions/canvas-bash-valve.js +5 -4
  451. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  452. package/dist/pi-extensions/canvas-doc-substrate.d.ts +0 -1
  453. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  454. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  455. package/dist/pi-extensions/canvas-passive-context.js +1 -1
  456. package/dist/pi-extensions/canvas-recap.js +2 -2
  457. package/dist/pi-extensions/canvas-stophook.d.ts +1 -1
  458. package/dist/pi-extensions/canvas-stophook.js +1 -1
  459. package/dist/prompts/review.js +3 -3
  460. package/dist/shared/env.d.ts +5 -0
  461. package/dist/shared/env.js +1 -1
  462. package/dist/shared/generated-context.js +2 -10
  463. package/dist/shared/inbox-entry-body.d.ts +22 -0
  464. package/dist/shared/inbox-entry-body.js +10 -0
  465. package/dist/{core/memory → shared}/inline-ref-guidance.d.ts +2 -2
  466. package/dist/shared/inline-ref-guidance.js +2 -0
  467. package/dist/types.d.ts +3 -1
  468. package/docs/cli/memory-and-preferences.md +12 -14
  469. package/docs/concepts/README.md +1 -1
  470. package/docs/concepts/lifecycle-and-wakes.md +1 -1
  471. package/docs/concepts/memory.md +15 -15
  472. package/docs/concepts/nodes-and-the-canvas.md +1 -1
  473. package/docs/concepts/profiles-kinds-and-modes.md +5 -5
  474. package/docs/concepts/scopes-and-trust.md +1 -1
  475. package/docs/concepts/why-a-daemon.md +1 -1
  476. package/docs/sdk/README.md +5 -6
  477. package/docs/sdk/errors.md +0 -13
  478. package/docs/sdk/guides/README.md +0 -1
  479. package/docs/sdk/nodes.md +0 -2
  480. package/docs/sdk/resources.md +0 -1
  481. package/package.json +2 -2
  482. package/packages/crouter-identity/package.json +1 -1
  483. package/runtime.lock.json +11 -11
  484. package/dist/api/dto/memory.d.ts +0 -171
  485. package/dist/api/dto/memory.js +0 -1
  486. package/dist/builtin-memory/crouter-sdk/guides/app-memory.md +0 -73
  487. package/dist/builtin-memory/crouter-sdk/memory.md +0 -87
  488. package/dist/commands/broker-permissions.d.ts +0 -2
  489. package/dist/commands/broker-permissions.js +0 -1
  490. package/dist/commands/memory/client.d.ts +0 -11
  491. package/dist/commands/memory/client.js +0 -1
  492. package/dist/commands/memory/delete.d.ts +0 -1
  493. package/dist/commands/memory/delete.js +0 -1
  494. package/dist/commands/memory/edit.d.ts +0 -1
  495. package/dist/commands/memory/edit.js +0 -21
  496. package/dist/commands/memory/find.d.ts +0 -1
  497. package/dist/commands/memory/find.js +0 -1
  498. package/dist/commands/memory/history.d.ts +0 -1
  499. package/dist/commands/memory/history.js +0 -5
  500. package/dist/commands/memory/lint.d.ts +0 -1
  501. package/dist/commands/memory/lint.js +0 -1
  502. package/dist/commands/memory/list.d.ts +0 -1
  503. package/dist/commands/memory/list.js +0 -1
  504. package/dist/commands/memory/move.d.ts +0 -1
  505. package/dist/commands/memory/move.js +0 -1
  506. package/dist/commands/memory/origin.d.ts +0 -1
  507. package/dist/commands/memory/origin.js +0 -1
  508. package/dist/commands/memory/read.d.ts +0 -1
  509. package/dist/commands/memory/read.js +0 -6
  510. package/dist/commands/memory/shared.d.ts +0 -22
  511. package/dist/commands/memory/shared.js +0 -1
  512. package/dist/commands/memory/write.d.ts +0 -1
  513. package/dist/commands/memory/write.js +0 -13
  514. package/dist/commands/memory.js +0 -1
  515. package/dist/commands/node-inspect-artifacts.d.ts +0 -1
  516. package/dist/commands/node-inspect-artifacts.js +0 -8
  517. package/dist/core/help/memory-extensions.d.ts +0 -3
  518. package/dist/core/help/memory-extensions.js +0 -2
  519. package/dist/core/memory/cli-selector.d.ts +0 -13
  520. package/dist/core/memory/cli-selector.js +0 -1
  521. package/dist/core/memory/doc-link-grammar.d.ts +0 -20
  522. package/dist/core/memory/doc-link-grammar.js +0 -2
  523. package/dist/core/memory/extensions.js +0 -1
  524. package/dist/core/memory/history.d.ts +0 -87
  525. package/dist/core/memory/history.js +0 -6
  526. package/dist/core/memory/identity.d.ts +0 -65
  527. package/dist/core/memory/identity.js +0 -1
  528. package/dist/core/memory/inline-ref-guidance.js +0 -2
  529. package/dist/core/memory/inline-ref-inventory.d.ts +0 -9
  530. package/dist/core/memory/inline-ref-inventory.js +0 -1
  531. package/dist/core/memory/lint.d.ts +0 -163
  532. package/dist/core/memory/lint.js +0 -2
  533. package/dist/core/memory/mutation-domain.d.ts +0 -113
  534. package/dist/core/memory/mutation-domain.js +0 -12
  535. package/dist/core/memory/mutations.d.ts +0 -74
  536. package/dist/core/memory/mutations.js +0 -1
  537. package/dist/core/memory/project-namespace.d.ts +0 -31
  538. package/dist/core/memory/project-namespace.js +0 -2
  539. package/dist/core/memory/repository-association.d.ts +0 -31
  540. package/dist/core/memory/repository-association.js +0 -1
  541. package/dist/core/memory/service.d.ts +0 -145
  542. package/dist/core/memory/service.js +0 -2
  543. package/dist/core/memory/tree.d.ts +0 -39
  544. package/dist/core/memory/tree.js +0 -1
  545. package/dist/core/memory-resolver.d.ts +0 -280
  546. package/dist/core/memory-resolver.js +0 -2
  547. package/dist/core/nested-stores.d.ts +0 -18
  548. package/dist/core/nested-stores.js +0 -1
  549. package/dist/core/runtime/memory.d.ts +0 -3
  550. package/dist/core/runtime/memory.js +0 -1
  551. package/dist/core/substrate/frontmatter-validation.d.ts +0 -11
  552. package/dist/core/substrate/frontmatter-validation.js +0 -1
  553. package/dist/core/substrate/gate.d.ts +0 -16
  554. package/dist/core/substrate/gate.js +0 -1
  555. package/dist/core/substrate/index.d.ts +0 -18
  556. package/dist/core/substrate/index.js +0 -1
  557. package/dist/core/substrate/injected-store.d.ts +0 -75
  558. package/dist/core/substrate/injected-store.js +0 -2
  559. package/dist/core/substrate/listings.d.ts +0 -28
  560. package/dist/core/substrate/listings.js +0 -1
  561. package/dist/core/substrate/memory-events.d.ts +0 -6
  562. package/dist/core/substrate/memory-events.js +0 -1
  563. package/dist/core/substrate/on-read-node.d.ts +0 -6
  564. package/dist/core/substrate/on-read-node.js +0 -1
  565. package/dist/core/substrate/on-read.d.ts +0 -101
  566. package/dist/core/substrate/on-read.js +0 -9
  567. package/dist/core/substrate/plan.d.ts +0 -94
  568. package/dist/core/substrate/plan.js +0 -1
  569. package/dist/core/substrate/render-node.d.ts +0 -12
  570. package/dist/core/substrate/render-node.js +0 -1
  571. package/dist/core/substrate/render.d.ts +0 -41
  572. package/dist/core/substrate/render.js +0 -65
  573. package/dist/core/substrate/session-cache.d.ts +0 -27
  574. package/dist/core/substrate/session-cache.js +0 -1
  575. package/dist/core/substrate/surface-match.d.ts +0 -73
  576. package/dist/core/substrate/surface-match.js +0 -1
  577. package/dist/daemon/api/handlers/memory.js +0 -5
  578. package/dist/migrations/001-surfaces-frontmatter.d.ts +0 -2
  579. package/dist/migrations/001-surfaces-frontmatter.js +0 -1
  580. package/dist/migrations/002-profile-project-memory.d.ts +0 -2
  581. package/dist/migrations/002-profile-project-memory.js +0 -1
  582. package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +0 -26
  583. package/dist/migrations/003-repository-root-memory-identity/front-door.js +0 -11
  584. package/dist/migrations/003-repository-root-memory-identity/index.d.ts +0 -2
  585. package/dist/migrations/003-repository-root-memory-identity/index.js +0 -5
  586. package/dist/migrations/003-repository-root-memory-identity/references.d.ts +0 -95
  587. package/dist/migrations/003-repository-root-memory-identity/references.js +0 -5
  588. package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +0 -39
  589. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +0 -3
  590. package/dist/migrations/convergent.d.ts +0 -43
  591. package/dist/migrations/convergent.js +0 -2
  592. package/dist/migrations/corpus.d.ts +0 -75
  593. package/dist/migrations/corpus.js +0 -3
  594. package/dist/migrations/frontmatter-splice.d.ts +0 -15
  595. package/dist/migrations/frontmatter-splice.js +0 -8
  596. package/dist/migrations/profile-manifests.d.ts +0 -30
  597. package/dist/migrations/profile-manifests.js +0 -2
  598. package/dist/migrations/registry.d.ts +0 -7
  599. package/dist/migrations/registry.js +0 -1
  600. package/dist/migrations/runner.d.ts +0 -43
  601. package/dist/migrations/runner.js +0 -1
  602. package/dist/migrations/types.d.ts +0 -211
  603. package/dist/shared/birth-announcement.d.ts +0 -12
  604. package/dist/shared/birth-announcement.js +0 -1
  605. package/docs/sdk/guides/app-memory.md +0 -22
  606. package/docs/sdk/memory.md +0 -85
  607. /package/dist/{migrations/types.js → api/dto/delivery.js} +0 -0
  608. /package/dist/{core/memory → shared}/inline-ref-grammar.d.ts +0 -0
  609. /package/dist/{core/memory → shared}/inline-ref-grammar.js +0 -0
@@ -1 +1 @@
1
- var P=Object.defineProperty;var r=(t,n)=>P(t,"name",{value:n,configurable:!0});import{join as e}from"node:path";import{mkdirSync as c}from"node:fs";import{appSpace as x,runtimeRoot as j,socketDir as m}from"../layout.js";import{envGrantee as k,envNodeId as R}from"../../shared/env.js";import{withDirBeneath as h}from"../spaces/open-beneath.js";function i(){return j()}r(i,"crtrHome");function A(){return e(i(),"canvas.db")}r(A,"canvasDbPath");function B(){return e(i(),"on-disk-migration.lock")}r(B,"onDiskMigrationLockPath");function L(){return e(i(),"on-disk-migrations.json")}r(L,"onDiskMigrationMarkerPath");function O(t){return e(u(t),"view.sock")}r(O,"viewSocketPath");function D(){return e(i(),"nodes")}r(D,"nodesRoot");function w(){return e(i(),"reviews")}r(w,"reviewsRoot");function l(t){return p(t),e(w(),t)}r(l,"reviewDir");function $(t){return e(l(t),"result.json")}r($,"reviewResultPath");function H(t){c(l(t),{recursive:!0,mode:448})}r(H,"ensureReviewDir");function X(){return e(m(),"api.sock")}r(X,"apiSocketPath");function F(){return e(i(),"session-list-cache.json")}r(F,"sessionListCachePath");const b=128;function g(t){return typeof t=="string"&&t!==""&&t!=="."&&t!==".."&&!/[\\/\0]/u.test(t)&&Buffer.byteLength(t,"utf8")<=b}r(g,"isSafeNodeId");function p(t){if(!g(t))throw new TypeError("node_id must be a non-empty path segment of at most 128 UTF-8 bytes")}r(p,"assertSafeNodeId");function a(t){return p(t),e(D(),t)}r(a,"nodeRecordDir");const s=a;function f(t,n){p(t);const o=n??(R()===t?k():void 0);if(!o)throw new Error(`node ${t} has no app assignment`);return e(x(o).nodes,t)}r(f,"nodeAgentDir");function u(t){return p(t),process.platform==="linux"?e(m(),"nodes",t):e(a(t),"run")}r(u,"nodeRunDir");function N(t,n){return e(f(t,n),"context")}r(N,"contextDir");function G(t,n,o){return t.replaceAll("$CRTR_CONTEXT_DIR",N(n,o)).replaceAll("$CRTR_NODE_ID",n)}r(G,"interpolateNodePaths");function _(t){return e(a(t),"job")}r(_,"jobDir");function S(t){return e(u(t),"job")}r(S,"nodeRunJobDir");function J(t,n){return e(f(t,n),"reports")}r(J,"reportsDir");function U(t){return e(s(t),"messages")}r(U,"messagesDir");function Y(t){return e(s(t),"meta.json")}r(Y,"nodeMetaPath");function q(t){return e(s(t),"inbox.jsonl")}r(q,"inboxPath");function z(t){return e(u(t),"situational-context.md")}r(z,"situationalContextPath");function K(t){return e(s(t),"passive.jsonl")}r(K,"passivePath");function Q(t){return e(s(t),"transcript.jsonl")}r(Q,"transcriptPath");function V(t){return e(s(t),"session.ptr")}r(V,"sessionPtrPath");function W(t){return e(u(t),"injected-docs.json")}r(W,"injectedDocsPath");function Z(t,n){const o=f(t,n);c(a(t),{recursive:!0}),c(_(t),{recursive:!0});for(const v of["context","reports","attachments","worktree"])h(x(n).nodes,e(o,v),()=>{},!0);h(u(t),S(t),()=>{},!0)}r(Z,"ensureNodeDirs");function I(){c(D(),{recursive:!0})}r(I,"ensureHome");export{X as apiSocketPath,A as canvasDbPath,N as contextDir,i as crtrHome,I as ensureHome,Z as ensureNodeDirs,H as ensureReviewDir,q as inboxPath,W as injectedDocsPath,G as interpolateNodePaths,g as isSafeNodeId,_ as jobDir,U as messagesDir,f as nodeAgentDir,s as nodeDir,Y as nodeMetaPath,a as nodeRecordDir,u as nodeRunDir,S as nodeRunJobDir,D as nodesRoot,B as onDiskMigrationLockPath,L as onDiskMigrationMarkerPath,K as passivePath,J as reportsDir,l as reviewDir,$ as reviewResultPath,w as reviewsRoot,F as sessionListCachePath,V as sessionPtrPath,z as situationalContextPath,Q as transcriptPath,O as viewSocketPath};
1
+ var P=Object.defineProperty;var r=(t,n)=>P(t,"name",{value:n,configurable:!0});import{join as e}from"node:path";import{mkdirSync as s}from"node:fs";import{appSpace as f,runtimeRoot as k,socketDir as x}from"../layout.js";import{envGrantee as R,envNodeId as w}from"../../shared/env.js";import{withDirBeneath as m}from"../spaces/open-beneath.js";function i(){return k()}r(i,"crtrHome");function d(){return e(i(),"canvas.db")}r(d,"canvasDbPath");function B(){return e(i(),"on-disk-migration.lock")}r(B,"onDiskMigrationLockPath");function L(){return e(i(),"on-disk-migrations.json")}r(L,"onDiskMigrationMarkerPath");function O(t){return e(p(t),"view.sock")}r(O,"viewSocketPath");function h(){return e(i(),"nodes")}r(h,"nodesRoot");function b(){return e(i(),"reviews")}r(b,"reviewsRoot");function D(t){return c(t),e(b(),t)}r(D,"reviewDir");function $(t){return e(D(t),"result.json")}r($,"reviewResultPath");function H(t){s(D(t),{recursive:!0,mode:448})}r(H,"ensureReviewDir");function X(){return e(x(),"api.sock")}r(X,"apiSocketPath");function F(){return e(i(),"session-list-cache.json")}r(F,"sessionListCachePath");const g=128;function j(t){return typeof t=="string"&&t!==""&&t!=="."&&t!==".."&&!/[\\/\0]/u.test(t)&&Buffer.byteLength(t,"utf8")<=g}r(j,"isSafeNodeId");function c(t){if(!j(t))throw new TypeError("node_id must be a non-empty path segment of at most 128 UTF-8 bytes")}r(c,"assertSafeNodeId");function a(t){return c(t),e(h(),t)}r(a,"nodeRecordDir");const u=a;function l(t,n){c(t);const o=n??(w()===t?R():void 0);if(!o)throw new Error(`node ${t} has no app assignment`);return e(f(o).nodes,t)}r(l,"nodeAgentDir");function p(t){return c(t),process.platform==="linux"?e(x(),"nodes",t):e(a(t),"run")}r(p,"nodeRunDir");function N(t,n){return e(l(t,n),"context")}r(N,"contextDir");function G(t,n,o){return t.replaceAll("$CRTR_CONTEXT_DIR",N(n,o)).replaceAll("$CRTR_NODE_ID",n)}r(G,"interpolateNodePaths");function _(t){return e(a(t),"job")}r(_,"jobDir");function S(t){return e(p(t),"job")}r(S,"nodeRunJobDir");function J(t){return e(u(t),"messages")}r(J,"messagesDir");function U(t){return e(u(t),"meta.json")}r(U,"nodeMetaPath");function Y(t){return e(u(t),"inbox.jsonl")}r(Y,"inboxPath");function q(t){return e(p(t),"situational-context.md")}r(q,"situationalContextPath");function z(t){return e(u(t),"passive.jsonl")}r(z,"passivePath");function K(t){return e(u(t),"transcript.jsonl")}r(K,"transcriptPath");function Q(t){return e(u(t),"session.ptr")}r(Q,"sessionPtrPath");function V(t,n){const o=l(t,n);s(a(t),{recursive:!0}),s(_(t),{recursive:!0});for(const v of["context","reports","attachments","worktree"])m(f(n).nodes,e(o,v),()=>{},!0);m(p(t),S(t),()=>{},!0)}r(V,"ensureNodeDirs");function W(){s(h(),{recursive:!0})}r(W,"ensureHome");export{X as apiSocketPath,d as canvasDbPath,N as contextDir,i as crtrHome,W as ensureHome,V as ensureNodeDirs,H as ensureReviewDir,Y as inboxPath,G as interpolateNodePaths,j as isSafeNodeId,_ as jobDir,J as messagesDir,l as nodeAgentDir,u as nodeDir,U as nodeMetaPath,a as nodeRecordDir,p as nodeRunDir,S as nodeRunJobDir,h as nodesRoot,B as onDiskMigrationLockPath,L as onDiskMigrationMarkerPath,z as passivePath,D as reviewDir,$ as reviewResultPath,b as reviewsRoot,F as sessionListCachePath,Q as sessionPtrPath,q as situationalContextPath,K as transcriptPath,O as viewSocketPath};
@@ -27,7 +27,6 @@ export interface RemoteShowResponse {
27
27
  pending_crons: number;
28
28
  paths: {
29
29
  context_dir: string;
30
- reports_dir: string;
31
30
  session_file?: string | null;
32
31
  };
33
32
  follow_up: string;
@@ -1 +1 @@
1
- var y=Object.defineProperty;var u=(s,e)=>y(s,"name",{value:e,configurable:!0});import{createRemoteExec as h}from"./remote-transport.js";const l=1e3;function r(s){return typeof s=="object"&&s!==null&&!Array.isArray(s)}u(r,"isPlainObject");function w(s){if(!r(s))return!1;const e=s.node;if(!r(e)||typeof e.node_id!="string"||!Array.isArray(s.reports)||!Array.isArray(s.managers))return!1;const t=s.artifacts;if(!r(t)||typeof t.report!="number"||typeof t.doc!="number"||typeof t.roadmap!="number"||typeof s.pending_crons!="number")return!1;const o=s.paths;if(!r(o)||typeof o.context_dir!="string"||typeof o.reports_dir!="string"||"session_file"in o&&o.session_file!==null&&typeof o.session_file!="string"||typeof s.follow_up!="string")return!1;const n=s.fault;if(n!=null){if(!r(n)||typeof n.link!="string"||typeof n.kind!="string"||typeof n.since!="string")return!1;const i=n.retry;if(!r(i)||typeof i.disposition!="string")return!1}return!0}u(w,"isValidShowResponse");function p(s){return r(s)&&typeof s.node_id=="string"&&typeof s.name=="string"&&typeof s.kind=="string"&&typeof s.status=="string"&&typeof s.active=="boolean"}u(p,"isValidNeighborEntry");function g(s){return r(s)&&typeof s.from_id=="string"&&typeof s.to_id=="string"&&typeof s.active=="boolean"&&typeof s.created=="string"}u(g,"isValidRosterEdge");function _(s){return r(s)?typeof s.node_id=="string"&&typeof s.name=="string"&&typeof s.kind=="string"&&typeof s.mode=="string"&&typeof s.lifecycle=="string"&&typeof s.status=="string"&&typeof s.cwd=="string"&&typeof s.created=="string":!1}u(_,"isValidNodeRow");class v{static{u(this,"RemoteCanvasSource")}previewEndpoint;relayToken;exec;nodeCache=new Map;rosterCache=new Map;topologyCache=null;viewCache=new Map;constructor(e,t){this.previewEndpoint=e,this.relayToken=t,this.exec=h(e,t)}async execJson(e){let t;try{t=await this.exec("crtr",["--json",...e])}catch{return null}if(!t.ok||t.exitCode!==void 0&&t.exitCode!==0)return null;try{return JSON.parse(t.stdout.trim())}catch{return null}}async fetchShow(e){const t=this.nodeCache.get(e);if(t&&Date.now()-t.at<l)return t.value;const o=await this.execJson(["node","inspect","show",e]),n=w(o)?{...o,fault:o.fault??null,reports:o.reports.filter(p),managers:o.managers.filter(p)}:null;return this.nodeCache.set(e,{value:n,at:Date.now()}),n}topology(){if(this.topologyCache!==null&&Date.now()-this.topologyCache.at<l)return this.topologyCache.value;const e=this.loadTopology();return this.topologyCache={value:e,at:Date.now()},e}async loadTopology(){const e=await this.exec("crtr",["--json","canvas","roster"]);if(!e.ok||e.exitCode!==void 0&&e.exitCode!==0)throw new Error("remote canvas topology is unavailable");let t;try{t=JSON.parse(e.stdout.trim())}catch{throw new Error("remote canvas topology is invalid")}if(!r(t)||!Array.isArray(t.edges)||!t.edges.every(g))throw new Error("remote canvas topology is invalid");const o=t.edges,n={subscriptions:new Map,subscribers:new Map};for(const i of o){const a={node_id:i.to_id,active:i.active,created:i.created},c={node_id:i.from_id,active:i.active,created:i.created},f=n.subscriptions.get(i.from_id);f===void 0?n.subscriptions.set(i.from_id,[a]):f.push(a);const d=n.subscribers.get(i.to_id);d===void 0?n.subscribers.set(i.to_id,[c]):d.push(c)}return n}async rawShow(e){return this.fetchShow(e)}async getNode(e){return(await this.fetchShow(e))?.node??null}async getRow(e){const t=(await this.fetchShow(e))?.node;return t?{node_id:t.node_id,name:t.name,kind:t.kind,mode:t.mode,lifecycle:t.lifecycle,status:t.status,cwd:t.cwd,host_kind:t.host_kind??null,profile_id:t.profile_id??null,scopes:t.scopes??null,parent:t.parent??null,created:t.created,intent:t.intent??null,waiting_for:t.waiting_for??null,frozen_at:t.frozen_at??null,terminal_reason:t.terminal_reason??null,pi_pid:t.pi_pid??null,pi_pid_identity:t.pi_pid_identity??null,window:t.window??null,tmux_session:t.tmux_session??null,pane:t.pane??null,fault:t.fault??null,streaming:t.streaming===!0}:null}async listNodes(e){const t=JSON.stringify(e?.status??null),o=this.rosterCache.get(t);if(o&&Date.now()-o.at<l)return o.value;const n=["node","inspect","list"];e?.status&&n.push("--status",(Array.isArray(e.status)?e.status:[e.status]).join(","));const i=await this.execJson(n),c=(r(i)&&Array.isArray(i.nodes)?i.nodes:[]).filter(_);return this.rosterCache.set(t,{value:c,at:Date.now()}),c}async subscriptionsOf(e){return(await this.topology()).subscriptions.get(e)??[]}async subscribersOf(e){return(await this.topology()).subscribers.get(e)??[]}async view(e){const t=this.viewCache.get(e);if(t&&Date.now()-t.at<l)return t.value;const o=new Set([e]),n=[],i=(await this.subscriptionsOf(e)).map(a=>a.node_id);for(;i.length>0;){const a=i.shift();if(!o.has(a)){o.add(a),n.push(a);for(const c of await this.subscriptionsOf(a))o.has(c.node_id)||i.push(c.node_id)}}return this.viewCache.set(e,{value:n,at:Date.now()}),n}async ticketCountsForNodes(e){if(e.length===0)return{};const t=await this.execJson(["canvas","attention","map","--nodes",e.join(",")]);return r(t)&&r(t.counts)?t.counts:{}}async ticketCountsForView(e){const t=await this.execJson(["canvas","attention","map","--view",e]);return r(t)&&r(t.counts)?t.counts:{}}async hasActiveLiveSubscription(e){const t=(await this.subscriptionsOf(e)).filter(o=>o.active);for(const o of t){const n=await this.getRow(o.node_id);if(n&&(n.status==="active"||n.status==="idle"))return!0}return!1}}export{v as RemoteCanvasSource};
1
+ var y=Object.defineProperty;var u=(s,e)=>y(s,"name",{value:e,configurable:!0});import{createRemoteExec as h}from"./remote-transport.js";const l=1e3;function r(s){return typeof s=="object"&&s!==null&&!Array.isArray(s)}u(r,"isPlainObject");function w(s){if(!r(s))return!1;const e=s.node;if(!r(e)||typeof e.node_id!="string"||!Array.isArray(s.reports)||!Array.isArray(s.managers))return!1;const t=s.artifacts;if(!r(t)||typeof t.report!="number"||typeof t.doc!="number"||typeof t.roadmap!="number"||typeof s.pending_crons!="number")return!1;const o=s.paths;if(!r(o)||typeof o.context_dir!="string"||"session_file"in o&&o.session_file!==null&&typeof o.session_file!="string"||typeof s.follow_up!="string")return!1;const n=s.fault;if(n!=null){if(!r(n)||typeof n.link!="string"||typeof n.kind!="string"||typeof n.since!="string")return!1;const i=n.retry;if(!r(i)||typeof i.disposition!="string")return!1}return!0}u(w,"isValidShowResponse");function p(s){return r(s)&&typeof s.node_id=="string"&&typeof s.name=="string"&&typeof s.kind=="string"&&typeof s.status=="string"&&typeof s.active=="boolean"}u(p,"isValidNeighborEntry");function g(s){return r(s)&&typeof s.from_id=="string"&&typeof s.to_id=="string"&&typeof s.active=="boolean"&&typeof s.created=="string"}u(g,"isValidRosterEdge");function _(s){return r(s)?typeof s.node_id=="string"&&typeof s.name=="string"&&typeof s.kind=="string"&&typeof s.mode=="string"&&typeof s.lifecycle=="string"&&typeof s.status=="string"&&typeof s.cwd=="string"&&typeof s.created=="string":!1}u(_,"isValidNodeRow");class v{static{u(this,"RemoteCanvasSource")}previewEndpoint;relayToken;exec;nodeCache=new Map;rosterCache=new Map;topologyCache=null;viewCache=new Map;constructor(e,t){this.previewEndpoint=e,this.relayToken=t,this.exec=h(e,t)}async execJson(e){let t;try{t=await this.exec("crtr",["--json",...e])}catch{return null}if(!t.ok||t.exitCode!==void 0&&t.exitCode!==0)return null;try{return JSON.parse(t.stdout.trim())}catch{return null}}async fetchShow(e){const t=this.nodeCache.get(e);if(t&&Date.now()-t.at<l)return t.value;const o=await this.execJson(["node","inspect","show",e]),n=w(o)?{...o,fault:o.fault??null,reports:o.reports.filter(p),managers:o.managers.filter(p)}:null;return this.nodeCache.set(e,{value:n,at:Date.now()}),n}topology(){if(this.topologyCache!==null&&Date.now()-this.topologyCache.at<l)return this.topologyCache.value;const e=this.loadTopology();return this.topologyCache={value:e,at:Date.now()},e}async loadTopology(){const e=await this.exec("crtr",["--json","canvas","roster"]);if(!e.ok||e.exitCode!==void 0&&e.exitCode!==0)throw new Error("remote canvas topology is unavailable");let t;try{t=JSON.parse(e.stdout.trim())}catch{throw new Error("remote canvas topology is invalid")}if(!r(t)||!Array.isArray(t.edges)||!t.edges.every(g))throw new Error("remote canvas topology is invalid");const o=t.edges,n={subscriptions:new Map,subscribers:new Map};for(const i of o){const a={node_id:i.to_id,active:i.active,created:i.created},c={node_id:i.from_id,active:i.active,created:i.created},f=n.subscriptions.get(i.from_id);f===void 0?n.subscriptions.set(i.from_id,[a]):f.push(a);const d=n.subscribers.get(i.to_id);d===void 0?n.subscribers.set(i.to_id,[c]):d.push(c)}return n}async rawShow(e){return this.fetchShow(e)}async getNode(e){return(await this.fetchShow(e))?.node??null}async getRow(e){const t=(await this.fetchShow(e))?.node;return t?{node_id:t.node_id,name:t.name,kind:t.kind,mode:t.mode,lifecycle:t.lifecycle,status:t.status,cwd:t.cwd,host_kind:t.host_kind??null,profile_id:t.profile_id??null,scopes:t.scopes??null,parent:t.parent??null,created:t.created,intent:t.intent??null,waiting_for:t.waiting_for??null,frozen_at:t.frozen_at??null,terminal_reason:t.terminal_reason??null,pi_pid:t.pi_pid??null,pi_pid_identity:t.pi_pid_identity??null,window:t.window??null,tmux_session:t.tmux_session??null,pane:t.pane??null,fault:t.fault??null,streaming:t.streaming===!0}:null}async listNodes(e){const t=JSON.stringify(e?.status??null),o=this.rosterCache.get(t);if(o&&Date.now()-o.at<l)return o.value;const n=["node","inspect","list"];e?.status&&n.push("--status",(Array.isArray(e.status)?e.status:[e.status]).join(","));const i=await this.execJson(n),c=(r(i)&&Array.isArray(i.nodes)?i.nodes:[]).filter(_);return this.rosterCache.set(t,{value:c,at:Date.now()}),c}async subscriptionsOf(e){return(await this.topology()).subscriptions.get(e)??[]}async subscribersOf(e){return(await this.topology()).subscribers.get(e)??[]}async view(e){const t=this.viewCache.get(e);if(t&&Date.now()-t.at<l)return t.value;const o=new Set([e]),n=[],i=(await this.subscriptionsOf(e)).map(a=>a.node_id);for(;i.length>0;){const a=i.shift();if(!o.has(a)){o.add(a),n.push(a);for(const c of await this.subscriptionsOf(a))o.has(c.node_id)||i.push(c.node_id)}}return this.viewCache.set(e,{value:n,at:Date.now()}),n}async ticketCountsForNodes(e){if(e.length===0)return{};const t=await this.execJson(["canvas","attention","map","--nodes",e.join(",")]);return r(t)&&r(t.counts)?t.counts:{}}async ticketCountsForView(e){const t=await this.execJson(["canvas","attention","map","--view",e]);return r(t)&&r(t.counts)?t.counts:{}}async hasActiveLiveSubscription(e){const t=(await this.subscriptionsOf(e)).filter(o=>o.active);for(const o of t){const n=await this.getRow(o.node_id);if(n&&(n.status==="active"||n.status==="idle"))return!0}return!1}}export{v as RemoteCanvasSource};
@@ -111,19 +111,22 @@ export interface DashboardRow {
111
111
  export declare function readGoalText(contextPath: string): string | undefined;
112
112
  /** The newest pushed report, reduced to what a preview panel can use. */
113
113
  export interface NodeReportPreview {
114
- /** final | update | urgent (frontmatter, else the filename suffix). */
114
+ /** final | update | urgent. */
115
115
  kind: string;
116
- /** ISO 8601 push time (frontmatter, else the filename stamp). */
116
+ /** ISO 8601 push time. */
117
117
  ts: string;
118
118
  /** The report's first markdown heading, or its first non-empty line. */
119
119
  heading: string;
120
120
  /** The body after that heading, whitespace-normalized + capped. */
121
121
  body: string;
122
122
  }
123
- /** The node's newest report, read straight off disk. Report filenames lead with a
124
- * compact timestamp, so the lexicographic maximum is the latest one — no stat of
125
- * the whole directory. Never throws; undefined when the node pushed nothing. */
126
- export declare function readNewestReport(reportPath: string): NodeReportPreview | undefined;
123
+ /** The node's newest report document, reduced to a preview. Never throws;
124
+ * undefined when the node pushed nothing. */
125
+ export declare function reportPreview(report: {
126
+ tier: string;
127
+ created: string;
128
+ body: string;
129
+ } | null | undefined): NodeReportPreview | undefined;
127
130
  interface SessionParts {
128
131
  prompts?: string;
129
132
  lastAssistant?: string;
@@ -1,7 +1,7 @@
1
- var H=Object.defineProperty;var u=(t,e)=>H(t,"name",{value:e,configurable:!0});import{conversationIdFromPath as v,conversationStore as A,ConversationNotFoundError as C}from"../conversation-store/index.js";import{dirname as b,join as N}from"node:path";import{readdirBeneath as J,readFileBeneath as F,readTextBeneathIfExists as U}from"../spaces/open-beneath.js";import{RemoteCanvasSource as y}from"./remote-canvas-source.js";import{fullName as $}from"./labels.js";import{nodeRunDir as Z,nodeRunJobDir as q,contextDir as K,reportsDir as Q}from"./paths.js";import{readNodeRecap as X}from"./node-recap.js";import{parseFrontmatterGeneric as I}from"../frontmatter.js";import{isFrozenRow as P,resolveNodeVisual as L,faultSummary as E}from"./status-glyph.js";import{parseCard as j}from"../../shared/generated-context.js";function w(t){return t===void 0||t===0?"0k":`${Math.floor(t/1e3)}k`}u(w,"fmtCtx");function tt(t,e,n,i,r,s){if(t===void 0)return`${n}${i}? <missing meta: ${e}>`;const a=t.fault??null,o=L(t.status,{hanging:a,frozen:P(t)}).glyph,c=r?"0k":w(t.telemetry_tokens_in??void 0),l=s[e]??0,h=l>0?` \u2691${l}`:"",m=a!==null?` \xB7 ${E(a)}`:"";return`${n}${i}${o} ${$(t)} [${t.kind}/${t.mode}] ctx ${c}${h}${m}`}u(tt,"nodeLineFromSource");async function M(t,e,n,i,r,s,a,o,c){if(s.has(n))return;s.add(n);const l=r?"\u2514\u2500 ":"\u251C\u2500 ";a.push(tt(e.get(n),n,i,l,o,c));const h=i+(r?" ":"\u2502 ");let m;try{m=await t.subscriptionsOf(n)}catch(f){a.push(`${h}\u26A0 children unavailable: ${f instanceof Error?f.message:String(f)}`);return}for(let f=0;f<m.length;f++){const d=m[f],x=f===m.length-1;if(s.has(d.node_id)){const S=x?"\u2514\u2500 ":"\u251C\u2500 ";a.push(`${h}${S}\u21BA <cycle: ${d.node_id}>`);continue}await M(t,e,d.node_id,h,x,s,a,o,c)}}u(M,"walkTreeFromSource");async function et(t,e,n,i,r){const s=t instanceof y,a=new Map((n??await t.listNodes()).map(p=>[p.node_id,p])),o=a.get(e);if(o===void 0)return`? <missing node: ${e}>`;let c=i,l=r??null;if(c===void 0)try{c=await t.ticketCountsForView(e)}catch(p){c={},l=p instanceof Error?p.message:String(p)}const h=s?"0k":w(o.telemetry_tokens_in??void 0),m=c[e]??0,f=m>0?` \u2691${m}`:"",d=o.fault??null,x=L(o.status,{hanging:d,frozen:P(o)}).glyph,S=d!==null?` \xB7 ${E(d)}`:"",g=[];g.push(`${x} ${$(o)} [${o.kind}/${o.mode}] ctx ${h}${f}${S}`);const G=new Set([e]);let _;try{_=await t.subscriptionsOf(e)}catch(p){g.push(`\u26A0 children unavailable: ${p instanceof Error?p.message:String(p)}`),_=[]}for(let p=0;p<_.length;p++){const Y=_[p],W=p===_.length-1;await M(t,a,Y.node_id,"",W,G,g,s,c)}return l!==null&&g.push(`Tickets: unavailable (${l}).`),g.join(`
2
- `)}u(et,"renderTreeFromSource");async function Tt(t,e,n,i){const r=e??await t.listNodes();if(r.length===0)return"(canvas is empty)";const s=r.filter(o=>o.parent===null&&(o.status==="active"||o.status==="idle"));if(s.length===0)return"(no live roots)";const a=[];for(const o of s)a.push(await et(t,o.node_id,r,n,i));return a.join(`
1
+ var Y=Object.defineProperty;var u=(t,e)=>Y(t,"name",{value:e,configurable:!0});import{conversationIdFromPath as R,conversationStore as v,ConversationNotFoundError as T}from"../conversation-store/index.js";import{dirname as H,join as A}from"node:path";import{readFileBeneath as J,readTextBeneathIfExists as W}from"../spaces/open-beneath.js";import{RemoteCanvasSource as y}from"./remote-canvas-source.js";import{fullName as k}from"./labels.js";import{nodeRunDir as U,nodeRunJobDir as q,contextDir as K}from"./paths.js";import{readNodeRecap as Q}from"./node-recap.js";import{isFrozenRow as C,resolveNodeVisual as P,faultSummary as L}from"./status-glyph.js";import{parseCard as E}from"../../shared/generated-context.js";function F(t){return t===void 0||t===0?"0k":`${Math.floor(t/1e3)}k`}u(F,"fmtCtx");function X(t,e,n,i,s,r){if(t===void 0)return`${n}${i}? <missing meta: ${e}>`;const a=t.fault??null,o=P(t.status,{hanging:a,frozen:C(t)}).glyph,c=s?"0k":F(t.telemetry_tokens_in??void 0),l=r[e]??0,m=l>0?` \u2691${l}`:"",p=a!==null?` \xB7 ${L(a)}`:"";return`${n}${i}${o} ${k(t)} [${t.kind}/${t.mode}] ctx ${c}${m}${p}`}u(X,"nodeLineFromSource");async function j(t,e,n,i,s,r,a,o,c){if(r.has(n))return;r.add(n);const l=s?"\u2514\u2500 ":"\u251C\u2500 ";a.push(X(e.get(n),n,i,l,o,c));const m=i+(s?" ":"\u2502 ");let p;try{p=await t.subscriptionsOf(n)}catch(d){a.push(`${m}\u26A0 children unavailable: ${d instanceof Error?d.message:String(d)}`);return}for(let d=0;d<p.length;d++){const h=p[d],x=d===p.length-1;if(r.has(h.node_id)){const $=x?"\u2514\u2500 ":"\u251C\u2500 ";a.push(`${m}${$}\u21BA <cycle: ${h.node_id}>`);continue}await j(t,e,h.node_id,m,x,r,a,o,c)}}u(j,"walkTreeFromSource");async function Z(t,e,n,i,s){const r=t instanceof y,a=new Map((n??await t.listNodes()).map(f=>[f.node_id,f])),o=a.get(e);if(o===void 0)return`? <missing node: ${e}>`;let c=i,l=s??null;if(c===void 0)try{c=await t.ticketCountsForView(e)}catch(f){c={},l=f instanceof Error?f.message:String(f)}const m=r?"0k":F(o.telemetry_tokens_in??void 0),p=c[e]??0,d=p>0?` \u2691${p}`:"",h=o.fault??null,x=P(o.status,{hanging:h,frozen:C(o)}).glyph,$=h!==null?` \xB7 ${L(h)}`:"",g=[];g.push(`${x} ${k(o)} [${o.kind}/${o.mode}] ctx ${m}${d}${$}`);const D=new Set([e]);let _;try{_=await t.subscriptionsOf(e)}catch(f){g.push(`\u26A0 children unavailable: ${f instanceof Error?f.message:String(f)}`),_=[]}for(let f=0;f<_.length;f++){const V=_[f],G=f===_.length-1;await j(t,a,V.node_id,"",G,D,g,r,c)}return l!==null&&g.push(`Tickets: unavailable (${l}).`),g.join(`
2
+ `)}u(Z,"renderTreeFromSource");async function kt(t,e,n,i){const s=e??await t.listNodes();if(s.length===0)return"(canvas is empty)";const r=s.filter(o=>o.parent===null&&(o.status==="active"||o.status==="idle"));if(r.length===0)return"(no live roots)";const a=[];for(const o of r)a.push(await Z(t,o.node_id,s,n,i));return a.join(`
3
3
 
4
- `)}u(Tt,"renderForestFromSource");const O=4096;function nt(t){try{const e=U(b(t),N(t,"initial-prompt.md"))?.trim()??"";return e===""?void 0:e.length>O?e.slice(0,O):e}catch{return}}u(nt,"readGoalText");const z=1024;function it(t){const e=t.match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\d{3})?$/);if(e!==null)return`${e[1]}-${e[2]}-${e[3]}T${e[4]}:${e[5]}:${e[6]}.${e[7]??"000"}Z`}u(it,"reportStampToIso");function rt(t){let e;try{for(const f of J(b(t),t)){const d=f.name;!f.isFile()||!d.endsWith(".md")||(e===void 0||d>e)&&(e=d)}}catch{return}if(e===void 0)return;let n;try{n=F(b(t),N(t,e)).toString("utf8")}catch{return}const{data:i,body:r}=I(n),s=e.replace(/\.md$/,""),a=typeof i?.kind=="string"?i.kind:s.split("-").pop()??"report",o=typeof i?.ts=="string"?i.ts:it(s.split("-")[0]??"")??"",c=r.split(`
5
- `);let l="",h=r;for(let f=0;f<c.length;f++){const d=(c[f]??"").trim();if(d!==""){l=d.startsWith("#")?d.replace(/^#+\s*/,"").trim():d,h=c.slice(f+1).join(`
6
- `);break}}const m=h.replace(/\s+/g," ").trim();return{kind:a,ts:o,heading:l,body:m.length>z?m.slice(0,z):m}}u(rt,"readNewestReport");const st=1<<20,ot=1<<20,at=4<<20;function B(t,e,n){if(t==null||t==="")return null;const i=v(t);if(i===null)return null;try{const{entries:r,tail:s}=A().read(i,{head:e,tail:n});return{head:r,tail:s??r}}catch(r){if(r instanceof C)return null;throw r}}u(B,"readSessionWindow");const T=8192,k=2048;function ct(t){const e=B(t,st,ot);if(e===null)return{};const n=[];let i=0;for(const a of e.head){if(a.type!=="message"||a.message.role!=="user")continue;const o=R(a.message.content);if(o===""||j({role:"user",content:o})!==null)continue;const c=o.length>k?o.slice(0,k):o;if(n.push(c),i+=c.length+1,i>=T)break}let r;if(n.length>0){const a=n.join(`
7
- `);r=a.length>T?a.slice(0,T):a}let s;for(let a=e.tail.length-1;a>=0;a--){const o=e.tail[a];if(o.type!=="message"||o.message.role!=="assistant")continue;const c=R(o.message.content);if(c!==""){s=c.length>k?c.slice(0,k):c;break}}return{prompts:r,lastAssistant:s}}u(ct,"readSessionParts");const D=120,V=4096;function lt(t){const e=B(t,0,at);if(e===null)return[];const n=[];for(const i of e.tail){if(i.type!=="message")continue;const r=i.message.role;if(r!=="user"&&r!=="assistant")continue;const s=R(i.message.content);s!==""&&j({role:r,content:s})===null&&n.push({role:r,text:s.length>V?s.slice(0,V):s})}return n.length>D?n.slice(n.length-D):n}u(lt,"readTranscript");function Rt(t){if(t==null||t==="")return!1;const e=v(t);if(e===null)return!1;let n;try{n=A().read(e).entries}catch(i){if(i instanceof C)return!1;throw i}for(const i of n)if(!(i.type!=="message"||i.message.role!=="assistant")&&ut(i.message.content))return!0;return!1}u(Rt,"nodeHasAssistantMessage");function ut(t){if(typeof t=="string")return t.trim()!=="";if(!Array.isArray(t))return!1;for(const e of t){if(e===null||typeof e!="object")continue;const n=e,i=(n.type??"").toLowerCase();if(i==="text"){if(typeof n.text=="string"&&n.text.trim()!=="")return!0}else if(i==="thinking"){if(typeof n.thinking=="string"&&n.thinking.trim()!=="")return!0}else return!0}return!1}u(ut,"assistantContentIsSubstantive");function R(t){if(typeof t=="string")return t.trim();if(!Array.isArray(t))return"";const e=[];for(const n of t)if(n!==null&&typeof n=="object"){const i=n;i.type==="text"&&typeof i.text=="string"&&e.push(i.text)}return e.join(" ").trim()}u(R,"extractUserText");function ft(t,e,n=!1){if(!n&&e!==null&&e!==void 0){const r=Date.parse(e);if(!Number.isNaN(r))return r}const i=Date.parse(t);return Number.isNaN(i)?0:i}u(ft,"sessionMtime");function dt(t){if(t.status!=="active")return!1;try{const e=JSON.parse(F(Z(t.node_id),N(q(t.node_id),"attach.json")).toString("utf8"));return typeof e.viewers=="number"&&e.viewers>0}catch{return!1}}u(dt,"hasLiveBrokerViewer");function pt(t,e,n){const i=t.status==="active"||t.status==="idle",r=t.fault??null;return{node_id:t.node_id,name:$(t),handle:t.name,description:t.description,status:t.status,frozen_at:t.frozen_at??null,terminal_reason:t.terminal_reason??null,kind:t.kind,mode:t.mode,ctx_tokens:n?0:t.telemetry_tokens_in??0,asks:0,cwd:t.cwd,profile_id:t.profile_id,created:t.created,lifecycle:t.lifecycle,finalized:t.final_report!=null,mtimeMs:ft(t.created,t.telemetry_updated_at,n),streaming:r===null&&i&&t.streaming===!0,hanging:r,viewed:n?!1:e.has(t.node_id)||dt(t),srcRow:t}}u(pt,"dashboardRowFromNodeRow");async function vt(t,e,n,i){const r=t instanceof y,s=i??await t.ticketCountsForView(e).catch(()=>({})),a=new Map((n??await t.listNodes()).map(c=>[c.node_id,c]));return[e,...await t.view(e)].flatMap(c=>{const l=a.get(c);return l===void 0?[]:[{node_id:c,name:$(l),handle:l.name,description:l.description,status:l.status,frozen_at:l.frozen_at??null,terminal_reason:l.terminal_reason??null,kind:l.kind,mode:l.mode,ctx_tokens:r?0:l.telemetry_tokens_in??0,asks:s[c]??0,cwd:l.cwd,profile_id:l.profile_id,created:l.created}]})}u(vt,"dashboardRowsFromSource");async function At(t,e=new Set,n=!1,i){const r=t instanceof y,s=r?new Set:e;return(i??await t.listNodes(n?{status:["active","idle"]}:void 0)).map(o=>pt(o,s,r))}u(At,"dashboardRowsAllFromSource");async function Ct(t,e,n){const i=e.filter(s=>s.enriched!==!0);if(i.length===0)return;const r=n??{};for(const s of i)s.asks=r[s.node_id]??0,s.enriched=!0}u(Ct,"enrichRowsFromSource");async function Ft(t,e){if(e.previewLoaded===!0)return e;if(!(t instanceof y)){const i=await t.getNode(e.node_id),r=i?.paths,s=r===void 0?e.srcRow?.grantee??(await t.getRow(e.node_id))?.grantee:void 0;if(r===void 0&&!s)throw new Error(`node ${e.node_id} has no app assignment`);const a=r?.context_dir??K(e.node_id,s),o=r?.reports_dir??Q(e.node_id,s);e.goal=nt(a);const{prompts:c,lastAssistant:l}=ct(i?.pi_session_file);e.prompts=c,e.lastAssistant=l,e.recap=X(e.node_id),e.report=rt(o)}return e.previewLoaded=!0,e}u(Ft,"loadPreviewFromSource");async function Pt(t,e){if(e.transcriptLoaded===!0)return e;if(t instanceof y)return e.transcript=[],e.transcriptLoaded=!0,e;const n=await t.getNode(e.node_id);return e.transcript=lt(n?.pi_session_file),e.transcriptLoaded=!0,e}u(Pt,"loadTranscriptFromSource");export{pt as dashboardRowFromNodeRow,At as dashboardRowsAllFromSource,vt as dashboardRowsFromSource,Ct as enrichRowsFromSource,w as fmtCtx,Ft as loadPreviewFromSource,Pt as loadTranscriptFromSource,Rt as nodeHasAssistantMessage,nt as readGoalText,rt as readNewestReport,ct as readSessionParts,lt as readTranscript,Tt as renderForestFromSource,et as renderTreeFromSource,ft as sessionMtime};
4
+ `)}u(kt,"renderForestFromSource");const w=4096;function I(t){try{const e=W(H(t),A(t,"initial-prompt.md"))?.trim()??"";return e===""?void 0:e.length>w?e.slice(0,w):e}catch{return}}u(I,"readGoalText");const M=1024;function tt(t){if(t==null)return;const e=t.tier,n=t.created,i=t.body,s=i.split(`
5
+ `);let r="",a=i;for(let c=0;c<s.length;c++){const l=(s[c]??"").trim();if(l!==""){r=l.startsWith("#")?l.replace(/^#+\s*/,"").trim():l,a=s.slice(c+1).join(`
6
+ `);break}}const o=a.replace(/\s+/g," ").trim();return{kind:e,ts:n,heading:r,body:o.length>M?o.slice(0,M):o}}u(tt,"reportPreview");const et=1<<20,nt=1<<20,it=4<<20;function O(t,e,n){if(t==null||t==="")return null;const i=R(t);if(i===null)return null;try{const{entries:s,tail:r}=v().read(i,{head:e,tail:n});return{head:s,tail:r??s}}catch(s){if(s instanceof T)return null;throw s}}u(O,"readSessionWindow");const b=8192,S=2048;function st(t){const e=O(t,et,nt);if(e===null)return{};const n=[];let i=0;for(const a of e.head){if(a.type!=="message"||a.message.role!=="user")continue;const o=N(a.message.content);if(o===""||E({role:"user",content:o})!==null)continue;const c=o.length>S?o.slice(0,S):o;if(n.push(c),i+=c.length+1,i>=b)break}let s;if(n.length>0){const a=n.join(`
7
+ `);s=a.length>b?a.slice(0,b):a}let r;for(let a=e.tail.length-1;a>=0;a--){const o=e.tail[a];if(o.type!=="message"||o.message.role!=="assistant")continue;const c=N(o.message.content);if(c!==""){r=c.length>S?c.slice(0,S):c;break}}return{prompts:s,lastAssistant:r}}u(st,"readSessionParts");const z=120,B=4096;function rt(t){const e=O(t,0,it);if(e===null)return[];const n=[];for(const i of e.tail){if(i.type!=="message")continue;const s=i.message.role;if(s!=="user"&&s!=="assistant")continue;const r=N(i.message.content);r!==""&&E({role:s,content:r})===null&&n.push({role:s,text:r.length>B?r.slice(0,B):r})}return n.length>z?n.slice(n.length-z):n}u(rt,"readTranscript");function St(t){if(t==null||t==="")return!1;const e=R(t);if(e===null)return!1;let n;try{n=v().read(e).entries}catch(i){if(i instanceof T)return!1;throw i}for(const i of n)if(!(i.type!=="message"||i.message.role!=="assistant")&&ot(i.message.content))return!0;return!1}u(St,"nodeHasAssistantMessage");function ot(t){if(typeof t=="string")return t.trim()!=="";if(!Array.isArray(t))return!1;for(const e of t){if(e===null||typeof e!="object")continue;const n=e,i=(n.type??"").toLowerCase();if(i==="text"){if(typeof n.text=="string"&&n.text.trim()!=="")return!0}else if(i==="thinking"){if(typeof n.thinking=="string"&&n.thinking.trim()!=="")return!0}else return!0}return!1}u(ot,"assistantContentIsSubstantive");function N(t){if(typeof t=="string")return t.trim();if(!Array.isArray(t))return"";const e=[];for(const n of t)if(n!==null&&typeof n=="object"){const i=n;i.type==="text"&&typeof i.text=="string"&&e.push(i.text)}return e.join(" ").trim()}u(N,"extractUserText");function at(t,e,n=!1){if(!n&&e!==null&&e!==void 0){const s=Date.parse(e);if(!Number.isNaN(s))return s}const i=Date.parse(t);return Number.isNaN(i)?0:i}u(at,"sessionMtime");function ct(t){if(t.status!=="active")return!1;try{const e=JSON.parse(J(U(t.node_id),A(q(t.node_id),"attach.json")).toString("utf8"));return typeof e.viewers=="number"&&e.viewers>0}catch{return!1}}u(ct,"hasLiveBrokerViewer");function lt(t,e,n){const i=t.status==="active"||t.status==="idle",s=t.fault??null;return{node_id:t.node_id,name:k(t),handle:t.name,description:t.description,status:t.status,frozen_at:t.frozen_at??null,terminal_reason:t.terminal_reason??null,kind:t.kind,mode:t.mode,ctx_tokens:n?0:t.telemetry_tokens_in??0,asks:0,cwd:t.cwd,profile_id:t.profile_id,created:t.created,lifecycle:t.lifecycle,finalized:t.final_report!=null,mtimeMs:at(t.created,t.telemetry_updated_at,n),streaming:s===null&&i&&t.streaming===!0,hanging:s,viewed:n?!1:e.has(t.node_id)||ct(t),srcRow:t}}u(lt,"dashboardRowFromNodeRow");async function $t(t,e,n,i){const s=t instanceof y,r=i??await t.ticketCountsForView(e).catch(()=>({})),a=new Map((n??await t.listNodes()).map(c=>[c.node_id,c]));return[e,...await t.view(e)].flatMap(c=>{const l=a.get(c);return l===void 0?[]:[{node_id:c,name:k(l),handle:l.name,description:l.description,status:l.status,frozen_at:l.frozen_at??null,terminal_reason:l.terminal_reason??null,kind:l.kind,mode:l.mode,ctx_tokens:s?0:l.telemetry_tokens_in??0,asks:r[c]??0,cwd:l.cwd,profile_id:l.profile_id,created:l.created}]})}u($t,"dashboardRowsFromSource");async function bt(t,e=new Set,n=!1,i){const s=t instanceof y,r=s?new Set:e;return(i??await t.listNodes(n?{status:["active","idle"]}:void 0)).map(o=>lt(o,r,s))}u(bt,"dashboardRowsAllFromSource");async function Nt(t,e,n){const i=e.filter(r=>r.enriched!==!0);if(i.length===0)return;const s=n??{};for(const r of i)r.asks=s[r.node_id]??0,r.enriched=!0}u(Nt,"enrichRowsFromSource");async function Rt(t,e){if(e.previewLoaded===!0)return e;if(!(t instanceof y)){const i=await t.getNode(e.node_id),s=i?.paths,r=s===void 0?e.srcRow?.grantee??(await t.getRow(e.node_id))?.grantee:void 0;if(s===void 0&&!r)throw new Error(`node ${e.node_id} has no app assignment`);const a=s?.context_dir??K(e.node_id,r);e.goal=I(a);const{prompts:o,lastAssistant:c}=st(i?.pi_session_file);e.prompts=o,e.lastAssistant=c,e.recap=Q(e.node_id),e.report=tt(await t.newestReport?.(e.node_id).catch(()=>null))}return e.previewLoaded=!0,e}u(Rt,"loadPreviewFromSource");async function vt(t,e){if(e.transcriptLoaded===!0)return e;if(t instanceof y)return e.transcript=[],e.transcriptLoaded=!0,e;const n=await t.getNode(e.node_id);return e.transcript=rt(n?.pi_session_file),e.transcriptLoaded=!0,e}u(vt,"loadTranscriptFromSource");export{lt as dashboardRowFromNodeRow,bt as dashboardRowsAllFromSource,$t as dashboardRowsFromSource,Nt as enrichRowsFromSource,F as fmtCtx,Rt as loadPreviewFromSource,vt as loadTranscriptFromSource,St as nodeHasAssistantMessage,I as readGoalText,st as readSessionParts,rt as readTranscript,kt as renderForestFromSource,Z as renderTreeFromSource,tt as reportPreview,at as sessionMtime};
@@ -1,4 +1,4 @@
1
- var v=Object.defineProperty;var i=(n,e)=>v(n,"name",{value:e,configurable:!0});import{randomUUID as R}from"node:crypto";import{closeSync as C,existsSync as w,openSync as U,readSync as A,statSync as W,truncateSync as g,unlinkSync as m}from"node:fs";import{openDb as d,withCanvasWrite as p}from"./db.js";import{canonicalSessionFile as L}from"./canvas.js";import{join as I}from"node:path";import{readConfig as h}from"../config.js";import{appSpace as y,socketDir as H}from"../layout.js";import{createFileStore as M,conversationStore as F,defaultConversationRoot as x,installConversationStore as D}from"../conversation-store/index.js";import{listenConversationStore as P}from"../conversation-store/listener.js";import{appendConversationEvents as O}from"../../daemon/runs/append-section.js";function f(){return new Date().toISOString()}i(f,"now");function b(n,e,s){return n.prepare("SELECT 1 FROM executions WHERE execution_id = ? AND node_id = ? AND state != 'exited'").get(s,e)!==void 0}i(b,"liveExecution");function B(n){return{bindingId:n.binding_id,sessionId:n.session_id??null,nodeId:n.node_id,transcriptPath:n.transcript_path??null,sourceSessionId:n.source_session_id??null,forkEntryId:n.fork_entry_id??null,createdAt:n.created_at,boundAt:n.bound_at,unboundAt:n.unbound_at??null}}i(B,"hydrate");function en(n){const e=d().prepare("SELECT * FROM sessions WHERE node_id = ? AND unbound_at IS NULL").get(n);return e===void 0?null:B(e)}i(en,"readLiveSession");function sn(n){return d().prepare("SELECT node_id FROM sessions WHERE transcript_path = ? AND unbound_at IS NULL").get(L(n))?.node_id??null}i(sn,"findNodeBySessionFileSql");function on(n,e){return p(s=>{if(!b(s,n,e.executionId))return"shutdown";const o=f(),r=e.transcriptPath===null?null:L(e.transcriptPath),a=s.prepare("SELECT binding_id, session_id FROM sessions WHERE node_id = ? AND unbound_at IS NULL").get(n);if(a!==void 0&&a.session_id===e.sessionId)s.prepare("UPDATE sessions SET transcript_path = ?, source_session_id = ?, bound_at = ? WHERE binding_id = ?").run(r,e.sourceSessionId??null,o,a.binding_id);else{a!==void 0&&s.prepare("UPDATE sessions SET unbound_at = ? WHERE binding_id = ?").run(o,a.binding_id);const t=e.sessionId===null?void 0:s.prepare("SELECT binding_id FROM sessions WHERE node_id = ? AND session_id = ? ORDER BY created_at DESC LIMIT 1").get(n,e.sessionId);t?s.prepare("UPDATE sessions SET transcript_path = ?, source_session_id = ?, bound_at = ?, unbound_at = NULL WHERE binding_id = ?").run(r,e.sourceSessionId??null,o,t.binding_id):s.prepare("INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at) VALUES (?, ?, ?, ?, ?, NULL, ?, ?)").run(R(),e.sessionId,n,r,e.sourceSessionId??null,o,o)}return s.prepare("UPDATE nodes SET cycle_pending = 0 WHERE node_id = ?").run(n),"bound"})}i(on,"bindSession");function rn(n,e){p(s=>{const o=f();s.prepare("UPDATE sessions SET unbound_at = ? WHERE node_id = ? AND unbound_at IS NULL").run(o,n),s.prepare("INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at) VALUES (?, ?, ?, ?, NULL, NULL, ?, ?)").run(R(),e.sessionId,n,e.transcriptPath===null?null:L(e.transcriptPath),o,o),s.prepare("UPDATE nodes SET cycle_pending = 0 WHERE node_id = ?").run(n)})}i(rn,"resetSession");function tn(n){return p(e=>{if(!b(e,n.toNodeId,n.executionId))return"shutdown";if(e.prepare("SELECT binding_id FROM sessions WHERE node_id = ? AND binding_id = ? AND unbound_at IS NULL").get(n.fromNodeId,n.fromBindingId)===void 0)return"changed";if(e.prepare("SELECT run_id FROM nodes WHERE node_id IN (?, ?) AND run_id IS NOT NULL LIMIT 1").get(n.fromNodeId,n.toNodeId))throw new Error("run conversation transfer is not supported");const r=f();return e.prepare("UPDATE sessions SET unbound_at = ? WHERE binding_id = ?").run(r,n.fromBindingId),e.prepare("UPDATE sessions SET unbound_at = ? WHERE node_id = ? AND unbound_at IS NULL").run(r,n.toNodeId),e.prepare("INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at) VALUES (?, ?, ?, ?, NULL, NULL, ?, ?)").run(R(),n.sessionId,n.toNodeId,n.transcriptPath===null?null:L(n.transcriptPath),r,r),e.prepare("UPDATE nodes SET cycle_pending = 0 WHERE node_id = ?").run(n.toNodeId),"transferred"})}i(tn,"transferSession");function dn(n){d().prepare("UPDATE sessions SET unbound_at = ? WHERE node_id = ? AND unbound_at IS NULL").run(f(),n)}i(dn,"unbindSession");function an(n,e){d().prepare("UPDATE nodes SET cycle_pending = ? WHERE node_id = ?").run(e?1:0,n)}i(an,"setCyclePending");const T="unbound_at IS NULL DESC, created_at DESC, rowid DESC";function _n(n){return d().prepare(`SELECT node_id FROM sessions WHERE session_id = ? ORDER BY ${T} LIMIT 1`).get(n)?.node_id??null}i(_n,"conversationOwner");const $={appendSection:i((n,e,s)=>{const o=e.kind==="create"?e:void 0;o&&p(r=>{if(!r.prepare("SELECT node_id FROM nodes WHERE node_id = ?").get(o.nodeId))throw new Error(`missing conversation owner ${o.nodeId}`);const t=f();r.prepare("INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at, unbound_at, event_offset) VALUES (?, ?, ?, ?, ?, NULL, ?, ?, ?, 0)").run(R(),n,o.nodeId,o.path,o.sourceId??null,t,t,t)}),p(r=>{const a=r.prepare(`SELECT node_id, binding_id, input_ids_json FROM sessions WHERE session_id = ? ORDER BY ${T} LIMIT 1`).get(n),t=o?o.nodeId:a?.node_id;if(!t)throw new Error(`conversation ${n} has no active owner`);const u=r.prepare("SELECT run_id FROM nodes WHERE node_id = ?").get(t);if(!u)throw new Error(`cannot write conversation ${n}: missing node ${t}`);if(e.kind==="replace"&&u.run_id!==null)throw new Error(`run conversation ${n} is append-only; replace refused`);const l=a.binding_id,S=s();if(u.run_id!==null&&e.kind!=="replace"){const E=o?.sourceId?[]:e.entries,_=O(r,u.run_id,t,E,JSON.parse(a?.input_ids_json??"[]"));r.prepare("UPDATE sessions SET event_offset = ?, indexed_entry_id = ?, input_ids_json = ? WHERE binding_id = ?").run(S,E.at(-1)?.id??null,JSON.stringify(_),l)}})},"appendSection"),abortCreate(n){d().prepare("DELETE FROM sessions WHERE session_id = ? AND event_offset = 0").run(n)},delete(n){d().prepare("DELETE FROM sessions WHERE session_id = ?").run(n)},pathFor(n){return d().prepare(`SELECT transcript_path FROM sessions WHERE session_id = ? ORDER BY ${T} LIMIT 1`).get(n)?.transcript_path??void 0},createPath(n,e){const s=d().prepare("SELECT grantee FROM nodes WHERE node_id = ?").get(n);if(!s)throw new Error(`missing conversation owner ${n}`);return I(y(s.grantee).conversations,n,`${e.timestamp.replace(/[:.]/g,"-")}_${e.id}.jsonl`)},repair(n,e){k(n,e)},owners(){const n=new Map,e=d().prepare(`SELECT session_id, node_id FROM sessions WHERE session_id IS NOT NULL ORDER BY session_id, ${T}`).all();for(const s of e)n.has(s.session_id)||n.set(s.session_id,s.node_id);return n}};function k(n,e){const s=d().prepare(`SELECT s.binding_id, s.node_id, s.event_offset, s.input_ids_json, s.source_session_id, n.run_id
2
- FROM sessions s JOIN nodes n ON n.node_id = s.node_id WHERE s.session_id = ? ORDER BY s.unbound_at IS NULL DESC, s.created_at DESC, s.rowid DESC LIMIT 1`).get(n);if(!s?.run_id||s.event_offset===null)return;if(s.event_offset===0&&!w(e)){d().prepare("DELETE FROM sessions WHERE binding_id = ?").run(s.binding_id);return}const o=W(e).size;if(o<s.event_offset)throw new Error(`conversation shorter than indexed offset: ${n}`);if(o===s.event_offset)return;const r=U(e,"r"),a=[];try{const _=Buffer.allocUnsafe(65536);for(let c=s.event_offset;c<o;){const N=A(r,_,0,Math.min(_.length,o-c),c);if(!N)throw new Error(`conversation read ended early: ${n}`);a.push(Buffer.from(_.subarray(0,N))),c+=N}}finally{C(r)}const t=Buffer.concat(a).toString("utf8"),u=t.lastIndexOf(`
1
+ var v=Object.defineProperty;var i=(n,e)=>v(n,"name",{value:e,configurable:!0});import{randomUUID as R}from"node:crypto";import{closeSync as w,existsSync as C,openSync as U,readSync as A,statSync as W,truncateSync as g,unlinkSync as m}from"node:fs";import{openDb as d,withCanvasWrite as p}from"./db.js";import{canonicalSessionFile as L}from"./canvas.js";import{join as I}from"node:path";import{readConfig as h}from"../config.js";import{appSpace as y,socketDir as H}from"../layout.js";import{createFileStore as M,conversationStore as F,defaultConversationRoot as x,installConversationStore as D}from"../conversation-store/index.js";import{listenConversationStore as P}from"../conversation-store/listener.js";import{appendConversationEvents as O}from"../../daemon/runs/append-section.js";function f(){return new Date().toISOString()}i(f,"now");function b(n,e,s){return n.prepare("SELECT 1 FROM executions WHERE execution_id = ? AND node_id = ? AND state != 'exited'").get(s,e)!==void 0}i(b,"liveExecution");function B(n){return{bindingId:n.binding_id,sessionId:n.session_id??null,nodeId:n.node_id,transcriptPath:n.transcript_path??null,sourceSessionId:n.source_session_id??null,forkEntryId:n.fork_entry_id??null,createdAt:n.created_at,boundAt:n.bound_at,unboundAt:n.unbound_at??null}}i(B,"hydrate");function en(n){const e=d().prepare("SELECT * FROM sessions WHERE node_id = ? AND unbound_at IS NULL").get(n);return e===void 0?null:B(e)}i(en,"readLiveSession");function sn(n){return d().prepare("SELECT node_id FROM sessions WHERE transcript_path = ? AND unbound_at IS NULL").get(L(n))?.node_id??null}i(sn,"findNodeBySessionFileSql");function on(n,e){return p(s=>{if(!b(s,n,e.executionId))return"shutdown";const o=f(),r=e.transcriptPath===null?null:L(e.transcriptPath),a=s.prepare("SELECT binding_id, session_id FROM sessions WHERE node_id = ? AND unbound_at IS NULL").get(n);if(a!==void 0&&a.session_id===e.sessionId)s.prepare("UPDATE sessions SET transcript_path = ?, source_session_id = ?, bound_at = ? WHERE binding_id = ?").run(r,e.sourceSessionId??null,o,a.binding_id);else{a!==void 0&&s.prepare("UPDATE sessions SET unbound_at = ? WHERE binding_id = ?").run(o,a.binding_id);const t=e.sessionId===null?void 0:s.prepare("SELECT binding_id FROM sessions WHERE node_id = ? AND session_id = ? ORDER BY created_at DESC LIMIT 1").get(n,e.sessionId);t?s.prepare("UPDATE sessions SET transcript_path = ?, source_session_id = ?, bound_at = ?, unbound_at = NULL WHERE binding_id = ?").run(r,e.sourceSessionId??null,o,t.binding_id):s.prepare("INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at) VALUES (?, ?, ?, ?, ?, NULL, ?, ?)").run(R(),e.sessionId,n,r,e.sourceSessionId??null,o,o)}return s.prepare("UPDATE nodes SET cycle_pending = 0 WHERE node_id = ?").run(n),"bound"})}i(on,"bindSession");function rn(n,e){p(s=>{const o=f();s.prepare("UPDATE sessions SET unbound_at = ? WHERE node_id = ? AND unbound_at IS NULL").run(o,n),s.prepare("INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at) VALUES (?, ?, ?, ?, NULL, NULL, ?, ?)").run(R(),e.sessionId,n,e.transcriptPath===null?null:L(e.transcriptPath),o,o),s.prepare("UPDATE nodes SET cycle_pending = 0 WHERE node_id = ?").run(n)})}i(rn,"resetSession");function tn(n){return p(e=>{if(!b(e,n.toNodeId,n.executionId))return"shutdown";if(e.prepare("SELECT binding_id FROM sessions WHERE node_id = ? AND binding_id = ? AND unbound_at IS NULL").get(n.fromNodeId,n.fromBindingId)===void 0)return"changed";if(e.prepare("SELECT run_id FROM nodes WHERE node_id IN (?, ?) AND run_id IS NOT NULL LIMIT 1").get(n.fromNodeId,n.toNodeId))throw new Error("run conversation transfer is not supported");const r=f();return e.prepare("UPDATE sessions SET unbound_at = ? WHERE binding_id = ?").run(r,n.fromBindingId),e.prepare("UPDATE sessions SET unbound_at = ? WHERE node_id = ? AND unbound_at IS NULL").run(r,n.toNodeId),e.prepare("INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at) VALUES (?, ?, ?, ?, NULL, NULL, ?, ?)").run(R(),n.sessionId,n.toNodeId,n.transcriptPath===null?null:L(n.transcriptPath),r,r),e.prepare("UPDATE nodes SET cycle_pending = 0 WHERE node_id = ?").run(n.toNodeId),"transferred"})}i(tn,"transferSession");function dn(n){d().prepare("UPDATE sessions SET unbound_at = ? WHERE node_id = ? AND unbound_at IS NULL").run(f(),n)}i(dn,"unbindSession");function an(n,e){d().prepare("UPDATE nodes SET cycle_pending = ? WHERE node_id = ?").run(e?1:0,n)}i(an,"setCyclePending");const T="unbound_at IS NULL DESC, created_at DESC, rowid DESC";function _n(n){return d().prepare(`SELECT node_id FROM sessions WHERE session_id = ? ORDER BY ${T} LIMIT 1`).get(n)?.node_id??null}i(_n,"conversationOwner");const $={appendSection:i((n,e,s)=>{const o=e.kind==="create"?e:void 0;o&&p(r=>{if(!r.prepare("SELECT node_id FROM nodes WHERE node_id = ?").get(o.nodeId))throw new Error(`missing conversation owner ${o.nodeId}`);const t=f();r.prepare("INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at, unbound_at, event_offset) VALUES (?, ?, ?, ?, ?, NULL, ?, ?, ?, 0)").run(R(),n,o.nodeId,o.path,o.sourceId??null,t,t,t)}),p(r=>{const a=r.prepare(`SELECT node_id, binding_id, input_ids_json FROM sessions WHERE session_id = ? ORDER BY ${T} LIMIT 1`).get(n),t=o?o.nodeId:a?.node_id;if(!t)throw new Error(`conversation ${n} has no active owner`);const u=r.prepare("SELECT run_id FROM nodes WHERE node_id = ?").get(t);if(!u)throw new Error(`cannot write conversation ${n}: missing node ${t}`);if(e.kind==="replace"&&u.run_id!==null)throw new Error(`run conversation ${n} is append-only; replace refused`);const l=a.binding_id,S=s();if(u.run_id!==null&&e.kind!=="replace"){const E=o?.sourceId?[]:e.entries,_=O(r,u.run_id,t,E,JSON.parse(a?.input_ids_json??"[]"));r.prepare("UPDATE sessions SET event_offset = ?, indexed_entry_id = ?, input_ids_json = ? WHERE binding_id = ?").run(S,E.at(-1)?.id??null,JSON.stringify(_),l)}})},"appendSection"),abortCreate(n){d().prepare("DELETE FROM sessions WHERE session_id = ? AND event_offset = 0").run(n)},delete(n){d().prepare("DELETE FROM sessions WHERE session_id = ?").run(n)},pathFor(n){return d().prepare(`SELECT transcript_path FROM sessions WHERE session_id = ? ORDER BY ${T} LIMIT 1`).get(n)?.transcript_path??void 0},createPath(n,e){const s=d().prepare("SELECT grantee FROM node_rows WHERE node_id = ?").get(n);if(!s)throw new Error(`missing conversation owner ${n}`);return I(y(s.grantee).conversations,n,`${e.timestamp.replace(/[:.]/g,"-")}_${e.id}.jsonl`)},repair(n,e){k(n,e)},owners(){const n=new Map,e=d().prepare(`SELECT session_id, node_id FROM sessions WHERE session_id IS NOT NULL ORDER BY session_id, ${T}`).all();for(const s of e)n.has(s.session_id)||n.set(s.session_id,s.node_id);return n}};function k(n,e){const s=d().prepare(`SELECT s.binding_id, s.node_id, s.event_offset, s.input_ids_json, s.source_session_id, n.run_id
2
+ FROM sessions s JOIN nodes n ON n.node_id = s.node_id WHERE s.session_id = ? ORDER BY s.unbound_at IS NULL DESC, s.created_at DESC, s.rowid DESC LIMIT 1`).get(n);if(!s?.run_id||s.event_offset===null)return;if(s.event_offset===0&&!C(e)){d().prepare("DELETE FROM sessions WHERE binding_id = ?").run(s.binding_id);return}const o=W(e).size;if(o<s.event_offset)throw new Error(`conversation shorter than indexed offset: ${n}`);if(o===s.event_offset)return;const r=U(e,"r"),a=[];try{const _=Buffer.allocUnsafe(65536);for(let c=s.event_offset;c<o;){const N=A(r,_,0,Math.min(_.length,o-c),c);if(!N)throw new Error(`conversation read ended early: ${n}`);a.push(Buffer.from(_.subarray(0,N))),c+=N}}finally{w(r)}const t=Buffer.concat(a).toString("utf8"),u=t.lastIndexOf(`
3
3
  `);if(u<0){s.event_offset===0?(m(e),d().prepare("DELETE FROM sessions WHERE binding_id = ?").run(s.binding_id)):g(e,s.event_offset);return}const l=t.slice(0,u+1),S=l.split(`
4
4
  `).filter(Boolean).map(_=>JSON.parse(_)).filter(_=>_.type!=="session"),E=s.event_offset+Buffer.byteLength(l);E<o&&g(e,E),p(_=>{const c=s.source_session_id?[]:O(_,s.run_id,s.node_id,S,JSON.parse(s.input_ids_json));_.prepare("UPDATE sessions SET event_offset = ?, indexed_entry_id = ?, input_ids_json = ? WHERE binding_id = ?").run(E,S.at(-1)?.id??null,JSON.stringify(c),s.binding_id)})}i(k,"repairConversationTail");function j(n){return M(n,$)}i(j,"openCanvasConversationStore");function un(n){const e=d().prepare("SELECT DISTINCT s.session_id FROM sessions s JOIN nodes n ON n.node_id = s.node_id WHERE n.run_id = ? AND s.session_id IS NOT NULL").all(n),s=F();for(const o of e)s.repair?.(o.session_id)}i(un,"repairRunConversations");async function En(){const n=h("user").store,e=n?.address??I(H(),"store.sock"),s=j(n?.root??x());D(s),process.env.CRTR_STORE_ADDRESS=e;const o=await P(e,s);return{async close(){await o.close(),D(void 0)}}}i(En,"serveCanvasConversationStore");export{on as bindSession,_n as conversationOwner,sn as findNodeBySessionFileSql,j as openCanvasConversationStore,en as readLiveSession,un as repairRunConversations,rn as resetSession,En as serveCanvasConversationStore,an as setCyclePending,tn as transferSession,dn as unbindSession};
@@ -12,6 +12,12 @@ export interface CanvasSource {
12
12
  ticketCountsForNodes(nodeIds: readonly string[]): Promise<Record<string, number>>;
13
13
  ticketCountsForView(root: string): Promise<Record<string, number>>;
14
14
  hasActiveLiveSubscription(nodeId: string): Promise<boolean>;
15
+ /** The node's newest report document, or null. Only a source that reads through `/v1` offers it. */
16
+ newestReport?(nodeId: string): Promise<{
17
+ tier: string;
18
+ created: string;
19
+ body: string;
20
+ } | null>;
15
21
  }
16
22
  export declare class LocalCanvasSource implements CanvasSource {
17
23
  getNode(nodeId: string): Promise<NodeMeta | null>;
@@ -0,0 +1,29 @@
1
+ import type { SubscriptionRef } from './types.js';
2
+ /** One tree edge between two nodes: `from_id` watches `to_id`. */
3
+ export interface RosterEdge {
4
+ from_id: string;
5
+ to_id: string;
6
+ active: boolean;
7
+ created: string;
8
+ }
9
+ /** Every in-tree node→node watch, oldest first — the roster's topology half. */
10
+ export declare function rosterEdges(): RosterEdge[];
11
+ /** `subscriber` asks to watch `publisher` (an `ask` watch, in the tree). Re-running sets the
12
+ * pair's tree subscriptions active or passive (`{"3":"next-turn"}`). */
13
+ export declare function subscribe(subscriber: string, publisher: string, active?: boolean): void;
14
+ /** Drop the pair's tree subscriptions; a reading or message watch on the same pair survives. */
15
+ export declare function unsubscribe(subscriber: string, publisher: string): void;
16
+ /** Rewrite the listening configuration of the pair's tree subscriptions: NULL (the watcher's
17
+ * default) for active, `{"3":"next-turn"}` for passive. */
18
+ export declare function setSubscriptionActive(subscriber: string, publisher: string, active: boolean): void;
19
+ /** Who watches `publisher` in the tree — the targets a push fans out to. */
20
+ export declare function subscribersOf(publisher: string): SubscriptionRef[];
21
+ /** The nodes `subscriber` watches in the tree — its reports. */
22
+ export declare function subscriptionsOf(subscriber: string): SubscriptionRef[];
23
+ /** Every node below `root` in the tree, excluding root. */
24
+ export declare function view(root: string): string[];
25
+ /** Stop-guard primitive: does this node hold an active tree subscription to a live node —
26
+ * something that can actually wake it? */
27
+ export declare function hasActiveLiveSubscription(nodeId: string): boolean;
28
+ /** Whether a live node still actively watches this one in the tree — a report this node owes. */
29
+ export declare function hasLiveSubscriber(nodeId: string): boolean;
@@ -0,0 +1,12 @@
1
+ var v=Object.defineProperty;var i=(o,t)=>v(o,"name",{value:t,configurable:!0});import{openDb as c,withCanvasWrite as u}from"./db.js";import{getById as A,nodeObject as a}from"../graph/objects.js";import{recordWatch as S,unwatch as b,descendants as O,configFromJson as E,configToJson as R}from"../graph/watches.js";import{publish as T}from"../graph/events.js";import{DEFAULT_LISTEN as j}from"../graph/types.js";const D=["spawn","job-start","ask"],m="('spawn','job-start','ask')",y=[{threshold:3,delivery:"next-turn"}];function N(o){const t=o.find(e=>e.threshold<=7);return t!==void 0&&t.delivery!=="next-turn"}i(N,"wakesAtSeven");function d(o,t,...e){const n=o.prepare(`SELECT wo.id AS from_id, oo.id AS to_id, ws.config_json, ws.created_at,
2
+ wn.listen_default_json, wn.status AS from_status, onode.status AS to_status
3
+ FROM watches w
4
+ JOIN objects wo ON wo.rowid = w.watcher AND wo.type = 'node'
5
+ JOIN objects oo ON oo.rowid = w.object AND oo.type = 'node'
6
+ JOIN watch_subscriptions ws ON ws.watch = w.rowid AND ws.started_by IN ${m}
7
+ JOIN nodes wn ON wn.node_id = wo.id
8
+ JOIN nodes onode ON onode.node_id = oo.id
9
+ WHERE w.in_tree = 1 ${t}
10
+ ORDER BY ws.created_at, ws.rowid`).all(...e),r=new Map;for(const s of n){const w=s.config_json,f=s.listen_default_json,_=w!=null?E(w):f!=null?E(f):j,p=`${s.from_id}\0${s.to_id}`,l=r.get(p);if(l){l.active||=N(_);continue}r.set(p,{from_id:s.from_id,to_id:s.to_id,active:N(_),created:s.created_at,from_status:s.from_status??null,to_status:s.to_status??null})}return[...r.values()]}i(d,"treeEdges");function F(){return d(c(),"").map(({from_id:o,to_id:t,active:e,created:n})=>({from_id:o,to_id:t,active:e,created:n}))}i(F,"rosterEdges");function $(o,t,e=!0){u(n=>{const r=a(n,o),s=a(n,t);S(n,r,s,"ask"),I(o,t,e),T(n,{event:"watched",object:s,actor:r,level:1,attrs:{}})})}i($,"subscribe");function C(o,t){u(e=>{const n=a(e,o),r=a(e,t);for(const s of D)b(e,n,r,{startedBy:s})})}i(C,"unsubscribe");function I(o,t,e){u(n=>{n.prepare(`UPDATE watch_subscriptions SET config_json = ?
11
+ WHERE started_by IN ${m}
12
+ AND watch IN (SELECT rowid FROM watches WHERE watcher = ? AND object = ?)`).run(e?null:R(y),a(n,o).rowid,a(n,t).rowid)})}i(I,"setSubscriptionActive");function H(o){return d(c(),"AND oo.id = ?",o).map(t=>({node_id:t.from_id,active:t.active,created:t.created}))}i(H,"subscribersOf");function M(o){return d(c(),"AND wo.id = ?",o).map(t=>({node_id:t.to_id,active:t.active,created:t.created}))}i(M,"subscriptionsOf");function B(o){const t=c(),e=A(t,o);if(e?.type!=="node")return[];const n=t.prepare("SELECT 1 FROM nodes WHERE node_id = ?");return O(t,e).map(r=>r.id).filter(r=>n.get(r)!==void 0)}i(B,"view");const h=new Set(["active","idle"]);function P(o){return d(c(),"AND wo.id = ?",o).some(t=>t.active&&h.has(t.to_status??""))}i(P,"hasActiveLiveSubscription");function U(o){return d(c(),"AND oo.id = ?",o).some(t=>t.active&&h.has(t.from_status??""))}i(U,"hasLiveSubscriber");export{P as hasActiveLiveSubscription,U as hasLiveSubscriber,F as rosterEdges,I as setSubscriptionActive,$ as subscribe,H as subscribersOf,M as subscriptionsOf,C as unsubscribe,B as view};
@@ -48,7 +48,6 @@ export interface DeclinedResult {
48
48
  }
49
49
  /** The two structural edges. `subscribes_to` is the load-bearing spine (flow,
50
50
  * org chart, views, completion routing). `spawned_by` is audit only. */
51
- export type EdgeType = 'subscribes_to' | 'spawned_by';
52
51
  /** The pi launch recipe, persisted so the daemon can faithfully revive a node
53
52
  * as its *current* self. Rewritten on every polymorph (base→orchestrator). */
54
53
  export interface LaunchSpec {
@@ -351,13 +350,6 @@ export interface NodeRuntime {
351
350
  * It retains the historical `NodeMeta` name for existing callers. */
352
351
  export type NodeMeta = NodeIdentity & NodeRuntime;
353
352
  /** The queryable projection of a node's SQL configuration and runtime state. */
354
- /** The SQL fields corpus discovery needs to resolve a node memory store. */
355
- export interface NodeMemoryTarget {
356
- nodeId: string;
357
- cwd: string;
358
- profileId: string | null;
359
- grantee: string;
360
- }
361
353
  export interface NodeRow {
362
354
  node_id: string;
363
355
  name: string;
@@ -429,18 +421,6 @@ export interface NodeRow {
429
421
  /** True only while the live execution has an open turn and its PID is alive. */
430
422
  streaming?: boolean;
431
423
  }
432
- /** An edge as stored. For `subscribes_to`, `from` is the subscriber and `to`
433
- * is the publisher (A subscribes_to B ⇒ A receives B's output). For
434
- * `spawned_by`, `from` is the child and `to` is the parent. */
435
- export interface Edge {
436
- type: EdgeType;
437
- from: string;
438
- to: string;
439
- /** Only meaningful for subscribes_to: active = wake the subscriber on emit;
440
- * passive = accumulate pointers, no wake. */
441
- active: boolean;
442
- created: string;
443
- }
444
424
  /** A FOCUS row as stored in the `focuses` table (canvas.db, migration v6): one
445
425
  * durable on-screen viewport the user looks at, bound to one node. Plural —
446
426
  * many focuses live at once across windows and sessions (the plural
@@ -1 +1 @@
1
- var p=Object.defineProperty;var m=(e,s)=>p(e,"name",{value:s,configurable:!0});import{Parser as b}from"tar";import{validateCommandManifest as y}from"../../api/command-manifest/manifest.js";import{invalidPluginKindsReasons as g}from"../config.js";import{invalidPageComponentsReasons as k,normalizePageComponents as v}from"../human/page-catalog.js";import{validateMemoryExtensionDeclarations as j}from"../memory/extensions.js";function _(e,s,t,n,r,i){return{code:e,message:s,received:t,expected:n,next:r,...i!==void 0?{path:i}:{}}}m(_,"issue");function d(e,s,t,n,r){return _("plugin_bundle_invalid",e,s,t,n,r)}m(d,"bundleInvalid");function x(e){if(e[0]===31&&e[1]===139)return d("bundle archive must be uncompressed tar data","gzip-compressed archive","an uncompressed tar archive","Serve the archive without compression.");if(e.length===0||e.length%512!==0)return d("bundle archive must be a non-empty whole number of 512-byte tar blocks",`${e.length} bytes`,"a non-empty tar stream with a 512-byte block length","Serve one complete uncompressed tar archive.");if(e.length<1024||!e.subarray(-1024).every(s=>s===0))return d("bundle archive is missing the required two zero-block terminator","archive tail is not 1024 zero bytes","a complete tar stream ending in two 512-byte zero blocks","Serve the complete uncompressed tar archive.")}m(x,"archiveEnvelopeIssue");function S(e,s){if(e.length===0||e.includes("\0")||e.includes("\\")||e.startsWith("/")||/^[A-Za-z]:($|\/)/.test(e))return d("bundle member path must be a safe relative POSIX path",e,"a relative path without absolute, drive-letter, backslash, or NUL forms","Use a safe relative POSIX member path.",e);if(s==="file"&&e.endsWith("/"))return d("only directory members may have a trailing slash",e,"a regular-file path without a trailing slash","Emit this member as a regular file path.",e);if((s==="directory"&&e.endsWith("/")?e.slice(0,-1):e).split("/").some(n=>n===""||n==="."||n===".."))return d("bundle member path contains an unsafe segment",e,"non-empty segments other than . or ..","Use a safe relative POSIX member path.",e)}m(S,"validateMemberName");function w(e,s){if(s==="file")return e==="bundle.json"||e==="commands.json"||e==="hooks.json"||e.startsWith("memory/")&&e.endsWith(".md")||e.startsWith("hooks/")?void 0:d("bundle contains an unsupported file member",e,"bundle.json, commands.json, hooks.json, memory/**/*.md, or hooks/**","Remove unsupported members from the archive.",e);if(!(e==="memory"||e.startsWith("memory/")||e==="hooks"||e.startsWith("hooks/")))return d("bundle contains an unsupported directory member",e,"memory or hooks, or a directory below either subtree","Remove unsupported directory members from the archive.",e)}m(w,"validateMemberShape");function $(e){return e.type==="directory"&&e.path.endsWith("/")?e.path.slice(0,-1):e.path}m($,"materializedPath");function E(e){const s=new Map;for(const t of e){const n=$(t),r=s.get(n);if(r!==void 0)return d(r===t.type?"bundle contains a duplicate member":"bundle claims one path as both a file and a directory",`${n} (${r} and ${t.type})`,"each materialized path exactly once, with one type","Emit each archive path once, as a single member type.",n);s.set(n,t.type)}for(const[t,n]of s)if(n==="file"){for(const r of s.keys())if(r.startsWith(`${t}/`))return d("bundle nests a member beneath a regular-file path",`${r} beneath file ${t}`,"members nested only beneath directory paths","Emit the parent path as a directory or remove the nested member.",r)}}m(E,"validateMemberTree");async function N(e){const s=[],t=new Set;let n;return await new Promise((r,i)=>{const c=new b({strict:!0,maxMetaEntrySize:Number.MAX_SAFE_INTEGER,gzip:!1,brotli:!1,zstd:!1,onReadEntry:m(a=>{const u=a.path,f=a.type==="File"||a.type==="OldFile"?"file":a.type==="Directory"?"directory":void 0;if(f===void 0||a.unsupported||a.ignore||a.linkpath!==void 0){n??=d("bundle member must be a regular file or directory without a link target",`${u} (${a.type})`,"a regular file or directory member without link metadata","Remove links and unsupported member types from the archive.",u),a.resume();return}n??=S(u,f),n??=w(u,f),t.has(u)&&(n??=d("bundle contains a duplicate member",u,"each member path exactly once","Emit each archive member only once.",u)),t.add(u);const l=[];a.on("data",h=>l.push(h)),a.on("end",()=>{n===void 0&&s.push({path:u,type:f,bytes:new Uint8Array(Buffer.concat(l))})})},"onReadEntry")});c.on("ignoredEntry",a=>{const u=a.path;n??=d("bundle contains an ignored or unsupported archive member",`${u} (${a.type})`,"only supported regular file or directory members","Remove ignored or unsupported members from the archive.",u),a.resume()}),c.once("error",i),c.once("end",r);try{c.end(Buffer.from(e))}catch(a){i(a)}}).catch(r=>{n??=d("bundle archive could not be parsed",r instanceof Error?r.message:String(r),"a valid complete uncompressed tar archive","Fix the archive format and serve it again.")}),n===void 0?{members:s}:{issue:n}}m(N,"parseArchive");function O(e){let s;try{s=JSON.parse(Buffer.from(e).toString("utf8"))}catch{return{issue:d("bundle.json is not valid JSON","invalid JSON",'{"bundleVersion":1}',"Write valid bundle metadata.","bundle.json")}}if(typeof s!="object"||s===null||Array.isArray(s))return{issue:d("bundle.json must be a JSON object",JSON.stringify(s),"an object with bundleVersion set to 1 and optionally kinds",'Set bundle.json to {"bundleVersion":1}.',"bundle.json")};const t=s,n=Object.keys(t).filter(i=>i!=="bundleVersion"&&i!=="kinds"&&i!=="page_components"&&i!=="memory_extensions");if(t.bundleVersion!==1||n.length>0)return{issue:d("bundle.json must contain bundleVersion 1 and at most kinds, page_components, and memory_extensions blocks",JSON.stringify(s),"an object with bundleVersion set to 1 and optional kinds, page_components, and memory_extensions",'Set bundle.json to {"bundleVersion":1} plus optional contribution blocks.',"bundle.json")};if(t.kinds!==void 0){const i=g(t.kinds);if(i.length>0)return{issue:d("bundle.json kinds block is invalid",i.join("; "),"each entry a full KindConfig (whenToUse required) or a sparse patch of launch fields","Fix the kinds entries in bundle.json.","bundle.json")}}if(t.page_components!==void 0){const i=k(t.page_components);if(i.length>0)return{issue:d("bundle.json page_components block is invalid",i.join("; "),"an array of page component registrations, each a kind string or {kind, description?, useWhen?, doc?, display?}","Fix the page_components entries in bundle.json.","bundle.json")}}let r;if(t.memory_extensions!==void 0)try{r=j(t.memory_extensions)}catch(i){return{issue:d("bundle.json memory_extensions block is invalid",i instanceof Error?i.message:String(i),"a valid memory_extensions declaration object","Fix the memory_extensions declarations in bundle.json.","bundle.json")}}return{...t.kinds!==void 0?{kinds:t.kinds}:{},...t.page_components!==void 0?{page_components:v(t.page_components)}:{},...r!==void 0?{memory_extensions:r}:{}}}m(O,"parseBundleMetadata");function W(e,s,t,n=new Set){let r;try{r=JSON.parse(Buffer.from(e).toString("utf8"))}catch{return{issues:[d("commands.json is not valid JSON","invalid JSON","a valid command-manifest JSON object","Regenerate commands.json.","commands.json")]}}const i=y(r,{transport:"http",reservedCoreNames:s,extensibleCoreBranches:n,...t!==void 0?{coreCommandPaths:t}:{}});return{...i.manifest!==void 0?{commands:i.manifest}:{},issues:i.issues}}m(W,"parseCommands");async function R(e,s){const t=x(e);if(t!==void 0)return{issues:[t]};const n=await N(e);if(n.issue!==void 0||n.members===void 0)return{issues:[n.issue]};const r=E(n.members);if(r!==void 0)return{issues:[r]};const i=n.members.find(o=>o.path==="bundle.json"&&o.type==="file"),c=n.members.find(o=>o.path==="commands.json"&&o.type==="file");if(i===void 0||c===void 0)return{issues:[d("bundle must contain exactly one bundle.json and one commands.json regular file",`bundle.json=${i!==void 0}, commands.json=${c!==void 0}`,"one regular bundle.json and one regular commands.json member","Add the required metadata members to the archive.")]};const a=n.members.find(o=>o.path==="hooks.json"&&o.type==="file"),u=n.members.filter(o=>o.type==="file"&&o.path.startsWith("hooks/"));if((a!==void 0||n.members.some(o=>o.path==="hooks"||o.path.startsWith("hooks/")))&&(a===void 0||!u.some(o=>o.path==="hooks/dispatch")))return{issues:[d("bundle hook payload must contain both hooks.json and hooks/dispatch regular files",`hooks.json=${a!==void 0}, hooks/dispatch=${u.some(o=>o.path==="hooks/dispatch")}`,"both hooks.json and hooks/dispatch regular files","Add both required hook members or remove the hook payload.")]};const l=O(i.bytes);if(l.issue!==void 0)return{issues:[l.issue]};const h=W(c.bytes,s.reservedCoreNames,s.coreCommandPaths,s.extensibleCoreBranches);return h.commands===void 0?{issues:h.issues}:{bundle:{bundleVersion:1,...l.kinds!==void 0?{kinds:l.kinds}:{},...l.page_components!==void 0?{page_components:l.page_components}:{},...l.memory_extensions!==void 0?{memory_extensions:l.memory_extensions}:{},commands:h.commands,commandsBytes:c.bytes,directories:n.members.filter(o=>o.type==="directory").map(o=>({path:o.path})),memory:n.members.filter(o=>o.type==="file"&&o.path.startsWith("memory/")).map(o=>({path:o.path,bytes:o.bytes})),...a!==void 0?{hooks:{manifest:a.bytes,files:u.map(o=>({path:o.path,bytes:o.bytes}))}}:{}},issues:[]}}m(R,"validatePluginBundle");export{R as validatePluginBundle};
1
+ var p=Object.defineProperty;var m=(e,s)=>p(e,"name",{value:s,configurable:!0});import{Parser as b}from"tar";import{validateCommandManifest as y}from"../../api/command-manifest/manifest.js";import{invalidPluginKindsReasons as g}from"../config.js";import{invalidPageComponentsReasons as k,normalizePageComponents as v}from"../human/page-catalog.js";import{validateMemoryExtensionDeclarations as j}from"../plugin-extensions.js";function _(e,s,t,n,r,i){return{code:e,message:s,received:t,expected:n,next:r,...i!==void 0?{path:i}:{}}}m(_,"issue");function d(e,s,t,n,r){return _("plugin_bundle_invalid",e,s,t,n,r)}m(d,"bundleInvalid");function x(e){if(e[0]===31&&e[1]===139)return d("bundle archive must be uncompressed tar data","gzip-compressed archive","an uncompressed tar archive","Serve the archive without compression.");if(e.length===0||e.length%512!==0)return d("bundle archive must be a non-empty whole number of 512-byte tar blocks",`${e.length} bytes`,"a non-empty tar stream with a 512-byte block length","Serve one complete uncompressed tar archive.");if(e.length<1024||!e.subarray(-1024).every(s=>s===0))return d("bundle archive is missing the required two zero-block terminator","archive tail is not 1024 zero bytes","a complete tar stream ending in two 512-byte zero blocks","Serve the complete uncompressed tar archive.")}m(x,"archiveEnvelopeIssue");function S(e,s){if(e.length===0||e.includes("\0")||e.includes("\\")||e.startsWith("/")||/^[A-Za-z]:($|\/)/.test(e))return d("bundle member path must be a safe relative POSIX path",e,"a relative path without absolute, drive-letter, backslash, or NUL forms","Use a safe relative POSIX member path.",e);if(s==="file"&&e.endsWith("/"))return d("only directory members may have a trailing slash",e,"a regular-file path without a trailing slash","Emit this member as a regular file path.",e);if((s==="directory"&&e.endsWith("/")?e.slice(0,-1):e).split("/").some(n=>n===""||n==="."||n===".."))return d("bundle member path contains an unsafe segment",e,"non-empty segments other than . or ..","Use a safe relative POSIX member path.",e)}m(S,"validateMemberName");function w(e,s){if(s==="file")return e==="bundle.json"||e==="commands.json"||e==="hooks.json"||e.startsWith("memory/")&&e.endsWith(".md")||e.startsWith("hooks/")?void 0:d("bundle contains an unsupported file member",e,"bundle.json, commands.json, hooks.json, memory/**/*.md, or hooks/**","Remove unsupported members from the archive.",e);if(!(e==="memory"||e.startsWith("memory/")||e==="hooks"||e.startsWith("hooks/")))return d("bundle contains an unsupported directory member",e,"memory or hooks, or a directory below either subtree","Remove unsupported directory members from the archive.",e)}m(w,"validateMemberShape");function $(e){return e.type==="directory"&&e.path.endsWith("/")?e.path.slice(0,-1):e.path}m($,"materializedPath");function E(e){const s=new Map;for(const t of e){const n=$(t),r=s.get(n);if(r!==void 0)return d(r===t.type?"bundle contains a duplicate member":"bundle claims one path as both a file and a directory",`${n} (${r} and ${t.type})`,"each materialized path exactly once, with one type","Emit each archive path once, as a single member type.",n);s.set(n,t.type)}for(const[t,n]of s)if(n==="file"){for(const r of s.keys())if(r.startsWith(`${t}/`))return d("bundle nests a member beneath a regular-file path",`${r} beneath file ${t}`,"members nested only beneath directory paths","Emit the parent path as a directory or remove the nested member.",r)}}m(E,"validateMemberTree");async function N(e){const s=[],t=new Set;let n;return await new Promise((r,i)=>{const c=new b({strict:!0,maxMetaEntrySize:Number.MAX_SAFE_INTEGER,gzip:!1,brotli:!1,zstd:!1,onReadEntry:m(a=>{const u=a.path,f=a.type==="File"||a.type==="OldFile"?"file":a.type==="Directory"?"directory":void 0;if(f===void 0||a.unsupported||a.ignore||a.linkpath!==void 0){n??=d("bundle member must be a regular file or directory without a link target",`${u} (${a.type})`,"a regular file or directory member without link metadata","Remove links and unsupported member types from the archive.",u),a.resume();return}n??=S(u,f),n??=w(u,f),t.has(u)&&(n??=d("bundle contains a duplicate member",u,"each member path exactly once","Emit each archive member only once.",u)),t.add(u);const l=[];a.on("data",h=>l.push(h)),a.on("end",()=>{n===void 0&&s.push({path:u,type:f,bytes:new Uint8Array(Buffer.concat(l))})})},"onReadEntry")});c.on("ignoredEntry",a=>{const u=a.path;n??=d("bundle contains an ignored or unsupported archive member",`${u} (${a.type})`,"only supported regular file or directory members","Remove ignored or unsupported members from the archive.",u),a.resume()}),c.once("error",i),c.once("end",r);try{c.end(Buffer.from(e))}catch(a){i(a)}}).catch(r=>{n??=d("bundle archive could not be parsed",r instanceof Error?r.message:String(r),"a valid complete uncompressed tar archive","Fix the archive format and serve it again.")}),n===void 0?{members:s}:{issue:n}}m(N,"parseArchive");function O(e){let s;try{s=JSON.parse(Buffer.from(e).toString("utf8"))}catch{return{issue:d("bundle.json is not valid JSON","invalid JSON",'{"bundleVersion":1}',"Write valid bundle metadata.","bundle.json")}}if(typeof s!="object"||s===null||Array.isArray(s))return{issue:d("bundle.json must be a JSON object",JSON.stringify(s),"an object with bundleVersion set to 1 and optionally kinds",'Set bundle.json to {"bundleVersion":1}.',"bundle.json")};const t=s,n=Object.keys(t).filter(i=>i!=="bundleVersion"&&i!=="kinds"&&i!=="page_components"&&i!=="memory_extensions");if(t.bundleVersion!==1||n.length>0)return{issue:d("bundle.json must contain bundleVersion 1 and at most kinds, page_components, and memory_extensions blocks",JSON.stringify(s),"an object with bundleVersion set to 1 and optional kinds, page_components, and memory_extensions",'Set bundle.json to {"bundleVersion":1} plus optional contribution blocks.',"bundle.json")};if(t.kinds!==void 0){const i=g(t.kinds);if(i.length>0)return{issue:d("bundle.json kinds block is invalid",i.join("; "),"each entry a full KindConfig (whenToUse required) or a sparse patch of launch fields","Fix the kinds entries in bundle.json.","bundle.json")}}if(t.page_components!==void 0){const i=k(t.page_components);if(i.length>0)return{issue:d("bundle.json page_components block is invalid",i.join("; "),"an array of page component registrations, each a kind string or {kind, description?, useWhen?, doc?, display?}","Fix the page_components entries in bundle.json.","bundle.json")}}let r;if(t.memory_extensions!==void 0)try{r=j(t.memory_extensions)}catch(i){return{issue:d("bundle.json memory_extensions block is invalid",i instanceof Error?i.message:String(i),"a valid memory_extensions declaration object","Fix the memory_extensions declarations in bundle.json.","bundle.json")}}return{...t.kinds!==void 0?{kinds:t.kinds}:{},...t.page_components!==void 0?{page_components:v(t.page_components)}:{},...r!==void 0?{memory_extensions:r}:{}}}m(O,"parseBundleMetadata");function W(e,s,t,n=new Set){let r;try{r=JSON.parse(Buffer.from(e).toString("utf8"))}catch{return{issues:[d("commands.json is not valid JSON","invalid JSON","a valid command-manifest JSON object","Regenerate commands.json.","commands.json")]}}const i=y(r,{transport:"http",reservedCoreNames:s,extensibleCoreBranches:n,...t!==void 0?{coreCommandPaths:t}:{}});return{...i.manifest!==void 0?{commands:i.manifest}:{},issues:i.issues}}m(W,"parseCommands");async function R(e,s){const t=x(e);if(t!==void 0)return{issues:[t]};const n=await N(e);if(n.issue!==void 0||n.members===void 0)return{issues:[n.issue]};const r=E(n.members);if(r!==void 0)return{issues:[r]};const i=n.members.find(o=>o.path==="bundle.json"&&o.type==="file"),c=n.members.find(o=>o.path==="commands.json"&&o.type==="file");if(i===void 0||c===void 0)return{issues:[d("bundle must contain exactly one bundle.json and one commands.json regular file",`bundle.json=${i!==void 0}, commands.json=${c!==void 0}`,"one regular bundle.json and one regular commands.json member","Add the required metadata members to the archive.")]};const a=n.members.find(o=>o.path==="hooks.json"&&o.type==="file"),u=n.members.filter(o=>o.type==="file"&&o.path.startsWith("hooks/"));if((a!==void 0||n.members.some(o=>o.path==="hooks"||o.path.startsWith("hooks/")))&&(a===void 0||!u.some(o=>o.path==="hooks/dispatch")))return{issues:[d("bundle hook payload must contain both hooks.json and hooks/dispatch regular files",`hooks.json=${a!==void 0}, hooks/dispatch=${u.some(o=>o.path==="hooks/dispatch")}`,"both hooks.json and hooks/dispatch regular files","Add both required hook members or remove the hook payload.")]};const l=O(i.bytes);if(l.issue!==void 0)return{issues:[l.issue]};const h=W(c.bytes,s.reservedCoreNames,s.coreCommandPaths,s.extensibleCoreBranches);return h.commands===void 0?{issues:h.issues}:{bundle:{bundleVersion:1,...l.kinds!==void 0?{kinds:l.kinds}:{},...l.page_components!==void 0?{page_components:l.page_components}:{},...l.memory_extensions!==void 0?{memory_extensions:l.memory_extensions}:{},commands:h.commands,commandsBytes:c.bytes,directories:n.members.filter(o=>o.type==="directory").map(o=>({path:o.path})),memory:n.members.filter(o=>o.type==="file"&&o.path.startsWith("memory/")).map(o=>({path:o.path,bytes:o.bytes})),...a!==void 0?{hooks:{manifest:a.bytes,files:u.map(o=>({path:o.path,bytes:o.bytes}))}}:{}},issues:[]}}m(R,"validatePluginBundle");export{R as validatePluginBundle};
@@ -186,7 +186,7 @@ export declare function resolveKindConfig(kind: string): KindConfig | undefined;
186
186
  * its own top-level ancestor, e.g. `audit/security` defaults to
187
187
  * `['audit']`) includes `kind` or `'*'`. The single source both `sys
188
188
  * prompt-review --list`'s `subPersonas` metadata and the live sub-persona
189
- * spawn-menu splice (`core/substrate/render.ts`) read, so the two can never
189
+ * spawn-menu splice (`core/substrate/delivery/render-boot.ts`) read, so the two can never
190
190
  * drift apart. Sorted by full kind name for stable rendering. */
191
191
  export declare function subKindsAvailableTo(kind: string): {
192
192
  kind: string;
@@ -1,3 +1,5 @@
1
- var S=Object.defineProperty;var l=(i,r)=>S(i,"name",{value:r,configurable:!0});import{createServer as _}from"node:http";import{chmodSync as P,existsSync as v,unlinkSync as k}from"node:fs";import{isConversationNotFound as T}from"./index.js";import{resolveNodeToken as x}from"../canvas/node-tokens.js";import{conversationOwner as E}from"../canvas/sessions.js";import{peerUid as N}from"../../native/linux.js";async function w(i){const r=[];for await(const a of i)r.push(Buffer.from(a));return JSON.parse(Buffer.concat(r).toString("utf8"))}l(w,"body");function c(i,r,a){i.writeHead(r,{"content-type":"application/json"}),i.end(JSON.stringify(a))}l(c,"json");async function G(i,r){const a=_(async(o,n)=>{try{const s=o.headers.authorization,d=typeof s=="string"&&s.startsWith("Bearer ")?x(s.slice(7)):null;if(!d){c(n,401,{error:"unauthorized"});return}if(process.platform==="linux"){let e;try{e=N(o.socket)}catch{c(n,401,{error:"unauthorized"});return}if(e!==d.uid){c(n,401,{error:"unauthorized"});return}}const h=l(e=>E(e)===d.node,"owns"),f=l(()=>c(n,404,{error:"not_found"}),"notFound"),p=new URL(o.url??"/","http://store"),u=p.pathname.split("/").filter(Boolean);if(u[0]!=="conversations"){c(n,404,{error:"not_found"});return}const t=u[1];if(!t&&o.method==="POST"){const e=await w(o);if(e.node_id!==d.node){f();return}c(n,201,{conversation_id:r.create(e.node_id,e.header,e.entries,e.path)})}else if(!t&&o.method==="GET"){if(p.searchParams.has("node_id")&&p.searchParams.get("node_id")!==d.node){f();return}c(n,200,{conversations:r.list(d.node)})}else if(t&&u[2]==="entries"&&o.method==="POST"){if(!h(t)){f();return}const e=await w(o);r.append(t,e.entries),n.writeHead(204).end()}else if(t&&u[2]==="header"&&o.method==="GET"){if(!h(t)){f();return}c(n,200,r.header(t))}else if(t&&u[2]==="fork"&&o.method==="POST"){if(!h(t)){f();return}const e=await w(o);if(e.node_id!==d.node){f();return}c(n,201,{conversation_id:r.fork(t,d.node,e.leaf_id,e.cwd)})}else if(t&&u.length===2&&o.method==="GET"){if(!h(t)){f();return}const e=p.searchParams.get("head"),g=p.searchParams.get("tail"),m=r.read(t,e===null||g===null?void 0:{head:Number(e),tail:Number(g)});n.writeHead(200,{"content-type":"application/x-ndjson","x-conversation-path":m.path,...m.tail?{"x-conversation-tail":String(1+m.entries.length)}:{}}),n.end([m.header,...m.entries,...m.tail??[]].map(y=>JSON.stringify(y)).join(`
1
+ var _=Object.defineProperty;var p=(s,r)=>_(s,"name",{value:r,configurable:!0});import{createServer as N}from"node:http";import{chmodSync as T,existsSync as P,unlinkSync as k}from"node:fs";import{isConversationNotFound as E}from"./index.js";import{resolveNodeToken as O}from"../canvas/node-tokens.js";import{conversationOwner as b}from"../canvas/sessions.js";import{peerUid as H}from"../../native/linux.js";async function S(s){const r=[];for await(const d of s)r.push(Buffer.from(d));return JSON.parse(Buffer.concat(r).toString("utf8"))}p(S,"body");function i(s,r,d){s.writeHead(r,{"content-type":"application/json"}),s.end(JSON.stringify(d))}p(i,"json");async function C(s,r){const d=N(async(t,n)=>{try{const a=t.headers.authorization,c=typeof a=="string"&&a.startsWith("Bearer ")?O(a.slice(7)):null,y=new URL(t.url??"/","http://store"),m=y.pathname.split("/").filter(Boolean);if(a===void 0&&process.platform!=="linux"&&t.method==="GET"&&m[0]==="conversations"&&(m.length===1||m.length===2||m.length===3&&m[2]==="header")){const e=m[1];if(!e)i(n,200,{conversations:r.list(y.searchParams.get("node_id")??void 0)});else if(m[2]==="header")i(n,200,r.header(e));else{const w=y.searchParams.get("head"),u=y.searchParams.get("tail"),h=r.read(e,w===null||u===null?void 0:{head:Number(w),tail:Number(u)});n.writeHead(200,{"content-type":"application/x-ndjson","x-conversation-path":h.path,...h.tail?{"x-conversation-tail":String(1+h.entries.length)}:{}}),n.end([h.header,...h.entries,...h.tail??[]].map(x=>JSON.stringify(x)).join(`
2
2
  `)+`
3
- `)}else if(t&&u.length===2&&o.method==="PUT"){if(!h(t)){f();return}const e=await w(o);r.replace(t,e.header,e.entries),n.writeHead(204).end()}else if(t&&u.length===2&&o.method==="DELETE"){if(!h(t)){f();return}r.delete(t),n.writeHead(204).end()}else c(n,404,{error:"not_found"})}catch(s){const d=s instanceof Error?s.message:String(s);c(n,T(s)?404:500,{error:d})}});if(v(i)&&k(i),await new Promise((o,n)=>{a.once("error",n),a.listen(i,()=>{a.off("error",n),o()})}),typeof a.address()!="string")throw a.close(),new Error(`store listener must bind a unix socket: ${JSON.stringify(a.address())}`);return P(i,process.platform==="linux"&&v("/run/crtr/launcher.sock")?438:384),{close:l(()=>new Promise((o,n)=>a.close(s=>s?n(s):o())),"close")}}l(G,"listenConversationStore");export{G as listenConversationStore};
3
+ `)}return}if(!c){i(n,401,{error:"unauthorized"});return}if(process.platform==="linux"){let e;try{e=H(t.socket)}catch{i(n,401,{error:"unauthorized"});return}if(e!==c.uid){i(n,401,{error:"unauthorized"});return}}const g=p(e=>b(e)===c.node,"owns"),l=p(()=>i(n,404,{error:"not_found"}),"notFound"),v=new URL(t.url??"/","http://store"),f=v.pathname.split("/").filter(Boolean);if(f[0]!=="conversations"){i(n,404,{error:"not_found"});return}const o=f[1];if(!o&&t.method==="POST"){const e=await S(t);if(e.node_id!==c.node){l();return}i(n,201,{conversation_id:r.create(e.node_id,e.header,e.entries,e.path)})}else if(!o&&t.method==="GET"){if(v.searchParams.has("node_id")&&v.searchParams.get("node_id")!==c.node){l();return}i(n,200,{conversations:r.list(c.node)})}else if(o&&f[2]==="entries"&&t.method==="POST"){if(!g(o)){l();return}const e=await S(t);r.append(o,e.entries),n.writeHead(204).end()}else if(o&&f[2]==="header"&&t.method==="GET"){if(!g(o)){l();return}i(n,200,r.header(o))}else if(o&&f[2]==="fork"&&t.method==="POST"){if(!g(o)){l();return}const e=await S(t);if(e.node_id!==c.node){l();return}i(n,201,{conversation_id:r.fork(o,c.node,e.leaf_id,e.cwd)})}else if(o&&f.length===2&&t.method==="GET"){if(!g(o)){l();return}const e=v.searchParams.get("head"),w=v.searchParams.get("tail"),u=r.read(o,e===null||w===null?void 0:{head:Number(e),tail:Number(w)});n.writeHead(200,{"content-type":"application/x-ndjson","x-conversation-path":u.path,...u.tail?{"x-conversation-tail":String(1+u.entries.length)}:{}}),n.end([u.header,...u.entries,...u.tail??[]].map(h=>JSON.stringify(h)).join(`
4
+ `)+`
5
+ `)}else if(o&&f.length===2&&t.method==="PUT"){if(!g(o)){l();return}const e=await S(t);r.replace(o,e.header,e.entries),n.writeHead(204).end()}else if(o&&f.length===2&&t.method==="DELETE"){if(!g(o)){l();return}r.delete(o),n.writeHead(204).end()}else i(n,404,{error:"not_found"})}catch(a){const c=a instanceof Error?a.message:String(a);i(n,E(a)?404:500,{error:c})}});if(P(s)&&k(s),await new Promise((t,n)=>{d.once("error",n),d.listen(s,()=>{d.off("error",n),t()})}),typeof d.address()!="string")throw d.close(),new Error(`store listener must bind a unix socket: ${JSON.stringify(d.address())}`);return T(s,process.platform==="linux"&&P("/run/crtr/launcher.sock")?438:384),{close:p(()=>new Promise((t,n)=>d.close(a=>a?n(a):t())),"close")}}p(C,"listenConversationStore");export{C as listenConversationStore};
@@ -11,6 +11,10 @@ export interface PushOpts {
11
11
  disposition?: InboxDisposition;
12
12
  /** Final only. The outcome the canonical final records; absent means `result`/`finalized`. */
13
13
  outcome?: FinalOutcome;
14
+ /** Update only: this report answers a one-off structured-output request (`report.result`). */
15
+ result?: {
16
+ requestMessageId: string | null;
17
+ };
14
18
  }
15
19
  /** A declined structured result: the node finishes, but its latch records a failure. */
16
20
  export interface FinalOutcome {
@@ -19,13 +23,15 @@ export interface FinalOutcome {
19
23
  detailJson: string | null;
20
24
  }
21
25
  export interface PushResult {
22
- reportPath: string;
26
+ /** `<nodeId>/reports/<name>` — the report document's ref. */
27
+ report: string;
28
+ reportId: string;
23
29
  deliveredTo: string[];
24
30
  }
25
31
  export declare class FinalizationError extends Error {
26
32
  readonly code: 'already_finalized' | 'finalization_forbidden' | 'unknown_node';
27
- readonly reportPath?: string | undefined;
28
- constructor(code: 'already_finalized' | 'finalization_forbidden' | 'unknown_node', reportPath?: string | undefined);
33
+ readonly report?: string | undefined;
34
+ constructor(code: 'already_finalized' | 'finalization_forbidden' | 'unknown_node', report?: string | undefined);
29
35
  }
30
36
  export declare function push(nodeId: string, opts: PushOpts): Promise<PushResult>;
31
37
  export declare function pushUpdate(nodeId: string, body: string, opts?: {
@@ -39,7 +45,3 @@ export declare function pushFinal(nodeId: string, body: string, opts?: {
39
45
  from?: string;
40
46
  disposition?: InboxDisposition;
41
47
  }): Promise<PushResult>;
42
- /** Re-fan a previously committed final to its ticket origin without finalizing again. */
43
- export declare function redeliverFinalReport(nodeId: string, originNodeId: string, reportBasename: string, body: string, opts?: {
44
- disposition?: InboxDisposition;
45
- }): PushResult;
@@ -1,7 +1,3 @@
1
- var U=Object.defineProperty;var o=(n,e)=>U(n,"name",{value:e,configurable:!0});import{dirname as L,join as E}from"node:path";import{randomUUID as O}from"node:crypto";import{cancelCronsOnWake as x,getNode as p}from"../canvas/index.js";import{nodeAgentDir as M,reportsDir as R}from"../canvas/node-agent-paths.js";import{createFileBeneath as F,fsyncDirBeneath as J,linkBeneath as W,unlinkBeneath as z}from"../spaces/open-beneath.js";import{openDb as A,withCanvasWrite as H}from"../canvas/db.js";import{activateArmedExternalActionDelivery as B,readExternalActionDelivery as Y}from"../canvas/deliveries.js";import{composeNodeOutcomeDocument as K}from"../runtime/outcome-document.js";import{closeNode as j}from"../runtime/close.js";import{enqueueSubscriberMail as q}from"./messages.js";import{operationIdContext as P}from"../events/operation-id.js";class h extends Error{static{o(this,"FinalizationError")}code;reportPath;constructor(e,r){super(e),this.code=e,this.reportPath=r}}function G(n){const e=o((r,i=2)=>String(r).padStart(i,"0"),"pad");return`${n.getUTCFullYear()}${e(n.getUTCMonth()+1)}${e(n.getUTCDate())}T${e(n.getUTCHours())}${e(n.getUTCMinutes())}${e(n.getUTCSeconds())}${e(n.getUTCMilliseconds(),3)}`}o(G,"compactTs");function Q(n,e,r){const i=M(n),c=R(n),u=new Date,s=`${G(u)}-${O().slice(-8)}-${e}.md`,a=E(c,s),d=E(c,`.${s}.${O()}.tmp`),t=u.toISOString();return F(i,d,`---
2
- node: ${n}
3
- kind: ${e}
4
- ts: ${t}
5
- ---
6
- ${r}`),{root:i,finalPath:a,stagedPath:d,basename:s,ts:t}}o(Q,"stageReport");function f(n,e){try{z(n.root,e)}catch(r){if(r.code!=="ENOENT")throw r}}o(f,"remove");function S(n){let e=!1;try{W(n.root,n.stagedPath,n.finalPath),e=!0,f(n,n.stagedPath),J(n.root,L(n.finalPath))}catch(r){throw e&&f(n,n.finalPath),r}}o(S,"install");function V(n,e=80){const r=n.split(`
7
- `)[0]??"";return r.length>e?`${r.slice(0,e-1)}\u2026`:r}o(V,"firstLine");function X(n,e){return e??(n==="urgent"?"urgent":"normal")}o(X,"tierFor");function Z(n){const e=Y(`node-outcome:${n}`);if(e===null)return null;const r=e.adapter;if(r?.adapter!=="subprocess"||!Array.isArray(r.argv)||!r.argv.every(i=>typeof i=="string")||typeof r.cwd!="string")throw new Error(`outcome delivery ${e.deliveryId} has an invalid subprocess adapter`);return{name:e.destinationId,payload:r.payload??null}}o(Z,"outcomeAction");function y(n,e,r,i,c,u,s,a){return q(n,{kind:i,label:V(s),senderNodeId:e,senderName:r,bodyRef:u,urgency:X(i,c),...a===void 0?{}:{disposition:a}}).map(d=>d.destinationNodeId)}o(y,"enqueueReport");function I(n,e,r,i,c,u,s){const a=A();let d=!1;a.exec("BEGIN IMMEDIATE");try{const t=a.prepare("SELECT status, final_report FROM nodes WHERE node_id = ?").get(n);if(t===void 0)throw new h("unknown_node");if(t.final_report!==null)throw new h("already_finalized",t.final_report);if(t.status==="canceled"||t.status==="dead")throw new h("finalization_forbidden");if(t.status!=="active"&&t.status!=="idle"&&t.status!=="done")throw new h("finalization_forbidden");const l=a.prepare("SELECT e.from_id AS node_id, e.active, e.created FROM edges e JOIN nodes source ON source.node_id = e.to_id JOIN nodes subscriber ON subscriber.node_id = e.from_id WHERE e.type = 'subscribes_to' AND e.to_id = ? AND subscriber.grantee = source.grantee AND (source.run_id IS NULL OR subscriber.run_id = source.run_id) ORDER BY e.created").all(n).map(b=>({node_id:b.node_id,active:b.active===1,created:b.created})),m=p(n),N=m?.kind!=="human",k=(m?.outcome_revision??0)+1,D=s?.kind??"result",_=s?.reason??"finalized",$=s?.detailJson??null,T=m===null?null:Z(n),w=!N||T===null||m===null?null:JSON.stringify(K({node:{...m,status:"done",intent:"done",terminal_reason:_},outcome:{kind:D,reason:_,at:e.ts,revision:k,detailJson:$},action:T,finalReport:e.basename}));S(e),d=!0,N?(a.prepare("UPDATE nodes SET status = 'done', intent = 'done', terminal_reason = ?, final_report = ?, finalized_at = ?, outcome_kind = ?, outcome_reason = ?, outcome_at = ?, outcome_revision = outcome_revision + 1, outcome_detail_json = ? WHERE node_id = ? AND final_report IS NULL").run(_,e.basename,e.ts,D,_,e.ts,$,n),w!==null&&B(a,{idempotencyKey:`node-outcome:${n}`,label:n,bodyJson:w,supersede:!0},Date.now())):a.prepare("UPDATE nodes SET status = 'done', intent = 'done', terminal_reason = 'finalized', final_report = ?, finalized_at = ? WHERE node_id = ? AND final_report IS NULL").run(e.basename,e.ts,n);const g=y(l,i,c,"final",void 0,`${n}:reports/${e.basename}`,r,u);return a.exec("COMMIT"),{deliveredTo:g}}catch(t){throw a.exec("ROLLBACK"),d&&f(e,e.finalPath),t}finally{f(e,e.stagedPath)}}o(I,"commitCanonicalFinal");async function C(n,e){if(!n)throw new Error(`push: empty nodeId (kind=${e.kind}) \u2014 a report must belong to a node`);if(e.kind==="final"&&e.deliveryTier!==void 0)throw new Error("push final does not accept a delivery tier");if(e.kind!=="final"&&e.outcome!==void 0)throw new Error("push outcome is final-only");const r=Q(n,e.kind,e.body),i=e.from??n,c=p(i)?.name;if(e.kind==="final"){const{deliveredTo:s}=I(n,r,e.body,i,c,e.disposition,e.outcome);if(x(n),p(n)?.run_id===n){const d=A().prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ? ORDER BY created DESC").all(n,n);for(const t of d){const l=p(t.node_id);l&&l.status!=="done"&&l.status!=="canceled"&&l.status!=="dead"&&j(t.node_id,{preserveEmpty:!0})}}return{reportPath:r.finalPath,deliveredTo:s}}let u=!1;try{S(r),u=!0;const s=H(a=>{const d=a.prepare("SELECT e.from_id AS node_id, e.active, e.created FROM edges e JOIN nodes source ON source.node_id = e.to_id JOIN nodes subscriber ON subscriber.node_id = e.from_id WHERE e.type = 'subscribes_to' AND e.to_id = ? AND subscriber.grantee = source.grantee AND (source.run_id IS NULL OR subscriber.run_id = source.run_id) ORDER BY e.created").all(n).map(t=>({node_id:t.node_id,active:t.active===1,created:t.created}));return y(d,i,c,e.kind,e.deliveryTier,`${n}:reports/${r.basename}`,e.body,e.disposition)});return{reportPath:r.finalPath,deliveredTo:s}}catch(s){throw u&&f(r,r.finalPath),s}finally{f(r,r.stagedPath)}}o(C,"pushWithContext");function v(n,e){return P.current()===void 0?P.fresh(()=>C(n,e)):C(n,e)}o(v,"push");async function fe(n,e,r){return v(n,{kind:"update",body:e,...r})}o(fe,"pushUpdate");async function me(n,e,r){return v(n,{kind:"urgent",body:e,...r})}o(me,"pushUrgent");async function pe(n,e,r){return v(n,{kind:"final",body:e,...r})}o(pe,"pushFinal");function _e(n,e,r,i,c){if(r===""||r.includes("/")||r.includes("\\"))throw new Error(`invalid canonical final report basename: ${r}`);const u=y([{node_id:e,active:!0,created:""}],n,p(n)?.name,"final",void 0,`${n}:reports/${r}`,i,c?.disposition);return{reportPath:E(R(n),r),deliveredTo:u}}o(_e,"redeliverFinalReport");export{h as FinalizationError,v as push,pe as pushFinal,fe as pushUpdate,me as pushUrgent,_e as redeliverFinalReport};
1
+ var $=Object.defineProperty;var o=(e,n)=>$(e,"name",{value:n,configurable:!0});import{cancelCronsOnWake as C,getNode as p}from"../canvas/index.js";import{openDb as E,withCanvasWrite as R}from"../canvas/db.js";import{randomUUID as A}from"node:crypto";import{activateArmedExternalActionDelivery as b,readExternalActionDelivery as U}from"../canvas/deliveries.js";import{composeNodeOutcomeDocument as N}from"../runtime/outcome-document.js";import{closeNode as O}from"../runtime/close.js";import{put as x}from"../graph/bodies.js";import{writeDocument as M}from"../graph/documents.js";import{publish as S}from"../graph/events.js";import{nodeObject as h}from"../graph/objects.js";import{readerForNode as F}from"../graph/reader.js";import{endMessageSubscriptions as w}from"../graph/watches.js";import{operationIdContext as g}from"../events/operation-id.js";class _ extends Error{static{o(this,"FinalizationError")}code;report;constructor(n,r){super(n),this.code=n,this.report=r}}function L(e){const n=o((r,t=2)=>String(r).padStart(t,"0"),"pad");return`${e.getUTCFullYear()}${n(e.getUTCMonth()+1)}${n(e.getUTCDate())}T${n(e.getUTCHours())}${n(e.getUTCMinutes())}${n(e.getUTCSeconds())}${n(e.getUTCMilliseconds(),3)}`}o(L,"compactTs");function T(e,n=80){const r=e.split(`
2
+ `)[0]??"";return r.length>n?`${r.slice(0,n-1)}\u2026`:r}o(T,"firstLine");function W(e){return e.kind==="final"?{event:"report.final",level:7}:e.result!==void 0?{event:"report.result",level:5}:e.kind==="urgent"?{event:"report.update",level:7}:{event:"report.update",level:e.deliveryTier==="deferred"?3:e.deliveryTier==="urgent"?7:5}}o(W,"eventFor");function z(e){const n=U(`node-outcome:${e}`);if(n===null)return null;const r=n.adapter;if(r?.adapter!=="subprocess"||!Array.isArray(r.argv)||!r.argv.every(t=>typeof t=="string")||typeof r.cwd!="string")throw new Error(`outcome delivery ${n.deliveryId} has an invalid subprocess adapter`);return{name:n.destinationId,payload:r.payload??null}}o(z,"outcomeAction");function k(e,n,r){const t=r.from??n,a=`reports/${L(new Date)}-${A().slice(-8)}-${r.kind}`,i=h(e,n),s=h(e,t),{object:d}=M(e,F(e,t,()=>[]),{owner:i,kind:"report",name:a,preview:T(r.body)||r.kind,privacy:"public"},r.body),u=`${n}/${a}`,{event:l,level:f}=W(r);S(e,{event:l,object:i,actor:s,level:f,attrs:{},pointer:d.id,messageBody:{kind:r.kind,label:T(r.body),bodyRef:u,...r.disposition===void 0?{}:{disposition:r.disposition}}});const c=e.prepare(`SELECT d.destination_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
3
+ WHERE m.body_ref = ? AND d.destination_kind = 'node_inbox' ORDER BY d.destination_id`).all(u).map(m=>m.destination_id);return r.kind==="final"?w(e,i,"final"):r.result?.requestMessageId&&w(e,i,{result:r.result.requestMessageId}),{name:a,ref:u,doc:d,createdAt:d.created_at,deliveredTo:c}}o(k,"writeReport");function J(e,n){const r=E();r.exec("BEGIN IMMEDIATE");try{const t=r.prepare("SELECT status, final_report FROM nodes WHERE node_id = ?").get(e);if(t===void 0)throw new _("unknown_node");if(t.final_report!==null)throw new _("already_finalized",`${e}/${t.final_report}`);if(t.status!=="active"&&t.status!=="idle"&&t.status!=="done")throw new _("finalization_forbidden");const a=k(r,e,n),i=p(e),s=i?.kind!=="human",d=(i?.outcome_revision??0)+1,u=n.outcome?.kind??"result",l=n.outcome?.reason??"finalized",f=n.outcome?.detailJson??null,c=a.createdAt;if(s){const m=i===null?null:z(e),y=m===null||i===null?null:JSON.stringify(N({node:{...i,status:"done",intent:"done",terminal_reason:l},outcome:{kind:u,reason:l,at:c,revision:d,detailJson:f},action:m,finalReport:a.name}));r.prepare("UPDATE nodes SET status = 'done', intent = 'done', terminal_reason = ?, final_report = ?, finalized_at = ?, outcome_kind = ?, outcome_reason = ?, outcome_at = ?, outcome_revision = outcome_revision + 1, outcome_detail_json = ? WHERE node_id = ? AND final_report IS NULL").run(l,a.name,c,u,l,c,f,e),y!==null&&b(r,{idempotencyKey:`node-outcome:${e}`,label:e,bodyJson:y,supersede:!0},Date.now())}else r.prepare("UPDATE nodes SET status = 'done', intent = 'done', terminal_reason = 'finalized', final_report = ?, finalized_at = ? WHERE node_id = ? AND final_report IS NULL").run(a.name,c,e);return r.exec("COMMIT"),a}catch(t){throw r.exec("ROLLBACK"),t}}o(J,"commitCanonicalFinal");async function D(e,n){if(!e)throw new Error(`push: empty nodeId (kind=${n.kind}) \u2014 a report must belong to a node`);if(n.kind==="final"&&n.deliveryTier!==void 0)throw new Error("push final does not accept a delivery tier");if(n.kind!=="final"&&n.outcome!==void 0)throw new Error("push outcome is final-only");if(n.kind!=="update"&&n.result!==void 0)throw new Error("a one-off result is an update report");if(x(n.body),n.kind==="final"){const t=J(e,n);if(C(e),p(e)?.run_id===e){const i=E().prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ? ORDER BY created DESC").all(e,e);for(const s of i){const d=p(s.node_id);d&&d.status!=="done"&&d.status!=="canceled"&&d.status!=="dead"&&O(s.node_id,{preserveEmpty:!0})}}return{report:t.ref,reportId:t.doc.id,deliveredTo:t.deliveredTo}}const r=R(t=>k(t,e,n));return{report:r.ref,reportId:r.doc.id,deliveredTo:r.deliveredTo}}o(D,"pushWithContext");function v(e,n){return g.current()===void 0?g.fresh(()=>D(e,n)):D(e,n)}o(v,"push");async function ne(e,n,r){return v(e,{kind:"update",body:n,...r})}o(ne,"pushUpdate");async function re(e,n,r){return v(e,{kind:"urgent",body:n,...r})}o(re,"pushUrgent");async function te(e,n,r){return v(e,{kind:"final",body:n,...r})}o(te,"pushFinal");export{_ as FinalizationError,v as push,te as pushFinal,ne as pushUpdate,re as pushUrgent};
@@ -22,11 +22,9 @@ export interface InboxEntry {
22
22
  }
23
23
  /** Project the immutable message body and destination-specific urgency into the canonical inbox rendering shape. */
24
24
  export declare function nodeMailEntry(delivery: ClaimedNodeMail): InboxEntry;
25
- /** Clip a body to the bounded preview stored beside a spilled message body. */
26
- export declare function clipBody(body: string): {
27
- text: string;
28
- clipped: boolean;
29
- };
25
+ /** The newest head body of the report document a message points at, or null when the entry
26
+ * is not a report or the document is gone. */
27
+ export declare function reportDocumentBody(objectId: string): string | null;
30
28
  export interface InboxDelivery {
31
29
  kind: 'human' | 'card';
32
30
  text: string;
@@ -1,10 +1 @@
1
- var m=Object.defineProperty;var r=(n,e)=>m(n,"name",{value:e,configurable:!0});import{resolveRef as b}from"../canvas/history.js";import{validateOperationId as h}from"../events/operation-id.js";import{formatInboxCard as I,formatInboxRefInstruction as l}from"../../shared/generated-context.js";import{renderBirthAnnouncementBody as g}from"../../shared/birth-announcement.js";const x=/^(?!0{32}$)[0-9a-f]{32}$/;function _(n){if(typeof n!="string"||!x.test(n))throw new TypeError("entry_id must be 32 lowercase non-zero hexadecimal characters");return n}r(_,"validateInboxEntryId");function w(n){const e=n.message;return{entry_id:_(e.messageId),operation_id:h(e.operationId),ts:e.createdAt,from:e.senderNodeId,...e.senderName===null?{}:{from_name:e.senderName},tier:n.urgency,kind:e.kind,...e.bodyRef===null?{}:{ref:e.bodyRef},label:e.label,...e.bodyJson===null?{}:{data:e.bodyJson},...e.disposition===null?{}:{disposition:e.disposition}}}r(w,"nodeMailEntry");const u=12,a=1e3,y=1e3;function E(n){let e=n,t=!1;const i=e.split(`
2
- `);return i.length>u&&(e=i.slice(0,u).join(`
3
- `),t=!0),e.length>a&&(e=e.slice(0,a),t=!0),{text:e.trimEnd(),clipped:t}}r(E,"clipBody");function p(n){const e=typeof n.data?.body=="string"?n.data.body.trim():"";return e===""||e===n.label?"":e}r(p,"inlineBody");function R(n){if(n.ref===void 0||n.ref.startsWith("/"))return null;try{const e=b(n.ref);return e?.source!=="report"||e.path===null||e.body.length>=y?null:e.body}catch{return null}}r(R,"inlineReport");function $(n){const e=g(n.data,n.ts);if(e!==null)return e;const t=R(n);if(t!==null)return`${t.trimEnd()}
4
-
5
- ${l(n.ref)}`;const i=p(n);if(i==="")return n.ref===void 0?n.label:`${n.label}
6
-
7
- ${l(n.ref)}`;const{text:s,clipped:o}=E(i);return n.ref!==void 0?`${s}
8
-
9
- ${l(n.ref)}`:o?`${s}
10
- \u2026 (body clipped)`:s}r($,"entryBody");function B(n){return{kind:n.kind,body:$(n),...n.ref===void 0?{}:{ref:n.ref},...n.disposition===void 0?{}:{disposition:n.disposition}}}r(B,"cardEntry");function S(n){if(n.length===0)return[];const e=new Map;for(const o of n){const d=o.from??"system";e.has(d)||e.set(d,[]),e.get(d).push(o)}const t=[],i=[];let s=-1;for(const[o,d]of e){if(o==="human"){for(const f of d){const c=p(f);t.push({kind:"human",text:c===""?f.label:c,entries:[f]})}continue}s<0&&(s=t.length,t.push({kind:"card",text:"",entries:[]})),i.push({id:o,entries:d.map(B)})}return s>=0&&(t[s]={kind:"card",text:I(i),entries:n.filter(o=>(o.from??"system")!=="human")}),t}r(S,"coalesce");export{E as clipBody,S as coalesce,w as nodeMailEntry};
1
+ var c=Object.defineProperty;var r=(o,e)=>c(o,"name",{value:e,configurable:!0});import{openDb as u}from"../canvas/db.js";import{heads as p}from"../graph/documents.js";import{getById as l}from"../graph/objects.js";import{bodyOf as m}from"../graph/bodies.js";import{validateOperationId as h}from"../events/operation-id.js";import{formatInboxCard as y}from"../../shared/generated-context.js";import{inlineBody as b,renderEntryBody as I,reportRefNodeId as g}from"../../shared/inbox-entry-body.js";const E=/^(?!0{32}$)[0-9a-f]{32}$/;function _(o){if(typeof o!="string"||!E.test(o))throw new TypeError("entry_id must be 32 lowercase non-zero hexadecimal characters");return o}r(_,"validateInboxEntryId");function C(o){const e=o.message;return{entry_id:_(e.messageId),operation_id:h(e.operationId),ts:e.createdAt,from:e.senderNodeId,...e.senderName===null?{}:{from_name:e.senderName},tier:o.urgency,kind:e.kind,...e.bodyRef===null?{}:{ref:e.bodyRef},label:e.label,...e.bodyJson===null?{}:{data:e.bodyJson},...e.disposition===null?{}:{disposition:e.disposition}}}r(C,"nodeMailEntry");function x(o){const e=u(),n=l(e,o);if(n===null||n.type!=="document"||n.deleted_at!==null)return null;const s=p(e,n)[0];if(s===void 0)return null;const d=e.prepare("SELECT source_path FROM documents WHERE object = ?").get(n.rowid);return m(s.body_hash,d?.source_path??null)}r(x,"reportDocumentBody");function k(o){const e=o.data?.push?.object?.id,n=g(o.ref)!==void 0&&e!==void 0?x(e):null;return I(o,n)}r(k,"entryBody");function B(o){return{kind:o.kind,body:k(o),...o.ref===void 0?{}:{ref:o.ref},...o.disposition===void 0?{}:{disposition:o.disposition}}}r(B,"cardEntry");function J(o){if(o.length===0)return[];const e=new Map;for(const t of o){const i=t.from??"system";e.has(i)||e.set(i,[]),e.get(i).push(t)}const n=[],s=[];let d=-1;for(const[t,i]of e){if(t==="human"){for(const f of i){const a=b(f);n.push({kind:"human",text:a===""?f.label:a,entries:[f]})}continue}d<0&&(d=n.length,n.push({kind:"card",text:"",entries:[]})),s.push({id:t,entries:i.map(B)})}return d>=0&&(n[d]={kind:"card",text:y(s),entries:o.filter(t=>(t.from??"system")!=="human")}),n}r(J,"coalesce");export{J as coalesce,C as nodeMailEntry,x as reportDocumentBody};