vellum 0.2.1 → 0.2.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 (361) hide show
  1. package/README.md +15 -2
  2. package/bun.lock +71 -100
  3. package/package.json +5 -3
  4. package/scripts/capture-x-graphql.ts +562 -0
  5. package/scripts/ipc/check-swift-decoder-drift.ts +2 -1
  6. package/scripts/test.sh +5 -0
  7. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +133 -34
  8. package/src/__tests__/account-registry.test.ts +2 -1
  9. package/src/__tests__/agent-heartbeat-service.test.ts +250 -0
  10. package/src/__tests__/asset-materialize-tool.test.ts +16 -15
  11. package/src/__tests__/asset-search-tool.test.ts +23 -22
  12. package/src/__tests__/attachments-store.test.ts +56 -127
  13. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +5 -4
  14. package/src/__tests__/browser-skill-endstate.test.ts +4 -3
  15. package/src/__tests__/call-bridge.test.ts +385 -0
  16. package/src/__tests__/call-constants.test.ts +40 -0
  17. package/src/__tests__/call-orchestrator.test.ts +130 -4
  18. package/src/__tests__/call-recovery.test.ts +518 -0
  19. package/src/__tests__/call-routes-http.test.ts +459 -0
  20. package/src/__tests__/call-state-machine.test.ts +143 -0
  21. package/src/__tests__/call-store.test.ts +216 -1
  22. package/src/__tests__/cli-discover.test.ts +1 -1
  23. package/src/__tests__/commit-message-enrichment-service.test.ts +148 -7
  24. package/src/__tests__/compaction.benchmark.test.ts +176 -0
  25. package/src/__tests__/computer-use-tools.test.ts +250 -0
  26. package/src/__tests__/config-schema.test.ts +305 -3
  27. package/src/__tests__/conflict-store.test.ts +2 -1
  28. package/src/__tests__/contacts-tools.test.ts +331 -0
  29. package/src/__tests__/conversation-store.test.ts +30 -32
  30. package/src/__tests__/credential-security-invariants.test.ts +4 -0
  31. package/src/__tests__/date-context.test.ts +373 -0
  32. package/src/__tests__/db-schedule-syntax-migration.test.ts +129 -0
  33. package/src/__tests__/fixtures/media-reuse-fixtures.ts +3 -3
  34. package/src/__tests__/followup-tools.test.ts +303 -0
  35. package/src/__tests__/handlers-twilio-config.test.ts +221 -0
  36. package/src/__tests__/handlers-twitter-config.test.ts +718 -0
  37. package/src/__tests__/intent-routing.test.ts +64 -57
  38. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +237 -0
  39. package/src/__tests__/ipc-snapshot.test.ts +71 -28
  40. package/src/__tests__/llm-usage-store.test.ts +3 -8
  41. package/src/__tests__/media-generate-image.test.ts +1 -1
  42. package/src/__tests__/media-reuse-story.e2e.test.ts +7 -7
  43. package/src/__tests__/memory-regressions.test.ts +100 -2
  44. package/src/__tests__/memory-retrieval.benchmark.test.ts +430 -0
  45. package/src/__tests__/parallel-tool.benchmark.test.ts +294 -0
  46. package/src/__tests__/playbook-tools.test.ts +342 -0
  47. package/src/__tests__/profile-compiler.test.ts +2 -1
  48. package/src/__tests__/provider-commit-message-generator.test.ts +303 -0
  49. package/src/__tests__/provider-streaming.benchmark.test.ts +773 -0
  50. package/src/__tests__/recurrence-engine-rruleset.test.ts +78 -0
  51. package/src/__tests__/recurrence-engine.test.ts +69 -0
  52. package/src/__tests__/recurrence-types.test.ts +71 -0
  53. package/src/__tests__/registry.test.ts +5 -3
  54. package/src/__tests__/relay-server.test.ts +633 -0
  55. package/src/__tests__/reminder-store.test.ts +6 -3
  56. package/src/__tests__/reminder.test.ts +43 -77
  57. package/src/__tests__/run-orchestrator-assistant-events.test.ts +8 -4
  58. package/src/__tests__/run-orchestrator.test.ts +4 -4
  59. package/src/__tests__/runtime-attachment-metadata.test.ts +7 -6
  60. package/src/__tests__/runtime-runs-http.test.ts +4 -4
  61. package/src/__tests__/runtime-runs.test.ts +4 -4
  62. package/src/__tests__/schedule-store.test.ts +482 -0
  63. package/src/__tests__/schedule-tools.test.ts +700 -0
  64. package/src/__tests__/scheduler-recurrence.test.ts +329 -0
  65. package/src/__tests__/server-history-render.test.ts +14 -13
  66. package/src/__tests__/session-conflict-gate.test.ts +28 -25
  67. package/src/__tests__/session-error.test.ts +28 -0
  68. package/src/__tests__/session-init.benchmark.test.ts +462 -0
  69. package/src/__tests__/session-queue.test.ts +71 -48
  70. package/src/__tests__/session-runtime-assembly.test.ts +161 -0
  71. package/src/__tests__/session-surfaces-task-progress.test.ts +104 -0
  72. package/src/__tests__/signup-e2e.test.ts +2 -1
  73. package/src/__tests__/skill-projection.benchmark.test.ts +328 -0
  74. package/src/__tests__/skill-script-runner.test.ts +159 -0
  75. package/src/__tests__/speaker-identification.test.ts +52 -0
  76. package/src/__tests__/subagent-manager-notify.test.ts +42 -10
  77. package/src/__tests__/subagent-tools.test.ts +141 -41
  78. package/src/__tests__/task-compiler.test.ts +2 -1
  79. package/src/__tests__/task-runner.test.ts +2 -1
  80. package/src/__tests__/task-scheduler.test.ts +2 -1
  81. package/src/__tests__/task-tools.test.ts +49 -56
  82. package/src/__tests__/tool-audit-listener.test.ts +1 -0
  83. package/src/__tests__/tool-domain-event-publisher.test.ts +2 -0
  84. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +500 -0
  85. package/src/__tests__/tool-executor.test.ts +13 -17
  86. package/src/__tests__/turn-commit.test.ts +218 -3
  87. package/src/__tests__/twilio-provider.test.ts +143 -0
  88. package/src/__tests__/twilio-routes.test.ts +789 -0
  89. package/src/__tests__/twitter-auth-handler.test.ts +581 -0
  90. package/src/__tests__/view-image-tool.test.ts +217 -0
  91. package/src/__tests__/workspace-git-service.test.ts +186 -0
  92. package/src/__tests__/workspace-heartbeat-service.test.ts +13 -3
  93. package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
  94. package/src/bundler/app-bundler.ts +12 -8
  95. package/src/calls/__tests__/twilio-webhook-urls.test.ts +162 -0
  96. package/src/calls/call-bridge.ts +95 -0
  97. package/src/calls/call-constants.ts +43 -5
  98. package/src/calls/call-domain.ts +276 -0
  99. package/src/calls/call-orchestrator.ts +43 -17
  100. package/src/calls/call-recovery.ts +207 -0
  101. package/src/calls/call-state-machine.ts +68 -0
  102. package/src/calls/call-store.ts +192 -5
  103. package/src/calls/relay-server.ts +41 -4
  104. package/src/calls/speaker-identification.ts +213 -0
  105. package/src/calls/twilio-config.ts +8 -8
  106. package/src/calls/twilio-provider.ts +13 -9
  107. package/src/calls/twilio-routes.ts +90 -76
  108. package/src/calls/twilio-webhook-urls.ts +50 -0
  109. package/src/calls/types.ts +1 -1
  110. package/src/cli/config-commands.ts +334 -0
  111. package/src/cli/core-commands.ts +776 -0
  112. package/src/cli/doordash.ts +251 -1
  113. package/src/cli/ipc-client.ts +82 -0
  114. package/src/cli/map.ts +270 -0
  115. package/src/cli/twitter.ts +575 -0
  116. package/src/cli.ts +7 -5
  117. package/src/commands/__tests__/cc-command-registry.test.ts +319 -0
  118. package/src/commands/cc-command-registry.ts +209 -0
  119. package/src/config/bundled-skills/contacts/SKILL.md +39 -0
  120. package/src/config/bundled-skills/contacts/TOOLS.json +122 -0
  121. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +9 -0
  122. package/src/config/bundled-skills/contacts/tools/contact-search.ts +9 -0
  123. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +9 -0
  124. package/src/config/bundled-skills/document/SKILL.md +18 -0
  125. package/src/config/bundled-skills/document/TOOLS.json +53 -0
  126. package/src/config/bundled-skills/document/tools/document-create.ts +9 -0
  127. package/src/config/bundled-skills/document/tools/document-update.ts +9 -0
  128. package/src/config/bundled-skills/doordash/SKILL.md +82 -23
  129. package/src/config/bundled-skills/followups/SKILL.md +32 -0
  130. package/src/config/bundled-skills/followups/TOOLS.json +100 -0
  131. package/src/config/bundled-skills/followups/tools/followup-create.ts +9 -0
  132. package/src/config/bundled-skills/followups/tools/followup-list.ts +9 -0
  133. package/src/config/bundled-skills/followups/tools/followup-resolve.ts +9 -0
  134. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -23
  135. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -1
  136. package/src/config/bundled-skills/playbooks/SKILL.md +31 -0
  137. package/src/config/bundled-skills/playbooks/TOOLS.json +126 -0
  138. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +9 -0
  139. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +9 -0
  140. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +9 -0
  141. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +9 -0
  142. package/src/config/bundled-skills/reminder/SKILL.md +20 -0
  143. package/src/config/bundled-skills/reminder/TOOLS.json +67 -0
  144. package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +9 -0
  145. package/src/config/bundled-skills/reminder/tools/reminder-create.ts +9 -0
  146. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +9 -0
  147. package/src/config/bundled-skills/schedule/SKILL.md +74 -0
  148. package/src/config/bundled-skills/schedule/TOOLS.json +135 -0
  149. package/src/config/bundled-skills/schedule/tools/schedule-create.ts +9 -0
  150. package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +9 -0
  151. package/src/config/bundled-skills/schedule/tools/schedule-list.ts +9 -0
  152. package/src/config/bundled-skills/schedule/tools/schedule-update.ts +9 -0
  153. package/src/config/bundled-skills/subagent/SKILL.md +25 -0
  154. package/src/config/bundled-skills/subagent/TOOLS.json +107 -0
  155. package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +9 -0
  156. package/src/config/bundled-skills/subagent/tools/subagent-message.ts +9 -0
  157. package/src/config/bundled-skills/subagent/tools/subagent-read.ts +9 -0
  158. package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +9 -0
  159. package/src/config/bundled-skills/subagent/tools/subagent-status.ts +9 -0
  160. package/src/config/bundled-skills/tasks/SKILL.md +28 -0
  161. package/src/config/bundled-skills/tasks/TOOLS.json +256 -0
  162. package/src/config/bundled-skills/tasks/tools/task-delete.ts +9 -0
  163. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +9 -0
  164. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +9 -0
  165. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +9 -0
  166. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +9 -0
  167. package/src/config/bundled-skills/tasks/tools/task-list.ts +9 -0
  168. package/src/config/bundled-skills/tasks/tools/task-run.ts +9 -0
  169. package/src/config/bundled-skills/tasks/tools/task-save.ts +9 -0
  170. package/src/config/bundled-skills/twitter/SKILL.md +134 -0
  171. package/src/config/bundled-skills/watcher/SKILL.md +27 -0
  172. package/src/config/bundled-skills/watcher/TOOLS.json +147 -0
  173. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +9 -0
  174. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +9 -0
  175. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +9 -0
  176. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +9 -0
  177. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +9 -0
  178. package/src/config/defaults.ts +34 -0
  179. package/src/config/loader.ts +4 -1
  180. package/src/config/schema.ts +165 -1
  181. package/src/config/system-prompt.ts +61 -16
  182. package/src/config/templates/IDENTITY.md +7 -0
  183. package/src/config/types.ts +4 -0
  184. package/src/config/vellum-skills/telegram-setup/SKILL.md +1 -5
  185. package/src/contacts/contact-store.ts +4 -4
  186. package/src/daemon/assistant-attachments.ts +10 -0
  187. package/src/daemon/classifier.ts +3 -1
  188. package/src/daemon/computer-use-session.ts +3 -1
  189. package/src/daemon/date-context.ts +136 -0
  190. package/src/daemon/handlers/apps.ts +16 -1
  191. package/src/daemon/handlers/browser.ts +54 -0
  192. package/src/daemon/handlers/computer-use.ts +7 -1
  193. package/src/daemon/handlers/config.ts +205 -5
  194. package/src/daemon/handlers/diagnostics.ts +5 -1
  195. package/src/daemon/handlers/documents.ts +18 -29
  196. package/src/daemon/handlers/home-base.ts +5 -1
  197. package/src/daemon/handlers/index.ts +40 -277
  198. package/src/daemon/handlers/misc.ts +9 -1
  199. package/src/daemon/handlers/publish.ts +6 -1
  200. package/src/daemon/handlers/sessions.ts +65 -12
  201. package/src/daemon/handlers/shared.ts +36 -1
  202. package/src/daemon/handlers/signing.ts +37 -0
  203. package/src/daemon/handlers/skills.ts +20 -6
  204. package/src/daemon/handlers/subagents.ts +8 -3
  205. package/src/daemon/handlers/twitter-auth.ts +169 -0
  206. package/src/daemon/handlers/work-items.ts +384 -68
  207. package/src/daemon/ipc-contract-inventory.json +32 -4
  208. package/src/daemon/ipc-contract.ts +156 -37
  209. package/src/daemon/ipc-protocol.ts +7 -2
  210. package/src/daemon/lifecycle.ts +21 -0
  211. package/src/daemon/main.ts +10 -4
  212. package/src/daemon/ride-shotgun-handler.ts +75 -10
  213. package/src/daemon/server.ts +143 -26
  214. package/src/daemon/session-agent-loop.ts +922 -0
  215. package/src/daemon/session-attachments.ts +28 -5
  216. package/src/daemon/session-conflict-gate.ts +18 -109
  217. package/src/daemon/session-error.ts +24 -3
  218. package/src/daemon/session-lifecycle.ts +147 -0
  219. package/src/daemon/session-media-retry.ts +147 -0
  220. package/src/daemon/session-messaging.ts +145 -0
  221. package/src/daemon/session-notifiers.ts +164 -0
  222. package/src/daemon/session-process.ts +2 -2
  223. package/src/daemon/session-queue-manager.ts +1 -0
  224. package/src/daemon/session-runtime-assembly.ts +52 -0
  225. package/src/daemon/session-skill-tools.ts +124 -5
  226. package/src/daemon/session-slash.ts +3 -0
  227. package/src/daemon/session-surfaces.ts +77 -2
  228. package/src/daemon/session-tool-setup.ts +216 -2
  229. package/src/daemon/session-usage.ts +0 -2
  230. package/src/daemon/session.ts +114 -1404
  231. package/src/daemon/video-thumbnail.ts +60 -0
  232. package/src/doordash/client.ts +121 -27
  233. package/src/doordash/queries.ts +1 -2
  234. package/src/export/formatter.ts +3 -1
  235. package/src/followups/followup-store.ts +4 -2
  236. package/src/followups/types.ts +6 -0
  237. package/src/hooks/templates.ts +1 -1
  238. package/src/index.ts +32 -1153
  239. package/src/memory/attachments-store.ts +28 -83
  240. package/src/memory/channel-delivery-store.ts +7 -21
  241. package/src/memory/clarification-resolver.ts +6 -5
  242. package/src/memory/conflict-intent.ts +114 -0
  243. package/src/memory/contradiction-checker.ts +3 -2
  244. package/src/memory/conversation-key-store.ts +10 -29
  245. package/src/memory/conversation-store.ts +2 -1
  246. package/src/memory/db.ts +96 -2
  247. package/src/memory/entity-extractor.ts +6 -3
  248. package/src/memory/items-extractor.ts +5 -4
  249. package/src/memory/job-handlers/conflict.ts +23 -1
  250. package/src/memory/jobs-store.ts +3 -2
  251. package/src/memory/llm-usage-store.ts +1 -2
  252. package/src/memory/runs-store.ts +1 -2
  253. package/src/memory/schema.ts +23 -2
  254. package/src/messaging/style-analyzer.ts +3 -2
  255. package/src/messaging/thread-summarizer.ts +8 -12
  256. package/src/messaging/triage-engine.ts +4 -2
  257. package/src/providers/openrouter/client.ts +20 -0
  258. package/src/providers/registry.ts +8 -0
  259. package/src/runtime/gateway-client.ts +36 -0
  260. package/src/runtime/http-server.ts +166 -22
  261. package/src/runtime/routes/attachment-routes.ts +2 -3
  262. package/src/runtime/routes/call-routes.ts +140 -0
  263. package/src/runtime/routes/channel-routes.ts +125 -88
  264. package/src/runtime/routes/conversation-routes.ts +5 -5
  265. package/src/runtime/routes/run-routes.ts +2 -2
  266. package/src/runtime/run-orchestrator.ts +9 -3
  267. package/src/schedule/recurrence-engine.ts +138 -0
  268. package/src/schedule/recurrence-types.ts +67 -0
  269. package/src/schedule/schedule-store.ts +102 -57
  270. package/src/schedule/scheduler.ts +9 -6
  271. package/src/security/oauth2.ts +29 -4
  272. package/src/security/secret-allowlist.ts +46 -0
  273. package/src/skills/clawhub.ts +1 -1
  274. package/src/subagent/manager.ts +40 -8
  275. package/src/swarm/backend-claude-code.ts +64 -9
  276. package/src/swarm/worker-prompts.ts +2 -1
  277. package/src/tasks/SPEC.md +34 -28
  278. package/src/tasks/ephemeral-permissions.ts +16 -7
  279. package/src/tasks/task-compiler.ts +5 -4
  280. package/src/tasks/task-runner.ts +10 -5
  281. package/src/tasks/task-scheduler.ts +1 -1
  282. package/src/tasks/tool-sanitizer.ts +36 -0
  283. package/src/tools/assets/search.ts +4 -4
  284. package/src/tools/browser/api-map.ts +293 -0
  285. package/src/tools/browser/auto-navigate.ts +270 -0
  286. package/src/tools/browser/browser-execution.ts +2 -1
  287. package/src/tools/browser/browser-manager.ts +2 -2
  288. package/src/tools/browser/network-recorder.ts +5 -4
  289. package/src/tools/browser/x-auto-navigate.ts +207 -0
  290. package/src/tools/calls/call-end.ts +17 -67
  291. package/src/tools/calls/call-start.ts +24 -85
  292. package/src/tools/calls/call-status.ts +35 -51
  293. package/src/tools/claude-code/claude-code.ts +207 -11
  294. package/src/tools/contacts/contact-merge.ts +46 -78
  295. package/src/tools/contacts/contact-search.ts +35 -79
  296. package/src/tools/contacts/contact-upsert.ts +35 -108
  297. package/src/tools/credentials/vault.ts +20 -4
  298. package/src/tools/document/document-tool.ts +71 -144
  299. package/src/tools/executor.ts +129 -10
  300. package/src/tools/followups/followup_create.ts +46 -88
  301. package/src/tools/followups/followup_list.ts +34 -74
  302. package/src/tools/followups/followup_resolve.ts +31 -66
  303. package/src/tools/host-terminal/cli-discover.ts +2 -1
  304. package/src/tools/host-terminal/host-shell.ts +10 -0
  305. package/src/tools/memory/handlers.ts +5 -4
  306. package/src/tools/network/__tests__/web-search.test.ts +427 -0
  307. package/src/tools/network/script-proxy/__tests__/logging.test.ts +248 -0
  308. package/src/tools/network/script-proxy/__tests__/policy.test.ts +234 -0
  309. package/src/tools/network/script-proxy/__tests__/router.test.ts +76 -0
  310. package/src/tools/network/web-fetch.ts +18 -6
  311. package/src/tools/playbooks/index.ts +4 -5
  312. package/src/tools/playbooks/playbook-create.ts +3 -47
  313. package/src/tools/playbooks/playbook-delete.ts +1 -25
  314. package/src/tools/playbooks/playbook-list.ts +1 -28
  315. package/src/tools/playbooks/playbook-update.ts +3 -51
  316. package/src/tools/reminder/reminder.ts +5 -78
  317. package/src/tools/schedule/create.ts +69 -74
  318. package/src/tools/schedule/delete.ts +21 -47
  319. package/src/tools/schedule/list.ts +55 -74
  320. package/src/tools/schedule/update.ts +77 -84
  321. package/src/tools/subagent/abort.ts +29 -58
  322. package/src/tools/subagent/message.ts +30 -63
  323. package/src/tools/subagent/read.ts +53 -84
  324. package/src/tools/subagent/spawn.ts +43 -82
  325. package/src/tools/subagent/status.ts +42 -71
  326. package/src/tools/swarm/delegate.ts +2 -1
  327. package/src/tools/tasks/index.ts +8 -8
  328. package/src/tools/tasks/task-delete.ts +60 -88
  329. package/src/tools/tasks/task-list.ts +31 -52
  330. package/src/tools/tasks/task-run.ts +72 -108
  331. package/src/tools/tasks/task-save.ts +33 -65
  332. package/src/tools/tasks/work-item-enqueue.ts +183 -215
  333. package/src/tools/tasks/work-item-list.ts +33 -63
  334. package/src/tools/tasks/work-item-remove.ts +45 -97
  335. package/src/tools/tasks/work-item-update.ts +91 -163
  336. package/src/tools/terminal/backends/native.ts +3 -1
  337. package/src/tools/tool-manifest.ts +0 -62
  338. package/src/tools/types.ts +6 -0
  339. package/src/tools/ui-surface/definitions.ts +3 -1
  340. package/src/tools/watch/screen-watch.ts +3 -1
  341. package/src/tools/watcher/create.ts +52 -98
  342. package/src/tools/watcher/delete.ts +20 -46
  343. package/src/tools/watcher/digest.ts +36 -70
  344. package/src/tools/watcher/list.ts +49 -79
  345. package/src/tools/watcher/update.ts +45 -91
  346. package/src/twitter/client.ts +690 -0
  347. package/src/twitter/session.ts +91 -0
  348. package/src/usage/types.ts +0 -1
  349. package/src/util/truncate.ts +6 -0
  350. package/src/watcher/providers/slack.ts +2 -1
  351. package/src/watcher/watcher-store.ts +3 -2
  352. package/src/work-items/work-item-store.ts +27 -2
  353. package/src/workspace/commit-message-enrichment-service.ts +31 -7
  354. package/src/workspace/git-service.ts +87 -22
  355. package/src/workspace/provider-commit-message-generator.ts +269 -0
  356. package/src/workspace/turn-commit.ts +62 -3
  357. package/src/tools/contacts/index.ts +0 -4
  358. package/src/tools/document/index.ts +0 -5
  359. package/src/tools/followups/index.ts +0 -3
  360. package/src/tools/subagent/index.ts +0 -5
  361. /package/src/__tests__/{memory-context-benchmark.test.ts → memory-context-benchmark.benchmark.test.ts} +0 -0
@@ -45,6 +45,8 @@ export interface UserMessageAttachment {
45
45
  extractedText?: string;
46
46
  /** Original file size in bytes. Present when data was omitted from history_response to reduce payload size. */
47
47
  sizeBytes?: number;
48
+ /** Base64-encoded JPEG thumbnail. Generated server-side for video attachments. */
49
+ thumbnailData?: string;
48
50
  }
49
51
 
50
52
  export interface ConfirmationResponse {
@@ -210,6 +212,9 @@ export interface RideShotgunStart {
210
212
  intervalSeconds: number;
211
213
  mode?: 'observe' | 'learn';
212
214
  targetDomain?: string;
215
+ /** Domain to auto-navigate (may differ from targetDomain, e.g. open.spotify.com vs spotify.com). */
216
+ navigateDomain?: string;
217
+ autoNavigate?: boolean;
213
218
  }
214
219
 
215
220
  export interface RideShotgunStop {
@@ -428,16 +433,18 @@ export interface OpenBundleRequest {
428
433
  export interface SignBundlePayloadResponse {
429
434
  type: 'sign_bundle_payload_response';
430
435
  requestId: string;
431
- signature: string;
432
- keyId: string;
433
- publicKey: string;
436
+ signature?: string;
437
+ keyId?: string;
438
+ publicKey?: string;
439
+ error?: string;
434
440
  }
435
441
 
436
442
  export interface GetSigningIdentityResponse {
437
443
  type: 'get_signing_identity_response';
438
444
  requestId: string;
439
- keyId: string;
440
- publicKey: string;
445
+ keyId?: string;
446
+ publicKey?: string;
447
+ error?: string;
441
448
  }
442
449
 
443
450
  export interface GalleryListRequest {
@@ -465,6 +472,12 @@ export interface SlackWebhookConfigRequest {
465
472
  webhookUrl?: string;
466
473
  }
467
474
 
475
+ export interface TwilioWebhookConfigRequest {
476
+ type: 'twilio_webhook_config';
477
+ action: 'get' | 'set';
478
+ webhookBaseUrl?: string;
479
+ }
480
+
468
481
  export interface VercelApiConfigRequest {
469
482
  type: 'vercel_api_config';
470
483
  action: 'get' | 'set' | 'delete';
@@ -478,6 +491,48 @@ export interface VercelApiConfigResponse {
478
491
  error?: string;
479
492
  }
480
493
 
494
+ export interface TwitterIntegrationConfigRequest {
495
+ type: 'twitter_integration_config';
496
+ action: 'get' | 'set_mode' | 'set_local_client' | 'clear_local_client' | 'disconnect';
497
+ mode?: 'local_byo' | 'managed';
498
+ clientId?: string;
499
+ clientSecret?: string;
500
+ }
501
+
502
+ export interface TwitterIntegrationConfigResponse {
503
+ type: 'twitter_integration_config_response';
504
+ success: boolean;
505
+ mode?: 'local_byo' | 'managed';
506
+ managedAvailable: boolean;
507
+ localClientConfigured: boolean;
508
+ connected: boolean;
509
+ accountInfo?: string;
510
+ error?: string;
511
+ }
512
+
513
+ export interface TwitterAuthStartRequest {
514
+ type: 'twitter_auth_start';
515
+ }
516
+
517
+ export interface TwitterAuthStatusRequest {
518
+ type: 'twitter_auth_status';
519
+ }
520
+
521
+ export interface TwitterAuthResult {
522
+ type: 'twitter_auth_result';
523
+ success: boolean;
524
+ accountInfo?: string;
525
+ error?: string;
526
+ }
527
+
528
+ export interface TwitterAuthStatusResponse {
529
+ type: 'twitter_auth_status_response';
530
+ connected: boolean;
531
+ accountInfo?: string;
532
+ mode?: 'local_byo' | 'managed';
533
+ error?: string;
534
+ }
535
+
481
536
  export interface LinkOpenRequest {
482
537
  type: 'link_open_request';
483
538
  url: string;
@@ -774,15 +829,6 @@ export interface WorkItemGetRequest {
774
829
  id: string;
775
830
  }
776
831
 
777
- export interface WorkItemCreateRequest {
778
- type: 'work_item_create';
779
- taskId: string;
780
- title?: string; // defaults to task title
781
- notes?: string;
782
- priorityTier?: number;
783
- sortIndex?: number;
784
- }
785
-
786
832
  export interface WorkItemUpdateRequest {
787
833
  type: 'work_item_update';
788
834
  id: string;
@@ -813,6 +859,22 @@ export interface WorkItemOutputRequest {
813
859
  id: string;
814
860
  }
815
861
 
862
+ export interface WorkItemPreflightRequest {
863
+ type: 'work_item_preflight';
864
+ id: string; // work item ID
865
+ }
866
+
867
+ export interface WorkItemApprovePermissionsRequest {
868
+ type: 'work_item_approve_permissions';
869
+ id: string;
870
+ approvedTools: string[]; // tools the user approved
871
+ }
872
+
873
+ export interface WorkItemCancelRequest {
874
+ type: 'work_item_cancel';
875
+ id: string;
876
+ }
877
+
816
878
  export type ClientMessage =
817
879
  | AuthMessage
818
880
  | UserMessage
@@ -879,7 +941,11 @@ export type ClientMessage =
879
941
  | ShareAppCloudRequest
880
942
  | ShareToSlackRequest
881
943
  | SlackWebhookConfigRequest
944
+ | TwilioWebhookConfigRequest
882
945
  | VercelApiConfigRequest
946
+ | TwitterIntegrationConfigRequest
947
+ | TwitterAuthStartRequest
948
+ | TwitterAuthStatusRequest
883
949
  | SessionsClearRequest
884
950
  | GalleryListRequest
885
951
  | GalleryInstallRequest
@@ -902,12 +968,14 @@ export type ClientMessage =
902
968
  | BrowserInteractiveMode
903
969
  | WorkItemsListRequest
904
970
  | WorkItemGetRequest
905
- | WorkItemCreateRequest
906
971
  | WorkItemUpdateRequest
907
972
  | WorkItemCompleteRequest
908
973
  | WorkItemDeleteRequest
909
974
  | WorkItemRunTaskRequest
910
975
  | WorkItemOutputRequest
976
+ | WorkItemPreflightRequest
977
+ | WorkItemApprovePermissionsRequest
978
+ | WorkItemCancelRequest
911
979
  | SubagentAbortRequest
912
980
  | SubagentStatusRequest
913
981
  | SubagentMessageRequest;
@@ -982,6 +1050,12 @@ export interface ToolUseStart {
982
1050
  export interface ToolOutputChunk {
983
1051
  type: 'tool_output_chunk';
984
1052
  chunk: string;
1053
+ sessionId?: string;
1054
+ subType?: 'tool_start' | 'tool_complete' | 'status';
1055
+ subToolName?: string;
1056
+ subToolInput?: string;
1057
+ subToolIsError?: boolean;
1058
+ subToolId?: string;
985
1059
  }
986
1060
 
987
1061
  export interface ToolInputDelta {
@@ -1088,6 +1162,7 @@ export interface PongMessage {
1088
1162
  export interface DaemonStatusMessage {
1089
1163
  type: 'daemon_status';
1090
1164
  httpPort?: number;
1165
+ version?: string;
1091
1166
  }
1092
1167
 
1093
1168
  export interface GenerationCancelled {
@@ -1146,6 +1221,13 @@ export interface HistoryResponse {
1146
1221
  contentOrder?: string[];
1147
1222
  /** UI surfaces (widgets) embedded in the message. */
1148
1223
  surfaces?: HistoryResponseSurface[];
1224
+ /** Present when this message is a subagent lifecycle notification (completed/failed/aborted). */
1225
+ subagentNotification?: {
1226
+ subagentId: string;
1227
+ label: string;
1228
+ status: 'completed' | 'failed' | 'aborted';
1229
+ error?: string;
1230
+ };
1149
1231
  }>;
1150
1232
  }
1151
1233
 
@@ -1422,6 +1504,8 @@ export interface SchedulesListResponse {
1422
1504
  id: string;
1423
1505
  name: string;
1424
1506
  enabled: boolean;
1507
+ syntax: string;
1508
+ expression: string;
1425
1509
  cronExpression: string;
1426
1510
  timezone: string | null;
1427
1511
  message: string;
@@ -1606,6 +1690,13 @@ export interface SlackWebhookConfigResponse {
1606
1690
  error?: string;
1607
1691
  }
1608
1692
 
1693
+ export interface TwilioWebhookConfigResponse {
1694
+ type: 'twilio_webhook_config_response';
1695
+ webhookBaseUrl: string;
1696
+ success: boolean;
1697
+ error?: string;
1698
+ }
1699
+
1609
1700
  export interface OpenUrl {
1610
1701
  type: 'open_url';
1611
1702
  url: string;
@@ -1637,6 +1728,12 @@ export interface WatcherEscalation {
1637
1728
  body: string;
1638
1729
  }
1639
1730
 
1731
+ export interface AgentHeartbeatAlert {
1732
+ type: 'agent_heartbeat_alert';
1733
+ title: string;
1734
+ body: string;
1735
+ }
1736
+
1640
1737
  export interface WatchStarted {
1641
1738
  type: 'watch_started';
1642
1739
  sessionId: string;
@@ -1892,26 +1989,6 @@ export interface WorkItemGetResponse {
1892
1989
  } | null;
1893
1990
  }
1894
1991
 
1895
- export interface WorkItemCreateResponse {
1896
- type: 'work_item_create_response';
1897
- item: {
1898
- id: string;
1899
- taskId: string;
1900
- title: string;
1901
- notes: string | null;
1902
- status: string;
1903
- priorityTier: number;
1904
- sortIndex: number | null;
1905
- lastRunId: string | null;
1906
- lastRunConversationId: string | null;
1907
- lastRunStatus: string | null;
1908
- sourceType: string | null;
1909
- sourceId: string | null;
1910
- createdAt: number;
1911
- updatedAt: number;
1912
- };
1913
- }
1914
-
1915
1992
  export interface WorkItemUpdateResponse {
1916
1993
  type: 'work_item_update_response';
1917
1994
  item: {
@@ -1966,6 +2043,33 @@ export interface WorkItemOutputResponse {
1966
2043
  };
1967
2044
  }
1968
2045
 
2046
+ export interface WorkItemPreflightResponse {
2047
+ type: 'work_item_preflight_response';
2048
+ id: string;
2049
+ success: boolean;
2050
+ error?: string;
2051
+ permissions?: {
2052
+ tool: string;
2053
+ description: string;
2054
+ riskLevel: 'low' | 'medium' | 'high';
2055
+ currentDecision: 'allow' | 'deny' | 'prompt';
2056
+ }[];
2057
+ }
2058
+
2059
+ export interface WorkItemApprovePermissionsResponse {
2060
+ type: 'work_item_approve_permissions_response';
2061
+ id: string;
2062
+ success: boolean;
2063
+ error?: string;
2064
+ }
2065
+
2066
+ export interface WorkItemCancelResponse {
2067
+ type: 'work_item_cancel_response';
2068
+ id: string;
2069
+ success: boolean;
2070
+ error?: string;
2071
+ }
2072
+
1969
2073
  /** Server push — tells the client to open/focus the tasks window. */
1970
2074
  export interface OpenTasksWindow {
1971
2075
  type: 'open_tasks_window';
@@ -1991,6 +2095,14 @@ export interface WorkItemStatusChanged {
1991
2095
  };
1992
2096
  }
1993
2097
 
2098
+ /** Server push — broadcast when a task run creates a conversation, so the client can show it as a chat thread. */
2099
+ export interface TaskRunThreadCreated {
2100
+ type: 'task_run_thread_created';
2101
+ conversationId: string;
2102
+ workItemId: string;
2103
+ title: string;
2104
+ }
2105
+
1994
2106
  export type ServerMessage =
1995
2107
  | AuthResult
1996
2108
  | UserMessageEcho
@@ -2045,6 +2157,7 @@ export type ServerMessage =
2045
2157
  | ScheduleComplete
2046
2158
  | WatcherNotification
2047
2159
  | WatcherEscalation
2160
+ | AgentHeartbeatAlert
2048
2161
  | WatchStarted
2049
2162
  | WatchCompleteRequest
2050
2163
  | TrustRulesListResponse
@@ -2067,7 +2180,11 @@ export type ServerMessage =
2067
2180
  | GalleryInstallResponse
2068
2181
  | ShareToSlackResponse
2069
2182
  | SlackWebhookConfigResponse
2183
+ | TwilioWebhookConfigResponse
2070
2184
  | VercelApiConfigResponse
2185
+ | TwitterIntegrationConfigResponse
2186
+ | TwitterAuthResult
2187
+ | TwitterAuthStatusResponse
2071
2188
  | OpenUrl
2072
2189
  | AppUpdatePreviewResponse
2073
2190
  | AppPreviewResponse
@@ -2089,12 +2206,15 @@ export type ServerMessage =
2089
2206
  | BrowserHandoffRequest
2090
2207
  | WorkItemsListResponse
2091
2208
  | WorkItemGetResponse
2092
- | WorkItemCreateResponse
2093
2209
  | WorkItemUpdateResponse
2094
2210
  | WorkItemDeleteResponse
2095
2211
  | WorkItemRunTaskResponse
2096
2212
  | WorkItemOutputResponse
2213
+ | WorkItemPreflightResponse
2214
+ | WorkItemApprovePermissionsResponse
2215
+ | WorkItemCancelResponse
2097
2216
  | WorkItemStatusChanged
2217
+ | TaskRunThreadCreated
2098
2218
  | TasksChanged
2099
2219
  | OpenTasksWindow
2100
2220
  | SubagentSpawned
@@ -2137,7 +2257,6 @@ export interface SubagentStatusRequest {
2137
2257
  type: 'subagent_status';
2138
2258
  /** If omitted, returns all subagents for the session. */
2139
2259
  subagentId?: string;
2140
- sessionId: string;
2141
2260
  }
2142
2261
 
2143
2262
  export interface SubagentMessageRequest {
@@ -2,6 +2,9 @@
2
2
  export * from './ipc-contract.js';
3
3
 
4
4
  import type { ClientMessage, ServerMessage } from './ipc-contract.js';
5
+ import { getLogger } from '../util/logger.js';
6
+
7
+ const log = getLogger('ipc-protocol');
5
8
 
6
9
  // === Serialization ===
7
10
 
@@ -43,8 +46,10 @@ export function createMessageParser(options?: { maxLineSize?: number }) {
43
46
  entry.rawByteLength = Buffer.byteLength(trimmed, 'utf8');
44
47
  }
45
48
  results.push(entry);
46
- } catch {
47
- // Skip malformed messages
49
+ } catch (err) {
50
+ // Log only the error name, not the message — JSON.parse errors embed
51
+ // fragments of the input which could contain sensitive data.
52
+ log.warn({ lineLength: trimmed.length, errorType: err instanceof Error ? err.name : 'unknown' }, 'Skipping malformed IPC message');
48
53
  }
49
54
  }
50
55
  }
@@ -44,7 +44,10 @@ import { RuntimeHttpServer } from '../runtime/http-server.js';
44
44
  import { getHookManager } from '../hooks/manager.js';
45
45
  import { installTemplates } from '../hooks/templates.js';
46
46
  import { HeartbeatService } from '../workspace/heartbeat-service.js';
47
+ import { AgentHeartbeatService } from '../agent-heartbeat/agent-heartbeat-service.js';
47
48
  import { getEnrichmentService } from '../workspace/commit-message-enrichment-service.js';
49
+ import { reconcileCallsOnStartup } from '../calls/call-recovery.js';
50
+ import { TwilioConversationRelayProvider } from '../calls/twilio-provider.js';
48
51
 
49
52
  const log = getLogger('lifecycle');
50
53
 
@@ -292,6 +295,15 @@ export async function runDaemon(): Promise<void> {
292
295
  log.info({ count: orphanedRunning.length }, 'Recovered orphaned running work items');
293
296
  }
294
297
 
298
+ // Reconcile in-flight calls that were left in non-terminal states
299
+ // after a daemon crash or restart.
300
+ try {
301
+ const twilioProvider = new TwilioConversationRelayProvider();
302
+ await reconcileCallsOnStartup(twilioProvider, log);
303
+ } catch (err) {
304
+ log.warn({ err }, 'Call recovery failed — continuing startup');
305
+ }
306
+
295
307
  log.info('Daemon startup: loading config');
296
308
  const config = loadConfig();
297
309
 
@@ -444,6 +456,14 @@ export async function runDaemon(): Promise<void> {
444
456
  const heartbeat = new HeartbeatService();
445
457
  heartbeat.start();
446
458
 
459
+ // Start model-driven heartbeat service (opt-in via config).
460
+ const agentHeartbeat = new AgentHeartbeatService({
461
+ processMessage: (conversationId, content) =>
462
+ server.processMessage(conversationId, content),
463
+ alerter: (alert) => server.broadcast(alert),
464
+ });
465
+ agentHeartbeat.start();
466
+
447
467
  // Graceful shutdown
448
468
  let shuttingDown = false;
449
469
  const shutdown = async () => {
@@ -464,6 +484,7 @@ export async function runDaemon(): Promise<void> {
464
484
  forceTimer.unref();
465
485
 
466
486
  await heartbeat.stop();
487
+ await agentHeartbeat.stop();
467
488
 
468
489
  try {
469
490
  await hookManager.trigger('daemon-stop', { pid: process.pid });
@@ -1,14 +1,20 @@
1
1
  #!/usr/bin/env bun
2
2
  import * as Sentry from '@sentry/node';
3
3
  import { runDaemon } from './lifecycle.js';
4
+ import { getLogger } from '../util/logger.js';
4
5
 
5
- // Use console.error instead of the structured logger here because
6
- // startDaemon() captures the child process's stderr to surface error
7
- // details to the parent process. The structured logger writes to a file
8
- // by default, so these messages would be lost from stderr.
9
6
  runDaemon().catch(async (err) => {
10
7
  Sentry.captureException(err);
11
8
  await Sentry.flush(2000);
9
+ // Try structured log first; fall back to console.error because
10
+ // startDaemon() captures the child process's stderr to surface error
11
+ // details to the parent process.
12
+ try {
13
+ const log = getLogger('daemon-main');
14
+ log.fatal({ err }, 'Failed to start daemon');
15
+ } catch {
16
+ // Logger may not be initialized yet
17
+ }
12
18
  console.error('Failed to start daemon:', err);
13
19
  console.error('Troubleshooting: check if another daemon is already running, verify ~/.vellum/ permissions, and review logs at ~/.vellum/workspace/data/logs/');
14
20
  process.exit(1);
@@ -15,12 +15,30 @@ import { getLogger } from '../util/logger.js';
15
15
  import { NetworkRecorder } from '../tools/browser/network-recorder.js';
16
16
  import { saveRecording } from '../tools/browser/recording-store.js';
17
17
  import type { SessionRecording } from '../tools/browser/network-recording-types.js';
18
+ import { navigateXPages } from '../tools/browser/x-auto-navigate.js';
19
+ import { autoNavigate } from '../tools/browser/auto-navigate.js';
18
20
 
19
21
  const log = getLogger('ride-shotgun-handler');
20
22
 
21
23
  /** Active network recorders keyed by watchId. */
22
24
  const activeRecorders = new Map<string, NetworkRecorder>();
23
25
 
26
+ /** Return domain-specific URL patterns that indicate a successful login. */
27
+ function getLoginSignals(targetDomain?: string): string[] {
28
+ if (targetDomain === 'x.com' || targetDomain === 'twitter.com') {
29
+ return [
30
+ '/i/api/graphql/', // any authenticated GraphQL call
31
+ '/1.1/account/settings', // legacy API session check
32
+ ];
33
+ }
34
+ // DoorDash and general fallback
35
+ return [
36
+ '/graphql/postLoginQuery',
37
+ '/graphql/homePageFacetFeed',
38
+ '/graphql/getConsumerOrdersWithDetails',
39
+ ];
40
+ }
41
+
24
42
  /**
25
43
  * Complete a session — finalize recording (if learn mode), generate summary, fire notifier.
26
44
  * Shared by both the duration timeout and the early-stop handler.
@@ -106,11 +124,7 @@ export async function handleRideShotgunStart(
106
124
  }
107
125
  try {
108
126
  const recorder = new NetworkRecorder(targetDomain);
109
- recorder.loginSignals = [
110
- '/graphql/postLoginQuery',
111
- '/graphql/homePageFacetFeed',
112
- '/graphql/getConsumerOrdersWithDetails',
113
- ];
127
+ recorder.loginSignals = getLoginSignals(targetDomain);
114
128
  await recorder.startDirect();
115
129
  // If session completed while we were connecting, stop immediately to avoid leak
116
130
  if (session.status !== 'active') {
@@ -118,13 +132,64 @@ export async function handleRideShotgunStart(
118
132
  await recorder.stop();
119
133
  return;
120
134
  }
121
- // Auto-stop when login is detected
122
- recorder.onLoginDetected = () => {
123
- log.info({ watchId }, 'Login detected — auto-stopping learn session');
124
- completeSession(session);
125
- };
126
135
  activeRecorders.set(watchId, recorder);
127
136
  log.info({ watchId, targetDomain, attempt }, 'Network recording started for learn session');
137
+
138
+ // For x.com, auto-navigate Chrome through key pages to capture the full API surface.
139
+ // Skip login detection — auto-navigation will complete the session when done.
140
+ if (targetDomain === 'x.com' || targetDomain === 'twitter.com') {
141
+ // Don't set onLoginDetected — it would kill the session after the first
142
+ // GraphQL call (5s grace), before auto-navigation finishes.
143
+ const abortSignal = { aborted: false };
144
+ const checkInterval = setInterval(() => {
145
+ if (session.status !== 'active') {
146
+ abortSignal.aborted = true;
147
+ clearInterval(checkInterval);
148
+ }
149
+ }, 1000);
150
+ navigateXPages(abortSignal).then(completed => {
151
+ clearInterval(checkInterval);
152
+ log.info({ watchId, completedSteps: completed.length }, 'X auto-navigation finished');
153
+ if (session.status === 'active') {
154
+ completeSession(session);
155
+ }
156
+ }).catch(err => {
157
+ clearInterval(checkInterval);
158
+ log.warn({ err, watchId }, 'X auto-navigation failed');
159
+ if (session.status === 'active') {
160
+ completeSession(session);
161
+ }
162
+ });
163
+ } else if (msg.autoNavigate && targetDomain) {
164
+ const navDomain = msg.navigateDomain ?? targetDomain;
165
+ const abortSignal = { aborted: false };
166
+ const checkInterval = setInterval(() => {
167
+ if (session.status !== 'active') {
168
+ abortSignal.aborted = true;
169
+ clearInterval(checkInterval);
170
+ }
171
+ }, 1000);
172
+ autoNavigate(navDomain, abortSignal).then(visited => {
173
+ clearInterval(checkInterval);
174
+ log.info({ watchId, visitedPages: visited.length }, 'Generic auto-navigation finished');
175
+ if (session.status === 'active') {
176
+ completeSession(session);
177
+ }
178
+ }).catch(err => {
179
+ clearInterval(checkInterval);
180
+ log.warn({ err, watchId }, 'Generic auto-navigation failed');
181
+ if (session.status === 'active') {
182
+ completeSession(session);
183
+ }
184
+ });
185
+ } else {
186
+ // No targetDomain: use login detection as before
187
+ recorder.onLoginDetected = () => {
188
+ log.info({ watchId }, 'Login detected — auto-stopping learn session');
189
+ completeSession(session);
190
+ };
191
+ }
192
+
128
193
  return;
129
194
  } catch (err) {
130
195
  if (attempt < 9) {