@north-light/crouter 0.3.352 → 0.3.354

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) hide show
  1. package/dist/api/client.d.ts +35 -25
  2. package/dist/api/client.js +2 -2
  3. package/dist/api/dto/broker-ops.d.ts +2 -36
  4. package/dist/api/dto/canvas.d.ts +8 -13
  5. package/dist/api/dto/config.d.ts +4 -0
  6. package/dist/api/dto/delivery.d.ts +61 -0
  7. package/dist/api/dto/docs.d.ts +133 -0
  8. package/dist/api/dto/docs.js +1 -0
  9. package/dist/api/dto/health.d.ts +26 -79
  10. package/dist/api/dto/node-outcomes.d.ts +1 -3
  11. package/dist/api/dto/nodes.d.ts +5 -26
  12. package/dist/api/dto/objects.d.ts +167 -0
  13. package/dist/api/dto/objects.js +1 -0
  14. package/dist/api/dto/profiles.d.ts +14 -8
  15. package/dist/api/dto/reports.d.ts +9 -7
  16. package/dist/api/dto/reviews.d.ts +9 -3
  17. package/dist/api/dto/worktree.d.ts +1 -1
  18. package/dist/api/index.d.ts +0 -1
  19. package/dist/api/index.js +1 -1
  20. package/dist/api/routes.d.ts +14 -12
  21. package/dist/api/routes.js +1 -1
  22. package/dist/build-root.js +1 -1
  23. package/dist/builtin-memory/00-runtime-base/00-authoring.md +10 -5
  24. package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
  25. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +1 -1
  26. package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
  27. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +2 -2
  28. package/dist/builtin-memory/crouter-concepts/INDEX.md +2 -2
  29. package/dist/builtin-memory/crouter-concepts/lifecycle-and-wakes.md +1 -1
  30. package/dist/builtin-memory/crouter-concepts/memory.md +15 -15
  31. package/dist/builtin-memory/crouter-concepts/nodes-and-the-canvas.md +1 -1
  32. package/dist/builtin-memory/crouter-concepts/profiles-kinds-and-modes.md +5 -5
  33. package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +1 -1
  34. package/dist/builtin-memory/crouter-concepts/why-a-daemon.md +1 -1
  35. package/dist/builtin-memory/crouter-sdk/INDEX.md +2 -2
  36. package/dist/builtin-memory/crouter-sdk/README.md +5 -6
  37. package/dist/builtin-memory/crouter-sdk/errors.md +0 -13
  38. package/dist/builtin-memory/crouter-sdk/guides/README.md +0 -1
  39. package/dist/builtin-memory/crouter-sdk/guides/event-driven-assistant.md +2 -2
  40. package/dist/builtin-memory/crouter-sdk/nodes.md +0 -2
  41. package/dist/builtin-memory/crouter-sdk/resources.md +0 -1
  42. package/dist/builtin-memory/explore/exploration-doc.md +4 -4
  43. package/dist/builtin-memory/insights/capture.md +6 -6
  44. package/dist/builtin-memory/insights/init.md +14 -14
  45. package/dist/builtin-memory/internal/INDEX.md +4 -4
  46. package/dist/builtin-memory/internal/agent-shaping.md +20 -20
  47. package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
  48. package/dist/builtin-memory/internal/marketplaces.md +2 -2
  49. package/dist/builtin-memory/internal/memory-loading.md +31 -30
  50. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  51. package/dist/builtin-memory/internal/plugins.md +16 -14
  52. package/dist/builtin-memory/internal/storage-tiers.md +4 -4
  53. package/dist/builtin-memory/memory-read-orientation.md +1 -1
  54. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +32 -40
  55. package/dist/clients/attach/input/controller.js +1 -1
  56. package/dist/clients/attach/input/ref-autocomplete.js +1 -1
  57. package/dist/clients/attach/input/titled-editor.js +1 -1
  58. package/dist/clients/attach/render/chat-view.js +1 -1
  59. package/dist/clients/attach/render/crtr-output.d.ts +1 -2
  60. package/dist/clients/attach/render/crtr-output.js +17 -17
  61. package/dist/clients/attach/render/group-activity.d.ts +8 -8
  62. package/dist/clients/attach/render/group-activity.js +2 -2
  63. package/dist/clients/attach/render/group-recap.js +1 -1
  64. package/dist/clients/attach/render/tool-calls.d.ts +1 -1
  65. package/dist/clients/attach/session/profile-files.js +1 -1
  66. package/dist/clients/attach/slash/dispatch.js +1 -1
  67. package/dist/clients/attach/viewer.js +806 -1553
  68. package/dist/commands/api-client.d.ts +2 -0
  69. package/dist/commands/api-client.js +3 -3
  70. package/dist/commands/canvas/edges.d.ts +2 -0
  71. package/dist/commands/canvas/edges.js +2 -0
  72. package/dist/commands/canvas/list.d.ts +4 -0
  73. package/dist/commands/canvas/list.js +3 -0
  74. package/dist/commands/canvas/read.d.ts +8 -0
  75. package/dist/commands/canvas/read.js +5 -0
  76. package/dist/commands/canvas/search.d.ts +2 -0
  77. package/dist/commands/canvas/search.js +3 -0
  78. package/dist/commands/canvas/unwatch.d.ts +2 -0
  79. package/dist/commands/canvas/unwatch.js +1 -0
  80. package/dist/commands/canvas/watch.d.ts +3 -0
  81. package/dist/commands/canvas/watch.js +1 -0
  82. package/dist/commands/canvas-analytics.js +1 -1
  83. package/dist/commands/canvas-history/grep.js +4 -4
  84. package/dist/commands/canvas-history/read.js +2 -2
  85. package/dist/commands/canvas-history/search.js +7 -7
  86. package/dist/commands/canvas-history/shared.d.ts +0 -1
  87. package/dist/commands/canvas-history/shared.js +1 -1
  88. package/dist/commands/canvas-history/stats.js +2 -2
  89. package/dist/commands/canvas-history.js +1 -1
  90. package/dist/commands/canvas.js +1 -1
  91. package/dist/commands/doc/delete.d.ts +2 -0
  92. package/dist/commands/doc/delete.js +1 -0
  93. package/dist/commands/doc/edit.d.ts +2 -0
  94. package/dist/commands/doc/edit.js +1 -0
  95. package/dist/commands/doc/history.d.ts +2 -0
  96. package/dist/commands/doc/history.js +2 -0
  97. package/dist/commands/doc/lint.d.ts +2 -0
  98. package/dist/commands/doc/lint.js +2 -0
  99. package/dist/commands/doc/list.d.ts +2 -0
  100. package/dist/commands/doc/list.js +1 -0
  101. package/dist/commands/doc/move.d.ts +2 -0
  102. package/dist/commands/doc/move.js +1 -0
  103. package/dist/commands/doc/read.d.ts +2 -0
  104. package/dist/commands/doc/read.js +1 -0
  105. package/dist/commands/doc/shared.d.ts +25 -0
  106. package/dist/commands/doc/shared.js +2 -0
  107. package/dist/commands/doc/write.d.ts +2 -0
  108. package/dist/commands/doc/write.js +1 -0
  109. package/dist/commands/{memory.d.ts → doc.d.ts} +1 -1
  110. package/dist/commands/doc.js +1 -0
  111. package/dist/commands/human/review.js +1 -1
  112. package/dist/commands/node/bash.js +2 -2
  113. package/dist/commands/node/create.js +1 -1
  114. package/dist/commands/node/inspect.js +10 -10
  115. package/dist/commands/node/lifecycle.js +2 -2
  116. package/dist/commands/node/outcome.js +1 -1
  117. package/dist/commands/node/subscription.js +1 -1
  118. package/dist/commands/node-context.js +2 -2
  119. package/dist/commands/pkg/browse/catalog.js +1 -1
  120. package/dist/commands/pkg/browse/doc-view.js +1 -1
  121. package/dist/commands/pkg/browse/model.d.ts +9 -17
  122. package/dist/commands/pkg/plugin-inspect.js +1 -1
  123. package/dist/commands/pkg/plugin-manage.d.ts +4 -8
  124. package/dist/commands/pkg/plugin-manage.js +15 -17
  125. package/dist/commands/profile/list.js +1 -1
  126. package/dist/commands/profile/new.js +1 -1
  127. package/dist/commands/profile/project.js +1 -1
  128. package/dist/commands/profile/show.js +1 -1
  129. package/dist/commands/push.js +3 -3
  130. package/dist/commands/sys/config.js +1 -1
  131. package/dist/commands/sys/context/admin/actions.d.ts +18 -43
  132. package/dist/commands/sys/context/admin/actions.js +1 -2
  133. package/dist/commands/sys/context/admin/detail-panel.d.ts +17 -25
  134. package/dist/commands/sys/context/admin/detail-panel.js +2 -1
  135. package/dist/commands/sys/context/admin/docs-panel.d.ts +7 -6
  136. package/dist/commands/sys/context/admin/docs-panel.js +1 -1
  137. package/dist/commands/sys/context/admin/list-view.d.ts +12 -12
  138. package/dist/commands/sys/context/admin/list-view.js +1 -1
  139. package/dist/commands/sys/context/admin/model.d.ts +96 -69
  140. package/dist/commands/sys/context/admin/model.js +1 -1
  141. package/dist/commands/sys/context/admin/rail-panel.d.ts +7 -5
  142. package/dist/commands/sys/context/admin/rail-panel.js +1 -1
  143. package/dist/commands/sys/context/admin/read-view.d.ts +10 -14
  144. package/dist/commands/sys/context/admin/read-view.js +1 -2
  145. package/dist/commands/sys/context/admin/shell.d.ts +26 -31
  146. package/dist/commands/sys/context/admin/shell.js +1 -1
  147. package/dist/commands/sys/context/admin.js +2 -2
  148. package/dist/commands/sys/context/doc.js +2 -3
  149. package/dist/commands/sys/context/expose.js +2 -2
  150. package/dist/commands/sys/context/prompt-review.js +4 -4
  151. package/dist/commands/sys/context/resolve.d.ts +92 -65
  152. package/dist/commands/sys/context/resolve.js +7 -9
  153. package/dist/commands/sys/context.js +1 -1
  154. package/dist/commands/sys/doctor.js +1 -1
  155. package/dist/commands/sys/migrate.js +1 -1
  156. package/dist/commands/sys/panels/profiles-panel.d.ts +3 -1
  157. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  158. package/dist/commands/sys/sync-deps.d.ts +6 -11
  159. package/dist/commands/sys/sync-deps.js +7 -8
  160. package/dist/commands/sys/sync-project-guidance.js +5 -4
  161. package/dist/commands/sys/sync-shared.d.ts +41 -4
  162. package/dist/commands/sys/sync-shared.js +1 -1
  163. package/dist/commands/sys/sync-skills.js +2 -2
  164. package/dist/commands/sys/sync.js +1 -1
  165. package/dist/core/bash-job-supervisor.d.ts +2 -3
  166. package/dist/core/bash-job-supervisor.js +3 -3
  167. package/dist/core/bash-jobs.d.ts +0 -5
  168. package/dist/core/bash-jobs.js +7 -7
  169. package/dist/core/bootstrap.js +2 -2
  170. package/dist/core/canvas/canvas.d.ts +6 -50
  171. package/dist/core/canvas/canvas.js +16 -21
  172. package/dist/core/canvas/db.d.ts +4 -1
  173. package/dist/core/canvas/db.js +2 -2
  174. package/dist/core/canvas/history.d.ts +11 -39
  175. package/dist/core/canvas/history.js +9 -20
  176. package/dist/core/canvas/install-id.d.ts +2 -2
  177. package/dist/core/canvas/install-id.js +1 -1
  178. package/dist/core/canvas/memory-reads.d.ts +5 -0
  179. package/dist/core/canvas/memory-reads.js +1 -1
  180. package/dist/core/canvas/migrations.js +215 -41
  181. package/dist/core/canvas/node-agent-paths.js +1 -1
  182. package/dist/core/canvas/node-tokens.js +1 -1
  183. package/dist/core/canvas/paths.d.ts +0 -4
  184. package/dist/core/canvas/paths.js +1 -1
  185. package/dist/core/canvas/remote-canvas-source.d.ts +0 -1
  186. package/dist/core/canvas/remote-canvas-source.js +1 -1
  187. package/dist/core/canvas/render-source.d.ts +9 -6
  188. package/dist/core/canvas/render-source.js +6 -6
  189. package/dist/core/canvas/sessions.js +2 -2
  190. package/dist/core/canvas/source.d.ts +6 -0
  191. package/dist/core/canvas/tree.d.ts +29 -0
  192. package/dist/core/canvas/tree.js +12 -0
  193. package/dist/core/canvas/types.d.ts +0 -20
  194. package/dist/core/command-plugins/bundle.js +1 -1
  195. package/dist/core/config.d.ts +1 -1
  196. package/dist/core/conversation-store/listener.js +4 -2
  197. package/dist/core/feed/feed.d.ts +9 -7
  198. package/dist/core/feed/feed.js +3 -7
  199. package/dist/core/feed/inbox.d.ts +3 -5
  200. package/dist/core/feed/inbox.js +1 -10
  201. package/dist/core/feed/messages.d.ts +33 -6
  202. package/dist/core/feed/messages.js +10 -7
  203. package/dist/core/feed/reports.d.ts +10 -0
  204. package/dist/core/feed/reports.js +2 -0
  205. package/dist/core/grants/remove.js +1 -1
  206. package/dist/core/graph/access.d.ts +24 -0
  207. package/dist/core/graph/access.js +8 -0
  208. package/dist/core/graph/bodies.d.ts +6 -0
  209. package/dist/core/graph/bodies.js +1 -0
  210. package/dist/core/graph/deletion.d.ts +9 -0
  211. package/dist/core/graph/deletion.js +5 -0
  212. package/dist/core/graph/diff.d.ts +4 -0
  213. package/dist/core/graph/diff.js +4 -0
  214. package/dist/core/graph/documents.d.ts +160 -0
  215. package/dist/core/graph/documents.js +7 -0
  216. package/dist/core/graph/edges.d.ts +24 -0
  217. package/dist/core/graph/edges.js +1 -0
  218. package/dist/core/graph/events.d.ts +26 -0
  219. package/dist/core/graph/events.js +6 -0
  220. package/dist/core/graph/exposures.d.ts +53 -0
  221. package/dist/core/graph/exposures.js +4 -0
  222. package/dist/core/graph/jobs.d.ts +31 -0
  223. package/dist/core/graph/jobs.js +2 -0
  224. package/dist/core/graph/names.d.ts +28 -0
  225. package/dist/core/graph/names.js +3 -0
  226. package/dist/core/graph/objects.d.ts +55 -0
  227. package/dist/core/graph/objects.js +9 -0
  228. package/dist/core/graph/package-docs.d.ts +31 -0
  229. package/dist/core/graph/package-docs.js +5 -0
  230. package/dist/core/graph/package-files.d.ts +20 -0
  231. package/dist/core/graph/package-files.js +2 -0
  232. package/dist/core/graph/reader.d.ts +21 -0
  233. package/dist/core/graph/reader.js +3 -0
  234. package/dist/core/graph/repo-sync/exchange.d.ts +34 -0
  235. package/dist/core/graph/repo-sync/exchange.js +2 -0
  236. package/dist/core/graph/repo-sync/identity.d.ts +30 -0
  237. package/dist/core/graph/repo-sync/identity.js +1 -0
  238. package/dist/core/graph/repo-sync/index.d.ts +4 -0
  239. package/dist/core/graph/repo-sync/index.js +1 -0
  240. package/dist/core/graph/repo-sync/mirror.d.ts +30 -0
  241. package/dist/core/graph/repo-sync/mirror.js +6 -0
  242. package/dist/core/graph/repo-sync/ref-format.d.ts +76 -0
  243. package/dist/core/graph/repo-sync/ref-format.js +2 -0
  244. package/dist/core/graph/repo-sync/repos.d.ts +17 -0
  245. package/dist/core/graph/repo-sync/repos.js +3 -0
  246. package/dist/core/graph/repo-sync/sync.d.ts +42 -0
  247. package/dist/core/graph/repo-sync/sync.js +2 -0
  248. package/dist/core/graph/rules.d.ts +26 -0
  249. package/dist/core/graph/rules.js +3 -0
  250. package/dist/core/graph/spaces/app.d.ts +3 -0
  251. package/dist/core/graph/spaces/app.js +1 -0
  252. package/dist/core/graph/spaces/index.d.ts +19 -0
  253. package/dist/core/graph/spaces/index.js +1 -0
  254. package/dist/core/graph/spaces/person.d.ts +5 -0
  255. package/dist/core/graph/spaces/person.js +2 -0
  256. package/dist/core/graph/spaces/repo.d.ts +4 -0
  257. package/dist/core/graph/spaces/repo.js +1 -0
  258. package/dist/core/graph/types.d.ts +75 -0
  259. package/dist/core/graph/types.js +1 -0
  260. package/dist/core/graph/watches.d.ts +62 -0
  261. package/dist/core/graph/watches.js +18 -0
  262. package/dist/core/human/feedback-companion.js +1 -1
  263. package/dist/core/human/requests.d.ts +3 -1
  264. package/dist/core/human/requests.js +6 -6
  265. package/dist/core/inspector/model.js +2 -2
  266. package/dist/core/io.js +5 -5
  267. package/dist/core/layout-migrate/index.d.ts +24 -1
  268. package/dist/core/layout-migrate/index.js +4 -4
  269. package/dist/core/layout-migrate/paths.d.ts +4 -0
  270. package/dist/core/layout-migrate/paths.js +1 -1
  271. package/dist/core/layout-migrate/stored-paths.d.ts +7 -0
  272. package/dist/core/layout-migrate/stored-paths.js +11 -11
  273. package/dist/core/layout-migrate/stores.d.ts +19 -6
  274. package/dist/core/layout-migrate/stores.js +3 -4
  275. package/dist/core/manifest.d.ts +0 -2
  276. package/dist/core/manifest.js +1 -1
  277. package/dist/core/{memory/extensions.d.ts → plugin-extensions.d.ts} +9 -10
  278. package/dist/core/plugin-extensions.js +1 -0
  279. package/dist/core/preview-registry.d.ts +1 -1
  280. package/dist/core/preview-registry.js +3 -2
  281. package/dist/core/profiles/manifest.d.ts +7 -7
  282. package/dist/core/profiles/manifest.js +1 -1
  283. package/dist/core/profiles/select.js +3 -3
  284. package/dist/core/review/birth.js +1 -1
  285. package/dist/core/review/companion.js +1 -1
  286. package/dist/core/review/stage.d.ts +12 -1
  287. package/dist/core/review/stage.js +1 -1
  288. package/dist/core/review/store.d.ts +2 -0
  289. package/dist/core/review/store.js +1 -1
  290. package/dist/core/review/types.d.ts +7 -1
  291. package/dist/core/runs/events.js +1 -1
  292. package/dist/core/runs/operations.js +5 -5
  293. package/dist/core/runs/questions.js +2 -2
  294. package/dist/core/runtime/bearings-render.d.ts +13 -7
  295. package/dist/core/runtime/bearings-render.js +12 -12
  296. package/dist/core/runtime/bearings.d.ts +8 -18
  297. package/dist/core/runtime/bearings.js +7 -7
  298. package/dist/core/runtime/broker/daemon-ops.d.ts +7 -12
  299. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  300. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  301. package/dist/core/runtime/broker/fault-retry.js +1 -1
  302. package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
  303. package/dist/core/runtime/broker/frame-memory-refs.d.ts +7 -2
  304. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  305. package/dist/core/runtime/broker/inbox.d.ts +1 -4
  306. package/dist/core/runtime/broker/inbox.js +1 -10
  307. package/dist/core/runtime/broker/rebind.js +1 -1
  308. package/dist/core/runtime/broker/retry-card-elision.d.ts +7 -0
  309. package/dist/core/runtime/broker/retry-card-elision.js +1 -0
  310. package/dist/core/runtime/broker-extension-render.d.ts +0 -13
  311. package/dist/core/runtime/broker-extension-render.js +2 -4
  312. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  313. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  314. package/dist/core/runtime/broker.js +1 -1
  315. package/dist/core/runtime/close.d.ts +9 -4
  316. package/dist/core/runtime/close.js +1 -1
  317. package/dist/core/runtime/deliver-live.js +1 -1
  318. package/dist/core/runtime/kickoff.js +17 -19
  319. package/dist/core/runtime/launch-target.d.ts +7 -0
  320. package/dist/core/runtime/launch-target.js +1 -1
  321. package/dist/core/runtime/ledger.d.ts +10 -0
  322. package/dist/core/runtime/ledger.js +3 -0
  323. package/dist/core/runtime/lifecycle.js +2 -2
  324. package/dist/core/runtime/nodes.d.ts +10 -2
  325. package/dist/core/runtime/nodes.js +1 -1
  326. package/dist/core/runtime/outcome-document.d.ts +2 -2
  327. package/dist/core/runtime/outcome-document.js +1 -1
  328. package/dist/core/runtime/persona.js +2 -2
  329. package/dist/core/runtime/placement.js +1 -1
  330. package/dist/core/runtime/promote.d.ts +2 -2
  331. package/dist/core/runtime/promote.js +1 -1
  332. package/dist/core/runtime/prospective-inventory-cli.js +2 -2
  333. package/dist/core/runtime/recycle.js +1 -1
  334. package/dist/core/runtime/reopen.js +1 -1
  335. package/dist/core/runtime/revive.js +2 -2
  336. package/dist/core/runtime/roadmap.d.ts +17 -9
  337. package/dist/core/runtime/roadmap.js +4 -4
  338. package/dist/core/runtime/spawn-env.js +1 -1
  339. package/dist/core/runtime/spawn.d.ts +5 -3
  340. package/dist/core/runtime/spawn.js +2 -2
  341. package/dist/core/runtime/structured-output.d.ts +3 -1
  342. package/dist/core/runtime/structured-output.js +4 -4
  343. package/dist/core/scope.d.ts +1 -32
  344. package/dist/core/scope.js +1 -1
  345. package/dist/core/scoped-state/db.js +2 -1
  346. package/dist/core/scoped-state/migrate.js +2 -2
  347. package/dist/core/scoped-state/profiles.d.ts +11 -0
  348. package/dist/core/scoped-state/profiles.js +1 -1
  349. package/dist/core/scoped-state/schema.d.ts +1 -1
  350. package/dist/core/scoped-state/schema.js +7 -5
  351. package/dist/core/spaces/permissions.d.ts +0 -14
  352. package/dist/core/spaces/permissions.js +1 -1
  353. package/dist/core/spaces/stop.d.ts +13 -0
  354. package/dist/core/spaces/stop.js +2 -2
  355. package/dist/core/storage/tables.d.ts +1 -1
  356. package/dist/core/substrate/delivery/corpus.d.ts +21 -0
  357. package/dist/core/substrate/delivery/corpus.js +3 -0
  358. package/dist/core/substrate/delivery/deliver.d.ts +76 -0
  359. package/dist/core/substrate/delivery/deliver.js +6 -0
  360. package/dist/core/substrate/delivery/listings.d.ts +27 -0
  361. package/dist/core/substrate/delivery/listings.js +4 -0
  362. package/dist/core/substrate/delivery/match.d.ts +28 -0
  363. package/dist/core/substrate/delivery/match.js +1 -0
  364. package/dist/core/substrate/delivery/plan.d.ts +67 -0
  365. package/dist/core/substrate/delivery/plan.js +3 -0
  366. package/dist/core/substrate/delivery/render-boot.d.ts +20 -0
  367. package/dist/core/substrate/delivery/render-boot.js +54 -0
  368. package/dist/core/substrate/delivery/render-event.d.ts +47 -0
  369. package/dist/core/substrate/delivery/render-event.js +6 -0
  370. package/dist/core/substrate/delivery/sub-persona-menu.d.ts +2 -0
  371. package/dist/core/substrate/delivery/sub-persona-menu.js +6 -0
  372. package/dist/core/substrate/delivery/types.d.ts +30 -0
  373. package/dist/core/substrate/delivery/types.js +0 -0
  374. package/dist/core/substrate/gate-explain.d.ts +0 -13
  375. package/dist/core/substrate/gate-explain.js +1 -1
  376. package/dist/core/substrate/schema.d.ts +11 -139
  377. package/dist/core/substrate/schema.js +1 -1
  378. package/dist/core/substrate/subject-fields.d.ts +3 -0
  379. package/dist/core/substrate/subject.d.ts +2 -1
  380. package/dist/core/substrate/subject.js +1 -1
  381. package/dist/daemon/api/app-listener.js +11 -11
  382. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  383. package/dist/daemon/api/handlers/bash-jobs.js +1 -2
  384. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  385. package/dist/daemon/api/handlers/canvas.js +5 -5
  386. package/dist/daemon/api/handlers/daemon.js +1 -1
  387. package/dist/daemon/api/handlers/delivery.d.ts +2 -0
  388. package/dist/daemon/api/handlers/delivery.js +1 -0
  389. package/dist/daemon/api/handlers/{memory.d.ts → docs.d.ts} +1 -1
  390. package/dist/daemon/api/handlers/docs.js +1 -0
  391. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  392. package/dist/daemon/api/handlers/messages.js +2 -2
  393. package/dist/daemon/api/handlers/modelauth.d.ts +3 -0
  394. package/dist/daemon/api/handlers/modelauth.js +1 -1
  395. package/dist/daemon/api/handlers/node-records.js +2 -2
  396. package/dist/daemon/api/handlers/nodes.js +1 -1
  397. package/dist/daemon/api/handlers/objects.d.ts +2 -0
  398. package/dist/daemon/api/handlers/objects.js +5 -0
  399. package/dist/daemon/api/handlers/package-docs.d.ts +2 -0
  400. package/dist/daemon/api/handlers/package-docs.js +1 -0
  401. package/dist/daemon/api/handlers/profiles.js +1 -1
  402. package/dist/daemon/api/handlers/reports.d.ts +2 -2
  403. package/dist/daemon/api/handlers/reports.js +4 -4
  404. package/dist/daemon/api/handlers/reviews.js +1 -1
  405. package/dist/daemon/api/handlers/vendor-status.d.ts +8 -0
  406. package/dist/daemon/api/handlers/vendor-status.js +1 -0
  407. package/dist/daemon/api/map.d.ts +2 -2
  408. package/dist/daemon/api/map.js +2 -2
  409. package/dist/daemon/api/operations.d.ts +1 -1
  410. package/dist/daemon/api/operations.js +1 -1
  411. package/dist/daemon/api/principal.d.ts +5 -0
  412. package/dist/daemon/api/principal.js +1 -1
  413. package/dist/daemon/api/reader.d.ts +17 -0
  414. package/dist/daemon/api/reader.js +1 -0
  415. package/dist/daemon/api/server.js +1 -1
  416. package/dist/daemon/control.d.ts +2 -3
  417. package/dist/daemon/crtrd.js +8 -6
  418. package/dist/daemon/fleet.js +4 -4
  419. package/dist/daemon/reconcilers/bash-deadline.d.ts +11 -1
  420. package/dist/daemon/reconcilers/bash-deadline.js +2 -1
  421. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  422. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  423. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  424. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  425. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -0
  426. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  427. package/dist/daemon/review/deliver.js +2 -2
  428. package/dist/daemon/review/finish.js +1 -1
  429. package/dist/hook-authoring.d.ts +0 -1
  430. package/dist/hook-authoring.js +3 -3
  431. package/dist/migrations/004-canvas-documents/apply.d.ts +10 -0
  432. package/dist/migrations/004-canvas-documents/apply.js +1 -0
  433. package/dist/migrations/004-canvas-documents/fields.d.ts +24 -0
  434. package/dist/migrations/004-canvas-documents/fields.js +2 -0
  435. package/dist/migrations/004-canvas-documents/index.d.ts +16 -0
  436. package/dist/migrations/004-canvas-documents/index.js +2 -0
  437. package/dist/migrations/004-canvas-documents/legacy/discover.d.ts +16 -0
  438. package/dist/migrations/004-canvas-documents/legacy/discover.js +1 -0
  439. package/dist/migrations/004-canvas-documents/legacy/history.d.ts +5 -0
  440. package/dist/migrations/004-canvas-documents/legacy/history.js +2 -0
  441. package/dist/migrations/004-canvas-documents/legacy/nested.d.ts +7 -0
  442. package/dist/migrations/004-canvas-documents/legacy/nested.js +1 -0
  443. package/dist/migrations/004-canvas-documents/legacy/parse.d.ts +14 -0
  444. package/dist/migrations/004-canvas-documents/legacy/parse.js +1 -0
  445. package/dist/migrations/004-canvas-documents/legacy/types.d.ts +91 -0
  446. package/dist/migrations/004-canvas-documents/legacy/types.js +0 -0
  447. package/dist/migrations/004-canvas-documents/legacy-edges.d.ts +6 -0
  448. package/dist/migrations/004-canvas-documents/legacy-edges.js +18 -0
  449. package/dist/migrations/004-canvas-documents/plan.d.ts +102 -0
  450. package/dist/migrations/004-canvas-documents/plan.js +3 -0
  451. package/dist/migrations/004-canvas-documents/pointers.d.ts +23 -0
  452. package/dist/migrations/004-canvas-documents/pointers.js +4 -0
  453. package/dist/migrations/activation.d.ts +9 -18
  454. package/dist/migrations/activation.js +2 -2
  455. package/dist/pi-extensions/broker-local.d.ts +2 -2
  456. package/dist/pi-extensions/broker-local.js +2 -2
  457. package/dist/pi-extensions/canvas-bash-valve.js +5 -4
  458. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  459. package/dist/pi-extensions/canvas-doc-substrate.d.ts +0 -1
  460. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  461. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  462. package/dist/pi-extensions/canvas-passive-context.js +1 -1
  463. package/dist/pi-extensions/canvas-recap.js +2 -2
  464. package/dist/pi-extensions/canvas-stophook.d.ts +1 -1
  465. package/dist/pi-extensions/canvas-stophook.js +1 -1
  466. package/dist/prompts/review.js +3 -3
  467. package/dist/shared/env.d.ts +5 -0
  468. package/dist/shared/env.js +1 -1
  469. package/dist/shared/generated-context.js +2 -10
  470. package/dist/shared/inbox-entry-body.d.ts +22 -0
  471. package/dist/shared/inbox-entry-body.js +10 -0
  472. package/dist/{core/memory → shared}/inline-ref-guidance.d.ts +2 -2
  473. package/dist/shared/inline-ref-guidance.js +2 -0
  474. package/dist/types.d.ts +3 -1
  475. package/docs/cli/memory-and-preferences.md +12 -14
  476. package/docs/concepts/README.md +1 -1
  477. package/docs/concepts/lifecycle-and-wakes.md +1 -1
  478. package/docs/concepts/memory.md +15 -15
  479. package/docs/concepts/nodes-and-the-canvas.md +1 -1
  480. package/docs/concepts/profiles-kinds-and-modes.md +5 -5
  481. package/docs/concepts/scopes-and-trust.md +1 -1
  482. package/docs/concepts/why-a-daemon.md +1 -1
  483. package/docs/sdk/README.md +5 -6
  484. package/docs/sdk/errors.md +0 -13
  485. package/docs/sdk/guides/README.md +0 -1
  486. package/docs/sdk/nodes.md +0 -2
  487. package/docs/sdk/resources.md +0 -1
  488. package/package.json +2 -2
  489. package/packages/crouter-identity/package.json +1 -1
  490. package/runtime.lock.json +11 -11
  491. package/dist/api/dto/memory.d.ts +0 -171
  492. package/dist/api/dto/memory.js +0 -1
  493. package/dist/builtin-memory/crouter-sdk/guides/app-memory.md +0 -73
  494. package/dist/builtin-memory/crouter-sdk/memory.md +0 -87
  495. package/dist/commands/broker-permissions.d.ts +0 -2
  496. package/dist/commands/broker-permissions.js +0 -1
  497. package/dist/commands/memory/client.d.ts +0 -11
  498. package/dist/commands/memory/client.js +0 -1
  499. package/dist/commands/memory/delete.d.ts +0 -1
  500. package/dist/commands/memory/delete.js +0 -1
  501. package/dist/commands/memory/edit.d.ts +0 -1
  502. package/dist/commands/memory/edit.js +0 -21
  503. package/dist/commands/memory/find.d.ts +0 -1
  504. package/dist/commands/memory/find.js +0 -1
  505. package/dist/commands/memory/history.d.ts +0 -1
  506. package/dist/commands/memory/history.js +0 -5
  507. package/dist/commands/memory/lint.d.ts +0 -1
  508. package/dist/commands/memory/lint.js +0 -1
  509. package/dist/commands/memory/list.d.ts +0 -1
  510. package/dist/commands/memory/list.js +0 -1
  511. package/dist/commands/memory/move.d.ts +0 -1
  512. package/dist/commands/memory/move.js +0 -1
  513. package/dist/commands/memory/origin.d.ts +0 -1
  514. package/dist/commands/memory/origin.js +0 -1
  515. package/dist/commands/memory/read.d.ts +0 -1
  516. package/dist/commands/memory/read.js +0 -6
  517. package/dist/commands/memory/shared.d.ts +0 -22
  518. package/dist/commands/memory/shared.js +0 -1
  519. package/dist/commands/memory/write.d.ts +0 -1
  520. package/dist/commands/memory/write.js +0 -13
  521. package/dist/commands/memory.js +0 -1
  522. package/dist/commands/node-inspect-artifacts.d.ts +0 -1
  523. package/dist/commands/node-inspect-artifacts.js +0 -8
  524. package/dist/core/help/memory-extensions.d.ts +0 -3
  525. package/dist/core/help/memory-extensions.js +0 -2
  526. package/dist/core/memory/cli-selector.d.ts +0 -13
  527. package/dist/core/memory/cli-selector.js +0 -1
  528. package/dist/core/memory/doc-link-grammar.d.ts +0 -20
  529. package/dist/core/memory/doc-link-grammar.js +0 -2
  530. package/dist/core/memory/extensions.js +0 -1
  531. package/dist/core/memory/history.d.ts +0 -87
  532. package/dist/core/memory/history.js +0 -6
  533. package/dist/core/memory/identity.d.ts +0 -65
  534. package/dist/core/memory/identity.js +0 -1
  535. package/dist/core/memory/inline-ref-guidance.js +0 -2
  536. package/dist/core/memory/inline-ref-inventory.d.ts +0 -9
  537. package/dist/core/memory/inline-ref-inventory.js +0 -1
  538. package/dist/core/memory/lint.d.ts +0 -163
  539. package/dist/core/memory/lint.js +0 -2
  540. package/dist/core/memory/mutation-domain.d.ts +0 -113
  541. package/dist/core/memory/mutation-domain.js +0 -12
  542. package/dist/core/memory/mutations.d.ts +0 -74
  543. package/dist/core/memory/mutations.js +0 -1
  544. package/dist/core/memory/project-namespace.d.ts +0 -31
  545. package/dist/core/memory/project-namespace.js +0 -2
  546. package/dist/core/memory/repository-association.d.ts +0 -31
  547. package/dist/core/memory/repository-association.js +0 -1
  548. package/dist/core/memory/service.d.ts +0 -145
  549. package/dist/core/memory/service.js +0 -2
  550. package/dist/core/memory/tree.d.ts +0 -39
  551. package/dist/core/memory/tree.js +0 -1
  552. package/dist/core/memory-resolver.d.ts +0 -280
  553. package/dist/core/memory-resolver.js +0 -2
  554. package/dist/core/nested-stores.d.ts +0 -18
  555. package/dist/core/nested-stores.js +0 -1
  556. package/dist/core/runtime/memory.d.ts +0 -3
  557. package/dist/core/runtime/memory.js +0 -1
  558. package/dist/core/substrate/frontmatter-validation.d.ts +0 -11
  559. package/dist/core/substrate/frontmatter-validation.js +0 -1
  560. package/dist/core/substrate/gate.d.ts +0 -16
  561. package/dist/core/substrate/gate.js +0 -1
  562. package/dist/core/substrate/index.d.ts +0 -18
  563. package/dist/core/substrate/index.js +0 -1
  564. package/dist/core/substrate/injected-store.d.ts +0 -75
  565. package/dist/core/substrate/injected-store.js +0 -2
  566. package/dist/core/substrate/listings.d.ts +0 -28
  567. package/dist/core/substrate/listings.js +0 -1
  568. package/dist/core/substrate/memory-events.d.ts +0 -6
  569. package/dist/core/substrate/memory-events.js +0 -1
  570. package/dist/core/substrate/on-read-node.d.ts +0 -6
  571. package/dist/core/substrate/on-read-node.js +0 -1
  572. package/dist/core/substrate/on-read.d.ts +0 -101
  573. package/dist/core/substrate/on-read.js +0 -9
  574. package/dist/core/substrate/plan.d.ts +0 -94
  575. package/dist/core/substrate/plan.js +0 -1
  576. package/dist/core/substrate/render-node.d.ts +0 -12
  577. package/dist/core/substrate/render-node.js +0 -1
  578. package/dist/core/substrate/render.d.ts +0 -41
  579. package/dist/core/substrate/render.js +0 -65
  580. package/dist/core/substrate/session-cache.d.ts +0 -27
  581. package/dist/core/substrate/session-cache.js +0 -1
  582. package/dist/core/substrate/surface-match.d.ts +0 -73
  583. package/dist/core/substrate/surface-match.js +0 -1
  584. package/dist/daemon/api/handlers/memory.js +0 -5
  585. package/dist/migrations/001-surfaces-frontmatter.d.ts +0 -2
  586. package/dist/migrations/001-surfaces-frontmatter.js +0 -1
  587. package/dist/migrations/002-profile-project-memory.d.ts +0 -2
  588. package/dist/migrations/002-profile-project-memory.js +0 -1
  589. package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +0 -26
  590. package/dist/migrations/003-repository-root-memory-identity/front-door.js +0 -11
  591. package/dist/migrations/003-repository-root-memory-identity/index.d.ts +0 -2
  592. package/dist/migrations/003-repository-root-memory-identity/index.js +0 -5
  593. package/dist/migrations/003-repository-root-memory-identity/references.d.ts +0 -95
  594. package/dist/migrations/003-repository-root-memory-identity/references.js +0 -5
  595. package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +0 -39
  596. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +0 -3
  597. package/dist/migrations/convergent.d.ts +0 -43
  598. package/dist/migrations/convergent.js +0 -2
  599. package/dist/migrations/corpus.d.ts +0 -75
  600. package/dist/migrations/corpus.js +0 -3
  601. package/dist/migrations/frontmatter-splice.d.ts +0 -15
  602. package/dist/migrations/frontmatter-splice.js +0 -8
  603. package/dist/migrations/profile-manifests.d.ts +0 -30
  604. package/dist/migrations/profile-manifests.js +0 -2
  605. package/dist/migrations/registry.d.ts +0 -7
  606. package/dist/migrations/registry.js +0 -1
  607. package/dist/migrations/runner.d.ts +0 -43
  608. package/dist/migrations/runner.js +0 -1
  609. package/dist/migrations/types.d.ts +0 -211
  610. package/dist/shared/birth-announcement.d.ts +0 -12
  611. package/dist/shared/birth-announcement.js +0 -1
  612. package/docs/sdk/guides/app-memory.md +0 -22
  613. package/docs/sdk/memory.md +0 -85
  614. /package/dist/{migrations/types.js → api/dto/delivery.js} +0 -0
  615. /package/dist/{core/memory → shared}/inline-ref-grammar.d.ts +0 -0
  616. /package/dist/{core/memory → shared}/inline-ref-grammar.js +0 -0
@@ -1,4 +1,5 @@
1
- var te=Object.defineProperty;var o=(r,n)=>te(r,"name",{value:n,configurable:!0});import{envBashAutoBgDeadlineMs as oe,envBashValveMs as ie,envNodeId as se}from"../shared/env.js";import{spawn as de}from"node:child_process";import{closeSync as ae,existsSync as B,mkdirSync as G,openSync as ce,readFileSync as ue,readSync as fe,rmSync as V,statSync as K,writeFileSync as y}from"node:fs";import{homedir as le}from"node:os";import{dirname as be}from"node:path";import{performance as O}from"node:perf_hooks";import{backgroundBashJob as z,bashJobPaths as pe,cancelBashJobProcessTree as he,formatBashElapsed as q,newBashJobId as me,normalizeBashJobPurpose as ge,readBashNiceness as we,writeJobDeadlineMs as ye}from"../core/bash-jobs.js";import{BASH_JOB_SUPERVISOR_SCRIPT as Se}from"../core/bash-job-supervisor.js";import{MAX_BACKGROUND_BASH_LOG_BYTES as ir,BACKGROUND_BASH_LOG_TRUNCATION_MARKER as sr}from"../core/bash-job-supervisor.js";import{startBrokerBashJob as Ee,stopBrokerBashJob as ve}from"../core/runtime/broker/daemon-ops.js";import{bashCommandRefusal as Be}from"../core/bash-guard.js";import{capturePidIdentities as Ie}from"../core/canvas/pid.js";import{readConfig as je}from"../core/config.js";import{PREVIEW_RESULT_PATH_ENV as _e,previewResultPath as Re}from"../core/preview-result-path.js";import{resolveAdmittedHostCommand as ke}from"../core/runtime/spawn-env.js";import{Type as P}from"typebox";import{createBashToolDefinition as W}from"@earendil-works/pi-coding-agent";const Le=200;function xe(){return ie()}o(xe,"resolveValveMs");function Te(r){return pe(r,me())}o(Te,"makeJobPaths");const I=new Set;let X=!1;function Y(){for(const r of[...I])try{z(r),I.delete(r)}catch(n){process.stderr.write(`crtr: failed to background bash job ${r.jobId} during broker termination: ${n.message}
2
- `)}}o(Y,"backgroundLiveJobsForTermination");function Ae(){X||(X=!0,process.prependListener("SIGTERM",Y),process.platform!=="win32"&&process.prependListener("SIGHUP",Y))}o(Ae,"installTerminationHandoff");const Oe=64*1024;function C(r,n,i){let s;try{s=K(r)}catch{return n}if(s.size<=n)return n;const c=ce(r,"r");try{for(;n<s.size;){const m=Math.min(Oe,s.size-n),f=Buffer.allocUnsafe(m),d=fe(c,f,0,m,n);if(d===0)break;i(f.subarray(0,d)),n+=d}return n}finally{ae(c)}}o(C,"tailOnce");function h(r){try{V(r,{recursive:!0,force:!0})}catch{}}o(h,"cleanupJobDir");function Pe(r){try{const n=ue(r,"utf8").trim(),i=Number(n);return Number.isFinite(i)?i:null}catch{return null}}o(Pe,"readExitCode");function Ce(r){try{if(K(r).isDirectory())return{cwd:r}}catch{}const n=le();return{cwd:n,warning:`[working directory no longer exists: ${r}; running from ${n}]
3
- `}}o(Ce,"resolveExecutionCwd");function Q(r,n,i=()=>null,s){return{exec:o((c,m,{onData:f,signal:d,timeout:p,env:k})=>new Promise((j,a)=>{const _=i();if(d?.aborted){a(new Error("aborted"));return}const L=Be(c,m);if(L!==null){a(new Error(L));return}const e=Te(n);G(e.dir,{recursive:!0}),y(e.cmdSh,c),y(e.jobLog,""),y(e.jobRun,""),_!==null&&y(e.jobPurpose,_);let g=0,x=!1,u,w,S,$=!1;const J=process.platform==="linux",M=O.now(),Z=xe();let T;const ee=o(()=>{T&&clearInterval(T),d&&d.removeEventListener("abort",D),I.delete(e)},"teardown"),l=o(t=>{x||(x=!0,ee(),t())},"finish");function A(t=!1){const b=q(O.now()-M);let U="";if(t){const F=oe();ye(e,Date.now()+F),U=`It will be CANCELED in ${q(F)} unless you claim it: crtr node bash extend ${e.jobId} --for <duration> (or --keep to run to completion). `}const ne=`
4
- [backgrounded as job ${e.jobId} after ${b} in the foreground${t?" (auto)":""}. `+U+`It will interrupt you with a message when it exits. Watch: tail -f ${e.jobLog} ; stop: crtr node bash kill ${e.jobId}]`;f(Buffer.from(ne)),l(()=>j({exitCode:0}))}o(A,"finishBackground");function N(){g=C(e.jobLog,g,f);const t=Pe(e.jobExit);l(()=>j({exitCode:t})),h(e.dir)}o(N,"finishForeground");function re(t=!1){const b=z(e);if(b==="backgrounded"||b==="already-backgrounded"){A(t);return}if(b==="finished"){N();return}l(()=>a(new Error(`bash job ${e.jobId} disappeared before it could be backgrounded`))),h(e.dir)}o(re,"requestBackground");function R(t){if(!(x||$)){if(g=C(e.jobLog,g,f),B(e.jobBg)){A();return}if(!B(e.jobExit)){if(u===void 0){S??=t;return}if(J){$=!0,ve(r,e.jobId).then(()=>{l(()=>a(t)),h(e.dir)},b=>l(()=>a(b)));return}u!==void 0&&w!==void 0&&he(u,w),l(()=>a(t)),h(e.dir)}}}o(R,"requestStop");function D(){R(new Error("aborted"))}o(D,"onAbort"),d&&d.addEventListener("abort",D,{once:!0});const E=Ce(m);E.warning&&f(Buffer.from(E.warning));let v=k??process.env;s!==void 0&&(G(be(s),{recursive:!0}),V(s,{force:!0}),v={...v,[_e]:s});const H=ke("bash",v,E.cwd);if(J)Ee(r,{job_id:e.jobId,cwd:E.cwd,env:v}).then(({pid:t})=>{u=t,w=`launcher:${t}`,I.add(e),S!==void 0&&R(S)},t=>{l(()=>a(t)),h(e.dir)});else{const t=de(H,["-c",Se,"--",e.cmdSh,e.jobLog,e.jobExit,e.jobRun,e.jobDone,e.jobBg,e.jobId,r,H,String(we(n)),process.execPath,"direct"],{cwd:E.cwd,detached:!0,stdio:"ignore",env:v});if(t.on("error",b=>{l(()=>a(b)),h(e.dir)}),u=t.pid,u!==void 0){if(w=Ie([u])?.get(u),w===void 0){try{process.kill(-u,"SIGKILL")}catch{}l(()=>a(new Error(`bash job ${e.jobId} started without a process identity`))),h(e.dir);return}y(e.jobPgid,String(u)),y(e.jobPgidIdentity,w),I.add(e),S!==void 0&&R(S)}t.unref()}T=setInterval(()=>{if(g=C(e.jobLog,g,f),B(e.jobDone)){N();return}if(B(e.jobBg)){A();return}if(B(e.jobExit))return;const t=O.now()-M;if(p!==void 0&&p>0){t>=p*1e3&&R(new Error(`timeout:${p}`));return}t>=Z&&re(!0)},Le)}),"exec")}}o(Q,"createValveOperations");const $e=["One short clause naming what this step is FOR, in the words of the person you",'are working for \u2014 "Reading the Acme thread", not "Fetching emails" and never','"Running GMAIL_FETCH_EMAILS". A person reads this while the command runs; it',"is the only thing they see of this step. Under about eight words. Omit it for","steps that only touch your own scratch work."].join(" ");function Je(r){return{...r,parameters:P.Object({purpose:P.Optional(P.String({description:$e})),...r.parameters.properties})}}o(Je,"withPurpose");function Me(r,n,i,s){const c=W(i,{operations:Q(r,n)});return{...s?Je(c):c,execute:o((d,p,k,j,a)=>{const _=s?ge(p.purpose):null;return W(i,{operations:Q(r,n,()=>_,Re(d))}).execute(d,p,k,j,a)},"execute")}}o(Me,"createValveToolDefinition");function Ne(r){const n=se();if(n===void 0||n.trim()==="")return;const i=process.env.CRTR_CONTEXT_DIR;i===void 0||i.trim()===""||(Ae(),r.on("session_start",(s,c)=>{r.registerTool(Me(n,i,c.cwd,je("user").bash_tool_purpose))}))}o(Ne,"default");export{sr as BACKGROUND_BASH_LOG_TRUNCATION_MARKER,ir as MAX_BACKGROUND_BASH_LOG_BYTES,Q as createValveOperations,Me as createValveToolDefinition,Ne as default};
1
+ var de=Object.defineProperty;var o=(r,n)=>de(r,"name",{value:n,configurable:!0});import{envBashAutoBgDeadlineMs as ae,envBashValveMs as ce,envNodeId as ue}from"../shared/env.js";import{spawn as fe}from"node:child_process";import{closeSync as le,existsSync as j,mkdirSync as K,openSync as be,readFileSync as z,readSync as pe,rmSync as W,statSync as q,writeFileSync as y}from"node:fs";import{homedir as he}from"node:os";import{dirname as me}from"node:path";import{performance as A}from"node:perf_hooks";import{backgroundBashJob as X,bashJobPaths as ge,cancelBashJobProcessTree as we,formatBashElapsed as Y,newBashJobId as ye,normalizeBashJobPurpose as Se,readBashNiceness as ve,writeJobDeadlineMs as Ee}from"../core/bash-jobs.js";import{BASH_JOB_SUPERVISOR_SCRIPT as Ie}from"../core/bash-job-supervisor.js";import{MAX_BACKGROUND_BASH_LOG_BYTES as cr,BACKGROUND_BASH_LOG_TRUNCATION_MARKER as ur}from"../core/bash-job-supervisor.js";import{recordBackgroundedJob as je,startBrokerBashJob as Be,stopBrokerBashJob as _e}from"../core/runtime/broker/daemon-ops.js";import{bashCommandRefusal as ke}from"../core/bash-guard.js";import{capturePidIdentities as Re}from"../core/canvas/pid.js";import{readConfig as Le}from"../core/config.js";import{PREVIEW_RESULT_PATH_ENV as xe,previewResultPath as Te}from"../core/preview-result-path.js";import{resolveAdmittedHostCommand as Oe}from"../core/runtime/spawn-env.js";import{Type as P}from"typebox";import{createBashToolDefinition as Q}from"@earendil-works/pi-coding-agent";const Ae=200;function Pe(){return ce()}o(Pe,"resolveValveMs");function Ce(r){return ge(r,ye())}o(Ce,"makeJobPaths");const B=new Set;let Z=!1;function ee(){for(const r of[...B])try{X(r),B.delete(r)}catch(n){process.stderr.write(`crtr: failed to background bash job ${r.jobId} during broker termination: ${n.message}
2
+ `)}}o(ee,"backgroundLiveJobsForTermination");function $e(){Z||(Z=!0,process.prependListener("SIGTERM",ee),process.platform!=="win32"&&process.prependListener("SIGHUP",ee))}o($e,"installTerminationHandoff");const Je=64*1024;function C(r,n,i){let s;try{s=q(r)}catch{return n}if(s.size<=n)return n;const u=be(r,"r");try{for(;n<s.size;){const m=Math.min(Je,s.size-n),l=Buffer.allocUnsafe(m),d=pe(u,l,0,m,n);if(d===0)break;i(l.subarray(0,d)),n+=d}return n}finally{le(u)}}o(C,"tailOnce");function h(r){try{W(r,{recursive:!0,force:!0})}catch{}}o(h,"cleanupJobDir");function Ne(r){try{const n=z(r,"utf8").trim(),i=Number(n);return Number.isFinite(i)?i:null}catch{return null}}o(Ne,"readExitCode");function Me(r){try{if(q(r).isDirectory())return{cwd:r}}catch{}const n=he();return{cwd:n,warning:`[working directory no longer exists: ${r}; running from ${n}]
3
+ `}}o(Me,"resolveExecutionCwd");function re(r,n,i=()=>null,s){return{exec:o((u,m,{onData:l,signal:d,timeout:p,env:x})=>new Promise((_,c)=>{const k=i();if(d?.aborted){c(new Error("aborted"));return}const T=ke(u,m);if(T!==null){c(new Error(T));return}const e=Ce(n);K(e.dir,{recursive:!0}),y(e.cmdSh,u),y(e.jobLog,""),y(e.jobRun,""),k!==null&&y(e.jobPurpose,k);let g=0,R=!1,f,w,S,$=!1;const J=process.platform==="linux",N=A.now(),ne=Pe();let v;const te=o(()=>{v&&clearInterval(v),d&&d.removeEventListener("abort",U),B.delete(e)},"teardown"),b=o(t=>{R||(R=!0,te(),t())},"finish");let M=!1;function O(t=!1){R||M||(M=!0,v&&clearInterval(v),je(r,e.jobId,{command:z(e.cmdSh,"utf8"),job_dir:e.dir,log_path:e.jobLog}).then(()=>D(t,""),a=>D(t,`
4
+ [crtr could not record job ${e.jobId} (${a.message}); it will NOT message you when it exits. Watch its log.]`)))}o(O,"finishBackground");function D(t,a){const ie=Y(A.now()-N);let G="";if(t){const V=ae();Ee(e,Date.now()+V),G=`It will be CANCELED in ${Y(V)} unless you claim it: crtr node bash extend ${e.jobId} --for <duration> (or --keep to run to completion). `}const se=`
5
+ [backgrounded as job ${e.jobId} after ${ie} in the foreground${t?" (auto)":""}. `+G+(a===""?"It will interrupt you with a message when it exits. ":"")+`Watch: tail -f ${e.jobLog} ; stop: crtr node bash kill ${e.jobId}]`;l(Buffer.from(se+a)),b(()=>_({exitCode:0}))}o(D,"handOff");function H(){g=C(e.jobLog,g,l);const t=Ne(e.jobExit);b(()=>_({exitCode:t})),h(e.dir)}o(H,"finishForeground");function oe(t=!1){const a=X(e);if(a==="backgrounded"||a==="already-backgrounded"){O(t);return}if(a==="finished"){H();return}b(()=>c(new Error(`bash job ${e.jobId} disappeared before it could be backgrounded`))),h(e.dir)}o(oe,"requestBackground");function L(t){if(!(R||$)){if(g=C(e.jobLog,g,l),j(e.jobBg)){O();return}if(!j(e.jobExit)){if(f===void 0){S??=t;return}if(J){$=!0,_e(r,e.jobId).then(()=>{b(()=>c(t)),h(e.dir)},a=>b(()=>c(a)));return}f!==void 0&&w!==void 0&&we(f,w),b(()=>c(t)),h(e.dir)}}}o(L,"requestStop");function U(){L(new Error("aborted"))}o(U,"onAbort"),d&&d.addEventListener("abort",U,{once:!0});const E=Me(m);E.warning&&l(Buffer.from(E.warning));let I=x??process.env;s!==void 0&&(K(me(s),{recursive:!0}),W(s,{force:!0}),I={...I,[xe]:s});const F=Oe("bash",I,E.cwd);if(J)Be(r,{job_id:e.jobId,cwd:E.cwd,env:I}).then(({pid:t})=>{f=t,w=`launcher:${t}`,B.add(e),S!==void 0&&L(S)},t=>{b(()=>c(t)),h(e.dir)});else{const t=fe(F,["-c",Ie,"--",e.cmdSh,e.jobLog,e.jobExit,e.jobRun,e.jobDone,F,String(ve(n)),process.execPath],{cwd:E.cwd,detached:!0,stdio:"ignore",env:I});if(t.on("error",a=>{b(()=>c(a)),h(e.dir)}),f=t.pid,f!==void 0){if(w=Re([f])?.get(f),w===void 0){try{process.kill(-f,"SIGKILL")}catch{}b(()=>c(new Error(`bash job ${e.jobId} started without a process identity`))),h(e.dir);return}y(e.jobPgid,String(f)),y(e.jobPgidIdentity,w),B.add(e),S!==void 0&&L(S)}t.unref()}v=setInterval(()=>{if(g=C(e.jobLog,g,l),j(e.jobDone)){H();return}if(j(e.jobBg)){O();return}if(j(e.jobExit))return;const t=A.now()-N;if(p!==void 0&&p>0){t>=p*1e3&&L(new Error(`timeout:${p}`));return}t>=ne&&oe(!0)},Ae)}),"exec")}}o(re,"createValveOperations");const De=["One short clause naming what this step is FOR, in the words of the person you",'are working for \u2014 "Reading the Acme thread", not "Fetching emails" and never','"Running GMAIL_FETCH_EMAILS". A person reads this while the command runs; it',"is the only thing they see of this step. Under about eight words. Omit it for","steps that only touch your own scratch work."].join(" ");function He(r){return{...r,parameters:P.Object({purpose:P.Optional(P.String({description:De})),...r.parameters.properties})}}o(He,"withPurpose");function Ue(r,n,i,s){const u=Q(i,{operations:re(r,n)});return{...s?He(u):u,execute:o((d,p,x,_,c)=>{const k=s?Se(p.purpose):null;return Q(i,{operations:re(r,n,()=>k,Te(d))}).execute(d,p,x,_,c)},"execute")}}o(Ue,"createValveToolDefinition");function Fe(r){const n=ue();if(n===void 0||n.trim()==="")return;const i=process.env.CRTR_CONTEXT_DIR;i===void 0||i.trim()===""||($e(),r.on("session_start",(s,u)=>{r.registerTool(Ue(n,i,u.cwd,Le("user").bash_tool_purpose))}))}o(Fe,"default");export{ur as BACKGROUND_BASH_LOG_TRUNCATION_MARKER,cr as MAX_BACKGROUND_BASH_LOG_BYTES,re as createValveOperations,Ue as createValveToolDefinition,Fe as default};
@@ -1,2 +1,2 @@
1
- var C=Object.defineProperty;var s=(t,n)=>C(t,"name",{value:n,configurable:!0});import{envNodeId as y}from"../shared/env.js";import{CONTEXT_INTRO_CUSTOM_TYPE as c,formatCard as b}from"../shared/generated-context.js";import{brokerContext as p,brokerExtensionState as f,commitBrokerContext as T}from"../core/runtime/broker/daemon-ops.js";import{buildForkBearingsFromState as l}from"../core/runtime/broker-extension-render.js";import{acknowledgePersonaBaseline as h}from"../core/runtime/broker-persona-guidance.js";import{situationalContextEnvelope as x}from"../core/runtime/situational-context.js";import{clearSessionCache as I}from"../core/substrate/session-cache.js";async function A(t){return(await p(t,"baseline")).content}s(A,"buildContextIntro");async function j(t){const n=await f(t);return l(n,x(t)??"")}s(j,"buildForkContextIntro");function g(t){const n=t.content;return typeof n=="string"?n:Array.isArray(n)?n.filter(r=>typeof r?.text=="string").map(r=>r.text).join(`
2
- `):""}s(g,"entryText");function _(t){t.on("session_start",async(n,r)=>{const e=y();if(e===void 0||e.trim()==="")return;const m=n?.reason,a=await f(e);if(a.warm_spare||m==="new"&&a.node.parent===null)return;m==="new"&&I();const d=r.sessionManager.getBranch().filter(o=>o.type==="custom_message"&&o.customType===c);if(d.some(o=>o.details?.nodeId===e||g(o).includes(e)))return;const i=await p(e,d.length>0?"compact":"baseline"),w=i.compact?l(a,x(e)??""):i.content,u=b("bearings",{},w);if(t.sendMessage({customType:c,content:u,display:!0,details:{nodeId:e}}),!r.sessionManager.getBranch().some(o=>o.type==="custom_message"&&o.customType===c&&o.details?.nodeId===e&&g(o)===u))throw new Error(`Pi did not materialize the context baseline for ${e}`);await T(e,i.snapshot,i.loads),await h(a)})}s(_,"registerCanvasContextIntro");var z=_;export{c as CONTEXT_INTRO_CUSTOM_TYPE,A as buildContextIntro,j as buildForkContextIntro,z as default,_ as registerCanvasContextIntro};
1
+ var w=Object.defineProperty;var s=(t,e)=>w(t,"name",{value:e,configurable:!0});import{envNodeId as b}from"../shared/env.js";import{CONTEXT_INTRO_CUSTOM_TYPE as a,formatCard as C}from"../shared/generated-context.js";import{brokerDelivery as m,brokerExtensionState as f}from"../core/runtime/broker/daemon-ops.js";import{buildForkBearingsFromState as p}from"../core/runtime/broker-extension-render.js";import{acknowledgePersonaBaseline as T}from"../core/runtime/broker-persona-guidance.js";import{situationalContextEnvelope as l}from"../core/runtime/situational-context.js";async function O(t){return(await m(t,{activity:"boot"})).content}s(O,"buildContextIntro");async function P(t){const e=await f(t);return p(e,l(t)??"")}s(P,"buildForkContextIntro");function g(t){const e=t.content;return typeof e=="string"?e:Array.isArray(e)?e.filter(r=>typeof r?.text=="string").map(r=>r.text).join(`
2
+ `):""}s(g,"entryText");function v(t){t.on("session_start",async(e,r)=>{const n=b();if(n===void 0||n.trim()==="")return;const x=e?.reason,i=await f(n);if(i.warm_spare||x==="new"&&i.node.parent===null)return;const c=r.sessionManager.getBranch().filter(o=>o.type==="custom_message"&&o.customType===a);if(c.some(o=>o.details?.nodeId===n||g(o).includes(n)))return;const d=await m(n,{activity:"boot",inherited:c.length>0}),y=d.inherited===!0?p(i,l(n)??""):d.content,u=C("bearings",{},y);if(t.sendMessage({customType:a,content:u,display:!0,details:{nodeId:n}}),!r.sessionManager.getBranch().some(o=>o.type==="custom_message"&&o.customType===a&&o.details?.nodeId===n&&g(o)===u))throw new Error(`Pi did not materialize the context baseline for ${n}`);await T(i)})}s(v,"registerCanvasContextIntro");var S=v;export{a as CONTEXT_INTRO_CUSTOM_TYPE,O as buildContextIntro,P as buildForkContextIntro,S as default,v as registerCanvasContextIntro};
@@ -42,7 +42,6 @@ type ToolCallResultLike = {
42
42
  } | void;
43
43
  interface PiLike {
44
44
  on(event: 'before_agent_start', handler: (event: BeforeAgentStartEventLike) => BeforeAgentStartResultLike | void | Promise<BeforeAgentStartResultLike | void>): void;
45
- on(event: 'session_start', handler: (event: unknown, ctx: unknown) => void | Promise<void>): void;
46
45
  on(event: 'session_compact', handler: (event: unknown, ctx: unknown) => void | Promise<void>): void;
47
46
  on(event: 'turn_end', handler: (event: unknown, ctx: unknown) => void | Promise<void>): void;
48
47
  on(event: 'tool_call', handler: (event: ToolCallEventLike, ctx: unknown) => ToolCallResultLike | Promise<ToolCallResultLike>): void;
@@ -1,9 +1,9 @@
1
- var E=Object.defineProperty;var l=(n,e)=>E(n,"name",{value:e,configurable:!0});import{envNodeId as g}from"../shared/env.js";import{homedir as C}from"node:os";import{join as S,resolve as _}from"node:path";import{brokerContext as O,brokerContextEvent as f,commitBrokerContext as p}from"../core/runtime/broker/daemon-ops.js";import{clearSessionCache as L}from"../core/substrate/session-cache.js";import{contextExposureStatesEqual as N,mergeContextExposureState as k,replaceContextExposureState as x,restoreContextExposure as h,sharedContextExposureState as P,snapshotContextExposure as T}from"../core/substrate/injected-store.js";import{autoLoadedContextInner as $,mergeAutoLoadedContext as H}from"./envelope-merge.js";const I=`
1
+ var y=Object.defineProperty;var c=(n,e)=>y(n,"name",{value:e,configurable:!0});import{envNodeId as p}from"../shared/env.js";import{homedir as b}from"node:os";import{join as w,resolve as g}from"node:path";import{brokerDelivery as m}from"../core/runtime/broker/daemon-ops.js";import{autoLoadedContextInner as x,mergeAutoLoadedContext as O}from"./envelope-merge.js";const _=`
2
2
 
3
- Guidelines:`;function R(n){const e=n?.command;return typeof e=="string"&&e.trim()!==""?e:null}l(R,"bashCommandOf");function j(n){return["HELD \u2014 nothing ran.","","Your bash command was NOT executed. It matched memory you had not yet read, and that memory is below.","","Read it, then re-issue your WHOLE command unchanged \u2014 every clause of it, including any heredoc, redirect, or `$(\u2026)` that built its input, because none of that ran either. The re-issue executes: this memory is now in your transcript, so there is nothing left to deliver and nothing left to hold.","",n].join(`
4
- `)}l(j,"heldReason");const A=["HELD \u2014 nothing ran.","","Your bash command was NOT executed. Another command in this same message was held against memory you had not read, and that memory was returned with it.","","Read it, then re-issue your WHOLE command unchanged. The re-issue executes."].join(`
5
- `);function D(n){const e=g();if(e===void 0||e.trim()==="")return;const s=P(e);n.on("session_start",()=>{L()}),n.on("before_agent_start",async t=>{const a=s.preferenceSnapshot===null,o=await O(e,"preferences"),i=h(o.snapshot);k(s,i);const r=s.preferenceSnapshot;if(r===null)throw new Error(`daemon returned no preference snapshot for ${e}`);if((a||!N(s,i))&&await p(e,T(s),o.loads),r==="")return;const c=t.systemPrompt.indexOf(I);return c===-1?{systemPrompt:`${t.systemPrompt}
3
+ Guidelines:`;function L(n){const e=n?.command;return typeof e=="string"&&e.trim()!==""?e:null}c(L,"bashCommandOf");function N(n){return["HELD \u2014 nothing ran.","","Your bash command was NOT executed. It matched memory you had not yet read, and that memory is below.","","Read it, then re-issue your WHOLE command unchanged \u2014 every clause of it, including any heredoc, redirect, or `$(\u2026)` that built its input, because none of that ran either. The re-issue executes: this memory is now in your transcript, so there is nothing left to deliver and nothing left to hold.","",n].join(`
4
+ `)}c(N,"heldReason");const E=["HELD \u2014 nothing ran.","","Your bash command was NOT executed. Another command in this same message was held against memory you had not read, and that memory was returned with it.","","Read it, then re-issue your WHOLE command unchanged. The re-issue executes."].join(`
5
+ `);function j(n){const e=p();if(e===void 0||e.trim()==="")return;n.on("before_agent_start",async t=>{const o=(await m(e,{activity:"system-prompt"})).content;if(o==="")return;const r=t.systemPrompt.indexOf(_);return r===-1?{systemPrompt:`${t.systemPrompt}
6
6
 
7
- ${r}`}:{systemPrompt:`${t.systemPrompt.slice(0,c)}
7
+ ${o}`}:{systemPrompt:`${t.systemPrompt.slice(0,r)}
8
8
 
9
- ${r}${t.systemPrompt.slice(c)}`}});let u=!1;n.on("turn_end",()=>{u=!1}),n.on("session_compact",async()=>{const t=await f(e,"compact");await p(e,t.snapshot,t.loads),x(s,h(t.snapshot)),u=!1}),n.on("tool_call",async t=>{if(t.toolName!=="bash")return;const a=R(t.input);if(a===null)return;if(u)return{block:!0,reason:A};const o=await f(e,"pre-command",a),i=o.content;if(i!=="")return u=!0,await p(e,o.snapshot,o.loads),x(s,h(o.snapshot)),{block:!0,reason:j(i)}}),n.on("tool_result",async(t,a)=>{if(t.isError===!0)return;let o=null,i=null;if(t.toolName==="read"){const d=t.input,m=d?.path??d?.file_path;if(m===void 0||m==="")return;const w=typeof a?.cwd=="string"&&a.cwd!==""?a.cwd:process.cwd(),b=m.startsWith("~")?S(C(),m.slice(1)):m;o=_(w,b)}else if(t.toolName==="bash"){const d=t.input;if(typeof d?.command!="string"||d.command.trim()==="")return;i=d.command}else return;const r=await f(e,o!==null?"read":"command",o??i),c=r.content;if(c==="")return;const y=$(c);if(y===null)throw new Error("substrate renderer returned an invalid auto-loaded context block");return await p(e,r.snapshot,r.loads),x(s,h(r.snapshot)),{content:H([y],t.content)}})}l(D,"registerCanvasDocSubstrate");var K=D;export{K as default,D as registerCanvasDocSubstrate};
9
+ ${o}${t.systemPrompt.slice(r)}`}});let i=!1;n.on("turn_end",()=>{i=!1}),n.on("session_compact",async()=>{await m(e,{activity:"compact"}),i=!1}),n.on("tool_call",async t=>{if(t.toolName!=="bash")return;const o=L(t.input);if(o===null)return;if(i)return{block:!0,reason:E};const r=(await m(e,{activity:"pre-command",subject:o})).content;if(r!=="")return i=!0,{block:!0,reason:N(r)}}),n.on("tool_result",async(t,o)=>{if(t.isError===!0)return;let r=null,d=null;if(t.toolName==="read"){const a=t.input,s=a?.path??a?.file_path;if(s===void 0||s==="")return;const f=typeof o?.cwd=="string"&&o.cwd!==""?o.cwd:process.cwd(),h=s.startsWith("~")?w(b(),s.slice(1)):s;r=g(f,h)}else if(t.toolName==="bash"){const a=t.input;if(typeof a?.command!="string"||a.command.trim()==="")return;d=a.command}else return;const u=(await m(e,r!==null?{activity:"file-read",subject:r}:{activity:"command",subject:d})).content;if(u==="")return;const l=x(u);if(l===null)throw new Error("substrate renderer returned an invalid auto-loaded context block");return{content:O([l],t.content)}})}c(j,"registerCanvasDocSubstrate");var C=j;export{C as default,j as registerCanvasDocSubstrate};
@@ -1,2 +1,2 @@
1
- var A=Object.defineProperty;var l=(s,t)=>A(s,"name",{value:t,configurable:!0});import{envNodeId as D,envProfileId as H,envWatcherDebounceMs as T,envWatcherTickMs as q}from"../shared/env.js";import{coalesceBrokerInbox as U,entryCards as B}from"../core/runtime/broker/inbox.js";import{acknowledgeBrokerMail as J,claimBrokerMail as $,brokerExtensionState as W}from"../core/runtime/broker/daemon-ops.js";import{wasTurnRefused as G}from"../core/runtime/broker/extension-abort.js";import{isDaemonTransportApiError as R}from"../api/errors.js";import{announceMessageOrigin as X,messageSignature as b}from"../core/runtime/stamp/channel.js";import{captureGoalIfAbsent as j,generateAndCommitInitialName as L}from"./broker-local.js";import{emitEvent as V}from"../core/events/emit.js";import{errorClassFromError as z}from"../core/events/errors.js";import{operationIdContext as p}from"../core/events/operation-id.js";import{situationalContextEnvelope as Q,SITUATIONAL_CONTEXT_CUSTOM_TYPE as _}from"../core/runtime/situational-context.js";import{isProfilePaused as Y}from"../core/profiles/manifest.js";import{brokerIdleTurnStart as K,brokerRunTurnBusy as Z,HELD_DEFERRED_INBOX_PROMPT_JOIN as ee}from"../core/runtime/broker/held-deferred-inbox.js";const v=64,S=16;let m,te=0;class O extends Error{static{l(this,"WatcherFatalError")}constructor(t,e){super(t,{cause:e}),this.name="WatcherFatalError"}}function ie(){return{tickMs:q(),debounceMs:T()}}l(ie,"resolveCadence");function I(){const s=D();return s===void 0||s.trim()===""?void 0:s}l(I,"currentNodeId");function P(){const s=H();return s!==void 0&&s!==""&&Y(s)}l(P,"profilePaused");function E(s){try{return z(s)}catch{return{class:"unknown"}}}l(E,"safeErrorClass");function w(s){try{V(s)}catch{}}l(w,"emitBestEffort");function C(s){try{p.fresh(t=>{w({...s,operation_id:t})})}catch{}}l(C,"emitFreshBestEffort");function x(s,t){try{p.run(s,()=>{w({...t,operation_id:s})})}catch{}}l(x,"emitStoredBestEffort");function ne(s){return s.kind==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:s.entries.map(t=>({...t.from===null?{}:{from:t.from},...t.from_name===void 0?{}:{fromName:t.from_name},kind:t.kind,tier:t.tier,...t.ref===void 0?{}:{ref:t.ref}}))}}l(ne,"deliveryOrigin");function F(s,t){if(s.length===0)throw new Error(`cannot create an empty ${t} delivery`);const e=[...new Set(s.map(n=>n.operation_id))].sort(),i=e.length-S;return{channel:t,entryIds:s.map(n=>n.entry_id),throughEntryId:s.at(-1).entry_id,sourceOperationIds:e.slice(0,S),...i>0?{sourceOperationIdsOmitted:i}:{}}}l(F,"deliveryFacts");function y(s){return{channel:s.channel,entry_ids:s.entryIds,through_entry_id:s.throughEntryId,source_operation_ids:s.sourceOperationIds,...s.sourceOperationIdsOmitted===void 0?{}:{source_operation_ids_omitted:s.sourceOperationIdsOmitted}}}l(y,"deliveryFields");function re(s){x(s.operationId,{level:"info",event:"inbox.delivery.completed",outcome:"succeeded",fields:y(s)})}l(re,"emitDeliveryCompleted");function M(s,t,e,i){x(s,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error:i,error_class:E(i),fields:{stage:e,...y(t)}})}l(M,"emitDeliveryFailure");function k(s,t){x(s.operationId,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error_class:{class:"unknown"},fields:{stage:"abandoned",reason:t,...y(s)}})}l(k,"emitDeliveryAbandoned");function se(s){return typeof s=="string"?s:Array.isArray(s)?s.filter(t=>typeof t=="object"&&t!==null&&typeof t.text=="string").map(t=>t.text).join(`
2
- `):""}l(se,"messageText");function N(s){return s==="quit"||s==="reload"||s==="new"||s==="resume"||s==="fork"}l(N,"isSessionShutdownReason");function ae(s){switch(s){case"quit":return"shutdown";case"reload":case"new":case"resume":case"fork":return"reload";default:return s}}l(ae,"disposalReasonForShutdown");function de(s){return typeof s=="string"?s.slice(0,128):s===null?"null":s===void 0?"undefined":typeof s=="number"||typeof s=="boolean"||typeof s=="bigint"?String(s).slice(0,128):typeof s}l(de,"boundedRuntimeReason");class oe{static{l(this,"CanvasInboxWatcher")}pi;cadence;generation;timer;armed=!1;lastCtx;streaming=!1;runNode=!!process.env.CRTR_RUN_ID;nodeId;claims=new Map;tickInFlight;buffer=[];lastArrival=0;pendingHandoffs=[];pendingCommit;promptJoinInFlight=!1;replayUnseenInherited=!1;seeded=!1;disposed=!1;disposalReason;fatalError;fatalEscaped=!1;constructor(t,e,i){this.pi=t,this.cadence=e,this.generation=i}start(){const t=l((e,i)=>{this.canMutate()&&this.captureCtx(e,i)},"capture");this.pi.on("session_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.arm())}),this.pi.on("turn_end",t),this.pi.on("agent_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!0)}),this.pi.on("agent_end",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!1)}),this.pi.on("message_end",e=>{if(!this.canMutate())return;const i=e?.message;if(i?.role!=="user"&&i?.role!=="custom"||!this.pendingHandoffs.some(a=>a.awaitingDequeue!==void 0))return;const n=b(se(i.content)),r=this.pendingHandoffs.find(a=>a.awaitingDequeue===n);r!==void 0&&delete r.awaitingDequeue}),this.pi.on("agent_settled",async(e,i)=>{if(!this.canMutate())return;this.captureCtx(e,i);const n=I();if(n!==void 0)try{this.assertNodeOwnership(n,"settle"),await this.tickInFlight,this.seeded||await this.claimMail(n);const r=await this.settle(n,i,!1,!0);r==="refresh_held"&&this.dispose("refresh",!1),this.runNode&&r==="settled"&&this.canMutate()&&this.buffer.length>0&&this.flushOrdinary(n)}catch(r){this.dispose("shutdown",!1,void 0,{error:r,stage:"settle"})}}),this.pi.on("session_shutdown",async e=>{if(!this.canMutate())return;let i;try{i=e?.reason}catch{i=void 0}const n=N(i)?ae(i):"reload";N(i)||C({level:"warn",event:"inbox.lifecycle.unknown_shutdown_reason",outcome:"failed",fields:{reason:de(i)}});try{await this.disposeAtSettlement(n,this.lastCtx)}catch(r){this.dispose(n,!1,void 0,{error:r,stage:"settle"})}})}arm(){this.armed||(this.armed=!0,this.timer=setInterval(()=>this.runTick(),this.cadence.tickMs),typeof this.timer.unref=="function"&&this.timer.unref(),this.runTick("schedule"))}async disposeAtSettlement(t,e){const i=I();if(i===void 0){this.dispose(t,!1);return}try{this.assertNodeOwnership(i,"settle");const n=await this.settle(i,e,t!=="refresh");this.dispose(n==="refresh_held"?"refresh":t,!1)}catch(n){this.dispose(t,!1,void 0,{error:n,stage:"settle"})}}dispose(t,e,i,n){if(this.disposed)return;this.disposed=!0,this.disposalReason=t,this.clearTimer();const r=n;{const a=[...new Set([...this.pendingCommit?.handoffs??[],...this.pendingHandoffs.splice(0)])];this.buffer.length=0,this.claims.clear(),this.pendingCommit=void 0,this.promptJoinInFlight=!1,this.replayUnseenInherited=!1,this.nodeId=void 0,this.lastCtx=void 0,this.lastArrival=0,this.streaming=!1,this.seeded=!1,this.ownsCurrentGeneration()&&(m=void 0);for(const d of a)k(d,t)}if(r!==void 0){this.scheduleHandlerFatal(r.error,r.stage);return}}ownsCurrentGeneration(){return m===this&&m.generation===this.generation}canMutate(){return this.ownsCurrentGeneration()&&!this.disposed&&this.fatalError===void 0}captureCtx(t,e){e!==void 0&&(this.lastCtx=e)}clearTimer(){this.timer!==void 0&&(clearInterval(this.timer),this.timer=void 0)}isIdle(){if(this.runNode&&Z())return!1;try{if(typeof this.lastCtx?.isIdle=="function")return this.lastCtx.isIdle()===!0}catch{}return!this.streaming}assertNodeOwnership(t,e){!this.seeded||this.nodeId===void 0||this.nodeId===t||this.raiseReadFatal(e,new Error(`watcher node changed from ${this.nodeId} to ${t}`))}raiseFatal(t,e,i,n){throw this.fatalError===void 0&&(this.fatalError=new O(e,i),this.clearTimer(),C({level:"error",event:t,outcome:"failed",error:i,error_class:E(i),fields:n})),this.fatalError}raiseReadFatal(t,e){return this.raiseFatal("inbox.read.failed",`inbox ${t} state is corrupt`,e,{stage:t})}raiseSituationalFatal(t,e){return this.raiseFatal("inbox.situational_context.missing","situational context marker has no readable sidecar",e,{entry_id:t})}escapeFatal(t,e){if(!this.fatalEscaped){if(this.fatalEscaped=!0,e==="throw")throw t;queueMicrotask(()=>{throw t})}}scheduleHandlerFatal(t,e){let i;if(t instanceof O)i=t;else try{this.raiseReadFatal(e,t)}catch(n){i=n}this.escapeFatal(i,"schedule")}runTick(t="throw"){if(!this.canMutate()||this.tickInFlight!==void 0)return;const e=this.tick().catch(i=>{if(this.canMutate()){if(R(i)){C({level:"warn",event:"inbox.read.failed",outcome:"failed",error:i,error_class:E(i),fields:{stage:"poll"}});return}this.scheduleHandlerFatal(i,"poll")}}).finally(()=>{this.tickInFlight===e&&(this.tickInFlight=void 0)});this.tickInFlight=e}async claimMail(t){this.assertNodeOwnership(t,"poll");let e;try{e=await $(t,"wake")}catch(a){throw R(a)&&(this.replayUnseenInherited=!0),a}if(!this.canMutate()||e.action==="hold")return!1;const i=this.replayUnseenInherited;this.replayUnseenInherited=!1,this.nodeId=t,this.seeded=!0;const n=new Set(e.deliveries.map(a=>a.entry.entry_id)),r=this.buffer.filter(a=>!n.has(a.entry_id));for(const a of r)this.claims.delete(a.entry_id);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(a=>n.has(a.entry_id)));for(const a of e.deliveries){const d=a.entry.entry_id;this.claims.has(d)||(this.claims.set(d,a),a.handoff==="inherited"&&!i?p.fresh(f=>{this.pendingHandoffs.push({...F([a.entry],"visible"),operationId:f,settleAtAgentSettled:!0})}):(this.buffer.push(a.entry),this.lastArrival=Date.now()))}return!0}async tick(){const t=I();if(t!==void 0){if(this.pendingCommit!==void 0){await this.retryPendingCommit(t)==="refresh_held"&&this.canMutate()&&this.dispose("refresh",!1);return}this.promptJoinInFlight||P()||this.pendingHandoffs.length>=v||await this.claimMail(t)&&this.buffer.length>0&&(!this.runNode||this.isIdle()||this.buffer.some(e=>e.tier==="critical"))&&Date.now()-this.lastArrival>=this.cadence.debounceMs&&this.flushOrdinary(t)}}missingChannelEntries(t){const e=t.filter(r=>this.claims.has(r.entry_id)),i=this.coveredEntryIds("hidden"),n=this.coveredEntryIds("visible");return{hiddenEntries:e.filter(r=>(r.data?.situational===!0||r.data?.situationalOnly===!0)&&!i.has(r.entry_id)),visibleEntries:e.filter(r=>r.data?.situationalOnly!==!0&&!n.has(r.entry_id))}}visibleRoute(t){return t.length===0?"none":this.isIdle()?"idle":this.runNode?t.some(e=>e.tier==="critical")?"critical":"none":t.some(e=>e.tier==="critical")?"critical":t.some(e=>e.tier==="urgent"||e.kind==="final")?"steer":"followUp"}buildPlan(t){const{hiddenEntries:e,visibleEntries:i}=this.missingChannelEntries(t),n=new Set(e.map(u=>u.entry_id)),r=new Set(i.map(u=>u.entry_id)),a=t.filter(u=>n.has(u.entry_id)||r.has(u.entry_id)),d=this.isIdle()&&a.length>0&&a.every(u=>u.tier==="deferred"),f=this.visibleRoute(i)==="critical",o=!d&&!f&&e.length>0,c=!d&&!f&&i.length>0;return{hiddenEntries:e,visibleEntries:i,deferredHold:d,sendCount:Number(o)+Number(c)}}ordinaryPlan(){return this.buildPlan(this.buffer)}contextCards(t,e){const i=[];if(e.some(n=>n.data?.situational===!0)){const n=e.at(-1).entry_id;let r;try{r=Q(t)}catch(a){this.raiseSituationalFatal(n,a)}r===null&&this.raiseSituationalFatal(n,new Error(`missing situational context for entry ${n}`)),i.push(r)}for(const n of e)n.data?.situationalOnly===!0&&i.push(...B(n));return i}digest(t,e){try{return U(t)}catch(i){this.raiseReadFatal(e,i)}}sendDelivery(t,e,i,n,r){this.pendingHandoffs.length>=v&&this.raiseReadFatal(n,new Error(`pending handoff capacity exceeded before ${t} send`));let a;try{a=F(e,t)}catch(o){this.raiseReadFatal(n,o)}let d;try{p.fresh(o=>{d=o,w({level:"info",event:"inbox.delivery.started",operation_id:o,fields:y(a)}),i()})}catch(o){return d===void 0&&this.raiseReadFatal(n,o),M(d,a,"send",o),"failed"}d===void 0&&this.raiseReadFatal(n,new Error(`${t} delivery returned without an operation id`));const f={operationId:d,...a,...r===void 0?{}:{awaitingDequeue:r}};return this.canMutate()?(this.pendingHandoffs.push(f),"handed-off"):(this.disposed&&this.disposalReason!==void 0&&k(f,this.disposalReason),"inactive")}sendContext(t,e,i,n,r,a){const d=n==="steer"||n==="followUp"?n:this.isIdle()?void 0:"followUp",f=d===void 0||i.length===0?void 0:b(i.at(-1));return this.sendDelivery("hidden",e,()=>{this.runNode&&r&&this.pi.appendEntry("crtr-turn-input",{message_ids:e.map(o=>o.entry_id)}),i.forEach((o,c)=>{const u=r&&c===i.length-1;this.pi.sendMessage({customType:_,content:o,display:!0,details:{nodeId:t}},d!==void 0?{deliverAs:d}:u?{deliverAs:"followUp",triggerTurn:!0}:{})})},a,f)}sendVisible(t,e,i,n,r,a){return this.sendDelivery("visible",t,()=>{if(r!=="idle"&&r!=="steer"&&r!=="followUp")throw new Error(`visible send requested for non-send route ${r}`);for(const d of e)this.pi.sendMessage({customType:_,content:d,display:!0},r==="idle"?{}:{deliverAs:r});if(X(i,n),r==="idle"){const d=K();if(d===void 0)throw new Error("broker idle-turn admission is unavailable");d(i,this.runNode?t.map(f=>f.entry_id):[])}else this.pi.sendUserMessage(i,{deliverAs:r})},a,r==="steer"||r==="followUp"?b(i):void 0)}abortCritical(){try{this.lastCtx?.abort?.()}catch{}}requeueFromBatch(t,e){if(e.size===0)return;const i=t.filter(a=>e.has(a.entry_id)),n=new Set(i.map(a=>a.entry_id)),r=this.buffer.filter(a=>!n.has(a.entry_id));this.buffer.splice(0,this.buffer.length,...i,...r)}executePlan(t,e,i){const n=new Set,r=this.visibleRoute(e.visibleEntries);if(r==="critical"){if(this.abortCritical(),!this.canMutate())return{inactive:!0,requeueEntryIds:n};for(const o of e.visibleEntries)n.add(o.entry_id);for(const o of e.hiddenEntries)n.add(o.entry_id);return{inactive:!1,requeueEntryIds:n}}if(this.runNode&&r==="none")return{inactive:!1,requeueEntryIds:new Set([...e.hiddenEntries,...e.visibleEntries].map(o=>o.entry_id))};const a=e.visibleEntries.length>0?this.digest(e.visibleEntries,i):[],[d,...f]=a;for(const o of f)for(const c of o.entries)n.add(c.entry_id);if(e.hiddenEntries.length>0){const o=this.contextCards(t,e.hiddenEntries),c=this.sendContext(t,e.hiddenEntries,o,r,d===void 0,i);if(c==="inactive")return{inactive:!0,requeueEntryIds:n};if(c==="failed")for(const u of e.hiddenEntries)n.add(u.entry_id)}if(!this.canMutate())return{inactive:!0,requeueEntryIds:n};if(d!==void 0){const o=this.sendVisible(d.entries,d.cards,d.text,ne(d),r,i);if(o==="inactive")return{inactive:!0,requeueEntryIds:n};if(o==="failed")for(const c of d.entries)n.add(c.entry_id);else d.kind==="human"&&(j(t,d.text),L(t,d.text))}return{inactive:!1,requeueEntryIds:n}}flushOrdinary(t){if(this.buffer.length===0)return"empty";const e=this.ordinaryPlan();if(e.deferredHold)return"held";if(this.pendingHandoffs.length+e.sendCount>v)return"capacity-blocked";const i=[...this.buffer],n=this.executePlan(t,e,"poll");return n.inactive||(this.buffer.splice(0,i.length),this.requeueFromBatch(i,n.requeueEntryIds)),"attempted"}async prependHeldDeferredInbox(t){if(!this.canMutate()||this.nodeId===void 0||P())return;const e=this.ordinaryPlan();if(!e.deferredHold)return;const i=e.visibleEntries.length===0?[]:this.digest(e.visibleEntries,"poll"),n=+(e.hiddenEntries.length>0)+i.length;if(this.pendingHandoffs.length+n>v)return;const r=[...this.buffer];this.promptJoinInFlight=!0;try{this.runNode&&this.pi.appendEntry("crtr-turn-input",{message_ids:[...e.hiddenEntries,...e.visibleEntries].map(a=>a.entry_id)}),e.hiddenEntries.length>0&&await this.sendPromptJoinDelivery(t,"hidden",e.hiddenEntries,this.contextCards(this.nodeId,e.hiddenEntries));for(const a of i)await this.sendPromptJoinDelivery(t,"visible",a.entries,[...a.cards,a.text]);if(!this.canMutate())return;this.buffer.splice(0,r.length)}finally{this.promptJoinInFlight=!1}}async sendPromptJoinDelivery(t,e,i,n){let r;try{r=F(i,e)}catch(f){this.raiseReadFatal("poll",f)}let a;try{await p.fresh(async f=>{a=f,w({level:"info",event:"inbox.delivery.started",operation_id:f,fields:y(r)});for(const o of n)await t.sendCustomMessage({customType:_,content:o,display:!0})})}catch(f){throw a===void 0&&this.raiseReadFatal("poll",f),M(a,r,"send",f),f}a===void 0&&this.raiseReadFatal("poll",new Error(`${e} prompt-join delivery returned without an operation id`));const d={operationId:a,...r,settleAtAgentSettled:!0};if(!this.canMutate()){this.disposed&&this.disposalReason!==void 0&&k(d,this.disposalReason);return}this.pendingHandoffs.push(d)}coveredEntryIds(t){const e=new Set;for(const i of this.pendingHandoffs)if(i.channel===t)for(const n of i.entryIds)e.add(n);return e}retryPendingCommit(t){const e=this.pendingCommit;if(e===void 0)return Promise.resolve("settled");if(e.attempt!==void 0)return e.attempt;const i=this.attemptPendingCommit(t,e).finally(()=>{e.attempt===i&&(e.attempt=void 0)});return e.attempt=i,i}async attemptPendingCommit(t,e){let i=!1;try{const r=await J(t,e.receipts);if(r.action==="hold")return"refresh_held";for(const a of e.receipts){const d=r.results.find(f=>f.delivery_id===a.delivery_id);if(d?.outcome!==a.disposition&&d?.outcome!=="stale")throw new Error("daemon returned no terminal mail settlement outcome")}i=r.results.every(a=>a.outcome==="acknowledged")}catch(r){if(this.pendingCommit===e)for(const a of e.handoffs)M(a.operationId,a,"receipt_commit",r);return"held"}if(this.pendingCommit!==e)return"settled";for(const r of e.entryIds)this.claims.delete(r);if(e.receipts.some(r=>r.disposition==="released")){const r=new Set(e.entryIds);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(a=>!r.has(a.entry_id)))}this.pendingCommit=void 0;const n=this.detachPending(r=>r.entryIds.every(a=>!this.claims.has(a)));for(const r of n)i&&re(r);return"settled"}async settle(t,e,i,n=!1){if(i)try{if(e?.hasPendingMessages?.()===!0)return"held"}catch{}if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const r=G(),a=!r&&this.pendingHandoffs.some(h=>h.awaitingDequeue!==void 0)&&await this.nodeRefreshing(t);if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const d=new Set(this.buffer.map(h=>h.entry_id)),f=new Set(a?this.pendingHandoffs.filter(h=>h.awaitingDequeue!==void 0).flatMap(h=>[...h.entryIds]):[]),o=this.pendingHandoffs.filter(h=>(n||h.settleAtAgentSettled!==!0)&&h.entryIds.every(g=>!f.has(g))),c=new Set(o.flatMap(h=>[...h.entryIds])),u=[...this.claims.keys()].filter(h=>r||c.has(h)&&!d.has(h));return u.length===0?"settled":(this.pendingCommit={handoffs:o,entryIds:u,receipts:u.map(h=>{const g=this.claims.get(h);return{delivery_id:g.delivery_id,attempts:g.attempts,disposition:r?"released":"acknowledged"}})},this.retryPendingCommit(t))}async nodeRefreshing(t){try{return(await W(t)).node.intent==="refresh"}catch{return!0}}detachPending(t){const e=[];for(let i=this.pendingHandoffs.length-1;i>=0;i-=1){const n=this.pendingHandoffs[i];t(n)&&e.push(...this.pendingHandoffs.splice(i,1))}return e.reverse(),e}}function fe(s,t){m?.dispose("reload",!1);const e=new oe(s,t,++te);m=e;const i=l(n=>e.prependHeldDeferredInbox(n),"promptJoin");globalThis[ee]=i;try{e.start()}catch(n){throw e.dispose("reload",!1),n}return e}l(fe,"installWatcher");function le(s){const t=fe(s,ie());return()=>t.dispose("shutdown",!1)}l(le,"registerCanvasInboxWatcher");var xe=le;export{xe as default,le as registerCanvasInboxWatcher};
1
+ var H=Object.defineProperty;var l=(s,t)=>H(s,"name",{value:t,configurable:!0});import{envInboxBetweenTurns as N,envNodeId as D,envProfileId as T,envWatcherDebounceMs as q,envWatcherTickMs as U}from"../shared/env.js";import{coalesceBrokerInbox as B,entryCards as J}from"../core/runtime/broker/inbox.js";import{acknowledgeBrokerMail as $,claimBrokerMail as W,brokerExtensionState as G}from"../core/runtime/broker/daemon-ops.js";import{wasTurnRefused as X}from"../core/runtime/broker/extension-abort.js";import{isDaemonTransportApiError as R}from"../api/errors.js";import{announceMessageOrigin as j,messageSignature as b}from"../core/runtime/stamp/channel.js";import{captureGoalIfAbsent as L,generateAndCommitInitialName as V}from"./broker-local.js";import{emitEvent as z}from"../core/events/emit.js";import{errorClassFromError as Q}from"../core/events/errors.js";import{operationIdContext as p}from"../core/events/operation-id.js";import{situationalContextEnvelope as Y,SITUATIONAL_CONTEXT_CUSTOM_TYPE as _}from"../core/runtime/situational-context.js";import{isProfilePaused as K}from"../core/profiles/manifest.js";import{brokerIdleTurnStart as Z,brokerRunTurnBusy as ee,HELD_DEFERRED_INBOX_PROMPT_JOIN as te}from"../core/runtime/broker/held-deferred-inbox.js";const v=64,S=16;let m,ie=0;class O extends Error{static{l(this,"WatcherFatalError")}constructor(t,e){super(t,{cause:e}),this.name="WatcherFatalError"}}function ne(){return{tickMs:U(),debounceMs:q()}}l(ne,"resolveCadence");function I(){const s=D();return s===void 0||s.trim()===""?void 0:s}l(I,"currentNodeId");function P(){const s=T();return s!==void 0&&s!==""&&K(s)}l(P,"profilePaused");function E(s){try{return Q(s)}catch{return{class:"unknown"}}}l(E,"safeErrorClass");function w(s){try{z(s)}catch{}}l(w,"emitBestEffort");function C(s){try{p.fresh(t=>{w({...s,operation_id:t})})}catch{}}l(C,"emitFreshBestEffort");function x(s,t){try{p.run(s,()=>{w({...t,operation_id:s})})}catch{}}l(x,"emitStoredBestEffort");function re(s){return s.kind==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:s.entries.map(t=>({...t.from===null?{}:{from:t.from},...t.from_name===void 0?{}:{fromName:t.from_name},kind:t.kind,tier:t.tier,...t.ref===void 0?{}:{ref:t.ref}}))}}l(re,"deliveryOrigin");function F(s,t){if(s.length===0)throw new Error(`cannot create an empty ${t} delivery`);const e=[...new Set(s.map(n=>n.operation_id))].sort(),i=e.length-S;return{channel:t,entryIds:s.map(n=>n.entry_id),throughEntryId:s.at(-1).entry_id,sourceOperationIds:e.slice(0,S),...i>0?{sourceOperationIdsOmitted:i}:{}}}l(F,"deliveryFacts");function y(s){return{channel:s.channel,entry_ids:s.entryIds,through_entry_id:s.throughEntryId,source_operation_ids:s.sourceOperationIds,...s.sourceOperationIdsOmitted===void 0?{}:{source_operation_ids_omitted:s.sourceOperationIdsOmitted}}}l(y,"deliveryFields");function se(s){x(s.operationId,{level:"info",event:"inbox.delivery.completed",outcome:"succeeded",fields:y(s)})}l(se,"emitDeliveryCompleted");function M(s,t,e,i){x(s,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error:i,error_class:E(i),fields:{stage:e,...y(t)}})}l(M,"emitDeliveryFailure");function k(s,t){x(s.operationId,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error_class:{class:"unknown"},fields:{stage:"abandoned",reason:t,...y(s)}})}l(k,"emitDeliveryAbandoned");function ae(s){return typeof s=="string"?s:Array.isArray(s)?s.filter(t=>typeof t=="object"&&t!==null&&typeof t.text=="string").map(t=>t.text).join(`
2
+ `):""}l(ae,"messageText");function A(s){return s==="quit"||s==="reload"||s==="new"||s==="resume"||s==="fork"}l(A,"isSessionShutdownReason");function de(s){switch(s){case"quit":return"shutdown";case"reload":case"new":case"resume":case"fork":return"reload";default:return s}}l(de,"disposalReasonForShutdown");function oe(s){return typeof s=="string"?s.slice(0,128):s===null?"null":s===void 0?"undefined":typeof s=="number"||typeof s=="boolean"||typeof s=="bigint"?String(s).slice(0,128):typeof s}l(oe,"boundedRuntimeReason");class fe{static{l(this,"CanvasInboxWatcher")}pi;cadence;generation;timer;armed=!1;lastCtx;streaming=!1;runNode=N();nodeId;claims=new Map;tickInFlight;buffer=[];lastArrival=0;pendingHandoffs=[];pendingCommit;promptJoinInFlight=!1;replayUnseenInherited=!1;seeded=!1;disposed=!1;disposalReason;fatalError;fatalEscaped=!1;constructor(t,e,i){this.pi=t,this.cadence=e,this.generation=i}start(){const t=l((e,i)=>{this.canMutate()&&this.captureCtx(e,i)},"capture");this.pi.on("session_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.arm())}),this.pi.on("turn_end",t),this.pi.on("agent_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!0)}),this.pi.on("agent_end",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!1)}),this.pi.on("message_end",e=>{if(!this.canMutate())return;const i=e?.message;if(i?.role!=="user"&&i?.role!=="custom"||!this.pendingHandoffs.some(a=>a.awaitingDequeue!==void 0))return;const n=b(ae(i.content)),r=this.pendingHandoffs.find(a=>a.awaitingDequeue===n);r!==void 0&&delete r.awaitingDequeue}),this.pi.on("agent_settled",async(e,i)=>{if(!this.canMutate())return;this.captureCtx(e,i);const n=I();if(n!==void 0)try{this.assertNodeOwnership(n,"settle"),await this.tickInFlight,this.seeded||await this.claimMail(n);const r=await this.settle(n,i,!1,!0);r==="refresh_held"&&this.dispose("refresh",!1),this.runNode&&r==="settled"&&this.canMutate()&&this.buffer.length>0&&this.flushOrdinary(n)}catch(r){this.dispose("shutdown",!1,void 0,{error:r,stage:"settle"})}}),this.pi.on("session_shutdown",async e=>{if(!this.canMutate())return;let i;try{i=e?.reason}catch{i=void 0}const n=A(i)?de(i):"reload";A(i)||C({level:"warn",event:"inbox.lifecycle.unknown_shutdown_reason",outcome:"failed",fields:{reason:oe(i)}});try{await this.disposeAtSettlement(n,this.lastCtx)}catch(r){this.dispose(n,!1,void 0,{error:r,stage:"settle"})}})}arm(){this.armed||(this.armed=!0,this.timer=setInterval(()=>this.runTick(),this.cadence.tickMs),typeof this.timer.unref=="function"&&this.timer.unref(),this.runTick("schedule"))}async disposeAtSettlement(t,e){const i=I();if(i===void 0){this.dispose(t,!1);return}try{this.assertNodeOwnership(i,"settle");const n=await this.settle(i,e,t!=="refresh");this.dispose(n==="refresh_held"?"refresh":t,!1)}catch(n){this.dispose(t,!1,void 0,{error:n,stage:"settle"})}}dispose(t,e,i,n){if(this.disposed)return;this.disposed=!0,this.disposalReason=t,this.clearTimer();const r=n;{const a=[...new Set([...this.pendingCommit?.handoffs??[],...this.pendingHandoffs.splice(0)])];this.buffer.length=0,this.claims.clear(),this.pendingCommit=void 0,this.promptJoinInFlight=!1,this.replayUnseenInherited=!1,this.nodeId=void 0,this.lastCtx=void 0,this.lastArrival=0,this.streaming=!1,this.seeded=!1,this.ownsCurrentGeneration()&&(m=void 0);for(const d of a)k(d,t)}if(r!==void 0){this.scheduleHandlerFatal(r.error,r.stage);return}}ownsCurrentGeneration(){return m===this&&m.generation===this.generation}canMutate(){return this.ownsCurrentGeneration()&&!this.disposed&&this.fatalError===void 0}captureCtx(t,e){e!==void 0&&(this.lastCtx=e)}clearTimer(){this.timer!==void 0&&(clearInterval(this.timer),this.timer=void 0)}isIdle(){if(this.runNode&&ee())return!1;try{if(typeof this.lastCtx?.isIdle=="function")return this.lastCtx.isIdle()===!0}catch{}return!this.streaming}assertNodeOwnership(t,e){!this.seeded||this.nodeId===void 0||this.nodeId===t||this.raiseReadFatal(e,new Error(`watcher node changed from ${this.nodeId} to ${t}`))}raiseFatal(t,e,i,n){throw this.fatalError===void 0&&(this.fatalError=new O(e,i),this.clearTimer(),C({level:"error",event:t,outcome:"failed",error:i,error_class:E(i),fields:n})),this.fatalError}raiseReadFatal(t,e){return this.raiseFatal("inbox.read.failed",`inbox ${t} state is corrupt`,e,{stage:t})}raiseSituationalFatal(t,e){return this.raiseFatal("inbox.situational_context.missing","situational context marker has no readable sidecar",e,{entry_id:t})}escapeFatal(t,e){if(!this.fatalEscaped){if(this.fatalEscaped=!0,e==="throw")throw t;queueMicrotask(()=>{throw t})}}scheduleHandlerFatal(t,e){let i;if(t instanceof O)i=t;else try{this.raiseReadFatal(e,t)}catch(n){i=n}this.escapeFatal(i,"schedule")}runTick(t="throw"){if(!this.canMutate()||this.tickInFlight!==void 0)return;const e=this.tick().catch(i=>{if(this.canMutate()){if(R(i)){C({level:"warn",event:"inbox.read.failed",outcome:"failed",error:i,error_class:E(i),fields:{stage:"poll"}});return}this.scheduleHandlerFatal(i,"poll")}}).finally(()=>{this.tickInFlight===e&&(this.tickInFlight=void 0)});this.tickInFlight=e}async claimMail(t){this.assertNodeOwnership(t,"poll");let e;try{e=await W(t,"wake")}catch(a){throw R(a)&&(this.replayUnseenInherited=!0),a}if(!this.canMutate()||e.action==="hold")return!1;const i=this.replayUnseenInherited;this.replayUnseenInherited=!1,this.nodeId=t,this.seeded=!0;const n=new Set(e.deliveries.map(a=>a.entry.entry_id)),r=this.buffer.filter(a=>!n.has(a.entry_id));for(const a of r)this.claims.delete(a.entry_id);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(a=>n.has(a.entry_id)));for(const a of e.deliveries){const d=a.entry.entry_id;this.claims.has(d)||(this.claims.set(d,a),a.handoff==="inherited"&&!i?p.fresh(f=>{this.pendingHandoffs.push({...F([a.entry],"visible"),operationId:f,settleAtAgentSettled:!0})}):(this.buffer.push(a.entry),this.lastArrival=Date.now()))}return!0}async tick(){const t=I();if(t!==void 0){if(this.pendingCommit!==void 0){await this.retryPendingCommit(t)==="refresh_held"&&this.canMutate()&&this.dispose("refresh",!1);return}this.promptJoinInFlight||P()||this.pendingHandoffs.length>=v||await this.claimMail(t)&&this.buffer.length>0&&(!this.runNode||this.isIdle()||this.buffer.some(e=>e.tier==="critical"))&&Date.now()-this.lastArrival>=this.cadence.debounceMs&&this.flushOrdinary(t)}}missingChannelEntries(t){const e=t.filter(r=>this.claims.has(r.entry_id)),i=this.coveredEntryIds("hidden"),n=this.coveredEntryIds("visible");return{hiddenEntries:e.filter(r=>(r.data?.situational===!0||r.data?.situationalOnly===!0)&&!i.has(r.entry_id)),visibleEntries:e.filter(r=>r.data?.situationalOnly!==!0&&!n.has(r.entry_id))}}visibleRoute(t){return t.length===0?"none":this.isIdle()?"idle":this.runNode?t.some(e=>e.tier==="critical")?"critical":"none":t.some(e=>e.tier==="critical")?"critical":t.some(e=>e.tier==="urgent"||e.kind==="final")?"steer":"followUp"}buildPlan(t){const{hiddenEntries:e,visibleEntries:i}=this.missingChannelEntries(t),n=new Set(e.map(u=>u.entry_id)),r=new Set(i.map(u=>u.entry_id)),a=t.filter(u=>n.has(u.entry_id)||r.has(u.entry_id)),d=this.isIdle()&&a.length>0&&a.every(u=>u.tier==="deferred"),f=this.visibleRoute(i)==="critical",o=!d&&!f&&e.length>0,c=!d&&!f&&i.length>0;return{hiddenEntries:e,visibleEntries:i,deferredHold:d,sendCount:Number(o)+Number(c)}}ordinaryPlan(){return this.buildPlan(this.buffer)}contextCards(t,e){const i=[];if(e.some(n=>n.data?.situational===!0)){const n=e.at(-1).entry_id;let r;try{r=Y(t)}catch(a){this.raiseSituationalFatal(n,a)}r===null&&this.raiseSituationalFatal(n,new Error(`missing situational context for entry ${n}`)),i.push(r)}for(const n of e)n.data?.situationalOnly===!0&&i.push(...J(n));return i}digest(t,e){try{return B(t)}catch(i){this.raiseReadFatal(e,i)}}sendDelivery(t,e,i,n,r){this.pendingHandoffs.length>=v&&this.raiseReadFatal(n,new Error(`pending handoff capacity exceeded before ${t} send`));let a;try{a=F(e,t)}catch(o){this.raiseReadFatal(n,o)}let d;try{p.fresh(o=>{d=o,w({level:"info",event:"inbox.delivery.started",operation_id:o,fields:y(a)}),i()})}catch(o){return d===void 0&&this.raiseReadFatal(n,o),M(d,a,"send",o),"failed"}d===void 0&&this.raiseReadFatal(n,new Error(`${t} delivery returned without an operation id`));const f={operationId:d,...a,...r===void 0?{}:{awaitingDequeue:r}};return this.canMutate()?(this.pendingHandoffs.push(f),"handed-off"):(this.disposed&&this.disposalReason!==void 0&&k(f,this.disposalReason),"inactive")}sendContext(t,e,i,n,r,a){const d=n==="steer"||n==="followUp"?n:this.isIdle()?void 0:"followUp",f=d===void 0||i.length===0?void 0:b(i.at(-1));return this.sendDelivery("hidden",e,()=>{this.runNode&&r&&this.pi.appendEntry("crtr-turn-input",{message_ids:e.map(o=>o.entry_id)}),i.forEach((o,c)=>{const u=r&&c===i.length-1;this.pi.sendMessage({customType:_,content:o,display:!0,details:{nodeId:t}},d!==void 0?{deliverAs:d}:u?{deliverAs:"followUp",triggerTurn:!0}:{})})},a,f)}sendVisible(t,e,i,n,r,a){return this.sendDelivery("visible",t,()=>{if(r!=="idle"&&r!=="steer"&&r!=="followUp")throw new Error(`visible send requested for non-send route ${r}`);for(const d of e)this.pi.sendMessage({customType:_,content:d,display:!0},r==="idle"?{}:{deliverAs:r});if(j(i,n),r==="idle"){const d=Z();if(d===void 0)throw new Error("broker idle-turn admission is unavailable");d(i,this.runNode?t.map(f=>f.entry_id):[])}else this.pi.sendUserMessage(i,{deliverAs:r})},a,r==="steer"||r==="followUp"?b(i):void 0)}abortCritical(){try{this.lastCtx?.abort?.()}catch{}}requeueFromBatch(t,e){if(e.size===0)return;const i=t.filter(a=>e.has(a.entry_id)),n=new Set(i.map(a=>a.entry_id)),r=this.buffer.filter(a=>!n.has(a.entry_id));this.buffer.splice(0,this.buffer.length,...i,...r)}executePlan(t,e,i){const n=new Set,r=this.visibleRoute(e.visibleEntries);if(r==="critical"){if(this.abortCritical(),!this.canMutate())return{inactive:!0,requeueEntryIds:n};for(const o of e.visibleEntries)n.add(o.entry_id);for(const o of e.hiddenEntries)n.add(o.entry_id);return{inactive:!1,requeueEntryIds:n}}if(this.runNode&&r==="none")return{inactive:!1,requeueEntryIds:new Set([...e.hiddenEntries,...e.visibleEntries].map(o=>o.entry_id))};const a=e.visibleEntries.length>0?this.digest(e.visibleEntries,i):[],[d,...f]=a;for(const o of f)for(const c of o.entries)n.add(c.entry_id);if(e.hiddenEntries.length>0){const o=this.contextCards(t,e.hiddenEntries),c=this.sendContext(t,e.hiddenEntries,o,r,d===void 0,i);if(c==="inactive")return{inactive:!0,requeueEntryIds:n};if(c==="failed")for(const u of e.hiddenEntries)n.add(u.entry_id)}if(!this.canMutate())return{inactive:!0,requeueEntryIds:n};if(d!==void 0){const o=this.sendVisible(d.entries,d.cards,d.text,re(d),r,i);if(o==="inactive")return{inactive:!0,requeueEntryIds:n};if(o==="failed")for(const c of d.entries)n.add(c.entry_id);else d.kind==="human"&&(L(t,d.text),V(t,d.text))}return{inactive:!1,requeueEntryIds:n}}flushOrdinary(t){if(this.buffer.length===0)return"empty";const e=this.ordinaryPlan();if(e.deferredHold)return"held";if(this.pendingHandoffs.length+e.sendCount>v)return"capacity-blocked";const i=[...this.buffer],n=this.executePlan(t,e,"poll");return n.inactive||(this.buffer.splice(0,i.length),this.requeueFromBatch(i,n.requeueEntryIds)),"attempted"}async prependHeldDeferredInbox(t){if(!this.canMutate()||this.nodeId===void 0||P())return;const e=this.ordinaryPlan();if(!e.deferredHold)return;const i=e.visibleEntries.length===0?[]:this.digest(e.visibleEntries,"poll"),n=+(e.hiddenEntries.length>0)+i.length;if(this.pendingHandoffs.length+n>v)return;const r=[...this.buffer];this.promptJoinInFlight=!0;try{this.runNode&&this.pi.appendEntry("crtr-turn-input",{message_ids:[...e.hiddenEntries,...e.visibleEntries].map(a=>a.entry_id)}),e.hiddenEntries.length>0&&await this.sendPromptJoinDelivery(t,"hidden",e.hiddenEntries,this.contextCards(this.nodeId,e.hiddenEntries));for(const a of i)await this.sendPromptJoinDelivery(t,"visible",a.entries,[...a.cards,a.text]);if(!this.canMutate())return;this.buffer.splice(0,r.length)}finally{this.promptJoinInFlight=!1}}async sendPromptJoinDelivery(t,e,i,n){let r;try{r=F(i,e)}catch(f){this.raiseReadFatal("poll",f)}let a;try{await p.fresh(async f=>{a=f,w({level:"info",event:"inbox.delivery.started",operation_id:f,fields:y(r)});for(const o of n)await t.sendCustomMessage({customType:_,content:o,display:!0})})}catch(f){throw a===void 0&&this.raiseReadFatal("poll",f),M(a,r,"send",f),f}a===void 0&&this.raiseReadFatal("poll",new Error(`${e} prompt-join delivery returned without an operation id`));const d={operationId:a,...r,settleAtAgentSettled:!0};if(!this.canMutate()){this.disposed&&this.disposalReason!==void 0&&k(d,this.disposalReason);return}this.pendingHandoffs.push(d)}coveredEntryIds(t){const e=new Set;for(const i of this.pendingHandoffs)if(i.channel===t)for(const n of i.entryIds)e.add(n);return e}retryPendingCommit(t){const e=this.pendingCommit;if(e===void 0)return Promise.resolve("settled");if(e.attempt!==void 0)return e.attempt;const i=this.attemptPendingCommit(t,e).finally(()=>{e.attempt===i&&(e.attempt=void 0)});return e.attempt=i,i}async attemptPendingCommit(t,e){let i=!1;try{const r=await $(t,e.receipts);if(r.action==="hold")return"refresh_held";for(const a of e.receipts){const d=r.results.find(f=>f.delivery_id===a.delivery_id);if(d?.outcome!==a.disposition&&d?.outcome!=="stale")throw new Error("daemon returned no terminal mail settlement outcome")}i=r.results.every(a=>a.outcome==="acknowledged")}catch(r){if(this.pendingCommit===e)for(const a of e.handoffs)M(a.operationId,a,"receipt_commit",r);return"held"}if(this.pendingCommit!==e)return"settled";for(const r of e.entryIds)this.claims.delete(r);if(e.receipts.some(r=>r.disposition==="released")){const r=new Set(e.entryIds);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(a=>!r.has(a.entry_id)))}this.pendingCommit=void 0;const n=this.detachPending(r=>r.entryIds.every(a=>!this.claims.has(a)));for(const r of n)i&&se(r);return"settled"}async settle(t,e,i,n=!1){if(i)try{if(e?.hasPendingMessages?.()===!0)return"held"}catch{}if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const r=X(),a=!r&&this.pendingHandoffs.some(h=>h.awaitingDequeue!==void 0)&&await this.nodeRefreshing(t);if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const d=new Set(this.buffer.map(h=>h.entry_id)),f=new Set(a?this.pendingHandoffs.filter(h=>h.awaitingDequeue!==void 0).flatMap(h=>[...h.entryIds]):[]),o=this.pendingHandoffs.filter(h=>(n||h.settleAtAgentSettled!==!0)&&h.entryIds.every(g=>!f.has(g))),c=new Set(o.flatMap(h=>[...h.entryIds])),u=[...this.claims.keys()].filter(h=>r||c.has(h)&&!d.has(h));return u.length===0?"settled":(this.pendingCommit={handoffs:o,entryIds:u,receipts:u.map(h=>{const g=this.claims.get(h);return{delivery_id:g.delivery_id,attempts:g.attempts,disposition:r?"released":"acknowledged"}})},this.retryPendingCommit(t))}async nodeRefreshing(t){try{return(await G(t)).node.intent==="refresh"}catch{return!0}}detachPending(t){const e=[];for(let i=this.pendingHandoffs.length-1;i>=0;i-=1){const n=this.pendingHandoffs[i];t(n)&&e.push(...this.pendingHandoffs.splice(i,1))}return e.reverse(),e}}function le(s,t){m?.dispose("reload",!1);const e=new fe(s,t,++ie);m=e;const i=l(n=>e.prependHeldDeferredInbox(n),"promptJoin");globalThis[te]=i;try{e.start()}catch(n){throw e.dispose("reload",!1),n}return e}l(le,"installWatcher");function he(s){const t=le(s,ne());return()=>t.dispose("shutdown",!1)}l(he,"registerCanvasInboxWatcher");var Fe=he;export{Fe as default,he as registerCanvasInboxWatcher};
@@ -2,7 +2,7 @@ var v=Object.defineProperty;var l=(t,e)=>v(t,"name",{value:e,configurable:!0});i
2
2
  `))return t;const e=t.indexOf(`
3
3
  ---
4
4
  `,4);return e===-1?t:t.slice(e+5)}l(P,"stripFrontmatter");async function j(t,e){if(e.ref!==void 0&&e.ref!==""){const n=e.data?.report_body;if(typeof n=="string"&&n.trim()!==""){const i=n.trim();return i.length>y?`${i.slice(0,y)}
5
- \u2026 (truncated; read the full report with \`crtr canvas history read ${e.ref}\`)`:i}if(h(e.ref))try{const{content:i}=await w(t,e.ref),f=P(i).trim();if(f!=="")return f.length>y?`${f.slice(0,y)}
5
+ \u2026 (truncated; read the full report with \`crtr canvas read ${e.ref}\`)`:i}if(h(e.ref))try{const{content:i}=await w(t,e.ref),f=P(i).trim();if(f!=="")return f.length>y?`${f.slice(0,y)}
6
6
  \u2026 (truncated; full report at ${e.ref})`:f}catch(i){if(!(i instanceof b)||i.status!==404)throw i}}const r=e.data?.body;return typeof r=="string"&&r.trim()!==""?r.trim():e.label}l(j,"entryContent");function m(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}l(m,"attr");async function B(t,e=p()??""){const r=(await Promise.all(t.map(async n=>{const i=m(n.from??"system"),f=n.from_name!==void 0&&n.from_name!==""?` from_name="${m(n.from_name)}"`:"",o=n.ref!==void 0&&n.ref!==""?` ref="${m(n.ref)}"`:"";return`<update from="${i}"${f} kind="${m(n.kind)}" at="${m(n.ts)}"${o}>
7
7
  ${await j(e,n)}
8
8
  </update>`}))).join(`
@@ -7,5 +7,5 @@ var W=Object.defineProperty;var a=(n,s)=>W(n,"name",{value:s,configurable:!0});i
7
7
 
8
8
  `):Array.from({length:o},(l,m)=>{const f=Math.round(m*(t.length-1)/(o-1));return t[f]}).join(`
9
9
 
10
- `)}a(ee,"buildNamingConversation");function te(n,s=U,r){const t=B();if(t===void 0||t.trim()==="")return;let o,u,l,m;const f=a(i=>{const e=i.model?.provider?.trim(),c=i.model?.id?.trim();e&&c&&(m=`${e}/${c}`)},"captureLiveModel");let p=Date.now(),d=0,g,_=!1,S=!1,E=!1,h=!1;const v=a(()=>o!==void 0&&typeof o.setWidget=="function","canPaint"),A=a(i=>{try{o?.notify?.(i,"info")}catch{}},"notify"),P=a(()=>{if(v())try{o.setWidget($,void 0,{placement:"aboveEditor"})}catch{}},"clearRecap"),D=a(i=>{if(!v()||i==="")return;const e=i.split(`
11
- `).filter(c=>c.trim()!=="");if(e.length!==0)try{o.setWidget($,e,{placement:"aboveEditor"})}catch{}},"showRecap"),I=a(()=>{p=Date.now(),d+=1,E=!1,_&&(S=!0)},"onMessage"),j=a(i=>{if(!(n.getSessionName===void 0||n.setSessionName===void 0)){if(r!==void 0){const e=n.getSessionName();if(e===void 0)return;r(t,i,()=>n.getSessionName?.()===e,c=>{try{n.setSessionName?.(c)}catch{}});return}G(t).then(({node:e})=>{if(e.name.trim()!==""&&e.name!==e.kind)return;const c=F(e);n.getSessionName?.()===c&&H(t,i,{name:e.name,description:e.description??"",title:e.title??"",icon:e.icon??"",kind:e.kind},()=>n.getSessionName?.()===c,R=>{try{n.setSessionName?.(R)}catch{}})}).catch(()=>{})}},"refreshAutomaticName"),x=a(i=>{if(!v()||u===void 0||h)return;const e=g,c=l?.review_binding?.review_id??u.getEntries().map(y=>y.details?.reviewId).find(y=>typeof y=="string"),R=Z(u,e,c);if(R===""){E=!0,_=!1,S=!1,P();return}E=!1;const T=i?ee(u,e,c):"",w=d;h=!0,i&&(A("Generating recap\u2026"),j(T));let k;try{k=K(t)??void 0}catch{}s(R,y=>{!i&&d!==w||!v()||V(t,y).then(()=>{!i&&d!==w||!v()||(_=!0,S=d!==w,D(y),i&&A("Recap ready"))}).catch(L=>A(`Recap could not be saved: ${String(L)}`)).finally(()=>{h=!1})},m,k),setTimeout(()=>{h=!1},3e4).unref?.()},"requestRecap");n.registerCommand?.("recap",{description:"Generate a Goal/State recap and refresh the original generated session title",handler:a((i,e)=>{o=e.ui,u=e.sessionManager,f(e),x(!0)},"handler")}),n.on("session_start",(i,e)=>{o=e.ui,u=e.sessionManager,f(e),l=void 0,G(t).then(c=>{l=c.node}).catch(()=>{}),p=Date.now(),d=0,g=void 0,_=!1,S=!1,E=!1,h=!1,P()}),n.on("input",(i,e)=>{I()}),n.on("message_update",(i,e)=>{const c=i?.message;c?.role==="assistant"&&(g=c),I()}),n.on("turn_end",(i,e)=>{g=void 0,f(e),I()}),M!==void 0&&clearInterval(M);const N=setInterval(()=>{try{if(!v()||u===void 0||E||_&&!S||h||Date.now()-p<Y())return;x(!1)}catch{}},z);typeof N.unref=="function"&&N.unref(),M=N,n.on("session_shutdown",()=>{clearInterval(N),M===N&&(M=void 0)})}a(te,"registerCanvasRecap");var de=te;export{de as default,te as registerCanvasRecap};
10
+ `)}a(ee,"buildNamingConversation");function te(n,s=U,r){const t=B();if(t===void 0||t.trim()==="")return;let o,u,l,m;const f=a(i=>{const e=i.model?.provider?.trim(),c=i.model?.id?.trim();e&&c&&(m=`${e}/${c}`)},"captureLiveModel");let p=Date.now(),d=0,g,y=!1,_=!1,S=!1,h=!1;const v=a(()=>o!==void 0&&typeof o.setWidget=="function","canPaint"),A=a(i=>{try{o?.notify?.(i,"info")}catch{}},"notify"),P=a(()=>{if(v())try{o.setWidget($,void 0,{placement:"aboveEditor"})}catch{}},"clearRecap"),D=a(i=>{if(!v()||i==="")return;const e=i.split(`
11
+ `).filter(c=>c.trim()!=="");if(e.length!==0)try{o.setWidget($,e,{placement:"aboveEditor"})}catch{}},"showRecap"),I=a(()=>{p=Date.now(),d+=1,S=!1,y&&(_=!0)},"onMessage"),j=a(i=>{if(!(n.getSessionName===void 0||n.setSessionName===void 0)){if(r!==void 0){const e=n.getSessionName();if(e===void 0)return;r(t,i,()=>n.getSessionName?.()===e,c=>{try{n.setSessionName?.(c)}catch{}});return}G(t).then(({node:e})=>{if(e.name.trim()!==""&&e.name!==e.kind)return;const c=F(e);n.getSessionName?.()===c&&H(t,i,{name:e.name,description:e.description??"",title:e.title??"",icon:e.icon??"",kind:e.kind},()=>n.getSessionName?.()===c,R=>{try{n.setSessionName?.(R)}catch{}})}).catch(()=>{})}},"refreshAutomaticName"),x=a(i=>{if(!v()||u===void 0||h)return;const e=g,c=l?.review_binding?.review_id??u.getEntries().map(N=>N.details?.reviewId).find(N=>typeof N=="string"),R=Z(u,e,c);if(R===""){S=!0,y=!1,_=!1,P();return}S=!1;const T=i?ee(u,e,c):"",w=d;h=!0,i&&(A("Generating recap\u2026"),j(T)),K(t).catch(()=>null).then(N=>s(R,k=>{!i&&d!==w||!v()||V(t,k).then(()=>{!i&&d!==w||!v()||(y=!0,_=d!==w,D(k),i&&A("Recap ready"))}).catch(L=>A(`Recap could not be saved: ${String(L)}`)).finally(()=>{h=!1})},m,N??void 0)),setTimeout(()=>{h=!1},3e4).unref?.()},"requestRecap");n.registerCommand?.("recap",{description:"Generate a Goal/State recap and refresh the original generated session title",handler:a((i,e)=>{o=e.ui,u=e.sessionManager,f(e),x(!0)},"handler")}),n.on("session_start",(i,e)=>{o=e.ui,u=e.sessionManager,f(e),l=void 0,G(t).then(c=>{l=c.node}).catch(()=>{}),p=Date.now(),d=0,g=void 0,y=!1,_=!1,S=!1,h=!1,P()}),n.on("input",(i,e)=>{I()}),n.on("message_update",(i,e)=>{const c=i?.message;c?.role==="assistant"&&(g=c),I()}),n.on("turn_end",(i,e)=>{g=void 0,f(e),I()}),M!==void 0&&clearInterval(M);const E=setInterval(()=>{try{if(!v()||u===void 0||S||y&&!_||h||Date.now()-p<Y())return;x(!1)}catch{}},z);typeof E.unref=="function"&&E.unref(),M=E,n.on("session_shutdown",()=>{clearInterval(E),M===E&&(M=void 0)})}a(te,"registerCanvasRecap");var de=te;export{de as default,te as registerCanvasRecap};
@@ -26,7 +26,7 @@ interface PiLike {
26
26
  * node's primary job — so no persona is ever steered at a bare `node promote` (which framed promotion as a heavy
27
27
  * "become an orchestrator" step and bred yield-avoidance).
28
28
  *
29
- * - orchestrator (terminal OR resident): checkpoint context/roadmap.md, then
29
+ * - orchestrator (terminal OR resident): bring the roadmap current, then
30
30
  * yield (it already has a roadmap to bring current first).
31
31
  * - resident/base (root conversation): yield to continue fresh if the chat is
32
32
  * growing into a job, else wrap up — a root can simply end.
@@ -1 +1 @@
1
- var N=Object.defineProperty;var c=(n,t)=>N(n,"name",{value:t,configurable:!0});import{envNodeId as U}from"../shared/env.js";import{stripCdPrefix as q}from"../shared/strip-cd-prefix.js";import{contextDir as J}from"../core/canvas/paths.js";import{mutateBrokerFault as T,recordBrokerTelemetry as H,recordBrokerTurn as b,putBrokerTelemetry as W,clearBrokerPushedFinal as j,consumeBrokerPushedFinal as Y}from"../core/runtime/broker/daemon-ops.js";import{bindBrokerSession as z,brokerExtensionState as $,relaunchBrokerRoot as G,settleBroker as M}from"../core/runtime/broker/daemon-ops.js";import{emitEvent as C}from"../core/events/emit.js";import{activeBackgroundBashJobs as L}from"../core/bash-jobs.js";import{CONTEXT_NUDGE_CUSTOM_TYPE as V,formatCard as X}from"../shared/generated-context.js";import{isReviewBoundary as K}from"../core/runtime/session-visibility.js";import{clearRefusedTurn as Q,isRuntimeTeardownInProgress as Z,refuseTurn as ee,runRefreshAbort as te}from"../core/runtime/broker/extension-abort.js";import{announceMessageOrigin as P}from"../core/runtime/stamp/channel.js";const F=80;function ne(n,t){const a=t??{},s=c(m=>typeof m=="string"?m:"","pick"),g=q(s(a.command).trim())||s(a.path)||s(a.file_path)||s(a.pattern)||s(a.description)||s(a.prompt),y=(g!==""?`${n}: ${g}`:n).replace(/\s+/g," ").trim();return y.length>F?y.slice(0,F):y}c(ne,"summarizeActivity");function oe(n){for(let t=n.length-1;t>=0;t--)if(n[t]?.role==="assistant")return n[t]}c(oe,"lastAssistantMessage");function re(n){try{const t=n?.sessionManager?.getBranch();if(!Array.isArray(t))return[];const a=new Set;for(const s of t){if(!K(s))continue;const d=s.details?.reviewId;typeof d=="string"&&a.add(d)}return[...a]}catch{return[]}}c(re,"currentReviewBoundaryIds");const O=1e4,v=[13e4,15e4,17e4,185e3,2e5];function se(n){const t=v[0],a=v[v.length-1];if(n<t)return null;if(n>=a)return a+Math.floor((n-a)/O)*O;let s=t;for(const d of v)n>=d&&(s=d);return s}c(se,"steerBand");function ae(n,t,a){const s=Math.round(n/1e3),d=n>=185e3;if(a==="orchestrator")return n<15e4?`Context ~${s}k and growing. When you reach a good stopping point, consider updating context/roadmap.md and running \`crtr node yield\` to refresh against it \u2014 no rush yet.`:d?`Context ~${s}k \u2014 this is getting long. Stop taking on new work now: checkpoint context/roadmap.md, hand off anything outstanding, and \`crtr node yield\` immediately to refresh before this context overflows.`:`Context ~${s}k. Update context/roadmap.md so a fresh revive can continue, delegate any outstanding work, then \`crtr node yield\` to refresh.`;if(t==="resident"){const g="If substantial work remains, `crtr node yield` to continue fresh against your goal and your note. Add --promote only when worthwhile independent work can run in parallel and coordinating it should become your primary job; `crtr node yield -h` has the boundary.";return n<15e4?`Context ~${s}k and growing. ${g} Otherwise no rush \u2014 wrap up when you reach a good stopping point.`:d?`Context ~${s}k \u2014 this is getting long. Wrap up now before this context overflows: finish what's in hand, or \`crtr node yield\` immediately to continue fresh against your goal and your note if substantial work remains.`:`Context ~${s}k. ${g} If you're near done, just finish here; if there's more open-ended work, \`crtr node yield\` rather than letting this context grow.`}return n<15e4?`Context ~${s}k and growing. If you're near done, finish with \`crtr push final\`. If real work remains, \`crtr node yield\` to continue in a fresh window against your goal and your note \u2014 no rush yet.`:d?`Context ~${s}k \u2014 this is getting long. Wrap up now before this context overflows: \`crtr push final\` if you're close, otherwise \`crtr node yield\` immediately to continue in a fresh window against your goal and your note.`:`Context ~${s}k. If you're close, finish with \`crtr push final\`; otherwise \`crtr node yield\` now to refresh into a clean window and keep going against your goal and your note.`}c(ae,"steerNote");function ie(n){const t=U();if(t===void 0||t.trim()==="")return;let a=0,s=0,d="",g=null,y=null;const m=new Set,S=c(()=>L(J(t)).length>0,"backgroundJobsRunning"),l=c((e,r)=>{C({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:r,fields:{operation:e}})},"emitDaemonOperationFailure"),B=c((e,r)=>{if(e.action==="reprompt"){P(e.prompt,{type:"runtime",kind:"stop-guard"}),n.sendUserMessage(e.prompt,{deliverAs:"followUp"});return}if(e.action==="shutdown")try{r?.shutdown?.()}catch{}},"enactSettleDirective"),D=3e3;let I=0,k=Promise.resolve();const R=c((e,r)=>{const o=new Date().toISOString(),f={tokens_in:a,tokens_out:s,model:d,context_tokens:e,last_activity:r,updated_at:o};k=k.then(()=>W(t,f)).catch(u=>l("telemetry-record",u));const h={tokens_in:a,context_tokens:e,last_activity:r,updated_at:o};k=k.then(()=>H(t,h)).catch(u=>l("telemetry",u))},"publishTelemetry"),_=c(()=>{const e=Date.now();e-I<D||(I=e,Promise.all([b(t,{event:"progress"}),T(t,{op:"clear",link:"daemon\u2192node"})]).catch(r=>l("turn_progress",r)))},"heartbeat");n.on("session_start",async(e,r)=>{try{const o=r?.sessionManager?.getSessionId?.();if(typeof o!="string"||o==="")return;const f=r?.sessionManager?.getSessionFile?.(),h=typeof f=="string"&&f!==""?f:null,u=typeof e?.reason=="string"?e.reason:null;u==="new"&&(a=0,s=0,m.clear());const i=await z(t,{piSessionId:o,sessionFile:h,pid:process.pid,reason:u,reviewBoundaryIds:re(r)});if(i.action==="shutdown"){try{r?.shutdown?.()}catch{}return}if(i.action==="relaunch_root"){G(t).catch(p=>{const w=p instanceof Error?p.message:String(p);r?.ui?.notify?.(`/new refused: ${w}`,"error"),C({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:p,fields:{operation:"relaunch_root"}})});return}}catch(o){C({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:o,fields:{operation:"session_bound"}})}}),n.on("agent_start",async(e,r)=>{try{if(!(await b(t,{event:"started"})).applied)throw new Error("daemon refused turn open")}catch(o){l("turn_open",o),r?.ui?.notify?.("Turn refused: the broker no longer owns this node.","error"),ee(()=>r?.abort?.())}}),n.on("input",async()=>{Q();try{await j(t)}catch(e){throw l("clear_pushed_final",e),e}}),n.on("tool_execution_start",e=>{try{y=ne(String(e?.toolName??""),e?.args),R(g,y),_()}catch{}}),n.on("tool_execution_update",()=>{try{_()}catch{}}),n.on("message_update",()=>{try{_()}catch{}}),n.on("tool_execution_end",async(e,r)=>{try{if(_(),(await $(t)).node.intent==="refresh")try{te(()=>r?.abort?.())}catch{}}catch{}}),n.on("session_shutdown",async(e,r)=>{try{await b(t,{event:"closed",end_reason:"teardown-aborted"})}catch(o){l("turn_close_teardown",o)}if(e?.reason==="quit")try{const o=await M(t,{stopReason:"quit",backgroundJobsRunning:S(),pushedFinal:!1});B(o,r)}catch(o){l("settle_quit",o)}});const E=c(e=>{e?.role!=="assistant"||e.usage==null||(a+=Number(e.usage.input??0)||0,s+=Number(e.usage.output??0)||0,typeof e.model=="string"&&e.model!==""&&(d=e.model))},"accumulate");n.on("turn_end",async(e,r)=>{E(e?.message);let o=null;try{const i=r.getContextUsage()?.tokens;typeof i=="number"&&(o=i)}catch{}o!==null&&(g=o),R(o,y),_();try{await Promise.all([T(t,{op:"clear",link:"daemon\u2192node"}),T(t,{op:"clear",link:"pi\u2192provider"})])}catch(i){l("turn_end_fault_clear",i)}const f=Array.isArray(e?.message?.content)?e.message.content:[],h=e?.message?.stopReason??"",u=h!=="error"&&h!=="aborted"&&f.some(i=>i?.type==="toolCall");try{const p=(await $(t)).node,w=o!==null?se(o):null;if(w!==null&&!m.has(w)){m.add(w);const A=X("context-nudge",{},ae(w,p.lifecycle,p.mode));u?(P(A,{type:"runtime",kind:"context-nudge"}),n.sendUserMessage(A,{deliverAs:"steer"})):n.sendMessage({customType:V,content:A,display:!0},{deliverAs:"nextTurn"})}}catch(i){l("turn_boundary",i)}});let x=null;n.on("agent_end",e=>{x=e;try{const r=Array.isArray(e?.messages)?e.messages:[];for(const o of r)E(o)}catch{}}),n.on("agent_settled",async(e,r)=>{const o=x;if(x=null,Z())return;try{await b(t,{event:"closed",end_reason:"settled"})}catch(i){l("turn_close",i);return}const f=Array.isArray(o?.messages)?o.messages:[],h=oe(f),u=typeof h?.stopReason=="string"?h.stopReason:"";try{const i=o===null?{pushedFinal:!1}:await Y(t),p=await M(t,{stopReason:u,backgroundJobsRunning:S(),pushedFinal:i.pushedFinal});B(p,r)}catch(i){l("settle",i)}})}c(ie,"registerCanvasStophook");var ke=ie;export{ke as default,ie as registerCanvasStophook,ae as steerNote};
1
+ var N=Object.defineProperty;var c=(n,t)=>N(n,"name",{value:t,configurable:!0});import{envNodeId as U}from"../shared/env.js";import{stripCdPrefix as q}from"../shared/strip-cd-prefix.js";import{contextDir as J}from"../core/canvas/paths.js";import{mutateBrokerFault as T,recordBrokerTelemetry as H,recordBrokerTurn as b,putBrokerTelemetry as W,clearBrokerPushedFinal as j,consumeBrokerPushedFinal as Y}from"../core/runtime/broker/daemon-ops.js";import{bindBrokerSession as z,brokerExtensionState as $,relaunchBrokerRoot as G,settleBroker as M}from"../core/runtime/broker/daemon-ops.js";import{emitEvent as C}from"../core/events/emit.js";import{activeBackgroundBashJobs as L}from"../core/bash-jobs.js";import{CONTEXT_NUDGE_CUSTOM_TYPE as V,formatCard as X}from"../shared/generated-context.js";import{isReviewBoundary as K}from"../core/runtime/session-visibility.js";import{clearRefusedTurn as Q,isRuntimeTeardownInProgress as Z,refuseTurn as ee,runRefreshAbort as te}from"../core/runtime/broker/extension-abort.js";import{announceMessageOrigin as P}from"../core/runtime/stamp/channel.js";const F=80;function ne(n,t){const a=t??{},s=c(m=>typeof m=="string"?m:"","pick"),g=q(s(a.command).trim())||s(a.path)||s(a.file_path)||s(a.pattern)||s(a.description)||s(a.prompt),y=(g!==""?`${n}: ${g}`:n).replace(/\s+/g," ").trim();return y.length>F?y.slice(0,F):y}c(ne,"summarizeActivity");function re(n){for(let t=n.length-1;t>=0;t--)if(n[t]?.role==="assistant")return n[t]}c(re,"lastAssistantMessage");function oe(n){try{const t=n?.sessionManager?.getBranch();if(!Array.isArray(t))return[];const a=new Set;for(const s of t){if(!K(s))continue;const d=s.details?.reviewId;typeof d=="string"&&a.add(d)}return[...a]}catch{return[]}}c(oe,"currentReviewBoundaryIds");const O=1e4,v=[13e4,15e4,17e4,185e3,2e5];function se(n){const t=v[0],a=v[v.length-1];if(n<t)return null;if(n>=a)return a+Math.floor((n-a)/O)*O;let s=t;for(const d of v)n>=d&&(s=d);return s}c(se,"steerBand");function ae(n,t,a){const s=Math.round(n/1e3),d=n>=185e3;if(a==="orchestrator")return n<15e4?`Context ~${s}k and growing. When you reach a good stopping point, consider updating your roadmap (\`crtr doc edit roadmap\`) and running \`crtr node yield\` to refresh against it \u2014 no rush yet.`:d?`Context ~${s}k \u2014 this is getting long. Stop taking on new work now: bring your roadmap current, hand off anything outstanding, and \`crtr node yield\` immediately to refresh before this context overflows.`:`Context ~${s}k. Update your roadmap (\`crtr doc edit roadmap\`) so a fresh revive can continue, delegate any outstanding work, then \`crtr node yield\` to refresh.`;if(t==="resident"){const g="If substantial work remains, `crtr node yield` to continue fresh against your goal and your note. Add --promote only when worthwhile independent work can run in parallel and coordinating it should become your primary job; `crtr node yield -h` has the boundary.";return n<15e4?`Context ~${s}k and growing. ${g} Otherwise no rush \u2014 wrap up when you reach a good stopping point.`:d?`Context ~${s}k \u2014 this is getting long. Wrap up now before this context overflows: finish what's in hand, or \`crtr node yield\` immediately to continue fresh against your goal and your note if substantial work remains.`:`Context ~${s}k. ${g} If you're near done, just finish here; if there's more open-ended work, \`crtr node yield\` rather than letting this context grow.`}return n<15e4?`Context ~${s}k and growing. If you're near done, finish with \`crtr push final\`. If real work remains, \`crtr node yield\` to continue in a fresh window against your goal and your note \u2014 no rush yet.`:d?`Context ~${s}k \u2014 this is getting long. Wrap up now before this context overflows: \`crtr push final\` if you're close, otherwise \`crtr node yield\` immediately to continue in a fresh window against your goal and your note.`:`Context ~${s}k. If you're close, finish with \`crtr push final\`; otherwise \`crtr node yield\` now to refresh into a clean window and keep going against your goal and your note.`}c(ae,"steerNote");function ie(n){const t=U();if(t===void 0||t.trim()==="")return;let a=0,s=0,d="",g=null,y=null;const m=new Set,S=c(()=>L(J(t)).length>0,"backgroundJobsRunning"),u=c((e,o)=>{C({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:o,fields:{operation:e}})},"emitDaemonOperationFailure"),B=c((e,o)=>{if(e.action==="reprompt"){P(e.prompt,{type:"runtime",kind:"stop-guard"}),n.sendUserMessage(e.prompt,{deliverAs:"followUp"});return}if(e.action==="shutdown")try{o?.shutdown?.()}catch{}},"enactSettleDirective"),D=3e3;let I=0,k=Promise.resolve();const R=c((e,o)=>{const r=new Date().toISOString(),f={tokens_in:a,tokens_out:s,model:d,context_tokens:e,last_activity:o,updated_at:r};k=k.then(()=>W(t,f)).catch(l=>u("telemetry-record",l));const h={tokens_in:a,context_tokens:e,last_activity:o,updated_at:r};k=k.then(()=>H(t,h)).catch(l=>u("telemetry",l))},"publishTelemetry"),_=c(()=>{const e=Date.now();e-I<D||(I=e,Promise.all([b(t,{event:"progress"}),T(t,{op:"clear",link:"daemon\u2192node"})]).catch(o=>u("turn_progress",o)))},"heartbeat");n.on("session_start",async(e,o)=>{try{const r=o?.sessionManager?.getSessionId?.();if(typeof r!="string"||r==="")return;const f=o?.sessionManager?.getSessionFile?.(),h=typeof f=="string"&&f!==""?f:null,l=typeof e?.reason=="string"?e.reason:null;l==="new"&&(a=0,s=0,m.clear());const i=await z(t,{piSessionId:r,sessionFile:h,pid:process.pid,reason:l,reviewBoundaryIds:oe(o)});if(i.action==="shutdown"){try{o?.shutdown?.()}catch{}return}if(i.action==="relaunch_root"){G(t).catch(p=>{const w=p instanceof Error?p.message:String(p);o?.ui?.notify?.(`/new refused: ${w}`,"error"),C({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:p,fields:{operation:"relaunch_root"}})});return}}catch(r){C({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:r,fields:{operation:"session_bound"}})}}),n.on("agent_start",async(e,o)=>{try{if(!(await b(t,{event:"started"})).applied)throw new Error("daemon refused turn open")}catch(r){u("turn_open",r),o?.ui?.notify?.("Turn refused: the broker no longer owns this node.","error"),ee(()=>o?.abort?.())}}),n.on("input",async()=>{Q();try{await j(t)}catch(e){throw u("clear_pushed_final",e),e}}),n.on("tool_execution_start",e=>{try{y=ne(String(e?.toolName??""),e?.args),R(g,y),_()}catch{}}),n.on("tool_execution_update",()=>{try{_()}catch{}}),n.on("message_update",()=>{try{_()}catch{}}),n.on("tool_execution_end",async(e,o)=>{try{if(_(),(await $(t)).node.intent==="refresh")try{te(()=>o?.abort?.())}catch{}}catch{}}),n.on("session_shutdown",async(e,o)=>{try{await b(t,{event:"closed",end_reason:"teardown-aborted"})}catch(r){u("turn_close_teardown",r)}if(e?.reason==="quit")try{const r=await M(t,{stopReason:"quit",backgroundJobsRunning:S(),pushedFinal:!1});B(r,o)}catch(r){u("settle_quit",r)}});const E=c(e=>{e?.role!=="assistant"||e.usage==null||(a+=Number(e.usage.input??0)||0,s+=Number(e.usage.output??0)||0,typeof e.model=="string"&&e.model!==""&&(d=e.model))},"accumulate");n.on("turn_end",async(e,o)=>{E(e?.message);let r=null;try{const i=o.getContextUsage()?.tokens;typeof i=="number"&&(r=i)}catch{}r!==null&&(g=r),R(r,y),_();try{await Promise.all([T(t,{op:"clear",link:"daemon\u2192node"}),T(t,{op:"clear",link:"pi\u2192provider"})])}catch(i){u("turn_end_fault_clear",i)}const f=Array.isArray(e?.message?.content)?e.message.content:[],h=e?.message?.stopReason??"",l=h!=="error"&&h!=="aborted"&&f.some(i=>i?.type==="toolCall");try{const p=(await $(t)).node,w=r!==null?se(r):null;if(w!==null&&!m.has(w)){m.add(w);const A=X("context-nudge",{},ae(w,p.lifecycle,p.mode));l?(P(A,{type:"runtime",kind:"context-nudge"}),n.sendUserMessage(A,{deliverAs:"steer"})):n.sendMessage({customType:V,content:A,display:!0},{deliverAs:"nextTurn"})}}catch(i){u("turn_boundary",i)}});let x=null;n.on("agent_end",e=>{x=e;try{const o=Array.isArray(e?.messages)?e.messages:[];for(const r of o)E(r)}catch{}}),n.on("agent_settled",async(e,o)=>{const r=x;if(x=null,Z())return;try{await b(t,{event:"closed",end_reason:"settled"})}catch(i){u("turn_close",i);return}const f=Array.isArray(r?.messages)?r.messages:[],h=re(f),l=typeof h?.stopReason=="string"?h.stopReason:"";try{const i=r===null?{pushedFinal:!1}:await Y(t),p=await M(t,{stopReason:l,backgroundJobsRunning:S(),pushedFinal:i.pushedFinal});B(p,o)}catch(i){u("settle",i)}})}c(ie,"registerCanvasStophook");var ke=ie;export{ke as default,ie as registerCanvasStophook,ae as steerNote};
@@ -32,9 +32,9 @@ seams to fall between \u2014 skip it for self-contained specs.
32
32
 
33
33
  For larger specs touching established patterns, optionally spawn a Task
34
34
  agent (\`general-purpose\`, \`sonnet\`) to cross-check the spec's design
35
- against the applicable project memory documents (discover them with
36
- \`crtr memory list\` and load them with \`crtr memory read\`) and the files they
37
- reference, looking for contradictions with project conventions. Skip for small
35
+ against the repo's documents (discover them with \`crtr canvas list --type document\`
36
+ or \`crtr canvas search\` and load them with \`crtr canvas read\`) and the files
37
+ they reference, looking for contradictions with project conventions. Skip for small
38
38
  specs.
39
39
 
40
40
  ## Calibration
@@ -4,6 +4,11 @@ export declare function envNodeId(): string | undefined;
4
4
  export declare function isSandboxedNode(): boolean;
5
5
  /** The app that owns the current node, supplied in its broker launch identity. */
6
6
  export declare function envGrantee(): string | undefined;
7
+ /** Set to '1' by `nodeEnv` for an app-started run's brokers, which admit inbox
8
+ * mail only between agent runs. Terminal nodes also carry `CRTR_RUN_ID`, so
9
+ * that variable is not this signal. */
10
+ export declare const INBOX_BETWEEN_TURNS_ENV = "CRTR_INBOX_BETWEEN_TURNS";
11
+ export declare function envInboxBetweenTurns(): boolean;
7
12
  /** The current run's scope allow-list; null means the row inherits everything. */
8
13
  export declare function envScopes(): readonly string[] | null;
9
14
  /** Whether a launched scope list covers a capability. Null means not narrowed. */
@@ -1 +1 @@
1
- var _=Object.defineProperty;var e=(n,r)=>_(n,"name",{value:r,configurable:!0});import{covers as R}from"@north-light/crouter-identity";function c(){return process.env.CRTR_NODE_ID}e(c,"envNodeId");function x(){return process.platform==="linux"&&!!(c()&&process.env.CRTR_API_SOCKET)}e(x,"isSandboxedNode");function S(){return process.env.CRTR_GRANTEE}e(S,"envGrantee");function N(){const n=process.env.CRTR_SCOPES;return n===void 0?null:n===""?[]:n.split(",")}e(N,"envScopes");function a(n,r){return n==null?!0:n.some(o=>R(o,r))}e(a,"scopeAllowed");function O(){return process.env.CRTR_EXECUTION_ID}e(O,"envExecutionId");function I(){return process.env.CRTR_PROFILE_ID}e(I,"envProfileId");function L(){return process.env.CRTR_NODE_CWD}e(L,"envNodeCwd");function P(){return process.env.CRTR_MODEL_INTENT}e(P,"envModelIntent");function B(){return process.env.CRTR_MODEL_EXACT==="1"}e(B,"envModelExact");function U(){return process.env.CRTR_HOME}e(U,"envHomeOverride");function m(){return process.env.CRTR_RUNTIME_HOME}e(m,"envRuntimeHomeOverride");function t(n,r){if(n===void 0)return r;const o=Number(n);return Number.isFinite(o)&&o>0?o:r}e(t,"parsePositiveMs");const i=5*6e4;function l(){return t(process.env.CRTR_STREAM_WATCHDOG_MS,i)}e(l,"envStreamWatchdogMs");const p=800;function H(){return t(process.env.CRTR_WATCHER_TICK_MS,p)}e(H,"envWatcherTickMs");const T=1e3;function G(){return t(process.env.CRTR_WATCHER_DEBOUNCE_MS,T)}e(G,"envWatcherDebounceMs");const v=6e4;function F(){return t(process.env.CRTR_RECAP_IDLE_MS,v)}e(F,"envRecapIdleMs");function K(){const n=process.env.CRTR_RECAP_MODEL;return n!==void 0&&n.trim()!==""?n.trim():void 0}e(K,"envRecapModelOverride");const E=300*1e3;function W(){return t(process.env.CRTR_BASH_VALVE_MS,E)}e(W,"envBashValveMs");const d=60*1e3;function k(){return t(process.env.CRTR_BASH_AUTO_BG_DEADLINE_MS,d)}e(k,"envBashAutoBgDeadlineMs");function b(){const n=process.env.CRTR_PIDFILE;return n!==void 0&&n!==""?n:void 0}e(b,"envPidfileOverride");const f="@earendil-works/pi-coding-agent";function g(){return process.env.CRTR_BROKER_ENGINE??f}e(g,"envBrokerEngine");function V(){return process.env.CRTR_PI_BINARY}e(V,"envPiBinaryOverride");function h(){return process.env.CRTR_NO_DAEMON_AUTOSTART==="1"}e(h,"envNoDaemonAutostart");function X(){return process.env.CRTRD_TCP}e(X,"envCrtrdTcp");function w(){const n=process.env.CRTRD_TOKEN;return n!==void 0&&n!==""?n:void 0}e(w,"envCrtrdToken");function y(){return process.env.CRTR_NO_EXPORTS==="1"}e(y,"envNoExports");function Y(){return process.env.CRTR_DEBUG==="1"}e(Y,"envDebug");function u(n){if(n===void 0||n==="")return;const r=Number(n);return Number.isSafeInteger(r)&&r>=1?r:void 0}e(u,"parsePositiveInteger");function j(){return u(process.env.CRTR_MAX_LIVE_BROKERS)}e(j,"envMaxLiveBrokers");function q(){return u(process.env.CRTR_WARN_LIVE_BROKERS)}e(q,"envWarnLiveBrokers");function s(n){if(n===void 0)return;const r=Number(n);return Number.isFinite(r)&&r>0?r:void 0}e(s,"parsePositiveMsNoDefault");function z(){return s(process.env.CRTR_TEST_UNATTENDED_PARK_MS)}e(z,"envTestUnattendedParkMs");function J(){return s(process.env.CRTR_UNATTENDED_PARK_MS)}e(J,"envUnattendedParkMs");function C(){return s(process.env.CRTR_TEST_PARK_SUMMARY_GRACE_MS)}e(C,"envTestParkSummaryGraceMs");const A=5*6e4;function Q(){return C()??A}e(Q,"parkSummaryGraceMs");export{k as envBashAutoBgDeadlineMs,W as envBashValveMs,g as envBrokerEngine,X as envCrtrdTcp,w as envCrtrdToken,Y as envDebug,O as envExecutionId,S as envGrantee,U as envHomeOverride,j as envMaxLiveBrokers,B as envModelExact,P as envModelIntent,h as envNoDaemonAutostart,y as envNoExports,L as envNodeCwd,c as envNodeId,V as envPiBinaryOverride,b as envPidfileOverride,I as envProfileId,F as envRecapIdleMs,K as envRecapModelOverride,m as envRuntimeHomeOverride,N as envScopes,l as envStreamWatchdogMs,C as envTestParkSummaryGraceMs,z as envTestUnattendedParkMs,J as envUnattendedParkMs,q as envWarnLiveBrokers,G as envWatcherDebounceMs,H as envWatcherTickMs,x as isSandboxedNode,Q as parkSummaryGraceMs,a as scopeAllowed};
1
+ var _=Object.defineProperty;var e=(n,r)=>_(n,"name",{value:r,configurable:!0});import{covers as R}from"@north-light/crouter-identity";function c(){return process.env.CRTR_NODE_ID}e(c,"envNodeId");function D(){return process.platform==="linux"&&!!(c()&&process.env.CRTR_API_SOCKET)}e(D,"isSandboxedNode");function S(){return process.env.CRTR_GRANTEE}e(S,"envGrantee");const i="CRTR_INBOX_BETWEEN_TURNS";function a(){return process.env[i]==="1"}e(a,"envInboxBetweenTurns");function O(){const n=process.env.CRTR_SCOPES;return n===void 0?null:n===""?[]:n.split(",")}e(O,"envScopes");function I(n,r){return n==null?!0:n.some(o=>R(o,r))}e(I,"scopeAllowed");function B(){return process.env.CRTR_EXECUTION_ID}e(B,"envExecutionId");function U(){return process.env.CRTR_PROFILE_ID}e(U,"envProfileId");function L(){return process.env.CRTR_NODE_CWD}e(L,"envNodeCwd");function P(){return process.env.CRTR_MODEL_INTENT}e(P,"envModelIntent");function m(){return process.env.CRTR_MODEL_EXACT==="1"}e(m,"envModelExact");function l(){return process.env.CRTR_HOME}e(l,"envHomeOverride");function H(){return process.env.CRTR_RUNTIME_HOME}e(H,"envRuntimeHomeOverride");function t(n,r){if(n===void 0)return r;const o=Number(n);return Number.isFinite(o)&&o>0?o:r}e(t,"parsePositiveMs");const T=5*6e4;function W(){return t(process.env.CRTR_STREAM_WATCHDOG_MS,T)}e(W,"envStreamWatchdogMs");const p=800;function G(){return t(process.env.CRTR_WATCHER_TICK_MS,p)}e(G,"envWatcherTickMs");const E=1e3;function F(){return t(process.env.CRTR_WATCHER_DEBOUNCE_MS,E)}e(F,"envWatcherDebounceMs");const v=6e4;function K(){return t(process.env.CRTR_RECAP_IDLE_MS,v)}e(K,"envRecapIdleMs");function b(){const n=process.env.CRTR_RECAP_MODEL;return n!==void 0&&n.trim()!==""?n.trim():void 0}e(b,"envRecapModelOverride");const f=300*1e3;function k(){return t(process.env.CRTR_BASH_VALVE_MS,f)}e(k,"envBashValveMs");const d=60*1e3;function g(){return t(process.env.CRTR_BASH_AUTO_BG_DEADLINE_MS,d)}e(g,"envBashAutoBgDeadlineMs");function V(){const n=process.env.CRTR_PIDFILE;return n!==void 0&&n!==""?n:void 0}e(V,"envPidfileOverride");const C="@earendil-works/pi-coding-agent";function X(){return process.env.CRTR_BROKER_ENGINE??C}e(X,"envBrokerEngine");function h(){return process.env.CRTR_PI_BINARY}e(h,"envPiBinaryOverride");function w(){return process.env.CRTR_NO_DAEMON_AUTOSTART==="1"}e(w,"envNoDaemonAutostart");function y(){return process.env.CRTRD_TCP}e(y,"envCrtrdTcp");function Y(){const n=process.env.CRTRD_TOKEN;return n!==void 0&&n!==""?n:void 0}e(Y,"envCrtrdToken");function j(){return process.env.CRTR_NO_EXPORTS==="1"}e(j,"envNoExports");function q(){return process.env.CRTR_DEBUG==="1"}e(q,"envDebug");function u(n){if(n===void 0||n==="")return;const r=Number(n);return Number.isSafeInteger(r)&&r>=1?r:void 0}e(u,"parsePositiveInteger");function z(){return u(process.env.CRTR_MAX_LIVE_BROKERS)}e(z,"envMaxLiveBrokers");function J(){return u(process.env.CRTR_WARN_LIVE_BROKERS)}e(J,"envWarnLiveBrokers");function s(n){if(n===void 0)return;const r=Number(n);return Number.isFinite(r)&&r>0?r:void 0}e(s,"parsePositiveMsNoDefault");function Q(){return s(process.env.CRTR_TEST_UNATTENDED_PARK_MS)}e(Q,"envTestUnattendedParkMs");function Z(){return s(process.env.CRTR_UNATTENDED_PARK_MS)}e(Z,"envUnattendedParkMs");function A(){return s(process.env.CRTR_TEST_PARK_SUMMARY_GRACE_MS)}e(A,"envTestParkSummaryGraceMs");const M=5*6e4;function $(){return A()??M}e($,"parkSummaryGraceMs");export{i as INBOX_BETWEEN_TURNS_ENV,g as envBashAutoBgDeadlineMs,k as envBashValveMs,X as envBrokerEngine,y as envCrtrdTcp,Y as envCrtrdToken,q as envDebug,B as envExecutionId,S as envGrantee,l as envHomeOverride,a as envInboxBetweenTurns,z as envMaxLiveBrokers,m as envModelExact,P as envModelIntent,w as envNoDaemonAutostart,j as envNoExports,L as envNodeCwd,c as envNodeId,h as envPiBinaryOverride,V as envPidfileOverride,U as envProfileId,K as envRecapIdleMs,b as envRecapModelOverride,H as envRuntimeHomeOverride,O as envScopes,W as envStreamWatchdogMs,A as envTestParkSummaryGraceMs,Q as envTestUnattendedParkMs,Z as envUnattendedParkMs,J as envWarnLiveBrokers,F as envWatcherDebounceMs,G as envWatcherTickMs,D as isSandboxedNode,$ as parkSummaryGraceMs,I as scopeAllowed};
@@ -1,11 +1,3 @@
1
- var T=Object.defineProperty;var o=(e,t)=>T(e,"name",{value:t,configurable:!0});const R="crtr-context",_="crtr-situational-context",E="crtr-context-nudge",v="crtr-review-boundary",$="You've stopped but you're not waiting on anyone and haven't finished. Pipe the result to `crtr push final` through a single-quoted heredoc if the work is done, or use `crtr human send` if you are blocked or need the user.",L=`This conversation has been idle with nothing left to wake it, so it is being concluded. This is your last turn. Use it to leave a trustworthy inheritance, not to restart or broaden the work. Do these four things now, then stop.
2
-
3
- 1. Establish current truth. Check only state that may have changed outside the transcript and matters to resuming\u2014such as the working tree, a remote run, or an external decision. Do not start new work; perform only a quick check needed to avoid recording an unverified claim. If no mandate or work ever began, record that plainly in the inheritance and keep every artifact minimal.
4
-
5
- 2. Put supporting material in your context directory only when it is needed to keep the inheritance concise. Rewrite existing living documents rather than leave superseded versions. Task state, identifiers, and recovery detail belong here, not in memory.
6
-
7
- 3. Use memory only for a non-obvious, reusable lesson that should survive this task and is not already recorded. Read \`crtr memory write -h\`, find before writing, and choose the narrowest scope that will reach the next agent who needs it. Do not put a conversation recap, task status, recovery handles, or facts already captured in code or docs into memory.
8
-
9
- 4. Push exactly one regular update with \`crtr push update --tier deferred\`, never \`crtr push final\`. Write for someone who has not seen this conversation: name the work in plain terms, say where it stands, and say what remains or is blocked. Put the current outcome in the first line; include only needed decisions and recovery handles, then stop.`,N="Provider credentials were just updated (a new login landed). Your previous turn stopped on a provider authentication failure. Continue from where you left off and retry the work that failed.",M="The network connection is back online. Your previous turn stopped on a connection error (the network was down). Continue from where you left off and retry the work that failed.",S="Your previous turn stopped on a provider fault. Continue from where you left off and retry the work that failed.",D="<crtr-review-approval>",j="</crtr-review-approval>",V="<model-fallback-recovery>",F="</model-fallback-recovery>",O='You must submit a result matching the required schema with `crtr push result` before you can stop, or decline it with `crtr push result --decline "<reason>" --code <token>` when the schema cannot be honestly satisfied. You cannot finish or go dormant any other way while this request is pending.\n\nRequired schema:\n\n```json\n',A="\n```";function B(e){return`${O}${e}${A}`}o(B,"formatStructuredOutputReprompt");function X(e,t,n){return n==="credential"?`The previous model (${e}) had no usable provider credential, so you were automatically switched to ${t}. Continue the task from where the failed turn left off.`:`The previous model (${e}) was unavailable (provider 404 not_found), so you were automatically switched to ${t}. Continue the task from where the failed turn left off.`}o(X,"formatModelFallbackRecovery");function x(e){switch(e){case E:return"context-nudge";case R:return"bearings";case v:return"review-boundary";case _:return"situational";default:return}}o(x,"legacyCustomTypeKind");const g=/^[A-Za-z_:][A-Za-z0-9_:.-]*$/,l=/\s+([A-Za-z_:][A-Za-z0-9_:.-]*)\s*=\s*(?:"([^"]*)"|'([^']*)')/gy;function k(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}o(k,"escapeXmlAttribute");function y(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;")}o(y,"escapeXmlText");function h(e){return e.replace(/&(?:amp|lt|gt|quot|apos);/g,t=>({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&apos;":"'"})[t])}o(h,"unescapeXmlAttribute");function f(e){const t={};l.lastIndex=0;let n=0;for(;n<e.length&&!/^\s*$/.test(e.slice(n));){l.lastIndex=n;const i=l.exec(e);if(i===null)return null;const[,r,a,u]=i;if(r===void 0||Object.hasOwn(t,r))return null;t[r]=h(a??u??""),n=l.lastIndex}return t}o(f,"parseAttributes");function p(e){return Object.entries(e).filter(([,t])=>t!==void 0).map(([t,n])=>{if(!g.test(t))throw new Error(`Invalid XML attribute name: ${t}`);return` ${t}="${k(String(n))}"`}).join("")}o(p,"formatAttributes");function C(e){return typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.filter(t=>typeof t=="object"&&t!==null&&t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(""):""}o(C,"generatedContextText");function w(e,t,n){if(e==="")throw new Error("Runtime card kind is required");if(Object.hasOwn(t,"kind"))throw new Error("Runtime card facts cannot replace kind");return`<runtime${p({kind:e,...t})}>${n}</runtime>`}o(w,"formatCard");function q(e,t,n){return w(e,t,y(n))}o(q,"formatDataCard");function P(e){const t=[],n=/<from\b([^>]*)>([\s\S]*?)<\/from>/g;for(const i of e.matchAll(n)){const r=f(i[1]??"");if(r?.id===void 0)continue;const a=[],u=i[2]??"",c=/<entry\b([^>]*)>([\s\S]*?)<\/entry>/g;for(const d of u.matchAll(c)){const s=f(d[1]??"");if(s?.kind===void 0)continue;const b=s.disposition==="human-answer"||s.disposition==="human-canceled"?s.disposition:"report";a.push({kind:s.kind,disposition:b,body:h(d[2]??""),...s.ref===void 0?{}:{ref:s.ref}})}const m=r.updates===void 0?Number.NaN:Number(r.updates);t.push({id:r.id,updates:Number.isFinite(m)?m:a.length,finished:r.finished==="true"||a.some(d=>d.kind==="final"),entries:a})}return t}o(P,"parseInboxBody");function U(e,t,n,i){return{kind:e,facts:t,body:n,senders:i}}o(U,"cardFor");function I(e){const t=/^<runtime\b([^>]*)>/.exec(e);if(t===null||!e.endsWith("</runtime>"))return null;const n=f(t[1]??"");if(n?.kind===void 0)return null;const i=e.slice(t[0].length,-10),{kind:r,...a}=n,u=Object.freeze(a),c=r.includes(":")?h(i):i;return U(r,u,c,r==="inbox"?P(c):[])}o(I,"parseEnvelope");function z(e){const t=C(e),n=I(t);if(n!==null)return n;if(e.role!=="custom")return null;const i=x(e.customType);return i===void 0?null:{kind:i,facts:Object.freeze({}),body:t,senders:[]}}o(z,"parseCard");function W(e){return e.startsWith("/")?`Preview only. Read the full body from file \`${e}\`.`:`Read this report with \`crtr canvas history read ${e}\`.`}o(W,"formatInboxRefInstruction");function K(e){const t=e.map(n=>{const i=n.entries.map(r=>{const a=r.disposition==="human-answer"||r.disposition==="human-canceled"?r.disposition:void 0;return`<entry${p({kind:r.kind,ref:r.ref,disposition:a})}>${y(r.body)}</entry>`}).join(`
1
+ var T=Object.defineProperty;var o=(e,t)=>T(e,"name",{value:t,configurable:!0});const v="crtr-context",R="crtr-situational-context",_="crtr-context-nudge",E="crtr-review-boundary",$="You've stopped but you're not waiting on anyone and haven't finished. Pipe the result to `crtr push final` through a single-quoted heredoc if the work is done, or use `crtr human send` if you are blocked or need the user.",L="This conversation has been idle with nothing left to wake it, so it is being concluded. This is your last turn. Use it to leave a trustworthy inheritance, not to restart or broaden the work. Do these four things now, then stop.\n\n1. Establish current truth. Check only state that may have changed outside the transcript and matters to resuming\u2014such as the working tree, a remote run, or an external decision. Do not start new work; perform only a quick check needed to avoid recording an unverified claim. If no mandate or work ever began, record that plainly in the inheritance and keep every artifact minimal.\n\n2. Put supporting material in documents you own (`crtr doc write`) only when it is needed to keep the inheritance concise. Rewrite existing living documents rather than leave superseded versions. Task state, identifiers, and recovery detail belong here, under this node, not under a longer-lived owner.\n\n3. Give a longer-lived owner (`--owner repo|profile|user`) only to a non-obvious, reusable lesson that should survive this task and is not already recorded. Read `crtr doc write -h`, search before writing (`crtr canvas search`), and choose the narrowest owner that will reach the next agent who needs it. Do not put a conversation recap, task status, recovery handles, or facts already captured in code or docs into such a document.\n\n4. Push exactly one regular update with `crtr push update --tier deferred`, never `crtr push final`. Write for someone who has not seen this conversation: name the work in plain terms, say where it stands, and say what remains or is blocked. Put the current outcome in the first line; include only needed decisions and recovery handles, then stop.",N="Provider credentials were just updated (a new login landed). Your previous turn stopped on a provider authentication failure. Continue from where you left off and retry the work that failed.",M="The network connection is back online. Your previous turn stopped on a connection error (the network was down). Continue from where you left off and retry the work that failed.",S="Your previous turn stopped on a provider fault. Continue from where you left off and retry the work that failed.",D="<crtr-review-approval>",j="</crtr-review-approval>",V="<model-fallback-recovery>",F="</model-fallback-recovery>",O='You must submit a result matching the required schema with `crtr push result` before you can stop, or decline it with `crtr push result --decline "<reason>" --code <token>` when the schema cannot be honestly satisfied. You cannot finish or go dormant any other way while this request is pending.\n\nRequired schema:\n\n```json\n',g="\n```";function B(e){return`${O}${e}${g}`}o(B,"formatStructuredOutputReprompt");function X(e,t,n){return n==="credential"?`The previous model (${e}) had no usable provider credential, so you were automatically switched to ${t}. Continue the task from where the failed turn left off.`:`The previous model (${e}) was unavailable (provider 404 not_found), so you were automatically switched to ${t}. Continue the task from where the failed turn left off.`}o(X,"formatModelFallbackRecovery");function A(e){switch(e){case _:return"context-nudge";case v:return"bearings";case E:return"review-boundary";case R:return"situational";default:return}}o(A,"legacyCustomTypeKind");const x=/^[A-Za-z_:][A-Za-z0-9_:.-]*$/,l=/\s+([A-Za-z_:][A-Za-z0-9_:.-]*)\s*=\s*(?:"([^"]*)"|'([^']*)')/gy;function k(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}o(k,"escapeXmlAttribute");function w(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;")}o(w,"escapeXmlText");function h(e){return e.replace(/&(?:amp|lt|gt|quot|apos);/g,t=>({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&apos;":"'"})[t])}o(h,"unescapeXmlAttribute");function f(e){const t={};l.lastIndex=0;let n=0;for(;n<e.length&&!/^\s*$/.test(e.slice(n));){l.lastIndex=n;const i=l.exec(e);if(i===null)return null;const[,r,a,u]=i;if(r===void 0||Object.hasOwn(t,r))return null;t[r]=h(a??u??""),n=l.lastIndex}return t}o(f,"parseAttributes");function p(e){return Object.entries(e).filter(([,t])=>t!==void 0).map(([t,n])=>{if(!x.test(t))throw new Error(`Invalid XML attribute name: ${t}`);return` ${t}="${k(String(n))}"`}).join("")}o(p,"formatAttributes");function C(e){return typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.filter(t=>typeof t=="object"&&t!==null&&t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(""):""}o(C,"generatedContextText");function y(e,t,n){if(e==="")throw new Error("Runtime card kind is required");if(Object.hasOwn(t,"kind"))throw new Error("Runtime card facts cannot replace kind");return`<runtime${p({kind:e,...t})}>${n}</runtime>`}o(y,"formatCard");function q(e,t,n){return y(e,t,w(n))}o(q,"formatDataCard");function P(e){const t=[],n=/<from\b([^>]*)>([\s\S]*?)<\/from>/g;for(const i of e.matchAll(n)){const r=f(i[1]??"");if(r?.id===void 0)continue;const a=[],u=i[2]??"",c=/<entry\b([^>]*)>([\s\S]*?)<\/entry>/g;for(const d of u.matchAll(c)){const s=f(d[1]??"");if(s?.kind===void 0)continue;const b=s.disposition==="human-answer"||s.disposition==="human-canceled"?s.disposition:"report";a.push({kind:s.kind,disposition:b,body:h(d[2]??""),...s.ref===void 0?{}:{ref:s.ref}})}const m=r.updates===void 0?Number.NaN:Number(r.updates);t.push({id:r.id,updates:Number.isFinite(m)?m:a.length,finished:r.finished==="true"||a.some(d=>d.kind==="final"),entries:a})}return t}o(P,"parseInboxBody");function U(e,t,n,i){return{kind:e,facts:t,body:n,senders:i}}o(U,"cardFor");function I(e){const t=/^<runtime\b([^>]*)>/.exec(e);if(t===null||!e.endsWith("</runtime>"))return null;const n=f(t[1]??"");if(n?.kind===void 0)return null;const i=e.slice(t[0].length,-10),{kind:r,...a}=n,u=Object.freeze(a),c=r.includes(":")?h(i):i;return U(r,u,c,r==="inbox"?P(c):[])}o(I,"parseEnvelope");function z(e){const t=C(e),n=I(t);if(n!==null)return n;if(e.role!=="custom")return null;const i=A(e.customType);return i===void 0?null:{kind:i,facts:Object.freeze({}),body:t,senders:[]}}o(z,"parseCard");function W(e){return e.startsWith("/")?`Preview only. Read the full body from file \`${e}\`.`:`Read this report with \`crtr canvas read ${e}\`.`}o(W,"formatInboxRefInstruction");function K(e){const t=e.map(n=>{const i=n.entries.map(r=>{const a=r.disposition==="human-answer"||r.disposition==="human-canceled"?r.disposition:void 0;return`<entry${p({kind:r.kind,ref:r.ref,disposition:a})}>${w(r.body)}</entry>`}).join(`
10
2
  `);return`<from${p({id:n.id})}>${i}</from>`}).join(`
11
- `);return w("inbox",{},t)}o(K,"formatInboxCard");export{N as AUTH_FAULT_RECOVERY_BODY,M as CONNECTION_FAULT_RECOVERY_BODY,R as CONTEXT_INTRO_CUSTOM_TYPE,E as CONTEXT_NUDGE_CUSTOM_TYPE,L as PARK_SUMMARY_PROMPT,S as PROVIDER_FAULT_RECOVERY_BODY,v as REVIEW_BOUNDARY_CUSTOM_TYPE,_ as SITUATIONAL_CONTEXT_CUSTOM_TYPE,$ as STALL_REPROMPT,w as formatCard,q as formatDataCard,K as formatInboxCard,W as formatInboxRefInstruction,X as formatModelFallbackRecovery,B as formatStructuredOutputReprompt,C as generatedContextText,z as parseCard};
3
+ `);return y("inbox",{},t)}o(K,"formatInboxCard");export{N as AUTH_FAULT_RECOVERY_BODY,M as CONNECTION_FAULT_RECOVERY_BODY,v as CONTEXT_INTRO_CUSTOM_TYPE,_ as CONTEXT_NUDGE_CUSTOM_TYPE,L as PARK_SUMMARY_PROMPT,S as PROVIDER_FAULT_RECOVERY_BODY,E as REVIEW_BOUNDARY_CUSTOM_TYPE,R as SITUATIONAL_CONTEXT_CUSTOM_TYPE,$ as STALL_REPROMPT,y as formatCard,q as formatDataCard,K as formatInboxCard,W as formatInboxRefInstruction,X as formatModelFallbackRecovery,B as formatStructuredOutputReprompt,C as generatedContextText,z as parseCard};
@@ -0,0 +1,22 @@
1
+ export declare const INLINE_REPORT_MAX_CHARS = 1000;
2
+ /** The rendering fields both inbox projections share. */
3
+ export interface InboxEntryFields {
4
+ ts: string;
5
+ from: string | null;
6
+ from_name?: string;
7
+ label: string;
8
+ ref?: string;
9
+ data?: Record<string, unknown>;
10
+ }
11
+ /** A report document's ref (`<node>/reports/<name>`), else undefined. */
12
+ export declare function reportRefNodeId(ref: string | undefined): string | undefined;
13
+ /** Clip a body to the bounded preview stored beside a spilled message body. */
14
+ export declare function clipBody(body: string): {
15
+ text: string;
16
+ clipped: boolean;
17
+ };
18
+ export declare function inlineBody(entry: Pick<InboxEntryFields, 'data' | 'label'>): string;
19
+ /** One entry's card body: an inlined short report, a bounded inline message body, an event
20
+ * push rendered from its metadata, or the label. `report` is the report document's body when
21
+ * the caller could read it. */
22
+ export declare function renderEntryBody(entry: InboxEntryFields, report: string | null): string;
@@ -0,0 +1,10 @@
1
+ var p=Object.defineProperty;var i=(e,t)=>p(e,"name",{value:t,configurable:!0});import{formatInboxRefInstruction as $}from"./generated-context.js";const l=12,f=1e3,j=1e3;function k(e){return(e===void 0?null:/^([a-z0-9-]+)\/reports\/[^/]+$/.exec(e))?.[1]}i(k,"reportRefNodeId");function h(e){let t=e,r=!1;const o=t.split(`
2
+ `);return o.length>l&&(t=o.slice(0,l).join(`
3
+ `),r=!0),t.length>f&&(t=t.slice(0,f),r=!0),{text:t.trimEnd(),clipped:r}}i(h,"clipBody");function y(e){const t=typeof e.data?.body=="string"?String(e.data.body).trim():"";return t===""||t===e.label?"":t}i(y,"inlineBody");function x(e){const t=e.data?.push;return typeof t=="object"&&t!==null&&typeof t.event=="string"?t:null}i(x,"pushOf");function v(e){return e.type==="document"?`[[${e.owner===null?e.name:`${e.owner}/${e.name}`}]]`:e.type==="job"?`job ${e.id} (\`${e.name}\`)`:e.type==="node"?`node ${e.name} (${e.id})`:`${e.type} ${e.name}`}i(v,"objectText");function _(e,t){return t.actor===null?"the runtime":e.from_name===void 0||e.from_name===t.actor?t.actor:`${e.from_name} (${t.actor})`}i(_,"actorText");function u(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}i(u,"list");function R(e,t){const r=v(t.object),o=_(e,t),n=t.attrs,a=t.object.type==="document"?` Read it with \`crtr canvas read ${t.object.owner===null?t.object.name:`${t.object.owner}/${t.object.name}`}\`.`:"";switch(t.event){case"created":return t.object.type==="node"?`${o} created ${r}${typeof n.kind=="string"?`, kind ${n.kind}`:""}.`:`${o} created ${r}.${a}`;case"read":return`${o} read ${r}.`;case"watched":return`${o} started watching ${r}.`;case"deleted":return`${o} deleted ${r}.`;case"edited":{const c=u(n.authors),d=u(n.rationales),s=typeof n.from_revision=="number"&&typeof n.revision=="number"&&n.revision-n.from_revision>1?`revisions ${n.from_revision+1}\u2013${n.revision}`:typeof n.revision=="number"?`revision ${n.revision}`:"a new revision",m=c.length===0?o:c.join(", "),b=d.length===0?"":` Rationale: ${d.join("; ")}.`,g=n.needs_merge===!0?" Two edits were made from the same revision; read it and edit it to merge them.":"",w=` You get this because you read or wrote it; if it no longer concerns your work, stop with \`crtr canvas unwatch ${t.object.owner===null?t.object.name:`${t.object.owner}/${t.object.name}`}\`.`;return`${m} edited ${r} (${s}).${b}${g}${a}${w}`}case"messaged":return`${o} messaged ${r}.`;case"sent":return`${o} sent a message as ${r}.`;case"configured":return`${o} changed the settings of ${r}${typeof n.changed=="string"?`: ${n.changed}`:""}.`;case"exited":return`${r[0].toUpperCase()}${r.slice(1)} exited with code ${String(n["exit-code"])}. Log: ${String(n["log-path"])}`;case"killed":{const c=t.actor===null?"":` by ${o}`,d=typeof n.reason=="string"?` (${n.reason})`:"",s=n.reason==="deadline"?` It was canceled at its deadline; claim it with \`crtr node bash extend ${t.object.id} --for <duration>\` next time.`:"";return`${r[0].toUpperCase()}${r.slice(1)} was killed${c}${d}.${s} Log: ${String(n["log-path"])}`}default:return e.label}}i(R,"renderPush");function E(e,t){if(t!==null&&t.length<j&&e.ref!==void 0)return`${t.trimEnd()}
4
+
5
+ ${$(e.ref)}`;const r=y(e);if(r===""){const a=x(e);return a!==null&&e.ref===void 0?R(e,a):e.ref===void 0?e.label:`${e.label}
6
+
7
+ ${$(e.ref)}`}const{text:o,clipped:n}=h(r);return e.ref!==void 0?`${o}
8
+
9
+ ${$(e.ref)}`:n?`${o}
10
+ \u2026 (body clipped)`:o}i(E,"renderEntryBody");export{j as INLINE_REPORT_MAX_CHARS,h as clipBody,y as inlineBody,E as renderEntryBody,k as reportRefNodeId};
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Resolve every slash token in `text` against `names` (the exact canonical
3
- * `buildRefInventory().names` set), collapse duplicates, and return one
2
+ * Resolve every slash token in `text` against `names` (the node's document
3
+ * names from the delivery route), collapse duplicates, and return one
4
4
  * directive line per distinct resolved ref in FIRST-APPEARANCE order.
5
5
  * Returns `null` when no token resolves, so the broker sends no guidance
6
6
  * message for prose with no refs.
@@ -0,0 +1,2 @@
1
+ var a=Object.defineProperty;var o=(n,t)=>a(n,"name",{value:t,configurable:!0});import{findRefTokens as s}from"./inline-ref-grammar.js";const r="The user explicitly called out specific documents. Read the relevant mentioned documents:";function f(n,t){const i=new Set,c=[];for(const e of s(n))i.has(e.candidate)||t.has(e.candidate)&&(i.add(e.candidate),c.push(e.candidate));if(c.length===0)return null;const d=c.map(e=>`- crtr canvas read ${e}`);return[r,...d].join(`
2
+ `)}o(f,"buildGuidance");export{f as buildGuidance};
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { BindingId } from './core/keybindings/catalog.js';
2
- import type { ProfileProject } from './api/dto/profiles.js';
2
+ import type { DeliveryLimits, ProfileProject } from './api/dto/profiles.js';
3
3
  export type Scope = 'user' | 'project' | 'builtin';
4
4
  export declare const ExitCode: {
5
5
  readonly SUCCESS: 0;
@@ -511,6 +511,8 @@ export interface ProfileManifest {
511
511
  * every broker launched under the profile as `CRTR_PROFILE_META_<KEY>`
512
512
  * env (see `core/runtime/spawn-env.ts`). Absent means none. */
513
513
  metadata?: Record<string, string>;
514
+ /** Per-owner delivery caps; absent means none. */
515
+ delivery_limits?: DeliveryLimits;
514
516
  /** App that owns this profile; older terminal profiles have no grantee. */
515
517
  grantee?: string;
516
518
  created_at: string;
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Memory and preferences
3
- description: When you want later agents to retain a fact or follow an instruction, read this page because it explains where memory is stored and how to inspect or revise it.
3
+ description: When you want later agents to retain a fact or follow an instruction, read this page because it explains who owns a saved document and how to inspect or revise it.
4
4
  ---
5
5
 
6
6
  # Memory and preferences
7
7
 
8
- You can give future agents useful context without pasting the same background into every conversation. Ask an agent to remember a durable fact or instruction, then inspect the saved memory yourself from the terminal.
8
+ You can give future agents useful context without pasting the same background into every conversation. Ask an agent to remember a durable fact or instruction, then inspect the saved document yourself from the terminal.
9
9
 
10
10
  ## Tell an agent what should persist
11
11
 
@@ -18,35 +18,33 @@ Say what should be remembered and where it applies.
18
18
  | Something for every project you use | “Remember this as a user preference.” |
19
19
  | Something only agents in this repository need | “Remember this for this project.” |
20
20
 
21
- A preference tells an agent how to act. Knowledge gives it facts or a procedure to consult. The narrowest useful store is best: a user memory follows you everywhere, while a project memory belongs to one repository. For the explanation of memory tiers and loading, see [Memory](../concepts/memory.md).
21
+ A preference tells an agent how to act. Knowledge gives it facts or a procedure to consult. The narrowest useful owner is best: a document you own follows you everywhere, while a document a repository owns belongs to that one repository. For the explanation of document owners and loading, see [Documents](../concepts/memory.md).
22
22
 
23
23
  ## Browse what was saved
24
24
 
25
- List the memory documents available in your current context:
25
+ List the documents available in your current context:
26
26
 
27
27
  ```sh
28
- crtr memory list
28
+ crtr canvas list --type document
29
29
  ```
30
30
 
31
31
  Read one by its name from that list:
32
32
 
33
33
  ```sh
34
- crtr memory read <name>
34
+ crtr canvas read <name>
35
35
  ```
36
36
 
37
- `crtr memory read` resolves the current winning document when the same name exists at more than one scope. Add `--scope user` to read only user memory, or `--dir <project-directory>` to inspect one exact project store.
37
+ `crtr canvas read` resolves a bare name in your view, nearest owner first. Write `<owner>/<name>` to read one owner's document, and `crtr canvas search` to find one by its text.
38
38
 
39
- ## Edit a memory document
39
+ ## Edit a document
40
40
 
41
- Memory revisions are intentional and recorded. To replace a document's body, pipe the complete replacement text to `crtr memory edit` and give the reason for the revision:
41
+ Document revisions are intentional and recorded. To replace a document's body, pipe the complete replacement text to `crtr doc edit` and give the reason for the revision:
42
42
 
43
43
  ```sh
44
44
  printf '%s\n' 'Production changes need an explicit approval.' | \
45
- crtr memory edit <name> --rationale "Updated the approval rule."
45
+ crtr doc edit <name> --rationale "Updated the approval rule."
46
46
  ```
47
47
 
48
- `crtr memory edit` replaces the whole body you pipe; it does not append text. Use `crtr memory history <name>` to read the revision history. If you want to create a document yourself, use `crtr memory write`; it requires a kind, a routing sentence that tells agents when to read it, and the document body. New documents persist `privacy: public` unless `--privacy friends` or `--privacy private` is supplied. `crtr memory edit --privacy <level>` changes the level and records the revision. Older documents without the field read as private until edited or migrated. Privacy levels are metadata; crouter does not yet enforce app read or write access by level.
48
+ `crtr doc edit` replaces the whole body you pipe; it does not append text, and `--replace '[{"old":"…","new":"…"}]'` changes only the named passages. Read the document before you edit it; an edit made from an older revision is refused. Use `crtr doc history <name>` to read the revision history. If you want to create a document yourself, use `crtr doc write`; it requires a kind, a preview sentence that tells agents when to read it, and the document body, and `--owner user|repo|profile` chooses who owns it. New documents are `privacy: public` unless `--privacy friends` or `--privacy private` is supplied; a repository owns only public documents. `crtr doc edit --privacy <level>` changes the level and records the revision.
49
49
 
50
- To set every existing user and profile memory document to public after updating crouter, run `npm run build && node scripts/migrate-memory-privacy.mjs` from the crouter repository. Each changed document gets an ordinary edit history record with rationale `privacy rollout: Silas's memories default to public`. The command excludes project, node, builtin, and plugin stores and leaves documents already marked public unchanged. It does not run automatically.
51
-
52
- Memory is for reusable current truth and durable instructions, not a transcript of one conversation. When a fact changes, update the existing document rather than saving a second version.
50
+ Documents are for reusable current truth and durable instructions, not a transcript of one conversation. When a fact changes, update the existing document rather than saving a second version.
@@ -11,7 +11,7 @@ Use these pages to choose the shape of an agent application before you start wir
11
11
  |---|---|
12
12
  | [Nodes and the canvas](./nodes-and-the-canvas.md) | Whether work needs a durable node rather than one request and response |
13
13
  | [Lifecycle and wakes](./lifecycle-and-wakes.md) | Whether a node should finish, remain resident, delegate, or wait |
14
- | [Memory](./memory.md) | What an agent should know or embody, who owns it, and where it belongs |
14
+ | [Documents](./memory.md) | What an agent should know or embody, who owns it, and where it belongs |
15
15
  | [Profiles, kinds, and modes](./profiles-kinds-and-modes.md) | Which run-shaping dial matches an application concern |
16
16
  | [Scopes and trust](./scopes-and-trust.md) | What an application or node may do and why only the daemon writes canvas state |
17
17
  | [Why a daemon](./why-a-daemon.md) | Why a broker survives a terminal and why viewers are clients rather than hosts |