@north-light/cli 0.3.561 → 0.3.562

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 (573) hide show
  1. package/dist/api/client.d.ts +27 -4
  2. package/dist/api/client.js +3 -3
  3. package/dist/api/contract.d.ts +1 -1
  4. package/dist/api/contract.js +1 -1
  5. package/dist/api/dto/bash-jobs.d.ts +5 -1
  6. package/dist/api/dto/broker-ops.d.ts +25 -1
  7. package/dist/api/dto/charges.d.ts +9 -2
  8. package/dist/api/dto/delivery.d.ts +26 -2
  9. package/dist/api/dto/execution-start.d.ts +57 -0
  10. package/dist/api/dto/execution-start.js +0 -0
  11. package/dist/api/dto/modelauth.d.ts +5 -0
  12. package/dist/api/dto/node-records.d.ts +16 -0
  13. package/dist/api/dto/objects.d.ts +1 -1
  14. package/dist/api/dto/reports.d.ts +0 -3
  15. package/dist/api/dto/run-events.d.ts +7 -1
  16. package/dist/api/dto/settings.d.ts +55 -0
  17. package/dist/api/dto/settings.js +0 -0
  18. package/dist/api/index.d.ts +2 -0
  19. package/dist/api/index.js +1 -1
  20. package/dist/api/routes.d.ts +11 -0
  21. package/dist/api/routes.js +1 -1
  22. package/dist/builtin-memory/crouter-sdk/release-notes.md +4 -0
  23. package/dist/cli.js +7 -7
  24. package/dist/clients/attach/chrome/bash-jobs.d.ts +11 -1
  25. package/dist/clients/attach/chrome/bash-jobs.js +1 -1
  26. package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
  27. package/dist/clients/attach/chrome/roster.js +6 -4
  28. package/dist/clients/attach/overlays/auth.js +2 -2
  29. package/dist/clients/attach/render/chat-view.js +1 -1
  30. package/dist/clients/attach/viewer.js +550 -567
  31. package/dist/commands/canvas-config.js +2 -2
  32. package/dist/commands/canvas-use.js +1 -1
  33. package/dist/commands/human.js +2 -2
  34. package/dist/commands/node/bash.js +3 -3
  35. package/dist/commands/node/create.js +2 -2
  36. package/dist/commands/person-settings.d.ts +1 -0
  37. package/dist/commands/person-settings.js +1 -0
  38. package/dist/commands/pkg/market-manage.d.ts +2 -2
  39. package/dist/commands/pkg/market-manage.js +1 -1
  40. package/dist/commands/pkg/plugin-manage.js +13 -13
  41. package/dist/commands/pkg/shared.js +1 -1
  42. package/dist/commands/profile/default.js +1 -1
  43. package/dist/commands/push.js +2 -3
  44. package/dist/commands/sys/config.js +1 -1
  45. package/dist/commands/sys/connect.js +1 -1
  46. package/dist/commands/sys/context/sysprompt.js +2 -2
  47. package/dist/commands/sys/doctor.js +1 -1
  48. package/dist/commands/sys/panels/broker-limits-panel.js +1 -1
  49. package/dist/commands/sys/panels/keybindings-panel.js +1 -1
  50. package/dist/commands/sys/panels/models-panel.d.ts +8 -2
  51. package/dist/commands/sys/panels/models-panel.js +1 -1
  52. package/dist/commands/sys/panels/prefs-panel.d.ts +1 -0
  53. package/dist/commands/sys/panels/prefs-panel.js +1 -1
  54. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  55. package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
  56. package/dist/commands/sys/panels/provider-panel.js +1 -1
  57. package/dist/commands/sys/provider-login.js +5 -5
  58. package/dist/commands/sys/setup-core.js +3 -3
  59. package/dist/commands/sys/setup-settings-runner.js +1 -1
  60. package/dist/commands/sys/spend.js +3 -3
  61. package/dist/commands/sys/update.js +1 -1
  62. package/dist/core/auth-file.d.ts +11 -19
  63. package/dist/core/auth-file.js +1 -2
  64. package/dist/core/auto-update.d.ts +1 -1
  65. package/dist/core/auto-update.js +4 -4
  66. package/dist/core/bash-jobs.d.ts +29 -71
  67. package/dist/core/bash-jobs.js +9 -10
  68. package/dist/core/blobs/directory.d.ts +3 -0
  69. package/dist/core/blobs/directory.js +1 -0
  70. package/dist/core/blobs/fault.d.ts +3 -0
  71. package/dist/core/blobs/fault.js +1 -0
  72. package/dist/core/blobs/index.d.ts +21 -0
  73. package/dist/core/blobs/index.js +1 -0
  74. package/dist/core/blobs/r2.d.ts +9 -0
  75. package/dist/core/blobs/r2.js +4 -0
  76. package/dist/core/bootstrap.d.ts +1 -1
  77. package/dist/core/bootstrap.js +2 -2
  78. package/dist/core/canvas/canvas.d.ts +9 -7
  79. package/dist/core/canvas/canvas.js +8 -8
  80. package/dist/core/canvas/crons.d.ts +3 -2
  81. package/dist/core/canvas/crons.js +3 -3
  82. package/dist/core/canvas/daemon-owner.d.ts +5 -0
  83. package/dist/core/canvas/daemon-owner.js +1 -1
  84. package/dist/core/canvas/db.d.ts +10 -9
  85. package/dist/core/canvas/db.js +4 -4
  86. package/dist/core/canvas/executions.d.ts +100 -4
  87. package/dist/core/canvas/executions.js +1 -1
  88. package/dist/core/canvas/export-sqlite.js +1 -1
  89. package/dist/core/canvas/focuses.d.ts +4 -0
  90. package/dist/core/canvas/focuses.js +1 -1
  91. package/dist/core/canvas/history.js +9 -9
  92. package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +2 -1
  93. package/dist/core/canvas/managed-worktree-sweep-candidates.js +3 -2
  94. package/dist/core/canvas/node-tokens.d.ts +1 -4
  95. package/dist/core/canvas/node-tokens.js +3 -3
  96. package/dist/core/canvas/paths.d.ts +0 -1
  97. package/dist/core/canvas/paths.js +1 -1
  98. package/dist/core/canvas/person-state.d.ts +26 -0
  99. package/dist/core/canvas/person-state.js +1 -0
  100. package/dist/core/canvas/person.d.ts +3 -10
  101. package/dist/core/canvas/person.js +7 -7
  102. package/dist/core/canvas/reconciler-leases.d.ts +12 -0
  103. package/dist/core/canvas/reconciler-leases.js +8 -0
  104. package/dist/core/canvas/recovery.d.ts +4 -0
  105. package/dist/core/canvas/recovery.js +1 -1
  106. package/dist/core/canvas/schema-pg/003-fleet-removals.sql +1 -1
  107. package/dist/core/canvas/schema-pg/005-fleet-blobs.sql +13 -0
  108. package/dist/core/canvas/schema-pg/006-job-rows.sql +20 -0
  109. package/dist/core/canvas/schema-pg/007-ledger-check.sql +117 -0
  110. package/dist/core/canvas/schema-version.d.ts +1 -1
  111. package/dist/core/canvas/schema-version.js +1 -1
  112. package/dist/core/canvas/sessions.d.ts +8 -11
  113. package/dist/core/canvas/sessions.js +1 -4
  114. package/dist/core/canvas/tree.d.ts +4 -2
  115. package/dist/core/canvas/tree.js +6 -6
  116. package/dist/core/canvas/types.d.ts +7 -0
  117. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  118. package/dist/core/command-plugins/bundle.d.ts +1 -1
  119. package/dist/core/command-plugins/bundle.js +1 -1
  120. package/dist/core/command-plugins/compose.d.ts +1 -1
  121. package/dist/core/command-plugins/discovery.d.ts +0 -1
  122. package/dist/core/command-plugins/discovery.js +1 -1
  123. package/dist/core/command-plugins/help-addenda.js +1 -1
  124. package/dist/core/command-plugins/presence.d.ts +2 -0
  125. package/dist/core/command-plugins/presence.js +1 -1
  126. package/dist/core/config.d.ts +16 -15
  127. package/dist/core/config.js +1 -1
  128. package/dist/core/conversation-store/client-worker.js +1 -1
  129. package/dist/core/conversation-store/client.js +2 -2
  130. package/dist/core/conversation-store/index.d.ts +9 -11
  131. package/dist/core/conversation-store/index.js +1 -1
  132. package/dist/core/conversation-store/patch.js +1 -1
  133. package/dist/core/conversation-store/row-store.d.ts +14 -0
  134. package/dist/core/conversation-store/row-store.js +13 -0
  135. package/dist/core/directory/join.js +1 -1
  136. package/dist/core/env-name.d.ts +1 -0
  137. package/dist/core/env-name.js +1 -1
  138. package/dist/core/environment-recipe.d.ts +15 -0
  139. package/dist/core/environment-recipe.js +1 -0
  140. package/dist/core/environments.js +1 -1
  141. package/dist/core/events/emit.js +2 -2
  142. package/dist/core/events/run-event-chunks.d.ts +25 -0
  143. package/dist/core/events/run-event-chunks.js +5 -0
  144. package/dist/core/feed/messages.js +5 -5
  145. package/dist/core/grants/mirror.d.ts +15 -0
  146. package/dist/core/grants/mirror.js +15 -3
  147. package/dist/core/grants/on-sync.d.ts +9 -5
  148. package/dist/core/grants/on-sync.js +1 -1
  149. package/dist/core/grants/remove.d.ts +1 -6
  150. package/dist/core/grants/remove.js +1 -1
  151. package/dist/core/grants/sync.js +1 -1
  152. package/dist/core/grants/watch.d.ts +15 -9
  153. package/dist/core/grants/watch.js +1 -1
  154. package/dist/core/graph/custom.js +8 -8
  155. package/dist/core/graph/jobs.d.ts +83 -5
  156. package/dist/core/graph/jobs.js +11 -2
  157. package/dist/core/graph/kinds/job.js +2 -2
  158. package/dist/core/graph/names.js +7 -7
  159. package/dist/core/graph/objects.d.ts +5 -1
  160. package/dist/core/graph/objects.js +11 -11
  161. package/dist/core/graph/reader.d.ts +3 -0
  162. package/dist/core/graph/reader.js +3 -3
  163. package/dist/core/graph/repo-sync/identity.d.ts +3 -1
  164. package/dist/core/graph/repo-sync/identity.js +1 -1
  165. package/dist/core/graph/repo-sync/repos.d.ts +1 -1
  166. package/dist/core/graph/repo-sync/repos.js +2 -2
  167. package/dist/core/graph/repo-sync/sync.js +2 -2
  168. package/dist/core/installed-plugins.js +1 -1
  169. package/dist/core/keybindings/persistence.d.ts +1 -1
  170. package/dist/core/keybindings/persistence.js +1 -1
  171. package/dist/core/layout-migrate/loose-keys.d.ts +1 -1
  172. package/dist/core/layout-migrate/loose-keys.js +1 -1
  173. package/dist/core/ledger/account.d.ts +12 -0
  174. package/dist/core/ledger/account.js +2 -0
  175. package/dist/core/ledger/charges.d.ts +2 -2
  176. package/dist/core/ledger/charges.js +1 -1
  177. package/dist/core/ledger/check.d.ts +5 -1
  178. package/dist/core/ledger/check.js +1 -7
  179. package/dist/core/ledger/chunks.d.ts +8 -0
  180. package/dist/core/ledger/chunks.js +2 -0
  181. package/dist/core/ledger/index.d.ts +2 -1
  182. package/dist/core/ledger/index.js +1 -1
  183. package/dist/core/ledger/infra-allowance.d.ts +9 -0
  184. package/dist/core/ledger/infra-allowance.js +1 -0
  185. package/dist/core/ledger/limits.js +3 -3
  186. package/dist/core/ledger/payer.d.ts +1 -1
  187. package/dist/core/ledger/payer.js +1 -1
  188. package/dist/core/ledger/read.d.ts +14 -4
  189. package/dist/core/ledger/read.js +2 -3
  190. package/dist/core/ledger/totals.d.ts +5 -16
  191. package/dist/core/ledger/totals.js +4 -4
  192. package/dist/core/ledger/types.d.ts +12 -3
  193. package/dist/core/llm/run.js +2 -2
  194. package/dist/core/managed-providers.d.ts +72 -0
  195. package/dist/core/managed-providers.js +1 -0
  196. package/dist/core/model-auth/api-credential-store.d.ts +10 -0
  197. package/dist/core/model-auth/api-credential-store.js +1 -0
  198. package/dist/core/model-auth/daemon-login.d.ts +1 -1
  199. package/dist/core/model-auth/daemon-login.js +1 -1
  200. package/dist/core/model-auth/flows.d.ts +5 -4
  201. package/dist/core/model-auth/flows.js +1 -1
  202. package/dist/core/model-auth/handoff-jti.d.ts +3 -4
  203. package/dist/core/model-auth/handoff-jti.js +1 -1
  204. package/dist/core/model-auth/readiness.js +1 -1
  205. package/dist/core/model-config.d.ts +1 -1
  206. package/dist/core/model-config.js +1 -1
  207. package/dist/core/model-routes-pool.d.ts +14 -0
  208. package/dist/core/model-routes-pool.js +1 -0
  209. package/dist/core/model-routes.d.ts +11 -16
  210. package/dist/core/model-routes.js +1 -1
  211. package/dist/core/peer/ingest.d.ts +2 -0
  212. package/dist/core/peer/ingest.js +1 -1
  213. package/dist/core/peer/stubs.d.ts +8 -0
  214. package/dist/core/peer/stubs.js +1 -1
  215. package/dist/core/permissions/evaluator.d.ts +7 -2
  216. package/dist/core/permissions/evaluator.js +2 -2
  217. package/dist/core/plugin-env.js +1 -1
  218. package/dist/core/pool-credential-store.d.ts +2 -5
  219. package/dist/core/pool-credential-store.js +1 -1
  220. package/dist/core/profiles/app-env-store.d.ts +5 -5
  221. package/dist/core/profiles/app-env-store.js +1 -2
  222. package/dist/core/profiles/default-binding.d.ts +5 -5
  223. package/dist/core/profiles/default-binding.js +1 -1
  224. package/dist/core/profiles/env-store.d.ts +10 -21
  225. package/dist/core/profiles/env-store.js +1 -2
  226. package/dist/core/profiles/manifest.d.ts +14 -18
  227. package/dist/core/profiles/manifest.js +1 -1
  228. package/dist/core/profiles/relocate.js +1 -1
  229. package/dist/core/profiles/select.js +21 -21
  230. package/dist/core/provider-credential.d.ts +1 -1
  231. package/dist/core/provider-credential.js +1 -1
  232. package/dist/core/provider-management.d.ts +3 -4
  233. package/dist/core/provider-management.js +1 -1
  234. package/dist/core/providers/bundles.js +2 -2
  235. package/dist/core/providers/call.d.ts +3 -34
  236. package/dist/core/providers/description.d.ts +34 -0
  237. package/dist/core/providers/description.js +0 -0
  238. package/dist/core/providers/token-cache.d.ts +14 -14
  239. package/dist/core/providers/token-cache.js +1 -1
  240. package/dist/core/review/companion.js +1 -1
  241. package/dist/core/runs/activity.d.ts +1 -1
  242. package/dist/core/runs/activity.js +1 -1
  243. package/dist/core/runs/events.d.ts +7 -5
  244. package/dist/core/runs/events.js +2 -6
  245. package/dist/core/runs/operations.d.ts +1 -1
  246. package/dist/core/runs/operations.js +6 -6
  247. package/dist/core/runtime/bearings.js +1 -1
  248. package/dist/core/runtime/broker/attachments-fetch.d.ts +5 -0
  249. package/dist/core/runtime/broker/attachments-fetch.js +1 -0
  250. package/dist/core/runtime/broker/bash-job-launch.d.ts +4 -2
  251. package/dist/core/runtime/broker/bash-job-launch.js +1 -1
  252. package/dist/core/runtime/broker/boot-state.d.ts +9 -0
  253. package/dist/core/runtime/broker/boot-state.js +1 -0
  254. package/dist/core/runtime/broker/cli-relay.d.ts +2 -1
  255. package/dist/core/runtime/broker/cli-relay.js +1 -1
  256. package/dist/core/runtime/broker/client-registry.d.ts +3 -3
  257. package/dist/core/runtime/broker/daemon-ops.d.ts +10 -1
  258. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  259. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  260. package/dist/core/runtime/broker/fault-retry.js +1 -1
  261. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  262. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -0
  263. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  264. package/dist/core/runtime/broker/job-reporter.d.ts +18 -0
  265. package/dist/core/runtime/broker/job-reporter.js +2 -0
  266. package/dist/core/runtime/broker/model-adapter.d.ts +3 -0
  267. package/dist/core/runtime/broker/model-adapter.js +3 -2
  268. package/dist/core/runtime/broker/signal-stream.js +1 -1
  269. package/dist/core/runtime/broker/spilled-body.d.ts +5 -0
  270. package/dist/core/runtime/broker/spilled-body.js +1 -0
  271. package/dist/core/runtime/broker/summaries-post.d.ts +5 -0
  272. package/dist/core/runtime/broker/summaries-post.js +1 -0
  273. package/dist/core/runtime/broker/tool-groups.d.ts +3 -0
  274. package/dist/core/runtime/broker/tool-groups.js +1 -1
  275. package/dist/core/runtime/broker/turn-replies.d.ts +1 -0
  276. package/dist/core/runtime/broker/turn-replies.js +1 -1
  277. package/dist/core/runtime/broker-persona-guidance.js +2 -2
  278. package/dist/core/runtime/broker.js +1 -1
  279. package/dist/core/runtime/deliver-live.js +1 -1
  280. package/dist/core/runtime/first-boot-rows.d.ts +8 -0
  281. package/dist/core/runtime/first-boot-rows.js +2 -0
  282. package/dist/core/runtime/fleet.d.ts +13 -12
  283. package/dist/core/runtime/front-door-login.js +1 -1
  284. package/dist/core/runtime/front-door.js +6 -6
  285. package/dist/core/runtime/headless-pi.js +1 -1
  286. package/dist/core/runtime/host.d.ts +14 -3
  287. package/dist/core/runtime/host.js +3 -3
  288. package/dist/core/runtime/invocation.d.ts +6 -0
  289. package/dist/core/runtime/kickoff.d.ts +2 -14
  290. package/dist/core/runtime/kickoff.js +17 -19
  291. package/dist/core/runtime/launch-config-worker.js +1 -1
  292. package/dist/core/runtime/launch.js +2 -2
  293. package/dist/core/runtime/model-registry.js +1 -1
  294. package/dist/core/runtime/node-read.d.ts +4 -6
  295. package/dist/core/runtime/node-read.js +3 -3
  296. package/dist/core/runtime/nodes.js +1 -1
  297. package/dist/core/runtime/outcome-document.d.ts +0 -1
  298. package/dist/core/runtime/outcome-document.js +1 -1
  299. package/dist/core/runtime/output-result.d.ts +15 -0
  300. package/dist/core/runtime/output-result.js +5 -0
  301. package/dist/core/runtime/placement.d.ts +17 -1
  302. package/dist/core/runtime/placement.js +1 -1
  303. package/dist/core/runtime/provider-credential-gate.d.ts +6 -2
  304. package/dist/core/runtime/provider-credential-gate.js +2 -2
  305. package/dist/core/runtime/recovery-hold.d.ts +21 -2
  306. package/dist/core/runtime/recovery-hold.js +2 -1
  307. package/dist/core/runtime/recycle.js +1 -1
  308. package/dist/core/runtime/reset.js +1 -1
  309. package/dist/core/runtime/revive.d.ts +2 -2
  310. package/dist/core/runtime/revive.js +2 -2
  311. package/dist/core/runtime/runner/blaxel/client.d.ts +81 -0
  312. package/dist/core/runtime/runner/blaxel/client.js +1 -0
  313. package/dist/core/runtime/runner/blaxel/image-build.d.ts +74 -0
  314. package/dist/core/runtime/runner/blaxel/image-build.js +5 -0
  315. package/dist/core/runtime/runner/blaxel/runner.d.ts +41 -0
  316. package/dist/core/runtime/runner/blaxel/runner.js +3 -0
  317. package/dist/core/runtime/runner/index.d.ts +8 -0
  318. package/dist/core/runtime/runner/index.js +1 -0
  319. package/dist/core/runtime/runner/process.d.ts +11 -0
  320. package/dist/core/runtime/runner/process.js +1 -0
  321. package/dist/core/runtime/runner/types.d.ts +95 -0
  322. package/dist/core/runtime/runner/types.js +0 -0
  323. package/dist/core/runtime/situational-context.d.ts +3 -6
  324. package/dist/core/runtime/situational-context.js +2 -2
  325. package/dist/core/runtime/situational-live.js +1 -1
  326. package/dist/core/runtime/spawn-env-rows.d.ts +5 -0
  327. package/dist/core/runtime/spawn-env-rows.js +1 -0
  328. package/dist/core/runtime/spawn-env.d.ts +4 -18
  329. package/dist/core/runtime/spawn-env.js +1 -1
  330. package/dist/core/runtime/spawn.js +2 -2
  331. package/dist/core/runtime/stop-guard.d.ts +1 -1
  332. package/dist/core/runtime/stop-guard.js +2 -8
  333. package/dist/core/runtime/structured-output.d.ts +0 -67
  334. package/dist/core/runtime/structured-output.js +3 -8
  335. package/dist/core/runtime/tmux-driver.d.ts +8 -0
  336. package/dist/core/runtime/tmux-driver.js +6 -6
  337. package/dist/core/runtime/view-socket.d.ts +20 -0
  338. package/dist/core/runtime/view-socket.js +3 -1
  339. package/dist/core/runtime/warm-pool.d.ts +13 -1
  340. package/dist/core/runtime/warm-pool.js +1 -1
  341. package/dist/core/scoped-state/legacy-profiles.d.ts +11 -0
  342. package/dist/core/scoped-state/legacy-profiles.js +1 -0
  343. package/dist/core/scoped-state/materialized-plugins.d.ts +18 -0
  344. package/dist/core/scoped-state/materialized-plugins.js +1 -0
  345. package/dist/core/scoped-state/migrate.d.ts +8 -1
  346. package/dist/core/scoped-state/migrate.js +3 -3
  347. package/dist/core/scoped-state/person-rows.d.ts +10 -0
  348. package/dist/core/scoped-state/person-rows.js +6 -0
  349. package/dist/core/scoped-state/person-store.d.ts +72 -0
  350. package/dist/core/scoped-state/person-store.js +1 -0
  351. package/dist/core/secrets/blaxel-launch.d.ts +24 -0
  352. package/dist/core/secrets/blaxel-launch.js +4 -0
  353. package/dist/core/secrets/blaxel-register.d.ts +2 -0
  354. package/dist/core/secrets/blaxel-register.js +1 -0
  355. package/dist/core/secrets/env-rows.d.ts +17 -0
  356. package/dist/core/secrets/env-rows.js +4 -0
  357. package/dist/core/secrets/environment-owner.d.ts +8 -0
  358. package/dist/core/secrets/environment-owner.js +1 -0
  359. package/dist/core/secrets/environment-secrets.d.ts +14 -0
  360. package/dist/core/secrets/environment-secrets.js +1 -0
  361. package/dist/core/secrets/index.d.ts +2 -0
  362. package/dist/core/secrets/index.js +1 -0
  363. package/dist/core/secrets/key.d.ts +3 -0
  364. package/dist/core/secrets/key.js +2 -0
  365. package/dist/core/secrets/seal.d.ts +18 -0
  366. package/dist/core/secrets/seal.js +1 -0
  367. package/dist/core/spaces/mounts.d.ts +1 -1
  368. package/dist/core/spaces/mounts.js +1 -1
  369. package/dist/core/spaces/process.d.ts +1 -1
  370. package/dist/core/spaces/stop.d.ts +7 -5
  371. package/dist/core/spaces/stop.js +2 -2
  372. package/dist/core/spaces/users.d.ts +2 -1
  373. package/dist/core/spaces/users.js +1 -1
  374. package/dist/core/storage/attachments.d.ts +11 -8
  375. package/dist/core/storage/attachments.js +1 -1
  376. package/dist/core/storage/tables.d.ts +4 -0
  377. package/dist/core/storage/tables.js +3 -3
  378. package/dist/core/subscription-state.d.ts +34 -72
  379. package/dist/core/subscription-state.js +1 -4
  380. package/dist/core/substrate/delivery/plan.js +1 -1
  381. package/dist/core/user-settings.js +1 -1
  382. package/dist/daemon/api/app-listener.js +10 -10
  383. package/dist/daemon/api/auth/person-bearer.d.ts +14 -0
  384. package/dist/daemon/api/auth/person-bearer.js +1 -0
  385. package/dist/daemon/api/bridge.js +4 -4
  386. package/dist/daemon/api/document-listener.js +3 -3
  387. package/dist/daemon/api/environment-of.d.ts +18 -0
  388. package/dist/daemon/api/environment-of.js +5 -0
  389. package/dist/daemon/api/handlers/analytics.js +1 -1
  390. package/dist/daemon/api/handlers/app-profiles.d.ts +2 -2
  391. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  392. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  393. package/dist/daemon/api/handlers/bash.js +1 -1
  394. package/dist/daemon/api/handlers/broker-ops.d.ts +3 -0
  395. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  396. package/dist/daemon/api/handlers/broker-recovery.js +1 -1
  397. package/dist/daemon/api/handlers/broker-signals.d.ts +0 -3
  398. package/dist/daemon/api/handlers/broker-signals.js +2 -2
  399. package/dist/daemon/api/handlers/canvas.js +4 -4
  400. package/dist/daemon/api/handlers/charges.d.ts +1 -1
  401. package/dist/daemon/api/handlers/charges.js +1 -1
  402. package/dist/daemon/api/handlers/conversations.d.ts +2 -0
  403. package/dist/daemon/api/handlers/conversations.js +3 -0
  404. package/dist/daemon/api/handlers/crons.js +1 -1
  405. package/dist/daemon/api/handlers/daemon.js +1 -1
  406. package/dist/daemon/api/handlers/delivery.d.ts +1 -1
  407. package/dist/daemon/api/handlers/delivery.js +1 -1
  408. package/dist/daemon/api/handlers/docs.js +1 -1
  409. package/dist/daemon/api/handlers/exec.js +1 -1
  410. package/dist/daemon/api/handlers/execution-start.d.ts +2 -0
  411. package/dist/daemon/api/handlers/execution-start.js +2 -0
  412. package/dist/daemon/api/handlers/files.js +1 -1
  413. package/dist/daemon/api/handlers/git-credential.d.ts +11 -0
  414. package/dist/daemon/api/handlers/git-credential.js +1 -0
  415. package/dist/daemon/api/handlers/hook-exec.d.ts +1 -1
  416. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  417. package/dist/daemon/api/handlers/human-requests.js +1 -1
  418. package/dist/daemon/api/handlers/inbox.js +1 -1
  419. package/dist/daemon/api/handlers/messages.js +1 -1
  420. package/dist/daemon/api/handlers/model-config.js +1 -1
  421. package/dist/daemon/api/handlers/modelauth.d.ts +1 -1
  422. package/dist/daemon/api/handlers/modelauth.js +1 -1
  423. package/dist/daemon/api/handlers/node-events.d.ts +6 -0
  424. package/dist/daemon/api/handlers/node-events.js +3 -3
  425. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  426. package/dist/daemon/api/handlers/node-records.js +3 -2
  427. package/dist/daemon/api/handlers/nodes.js +1 -1
  428. package/dist/daemon/api/handlers/objects.js +3 -3
  429. package/dist/daemon/api/handlers/profiles.js +1 -1
  430. package/dist/daemon/api/handlers/providers.js +1 -1
  431. package/dist/daemon/api/handlers/reports.js +9 -13
  432. package/dist/daemon/api/handlers/reviews.js +1 -1
  433. package/dist/daemon/api/handlers/runs.js +1 -1
  434. package/dist/daemon/api/handlers/settings.d.ts +2 -0
  435. package/dist/daemon/api/handlers/settings.js +1 -0
  436. package/dist/daemon/api/handlers/structured-requests.js +1 -1
  437. package/dist/daemon/api/handlers/vendor-status.d.ts +1 -1
  438. package/dist/daemon/api/handlers/vendor-status.js +1 -1
  439. package/dist/daemon/api/handlers/worktree.js +1 -1
  440. package/dist/daemon/api/map.d.ts +2 -2
  441. package/dist/daemon/api/map.js +2 -2
  442. package/dist/daemon/api/operations.js +1 -1
  443. package/dist/daemon/api/reader.d.ts +8 -1
  444. package/dist/daemon/api/reader.js +1 -1
  445. package/dist/daemon/api/router.d.ts +4 -2
  446. package/dist/daemon/api/router.js +1 -1
  447. package/dist/daemon/api/server.d.ts +15 -3
  448. package/dist/daemon/api/server.js +1 -1
  449. package/dist/daemon/api/vendor-signin.d.ts +2 -1
  450. package/dist/daemon/api/vendor-signin.js +19 -19
  451. package/dist/daemon/api/viewer-presence.d.ts +20 -6
  452. package/dist/daemon/api/viewer-presence.js +2 -1
  453. package/dist/daemon/broker-signals/bus.d.ts +48 -11
  454. package/dist/daemon/broker-signals/bus.js +1 -1
  455. package/dist/daemon/cron/armed-context.js +1 -1
  456. package/dist/daemon/cron/lease-recovery.js +1 -1
  457. package/dist/daemon/cron/live-runs.d.ts +6 -0
  458. package/dist/daemon/cron/live-runs.js +1 -1
  459. package/dist/daemon/cron/run-socket.js +1 -1
  460. package/dist/daemon/cron-run.js +2 -2
  461. package/dist/daemon/crtrd-cli.js +1 -1
  462. package/dist/daemon/crtrd.d.ts +10 -0
  463. package/dist/daemon/crtrd.js +18 -17
  464. package/dist/daemon/delivery/run-delivery.d.ts +1 -1
  465. package/dist/daemon/delivery/run-delivery.js +1 -1
  466. package/dist/daemon/due-sources.d.ts +1 -1
  467. package/dist/daemon/due-sources.js +1 -1
  468. package/dist/daemon/due.js +7 -6
  469. package/dist/daemon/fleet.d.ts +6 -6
  470. package/dist/daemon/fleet.js +9 -9
  471. package/dist/daemon/park-activity.d.ts +2 -1
  472. package/dist/daemon/park-activity.js +1 -1
  473. package/dist/daemon/park-pending.d.ts +20 -13
  474. package/dist/daemon/park-pending.js +3 -1
  475. package/dist/daemon/profile-delete.js +1 -1
  476. package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
  477. package/dist/daemon/reconcilers/bash-deadline.js +1 -3
  478. package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
  479. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  480. package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
  481. package/dist/daemon/reconcilers/cron-lane.js +1 -1
  482. package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
  483. package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
  484. package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
  485. package/dist/daemon/reconcilers/grant-effects.js +1 -0
  486. package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
  487. package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
  488. package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
  489. package/dist/daemon/reconcilers/ledger-r2.js +7 -0
  490. package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
  491. package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
  492. package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
  493. package/dist/daemon/reconcilers/ledger-storage.js +5 -0
  494. package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
  495. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  496. package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
  497. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
  498. package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
  499. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  500. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
  501. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  502. package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
  503. package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
  504. package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
  505. package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
  506. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  507. package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
  508. package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
  509. package/dist/daemon/reconcilers/recipe-image.js +7 -0
  510. package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
  511. package/dist/daemon/reconcilers/row-claim.js +2 -0
  512. package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
  513. package/dist/daemon/reconcilers/storage-due-work.js +2 -1
  514. package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
  515. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  516. package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
  517. package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
  518. package/dist/daemon/reconcilers/throttled-lane.js +1 -0
  519. package/dist/daemon/review/finish.js +1 -1
  520. package/dist/daemon/run-notices.d.ts +3 -0
  521. package/dist/daemon/run-notices.js +1 -1
  522. package/dist/daemon/runs/append-section.d.ts +4 -1
  523. package/dist/daemon/runs/append-section.js +2 -2
  524. package/dist/daemon/runs/observer.d.ts +3 -2
  525. package/dist/daemon/runs/observer.js +3 -2
  526. package/dist/daemon/runs/view-transport.d.ts +19 -0
  527. package/dist/daemon/runs/view-transport.js +1 -0
  528. package/dist/daemon/structured-requests/boot.d.ts +2 -1
  529. package/dist/daemon/structured-requests/boot.js +1 -1
  530. package/dist/daemon/structured-requests/effects.d.ts +4 -3
  531. package/dist/daemon/structured-requests/effects.js +1 -1
  532. package/dist/daemon/structured-requests/notifier.d.ts +2 -0
  533. package/dist/daemon/structured-requests/notifier.js +1 -1
  534. package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
  535. package/dist/daemon/structured-requests/sidecar.js +1 -1
  536. package/dist/launcher/validate.js +1 -1
  537. package/dist/migrations/004-canvas-documents/index.js +2 -2
  538. package/dist/pi-extensions/broker-local.d.ts +3 -3
  539. package/dist/pi-extensions/broker-local.js +1 -2
  540. package/dist/pi-extensions/canvas-bash-valve.js +6 -6
  541. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  542. package/dist/pi-extensions/canvas-elapsed.js +2 -2
  543. package/dist/pi-extensions/canvas-goal-capture.js +1 -1
  544. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  545. package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
  546. package/dist/pi-extensions/canvas-review-boundary.js +3 -3
  547. package/dist/pi-extensions/canvas-stophook.js +1 -1
  548. package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
  549. package/dist/pi-extensions/canvas-structured-output.js +6 -11
  550. package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
  551. package/dist/pi-extensions/canvas-tool-guide.js +6 -6
  552. package/dist/shared/inbox-entry-body.js +7 -7
  553. package/dist/types.d.ts +12 -0
  554. package/docs/sdk/release-notes.md +4 -0
  555. package/package.json +7 -4
  556. package/packages/crouter-identity/package.json +1 -1
  557. package/runtime.lock.json +13 -13
  558. package/scripts/git-credential-crtr +33 -0
  559. package/scripts/sandbox-bootstrap.sh +54 -0
  560. package/scripts/sandbox-start.mjs +320 -0
  561. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
  562. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
  563. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
  564. package/dist/core/conversation-store/file-store.d.ts +0 -37
  565. package/dist/core/conversation-store/file-store.js +0 -9
  566. package/dist/core/conversation-store/listener.d.ts +0 -4
  567. package/dist/core/conversation-store/listener.js +0 -8
  568. package/dist/core/scoped-state/profiles.d.ts +0 -27
  569. package/dist/core/scoped-state/profiles.js +0 -1
  570. package/dist/core/scoped-state/providers.d.ts +0 -24
  571. package/dist/core/scoped-state/providers.js +0 -1
  572. package/dist/core/scoped-state/settings.d.ts +0 -28
  573. package/dist/core/scoped-state/settings.js +0 -1
@@ -1 +1 @@
1
- var R=Object.defineProperty;var h=(n,t)=>R(n,"name",{value:t,configurable:!0});import{chownSync as P,chmodSync as $,closeSync as l,constants as _,lstatSync as f,mkdirSync as E,openSync as L,realpathSync as A}from"node:fs";import{isAbsolute as G,join as e,relative as T,resolve as j,sep as S}from"node:path";import{loadLinuxNative as q,O_PATH as x,RESOLVE_BENEATH as z,RESOLVE_NO_SYMLINKS as V}from"../native/linux.js";import{APP_UID_MAX as W,APP_UID_MIN as Z,LaunchRefused as s}from"./spec.js";import{systemIdentity as b}from"./users.js";const a=q(),v=x|_.O_NOFOLLOW,g=z|V,M=32768,F=16384,I=49152;function c(n,t){return n===t||n.startsWith(t==="/"?"/":`${t}${S}`)}h(c,"within");function N(n){if(!G(n)||j(n)!==n||n.includes("\0")||n.split(S).includes(".."))throw new s("invalid_spec",`non-canonical source: ${n}`)}h(N,"assertPath");class Q{static{h(this,"SourceValidator")}daemonGid;socketDir;rootFd;runtimeDev;runtimeIno;runtimeFd;root;runtime;constructor(t,d=b().daemonGid,u="/run/crtr"){if(this.daemonGid=d,this.socketDir=u,!a)throw new Error("Linux native addon is required by the root launcher");this.root=A(t),this.runtime=A(e(this.root,"runtime")),this.rootFd=L("/",v),this.runtimeFd=L(this.runtime,v);const r=a.fstat(this.runtimeFd);this.runtimeDev=r.dev,this.runtimeIno=r.ino}close(){l(this.rootFd),l(this.runtimeFd)}openLog(t){if(!a)throw new Error("Linux native addon is required");return a.openat2(this.runtimeFd,`nodes/${t}/job/broker.log`,_.O_WRONLY|_.O_APPEND|_.O_NOFOLLOW,g)}isRuntimeAncestor(t){if(!a)throw new Error("Linux native addon is required");const d=t.split("/").filter(Boolean);for(let u=1;u<=d.length;u++){let r;try{r=a.openat2(this.rootFd,d.slice(0,u).join("/"),v,g)}catch{return!1}try{const m=a.fstat(r);if(m.dev===this.runtimeDev&&m.ino===this.runtimeIno)return!0}finally{l(r)}}return!1}pin(t){if(!a)throw new Error("Linux native addon is required");if(!Number.isInteger(t.uid)||t.uid<Z||t.uid>W)throw new s("invalid_uid","uid outside app range");if(!/^[a-zA-Z0-9][a-zA-Z0-9-]{0,127}$/.test(t.nodeId)||!Array.isArray(t.mounts)||!Array.isArray(t.command)||!t.command.length||!t.command.every(i=>typeof i=="string"&&i.length>0&&!i.includes("\0"))||!t.env||Object.entries(t.env).some(([i,o])=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)||typeof o!="string"||o.includes("\0")))throw new s("invalid_spec","invalid node id, command, environment or mount list");const d=e(this.socketDir,"nodes",t.nodeId),u=e(this.socketDir,"nodes");if(E(u,{recursive:!0,mode:493}),f(u).uid!==0||f(u).gid!==this.daemonGid||!f(u).isDirectory()||(f(u).mode&511)!==504)throw new s("run_source","nodes directory is not root-and-daemon-controlled");E(d,{recursive:!0,mode:504});const r=f(d);if(!r.isDirectory())throw new s("run_source","run folder is not a directory");if(r.uid===0||r.uid===b().daemonUid&&r.gid===this.daemonGid&&(r.mode&511)===504)P(d,t.uid,this.daemonGid),$(d,504);else if(r.uid!==t.uid||r.gid!==this.daemonGid||(r.mode&511)!==504)throw new s("run_source","run folder has wrong owner or mode");const m=[];try{for(const i of t.mounts){if(!i||typeof i.source!="string"||typeof i.writable!="boolean")throw new s("invalid_spec","invalid mount");const o=i.source;N(o);const p=t.pluginRoot===o&&!i.writable&&c(o,e(this.runtime,"plugins"))&&o!==e(this.runtime,"plugins");if(!p&&(c(o,this.runtime)||this.isRuntimeAncestor(o)))throw new s("runtime_source",o);const O=o===e(this.socketDir,"api.sock")||o===e(this.socketDir,"store.sock")||c(o,e(this.socketDir,"bin"))||o===d;if(c(o,this.socketDir)&&!O)throw new s("run_source",o);if(i.writable&&!c(o,e(this.root,"user"))&&!c(o,e(this.root,"apps"))&&o!==d&&o!==e(this.socketDir,"api.sock")&&o!==e(this.socketDir,"store.sock"))throw new s("writable_source",o);if(!c(o,e(this.root,"user"))&&!c(o,e(this.root,"apps"))&&!c(o,this.socketDir)&&!U(o)&&!p)throw new s("invalid_spec",`unknown read-only source: ${o}`);let w;try{w=a.openat2(this.rootFd,T("/",o)||".",v,g)}catch(k){const D=k.code;throw new s(D==="ENOENT"?"source_missing":D==="ELOOP"?"symlink_source":"launch_failed",`${o}: ${String(k)}`)}const y=a.fstat(w).mode&61440;if(![M,F,I].includes(y)||y===I&&!O)throw l(w),new s(y===40960?"symlink_source":"source_type",o);m.push({source:o,writable:i.writable,fd:w,kind:y})}if(N(t.cwd),!m.some(i=>i.kind===F&&c(t.cwd,i.source)))throw new s("invalid_spec","cwd is not mounted");return m}catch(i){for(const o of m)l(o.fd);throw i}}}function U(n){return["/usr","/bin","/lib","/lib64","/opt/crouter","/etc/passwd","/etc/group","/etc/resolv.conf","/etc/hosts","/etc/ssl","/etc/ca-certificates"].some(t=>c(n,t))}h(U,"isSystemSource");export{Q as SourceValidator};
1
+ var R=Object.defineProperty;var l=(n,o)=>R(n,"name",{value:o,configurable:!0});import{chownSync as P,chmodSync as $,closeSync as h,constants as _,lstatSync as f,mkdirSync as L,openSync as k,realpathSync as A}from"node:fs";import{isAbsolute as G,join as s,relative as T,resolve as j,sep as S}from"node:path";import{loadLinuxNative as q,O_PATH as x,RESOLVE_BENEATH as z,RESOLVE_NO_SYMLINKS as V}from"../native/linux.js";import{APP_UID_MAX as W,APP_UID_MIN as Z,LaunchRefused as e}from"./spec.js";import{systemIdentity as b}from"./users.js";const a=q(),v=x|_.O_NOFOLLOW,g=z|V,M=32768,F=16384,I=49152;function c(n,o){return n===o||n.startsWith(o==="/"?"/":`${o}${S}`)}l(c,"within");function N(n){if(!G(n)||j(n)!==n||n.includes("\0")||n.split(S).includes(".."))throw new e("invalid_spec",`non-canonical source: ${n}`)}l(N,"assertPath");class Q{static{l(this,"SourceValidator")}daemonGid;socketDir;rootFd;runtimeDev;runtimeIno;runtimeFd;root;runtime;constructor(o,d=b().daemonGid,u="/run/crtr"){if(this.daemonGid=d,this.socketDir=u,!a)throw new Error("Linux native addon is required by the root launcher");this.root=A(o),this.runtime=A(s(this.root,"runtime")),this.rootFd=k("/",v),this.runtimeFd=k(this.runtime,v);const r=a.fstat(this.runtimeFd);this.runtimeDev=r.dev,this.runtimeIno=r.ino}close(){h(this.rootFd),h(this.runtimeFd)}openLog(o){if(!a)throw new Error("Linux native addon is required");return a.openat2(this.runtimeFd,`nodes/${o}/job/broker.log`,_.O_WRONLY|_.O_APPEND|_.O_NOFOLLOW,g)}isRuntimeAncestor(o){if(!a)throw new Error("Linux native addon is required");const d=o.split("/").filter(Boolean);for(let u=1;u<=d.length;u++){let r;try{r=a.openat2(this.rootFd,d.slice(0,u).join("/"),v,g)}catch{return!1}try{const m=a.fstat(r);if(m.dev===this.runtimeDev&&m.ino===this.runtimeIno)return!0}finally{h(r)}}return!1}pin(o){if(!a)throw new Error("Linux native addon is required");if(!Number.isInteger(o.uid)||o.uid<Z||o.uid>W)throw new e("invalid_uid","uid outside app range");if(!/^[a-zA-Z0-9][a-zA-Z0-9-]{0,127}$/.test(o.nodeId)||!Array.isArray(o.mounts)||!Array.isArray(o.command)||!o.command.length||!o.command.every(i=>typeof i=="string"&&i.length>0&&!i.includes("\0"))||!o.env||Object.entries(o.env).some(([i,t])=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)||typeof t!="string"||t.includes("\0")))throw new e("invalid_spec","invalid node id, command, environment or mount list");const d=s(this.socketDir,"nodes",o.nodeId),u=s(this.socketDir,"nodes");if(L(u,{recursive:!0,mode:493}),f(u).uid!==0||f(u).gid!==this.daemonGid||!f(u).isDirectory()||(f(u).mode&511)!==504)throw new e("run_source","nodes directory is not root-and-daemon-controlled");L(d,{recursive:!0,mode:504});const r=f(d);if(!r.isDirectory())throw new e("run_source","run folder is not a directory");if(r.uid===0||r.uid===b().daemonUid&&r.gid===this.daemonGid&&(r.mode&511)===504)P(d,o.uid,this.daemonGid),$(d,504);else if(r.uid!==o.uid||r.gid!==this.daemonGid||(r.mode&511)!==504)throw new e("run_source","run folder has wrong owner or mode");const m=[];try{for(const i of o.mounts){if(!i||typeof i.source!="string"||typeof i.writable!="boolean")throw new e("invalid_spec","invalid mount");const t=i.source;N(t);const p=o.pluginRoot===t&&!i.writable&&c(t,s(this.runtime,"plugins"))&&t!==s(this.runtime,"plugins");if(!p&&(c(t,this.runtime)||this.isRuntimeAncestor(t)))throw new e("runtime_source",t);const O=t===s(this.socketDir,"api.sock")||c(t,s(this.socketDir,"bin"))||t===d;if(c(t,this.socketDir)&&!O)throw new e("run_source",t);if(i.writable&&!c(t,s(this.root,"user"))&&!c(t,s(this.root,"apps"))&&t!==d&&t!==s(this.socketDir,"api.sock"))throw new e("writable_source",t);if(!c(t,s(this.root,"user"))&&!c(t,s(this.root,"apps"))&&!c(t,this.socketDir)&&!U(t)&&!p)throw new e("invalid_spec",`unknown read-only source: ${t}`);let w;try{w=a.openat2(this.rootFd,T("/",t)||".",v,g)}catch(E){const D=E.code;throw new e(D==="ENOENT"?"source_missing":D==="ELOOP"?"symlink_source":"launch_failed",`${t}: ${String(E)}`)}const y=a.fstat(w).mode&61440;if(![M,F,I].includes(y)||y===I&&!O)throw h(w),new e(y===40960?"symlink_source":"source_type",t);m.push({source:t,writable:i.writable,fd:w,kind:y})}if(N(o.cwd),!m.some(i=>i.kind===F&&c(o.cwd,i.source)))throw new e("invalid_spec","cwd is not mounted");return m}catch(i){for(const t of m)h(t.fd);throw i}}}function U(n){return["/usr","/bin","/lib","/lib64","/opt/crouter","/etc/passwd","/etc/group","/etc/resolv.conf","/etc/hosts","/etc/ssl","/etc/ca-certificates"].some(o=>c(n,o))}l(U,"isSystemSource");export{Q as SourceValidator};
@@ -1,2 +1,2 @@
1
- var R=Object.defineProperty;var p=(e,n)=>R(e,"name",{value:n,configurable:!0});import{existsSync as f}from"node:fs";import{join as l}from"node:path";import{openDb as m,withCanvasWrite as g}from"../../core/canvas/db.js";import{nodeAgentDir as C,nodeRecordDir as S,onDiskMigrationMarkerPath as k}from"../../core/canvas/paths.js";import{identifyCheckout as E}from"../../core/graph/repo-sync/identity.js";import{profileSpace as L,userRoot as j}from"../../core/layout.js";import{commitConvertedProjectCaps as I,listLegacyProjectCaps as P,listStoredProfiles as _}from"../../core/scoped-state/profiles.js";import{userStore as b}from"../../core/scoped-state/paths.js";import{userScopeRoot as y}from"../../core/scope.js";import{LEGACY_LOCAL_PERSON as O}from"../../core/canvas/legacy-person.js";import{applyPlan as x,readImportRecord as w,storePlanBodies as M}from"./apply.js";import{readLegacyCorpus as v,readMarkerIds as D}from"./legacy/discover.js";import{planImport as A}from"./plan.js";const F=p(()=>({stores:[],counts:{},rewrites:[],droppedFields:[],skipped:[],resolutions:[]}),"emptyReport");async function N(){const e=y(),n=_(e),t=P(e),c=b(e).path,s=n.map(({profileId:r,manifest:a})=>{const i=a.grantee??"app:terminal",d=new Map(t.filter(o=>o.profileId===r).map(o=>[o.path,o.memory]));return{id:r,name:a.name,app:i,memory:L(i,r).dir,projects:a.projects.map(o=>o.path),raw:{projects:a.projects.map(o=>d.has(o.path)?{path:o.path,memory:d.get(o.path)}:{path:o.path})},manifestPath:`${c}#${r}`}}),u=await(await m()).prepareUncached("SELECT node_id, cwd, grantee FROM node_rows ORDER BY created").all(),h=u.map(r=>{const a=r.grantee===O?"app:terminal":r.grantee,i=a?.startsWith("app:")?C(r.node_id,a):null,d=i!==null&&(f(l(i,"context"))||f(l(i,"reports")))?i:S(r.node_id);return{id:r.node_id,dir:d}});return{roots:{userMemory:l(j(),"memory"),profiles:s,nodeCwds:[...new Set(u.map(r=>r.cwd))],nodes:h},stored:n}}p(N,"legacyRoots");async function T(){const{roots:e,stored:n}=await N(),t=v(e),c=await(await m()).prepareUncached(`SELECT o.type, o.name AS handle, i.external_id AS externalId FROM objects o
2
- LEFT JOIN identities i ON i.object = o.id WHERE o.type IN ('person','app','repo','profile')`).all();return A(t,{roots:e,markerIds:D(k()),repoIdentity:E,existingOwners:c,storedProfiles:n.map(s=>({id:s.profileId,deliveryLimits:{...s.manifest.delivery_limits??{}}}))})}p(T,"plan");async function Z(){return await w(await m())!==null}p(Z,"canvasImportDone");async function ee(e){const n=await w(await m());if(n!==null)return{report:e.dryRun?n:F(),blockers:[],dryRun:e.dryRun,pending:!1};const t=await T();if(e.dryRun||t.blockers.length>0)return{report:t.report,blockers:t.blockers,dryRun:e.dryRun,pending:!0};const c=M(t);return I(y(),t.profileLimits),await g(async s=>await x(s,t,c)),{report:t.report,blockers:[],dryRun:!1,pending:!1}}p(ee,"runCanvasImport");export{Z as canvasImportDone,ee as runCanvasImport};
1
+ var R=Object.defineProperty;var c=(r,n)=>R(r,"name",{value:n,configurable:!0});import{existsSync as u}from"node:fs";import{join as y}from"node:path";import{openDb as f,withCanvasWrite as w}from"../../core/canvas/db.js";import{nodeAgentDir as E,nodeRecordDir as S,onDiskMigrationMarkerPath as L}from"../../core/canvas/paths.js";import{identifyCheckout as I}from"../../core/graph/repo-sync/identity.js";import{profileSpace as k,userRoot as C}from"../../core/layout.js";import{deleteLegacyProjectCaps as _,listLegacyProjectCaps as j,readLegacyUserSnapshot as O}from"../../core/scoped-state/legacy-profiles.js";import{personIdAsync as P}from"../../core/canvas/person.js";import{userStore as b}from"../../core/scoped-state/paths.js";import{userScopeRoot as h}from"../../core/scope.js";import{LEGACY_LOCAL_PERSON as A}from"../../core/canvas/legacy-person.js";import{applyPlan as D,readImportRecord as g,storePlanBodies as v}from"./apply.js";import{readLegacyCorpus as x,readMarkerIds as M}from"./legacy/discover.js";import{planImport as N}from"./plan.js";const T=c(()=>({stores:[],counts:{},rewrites:[],droppedFields:[],skipped:[],resolutions:[]}),"emptyReport");async function F(){const r=h(),n=O(r)?.profiles??[],o=j(r),d=b(r).path,s=n.map(({profileId:e,manifest:a})=>{const i=a.grantee??"app:terminal",l=new Map(o.filter(t=>t.profileId===e).map(t=>[t.path,t.memory]));return{id:e,name:a.name,app:i,memory:k(i,e).dir,projects:a.projects.map(t=>t.path),raw:{projects:a.projects.map(t=>l.has(t.path)?{path:t.path,memory:l.get(t.path)}:{path:t.path})},manifestPath:`${d}#${e}`}}),p=await(await f()).prepareUncached("SELECT node_id, cwd, grantee FROM node_rows ORDER BY created").all(),m=p.map(e=>{const a=e.grantee===A?"app:terminal":e.grantee,i=a?.startsWith("app:")?E(e.node_id,a):null,l=i!==null&&(u(y(i,"context"))||u(y(i,"reports")))?i:S(e.node_id);return{id:e.node_id,dir:l}});return{roots:{userMemory:y(C(),"memory"),profiles:s,nodeCwds:[...new Set(p.map(e=>e.cwd))],nodes:m},stored:n}}c(F,"legacyRoots");async function U(){const{roots:r,stored:n}=await F(),o=x(r),d=await(await f()).prepareUncached(`SELECT o.type, o.name AS handle, i.external_id AS externalId FROM objects o
2
+ LEFT JOIN identities i ON i.object = o.id WHERE o.type IN ('person','app','repo','profile')`).all();return N(o,{roots:r,markerIds:M(L()),repoIdentity:I,existingOwners:d,storedProfiles:n.map(s=>({id:s.profileId,deliveryLimits:{...s.manifest.delivery_limits??{}}}))})}c(U,"plan");async function er(){return await g(await f())!==null}c(er,"canvasImportDone");async function or(r){const n=await g(await f());if(n!==null)return{report:r.dryRun?n:T(),blockers:[],dryRun:r.dryRun,pending:!1};const o=await U();if(r.dryRun||o.blockers.length>0)return{report:o.report,blockers:o.blockers,dryRun:r.dryRun,pending:!0};const d=v(o),s=await P();return await w(async p=>{for(const m of o.profileLimits)if((await p.prepare("UPDATE profiles SET delivery_limits_json = ? WHERE id = ? AND person = ?").run(JSON.stringify(m.deliveryLimits),m.profileId,s)).changes!==1)throw new Error(`no stored profile ${m.profileId}`)}),_(h()),await w(async p=>await D(p,o,d)),{report:o.report,blockers:[],dryRun:!1,pending:!1}}c(or,"runCanvasImport");export{er as canvasImportDone,or as runCanvasImport};
@@ -1,6 +1,6 @@
1
- /** Persist a bare root's first real interactive message without clobbering an
2
- * existing spawning mandate. This is broker-local file state, not canvas.db. */
3
- export declare function captureGoalIfAbsent(nodeId: string, text: string): boolean;
1
+ /** Post a bare root's first real interactive message to crtrd, which stores it as the node's goal only
2
+ * while the goal is empty. Resolves to whether this call stored it. */
3
+ export declare function captureGoalIfAbsent(nodeId: string, text: string): Promise<boolean>;
4
4
  /** The node's `roadmap` document body, read through crtrd (`/v1`), or null. */
5
5
  export declare function readRoadmap(nodeId: string): Promise<string | null>;
6
6
  /** Generate and commit the first name for a node. The initial operation is
@@ -1,2 +1 @@
1
- var f=Object.defineProperty;var o=(i,t)=>f(i,"name",{value:t,configurable:!0});import{existsSync as s,mkdirSync as u,readFileSync as l,writeFileSync as b}from"node:fs";import{join as h}from"node:path";import{contextDir as y}from"../core/canvas/paths.js";import{brokerExtensionState as d,commitBrokerGeneratedName as c}from"../core/runtime/broker/daemon-ops.js";import{publishNodeNamed as N}from"../core/runtime/broker/node-named.js";import{headlessName as x,headlessNameFromConversation as L,sanitizeSessionName as S,sanitizeSessionTitle as k,slugFromPrompt as F,titleFromPrompt as v}from"../core/runtime/naming.js";function R(i,t){const r=y(i),n=h(r,"initial-prompt.md");if(s(n)&&l(n,"utf8").trim()!=="")return!1;const e=t.trim();return e===""?!1:(u(r,{recursive:!0}),b(n,`${e}
2
- `,"utf8"),!0)}o(R,"captureGoalIfAbsent");async function j(i){return(await d(i)).roadmap}o(j,"readRoadmap");function p(i,t){return{description:S(t.name)||F(i),title:k(t.title)||v(i),icon:t.icon}}o(p,"generatedLabel");function B(i,t,r){const n=t.trim();n!==""&&d(i).then(e=>{if((e.node.description??"").trim()==="")return x(n).then(a=>c(i,{kind:"initial",...p(n,a)}))}).then(e=>{!e?.applied||e.editorLabel===void 0||(N({description:e.description??"",title:e.title??"",icon:e.icon??"",editorLabel:e.editorLabel}),r?.(e.editorLabel))}).catch(()=>{})}o(B,"generateAndCommitInitialName");function D(i,t,r,n,e){const a=t.trim();a!==""&&L(a).then(m=>{if(n())return c(i,{kind:"recap",...p(a,m),expected:r})}).then(m=>{m?.applied&&m.editorLabel!==void 0&&e?.(m.editorLabel)}).catch(()=>{})}o(D,"generateAndCommitRecapName");export{R as captureGoalIfAbsent,B as generateAndCommitInitialName,D as generateAndCommitRecapName,j as readRoadmap};
1
+ var f=Object.defineProperty;var r=(e,t)=>f(e,"name",{value:t,configurable:!0});import{localClient as l}from"../api/node-transport.js";import{brokerExecutionId as s,brokerExtensionState as m,commitBrokerGeneratedName as c}from"../core/runtime/broker/daemon-ops.js";import{publishNodeNamed as u}from"../core/runtime/broker/node-named.js";import{headlessName as b,headlessNameFromConversation as h,sanitizeSessionName as x,sanitizeSessionTitle as N,slugFromPrompt as L,titleFromPrompt as k}from"../core/runtime/naming.js";async function G(e,t){const n=t.trim();return n===""?!1:(await l({autostart:!1}).captureBrokerGoal(e,{text:n,expected_execution_id:s()})).captured}r(G,"captureGoalIfAbsent");async function S(e){return(await m(e)).roadmap}r(S,"readRoadmap");function p(e,t){return{description:x(t.name)||L(e),title:N(t.title)||k(e),icon:t.icon}}r(p,"generatedLabel");function g(e,t,n){const o=t.trim();o!==""&&m(e).then(i=>{if((i.node.description??"").trim()==="")return b(o).then(a=>c(e,{kind:"initial",...p(o,a)}))}).then(i=>{!i?.applied||i.editorLabel===void 0||(u({description:i.description??"",title:i.title??"",icon:i.icon??"",editorLabel:i.editorLabel}),n?.(i.editorLabel))}).catch(()=>{})}r(g,"generateAndCommitInitialName");function w(e,t,n,o,i){const a=t.trim();a!==""&&h(a).then(d=>{if(o())return c(e,{kind:"recap",...p(a,d),expected:n})}).then(d=>{d?.applied&&d.editorLabel!==void 0&&i?.(d.editorLabel)}).catch(()=>{})}r(w,"generateAndCommitRecapName");export{G as captureGoalIfAbsent,g as generateAndCommitInitialName,w as generateAndCommitRecapName,S as readRoadmap};
@@ -1,7 +1,7 @@
1
- var ae=Object.defineProperty;var o=(t,n)=>ae(t,"name",{value:n,configurable:!0});import{envBashAutoBgDeadlineMs as ce,envBashValveMs as ue,envNodeId as de}from"../shared/env.js";import{closeSync as le,existsSync as j,mkdirSync as z,openSync as fe,readFileSync as K,readSync as he,rmSync as W,statSync as q,writeFileSync as S}from"node:fs";import{homedir as be}from"node:os";import{dirname as me}from"node:path";import{performance as J}from"node:perf_hooks";import{backgroundBashJob as X,bashJobPaths as pe,cancelBashJobProcessTree as ge,countJobLogLines as we,formatBashElapsed as Y,newBashJobId as ye,normalizeBashJobPurpose as je,tailJobLog as ve,writeJobDeadlineMs as Ee}from"../core/bash-jobs.js";import{MAX_BACKGROUND_BASH_LOG_BYTES as ct,BACKGROUND_BASH_LOG_TRUNCATION_MARKER as ut}from"../core/bash-job-supervisor.js";import{recordBackgroundedJob as _e,stopBrokerBashJob as Se}from"../core/runtime/broker/daemon-ops.js";import{BASH_JOBS_USE_LAUNCHER as Be,launchBashJobSupervisor as Ie}from"../core/runtime/broker/bash-job-launch.js";import{bashCommandRefusal as Le}from"../core/bash-guard.js";import{readConfig as ke}from"../core/config.js";import{PREVIEW_RESULT_PATH_ENV as Ae,previewResultPath as Oe}from"../core/preview-result-path.js";import{Type as B}from"typebox";import{createBashToolDefinition as Q}from"@earendil-works/pi-coding-agent";const xe=200;function Re(){return ue()}o(Re,"resolveValveMs");function Te(t){return pe(t,ye())}o(Te,"makeJobPaths");const I=new Set;let Z=!1;function ee(){for(const t of[...I])try{X(t),I.delete(t)}catch(n){process.stderr.write(`crtr: failed to background bash job ${t.jobId} during broker termination: ${n.message}
2
- `)}}o(ee,"backgroundLiveJobsForTermination");function $e(){Z||(Z=!0,process.prependListener("SIGTERM",ee),process.platform!=="win32"&&process.prependListener("SIGHUP",ee))}o($e,"installTerminationHandoff");const Je=64*1024;function N(t,n,i){let s;try{s=q(t)}catch{return n}if(s.size<=n)return n;const c=fe(t,"r");try{for(;n<s.size;){const b=Math.min(Je,s.size-n),m=Buffer.allocUnsafe(b),a=he(c,m,0,b,n);if(a===0)break;i(m.subarray(0,a)),n+=a}return n}finally{le(c)}}o(N,"tailOnce");function v(t){try{W(t,{recursive:!0,force:!0})}catch{}}o(v,"cleanupJobDir");function Ne(t){try{const n=K(t,"utf8").trim(),i=Number(n);return Number.isFinite(i)?i:null}catch{return null}}o(Ne,"readExitCode");function Ce(t){try{if(q(t).isDirectory())return{cwd:t}}catch{}const n=be();return{cwd:n,warning:`[working directory no longer exists: ${t}; running from ${n}]
3
- `}}o(Ce,"resolveExecutionCwd");function te(t,n,i=()=>null,s,c=()=>{}){return{exec:o(async(b,m,{onData:a,signal:f,timeout:p,env:L})=>new Promise((E,d)=>{const w=i();if(f?.aborted){d(new Error("aborted"));return}const k=Le(b,m);if(k!==null){d(new Error(k));return}const e=Te(n);z(e.dir,{recursive:!0}),S(e.cmdSh,b),S(e.jobLog,""),S(e.jobRun,""),w!==null&&S(e.jobPurpose,w);let l=0,g=!1,_,A,O,C=!1;const ne=Be,M=J.now(),oe=Re();let y;const re=o(()=>{y&&clearInterval(y),f&&f.removeEventListener("abort",H),I.delete(e)},"teardown"),h=o(r=>{g||(g=!0,re(),r())},"finish");let D=!1;function x(r=!1){g||D||(D=!0,y&&clearInterval(y),_e(t,e.jobId,{command:K(e.cmdSh,"utf8"),job_dir:e.dir,log_path:e.jobLog}).then(()=>P(r,""),u=>P(r,`
4
- [crtr could not record job ${e.jobId} (${u.message}); it will NOT message you when it exits. Watch its log.]`)))}o(x,"finishBackground");function P(r,u){const se=Y(J.now()-M);let F="";if(r){const V=ce();Ee(e,Date.now()+V),F=`It will be CANCELED in ${Y(V)} unless you claim it: crtr node bash extend ${e.jobId} --for <duration> (or --keep to run to completion). `}const G=`
5
- [backgrounded as job ${e.jobId} after ${se} in the foreground${r?" (auto)":""}. `+F+(u===""?"It will interrupt you with a message when it exits. ":"")+`Watch: tail -f ${e.jobLog} ; stop: crtr node bash kill ${e.jobId}]`;a(Buffer.from(G+u)),c({jobId:e.jobId,logPath:e.jobLog,notice:G+u}),h(()=>E({exitCode:0}))}o(P,"handOff");function U(){l=N(e.jobLog,l,a);const r=Ne(e.jobExit);h(()=>E({exitCode:r})),v(e.dir)}o(U,"finishForeground");function ie(r=!1){const u=X(e);if(u==="backgrounded"||u==="already-backgrounded"){x(r);return}if(u==="finished"){U();return}h(()=>d(new Error(`bash job ${e.jobId} disappeared before it could be backgrounded`))),v(e.dir)}o(ie,"requestBackground");function R(r){if(!(g||C)){if(l=N(e.jobLog,l,a),j(e.jobBg)){x();return}if(!j(e.jobExit)){if(_===void 0){O??=r;return}if(ne){C=!0,Se(t,e.jobId).then(()=>{h(()=>d(r)),v(e.dir)},u=>h(()=>d(u)));return}_!==void 0&&A!==void 0&&ge(_,A),h(()=>d(r)),v(e.dir)}}}o(R,"requestStop");function H(){R(new Error("aborted"))}o(H,"onAbort"),f&&f.addEventListener("abort",H,{once:!0});const T=Ce(m);T.warning&&a(Buffer.from(T.warning));let $=L??process.env;s!==void 0&&(z(me(s),{recursive:!0}),W(s,{force:!0}),$={...$,[Ae]:s}),Ie(t,e,n,T.cwd,$).then(r=>{_=r.pgid,A=r.identity,I.add(e),O!==void 0&&R(O)},r=>{h(()=>d(r)),v(e.dir)}),y=setInterval(()=>{if(l=N(e.jobLog,l,a),j(e.jobDone)){U();return}if(j(e.jobBg)){x();return}if(j(e.jobExit))return;const r=J.now()-M;if(p!==void 0&&p>0){r>=p*1e3&&R(new Error(`timeout:${p}`));return}r>=oe&&ie(!0)},xe)}),"exec")}}o(te,"createValveOperations");const Me=["One short clause naming what this step is FOR, in the words of the person you",'are working for \u2014 "Reading the Acme thread", not "Fetching emails" and never','"Running GMAIL_FETCH_EMAILS". A person reads this while the command runs; it',"is the only thing they see of this step. Under about eight words. Omit it for","steps that only touch your own scratch work."].join(" "),De=3;function Pe(t){const n=ve(t.logPath,De),i=Math.max(0,we(t.logPath)-n.length),s=n.length===0?"(no output yet)":n.join(`
1
+ var ce=Object.defineProperty;var o=(e,n)=>ce(e,"name",{value:n,configurable:!0});import{envBashAutoBgDeadlineMs as z,envBashValveMs as ue,envNodeId as de}from"../shared/env.js";import{closeSync as le,existsSync as v,mkdirSync as K,openSync as fe,readFileSync as W,readSync as he,rmSync as q,statSync as X,writeFileSync as $}from"node:fs";import{homedir as be}from"node:os";import{dirname as me}from"node:path";import{performance as N}from"node:perf_hooks";import{backgroundBashJob as Y,bashJobPaths as pe,clearJobDeadlineFile as ge,writeJobDeadlineFile as we,cancelBashJobProcessTree as ye,countJobLogLines as ve,formatBashElapsed as Q,newBashJobId as Ee,normalizeBashJobPurpose as je,tailJobLog as Ie}from"../core/bash-jobs.js";import{MAX_BACKGROUND_BASH_LOG_BYTES as ht,BACKGROUND_BASH_LOG_TRUNCATION_MARKER as bt}from"../core/bash-job-supervisor.js";import{brokerApiUrl as _e,recordBackgroundedJob as Be,reportBrokerJob as Se,stopBrokerBashJob as ke}from"../core/runtime/broker/daemon-ops.js";import{bashJobsUseLauncher as Le,launchBashJobSupervisor as Ae}from"../core/runtime/broker/bash-job-launch.js";import{JobReporter as xe}from"../core/runtime/broker/job-reporter.js";import{bashCommandRefusal as Oe}from"../core/bash-guard.js";import{readConfig as Je}from"../core/config.js";import{PREVIEW_RESULT_PATH_ENV as Re,previewResultPath as Te}from"../core/preview-result-path.js";import{Type as _}from"typebox";import{createBashToolDefinition as Z}from"@earendil-works/pi-coding-agent";const $e=200;function Ne(){return ue()}o(Ne,"resolveValveMs");function Ce(e){return pe(e,Ee())}o(Ce,"makeJobPaths");const B=new Set;let ee=!1;function te(){for(const e of[...B])try{Y(e),B.delete(e)}catch(n){process.stderr.write(`crtr: failed to background bash job ${e.jobId} during broker termination: ${n.message}
2
+ `)}}o(te,"backgroundLiveJobsForTermination");function Me(){ee||(ee=!0,process.prependListener("SIGTERM",te),process.platform!=="win32"&&process.prependListener("SIGHUP",te))}o(Me,"installTerminationHandoff");const De=64*1024;function C(e,n,i){let s;try{s=X(e)}catch{return n}if(s.size<=n)return n;const c=fe(e,"r");try{for(;n<s.size;){const b=Math.min(De,s.size-n),m=Buffer.allocUnsafe(b),u=he(c,m,0,b,n);if(u===0)break;i(m.subarray(0,u)),n+=u}return n}finally{le(c)}}o(C,"tailOnce");function E(e){try{q(e,{recursive:!0,force:!0})}catch{}}o(E,"cleanupJobDir");function Pe(e){try{const n=W(e,"utf8").trim(),i=Number(n);return Number.isFinite(i)?i:null}catch{return null}}o(Pe,"readExitCode");function Ue(e){try{if(X(e).isDirectory())return{cwd:e}}catch{}const n=be();return{cwd:n,warning:`[working directory no longer exists: ${e}; running from ${n}]
3
+ `}}o(Ue,"resolveExecutionCwd");function ne(e,n,i=()=>null,s,c=()=>{}){return{exec:o(async(b,m,{onData:u,signal:f,timeout:p,env:S})=>new Promise((j,d)=>{const w=i();if(f?.aborted){d(new Error("aborted"));return}const k=Oe(b,m);if(k!==null){d(new Error(k));return}const t=Ce(n);K(t.dir,{recursive:!0}),$(t.cmdSh,b),$(t.jobLog,""),$(t.jobRun,"");let l=0,g=!1,I,L,A,M=!1;const oe=Le(),D=N.now(),re=Ne();let y;const ie=o(()=>{y&&clearInterval(y),f&&f.removeEventListener("abort",G),B.delete(t)},"teardown"),h=o(r=>{g||(g=!0,ie(),r())},"finish");let P=!1;function x(r=!1){if(g||P)return;P=!0,y&&clearInterval(y);const a=r?Date.now()+z():void 0;a!==void 0&&we(t,a),Be(e,t.jobId,{command:W(t.cmdSh,"utf8"),...w===null?{}:{purpose:w},...a===void 0?{}:{deadline_at_ms:a}}).then(()=>{try{ge(t)}catch{}U(r,"")},T=>U(r,`
4
+ [crtr could not record job ${t.jobId} (${T.message}); it will NOT message you when it exits. Watch its log.]`))}o(x,"finishBackground");function U(r,a){const T=Q(N.now()-D);let H="";if(r){const ae=z();H=`It will be CANCELED in ${Q(ae)} unless you claim it: crtr node bash extend ${t.jobId} --for <duration> (or --keep to run to completion). `}const V=`
5
+ [backgrounded as job ${t.jobId} after ${T} in the foreground${r?" (auto)":""}. `+H+(a===""?"It will interrupt you with a message when it exits. ":"")+`Watch: tail -f ${t.jobLog} ; stop: crtr node bash kill ${t.jobId}]`;u(Buffer.from(V+a)),c({jobId:t.jobId,logPath:t.jobLog,notice:V+a}),h(()=>j({exitCode:0}))}o(U,"handOff");function F(){l=C(t.jobLog,l,u);const r=Pe(t.jobExit);h(()=>j({exitCode:r})),E(t.dir)}o(F,"finishForeground");function se(r=!1){const a=Y(t);if(a==="backgrounded"||a==="already-backgrounded"){x(r);return}if(a==="finished"){F();return}h(()=>d(new Error(`bash job ${t.jobId} disappeared before it could be backgrounded`))),E(t.dir)}o(se,"requestBackground");function O(r){if(!(g||M)){if(l=C(t.jobLog,l,u),v(t.jobBg)){x();return}if(!v(t.jobExit)){if(I===void 0){A??=r;return}if(oe){M=!0,ke(e,t.jobId).then(()=>{h(()=>d(r)),E(t.dir)},a=>h(()=>d(a)));return}I!==void 0&&L!==void 0&&ye(I,L),h(()=>d(r)),E(t.dir)}}}o(O,"requestStop");function G(){O(new Error("aborted"))}o(G,"onAbort"),f&&f.addEventListener("abort",G,{once:!0});const J=Ue(m);J.warning&&u(Buffer.from(J.warning));let R=S??process.env;s!==void 0&&(K(me(s),{recursive:!0}),q(s,{force:!0}),R={...R,[Re]:s}),Ae(e,t,n,J.cwd,R).then(r=>{I=r.pgid,L=r.identity,B.add(t),A!==void 0&&O(A)},r=>{h(()=>d(r)),E(t.dir)}),y=setInterval(()=>{if(l=C(t.jobLog,l,u),v(t.jobDone)){F();return}if(v(t.jobBg)){x();return}if(v(t.jobExit))return;const r=N.now()-D;if(p!==void 0&&p>0){r>=p*1e3&&O(new Error(`timeout:${p}`));return}r>=re&&se(!0)},$e)}),"exec")}}o(ne,"createValveOperations");const Fe=["One short clause naming what this step is FOR, in the words of the person you",'are working for \u2014 "Reading the Acme thread", not "Fetching emails" and never','"Running GMAIL_FETCH_EMAILS". A person reads this while the command runs; it',"is the only thing they see of this step. Under about eight words. Omit it for","steps that only touch your own scratch work."].join(" "),Ge=3;function He(e){const n=Ie(e.logPath,Ge),i=Math.max(0,ve(e.logPath)-n.length),s=n.length===0?"(no output yet)":n.join(`
6
6
  `),c=i===0?"":`
7
- [${i} earlier output line${i===1?"":"s"} are in the job log only]`;return{content:[{type:"text",text:`${s}${c}${t.notice}`}],details:void 0}}o(Pe,"handoffResult");function Ue(t){return{...t,parameters:B.Object({purpose:B.Optional(B.String({description:Me})),...t.parameters.properties})}}o(Ue,"withPurpose");const He=["A command that needs longer than one call \u2014 a test lane, a build, a soak \u2014 is started with","`crtr node bash run '<command>'`, which returns at once and wakes you with the exit code; the job is a canvas","object others can watch. Do not use `&`, `nohup`, `setsid`, or a cron that polls a log. A foreground command","past 5 minutes is moved to a job automatically; a `timeout` kills it and everything it started."].join(" ");function Fe(t){const{command:n,...i}=t.parameters.properties;return{...t,parameters:B.Object({command:{...n,description:`${n.description??""} ${He}`.trim()},...i})}}o(Fe,"withJobGuidance");function Ge(t,n,i,s){const c=Fe(Q(i,{operations:te(t,n)}));return{...s?Ue(c):c,execute:o(async(a,f,p,L,E)=>{const d=s?je(f.purpose):null;let w=null;const e=await Q(i,{operations:te(t,n,()=>d,Oe(a),g=>{w=g})}).execute(a,f,p,L,E),l=w;return l===null?e:Pe(l)},"execute")}}o(Ge,"createValveToolDefinition");function Ve(t){const n=de();if(n===void 0||n.trim()==="")return;const i=process.env.CRTR_CONTEXT_DIR;i===void 0||i.trim()===""||($e(),t.on("session_start",(s,c)=>{t.registerTool(Ge(n,i,c.cwd,ke("user").bash_tool_purpose))}))}o(Ve,"default");export{ut as BACKGROUND_BASH_LOG_TRUNCATION_MARKER,ct as MAX_BACKGROUND_BASH_LOG_BYTES,te as createValveOperations,Ge as createValveToolDefinition,Ve as default};
7
+ [${i} earlier output line${i===1?"":"s"} are in the job log only]`;return{content:[{type:"text",text:`${s}${c}${e.notice}`}],details:void 0}}o(He,"handoffResult");function Ve(e){return{...e,parameters:_.Object({purpose:_.Optional(_.String({description:Fe})),...e.parameters.properties})}}o(Ve,"withPurpose");const ze=["A command that needs longer than one call \u2014 a test lane, a build, a soak \u2014 is started with","`crtr node bash run '<command>'`, which returns at once and wakes you with the exit code; the job is a canvas","object others can watch. Do not use `&`, `nohup`, `setsid`, or a cron that polls a log. A foreground command","past 5 minutes is moved to a job automatically; a `timeout` kills it and everything it started."].join(" ");function Ke(e){const{command:n,...i}=e.parameters.properties;return{...e,parameters:_.Object({command:{...n,description:`${n.description??""} ${ze}`.trim()},...i})}}o(Ke,"withJobGuidance");function We(e,n,i,s){const c=Ke(Z(i,{operations:ne(e,n)}));return{...s?Ve(c):c,execute:o(async(u,f,p,S,j)=>{const d=s?je(f.purpose):null;let w=null;const t=await Z(i,{operations:ne(e,n,()=>d,Te(u),g=>{w=g})}).execute(u,f,p,S,j),l=w;return l===null?t:He(l)},"execute")}}o(We,"createValveToolDefinition");function qe(e){const n=de();if(n===void 0||n.trim()==="")return;const i=process.env.CRTR_CONTEXT_DIR;i===void 0||i.trim()===""||(Me(),_e()!==void 0&&new xe(i,(s,c)=>Se(n,s,c)).start(),e.on("session_start",(s,c)=>{e.registerTool(We(n,i,c.cwd,Je("user").bash_tool_purpose))}))}o(qe,"default");export{bt as BACKGROUND_BASH_LOG_TRUNCATION_MARKER,ht as MAX_BACKGROUND_BASH_LOG_BYTES,ne as createValveOperations,We as createValveToolDefinition,qe as default};
@@ -1,2 +1,2 @@
1
- var w=Object.defineProperty;var s=(t,e)=>w(t,"name",{value:e,configurable:!0});import{envNodeId as b}from"../shared/env.js";import{CONTEXT_INTRO_CUSTOM_TYPE as a,formatCard as C}from"../shared/generated-context.js";import{brokerDelivery as m,brokerExtensionState as f}from"../core/runtime/broker/daemon-ops.js";import{buildForkBearingsFromState as p}from"../core/runtime/broker-extension-render.js";import{acknowledgePersonaBaseline as T}from"../core/runtime/broker-persona-guidance.js";import{situationalContextEnvelope as l}from"../core/runtime/situational-context.js";async function O(t){return(await m(t,{activity:"boot"})).content}s(O,"buildContextIntro");async function P(t){const e=await f(t);return p(e,l(t)??"")}s(P,"buildForkContextIntro");function g(t){const e=t.content;return typeof e=="string"?e:Array.isArray(e)?e.filter(r=>typeof r?.text=="string").map(r=>r.text).join(`
2
- `):""}s(g,"entryText");function v(t){t.on("session_start",async(e,r)=>{const n=b();if(n===void 0||n.trim()==="")return;const x=e?.reason,i=await f(n);if(i.warm_spare||x==="new"&&i.node.parent===null)return;const c=r.sessionManager.getBranch().filter(o=>o.type==="custom_message"&&o.customType===a);if(c.some(o=>o.details?.nodeId===n||g(o).includes(n)))return;const d=await m(n,{activity:"boot",inherited:c.length>0}),y=d.inherited===!0?p(i,l(n)??""):d.content,u=C("bearings",{},y);if(t.sendMessage({customType:a,content:u,display:!0,details:{nodeId:n}}),!r.sessionManager.getBranch().some(o=>o.type==="custom_message"&&o.customType===a&&o.details?.nodeId===n&&g(o)===u))throw new Error(`Pi did not materialize the context baseline for ${n}`);await T(i)})}s(v,"registerCanvasContextIntro");var S=v;export{a as CONTEXT_INTRO_CUSTOM_TYPE,O as buildContextIntro,P as buildForkContextIntro,S as default,v as registerCanvasContextIntro};
1
+ var x=Object.defineProperty;var s=(e,t)=>x(e,"name",{value:t,configurable:!0});import{envNodeId as w}from"../shared/env.js";import{CONTEXT_INTRO_CUSTOM_TYPE as a,formatCard as b}from"../shared/generated-context.js";import{brokerDelivery as m}from"../core/runtime/broker/daemon-ops.js";import{boundExtensionState as f}from"../core/runtime/broker/boot-state.js";import{buildForkBearingsFromState as l}from"../core/runtime/broker-extension-render.js";import{acknowledgePersonaBaseline as T}from"../core/runtime/broker-persona-guidance.js";async function N(e){return(await m(e,{activity:"boot"})).content}s(N,"buildContextIntro");async function O(e){const t=await f(e);return l(t,t.situational_card??"")}s(O,"buildForkContextIntro");function p(e){const t=e.content;return typeof t=="string"?t:Array.isArray(t)?t.filter(r=>typeof r?.text=="string").map(r=>r.text).join(`
2
+ `):""}s(p,"entryText");function _(e){e.on("session_start",async(t,r)=>{const o=w();if(o===void 0||o.trim()==="")return;const g=t?.reason,i=await f(o);if(i.warm_spare||g==="new"&&i.node.parent===null)return;const c=r.sessionManager.getBranch().filter(n=>n.type==="custom_message"&&n.customType===a);if(c.some(n=>n.details?.nodeId===o||p(n).includes(o)))return;const d=await m(o,{activity:"boot",inherited:c.length>0}),y=d.inherited===!0?l(i,i.situational_card??""):d.content,u=b("bearings",{},y);if(e.sendMessage({customType:a,content:u,display:!0,details:{nodeId:o}}),!r.sessionManager.getBranch().some(n=>n.type==="custom_message"&&n.customType===a&&n.details?.nodeId===o&&p(n)===u))throw new Error(`Pi did not materialize the context baseline for ${o}`);await T(i)})}s(_,"registerCanvasContextIntro");var P=_;export{a as CONTEXT_INTRO_CUSTOM_TYPE,N as buildContextIntro,O as buildForkContextIntro,P as default,_ as registerCanvasContextIntro};
@@ -1,2 +1,2 @@
1
- var f=Object.defineProperty;var d=(e,t)=>f(e,"name",{value:t,configurable:!0});import{envNodeId as h}from"../shared/env.js";import{brokerExtensionState as p}from"../core/runtime/broker/daemon-ops.js";import{crtrPreviewRecords as m}from"../core/preview-registry.js";const g="This is how long you have been on this work, shown because you have delegates. Finishing sooner is worth something: keep independent work running in parallel and take the quicker path when quality is unchanged. It is not a budget; never trade verification or scope for time.";function w(e){const t=Math.floor(Math.max(0,e)/1e3),o=Math.floor(t/60),r=Math.floor(o/60);return`elapsed ${r>0?`${r}h `:""}${o%60}m ${t%60}s`}d(w,"elapsedLine");function v(e){return m(e).some(t=>t.path==="node new"&&t.error===void 0)}d(v,"spawnedChild");function x(e,t=p,o=Date.now){const r=h();if(r===void 0||r.trim()==="")return;let l,a=o(),i=!1,c=!1;e.on("session_start",async()=>{a=o(),c=!1;const n=await t(r);if(l=n.node.lifecycle,i=i||n.children.length>0,l==="terminal"){const s=Date.parse(n.node.created);Number.isFinite(s)&&(a=s)}}),e.on("input",n=>{l==="resident"&&n?.streamingBehavior===void 0&&(a=o())}),e.on("tool_result",n=>{if(!i&&v(n)&&(i=!0),!i)return;const s=w(o()-a),u=c?s:`${s}
2
- ${g}`;return c=!0,{content:[...n.content,{type:"text",text:u}]}})}d(x,"registerCanvasElapsed");var I=x;export{I as default,x as registerCanvasElapsed};
1
+ var f=Object.defineProperty;var l=(e,t)=>f(e,"name",{value:t,configurable:!0});import{envNodeId as h}from"../shared/env.js";import{boundExtensionState as p,retireBootExtensionState as m}from"../core/runtime/broker/boot-state.js";import{crtrPreviewRecords as g}from"../core/preview-registry.js";const y="This is how long you have been on this work, shown because you have delegates. Finishing sooner is worth something: keep independent work running in parallel and take the quicker path when quality is unchanged. It is not a budget; never trade verification or scope for time.";function w(e){const t=Math.floor(Math.max(0,e)/1e3),o=Math.floor(t/60),r=Math.floor(o/60);return`elapsed ${r>0?`${r}h `:""}${o%60}m ${t%60}s`}l(w,"elapsedLine");function x(e){return g(e).some(t=>t.path==="node new"&&t.error===void 0)}l(x,"spawnedChild");function v(e,t=p,o=Date.now){const r=h();if(r===void 0||r.trim()==="")return;let d,a=o(),i=!1,c=!1;e.on("session_start",async()=>{a=o(),c=!1;let n;try{n=await t(r)}finally{m()}if(d=n.node.lifecycle,i=i||n.children.length>0,d==="terminal"){const s=Date.parse(n.node.created);Number.isFinite(s)&&(a=s)}}),e.on("input",n=>{d==="resident"&&n?.streamingBehavior===void 0&&(a=o())}),e.on("tool_result",n=>{if(!i&&x(n)&&(i=!0),!i)return;const s=w(o()-a),u=c?s:`${s}
2
+ ${y}`;return c=!0,{content:[...n.content,{type:"text",text:u}]}})}l(v,"registerCanvasElapsed");var I=v;export{I as default,v as registerCanvasElapsed};
@@ -1 +1 @@
1
- var a=Object.defineProperty;var o=(e,t)=>a(e,"name",{value:t,configurable:!0});import{envNodeId as u}from"../shared/env.js";import{captureGoalIfAbsent as s,generateAndCommitInitialName as c}from"./broker-local.js";import{parseCard as f}from"../shared/generated-context.js";function m(e){e.on("input",t=>{try{const r=u();if(r===void 0||r.trim()==="")return;const n=(t.text??"").trim();if(n===""||t.source==="extension"||f({role:"user",content:n})!==null)return;t.source==="interactive"&&s(r,n),c(r,n,i=>{try{e.setSessionName?.(i)}catch{}})}catch{}})}o(m,"registerCanvasGoalCapture");var C=m;export{C as default,m as registerCanvasGoalCapture};
1
+ var a=Object.defineProperty;var o=(e,t)=>a(e,"name",{value:t,configurable:!0});import{envNodeId as c}from"../shared/env.js";import{captureGoalIfAbsent as u,generateAndCommitInitialName as s}from"./broker-local.js";import{parseCard as f}from"../shared/generated-context.js";function m(e){e.on("input",t=>{try{const r=c();if(r===void 0||r.trim()==="")return;const n=(t.text??"").trim();if(n===""||t.source==="extension"||f({role:"user",content:n})!==null)return;t.source==="interactive"&&u(r,n).catch(()=>{}),s(r,n,i=>{try{e.setSessionName?.(i)}catch{}})}catch{}})}o(m,"registerCanvasGoalCapture");var C=m;export{C as default,m as registerCanvasGoalCapture};
@@ -1,2 +1,2 @@
1
- var O=Object.defineProperty;var l=(s,t)=>O(s,"name",{value:t,configurable:!0});import{envInboxBetweenTurns as A,envNodeId as H,envProfileId as U,envWatcherDebounceMs as q,envWatcherTickMs as B,envWatcherBackstopMs as J}from"../shared/env.js";import{coalesceBrokerInbox as W,entryCards as $}from"../core/runtime/broker/inbox.js";import{acknowledgeBrokerMail as G,claimBrokerMail as X,brokerExtensionState as j}from"../core/runtime/broker/daemon-ops.js";import{brokerSignalClient as F}from"../core/runtime/broker/signal-stream.js";import{wasTurnRefused as L}from"../core/runtime/broker/extension-abort.js";import{isDaemonTransportApiError as S}from"../api/errors.js";import{announceMessageOrigin as V,messageSignature as w}from"../core/runtime/stamp/channel.js";import{captureGoalIfAbsent as z,generateAndCommitInitialName as Q}from"./broker-local.js";import{emitEvent as Y}from"../core/events/emit.js";import{errorClassFromError as K}from"../core/events/errors.js";import{operationIdContext as m}from"../core/events/operation-id.js";import{situationalContextEnvelope as Z,SITUATIONAL_CONTEXT_CUSTOM_TYPE as _}from"../core/runtime/situational-context.js";import{isProfilePaused as ee}from"../core/profiles/manifest.js";import{brokerIdleTurnStart as te,brokerRunTurnBusy as ie,HELD_DEFERRED_INBOX_PROMPT_JOIN as ne}from"../core/runtime/broker/held-deferred-inbox.js";const b=64,R=16;let p,re=0;class N extends Error{static{l(this,"WatcherFatalError")}constructor(t,e){super(t,{cause:e}),this.name="WatcherFatalError"}}function se(){return{tickMs:B(),debounceMs:q()}}l(se,"resolveCadence");function I(){const s=H();return s===void 0||s.trim()===""?void 0:s}l(I,"currentNodeId");function P(){const s=U();return s!==void 0&&s!==""&&ee(s)}l(P,"profilePaused");function E(s){try{return K(s)}catch{return{class:"unknown"}}}l(E,"safeErrorClass");function v(s){try{Y(s)}catch{}}l(v,"emitBestEffort");function C(s){try{m.fresh(t=>{v({...s,operation_id:t})})}catch{}}l(C,"emitFreshBestEffort");function k(s,t){try{m.run(s,()=>{v({...t,operation_id:s})})}catch{}}l(k,"emitStoredBestEffort");function ae(s){return s.kind==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:s.entries.map(t=>({...t.from===null?{}:{from:t.from},...t.from_name===void 0?{}:{fromName:t.from_name},kind:t.kind,tier:t.tier,...t.ref===void 0?{}:{ref:t.ref}}))}}l(ae,"deliveryOrigin");function x(s,t){if(s.length===0)throw new Error(`cannot create an empty ${t} delivery`);const e=[...new Set(s.map(n=>n.operation_id))].sort(),i=e.length-R;return{channel:t,entryIds:s.map(n=>n.entry_id),throughEntryId:s.at(-1).entry_id,sourceOperationIds:e.slice(0,R),...i>0?{sourceOperationIdsOmitted:i}:{}}}l(x,"deliveryFacts");function y(s){return{channel:s.channel,entry_ids:s.entryIds,through_entry_id:s.throughEntryId,source_operation_ids:s.sourceOperationIds,...s.sourceOperationIdsOmitted===void 0?{}:{source_operation_ids_omitted:s.sourceOperationIdsOmitted}}}l(y,"deliveryFields");function de(s){k(s.operationId,{level:"info",event:"inbox.delivery.completed",outcome:"succeeded",fields:y(s)})}l(de,"emitDeliveryCompleted");function T(s,t,e,i){k(s,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error:i,error_class:E(i),fields:{stage:e,...y(t)}})}l(T,"emitDeliveryFailure");function M(s,t){k(s.operationId,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error_class:{class:"unknown"},fields:{stage:"abandoned",reason:t,...y(s)}})}l(M,"emitDeliveryAbandoned");function oe(s){return typeof s=="string"?s:Array.isArray(s)?s.filter(t=>typeof t=="object"&&t!==null&&typeof t.text=="string").map(t=>t.text).join(`
2
- `):""}l(oe,"messageText");function D(s){return s==="quit"||s==="reload"||s==="new"||s==="resume"||s==="fork"}l(D,"isSessionShutdownReason");function fe(s){switch(s){case"quit":return"shutdown";case"reload":case"new":case"resume":case"fork":return"reload";default:return s}}l(fe,"disposalReasonForShutdown");function le(s){return typeof s=="string"?s.slice(0,128):s===null?"null":s===void 0?"undefined":typeof s=="number"||typeof s=="boolean"||typeof s=="bigint"?String(s).slice(0,128):typeof s}l(le,"boundedRuntimeReason");class he{static{l(this,"CanvasInboxWatcher")}pi;cadence;generation;timer;backstop;debounceTimer;signalUnsubscribers=[];rerun=!1;retryNeeded=!1;armed=!1;lastCtx;streaming=!1;runNode=A();nodeId;claims=new Map;reportBodies=new Map;tickInFlight;buffer=[];lastArrival=0;pendingHandoffs=[];pendingCommit;promptJoinInFlight=!1;replayUnseenInherited=!1;seeded=!1;disposed=!1;disposalReason;fatalError;fatalEscaped=!1;constructor(t,e,i){this.pi=t,this.cadence=e,this.generation=i}start(){const t=l((e,i)=>{this.canMutate()&&this.captureCtx(e,i)},"capture");this.pi.on("session_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.arm())}),this.pi.on("turn_end",t),this.pi.on("agent_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!0)}),this.pi.on("agent_end",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!1)}),this.pi.on("message_end",e=>{if(!this.canMutate())return;const i=e?.message;if(i?.role!=="user"&&i?.role!=="custom"||!this.pendingHandoffs.some(d=>d.awaitingDequeue!==void 0))return;const n=w(oe(i.content)),r=this.pendingHandoffs.find(d=>d.awaitingDequeue===n);r!==void 0&&delete r.awaitingDequeue}),this.pi.on("agent_settled",async(e,i)=>{if(!this.canMutate())return;this.captureCtx(e,i);const n=I();if(n!==void 0)try{this.assertNodeOwnership(n,"settle"),await this.tickInFlight,this.seeded||await this.claimMail(n);const r=await this.settle(n,i,!1,!0);r==="refresh_held"&&this.dispose("refresh",!1),this.runNode&&r==="settled"&&this.canMutate()&&this.buffer.length>0&&this.flushOrdinary(n),this.syncTimers()}catch(r){this.dispose("shutdown",!1,void 0,{error:r,stage:"settle"})}}),this.pi.on("session_shutdown",async e=>{if(!this.canMutate())return;let i;try{i=e?.reason}catch{i=void 0}const n=D(i)?fe(i):"reload";D(i)||C({level:"warn",event:"inbox.lifecycle.unknown_shutdown_reason",outcome:"failed",fields:{reason:le(i)}});try{await this.disposeAtSettlement(n,this.lastCtx)}catch(r){this.dispose(n,!1,void 0,{error:r,stage:"settle"})}})}arm(){if(this.armed)return;this.armed=!0;const t=F();this.signalUnsubscribers.push(t.subscribe("state",()=>this.syncTimers()),t.subscribe("mail",()=>this.runTick("schedule")),t.subscribe("resync",()=>this.runTick("schedule"))),this.syncTimers(),t.state!=="connected"&&this.runTick("schedule")}async disposeAtSettlement(t,e){const i=I();if(i===void 0){this.dispose(t,!1);return}try{this.assertNodeOwnership(i,"settle");const n=await this.settle(i,e,t!=="refresh");this.dispose(n==="refresh_held"?"refresh":t,!1)}catch(n){this.dispose(t,!1,void 0,{error:n,stage:"settle"})}}dispose(t,e,i,n){if(this.disposed)return;this.disposed=!0,this.disposalReason=t,this.clearTimer();for(const d of this.signalUnsubscribers.splice(0))d();const r=n;{const d=[...new Set([...this.pendingCommit?.handoffs??[],...this.pendingHandoffs.splice(0)])];this.buffer.length=0,this.claims.clear(),this.reportBodies.clear(),this.pendingCommit=void 0,this.promptJoinInFlight=!1,this.replayUnseenInherited=!1,this.nodeId=void 0,this.lastCtx=void 0,this.lastArrival=0,this.streaming=!1,this.seeded=!1,this.ownsCurrentGeneration()&&(p=void 0);for(const a of d)M(a,t)}if(r!==void 0){this.scheduleHandlerFatal(r.error,r.stage);return}}ownsCurrentGeneration(){return p===this&&p.generation===this.generation}canMutate(){return this.ownsCurrentGeneration()&&!this.disposed&&this.fatalError===void 0}captureCtx(t,e){e!==void 0&&(this.lastCtx=e)}clearTimer(){this.timer!==void 0&&clearInterval(this.timer),this.backstop!==void 0&&clearInterval(this.backstop),this.debounceTimer!==void 0&&clearTimeout(this.debounceTimer),this.timer=this.backstop=this.debounceTimer=void 0}syncTimers(){if(!this.armed||!this.canMutate())return;const t=F().state==="connected",e=!t||this.buffer.length>0||this.pendingCommit!==void 0||this.retryNeeded;e&&this.timer===void 0?(this.timer=setInterval(()=>this.runTick("schedule"),this.cadence.tickMs),this.timer.unref?.()):!e&&this.timer!==void 0&&(clearInterval(this.timer),this.timer=void 0),t&&this.backstop===void 0?(this.backstop=setInterval(()=>this.runTick("schedule"),J()),this.backstop.unref?.()):!t&&this.backstop!==void 0&&(clearInterval(this.backstop),this.backstop=void 0),this.buffer.length===0&&this.debounceTimer!==void 0&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0)}armDebounce(){this.debounceTimer!==void 0&&clearTimeout(this.debounceTimer);const t=Math.max(0,this.lastArrival+this.cadence.debounceMs-Date.now());this.debounceTimer=setTimeout(()=>{this.debounceTimer=void 0,this.runTick("schedule")},t),this.debounceTimer.unref?.()}isIdle(){if(this.runNode&&ie())return!1;try{if(typeof this.lastCtx?.isIdle=="function")return this.lastCtx.isIdle()===!0}catch{}return!this.streaming}assertNodeOwnership(t,e){!this.seeded||this.nodeId===void 0||this.nodeId===t||this.raiseReadFatal(e,new Error(`watcher node changed from ${this.nodeId} to ${t}`))}raiseFatal(t,e,i,n){throw this.fatalError===void 0&&(this.fatalError=new N(e,i),this.clearTimer(),C({level:"error",event:t,outcome:"failed",error:i,error_class:E(i),fields:n})),this.fatalError}raiseReadFatal(t,e){return this.raiseFatal("inbox.read.failed",`inbox ${t} state is corrupt`,e,{stage:t})}raiseSituationalFatal(t,e){return this.raiseFatal("inbox.situational_context.missing","situational context marker has no readable sidecar",e,{entry_id:t})}escapeFatal(t,e){if(!this.fatalEscaped){if(this.fatalEscaped=!0,e==="throw")throw t;queueMicrotask(()=>{throw t})}}scheduleHandlerFatal(t,e){let i;if(t instanceof N)i=t;else try{this.raiseReadFatal(e,t)}catch(n){i=n}this.escapeFatal(i,"schedule")}runTick(t="throw"){if(!this.canMutate())return;if(this.tickInFlight!==void 0){this.rerun=!0;return}const e=this.tick().then(()=>{this.retryNeeded=!1}).catch(i=>{if(this.canMutate()){if(S(i)){this.retryNeeded=!0,C({level:"warn",event:"inbox.read.failed",outcome:"failed",error:i,error_class:E(i),fields:{stage:"poll"}});return}this.scheduleHandlerFatal(i,"poll")}}).finally(()=>{this.tickInFlight===e&&(this.tickInFlight=void 0),this.syncTimers(),this.rerun&&this.canMutate()&&(this.rerun=!1,this.runTick("schedule"))});this.tickInFlight=e}async claimMail(t){this.assertNodeOwnership(t,"poll");let e;try{e=await X(t,"wake",this.reportBodies)}catch(a){throw S(a)&&(this.replayUnseenInherited=!0),a}if(!this.canMutate()||e.action==="hold")return!1;const i=this.replayUnseenInherited;this.replayUnseenInherited=!1,this.nodeId=t,this.seeded=!0;const n=new Set(e.deliveries.map(a=>a.entry.entry_id)),r=this.buffer.filter(a=>!n.has(a.entry_id));for(const a of r)this.claims.delete(a.entry_id);if(this.buffer.splice(0,this.buffer.length,...this.buffer.filter(a=>n.has(a.entry_id))),r.length>0){const a=globalThis[Symbol.for("@crouton-kit/crtr:watcher-cancel-probe")];typeof a=="function"&&a(r.map(f=>f.entry_id),process.hrtime.bigint())}let d=!1;for(const a of e.deliveries){const f=a.entry.entry_id;this.claims.has(f)||(this.claims.set(f,a),a.handoff==="inherited"&&!i?m.fresh(o=>{this.pendingHandoffs.push({...x([a.entry],"visible"),operationId:o,settleAtAgentSettled:!0})}):(this.buffer.push(a.entry),this.lastArrival=Date.now(),d=!0))}return d&&this.armDebounce(),this.syncTimers(),!0}async tick(){const t=I();if(t!==void 0){if(this.pendingCommit!==void 0){await this.retryPendingCommit(t)==="refresh_held"&&this.canMutate()&&this.dispose("refresh",!1);return}this.promptJoinInFlight||P()||this.pendingHandoffs.length>=b||await this.claimMail(t)&&this.buffer.length>0&&(!this.runNode||this.isIdle()||this.buffer.some(e=>e.tier==="critical"))&&Date.now()-this.lastArrival>=this.cadence.debounceMs&&this.flushOrdinary(t)}}missingChannelEntries(t){const e=t.filter(r=>this.claims.has(r.entry_id)),i=this.coveredEntryIds("hidden"),n=this.coveredEntryIds("visible");return{hiddenEntries:e.filter(r=>(r.data?.situational===!0||r.data?.situationalOnly===!0)&&!i.has(r.entry_id)),visibleEntries:e.filter(r=>r.data?.situationalOnly!==!0&&!n.has(r.entry_id))}}visibleRoute(t){return t.length===0?"none":this.isIdle()?"idle":this.runNode?t.some(e=>e.tier==="critical")?"critical":"none":t.some(e=>e.tier==="critical")?"critical":t.some(e=>e.tier==="urgent"||e.kind==="final")?"steer":"followUp"}buildPlan(t){const{hiddenEntries:e,visibleEntries:i}=this.missingChannelEntries(t),n=new Set(e.map(u=>u.entry_id)),r=new Set(i.map(u=>u.entry_id)),d=t.filter(u=>n.has(u.entry_id)||r.has(u.entry_id)),a=this.isIdle()&&d.length>0&&d.every(u=>u.tier==="deferred"),f=this.visibleRoute(i)==="critical",o=!a&&!f&&e.length>0,c=!a&&!f&&i.length>0;return{hiddenEntries:e,visibleEntries:i,deferredHold:a,sendCount:Number(o)+Number(c)}}ordinaryPlan(){return this.buildPlan(this.buffer)}contextCards(t,e){const i=[];if(e.some(n=>n.data?.situational===!0)){const n=e.at(-1).entry_id;let r;try{r=Z(t)}catch(d){this.raiseSituationalFatal(n,d)}r===null&&this.raiseSituationalFatal(n,new Error(`missing situational context for entry ${n}`)),i.push(r)}for(const n of e)n.data?.situationalOnly===!0&&i.push(...$(n));return i}digest(t,e){try{return W(t)}catch(i){this.raiseReadFatal(e,i)}}sendDelivery(t,e,i,n,r){this.pendingHandoffs.length>=b&&this.raiseReadFatal(n,new Error(`pending handoff capacity exceeded before ${t} send`));let d;try{d=x(e,t)}catch(o){this.raiseReadFatal(n,o)}let a;try{m.fresh(o=>{a=o,v({level:"info",event:"inbox.delivery.started",operation_id:o,fields:y(d)}),i()})}catch(o){return a===void 0&&this.raiseReadFatal(n,o),T(a,d,"send",o),"failed"}a===void 0&&this.raiseReadFatal(n,new Error(`${t} delivery returned without an operation id`));const f={operationId:a,...d,...r===void 0?{}:{awaitingDequeue:r}};return this.canMutate()?(this.pendingHandoffs.push(f),"handed-off"):(this.disposed&&this.disposalReason!==void 0&&M(f,this.disposalReason),"inactive")}sendContext(t,e,i,n,r,d){const a=n==="steer"||n==="followUp"?n:this.isIdle()?void 0:"followUp",f=a===void 0||i.length===0?void 0:w(i.at(-1));return this.sendDelivery("hidden",e,()=>{this.runNode&&r&&this.pi.appendEntry("crtr-turn-input",{message_ids:e.map(o=>o.entry_id)}),i.forEach((o,c)=>{const u=r&&c===i.length-1;this.pi.sendMessage({customType:_,content:o,display:!0,details:{nodeId:t}},a!==void 0?{deliverAs:a}:u?{deliverAs:"followUp",triggerTurn:!0}:{})})},d,f)}sendVisible(t,e,i,n,r,d){return this.sendDelivery("visible",t,()=>{if(r!=="idle"&&r!=="steer"&&r!=="followUp")throw new Error(`visible send requested for non-send route ${r}`);for(const a of e)this.pi.sendMessage({customType:_,content:a,display:!0},r==="idle"?{}:{deliverAs:r});if(V(i,n),r==="idle"){const a=te();if(a===void 0)throw new Error("broker idle-turn admission is unavailable");a(i,this.runNode?t.map(f=>f.entry_id):[])}else this.pi.sendUserMessage(i,{deliverAs:r})},d,r==="steer"||r==="followUp"?w(i):void 0)}abortCritical(){try{this.lastCtx?.abort?.()}catch{}}requeueFromBatch(t,e){if(e.size===0)return;const i=t.filter(d=>e.has(d.entry_id)),n=new Set(i.map(d=>d.entry_id)),r=this.buffer.filter(d=>!n.has(d.entry_id));this.buffer.splice(0,this.buffer.length,...i,...r)}executePlan(t,e,i){const n=new Set,r=this.visibleRoute(e.visibleEntries);if(r==="critical"){if(this.abortCritical(),!this.canMutate())return{inactive:!0,requeueEntryIds:n};for(const o of e.visibleEntries)n.add(o.entry_id);for(const o of e.hiddenEntries)n.add(o.entry_id);return{inactive:!1,requeueEntryIds:n}}if(this.runNode&&r==="none")return{inactive:!1,requeueEntryIds:new Set([...e.hiddenEntries,...e.visibleEntries].map(o=>o.entry_id))};const d=e.visibleEntries.length>0?this.digest(e.visibleEntries,i):[],[a,...f]=d;for(const o of f)for(const c of o.entries)n.add(c.entry_id);if(e.hiddenEntries.length>0){const o=this.contextCards(t,e.hiddenEntries),c=this.sendContext(t,e.hiddenEntries,o,r,a===void 0,i);if(c==="inactive")return{inactive:!0,requeueEntryIds:n};if(c==="failed")for(const u of e.hiddenEntries)n.add(u.entry_id)}if(!this.canMutate())return{inactive:!0,requeueEntryIds:n};if(a!==void 0){const o=this.sendVisible(a.entries,a.cards,a.text,ae(a),r,i);if(o==="inactive")return{inactive:!0,requeueEntryIds:n};if(o==="failed")for(const c of a.entries)n.add(c.entry_id);else a.kind==="human"&&(z(t,a.text),Q(t,a.text))}return{inactive:!1,requeueEntryIds:n}}flushOrdinary(t){if(this.buffer.length===0)return"empty";const e=this.ordinaryPlan();if(e.deferredHold)return"held";if(this.pendingHandoffs.length+e.sendCount>b)return"capacity-blocked";const i=[...this.buffer],n=this.executePlan(t,e,"poll");return n.inactive||(this.buffer.splice(0,i.length),this.requeueFromBatch(i,n.requeueEntryIds)),"attempted"}async prependHeldDeferredInbox(t){if(!this.canMutate()||this.nodeId===void 0||P())return;const e=this.ordinaryPlan();if(!e.deferredHold)return;const i=e.visibleEntries.length===0?[]:this.digest(e.visibleEntries,"poll"),n=+(e.hiddenEntries.length>0)+i.length;if(this.pendingHandoffs.length+n>b)return;const r=[...this.buffer];this.promptJoinInFlight=!0;try{this.runNode&&this.pi.appendEntry("crtr-turn-input",{message_ids:[...e.hiddenEntries,...e.visibleEntries].map(d=>d.entry_id)}),e.hiddenEntries.length>0&&await this.sendPromptJoinDelivery(t,"hidden",e.hiddenEntries,this.contextCards(this.nodeId,e.hiddenEntries));for(const d of i)await this.sendPromptJoinDelivery(t,"visible",d.entries,[...d.cards,d.text]);if(!this.canMutate())return;this.buffer.splice(0,r.length)}finally{this.promptJoinInFlight=!1}}async sendPromptJoinDelivery(t,e,i,n){let r;try{r=x(i,e)}catch(f){this.raiseReadFatal("poll",f)}let d;try{await m.fresh(async f=>{d=f,v({level:"info",event:"inbox.delivery.started",operation_id:f,fields:y(r)});for(const o of n)await t.sendCustomMessage({customType:_,content:o,display:!0})})}catch(f){throw d===void 0&&this.raiseReadFatal("poll",f),T(d,r,"send",f),f}d===void 0&&this.raiseReadFatal("poll",new Error(`${e} prompt-join delivery returned without an operation id`));const a={operationId:d,...r,settleAtAgentSettled:!0};if(!this.canMutate()){this.disposed&&this.disposalReason!==void 0&&M(a,this.disposalReason);return}this.pendingHandoffs.push(a)}coveredEntryIds(t){const e=new Set;for(const i of this.pendingHandoffs)if(i.channel===t)for(const n of i.entryIds)e.add(n);return e}retryPendingCommit(t){const e=this.pendingCommit;if(e===void 0)return Promise.resolve("settled");if(e.attempt!==void 0)return e.attempt;const i=this.attemptPendingCommit(t,e).finally(()=>{e.attempt===i&&(e.attempt=void 0)});return e.attempt=i,i}async attemptPendingCommit(t,e){let i=!1;try{const r=await G(t,e.receipts);if(r.action==="hold")return"refresh_held";for(const d of e.receipts){const a=r.results.find(f=>f.delivery_id===d.delivery_id);if(a?.outcome!==d.disposition&&a?.outcome!=="stale")throw new Error("daemon returned no terminal mail settlement outcome")}i=r.results.every(d=>d.outcome==="acknowledged")}catch(r){if(this.pendingCommit===e)for(const d of e.handoffs)T(d.operationId,d,"receipt_commit",r);return"held"}if(this.pendingCommit!==e)return"settled";for(const r of e.entryIds)this.claims.delete(r);if(e.receipts.some(r=>r.disposition==="released")){const r=new Set(e.entryIds);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(d=>!r.has(d.entry_id)))}this.pendingCommit=void 0;const n=this.detachPending(r=>r.entryIds.every(d=>!this.claims.has(d)));for(const r of n)i&&de(r);return"settled"}async settle(t,e,i,n=!1){if(i)try{if(e?.hasPendingMessages?.()===!0)return"held"}catch{}if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const r=L(),d=!r&&this.pendingHandoffs.some(h=>h.awaitingDequeue!==void 0)&&await this.nodeRefreshing(t);if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const a=new Set(this.buffer.map(h=>h.entry_id)),f=new Set(d?this.pendingHandoffs.filter(h=>h.awaitingDequeue!==void 0).flatMap(h=>[...h.entryIds]):[]),o=this.pendingHandoffs.filter(h=>(n||h.settleAtAgentSettled!==!0)&&h.entryIds.every(g=>!f.has(g))),c=new Set(o.flatMap(h=>[...h.entryIds])),u=[...this.claims.keys()].filter(h=>r||c.has(h)&&!a.has(h));return u.length===0?"settled":(this.pendingCommit={handoffs:o,entryIds:u,receipts:u.map(h=>{const g=this.claims.get(h);return{delivery_id:g.delivery_id,attempts:g.attempts,disposition:r?"released":"acknowledged"}})},this.retryPendingCommit(t))}async nodeRefreshing(t){try{return(await j(t)).node.intent==="refresh"}catch{return!0}}detachPending(t){const e=[];for(let i=this.pendingHandoffs.length-1;i>=0;i-=1){const n=this.pendingHandoffs[i];t(n)&&e.push(...this.pendingHandoffs.splice(i,1))}return e.reverse(),e}}function ue(s,t){p?.dispose("reload",!1);const e=new he(s,t,++re);p=e;const i=l(n=>e.prependHeldDeferredInbox(n),"promptJoin");globalThis[ne]=i;try{e.start()}catch(n){throw e.dispose("reload",!1),n}return e}l(ue,"installWatcher");function ce(s){const t=ue(s,se());return()=>t.dispose("shutdown",!1)}l(ce,"registerCanvasInboxWatcher");var Fe=ce;export{Fe as default,ce as registerCanvasInboxWatcher};
1
+ var H=Object.defineProperty;var l=(s,t)=>H(s,"name",{value:t,configurable:!0});import{envInboxBetweenTurns as U,envNodeId as q,envProfileId as B,envWatcherDebounceMs as J,envWatcherTickMs as W,envWatcherBackstopMs as $}from"../shared/env.js";import{coalesceBrokerInbox as G,entryCards as X}from"../core/runtime/broker/inbox.js";import{acknowledgeBrokerMail as j,claimBrokerMail as z,brokerExtensionState as F}from"../core/runtime/broker/daemon-ops.js";import{materializeSpilledBody as L}from"../core/runtime/broker/spilled-body.js";import{brokerSignalClient as S}from"../core/runtime/broker/signal-stream.js";import{wasTurnRefused as V}from"../core/runtime/broker/extension-abort.js";import{isDaemonTransportApiError as R}from"../api/errors.js";import{announceMessageOrigin as Q,messageSignature as v}from"../core/runtime/stamp/channel.js";import{captureGoalIfAbsent as Y,generateAndCommitInitialName as K}from"./broker-local.js";import{emitEvent as N}from"../core/events/emit.js";import{errorClassFromError as Z}from"../core/events/errors.js";import{operationIdContext as m}from"../core/events/operation-id.js";import{SITUATIONAL_CONTEXT_CUSTOM_TYPE as _}from"../shared/generated-context.js";import{isProfilePaused as ee}from"../core/profiles/manifest.js";import{brokerDisposeAndExit as te,brokerIdleTurnStart as ie,brokerRunTurnBusy as ne,HELD_DEFERRED_INBOX_PROMPT_JOIN as re}from"../core/runtime/broker/held-deferred-inbox.js";const b=64,D=16;let p,se=0;class P extends Error{static{l(this,"WatcherFatalError")}constructor(t,e){super(t,{cause:e}),this.name="WatcherFatalError"}}function ae(){return{tickMs:W(),debounceMs:J()}}l(ae,"resolveCadence");function I(){const s=q();return s===void 0||s.trim()===""?void 0:s}l(I,"currentNodeId");function A(){const s=B();return s!==void 0&&s!==""&&ee(s)}l(A,"profilePaused");function E(s){try{return Z(s)}catch{return{class:"unknown"}}}l(E,"safeErrorClass");function w(s){try{N(s)}catch{}}l(w,"emitBestEffort");function C(s){try{m.fresh(t=>{w({...s,operation_id:t})})}catch{}}l(C,"emitFreshBestEffort");function k(s,t){try{m.run(s,()=>{w({...t,operation_id:s})})}catch{}}l(k,"emitStoredBestEffort");function de(s){return s.kind==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:s.entries.map(t=>({...t.from===null?{}:{from:t.from},...t.from_name===void 0?{}:{fromName:t.from_name},kind:t.kind,tier:t.tier,...t.ref===void 0?{}:{ref:t.ref}}))}}l(de,"deliveryOrigin");function x(s,t){if(s.length===0)throw new Error(`cannot create an empty ${t} delivery`);const e=[...new Set(s.map(r=>r.operation_id))].sort(),i=e.length-D;return{channel:t,entryIds:s.map(r=>r.entry_id),throughEntryId:s.at(-1).entry_id,sourceOperationIds:e.slice(0,D),...i>0?{sourceOperationIdsOmitted:i}:{}}}l(x,"deliveryFacts");function y(s){return{channel:s.channel,entry_ids:s.entryIds,through_entry_id:s.throughEntryId,source_operation_ids:s.sourceOperationIds,...s.sourceOperationIdsOmitted===void 0?{}:{source_operation_ids_omitted:s.sourceOperationIdsOmitted}}}l(y,"deliveryFields");function oe(s){k(s.operationId,{level:"info",event:"inbox.delivery.completed",outcome:"succeeded",fields:y(s)})}l(oe,"emitDeliveryCompleted");function T(s,t,e,i){k(s,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error:i,error_class:E(i),fields:{stage:e,...y(t)}})}l(T,"emitDeliveryFailure");function M(s,t){k(s.operationId,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error_class:{class:"unknown"},fields:{stage:"abandoned",reason:t,...y(s)}})}l(M,"emitDeliveryAbandoned");function fe(s){return typeof s=="string"?s:Array.isArray(s)?s.filter(t=>typeof t=="object"&&t!==null&&typeof t.text=="string").map(t=>t.text).join(`
2
+ `):""}l(fe,"messageText");function O(s){return s==="quit"||s==="reload"||s==="new"||s==="resume"||s==="fork"}l(O,"isSessionShutdownReason");function le(s){switch(s){case"quit":return"shutdown";case"reload":case"new":case"resume":case"fork":return"reload";default:return s}}l(le,"disposalReasonForShutdown");function he(s){return typeof s=="string"?s.slice(0,128):s===null?"null":s===void 0?"undefined":typeof s=="number"||typeof s=="boolean"||typeof s=="bigint"?String(s).slice(0,128):typeof s}l(he,"boundedRuntimeReason");class ue{static{l(this,"CanvasInboxWatcher")}pi;cadence;generation;timer;backstop;debounceTimer;signalUnsubscribers=[];rerun=!1;retryNeeded=!1;armed=!1;lastCtx;streaming=!1;runNode=U();nodeId;claims=new Map;reportBodies=new Map;tickInFlight;buffer=[];lastArrival=0;pendingHandoffs=[];pendingCommit;promptJoinInFlight=!1;replayUnseenInherited=!1;seeded=!1;disposed=!1;disposalReason;fatalError;fatalEscaped=!1;constructor(t,e,i){this.pi=t,this.cadence=e,this.generation=i}start(){const t=l((e,i)=>{this.canMutate()&&this.captureCtx(e,i)},"capture");this.pi.on("session_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.arm())}),this.pi.on("turn_end",t),this.pi.on("agent_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!0)}),this.pi.on("agent_end",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!1)}),this.pi.on("message_end",e=>{if(!this.canMutate())return;const i=e?.message;if(i?.role!=="user"&&i?.role!=="custom"||!this.pendingHandoffs.some(d=>d.awaitingDequeue!==void 0))return;const r=v(fe(i.content)),n=this.pendingHandoffs.find(d=>d.awaitingDequeue===r);n!==void 0&&delete n.awaitingDequeue}),this.pi.on("agent_settled",async(e,i)=>{if(!this.canMutate())return;this.captureCtx(e,i);const r=I();if(r!==void 0)try{this.assertNodeOwnership(r,"settle"),await this.tickInFlight,this.seeded||await this.claimMail(r);const n=await this.settle(r,i,!1,!0);n==="refresh_held"&&this.dispose("refresh",!1),this.runNode&&n==="settled"&&this.canMutate()&&this.buffer.length>0&&await this.flushOrdinary(r),this.syncTimers()}catch(n){this.dispose("shutdown",!1,void 0,{error:n,stage:"settle"})}}),this.pi.on("session_shutdown",async e=>{if(!this.canMutate())return;let i;try{i=e?.reason}catch{i=void 0}const r=O(i)?le(i):"reload";O(i)||C({level:"warn",event:"inbox.lifecycle.unknown_shutdown_reason",outcome:"failed",fields:{reason:he(i)}});try{await this.disposeAtSettlement(r,this.lastCtx)}catch(n){this.dispose(r,!1,void 0,{error:n,stage:"settle"})}})}arm(){if(this.armed)return;this.armed=!0;const t=S();this.signalUnsubscribers.push(t.subscribe("state",()=>this.syncTimers()),t.subscribe("mail",()=>this.runTick("schedule")),t.subscribe("resync",()=>this.runTick("schedule"))),this.syncTimers(),t.state!=="connected"&&this.runTick("schedule")}async disposeAtSettlement(t,e){const i=I();if(i===void 0){this.dispose(t,!1);return}try{this.assertNodeOwnership(i,"settle");const r=await this.settle(i,e,t!=="refresh");this.dispose(r==="refresh_held"?"refresh":t,!1)}catch(r){this.dispose(t,!1,void 0,{error:r,stage:"settle"})}}dispose(t,e,i,r){if(this.disposed)return;this.disposed=!0,this.disposalReason=t,this.clearTimer();for(const d of this.signalUnsubscribers.splice(0))d();const n=r;{const d=[...new Set([...this.pendingCommit?.handoffs??[],...this.pendingHandoffs.splice(0)])];this.buffer.length=0,this.claims.clear(),this.reportBodies.clear(),this.pendingCommit=void 0,this.promptJoinInFlight=!1,this.replayUnseenInherited=!1,this.nodeId=void 0,this.lastCtx=void 0,this.lastArrival=0,this.streaming=!1,this.seeded=!1,this.ownsCurrentGeneration()&&(p=void 0);for(const a of d)M(a,t)}if(n!==void 0){this.scheduleHandlerFatal(n.error,n.stage);return}}ownsCurrentGeneration(){return p===this&&p.generation===this.generation}canMutate(){return this.ownsCurrentGeneration()&&!this.disposed&&this.fatalError===void 0}captureCtx(t,e){e!==void 0&&(this.lastCtx=e)}clearTimer(){this.timer!==void 0&&clearInterval(this.timer),this.backstop!==void 0&&clearInterval(this.backstop),this.debounceTimer!==void 0&&clearTimeout(this.debounceTimer),this.timer=this.backstop=this.debounceTimer=void 0}syncTimers(){if(!this.armed||!this.canMutate())return;const t=S().state==="connected",e=!t||this.buffer.length>0||this.pendingCommit!==void 0||this.retryNeeded;e&&this.timer===void 0?(this.timer=setInterval(()=>this.runTick("schedule"),this.cadence.tickMs),this.timer.unref?.()):!e&&this.timer!==void 0&&(clearInterval(this.timer),this.timer=void 0),t&&this.backstop===void 0?(this.backstop=setInterval(()=>this.runTick("schedule"),$()),this.backstop.unref?.()):!t&&this.backstop!==void 0&&(clearInterval(this.backstop),this.backstop=void 0),this.buffer.length===0&&this.debounceTimer!==void 0&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0)}armDebounce(){this.debounceTimer!==void 0&&clearTimeout(this.debounceTimer);const t=Math.max(0,this.lastArrival+this.cadence.debounceMs-Date.now());this.debounceTimer=setTimeout(()=>{this.debounceTimer=void 0,this.runTick("schedule")},t),this.debounceTimer.unref?.()}isIdle(){if(this.runNode&&ne())return!1;try{if(typeof this.lastCtx?.isIdle=="function")return this.lastCtx.isIdle()===!0}catch{}return!this.streaming}assertNodeOwnership(t,e){!this.seeded||this.nodeId===void 0||this.nodeId===t||this.raiseReadFatal(e,new Error(`watcher node changed from ${this.nodeId} to ${t}`))}raiseFatal(t,e,i,r){throw this.fatalError===void 0&&(this.fatalError=new P(e,i),this.clearTimer(),C({level:"error",event:t,outcome:"failed",error:i,error_class:E(i),fields:r})),this.fatalError}raiseReadFatal(t,e){return this.raiseFatal("inbox.read.failed",`inbox ${t} state is corrupt`,e,{stage:t})}raiseSituationalFatal(t,e){return this.raiseFatal("inbox.situational_context.missing","situational context marker has no readable sidecar",e,{entry_id:t})}escapeFatal(t,e){if(!this.fatalEscaped){if(this.fatalEscaped=!0,e==="throw")throw t;queueMicrotask(()=>{throw t})}}scheduleHandlerFatal(t,e){let i;if(t instanceof P)i=t;else try{this.raiseReadFatal(e,t)}catch(r){i=r}this.escapeFatal(i,"schedule")}runTick(t="throw"){if(!this.canMutate())return;if(this.tickInFlight!==void 0){this.rerun=!0;return}const e=this.tick().then(()=>{this.retryNeeded=!1}).catch(i=>{if(this.canMutate()){if(R(i)){this.retryNeeded=!0,C({level:"warn",event:"inbox.read.failed",outcome:"failed",error:i,error_class:E(i),fields:{stage:"poll"}});return}this.scheduleHandlerFatal(i,"poll")}}).finally(()=>{this.tickInFlight===e&&(this.tickInFlight=void 0),this.syncTimers(),this.rerun&&this.canMutate()&&(this.rerun=!1,this.runTick("schedule"))});this.tickInFlight=e}async claimMail(t){this.assertNodeOwnership(t,"poll");let e;try{e=await z(t,"wake",this.reportBodies)}catch(a){throw R(a)&&(this.replayUnseenInherited=!0),a}if(!this.canMutate()||e.action==="hold")return!1;const i=this.replayUnseenInherited;this.replayUnseenInherited=!1,this.nodeId=t,this.seeded=!0;const r=new Set(e.deliveries.map(a=>a.entry.entry_id)),n=this.buffer.filter(a=>!r.has(a.entry_id));for(const a of n)this.claims.delete(a.entry_id);if(this.buffer.splice(0,this.buffer.length,...this.buffer.filter(a=>r.has(a.entry_id))),n.length>0){const a=globalThis[Symbol.for("@crouton-kit/crtr:watcher-cancel-probe")];typeof a=="function"&&a(n.map(f=>f.entry_id),process.hrtime.bigint())}let d=!1;for(const a of e.deliveries){const f=a.entry.entry_id;this.claims.has(f)||(a.entry=L(a.entry),this.claims.set(f,a),a.handoff==="inherited"&&!i?m.fresh(o=>{this.pendingHandoffs.push({...x([a.entry],"visible"),operationId:o,settleAtAgentSettled:!0})}):(this.buffer.push(a.entry),this.lastArrival=Date.now(),d=!0))}return d&&this.armDebounce(),this.syncTimers(),!0}async tick(){const t=I();if(t!==void 0){if(this.pendingCommit!==void 0){await this.retryPendingCommit(t)==="refresh_held"&&this.canMutate()&&this.dispose("refresh",!1);return}this.promptJoinInFlight||A()||this.pendingHandoffs.length>=b||await this.claimMail(t)&&this.buffer.length>0&&(!this.runNode||this.isIdle()||this.buffer.some(e=>e.tier==="critical"))&&Date.now()-this.lastArrival>=this.cadence.debounceMs&&await this.flushOrdinary(t)}}missingChannelEntries(t){const e=t.filter(n=>this.claims.has(n.entry_id)),i=this.coveredEntryIds("hidden"),r=this.coveredEntryIds("visible");return{hiddenEntries:e.filter(n=>(n.data?.situational===!0||n.data?.situationalOnly===!0)&&!i.has(n.entry_id)),visibleEntries:e.filter(n=>n.data?.situationalOnly!==!0&&!r.has(n.entry_id))}}visibleRoute(t){return t.length===0?"none":this.isIdle()?"idle":this.runNode?t.some(e=>e.tier==="critical")?"critical":"none":t.some(e=>e.tier==="critical")?"critical":t.some(e=>e.tier==="urgent"||e.kind==="final")?"steer":"followUp"}buildPlan(t){const{hiddenEntries:e,visibleEntries:i}=this.missingChannelEntries(t),r=new Set(e.map(u=>u.entry_id)),n=new Set(i.map(u=>u.entry_id)),d=t.filter(u=>r.has(u.entry_id)||n.has(u.entry_id)),a=this.isIdle()&&d.length>0&&d.every(u=>u.tier==="deferred"),f=this.visibleRoute(i)==="critical",o=!a&&!f&&e.length>0,c=!a&&!f&&i.length>0;return{hiddenEntries:e,visibleEntries:i,deferredHold:a,sendCount:Number(o)+Number(c)}}ordinaryPlan(){return this.buildPlan(this.buffer)}async contextCards(t,e){const i=[];if(e.some(r=>r.data?.situational===!0)){const r=e.at(-1).entry_id;let n;try{n=(await F(t)).situational_card}catch(d){this.raiseSituationalFatal(r,d)}n===null&&this.raiseSituationalFatal(r,new Error(`missing situational context for entry ${r}`)),i.push(n)}for(const r of e)r.data?.situationalOnly===!0&&i.push(...X(r));return i}digest(t,e){try{return G(t)}catch(i){this.raiseReadFatal(e,i)}}sendDelivery(t,e,i,r,n){this.pendingHandoffs.length>=b&&this.raiseReadFatal(r,new Error(`pending handoff capacity exceeded before ${t} send`));let d;try{d=x(e,t)}catch(o){this.raiseReadFatal(r,o)}let a;try{m.fresh(o=>{a=o,w({level:"info",event:"inbox.delivery.started",operation_id:o,fields:y(d)}),i()})}catch(o){return a===void 0&&this.raiseReadFatal(r,o),T(a,d,"send",o),"failed"}a===void 0&&this.raiseReadFatal(r,new Error(`${t} delivery returned without an operation id`));const f={operationId:a,...d,...n===void 0?{}:{awaitingDequeue:n}};return this.canMutate()?(this.pendingHandoffs.push(f),"handed-off"):(this.disposed&&this.disposalReason!==void 0&&M(f,this.disposalReason),"inactive")}sendContext(t,e,i,r,n,d){const a=r==="steer"||r==="followUp"?r:this.isIdle()?void 0:"followUp",f=a===void 0||i.length===0?void 0:v(i.at(-1));return this.sendDelivery("hidden",e,()=>{this.runNode&&n&&this.pi.appendEntry("crtr-turn-input",{message_ids:e.map(o=>o.entry_id)}),i.forEach((o,c)=>{const u=n&&c===i.length-1;this.pi.sendMessage({customType:_,content:o,display:!0,details:{nodeId:t}},a!==void 0?{deliverAs:a}:u?{deliverAs:"followUp",triggerTurn:!0}:{})})},d,f)}sendVisible(t,e,i,r,n,d){return this.sendDelivery("visible",t,()=>{if(n!=="idle"&&n!=="steer"&&n!=="followUp")throw new Error(`visible send requested for non-send route ${n}`);for(const a of e)this.pi.sendMessage({customType:_,content:a,display:!0},n==="idle"?{}:{deliverAs:n});if(Q(i,r),n==="idle"){const a=ie();if(a===void 0)throw new Error("broker idle-turn admission is unavailable");a(i,this.runNode?t.map(f=>f.entry_id):[])}else this.pi.sendUserMessage(i,{deliverAs:n})},d,n==="steer"||n==="followUp"?v(i):void 0)}abortCritical(){try{this.lastCtx?.abort?.()}catch{}}requeueFromBatch(t,e){if(e.size===0)return;const i=t.filter(d=>e.has(d.entry_id)),r=new Set(i.map(d=>d.entry_id)),n=this.buffer.filter(d=>!r.has(d.entry_id));this.buffer.splice(0,this.buffer.length,...i,...n)}async executePlan(t,e,i){const r=new Set,n=this.visibleRoute(e.visibleEntries);if(n==="critical"){if(this.abortCritical(),!this.canMutate())return{inactive:!0,requeueEntryIds:r};for(const o of e.visibleEntries)r.add(o.entry_id);for(const o of e.hiddenEntries)r.add(o.entry_id);return{inactive:!1,requeueEntryIds:r}}if(this.runNode&&n==="none")return{inactive:!1,requeueEntryIds:new Set([...e.hiddenEntries,...e.visibleEntries].map(o=>o.entry_id))};const d=e.visibleEntries.length>0?this.digest(e.visibleEntries,i):[],[a,...f]=d;for(const o of f)for(const c of o.entries)r.add(c.entry_id);if(e.hiddenEntries.length>0){const o=await this.contextCards(t,e.hiddenEntries),c=this.sendContext(t,e.hiddenEntries,o,n,a===void 0,i);if(c==="inactive")return{inactive:!0,requeueEntryIds:r};if(c==="failed")for(const u of e.hiddenEntries)r.add(u.entry_id)}if(!this.canMutate())return{inactive:!0,requeueEntryIds:r};if(a!==void 0){const o=this.sendVisible(a.entries,a.cards,a.text,de(a),n,i);if(o==="inactive")return{inactive:!0,requeueEntryIds:r};if(o==="failed")for(const c of a.entries)r.add(c.entry_id);else a.kind==="human"&&(await Y(t,a.text).catch(()=>{}),K(t,a.text))}return{inactive:!1,requeueEntryIds:r}}async flushOrdinary(t){if(this.buffer.length===0)return"empty";const e=this.ordinaryPlan();if(e.deferredHold)return"held";if(this.pendingHandoffs.length+e.sendCount>b)return"capacity-blocked";const i=[...this.buffer],r=await this.executePlan(t,e,"poll");return r.inactive||(this.buffer.splice(0,i.length),this.requeueFromBatch(i,r.requeueEntryIds)),"attempted"}async prependHeldDeferredInbox(t){if(!this.canMutate()||this.nodeId===void 0||A())return;const e=this.ordinaryPlan();if(!e.deferredHold)return;const i=e.visibleEntries.length===0?[]:this.digest(e.visibleEntries,"poll"),r=+(e.hiddenEntries.length>0)+i.length;if(this.pendingHandoffs.length+r>b)return;const n=[...this.buffer];this.promptJoinInFlight=!0;try{this.runNode&&this.pi.appendEntry("crtr-turn-input",{message_ids:[...e.hiddenEntries,...e.visibleEntries].map(d=>d.entry_id)}),e.hiddenEntries.length>0&&await this.sendPromptJoinDelivery(t,"hidden",e.hiddenEntries,await this.contextCards(this.nodeId,e.hiddenEntries));for(const d of i)await this.sendPromptJoinDelivery(t,"visible",d.entries,[...d.cards,d.text]);if(!this.canMutate())return;this.buffer.splice(0,n.length)}finally{this.promptJoinInFlight=!1}}async sendPromptJoinDelivery(t,e,i,r){let n;try{n=x(i,e)}catch(f){this.raiseReadFatal("poll",f)}let d;try{await m.fresh(async f=>{d=f,w({level:"info",event:"inbox.delivery.started",operation_id:f,fields:y(n)});for(const o of r)await t.sendCustomMessage({customType:_,content:o,display:!0})})}catch(f){throw d===void 0&&this.raiseReadFatal("poll",f),T(d,n,"send",f),f}d===void 0&&this.raiseReadFatal("poll",new Error(`${e} prompt-join delivery returned without an operation id`));const a={operationId:d,...n,settleAtAgentSettled:!0};if(!this.canMutate()){this.disposed&&this.disposalReason!==void 0&&M(a,this.disposalReason);return}this.pendingHandoffs.push(a)}coveredEntryIds(t){const e=new Set;for(const i of this.pendingHandoffs)if(i.channel===t)for(const r of i.entryIds)e.add(r);return e}retryPendingCommit(t){const e=this.pendingCommit;if(e===void 0)return Promise.resolve("settled");if(e.attempt!==void 0)return e.attempt;const i=this.attemptPendingCommit(t,e).finally(()=>{e.attempt===i&&(e.attempt=void 0)});return e.attempt=i,i}async attemptPendingCommit(t,e){let i=!1;try{const n=await j(t,e.receipts);if(n.action==="hold")return"refresh_held";for(const d of e.receipts){const a=n.results.find(f=>f.delivery_id===d.delivery_id);if(a?.outcome!==d.disposition&&a?.outcome!=="stale")throw new Error("daemon returned no terminal mail settlement outcome")}i=n.results.every(d=>d.outcome==="acknowledged")}catch(n){if(this.pendingCommit===e)for(const d of e.handoffs)T(d.operationId,d,"receipt_commit",n);return String(n?.message).startsWith("conversation_write_failed")&&(N({level:"error",event:"broker.exited",node_id:t,error:n,fields:{fault:"conversation_write_failed"}}),te()?.("conversation_write_failed",1)),"held"}if(this.pendingCommit!==e)return"settled";for(const n of e.entryIds)this.claims.delete(n);if(e.receipts.some(n=>n.disposition==="released")){const n=new Set(e.entryIds);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(d=>!n.has(d.entry_id)))}this.pendingCommit=void 0;const r=this.detachPending(n=>n.entryIds.every(d=>!this.claims.has(d)));for(const n of r)i&&oe(n);return"settled"}async settle(t,e,i,r=!1){if(i)try{if(e?.hasPendingMessages?.()===!0)return"held"}catch{}if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const n=V(),d=!n&&this.pendingHandoffs.some(h=>h.awaitingDequeue!==void 0)&&await this.nodeRefreshing(t);if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const a=new Set(this.buffer.map(h=>h.entry_id)),f=new Set(d?this.pendingHandoffs.filter(h=>h.awaitingDequeue!==void 0).flatMap(h=>[...h.entryIds]):[]),o=this.pendingHandoffs.filter(h=>(r||h.settleAtAgentSettled!==!0)&&h.entryIds.every(g=>!f.has(g))),c=new Set(o.flatMap(h=>[...h.entryIds])),u=[...this.claims.keys()].filter(h=>n||c.has(h)&&!a.has(h));return u.length===0?"settled":(this.pendingCommit={handoffs:o,entryIds:u,receipts:u.map(h=>{const g=this.claims.get(h);return{delivery_id:g.delivery_id,attempts:g.attempts,disposition:n?"released":"acknowledged"}})},this.retryPendingCommit(t))}async nodeRefreshing(t){try{return(await F(t)).node.intent==="refresh"}catch{return!0}}detachPending(t){const e=[];for(let i=this.pendingHandoffs.length-1;i>=0;i-=1){const r=this.pendingHandoffs[i];t(r)&&e.push(...this.pendingHandoffs.splice(i,1))}return e.reverse(),e}}function ce(s,t){p?.dispose("reload",!1);const e=new ue(s,t,++se);p=e;const i=l(r=>e.prependHeldDeferredInbox(r),"promptJoin");globalThis[re]=i;try{e.start()}catch(r){throw e.dispose("reload",!1),r}return e}l(ce,"installWatcher");function me(s){const t=ce(s,ae());return()=>t.dispose("shutdown",!1)}l(me,"registerCanvasInboxWatcher");var Re=me;export{Re as default,me as registerCanvasInboxWatcher};
@@ -5,6 +5,12 @@ interface SessionEntryLike {
5
5
  reviewId?: string;
6
6
  };
7
7
  }
8
+ interface ReviewBindingLike {
9
+ kind?: 'review' | 'page_feedback';
10
+ review_id: string;
11
+ origin_node_id: string;
12
+ target_file: string;
13
+ }
8
14
  interface SessionStartCtxLike {
9
15
  sessionManager: {
10
16
  /** Required by pi's `ReadonlySessionManager`: the active branch, which is
@@ -38,5 +44,9 @@ interface PiLike {
38
44
  * marker on session_start that separates inherited context from the visible
39
45
  * transcript. Ordinary nodes get nothing.
40
46
  */
41
- export declare function registerCanvasReviewBoundary(pi: PiLike): void;
47
+ export declare function registerCanvasReviewBoundary(pi: PiLike, loadState?: (id: string) => Promise<{
48
+ node: {
49
+ review_binding?: ReviewBindingLike | null;
50
+ };
51
+ }>): void;
42
52
  export default registerCanvasReviewBoundary;
@@ -1,3 +1,3 @@
1
- var h=Object.defineProperty;var d=(e,a)=>h(e,"name",{value:a,configurable:!0});import{envNodeId as f}from"../shared/env.js";import{brokerExtensionState as m}from"../core/runtime/broker/daemon-ops.js";import{isReviewBoundary as w,REVIEW_BOUNDARY_CUSTOM_TYPE as _}from"../core/runtime/session-visibility.js";import{formatCard as b}from"../shared/generated-context.js";function l(e){e.on("session_start",async(a,v)=>{const i=f();if(!i||i.trim()==="")return;let n;try{n=(await m(i)).node}catch{return}if(n.review_binding==null||v.sessionManager.getBranch().some(g=>w(g,n.review_binding?.review_id)))return;const r=n.review_binding,{review_id:t,origin_node_id:o,target_file:s}=r,c=r.kind==="page_feedback"?[`This conversation began from feedback on page ${t}.`,`Page source: ${s}`,`Origin node: ${o}`,"","The person's visible transcript starts here. Everything above this marker is the origin node's work \u2014 inherited context they have not seen."].join(`
2
- `):[`Reviewed file: ${s}`,`Review ID: ${t}`,`Origin node: ${o}`,"","The person's visible transcript starts here. Everything above this marker is inherited context they have not seen."].join(`
3
- `);e.sendMessage({customType:_,content:b("review-boundary",{},c),display:!0,details:{reviewId:t,originNodeId:o,targetFile:s,kind:r.kind??"review"}})})}d(l,"registerCanvasReviewBoundary");var R=l;export{R as default,l as registerCanvasReviewBoundary};
1
+ var h=Object.defineProperty;var d=(e,i)=>h(e,"name",{value:i,configurable:!0});import{envNodeId as f}from"../shared/env.js";import{bootExtensionState as m}from"../core/runtime/broker/boot-state.js";import{isReviewBoundary as w,REVIEW_BOUNDARY_CUSTOM_TYPE as _}from"../core/runtime/session-visibility.js";import{formatCard as b}from"../shared/generated-context.js";function l(e,i=m){e.on("session_start",async(p,v)=>{const r=f();if(!r||r.trim()==="")return;let n;try{n=(await i(r)).node}catch{return}if(n.review_binding==null||v.sessionManager.getBranch().some(g=>w(g,n.review_binding?.review_id)))return;const t=n.review_binding,{review_id:o,origin_node_id:s,target_file:a}=t,c=t.kind==="page_feedback"?[`This conversation began from feedback on page ${o}.`,`Page source: ${a}`,`Origin node: ${s}`,"","The person's visible transcript starts here. Everything above this marker is the origin node's work \u2014 inherited context they have not seen."].join(`
2
+ `):[`Reviewed file: ${a}`,`Review ID: ${o}`,`Origin node: ${s}`,"","The person's visible transcript starts here. Everything above this marker is inherited context they have not seen."].join(`
3
+ `);e.sendMessage({customType:_,content:b("review-boundary",{},c),display:!0,details:{reviewId:o,originNodeId:s,targetFile:a,kind:t.kind??"review"}})})}d(l,"registerCanvasReviewBoundary");var T=l;export{T as default,l as registerCanvasReviewBoundary};
@@ -1 +1 @@
1
- var X=Object.defineProperty;var l=(n,t)=>X(n,"name",{value:t,configurable:!0});import{brokerSignalClient as P}from"../core/runtime/broker/signal-stream.js";import{brokerExecutionId as K}from"../core/runtime/broker/daemon-ops.js";import{envNodeId as Z}from"../shared/env.js";import{stripCdPrefix as ee}from"../shared/strip-cd-prefix.js";import{contextDir as te}from"../core/canvas/paths.js";import{mutateBrokerFault as ne,recordBrokerTelemetry as re,recordBrokerTurn as x,clearBrokerPushedFinal as oe,consumeBrokerPushedFinal as se}from"../core/runtime/broker/daemon-ops.js";import{bindBrokerSession as ae,cachedBrokerNode as j,relaunchBrokerRoot as ie,settleBroker as L}from"../core/runtime/broker/daemon-ops.js";import{emitEvent as F}from"../core/events/emit.js";import{activeBackgroundBashJobs as le}from"../core/bash-jobs.js";import{CONTEXT_NUDGE_CUSTOM_TYPE as ue,formatCard as ce}from"../shared/generated-context.js";import{isReviewBoundary as de}from"../core/runtime/session-visibility.js";import{clearRefusedTurn as fe,isRuntimeTeardownInProgress as he,refuseTurn as me,runRefreshAbort as ge}from"../core/runtime/broker/extension-abort.js";import{announceMessageOrigin as Y}from"../core/runtime/stamp/channel.js";const z=80;function ye(n,t){const i=t??{},s=l(w=>typeof w=="string"?w:"","pick"),h=ee(s(i.command).trim())||s(i.path)||s(i.file_path)||s(i.pattern)||s(i.description)||s(i.prompt),m=(h!==""?`${n}: ${h}`:n).replace(/\s+/g," ").trim();return m.length>z?m.slice(0,z):m}l(ye,"summarizeActivity");function pe(n){for(let t=n.length-1;t>=0;t--)if(n[t]?.role==="assistant")return n[t]}l(pe,"lastAssistantMessage");function we(n){try{const t=n?.sessionManager?.getBranch();if(!Array.isArray(t))return[];const i=new Set;for(const s of t){if(!de(s))continue;const u=s.details?.reviewId;typeof u=="string"&&i.add(u)}return[...i]}catch{return[]}}l(we,"currentReviewBoundaryIds");const G=1e4,A=[13e4,15e4,17e4,185e3,2e5];function _e(n){const t=A[0],i=A[A.length-1];if(n<t)return null;if(n>=i)return i+Math.floor((n-i)/G)*G;let s=t;for(const u of A)n>=u&&(s=u);return s}l(_e,"steerBand");function ke(n,t,i){const s=Math.round(n/1e3),u=n>=185e3;if(i==="orchestrator")return n<15e4?`Context ~${s}k and growing. When you reach a good stopping point, consider updating your roadmap (\`crtr doc edit roadmap\`) and running \`crtr node yield\` to refresh against it \u2014 no rush yet.`:u?`Context ~${s}k \u2014 this is getting long. Stop taking on new work now: bring your roadmap current, hand off anything outstanding, and \`crtr node yield\` immediately to refresh before this context overflows.`:`Context ~${s}k. Update your roadmap (\`crtr doc edit roadmap\`) so a fresh revive can continue, delegate any outstanding work, then \`crtr node yield\` to refresh.`;if(t==="resident"){const h="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. ${h} Otherwise no rush \u2014 wrap up when you reach a good stopping point.`:u?`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. ${h} 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.`:u?`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.`}l(ke,"steerNote");function be(n){const t=Z();if(t===void 0||t.trim()==="")return;let i=0,s=0,u="",h=null,m=null;const w=new Set;let k=!1,C=!1;const D=l(e=>{if(!C){C=!0;try{ge(()=>e?.abort?.())}catch{}}},"abortForRefresh");let T;const Q=P().subscribe("node",()=>{const e=P();k&&e.state==="connected"&&e.latestNode?.intent==="refresh"&&D(T)}),N=l(()=>le(te(t)).length>0,"backgroundJobsRunning"),c=l((e,r)=>{F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:r,fields:{operation:e}})},"emitDaemonOperationFailure"),O=l((e,r)=>{if(e.action==="reprompt"){Y(e.prompt,{type:"runtime",kind:"stop-guard"}),n.sendUserMessage(e.prompt,{deliverAs:"followUp"});return}if(e.action==="shutdown")try{r?.shutdown?.()}catch{}},"enactSettleDirective"),V=3e3;let U=0,I=Promise.resolve(),d=null,q=null,J=-1/0,g=null,R=0;const S=l(()=>{if(d===null||d===q)return;const e=d;q=e,J=Date.now(),I=I.then(()=>re(t,e)).catch(r=>c("telemetry",r))},"queueTelemetry"),B=l((e,r)=>{if(d!==null&&d.tokens_in===i&&d.tokens_out===s&&d.model===u&&d.context_tokens===e&&d.last_activity===r)return;R=Math.max(Date.now(),R+1),d={tokens_in:i,tokens_out:s,model:u,context_tokens:e,last_activity:r,updated_at:new Date(R).toISOString()};const o=2e3-(Date.now()-J);o<=0?S():g===null&&(g=setTimeout(()=>{g=null,S()},o),g.unref?.())},"publishTelemetry"),E=l(()=>(g!==null&&clearTimeout(g),g=null,S(),I),"flushTelemetry");let $=Promise.resolve();const H=l(e=>($=$.catch(()=>{}).then(async()=>{const r=await x(t,{event:"progress"});(r.fault_link==="daemon\u2192node"||e&&r.fault_link==="pi\u2192provider")&&await ne(t,{op:"clear",link:r.fault_link})}),$),"reportProgress"),v=l(()=>{const e=Date.now();e-U<V||(U=e,H(!1).catch(r=>c("turn_progress",r)))},"heartbeat");n.on("session_start",async(e,r)=>{try{const o=r?.sessionManager?.getSessionId?.();if(typeof o!="string"||o==="")return;const y=r?.sessionManager?.getSessionFile?.(),p=typeof y=="string"&&y!==""?y:null,_=typeof e?.reason=="string"?e.reason:null;_==="new"&&(i=0,s=0,w.clear());const a=await ae(t,{piSessionId:o,sessionFile:p,pid:process.pid,reason:_,reviewBoundaryIds:we(r)});if(a.action==="none"&&P().start(t,K()),a.action==="shutdown"){try{r?.shutdown?.()}catch{}return}if(a.action==="relaunch_root"){ie(t).catch(f=>{const b=f instanceof Error?f.message:String(f);r?.ui?.notify?.(`/new refused: ${b}`,"error"),F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:f,fields:{operation:"relaunch_root"}})});return}}catch(o){F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:o,fields:{operation:"session_bound"}})}}),n.on("agent_start",async(e,r)=>{k=!0,T=r;try{if(!(await x(t,{event:"started"})).applied)throw new Error("daemon refused turn open")}catch(o){c("turn_open",o),r?.ui?.notify?.("Turn refused: the broker no longer owns this node.","error"),me(()=>r?.abort?.())}}),n.on("input",async()=>{k||(C=!1),fe();try{await oe(t)}catch(e){throw c("clear_pushed_final",e),e}}),n.on("tool_execution_start",e=>{try{m=ye(String(e?.toolName??""),e?.args),B(h,m),v()}catch{}}),n.on("tool_execution_update",()=>{try{v()}catch{}}),n.on("message_update",()=>{try{v()}catch{}}),n.on("tool_execution_end",async(e,r)=>{try{v(),(await j(t)).intent==="refresh"&&D(r)}catch{}}),n.on("session_shutdown",async(e,r)=>{Q(),k=!1,T=void 0,await E();try{await x(t,{event:"closed",end_reason:"teardown-aborted"})}catch(o){c("turn_close_teardown",o)}if(e?.reason==="quit")try{const o=await L(t,{stopReason:"quit",backgroundJobsRunning:N(),pushedFinal:!1});O(o,r)}catch(o){c("settle_quit",o)}});const W=l(e=>{e?.role!=="assistant"||e.usage==null||(i+=Number(e.usage.input??0)||0,s+=Number(e.usage.output??0)||0,typeof e.model=="string"&&e.model!==""&&(u=e.model))},"accumulate");n.on("turn_end",async(e,r)=>{W(e?.message);let o=null;try{const a=r.getContextUsage()?.tokens;typeof a=="number"&&(o=a)}catch{}o!==null&&(h=o),B(o,m),await E();try{const a=e?.message?.stopReason!=="error"&&e?.message?.stopReason!=="aborted";await H(a)}catch(a){c("turn_end_fault_clear",a)}const y=Array.isArray(e?.message?.content)?e.message.content:[],p=e?.message?.stopReason??"",_=p!=="error"&&p!=="aborted"&&y.some(a=>a?.type==="toolCall");try{const a=o!==null?_e(o):null,f=a!==null&&!w.has(a)?await j(t):null;if(a!==null&&f!==null){w.add(a);const b=ce("context-nudge",{},ke(a,f.lifecycle,f.mode));_?(Y(b,{type:"runtime",kind:"context-nudge"}),n.sendUserMessage(b,{deliverAs:"steer"})):n.sendMessage({customType:ue,content:b,display:!0},{deliverAs:"nextTurn"})}}catch(a){c("turn_boundary",a)}});let M=null;n.on("agent_end",e=>{M=e;try{const r=Array.isArray(e?.messages)?e.messages:[];for(const o of r)W(o)}catch{}}),n.on("agent_settled",async(e,r)=>{k=!1,T=void 0,B(h,m),await E();const o=M;if(M=null,he())return;try{await x(t,{event:"closed",end_reason:"settled"})}catch(a){c("turn_close",a);return}const y=Array.isArray(o?.messages)?o.messages:[],p=pe(y),_=typeof p?.stopReason=="string"?p.stopReason:"";try{const a=o===null?{pushedFinal:!1}:await se(t),f=await L(t,{stopReason:_,backgroundJobsRunning:N(),pushedFinal:a.pushedFinal});O(f,r)}catch(a){c("settle",a)}})}l(be,"registerCanvasStophook");var De=be;export{De as default,be as registerCanvasStophook,ke as steerNote};
1
+ var X=Object.defineProperty;var l=(n,t)=>X(n,"name",{value:t,configurable:!0});import{brokerSignalClient as A}from"../core/runtime/broker/signal-stream.js";import{brokerExecutionId as J}from"../core/runtime/broker/daemon-ops.js";import{envNodeId as K}from"../shared/env.js";import{stripCdPrefix as Z}from"../shared/strip-cd-prefix.js";import{mutateBrokerFault as ee,recordBrokerTelemetry as te,recordBrokerTurn as x,clearBrokerPushedFinal as ne,consumeBrokerPushedFinal as re}from"../core/runtime/broker/daemon-ops.js";import{bindBrokerSession as oe,cachedBrokerNode as j,postBrokerIdle as se,relaunchBrokerRoot as ae,settleBroker as L}from"../core/runtime/broker/daemon-ops.js";import{emitEvent as F}from"../core/events/emit.js";import{CONTEXT_NUDGE_CUSTOM_TYPE as ie,formatCard as le}from"../shared/generated-context.js";import{isReviewBoundary as ue}from"../core/runtime/session-visibility.js";import{clearRefusedTurn as ce,isRuntimeTeardownInProgress as de,refuseTurn as fe,runRefreshAbort as he}from"../core/runtime/broker/extension-abort.js";import{announceMessageOrigin as Y}from"../core/runtime/stamp/channel.js";const z=80;function ye(n,t){const i=t??{},s=l(w=>typeof w=="string"?w:"","pick"),h=Z(s(i.command).trim())||s(i.path)||s(i.file_path)||s(i.pattern)||s(i.description)||s(i.prompt),y=(h!==""?`${n}: ${h}`:n).replace(/\s+/g," ").trim();return y.length>z?y.slice(0,z):y}l(ye,"summarizeActivity");function pe(n){for(let t=n.length-1;t>=0;t--)if(n[t]?.role==="assistant")return n[t]}l(pe,"lastAssistantMessage");function me(n){try{const t=n?.sessionManager?.getBranch();if(!Array.isArray(t))return[];const i=new Set;for(const s of t){if(!ue(s))continue;const u=s.details?.reviewId;typeof u=="string"&&i.add(u)}return[...i]}catch{return[]}}l(me,"currentReviewBoundaryIds");const G=1e4,C=[13e4,15e4,17e4,185e3,2e5];function ge(n){const t=C[0],i=C[C.length-1];if(n<t)return null;if(n>=i)return i+Math.floor((n-i)/G)*G;let s=t;for(const u of C)n>=u&&(s=u);return s}l(ge,"steerBand");function we(n,t,i){const s=Math.round(n/1e3),u=n>=185e3;if(i==="orchestrator")return n<15e4?`Context ~${s}k and growing. When you reach a good stopping point, consider updating your roadmap (\`crtr doc edit roadmap\`) and running \`crtr node yield\` to refresh against it \u2014 no rush yet.`:u?`Context ~${s}k \u2014 this is getting long. Stop taking on new work now: bring your roadmap current, hand off anything outstanding, and \`crtr node yield\` immediately to refresh before this context overflows.`:`Context ~${s}k. Update your roadmap (\`crtr doc edit roadmap\`) so a fresh revive can continue, delegate any outstanding work, then \`crtr node yield\` to refresh.`;if(t==="resident"){const h="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. ${h} Otherwise no rush \u2014 wrap up when you reach a good stopping point.`:u?`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. ${h} 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.`:u?`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.`}l(we,"steerNote");function _e(n){const t=K();if(t===void 0||t.trim()==="")return;let i=0,s=0,u="",h=null,y=null;const w=new Set;let k=!1,I=!1;const N=l(e=>{if(!I){I=!0;try{he(()=>e?.abort?.())}catch{}}},"abortForRefresh");let T;const Q=A().subscribe("node",()=>{const e=A();k&&e.state==="connected"&&e.latestNode?.intent==="refresh"&&N(T)}),c=l((e,r)=>{F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:r,fields:{operation:e}})},"emitDaemonOperationFailure"),D=l((e,r)=>{if(e.action==="reprompt"){Y(e.prompt,{type:"runtime",kind:"stop-guard"}),n.sendUserMessage(e.prompt,{deliverAs:"followUp"});return}if(e.action==="stay_resident"){se(t).then(()=>A().stop(),o=>c("idle",o));return}if(e.action==="shutdown")try{r?.shutdown?.()}catch{}},"enactSettleDirective"),V=3e3;let O=0,S=Promise.resolve(),d=null,U=null,q=-1/0,p=null,B=0;const R=l(()=>{if(d===null||d===U)return;const e=d;U=e,q=Date.now(),S=S.then(()=>te(t,e)).catch(r=>c("telemetry",r))},"queueTelemetry"),E=l((e,r)=>{if(d!==null&&d.tokens_in===i&&d.tokens_out===s&&d.model===u&&d.context_tokens===e&&d.last_activity===r)return;B=Math.max(Date.now(),B+1),d={tokens_in:i,tokens_out:s,model:u,context_tokens:e,last_activity:r,updated_at:new Date(B).toISOString()};const o=2e3-(Date.now()-q);o<=0?R():p===null&&(p=setTimeout(()=>{p=null,R()},o),p.unref?.())},"publishTelemetry"),$=l(()=>(p!==null&&clearTimeout(p),p=null,R(),S),"flushTelemetry");let M=Promise.resolve();const H=l(e=>(M=M.catch(()=>{}).then(async()=>{const r=await x(t,{event:"progress"});(r.fault_link==="daemon\u2192node"||e&&r.fault_link==="pi\u2192provider")&&await ee(t,{op:"clear",link:r.fault_link})}),M),"reportProgress"),v=l(()=>{const e=Date.now();e-O<V||(O=e,H(!1).catch(r=>c("turn_progress",r)))},"heartbeat");n.on("session_start",async(e,r)=>{try{const o=r?.sessionManager?.getSessionId?.();if(typeof o!="string"||o==="")return;const m=r?.sessionManager?.getSessionFile?.(),g=typeof m=="string"&&m!==""?m:null,_=typeof e?.reason=="string"?e.reason:null;_==="new"&&(i=0,s=0,w.clear());const a=await oe(t,{piSessionId:o,sessionFile:g,pid:process.pid,reason:_,reviewBoundaryIds:me(r)});if(a.action==="none"&&A().start(t,J()),a.action==="shutdown"){try{r?.shutdown?.()}catch{}return}if(a.action==="relaunch_root"){ae(t).catch(f=>{const b=f instanceof Error?f.message:String(f);r?.ui?.notify?.(`/new refused: ${b}`,"error"),F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:f,fields:{operation:"relaunch_root"}})});return}}catch(o){F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:o,fields:{operation:"session_bound"}})}}),n.on("agent_start",async(e,r)=>{k=!0,T=r;try{if(!(await x(t,{event:"started"})).applied)throw new Error("daemon refused turn open")}catch(o){c("turn_open",o),r?.ui?.notify?.("Turn refused: the broker no longer owns this node.","error"),fe(()=>r?.abort?.())}}),n.on("input",async()=>{k||(I=!1),ce();try{await ne(t)}catch(e){throw c("clear_pushed_final",e),e}}),n.on("tool_execution_start",e=>{try{y=ye(String(e?.toolName??""),e?.args),E(h,y),v()}catch{}}),n.on("tool_execution_update",()=>{try{v()}catch{}}),n.on("message_update",()=>{try{v()}catch{}}),n.on("tool_execution_end",async(e,r)=>{try{v(),(await j(t)).intent==="refresh"&&N(r)}catch{}}),n.on("session_shutdown",async(e,r)=>{Q(),k=!1,T=void 0,await $();try{await x(t,{event:"closed",end_reason:"teardown-aborted"})}catch(o){c("turn_close_teardown",o)}if(e?.reason==="quit")try{const o=await L(t,{stopReason:"quit",pushedFinal:!1});D(o,r)}catch(o){c("settle_quit",o)}});const W=l(e=>{e?.role!=="assistant"||e.usage==null||(i+=Number(e.usage.input??0)||0,s+=Number(e.usage.output??0)||0,typeof e.model=="string"&&e.model!==""&&(u=e.model))},"accumulate");n.on("turn_end",async(e,r)=>{W(e?.message);let o=null;try{const a=r.getContextUsage()?.tokens;typeof a=="number"&&(o=a)}catch{}o!==null&&(h=o),E(o,y),await $();try{const a=e?.message?.stopReason!=="error"&&e?.message?.stopReason!=="aborted";await H(a)}catch(a){c("turn_end_fault_clear",a)}const m=Array.isArray(e?.message?.content)?e.message.content:[],g=e?.message?.stopReason??"",_=g!=="error"&&g!=="aborted"&&m.some(a=>a?.type==="toolCall");try{const a=o!==null?ge(o):null,f=a!==null&&!w.has(a)?await j(t):null;if(a!==null&&f!==null){w.add(a);const b=le("context-nudge",{},we(a,f.lifecycle,f.mode));_?(Y(b,{type:"runtime",kind:"context-nudge"}),n.sendUserMessage(b,{deliverAs:"steer"})):n.sendMessage({customType:ie,content:b,display:!0},{deliverAs:"nextTurn"})}}catch(a){c("turn_boundary",a)}});let P=null;n.on("agent_end",e=>{P=e;try{const r=Array.isArray(e?.messages)?e.messages:[];for(const o of r)W(o)}catch{}}),n.on("agent_settled",async(e,r)=>{k=!1,T=void 0,E(h,y),await $();const o=P;if(P=null,de())return;try{await x(t,{event:"closed",end_reason:"settled"})}catch(a){c("turn_close",a);return}const m=Array.isArray(o?.messages)?o.messages:[],g=pe(m),_=typeof g?.stopReason=="string"?g.stopReason:"";try{const a=o===null?{pushedFinal:!1}:await re(t),f=await L(t,{stopReason:_,pushedFinal:a.pushedFinal});D(f,r)}catch(a){c("settle",a)}})}l(_e,"registerCanvasStophook");var $e=_e;export{$e as default,_e as registerCanvasStophook,we as steerNote};
@@ -33,8 +33,10 @@ interface ToolDefinitionLike {
33
33
  interface PiLike {
34
34
  on(event: 'before_agent_start', handler: (event: BeforeAgentStartEventLike) => {
35
35
  systemPrompt: string;
36
- } | void): void;
37
- on(event: 'turn_end', handler: () => void): void;
36
+ } | void | Promise<{
37
+ systemPrompt: string;
38
+ } | void>): void;
39
+ on(event: 'turn_end', handler: () => void | Promise<void>): void;
38
40
  registerTool(tool: ToolDefinitionLike): void;
39
41
  getActiveTools(): string[];
40
42
  setActiveTools(toolNames: string[]): void;
@@ -44,6 +46,6 @@ export declare function structuredOutputPromptBlock(request: StructuredOutputReq
44
46
  /** The model-facing text for an accepted submission — the same wording `crtr push result` prints. */
45
47
  export declare function submitResultText(result: SubmitResultDTO): string;
46
48
  /** Build the `submit_result` tool for one node. Exported for the test suite. */
47
- export declare function createSubmitResultTool(nodeId: string, submit?: (req: SubmitResultRequest) => Promise<SubmitResultDTO>): ToolDefinitionLike;
49
+ export declare function createSubmitResultTool(nodeId: string, submit?: (req: SubmitResultRequest) => Promise<SubmitResultDTO>, readPending?: () => Promise<StructuredOutputRequest | null>): ToolDefinitionLike;
48
50
  export declare function registerCanvasStructuredOutput(pi: PiLike): void;
49
51
  export default registerCanvasStructuredOutput;
@@ -1,5 +1,5 @@
1
- var b=Object.defineProperty;var d=(e,t)=>b(e,"name",{value:t,configurable:!0});import{Type as i}from"typebox";import{envNodeId as g}from"../shared/env.js";import{localClient as y}from"../api/node-transport.js";import{ApiError as q}from"../api/index.js";import{readBrokerOutputRequest as h,SUBMIT_RESULT_TOOL as a}from"../core/runtime/structured-output.js";function $(e){const t=JSON.stringify(e.schema,null,2),n=`call the ${`\`${a}\` tool with \`request_id: "${e.request_id}"\``} and the JSON in \`result\``,r=`call \`${a}\` with \`decline: { reason, code }\` instead`;return`<structured-output-request>
2
- ${e.mode==="terminal"?`This node owes a terminal structured result. When the work is complete, submit it: ${n}. 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), ${r} 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: ${n}. That records it and pushes an update report to your subscribers, then you continue working normally. If the schema cannot be honestly satisfied, ${r} of inventing a value. You cannot stop or go dormant until the result is accepted or declined.`}
1
+ var b=Object.defineProperty;var o=(e,t)=>b(e,"name",{value:t,configurable:!0});import{Type as i}from"typebox";import{envNodeId as q}from"../shared/env.js";import{localClient as p}from"../api/node-transport.js";import{ApiError as w}from"../api/index.js";import{SUBMIT_RESULT_TOOL as a}from"../core/runtime/structured-output.js";function O(e){const t=JSON.stringify(e.schema,null,2),r=`call the ${`\`${a}\` tool with \`request_id: "${e.request_id}"\``} and the JSON in \`result\``,n=`call \`${a}\` with \`decline: { reason, code }\` instead`;return`<structured-output-request>
2
+ ${e.mode==="terminal"?`This node owes a terminal structured result. When the work is complete, submit it: ${r}. 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), ${n} 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: ${r}. That records it and pushes an update report to your subscribers, then you continue working normally. If the schema cannot be honestly satisfied, ${n} 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 it and call the tool again.
5
5
 
@@ -8,16 +8,11 @@ Required schema:
8
8
  \`\`\`json
9
9
  ${t}
10
10
  \`\`\`
11
- </structured-output-request>`}d($,"structuredOutputPromptBlock");function w(e){const t=e.declined,s=e.mode==="terminal"?`${t?"Decline recorded":"Result recorded"} \u2014 node finished; its engine shuts down on next stop. Nothing more to do here: STOP your turn immediately. Reply with just "Done." and nothing else.`:`${t?"One-off request declined":"One-off result recorded"} and pushed \u2014 the structured-output gate is cleared; continue working normally.`,n=t===void 0?"":`
11
+ </structured-output-request>`}o(O,"structuredOutputPromptBlock");function $(e){const t=e.declined,s=e.mode==="terminal"?`${t?"Decline recorded":"Result recorded"} \u2014 node finished; its engine shuts down on next stop. Nothing more to do here: STOP your turn immediately. Reply with just "Done." and nothing else.`:`${t?"One-off request declined":"One-off result recorded"} and pushed \u2014 the structured-output gate is cleared; continue working normally.`,r=t===void 0?"":`
12
12
  - code: ${t.code} (${t.retryable?"retryable":"not retryable"})`;return`${s}
13
13
 
14
- - ${t?"declined":"result"}: ${e.result_path}${n}
15
- - report: ${e.report}`}d(w,"submitResultText");function O(e,t){if(typeof t!="string")return t;const s=h(e),n=s.state==="valid"?s.request.schema.type:void 0;if(n!=="object"&&n!=="array")return t;try{return JSON.parse(t)}catch{return t}}d(O,"normalizeResult");function l(e){return{content:[{type:"text",text:e}],details:void 0,isError:!0}}d(l,"errorResult");function T(e,t=s=>y({autostart:!1}).submitResult(e,s)){return{name:a,label:"Submit result",description:"Answer this node's pending structured-output request. Pass the request id from the structured-output instruction and either `result` (the JSON value matching the required schema) or `decline` when the schema cannot be honestly satisfied. The result is validated against the schema; a mismatch is rejected with field errors and nothing is recorded.",promptSnippet:"Submit the JSON result for a pending structured-output request (or decline it)",parameters:i.Object({request_id:i.String({description:"The request id named in the structured-output instruction."}),result:i.Optional(i.Unknown({description:"The JSON value matching the required schema. Omit when declining."})),decline:i.Optional(i.Object({reason:i.String({description:"One sentence on why the schema cannot be honestly satisfied."}),code:i.String({description:"A whitespace-free token naming the decline class, as the requester documented."}),retryable:i.Optional(i.Boolean({description:"Whether a retry could succeed. Default false."}))},{description:"Decline the request instead of submitting a result."}))}),defaultActive:!1,async execute(s,n){const r=typeof n.request_id=="string"?n.request_id.trim():"";if(r==="")return l("request_id is required: pass the request id named in the structured-output instruction.");const c=Object.hasOwn(n,"result")&&n.result!==void 0,o=n.decline;if(c&&o!==void 0)return l("Pass either `result` or `decline`, not both.");if(!c&&o===void 0)return l("Pass `result` (the JSON value matching the required schema), or `decline` when the schema cannot be honestly satisfied.");const f=o!==void 0?{request_id:r,decline:o.reason,code:o.code,retryable:o.retryable===!0}:{request_id:r,value:O(e,n.result)};try{const u=await t(f);return{content:[{type:"text",text:w(u)}],details:u}}catch(u){if(u instanceof q){const m=u.details,p=typeof m?.next=="string"?`
14
+ - report: ${e.report}${r}`}o($,"submitResultText");async function m(e){return(await p({autostart:!1}).brokerStructuredRequest(e)).request}o(m,"readPendingRequest");function T(e,t){if(typeof t!="string")return t;const s=e?.schema.type;if(s!=="object"&&s!=="array")return t;try{return JSON.parse(t)}catch{return t}}o(T,"normalizeResult");function l(e){return{content:[{type:"text",text:e}],details:void 0,isError:!0}}o(l,"errorResult");function S(e,t=r=>p({autostart:!1}).submitResult(e,r),s=()=>m(e)){return{name:a,label:"Submit result",description:"Answer this node's pending structured-output request. Pass the request id from the structured-output instruction and either `result` (the JSON value matching the required schema) or `decline` when the schema cannot be honestly satisfied. The result is validated against the schema; a mismatch is rejected with field errors and nothing is recorded.",promptSnippet:"Submit the JSON result for a pending structured-output request (or decline it)",parameters:i.Object({request_id:i.String({description:"The request id named in the structured-output instruction."}),result:i.Optional(i.Unknown({description:"The JSON value matching the required schema. Omit when declining."})),decline:i.Optional(i.Object({reason:i.String({description:"One sentence on why the schema cannot be honestly satisfied."}),code:i.String({description:"A whitespace-free token naming the decline class, as the requester documented."}),retryable:i.Optional(i.Boolean({description:"Whether a retry could succeed. Default false."}))},{description:"Decline the request instead of submitting a result."}))}),defaultActive:!1,async execute(r,n){const d=typeof n.request_id=="string"?n.request_id.trim():"";if(d==="")return l("request_id is required: pass the request id named in the structured-output instruction.");const h=Object.hasOwn(n,"result")&&n.result!==void 0,c=n.decline;if(h&&c!==void 0)return l("Pass either `result` or `decline`, not both.");if(!h&&c===void 0)return l("Pass `result` (the JSON value matching the required schema), or `decline` when the schema cannot be honestly satisfied.");const y=c!==void 0?{request_id:d,decline:c.reason,code:c.code,retryable:c.retryable===!0}:{request_id:d,value:T(await s(),n.result)};try{const u=await t(y);return{content:[{type:"text",text:$(u)}],details:u}}catch(u){if(u instanceof w){const f=u.details,g=typeof f?.next=="string"?`
16
15
 
17
- ${m.next}`:"";return l(`${u.code}: ${u.message}${p}`)}return l(`The result was not submitted: ${u.message}`)}}}}d(T,"createSubmitResultTool");function S(e){const t=g();if(t===void 0||t.trim()==="")return;e.registerTool(T(t));const s=d(n=>{const r=e.getActiveTools(),c=r.includes(a);n&&!c?e.setActiveTools([...r,a]):!n&&c&&e.setActiveTools(r.filter(o=>o!==a))},"syncTool");e.on("before_agent_start",n=>{const r=h(t);if(s(r.state!=="absent"),r.state==="invalid")return{systemPrompt:`${n.systemPrompt}
16
+ ${f.next}`:"";return l(`${u.code}: ${u.message}${g}`)}return l(`The result was not submitted: ${u.message}`)}}}}o(S,"createSubmitResultTool");function x(e){const t=q();if(t===void 0||t.trim()==="")return;e.registerTool(S(t));const s=o(r=>{const n=e.getActiveTools(),d=n.includes(a);r&&!d?e.setActiveTools([...n,a]):!r&&d&&e.setActiveTools(n.filter(h=>h!==a))},"syncTool");e.on("before_agent_start",async r=>{const n=await m(t);if(s(n!==null),n!==null)return{systemPrompt:`${r.systemPrompt}
18
17
 
19
- <structured-output-request>
20
- This node owes a structured result, but its request file is unreadable to this process (${r.error}). Call the \`${a}\` tool with the request_id and required schema named in the stop-guard message; the server validates it.
21
- </structured-output-request>`};if(r.state==="valid")return{systemPrompt:`${n.systemPrompt}
22
-
23
- ${$(r.request)}`}}),e.on("turn_end",()=>{s(h(t).state!=="absent")})}d(S,"registerCanvasStructuredOutput");var P=S;export{a as SUBMIT_RESULT_TOOL,T as createSubmitResultTool,P as default,S as registerCanvasStructuredOutput,$ as structuredOutputPromptBlock,w as submitResultText};
18
+ ${O(n)}`}}),e.on("turn_end",async()=>{s(await m(t)!==null)})}o(x,"registerCanvasStructuredOutput");var J=x;export{a as SUBMIT_RESULT_TOOL,S as createSubmitResultTool,J as default,x as registerCanvasStructuredOutput,O as structuredOutputPromptBlock,$ as submitResultText};
@@ -2,13 +2,20 @@ declare function injectToolGuide(systemPrompt: string, helpText: string): string
2
2
  interface BeforeAgentStartEventLike {
3
3
  systemPrompt: string;
4
4
  }
5
+ interface SessionStartCtxLike {
6
+ sessionManager: {
7
+ getBranch(): ReadonlyArray<{
8
+ type: string;
9
+ }>;
10
+ };
11
+ }
5
12
  interface PiLike {
6
- on(event: 'session_start', handler: () => void | Promise<void>): void;
13
+ on(event: 'session_start', handler: (event: unknown, ctx: SessionStartCtxLike) => void | Promise<void>): void;
7
14
  on(event: 'before_agent_start', handler: (event: BeforeAgentStartEventLike) => {
8
15
  systemPrompt: string;
9
16
  } | void): void;
10
17
  }
11
18
  /** Register the root crtr tool-guide injection for a canvas node. */
12
- export declare function registerCanvasToolGuide(pi: PiLike): void;
19
+ export declare function registerCanvasToolGuide(pi: PiLike, release?: () => string): void;
13
20
  export { injectToolGuide };
14
21
  export default registerCanvasToolGuide;
@@ -1,9 +1,9 @@
1
- var f=Object.defineProperty;var c=(t,o)=>f(t,"name",{value:o,configurable:!0});import{envNodeId as d,envScopes as l}from"../shared/env.js";import{execFile as m}from"node:child_process";import{createHash as p}from"node:crypto";import{mkdirSync as h,readFileSync as x,writeFileSync as y}from"node:fs";import{homedir as g}from"node:os";import{dirname as $,join as S}from"node:path";import{promisify as _}from"node:util";const w=_(m),s=15e3,O=`
1
+ var p=Object.defineProperty;var i=(e,r)=>p(e,"name",{value:r,configurable:!0});import{envNodeId as h,envScopes as v}from"../shared/env.js";import{crtrVersion as g}from"../shared/crtr-version.js";import{effectiveCommandPlugins as x}from"../core/command-plugins/presence.js";import{emitEvent as y}from"../core/events/emit.js";import{execFile as _}from"node:child_process";import{createHash as $}from"node:crypto";import{mkdirSync as S,readFileSync as O,writeFileSync as j}from"node:fs";import{homedir as N}from"node:os";import{dirname as k,join as w}from"node:path";import{promisify as C}from"node:util";const I=C(_),R=`
2
2
 
3
- Guidelines:`;function T(t){const o=p("sha1").update(`${t}\0${l()?.join(",")??""}`).digest("hex").slice(0,16);return S(g(),".cache","crouter",`crtr-tool-guide-${o}.json`)}c(T,"helpCacheFile");function a(t,o){const r=`<crtr-tool-guide>
4
- ${o}
5
- </crtr-tool-guide>`,n=t.indexOf(O);return n===-1?`${t}
3
+ Guidelines:`;function T(e){const r=process.env.CRTR_PLUGINS_REVISION;return r!==void 0&&r!==""?r:x(e).map(t=>`${t.scope}:${t.name}@${t.version??""}:${t.root}`).sort().join("|")}i(T,"pluginsRevision");function b(e,r){const t=[r,e,v()?.join(",")??"",T(e)].join("\0"),o=$("sha1").update(t).digest("hex").slice(0,16);return w(N(),".cache","crouter",`crtr-tool-guide-${o}.json`)}i(b,"helpCacheFile");function d(e,r){const t=`<crtr-tool-guide>
4
+ ${r}
5
+ </crtr-tool-guide>`,o=e.indexOf(R);return o===-1?`${e}
6
6
 
7
- ${r}`:`${t.slice(0,n)}
7
+ ${t}`:`${e.slice(0,o)}
8
8
 
9
- ${r}${t.slice(n)}`}c(a,"injectToolGuide");function v(t){const o=d();if(o===void 0||o.trim()==="")return;let r="",n=0;async function u(){if(r!==""&&Date.now()-n<s)return;const i=T(process.cwd());try{const e=JSON.parse(x(i,"utf8"));if(typeof e.text=="string"&&e.text!==""&&typeof e.at=="number"&&Date.now()-e.at<s){r=e.text,n=e.at;return}}catch{}try{const{stdout:e}=await w("crtr",["-h"],{timeout:1e4});r=e.trim(),n=Date.now();try{h($(i),{recursive:!0}),y(i,JSON.stringify({text:r,at:n}),"utf8")}catch{}}catch(e){console.error("[canvas-tool-guide] crtr -h capture failed:",e)}}c(u,"refresh"),t.on("session_start",u),t.on("before_agent_start",i=>{if(r!=="")return{systemPrompt:a(i.systemPrompt,r)}})}c(v,"registerCanvasToolGuide");var A=v;export{A as default,a as injectToolGuide,v as registerCanvasToolGuide};
9
+ ${t}${e.slice(o)}`}i(d,"injectToolGuide");function F(e,r=g){const t=h();if(t===void 0||t.trim()==="")return;let o="";function a(c,f,s){y({level:c==="failed"?"warn":"info",event:"broker.startup.tool_guide",duration_ms:performance.now()-f,...c==="failed"?{outcome:"failed"}:{},fields:{source:c,resumed:s}})}i(a,"emitSource");async function l(c,f){const s=performance.now(),m=f.sessionManager.getBranch().some(n=>n.type==="message"),u=b(process.cwd(),r());try{const n=JSON.parse(O(u,"utf8"));if(typeof n.text=="string"&&n.text!==""){o=n.text,a("disk_cache",s,m);return}}catch{}try{const{stdout:n}=await I("crtr",["-h"],{timeout:1e4});o=n.trim();try{S(k(u),{recursive:!0}),j(u,JSON.stringify({text:o}),"utf8")}catch{}a("captured",s,m)}catch(n){console.error("[canvas-tool-guide] crtr -h capture failed:",n),a("failed",s,m)}}i(l,"refresh"),e.on("session_start",l),e.on("before_agent_start",c=>{if(o!=="")return{systemPrompt:d(c.systemPrompt,o)}})}i(F,"registerCanvasToolGuide");var q=F;export{q as default,d as injectToolGuide,F as registerCanvasToolGuide};
@@ -1,10 +1,10 @@
1
- var w=Object.defineProperty;var i=(e,t)=>w(e,"name",{value:t,configurable:!0});import{formatInboxRefInstruction as l}from"./generated-context.js";const $=12,u=1e3,y=1e3;function A(e){return(e===void 0?null:/^([a-z0-9-]+)\/reports\/[^/]+$/.exec(e))?.[1]}i(A,"reportRefNodeId");function j(e){let t=e,r=!1;const o=t.split(`
2
- `);return o.length>$&&(t=o.slice(0,$).join(`
3
- `),r=!0),t.length>u&&(t=t.slice(0,u),r=!0),{text:t.trimEnd(),clipped:r}}i(j,"clipBody");function x(e){const t=typeof e.data?.body=="string"?String(e.data.body).trim():"";return t===""||t===e.label?"":t}i(x,"inlineBody");function v(e){const t=e.data?.push;return typeof t=="object"&&t!==null&&typeof t.event=="string"?t:null}i(v,"pushOf");function f(e){const t=e.owner_handle??e.owner;return t==null?e.name:`${t}/${e.name}`}i(f,"objectRef");function _(e){return e.type==="document"?`[[${f(e)}]]`:e.type==="job"?`job ${e.id} (\`${e.name}\`)`:e.type==="node"?`node ${e.name} (${e.id})${e.machine?` on ${e.machine}`:""}`:`${e.type} ${e.name}`}i(_,"objectText");function I(e,t){return t.actor===null?"the runtime":e.from_name===void 0||e.from_name===t.actor?t.actor:`${e.from_name} (${t.actor})`}i(I,"actorText");function m(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}i(m,"list");function R(e,t){const r=_(t.object),o=I(e,t),n=t.attrs,a=t.object.type==="document"?` Read it with \`crtr canvas read ${f(t.object)}\`.`:"";switch(t.event){case"created":return t.object.type==="node"?`${o} created ${r}${typeof n.kind=="string"?`, kind ${n.kind}`:""}.`:`${o} created ${r}.${a}`;case"read":return`${o} read ${r}.`;case"watched":return`${o} started watching ${r}.`;case"deleted":return`${o} deleted ${r}.`;case"edited":{const s=m(n.authors),c=m(n.rationales),d=typeof n.from_revision=="number"&&typeof n.revision=="number"&&n.revision-n.from_revision>1?`revisions ${n.from_revision+1}\u2013${n.revision}`:typeof n.revision=="number"?`revision ${n.revision}`:"a new revision",g=s.length===0?o:s.join(", "),h=c.length===0?"":` Rationale: ${c.join("; ")}.`,b=n.needs_merge===!0?" Two edits were made from the same revision; read it and edit it to merge them.":"",p=` You get this because you read or wrote it; if it no longer concerns your work, stop with \`crtr canvas unwatch ${f(t.object)}\`.`;return`${g} edited ${r} (${d}).${h}${b}${a}${p}`}case"messaged":return`${o} messaged ${r}.`;case"sent":return`${o} sent a message as ${r}.`;case"configured":return`${o} changed the settings of ${r}${typeof n.changed=="string"?`: ${n.changed}`:""}.`;case"exited":return`${r[0].toUpperCase()}${r.slice(1)} exited with code ${String(n["exit-code"])}. Log: ${String(n["log-path"])}`;case"silent":{const s=typeof n.files=="string"?n.files:"";return`${r[0].toUpperCase()}${r.slice(1)} has been silent for ${String(n["silent-for"])}: its processes used almost no CPU and none of the files they hold open for writing changed. It may be hung. Watched: ${s===""?"the job log only":s}. Inspect those files; stop it with \`crtr node bash kill ${t.object.id}\`; or, if it is meant to sit idle, stop these messages with \`crtr node bash quiet ${t.object.id}\`.`}case"killed":{const s=t.actor===null?"":` by ${o}`,c=typeof n.reason=="string"?` (${n.reason})`:"",d=n.reason==="deadline"?` It was canceled at its deadline; claim it with \`crtr node bash extend ${t.object.id} --for <duration>\` next time.`:"";return`${r[0].toUpperCase()}${r.slice(1)} was killed${s}${c}.${d} Log: ${String(n["log-path"])}`}default:return e.label}}i(R,"renderPush");function C(e,t){if(t!==null&&t.length<y&&e.ref!==void 0)return`${t.trimEnd()}
1
+ var w=Object.defineProperty;var o=(e,t)=>w(e,"name",{value:t,configurable:!0});import{formatInboxRefInstruction as l}from"./generated-context.js";const f=12,$=1e3,y=1e3;function A(e){return(e===void 0?null:/^([a-z0-9-]+)\/reports\/[^/]+$/.exec(e))?.[1]}o(A,"reportRefNodeId");function j(e){let t=e,r=!1;const i=t.split(`
2
+ `);return i.length>f&&(t=i.slice(0,f).join(`
3
+ `),r=!0),t.length>$&&(t=t.slice(0,$),r=!0),{text:t.trimEnd(),clipped:r}}o(j,"clipBody");function x(e){const t=typeof e.data?.body=="string"?String(e.data.body).trim():"";return t===""||t===e.label?"":t}o(x,"inlineBody");function v(e){const t=e.data?.push;return typeof t=="object"&&t!==null&&typeof t.event=="string"?t:null}o(v,"pushOf");function u(e){const t=e.owner_handle??e.owner;return t==null?e.name:`${t}/${e.name}`}o(u,"objectRef");function _(e){return e.type==="document"?`[[${u(e)}]]`:e.type==="job"?`job ${e.id} (\`${e.name}\`)`:e.type==="node"?`node ${e.name} (${e.id})${e.machine?` on ${e.machine}`:""}`:`${e.type} ${e.name}`}o(_,"objectText");function k(e,t){return t.actor===null?"the runtime":e.from_name===void 0||e.from_name===t.actor?t.actor:`${e.from_name} (${t.actor})`}o(k,"actorText");function m(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}o(m,"list");function I(e,t){const r=_(t.object),i=k(e,t),n=t.attrs,a=t.object.type==="document"?` Read it with \`crtr canvas read ${u(t.object)}\`.`:"";switch(t.event){case"created":return t.object.type==="node"?`${i} created ${r}${typeof n.kind=="string"?`, kind ${n.kind}`:""}.`:`${i} created ${r}.${a}`;case"read":return`${i} read ${r}.`;case"watched":return`${i} started watching ${r}.`;case"deleted":return`${i} deleted ${r}.`;case"edited":{const s=m(n.authors),c=m(n.rationales),d=typeof n.from_revision=="number"&&typeof n.revision=="number"&&n.revision-n.from_revision>1?`revisions ${n.from_revision+1}\u2013${n.revision}`:typeof n.revision=="number"?`revision ${n.revision}`:"a new revision",b=s.length===0?i:s.join(", "),g=c.length===0?"":` Rationale: ${c.join("; ")}.`,h=n.needs_merge===!0?" Two edits were made from the same revision; read it and edit it to merge them.":"",p=` You get this because you read or wrote it; if it no longer concerns your work, stop with \`crtr canvas unwatch ${u(t.object)}\`.`;return`${b} edited ${r} (${d}).${g}${h}${a}${p}`}case"messaged":return`${i} messaged ${r}.`;case"sent":return`${i} sent a message as ${r}.`;case"configured":return`${i} changed the settings of ${r}${typeof n.changed=="string"?`: ${n.changed}`:""}.`;case"exited":return`${r[0].toUpperCase()}${r.slice(1)} exited with code ${String(n["exit-code"])}. Output: ${String(n["output-key"])}`;case"silent":{const s=typeof n.files=="string"?n.files:"";return`${r[0].toUpperCase()}${r.slice(1)} has been silent for ${String(n["silent-for"])}: its processes used almost no CPU and none of the files they hold open for writing changed. It may be hung. Watched: ${s===""?"the job log only":s}. Inspect those files; stop it with \`crtr node bash kill ${t.object.id}\`; or, if it is meant to sit idle, stop these messages with \`crtr node bash quiet ${t.object.id}\`.`}case"killed":{const s=t.actor===null?"":` by ${i}`,c=typeof n.reason=="string"?` (${n.reason})`:"",d=n.reason==="deadline"?` It was canceled at its deadline; claim it with \`crtr node bash extend ${t.object.id} --for <duration>\` next time.`:"";return`${r[0].toUpperCase()}${r.slice(1)} was killed${s}${c}.${d} Output: ${String(n["output-key"])}`}default:return e.label}}o(I,"renderPush");function C(e,t){if(t!==null&&t.length<y&&e.ref!==void 0)return`${t.trimEnd()}
4
4
 
5
- ${l(e.ref)}`;const r=x(e);if(r===""){const a=v(e);return a!==null&&e.ref===void 0?R(e,a):e.ref===void 0?e.label:`${e.label}
5
+ ${l(e.ref)}`;const r=x(e);if(r===""){const a=v(e);return a!==null&&e.ref===void 0?I(e,a):e.ref===void 0?e.label:`${e.label}
6
6
 
7
- ${l(e.ref)}`}const{text:o,clipped:n}=j(r);return e.ref!==void 0?`${o}
7
+ ${l(e.ref)}`}const{text:i,clipped:n}=j(r);return e.ref!==void 0?`${i}
8
8
 
9
- ${l(e.ref)}`:n?`${o}
10
- \u2026 (body clipped)`:o}i(C,"renderEntryBody");export{y as INLINE_REPORT_MAX_CHARS,j as clipBody,x as inlineBody,C as renderEntryBody,A as reportRefNodeId};
9
+ ${l(e.ref)}`:n?`${i}
10
+ \u2026 (body clipped)`:i}o(C,"renderEntryBody");export{y as INLINE_REPORT_MAX_CHARS,j as clipBody,x as inlineBody,C as renderEntryBody,A as reportRefNodeId};