@north-light/crouter 0.3.349 → 0.3.350

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 (629) hide show
  1. package/bin/crtr-launcher +4 -0
  2. package/bin/runtime-generation-manifest.mjs +12 -2
  3. package/dist/api/client.d.ts +50 -7
  4. package/dist/api/client.js +2 -2
  5. package/dist/api/dto/analytics.d.ts +184 -0
  6. package/dist/api/dto/analytics.js +0 -0
  7. package/dist/api/dto/broker-ops.d.ts +43 -1
  8. package/dist/api/dto/config.d.ts +11 -0
  9. package/dist/api/dto/grants.d.ts +14 -0
  10. package/dist/api/dto/grants.js +0 -0
  11. package/dist/api/dto/human-requests.d.ts +14 -0
  12. package/dist/api/dto/memory.d.ts +6 -0
  13. package/dist/api/dto/modelauth.d.ts +35 -0
  14. package/dist/api/dto/node-records.d.ts +35 -0
  15. package/dist/api/dto/node-records.js +0 -0
  16. package/dist/api/dto/nodes.d.ts +5 -0
  17. package/dist/api/dto/profiles.d.ts +38 -3
  18. package/dist/api/dto/worktree.d.ts +11 -0
  19. package/dist/api/errors.d.ts +23 -1
  20. package/dist/api/errors.js +1 -1
  21. package/dist/api/index.d.ts +2 -0
  22. package/dist/api/index.js +1 -1
  23. package/dist/api/node-transport.js +1 -1
  24. package/dist/api/routes.d.ts +22 -0
  25. package/dist/api/routes.js +1 -1
  26. package/dist/build-root.d.ts +6 -1
  27. package/dist/build-root.js +1 -1
  28. package/dist/builtin-memory/crouter-sdk/client.md +34 -0
  29. package/dist/builtin-memory/crouter-sdk/errors.md +2 -0
  30. package/dist/builtin-memory/crouter-sdk/memory.md +2 -2
  31. package/dist/builtin-memory/crouter-sdk/streaming.md +21 -0
  32. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +8 -4
  33. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +39 -118
  34. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -1
  35. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +41 -27
  36. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +52 -29
  37. package/dist/cli.js +9 -8
  38. package/dist/clients/attach/chrome/inbox-strip.js +1 -1
  39. package/dist/clients/attach/chrome/roster.js +1 -1
  40. package/dist/clients/attach/config.js +1 -1
  41. package/dist/clients/attach/overlays/auth.js +2 -2
  42. package/dist/clients/attach/overlays/graph.js +1 -1
  43. package/dist/clients/attach/render/tool-calls.js +3 -3
  44. package/dist/clients/attach/session/connection.js +1 -1
  45. package/dist/clients/attach/session/profile-files.js +1 -1
  46. package/dist/clients/attach/viewer.js +1569 -816
  47. package/dist/commands/api-client.js +3 -3
  48. package/dist/commands/broker-permissions.d.ts +2 -0
  49. package/dist/commands/broker-permissions.js +1 -0
  50. package/dist/commands/canvas-analytics/chart.d.ts +52 -0
  51. package/dist/commands/canvas-analytics/chart.js +1 -0
  52. package/dist/commands/canvas-analytics/drilldown.d.ts +34 -0
  53. package/dist/commands/canvas-analytics/drilldown.js +1 -0
  54. package/dist/commands/canvas-analytics/format.d.ts +29 -0
  55. package/dist/commands/canvas-analytics/format.js +1 -0
  56. package/dist/commands/canvas-analytics/graph-detail.d.ts +2 -0
  57. package/dist/commands/canvas-analytics/graph-detail.js +2 -0
  58. package/dist/commands/canvas-analytics/graphs.d.ts +9 -0
  59. package/dist/commands/canvas-analytics/graphs.js +1 -0
  60. package/dist/commands/canvas-analytics/memory.d.ts +2 -0
  61. package/dist/commands/canvas-analytics/memory.js +1 -0
  62. package/dist/commands/canvas-analytics/overview.d.ts +2 -0
  63. package/dist/commands/canvas-analytics/overview.js +1 -0
  64. package/dist/commands/canvas-analytics/shell.d.ts +60 -0
  65. package/dist/commands/canvas-analytics/shell.js +2 -0
  66. package/dist/commands/canvas-analytics/time.d.ts +2 -0
  67. package/dist/commands/canvas-analytics/time.js +1 -0
  68. package/dist/commands/canvas-analytics/usage.d.ts +2 -0
  69. package/dist/commands/canvas-analytics/usage.js +1 -0
  70. package/dist/commands/canvas-analytics/view.d.ts +85 -0
  71. package/dist/commands/canvas-analytics/view.js +1 -0
  72. package/dist/commands/canvas-analytics.d.ts +2 -0
  73. package/dist/commands/canvas-analytics.js +1 -0
  74. package/dist/commands/canvas-prune.js +1 -1
  75. package/dist/commands/canvas.js +1 -1
  76. package/dist/commands/cron.js +5 -5
  77. package/dist/commands/human/components.d.ts +2 -0
  78. package/dist/commands/human/components.js +2 -2
  79. package/dist/commands/human/prompts.js +1 -1
  80. package/dist/commands/human/queue.js +1 -1
  81. package/dist/commands/memory/client.d.ts +11 -0
  82. package/dist/commands/memory/client.js +1 -0
  83. package/dist/commands/memory/delete.js +1 -1
  84. package/dist/commands/memory/edit.js +3 -3
  85. package/dist/commands/memory/find.js +1 -1
  86. package/dist/commands/memory/history.js +4 -4
  87. package/dist/commands/memory/lint.js +1 -1
  88. package/dist/commands/memory/list.d.ts +0 -2
  89. package/dist/commands/memory/list.js +1 -1
  90. package/dist/commands/memory/move.js +1 -1
  91. package/dist/commands/memory/origin.js +1 -1
  92. package/dist/commands/memory/read.d.ts +0 -5
  93. package/dist/commands/memory/read.js +3 -3
  94. package/dist/commands/memory/shared.d.ts +0 -178
  95. package/dist/commands/memory/shared.js +1 -12
  96. package/dist/commands/memory/write.js +5 -5
  97. package/dist/commands/node/bash.js +5 -5
  98. package/dist/commands/node/create.d.ts +0 -17
  99. package/dist/commands/node/create.js +2 -3
  100. package/dist/commands/node/inspect.js +6 -6
  101. package/dist/commands/node/lifecycle.js +2 -2
  102. package/dist/commands/node-context.js +2 -2
  103. package/dist/commands/node-inspect-artifacts.js +6 -6
  104. package/dist/commands/pkg/browse/catalog.js +1 -1
  105. package/dist/commands/pkg/browse/model.d.ts +1 -1
  106. package/dist/commands/pkg/market-manage.js +1 -1
  107. package/dist/commands/pkg/plugin-manage.js +10 -10
  108. package/dist/commands/profile/daemon-profiles.d.ts +13 -0
  109. package/dist/commands/profile/daemon-profiles.js +4 -0
  110. package/dist/commands/profile/delete.js +1 -1
  111. package/dist/commands/profile/env.d.ts +6 -0
  112. package/dist/commands/profile/env.js +2 -2
  113. package/dist/commands/profile/kind.js +1 -2
  114. package/dist/commands/profile/list.js +1 -1
  115. package/dist/commands/profile/meta.js +1 -1
  116. package/dist/commands/profile/new.js +1 -1
  117. package/dist/commands/profile/pause.js +1 -1
  118. package/dist/commands/profile/project.js +1 -1
  119. package/dist/commands/profile/rename.js +1 -1
  120. package/dist/commands/profile/show.js +1 -1
  121. package/dist/commands/profile.js +1 -1
  122. package/dist/commands/push.js +3 -3
  123. package/dist/commands/surface-inspect.js +1 -1
  124. package/dist/commands/sys/branch.js +1 -1
  125. package/dist/commands/sys/config.js +1 -1
  126. package/dist/commands/sys/connect.js +3 -3
  127. package/dist/commands/sys/context/admin/actions.js +1 -1
  128. package/dist/commands/sys/context/admin/model.d.ts +1 -0
  129. package/dist/commands/sys/context/admin/model.js +1 -1
  130. package/dist/commands/sys/context/admin.js +1 -1
  131. package/dist/commands/sys/context/expose.js +2 -1
  132. package/dist/commands/sys/context/prompt-review.js +2 -2
  133. package/dist/commands/sys/context/resolve.js +7 -7
  134. package/dist/commands/sys/context/sysprompt.js +1 -1
  135. package/dist/commands/sys/join.d.ts +1 -0
  136. package/dist/commands/sys/join.js +1 -0
  137. package/dist/commands/sys/migrate.js +1 -1
  138. package/dist/commands/sys/panels/models-panel.js +1 -1
  139. package/dist/commands/sys/panels/profiles-panel.d.ts +0 -1
  140. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  141. package/dist/commands/sys/provider-login.js +6 -6
  142. package/dist/commands/sys/setup-core.d.ts +1 -1
  143. package/dist/commands/sys/setup-core.js +6 -6
  144. package/dist/commands/sys/setup-settings-runner.js +1 -1
  145. package/dist/commands/sys/setup.js +1 -1
  146. package/dist/commands/sys/spaces.d.ts +1 -0
  147. package/dist/commands/sys/spaces.js +2 -0
  148. package/dist/commands/sys/sync-deps.js +2 -2
  149. package/dist/commands/sys/sync-project-guidance.js +4 -4
  150. package/dist/commands/sys/sync-skills.js +2 -2
  151. package/dist/commands/sys/worktrees.d.ts +1 -0
  152. package/dist/commands/sys/worktrees.js +1 -1
  153. package/dist/commands/sys.js +1 -1
  154. package/dist/core/auth-file.js +2 -2
  155. package/dist/core/bash-job-supervisor.d.ts +6 -0
  156. package/dist/core/bash-job-supervisor.js +4 -0
  157. package/dist/core/bash-jobs.d.ts +13 -6
  158. package/dist/core/bash-jobs.js +8 -7
  159. package/dist/core/broker-client/transport-relay.d.ts +6 -3
  160. package/dist/core/broker-client/transport-relay.js +1 -1
  161. package/dist/core/broker-client/transport-socket.d.ts +6 -1
  162. package/dist/core/broker-client/transport-socket.js +1 -1
  163. package/dist/core/canvas/canvas.d.ts +39 -18
  164. package/dist/core/canvas/canvas.js +21 -20
  165. package/dist/core/canvas/context-strip.d.ts +20 -0
  166. package/dist/core/canvas/context-strip.js +5 -0
  167. package/dist/core/canvas/crons.d.ts +12 -20
  168. package/dist/core/canvas/crons.js +15 -13
  169. package/dist/core/canvas/db.js +2 -2
  170. package/dist/core/canvas/deliveries.d.ts +4 -1
  171. package/dist/core/canvas/deliveries.js +1 -1
  172. package/dist/core/canvas/executions.js +1 -1
  173. package/dist/core/canvas/history.d.ts +2 -1
  174. package/dist/core/canvas/history.js +17 -18
  175. package/dist/core/canvas/memory-reads.d.ts +19 -0
  176. package/dist/core/canvas/memory-reads.js +1 -0
  177. package/dist/core/canvas/migrations.d.ts +0 -4
  178. package/dist/core/canvas/migrations.js +99 -32
  179. package/dist/core/canvas/nav-render.js +1 -1
  180. package/dist/core/canvas/node-agent-paths.d.ts +8 -0
  181. package/dist/core/canvas/node-agent-paths.js +1 -0
  182. package/dist/core/canvas/node-recap.d.ts +2 -2
  183. package/dist/core/canvas/node-recap.js +2 -2
  184. package/dist/core/canvas/node-tokens.d.ts +24 -0
  185. package/dist/core/canvas/node-tokens.js +5 -0
  186. package/dist/core/canvas/paths.d.ts +16 -19
  187. package/dist/core/canvas/paths.js +1 -1
  188. package/dist/core/canvas/render-source.d.ts +2 -2
  189. package/dist/core/canvas/render-source.js +6 -9
  190. package/dist/core/canvas/sessions.d.ts +18 -0
  191. package/dist/core/canvas/sessions.js +4 -1
  192. package/dist/core/canvas/types.d.ts +22 -6
  193. package/dist/core/command-hooks/compose.js +1 -1
  194. package/dist/core/command-hooks/discovery.d.ts +15 -1
  195. package/dist/core/command-hooks/discovery.js +1 -1
  196. package/dist/core/command-hooks/help.d.ts +2 -2
  197. package/dist/core/command-hooks/lifecycle-create.d.ts +1 -1
  198. package/dist/core/command-hooks/lifecycle-create.js +1 -1
  199. package/dist/core/command-hooks/transport/exec-invoke.d.ts +2 -0
  200. package/dist/core/command-hooks/transport/exec-invoke.js +1 -1
  201. package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +1 -0
  202. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  203. package/dist/core/command-hooks/transport/plan.d.ts +3 -0
  204. package/dist/core/command-hooks/transport/plan.js +1 -0
  205. package/dist/core/command-plugins/discovery.js +1 -1
  206. package/dist/core/command.d.ts +6 -2
  207. package/dist/core/command.js +6 -6
  208. package/dist/core/config.d.ts +8 -5
  209. package/dist/core/config.js +1 -1
  210. package/dist/core/conversation-store/client-worker.d.ts +1 -0
  211. package/dist/core/conversation-store/client-worker.js +1 -0
  212. package/dist/core/conversation-store/client.d.ts +2 -0
  213. package/dist/core/conversation-store/client.js +2 -0
  214. package/dist/core/conversation-store/file-store.d.ts +37 -0
  215. package/dist/core/conversation-store/file-store.js +9 -0
  216. package/dist/core/conversation-store/index.d.ts +50 -0
  217. package/dist/core/conversation-store/index.js +1 -0
  218. package/dist/core/conversation-store/listener.d.ts +4 -0
  219. package/dist/core/conversation-store/listener.js +3 -0
  220. package/dist/core/conversation-store/patch.d.ts +1 -0
  221. package/dist/core/conversation-store/patch.js +1 -0
  222. package/dist/core/directory/join.d.ts +27 -0
  223. package/dist/core/directory/join.js +1 -0
  224. package/dist/core/disk-usage.d.ts +4 -0
  225. package/dist/core/disk-usage.js +1 -0
  226. package/dist/core/events/emit.d.ts +2 -0
  227. package/dist/core/events/emit.js +3 -1
  228. package/dist/core/feed/feed.js +4 -4
  229. package/dist/core/feed/messages.d.ts +3 -0
  230. package/dist/core/feed/messages.js +6 -6
  231. package/dist/core/fs-utils.d.ts +2 -0
  232. package/dist/core/fs-utils.js +3 -3
  233. package/dist/core/grants/local.d.ts +4 -0
  234. package/dist/core/grants/local.js +1 -0
  235. package/dist/core/grants/mirror.d.ts +44 -0
  236. package/dist/core/grants/mirror.js +4 -0
  237. package/dist/core/grants/on-sync.d.ts +22 -0
  238. package/dist/core/grants/on-sync.js +1 -0
  239. package/dist/core/grants/remove.d.ts +7 -0
  240. package/dist/core/grants/remove.js +1 -0
  241. package/dist/core/grants/sandboxes.d.ts +7 -0
  242. package/dist/core/grants/sandboxes.js +1 -0
  243. package/dist/core/grants/sync.d.ts +12 -0
  244. package/dist/core/grants/sync.js +1 -0
  245. package/dist/core/help/memory-extensions.d.ts +3 -0
  246. package/dist/core/help/memory-extensions.js +2 -0
  247. package/dist/core/help.d.ts +14 -0
  248. package/dist/core/help.js +7 -7
  249. package/dist/core/host-exports/builtins.js +3 -3
  250. package/dist/core/host-exports/export.js +3 -3
  251. package/dist/core/human/action-binding.d.ts +2 -0
  252. package/dist/core/human/action-binding.js +1 -1
  253. package/dist/core/human/feedback-companion.d.ts +0 -1
  254. package/dist/core/human/feedback-companion.js +1 -1
  255. package/dist/core/human/page-schema.d.ts +1 -1
  256. package/dist/core/inspector/core.d.ts +2 -0
  257. package/dist/core/inspector/core.js +1 -1
  258. package/dist/core/inspector/tui.js +2 -2
  259. package/dist/core/installed-plugins.js +1 -1
  260. package/dist/core/io.js +6 -6
  261. package/dist/core/keybindings/catalog.d.ts +1 -1
  262. package/dist/core/keybindings/catalog.js +1 -1
  263. package/dist/core/layout-migrate/index.d.ts +15 -0
  264. package/dist/core/layout-migrate/index.js +4 -0
  265. package/dist/core/layout-migrate/paths.d.ts +26 -0
  266. package/dist/core/layout-migrate/paths.js +1 -0
  267. package/dist/core/layout-migrate/stored-paths.d.ts +2 -0
  268. package/dist/core/layout-migrate/stored-paths.js +11 -0
  269. package/dist/core/layout-migrate/stores.d.ts +17 -0
  270. package/dist/core/layout-migrate/stores.js +4 -0
  271. package/dist/core/layout.d.ts +26 -0
  272. package/dist/core/layout.js +2 -0
  273. package/dist/core/llm/run.d.ts +60 -0
  274. package/dist/core/llm/run.js +4 -0
  275. package/dist/core/memory/cli-selector.d.ts +13 -0
  276. package/dist/core/memory/cli-selector.js +1 -0
  277. package/dist/core/memory/history.d.ts +5 -4
  278. package/dist/core/memory/history.js +6 -6
  279. package/dist/core/memory/inline-ref-inventory.d.ts +2 -1
  280. package/dist/core/memory/inline-ref-inventory.js +1 -1
  281. package/dist/core/memory/lint.js +2 -2
  282. package/dist/core/memory/mutation-domain.d.ts +2 -2
  283. package/dist/core/memory/mutation-domain.js +8 -7
  284. package/dist/core/memory/mutations.js +1 -1
  285. package/dist/core/memory/service.d.ts +5 -0
  286. package/dist/core/memory/service.js +2 -2
  287. package/dist/core/memory-resolver.d.ts +11 -7
  288. package/dist/core/memory-resolver.js +2 -2
  289. package/dist/core/model-auth/daemon-login.d.ts +13 -0
  290. package/dist/core/model-auth/daemon-login.js +1 -0
  291. package/dist/core/model-auth/flows.d.ts +45 -0
  292. package/dist/core/model-auth/flows.js +1 -0
  293. package/dist/core/model-auth/handoff-jti.d.ts +4 -0
  294. package/dist/core/model-auth/handoff-jti.js +1 -0
  295. package/dist/core/model-routes.js +1 -1
  296. package/dist/core/nested-stores.d.ts +2 -1
  297. package/dist/core/nested-stores.js +1 -2
  298. package/dist/core/preview-registry.js +2 -2
  299. package/dist/core/profiles/env-store.js +2 -2
  300. package/dist/core/profiles/manifest.d.ts +16 -5
  301. package/dist/core/profiles/manifest.js +1 -1
  302. package/dist/core/provider-management.js +1 -1
  303. package/dist/core/review/birth.js +1 -1
  304. package/dist/core/review/companion.d.ts +0 -2
  305. package/dist/core/review/companion.js +1 -1
  306. package/dist/core/review/fork.js +2 -2
  307. package/dist/core/review/realize.js +1 -1
  308. package/dist/core/review/stage.d.ts +1 -1
  309. package/dist/core/review/stage.js +1 -1
  310. package/dist/core/review/types.d.ts +1 -1
  311. package/dist/core/runs/events.d.ts +34 -0
  312. package/dist/core/runs/events.js +1 -0
  313. package/dist/core/runs/operations.d.ts +43 -0
  314. package/dist/core/runs/operations.js +12 -0
  315. package/dist/core/runtime/bearings-render.d.ts +2 -2
  316. package/dist/core/runtime/bearings-render.js +11 -11
  317. package/dist/core/runtime/bearings.js +2 -2
  318. package/dist/core/runtime/broker/cli-relay.d.ts +5 -0
  319. package/dist/core/runtime/broker/cli-relay.js +1 -0
  320. package/dist/core/runtime/broker/client-registry.d.ts +0 -5
  321. package/dist/core/runtime/broker/client-registry.js +1 -1
  322. package/dist/core/runtime/broker/daemon-ops.d.ts +28 -1
  323. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  324. package/dist/core/runtime/broker/engine-drive.d.ts +0 -2
  325. package/dist/core/runtime/broker/engine-drive.js +1 -1
  326. package/dist/core/runtime/broker/fault-retry.d.ts +9 -0
  327. package/dist/core/runtime/broker/fault-retry.js +1 -1
  328. package/dist/core/runtime/broker/frame-dispatch.d.ts +5 -9
  329. package/dist/core/runtime/broker/frame-dispatch.js +1 -1
  330. package/dist/core/runtime/broker/frame-engine-control.d.ts +3 -2
  331. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  332. package/dist/core/runtime/broker/frame-memory-refs.d.ts +4 -3
  333. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  334. package/dist/core/runtime/broker/frame-read.js +1 -1
  335. package/dist/core/runtime/broker/frame-session.js +1 -1
  336. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -1
  337. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  338. package/dist/core/runtime/broker/inbox.d.ts +1 -2
  339. package/dist/core/runtime/broker/inbox.js +7 -10
  340. package/dist/core/runtime/broker/model-adapter.d.ts +9 -0
  341. package/dist/core/runtime/broker/model-adapter.js +2 -0
  342. package/dist/core/runtime/broker/node-token.d.ts +3 -0
  343. package/dist/core/runtime/broker/node-token.js +1 -0
  344. package/dist/core/runtime/broker/read-ops.js +1 -1
  345. package/dist/core/runtime/broker/rebind.d.ts +2 -0
  346. package/dist/core/runtime/broker/rebind.js +1 -1
  347. package/dist/core/runtime/broker/tool-groups.js +1 -1
  348. package/dist/core/runtime/broker/turn-ignition.d.ts +3 -3
  349. package/dist/core/runtime/broker/turn-ignition.js +1 -1
  350. package/dist/core/runtime/broker-cli.js +3 -3
  351. package/dist/core/runtime/broker-extension-render.d.ts +2 -5
  352. package/dist/core/runtime/broker-extension-render.js +4 -4
  353. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  354. package/dist/core/runtime/broker-protocol.d.ts +7 -8
  355. package/dist/core/runtime/broker.js +1 -1
  356. package/dist/core/runtime/canvas-extensions.d.ts +1 -0
  357. package/dist/core/runtime/canvas-extensions.js +1 -1
  358. package/dist/core/runtime/close.d.ts +9 -0
  359. package/dist/core/runtime/close.js +1 -1
  360. package/dist/core/runtime/deliver-live.js +1 -1
  361. package/dist/core/runtime/fleet.d.ts +1 -1
  362. package/dist/core/runtime/front-door-login.js +1 -1
  363. package/dist/core/runtime/front-door.js +2 -2
  364. package/dist/core/runtime/headless-pi.d.ts +1 -1
  365. package/dist/core/runtime/headless-pi.js +1 -1
  366. package/dist/core/runtime/host.d.ts +1 -1
  367. package/dist/core/runtime/host.js +3 -1
  368. package/dist/core/runtime/invocation.d.ts +3 -0
  369. package/dist/core/runtime/kickoff.d.ts +1 -0
  370. package/dist/core/runtime/kickoff.js +16 -16
  371. package/dist/core/runtime/launch-target.d.ts +1 -1
  372. package/dist/core/runtime/launch-target.js +1 -1
  373. package/dist/core/runtime/launch.d.ts +10 -35
  374. package/dist/core/runtime/launch.js +1 -1
  375. package/dist/core/runtime/lifecycle.js +2 -2
  376. package/dist/core/runtime/memory.d.ts +1 -1
  377. package/dist/core/runtime/memory.js +1 -1
  378. package/dist/core/runtime/model-registry.js +1 -1
  379. package/dist/core/runtime/model-swap.d.ts +17 -19
  380. package/dist/core/runtime/model-swap.js +1 -1
  381. package/dist/core/runtime/node-read.js +3 -2
  382. package/dist/core/runtime/nodes.d.ts +7 -0
  383. package/dist/core/runtime/nodes.js +1 -1
  384. package/dist/core/runtime/outcome-document.js +1 -1
  385. package/dist/core/runtime/package-health.js +2 -2
  386. package/dist/core/runtime/persona.js +2 -2
  387. package/dist/core/runtime/pi-vendored.js +1 -1
  388. package/dist/core/runtime/placement-tmux.d.ts +1 -1
  389. package/dist/core/runtime/placement-tmux.js +1 -1
  390. package/dist/core/runtime/placement.js +1 -1
  391. package/dist/core/runtime/promote.js +1 -1
  392. package/dist/core/runtime/provider-credential-gate.js +2 -2
  393. package/dist/core/runtime/recovery-hold.d.ts +2 -0
  394. package/dist/core/runtime/recovery-hold.js +1 -0
  395. package/dist/core/runtime/recycle.js +1 -1
  396. package/dist/core/runtime/reopen.js +1 -1
  397. package/dist/core/runtime/reset.js +1 -1
  398. package/dist/core/runtime/revive.d.ts +1 -1
  399. package/dist/core/runtime/revive.js +2 -3
  400. package/dist/core/runtime/roadmap.js +4 -4
  401. package/dist/core/runtime/run-command.d.ts +6 -0
  402. package/dist/core/runtime/run-command.js +1 -1
  403. package/dist/core/runtime/session-branch.d.ts +2 -8
  404. package/dist/core/runtime/session-branch.js +1 -1
  405. package/dist/core/runtime/session-list-cache.d.ts +6 -22
  406. package/dist/core/runtime/session-list-cache.js +1 -1
  407. package/dist/core/runtime/situational-context.js +2 -2
  408. package/dist/core/runtime/spawn-env.d.ts +6 -6
  409. package/dist/core/runtime/spawn-env.js +1 -1
  410. package/dist/core/runtime/spawn.d.ts +5 -0
  411. package/dist/core/runtime/spawn.js +2 -2
  412. package/dist/core/runtime/stop-guard.js +2 -2
  413. package/dist/core/runtime/stop-signals.d.ts +2 -2
  414. package/dist/core/runtime/stop-signals.js +1 -1
  415. package/dist/core/runtime/structured-output.d.ts +10 -4
  416. package/dist/core/runtime/structured-output.js +4 -4
  417. package/dist/core/runtime/tmux-bindings.js +3 -3
  418. package/dist/core/runtime/tmux-driver.d.ts +4 -0
  419. package/dist/core/runtime/tmux-driver.js +7 -7
  420. package/dist/core/runtime/view-socket.d.ts +9 -2
  421. package/dist/core/runtime/view-socket.js +1 -1
  422. package/dist/core/runtime/warm-pool.js +1 -1
  423. package/dist/core/scope.d.ts +3 -2
  424. package/dist/core/scope.js +1 -1
  425. package/dist/core/scoped-state/db.js +1 -1
  426. package/dist/core/scoped-state/migrate.js +3 -3
  427. package/dist/core/scoped-state/profiles.d.ts +2 -1
  428. package/dist/core/scoped-state/profiles.js +1 -1
  429. package/dist/core/scoped-state/schema.d.ts +2 -1
  430. package/dist/core/scoped-state/schema.js +4 -4
  431. package/dist/core/scopes.d.ts +2 -2
  432. package/dist/core/scopes.js +1 -1
  433. package/dist/core/secrets.d.ts +1 -0
  434. package/dist/core/secrets.js +2 -2
  435. package/dist/core/spaces/mounts.d.ts +32 -0
  436. package/dist/core/spaces/mounts.js +1 -0
  437. package/dist/core/spaces/open-beneath.d.ts +71 -0
  438. package/dist/core/spaces/open-beneath.js +1 -0
  439. package/dist/core/spaces/permissions.d.ts +46 -0
  440. package/dist/core/spaces/permissions.js +1 -0
  441. package/dist/core/spaces/process.d.ts +27 -0
  442. package/dist/core/spaces/process.js +1 -0
  443. package/dist/core/spaces/space.d.ts +8 -0
  444. package/dist/core/spaces/space.js +2 -0
  445. package/dist/core/spaces/stop.d.ts +8 -0
  446. package/dist/core/spaces/stop.js +2 -0
  447. package/dist/core/spaces/users.d.ts +19 -0
  448. package/dist/core/spaces/users.js +1 -0
  449. package/dist/core/subscription-state.d.ts +2 -0
  450. package/dist/core/subscription-state.js +3 -3
  451. package/dist/core/substrate/frontmatter-validation.js +1 -1
  452. package/dist/core/substrate/injected-store.d.ts +28 -3
  453. package/dist/core/substrate/injected-store.js +2 -1
  454. package/dist/core/substrate/listings.js +1 -1
  455. package/dist/core/substrate/memory-events.d.ts +6 -0
  456. package/dist/core/substrate/memory-events.js +1 -0
  457. package/dist/core/substrate/on-read-node.js +1 -1
  458. package/dist/core/substrate/on-read.d.ts +6 -6
  459. package/dist/core/substrate/on-read.js +5 -5
  460. package/dist/core/substrate/plan.js +1 -1
  461. package/dist/core/substrate/render-node.js +1 -1
  462. package/dist/core/substrate/render.d.ts +4 -3
  463. package/dist/core/substrate/render.js +38 -38
  464. package/dist/core/substrate/schema.d.ts +6 -0
  465. package/dist/core/substrate/schema.js +1 -1
  466. package/dist/core/tui/panel.js +1 -1
  467. package/dist/core/user-settings.d.ts +12 -0
  468. package/dist/core/user-settings.js +1 -1
  469. package/dist/core/worktree-mutation-async.js +5 -5
  470. package/dist/core/worktree-quarantine.js +1 -1
  471. package/dist/core/worktree-remove.d.ts +15 -0
  472. package/dist/core/worktree-remove.js +1 -0
  473. package/dist/core/worktree-sweep.js +6 -6
  474. package/dist/daemon/analytics/compute.d.ts +37 -0
  475. package/dist/daemon/analytics/compute.js +1 -0
  476. package/dist/daemon/analytics/scan-worker.d.ts +1 -0
  477. package/dist/daemon/analytics/scan-worker.js +2 -0
  478. package/dist/daemon/analytics/scan.d.ts +37 -0
  479. package/dist/daemon/analytics/scan.js +1 -0
  480. package/dist/daemon/api/app-listener.d.ts +11 -0
  481. package/dist/daemon/api/app-listener.js +21 -0
  482. package/dist/daemon/api/bridge.js +5 -5
  483. package/dist/daemon/api/handlers/analytics.d.ts +2 -0
  484. package/dist/daemon/api/handlers/analytics.js +1 -0
  485. package/dist/daemon/api/handlers/attach.js +1 -1
  486. package/dist/daemon/api/handlers/bash-jobs.js +2 -2
  487. package/dist/daemon/api/handlers/bash.js +1 -1
  488. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  489. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  490. package/dist/daemon/api/handlers/canvas.js +6 -6
  491. package/dist/daemon/api/handlers/crons.js +1 -1
  492. package/dist/daemon/api/handlers/files.d.ts +1 -1
  493. package/dist/daemon/api/handlers/files.js +1 -1
  494. package/dist/daemon/api/handlers/health.js +2 -2
  495. package/dist/daemon/api/handlers/hook-exec.d.ts +2 -0
  496. package/dist/daemon/api/handlers/hook-exec.js +1 -0
  497. package/dist/daemon/api/handlers/human-requests.js +1 -1
  498. package/dist/daemon/api/handlers/inbox.js +1 -1
  499. package/dist/daemon/api/handlers/llm.d.ts +2 -0
  500. package/dist/daemon/api/handlers/llm.js +3 -0
  501. package/dist/daemon/api/handlers/memory-reads.d.ts +4 -0
  502. package/dist/daemon/api/handlers/memory-reads.js +1 -0
  503. package/dist/daemon/api/handlers/memory.js +5 -1
  504. package/dist/daemon/api/handlers/messages.js +2 -2
  505. package/dist/daemon/api/handlers/modelauth.js +1 -1
  506. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  507. package/dist/daemon/api/handlers/node-records.d.ts +2 -0
  508. package/dist/daemon/api/handlers/node-records.js +3 -0
  509. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  510. package/dist/daemon/api/handlers/nodes.js +1 -1
  511. package/dist/daemon/api/handlers/profiles.d.ts +4 -1
  512. package/dist/daemon/api/handlers/profiles.js +1 -1
  513. package/dist/daemon/api/handlers/reports.js +5 -3
  514. package/dist/daemon/api/handlers/reviews.d.ts +1 -1
  515. package/dist/daemon/api/handlers/reviews.js +1 -1
  516. package/dist/daemon/api/handlers/run-routes.d.ts +2 -0
  517. package/dist/daemon/api/handlers/run-routes.js +1 -0
  518. package/dist/daemon/api/handlers/runs.d.ts +9 -0
  519. package/dist/daemon/api/handlers/runs.js +1 -0
  520. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  521. package/dist/daemon/api/handlers/worktree.js +1 -1
  522. package/dist/daemon/api/map.d.ts +10 -4
  523. package/dist/daemon/api/map.js +2 -2
  524. package/dist/daemon/api/operations.d.ts +18 -0
  525. package/dist/daemon/api/operations.js +1 -0
  526. package/dist/daemon/api/principal.d.ts +42 -0
  527. package/dist/daemon/api/principal.js +1 -0
  528. package/dist/daemon/api/router.d.ts +27 -3
  529. package/dist/daemon/api/router.js +1 -1
  530. package/dist/daemon/api/server.d.ts +4 -0
  531. package/dist/daemon/api/server.js +1 -1
  532. package/dist/daemon/api/vendor-signin.d.ts +7 -0
  533. package/dist/daemon/api/vendor-signin.js +77 -0
  534. package/dist/daemon/api/viewer-presence.d.ts +3 -0
  535. package/dist/daemon/api/viewer-presence.js +1 -0
  536. package/dist/daemon/cron/armed-context.d.ts +4 -0
  537. package/dist/daemon/cron/armed-context.js +1 -1
  538. package/dist/daemon/cron/escalation.js +3 -3
  539. package/dist/daemon/cron/lease-recovery.js +1 -1
  540. package/dist/daemon/cron/sinks.js +2 -2
  541. package/dist/daemon/cron-run.d.ts +5 -5
  542. package/dist/daemon/cron-run.js +1 -1
  543. package/dist/daemon/crtrd.js +8 -7
  544. package/dist/daemon/delivery/run-delivery.d.ts +4 -0
  545. package/dist/daemon/delivery/run-delivery.js +1 -1
  546. package/dist/daemon/fleet.d.ts +1 -1
  547. package/dist/daemon/fleet.js +6 -6
  548. package/dist/daemon/human/finish.js +7 -7
  549. package/dist/daemon/joined-owner.d.ts +5 -0
  550. package/dist/daemon/joined-owner.js +1 -0
  551. package/dist/daemon/manage.js +2 -2
  552. package/dist/daemon/messaging/node-message.js +1 -1
  553. package/dist/daemon/park-activity.js +1 -1
  554. package/dist/daemon/reconcilers/bash-deadline.js +1 -1
  555. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  556. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  557. package/dist/daemon/reconcilers/delivery-lane.js +1 -1
  558. package/dist/daemon/reconcilers/live-obligation.d.ts +7 -0
  559. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  560. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  561. package/dist/daemon/reconcilers/storage-maintenance.d.ts +20 -1
  562. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  563. package/dist/daemon/runs/append-section.d.ts +6 -0
  564. package/dist/daemon/runs/append-section.js +2 -0
  565. package/dist/daemon/runs/observer.d.ts +5 -0
  566. package/dist/daemon/runs/observer.js +4 -0
  567. package/dist/launcher/bwrap.d.ts +4 -0
  568. package/dist/launcher/bwrap.js +2 -0
  569. package/dist/launcher/client.d.ts +2 -0
  570. package/dist/launcher/client.js +3 -0
  571. package/dist/launcher/main.d.ts +1 -0
  572. package/dist/launcher/main.js +3 -0
  573. package/dist/launcher/netrule.d.ts +1 -0
  574. package/dist/launcher/netrule.js +1 -0
  575. package/dist/launcher/seccomp.d.ts +1 -0
  576. package/dist/launcher/seccomp.js +1 -0
  577. package/dist/launcher/spec.d.ts +88 -0
  578. package/dist/launcher/spec.js +1 -0
  579. package/dist/launcher/users.d.ts +18 -0
  580. package/dist/launcher/users.js +7 -0
  581. package/dist/launcher/validate.d.ts +22 -0
  582. package/dist/launcher/validate.js +1 -0
  583. package/dist/migrations/corpus.js +3 -3
  584. package/dist/migrations/runner.js +1 -1
  585. package/dist/native/linux/addon.node +0 -0
  586. package/dist/native/linux.d.ts +29 -0
  587. package/dist/native/linux.js +1 -0
  588. package/dist/pi-extensions/broker-local.js +2 -2
  589. package/dist/pi-extensions/canvas-bash-valve.d.ts +1 -3
  590. package/dist/pi-extensions/canvas-bash-valve.js +4 -7
  591. package/dist/pi-extensions/canvas-context-intro.d.ts +1 -2
  592. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  593. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  594. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +2 -1
  595. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -1
  596. package/dist/pi-extensions/canvas-passive-context.d.ts +1 -1
  597. package/dist/pi-extensions/canvas-passive-context.js +11 -11
  598. package/dist/pi-extensions/canvas-recap.js +6 -6
  599. package/dist/pi-extensions/canvas-stophook.js +1 -1
  600. package/dist/pi-extensions/canvas-structured-output.js +4 -4
  601. package/dist/pi-extensions/canvas-tool-guide.js +1 -1
  602. package/dist/pi-extensions/system-prompt-entry.d.ts +15 -0
  603. package/dist/pi-extensions/system-prompt-entry.js +1 -0
  604. package/dist/shared/env.d.ts +5 -1
  605. package/dist/shared/env.js +1 -1
  606. package/dist/shared/strip-cd-prefix.d.ts +1 -0
  607. package/dist/shared/strip-cd-prefix.js +1 -0
  608. package/dist/types.d.ts +31 -15
  609. package/docs/cli/memory-and-preferences.md +3 -1
  610. package/docs/sdk/client.md +34 -0
  611. package/docs/sdk/errors.md +2 -0
  612. package/docs/sdk/memory.md +2 -2
  613. package/docs/sdk/streaming.md +21 -0
  614. package/package.json +18 -4
  615. package/packages/crouter-identity/dist/index.d.ts +54 -0
  616. package/packages/crouter-identity/dist/index.js +166 -0
  617. package/packages/crouter-identity/package.json +33 -0
  618. package/runtime.lock.json +34 -8
  619. package/scripts/build-native-linux.mjs +16 -0
  620. package/scripts/install-runtime.mjs +9 -7
  621. package/scripts/lib/isolation-env.mjs +42 -0
  622. package/scripts/runtime-smoke.mjs +49 -0
  623. package/src/native/linux/addon.c +249 -0
  624. package/dist/core/profiles/state-block.d.ts +0 -4
  625. package/dist/core/profiles/state-block.js +0 -3
  626. package/dist/core/runtime/broker/auth-reload.d.ts +0 -41
  627. package/dist/core/runtime/broker/auth-reload.js +0 -1
  628. package/dist/core/substrate/cli-context-delivery.d.ts +0 -22
  629. package/dist/core/substrate/cli-context-delivery.js +0 -1
@@ -1,25 +1,12 @@
1
- import { envNodeId } from '../../../shared/env.js';
1
+ import { envNodeId, envProfileId } from '../../../shared/env.js';
2
2
  import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
3
- import { createMemoryDocSnapshot, listAllMemoryDocs, readMemoryDocContent } from '../../../core/memory-resolver.js';
4
- import { parseSubstrateDoc } from '../../../core/substrate/schema.js';
5
- import { docsByName } from '../../../core/substrate/listings.js';
6
- import { contentReadAttachments } from '../../../core/substrate/on-read.js';
7
- import { brokerExtensionState } from '../../../core/runtime/broker/daemon-ops.js';
8
- import type { NodeConfigSubject } from '../../../core/substrate/subject-fields.js';
3
+ import { localClient } from '../../../api/node-transport.js';
9
4
  import {
10
5
  expandDeterministicCommand,
11
6
  type DeterministicCommandExpansion,
12
7
  } from '../../../core/runtime/command-expansion.js';
13
8
  import { expandShellBlocks, hasShellBlocks, DEFAULT_SHELL_TIMEOUT_MS } from '../../../core/runtime/shell-expansion.js';
14
9
  import type { ChatCommandMetadata } from '../../../core/runtime/command-surface.js';
15
- import {
16
- exposureTarget,
17
- loadContextExposureState,
18
- mergeContextExposureState,
19
- registerDocumentExposure,
20
- saveContextExposureState,
21
- sharedContextExposureState,
22
- } from '../../../core/substrate/injected-store.js';
23
10
  import { piShellRunner } from './pi-shell-runner.js';
24
11
 
25
12
  // memory-slash-commands: any memory doc frontmatter-flagged `slash: true`
@@ -28,15 +15,16 @@ import { piShellRunner } from './pi-shell-runner.js';
28
15
  // the doc body (plus the user's free-text args) as a normal turn instead of
29
16
  // requiring a separate skill-invocation mechanism.
30
17
  //
31
- // Discovery uses one in-process target snapshot for both listing and body
32
- // resolution. The snapshot already resolves exact canonical identities in
33
- // source precedence; this file does not walk memory directories or reimplement
34
- // scope resolution.
18
+ // The daemon resolves the target snapshot and returns command bodies. The
19
+ // broker never opens memory stores; shell blocks run only when invoked here.
35
20
 
36
21
  interface MemoryListItem {
37
22
  name: string;
38
23
  short_form: string;
39
- slash: boolean;
24
+ path: string;
25
+ canonical_body: string;
26
+ execution_body?: string;
27
+ error?: string;
40
28
  }
41
29
 
42
30
  export interface SlashDoc {
@@ -48,85 +36,32 @@ export interface SlashDoc {
48
36
  description: string;
49
37
  }
50
38
 
51
- // Keep each canonical winner's body and path for disclosure classification and
52
- // the existing execution read.
53
- const resolvedMemoryDocs = new Map<string, { path: string; canonicalBody: string }>();
39
+ // Keep each canonical winner's body for registration-time disclosure classification.
40
+ const resolvedMemoryDocs = new Map<string, MemoryListItem>();
54
41
 
55
42
  async function defaultListMemoryDocs(): Promise<MemoryListItem[]> {
56
- const snapshot = createMemoryDocSnapshot();
57
- const items: MemoryListItem[] = [];
58
- const seen = new Set<string>();
59
- for (const memoryDoc of snapshot.docs) {
60
- if (seen.has(memoryDoc.name)) continue;
61
- seen.add(memoryDoc.name);
62
- const doc = parseSubstrateDoc(memoryDoc);
63
- if (doc === null) continue;
64
- items.push({
65
- name: memoryDoc.name,
66
- short_form: doc.shortForm,
67
- slash: doc.slash,
68
- });
69
- }
70
-
71
- // Resolve eligible canonical names against the same target snapshot that
72
- // supplied the list rows.
73
- const resolved = snapshot.resolve(items.filter((item) => item.slash).map((item) => item.name));
43
+ const node = envNodeId();
44
+ const query = new URLSearchParams(node ? { node } : { cwd: process.cwd(), ...(envProfileId() ? { profile: envProfileId() } : {}) });
45
+ const docs = await localClient({ autostart: false }).request<MemoryListItem[]>('GET', `/v1/memory/slash?${query}`);
74
46
  resolvedMemoryDocs.clear();
75
- for (const [name, doc] of resolved) {
76
- resolvedMemoryDocs.set(name, { path: doc.path, canonicalBody: doc.body });
77
- }
78
- return items;
47
+ for (const doc of docs) resolvedMemoryDocs.set(doc.name, doc);
48
+ return docs;
79
49
  }
80
50
 
81
- function defaultReadMemoryDoc(name: string): { path: string; canonicalBody: string; executionBody: string } {
51
+ function defaultReadMemoryDoc(name: string): { canonicalBody: string; executionBody: string } {
82
52
  const resolved = resolvedMemoryDocs.get(name);
83
53
  if (resolved === undefined) throw new Error(`memory slash document was not resolved: ${name}`);
84
- return {
85
- path: resolved.path,
86
- canonicalBody: resolved.canonicalBody,
87
- executionBody: readMemoryDocContent(resolved.path),
88
- };
54
+ if (resolved.error !== undefined) throw new Error(resolved.error);
55
+ if (resolved.execution_body === undefined) throw new Error(`memory slash document has no execution body: ${name}`);
56
+ return { canonicalBody: resolved.canonical_body, executionBody: resolved.execution_body };
89
57
  }
90
58
 
91
- /** The node-config subject the companion `memory-read` gates evaluate against.
92
- * Unreachable daemon = null, which skips gated docs and delivers ungated ones. */
93
- async function slashSubject(nodeId: string): Promise<NodeConfigSubject | null> {
94
- try {
95
- return (await brokerExtensionState(nodeId)).subject;
96
- } catch {
97
- return null;
98
- }
99
- }
100
-
101
- /** Invoking a document is content delivery, so it carries the same companions
102
- * `crtr memory read` attaches: the directory listings that place it, and every
103
- * corpus doc whose `memory-read` route matches its name. Returns the blocks to
104
- * prepend and records the whole delivery in the exposure ledger. Without a node
105
- * identity nothing records and nothing attaches. */
106
- async function slashReadAttachments(name: string, path: string, body: string): Promise<string[]> {
107
- const nodeId = envNodeId();
108
- if (nodeId === undefined || nodeId === "") return [];
109
- const state = sharedContextExposureState(nodeId);
110
- mergeContextExposureState(state, loadContextExposureState(nodeId));
111
- const target = exposureTarget(state, "transcript");
112
- // Register the invoked body BEFORE the attachments, so the listings and
113
- // companion routes dedupe against the document about to be delivered.
114
- registerDocumentExposure(target, path, body, "content");
115
- let blocks: string[] = [];
116
- try {
117
- const byName = docsByName(listAllMemoryDocs(undefined, true, true));
118
- // No `explicit`: the read leaf returns a doc's own directory listing in a
119
- // separate field, while this path has only the turn — it wants that
120
- // listing attached as a block like every other.
121
- blocks = contentReadAttachments(
122
- { name, path, body },
123
- { subject: await slashSubject(nodeId), target, byName, listings: "blocks" },
124
- ).blocks;
125
- } catch {
126
- blocks = [];
127
- }
128
- saveContextExposureState(nodeId, state);
129
- return blocks;
59
+ async function slashReadAttachments(name: string): Promise<{ blocks: string[]; execution_body: string }> {
60
+ const node = envNodeId();
61
+ if (!node) throw new Error('memory slash attachments require a node');
62
+ return localClient({ autostart: false }).request<{ blocks: string[]; execution_body: string }>(
63
+ 'POST', '/v1/memory/slash/attachments', { node, name },
64
+ );
130
65
  }
131
66
 
132
67
  function hasNodeRelativeExpansion(body: string): boolean {
@@ -141,20 +76,13 @@ export function slashCommandName(docName: string): string {
141
76
  /** Every `slash: true` canonical winner, scope-precedence-deduped by name. A
142
77
  * doc without `slash` (or `slash: false`) is silently excluded. */
143
78
  export async function discoverSlashDocs(): Promise<SlashDoc[]> {
144
- let items: MemoryListItem[];
145
- try {
146
- items = await defaultListMemoryDocs();
147
- } catch {
148
- return [];
149
- }
79
+ const items = await defaultListMemoryDocs();
150
80
  const seen = new Set<string>();
151
81
  const out: SlashDoc[] = [];
152
82
  for (const item of items) {
153
83
  if (seen.has(item.name)) continue;
154
84
  seen.add(item.name);
155
- if (item.slash) {
156
- out.push({ name: item.name, commandName: slashCommandName(item.name), description: item.short_form });
157
- }
85
+ out.push({ name: item.name, commandName: slashCommandName(item.name), description: item.short_form });
158
86
  }
159
87
  return out;
160
88
  }
@@ -163,9 +91,7 @@ export default async function (pi: ExtensionAPI) {
163
91
  const docs = await discoverSlashDocs();
164
92
  for (const doc of docs) {
165
93
  let expansion: DeterministicCommandExpansion | undefined;
166
- let exposure: { path: string; body: string } | undefined;
167
94
  let discloseExpansion = false;
168
- let loadError: unknown;
169
95
  try {
170
96
  const body = defaultReadMemoryDoc(doc.name);
171
97
  expansion = {
@@ -173,10 +99,10 @@ export default async function (pi: ExtensionAPI) {
173
99
  commandName: doc.commandName,
174
100
  body: body.executionBody,
175
101
  };
176
- exposure = { path: body.path, body: body.canonicalBody };
177
102
  discloseExpansion = !hasNodeRelativeExpansion(body.canonicalBody);
178
- } catch (err) {
179
- loadError = err;
103
+ } catch {
104
+ // Keep registration for a document that became unreadable; invocation
105
+ // reports the current read error without executing the cached body.
180
106
  }
181
107
 
182
108
  // pi preserves unknown registration fields on the resolved command object.
@@ -193,28 +119,23 @@ export default async function (pi: ExtensionAPI) {
193
119
  ? {}
194
120
  : { gateway: true as const, ...(discloseExpansion ? { expansion } : {}) }),
195
121
  handler: async (args, ctx) => {
196
- if (expansion === undefined) {
197
- ctx.ui.notify(
198
- `/${doc.commandName}: failed to read memory doc "${doc.name}": ${loadError instanceof Error ? loadError.message : String(loadError)}`,
199
- "error",
200
- );
122
+ let current: { blocks: string[]; execution_body: string };
123
+ try {
124
+ current = await slashReadAttachments(doc.name);
125
+ } catch (error) {
126
+ ctx.ui.notify(`/${doc.commandName}: failed to read memory doc "${doc.name}": ${error instanceof Error ? error.message : String(error)}`, "error");
201
127
  return;
202
128
  }
203
- // Shell runs HERE and only here. `expandDeterministicCommand` stays
204
- // inert because it also drives the attach viewer's pre-submit preview,
205
- // which re-expands on every keystroke — executing there would run the
206
- // document's commands repeatedly while the user is still typing. This
207
- // handler fires once, at submit, so the preview shows the command text
208
- // and the submitted turn carries its output.
209
- const expanded = expandDeterministicCommand(expansion, args ?? "");
129
+ // The daemon resolves the current slash document and attachments in one
130
+ // request, before the document can execute any shell block.
131
+ const expanded = expandDeterministicCommand({ kind: 'memory-slash', commandName: doc.commandName, body: current.execution_body }, args ?? "");
210
132
  const content = hasShellBlocks(expanded)
211
133
  ? await expandShellBlocks(
212
134
  expanded,
213
135
  piShellRunner(pi, (ctx as { cwd?: string }).cwd ?? process.cwd(), DEFAULT_SHELL_TIMEOUT_MS),
214
136
  )
215
137
  : expanded;
216
- const blocks =
217
- exposure === undefined ? [] : await slashReadAttachments(doc.name, exposure.path, exposure.body);
138
+ const blocks = current.blocks;
218
139
  pi.sendMessage(
219
140
  {
220
141
  customType: "memory-slash-command",
@@ -11,12 +11,17 @@ type ProviderErrorClassification = {
11
11
  status?: number;
12
12
  reason: string;
13
13
  hadRetryAfterHeader: boolean;
14
+ /** Cooldown this classification imposes regardless of any Retry-After header. */
15
+ cooldownMs?: number;
16
+ };
17
+ type ProviderClassificationPolicy = {
18
+ rotateOnAuth: boolean;
14
19
  };
15
20
  /** Test seam for the policy mapping over the shared recognition signal. */
16
21
  export declare function __classifyProviderErrorForTest(error: unknown, observed?: {
17
22
  status?: number;
18
23
  retryAfterMs?: number;
19
- }): ProviderErrorClassification;
24
+ }, policy?: ProviderClassificationPolicy): ProviderErrorClassification;
20
25
  declare function defaultSleep(ms: number): Promise<void>;
21
26
  /** Test-only seam: override the sleep implementation used for in-place/wait-out retries. Pass undefined to restore the default. */
22
27
  export declare function __setSleepForTest(fn: typeof defaultSleep | undefined): void;
@@ -1,7 +1,7 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { createAssistantMessageEventStream, } from '@earendil-works/pi-ai';
3
3
  import { anthropicMessagesApi, openAICodexResponsesApi } 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';
4
+ import { ANTHROPIC_PROVIDER_ID, OPENAI_CODEX_PROVIDER_ID, INVALID_REFRESH_TOKEN_BACKOFF_MS, formatStatusLine, getProviderLabel, isManagedProvider, isInvalidRefreshTokenError, addSubscription, enrichManagedLoginIdentity, markSubscriptionAuthenticationFailed, markSubscriptionRateLimited, markSubscriptionSuccess, retryAfterMsFromHeaders, retryAfterMsFromError, promoteSubscription, readRotationConfig, readSubscriptionPool, refreshSubscriptionCredential, removeManagedAccount, resolveProviderCandidates, upsertSubscriptionWithUniqueAccount, } from '../../../core/subscription-state.js';
5
5
  import { readMergedLaunchConfig } from '../../../core/config.js';
6
6
  import { expandModelCandidates, modelRequestFromConfig, probeRouteAvailability } from '../../../core/model-routes.js';
7
7
  import { envModelExact, envNodeId } from '../../../shared/env.js';
@@ -23,6 +23,11 @@ const TRANSIENT_RETRY_BACKOFFS_MS = [250, 750];
23
23
  // so cool it down only briefly -- long enough to rotate to another credential / fallback
24
24
  // provider, short enough that it comes back quickly if it was the only option.
25
25
  const TRANSIENT_ROTATE_COOLDOWN_MS = 60 * 1000;
26
+ // A 401/403 before any content means the provider refused this credential (a lapsed
27
+ // plan, a revoked server-side key). That is not a transient blip, but it is not proof
28
+ // the account is gone either: cool the account for 30 minutes and rotate, rather than
29
+ // the 30-day invalid_grant backoff. Exact requests keep the auth error.
30
+ const AUTH_REJECTED_COOLDOWN_MS = 30 * 60 * 1000;
26
31
  // A few short outer retries absorb a normal multi-broker collision; if the metadata file
27
32
  // remains busy, the provider call still proceeds. Subscription bookkeeping must never turn a
28
33
  // healthy model response into a fatal generation fault.
@@ -38,7 +43,7 @@ function configuredValue(state, key, envName) {
38
43
  function isExactModel(state) {
39
44
  return state.options === undefined && envModelExact();
40
45
  }
41
- function classifyProviderSignal(signal) {
46
+ function classifyProviderSignal(signal, policy) {
42
47
  const hadRetryAfterHeader = signal.retryAfterMs !== undefined;
43
48
  if (signal.kind === 'rate-limit' && signal.matchedOn === 'status') {
44
49
  return { kind: 'rate_limit', status: signal.status, reason: 'http 429', hadRetryAfterHeader };
@@ -50,6 +55,9 @@ function classifyProviderSignal(signal) {
50
55
  return { kind: 'transient', status: signal.status, reason: `http ${signal.status}`, hadRetryAfterHeader };
51
56
  }
52
57
  const textMatches = signal.textMatches ?? (signal.matchedOn === 'text' && signal.match ? [{ kind: signal.kind, match: signal.match }] : []);
58
+ if (policy.rotateOnAuth && signal.kind === 'auth' && signal.matchedOn === 'status' && !textMatches.some(({ kind }) => kind === 'rate-limit')) {
59
+ return { kind: 'rate_limit', status: signal.status, reason: `http ${signal.status}`, hadRetryAfterHeader, cooldownMs: AUTH_REJECTED_COOLDOWN_MS };
60
+ }
53
61
  const transientMatch = textMatches.find(({ kind }) => kind === 'connection' || kind === 'socket' || kind === 'service-unavailable' || kind === 'overloaded');
54
62
  if (transientMatch) {
55
63
  return { kind: 'transient', status: signal.status, reason: transientMatch.match.toLowerCase(), hadRetryAfterHeader };
@@ -60,7 +68,7 @@ function classifyProviderSignal(signal) {
60
68
  }
61
69
  return { kind: 'fatal', status: signal.status, reason: 'unclassified', hadRetryAfterHeader };
62
70
  }
63
- function classifyProviderFailure(failure, retryAfterMs) {
71
+ function classifyProviderFailure(failure, retryAfterMs, policy) {
64
72
  const nested = failure.causes ?? [];
65
73
  const code = failure.code ?? nested.find((cause) => cause.code !== undefined)?.code;
66
74
  const errno = failure.errno ?? nested.find((cause) => cause.errno !== undefined)?.errno;
@@ -73,14 +81,11 @@ function classifyProviderFailure(failure, retryAfterMs) {
73
81
  code,
74
82
  errno,
75
83
  message,
76
- }));
77
- }
78
- function classifyProviderError(error, observed) {
79
- return classifyProviderFailure(normalizeProviderFailure(error, { status: observed.status }), observed.retryAfterMs);
84
+ }), policy);
80
85
  }
81
86
  /** Test seam for the policy mapping over the shared recognition signal. */
82
- export function __classifyProviderErrorForTest(error, observed = {}) {
83
- return classifyProviderError(error, observed);
87
+ export function __classifyProviderErrorForTest(error, observed = {}, policy = { rotateOnAuth: false }) {
88
+ return classifyProviderFailure(normalizeProviderFailure(error, { status: observed.status }), observed.retryAfterMs, policy);
84
89
  }
85
90
  function providerFailureAssistantMessage(model, failure) {
86
91
  const message = toAssistantError(model, failure.message);
@@ -214,15 +219,6 @@ function toAssistantError(model, errorMessage) {
214
219
  timestamp: Date.now(),
215
220
  };
216
221
  }
217
- function retryAfterMs(headers) {
218
- const retryAfterMsHeader = headers["retry-after-ms"];
219
- if (retryAfterMsHeader) {
220
- const millis = Number(retryAfterMsHeader);
221
- if (Number.isFinite(millis))
222
- return Math.max(0, millis);
223
- }
224
- return parseRetryAfterHeader(headers["retry-after"]);
225
- }
226
222
  // Extract an account identity supplied directly by the OAuth credential.
227
223
  function loginAccountId(cred) {
228
224
  return typeof cred.accountId === "string" && cred.accountId.trim() ? cred.accountId.trim() : undefined;
@@ -392,6 +388,7 @@ export function __setStreamForProviderForTest(fn) {
392
388
  // A genuine rate limit ends the attempt immediately (the caller cools the credential down
393
389
  // and rotates); a transient blip gets a short in-place retry budget before giving up.
394
390
  async function streamProviderAttempt(state, providerId, model, context, options, credential, outer) {
391
+ const policy = { rotateOnAuth: !isExactModel(state) };
395
392
  for (let attempt = 1;; attempt++) {
396
393
  const attemptAt = Date.now();
397
394
  let observedStatus;
@@ -429,7 +426,7 @@ async function streamProviderAttempt(state, providerId, model, context, options,
429
426
  onResponse: async (response, responseModel) => {
430
427
  observedStatus = response.status;
431
428
  if (response.status === 429 || response.status === 503) {
432
- requestedRetryAfterMs = retryAfterMs(response.headers);
429
+ requestedRetryAfterMs = retryAfterMsFromHeaders(response.headers);
433
430
  }
434
431
  await options?.onResponse?.(response, responseModel);
435
432
  },
@@ -474,7 +471,7 @@ async function streamProviderAttempt(state, providerId, model, context, options,
474
471
  }
475
472
  failure = normalizeProviderFailure(event.error, { status: observedStatus });
476
473
  failureMessage = failure.message;
477
- classification = classifyProviderFailure(failure, requestedRetryAfterMs);
474
+ classification = classifyProviderFailure(failure, requestedRetryAfterMs, policy);
478
475
  if (classification.kind === "fatal" || sawContent) {
479
476
  emit({ ...event, error: providerFailureAssistantMessage(model, failure) });
480
477
  flush();
@@ -501,9 +498,10 @@ async function streamProviderAttempt(state, providerId, model, context, options,
501
498
  flush();
502
499
  return { result: "fatal", attemptAt };
503
500
  }
501
+ requestedRetryAfterMs ??= retryAfterMsFromError(error);
504
502
  failure = normalizeProviderFailure(error, { status: observedStatus });
505
503
  failureMessage = failure.message;
506
- classification = classifyProviderFailure(failure, requestedRetryAfterMs);
504
+ classification = classifyProviderFailure(failure, requestedRetryAfterMs, policy);
507
505
  if (classification.kind === "fatal" || sawContent) {
508
506
  emit({
509
507
  type: "error",
@@ -524,7 +522,7 @@ async function streamProviderAttempt(state, providerId, model, context, options,
524
522
  return { result: "success", attemptAt };
525
523
  }
526
524
  if (classification.kind === "rate_limit") {
527
- return { result: "rate_limited", retryAfterMs: requestedRetryAfterMs, attemptAt, classification };
525
+ return { result: "rate_limited", retryAfterMs: classification.cooldownMs ?? requestedRetryAfterMs, attemptAt, classification, failureMessage };
528
526
  }
529
527
  // Transient: retry the SAME credential/provider in place first -- no cooldown for the
530
528
  // quick in-place budget.
@@ -582,7 +580,10 @@ async function runManagedProvider(state, model, context, options, stream) {
582
580
  : state.runtimeContext.thinkingLevel;
583
581
  const request = modelRequestFromConfig(`${model.provider}/${model.id}${liveThinking ? `:${liveThinking}` : ''}`, configuredValue(state, 'modelIntent', 'CRTR_MODEL_INTENT'), isExactModel(state));
584
582
  const expanded = request ? expandModelCandidates(request, configuredValue(state, 'nodeCwd', 'CRTR_NODE_CWD'), configuredValue(state, 'profileId', 'CRTR_PROFILE_ID')) : [];
585
- const liveRank = expanded.find((candidate) => candidate.providerId === model.provider && candidate.modelId === model.id && candidate.thinkingLevel === liveThinking)?.rank ?? 0;
583
+ // The node's thinking level holds on its own model; a route to another
584
+ // provider or model takes that cell's thinking.
585
+ const onLiveModel = (candidate) => candidate.providerId === model.provider && candidate.modelId === model.id;
586
+ const liveRank = (expanded.find((candidate) => onLiveModel(candidate) && candidate.thinkingLevel === liveThinking) ?? expanded.find(onLiveModel))?.rank ?? 0;
586
587
  const routeCandidates = expanded.slice(liveRank)
587
588
  .map((route) => {
588
589
  const registry = state.runtimeContext?.modelRegistry;
@@ -592,9 +593,10 @@ async function runManagedProvider(state, model, context, options, stream) {
592
593
  const availability = probeRouteAvailability(route, registry);
593
594
  if (!availability.registered || (!isManagedProvider(route.providerId) && !availability.authenticated))
594
595
  return undefined;
595
- return { routeId: route.routeId, credentialSource: route.credentialSource, rank: route.rank, providerId: route.providerId, model: routeModel, thinkingLevel: route.thinkingLevel };
596
+ return { routeId: route.routeId, credentialSource: route.credentialSource, rank: route.rank, providerId: route.providerId, model: routeModel, thinkingLevel: onLiveModel(route) ? liveThinking : route.thinkingLevel };
596
597
  })
597
- .filter((candidate) => candidate !== undefined);
598
+ .filter((candidate) => candidate !== undefined)
599
+ .filter((candidate, index, all) => all.findIndex((other) => other.routeId === candidate.routeId && other.providerId === candidate.providerId && other.model.id === candidate.model.id && other.thinkingLevel === candidate.thinkingLevel) === index);
598
600
  const isLiveRoute = (candidate) => candidate.providerId === model.provider && candidate.model.id === model.id && candidate.thinkingLevel === liveThinking;
599
601
  // A cooling or unauthenticated managed route contributes its diagnostic and may
600
602
  // later re-enter when a credential becomes ready, but it is never selected now.
@@ -618,6 +620,9 @@ async function runManagedProvider(state, model, context, options, stream) {
618
620
  const cooldownAttempts = new Map();
619
621
  let terminalModel = model;
620
622
  let lastTransientFailure;
623
+ // The last pre-content 401/403 that cooled a route; its text is the only
624
+ // record of why the routes ran out when they end in a cooling error.
625
+ let lastAuthRejection;
621
626
  // Any HTTP response observed this pass (a status, a Retry-After header, or a
622
627
  // rate-limit classification) proves this process can still reach a provider,
623
628
  // clearing the poisoned-transport suspicion.
@@ -661,6 +666,8 @@ async function runManagedProvider(state, model, context, options, stream) {
661
666
  const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
662
667
  if (result.result === 'transient_exhausted')
663
668
  lastTransientFailure = result;
669
+ if (result.result === 'rate_limited' && (result.classification?.status === 401 || result.classification?.status === 403))
670
+ lastAuthRejection = result;
664
671
  localCoolingDeadlines.set(routeId, Math.max(localCoolingDeadlines.get(routeId) ?? 0, Date.now() + cooldownMs));
665
672
  logRouteQueueAdvance(candidate, candidates[0], result);
666
673
  continue;
@@ -715,6 +722,8 @@ async function runManagedProvider(state, model, context, options, stream) {
715
722
  const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
716
723
  if (result.result === 'transient_exhausted')
717
724
  lastTransientFailure = result;
725
+ if (result.result === 'rate_limited' && (result.classification?.status === 401 || result.classification?.status === 403))
726
+ lastAuthRejection = result;
718
727
  if (result.result === 'rate_limited' && result.retryAfterMs !== undefined) {
719
728
  const persisted = await recordSubscriptionMutation(`recording ${getProviderLabel(providerId)} server cooldown`, () => markSubscriptionRateLimited(providerId, freshCredential.label, cooldownMs, result.attemptAt));
720
729
  if (persisted)
@@ -750,7 +759,11 @@ async function runManagedProvider(state, model, context, options, stream) {
750
759
  }
751
760
  state.transportOnlyExhaustedPasses = 0;
752
761
  if (coolingDeadline !== undefined) {
753
- emitCoolingError(stream, terminalModel, new ManagedProviderCoolingError(`All provider routes are rate limited (cooling down ~${Math.ceil((coolingDeadline - Date.now()) / 1000)}s; tried ${tried})`, coolingDeadline));
762
+ const cooling = `cooling down ~${Math.ceil((coolingDeadline - Date.now()) / 1000)}s`;
763
+ const message = lastAuthRejection === undefined
764
+ ? `All provider routes are rate limited (${cooling}; tried ${tried})`
765
+ : `All provider routes are rate limited or rejected (${cooling}; last rejection ${lastAuthRejection.classification.reason}: ${lastAuthRejection.failureMessage ?? 'no error message'}; tried ${tried})`;
766
+ emitCoolingError(stream, terminalModel, new ManagedProviderCoolingError(message, coolingDeadline));
754
767
  return;
755
768
  }
756
769
  const authFailure = [...authFailures][0];
@@ -856,7 +869,8 @@ async function restoreHigherRankIfAvailable(state, pi, ctx) {
856
869
  if (!request || !ctx.model)
857
870
  return false;
858
871
  const candidates = expandModelCandidates(request, configuredValue(state, 'nodeCwd', 'CRTR_NODE_CWD'), configuredValue(state, 'profileId', 'CRTR_PROFILE_ID'));
859
- const liveRank = candidates.find((candidate) => candidate.providerId === ctx.model?.provider && candidate.modelId === ctx.model?.id && candidate.thinkingLevel === liveThinking)?.rank;
872
+ const onLiveModel = (candidate) => candidate.providerId === ctx.model?.provider && candidate.modelId === ctx.model?.id;
873
+ const liveRank = (candidates.find((candidate) => onLiveModel(candidate) && candidate.thinkingLevel === liveThinking) ?? candidates.find(onLiveModel))?.rank;
860
874
  if (liveRank === undefined)
861
875
  return false;
862
876
  const preferred = candidates.find((candidate) => candidate.rank < liveRank && resolveProviderCandidates([{