@vellumai/assistant 0.5.16 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (592) hide show
  1. package/AGENTS.md +4 -0
  2. package/ARCHITECTURE.md +69 -16
  3. package/Dockerfile +2 -5
  4. package/bun.lock +6 -2
  5. package/docker-entrypoint.sh +32 -1
  6. package/docs/architecture/integrations.md +1 -1
  7. package/docs/architecture/memory.md +21 -24
  8. package/knip.json +2 -1
  9. package/openapi.yaml +1198 -83
  10. package/package.json +5 -1
  11. package/src/__tests__/actor-token-service.test.ts +68 -0
  12. package/src/__tests__/agent-loop.test.ts +0 -32
  13. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  14. package/src/__tests__/anthropic-provider.test.ts +217 -98
  15. package/src/__tests__/app-compiler.test.ts +120 -0
  16. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  17. package/src/__tests__/app-executors.test.ts +47 -1
  18. package/src/__tests__/app-source-watcher.test.ts +159 -0
  19. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  20. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  21. package/src/__tests__/call-domain.test.ts +2 -6
  22. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  23. package/src/__tests__/call-recovery.test.ts +2 -6
  24. package/src/__tests__/call-routes-http.test.ts +2 -6
  25. package/src/__tests__/call-store.test.ts +2 -6
  26. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  27. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  28. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  29. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  30. package/src/__tests__/checker.test.ts +63 -9
  31. package/src/__tests__/clawhub.test.ts +54 -24
  32. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  33. package/src/__tests__/config-schema.test.ts +6 -1
  34. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  35. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  36. package/src/__tests__/contacts-tools.test.ts +31 -0
  37. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  38. package/src/__tests__/context-token-estimator.test.ts +175 -10
  39. package/src/__tests__/conversation-agent-loop-overflow.test.ts +13 -6
  40. package/src/__tests__/conversation-agent-loop.test.ts +13 -51
  41. package/src/__tests__/conversation-attachments.test.ts +2 -6
  42. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  43. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  44. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  45. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  46. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  47. package/src/__tests__/conversation-error.test.ts +33 -2
  48. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  49. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  50. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  51. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  52. package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
  53. package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
  54. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  55. package/src/__tests__/conversation-store.test.ts +2 -6
  56. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
  57. package/src/__tests__/conversation-usage.test.ts +2 -6
  58. package/src/__tests__/conversation-wipe.test.ts +13 -414
  59. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
  60. package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
  61. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  62. package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
  63. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  64. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  65. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  66. package/src/__tests__/date-context.test.ts +76 -210
  67. package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
  68. package/src/__tests__/file-list-tool.test.ts +219 -0
  69. package/src/__tests__/first-greeting.test.ts +1 -1
  70. package/src/__tests__/followup-tools.test.ts +2 -6
  71. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  72. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  73. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  74. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  75. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  76. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  77. package/src/__tests__/guardian-action-store.test.ts +2 -6
  78. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  79. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  80. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  81. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  82. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  83. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  84. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  85. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  86. package/src/__tests__/heartbeat-service.test.ts +180 -3
  87. package/src/__tests__/identity-routes.test.ts +328 -0
  88. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  89. package/src/__tests__/injection-block.test.ts +178 -0
  90. package/src/__tests__/install-meta.test.ts +506 -0
  91. package/src/__tests__/install-skill-routing.test.ts +293 -0
  92. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  93. package/src/__tests__/invite-routes-http.test.ts +2 -6
  94. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +17 -28
  95. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  96. package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
  97. package/src/__tests__/llm-context-normalization.test.ts +18 -18
  98. package/src/__tests__/llm-context-route-provider.test.ts +103 -6
  99. package/src/__tests__/llm-request-log-turn-query.test.ts +164 -6
  100. package/src/__tests__/llm-usage-store.test.ts +2 -6
  101. package/src/__tests__/log-export-workspace.test.ts +74 -111
  102. package/src/__tests__/managed-store.test.ts +38 -11
  103. package/src/__tests__/mcp-abort-signal.test.ts +5 -0
  104. package/src/__tests__/mcp-client-auth.test.ts +5 -0
  105. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  106. package/src/__tests__/memory-recall-log-store.test.ts +134 -6
  107. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  108. package/src/__tests__/migration-export-streaming.test.ts +304 -0
  109. package/src/__tests__/migration-import-commit-http.test.ts +11 -10
  110. package/src/__tests__/mock-fetch.ts +87 -0
  111. package/src/__tests__/non-member-access-request.test.ts +2 -6
  112. package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
  113. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  114. package/src/__tests__/oauth-cli.test.ts +364 -2
  115. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  116. package/src/__tests__/onboarding-template-contract.test.ts +62 -14
  117. package/src/__tests__/outlook-attachments.test.ts +301 -0
  118. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  119. package/src/__tests__/outlook-categories.test.ts +212 -0
  120. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  121. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  122. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  123. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  124. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  125. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  126. package/src/__tests__/outlook-trash.test.ts +77 -0
  127. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  128. package/src/__tests__/parser.test.ts +32 -0
  129. package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
  130. package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
  131. package/src/__tests__/permission-mode-sse.test.ts +418 -0
  132. package/src/__tests__/permission-mode-store.test.ts +277 -0
  133. package/src/__tests__/permission-mode.test.ts +101 -0
  134. package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
  135. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  136. package/src/__tests__/playbook-execution.test.ts +76 -80
  137. package/src/__tests__/playbook-tools.test.ts +5 -7
  138. package/src/__tests__/profiler-routes.test.ts +502 -0
  139. package/src/__tests__/profiler-run-store.test.ts +441 -0
  140. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  141. package/src/__tests__/proxy-approval-callback.test.ts +4 -75
  142. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  143. package/src/__tests__/registry.test.ts +3 -3
  144. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  145. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  146. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  147. package/src/__tests__/sandbox-host-parity.test.ts +5 -4
  148. package/src/__tests__/schedule-store.test.ts +2 -6
  149. package/src/__tests__/schedule-tools.test.ts +2 -6
  150. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  151. package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
  152. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  153. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  154. package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
  155. package/src/__tests__/search-skills-unified.test.ts +422 -0
  156. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  157. package/src/__tests__/send-endpoint-busy.test.ts +44 -9
  158. package/src/__tests__/sequence-store.test.ts +2 -6
  159. package/src/__tests__/server-history-render.test.ts +2 -6
  160. package/src/__tests__/set-permission-mode.test.ts +274 -0
  161. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  162. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  163. package/src/__tests__/skill-load-feature-flag.test.ts +23 -11
  164. package/src/__tests__/skill-memory.test.ts +2 -741
  165. package/src/__tests__/skills-uninstall.test.ts +2 -2
  166. package/src/__tests__/skills.test.ts +1 -1
  167. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  168. package/src/__tests__/strip-memory-injections.test.ts +187 -0
  169. package/src/__tests__/subagent-detail.test.ts +84 -0
  170. package/src/__tests__/subagent-disposal.test.ts +308 -0
  171. package/src/__tests__/subagent-manager-notify.test.ts +19 -10
  172. package/src/__tests__/subagent-notify-parent.test.ts +390 -0
  173. package/src/__tests__/subagent-role-registry.test.ts +108 -0
  174. package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
  175. package/src/__tests__/subagent-tools.test.ts +464 -4
  176. package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
  177. package/src/__tests__/task-compiler.test.ts +2 -6
  178. package/src/__tests__/task-management-tools.test.ts +2 -6
  179. package/src/__tests__/task-memory-cleanup.test.ts +185 -241
  180. package/src/__tests__/task-runner.test.ts +2 -6
  181. package/src/__tests__/task-scheduler.test.ts +2 -6
  182. package/src/__tests__/terminal-tools.test.ts +17 -27
  183. package/src/__tests__/test-preload.ts +7 -0
  184. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  185. package/src/__tests__/tool-executor.test.ts +4 -26
  186. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  187. package/src/__tests__/tool-side-effects-slack-dm.test.ts +277 -0
  188. package/src/__tests__/top-level-renderer.test.ts +10 -13
  189. package/src/__tests__/trust-store.test.ts +1 -1
  190. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  191. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +118 -8
  192. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  193. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  194. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  195. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  196. package/src/__tests__/usage-routes.test.ts +2 -6
  197. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  198. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  199. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  200. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  201. package/src/__tests__/volume-security-guard.test.ts +2 -0
  202. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  203. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  204. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  205. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  206. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
  207. package/src/__tests__/workspace-policy.test.ts +1 -1
  208. package/src/agent/attachments.ts +7 -2
  209. package/src/agent/image-optimize.ts +165 -0
  210. package/src/agent/loop.ts +7 -15
  211. package/src/approvals/guardian-request-resolvers.ts +24 -0
  212. package/src/avatar/traits-png-sync.ts +3 -3
  213. package/src/bundler/app-compiler.ts +179 -2
  214. package/src/bundler/package-resolver.ts +3 -5
  215. package/src/cli/__tests__/notifications.test.ts +1 -2
  216. package/src/cli/__tests__/run-assistant-command.ts +29 -0
  217. package/src/cli/commands/__tests__/email-download.test.ts +245 -0
  218. package/src/cli/commands/__tests__/email-list.test.ts +192 -0
  219. package/src/cli/commands/__tests__/email-register.test.ts +186 -0
  220. package/src/cli/commands/__tests__/email-send.test.ts +291 -0
  221. package/src/cli/commands/__tests__/email-status.test.ts +181 -0
  222. package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
  223. package/src/cli/commands/__tests__/routes.test.ts +562 -0
  224. package/src/cli/commands/avatar.ts +3 -3
  225. package/src/cli/commands/config.ts +26 -13
  226. package/src/cli/commands/conversations.ts +1 -8
  227. package/src/cli/commands/doctor.ts +2 -2
  228. package/src/cli/commands/email.ts +584 -835
  229. package/src/cli/commands/memory.ts +37 -84
  230. package/src/cli/commands/notifications.ts +7 -2
  231. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  232. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  233. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  234. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  235. package/src/cli/commands/oauth/connect.ts +25 -11
  236. package/src/cli/commands/oauth/mode.ts +7 -0
  237. package/src/cli/commands/oauth/shared.ts +39 -3
  238. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  239. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  240. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  241. package/src/cli/commands/platform/index.ts +16 -16
  242. package/src/cli/commands/routes.ts +396 -0
  243. package/src/cli/commands/skills.ts +218 -36
  244. package/src/cli/commands/trust.ts +2 -2
  245. package/src/cli/lib/daemon-credential-client.ts +2 -3
  246. package/src/cli/program.ts +2 -0
  247. package/src/cli.ts +1 -120
  248. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  249. package/src/config/bundled-skills/app-builder/SKILL.md +4 -1
  250. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  251. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  252. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  253. package/src/config/bundled-skills/gmail/SKILL.md +4 -12
  254. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  255. package/src/config/bundled-skills/messaging/SKILL.md +17 -18
  256. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  257. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  258. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  259. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  260. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  261. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  262. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  263. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  264. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  265. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  266. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  267. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  268. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  269. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  270. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  271. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  272. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  273. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  274. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  275. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  276. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  277. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  278. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  279. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  280. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  281. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  282. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  283. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  284. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  285. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  286. package/src/config/bundled-skills/schedule/SKILL.md +22 -2
  287. package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
  288. package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
  289. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
  290. package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
  291. package/src/config/bundled-skills/slack/SKILL.md +3 -7
  292. package/src/config/bundled-skills/subagent/SKILL.md +43 -3
  293. package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
  294. package/src/config/bundled-tool-registry.ts +56 -4
  295. package/src/config/env-registry.ts +78 -8
  296. package/src/config/feature-flag-registry.json +38 -125
  297. package/src/config/schema.ts +8 -0
  298. package/src/config/schemas/filing.ts +51 -0
  299. package/src/config/schemas/heartbeat.ts +15 -12
  300. package/src/config/schemas/memory-lifecycle.ts +12 -0
  301. package/src/config/schemas/platform.ts +8 -0
  302. package/src/config/schemas/security.ts +14 -0
  303. package/src/config/schemas/timeouts.ts +1 -1
  304. package/src/config/skills.ts +18 -7
  305. package/src/context/token-estimator.ts +25 -18
  306. package/src/context/window-manager.ts +6 -2
  307. package/src/credential-execution/process-manager.ts +3 -1
  308. package/src/daemon/app-source-watcher.ts +93 -0
  309. package/src/daemon/config-watcher.ts +79 -1
  310. package/src/daemon/context-overflow-reducer.ts +46 -2
  311. package/src/daemon/conversation-agent-loop-handlers.ts +143 -82
  312. package/src/daemon/conversation-agent-loop.ts +236 -108
  313. package/src/daemon/conversation-error.ts +31 -8
  314. package/src/daemon/conversation-history.ts +4 -19
  315. package/src/daemon/conversation-lifecycle.ts +36 -9
  316. package/src/daemon/conversation-media-retry.ts +85 -7
  317. package/src/daemon/conversation-notifiers.ts +4 -1
  318. package/src/daemon/conversation-process.ts +13 -7
  319. package/src/daemon/conversation-runtime-assembly.ts +305 -306
  320. package/src/daemon/conversation-tool-setup.ts +44 -14
  321. package/src/daemon/conversation-workspace.ts +1 -2
  322. package/src/daemon/conversation.ts +59 -2
  323. package/src/daemon/daemon-control.ts +8 -2
  324. package/src/daemon/date-context.ts +26 -53
  325. package/src/daemon/first-greeting.ts +1 -1
  326. package/src/daemon/handlers/conversations.ts +4 -7
  327. package/src/daemon/handlers/shared.test.ts +143 -0
  328. package/src/daemon/handlers/shared.ts +85 -17
  329. package/src/daemon/handlers/skills.ts +416 -209
  330. package/src/daemon/lifecycle.ts +212 -131
  331. package/src/daemon/main.ts +5 -1
  332. package/src/daemon/message-types/conversations.ts +29 -7
  333. package/src/daemon/message-types/messages.ts +12 -2
  334. package/src/daemon/message-types/schedules.ts +1 -0
  335. package/src/daemon/message-types/settings.ts +6 -0
  336. package/src/daemon/message-types/skills.ts +97 -36
  337. package/src/daemon/profiler-run-store.ts +557 -0
  338. package/src/daemon/providers-setup.ts +5 -0
  339. package/src/daemon/server.ts +100 -11
  340. package/src/daemon/shutdown-handlers.ts +5 -0
  341. package/src/daemon/tool-side-effects.ts +50 -8
  342. package/src/export/transcript-formatter.ts +148 -0
  343. package/src/filing/filing-service.ts +228 -0
  344. package/src/heartbeat/heartbeat-service.ts +97 -7
  345. package/src/hooks/cli.ts +2 -2
  346. package/src/hooks/runner.ts +15 -38
  347. package/src/inbound/platform-callback-registration.ts +14 -14
  348. package/src/mcp/client.ts +6 -0
  349. package/src/mcp/mcp-oauth-provider.ts +149 -27
  350. package/src/memory/admin.ts +42 -75
  351. package/src/memory/app-store.ts +69 -0
  352. package/src/memory/conversation-bootstrap.ts +3 -1
  353. package/src/memory/conversation-crud.ts +211 -288
  354. package/src/memory/conversation-group-migration.ts +157 -0
  355. package/src/memory/conversation-queries.ts +61 -13
  356. package/src/memory/conversation-title-service.ts +1 -0
  357. package/src/memory/db-init.ts +194 -361
  358. package/src/memory/embed.ts +73 -0
  359. package/src/memory/embedding-backend.ts +8 -14
  360. package/src/memory/embedding-runtime-manager.ts +12 -114
  361. package/src/memory/fingerprint.ts +2 -2
  362. package/src/memory/graph/bootstrap.ts +521 -0
  363. package/src/memory/graph/capability-seed.ts +449 -0
  364. package/src/memory/graph/consolidation.ts +725 -0
  365. package/src/memory/graph/conversation-graph-memory.ts +659 -0
  366. package/src/memory/graph/decay.test.ts +208 -0
  367. package/src/memory/graph/decay.ts +195 -0
  368. package/src/memory/graph/extraction-job.ts +74 -0
  369. package/src/memory/graph/extraction.test.ts +936 -0
  370. package/src/memory/graph/extraction.ts +1297 -0
  371. package/src/memory/graph/graph-memory-state-store.ts +37 -0
  372. package/src/memory/graph/graph-search.ts +280 -0
  373. package/src/memory/graph/image-ref-utils.ts +29 -0
  374. package/src/memory/graph/injection.test.ts +513 -0
  375. package/src/memory/graph/injection.ts +469 -0
  376. package/src/memory/graph/inspect.ts +543 -0
  377. package/src/memory/graph/narrative.ts +267 -0
  378. package/src/memory/graph/pattern-scan.ts +269 -0
  379. package/src/memory/graph/retriever.ts +1111 -0
  380. package/src/memory/graph/scoring.test.ts +548 -0
  381. package/src/memory/graph/scoring.ts +232 -0
  382. package/src/memory/graph/serendipity.ts +65 -0
  383. package/src/memory/graph/store.test.ts +1098 -0
  384. package/src/memory/graph/store.ts +838 -0
  385. package/src/memory/graph/tool-handlers.ts +301 -0
  386. package/src/memory/graph/tools.ts +97 -0
  387. package/src/memory/graph/triggers.test.ts +487 -0
  388. package/src/memory/graph/triggers.ts +223 -0
  389. package/src/memory/graph/types.ts +295 -0
  390. package/src/memory/group-crud.ts +191 -0
  391. package/src/memory/indexer.ts +37 -19
  392. package/src/memory/job-handlers/cleanup.ts +32 -42
  393. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  394. package/src/memory/job-handlers/embedding.ts +5 -31
  395. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  396. package/src/memory/job-handlers/summarization.ts +32 -17
  397. package/src/memory/job-utils.ts +1 -1
  398. package/src/memory/jobs-store.ts +21 -31
  399. package/src/memory/jobs-worker.ts +180 -129
  400. package/src/memory/llm-request-log-store.ts +96 -12
  401. package/src/memory/memory-recall-log-store.ts +49 -5
  402. package/src/memory/message-content.ts +1 -0
  403. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  404. package/src/memory/migrations/203-drop-memory-items-tables.ts +55 -0
  405. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  406. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  407. package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
  408. package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
  409. package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
  410. package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
  411. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
  412. package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
  413. package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
  414. package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
  415. package/src/memory/migrations/index.ts +12 -0
  416. package/src/memory/migrations/registry.ts +16 -0
  417. package/src/memory/qdrant-client.ts +44 -17
  418. package/src/memory/schema/conversations.ts +14 -0
  419. package/src/memory/schema/index.ts +1 -0
  420. package/src/memory/schema/infrastructure.ts +8 -1
  421. package/src/memory/schema/memory-core.ts +0 -51
  422. package/src/memory/schema/memory-graph.ts +154 -0
  423. package/src/memory/search/semantic.ts +47 -91
  424. package/src/memory/task-memory-cleanup.ts +58 -61
  425. package/src/messaging/providers/outlook/adapter.ts +8 -1
  426. package/src/messaging/providers/outlook/client.ts +299 -0
  427. package/src/messaging/providers/outlook/types.ts +118 -0
  428. package/src/notifications/adapters/macos.ts +1 -0
  429. package/src/notifications/copy-composer.ts +95 -0
  430. package/src/notifications/decision-engine.ts +35 -0
  431. package/src/notifications/signal.ts +16 -0
  432. package/src/oauth/seed-providers.ts +2 -1
  433. package/src/permissions/checker.ts +36 -4
  434. package/src/permissions/defaults.ts +4 -4
  435. package/src/permissions/permission-mode-store.ts +180 -0
  436. package/src/permissions/permission-mode.ts +31 -0
  437. package/src/permissions/workspace-policy.ts +10 -1
  438. package/src/playbooks/playbook-compiler.ts +19 -18
  439. package/src/playbooks/types.ts +4 -3
  440. package/src/prompts/system-prompt.ts +62 -36
  441. package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
  442. package/src/prompts/templates/BOOTSTRAP.md +70 -165
  443. package/src/prompts/templates/HEARTBEAT.md +3 -1
  444. package/src/prompts/templates/SOUL.md +25 -4
  445. package/src/prompts/templates/UPDATES.md +8 -0
  446. package/src/providers/anthropic/client.ts +136 -220
  447. package/src/providers/gemini/client.ts +1 -1
  448. package/src/providers/openai/client.ts +1 -1
  449. package/src/providers/registry.ts +1 -1
  450. package/src/providers/retry.ts +19 -3
  451. package/src/runtime/actor-trust-resolver.ts +5 -1
  452. package/src/runtime/auth/route-policy.ts +30 -0
  453. package/src/runtime/guardian-reply-router.ts +5 -1
  454. package/src/runtime/http-server.ts +55 -5
  455. package/src/runtime/http-types.ts +12 -1
  456. package/src/runtime/middleware/auth.ts +20 -0
  457. package/src/runtime/migrations/vbundle-builder.ts +389 -3
  458. package/src/runtime/migrations/vbundle-importer.ts +8 -6
  459. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
  460. package/src/runtime/routes/app-management-routes.ts +1 -11
  461. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
  462. package/src/runtime/routes/archive-utils.ts +29 -0
  463. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  464. package/src/runtime/routes/attachment-routes.ts +106 -16
  465. package/src/runtime/routes/avatar-routes.ts +2 -9
  466. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  467. package/src/runtime/routes/btw-routes.ts +22 -1
  468. package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
  469. package/src/runtime/routes/conversation-management-routes.ts +3 -14
  470. package/src/runtime/routes/conversation-query-routes.ts +49 -3
  471. package/src/runtime/routes/conversation-routes.ts +264 -44
  472. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  473. package/src/runtime/routes/debug-routes.ts +1 -1
  474. package/src/runtime/routes/global-search-routes.ts +21 -19
  475. package/src/runtime/routes/group-routes.ts +207 -0
  476. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  477. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  478. package/src/runtime/routes/heartbeat-routes.ts +4 -10
  479. package/src/runtime/routes/identity-routes.ts +53 -18
  480. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  481. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  482. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  483. package/src/runtime/routes/llm-context-normalization.ts +14 -10
  484. package/src/runtime/routes/log-export-routes.ts +23 -275
  485. package/src/runtime/routes/memory-item-routes.test.ts +170 -247
  486. package/src/runtime/routes/memory-item-routes.ts +341 -388
  487. package/src/runtime/routes/migration-routes.ts +18 -7
  488. package/src/runtime/routes/profiler-routes.ts +350 -0
  489. package/src/runtime/routes/schedule-routes.ts +28 -11
  490. package/src/runtime/routes/settings-routes.ts +95 -8
  491. package/src/runtime/routes/skills-routes.ts +103 -37
  492. package/src/runtime/routes/subagents-routes.ts +28 -7
  493. package/src/runtime/routes/user-route-dispatcher.ts +223 -0
  494. package/src/runtime/routes/user-routes.ts +41 -0
  495. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  496. package/src/runtime/routes/workspace-routes.ts +0 -1
  497. package/src/schedule/schedule-store.ts +30 -0
  498. package/src/schedule/scheduler.ts +52 -18
  499. package/src/security/oauth2.ts +1 -1
  500. package/src/security/secure-keys.ts +4 -8
  501. package/src/shared/provider-env-vars.ts +19 -0
  502. package/src/skills/catalog-cache.ts +5 -0
  503. package/src/skills/catalog-install.ts +25 -16
  504. package/src/skills/clawhub.ts +134 -154
  505. package/src/skills/install-meta.ts +208 -0
  506. package/src/skills/managed-store.ts +29 -18
  507. package/src/skills/skill-memory.ts +12 -229
  508. package/src/skills/skillssh-registry.ts +19 -17
  509. package/src/subagent/index.ts +13 -3
  510. package/src/subagent/manager.ts +308 -29
  511. package/src/subagent/types.ts +68 -0
  512. package/src/tasks/task-runner.ts +7 -5
  513. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  514. package/src/tools/apps/executors.ts +29 -4
  515. package/src/tools/browser/runtime-check.ts +3 -1
  516. package/src/tools/filesystem/list.ts +93 -0
  517. package/src/tools/memory/register.ts +63 -46
  518. package/src/tools/permission-checker.ts +85 -1
  519. package/src/tools/registry.ts +4 -0
  520. package/src/tools/schedule/create.ts +3 -0
  521. package/src/tools/schedule/list.ts +1 -0
  522. package/src/tools/schedule/update.ts +6 -0
  523. package/src/tools/shared/filesystem/errors.ts +5 -0
  524. package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
  525. package/src/tools/shared/filesystem/image-read.ts +22 -85
  526. package/src/tools/shared/filesystem/types.ts +17 -0
  527. package/src/tools/shared/shell-output.ts +31 -2
  528. package/src/tools/subagent/abort.ts +12 -2
  529. package/src/tools/subagent/message.ts +9 -2
  530. package/src/tools/subagent/notify-parent.ts +79 -0
  531. package/src/tools/subagent/read.ts +29 -8
  532. package/src/tools/subagent/resolve.ts +21 -0
  533. package/src/tools/subagent/spawn.ts +2 -0
  534. package/src/tools/subagent/status.ts +11 -1
  535. package/src/tools/system/avatar-generator.ts +3 -3
  536. package/src/tools/system/register.ts +23 -0
  537. package/src/tools/system/set-permission-mode.ts +103 -0
  538. package/src/tools/terminal/parser.ts +30 -5
  539. package/src/tools/terminal/safe-env.ts +17 -1
  540. package/src/tools/tool-manifest.ts +9 -3
  541. package/src/tools/types.ts +2 -0
  542. package/src/util/browser.ts +25 -10
  543. package/src/util/bun-runtime.ts +172 -0
  544. package/src/util/logger.ts +1 -1
  545. package/src/util/platform.ts +50 -17
  546. package/src/watcher/providers/outlook-calendar.ts +343 -0
  547. package/src/watcher/providers/outlook.ts +198 -0
  548. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
  549. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
  550. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  551. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  552. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  553. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
  554. package/src/workspace/migrations/029-seed-pkb.ts +84 -0
  555. package/src/workspace/migrations/registry.ts +10 -0
  556. package/src/workspace/top-level-renderer.ts +5 -9
  557. package/src/__tests__/cli-memory.test.ts +0 -372
  558. package/src/__tests__/clipboard.test.ts +0 -88
  559. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  560. package/src/__tests__/journal-context.test.ts +0 -268
  561. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  562. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  563. package/src/__tests__/memory-query-builder.test.ts +0 -59
  564. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  565. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  566. package/src/__tests__/memory-regressions.test.ts +0 -3696
  567. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  568. package/src/cli/cli-memory.ts +0 -176
  569. package/src/daemon/conversation-memory.ts +0 -207
  570. package/src/memory/conversation-starters-cadence.ts +0 -74
  571. package/src/memory/items-extractor.ts +0 -860
  572. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  573. package/src/memory/job-handlers/extraction.ts +0 -40
  574. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  575. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  576. package/src/memory/journal-memory.ts +0 -224
  577. package/src/memory/query-builder.ts +0 -47
  578. package/src/memory/query-expansion.ts +0 -83
  579. package/src/memory/retriever.test.ts +0 -1592
  580. package/src/memory/retriever.ts +0 -1331
  581. package/src/memory/search/formatting.test.ts +0 -140
  582. package/src/memory/search/formatting.ts +0 -262
  583. package/src/memory/search/mmr.ts +0 -139
  584. package/src/memory/search/ranking.ts +0 -15
  585. package/src/memory/search/staleness.ts +0 -40
  586. package/src/memory/search/tier-classifier.ts +0 -18
  587. package/src/memory/search/types.ts +0 -121
  588. package/src/prompts/journal-context.ts +0 -154
  589. package/src/tools/memory/definitions.ts +0 -69
  590. package/src/tools/memory/handlers.test.ts +0 -562
  591. package/src/tools/memory/handlers.ts +0 -434
  592. package/src/util/clipboard.ts +0 -34
@@ -3,6 +3,9 @@ import { join } from "node:path";
3
3
 
4
4
  import type { Command } from "commander";
5
5
 
6
+ import { getConfig } from "../../config/loader.js";
7
+ import { resolveSkillStates } from "../../config/skill-state.js";
8
+ import { loadSkillCatalog } from "../../config/skills.js";
6
9
  import type { CatalogSkill } from "../../skills/catalog-install.js";
7
10
  import {
8
11
  fetchCatalog,
@@ -12,6 +15,7 @@ import {
12
15
  uninstallSkillLocally,
13
16
  } from "../../skills/catalog-install.js";
14
17
  import { filterByQuery } from "../../skills/catalog-search.js";
18
+ import { clawhubSearch } from "../../skills/clawhub.js";
15
19
  import type {
16
20
  AuditResponse,
17
21
  SkillsShSearchResult,
@@ -55,13 +59,13 @@ Examples:
55
59
 
56
60
  skills
57
61
  .command("list")
58
- .description("List available catalog skills")
62
+ .description("List all skills (bundled, installed, and catalog)")
59
63
  .option("--json", "Machine-readable JSON output")
60
64
  .addHelpText(
61
65
  "after",
62
66
  `
63
- Lists all skills available in the Vellum catalog with their ID, name,
64
- description, and dependency information.
67
+ Lists all skills: bundled (compiled-in), installed (user-added), and
68
+ available catalog skills with their ID, name, and description.
65
69
 
66
70
  Examples:
67
71
  $ assistant skills list
@@ -69,34 +73,103 @@ Examples:
69
73
  )
70
74
  .action(async (opts: { json?: boolean }) => {
71
75
  try {
72
- // In dev mode, use the local catalog as the source of truth
73
- // and skip the remote Platform API entirely.
76
+ // ── Bundled + installed skills (from loadSkillCatalog) ────────
77
+ const localCatalog = loadSkillCatalog();
78
+ const config = getConfig();
79
+ const resolved = resolveSkillStates(localCatalog, config);
80
+ const bundled = resolved.filter(
81
+ (r) => r.summary.source === "bundled",
82
+ );
83
+ const installed = resolved.filter(
84
+ (r) =>
85
+ r.summary.source === "managed" ||
86
+ r.summary.source === "workspace" ||
87
+ r.summary.source === "extra",
88
+ );
89
+
90
+ // ── Remote catalog skills ────────────────────────────────────
74
91
  const repoSkillsDir = getRepoSkillsDir();
75
- let catalog: CatalogSkill[];
92
+ let remoteCatalog: CatalogSkill[];
76
93
  if (repoSkillsDir) {
77
- catalog = readLocalCatalog(repoSkillsDir);
94
+ remoteCatalog = readLocalCatalog(repoSkillsDir);
78
95
  } else {
79
- catalog = await fetchCatalog();
96
+ remoteCatalog = await fetchCatalog();
80
97
  }
98
+ // Exclude catalog skills that are already installed/bundled
99
+ const localIds = new Set(localCatalog.map((s) => s.id));
100
+ const availableCatalog = remoteCatalog.filter(
101
+ (s) => !localIds.has(s.id),
102
+ );
103
+
104
+ const totalCount =
105
+ bundled.length + installed.length + availableCatalog.length;
81
106
 
82
107
  if (opts.json) {
83
- console.log(JSON.stringify({ ok: true, skills: catalog }));
108
+ const bundledJson = bundled.map((r) => ({
109
+ id: r.summary.id,
110
+ name: r.summary.displayName,
111
+ description: r.summary.description,
112
+ emoji: r.summary.emoji,
113
+ state: r.state,
114
+ }));
115
+ const installedJson = installed.map((r) => ({
116
+ id: r.summary.id,
117
+ name: r.summary.displayName,
118
+ description: r.summary.description,
119
+ emoji: r.summary.emoji,
120
+ state: r.state,
121
+ }));
122
+ console.log(
123
+ JSON.stringify({
124
+ ok: true,
125
+ skills: [...bundledJson, ...installedJson, ...availableCatalog],
126
+ bundled: bundledJson,
127
+ installed: installedJson,
128
+ catalog: availableCatalog,
129
+ }),
130
+ );
84
131
  return;
85
132
  }
86
133
 
87
- if (catalog.length === 0) {
88
- log.info("No skills available in the catalog.");
134
+ if (totalCount === 0) {
135
+ log.info("No skills available.");
89
136
  return;
90
137
  }
91
138
 
92
- log.info(`Available skills (${catalog.length}):\n`);
93
- for (const s of catalog) {
94
- const emoji = s.emoji ? `${s.emoji} ` : "";
95
- const deps = s.includes?.length
96
- ? ` (requires: ${s.includes.join(", ")})`
97
- : "";
98
- log.info(` ${emoji}${s.id}`);
99
- log.info(` ${s.name} — ${s.description}${deps}`);
139
+ if (bundled.length > 0) {
140
+ log.info(`Bundled skills (${bundled.length}):\n`);
141
+ for (const r of bundled) {
142
+ const s = r.summary;
143
+ const emoji = s.emoji ? `${s.emoji} ` : "";
144
+ const state = r.state === "disabled" ? " [disabled]" : "";
145
+ log.info(` ${emoji}${s.id}${state}`);
146
+ log.info(` ${s.displayName} — ${s.description}`);
147
+ }
148
+ log.info("");
149
+ }
150
+
151
+ if (installed.length > 0) {
152
+ log.info(`Installed skills (${installed.length}):\n`);
153
+ for (const r of installed) {
154
+ const s = r.summary;
155
+ const emoji = s.emoji ? `${s.emoji} ` : "";
156
+ const state = r.state === "disabled" ? " [disabled]" : "";
157
+ log.info(` ${emoji}${s.id}${state}`);
158
+ log.info(` ${s.displayName} — ${s.description}`);
159
+ }
160
+ log.info("");
161
+ }
162
+
163
+ if (availableCatalog.length > 0) {
164
+ log.info(`Available catalog skills (${availableCatalog.length}):\n`);
165
+ for (const s of availableCatalog) {
166
+ const emoji = s.emoji ? `${s.emoji} ` : "";
167
+ const deps = s.includes?.length
168
+ ? ` (requires: ${s.includes.join(", ")})`
169
+ : "";
170
+ log.info(` ${emoji}${s.id}`);
171
+ log.info(` ${s.name} — ${s.description}${deps}`);
172
+ }
100
173
  }
101
174
  } catch (err) {
102
175
  const msg = err instanceof Error ? err.message : String(err);
@@ -111,7 +184,9 @@ Examples:
111
184
 
112
185
  skills
113
186
  .command("search <query>")
114
- .description("Search the Vellum catalog and skills.sh community registry")
187
+ .description(
188
+ "Search the Vellum catalog, skills.sh, and clawhub community registries",
189
+ )
115
190
  .option("--limit <n>", "Maximum number of community results", "10")
116
191
  .option("--json", "Machine-readable JSON output")
117
192
  .addHelpText(
@@ -119,11 +194,11 @@ Examples:
119
194
  `
120
195
  Arguments:
121
196
  query Free-text search term matched against skill names, descriptions,
122
- and tags. Searches the Vellum catalog first, then the skills.sh
123
- community registry.
197
+ and tags. Searches the Vellum catalog, the skills.sh community
198
+ registry, and the clawhub registry.
124
199
 
125
- Displays results from both sources with clear labels. When a skill ID
126
- exists in both the Vellum catalog and the community registry, a conflict
200
+ Displays results from all sources with clear labels. When a skill ID
201
+ exists in both the Vellum catalog and a community registry, a conflict
127
202
  note is shown with guidance on which install command to use.
128
203
 
129
204
  Examples:
@@ -136,6 +211,14 @@ Examples:
136
211
  const limit = parseInt(opts.limit, 10) || 10;
137
212
 
138
213
  try {
214
+ // ── Bundled + installed skill search ─────────────────────────
215
+ const localCatalog = loadSkillCatalog();
216
+ const bundledMatches = filterByQuery(localCatalog, query, [
217
+ (s) => s.id,
218
+ (s) => s.displayName,
219
+ (s) => s.description,
220
+ ]);
221
+
139
222
  // ── Vellum catalog search ────────────────────────────────────
140
223
  const repoSkillsDir = getRepoSkillsDir();
141
224
  let catalog: CatalogSkill[];
@@ -148,39 +231,76 @@ Examples:
148
231
  catalog = [];
149
232
  }
150
233
  }
234
+ // Exclude catalog entries that match a bundled/installed skill
235
+ const localIds = new Set(localCatalog.map((s) => s.id));
236
+ const filteredCatalog = catalog.filter((s) => !localIds.has(s.id));
151
237
 
152
- const catalogMatches = filterByQuery(catalog, query, [
238
+ const catalogMatches = filterByQuery(filteredCatalog, query, [
153
239
  (s) => s.id,
154
240
  (s) => s.name,
155
241
  (s) => s.description,
156
242
  ]);
157
243
 
158
- // ── Community registry search (non-fatal on failure) ─────────
244
+ // ── Community registry searches (non-fatal on failure) ────────
245
+ // Run skills.sh and clawhub searches in parallel.
159
246
  let registryResults: SkillsShSearchResult[] = [];
160
247
  let registryError: string | undefined;
161
- try {
162
- registryResults = await searchSkillsRegistry(query, limit);
163
- } catch (err) {
164
- registryError = err instanceof Error ? err.message : String(err);
248
+ let clawhubResults: Awaited<
249
+ ReturnType<typeof clawhubSearch>
250
+ >["skills"] = [];
251
+ let clawhubError: string | undefined;
252
+
253
+ const [skillsShResult, clawhubResult] = await Promise.allSettled([
254
+ searchSkillsRegistry(query, limit),
255
+ clawhubSearch(query, { limit }),
256
+ ]);
257
+
258
+ if (skillsShResult.status === "fulfilled") {
259
+ registryResults = skillsShResult.value;
260
+ } else {
261
+ registryError =
262
+ skillsShResult.reason instanceof Error
263
+ ? skillsShResult.reason.message
264
+ : String(skillsShResult.reason);
265
+ }
266
+
267
+ if (clawhubResult.status === "fulfilled") {
268
+ clawhubResults = clawhubResult.value.skills;
269
+ } else {
270
+ clawhubError =
271
+ clawhubResult.reason instanceof Error
272
+ ? clawhubResult.reason.message
273
+ : String(clawhubResult.reason);
165
274
  }
166
275
 
167
276
  // ── Conflict detection ───────────────────────────────────────
168
277
  const catalogIds = new Set(catalogMatches.map((s) => s.id));
169
- const conflictIds = new Set(
170
- registryResults
278
+ const conflictIds = new Set([
279
+ ...registryResults
171
280
  .filter((r) => catalogIds.has(r.skillId))
172
281
  .map((r) => r.skillId),
173
- );
282
+ ...clawhubResults
283
+ .filter((r) => catalogIds.has(r.slug))
284
+ .map((r) => r.slug),
285
+ ]);
174
286
 
175
- if (catalogMatches.length === 0 && registryResults.length === 0) {
287
+ if (
288
+ bundledMatches.length === 0 &&
289
+ catalogMatches.length === 0 &&
290
+ registryResults.length === 0 &&
291
+ clawhubResults.length === 0
292
+ ) {
176
293
  if (json) {
177
294
  console.log(
178
295
  JSON.stringify({
179
296
  ok: true,
297
+ bundled: [],
180
298
  catalog: [],
181
299
  community: [],
300
+ clawhub: [],
182
301
  audits: {},
183
302
  ...(registryError ? { registryError } : {}),
303
+ ...(clawhubError ? { clawhubError } : {}),
184
304
  }),
185
305
  );
186
306
  } else {
@@ -188,6 +308,9 @@ Examples:
188
308
  if (registryError) {
189
309
  log.warn(`(skills.sh registry unavailable: ${registryError})`);
190
310
  }
311
+ if (clawhubError) {
312
+ log.warn(`(clawhub registry unavailable: ${clawhubError})`);
313
+ }
191
314
  }
192
315
  return;
193
316
  }
@@ -217,10 +340,19 @@ Examples:
217
340
  console.log(
218
341
  JSON.stringify({
219
342
  ok: true,
343
+ bundled: bundledMatches.map((s) => ({
344
+ id: s.id,
345
+ name: s.displayName,
346
+ description: s.description,
347
+ emoji: s.emoji,
348
+ source: s.source,
349
+ })),
220
350
  catalog: catalogMatches,
221
351
  community: registryResults,
352
+ clawhub: clawhubResults,
222
353
  audits: allAudits,
223
354
  ...(registryError ? { registryError } : {}),
355
+ ...(clawhubError ? { clawhubError } : {}),
224
356
  }),
225
357
  );
226
358
  return;
@@ -231,6 +363,24 @@ Examples:
231
363
  const isInstalled = (id: string) =>
232
364
  existsSync(join(skillsDir, id, "SKILL.md"));
233
365
 
366
+ // ── Display bundled/installed results ─────────────────────────
367
+ if (bundledMatches.length > 0) {
368
+ log.info(
369
+ `Bundled & installed skills (${bundledMatches.length}):\n`,
370
+ );
371
+ for (const s of bundledMatches) {
372
+ const emoji = s.emoji ? `${s.emoji} ` : "";
373
+ const tag = s.source === "bundled" ? " [bundled]" : " [installed]";
374
+ log.info(` ${emoji}${s.displayName}${tag}`);
375
+ if (s.displayName !== s.id) {
376
+ log.info(` ID: ${s.id}`);
377
+ }
378
+ log.info(` ${s.description}`);
379
+ log.info(` Load: skill_load skill=${s.id}`);
380
+ log.info("");
381
+ }
382
+ }
383
+
234
384
  // ── Display catalog results ──────────────────────────────────
235
385
  if (catalogMatches.length > 0) {
236
386
  log.info(`Vellum catalog (${catalogMatches.length}):\n`);
@@ -280,6 +430,38 @@ Examples:
280
430
  } else if (registryError) {
281
431
  log.warn(`\n(skills.sh registry unavailable: ${registryError})`);
282
432
  }
433
+
434
+ // ── Display clawhub results ─────────────────────────────────
435
+ if (clawhubResults.length > 0) {
436
+ log.info(`Clawhub registry (${clawhubResults.length}):\n`);
437
+ for (const r of clawhubResults) {
438
+ const installed = isInstalled(r.slug);
439
+ const badge = installed ? " [installed]" : "";
440
+ log.info(` ${r.name}${badge}`);
441
+ if (r.name !== r.slug) {
442
+ log.info(` ID: ${r.slug}`);
443
+ }
444
+ if (r.author) {
445
+ log.info(` Author: ${r.author}`);
446
+ }
447
+ if (r.description) {
448
+ log.info(` Description: ${r.description}`);
449
+ }
450
+ if (r.stars > 0) {
451
+ log.info(` Stars: ${r.stars}`);
452
+ }
453
+ if (r.installs > 0) {
454
+ log.info(` Installs: ${r.installs}`);
455
+ }
456
+ log.info(` Install: npx clawhub install ${r.slug}`);
457
+ if (conflictIds.has(r.slug)) {
458
+ log.info(` NOTE: Conflicts with Vellum catalog skill`);
459
+ }
460
+ log.info("");
461
+ }
462
+ } else if (clawhubError) {
463
+ log.warn(`\n(clawhub registry unavailable: ${clawhubError})`);
464
+ }
283
465
  } catch (err) {
284
466
  const msg = err instanceof Error ? err.message : String(err);
285
467
  if (json) {
@@ -416,8 +598,8 @@ Arguments:
416
598
 
417
599
  Notes:
418
600
  Fetches the skill's SKILL.md and supporting files from the specified GitHub
419
- repository and installs them into the workspace skills directory. A
420
- version.json file is written with origin metadata for provenance tracking.
601
+ repository and installs them into the workspace skills directory. An
602
+ install-meta.json file is written with origin metadata for provenance tracking.
421
603
 
422
604
  Examples:
423
605
  $ assistant skills add vercel-labs/skills@find-skills
@@ -18,7 +18,7 @@ export function registerTrustCommand(program: Command): void {
18
18
  Trust rules are pattern-based decisions (allow/deny) for tool invocations.
19
19
  Each rule specifies a tool name, a command pattern matched with glob syntax,
20
20
  a scope, a decision (allow or deny), and a priority. Rules are stored in
21
- ~/.vellum/protected/trust.json and evaluated in priority order when the
21
+ the protected directory (trust.json) and evaluated in priority order when the
22
22
  assistant invokes a tool.
23
23
 
24
24
  Examples:
@@ -141,7 +141,7 @@ Examples:
141
141
  .addHelpText(
142
142
  "after",
143
143
  `
144
- Removes every trust rule from ~/.vellum/protected/trust.json. Prompts for
144
+ Removes every trust rule from the protected directory (trust.json). Prompts for
145
145
  confirmation before proceeding (y/N). This action is irreversible — all
146
146
  rules must be re-created manually after clearing.
147
147
 
@@ -7,7 +7,6 @@
7
7
  * (health check, JWT minting, HTTP call).
8
8
  */
9
9
 
10
- import providerEnvVarsRegistry from "../../../../meta/provider-env-vars.json" with { type: "json" };
11
10
  import { getRuntimeHttpHost, getRuntimeHttpPort } from "../../config/env.js";
12
11
  import { API_KEY_PROVIDERS } from "../../config/loader.js";
13
12
  import { healthCheckHost, isHttpHealthy } from "../../daemon/daemon-control.js";
@@ -25,13 +24,13 @@ import {
25
24
  getSecureKeyResultAsync,
26
25
  setSecureKeyAsync,
27
26
  } from "../../security/secure-keys.js";
27
+ import { PROVIDER_ENV_VAR_NAMES } from "../../shared/provider-env-vars.js";
28
28
  import { getLogger } from "../../util/logger.js";
29
29
 
30
30
  const log = getLogger("daemon-credential-client");
31
31
  const CREDENTIAL_KEY_PREFIX = "credential/";
32
32
 
33
- const PROVIDER_ENV_VARS: Record<string, string> =
34
- providerEnvVarsRegistry.providers;
33
+ const PROVIDER_ENV_VARS: Record<string, string> = PROVIDER_ENV_VAR_NAMES;
35
34
 
36
35
  // ---------------------------------------------------------------------------
37
36
  // Private daemon fetch helper
@@ -26,6 +26,7 @@ import { registerMemoryCommand } from "./commands/memory.js";
26
26
  import { registerNotificationsCommand } from "./commands/notifications.js";
27
27
  import { registerOAuthCommand } from "./commands/oauth/index.js";
28
28
  import { registerPlatformCommand } from "./commands/platform/index.js";
29
+ import { registerRoutesCommand } from "./commands/routes.js";
29
30
  import { registerSequenceCommand } from "./commands/sequence.js";
30
31
  import { registerShotgunCommand } from "./commands/shotgun.js";
31
32
  import { registerSkillsCommand } from "./commands/skills.js";
@@ -75,6 +76,7 @@ Examples:
75
76
  registerNotificationsCommand(program);
76
77
  registerPlatformCommand(program);
77
78
  registerOAuthCommand(program);
79
+ registerRoutesCommand(program);
78
80
  registerSkillsCommand(program);
79
81
  registerBrowserRelayCommand(program);
80
82
  registerUsageCommand(program);
package/src/cli.ts CHANGED
@@ -33,11 +33,6 @@ import {
33
33
  type EventStreamWatcher,
34
34
  watchEventStream,
35
35
  } from "./signals/event-stream.js";
36
- import {
37
- copyToClipboard,
38
- extractLastCodeBlock,
39
- formatConversationForExport,
40
- } from "./util/clipboard.js";
41
36
  import { formatDiff, formatNewFileDiff } from "./util/diff.js";
42
37
  import { getHistoryPath, getSignalsDir } from "./util/platform.js";
43
38
  import { Spinner } from "./util/spinner.js";
@@ -143,7 +138,6 @@ export async function startCli(): Promise<void> {
143
138
  let conversationId = "";
144
139
  let pendingUserContent: string | null = null;
145
140
  let generating = false;
146
- let lastResponse = "";
147
141
  let lastUsage: {
148
142
  inputTokens: number;
149
143
  outputTokens: number;
@@ -153,7 +147,6 @@ export async function startCli(): Promise<void> {
153
147
  model: string;
154
148
  } | null = null;
155
149
  let pendingSessionPick = false;
156
- let pendingCopySession = false;
157
150
  let toolStreaming = false;
158
151
  let lastDisplayedError: string | null = null;
159
152
  let eventSubscription: EventStreamWatcher | null = null;
@@ -398,7 +391,6 @@ export async function startCli(): Promise<void> {
398
391
  if (pendingUserContent) {
399
392
  const content = pendingUserContent;
400
393
  pendingUserContent = null;
401
- lastResponse = "";
402
394
  sendUserMessage(content).then((result) => {
403
395
  if (result.ok) {
404
396
  generating = true;
@@ -408,7 +400,6 @@ export async function startCli(): Promise<void> {
408
400
  process.stdout.write(`${result.message}\n`);
409
401
  rl.question("Send anyway? (y/N): ", (answer) => {
410
402
  if (answer.trim().toLowerCase() === "y") {
411
- lastResponse = "";
412
403
  sendUserMessage(content, {
413
404
  bypassSecretCheck: true,
414
405
  }).then((retryResult) => {
@@ -439,7 +430,6 @@ export async function startCli(): Promise<void> {
439
430
 
440
431
  case "assistant_text_delta":
441
432
  spinner.stop();
442
- lastResponse += msg.text;
443
433
  process.stdout.write(msg.text);
444
434
  break;
445
435
 
@@ -595,9 +585,8 @@ export async function startCli(): Promise<void> {
595
585
  case "error":
596
586
  spinner.stop();
597
587
  generating = false;
598
- if (pendingSessionPick || pendingCopySession) {
588
+ if (pendingSessionPick) {
599
589
  pendingSessionPick = false;
600
- pendingCopySession = false;
601
590
  rl.removeAllListeners("line");
602
591
  rl.on("line", handleLine);
603
592
  }
@@ -646,26 +635,6 @@ export async function startCli(): Promise<void> {
646
635
  break;
647
636
 
648
637
  case "history_response":
649
- if (pendingCopySession) {
650
- pendingCopySession = false;
651
- if (msg.messages.length === 0) {
652
- process.stdout.write("\n No messages to copy.\n\n");
653
- } else {
654
- try {
655
- const formatted = formatConversationForExport(msg.messages);
656
- copyToClipboard(formatted);
657
- process.stdout.write(
658
- `\n Copied conversation (${msg.messages.length} messages) to clipboard.\n\n`,
659
- );
660
- } catch (err) {
661
- process.stdout.write(
662
- `\n Clipboard error: ${(err as Error).message}\n\n`,
663
- );
664
- }
665
- }
666
- prompt();
667
- break;
668
- }
669
638
  process.stdout.write("\n");
670
639
  if (msg.messages.length === 0) {
671
640
  process.stdout.write(" No messages in this conversation.\n");
@@ -686,7 +655,6 @@ export async function startCli(): Promise<void> {
686
655
  if (msg.removedCount === 0) {
687
656
  process.stdout.write("\n Nothing to undo.\n\n");
688
657
  } else {
689
- lastResponse = "";
690
658
  process.stdout.write(
691
659
  `\n Removed last exchange (${msg.removedCount} messages).\n\n`,
692
660
  );
@@ -754,21 +722,6 @@ export async function startCli(): Promise<void> {
754
722
  /* ignore */
755
723
  }
756
724
 
757
- if (content === "/copy") {
758
- if (!lastResponse) {
759
- process.stdout.write("No response to copy.\n");
760
- } else {
761
- try {
762
- copyToClipboard(lastResponse);
763
- process.stdout.write("Copied to clipboard.\n");
764
- } catch (err) {
765
- process.stdout.write(`Clipboard error: ${(err as Error).message}\n`);
766
- }
767
- }
768
- prompt();
769
- return;
770
- }
771
-
772
725
  if (content === "/conversations") {
773
726
  pendingSessionPick = true;
774
727
  try {
@@ -787,65 +740,6 @@ export async function startCli(): Promise<void> {
787
740
  return;
788
741
  }
789
742
 
790
- if (content === "/copy-code") {
791
- const code = extractLastCodeBlock(lastResponse);
792
- if (code == null) {
793
- process.stdout.write("No code block found.\n");
794
- } else {
795
- try {
796
- copyToClipboard(code);
797
- process.stdout.write("Copied code block to clipboard.\n");
798
- } catch (err) {
799
- process.stdout.write(`Clipboard error: ${(err as Error).message}\n`);
800
- }
801
- }
802
- prompt();
803
- return;
804
- }
805
-
806
- if (content === "/copy-conversation") {
807
- try {
808
- const mapping = getConversationByKey(conversationKey);
809
- if (!mapping) {
810
- process.stdout.write("\n No messages to copy.\n\n");
811
- prompt();
812
- return;
813
- }
814
- const rawMessages = getMessages(mapping.conversationId);
815
- if (rawMessages.length === 0) {
816
- process.stdout.write("\n No messages to copy.\n\n");
817
- } else {
818
- const rendered = rawMessages.map((msg) => {
819
- let parsedContent: unknown;
820
- try {
821
- parsedContent = JSON.parse(msg.content);
822
- } catch {
823
- parsedContent = msg.content;
824
- }
825
- return {
826
- role: msg.role as "user" | "assistant",
827
- text: renderHistoryContent(parsedContent).text,
828
- };
829
- });
830
- try {
831
- const formatted = formatConversationForExport(rendered);
832
- copyToClipboard(formatted);
833
- process.stdout.write(
834
- `\n Copied conversation (${rawMessages.length} messages) to clipboard.\n\n`,
835
- );
836
- } catch (err) {
837
- process.stdout.write(
838
- `\n Clipboard error: ${(err as Error).message}\n\n`,
839
- );
840
- }
841
- }
842
- } catch {
843
- process.stdout.write("[Failed to fetch history]\n");
844
- }
845
- prompt();
846
- return;
847
- }
848
-
849
743
  if (content === "/new") {
850
744
  // Create a new conversation by using a unique key
851
745
  conversationKey = `builtin-cli:${randomUUID()}`;
@@ -859,7 +753,6 @@ export async function startCli(): Promise<void> {
859
753
  }
860
754
 
861
755
  if (content === "/clear") {
862
- lastResponse = "";
863
756
  process.stdout.write("\x1b[r");
864
757
  process.stdout.write("\x1b[2J\x1b[H");
865
758
  mainScreenLayout = renderMainScreen();
@@ -955,7 +848,6 @@ export async function startCli(): Promise<void> {
955
848
  if (result.removedCount === 0) {
956
849
  process.stdout.write("\n Nothing to undo.\n\n");
957
850
  } else {
958
- lastResponse = "";
959
851
  process.stdout.write(
960
852
  `\n Removed last exchange (${result.removedCount} messages).\n\n`,
961
853
  );
@@ -1016,15 +908,6 @@ export async function startCli(): Promise<void> {
1016
908
  " /undo Remove last message exchange\n",
1017
909
  );
1018
910
  process.stdout.write(" /usage Show token usage and cost\n");
1019
- process.stdout.write(
1020
- " /copy Copy last response to clipboard\n",
1021
- );
1022
- process.stdout.write(
1023
- " /copy-code Copy last code block to clipboard\n",
1024
- );
1025
- process.stdout.write(
1026
- " /copy-conversation Copy entire conversation to clipboard\n",
1027
- );
1028
911
  process.stdout.write(" /help Show this help\n");
1029
912
  process.stdout.write("\n");
1030
913
  prompt();
@@ -1032,14 +915,12 @@ export async function startCli(): Promise<void> {
1032
915
  }
1033
916
 
1034
917
  // Regular user message
1035
- lastResponse = "";
1036
918
  sendUserMessage(content).then((result) => {
1037
919
  if (!result.ok) {
1038
920
  if (result.error === "secret_blocked" && result.message) {
1039
921
  process.stdout.write(`${result.message}\n`);
1040
922
  rl.question("Send anyway? (y/N): ", (answer) => {
1041
923
  if (answer.trim().toLowerCase() === "y") {
1042
- lastResponse = "";
1043
924
  sendUserMessage(content, { bypassSecretCheck: true }).then(
1044
925
  (retryResult) => {
1045
926
  if (retryResult.ok) {
@@ -5,7 +5,7 @@
5
5
  "name": "acp_spawn",
6
6
  "description": "Spawn an external coding agent (e.g. Claude Code, Codex, Gemini CLI) via ACP to work on a task. The agent runs as a subprocess and streams results back. Use this when you want to delegate a coding task to an external agent that has its own tools, file editing, and terminal access. If ACP is not enabled, follow the setup instructions in SKILL.md to install claude-agent-acp and configure it. The command MUST be 'claude-agent-acp' - NEVER use 'claude', 'claude -p', or 'claude --acp'.",
7
7
  "category": "orchestration",
8
- "risk": "low",
8
+ "risk": "high",
9
9
  "input_schema": {
10
10
  "type": "object",
11
11
  "properties": {