@north-light/crouter 0.3.348 → 0.3.350

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 (634) hide show
  1. package/bin/crtr-launcher +4 -0
  2. package/bin/runtime-generation-manifest.mjs +12 -2
  3. package/dist/api/client.d.ts +50 -7
  4. package/dist/api/client.js +2 -2
  5. package/dist/api/command-manifest/schema.js +1 -1
  6. package/dist/api/dto/analytics.d.ts +184 -0
  7. package/dist/api/dto/analytics.js +0 -0
  8. package/dist/api/dto/broker-ops.d.ts +43 -1
  9. package/dist/api/dto/config.d.ts +11 -0
  10. package/dist/api/dto/grants.d.ts +14 -0
  11. package/dist/api/dto/grants.js +0 -0
  12. package/dist/api/dto/human-requests.d.ts +14 -0
  13. package/dist/api/dto/memory.d.ts +6 -0
  14. package/dist/api/dto/modelauth.d.ts +35 -0
  15. package/dist/api/dto/node-records.d.ts +35 -0
  16. package/dist/api/dto/node-records.js +0 -0
  17. package/dist/api/dto/nodes.d.ts +5 -0
  18. package/dist/api/dto/profiles.d.ts +38 -3
  19. package/dist/api/dto/worktree.d.ts +11 -0
  20. package/dist/api/errors.d.ts +23 -1
  21. package/dist/api/errors.js +1 -1
  22. package/dist/api/index.d.ts +2 -0
  23. package/dist/api/index.js +1 -1
  24. package/dist/api/node-transport.js +1 -1
  25. package/dist/api/routes.d.ts +22 -0
  26. package/dist/api/routes.js +1 -1
  27. package/dist/build-root.d.ts +6 -1
  28. package/dist/build-root.js +1 -1
  29. package/dist/builtin-memory/crouter-sdk/client.md +34 -0
  30. package/dist/builtin-memory/crouter-sdk/errors.md +2 -0
  31. package/dist/builtin-memory/crouter-sdk/memory.md +2 -2
  32. package/dist/builtin-memory/crouter-sdk/streaming.md +21 -0
  33. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +8 -4
  34. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +39 -118
  35. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -1
  36. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +41 -27
  37. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +52 -29
  38. package/dist/cli.js +9 -8
  39. package/dist/clients/attach/chrome/inbox-strip.js +1 -1
  40. package/dist/clients/attach/chrome/roster.js +1 -1
  41. package/dist/clients/attach/config.js +1 -1
  42. package/dist/clients/attach/overlays/auth.js +2 -2
  43. package/dist/clients/attach/overlays/graph.js +1 -1
  44. package/dist/clients/attach/render/tool-calls.js +3 -3
  45. package/dist/clients/attach/session/connection.js +1 -1
  46. package/dist/clients/attach/session/profile-files.js +1 -1
  47. package/dist/clients/attach/viewer.js +1569 -816
  48. package/dist/commands/api-client.js +3 -3
  49. package/dist/commands/broker-permissions.d.ts +2 -0
  50. package/dist/commands/broker-permissions.js +1 -0
  51. package/dist/commands/canvas-analytics/chart.d.ts +52 -0
  52. package/dist/commands/canvas-analytics/chart.js +1 -0
  53. package/dist/commands/canvas-analytics/drilldown.d.ts +34 -0
  54. package/dist/commands/canvas-analytics/drilldown.js +1 -0
  55. package/dist/commands/canvas-analytics/format.d.ts +29 -0
  56. package/dist/commands/canvas-analytics/format.js +1 -0
  57. package/dist/commands/canvas-analytics/graph-detail.d.ts +2 -0
  58. package/dist/commands/canvas-analytics/graph-detail.js +2 -0
  59. package/dist/commands/canvas-analytics/graphs.d.ts +9 -0
  60. package/dist/commands/canvas-analytics/graphs.js +1 -0
  61. package/dist/commands/canvas-analytics/memory.d.ts +2 -0
  62. package/dist/commands/canvas-analytics/memory.js +1 -0
  63. package/dist/commands/canvas-analytics/overview.d.ts +2 -0
  64. package/dist/commands/canvas-analytics/overview.js +1 -0
  65. package/dist/commands/canvas-analytics/shell.d.ts +60 -0
  66. package/dist/commands/canvas-analytics/shell.js +2 -0
  67. package/dist/commands/canvas-analytics/time.d.ts +2 -0
  68. package/dist/commands/canvas-analytics/time.js +1 -0
  69. package/dist/commands/canvas-analytics/usage.d.ts +2 -0
  70. package/dist/commands/canvas-analytics/usage.js +1 -0
  71. package/dist/commands/canvas-analytics/view.d.ts +85 -0
  72. package/dist/commands/canvas-analytics/view.js +1 -0
  73. package/dist/commands/canvas-analytics.d.ts +2 -0
  74. package/dist/commands/canvas-analytics.js +1 -0
  75. package/dist/commands/canvas-prune.js +1 -1
  76. package/dist/commands/canvas.js +1 -1
  77. package/dist/commands/cron.js +5 -5
  78. package/dist/commands/human/components.d.ts +2 -0
  79. package/dist/commands/human/components.js +2 -2
  80. package/dist/commands/human/prompts.js +1 -1
  81. package/dist/commands/human/queue.js +1 -1
  82. package/dist/commands/memory/client.d.ts +11 -0
  83. package/dist/commands/memory/client.js +1 -0
  84. package/dist/commands/memory/delete.js +1 -1
  85. package/dist/commands/memory/edit.js +3 -3
  86. package/dist/commands/memory/find.js +1 -1
  87. package/dist/commands/memory/history.js +4 -4
  88. package/dist/commands/memory/lint.js +1 -1
  89. package/dist/commands/memory/list.d.ts +0 -2
  90. package/dist/commands/memory/list.js +1 -1
  91. package/dist/commands/memory/move.js +1 -1
  92. package/dist/commands/memory/origin.js +1 -1
  93. package/dist/commands/memory/read.d.ts +0 -5
  94. package/dist/commands/memory/read.js +3 -3
  95. package/dist/commands/memory/shared.d.ts +0 -178
  96. package/dist/commands/memory/shared.js +1 -12
  97. package/dist/commands/memory/write.js +5 -5
  98. package/dist/commands/node/bash.js +5 -5
  99. package/dist/commands/node/create.d.ts +0 -17
  100. package/dist/commands/node/create.js +2 -3
  101. package/dist/commands/node/inspect.js +6 -6
  102. package/dist/commands/node/lifecycle.js +2 -2
  103. package/dist/commands/node-context.js +2 -2
  104. package/dist/commands/node-inspect-artifacts.js +6 -6
  105. package/dist/commands/pkg/browse/catalog.js +1 -1
  106. package/dist/commands/pkg/browse/model.d.ts +1 -1
  107. package/dist/commands/pkg/market-manage.js +1 -1
  108. package/dist/commands/pkg/plugin-manage.js +10 -10
  109. package/dist/commands/profile/daemon-profiles.d.ts +13 -0
  110. package/dist/commands/profile/daemon-profiles.js +4 -0
  111. package/dist/commands/profile/delete.js +1 -1
  112. package/dist/commands/profile/env.d.ts +6 -0
  113. package/dist/commands/profile/env.js +2 -2
  114. package/dist/commands/profile/kind.js +1 -2
  115. package/dist/commands/profile/list.js +1 -1
  116. package/dist/commands/profile/meta.js +1 -1
  117. package/dist/commands/profile/new.js +1 -1
  118. package/dist/commands/profile/pause.js +1 -1
  119. package/dist/commands/profile/project.js +1 -1
  120. package/dist/commands/profile/rename.js +1 -1
  121. package/dist/commands/profile/show.js +1 -1
  122. package/dist/commands/profile.js +1 -1
  123. package/dist/commands/push.js +3 -3
  124. package/dist/commands/surface-inspect.js +1 -1
  125. package/dist/commands/sys/branch.js +1 -1
  126. package/dist/commands/sys/config.js +1 -1
  127. package/dist/commands/sys/connect.js +3 -3
  128. package/dist/commands/sys/context/admin/actions.js +1 -1
  129. package/dist/commands/sys/context/admin/model.d.ts +1 -0
  130. package/dist/commands/sys/context/admin/model.js +1 -1
  131. package/dist/commands/sys/context/admin.js +1 -1
  132. package/dist/commands/sys/context/expose.js +2 -1
  133. package/dist/commands/sys/context/prompt-review.js +2 -2
  134. package/dist/commands/sys/context/resolve.js +7 -7
  135. package/dist/commands/sys/context/sysprompt.js +1 -1
  136. package/dist/commands/sys/join.d.ts +1 -0
  137. package/dist/commands/sys/join.js +1 -0
  138. package/dist/commands/sys/migrate.js +1 -1
  139. package/dist/commands/sys/panels/models-panel.js +1 -1
  140. package/dist/commands/sys/panels/profiles-panel.d.ts +0 -1
  141. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  142. package/dist/commands/sys/provider-login.js +6 -6
  143. package/dist/commands/sys/setup-core.d.ts +1 -1
  144. package/dist/commands/sys/setup-core.js +6 -6
  145. package/dist/commands/sys/setup-settings-runner.js +1 -1
  146. package/dist/commands/sys/setup.js +1 -1
  147. package/dist/commands/sys/spaces.d.ts +1 -0
  148. package/dist/commands/sys/spaces.js +2 -0
  149. package/dist/commands/sys/sync-deps.js +2 -2
  150. package/dist/commands/sys/sync-project-guidance.js +4 -4
  151. package/dist/commands/sys/sync-skills.js +2 -2
  152. package/dist/commands/sys/worktrees.d.ts +1 -0
  153. package/dist/commands/sys/worktrees.js +1 -1
  154. package/dist/commands/sys.js +1 -1
  155. package/dist/core/auth-file.js +2 -2
  156. package/dist/core/bash-job-supervisor.d.ts +6 -0
  157. package/dist/core/bash-job-supervisor.js +4 -0
  158. package/dist/core/bash-jobs.d.ts +13 -6
  159. package/dist/core/bash-jobs.js +8 -7
  160. package/dist/core/broker-client/transport-relay.d.ts +6 -3
  161. package/dist/core/broker-client/transport-relay.js +1 -1
  162. package/dist/core/broker-client/transport-socket.d.ts +6 -1
  163. package/dist/core/broker-client/transport-socket.js +1 -1
  164. package/dist/core/canvas/canvas.d.ts +39 -18
  165. package/dist/core/canvas/canvas.js +21 -20
  166. package/dist/core/canvas/context-strip.d.ts +20 -0
  167. package/dist/core/canvas/context-strip.js +5 -0
  168. package/dist/core/canvas/crons.d.ts +12 -20
  169. package/dist/core/canvas/crons.js +15 -13
  170. package/dist/core/canvas/db.js +2 -2
  171. package/dist/core/canvas/deliveries.d.ts +4 -1
  172. package/dist/core/canvas/deliveries.js +1 -1
  173. package/dist/core/canvas/executions.js +1 -1
  174. package/dist/core/canvas/history.d.ts +2 -1
  175. package/dist/core/canvas/history.js +17 -18
  176. package/dist/core/canvas/memory-reads.d.ts +19 -0
  177. package/dist/core/canvas/memory-reads.js +1 -0
  178. package/dist/core/canvas/migrations.d.ts +0 -4
  179. package/dist/core/canvas/migrations.js +99 -32
  180. package/dist/core/canvas/nav-render.js +1 -1
  181. package/dist/core/canvas/node-agent-paths.d.ts +8 -0
  182. package/dist/core/canvas/node-agent-paths.js +1 -0
  183. package/dist/core/canvas/node-recap.d.ts +2 -2
  184. package/dist/core/canvas/node-recap.js +2 -2
  185. package/dist/core/canvas/node-tokens.d.ts +24 -0
  186. package/dist/core/canvas/node-tokens.js +5 -0
  187. package/dist/core/canvas/paths.d.ts +16 -19
  188. package/dist/core/canvas/paths.js +1 -1
  189. package/dist/core/canvas/render-source.d.ts +2 -2
  190. package/dist/core/canvas/render-source.js +6 -9
  191. package/dist/core/canvas/sessions.d.ts +18 -0
  192. package/dist/core/canvas/sessions.js +4 -1
  193. package/dist/core/canvas/types.d.ts +22 -6
  194. package/dist/core/command-hooks/compose.js +1 -1
  195. package/dist/core/command-hooks/discovery.d.ts +15 -1
  196. package/dist/core/command-hooks/discovery.js +1 -1
  197. package/dist/core/command-hooks/help.d.ts +2 -2
  198. package/dist/core/command-hooks/lifecycle-create.d.ts +1 -1
  199. package/dist/core/command-hooks/lifecycle-create.js +1 -1
  200. package/dist/core/command-hooks/transport/exec-invoke.d.ts +2 -0
  201. package/dist/core/command-hooks/transport/exec-invoke.js +1 -1
  202. package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +1 -0
  203. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  204. package/dist/core/command-hooks/transport/plan.d.ts +3 -0
  205. package/dist/core/command-hooks/transport/plan.js +1 -0
  206. package/dist/core/command-plugins/discovery.js +1 -1
  207. package/dist/core/command-plugins/transport/http-invoke.js +2 -2
  208. package/dist/core/command.d.ts +6 -2
  209. package/dist/core/command.js +6 -6
  210. package/dist/core/config.d.ts +8 -5
  211. package/dist/core/config.js +1 -1
  212. package/dist/core/conversation-store/client-worker.d.ts +1 -0
  213. package/dist/core/conversation-store/client-worker.js +1 -0
  214. package/dist/core/conversation-store/client.d.ts +2 -0
  215. package/dist/core/conversation-store/client.js +2 -0
  216. package/dist/core/conversation-store/file-store.d.ts +37 -0
  217. package/dist/core/conversation-store/file-store.js +9 -0
  218. package/dist/core/conversation-store/index.d.ts +50 -0
  219. package/dist/core/conversation-store/index.js +1 -0
  220. package/dist/core/conversation-store/listener.d.ts +4 -0
  221. package/dist/core/conversation-store/listener.js +3 -0
  222. package/dist/core/conversation-store/patch.d.ts +1 -0
  223. package/dist/core/conversation-store/patch.js +1 -0
  224. package/dist/core/directory/join.d.ts +27 -0
  225. package/dist/core/directory/join.js +1 -0
  226. package/dist/core/disk-usage.d.ts +4 -0
  227. package/dist/core/disk-usage.js +1 -0
  228. package/dist/core/events/emit.d.ts +2 -0
  229. package/dist/core/events/emit.js +3 -1
  230. package/dist/core/feed/feed.js +4 -4
  231. package/dist/core/feed/messages.d.ts +3 -0
  232. package/dist/core/feed/messages.js +6 -6
  233. package/dist/core/fs-utils.d.ts +2 -0
  234. package/dist/core/fs-utils.js +3 -3
  235. package/dist/core/grants/local.d.ts +4 -0
  236. package/dist/core/grants/local.js +1 -0
  237. package/dist/core/grants/mirror.d.ts +44 -0
  238. package/dist/core/grants/mirror.js +4 -0
  239. package/dist/core/grants/on-sync.d.ts +22 -0
  240. package/dist/core/grants/on-sync.js +1 -0
  241. package/dist/core/grants/remove.d.ts +7 -0
  242. package/dist/core/grants/remove.js +1 -0
  243. package/dist/core/grants/sandboxes.d.ts +7 -0
  244. package/dist/core/grants/sandboxes.js +1 -0
  245. package/dist/core/grants/sync.d.ts +12 -0
  246. package/dist/core/grants/sync.js +1 -0
  247. package/dist/core/help/memory-extensions.d.ts +3 -0
  248. package/dist/core/help/memory-extensions.js +2 -0
  249. package/dist/core/help.d.ts +14 -0
  250. package/dist/core/help.js +7 -7
  251. package/dist/core/host-exports/builtins.js +3 -3
  252. package/dist/core/host-exports/export.js +3 -3
  253. package/dist/core/human/action-binding.d.ts +2 -0
  254. package/dist/core/human/action-binding.js +1 -1
  255. package/dist/core/human/feedback-companion.d.ts +0 -1
  256. package/dist/core/human/feedback-companion.js +1 -1
  257. package/dist/core/human/page-schema.d.ts +1 -1
  258. package/dist/core/inspector/core.d.ts +2 -0
  259. package/dist/core/inspector/core.js +1 -1
  260. package/dist/core/inspector/tui.js +2 -2
  261. package/dist/core/installed-plugins.js +1 -1
  262. package/dist/core/io.js +6 -6
  263. package/dist/core/keybindings/catalog.d.ts +1 -1
  264. package/dist/core/keybindings/catalog.js +1 -1
  265. package/dist/core/layout-migrate/index.d.ts +15 -0
  266. package/dist/core/layout-migrate/index.js +4 -0
  267. package/dist/core/layout-migrate/paths.d.ts +26 -0
  268. package/dist/core/layout-migrate/paths.js +1 -0
  269. package/dist/core/layout-migrate/stored-paths.d.ts +2 -0
  270. package/dist/core/layout-migrate/stored-paths.js +11 -0
  271. package/dist/core/layout-migrate/stores.d.ts +17 -0
  272. package/dist/core/layout-migrate/stores.js +4 -0
  273. package/dist/core/layout.d.ts +26 -0
  274. package/dist/core/layout.js +2 -0
  275. package/dist/core/llm/run.d.ts +60 -0
  276. package/dist/core/llm/run.js +4 -0
  277. package/dist/core/memory/cli-selector.d.ts +13 -0
  278. package/dist/core/memory/cli-selector.js +1 -0
  279. package/dist/core/memory/history.d.ts +5 -4
  280. package/dist/core/memory/history.js +6 -6
  281. package/dist/core/memory/inline-ref-inventory.d.ts +2 -1
  282. package/dist/core/memory/inline-ref-inventory.js +1 -1
  283. package/dist/core/memory/lint.js +2 -2
  284. package/dist/core/memory/mutation-domain.d.ts +2 -2
  285. package/dist/core/memory/mutation-domain.js +8 -7
  286. package/dist/core/memory/mutations.js +1 -1
  287. package/dist/core/memory/service.d.ts +5 -0
  288. package/dist/core/memory/service.js +2 -2
  289. package/dist/core/memory-resolver.d.ts +11 -7
  290. package/dist/core/memory-resolver.js +2 -2
  291. package/dist/core/model-auth/daemon-login.d.ts +13 -0
  292. package/dist/core/model-auth/daemon-login.js +1 -0
  293. package/dist/core/model-auth/flows.d.ts +45 -0
  294. package/dist/core/model-auth/flows.js +1 -0
  295. package/dist/core/model-auth/handoff-jti.d.ts +4 -0
  296. package/dist/core/model-auth/handoff-jti.js +1 -0
  297. package/dist/core/model-routes.js +1 -1
  298. package/dist/core/nested-stores.d.ts +2 -1
  299. package/dist/core/nested-stores.js +1 -2
  300. package/dist/core/preview-registry.js +2 -2
  301. package/dist/core/profiles/env-store.js +2 -2
  302. package/dist/core/profiles/manifest.d.ts +16 -5
  303. package/dist/core/profiles/manifest.js +1 -1
  304. package/dist/core/provider-management.js +1 -1
  305. package/dist/core/review/birth.js +1 -1
  306. package/dist/core/review/companion.d.ts +0 -2
  307. package/dist/core/review/companion.js +1 -1
  308. package/dist/core/review/fork.js +2 -2
  309. package/dist/core/review/realize.js +1 -1
  310. package/dist/core/review/stage.d.ts +1 -1
  311. package/dist/core/review/stage.js +1 -1
  312. package/dist/core/review/types.d.ts +1 -1
  313. package/dist/core/runs/events.d.ts +34 -0
  314. package/dist/core/runs/events.js +1 -0
  315. package/dist/core/runs/operations.d.ts +43 -0
  316. package/dist/core/runs/operations.js +12 -0
  317. package/dist/core/runtime/bearings-render.d.ts +2 -2
  318. package/dist/core/runtime/bearings-render.js +11 -11
  319. package/dist/core/runtime/bearings.js +2 -2
  320. package/dist/core/runtime/broker/cli-relay.d.ts +5 -0
  321. package/dist/core/runtime/broker/cli-relay.js +1 -0
  322. package/dist/core/runtime/broker/client-registry.d.ts +0 -5
  323. package/dist/core/runtime/broker/client-registry.js +1 -1
  324. package/dist/core/runtime/broker/daemon-ops.d.ts +28 -1
  325. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  326. package/dist/core/runtime/broker/engine-drive.d.ts +0 -2
  327. package/dist/core/runtime/broker/engine-drive.js +1 -1
  328. package/dist/core/runtime/broker/fault-retry.d.ts +9 -0
  329. package/dist/core/runtime/broker/fault-retry.js +1 -1
  330. package/dist/core/runtime/broker/frame-dispatch.d.ts +5 -9
  331. package/dist/core/runtime/broker/frame-dispatch.js +1 -1
  332. package/dist/core/runtime/broker/frame-engine-control.d.ts +3 -2
  333. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  334. package/dist/core/runtime/broker/frame-memory-refs.d.ts +4 -3
  335. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  336. package/dist/core/runtime/broker/frame-read.js +1 -1
  337. package/dist/core/runtime/broker/frame-session.js +1 -1
  338. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -1
  339. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  340. package/dist/core/runtime/broker/inbox.d.ts +1 -2
  341. package/dist/core/runtime/broker/inbox.js +7 -10
  342. package/dist/core/runtime/broker/model-adapter.d.ts +9 -0
  343. package/dist/core/runtime/broker/model-adapter.js +2 -0
  344. package/dist/core/runtime/broker/node-token.d.ts +3 -0
  345. package/dist/core/runtime/broker/node-token.js +1 -0
  346. package/dist/core/runtime/broker/read-ops.js +1 -1
  347. package/dist/core/runtime/broker/rebind.d.ts +2 -0
  348. package/dist/core/runtime/broker/rebind.js +1 -1
  349. package/dist/core/runtime/broker/tool-groups.js +1 -1
  350. package/dist/core/runtime/broker/turn-ignition.d.ts +3 -3
  351. package/dist/core/runtime/broker/turn-ignition.js +1 -1
  352. package/dist/core/runtime/broker-cli.js +3 -3
  353. package/dist/core/runtime/broker-extension-render.d.ts +2 -5
  354. package/dist/core/runtime/broker-extension-render.js +4 -4
  355. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  356. package/dist/core/runtime/broker-protocol.d.ts +7 -8
  357. package/dist/core/runtime/broker.js +1 -1
  358. package/dist/core/runtime/canvas-extensions.d.ts +1 -0
  359. package/dist/core/runtime/canvas-extensions.js +1 -1
  360. package/dist/core/runtime/close.d.ts +9 -0
  361. package/dist/core/runtime/close.js +1 -1
  362. package/dist/core/runtime/deliver-live.js +1 -1
  363. package/dist/core/runtime/fleet.d.ts +1 -1
  364. package/dist/core/runtime/front-door-login.js +1 -1
  365. package/dist/core/runtime/front-door.js +2 -2
  366. package/dist/core/runtime/headless-pi.d.ts +1 -1
  367. package/dist/core/runtime/headless-pi.js +1 -1
  368. package/dist/core/runtime/host.d.ts +1 -1
  369. package/dist/core/runtime/host.js +3 -1
  370. package/dist/core/runtime/invocation.d.ts +3 -0
  371. package/dist/core/runtime/kickoff.d.ts +1 -0
  372. package/dist/core/runtime/kickoff.js +16 -16
  373. package/dist/core/runtime/launch-target.d.ts +1 -1
  374. package/dist/core/runtime/launch-target.js +1 -1
  375. package/dist/core/runtime/launch.d.ts +10 -35
  376. package/dist/core/runtime/launch.js +1 -1
  377. package/dist/core/runtime/lifecycle.js +2 -2
  378. package/dist/core/runtime/memory.d.ts +1 -1
  379. package/dist/core/runtime/memory.js +1 -1
  380. package/dist/core/runtime/model-registry.js +1 -1
  381. package/dist/core/runtime/model-swap.d.ts +17 -19
  382. package/dist/core/runtime/model-swap.js +1 -1
  383. package/dist/core/runtime/node-read.js +3 -2
  384. package/dist/core/runtime/nodes.d.ts +7 -0
  385. package/dist/core/runtime/nodes.js +1 -1
  386. package/dist/core/runtime/outcome-document.js +1 -1
  387. package/dist/core/runtime/package-health.js +2 -2
  388. package/dist/core/runtime/persona.js +2 -2
  389. package/dist/core/runtime/pi-vendored.js +1 -1
  390. package/dist/core/runtime/placement-tmux.d.ts +1 -1
  391. package/dist/core/runtime/placement-tmux.js +1 -1
  392. package/dist/core/runtime/placement.js +1 -1
  393. package/dist/core/runtime/promote.js +1 -1
  394. package/dist/core/runtime/provider-credential-gate.js +2 -2
  395. package/dist/core/runtime/recovery-hold.d.ts +2 -0
  396. package/dist/core/runtime/recovery-hold.js +1 -0
  397. package/dist/core/runtime/recycle.js +1 -1
  398. package/dist/core/runtime/reopen.js +1 -1
  399. package/dist/core/runtime/reset.js +1 -1
  400. package/dist/core/runtime/revive.d.ts +1 -1
  401. package/dist/core/runtime/revive.js +2 -3
  402. package/dist/core/runtime/roadmap.js +4 -4
  403. package/dist/core/runtime/run-command.d.ts +6 -0
  404. package/dist/core/runtime/run-command.js +1 -1
  405. package/dist/core/runtime/session-branch.d.ts +2 -8
  406. package/dist/core/runtime/session-branch.js +1 -1
  407. package/dist/core/runtime/session-list-cache.d.ts +6 -22
  408. package/dist/core/runtime/session-list-cache.js +1 -1
  409. package/dist/core/runtime/situational-context.js +2 -2
  410. package/dist/core/runtime/spawn-env.d.ts +6 -6
  411. package/dist/core/runtime/spawn-env.js +1 -1
  412. package/dist/core/runtime/spawn.d.ts +5 -0
  413. package/dist/core/runtime/spawn.js +2 -2
  414. package/dist/core/runtime/stop-guard.js +2 -2
  415. package/dist/core/runtime/stop-signals.d.ts +2 -2
  416. package/dist/core/runtime/stop-signals.js +1 -1
  417. package/dist/core/runtime/structured-output.d.ts +10 -4
  418. package/dist/core/runtime/structured-output.js +4 -4
  419. package/dist/core/runtime/tmux-bindings.js +3 -3
  420. package/dist/core/runtime/tmux-driver.d.ts +4 -0
  421. package/dist/core/runtime/tmux-driver.js +7 -7
  422. package/dist/core/runtime/view-socket.d.ts +9 -2
  423. package/dist/core/runtime/view-socket.js +1 -1
  424. package/dist/core/runtime/warm-pool.js +1 -1
  425. package/dist/core/scope.d.ts +3 -2
  426. package/dist/core/scope.js +1 -1
  427. package/dist/core/scoped-state/db.js +1 -1
  428. package/dist/core/scoped-state/migrate.js +3 -3
  429. package/dist/core/scoped-state/profiles.d.ts +2 -1
  430. package/dist/core/scoped-state/profiles.js +1 -1
  431. package/dist/core/scoped-state/schema.d.ts +2 -1
  432. package/dist/core/scoped-state/schema.js +4 -4
  433. package/dist/core/scopes.d.ts +2 -2
  434. package/dist/core/scopes.js +1 -1
  435. package/dist/core/secrets.d.ts +1 -0
  436. package/dist/core/secrets.js +2 -2
  437. package/dist/core/spaces/mounts.d.ts +32 -0
  438. package/dist/core/spaces/mounts.js +1 -0
  439. package/dist/core/spaces/open-beneath.d.ts +71 -0
  440. package/dist/core/spaces/open-beneath.js +1 -0
  441. package/dist/core/spaces/permissions.d.ts +46 -0
  442. package/dist/core/spaces/permissions.js +1 -0
  443. package/dist/core/spaces/process.d.ts +27 -0
  444. package/dist/core/spaces/process.js +1 -0
  445. package/dist/core/spaces/space.d.ts +8 -0
  446. package/dist/core/spaces/space.js +2 -0
  447. package/dist/core/spaces/stop.d.ts +8 -0
  448. package/dist/core/spaces/stop.js +2 -0
  449. package/dist/core/spaces/users.d.ts +19 -0
  450. package/dist/core/spaces/users.js +1 -0
  451. package/dist/core/subscription-state.d.ts +2 -0
  452. package/dist/core/subscription-state.js +3 -3
  453. package/dist/core/substrate/frontmatter-validation.js +1 -1
  454. package/dist/core/substrate/injected-store.d.ts +28 -3
  455. package/dist/core/substrate/injected-store.js +2 -1
  456. package/dist/core/substrate/listings.js +1 -1
  457. package/dist/core/substrate/memory-events.d.ts +6 -0
  458. package/dist/core/substrate/memory-events.js +1 -0
  459. package/dist/core/substrate/on-read-node.js +1 -1
  460. package/dist/core/substrate/on-read.d.ts +6 -6
  461. package/dist/core/substrate/on-read.js +5 -5
  462. package/dist/core/substrate/plan.js +1 -1
  463. package/dist/core/substrate/render-node.js +1 -1
  464. package/dist/core/substrate/render.d.ts +4 -3
  465. package/dist/core/substrate/render.js +38 -38
  466. package/dist/core/substrate/schema.d.ts +6 -0
  467. package/dist/core/substrate/schema.js +1 -1
  468. package/dist/core/tui/panel.js +1 -1
  469. package/dist/core/user-settings.d.ts +12 -0
  470. package/dist/core/user-settings.js +1 -1
  471. package/dist/core/worktree-mutation-async.js +5 -5
  472. package/dist/core/worktree-quarantine.js +1 -1
  473. package/dist/core/worktree-remove.d.ts +15 -0
  474. package/dist/core/worktree-remove.js +1 -0
  475. package/dist/core/worktree-sweep.js +6 -6
  476. package/dist/daemon/analytics/compute.d.ts +37 -0
  477. package/dist/daemon/analytics/compute.js +1 -0
  478. package/dist/daemon/analytics/scan-worker.d.ts +1 -0
  479. package/dist/daemon/analytics/scan-worker.js +2 -0
  480. package/dist/daemon/analytics/scan.d.ts +37 -0
  481. package/dist/daemon/analytics/scan.js +1 -0
  482. package/dist/daemon/api/app-listener.d.ts +11 -0
  483. package/dist/daemon/api/app-listener.js +21 -0
  484. package/dist/daemon/api/bridge.js +5 -5
  485. package/dist/daemon/api/handlers/analytics.d.ts +2 -0
  486. package/dist/daemon/api/handlers/analytics.js +1 -0
  487. package/dist/daemon/api/handlers/attach.js +1 -1
  488. package/dist/daemon/api/handlers/bash-jobs.js +2 -2
  489. package/dist/daemon/api/handlers/bash.js +1 -1
  490. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  491. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  492. package/dist/daemon/api/handlers/canvas.js +6 -6
  493. package/dist/daemon/api/handlers/crons.js +1 -1
  494. package/dist/daemon/api/handlers/files.d.ts +1 -1
  495. package/dist/daemon/api/handlers/files.js +1 -1
  496. package/dist/daemon/api/handlers/health.js +2 -2
  497. package/dist/daemon/api/handlers/hook-exec.d.ts +2 -0
  498. package/dist/daemon/api/handlers/hook-exec.js +1 -0
  499. package/dist/daemon/api/handlers/human-requests.js +1 -1
  500. package/dist/daemon/api/handlers/inbox.js +1 -1
  501. package/dist/daemon/api/handlers/llm.d.ts +2 -0
  502. package/dist/daemon/api/handlers/llm.js +3 -0
  503. package/dist/daemon/api/handlers/memory-reads.d.ts +4 -0
  504. package/dist/daemon/api/handlers/memory-reads.js +1 -0
  505. package/dist/daemon/api/handlers/memory.js +5 -1
  506. package/dist/daemon/api/handlers/messages.js +2 -2
  507. package/dist/daemon/api/handlers/modelauth.js +1 -1
  508. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  509. package/dist/daemon/api/handlers/node-records.d.ts +2 -0
  510. package/dist/daemon/api/handlers/node-records.js +3 -0
  511. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  512. package/dist/daemon/api/handlers/nodes.js +1 -1
  513. package/dist/daemon/api/handlers/profiles.d.ts +4 -1
  514. package/dist/daemon/api/handlers/profiles.js +1 -1
  515. package/dist/daemon/api/handlers/reports.js +5 -3
  516. package/dist/daemon/api/handlers/reviews.d.ts +1 -1
  517. package/dist/daemon/api/handlers/reviews.js +1 -1
  518. package/dist/daemon/api/handlers/run-routes.d.ts +2 -0
  519. package/dist/daemon/api/handlers/run-routes.js +1 -0
  520. package/dist/daemon/api/handlers/runs.d.ts +9 -0
  521. package/dist/daemon/api/handlers/runs.js +1 -0
  522. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  523. package/dist/daemon/api/handlers/worktree.js +1 -1
  524. package/dist/daemon/api/map.d.ts +10 -4
  525. package/dist/daemon/api/map.js +2 -2
  526. package/dist/daemon/api/operations.d.ts +18 -0
  527. package/dist/daemon/api/operations.js +1 -0
  528. package/dist/daemon/api/principal.d.ts +42 -0
  529. package/dist/daemon/api/principal.js +1 -0
  530. package/dist/daemon/api/router.d.ts +27 -3
  531. package/dist/daemon/api/router.js +1 -1
  532. package/dist/daemon/api/server.d.ts +4 -0
  533. package/dist/daemon/api/server.js +1 -1
  534. package/dist/daemon/api/vendor-signin.d.ts +7 -0
  535. package/dist/daemon/api/vendor-signin.js +77 -0
  536. package/dist/daemon/api/viewer-presence.d.ts +3 -0
  537. package/dist/daemon/api/viewer-presence.js +1 -0
  538. package/dist/daemon/cron/armed-context.d.ts +4 -0
  539. package/dist/daemon/cron/armed-context.js +1 -1
  540. package/dist/daemon/cron/escalation.js +3 -3
  541. package/dist/daemon/cron/lease-recovery.js +1 -1
  542. package/dist/daemon/cron/sinks.js +2 -2
  543. package/dist/daemon/cron-run.d.ts +5 -5
  544. package/dist/daemon/cron-run.js +1 -1
  545. package/dist/daemon/crtrd-cli.js +1 -1
  546. package/dist/daemon/crtrd.js +8 -7
  547. package/dist/daemon/delivery/run-delivery.d.ts +4 -0
  548. package/dist/daemon/delivery/run-delivery.js +1 -1
  549. package/dist/daemon/fleet.d.ts +1 -1
  550. package/dist/daemon/fleet.js +6 -6
  551. package/dist/daemon/http-dispatcher.d.ts +1 -0
  552. package/dist/daemon/http-dispatcher.js +1 -0
  553. package/dist/daemon/human/finish.js +7 -7
  554. package/dist/daemon/joined-owner.d.ts +5 -0
  555. package/dist/daemon/joined-owner.js +1 -0
  556. package/dist/daemon/manage.js +2 -2
  557. package/dist/daemon/messaging/node-message.js +1 -1
  558. package/dist/daemon/park-activity.js +1 -1
  559. package/dist/daemon/reconcilers/bash-deadline.js +1 -1
  560. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  561. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  562. package/dist/daemon/reconcilers/delivery-lane.js +1 -1
  563. package/dist/daemon/reconcilers/live-obligation.d.ts +7 -0
  564. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  565. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  566. package/dist/daemon/reconcilers/storage-maintenance.d.ts +20 -1
  567. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  568. package/dist/daemon/runs/append-section.d.ts +6 -0
  569. package/dist/daemon/runs/append-section.js +2 -0
  570. package/dist/daemon/runs/observer.d.ts +5 -0
  571. package/dist/daemon/runs/observer.js +4 -0
  572. package/dist/launcher/bwrap.d.ts +4 -0
  573. package/dist/launcher/bwrap.js +2 -0
  574. package/dist/launcher/client.d.ts +2 -0
  575. package/dist/launcher/client.js +3 -0
  576. package/dist/launcher/main.d.ts +1 -0
  577. package/dist/launcher/main.js +3 -0
  578. package/dist/launcher/netrule.d.ts +1 -0
  579. package/dist/launcher/netrule.js +1 -0
  580. package/dist/launcher/seccomp.d.ts +1 -0
  581. package/dist/launcher/seccomp.js +1 -0
  582. package/dist/launcher/spec.d.ts +88 -0
  583. package/dist/launcher/spec.js +1 -0
  584. package/dist/launcher/users.d.ts +18 -0
  585. package/dist/launcher/users.js +7 -0
  586. package/dist/launcher/validate.d.ts +22 -0
  587. package/dist/launcher/validate.js +1 -0
  588. package/dist/migrations/corpus.js +3 -3
  589. package/dist/migrations/runner.js +1 -1
  590. package/dist/native/linux/addon.node +0 -0
  591. package/dist/native/linux.d.ts +29 -0
  592. package/dist/native/linux.js +1 -0
  593. package/dist/pi-extensions/broker-local.js +2 -2
  594. package/dist/pi-extensions/canvas-bash-valve.d.ts +1 -3
  595. package/dist/pi-extensions/canvas-bash-valve.js +4 -7
  596. package/dist/pi-extensions/canvas-context-intro.d.ts +1 -2
  597. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  598. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  599. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +2 -1
  600. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -1
  601. package/dist/pi-extensions/canvas-passive-context.d.ts +1 -1
  602. package/dist/pi-extensions/canvas-passive-context.js +11 -11
  603. package/dist/pi-extensions/canvas-recap.js +6 -6
  604. package/dist/pi-extensions/canvas-stophook.js +1 -1
  605. package/dist/pi-extensions/canvas-structured-output.js +4 -4
  606. package/dist/pi-extensions/canvas-tool-guide.js +1 -1
  607. package/dist/pi-extensions/system-prompt-entry.d.ts +15 -0
  608. package/dist/pi-extensions/system-prompt-entry.js +1 -0
  609. package/dist/shared/env.d.ts +5 -1
  610. package/dist/shared/env.js +1 -1
  611. package/dist/shared/strip-cd-prefix.d.ts +1 -0
  612. package/dist/shared/strip-cd-prefix.js +1 -0
  613. package/dist/types.d.ts +31 -15
  614. package/docs/cli/memory-and-preferences.md +3 -1
  615. package/docs/sdk/client.md +34 -0
  616. package/docs/sdk/errors.md +2 -0
  617. package/docs/sdk/memory.md +2 -2
  618. package/docs/sdk/streaming.md +21 -0
  619. package/package.json +19 -4
  620. package/packages/crouter-identity/dist/index.d.ts +54 -0
  621. package/packages/crouter-identity/dist/index.js +166 -0
  622. package/packages/crouter-identity/package.json +33 -0
  623. package/runtime.lock.json +44 -8
  624. package/scripts/build-native-linux.mjs +16 -0
  625. package/scripts/install-runtime.mjs +9 -7
  626. package/scripts/lib/isolation-env.mjs +42 -0
  627. package/scripts/runtime-smoke.mjs +49 -0
  628. package/src/native/linux/addon.c +249 -0
  629. package/dist/core/profiles/state-block.d.ts +0 -4
  630. package/dist/core/profiles/state-block.js +0 -3
  631. package/dist/core/runtime/broker/auth-reload.d.ts +0 -41
  632. package/dist/core/runtime/broker/auth-reload.js +0 -1
  633. package/dist/core/substrate/cli-context-delivery.d.ts +0 -22
  634. package/dist/core/substrate/cli-context-delivery.js +0 -1
@@ -1,4 +1,4 @@
1
- var D=Object.defineProperty;var s=(t,e)=>D(t,"name",{value:e,configurable:!0});import{existsSync as P,readdirSync as E,readFileSync as A,statSync as C}from"node:fs";import{join as I}from"node:path";import{getNode as f}from"../../../core/canvas/canvas.js";import{push as F,FinalizationError as S}from"../../../core/feed/feed.js";import{branchIsPushedAtCurrentTip as j,hasOpenManagedWorktree as J,missingWorktreeRecoveryHint as M}from"../../../core/worktree.js";import{autoDropCleanManagedWorktreeAsync as z}from"../../../core/worktree-mutation-async.js";import{reportsDir as B}from"../../../core/canvas/paths.js";import{notFound as H,usage as c}from"../../../core/errors.js";import{InputError as d}from"../../../core/io.js";import{parseFrontmatterGeneric as W}from"../../../core/frontmatter.js";import{toReportResultDTO as L}from"../map.js";import{outputSchemaPath as G,readOutputRequest as k,removeOutputSchema as X,validateStructuredResult as K,writeOutputDeclined as V,writeOutputResult as Q}from"../../../core/runtime/structured-output.js";import{nodeEventStreams as O}from"./node-events.js";function g(t){if(f(t)===null)throw H(`unknown node: ${t}`,{received:t})}s(g,"requireNode");function U(t){if(typeof t!="object"||t===null)throw c("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 c(`invalid report tier: ${String(e)} (expected update|urgent|final)`);if(r!==void 0&&r!=="deferred"&&r!=="normal"&&r!=="urgent")throw c(`invalid delivery_tier: ${String(r)} (expected deferred|normal|urgent)`);if(e!=="update"&&r!==void 0)throw c("delivery_tier is only valid for update reports");if(typeof n!="string"||n.trim()==="")throw c("a push report requires a non-empty body");return{tier:e,...r===void 0?{}:{delivery_tier:r},body:n}}s(U,"parsePushBody");async function Y(t){const e=t.params.id;g(e);const r=U(t.body);if(r.tier==="final"&&k(e).state==="valid")throw new d({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"?f(e)?.status:void 0,i=r.tier==="final"?await $(e):void 0,o=await q(e,r),u=r.tier==="final"&&n!==void 0?{from:n,to:f(e)?.status??"done"}:void 0,l=L(o,u,i),p=b(e).find(a=>a.path===o.reportPath);return p!==void 0&&O.report(e,p),{status:200,body:l}}s(Y,"handlePush");async function $(t){if(!J(f(t)))return;const e=await z(t);if(e!==null)return e.worktree_path;if(!await j(f(t).managed_worktree))throw new d({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=f(t)?.managed_worktree;return r!=null&&r.state==="open"&&!P(r.path)?M(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."})()})}s($,"guardFinalWorktree");const R=2e3;function Z(t,e){const r=JSON.stringify(e,null,2),n=r.length>R?`${r.slice(0,R)}
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)}
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,11 +6,13 @@ Result path: ${t}
6
6
  \`\`\`json
7
7
  ${n}
8
8
  \`\`\`
9
- `}s(Z,"submitReportBody");function ee(t,e){return`Structured result declined.
9
+ `}a(de,"submitReportBody");function ue(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
- `}s(ee,"declineReportBody");const T=1024,N=64;function te(t){if(typeof t!="object"||t===null)throw c("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 c("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 d({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>T)throw new d({error:"decline_reason_too_long",message:`A decline reason is at most ${T} 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>N)throw new d({error:"invalid_decline_code",message:`A decline needs a code: one whitespace-free token of at most ${N} characters naming the decline class.`,next:"Rerun with `--code <token>` \u2014 the token your requester documented for this case."});if(typeof o!="boolean")throw c("a decline carries `retryable` as a boolean");return{declined:{reason:n.trim(),code:i.trim(),retryable:o}}}if(!e)throw c("a result submission requires a JSON body { value } or { decline, code, retryable }");return{value:t.value}}s(te,"parseSubmitBody");async function re(t){const e=t.params.id;g(e);const r=te(t.body),n=k(e);if(n.state==="absent")throw new d({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(n.state==="invalid")throw new d({error:"invalid_output_request",message:`The structured-output request file is invalid: ${n.error}`,next:`Have the requester re-issue the request, or remove ${G(e)} and finish with \`crtr push final\`.`});const{mode:i,schema:o}=n.request;let u;if("value"in r)try{u=await K(o,r.value)}catch(h){throw new d({error:"result_schema_mismatch",message:`the submitted result does not match the requested schema: ${h.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 l=i==="terminal"?f(e)?.status:void 0,p=i==="terminal"?await $(e):void 0;let a,m,w;if("declined"in r){const{declined:h}=r;if(a=V(e,{mode:i,...h,at:new Date().toISOString()}),m=ee(a,h),i==="terminal"){const x={schema:"crtr.node-outcome-detail/v1",message:h.reason,declined:h};w={kind:"failure",reason:"declined",detailJson:JSON.stringify(x)}}}else a=Q(e,u),m=Z(a,u);const y=await q(e,{tier:i==="terminal"?"final":"update",body:m},w);X(e);const _=i==="terminal"&&l!==void 0?{from:l,to:f(e)?.status??"done"}:void 0,v=b(e).find(h=>h.path===y.reportPath);return v!==void 0&&O.report(e,v),{status:200,body:{mode:i,result_path:a,report_path:y.reportPath,notified:[...y.deliveredTo],..."declined"in r?{declined:r.declined}:{},..._===void 0?{}:{transitioned:_},...p===void 0?{}:{worktree_auto_dropped:!0,worktree_auto_dropped_path:p}}}}s(re,"handleSubmitResult");async function q(t,e,r){try{return await F(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 d({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 d({error:"finalization_forbidden",message:"A canceled or dead node cannot submit a canonical final result.",next:"Do not push final from this node."}):n}}s(q,"pushOrRethrow");function ne(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]}`}s(ne,"compactToIso");function b(t){const e=B(t);let r;try{r=E(e).filter(i=>i.endsWith(".md"))}catch{r=[]}const n=[];for(const i of r){const o=I(e,i),u=A(o,"utf8"),{data:l,body:p}=W(u),a=i.match(/^([0-9]{8}T[0-9]{6})-(\w+)\.md$/),m=(typeof l?.kind=="string"?l.kind:void 0)??(a?a[2]:"update"),w=(typeof l?.ts=="string"?l.ts:void 0)??(a?ne(a[1]):new Date(C(o).mtimeMs).toISOString());n.push({path:o,tier:m,body:p.trim(),created:w})}return n.sort((i,o)=>i.created<o.created?1:i.created>o.created?-1:0),n}s(b,"reportsForNode");function ie(t){const e=t.params.id;g(e);const r=t.query.get("tier"),n=t.query.get("limit"),i=n!==null?Number(n):void 0;let o=b(e);return r!==null&&(o=o.filter(u=>u.tier===r)),i!==void 0&&Number.isFinite(i)&&i>=0&&(o=o.slice(0,i)),{status:200,body:o}}s(ie,"handleList");const _e=[{method:"POST",pattern:"/v1/nodes/:id/reports",ownerOnly:!0,handler:Y},{method:"GET",pattern:"/v1/nodes/:id/reports",handler:ie},{method:"POST",pattern:"/v1/nodes/:id/result",handler:re}];export{_e as reportRoutes,b as reportsForNode};
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)}
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};
@@ -1,2 +1,2 @@
1
- import type { RouteTable } from '../router.js';
1
+ import { type RouteTable } from '../router.js';
2
2
  export declare const reviewRoutes: RouteTable;
@@ -1 +1 @@
1
- var _=Object.defineProperty;var d=(n,e)=>_(n,"name",{value:e,configurable:!0});import{isSafeNodeId as f}from"../../../core/canvas/paths.js";import{getNode as y}from"../../../core/canvas/canvas.js";import{assertScope as g}from"../../../core/scopes.js";import{createReview as k}from"../../../core/review/birth.js";import{readAnchorBase as R,listReviews as q,requireVisibleReview as w}from"../../../core/review/store.js";import{cancelReview as S,submitReviewApproval as E}from"../../review/finish.js";import{toFeedbackResultDTO as T,toReviewDTO as I}from"../map.js";import{invalidRequest as C,objectBody as v,optionalString as l,requireParam as D,requiredString as h}from"./validate.js";const A=new Set(["open","approved","canceled"]),O=["origin_kind","origin_node_id","file","idempotency_key","subtitle","output_path"],L=["reason","actor","disposition"];function a(n){C("review request",n)}d(a,"invalidRequest");function p(n,e){return D(n,"review_id","must be a safe review id",f,e)}d(p,"requireReviewId");function c(n){return{...I(n,n.state==="approved"?{result_path:`${n.review_dir}/result.json`}:{}),review_dir:n.review_dir}}d(c,"toReviewResponseDTO");function P(n){const e=[],i=v(n.body,O,e),o=i.origin_kind,t=o==="ticket"||o==="inline"?o:void 0;t===void 0&&e.push({field:"origin_kind",problem:"must be ticket or inline",...o===void 0?{}:{received:o}});const r=h(i,"origin_node_id",e);r!==void 0&&!f(r)&&e.push({field:"origin_node_id",problem:"must be a safe node id",received:r});const s=h(i,"file",e),u=h(i,"idempotency_key",e);u!==void 0&&u.length>128&&e.push({field:"idempotency_key",problem:"must be at most 128 characters",received:u});const m=l(i,"subtitle",e),b=l(i,"output_path",e);return t==="ticket"&&m===void 0&&i.subtitle===void 0&&e.push({field:"subtitle",problem:"is required for ticket reviews"}),t==="inline"&&i.subtitle!==void 0&&e.push({field:"subtitle",problem:"is only allowed for ticket reviews",received:i.subtitle}),t==="inline"&&i.output_path!==void 0&&e.push({field:"output_path",problem:"is only allowed for ticket reviews",received:i.output_path}),(e.length>0||t===void 0||r===void 0||!f(r)||s===void 0||u===void 0||u.length>128)&&a(e),{origin_kind:t,origin_node_id:r,file:s,idempotency_key:u,...m===void 0?{}:{subtitle:m},...b===void 0?{}:{output_path:b}}}d(P,"parseCreate");function j(n){const e=[],i={},o=new Set(["state","origin_node_id","file"]);for(const[t,r]of n.query.entries())o.has(t)||e.push({field:t,problem:"is not allowed",received:r});for(const t of o){const r=n.query.getAll(t);if(r.length>1){e.push({field:t,problem:"must appear at most once",received:r});continue}const s=r[0];s!==void 0&&(t==="state"?A.has(s)?i.state=s:e.push({field:t,problem:"must be open, approved, or canceled",received:s}):t==="origin_node_id"?f(s)?i.origin_node_id=s:e.push({field:t,problem:"must be a safe node id",received:s}):s===""?e.push({field:t,problem:"must be a non-empty string",received:s}):i.file=s)}return e.length>0&&a(e),i}d(j,"parseList");function B(n,e){const i=n.body===void 0?{}:v(n.body,L,e),o=l(i,"reason",e),t=l(i,"actor",e),r=l(i,"disposition",e);return r!==void 0&&r!=="canceled"&&r!=="dismissed"&&e.push({field:"disposition",problem:'must be "canceled" or "dismissed"',received:r}),{...o===void 0?{}:{reason:o},...t===void 0?{}:{actor:t},...r==="canceled"||r==="dismissed"?{disposition:r}:{}}}d(B,"parseCancel");function F(n,e){v(n.body,[],e)}d(F,"requireEmptyBody");async function G(n){const e=P(n),i=y(e.origin_node_id);i!==null&&g(i,"ask");const o=await k(e);return{status:200,body:c(o)}}d(G,"handleCreate");function N(n){const e=j(n);return{status:200,body:{reviews:q(e).map(c)}}}d(N,"handleList");function V(n){const e=[],i=p(n,e);return(e.length>0||i===void 0)&&a(e),{status:200,body:c(w(i))}}d(V,"handleRead");async function $(n){const e=[],i=p(n,e);F(n,e),(e.length>0||i===void 0)&&a(e);const o=await E(i);return{status:200,body:o.outcome==="awaiting_companion"?{review:c(o.record),outcome:o.outcome}:{review:c(o.record),result:T(o.result),outcome:o.outcome}}}d($,"handleSubmit");async function K(n){const e=[],i=p(n,e),o=B(n,e);(e.length>0||i===void 0)&&a(e);const t=await S(i,o);return{status:200,body:{review:c(t.record),outcome:t.outcome}}}d(K,"handleCancel");function W(n){const e=[],i=p(n,e);(e.length>0||i===void 0)&&a(e);const o=w(i),t=R(o.review_id);if(t===null)throw new Error(`review anchor base is missing: ${o.review_id}`);return{status:200,body:{review_id:o.review_id,anchor_base_sha256:t.sha256,anchor_base_text:new TextDecoder("utf-8",{fatal:!0}).decode(t.bytes),file:o.file}}}d(W,"handleDocument");const x=[{method:"POST",pattern:"/v1/human/reviews",scope:"ask",handler:G},{method:"GET",pattern:"/v1/human/reviews",handler:N},{method:"GET",pattern:"/v1/human/reviews/:review_id",handler:V},{method:"POST",pattern:"/v1/human/reviews/:review_id/submit",handler:$},{method:"POST",pattern:"/v1/human/reviews/:review_id/cancel",handler:K},{method:"GET",pattern:"/v1/human/reviews/:review_id/document",handler:W}];export{x as reviewRoutes};
1
+ var y=Object.defineProperty;var d=(i,e)=>y(i,"name",{value:e,configurable:!0});import{isSafeNodeId as f}from"../../../core/canvas/paths.js";import{getNode as w}from"../../../core/canvas/canvas.js";import{assertScope as g}from"../../../core/scopes.js";import{createReview as R}from"../../../core/review/birth.js";import{readAnchorBase as k,listReviews as q,requireVisibleReview as _}from"../../../core/review/store.js";import{cancelReview as S,submitReviewApproval as E}from"../../review/finish.js";import{toFeedbackResultDTO as T,toReviewDTO as I}from"../map.js";import{canReadNode as C}from"../router.js";import{invalidRequest as D,objectBody as v,optionalString as l,requireParam as A,requiredString as h}from"./validate.js";const O=new Set(["open","approved","canceled"]),L=["origin_kind","origin_node_id","file","idempotency_key","subtitle","output_path"],N=["reason","actor","disposition"];function a(i){D("review request",i)}d(a,"invalidRequest");function p(i,e){return A(i,"review_id","must be a safe review id",f,e)}d(p,"requireReviewId");function c(i){return{...I(i,i.state==="approved"?{result_path:`${i.review_dir}/result.json`}:{}),review_dir:i.review_dir}}d(c,"toReviewResponseDTO");function P(i){const e=[],n=v(i.body,L,e),o=n.origin_kind,t=o==="ticket"||o==="inline"?o:void 0;t===void 0&&e.push({field:"origin_kind",problem:"must be ticket or inline",...o===void 0?{}:{received:o}});const r=h(n,"origin_node_id",e);r!==void 0&&!f(r)&&e.push({field:"origin_node_id",problem:"must be a safe node id",received:r});const s=h(n,"file",e),u=h(n,"idempotency_key",e);u!==void 0&&u.length>128&&e.push({field:"idempotency_key",problem:"must be at most 128 characters",received:u});const m=l(n,"subtitle",e),b=l(n,"output_path",e);return t==="ticket"&&m===void 0&&n.subtitle===void 0&&e.push({field:"subtitle",problem:"is required for ticket reviews"}),t==="inline"&&n.subtitle!==void 0&&e.push({field:"subtitle",problem:"is only allowed for ticket reviews",received:n.subtitle}),t==="inline"&&n.output_path!==void 0&&e.push({field:"output_path",problem:"is only allowed for ticket reviews",received:n.output_path}),(e.length>0||t===void 0||r===void 0||!f(r)||s===void 0||u===void 0||u.length>128)&&a(e),{origin_kind:t,origin_node_id:r,file:s,idempotency_key:u,...m===void 0?{}:{subtitle:m},...b===void 0?{}:{output_path:b}}}d(P,"parseCreate");function j(i){const e=[],n={},o=new Set(["state","origin_node_id","file"]);for(const[t,r]of i.query.entries())o.has(t)||e.push({field:t,problem:"is not allowed",received:r});for(const t of o){const r=i.query.getAll(t);if(r.length>1){e.push({field:t,problem:"must appear at most once",received:r});continue}const s=r[0];s!==void 0&&(t==="state"?O.has(s)?n.state=s:e.push({field:t,problem:"must be open, approved, or canceled",received:s}):t==="origin_node_id"?f(s)?n.origin_node_id=s:e.push({field:t,problem:"must be a safe node id",received:s}):s===""?e.push({field:t,problem:"must be a non-empty string",received:s}):n.file=s)}return e.length>0&&a(e),n}d(j,"parseList");function B(i,e){const n=i.body===void 0?{}:v(i.body,N,e),o=l(n,"reason",e),t=l(n,"actor",e),r=l(n,"disposition",e);return r!==void 0&&r!=="canceled"&&r!=="dismissed"&&e.push({field:"disposition",problem:'must be "canceled" or "dismissed"',received:r}),{...o===void 0?{}:{reason:o},...t===void 0?{}:{actor:t},...r==="canceled"||r==="dismissed"?{disposition:r}:{}}}d(B,"parseCancel");function F(i,e){v(i.body,[],e)}d(F,"requireEmptyBody");async function G(i){const e=P(i),n=w(e.origin_node_id);n!==null&&g(n,"crtr:act");const o=await R(e);return{status:200,body:c(o)}}d(G,"handleCreate");function V(i){const e=j(i);return{status:200,body:{reviews:q(e).filter(o=>{if(i.principal.class==="person")return!0;const t=w(o.origin_node_id);return t!==null&&C(i.principal,t.grantee??"app:terminal")}).map(c)}}}d(V,"handleList");function $(i){const e=[],n=p(i,e);return(e.length>0||n===void 0)&&a(e),{status:200,body:c(_(n))}}d($,"handleRead");async function K(i){const e=[],n=p(i,e);F(i,e),(e.length>0||n===void 0)&&a(e);const o=await E(n);return{status:200,body:o.outcome==="awaiting_companion"?{review:c(o.record),outcome:o.outcome}:{review:c(o.record),result:T(o.result),outcome:o.outcome}}}d(K,"handleSubmit");async function W(i){const e=[],n=p(i,e),o=B(i,e);(e.length>0||n===void 0)&&a(e);const t=await S(n,o);return{status:200,body:{review:c(t.record),outcome:t.outcome}}}d(W,"handleCancel");function z(i){const e=[],n=p(i,e);(e.length>0||n===void 0)&&a(e);const o=_(n),t=k(o.review_id);if(t===null)throw new Error(`review anchor base is missing: ${o.review_id}`);return{status:200,body:{review_id:o.review_id,anchor_base_sha256:t.sha256,anchor_base_text:new TextDecoder("utf-8",{fatal:!0}).decode(t.bytes),file:o.file}}}d(z,"handleDocument");const ie=[{method:"POST",pattern:"/v1/human/reviews",scope:"crtr:act",handler:G},{method:"GET",pattern:"/v1/human/reviews",handler:V},{method:"GET",pattern:"/v1/human/reviews/:review_id",handler:$},{method:"POST",pattern:"/v1/human/reviews/:review_id/submit",handler:K},{method:"POST",pattern:"/v1/human/reviews/:review_id/cancel",handler:W},{method:"GET",pattern:"/v1/human/reviews/:review_id/document",handler:z}];export{ie as reviewRoutes};
@@ -0,0 +1,2 @@
1
+ import type { RouteTable } from '../router.js';
2
+ export declare const runRoutes: RouteTable;
@@ -0,0 +1 @@
1
+ var a=Object.defineProperty;var t=(e,r)=>a(e,"name",{value:r,configurable:!0});import{randomUUID as s}from"node:crypto";import{cursor as m,streamRunEvents as i}from"../app-listener.js";import{handleRunOperation as o}from"./runs.js";import{OPERATIONS as d}from"../operations.js";const y=d.filter(e=>["run.list","run.get","run.events","trace.get","run.message","run.interrupt","run.cancel","run.delete"].includes(e.name)).map(e=>({method:e.method,pattern:e.path,handler:t(async r=>{const n=r.params.run_id;if(e.name==="run.events"){const u=m(r.req,r.query);return await i(r.req,r.res,n,r.principal,u,s(),"ndjson"),{status:200}}return o(e,r.principal,n,r.query,r.body,void 0)},"handler")}));export{y as runRoutes};
@@ -0,0 +1,9 @@
1
+ import type { AppPrincipal } from '../principal.js';
2
+ import { type RequestPrincipal } from '../router.js';
3
+ import type { AppOperation } from '../operations.js';
4
+ declare function integer(value: string | null, param: string, min: number, max: number, fallback: number): number;
5
+ export { integer };
6
+ export declare function handleRunOperation(operation: AppOperation, principal: AppPrincipal | RequestPrincipal, id: string | undefined, query: URLSearchParams, body: unknown, key: string | undefined): Promise<{
7
+ status: number;
8
+ body: unknown;
9
+ }>;
@@ -0,0 +1 @@
1
+ var h=Object.defineProperty;var w=(r,t)=>h(r,"name",{value:t,configurable:!0});import{RunError as n,cancelRun as g,deleteRun as b,interruptRun as v,listRuns as k,messageRun as y,requestedScopes as q,startRun as R,traceRun as N,waitRun as $}from"../../../core/runs/operations.js";import{canReadRun as x,requireRun as f,runCallerApp as S}from"../router.js";function l(r){if(!r||typeof r!="object"||Array.isArray(r))throw new n(400,"invalid_request","a JSON object is required");return r}w(l,"object");function c(r,t,s,i,u){if(r===null)return u;if(!/^(0|[1-9]\d*)$/.test(r)||!Number.isSafeInteger(Number(r))||Number(r)<s||Number(r)>i)throw new n(400,"invalid_request",`invalid ${t}`,t);return Number(r)}w(c,"integer");async function z(r,t,s,i,u,p){switch(r.name){case"grant.get":{if("class"in t)throw new n(403,"permission_error","an app token is required");return{status:200,body:{sub:t.sub,grantee:t.grantee,client_id:t.client_id,grant:t.grant,rev:t.rev,resolved_scopes:t.resolved_scopes,spend_cap:t.spend_cap,exp:t.exp,payer:"user"}}}case"run.start":{if("class"in t)throw new n(403,"permission_error","an app token is required");const e=l(u),o=["mode","parent","fork_from","node_id","env","tools","system_prompt"];for(const a of o)if(e[a]!==void 0)throw new n(403,"owner_only",`${a} is owner-only`,a);const d=["payer","model","model_policy","output_schema","deadline","cwd","worktree","kind"];for(const a of d)if(e[a]!==void 0)throw new n(400,"invalid_request",`${a} is not available`,a);for(const a of Object.keys(e))if(!["prompt","scopes","metadata","profile"].includes(a))throw new n(400,"invalid_request",`unknown field ${a}`,a);if(e.profile!==void 0&&(typeof e.profile!="string"||!e.profile))throw new n(400,"invalid_request","profile must be a profile id","profile");if(typeof e.prompt!="string"||!e.prompt.trim())throw new n(400,"invalid_request","prompt is required","prompt");const m=e.metadata===void 0?{}:l(e.metadata);if(Buffer.byteLength(JSON.stringify(m))>4096)throw new n(400,"invalid_request","metadata exceeds 4 KB","metadata");const _=q(t.resolved,e.scopes,t.grantee);return{status:201,body:await R(t,{prompt:e.prompt,scopes:_,metadata:m,profile:e.profile},p)}}case"run.list":{const e=i.get("status")??void 0;if(e&&!["running","waiting_on_user","idle","settled"].includes(e))throw new n(400,"invalid_request","invalid status","status");const o=i.get("app");if(o!==null&&!/^(?:app:)?[a-z0-9][a-z0-9-]*$/.test(o))throw new n(400,"invalid_request","invalid app","app");const d=o===null?S(t):o.startsWith("app:")?o:`app:${o}`;if(d!==null&&!x(t,d))throw new n(404,"not_found","run not found");return{status:200,body:k(d,{status:e,after:i.get("after")??void 0,limit:c(i.get("limit"),"limit",1,100,50)})}}case"run.get":{const e=i.has("wait")?c(i.get("wait"),"wait",1,25,0):0,o=f(t,s),d=await $(s,o.grantee,e);return f(t,s),{status:200,body:d}}case"run.message":{const e=l(u);if(typeof e.message!="string"||!e.message.trim())throw new n(400,"invalid_request","message is required","message");return{status:202,body:await y(f(t,s,!0),e.message)}}case"run.interrupt":{const e=l(u===void 0?{}:u);if(e.children!==void 0&&e.children!=="stop"&&e.children!=="continue")throw new n(400,"invalid_request","invalid children","children");return{status:200,body:await v(f(t,s,!0),e.children)}}case"run.cancel":{const e=l(u===void 0?{}:u);if(e.keep_schedules!==void 0&&typeof e.keep_schedules!="boolean")throw new n(400,"invalid_request","invalid keep_schedules","keep_schedules");return{status:200,body:await g(f(t,s,!0),{keepSchedules:e.keep_schedules})}}case"run.delete":return await b(f(t,s,!0,!0)),{status:200,body:{run_id:s,deleted:!0}};case"trace.get":{const e=i.get("format")??void 0;if(e&&e!=="entries")throw new n(400,"invalid_request","unknown trace format","format");const o=f(t,s);return{status:200,body:N(s,o.grantee,e)}}default:throw new n(404,"not_found","unknown operation")}}w(z,"handleRunOperation");export{z as handleRunOperation,c as integer};
@@ -1 +1 @@
1
- var c=Object.defineProperty;var o=(t,e)=>c(t,"name",{value:e,configurable:!0});import{ApiError as s}from"../../../api/index.js";import{getNode as b,subscribe as p,subscriptionsOf as f,unsubscribe as h}from"../../../core/canvas/canvas.js";import{toSubscriptionDTO as m}from"../map.js";function i(t){if(b(t)===null)throw new s(404,"node_not_found",`unknown node: ${t}`)}o(i,"requireNode");function g(t){const e=t.params.id,r=t.body??{},n=r.target;if(typeof n!="string"||n==="")throw new s(400,"invalid_request","subscribe body requires a `target` node id");if(n===e)throw new s(422,"unprocessable","a node cannot subscribe to itself");i(e),i(n);const a=r.active??!0;p(e,n,a);const d=f(e).find(u=>u.node_id===n);if(d===void 0)throw new s(500,"internal","subscription edge vanished after write");return{status:200,body:m(d)}}o(g,"handleSubscribe");function l(t){const e=t.params.id,r=t.params.target;return i(e),h(e,r),{status:204}}o(l,"handleUnsubscribe");const E=[{method:"POST",pattern:"/v1/nodes/:id/subscriptions",handler:g},{method:"DELETE",pattern:"/v1/nodes/:id/subscriptions/:target",handler:l}];export{E as subscriptionRoutes};
1
+ var l=Object.defineProperty;var p=(n,i)=>l(n,"name",{value:i,configurable:!0});import{ApiError as e}from"../../../api/index.js";import{getNode as a,subscribe as b,subscriptionsOf as f,unsubscribe as h}from"../../../core/canvas/canvas.js";import{toSubscriptionDTO as g}from"../map.js";function u(n){if(a(n)===null)throw new e(404,"node_not_found",`unknown node: ${n}`)}p(u,"requireNode");function w(n){const i=n.params.id,t=n.body??{},r=t.target;if(typeof r!="string"||r==="")throw new e(400,"invalid_request","subscribe body requires a `target` node id");if(r===i)throw new e(422,"unprocessable","a node cannot subscribe to itself");if(u(i),u(r),n.principal.class==="broker"){const o=a(i),c=a(r);if(o.grantee!==n.principal.app||c.grantee!==n.principal.app||o.run_id!==c.run_id||n.principal.run!==null&&o.run_id!==n.principal.run)throw new e(403,"other_app_run","subscriptions must stay within the calling app run")}const s=t.active??!0;b(i,r,s);const d=f(i).find(o=>o.node_id===r);if(d===void 0)throw new e(500,"internal","subscription edge vanished after write");return{status:200,body:g(d)}}p(w,"handleSubscribe");function _(n){const i=n.params.id,t=n.params.target;if(u(i),n.principal.class==="broker"){const r=a(i),s=a(t);if(r.grantee!==n.principal.app||n.principal.run!==null&&r.run_id!==n.principal.run||s&&(s.grantee!==r.grantee||s.run_id!==r.run_id))throw new e(403,"other_app_run","subscriptions must stay within the calling app run")}return h(i,t),{status:204}}p(_,"handleUnsubscribe");const E=[{method:"POST",pattern:"/v1/nodes/:id/subscriptions",handler:w},{method:"DELETE",pattern:"/v1/nodes/:id/subscriptions/:target",handler:_}];export{E as subscriptionRoutes};
@@ -1 +1 @@
1
- var o=Object.defineProperty;var t=(e,n)=>o(e,"name",{value:n,configurable:!0});import{closeManagedWorktreeAsync as a}from"../../../core/worktree-close.js";import{abandonManagedWorktreeAsync as d}from"../../../core/worktree-mutation-async.js";import{listQuarantinedManagedWorktrees as i}from"../../../core/worktree-quarantine.js";import{usage as s}from"../../../core/errors.js";import{ownerOnly as m}from"../router.js";async function y(e){const n=e.params.id;return{status:200,body:await a(n)}}t(y,"handleWorktreeClose");async function u(e){const n=e.body?.by,r=typeof n=="string"?n.trim():"";if(r==="")throw s("abandon requires a non-empty invoking identity",{received:e.body,next:"Pass the invoking node id or human identity."});return{status:200,body:await d(e.params.id,r)}}t(u,"handleWorktreeAbandon");async function c(){return{status:200,body:await i()}}t(c,"handleQuarantinedWorktrees");const w=m([{method:"POST",pattern:"/v1/nodes/:id/worktree/close",handler:y},{method:"POST",pattern:"/v1/nodes/:id/worktree/abandon",handler:u},{method:"GET",pattern:"/v1/worktrees/quarantined",handler:c}]);export{w as worktreeRoutes};
1
+ var s=Object.defineProperty;var a=(e,r)=>s(e,"name",{value:r,configurable:!0});import{closeManagedWorktreeAsync as i}from"../../../core/worktree-close.js";import{abandonManagedWorktreeAsync as d}from"../../../core/worktree-mutation-async.js";import{listQuarantinedManagedWorktrees as p}from"../../../core/worktree-quarantine.js";import{usage as m}from"../../../core/errors.js";import{directorySizeBytes as c}from"../../../core/disk-usage.js";import{appsRoot as n,userRoot as y}from"../../../core/layout.js";import{existsSync as u,readdirSync as h}from"node:fs";import{join as l}from"node:path";import{ownerOnly as f}from"../router.js";async function b(e){const r=e.params.id;return{status:200,body:await i(r)}}a(b,"handleWorktreeClose");async function w(e){const r=e.body?.by,o=typeof r=="string"?r.trim():"";if(o==="")throw m("abandon requires a non-empty invoking identity",{received:e.body,next:"Pass the invoking node id or human identity."});return{status:200,body:await d(e.params.id,o)}}a(w,"handleWorktreeAbandon");async function k(){return{status:200,body:await p()}}a(k,"handleQuarantinedWorktrees");async function g(){const e=u(n())?h(n(),{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>t.name).sort():[],r=[{space:"user",path:y()},...e.map(t=>({space:`app:${t}`,path:l(n(),t)}))];return{status:200,body:{spaces:await Promise.all(r.map(async t=>({...t,size_bytes:await c(t.path)})))}}}a(g,"handleSpaces");const z=f([{method:"GET",pattern:"/v1/spaces",handler:g},{method:"POST",pattern:"/v1/nodes/:id/worktree/close",handler:b},{method:"POST",pattern:"/v1/nodes/:id/worktree/abandon",handler:w},{method:"GET",pattern:"/v1/worktrees/quarantined",handler:k}]);export{z as worktreeRoutes};
@@ -15,7 +15,13 @@ export declare function toMigrateStateDTO(result: OnDiskMigrationRunResult, opti
15
15
  /** Project the list-row outcome, or null while this node remains unsettled. */
16
16
  export declare function toNodeOutcomeSummaryDTO(node: NodeRuntime): NodeOutcomeSummaryDTO | null;
17
17
  /** Project the full outcome, or null while this node remains unsettled. */
18
- export declare function toNodeOutcomeDTO(node: Pick<NodeMeta, 'node_id' | 'final_report'> & NodeRuntime): NodeOutcomeDTO | null;
18
+ export declare function toNodeOutcomeDTO(node: Pick<NodeMeta, 'node_id' | 'final_report' | 'grantee'> & NodeRuntime): NodeOutcomeDTO | null;
19
+ export declare function toRunOutcomeDTO(node: Pick<NodeMeta, 'node_id' | 'final_report'> & NodeRuntime): (Omit<NodeOutcomeDTO, 'reason'> & {
20
+ reason: string;
21
+ details?: {
22
+ crouter_reason: string;
23
+ };
24
+ }) | null;
19
25
  /** The outcome-delivery fields exposed by the API. The delivery store supplies this projection directly. */
20
26
  export interface OutcomeDeliveryDTOInput {
21
27
  nodeId: string;
@@ -65,9 +71,9 @@ export interface NodeEdgesInput {
65
71
  }
66
72
  /** Project a node's spine + subscription edges (absorbs `managers`/`paths`). */
67
73
  export declare function toNodeEdgesDTO(meta: NodeMeta, edges: NodeEdgesInput): NodeEdgesDTO;
68
- /** Absolute filesystem paths for a node (absorbs the `paths` read). Pure — the
69
- * `core/canvas/paths.ts` helpers are string constructors, not db reach. */
70
- export declare function toNodePathsDTO(nodeId: string): NodePathsDTO;
74
+ /** Absolute filesystem paths for a node (absorbs the `paths` read).
75
+ * App assignment comes from the authoritative node row. */
76
+ export declare function toNodePathsDTO(nodeId: string, grantee: string): NodePathsDTO;
71
77
  /** Project a node's managed git worktree, if any. */
72
78
  export declare function toNodeWorktreeDTO(w: ManagedWorktree): NodeWorktreeDTO;
73
79
  /** Project the hydrated node view (`getNode` → `NodeMeta`) into a detail DTO.
@@ -1,2 +1,2 @@
1
- var m=Object.defineProperty;var o=(e,t)=>m(e,"name",{value:t,configurable:!0});import{existsSync as h,readFileSync as v}from"node:fs";import{join as g}from"node:path";import{outputResultPath as y}from"../../core/runtime/structured-output.js";import{ReviewOperationError as l}from"../../core/review/types.js";import{cronSinkDisplay as k}from"../../core/canvas/crons.js";import{isProfilePaused as u,sanitizeProfileMetadata as b}from"../../core/profiles/manifest.js";import{contextDir as x,nodeDir as O,nodeMetaPath as D,reportsDir as c,transcriptPath as S,viewSocketPath as T}from"../../core/canvas/paths.js";import{FinalizationError as R}from"../../core/feed/feed.js";import{NodeIdConflictError as E}from"../../core/runtime/nodes.js";import{ScopeDeniedError as A}from"../../core/scopes.js";import{CrtrError as s}from"../../core/errors.js";import{WorktreeError as N}from"../../core/worktree.js";import{ApiError as z}from"../../api/errors.js";import{ExitCode as d}from"../../types.js";function se(e,t){const{discovery:i,snapshots:r}=e;return{profiles:e.profiles,stores:i.stores.length,changed:e.changed,applied:e.applied,skipped:e.skipped,blockers:e.blockers.map(n=>({kind:n.kind,message:n.message,...n.storeRoot===void 0?{}:{store:n.storeRoot},...n.targetId===void 0?{}:{target:n.targetId},...n.path===void 0?{}:{path:n.path},...n.name===void 0?{}:{name:n.name},...n.paths===void 0?{}:{paths:n.paths}})),discovery_roots:i.roots.map(n=>({reason:n.reason,root:n.root,boundary:n.boundary,...n.detail===void 0?{}:{detail:n.detail}})),discovered_stores:i.stores.map(n=>({store:n.key,scope:n.descriptor.scope,namespace:n.descriptor.namespace,mount_status:n.descriptor.mountStatus,writable:n.writable,reasons:[...new Set(n.discovery.map(a=>a.reason))],targets:n.targets,docs:r.get(n.key)?.docs.length??0})),discovered_targets:i.targets.map(n=>({id:n.id,kind:n.kind,origin:n.origin,cwd:n.target.cwd,profile_id:n.target.profileId,node_id:n.target.nodeId,stores:n.storeKeys})),repository_namespaces:e.repositories.map(n=>({repository_root:n.repositoryRoot,repository_key:n.repositoryKey,declaration_path:n.declarationPath,namespace:n.namespace,source:n.source,action:n.action})),store_prefixes:e.storePrefixes.map(n=>({store_root:n.storeRoot,owner_dir:n.ownerDir,repository_root:n.repositoryRoot,owner_relative_path:n.ownerRelativePath,old_prefix:n.oldPrefix,old_rule:n.oldRule,effective_prefix:n.effectivePrefix,nested_declaration_action:n.nestedDeclarationAction,front_door_action:n.frontDoorAction})),renames:e.renames.map(n=>({store_root:n.storeRoot,path:n.path,from:n.from,to:n.to})),references:e.references.map(n=>({store_root:n.storeRoot,path:n.path,kind:n.kind,from:n.from,to:n.to})),dryRun:e.dryRun,blocked:e.blocked,corpus_phase:e.corpusPhase,wrote:{profile_manifests:e.wrote.profileManifests,documents:e.wrote.documents,corpus_consumers:e.wrote.corpusConsumers,corpus_identities:e.wrote.corpusIdentities},resumed:t.resumed,...t.resumeError===void 0?{}:{resume_error:t.resumeError}}}o(se,"toMigrateStateDTO");function P(e){const t=y(e);try{return h(t)?JSON.parse(v(t,"utf8")):null}catch{return null}}o(P,"readStructuredResult");function C(e){return e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0?null:{kind:e.outcome_kind,reason:e.outcome_reason,settled_at:e.outcome_at}}o(C,"toNodeOutcomeSummaryDTO");function j(e){if(e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0)return null;let t=null;if(e.outcome_detail_json!==null&&e.outcome_detail_json!==void 0)try{t=JSON.parse(e.outcome_detail_json)}catch{t=null}const i=e.final_report??null,r={node_id:e.node_id,revision:e.outcome_revision??1,settled_at:e.outcome_at,final_report:i,final_report_path:i===null?null:`${c(e.node_id)}/${i}`,structured_result:e.outcome_kind==="result"?P(e.node_id):null,detail:t};return e.outcome_kind==="result"?{...r,kind:"result",reason:e.outcome_reason,declined:null}:e.outcome_reason==="declined"?{...r,kind:"failure",reason:"declined",declined:t?.declined??null}:{...r,kind:"failure",reason:e.outcome_reason,declined:null}}o(j,"toNodeOutcomeDTO");function _e(e){const t=e.lastFailure;return{node_id:e.nodeId,state:e.state,action:e.actionName,attempt:e.attempt,next_attempt_at:e.nextAttemptAt===0?null:new Date(e.nextAttemptAt).toISOString(),accepted_at:e.acceptedAt===null?null:new Date(e.acceptedAt).toISOString(),permanent_failed_at:e.permanentFailedAt===null?null:new Date(e.permanentFailedAt).toISOString(),last_failure:t===null?null:{kind:t.kind,...t.exitCode===void 0?{}:{exit_code:t.exitCode},...t.signal===void 0?{}:{signal:t.signal},...t.message===void 0?{}:{message:t.message}},created_at:new Date(e.createdAt).toISOString(),updated_at:new Date(e.updatedAt).toISOString()}}o(_e,"toOutcomeDeliveryDTO");function le(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,status:e.status,frozen_at:e.frozen_at,pi_pid:e.pi_pid,telemetry_context_tokens:e.telemetry_context_tokens,telemetry_last_activity:e.telemetry_last_activity,fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming}}o(le,"toGraphNodeDTO");function ue(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind,profile_id:e.profile_id,scopes:e.scopes,profile_paused:u(e.profile_id),parent:e.parent,created:e.created,intent:e.intent,waiting_for:e.waiting_for,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid,pi_pid_identity:e.pi_pid_identity,window:e.window,tmux_session:e.tmux_session,pane:e.pane,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,outcome:C(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1}}o(ue,"toNodeSummaryDTO");function I(e,t){return{parent:e.parent??null,spawned_by:e.spawned_by??null,subscribes_to:t.subscribesTo.map(i=>i.node_id),subscribers:t.subscribers.map(i=>i.node_id),children:[...t.children]}}o(I,"toNodeEdgesDTO");function q(e){return{node_dir:O(e),context_dir:x(e),reports_dir:c(e),meta_path:D(e),transcript_path:S(e),view_socket:T(e)}}o(q,"toNodePathsDTO");function F(e){const t={state:e.state,path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created};return e.cleanup!==void 0&&(t.cleanup=e.cleanup),e.closed!==void 0&&(t.closed=e.closed),e.abandoned!==void 0&&(t.abandoned={...e.abandoned}),t}o(F,"toNodeWorktreeDTO");function ce(e,t){const i={node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes??null,profile_paused:u(e.profile_id),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,outcome:j(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1,creator:e.creator??null,edges:I(e,t),paths:q(e.node_id)};return e.description!==void 0&&(i.description=e.description),e.title!==void 0&&(i.title=e.title),e.icon!==void 0&&(i.icon=e.icon),e.cycles!==void 0&&(i.cycles=e.cycles),i.context_tokens=e.telemetry_context_tokens??e.telemetry_tokens_in??null,e.pi_session_id!==void 0&&(i.pi_session_id=e.pi_session_id??null),i.model_override=e.model_override??null,e.pi_session_file!==void 0&&(i.pi_session_file=e.pi_session_file??null),e.review_binding!==void 0&&(i.review_binding=e.review_binding===null?null:{...e.review_binding.kind===void 0?{}:{kind:e.review_binding.kind},review_id:e.review_binding.review_id,origin_node_id:e.review_binding.origin_node_id,branch_file:e.review_binding.branch_file,target_file:e.review_binding.target_file}),e.managed_worktree!=null&&(i.worktree=F(e.managed_worktree)),i}o(ce,"toNodeDetailDTO");function pe(e,t,i){return{node_id:e,revived:t.launch!==void 0,resumed:t.resumed,status:i,outcome:t.outcome}}o(pe,"toReviveResultDTO");function fe(e){return{root:e.root,closed:[...e.closed],spared:[...e.spared]}}o(fe,"toCloseResultDTO");function me(e,t,i){const r={report_path:e.reportPath,notified:[...e.deliveredTo]};return t!==void 0&&(r.transitioned=t),i!==void 0&&(r.worktree_auto_dropped=!0,r.worktree_auto_dropped_path=i),r}o(me,"toReportResultDTO");function he(e){return{node_id:e.node_id,active:e.active,created:e.created}}o(he,"toSubscriptionDTO");function M(e){if(e===null||e==="")return[];try{const t=JSON.parse(e);return typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t):[]}catch{return[]}}o(M,"envKeys");function ve(e,t){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by,command:e.command,fire_at:e.fire_at,recur:e.recur,tz:e.tz,expires_at:e.expires_at,anchor_node:e.anchor_node,cancel_on_wake:e.cancel_on_wake,cwd:e.cwd,profile:e.profile,scope:e.scope,env_keys:M(e.env_json),run_timeout_s:e.run_timeout_s,overlap:e.overlap,on_output:e.on_output,sink:k(e.sink),tier:e.tier,state:e.state,held:e.held,run_state:e.run_state,last_run:t==null?null:{finished:t.finished,exit_code:t.exit_code,delivered:t.delivered},created:e.created,updated:e.updated}}o(ve,"toCronDTO");function ge(e){return{run_id:e.run_id,started:e.started,finished:e.finished,duration_ms:e.duration_ms,exit_code:e.exit_code,stdout_head:e.stdout_head,stderr_head:e.stderr_head,delivered:e.delivered}}o(ge,"toCronRunDTO");function ye(e){return{id:e.profileId,name:e.manifest.name,projects:e.manifest.projects.map(t=>({...t})),home:e.manifest.home,paused_at:e.manifest.paused_at,default_kind:e.manifest.default_kind??"general",metadata:b(e.manifest.metadata),default_dir:null}}o(ye,"toProfileDTO");function p(e,t={}){const i={review_id:e.review_id,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,review_dir:e.review_dir,companion_node_id:e.companion_node_id,file:e.file,state:e.state,created:e.created,source_missing:e.source_missing,anchor_base_sha256:e.anchor_base_sha256};return e.opened_at!==null&&(i.opened_at=e.opened_at),e.submit_requested_at!==null&&(i.submit_requested_at=e.submit_requested_at),e.approved_at!==null&&(i.approved_at=e.approved_at),e.changed!==null&&(i.changed=e.changed),e.comments_total!==null&&(i.comments_total=e.comments_total),e.comments_unresolved!==null&&(i.comments_unresolved=e.comments_unresolved),e.canceled_at!==null&&(i.canceled_at=e.canceled_at),e.cancel_reason!==null&&(i.cancel_reason=e.cancel_reason),e.cancel_actor!==null&&(i.cancel_actor=e.cancel_actor),t.result_path!==void 0&&(i.result_path=t.result_path),e.delivery_error!==null&&(i.delivery_error=e.delivery_error),e.projection_error!==null&&(i.projection_error=e.projection_error),i}o(p,"toReviewDTO");function ke(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{...e.anchor},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author.kind,...e.author.node_id===null?{}:{node_id:e.author.node_id}},updated_by:{kind:e.updated_by.kind,...e.updated_by.node_id===null?{}:{node_id:e.updated_by.node_id}},created_at:e.created_at,updated_at:e.updated_at,...e.resolved_at===null?{}:{resolved_at:e.resolved_at},...e.deleted_at===null?{}:{deleted_at:e.deleted_at},created_seq:e.created_seq}}o(ke,"toReviewCommentDTO");function U(e){return{id:e.id,quote:e.quote,...e.context===void 0?{}:{context:e.context},note:e.note,status:e.status,created_at:e.createdAt,...e.resolvedAt===void 0?{}:{resolved_at:e.resolvedAt}}}o(U,"toPageFeedbackCommentDTO");function be(e){return{companion_node_id:e.companionNodeId??null,open_count:e.comments.filter(t=>t.status==="open").length,comments:e.comments.map(U)}}o(be,"toPageFeedbackDTO");function xe(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===1,revision_after:e.revision_after,actor:{kind:e.actor.kind,...e.actor.node_id===null?{}:{node_id:e.actor.node_id}},at:e.at,operation_id:e.operation_id,...e.payload===void 0?{}:{payload:e.payload}}}o(xe,"toReviewCommentEventDTO");function Oe(e){return{file:e.file,submitted:e.submitted,approved:e.approved,comments:e.comments.map(i=>({...i})),submittedAt:e.submittedAt,savedAt:e.savedAt,reviewId:e.review_id,changed:e.changed,baselineSha256:e.baseline_sha256,approvedSha256:e.approved_sha256,companionNodeId:e.companion_node_id,commentsTotal:e.comments_total,commentsUnresolved:e.comments_unresolved}}o(Oe,"toFeedbackResultDTO");const G=!0,K=Object.freeze({review_origin_missing:{status:400,code:"review_origin_unavailable"},review_origin_unforkable:{status:400,code:"review_origin_unavailable"},review_origin_unstable:{status:409,code:"review_origin_unstable"},review_branch_unavailable:{status:409,code:"review_branch_unavailable"},branch_lost:{status:409,code:"review_branch_unavailable"},review_companion_unbound:{status:409,code:"review_companion_unbound"},review_bridge_unsubscribed:{status:409,code:"review_bridge_unavailable"},review_target_unreviewable:{status:400,code:"review_file_unreadable"},source_unreadable:{status:409,code:"review_source_unreadable"},delivery_unroutable:{status:409,code:"review_delivery_unroutable"},unknown_review:{status:404,code:"unknown_review"},review_terminal:{status:409,code:"review_terminal_conflict"},review_required:{status:400,code:"review_required"},stale_document:{status:409,code:"stale_document"},unknown_comment:{status:404,code:"unknown_comment"},comment_deleted:{status:409,code:"comment_deleted"},invalid_anchor:{status:400,code:"invalid_anchor"},anchor_out_of_range:{status:400,code:"anchor_out_of_range"},text_too_long:{status:400,code:"text_too_long"},comment_limit_reached:{status:409,code:"comment_limit_reached"},stale_comment:{status:409,code:"stale_comment"},range_batch_incomplete:{status:409,code:"range_batch_incomplete"},range_batch_stale:{status:409,code:"range_batch_stale"}});function L(e){const t=f(e);if(typeof t=="object"&&t!==null&&typeof t.status=="number"&&typeof t.code=="string")return{status:t.status,code:t.code};if(t instanceof R)return t.code==="unknown_node"?{status:404,code:"node_not_found"}:t.code==="already_finalized"?{status:409,code:"already_finalized"}:{status:409,code:"finalization_forbidden"};if(t instanceof E)return{status:409,code:"node_id_exists"};if(t instanceof A)return{status:403,code:"scope_denied"};if(t instanceof l)return K[t.code];if(t instanceof s)return{status:B(t.exitCode),code:t.code};if(t instanceof Error){const i=t.message;if(/unknown node/i.test(i))return{status:404,code:"node_not_found"};if(/finalization latch/i.test(i))return{status:409,code:"already_finalized"};if(/illegal lifecycle transition/i.test(i))return{status:409,code:"illegal_transition"}}return{status:500,code:"internal"}}o(L,"errorToStatus");function f(e){if(!(e instanceof N))return e;const t=e.code==="unknown_node"?d.NOT_FOUND:d.GENERAL,i={error:e.code,message:e.message,next:e.next};return e.detail!==void 0&&(i.received=e.detail),new s(e.code,e.message,t,i)}o(f,"normalizeThrow");function W(e){if(e.code!=="review_terminal")return e.detail;const{review:t,...i}=e.detail;return{...i,review:$(t)}}o(W,"reviewErrorDetails");function $(e){return e.state!=="approved"?p(e):p(e,{result_path:g(e.review_dir,"result.json")})}o($,"terminalConflictReviewDTO");function B(e){switch(e){case d.NOT_FOUND:return 404;case d.USAGE:return 400;case d.AMBIGUOUS:return 400;case d.NETWORK:return 503;case d.GENERAL:return 400;default:return 500}}o(B,"statusForExitCode");function J(e){const i=(e instanceof Error?e.message:String(e)).split(`
2
- `,1)[0].trim();return i===""?"internal error":i.length>500?`${i.slice(0,497)}\u2026`:i}o(J,"boundedCause");function De(e){const t=f(e),{status:i,code:r}=L(t);if(i>=500)return{status:i,body:{error:{code:r,message:J(t)}}};const n=t instanceof Error?t.message:String(t),a=t instanceof l?W(t):(t instanceof s||t instanceof z)&&t.details!==void 0?t.details:void 0,_={error:{code:r,message:n}};return a!==void 0&&(_.error.details=a),{status:i,body:_}}o(De,"toErrorBody");export{K as REVIEW_ERROR_MAP,L as errorToStatus,fe as toCloseResultDTO,ve as toCronDTO,ge as toCronRunDTO,De as toErrorBody,Oe as toFeedbackResultDTO,le as toGraphNodeDTO,se as toMigrateStateDTO,ce as toNodeDetailDTO,I as toNodeEdgesDTO,j as toNodeOutcomeDTO,C as toNodeOutcomeSummaryDTO,q as toNodePathsDTO,ue as toNodeSummaryDTO,F as toNodeWorktreeDTO,_e as toOutcomeDeliveryDTO,U as toPageFeedbackCommentDTO,be as toPageFeedbackDTO,ye as toProfileDTO,me as toReportResultDTO,ke as toReviewCommentDTO,xe as toReviewCommentEventDTO,p as toReviewDTO,pe as toReviveResultDTO,he as toSubscriptionDTO};
1
+ var y=Object.defineProperty;var o=(e,t)=>y(e,"name",{value:t,configurable:!0});import{join as k}from"node:path";import{readOutputResult as b}from"../../core/runtime/structured-output.js";import{ReviewOperationError as c}from"../../core/review/types.js";import{cronSinkDisplay as x}from"../../core/canvas/crons.js";import{isProfilePaused as p,profileMemoryDir as O,sanitizeProfileMetadata as D}from"../../core/profiles/manifest.js";import{nodeMetaPath as R,transcriptPath as T,viewSocketPath as E}from"../../core/canvas/paths.js";import{appForNode as f,contextDir as S,nodeAgentDir as A,reportsDir as m}from"../../core/canvas/node-agent-paths.js";import{FinalizationError as z}from"../../core/feed/feed.js";import{NodeIdConflictError as N}from"../../core/runtime/nodes.js";import{ScopeDeniedError as C}from"../../core/scopes.js";import{isBeneathRefusal as P}from"../../core/spaces/open-beneath.js";import{CrtrError as l}from"../../core/errors.js";import{WorktreeError as j}from"../../core/worktree.js";import{ApiError as I}from"../../api/errors.js";import{RunError as u}from"../../core/runs/operations.js";import{ExitCode as a}from"../../types.js";function pe(e,t){const{discovery:i,snapshots:r}=e;return{profiles:e.profiles,stores:i.stores.length,changed:e.changed,applied:e.applied,skipped:e.skipped,blockers:e.blockers.map(n=>({kind:n.kind,message:n.message,...n.storeRoot===void 0?{}:{store:n.storeRoot},...n.targetId===void 0?{}:{target:n.targetId},...n.path===void 0?{}:{path:n.path},...n.name===void 0?{}:{name:n.name},...n.paths===void 0?{}:{paths:n.paths}})),discovery_roots:i.roots.map(n=>({reason:n.reason,root:n.root,boundary:n.boundary,...n.detail===void 0?{}:{detail:n.detail}})),discovered_stores:i.stores.map(n=>({store:n.key,scope:n.descriptor.scope,namespace:n.descriptor.namespace,mount_status:n.descriptor.mountStatus,writable:n.writable,reasons:[...new Set(n.discovery.map(s=>s.reason))],targets:n.targets,docs:r.get(n.key)?.docs.length??0})),discovered_targets:i.targets.map(n=>({id:n.id,kind:n.kind,origin:n.origin,cwd:n.target.cwd,profile_id:n.target.profileId,node_id:n.target.nodeId,stores:n.storeKeys})),repository_namespaces:e.repositories.map(n=>({repository_root:n.repositoryRoot,repository_key:n.repositoryKey,declaration_path:n.declarationPath,namespace:n.namespace,source:n.source,action:n.action})),store_prefixes:e.storePrefixes.map(n=>({store_root:n.storeRoot,owner_dir:n.ownerDir,repository_root:n.repositoryRoot,owner_relative_path:n.ownerRelativePath,old_prefix:n.oldPrefix,old_rule:n.oldRule,effective_prefix:n.effectivePrefix,nested_declaration_action:n.nestedDeclarationAction,front_door_action:n.frontDoorAction})),renames:e.renames.map(n=>({store_root:n.storeRoot,path:n.path,from:n.from,to:n.to})),references:e.references.map(n=>({store_root:n.storeRoot,path:n.path,kind:n.kind,from:n.from,to:n.to})),dryRun:e.dryRun,blocked:e.blocked,corpus_phase:e.corpusPhase,wrote:{profile_manifests:e.wrote.profileManifests,documents:e.wrote.documents,corpus_consumers:e.wrote.corpusConsumers,corpus_identities:e.wrote.corpusIdentities},resumed:t.resumed,...t.resumeError===void 0?{}:{resume_error:t.resumeError}}}o(pe,"toMigrateStateDTO");function q(e,t){try{return b(e,t)??null}catch{return null}}o(q,"readStructuredResult");function F(e){return e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0?null:{kind:e.outcome_kind,reason:e.outcome_reason,settled_at:e.outcome_at}}o(F,"toNodeOutcomeSummaryDTO");function h(e){if(e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0)return null;let t=null;if(e.outcome_detail_json!==null&&e.outcome_detail_json!==void 0)try{t=JSON.parse(e.outcome_detail_json)}catch{t=null}const i=e.final_report??null,r={node_id:e.node_id,revision:e.outcome_revision??1,settled_at:e.outcome_at,final_report:i,final_report_path:i===null?null:`${m(e.node_id)}/${i}`,structured_result:e.outcome_kind==="result"?q(e.node_id,e.grantee):null,detail:t};return e.outcome_kind==="result"?{...r,kind:"result",reason:e.outcome_reason,declined:null}:e.outcome_reason==="declined"?{...r,kind:"failure",reason:"declined",declined:t?.declined??null}:{...r,kind:"failure",reason:e.outcome_reason,declined:null}}o(h,"toNodeOutcomeDTO");function fe(e){const t=h(e);return t===null||t.reason==="parked"?null:t.kind==="result"||t.reason==="finished"?{...t,kind:"result",reason:"finalized"}:t.reason==="closed"||t.reason==="stranded"||t.reason==="retired"?{...t,reason:"canceled"}:t.reason==="declined"||t.reason==="deadline_exceeded"?t:{...t,reason:"runtime_error",details:{crouter_reason:t.reason}}}o(fe,"toRunOutcomeDTO");function me(e){const t=e.lastFailure;return{node_id:e.nodeId,state:e.state,action:e.actionName,attempt:e.attempt,next_attempt_at:e.nextAttemptAt===0?null:new Date(e.nextAttemptAt).toISOString(),accepted_at:e.acceptedAt===null?null:new Date(e.acceptedAt).toISOString(),permanent_failed_at:e.permanentFailedAt===null?null:new Date(e.permanentFailedAt).toISOString(),last_failure:t===null?null:{kind:t.kind,...t.exitCode===void 0?{}:{exit_code:t.exitCode},...t.signal===void 0?{}:{signal:t.signal},...t.message===void 0?{}:{message:t.message}},created_at:new Date(e.createdAt).toISOString(),updated_at:new Date(e.updatedAt).toISOString()}}o(me,"toOutcomeDeliveryDTO");function he(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,status:e.status,frozen_at:e.frozen_at,pi_pid:e.pi_pid,telemetry_context_tokens:e.telemetry_context_tokens,telemetry_last_activity:e.telemetry_last_activity,fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming}}o(he,"toGraphNodeDTO");function ve(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind,profile_id:e.profile_id,scopes:e.scopes,grantee:e.grantee??f(e.node_id),profile_paused:p(e.profile_id),parent:e.parent,created:e.created,intent:e.intent,waiting_for:e.waiting_for,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid,pi_pid_identity:e.pi_pid_identity,window:e.window,tmux_session:e.tmux_session,pane:e.pane,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,outcome:F(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1}}o(ve,"toNodeSummaryDTO");function M(e,t){return{parent:e.parent??null,spawned_by:e.spawned_by??null,subscribes_to:t.subscribesTo.map(i=>i.node_id),subscribers:t.subscribers.map(i=>i.node_id),children:[...t.children]}}o(M,"toNodeEdgesDTO");function U(e,t){return{node_dir:A(e,t),context_dir:S(e,t),reports_dir:m(e,t),meta_path:R(e),transcript_path:T(e),view_socket:E(e)}}o(U,"toNodePathsDTO");function G(e){const t={state:e.state,path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created};return e.cleanup!==void 0&&(t.cleanup=e.cleanup),e.closed!==void 0&&(t.closed=e.closed),e.abandoned!==void 0&&(t.abandoned={...e.abandoned}),t}o(G,"toNodeWorktreeDTO");function ge(e,t){const i=f(e.node_id),r={node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes??null,grantee:i,profile_paused:p(e.profile_id),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,outcome:h(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1,creator:e.creator??null,edges:M(e,t),paths:U(e.node_id,i)};return e.description!==void 0&&(r.description=e.description),e.title!==void 0&&(r.title=e.title),e.icon!==void 0&&(r.icon=e.icon),e.cycles!==void 0&&(r.cycles=e.cycles),r.context_tokens=e.telemetry_context_tokens??e.telemetry_tokens_in??null,e.pi_session_id!==void 0&&(r.pi_session_id=e.pi_session_id??null),r.model_override=e.model_override??null,e.pi_session_file!==void 0&&(r.pi_session_file=e.pi_session_file??null),e.review_binding!==void 0&&(r.review_binding=e.review_binding===null?null:{...e.review_binding.kind===void 0?{}:{kind:e.review_binding.kind},review_id:e.review_binding.review_id,origin_node_id:e.review_binding.origin_node_id,branch_file:e.review_binding.branch_file,target_file:e.review_binding.target_file}),e.managed_worktree!=null&&(r.worktree=G(e.managed_worktree)),r}o(ge,"toNodeDetailDTO");function ye(e,t,i){return{node_id:e,revived:t.launch!==void 0,resumed:t.resumed,status:i,outcome:t.outcome}}o(ye,"toReviveResultDTO");function ke(e){return{root:e.root,closed:[...e.closed],spared:[...e.spared]}}o(ke,"toCloseResultDTO");function be(e,t,i){const r={report_path:e.reportPath,notified:[...e.deliveredTo]};return t!==void 0&&(r.transitioned=t),i!==void 0&&(r.worktree_auto_dropped=!0,r.worktree_auto_dropped_path=i),r}o(be,"toReportResultDTO");function xe(e){return{node_id:e.node_id,active:e.active,created:e.created}}o(xe,"toSubscriptionDTO");function K(e){if(e===null||e==="")return[];try{const t=JSON.parse(e);return typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t):[]}catch{return[]}}o(K,"envKeys");function Oe(e,t){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by,command:e.command,fire_at:e.fire_at,recur:e.recur,tz:e.tz,expires_at:e.expires_at,anchor_node:e.anchor_node,cancel_on_wake:e.cancel_on_wake,cwd:e.cwd,profile:e.profile,scope:e.scope,env_keys:K(e.env_json),run_timeout_s:e.run_timeout_s,overlap:e.overlap,on_output:e.on_output,sink:x(e.sink),tier:e.tier,state:e.state,held:e.held,run_state:e.run_state,last_run:t==null?null:{finished:t.finished,exit_code:t.exit_code,delivered:t.delivered},created:e.created,updated:e.updated}}o(Oe,"toCronDTO");function De(e){return{run_id:e.run_id,started:e.started,finished:e.finished,duration_ms:e.duration_ms,exit_code:e.exit_code,stdout_head:e.stdout_head,stderr_head:e.stderr_head,delivered:e.delivered}}o(De,"toCronRunDTO");function Re(e){return{id:e.profileId,app:e.manifest.grantee??"app:terminal",name:e.manifest.name,projects:e.manifest.projects.map(t=>({...t})),paused_at:e.manifest.paused_at,default_kind:e.manifest.default_kind??"general",metadata:D(e.manifest.metadata),default_dir:null,created_at:e.manifest.created_at,last_used_at:e.manifest.last_used_at,memory_path:O(e.profileId)}}o(Re,"toProfileDTO");function v(e,t={}){const i={review_id:e.review_id,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,review_dir:e.review_dir,companion_node_id:e.companion_node_id,file:e.file,state:e.state,created:e.created,source_missing:e.source_missing,anchor_base_sha256:e.anchor_base_sha256};return e.opened_at!==null&&(i.opened_at=e.opened_at),e.submit_requested_at!==null&&(i.submit_requested_at=e.submit_requested_at),e.approved_at!==null&&(i.approved_at=e.approved_at),e.changed!==null&&(i.changed=e.changed),e.comments_total!==null&&(i.comments_total=e.comments_total),e.comments_unresolved!==null&&(i.comments_unresolved=e.comments_unresolved),e.canceled_at!==null&&(i.canceled_at=e.canceled_at),e.cancel_reason!==null&&(i.cancel_reason=e.cancel_reason),e.cancel_actor!==null&&(i.cancel_actor=e.cancel_actor),t.result_path!==void 0&&(i.result_path=t.result_path),e.delivery_error!==null&&(i.delivery_error=e.delivery_error),e.projection_error!==null&&(i.projection_error=e.projection_error),i}o(v,"toReviewDTO");function Te(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{...e.anchor},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author.kind,...e.author.node_id===null?{}:{node_id:e.author.node_id}},updated_by:{kind:e.updated_by.kind,...e.updated_by.node_id===null?{}:{node_id:e.updated_by.node_id}},created_at:e.created_at,updated_at:e.updated_at,...e.resolved_at===null?{}:{resolved_at:e.resolved_at},...e.deleted_at===null?{}:{deleted_at:e.deleted_at},created_seq:e.created_seq}}o(Te,"toReviewCommentDTO");function B(e){return{id:e.id,quote:e.quote,...e.context===void 0?{}:{context:e.context},note:e.note,status:e.status,created_at:e.createdAt,...e.resolvedAt===void 0?{}:{resolved_at:e.resolvedAt}}}o(B,"toPageFeedbackCommentDTO");function Ee(e){return{companion_node_id:e.companionNodeId??null,open_count:e.comments.filter(t=>t.status==="open").length,comments:e.comments.map(B)}}o(Ee,"toPageFeedbackDTO");function Se(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===1,revision_after:e.revision_after,actor:{kind:e.actor.kind,...e.actor.node_id===null?{}:{node_id:e.actor.node_id}},at:e.at,operation_id:e.operation_id,...e.payload===void 0?{}:{payload:e.payload}}}o(Se,"toReviewCommentEventDTO");function Ae(e){return{file:e.file,submitted:e.submitted,approved:e.approved,comments:e.comments.map(i=>({...i})),submittedAt:e.submittedAt,savedAt:e.savedAt,reviewId:e.review_id,changed:e.changed,baselineSha256:e.baseline_sha256,approvedSha256:e.approved_sha256,companionNodeId:e.companion_node_id,commentsTotal:e.comments_total,commentsUnresolved:e.comments_unresolved}}o(Ae,"toFeedbackResultDTO");const L=!0,W=Object.freeze({review_origin_missing:{status:400,code:"review_origin_unavailable"},review_origin_unforkable:{status:400,code:"review_origin_unavailable"},review_branch_unavailable:{status:409,code:"review_branch_unavailable"},branch_lost:{status:409,code:"review_branch_unavailable"},review_companion_unbound:{status:409,code:"review_companion_unbound"},review_bridge_unsubscribed:{status:409,code:"review_bridge_unavailable"},review_target_unreviewable:{status:400,code:"review_file_unreadable"},source_unreadable:{status:409,code:"review_source_unreadable"},delivery_unroutable:{status:409,code:"review_delivery_unroutable"},unknown_review:{status:404,code:"unknown_review"},review_terminal:{status:409,code:"review_terminal_conflict"},review_required:{status:400,code:"review_required"},stale_document:{status:409,code:"stale_document"},unknown_comment:{status:404,code:"unknown_comment"},comment_deleted:{status:409,code:"comment_deleted"},invalid_anchor:{status:400,code:"invalid_anchor"},anchor_out_of_range:{status:400,code:"anchor_out_of_range"},text_too_long:{status:400,code:"text_too_long"},comment_limit_reached:{status:409,code:"comment_limit_reached"},stale_comment:{status:409,code:"stale_comment"},range_batch_incomplete:{status:409,code:"range_batch_incomplete"},range_batch_stale:{status:409,code:"range_batch_stale"}});function $(e){const t=g(e);if(typeof t=="object"&&t!==null&&typeof t.status=="number"&&typeof t.code=="string")return{status:t.status,code:t.code};if(t instanceof z)return t.code==="unknown_node"?{status:404,code:"node_not_found"}:t.code==="already_finalized"?{status:409,code:"already_finalized"}:{status:409,code:"finalization_forbidden"};if(t instanceof N)return{status:409,code:"node_id_exists"};if(t instanceof C)return{status:403,code:"scope_denied"};if(P(t))return{status:400,code:"invalid_request"};if(t instanceof c)return W[t.code];if(t instanceof l)return{status:J(t.exitCode),code:t.code};if(t instanceof Error){const i=t.message;if(/unknown node/i.test(i))return{status:404,code:"node_not_found"};if(/finalization latch/i.test(i))return{status:409,code:"already_finalized"};if(/illegal lifecycle transition/i.test(i))return{status:409,code:"illegal_transition"}}return{status:500,code:"internal"}}o($,"errorToStatus");function g(e){if(!(e instanceof j))return e;const t=e.code==="unknown_node"?a.NOT_FOUND:a.GENERAL,i={error:e.code,message:e.message,next:e.next};return e.detail!==void 0&&(i.received=e.detail),new l(e.code,e.message,t,i)}o(g,"normalizeThrow");function V(e){if(e.code!=="review_terminal")return e.detail;const{review:t,...i}=e.detail;return{...i,review:H(t)}}o(V,"reviewErrorDetails");function H(e){return e.state!=="approved"?v(e):v(e,{result_path:k(e.review_dir,"result.json")})}o(H,"terminalConflictReviewDTO");function J(e){switch(e){case a.NOT_FOUND:return 404;case a.USAGE:return 400;case a.AMBIGUOUS:return 400;case a.NETWORK:return 503;case a.GENERAL:return 400;default:return 500}}o(J,"statusForExitCode");function Q(e){const i=(e instanceof Error?e.message:String(e)).split(`
2
+ `,1)[0].trim();return i===""?"internal error":i.length>500?`${i.slice(0,497)}\u2026`:i}o(Q,"boundedCause");function ze(e){const t=g(e),{status:i,code:r}=$(t);if(i>=500){const _={error:{code:r,message:Q(t)}};return t instanceof u&&(_.error.origin="runtime",_.error.retryable=t.retryable),{status:i,body:_}}const n=t instanceof Error?t.message:String(t),s=t instanceof c?V(t):(t instanceof l||t instanceof I||t instanceof u)&&t.details!==void 0?t.details:void 0,d={error:{code:r,message:n}};return s!==void 0&&(d.error.details=s),t instanceof u&&(t.param&&(d.error.param=t.param),t.scope&&(d.error.scope=t.scope),d.error.origin="runtime",d.error.retryable=t.retryable),{status:i,body:d}}o(ze,"toErrorBody");export{W as REVIEW_ERROR_MAP,$ as errorToStatus,ke as toCloseResultDTO,Oe as toCronDTO,De as toCronRunDTO,ze as toErrorBody,Ae as toFeedbackResultDTO,he as toGraphNodeDTO,pe as toMigrateStateDTO,ge as toNodeDetailDTO,M as toNodeEdgesDTO,h as toNodeOutcomeDTO,F as toNodeOutcomeSummaryDTO,U as toNodePathsDTO,ve as toNodeSummaryDTO,G as toNodeWorktreeDTO,me as toOutcomeDeliveryDTO,B as toPageFeedbackCommentDTO,Ee as toPageFeedbackDTO,Re as toProfileDTO,be as toReportResultDTO,Te as toReviewCommentDTO,Se as toReviewCommentEventDTO,v as toReviewDTO,ye as toReviveResultDTO,fe as toRunOutcomeDTO,xe as toSubscriptionDTO};
@@ -0,0 +1,18 @@
1
+ import type { Scope } from '@north-light/crouter-identity';
2
+ export type CallerClass = 'anonymous' | 'person' | 'app' | 'broker' | 'directory';
3
+ export type ResourceRule = 'none' | 'node-read' | 'node-write' | 'node-own' | 'nodes-list' | 'canvas-read' | 'memory' | 'cron' | 'profile' | 'human' | 'run' | 'daemon-bash';
4
+ export interface Operation {
5
+ name: string;
6
+ method: string;
7
+ path: string;
8
+ classes: readonly CallerClass[];
9
+ scope?: Scope;
10
+ resource: ResourceRule;
11
+ stage?: string;
12
+ idempotency?: string;
13
+ stream?: boolean;
14
+ wait?: boolean;
15
+ }
16
+ export type AppOperation = Operation;
17
+ export declare const OPERATIONS: readonly Operation[];
18
+ export declare function operationFor(method: string, path: string): Operation | undefined;
@@ -0,0 +1 @@
1
+ var n=Object.defineProperty;var r=(e,s)=>n(e,"name",{value:s,configurable:!0});const a=[{name:"health",method:"GET",path:"/v1/health",classes:["anonymous"],resource:"none",stage:"v0.5"},{name:"chat-inventory.get.1",method:"GET",path:"/v1/nodes/:id/chat-inventory",classes:["person","broker"],resource:"node-read"},{name:"model-config.put.2",method:"PUT",path:"/v1/model-config",classes:["person"],resource:"none"},{name:"files.get.3",method:"GET",path:"/v1/files/peek",classes:["person","broker"],resource:"none"},{name:"files.post.4",method:"POST",path:"/v1/files/write",classes:["person","broker"],resource:"none"},{name:"files.get.5",method:"GET",path:"/v1/files/list",classes:["person","broker"],resource:"none"},{name:"reviews.post.6",method:"POST",path:"/v1/human/reviews",classes:["person","broker"],resource:"human",scope:"crtr:act"},{name:"reviews.get.7",method:"GET",path:"/v1/human/reviews",classes:["person","broker"],resource:"human"},{name:"reviews.get.8",method:"GET",path:"/v1/human/reviews/:review_id",classes:["person","broker"],resource:"human"},{name:"reviews.post.9",method:"POST",path:"/v1/human/reviews/:review_id/submit",classes:["person","broker"],resource:"human"},{name:"reviews.post.10",method:"POST",path:"/v1/human/reviews/:review_id/cancel",classes:["person","broker"],resource:"human"},{name:"reviews.get.11",method:"GET",path:"/v1/human/reviews/:review_id/document",classes:["person","broker"],resource:"human"},{name:"feedback-comments.post.12",method:"POST",path:"/v1/human/inbox/:ticket_id/feedback-comments",classes:["person","broker"],resource:"human"},{name:"feedback-comments.post.13",method:"POST",path:"/v1/human/inbox/:ticket_id/feedback-comments/:comment_id/resolve",classes:["person","broker"],resource:"human"},{name:"node.log.append",method:"POST",path:"/v1/nodes/:id/records/log",classes:["person","broker"],resource:"node-own"},{name:"node.telemetry.put",method:"PUT",path:"/v1/nodes/:id/records/telemetry",classes:["person","broker"],resource:"node-own"},{name:"node.recap.put",method:"PUT",path:"/v1/nodes/:id/records/recap",classes:["person","broker"],resource:"node-own"},{name:"node.inbox.read",method:"GET",path:"/v1/nodes/:id/records/inbox",classes:["person","broker"],resource:"node-own"},{name:"node.passive.read",method:"GET",path:"/v1/nodes/:id/records/passive",classes:["person","broker"],resource:"node-own"},{name:"node.pushed-final",method:"POST",path:"/v1/nodes/:id/records/pushed-final",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.14",method:"POST",path:"/v1/nodes/:id/broker/session-bound",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.15",method:"POST",path:"/v1/nodes/:id/broker/settle",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.16",method:"POST",path:"/v1/nodes/:id/broker/park-complete",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.17",method:"POST",path:"/v1/nodes/:id/broker/park-activity",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.18",method:"POST",path:"/v1/nodes/:id/broker/telemetry",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.19",method:"POST",path:"/v1/nodes/:id/broker/model",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.get.20",method:"GET",path:"/v1/nodes/:id/broker/extension-state",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.context",method:"POST",path:"/v1/nodes/:id/broker/context",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.memory-refs",method:"POST",path:"/v1/nodes/:id/broker/memory-refs",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.context-commit",method:"POST",path:"/v1/nodes/:id/broker/context/commit",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.context-event",method:"POST",path:"/v1/nodes/:id/broker/context/event",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.21",method:"POST",path:"/v1/nodes/:id/broker/generated-name",classes:["person","broker"],resource:"node-own"},{name:"broker-ops.post.22",method:"POST",path:"/v1/nodes/:id/broker/persona-ack",classes:["person","broker"],resource:"node-own"},{name:"memory.get.23",method:"GET",path:"/v1/memory/docs",classes:["person","app","broker"],resource:"memory"},{name:"memory.get.24",method:"GET",path:"/v1/memory/docs/:name",classes:["person","app","broker"],resource:"memory"},{name:"memory.post.25",method:"POST",path:"/v1/memory/docs",classes:["person","app","broker"],resource:"memory"},{name:"memory.patch.26",method:"PATCH",path:"/v1/memory/docs/:name",classes:["person","app","broker"],resource:"memory"},{name:"memory.delete.27",method:"DELETE",path:"/v1/memory/docs/:name",classes:["person","app","broker"],resource:"memory"},{name:"memory.post.28",method:"POST",path:"/v1/memory/docs/:name/move",classes:["person","app","broker"],resource:"memory"},{name:"memory.post.29",method:"POST",path:"/v1/memory/search",classes:["person","app","broker"],resource:"memory"},{name:"memory.get.30",method:"GET",path:"/v1/memory/docs/:name/history",classes:["person","app","broker"],resource:"memory"},{name:"memory.get.31",method:"GET",path:"/v1/memory/resolve",classes:["person","app","broker"],resource:"memory"},{name:"memory.get.32",method:"GET",path:"/v1/memory/origin",classes:["person","app","broker"],resource:"memory"},{name:"memory.lint",method:"POST",path:"/v1/memory/lint",classes:["person","app","broker"],resource:"memory"},{name:"memory.extensions",method:"GET",path:"/v1/memory/extensions",classes:["person","broker"],resource:"memory"},{name:"memory.slash.list",method:"GET",path:"/v1/memory/slash",classes:["person","broker"],resource:"memory"},{name:"memory.slash.attachments",method:"POST",path:"/v1/memory/slash/attachments",classes:["person","broker"],resource:"memory"},{name:"health.get.33",method:"GET",path:"/healthz",classes:["anonymous"],resource:"none"},{name:"health.get.34",method:"GET",path:"/v1/status",classes:["person"],resource:"none"},{name:"bash-jobs.start",method:"POST",path:"/v1/nodes/:id/jobs/start",classes:["broker"],resource:"node-own",scope:"crtr:act"},{name:"hooks.plan",method:"GET",path:"/v1/nodes/:id/hooks/plan",classes:["broker"],resource:"node-own"},{name:"hooks.exec",method:"POST",path:"/v1/nodes/:id/hooks/exec",classes:["broker"],resource:"node-own"},{name:"hooks.exec.person",method:"POST",path:"/v1/hooks/exec",classes:["person"],resource:"none"},{name:"bash-jobs.get.35",method:"GET",path:"/v1/nodes/:id/jobs",classes:["person","broker"],resource:"node-read"},{name:"bash-jobs.delete.36",method:"DELETE",path:"/v1/nodes/:id/jobs/:jobId",classes:["person","broker"],resource:"node-write"},{name:"prospective-chat-inventory.get.37",method:"GET",path:"/v1/prospective-chat-inventory",classes:["person"],resource:"none"},{name:"node-events.get.38",method:"GET",path:"/v1/nodes/:id/events",classes:["person","broker"],resource:"node-read"},{name:"bash.post.39",method:"POST",path:"/v1/bash",classes:["person","broker"],resource:"daemon-bash",scope:"crtr:act"},{name:"subscriptions.post.40",method:"POST",path:"/v1/nodes/:id/subscriptions",classes:["person","broker"],resource:"node-write"},{name:"subscriptions.delete.41",method:"DELETE",path:"/v1/nodes/:id/subscriptions/:target",classes:["person","broker"],resource:"node-write"},{name:"attach.post.42",method:"POST",path:"/v1/nodes/:id/attach",classes:["person"],resource:"none"},{name:"review-comments.post.44",method:"POST",path:"/v1/human/reviews/self/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.45",method:"GET",path:"/v1/human/reviews/self/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.post.46",method:"POST",path:"/v1/human/reviews/:review_id/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.47",method:"GET",path:"/v1/human/reviews/:review_id/comments",classes:["person","broker"],resource:"human"},{name:"review-comments.get.48",method:"GET",path:"/v1/human/reviews/:review_id/comment-events",classes:["person","broker"],resource:"human"},{name:"review-comments.post.49",method:"POST",path:"/v1/human/reviews/:review_id/comment-ranges",classes:["person","broker"],resource:"human"},{name:"review-comments.get.50",method:"GET",path:"/v1/human/comments/:comment_id",classes:["person","broker"],resource:"human"},{name:"review-comments.post.51",method:"POST",path:"/v1/human/comments/:comment_id/edit",classes:["person","broker"],resource:"human"},{name:"review-comments.post.52",method:"POST",path:"/v1/human/comments/:comment_id/resolve",classes:["person","broker"],resource:"human"},{name:"review-comments.post.53",method:"POST",path:"/v1/human/comments/:comment_id/reopen",classes:["person","broker"],resource:"human"},{name:"review-comments.post.54",method:"POST",path:"/v1/human/comments/:comment_id/delete",classes:["person","broker"],resource:"human"},{name:"review-comments.post.55",method:"POST",path:"/v1/human/comments/:comment_id/fork",classes:["person","broker"],resource:"human"},{name:"messages.post.56",method:"POST",path:"/v1/nodes/:id/mail/claim",classes:["person","broker"],resource:"node-own"},{name:"messages.post.57",method:"POST",path:"/v1/nodes/:id/mail/acknowledge",classes:["person","broker"],resource:"node-own"},{name:"messages.post.58",method:"POST",path:"/v1/nodes/:id/messages",classes:["person","broker"],resource:"node-write"},{name:"messages.post.59",method:"POST",path:"/v1/nodes/:id/interrupt",classes:["person","broker"],resource:"node-write"},{name:"reports.post.60",method:"POST",path:"/v1/nodes/:id/reports",classes:["person","broker"],resource:"node-own"},{name:"reports.get.61",method:"GET",path:"/v1/nodes/:id/reports",classes:["person","broker"],resource:"node-read"},{name:"reports.post.62",method:"POST",path:"/v1/nodes/:id/result",classes:["person","broker"],resource:"node-own"},{name:"inbox.get.63",method:"GET",path:"/v1/human/inbox",classes:["person","broker"],resource:"human"},{name:"inbox.get.64",method:"GET",path:"/v1/human/inbox/history",classes:["person","broker"],resource:"human"},{name:"inbox.get.65",method:"GET",path:"/v1/human/inbox/:ticket_id",classes:["person","broker"],resource:"human"},{name:"inbox.get.66",method:"GET",path:"/v1/human/inbox/:ticket_id/response",classes:["person","broker"],resource:"human"},{name:"inbox.post.67",method:"POST",path:"/v1/human/inbox/:ticket_id/respond",classes:["person","broker"],resource:"human"},{name:"inbox.post.68",method:"POST",path:"/v1/human/inbox/:ticket_id/progress",classes:["person","broker"],resource:"human"},{name:"inbox.post.69",method:"POST",path:"/v1/human/inbox/:ticket_id/cancel",classes:["person","broker"],resource:"human"},{name:"worktree.post.70",method:"POST",path:"/v1/nodes/:id/worktree/close",classes:["person","broker"],resource:"node-write"},{name:"worktree.post.71",method:"POST",path:"/v1/nodes/:id/worktree/abandon",classes:["person","broker"],resource:"node-write"},{name:"worktree.get.72",method:"GET",path:"/v1/worktrees/quarantined",classes:["person"],resource:"none"},{name:"crons.post.73",method:"POST",path:"/v1/crons",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.get.74",method:"GET",path:"/v1/crons",classes:["person","app","broker"],resource:"cron"},{name:"crons.get.75",method:"GET",path:"/v1/crons/:cronId",classes:["person","app","broker"],resource:"cron"},{name:"crons.post.76",method:"POST",path:"/v1/crons/:cronId/pause",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.77",method:"POST",path:"/v1/crons/:cronId/resume",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.78",method:"POST",path:"/v1/crons/poke",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.post.79",method:"POST",path:"/v1/crons/:cronId/run",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"crons.delete.80",method:"DELETE",path:"/v1/crons/:cronId",classes:["person","app","broker"],resource:"cron",scope:"crtr:schedule"},{name:"modelauth.get.81",method:"GET",path:"/v1/model-auth",classes:["person"],resource:"none"},{name:"modelauth.get.82",method:"GET",path:"/v1/model-auth/readiness",classes:["person"],resource:"none"},{name:"modelauth.put.83",method:"PUT",path:"/v1/model-auth/:provider",classes:["person"],resource:"none"},{name:"modelauth.delete.84",method:"DELETE",path:"/v1/model-auth/:provider",classes:["person"],resource:"none"},{name:"model_auth.start",method:"POST",path:"/v1/model-auth/flows",classes:["person"],resource:"none"},{name:"model_auth.complete",method:"POST",path:"/v1/model-auth/flows/:flow_id/complete",classes:["person"],resource:"none"},{name:"model_auth.cancel",method:"POST",path:"/v1/model-auth/flows/:flow_id/cancel",classes:["person"],resource:"none"},{name:"model_auth.get",method:"GET",path:"/v1/model-auth/flows/:flow_id",classes:["person"],resource:"none",wait:!0},{name:"nodes.post.85",method:"POST",path:"/v1/nodes",classes:["person","broker"],resource:"node-own",scope:"crtr:act"},{name:"nodes.get.86",method:"GET",path:"/v1/nodes",classes:["person","broker"],resource:"nodes-list"},{name:"nodes.post.87",method:"POST",path:"/v1/nodes/revive-all",classes:["person"],resource:"none"},{name:"nodes.get.88",method:"GET",path:"/v1/nodes/:id",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.89",method:"GET",path:"/v1/nodes/:id/snapshot",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.90",method:"GET",path:"/v1/nodes/:id/subject",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.91",method:"GET",path:"/v1/nodes/:id/messages",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.92",method:"GET",path:"/v1/nodes/:id/session",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.93",method:"GET",path:"/v1/nodes/:id/transcript",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.94",method:"GET",path:"/v1/nodes/:id/context",classes:["person","broker"],resource:"node-read"},{name:"nodes.get.95",method:"GET",path:"/v1/nodes/:id/artifacts",classes:["person","broker"],resource:"node-read"},{name:"nodes.post.96",method:"POST",path:"/v1/nodes/:id/fork",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.97",method:"POST",path:"/v1/nodes/:id/revive",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.98",method:"POST",path:"/v1/nodes/:id/relaunch-root",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.99",method:"POST",path:"/v1/nodes/:id/close",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.100",method:"POST",path:"/v1/nodes/:id/recycle",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.101",method:"POST",path:"/v1/nodes/:id/demote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.102",method:"POST",path:"/v1/nodes/:id/promote",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.103",method:"POST",path:"/v1/nodes/:id/yield",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.post.104",method:"POST",path:"/v1/nodes/:id/wait",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"nodes.patch.105",method:"PATCH",path:"/v1/nodes/:id/config",classes:["person","broker"],resource:"node-write",scope:"crtr:act"},{name:"broker-recovery.post.106",method:"POST",path:"/v1/broker/:id/turn",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.107",method:"POST",path:"/v1/broker/:id/provider-retry",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.108",method:"POST",path:"/v1/broker/:id/fault",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.get.109",method:"GET",path:"/v1/broker/:id/recovery",classes:["person","broker"],resource:"node-own"},{name:"broker-recovery.post.110",method:"POST",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"broker-recovery.delete.111",method:"DELETE",path:"/v1/nodes/:id/fault",classes:["person","broker"],resource:"node-write"},{name:"profiles.put.112",method:"PUT",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profiles.post.113",method:"POST",path:"/v1/profiles/:name/pause",classes:["person"],resource:"profile"},{name:"profiles.post.114",method:"POST",path:"/v1/profiles/:name/resume",classes:["person"],resource:"profile"},{name:"profiles.patch.115",method:"PATCH",path:"/v1/profiles/:name/metadata",classes:["person","app","broker"],resource:"profile"},{name:"profile.create",method:"POST",path:"/v1/profiles",classes:["person","app","broker"],resource:"profile"},{name:"profile.update",method:"PATCH",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.list",method:"GET",path:"/v1/profiles/:name/env",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.set",method:"PUT",path:"/v1/profiles/:name/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"profile.env.remove",method:"DELETE",path:"/v1/profiles/:name/env/:var",classes:["person","app","broker"],resource:"profile"},{name:"profiles.delete.116",method:"DELETE",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"profiles.get.117",method:"GET",path:"/v1/profiles",classes:["person","app","broker"],resource:"profile"},{name:"profiles.get.118",method:"GET",path:"/v1/profiles/:name",classes:["person","app","broker"],resource:"profile"},{name:"node-outcomes.get.119",method:"GET",path:"/v1/nodes/:id/outcome",classes:["person","broker"],resource:"node-read"},{name:"node-outcomes.put.120",method:"PUT",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-write"},{name:"node-outcomes.get.121",method:"GET",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-read"},{name:"node-outcomes.delete.122",method:"DELETE",path:"/v1/nodes/:id/outcome-delivery",classes:["person","broker"],resource:"node-write"},{name:"canvas.get.123",method:"GET",path:"/v1/canvas/attention",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.124",method:"POST",path:"/v1/canvas/attention/counts",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.125",method:"POST",path:"/v1/canvas/history/search",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.126",method:"POST",path:"/v1/canvas/history/grep",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.127",method:"GET",path:"/v1/canvas/history/read",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.128",method:"POST",path:"/v1/canvas/history/stats",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.129",method:"GET",path:"/v1/canvas/snapshot",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.130",method:"GET",path:"/v1/canvas/roster",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.get.analytics",method:"GET",path:"/v1/canvas/analytics",classes:["person"],resource:"canvas-read"},{name:"memory-reads.post",method:"POST",path:"/v1/nodes/:id/memory-reads",classes:["person","broker"],resource:"node-own"},{name:"canvas.get.131",method:"GET",path:"/v1/canvas/graph",classes:["person","broker"],resource:"canvas-read"},{name:"canvas.post.132",method:"POST",path:"/v1/canvas/prune",classes:["person"],resource:"none"},{name:"daemon.post.133",method:"POST",path:"/v1/daemon/restart",classes:["person"],resource:"none"},{name:"daemon.post.134",method:"POST",path:"/v1/daemon/migrate",classes:["person"],resource:"none"},{name:"daemon.post.135",method:"POST",path:"/v1/daemon/admit",classes:["person"],resource:"none"},{name:"human.components.list",method:"GET",path:"/v1/human/components",classes:["person","broker"],resource:"none"},{name:"human-requests.post.136",method:"POST",path:"/v1/human/requests",classes:["person","broker"],resource:"human",scope:"crtr:act"},{name:"human-requests.get.137",method:"GET",path:"/v1/human/requests/:request_id",classes:["person","broker"],resource:"human"},{name:"human-requests.post.138",method:"POST",path:"/v1/human/requests/:request_id/replace",classes:["person","broker"],resource:"human"},{name:"human-requests.post.139",method:"POST",path:"/v1/human/requests/:request_id/respond",classes:["person","broker"],resource:"human"},{name:"human-requests.post.140",method:"POST",path:"/v1/human/requests/:request_id/dismiss",classes:["person","broker"],resource:"human"},{name:"human-requests.post.141",method:"POST",path:"/v1/human/requests/:request_id/cancel",classes:["person","broker"],resource:"human"},{name:"focus.get.142",method:"GET",path:"/v1/focuses",classes:["person"],resource:"none"},{name:"focus.post.143",method:"POST",path:"/v1/focuses",classes:["person"],resource:"none"},{name:"focus.get.144",method:"GET",path:"/v1/focuses/by-node",classes:["person"],resource:"none"},{name:"focus.get.145",method:"GET",path:"/v1/focuses/by-pane",classes:["person"],resource:"none"},{name:"focus.patch.146",method:"PATCH",path:"/v1/focuses/:focus_id",classes:["person"],resource:"none"},{name:"focus.delete.147",method:"DELETE",path:"/v1/focuses/:focus_id",classes:["person"],resource:"none"},{name:"space.list",method:"GET",path:"/v1/spaces",classes:["person"],resource:"none"},{name:"kinds.list",method:"GET",path:"/v1/kinds",classes:["person","app","broker"],resource:"none"},{name:"grant.get",method:"GET",path:"/v1/grant",classes:["app"],resource:"none",stage:"v0.5"},{name:"llm",method:"POST",path:"/v1/llm",classes:["app","person","broker"],scope:"crtr:llm",resource:"none",stage:"v1"},{name:"run.start",method:"POST",path:"/v1/runs",classes:["app"],scope:"crtr:act",resource:"none",stage:"v0.5",idempotency:"24h"},{name:"run.list",method:"GET",path:"/v1/runs",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.get",method:"GET",path:"/v1/runs/:run_id",classes:["app","person","broker"],resource:"run",stage:"v0.5",wait:!0},{name:"run.message",method:"POST",path:"/v1/runs/:run_id/messages",classes:["app","person","broker"],scope:"crtr:act",resource:"run",stage:"v0.5"},{name:"run.events",method:"GET",path:"/v1/runs/:run_id/events",classes:["app","person","broker"],resource:"run",stage:"v0.5",stream:!0},{name:"run.interrupt",method:"POST",path:"/v1/runs/:run_id/interrupt",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.cancel",method:"POST",path:"/v1/runs/:run_id/cancel",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"run.delete",method:"DELETE",path:"/v1/runs/:run_id",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"trace.get",method:"GET",path:"/v1/runs/:run_id/trace",classes:["app","person","broker"],resource:"run",stage:"v0.5"},{name:"runtime.sync-notice",method:"POST",path:"/v1/runtime/sync-notice",classes:["directory"],resource:"none",stage:"v1"}];function m(e,s){return a.find(o=>o.method===e.toUpperCase()&&o.path===s)}r(m,"operationFor");export{a as OPERATIONS,m as operationFor};
@@ -0,0 +1,42 @@
1
+ import { type Scope } from '@north-light/crouter-identity';
2
+ import { type GrantScope } from '../../core/grants/mirror.js';
3
+ export interface AppPrincipal {
4
+ sub: string;
5
+ grantee: string;
6
+ client_id: string;
7
+ grant: string;
8
+ rev: number;
9
+ resolved: Scope[];
10
+ resolved_scopes: GrantScope[];
11
+ spend_cap: number | null;
12
+ exp: number;
13
+ }
14
+ /** A verified vendor sign-in handoff (directory spec, Interfaces → Runtime). */
15
+ export interface VendorHandoff {
16
+ sub: string;
17
+ jti: string;
18
+ exp: number;
19
+ }
20
+ export declare class AppPrincipalResolver {
21
+ readonly issuer: string;
22
+ readonly audience: string;
23
+ private readonly syncGrants;
24
+ private readonly cache;
25
+ private ready;
26
+ private timer;
27
+ constructor(issuer: string, audience: string, syncGrants: () => Promise<void>, jwksUrl?: string);
28
+ private load;
29
+ isReady(): boolean;
30
+ close(): void;
31
+ /** jti → exp of every notice accepted within its lifetime. */
32
+ private readonly notices;
33
+ /** A directory sync notice authorizes one grant sync and nothing else.
34
+ * Returns false for a replay of a notice already accepted. */
35
+ verifySyncNotice(authorization: string | undefined): Promise<boolean>;
36
+ /** Verify a directory `vendor_sign_in` handoff: ES256 signature against the
37
+ * JWKS mirror, `iss`, `aud`, `exp`, `purpose`, and that `jti` and `sub` are
38
+ * present (runtime spec §7 "Vendor sign-in page", RT-LLM-52). The owner and
39
+ * single-use `jti` checks are the caller's. Every failure is 401. */
40
+ verifyHandoff(token: string | undefined): Promise<VendorHandoff>;
41
+ resolve(authorization: string | undefined, scope?: string): Promise<AppPrincipal>;
42
+ }
@@ -0,0 +1 @@
1
+ var l=Object.defineProperty;var a=(c,i)=>l(c,"name",{value:i,configurable:!0});import{covers as w,JwksCache as y,verifyAccessToken as p,verifySyncNotice as g}from"@north-light/crouter-identity";import{createLocalJWKSet as m,decodeProtectedHeader as v,jwtVerify as _}from"jose";import{activeGrant as k,hasGrant as x}from"../../core/grants/mirror.js";import{RunError as s}from"../../core/runs/operations.js";class D{static{a(this,"AppPrincipalResolver")}issuer;audience;syncGrants;cache;ready=!1;timer;constructor(i,r,e,t){this.issuer=i,this.audience=r,this.syncGrants=e,this.cache=new y(i,fetch,t),this.load(),this.timer=setInterval(()=>{this.ready||this.load()},5e3),this.timer.unref()}async load(){try{await this.cache.load(),this.ready=!0}catch{}}isReady(){return this.ready}close(){this.timer&&clearInterval(this.timer)}notices=new Map;async verifySyncNotice(i){if(!this.ready)throw new s(503,"runtime_starting","runtime_starting");if(!i?.startsWith("Bearer ")||i.length<=7)throw new s(401,"unauthorized","a directory sync notice token is required");let r;try{r=await g({token:i.slice(7),jwks:this.cache,issuer:this.issuer,audience:this.audience})}catch{throw new s(401,"unauthorized","invalid directory sync notice token")}const e=Math.floor(Date.now()/1e3);for(const[t,n]of this.notices)n+30<e&&this.notices.delete(t);return this.notices.has(r.jti)?!1:(this.notices.set(r.jti,r.exp),!0)}async verifyHandoff(i){if(!this.ready)throw new s(503,"runtime_starting","runtime_starting");const r=a(()=>new s(401,"unauthorized","invalid vendor sign-in handoff"),"refuse");if(!i)throw r();let e;try{const h=v(i);if(h.alg!=="ES256")throw r();const f=await this.cache.forKid(h.kid);({payload:e}=await _(i,m(f),{issuer:this.issuer,audience:this.audience,algorithms:["ES256"],requiredClaims:["exp","jti","sub"]}))}catch{throw r()}const{sub:t,jti:n,exp:o,purpose:d,aud:u}=e;if(d!=="vendor_sign_in"||u!==this.audience||typeof t!="string"||typeof n!="string"||n===""||typeof o!="number")throw r();return{sub:t,jti:n,exp:o}}async resolve(i,r){if(!this.ready)throw new s(503,"runtime_starting","runtime_starting");if(!i?.startsWith("Bearer ")||i.length<=7)throw new s(401,"unauthorized","a directory access token is required");let e;try{e=await p({token:i.slice(7),jwks:this.cache,issuer:this.issuer,audience:this.audience})}catch{throw new s(401,"unauthorized","invalid directory access token")}x(e.grant)||await this.syncGrants();const t=k(e.grant);if(!t||t.sub!==e.sub||t.grantee!==e.grantee||t.expires_at!==null&&!(Date.parse(t.expires_at)>Date.now()))throw new s(401,"grant_revoked","grant is not active");if(r&&!t.resolved.some(n=>w(n,r)))throw new s(403,"scope_missing",`missing scope ${r}`,void 0,void 0,r);return{sub:e.sub,grantee:e.grantee,client_id:e.client_id,grant:e.grant,rev:t.rev,resolved:t.resolved,resolved_scopes:t.resolved_scopes,spend_cap:t.spend_cap,exp:e.exp}}}export{D as AppPrincipalResolver};
@@ -1,8 +1,32 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
2
  import { ApiError } from '../../api/errors.js';
3
+ import type { AppPrincipal } from './principal.js';
4
+ import { type Operation } from './operations.js';
3
5
  /** What the caller's bearer token may reach: `null` is the owner (every scope,
4
6
  * every route); a list is the ceiling minted by `crtr sys connect --scopes`. */
5
7
  export type Ceiling = readonly string[] | null;
8
+ export type RequestPrincipal = {
9
+ class: 'person';
10
+ } | {
11
+ class: 'app';
12
+ app: string;
13
+ scopes: readonly string[];
14
+ } | {
15
+ class: 'broker';
16
+ app: string;
17
+ node: string;
18
+ run: string | null;
19
+ uid: number;
20
+ sub: string;
21
+ grant: string | null;
22
+ client_id: string | null;
23
+ scopes: string[] | null;
24
+ };
25
+ export declare function resolvedScopes(principal: RequestPrincipal): readonly string[];
26
+ export declare function runCallerApp(principal: RequestPrincipal | AppPrincipal): string | null;
27
+ export declare function canReadRun(principal: RequestPrincipal | AppPrincipal, grantee: string): boolean;
28
+ export declare function requireRun(principal: RequestPrincipal | AppPrincipal, id: string, acting?: boolean, allowDeleting?: boolean): import("../../index.js").NodeMeta;
29
+ export declare function canReadNode(principal: RequestPrincipal, grantee: string): boolean;
6
30
  /** Throw the 403 `scope_denied` a scoped bearer earns when its ceiling lacks
7
31
  * `scope`. The owner (`null`) always passes. */
8
32
  export declare function assertCeiling(ceiling: Ceiling, scope: string): void;
@@ -25,6 +49,7 @@ export interface RequestContext {
25
49
  body: unknown;
26
50
  /** The caller's scope ceiling — `null` for the owner token or the unix socket. */
27
51
  ceiling: Ceiling;
52
+ principal: RequestPrincipal;
28
53
  req: IncomingMessage;
29
54
  res: ServerResponse;
30
55
  }
@@ -68,12 +93,11 @@ export declare class Router {
68
93
  match(method: string, path: string): {
69
94
  handler: RouteHandler;
70
95
  params: Record<string, string>;
71
- ownerOnly: boolean;
72
- scope: string | undefined;
96
+ operation: Operation;
73
97
  } | null;
74
98
  /** Resolve the JSON body, dispatch to the matched handler, and write the
75
99
  * response. Every failure path — no route, bad JSON, a handler throw — is
76
100
  * turned into a JSON `ErrorBody` (map.ts §8); this method never throws and
77
101
  * never leaves the daemon crashed. */
78
- handle(req: IncomingMessage, res: ServerResponse, ceiling: Ceiling): Promise<void>;
102
+ handle(req: IncomingMessage, res: ServerResponse, ceiling: Ceiling, principal?: RequestPrincipal): Promise<void>;
79
103
  }
@@ -1 +1 @@
1
- var g=Object.defineProperty;var a=(e,t)=>g(e,"name",{value:t,configurable:!0});import{toErrorBody as E}from"./map.js";import{emitEvent as O}from"../../core/events/emit.js";import{scopeAllowed as b,ScopeDeniedError as S}from"../../core/scopes.js";import{ApiError as _}from"../../api/errors.js";function x(e,t){if(!b(e,t))throw new S("the bearer token",t)}a(x,"assertCeiling");function B(){return new _(403,"owner_only","this operation is owner-only; a scoped token does not reach it")}a(B,"ownerOnlyError");function R(e){return e.map(t=>({...t,ownerOnly:!0}))}a(R,"ownerOnly");const h=4*1024*1024;class T{static{a(this,"Router")}routes=[];register(t){return this.routes.push({method:t.method.toUpperCase(),segments:f(t.pattern),handler:t.handler,ownerOnly:t.ownerOnly===!0,scope:t.scope}),this}registerAll(t){for(const n of t)this.register(n);return this}match(t,n){const s=t.toUpperCase(),r=f(n);for(const o of this.routes){if(o.method!==s)continue;const i=C(o.segments,r);if(i!==null)return{handler:o.handler,params:i,ownerOnly:o.ownerOnly,scope:o.scope}}return null}async handle(t,n,s){try{const r=new URL(t.url??"/","http://127.0.0.1"),o=(t.method??"GET").toUpperCase(),i=this.match(o,r.pathname);if(i===null){y(n,404,"not_found",`no route for ${o} ${r.pathname}`);return}if(i.ownerOnly&&s!==null)throw B();i.scope!==void 0&&x(s,i.scope);let c;try{c=await J(t)}catch(d){const u=d instanceof l?"payload_too_large":"invalid_request";y(n,u==="payload_too_large"?413:400,u,d.message);return}const m={method:o,path:r.pathname,params:i.params,query:r.searchParams,body:c,ceiling:s,req:t,res:n},w=await i.handler(m);U(n,w)}catch(r){const{status:o,body:i}=E(r);o>=500&&O({event:"api.request.failed",level:"error",error:r instanceof Error?r:new Error(String(r)),fields:{method:(t.method??"GET").toUpperCase(),path:t.url??""}}),p(n,o,i)}}}function f(e){return e.split("/").filter(t=>t.length>0)}a(f,"splitPath");function C(e,t){if(e.length!==t.length)return null;const n={};for(let s=0;s<e.length;s++){const r=e[s],o=t[s];if(r.startsWith(":"))n[r.slice(1)]=decodeURIComponent(o);else if(r!==o)return null}return n}a(C,"matchSegments");class l extends Error{static{a(this,"BodyTooLargeError")}}async function J(e){const t=[];let n=0;for await(const r of e){const o=r;if(n+=o.length,n>h)throw new l(`request body exceeds ${h} bytes`);t.push(o)}if(n===0)return;const s=Buffer.concat(t).toString("utf8").trim();if(s!=="")try{return JSON.parse(s)}catch{throw new Error("request body is not valid JSON")}}a(J,"readJsonBody");function U(e,t){if(e.headersSent)return;const n={...t.headers??{}};if(t.rawBody!==void 0){e.writeHead(t.status,n),e.end(t.rawBody);return}if(t.status===204||t.body===void 0){e.writeHead(t.status,n),e.end();return}n["content-type"]===void 0&&(n["content-type"]="application/json; charset=utf-8"),e.writeHead(t.status,n),e.end(JSON.stringify(t.body))}a(U,"writeResult");function p(e,t,n){if(e.headersSent){e.end();return}e.writeHead(t,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify(n))}a(p,"writeJson");function y(e,t,n,s){p(e,t,{error:{code:n,message:s}})}a(y,"writeError");export{T as Router,x as assertCeiling,R as ownerOnly,B as ownerOnlyError};
1
+ var $=Object.defineProperty;var a=(e,t)=>$(e,"name",{value:t,configurable:!0});import{toErrorBody as B}from"./map.js";import{emitEvent as O}from"../../core/events/emit.js";import{scopeAllowed as h,ScopeDeniedError as A}from"../../core/scopes.js";import{ApiError as i}from"../../api/errors.js";import{activeGrant as b,grantFor as T}from"../../core/grants/mirror.js";import{getNode as l}from"../../core/canvas/canvas.js";import{ownedRun as U,RunError as _}from"../../core/runs/operations.js";import{readConfig as W}from"../../core/config.js";import{SCOPE_VOCABULARY as j}from"../../core/scopes.js";import{operationFor as G}from"./operations.js";import{getRequest as J,getRequestByInboxTicket as N}from"../../core/human/requests.js";import{requireVisibleReview as v}from"../../core/review/store.js";import{getComment as E}from"../../core/review/comments.js";function H(e,t,o,s,n){const r=e.path,u=n&&typeof n=="object"&&!Array.isArray(n)?n:{};if(r==="/v1/human/requests"||r==="/v1/human/reviews"){if((r.endsWith("/reviews")?u.origin_node_id:u.requester_node_id)!==t.node)throw new i(403,"other_app_run","a broker may create a human request only for its own node");const c=u.source;if(c&&typeof c=="object"&&"nodeId"in c&&c.nodeId!==t.node)throw new i(403,"other_app_run","request source must name the calling node")}if(r==="/v1/human/reviews/self/comments"&&e.method==="GET"&&s.get("actor_node_id")!==t.node)throw new i(403,"other_app_run","self review requires the calling node");if(r.includes("/comments")&&e.method!=="GET"&&u.actor_node_id!==t.node)throw new i(403,"other_app_run","comment author must be the calling node");if(o.comment_id&&!E(o.comment_id))throw new i(404,"not_found","comment not found")}a(H,"authorizeHumanBody");function g(e){if(e.class==="person")return[];if(e.class==="app")return e.scopes;const t=e.grant?b(e.grant):T(e.app,e.sub);if(t&&t.grantee===e.app&&t.sub===e.sub)return t.resolved;if(e.app==="app:terminal"&&!W("user").runtime?.issuer)return j;throw new i(401,"grant_revoked","the node grant is not active")}a(g,"resolvedScopes");function p(e){return"class"in e?e.class==="person"?null:e.app:e.grantee}a(p,"runCallerApp");function I(e,t){const o=p(e);if(o===null||o===t)return!0;const s="class"in e?null:b(e.grant),n="class"in e?g(e):s?.sub===e.sub&&s.grantee===e.grantee?s.resolved:[];return h(n,`crtr:conversations:read:${t}`)&&(!("class"in e)||e.class!=="broker"||h(e.scopes,`crtr:conversations:read:${t}`))}a(I,"canReadRun");function de(e,t,o=!1,s=!1){const n=l(t);if(!n||n.parent!==null||n.run_id!==t||!n.grantee||n.deleting_at&&!s)throw new _(404,"not_found","run not found");if(!I(e,n.grantee))throw new _(404,"not_found","run not found");if(o&&p(e)!==null&&p(e)!==n.grantee)throw new _(403,"other_app_run","cannot change another app's run");return U(t,n.grantee,s)}a(de,"requireRun");function q(e,t){return e.class==="person"||e.app===t||h(g(e),`crtr:objects:read:${t}`)&&(e.class!=="broker"||h(e.scopes,`crtr:objects:read:${t}`))}a(q,"canReadNode");function P(e,t,o){if(!e.classes.includes(t.class)&&!e.classes.includes("anonymous"))throw new i(403,"permission_error","this operation is not available to the caller");if(t.class==="person")return;const s=g(t);if(e.scope&&(!h(s,e.scope)||t.class==="broker"&&!h(t.scopes,e.scope)))throw new i(403,"scope_missing",`missing scope ${e.scope}`);if(t.class!=="broker")return;if(e.resource==="daemon-bash"&&(!h(s,"crtr:files:rw:user:.")||!h(t.scopes,"crtr:files:rw:user:.")))throw new i(403,"scope_missing","missing scope crtr:files:rw:user:.");if(e.resource==="human"){const r=e.path,u=e.method==="GET";if(!u&&(r.endsWith("/respond")||r.endsWith("/submit")||r.endsWith("/dismiss")||r.endsWith("/progress")||r.endsWith("/comment-ranges")||r.includes("/feedback-comments")))throw new i(403,"permission_error","only the person may answer or edit the human inbox");const d=o.request_id?J(o.request_id):o.ticket_id?N(o.ticket_id):null,c=o.comment_id?E(o.comment_id):null,w=o.review_id?v(o.review_id):c?v(c.review_id):null,m=d?.requester_node_id??w?.origin_node_id;if(m!=null){const f=l(m);if(f&&(u?!q(t,f.grantee??"app:terminal"):f.grantee!==t.app))throw new i(u?404:403,u?"not_found":"other_app_run","human request belongs to another app")}else if(d||w)throw new i(403,"permission_error","only the person may access a request without a node")}const n=o.id;if(e.resource==="node-own"&&n!==void 0&&n!==t.node)throw new i(403,"other_app_run","the operation requires the calling node");if((e.resource==="node-read"||e.resource==="node-write")&&n!==void 0){const r=l(n);if(!r)return;if(e.resource==="node-write"&&r.grantee!==t.app)throw new i(403,"other_app_run","cannot change another app's node");if(e.resource==="node-read"&&!q(t,r.grantee??"app:terminal"))throw new i(404,"not_found","node not found")}}a(P,"authorizeOperation");function L(e,t){if(!h(e,t))throw new A("the bearer token",t)}a(L,"assertCeiling");function Y(){return new i(403,"owner_only","this operation is owner-only; a scoped token does not reach it")}a(Y,"ownerOnlyError");function ie(e){return e.map(t=>({...t,ownerOnly:!0}))}a(ie,"ownerOnly");const k=4*1024*1024;class ce{static{a(this,"Router")}routes=[];register(t){const o=G(t.method,t.pattern);if(!o)throw new Error(`route has no operation row: ${t.method} ${t.pattern}`);if(this.routes.some(s=>s.method===t.method.toUpperCase()&&s.operation.path===t.pattern))throw new Error(`duplicate route: ${t.method} ${t.pattern}`);return this.routes.push({operation:o,method:t.method.toUpperCase(),segments:x(t.pattern),handler:t.handler}),this}registerAll(t){for(const o of t)this.register(o);return this}match(t,o){const s=t.toUpperCase(),n=x(o);for(const r of this.routes){if(r.method!==s)continue;const u=z(r.segments,n);if(u!==null)return{handler:r.handler,params:u,operation:r.operation}}return null}async handle(t,o,s,n={class:"person"}){try{const r=new URL(t.url??"/","http://127.0.0.1"),u=(t.method??"GET").toUpperCase(),d=this.match(u,r.pathname);if(d===null){C(o,404,"not_found",`no route for ${u} ${r.pathname}`);return}if(P(d.operation,n,d.params),s!==null){if(d.operation.classes.length===1&&d.operation.classes[0]==="person")throw Y();d.operation.scope&&L(s,d.operation.scope)}let c;try{c=await F(t)}catch(f){const y=f instanceof R?"payload_too_large":"invalid_request";C(o,y==="payload_too_large"?413:400,y,f.message);return}n.class==="broker"&&d.operation.resource==="human"&&H(d.operation,n,d.params,r.searchParams,c);const w={method:u,path:r.pathname,params:d.params,query:r.searchParams,body:c,ceiling:s,principal:n,req:t,res:o},m=await d.handler(w);o.writableEnded||V(o,m)}catch(r){const{status:u,body:d}=B(r);u>=500&&O({event:"api.request.failed",level:"error",error:r instanceof Error?r:new Error(String(r)),fields:{method:(t.method??"GET").toUpperCase(),path:t.url??""}}),S(o,u,d)}}}function x(e){return e.split("/").filter(t=>t.length>0)}a(x,"splitPath");function z(e,t){if(e.length!==t.length)return null;const o={};for(let s=0;s<e.length;s++){const n=e[s],r=t[s];if(n.startsWith(":"))o[n.slice(1)]=decodeURIComponent(r);else if(n!==r)return null}return o}a(z,"matchSegments");class R extends Error{static{a(this,"BodyTooLargeError")}}async function F(e){const t=[];let o=0;for await(const n of e){const r=n;if(o+=r.length,o>k)throw new R(`request body exceeds ${k} bytes`);t.push(r)}if(o===0)return;const s=Buffer.concat(t).toString("utf8").trim();if(s!=="")try{return JSON.parse(s)}catch{throw new Error("request body is not valid JSON")}}a(F,"readJsonBody");function V(e,t){if(e.headersSent)return;const o={...t.headers??{}};if(t.rawBody!==void 0){e.writeHead(t.status,o),e.end(t.rawBody);return}if(t.status===204||t.body===void 0){e.writeHead(t.status,o),e.end();return}o["content-type"]===void 0&&(o["content-type"]="application/json; charset=utf-8"),e.writeHead(t.status,o),e.end(JSON.stringify(t.body))}a(V,"writeResult");function S(e,t,o){if(e.headersSent){e.end();return}e.writeHead(t,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}a(S,"writeJson");function C(e,t,o,s){S(e,t,{error:{code:o,message:s}})}a(C,"writeError");export{ce as Router,L as assertCeiling,q as canReadNode,I as canReadRun,ie as ownerOnly,Y as ownerOnlyError,de as requireRun,g as resolvedScopes,p as runCallerApp};
@@ -1,3 +1,5 @@
1
+ import { type IncomingMessage } from 'node:http';
2
+ import { type RequestPrincipal } from './router.js';
1
3
  export interface CreateApiServerOptions {
2
4
  /** Opt-in TCP listener as `host:port` (or `:port` for all interfaces).
3
5
  * Falls back to `CRTRD_TCP`, then the user setting. Absent → unix socket only. */
@@ -13,6 +15,8 @@ export interface ApiServer {
13
15
  /** Tear down both listeners and unlink the socket file. Double-close safe. */
14
16
  close(): Promise<void>;
15
17
  }
18
+ export type SocketPrincipal = RequestPrincipal;
19
+ export declare function socketPrincipal(req: IncomingMessage): SocketPrincipal | undefined;
16
20
  /** Create and start the crtrd API server. Returns immediately with a `close()`
17
21
  * handle and a `ready` promise for the mandatory Unix socket bind. TCP remains
18
22
  * opt-in, and its bind or post-listen accept errors are emitted but non-fatal.