@north-light/crouter 0.3.311 → 0.3.313

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 (520) hide show
  1. package/dist/api/client.d.ts +27 -30
  2. package/dist/api/client.js +80 -67
  3. package/dist/api/dto/broker-ops.d.ts +10 -20
  4. package/dist/api/dto/canvas.d.ts +1 -10
  5. package/dist/api/dto/health.d.ts +113 -0
  6. package/dist/api/dto/human-requests.d.ts +14 -3
  7. package/dist/api/dto/human.d.ts +2 -48
  8. package/dist/api/dto/human.js +3 -2
  9. package/dist/api/dto/inbox.d.ts +14 -0
  10. package/dist/api/dto/mail.d.ts +43 -0
  11. package/dist/api/dto/nodes.d.ts +11 -8
  12. package/dist/api/dto/recovery.d.ts +96 -0
  13. package/dist/api/dto/reviews.d.ts +2 -2
  14. package/dist/api/routes.d.ts +9 -6
  15. package/dist/api/routes.js +11 -11
  16. package/dist/build-root.d.ts +4 -0
  17. package/dist/build-root.js +11 -1
  18. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
  19. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
  20. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
  21. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
  22. package/dist/cli.js +10 -1
  23. package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
  24. package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
  25. package/dist/clients/attach/chrome/canvas-panels.js +1 -1
  26. package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
  27. package/dist/clients/attach/chrome/inbox-strip.js +17 -9
  28. package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
  29. package/dist/clients/attach/chrome/ticket-panel.js +77 -46
  30. package/dist/clients/attach/overlays/graph.js +6 -9
  31. package/dist/clients/attach/render/chat-view.d.ts +5 -4
  32. package/dist/clients/attach/render/chat-view.js +22 -13
  33. package/dist/clients/attach/render/page-block.d.ts +11 -7
  34. package/dist/clients/attach/render/page-block.js +64 -55
  35. package/dist/clients/attach/viewer.js +746 -735
  36. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
  37. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
  38. package/dist/clients/inbox/controller.d.ts +42 -14
  39. package/dist/clients/inbox/controller.js +240 -124
  40. package/dist/clients/inbox/dto-adapt.d.ts +28 -0
  41. package/dist/clients/inbox/dto-adapt.js +93 -0
  42. package/dist/clients/inbox/page-adapter.d.ts +5 -4
  43. package/dist/clients/inbox/page-adapter.js +12 -12
  44. package/dist/clients/inbox/resolve.d.ts +10 -5
  45. package/dist/clients/inbox/resolve.js +13 -12
  46. package/dist/clients/inbox/review/review-client.d.ts +0 -1
  47. package/dist/clients/inbox/review/review-client.js +0 -4
  48. package/dist/clients/inbox/review-adapter.d.ts +2 -1
  49. package/dist/clients/inbox/review-adapter.js +3 -5
  50. package/dist/clients/inbox/surface.d.ts +2 -2
  51. package/dist/clients/inbox/surface.js +19 -8
  52. package/dist/clients/inbox/tui.d.ts +3 -3
  53. package/dist/commands/__tests__/human.test.js +31 -15
  54. package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
  55. package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
  56. package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
  57. package/dist/commands/api-client.d.ts +5 -4
  58. package/dist/commands/api-client.js +13 -7
  59. package/dist/commands/canvas-history/shared.js +1 -1
  60. package/dist/commands/canvas-history.js +1 -1
  61. package/dist/commands/canvas-roster.js +1 -1
  62. package/dist/commands/canvas.js +1 -2
  63. package/dist/commands/human/feedback.js +20 -17
  64. package/dist/commands/human/prompts.js +45 -36
  65. package/dist/commands/human/queue.js +73 -123
  66. package/dist/commands/human/review.js +6 -16
  67. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
  68. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
  69. package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
  70. package/dist/commands/node-inspect-artifacts.js +1 -1
  71. package/dist/commands/node-lifecycle-revive.d.ts +2 -2
  72. package/dist/commands/node-lifecycle-revive.js +9 -19
  73. package/dist/commands/pkg/plugin-manage.js +0 -1
  74. package/dist/commands/profile/show.js +4 -12
  75. package/dist/commands/surface-tmux-spread.js +1 -5
  76. package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
  77. package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
  78. package/dist/commands/sys/branch.d.ts +2 -0
  79. package/dist/commands/sys/branch.js +19 -0
  80. package/dist/commands/sys/config.js +106 -33
  81. package/dist/commands/sys/daemon.d.ts +2 -0
  82. package/dist/commands/sys/daemon.js +130 -7
  83. package/dist/commands/sys/doctor.js +5 -15
  84. package/dist/commands/sys/migrate.js +21 -92
  85. package/dist/commands/sys/setup-settings-runner.js +4 -2
  86. package/dist/commands/sys.js +2 -15
  87. package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
  88. package/dist/core/__tests__/boot.test.js +32 -25
  89. package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
  90. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
  91. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
  92. package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
  93. package/dist/core/__tests__/canvas.test.js +18 -47
  94. package/dist/core/__tests__/child-death-wake.test.js +29 -7
  95. package/dist/core/__tests__/cli-help-contract.test.js +2 -0
  96. package/dist/core/__tests__/close.test.js +29 -10
  97. package/dist/core/__tests__/collectible.test.js +2 -1
  98. package/dist/core/__tests__/config-change-delta.test.js +2 -0
  99. package/dist/core/__tests__/context-intro.test.js +17 -5
  100. package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
  101. package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
  102. package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
  103. package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
  104. package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
  105. package/dist/core/__tests__/daemon-boot.test.js +51 -14
  106. package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
  107. package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
  108. package/dist/core/__tests__/focuses.test.js +10 -5
  109. package/dist/core/__tests__/helpers/harness.js +50 -18
  110. package/dist/core/__tests__/history-inbox.test.js +12 -16
  111. package/dist/core/__tests__/human-action-delivery.test.js +48 -28
  112. package/dist/core/__tests__/human-actions.test.js +7 -3
  113. package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
  114. package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
  115. package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
  116. package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
  117. package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
  118. package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
  119. package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
  120. package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
  121. package/dist/core/__tests__/integration/lifecycle-hooks.test.js +312 -1
  122. package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
  123. package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
  124. package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
  125. package/dist/core/__tests__/integration/revive.test.js +67 -21
  126. package/dist/core/__tests__/integration/spawn-root.test.js +62 -19
  127. package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
  128. package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
  129. package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
  130. package/dist/core/__tests__/kickoff.test.js +36 -39
  131. package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
  132. package/dist/core/__tests__/lifecycle.test.js +2 -1
  133. package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
  134. package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
  135. package/dist/core/__tests__/migration.test.js +145 -31
  136. package/dist/core/__tests__/model-pin-durability.test.js +4 -1
  137. package/dist/core/__tests__/model-routes-config.test.js +13 -5
  138. package/dist/core/__tests__/node-outcome.test.js +93 -26
  139. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +4 -3
  140. package/dist/core/__tests__/on-read-dedup-resume.test.js +8 -7
  141. package/dist/core/__tests__/on-read-nested-store.test.js +8 -7
  142. package/dist/core/__tests__/passive-subscription.test.js +50 -157
  143. package/dist/core/__tests__/plugin-kinds.test.js +6 -4
  144. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
  145. package/dist/core/__tests__/plugin-page-components.test.js +6 -4
  146. package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
  147. package/dist/core/__tests__/profile-project-memory-delivery.test.js +35 -32
  148. package/dist/core/__tests__/prune.test.js +11 -5
  149. package/dist/core/__tests__/push-final-guard.test.js +14 -7
  150. package/dist/core/__tests__/relaunch-root.test.js +30 -2
  151. package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
  152. package/dist/core/__tests__/repository-root-identity.test.js +4 -0
  153. package/dist/core/__tests__/review-model-floor.test.js +6 -3
  154. package/dist/core/__tests__/revive-all.test.js +13 -3
  155. package/dist/core/__tests__/revive-capacity.test.js +26 -4
  156. package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
  157. package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
  158. package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
  159. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
  160. package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
  161. package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
  162. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
  163. package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
  164. package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
  165. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +5 -4
  166. package/dist/core/__tests__/stop-guard.test.js +2 -1
  167. package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
  168. package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +19 -5
  169. package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
  170. package/dist/core/bootstrap.js +2 -0
  171. package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
  172. package/dist/core/broker-client/transport-socket.d.ts +1 -0
  173. package/dist/core/broker-client/transport-socket.js +13 -5
  174. package/dist/core/canvas/__tests__/attention.test.js +29 -35
  175. package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
  176. package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
  177. package/dist/core/canvas/attention.d.ts +2 -5
  178. package/dist/core/canvas/attention.js +15 -64
  179. package/dist/core/canvas/boot.d.ts +6 -7
  180. package/dist/core/canvas/boot.js +5 -9
  181. package/dist/core/canvas/canvas.d.ts +13 -109
  182. package/dist/core/canvas/canvas.js +140 -401
  183. package/dist/core/canvas/crons.d.ts +2 -0
  184. package/dist/core/canvas/crons.js +16 -15
  185. package/dist/core/canvas/daemon-owner.js +10 -0
  186. package/dist/core/canvas/db.d.ts +2 -2
  187. package/dist/core/canvas/db.js +2 -18
  188. package/dist/core/canvas/deliveries.d.ts +104 -0
  189. package/dist/core/canvas/deliveries.js +354 -0
  190. package/dist/core/canvas/executions.d.ts +29 -0
  191. package/dist/core/canvas/executions.js +68 -0
  192. package/dist/core/canvas/history.js +35 -35
  193. package/dist/core/canvas/index.d.ts +3 -1
  194. package/dist/core/canvas/index.js +3 -1
  195. package/dist/core/canvas/migrations.js +20 -12
  196. package/dist/core/canvas/nav-model.js +1 -3
  197. package/dist/core/canvas/nav-render.d.ts +4 -4
  198. package/dist/core/canvas/nav-render.js +11 -21
  199. package/dist/core/canvas/node-sql-migration.d.ts +3 -0
  200. package/dist/core/canvas/node-sql-migration.js +261 -0
  201. package/dist/core/canvas/paths.d.ts +2 -16
  202. package/dist/core/canvas/paths.js +2 -31
  203. package/dist/core/canvas/recovery.d.ts +76 -0
  204. package/dist/core/canvas/recovery.js +588 -0
  205. package/dist/core/canvas/remote-canvas-source.js +4 -0
  206. package/dist/core/canvas/render-source.d.ts +16 -27
  207. package/dist/core/canvas/render-source.js +16 -45
  208. package/dist/core/canvas/sessions.d.ts +33 -0
  209. package/dist/core/canvas/sessions.js +78 -0
  210. package/dist/core/canvas/types.d.ts +33 -33
  211. package/dist/core/canvas/types.js +2 -5
  212. package/dist/core/canvas/waits.d.ts +18 -0
  213. package/dist/core/canvas/waits.js +70 -0
  214. package/dist/core/canvas/worktrees.d.ts +40 -0
  215. package/dist/core/canvas/worktrees.js +93 -0
  216. package/dist/core/command-hooks/artifact.d.ts +6 -0
  217. package/dist/core/command-hooks/artifact.js +22 -6
  218. package/dist/core/command-hooks/discovery.d.ts +2 -0
  219. package/dist/core/command-hooks/discovery.js +2 -0
  220. package/dist/core/command-hooks/lifecycle-catalog.d.ts +20 -2
  221. package/dist/core/command-hooks/lifecycle-catalog.js +7 -2
  222. package/dist/core/command-hooks/lifecycle-create.d.ts +4 -0
  223. package/dist/core/command-hooks/lifecycle-create.js +51 -0
  224. package/dist/core/command-hooks/schema.d.ts +2 -2
  225. package/dist/core/command-hooks/schema.js +5 -4
  226. package/dist/core/command-hooks/transport/exec-invoke.js +3 -1
  227. package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +18 -8
  228. package/dist/core/command-hooks/transport/exec-lifecycle.js +89 -30
  229. package/dist/core/config.d.ts +17 -12
  230. package/dist/core/config.js +106 -155
  231. package/dist/core/errors.d.ts +1 -0
  232. package/dist/core/errors.js +4 -0
  233. package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
  234. package/dist/core/feed/feed.d.ts +0 -6
  235. package/dist/core/feed/feed.js +68 -56
  236. package/dist/core/feed/inbox.d.ts +7 -81
  237. package/dist/core/feed/inbox.js +46 -378
  238. package/dist/core/feed/messages.d.ts +58 -0
  239. package/dist/core/feed/messages.js +217 -0
  240. package/dist/core/fs-utils.d.ts +4 -0
  241. package/dist/core/fs-utils.js +21 -1
  242. package/dist/core/human/answer.d.ts +1 -1
  243. package/dist/core/human/answer.js +1 -1
  244. package/dist/core/human/claim.d.ts +1 -1
  245. package/dist/core/human/claim.js +2 -4
  246. package/dist/core/human/component-docs.js +1 -1
  247. package/dist/core/human/feedback-companion.js +4 -3
  248. package/dist/core/human/feedback.d.ts +5 -8
  249. package/dist/core/human/feedback.js +57 -85
  250. package/dist/core/human/page-authoring.d.ts +30 -0
  251. package/dist/core/human/page-authoring.js +19 -0
  252. package/dist/core/human/requests.d.ts +136 -0
  253. package/dist/core/human/requests.js +515 -0
  254. package/dist/core/human/root.d.ts +0 -7
  255. package/dist/core/human/root.js +0 -17
  256. package/dist/core/human/scan.d.ts +2 -7
  257. package/dist/core/human/scan.js +48 -132
  258. package/dist/core/human/summary.d.ts +1 -1
  259. package/dist/core/human/summary.js +1 -1
  260. package/dist/core/human/tickets.d.ts +23 -83
  261. package/dist/core/human/tickets.js +92 -243
  262. package/dist/core/human/types.d.ts +5 -1
  263. package/dist/core/installed-plugins.js +8 -3
  264. package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
  265. package/dist/core/locked-file.d.ts +6 -3
  266. package/dist/core/locked-file.js +36 -9
  267. package/dist/core/memory/extensions.js +2 -0
  268. package/dist/core/preview-registry.js +0 -1
  269. package/dist/core/profiles/__tests__/env-store.test.js +2 -0
  270. package/dist/core/profiles/default-binding.d.ts +0 -4
  271. package/dist/core/profiles/default-binding.js +12 -58
  272. package/dist/core/profiles/env-store.js +8 -3
  273. package/dist/core/profiles/manifest.d.ts +2 -37
  274. package/dist/core/profiles/manifest.js +35 -161
  275. package/dist/core/profiles/select.js +3 -0
  276. package/dist/core/review/__tests__/capture-origin.test.js +13 -2
  277. package/dist/core/review/__tests__/comments.test.js +28 -10
  278. package/dist/core/review/__tests__/remap.test.js +28 -10
  279. package/dist/core/review/__tests__/stage-identity.test.js +17 -7
  280. package/dist/core/review/birth.d.ts +1 -1
  281. package/dist/core/review/birth.js +34 -5
  282. package/dist/core/review/comments.js +1 -1
  283. package/dist/core/review/companion.d.ts +1 -1
  284. package/dist/core/review/companion.js +2 -2
  285. package/dist/core/review/document.js +1 -1
  286. package/dist/core/review/project.d.ts +5 -1
  287. package/dist/core/review/project.js +14 -36
  288. package/dist/core/review/realize.d.ts +3 -6
  289. package/dist/core/review/realize.js +51 -168
  290. package/dist/core/review/remap.js +1 -1
  291. package/dist/core/review/stage.d.ts +3 -2
  292. package/dist/core/review/stage.js +2 -3
  293. package/dist/core/review/store.d.ts +3 -21
  294. package/dist/core/review/store.js +140 -186
  295. package/dist/core/review/types.d.ts +0 -1
  296. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
  297. package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
  298. package/dist/core/runtime/broker/auth-reload.js +9 -10
  299. package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
  300. package/dist/core/runtime/broker/daemon-ops.js +42 -9
  301. package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
  302. package/dist/core/runtime/broker/extension-abort.js +11 -0
  303. package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
  304. package/dist/core/runtime/broker/fault-retry.js +142 -95
  305. package/dist/core/runtime/broker/inbox.d.ts +4 -32
  306. package/dist/core/runtime/broker/inbox.js +4 -92
  307. package/dist/core/runtime/broker/rebind.d.ts +1 -0
  308. package/dist/core/runtime/broker/rebind.js +21 -12
  309. package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
  310. package/dist/core/runtime/broker-persona-guidance.js +2 -13
  311. package/dist/core/runtime/broker.js +28 -22
  312. package/dist/core/runtime/close.d.ts +3 -9
  313. package/dist/core/runtime/close.js +16 -27
  314. package/dist/core/runtime/fault.d.ts +3 -93
  315. package/dist/core/runtime/fault.js +9 -419
  316. package/dist/core/runtime/kickoff.d.ts +3 -6
  317. package/dist/core/runtime/kickoff.js +12 -18
  318. package/dist/core/runtime/launch.js +1 -1
  319. package/dist/core/runtime/lifecycle.js +40 -7
  320. package/dist/core/runtime/nodes.d.ts +5 -1
  321. package/dist/core/runtime/nodes.js +26 -11
  322. package/dist/core/runtime/placement.js +2 -2
  323. package/dist/core/runtime/recycle.js +24 -14
  324. package/dist/core/runtime/reset.js +26 -7
  325. package/dist/core/runtime/revive.js +226 -217
  326. package/dist/core/runtime/spawn.d.ts +4 -1
  327. package/dist/core/runtime/spawn.js +43 -5
  328. package/dist/core/runtime/warm-pool.d.ts +2 -2
  329. package/dist/core/runtime/warm-pool.js +23 -3
  330. package/dist/core/scoped-state/db.d.ts +7 -0
  331. package/dist/core/scoped-state/db.js +92 -0
  332. package/dist/core/scoped-state/migrate.d.ts +11 -0
  333. package/dist/core/scoped-state/migrate.js +198 -0
  334. package/dist/core/scoped-state/paths.d.ts +9 -0
  335. package/dist/core/scoped-state/paths.js +27 -0
  336. package/dist/core/scoped-state/profiles.d.ts +12 -0
  337. package/dist/core/scoped-state/profiles.js +62 -0
  338. package/dist/core/scoped-state/providers.d.ts +16 -0
  339. package/dist/core/scoped-state/providers.js +8 -0
  340. package/dist/core/scoped-state/schema.d.ts +3 -0
  341. package/dist/core/scoped-state/schema.js +26 -0
  342. package/dist/core/scoped-state/settings.d.ts +28 -0
  343. package/dist/core/scoped-state/settings.js +82 -0
  344. package/dist/core/subscription-state.d.ts +29 -48
  345. package/dist/core/subscription-state.js +176 -712
  346. package/dist/core/worktree-close.js +4 -4
  347. package/dist/core/worktree-mutation-async.js +2 -2
  348. package/dist/core/worktree-sweep.js +11 -16
  349. package/dist/core/worktree.js +6 -12
  350. package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
  351. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
  352. package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
  353. package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
  354. package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
  355. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +41 -17
  356. package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
  357. package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
  358. package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
  359. package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
  360. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
  361. package/dist/daemon/api/__tests__/model-config.test.js +8 -8
  362. package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
  363. package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
  364. package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
  365. package/dist/daemon/api/__tests__/profile-launch-gates.test.js +6 -3
  366. package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
  367. package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
  368. package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
  369. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
  370. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
  371. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +29 -43
  372. package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
  373. package/dist/daemon/api/bridge.js +1 -1
  374. package/dist/daemon/api/handlers/bash-jobs.js +6 -7
  375. package/dist/daemon/api/handlers/broker-ops.js +47 -84
  376. package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
  377. package/dist/daemon/api/handlers/broker-recovery.js +251 -0
  378. package/dist/daemon/api/handlers/canvas.js +2 -44
  379. package/dist/daemon/api/handlers/daemon.js +41 -0
  380. package/dist/daemon/api/handlers/feedback-comments.js +2 -2
  381. package/dist/daemon/api/handlers/health.js +10 -5
  382. package/dist/daemon/api/handlers/human-requests.js +168 -188
  383. package/dist/daemon/api/handlers/human.js +3 -148
  384. package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
  385. package/dist/daemon/api/handlers/inbox-page.js +89 -0
  386. package/dist/daemon/api/handlers/inbox.js +21 -120
  387. package/dist/daemon/api/handlers/messages.d.ts +1 -0
  388. package/dist/daemon/api/handlers/messages.js +73 -15
  389. package/dist/daemon/api/handlers/node-outcomes.js +58 -13
  390. package/dist/daemon/api/handlers/nodes.d.ts +1 -0
  391. package/dist/daemon/api/handlers/nodes.js +41 -42
  392. package/dist/daemon/api/handlers/reviews.js +4 -29
  393. package/dist/daemon/api/map.d.ts +25 -3
  394. package/dist/daemon/api/map.js +84 -14
  395. package/dist/daemon/api/server.js +68 -9
  396. package/dist/daemon/control.d.ts +18 -0
  397. package/dist/daemon/cron/disposition.d.ts +2 -0
  398. package/dist/daemon/cron/disposition.js +8 -5
  399. package/dist/daemon/cron/settle.js +37 -13
  400. package/dist/daemon/cron/sinks.d.ts +18 -1
  401. package/dist/daemon/cron/sinks.js +47 -93
  402. package/dist/daemon/crtrd-cli.js +4 -19
  403. package/dist/daemon/crtrd.d.ts +2 -0
  404. package/dist/daemon/crtrd.js +206 -81
  405. package/dist/daemon/fleet.js +5 -6
  406. package/dist/daemon/human/finish.d.ts +12 -24
  407. package/dist/daemon/human/finish.js +88 -285
  408. package/dist/daemon/human/settle.d.ts +40 -0
  409. package/dist/daemon/human/settle.js +89 -0
  410. package/dist/daemon/human/sweep.d.ts +20 -5
  411. package/dist/daemon/human/sweep.js +56 -60
  412. package/dist/daemon/manage.d.ts +21 -16
  413. package/dist/daemon/manage.js +85 -51
  414. package/dist/daemon/messaging/node-message.d.ts +1 -1
  415. package/dist/daemon/messaging/node-message.js +9 -12
  416. package/dist/daemon/park-activity.js +3 -3
  417. package/dist/daemon/reconcilers/bash-deadline.js +6 -7
  418. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  419. package/dist/daemon/reconcilers/broker-supervision.js +41 -19
  420. package/dist/daemon/reconcilers/controller-death.js +6 -18
  421. package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
  422. package/dist/daemon/reconcilers/delivery-lane.js +130 -0
  423. package/dist/daemon/reconcilers/live-obligation.js +3 -3
  424. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  425. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
  426. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
  427. package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
  428. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
  429. package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
  430. package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
  431. package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
  432. package/dist/daemon/review/companion.js +5 -11
  433. package/dist/daemon/review/deliver.d.ts +1 -5
  434. package/dist/daemon/review/deliver.js +3 -52
  435. package/dist/daemon/review/finish.d.ts +2 -27
  436. package/dist/daemon/review/finish.js +79 -263
  437. package/dist/daemon/review/sweep.d.ts +3 -10
  438. package/dist/daemon/review/sweep.js +13 -131
  439. package/dist/daemon/startup-policy.d.ts +0 -5
  440. package/dist/daemon/startup-policy.js +0 -5
  441. package/dist/hook-authoring.d.ts +28 -2
  442. package/dist/hook-authoring.js +53 -1
  443. package/dist/index.d.ts +3 -2
  444. package/dist/index.js +1 -1
  445. package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
  446. package/dist/migrations/__tests__/activation.test.js +9 -6
  447. package/dist/migrations/activation.d.ts +3 -2
  448. package/dist/migrations/activation.js +2 -4
  449. package/dist/migrations/corpus.d.ts +2 -5
  450. package/dist/migrations/corpus.js +9 -20
  451. package/dist/migrations/runner.d.ts +3 -1
  452. package/dist/migrations/runner.js +6 -2
  453. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
  454. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
  455. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
  456. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
  457. package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
  458. package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
  459. package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
  460. package/dist/pi-extensions/canvas-passive-context.js +85 -37
  461. package/dist/pi-extensions/canvas-stophook.js +47 -31
  462. package/dist/shared/env.d.ts +1 -0
  463. package/dist/shared/env.js +3 -0
  464. package/package.json +1 -1
  465. package/runtime.lock.json +5 -5
  466. package/dist/clients/attach/__tests__/page-block.test.js +0 -54
  467. package/dist/clients/inbox/review-visibility.d.ts +0 -5
  468. package/dist/clients/inbox/review-visibility.js +0 -19
  469. package/dist/commands/canvas-rebuild-index.d.ts +0 -2
  470. package/dist/commands/canvas-rebuild-index.js +0 -46
  471. package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
  472. package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
  473. package/dist/core/__tests__/human-deliver.test.js +0 -256
  474. package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
  475. package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
  476. package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
  477. package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
  478. package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
  479. package/dist/core/__tests__/phase4-review-store.test.js +0 -144
  480. package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
  481. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
  482. package/dist/core/canvas/human-deliveries.d.ts +0 -39
  483. package/dist/core/canvas/human-deliveries.js +0 -75
  484. package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
  485. package/dist/core/canvas/node-outcome-deliveries.js +0 -159
  486. package/dist/core/feed/passive.d.ts +0 -3
  487. package/dist/core/feed/passive.js +0 -53
  488. package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
  489. package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
  490. package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
  491. package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
  492. package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
  493. package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
  494. package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
  495. package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
  496. package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
  497. package/dist/core/human/__tests__/page-tickets.test.js +0 -161
  498. package/dist/core/review/ticket-filter.d.ts +0 -17
  499. package/dist/core/review/ticket-filter.js +0 -21
  500. package/dist/core/runtime/broker/passive.d.ts +0 -17
  501. package/dist/core/runtime/broker/passive.js +0 -44
  502. package/dist/core/runtime/busy.d.ts +0 -46
  503. package/dist/core/runtime/busy.js +0 -150
  504. package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
  505. package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
  506. package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
  507. package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
  508. package/dist/daemon/human/deliver-action.d.ts +0 -3
  509. package/dist/daemon/human/deliver-action.js +0 -9
  510. package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
  511. package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
  512. package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
  513. package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
  514. package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
  515. package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
  516. package/dist/daemon/startup-block-marker.d.ts +0 -25
  517. package/dist/daemon/startup-block-marker.js +0 -99
  518. /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
  519. /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
  520. /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
@@ -24,15 +24,14 @@ import { envNodeId } from '../shared/env.js';
24
24
  import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';
25
25
  import { join } from 'node:path';
26
26
  import { contextDir, jobDir } from '../core/canvas/paths.js';
27
- import { markBusy, clearBusy, touchBusy } from '../core/runtime/busy.js';
28
- import { clearFault } from '../core/runtime/fault.js';
27
+ import { mutateBrokerFault, recordBrokerTurn } from '../core/runtime/broker/daemon-ops.js';
29
28
  import { clearStopSignals, consumeStopSignals } from '../core/runtime/stop-signals.js';
30
29
  import { bindBrokerSession, brokerExtensionState, relaunchBrokerRoot, settleBroker } from '../core/runtime/broker/daemon-ops.js';
31
30
  import { emitEvent } from '../core/events/emit.js';
32
31
  import { activeBackgroundBashJobs } from '../core/bash-jobs.js';
33
32
  import { CONTEXT_NUDGE_CUSTOM_TYPE, formatCard } from '../shared/generated-context.js';
34
33
  import { isReviewBoundary } from '../core/runtime/session-visibility.js';
35
- import { runRefreshAbort } from '../core/runtime/broker/extension-abort.js';
34
+ import { clearRefusedTurn, refuseTurn, runRefreshAbort } from '../core/runtime/broker/extension-abort.js';
36
35
  import { announceMessageOrigin } from '../core/runtime/stamp/channel.js';
37
36
  /** Condense a tool call into one short line for the activity cue. Picks the most
38
37
  * identifying arg (command / path / pattern / description), collapses whitespace,
@@ -283,15 +282,7 @@ export function registerCanvasStophook(pi) {
283
282
  catch { /* Pi shutdown is local best-effort */ }
284
283
  }
285
284
  };
286
- // Wedge-heartbeat throttle: message_update/tool_execution_update can fire many
287
- // times per second while streaming, and touchBusy is a disk write — rate-limit
288
- // it to at most once per HEARTBEAT_THROTTLE_MS. The daemon's wedge grace is
289
- // measured in minutes, so this throttle costs it nothing. Also clears any
290
- // stale `daemon→node` wedge fault at the same throttled cadence: a sign of
291
- // life should both refresh the heartbeat marker AND clear a stale wedge
292
- // notice as one coherent act, same as every coarser progress site below
293
- // (tool execution, turn_end, agent_settled) already does. clearFault is
294
- // a cheap no-op when no fault exists, so this stays safe to call every time.
285
+ // Streaming updates are rate-limited because daemon wedge grace is measured in minutes.
295
286
  const HEARTBEAT_THROTTLE_MS = 3_000;
296
287
  let lastHeartbeatAt = 0;
297
288
  const heartbeat = () => {
@@ -299,8 +290,10 @@ export function registerCanvasStophook(pi) {
299
290
  if (now - lastHeartbeatAt < HEARTBEAT_THROTTLE_MS)
300
291
  return;
301
292
  lastHeartbeatAt = now;
302
- touchBusy(nodeId);
303
- clearFault(nodeId, { link: 'daemon→node' });
293
+ void Promise.all([
294
+ recordBrokerTurn(nodeId, { event: 'progress' }),
295
+ mutateBrokerFault(nodeId, { op: 'clear', link: 'daemon→node' }),
296
+ ]).catch((error) => emitDaemonOperationFailure('turn_progress', error));
304
297
  };
305
298
  // session_start — capture pi's session id, and detect `/new`.
306
299
  //
@@ -385,13 +378,19 @@ export function registerCanvasStophook(pi) {
385
378
  // agent_start — pi entered a turn. Mark the node mid-turn (busy) so a
386
379
  // focus-away while it is genuinely working backstages it (Invariant F2)
387
380
  // rather than reaping it. Cleared only after the whole run settles.
388
- pi.on('agent_start', () => {
389
- // A fresh turn started. Keep any active fault marker in place so the daemon's
390
- // retry accounting survives a failed retry cycle; just mark the turn busy.
381
+ pi.on('agent_start', async (_event, ctx) => {
382
+ // A turn may not enter Pi until crtrd has fenced and recorded it. Otherwise
383
+ // a broker that lost daemon ownership can run work with no durable turn.
391
384
  try {
392
- markBusy(nodeId);
385
+ const result = await recordBrokerTurn(nodeId, { event: 'started' });
386
+ if (!result.applied)
387
+ throw new Error('daemon refused turn open');
388
+ }
389
+ catch (error) {
390
+ emitDaemonOperationFailure('turn_open', error);
391
+ ctx?.ui?.notify?.('Turn refused: the broker no longer owns this node.', 'error');
392
+ refuseTurn(() => ctx?.abort?.());
393
393
  }
394
- catch { /* best-effort */ }
395
394
  });
396
395
  // input — a new user-directed run is beginning. This is the ONLY place stop
397
396
  // signals are cleared: `agent_start` re-fires for pi's automatic retries and
@@ -403,6 +402,7 @@ export function registerCanvasStophook(pi) {
403
402
  // of this same broker is discarded here, when the next prompt arrives (the pid
404
403
  // stamp only rules out a PRIOR broker's markers, not this broker's own).
405
404
  pi.on('input', () => {
405
+ clearRefusedTurn();
406
406
  try {
407
407
  clearStopSignals(nodeId);
408
408
  }
@@ -415,8 +415,7 @@ export function registerCanvasStophook(pi) {
415
415
  try {
416
416
  lastActivity = summarizeActivity(String(event?.toolName ?? ''), event?.args);
417
417
  flushTelemetry(jobDirPath, totalIn, totalOut, model, lastContext, lastActivity);
418
- touchBusy(nodeId); // wedge heartbeat: a fresh tool starting is a sign of life
419
- clearFault(nodeId, { link: 'daemon→node' }); // a tool actually starting clears any prior wedge notice
418
+ heartbeat(); // a fresh tool starting is a sign of life
420
419
  }
421
420
  catch { /* best-effort */ }
422
421
  });
@@ -458,8 +457,7 @@ export function registerCanvasStophook(pi) {
458
457
  // refreshes on its first tool — the desired outcome.)
459
458
  pi.on('tool_execution_end', async (_event, ctx) => {
460
459
  try {
461
- touchBusy(nodeId); // wedge heartbeat: the tool returning is a sign of life
462
- clearFault(nodeId, { link: 'daemon→node' }); // a tool that was "stuck" just returned — the wedge notice was resolved
460
+ heartbeat(); // a tool that returned is a sign of life
463
461
  if ((await brokerExtensionState(nodeId)).node.intent === 'refresh') {
464
462
  // Stop this turn immediately so the large context does not keep running.
465
463
  // The broker clears Pi's queued steering/follow-up messages inside this
@@ -479,7 +477,12 @@ export function registerCanvasStophook(pi) {
479
477
  // finish transition, focus teardown, presence clear, and fault clear. Other
480
478
  // session swaps keep the same node and need no durable settlement.
481
479
  pi.on('session_shutdown', async (event, ctx) => {
482
- clearBusy(nodeId); // turn marker is meaningless once Pi is exiting
480
+ try {
481
+ await recordBrokerTurn(nodeId, { event: 'closed', end_reason: 'teardown-aborted' });
482
+ }
483
+ catch (error) {
484
+ emitDaemonOperationFailure('turn_close_teardown', error);
485
+ }
483
486
  if (event?.reason !== 'quit')
484
487
  return;
485
488
  try {
@@ -526,9 +529,16 @@ export function registerCanvasStophook(pi) {
526
529
  lastContext = contextTokens;
527
530
  // Fire-and-forget: flushTelemetry uses synchronous fs writes and never throws.
528
531
  flushTelemetry(jobDirPath, totalIn, totalOut, model, contextTokens, lastActivity);
529
- touchBusy(nodeId); // wedge heartbeat: a turn ending is a sign of life
530
- clearFault(nodeId, { link: 'daemon→node' }); // reaching turn_end proves this turn wasn't wedged
531
- clearFault(nodeId, { link: 'pi→provider' }); // a completed provider round-trip proves this episode is over
532
+ heartbeat(); // reaching turn_end proves this turn was not wedged
533
+ try {
534
+ await Promise.all([
535
+ mutateBrokerFault(nodeId, { op: 'clear', link: 'daemon→node' }),
536
+ mutateBrokerFault(nodeId, { op: 'clear', link: 'pi→provider' }),
537
+ ]);
538
+ }
539
+ catch (error) {
540
+ emitDaemonOperationFailure('turn_end_fault_clear', error);
541
+ }
532
542
  // Will the agent run CONTINUE past this turn? Deterministic at turn_end:
533
543
  // the loop keeps going exactly when this assistant message carried tool
534
544
  // calls and the run wasn't aborted/errored (those end unconditionally,
@@ -598,10 +608,16 @@ export function registerCanvasStophook(pi) {
598
608
  pi.on('agent_settled', async (_event, ctx) => {
599
609
  const event = stagedAgentEnd;
600
610
  stagedAgentEnd = null;
601
- // Busy is a broker-local job marker. The daemon operation below owns the
602
- // fault marker, stop policy, lifecycle transition, focus, and inbox cursor
603
- // decision even when Pi had no stageable final agent_end payload.
604
- clearBusy(nodeId);
611
+ // crtrd owns the durable turn close, fault marker, stop policy, lifecycle
612
+ // transition, focus, and mail decision even when Pi had no stageable final
613
+ // agent_end payload.
614
+ try {
615
+ await recordBrokerTurn(nodeId, { event: 'closed', end_reason: 'settled' });
616
+ }
617
+ catch (error) {
618
+ emitDaemonOperationFailure('turn_close', error);
619
+ return;
620
+ }
605
621
  const messages = Array.isArray(event?.messages) ? event.messages : [];
606
622
  const last = lastAssistantMessage(messages);
607
623
  const stopReason = typeof last?.stopReason === 'string' ? last.stopReason : '';
@@ -1,5 +1,6 @@
1
1
  /** The current node's id (`CRTR_NODE_ID`), or undefined outside a node. */
2
2
  export declare function envNodeId(): string | undefined;
3
+ export declare function envExecutionId(): string | undefined;
3
4
  /** The current node's target profile id (`CRTR_PROFILE_ID`), or undefined. */
4
5
  export declare function envProfileId(): string | undefined;
5
6
  /** The current node's working directory (`CRTR_NODE_CWD`), or undefined. */
@@ -26,6 +26,9 @@
26
26
  export function envNodeId() {
27
27
  return process.env['CRTR_NODE_ID'];
28
28
  }
29
+ export function envExecutionId() {
30
+ return process.env['CRTR_EXECUTION_ID'];
31
+ }
29
32
  /** The current node's target profile id (`CRTR_PROFILE_ID`), or undefined. */
30
33
  export function envProfileId() {
31
34
  return process.env['CRTR_PROFILE_ID'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.311",
3
+ "version": "0.3.313",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.311",
3
+ "version": "0.3.313",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/crouter",
9
- "version": "0.3.311",
9
+ "version": "0.3.313",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "workspaces": [
@@ -5206,17 +5206,17 @@
5206
5206
  },
5207
5207
  "packages/crouter-api": {
5208
5208
  "name": "@north-light/crouter-api",
5209
- "version": "0.3.311",
5209
+ "version": "0.3.313",
5210
5210
  "license": "UNLICENSED"
5211
5211
  },
5212
5212
  "packages/crouter-env-docker": {
5213
5213
  "name": "@north-light/crouter-env-docker",
5214
- "version": "0.3.311",
5214
+ "version": "0.3.313",
5215
5215
  "license": "UNLICENSED"
5216
5216
  },
5217
5217
  "packages/crouter-sdk": {
5218
5218
  "name": "@north-light/crouter-sdk",
5219
- "version": "0.3.311",
5219
+ "version": "0.3.313",
5220
5220
  "license": "UNLICENSED",
5221
5221
  "dependencies": {
5222
5222
  "@north-light/crouter-api": "^0.3.295"
@@ -1,54 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import { mkdtempSync, utimesSync, writeFileSync } from 'node:fs';
3
- import { tmpdir } from 'node:os';
4
- import { join } from 'node:path';
5
- import test from 'node:test';
6
- import { atomicWriteJson, pageManifestPath, pagePath } from '../../../core/human/convention.js';
7
- import { derivePageManifestFromDocument } from '../../../core/human/page.js';
8
- import { sanitize } from '../../inbox/tui/ansi.js';
9
- import { PageBlockComponent } from '../render/page-block.js';
10
- function proposal(intro) {
11
- return `const DOCS = ['Local stack', 'Guest home', 'Data and dependencies', 'Troubleshooting'];
12
- function Proposal({ docs }) {
13
- return (
14
- <Card>
15
- <p>Move the <code>{docs.length}</code> operational areas behind focused pointers.</p>
16
- <ul>{docs.map((doc) => <li key={doc}><strong>{doc}</strong> reference</li>)}</ul>
17
- </Card>
18
- );
19
- }
20
- export default function DevMemorySplit() {
21
- return (
22
- <Page title="Northlight dev memory" subtitle="Choose the documentation shape">
23
- <p>${intro}</p>
24
- <Proposal docs={DOCS} />
25
- <UserQuestion id="decision" label="Approve the split?" body="The current file is 4,189 words." mode="single" options={[{ id: 'approve', label: 'Approve' }, { id: 'keep', label: 'Keep one file' }]} />
26
- </Page>
27
- );
28
- }
29
- `;
30
- }
31
- test('an inline page renders dynamic display JSX beside its manifest question and refreshes source-only revisions', () => {
32
- const dir = mkdtempSync(join(tmpdir(), 'crtr-page-block-'));
33
- const source = proposal('The current guide mixes routing and operational detail.');
34
- const manifest = derivePageManifestFromDocument(source);
35
- writeFileSync(pagePath(dir), source);
36
- atomicWriteJson(pageManifestPath(dir), manifest);
37
- const block = new PageBlockComponent('dev-memory', dir, () => 'open it');
38
- const rendered = sanitize(block.render(88).join('\n'));
39
- assert.match(rendered, /The current guide mixes routing and operational detail\./);
40
- assert.match(rendered, /Move the 4 operational areas behind focused pointers\./);
41
- assert.match(rendered, /Local stack.*reference/);
42
- assert.match(rendered, /Troubleshooting.*reference/);
43
- assert.match(rendered, /Approve the split\?/);
44
- assert.match(rendered, /The current file is 4,189 words\./);
45
- assert.match(rendered, /Keep one file/);
46
- const revised = proposal('The replacement keeps the intent router short.');
47
- writeFileSync(pagePath(dir), revised);
48
- const future = new Date(Date.now() + 2_000);
49
- utimesSync(pagePath(dir), future, future);
50
- assert.equal(block.refresh(), true);
51
- const refreshed = sanitize(block.render(88).join('\n'));
52
- assert.match(refreshed, /The replacement keeps the intent router short\./);
53
- assert.doesNotMatch(refreshed, /mixes routing and operational detail/);
54
- });
@@ -1,5 +0,0 @@
1
- import type { TicketSummary } from '../../core/human/types.js';
2
- /** Match the daemon's opaque inbox id: canonical tickets root, NUL, bridge id. */
3
- export declare function opaqueTicketId(canonicalTicketsRoot: string, bridgeNodeId: string): string;
4
- /** Retain local page rows and only daemon-visible review rows. */
5
- export declare function filterVisibleReviewTickets(tickets: readonly TicketSummary[], visibleIds: ReadonlySet<string>): TicketSummary[];
@@ -1,19 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
- import { realpathSync } from 'node:fs';
3
- import { basename } from 'node:path';
4
- import { ticketsRoot } from '../../core/human/root.js';
5
- /** Match the daemon's opaque inbox id: canonical tickets root, NUL, bridge id. */
6
- export function opaqueTicketId(canonicalTicketsRoot, bridgeNodeId) {
7
- return createHash('sha256').update(`${canonicalTicketsRoot}\0${bridgeNodeId}`, 'utf8').digest('hex');
8
- }
9
- /** Retain local page rows and only daemon-visible review rows. */
10
- export function filterVisibleReviewTickets(tickets, visibleIds) {
11
- let canonicalTicketsRoot;
12
- try {
13
- canonicalTicketsRoot = realpathSync(ticketsRoot());
14
- }
15
- catch {
16
- return tickets.filter((ticket) => ticket.kind !== 'review');
17
- }
18
- return tickets.filter((ticket) => ticket.kind !== 'review' || visibleIds.has(opaqueTicketId(canonicalTicketsRoot, basename(ticket.dir))));
19
- }
@@ -1,2 +0,0 @@
1
- import type { LeafDef } from '../core/command.js';
2
- export declare const canvasRebuildIndexLeaf: LeafDef;
@@ -1,46 +0,0 @@
1
- // `crtr canvas rebuild-index` — re-derive the node-table index from on-disk metas.
2
- //
3
- // canvas.db's node rows are a derived index over `nodes/<id>/meta.json`. When the
4
- // db is absent or stale relative to the metas — most concretely a remote/guest
5
- // deployment's recreate-from-template, where node data lives on a durable Volume
6
- // but canvas.db lives on local disk that the recreate wipes — this verb rebuilds
7
- // the rows (identity columns) from the surviving metas via `rebuildIndex()`, so a
8
- // subsequent `node lifecycle revive` finds its node again.
9
- //
10
- // Fails loud if metas are present but the rebuild yields zero rows: a silent
11
- // empty db there means the revive would no-op against nothing.
12
- //
13
- // Exported as a leaf; `crtr canvas` (canvas.ts) mounts it.
14
- import { defineLeaf } from '../core/command.js';
15
- import { cliClient, rethrowAsCliError } from './api-client.js';
16
- export const canvasRebuildIndexLeaf = defineLeaf({
17
- name: 'rebuild-index',
18
- description: 're-derive node rows in canvas.db from on-disk nodes/<id>/meta.json',
19
- whenToUse: 'canvas.db is missing or stale relative to the on-disk node metas and you need its node rows re-derived — most concretely after a remote/guest deployment\'s recreate-from-template, where node data survives on a durable Volume but canvas.db (local disk) was wiped, so a `node lifecycle revive` would otherwise find no row. Identity columns are rebuilt from each meta; runtime columns (status/intent/pi_pid/window/tmux) take their quiescent defaults, and subscribes_to edges are left intact',
20
- help: {
21
- name: 'canvas rebuild-index',
22
- summary: 're-derive canvas.db node rows from on-disk metas; fails loud if metas exist but yield no rows',
23
- params: [],
24
- output: [
25
- { name: 'metas', type: 'integer', required: true, constraint: 'How many `nodes/<id>/meta.json` files were found on disk.' },
26
- { name: 'rows', type: 'integer', required: true, constraint: 'How many node rows exist in canvas.db after the rebuild.' },
27
- ],
28
- outputKind: 'object',
29
- effects: [
30
- 'Upserts a node row for every on-disk meta (identity columns only); runtime columns take schema defaults on freshly created rows.',
31
- 'Leaves subscribes_to edges intact; re-derives spawned_by provenance edges from each meta.',
32
- 'Throws (non-zero exit) if metas are present but the rebuild produced zero rows.',
33
- ],
34
- },
35
- run: async () => {
36
- // The rebuild + the fail-loud “metas exist but 0 rows” guard run server-side
37
- // (crtrd owns canvas.db and the on-disk metas under the same CRTR_HOME).
38
- try {
39
- const res = await cliClient().rebuildIndex();
40
- return { metas: res.metas, rows: res.rows };
41
- }
42
- catch (err) {
43
- rethrowAsCliError(err);
44
- }
45
- },
46
- });
@@ -1,110 +0,0 @@
1
- // Run with: node --import tsx/esm --test src/core/__tests__/human-cancel-guard.test.ts
2
- //
3
- // N2 — humanCancel on a ticket the store has already settled must short-circuit to
4
- // {canceled:false, reason:'already_resolved'} rather than throwing. A second cancel
5
- // is the ordinary race (the human submits while the agent retracts), so the client
6
- // guard in queue.ts turns the daemon's 409 into an idempotent no-op.
7
- import { test, before, after, beforeEach, afterEach } from 'node:test';
8
- import assert from 'node:assert/strict';
9
- import { mkdtempSync, mkdirSync, rmSync, existsSync } from 'node:fs';
10
- import { tmpdir } from 'node:os';
11
- import { join } from 'node:path';
12
- import { createNode } from '../canvas/canvas.js';
13
- import { closeDb } from '../canvas/db.js';
14
- import { nodeDir } from '../canvas/paths.js';
15
- import { atomicWriteJson, bindTicketReplyRoute, pageManifestPath } from '../human/convention.js';
16
- import { cancelTicket, readTicketResult } from '../human/tickets.js';
17
- import { humanCancel } from '../../commands/human/queue.js';
18
- import { createApiServer } from '../../daemon/api/server.js';
19
- import { apiSocketPath } from '../canvas/paths.js';
20
- // `humanCancel` is a thin CLI forwarder since the crtrd-API re-plumb: its
21
- // already-canceled short-circuit guard runs client-side after fetching the node
22
- // through `cliClient().getNode`. Stand up a real in-process `createApiServer()`
23
- // bound to the isolated CRTR_HOME's socket so that fetch resolves against the
24
- // genuine daemon seam (never an autostarted subprocess, never a mock client).
25
- let server;
26
- async function waitForSocket(path) {
27
- for (let i = 0; i < 200; i++) {
28
- if (existsSync(path))
29
- return;
30
- await new Promise((r) => setTimeout(r, 25));
31
- }
32
- throw new Error(`api socket never bound at ${path}`);
33
- }
34
- let home;
35
- function node(id) {
36
- return {
37
- node_id: id,
38
- name: id,
39
- created: new Date().toISOString(),
40
- cwd: '/tmp/work',
41
- kind: 'human',
42
- mode: 'base',
43
- lifecycle: 'terminal',
44
- status: 'active',
45
- };
46
- }
47
- /** Publish a reply-bearing page ticket in the bridge node's directory, exactly as
48
- * `human send` does: reply route first, then the page manifest. */
49
- function publishTicket(id, slots = []) {
50
- const dir = nodeDir(id);
51
- mkdirSync(dir, { recursive: true });
52
- bindTicketReplyRoute(dir, id);
53
- atomicWriteJson(pageManifestPath(dir), {
54
- schema: 'crtr.page/v2',
55
- dialect: 'jsx',
56
- title: id,
57
- subtitle: 'Acknowledge this ticket so the request can proceed.',
58
- delivery: { placement: 'inline', inbox: true, reply: true },
59
- document: 'page.tsx',
60
- steps: 1,
61
- slots,
62
- });
63
- }
64
- before(() => {
65
- home = mkdtempSync(join(tmpdir(), 'crtr-humancancel-'));
66
- process.env['CRTR_HOME'] = home;
67
- });
68
- beforeEach(async () => {
69
- closeDb();
70
- rmSync(home, { recursive: true, force: true });
71
- mkdirSync(home, { recursive: true });
72
- server = createApiServer();
73
- await waitForSocket(apiSocketPath());
74
- });
75
- afterEach(async () => {
76
- await server?.close();
77
- });
78
- after(() => {
79
- closeDb();
80
- rmSync(home, { recursive: true, force: true });
81
- delete process.env['CRTR_HOME'];
82
- });
83
- test('cancel accepts newer page config and treats an already-canceled ticket as a no-op', async () => {
84
- const newerId = 'newerPage';
85
- createNode(node(newerId));
86
- publishTicket(newerId, [{
87
- id: 'decision',
88
- kind: 'options',
89
- step: 0,
90
- config: {
91
- label: 'Decision',
92
- body: 'Choose one.',
93
- options: [{ id: 'yes', label: 'Yes' }],
94
- mode: 'single',
95
- futureField: true,
96
- },
97
- }]);
98
- const canceled = (await humanCancel.run({ ticket_id: newerId }));
99
- assert.equal(canceled['canceled'], true);
100
- assert.equal(canceled['ticket_id'], newerId);
101
- assert.equal(readTicketResult(nodeDir(newerId))?.kind, 'canceled');
102
- const settledId = 'canceledJob';
103
- createNode(node(settledId));
104
- publishTicket(settledId);
105
- cancelTicket(nodeDir(settledId), { actor: 'human' });
106
- const settled = (await humanCancel.run({ ticket_id: settledId }));
107
- assert.equal(settled['canceled'], false);
108
- assert.equal(settled['reason'], 'already_resolved');
109
- assert.equal(settled['ticket_id'], settledId);
110
- });
@@ -1 +0,0 @@
1
- export {};