@vellumai/assistant 0.8.8 → 0.8.9-staging.1

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 (340) hide show
  1. package/bun.lock +2 -2
  2. package/examples/plugins/echo/README.md +61 -60
  3. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  4. package/examples/plugins/echo/hooks/stop.ts +16 -0
  5. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  6. package/examples/plugins/echo/package.json +1 -2
  7. package/examples/plugins/echo/src/emit.ts +19 -0
  8. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  9. package/openapi.yaml +236 -6
  10. package/package.json +2 -2
  11. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  12. package/src/__tests__/agent-loop-exit-reason.test.ts +185 -140
  13. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  14. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  15. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  16. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  17. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  18. package/src/__tests__/agent-loop.test.ts +441 -96
  19. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  20. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  21. package/src/__tests__/anthropic-provider.test.ts +1 -1
  22. package/src/__tests__/app-control-flow.test.ts +1 -1
  23. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  24. package/src/__tests__/approval-cascade.test.ts +5 -4
  25. package/src/__tests__/approval-routes-http.test.ts +4 -1
  26. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  27. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  28. package/src/__tests__/channel-approvals.test.ts +1 -1
  29. package/src/__tests__/compaction-circuit.test.ts +258 -0
  30. package/src/__tests__/compaction-direct.test.ts +132 -0
  31. package/src/__tests__/compaction-events.test.ts +5 -5
  32. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
  33. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  34. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +59 -103
  35. package/src/__tests__/conversation-agent-loop-overflow.test.ts +94 -189
  36. package/src/__tests__/conversation-agent-loop.test.ts +249 -490
  37. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  38. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
  39. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  40. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
  41. package/src/__tests__/conversation-process-callsite.test.ts +14 -14
  42. package/src/__tests__/conversation-provider-retry-repair.test.ts +18 -16
  43. package/src/__tests__/conversation-queue.test.ts +9 -9
  44. package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
  45. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  46. package/src/__tests__/conversation-slash-queue.test.ts +6 -4
  47. package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
  48. package/src/__tests__/conversation-speed-override.test.ts +10 -9
  49. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  50. package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
  51. package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
  52. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
  53. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  54. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  55. package/src/__tests__/db-acp-history.test.ts +101 -0
  56. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  57. package/src/__tests__/empty-response-hook.test.ts +1 -1
  58. package/src/__tests__/file-write-tool.test.ts +63 -0
  59. package/src/__tests__/gateway-only-guard.test.ts +12 -2
  60. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  61. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  62. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  63. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  64. package/src/__tests__/heartbeat-service.test.ts +1 -0
  65. package/src/__tests__/history-repair-hook.test.ts +1 -1
  66. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  67. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  68. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  69. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  70. package/src/__tests__/injector-background-turn.test.ts +13 -23
  71. package/src/__tests__/injector-chain.test.ts +268 -44
  72. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  73. package/src/__tests__/injector-document-comments.test.ts +97 -114
  74. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  75. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  76. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  77. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  78. package/src/__tests__/memory-retrieval-hook.test.ts +73 -6
  79. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  80. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  81. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  82. package/src/__tests__/plugin-bootstrap.test.ts +12 -23
  83. package/src/__tests__/plugin-registry.test.ts +3 -49
  84. package/src/__tests__/plugin-types.test.ts +0 -70
  85. package/src/__tests__/reaction-persistence.test.ts +1 -1
  86. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  87. package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
  88. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  89. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  90. package/src/__tests__/subagent-detail.test.ts +25 -7
  91. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  92. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  93. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  94. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  95. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  96. package/src/__tests__/title-generate-hook.test.ts +1 -1
  97. package/src/__tests__/tool-error-hook.test.ts +1 -1
  98. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  99. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  100. package/src/acp/__tests__/agent-process.test.ts +161 -0
  101. package/src/acp/__tests__/client-handler.test.ts +40 -0
  102. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  103. package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
  104. package/src/acp/__tests__/prepare-agent-env.test.ts +137 -0
  105. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  106. package/src/acp/__tests__/session-manager-resume.test.ts +736 -0
  107. package/src/acp/agent-process.ts +61 -1
  108. package/src/acp/auto-install.test.ts +196 -0
  109. package/src/acp/auto-install.ts +177 -0
  110. package/src/acp/client-handler.ts +31 -0
  111. package/src/acp/feature-gate.test.ts +48 -0
  112. package/src/acp/feature-gate.ts +34 -0
  113. package/src/acp/prepare-agent-env.ts +83 -29
  114. package/src/acp/resolve-agent.test.ts +320 -7
  115. package/src/acp/resolve-agent.ts +182 -18
  116. package/src/acp/resume-hint.ts +25 -0
  117. package/src/acp/session-manager.ts +495 -73
  118. package/src/acp/types.ts +8 -0
  119. package/src/agent/compaction-circuit.ts +60 -102
  120. package/src/agent/loop.ts +390 -240
  121. package/src/api/responses/conversation-message.ts +14 -1
  122. package/src/approvals/guardian-request-resolvers.ts +1 -1
  123. package/src/background-wake/next-wake.ts +1 -0
  124. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  125. package/src/cli/commands/plugins.ts +43 -37
  126. package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
  127. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  128. package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
  129. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
  130. package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
  131. package/src/cli/lib/install-from-github.ts +464 -55
  132. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  133. package/src/cli/lib/plugin-details.ts +409 -0
  134. package/src/cli/lib/plugin-marketplace.ts +197 -0
  135. package/src/cli/lib/search-plugins.ts +195 -29
  136. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  137. package/src/config/acp-defaults.test.ts +10 -0
  138. package/src/config/acp-defaults.ts +6 -0
  139. package/src/config/bundled-skills/acp/SKILL.md +83 -31
  140. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  141. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  142. package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
  143. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  144. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  145. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  146. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  147. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  148. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  149. package/src/config/bundled-tool-registry.ts +2 -0
  150. package/src/config/feature-flag-registry.json +14 -5
  151. package/src/config/schemas/heartbeat.ts +9 -0
  152. package/src/context/strip-injections.ts +8 -2
  153. package/src/context/window-manager.ts +27 -13
  154. package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
  155. package/src/daemon/conversation-agent-loop.ts +167 -1005
  156. package/src/daemon/conversation-lifecycle.ts +11 -255
  157. package/src/daemon/conversation-process.ts +8 -136
  158. package/src/daemon/conversation-registry.ts +159 -0
  159. package/src/daemon/conversation-runtime-assembly.ts +293 -392
  160. package/src/daemon/conversation-store.ts +9 -90
  161. package/src/daemon/conversation-surfaces.ts +24 -8
  162. package/src/daemon/conversation-workspace.ts +17 -0
  163. package/src/daemon/conversation.ts +383 -56
  164. package/src/daemon/external-plugins-bootstrap.ts +14 -19
  165. package/src/daemon/handlers/conversations.ts +3 -1
  166. package/src/daemon/handlers/skills.ts +4 -1
  167. package/src/daemon/host-proxy-preactivation.ts +1 -3
  168. package/src/daemon/lifecycle.ts +21 -0
  169. package/src/daemon/server.ts +2 -0
  170. package/src/daemon/wake-conversation-ops.ts +269 -0
  171. package/src/embedded/plugin-api.ts +2 -2
  172. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  173. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  174. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  175. package/src/heartbeat/heartbeat-service.ts +26 -0
  176. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  177. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  178. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  179. package/src/ipc/skill-routes/memory.ts +4 -2
  180. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  181. package/src/memory/conversation-crud.ts +29 -19
  182. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  183. package/src/memory/db-init.ts +2 -0
  184. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  185. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  186. package/src/memory/jobs-worker.ts +25 -1
  187. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  188. package/src/memory/migrations/index.ts +1 -0
  189. package/src/memory/schema/acp.ts +4 -0
  190. package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
  191. package/src/memory/v2/consolidation-job.ts +13 -4
  192. package/src/plugin-api/constants.ts +4 -0
  193. package/src/plugin-api/index.ts +6 -5
  194. package/src/plugin-api/types.ts +75 -0
  195. package/src/plugins/defaults/compaction/compact.ts +59 -0
  196. package/src/plugins/defaults/compaction/manager-store.ts +44 -0
  197. package/src/plugins/defaults/compaction/package.json +1 -2
  198. package/src/plugins/defaults/empty-response/package.json +0 -1
  199. package/src/plugins/defaults/history-repair/package.json +0 -1
  200. package/src/plugins/defaults/index.ts +135 -26
  201. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +103 -38
  202. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +167 -56
  203. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  204. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  205. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  206. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
  207. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +9 -6
  208. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
  209. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +8 -5
  210. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
  211. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
  212. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +10 -5
  213. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
  214. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +5 -5
  215. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
  216. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
  217. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
  218. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
  219. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  220. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  221. package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
  222. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
  223. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
  224. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  225. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
  226. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
  227. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
  228. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
  229. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +5 -5
  230. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
  231. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +7 -7
  232. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
  233. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
  234. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -1
  235. package/src/plugins/defaults/title-generate/package.json +0 -1
  236. package/src/plugins/defaults/tool-error/package.json +0 -1
  237. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  238. package/src/plugins/pipeline.ts +6 -293
  239. package/src/plugins/registry.ts +9 -37
  240. package/src/plugins/types.ts +76 -381
  241. package/src/plugins/user-loader.ts +30 -127
  242. package/src/proactive-artifact/aux-message-injector.ts +1 -1
  243. package/src/proactive-artifact/job.test.ts +1 -1
  244. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  245. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
  246. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  247. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  248. package/src/runtime/agent-wake.ts +108 -209
  249. package/src/runtime/assistant-event-hub.ts +1 -1
  250. package/src/runtime/channel-approvals.ts +1 -1
  251. package/src/runtime/interactive-ui.ts +1 -1
  252. package/src/runtime/routes/__tests__/acp-routes.test.ts +283 -55
  253. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  254. package/src/runtime/routes/__tests__/plugins-routes.test.ts +398 -73
  255. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  256. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  257. package/src/runtime/routes/acp-routes.test.ts +89 -25
  258. package/src/runtime/routes/acp-routes.ts +81 -29
  259. package/src/runtime/routes/approval-routes.ts +1 -1
  260. package/src/runtime/routes/browser-routes.ts +1 -1
  261. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  262. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  263. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  264. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  265. package/src/runtime/routes/conversation-routes.ts +28 -2
  266. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  267. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  268. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  269. package/src/runtime/routes/host-cu-routes.ts +1 -1
  270. package/src/runtime/routes/identity-routes.ts +18 -3
  271. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  272. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  273. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  274. package/src/runtime/routes/memory-v3-routes.ts +16 -6
  275. package/src/runtime/routes/playground/helpers.ts +1 -1
  276. package/src/runtime/routes/plugins-routes.ts +336 -35
  277. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  278. package/src/runtime/routes/work-items-routes.ts +2 -4
  279. package/src/runtime/services/conversation-serializer.ts +1 -1
  280. package/src/signals/cancel.ts +2 -4
  281. package/src/subagent/manager.ts +21 -5
  282. package/src/tools/acp/context.ts +20 -0
  283. package/src/tools/acp/list-agents.test.ts +7 -1
  284. package/src/tools/acp/spawn.test.ts +158 -55
  285. package/src/tools/acp/spawn.ts +47 -72
  286. package/src/tools/acp/steer.test.ts +105 -8
  287. package/src/tools/acp/steer.ts +48 -17
  288. package/src/tools/apps/executors.ts +13 -8
  289. package/src/tools/filesystem/write.ts +34 -0
  290. package/src/tools/subagent/spawn.ts +2 -4
  291. package/src/tools/ui-surface/definitions.ts +25 -5
  292. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  293. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  294. package/docs/plugins.md +0 -832
  295. package/examples/plugins/echo/register.ts +0 -143
  296. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  297. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  298. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  299. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  300. package/src/__tests__/pipeline-runner.test.ts +0 -554
  301. package/src/__tests__/plugin-external-api.test.ts +0 -68
  302. package/src/daemon/wake-target-adapter.ts +0 -253
  303. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  304. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  305. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  306. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  307. package/src/plugins/defaults/compaction/register.ts +0 -35
  308. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  309. package/src/plugins/defaults/empty-response/register.ts +0 -23
  310. package/src/plugins/defaults/history-repair/register.ts +0 -24
  311. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  312. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  313. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  314. package/src/plugins/defaults/title-generate/register.ts +0 -35
  315. package/src/plugins/defaults/tool-error/register.ts +0 -23
  316. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  317. package/src/plugins/external-api.ts +0 -104
  318. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
  319. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
  320. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  321. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  322. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +0 -0
  323. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
  324. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/provider-blocks.test.ts +0 -0
  325. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
  326. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
  327. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  328. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  329. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
  330. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  331. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  332. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  333. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  334. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  335. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  336. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
  337. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
  338. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
  339. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
  340. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
@@ -1,13 +1,23 @@
1
1
  /**
2
- * Tests for `GET /v1/acp/sessions`.
2
+ * Tests for ACP route handlers.
3
3
  *
4
- * The handler merges in-memory `AcpSessionManager.getStatus()` output with
5
- * persisted `acp_session_history` rows, deduping by id (in-memory wins),
6
- * filtering by `?conversationId`, sorting newest-first, and truncating to
7
- * `?limit` (default 50, max 500).
4
+ * `GET /v1/acp/sessions`: the handler merges in-memory
5
+ * `AcpSessionManager.getStatus()` output with persisted
6
+ * `acp_session_history` rows, deduping by id (in-memory wins), filtering by
7
+ * `?conversationId`, sorting newest-first, and truncating to `?limit`
8
+ * (default 50, max 500).
9
+ *
10
+ * `POST /v1/acp/spawn`: when the adapter binary is missing, the handler
11
+ * silently auto-installs allowlisted adapter packages before failing with
12
+ * the install hint. `execFile` is stubbed via the shared
13
+ * `installExecFileStub` helper so tests can script `npm i -g` outcomes.
8
14
  */
9
15
 
10
- import { beforeEach, describe, expect, mock, test } from "bun:test";
16
+ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
17
+
18
+ import { installAcpConfigStub } from "../../../acp/__tests__/helpers/acp-config-stub.js";
19
+ import { installExecFileStub } from "../../../acp/__tests__/helpers/exec-file-stub.js";
20
+ import { installWhichStub } from "../../../acp/__tests__/helpers/which-stub.js";
11
21
 
12
22
  mock.module("../../../util/logger.js", () => ({
13
23
  getLogger: () =>
@@ -16,6 +26,12 @@ mock.module("../../../util/logger.js", () => ({
16
26
  }),
17
27
  }));
18
28
 
29
+ const {
30
+ execScripts,
31
+ execFileMock,
32
+ reset: resetExecFileStub,
33
+ } = installExecFileStub();
34
+
19
35
  // ---------------------------------------------------------------------------
20
36
  // Stub the ACP session manager so tests control the in-memory side without
21
37
  // spawning real child processes. The route handler imports
@@ -37,64 +53,61 @@ interface FakeSessionState {
37
53
 
38
54
  let fakeInMemorySessions: FakeSessionState[] = [];
39
55
 
56
+ const spawnMock = mock(async () => ({
57
+ acpSessionId: "acp-route-session",
58
+ protocolSessionId: "proto-route-session",
59
+ }));
60
+
61
+ const defaultSteerOrResumeImpl = async (
62
+ _id: string,
63
+ _instruction: string,
64
+ ): Promise<{ resumed: boolean }> => ({ resumed: false });
65
+ let steerOrResumeImpl: (
66
+ id: string,
67
+ instruction: string,
68
+ ) => Promise<{ resumed: boolean }> = defaultSteerOrResumeImpl;
69
+ const steerOrResumeMock = mock(
70
+ (id: string, instruction: string, _send: unknown) =>
71
+ steerOrResumeImpl(id, instruction),
72
+ );
73
+
40
74
  mock.module("../../../acp/index.js", () => ({
41
75
  getAcpSessionManager: () => ({
42
76
  getStatus: () => fakeInMemorySessions,
77
+ spawn: spawnMock,
78
+ steerOrResume: steerOrResumeMock,
43
79
  }),
44
80
  }));
45
81
 
46
- import { getSqlite } from "../../../memory/db-connection.js";
82
+ // Identity env-prep: the credential-broker plumbing it wraps is exercised in
83
+ // its own suite; spawn tests here only care about the resolve/install flow.
84
+ mock.module("../../../acp/prepare-agent-env.js", () => ({
85
+ prepareAgentEnv: async (agentConfig: unknown) => agentConfig,
86
+ }));
87
+
88
+ const config = await installAcpConfigStub();
89
+ const which = installWhichStub();
90
+
91
+ import {
92
+ clearHistory,
93
+ insertHistoryRow,
94
+ } from "../../../acp/__tests__/helpers/acp-history-db.js";
95
+ import {
96
+ AcpResumeError,
97
+ AcpSessionNotFoundError,
98
+ } from "../../../acp/session-manager.js";
47
99
  import { initializeDb } from "../../../memory/db-init.js";
48
- import { ROUTES } from "../acp-routes.js";
100
+ import { FailedDependencyError, NotFoundError } from "../errors.js";
49
101
 
50
- initializeDb();
102
+ const { ROUTES } = await import("../acp-routes.js");
103
+ const { _resetAdapterInstallCacheForTests } =
104
+ await import("../../../acp/auto-install.js");
51
105
 
52
- function clearHistory(): void {
53
- getSqlite().run("DELETE FROM acp_session_history");
54
- }
106
+ initializeDb();
55
107
 
56
- function insertHistoryRow(row: {
57
- id: string;
58
- agentId: string;
59
- acpSessionId: string;
60
- parentConversationId: string;
61
- startedAt: number;
62
- completedAt?: number | null;
63
- status: string;
64
- stopReason?: string | null;
65
- error?: string | null;
66
- eventLogJson?: string;
67
- }): void {
68
- getSqlite()
69
- .query(
70
- /*sql*/ `
71
- INSERT INTO acp_session_history (
72
- id,
73
- agent_id,
74
- acp_session_id,
75
- parent_conversation_id,
76
- started_at,
77
- completed_at,
78
- status,
79
- stop_reason,
80
- error,
81
- event_log_json
82
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
83
- `,
84
- )
85
- .run(
86
- row.id,
87
- row.agentId,
88
- row.acpSessionId,
89
- row.parentConversationId,
90
- row.startedAt,
91
- row.completedAt ?? null,
92
- row.status,
93
- row.stopReason ?? null,
94
- row.error ?? null,
95
- row.eventLogJson ?? "[]",
96
- );
97
- }
108
+ afterAll(() => {
109
+ which.restore();
110
+ });
98
111
 
99
112
  function getSessionsHandler() {
100
113
  const route = ROUTES.find(
@@ -122,6 +135,13 @@ interface ResponseShape {
122
135
  beforeEach(() => {
123
136
  fakeInMemorySessions = [];
124
137
  clearHistory();
138
+ resetExecFileStub();
139
+ spawnMock.mockClear();
140
+ steerOrResumeMock.mockClear();
141
+ steerOrResumeImpl = defaultSteerOrResumeImpl;
142
+ _resetAdapterInstallCacheForTests();
143
+ config.setConfig({});
144
+ which.setWhich((cmd) => `/usr/local/bin/${cmd}`);
125
145
  });
126
146
 
127
147
  describe("GET /v1/acp/sessions — merged in-memory + history", () => {
@@ -306,7 +326,9 @@ describe("GET /v1/acp/sessions — merged in-memory + history", () => {
306
326
  });
307
327
 
308
328
  const handler = getSessionsHandler();
309
- const body = (await handler({ queryParams: { limit: "2" } })) as ResponseShape;
329
+ const body = (await handler({
330
+ queryParams: { limit: "2" },
331
+ })) as ResponseShape;
310
332
  expect(body.sessions).toHaveLength(2);
311
333
  expect(body.sessions.map((s) => s.id)).toEqual(["live-newest", "hist-mid"]);
312
334
  });
@@ -392,3 +414,209 @@ describe("GET /v1/acp/sessions — merged in-memory + history", () => {
392
414
  expect(body.sessions).toHaveLength(3);
393
415
  });
394
416
  });
417
+
418
+ // ---------------------------------------------------------------------------
419
+ // POST /v1/acp/spawn: auto-install on missing adapter binary
420
+ // ---------------------------------------------------------------------------
421
+
422
+ function getSpawnHandler() {
423
+ const route = ROUTES.find(
424
+ (r) => r.endpoint === "acp/spawn" && r.method === "POST",
425
+ );
426
+ if (!route) throw new Error("acp/spawn POST route not found");
427
+ return route.handler;
428
+ }
429
+
430
+ const SPAWN_BODY = {
431
+ agent: "claude",
432
+ task: "do something",
433
+ conversationId: "conv-1",
434
+ };
435
+
436
+ describe("POST /v1/acp/spawn: auto-install on missing binary", () => {
437
+ test("binary missing + bun present: spawn proceeds via bunx without npm", async () => {
438
+ which.setWhich({ bun: "/usr/local/bin/bun" });
439
+
440
+ const handler = getSpawnHandler();
441
+ const body = (await handler({ body: SPAWN_BODY })) as Record<
442
+ string,
443
+ unknown
444
+ >;
445
+
446
+ expect(body).toEqual({
447
+ acpSessionId: "acp-route-session",
448
+ protocolSessionId: "proto-route-session",
449
+ agent: "claude",
450
+ });
451
+ expect(execFileMock).not.toHaveBeenCalled();
452
+ expect(spawnMock).toHaveBeenCalledTimes(1);
453
+ const agentConfigArg = (spawnMock.mock.calls[0] as unknown[])[1] as {
454
+ command: string;
455
+ args: string[];
456
+ adapterCommand?: string;
457
+ };
458
+ expect(agentConfigArg.command).toBe("bun");
459
+ expect(agentConfigArg.args).toEqual([
460
+ "x",
461
+ "--bun",
462
+ "@agentclientprotocol/claude-agent-acp",
463
+ ]);
464
+ expect(agentConfigArg.adapterCommand).toBe("claude-agent-acp");
465
+ });
466
+
467
+ test("known command: installs the mapped package and spawn proceeds", async () => {
468
+ // Binary appears on PATH only after `npm i -g` runs, simulating a
469
+ // successful global install.
470
+ let binaryOnPath = false;
471
+ which.setWhich((cmd) => (binaryOnPath ? `/usr/local/bin/${cmd}` : null));
472
+ execScripts.set("npm i", {
473
+ stdout: "",
474
+ onCall: () => {
475
+ binaryOnPath = true;
476
+ },
477
+ });
478
+
479
+ const handler = getSpawnHandler();
480
+ const body = (await handler({ body: SPAWN_BODY })) as Record<
481
+ string,
482
+ unknown
483
+ >;
484
+
485
+ expect(body).toEqual({
486
+ acpSessionId: "acp-route-session",
487
+ protocolSessionId: "proto-route-session",
488
+ agent: "claude",
489
+ });
490
+ expect(spawnMock).toHaveBeenCalledTimes(1);
491
+ expect(execFileMock).toHaveBeenCalledTimes(1);
492
+ expect(execFileMock.mock.calls[0][1]).toEqual([
493
+ "i",
494
+ "-g",
495
+ "@agentclientprotocol/claude-agent-acp",
496
+ ]);
497
+ });
498
+
499
+ test("npm failure: FailedDependencyError carries hint and failure reason", async () => {
500
+ which.setWhich({});
501
+ execScripts.set("npm i", {
502
+ error: new Error("EACCES: permission denied"),
503
+ });
504
+
505
+ const handler = getSpawnHandler();
506
+ const promise = handler({ body: SPAWN_BODY });
507
+ await expect(promise).rejects.toBeInstanceOf(FailedDependencyError);
508
+ await expect(promise).rejects.toThrow(
509
+ /claude-agent-acp is not on PATH.*npm i -g @agentclientprotocol\/claude-agent-acp.*auto-install failed.*EACCES/,
510
+ );
511
+ expect(spawnMock).not.toHaveBeenCalled();
512
+ });
513
+
514
+ test("unknown command: plain hint maps to FailedDependencyError", async () => {
515
+ // The allowlist itself (no npm invocation for unmapped commands) is
516
+ // pinned in auto-install.test.ts and spawn.test.ts; this asserts only
517
+ // the route's transport mapping of the plain-hint failure.
518
+ config.setConfig({
519
+ agents: { custom: { command: "custom-bin", args: [] } },
520
+ });
521
+ which.setWhich({});
522
+
523
+ const handler = getSpawnHandler();
524
+ const promise = handler({ body: { ...SPAWN_BODY, agent: "custom" } });
525
+ await expect(promise).rejects.toBeInstanceOf(FailedDependencyError);
526
+ await expect(promise).rejects.toThrow(
527
+ "custom-bin is not on PATH. Install 'custom-bin' and ensure it is on PATH.",
528
+ );
529
+ });
530
+ });
531
+
532
+ // ---------------------------------------------------------------------------
533
+ // POST /v1/acp/:id/steer: transparent resume of sessions not in memory
534
+ // ---------------------------------------------------------------------------
535
+
536
+ function getSteerHandler() {
537
+ const route = ROUTES.find(
538
+ (r) => r.endpoint === "acp/:id/steer" && r.method === "POST",
539
+ );
540
+ if (!route) throw new Error("acp/:id/steer POST route not found");
541
+ return route.handler;
542
+ }
543
+
544
+ describe("POST /v1/acp/:id/steer: resume fallback", () => {
545
+ test("in-memory session steers without a resume", async () => {
546
+ const handler = getSteerHandler();
547
+ const body = await handler({
548
+ pathParams: { id: "live-1" },
549
+ body: { instruction: "redirect" },
550
+ });
551
+
552
+ expect(body).toEqual({ acpSessionId: "live-1", steered: true });
553
+ expect(steerOrResumeMock).toHaveBeenCalledTimes(1);
554
+ expect(steerOrResumeMock.mock.calls[0][0]).toBe("live-1");
555
+ expect(steerOrResumeMock.mock.calls[0][1]).toBe("redirect");
556
+ expect(typeof steerOrResumeMock.mock.calls[0][2]).toBe("function");
557
+ });
558
+
559
+ test("resumed session reports the resumed flag", async () => {
560
+ steerOrResumeImpl = async () => ({ resumed: true });
561
+
562
+ const handler = getSteerHandler();
563
+ const body = await handler({
564
+ pathParams: { id: "gone-1" },
565
+ body: { instruction: "keep going" },
566
+ });
567
+
568
+ expect(body).toEqual({
569
+ acpSessionId: "gone-1",
570
+ steered: true,
571
+ resumed: true,
572
+ });
573
+ });
574
+
575
+ test("typed not-found (no session, no history row) maps to NotFoundError", async () => {
576
+ steerOrResumeImpl = async (id) => {
577
+ throw new AcpSessionNotFoundError(id);
578
+ };
579
+
580
+ const handler = getSteerHandler();
581
+ const promise = handler({
582
+ pathParams: { id: "missing-1" },
583
+ body: { instruction: "go" },
584
+ });
585
+ await expect(promise).rejects.toBeInstanceOf(NotFoundError);
586
+ });
587
+
588
+ test("resume failure surfaces as FailedDependencyError with the actionable hint", async () => {
589
+ steerOrResumeImpl = async (id) => {
590
+ throw new AcpResumeError(
591
+ new Error(
592
+ `ACP session "${id}" was recorded before resume support ` +
593
+ `(no working directory persisted) and cannot be resumed. ` +
594
+ `Spawn a new session instead.`,
595
+ ),
596
+ );
597
+ };
598
+
599
+ const handler = getSteerHandler();
600
+ const promise = handler({
601
+ pathParams: { id: "legacy-1" },
602
+ body: { instruction: "go" },
603
+ });
604
+ await expect(promise).rejects.toBeInstanceOf(FailedDependencyError);
605
+ await expect(promise).rejects.toThrow(/recorded before resume support/);
606
+ });
607
+
608
+ test("plain steer errors map to NotFoundError", async () => {
609
+ steerOrResumeImpl = async (id) => {
610
+ throw new Error(
611
+ `ACP session "${id}" is not running (status: initializing)`,
612
+ );
613
+ };
614
+
615
+ const handler = getSteerHandler();
616
+ const promise = handler({
617
+ pathParams: { id: "init-1" },
618
+ body: { instruction: "go" },
619
+ });
620
+ await expect(promise).rejects.toBeInstanceOf(NotFoundError);
621
+ });
622
+ });
@@ -23,7 +23,7 @@ mock.module("../../assistant-event-hub.js", () => ({
23
23
  broadcastMessage: () => {},
24
24
  }));
25
25
 
26
- import { findConversation } from "../../../daemon/conversation-store.js";
26
+ import { findConversation } from "../../../daemon/conversation-registry.js";
27
27
  import { createConversation } from "../../../memory/conversation-crud.js";
28
28
  import { getDb } from "../../../memory/db-connection.js";
29
29
  import { initializeDb } from "../../../memory/db-init.js";