@north-light/crouter 0.3.348 → 0.3.350

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (634) hide show
  1. package/bin/crtr-launcher +4 -0
  2. package/bin/runtime-generation-manifest.mjs +12 -2
  3. package/dist/api/client.d.ts +50 -7
  4. package/dist/api/client.js +2 -2
  5. package/dist/api/command-manifest/schema.js +1 -1
  6. package/dist/api/dto/analytics.d.ts +184 -0
  7. package/dist/api/dto/analytics.js +0 -0
  8. package/dist/api/dto/broker-ops.d.ts +43 -1
  9. package/dist/api/dto/config.d.ts +11 -0
  10. package/dist/api/dto/grants.d.ts +14 -0
  11. package/dist/api/dto/grants.js +0 -0
  12. package/dist/api/dto/human-requests.d.ts +14 -0
  13. package/dist/api/dto/memory.d.ts +6 -0
  14. package/dist/api/dto/modelauth.d.ts +35 -0
  15. package/dist/api/dto/node-records.d.ts +35 -0
  16. package/dist/api/dto/node-records.js +0 -0
  17. package/dist/api/dto/nodes.d.ts +5 -0
  18. package/dist/api/dto/profiles.d.ts +38 -3
  19. package/dist/api/dto/worktree.d.ts +11 -0
  20. package/dist/api/errors.d.ts +23 -1
  21. package/dist/api/errors.js +1 -1
  22. package/dist/api/index.d.ts +2 -0
  23. package/dist/api/index.js +1 -1
  24. package/dist/api/node-transport.js +1 -1
  25. package/dist/api/routes.d.ts +22 -0
  26. package/dist/api/routes.js +1 -1
  27. package/dist/build-root.d.ts +6 -1
  28. package/dist/build-root.js +1 -1
  29. package/dist/builtin-memory/crouter-sdk/client.md +34 -0
  30. package/dist/builtin-memory/crouter-sdk/errors.md +2 -0
  31. package/dist/builtin-memory/crouter-sdk/memory.md +2 -2
  32. package/dist/builtin-memory/crouter-sdk/streaming.md +21 -0
  33. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +8 -4
  34. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +39 -118
  35. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -1
  36. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +41 -27
  37. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +52 -29
  38. package/dist/cli.js +9 -8
  39. package/dist/clients/attach/chrome/inbox-strip.js +1 -1
  40. package/dist/clients/attach/chrome/roster.js +1 -1
  41. package/dist/clients/attach/config.js +1 -1
  42. package/dist/clients/attach/overlays/auth.js +2 -2
  43. package/dist/clients/attach/overlays/graph.js +1 -1
  44. package/dist/clients/attach/render/tool-calls.js +3 -3
  45. package/dist/clients/attach/session/connection.js +1 -1
  46. package/dist/clients/attach/session/profile-files.js +1 -1
  47. package/dist/clients/attach/viewer.js +1569 -816
  48. package/dist/commands/api-client.js +3 -3
  49. package/dist/commands/broker-permissions.d.ts +2 -0
  50. package/dist/commands/broker-permissions.js +1 -0
  51. package/dist/commands/canvas-analytics/chart.d.ts +52 -0
  52. package/dist/commands/canvas-analytics/chart.js +1 -0
  53. package/dist/commands/canvas-analytics/drilldown.d.ts +34 -0
  54. package/dist/commands/canvas-analytics/drilldown.js +1 -0
  55. package/dist/commands/canvas-analytics/format.d.ts +29 -0
  56. package/dist/commands/canvas-analytics/format.js +1 -0
  57. package/dist/commands/canvas-analytics/graph-detail.d.ts +2 -0
  58. package/dist/commands/canvas-analytics/graph-detail.js +2 -0
  59. package/dist/commands/canvas-analytics/graphs.d.ts +9 -0
  60. package/dist/commands/canvas-analytics/graphs.js +1 -0
  61. package/dist/commands/canvas-analytics/memory.d.ts +2 -0
  62. package/dist/commands/canvas-analytics/memory.js +1 -0
  63. package/dist/commands/canvas-analytics/overview.d.ts +2 -0
  64. package/dist/commands/canvas-analytics/overview.js +1 -0
  65. package/dist/commands/canvas-analytics/shell.d.ts +60 -0
  66. package/dist/commands/canvas-analytics/shell.js +2 -0
  67. package/dist/commands/canvas-analytics/time.d.ts +2 -0
  68. package/dist/commands/canvas-analytics/time.js +1 -0
  69. package/dist/commands/canvas-analytics/usage.d.ts +2 -0
  70. package/dist/commands/canvas-analytics/usage.js +1 -0
  71. package/dist/commands/canvas-analytics/view.d.ts +85 -0
  72. package/dist/commands/canvas-analytics/view.js +1 -0
  73. package/dist/commands/canvas-analytics.d.ts +2 -0
  74. package/dist/commands/canvas-analytics.js +1 -0
  75. package/dist/commands/canvas-prune.js +1 -1
  76. package/dist/commands/canvas.js +1 -1
  77. package/dist/commands/cron.js +5 -5
  78. package/dist/commands/human/components.d.ts +2 -0
  79. package/dist/commands/human/components.js +2 -2
  80. package/dist/commands/human/prompts.js +1 -1
  81. package/dist/commands/human/queue.js +1 -1
  82. package/dist/commands/memory/client.d.ts +11 -0
  83. package/dist/commands/memory/client.js +1 -0
  84. package/dist/commands/memory/delete.js +1 -1
  85. package/dist/commands/memory/edit.js +3 -3
  86. package/dist/commands/memory/find.js +1 -1
  87. package/dist/commands/memory/history.js +4 -4
  88. package/dist/commands/memory/lint.js +1 -1
  89. package/dist/commands/memory/list.d.ts +0 -2
  90. package/dist/commands/memory/list.js +1 -1
  91. package/dist/commands/memory/move.js +1 -1
  92. package/dist/commands/memory/origin.js +1 -1
  93. package/dist/commands/memory/read.d.ts +0 -5
  94. package/dist/commands/memory/read.js +3 -3
  95. package/dist/commands/memory/shared.d.ts +0 -178
  96. package/dist/commands/memory/shared.js +1 -12
  97. package/dist/commands/memory/write.js +5 -5
  98. package/dist/commands/node/bash.js +5 -5
  99. package/dist/commands/node/create.d.ts +0 -17
  100. package/dist/commands/node/create.js +2 -3
  101. package/dist/commands/node/inspect.js +6 -6
  102. package/dist/commands/node/lifecycle.js +2 -2
  103. package/dist/commands/node-context.js +2 -2
  104. package/dist/commands/node-inspect-artifacts.js +6 -6
  105. package/dist/commands/pkg/browse/catalog.js +1 -1
  106. package/dist/commands/pkg/browse/model.d.ts +1 -1
  107. package/dist/commands/pkg/market-manage.js +1 -1
  108. package/dist/commands/pkg/plugin-manage.js +10 -10
  109. package/dist/commands/profile/daemon-profiles.d.ts +13 -0
  110. package/dist/commands/profile/daemon-profiles.js +4 -0
  111. package/dist/commands/profile/delete.js +1 -1
  112. package/dist/commands/profile/env.d.ts +6 -0
  113. package/dist/commands/profile/env.js +2 -2
  114. package/dist/commands/profile/kind.js +1 -2
  115. package/dist/commands/profile/list.js +1 -1
  116. package/dist/commands/profile/meta.js +1 -1
  117. package/dist/commands/profile/new.js +1 -1
  118. package/dist/commands/profile/pause.js +1 -1
  119. package/dist/commands/profile/project.js +1 -1
  120. package/dist/commands/profile/rename.js +1 -1
  121. package/dist/commands/profile/show.js +1 -1
  122. package/dist/commands/profile.js +1 -1
  123. package/dist/commands/push.js +3 -3
  124. package/dist/commands/surface-inspect.js +1 -1
  125. package/dist/commands/sys/branch.js +1 -1
  126. package/dist/commands/sys/config.js +1 -1
  127. package/dist/commands/sys/connect.js +3 -3
  128. package/dist/commands/sys/context/admin/actions.js +1 -1
  129. package/dist/commands/sys/context/admin/model.d.ts +1 -0
  130. package/dist/commands/sys/context/admin/model.js +1 -1
  131. package/dist/commands/sys/context/admin.js +1 -1
  132. package/dist/commands/sys/context/expose.js +2 -1
  133. package/dist/commands/sys/context/prompt-review.js +2 -2
  134. package/dist/commands/sys/context/resolve.js +7 -7
  135. package/dist/commands/sys/context/sysprompt.js +1 -1
  136. package/dist/commands/sys/join.d.ts +1 -0
  137. package/dist/commands/sys/join.js +1 -0
  138. package/dist/commands/sys/migrate.js +1 -1
  139. package/dist/commands/sys/panels/models-panel.js +1 -1
  140. package/dist/commands/sys/panels/profiles-panel.d.ts +0 -1
  141. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  142. package/dist/commands/sys/provider-login.js +6 -6
  143. package/dist/commands/sys/setup-core.d.ts +1 -1
  144. package/dist/commands/sys/setup-core.js +6 -6
  145. package/dist/commands/sys/setup-settings-runner.js +1 -1
  146. package/dist/commands/sys/setup.js +1 -1
  147. package/dist/commands/sys/spaces.d.ts +1 -0
  148. package/dist/commands/sys/spaces.js +2 -0
  149. package/dist/commands/sys/sync-deps.js +2 -2
  150. package/dist/commands/sys/sync-project-guidance.js +4 -4
  151. package/dist/commands/sys/sync-skills.js +2 -2
  152. package/dist/commands/sys/worktrees.d.ts +1 -0
  153. package/dist/commands/sys/worktrees.js +1 -1
  154. package/dist/commands/sys.js +1 -1
  155. package/dist/core/auth-file.js +2 -2
  156. package/dist/core/bash-job-supervisor.d.ts +6 -0
  157. package/dist/core/bash-job-supervisor.js +4 -0
  158. package/dist/core/bash-jobs.d.ts +13 -6
  159. package/dist/core/bash-jobs.js +8 -7
  160. package/dist/core/broker-client/transport-relay.d.ts +6 -3
  161. package/dist/core/broker-client/transport-relay.js +1 -1
  162. package/dist/core/broker-client/transport-socket.d.ts +6 -1
  163. package/dist/core/broker-client/transport-socket.js +1 -1
  164. package/dist/core/canvas/canvas.d.ts +39 -18
  165. package/dist/core/canvas/canvas.js +21 -20
  166. package/dist/core/canvas/context-strip.d.ts +20 -0
  167. package/dist/core/canvas/context-strip.js +5 -0
  168. package/dist/core/canvas/crons.d.ts +12 -20
  169. package/dist/core/canvas/crons.js +15 -13
  170. package/dist/core/canvas/db.js +2 -2
  171. package/dist/core/canvas/deliveries.d.ts +4 -1
  172. package/dist/core/canvas/deliveries.js +1 -1
  173. package/dist/core/canvas/executions.js +1 -1
  174. package/dist/core/canvas/history.d.ts +2 -1
  175. package/dist/core/canvas/history.js +17 -18
  176. package/dist/core/canvas/memory-reads.d.ts +19 -0
  177. package/dist/core/canvas/memory-reads.js +1 -0
  178. package/dist/core/canvas/migrations.d.ts +0 -4
  179. package/dist/core/canvas/migrations.js +99 -32
  180. package/dist/core/canvas/nav-render.js +1 -1
  181. package/dist/core/canvas/node-agent-paths.d.ts +8 -0
  182. package/dist/core/canvas/node-agent-paths.js +1 -0
  183. package/dist/core/canvas/node-recap.d.ts +2 -2
  184. package/dist/core/canvas/node-recap.js +2 -2
  185. package/dist/core/canvas/node-tokens.d.ts +24 -0
  186. package/dist/core/canvas/node-tokens.js +5 -0
  187. package/dist/core/canvas/paths.d.ts +16 -19
  188. package/dist/core/canvas/paths.js +1 -1
  189. package/dist/core/canvas/render-source.d.ts +2 -2
  190. package/dist/core/canvas/render-source.js +6 -9
  191. package/dist/core/canvas/sessions.d.ts +18 -0
  192. package/dist/core/canvas/sessions.js +4 -1
  193. package/dist/core/canvas/types.d.ts +22 -6
  194. package/dist/core/command-hooks/compose.js +1 -1
  195. package/dist/core/command-hooks/discovery.d.ts +15 -1
  196. package/dist/core/command-hooks/discovery.js +1 -1
  197. package/dist/core/command-hooks/help.d.ts +2 -2
  198. package/dist/core/command-hooks/lifecycle-create.d.ts +1 -1
  199. package/dist/core/command-hooks/lifecycle-create.js +1 -1
  200. package/dist/core/command-hooks/transport/exec-invoke.d.ts +2 -0
  201. package/dist/core/command-hooks/transport/exec-invoke.js +1 -1
  202. package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +1 -0
  203. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  204. package/dist/core/command-hooks/transport/plan.d.ts +3 -0
  205. package/dist/core/command-hooks/transport/plan.js +1 -0
  206. package/dist/core/command-plugins/discovery.js +1 -1
  207. package/dist/core/command-plugins/transport/http-invoke.js +2 -2
  208. package/dist/core/command.d.ts +6 -2
  209. package/dist/core/command.js +6 -6
  210. package/dist/core/config.d.ts +8 -5
  211. package/dist/core/config.js +1 -1
  212. package/dist/core/conversation-store/client-worker.d.ts +1 -0
  213. package/dist/core/conversation-store/client-worker.js +1 -0
  214. package/dist/core/conversation-store/client.d.ts +2 -0
  215. package/dist/core/conversation-store/client.js +2 -0
  216. package/dist/core/conversation-store/file-store.d.ts +37 -0
  217. package/dist/core/conversation-store/file-store.js +9 -0
  218. package/dist/core/conversation-store/index.d.ts +50 -0
  219. package/dist/core/conversation-store/index.js +1 -0
  220. package/dist/core/conversation-store/listener.d.ts +4 -0
  221. package/dist/core/conversation-store/listener.js +3 -0
  222. package/dist/core/conversation-store/patch.d.ts +1 -0
  223. package/dist/core/conversation-store/patch.js +1 -0
  224. package/dist/core/directory/join.d.ts +27 -0
  225. package/dist/core/directory/join.js +1 -0
  226. package/dist/core/disk-usage.d.ts +4 -0
  227. package/dist/core/disk-usage.js +1 -0
  228. package/dist/core/events/emit.d.ts +2 -0
  229. package/dist/core/events/emit.js +3 -1
  230. package/dist/core/feed/feed.js +4 -4
  231. package/dist/core/feed/messages.d.ts +3 -0
  232. package/dist/core/feed/messages.js +6 -6
  233. package/dist/core/fs-utils.d.ts +2 -0
  234. package/dist/core/fs-utils.js +3 -3
  235. package/dist/core/grants/local.d.ts +4 -0
  236. package/dist/core/grants/local.js +1 -0
  237. package/dist/core/grants/mirror.d.ts +44 -0
  238. package/dist/core/grants/mirror.js +4 -0
  239. package/dist/core/grants/on-sync.d.ts +22 -0
  240. package/dist/core/grants/on-sync.js +1 -0
  241. package/dist/core/grants/remove.d.ts +7 -0
  242. package/dist/core/grants/remove.js +1 -0
  243. package/dist/core/grants/sandboxes.d.ts +7 -0
  244. package/dist/core/grants/sandboxes.js +1 -0
  245. package/dist/core/grants/sync.d.ts +12 -0
  246. package/dist/core/grants/sync.js +1 -0
  247. package/dist/core/help/memory-extensions.d.ts +3 -0
  248. package/dist/core/help/memory-extensions.js +2 -0
  249. package/dist/core/help.d.ts +14 -0
  250. package/dist/core/help.js +7 -7
  251. package/dist/core/host-exports/builtins.js +3 -3
  252. package/dist/core/host-exports/export.js +3 -3
  253. package/dist/core/human/action-binding.d.ts +2 -0
  254. package/dist/core/human/action-binding.js +1 -1
  255. package/dist/core/human/feedback-companion.d.ts +0 -1
  256. package/dist/core/human/feedback-companion.js +1 -1
  257. package/dist/core/human/page-schema.d.ts +1 -1
  258. package/dist/core/inspector/core.d.ts +2 -0
  259. package/dist/core/inspector/core.js +1 -1
  260. package/dist/core/inspector/tui.js +2 -2
  261. package/dist/core/installed-plugins.js +1 -1
  262. package/dist/core/io.js +6 -6
  263. package/dist/core/keybindings/catalog.d.ts +1 -1
  264. package/dist/core/keybindings/catalog.js +1 -1
  265. package/dist/core/layout-migrate/index.d.ts +15 -0
  266. package/dist/core/layout-migrate/index.js +4 -0
  267. package/dist/core/layout-migrate/paths.d.ts +26 -0
  268. package/dist/core/layout-migrate/paths.js +1 -0
  269. package/dist/core/layout-migrate/stored-paths.d.ts +2 -0
  270. package/dist/core/layout-migrate/stored-paths.js +11 -0
  271. package/dist/core/layout-migrate/stores.d.ts +17 -0
  272. package/dist/core/layout-migrate/stores.js +4 -0
  273. package/dist/core/layout.d.ts +26 -0
  274. package/dist/core/layout.js +2 -0
  275. package/dist/core/llm/run.d.ts +60 -0
  276. package/dist/core/llm/run.js +4 -0
  277. package/dist/core/memory/cli-selector.d.ts +13 -0
  278. package/dist/core/memory/cli-selector.js +1 -0
  279. package/dist/core/memory/history.d.ts +5 -4
  280. package/dist/core/memory/history.js +6 -6
  281. package/dist/core/memory/inline-ref-inventory.d.ts +2 -1
  282. package/dist/core/memory/inline-ref-inventory.js +1 -1
  283. package/dist/core/memory/lint.js +2 -2
  284. package/dist/core/memory/mutation-domain.d.ts +2 -2
  285. package/dist/core/memory/mutation-domain.js +8 -7
  286. package/dist/core/memory/mutations.js +1 -1
  287. package/dist/core/memory/service.d.ts +5 -0
  288. package/dist/core/memory/service.js +2 -2
  289. package/dist/core/memory-resolver.d.ts +11 -7
  290. package/dist/core/memory-resolver.js +2 -2
  291. package/dist/core/model-auth/daemon-login.d.ts +13 -0
  292. package/dist/core/model-auth/daemon-login.js +1 -0
  293. package/dist/core/model-auth/flows.d.ts +45 -0
  294. package/dist/core/model-auth/flows.js +1 -0
  295. package/dist/core/model-auth/handoff-jti.d.ts +4 -0
  296. package/dist/core/model-auth/handoff-jti.js +1 -0
  297. package/dist/core/model-routes.js +1 -1
  298. package/dist/core/nested-stores.d.ts +2 -1
  299. package/dist/core/nested-stores.js +1 -2
  300. package/dist/core/preview-registry.js +2 -2
  301. package/dist/core/profiles/env-store.js +2 -2
  302. package/dist/core/profiles/manifest.d.ts +16 -5
  303. package/dist/core/profiles/manifest.js +1 -1
  304. package/dist/core/provider-management.js +1 -1
  305. package/dist/core/review/birth.js +1 -1
  306. package/dist/core/review/companion.d.ts +0 -2
  307. package/dist/core/review/companion.js +1 -1
  308. package/dist/core/review/fork.js +2 -2
  309. package/dist/core/review/realize.js +1 -1
  310. package/dist/core/review/stage.d.ts +1 -1
  311. package/dist/core/review/stage.js +1 -1
  312. package/dist/core/review/types.d.ts +1 -1
  313. package/dist/core/runs/events.d.ts +34 -0
  314. package/dist/core/runs/events.js +1 -0
  315. package/dist/core/runs/operations.d.ts +43 -0
  316. package/dist/core/runs/operations.js +12 -0
  317. package/dist/core/runtime/bearings-render.d.ts +2 -2
  318. package/dist/core/runtime/bearings-render.js +11 -11
  319. package/dist/core/runtime/bearings.js +2 -2
  320. package/dist/core/runtime/broker/cli-relay.d.ts +5 -0
  321. package/dist/core/runtime/broker/cli-relay.js +1 -0
  322. package/dist/core/runtime/broker/client-registry.d.ts +0 -5
  323. package/dist/core/runtime/broker/client-registry.js +1 -1
  324. package/dist/core/runtime/broker/daemon-ops.d.ts +28 -1
  325. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  326. package/dist/core/runtime/broker/engine-drive.d.ts +0 -2
  327. package/dist/core/runtime/broker/engine-drive.js +1 -1
  328. package/dist/core/runtime/broker/fault-retry.d.ts +9 -0
  329. package/dist/core/runtime/broker/fault-retry.js +1 -1
  330. package/dist/core/runtime/broker/frame-dispatch.d.ts +5 -9
  331. package/dist/core/runtime/broker/frame-dispatch.js +1 -1
  332. package/dist/core/runtime/broker/frame-engine-control.d.ts +3 -2
  333. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  334. package/dist/core/runtime/broker/frame-memory-refs.d.ts +4 -3
  335. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  336. package/dist/core/runtime/broker/frame-read.js +1 -1
  337. package/dist/core/runtime/broker/frame-session.js +1 -1
  338. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -1
  339. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  340. package/dist/core/runtime/broker/inbox.d.ts +1 -2
  341. package/dist/core/runtime/broker/inbox.js +7 -10
  342. package/dist/core/runtime/broker/model-adapter.d.ts +9 -0
  343. package/dist/core/runtime/broker/model-adapter.js +2 -0
  344. package/dist/core/runtime/broker/node-token.d.ts +3 -0
  345. package/dist/core/runtime/broker/node-token.js +1 -0
  346. package/dist/core/runtime/broker/read-ops.js +1 -1
  347. package/dist/core/runtime/broker/rebind.d.ts +2 -0
  348. package/dist/core/runtime/broker/rebind.js +1 -1
  349. package/dist/core/runtime/broker/tool-groups.js +1 -1
  350. package/dist/core/runtime/broker/turn-ignition.d.ts +3 -3
  351. package/dist/core/runtime/broker/turn-ignition.js +1 -1
  352. package/dist/core/runtime/broker-cli.js +3 -3
  353. package/dist/core/runtime/broker-extension-render.d.ts +2 -5
  354. package/dist/core/runtime/broker-extension-render.js +4 -4
  355. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  356. package/dist/core/runtime/broker-protocol.d.ts +7 -8
  357. package/dist/core/runtime/broker.js +1 -1
  358. package/dist/core/runtime/canvas-extensions.d.ts +1 -0
  359. package/dist/core/runtime/canvas-extensions.js +1 -1
  360. package/dist/core/runtime/close.d.ts +9 -0
  361. package/dist/core/runtime/close.js +1 -1
  362. package/dist/core/runtime/deliver-live.js +1 -1
  363. package/dist/core/runtime/fleet.d.ts +1 -1
  364. package/dist/core/runtime/front-door-login.js +1 -1
  365. package/dist/core/runtime/front-door.js +2 -2
  366. package/dist/core/runtime/headless-pi.d.ts +1 -1
  367. package/dist/core/runtime/headless-pi.js +1 -1
  368. package/dist/core/runtime/host.d.ts +1 -1
  369. package/dist/core/runtime/host.js +3 -1
  370. package/dist/core/runtime/invocation.d.ts +3 -0
  371. package/dist/core/runtime/kickoff.d.ts +1 -0
  372. package/dist/core/runtime/kickoff.js +16 -16
  373. package/dist/core/runtime/launch-target.d.ts +1 -1
  374. package/dist/core/runtime/launch-target.js +1 -1
  375. package/dist/core/runtime/launch.d.ts +10 -35
  376. package/dist/core/runtime/launch.js +1 -1
  377. package/dist/core/runtime/lifecycle.js +2 -2
  378. package/dist/core/runtime/memory.d.ts +1 -1
  379. package/dist/core/runtime/memory.js +1 -1
  380. package/dist/core/runtime/model-registry.js +1 -1
  381. package/dist/core/runtime/model-swap.d.ts +17 -19
  382. package/dist/core/runtime/model-swap.js +1 -1
  383. package/dist/core/runtime/node-read.js +3 -2
  384. package/dist/core/runtime/nodes.d.ts +7 -0
  385. package/dist/core/runtime/nodes.js +1 -1
  386. package/dist/core/runtime/outcome-document.js +1 -1
  387. package/dist/core/runtime/package-health.js +2 -2
  388. package/dist/core/runtime/persona.js +2 -2
  389. package/dist/core/runtime/pi-vendored.js +1 -1
  390. package/dist/core/runtime/placement-tmux.d.ts +1 -1
  391. package/dist/core/runtime/placement-tmux.js +1 -1
  392. package/dist/core/runtime/placement.js +1 -1
  393. package/dist/core/runtime/promote.js +1 -1
  394. package/dist/core/runtime/provider-credential-gate.js +2 -2
  395. package/dist/core/runtime/recovery-hold.d.ts +2 -0
  396. package/dist/core/runtime/recovery-hold.js +1 -0
  397. package/dist/core/runtime/recycle.js +1 -1
  398. package/dist/core/runtime/reopen.js +1 -1
  399. package/dist/core/runtime/reset.js +1 -1
  400. package/dist/core/runtime/revive.d.ts +1 -1
  401. package/dist/core/runtime/revive.js +2 -3
  402. package/dist/core/runtime/roadmap.js +4 -4
  403. package/dist/core/runtime/run-command.d.ts +6 -0
  404. package/dist/core/runtime/run-command.js +1 -1
  405. package/dist/core/runtime/session-branch.d.ts +2 -8
  406. package/dist/core/runtime/session-branch.js +1 -1
  407. package/dist/core/runtime/session-list-cache.d.ts +6 -22
  408. package/dist/core/runtime/session-list-cache.js +1 -1
  409. package/dist/core/runtime/situational-context.js +2 -2
  410. package/dist/core/runtime/spawn-env.d.ts +6 -6
  411. package/dist/core/runtime/spawn-env.js +1 -1
  412. package/dist/core/runtime/spawn.d.ts +5 -0
  413. package/dist/core/runtime/spawn.js +2 -2
  414. package/dist/core/runtime/stop-guard.js +2 -2
  415. package/dist/core/runtime/stop-signals.d.ts +2 -2
  416. package/dist/core/runtime/stop-signals.js +1 -1
  417. package/dist/core/runtime/structured-output.d.ts +10 -4
  418. package/dist/core/runtime/structured-output.js +4 -4
  419. package/dist/core/runtime/tmux-bindings.js +3 -3
  420. package/dist/core/runtime/tmux-driver.d.ts +4 -0
  421. package/dist/core/runtime/tmux-driver.js +7 -7
  422. package/dist/core/runtime/view-socket.d.ts +9 -2
  423. package/dist/core/runtime/view-socket.js +1 -1
  424. package/dist/core/runtime/warm-pool.js +1 -1
  425. package/dist/core/scope.d.ts +3 -2
  426. package/dist/core/scope.js +1 -1
  427. package/dist/core/scoped-state/db.js +1 -1
  428. package/dist/core/scoped-state/migrate.js +3 -3
  429. package/dist/core/scoped-state/profiles.d.ts +2 -1
  430. package/dist/core/scoped-state/profiles.js +1 -1
  431. package/dist/core/scoped-state/schema.d.ts +2 -1
  432. package/dist/core/scoped-state/schema.js +4 -4
  433. package/dist/core/scopes.d.ts +2 -2
  434. package/dist/core/scopes.js +1 -1
  435. package/dist/core/secrets.d.ts +1 -0
  436. package/dist/core/secrets.js +2 -2
  437. package/dist/core/spaces/mounts.d.ts +32 -0
  438. package/dist/core/spaces/mounts.js +1 -0
  439. package/dist/core/spaces/open-beneath.d.ts +71 -0
  440. package/dist/core/spaces/open-beneath.js +1 -0
  441. package/dist/core/spaces/permissions.d.ts +46 -0
  442. package/dist/core/spaces/permissions.js +1 -0
  443. package/dist/core/spaces/process.d.ts +27 -0
  444. package/dist/core/spaces/process.js +1 -0
  445. package/dist/core/spaces/space.d.ts +8 -0
  446. package/dist/core/spaces/space.js +2 -0
  447. package/dist/core/spaces/stop.d.ts +8 -0
  448. package/dist/core/spaces/stop.js +2 -0
  449. package/dist/core/spaces/users.d.ts +19 -0
  450. package/dist/core/spaces/users.js +1 -0
  451. package/dist/core/subscription-state.d.ts +2 -0
  452. package/dist/core/subscription-state.js +3 -3
  453. package/dist/core/substrate/frontmatter-validation.js +1 -1
  454. package/dist/core/substrate/injected-store.d.ts +28 -3
  455. package/dist/core/substrate/injected-store.js +2 -1
  456. package/dist/core/substrate/listings.js +1 -1
  457. package/dist/core/substrate/memory-events.d.ts +6 -0
  458. package/dist/core/substrate/memory-events.js +1 -0
  459. package/dist/core/substrate/on-read-node.js +1 -1
  460. package/dist/core/substrate/on-read.d.ts +6 -6
  461. package/dist/core/substrate/on-read.js +5 -5
  462. package/dist/core/substrate/plan.js +1 -1
  463. package/dist/core/substrate/render-node.js +1 -1
  464. package/dist/core/substrate/render.d.ts +4 -3
  465. package/dist/core/substrate/render.js +38 -38
  466. package/dist/core/substrate/schema.d.ts +6 -0
  467. package/dist/core/substrate/schema.js +1 -1
  468. package/dist/core/tui/panel.js +1 -1
  469. package/dist/core/user-settings.d.ts +12 -0
  470. package/dist/core/user-settings.js +1 -1
  471. package/dist/core/worktree-mutation-async.js +5 -5
  472. package/dist/core/worktree-quarantine.js +1 -1
  473. package/dist/core/worktree-remove.d.ts +15 -0
  474. package/dist/core/worktree-remove.js +1 -0
  475. package/dist/core/worktree-sweep.js +6 -6
  476. package/dist/daemon/analytics/compute.d.ts +37 -0
  477. package/dist/daemon/analytics/compute.js +1 -0
  478. package/dist/daemon/analytics/scan-worker.d.ts +1 -0
  479. package/dist/daemon/analytics/scan-worker.js +2 -0
  480. package/dist/daemon/analytics/scan.d.ts +37 -0
  481. package/dist/daemon/analytics/scan.js +1 -0
  482. package/dist/daemon/api/app-listener.d.ts +11 -0
  483. package/dist/daemon/api/app-listener.js +21 -0
  484. package/dist/daemon/api/bridge.js +5 -5
  485. package/dist/daemon/api/handlers/analytics.d.ts +2 -0
  486. package/dist/daemon/api/handlers/analytics.js +1 -0
  487. package/dist/daemon/api/handlers/attach.js +1 -1
  488. package/dist/daemon/api/handlers/bash-jobs.js +2 -2
  489. package/dist/daemon/api/handlers/bash.js +1 -1
  490. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  491. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  492. package/dist/daemon/api/handlers/canvas.js +6 -6
  493. package/dist/daemon/api/handlers/crons.js +1 -1
  494. package/dist/daemon/api/handlers/files.d.ts +1 -1
  495. package/dist/daemon/api/handlers/files.js +1 -1
  496. package/dist/daemon/api/handlers/health.js +2 -2
  497. package/dist/daemon/api/handlers/hook-exec.d.ts +2 -0
  498. package/dist/daemon/api/handlers/hook-exec.js +1 -0
  499. package/dist/daemon/api/handlers/human-requests.js +1 -1
  500. package/dist/daemon/api/handlers/inbox.js +1 -1
  501. package/dist/daemon/api/handlers/llm.d.ts +2 -0
  502. package/dist/daemon/api/handlers/llm.js +3 -0
  503. package/dist/daemon/api/handlers/memory-reads.d.ts +4 -0
  504. package/dist/daemon/api/handlers/memory-reads.js +1 -0
  505. package/dist/daemon/api/handlers/memory.js +5 -1
  506. package/dist/daemon/api/handlers/messages.js +2 -2
  507. package/dist/daemon/api/handlers/modelauth.js +1 -1
  508. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  509. package/dist/daemon/api/handlers/node-records.d.ts +2 -0
  510. package/dist/daemon/api/handlers/node-records.js +3 -0
  511. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  512. package/dist/daemon/api/handlers/nodes.js +1 -1
  513. package/dist/daemon/api/handlers/profiles.d.ts +4 -1
  514. package/dist/daemon/api/handlers/profiles.js +1 -1
  515. package/dist/daemon/api/handlers/reports.js +5 -3
  516. package/dist/daemon/api/handlers/reviews.d.ts +1 -1
  517. package/dist/daemon/api/handlers/reviews.js +1 -1
  518. package/dist/daemon/api/handlers/run-routes.d.ts +2 -0
  519. package/dist/daemon/api/handlers/run-routes.js +1 -0
  520. package/dist/daemon/api/handlers/runs.d.ts +9 -0
  521. package/dist/daemon/api/handlers/runs.js +1 -0
  522. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  523. package/dist/daemon/api/handlers/worktree.js +1 -1
  524. package/dist/daemon/api/map.d.ts +10 -4
  525. package/dist/daemon/api/map.js +2 -2
  526. package/dist/daemon/api/operations.d.ts +18 -0
  527. package/dist/daemon/api/operations.js +1 -0
  528. package/dist/daemon/api/principal.d.ts +42 -0
  529. package/dist/daemon/api/principal.js +1 -0
  530. package/dist/daemon/api/router.d.ts +27 -3
  531. package/dist/daemon/api/router.js +1 -1
  532. package/dist/daemon/api/server.d.ts +4 -0
  533. package/dist/daemon/api/server.js +1 -1
  534. package/dist/daemon/api/vendor-signin.d.ts +7 -0
  535. package/dist/daemon/api/vendor-signin.js +77 -0
  536. package/dist/daemon/api/viewer-presence.d.ts +3 -0
  537. package/dist/daemon/api/viewer-presence.js +1 -0
  538. package/dist/daemon/cron/armed-context.d.ts +4 -0
  539. package/dist/daemon/cron/armed-context.js +1 -1
  540. package/dist/daemon/cron/escalation.js +3 -3
  541. package/dist/daemon/cron/lease-recovery.js +1 -1
  542. package/dist/daemon/cron/sinks.js +2 -2
  543. package/dist/daemon/cron-run.d.ts +5 -5
  544. package/dist/daemon/cron-run.js +1 -1
  545. package/dist/daemon/crtrd-cli.js +1 -1
  546. package/dist/daemon/crtrd.js +8 -7
  547. package/dist/daemon/delivery/run-delivery.d.ts +4 -0
  548. package/dist/daemon/delivery/run-delivery.js +1 -1
  549. package/dist/daemon/fleet.d.ts +1 -1
  550. package/dist/daemon/fleet.js +6 -6
  551. package/dist/daemon/http-dispatcher.d.ts +1 -0
  552. package/dist/daemon/http-dispatcher.js +1 -0
  553. package/dist/daemon/human/finish.js +7 -7
  554. package/dist/daemon/joined-owner.d.ts +5 -0
  555. package/dist/daemon/joined-owner.js +1 -0
  556. package/dist/daemon/manage.js +2 -2
  557. package/dist/daemon/messaging/node-message.js +1 -1
  558. package/dist/daemon/park-activity.js +1 -1
  559. package/dist/daemon/reconcilers/bash-deadline.js +1 -1
  560. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  561. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  562. package/dist/daemon/reconcilers/delivery-lane.js +1 -1
  563. package/dist/daemon/reconcilers/live-obligation.d.ts +7 -0
  564. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  565. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  566. package/dist/daemon/reconcilers/storage-maintenance.d.ts +20 -1
  567. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  568. package/dist/daemon/runs/append-section.d.ts +6 -0
  569. package/dist/daemon/runs/append-section.js +2 -0
  570. package/dist/daemon/runs/observer.d.ts +5 -0
  571. package/dist/daemon/runs/observer.js +4 -0
  572. package/dist/launcher/bwrap.d.ts +4 -0
  573. package/dist/launcher/bwrap.js +2 -0
  574. package/dist/launcher/client.d.ts +2 -0
  575. package/dist/launcher/client.js +3 -0
  576. package/dist/launcher/main.d.ts +1 -0
  577. package/dist/launcher/main.js +3 -0
  578. package/dist/launcher/netrule.d.ts +1 -0
  579. package/dist/launcher/netrule.js +1 -0
  580. package/dist/launcher/seccomp.d.ts +1 -0
  581. package/dist/launcher/seccomp.js +1 -0
  582. package/dist/launcher/spec.d.ts +88 -0
  583. package/dist/launcher/spec.js +1 -0
  584. package/dist/launcher/users.d.ts +18 -0
  585. package/dist/launcher/users.js +7 -0
  586. package/dist/launcher/validate.d.ts +22 -0
  587. package/dist/launcher/validate.js +1 -0
  588. package/dist/migrations/corpus.js +3 -3
  589. package/dist/migrations/runner.js +1 -1
  590. package/dist/native/linux/addon.node +0 -0
  591. package/dist/native/linux.d.ts +29 -0
  592. package/dist/native/linux.js +1 -0
  593. package/dist/pi-extensions/broker-local.js +2 -2
  594. package/dist/pi-extensions/canvas-bash-valve.d.ts +1 -3
  595. package/dist/pi-extensions/canvas-bash-valve.js +4 -7
  596. package/dist/pi-extensions/canvas-context-intro.d.ts +1 -2
  597. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  598. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  599. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +2 -1
  600. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -1
  601. package/dist/pi-extensions/canvas-passive-context.d.ts +1 -1
  602. package/dist/pi-extensions/canvas-passive-context.js +11 -11
  603. package/dist/pi-extensions/canvas-recap.js +6 -6
  604. package/dist/pi-extensions/canvas-stophook.js +1 -1
  605. package/dist/pi-extensions/canvas-structured-output.js +4 -4
  606. package/dist/pi-extensions/canvas-tool-guide.js +1 -1
  607. package/dist/pi-extensions/system-prompt-entry.d.ts +15 -0
  608. package/dist/pi-extensions/system-prompt-entry.js +1 -0
  609. package/dist/shared/env.d.ts +5 -1
  610. package/dist/shared/env.js +1 -1
  611. package/dist/shared/strip-cd-prefix.d.ts +1 -0
  612. package/dist/shared/strip-cd-prefix.js +1 -0
  613. package/dist/types.d.ts +31 -15
  614. package/docs/cli/memory-and-preferences.md +3 -1
  615. package/docs/sdk/client.md +34 -0
  616. package/docs/sdk/errors.md +2 -0
  617. package/docs/sdk/memory.md +2 -2
  618. package/docs/sdk/streaming.md +21 -0
  619. package/package.json +19 -4
  620. package/packages/crouter-identity/dist/index.d.ts +54 -0
  621. package/packages/crouter-identity/dist/index.js +166 -0
  622. package/packages/crouter-identity/package.json +33 -0
  623. package/runtime.lock.json +44 -8
  624. package/scripts/build-native-linux.mjs +16 -0
  625. package/scripts/install-runtime.mjs +9 -7
  626. package/scripts/lib/isolation-env.mjs +42 -0
  627. package/scripts/runtime-smoke.mjs +49 -0
  628. package/src/native/linux/addon.c +249 -0
  629. package/dist/core/profiles/state-block.d.ts +0 -4
  630. package/dist/core/profiles/state-block.js +0 -3
  631. package/dist/core/runtime/broker/auth-reload.d.ts +0 -41
  632. package/dist/core/runtime/broker/auth-reload.js +0 -1
  633. package/dist/core/substrate/cli-context-delivery.d.ts +0 -22
  634. package/dist/core/substrate/cli-context-delivery.js +0 -1
@@ -1,14 +1,14 @@
1
- var $=Object.defineProperty;var f=(e,n)=>$(e,"name",{value:n,configurable:!0});import{envNodeId as h}from"../shared/env.js";import{existsSync as b,readFileSync as v}from"node:fs";import{acknowledgeBrokerMail as w,claimBrokerMail as k,brokerExtensionState as C}from"../core/runtime/broker/daemon-ops.js";import{wasTurnRefused as M}from"../core/runtime/broker/extension-abort.js";import{emitEvent as P}from"../core/events/emit.js";import{reportPathFromRef as S}from"../core/runtime/broker-extension-render.js";import{parseCard as j}from"../shared/generated-context.js";const y=4e3;function _(e){if(!e.startsWith(`---
2
- `))return e;const n=e.indexOf(`
1
+ var v=Object.defineProperty;var l=(t,e)=>v(t,"name",{value:e,configurable:!0});import{envNodeId as p}from"../shared/env.js";import{isAbsolute as h}from"node:path";import{acknowledgeBrokerMail as $,claimBrokerMail as _,readBrokerPassiveMessage as w}from"../core/runtime/broker/daemon-ops.js";import{ApiError as b}from"../api/errors.js";import{wasTurnRefused as k}from"../core/runtime/broker/extension-abort.js";import{emitEvent as C}from"../core/events/emit.js";import{parseCard as A}from"../shared/generated-context.js";const y=4e3;function P(t){if(!t.startsWith(`---
2
+ `))return t;const e=t.indexOf(`
3
3
  ---
4
- `,4);return n===-1?e:e.slice(n+5)}f(_,"stripFrontmatter");function x(e,n){if(e.ref!==void 0&&e.ref!==""){const t=S(e.ref,n);if(t!==null)try{const i=_(v(t,"utf8")).trim();if(i!=="")return i.length>y?`${i.slice(0,y)}
5
- \u2026 (truncated; read the full report with \`crtr canvas history read ${e.ref}\`)`:i}catch{}if(b(e.ref))try{const i=_(v(e.ref,"utf8")).trim();if(i!=="")return i.length>y?`${i.slice(0,y)}
6
- \u2026 (truncated; full report at ${e.ref})`:i}catch{}}const r=e.data?.body;return typeof r=="string"&&r.trim()!==""?r.trim():e.label}f(x,"entryContent");function m(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}f(m,"attr");function A(e,n=new Map){const r=e.map(t=>{const i=m(t.from??"system"),u=t.from_name!==void 0&&t.from_name!==""?` from_name="${m(t.from_name)}"`:"",o=t.ref!==void 0&&t.ref!==""?` ref="${m(t.ref)}"`:"";return`<update from="${i}"${u} kind="${m(t.kind)}" at="${m(t.ts)}"${o}>
7
- ${x(t,n)}
8
- </update>`}).join(`
9
- `);return`<passive-subscription-backlog count="${e.length}" note="Reports accumulated from nodes you passively subscribe to while you were not actively listening. Surfaced now because you were messaged. Oldest first.">
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)}
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
+ ${await j(e,n)}
8
+ </update>`}))).join(`
9
+ `);return`<passive-subscription-backlog count="${t.length}" note="Reports accumulated from nodes you passively subscribe to while you were not actively listening. Surfaced now because you were messaged. Oldest first.">
10
10
  ${r}
11
- </passive-subscription-backlog>`}f(A,"formatPassive");const B="</runtime>";function E(e,n){if(e.trim()==="")return n;const r=j({role:"user",content:e});if(r===null)return`${n}
11
+ </passive-subscription-backlog>`}l(B,"formatPassive");const M="</runtime>";function E(t,e){if(t.trim()==="")return e;const r=A({role:"user",content:t});if(r===null)return`${e}
12
12
 
13
- ${e}`;const t=e.length-r.body.length-B.length;return`${e.slice(0,t)}${n}
14
- ${e.slice(t)}`}f(E,"placeBacklog");function F(e){const n=new Map;let r,t;function i(o){try{P({level:"error",event:"inbox.delivery.failed",outcome:"failed",error:o,fields:{channel:"passive"}})}catch{}}f(i,"reportFailure");async function u(o){if(t!==void 0)return t;if(r===void 0&&(r=[...n.values()].filter(s=>s.injected).map(({claim:s})=>({delivery_id:s.delivery_id,attempts:s.attempts,disposition:M()?"released":"acknowledged"}))),r.length===0)return r=void 0,!0;const d=r,a=(async()=>{try{const s=await w(o,d);if(s.action==="hold")return!1;for(const l of d){const p=s.results.find(g=>g.delivery_id===l.delivery_id);if(p?.outcome!==l.disposition&&p?.outcome!=="stale")throw new Error(`passive mail settlement has no terminal outcome: ${l.delivery_id}`)}for(const l of d)n.delete(l.delivery_id);return r=void 0,!0}catch(s){return i(s),!1}})().finally(()=>{t===a&&(t=void 0)});return t=a,a}f(u,"settle"),e.on("input",async o=>{const d=h();if(!(d===void 0||d.trim()===""))try{if(r!==void 0&&!await u(d))return;const a=await k(d,"passive");if(a.action==="hold")return;for(const c of a.deliveries)n.has(c.delivery_id)||n.set(c.delivery_id,{claim:c,injected:!1});const s=[...n.values()].filter(c=>!c.injected);if(s.length===0)return;const l=await C(d),p=new Map(l.report_nodes.map(c=>[c.node_id,c])),g=E(o.text,A(s.map(({claim:c})=>c.entry),p));for(const c of s)c.injected=!0;return{action:"transform",text:g,images:o.images}}catch(a){i(a);return}}),e.on("agent_settled",async()=>{const o=h();o!==void 0&&o!==""&&await u(o)}),e.on("session_shutdown",async(o,d)=>{const a=h();a!==void 0&&a!==""&&d?.hasPendingMessages?.()!==!0&&await u(a)})}f(F,"registerCanvasPassiveContext");var Y=F;export{Y as default,A as formatPassive,E as placeBacklog,F as registerCanvasPassiveContext};
13
+ ${t}`;const n=t.length-r.body.length-M.length;return`${t.slice(0,n)}${e}
14
+ ${t.slice(n)}`}l(E,"placeBacklog");function I(t){const e=new Map;let r,n;function i(o){try{C({level:"error",event:"inbox.delivery.failed",outcome:"failed",error:o,fields:{channel:"passive"}})}catch{}}l(i,"reportFailure");async function f(o){if(n!==void 0)return n;if(r===void 0&&(r=[...e.values()].filter(s=>s.injected).map(({claim:s})=>({delivery_id:s.delivery_id,attempts:s.attempts,disposition:k()?"released":"acknowledged"}))),r.length===0)return r=void 0,!0;const d=r,a=(async()=>{try{const s=await $(o,d);if(s.action==="hold")return!1;for(const u of d){const c=s.results.find(g=>g.delivery_id===u.delivery_id);if(c?.outcome!==u.disposition&&c?.outcome!=="stale")throw new Error(`passive mail settlement has no terminal outcome: ${u.delivery_id}`)}for(const u of d)e.delete(u.delivery_id);return r=void 0,!0}catch(s){return i(s),!1}})().finally(()=>{n===a&&(n=void 0)});return n=a,a}l(f,"settle"),t.on("input",async o=>{const d=p();if(!(d===void 0||d.trim()===""))try{if(r!==void 0&&!await f(d))return;const a=await _(d,"passive");if(a.action==="hold")return;for(const c of a.deliveries)e.has(c.delivery_id)||e.set(c.delivery_id,{claim:c,injected:!1});const s=[...e.values()].filter(c=>!c.injected);if(s.length===0)return;const u=E(o.text,await B(s.map(({claim:c})=>c.entry),d));for(const c of s)c.injected=!0;return{action:"transform",text:u,images:o.images}}catch(a){i(a);return}}),t.on("agent_settled",async()=>{const o=p();o!==void 0&&o!==""&&await f(o)}),t.on("session_shutdown",async(o,d)=>{const a=p();a!==void 0&&a!==""&&d?.hasPendingMessages?.()!==!0&&await f(a)})}l(I,"registerCanvasPassiveContext");var N=I;export{N as default,B as formatPassive,E as placeBacklog,I as registerCanvasPassiveContext};
@@ -1,11 +1,11 @@
1
- var L=Object.defineProperty;var a=(n,s)=>L(n,"name",{value:s,configurable:!0});import{envNodeId as W,envRecapIdleMs as O}from"../shared/env.js";import{brokerExtensionState as k}from"../core/runtime/broker/daemon-ops.js";import{generateRecap as U}from"../core/runtime/recap.js";import{writeNodeRecap as V}from"../core/canvas/node-recap.js";import{isReviewBoundary as B}from"../core/runtime/session-visibility.js";import{editorLabelForBrokerNode as q}from"../core/runtime/broker-extension-render.js";import{generateAndCommitRecapName as F,readRoadmap as H}from"./broker-local.js";function K(){return O()}a(K,"idleMs");const Y=7e3,A=5,z=1200,C="crtr-recap";let M;function J(n){const s=n.content;return typeof s=="string"?s.trim():Array.isArray(s)?s.filter(r=>r!==null&&typeof r=="object"&&r.type==="text"&&typeof r.text=="string").map(r=>(r.text??"").trim()).filter(r=>r!=="").join(`
2
- `).trim():""}a(J,"messageText");function Q(n,s){let r;try{r=n.getEntries()}catch{return{entries:[],boundaryPresent:s===void 0}}if(s===void 0)return{entries:r,boundaryPresent:!0};const t=r.findIndex(o=>B(o,s));return t===-1?{entries:[],boundaryPresent:!1}:{entries:r.slice(t+1),boundaryPresent:!0}}a(Q,"recapEntries");function D(n,s,r,t){const{entries:o,boundaryPresent:u}=Q(n,t),l=[],m=a(f=>{const p=f.role;if(p!=="user"&&p!=="assistant")return;let d=J(f);if(d==="")return;d.length>s&&(d=`${d.slice(0,s)} \u2026[truncated]`);const g=`${p==="user"?"User":"Agent"}: ${d}`;l.at(-1)!==g&&l.push(g)},"append");for(const f of o)f.type!=="message"||f.message===void 0||m(f.message);return u&&r?.role==="assistant"&&m(r),l}a(D,"conversationParts");function X(n,s,r){const t=D(n,z,s,r);if(t.length===0)return"";if(t.length<=A*2)return t.join(`
1
+ var W=Object.defineProperty;var a=(n,s)=>W(n,"name",{value:s,configurable:!0});import{envNodeId as B,envRecapIdleMs as O}from"../shared/env.js";import{brokerExtensionState as G}from"../core/runtime/broker/daemon-ops.js";import{generateRecap as U}from"../core/runtime/recap.js";import{putBrokerRecap as V}from"../core/runtime/broker/daemon-ops.js";import{isReviewBoundary as q}from"../core/runtime/session-visibility.js";import{editorLabelForBrokerNode as F}from"../core/runtime/broker-extension-render.js";import{generateAndCommitRecapName as H,readRoadmap as K}from"./broker-local.js";function Y(){return O()}a(Y,"idleMs");const z=7e3,b=5,J=1200,$="crtr-recap";let M;function Q(n){const s=n.content;return typeof s=="string"?s.trim():Array.isArray(s)?s.filter(r=>r!==null&&typeof r=="object"&&r.type==="text"&&typeof r.text=="string").map(r=>(r.text??"").trim()).filter(r=>r!=="").join(`
2
+ `).trim():""}a(Q,"messageText");function X(n,s){let r;try{r=n.getEntries()}catch{return{entries:[],boundaryPresent:s===void 0}}if(s===void 0)return{entries:r,boundaryPresent:!0};const t=r.findIndex(o=>q(o,s));return t===-1?{entries:[],boundaryPresent:!1}:{entries:r.slice(t+1),boundaryPresent:!0}}a(X,"recapEntries");function C(n,s,r,t){const{entries:o,boundaryPresent:u}=X(n,t),l=[],m=a(f=>{const p=f.role;if(p!=="user"&&p!=="assistant")return;let d=Q(f);if(d==="")return;d.length>s&&(d=`${d.slice(0,s)} \u2026[truncated]`);const g=`${p==="user"?"User":"Agent"}: ${d}`;l.at(-1)!==g&&l.push(g)},"append");for(const f of o)f.type!=="message"||f.message===void 0||m(f.message);return u&&r?.role==="assistant"&&m(r),l}a(C,"conversationParts");function Z(n,s,r){const t=C(n,J,s,r);if(t.length===0)return"";if(t.length<=b*2)return t.join(`
3
3
 
4
- `);const o=t.length-A*2;return[...t.slice(0,A),`[\u2026 ${o} message${o===1?"":"s"} omitted \u2026]`,...t.slice(t.length-A)].join(`
4
+ `);const o=t.length-b*2;return[...t.slice(0,b),`[\u2026 ${o} message${o===1?"":"s"} omitted \u2026]`,...t.slice(t.length-b)].join(`
5
5
 
6
- `)}a(X,"buildConversation");function Z(n,s,r){const t=D(n,600,s,r);if(t.length===0)return"";const o=48;return t.length<=o?t.join(`
6
+ `)}a(Z,"buildConversation");function ee(n,s,r){const t=C(n,600,s,r);if(t.length===0)return"";const o=48;return t.length<=o?t.join(`
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(Z,"buildNamingConversation");function ee(n,s=U,r){const t=W();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,v=!1,_=!1,S=!1,h=!1;const N=a(()=>o!==void 0&&typeof o.setWidget=="function","canPaint"),R=a(i=>{try{o?.notify?.(i,"info")}catch{}},"notify"),b=a(()=>{if(N())try{o.setWidget(C,void 0,{placement:"aboveEditor"})}catch{}},"clearRecap"),$=a(i=>{if(!N()||i==="")return;const e=i.split(`
11
- `).filter(c=>c.trim()!=="");if(e.length!==0)try{o.setWidget(C,e,{placement:"aboveEditor"})}catch{}},"showRecap"),I=a(()=>{p=Date.now(),d+=1,S=!1,v&&(_=!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}k(t).then(({node:e})=>{if(e.name.trim()!==""&&e.name!==e.kind)return;const c=q(e);n.getSessionName?.()===c&&F(t,i,{name:e.name,description:e.description??"",title:e.title??"",icon:e.icon??"",kind:e.kind},()=>n.getSessionName?.()===c,w=>{try{n.setSessionName?.(w)}catch{}})}).catch(()=>{})}},"refreshAutomaticName"),P=a(i=>{if(!N()||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"),w=X(u,e,c);if(w===""){S=!0,v=!1,_=!1,b();return}S=!1;const T=i?Z(u,e,c):"",x=d;h=!0,i&&(R("Generating recap\u2026"),j(T));let G;try{G=H(t)??void 0}catch{}s(w,y=>{h=!1,!(!i&&d!==x||!N())&&(V(t,y),v=!0,_=d!==x,$(y),i&&R("Recap ready"))},m,G),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),P(!0)},"handler")}),n.on("session_start",(i,e)=>{o=e.ui,u=e.sessionManager,f(e),l=void 0,k(t).then(c=>{l=c.node}).catch(()=>{}),p=Date.now(),d=0,g=void 0,v=!1,_=!1,S=!1,h=!1,b()}),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(!N()||u===void 0||S||v&&!_||h||Date.now()-p<K())return;P(!1)}catch{}},Y);typeof E.unref=="function"&&E.unref(),M=E,n.on("session_shutdown",()=>{clearInterval(E),M===E&&(M=void 0)})}a(ee,"registerCanvasRecap");var fe=ee;export{fe as default,ee 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,_=!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};
@@ -1 +1 @@
1
- var J=Object.defineProperty;var c=(t,e)=>J(t,"name",{value:e,configurable:!0});import{envNodeId as j}from"../shared/env.js";import{writeFileSync as q,mkdirSync as H,existsSync as M,readFileSync as W}from"node:fs";import{join as Y}from"node:path";import{contextDir as z,jobDir as G}from"../core/canvas/paths.js";import{mutateBrokerFault as T,recordBrokerTelemetry as L,recordBrokerTurn as v}from"../core/runtime/broker/daemon-ops.js";import{clearStopSignals as V,consumeStopSignals as X}from"../core/runtime/stop-signals.js";import{bindBrokerSession as K,brokerExtensionState as F,relaunchBrokerRoot as Q,settleBroker as O}from"../core/runtime/broker/daemon-ops.js";import{emitEvent as C}from"../core/events/emit.js";import{activeBackgroundBashJobs as Z}from"../core/bash-jobs.js";import{CONTEXT_NUDGE_CUSTOM_TYPE as ee,formatCard as te}from"../shared/generated-context.js";import{isReviewBoundary as ne}from"../core/runtime/session-visibility.js";import{clearRefusedTurn as oe,isRuntimeTeardownInProgress as re,refuseTurn as se,runRefreshAbort as ae}from"../core/runtime/broker/extension-abort.js";import{announceMessageOrigin as N}from"../core/runtime/stamp/channel.js";const P=80;function ie(t,e){const a=e??{},o=c(p=>typeof p=="string"?p:"","pick"),i=o(a.command)||o(a.path)||o(a.file_path)||o(a.pattern)||o(a.description)||o(a.prompt),u=(i!==""?`${t}: ${i}`:t).replace(/\s+/g," ").trim();return u.length>P?u.slice(0,P):u}c(ie,"summarizeActivity");function ce(t,e,a,o,i,u,p){try{M(t)||H(t,{recursive:!0});const m=Y(t,"telemetry.json");let g={};if(M(m))try{g=JSON.parse(W(m,"utf8"))}catch{}const b={tokens_in:e,tokens_out:a,context_tokens:i??g.context_tokens,last_activity:u??g.last_activity,model:o!==""?o:g.model??"",updated_at:p};q(m,JSON.stringify(b,null,2),"utf8")}catch{}}c(ce,"flushTelemetry");function le(t){for(let e=t.length-1;e>=0;e--)if(t[e]?.role==="assistant")return t[e]}c(le,"lastAssistantMessage");function de(t){try{const e=t?.sessionManager?.getBranch();if(!Array.isArray(e))return[];const a=new Set;for(const o of e){if(!ne(o))continue;const i=o.details?.reviewId;typeof i=="string"&&a.add(i)}return[...a]}catch{return[]}}c(de,"currentReviewBoundaryIds");const D=1e4,S=[13e4,15e4,17e4,185e3,2e5];function ue(t){const e=S[0],a=S[S.length-1];if(t<e)return null;if(t>=a)return a+Math.floor((t-a)/D)*D;let o=e;for(const i of S)t>=i&&(o=i);return o}c(ue,"steerBand");function fe(t,e,a){const o=Math.round(t/1e3),i=t>=185e3;if(a==="orchestrator")return t<15e4?`Context ~${o}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.`:i?`Context ~${o}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 ~${o}k. Update context/roadmap.md so a fresh revive can continue, delegate any outstanding work, then \`crtr node yield\` to refresh.`;if(e==="resident"){const u="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 t<15e4?`Context ~${o}k and growing. ${u} Otherwise no rush \u2014 wrap up when you reach a good stopping point.`:i?`Context ~${o}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 ~${o}k. ${u} 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 t<15e4?`Context ~${o}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.`:i?`Context ~${o}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 ~${o}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(fe,"steerNote");function he(t){const e=j();if(e===void 0||e.trim()==="")return;const a=G(e);let o=0,i=0,u="",p=null,m=null;const g=new Set,b=c(()=>Z(z(e)).length>0,"backgroundJobsRunning"),f=c((n,s)=>{C({event:"broker.daemon.operation.failed",level:"error",node_id:e,error:s,fields:{operation:n}})},"emitDaemonOperationFailure"),I=c((n,s)=>{if(n.action==="reprompt"){N(n.prompt,{type:"runtime",kind:"stop-guard"}),t.sendUserMessage(n.prompt,{deliverAs:"followUp"});return}if(n.action==="shutdown")try{s?.shutdown?.()}catch{}},"enactSettleDirective"),U=3e3;let R=0,B=Promise.resolve();const E=c((n,s)=>{const r=new Date().toISOString();ce(a,o,i,u,n,s,r);const h={tokens_in:o,context_tokens:n,last_activity:s,updated_at:r};B=B.then(()=>L(e,h)).catch(y=>f("telemetry",y))},"publishTelemetry"),k=c(()=>{const n=Date.now();n-R<U||(R=n,Promise.all([v(e,{event:"progress"}),T(e,{op:"clear",link:"daemon\u2192node"})]).catch(s=>f("turn_progress",s)))},"heartbeat");t.on("session_start",async(n,s)=>{try{const r=s?.sessionManager?.getSessionId?.();if(typeof r!="string"||r==="")return;const h=s?.sessionManager?.getSessionFile?.(),y=typeof h=="string"&&h!==""?h:null,w=typeof n?.reason=="string"?n.reason:null;w==="new"&&(o=0,i=0,g.clear());const l=await K(e,{piSessionId:r,sessionFile:y,pid:process.pid,reason:w,reviewBoundaryIds:de(s)});if(l.action==="shutdown"){try{s?.shutdown?.()}catch{}return}if(l.action==="relaunch_root"){Q(e).catch(d=>{const _=d instanceof Error?d.message:String(d);s?.ui?.notify?.(`/new refused: ${_}`,"error"),C({event:"broker.daemon.operation.failed",level:"error",node_id:e,error:d,fields:{operation:"relaunch_root"}})});return}}catch(r){C({event:"broker.daemon.operation.failed",level:"error",node_id:e,error:r,fields:{operation:"session_bound"}})}}),t.on("agent_start",async(n,s)=>{try{if(!(await v(e,{event:"started"})).applied)throw new Error("daemon refused turn open")}catch(r){f("turn_open",r),s?.ui?.notify?.("Turn refused: the broker no longer owns this node.","error"),se(()=>s?.abort?.())}}),t.on("input",()=>{oe();try{V(e)}catch{}}),t.on("tool_execution_start",n=>{try{m=ie(String(n?.toolName??""),n?.args),E(p,m),k()}catch{}}),t.on("tool_execution_update",()=>{try{k()}catch{}}),t.on("message_update",()=>{try{k()}catch{}}),t.on("tool_execution_end",async(n,s)=>{try{if(k(),(await F(e)).node.intent==="refresh")try{ae(()=>s?.abort?.())}catch{}}catch{}}),t.on("session_shutdown",async(n,s)=>{try{await v(e,{event:"closed",end_reason:"teardown-aborted"})}catch(r){f("turn_close_teardown",r)}if(n?.reason==="quit")try{const r=await O(e,{stopReason:"quit",backgroundJobsRunning:b(),pushedFinal:!1});I(r,s)}catch(r){f("settle_quit",r)}});const $=c(n=>{n?.role!=="assistant"||n.usage==null||(o+=Number(n.usage.input??0)||0,i+=Number(n.usage.output??0)||0,typeof n.model=="string"&&n.model!==""&&(u=n.model))},"accumulate");t.on("turn_end",async(n,s)=>{$(n?.message);let r=null;try{const l=s.getContextUsage()?.tokens;typeof l=="number"&&(r=l)}catch{}r!==null&&(p=r),E(r,m),k();try{await Promise.all([T(e,{op:"clear",link:"daemon\u2192node"}),T(e,{op:"clear",link:"pi\u2192provider"})])}catch(l){f("turn_end_fault_clear",l)}const h=Array.isArray(n?.message?.content)?n.message.content:[],y=n?.message?.stopReason??"",w=y!=="error"&&y!=="aborted"&&h.some(l=>l?.type==="toolCall");try{const d=(await F(e)).node,_=r!==null?ue(r):null;if(_!==null&&!g.has(_)){g.add(_);const A=te("context-nudge",{},fe(_,d.lifecycle,d.mode));w?(N(A,{type:"runtime",kind:"context-nudge"}),t.sendUserMessage(A,{deliverAs:"steer"})):t.sendMessage({customType:ee,content:A,display:!0},{deliverAs:"nextTurn"})}}catch(l){f("turn_boundary",l)}});let x=null;t.on("agent_end",n=>{x=n;try{const s=Array.isArray(n?.messages)?n.messages:[];for(const r of s)$(r)}catch{}}),t.on("agent_settled",async(n,s)=>{const r=x;if(x=null,re())return;try{await v(e,{event:"closed",end_reason:"settled"})}catch(d){f("turn_close",d);return}const h=Array.isArray(r?.messages)?r.messages:[],y=le(h),w=typeof y?.stopReason=="string"?y.stopReason:"",l=r===null?{pushedFinal:!1}:X(e);try{const d=await O(e,{stopReason:w,backgroundJobsRunning:b(),pushedFinal:l.pushedFinal});I(d,s)}catch(d){f("settle",d)}})}c(he,"registerCanvasStophook");var Ie=he;export{Ie as default,he as registerCanvasStophook,fe 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 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,13 +1,13 @@
1
- var o=Object.defineProperty;var n=(e,t)=>o(e,"name",{value:t,configurable:!0});import{envNodeId as i}from"../shared/env.js";import{readOutputRequest as u}from"../core/runtime/structured-output.js";function a(e){const t=JSON.stringify(e.schema,null,2);return`<structured-output-request>
2
- ${e.mode==="terminal"?'This node owes a terminal structured result. When the work is complete, submit the result with `crtr push result` (pipe the JSON on stdin) \u2014 that records it and pushes your final report in one step, finishing this node. Do NOT call `crtr push final` yourself; it is blocked while this request is pending. If the schema cannot be honestly satisfied (blocked, unavailable, bad input), decline with `crtr push result --decline "<reason>" --code <token>` instead of inventing a value \u2014 that finishes the node with a declined outcome. You cannot stop or go dormant until the result is accepted or declined.':'This node owes a one-off structured result. Submit it with `crtr push result` (pipe the JSON on stdin) \u2014 that records it and pushes an update report to your subscribers, then you continue working normally. If the schema cannot be honestly satisfied, decline with `crtr push result --decline "<reason>" --code <token>` instead of inventing a value. You cannot stop or go dormant until the result is accepted or declined.'}
1
+ var o=Object.defineProperty;var n=(t,e)=>o(t,"name",{value:e,configurable:!0});import{envNodeId as i}from"../shared/env.js";import{readBrokerOutputRequest as u}from"../core/runtime/structured-output.js";function a(t){const e=JSON.stringify(t.schema,null,2);return`<structured-output-request>
2
+ ${t.mode==="terminal"?'This node owes a terminal structured result. When the work is complete, submit the result with `crtr push result` (pipe the JSON on stdin) \u2014 that records it and pushes your final report in one step, finishing this node. Do NOT call `crtr push final` yourself; it is blocked while this request is pending. If the schema cannot be honestly satisfied (blocked, unavailable, bad input), decline with `crtr push result --decline "<reason>" --code <token>` instead of inventing a value \u2014 that finishes the node with a declined outcome. You cannot stop or go dormant until the result is accepted or declined.':'This node owes a one-off structured result. Submit it with `crtr push result` (pipe the JSON on stdin) \u2014 that records it and pushes an update report to your subscribers, then you continue working normally. If the schema cannot be honestly satisfied, decline with `crtr push result --decline "<reason>" --code <token>` instead of inventing a value. You cannot stop or go dormant until the result is accepted or declined.'}
3
3
 
4
4
  The submitted JSON is validated against this schema; a mismatch rejects with field errors and records nothing, so fix and rerun.
5
5
 
6
6
  Required schema:
7
7
 
8
8
  \`\`\`json
9
- ${t}
9
+ ${e}
10
10
  \`\`\`
11
- </structured-output-request>`}n(a,"structuredOutputPromptBlock");function d(e){const t=i();t===void 0||t.trim()===""||e.on("before_agent_start",r=>{const s=u(t);if(s.state==="valid")return{systemPrompt:`${r.systemPrompt}
11
+ </structured-output-request>`}n(a,"structuredOutputPromptBlock");function d(t){const e=i();e===void 0||e.trim()===""||t.on("before_agent_start",r=>{const s=u(e);if(s.state==="valid")return{systemPrompt:`${r.systemPrompt}
12
12
 
13
13
  ${a(s.request)}`}})}n(d,"registerCanvasStructuredOutput");var p=d;export{p as default,d as registerCanvasStructuredOutput,a as structuredOutputPromptBlock};
@@ -1,6 +1,6 @@
1
1
  var f=Object.defineProperty;var c=(t,o)=>f(t,"name",{value:o,configurable:!0});import{envNodeId as d}from"../shared/env.js";import{execFile as l}from"node:child_process";import{createHash as m}from"node:crypto";import{mkdirSync as p,readFileSync as h,writeFileSync as x}from"node:fs";import{homedir as y}from"node:os";import{dirname as g,join as S}from"node:path";import{promisify as $}from"node:util";const _=$(l),s=15e3,O=`
2
2
 
3
- Guidelines:`;function T(t){const o=m("sha1").update(`${t}\0${process.env.CRTR_SCOPES??""}`).digest("hex").slice(0,16);return S(y(),".crouter","cache",`crtr-tool-guide-${o}.json`)}c(T,"helpCacheFile");function a(t,o){const r=`<crtr-tool-guide>
3
+ Guidelines:`;function T(t){const o=m("sha1").update(`${t}\0${process.env.CRTR_SCOPES??""}`).digest("hex").slice(0,16);return S(y(),".cache","crouter",`crtr-tool-guide-${o}.json`)}c(T,"helpCacheFile");function a(t,o){const r=`<crtr-tool-guide>
4
4
  ${o}
5
5
  </crtr-tool-guide>`,n=t.indexOf(O);return n===-1?`${t}
6
6
 
@@ -0,0 +1,15 @@
1
+ interface PiLike {
2
+ on(event: 'agent_start', handler: (event: unknown, ctx: {
3
+ getSystemPrompt(): string;
4
+ sessionManager: {
5
+ getEntries(): Array<{
6
+ type: string;
7
+ customType?: string;
8
+ data?: unknown;
9
+ }>;
10
+ };
11
+ }) => void): void;
12
+ appendEntry(type: string, data: unknown): void;
13
+ }
14
+ export default function registerSystemPromptEntry(pi: PiLike): void;
15
+ export {};
@@ -0,0 +1 @@
1
+ var p=Object.defineProperty;var n=(t,e)=>p(t,"name",{value:e,configurable:!0});import{envNodeId as m}from"../shared/env.js";function i(t){t.on("agent_start",(e,r)=>{if(!m())return;const s=r.getSystemPrompt();[...r.sessionManager.getEntries()].reverse().find(o=>o.type==="custom"&&o.customType==="crtr-system-prompt")?.data?.text!==s&&t.appendEntry("crtr-system-prompt",{text:s})})}n(i,"registerSystemPromptEntry");export{i as default};
@@ -1,8 +1,12 @@
1
1
  /** The current node's id (`CRTR_NODE_ID`), or undefined outside a node. */
2
2
  export declare function envNodeId(): string | undefined;
3
+ /** A Linux node command inherits the broker's relay, not the daemon's filesystem. */
4
+ export declare function isSandboxedNode(): boolean;
5
+ /** The app that owns the current node, supplied in its broker launch identity. */
6
+ export declare function envGrantee(): string | undefined;
3
7
  /** The current run's scope allow-list; null means the row inherits everything. */
4
8
  export declare function envScopes(): readonly string[] | null;
5
- /** Whether an allow-list holds a capability. Parameterized memory-read scopes are equivalent in beta. */
9
+ /** Whether a launched scope list covers a capability. Null means not narrowed. */
6
10
  export declare function scopeAllowed(scopes: readonly string[] | null | undefined, scope: string): boolean;
7
11
  export declare function envExecutionId(): string | undefined;
8
12
  /** The current node's target profile id (`CRTR_PROFILE_ID`), or undefined. */
@@ -1 +1 @@
1
- var _=Object.defineProperty;var e=(n,r)=>_(n,"name",{value:r,configurable:!0});function A(){return process.env.CRTR_NODE_ID}e(A,"envNodeId");function M(){const n=process.env.CRTR_SCOPES;return n===void 0?null:n===""?[]:n.split(",")}e(M,"envScopes");function D(n,r){return n==null?!0:n.some(t=>t===r||r==="memory:read"&&t.startsWith("memory:read:"))}e(D,"scopeAllowed");function S(){return process.env.CRTR_EXECUTION_ID}e(S,"envExecutionId");function x(){return process.env.CRTR_PROFILE_ID}e(x,"envProfileId");function N(){return process.env.CRTR_NODE_CWD}e(N,"envNodeCwd");function a(){return process.env.CRTR_MODEL_INTENT}e(a,"envModelIntent");function O(){return process.env.CRTR_MODEL_EXACT==="1"}e(O,"envModelExact");function I(){return process.env.CRTR_HOME}e(I,"envHomeOverride");function L(){return process.env.CRTR_RUNTIME_HOME}e(L,"envRuntimeHomeOverride");function o(n,r){if(n===void 0)return r;const t=Number(n);return Number.isFinite(t)&&t>0?t:r}e(o,"parsePositiveMs");const R=5*6e4;function m(){return o(process.env.CRTR_STREAM_WATCHDOG_MS,R)}e(m,"envStreamWatchdogMs");const i=800;function P(){return o(process.env.CRTR_WATCHER_TICK_MS,i)}e(P,"envWatcherTickMs");const c=1e3;function U(){return o(process.env.CRTR_WATCHER_DEBOUNCE_MS,c)}e(U,"envWatcherDebounceMs");const T=6e4;function B(){return o(process.env.CRTR_RECAP_IDLE_MS,T)}e(B,"envRecapIdleMs");function l(){const n=process.env.CRTR_RECAP_MODEL;return n!==void 0&&n.trim()!==""?n.trim():void 0}e(l,"envRecapModelOverride");const E=300*1e3;function H(){return o(process.env.CRTR_BASH_VALVE_MS,E)}e(H,"envBashValveMs");const p=60*1e3;function W(){return o(process.env.CRTR_BASH_AUTO_BG_DEADLINE_MS,p)}e(W,"envBashAutoBgDeadlineMs");function F(){const n=process.env.CRTR_PIDFILE;return n!==void 0&&n!==""?n:void 0}e(F,"envPidfileOverride");const v="@earendil-works/pi-coding-agent";function G(){return process.env.CRTR_BROKER_ENGINE??v}e(G,"envBrokerEngine");function K(){return process.env.CRTR_PI_BINARY}e(K,"envPiBinaryOverride");function k(){return process.env.CRTR_NO_DAEMON_AUTOSTART==="1"}e(k,"envNoDaemonAutostart");function g(){return process.env.CRTRD_TCP}e(g,"envCrtrdTcp");function b(){const n=process.env.CRTRD_TOKEN;return n!==void 0&&n!==""?n:void 0}e(b,"envCrtrdToken");function V(){return process.env.CRTR_NO_EXPORTS==="1"}e(V,"envNoExports");function h(){return process.env.CRTR_DEBUG==="1"}e(h,"envDebug");function s(n){if(n===void 0||n==="")return;const r=Number(n);return Number.isSafeInteger(r)&&r>=1?r:void 0}e(s,"parsePositiveInteger");function y(){return s(process.env.CRTR_MAX_LIVE_BROKERS)}e(y,"envMaxLiveBrokers");function X(){return s(process.env.CRTR_WARN_LIVE_BROKERS)}e(X,"envWarnLiveBrokers");function u(n){if(n===void 0)return;const r=Number(n);return Number.isFinite(r)&&r>0?r:void 0}e(u,"parsePositiveMsNoDefault");function w(){return u(process.env.CRTR_TEST_UNATTENDED_PARK_MS)}e(w,"envTestUnattendedParkMs");function Y(){return u(process.env.CRTR_UNATTENDED_PARK_MS)}e(Y,"envUnattendedParkMs");function d(){return u(process.env.CRTR_TEST_PARK_SUMMARY_GRACE_MS)}e(d,"envTestParkSummaryGraceMs");const f=5*6e4;function j(){return d()??f}e(j,"parkSummaryGraceMs");export{W as envBashAutoBgDeadlineMs,H as envBashValveMs,G as envBrokerEngine,g as envCrtrdTcp,b as envCrtrdToken,h as envDebug,S as envExecutionId,I as envHomeOverride,y as envMaxLiveBrokers,O as envModelExact,a as envModelIntent,k as envNoDaemonAutostart,V as envNoExports,N as envNodeCwd,A as envNodeId,K as envPiBinaryOverride,F as envPidfileOverride,x as envProfileId,B as envRecapIdleMs,l as envRecapModelOverride,L as envRuntimeHomeOverride,M as envScopes,m as envStreamWatchdogMs,d as envTestParkSummaryGraceMs,w as envTestUnattendedParkMs,Y as envUnattendedParkMs,X as envWarnLiveBrokers,U as envWatcherDebounceMs,P as envWatcherTickMs,j as parkSummaryGraceMs,D 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 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};
@@ -0,0 +1 @@
1
+ export declare function stripCdPrefix(line: string): string;
@@ -0,0 +1 @@
1
+ var c=Object.defineProperty;var r=(e,t)=>c(e,"name",{value:t,configurable:!0});const s=/^cd\s+(?:"[^"]*"|'[^']*'|\S+)\s*(?:&&|;)\s*/;function n(e){let t=e;for(;s.test(t);)t=t.replace(s,"");return t}r(n,"stripCdPrefix");export{n as stripCdPrefix};
package/dist/types.d.ts CHANGED
@@ -188,6 +188,12 @@ export interface CanvasMenuItem {
188
188
  confirm?: boolean;
189
189
  }
190
190
  export type ModelStrength = 'ultra' | 'strong' | 'medium' | 'light';
191
+ /** A portable model preference: a provider family at a strength, free to rotate
192
+ * to another family at the same strength. */
193
+ export interface ModelIntent {
194
+ family: string;
195
+ strength: ModelStrength;
196
+ }
191
197
  export type ModelProvider = 'anthropic' | 'openai';
192
198
  export interface ModelLaddersConfig {
193
199
  /** Optional default provider for bare strengths. If unset, runtime falls back
@@ -356,6 +362,26 @@ export interface ScopeConfig {
356
362
  remoteCanvas: RemoteCanvasConfig;
357
363
  /** The user-owned TCP listener address. Empty leaves the TCP listener off. */
358
364
  api: ApiConfig;
365
+ /** Volume root is CRTR_HOME; this optional key selects the person's file tree. */
366
+ paths?: {
367
+ user_files?: string;
368
+ };
369
+ /** Conversation store configuration for the daemon. */
370
+ store?: {
371
+ root?: string;
372
+ address?: string;
373
+ };
374
+ /** App-facing listener; absent unless this daemon serves a user's runtime. */
375
+ runtime?: {
376
+ issuer: string;
377
+ audience: string;
378
+ listener: {
379
+ address: string;
380
+ port: number;
381
+ };
382
+ jwksUrl?: string;
383
+ person_uids?: number[];
384
+ };
359
385
  /** Extra env-var names/globs a scope explicitly admits across the broker
360
386
  * spawn-env boundary (`buildBrokerEnv`, `core/runtime/spawn-env.ts`) — the
361
387
  * "I accept this crosses as a shell-visible credential" escape hatch for a
@@ -463,25 +489,13 @@ export interface InstalledMarketplace {
463
489
  url: string;
464
490
  ref: string;
465
491
  }
466
- /** The on-disk manifest at `~/.crouter/profiles/<slug>-<id>/profile.json`
467
- * (spec §2.1). A profile is an agent identity defined at the user root: it
468
- * names N project directories and owns its own `memory/` store. Project
469
- * `path`s are absolute, real-path-resolved directories in manifest order —
470
- * the pointer set `findProjectScopeRoots` walks, after the node's own
471
- * cwd. `name` is the mutable display name (and the gateable `profile` subject
472
- * field); `<slug>-<id>` in the directory name is the stable id and
473
- * never changes on rename. See `src/core/profiles/manifest.ts` for every
474
- * read/write of this file — it is the sole owner of path resolution and
475
- * mutation. */
492
+ /** A profile definition in the scoped-state `profiles` row. Its project
493
+ * paths are real-path-resolved and ordered; its id remains stable on rename.
494
+ * Memory and environment live in separate app-owned paths. */
476
495
  export interface ProfileManifest {
477
496
  schema_version: number;
478
497
  name: string;
479
498
  projects: ProfileProject[];
480
- /** The directory nodes under this profile are pinned to (see
481
- * `profileHome`). Normalized on read to the first project's path when the
482
- * manifest carries none, so a profile written before homes existed still
483
- * has one. */
484
- home: string | null;
485
499
  /** ISO timestamp while the profile is inert; null (or absent on older manifests) means active. */
486
500
  paused_at: string | null;
487
501
  /** Persona kind for creates that omit kind; absent means `general`. */
@@ -491,6 +505,8 @@ export interface ProfileManifest {
491
505
  * every broker launched under the profile as `CRTR_PROFILE_META_<KEY>`
492
506
  * env (see `core/runtime/spawn-env.ts`). Absent means none. */
493
507
  metadata?: Record<string, string>;
508
+ /** App that owns this profile; older terminal profiles have no grantee. */
509
+ grantee?: string;
494
510
  created_at: string;
495
511
  last_used_at: string | null;
496
512
  }
@@ -45,6 +45,8 @@ printf '%s\n' 'Production changes need an explicit approval.' | \
45
45
  crtr memory 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.
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.
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.
49
51
 
50
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.
@@ -15,6 +15,40 @@ const customSocketClient = new Crouter({ socketPath: '/custom/path/crtrd.sock' }
15
15
 
16
16
  `Crouter` is the default export and the only class an application constructs. `CrtrClient` from `@north-light/crouter-api` is an implementation detail and is not re-exported.
17
17
 
18
+ ## An app connection and refresh
19
+
20
+ ```ts
21
+ import { OAuth2Client } from '@north-light/crouter-sdk';
22
+
23
+ const oauth = new OAuth2Client({clientId, privateKey, keyId, redirectUri, issuer});
24
+ const {url, codeVerifier, state, nonce} = await oauth.authorizeUrl({scopes: ['openid', 'crtr:act'], state: sessionState});
25
+ // Save codeVerifier, state, and nonce in the app session; redirect the user to url.
26
+ const connection = await oauth.exchangeCode({code: callbackCode, codeVerifier, state, nonce});
27
+ const client = oauth.client(connection, store);
28
+ ```
29
+
30
+ `ConnectionStore` provides `load(userId)` and `save(connection)`; it may also implement `lock(userId, fn)`. A multi-process app must implement the lock across every process: the SDK reloads the connection, sends the refresh request only if no other process rotated its token, and saves the result while the lock is held. `MemoryConnectionStore` locks only within one process and is for local development.
31
+
32
+ A Postgres store can hold a transaction-scoped advisory lock for the whole callback (all workers must use the same database):
33
+
34
+ ```ts
35
+ async function lock<T>(userId: string, fn: () => Promise<T>): Promise<T> {
36
+ const db = await pool.connect();
37
+ try {
38
+ await db.query('BEGIN');
39
+ await db.query('SELECT pg_advisory_xact_lock(hashtextextended($1, 0))', [userId]);
40
+ const result = await fn(); // load, token request, and save complete before COMMIT
41
+ await db.query('COMMIT');
42
+ return result;
43
+ } catch (error) {
44
+ await db.query('ROLLBACK');
45
+ throw error;
46
+ } finally { db.release(); }
47
+ }
48
+ ```
49
+
50
+ `refresh_token_reused` means the app's processes raced on one refresh token; the directory invalidates the grant's refresh tokens, so the user reconnects (without another consent page). Fix the store's `lock` before reconnecting or the race will recur. `runtime_provisioning` means the user's runtime is still being set up and the SDK retries the token request.
51
+
18
52
  ## Options
19
53
 
20
54
  | Option | Type | Default | Meaning |
@@ -11,6 +11,8 @@ description: Handle API and connection errors separately from settled agent outc
11
11
 
12
12
  Exceptions are for the layer underneath: the SDK rejected an invalid local identifier or configuration, the daemon refused the request, the connection failed, the request timed out, or you aborted.
13
13
 
14
+ An error without `origin` was produced by the SDK because the request reached no server (runtime, router, or directory). Show it as a connection failure, never as a refusal. An OAuth ID token with a missing or mismatched nonce raises the SDK-only `id_token_invalid` code.
15
+
14
16
  ## Classes and mappings
15
17
 
16
18
  Every class below extends `APIError`, which carries `status`, `code`, `message`, `details`, and `headers`.
@@ -43,9 +43,9 @@ Every method accepts `RequestOptions` as its final optional argument (`signal`,
43
43
  | `memory.history(name, query?, options?)` | `name`; `MemoryHistoryQuery` | `MemoryHistoryDTO` |
44
44
  | `memory.resolve(name, scope?, options?)` | `name`; `MemoryScope` | `MemoryDocRefDTO` |
45
45
 
46
- `MemoryDocCreateRequest` requires `name`, `kind`, `when_and_why_to_read`, and `body`; it also accepts `frontmatter`, `extensions`, and the scope fields. `MemoryDocUpdateRequest` requires `rationale`, which is stored in revision history rather than document text, and optionally accepts `body`, `frontmatter`, `extensions`, `unset`, and the scope fields. `MemoryDocMoveRequest` requires `to` and accepts the scope fields.
46
+ `MemoryDocCreateRequest` requires `name`, `kind`, `when_and_why_to_read`, and `body`; it also accepts `frontmatter`, `extensions`, and the scope fields. `frontmatter.privacy` accepts `public`, `friends`, or `private`; creation defaults to persisted `public`. `MemoryDocUpdateRequest` requires `rationale`, which is stored in revision history rather than document text, and optionally accepts `body`, `frontmatter`, `extensions`, `unset`, and the scope fields. Set `frontmatter.privacy` to change the level; it cannot be unset. A legacy document without the field reads as `private`. `MemoryDocMoveRequest` requires `to` and accepts the scope fields.
47
47
 
48
- `retrieve` returns the body by default. With `frontmatter: true`, its `body` is the complete document source. `MemoryDocDTO` also contains `frontmatter`, `representation` (`'leaf-file'` or `'directory-index'`), `links`, and any lint `findings`; document DTOs include their canonical name, kind, scope, extensions, path, store root, physical relative path, and any competing candidates. `resolve` returns the winning document's location and optional plugin name without reading its body.
48
+ `retrieve` returns the body by default. With `frontmatter: true`, its `body` is the complete document source with the effective privacy level included for older documents. `MemoryDocDTO` also contains `privacy`, `frontmatter`, `representation` (`'leaf-file'` or `'directory-index'`), `links`, and any lint `findings`; document DTOs include their canonical name, kind, scope, extensions, path, store root, physical relative path, and any competing candidates. `resolve` returns the winning document's location and optional plugin name without reading its body.
49
49
 
50
50
  ```ts
51
51
  await client.memory.create({
@@ -7,6 +7,27 @@ description: Follow assistant text, tool activity, reports, and outcomes as an a
7
7
 
8
8
  Watch a run as it works: assistant text as it is produced, tool calls as they start and finish, reports as they are pushed, and the settled outcome.
9
9
 
10
+ ## Forwarding a run to a browser
11
+
12
+ The app server keeps the runtime token and connection; the browser connects only to the app. The app server calls `forwardRunEvents(client, runId, {after: cursorFromRequest(request), signal: request.signal})` and returns the Fetch `Response`. After a host cuts the browser connection, EventSource sends its last SSE id as `Last-Event-ID`; `cursorFromRequest` prefers it over the URL's `after` query parameter.
13
+
14
+ Every forwarded run event is an unnamed SSE record with its `sequence_number` as `id` and the complete event object as `data`. Receive all event types with one handler:
15
+
16
+ ```ts
17
+ const source = new EventSource(`/api/runs/${runId}/events?after=${cursor}`);
18
+ source.onmessage = ({data}) => {
19
+ const event = JSON.parse(data);
20
+ if (event.type === 'stream.refused') { showRefusal(event.error); source.close(); return; }
21
+ if (event.type === 'stream.reconnecting') { showConnectionFailure(event.error); return; }
22
+ if (event.type === 'stream.reconnected') { clearConnectionFailure(); return; }
23
+ showRunEvent(event);
24
+ };
25
+ ```
26
+
27
+ The three `stream.*` records are forwarded-stream notices, not daemon run events; they have no `sequence_number` or SSE id. A `stream.refused` carries the full error envelope, including `stream_gap`'s `details.latest_sequence` and `details.earliest_sequence`. The helper ends that response after a refusal. The SDK does not recover a gap by skipping missing events.
28
+
29
+ When the page reloads mid-reply or gets `stream_gap`, the app reads `runs.trace(runId)` through its server and shows each node's `in_progress_message` (`{thinking, text}` or `null`) as that node's open message. The trace's `latest_sequence` is read consistently with its conversations and open messages. Resume `runs.events(runId, {after: trace.latest_sequence})` (or forward with that cursor); do not use a separately read `runs.get` cursor. Continue appending new deltas to the open message, but replace its thinking or text with the complete content repeated by `node.thinking.done` or `node.output_text.done`. This shows the message from its beginning without duplicating content. `runs.get` and every `runs.list` entry expose `latest_sequence` and `last_activity_at`; a cursor equal to `latest_sequence` is not a gap even when older events have expired.
30
+
10
31
  ## The SDK surface
11
32
 
12
33
  ```ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.348",
3
+ "version": "0.3.350",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -12,7 +12,8 @@
12
12
  "bin": {
13
13
  "crtr": "bin/crtr",
14
14
  "crouter": "bin/crouter",
15
- "crtrd": "bin/crtrd"
15
+ "crtrd": "bin/crtrd",
16
+ "crtr-launcher": "bin/crtr-launcher"
16
17
  },
17
18
  "imports": {
18
19
  "#api/*": {
@@ -69,6 +70,13 @@
69
70
  "scripts/postinstall.mjs",
70
71
  "scripts/patch-pi-tree-root-ordering.mjs",
71
72
  "scripts/install-runtime.mjs",
73
+ "scripts/lib/isolation-env.mjs",
74
+ "scripts/runtime-smoke.mjs",
75
+ "scripts/build-native-linux.mjs",
76
+ "src/native/linux/addon.c",
77
+ "packages/crouter-identity/package.json",
78
+ "packages/crouter-identity/dist",
79
+ "!packages/crouter-identity/dist/**/__tests__/**",
72
80
  "scripts/pack-minify.mjs",
73
81
  "scripts/runtime-lock.mjs",
74
82
  "scripts/self-update.mjs",
@@ -76,13 +84,15 @@
76
84
  ],
77
85
  "scripts": {
78
86
  "build": "node scripts/build.mjs",
87
+ "build:native:linux": "node scripts/build-native-linux.mjs",
79
88
  "activate": "npm run build && npm run install-runtime && crtr sys daemon restart",
80
89
  "activate:pull": "git pull && npm install && npm run activate",
81
90
  "build:api": "tsc -p packages/crouter-api/tsconfig.json",
82
91
  "build:env-docker": "tsc -p packages/crouter-env-docker/tsconfig.json",
83
- "build:sdk": "tsc -p packages/crouter-sdk/tsconfig.json",
92
+ "build:sdk": "npm run build:api && npm run build:identity && tsc -p packages/crouter-sdk/tsconfig.json",
84
93
  "build:plugin": "tsc -p packages/crouter-plugin/tsconfig.json",
85
94
  "typecheck:pi-packages": "npx tsc -p src/builtin-pi-packages/pi-crtr-extensions/tsconfig.json",
95
+ "test:runtime-packaging": "node --test scripts/runtime-smoke.test.mjs",
86
96
  "test:build-output": "node scripts/build-concurrency-test.mjs",
87
97
  "check:cli-no-canvas": "node scripts/check-cli-no-canvas.mjs",
88
98
  "check:cli-cold-start": "node scripts/check-cli-cold-start.mjs",
@@ -99,7 +109,9 @@
99
109
  "test:integration": "npm run build:api && CRTR_NO_DAEMON_AUTOSTART=1 node --conditions=crtr-src --import tsx/esm --import ./scripts/test-env-scrub.mjs --test --test-concurrency=$(node -p 'Math.min(8, Math.max(2, require(`node:os`).availableParallelism() - 1))') --test-timeout=60000 ${CRTR_TEST_SHARD:+--test-shard=$CRTR_TEST_SHARD} 'src/**/__tests__/integration/*.test.ts' 'packages/crouter-sdk/src/**/__tests__/integration/*.test.ts' 'packages/crouter-plugin/src/**/__tests__/integration/*.test.ts'",
100
110
  "test:seam": "npm run build && npm run test:seam:built",
101
111
  "test:seam:built": "CRTR_NO_DAEMON_AUTOSTART=1 node --import ./scripts/test-env-scrub.mjs --test --test-concurrency=$(node -p 'Math.min(4, Math.max(2, require(`node:os`).availableParallelism() - 2))') --test-timeout=180000 ${CRTR_TEST_SHARD:+--test-shard=$CRTR_TEST_SHARD} 'dist/**/__tests__/seam/*.test.js'",
102
- "test:all": "npm test && npm run test:integration && npm run test:seam"
112
+ "test:all": "npm test && npm run test:integration && npm run test:seam",
113
+ "test:isolated": "node scripts/test-isolated.mjs",
114
+ "build:identity": "tsc -p packages/crouter-identity/tsconfig.json"
103
115
  },
104
116
  "overrides": {
105
117
  "@earendil-works/pi-ai": "0.87.1",
@@ -119,12 +131,15 @@
119
131
  "@earendil-works/pi-ai": "0.87.1",
120
132
  "@earendil-works/pi-coding-agent": "0.87.1",
121
133
  "@earendil-works/pi-tui": "0.87.1",
134
+ "@north-light/crouter-identity": "^0.3.350",
122
135
  "cron-parser": "^5.6.0",
123
136
  "esbuild": "^0.27.7",
137
+ "jose": "^6.2.12",
124
138
  "proper-lockfile": "4.1.2",
125
139
  "string-width": "^7.0.0",
126
140
  "tar": "^7.5.22",
127
141
  "typescript": "^5.7.0",
142
+ "undici": "8.10.2",
128
143
  "ws": "^8.21.0",
129
144
  "yaml": "^2.9.0",
130
145
  "zod": "^4.3.6"
@@ -0,0 +1,54 @@
1
+ import { type JSONWebKeySet, type JWTPayload } from 'jose';
2
+ export interface AccessTokenClaims extends JWTPayload {
3
+ sub: string;
4
+ grantee: string;
5
+ client_id: string;
6
+ grant: string;
7
+ exp: number;
8
+ }
9
+ export interface IdTokenClaims extends JWTPayload {
10
+ sub: string;
11
+ }
12
+ export type Scope = 'crtr:llm' | 'crtr:act' | 'crtr:schedule' | `crtr:memory:${'read' | 'rw'}:user${'' | `:${string}`}` | 'crtr:memory:manage:user' | `crtr:memory:${'read' | 'rw'}:app:${string}` | `crtr:files:${'read' | 'rw'}:${'user' | `app:${string}`}:${string}` | 'crtr:files:share' | `crtr:${'conversations' | 'objects'}:read:app:${string}` | `crtr:peer:${string}` | `${string}:${string}`;
13
+ /** App-memory form keys omit the app id. */
14
+ export declare const ENFORCED: ReadonlySet<string>;
15
+ export declare function parseScope(value: string, grantee?: string): Scope;
16
+ export declare function covers(held: string, requested: string): boolean;
17
+ /** Keys are scoped to one configured issuer; failed refreshes keep the last successful set. */
18
+ export declare class JwksCache {
19
+ readonly issuer: string;
20
+ private readonly fetcher;
21
+ private keys;
22
+ private lastUnknownRefresh;
23
+ private discovery;
24
+ constructor(issuer: string, fetcher?: typeof fetch, jwksUri?: string);
25
+ load(): Promise<JSONWebKeySet>;
26
+ forKid(kid: string | undefined): Promise<JSONWebKeySet>;
27
+ }
28
+ export declare function verifyAccessToken(options: {
29
+ token: string;
30
+ jwks: JSONWebKeySet | JwksCache;
31
+ issuer: string;
32
+ audience: string;
33
+ }): Promise<AccessTokenClaims>;
34
+ export interface SyncNoticeClaims extends JWTPayload {
35
+ purpose: 'grant_sync';
36
+ iat: number;
37
+ exp: number;
38
+ jti: string;
39
+ }
40
+ /** The directory's grant-sync notice: ES256 with the directory signing key named
41
+ * by `kid`, no `typ`, `aud` = the runtime's registered URL, a lifetime of at most
42
+ * five minutes, and a `jti` the runtime uses to answer replays without a sync. */
43
+ export declare function verifySyncNotice(options: {
44
+ token: string;
45
+ jwks: JSONWebKeySet | JwksCache;
46
+ issuer: string;
47
+ audience: string;
48
+ }): Promise<SyncNoticeClaims>;
49
+ export declare function verifyIdToken(options: {
50
+ token: string;
51
+ jwks: JSONWebKeySet | JwksCache;
52
+ issuer: string;
53
+ audience: string;
54
+ }): Promise<IdTokenClaims>;