@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
@@ -0,0 +1,149 @@
1
+ import { AUTH_FAULT_RECOVERY_BODY, formatCard, } from '../../../shared/generated-context.js';
2
+ import { envModelIntent } from '../../../shared/env.js';
3
+ import { emitEvent } from '../../events/emit.js';
4
+ import { clearFault, readFault } from '../fault.js';
5
+ import { isUnknownModel } from '../model-selection.js';
6
+ export function createAuthReloadGate(deps) {
7
+ const { nodeId, cfg, replies, rebind, session, services, broadcastModelChanged, formatModelSpec, resolveLaunchModel, driveKickoff, } = deps;
8
+ let reloadInFlight = null;
9
+ let faultRedriveInFlight = false;
10
+ /** True once the engine this work started against has been replaced — every
11
+ * step of both flows re-checks it before touching the session again. */
12
+ const supersededBy = (generation, boundSession) => rebind.installedGeneration() !== generation || session() !== boundSession;
13
+ /** Rebuild the model snapshot against re-read credentials and reconcile the
14
+ * session's model with the launch route. */
15
+ const runAuthReload = async (generation, authSession, authServices) => {
16
+ // Credentials are read fresh by PoolCredentialStore; only the
17
+ // ModelRuntime snapshot needs rebuilding. Authentication reloads
18
+ // never fetch provider catalogs over the network.
19
+ await authServices.modelRuntime.refresh({ allowNetwork: false });
20
+ if (supersededBy(generation, authSession))
21
+ return;
22
+ const modelLess = authSession.model === undefined || isUnknownModel(authSession.model);
23
+ const reconcilesLogicalRoute = cfg.modelExact !== true &&
24
+ cfg.modelProviderPinned !== true &&
25
+ (envModelIntent() ?? '').trim() !== '';
26
+ if (modelLess || reconcilesLogicalRoute) {
27
+ const resolved = await resolveLaunchModel(authServices, cfg);
28
+ if (supersededBy(generation, authSession))
29
+ return;
30
+ if (resolved !== undefined) {
31
+ const currentSpec = formatModelSpec(authSession.model, authSession.thinkingLevel);
32
+ const resolvedSpec = formatModelSpec(resolved.model, resolved.thinkingLevel);
33
+ if (resolvedSpec !== null && resolvedSpec !== currentSpec) {
34
+ await authSession.setModel(resolved.model);
35
+ if (supersededBy(generation, authSession))
36
+ return;
37
+ authSession.setThinkingLevel((resolved.thinkingLevel ?? 'off'));
38
+ }
39
+ }
40
+ }
41
+ if (supersededBy(generation, authSession))
42
+ return;
43
+ // Persist an algorithmic route choice without clearing the logical
44
+ // intent that makes future reconciliation possible.
45
+ await broadcastModelChanged();
46
+ driveKickoff();
47
+ };
48
+ /** Start (or join) this generation's reconcile. */
49
+ const startAuthReload = () => {
50
+ const generation = rebind.installedGeneration();
51
+ const existing = reloadInFlight;
52
+ if (existing !== null && existing.generation === generation)
53
+ return existing.promise;
54
+ if (generation === undefined)
55
+ return undefined;
56
+ const authSession = session();
57
+ const authServices = services();
58
+ const promise = runAuthReload(generation, authSession, authServices).catch((err) => {
59
+ emitEvent({
60
+ level: 'warn',
61
+ event: 'broker.auth_reload.reconcile_failed',
62
+ error: err,
63
+ });
64
+ });
65
+ const work = { generation, promise };
66
+ reloadInFlight = work;
67
+ void promise.finally(() => {
68
+ if (reloadInFlight === work)
69
+ reloadInFlight = null;
70
+ });
71
+ return promise;
72
+ };
73
+ /** Rewind to the entry the recorded auth fault killed and re-drive the turn
74
+ * with the recovery prompt — once, after the reconcile it depends on. */
75
+ const redriveAuthFault = (reload) => {
76
+ const authFault = readFault(nodeId);
77
+ const generation = rebind.installedGeneration();
78
+ const faultSession = session();
79
+ if (authFault?.link !== 'pi→provider' ||
80
+ authFault.kind !== 'auth' ||
81
+ faultSession.isStreaming ||
82
+ faultRedriveInFlight)
83
+ return;
84
+ faultRedriveInFlight = true;
85
+ void (async () => {
86
+ try {
87
+ if (reload !== undefined)
88
+ await reload;
89
+ if (supersededBy(generation, faultSession))
90
+ return;
91
+ const anchorEntryId = authFault.anchorEntryId;
92
+ if (anchorEntryId !== undefined) {
93
+ try {
94
+ const leafId = faultSession.sessionManager.getLeafId?.() ?? null;
95
+ if (leafId !== anchorEntryId)
96
+ await faultSession.navigateTree(anchorEntryId);
97
+ if (supersededBy(generation, faultSession))
98
+ return;
99
+ }
100
+ catch (err) {
101
+ emitEvent({
102
+ level: 'warn',
103
+ event: 'broker.auth_fault.rewind_skipped',
104
+ error: err,
105
+ });
106
+ }
107
+ }
108
+ const fresh = readFault(nodeId);
109
+ if (supersededBy(generation, faultSession) ||
110
+ faultSession.isStreaming ||
111
+ fresh?.link !== 'pi→provider' ||
112
+ fresh.kind !== 'auth' ||
113
+ fresh.since !== authFault.since)
114
+ return;
115
+ clearFault(nodeId, { link: 'pi→provider' });
116
+ await faultSession.prompt(formatCard('recovery', {}, AUTH_FAULT_RECOVERY_BODY));
117
+ }
118
+ catch (err) {
119
+ emitEvent({
120
+ level: 'error',
121
+ event: 'broker.auth_fault.redrive_failed',
122
+ error: err,
123
+ });
124
+ }
125
+ finally {
126
+ faultRedriveInFlight = false;
127
+ }
128
+ })();
129
+ };
130
+ return {
131
+ inFlight: () => reloadInFlight?.promise,
132
+ handle(client) {
133
+ // Open to any client, observers included: reload_auth is an idempotent
134
+ // local re-read of shared credentials + the runtime's availability
135
+ // snapshot. It does not steer the conversation, so the daemon's
136
+ // canvas-wide /login fan can ride an observer connection.
137
+ try {
138
+ replies.ackTo(client, 'reload_auth');
139
+ redriveAuthFault(startAuthReload());
140
+ }
141
+ catch (err) {
142
+ replies.engineErrorTo(client)(err);
143
+ }
144
+ },
145
+ resetForSession() {
146
+ reloadInFlight = null;
147
+ },
148
+ };
149
+ }
@@ -0,0 +1,26 @@
1
+ import type { ClientToBroker } from '../broker-protocol.js';
2
+ import type { BrokerClient, BrokerClientRegistry } from './client-registry.js';
3
+ import type { EventProjection } from './event-projection.js';
4
+ import type { MemoryRefGuidance } from './frame-memory-refs.js';
5
+ import type { FrameReplies } from './frame-replies.js';
6
+ import type { AuthReloadGate } from './auth-reload.js';
7
+ import type { BrokerSession } from './read-ops.js';
8
+ import type { RebindDriver } from './rebind.js';
9
+ import type { ToolGroupTracker } from './tool-groups.js';
10
+ import type { PromptDispatchTracker } from './turn-ignition.js';
11
+ /** The frames that drive the live engine — the viewer's input vocabulary. */
12
+ export type DriveFrame = Extract<ClientToBroker, {
13
+ type: 'prompt' | 'steer' | 'follow_up' | 'abort' | 'bash';
14
+ }>;
15
+ export type EngineDriver = (client: BrokerClient, frame: DriveFrame) => Promise<unknown> | undefined;
16
+ export declare function createEngineDriver(deps: {
17
+ registry: BrokerClientRegistry;
18
+ replies: FrameReplies;
19
+ session: () => BrokerSession;
20
+ dispatches: PromptDispatchTracker;
21
+ memoryRefs: MemoryRefGuidance;
22
+ authReloadGate: AuthReloadGate;
23
+ rebind: RebindDriver;
24
+ projection: EventProjection;
25
+ toolGroups: ToolGroupTracker;
26
+ }): EngineDriver;
@@ -0,0 +1,257 @@
1
+ import { emitEvent } from '../../events/emit.js';
2
+ import { operationIdContext } from '../../events/operation-id.js';
3
+ import { promptWithAdvertisedCommandInvocation } from '../advertised-command-invocation.js';
4
+ import { chooseGuidanceDeliveryMode, promptWithNextTurnGuidance, resolveEngineRoute, resolveSteerCall, } from './engine-routing.js';
5
+ export function createEngineDriver(deps) {
6
+ const { registry, replies, session, dispatches, memoryRefs, authReloadGate, rebind, projection, toolGroups, } = deps;
7
+ const { ackTo, engineErrorTo } = replies;
8
+ const errorRelay = (client) => {
9
+ let failure;
10
+ return {
11
+ relay: (err) => {
12
+ failure = err;
13
+ registry.sendFrame(client, {
14
+ type: 'error',
15
+ code: 'engine_error',
16
+ message: String(err),
17
+ });
18
+ },
19
+ failure: () => failure,
20
+ };
21
+ };
22
+ // Hidden `crtr-memory-refs` guidance rides ALONGSIDE the human frame's own
23
+ // engine call, never rewriting `frame.text` — see MemoryRefGuidance /
24
+ // chooseGuidanceDeliveryMode. A failed SEND (as opposed to a failed
25
+ // resolve, handled above) is likewise logged-and-swallowed: it must never
26
+ // reach the error relay, which is reserved for the human call's own outcome.
27
+ const sendGuidance = (guidance, deliverAs) => session()
28
+ .sendCustomMessage({ customType: 'crtr-memory-refs', content: guidance, display: false }, { deliverAs })
29
+ .catch((err) => {
30
+ emitEvent({
31
+ level: 'warn',
32
+ event: 'broker.memory_refs.guidance_send_failed',
33
+ error: err,
34
+ });
35
+ });
36
+ const drivePromptOrFollowUp = (client, frame, errors) => {
37
+ const relayError = errors.relay;
38
+ // Settle on the engine call's outcome: the failure is set by relayError
39
+ // before the caught promise resolves, so reading it after the chain is
40
+ // the call's verdict.
41
+ const settle = (p) => p.then(() => errors.failure());
42
+ const dispatch = () => {
43
+ const route = resolveEngineRoute(frame, session().isStreaming);
44
+ const guidance = memoryRefs.guidanceFor(frame.text);
45
+ if (guidance === null) {
46
+ if (route.call === 'prompt') {
47
+ // A routed prompt STARTS a turn — including an idle follow_up
48
+ // escalated by m-C — so it gets a fresh operation id. A true
49
+ // (mid-stream) followUp rides the current turn's operation, like
50
+ // steer.
51
+ return settle(dispatches.track(operationIdContext.fresh(() => promptWithAdvertisedCommandInvocation(session(), frame.text, () => session().prompt(frame.text, route.options)).catch(relayError))));
52
+ }
53
+ // C1: pi's followUp() takes images as a POSITIONAL 2nd arg (`followUp(text, images?)`).
54
+ return settle(session().followUp(frame.text, frame.images).catch(relayError));
55
+ }
56
+ const deliverAs = chooseGuidanceDeliveryMode(frame.type, route.call, session().isStreaming);
57
+ if (route.call === 'prompt') {
58
+ if (deliverAs === 'nextTurn') {
59
+ // The ONLY ordering where guidance precedes the human call — pi's
60
+ // prompt() reads+clears its pending-nextTurn queue synchronously
61
+ // at call time, injecting it into the SAME turn as the new user
62
+ // message. promptWithNextTurnGuidance queues the guidance and then
63
+ // ATOMICALLY clears its own pending entry if prompt() settles
64
+ // without ever reaching that drain (an early throw/return leaves
65
+ // nothing stranded to leak into a later, unrelated turn).
66
+ return settle(dispatches.track(promptWithNextTurnGuidance(session(), guidance, () => operationIdContext.fresh(() => promptWithAdvertisedCommandInvocation(session(), frame.text, () => session().prompt(frame.text, route.options)))).catch(relayError)));
67
+ }
68
+ return settle(dispatches.track(operationIdContext.fresh(() => promptWithAdvertisedCommandInvocation(session(), frame.text, () => session().prompt(frame.text, route.options))
69
+ .catch(relayError)
70
+ .then(() => sendGuidance(guidance, deliverAs)))));
71
+ }
72
+ // deliverAs is always 'followUp' here per chooseGuidanceDeliveryMode's
73
+ // contract (a followUp routeCall never yields 'nextTurn').
74
+ return settle(session()
75
+ .followUp(frame.text, frame.images)
76
+ .catch(relayError)
77
+ .then(() => sendGuidance(guidance, deliverAs)));
78
+ };
79
+ // /login acknowledges before its asynchronous local refresh completes.
80
+ // An idle turn must not overtake that refresh and launch on the stale
81
+ // route; true mid-stream follow-ups keep their immediate queue behavior.
82
+ const authReload = session().isStreaming
83
+ ? undefined
84
+ : authReloadGate.inFlight();
85
+ if (authReload === undefined)
86
+ return dispatch();
87
+ const waitingGeneration = rebind.installedGeneration();
88
+ const waitingSession = session();
89
+ return authReload.then(() => {
90
+ if (rebind.installedGeneration() !== waitingGeneration ||
91
+ session() !== waitingSession) {
92
+ relayError(new Error('session changed while prompt waited for authentication reload'));
93
+ return errors.failure();
94
+ }
95
+ return dispatch();
96
+ });
97
+ };
98
+ /**
99
+ * `prompt { interrupt: true }` is one atomic viewer intention: end whatever
100
+ * is producing now, then start this as a new turn. A normal mid-stream
101
+ * prompt deliberately steers into pi's queue; the whip must not.
102
+ */
103
+ const driveInterruptPrompt = (client, frame, errors) => (async () => {
104
+ if (session().isBashRunning) {
105
+ session().abortBash();
106
+ }
107
+ else {
108
+ // A prompt can be in pi's async setup before isStreaming flips. Match
109
+ // the correlated interrupt's guard so a whip cannot silently miss it.
110
+ await dispatches.waitUntilAbortable();
111
+ if (session().isStreaming)
112
+ await session().abort();
113
+ }
114
+ return drivePromptOrFollowUp(client, {
115
+ type: 'prompt',
116
+ text: frame.text,
117
+ ...(frame.images !== undefined ? { images: frame.images } : {}),
118
+ }, errorRelay(client));
119
+ })().catch((err) => {
120
+ errors.relay(err);
121
+ return errors.failure();
122
+ });
123
+ /**
124
+ * A viewer submits ordinary text as `steer` while the agent is running,
125
+ * including a slash command injected by the tmux prefix menu. pi's steer()
126
+ * deliberately rejects registered extension commands because they cannot be
127
+ * queued; prompt() performs the command preflight first and executes it
128
+ * immediately even while streaming. It also expands a matching
129
+ * skill/template before applying the same steer behavior.
130
+ */
131
+ const driveSteer = (frame, errors) => {
132
+ const relayError = errors.relay;
133
+ if (resolveSteerCall(frame.text, session()) === 'prompt') {
134
+ void promptWithAdvertisedCommandInvocation(session(), frame.text, () => session().prompt(frame.text, {
135
+ images: frame.images,
136
+ streamingBehavior: 'steer',
137
+ })).catch(relayError);
138
+ return;
139
+ }
140
+ const guidance = memoryRefs.guidanceFor(frame.text);
141
+ // C1: pi's steer() takes images as a POSITIONAL 2nd arg (`steer(text, images?)`).
142
+ if (guidance === null) {
143
+ void session().steer(frame.text, frame.images).catch(relayError);
144
+ return;
145
+ }
146
+ void session()
147
+ .steer(frame.text, frame.images)
148
+ .catch(relayError)
149
+ .then(() => sendGuidance(guidance, 'steer'));
150
+ };
151
+ /**
152
+ * esc/abort cancels whatever is live: a running `!` command (abortBash)
153
+ * takes precedence over the agent turn, mirroring pi interactive mode.
154
+ */
155
+ const driveAbort = (client, frame, errors) => {
156
+ if (session().isBashRunning) {
157
+ session().abortBash();
158
+ if (frame.id !== undefined)
159
+ ackTo(client, 'abort', true, 'bash', frame.id);
160
+ return;
161
+ }
162
+ if (frame.id === undefined) {
163
+ // A viewer's Esc — unchanged instant semantics, no ack.
164
+ void session().abort().catch(errors.relay);
165
+ return;
166
+ }
167
+ // An id-bearing abort (a one-shot daemon interrupt) must close the
168
+ // pre-turn window: a routed deliver whose prompt() is still in async
169
+ // setup reads as idle and abort() would silently miss it. If a prompt
170
+ // dispatch is pending, wait (bounded) for the run to become abortable
171
+ // — or for every dispatch to settle without one (an early return) —
172
+ // then abort and ack with what was actually interrupted.
173
+ void (async () => {
174
+ try {
175
+ await dispatches.waitUntilAbortable();
176
+ const detail = session().isStreaming ? 'turn' : 'idle';
177
+ await session().abort();
178
+ ackTo(client, 'abort', true, detail, frame.id);
179
+ }
180
+ catch (err) {
181
+ engineErrorTo(client, frame.id)(err);
182
+ }
183
+ })();
184
+ };
185
+ /**
186
+ * `!`/`!!` bash: run via session.executeBash (records a bashExecution context
187
+ * message, starts NO agent turn) and relay its lifecycle to ALL viewers as
188
+ * bash_start/bash_output/bash_end so each renders the live component.
189
+ * Serialized like pi's interactive mode — reject a second `!` while one is
190
+ * already running rather than racing _bashAbortController.
191
+ */
192
+ const driveBash = (client, frame, errors) => {
193
+ const command = frame.command;
194
+ if (command.trim() === '')
195
+ return;
196
+ if (session().isBashRunning) {
197
+ registry.sendFrame(client, {
198
+ type: 'error',
199
+ code: 'bash_busy',
200
+ message: 'A bash command is already running',
201
+ });
202
+ return;
203
+ }
204
+ const exclude = frame.excludeFromContext === true;
205
+ // Order before any held assistant message_update, so a `!` run mid-stream
206
+ // never renders ahead of the update it follows.
207
+ projection.flush();
208
+ // The live bash component is a visible transcript boundary, even though
209
+ // its persisted bashExecution message arrives later via the session.
210
+ toolGroups.finishOpenToolGroup();
211
+ registry.broadcast({
212
+ type: 'bash_start',
213
+ command,
214
+ excludeFromContext: exclude,
215
+ });
216
+ void session()
217
+ .executeBash(command, (chunk) => registry.broadcast({ type: 'bash_output', chunk }), { excludeFromContext: exclude })
218
+ .then((result) => {
219
+ registry.broadcast({
220
+ type: 'bash_end',
221
+ exitCode: result.exitCode,
222
+ cancelled: result.cancelled,
223
+ truncated: result.truncated,
224
+ fullOutputPath: result.fullOutputPath,
225
+ });
226
+ })
227
+ .catch(errors.relay);
228
+ };
229
+ /**
230
+ * Drive the engine for one client frame. For a prompt/follow_up frame this
231
+ * returns a promise that settles with the engine call's OUTCOME — `undefined`
232
+ * when the call succeeded, the rejection value when it did not — so a caller
233
+ * that must report success (the `deliver` ack) can read it instead of assuming
234
+ * the dispatch worked. Every other frame type keeps the fire-and-forget shape
235
+ * and returns `undefined`.
236
+ */
237
+ return (client, frame) => {
238
+ const errors = errorRelay(client);
239
+ switch (frame.type) {
240
+ case 'prompt':
241
+ return frame.interrupt === true
242
+ ? driveInterruptPrompt(client, frame, errors)
243
+ : drivePromptOrFollowUp(client, frame, errors);
244
+ case 'follow_up':
245
+ return drivePromptOrFollowUp(client, frame, errors);
246
+ case 'steer':
247
+ driveSteer(frame, errors);
248
+ return undefined;
249
+ case 'abort':
250
+ driveAbort(client, frame, errors);
251
+ return undefined;
252
+ case 'bash':
253
+ driveBash(client, frame, errors);
254
+ return undefined;
255
+ }
256
+ };
257
+ }
@@ -0,0 +1,143 @@
1
+ import type { PromptOptions } from '@earendil-works/pi-coding-agent';
2
+ import type { ImageContent } from '@earendil-works/pi-ai';
3
+ /**
4
+ * Route a writable client's `prompt`/`follow_up` frame against the LIVE session
5
+ * state. The client picks its frame type off a possibly-STALE `isStreaming`
6
+ * snapshot, so the broker is authoritative and the client's choice is a HINT:
7
+ *
8
+ * - m-B (streaming-safe prompt): a `prompt` arriving mid-stream needs
9
+ * PromptOptions.streamingBehavior ("Required if streaming"; prompt() throws
10
+ * without it). "steer" mirrors pi interactive-mode's own
11
+ * Enter-while-streaming submit (`prompt(text, { streamingBehavior: "steer" })`).
12
+ * - m-C (idle-safe follow_up): pi's followUp() only enqueues into a RUNNING
13
+ * agent loop — on an idle session nothing ever drains the queue and the text
14
+ * is silently lost. An idle `follow_up` therefore runs as a prompt now.
15
+ *
16
+ * driveEngine calls this synchronously with `session.isStreaming`, so the
17
+ * routed state cannot go stale between the check and the engine call.
18
+ * C1: images ride as a field on PromptOptions (pi: `prompt(text, { images })`).
19
+ */
20
+ export declare function resolveEngineRoute(frame: {
21
+ type: 'prompt' | 'follow_up';
22
+ images?: ImageContent[];
23
+ }, isStreaming: boolean): {
24
+ call: 'prompt';
25
+ options: PromptOptions;
26
+ } | {
27
+ call: 'followUp';
28
+ };
29
+ /**
30
+ * True iff `text` would be consumed by pi's OWN leading-name preflight before
31
+ * `session.prompt/steer/followUp` ever sees it as prose — an extension command
32
+ * (`session.extensionRunner.getCommand`), a `/skill:name` skill, or a `/name`
33
+ * prompt template (mirrors `_tryExecuteExtensionCommand` / `_expandSkillCommand`
34
+ * / `expandPromptTemplate` in the pinned SDK verbatim, including the exact
35
+ * name-parsing substrings). Inline memory-reference guidance must NEVER fire
36
+ * for these — the leading token routes to the engine's own command surface,
37
+ * not prose referencing a memory doc. Each lookup is independently wrapped so
38
+ * an engine missing one accessor (the fake, or a degraded session) degrades
39
+ * that check to "not a match" rather than aborting the whole classification —
40
+ * matching `buildCommandList`'s existing "no live extensionRunner" tolerance.
41
+ */
42
+ export declare function isLeadingEngineCommand(text: string, session: {
43
+ extensionRunner?: {
44
+ getCommand(name: string): unknown;
45
+ };
46
+ resourceLoader?: {
47
+ getSkills(): {
48
+ skills: Array<{
49
+ name: string;
50
+ }>;
51
+ };
52
+ };
53
+ promptTemplates?: ReadonlyArray<{
54
+ name: string;
55
+ }>;
56
+ }): boolean;
57
+ /** A `steer` frame normally maps directly to pi's steer queue. Engine commands,
58
+ * skills, and templates must instead pass through prompt()'s leading-command
59
+ * preflight; with streamingBehavior:'steer', ordinary expanded text still lands
60
+ * in the same queue. */
61
+ export declare function resolveSteerCall(text: string, session: Parameters<typeof isLeadingEngineCommand>[1]): 'prompt' | 'steer';
62
+ /**
63
+ * Enumerate every leading-token STRING this session's engine would
64
+ * independently consume as a leading command/skill/template dispatch BEFORE
65
+ * inline memory-reference guidance ever applies — the read-op sibling of
66
+ * `isLeadingEngineCommand`'s point-lookup, gathered as a full enumeration for
67
+ * viewer-side suppression instead of a per-submission membership check. Same
68
+ * three sources, same shape of the leading match `isLeadingEngineCommand`
69
+ * checks (bare extension-command invocation names and prompt-template names,
70
+ * `skill:<name>` for skills), so `/${token}` round-trips through
71
+ * `isLeadingEngineCommand(text, session)` for every emitted token (locked by
72
+ * a test). Kept STRICTLY separate from `buildCommandList` (command
73
+ * completion) and the ref inventory (`RefMeta` rows) — this is neither.
74
+ */
75
+ export declare function engineLeadingCommandTokens(session: {
76
+ extensionRunner?: {
77
+ getRegisteredCommands(): Array<{
78
+ invocationName: string;
79
+ }>;
80
+ };
81
+ resourceLoader?: {
82
+ getSkills(): {
83
+ skills: Array<{
84
+ name: string;
85
+ }>;
86
+ };
87
+ };
88
+ promptTemplates?: ReadonlyArray<{
89
+ name: string;
90
+ }>;
91
+ }): string[];
92
+ /**
93
+ * Choose how the hidden `crtr-memory-refs` guidance custom message rides
94
+ * alongside a human frame's own engine call (design Flow B). Pure over the
95
+ * frame's routing outcome — never reads live session state itself, so a
96
+ * caller can decide the delivery mode from the exact same `route`
97
+ * `resolveEngineRoute` already computed for the human call.
98
+ *
99
+ * - `steer` frame -> 'steer' (always; no route call exists).
100
+ * - a TRUE mid-stream follow_up (`routeCall === 'followUp'`) -> 'followUp'.
101
+ * - every other `prompt`/`follow_up` routed as `routeCall === 'prompt'`:
102
+ * idle -> 'nextTurn' (the ONLY case guidance precedes the human call —
103
+ * pi's `prompt()` reads+clears its pending-nextTurn queue synchronously
104
+ * into the SAME turn as the new user message); streaming (m-B
105
+ * steer-while-streaming) -> 'steer', never 'nextTurn' (that would attach
106
+ * to a later, unrelated turn).
107
+ */
108
+ export declare function chooseGuidanceDeliveryMode(frameType: 'prompt' | 'follow_up' | 'steer', routeCall: 'prompt' | 'followUp' | undefined, isStreaming: boolean): 'steer' | 'followUp' | 'nextTurn';
109
+ /**
110
+ * Deliver a `nextTurn` guidance custom message ATOMICALLY around the idle-
111
+ * prompt call it's meant to ride alongside. Pi's `_pendingNextTurnMessages`
112
+ * queue (the only public seam for `deliverAs:'nextTurn'`) is drained ONLY deep
113
+ * inside `session.prompt()`, well after several await points — extension-
114
+ * command interception, the `input` extension transform, a streaming reroute,
115
+ * model/auth validation, pre-turn compaction — that can return or throw BEFORE
116
+ * the drain ever runs. `sendCustomMessage`'s nextTurn branch pushes
117
+ * synchronously and unconditionally, so any of those early exits strands the
118
+ * pushed guidance in the queue to attach itself to whichever LATER, unrelated
119
+ * prompt happens to reach the drain first.
120
+ *
121
+ * There is no public SDK seam to observe or cancel a pending nextTurn message
122
+ * (`_pendingNextTurnMessages` is TS-`private` only — a plain runtime field, not
123
+ * `#private`), so this reaches into that one field and removes EXACTLY the
124
+ * entry this call pushed, identified by object identity via a locally-
125
+ * generated marker riding the message's own `details` field (never surfaced to
126
+ * the model, and irrelevant if the message WAS consumed normally — `details`
127
+ * is just carried through like any other field once folded into a real turn).
128
+ * Runs UNCONDITIONALLY after the human call settles, success or failure/early-
129
+ * return alike — a "successful" `prompt()` promise can just as easily be an
130
+ * early return that skipped the drain (an intercepted extension command, an
131
+ * `input` transform, a streaming reroute) as a genuine consumed turn, so only
132
+ * checking `.catch` is not enough.
133
+ */
134
+ export declare function promptWithNextTurnGuidance(session: {
135
+ sendCustomMessage(message: {
136
+ customType: string;
137
+ content: unknown;
138
+ display?: boolean;
139
+ details?: unknown;
140
+ }, options?: {
141
+ deliverAs?: 'steer' | 'followUp' | 'nextTurn';
142
+ }): Promise<void>;
143
+ }, guidance: string, runPrompt: () => Promise<void>): Promise<void>;