@north-light/crouter 0.3.233 → 0.3.234

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 (379) hide show
  1. package/dist/api/client.js +16 -15
  2. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +1 -1
  3. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +14 -17
  4. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crtr-commands/index.ts +7 -11
  5. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +8 -8
  6. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +10 -11
  7. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/pi-shell-runner.ts +2 -2
  8. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +3 -3
  9. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +7 -7
  10. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +8 -8
  11. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +6 -6
  12. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/sysprompt-window.ts +3 -3
  13. package/dist/builtin-pi-packages/pi-crtr-extensions/lib/subscription-state.ts +1 -1
  14. package/dist/clients/attach/chrome/ticket-panel.js +15 -2
  15. package/dist/clients/attach/overlays/graph.js +0 -3
  16. package/dist/clients/attach/overlays/mcp.js +1 -2
  17. package/dist/clients/attach/render/chat-view.js +0 -12
  18. package/dist/clients/attach/render/crtr-output.js +0 -2
  19. package/dist/clients/attach/render/tool-calls.js +0 -6
  20. package/dist/clients/attach/slash/dispatch.js +8 -11
  21. package/dist/clients/attach/viewer.js +532 -534
  22. package/dist/clients/conversation/projection.js +0 -2
  23. package/dist/clients/inbox/controller.js +22 -3
  24. package/dist/clients/inbox/review/companion-pane.js +0 -4
  25. package/dist/clients/inbox/review-adapter.js +0 -7
  26. package/dist/clients/inbox/tui/slots.d.ts +3 -3
  27. package/dist/clients/inbox/tui/types.d.ts +2 -2
  28. package/dist/commands/api-client.js +0 -8
  29. package/dist/commands/attention.js +0 -8
  30. package/dist/commands/canvas-browse.js +2 -1
  31. package/dist/commands/canvas-config.js +0 -10
  32. package/dist/commands/canvas-history.js +2 -1
  33. package/dist/commands/cron.js +5 -18
  34. package/dist/commands/dashboard.js +0 -2
  35. package/dist/commands/human/feedback.js +2 -1
  36. package/dist/commands/human/prompts.js +2 -5
  37. package/dist/commands/human/queue.js +2 -7
  38. package/dist/commands/human/request.js +0 -14
  39. package/dist/commands/human/review.js +2 -1
  40. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +4 -4
  41. package/dist/commands/memory/find.js +2 -2
  42. package/dist/commands/memory/lint.js +2 -1
  43. package/dist/commands/memory/read.d.ts +2 -7
  44. package/dist/commands/memory/read.js +5 -16
  45. package/dist/commands/memory/shared.js +4 -7
  46. package/dist/commands/memory/write.js +4 -3
  47. package/dist/commands/node/bash.js +2 -1
  48. package/dist/commands/node/create.js +2 -1
  49. package/dist/commands/node/inspect.js +0 -6
  50. package/dist/commands/node/lifecycle.js +4 -13
  51. package/dist/commands/node/message.js +3 -2
  52. package/dist/commands/node/subscription.js +2 -1
  53. package/dist/commands/node/wait.js +4 -3
  54. package/dist/commands/node-context.js +2 -1
  55. package/dist/commands/node-lifecycle-revive.js +0 -2
  56. package/dist/commands/node-worktree.js +2 -1
  57. package/dist/commands/pkg/browse/actions.d.ts +1 -1
  58. package/dist/commands/pkg/browse/actions.js +4 -4
  59. package/dist/commands/pkg/browse/catalog.d.ts +1 -1
  60. package/dist/commands/pkg/browse/catalog.js +15 -15
  61. package/dist/commands/pkg/browse/command-view.d.ts +1 -1
  62. package/dist/commands/pkg/browse/command-view.js +3 -3
  63. package/dist/commands/pkg/browse/detail-panel.d.ts +1 -1
  64. package/dist/commands/pkg/browse/detail-panel.js +8 -8
  65. package/dist/commands/pkg/browse/doc-view.d.ts +1 -1
  66. package/dist/commands/pkg/browse/doc-view.js +3 -3
  67. package/dist/commands/pkg/browse/list-panel.d.ts +1 -1
  68. package/dist/commands/pkg/browse/list-panel.js +3 -3
  69. package/dist/commands/pkg/browse/model.d.ts +3 -3
  70. package/dist/commands/pkg/browse/shell.d.ts +2 -2
  71. package/dist/commands/pkg/browse/shell.js +13 -13
  72. package/dist/commands/pkg/plugin-manage.js +2 -1
  73. package/dist/commands/pkg/shared.js +0 -2
  74. package/dist/commands/profile/delete.js +2 -1
  75. package/dist/commands/push.js +2 -3
  76. package/dist/commands/revive.js +0 -2
  77. package/dist/commands/surface/node/placement.js +2 -1
  78. package/dist/commands/surface-edit.js +2 -1
  79. package/dist/commands/sys/config.js +0 -4
  80. package/dist/commands/sys/daemon.js +0 -10
  81. package/dist/commands/sys/doctor.js +3 -2
  82. package/dist/commands/sys/panels/broker-limits-panel.d.ts +2 -2
  83. package/dist/commands/sys/panels/broker-limits-panel.js +4 -4
  84. package/dist/commands/sys/panels/dependencies-panel.d.ts +2 -2
  85. package/dist/commands/sys/panels/dependencies-panel.js +2 -2
  86. package/dist/commands/sys/panels/keybindings-panel.d.ts +1 -1
  87. package/dist/commands/sys/panels/keybindings-panel.js +5 -5
  88. package/dist/commands/sys/panels/models-panel.d.ts +4 -4
  89. package/dist/commands/sys/panels/models-panel.js +11 -10
  90. package/dist/commands/sys/panels/plugins-panel.d.ts +2 -2
  91. package/dist/commands/sys/panels/plugins-panel.js +2 -2
  92. package/dist/commands/sys/panels/prefs-panel.d.ts +2 -2
  93. package/dist/commands/sys/panels/prefs-panel.js +4 -4
  94. package/dist/commands/sys/panels/profiles-panel.d.ts +1 -1
  95. package/dist/commands/sys/panels/profiles-panel.js +14 -13
  96. package/dist/commands/sys/panels/provider-panel.d.ts +3 -3
  97. package/dist/commands/sys/panels/provider-panel.js +8 -8
  98. package/dist/commands/sys/settings-shell.d.ts +3 -3
  99. package/dist/commands/sys/settings-shell.js +15 -15
  100. package/dist/commands/sys/setup-settings-runner.d.ts +3 -3
  101. package/dist/commands/sys/setup-settings-runner.js +5 -5
  102. package/dist/commands/sys/setup-wizard.d.ts +4 -4
  103. package/dist/commands/sys/setup-wizard.js +8 -8
  104. package/dist/commands/sys/support/prepare.js +4 -4
  105. package/dist/commands/sys/support/submit.js +2 -2
  106. package/dist/commands/sys/sync-deps.js +0 -2
  107. package/dist/commands/sys/sync-project-guidance.js +2 -1
  108. package/dist/commands/sys/sysprompt.js +2 -1
  109. package/dist/core/__tests__/boot.test.js +0 -8
  110. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +23 -1
  111. package/dist/core/__tests__/canvas-db-boundary.test.d.ts +1 -0
  112. package/dist/core/__tests__/canvas-db-boundary.test.js +46 -0
  113. package/dist/core/__tests__/canvas.test.js +1 -1
  114. package/dist/core/__tests__/child-death-wake.test.js +0 -2
  115. package/dist/core/__tests__/cron-armed-context-failure.test.d.ts +1 -0
  116. package/dist/core/__tests__/cron-armed-context-failure.test.js +145 -0
  117. package/dist/core/__tests__/daemon-wedge.test.js +0 -4
  118. package/dist/core/__tests__/dead-node-policy-table.test.js +0 -4
  119. package/dist/core/__tests__/fixtures/fake-engine.js +4 -14
  120. package/dist/core/__tests__/fixtures/fake-pi-host.js +5 -5
  121. package/dist/core/__tests__/focuses.test.js +0 -6
  122. package/dist/core/__tests__/fs-utils.test.d.ts +1 -0
  123. package/dist/core/__tests__/fs-utils.test.js +50 -0
  124. package/dist/core/__tests__/helpers/harness.js +1 -1
  125. package/dist/core/__tests__/inline-memory-refs.test.js +0 -2
  126. package/dist/core/__tests__/integration/broker-fork-seam.test.js +0 -2
  127. package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +3 -16
  128. package/dist/core/__tests__/integration/command-plugins.test.js +0 -24
  129. package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -6
  130. package/dist/core/__tests__/integration/flagship-lifecycle.test.js +0 -26
  131. package/dist/core/__tests__/integration/live-mutation-verbs.test.js +0 -4
  132. package/dist/core/__tests__/integration/live-mutation.test.js +1 -5
  133. package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +1 -5
  134. package/dist/core/__tests__/integration/revive.test.js +0 -12
  135. package/dist/core/__tests__/integration/subscription-delivery.test.js +0 -6
  136. package/dist/core/__tests__/integration/tmux-surface.test.js +24 -8
  137. package/dist/core/__tests__/integration/worktree-reap.test.js +0 -6
  138. package/dist/core/__tests__/lifecycle.test.js +0 -18
  139. package/dist/core/__tests__/memory-resolver-precedence.test.js +1 -1
  140. package/dist/core/__tests__/migration.test.js +2 -2
  141. package/dist/core/__tests__/on-read-dedup-resume.test.js +3 -3
  142. package/dist/core/__tests__/pid-identity-match.test.js +1 -1
  143. package/dist/core/__tests__/plugin-kinds.test.js +1 -1
  144. package/dist/core/__tests__/plugin-page-components.test.js +1 -1
  145. package/dist/core/__tests__/preview-registry-sync.test.js +42 -1
  146. package/dist/core/__tests__/respawn-throttle.test.js +0 -4
  147. package/dist/core/__tests__/revive-all.test.js +5 -5
  148. package/dist/core/__tests__/revive-parked-fresh.test.js +62 -11
  149. package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +0 -8
  150. package/dist/core/__tests__/seam/broker-attach-stream.test.js +0 -8
  151. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +0 -2
  152. package/dist/core/__tests__/tmux-driver-boundary.test.d.ts +1 -0
  153. package/dist/core/__tests__/tmux-driver-boundary.test.js +50 -0
  154. package/dist/core/activity-signal.d.ts +7 -0
  155. package/dist/core/activity-signal.js +38 -0
  156. package/dist/core/auto-update.js +2 -1
  157. package/dist/core/bootstrap.js +2 -1
  158. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
  159. package/dist/core/canvas/__tests__/remote-transport.test.js +1 -1
  160. package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
  161. package/dist/core/canvas/browse/app.js +3 -2
  162. package/dist/core/canvas/browse/model.d.ts +1 -1
  163. package/dist/core/canvas/browse/model.js +0 -4
  164. package/dist/core/canvas/canvas.d.ts +22 -0
  165. package/dist/core/canvas/canvas.js +50 -18
  166. package/dist/core/canvas/crons.js +0 -6
  167. package/dist/core/canvas/db.d.ts +14 -20
  168. package/dist/core/canvas/db.js +30 -1332
  169. package/dist/core/canvas/focuses.js +0 -4
  170. package/dist/core/canvas/history.js +2 -1
  171. package/dist/core/canvas/migrations.d.ts +20 -0
  172. package/dist/core/canvas/migrations.js +1339 -0
  173. package/dist/core/canvas/nav-model.js +1 -11
  174. package/dist/core/canvas/nav-render.js +0 -8
  175. package/dist/core/canvas/remote-canvas-source.js +0 -2
  176. package/dist/core/canvas/render-source.js +31 -13
  177. package/dist/core/command-manifests/manifest.js +0 -10
  178. package/dist/core/command-manifests/schema.js +0 -4
  179. package/dist/core/command-plugins/transport/http-invoke.js +0 -14
  180. package/dist/core/command.js +0 -4
  181. package/dist/core/config.js +2 -1
  182. package/dist/core/feed/inbox.d.ts +10 -0
  183. package/dist/core/feed/inbox.js +18 -12
  184. package/dist/core/fs-utils.d.ts +9 -2
  185. package/dist/core/fs-utils.js +7 -15
  186. package/dist/core/help.js +0 -8
  187. package/dist/core/host-exports/export.d.ts +2 -2
  188. package/dist/core/host-exports/export.js +9 -12
  189. package/dist/core/human/answer.d.ts +2 -2
  190. package/dist/core/human/convention.d.ts +2 -5
  191. package/dist/core/human/convention.js +3 -13
  192. package/dist/core/human/page-schema.d.ts +2 -2
  193. package/dist/core/human/page-schema.js +2 -2
  194. package/dist/core/human/root.js +6 -23
  195. package/dist/core/human/scan.js +24 -7
  196. package/dist/core/human/tickets.d.ts +4 -1
  197. package/dist/core/human/tickets.js +20 -6
  198. package/dist/core/io.js +0 -12
  199. package/dist/core/memory/identity.js +0 -4
  200. package/dist/core/memory/inline-ref-inventory.js +3 -2
  201. package/dist/core/memory/lint.js +3 -6
  202. package/dist/core/memory-resolver.d.ts +5 -0
  203. package/dist/core/memory-resolver.js +14 -12
  204. package/dist/core/pagination.js +0 -2
  205. package/dist/core/preview-registry.d.ts +14 -0
  206. package/dist/core/preview-registry.js +2 -4
  207. package/dist/core/preview-result-path.js +2 -1
  208. package/dist/core/profiles/manifest.d.ts +37 -5
  209. package/dist/core/profiles/manifest.js +44 -24
  210. package/dist/core/profiles/select.js +0 -4
  211. package/dist/core/review/signal.js +4 -23
  212. package/dist/core/review/ticket-filter.d.ts +3 -3
  213. package/dist/core/review/ticket-filter.js +4 -9
  214. package/dist/core/runtime/__tests__/engine-route.test.js +1 -1
  215. package/dist/core/runtime/__tests__/spawn-env.test.js +0 -8
  216. package/dist/core/runtime/bearings-render.d.ts +56 -0
  217. package/dist/core/runtime/bearings-render.js +241 -0
  218. package/dist/core/runtime/bearings.d.ts +2 -17
  219. package/dist/core/runtime/bearings.js +12 -198
  220. package/dist/core/runtime/broker/auth-reload.d.ts +39 -0
  221. package/dist/core/runtime/broker/auth-reload.js +149 -0
  222. package/dist/core/runtime/broker/engine-drive.d.ts +26 -0
  223. package/dist/core/runtime/broker/engine-drive.js +257 -0
  224. package/dist/core/runtime/broker/engine-routing.d.ts +143 -0
  225. package/dist/core/runtime/broker/engine-routing.js +211 -0
  226. package/dist/core/runtime/broker/event-projection.js +3 -2
  227. package/dist/core/runtime/broker/fault-retry.js +5 -4
  228. package/dist/core/runtime/broker/frame-client.d.ts +38 -0
  229. package/dist/core/runtime/broker/frame-client.js +129 -0
  230. package/dist/core/runtime/broker/frame-dispatch.d.ts +12 -189
  231. package/dist/core/runtime/broker/frame-dispatch.js +89 -1476
  232. package/dist/core/runtime/broker/frame-engine-control.d.ts +20 -0
  233. package/dist/core/runtime/broker/frame-engine-control.js +231 -0
  234. package/dist/core/runtime/broker/frame-memory-refs.d.ts +19 -0
  235. package/dist/core/runtime/broker/frame-memory-refs.js +41 -0
  236. package/dist/core/runtime/broker/frame-model-query.d.ts +13 -0
  237. package/dist/core/runtime/broker/frame-model-query.js +69 -0
  238. package/dist/core/runtime/broker/frame-read.d.ts +19 -0
  239. package/dist/core/runtime/broker/frame-read.js +116 -0
  240. package/dist/core/runtime/broker/frame-replies.d.ts +24 -0
  241. package/dist/core/runtime/broker/frame-replies.js +64 -0
  242. package/dist/core/runtime/broker/frame-session.d.ts +34 -0
  243. package/dist/core/runtime/broker/frame-session.js +203 -0
  244. package/dist/core/runtime/broker/turn-ignition.d.ts +42 -0
  245. package/dist/core/runtime/broker/turn-ignition.js +74 -0
  246. package/dist/core/runtime/broker-extension-render.js +9 -85
  247. package/dist/core/runtime/broker-protocol.js +0 -4
  248. package/dist/core/runtime/broker-sdk.js +2 -1
  249. package/dist/core/runtime/broker.d.ts +1 -1
  250. package/dist/core/runtime/broker.js +5 -23
  251. package/dist/core/runtime/fault.js +3 -2
  252. package/dist/core/runtime/headless-pi.js +3 -2
  253. package/dist/core/runtime/host.js +2 -3
  254. package/dist/core/runtime/kickoff.js +0 -4
  255. package/dist/core/runtime/launch-target.js +2 -1
  256. package/dist/core/runtime/launch.js +3 -6
  257. package/dist/core/runtime/lifecycle.js +17 -26
  258. package/dist/core/runtime/managed-provider-cooling.d.ts +1 -1
  259. package/dist/core/runtime/naming.js +0 -2
  260. package/dist/core/runtime/nodes.js +2 -1
  261. package/dist/core/runtime/persona.js +0 -6
  262. package/dist/core/runtime/placement-tmux.js +2 -5
  263. package/dist/core/runtime/placement.js +4 -11
  264. package/dist/core/runtime/recap.js +4 -3
  265. package/dist/core/runtime/reopen.js +4 -7
  266. package/dist/core/runtime/reset.js +0 -4
  267. package/dist/core/runtime/resume-root.js +0 -2
  268. package/dist/core/runtime/revive.js +17 -13
  269. package/dist/core/runtime/session-list-cache.js +2 -2
  270. package/dist/core/runtime/shell-expansion.js +0 -2
  271. package/dist/core/runtime/spawn.js +0 -2
  272. package/dist/core/runtime/stream-watchdog.d.ts +0 -1
  273. package/dist/core/runtime/stream-watchdog.js +13 -18
  274. package/dist/core/runtime/tmux-bindings.js +0 -2
  275. package/dist/core/runtime/tmux-driver.d.ts +12 -0
  276. package/dist/core/runtime/tmux-driver.js +18 -13
  277. package/dist/core/runtime/warm-pool.js +0 -4
  278. package/dist/core/scope.js +4 -3
  279. package/dist/core/spawn.js +2 -3
  280. package/dist/core/subscription-state.js +10 -17
  281. package/dist/core/substrate/__tests__/surface-match-pre-command.test.js +3 -3
  282. package/dist/core/substrate/render.js +0 -12
  283. package/dist/core/substrate/schema.js +0 -12
  284. package/dist/core/substrate/surface-match.js +0 -2
  285. package/dist/core/termrender/display.js +2 -1
  286. package/dist/core/tui/page-host.d.ts +3 -3
  287. package/dist/core/tui/page-host.js +4 -4
  288. package/dist/core/tui/panel.js +3 -3
  289. package/dist/core/wake.js +0 -12
  290. package/dist/core/worktree.js +0 -2
  291. package/dist/daemon/__tests__/reconciler-signature.test.d.ts +1 -0
  292. package/dist/daemon/__tests__/reconciler-signature.test.js +36 -0
  293. package/dist/daemon/api/__tests__/seam/api-server.test.js +2 -16
  294. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +3 -11
  295. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +0 -6
  296. package/dist/daemon/api/handlers/attach.js +2 -1
  297. package/dist/daemon/api/handlers/broker-ops.js +3 -6
  298. package/dist/daemon/api/handlers/canvas.js +12 -18
  299. package/dist/daemon/api/handlers/feedback-comments.js +0 -8
  300. package/dist/daemon/api/handlers/health.js +3 -2
  301. package/dist/daemon/api/handlers/human-requests.js +0 -10
  302. package/dist/daemon/api/handlers/human.js +1 -5
  303. package/dist/daemon/api/handlers/inbox.js +0 -18
  304. package/dist/daemon/api/handlers/memory.js +1 -1
  305. package/dist/daemon/api/handlers/messages.js +4 -8
  306. package/dist/daemon/api/handlers/nodes.js +10 -21
  307. package/dist/daemon/api/handlers/reports.js +1 -1
  308. package/dist/daemon/api/handlers/reviews.js +1 -6
  309. package/dist/daemon/api/map.js +0 -6
  310. package/dist/daemon/api/router.js +0 -4
  311. package/dist/daemon/api/server.js +2 -5
  312. package/dist/daemon/boot-migrations.d.ts +14 -0
  313. package/dist/daemon/boot-migrations.js +31 -0
  314. package/dist/daemon/cron/armed-context.d.ts +21 -0
  315. package/dist/daemon/cron/armed-context.js +100 -0
  316. package/dist/daemon/cron/capture.d.ts +20 -0
  317. package/dist/daemon/cron/capture.js +45 -0
  318. package/dist/daemon/cron/disposition.d.ts +19 -0
  319. package/dist/daemon/cron/disposition.js +52 -0
  320. package/dist/daemon/cron/escalation.d.ts +12 -0
  321. package/dist/daemon/cron/escalation.js +124 -0
  322. package/dist/daemon/cron/held.d.ts +4 -0
  323. package/dist/daemon/cron/held.js +20 -0
  324. package/dist/daemon/cron/lease-recovery.d.ts +3 -0
  325. package/dist/daemon/cron/lease-recovery.js +119 -0
  326. package/dist/daemon/cron/live-runs.d.ts +11 -0
  327. package/dist/daemon/cron/live-runs.js +23 -0
  328. package/dist/daemon/cron/passes.d.ts +11 -0
  329. package/dist/daemon/cron/passes.js +78 -0
  330. package/dist/daemon/cron/settle.d.ts +28 -0
  331. package/dist/daemon/cron/settle.js +37 -0
  332. package/dist/daemon/cron/sinks.d.ts +2 -0
  333. package/dist/daemon/cron/sinks.js +100 -0
  334. package/dist/daemon/cron-run.d.ts +5 -41
  335. package/dist/daemon/cron-run.js +193 -882
  336. package/dist/daemon/crtrd-cli.js +2 -1
  337. package/dist/daemon/crtrd.js +22 -22
  338. package/dist/daemon/fleet.js +0 -4
  339. package/dist/daemon/human/deliver-action.js +2 -1
  340. package/dist/daemon/human/sweep.js +15 -4
  341. package/dist/daemon/manage.d.ts +2 -2
  342. package/dist/daemon/manage.js +4 -13
  343. package/dist/daemon/pidfile.js +2 -2
  344. package/dist/daemon/reconcilers/broker-supervision.js +26 -29
  345. package/dist/daemon/reconcilers/dormant-inbox.d.ts +1 -1
  346. package/dist/daemon/reconcilers/dormant-inbox.js +2 -1
  347. package/dist/daemon/reconcilers/live-obligation.js +2 -2
  348. package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
  349. package/dist/daemon/reconcilers/pending-review-submit.js +2 -1
  350. package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -1
  351. package/dist/daemon/reconcilers/storage-maintenance.js +2 -1
  352. package/dist/daemon/review/companion.js +2 -2
  353. package/dist/daemon/review/sweep.js +8 -3
  354. package/dist/migrations/001-surfaces-frontmatter.js +0 -6
  355. package/dist/migrations/corpus.js +2 -5
  356. package/dist/migrations/registry.js +15 -2
  357. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +0 -4
  358. package/dist/pi-extensions/broker-local.js +2 -1
  359. package/dist/pi-extensions/canvas-bash-valve.js +3 -17
  360. package/dist/pi-extensions/canvas-context-intro.js +2 -7
  361. package/dist/pi-extensions/canvas-doc-substrate.js +2 -3
  362. package/dist/pi-extensions/canvas-goal-capture.js +2 -1
  363. package/dist/pi-extensions/canvas-inbox-watcher.js +5 -12
  364. package/dist/pi-extensions/canvas-passive-context.js +2 -5
  365. package/dist/pi-extensions/canvas-preview-result.js +2 -1
  366. package/dist/pi-extensions/canvas-prompt-scrub.js +2 -1
  367. package/dist/pi-extensions/canvas-recap.js +3 -16
  368. package/dist/pi-extensions/canvas-review-boundary.js +2 -5
  369. package/dist/pi-extensions/canvas-stophook.js +2 -26
  370. package/dist/pi-extensions/canvas-structured-output.js +2 -1
  371. package/dist/pi-extensions/canvas-tool-guide.js +2 -1
  372. package/dist/shared/__tests__/env-boundary.test.d.ts +1 -0
  373. package/dist/shared/__tests__/env-boundary.test.js +93 -0
  374. package/dist/shared/env.d.ts +68 -0
  375. package/dist/shared/env.js +171 -0
  376. package/package.json +3 -1
  377. package/runtime.lock.json +2 -2
  378. package/dist/core/canvas/render.d.ts +0 -47
  379. package/dist/core/canvas/render.js +0 -245
@@ -9,6 +9,7 @@
9
9
  //
10
10
  // TRANSPORT (spec O-1): `node:http`/`node:https` `request()` — NO `undici`.
11
11
  // unix socket via `{ socketPath }`; TCP/remote via a parsed `baseUrl`.
12
+ import { envHomeOverride } from '../shared/env.js';
12
13
  import { request as httpRequest } from 'node:http';
13
14
  import { request as httpsRequest } from 'node:https';
14
15
  import { homedir } from 'node:os';
@@ -27,7 +28,7 @@ const SOCKET_BASENAME = 'crtrd.sock';
27
28
  /** Resolve crtrd's default unix socket path the same way `apiSocketPath()` does,
28
29
  * via Node built-ins only (no `core/canvas/paths.ts` import). */
29
30
  function defaultSocketPath() {
30
- const override = process.env['CRTR_HOME'];
31
+ const override = envHomeOverride();
31
32
  const home = override !== undefined && override !== ''
32
33
  ? override
33
34
  : join(homedir(), CRTR_DIR_NAME, 'canvas');
@@ -74,7 +75,7 @@ export class CrtrClient {
74
75
  static forLocalSocket(opts) {
75
76
  return new CrtrClient({ socketPath: defaultSocketPath(), autostart: true, ...opts });
76
77
  }
77
- // ---- Health / status ---------------------------------------------------
78
+ // Health / status
78
79
  healthz() {
79
80
  return this.request('GET', routes.healthz());
80
81
  }
@@ -88,7 +89,7 @@ export class CrtrClient {
88
89
  restartDaemon() {
89
90
  return this.request('POST', routes.daemonRestart());
90
91
  }
91
- // ---- Nodes -------------------------------------------------------------
92
+ // Nodes
92
93
  createNode(req) {
93
94
  return this.request('POST', routes.nodes(), req);
94
95
  }
@@ -178,7 +179,7 @@ export class CrtrClient {
178
179
  subscribe(id, req) {
179
180
  return this.request('POST', routes.nodeSubscriptions(this.nodePath(id)), req);
180
181
  }
181
- // ---- Focuses (viewer registry) ----------------------------------------
182
+ // Focuses (viewer registry)
182
183
  // The tmux verbs that open/move/close a viewer pane run LOCALLY in the
183
184
  // caller's session (placement-tmux); only the canvas.db focus rows route here.
184
185
  // Reads GC lazily server-side, so a returned row is always live; a `null` body
@@ -245,7 +246,7 @@ export class CrtrClient {
245
246
  ensureAttach(id, req) {
246
247
  return this.request('POST', routes.nodeAttach(this.nodePath(id)), req ?? {});
247
248
  }
248
- // ---- Reads / feed ------------------------------------------------------
249
+ // Reads / feed
249
250
  getReports(id, q) {
250
251
  return this.request('GET', withQuery(routes.nodeReports(this.nodePath(id)), q));
251
252
  }
@@ -283,20 +284,20 @@ export class CrtrClient {
283
284
  getContext(id) {
284
285
  return this.request('GET', routes.nodeContext(this.nodePath(id)));
285
286
  }
286
- // ---- Host file read ----------------------------------------------------
287
+ // Host file read
287
288
  /** Read an absolute host path as UTF-8 (capped, `truncated` when clipped) for
288
289
  * the browser file-peek panel. */
289
290
  peekFile(path) {
290
291
  return this.request('GET', withQuery(routes.filePeek(), { path }));
291
292
  }
292
- // ---- Memory documents --------------------------------------------------
293
+ // Memory documents
293
294
  /** Resolve an exact canonical `[[name]]` memory-document link to the winning
294
295
  * document's physical origin for the given node — the node's own precedence
295
296
  * chain, not this process's. Pair with `peekFile` to render the document. */
296
297
  resolveMemoryDoc(name, nodeId) {
297
298
  return this.request('GET', withQuery(routes.memoryResolve(), { name, node: nodeId }));
298
299
  }
299
- // ---- Profiles ----------------------------------------------------------
300
+ // Profiles
300
301
  /** Create-or-return by name. Supplied `projects` are shape-checked even when
301
302
  * the profile already exists; their directories are only required to exist
302
303
  * when this call creates the profile. */
@@ -317,7 +318,7 @@ export class CrtrClient {
317
318
  deleteProfile(name, req) {
318
319
  return this.request('DELETE', routes.profile(name), req);
319
320
  }
320
- // ---- Model auth --------------------------------------------------------
321
+ // Model auth
321
322
  listModelAuth() {
322
323
  return this.request('GET', routes.modelAuths());
323
324
  }
@@ -327,7 +328,7 @@ export class CrtrClient {
327
328
  removeCredential(provider) {
328
329
  return this.request('DELETE', routes.modelAuth(provider));
329
330
  }
330
- // ---- Human bridge + completion-handler forwarding (spec §6.5) ----------
331
+ // Human bridge + completion-handler forwarding (spec §6.5)
331
332
  /** Create a terminal `kind:'human'` bridge node with NO broker engine
332
333
  * (`spawnNode` server-side). Distinct from `createNode` (which launches a
333
334
  * broker) precisely because a human bridge must never have one. */
@@ -344,7 +345,7 @@ export class CrtrClient {
344
345
  cancelHumanTicket(ticketId, body) {
345
346
  return this.request('POST', routes.humanTicketCancel(this.interactionPath(ticketId)), body);
346
347
  }
347
- // ---- Daemon-owned document reviews and comments -----------------------
348
+ // Daemon-owned document reviews and comments
348
349
  createReview(req) {
349
350
  return this.request('POST', routes.humanReviews(), req);
350
351
  }
@@ -433,7 +434,7 @@ export class CrtrClient {
433
434
  cancelHumanInboxTicket(ticketId, request) {
434
435
  return this.request('POST', routes.humanInboxCancel(this.ticketId(ticketId)), request ?? {});
435
436
  }
436
- // ---- Durable programmatic human requests -------------------------------
437
+ // Durable programmatic human requests
437
438
  /** Create one durable human request. Its `request_id` is the same opaque id
438
439
  * the inbox routes address, so the request and the inbox ticket are one
439
440
  * record. An unresolvable `action.name` is rejected before the page is
@@ -474,7 +475,7 @@ export class CrtrClient {
474
475
  }
475
476
  return this.request('POST', routes.humanInboxFeedbackResolve(this.ticketId(ticketId), commentId), { node_id: nodeId });
476
477
  }
477
- // ---- Canvas reads / maintenance ---------------------------------------
478
+ // Canvas reads / maintenance
478
479
  /** Composed client-side from `GET /v1/nodes` + `GET /v1/status` (spec §6.3 —
479
480
  * the dashboard is absorbed into those two reads; there is no single route).
480
481
  * `generated_at` is the client-side capture instant of the composition. */
@@ -527,7 +528,7 @@ export class CrtrClient {
527
528
  rebuildIndex() {
528
529
  return this.request('POST', routes.canvasRebuildIndex(), {});
529
530
  }
530
- // ---- Escape hatch ------------------------------------------------------
531
+ // Escape hatch
531
532
  /** Raw request for routes not yet method-wrapped. Applies the same
532
533
  * autostart + error-mapping semantics. */
533
534
  async request(method, path, body) {
@@ -549,7 +550,7 @@ export class CrtrClient {
549
550
  throw toTransportApiError(err);
550
551
  }
551
552
  }
552
- // ---- internals ---------------------------------------------------------
553
+ // internals
553
554
  nodePath(id) {
554
555
  if (!isSafeNodeId(id)) {
555
556
  throw new ApiError(400, 'invalid_node_id', `invalid node id: ${JSON.stringify(id)}`);
@@ -2223,7 +2223,7 @@ test("a concrete model's headerless usage-limit stays turn-local and carries its
2223
2223
  }
2224
2224
  });
2225
2225
 
2226
- // --- Provider-management removal routing and login coordination ---
2226
+ // Provider-management removal routing and login coordination
2227
2227
 
2228
2228
  function readAuthRecord(providerId: string): unknown {
2229
2229
  const authPath = join(home, ".pi", "agent", "auth.json");
@@ -1,4 +1,5 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
1
+ import { envProfileId } from '../../../shared/env.js';
2
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
3
  import {
3
4
  readFileSync,
4
5
  readdirSync,
@@ -8,15 +9,14 @@ import {
8
9
  rmSync,
9
10
  writeFileSync,
10
11
  realpathSync,
11
- } from "node:fs";
12
- import { homedir } from "node:os";
13
- import { join, resolve, dirname } from "node:path";
14
- import { loadProfileManifest } from "../../../core/profiles/manifest.js";
15
- import { stripMarkdownComments } from "../../../core/runtime/command-expansion.js";
16
- import { expandShellBlocks, DEFAULT_SHELL_TIMEOUT_MS } from "../../../core/runtime/shell-expansion.js";
17
- import { piShellRunner } from "./pi-shell-runner.js";
18
-
19
- // ---------------------------------------------------------------------------
12
+ } from 'node:fs';
13
+ import { homedir } from 'node:os';
14
+ import { join, resolve, dirname } from 'node:path';
15
+ import { loadProfileManifest } from '../../../core/profiles/manifest.js';
16
+ import { stripMarkdownComments } from '../../../core/runtime/command-expansion.js';
17
+ import { expandShellBlocks, DEFAULT_SHELL_TIMEOUT_MS } from '../../../core/runtime/shell-expansion.js';
18
+ import { piShellRunner } from './pi-shell-runner.js';
19
+
20
20
  // claude-plugin-commands: surfaces Claude Code commands AND skills as pi slash
21
21
  // commands, with Claude's `plugin:command` namespacing AND full runtime
22
22
  // behavior: `$1/$ARGUMENTS` argument substitution and `!`cmd` / ```! shell
@@ -43,7 +43,6 @@ import { piShellRunner } from "./pi-shell-runner.js";
43
43
  // BEFORE expansion, read the ORIGINAL source file, substitute args, run
44
44
  // the embedded shell, and `transform` the input to the resolved text.
45
45
  // Shell-execution logic mirrors @juicesharp/rpiv-args.
46
- // ---------------------------------------------------------------------------
47
46
 
48
47
  const HOME = homedir();
49
48
  const CLAUDE = join(HOME, ".claude");
@@ -67,7 +66,7 @@ type InstallRecord = { installPath?: string };
67
66
  type InstalledPlugins = { plugins?: Record<string, InstallRecord[]> };
68
67
  type Shim = { name: string; target: string; kind: Kind; baseDir: string };
69
68
 
70
- // ---- discovery ------------------------------------------------------------
69
+ // discovery
71
70
 
72
71
  function collectCommands(root: string, prefix: string[], rel: string[], out: Shim[]): void {
73
72
  if (!existsSync(root)) return;
@@ -161,7 +160,7 @@ export function projectClaudeDirs(cwd: string, profileProjectDirs: readonly stri
161
160
  }
162
161
 
163
162
  function selectedProfileProjects(): string[] {
164
- const profileId = process.env["CRTR_PROFILE_ID"] ?? "";
163
+ const profileId = envProfileId() ?? "";
165
164
  if (profileId === "") return [];
166
165
  try {
167
166
  return loadProfileManifest(profileId).manifest.projects.map((project) => project.path);
@@ -289,7 +288,7 @@ function buildShims(cwd: string): string {
289
288
  return SHIM_DIR;
290
289
  }
291
290
 
292
- // ---- argument substitution (mirrors pi's prompt-template engine) -----------
291
+ // argument substitution (mirrors pi's prompt-template engine)
293
292
 
294
293
  function parseCommandArgs(s: string): string[] {
295
294
  const args: string[] = [];
@@ -367,7 +366,7 @@ function shellTimeoutMs(fm: string): number {
367
366
  return v === 0 ? 0 : v * 1000;
368
367
  }
369
368
 
370
- // ---- shell execution (mirrors @juicesharp/rpiv-args) -----------------------
369
+ // shell execution (mirrors @juicesharp/rpiv-args)
371
370
  //
372
371
  // The `!`cmd`` / ```! grammar and substitution order are shared with every
373
372
  // other surface that expands a Markdown body (`core/runtime/shell-expansion`);
@@ -377,8 +376,6 @@ async function executeShell(body: string, pi: ExtensionAPI, cwd: string, timeout
377
376
  return expandShellBlocks(body, piShellRunner(pi, cwd, timeoutMs));
378
377
  }
379
378
 
380
- // ---------------------------------------------------------------------------
381
-
382
379
  export default function (pi: ExtensionAPI) {
383
380
  pi.on("resources_discover", async (event: { cwd?: string }) => {
384
381
  const dir = buildShims(event?.cwd ?? process.cwd());
@@ -1,14 +1,13 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { execFile } from "node:child_process";
3
- import { promisify } from "node:util";
4
- import { readFileSync, existsSync, realpathSync } from "node:fs";
5
- import { fileURLToPath, pathToFileURL } from "node:url";
6
- import { dirname, join } from "node:path";
7
- import type { ChatCommandMetadata } from "../../../../core/runtime/command-surface.js";
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ import { execFile } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
+ import { readFileSync, existsSync, realpathSync } from 'node:fs';
5
+ import { fileURLToPath, pathToFileURL } from 'node:url';
6
+ import { dirname, join } from 'node:path';
7
+ import type { ChatCommandMetadata } from '../../../../core/runtime/command-surface.js';
8
8
 
9
9
  const exec = promisify(execFile);
10
10
 
11
- // ---------------------------------------------------------------------------
12
11
  // crtr-commands: auto-generates a slash command for every node in the crtr
13
12
  // CLI tree. `/node:new` runs `crtr node new -h`; `/node:list`
14
13
  // runs `crtr node list -h`, and so on.
@@ -26,7 +25,6 @@ const exec = promisify(execFile);
26
25
  //
27
26
  // Registered handlers still shell out to the real `crtr` binary, but only
28
27
  // when the user invokes one — never on the boot path.
29
- // ---------------------------------------------------------------------------
30
28
 
31
29
  const HERE = dirname(fileURLToPath(import.meta.url));
32
30
  const FILTERS_PATH = join(HERE, "filters.json");
@@ -76,9 +74,7 @@ export function isAllowed(name: string, filters: Filters): boolean {
76
74
  return true;
77
75
  }
78
76
 
79
- // ---------------------------------------------------------------------------
80
77
  // Locate + import crtr's real command tree (mirrors crtr-help-gate.ts).
81
- // ---------------------------------------------------------------------------
82
78
 
83
79
  async function resolveCrtrDist(): Promise<string | null> {
84
80
  const dirs = (process.env.PATH ?? "").split(":");
@@ -65,12 +65,12 @@
65
65
  * .pi/extensions/. Run `npm install` here once so `yaml` resolves.
66
66
  */
67
67
 
68
- import type { ExtensionAPI, ToolResultEvent } from "@earendil-works/pi-coding-agent";
69
- import * as fs from "node:fs";
70
- import * as os from "node:os";
71
- import * as path from "node:path";
72
- import { parse as parseYaml } from "yaml";
73
- import { mergeAutoLoadedContext } from "../../../../pi-extensions/envelope-merge.js";
68
+ import type { ExtensionAPI, ToolResultEvent } from '@earendil-works/pi-coding-agent';
69
+ import * as fs from 'node:fs';
70
+ import * as os from 'node:os';
71
+ import * as path from 'node:path';
72
+ import { parse as parseYaml } from 'yaml';
73
+ import { mergeAutoLoadedContext } from '../../../../pi-extensions/envelope-merge.js';
74
74
 
75
75
  const MARKDOWN_EXTS = new Set([".md", ".mdx", ".markdown"]);
76
76
 
@@ -198,7 +198,7 @@ function parseRuleFile(filePath: string): Rule {
198
198
  return { name, description, when: front.when, body: (m[2] ?? "").trim() };
199
199
  }
200
200
 
201
- // ---- Condition language ----------------------------------------------------
201
+ // Condition language
202
202
 
203
203
  function asArray(v: unknown): unknown[] {
204
204
  if (Array.isArray(v)) return v;
@@ -323,7 +323,7 @@ function evalCondition(cond: unknown, fm: Frontmatter): boolean {
323
323
  return keys.every((k) => matchField(getField(fm, k), c[k]));
324
324
  }
325
325
 
326
- // ---- Extension -------------------------------------------------------------
326
+ // Extension
327
327
 
328
328
  export default function frontmatterRules(pi: ExtensionAPI) {
329
329
  const seen = new Set<string>();
@@ -1,12 +1,13 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { createMemoryDocSnapshot, readMemoryDocContent } from "../../../commands/memory/read.js";
3
- import { parseSubstrateDoc } from "../../../core/substrate/schema.js";
1
+ import { envNodeId } from '../../../shared/env.js';
2
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
3
+ import { createMemoryDocSnapshot, readMemoryDocContent } from '../../../core/memory-resolver.js';
4
+ import { parseSubstrateDoc } from '../../../core/substrate/schema.js';
4
5
  import {
5
6
  expandDeterministicCommand,
6
7
  type DeterministicCommandExpansion,
7
- } from "../../../core/runtime/command-expansion.js";
8
- import { expandShellBlocks, hasShellBlocks, DEFAULT_SHELL_TIMEOUT_MS } from "../../../core/runtime/shell-expansion.js";
9
- import type { ChatCommandMetadata } from "../../../core/runtime/command-surface.js";
8
+ } from '../../../core/runtime/command-expansion.js';
9
+ import { expandShellBlocks, hasShellBlocks, DEFAULT_SHELL_TIMEOUT_MS } from '../../../core/runtime/shell-expansion.js';
10
+ import type { ChatCommandMetadata } from '../../../core/runtime/command-surface.js';
10
11
  import {
11
12
  exposureTarget,
12
13
  loadContextExposureState,
@@ -14,10 +15,9 @@ import {
14
15
  registerDocumentExposure,
15
16
  saveContextExposureState,
16
17
  sharedContextExposureState,
17
- } from "../../../core/substrate/injected-store.js";
18
- import { piShellRunner } from "./pi-shell-runner.js";
18
+ } from '../../../core/substrate/injected-store.js';
19
+ import { piShellRunner } from './pi-shell-runner.js';
19
20
 
20
- // ---------------------------------------------------------------------------
21
21
  // memory-slash-commands: any memory doc frontmatter-flagged `slash: true`
22
22
  // becomes an invocable slash command (`/<name>`). This mirrors Hermes Agent's
23
23
  // "every skill is automatically a slash command" — /research-alpha injects
@@ -28,7 +28,6 @@ import { piShellRunner } from "./pi-shell-runner.js";
28
28
  // resolution. The snapshot already resolves exact canonical identities in
29
29
  // source precedence; this file does not walk memory directories or reimplement
30
30
  // scope resolution.
31
- // ---------------------------------------------------------------------------
32
31
 
33
32
  interface MemoryListItem {
34
33
  name: string;
@@ -86,7 +85,7 @@ function defaultReadMemoryDoc(name: string): { path: string; canonicalBody: stri
86
85
  }
87
86
 
88
87
  function registerSlashExposure(path: string, body: string): void {
89
- const nodeId = process.env["CRTR_NODE_ID"];
88
+ const nodeId = envNodeId();
90
89
  if (nodeId === undefined || nodeId === "") return;
91
90
  const state = sharedContextExposureState(nodeId);
92
91
  mergeContextExposureState(state, loadContextExposureState(nodeId));
@@ -1,5 +1,5 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { truncateTail, formatSize, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES } from "@earendil-works/pi-coding-agent";
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ import { truncateTail, formatSize, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES } from '@earendil-works/pi-coding-agent';
3
3
 
4
4
  // The broker-side execution strategy for `core/runtime/shell-expansion`. Every
5
5
  // command surface that expands a Markdown body inside a pi engine shares it, so
@@ -1,6 +1,6 @@
1
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import { type AssistantMessageEventStream, type Context, type Model, type SimpleStreamOptions } from "@earendil-works/pi-ai";
3
- import { type ManagedProviderId, type SubscriptionCredential } from "../../../core/subscription-state.js";
1
+ import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';
2
+ import { type AssistantMessageEventStream, type Context, type Model, type SimpleStreamOptions } from '@earendil-works/pi-ai';
3
+ import { type ManagedProviderId, type SubscriptionCredential } from '../../../core/subscription-state.js';
4
4
  export interface ProviderRotationOptions {
5
5
  modelIntent?: string;
6
6
  nodeCwd?: string;
@@ -1,10 +1,10 @@
1
- import { spawn } from "node:child_process";
2
- import { createAssistantMessageEventStream, } from "@earendil-works/pi-ai";
3
- import { streamSimpleAnthropic, streamSimpleOpenAICodexResponses } from "@earendil-works/pi-ai/compat";
4
- import { ANTHROPIC_PROVIDER_ID, OPENAI_CODEX_PROVIDER_ID, INVALID_REFRESH_TOKEN_BACKOFF_MS, formatStatusLine, getProviderLabel, isManagedProvider, isInvalidRefreshTokenError, addSubscription, enrichManagedLoginIdentity, markSubscriptionAuthenticationFailed, markSubscriptionRateLimited, markSubscriptionSuccess, parseRetryAfterHeader, promoteSubscription, readRotationConfig, readSubscriptionPool, refreshSubscriptionCredential, removeManagedAccount, resolveProviderCandidates, upsertSubscriptionWithUniqueAccount, } from "../../../core/subscription-state.js";
5
- import { readMergedLaunchConfig } from "../../../core/config.js";
6
- import { expandModelCandidates, modelRequestFromConfig, probeRouteAvailability } from "../../../core/model-routes.js";
7
- import { ManagedProviderCoolingError } from "../../../core/runtime/managed-provider-cooling.js";
1
+ import { spawn } from 'node:child_process';
2
+ import { createAssistantMessageEventStream, } from '@earendil-works/pi-ai';
3
+ import { streamSimpleAnthropic, streamSimpleOpenAICodexResponses } from '@earendil-works/pi-ai/compat';
4
+ import { ANTHROPIC_PROVIDER_ID, OPENAI_CODEX_PROVIDER_ID, INVALID_REFRESH_TOKEN_BACKOFF_MS, formatStatusLine, getProviderLabel, isManagedProvider, isInvalidRefreshTokenError, addSubscription, enrichManagedLoginIdentity, markSubscriptionAuthenticationFailed, markSubscriptionRateLimited, markSubscriptionSuccess, parseRetryAfterHeader, promoteSubscription, readRotationConfig, readSubscriptionPool, refreshSubscriptionCredential, removeManagedAccount, resolveProviderCandidates, upsertSubscriptionWithUniqueAccount, } from '../../../core/subscription-state.js';
5
+ import { readMergedLaunchConfig } from '../../../core/config.js';
6
+ import { expandModelCandidates, modelRequestFromConfig, probeRouteAvailability } from '../../../core/model-routes.js';
7
+ import { ManagedProviderCoolingError } from '../../../core/runtime/managed-provider-cooling.js';
8
8
  // A response without Retry-After proves only that THIS attempt was throttled; it
9
9
  // does not authorize crouter to invent a five-minute provider-wide outage. Keep
10
10
  // a short turn-local probe backoff to avoid an immediate retry loop, then let a
@@ -1,5 +1,5 @@
1
- import { spawn } from "node:child_process";
2
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
1
+ import { spawn } from 'node:child_process';
2
+ import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';
3
3
  import {
4
4
  createAssistantMessageEventStream,
5
5
  type AssistantMessage,
@@ -11,8 +11,8 @@ import {
11
11
  type Model,
12
12
  type OAuthAuth,
13
13
  type SimpleStreamOptions,
14
- } from "@earendil-works/pi-ai";
15
- import { streamSimpleAnthropic, streamSimpleOpenAICodexResponses } from "@earendil-works/pi-ai/compat";
14
+ } from '@earendil-works/pi-ai';
15
+ import { streamSimpleAnthropic, streamSimpleOpenAICodexResponses } from '@earendil-works/pi-ai/compat';
16
16
  import {
17
17
  ANTHROPIC_PROVIDER_ID,
18
18
  OPENAI_CODEX_PROVIDER_ID,
@@ -36,10 +36,10 @@ import {
36
36
  upsertSubscriptionWithUniqueAccount,
37
37
  type ManagedProviderId,
38
38
  type SubscriptionCredential,
39
- } from "../../../core/subscription-state.js";
40
- import { readMergedLaunchConfig } from "../../../core/config.js";
41
- import { expandModelCandidates, modelRequestFromConfig, probeRouteAvailability } from "../../../core/model-routes.js";
42
- import { ManagedProviderCoolingError } from "../../../core/runtime/managed-provider-cooling.js";
39
+ } from '../../../core/subscription-state.js';
40
+ import { readMergedLaunchConfig } from '../../../core/config.js';
41
+ import { expandModelCandidates, modelRequestFromConfig, probeRouteAvailability } from '../../../core/model-routes.js';
42
+ import { ManagedProviderCoolingError } from '../../../core/runtime/managed-provider-cooling.js';
43
43
 
44
44
  // A response without Retry-After proves only that THIS attempt was throttled; it
45
45
  // does not authorize crouter to invent a five-minute provider-wide outage. Keep
@@ -11,10 +11,10 @@
11
11
  * navigation and interactive chrome live in crouter's attach viewer.
12
12
  */
13
13
 
14
- import { execFile } from "node:child_process";
15
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
16
- import { CustomEditor, type ExtensionContext } from "@earendil-works/pi-coding-agent";
17
- import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
14
+ import { execFile } from 'node:child_process';
15
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
16
+ import { CustomEditor, type ExtensionContext } from '@earendil-works/pi-coding-agent';
17
+ import { truncateToWidth, visibleWidth } from '@earendil-works/pi-tui';
18
18
 
19
19
  function lastDir(cwd: string): string {
20
20
  const trimmed = cwd.replace(/\/+$/, "");
@@ -178,7 +178,7 @@ function borderWithBadge(
178
178
 
179
179
  export default function (pi: ExtensionAPI) {
180
180
  pi.on("session_start", (_event, ctx) => {
181
- // --- Statusline (footer): model · [subscription] · tokens · cycle, with cwd/git right-aligned ---
181
+ // Statusline (footer): model · [subscription] · tokens · cycle, with cwd/git right-aligned
182
182
  ctx.ui.setFooter((tui, theme, footerData) => {
183
183
  let gitStatus: GitStatus | null = null;
184
184
 
@@ -217,7 +217,7 @@ export default function (pi: ExtensionAPI) {
217
217
  };
218
218
  });
219
219
 
220
- // --- Input bar border: session-name badge with solid background ---
220
+ // Input bar border: session-name badge with solid background
221
221
  // Compose with whatever editor is already installed instead of replacing it:
222
222
  // wrap the previous factory in a Proxy that overrides only render
223
223
  // (session-name badge on the top border). Other editor decorations keep
@@ -1,6 +1,6 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { execFile } from "node:child_process";
3
- import { promisify } from "node:util";
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ import { execFile } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
4
 
5
5
  const exec = promisify(execFile);
6
6
  const CRTR = "crtr";
@@ -1,2 +1,2 @@
1
1
  // Provider pool state belongs to crouter core so every human surface and the rotation runtime share one invariant-preserving implementation.
2
- export * from "../../../core/subscription-state.js";
2
+ export * from '../../../core/subscription-state.js';
@@ -145,7 +145,15 @@ export function createTicketPanel(s, hooks) {
145
145
  reload(entry);
146
146
  return;
147
147
  }
148
- const result = readTicketResult(entry.dir);
148
+ let result;
149
+ try {
150
+ result = readTicketResult(entry.dir);
151
+ }
152
+ catch (error) {
153
+ closeSession(true);
154
+ hooks.setNotice(`ticket result is unreadable: ${error instanceof Error ? error.message : String(error)}`);
155
+ return;
156
+ }
149
157
  if (result !== null) {
150
158
  closeSession(true);
151
159
  hooks.setNotice(result.kind === 'canceled' ? 'Ticket was canceled by its requester' : 'Ticket was resolved elsewhere');
@@ -203,7 +211,12 @@ export function createTicketPanel(s, hooks) {
203
211
  };
204
212
  }
205
213
  function resolvedElsewhereNotice(dir) {
206
- return readTicketResult(dir)?.kind === 'canceled' ? 'Ticket was already canceled' : 'Ticket was already resolved';
214
+ try {
215
+ return readTicketResult(dir)?.kind === 'canceled' ? 'Ticket was already canceled' : 'Ticket was already resolved';
216
+ }
217
+ catch (error) {
218
+ return `ticket result is unreadable: ${error instanceof Error ? error.message : String(error)}`;
219
+ }
207
220
  }
208
221
  /** The SGR opening the theme's `customMessageBg` — the background the crouter
209
222
  * context cards use. pi shares its live theme across module loaders on this
@@ -203,7 +203,6 @@ export class GraphOverlay {
203
203
  invalidate() {
204
204
  this.refresh();
205
205
  }
206
- // -------------------------------------------------------------------------
207
206
  async buildSnapshot() {
208
207
  beginFrameTelem();
209
208
  const nodes = new Map();
@@ -444,7 +443,6 @@ export class GraphOverlay {
444
443
  const fill = Math.max(0, width - 5 - visibleWidth(lbl));
445
444
  return `${B(`${lc}─`)} ${lbl} ${B('─'.repeat(fill) + rc)}`;
446
445
  }
447
- // -------------------------------------------------------------------------
448
446
  handleInput(data) {
449
447
  try {
450
448
  this.dispatch(data);
@@ -611,7 +609,6 @@ export class GraphOverlay {
611
609
  // Modal: swallow everything else so a stray
612
610
  // key never reaches the editor underneath.
613
611
  }
614
- // -------------------------------------------------------------------------
615
612
  /** Focus node `id` from the overlay by shelling `crtr surface node focus <id> --pane <here>`.
616
613
  * Under the one-viewer-per-node model `--pane` is the ANCHOR to open beside: if
617
614
  * `id` has no viewer yet a fresh one splits beside this pane; if it already has
@@ -147,7 +147,7 @@ function readConfigSource(path, cwd, home) {
147
147
  }
148
148
  return mergeServerMaps(imported, own);
149
149
  }
150
- // --- configHash recomputation — mirrors pi-mcp-adapter metadata-cache.ts ----
150
+ // configHash recomputation — mirrors pi-mcp-adapter metadata-cache.ts
151
151
  function interpolateEnvVars(value) {
152
152
  return value
153
153
  .replace(/\$\{(\w+)\}/g, (_, name) => process.env[name] ?? '')
@@ -204,7 +204,6 @@ function computeServerHash(spec) {
204
204
  };
205
205
  return createHash('sha256').update(stableStringify(identity)).digest('hex');
206
206
  }
207
- // ---------------------------------------------------------------------------
208
207
  /** Read + merge the adapter's config sources (see file header) and join the
209
208
  * tool cache into display rows. Returns [] when nothing is configured. */
210
209
  export function readMcpServers(home = homedir(), cwd = process.cwd()) {
@@ -419,9 +419,7 @@ export class ChatView {
419
419
  transcriptSource() {
420
420
  return this.transcript;
421
421
  }
422
- // -------------------------------------------------------------------------
423
422
  // Catch-up: render the welcome snapshot, then live events resume.
424
- // -------------------------------------------------------------------------
425
423
  /** Render the full message history from a `welcome` snapshot. Ports pi's
426
424
  * `renderSessionContext` (interactive-mode.js:2553): assistant messages spawn
427
425
  * tool-execution components matched to their toolResult messages; everything
@@ -664,11 +662,9 @@ export class ChatView {
664
662
  dispose() {
665
663
  this.settleRun();
666
664
  }
667
- // -------------------------------------------------------------------------
668
665
  // Global display toggles (Ctrl+O / Ctrl+T), driven by the input controller.
669
666
  // Pure client-side render state — no broker round-trip — ported from pi's
670
667
  // `setToolsExpanded` / `toggleThinkingBlockVisibility`.
671
- // -------------------------------------------------------------------------
672
668
  /** Ctrl+O prefers summaries when the user enabled both folding and summary
673
669
  * generation. */
674
670
  toggleToolsExpanded() {
@@ -733,10 +729,8 @@ export class ChatView {
733
729
  this.tui.requestRender();
734
730
  return this.hideThinking;
735
731
  }
736
- // -------------------------------------------------------------------------
737
732
  // Live stream: the 15-of-17-case handleEvent port (turn_start/turn_end no-op,
738
733
  // exactly as interactive pi falls through default for those two).
739
- // -------------------------------------------------------------------------
740
734
  handleEvent(event) {
741
735
  // Order behind an in-flight catch-up: a live turn that starts while a large
742
736
  // welcome is still building is replayed after it, never interleaved into it.
@@ -986,12 +980,10 @@ export class ChatView {
986
980
  // independent status loader animates.
987
981
  this.tui.requestRender();
988
982
  }
989
- // -------------------------------------------------------------------------
990
983
  // `!` bash live stream (broker bash_start/bash_output/bash_end frames). Mirrors
991
984
  // pi interactive mode's `!` handling: create the component on start, stream
992
985
  // chunks into it, mark complete on end. The persisted `bashExecution` message
993
986
  // also rides the next snapshot, so this only drives the LIVE view.
994
- // -------------------------------------------------------------------------
995
987
  bashStart(command, excludeFromContext) {
996
988
  if (this.deferIfBuilding(() => this.bashStart(command, excludeFromContext)))
997
989
  return;
@@ -1022,9 +1014,7 @@ export class ChatView {
1022
1014
  this.settleBashComponent(result);
1023
1015
  this.tui.requestRender();
1024
1016
  }
1025
- // -------------------------------------------------------------------------
1026
1017
  // Rebuild path (ports addMessageToChat, interactive-mode.js:2483).
1027
- // -------------------------------------------------------------------------
1028
1018
  addMessageToChat(message) {
1029
1019
  // Crouter-generated context retains its runtime role (user vs custom) so
1030
1020
  // delivery to the model is unchanged, but every attached view presents it
@@ -1166,9 +1156,7 @@ export class ChatView {
1166
1156
  break;
1167
1157
  }
1168
1158
  }
1169
- // -------------------------------------------------------------------------
1170
1159
  // Helpers
1171
- // -------------------------------------------------------------------------
1172
1160
  /** Render an assistant reply plus its initially-hidden boundary separator.
1173
1161
  * A turn that ended on its own abort is rendered as the interrupt it is,
1174
1162
  * matching the live seam above, so re-reading the transcript later never
@@ -255,9 +255,7 @@ export function renderCrtrOutputText(text, theme, preserveSyntax = false) {
255
255
  const body = text || '(no output)';
256
256
  return body.split('\n').map((line) => lineStyle(line, theme, preserveSyntax)).join('\n');
257
257
  }
258
- // ---------------------------------------------------------------------------
259
258
  // Help preview synthesis
260
- // ---------------------------------------------------------------------------
261
259
  //
262
260
  // A collapsed `-h` card must never just parrot the call header (the command
263
261
  // path, already shown by renderCall) or bottom out in a bare "(schema — ctrl+o