@vellumai/assistant 0.3.4 → 0.3.6

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 (506) hide show
  1. package/Dockerfile +2 -0
  2. package/README.md +88 -2
  3. package/eslint.config.mjs +31 -0
  4. package/package.json +1 -1
  5. package/scripts/ipc/check-swift-decoder-drift.ts +4 -1
  6. package/scripts/ipc/generate-swift.ts +31 -2
  7. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +438 -1
  8. package/src/__tests__/approval-conversation-turn.test.ts +214 -0
  9. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +41 -0
  10. package/src/__tests__/approval-message-composer.test.ts +253 -0
  11. package/src/__tests__/browser-manager.test.ts +1 -0
  12. package/src/__tests__/call-conversation-messages.test.ts +130 -0
  13. package/src/__tests__/call-domain.test.ts +12 -2
  14. package/src/__tests__/call-orchestrator.test.ts +799 -249
  15. package/src/__tests__/call-pointer-messages.test.ts +148 -0
  16. package/src/__tests__/call-recovery.test.ts +3 -0
  17. package/src/__tests__/call-routes-http.test.ts +32 -2
  18. package/src/__tests__/call-store.test.ts +3 -0
  19. package/src/__tests__/channel-approval-routes.test.ts +1277 -98
  20. package/src/__tests__/channel-approval.test.ts +37 -0
  21. package/src/__tests__/channel-approvals.test.ts +36 -50
  22. package/src/__tests__/channel-guardian.test.ts +630 -22
  23. package/src/__tests__/channel-readiness-service.test.ts +324 -0
  24. package/src/__tests__/checker.test.ts +14 -7
  25. package/src/__tests__/clarification-resolver.test.ts +44 -24
  26. package/src/__tests__/commit-message-enrichment-service.test.ts +9 -4
  27. package/src/__tests__/computer-use-session-working-dir.test.ts +8 -0
  28. package/src/__tests__/config-schema.test.ts +14 -8
  29. package/src/__tests__/context-window-manager.test.ts +30 -2
  30. package/src/__tests__/contradiction-checker.test.ts +20 -5
  31. package/src/__tests__/credential-security-invariants.test.ts +7 -2
  32. package/src/__tests__/daemon-lifecycle.test.ts +13 -12
  33. package/src/__tests__/db-migration-rollback.test.ts +752 -0
  34. package/src/__tests__/dictation-mode-detection.test.ts +63 -0
  35. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -0
  36. package/src/__tests__/entity-search.test.ts +615 -0
  37. package/src/__tests__/fuzzy-match-property.test.ts +5 -5
  38. package/src/__tests__/guardian-action-store.test.ts +123 -0
  39. package/src/__tests__/guardian-action-sweep.test.ts +277 -0
  40. package/src/__tests__/guardian-dispatch.test.ts +389 -0
  41. package/src/__tests__/guardian-question-copy.test.ts +47 -0
  42. package/src/__tests__/handlers-telegram-config.test.ts +4 -2
  43. package/src/__tests__/handlers-twilio-config.test.ts +533 -0
  44. package/src/__tests__/intent-routing.test.ts +2 -0
  45. package/src/__tests__/ipc-snapshot.test.ts +291 -1
  46. package/src/__tests__/memory-upsert-concurrency.test.ts +828 -0
  47. package/src/__tests__/messaging-send-tool.test.ts +65 -0
  48. package/src/__tests__/model-intents.test.ts +96 -0
  49. package/src/__tests__/no-direct-anthropic-sdk-imports.test.ts +42 -0
  50. package/src/__tests__/oauth2-gateway-transport.test.ts +130 -0
  51. package/src/__tests__/onboarding-starter-tasks.test.ts +2 -0
  52. package/src/__tests__/provider-commit-message-generator.test.ts +89 -13
  53. package/src/__tests__/provider-error-scenarios.test.ts +621 -0
  54. package/src/__tests__/provider-fail-open-selection.test.ts +119 -0
  55. package/src/__tests__/qdrant-manager.test.ts +27 -20
  56. package/src/__tests__/relay-server.test.ts +779 -40
  57. package/src/__tests__/run-orchestrator-assistant-events.test.ts +6 -0
  58. package/src/__tests__/run-orchestrator.test.ts +42 -4
  59. package/src/__tests__/runtime-runs-http.test.ts +17 -1
  60. package/src/__tests__/runtime-runs.test.ts +16 -0
  61. package/src/__tests__/schedule-store.test.ts +18 -4
  62. package/src/__tests__/scheduler-recurrence.test.ts +13 -4
  63. package/src/__tests__/session-abort-tool-results.test.ts +6 -0
  64. package/src/__tests__/session-agent-loop.test.ts +857 -0
  65. package/src/__tests__/session-conflict-gate.test.ts +6 -0
  66. package/src/__tests__/session-pre-run-repair.test.ts +6 -0
  67. package/src/__tests__/session-profile-injection.test.ts +6 -0
  68. package/src/__tests__/session-provider-retry-repair.test.ts +6 -0
  69. package/src/__tests__/session-queue.test.ts +6 -0
  70. package/src/__tests__/session-runtime-assembly.test.ts +321 -13
  71. package/src/__tests__/session-slash-known.test.ts +6 -0
  72. package/src/__tests__/session-slash-queue.test.ts +6 -0
  73. package/src/__tests__/session-slash-unknown.test.ts +6 -0
  74. package/src/__tests__/session-surfaces-task-progress.test.ts +2 -0
  75. package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -0
  76. package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -0
  77. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -0
  78. package/src/__tests__/session-workspace-injection.test.ts +6 -0
  79. package/src/__tests__/session-workspace-tool-tracking.test.ts +6 -0
  80. package/src/__tests__/skills.test.ts +2 -0
  81. package/src/__tests__/sms-messaging-provider.test.ts +126 -0
  82. package/src/__tests__/starter-task-flow.test.ts +2 -0
  83. package/src/__tests__/swarm-dag-pathological.test.ts +535 -0
  84. package/src/__tests__/system-prompt.test.ts +2 -0
  85. package/src/__tests__/task-management-tools.test.ts +2 -2
  86. package/src/__tests__/task-runner.test.ts +14 -4
  87. package/src/__tests__/terminal-tools.test.ts +25 -19
  88. package/src/__tests__/tool-execution-abort-cleanup.test.ts +545 -0
  89. package/src/__tests__/tool-executor-shell-integration.test.ts +11 -11
  90. package/src/__tests__/tool-executor.test.ts +23 -24
  91. package/src/__tests__/trust-store.test.ts +3 -3
  92. package/src/__tests__/twilio-rest.test.ts +29 -0
  93. package/src/__tests__/twilio-routes-elevenlabs.test.ts +3 -0
  94. package/src/__tests__/twilio-routes-twiml.test.ts +11 -0
  95. package/src/__tests__/twilio-routes.test.ts +167 -11
  96. package/src/__tests__/twitter-cli-error-shaping.test.ts +2 -2
  97. package/src/__tests__/user-reference.test.ts +2 -0
  98. package/src/__tests__/voice-quality.test.ts +222 -0
  99. package/src/__tests__/web-search.test.ts +46 -30
  100. package/src/__tests__/work-item-output.test.ts +110 -0
  101. package/src/agent/loop.ts +1 -1
  102. package/src/agent-heartbeat/agent-heartbeat-service.ts +2 -10
  103. package/src/amazon/client.ts +1418 -0
  104. package/src/amazon/request-extractor.ts +135 -0
  105. package/src/amazon/session.ts +109 -0
  106. package/src/autonomy/autonomy-store.ts +5 -5
  107. package/src/browser-extension-relay/client.ts +124 -0
  108. package/src/browser-extension-relay/protocol.ts +63 -0
  109. package/src/browser-extension-relay/server.ts +177 -0
  110. package/src/bundler/app-bundler.ts +3 -3
  111. package/src/bundler/bundle-signer.ts +1 -1
  112. package/src/bundler/signature-verifier.ts +1 -1
  113. package/src/calls/call-conversation-messages.ts +33 -0
  114. package/src/calls/call-domain.ts +114 -10
  115. package/src/calls/call-orchestrator.ts +268 -59
  116. package/src/calls/call-pointer-messages.ts +53 -0
  117. package/src/calls/call-recovery.ts +3 -8
  118. package/src/calls/call-store.ts +69 -87
  119. package/src/calls/elevenlabs-config.ts +3 -2
  120. package/src/calls/guardian-action-sweep.ts +105 -0
  121. package/src/calls/guardian-dispatch.ts +203 -0
  122. package/src/calls/guardian-question-copy.ts +133 -0
  123. package/src/calls/relay-server.ts +466 -8
  124. package/src/calls/speaker-identification.ts +1 -1
  125. package/src/calls/twilio-config.ts +22 -14
  126. package/src/calls/twilio-provider.ts +6 -4
  127. package/src/calls/twilio-rest.ts +308 -7
  128. package/src/calls/twilio-routes.ts +65 -12
  129. package/src/calls/types.ts +3 -1
  130. package/src/channels/types.ts +25 -0
  131. package/src/cli/amazon.ts +815 -0
  132. package/src/cli/config-commands.ts +2 -2
  133. package/src/cli/core-commands.ts +4 -3
  134. package/src/cli/influencer.ts +244 -0
  135. package/src/cli/map.ts +89 -6
  136. package/src/cli.ts +1 -1
  137. package/src/config/agent-schema.ts +171 -0
  138. package/src/config/bundled-skills/amazon/SKILL.md +127 -0
  139. package/src/config/bundled-skills/amazon/icon.svg +13 -0
  140. package/src/config/bundled-skills/api-mapping/SKILL.md +78 -0
  141. package/src/config/bundled-skills/browser/SKILL.md +1 -0
  142. package/src/config/bundled-skills/browser/TOOLS.json +17 -0
  143. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +25 -0
  144. package/src/config/bundled-skills/doordash/SKILL.md +51 -51
  145. package/src/config/bundled-skills/email-setup/SKILL.md +14 -5
  146. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +183 -0
  147. package/src/config/bundled-skills/influencer/SKILL.md +144 -0
  148. package/src/config/bundled-skills/knowledge-graph/SKILL.md +15 -0
  149. package/src/config/bundled-skills/knowledge-graph/TOOLS.json +56 -0
  150. package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +185 -0
  151. package/src/config/bundled-skills/macos-automation/icon.svg +12 -0
  152. package/src/config/bundled-skills/media-processing/SKILL.md +176 -0
  153. package/src/config/bundled-skills/media-processing/TOOLS.json +230 -0
  154. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +77 -0
  155. package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +69 -0
  156. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +303 -0
  157. package/src/config/bundled-skills/media-processing/services/concurrency-pool.ts +55 -0
  158. package/src/config/bundled-skills/media-processing/services/cost-tracker.ts +86 -0
  159. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +339 -0
  160. package/src/config/bundled-skills/media-processing/services/preprocess.ts +551 -0
  161. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +259 -0
  162. package/src/config/bundled-skills/media-processing/services/reduce.ts +197 -0
  163. package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +136 -0
  164. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +59 -0
  165. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +195 -0
  166. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +197 -0
  167. package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +143 -0
  168. package/src/config/bundled-skills/media-processing/tools/media-status.ts +75 -0
  169. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +65 -0
  170. package/src/config/bundled-skills/messaging/SKILL.md +33 -8
  171. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -7
  172. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +2 -1
  173. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -1
  174. package/src/config/bundled-skills/phone-calls/SKILL.md +88 -23
  175. package/src/config/bundled-skills/twitter/SKILL.md +19 -3
  176. package/src/config/bundled-skills/twitter/icon.svg +14 -0
  177. package/src/config/bundled-tool-registry.ts +310 -0
  178. package/src/config/calls-schema.ts +181 -0
  179. package/src/config/core-schema.ts +309 -0
  180. package/src/config/defaults.ts +28 -3
  181. package/src/config/env-registry.ts +162 -0
  182. package/src/config/env.ts +175 -0
  183. package/src/config/loader.ts +6 -6
  184. package/src/config/memory-schema.ts +528 -0
  185. package/src/config/sandbox-schema.ts +55 -0
  186. package/src/config/schema.ts +158 -1133
  187. package/src/config/skill-state.ts +1 -1
  188. package/src/config/skills-schema.ts +32 -0
  189. package/src/config/skills.ts +35 -24
  190. package/src/config/system-prompt.ts +131 -56
  191. package/src/config/templates/IDENTITY.md +2 -2
  192. package/src/config/templates/SOUL.md +1 -1
  193. package/src/config/types.ts +1 -0
  194. package/src/config/user-reference.ts +4 -9
  195. package/src/config/vellum-skills/catalog.json +6 -7
  196. package/src/config/vellum-skills/chatgpt-import/tools/chatgpt-import.ts +5 -1
  197. package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +4 -3
  198. package/src/config/vellum-skills/sms-setup/SKILL.md +216 -0
  199. package/src/config/vellum-skills/twilio-setup/SKILL.md +40 -8
  200. package/src/context/window-manager.ts +27 -7
  201. package/src/daemon/approval-generators.ts +186 -0
  202. package/src/daemon/approved-devices-store.ts +140 -0
  203. package/src/daemon/assistant-attachments.ts +1 -1
  204. package/src/daemon/classifier.ts +35 -32
  205. package/src/daemon/config-watcher.ts +1 -1
  206. package/src/daemon/daemon-control.ts +217 -0
  207. package/src/daemon/handlers/apps.ts +2 -3
  208. package/src/daemon/handlers/config-channels.ts +158 -0
  209. package/src/daemon/handlers/config-inbox.ts +540 -0
  210. package/src/daemon/handlers/config-ingress.ts +231 -0
  211. package/src/daemon/handlers/config-integrations.ts +258 -0
  212. package/src/daemon/handlers/config-model.ts +143 -0
  213. package/src/daemon/handlers/config-parental.ts +163 -0
  214. package/src/daemon/handlers/config-scheduling.ts +172 -0
  215. package/src/daemon/handlers/config-slack.ts +92 -0
  216. package/src/daemon/handlers/config-telegram.ts +301 -0
  217. package/src/daemon/handlers/config-tools.ts +177 -0
  218. package/src/daemon/handlers/config-trust.ts +104 -0
  219. package/src/daemon/handlers/config-twilio.ts +1080 -0
  220. package/src/daemon/handlers/config.ts +53 -1689
  221. package/src/daemon/handlers/diagnostics.ts +1 -1
  222. package/src/daemon/handlers/dictation.ts +180 -0
  223. package/src/daemon/handlers/documents.ts +18 -32
  224. package/src/daemon/handlers/identity.ts +14 -23
  225. package/src/daemon/handlers/index.ts +11 -0
  226. package/src/daemon/handlers/misc.ts +3 -5
  227. package/src/daemon/handlers/pairing.ts +98 -0
  228. package/src/daemon/handlers/sessions.ts +56 -5
  229. package/src/daemon/handlers/shared.ts +6 -1
  230. package/src/daemon/handlers/skills.ts +1 -1
  231. package/src/daemon/handlers/twitter-auth.ts +2 -0
  232. package/src/daemon/handlers/work-items.ts +17 -9
  233. package/src/daemon/handlers/workspace-files.ts +4 -3
  234. package/src/daemon/install-cli-launchers.ts +113 -0
  235. package/src/daemon/ipc-contract/apps.ts +356 -0
  236. package/src/daemon/ipc-contract/browser.ts +74 -0
  237. package/src/daemon/ipc-contract/computer-use.ts +151 -0
  238. package/src/daemon/ipc-contract/diagnostics.ts +56 -0
  239. package/src/daemon/ipc-contract/documents.ts +74 -0
  240. package/src/daemon/ipc-contract/inbox.ts +209 -0
  241. package/src/daemon/ipc-contract/integrations.ts +284 -0
  242. package/src/daemon/ipc-contract/memory.ts +48 -0
  243. package/src/daemon/ipc-contract/messages.ts +211 -0
  244. package/src/daemon/ipc-contract/pairing.ts +45 -0
  245. package/src/daemon/ipc-contract/parental-control.ts +95 -0
  246. package/src/daemon/ipc-contract/schedules.ts +97 -0
  247. package/src/daemon/ipc-contract/sessions.ts +315 -0
  248. package/src/daemon/ipc-contract/shared.ts +42 -0
  249. package/src/daemon/ipc-contract/skills.ts +120 -0
  250. package/src/daemon/ipc-contract/subagents.ts +58 -0
  251. package/src/daemon/ipc-contract/surfaces.ts +250 -0
  252. package/src/daemon/ipc-contract/trust.ts +60 -0
  253. package/src/daemon/ipc-contract/work-items.ts +225 -0
  254. package/src/daemon/ipc-contract/workspace.ts +113 -0
  255. package/src/daemon/ipc-contract-inventory.json +70 -0
  256. package/src/daemon/ipc-contract-inventory.ts +55 -29
  257. package/src/daemon/ipc-contract.ts +229 -2426
  258. package/src/daemon/ipc-protocol.ts +1 -1
  259. package/src/daemon/ipc-validate.ts +7 -0
  260. package/src/daemon/lifecycle.ts +97 -377
  261. package/src/daemon/pairing-store.ts +177 -0
  262. package/src/daemon/providers-setup.ts +43 -0
  263. package/src/daemon/ride-shotgun-handler.ts +68 -3
  264. package/src/daemon/server.ts +66 -46
  265. package/src/daemon/session-agent-loop-handlers.ts +421 -0
  266. package/src/daemon/session-agent-loop.ts +117 -275
  267. package/src/daemon/session-dynamic-profile.ts +1 -1
  268. package/src/daemon/session-history.ts +1 -1
  269. package/src/daemon/session-media-retry.ts +1 -1
  270. package/src/daemon/session-messaging.ts +37 -2
  271. package/src/daemon/session-notifiers.ts +5 -25
  272. package/src/daemon/session-process.ts +99 -59
  273. package/src/daemon/session-queue-manager.ts +96 -4
  274. package/src/daemon/session-runtime-assembly.ts +199 -10
  275. package/src/daemon/session-surfaces.ts +19 -4
  276. package/src/daemon/session-tool-setup.ts +30 -30
  277. package/src/daemon/session-workspace.ts +1 -1
  278. package/src/daemon/session.ts +35 -2
  279. package/src/daemon/shutdown-handlers.ts +122 -0
  280. package/src/daemon/trace-emitter.ts +1 -1
  281. package/src/daemon/watch-handler.ts +36 -33
  282. package/src/doordash/cart-queries.ts +787 -0
  283. package/src/doordash/client.ts +144 -127
  284. package/src/doordash/order-queries.ts +85 -0
  285. package/src/doordash/queries.ts +10 -1308
  286. package/src/doordash/search-queries.ts +203 -0
  287. package/src/doordash/session.ts +3 -2
  288. package/src/doordash/store-queries.ts +246 -0
  289. package/src/doordash/types.ts +367 -0
  290. package/src/email/providers/agentmail.ts +2 -1
  291. package/src/email/providers/index.ts +3 -2
  292. package/src/email/service.ts +3 -2
  293. package/src/errors.ts +43 -0
  294. package/src/home-base/prebuilt/seed.ts +1 -1
  295. package/src/hooks/cli.ts +6 -5
  296. package/src/hooks/config.ts +6 -8
  297. package/src/hooks/discovery.ts +6 -5
  298. package/src/hooks/manager.ts +4 -3
  299. package/src/hooks/runner.ts +2 -2
  300. package/src/hooks/templates.ts +5 -5
  301. package/src/inbound/public-ingress-urls.ts +6 -4
  302. package/src/index.ts +4 -2
  303. package/src/influencer/client.ts +1104 -0
  304. package/src/instrument.ts +4 -3
  305. package/src/logfire.ts +4 -3
  306. package/src/memory/admin.ts +25 -35
  307. package/src/memory/attachments-store.ts +4 -7
  308. package/src/memory/channel-delivery-store.ts +30 -1
  309. package/src/memory/channel-guardian-store.ts +202 -2
  310. package/src/memory/clarification-resolver.ts +37 -33
  311. package/src/memory/conflict-store.ts +67 -61
  312. package/src/memory/contradiction-checker.ts +141 -117
  313. package/src/memory/conversation-store.ts +335 -51
  314. package/src/memory/db-connection.ts +27 -4
  315. package/src/memory/db-init.ts +265 -4
  316. package/src/memory/db.ts +14 -1
  317. package/src/memory/embedding-backend.ts +27 -5
  318. package/src/memory/embedding-ollama.ts +2 -1
  319. package/src/memory/entity-extractor.ts +38 -35
  320. package/src/memory/guardian-action-store.ts +430 -0
  321. package/src/memory/inbox-escalation-projection.ts +59 -0
  322. package/src/memory/inbox-thread-store.ts +218 -0
  323. package/src/memory/ingress-invite-store.ts +338 -0
  324. package/src/memory/ingress-member-store.ts +350 -0
  325. package/src/memory/items-extractor.ts +91 -97
  326. package/src/memory/job-handlers/index-maintenance.ts +3 -3
  327. package/src/memory/job-handlers/media-processing.ts +69 -0
  328. package/src/memory/job-handlers/summarization.ts +32 -26
  329. package/src/memory/job-utils.ts +3 -10
  330. package/src/memory/jobs-store.ts +8 -10
  331. package/src/memory/jobs-worker.ts +55 -36
  332. package/src/memory/media-store.ts +759 -0
  333. package/src/memory/migrations/001-job-deferrals.ts +45 -0
  334. package/src/memory/migrations/002-tool-invocations-fk.ts +43 -0
  335. package/src/memory/migrations/003-memory-fts-backfill.ts +24 -0
  336. package/src/memory/migrations/004-entity-relation-dedup.ts +87 -0
  337. package/src/memory/migrations/005-fingerprint-scope-unique.ts +80 -0
  338. package/src/memory/migrations/006-scope-salted-fingerprints.ts +62 -0
  339. package/src/memory/migrations/007-assistant-id-to-self.ts +254 -0
  340. package/src/memory/migrations/008-remove-assistant-id-columns.ts +208 -0
  341. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +83 -0
  342. package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +56 -0
  343. package/src/memory/migrations/011-call-sessions-provider-sid-dedup.ts +63 -0
  344. package/src/memory/migrations/012-call-sessions-add-initiated-from.ts +19 -0
  345. package/src/memory/migrations/013-guardian-action-tables.ts +68 -0
  346. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +76 -0
  347. package/src/memory/migrations/015-drop-active-search-index.ts +27 -0
  348. package/src/memory/migrations/016-memory-segments-indexes.ts +11 -0
  349. package/src/memory/migrations/017-memory-items-indexes.ts +10 -0
  350. package/src/memory/migrations/018-remaining-table-indexes.ts +13 -0
  351. package/src/memory/migrations/index.ts +24 -0
  352. package/src/memory/migrations/registry.ts +79 -0
  353. package/src/memory/migrations/validate-migration-state.ts +69 -0
  354. package/src/memory/qdrant-manager.ts +49 -8
  355. package/src/memory/query-builder.ts +1 -1
  356. package/src/memory/raw-query.ts +119 -0
  357. package/src/memory/recall-cache.ts +4 -1
  358. package/src/memory/retriever.ts +165 -47
  359. package/src/memory/schema-migration.ts +25 -984
  360. package/src/memory/schema.ts +228 -7
  361. package/src/memory/search/entity.ts +205 -31
  362. package/src/memory/search/lexical.ts +81 -52
  363. package/src/memory/search/ranking.ts +27 -23
  364. package/src/memory/search/semantic.ts +157 -19
  365. package/src/memory/search/types.ts +24 -0
  366. package/src/memory/shared-app-links-store.ts +4 -5
  367. package/src/memory/validation.ts +19 -0
  368. package/src/messaging/draft-store.ts +5 -6
  369. package/src/messaging/provider-types.ts +2 -0
  370. package/src/messaging/providers/sms/adapter.ts +201 -0
  371. package/src/messaging/providers/sms/client.ts +93 -0
  372. package/src/messaging/providers/sms/types.ts +7 -0
  373. package/src/messaging/providers/telegram-bot/adapter.ts +2 -5
  374. package/src/messaging/providers/whatsapp/adapter.ts +136 -0
  375. package/src/messaging/providers/whatsapp/client.ts +67 -0
  376. package/src/messaging/style-analyzer.ts +5 -4
  377. package/src/messaging/thread-summarizer.ts +61 -69
  378. package/src/messaging/triage-engine.ts +62 -71
  379. package/src/migrations/config-merge.ts +53 -0
  380. package/src/migrations/data-layout.ts +68 -0
  381. package/src/migrations/data-merge.ts +33 -0
  382. package/src/migrations/hooks-merge.ts +90 -0
  383. package/src/migrations/index.ts +6 -0
  384. package/src/migrations/log.ts +23 -0
  385. package/src/migrations/skills-merge.ts +33 -0
  386. package/src/migrations/workspace-layout.ts +79 -0
  387. package/src/permissions/checker.ts +133 -11
  388. package/src/permissions/prompter.ts +14 -0
  389. package/src/permissions/shell-identity.ts +31 -1
  390. package/src/permissions/trust-store.ts +21 -1
  391. package/src/providers/anthropic/client.ts +4 -4
  392. package/src/providers/failover.ts +2 -2
  393. package/src/providers/model-intents.ts +70 -0
  394. package/src/providers/ollama/client.ts +2 -1
  395. package/src/providers/provider-send-message.ts +176 -0
  396. package/src/providers/registry.ts +71 -30
  397. package/src/providers/retry.ts +35 -1
  398. package/src/providers/types.ts +12 -1
  399. package/src/runtime/approval-conversation-turn.ts +97 -0
  400. package/src/runtime/approval-message-composer.ts +253 -0
  401. package/src/runtime/channel-approval-parser.ts +36 -2
  402. package/src/runtime/channel-approvals.ts +11 -24
  403. package/src/runtime/channel-guardian-service.ts +88 -21
  404. package/src/runtime/channel-readiness-service.ts +418 -0
  405. package/src/runtime/channel-readiness-types.ts +35 -0
  406. package/src/runtime/channel-retry-sweep.ts +184 -0
  407. package/src/runtime/guardian-context-resolver.ts +108 -0
  408. package/src/runtime/http-server.ts +275 -717
  409. package/src/runtime/http-types.ts +59 -3
  410. package/src/runtime/middleware/auth.ts +116 -0
  411. package/src/runtime/middleware/error-handler.ts +33 -0
  412. package/src/runtime/middleware/twilio-validation.ts +127 -0
  413. package/src/runtime/routes/app-routes.ts +1 -1
  414. package/src/runtime/routes/call-routes.ts +51 -7
  415. package/src/runtime/routes/channel-delivery-routes.ts +170 -0
  416. package/src/runtime/routes/channel-guardian-routes.ts +1191 -0
  417. package/src/runtime/routes/channel-inbound-routes.ts +1152 -0
  418. package/src/runtime/routes/channel-route-shared.ts +144 -0
  419. package/src/runtime/routes/channel-routes.ts +32 -1588
  420. package/src/runtime/routes/conversation-routes.ts +50 -7
  421. package/src/runtime/routes/events-routes.ts +2 -2
  422. package/src/runtime/routes/identity-routes.ts +126 -0
  423. package/src/runtime/routes/pairing-routes.ts +143 -0
  424. package/src/runtime/routes/run-routes.ts +15 -1
  425. package/src/runtime/run-orchestrator.ts +86 -35
  426. package/src/schedule/schedule-store.ts +36 -32
  427. package/src/schedule/scheduler.ts +3 -3
  428. package/src/security/encrypted-store.ts +5 -7
  429. package/src/security/oauth2.ts +45 -15
  430. package/src/security/parental-control-store.ts +183 -0
  431. package/src/security/secret-allowlist.ts +4 -3
  432. package/src/security/secret-scanner.ts +5 -5
  433. package/src/security/secure-keys.ts +1 -1
  434. package/src/security/token-manager.ts +3 -2
  435. package/src/services/vercel-deploy.ts +6 -2
  436. package/src/skills/tool-manifest.ts +3 -3
  437. package/src/skills/vellum-catalog-remote.ts +75 -16
  438. package/src/slack/slack-webhook.ts +2 -1
  439. package/src/swarm/orchestrator.ts +92 -1
  440. package/src/swarm/router-planner.ts +6 -9
  441. package/src/swarm/worker-prompts.ts +9 -12
  442. package/src/tasks/task-compiler.ts +19 -28
  443. package/src/tasks/task-runner.ts +1 -1
  444. package/src/tools/assets/materialize.ts +2 -2
  445. package/src/tools/assets/search.ts +15 -14
  446. package/src/tools/browser/__tests__/auth-detector.test.ts +1 -0
  447. package/src/tools/browser/auto-navigate.ts +1 -0
  448. package/src/tools/browser/browser-execution.ts +10 -1
  449. package/src/tools/browser/browser-manager.ts +119 -4
  450. package/src/tools/browser/network-recorder.ts +5 -0
  451. package/src/tools/calls/call-start.ts +1 -0
  452. package/src/tools/credentials/broker.ts +11 -2
  453. package/src/tools/credentials/metadata-store.ts +18 -14
  454. package/src/tools/credentials/post-connect-hooks.ts +61 -0
  455. package/src/tools/credentials/vault.ts +49 -23
  456. package/src/tools/execution-target.ts +11 -1
  457. package/src/tools/executor.ts +68 -9
  458. package/src/tools/host-terminal/cli-discover.ts +1 -1
  459. package/src/tools/network/script-proxy/http-forwarder.ts +1 -1
  460. package/src/tools/network/script-proxy/mitm-handler.ts +1 -1
  461. package/src/tools/network/script-proxy/server.ts +1 -1
  462. package/src/tools/network/script-proxy/session-manager.ts +6 -5
  463. package/src/tools/network/web-fetch.ts +18 -2
  464. package/src/tools/network/web-search.ts +8 -4
  465. package/src/tools/reminder/reminder-store.ts +14 -15
  466. package/src/tools/schedule/create.ts +1 -0
  467. package/src/tools/schedule/list.ts +2 -1
  468. package/src/tools/shared/filesystem/file-ops-service.ts +5 -7
  469. package/src/tools/skills/skill-script-runner.ts +24 -9
  470. package/src/tools/skills/skill-tool-factory.ts +1 -0
  471. package/src/tools/tasks/work-item-enqueue.ts +2 -2
  472. package/src/tools/terminal/evaluate-typescript.ts +21 -12
  473. package/src/tools/terminal/parser.ts +50 -0
  474. package/src/tools/types.ts +2 -0
  475. package/src/tools/watcher/delete.ts +6 -0
  476. package/src/tools/weather/service.ts +1 -1
  477. package/src/twitter/client.ts +190 -24
  478. package/src/twitter/router.ts +1 -1
  479. package/src/twitter/session.ts +4 -3
  480. package/src/util/clipboard.ts +1 -1
  481. package/src/util/errors.ts +65 -8
  482. package/src/util/fs.ts +40 -0
  483. package/src/util/json.ts +10 -0
  484. package/src/util/log-redact.ts +189 -0
  485. package/src/util/logger.ts +19 -17
  486. package/src/util/object.ts +3 -0
  487. package/src/util/platform.ts +105 -363
  488. package/src/util/pricing.ts +1 -1
  489. package/src/util/promise-guard.ts +1 -1
  490. package/src/util/retry.ts +19 -0
  491. package/src/util/row-mapper.ts +79 -0
  492. package/src/util/silently.ts +21 -0
  493. package/src/watcher/engine.ts +5 -1
  494. package/src/watcher/provider-types.ts +20 -0
  495. package/src/watcher/providers/github.ts +156 -0
  496. package/src/watcher/providers/gmail.ts +1 -0
  497. package/src/watcher/providers/google-calendar.ts +1 -0
  498. package/src/watcher/providers/linear.ts +460 -0
  499. package/src/watcher/providers/slack.ts +1 -0
  500. package/src/work-items/work-item-runner.ts +1 -1
  501. package/src/workspace/git-service.ts +1 -1
  502. package/src/workspace/provider-commit-message-generator.ts +51 -22
  503. package/src/__tests__/call-bridge.test.ts +0 -517
  504. package/src/__tests__/session-process-bridge.test.ts +0 -244
  505. package/src/calls/call-bridge.ts +0 -168
  506. package/src/config/vellum-skills/google-oauth-setup/SKILL.md +0 -199
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Type definitions for DoorDash GraphQL API responses.
3
+ * These model the raw shapes returned by the API before extraction
4
+ * into the public-facing interfaces (SearchResult, StoreInfo, etc.).
5
+ */
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // Shared / reusable fragments
9
+ // ---------------------------------------------------------------------------
10
+
11
+ export interface DDTextAttributes {
12
+ textStyle?: string;
13
+ textColor?: string;
14
+ }
15
+
16
+ export interface DDText {
17
+ title?: string;
18
+ titleTextAttributes?: DDTextAttributes;
19
+ subtitle?: string;
20
+ subtitleTextAttributes?: DDTextAttributes;
21
+ accessory?: string;
22
+ accessoryTextAttributes?: DDTextAttributes;
23
+ description?: string;
24
+ }
25
+
26
+ export interface DDImage {
27
+ uri?: string;
28
+ }
29
+
30
+ export interface DDImages {
31
+ main?: DDImage;
32
+ }
33
+
34
+ export interface DDClickEvent {
35
+ data?: string;
36
+ }
37
+
38
+ export interface DDEvents {
39
+ click?: DDClickEvent;
40
+ }
41
+
42
+ export interface DDAddress {
43
+ displayAddress?: string;
44
+ }
45
+
46
+ export interface DDRatings {
47
+ averageRating?: number;
48
+ numRatingsDisplayString?: string;
49
+ }
50
+
51
+ export interface DDFeeLayout {
52
+ title?: string;
53
+ }
54
+
55
+ export interface DDPrice {
56
+ display_string?: string;
57
+ displayString?: string;
58
+ unit_amount?: number;
59
+ unitAmount?: number;
60
+ }
61
+
62
+ // ---------------------------------------------------------------------------
63
+ // Search / Feed responses
64
+ // ---------------------------------------------------------------------------
65
+
66
+ export interface DDFacetItem {
67
+ id?: string;
68
+ childrenCount?: number;
69
+ component?: { id?: string; category?: string };
70
+ name?: string;
71
+ text?: DDText;
72
+ images?: DDImages;
73
+ events?: DDEvents;
74
+ childrenMap?: DDFacetItem[];
75
+ }
76
+
77
+ export interface DDFeedSection {
78
+ id?: string;
79
+ header?: DDFacetItem;
80
+ body?: DDFacetItem[];
81
+ layout?: { omitFooter?: boolean };
82
+ }
83
+
84
+ export interface DDFacetFeed {
85
+ body?: DDFeedSection[];
86
+ page?: DDFacetItem;
87
+ header?: DDFacetItem;
88
+ footer?: DDFacetItem;
89
+ custom?: string;
90
+ logging?: string;
91
+ }
92
+
93
+ export interface DDSearchClickData {
94
+ store_id?: string | number;
95
+ storeId?: string | number;
96
+ }
97
+
98
+ // ---------------------------------------------------------------------------
99
+ // Store page responses
100
+ // ---------------------------------------------------------------------------
101
+
102
+ export interface DDStoreHeader {
103
+ id?: string;
104
+ name?: string;
105
+ description?: string;
106
+ address?: DDAddress;
107
+ ratings?: DDRatings;
108
+ deliveryFeeLayout?: DDFeeLayout;
109
+ deliveryTimeLayout?: DDFeeLayout;
110
+ priceRangeDisplayString?: string;
111
+ }
112
+
113
+ export interface DDMenuCategory {
114
+ id?: string;
115
+ name?: string;
116
+ numItems?: number;
117
+ }
118
+
119
+ export interface DDMenuBook {
120
+ menuCategories?: DDMenuCategory[];
121
+ }
122
+
123
+ export interface DDStoreItem {
124
+ id?: string;
125
+ name?: string;
126
+ description?: string;
127
+ displayPrice?: string;
128
+ imageUrl?: string;
129
+ imgUrl?: string;
130
+ storeId?: string;
131
+ }
132
+
133
+ export interface DDItemList {
134
+ items?: DDStoreItem[];
135
+ }
136
+
137
+ export interface DDCarousel {
138
+ items?: DDStoreItem[];
139
+ }
140
+
141
+ export interface DDStorepageFeed {
142
+ storeHeader?: DDStoreHeader;
143
+ menuBook?: DDMenuBook;
144
+ itemLists?: DDItemList[];
145
+ carousels?: DDCarousel[];
146
+ }
147
+
148
+ // ---------------------------------------------------------------------------
149
+ // Retail store feed responses
150
+ // ---------------------------------------------------------------------------
151
+
152
+ export interface DDRetailStoreStatus {
153
+ delivery?: { etaDisplayString?: string };
154
+ }
155
+
156
+ export interface DDRetailStoreHeader {
157
+ name?: string;
158
+ description?: string;
159
+ address?: DDAddress;
160
+ ratings?: DDRatings;
161
+ deliveryFeeLayout?: DDFeeLayout;
162
+ priceRangeDisplayString?: string;
163
+ status?: DDRetailStoreStatus;
164
+ }
165
+
166
+ export interface DDRetailStoreDetails {
167
+ id?: string;
168
+ name?: string;
169
+ storeHeader?: DDRetailStoreHeader;
170
+ }
171
+
172
+ export interface DDRetailProduct {
173
+ id?: string;
174
+ name?: string;
175
+ description?: string;
176
+ displayPrice?: string;
177
+ imageUrl?: string;
178
+ imgUrl?: string;
179
+ storeId?: string;
180
+ price?: DDPrice;
181
+ }
182
+
183
+ export interface DDRetailCollection {
184
+ products?: DDRetailProduct[];
185
+ items?: DDRetailProduct[];
186
+ }
187
+
188
+ export interface DDRetailL1Category {
189
+ id?: string;
190
+ name?: string;
191
+ numItems?: number;
192
+ }
193
+
194
+ export interface DDRetailStorePageFeed {
195
+ storeDetails?: DDRetailStoreDetails;
196
+ l1Categories?: DDRetailL1Category[];
197
+ collections?: DDRetailCollection[];
198
+ page?: unknown;
199
+ }
200
+
201
+ // ---------------------------------------------------------------------------
202
+ // Retail search responses
203
+ // ---------------------------------------------------------------------------
204
+
205
+ export interface DDRetailItemImage {
206
+ remote?: { uri?: string };
207
+ }
208
+
209
+ export interface DDRetailItemPrice {
210
+ display_string?: string;
211
+ unit_amount?: number;
212
+ }
213
+
214
+ export interface DDRetailItemData {
215
+ item_id?: string | number;
216
+ item_name?: string;
217
+ description?: string;
218
+ store_id?: string | number;
219
+ menu_id?: string | number;
220
+ price?: DDRetailItemPrice;
221
+ }
222
+
223
+ export interface DDRetailItemCustom {
224
+ item_data?: DDRetailItemData;
225
+ image?: DDRetailItemImage;
226
+ }
227
+
228
+ export interface DDLegoRetailItem {
229
+ custom?: string;
230
+ }
231
+
232
+ export interface DDSearchSummary {
233
+ totalCount?: number;
234
+ suggestedSearchKeyword?: string;
235
+ }
236
+
237
+ export interface DDRetailSearchResult {
238
+ legoRetailItems?: DDLegoRetailItem[];
239
+ searchSummary?: DDSearchSummary;
240
+ }
241
+
242
+ // ---------------------------------------------------------------------------
243
+ // Item page responses
244
+ // ---------------------------------------------------------------------------
245
+
246
+ export interface DDItemHeader {
247
+ id?: string;
248
+ name?: string;
249
+ description?: string;
250
+ displayString?: string;
251
+ unitAmount?: number;
252
+ currency?: string;
253
+ imgUrl?: string;
254
+ menuId?: string;
255
+ }
256
+
257
+ export interface DDOptionChoice {
258
+ id?: string;
259
+ name?: string;
260
+ displayString?: string;
261
+ unitAmount?: number;
262
+ defaultQuantity?: number;
263
+ nestedExtrasList?: DDNestedExtra[];
264
+ }
265
+
266
+ export interface DDNestedExtra {
267
+ id?: string;
268
+ name?: string;
269
+ isOptional?: boolean;
270
+ options?: DDNestedExtraChoice[];
271
+ }
272
+
273
+ export interface DDNestedExtraChoice {
274
+ id?: string;
275
+ name?: string;
276
+ displayString?: string;
277
+ }
278
+
279
+ export interface DDOptionList {
280
+ id?: string;
281
+ name?: string;
282
+ isOptional?: boolean;
283
+ minNumOptions?: number;
284
+ maxNumOptions?: number;
285
+ options?: DDOptionChoice[];
286
+ }
287
+
288
+ export interface DDSpecialInstructions {
289
+ characterMaxLength?: number;
290
+ placeholderText?: string;
291
+ isEnabled?: boolean;
292
+ }
293
+
294
+ export interface DDItemPreferences {
295
+ specialInstructions?: DDSpecialInstructions;
296
+ }
297
+
298
+ export interface DDItemPage {
299
+ itemHeader?: DDItemHeader;
300
+ optionLists?: DDOptionList[];
301
+ itemPreferences?: DDItemPreferences;
302
+ }
303
+
304
+ // ---------------------------------------------------------------------------
305
+ // Cart responses
306
+ // ---------------------------------------------------------------------------
307
+
308
+ export interface DDCartItemDetail {
309
+ name?: string;
310
+ }
311
+
312
+ export interface DDOrderItem {
313
+ id?: string;
314
+ item?: DDCartItemDetail;
315
+ quantity?: number;
316
+ priceDisplayString?: string;
317
+ }
318
+
319
+ export interface DDOrder {
320
+ orderItems?: DDOrderItem[];
321
+ }
322
+
323
+ export interface DDCartRestaurant {
324
+ id?: string;
325
+ name?: string;
326
+ }
327
+
328
+ export interface DDCart {
329
+ id?: string;
330
+ restaurant?: DDCartRestaurant;
331
+ orders?: DDOrder[];
332
+ subtotal?: number;
333
+ total?: number;
334
+ }
335
+
336
+ // ---------------------------------------------------------------------------
337
+ // Dropoff options responses
338
+ // ---------------------------------------------------------------------------
339
+
340
+ export interface DDDropoffOption {
341
+ id?: string;
342
+ displayString?: string;
343
+ isDefault?: boolean;
344
+ isEnabled?: boolean;
345
+ }
346
+
347
+ // ---------------------------------------------------------------------------
348
+ // Payment method responses
349
+ // ---------------------------------------------------------------------------
350
+
351
+ export interface DDPaymentMethod {
352
+ id?: string;
353
+ type?: string;
354
+ last4?: string;
355
+ isDefault?: boolean;
356
+ paymentMethodUuid?: string;
357
+ uuid?: string;
358
+ }
359
+
360
+ // ---------------------------------------------------------------------------
361
+ // Order responses
362
+ // ---------------------------------------------------------------------------
363
+
364
+ export interface DDCreateOrderResult {
365
+ cartId?: string;
366
+ orderUuid?: string;
367
+ }
@@ -7,6 +7,7 @@
7
7
  import type { AgentMailClient } from 'agentmail';
8
8
  import type { EmailProvider, SetupDomainOpts, CreateInboxOpts, EnsureInboxesOpts, SetupWebhookOpts, CreateDraftOpts, ListDraftsOpts, ListMessagesOpts, ListThreadsOpts } from '../provider.js';
9
9
  import type { EmailDomain, DnsRecord, EmailInbox, EmailDraft, EmailMessage, EmailThread, EmailWebhook, ProviderHealth, SendResult } from '../types.js';
10
+ import { ConfigError } from '../../util/errors.js';
10
11
 
11
12
  const DEFAULT_INBOX_PREFIXES = ['hello', 'support', 'ops'];
12
13
 
@@ -201,7 +202,7 @@ export class AgentMailProvider implements EmailProvider {
201
202
  if (inboxes.inboxes.length > 0) {
202
203
  return inboxes.inboxes[0].inboxId;
203
204
  }
204
- throw new Error('No inboxes found. Run: vellum email setup inboxes --domain <domain>');
205
+ throw new ConfigError('No inboxes found. Run: vellum email setup inboxes --domain <domain>');
205
206
  }
206
207
  }
207
208
 
@@ -7,6 +7,7 @@
7
7
  import type { EmailProvider } from '../provider.js';
8
8
  import { getSecureKey } from '../../security/secure-keys.js';
9
9
  import { loadRawConfig, getNestedValue } from '../../config/loader.js';
10
+ import { ConfigError } from '../../util/errors.js';
10
11
 
11
12
  export const SUPPORTED_PROVIDERS = ['agentmail'] as const;
12
13
  export type SupportedProvider = (typeof SUPPORTED_PROVIDERS)[number];
@@ -44,7 +45,7 @@ export async function createProvider(name?: SupportedProvider): Promise<EmailPro
44
45
  if (apiKey) break;
45
46
  }
46
47
  if (!apiKey) {
47
- throw new Error(
48
+ throw new ConfigError(
48
49
  'No AgentMail API key configured. Run: vellum keys set agentmail <key>',
49
50
  );
50
51
  }
@@ -53,6 +54,6 @@ export async function createProvider(name?: SupportedProvider): Promise<EmailPro
53
54
  return new AgentMailProvider(new AgentMailClient({ apiKey }));
54
55
  }
55
56
  default:
56
- throw new Error(`Unknown email provider: ${providerName}`);
57
+ throw new ConfigError(`Unknown email provider: ${providerName}`);
57
58
  }
58
59
  }
@@ -31,6 +31,7 @@ import {
31
31
  } from '../cli/email-guardrails.js';
32
32
  import { createProvider, getActiveProviderName, type SupportedProvider } from './providers/index.js';
33
33
  import { loadRawConfig, setNestedValue, saveRawConfig } from '../config/loader.js';
34
+ import { ConfigError } from '../util/errors.js';
34
35
 
35
36
  // ---------------------------------------------------------------------------
36
37
  // Guardrail error
@@ -156,12 +157,12 @@ export class EmailService {
156
157
  // Resolve inbox from the "from" address — fail fast if not found
157
158
  const health = await p.health();
158
159
  if (health.inboxes.length === 0) {
159
- throw new Error('No inboxes found. Run: vellum email setup inboxes --domain <domain>');
160
+ throw new ConfigError('No inboxes found. Run: vellum email setup inboxes --domain <domain>');
160
161
  }
161
162
  const inbox = health.inboxes.find(i => i.address === input.from || i.id === input.from);
162
163
  if (!inbox) {
163
164
  const available = health.inboxes.map(i => i.address || i.id).join(', ');
164
- throw new Error(`No inbox matches --from "${input.from}". Available: ${available}`);
165
+ throw new ConfigError(`No inbox matches --from "${input.from}". Available: ${available}`);
165
166
  }
166
167
  const inboxId = inbox.id;
167
168
  return p.createDraft({
package/src/errors.ts ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Central export point for the Vellum error hierarchy.
3
+ *
4
+ * Import from this module to access any named error class:
5
+ *
6
+ * import { VellumError, BackendUnavailableError, RateLimitError, ... } from '../errors.js';
7
+ *
8
+ * Full hierarchy (defined in util/errors.ts):
9
+ *
10
+ * VellumError — root base
11
+ * ├─ BackendError — infrastructure / external-service failures
12
+ * │ ├─ BackendUnavailableError — service not reachable or not configured
13
+ * │ └─ RateLimitError — request or token quota exceeded
14
+ * ├─ UserError — user input / policy violations
15
+ * └─ AssistantError — assistant-logic errors (carries ErrorCode)
16
+ * ├─ ProviderError
17
+ * ├─ ToolError
18
+ * ├─ PermissionDeniedError
19
+ * ├─ ConfigError
20
+ * ├─ DaemonError
21
+ * ├─ IpcError
22
+ * ├─ PlatformError
23
+ * ├─ IntegrityError
24
+ * └─ IngressBlockedError
25
+ */
26
+ export {
27
+ ErrorCode,
28
+ VellumError,
29
+ BackendError,
30
+ BackendUnavailableError,
31
+ RateLimitError,
32
+ UserError,
33
+ AssistantError,
34
+ ProviderError,
35
+ ToolError,
36
+ PermissionDeniedError,
37
+ ConfigError,
38
+ DaemonError,
39
+ IpcError,
40
+ PlatformError,
41
+ IntegrityError,
42
+ IngressBlockedError,
43
+ } from './util/errors.js';
@@ -94,7 +94,7 @@ export function ensurePrebuiltHomeBaseSeeded(): { appId: string; created: boolea
94
94
 
95
95
  const metadata = loadSeedMetadata();
96
96
  const html = loadPrebuiltHtml();
97
- if (html === null) {
97
+ if (html == null) {
98
98
  log.warn('Skipping Home Base seed — prebuilt HTML not available');
99
99
  return null;
100
100
  }
package/src/hooks/cli.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Command } from 'commander';
2
- import { existsSync, cpSync, readFileSync, chmodSync, rmSync } from 'node:fs';
2
+ import { cpSync, readFileSync, chmodSync, rmSync } from 'node:fs';
3
+ import { pathExists } from '../util/fs.js';
3
4
  import { join, resolve, sep } from 'node:path';
4
5
  import { discoverHooks, isValidInstallManifest } from './discovery.js';
5
6
  import { setHookEnabled, ensureHookInConfig, removeHook } from './config.js';
@@ -79,13 +80,13 @@ export function registerHooksCommand(program: Command): void {
79
80
  .description('Install a hook from a directory')
80
81
  .action((hookPath: string) => {
81
82
  const srcDir = resolve(hookPath);
82
- if (!existsSync(srcDir)) {
83
+ if (!pathExists(srcDir)) {
83
84
  log.error(`Directory not found: ${srcDir}`);
84
85
  process.exit(1);
85
86
  }
86
87
 
87
88
  const manifestPath = join(srcDir, 'hook.json');
88
- if (!existsSync(manifestPath)) {
89
+ if (!pathExists(manifestPath)) {
89
90
  log.error(`No hook.json found in ${srcDir}`);
90
91
  process.exit(1);
91
92
  }
@@ -117,7 +118,7 @@ export function registerHooksCommand(program: Command): void {
117
118
  process.exit(1);
118
119
  }
119
120
 
120
- if (existsSync(targetDir)) {
121
+ if (pathExists(targetDir)) {
121
122
  log.error(`Hook already installed: ${manifest.name}`);
122
123
  process.exit(1);
123
124
  }
@@ -125,7 +126,7 @@ export function registerHooksCommand(program: Command): void {
125
126
  cpSync(srcDir, targetDir, { recursive: true });
126
127
 
127
128
  // Make script executable
128
- if (existsSync(scriptPath)) {
129
+ if (pathExists(scriptPath)) {
129
130
  chmodSync(scriptPath, 0o755);
130
131
  }
131
132
 
@@ -1,5 +1,6 @@
1
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
1
+ import { writeFileSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
+ import { ensureDir, readTextFileSync } from '../util/fs.js';
3
4
  import { getHooksDir } from '../util/platform.js';
4
5
  import { getLogger } from '../util/logger.js';
5
6
  import type { HookConfig, HookConfigEntry, HookManifest } from './types.js';
@@ -14,14 +15,14 @@ function getConfigPath(): string {
14
15
 
15
16
  export function loadHooksConfig(): HookConfig {
16
17
  const configPath = getConfigPath();
17
- if (!existsSync(configPath)) {
18
+ const raw = readTextFileSync(configPath);
19
+ if (raw == null) {
18
20
  return { version: HOOKS_CONFIG_VERSION, hooks: {} };
19
21
  }
20
22
 
21
23
  try {
22
- const raw = readFileSync(configPath, 'utf-8');
23
24
  const parsed = JSON.parse(raw) as HookConfig;
24
- if (typeof parsed.version !== 'number' || typeof parsed.hooks !== 'object' || parsed.hooks === null) {
25
+ if (typeof parsed.version !== 'number' || typeof parsed.hooks !== 'object' || parsed.hooks == null) {
25
26
  log.warn({ configPath }, 'Invalid hooks config, using defaults');
26
27
  return { version: HOOKS_CONFIG_VERSION, hooks: {} };
27
28
  }
@@ -34,10 +35,7 @@ export function loadHooksConfig(): HookConfig {
34
35
 
35
36
  export function saveHooksConfig(config: HookConfig): void {
36
37
  const configPath = getConfigPath();
37
- const dir = dirname(configPath);
38
- if (!existsSync(dir)) {
39
- mkdirSync(dir, { recursive: true });
40
- }
38
+ ensureDir(dirname(configPath));
41
39
  writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
42
40
  }
43
41
 
@@ -1,5 +1,6 @@
1
- import { readdirSync, readFileSync, existsSync, type Dirent } from 'node:fs';
1
+ import { readdirSync, readFileSync, type Dirent } from 'node:fs';
2
2
  import { join, resolve, relative } from 'node:path';
3
+ import { pathExists } from '../util/fs.js';
3
4
  import { getHooksDir } from '../util/platform.js';
4
5
  import { loadHooksConfig } from './config.js';
5
6
  import { getLogger } from '../util/logger.js';
@@ -23,7 +24,7 @@ const VALID_EVENTS = new Set<string>([
23
24
  * (created before those fields were added) continue to be discovered.
24
25
  */
25
26
  export function isValidManifest(manifest: unknown): manifest is HookManifest {
26
- if (typeof manifest !== 'object' || manifest === null) return false;
27
+ if (typeof manifest !== 'object' || manifest == null) return false;
27
28
  const m = manifest as Record<string, unknown>;
28
29
  if (typeof m.name !== 'string' || !m.name) return false;
29
30
  if (typeof m.script !== 'string' || !m.script) return false;
@@ -50,7 +51,7 @@ export function isValidInstallManifest(manifest: unknown): manifest is HookManif
50
51
 
51
52
  export function discoverHooks(hooksDir?: string): DiscoveredHook[] {
52
53
  const dir = hooksDir ?? getHooksDir();
53
- if (!existsSync(dir)) return [];
54
+ if (!pathExists(dir)) return [];
54
55
 
55
56
  const config = loadHooksConfig();
56
57
  const hooks: DiscoveredHook[] = [];
@@ -68,7 +69,7 @@ export function discoverHooks(hooksDir?: string): DiscoveredHook[] {
68
69
 
69
70
  const hookDir = join(dir, entry.name);
70
71
  const manifestPath = join(hookDir, 'hook.json');
71
- if (!existsSync(manifestPath)) continue;
72
+ if (!pathExists(manifestPath)) continue;
72
73
 
73
74
  let manifest: unknown;
74
75
  try {
@@ -92,7 +93,7 @@ export function discoverHooks(hooksDir?: string): DiscoveredHook[] {
92
93
  log.warn({ hookDir, script: manifest.script }, 'Hook script path traversal detected, skipping');
93
94
  continue;
94
95
  }
95
- if (!existsSync(scriptPath)) {
96
+ if (!pathExists(scriptPath)) {
96
97
  log.warn({ hookDir, script: manifest.script }, 'Hook script not found, skipping');
97
98
  continue;
98
99
  }
@@ -1,4 +1,5 @@
1
- import { watch, existsSync, type FSWatcher } from 'node:fs';
1
+ import { watch, type FSWatcher } from 'node:fs';
2
+ import { pathExists } from '../util/fs.js';
2
3
  import { discoverHooks } from './discovery.js';
3
4
  import { runHookScript } from './runner.js';
4
5
  import { getLogger, isDebug } from '../util/logger.js';
@@ -49,7 +50,7 @@ export class HookManager {
49
50
  for (const hook of hooks) {
50
51
  try {
51
52
  const result = await runHookScript(hook, eventData);
52
- if (result.exitCode !== null && result.exitCode !== 0) {
53
+ if (result.exitCode != null && result.exitCode !== 0) {
53
54
  // Blocking hooks on pre-* events cancel the action
54
55
  if (isPreEvent && hook.manifest.blocking) {
55
56
  log.info({ hook: hook.name, event, exitCode: result.exitCode }, 'Blocking hook rejected action');
@@ -77,7 +78,7 @@ export class HookManager {
77
78
 
78
79
  watch(): void {
79
80
  const hooksDir = getHooksDir();
80
- if (!existsSync(hooksDir)) return;
81
+ if (!pathExists(hooksDir)) return;
81
82
 
82
83
  this.stopWatching();
83
84
 
@@ -1,6 +1,6 @@
1
1
  import { spawn } from 'node:child_process';
2
- import { existsSync } from 'node:fs';
3
2
  import { basename, extname, join } from 'node:path';
3
+ import { pathExists } from '../util/fs.js';
4
4
  import { homedir } from 'node:os';
5
5
  import { getRootDir, getWorkspaceDir } from '../util/platform.js';
6
6
  import { getHookSettings } from './config.js';
@@ -24,7 +24,7 @@ function resolveBunPath(): string {
24
24
  if (found) return found;
25
25
 
26
26
  const fallback = join(homedir(), '.bun', 'bin', 'bun');
27
- if (existsSync(fallback)) return fallback;
27
+ if (pathExists(fallback)) return fallback;
28
28
 
29
29
  throw new Error(
30
30
  'Cannot find a bun runtime to execute .ts hooks. ' +
@@ -1,6 +1,6 @@
1
- import { existsSync, readdirSync, readFileSync, cpSync, chmodSync, rmSync } from 'node:fs';
1
+ import { readdirSync, readFileSync, cpSync, chmodSync, rmSync, type Dirent } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- import type { Dirent } from 'node:fs';
3
+ import { pathExists } from '../util/fs.js';
4
4
  import { getHooksDir } from '../util/platform.js';
5
5
  import { ensureHookInConfig } from './config.js';
6
6
  import { getLogger } from '../util/logger.js';
@@ -15,7 +15,7 @@ const log = getLogger('hooks-templates');
15
15
  */
16
16
  export function installTemplates(): void {
17
17
  const templatesDir = join(import.meta.dirname ?? __dirname, '../../hook-templates');
18
- if (!existsSync(templatesDir)) return;
18
+ if (!pathExists(templatesDir)) return;
19
19
 
20
20
  const hooksDir = getHooksDir();
21
21
  const entries = readdirSync(templatesDir, { withFileTypes: true }) as Dirent[];
@@ -24,7 +24,7 @@ export function installTemplates(): void {
24
24
  if (!entry.isDirectory()) continue;
25
25
 
26
26
  const targetDir = join(hooksDir, entry.name);
27
- if (existsSync(targetDir)) continue; // Never overwrite user hooks
27
+ if (pathExists(targetDir)) continue; // Never overwrite user hooks
28
28
 
29
29
  try {
30
30
  // Copy template directory
@@ -32,7 +32,7 @@ export function installTemplates(): void {
32
32
 
33
33
  // Make script executable
34
34
  const manifestPath = join(targetDir, 'hook.json');
35
- if (existsSync(manifestPath)) {
35
+ if (pathExists(manifestPath)) {
36
36
  const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
37
37
  if (manifest.script) {
38
38
  chmodSync(join(targetDir, manifest.script), 0o755);