@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
@@ -1,8 +1,11 @@
1
1
  import { defineBranch, defineLeaf } from '../../core/command.js';
2
- import { readConfig, updateConfig, persistModelLadders, configPath as coreConfigPath } from '../../core/config.js';
2
+ import { InvalidRawSettingsError, readConfig, readRawSettingsForTarget, replaceRawSettingsForTarget, updateConfig, persistModelLadders, configPath as coreConfigPath } from '../../core/config.js';
3
3
  import { usage, notFound } from '../../core/errors.js';
4
- import { scopeRoot, requireScopeRoot, listScopes } from '../../core/scope.js';
4
+ import { requireScopeRoot } from '../../core/scope.js';
5
5
  import { resolveScope } from './shared.js';
6
+ import { resolveProfileOperand } from '../../core/profiles/manifest.js';
7
+ import { SettingsRevisionConflictError } from '../../core/scoped-state/settings.js';
8
+ import { InputError } from '../../core/io.js';
6
9
  import { SCOPE_CONFIG_KEYS, USER_SETTINGS, findUserSetting } from '../../core/user-settings.js';
7
10
  // Config helpers (ported from commands/config.ts)
8
11
  const CONFIG_TOP_LEVEL_HELP = SCOPE_CONFIG_KEYS.join(', ');
@@ -90,6 +93,34 @@ function modelLadderPatch(key, rawValue) {
90
93
  }
91
94
  throw usage(`unsupported key path for set: ${key}`);
92
95
  }
96
+ function rawSettingsTarget(input) {
97
+ const scope = input['scope'];
98
+ if (scope === 'project') {
99
+ throw usage('project settings remain a JSON file; use `crtr sys config set` or `crtr sys config path --scope project`.');
100
+ }
101
+ const profile = input['profile'];
102
+ if (scope === 'user') {
103
+ if (profile !== undefined)
104
+ throw usage('--profile is available only with --scope profile.');
105
+ return { scope: 'user' };
106
+ }
107
+ if (profile === undefined)
108
+ throw usage('--profile is required with --scope profile.');
109
+ return { scope: 'profile', profileId: resolveProfileOperand(profile).profileId };
110
+ }
111
+ function parseRawSettings(raw) {
112
+ let value;
113
+ try {
114
+ value = JSON.parse(raw);
115
+ }
116
+ catch {
117
+ throw new InputError({ error: 'invalid_request', message: 'stdin must be valid JSON', field: 'stdin', next: 'Pipe one complete JSON object on stdin.' });
118
+ }
119
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
120
+ throw new InputError({ error: 'invalid_request', message: 'stdin must be a JSON object', field: 'stdin', next: 'Pipe one complete JSON object on stdin.' });
121
+ }
122
+ return value;
123
+ }
93
124
  function setNestedValue(cfg, key, rawValue, value) {
94
125
  const parts = key.split('.');
95
126
  const topKey = parts[0];
@@ -193,7 +224,7 @@ const configSet = defineLeaf({
193
224
  name: 'sys config set',
194
225
  summary: 'write a config value by dotted key',
195
226
  params: [
196
- { kind: 'positional', name: 'key', type: 'string', required: true, constraint: `Dotted key path. User-scope scalar settings: ${SCALAR_SETTING_HELP}. Also supported: working_gerunds and whip_messages (non-empty JSON string arrays), brokerThresholds.warning and brokerThresholds.automaticReviveCap (user scope; integer >= 1), lifecycle.unattendedParkMs (user scope; integer ms >= 1), modelLadders.defaultProvider, and modelLadders.<anthropic|openai>.<ultra|strong|medium|light>. Keybindings are edited only through sys settings. humanActions is an object map edited directly in ~/.crouter/config.json or <repo>/.crouter/config.json.` },
227
+ { kind: 'positional', name: 'key', type: 'string', required: true, constraint: `Dotted key path. User-scope scalar settings: ${SCALAR_SETTING_HELP}. Also supported: working_gerunds and whip_messages (non-empty JSON string arrays), brokerThresholds.warning and brokerThresholds.automaticReviveCap (user scope; integer >= 1), lifecycle.unattendedParkMs (user scope; integer ms >= 1), modelLadders.defaultProvider, and modelLadders.<anthropic|openai>.<ultra|strong|medium|light>. Keybindings are edited only through sys settings. For arbitrary raw user or profile documents, use sys config get-raw and set-raw.` },
197
228
  { kind: 'flag', name: 'value', type: 'string', required: true, constraint: 'value VALUE — string, required. working_gerunds and whip_messages accept JSON arrays; other values are stored as-is if quoted and coerced to number or boolean when unambiguous.' },
198
229
  { kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'project'], required: false, constraint: 'Scope to write to. Default: user. Project scope is supported only for modelLadders.' },
199
230
  ],
@@ -202,7 +233,7 @@ const configSet = defineLeaf({
202
233
  { name: 'scope', type: 'string', required: true, constraint: 'Scope the value was written to.' },
203
234
  ],
204
235
  outputKind: 'object',
205
- effects: ['Writes the updated value to config.json in the target scope.'],
236
+ effects: ['Writes the updated value through the target scope’s configuration storage.'],
206
237
  },
207
238
  run: async (input) => {
208
239
  const key = input['key'];
@@ -227,54 +258,96 @@ const configSet = defineLeaf({
227
258
  return { value: written, scope };
228
259
  },
229
260
  });
261
+ const configGetRaw = defineLeaf({
262
+ name: 'get-raw',
263
+ description: 'read one raw SQL-backed settings document and revision',
264
+ whenToUse: 'you need the exact stored user or profile settings document before replacing it with set-raw.',
265
+ help: {
266
+ name: 'sys config get-raw',
267
+ summary: 'read one raw user or profile settings document',
268
+ params: [
269
+ { kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'profile', 'project'], required: true, constraint: 'SQL-backed target: user or profile. project is rejected because its settings remain a JSON file.' },
270
+ { kind: 'flag', name: 'profile', type: 'string', required: false, constraint: 'Profile id or name to target. Required with --scope profile; rejected with --scope user or project.' },
271
+ ],
272
+ output: [
273
+ { name: 'revision', type: 'string', required: true, constraint: 'Opaque revision token for set-raw. absent means the settings row does not exist.' },
274
+ { name: 'settings', type: 'object | null', required: true, constraint: 'Exact stored settings document, or null when no row exists.' },
275
+ ],
276
+ outputKind: 'object',
277
+ effects: ['None. Read-only.'],
278
+ },
279
+ run: async (input) => readRawSettingsForTarget(rawSettingsTarget(input)),
280
+ });
281
+ const configSetRaw = defineLeaf({
282
+ name: 'set-raw',
283
+ description: 'replace one raw SQL-backed settings document at a revision',
284
+ whenToUse: 'you have a complete user or profile settings document from get-raw and must replace it without losing a concurrent change.',
285
+ help: {
286
+ name: 'sys config set-raw',
287
+ summary: 'atomically replace one raw user or profile settings document',
288
+ params: [
289
+ { kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'profile', 'project'], required: true, constraint: 'SQL-backed target: user or profile. project is rejected because its settings remain a JSON file.' },
290
+ { kind: 'flag', name: 'profile', type: 'string', required: false, constraint: 'Profile id or name to target. Required with --scope profile; rejected with --scope user or project.' },
291
+ { kind: 'flag', name: 'if-revision', type: 'string', required: true, constraint: 'Revision returned by get-raw. Required; use absent only when get-raw reported no settings row.' },
292
+ { kind: 'stdin', name: 'settings', required: true, allowPositional: false, constraint: 'One complete JSON object. It replaces the document exactly; values are not normalized or merged.' },
293
+ ],
294
+ output: [
295
+ { name: 'revision', type: 'string', required: true, constraint: 'Revision token of the stored document after this operation.' },
296
+ { name: 'changed', type: 'boolean', required: true, constraint: 'Whether the stored document changed.' },
297
+ ],
298
+ outputKind: 'object',
299
+ effects: ['Atomically replaces the SQL-backed settings document only when --if-revision matches its current revision.'],
300
+ },
301
+ run: async (input) => {
302
+ const target = rawSettingsTarget(input);
303
+ const settings = parseRawSettings(input['settings']);
304
+ try {
305
+ return replaceRawSettingsForTarget(target, settings, input['ifRevision']);
306
+ }
307
+ catch (error) {
308
+ if (error instanceof SettingsRevisionConflictError) {
309
+ throw new InputError({ error: 'settings_revision_conflict', message: 'settings changed since the supplied revision', field: 'if_revision', next: 'Run `crtr sys config get-raw` again, reapply the intended transformation, and retry with its revision.' });
310
+ }
311
+ if (error instanceof InvalidRawSettingsError) {
312
+ throw new InputError({ error: 'invalid_settings', message: error.message, field: 'stdin', next: 'Correct the document so crouter can merge it into resolved settings, then retry with a fresh revision.' });
313
+ }
314
+ throw error;
315
+ }
316
+ },
317
+ });
230
318
  const configPath = defineLeaf({
231
319
  name: 'path',
232
- description: 'print path(s) to config.json',
233
- whenToUse: 'you need the absolute path to a user or project config.json for inspection or backup.',
320
+ description: 'print the project config.json path',
321
+ whenToUse: 'you need the project config.json path for inspection or backup. User and profile settings use get-raw and set-raw instead.',
234
322
  help: {
235
323
  name: 'sys config path',
236
- summary: 'print absolute path(s) to config.json',
324
+ summary: 'print the project config.json path',
237
325
  params: [
238
- { kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'project', 'all'], required: false, constraint: 'Scope to show paths for. Default: all.' },
326
+ { kind: 'flag', name: 'scope', type: 'enum', choices: ['project', 'user', 'profile'], required: false, constraint: 'Project is the only path-backed settings scope. user and profile are rejected because they use SQL-backed get-raw and set-raw. Default: project.' },
239
327
  ],
240
328
  output: [
241
- { name: 'paths', type: 'object[]', required: true, constraint: 'Each: {scope, path}. Only includes scopes that have a config file.' },
329
+ { name: 'paths', type: 'object[]', required: true, constraint: 'One {scope: "project", path} entry when the current project has a config file; otherwise empty.' },
242
330
  ],
243
331
  outputKind: 'object',
244
332
  effects: ['None. Read-only.'],
245
333
  },
246
334
  run: async (input) => {
247
- const scopeArg = input['scope'];
248
- // Resolve 'all' or undefined → all writable scopes
249
- let scopes;
250
- if (scopeArg === undefined || scopeArg === 'all') {
251
- scopes = listScopes(undefined);
252
- }
253
- else {
254
- scopes = listScopes(scopeArg);
335
+ const scope = input['scope'];
336
+ if (scope === 'user' || scope === 'profile') {
337
+ throw usage(`${scope} settings are SQL-backed; use \`crtr sys config get-raw --scope ${scope}\` instead.`);
255
338
  }
256
- const paths = scopes
257
- .map((s) => {
258
- const root = scopeRoot(s);
259
- if (!root)
260
- return null;
261
- const p = coreConfigPath(s);
262
- if (!p)
263
- return null;
264
- return { scope: s, path: p };
265
- })
266
- .filter((x) => x !== null);
267
- return { paths };
339
+ const path = coreConfigPath('project');
340
+ return { paths: path === null ? [] : [{ scope: 'project', path }] };
268
341
  },
269
342
  });
270
343
  export const configBranch = defineBranch({
271
344
  name: 'config',
272
345
  description: 'read and write configuration',
273
- whenToUse: 'inspecting crtr settings, changing supported scalar values, or locating config.json. Keybinding changes belong in sys settings.',
346
+ whenToUse: 'inspecting crtr settings, changing supported scalar values, replacing complete raw user or profile settings documents, or locating a project config.json. Keybinding changes belong in sys settings.',
274
347
  help: {
275
348
  name: 'sys config',
276
- summary: 'read and write crtr configuration, including model ladders; edit humanActions maps directly in ~/.crouter/config.json or <repo>/.crouter/config.json',
277
- model: 'Configuration resolves through ordered scopes. Reads can resolve the effective value, writes target one writable scope, and path inspection reveals the backing files without reading values.',
349
+ summary: 'read and write crtr configuration, including model ladders and raw SQL-backed user/profile settings',
350
+ model: 'get and set resolve individual settings. get-raw and set-raw read and replace complete user or profile documents with a revision precondition. path applies only to project config.json.',
278
351
  },
279
- children: [configGet, configSet, configPath],
352
+ children: [configGet, configSet, configGetRaw, configSetRaw, configPath],
280
353
  });
@@ -1,2 +1,4 @@
1
1
  import type { BranchDef } from '../../core/command.js';
2
2
  export declare const daemonBranch: BranchDef;
3
+ /** The daemon-only `sys` subtree used before scoped user state is available. */
4
+ export declare function registerDaemonControlSys(): BranchDef;
@@ -8,9 +8,12 @@
8
8
  // This subtree starts, checks, and stops the daemon process.
9
9
  import { defineLeaf, defineBranch } from '../../core/command.js';
10
10
  import { InputError } from '../../core/io.js';
11
- import { probeDaemonServing, spawnDaemon, stopDaemonProcess, sweepStrayDaemons } from '../../daemon/manage.js';
11
+ import { parseDurationMs } from '../../core/wake.js';
12
+ import { DaemonNotPreparedError, probeDaemonHealth, spawnDaemon, stopDaemonProcess, sweepStrayDaemons } from '../../daemon/manage.js';
12
13
  import { isDaemonRunning, readPidfile, isPidAlive } from '../../daemon/pidfile.js';
13
14
  import { cliClient } from '../api-client.js';
15
+ import { CrtrClient } from '../../api/index.js';
16
+ import { defineSysBranch } from './branch.js';
14
17
  // daemon start
15
18
  const daemonStart = defineLeaf({
16
19
  name: 'start',
@@ -19,7 +22,9 @@ const daemonStart = defineLeaf({
19
22
  help: {
20
23
  name: 'sys daemon start',
21
24
  summary: 'start the crtrd supervisor daemon in the background (no-op only if its Unix API socket serves)',
22
- params: [],
25
+ params: [
26
+ { kind: 'flag', name: 'prepare', type: 'bool', required: false, constraint: 'Hold normal daemon work after storage preparation until `sys daemon admit`; omit for ordinary startup.' },
27
+ ],
23
28
  output: [
24
29
  { name: 'started', type: 'boolean', required: true, constraint: 'True when a new daemon process was spawned; false when one was already running.' },
25
30
  { name: 'pid', type: 'number', required: false, constraint: 'PID of the newly spawned daemon.' },
@@ -27,6 +32,7 @@ const daemonStart = defineLeaf({
27
32
  { name: 'running', type: 'boolean', required: false, constraint: 'True only when a live pidfile owner does not serve its Unix API socket.' },
28
33
  { name: 'serving', type: 'boolean', required: false, constraint: 'False only when a live pidfile owner does not answer /healthz.' },
29
34
  { name: 'probe_error', type: 'string', required: false, constraint: 'The final /healthz probe failure when a live owner missed readiness.' },
35
+ { name: 'startup_phase', type: 'string', required: false, constraint: 'The observed daemon phase when it was reachable.' },
30
36
  ],
31
37
  outputKind: 'object',
32
38
  effects: [
@@ -34,9 +40,116 @@ const daemonStart = defineLeaf({
34
40
  'Writes a pidfile at CRTR_PIDFILE if set, otherwise crtrHome()/crtrd.pid.'
35
41
  ],
36
42
  },
43
+ run: async (input) => {
44
+ try {
45
+ const result = await spawnDaemon({ targetPhase: input.prepare === true ? 'prepared' : 'ready' });
46
+ return result;
47
+ }
48
+ catch (error) {
49
+ if (error instanceof DaemonNotPreparedError) {
50
+ throw new InputError({
51
+ error: 'daemon_not_prepared',
52
+ message: error.message,
53
+ next: 'Stop the live daemon, then start a new one with `crtr sys daemon start --prepare` before setup.',
54
+ });
55
+ }
56
+ throw error;
57
+ }
58
+ },
59
+ });
60
+ // daemon await / admit
61
+ const DAEMON_AWAIT_POLL_MS = 100;
62
+ async function awaitDaemonPhase(phase, timeoutMs) {
63
+ const startedAt = Date.now();
64
+ const deadline = startedAt + timeoutMs;
65
+ let lastPhase = 'initializing';
66
+ let lastObservation = 'the daemon socket was not reachable';
67
+ while (Date.now() < deadline) {
68
+ try {
69
+ const health = await probeDaemonHealth(Math.min(1_000, Math.max(1, deadline - Date.now())));
70
+ lastPhase = health.startup_phase;
71
+ lastObservation = health.startup_blocked ?? `daemon is ${health.startup_phase}`;
72
+ if (health.startup_phase === 'blocked') {
73
+ throw new InputError({
74
+ error: 'startup_blocked',
75
+ message: health.startup_blocked ?? 'daemon startup is blocked',
76
+ received: health.startup_phase,
77
+ field: 'phase',
78
+ next: 'Repair the reported blocker paths with `crtr sys migrate`, then retry the await.',
79
+ });
80
+ }
81
+ if (health.startup_phase === phase)
82
+ return { startup_phase: phase, waited_ms: Date.now() - startedAt };
83
+ if (phase === 'prepared' && health.startup_phase === 'ready') {
84
+ throw new InputError({
85
+ error: 'await_missed_phase',
86
+ message: 'daemon is already ready and cannot return to prepared in this process',
87
+ received: health.startup_phase,
88
+ field: 'phase',
89
+ next: 'Start a new daemon with `crtr sys daemon start --prepare` before awaiting prepared.',
90
+ });
91
+ }
92
+ }
93
+ catch (error) {
94
+ if (error instanceof InputError)
95
+ throw error;
96
+ lastObservation = error instanceof Error ? error.message : String(error);
97
+ }
98
+ await new Promise((resolve) => setTimeout(resolve, Math.min(DAEMON_AWAIT_POLL_MS, Math.max(0, deadline - Date.now()))));
99
+ }
100
+ throw new InputError({
101
+ error: 'await_timeout',
102
+ message: `daemon did not reach ${phase} within ${timeoutMs}ms (last phase: ${lastPhase}; last observation: ${lastObservation})`,
103
+ received: lastPhase,
104
+ field: 'phase',
105
+ next: 'Inspect `crtr sys daemon status` and resolve any reported startup blocker before retrying.',
106
+ });
107
+ }
108
+ const daemonAwait = defineLeaf({
109
+ name: 'await',
110
+ description: 'wait for a daemon startup phase',
111
+ whenToUse: 'a caller started or was given a daemon that must reach prepared or ready before its next step.',
112
+ help: {
113
+ name: 'sys daemon await',
114
+ summary: 'wait for the running daemon to report one startup phase',
115
+ params: [
116
+ { kind: 'flag', name: 'phase', type: 'enum', choices: ['prepared', 'ready'], required: true, constraint: 'The phase that permits the caller’s next step.' },
117
+ { kind: 'flag', name: 'timeout', type: 'string', required: false, default: '5m', constraint: 'Maximum wait as a positive duration such as 90s, 5m, or 1h30m.' },
118
+ ],
119
+ output: [
120
+ { name: 'startup_phase', type: 'string', required: true, constraint: 'The requested phase.' },
121
+ { name: 'waited_ms', type: 'number', required: true, constraint: 'Elapsed wall-clock time before the phase was observed.' },
122
+ ],
123
+ outputKind: 'object',
124
+ effects: ['Read-only: polls /healthz until the requested phase is observed or the caller-bounded timeout expires.'],
125
+ },
126
+ run: async (input) => {
127
+ const rawTimeout = input.timeout;
128
+ const timeoutMs = parseDurationMs(rawTimeout);
129
+ if (timeoutMs === null || timeoutMs <= 0) {
130
+ throw new InputError({ error: 'invalid_duration', message: `not a positive duration: ${rawTimeout}`, received: rawTimeout, field: 'timeout', next: 'Use a positive duration such as 90s, 5m, or 1h30m.' });
131
+ }
132
+ return awaitDaemonPhase(input.phase, timeoutMs);
133
+ },
134
+ });
135
+ const daemonAdmit = defineLeaf({
136
+ name: 'admit',
137
+ description: 'admit normal work after daemon preparation',
138
+ whenToUse: 'the caller has completed its setup against a prepared daemon and is ready for normal daemon work to start.',
139
+ help: {
140
+ name: 'sys daemon admit',
141
+ summary: 'ask a prepared daemon to start normal services',
142
+ params: [],
143
+ output: [
144
+ { name: 'admitted', type: 'boolean', required: true, constraint: 'True only when this request began admission.' },
145
+ { name: 'already_admitted', type: 'boolean', required: true, constraint: 'True when admission had already begun or completed.' },
146
+ { name: 'startup_phase', type: 'string', required: true, constraint: 'The phase after admission settles.' },
147
+ ],
148
+ outputKind: 'object',
149
+ effects: ['Starts normal daemon services when the daemon is prepared.'],
150
+ },
37
151
  run: async (_input) => {
38
- const result = await spawnDaemon();
39
- return result;
152
+ return await CrtrClient.forLocalSocket({ autostart: false }).admitDaemon();
40
153
  },
41
154
  });
42
155
  // daemon status
@@ -53,6 +166,7 @@ const daemonStatus = defineLeaf({
53
166
  { name: 'serving', type: 'boolean', required: false, constraint: 'True when the live daemon answers /healthz; false when one probe does not.' },
54
167
  { name: 'pid', type: 'number', required: false, constraint: 'PID of the running daemon.' },
55
168
  { name: 'probe_error', type: 'string', required: false, constraint: 'The failed /healthz observation when the live owner did not answer.' },
169
+ { name: 'startup_phase', type: 'string', required: false, constraint: 'The observed daemon startup phase when the socket answered.' },
56
170
  ],
57
171
  outputKind: 'object',
58
172
  effects: ['Read-only: reads the pidfile, probes the pid, and requests /healthz without autostart.'],
@@ -63,8 +177,13 @@ const daemonStatus = defineLeaf({
63
177
  if (!running)
64
178
  return { running: false };
65
179
  try {
66
- await probeDaemonServing();
67
- return { running: true, serving: true, pid };
180
+ const health = await probeDaemonHealth();
181
+ return {
182
+ running: true,
183
+ serving: health.ok,
184
+ pid,
185
+ ...(health.startup_phase === undefined ? {} : { startup_phase: health.startup_phase }),
186
+ };
68
187
  }
69
188
  catch (error) {
70
189
  return { running: true, serving: false, pid, probe_error: error.message };
@@ -186,5 +305,9 @@ export const daemonBranch = defineBranch({
186
305
  summary: 'manage the crtrd canvas supervisor daemon',
187
306
  model: 'crtrd is a thin background daemon that polls active+idle nodes and acts on window exit: crashed windows become dead; refresh-yield windows get a fresh respawn. It holds no orchestration logic — just process supervision. These are operator/dev self-management, not something a normal agent turn needs to check. Picking up a newly installed runtime generation is `restart` (a handover the daemon performs on itself); `stop` is the terminal one, and it kills the caller along with the rest of the fleet.',
188
307
  },
189
- children: [daemonStart, daemonRestart, daemonStatus, daemonStop],
308
+ children: [daemonStart, daemonAwait, daemonAdmit, daemonRestart, daemonStatus, daemonStop],
190
309
  });
310
+ /** The daemon-only `sys` subtree used before scoped user state is available. */
311
+ export function registerDaemonControlSys() {
312
+ return defineSysBranch([daemonBranch]);
313
+ }
@@ -8,9 +8,7 @@ import { scopeRoot, listScopes, marketplacesDir, pluginsDir } from '../../core/s
8
8
  import { readMarketplaceManifest, readPluginManifest } from '../../core/manifest.js';
9
9
  import { pathExists, listDirs, removePath } from '../../core/fs-utils.js';
10
10
  import { lsRemote } from '../../core/git.js';
11
- import { isPidAlive } from '../../core/canvas/pid.js';
12
11
  import { cliClient } from '../api-client.js';
13
- import { readFault } from '../../core/runtime/fault.js';
14
12
  import { detectNerdFont, nerdFontInstallCommand, NERD_FONT_SELECT_HINT } from '../../core/runtime/nerd-font.js';
15
13
  import { detectPackageManager } from './setup-core.js';
16
14
  import { validateEffectiveCommandPlugins } from '../../core/command-plugins/discovery.js';
@@ -406,22 +404,14 @@ async function generationChecks(label, lookup, allowAbsent) {
406
404
  }
407
405
  return results;
408
406
  }
409
- /** Local copy of `render.ts`'s `activeFaultForDisplay` overlay: a stale
410
- * daemon-owned auto-retry provider fault is hidden once the broker pid is gone;
411
- * manual/client faults stay visible. Inlined here (rather than imported from
412
- * `core/canvas/render.ts`) because that module's runtime graph reaches
413
- * `core/canvas/canvas.ts` — which a pure-client CLI leaf must not pull in. */
414
- function activeFaultForDisplay(node, fault) {
415
- if (fault === null)
416
- return null;
417
- if (fault.link === 'pi→provider' && fault.retry.by === 'daemon' && fault.retry.disposition === 'auto' && !isPidAlive(node.pi_pid))
418
- return null;
419
- return fault;
420
- }
407
+ /** One failing check per node parked on an active fault. The fault is the
408
+ * daemon's projection on the node summary — the stale-provider overlay (a
409
+ * daemon-owned auto retry whose broker pid is gone) is already applied there,
410
+ * so this leaf needs no local read. */
421
411
  async function runFaultChecks() {
422
412
  const results = [];
423
413
  for (const node of await cliClient().listNodes()) {
424
- const fault = activeFaultForDisplay(node, readFault(node.node_id));
414
+ const fault = node.fault ?? null;
425
415
  if (fault === null)
426
416
  continue;
427
417
  const name = `fault:${node.node_id}:${fault.link}`;
@@ -2,8 +2,9 @@
2
2
  // Journaled canvas-db migrations remain in the database's ordered chain.
3
3
  import { defineLeaf } from '../../core/command.js';
4
4
  import { general, usage } from '../../core/errors.js';
5
+ import { resolve } from 'node:path';
5
6
  import { pathExists } from '../../core/fs-utils.js';
6
- import { runForcedOnDiskMigrations } from '../../migrations/activation.js';
7
+ import { cliClient, rethrowAsCliError } from '../api-client.js';
7
8
  export const sysMigrateLeaf = defineLeaf({
8
9
  name: 'migrate',
9
10
  description: 'converge every profile manifest and writable memory store to the current on-disk format',
@@ -26,16 +27,17 @@ export const sysMigrateLeaf = defineLeaf({
26
27
  { name: 'discovery_roots', type: 'object[]', required: true, constraint: 'The frontier searched: {reason, root, boundary, detail?}. reason is user, profile, profile-project, cwd-ancestor, descendant, node, plugin, builtin, or explicit-dir; boundary is store, ancestors, descendants, plugins, or nodes.' },
27
28
  { name: 'discovered_stores', type: 'object[]', required: true, constraint: 'One row per physical store: {store, scope, namespace, mount_status, writable, reasons, targets, docs}. reasons holds every way the store was reached; targets the target ids that mount it; docs its parseable document count.' },
28
29
  { name: 'discovered_targets', type: 'object[]', required: true, constraint: 'One row per resolution view: {id, kind, origin, cwd, profile_id, node_id, stores}. stores lists store keys in that target\'s precedence order.' },
29
- { name: 'node_metadata', type: 'object', required: true, constraint: '{available, nodes, error?} — whether cwd/profile metadata was readable from every durable meta.json whose node store holds documents. Missing or corrupt metadata blocks corpus writes.' },
30
30
  { name: 'repository_namespaces', type: 'object[]', required: true, constraint: 'Repository-root namespace decisions this run makes: {repository_root, repository_key, declaration_path, namespace, source, action}. A nested store inherits this declaration; its reported effective prefix is not a declaration.' },
31
31
  { name: 'store_prefixes', type: 'object[]', required: true, constraint: 'Effective prefix facts for each project store: {store_root, owner_dir, repository_root, owner_relative_path, old_prefix, old_rule, effective_prefix, nested_declaration_action, front_door_action}. A nonempty owner_relative_path always reports front_door_action `none`; a nested effective_prefix is derived, not a declaration.' },
32
32
  { name: 'renames', type: 'object[]', required: true, constraint: 'Canonical identity changes: {store_root, path, from, to}.' },
33
33
  { name: 'references', type: 'object[]', required: true, constraint: 'Rewritten pointers at a changed identity: {store_root, path, kind, from, to}, kind link or memory-read.' },
34
34
  { name: 'dryRun', type: 'boolean', required: true, constraint: 'True when nothing was written (preview only).' },
35
+ { name: 'resumed', type: 'boolean', required: true, constraint: 'True only when this repair resumed the blocked daemon startup.' },
36
+ { name: 'resume_error', type: 'string', required: false, constraint: 'Present when corpus repair succeeded but normal daemon startup then failed.' },
35
37
  ],
36
38
  outputKind: 'object',
37
39
  effects: [
38
- 'Rewrites old-format `profile.json` manifests in place (atomic, under the same per-profile lock `profile project add/remove` take). A manifest whose structure cannot be converted fails the whole run — no project setting is ever guessed.',
40
+ 'The daemon that owns this canvas runs the migration. Rewrites old-format `profile.json` manifests in place (atomic, under the same per-profile lock `profile project add/remove` take). A manifest whose structure cannot be converted fails the whole run — no project setting is ever guessed.',
39
41
  'Rewrites old-format memory documents in place (atomic per-file writes) across every writable discovered store: profiles, profile-owned projects, this directory\'s ancestors, nested descendant stores, installed plugin stores, and node stores. Builtin docs are package-owned and never touched.',
40
42
  'Applies corpus-wide identity changes in two ordered phases across every writable store, after the global plan comes back blocker-free; a post-write pass re-reads the corpus from disk and verifies it.',
41
43
  'Under --dry-run: read-only, writes nothing.',
@@ -43,7 +45,7 @@ export const sysMigrateLeaf = defineLeaf({
43
45
  },
44
46
  run: async (input) => {
45
47
  const dryRun = input.dryRun === true;
46
- const explicitDirs = input['dir'] ?? [];
48
+ const explicitDirs = (input['dir'] ?? []).map((dir) => resolve(dir));
47
49
  const missingDirs = explicitDirs.filter((dir) => !pathExists(dir));
48
50
  if (missingDirs.length > 0) {
49
51
  throw usage(`--dir path does not exist: ${missingDirs.join(', ')}`, {
@@ -52,91 +54,18 @@ export const sysMigrateLeaf = defineLeaf({
52
54
  next: 'Pass the project directory that contains `.crouter/`, or omit --dir to migrate the discovered frontier only.',
53
55
  });
54
56
  }
55
- const result = await runForcedOnDiskMigrations({ dryRun, explicitDirs });
56
- const { applied, changed, discovery, skipped, snapshots } = result;
57
- const blockers = result.blockers.map((blocker) => ({
58
- kind: blocker.kind,
59
- message: blocker.message,
60
- ...(blocker.storeRoot === undefined ? {} : { store: blocker.storeRoot }),
61
- ...(blocker.targetId === undefined ? {} : { target: blocker.targetId }),
62
- ...(blocker.path === undefined ? {} : { path: blocker.path }),
63
- ...(blocker.name === undefined ? {} : { name: blocker.name }),
64
- ...(blocker.paths === undefined ? {} : { paths: blocker.paths }),
65
- }));
66
- // One report body, whether the run converged or blocked: a blocked planner
67
- // stays as inspectable as a successful one, and the failure payload adds only
68
- // the phase and the write inventory that a success cannot have.
69
- const report = {
70
- profiles: result.profiles,
71
- stores: discovery.stores.length,
72
- changed,
73
- applied,
74
- skipped,
75
- blockers,
76
- discovery_roots: discovery.roots.map((row) => ({
77
- reason: row.reason,
78
- root: row.root,
79
- boundary: row.boundary,
80
- ...(row.detail === undefined ? {} : { detail: row.detail }),
81
- })),
82
- discovered_stores: discovery.stores.map((store) => ({
83
- store: store.key,
84
- scope: store.descriptor.scope,
85
- namespace: store.descriptor.namespace,
86
- mount_status: store.descriptor.mountStatus,
87
- writable: store.writable,
88
- reasons: [...new Set(store.discovery.map((row) => row.reason))],
89
- targets: store.targets,
90
- docs: snapshots.get(store.key)?.docs.length ?? 0,
91
- })),
92
- discovered_targets: discovery.targets.map((target) => ({
93
- id: target.id,
94
- kind: target.kind,
95
- origin: target.origin,
96
- cwd: target.target.cwd,
97
- profile_id: target.target.profileId,
98
- node_id: target.target.nodeId,
99
- stores: target.storeKeys,
100
- })),
101
- node_metadata: discovery.nodeMetadata,
102
- repository_namespaces: result.repositories.map((row) => ({
103
- repository_root: row.repositoryRoot,
104
- repository_key: row.repositoryKey,
105
- declaration_path: row.declarationPath,
106
- namespace: row.namespace,
107
- source: row.source,
108
- action: row.action,
109
- })),
110
- store_prefixes: result.storePrefixes.map((row) => ({
111
- store_root: row.storeRoot,
112
- owner_dir: row.ownerDir,
113
- repository_root: row.repositoryRoot,
114
- owner_relative_path: row.ownerRelativePath,
115
- old_prefix: row.oldPrefix,
116
- old_rule: row.oldRule,
117
- effective_prefix: row.effectivePrefix,
118
- nested_declaration_action: row.nestedDeclarationAction,
119
- front_door_action: row.frontDoorAction,
120
- })),
121
- renames: result.renames.map((row) => ({ store_root: row.storeRoot, path: row.path, from: row.from, to: row.to })),
122
- references: result.references.map((row) => ({
123
- store_root: row.storeRoot,
124
- path: row.path,
125
- kind: row.kind,
126
- from: row.from,
127
- to: row.to,
128
- })),
129
- dryRun,
130
- };
131
- if (result.blocked) {
132
- const earlier = applied.filter((row) => row.lane !== 'corpus').flatMap((row) => row.files);
133
- const corpusPhase = result.corpusPhase;
134
- const wrote = {
135
- profile_manifests: result.wrote.profileManifests,
136
- documents: result.wrote.documents,
137
- corpus_consumers: result.wrote.corpusConsumers,
138
- corpus_identities: result.wrote.corpusIdentities,
139
- };
57
+ let report;
58
+ try {
59
+ report = await cliClient().migrateState({ dry_run: dryRun, dirs: explicitDirs });
60
+ }
61
+ catch (error) {
62
+ rethrowAsCliError(error);
63
+ }
64
+ if (report.blocked) {
65
+ const blockers = report.blockers;
66
+ const earlier = report.applied.filter((row) => row.lane !== 'corpus').flatMap((row) => row.files);
67
+ const corpusPhase = report.corpus_phase;
68
+ const wrote = report.wrote;
140
69
  const wroteSummary = dryRun
141
70
  ? '— this was a --dry-run; nothing was written'
142
71
  : corpusPhase === 'written'
@@ -145,7 +74,7 @@ export const sysMigrateLeaf = defineLeaf({
145
74
  ? `before any corpus write — the corpus is unchanged, but ${earlier.length} earlier manifest/document rewrite(s) are already on disk`
146
75
  : '— nothing was written';
147
76
  throw general(`corpus migration ${corpusPhase === 'written' ? 'verification failed with' : 'blocked by'} ${blockers.length} finding(s) ${wroteSummary}`, {
148
- received: { ...report, corpus_phase: corpusPhase, wrote },
77
+ received: report,
149
78
  next: corpusPhase === 'written'
150
79
  ? 'Resolve every verification finding against the files listed in received.wrote.corpus_identities and .corpus_consumers, then re-run `crtr sys migrate` — the lane converges from file truth.'
151
80
  : 'Resolve every blocker, then re-run `crtr sys migrate` — the earlier lanes are convergent and re-running them is a no-op.',
@@ -153,9 +82,9 @@ export const sysMigrateLeaf = defineLeaf({
153
82
  }
154
83
  return {
155
84
  ...report,
156
- follow_up: skipped.length > 0
85
+ follow_up: report.skipped.length > 0
157
86
  ? 'Some files could not be parsed and were left untouched — fix each named file, then re-run `crtr sys migrate`.'
158
- : changed === 0
87
+ : report.changed === 0
159
88
  ? 'State already current — nothing to rewrite.'
160
89
  : dryRun
161
90
  ? 'Preview only — re-run without --dry-run to write these changes.'
@@ -1,10 +1,12 @@
1
1
  import { ModelRegistry, ModelRuntime } from '@earendil-works/pi-coding-agent';
2
2
  import { join } from 'node:path';
3
- import { defaultAgentDir } from '../../clients/attach/config.js';
3
+ import { piAgentDir } from '../../core/runtime/package-health.js';
4
4
  import { PoolCredentialStore } from '../../core/pool-credential-store.js';
5
+ import { initializeFreshScopedStore } from '../../core/scoped-state/migrate.js';
5
6
  import { runTuiPage, } from '../../core/tui/page-host.js';
6
7
  export async function runSetupSettingsProcess(createSurface, interceptCancel) {
7
- const agentDir = defaultAgentDir();
8
+ const agentDir = piAgentDir();
9
+ initializeFreshScopedStore({ kind: 'provider', root: agentDir });
8
10
  const runtime = await ModelRuntime.create({
9
11
  credentials: new PoolCredentialStore(join(agentDir, "auth.json")),
10
12
  modelsPath: join(agentDir, "models.json"),
@@ -1,5 +1,5 @@
1
1
  // `crtr sys` subtree: configuration, diagnostics, and self-management.
2
- import { defineBranch } from '../core/command.js';
2
+ import { defineSysBranch } from './sys/branch.js';
3
3
  import { configBranch } from './sys/config.js';
4
4
  import { daemonBranch } from './sys/daemon.js';
5
5
  import { sysDoctorLeaf } from './sys/doctor.js';
@@ -14,18 +14,5 @@ import { sysSyncBranch } from './sys/sync.js';
14
14
  import { sysMigrateLeaf } from './sys/migrate.js';
15
15
  import { sysUpdateLeaf, sysVersionLeaf } from './sys/update.js';
16
16
  export function registerSys() {
17
- return defineBranch({
18
- name: 'sys',
19
- rootEntry: {
20
- concept: 'crtr configuration, diagnostics, and self-management',
21
- desc: 'settings, config, setup, doctor, context, sync, migrate, update, version, feedback, logs, support, daemon',
22
- useWhen: 'managing the crtr installation, inspecting diagnostics, or operating the crtrd supervisor process',
23
- },
24
- help: {
25
- name: 'sys',
26
- summary: 'crtr system configuration, settings, diagnostics, and self-management',
27
- model: 'Configuration and settings own durable behavior; diagnostics and support observe it. Setup, migration, sync, and update change installed or generated state, while daemon control owns the supervisor lifecycle.',
28
- },
29
- children: [sysSettingsLeaf, configBranch, sysSetupLeaf, sysDoctorLeaf, contextBranch, sysFeedbackLeaf, sysLogsLeaf, sysWorktreesLeaf, supportBranch, sysUpdateLeaf, sysVersionLeaf, sysMigrateLeaf, sysSyncBranch, daemonBranch],
30
- });
17
+ return defineSysBranch([sysSettingsLeaf, configBranch, sysSetupLeaf, sysDoctorLeaf, contextBranch, sysFeedbackLeaf, sysLogsLeaf, sysWorktreesLeaf, supportBranch, sysUpdateLeaf, sysVersionLeaf, sysMigrateLeaf, sysSyncBranch, daemonBranch]);
31
18
  }