vellum 0.2.1 → 0.2.2

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 (349) hide show
  1. package/README.md +15 -2
  2. package/bun.lock +5 -2
  3. package/package.json +4 -2
  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 +299 -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-twitter-config.test.ts +718 -0
  36. package/src/__tests__/intent-routing.test.ts +64 -57
  37. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +237 -0
  38. package/src/__tests__/ipc-snapshot.test.ts +62 -28
  39. package/src/__tests__/llm-usage-store.test.ts +3 -8
  40. package/src/__tests__/media-generate-image.test.ts +1 -1
  41. package/src/__tests__/media-reuse-story.e2e.test.ts +7 -7
  42. package/src/__tests__/memory-retrieval.benchmark.test.ts +430 -0
  43. package/src/__tests__/parallel-tool.benchmark.test.ts +294 -0
  44. package/src/__tests__/playbook-tools.test.ts +342 -0
  45. package/src/__tests__/profile-compiler.test.ts +2 -1
  46. package/src/__tests__/provider-streaming.benchmark.test.ts +773 -0
  47. package/src/__tests__/recurrence-engine-rruleset.test.ts +78 -0
  48. package/src/__tests__/recurrence-engine.test.ts +69 -0
  49. package/src/__tests__/recurrence-types.test.ts +71 -0
  50. package/src/__tests__/registry.test.ts +5 -3
  51. package/src/__tests__/relay-server.test.ts +633 -0
  52. package/src/__tests__/reminder-store.test.ts +6 -3
  53. package/src/__tests__/reminder.test.ts +43 -77
  54. package/src/__tests__/run-orchestrator-assistant-events.test.ts +8 -4
  55. package/src/__tests__/run-orchestrator.test.ts +4 -4
  56. package/src/__tests__/runtime-attachment-metadata.test.ts +7 -6
  57. package/src/__tests__/runtime-runs-http.test.ts +4 -4
  58. package/src/__tests__/runtime-runs.test.ts +4 -4
  59. package/src/__tests__/schedule-store.test.ts +482 -0
  60. package/src/__tests__/schedule-tools.test.ts +700 -0
  61. package/src/__tests__/scheduler-recurrence.test.ts +329 -0
  62. package/src/__tests__/server-history-render.test.ts +14 -13
  63. package/src/__tests__/session-error.test.ts +28 -0
  64. package/src/__tests__/session-init.benchmark.test.ts +462 -0
  65. package/src/__tests__/session-queue.test.ts +71 -48
  66. package/src/__tests__/session-runtime-assembly.test.ts +161 -0
  67. package/src/__tests__/session-surfaces-task-progress.test.ts +104 -0
  68. package/src/__tests__/signup-e2e.test.ts +2 -1
  69. package/src/__tests__/skill-projection.benchmark.test.ts +328 -0
  70. package/src/__tests__/skill-script-runner.test.ts +159 -0
  71. package/src/__tests__/speaker-identification.test.ts +52 -0
  72. package/src/__tests__/subagent-manager-notify.test.ts +42 -10
  73. package/src/__tests__/subagent-tools.test.ts +141 -41
  74. package/src/__tests__/task-compiler.test.ts +2 -1
  75. package/src/__tests__/task-runner.test.ts +2 -1
  76. package/src/__tests__/task-scheduler.test.ts +2 -1
  77. package/src/__tests__/task-tools.test.ts +49 -56
  78. package/src/__tests__/tool-audit-listener.test.ts +1 -0
  79. package/src/__tests__/tool-domain-event-publisher.test.ts +2 -0
  80. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +500 -0
  81. package/src/__tests__/tool-executor.test.ts +13 -17
  82. package/src/__tests__/turn-commit.test.ts +218 -3
  83. package/src/__tests__/twilio-provider.test.ts +143 -0
  84. package/src/__tests__/twilio-routes.test.ts +789 -0
  85. package/src/__tests__/twitter-auth-handler.test.ts +581 -0
  86. package/src/__tests__/view-image-tool.test.ts +217 -0
  87. package/src/__tests__/workspace-git-service.test.ts +186 -0
  88. package/src/__tests__/workspace-heartbeat-service.test.ts +13 -3
  89. package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
  90. package/src/bundler/app-bundler.ts +12 -8
  91. package/src/calls/call-bridge.ts +95 -0
  92. package/src/calls/call-constants.ts +43 -5
  93. package/src/calls/call-domain.ts +276 -0
  94. package/src/calls/call-orchestrator.ts +43 -17
  95. package/src/calls/call-recovery.ts +207 -0
  96. package/src/calls/call-state-machine.ts +68 -0
  97. package/src/calls/call-store.ts +192 -5
  98. package/src/calls/relay-server.ts +41 -4
  99. package/src/calls/speaker-identification.ts +213 -0
  100. package/src/calls/twilio-provider.ts +10 -6
  101. package/src/calls/twilio-routes.ts +90 -76
  102. package/src/calls/types.ts +1 -1
  103. package/src/cli/config-commands.ts +334 -0
  104. package/src/cli/core-commands.ts +776 -0
  105. package/src/cli/doordash.ts +251 -1
  106. package/src/cli/ipc-client.ts +82 -0
  107. package/src/cli/map.ts +246 -0
  108. package/src/cli/twitter.ts +575 -0
  109. package/src/cli.ts +7 -5
  110. package/src/commands/__tests__/cc-command-registry.test.ts +319 -0
  111. package/src/commands/cc-command-registry.ts +209 -0
  112. package/src/config/bundled-skills/contacts/SKILL.md +39 -0
  113. package/src/config/bundled-skills/contacts/TOOLS.json +122 -0
  114. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +9 -0
  115. package/src/config/bundled-skills/contacts/tools/contact-search.ts +9 -0
  116. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +9 -0
  117. package/src/config/bundled-skills/document/SKILL.md +18 -0
  118. package/src/config/bundled-skills/document/TOOLS.json +53 -0
  119. package/src/config/bundled-skills/document/tools/document-create.ts +9 -0
  120. package/src/config/bundled-skills/document/tools/document-update.ts +9 -0
  121. package/src/config/bundled-skills/doordash/SKILL.md +82 -23
  122. package/src/config/bundled-skills/followups/SKILL.md +32 -0
  123. package/src/config/bundled-skills/followups/TOOLS.json +100 -0
  124. package/src/config/bundled-skills/followups/tools/followup-create.ts +9 -0
  125. package/src/config/bundled-skills/followups/tools/followup-list.ts +9 -0
  126. package/src/config/bundled-skills/followups/tools/followup-resolve.ts +9 -0
  127. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -23
  128. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -1
  129. package/src/config/bundled-skills/playbooks/SKILL.md +31 -0
  130. package/src/config/bundled-skills/playbooks/TOOLS.json +126 -0
  131. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +9 -0
  132. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +9 -0
  133. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +9 -0
  134. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +9 -0
  135. package/src/config/bundled-skills/reminder/SKILL.md +20 -0
  136. package/src/config/bundled-skills/reminder/TOOLS.json +67 -0
  137. package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +9 -0
  138. package/src/config/bundled-skills/reminder/tools/reminder-create.ts +9 -0
  139. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +9 -0
  140. package/src/config/bundled-skills/schedule/SKILL.md +74 -0
  141. package/src/config/bundled-skills/schedule/TOOLS.json +135 -0
  142. package/src/config/bundled-skills/schedule/tools/schedule-create.ts +9 -0
  143. package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +9 -0
  144. package/src/config/bundled-skills/schedule/tools/schedule-list.ts +9 -0
  145. package/src/config/bundled-skills/schedule/tools/schedule-update.ts +9 -0
  146. package/src/config/bundled-skills/subagent/SKILL.md +25 -0
  147. package/src/config/bundled-skills/subagent/TOOLS.json +107 -0
  148. package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +9 -0
  149. package/src/config/bundled-skills/subagent/tools/subagent-message.ts +9 -0
  150. package/src/config/bundled-skills/subagent/tools/subagent-read.ts +9 -0
  151. package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +9 -0
  152. package/src/config/bundled-skills/subagent/tools/subagent-status.ts +9 -0
  153. package/src/config/bundled-skills/tasks/SKILL.md +28 -0
  154. package/src/config/bundled-skills/tasks/TOOLS.json +256 -0
  155. package/src/config/bundled-skills/tasks/tools/task-delete.ts +9 -0
  156. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +9 -0
  157. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +9 -0
  158. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +9 -0
  159. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +9 -0
  160. package/src/config/bundled-skills/tasks/tools/task-list.ts +9 -0
  161. package/src/config/bundled-skills/tasks/tools/task-run.ts +9 -0
  162. package/src/config/bundled-skills/tasks/tools/task-save.ts +9 -0
  163. package/src/config/bundled-skills/twitter/SKILL.md +134 -0
  164. package/src/config/bundled-skills/watcher/SKILL.md +27 -0
  165. package/src/config/bundled-skills/watcher/TOOLS.json +147 -0
  166. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +9 -0
  167. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +9 -0
  168. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +9 -0
  169. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +9 -0
  170. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +9 -0
  171. package/src/config/defaults.ts +33 -0
  172. package/src/config/loader.ts +4 -1
  173. package/src/config/schema.ts +161 -1
  174. package/src/config/system-prompt.ts +61 -16
  175. package/src/config/templates/IDENTITY.md +7 -0
  176. package/src/config/types.ts +4 -0
  177. package/src/contacts/contact-store.ts +4 -4
  178. package/src/daemon/assistant-attachments.ts +10 -0
  179. package/src/daemon/classifier.ts +3 -1
  180. package/src/daemon/computer-use-session.ts +3 -1
  181. package/src/daemon/date-context.ts +136 -0
  182. package/src/daemon/handlers/apps.ts +16 -1
  183. package/src/daemon/handlers/browser.ts +54 -0
  184. package/src/daemon/handlers/computer-use.ts +7 -1
  185. package/src/daemon/handlers/config.ts +163 -5
  186. package/src/daemon/handlers/diagnostics.ts +5 -1
  187. package/src/daemon/handlers/documents.ts +18 -29
  188. package/src/daemon/handlers/home-base.ts +5 -1
  189. package/src/daemon/handlers/index.ts +40 -277
  190. package/src/daemon/handlers/misc.ts +9 -1
  191. package/src/daemon/handlers/publish.ts +6 -1
  192. package/src/daemon/handlers/sessions.ts +65 -12
  193. package/src/daemon/handlers/shared.ts +36 -1
  194. package/src/daemon/handlers/signing.ts +37 -0
  195. package/src/daemon/handlers/skills.ts +20 -6
  196. package/src/daemon/handlers/subagents.ts +8 -3
  197. package/src/daemon/handlers/twitter-auth.ts +169 -0
  198. package/src/daemon/handlers/work-items.ts +384 -68
  199. package/src/daemon/ipc-contract-inventory.json +28 -4
  200. package/src/daemon/ipc-contract.ts +133 -37
  201. package/src/daemon/ipc-protocol.ts +7 -2
  202. package/src/daemon/lifecycle.ts +21 -0
  203. package/src/daemon/main.ts +10 -4
  204. package/src/daemon/ride-shotgun-handler.ts +74 -10
  205. package/src/daemon/server.ts +143 -26
  206. package/src/daemon/session-agent-loop.ts +887 -0
  207. package/src/daemon/session-attachments.ts +28 -5
  208. package/src/daemon/session-error.ts +24 -3
  209. package/src/daemon/session-lifecycle.ts +147 -0
  210. package/src/daemon/session-media-retry.ts +147 -0
  211. package/src/daemon/session-messaging.ts +145 -0
  212. package/src/daemon/session-notifiers.ts +164 -0
  213. package/src/daemon/session-process.ts +2 -2
  214. package/src/daemon/session-queue-manager.ts +1 -0
  215. package/src/daemon/session-runtime-assembly.ts +52 -0
  216. package/src/daemon/session-skill-tools.ts +124 -5
  217. package/src/daemon/session-slash.ts +3 -0
  218. package/src/daemon/session-surfaces.ts +77 -2
  219. package/src/daemon/session-tool-setup.ts +216 -2
  220. package/src/daemon/session-usage.ts +0 -2
  221. package/src/daemon/session.ts +114 -1404
  222. package/src/daemon/video-thumbnail.ts +60 -0
  223. package/src/doordash/client.ts +121 -27
  224. package/src/doordash/queries.ts +1 -2
  225. package/src/export/formatter.ts +3 -1
  226. package/src/followups/followup-store.ts +4 -2
  227. package/src/followups/types.ts +6 -0
  228. package/src/hooks/templates.ts +1 -1
  229. package/src/index.ts +32 -1153
  230. package/src/memory/attachments-store.ts +28 -83
  231. package/src/memory/channel-delivery-store.ts +7 -21
  232. package/src/memory/clarification-resolver.ts +6 -5
  233. package/src/memory/contradiction-checker.ts +3 -2
  234. package/src/memory/conversation-key-store.ts +10 -29
  235. package/src/memory/conversation-store.ts +2 -1
  236. package/src/memory/db.ts +96 -2
  237. package/src/memory/entity-extractor.ts +6 -3
  238. package/src/memory/items-extractor.ts +5 -4
  239. package/src/memory/jobs-store.ts +3 -2
  240. package/src/memory/llm-usage-store.ts +1 -2
  241. package/src/memory/runs-store.ts +1 -2
  242. package/src/memory/schema.ts +23 -2
  243. package/src/messaging/style-analyzer.ts +3 -2
  244. package/src/messaging/thread-summarizer.ts +8 -12
  245. package/src/messaging/triage-engine.ts +4 -2
  246. package/src/providers/openrouter/client.ts +20 -0
  247. package/src/providers/registry.ts +8 -0
  248. package/src/runtime/http-server.ts +108 -20
  249. package/src/runtime/routes/attachment-routes.ts +2 -3
  250. package/src/runtime/routes/call-routes.ts +140 -0
  251. package/src/runtime/routes/channel-routes.ts +5 -10
  252. package/src/runtime/routes/conversation-routes.ts +5 -5
  253. package/src/runtime/routes/run-routes.ts +2 -2
  254. package/src/runtime/run-orchestrator.ts +9 -3
  255. package/src/schedule/recurrence-engine.ts +138 -0
  256. package/src/schedule/recurrence-types.ts +67 -0
  257. package/src/schedule/schedule-store.ts +102 -57
  258. package/src/schedule/scheduler.ts +9 -6
  259. package/src/security/oauth2.ts +29 -4
  260. package/src/security/secret-allowlist.ts +46 -0
  261. package/src/skills/clawhub.ts +1 -1
  262. package/src/subagent/manager.ts +40 -8
  263. package/src/swarm/backend-claude-code.ts +64 -9
  264. package/src/swarm/worker-prompts.ts +2 -1
  265. package/src/tasks/SPEC.md +34 -28
  266. package/src/tasks/ephemeral-permissions.ts +16 -7
  267. package/src/tasks/task-compiler.ts +5 -4
  268. package/src/tasks/task-runner.ts +10 -5
  269. package/src/tasks/task-scheduler.ts +1 -1
  270. package/src/tasks/tool-sanitizer.ts +36 -0
  271. package/src/tools/assets/search.ts +4 -4
  272. package/src/tools/browser/api-map.ts +220 -0
  273. package/src/tools/browser/auto-navigate.ts +270 -0
  274. package/src/tools/browser/browser-execution.ts +2 -1
  275. package/src/tools/browser/browser-manager.ts +2 -2
  276. package/src/tools/browser/network-recorder.ts +5 -4
  277. package/src/tools/browser/x-auto-navigate.ts +207 -0
  278. package/src/tools/calls/call-end.ts +17 -67
  279. package/src/tools/calls/call-start.ts +24 -85
  280. package/src/tools/calls/call-status.ts +35 -51
  281. package/src/tools/claude-code/claude-code.ts +77 -11
  282. package/src/tools/contacts/contact-merge.ts +46 -78
  283. package/src/tools/contacts/contact-search.ts +35 -79
  284. package/src/tools/contacts/contact-upsert.ts +35 -108
  285. package/src/tools/credentials/vault.ts +20 -4
  286. package/src/tools/document/document-tool.ts +71 -144
  287. package/src/tools/executor.ts +129 -10
  288. package/src/tools/followups/followup_create.ts +46 -88
  289. package/src/tools/followups/followup_list.ts +34 -74
  290. package/src/tools/followups/followup_resolve.ts +31 -66
  291. package/src/tools/host-terminal/cli-discover.ts +2 -1
  292. package/src/tools/host-terminal/host-shell.ts +10 -0
  293. package/src/tools/memory/handlers.ts +5 -4
  294. package/src/tools/network/__tests__/web-search.test.ts +427 -0
  295. package/src/tools/network/script-proxy/__tests__/logging.test.ts +248 -0
  296. package/src/tools/network/script-proxy/__tests__/policy.test.ts +234 -0
  297. package/src/tools/network/script-proxy/__tests__/router.test.ts +76 -0
  298. package/src/tools/network/web-fetch.ts +18 -6
  299. package/src/tools/playbooks/index.ts +4 -5
  300. package/src/tools/playbooks/playbook-create.ts +3 -47
  301. package/src/tools/playbooks/playbook-delete.ts +1 -25
  302. package/src/tools/playbooks/playbook-list.ts +1 -28
  303. package/src/tools/playbooks/playbook-update.ts +3 -51
  304. package/src/tools/reminder/reminder.ts +5 -78
  305. package/src/tools/schedule/create.ts +69 -74
  306. package/src/tools/schedule/delete.ts +21 -47
  307. package/src/tools/schedule/list.ts +55 -74
  308. package/src/tools/schedule/update.ts +77 -84
  309. package/src/tools/subagent/abort.ts +29 -58
  310. package/src/tools/subagent/message.ts +30 -63
  311. package/src/tools/subagent/read.ts +53 -84
  312. package/src/tools/subagent/spawn.ts +43 -82
  313. package/src/tools/subagent/status.ts +42 -71
  314. package/src/tools/swarm/delegate.ts +2 -1
  315. package/src/tools/tasks/index.ts +8 -8
  316. package/src/tools/tasks/task-delete.ts +60 -88
  317. package/src/tools/tasks/task-list.ts +31 -52
  318. package/src/tools/tasks/task-run.ts +72 -108
  319. package/src/tools/tasks/task-save.ts +33 -65
  320. package/src/tools/tasks/work-item-enqueue.ts +183 -215
  321. package/src/tools/tasks/work-item-list.ts +33 -63
  322. package/src/tools/tasks/work-item-remove.ts +45 -97
  323. package/src/tools/tasks/work-item-update.ts +91 -163
  324. package/src/tools/terminal/backends/native.ts +3 -1
  325. package/src/tools/tool-manifest.ts +0 -62
  326. package/src/tools/types.ts +6 -0
  327. package/src/tools/ui-surface/definitions.ts +3 -1
  328. package/src/tools/watch/screen-watch.ts +3 -1
  329. package/src/tools/watcher/create.ts +52 -98
  330. package/src/tools/watcher/delete.ts +20 -46
  331. package/src/tools/watcher/digest.ts +36 -70
  332. package/src/tools/watcher/list.ts +49 -79
  333. package/src/tools/watcher/update.ts +45 -91
  334. package/src/twitter/client.ts +690 -0
  335. package/src/twitter/session.ts +91 -0
  336. package/src/usage/types.ts +0 -1
  337. package/src/util/truncate.ts +6 -0
  338. package/src/watcher/providers/slack.ts +2 -1
  339. package/src/watcher/watcher-store.ts +3 -2
  340. package/src/work-items/work-item-store.ts +27 -2
  341. package/src/workspace/commit-message-enrichment-service.ts +31 -7
  342. package/src/workspace/git-service.ts +87 -22
  343. package/src/workspace/provider-commit-message-generator.ts +242 -0
  344. package/src/workspace/turn-commit.ts +62 -3
  345. package/src/tools/contacts/index.ts +0 -4
  346. package/src/tools/document/index.ts +0 -5
  347. package/src/tools/followups/index.ts +0 -3
  348. package/src/tools/subagent/index.ts +0 -5
  349. /package/src/__tests__/{memory-context-benchmark.test.ts → memory-context-benchmark.benchmark.test.ts} +0 -0
@@ -0,0 +1,107 @@
1
+ {
2
+ "version": 1,
3
+ "tools": [
4
+ {
5
+ "name": "subagent_spawn",
6
+ "description": "Spawn an independent subagent to work on a task in parallel. The subagent runs autonomously and its results are reported back when complete.",
7
+ "category": "orchestration",
8
+ "risk": "low",
9
+ "input_schema": {
10
+ "type": "object",
11
+ "properties": {
12
+ "label": {
13
+ "type": "string",
14
+ "description": "Short human-readable label for this subagent (e.g. \"Research competitor pricing\")"
15
+ },
16
+ "objective": {
17
+ "type": "string",
18
+ "description": "The task objective — what the subagent should accomplish"
19
+ },
20
+ "context": {
21
+ "type": "string",
22
+ "description": "Optional additional context to pass to the subagent"
23
+ }
24
+ },
25
+ "required": ["label", "objective"]
26
+ },
27
+ "executor": "tools/subagent-spawn.ts",
28
+ "execution_target": "host"
29
+ },
30
+ {
31
+ "name": "subagent_status",
32
+ "description": "Get the status of a specific subagent or list all subagents for the current session. Only use this when the user explicitly asks about subagent status — do NOT poll automatically, as you will be notified when subagents complete.",
33
+ "category": "orchestration",
34
+ "risk": "low",
35
+ "input_schema": {
36
+ "type": "object",
37
+ "properties": {
38
+ "subagent_id": {
39
+ "type": "string",
40
+ "description": "Optional subagent ID to query. If omitted, returns all subagents for this session."
41
+ }
42
+ },
43
+ "required": []
44
+ },
45
+ "executor": "tools/subagent-status.ts",
46
+ "execution_target": "host"
47
+ },
48
+ {
49
+ "name": "subagent_abort",
50
+ "description": "Abort a running subagent by ID.",
51
+ "category": "orchestration",
52
+ "risk": "low",
53
+ "input_schema": {
54
+ "type": "object",
55
+ "properties": {
56
+ "subagent_id": {
57
+ "type": "string",
58
+ "description": "The ID of the subagent to abort."
59
+ }
60
+ },
61
+ "required": ["subagent_id"]
62
+ },
63
+ "executor": "tools/subagent-abort.ts",
64
+ "execution_target": "host"
65
+ },
66
+ {
67
+ "name": "subagent_message",
68
+ "description": "Send a follow-up message to a running subagent.",
69
+ "category": "orchestration",
70
+ "risk": "low",
71
+ "input_schema": {
72
+ "type": "object",
73
+ "properties": {
74
+ "subagent_id": {
75
+ "type": "string",
76
+ "description": "The ID of the subagent to send a message to."
77
+ },
78
+ "content": {
79
+ "type": "string",
80
+ "description": "The message content to send to the subagent."
81
+ }
82
+ },
83
+ "required": ["subagent_id", "content"]
84
+ },
85
+ "executor": "tools/subagent-message.ts",
86
+ "execution_target": "host"
87
+ },
88
+ {
89
+ "name": "subagent_read",
90
+ "description": "Read the full conversation output from a subagent. Use this after a subagent completes to retrieve its full work product.",
91
+ "category": "orchestration",
92
+ "risk": "low",
93
+ "input_schema": {
94
+ "type": "object",
95
+ "properties": {
96
+ "subagent_id": {
97
+ "type": "string",
98
+ "description": "The ID of the subagent whose output to read."
99
+ }
100
+ },
101
+ "required": ["subagent_id"]
102
+ },
103
+ "executor": "tools/subagent-read.ts",
104
+ "execution_target": "host"
105
+ }
106
+ ]
107
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeSubagentAbort } from '../../../../tools/subagent/abort.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeSubagentAbort(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeSubagentMessage } from '../../../../tools/subagent/message.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeSubagentMessage(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeSubagentRead } from '../../../../tools/subagent/read.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeSubagentRead(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeSubagentSpawn } from '../../../../tools/subagent/spawn.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeSubagentSpawn(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeSubagentStatus } from '../../../../tools/subagent/status.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeSubagentStatus(input, context);
9
+ }
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: "Tasks"
3
+ description: "Two-layer task system with reusable templates and a prioritized work queue"
4
+ metadata: {"vellum": {"emoji": "\u2705"}}
5
+ ---
6
+
7
+ Two-layer task system: **task templates** (reusable definitions with input placeholders) and **work items** (instances in the Task Queue with priority tiers and status tracking).
8
+
9
+ ## Task Templates
10
+
11
+ Templates are reusable definitions saved from conversations via `task_save`. They capture the conversation pattern with placeholders that can be run later with different inputs via `task_run`. List templates with `task_list`, delete with `task_delete`.
12
+
13
+ ## Work Items (Task Queue)
14
+
15
+ Work items are the user-facing "Tasks" shown in the Tasks panel. They track status and priority:
16
+
17
+ - **Priority tiers**: 0 = high, 1 = medium (default), 2 = low
18
+ - **Status flow**: queued -> running -> awaiting_review -> done
19
+ - **Resolution precedence**: work_item_id > task_id > task_name > title
20
+
21
+ Use `task_list_add` to enqueue items (ad-hoc or from a template), `task_list_show` to view the queue, `task_list_update` to modify, and `task_list_remove` to remove.
22
+
23
+ ## Tips
24
+
25
+ - When the user says "add to my tasks" or "add to my queue", use `task_list_add` (NOT schedule_create or reminder_create).
26
+ - Use `task_save` only when the user wants to capture a conversation pattern as a reusable template.
27
+ - `task_list` shows saved templates; `task_list_show` shows the active work queue.
28
+ - **Always specify `required_tools`** when calling `task_list_add`. Think about what tools the task will need at execution time and list them explicitly (e.g. `["host_bash"]` for shell commands, `["host_file_read", "host_file_write"]` for file operations, `["web_search", "web_fetch"]` for web lookups). The user must approve these tools before the task can run — omitting them forces a fallback to all tools, which is noisy and may miss non-standard tools the task actually needs.
@@ -0,0 +1,256 @@
1
+ {
2
+ "version": 1,
3
+ "tools": [
4
+ {
5
+ "name": "task_save",
6
+ "description": "Save the current conversation as a reusable task template (definition). This is NOT for adding items to the user's task queue — use task_list_add for that. task_save extracts the conversation pattern into a reusable definition with placeholders that can be run later with different inputs.",
7
+ "category": "tasks",
8
+ "risk": "low",
9
+ "input_schema": {
10
+ "type": "object",
11
+ "properties": {
12
+ "conversation_id": {
13
+ "type": "string",
14
+ "description": "The conversation to capture as a task template. If omitted, uses the current conversation."
15
+ },
16
+ "title": {
17
+ "type": "string",
18
+ "description": "Optional override for the auto-generated task title"
19
+ }
20
+ },
21
+ "required": []
22
+ },
23
+ "executor": "tools/task-save.ts",
24
+ "execution_target": "host"
25
+ },
26
+ {
27
+ "name": "task_run",
28
+ "description": "Run a task template. Resolves the template by name (fuzzy match) or ID, renders it with the provided inputs, and returns the rendered prompt for execution as a Task (work item).",
29
+ "category": "tasks",
30
+ "risk": "low",
31
+ "input_schema": {
32
+ "type": "object",
33
+ "properties": {
34
+ "task_name": {
35
+ "type": "string",
36
+ "description": "Fuzzy match a task template by name (case-insensitive substring match)"
37
+ },
38
+ "task_id": {
39
+ "type": "string",
40
+ "description": "Exact match a task template by ID"
41
+ },
42
+ "inputs": {
43
+ "type": "object",
44
+ "description": "Values for template placeholders (e.g. {\"file_path\": \"/tmp/foo.txt\", \"url\": \"https://example.com\"})",
45
+ "additionalProperties": { "type": "string" }
46
+ }
47
+ }
48
+ },
49
+ "executor": "tools/task-run.ts",
50
+ "execution_target": "host"
51
+ },
52
+ {
53
+ "name": "task_list",
54
+ "description": "List saved task templates (reusable definitions). To see your active Tasks (work items), use task_list_show instead.",
55
+ "category": "tasks",
56
+ "risk": "low",
57
+ "input_schema": {
58
+ "type": "object",
59
+ "properties": {}
60
+ },
61
+ "executor": "tools/task-list.ts",
62
+ "execution_target": "host"
63
+ },
64
+ {
65
+ "name": "task_delete",
66
+ "description": "Delete one or more task templates by ID. Also removes associated task runs and work items (Tasks).",
67
+ "category": "tasks",
68
+ "risk": "medium",
69
+ "input_schema": {
70
+ "type": "object",
71
+ "properties": {
72
+ "task_ids": {
73
+ "type": "array",
74
+ "items": { "type": "string" },
75
+ "description": "One or more task IDs to delete."
76
+ }
77
+ },
78
+ "required": ["task_ids"]
79
+ },
80
+ "executor": "tools/task-delete.ts",
81
+ "execution_target": "host"
82
+ },
83
+ {
84
+ "name": "task_list_show",
85
+ "description": "List the user's Task Queue (work items) with their status, priority, and last run info. Use this when the user says \"show my tasks\", \"what's in my queue\", \"what's on my task list\", or similar.",
86
+ "category": "tasks",
87
+ "risk": "low",
88
+ "input_schema": {
89
+ "type": "object",
90
+ "properties": {
91
+ "status": {
92
+ "oneOf": [
93
+ { "type": "string" },
94
+ { "type": "array", "items": { "type": "string" } }
95
+ ],
96
+ "description": "Optional status filter. A single status string (e.g. \"queued\") or an array of statuses to include."
97
+ }
98
+ }
99
+ },
100
+ "executor": "tools/task-list-show.ts",
101
+ "execution_target": "host"
102
+ },
103
+ {
104
+ "name": "task_list_add",
105
+ "description": "Add a task to the user's Task Queue. Use this when the user says \"add to my tasks\", \"add to my queue\", \"put this on my task list\", \"track this task\", or any variation of adding a one-off item they want to remember or work on. You can provide just a title for ad-hoc items, or reference an existing task definition by name or ID. Do NOT use schedule_create or reminder for simple \"add to tasks\" requests — those are for timed/recurring automation only.",
106
+ "category": "tasks",
107
+ "risk": "low",
108
+ "input_schema": {
109
+ "type": "object",
110
+ "properties": {
111
+ "task_id": {
112
+ "type": "string",
113
+ "description": "ID of an existing task definition to enqueue. Provide this, task_name, or just title."
114
+ },
115
+ "task_name": {
116
+ "type": "string",
117
+ "description": "Title/name of an existing task definition to search for (case-insensitive substring match). Provide this, task_id, or just title."
118
+ },
119
+ "title": {
120
+ "type": "string",
121
+ "description": "Title for the work item. When provided WITHOUT task_id or task_name, creates an ad-hoc work item directly (a lightweight task template is auto-created behind the scenes). When provided WITH task_id or task_name, overrides the task definition title."
122
+ },
123
+ "execution_prompt": {
124
+ "type": "string",
125
+ "description": "The full instruction to execute when this task runs. If omitted, the title is used as the execution prompt. Use this to preserve detailed instructions (e.g. full file paths, specific parameters) that would be lost in a short display title."
126
+ },
127
+ "notes": {
128
+ "type": "string",
129
+ "description": "Notes to attach to the work item."
130
+ },
131
+ "priority_tier": {
132
+ "type": "number",
133
+ "description": "0 = high, 1 = medium (default), 2 = low."
134
+ },
135
+ "sort_index": {
136
+ "type": "number",
137
+ "description": "Manual sort order within the priority tier."
138
+ },
139
+ "if_exists": {
140
+ "type": "string",
141
+ "enum": ["create_duplicate", "reuse_existing", "update_existing"],
142
+ "description": "What to do if an active work item with the same title already exists. Defaults to \"reuse_existing\"."
143
+ },
144
+ "required_tools": {
145
+ "type": "array",
146
+ "items": { "type": "string" },
147
+ "description": "Tools the task will need at execution time. Always specify this — think about what tools are needed to accomplish the task (e.g. [\"host_bash\"] for shell commands, [\"host_file_read\", \"host_file_write\"] for file operations, [\"web_search\"] for web lookups). The user must approve these before the task runs. Pass [] if no tools are needed."
148
+ }
149
+ }
150
+ },
151
+ "executor": "tools/task-list-add.ts",
152
+ "execution_target": "host"
153
+ },
154
+ {
155
+ "name": "task_list_update",
156
+ "description": "Update an existing task in the Task Queue. Can change priority, notes, status, or sort order. Identifies the task by work item ID, task ID, task name, or title.",
157
+ "category": "tasks",
158
+ "risk": "low",
159
+ "input_schema": {
160
+ "type": "object",
161
+ "properties": {
162
+ "work_item_id": {
163
+ "type": "string",
164
+ "description": "Direct work item ID (most precise selector)"
165
+ },
166
+ "task_id": {
167
+ "type": "string",
168
+ "description": "Task definition ID to find the work item for"
169
+ },
170
+ "task_name": {
171
+ "type": "string",
172
+ "description": "Task name/title to search for (case-insensitive exact match)"
173
+ },
174
+ "title": {
175
+ "type": "string",
176
+ "description": "Work item title to search for (case-insensitive exact match)"
177
+ },
178
+ "priority_tier": {
179
+ "type": "number",
180
+ "description": "0 = high, 1 = medium, 2 = low"
181
+ },
182
+ "notes": {
183
+ "type": "string",
184
+ "description": "Updated notes for the work item"
185
+ },
186
+ "status": {
187
+ "type": "string",
188
+ "enum": ["queued", "running", "awaiting_review", "failed", "cancelled", "archived"],
189
+ "description": "New status for the work item"
190
+ },
191
+ "sort_index": {
192
+ "type": "number",
193
+ "description": "Manual sort order within the same priority tier"
194
+ },
195
+ "filter_priority_tier": {
196
+ "type": "number",
197
+ "description": "Disambiguation filter: narrow by current priority tier (0=high, 1=medium, 2=low) when multiple items share the same title/task_id. This identifies WHICH item to update — it is NOT the new priority value."
198
+ },
199
+ "filter_status": {
200
+ "type": "string",
201
+ "enum": ["queued", "running", "awaiting_review", "failed", "cancelled", "done", "archived"],
202
+ "description": "Disambiguation filter: narrow by current status when multiple items share the same title/task_id."
203
+ },
204
+ "created_order": {
205
+ "type": "number",
206
+ "description": "Disambiguation filter: pick the Nth oldest match (1 = oldest, 2 = second oldest, etc.) when multiple items share the same title/task_id."
207
+ }
208
+ }
209
+ },
210
+ "executor": "tools/task-list-update.ts",
211
+ "execution_target": "host"
212
+ },
213
+ {
214
+ "name": "task_list_remove",
215
+ "description": "Remove a task from the Task Queue. Identifies the task by work item ID, task ID, task name, or title. When multiple items match, use the disambiguation fields (priority_tier, status, created_order) to narrow down.",
216
+ "category": "tasks",
217
+ "risk": "low",
218
+ "input_schema": {
219
+ "type": "object",
220
+ "properties": {
221
+ "work_item_id": {
222
+ "type": "string",
223
+ "description": "Direct work item ID (most precise selector)"
224
+ },
225
+ "task_id": {
226
+ "type": "string",
227
+ "description": "Task definition ID to find the work item for"
228
+ },
229
+ "task_name": {
230
+ "type": "string",
231
+ "description": "Task name/title to search for (case-insensitive exact match)"
232
+ },
233
+ "title": {
234
+ "type": "string",
235
+ "description": "Work item title to search for (case-insensitive exact match)"
236
+ },
237
+ "priority_tier": {
238
+ "type": "number",
239
+ "description": "Disambiguator: filter by priority tier (0 = high, 1 = medium, 2 = low)"
240
+ },
241
+ "status": {
242
+ "type": "string",
243
+ "enum": ["queued", "running", "awaiting_review", "failed", "cancelled"],
244
+ "description": "Disambiguator: filter by work item status"
245
+ },
246
+ "created_order": {
247
+ "type": "number",
248
+ "description": "Disambiguator: 1-indexed creation order among matches (1 = oldest, 2 = second oldest, etc.)"
249
+ }
250
+ }
251
+ },
252
+ "executor": "tools/task-list-remove.ts",
253
+ "execution_target": "host"
254
+ }
255
+ ]
256
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeTaskDelete } from '../../../../tools/tasks/task-delete.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeTaskDelete(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeTaskListAdd } from '../../../../tools/tasks/work-item-enqueue.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeTaskListAdd(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeTaskListRemove } from '../../../../tools/tasks/work-item-remove.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeTaskListRemove(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeTaskListShow } from '../../../../tools/tasks/work-item-list.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeTaskListShow(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeTaskListUpdate } from '../../../../tools/tasks/work-item-update.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeTaskListUpdate(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeTaskList } from '../../../../tools/tasks/task-list.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeTaskList(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeTaskRun } from '../../../../tools/tasks/task-run.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeTaskRun(input, context);
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js';
2
+ import { executeTaskSave } from '../../../../tools/tasks/task-save.js';
3
+
4
+ export async function run(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ return executeTaskSave(input, context);
9
+ }
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: "X"
3
+ description: "Read and post on X (formerly Twitter) using your authenticated session"
4
+ user-invocable: true
5
+ metadata: {"vellum": {"emoji": "𝕏"}}
6
+ ---
7
+
8
+ You are an X (formerly Twitter) assistant. Use the `execute_bash` tool to run `vellum x` CLI commands.
9
+
10
+ ## Posting
11
+
12
+ ```bash
13
+ vellum x post "The post text here"
14
+ ```
15
+
16
+ Returns JSON with `ok`, `tweetId`, `text`, and `url` fields. Share the URL with the user so they can verify the post.
17
+
18
+ ## Replying
19
+
20
+ ```bash
21
+ vellum x reply <tweetUrl> "The reply text here"
22
+ ```
23
+
24
+ The first argument is a tweet URL (e.g. `https://x.com/user/status/123456`) or a bare tweet ID.
25
+
26
+ ## Reading
27
+
28
+ ### User timeline
29
+ ```bash
30
+ vellum x timeline <screenName> [--count N]
31
+ ```
32
+ Returns `user` and `tweets` array.
33
+
34
+ ### Single tweet + replies
35
+ ```bash
36
+ vellum x tweet <tweetIdOrUrl>
37
+ ```
38
+ Returns the focal tweet and its reply thread.
39
+
40
+ ### Search
41
+ ```bash
42
+ vellum x search "query" [--count N] [--product Top|Latest|People|Media]
43
+ ```
44
+
45
+ ### Home timeline
46
+ ```bash
47
+ vellum x home [--count N]
48
+ ```
49
+
50
+ ### Bookmarks
51
+ ```bash
52
+ vellum x bookmarks [--count N]
53
+ ```
54
+
55
+ ### Notifications
56
+ ```bash
57
+ vellum x notifications [--count N]
58
+ ```
59
+ Returns `notifications` array with `id`, `message`, `timestamp`, `url`.
60
+
61
+ ### Likes
62
+ ```bash
63
+ vellum x likes <screenName> [--count N]
64
+ ```
65
+
66
+ ### Followers / Following
67
+ ```bash
68
+ vellum x followers <screenName> [--count N]
69
+ vellum x following <screenName> [--count N]
70
+ ```
71
+ Returns `user` and `followers`/`following` array (userId, screenName, name).
72
+
73
+ ### Media
74
+ ```bash
75
+ vellum x media <screenName> [--count N]
76
+ ```
77
+ Returns tweets that contain media from the user's profile.
78
+
79
+ ## Session Management
80
+
81
+ Check if a session exists:
82
+ ```bash
83
+ vellum x status --json
84
+ ```
85
+
86
+ If there is no session or the session has expired, refresh it:
87
+ ```bash
88
+ vellum x refresh
89
+ ```
90
+
91
+ This opens Chrome, navigates through x.com automatically, and captures auth cookies. Do NOT tell the user to run this manually — run it yourself.
92
+
93
+ ## Workflows
94
+
95
+ ### Check Mentions
96
+
97
+ When the user asks to check mentions, check X, or see what's happening:
98
+
99
+ 1. Fetch notifications: `vellum x notifications --count 20 --json`
100
+ 2. Fetch their recent tweets to see replies: `vellum x timeline <theirScreenName> --count 10 --json`
101
+ 3. Summarize what needs attention:
102
+ - Group by type: replies to their tweets, likes, new followers, mentions
103
+ - For anything that looks like it needs a reply, fetch the full thread with `vellum x tweet <tweetId>` to understand context
104
+ - Prioritize: direct questions > mentions > engagement notifications
105
+ 4. For items that need replies, draft a response and ask the user to approve before sending with `vellum x reply`
106
+
107
+ Present the summary as a scannable list, not a wall of text. Lead with action items.
108
+
109
+ ### Research a Topic
110
+
111
+ When the user wants to understand what people are saying about something:
112
+
113
+ 1. Search: `vellum x search "topic" --count 20 --json`
114
+ 2. For the most interesting tweets, fetch threads: `vellum x tweet <tweetId>`
115
+ 3. Summarize: key themes, notable voices, sentiment, and any emerging consensus
116
+ 4. If the user wants to engage, draft a post or reply that adds to the conversation
117
+
118
+ ### Engagement Check
119
+
120
+ When the user wants to see how their posts are performing:
121
+
122
+ 1. Fetch their recent tweets: `vellum x timeline <screenName> --count 20 --json`
123
+ 2. For each tweet, note engagement signals from the text/metadata
124
+ 3. Fetch notifications to see who's interacting: `vellum x notifications --count 20 --json`
125
+ 4. Summarize: which posts got traction, who's engaging, any conversations worth continuing
126
+
127
+ ## Tips
128
+
129
+ - Keep posts under 280 characters
130
+ - All `screenName` arguments should be without the `@` prefix
131
+ - All commands return JSON with an `ok` field
132
+ - When drafting replies, match the tone of the conversation — casual threads get casual replies
133
+ - Always show the user what you're about to post and get approval before sending
134
+ - If a session is expired, refresh it silently with `vellum x refresh` before retrying