@north-light/crouter 0.3.353 → 0.3.355

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (626) hide show
  1. package/dist/api/client.d.ts +35 -25
  2. package/dist/api/client.js +2 -2
  3. package/dist/api/dto/broker-ops.d.ts +2 -36
  4. package/dist/api/dto/canvas.d.ts +8 -13
  5. package/dist/api/dto/config.d.ts +4 -0
  6. package/dist/api/dto/delivery.d.ts +61 -0
  7. package/dist/api/dto/docs.d.ts +135 -0
  8. package/dist/api/dto/docs.js +1 -0
  9. package/dist/api/dto/health.d.ts +26 -79
  10. package/dist/api/dto/node-outcomes.d.ts +1 -3
  11. package/dist/api/dto/nodes.d.ts +5 -26
  12. package/dist/api/dto/objects.d.ts +168 -0
  13. package/dist/api/dto/objects.js +1 -0
  14. package/dist/api/dto/profiles.d.ts +14 -8
  15. package/dist/api/dto/reports.d.ts +9 -7
  16. package/dist/api/dto/reviews.d.ts +11 -3
  17. package/dist/api/dto/worktree.d.ts +1 -1
  18. package/dist/api/index.d.ts +0 -1
  19. package/dist/api/index.js +1 -1
  20. package/dist/api/routes.d.ts +14 -12
  21. package/dist/api/routes.js +1 -1
  22. package/dist/build-root.js +1 -1
  23. package/dist/builtin-memory/00-runtime-base/00-authoring.md +10 -5
  24. package/dist/builtin-memory/02-turn-lifecycle/02-resident.md +1 -0
  25. package/dist/builtin-memory/04-orchestration-kernel.md +10 -31
  26. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +1 -1
  27. package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
  28. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +2 -2
  29. package/dist/builtin-memory/crouter-concepts/INDEX.md +2 -2
  30. package/dist/builtin-memory/crouter-concepts/lifecycle-and-wakes.md +1 -1
  31. package/dist/builtin-memory/crouter-concepts/memory.md +15 -15
  32. package/dist/builtin-memory/crouter-concepts/nodes-and-the-canvas.md +1 -1
  33. package/dist/builtin-memory/crouter-concepts/profiles-kinds-and-modes.md +5 -5
  34. package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +1 -1
  35. package/dist/builtin-memory/crouter-concepts/why-a-daemon.md +1 -1
  36. package/dist/builtin-memory/crouter-sdk/INDEX.md +2 -2
  37. package/dist/builtin-memory/crouter-sdk/README.md +5 -6
  38. package/dist/builtin-memory/crouter-sdk/errors.md +0 -13
  39. package/dist/builtin-memory/crouter-sdk/guides/README.md +0 -1
  40. package/dist/builtin-memory/crouter-sdk/guides/event-driven-assistant.md +2 -2
  41. package/dist/builtin-memory/crouter-sdk/nodes.md +0 -2
  42. package/dist/builtin-memory/crouter-sdk/resources.md +0 -1
  43. package/dist/builtin-memory/explore/exploration-doc.md +4 -4
  44. package/dist/builtin-memory/insights/capture.md +6 -6
  45. package/dist/builtin-memory/insights/init.md +14 -14
  46. package/dist/builtin-memory/internal/INDEX.md +4 -4
  47. package/dist/builtin-memory/internal/agent-shaping.md +20 -20
  48. package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
  49. package/dist/builtin-memory/internal/marketplaces.md +2 -2
  50. package/dist/builtin-memory/internal/memory-loading.md +31 -30
  51. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  52. package/dist/builtin-memory/internal/plugins.md +16 -14
  53. package/dist/builtin-memory/internal/storage-tiers.md +4 -4
  54. package/dist/builtin-memory/memory-read-orientation.md +1 -1
  55. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +32 -40
  56. package/dist/clients/attach/input/controller.js +1 -1
  57. package/dist/clients/attach/input/ref-autocomplete.js +1 -1
  58. package/dist/clients/attach/input/titled-editor.js +1 -1
  59. package/dist/clients/attach/overlays/file-review.d.ts +1 -0
  60. package/dist/clients/attach/overlays/file-review.js +2 -2
  61. package/dist/clients/attach/render/chat-view.d.ts +6 -0
  62. package/dist/clients/attach/render/chat-view.js +2 -2
  63. package/dist/clients/attach/render/crtr-output.d.ts +1 -2
  64. package/dist/clients/attach/render/crtr-output.js +17 -17
  65. package/dist/clients/attach/render/doc-links.d.ts +34 -0
  66. package/dist/clients/attach/render/doc-links.js +1 -0
  67. package/dist/clients/attach/render/group-activity.d.ts +8 -8
  68. package/dist/clients/attach/render/group-activity.js +2 -2
  69. package/dist/clients/attach/render/group-recap.js +1 -1
  70. package/dist/clients/attach/render/markdown-source.js +5 -5
  71. package/dist/clients/attach/render/tool-calls.d.ts +1 -1
  72. package/dist/clients/attach/session/doc-materialize.d.ts +53 -0
  73. package/dist/clients/attach/session/doc-materialize.js +3 -0
  74. package/dist/clients/attach/session/document-links.d.ts +21 -0
  75. package/dist/clients/attach/session/document-links.js +1 -0
  76. package/dist/clients/attach/session/file-links.d.ts +2 -0
  77. package/dist/clients/attach/session/file-links.js +1 -1
  78. package/dist/clients/attach/session/profile-files.js +1 -1
  79. package/dist/clients/attach/slash/dispatch.js +1 -1
  80. package/dist/clients/attach/viewer.js +816 -1561
  81. package/dist/clients/inbox/review/review-client.d.ts +5 -1
  82. package/dist/clients/inbox/review/review-client.js +1 -1
  83. package/dist/commands/api-client.d.ts +2 -0
  84. package/dist/commands/api-client.js +3 -3
  85. package/dist/commands/canvas/edges.d.ts +2 -0
  86. package/dist/commands/canvas/edges.js +2 -0
  87. package/dist/commands/canvas/list.d.ts +4 -0
  88. package/dist/commands/canvas/list.js +3 -0
  89. package/dist/commands/canvas/read.d.ts +8 -0
  90. package/dist/commands/canvas/read.js +5 -0
  91. package/dist/commands/canvas/search.d.ts +2 -0
  92. package/dist/commands/canvas/search.js +3 -0
  93. package/dist/commands/canvas/unwatch.d.ts +2 -0
  94. package/dist/commands/canvas/unwatch.js +1 -0
  95. package/dist/commands/canvas/watch.d.ts +3 -0
  96. package/dist/commands/canvas/watch.js +1 -0
  97. package/dist/commands/canvas-analytics.js +1 -1
  98. package/dist/commands/canvas-history/grep.js +4 -4
  99. package/dist/commands/canvas-history/read.js +2 -2
  100. package/dist/commands/canvas-history/search.js +7 -7
  101. package/dist/commands/canvas-history/shared.d.ts +0 -1
  102. package/dist/commands/canvas-history/shared.js +1 -1
  103. package/dist/commands/canvas-history/stats.js +2 -2
  104. package/dist/commands/canvas-history.js +1 -1
  105. package/dist/commands/canvas.js +1 -1
  106. package/dist/commands/doc/delete.d.ts +2 -0
  107. package/dist/commands/doc/delete.js +1 -0
  108. package/dist/commands/doc/edit.d.ts +2 -0
  109. package/dist/commands/doc/edit.js +1 -0
  110. package/dist/commands/doc/history.d.ts +2 -0
  111. package/dist/commands/doc/history.js +2 -0
  112. package/dist/commands/doc/lint.d.ts +2 -0
  113. package/dist/commands/doc/lint.js +2 -0
  114. package/dist/commands/doc/list.d.ts +2 -0
  115. package/dist/commands/doc/list.js +1 -0
  116. package/dist/commands/doc/move.d.ts +2 -0
  117. package/dist/commands/doc/move.js +1 -0
  118. package/dist/commands/doc/read.d.ts +2 -0
  119. package/dist/commands/doc/read.js +1 -0
  120. package/dist/commands/doc/shared.d.ts +25 -0
  121. package/dist/commands/doc/shared.js +2 -0
  122. package/dist/commands/doc/write.d.ts +2 -0
  123. package/dist/commands/doc/write.js +1 -0
  124. package/dist/commands/{memory.d.ts → doc.d.ts} +1 -1
  125. package/dist/commands/doc.js +1 -0
  126. package/dist/commands/human/review.js +1 -1
  127. package/dist/commands/node/bash.js +2 -2
  128. package/dist/commands/node/create.js +1 -1
  129. package/dist/commands/node/inspect.js +10 -10
  130. package/dist/commands/node/lifecycle.js +2 -2
  131. package/dist/commands/node/outcome.js +1 -1
  132. package/dist/commands/node/subscription.js +1 -1
  133. package/dist/commands/node-context.js +2 -2
  134. package/dist/commands/pkg/browse/catalog.js +1 -1
  135. package/dist/commands/pkg/browse/doc-view.js +1 -1
  136. package/dist/commands/pkg/browse/model.d.ts +9 -17
  137. package/dist/commands/pkg/plugin-inspect.js +1 -1
  138. package/dist/commands/pkg/plugin-manage.d.ts +4 -8
  139. package/dist/commands/pkg/plugin-manage.js +15 -17
  140. package/dist/commands/profile/list.js +1 -1
  141. package/dist/commands/profile/new.js +1 -1
  142. package/dist/commands/profile/project.js +1 -1
  143. package/dist/commands/profile/show.js +1 -1
  144. package/dist/commands/push.js +3 -3
  145. package/dist/commands/sys/config.js +1 -1
  146. package/dist/commands/sys/context/admin/actions.d.ts +18 -43
  147. package/dist/commands/sys/context/admin/actions.js +1 -2
  148. package/dist/commands/sys/context/admin/detail-panel.d.ts +17 -25
  149. package/dist/commands/sys/context/admin/detail-panel.js +2 -1
  150. package/dist/commands/sys/context/admin/docs-panel.d.ts +7 -6
  151. package/dist/commands/sys/context/admin/docs-panel.js +1 -1
  152. package/dist/commands/sys/context/admin/list-view.d.ts +12 -12
  153. package/dist/commands/sys/context/admin/list-view.js +1 -1
  154. package/dist/commands/sys/context/admin/model.d.ts +96 -69
  155. package/dist/commands/sys/context/admin/model.js +1 -1
  156. package/dist/commands/sys/context/admin/rail-panel.d.ts +7 -5
  157. package/dist/commands/sys/context/admin/rail-panel.js +1 -1
  158. package/dist/commands/sys/context/admin/read-view.d.ts +10 -14
  159. package/dist/commands/sys/context/admin/read-view.js +1 -2
  160. package/dist/commands/sys/context/admin/shell.d.ts +26 -31
  161. package/dist/commands/sys/context/admin/shell.js +1 -1
  162. package/dist/commands/sys/context/admin.js +2 -2
  163. package/dist/commands/sys/context/doc.js +2 -3
  164. package/dist/commands/sys/context/expose.js +2 -2
  165. package/dist/commands/sys/context/prompt-review.js +4 -4
  166. package/dist/commands/sys/context/resolve.d.ts +92 -65
  167. package/dist/commands/sys/context/resolve.js +7 -9
  168. package/dist/commands/sys/context.js +1 -1
  169. package/dist/commands/sys/doctor.js +1 -1
  170. package/dist/commands/sys/migrate.js +1 -1
  171. package/dist/commands/sys/panels/profiles-panel.d.ts +3 -1
  172. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  173. package/dist/commands/sys/sync-deps.d.ts +6 -11
  174. package/dist/commands/sys/sync-deps.js +7 -8
  175. package/dist/commands/sys/sync-project-guidance.js +5 -4
  176. package/dist/commands/sys/sync-shared.d.ts +41 -4
  177. package/dist/commands/sys/sync-shared.js +1 -1
  178. package/dist/commands/sys/sync-skills.js +2 -2
  179. package/dist/commands/sys/sync.js +1 -1
  180. package/dist/core/bash-job-supervisor.d.ts +2 -3
  181. package/dist/core/bash-job-supervisor.js +3 -3
  182. package/dist/core/bash-jobs.d.ts +0 -5
  183. package/dist/core/bash-jobs.js +7 -7
  184. package/dist/core/bootstrap.js +2 -2
  185. package/dist/core/canvas/canvas.d.ts +6 -50
  186. package/dist/core/canvas/canvas.js +16 -21
  187. package/dist/core/canvas/db.d.ts +4 -1
  188. package/dist/core/canvas/db.js +2 -2
  189. package/dist/core/canvas/history.d.ts +11 -39
  190. package/dist/core/canvas/history.js +9 -20
  191. package/dist/core/canvas/install-id.d.ts +2 -2
  192. package/dist/core/canvas/install-id.js +1 -1
  193. package/dist/core/canvas/memory-reads.d.ts +5 -0
  194. package/dist/core/canvas/memory-reads.js +1 -1
  195. package/dist/core/canvas/migrations.js +215 -41
  196. package/dist/core/canvas/node-agent-paths.js +1 -1
  197. package/dist/core/canvas/node-tokens.js +1 -1
  198. package/dist/core/canvas/paths.d.ts +0 -4
  199. package/dist/core/canvas/paths.js +1 -1
  200. package/dist/core/canvas/remote-canvas-source.d.ts +0 -1
  201. package/dist/core/canvas/remote-canvas-source.js +1 -1
  202. package/dist/core/canvas/render-source.d.ts +9 -6
  203. package/dist/core/canvas/render-source.js +6 -6
  204. package/dist/core/canvas/sessions.js +2 -2
  205. package/dist/core/canvas/source.d.ts +6 -0
  206. package/dist/core/canvas/tree.d.ts +29 -0
  207. package/dist/core/canvas/tree.js +12 -0
  208. package/dist/core/canvas/types.d.ts +0 -20
  209. package/dist/core/command-plugins/bundle.js +1 -1
  210. package/dist/core/config.d.ts +1 -1
  211. package/dist/core/conversation-store/listener.js +4 -2
  212. package/dist/core/feed/feed.d.ts +9 -7
  213. package/dist/core/feed/feed.js +3 -7
  214. package/dist/core/feed/inbox.d.ts +3 -5
  215. package/dist/core/feed/inbox.js +1 -10
  216. package/dist/core/feed/messages.d.ts +33 -6
  217. package/dist/core/feed/messages.js +10 -7
  218. package/dist/core/feed/reports.d.ts +10 -0
  219. package/dist/core/feed/reports.js +2 -0
  220. package/dist/core/grants/remove.js +1 -1
  221. package/dist/core/graph/access.d.ts +24 -0
  222. package/dist/core/graph/access.js +8 -0
  223. package/dist/core/graph/bodies.d.ts +6 -0
  224. package/dist/core/graph/bodies.js +1 -0
  225. package/dist/core/graph/deletion.d.ts +10 -0
  226. package/dist/core/graph/deletion.js +5 -0
  227. package/dist/core/graph/diff.d.ts +4 -0
  228. package/dist/core/graph/diff.js +4 -0
  229. package/dist/core/graph/documents.d.ts +167 -0
  230. package/dist/core/graph/documents.js +10 -0
  231. package/dist/core/graph/edges.d.ts +25 -0
  232. package/dist/core/graph/edges.js +1 -0
  233. package/dist/core/graph/events.d.ts +26 -0
  234. package/dist/core/graph/events.js +7 -0
  235. package/dist/core/graph/exposures.d.ts +53 -0
  236. package/dist/core/graph/exposures.js +4 -0
  237. package/dist/core/graph/jobs.d.ts +31 -0
  238. package/dist/core/graph/jobs.js +2 -0
  239. package/dist/core/graph/names.d.ts +30 -0
  240. package/dist/core/graph/names.js +3 -0
  241. package/dist/core/graph/objects.d.ts +55 -0
  242. package/dist/core/graph/objects.js +9 -0
  243. package/dist/core/graph/package-docs.d.ts +31 -0
  244. package/dist/core/graph/package-docs.js +5 -0
  245. package/dist/core/graph/package-files.d.ts +20 -0
  246. package/dist/core/graph/package-files.js +2 -0
  247. package/dist/core/graph/reader.d.ts +21 -0
  248. package/dist/core/graph/reader.js +3 -0
  249. package/dist/core/graph/repo-sync/exchange.d.ts +34 -0
  250. package/dist/core/graph/repo-sync/exchange.js +2 -0
  251. package/dist/core/graph/repo-sync/identity.d.ts +30 -0
  252. package/dist/core/graph/repo-sync/identity.js +1 -0
  253. package/dist/core/graph/repo-sync/index.d.ts +4 -0
  254. package/dist/core/graph/repo-sync/index.js +1 -0
  255. package/dist/core/graph/repo-sync/mirror.d.ts +30 -0
  256. package/dist/core/graph/repo-sync/mirror.js +6 -0
  257. package/dist/core/graph/repo-sync/ref-format.d.ts +76 -0
  258. package/dist/core/graph/repo-sync/ref-format.js +2 -0
  259. package/dist/core/graph/repo-sync/repos.d.ts +17 -0
  260. package/dist/core/graph/repo-sync/repos.js +3 -0
  261. package/dist/core/graph/repo-sync/sync.d.ts +42 -0
  262. package/dist/core/graph/repo-sync/sync.js +2 -0
  263. package/dist/core/graph/rules.d.ts +26 -0
  264. package/dist/core/graph/rules.js +3 -0
  265. package/dist/core/graph/spaces/app.d.ts +3 -0
  266. package/dist/core/graph/spaces/app.js +1 -0
  267. package/dist/core/graph/spaces/index.d.ts +19 -0
  268. package/dist/core/graph/spaces/index.js +1 -0
  269. package/dist/core/graph/spaces/person.d.ts +5 -0
  270. package/dist/core/graph/spaces/person.js +2 -0
  271. package/dist/core/graph/spaces/repo.d.ts +4 -0
  272. package/dist/core/graph/spaces/repo.js +1 -0
  273. package/dist/core/graph/types.d.ts +75 -0
  274. package/dist/core/graph/types.js +1 -0
  275. package/dist/core/graph/watches.d.ts +62 -0
  276. package/dist/core/graph/watches.js +18 -0
  277. package/dist/core/human/feedback-companion.js +1 -1
  278. package/dist/core/human/requests.d.ts +3 -1
  279. package/dist/core/human/requests.js +6 -6
  280. package/dist/core/inspector/model.js +2 -2
  281. package/dist/core/io.js +5 -5
  282. package/dist/core/layout-migrate/index.d.ts +24 -1
  283. package/dist/core/layout-migrate/index.js +4 -4
  284. package/dist/core/layout-migrate/paths.d.ts +4 -0
  285. package/dist/core/layout-migrate/paths.js +1 -1
  286. package/dist/core/layout-migrate/stored-paths.d.ts +7 -0
  287. package/dist/core/layout-migrate/stored-paths.js +11 -11
  288. package/dist/core/layout-migrate/stores.d.ts +19 -6
  289. package/dist/core/layout-migrate/stores.js +3 -4
  290. package/dist/core/manifest.d.ts +0 -2
  291. package/dist/core/manifest.js +1 -1
  292. package/dist/core/{memory/extensions.d.ts → plugin-extensions.d.ts} +9 -10
  293. package/dist/core/plugin-extensions.js +1 -0
  294. package/dist/core/preview-registry.d.ts +1 -1
  295. package/dist/core/preview-registry.js +3 -2
  296. package/dist/core/profiles/manifest.d.ts +7 -7
  297. package/dist/core/profiles/manifest.js +1 -1
  298. package/dist/core/profiles/select.js +3 -3
  299. package/dist/core/review/birth.js +1 -1
  300. package/dist/core/review/companion.js +1 -1
  301. package/dist/core/review/stage.d.ts +12 -1
  302. package/dist/core/review/stage.js +1 -1
  303. package/dist/core/review/store.d.ts +2 -0
  304. package/dist/core/review/store.js +1 -1
  305. package/dist/core/review/types.d.ts +7 -1
  306. package/dist/core/runs/events.js +1 -1
  307. package/dist/core/runs/operations.js +5 -5
  308. package/dist/core/runs/questions.js +2 -2
  309. package/dist/core/runtime/bearings-render.d.ts +13 -7
  310. package/dist/core/runtime/bearings-render.js +12 -12
  311. package/dist/core/runtime/bearings.d.ts +8 -18
  312. package/dist/core/runtime/bearings.js +7 -7
  313. package/dist/core/runtime/broker/daemon-ops.d.ts +7 -12
  314. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  315. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  316. package/dist/core/runtime/broker/fault-retry.js +1 -1
  317. package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
  318. package/dist/core/runtime/broker/frame-memory-refs.d.ts +7 -2
  319. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  320. package/dist/core/runtime/broker/inbox.d.ts +1 -4
  321. package/dist/core/runtime/broker/inbox.js +1 -10
  322. package/dist/core/runtime/broker/rebind.js +1 -1
  323. package/dist/core/runtime/broker/retry-card-elision.d.ts +7 -0
  324. package/dist/core/runtime/broker/retry-card-elision.js +1 -0
  325. package/dist/core/runtime/broker-extension-render.d.ts +0 -13
  326. package/dist/core/runtime/broker-extension-render.js +2 -4
  327. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  328. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  329. package/dist/core/runtime/broker.js +1 -1
  330. package/dist/core/runtime/close.d.ts +9 -4
  331. package/dist/core/runtime/close.js +1 -1
  332. package/dist/core/runtime/deliver-live.js +1 -1
  333. package/dist/core/runtime/kickoff.js +17 -19
  334. package/dist/core/runtime/launch-target.d.ts +7 -0
  335. package/dist/core/runtime/launch-target.js +1 -1
  336. package/dist/core/runtime/ledger.d.ts +10 -0
  337. package/dist/core/runtime/ledger.js +3 -0
  338. package/dist/core/runtime/lifecycle.js +2 -2
  339. package/dist/core/runtime/nodes.d.ts +10 -2
  340. package/dist/core/runtime/nodes.js +1 -1
  341. package/dist/core/runtime/outcome-document.d.ts +2 -2
  342. package/dist/core/runtime/outcome-document.js +1 -1
  343. package/dist/core/runtime/persona.js +2 -2
  344. package/dist/core/runtime/placement.js +1 -1
  345. package/dist/core/runtime/promote.d.ts +2 -2
  346. package/dist/core/runtime/promote.js +1 -1
  347. package/dist/core/runtime/prospective-inventory-cli.js +2 -2
  348. package/dist/core/runtime/recycle.js +1 -1
  349. package/dist/core/runtime/reopen.js +1 -1
  350. package/dist/core/runtime/revive.js +2 -2
  351. package/dist/core/runtime/roadmap.d.ts +20 -9
  352. package/dist/core/runtime/roadmap.js +10 -6
  353. package/dist/core/runtime/spawn-env.js +1 -1
  354. package/dist/core/runtime/spawn.d.ts +5 -3
  355. package/dist/core/runtime/spawn.js +2 -2
  356. package/dist/core/runtime/structured-output.d.ts +3 -1
  357. package/dist/core/runtime/structured-output.js +4 -4
  358. package/dist/core/scope.d.ts +1 -32
  359. package/dist/core/scope.js +1 -1
  360. package/dist/core/scoped-state/db.js +2 -1
  361. package/dist/core/scoped-state/migrate.js +2 -2
  362. package/dist/core/scoped-state/profiles.d.ts +11 -0
  363. package/dist/core/scoped-state/profiles.js +1 -1
  364. package/dist/core/scoped-state/schema.d.ts +1 -1
  365. package/dist/core/scoped-state/schema.js +7 -5
  366. package/dist/core/spaces/permissions.d.ts +0 -14
  367. package/dist/core/spaces/permissions.js +1 -1
  368. package/dist/core/spaces/stop.d.ts +13 -0
  369. package/dist/core/spaces/stop.js +2 -2
  370. package/dist/core/storage/tables.d.ts +1 -1
  371. package/dist/core/substrate/delivery/corpus.d.ts +21 -0
  372. package/dist/core/substrate/delivery/corpus.js +3 -0
  373. package/dist/core/substrate/delivery/deliver.d.ts +76 -0
  374. package/dist/core/substrate/delivery/deliver.js +6 -0
  375. package/dist/core/substrate/delivery/listings.d.ts +30 -0
  376. package/dist/core/substrate/delivery/listings.js +7 -0
  377. package/dist/core/substrate/delivery/match.d.ts +28 -0
  378. package/dist/core/substrate/delivery/match.js +1 -0
  379. package/dist/core/substrate/delivery/plan.d.ts +67 -0
  380. package/dist/core/substrate/delivery/plan.js +3 -0
  381. package/dist/core/substrate/delivery/render-boot.d.ts +20 -0
  382. package/dist/core/substrate/delivery/render-boot.js +54 -0
  383. package/dist/core/substrate/delivery/render-event.d.ts +54 -0
  384. package/dist/core/substrate/delivery/render-event.js +8 -0
  385. package/dist/core/substrate/delivery/sub-persona-menu.d.ts +2 -0
  386. package/dist/core/substrate/delivery/sub-persona-menu.js +6 -0
  387. package/dist/core/substrate/delivery/types.d.ts +30 -0
  388. package/dist/core/substrate/delivery/types.js +0 -0
  389. package/dist/core/substrate/gate-explain.d.ts +0 -13
  390. package/dist/core/substrate/gate-explain.js +1 -1
  391. package/dist/core/substrate/schema.d.ts +11 -139
  392. package/dist/core/substrate/schema.js +1 -1
  393. package/dist/core/substrate/subject-fields.d.ts +3 -0
  394. package/dist/core/substrate/subject.d.ts +2 -1
  395. package/dist/core/substrate/subject.js +1 -1
  396. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  397. package/dist/daemon/api/handlers/bash-jobs.js +1 -2
  398. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  399. package/dist/daemon/api/handlers/canvas.js +5 -5
  400. package/dist/daemon/api/handlers/daemon.js +1 -1
  401. package/dist/daemon/api/handlers/delivery.d.ts +2 -0
  402. package/dist/daemon/api/handlers/delivery.js +1 -0
  403. package/dist/daemon/api/handlers/{memory.d.ts → docs.d.ts} +1 -1
  404. package/dist/daemon/api/handlers/docs.js +1 -0
  405. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  406. package/dist/daemon/api/handlers/messages.js +2 -2
  407. package/dist/daemon/api/handlers/node-records.js +2 -2
  408. package/dist/daemon/api/handlers/nodes.js +1 -1
  409. package/dist/daemon/api/handlers/objects.d.ts +2 -0
  410. package/dist/daemon/api/handlers/objects.js +5 -0
  411. package/dist/daemon/api/handlers/package-docs.d.ts +2 -0
  412. package/dist/daemon/api/handlers/package-docs.js +1 -0
  413. package/dist/daemon/api/handlers/profiles.js +1 -1
  414. package/dist/daemon/api/handlers/reports.d.ts +2 -2
  415. package/dist/daemon/api/handlers/reports.js +4 -4
  416. package/dist/daemon/api/handlers/reviews.d.ts +4 -1
  417. package/dist/daemon/api/handlers/reviews.js +1 -1
  418. package/dist/daemon/api/map.d.ts +2 -2
  419. package/dist/daemon/api/map.js +2 -2
  420. package/dist/daemon/api/operations.d.ts +1 -1
  421. package/dist/daemon/api/operations.js +1 -1
  422. package/dist/daemon/api/reader.d.ts +17 -0
  423. package/dist/daemon/api/reader.js +1 -0
  424. package/dist/daemon/api/server.js +1 -1
  425. package/dist/daemon/control.d.ts +2 -3
  426. package/dist/daemon/crtrd.js +8 -6
  427. package/dist/daemon/fleet.js +4 -4
  428. package/dist/daemon/reconcilers/bash-deadline.d.ts +11 -1
  429. package/dist/daemon/reconcilers/bash-deadline.js +2 -1
  430. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  431. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  432. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  433. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  434. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -0
  435. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  436. package/dist/daemon/review/deliver.js +2 -2
  437. package/dist/daemon/review/finish.js +1 -1
  438. package/dist/hook-authoring.d.ts +0 -1
  439. package/dist/hook-authoring.js +3 -3
  440. package/dist/migrations/004-canvas-documents/apply.d.ts +10 -0
  441. package/dist/migrations/004-canvas-documents/apply.js +1 -0
  442. package/dist/migrations/004-canvas-documents/fields.d.ts +24 -0
  443. package/dist/migrations/004-canvas-documents/fields.js +2 -0
  444. package/dist/migrations/004-canvas-documents/index.d.ts +16 -0
  445. package/dist/migrations/004-canvas-documents/index.js +2 -0
  446. package/dist/migrations/004-canvas-documents/legacy/discover.d.ts +16 -0
  447. package/dist/migrations/004-canvas-documents/legacy/discover.js +1 -0
  448. package/dist/migrations/004-canvas-documents/legacy/history.d.ts +5 -0
  449. package/dist/migrations/004-canvas-documents/legacy/history.js +2 -0
  450. package/dist/migrations/004-canvas-documents/legacy/nested.d.ts +7 -0
  451. package/dist/migrations/004-canvas-documents/legacy/nested.js +1 -0
  452. package/dist/migrations/004-canvas-documents/legacy/parse.d.ts +14 -0
  453. package/dist/migrations/004-canvas-documents/legacy/parse.js +1 -0
  454. package/dist/migrations/004-canvas-documents/legacy/types.d.ts +91 -0
  455. package/dist/migrations/004-canvas-documents/legacy/types.js +0 -0
  456. package/dist/migrations/004-canvas-documents/legacy-edges.d.ts +6 -0
  457. package/dist/migrations/004-canvas-documents/legacy-edges.js +18 -0
  458. package/dist/migrations/004-canvas-documents/plan.d.ts +102 -0
  459. package/dist/migrations/004-canvas-documents/plan.js +3 -0
  460. package/dist/migrations/004-canvas-documents/pointers.d.ts +23 -0
  461. package/dist/migrations/004-canvas-documents/pointers.js +4 -0
  462. package/dist/migrations/activation.d.ts +9 -18
  463. package/dist/migrations/activation.js +2 -2
  464. package/dist/pi-extensions/broker-local.d.ts +2 -2
  465. package/dist/pi-extensions/broker-local.js +2 -2
  466. package/dist/pi-extensions/canvas-bash-valve.js +5 -4
  467. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  468. package/dist/pi-extensions/canvas-doc-substrate.d.ts +0 -1
  469. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  470. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  471. package/dist/pi-extensions/canvas-passive-context.js +1 -1
  472. package/dist/pi-extensions/canvas-recap.js +2 -2
  473. package/dist/pi-extensions/canvas-stophook.d.ts +1 -1
  474. package/dist/pi-extensions/canvas-stophook.js +1 -1
  475. package/dist/prompts/review.js +3 -3
  476. package/dist/shared/env.d.ts +5 -0
  477. package/dist/shared/env.js +1 -1
  478. package/dist/shared/generated-context.js +2 -10
  479. package/dist/shared/inbox-entry-body.d.ts +22 -0
  480. package/dist/shared/inbox-entry-body.js +10 -0
  481. package/dist/{core/memory → shared}/inline-ref-guidance.d.ts +2 -2
  482. package/dist/shared/inline-ref-guidance.js +2 -0
  483. package/dist/types.d.ts +3 -1
  484. package/docs/cli/memory-and-preferences.md +12 -14
  485. package/docs/concepts/README.md +1 -1
  486. package/docs/concepts/lifecycle-and-wakes.md +1 -1
  487. package/docs/concepts/memory.md +15 -15
  488. package/docs/concepts/nodes-and-the-canvas.md +1 -1
  489. package/docs/concepts/profiles-kinds-and-modes.md +5 -5
  490. package/docs/concepts/scopes-and-trust.md +1 -1
  491. package/docs/concepts/why-a-daemon.md +1 -1
  492. package/docs/sdk/README.md +5 -6
  493. package/docs/sdk/errors.md +0 -13
  494. package/docs/sdk/guides/README.md +0 -1
  495. package/docs/sdk/nodes.md +0 -2
  496. package/docs/sdk/resources.md +0 -1
  497. package/package.json +2 -2
  498. package/packages/crouter-identity/package.json +1 -1
  499. package/runtime.lock.json +11 -11
  500. package/scripts/lib/isolation-env.mjs +8 -2
  501. package/dist/api/dto/memory.d.ts +0 -171
  502. package/dist/api/dto/memory.js +0 -1
  503. package/dist/builtin-memory/crouter-sdk/guides/app-memory.md +0 -73
  504. package/dist/builtin-memory/crouter-sdk/memory.md +0 -87
  505. package/dist/commands/broker-permissions.d.ts +0 -2
  506. package/dist/commands/broker-permissions.js +0 -1
  507. package/dist/commands/memory/client.d.ts +0 -11
  508. package/dist/commands/memory/client.js +0 -1
  509. package/dist/commands/memory/delete.d.ts +0 -1
  510. package/dist/commands/memory/delete.js +0 -1
  511. package/dist/commands/memory/edit.d.ts +0 -1
  512. package/dist/commands/memory/edit.js +0 -21
  513. package/dist/commands/memory/find.d.ts +0 -1
  514. package/dist/commands/memory/find.js +0 -1
  515. package/dist/commands/memory/history.d.ts +0 -1
  516. package/dist/commands/memory/history.js +0 -5
  517. package/dist/commands/memory/lint.d.ts +0 -1
  518. package/dist/commands/memory/lint.js +0 -1
  519. package/dist/commands/memory/list.d.ts +0 -1
  520. package/dist/commands/memory/list.js +0 -1
  521. package/dist/commands/memory/move.d.ts +0 -1
  522. package/dist/commands/memory/move.js +0 -1
  523. package/dist/commands/memory/origin.d.ts +0 -1
  524. package/dist/commands/memory/origin.js +0 -1
  525. package/dist/commands/memory/read.d.ts +0 -1
  526. package/dist/commands/memory/read.js +0 -6
  527. package/dist/commands/memory/shared.d.ts +0 -22
  528. package/dist/commands/memory/shared.js +0 -1
  529. package/dist/commands/memory/write.d.ts +0 -1
  530. package/dist/commands/memory/write.js +0 -13
  531. package/dist/commands/memory.js +0 -1
  532. package/dist/commands/node-inspect-artifacts.d.ts +0 -1
  533. package/dist/commands/node-inspect-artifacts.js +0 -8
  534. package/dist/core/help/memory-extensions.d.ts +0 -3
  535. package/dist/core/help/memory-extensions.js +0 -2
  536. package/dist/core/memory/cli-selector.d.ts +0 -13
  537. package/dist/core/memory/cli-selector.js +0 -1
  538. package/dist/core/memory/doc-link-grammar.d.ts +0 -20
  539. package/dist/core/memory/doc-link-grammar.js +0 -2
  540. package/dist/core/memory/extensions.js +0 -1
  541. package/dist/core/memory/history.d.ts +0 -87
  542. package/dist/core/memory/history.js +0 -6
  543. package/dist/core/memory/identity.d.ts +0 -65
  544. package/dist/core/memory/identity.js +0 -1
  545. package/dist/core/memory/inline-ref-guidance.js +0 -2
  546. package/dist/core/memory/inline-ref-inventory.d.ts +0 -9
  547. package/dist/core/memory/inline-ref-inventory.js +0 -1
  548. package/dist/core/memory/lint.d.ts +0 -163
  549. package/dist/core/memory/lint.js +0 -2
  550. package/dist/core/memory/mutation-domain.d.ts +0 -113
  551. package/dist/core/memory/mutation-domain.js +0 -12
  552. package/dist/core/memory/mutations.d.ts +0 -74
  553. package/dist/core/memory/mutations.js +0 -1
  554. package/dist/core/memory/project-namespace.d.ts +0 -31
  555. package/dist/core/memory/project-namespace.js +0 -2
  556. package/dist/core/memory/repository-association.d.ts +0 -31
  557. package/dist/core/memory/repository-association.js +0 -1
  558. package/dist/core/memory/service.d.ts +0 -145
  559. package/dist/core/memory/service.js +0 -2
  560. package/dist/core/memory/tree.d.ts +0 -39
  561. package/dist/core/memory/tree.js +0 -1
  562. package/dist/core/memory-resolver.d.ts +0 -280
  563. package/dist/core/memory-resolver.js +0 -2
  564. package/dist/core/nested-stores.d.ts +0 -18
  565. package/dist/core/nested-stores.js +0 -1
  566. package/dist/core/runtime/memory.d.ts +0 -3
  567. package/dist/core/runtime/memory.js +0 -1
  568. package/dist/core/substrate/frontmatter-validation.d.ts +0 -11
  569. package/dist/core/substrate/frontmatter-validation.js +0 -1
  570. package/dist/core/substrate/gate.d.ts +0 -16
  571. package/dist/core/substrate/gate.js +0 -1
  572. package/dist/core/substrate/index.d.ts +0 -18
  573. package/dist/core/substrate/index.js +0 -1
  574. package/dist/core/substrate/injected-store.d.ts +0 -75
  575. package/dist/core/substrate/injected-store.js +0 -2
  576. package/dist/core/substrate/listings.d.ts +0 -28
  577. package/dist/core/substrate/listings.js +0 -1
  578. package/dist/core/substrate/memory-events.d.ts +0 -6
  579. package/dist/core/substrate/memory-events.js +0 -1
  580. package/dist/core/substrate/on-read-node.d.ts +0 -6
  581. package/dist/core/substrate/on-read-node.js +0 -1
  582. package/dist/core/substrate/on-read.d.ts +0 -101
  583. package/dist/core/substrate/on-read.js +0 -9
  584. package/dist/core/substrate/plan.d.ts +0 -94
  585. package/dist/core/substrate/plan.js +0 -1
  586. package/dist/core/substrate/render-node.d.ts +0 -12
  587. package/dist/core/substrate/render-node.js +0 -1
  588. package/dist/core/substrate/render.d.ts +0 -41
  589. package/dist/core/substrate/render.js +0 -65
  590. package/dist/core/substrate/session-cache.d.ts +0 -27
  591. package/dist/core/substrate/session-cache.js +0 -1
  592. package/dist/core/substrate/surface-match.d.ts +0 -73
  593. package/dist/core/substrate/surface-match.js +0 -1
  594. package/dist/daemon/api/handlers/memory.js +0 -5
  595. package/dist/migrations/001-surfaces-frontmatter.d.ts +0 -2
  596. package/dist/migrations/001-surfaces-frontmatter.js +0 -1
  597. package/dist/migrations/002-profile-project-memory.d.ts +0 -2
  598. package/dist/migrations/002-profile-project-memory.js +0 -1
  599. package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +0 -26
  600. package/dist/migrations/003-repository-root-memory-identity/front-door.js +0 -11
  601. package/dist/migrations/003-repository-root-memory-identity/index.d.ts +0 -2
  602. package/dist/migrations/003-repository-root-memory-identity/index.js +0 -5
  603. package/dist/migrations/003-repository-root-memory-identity/references.d.ts +0 -95
  604. package/dist/migrations/003-repository-root-memory-identity/references.js +0 -5
  605. package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +0 -39
  606. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +0 -3
  607. package/dist/migrations/convergent.d.ts +0 -43
  608. package/dist/migrations/convergent.js +0 -2
  609. package/dist/migrations/corpus.d.ts +0 -75
  610. package/dist/migrations/corpus.js +0 -3
  611. package/dist/migrations/frontmatter-splice.d.ts +0 -15
  612. package/dist/migrations/frontmatter-splice.js +0 -8
  613. package/dist/migrations/profile-manifests.d.ts +0 -30
  614. package/dist/migrations/profile-manifests.js +0 -2
  615. package/dist/migrations/registry.d.ts +0 -7
  616. package/dist/migrations/registry.js +0 -1
  617. package/dist/migrations/runner.d.ts +0 -43
  618. package/dist/migrations/runner.js +0 -1
  619. package/dist/migrations/types.d.ts +0 -211
  620. package/dist/shared/birth-announcement.d.ts +0 -12
  621. package/dist/shared/birth-announcement.js +0 -1
  622. package/docs/sdk/guides/app-memory.md +0 -22
  623. package/docs/sdk/memory.md +0 -85
  624. /package/dist/{migrations/types.js → api/dto/delivery.js} +0 -0
  625. /package/dist/{core/memory → shared}/inline-ref-grammar.d.ts +0 -0
  626. /package/dist/{core/memory → shared}/inline-ref-grammar.js +0 -0
@@ -1 +1 @@
1
- var i=Object.defineProperty;var s=(e,t)=>i(e,"name",{value:t,configurable:!0});import{toMigrateStateDTO as u}from"../map.js";import{boundDaemonControl as a}from"../../control.js";import{ownerOnly as m}from"../router.js";function c(){const e=a();if(e===null)throw{status:503,code:"daemon_control_unavailable",message:"this API server is not hosted by a live daemon and cannot hand over"};const{graceMs:t}=e.requestHandover();return{status:202,body:{accepted:!0,predecessor_pid:process.pid,predecessor_epoch:e.epoch,grace_ms:t}}}s(c,"handleRestart");async function l(e){if(e.body!==void 0)throw{status:400,code:"invalid_request",message:"admission request must not include a body"};const t=a();if(t===null)throw{status:503,code:"daemon_control_unavailable",message:"this API server is not hosted by a live daemon and cannot admit normal work"};return{status:200,body:await t.admitStartup()}}s(l,"handleAdmit");async function y(e){const t=a();if(t===null)throw{status:503,code:"daemon_control_unavailable",message:"this API server is not hosted by a live daemon and cannot migrate its corpus"};const r=e.body;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))throw{status:400,code:"invalid_request",message:"migration request body must be an object"};const o=r??{};if(o.dry_run!==void 0&&typeof o.dry_run!="boolean")throw{status:400,code:"invalid_request",message:"dry_run must be a boolean"};if(o.dirs!==void 0&&(!Array.isArray(o.dirs)||o.dirs.some(d=>typeof d!="string")))throw{status:400,code:"invalid_request",message:"dirs must be an array of strings"};const n=await t.repairMigrations({dryRun:o.dry_run===!0,dirs:o.dirs??[]});return{status:200,body:u(n.result,{resumed:n.resumed,resumeError:n.resumeError})}}s(y,"handleMigrate");const v=m([{method:"POST",pattern:"/v1/daemon/restart",handler:s(e=>c(),"handler")},{method:"POST",pattern:"/v1/daemon/migrate",handler:y},{method:"POST",pattern:"/v1/daemon/admit",handler:l}]);export{v as daemonRoutes};
1
+ var d=Object.defineProperty;var n=(e,t)=>d(e,"name",{value:t,configurable:!0});import{toMigrateStateDTO as i}from"../map.js";import{boundDaemonControl as s}from"../../control.js";import{ownerOnly as u}from"../router.js";function c(){const e=s();if(e===null)throw{status:503,code:"daemon_control_unavailable",message:"this API server is not hosted by a live daemon and cannot hand over"};const{graceMs:t}=e.requestHandover();return{status:202,body:{accepted:!0,predecessor_pid:process.pid,predecessor_epoch:e.epoch,grace_ms:t}}}n(c,"handleRestart");async function m(e){if(e.body!==void 0)throw{status:400,code:"invalid_request",message:"admission request must not include a body"};const t=s();if(t===null)throw{status:503,code:"daemon_control_unavailable",message:"this API server is not hosted by a live daemon and cannot admit normal work"};return{status:200,body:await t.admitStartup()}}n(m,"handleAdmit");async function l(e){const t=s();if(t===null)throw{status:503,code:"daemon_control_unavailable",message:"this API server is not hosted by a live daemon and cannot run the canvas import"};const o=e.body;if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))throw{status:400,code:"invalid_request",message:"migration request body must be an object"};const r=o??{};if(r.dry_run!==void 0&&typeof r.dry_run!="boolean")throw{status:400,code:"invalid_request",message:"dry_run must be a boolean"};const a=await t.repairMigrations({dryRun:r.dry_run===!0});return{status:200,body:i(a.result,{resumed:a.resumed,resumeError:a.resumeError})}}n(l,"handleMigrate");const v=u([{method:"POST",pattern:"/v1/daemon/restart",handler:n(e=>c(),"handler")},{method:"POST",pattern:"/v1/daemon/migrate",handler:l},{method:"POST",pattern:"/v1/daemon/admit",handler:m}]);export{v as daemonRoutes};
@@ -0,0 +1,2 @@
1
+ import type { RouteTable } from '../router.js';
2
+ export declare const deliveryRoutes: RouteTable;
@@ -0,0 +1 @@
1
+ var v=Object.defineProperty;var d=(e,n)=>v(e,"name",{value:n,configurable:!0});import{ApiError as i}from"../../../api/errors.js";import{openDb as _,withCanvasWrite as j}from"../../../core/canvas/db.js";import{readerForNode as l}from"../../../core/graph/reader.js";import{noteNodeBooting as A}from"../../../core/graph/repo-sync/index.js";import{reposForCwd as f}from"../../../core/graph/repo-sync/repos.js";import{DRY_RUN_ONLY as E,deliver as I,hypotheticalFrom as O,hypotheticalReader as k,inspect as p}from"../../../core/substrate/delivery/deliver.js";import{requireCurrentExecution as h}from"./broker-recovery.js";const N=["boot","system-prompt","compact","persona","file-read","command","pre-command","slash-command","names",...E];function y(e){if(typeof e!="object"||e===null||Array.isArray(e))throw new i(400,"usage","delivery requires a JSON body");const n=e;if(!N.includes(n.activity))throw new i(400,"usage",`invalid delivery activity: ${String(n.activity)}`);if(n.subject!==void 0&&typeof n.subject!="string")throw new i(400,"usage","delivery subject must be a string");return n}d(y,"parse");function m(e){if(e.principal.class!=="person"&&e.principal.class!=="broker")throw new i(403,"permission_error","a delivery dry run is available to a person or a node only")}d(m,"requirePerson");function w(e){const n=_(),r=n.isTransaction;n.exec(r?"SAVEPOINT delivery_dry_run":"BEGIN IMMEDIATE");try{return e(n)}finally{r?n.exec("ROLLBACK TO delivery_dry_run; RELEASE delivery_dry_run"):n.exec("ROLLBACK")}}d(w,"rolledBack");function R(e){if(typeof e!="object"||e===null||Array.isArray(e))throw new i(400,"usage","hypothetical must be an object");const n=d((a,s)=>{if(a!==void 0){if(typeof a!="string"||a==="")throw new i(400,"usage",`hypothetical.${s} must be a non-empty string`);return a}},"str"),r=n(e.cwd,"cwd");if(r!==void 0&&!r.startsWith("/"))throw new i(400,"usage","hypothetical.cwd must be an absolute path");if(e.mode!==void 0&&e.mode!=="base"&&e.mode!=="orchestrator")throw new i(400,"usage","hypothetical.mode must be base or orchestrator");if(e.lifecycle!==void 0&&e.lifecycle!=="terminal"&&e.lifecycle!=="resident")throw new i(400,"usage","hypothetical.lifecycle must be terminal or resident");if(e.has_manager!==void 0&&typeof e.has_manager!="boolean")throw new i(400,"usage","hypothetical.has_manager must be a boolean");if(e.depth!==void 0&&(!Number.isInteger(e.depth)||e.depth<0))throw new i(400,"usage","hypothetical.depth must be a non-negative integer");const t={};r!==void 0&&(t.cwd=r),e.profile!==void 0&&(t.profile=e.profile===null?null:n(e.profile,"profile"));const c=n(e.grantee,"grantee");c!==void 0&&(t.grantee=c);const o=n(e.kind,"kind");return o!==void 0&&(t.kind=o),e.mode!==void 0&&(t.mode=e.mode),e.lifecycle!==void 0&&(t.lifecycle=e.lifecycle),e.has_manager!==void 0&&(t.hasManager=e.has_manager),e.depth!==void 0&&(t.depth=e.depth),t}d(R,"hypotheticalOf");async function T(e){m(e);const n=y(e.body);if(n.node!==void 0&&typeof n.node!="string")throw new i(400,"usage","node must be a node id");const r={activity:n.activity,...n.subject!==void 0?{subject:n.subject}:{}},{result:t,plan:c}=w(o=>{if(n.hypothetical===void 0){if(n.node===void 0)throw new i(400,"usage","a delivery dry run names a node, a hypothetical node, or both");return p(o,l(o,n.node,g=>f(o,g)),r,n.subject_override)}const a=R(n.hypothetical),s=n.node!==void 0?O(n.node,a):{...a,cwd:a.cwd??""};if(s.cwd==="")throw new i(400,"usage","a hypothetical node needs a cwd");const{reader:u,subject:b}=k(o,s);return p(o,u,r,n.subject_override,b)});return{status:200,body:{...t,plan:c}}}d(T,"handleDryRun");async function S(e){const n=e.params.id,r=y(e.body),t={activity:r.activity,...r.subject!==void 0?{subject:r.subject}:{},...r.inherited===!0?{inherited:!0}:{}};if(r.dry_run===!0){m(e);const{result:o,plan:a}=w(s=>p(s,l(s,n,u=>f(s,u)),t,r.subject_override));return{status:200,body:{...o,plan:a}}}if(e.principal.class==="broker"&&e.principal.node!==n)throw new i(403,"permission_error","delivery is performed by the node's own broker");return h(n,r.expected_execution_id),r.activity==="boot"&&(await A(n),h(n,r.expected_execution_id)),{status:200,body:j(o=>I(o,l(o,n,a=>f(o,a)),t))}}d(S,"handleDelivery");const M=[{method:"POST",pattern:"/v1/nodes/:id/delivery",handler:S},{method:"POST",pattern:"/v1/delivery/dry-run",handler:T}];export{M as deliveryRoutes};
@@ -1,2 +1,2 @@
1
1
  import type { RouteTable } from '../router.js';
2
- export declare const memoryRoutes: RouteTable;
2
+ export declare const docRoutes: RouteTable;
@@ -0,0 +1 @@
1
+ var oe=Object.defineProperty;var u=(t,e)=>oe(t,"name",{value:e,configurable:!0});import{ApiError as g}from"../../../api/errors.js";import{DOC_KINDS as P,DOC_UNSET_FIELDS as q}from"../../../api/dto/docs.js";import{PRIVACY_LEVELS_DTO as H}from"../../../api/dto/objects.js";import{withCanvasWrite as k}from"../../../core/canvas/db.js";import{CrtrError as re}from"../../../core/errors.js";import{emitEvent as ie}from"../../../core/events/emit.js";import{canChange as V,spaceOf as se}from"../../../core/graph/access.js";import{get as A}from"../../../core/graph/bodies.js";import{deleteDocument as ae,documentRecord as F,editDocument as ce,heads as I,history as de,linksIn as K,moveDocument as ue,readBase as fe,setDocumentRecord as le,withCurrentNames as me,writeDocument as pe}from"../../../core/graph/documents.js";import{resolveName as U}from"../../../core/graph/names.js";import{getByRowid as M}from"../../../core/graph/objects.js";import{noteRepoDocumentsChanged as he}from"../../../core/graph/repo-sync/index.js";import{reposForCwd as we}from"../../../core/graph/repo-sync/repos.js";import{lintRules as ye,rulesOf as ve}from"../../../core/graph/rules.js";import{unifiedDiff as ge}from"../../../core/graph/diff.js";import{ownerFromFlag as W,readerFor as E,resolveRef as X}from"../reader.js";function _(t,e,n,o,i={}){return new g(t,e,n,{...i,error:e,message:n,next:o})}u(_,"refuse");const b=u((t,e)=>new g(400,"invalid_request",t,e),"invalid");function D(t){const e=t.body;if(e===void 0)return{};if(typeof e!="object"||e===null||Array.isArray(e))throw b("the request body must be a JSON object");return e}u(D,"bodyOf");const x=u(t=>e=>we(t,e),"reposFnFor");function C(t,e){if(t instanceof re){const n=t.details;if(t.code==="read_first")throw _(409,"read_first",t.message,`Read it first with \`crtr canvas read ${e?.id??"<ref>"}\`, then rerun the edit.`,n??{});if(t.code==="conflict")throw new g(409,"name_taken",t.message,n);if(t.code==="forbidden")throw new g(403,"forbidden",t.message,n);if(n?.rule==="repo-public-only")throw _(422,"repo_documents_are_public",t.message,'Own it as `user` and add a rule with `if: {"repo": "<handle>"}` so it loads only in that repo.')}throw t}u(C,"mapGraphError");function B(t,e,n){const o=X(t,e,decodeURIComponent(n));if("remote"in o)throw _(404,"not_found",z(o.remote),"Check the name with `crtr canvas search`.");if("deleted"in o)throw new g(404,"not_found",`${o.deleted.name} is deleted`,{id:o.deleted.id,deleted:!0});if(o.type!=="document")throw b(`${n} is a ${o.type}, not a document`);return o}u(B,"refDocument");function z(t){return`no object named ${t} on this runtime; it may be on another runtime, or the name may be misspelled`}u(z,"remoteMessage");function _e(t,e){const n=e.owner===null?null:M(t,e.owner);return n?n.type==="node"?n.id:n.name:""}u(_e,"ownerHandle");function j(t,e){const n=_e(t,e);return n?`${n}/${e.name}`:e.name}u(j,"canonicalName");function be(t,e){const n=e.owner===null?null:M(t,e.owner),o=n?{id:n.id,type:n.type,handle:n.type==="node"?n.id:n.name}:null;return{id:e.id,type:e.type,kind:e.kind,owner:o,privacy:e.privacy,name:e.name,preview:e.preview??"",created_at:e.created_at,deleted_at:e.deleted_at}}u(be,"objectDTO");function ke(t,e){const n=e.owner===null?null:M(t,e.owner);return n?.type==="repo"?n:null}u(ke,"repoOwner");function T(t,e,n,o){const i=[...new Map(n.flatMap(r=>{const f=ke(t,r);return f?[[f.id,f]]:[]})).values()],a=e.class==="node"?e.cwd:o;return{repos:i,...a!==void 0?{cwd:a}:{}}}u(T,"repoChange");function N(t){for(const e of t.repos)try{he(e,t.cwd)}catch(n){ie({level:"warn",event:"repo_sync.failed",outcome:"failed",error:n,fields:{repo:e.name,step:"export",reason:n instanceof Error?n.message:String(n)}})}}u(N,"syncChanged");const G=/^[A-Za-z0-9_-]+(\/[A-Za-z0-9_-]+)*$/;function Ee(t,e){if(t===void 0)return;if(!Array.isArray(t)){e.push("`rules` must be a list");return}const n=t.map(i=>{if(typeof i!="object"||i===null||Array.isArray(i))return i;const{match_frontmatter:a,...r}=i;return"matchFrontmatter"in r?{...r,match_frontmatter:r.matchFrontmatter}:a===void 0?r:{...r,matchFrontmatter:a}}),o=ye(n);if(o){e.push(o.replaceAll("matchFrontmatter","match_frontmatter"));return}return n}u(Ee,"rulesFromDTO");function Y(t,e){const n={},o=u(s=>{const c=t[s];if(c!==void 0){if(typeof c!="string"){e.push(`\`${s}\` must be a string`);return}return c}},"str"),i=o("preview");i!==void 0&&(i.trim()===""||/[\r\n]/.test(i)?e.push("`preview` must be one non-empty line"):n.preview=i);const a=o("summary");a!==void 0&&(n.summary=a);const r=o("why_it_exists");if(r!==void 0&&(n.whyItExists=r),t.privacy!==void 0&&(H.includes(t.privacy)?n.privacy=t.privacy:e.push(`\`privacy\` must be one of ${H.join(", ")}`)),t.unlisted!==void 0&&(typeof t.unlisted!="boolean"?e.push("`unlisted` must be a boolean"):n.unlisted=t.unlisted),t.lint_ignore!==void 0){const s=t.lint_ignore;!Array.isArray(s)||s.some(c=>typeof c!="string")?e.push("`lint_ignore` must be a list of strings"):n.lintIgnore=s}if(t.extensions!==void 0){const s=t.extensions;typeof s!="object"||s===null||Array.isArray(s)||Object.values(s).some(c=>typeof c!="object"||c===null||Array.isArray(c))?e.push("`extensions` must map each plugin to an object of fields"):n.extensions=s}const f=Ee(t.rules,e);return f!==void 0&&(n.rules=f),n}u(Y,"fieldsFrom");function Z(t){if(t.length>0)throw b(t.join("; "),{errors:t})}u(Z,"failOn");function J(t,e,n,o){const i=K(n).filter(a=>"remote"in U(t,e,a));return{...o.length>0?{unresolved_links:o}:{},...i.length>0?{remote_links:i}:{}}}u(J,"linkReport");function Oe(t){const e=D(t),n=[],o=e.name;(typeof o!="string"||!G.test(o))&&n.push("`name` must be segments of letters, digits, `_` or `-` joined by `/`"),typeof e.body!="string"&&n.push("`body` must be a string"),typeof e.preview!="string"&&n.push("`preview` is required");const i=e.kind??"knowledge";P.includes(i)||n.push(i==="report"?"reports are written only by `crtr push`":`\`kind\` must be one of ${P.join(", ")}`);const a=Y(e,n);e.cwd!==void 0&&typeof e.cwd!="string"&&n.push("`cwd` must be a string"),Z(n);const r=e,{dto:f,change:s}=k(c=>{const h=E(c,t),d=W(c,h,r.owner,r.cwd);if(!V(c,h,d))throw new g(404,"not_found",`no owner ${d.name} you can write to`);try{const{object:p,unresolved:l}=pe(c,h,{...a,owner:d,name:r.name,kind:i,preview:a.preview,privacy:a.privacy??"public"},r.body,x(c));return{dto:{id:p.id,name:j(c,p),...J(c,h,r.body,l)},change:T(c,h,[p],r.cwd)}}catch(p){C(p)}});return N(s),f}u(Oe,"write");function $e(t,e){let n=t;e.forEach(({old:o,new:i},a)=>{const r=o===""?-1:n.indexOf(o);if(r<0)throw _(422,"replace_no_match",`replace[${a}]: old text not found in the revision you read`,"Copy the old text exactly from your last read and rerun.",{index:a});if(n.indexOf(o,r+1)>=0)throw _(422,"replace_ambiguous",`replace[${a}]: old text occurs more than once`,"Include more surrounding text so the old text matches once, and rerun.",{index:a});n=n.slice(0,r)+i+n.slice(r+o.length)})}u($e,"checkReplacements");function Ae(t){const e=D(t),n=[],o=e.body!==void 0,i=e.replace!==void 0;o&&i&&n.push("give `body` or `replace`, not both"),o&&typeof e.body!="string"&&n.push("`body` must be a string");const a=e.replace;i&&(!Array.isArray(a)||a.length===0||a.some(d=>typeof d!="object"||d===null||typeof d.old!="string"||typeof d.new!="string"))&&n.push("`replace` must be a non-empty list of {old, new} strings"),(typeof e.rationale!="string"||e.rationale.trim()==="")&&n.push("`rationale` is required"),e.verbatim!==void 0&&typeof e.verbatim!="boolean"&&n.push("`verbatim` must be a boolean"),e.base!==void 0&&(typeof e.base!="string"||e.base==="")&&n.push("`base` must be a non-empty heads key"),e.base!==void 0&&!o&&!i&&n.push("`base` applies only to a `body` or `replace` edit");const r=Y(e,n),f=e.unset??[];if(!Array.isArray(f)||f.some(d=>!q.includes(d)))n.push(`\`unset\` takes only ${q.join(", ")}`);else for(const d of f)d==="summary"&&(r.summary=null),d==="why_it_exists"&&(r.whyItExists=null),d==="unlisted"&&(r.unlisted=!1),d==="lint_ignore"&&(r.lintIgnore=null),d==="extensions"&&(r.extensions=null),d==="rules"&&(r.rules=[]);!o&&!i&&Object.keys(r).length===0&&n.push("nothing to change: give `body`, `replace`, or a field"),Z(n);const s=e,{dto:c,synced:h}=k(d=>{const p=E(d,t),l=B(d,p,t.params.ref),v=j(d,l),$=T(d,p,[l]);try{if(!o&&!i)return le(d,p,l,r),{dto:{id:l.id,name:v,revision:F(d,l).revision},synced:$};const w=s.base??fe(d,p,l);if(i&&w!==null){const te=F(d,l),L=I(d,l);te.heads_key===w&&L.length===1&&$e(me(d,l,A(L[0].body_hash)),s.replace)}const R=s.verbatim===!0,m=o?{body:s.body,verbatim:R}:{replace:s.replace,verbatim:R},y=ce(d,p,l,m,s.rationale,w,r,x(d));if("stale"in y)throw _(409,"stale_revision",`${v} changed after your read; it is now at revision ${y.stale.revision}`,`Read it again with \`crtr canvas read ${v}\`, then redo your change on the current text.`,{stale:y.stale});const S=A(I(d,l)[0].body_hash);return{dto:{id:l.id,name:v,revision:y.revision,...J(d,p,S,y.unresolved)},synced:$}}catch(w){C(w,l)}});return N(h),c}u(Ae,"edit");function je(t){const e=D(t);if(e.new_name===void 0&&e.owner===void 0)throw b("give a new name, an owner, or both");if(e.new_name!==void 0&&(typeof e.new_name!="string"||!G.test(e.new_name)))throw b("`new_name` must be segments of letters, digits, `_` or `-` joined by `/`");const{dto:n,change:o}=k(i=>{const a=E(i,t),r=B(i,a,t.params.ref),f=e.owner===void 0?void 0:W(i,a,e.owner,e.cwd);try{const s=ue(i,a,r,{...e.new_name!==void 0?{name:e.new_name}:{},...f?{owner:f}:{}});return{dto:{id:s.id,name:j(i,s)},change:T(i,a,[r,s],e.cwd)}}catch(s){C(s,r)}});return N(o),n}u(je,"move");function Re(t){const{dto:e,change:n}=k(o=>{const i=E(o,t),a=B(o,i,t.params.ref),r=j(o,a),f=T(o,i,[a]);try{ae(o,i,a,x(o))}catch(s){C(s,a)}return{dto:{id:a.id,name:r},change:f}});return N(n),e}u(Re,"remove");function De(t){const e=t.query.get("diff"),n=e===null?void 0:Number(e);if(n!==void 0&&!(Number.isInteger(n)&&n>0))throw b("`diff` must be a revision number");return k(o=>{const i=E(o,t),a=X(o,i,decodeURIComponent(t.params.ref));if("remote"in a)throw _(404,"not_found",z(a.remote),"Check the name with `crtr canvas search`.");const r="deleted"in a?a.deleted:a;if(r.type!=="document")throw b(`${r.name} is a ${r.type}, not a document`);const f=de(o,i,r),s={object:be(o,r),revisions:f.map(c=>({rev_id:c.rev_id,number:c.number,author_id:c.author,rationale:c.rationale,verbatim:c.verbatim,created_at:c.created_at,parents:c.parents}))};if(n!==void 0){const c=f.find(d=>d.number===n);if(!c)throw new g(404,"not_found",`${r.name} has no revision ${n}`);const h=c.parents[0]===void 0?void 0:f.find(d=>d.rev_id===c.parents[0]);s.diff=ge(h?A(h.body_hash):"",A(c.body_hash))}return s})}u(De,"revisionHistory");const Q=1e3,ee=1e3,ne=3e3,Ce=/^When\b.+\bbecause\b.+/,Te=u(t=>{const e=t.trim();return e===""?0:e.split(/\s+/).length},"words");function Ne(t,e){if(t.some(o=>o.on==="boot"&&o.deliver==="content")&&e>Q)return`body is ${e} words, over the ${Q}-word cap for a boot rule at content (the whole body enters every node's context). Keep the core here and move separate subjects into [[linked]] documents.`;const n=[...new Set(t.filter(o=>o.on!=="boot"&&o.deliver==="content").map(o=>o.on))];return n.length>0&&e>ee?`body is ${e} words, over the ${ee}-word cap for a content rule on ${n.join("/")}. Keep the core here and move separate subjects into [[linked]] documents.`:t.some(o=>o.on==="boot"&&o.deliver==="preview")&&e>ne?`body is ${e} words, over the ${ne}-word cap for a boot rule at preview. Keep the core here and move separate subjects into [[linked]] documents.`:null}u(Ne,"lengthFinding");function Se(t){const e=D(t);return k(n=>{const o=E(n,t),i=e.owner===void 0?null:W(n,o,e.owner,e.cwd),a=n.prepare("SELECT * FROM objects WHERE type = 'document' AND deleted_at IS NULL AND kind != 'report' ORDER BY name").all(),r=[],f=new Map;for(const s of a){if(i&&s.owner!==i.rowid||!V(n,o,s))continue;const c=F(n,s),h=new Set(c.lint_ignore??[]),d=j(n,s),p=u((m,y,S)=>{h.has(m)||r.push({name:d,severity:y,rule:m,message:S})},"add"),l=ve(n,s),v=I(n,s)[0],$=v?A(v.body_hash):"",w=Ne(l,Te($));w&&p("length","error",w),l.some(m=>m.deliver==="preview")&&!Ce.test(s.preview??"")&&p("preview-shape","error",`a rule delivers this document at preview, so the preview must read "When <situation in the reader's work>, read this because <what the reader gains>"`);const R=new Set(n.prepare("SELECT written_as FROM edges WHERE type = 'links-to' AND src = ?").all(s.rowid).map(m=>m.written_as));for(const m of K($))R.has(m)||"remote"in U(n,o,m)||p("links","warning",`[[${m}]] names no object in your view`);if(l.some(m=>m.on==="workspace-open"&&m.deliver==="content")){const m=se(n,s);m.type==="repo"&&!h.has("workspace-open")&&f.set(m.name,[...f.get(m.name)??[],d])}}for(const[s,c]of f)if(!(c.length<2))for(const h of c)r.push({name:h,severity:"warning",rule:"workspace-open",message:`repo ${s} has ${c.length} documents delivered at content on workspace-open (${c.join(", ")}); keep one and link the rest from it`});return{findings:r}})}u(Se,"lint");const O=u((t,e=200)=>n=>({status:e,body:t(n)}),"ok"),Ze=[{method:"POST",pattern:"/v1/docs",handler:O(Oe,201)},{method:"PATCH",pattern:"/v1/docs/:ref",handler:O(Ae)},{method:"POST",pattern:"/v1/docs/:ref/move",handler:O(je)},{method:"DELETE",pattern:"/v1/docs/:ref",handler:O(Re)},{method:"GET",pattern:"/v1/docs/:ref/history",handler:O(De)},{method:"POST",pattern:"/v1/docs/lint",handler:O(Se)}];export{Ze as docRoutes};
@@ -1 +1 @@
1
- var v=Object.defineProperty;var u=(o,n)=>v(o,"name",{value:n,configurable:!0});import{realpathSync as q}from"node:fs";import{isAbsolute as y,relative as x,sep as E}from"node:path";import{ApiError as i}from"../../../api/index.js";import{coreHookCatalog as T}from"../../../build-root.js";import{getNode as O}from"../../../core/canvas/canvas.js";import{isSafeNodeId as P}from"../../../core/canvas/paths.js";import{discoverHookRegistry as I}from"../../../core/command-hooks/discovery.js";import{EXEC_HOOK_TIMEOUT_MS as S}from"../../../core/command-hooks/transport/exec-invoke.js";import{buildAppProcessEnv as A}from"../../../core/runtime/spawn-env.js";import{compileLaunch as H}from"../../../core/spaces/mounts.js";import{appProcessSandboxed as N,launchAppProcess as M}from"../../../core/spaces/process.js";import{requireCurrentExecution as R}from"./broker-recovery.js";function _(o,n,t){const r=o.params.id;if(r===void 0?o.principal.class!=="person":!P(r)||o.principal.class!=="broker"||o.principal.node!==r)throw new i(403,"permission_error","hook execution requires its current node or the person");const e=r===void 0?null:O(r);if(r!==void 0&&!e)throw new i(404,"not_found","node not found");if(r!==void 0&&R(r,n),typeof t!="string"||!y(t))throw new i(400,"invalid_request","hook cwd must be absolute");if(!N())throw new i(400,"invalid_request","hook routes require the root launcher");let s;try{s=q(t)}catch(d){throw d.code==="ENOENT"?new i(400,"invalid_request","hook cwd does not exist"):d}if(e){const d=H({nodeId:r,app:o.principal.class==="broker"?o.principal.app:"app:terminal",sub:e.sub??"user:local",grantId:e.grant_id??null,scopes:e.scopes??null,command:[],env:{},auditMissing:u(()=>{},"auditMissing")}),h=u(a=>{const p=x(a,s);return p===""||p!==".."&&!p.startsWith(`..${E}`)&&!y(p)},"within");if(!d.mounts.some(a=>h(a.source)))throw new i(403,"permission_error","hook cwd is outside the node mounts")}return{id:r,node:e,cwd:s,app:e&&o.principal.class==="broker"?o.principal.app:"app:terminal"}}u(_,"checkedContext");async function g(o,n){const t=I(await T(),o,n);if(!t.valid)throw new i(422,"hook_registry_invalid","the effective hook registry is invalid");return t}u(g,"currentRegistry");async function B(o){const{node:n,cwd:t}=_(o,o.query.get("expected_execution_id"),o.query.get("cwd"));return{status:200,body:{hooks:(await g(t,n.profile_id??null)).hooks.filter(e=>e.plugin.scope==="user").map(e=>({id:e.id,plugin:e.plugin.name,target:e.target,phase:e.phase,op:e.op,description:e.description,effects:e.effects,declarationIndex:e.declarationIndex}))}}}u(B,"handleHookPlan");async function k(o){const n=o.body;if(!n||typeof n!="object"||Array.isArray(n))throw new i(400,"invalid_request","hook execution requires a JSON body");const t=n,{id:r,node:e,cwd:s,app:d}=_(o,t.expected_execution_id,t.cwd);if(typeof t.hook_id!="string"||typeof t.request!="string")throw new i(400,"invalid_request","hook execution requires hook_id and request");const a=(await g(s,e?.profile_id??null)).hooks.find(c=>c.id===t.hook_id);if(!a)throw new i(404,"hook_not_registered","hook id is not registered for this cwd");const p=A(s,e?.profile_id??null,d),f=await M({...r===void 0?{}:{nodeId:r},app:d,command:[a.executable,"--crtr-hook-protocol","1"],cwd:s,pluginRoot:a.plugin.root,env:p,stdin:t.request,stdoutBytes:10*1024*1024,stderrBytes:64*1024});let l,m=!1;try{const c=await Promise.race([f.completion,new Promise((C,w)=>{l=setTimeout(()=>{m=!0,f.stop().then(()=>w(new i(504,"hook_timeout","hook executable timed out")),b=>w(b))},S)})]);if(m)throw new i(504,"hook_timeout","hook executable timed out");if(c.stdoutTruncated)throw new i(502,"hook_output_limit","hook stdout exceeded the 10 MiB cap");return{status:200,body:{stdout:c.stdout,status:c.exitCode,signal:c.signal}}}finally{l&&clearTimeout(l)}}u(k,"handleHookExec");const V=[{method:"GET",pattern:"/v1/nodes/:id/hooks/plan",handler:B},{method:"POST",pattern:"/v1/nodes/:id/hooks/exec",handler:k},{method:"POST",pattern:"/v1/hooks/exec",handler:k}];export{V as hookExecRoutes};
1
+ var v=Object.defineProperty;var p=(o,n)=>v(o,"name",{value:n,configurable:!0});import{realpathSync as q}from"node:fs";import{isAbsolute as g,relative as x,sep as E}from"node:path";import{ApiError as i}from"../../../api/index.js";import{coreHookCatalog as T}from"../../../build-root.js";import{getNode as O}from"../../../core/canvas/canvas.js";import{isSafeNodeId as P}from"../../../core/canvas/paths.js";import{discoverHookRegistry as I}from"../../../core/command-hooks/discovery.js";import{EXEC_HOOK_TIMEOUT_MS as S}from"../../../core/command-hooks/transport/exec-invoke.js";import{buildAppProcessEnv as A}from"../../../core/runtime/spawn-env.js";import{compileLaunch as H}from"../../../core/spaces/mounts.js";import{appProcessSandboxed as N,launchAppProcess as M}from"../../../core/spaces/process.js";import{requireCurrentExecution as R}from"./broker-recovery.js";function k(o,n,t){const r=o.params.id;if(r===void 0?o.principal.class!=="person"&&o.principal.class!=="broker":!P(r)||o.principal.class!=="broker"||o.principal.node!==r)throw new i(403,"permission_error","hook execution requires its current node, or the person or a node for the global route");const e=r===void 0?null:O(r);if(r!==void 0&&!e)throw new i(404,"not_found","node not found");if(r!==void 0&&R(r,n),typeof t!="string"||!g(t))throw new i(400,"invalid_request","hook cwd must be absolute");if(!N())throw new i(400,"invalid_request","hook routes require the root launcher");let s;try{s=q(t)}catch(d){throw d.code==="ENOENT"?new i(400,"invalid_request","hook cwd does not exist"):d}if(e){const d=H({nodeId:r,app:o.principal.class==="broker"?o.principal.app:"app:terminal",sub:e.sub??"user:local",grantId:e.grant_id??null,scopes:e.scopes??null,command:[],env:{},auditMissing:p(()=>{},"auditMissing")}),h=p(a=>{const u=x(a,s);return u===""||u!==".."&&!u.startsWith(`..${E}`)&&!g(u)},"within");if(!d.mounts.some(a=>h(a.source)))throw new i(403,"permission_error","hook cwd is outside the node mounts")}return{id:r,node:e,cwd:s,app:e&&o.principal.class==="broker"?o.principal.app:"app:terminal"}}p(k,"checkedContext");async function y(o,n){const t=I(await T(),o,n);if(!t.valid)throw new i(422,"hook_registry_invalid","the effective hook registry is invalid");return t}p(y,"currentRegistry");async function B(o){const{node:n,cwd:t}=k(o,o.query.get("expected_execution_id"),o.query.get("cwd"));return{status:200,body:{hooks:(await y(t,n.profile_id??null)).hooks.filter(e=>e.plugin.scope==="user").map(e=>({id:e.id,plugin:e.plugin.name,target:e.target,phase:e.phase,op:e.op,description:e.description,effects:e.effects,declarationIndex:e.declarationIndex}))}}}p(B,"handleHookPlan");async function _(o){const n=o.body;if(!n||typeof n!="object"||Array.isArray(n))throw new i(400,"invalid_request","hook execution requires a JSON body");const t=n,{id:r,node:e,cwd:s,app:d}=k(o,t.expected_execution_id,t.cwd);if(typeof t.hook_id!="string"||typeof t.request!="string")throw new i(400,"invalid_request","hook execution requires hook_id and request");const a=(await y(s,e?.profile_id??null)).hooks.find(c=>c.id===t.hook_id);if(!a)throw new i(404,"hook_not_registered","hook id is not registered for this cwd");const u=A(s,e?.profile_id??null,d),f=await M({...r===void 0?{}:{nodeId:r},app:d,command:[a.executable,"--crtr-hook-protocol","1"],cwd:s,pluginRoot:a.plugin.root,env:u,stdin:t.request,stdoutBytes:10*1024*1024,stderrBytes:64*1024});let l,m=!1;try{const c=await Promise.race([f.completion,new Promise((C,w)=>{l=setTimeout(()=>{m=!0,f.stop().then(()=>w(new i(504,"hook_timeout","hook executable timed out")),b=>w(b))},S)})]);if(m)throw new i(504,"hook_timeout","hook executable timed out");if(c.stdoutTruncated)throw new i(502,"hook_output_limit","hook stdout exceeded the 10 MiB cap");return{status:200,body:{stdout:c.stdout,status:c.exitCode,signal:c.signal}}}finally{l&&clearTimeout(l)}}p(_,"handleHookExec");const V=[{method:"GET",pattern:"/v1/nodes/:id/hooks/plan",handler:B},{method:"POST",pattern:"/v1/nodes/:id/hooks/exec",handler:_},{method:"POST",pattern:"/v1/hooks/exec",handler:_}];export{V as hookExecRoutes};
@@ -1,2 +1,2 @@
1
- var E=Object.defineProperty;var c=(r,e)=>E(r,"name",{value:e,configurable:!0});import{join as J}from"node:path";import{claimNodeMail as W,acknowledgeNodeMail as D}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as L}from"../../../core/feed/inbox.js";import{enqueueNodeMail as q,cancelPendingNodeMail as G}from"../../../core/feed/messages.js";import{reviveNode as O}from"../../../core/runtime/revive.js";import{BrokerUnreachableError as F}from"../../../core/runtime/broker-request.js";import{isBrokerLive as C}from"../../../core/runtime/model-swap.js";import{deliverLive as U,interruptLive as H}from"../../../core/runtime/interactive-deliver.js";import{isProfilePaused as K}from"../../../core/profiles/manifest.js";import{getNode as x,withFreshTerminalGuard as Q}from"../../../core/canvas/canvas.js";import{reportsDir as V}from"../../../core/canvas/node-agent-paths.js";import{withCanvasWrite as X}from"../../../core/canvas/db.js";import{cancelCronsOnWake as I}from"../../../core/canvas/crons.js";import{assertNotFinalized as N,assertFinalizedForReopen as Y,commitReopenResident as A}from"../../../core/runtime/reopen.js";import{writeOutputSchema as Z}from"../../../core/runtime/structured-output.js";import{appendSituationalContext as j,formatSituationalProse as ee}from"../../../core/runtime/situational-context.js";import{formatDataCard as P}from"../../../shared/generated-context.js";import{hasNoNaturalCycle as te}from"../../../core/runtime/revive-all.js";import{recordPendingParkActivity as re}from"../../park-pending.js";import{wantsExecution as ne}from"../../reconcilers/node-lifecycle/wants-execution.js";import{hasFreshGroundState as oe}from"../../../core/runtime/revive.js";import{notFound as S,usage as a}from"../../../core/errors.js";import{assertScope as ie}from"../../../core/scopes.js";import{InputError as ae}from"../../../core/io.js";import{ApiError as se}from"../../../api/index.js";import{ownerOnly as de}from"../router.js";const ce=["critical","urgent","normal","deferred"];function M(r,e){if(typeof r!="object"||r===null||Array.isArray(r))throw a(`${e} must be an object { kind, facts?, body? }`);const i=r,t=i.kind;if(typeof t!="string"||t.trim()==="")throw a(`${e}.kind is required`);if(!t.includes(":"))throw a(`${e}.kind must be namespaced (contain ':'): ${t}`);const s={kind:t},n=i.facts;if(n!==void 0){if(typeof n!="object"||n===null||Array.isArray(n))throw a(`${e}.facts must be an object of string or number values`);const y={};for(const[m,f]of Object.entries(n)){if(typeof f!="string"&&typeof f!="number")throw a(`${e}.facts.${m} must be a string or number`);y[m]=f}s.facts=y}const o=i.body;if(o!==void 0){if(typeof o!="string")throw a(`${e}.body must be a string`);s.body=o}return s}c(M,"parseCardRequest");function T(r,e){try{return P(r.kind,r.facts??{},r.body??"")}catch(i){throw a(`${e}: ${i instanceof Error?i.message:String(i)}`)}}c(T,"renderCard");function ue(r){if(typeof r!="object"||r===null)throw a("a message requires a JSON body { body, tier?, fresh? }");const e=r,i=e.body,t=e.fresh===!0,s=e.tier,n=e.situational_context,o=e.output_schema,y=typeof i=="string"&&i.trim()!=="",m=typeof n=="string"&&n.trim()!=="",f=typeof o=="string"&&o.trim()!=="",g=e.situational_card,h=e.context_cards,b=g===void 0?void 0:M(g,"situational_card");if(h!==void 0&&!Array.isArray(h))throw a("context_cards must be an array of { kind, facts?, body? }");const l=h?.map((v,k)=>M(v,`context_cards[${k}]`));if(b!==void 0&&typeof n=="string"&&n!=="")throw a("situational_card and situational_context are mutually exclusive");const _=b!==void 0||l!==void 0&&l.length>0;if(!t&&!y&&!m&&!f&&!_)throw a("a message requires a non-empty body (or fresh: true, situational_context, a runtime card, or output_schema)");if(t&&l!==void 0&&l.length>0)throw a("context_cards cannot ride a fresh revive (no inbox entry carries them)");if(s!==void 0&&!ce.includes(s))throw a(`invalid tier: ${String(s)} (expected critical|urgent|normal|deferred)`);const u={body:typeof i=="string"?i:""};s!==void 0&&(u.tier=s),t&&(u.fresh=!0),e.reopen===!0&&(u.reopen=!0),typeof n=="string"&&(u.situational_context=n),b!==void 0&&(u.situational_card=b),l!==void 0&&(u.context_cards=l),typeof o=="string"&&(u.output_schema=o),typeof e.from=="string"&&(u.from=e.from);const p=e.delivery;if(p!==void 0&&p!=="interactive")throw a(`invalid delivery: ${String(p)} (expected interactive)`);if(p==="interactive"){if(t||u.situational_context!==void 0||u.output_schema!==void 0)throw a("interactive delivery supports a body, runtime cards, and reopen only (no fresh, situational_context, or output_schema)");if(!y)throw a("interactive delivery requires a non-empty body");if(u.tier==="deferred")throw a("interactive delivery cannot be deferred");u.delivery="interactive"}return u}c(ue,"parseSendBody");function fe(r){try{return JSON.parse(r)}catch{throw a("output_schema must be a JSON schema string")}}c(fe,"parseSchema");function le(r){return r.split(`
2
- `)[0].slice(0,120)}c(le,"label");function z(r,e){if(e===null)return"";const i=J(V(r),e);return P("reopen-final-report",{path:i},"This node previously completed work. Read this final report before acting on the new instruction.")}c(z,"previousFinalReportCard");function me(r,e){return new ae({error:"deferred_no_natural_cycle",message:`${r} is ${e} with no natural next cycle ahead of it \u2014 a deferred message would never be delivered.`,next:"Use --tier normal, urgent, or critical to wake it now, or --reopen (with a body or --fresh) to re-task it first."})}c(me,"deferredNoNaturalCycle");function pe(r){if(!oe(r))throw new se(422,"unprocessable",`node ${r} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}c(pe,"assertRecoverableForFresh");async function ye(r){const e=r.params.id,i=x(e);if(i===null)throw S(`unknown node: ${e}`,{received:e});const t=ue(r.body),s=t.tier??"normal",n=K(i.profile_id),o=t.from??null;if(o!==null){const d=x(o);d!==null&&ie(d,"crtr:act")}const y=t.body.trim()!=="",m=t.situational_card!==void 0?T(t.situational_card,"situational_card"):t.situational_context!==void 0?ee(t.situational_context.trim()):"",f=m!=="",g=(t.context_cards??[]).map((d,w)=>T(d,`context_cards[${w}]`)),h=t.output_schema!==void 0&&t.output_schema.trim()!==""?fe(t.output_schema):null;if(t.fresh){const d=t.reopen?Y(e):null;t.reopen||N(e),pe(e),f&&j(e,m),t.reopen&&A(e,d);const w=await O(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:w.launch!==void 0}}}t.delivery==="interactive"&&!t.reopen&&N(e);let b=!1,l="";if(t.delivery==="interactive"&&t.reopen&&(l=z(e,A(e)),b=!0),t.delivery==="interactive"&&!n&&!i.run_id&&C(i))try{return f&&j(e,m),await U(e,t.body,{cards:[...l===""?[]:[l],...f?[m]:[],...g],origin:o==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...o===null?{}:{from:o},kind:"message",tier:s}]}}),I(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(d){if(!(d instanceof F))throw d}const _=c(()=>{t.reopen||N(e),h!==null&&Z(e,"oneoff",h),f&&j(e,m),t.reopen&&!b&&(l=z(e,A(e)));const d=[...l===""?[]:[l],...g],w=d.length>0?{cards:d}:{};if(y||h!==null){const $=y?t.body:"A one-off structured-output request has been granted. Submit a result matching the requested schema with `crtr push result` before you stop; after it is accepted, continue normally.";return q(e,{senderNodeId:o,urgency:s,wake:1,kind:"message",label:le($),bodyJson:{body:$,...f?{situational:!0}:{},...w}})}return q(e,{senderNodeId:o,urgency:s,wake:1,kind:"message",label:f?"(ambient context updated)":"(context delivered)",bodyJson:{...f?{situational:!0}:{},situationalOnly:!0,...w}})},"deliverImmediate"),p=c(()=>{if(s==="deferred"){const d=Q(e,te,_);if(d.kind==="missing")throw S(`unknown node: ${e}`,{received:e});if(d.kind==="terminal")throw me(e,d.status);return d.result}return _()},"deliver")();p.urgency!=="deferred"&&X(()=>re(e));const v=x(e);if(v===null)throw S(`unknown node: ${e}`,{received:e});i.frozen_at!==null&&I(e);let k=!1,R=!1;if((t.reopen||v.lifecycle==="terminal"||!ne(v))&&p.urgency!=="deferred"&&!n&&!C(v))try{const d=await O(e,{resume:!0,capacity:"freeze"});k=d.launch!==void 0,R=d.outcome==="frozen"}catch{}return{status:201,body:{node_id:e,delivered:!0,revived:k,...R?{not_revived_reason:"capacity_frozen"}:{},delivered_at:p.createdAt,...p.urgency===s?{}:{delivered_tier:p.urgency},...t.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}c(ye,"handleMessage");async function he(r){const e=r.params.id,i=x(e);if(i===null)throw S(`unknown node: ${e}`,{received:e});const t=G(e,{senderNodeId:"human",kind:"message"});let s=!1;if(C(i))try{s=await H(e)!=="idle"}catch(o){if(!(o instanceof F))throw o}return{status:200,body:{node_id:e,outcome:s?"aborted_turn":t.length>0?"canceled_pending":"idle",aborted_turn:s,canceled_pending:t.length}}}c(he,"handleInterrupt");function B(r){if(typeof r.body!="object"||r.body===null||Array.isArray(r.body))throw a("mail requires an object body");const e=r.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw a("execution_id is required");return e}c(B,"mailBody");function be(r){const e=B(r),i=e.channel;if(i!=="wake"&&i!=="passive")throw a("channel must be wake or passive");const t=W(r.params.id,e.execution_id,i);return{status:200,body:{action:t.action,deliveries:t.deliveries.map(n=>({delivery_id:n.deliveryId,attempts:n.attempts,handoff:n.handoff,entry:L(n)}))}}}c(be,"handleMailClaim");function ve(r){const e=B(r);if(!Array.isArray(e.deliveries))throw a("deliveries must be an array");const i=e.deliveries.map(n=>{if(typeof n!="object"||n===null||Array.isArray(n))throw a("each delivery must be an object");const o=n;if(typeof o.delivery_id!="string"||o.delivery_id==="")throw a("delivery_id is required");if(!Number.isSafeInteger(o.attempts)||o.attempts<1)throw a("attempts must be a positive integer");if(o.disposition!=="acknowledged"&&o.disposition!=="released")throw a("disposition must be acknowledged or released");return{delivery_id:o.delivery_id,attempts:o.attempts,disposition:o.disposition}}),t=D(r.params.id,e.execution_id,i.map(n=>({deliveryId:n.delivery_id,attempts:n.attempts,disposition:n.disposition})));return{status:200,body:{action:t.action,results:t.results.map(n=>({delivery_id:n.deliveryId,outcome:n.outcome}))}}}c(ve,"handleMailAcknowledge");const Ke=de([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:be},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:ve}]),Qe=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:ye},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:he}];export{Ke as brokerMailRoutes,Qe as messageRoutes};
1
+ var U=Object.defineProperty;var c=(r,e)=>U(r,"name",{value:e,configurable:!0});import{randomBytes as H}from"node:crypto";import{claimNodeMail as K,acknowledgeNodeMail as Q}from"../../../core/canvas/deliveries.js";import{nodeMailEntry as V}from"../../../core/feed/inbox.js";import{enqueueNodeMail as R,cancelPendingNodeMail as X}from"../../../core/feed/messages.js";import{reviveNode as I}from"../../../core/runtime/revive.js";import{BrokerUnreachableError as M}from"../../../core/runtime/broker-request.js";import{isBrokerLive as A}from"../../../core/runtime/model-swap.js";import{deliverLive as Y,interruptLive as Z}from"../../../core/runtime/interactive-deliver.js";import{isProfilePaused as ee}from"../../../core/profiles/manifest.js";import{getNode as S,withFreshTerminalGuard as te}from"../../../core/canvas/canvas.js";import{getById as re,nodeObject as P,ownerForGrantee as ne}from"../../../core/graph/objects.js";import{recordActedOn as oe}from"../../../core/graph/edges.js";import{recordWatch as ie}from"../../../core/graph/watches.js";import{publish as B}from"../../../core/graph/events.js";import{readerFor as ae}from"../reader.js";import{withCanvasWrite as E}from"../../../core/canvas/db.js";import{cancelCronsOnWake as T}from"../../../core/canvas/crons.js";import{assertNotFinalized as C,assertFinalizedForReopen as se,commitReopenResident as j}from"../../../core/runtime/reopen.js";import{writeOutputSchema as de}from"../../../core/runtime/structured-output.js";import{appendSituationalContext as O,formatSituationalProse as ce}from"../../../core/runtime/situational-context.js";import{formatDataCard as z}from"../../../shared/generated-context.js";import{hasNoNaturalCycle as ue}from"../../../core/runtime/revive-all.js";import{recordPendingParkActivity as le}from"../../park-pending.js";import{wantsExecution as fe}from"../../reconcilers/node-lifecycle/wants-execution.js";import{hasFreshGroundState as me}from"../../../core/runtime/revive.js";import{notFound as $,usage as s}from"../../../core/errors.js";import{assertScope as pe}from"../../../core/scopes.js";import{InputError as ye}from"../../../core/io.js";import{ApiError as he}from"../../../api/index.js";import{ownerOnly as ve}from"../router.js";const be=["critical","urgent","normal","deferred"];function J(r,e){if(typeof r!="object"||r===null||Array.isArray(r))throw s(`${e} must be an object { kind, facts?, body? }`);const i=r,t=i.kind;if(typeof t!="string"||t.trim()==="")throw s(`${e}.kind is required`);if(!t.includes(":"))throw s(`${e}.kind must be namespaced (contain ':'): ${t}`);const a={kind:t},n=i.facts;if(n!==void 0){if(typeof n!="object"||n===null||Array.isArray(n))throw s(`${e}.facts must be an object of string or number values`);const p={};for(const[u,l]of Object.entries(n)){if(typeof l!="string"&&typeof l!="number")throw s(`${e}.facts.${u} must be a string or number`);p[u]=l}a.facts=p}const o=i.body;if(o!==void 0){if(typeof o!="string")throw s(`${e}.body must be a string`);a.body=o}return a}c(J,"parseCardRequest");function W(r,e){try{return z(r.kind,r.facts??{},r.body??"")}catch(i){throw s(`${e}: ${i instanceof Error?i.message:String(i)}`)}}c(W,"renderCard");function we(r){if(typeof r!="object"||r===null)throw s("a message requires a JSON body { body, tier?, fresh? }");const e=r,i=e.body,t=e.fresh===!0,a=e.tier,n=e.situational_context,o=e.output_schema,p=typeof i=="string"&&i.trim()!=="",u=typeof n=="string"&&n.trim()!=="",l=typeof o=="string"&&o.trim()!=="",g=e.situational_card,h=e.context_cards,b=g===void 0?void 0:J(g,"situational_card");if(h!==void 0&&!Array.isArray(h))throw s("context_cards must be an array of { kind, facts?, body? }");const m=h?.map((w,k)=>J(w,`context_cards[${k}]`));if(b!==void 0&&typeof n=="string"&&n!=="")throw s("situational_card and situational_context are mutually exclusive");const _=b!==void 0||m!==void 0&&m.length>0;if(!t&&!p&&!u&&!l&&!_)throw s("a message requires a non-empty body (or fresh: true, situational_context, a runtime card, or output_schema)");if(t&&m!==void 0&&m.length>0)throw s("context_cards cannot ride a fresh revive (no inbox entry carries them)");if(a!==void 0&&!be.includes(a))throw s(`invalid tier: ${String(a)} (expected critical|urgent|normal|deferred)`);const f={body:typeof i=="string"?i:""};a!==void 0&&(f.tier=a),t&&(f.fresh=!0),e.reopen===!0&&(f.reopen=!0),typeof n=="string"&&(f.situational_context=n),b!==void 0&&(f.situational_card=b),m!==void 0&&(f.context_cards=m),typeof o=="string"&&(f.output_schema=o),typeof e.from=="string"&&(f.from=e.from);const y=e.delivery;if(y!==void 0&&y!=="interactive")throw s(`invalid delivery: ${String(y)} (expected interactive)`);if(y==="interactive"){if(t||f.situational_context!==void 0||f.output_schema!==void 0)throw s("interactive delivery supports a body, runtime cards, and reopen only (no fresh, situational_context, or output_schema)");if(!p)throw s("interactive delivery requires a non-empty body");if(f.tier==="deferred")throw s("interactive delivery cannot be deferred");f.delivery="interactive"}return f}c(we,"parseSendBody");function ge(r){try{return JSON.parse(r)}catch{throw s("output_schema must be a JSON schema string")}}c(ge,"parseSchema");function _e(r){return r.split(`
2
+ `)[0].slice(0,120)}c(_e,"label");function G(r,e){return e===null?"":z("reopen-final-report",{report:`${r}/${e}`},"This node previously completed work. Read this final report before acting on the new instruction.")}c(G,"previousFinalReportCard");function ke(r,e,i){if(i!==null&&i!=="human"&&re(r,i)?.type==="node"){const n=P(r,i);return{actor:n,senderNode:n}}if(i==="human")return{actor:ne(r,"user:local"),senderNode:null};const t=ae(r,e);return{actor:t.class==="person"?t.person:t.class==="app"?t.app:t.node,senderNode:t.class==="node"?t.node:null}}c(ke,"messageActor");function L(r,e,i,t,a,n){const o=P(r,i),{actor:p,senderNode:u}=ke(r,e,t),l=a===null?{}:{pointer:a};oe(r,p,o),u!==null&&u.rowid!==o.rowid&&ie(r,u,o,"message",{endsOn:n&&a!==null?`result:${a}`:"final"}),B(r,{event:"messaged",object:o,actor:p,level:2,attrs:{},...l}),u!==null&&B(r,{event:"sent",object:u,actor:u,level:1,attrs:{to:o.id},...l})}c(L,"recordMessage");function xe(r,e){return new ye({error:"deferred_no_natural_cycle",message:`${r} is ${e} with no natural next cycle ahead of it \u2014 a deferred message would never be delivered.`,next:"Use --tier normal, urgent, or critical to wake it now, or --reopen (with a body or --fresh) to re-task it first."})}c(xe,"deferredNoNaturalCycle");function Se(r){if(!me(r))throw new he(422,"unprocessable",`node ${r} has no goal/roadmap on disk \u2014 a fresh revive would resume amnesiac.`)}c(Se,"assertRecoverableForFresh");async function $e(r){const e=r.params.id,i=S(e);if(i===null)throw $(`unknown node: ${e}`,{received:e});const t=we(r.body),a=t.tier??"normal",n=ee(i.profile_id),o=t.from??null;if(o!==null){const d=S(o);d!==null&&pe(d,"crtr:act")}const p=t.body.trim()!=="",u=t.situational_card!==void 0?W(t.situational_card,"situational_card"):t.situational_context!==void 0?ce(t.situational_context.trim()):"",l=u!=="",g=(t.context_cards??[]).map((d,v)=>W(d,`context_cards[${v}]`)),h=t.output_schema!==void 0&&t.output_schema.trim()!==""?ge(t.output_schema):null;if(t.fresh){const d=t.reopen?se(e):null;t.reopen||C(e),Se(e),l&&O(e,u),t.reopen&&j(e,d);const v=await I(e,{resume:!1,capacity:"refuse"});return{status:201,body:{node_id:e,delivered:!1,revived:v.launch!==void 0}}}t.delivery==="interactive"&&!t.reopen&&C(e);let b=!1,m="";if(t.delivery==="interactive"&&t.reopen&&(m=G(e,j(e)),b=!0),t.delivery==="interactive"&&!n&&!i.run_id&&A(i))try{return l&&O(e,u),await Y(e,t.body,{cards:[...m===""?[]:[m],...l?[u]:[],...g],origin:o==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:[{...o===null?{}:{from:o},kind:"message",tier:a}]}}),E(v=>L(v,r,e,o,null,!1)),T(e),{status:201,body:{node_id:e,delivered:!0,revived:!1,delivered_via:"engine"}}}catch(d){if(!(d instanceof M))throw d}const _=c(()=>{t.reopen||C(e);const d=H(16).toString("hex"),v=c(x=>L(x,r,e,o,d,h!==null),"withinEnqueue");h!==null&&de(e,"oneoff",h,d),l&&O(e,u),t.reopen&&!b&&(m=G(e,j(e)));const N=[...m===""?[]:[m],...g],F=N.length>0?{cards:N}:{};if(p||h!==null){const x=p?t.body:"A one-off structured-output request has been granted. Submit a result matching the requested schema with `crtr push result` before you stop; after it is accepted, continue normally.";return R(e,{senderNodeId:o,urgency:a,wake:1,kind:"message",messageId:d,withinEnqueue:v,label:_e(x),bodyJson:{body:x,...l?{situational:!0}:{},...F}})}return R(e,{senderNodeId:o,urgency:a,wake:1,kind:"message",messageId:d,withinEnqueue:v,label:l?"(ambient context updated)":"(context delivered)",bodyJson:{...l?{situational:!0}:{},situationalOnly:!0,...F}})},"deliverImmediate"),y=c(()=>{if(a==="deferred"){const d=te(e,ue,_);if(d.kind==="missing")throw $(`unknown node: ${e}`,{received:e});if(d.kind==="terminal")throw xe(e,d.status);return d.result}return _()},"deliver")();y.urgency!=="deferred"&&E(()=>le(e));const w=S(e);if(w===null)throw $(`unknown node: ${e}`,{received:e});i.frozen_at!==null&&T(e);let k=!1,q=!1;if((t.reopen||w.lifecycle==="terminal"||!fe(w))&&y.urgency!=="deferred"&&!n&&!A(w))try{const d=await I(e,{resume:!0,capacity:"freeze"});k=d.launch!==void 0,q=d.outcome==="frozen"}catch{}return{status:201,body:{node_id:e,delivered:!0,revived:k,...q?{not_revived_reason:"capacity_frozen"}:{},delivered_at:y.createdAt,...y.urgency===a?{}:{delivered_tier:y.urgency},...t.delivery==="interactive"?{delivered_via:"inbox"}:{}}}}c($e,"handleMessage");async function Ne(r){const e=r.params.id,i=S(e);if(i===null)throw $(`unknown node: ${e}`,{received:e});const t=X(e,{senderNodeId:"human",kind:"message"});let a=!1;if(A(i))try{a=await Z(e)!=="idle"}catch(o){if(!(o instanceof M))throw o}return{status:200,body:{node_id:e,outcome:a?"aborted_turn":t.length>0?"canceled_pending":"idle",aborted_turn:a,canceled_pending:t.length}}}c(Ne,"handleInterrupt");function D(r){if(typeof r.body!="object"||r.body===null||Array.isArray(r.body))throw s("mail requires an object body");const e=r.body;if(typeof e.execution_id!="string"||e.execution_id.trim()==="")throw s("execution_id is required");return e}c(D,"mailBody");function Ae(r){const e=D(r),i=e.channel;if(i!=="wake"&&i!=="passive")throw s("channel must be wake or passive");const t=K(r.params.id,e.execution_id,i);return{status:200,body:{action:t.action,deliveries:t.deliveries.map(n=>({delivery_id:n.deliveryId,attempts:n.attempts,handoff:n.handoff,entry:V(n)}))}}}c(Ae,"handleMailClaim");function Ce(r){const e=D(r);if(!Array.isArray(e.deliveries))throw s("deliveries must be an array");const i=e.deliveries.map(n=>{if(typeof n!="object"||n===null||Array.isArray(n))throw s("each delivery must be an object");const o=n;if(typeof o.delivery_id!="string"||o.delivery_id==="")throw s("delivery_id is required");if(!Number.isSafeInteger(o.attempts)||o.attempts<1)throw s("attempts must be a positive integer");if(o.disposition!=="acknowledged"&&o.disposition!=="released")throw s("disposition must be acknowledged or released");return{delivery_id:o.delivery_id,attempts:o.attempts,disposition:o.disposition}}),t=Q(r.params.id,e.execution_id,i.map(n=>({deliveryId:n.delivery_id,attempts:n.attempts,disposition:n.disposition})));return{status:200,body:{action:t.action,results:t.results.map(n=>({delivery_id:n.deliveryId,outcome:n.outcome}))}}}c(Ce,"handleMailAcknowledge");const dt=ve([{method:"POST",pattern:"/v1/nodes/:id/mail/claim",handler:Ae},{method:"POST",pattern:"/v1/nodes/:id/mail/acknowledge",handler:Ce}]),ct=[{method:"POST",pattern:"/v1/nodes/:id/messages",scope:"crtr:act",handler:$e},{method:"POST",pattern:"/v1/nodes/:id/interrupt",scope:"crtr:act",handler:Ne}];export{dt as brokerMailRoutes,ct as messageRoutes};
@@ -1,3 +1,3 @@
1
- var g=Object.defineProperty;var n=(e,t)=>g(e,"name",{value:t,configurable:!0});import{mkdirSync as v,readFileSync as N,writeFileSync as S}from"node:fs";import{dirname as w,isAbsolute as k,join as h,resolve as E}from"node:path";import{appendRotatingRecord as O}from"../../../core/log.js";import{jobDir as c,messagesDir as T}from"../../../core/canvas/paths.js";import{openDb as F}from"../../../core/canvas/db.js";import{resolveRef as A}from"../../../core/canvas/history.js";import{writeNodeRecap as D}from"../../../core/canvas/node-recap.js";import{markStopSignal as R,consumeStopSignals as x,clearStopSignals as j}from"../../../core/runtime/stop-signals.js";import{notFound as l,usage as s}from"../../../core/errors.js";import{isBeneathRefusal as q,readFileBeneath as I}from"../../../core/spaces/open-beneath.js";import{requireCurrentExecution as _}from"./broker-recovery.js";function m(e){if(e.body===null||typeof e.body!="object"||Array.isArray(e.body))throw s("node record requires a JSON object");const t=e.body;return _(e.params.id,t.expected_execution_id),t}n(m,"body");function d(e,t){if(typeof e!="string")throw s(`${t} must be a string`);return e}n(d,"text");const K=[{method:"POST",pattern:"/v1/nodes/:id/records/log",handler:n(e=>{const t=d(m(e).record,"record");return{status:200,body:{appended:O(h(c(e.params.id),"log.jsonl"),t)}}},"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/telemetry",handler:n(e=>{const t=m(e),r=t.tokens_in,o=t.tokens_out,i=t.context_tokens,u=t.last_activity,b=d(t.model,"model"),f=d(t.updated_at,"updated_at");if(typeof r!="number"||!Number.isFinite(r)||r<0||typeof o!="number"||!Number.isFinite(o)||o<0||i!==null&&(typeof i!="number"||!Number.isFinite(i)||i<0)||u!==null&&typeof u!="string"||Number.isNaN(Date.parse(f)))throw s("invalid telemetry");const y=h(c(e.params.id),"telemetry.json");let a={};try{a=JSON.parse(N(y,"utf8"))}catch(p){if(!(p instanceof SyntaxError)&&p.code!=="ENOENT")throw p}return v(c(e.params.id),{recursive:!0}),S(y,JSON.stringify({tokens_in:r,tokens_out:o,context_tokens:i??a.context_tokens,last_activity:u??a.last_activity,model:b||a.model||"",updated_at:f},null,2),"utf8"),{status:204}},"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/recap",handler:n(e=>(D(e.params.id,d(m(e).briefing,"briefing")),{status:204}),"handler")},{method:"GET",pattern:"/v1/nodes/:id/records/inbox",handler:n(e=>{const t=e.params.id,r=e.query.get("ref");if(_(t,e.query.get("execution_id")),r===null||!/^[a-z0-9-]+:reports\/[^/]+\.md$/.test(r))throw s("ref must be a report handle");if(F().prepare(`SELECT 1 FROM deliveries d JOIN messages m ON m.message_id = d.message_id
1
+ var g=Object.defineProperty;var n=(e,t)=>g(e,"name",{value:t,configurable:!0});import{mkdirSync as N,readFileSync as v,writeFileSync as S}from"node:fs";import{dirname as w,isAbsolute as k,join as h,resolve as E}from"node:path";import{appendRotatingRecord as O}from"../../../core/log.js";import{jobDir as c,messagesDir as T}from"../../../core/canvas/paths.js";import{openDb as D}from"../../../core/canvas/db.js";import{reportDocumentBody as F}from"../../../core/feed/inbox.js";import{reportRefNodeId as j}from"../../../shared/inbox-entry-body.js";import{writeNodeRecap as A}from"../../../core/canvas/node-recap.js";import{markStopSignal as R,consumeStopSignals as x,clearStopSignals as I}from"../../../core/runtime/stop-signals.js";import{notFound as p,usage as d}from"../../../core/errors.js";import{isBeneathRefusal as q,readFileBeneath as J}from"../../../core/spaces/open-beneath.js";import{requireCurrentExecution as _}from"./broker-recovery.js";function u(e){if(e.body===null||typeof e.body!="object"||Array.isArray(e.body))throw d("node record requires a JSON object");const t=e.body;return _(e.params.id,t.expected_execution_id),t}n(u,"body");function s(e,t){if(typeof e!="string")throw d(`${t} must be a string`);return e}n(s,"text");const V=[{method:"POST",pattern:"/v1/nodes/:id/records/log",handler:n(e=>{const t=s(u(e).record,"record");return{status:200,body:{appended:O(h(c(e.params.id),"log.jsonl"),t)}}},"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/telemetry",handler:n(e=>{const t=u(e),r=t.tokens_in,o=t.tokens_out,i=t.context_tokens,m=t.last_activity,b=s(t.model,"model"),f=s(t.updated_at,"updated_at");if(typeof r!="number"||!Number.isFinite(r)||r<0||typeof o!="number"||!Number.isFinite(o)||o<0||i!==null&&(typeof i!="number"||!Number.isFinite(i)||i<0)||m!==null&&typeof m!="string"||Number.isNaN(Date.parse(f)))throw d("invalid telemetry");const y=h(c(e.params.id),"telemetry.json");let a={};try{a=JSON.parse(v(y,"utf8"))}catch(l){if(!(l instanceof SyntaxError)&&l.code!=="ENOENT")throw l}return N(c(e.params.id),{recursive:!0}),S(y,JSON.stringify({tokens_in:r,tokens_out:o,context_tokens:i??a.context_tokens,last_activity:m??a.last_activity,model:b||a.model||"",updated_at:f},null,2),"utf8"),{status:204}},"handler")},{method:"PUT",pattern:"/v1/nodes/:id/records/recap",handler:n(e=>(A(e.params.id,s(u(e).briefing,"briefing")),{status:204}),"handler")},{method:"GET",pattern:"/v1/nodes/:id/records/inbox",handler:n(e=>{const t=e.params.id,r=e.query.get("ref");if(_(t,e.query.get("execution_id")),r===null||j(r)===void 0)throw d("ref must be a report handle");const o=D().prepare(`SELECT m.object_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
2
2
  WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND d.state = 'handed_off'
3
- AND d.claim_owner = ? AND d.canceled_at IS NULL AND m.body_ref = ? LIMIT 1`).get(t,e.query.get("execution_id"),r)===void 0)throw l("report was not delivered to this node");const i=A(r);if(i?.source!=="report")throw l("report not found");return{status:200,body:{content:i.body}}},"handler")},{method:"GET",pattern:"/v1/nodes/:id/records/passive",handler:n(e=>{const t=e.query.get("ref"),r=T(e.params.id);if(t===null||!k(t)||w(E(t))!==r||!t.endsWith(".md"))throw s("ref must be a direct-message spill path for this node");try{return{status:200,body:{content:I(r,t).toString("utf8")}}}catch(o){throw o.code==="ENOENT"?l("passive message not found"):q(o)?s("ref meets a symlink or is not a regular file; only the node's own message files are served"):o}},"handler")},{method:"POST",pattern:"/v1/nodes/:id/records/pushed-final",handler:n(e=>{const t=m(e);if(t.action==="mark")R(e.params.id,"pushedFinal",d(t.expected_execution_id,"expected_execution_id"));else if(t.action==="clear")j(e.params.id);else{if(t.action==="consume")return{status:200,body:x(e.params.id,d(t.expected_execution_id,"expected_execution_id"))};throw s("action must be mark, clear or consume")}return{status:200,body:{pushedFinal:!1}}},"handler")}];export{K as nodeRecordRoutes};
3
+ AND d.claim_owner = ? AND d.canceled_at IS NULL AND m.body_ref = ? LIMIT 1`).get(t,e.query.get("execution_id"),r);if(o===void 0)throw p("report was not delivered to this node");const i=o.object_id===null?null:F(o.object_id);if(i===null)throw p("report not found");return{status:200,body:{content:i}}},"handler")},{method:"GET",pattern:"/v1/nodes/:id/records/passive",handler:n(e=>{const t=e.query.get("ref"),r=T(e.params.id);if(t===null||!k(t)||w(E(t))!==r||!t.endsWith(".md"))throw d("ref must be a direct-message spill path for this node");try{return{status:200,body:{content:J(r,t).toString("utf8")}}}catch(o){throw o.code==="ENOENT"?p("passive message not found"):q(o)?d("ref meets a symlink or is not a regular file; only the node's own message files are served"):o}},"handler")},{method:"POST",pattern:"/v1/nodes/:id/records/pushed-final",handler:n(e=>{const t=u(e);if(t.action==="mark")R(e.params.id,"pushedFinal",s(t.expected_execution_id,"expected_execution_id"));else if(t.action==="clear")I(e.params.id);else{if(t.action==="consume")return{status:200,body:x(e.params.id,s(t.expected_execution_id,"expected_execution_id"))};throw d("action must be mark, clear or consume")}return{status:200,body:{pushedFinal:!1}}},"handler")}];export{V as nodeRecordRoutes};
@@ -1 +1 @@
1
- var oe=Object.defineProperty;var d=(e,t)=>oe(e,"name",{value:t,configurable:!0});import{envProfileId as re}from"../../../shared/env.js";import{existsSync as E,statSync as ie}from"node:fs";import{basename as de,isAbsolute as se,resolve as M}from"node:path";import{appendSituationalContext as ae,formatSituationalProse as le}from"../../../core/runtime/situational-context.js";import{closeNode as ce}from"../../../core/runtime/close.js";import{reviveNode as ue}from"../../../core/runtime/revive.js";import{nowIso as A}from"../../../core/fs-utils.js";import{assertLaunchModelRegistered as R,forkNode as fe,resolveForkSource as me,spawnChildPrepared as pe}from"../../../core/runtime/spawn.js";import{forkSourceNode as he}from"../../../core/runtime/nodes.js";import{childrenOf as we,getNode as O,listNodes as I,subscribersOf as ye,subscriptionsOf as L,setMessageWait as _e,updateNode as $}from"../../../core/canvas/canvas.js";import{subtreeIds as ge}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as ve}from"../../../core/canvas/db.js";import{unbindSession as be}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as ke}from"../../../core/canvas/attention.js";import{contextDir as G,nodeAgentDir as C,reportsDir as j}from"../../../core/canvas/node-agent-paths.js";import{existsBeneath as Se,isAbsentOrRefused as Oe,isBeneathRefusal as Ne,readdirBeneath as Te,statBeneath as Ae}from"../../../core/spaces/open-beneath.js";import{nodeArtifacts as Re}from"../../../core/canvas/history.js";import{readNodeMessagesPage as $e,readNodeSession as Ce,readNodeSnapshot as Pe,transcriptMarkdown as De}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as xe}from"../../../core/substrate/subject.js";import{reviveAll as Ee}from"../../../core/runtime/revive-all.js";import{promoteAsync as Me,requestYieldAsync as Ie,reshapeNodeAsync as F}from"../../../core/runtime/promote.js";import{recycleNode as Le}from"../../../core/runtime/recycle.js";import{relaunchRoot as Ge}from"../../../core/runtime/reset.js";import{assertReopenGate as je}from"../../../core/runtime/reopen.js";import{writeYieldMessage as Fe,readGoal as ze}from"../../../core/runtime/kickoff.js";import{hasRoadmap as Be,seedRoadmap as Ke}from"../../../core/runtime/roadmap.js";import{renameWindow as Ve}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as We,explicitModelIntent as Je,normalizeModel as Ye,readMergedLaunchConfigAsync as z}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as Ue}from"../../../core/model-routes.js";import{persistDormantModel as He,setModelLive as Qe}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as Xe}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as Ze}from"../../../core/runtime/broker-request.js";import{boundFleet as B}from"../../../core/runtime/fleet.js";import{writeOutputSchema as K}from"../../../core/runtime/structured-output.js";import{OUTCOME_PAYLOAD_MAX_BYTES as V}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as qe}from"../../../core/human/action-binding.js";import{resolveHumanAction as en}from"../../../core/human-actions.js";import{parseDurationMs as nn}from"../../../core/wake.js";import{claimWarmNode as tn,refillWarmPool as W,warmPoolEnabled as on}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as J,resolveLaunchTarget as rn}from"../../../core/runtime/launch-target.js";import{fullName as dn}from"../../../core/canvas/labels.js";import{reportsForNode as sn}from"./reports.js";import{getCron as an}from"../../../core/canvas/crons.js";import{cronWakeOrigin as ln}from"../../../core/runtime/bearings.js";import{boundDaemonControl as cn}from"../../control.js";import{notFound as P,usage as u}from"../../../core/errors.js";import{assertScope as un,validateScopes as Y}from"../../../core/scopes.js";import{scopeAllowed as S}from"../../../shared/env.js";import{toCloseResultDTO as fn,toNodeDetailDTO as D,toNodeSummaryDTO as mn,toReviveResultDTO as pn}from"../map.js";import{ApiError as m}from"../../../api/index.js";import{InputError as p}from"../../../core/io.js";import{canReadNode as hn}from"../router.js";import{activeGrant as wn,terminalGrant as yn}from"../../../core/grants/mirror.js";import{readConfig as _n}from"../../../core/config.js";import{hasConfiguredProviderCredential as gn,NO_PROVIDER_CREDENTIAL_MESSAGE as U}from"../../../core/runtime/provider-credential-gate.js";function f(e){const t=O(e);if(t===null)throw P(`unknown node: ${e}`,{received:e});return t}d(f,"requireMeta");function x(e){return{subscribesTo:L(e),subscribers:ye(e),children:we(e)}}d(x,"edgesFor");function v(e){const t=f(e);return D(t,x(e))}d(v,"detailOf");function vn(e){let t=0;for(const n of[G(e),j(e)])try{t+=Te(C(e),n).length}catch(i){if(!Oe(i))throw i}return t}d(vn,"countFiles");function bn(e){if(typeof e!="object"||e===null)throw u("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw u("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw u("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw u("creator must be a non-empty node id when provided");t.scopes!==void 0&&Y(t.scopes);const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw u("root_lifecycle must be 'resident' or 'terminal'");return t}d(bn,"parseCreateBody");function kn(e){if(e===void 0)return;const t=nn(e),n=t===null?null:new Date(Date.now()+t);if(t===null||!Number.isFinite(t)||t<=0||n===null||!Number.isFinite(n.getTime()))throw new m(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}d(kn,"parseDeadline");function Sn(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new m(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!qe.test(e.action))throw new m(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let t;try{t=JSON.stringify(e.payload)}catch{throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new m(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>V)throw new m(413,"payload_too_large",`serialized payload exceeds ${V} bytes`)}return e}}d(Sn,"parseOutcomeDelivery");function On(e,t){const n=en(e.action,t);if(!("kind"in n))return{actionName:e.action,argv:n.argv,cwd:n.cwd,configOrigin:n.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw n.kind==="unknown_action"?new m(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new m(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}d(On,"resolveOutcomeDelivery");function Nn(e,t,n){const i={kind:e.kind,cwd:n,prompt:e.prompt??""};return e.mode!==void 0&&(i.mode=e.mode),e.name!==void 0&&(i.name=e.name),e.description!==void 0&&(i.description=e.description),t!==void 0&&(i.parent=t),e.creator!==void 0&&(i.creator=e.creator),e.scopes!==void 0&&(i.scopes=e.scopes),e.root===!0&&(i.root=!0),e.root_lifecycle!==void 0&&(i.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(i.worktree=!0),typeof e.worktree=="string"&&(i.worktreeBase=e.worktree),e.worktree!==void 0&&(i.worktreeCwd=M(e.pin_cwd??e.cwd??n)),e.fork_from!==void 0&&(i.forkFrom=e.fork_from),e.model!==void 0&&(i.model=e.model),e.profile!==void 0&&(i.profile=e.profile),e.situational_context!==void 0&&(i.situationalContext=e.situational_context),e.node_id!==void 0&&(i.nodeId=e.node_id),i}d(Nn,"buildRecipe");function Tn(e,t,n){return!on()||e.prefer_warm!==!0||e.root!==!0||e.parent!=null||e.root_lifecycle==="terminal"||(e.prompt??"")!==""||e.model!==void 0||e.fork_from!==void 0||e.worktree!==void 0||e.node_id!==void 0||e.scopes!==void 0?null:{kind:e.kind,mode:e.mode??"base",cwd:t,profileId:n,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}d(Tn,"warmRequestFor");import{resolveCreateKind as ro}from"../../../core/runtime/launch-target.js";function H(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return Ue(e.model,t,e.modelExact===!0)}d(H,"requestFromLaunch");function An(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(i=>!S(t,i));if(n.length===0)return e;throw new m(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}d(An,"withinCeiling");async function Q(e,t,n){const i=(await We(t.kind,t.mode,{lifecycle:t.lifecycle,hasManager:e.parent!==null,model:t.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await R(H(i),{cwd:e.cwd,profileId:e.profile_id??null},n)}d(Q,"assertNodeModelChangeRegistered");async function Rn(e,t={}){const n=An(bn(e.body),e.ceiling);if(e.principal.class==="broker"){const _=e.principal;if(n.root===!0||n.parent==null||n.prefer_warm===!0)throw new m(403,"other_app_run","a broker may create only a child of its run, without a warm claim");if(n.parent!=null){const g=f(n.parent);if(g.grantee!==_.app||g.run_id!==_.run)throw new m(403,"other_app_run","cannot create outside the calling app run")}if(n.creator!==void 0&&n.creator!==_.node)throw new m(403,"other_app_run","cannot create for another node");if(n.fork_from!==void 0){let g=null;try{g=he(me(n.fork_from))}catch{}if(g?.grantee!==_.app)throw new m(403,"other_app_run","cannot fork another app's conversation")}n.creator=_.node}n.creator!==void 0&&un(f(n.creator),"crtr:act");const i=kn(n.deadline),o=Sn(n.outcome_delivery),r=n.parent??void 0;if(r==null&&n.root!==!0)throw u("a node create requires a parent (or root: true for an independent root)");let s=null;if(n.output_schema!==void 0)try{s=JSON.parse(n.output_schema)}catch{throw u("output_schema must be a JSON schema string")}const{profileId:a,kind:c,cwd:l,launch:h}=await rn(n,{validateKind:ee}),w={...n,kind:c},b=o===void 0?void 0:On(o,l);if(await R(H(h),{cwd:l,profileId:a},t.modelRegistry),!await gn(a))throw new m(412,"no_provider_credential",U,{error:"no_provider_credential",message:U,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let k=null;{const _=Tn(w,l,a);if(_!==null){const N=await tn(_,{...i===void 0?{}:{deadlineAt:i},...b===void 0?{}:{outcomeDelivery:b}},s===null?void 0:te=>K(te,"terminal",s));if(N!==null)return W(_),{status:201,body:v(N)};k=_}const g=Nn(w,r,l);i!==void 0&&(g.deadlineAt=i),b!==void 0&&(g.outcomeDelivery=b),g.readiness=n.root===!0?"await":"launch";const ne=await pe(g,s===null?void 0:N=>K(N,"terminal",s),()=>{k!==null&&W(k)});return{status:201,body:v(ne.node.node_id)}}}d(Rn,"handleCreate");function y(e,t){const n=e.query.getAll(t);if(n.length>1)throw u(`${t} must appear at most once`);return n[0]}d(y,"singleQueryValue");function X(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw u(`${t} must be true or false`)}}d(X,"optionalBoolean");function T(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw u(`${t} must be one of: ${n.join(", ")}`)}}d(T,"oneOf");function $n(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[k]of e.query)if(!t.has(k))throw u(`unknown nodes query parameter: ${k}`);const n=T(y(e,"status"),"status",["active","idle","done","dead","canceled"]),i=T(y(e,"lifecycle"),"lifecycle",["terminal","resident"]),o=y(e,"kind"),r=T(y(e,"mode"),"mode",["base","orchestrator"]),s=y(e,"profile_id"),a=y(e,"profile_prefix"),c=y(e,"parent"),l=X(y(e,"top_level"),"top_level"),h=y(e,"under"),w=X(y(e,"hanging"),"hanging"),b=T(y(e,"include"),"include",["activity"]);if(c!==void 0&&l===!0)throw u("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...i!==void 0?{lifecycle:i}:{},...o!==void 0?{kind:o}:{},...r!==void 0?{mode:r}:{},...s!==void 0?{profile_id:s}:{},...a!==void 0?{profile_prefix:a}:{},...c!==void 0?{parent:c}:{},...l!==void 0?{top_level:l}:{},...h!==void 0?{under:h}:{},...w!==void 0?{hanging:w}:{},...b!==void 0?{include:b}:{}}}d($n,"parseListQuery");function Cn(e){const t=$n(e);let n=t.status!==void 0?I({status:t.status}):I();if(e.principal.class!=="person"&&(n=n.filter(r=>hn(e.principal,r.grantee??"app:terminal"))),t.lifecycle!==void 0&&(n=n.filter(r=>r.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(r=>r.kind===t.kind)),t.mode!==void 0&&(n=n.filter(r=>r.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(r=>r.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(r=>r.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(r=>r.parent===t.parent)),t.top_level===!0&&(n=n.filter(r=>r.parent===null)),t.under!==void 0){const r=new Set(ge(t.under));n=n.filter(s=>r.has(s.node_id))}t.hanging===!0&&(n=n.filter(r=>r.parent!==null&&O(r.parent)===null));const i=t.include==="activity"?ke(n.map(r=>r.node_id)):null;return{status:200,body:n.map(r=>{const s=mn(r);if(i!==null){const a=sn(r.node_id);s.activity={latest_report:a[0]??null,final_report:r.final_report===null?null:a.find(c=>de(c.path)===r.final_report)??null,pending_human_count:i[r.node_id]??0}}return s})}}d(Cn,"handleList");function Pn(e){const t=e.params.id;return f(t),{status:200,body:v(t)}}d(Pn,"handleDetail");async function Dn(e){const t=e.params.id;f(t);const n=await Pe(t);return{status:200,body:{node_id:t,snapshot:{messages:n.snapshot.messages,...n.snapshot.messageIds===void 0?{}:{messageIds:n.snapshot.messageIds},messageVisibility:n.snapshot.messageVisibility,turnVisibility:n.snapshot.turnVisibility,stats:n.snapshot.stats,state:n.snapshot.state,display:n.snapshot.display,...n.snapshot.queued===void 0?{}:{queued:n.snapshot.queued},...n.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:n.snapshot.toolGroupSummaries},...n.snapshot.workingActivity===void 0?{}:{workingActivity:n.snapshot.workingActivity}},commands:n.commands.map(o=>({name:o.name,description:o.description,source:o.source})),captured_at:A()}}}d(Dn,"handleSnapshot");async function xn(e){const t=e.params.id,n=xe(t);if(n===null)throw P(`unknown node: ${t}`,{received:t});return{status:200,body:n}}d(xn,"handleSubject");function En(e){for(const[r]of e.query)if(r!=="cursor"&&r!=="limit")throw u(`unknown messages query parameter: ${r}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw u("cursor must appear at most once");if(n.length>1)throw u("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const i=n[0],o=Number(i);if(!Number.isSafeInteger(o)||i==="")throw u("limit must be an integer from 1 through 500");return t.length===0?{limit:o}:{cursor:t[0],limit:o}}d(En,"parseMessagesQuery");async function Mn(e){const t=e.params.id,n=await $e(t,En(e));return{status:200,body:{node_id:t,messages:n.messages,...n.messageIds===void 0?{}:{message_ids:n.messageIds},message_visibility:n.messageVisibility,next_cursor:n.nextCursor,captured_at:A()}}}d(Mn,"handleMessages");function In(e){const t=e.params.id;f(t);const n=Ce(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:A()}}}d(In,"handleSession");async function Ln(e){const t=e.params.id;return f(t),{status:200,body:{node_id:t,markdown:await De(t)}}}d(Ln,"handleTranscript");function Gn(e){const t=e.params.id;f(t);const n=d((o,r)=>({node_id:o,label:O(o)?.name??o,dir:G(o),reports_dir:j(o),self:r,files:vn(o)}),"root"),i=[n(t,!0),...L(t).map(o=>n(o.node_id,!1))].filter(o=>Z(o.node_id,o.dir)||Z(o.node_id,o.reports_dir));return{status:200,body:{node_id:t,roots:i}}}d(Gn,"handleContext");function Z(e,t){try{return Se(C(e),t)}catch(n){if(Ne(n))return!1;throw n}}d(Z,"hasDir");function jn(e,t){if(t===null)return 0;try{return Ae(C(e),t).size}catch{return 0}}d(jn,"artifactSize");function Fn(e){const t=e.params.id;f(t);const n=e.query.get("type"),i=Re(t,n!==null?[n]:void 0).map(r=>({ref:r.ref,source:r.source==="report"&&r.reportKind!==void 0?`report:${r.reportKind}`:r.source,ts:r.ts,title:r.title,size:jn(t,r.path)}));return{status:200,body:{node_id:t,artifacts:i}}}d(Fn,"handleArtifacts");async function zn(e){const t=f(e.params.id),n=e.principal.class==="broker"?e.principal.scopes:e.ceiling,i=n===null?void 0:t.scopes==null?[...n]:[...new Set([...t.scopes.filter(r=>S(n,r)),...n.filter(r=>S(t.scopes,r))])],o=await fe(t.node_id,i);return{status:201,body:v(o.node.node_id)}}d(zn,"handleFork");async function Bn(e){const t=e.params.id;f(t);const n=e.body,i=n?.resume??!0,o=n?.reopen??!1;je(t,o);const r=!i&&n?.cron_id!==void 0?an(n.cron_id):null,s=await ue(t,{resume:i,capacity:"refuse",...r!==null?{wakeReason:ln(r,"schedule_revive")}:{}}),a=O(t)?.status??"active";return{status:200,body:pn(t,s,a)}}d(Bn,"handleRevive");async function Kn(e){const t=e.params.id;return{status:200,body:{newNodeId:(await Ge(t))?.newNodeId??null}}}d(Kn,"handleRelaunchRoot");function Vn(e){const t=e.params.id;f(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw u("caller_pid must be a positive integer when provided");const i=cn(),o=ce(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...i===null?{}:{registerDetached:i.registerDetached}});return{status:200,body:fn(o)}}d(Vn,"handleClose");async function Wn(e){const t=e.params.id;f(t);const n=await Le(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}d(Wn,"handleRecycle");async function Jn(e){const t=e.params.id;return f(t),await F(t,{lifecycle:"terminal"}),{status:200,body:v(t)}}d(Jn,"handleDemote");async function Yn(e,t={}){const n=e.params.id,i=f(n),o=e.body??{};o.kind!==void 0&&await J(o.kind,i.cwd,i.profile_id??null),o.model!==void 0&&await Q(i,{kind:o.kind??i.kind,mode:"orchestrator",lifecycle:o.resident===!0?"resident":i.lifecycle,model:o.model},t.modelRegistry);const r=await Me(n,{...o.kind!==void 0?{kind:o.kind}:{},...o.resident===!0?{resident:!0}:{},...o.model!==void 0?{model:o.model}:{}}),s=D(r.meta,x(n));return s.roadmap_written=r.roadmapWritten,s.roadmap_path=r.roadmapPath,s.goal_path=r.goalPath,{status:200,body:s}}d(Yn,"handlePromote");async function Un(e,t={}){const n=e.params.id,i=f(n),o=e.body??{};o.kind!==void 0&&await J(o.kind,i.cwd,i.profile_id??null),o.model!==void 0&&await Q(i,{kind:o.kind??i.kind,mode:o.promote===!0?"orchestrator":i.mode,lifecycle:i.lifecycle,model:o.model},t.modelRegistry);const r=o.note??"Refresh: continue against your roadmap or goal.";Fe(n,r);const s=await Ie(n,{...o.promote===!0?{promote:!0}:{},...o.kind!==void 0?{kind:o.kind}:{},...o.model!==void 0?{model:o.model}:{}});return{status:200,body:D(s.meta,x(n))}}d(Un,"handleYield");function Hn(e){const t=e.params.id;f(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw u("a wait requires a controller node id");const i=O(n.controller);if(i===null)throw P(`unknown controller: ${n.controller}`,{received:n.controller});if(i.status!=="active"&&i.status!=="idle")throw new m(422,"unprocessable",`controller ${n.controller} is ${i.status}`);return _e(t,n.controller),{status:200,body:v(t)}}d(Hn,"handleWait");async function Qn(){const e=await Ee();return{status:200,body:{revived:[...e.revived],failed:[...e.failed],frozen:[...e.frozen]}}}d(Qn,"handleReviveAll");async function Xn(e,t={}){const n=e.params.id,i=e.body;let o;if(i===void 0)o={};else if(typeof i=="object"&&i!==null&&!Array.isArray(i))o=i;else throw new p({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:i,field:"cwd",next:"Send a config patch with a non-empty absolute cwd string."});if(Object.prototype.hasOwnProperty.call(o,"cwd")){const s=o.cwd;if(typeof s!="string"||s==="")throw new p({error:"cwd_invalid",message:"cwd must be a non-empty string",received:s,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(o).some(l=>l!=="cwd"&&o[l]!==void 0))throw new p({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:o,field:"cwd",next:"Send cwd as the only config field."});const a=f(n);if(B().has(n)){const l=`${n} cannot repair its cwd while its broker is live`;throw new m(409,"cwd_node_live",l,{error:"cwd_node_live",message:l,received:s,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(a.fork_from!=null)throw new p({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${a.cwd}`,received:s,field:"cwd",next:`Restore ${a.cwd}, then revive the fork normally.`});if(a.managed_worktree?.state==="open")throw new p({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:s,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(E(a.cwd))throw new p({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${a.cwd}; cwd repair is not a relocation command`,received:s,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!se(s))throw new p({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${s}`,received:s,field:"cwd",next:"Send an absolute path."});const c=M(s);if(!E(c))throw new p({error:"cwd_missing",message:`cwd does not exist: ${c}`,received:s,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!ie(c).isDirectory())throw new p({error:"cwd_not_a_directory",message:`cwd is not a directory: ${c}`,received:s,field:"cwd",next:"Send an existing absolute directory."})}catch(l){throw l instanceof p?l:new p({error:"cwd_missing",message:`cwd does not exist: ${c}`,received:s,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return ve(()=>{$(n,{cwd:c}),be(n)}),{status:200,body:v(n)}}let r=f(n);if(o.scopes!==void 0){const s=Y(o.scopes),a=r.grantee==="app:terminal"?yn():r.grant_id?wn(r.grant_id):null,c=r.grantee==="app:terminal"&&!_n("user").runtime?.issuer;if(!s.every(l=>S(r.scopes,l)&&(a?S(a.resolved,l):c)))throw new p({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:s,field:"scopes",next:"Send only scopes the node currently holds."});if(s.includes("crtr:act")&&!S(s,"crtr:llm"))throw new m(400,"invalid_scope","crtr:act requires crtr:llm");r=$(n,{scopes:s})}if(o.situational_context!==void 0&&ae(n,le(o.situational_context)),o.model!==void 0){const s=(await z(r.cwd,r.profile_id??null)).modelLadders,a=Je(o.model,s),c=Ye(o.model,s);await R({kind:"concrete",spec:c},{cwd:r.cwd,profileId:r.profile_id??null},t.modelRegistry);const l=B();let h=!1;if(l.isClaimed(n)&&await Xe(n,l.get(n)?.handle.exited)&&(h=await Qe(n,c,a).then(()=>!0,w=>{if(w instanceof Ze)return!1;throw w})),!h){if(l.isClaimed(n)){const w=`${n}'s broker did not accept the model switch; the model was not changed`;throw new m(409,"broker_not_ready",w,{error:"broker_not_ready",message:w,received:o.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!c.includes("/"))throw u(`model must resolve to a provider/id spec: ${o.model}`);He(n,c,a)}r=f(n)}if(o.kind!==void 0||o.mode!==void 0||o.lifecycle!==void 0){o.kind!==void 0&&await ee(o.kind);const s=o.kind??r.kind,a=o.mode??r.mode,c=o.lifecycle??r.lifecycle;let l;a==="orchestrator"&&!Be(n)&&(l=d(()=>{const h=ze(n);Ke(n,h!==null&&h.trim()!==""?{goal:h.trim()}:{})},"beforePersist")),r=await F(n,{...o.kind!==void 0?{kind:s}:{},...o.mode!==void 0?{mode:a}:{},...o.lifecycle!==void 0?{lifecycle:c}:{}},l)}return o.name!==void 0&&(r=$(n,{name:o.name}),r.window&&Ve(r.window,dn(r))),{status:200,body:v(n)}}d(Xn,"handleConfig");async function q(){return(await z(process.cwd(),re()||null)).kinds}d(q,"daemonKinds");async function ee(e){const t=Object.keys(await q());if(!t.includes(e))throw u(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}d(ee,"assertKindServer");async function Zn(){const e=await q();return{status:200,body:{kinds:Object.keys(e).sort().map(n=>({kind:n,when_to_use:e[n]?.whenToUse??null,available_to:e[n]?.availableTo??null}))}}}d(Zn,"handleListKinds");const no=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:Rn},{method:"GET",pattern:"/v1/nodes",handler:Cn},{method:"GET",pattern:"/v1/kinds",handler:d(()=>Zn(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:d(()=>Qn(),"handler")},{method:"GET",pattern:"/v1/nodes/:id",handler:Pn},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:Dn},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:xn},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:Mn},{method:"GET",pattern:"/v1/nodes/:id/session",handler:In},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:Ln},{method:"GET",pattern:"/v1/nodes/:id/context",handler:Gn},{method:"GET",pattern:"/v1/nodes/:id/artifacts",handler:Fn},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:zn},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:Bn},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:Kn},{method:"POST",pattern:"/v1/nodes/:id/close",handler:Vn},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:Wn},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Jn},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Yn},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:Un},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:Hn},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Xn}];export{Xn as handleConfig,Rn as handleCreate,zn as handleFork,Cn as handleList,Yn as handlePromote,Un as handleYield,no as nodeRoutes,ro as resolveCreateKind};
1
+ var re=Object.defineProperty;var d=(e,t)=>re(e,"name",{value:t,configurable:!0});import{envProfileId as ie}from"../../../shared/env.js";import{existsSync as j,statSync as de}from"node:fs";import{isAbsolute as se,resolve as I}from"node:path";import{appendSituationalContext as ae,formatSituationalProse as le}from"../../../core/runtime/situational-context.js";import{closeNode as ce}from"../../../core/runtime/close.js";import{reviveNode as ue}from"../../../core/runtime/revive.js";import{nowIso as R}from"../../../core/fs-utils.js";import{assertLaunchModelRegistered as $,forkNode as fe,resolveForkSource as me,spawnChildPrepared as pe}from"../../../core/runtime/spawn.js";import{forkSourceNode as he}from"../../../core/runtime/nodes.js";import{childrenOf as we,getNode as O,listNodes as x,subscribersOf as ye,subscriptionsOf as M,setMessageWait as ge,updateNode as C}from"../../../core/canvas/canvas.js";import{subtreeIds as _e}from"../../../core/canvas/nav-model.js";import{withCanvasWrite as L}from"../../../core/canvas/db.js";import{nodeObject as be}from"../../../core/graph/objects.js";import{recordActedOn as ve}from"../../../core/graph/edges.js";import{publish as ke}from"../../../core/graph/events.js";import{readerFor as Se}from"../reader.js";import{unbindSession as Oe}from"../../../core/canvas/sessions.js";import{ticketCountsForNodes as Ne}from"../../../core/canvas/attention.js";import{contextDir as F,nodeAgentDir as G}from"../../../core/canvas/node-agent-paths.js";import{existsBeneath as Te,isAbsentOrRefused as Ae,isBeneathRefusal as Re,readdirBeneath as $e}from"../../../core/spaces/open-beneath.js";import{readNodeMessagesPage as Ce,readNodeSession as Ee,readNodeSnapshot as De,transcriptMarkdown as Pe}from"../../../core/runtime/node-read.js";import{assembleNodeSubject as je}from"../../../core/substrate/subject.js";import{reviveAll as Ie}from"../../../core/runtime/revive-all.js";import{promoteAsync as xe,requestYieldAsync as Me,reshapeNodeAsync as B}from"../../../core/runtime/promote.js";import{recycleNode as Le}from"../../../core/runtime/recycle.js";import{relaunchRoot as Fe}from"../../../core/runtime/reset.js";import{assertReopenGate as Ge}from"../../../core/runtime/reopen.js";import{writeYieldMessage as Be,readGoal as Ve}from"../../../core/runtime/kickoff.js";import{ensureRoadmap as We,hasRoadmap as ze}from"../../../core/runtime/roadmap.js";import{renameWindow as Je}from"../../../core/runtime/placement.js";import{buildLaunchSpecAsync as Ke,explicitModelIntent as Ue,normalizeModel as Ye,readMergedLaunchConfigAsync as V}from"../../../core/runtime/launch.js";import{modelRequestFromConfig as He}from"../../../core/model-routes.js";import{persistDormantModel as Qe,setModelLive as Xe}from"../../../core/runtime/model-swap.js";import{waitForBrokerViewSocket as Ze}from"../../../core/runtime/view-socket.js";import{BrokerUnreachableError as qe}from"../../../core/runtime/broker-request.js";import{boundFleet as W}from"../../../core/runtime/fleet.js";import{writeOutputSchema as z}from"../../../core/runtime/structured-output.js";import{OUTCOME_PAYLOAD_MAX_BYTES as J}from"../../../core/canvas/types.js";import{HUMAN_ACTION_NAME_PATTERN as en}from"../../../core/human/action-binding.js";import{resolveHumanAction as nn}from"../../../core/human-actions.js";import{parseDurationMs as tn}from"../../../core/wake.js";import{claimWarmNode as on,refillWarmPool as K,warmPoolEnabled as rn}from"../../../core/runtime/warm-pool.js";import{assertLaunchKind as U,resolveLaunchTarget as dn}from"../../../core/runtime/launch-target.js";import{fullName as sn}from"../../../core/canvas/labels.js";import{reportsForNode as Y}from"./reports.js";import{getCron as an}from"../../../core/canvas/crons.js";import{cronWakeOrigin as ln}from"../../../core/runtime/bearings.js";import{boundDaemonControl as cn}from"../../control.js";import{notFound as E,usage as f}from"../../../core/errors.js";import{assertScope as un,validateScopes as H}from"../../../core/scopes.js";import{scopeAllowed as S}from"../../../shared/env.js";import{toCloseResultDTO as fn,toNodeDetailDTO as D,toNodeSummaryDTO as mn,toReviveResultDTO as pn}from"../map.js";import{ApiError as p}from"../../../api/index.js";import{InputError as y}from"../../../core/io.js";import{canReadNode as hn}from"../router.js";import{activeGrant as wn,terminalGrant as yn}from"../../../core/grants/mirror.js";import{readConfig as gn}from"../../../core/config.js";import{hasConfiguredProviderCredential as _n,NO_PROVIDER_CREDENTIAL_MESSAGE as Q}from"../../../core/runtime/provider-credential-gate.js";function m(e){const t=O(e);if(t===null)throw E(`unknown node: ${e}`,{received:e});return t}d(m,"requireMeta");function P(e){return{subscribesTo:M(e),subscribers:ye(e),children:we(e)}}d(P,"edgesFor");function k(e){const t=m(e);return D(t,P(e))}d(k,"detailOf");function bn(e){let t=Y(e).length;try{t+=$e(G(e),F(e)).length}catch(n){if(!Ae(n))throw n}return t}d(bn,"countFiles");function vn(e){if(typeof e!="object"||e===null)throw f("a node create requires a JSON body");const t=e;if(t.kind!==void 0&&(typeof t.kind!="string"||t.kind.trim()===""))throw f("kind must be a non-empty string when provided");if(t.description!==void 0&&(typeof t.description!="string"||t.description.trim()===""))throw f("description must be a non-empty string when provided");if(t.creator!==void 0&&(typeof t.creator!="string"||t.creator.trim()===""))throw f("creator must be a non-empty node id when provided");t.scopes!==void 0&&H(t.scopes);const n=t.root_lifecycle;if(n!==void 0&&n!=="resident"&&n!=="terminal")throw f("root_lifecycle must be 'resident' or 'terminal'");return t}d(vn,"parseCreateBody");function kn(e){if(e===void 0)return;const t=tn(e),n=t===null?null:new Date(Date.now()+t);if(t===null||!Number.isFinite(t)||t<=0||n===null||!Number.isFinite(n.getTime()))throw new p(422,"invalid_deadline","`deadline` must be a positive representable duration");return n.toISOString()}d(kn,"parseDeadline");function Sn(e){if(e!==void 0){if(typeof e!="object"||e===null||Array.isArray(e))throw new p(400,"invalid_request","`outcome_delivery` must be an object");if(typeof e.action!="string"||!en.test(e.action))throw new p(400,"invalid_request","`outcome_delivery.action` must be a declared action name");if(e.payload!==void 0){let t;try{t=JSON.stringify(e.payload)}catch{throw new p(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable")}if(t===void 0)throw new p(400,"invalid_request","`outcome_delivery.payload` must be JSON-serializable");if(Buffer.byteLength(t,"utf8")>J)throw new p(413,"payload_too_large",`serialized payload exceeds ${J} bytes`)}return e}}d(Sn,"parseOutcomeDelivery");function On(e,t){const n=nn(e.action,t);if(!("kind"in n))return{actionName:e.action,argv:n.argv,cwd:n.cwd,configOrigin:n.configOrigin,...e.payload===void 0?{}:{payload:e.payload}};throw n.kind==="unknown_action"?new p(422,"unknown_action",`no action named ${e.action} is declared from ${t}`):new p(422,"invalid_action",`${e.action} is declared in ${n.configOrigin} but unusable: ${n.reason}`,{reason:n.reason,configOrigin:n.configOrigin})}d(On,"resolveOutcomeDelivery");function Nn(e,t,n){const r={kind:e.kind,cwd:n,prompt:e.prompt??""};return e.mode!==void 0&&(r.mode=e.mode),e.name!==void 0&&(r.name=e.name),e.description!==void 0&&(r.description=e.description),t!==void 0&&(r.parent=t),e.creator!==void 0&&(r.creator=e.creator),e.scopes!==void 0&&(r.scopes=e.scopes),e.root===!0&&(r.root=!0),e.root_lifecycle!==void 0&&(r.rootLifecycle=e.root_lifecycle),(e.worktree===!0||typeof e.worktree=="string")&&(r.worktree=!0),typeof e.worktree=="string"&&(r.worktreeBase=e.worktree),e.worktree!==void 0&&(r.worktreeCwd=I(e.pin_cwd??e.cwd??n)),e.fork_from!==void 0&&(r.forkFrom=e.fork_from),e.model!==void 0&&(r.model=e.model),e.profile!==void 0&&(r.profile=e.profile),e.situational_context!==void 0&&(r.situationalContext=e.situational_context),e.node_id!==void 0&&(r.nodeId=e.node_id),r}d(Nn,"buildRecipe");function Tn(e,t,n){return!rn()||e.prefer_warm!==!0||e.root!==!0||e.parent!=null||e.root_lifecycle==="terminal"||(e.prompt??"")!==""||e.model!==void 0||e.fork_from!==void 0||e.worktree!==void 0||e.node_id!==void 0||e.scopes!==void 0?null:{kind:e.kind,mode:e.mode??"base",cwd:t,profileId:n,model:e.model??null,situationalContext:e.situational_context??null,name:e.name??null,creator:e.creator??null}}d(Tn,"warmRequestFor");import{resolveCreateKind as lo}from"../../../core/runtime/launch-target.js";function X(e){const t=e.modelIntent===void 0?void 0:`${e.modelIntent.family}/${e.modelIntent.strength}`;return He(e.model,t,e.modelExact===!0)}d(X,"requestFromLaunch");function An(e,t){if(t===null)return e;if(e.scopes===void 0)return{...e,scopes:[...t]};const n=e.scopes.filter(r=>!S(t,r));if(n.length===0)return e;throw new p(403,"scope_denied",`scopes exceed the bearer token's ceiling: ${n.join(", ")}`,{scopes:n,ceiling:t})}d(An,"withinCeiling");async function Z(e,t,n){const r=(await Ke(t.kind,t.mode,{lifecycle:t.lifecycle,hasManager:e.parent!==null,model:t.model,modelOverride:!0,cwd:e.cwd,profileId:e.profile_id??null})).launch;await $(X(r),{cwd:e.cwd,profileId:e.profile_id??null},n)}d(Z,"assertNodeModelChangeRegistered");async function Rn(e,t={}){const n=An(vn(e.body),e.ceiling);if(e.principal.class==="broker"){const b=e.principal;if(n.prefer_warm===!0&&b.app!=="app:terminal"&&(n.prefer_warm=!1),n.parent!=null&&m(n.parent).grantee!==b.app)throw new p(403,"other_app_run","cannot create a child under another app's node");if(n.creator!==void 0&&n.creator!==b.node)throw new p(403,"other_app_run","cannot create for another node");if(n.fork_from!==void 0){let v=null;try{v=he(me(n.fork_from))}catch{}if(v?.grantee!==b.app)throw new p(403,"other_app_run","cannot fork another app's conversation")}n.creator=b.node}n.creator!==void 0&&un(m(n.creator),"crtr:act");const r=kn(n.deadline),o=Sn(n.outcome_delivery),i=n.parent??void 0;if(i==null&&n.root!==!0)throw f("a node create requires a parent (or root: true for an independent root)");let a=null;if(n.output_schema!==void 0)try{a=JSON.parse(n.output_schema)}catch{throw f("output_schema must be a JSON schema string")}const{profileId:h,kind:s,cwd:l,launch:u}=await dn(n,{validateKind:ne}),c={...n,kind:s},w=o===void 0?void 0:On(o,l);if(await $(X(u),{cwd:l,profileId:h},t.modelRegistry),!await _n(h))throw new p(412,"no_provider_credential",Q,{error:"no_provider_credential",message:Q,next:"The person running this runtime logs a provider in with `crtr sys setup`, or stores a provider key on the profile."});let g=null;{const b=Tn(c,l,h);if(b!==null){const N=await on(b,{...r===void 0?{}:{deadlineAt:r},...w===void 0?{}:{outcomeDelivery:w}},a===null?void 0:oe=>z(oe,"terminal",a));if(N!==null)return K(b),{status:201,body:k(N)};g=b}const v=Nn(c,i,l);r!==void 0&&(v.deadlineAt=r),w!==void 0&&(v.outcomeDelivery=w),v.readiness=n.root===!0?"await":"launch";const te=await pe(v,a===null?void 0:N=>z(N,"terminal",a),()=>{g!==null&&K(g)});return{status:201,body:k(te.node.node_id)}}}d(Rn,"handleCreate");function _(e,t){const n=e.query.getAll(t);if(n.length>1)throw f(`${t} must appear at most once`);return n[0]}d(_,"singleQueryValue");function q(e,t){if(e!==void 0){if(e==="1"||e==="true")return!0;if(e==="0"||e==="false")return!1;throw f(`${t} must be true or false`)}}d(q,"optionalBoolean");function T(e,t,n){if(e!==void 0){if(n.includes(e))return e;throw f(`${t} must be one of: ${n.join(", ")}`)}}d(T,"oneOf");function $n(e){const t=new Set(["status","lifecycle","kind","mode","profile_id","profile_prefix","parent","top_level","under","hanging","include"]);for(const[g]of e.query)if(!t.has(g))throw f(`unknown nodes query parameter: ${g}`);const n=T(_(e,"status"),"status",["active","idle","done","dead","canceled"]),r=T(_(e,"lifecycle"),"lifecycle",["terminal","resident"]),o=_(e,"kind"),i=T(_(e,"mode"),"mode",["base","orchestrator"]),a=_(e,"profile_id"),h=_(e,"profile_prefix"),s=_(e,"parent"),l=q(_(e,"top_level"),"top_level"),u=_(e,"under"),c=q(_(e,"hanging"),"hanging"),w=T(_(e,"include"),"include",["activity"]);if(s!==void 0&&l===!0)throw f("parent and top_level=true cannot be combined");return{...n!==void 0?{status:n}:{},...r!==void 0?{lifecycle:r}:{},...o!==void 0?{kind:o}:{},...i!==void 0?{mode:i}:{},...a!==void 0?{profile_id:a}:{},...h!==void 0?{profile_prefix:h}:{},...s!==void 0?{parent:s}:{},...l!==void 0?{top_level:l}:{},...u!==void 0?{under:u}:{},...c!==void 0?{hanging:c}:{},...w!==void 0?{include:w}:{}}}d($n,"parseListQuery");function Cn(e){const t=$n(e);let n=t.status!==void 0?x({status:t.status}):x();if(e.principal.class!=="person"&&(n=n.filter(i=>hn(e.principal,i.grantee??"app:terminal"))),t.lifecycle!==void 0&&(n=n.filter(i=>i.lifecycle===t.lifecycle)),t.kind!==void 0&&(n=n.filter(i=>i.kind===t.kind)),t.mode!==void 0&&(n=n.filter(i=>i.mode===t.mode)),t.profile_id!==void 0&&(n=n.filter(i=>i.profile_id===t.profile_id)),t.profile_prefix!==void 0&&(n=n.filter(i=>i.profile_id?.startsWith(t.profile_prefix))),t.parent!==void 0&&(n=n.filter(i=>i.parent===t.parent)),t.top_level===!0&&(n=n.filter(i=>i.parent===null)),t.under!==void 0){const i=new Set(_e(t.under));n=n.filter(a=>i.has(a.node_id))}t.hanging===!0&&(n=n.filter(i=>i.parent!==null&&O(i.parent)===null));const r=t.include==="activity"?Ne(n.map(i=>i.node_id)):null;return{status:200,body:n.map(i=>{const a=mn(i);if(r!==null){const h=Y(i.node_id);a.activity={latest_report:h[0]??null,final_report:i.final_report===null?null:h.find(s=>s.name===i.final_report)??null,pending_human_count:r[i.node_id]??0}}return a})}}d(Cn,"handleList");function En(e){const t=e.params.id;return m(t),{status:200,body:k(t)}}d(En,"handleDetail");async function Dn(e){const t=e.params.id;m(t);const n=await De(t);return{status:200,body:{node_id:t,snapshot:{messages:n.snapshot.messages,...n.snapshot.messageIds===void 0?{}:{messageIds:n.snapshot.messageIds},messageVisibility:n.snapshot.messageVisibility,turnVisibility:n.snapshot.turnVisibility,stats:n.snapshot.stats,state:n.snapshot.state,display:n.snapshot.display,...n.snapshot.queued===void 0?{}:{queued:n.snapshot.queued},...n.snapshot.toolGroupSummaries===void 0?{}:{toolGroupSummaries:n.snapshot.toolGroupSummaries},...n.snapshot.workingActivity===void 0?{}:{workingActivity:n.snapshot.workingActivity}},commands:n.commands.map(o=>({name:o.name,description:o.description,source:o.source})),captured_at:R()}}}d(Dn,"handleSnapshot");async function Pn(e){const t=e.params.id,n=je(t);if(n===null)throw E(`unknown node: ${t}`,{received:t});return{status:200,body:n}}d(Pn,"handleSubject");function jn(e){for(const[i]of e.query)if(i!=="cursor"&&i!=="limit")throw f(`unknown messages query parameter: ${i}`);const t=e.query.getAll("cursor"),n=e.query.getAll("limit");if(t.length>1)throw f("cursor must appear at most once");if(n.length>1)throw f("limit must appear at most once");if(n.length===0)return t.length===0?{}:{cursor:t[0]};const r=n[0],o=Number(r);if(!Number.isSafeInteger(o)||r==="")throw f("limit must be an integer from 1 through 500");return t.length===0?{limit:o}:{cursor:t[0],limit:o}}d(jn,"parseMessagesQuery");async function In(e){const t=e.params.id,n=await Ce(t,jn(e));return{status:200,body:{node_id:t,messages:n.messages,...n.messageIds===void 0?{}:{message_ids:n.messageIds},message_visibility:n.messageVisibility,next_cursor:n.nextCursor,captured_at:R()}}}d(In,"handleMessages");function xn(e){const t=e.params.id;m(t);const n=Ee(t);return{status:200,body:{node_id:t,session_file:n.sessionFile,session_jsonl:n.sessionJsonl,system_prompt:n.systemPrompt,captured_at:R()}}}d(xn,"handleSession");async function Mn(e){const t=e.params.id;return m(t),{status:200,body:{node_id:t,markdown:await Pe(t)}}}d(Mn,"handleTranscript");function Ln(e){const t=e.params.id;m(t);const n=d((o,i)=>({node_id:o,label:O(o)?.name??o,dir:F(o),self:i,files:bn(o)}),"root"),r=[n(t,!0),...M(t).map(o=>n(o.node_id,!1))].filter(o=>Fn(o.node_id,o.dir)||o.files>0);return{status:200,body:{node_id:t,roots:r}}}d(Ln,"handleContext");function Fn(e,t){try{return Te(G(e),t)}catch(n){if(Re(n))return!1;throw n}}d(Fn,"hasDir");async function Gn(e){const t=m(e.params.id),n=e.principal.class==="broker"?e.principal.scopes:e.ceiling,r=n===null?void 0:t.scopes==null?[...n]:[...new Set([...t.scopes.filter(i=>S(n,i)),...n.filter(i=>S(t.scopes,i))])],o=await fe(t.node_id,r,e.principal.class==="broker"?e.principal.node:void 0);return{status:201,body:k(o.node.node_id)}}d(Gn,"handleFork");async function Bn(e){const t=e.params.id;m(t);const n=e.body,r=n?.resume??!0,o=n?.reopen??!1;Ge(t,o);const i=!r&&n?.cron_id!==void 0?an(n.cron_id):null,a=await ue(t,{resume:r,capacity:"refuse",...i!==null?{wakeReason:ln(i,"schedule_revive")}:{}}),h=O(t)?.status??"active";return{status:200,body:pn(t,a,h)}}d(Bn,"handleRevive");async function Vn(e){const t=e.params.id;return{status:200,body:{newNodeId:(await Fe(t))?.newNodeId??null}}}d(Vn,"handleRelaunchRoot");function Wn(e){const t=e.params.id;m(t);const n=e.body;if(n?.caller_pid!==void 0&&(!Number.isInteger(n.caller_pid)||n.caller_pid<=0))throw f("caller_pid must be a positive integer when provided");const r=cn(),o=ce(t,{rootEvent:n?.finish===!0?"finish":"cancel",callerPid:n?.caller_pid,...e.principal.class==="broker"?{closer:e.principal.node}:{},...r===null?{}:{registerDetached:r.registerDetached}});return{status:200,body:fn(o)}}d(Wn,"handleClose");async function zn(e){const t=e.params.id;m(t);const n=await Le(t);return{status:200,body:{recycled:n.recycled,finalized:n.finalized,new_root:n.newRoot,delivered:n.delivered}}}d(zn,"handleRecycle");async function Jn(e){const t=e.params.id;return m(t),await B(t,{lifecycle:"terminal"}),A(e,t,["lifecycle"]),{status:200,body:k(t)}}d(Jn,"handleDemote");async function Kn(e,t={}){const n=e.params.id,r=m(n),o=e.body??{};o.kind!==void 0&&await U(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await Z(r,{kind:o.kind??r.kind,mode:"orchestrator",lifecycle:o.resident===!0?"resident":r.lifecycle,model:o.model},t.modelRegistry);const i=await xe(n,{...o.kind!==void 0?{kind:o.kind}:{},...o.resident===!0?{resident:!0}:{},...o.model!==void 0?{model:o.model}:{}});A(e,n,["mode",...o.kind!==void 0?["kind"]:[],...o.resident===!0?["lifecycle"]:[],...o.model!==void 0?["model"]:[]]);const a=D(i.meta,P(n));return a.roadmap_written=i.roadmapWritten,a.roadmap_ref=i.roadmapRef,a.goal_path=i.goalPath,{status:200,body:a}}d(Kn,"handlePromote");async function Un(e,t={}){const n=e.params.id,r=m(n),o=e.body??{};o.kind!==void 0&&await U(o.kind,r.cwd,r.profile_id??null),o.model!==void 0&&await Z(r,{kind:o.kind??r.kind,mode:o.promote===!0?"orchestrator":r.mode,lifecycle:r.lifecycle,model:o.model},t.modelRegistry);const i=o.note??"Refresh: continue against your roadmap or goal.";Be(n,i);const a=await Me(n,{...o.promote===!0?{promote:!0}:{},...o.kind!==void 0?{kind:o.kind}:{},...o.model!==void 0?{model:o.model}:{}});return{status:200,body:D(a.meta,P(n))}}d(Un,"handleYield");function Yn(e){const t=e.params.id;m(t);const n=e.body;if(n===void 0||typeof n.controller!="string"||n.controller.trim()==="")throw f("a wait requires a controller node id");const r=O(n.controller);if(r===null)throw E(`unknown controller: ${n.controller}`,{received:n.controller});if(r.status!=="active"&&r.status!=="idle")throw new p(422,"unprocessable",`controller ${n.controller} is ${r.status}`);return ge(t,n.controller),{status:200,body:k(t)}}d(Yn,"handleWait");async function Hn(){const e=await Ie();return{status:200,body:{revived:[...e.revived],failed:[...e.failed],frozen:[...e.frozen]}}}d(Hn,"handleReviveAll");const Qn=new Set(["interrupt","steer","after-turn","next-turn"]);function Xn(e){if(e===null)return null;const t=d(r=>{throw new y({error:"invalid_listen",message:r,received:e,field:"listen",next:'Send an object mapping levels "1".."10" to interrupt|steer|after-turn|next-turn (e.g. {"3":"next-turn"}), or null to reset to the global default.'})},"bad");if(typeof e!="object"||Array.isArray(e))return t("listen must be an object or null");const n=Object.entries(e);if(n.length===0)return t("listen must name at least one level");for(const[r,o]of n)/^(?:[1-9]|10)$/.test(r)||t(`listen level must be 1..10: ${r}`),(typeof o!="string"||!Qn.has(o))&&t(`listen delivery must be interrupt|steer|after-turn|next-turn: ${String(o)}`);return JSON.stringify(Object.fromEntries(n))}d(Xn,"listenJson");function A(e,t,n,r){n.length===0&&r===void 0||L(o=>{if(r?.(o),n.length===0)return;const i=be(o,t),a=Se(o,e),h=a.class==="person"?a.person:a.class==="app"?a.app:a.node;ve(o,h,i),ke(o,{event:"configured",object:i,actor:h,level:1,attrs:{changed:n.join(",")}})})}d(A,"recordConfigured");async function Zn(e,t={}){const n=e.params.id,r=e.body;let o;if(r===void 0)o={};else if(typeof r=="object"&&r!==null&&!Array.isArray(r))o=r;else throw new y({error:"cwd_invalid",message:"cwd repair requires a non-null object with a non-empty cwd string",received:r,field:"cwd",next:"Send a config patch with a non-empty absolute cwd string."});if(Object.prototype.hasOwnProperty.call(o,"cwd")){const s=o.cwd;if(typeof s!="string"||s==="")throw new y({error:"cwd_invalid",message:"cwd must be a non-empty string",received:s,field:"cwd",next:"Send a non-empty absolute cwd string."});if(Object.keys(o).some(c=>c!=="cwd"&&o[c]!==void 0))throw new y({error:"cwd_not_exclusive",message:"cwd repair cannot be combined with another config field",received:o,field:"cwd",next:"Send cwd as the only config field."});const l=m(n);if(W().has(n)){const c=`${n} cannot repair its cwd while its broker is live`;throw new p(409,"cwd_node_live",c,{error:"cwd_node_live",message:c,received:s,field:"cwd",next:"Let the node become dormant, then retry the cwd repair."})}if(l.fork_from!=null)throw new y({error:"cwd_node_forked",message:`${n} is a fork and cannot repair its cwd; recorded cwd: ${l.cwd}`,received:s,field:"cwd",next:`Restore ${l.cwd}, then revive the fork normally.`});if(l.managed_worktree?.state==="open")throw new y({error:"cwd_node_managed_worktree_open",message:`${n} owns an open managed worktree and cannot repair its cwd`,received:s,field:"cwd",next:"Restore or reconcile the recorded checkout, then use the managed-worktree close or abandon flow."});if(j(l.cwd))throw new y({error:"cwd_still_present",message:`${n} recorded cwd still exists: ${l.cwd}; cwd repair is not a relocation command`,received:s,field:"cwd",next:"This command only repairs a node whose recorded cwd is gone."});if(!se(s))throw new y({error:"cwd_not_absolute",message:`cwd must be an absolute path: ${s}`,received:s,field:"cwd",next:"Send an absolute path."});const u=I(s);if(!j(u))throw new y({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:s,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."});try{if(!de(u).isDirectory())throw new y({error:"cwd_not_a_directory",message:`cwd is not a directory: ${u}`,received:s,field:"cwd",next:"Send an existing absolute directory."})}catch(c){throw c instanceof y?c:new y({error:"cwd_missing",message:`cwd does not exist: ${u}`,received:s,field:"cwd",next:"Create the replacement directory or send an existing absolute directory."})}return L(()=>{C(n,{cwd:u}),Oe(n)}),A(e,n,["cwd"]),{status:200,body:k(n)}}let i=m(n);const a=o.listen===void 0?void 0:Xn(o.listen);if(o.scopes!==void 0){const s=H(o.scopes),l=i.grantee==="app:terminal"?yn():i.grant_id?wn(i.grant_id):null,u=i.grantee==="app:terminal"&&!gn("user").runtime?.issuer;if(!s.every(c=>S(i.scopes,c)&&(l?S(l.resolved,c):u)))throw new y({error:"unknown_scope",message:"scopes may only narrow the node's current effective set",received:s,field:"scopes",next:"Send only scopes the node currently holds."});if(s.includes("crtr:act")&&!S(s,"crtr:llm"))throw new p(400,"invalid_scope","crtr:act requires crtr:llm");i=C(n,{scopes:s})}if(o.situational_context!==void 0&&ae(n,le(o.situational_context)),o.model!==void 0){const s=(await V(i.cwd,i.profile_id??null)).modelLadders,l=Ue(o.model,s),u=Ye(o.model,s);await $({kind:"concrete",spec:u},{cwd:i.cwd,profileId:i.profile_id??null},t.modelRegistry);const c=W();let w=!1;if(c.isClaimed(n)&&await Ze(n,c.get(n)?.handle.exited)&&(w=await Xe(n,u,l).then(()=>!0,g=>{if(g instanceof qe)return!1;throw g})),!w){if(c.isClaimed(n)){const g=`${n}'s broker did not accept the model switch; the model was not changed`;throw new p(409,"broker_not_ready",g,{error:"broker_not_ready",message:g,received:o.model,field:"model",next:"Check the node with `crtr node show`, then retry the model change."})}if(!u.includes("/"))throw f(`model must resolve to a provider/id spec: ${o.model}`);Qe(n,u,l)}i=m(n)}if(o.kind!==void 0||o.mode!==void 0||o.lifecycle!==void 0){o.kind!==void 0&&await ne(o.kind);const s=o.kind??i.kind,l=o.mode??i.mode,u=o.lifecycle??i.lifecycle;let c;l==="orchestrator"&&!ze(n)&&(c=d(()=>{const w=Ve(n);We(n,w!==null&&w.trim()!==""?{goal:w.trim()}:{})},"beforePersist")),i=await B(n,{...o.kind!==void 0?{kind:s}:{},...o.mode!==void 0?{mode:l}:{},...o.lifecycle!==void 0?{lifecycle:u}:{}},c)}o.name!==void 0&&(i=C(n,{name:o.name}),i.window&&Je(i.window,sn(i)));const h=["scopes","situational_context","model","kind","mode","lifecycle","name","listen"].filter(s=>o[s]!==void 0);return A(e,n,h,a===void 0?void 0:s=>{s.prepare("UPDATE nodes SET listen_default_json = ? WHERE node_id = ?").run(a,n)}),{status:200,body:k(n)}}d(Zn,"handleConfig");async function ee(){return(await V(process.cwd(),ie()||null)).kinds}d(ee,"daemonKinds");async function ne(e){const t=Object.keys(await ee());if(!t.includes(e))throw f(`unknown kind: ${e}`,{received:e,next:`Valid kinds: ${t.sort().join(", ")}.`})}d(ne,"assertKindServer");async function qn(){const e=await ee();return{status:200,body:{kinds:Object.keys(e).sort().map(n=>({kind:n,when_to_use:e[n]?.whenToUse??null,available_to:e[n]?.availableTo??null}))}}}d(qn,"handleListKinds");const io=[{method:"POST",pattern:"/v1/nodes",scope:"crtr:act",handler:Rn},{method:"GET",pattern:"/v1/nodes",handler:Cn},{method:"GET",pattern:"/v1/kinds",handler:d(()=>qn(),"handler")},{method:"POST",pattern:"/v1/nodes/revive-all",scope:"crtr:act",handler:d(()=>Hn(),"handler")},{method:"GET",pattern:"/v1/nodes/:id",handler:En},{method:"GET",pattern:"/v1/nodes/:id/snapshot",handler:Dn},{method:"GET",pattern:"/v1/nodes/:id/subject",handler:Pn},{method:"GET",pattern:"/v1/nodes/:id/messages",handler:In},{method:"GET",pattern:"/v1/nodes/:id/session",handler:xn},{method:"GET",pattern:"/v1/nodes/:id/transcript",handler:Mn},{method:"GET",pattern:"/v1/nodes/:id/context",handler:Ln},{method:"POST",pattern:"/v1/nodes/:id/fork",scope:"crtr:act",handler:Gn},{method:"POST",pattern:"/v1/nodes/:id/revive",scope:"crtr:act",handler:Bn},{method:"POST",pattern:"/v1/nodes/:id/relaunch-root",scope:"crtr:act",handler:Vn},{method:"POST",pattern:"/v1/nodes/:id/close",handler:Wn},{method:"POST",pattern:"/v1/nodes/:id/recycle",scope:"crtr:act",handler:zn},{method:"POST",pattern:"/v1/nodes/:id/demote",scope:"crtr:act",handler:Jn},{method:"POST",pattern:"/v1/nodes/:id/promote",scope:"crtr:act",handler:Kn},{method:"POST",pattern:"/v1/nodes/:id/yield",scope:"crtr:act",handler:Un},{method:"POST",pattern:"/v1/nodes/:id/wait",handler:Yn},{method:"PATCH",pattern:"/v1/nodes/:id/config",handler:Zn}];export{Zn as handleConfig,Rn as handleCreate,Gn as handleFork,Cn as handleList,Kn as handlePromote,Un as handleYield,io as nodeRoutes,lo as resolveCreateKind};
@@ -0,0 +1,2 @@
1
+ import type { RouteTable } from '../router.js';
2
+ export declare const objectRoutes: RouteTable;
@@ -0,0 +1,5 @@
1
+ var G=Object.defineProperty;var c=(t,n)=>G(t,"name",{value:n,configurable:!0});import{ApiError as S}from"../../../api/errors.js";import{OBJECT_TYPES as A,PRIVACY_LEVELS_DTO as J}from"../../../api/dto/objects.js";import{withCanvasWrite as g}from"../../../core/canvas/db.js";import{recordMemoryReadsIn as U}from"../../../core/canvas/memory-reads.js";import{canRead as I}from"../../../core/graph/access.js";import{actorOf as N,documentRecord as V,readDocument as z}from"../../../core/graph/documents.js";import{edgesOf as Z}from"../../../core/graph/edges.js";import{publish as C}from"../../../core/graph/events.js";import{jobRow as K}from"../../../core/graph/jobs.js";import{getByRowid as q,listObjects as Q,searchObjects as M}from"../../../core/graph/objects.js";import{reposForCwd as X}from"../../../core/graph/repo-sync/repos.js";import{rulesOf as F}from"../../../core/graph/rules.js";import{recordWatch as $,unwatch as ee,watchersOf as te,watchesOf as ne}from"../../../core/graph/watches.js";import{loadLedger as re,saveLedger as oe}from"../../../core/graph/exposures.js";import{deliveryDocOf as ie,nodeSubject as se,ownerHandle as ce}from"../../../core/substrate/delivery/corpus.js";import{recordContentDelivery as de}from"../../../core/substrate/delivery/deliver.js";import{renderExplicitRead as le}from"../../../core/substrate/delivery/render-event.js";import{readGoal as ae}from"../../../core/runtime/kickoff.js";import{readerFor as b,resolveRef as W}from"../reader.js";import{invalidRequest as E,isRecord as _}from"./validate.js";const L=c(t=>n=>X(t,n),"reposFnFor");function u(t,n){const e=n.owner===null?null:q(t,n.owner),r=e?{id:e.id,type:e.type,handle:e.type==="node"?e.id:e.name}:null;return{id:n.id,type:n.type,kind:n.kind,owner:r,privacy:n.privacy,name:n.name,preview:n.preview??"",created_at:n.created_at,deleted_at:n.deleted_at}}c(u,"objectDTO");function H(t,n){return n.type!=="document"?u(t,n):{...u(t,n),summary:V(t,n).summary??null,rules:F(t,n).length}}c(H,"listItem");function ue(t){return`no object named ${t} on this runtime; it may be on another runtime, or the name may be misspelled`}c(ue,"remoteMessage");function P(t,n,e){try{return R(t,n,e)}catch(r){if(r instanceof S&&r.code==="not_found"&&!r.details?.deleted)return null;throw r}}c(P,"ownerFilter");function R(t,n,e){const r=W(t,n,e);if("remote"in r)throw new S(404,"not_found",ue(r.remote),{next:"Check the name with `crtr canvas search`."});if("deleted"in r)throw new S(404,"not_found",`${r.deleted.name} is deleted`,{id:r.deleted.id,deleted:!0});return r}c(R,"liveRef");const O=c(t=>decodeURIComponent(t.params.ref),"refParam");function fe(t,n,e){const r=`${e.name}/`;return t.prepare(`SELECT * FROM objects WHERE type = 'document' AND deleted_at IS NULL AND owner IS ?
2
+ AND substr(name, 1, ?) = ? ORDER BY name`).all(e.owner,r.length,r).filter(i=>!i.name.slice(r.length).includes("/")&&I(t,n,i)).map(i=>u(t,i))}c(fe,"listingOf");function D(t,n,e){const r=N(n);r.rowid!==e.rowid&&($(t,r,e,"read"),C(t,{event:"read",object:e,actor:r,level:1,attrs:{}},L(t)))}c(D,"recordLiveRead");function pe(t,n,e){const r=n.class==="node",o=r?re(t,n.node.rowid):{node:0,preferenceSnapshot:null,objects:new Map,listed:new Map},i={db:t,reader:n,subject:r?se(t,n):null,ledger:o,channel:"transcript"},d=le(i,ie(t,n,e));return r&&(de(t,n,d.delivered),oe(t,o)),{attachments:d.attachments,linked:d.linked.map(s=>s.object)}}c(pe,"explicitReadAttachments");function me(t,n,e){if(n.class!=="node"||e.kind!=="knowledge"&&e.kind!=="preference"||e.owner===null)return;const r=q(t,e.owner);r!==null&&U(t,n.node.id,[{name:e.name,scope:ce(r),at:new Date().toISOString(),type:"read"}])}c(me,"recordExplicitMemoryRead");function he(t,n,e,r){const o=z(t,n,e,L(t));me(t,n,e);const i=o.record,d=fe(t,n,e),{attachments:s,linked:l}=pe(t,n,e),p=new Set(d.map(a=>a.id)),h=[...d,...l.filter(a=>!p.has(a.id)).map(a=>u(t,a))],w={state:"object",type:"document",object:u(t,e),summary:i.summary??null,revision:i.revision,heads:o.heads.map(a=>({rev_id:a.rev_id,number:a.number,author_id:a.author,created_at:a.created_at})),bodies:o.heads.map(a=>a.body),needs_merge:o.needsMerge,...h.length>0?{listing:h}:{},...s===""?{}:{attachments:s}};return r&&(w.fields={why_it_exists:i.why_it_exists??null,unlisted:i.unlisted,lint_ignore:i.lint_ignore??[],extensions:i.extensions??{},rules:F(t,e).map(({matchFrontmatter:a,...m})=>({...m,...a===void 0?{}:{match_frontmatter:a}}))}),w}c(he,"readDoc");function we(t){return t?.split(`
3
+ `).map(n=>n.trim()).find(n=>n!=="")??""}c(we,"firstLine");function ye(t,n,e){const r=t.prepare("SELECT status FROM nodes WHERE node_id = ?").get(e.id),o=c(s=>s.filter(l=>I(t,n,l)).map(l=>u(t,l)),"visible"),i=t.prepare(`SELECT o.* FROM nodes n JOIN objects o ON o.id = n.node_id
4
+ WHERE n.parent = ? AND o.deleted_at IS NULL ORDER BY o.rowid`).all(e.id),d=t.prepare("SELECT * FROM objects WHERE owner = ? AND deleted_at IS NULL ORDER BY rowid").all(e.rowid);return D(t,n,e),{state:"object",type:"node",object:u(t,e),status:r?.status??"deleted",mandate_first_line:we(ae(e.id)),children:o(i),owned:o(d.filter(s=>s.type!=="job")),jobs:o(d.filter(s=>s.type==="job"))}}c(ye,"readNode");function ge(t,n,e){const r=K(t,e);if(!r)throw new Error(`job object ${e.id} has no jobs row`);return D(t,n,e),{state:"object",type:"job",object:u(t,e),command:r.command,status:r.status,exit_code:r.exit_code,log_path:r.log_path}}c(ge,"readJob");function be(t,n,e){const r=t.prepare("SELECT scheme, external_id FROM identities WHERE object = ?").get(e.rowid);return D(t,n,e),{state:"object",type:e.type,object:u(t,e),handle:e.name,display_name:e.preview||e.name,identity:{scheme:r?.scheme??"",external_id:r?.external_id??""}}}c(be,"readOwner");function je(t){const n=["1","true"].includes(t.query.get("fields")??"");return g(e=>{const r=b(e,t),o=W(e,r,O(t));return"remote"in o?{state:"remote",remote:o.remote}:"deleted"in o?{state:"deleted",deleted:u(e,o.deleted)}:o.type==="document"?he(e,r,o,n):o.type==="node"?ye(e,r,o):o.type==="job"?ge(e,r,o):be(e,r,o)})}c(je,"read");function v(t,n,e,r){if(t!=null){if(!e.includes(t)){r.push({field:n,problem:`must be one of ${e.join(", ")}`,received:t});return}return t}}c(v,"oneOf");function B(t,n,e,r){if(t==null)return r;const o=Number(t);return!Number.isInteger(o)||o<1||o>100?(e.push({field:n,problem:"must be an integer from 1 to 100",received:t}),r):o}c(B,"limitOf");function _e(t){const n=t.query,e=[],r=v(n.get("type"),"type",A,e),o=v(n.get("privacy"),"privacy",J,e),i=B(n.get("limit"),"limit",e,50),d=n.get("cursor");d!==null&&!/^\d+$/.test(d)&&e.push({field:"cursor",problem:"is not a cursor from a previous page",received:d});const s=n.get("deleted");return s!==null&&!["0","1","true","false"].includes(s)&&e.push({field:"deleted",problem:"must be true or false",received:s}),e.length>0&&E("object list request",e),g(l=>{const p=b(l,t),h={...r?{type:r}:{},...o?{privacy:o}:{},...n.get("kind")!==null?{kind:n.get("kind")}:{},...s==="1"||s==="true"?{deleted:!0}:{}},w=n.get("owner");if(w!==null){const y=P(l,p,w);if(y===null)return{items:[],next_cursor:null};h.owner=y}const a=n.get("name"),m=[];let f=d===null?0:Number(d),T=!0;for(;m.length<i&&T;){const y=Q(l,p,h,{limit:100,after_rowid:f});T=y.length===100;for(const k of y)if(f=k.rowid,(a===null||k.name.startsWith(a))&&m.push(k),m.length===i)break}const x=m.at(-1);return{items:m.map(y=>H(l,y)),next_cursor:m.length===i&&x?String(x.rowid):null}})}c(_e,"list");function ve(t){const n=[],e=_(t.body)?t.body:{};_(t.body)||n.push({field:"body",problem:"must be an object",received:t.body});const r=e.text;(typeof r!="string"||r.trim()==="")&&n.push({field:"text",problem:"is required",received:r});const o=e.grep;if(o!==void 0)if(typeof o!="string")n.push({field:"grep",problem:"must be a regular expression string",received:o});else try{new RegExp(o)}catch(s){n.push({field:"grep",problem:`is not a valid regular expression: ${s.message}`,received:o})}e.body!==void 0&&typeof e.body!="boolean"&&n.push({field:"body",problem:"must be a boolean",received:e.body});const i=v(e.type,"type",A,n);e.kind!==void 0&&typeof e.kind!="string"&&n.push({field:"kind",problem:"must be a string",received:e.kind}),e.owner!==void 0&&typeof e.owner!="string"&&n.push({field:"owner",problem:"must be a string",received:e.owner});const d=B(e.limit,"limit",n,50);return n.length>0&&E("object search request",n),g(s=>{const l=b(s,t),p=typeof e.owner=="string"?P(s,l,e.owner):null;if(typeof e.owner=="string"&&p===null)return{items:[]};const h=M(s,l,{text:r,body:e.body===!0||typeof o=="string"}),w=new Set(h.map(f=>f.object.rowid));return{items:(typeof o=="string"?M(s,l,{text:o,grep:!0}).filter(f=>w.has(f.object.rowid)):h).filter(f=>(!i||f.object.type===i)&&(e.kind===void 0||f.object.kind===e.kind)&&(!p||f.object.owner===p.rowid)).slice(0,d).map(f=>({object:H(s,f.object),...f.line!==void 0?{matches:[{line:f.line,text:f.text??""}]}:{}}))}})}c(ve,"search");const Y=["interrupt","steer","after-turn","next-turn"],Ee=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function Re(t,n){if(t!==void 0){if(!Array.isArray(t)||t.length===0||t.some(e=>typeof e!="string"||!Ee.test(e)||e.includes(">")&&!e.endsWith(">"))){n.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:t});return}return t}}c(Re,"patternsOf");function Oe(t,n){if(t===void 0)return;if(!_(t)||Object.keys(t).length===0){n.push({field:"config",problem:"must map levels 1-10 to a delivery",received:t});return}const e=[];for(const[r,o]of Object.entries(t)){const i=Number(r);!Number.isInteger(i)||i<1||i>10?n.push({field:`config.${r}`,problem:"level must be an integer from 1 to 10"}):Y.includes(o)?e.push({threshold:i,delivery:o}):n.push({field:`config.${r}`,problem:`delivery must be one of ${Y.join(", ")}`,received:o})}return e.sort((r,o)=>o.threshold-r.threshold)}c(Oe,"configOf");function ke(t){const n=[],e=t.body===void 0?{}:_(t.body)?t.body:(n.push({field:"body",problem:"must be an object"}),{}),r=Re(e.patterns,n),o=Oe(e.config,n);return e.filter!==void 0&&!_(e.filter)&&n.push({field:"filter",problem:"must be an object",received:e.filter}),n.length>0&&E("watch request",n),g(i=>{const d=b(i,t),s=R(i,d,O(t)),l=N(d),p=r??[">"];return $(i,l,s,"ask",{patterns:p,...o?{config:o}:{},...e.filter!==void 0?{filter:e.filter}:{}}),C(i,{event:"watched",object:s,actor:l,level:1,attrs:{}},L(i)),{object:u(i,s),patterns:p}})}c(ke,"watch");function Se(t){const n=t.query.get("pattern");return g(e=>{const r=b(e,t),o=R(e,r,O(t)),i=N(r),d=c(()=>e.prepare(`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.rowid = s.watch
5
+ WHERE w.watcher = ? AND w.object = ?`).get(i.rowid,o.rowid).n,"count"),s=d();return ee(e,i,o,n??void 0),{object:u(e,o),removed:s-d()}})}c(Se,"unwatchRoute");function Ne(t){const n=[],e=v(t.query.get("type"),"type",["acted-on","links-to","watches"],n),r=v(t.query.get("direction"),"direction",["out","in"],n);return n.length>0&&E("edges request",n),g(o=>{const i=b(o,t),d=R(o,i,O(t)),s=[];if(e!=="watches")for(const l of Z(o,i,d,{...e?{type:e}:{},direction:r??"both"}))s.push({type:l.type,src:u(o,l.src),dst:u(o,l.dst),...l.written_as?{written_as:l.written_as}:{}});if(e===void 0||e==="watches"){const l=[...r!=="in"?ne(o,i,d):[],...r!=="out"?te(o,i,d):[]];for(const p of l)s.push({type:"watches",src:u(o,p.watcher),dst:u(o,p.object)})}return{items:s}})}c(Ne,"edges");const j=c(t=>n=>({status:200,body:t(n)}),"ok"),Ze=[{method:"POST",pattern:"/v1/objects/search",handler:j(ve)},{method:"GET",pattern:"/v1/objects/:ref/edges",handler:j(Ne)},{method:"POST",pattern:"/v1/objects/:ref/watch",handler:j(ke)},{method:"DELETE",pattern:"/v1/objects/:ref/watch",handler:j(Se)},{method:"GET",pattern:"/v1/objects/:ref",handler:j(je)},{method:"GET",pattern:"/v1/objects",handler:j(_e)}];export{Ze as objectRoutes};
@@ -0,0 +1,2 @@
1
+ import type { RouteTable } from '../router.js';
2
+ export declare const packageDocRoutes: RouteTable;
@@ -0,0 +1 @@
1
+ var a=Object.defineProperty;var o=(e,t)=>a(e,"name",{value:t,configurable:!0});import{withCanvasWrite as c}from"../../../core/canvas/db.js";import{reconcilePackageDocuments as r}from"../../../core/graph/package-docs.js";const i=[{method:"POST",pattern:"/v1/documents/reconcile-packages",handler:o(()=>({status:200,body:c(e=>r(e))}),"handler")}];export{i as packageDocRoutes};
@@ -1 +1 @@
1
- var A=Object.defineProperty;var i=(r,e)=>A(r,"name",{value:e,configurable:!0});import{assertLaunchKind as m}from"../../../core/runtime/launch-target.js";import{listNodesByProfile as v,shiftProfileNodeDeadlines as T}from"../../../core/canvas/canvas.js";import{shiftAutoBackgroundBashDeadlines as k}from"../../../core/bash-jobs.js";import{contextDir as q}from"../../../core/canvas/node-agent-paths.js";import{boundFleet as D}from"../../../core/runtime/fleet.js";import{recordedPidLiveness as N}from"../../../core/canvas/pid.js";import{usage as l}from"../../../core/errors.js";import{ApiError as p}from"../../../api/errors.js";import{scopeAllowed as y}from"../../../core/scopes.js";import{validateEnvVarName as O}from"../../../core/env-name.js";import{listProfileEnvNames as L,removeProfileEnvVar as $,setProfileEnvVar as M}from"../../../core/profiles/env-store.js";import{addProfileProject as R,assertProfileProjects as c,createProfile as _,ensureRootProfile as S,listProfiles as u,loadProfileManifest as h,pauseProfile as F,removeProfileProject as V,renameProfile as G,resumeProfile as K,setProfileDefaultKind as U,updateProfileMetadata as B}from"../../../core/profiles/manifest.js";import{requestProfileDeletion as C}from"../../profile-delete.js";import{toProfileDTO as d}from"../map.js";import{resolvedScopes as H}from"../router.js";const b="root";function P(r){return r.principal.class==="person"?"app:terminal":r.principal.app}i(P,"callerApp");function w(r,e,t=null){if(u().some(n=>n.manifest.name===e&&n.profileId!==t&&(n.manifest.grantee??"app:terminal")===r))throw new p(400,"invalid_request",`${r} already has a profile named ${e}`)}i(w,"assertNameFree");function f(r,e){const t=j(r,e),n=t.manifest.grantee??"app:terminal";if(r.principal.class!=="person"&&n!==r.principal.app)throw new p(403,"permission_error",`profile ${t.profileId} belongs to ${n}; only that app changes it`);return t}i(f,"requireOwnProfile");async function z(r){const e=r.body??{};if(typeof e.name!="string"||e.name.trim()==="")throw l("a profile name is required",{field:"name"});e.projects!==void 0&&c(e.projects);const t=P(r),n=e.name.trim();w(t,n),e.default_kind!==void 0&&await m(e.default_kind,process.cwd(),null);const o=_(n,e.projects??[],{defaultKind:e.default_kind,metadata:e.metadata,grantee:t});return{status:201,body:d(o)}}i(z,"handleCreate");async function J(r){const{profileId:e,manifest:t}=f(r,r.params.name),n=r.body??{};return n.name!==void 0&&w(t.grantee??"app:terminal",n.name.trim(),e),n.default_kind!==void 0&&await m(n.default_kind,process.cwd(),e),n.add_project!==void 0&&c([n.add_project]),n.name!==void 0&&G(e,n.name),n.default_kind!==void 0&&U(e,n.default_kind),n.add_project!==void 0&&R(e,n.add_project.path,{memory:n.add_project.memory}),n.remove_project!==void 0&&V(e,n.remove_project),{status:200,body:d(h(e))}}i(J,"handleUpdate");function Q(r){const{profileId:e}=f(r,r.params.name);return{status:200,body:{profile_id:e,names:L(e)}}}i(Q,"handleEnvList");function g(r){const e=r.params.var,t=O(e);if(!t.isValid)throw l(`invalid env var name: ${t.errors.join("; ")}`,{field:"name",received:e});return e}i(g,"requireEnvVarName");function W(r){const{profileId:e}=f(r,r.params.name),t=g(r),{value:n}=r.body??{};if(typeof n!="string"||n==="")throw l("a non-empty env value is required",{field:"value"});return{status:200,body:{profile_id:e,changed:M(e,t,n)}}}i(W,"handleEnvSet");function X(r){const{profileId:e}=f(r,r.params.name),t=g(r);return{status:200,body:{profile_id:e,changed:$(e,t)}}}i(X,"handleEnvRemove");async function Y(r){const e=r.params.name,t=r.body??{};t.projects!==void 0&&c(t.projects);const n=P(r);if(e===b&&n==="app:terminal")return{status:200,body:d(S())};if(e===b)throw new p(403,"permission_error","root belongs to the terminal app");const o=u().find(s=>s.manifest.name===e&&(s.manifest.grantee??"app:terminal")===n);if(o!==void 0)return{status:200,body:d(o)};t.default_kind!==void 0&&await m(t.default_kind,process.cwd(),null);const a=_(e,t.projects??[],{defaultKind:t.default_kind,metadata:t.metadata,grantee:n});return{status:200,body:d(a)}}i(Y,"handleEnsure");function Z(r){const e=f(r,r.params.name),t=r.body??{};if(typeof t!="object"||t===null||Array.isArray(t))throw l("profile metadata body must be an object",{field:"body"});const n=t,o=n.unset===void 0?[]:n.unset;if(!Array.isArray(o)||o.some(I=>typeof I!="string"))throw l("profile metadata `unset` must be an array of strings",{field:"unset"});const a=n.set===void 0?{}:n.set,s=B(e.profileId,a,o);return{status:200,body:d(s)}}i(Z,"handleSetMetadata");function x(r){const e=h(r.params.name),t=F(e.profileId),n=v(e.profileId).filter(a=>a.status==="active"||a.status==="idle");if(n.length===0)return{status:200,body:{profile_id:e.profileId,paused_at:t.manifest.paused_at}};const o=D();for(const a of n){const s=o.get(a.node_id);if(s!==void 0){o.interruptForProfilePause(a.node_id,s.pid);continue}a.pi_pid!=null&&N(a.pi_pid,a.pi_pid_identity)==="alive"&&o.interruptForProfilePause(a.node_id,a.pi_pid)}return{status:200,body:{profile_id:e.profileId,paused_at:t.manifest.paused_at}}}i(x,"handlePause");function ee(r){const e=h(r.params.name),t=K(e.profileId);if(t.pausedAt!==null){const n=Date.parse(t.pausedAt);if(!Number.isNaN(n)){const o=Math.max(0,Date.now()-n);T(e.profileId,o);for(const a of v(e.profileId))a.status!=="dead"&&k(q(a.node_id),o)}}return{status:200,body:{profile_id:e.profileId,paused_at:t.manifest.paused_at}}}i(ee,"handleResume");function E(r){const e=r.principal;if(e.class==="person")return u();const t=H(e);return u().filter(({profileId:n,manifest:o})=>{const a=o.grantee??"app:terminal";if(a===e.app)return!0;const s=`crtr:memory:rw:${a}:profile:${n}`;return y(t,s)&&(e.class!=="broker"||y(e.scopes,s))})}i(E,"visibleProfiles");function j(r,e){const t=E(r),n=t.find(({profileId:a})=>a===e),o=n?[n]:t.filter(({manifest:a})=>a.name===e);if(o.length===0)throw new p(404,"not_found","profile not found");if(o.length>1)throw new p(400,"ambiguous","profile name matches multiple visible profiles; use an exact id");return o[0]}i(j,"requireUsableProfile");function re(r){return{status:200,body:E(r).map(d)}}i(re,"handleList");function ne(r){return{status:200,body:d(j(r,r.params.name))}}i(ne,"handleGet");async function te(r){return C(f(r,r.params.name).profileId,r.body)}i(te,"handleDelete");const Pe=[{method:"PUT",pattern:"/v1/profiles/:name",handler:Y},{method:"POST",pattern:"/v1/profiles/:name/pause",ownerOnly:!0,handler:x},{method:"POST",pattern:"/v1/profiles/:name/resume",ownerOnly:!0,handler:ee},{method:"PATCH",pattern:"/v1/profiles/:name/metadata",handler:Z},{method:"POST",pattern:"/v1/profiles",handler:z},{method:"PATCH",pattern:"/v1/profiles/:name",handler:J},{method:"GET",pattern:"/v1/profiles/:name/env",handler:Q},{method:"PUT",pattern:"/v1/profiles/:name/env/:var",handler:W},{method:"DELETE",pattern:"/v1/profiles/:name/env/:var",handler:X},{method:"DELETE",pattern:"/v1/profiles/:name",handler:te},{method:"GET",pattern:"/v1/profiles",handler:re},{method:"GET",pattern:"/v1/profiles/:name",handler:ne}];export{Pe as profileRoutes,j as requireUsableProfile};
1
+ var A=Object.defineProperty;var o=(t,e)=>A(t,"name",{value:e,configurable:!0});import{assertLaunchKind as u}from"../../../core/runtime/launch-target.js";import{listNodesByProfile as v,shiftProfileNodeDeadlines as T}from"../../../core/canvas/canvas.js";import{shiftAutoBackgroundBashDeadlines as k}from"../../../core/bash-jobs.js";import{contextDir as D}from"../../../core/canvas/node-agent-paths.js";import{boundFleet as q}from"../../../core/runtime/fleet.js";import{recordedPidLiveness as N}from"../../../core/canvas/pid.js";import{usage as f}from"../../../core/errors.js";import{ApiError as p}from"../../../api/errors.js";import{scopeAllowed as _}from"../../../core/scopes.js";import{validateEnvVarName as O}from"../../../core/env-name.js";import{listProfileEnvNames as L,removeProfileEnvVar as $,setProfileEnvVar as M}from"../../../core/profiles/env-store.js";import{addProfileProject as R,assertDeliveryLimits as S,setProfileDeliveryLimit as F,assertProfileProjects as c,createProfile as y,ensureRootProfile as V,listProfiles as m,loadProfileManifest as h,pauseProfile as G,removeProfileProject as K,renameProfile as U,resumeProfile as B,setProfileDefaultKind as C,updateProfileMetadata as H}from"../../../core/profiles/manifest.js";import{requestProfileDeletion as z}from"../../profile-delete.js";import{toProfileDTO as d}from"../map.js";import{resolvedScopes as J}from"../router.js";const P="root";function b(t){return t.principal.class==="person"?"app:terminal":t.principal.app}o(b,"callerApp");function w(t,e,n=null){if(m().some(r=>r.manifest.name===e&&r.profileId!==n&&(r.manifest.grantee??"app:terminal")===t))throw new p(400,"invalid_request",`${t} already has a profile named ${e}`)}o(w,"assertNameFree");function l(t,e){const n=j(t,e),r=n.manifest.grantee??"app:terminal";if(t.principal.class!=="person"&&r!==t.principal.app)throw new p(403,"permission_error",`profile ${n.profileId} belongs to ${r}; only that app changes it`);return n}o(l,"requireOwnProfile");async function Q(t){const e=t.body??{};if(typeof e.name!="string"||e.name.trim()==="")throw f("a profile name is required",{field:"name"});e.projects!==void 0&&c(e.projects);const n=b(t),r=e.name.trim();w(n,r),e.default_kind!==void 0&&await u(e.default_kind,process.cwd(),null);const a=y(r,e.projects??[],{defaultKind:e.default_kind,metadata:e.metadata,grantee:n});return{status:201,body:d(a)}}o(Q,"handleCreate");async function W(t){const{profileId:e,manifest:n}=l(t,t.params.name),r=t.body??{};return r.name!==void 0&&w(n.grantee??"app:terminal",r.name.trim(),e),r.default_kind!==void 0&&await u(r.default_kind,process.cwd(),e),r.add_project!==void 0&&c([r.add_project]),r.set_delivery_limit!==void 0&&S({[r.set_delivery_limit.owner]:r.set_delivery_limit.level}),r.name!==void 0&&U(e,r.name),r.default_kind!==void 0&&C(e,r.default_kind),r.add_project!==void 0&&R(e,r.add_project.path),r.set_delivery_limit!==void 0&&F(e,r.set_delivery_limit.owner,r.set_delivery_limit.level),r.remove_project!==void 0&&K(e,r.remove_project),{status:200,body:d(h(e))}}o(W,"handleUpdate");function X(t){const{profileId:e}=l(t,t.params.name);return{status:200,body:{profile_id:e,names:L(e)}}}o(X,"handleEnvList");function g(t){const e=t.params.var,n=O(e);if(!n.isValid)throw f(`invalid env var name: ${n.errors.join("; ")}`,{field:"name",received:e});return e}o(g,"requireEnvVarName");function Y(t){const{profileId:e}=l(t,t.params.name),n=g(t),{value:r}=t.body??{};if(typeof r!="string"||r==="")throw f("a non-empty env value is required",{field:"value"});return{status:200,body:{profile_id:e,changed:M(e,n,r)}}}o(Y,"handleEnvSet");function Z(t){const{profileId:e}=l(t,t.params.name),n=g(t);return{status:200,body:{profile_id:e,changed:$(e,n)}}}o(Z,"handleEnvRemove");async function x(t){const e=t.params.name,n=t.body??{};n.projects!==void 0&&c(n.projects);const r=b(t);if(e===P&&r==="app:terminal")return{status:200,body:d(V())};if(e===P)throw new p(403,"permission_error","root belongs to the terminal app");const a=m().find(s=>s.manifest.name===e&&(s.manifest.grantee??"app:terminal")===r);if(a!==void 0)return{status:200,body:d(a)};n.default_kind!==void 0&&await u(n.default_kind,process.cwd(),null);const i=y(e,n.projects??[],{defaultKind:n.default_kind,metadata:n.metadata,grantee:r});return{status:200,body:d(i)}}o(x,"handleEnsure");function ee(t){const e=l(t,t.params.name),n=t.body??{};if(typeof n!="object"||n===null||Array.isArray(n))throw f("profile metadata body must be an object",{field:"body"});const r=n,a=r.unset===void 0?[]:r.unset;if(!Array.isArray(a)||a.some(I=>typeof I!="string"))throw f("profile metadata `unset` must be an array of strings",{field:"unset"});const i=r.set===void 0?{}:r.set,s=H(e.profileId,i,a);return{status:200,body:d(s)}}o(ee,"handleSetMetadata");function te(t){const e=h(t.params.name),n=G(e.profileId),r=v(e.profileId).filter(i=>i.status==="active"||i.status==="idle");if(r.length===0)return{status:200,body:{profile_id:e.profileId,paused_at:n.manifest.paused_at}};const a=q();for(const i of r){const s=a.get(i.node_id);if(s!==void 0){a.interruptForProfilePause(i.node_id,s.pid);continue}i.pi_pid!=null&&N(i.pi_pid,i.pi_pid_identity)==="alive"&&a.interruptForProfilePause(i.node_id,i.pi_pid)}return{status:200,body:{profile_id:e.profileId,paused_at:n.manifest.paused_at}}}o(te,"handlePause");function re(t){const e=h(t.params.name),n=B(e.profileId);if(n.pausedAt!==null){const r=Date.parse(n.pausedAt);if(!Number.isNaN(r)){const a=Math.max(0,Date.now()-r);T(e.profileId,a);for(const i of v(e.profileId))i.status!=="dead"&&k(D(i.node_id),a)}}return{status:200,body:{profile_id:e.profileId,paused_at:n.manifest.paused_at}}}o(re,"handleResume");function E(t){const e=t.principal;if(e.class==="person")return m();const n=J(e);return m().filter(({profileId:r,manifest:a})=>{const i=a.grantee??"app:terminal";if(i===e.app)return!0;const s=`crtr:memory:rw:${i}:profile:${r}`;return _(n,s)&&(e.class!=="broker"||_(e.scopes,s))})}o(E,"visibleProfiles");function j(t,e){const n=E(t),r=n.find(({profileId:i})=>i===e),a=r?[r]:n.filter(({manifest:i})=>i.name===e);if(a.length===0)throw new p(404,"not_found","profile not found");if(a.length>1)throw new p(400,"ambiguous","profile name matches multiple visible profiles; use an exact id");return a[0]}o(j,"requireUsableProfile");function ne(t){return{status:200,body:E(t).map(d)}}o(ne,"handleList");function ie(t){return{status:200,body:d(j(t,t.params.name))}}o(ie,"handleGet");async function ae(t){return z(l(t,t.params.name).profileId,t.body)}o(ae,"handleDelete");const ge=[{method:"PUT",pattern:"/v1/profiles/:name",handler:x},{method:"POST",pattern:"/v1/profiles/:name/pause",ownerOnly:!0,handler:te},{method:"POST",pattern:"/v1/profiles/:name/resume",ownerOnly:!0,handler:re},{method:"PATCH",pattern:"/v1/profiles/:name/metadata",handler:ee},{method:"POST",pattern:"/v1/profiles",handler:Q},{method:"PATCH",pattern:"/v1/profiles/:name",handler:W},{method:"GET",pattern:"/v1/profiles/:name/env",handler:X},{method:"PUT",pattern:"/v1/profiles/:name/env/:var",handler:Y},{method:"DELETE",pattern:"/v1/profiles/:name/env/:var",handler:Z},{method:"DELETE",pattern:"/v1/profiles/:name",handler:ae},{method:"GET",pattern:"/v1/profiles",handler:ne},{method:"GET",pattern:"/v1/profiles/:name",handler:ie}];export{ge as profileRoutes,j as requireUsableProfile};
@@ -1,6 +1,6 @@
1
1
  import type { ReportDTO } from '../../../api/index.js';
2
2
  import type { RouteTable } from '../router.js';
3
- /** Read one node's pushed reports, newest first. This stays in the daemon so
4
- * collection projections can include report activity without client-side N+1s. */
3
+ /** One node's report documents, newest first, read as the person (records nothing). This stays
4
+ * in the daemon so collection projections can include report activity without client-side N+1s. */
5
5
  export declare function reportsForNode(id: string): ReportDTO[];
6
6
  export declare const reportRoutes: RouteTable;
@@ -1,4 +1,4 @@
1
- var A=Object.defineProperty;var a=(t,e)=>A(t,"name",{value:e,configurable:!0});import{existsSync as F}from"node:fs";import{join as C}from"node:path";import{getNode as c}from"../../../core/canvas/canvas.js";import{liveExecutionForNode as B}from"../../../core/canvas/executions.js";import{markStopSignal as I}from"../../../core/runtime/stop-signals.js";import{emitEvent as j}from"../../../core/events/emit.js";import{push as J,FinalizationError as S}from"../../../core/feed/feed.js";import{branchIsPushedAtCurrentTip as M,hasOpenManagedWorktree as z,missingWorktreeRecoveryHint as H}from"../../../core/worktree.js";import{autoDropCleanManagedWorktreeAsync as W}from"../../../core/worktree-mutation-async.js";import{nodeAgentDir as L,reportsDir as G}from"../../../core/canvas/node-agent-paths.js";import{isAbsentOrRefused as X,isBeneathRefusal as K,readdirBeneath as V,readFileBeneath as Q,statBeneath as U}from"../../../core/spaces/open-beneath.js";import{notFound as Y,usage as m}from"../../../core/errors.js";import{InputError as f}from"../../../core/io.js";import{parseFrontmatterGeneric as Z}from"../../../core/frontmatter.js";import{toReportResultDTO as ee}from"../map.js";import{outputSchemaPath as te,readOutputRequest as $,removeOutputSchema as re,validateStructuredResult as ne,writeOutputDeclined as ie,writeOutputResult as oe}from"../../../core/runtime/structured-output.js";import{nodeEventStreams as O}from"./node-events.js";import{emitRunEvent as R}from"../../../core/runs/events.js";function _(t){const e=c(t);if(e===null)throw Y(`unknown node: ${t}`,{received:t});return e}a(_,"requireNode");function ae(t){if(typeof t!="object"||t===null)throw m("a push report requires a JSON body { tier, body }");const e=t.tier,r=t.delivery_tier,n=t.body;if(e!=="update"&&e!=="urgent"&&e!=="final")throw m(`invalid report tier: ${String(e)} (expected update|urgent|final)`);if(r!==void 0&&r!=="deferred"&&r!=="normal"&&r!=="urgent")throw m(`invalid delivery_tier: ${String(r)} (expected deferred|normal|urgent)`);if(e!=="update"&&r!==void 0)throw m("delivery_tier is only valid for update reports");if(typeof n!="string"||n.trim()==="")throw m("a push report requires a non-empty body");return{tier:e,...r===void 0?{}:{delivery_tier:r},body:n}}a(ae,"parsePushBody");async function se(t){const e=t.params.id;_(e);const r=ae(t.body);if(r.tier==="final"&&$(e).state==="valid")throw new f({error:"structured_result_pending",message:"This node owes a structured result \u2014 a plain `push final` would finish it without recording one.",next:'Submit the result with `crtr push result` instead; it validates against the pending schema, records it, and pushes the final report for you. If the schema cannot be honestly satisfied, `crtr push result --decline "<reason>" --code <token>` records the decline and finishes the node.'});const n=r.tier==="final"?c(e)?.status:void 0,o=r.tier==="final"?await T(e):void 0,i=await E(e,r);r.tier==="final"&&q(e);const s=r.tier==="final"&&n!==void 0?{from:n,to:c(e)?.status??"done"}:void 0,p=ee(i,s,o),d=v(e).find(h=>h.path===i.reportPath);if(d!==void 0){O.report(e,d);const h=c(e)?.run_id;h&&R(h,e,"node.report.pushed",{body:d.body,kind:d.tier==="final"?"final":"update"})}return{status:200,body:p}}a(se,"handlePush");async function T(t){if(!z(c(t)))return;const e=await W(t);if(e!==null)return e.worktree_path;if(!await M(c(t).managed_worktree))throw new f({error:"open_managed_worktree",message:"This node still owns an open managed worktree that is neither clean and locally landed nor clean with its exact tip on origin \u2014 `push final` cannot finish.",next:(()=>{const r=c(t)?.managed_worktree;return r!=null&&r.state==="open"&&!F(r.path)?H(r):"Commit the remaining work in the worktree, push its branch to origin at its current tip, then rerun `crtr push final`; or run `crtr node worktree close` to land it locally."})()})}a(T,"guardFinalWorktree");const x=2e3;function de(t,e){const r=JSON.stringify(e,null,2),n=r.length>x?`${r.slice(0,x)}
1
+ var A=Object.defineProperty;var a=(t,e)=>A(t,"name",{value:e,configurable:!0});import{existsSync as F}from"node:fs";import{getNode as d}from"../../../core/canvas/canvas.js";import{liveExecutionForNode as I}from"../../../core/canvas/executions.js";import{markStopSignal as P}from"../../../core/runtime/stop-signals.js";import{emitEvent as j}from"../../../core/events/emit.js";import{push as J,FinalizationError as S}from"../../../core/feed/feed.js";import{branchIsPushedAtCurrentTip as M,hasOpenManagedWorktree as B,missingWorktreeRecoveryHint as z}from"../../../core/worktree.js";import{autoDropCleanManagedWorktreeAsync as H}from"../../../core/worktree-mutation-async.js";import{openDb as L}from"../../../core/canvas/db.js";import{get as W}from"../../../core/graph/bodies.js";import{heads as X}from"../../../core/graph/documents.js";import{listObjects as G,nodeObject as K}from"../../../core/graph/objects.js";import{readerFor as V}from"../../../core/graph/reader.js";import{notFound as Q,usage as l}from"../../../core/errors.js";import{InputError as u}from"../../../core/io.js";import{toReportResultDTO as U}from"../map.js";import{outputSchemaPath as Y,readOutputRequest as O,removeOutputSchema as Z,validateStructuredResult as ee,writeOutputDeclined as te,writeOutputResult as re}from"../../../core/runtime/structured-output.js";import{nodeEventStreams as R}from"./node-events.js";import{emitRunEvent as $}from"../../../core/runs/events.js";function b(t){const e=d(t);if(e===null)throw Q(`unknown node: ${t}`,{received:t});return e}a(b,"requireNode");function ne(t){if(typeof t!="object"||t===null)throw l("a push report requires a JSON body { tier, body }");const e=t.tier,r=t.delivery_tier,n=t.body;if(e!=="update"&&e!=="urgent"&&e!=="final")throw l(`invalid report tier: ${String(e)} (expected update|urgent|final)`);if(r!==void 0&&r!=="deferred"&&r!=="normal"&&r!=="urgent")throw l(`invalid delivery_tier: ${String(r)} (expected deferred|normal|urgent)`);if(e!=="update"&&r!==void 0)throw l("delivery_tier is only valid for update reports");if(typeof n!="string"||n.trim()==="")throw l("a push report requires a non-empty body");return{tier:e,...r===void 0?{}:{delivery_tier:r},body:n}}a(ne,"parsePushBody");async function ie(t){const e=t.params.id;b(e);const r=ne(t.body);if(r.tier==="final"&&O(e).state==="valid")throw new u({error:"structured_result_pending",message:"This node owes a structured result \u2014 a plain `push final` would finish it without recording one.",next:'Submit the result with `crtr push result` instead; it validates against the pending schema, records it, and pushes the final report for you. If the schema cannot be honestly satisfied, `crtr push result --decline "<reason>" --code <token>` records the decline and finishes the node.'});const n=r.tier==="final"?d(e)?.status:void 0,i=r.tier==="final"?await q(e):void 0,o=await D(e,r);r.tier==="final"&&T(e);const h=r.tier==="final"&&n!==void 0?{from:n,to:d(e)?.status??"done"}:void 0,m=U(o,h,i),c=_(e).find(f=>f.id===o.reportId);if(c!==void 0){R.report(e,c);const f=d(e)?.run_id;f&&$(f,e,"node.report.pushed",{body:c.body,kind:c.tier==="final"?"final":"update"})}return{status:200,body:m}}a(ie,"handlePush");async function q(t){if(!B(d(t)))return;const e=await H(t);if(e!==null)return e.worktree_path;if(!await M(d(t).managed_worktree))throw new u({error:"open_managed_worktree",message:"This node still owns an open managed worktree that is neither clean and locally landed nor clean with its exact tip on origin \u2014 `push final` cannot finish.",next:(()=>{const r=d(t)?.managed_worktree;return r!=null&&r.state==="open"&&!F(r.path)?z(r):"Commit the remaining work in the worktree, push its branch to origin at its current tip, then rerun `crtr push final`; or run `crtr node worktree close` to land it locally."})()})}a(q,"guardFinalWorktree");const x=2e3;function oe(t,e){const r=JSON.stringify(e,null,2),n=r.length>x?`${r.slice(0,x)}
2
2
  \u2026 (truncated \u2014 the full result is at the result path above)`:r;return`Structured output submitted.
3
3
 
4
4
  Result path: ${t}
@@ -6,13 +6,13 @@ Result path: ${t}
6
6
  \`\`\`json
7
7
  ${n}
8
8
  \`\`\`
9
- `}a(de,"submitReportBody");function ue(t,e){return`Structured result declined.
9
+ `}a(oe,"submitReportBody");function ae(t,e){return`Structured result declined.
10
10
 
11
11
  Reason: ${e.reason}
12
12
  Code: ${e.code}
13
13
  Retryable: ${e.retryable?"yes":"no"}
14
14
 
15
15
  Declined marker: ${t}
16
- `}a(ue,"declineReportBody");const N=1024,D=64;function le(t){if(typeof t!="object"||t===null)throw m("a result submission requires a JSON body { value } or { decline, code, retryable }");const e=Object.hasOwn(t,"value"),r=Object.hasOwn(t,"decline");if(e&&r)throw m("a result submission carries either { value } or { decline, code, retryable }, not both");if(r){const{decline:n,code:o,retryable:i}=t;if(typeof n!="string"||n.trim()==="")throw new f({error:"missing_decline_reason",message:"A decline needs a reason.",next:'Rerun with `--decline "<one sentence on why the schema cannot be honestly satisfied>" --code <token>`.'});if(n.length>N)throw new f({error:"decline_reason_too_long",message:`A decline reason is at most ${N} characters (got ${n.length}).`,next:"Keep the reason to one plain sentence; put any detail in an artifact and name its path."});if(typeof o!="string"||o.trim()===""||/\s/.test(o.trim())||o.trim().length>D)throw new f({error:"invalid_decline_code",message:`A decline needs a code: one whitespace-free token of at most ${D} characters naming the decline class.`,next:"Rerun with `--code <token>` \u2014 the token your requester documented for this case."});if(typeof i!="boolean")throw m("a decline carries `retryable` as a boolean");return{declined:{reason:n.trim(),code:o.trim(),retryable:i}}}if(!e)throw m("a result submission requires a JSON body { value } or { decline, code, retryable }");return{value:t.value}}a(le,"parseSubmitBody");async function ce(t){const e=t.params.id,r=_(e),n=le(t.body),o=$(e);if(o.state==="absent")throw new f({error:"no_output_request",message:"No structured output is currently requested of this node.",next:"Nothing to submit here \u2014 continue working, or finish with `crtr push final`."});if(o.state==="invalid")throw new f({error:"invalid_output_request",message:`The structured-output request file is invalid: ${o.error}`,next:`Have the requester re-issue the request, or remove ${te(e)} and finish with \`crtr push final\`.`});const{mode:i,schema:s}=o.request;let p;if("value"in n)try{p=await ne(s,n.value)}catch(u){throw new f({error:"result_schema_mismatch",message:`the submitted result does not match the requested schema: ${u.message}`,next:'Fix the listed fields and rerun `crtr push result`; if the schema cannot be honestly satisfied, rerun with `--decline "<reason>" --code <token>`.'})}const d=i==="terminal"?c(e)?.status:void 0,h=i==="terminal"?await T(e):void 0;let l,y,g;if("declined"in n){const{declined:u}=n;if(l=ie(e,{mode:i,...u,at:new Date().toISOString()},r.grantee),y=ue(l,u),i==="terminal"){const P={schema:"crtr.node-outcome-detail/v1",message:u.reason,declined:u};g={kind:"failure",reason:"declined",detailJson:JSON.stringify(P)}}}else l=oe(e,p,r.grantee),y=de(l,p);const w=await E(e,{tier:i==="terminal"?"final":"update",body:y},g);i==="terminal"&&q(e),re(e);const k=i==="terminal"&&d!==void 0?{from:d,to:c(e)?.status??"done"}:void 0,b=v(e).find(u=>u.path===w.reportPath);if(b!==void 0){O.report(e,b);const u=c(e)?.run_id;u&&R(u,e,"node.report.pushed",{body:b.body,kind:b.tier==="final"?"final":"update"})}return{status:200,body:{mode:i,result_path:l,report_path:w.reportPath,notified:[...w.deliveredTo],..."declined"in n?{declined:n.declined}:{},...k===void 0?{}:{transitioned:k},...h===void 0?{}:{worktree_auto_dropped:!0,worktree_auto_dropped_path:h}}}}a(ce,"handleSubmitResult");function q(t){try{const e=B(t);e!==null&&I(t,"pushedFinal",e.executionId)}catch(e){try{j({event:"daemon.node.final-marker.failed",level:"error",node_id:t,error:e})||process.stderr.write(`final marker failed for ${t}: ${String(e)}
16
+ `}a(ae,"declineReportBody");const N=1024,E=64;function se(t){if(typeof t!="object"||t===null)throw l("a result submission requires a JSON body { value } or { decline, code, retryable }");const e=Object.hasOwn(t,"value"),r=Object.hasOwn(t,"decline");if(e&&r)throw l("a result submission carries either { value } or { decline, code, retryable }, not both");if(r){const{decline:n,code:i,retryable:o}=t;if(typeof n!="string"||n.trim()==="")throw new u({error:"missing_decline_reason",message:"A decline needs a reason.",next:'Rerun with `--decline "<one sentence on why the schema cannot be honestly satisfied>" --code <token>`.'});if(n.length>N)throw new u({error:"decline_reason_too_long",message:`A decline reason is at most ${N} characters (got ${n.length}).`,next:"Keep the reason to one plain sentence; put any detail in an artifact and name its path."});if(typeof i!="string"||i.trim()===""||/\s/.test(i.trim())||i.trim().length>E)throw new u({error:"invalid_decline_code",message:`A decline needs a code: one whitespace-free token of at most ${E} characters naming the decline class.`,next:"Rerun with `--code <token>` \u2014 the token your requester documented for this case."});if(typeof o!="boolean")throw l("a decline carries `retryable` as a boolean");return{declined:{reason:n.trim(),code:i.trim(),retryable:o}}}if(!e)throw l("a result submission requires a JSON body { value } or { decline, code, retryable }");return{value:t.value}}a(se,"parseSubmitBody");async function de(t){const e=t.params.id,r=b(e),n=se(t.body),i=O(e);if(i.state==="absent")throw new u({error:"no_output_request",message:"No structured output is currently requested of this node.",next:"Nothing to submit here \u2014 continue working, or finish with `crtr push final`."});if(i.state==="invalid")throw new u({error:"invalid_output_request",message:`The structured-output request file is invalid: ${i.error}`,next:`Have the requester re-issue the request, or remove ${Y(e)} and finish with \`crtr push final\`.`});const{mode:o,schema:h}=i.request;let m;if("value"in n)try{m=await ee(h,n.value)}catch(s){throw new u({error:"result_schema_mismatch",message:`the submitted result does not match the requested schema: ${s.message}`,next:'Fix the listed fields and rerun `crtr push result`; if the schema cannot be honestly satisfied, rerun with `--decline "<reason>" --code <token>`.'})}const c=o==="terminal"?d(e)?.status:void 0,f=o==="terminal"?await q(e):void 0;let p,y,v;if("declined"in n){const{declined:s}=n;if(p=te(e,{mode:o,...s,at:new Date().toISOString()},r.grantee),y=ae(p,s),o==="terminal"){const C={schema:"crtr.node-outcome-detail/v1",message:s.reason,declined:s};v={kind:"failure",reason:"declined",detailJson:JSON.stringify(C)}}}else p=re(e,m,r.grantee),y=oe(p,m);const g=await D(e,{tier:o==="terminal"?"final":"update",body:y},v,o==="oneoff"?{requestMessageId:i.request.requestMessageId??null}:void 0);o==="terminal"&&T(e),Z(e);const k=o==="terminal"&&c!==void 0?{from:c,to:d(e)?.status??"done"}:void 0,w=_(e).find(s=>s.id===g.reportId);if(w!==void 0){R.report(e,w);const s=d(e)?.run_id;s&&$(s,e,"node.report.pushed",{body:w.body,kind:w.tier==="final"?"final":"update"})}return{status:200,body:{mode:o,result_path:p,report:g.report,notified:[...g.deliveredTo],..."declined"in n?{declined:n.declined}:{},...k===void 0?{}:{transitioned:k},...f===void 0?{}:{worktree_auto_dropped:!0,worktree_auto_dropped_path:f}}}}a(de,"handleSubmitResult");function T(t){try{const e=I(t);e!==null&&P(t,"pushedFinal",e.executionId)}catch(e){try{j({event:"daemon.node.final-marker.failed",level:"error",node_id:t,error:e})||process.stderr.write(`final marker failed for ${t}: ${String(e)}
17
17
  `)}catch{process.stderr.write(`final marker failed for ${t}: ${String(e)}
18
- `)}}}a(q,"markCommittedFinal");async function E(t,e,r){try{return await J(t,{kind:e.tier,body:e.body,...e.delivery_tier===void 0?{}:{deliveryTier:e.delivery_tier},...r===void 0?{}:{outcome:r}})}catch(n){throw n instanceof S&&n.code==="already_finalized"?new f({error:"already_finalized",message:"This node already submitted its canonical final result.",next:"Push an update with the new information, then stop."}):n instanceof S&&n.code==="finalization_forbidden"?new f({error:"finalization_forbidden",message:"A canceled or dead node cannot submit a canonical final result.",next:"Do not push final from this node."}):n}}a(E,"pushOrRethrow");function fe(t){const e=t.match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})$/);return e===null?t:`${e[1]}-${e[2]}-${e[3]}T${e[4]}:${e[5]}:${e[6]}`}a(fe,"compactToIso");function v(t){const e=L(t),r=G(t);let n;try{n=V(e,r).filter(i=>!i.isDirectory()&&i.name.endsWith(".md")).map(i=>i.name)}catch(i){if(!X(i))throw i;n=[]}const o=[];for(const i of n){const s=C(r,i);let p;try{p=Q(e,s).toString("utf8")}catch(w){if(K(w))continue;throw w}const{data:d,body:h}=Z(p),l=i.match(/^([0-9]{8}T[0-9]{6})-(\w+)\.md$/),y=(typeof d?.kind=="string"?d.kind:void 0)??(l?l[2]:"update"),g=(typeof d?.ts=="string"?d.ts:void 0)??(l?fe(l[1]):new Date(U(e,s).mtimeMs).toISOString());o.push({path:s,tier:y,body:h.trim(),created:g})}return o.sort((i,s)=>i.created<s.created?1:i.created>s.created?-1:0),o}a(v,"reportsForNode");function he(t){const e=t.params.id;_(e);const r=t.query.get("tier"),n=t.query.get("limit"),o=n!==null?Number(n):void 0;let i=v(e);return r!==null&&(i=i.filter(s=>s.tier===r)),o!==void 0&&Number.isFinite(o)&&o>=0&&(i=i.slice(0,o)),{status:200,body:i}}a(he,"handleList");const Ae=[{method:"POST",pattern:"/v1/nodes/:id/reports",ownerOnly:!0,handler:se},{method:"GET",pattern:"/v1/nodes/:id/reports",handler:he},{method:"POST",pattern:"/v1/nodes/:id/result",handler:ce}];export{Ae as reportRoutes,v as reportsForNode};
18
+ `)}}}a(T,"markCommittedFinal");async function D(t,e,r,n){try{return await J(t,{kind:e.tier,body:e.body,...e.delivery_tier===void 0?{}:{deliveryTier:e.delivery_tier},...r===void 0?{}:{outcome:r},...n===void 0?{}:{result:n}})}catch(i){throw i instanceof S&&i.code==="already_finalized"?new u({error:"already_finalized",message:"This node already submitted its canonical final result.",next:"Push an update with the new information, then stop."}):i instanceof S&&i.code==="finalization_forbidden"?new u({error:"finalization_forbidden",message:"A canceled or dead node cannot submit a canonical final result.",next:"Do not push final from this node."}):i}}a(D,"pushOrRethrow");function _(t){const e=L();return G(e,V(e,{class:"person"},()=>[]),{type:"document",kind:"report",owner:K(e,t)}).map(n=>{const i=n.name.match(/-(update|urgent|final)$/)?.[1]??"update",o=X(e,n)[0];return{name:n.name,id:n.id,tier:i,body:o===void 0?"":W(o.body_hash).trim(),created:n.created_at}}).sort((n,i)=>n.created<i.created?1:n.created>i.created?-1:i.name.localeCompare(n.name))}a(_,"reportsForNode");function ue(t){const e=t.params.id;b(e);const r=t.query.get("tier"),n=t.query.get("limit"),i=n!==null?Number(n):void 0;let o=_(e);return r!==null&&(o=o.filter(h=>h.tier===r)),i!==void 0&&Number.isFinite(i)&&i>=0&&(o=o.slice(0,i)),{status:200,body:o}}a(ue,"handleList");const Te=[{method:"POST",pattern:"/v1/nodes/:id/reports",ownerOnly:!0,handler:ie},{method:"GET",pattern:"/v1/nodes/:id/reports",handler:ue},{method:"POST",pattern:"/v1/nodes/:id/result",handler:de}];export{Te as reportRoutes,_ as reportsForNode};