@vellumai/assistant 0.8.5 → 0.8.7

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 (1171) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +1 -1
  3. package/Dockerfile +1 -0
  4. package/bun.lock +11 -2
  5. package/bunfig.toml +6 -1
  6. package/docker-entrypoint.sh +8 -6
  7. package/docs/credential-execution-service.md +6 -6
  8. package/docs/plugins.md +67 -31
  9. package/examples/plugins/echo/register.ts +4 -7
  10. package/knip.json +1 -0
  11. package/node_modules/@vellumai/environments/bun.lock +24 -0
  12. package/node_modules/@vellumai/environments/package.json +18 -0
  13. package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
  14. package/node_modules/@vellumai/environments/src/index.ts +11 -0
  15. package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
  16. package/node_modules/@vellumai/environments/src/types.ts +70 -0
  17. package/node_modules/@vellumai/environments/tsconfig.json +20 -0
  18. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
  19. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +15 -17
  20. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +10 -3
  21. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  22. package/openapi.yaml +5585 -469
  23. package/package.json +7 -3
  24. package/scripts/generate-openapi.ts +20 -13
  25. package/src/__tests__/actor-token-service.test.ts +3 -2
  26. package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
  27. package/src/__tests__/agent-loop-exit-reason.test.ts +336 -42
  28. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
  29. package/src/__tests__/agent-loop-override-profile.test.ts +21 -33
  30. package/src/__tests__/agent-loop-provider-error-recording.test.ts +6 -4
  31. package/src/__tests__/agent-loop-thinking.test.ts +17 -12
  32. package/src/__tests__/agent-loop.test.ts +207 -341
  33. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +5 -2
  34. package/src/__tests__/agent-wake-override-profile.test.ts +23 -40
  35. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  36. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  37. package/src/__tests__/anthropic-provider.test.ts +201 -55
  38. package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
  39. package/src/__tests__/app-control-flow.test.ts +5 -0
  40. package/src/__tests__/approval-cascade.test.ts +5 -11
  41. package/src/__tests__/approval-routes-http.test.ts +13 -15
  42. package/src/__tests__/assert-not-live-db.ts +79 -0
  43. package/src/__tests__/assistant-event.test.ts +15 -0
  44. package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -27
  45. package/src/__tests__/audit-log-rotation.test.ts +2 -2
  46. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  47. package/src/__tests__/avatar-e2e.test.ts +7 -37
  48. package/src/__tests__/avatar-generator.test.ts +12 -42
  49. package/src/__tests__/avatar-identity-sync.test.ts +28 -3
  50. package/src/__tests__/background-shell-bash.test.ts +3 -7
  51. package/src/__tests__/background-workers-disk-pressure.test.ts +5 -8
  52. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  53. package/src/__tests__/btw-routes.test.ts +10 -14
  54. package/src/__tests__/call-controller.test.ts +3 -2
  55. package/src/__tests__/call-pointer-messages.test.ts +5 -3
  56. package/src/__tests__/call-site-routing-provider.test.ts +22 -40
  57. package/src/__tests__/catalog-files.test.ts +1 -0
  58. package/src/__tests__/channel-approval-routes.test.ts +51 -22
  59. package/src/__tests__/channel-approvals.test.ts +3 -1
  60. package/src/__tests__/channel-guardian.test.ts +3 -2
  61. package/src/__tests__/channel-invite-transport.test.ts +1 -5
  62. package/src/__tests__/channel-readiness-routes.test.ts +0 -4
  63. package/src/__tests__/channel-readiness-slack-remote.test.ts +170 -0
  64. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  65. package/src/__tests__/channel-retry-sweep.test.ts +388 -79
  66. package/src/__tests__/checker.test.ts +12 -12
  67. package/src/__tests__/circuit-breaker-pipeline.test.ts +3 -3
  68. package/src/__tests__/clawhub-files.test.ts +1 -0
  69. package/src/__tests__/compaction-events.test.ts +6 -17
  70. package/src/__tests__/compaction-pipeline.test.ts +1 -1
  71. package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
  72. package/src/__tests__/compaction-trail-store.test.ts +186 -0
  73. package/src/__tests__/compactor-call-site-logging.test.ts +1 -0
  74. package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
  75. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  76. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +7 -5
  77. package/src/__tests__/computer-use-tools.test.ts +14 -16
  78. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  79. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  80. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  81. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  82. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  83. package/src/__tests__/config-schema.test.ts +10 -10
  84. package/src/__tests__/config-watcher.test.ts +28 -0
  85. package/src/__tests__/connection-model-compat.test.ts +83 -0
  86. package/src/__tests__/contacts-tools.test.ts +3 -2
  87. package/src/__tests__/context-search-agent-runner.test.ts +6 -3
  88. package/src/__tests__/context-token-estimator.test.ts +56 -0
  89. package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
  90. package/src/__tests__/conversation-abort-tool-results.test.ts +19 -7
  91. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +4 -2
  92. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  93. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -27
  94. package/src/__tests__/conversation-agent-loop-overflow.test.ts +464 -90
  95. package/src/__tests__/conversation-agent-loop.test.ts +1069 -64
  96. package/src/__tests__/conversation-analysis-routes.test.ts +2 -3
  97. package/src/__tests__/conversation-app-control-instantiation.test.ts +29 -19
  98. package/src/__tests__/conversation-app-control-lifecycle.test.ts +2 -1
  99. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  100. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  101. package/src/__tests__/conversation-clear-safety.test.ts +20 -10
  102. package/src/__tests__/conversation-confirmation-signals.test.ts +16 -45
  103. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  104. package/src/__tests__/conversation-disk-view.test.ts +10 -17
  105. package/src/__tests__/conversation-error.test.ts +30 -0
  106. package/src/__tests__/conversation-fork-crud.test.ts +132 -157
  107. package/src/__tests__/conversation-fork-route.test.ts +19 -16
  108. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  109. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  110. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  111. package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
  112. package/src/__tests__/conversation-lifecycle.test.ts +4 -2
  113. package/src/__tests__/conversation-list-source.test.ts +3 -2
  114. package/src/__tests__/conversation-load-history-repair.test.ts +5 -3
  115. package/src/__tests__/conversation-load-history-stripped.test.ts +2 -1
  116. package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
  117. package/src/__tests__/conversation-pairing.test.ts +87 -4
  118. package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
  119. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +30 -7
  120. package/src/__tests__/conversation-process-callsite.test.ts +28 -30
  121. package/src/__tests__/conversation-provider-retry-repair.test.ts +58 -44
  122. package/src/__tests__/conversation-queue.test.ts +603 -455
  123. package/src/__tests__/conversation-routes-disk-view.test.ts +6 -20
  124. package/src/__tests__/conversation-routes-guardian-reply.test.ts +35 -10
  125. package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -4
  126. package/src/__tests__/conversation-runtime-assembly.test.ts +98 -22
  127. package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
  128. package/src/__tests__/conversation-skill-tools.test.ts +38 -142
  129. package/src/__tests__/conversation-slash-queue.test.ts +120 -62
  130. package/src/__tests__/conversation-slash-unknown.test.ts +18 -15
  131. package/src/__tests__/conversation-speed-override.test.ts +9 -22
  132. package/src/__tests__/conversation-stream-state.test.ts +484 -0
  133. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +52 -15
  134. package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
  135. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  136. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  137. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  138. package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
  139. package/src/__tests__/conversation-surfaces-table-action.test.ts +13 -32
  140. package/src/__tests__/conversation-sync-tags.test.ts +128 -12
  141. package/src/__tests__/conversation-title-service.test.ts +1 -0
  142. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +53 -11
  143. package/src/__tests__/conversation-unread-route.test.ts +14 -2
  144. package/src/__tests__/conversation-usage.test.ts +1 -2
  145. package/src/__tests__/conversation-wipe.test.ts +1 -1
  146. package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
  147. package/src/__tests__/conversation-workspace-injection.test.ts +53 -22
  148. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +32 -7
  149. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  150. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  151. package/src/__tests__/credential-execution-client.test.ts +72 -1
  152. package/src/__tests__/credential-execution-feature-gates.test.ts +10 -12
  153. package/src/__tests__/credential-execution-tools.test.ts +1 -2
  154. package/src/__tests__/credential-health-service.test.ts +252 -3
  155. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  156. package/src/__tests__/credential-vault-unit.test.ts +19 -19
  157. package/src/__tests__/credential-vault.test.ts +5 -5
  158. package/src/__tests__/cross-provider-web-search.test.ts +61 -3
  159. package/src/__tests__/cu-unified-flow.test.ts +26 -1
  160. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  161. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  162. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  163. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  164. package/src/__tests__/db-schedule-syntax-migration.test.ts +11 -0
  165. package/src/__tests__/db-test-helpers.ts +58 -0
  166. package/src/__tests__/disk-pressure-guard.test.ts +119 -36
  167. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  168. package/src/__tests__/disk-pressure-routes.test.ts +9 -35
  169. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  170. package/src/__tests__/dm-persistence.test.ts +33 -42
  171. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  172. package/src/__tests__/document-find-replace.test.ts +3 -2
  173. package/src/__tests__/document-tool-security.test.ts +81 -2
  174. package/src/__tests__/dynamic-page-surface.test.ts +68 -0
  175. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  176. package/src/__tests__/edit-propagation.test.ts +1 -2
  177. package/src/__tests__/empty-response-pipeline.test.ts +127 -5
  178. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  179. package/src/__tests__/encrypted-store.test.ts +11 -9
  180. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  181. package/src/__tests__/filing-service.test.ts +3 -2
  182. package/src/__tests__/first-greeting.test.ts +103 -12
  183. package/src/__tests__/gateway-flag-listener.test.ts +0 -1
  184. package/src/__tests__/gemini-inline-media.test.ts +78 -0
  185. package/src/__tests__/gemini-provider.test.ts +375 -26
  186. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  187. package/src/__tests__/guardian-outbound-http.test.ts +3 -2
  188. package/src/__tests__/guardian-routing-state.test.ts +60 -71
  189. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  190. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +10 -7
  191. package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
  192. package/src/__tests__/heartbeat-service.test.ts +3 -1
  193. package/src/__tests__/helpers/mock-logger.ts +26 -0
  194. package/src/__tests__/history-repair-hook.test.ts +161 -0
  195. package/src/__tests__/history-repair-observability.test.ts +1 -1
  196. package/src/__tests__/history-repair.test.ts +2 -1
  197. package/src/__tests__/host-app-control-proxy.test.ts +2 -0
  198. package/src/__tests__/host-bash-routes.test.ts +1 -0
  199. package/src/__tests__/host-cu-proxy.test.ts +2 -0
  200. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  201. package/src/__tests__/host-file-edit-tool.test.ts +4 -2
  202. package/src/__tests__/host-file-proxy.test.ts +31 -0
  203. package/src/__tests__/host-file-read-tool.test.ts +4 -2
  204. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  205. package/src/__tests__/host-file-write-tool.test.ts +9 -3
  206. package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
  207. package/src/__tests__/host-shell-tool.test.ts +11 -5
  208. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  209. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  210. package/src/__tests__/http-user-message-parity.test.ts +31 -9
  211. package/src/__tests__/identity-intro-cache.test.ts +154 -22
  212. package/src/__tests__/inbound-slack-persistence.test.ts +51 -74
  213. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  214. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  215. package/src/__tests__/injector-background-turn.test.ts +1 -1
  216. package/src/__tests__/injector-chain.test.ts +1 -1
  217. package/src/__tests__/injector-disk-pressure.test.ts +4 -18
  218. package/src/__tests__/injector-document-comments.test.ts +1 -1
  219. package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
  220. package/src/__tests__/injector-v3-suppression.test.ts +220 -0
  221. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  222. package/src/__tests__/list-messages-attachments.test.ts +7 -8
  223. package/src/__tests__/list-messages-hidden-metadata.test.ts +93 -11
  224. package/src/__tests__/list-messages-page-latest.test.ts +0 -1
  225. package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
  226. package/src/__tests__/llm-call-pipeline.test.ts +21 -15
  227. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  228. package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
  229. package/src/__tests__/llm-resolver.test.ts +346 -39
  230. package/src/__tests__/llm-schema.test.ts +1 -1
  231. package/src/__tests__/llm-usage-store.test.ts +45 -0
  232. package/src/__tests__/log-export-routes.test.ts +59 -0
  233. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
  234. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  235. package/src/__tests__/mcp-abort-signal.test.ts +14 -0
  236. package/src/__tests__/mcp-auth-routes.test.ts +15 -10
  237. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  238. package/src/__tests__/mcp-health-check.test.ts +18 -13
  239. package/src/__tests__/memory-retrieval-pipeline.test.ts +1 -1
  240. package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
  241. package/src/__tests__/messaging-send-tool.test.ts +9 -4
  242. package/src/__tests__/migration-export-http.test.ts +12 -12
  243. package/src/__tests__/migration-import-commit-http.test.ts +8 -8
  244. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  245. package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
  246. package/src/__tests__/migration-validate-http.test.ts +3 -3
  247. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  248. package/src/__tests__/model-intents.test.ts +3 -3
  249. package/src/__tests__/native-web-search.test.ts +44 -22
  250. package/src/__tests__/notification-decision-identity.test.ts +9 -18
  251. package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
  252. package/src/__tests__/notification-deep-link.test.ts +62 -0
  253. package/src/__tests__/oauth-commands-routes.test.ts +38 -1
  254. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  255. package/src/__tests__/oauth-store.test.ts +3 -2
  256. package/src/__tests__/onboarding-template-contract.test.ts +13 -2
  257. package/src/__tests__/openai-provider.test.ts +74 -79
  258. package/src/__tests__/openai-responses-provider.test.ts +90 -86
  259. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  260. package/src/__tests__/outbound-slack-persistence.test.ts +48 -2
  261. package/src/__tests__/overflow-reduce-pipeline.test.ts +2 -4
  262. package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
  263. package/src/__tests__/persistence-pipeline.test.ts +154 -27
  264. package/src/__tests__/persistence-secret-redaction.test.ts +85 -13
  265. package/src/__tests__/pipeline-runner.test.ts +2 -3
  266. package/src/__tests__/plugin-bootstrap.test.ts +60 -36
  267. package/src/__tests__/plugin-route-contribution.test.ts +6 -16
  268. package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
  269. package/src/__tests__/plugin-tool-contribution.test.ts +51 -64
  270. package/src/__tests__/plugin-types.test.ts +7 -14
  271. package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
  272. package/src/__tests__/process-message-background-slack.test.ts +38 -32
  273. package/src/__tests__/process-message-display-content.test.ts +49 -64
  274. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  275. package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
  276. package/src/__tests__/provider-error-scenarios.test.ts +7 -6
  277. package/src/__tests__/provider-platform-proxy-integration.test.ts +215 -8
  278. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  279. package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
  280. package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
  281. package/src/__tests__/provider-usage-tracking.test.ts +0 -6
  282. package/src/__tests__/ratelimit.test.ts +9 -4
  283. package/src/__tests__/recording-handler.test.ts +1 -0
  284. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  285. package/src/__tests__/registry.test.ts +82 -76
  286. package/src/__tests__/relay-server.test.ts +30 -23
  287. package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
  288. package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
  289. package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
  290. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  291. package/src/__tests__/runtime-events-sse-reconnect.test.ts +353 -0
  292. package/src/__tests__/schedule-routes.test.ts +80 -10
  293. package/src/__tests__/schedule-store.test.ts +83 -1
  294. package/src/__tests__/schedule-tools.test.ts +125 -0
  295. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  296. package/src/__tests__/secret-ingress-http.test.ts +7 -3
  297. package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
  298. package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
  299. package/src/__tests__/secret-response-routing.test.ts +13 -11
  300. package/src/__tests__/secure-keys.test.ts +3 -3
  301. package/src/__tests__/send-endpoint-busy.test.ts +83 -43
  302. package/src/__tests__/server-history-render.test.ts +4 -1
  303. package/src/__tests__/shell-observability.test.ts +249 -0
  304. package/src/__tests__/skill-feature-flags-integration.test.ts +19 -21
  305. package/src/__tests__/skill-feature-flags.test.ts +20 -22
  306. package/src/__tests__/skill-load-feature-flag.test.ts +15 -15
  307. package/src/__tests__/skill-projection-feature-flag.test.ts +44 -30
  308. package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
  309. package/src/__tests__/skill-tool-factory.test.ts +96 -95
  310. package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
  311. package/src/__tests__/skillssh-files.test.ts +1 -0
  312. package/src/__tests__/slack-channel-config.test.ts +3 -3
  313. package/src/__tests__/starter-task-flow.test.ts +6 -6
  314. package/src/__tests__/strip-memory-injections.test.ts +102 -14
  315. package/src/__tests__/subagent-call-site-routing.test.ts +13 -5
  316. package/src/__tests__/subagent-disposal.test.ts +27 -8
  317. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  318. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  319. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  320. package/src/__tests__/subagent-notify-parent.test.ts +5 -4
  321. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  322. package/src/__tests__/subagent-tools.test.ts +2 -1
  323. package/src/__tests__/suggestion-routes.test.ts +4 -3
  324. package/src/__tests__/sync-message-contract.test.ts +19 -16
  325. package/src/__tests__/system-prompt.test.ts +92 -0
  326. package/src/__tests__/terminal-tools.test.ts +3 -24
  327. package/src/__tests__/test-preload-verifier.ts +68 -0
  328. package/src/__tests__/test-preload.ts +32 -39
  329. package/src/__tests__/thread-backfill.test.ts +4 -9
  330. package/src/__tests__/title-generate-pipeline.test.ts +1 -1
  331. package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
  332. package/src/__tests__/tool-error-pipeline.test.ts +2 -2
  333. package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
  334. package/src/__tests__/tool-executor-lifecycle-events.test.ts +20 -7
  335. package/src/__tests__/tool-executor.test.ts +55 -10
  336. package/src/__tests__/tool-preview-lifecycle.test.ts +14 -11
  337. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  338. package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
  339. package/src/__tests__/tool-result-truncation.test.ts +3 -1
  340. package/src/__tests__/tools-audio-read.test.ts +113 -0
  341. package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
  342. package/src/__tests__/turn-events-store.test.ts +11 -7
  343. package/src/__tests__/twilio-routes.test.ts +3 -2
  344. package/src/__tests__/validate-input.test.ts +381 -0
  345. package/src/__tests__/verification-control-plane-policy.test.ts +1 -0
  346. package/src/__tests__/voice-scoped-grant-consumer.test.ts +10 -7
  347. package/src/__tests__/voice-session-bridge.test.ts +50 -35
  348. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  349. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  350. package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
  351. package/src/acp/prepare-agent-env.ts +52 -11
  352. package/src/acp/session-manager.ts +5 -6
  353. package/src/agent/compaction-circuit.ts +140 -0
  354. package/src/agent/loop.ts +489 -85
  355. package/src/api/README.md +126 -2
  356. package/src/api/constants/call-sites.ts +27 -0
  357. package/src/api/constants/tool-execution.ts +21 -0
  358. package/src/api/events/assistant-activity-state.ts +75 -0
  359. package/src/api/events/assistant-outbound-attachment.ts +49 -0
  360. package/src/api/events/assistant-text-delta.ts +30 -0
  361. package/src/api/events/assistant-turn-start.ts +31 -0
  362. package/src/api/events/avatar-updated.ts +24 -0
  363. package/src/api/events/compaction-circuit-closed.ts +26 -0
  364. package/src/api/events/compaction-circuit-open.ts +28 -0
  365. package/src/api/events/confirmation-request.ts +114 -0
  366. package/src/api/events/contact-request.ts +33 -0
  367. package/src/api/events/conversation-error.ts +77 -0
  368. package/src/api/events/conversation-list-invalidated.ts +38 -0
  369. package/src/api/events/conversation-title-updated.ts +24 -0
  370. package/src/api/events/disk-pressure-status-changed.ts +61 -0
  371. package/src/api/events/document-comment-created.ts +44 -0
  372. package/src/api/events/document-comment-deleted.ts +22 -0
  373. package/src/api/events/document-comment-reopened.ts +23 -0
  374. package/src/api/events/document-comment-resolved.ts +25 -0
  375. package/src/api/events/document-editor-update.ts +27 -0
  376. package/src/api/events/error.ts +32 -0
  377. package/src/api/events/generation-cancelled.ts +22 -0
  378. package/src/api/events/generation-handoff.ts +39 -0
  379. package/src/api/events/home-feed-updated.ts +26 -0
  380. package/src/api/events/identity-changed.ts +32 -0
  381. package/src/api/events/interaction-resolved.ts +50 -0
  382. package/src/api/events/message-complete.ts +40 -0
  383. package/src/api/events/message-dequeued.ts +21 -0
  384. package/src/api/events/message-queued-deleted.ts +23 -0
  385. package/src/api/events/message-queued.ts +22 -0
  386. package/src/api/events/message-request-complete.ts +29 -0
  387. package/src/api/events/navigate-settings.ts +20 -0
  388. package/src/api/events/notification-intent.ts +33 -0
  389. package/src/api/events/open-url.ts +28 -0
  390. package/src/api/events/question-request.ts +67 -0
  391. package/src/{events → api/events}/relationship-state-updated.ts +6 -8
  392. package/src/api/events/secret-request.ts +42 -0
  393. package/src/api/events/subagent-event.ts +79 -0
  394. package/src/api/events/subagent-spawned.ts +40 -0
  395. package/src/api/events/subagent-status-changed.ts +65 -0
  396. package/src/api/events/sync-changed.ts +29 -0
  397. package/src/api/events/tool-result.ts +129 -0
  398. package/src/api/events/tool-use-start.ts +30 -0
  399. package/src/api/events/turn-profile-auto-routed.ts +28 -0
  400. package/src/api/events/ui-surface-complete.ts +30 -0
  401. package/src/api/events/ui-surface-dismiss.ts +22 -0
  402. package/src/api/events/ui-surface-show.ts +67 -0
  403. package/src/api/events/ui-surface-update.ts +26 -0
  404. package/src/api/events/usage-update.ts +34 -0
  405. package/src/api/events/user-message-echo.ts +35 -0
  406. package/src/api/index.ts +482 -3
  407. package/src/api/requests/dictation.ts +45 -0
  408. package/src/api/responses/disk-pressure-status.ts +26 -0
  409. package/src/api/responses/home.ts +217 -0
  410. package/src/api/responses/llm-context-response.ts +41 -0
  411. package/src/api/responses/llm-request-log-entry.ts +93 -0
  412. package/src/api/responses/memory-recall-log.ts +65 -0
  413. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  414. package/src/api/responses/memory-v3-selection-log.ts +50 -0
  415. package/src/api/responses/subagent-detail.ts +48 -0
  416. package/src/approvals/guardian-decision-primitive.ts +7 -15
  417. package/src/approvals/guardian-request-resolvers.ts +6 -9
  418. package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
  419. package/src/avatar/__tests__/avatar-store.test.ts +193 -0
  420. package/src/avatar/avatar-manifest.ts +195 -0
  421. package/src/avatar/avatar-store.ts +113 -0
  422. package/src/avatar/traits-png-sync.ts +8 -2
  423. package/src/background-wake/background-wake-routes.test.ts +687 -52
  424. package/src/background-wake/next-wake.test.ts +31 -1
  425. package/src/background-wake/next-wake.ts +4 -1
  426. package/src/background-wake/platform-client.test.ts +308 -0
  427. package/src/background-wake/platform-client.ts +167 -0
  428. package/src/background-wake/publisher.ts +91 -0
  429. package/src/background-wake/runtime-registry.ts +2 -2
  430. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  431. package/src/calls/call-conversation-messages.ts +6 -4
  432. package/src/calls/guardian-action-sweep.ts +6 -4
  433. package/src/calls/guardian-dispatch.ts +1 -0
  434. package/src/calls/relay-server.ts +12 -8
  435. package/src/calls/voice-session-bridge.ts +17 -31
  436. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  437. package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
  438. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  439. package/src/cli/commands/avatar.ts +17 -11
  440. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  441. package/src/cli/commands/channels/index.ts +229 -0
  442. package/src/cli/commands/conversations.ts +15 -1
  443. package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
  444. package/src/cli/commands/db/__tests__/status.test.ts +253 -0
  445. package/src/cli/commands/db/format.ts +48 -0
  446. package/src/cli/commands/db/index.ts +29 -0
  447. package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
  448. package/src/cli/commands/db/repair-step-integrity.ts +146 -0
  449. package/src/cli/commands/db/repair-steps.ts +164 -0
  450. package/src/cli/commands/db/repair.ts +141 -0
  451. package/src/cli/commands/db/status.ts +366 -0
  452. package/src/cli/commands/memory-v3.ts +168 -203
  453. package/src/cli/commands/notifications.ts +365 -55
  454. package/src/cli/lib/cli-colors.ts +24 -6
  455. package/src/cli/lib/open-browser.ts +7 -2
  456. package/src/cli/program.ts +6 -5
  457. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  458. package/src/config/assistant-feature-flags.ts +25 -44
  459. package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
  460. package/src/config/bundled-skills/document-editor/SKILL.md +5 -1
  461. package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
  462. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
  463. package/src/config/bundled-skills/schedule/SKILL.md +2 -2
  464. package/src/config/bundled-skills/schedule/TOOLS.json +10 -2
  465. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  466. package/src/config/call-site-defaults.ts +3 -8
  467. package/src/config/feature-flag-cache.ts +86 -0
  468. package/src/config/feature-flag-registry.json +42 -26
  469. package/src/config/llm-context-resolution.ts +10 -1
  470. package/src/config/llm-resolver.ts +121 -15
  471. package/src/config/loader.ts +4 -5
  472. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -211
  473. package/src/config/schemas/call-site-catalog.ts +8 -15
  474. package/src/config/schemas/heartbeat.ts +1 -1
  475. package/src/config/schemas/llm.ts +92 -4
  476. package/src/config/schemas/memory-lifecycle.ts +24 -0
  477. package/src/config/schemas/memory-v2.ts +0 -227
  478. package/src/config/schemas/memory-v3.ts +39 -0
  479. package/src/config/schemas/memory.ts +6 -1
  480. package/src/config/schemas/services.ts +6 -2
  481. package/src/config/schemas/timeouts.ts +3 -1
  482. package/src/config/seed-inference-profiles.ts +36 -16
  483. package/src/context/compactor.ts +54 -31
  484. package/src/context/token-estimator.ts +29 -5
  485. package/src/context/tool-result-truncation.ts +1 -43
  486. package/src/context/window-manager.ts +138 -20
  487. package/src/credential-execution/executable-discovery.ts +40 -0
  488. package/src/credential-execution/process-manager.ts +6 -2
  489. package/src/credential-health/credential-health-service.ts +125 -40
  490. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  491. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +15 -17
  492. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -2
  493. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  494. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  495. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  496. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  497. package/src/daemon/__tests__/web-search-status-text.test.ts +11 -6
  498. package/src/daemon/approval-generators.ts +4 -4
  499. package/src/daemon/config-watcher.ts +7 -1
  500. package/src/daemon/conversation-agent-loop-handlers.ts +613 -155
  501. package/src/daemon/conversation-agent-loop.ts +409 -605
  502. package/src/daemon/conversation-error.ts +40 -12
  503. package/src/daemon/conversation-history.ts +22 -6
  504. package/src/daemon/conversation-launch.ts +4 -8
  505. package/src/daemon/conversation-lifecycle.ts +10 -38
  506. package/src/daemon/conversation-messaging.ts +83 -44
  507. package/src/daemon/conversation-notifiers.ts +7 -5
  508. package/src/daemon/conversation-process.ts +174 -116
  509. package/src/daemon/conversation-runtime-assembly.ts +76 -30
  510. package/src/daemon/conversation-skill-tools.ts +14 -30
  511. package/src/daemon/conversation-store.ts +6 -5
  512. package/src/daemon/conversation-surfaces.ts +124 -103
  513. package/src/daemon/conversation-tool-setup.ts +36 -48
  514. package/src/daemon/conversation.ts +111 -166
  515. package/src/daemon/daemon-control.ts +1 -1
  516. package/src/daemon/daemon-skill-host.ts +7 -4
  517. package/src/daemon/disk-pressure-guard.ts +54 -50
  518. package/src/daemon/external-plugins-bootstrap.ts +46 -24
  519. package/src/daemon/first-greeting.ts +53 -13
  520. package/src/daemon/guardian-action-generators.ts +2 -2
  521. package/src/daemon/handlers/conversations.ts +6 -22
  522. package/src/daemon/handlers/shared.ts +10 -1
  523. package/src/daemon/handlers/skills.ts +15 -14
  524. package/src/daemon/host-app-control-proxy.ts +54 -1
  525. package/src/daemon/host-cu-proxy.ts +46 -22
  526. package/src/daemon/host-file-proxy.ts +25 -1
  527. package/src/daemon/host-proxy-preactivation.ts +25 -6
  528. package/src/daemon/lifecycle.ts +40 -67
  529. package/src/daemon/mcp-reload-service.ts +1 -1
  530. package/src/daemon/meet-manifest-loader.ts +10 -17
  531. package/src/daemon/message-protocol.ts +2 -3
  532. package/src/daemon/message-provenance.ts +49 -0
  533. package/src/daemon/message-types/contacts.ts +3 -20
  534. package/src/daemon/message-types/conversations.ts +25 -125
  535. package/src/daemon/message-types/document-comments.ts +8 -44
  536. package/src/daemon/message-types/documents.ts +3 -9
  537. package/src/daemon/message-types/home.ts +5 -18
  538. package/src/daemon/message-types/integrations.ts +4 -13
  539. package/src/daemon/message-types/messages.ts +47 -377
  540. package/src/daemon/message-types/notifications.ts +2 -32
  541. package/src/daemon/message-types/settings.ts +3 -8
  542. package/src/daemon/message-types/skills.ts +2 -0
  543. package/src/daemon/message-types/subagents.ts +6 -0
  544. package/src/daemon/message-types/surfaces.ts +2 -0
  545. package/src/daemon/message-types/sync.ts +12 -25
  546. package/src/daemon/message-types/workspace.ts +3 -11
  547. package/src/daemon/process-message.ts +58 -55
  548. package/src/daemon/providers-setup.ts +1 -1
  549. package/src/daemon/server.ts +28 -0
  550. package/src/daemon/switch-inference-profile-tool.ts +13 -3
  551. package/src/daemon/tool-setup-types.ts +0 -6
  552. package/src/daemon/tool-side-effects.ts +10 -7
  553. package/src/daemon/trust-context.ts +13 -0
  554. package/src/daemon/wake-target-adapter.ts +21 -1
  555. package/src/documents/document-store.ts +38 -0
  556. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  557. package/src/heartbeat/__tests__/heartbeat-service.test.ts +31 -0
  558. package/src/heartbeat/heartbeat-run-store.ts +31 -0
  559. package/src/heartbeat/heartbeat-service.ts +79 -0
  560. package/src/home/__tests__/feed-writer.test.ts +161 -0
  561. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  562. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  563. package/src/home/feature-gate.ts +22 -0
  564. package/src/home/feed-types.ts +36 -221
  565. package/src/home/feed-writer.ts +146 -7
  566. package/src/home/suggested-prompts.ts +27 -145
  567. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  568. package/src/ipc/__tests__/email-ipc.test.ts +0 -9
  569. package/src/ipc/gateway-client.test.ts +4 -1
  570. package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
  571. package/src/ipc/routes/route-adapter.ts +45 -6
  572. package/src/ipc/skill-routes/__tests__/memory.test.ts +19 -9
  573. package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
  574. package/src/ipc/skill-routes/__tests__/registries.test.ts +59 -20
  575. package/src/ipc/skill-routes/memory.ts +27 -13
  576. package/src/ipc/skill-routes/providers.ts +5 -6
  577. package/src/ipc/skill-routes/registries.ts +39 -88
  578. package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
  579. package/src/memory/__tests__/conversation-queries.test.ts +192 -8
  580. package/src/memory/__tests__/db-maintenance.test.ts +128 -0
  581. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +1 -0
  582. package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
  583. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  584. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  585. package/src/memory/__tests__/memory-retrospective-job.test.ts +11 -6
  586. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  587. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  588. package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
  589. package/src/memory/context-search/agent-runner.ts +2 -4
  590. package/src/memory/conversation-attention-store.ts +17 -3
  591. package/src/memory/conversation-crud.ts +386 -115
  592. package/src/memory/conversation-queries.ts +78 -22
  593. package/src/memory/db-connection.ts +29 -19
  594. package/src/memory/db-init.ts +12 -0
  595. package/src/memory/db-maintenance.ts +18 -2
  596. package/src/memory/db-singleton.ts +77 -0
  597. package/src/memory/delivery-channels.ts +82 -0
  598. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  599. package/src/memory/graph/consolidation.ts +8 -11
  600. package/src/memory/graph/conversation-graph-memory.ts +41 -8
  601. package/src/memory/graph/extraction.ts +6 -9
  602. package/src/memory/graph/narrative.ts +2 -2
  603. package/src/memory/graph/pattern-scan.ts +2 -2
  604. package/src/memory/graph/retriever.test.ts +3 -3
  605. package/src/memory/graph/retriever.ts +20 -26
  606. package/src/memory/graph/tools.ts +4 -4
  607. package/src/memory/job-handlers/conversation-starters.ts +32 -32
  608. package/src/memory/job-handlers/embedding.test.ts +3 -2
  609. package/src/memory/job-handlers/summarization.ts +1 -2
  610. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  611. package/src/memory/jobs-store.ts +3 -1
  612. package/src/memory/jobs-worker.ts +63 -40
  613. package/src/memory/llm-request-log-source-clickhouse.ts +55 -1
  614. package/src/memory/llm-request-log-source-local.ts +13 -0
  615. package/src/memory/llm-request-log-source.ts +21 -6
  616. package/src/memory/llm-request-log-store.ts +147 -3
  617. package/src/memory/llm-usage-store.ts +10 -0
  618. package/src/memory/memory-marker.ts +17 -0
  619. package/src/memory/memory-retrospective-job.ts +6 -2
  620. package/src/memory/memory-v2-activation-log-store.ts +13 -1
  621. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  622. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  623. package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
  624. package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
  625. package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
  626. package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
  627. package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
  628. package/src/memory/migrations/index.ts +6 -0
  629. package/src/memory/schema/conversations.ts +9 -1
  630. package/src/memory/schema/inference.ts +0 -1
  631. package/src/memory/schema/infrastructure.ts +11 -0
  632. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  633. package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
  634. package/src/memory/v2/__tests__/harness-metrics.test.ts +9 -0
  635. package/src/memory/v2/__tests__/harness-replay-input.test.ts +9 -4
  636. package/src/memory/v2/__tests__/harness-runner.test.ts +26 -0
  637. package/src/memory/v2/__tests__/migration.test.ts +11 -3
  638. package/src/memory/v2/__tests__/page-index.test.ts +37 -1
  639. package/src/memory/v2/__tests__/router.test.ts +14 -4
  640. package/src/memory/v2/__tests__/sweep-job.test.ts +9 -5
  641. package/src/memory/v2/backfill-jobs.ts +6 -0
  642. package/src/memory/v2/consolidation-job.ts +89 -9
  643. package/src/memory/v2/harness/metrics.ts +5 -1
  644. package/src/memory/v2/harness/replay-input.ts +19 -3
  645. package/src/memory/v2/harness/runner.ts +6 -0
  646. package/src/memory/v2/harness/trace.ts +6 -0
  647. package/src/memory/v2/migration.ts +5 -3
  648. package/src/memory/v2/page-index.ts +11 -0
  649. package/src/memory/v2/router.ts +8 -11
  650. package/src/memory/v2/sweep-job.ts +8 -11
  651. package/src/memory/v2/types.ts +1 -0
  652. package/src/memory/v3/__tests__/assign.test.ts +242 -0
  653. package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
  654. package/src/memory/v3/__tests__/core.test.ts +39 -0
  655. package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
  656. package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
  657. package/src/memory/v3/__tests__/health.test.ts +203 -0
  658. package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
  659. package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
  660. package/src/memory/v3/__tests__/needle.test.ts +107 -0
  661. package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
  662. package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
  663. package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
  664. package/src/memory/v3/__tests__/router.test.ts +260 -0
  665. package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
  666. package/src/memory/v3/__tests__/selector.test.ts +404 -0
  667. package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
  668. package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
  669. package/src/memory/v3/__tests__/tree.test.ts +192 -0
  670. package/src/memory/v3/__tests__/types.test.ts +54 -0
  671. package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
  672. package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
  673. package/src/memory/v3/assign.ts +268 -0
  674. package/src/memory/v3/capabilities.ts +124 -0
  675. package/src/memory/v3/core.ts +26 -0
  676. package/src/memory/v3/data/README.md +84 -0
  677. package/src/memory/v3/data/assignments.json +5 -0
  678. package/src/memory/v3/data/core.json +1 -0
  679. package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
  680. package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
  681. package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
  682. package/src/memory/v3/health.ts +0 -0
  683. package/src/memory/v3/maintain-job.ts +314 -0
  684. package/src/memory/v3/needle.ts +115 -0
  685. package/src/memory/v3/orchestrate.ts +114 -0
  686. package/src/memory/v3/page-content.ts +34 -0
  687. package/src/memory/v3/provider-blocks.ts +16 -0
  688. package/src/memory/v3/reconcile.ts +523 -0
  689. package/src/memory/v3/render-injection.ts +32 -0
  690. package/src/memory/v3/router.ts +184 -0
  691. package/src/memory/v3/selection-log-store.ts +84 -0
  692. package/src/memory/v3/selector.ts +211 -0
  693. package/src/memory/v3/shadow-plugin.ts +379 -0
  694. package/src/memory/v3/snapshot.ts +209 -0
  695. package/src/memory/v3/tree.ts +174 -0
  696. package/src/memory/v3/types.ts +46 -60
  697. package/src/memory/v3/working-set.ts +88 -0
  698. package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
  699. package/src/messaging/providers/slack/render-transcript.ts +2 -2
  700. package/src/messaging/style-analyzer.ts +8 -11
  701. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  702. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  703. package/src/notifications/adapters/slack.ts +45 -11
  704. package/src/notifications/broadcaster.ts +114 -63
  705. package/src/notifications/conversation-pairing.ts +30 -8
  706. package/src/notifications/decision-engine.ts +10 -13
  707. package/src/notifications/decisions-store.ts +32 -1
  708. package/src/notifications/deliveries-store.ts +45 -0
  709. package/src/notifications/edit-notification.ts +201 -0
  710. package/src/notifications/emit-signal.ts +11 -1
  711. package/src/notifications/preference-extractor.ts +11 -14
  712. package/src/notifications/signal.ts +10 -0
  713. package/src/notifications/types.ts +37 -0
  714. package/src/oauth/byo-connection.test.ts +67 -3
  715. package/src/oauth/byo-connection.ts +32 -5
  716. package/src/oauth/connect-orchestrator.ts +9 -0
  717. package/src/oauth/connection-resolver.test.ts +76 -0
  718. package/src/oauth/connection-resolver.ts +49 -10
  719. package/src/oauth/manual-token-connection.ts +51 -3
  720. package/src/oauth/seed-providers.ts +3 -0
  721. package/src/permissions/approval-policy.test.ts +19 -5
  722. package/src/permissions/approval-policy.ts +14 -3
  723. package/src/permissions/checker.ts +21 -8
  724. package/src/permissions/prompter.ts +42 -36
  725. package/src/permissions/question-prompter.test.ts +35 -26
  726. package/src/permissions/question-prompter.ts +6 -10
  727. package/src/platform/client.test.ts +24 -1
  728. package/src/platform/client.ts +8 -0
  729. package/src/platform/feature-gate.ts +15 -0
  730. package/src/plugin-api/index.ts +2 -0
  731. package/src/plugin-api/types.ts +25 -3
  732. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
  733. package/src/plugins/defaults/circuit-breaker/package.json +15 -0
  734. package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
  735. package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
  736. package/src/plugins/defaults/compaction/package.json +15 -0
  737. package/src/plugins/defaults/compaction/register.ts +35 -0
  738. package/src/plugins/defaults/compaction/terminal.ts +73 -0
  739. package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
  740. package/src/plugins/defaults/empty-response/package.json +15 -0
  741. package/src/plugins/defaults/empty-response/register.ts +28 -0
  742. package/src/plugins/defaults/empty-response/terminal.ts +106 -0
  743. package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
  744. package/src/plugins/defaults/history-repair/package.json +15 -0
  745. package/src/plugins/defaults/history-repair/register.ts +24 -0
  746. package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
  747. package/src/plugins/defaults/index.ts +29 -40
  748. package/src/plugins/defaults/injectors/package.json +15 -0
  749. package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +16 -46
  750. package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
  751. package/src/plugins/defaults/llm-call/package.json +15 -0
  752. package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
  753. package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
  754. package/src/plugins/defaults/memory-retrieval/package.json +15 -0
  755. package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
  756. package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
  757. package/src/plugins/defaults/overflow-reduce/package.json +15 -0
  758. package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
  759. package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
  760. package/src/plugins/defaults/persistence/package.json +15 -0
  761. package/src/plugins/defaults/persistence/register.ts +38 -0
  762. package/src/plugins/defaults/persistence/terminal.ts +83 -0
  763. package/src/plugins/defaults/title-generate/package.json +15 -0
  764. package/src/plugins/defaults/title-generate/register.ts +35 -0
  765. package/src/plugins/defaults/title-generate/terminal.ts +31 -0
  766. package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
  767. package/src/plugins/defaults/token-estimate/package.json +15 -0
  768. package/src/plugins/defaults/token-estimate/register.ts +34 -0
  769. package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
  770. package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
  771. package/src/plugins/defaults/tool-error/package.json +15 -0
  772. package/src/plugins/defaults/tool-error/register.ts +35 -0
  773. package/src/plugins/defaults/tool-error/terminal.ts +47 -0
  774. package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
  775. package/src/plugins/defaults/tool-execute/package.json +15 -0
  776. package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
  777. package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
  778. package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
  779. package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
  780. package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
  781. package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
  782. package/src/plugins/external-plugin-loader.ts +2 -2
  783. package/src/plugins/pipeline.ts +0 -12
  784. package/src/plugins/types.ts +107 -102
  785. package/src/plugins/user-loader.ts +4 -3
  786. package/src/proactive-artifact/aux-message-injector.ts +0 -1
  787. package/src/proactive-artifact/job.test.ts +21 -8
  788. package/src/proactive-artifact/job.ts +3 -1
  789. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  790. package/src/prompts/sections.ts +20 -7
  791. package/src/prompts/system-prompt.ts +38 -40
  792. package/src/prompts/template-detection.ts +10 -4
  793. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
  794. package/src/prompts/templates/BOOTSTRAP.md +10 -10
  795. package/src/prompts/templates/IDENTITY.md +0 -2
  796. package/src/prompts/templates/system-sections.ts +6 -0
  797. package/src/providers/__tests__/connection-model-compat.test.ts +3 -4
  798. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  799. package/src/providers/__tests__/retry-callsite.test.ts +25 -25
  800. package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
  801. package/src/providers/anthropic/client.ts +24 -5
  802. package/src/providers/call-site-routing.ts +34 -18
  803. package/src/providers/connection-model-compat.ts +23 -0
  804. package/src/providers/connection-resolution.ts +39 -20
  805. package/src/providers/fireworks/client.ts +1 -0
  806. package/src/providers/gemini/client.ts +176 -37
  807. package/src/providers/gemini/inline-media.ts +74 -0
  808. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  809. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  810. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  811. package/src/providers/inference/auth.ts +0 -8
  812. package/src/providers/inference/connections.ts +3 -66
  813. package/src/providers/inference/resolve-auth.ts +2 -3
  814. package/src/providers/model-catalog.ts +35 -1
  815. package/src/providers/model-intents.ts +3 -3
  816. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  817. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -7
  818. package/src/providers/openai/chat-completions-provider.ts +111 -16
  819. package/src/providers/openai/codex-models.ts +2 -0
  820. package/src/providers/openai/responses-provider.ts +54 -57
  821. package/src/providers/openrouter/client.ts +14 -14
  822. package/src/providers/provider-send-message.ts +23 -14
  823. package/src/providers/ratelimit.ts +1 -9
  824. package/src/providers/registry.ts +48 -8
  825. package/src/providers/retry.ts +16 -9
  826. package/src/providers/search-provider-catalog.ts +17 -9
  827. package/src/providers/types.ts +20 -2
  828. package/src/providers/usage-tracking.ts +1 -9
  829. package/src/runtime/__tests__/agent-wake.test.ts +132 -26
  830. package/src/runtime/__tests__/background-job-runner.test.ts +2 -3
  831. package/src/runtime/access-request-helper.ts +1 -0
  832. package/src/runtime/agent-wake.ts +93 -18
  833. package/src/runtime/assistant-event-hub.ts +2 -2
  834. package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
  835. package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
  836. package/src/runtime/auth/route-policy.ts +42 -1069
  837. package/src/runtime/background-job-runner.ts +1 -4
  838. package/src/runtime/btw-sidechain.ts +3 -1
  839. package/src/runtime/channel-approvals.ts +3 -14
  840. package/src/runtime/channel-invite-transport.ts +5 -6
  841. package/src/runtime/channel-readiness-service.ts +70 -5
  842. package/src/runtime/channel-reply-delivery.ts +23 -0
  843. package/src/runtime/channel-retry-sweep.ts +59 -30
  844. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  845. package/src/runtime/conversation-stream-state.ts +294 -0
  846. package/src/runtime/http-router.ts +19 -22
  847. package/src/runtime/http-types.ts +12 -6
  848. package/src/runtime/invite-instruction-generator.ts +3 -3
  849. package/src/runtime/migrations/vbundle-builder.ts +3 -2
  850. package/src/runtime/pending-interactions.ts +2 -2
  851. package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
  852. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  853. package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
  854. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +436 -0
  855. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
  856. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
  857. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  858. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  859. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +26 -72
  860. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +58 -5
  861. package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
  862. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  863. package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
  864. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
  865. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  866. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  867. package/src/runtime/routes/__tests__/tts-routes.test.ts +3 -3
  868. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  869. package/src/runtime/routes/acp-routes.test.ts +97 -75
  870. package/src/runtime/routes/acp-routes.ts +29 -6
  871. package/src/runtime/routes/app-management-routes.ts +208 -28
  872. package/src/runtime/routes/app-routes.ts +25 -5
  873. package/src/runtime/routes/approval-routes.ts +16 -4
  874. package/src/runtime/routes/attachment-routes.ts +25 -1
  875. package/src/runtime/routes/audio-routes.ts +1 -0
  876. package/src/runtime/routes/audit-routes.ts +5 -0
  877. package/src/runtime/routes/auth-routes.ts +5 -0
  878. package/src/runtime/routes/avatar-routes.ts +238 -59
  879. package/src/runtime/routes/background-tool-routes.ts +9 -0
  880. package/src/runtime/routes/background-wake-routes.ts +201 -23
  881. package/src/runtime/routes/backup-routes.ts +45 -0
  882. package/src/runtime/routes/bookmark-routes.ts +13 -0
  883. package/src/runtime/routes/brain-graph-routes.ts +9 -0
  884. package/src/runtime/routes/browser-routes.ts +5 -0
  885. package/src/runtime/routes/browser-tabs-routes.ts +5 -0
  886. package/src/runtime/routes/btw-routes.ts +9 -5
  887. package/src/runtime/routes/cache-routes.ts +13 -0
  888. package/src/runtime/routes/call-routes.ts +21 -10
  889. package/src/runtime/routes/channel-availability-routes.ts +5 -1
  890. package/src/runtime/routes/channel-readiness-routes.ts +37 -4
  891. package/src/runtime/routes/channel-route-definitions.ts +21 -0
  892. package/src/runtime/routes/channel-verification-routes.ts +21 -0
  893. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
  894. package/src/runtime/routes/client-routes.ts +9 -0
  895. package/src/runtime/routes/consolidation-routes.ts +13 -5
  896. package/src/runtime/routes/contact-prompt-routes.ts +9 -0
  897. package/src/runtime/routes/contact-routes.ts +90 -23
  898. package/src/runtime/routes/content-source-routes.ts +5 -1
  899. package/src/runtime/routes/conversation-analysis-routes.ts +11 -1
  900. package/src/runtime/routes/conversation-attention-routes.ts +5 -0
  901. package/src/runtime/routes/conversation-cli-routes.ts +54 -7
  902. package/src/runtime/routes/conversation-compaction-routes.ts +292 -0
  903. package/src/runtime/routes/conversation-list-routes.ts +225 -9
  904. package/src/runtime/routes/conversation-management-routes.ts +96 -28
  905. package/src/runtime/routes/conversation-query-routes.ts +148 -51
  906. package/src/runtime/routes/conversation-routes.ts +259 -158
  907. package/src/runtime/routes/conversation-starter-routes.ts +22 -13
  908. package/src/runtime/routes/conversations-import-routes.ts +25 -7
  909. package/src/runtime/routes/credential-prompt-routes.ts +5 -0
  910. package/src/runtime/routes/credential-routes.ts +25 -6
  911. package/src/runtime/routes/debug-bash-routes.ts +5 -0
  912. package/src/runtime/routes/debug-routes.ts +11 -2
  913. package/src/runtime/routes/defer-routes.ts +13 -0
  914. package/src/runtime/routes/diagnostics-routes.ts +37 -46
  915. package/src/runtime/routes/disk-pressure-routes.ts +17 -31
  916. package/src/runtime/routes/document-comments-routes.ts +46 -27
  917. package/src/runtime/routes/documents-routes.ts +31 -11
  918. package/src/runtime/routes/domain-routes.ts +61 -28
  919. package/src/runtime/routes/email-routes.ts +33 -0
  920. package/src/runtime/routes/events-routes.ts +114 -9
  921. package/src/runtime/routes/filing-routes.ts +9 -4
  922. package/src/runtime/routes/gateway-log-routes.ts +5 -0
  923. package/src/runtime/routes/global-search-routes.ts +53 -50
  924. package/src/runtime/routes/group-routes.ts +32 -5
  925. package/src/runtime/routes/guardian-action-routes.ts +9 -0
  926. package/src/runtime/routes/guardian-approval-interception.ts +0 -31
  927. package/src/runtime/routes/heartbeat-routes.ts +25 -9
  928. package/src/runtime/routes/home-feed-routes.ts +149 -16
  929. package/src/runtime/routes/home-state-routes.ts +8 -40
  930. package/src/runtime/routes/host-app-control-routes.ts +5 -0
  931. package/src/runtime/routes/host-bash-routes.ts +5 -0
  932. package/src/runtime/routes/host-browser-routes.ts +13 -0
  933. package/src/runtime/routes/host-cu-routes.ts +5 -0
  934. package/src/runtime/routes/host-file-routes.ts +26 -6
  935. package/src/runtime/routes/host-transfer-routes.ts +13 -2
  936. package/src/runtime/routes/http-adapter.ts +1 -2
  937. package/src/runtime/routes/identity-intro-cache.ts +72 -16
  938. package/src/runtime/routes/identity-routes.ts +42 -11
  939. package/src/runtime/routes/image-generation-routes.ts +5 -0
  940. package/src/runtime/routes/inbound-message-handler.ts +15 -11
  941. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +524 -12
  942. package/src/runtime/routes/inbound-stages/background-dispatch.ts +72 -27
  943. package/src/runtime/routes/index.ts +2 -0
  944. package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
  945. package/src/runtime/routes/inference-provider-connection-routes.ts +26 -31
  946. package/src/runtime/routes/inference-send-routes.ts +11 -11
  947. package/src/runtime/routes/integrations/a2a.ts +30 -7
  948. package/src/runtime/routes/integrations/slack/channel.ts +19 -3
  949. package/src/runtime/routes/integrations/slack/share.ts +9 -2
  950. package/src/runtime/routes/integrations/telegram.ts +28 -9
  951. package/src/runtime/routes/integrations/twilio.ts +35 -7
  952. package/src/runtime/routes/integrations/vercel.ts +18 -3
  953. package/src/runtime/routes/internal-oauth-routes.ts +5 -0
  954. package/src/runtime/routes/internal-twilio-routes.ts +13 -0
  955. package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
  956. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  957. package/src/runtime/routes/log-export-routes.ts +28 -10
  958. package/src/runtime/routes/mcp-auth-routes.ts +25 -0
  959. package/src/runtime/routes/memory-item-routes.ts +21 -10
  960. package/src/runtime/routes/memory-v2-routes.ts +90 -36
  961. package/src/runtime/routes/memory-v3-routes.ts +283 -259
  962. package/src/runtime/routes/migration-rollback-routes.ts +5 -1
  963. package/src/runtime/routes/migration-routes.ts +49 -13
  964. package/src/runtime/routes/notification-routes.ts +80 -2
  965. package/src/runtime/routes/oauth-apps.ts +33 -11
  966. package/src/runtime/routes/oauth-commands-routes.ts +43 -15
  967. package/src/runtime/routes/oauth-connect-routes.ts +9 -0
  968. package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
  969. package/src/runtime/routes/oauth-providers.ts +35 -10
  970. package/src/runtime/routes/platform-routes.ts +21 -0
  971. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
  972. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
  973. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
  974. package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
  975. package/src/runtime/routes/playground/force-compact.ts +1 -1
  976. package/src/runtime/routes/playground/helpers.ts +0 -1
  977. package/src/runtime/routes/playground/inject-failures.ts +13 -8
  978. package/src/runtime/routes/playground/reset-circuit.ts +14 -9
  979. package/src/runtime/routes/playground/seed-conversation.ts +1 -1
  980. package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
  981. package/src/runtime/routes/playground/state.ts +4 -3
  982. package/src/runtime/routes/plugins-routes.ts +22 -19
  983. package/src/runtime/routes/profiler-routes.ts +17 -4
  984. package/src/runtime/routes/ps-routes.ts +5 -0
  985. package/src/runtime/routes/publish-routes.ts +13 -3
  986. package/src/runtime/routes/question-routes.ts +5 -0
  987. package/src/runtime/routes/recording-routes.ts +25 -12
  988. package/src/runtime/routes/rename-conversation-routes.ts +5 -0
  989. package/src/runtime/routes/sanity-routes.ts +9 -2
  990. package/src/runtime/routes/schedule-routes.ts +137 -47
  991. package/src/runtime/routes/secret-routes.ts +17 -4
  992. package/src/runtime/routes/sequence-routes.ts +33 -0
  993. package/src/runtime/routes/settings-routes.ts +65 -19
  994. package/src/runtime/routes/skills-routes.ts +133 -69
  995. package/src/runtime/routes/slack-channel-routes.ts +5 -0
  996. package/src/runtime/routes/stt-routes.ts +13 -6
  997. package/src/runtime/routes/subagents-routes.ts +24 -18
  998. package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
  999. package/src/runtime/routes/surface-action-routes.ts +10 -38
  1000. package/src/runtime/routes/surface-content-routes.ts +21 -6
  1001. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  1002. package/src/runtime/routes/task-routes.ts +37 -0
  1003. package/src/runtime/routes/telemetry-routes.ts +9 -0
  1004. package/src/runtime/routes/trace-event-routes.ts +42 -1
  1005. package/src/runtime/routes/trust-rules-routes.ts +5 -0
  1006. package/src/runtime/routes/tts-routes.ts +13 -6
  1007. package/src/runtime/routes/types.ts +17 -8
  1008. package/src/runtime/routes/ui-request-routes.ts +5 -0
  1009. package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
  1010. package/src/runtime/routes/usage-routes.ts +71 -3
  1011. package/src/runtime/routes/user-routes-cli.ts +9 -0
  1012. package/src/runtime/routes/user-routes.ts +5 -1
  1013. package/src/runtime/routes/wake-conversation-routes.ts +5 -0
  1014. package/src/runtime/routes/watcher-routes.ts +21 -0
  1015. package/src/runtime/routes/webhook-routes.ts +9 -0
  1016. package/src/runtime/routes/wipe-conversation-routes.ts +8 -0
  1017. package/src/runtime/routes/work-items-routes.ts +47 -19
  1018. package/src/runtime/routes/workspace-commit-routes.ts +5 -0
  1019. package/src/runtime/routes/workspace-routes.test.ts +42 -0
  1020. package/src/runtime/routes/workspace-routes.ts +120 -9
  1021. package/src/runtime/services/__tests__/analyze-conversation.test.ts +4 -4
  1022. package/src/runtime/services/analyze-conversation.ts +3 -6
  1023. package/src/runtime/services/conversation-serializer.ts +24 -2
  1024. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  1025. package/src/runtime/sync/resource-sync-events.ts +17 -3
  1026. package/src/runtime/sync/sync-publisher.ts +2 -2
  1027. package/src/runtime/tool-grant-request-helper.ts +1 -0
  1028. package/src/schedule/run-script.ts +28 -3
  1029. package/src/schedule/schedule-store.ts +16 -1
  1030. package/src/schedule/scheduler.ts +114 -16
  1031. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  1032. package/src/security/encrypted-store.ts +7 -16
  1033. package/src/security/store-path-override.ts +61 -0
  1034. package/src/signals/user-message.ts +10 -16
  1035. package/src/skills/catalog-files.ts +4 -1
  1036. package/src/skills/clawhub-files.ts +2 -0
  1037. package/src/skills/skillssh-files.ts +2 -0
  1038. package/src/skills/validate-input.ts +177 -0
  1039. package/src/subagent/manager.ts +16 -19
  1040. package/src/subagent/types.ts +6 -0
  1041. package/src/tasks/tool-sanitizer.ts +2 -2
  1042. package/src/telemetry/types.ts +26 -0
  1043. package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
  1044. package/src/telemetry/usage-telemetry-reporter.ts +31 -0
  1045. package/src/tools/acp/spawn.test.ts +88 -38
  1046. package/src/tools/apps/definitions.ts +42 -24
  1047. package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
  1048. package/src/tools/ask-question/ask-question-tool.ts +85 -90
  1049. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  1050. package/src/tools/computer-use/definitions.ts +295 -289
  1051. package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
  1052. package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
  1053. package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
  1054. package/src/tools/credentials/vault.ts +112 -111
  1055. package/src/tools/document/document-tool.ts +131 -8
  1056. package/src/tools/execution-target.ts +3 -6
  1057. package/src/tools/execution-timeout.ts +3 -4
  1058. package/src/tools/executor.ts +18 -55
  1059. package/src/tools/filesystem/edit.ts +45 -42
  1060. package/src/tools/filesystem/list.ts +33 -30
  1061. package/src/tools/filesystem/read.ts +54 -35
  1062. package/src/tools/filesystem/write.ts +34 -31
  1063. package/src/tools/host-filesystem/edit.test.ts +1 -0
  1064. package/src/tools/host-filesystem/edit.ts +44 -42
  1065. package/src/tools/host-filesystem/read.test.ts +1 -0
  1066. package/src/tools/host-filesystem/read.ts +49 -35
  1067. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  1068. package/src/tools/host-filesystem/transfer.ts +121 -108
  1069. package/src/tools/host-filesystem/write.test.ts +1 -0
  1070. package/src/tools/host-filesystem/write.ts +33 -31
  1071. package/src/tools/host-terminal/host-shell.ts +50 -48
  1072. package/src/tools/mcp/mcp-tool-factory.ts +0 -2
  1073. package/src/tools/memory/register.ts +23 -24
  1074. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  1075. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  1076. package/src/tools/network/managed-search-proxy.ts +183 -0
  1077. package/src/tools/network/web-fetch.ts +49 -46
  1078. package/src/tools/network/web-search.ts +215 -57
  1079. package/src/tools/policy-context.ts +3 -1
  1080. package/src/tools/registry.ts +184 -118
  1081. package/src/tools/schedule/create.ts +12 -1
  1082. package/src/tools/schedule/update.ts +16 -0
  1083. package/src/tools/shared/filesystem/audio-read.ts +122 -0
  1084. package/src/tools/shared/filesystem/image-read.ts +1 -1
  1085. package/src/tools/skills/execute.ts +34 -31
  1086. package/src/tools/skills/load.ts +29 -23
  1087. package/src/tools/skills/skill-tool-factory.ts +17 -36
  1088. package/src/tools/subagent/notify-parent.ts +35 -32
  1089. package/src/tools/subagent/spawn.ts +3 -0
  1090. package/src/tools/system/avatar-generator.ts +13 -22
  1091. package/src/tools/system/request-permission.ts +30 -27
  1092. package/src/tools/terminal/shell.ts +190 -61
  1093. package/src/tools/tool-approval-handler.ts +10 -4
  1094. package/src/tools/tool-defaults.ts +20 -9
  1095. package/src/tools/tool-manifest.ts +4 -4
  1096. package/src/tools/tool-name-aliases.ts +72 -14
  1097. package/src/tools/types.ts +86 -33
  1098. package/src/tools/ui-surface/definitions.ts +166 -94
  1099. package/src/types/onboarding-context.ts +6 -0
  1100. package/src/usage/attribution.ts +32 -1
  1101. package/src/usage/types.ts +10 -0
  1102. package/src/util/browser.ts +7 -2
  1103. package/src/util/errors.ts +2 -2
  1104. package/src/util/map-limit.ts +27 -0
  1105. package/src/util/platform.ts +15 -12
  1106. package/src/work-items/work-item-runner.ts +7 -2
  1107. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
  1108. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  1109. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  1110. package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
  1111. package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
  1112. package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
  1113. package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
  1114. package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
  1115. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
  1116. package/src/workspace/migrations/registry.ts +10 -0
  1117. package/src/workspace/provider-commit-message-generator.ts +15 -17
  1118. package/tsconfig.json +4 -1
  1119. package/src/__tests__/history-repair-pipeline.test.ts +0 -396
  1120. package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
  1121. package/src/cli/commands/memory-v3-render.ts +0 -344
  1122. package/src/daemon/message-types/disk-pressure.ts +0 -9
  1123. package/src/email/feature-gate.ts +0 -23
  1124. package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
  1125. package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -468
  1126. package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
  1127. package/src/memory/v3/__tests__/edges.test.ts +0 -563
  1128. package/src/memory/v3/__tests__/filter.test.ts +0 -512
  1129. package/src/memory/v3/__tests__/gate.test.ts +0 -574
  1130. package/src/memory/v3/__tests__/index-composition.test.ts +0 -233
  1131. package/src/memory/v3/__tests__/loop.test.ts +0 -530
  1132. package/src/memory/v3/__tests__/retriever.test.ts +0 -226
  1133. package/src/memory/v3/__tests__/scouts.test.ts +0 -440
  1134. package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -312
  1135. package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
  1136. package/src/memory/v3/__tests__/traversal.test.ts +0 -469
  1137. package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
  1138. package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
  1139. package/src/memory/v3/__tests__/tree-walk.test.ts +0 -707
  1140. package/src/memory/v3/__tests__/validate.test.ts +0 -245
  1141. package/src/memory/v3/auto-edges.ts +0 -223
  1142. package/src/memory/v3/coactivation-store.ts +0 -124
  1143. package/src/memory/v3/consolidation-job.ts +0 -323
  1144. package/src/memory/v3/edge-learning-job.ts +0 -160
  1145. package/src/memory/v3/edges.ts +0 -249
  1146. package/src/memory/v3/filter.ts +0 -281
  1147. package/src/memory/v3/gate.ts +0 -334
  1148. package/src/memory/v3/index-composition.ts +0 -113
  1149. package/src/memory/v3/llm-capture.ts +0 -46
  1150. package/src/memory/v3/loop.ts +0 -382
  1151. package/src/memory/v3/maintenance.ts +0 -144
  1152. package/src/memory/v3/prompt-context.ts +0 -33
  1153. package/src/memory/v3/prompts/consolidation.ts +0 -458
  1154. package/src/memory/v3/prompts/system-prompts.ts +0 -196
  1155. package/src/memory/v3/retriever.ts +0 -33
  1156. package/src/memory/v3/scouts.ts +0 -420
  1157. package/src/memory/v3/shadow-middleware.ts +0 -305
  1158. package/src/memory/v3/traversal.ts +0 -206
  1159. package/src/memory/v3/tree-index.ts +0 -237
  1160. package/src/memory/v3/tree-store.ts +0 -394
  1161. package/src/memory/v3/tree-walk.ts +0 -351
  1162. package/src/memory/v3/validate.ts +0 -300
  1163. package/src/plugins/defaults/circuit-breaker.ts +0 -141
  1164. package/src/plugins/defaults/compaction.ts +0 -141
  1165. package/src/plugins/defaults/empty-response.ts +0 -124
  1166. package/src/plugins/defaults/history-repair.ts +0 -83
  1167. package/src/plugins/defaults/persistence.ts +0 -127
  1168. package/src/plugins/defaults/title-generate.ts +0 -90
  1169. package/src/plugins/defaults/token-estimate.ts +0 -101
  1170. package/src/plugins/defaults/tool-error.ts +0 -119
  1171. package/src/plugins/defaults/tool-result-truncate.ts +0 -84
@@ -1,237 +0,0 @@
1
- /**
2
- * Memory v3 — Tree index (DAG build + cache).
3
- *
4
- * The v3 tree is a DAG *overlay* over the flat `memory/concepts/` pages: every
5
- * node carries an ordered `children` list whose entries are either
6
- * `"page:<slug>"` (a leaf concept page, canonical content untouched by v3) or
7
- * `"node:<id>"` (a sub-node in the tree). A page or node may be referenced by
8
- * more than one parent — hence DAG, not tree.
9
- *
10
- * This module scans every node on disk and materializes that edge list into
11
- * forward and reverse adjacency maps so downstream routing/validation can walk
12
- * the graph without re-reading the filesystem:
13
- * - `childrenByNode` — node id → ordered child refs (forward edges).
14
- * - `parentsByNode` — node id → set of parent node ids (reverse edges for
15
- * `node:` children).
16
- * - `pageParents` — page slug → set of parent node ids (reverse edges for
17
- * `page:` children).
18
- *
19
- * The build is **structural only**: it never verifies that a referenced page
20
- * or node actually exists. Dangling refs are retained in the adjacency maps so
21
- * a later validation pass can report them. Root detection prefers the reserved
22
- * `_root` id; absent that it picks the single node with no parents (warning and
23
- * picking deterministically if the choice is ambiguous).
24
- *
25
- * The build is cached module-locally per `workspaceDir`, mirroring
26
- * `../v2/page-index.ts`. Callers must invalidate via `invalidateTreeIndex` when
27
- * tree nodes change — `tree-store.ts`'s `writeNode` / `deleteNode` already do.
28
- */
29
-
30
- import { getLogger } from "../../util/logger.js";
31
- import { listNodes, readNode, ROOT_NODE_ID } from "./tree-store.js";
32
- import type { TreeNode } from "./types.js";
33
-
34
- const log = getLogger("memory-v3-tree-index");
35
-
36
- /** Prefix marking a child ref that targets a leaf concept page. */
37
- const PAGE_REF_PREFIX = "page:";
38
-
39
- /** Prefix marking a child ref that targets a sub-node in the tree. */
40
- const NODE_REF_PREFIX = "node:";
41
-
42
- /**
43
- * A single parsed `children` entry. `kind` distinguishes a leaf concept page
44
- * (`"page"`) from a sub-node (`"node"`); `ref` is the bare slug or node id with
45
- * the `page:` / `node:` prefix stripped.
46
- */
47
- export interface ChildRef {
48
- kind: "page" | "node";
49
- ref: string;
50
- }
51
-
52
- /**
53
- * Snapshot of the v3 tree DAG for one workspace.
54
- *
55
- * `nodes` is every readable node keyed by id. The three adjacency maps are
56
- * derived from each node's `children`:
57
- * - `childrenByNode` — forward edges, preserving `children` order.
58
- * - `parentsByNode` — reverse edges restricted to `node:` children.
59
- * - `pageParents` — reverse edges restricted to `page:` children, keyed by
60
- * page slug.
61
- *
62
- * `root` is the entry-point node id (`_root` when present). Dangling refs (a
63
- * `node:`/`page:` target with no on-disk file) are retained throughout —
64
- * validation, not the index build, is responsible for surfacing them.
65
- */
66
- export interface TreeIndex {
67
- nodes: Map<string, TreeNode>;
68
- childrenByNode: Map<string, ReadonlyArray<ChildRef>>;
69
- parentsByNode: Map<string, Set<string>>;
70
- pageParents: Map<string, Set<string>>;
71
- root: string;
72
- }
73
-
74
- interface CachedIndex {
75
- workspaceDir: string;
76
- index: TreeIndex;
77
- }
78
-
79
- let cache: CachedIndex | null = null;
80
-
81
- /**
82
- * Parse a raw `children` entry into a {@link ChildRef}. Returns `null` for any
83
- * entry that does not carry a recognized `page:` / `node:` prefix or whose ref
84
- * body is empty — those are malformed and dropped (with a warn) rather than
85
- * faithfully threaded through adjacency.
86
- */
87
- function parseChildRef(raw: string): ChildRef | null {
88
- if (raw.startsWith(PAGE_REF_PREFIX)) {
89
- const ref = raw.slice(PAGE_REF_PREFIX.length);
90
- return ref.length > 0 ? { kind: "page", ref } : null;
91
- }
92
- if (raw.startsWith(NODE_REF_PREFIX)) {
93
- const ref = raw.slice(NODE_REF_PREFIX.length);
94
- return ref.length > 0 ? { kind: "node", ref } : null;
95
- }
96
- return null;
97
- }
98
-
99
- /** Append `parent` to the parent-set for `key`, creating the set on demand. */
100
- function addParent(
101
- map: Map<string, Set<string>>,
102
- key: string,
103
- parent: string,
104
- ): void {
105
- let parents = map.get(key);
106
- if (!parents) {
107
- parents = new Set();
108
- map.set(key, parents);
109
- }
110
- parents.add(parent);
111
- }
112
-
113
- /**
114
- * Pick the root node id from the materialized adjacency. Prefers the reserved
115
- * {@link ROOT_NODE_ID} when a node with that id exists. Otherwise the root is
116
- * the single node with no parents; if several nodes are parentless the choice
117
- * is ambiguous, so warn and pick the ASCII-smallest id for determinism. With no
118
- * nodes at all the root is `_root` (the well-known handle a migration authors
119
- * first), matching the empty-workspace contract.
120
- */
121
- function pickRoot(
122
- nodes: Map<string, TreeNode>,
123
- parentsByNode: Map<string, Set<string>>,
124
- ): string {
125
- if (nodes.has(ROOT_NODE_ID)) {
126
- return ROOT_NODE_ID;
127
- }
128
-
129
- const parentless = [...nodes.keys()].filter(
130
- (id) => !parentsByNode.has(id) || parentsByNode.get(id)!.size === 0,
131
- );
132
- parentless.sort();
133
-
134
- if (parentless.length === 1) {
135
- return parentless[0];
136
- }
137
- if (parentless.length === 0) {
138
- return ROOT_NODE_ID;
139
- }
140
- log.warn(
141
- { parentless },
142
- "Ambiguous tree root — no '_root' node and multiple parentless nodes; picking ASCII-smallest deterministically",
143
- );
144
- return parentless[0];
145
- }
146
-
147
- /**
148
- * Return a `TreeIndex` for `workspaceDir`. Cached module-locally; the cache is
149
- * invalidated by `invalidateTreeIndex` (called by `tree-store.ts` hooks when
150
- * nodes change).
151
- *
152
- * Cold builds list every node and read them in parallel, dropping any whose
153
- * read rejects with a warn so one broken node never blocks the rest of the
154
- * index. Each readable node's `children` is parsed into {@link ChildRef}s and
155
- * threaded into forward (`childrenByNode`) and reverse (`parentsByNode` /
156
- * `pageParents`) adjacency. The build is structural only — referenced
157
- * pages/nodes are never verified to exist; dangling refs are retained for a
158
- * later validation pass.
159
- */
160
- export async function getTreeIndex(workspaceDir: string): Promise<TreeIndex> {
161
- if (cache && cache.workspaceDir === workspaceDir) {
162
- return cache.index;
163
- }
164
-
165
- const ids = await listNodes(workspaceDir);
166
-
167
- // Read every node in parallel; nodes whose read rejects are dropped with a
168
- // warn so a single broken node never blocks the rest of the index.
169
- const settled = await Promise.allSettled(
170
- ids.map((id) => readNode(workspaceDir, id)),
171
- );
172
-
173
- const nodes = new Map<string, TreeNode>();
174
- const childrenByNode = new Map<string, ReadonlyArray<ChildRef>>();
175
- const parentsByNode = new Map<string, Set<string>>();
176
- const pageParents = new Map<string, Set<string>>();
177
-
178
- for (let i = 0; i < settled.length; i++) {
179
- const result = settled[i];
180
- const id = ids[i];
181
- if (result.status === "rejected") {
182
- log.warn(
183
- { id, err: result.reason },
184
- "Dropping tree node from index — read failed",
185
- );
186
- continue;
187
- }
188
- const node = result.value;
189
- // `readNode` returns null only on ENOENT; a node listed by `listNodes`
190
- // that vanishes between list and read is a benign race — drop it silently.
191
- if (!node) continue;
192
- nodes.set(id, node);
193
- }
194
-
195
- // Build adjacency in a second pass so every node is registered first — that
196
- // keeps a deterministic, list-order iteration independent of read timing.
197
- for (const node of nodes.values()) {
198
- const childRefs: ChildRef[] = [];
199
- for (const raw of node.frontmatter.children) {
200
- const parsed = parseChildRef(raw);
201
- if (!parsed) {
202
- log.warn(
203
- { id: node.id, raw },
204
- "Dropping malformed child ref — expected 'page:<slug>' or 'node:<id>'",
205
- );
206
- continue;
207
- }
208
- childRefs.push(parsed);
209
- const reverse = parsed.kind === "node" ? parentsByNode : pageParents;
210
- addParent(reverse, parsed.ref, node.id);
211
- }
212
- childrenByNode.set(node.id, childRefs);
213
- }
214
-
215
- const root = pickRoot(nodes, parentsByNode);
216
-
217
- const index: TreeIndex = {
218
- nodes,
219
- childrenByNode,
220
- parentsByNode,
221
- pageParents,
222
- root,
223
- };
224
- cache = { workspaceDir, index };
225
- return index;
226
- }
227
-
228
- /**
229
- * Clear the cached index. Pass `workspaceDir` to scope invalidation to a
230
- * specific cache entry; omit it to clear unconditionally.
231
- */
232
- export function invalidateTreeIndex(workspaceDir?: string): void {
233
- if (!cache) return;
234
- if (workspaceDir === undefined || cache.workspaceDir === workspaceDir) {
235
- cache = null;
236
- }
237
- }
@@ -1,394 +0,0 @@
1
- /**
2
- * Memory v3 — Tree node store.
3
- *
4
- * Owns the on-disk read/write contract for `memory/tree/<id>.md`. Nodes may
5
- * live directly under `memory/tree/` or nested in subdirectories (e.g.
6
- * `memory/tree/people/colleagues.md`); the id encodes the relative path from
7
- * `tree/` minus the `.md` extension, using forward slashes as separators (so
8
- * `people/colleagues` is a valid id).
9
- *
10
- * The v3 tree is a DAG *overlay* over the existing flat `memory/concepts/`
11
- * pages — this module never touches `memory/concepts/`. Pages stay canonical
12
- * and shared; nodes reference pages and sub-nodes by `children` refs
13
- * (`page:<slug>` / `node:<id>`), which are the portable replacement for
14
- * filesystem symlinks.
15
- *
16
- * Each node is a YAML-frontmatter Markdown file: a `---`-delimited block
17
- * (`children`, optional `routing_hints` / `summary`) followed by the prose body
18
- * that is the node's full self-description. This module is the only v3
19
- * component that knows how to parse or render that format — every other v3
20
- * module routes through `readNode` / `writeNode` so the on-disk shape can
21
- * evolve without touching downstream callers.
22
- *
23
- * Writes are atomic (temp + rename) so a crash mid-write leaves either the old
24
- * file or the new file in place — never a half-written node. The id machinery
25
- * mirrors v2's page-store `slugify` / `validateSlug` so node ids and page slugs
26
- * share the same filesystem-safe shape.
27
- */
28
-
29
- import { randomUUID } from "node:crypto";
30
- import {
31
- mkdir,
32
- readdir,
33
- readFile,
34
- rename,
35
- rm,
36
- stat,
37
- writeFile,
38
- } from "node:fs/promises";
39
- import { dirname, join, relative, sep } from "node:path";
40
-
41
- import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
42
-
43
- import { FRONTMATTER_REGEX } from "../../skills/frontmatter.js";
44
- import { invalidateTreeIndex } from "./tree-index.js";
45
- import { type TreeNode, TreeNodeFrontmatterSchema } from "./types.js";
46
-
47
- /** Filename suffix for tree nodes. */
48
- const NODE_EXTENSION = ".md";
49
-
50
- /** Cap individual id-segment length so we stay well under filesystem limits. */
51
- const MAX_ID_SEGMENT_LENGTH = 80;
52
-
53
- /** Cap the full id (including any folder separators) to a sane bound. */
54
- const MAX_ID_TOTAL_LENGTH = 200;
55
-
56
- /** Each path segment must match this — same shape `slugify` produces. */
57
- const ID_SEGMENT_REGEX = /^[a-z0-9](?:[a-z0-9-]*)$/;
58
-
59
- /**
60
- * Reserved id for the root of the v3 tree. The root node is the entry point a
61
- * future migration authors first; reserving the id keeps the well-known handle
62
- * stable across the codebase.
63
- */
64
- export const ROOT_NODE_ID = "_root";
65
-
66
- /**
67
- * Convert an arbitrary input string into a filesystem-safe id **segment**.
68
- *
69
- * Returns a single path segment (no `/`). Path-shaped ids are constructed by
70
- * the authoring migration writing files at full paths; this helper is for
71
- * turning free-form text (e.g. a node label) into one clean segment.
72
- *
73
- * Rules:
74
- * - Lowercase ASCII letters, digits, and hyphens only.
75
- * - Non-ASCII / non-alphanumeric characters (including `/`) collapse to hyphens.
76
- * - Consecutive hyphens collapse to one; leading/trailing hyphens trimmed.
77
- * - Truncated to {@link MAX_ID_SEGMENT_LENGTH} characters (with trailing
78
- * hyphen re-trimmed after truncation).
79
- * - Empty inputs (e.g. emoji-only) fall back to `node-<random>` so the caller
80
- * always gets a non-empty, write-safe segment.
81
- */
82
- export function slugify(input: string): string {
83
- let slug = input
84
- .toLowerCase()
85
- .normalize("NFKD")
86
- .replace(/[^a-z0-9-]+/g, "-")
87
- .replace(/-{2,}/g, "-")
88
- .replace(/^-+|-+$/g, "");
89
-
90
- if (slug.length > MAX_ID_SEGMENT_LENGTH) {
91
- slug = slug.slice(0, MAX_ID_SEGMENT_LENGTH).replace(/-+$/, "");
92
- }
93
-
94
- if (!slug) {
95
- slug = `node-${randomUUID().slice(0, 8)}`;
96
- }
97
-
98
- return slug;
99
- }
100
-
101
- /**
102
- * Validate a node id — possibly path-shaped — that is about to cross the
103
- * storage boundary. Throws on any malformed or unsafe value.
104
- *
105
- * The on-disk tree treats ids as relative paths under `memory/tree/`. A
106
- * malformed id (e.g. `..`, leading `/`, embedded null byte) could escape that
107
- * root via `path.join` if it slipped through, so we enforce shape here at every
108
- * read/write/delete entry point rather than relying on callers.
109
- *
110
- * The reserved {@link ROOT_NODE_ID} (`_root`) is accepted as a special case;
111
- * its leading underscore would otherwise fail {@link ID_SEGMENT_REGEX}.
112
- *
113
- * Rules:
114
- * - Non-empty, ≤ {@link MAX_ID_TOTAL_LENGTH} chars.
115
- * - Each `/`-separated segment matches {@link ID_SEGMENT_REGEX}
116
- * (lowercase alphanum + hyphen, no leading hyphen, ≤80 chars).
117
- * - No `..` segments, no empty segments (`a//b`), no leading or trailing `/`.
118
- * - No `\` (Windows separator), no null bytes, no whitespace, no non-ASCII.
119
- */
120
- export function validateNodeId(id: string): void {
121
- if (typeof id !== "string" || id.length === 0) {
122
- throw new Error(`Invalid tree-node id: empty`);
123
- }
124
- if (id === ROOT_NODE_ID) {
125
- return;
126
- }
127
- if (id.length > MAX_ID_TOTAL_LENGTH) {
128
- throw new Error(
129
- `Invalid tree-node id: length ${id.length} exceeds max ${MAX_ID_TOTAL_LENGTH}: ${id}`,
130
- );
131
- }
132
- if (id.includes("\\")) {
133
- throw new Error(`Invalid tree-node id: backslash not allowed: ${id}`);
134
- }
135
- if (id.includes("\0")) {
136
- throw new Error(`Invalid tree-node id: null byte not allowed`);
137
- }
138
- if (/\s/.test(id)) {
139
- throw new Error(`Invalid tree-node id: whitespace not allowed: ${id}`);
140
- }
141
- if (id.startsWith("/") || id.endsWith("/")) {
142
- throw new Error(
143
- `Invalid tree-node id: leading or trailing '/' not allowed: ${id}`,
144
- );
145
- }
146
- const segments = id.split("/");
147
- for (const segment of segments) {
148
- if (segment.length === 0) {
149
- throw new Error(`Invalid tree-node id: empty path segment: ${id}`);
150
- }
151
- if (segment === "..") {
152
- throw new Error(`Invalid tree-node id: '..' segment not allowed: ${id}`);
153
- }
154
- if (segment.length > MAX_ID_SEGMENT_LENGTH) {
155
- throw new Error(
156
- `Invalid tree-node id: segment '${segment}' exceeds max ${MAX_ID_SEGMENT_LENGTH} chars: ${id}`,
157
- );
158
- }
159
- if (!ID_SEGMENT_REGEX.test(segment)) {
160
- throw new Error(
161
- `Invalid tree-node id: segment '${segment}' must match [a-z0-9][a-z0-9-]*: ${id}`,
162
- );
163
- }
164
- }
165
- }
166
-
167
- // ---------------------------------------------------------------------------
168
- // Path helpers
169
- // ---------------------------------------------------------------------------
170
-
171
- export function getTreeDir(workspaceDir: string): string {
172
- return join(workspaceDir, "memory", "tree");
173
- }
174
-
175
- /**
176
- * Resolve the absolute path for a node id. Ids may contain `/` to indicate
177
- * folder hierarchy under `memory/tree/`; `path.join` handles those correctly
178
- * on POSIX, and `validateNodeId` (called at every public entry point) rejects
179
- * shapes that could escape the tree root.
180
- */
181
- function getNodePath(workspaceDir: string, id: string): string {
182
- return join(getTreeDir(workspaceDir), `${id}${NODE_EXTENSION}`);
183
- }
184
-
185
- /**
186
- * Compute the id for a tree-node file, given the tree root and the absolute
187
- * file path. Returns the path-relative location with `.md` stripped and
188
- * platform separators normalized to `/`. Tolerant of paths that don't end in
189
- * `.md` so callers walking arbitrary content can use it defensively.
190
- */
191
- function idFromNodePath(treeRoot: string, filePath: string): string {
192
- const rel = relative(treeRoot, filePath);
193
- const withoutExt = rel.endsWith(NODE_EXTENSION)
194
- ? rel.slice(0, -NODE_EXTENSION.length)
195
- : rel;
196
- return sep === "/" ? withoutExt : withoutExt.split(sep).join("/");
197
- }
198
-
199
- // ---------------------------------------------------------------------------
200
- // Frontmatter parse / render
201
- // ---------------------------------------------------------------------------
202
-
203
- /**
204
- * Split raw file contents into (frontmatter, body). If no frontmatter block is
205
- * present the entire input is treated as body and an empty frontmatter block is
206
- * returned (validated by `TreeNodeFrontmatterSchema` so any unexpected shape —
207
- * bad types, extra junk — surfaces as a parse error to the caller, not silent
208
- * dropped data).
209
- *
210
- * The schema's default guarantees `children` is always an array even on a
211
- * freshly created node with empty frontmatter.
212
- */
213
- function parseNodeContent(raw: string): {
214
- frontmatter: TreeNode["frontmatter"];
215
- body: string;
216
- } {
217
- const match = raw.match(FRONTMATTER_REGEX);
218
- if (!match) {
219
- return {
220
- frontmatter: TreeNodeFrontmatterSchema.parse({}),
221
- body: raw,
222
- };
223
- }
224
- const yamlBlock = match[1];
225
- const body = raw.slice(match[0].length);
226
- const parsed = parseYaml(yamlBlock) ?? {};
227
- return {
228
- frontmatter: TreeNodeFrontmatterSchema.parse(parsed),
229
- body,
230
- };
231
- }
232
-
233
- /**
234
- * Render a tree node back into the on-disk Markdown form. The output is always
235
- * frontmatter + body; even nodes with empty `children` keep the explicit YAML
236
- * key so callers see the canonical shape on round-trip.
237
- */
238
- export function renderNodeContent(node: TreeNode): string {
239
- const frontmatter = TreeNodeFrontmatterSchema.parse(node.frontmatter);
240
- const yamlBlock = stringifyYaml(frontmatter, { indent: 2 }).trimEnd();
241
- return `---\n${yamlBlock}\n---\n${node.body}`;
242
- }
243
-
244
- // ---------------------------------------------------------------------------
245
- // Public API
246
- // ---------------------------------------------------------------------------
247
-
248
- /**
249
- * Read a single tree node. Returns `null` if the file does not exist.
250
- *
251
- * Any other read or parse failure (permission denied, malformed YAML,
252
- * frontmatter that fails schema validation) throws — unlike "missing", these
253
- * are programmer / data-corruption errors the caller needs to see.
254
- */
255
- export async function readNode(
256
- workspaceDir: string,
257
- id: string,
258
- ): Promise<TreeNode | null> {
259
- validateNodeId(id);
260
- const path = getNodePath(workspaceDir, id);
261
- let raw: string;
262
- try {
263
- raw = await readFile(path, "utf-8");
264
- } catch (err) {
265
- if ((err as NodeJS.ErrnoException).code === "ENOENT") {
266
- return null;
267
- }
268
- throw err;
269
- }
270
- const { frontmatter, body } = parseNodeContent(raw);
271
- return { id, frontmatter, body };
272
- }
273
-
274
- /**
275
- * File mtime for a tree node, in epoch ms. Returns 0 when the file is missing
276
- * or unreadable — callers treat 0 as "no mtime" (e.g. the validator's stale-
277
- * index check reads a missing node as the oldest possible mtime so it never
278
- * spuriously flags a parent against an absent child). Mirrors v2's
279
- * `getPageMtimeMs`.
280
- */
281
- export async function getNodeMtimeMs(
282
- workspaceDir: string,
283
- id: string,
284
- ): Promise<number> {
285
- validateNodeId(id);
286
- try {
287
- const s = await stat(getNodePath(workspaceDir, id));
288
- return s.mtimeMs;
289
- } catch {
290
- return 0;
291
- }
292
- }
293
-
294
- /**
295
- * Write a tree node atomically (temp file + rename). A crash between the temp
296
- * write and the rename leaves the prior file intact; a crash after the rename
297
- * leaves the new file. Readers therefore never observe a partial node.
298
- *
299
- * Parent directories are created on demand (`mkdir -p`) so nested-folder ids
300
- * like `people/colleagues` work without callers pre-creating the folder.
301
- */
302
- export async function writeNode(
303
- workspaceDir: string,
304
- node: TreeNode,
305
- ): Promise<void> {
306
- validateNodeId(node.id);
307
- const path = getNodePath(workspaceDir, node.id);
308
- const tmpPath = `${path}.tmp.${process.pid}.${randomUUID()}`;
309
- const content = renderNodeContent(node);
310
- try {
311
- await mkdir(dirname(path), { recursive: true });
312
- await writeFile(tmpPath, content, "utf-8");
313
- await rename(tmpPath, path);
314
- } catch (err) {
315
- // Best-effort cleanup: if the rename failed (or the write succeeded but the
316
- // rename did not), remove the orphan tmp file so we don't leak it into the
317
- // tree/ directory where listNodes would then surface it.
318
- await rm(tmpPath, { force: true }).catch(() => {});
319
- throw err;
320
- }
321
- invalidateTreeIndex(workspaceDir);
322
- }
323
-
324
- /**
325
- * List every tree-node id present on disk, walking subdirectories.
326
- *
327
- * Ids are returned in path-relative form with forward slashes as separators
328
- * (e.g. `people/colleagues`) so callers can pass them straight back to
329
- * `readNode`.
330
- *
331
- * Hidden directories (segment starts with `.`), non-`.md` files, and atomic-
332
- * write temp files (`.tmp.<pid>.<uuid>`) are skipped. If the tree/ directory
333
- * does not yet exist (fresh workspace pre-migration), returns `[]`.
334
- */
335
- export async function listNodes(workspaceDir: string): Promise<string[]> {
336
- const root = getTreeDir(workspaceDir);
337
- const ids: string[] = [];
338
- const queue: string[] = [root];
339
-
340
- while (queue.length > 0) {
341
- const dir = queue.shift()!;
342
- let entries;
343
- try {
344
- entries = await readdir(dir, { withFileTypes: true });
345
- } catch (err) {
346
- if ((err as NodeJS.ErrnoException).code === "ENOENT") {
347
- // Root missing → return []. Nested missing dir is impossible mid-walk
348
- // (we only enqueue what readdir surfaced) but treat the same defensively.
349
- if (dir === root) return [];
350
- continue;
351
- }
352
- throw err;
353
- }
354
-
355
- for (const entry of entries) {
356
- if (entry.name.startsWith(".")) continue;
357
- const fullPath = join(dir, entry.name);
358
- if (entry.isDirectory()) {
359
- queue.push(fullPath);
360
- continue;
361
- }
362
- if (!entry.isFile()) continue;
363
- if (!entry.name.endsWith(NODE_EXTENSION)) continue;
364
- // Skip orphaned temp files left behind by a crashed atomic write.
365
- if (entry.name.includes(".tmp.")) continue;
366
- ids.push(idFromNodePath(root, fullPath));
367
- }
368
- }
369
-
370
- ids.sort();
371
- return ids;
372
- }
373
-
374
- /**
375
- * Delete a tree node. Idempotent — missing files are not an error.
376
- *
377
- * Any other failure (permission denied, etc.) throws so the caller can react.
378
- */
379
- export async function deleteNode(
380
- workspaceDir: string,
381
- id: string,
382
- ): Promise<void> {
383
- validateNodeId(id);
384
- const path = getNodePath(workspaceDir, id);
385
- try {
386
- await rm(path);
387
- } catch (err) {
388
- if ((err as NodeJS.ErrnoException).code === "ENOENT") {
389
- return;
390
- }
391
- throw err;
392
- }
393
- invalidateTreeIndex(workspaceDir);
394
- }