@vellumai/assistant 0.4.56 → 0.4.57

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 (450) hide show
  1. package/ARCHITECTURE.md +10 -10
  2. package/Dockerfile +3 -0
  3. package/README.md +11 -11
  4. package/docs/architecture/integrations.md +2 -2
  5. package/docs/architecture/memory.md +3 -4
  6. package/docs/credential-execution-service.md +13 -20
  7. package/node_modules/@vellumai/ces-contracts/src/error.ts +5 -4
  8. package/package.json +1 -1
  9. package/src/__tests__/actor-token-service.test.ts +7 -7
  10. package/src/__tests__/anthropic-provider.test.ts +172 -0
  11. package/src/__tests__/app-builder-tool-scripts.test.ts +15 -1
  12. package/src/__tests__/approval-cascade.test.ts +2 -2
  13. package/src/__tests__/approval-routes-http.test.ts +3 -4
  14. package/src/__tests__/asset-materialize-tool.test.ts +5 -5
  15. package/src/__tests__/asset-search-tool.test.ts +1 -1
  16. package/src/__tests__/assistant-attachments.test.ts +5 -5
  17. package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
  18. package/src/__tests__/assistant-feature-flags-integration.test.ts +50 -38
  19. package/src/__tests__/attachments-store.test.ts +2 -2
  20. package/src/__tests__/avatar-e2e.test.ts +5 -3
  21. package/src/__tests__/browser-skill-endstate.test.ts +0 -1
  22. package/src/__tests__/call-routes-http.test.ts +2 -2
  23. package/src/__tests__/callback-handoff-copy.test.ts +1 -1
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +158 -0
  25. package/src/__tests__/channel-readiness-routes.test.ts +0 -1
  26. package/src/__tests__/channel-readiness-service.test.ts +0 -1
  27. package/src/__tests__/checker.test.ts +31 -32
  28. package/src/__tests__/chrome-cdp.test.ts +47 -18
  29. package/src/__tests__/claude-code-skill-regression.test.ts +2 -2
  30. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  31. package/src/__tests__/config-schema.test.ts +9 -18
  32. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -4
  34. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -2
  35. package/src/__tests__/conversation-agent-loop.test.ts +11 -4
  36. package/src/__tests__/conversation-attachments.test.ts +1 -1
  37. package/src/__tests__/conversation-confirmation-signals.test.ts +2 -2
  38. package/src/__tests__/conversation-error.test.ts +33 -0
  39. package/src/__tests__/conversation-init.benchmark.test.ts +0 -1
  40. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  41. package/src/__tests__/conversation-pairing.test.ts +1 -1
  42. package/src/__tests__/conversation-pre-run-repair.test.ts +4 -4
  43. package/src/__tests__/conversation-provider-retry-repair.test.ts +4 -4
  44. package/src/__tests__/conversation-queue.test.ts +23 -14
  45. package/src/__tests__/conversation-routes-slash-commands.test.ts +3 -3
  46. package/src/__tests__/conversation-runtime-assembly.test.ts +185 -173
  47. package/src/__tests__/conversation-seed-composer.test.ts +1 -1
  48. package/src/__tests__/conversation-slash-queue.test.ts +4 -4
  49. package/src/__tests__/conversation-slash-unknown.test.ts +4 -4
  50. package/src/__tests__/conversation-starter-routes.test.ts +291 -0
  51. package/src/__tests__/conversation-wipe.test.ts +438 -0
  52. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -3
  53. package/src/__tests__/conversation-workspace-injection.test.ts +4 -5
  54. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -5
  55. package/src/__tests__/credential-security-e2e.test.ts +20 -0
  56. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  57. package/src/__tests__/credential-vault-unit.test.ts +227 -0
  58. package/src/__tests__/credentials-cli.test.ts +3 -0
  59. package/src/__tests__/date-context.test.ts +59 -377
  60. package/src/__tests__/drop-capability-card-state-migration.test.ts +169 -0
  61. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +11 -45
  62. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
  63. package/src/__tests__/encrypted-store.test.ts +237 -15
  64. package/src/__tests__/ephemeral-permissions.test.ts +4 -5
  65. package/src/__tests__/event-bus.test.ts +3 -3
  66. package/src/__tests__/gateway-only-enforcement.test.ts +2 -2
  67. package/src/__tests__/gateway-only-guard.test.ts +1 -0
  68. package/src/__tests__/gemini-image-service.test.ts +4 -4
  69. package/src/__tests__/gemini-provider.test.ts +6 -9
  70. package/src/__tests__/guardian-binding-drift-heal.test.ts +128 -0
  71. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  72. package/src/__tests__/host-shell-tool.test.ts +6 -6
  73. package/src/__tests__/http-user-message-parity.test.ts +2 -2
  74. package/src/__tests__/intent-routing.test.ts +51 -99
  75. package/src/__tests__/invite-routes-http.test.ts +5 -0
  76. package/src/__tests__/list-messages-attachments.test.ts +1 -1
  77. package/src/__tests__/managed-proxy-context.test.ts +2 -5
  78. package/src/__tests__/managed-skill-lifecycle.test.ts +8 -8
  79. package/src/__tests__/media-generate-image.test.ts +32 -15
  80. package/src/__tests__/media-reuse-story.e2e.test.ts +1 -1
  81. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +1 -1
  82. package/src/__tests__/memory-lifecycle-e2e.test.ts +24 -18
  83. package/src/__tests__/memory-recall-quality.test.ts +4 -3
  84. package/src/__tests__/memory-regressions.test.ts +86 -90
  85. package/src/__tests__/migration-cross-version-compatibility.test.ts +32 -32
  86. package/src/__tests__/migration-export-http.test.ts +26 -27
  87. package/src/__tests__/migration-import-commit-http.test.ts +165 -37
  88. package/src/__tests__/migration-import-preflight-http.test.ts +81 -20
  89. package/src/__tests__/migration-validate-http.test.ts +16 -16
  90. package/src/__tests__/model-intents.test.ts +1 -1
  91. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +1 -1
  92. package/src/__tests__/notification-broadcaster.test.ts +1 -1
  93. package/src/__tests__/notification-decision-fallback.test.ts +2 -2
  94. package/src/__tests__/notification-decision-identity.test.ts +8 -9
  95. package/src/__tests__/notification-decision-strategy.test.ts +1 -1
  96. package/src/__tests__/notification-deep-link.test.ts +1 -1
  97. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  98. package/src/__tests__/notification-schedule-dedup.test.ts +7 -7
  99. package/src/__tests__/oauth-store.test.ts +1 -3
  100. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -1
  101. package/src/__tests__/onboarding-template-contract.test.ts +23 -59
  102. package/src/__tests__/provider-error-scenarios.test.ts +154 -0
  103. package/src/__tests__/provider-fail-open-selection.test.ts +2 -2
  104. package/src/__tests__/provider-managed-proxy-integration.test.ts +8 -9
  105. package/src/__tests__/provider-registry-ollama.test.ts +5 -2
  106. package/src/__tests__/qdrant-manager.test.ts +7 -7
  107. package/src/__tests__/ratelimit.test.ts +0 -74
  108. package/src/__tests__/recording-handler.test.ts +0 -1
  109. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  110. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  111. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  112. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  113. package/src/__tests__/scheduler-recurrence.test.ts +46 -2
  114. package/src/__tests__/schema-transforms.test.ts +114 -54
  115. package/src/__tests__/secret-onetime-send.test.ts +20 -0
  116. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -2
  117. package/src/__tests__/secret-scanner-executor.test.ts +1 -2
  118. package/src/__tests__/send-endpoint-busy.test.ts +63 -4
  119. package/src/__tests__/send-notification-tool.test.ts +2 -2
  120. package/src/__tests__/shell-credential-ref.test.ts +0 -1
  121. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -2
  122. package/src/__tests__/skill-memory.test.ts +547 -0
  123. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -2
  124. package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -0
  125. package/src/__tests__/slack-channel-config.test.ts +109 -94
  126. package/src/__tests__/swarm-conversation-integration.test.ts +2 -2
  127. package/src/__tests__/swarm-recursion.test.ts +2 -2
  128. package/src/__tests__/swarm-tool.test.ts +2 -2
  129. package/src/__tests__/system-prompt.test.ts +19 -66
  130. package/src/__tests__/telegram-config.test.ts +121 -0
  131. package/src/__tests__/terminal-tools.test.ts +1 -1
  132. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -2
  133. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  134. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
  135. package/src/__tests__/tool-executor.test.ts +1 -1
  136. package/src/__tests__/trace-emitter.test.ts +8 -1
  137. package/src/__tests__/trust-store.test.ts +7 -8
  138. package/src/__tests__/twilio-routes.test.ts +1 -18
  139. package/src/__tests__/user-reference.test.ts +82 -2
  140. package/src/__tests__/vbundle-pax-and-symlink.test.ts +196 -0
  141. package/src/__tests__/verification-control-plane-policy.test.ts +1 -1
  142. package/src/approvals/guardian-request-resolvers.ts +3 -3
  143. package/src/avatar/ascii-renderer.ts +2 -2
  144. package/src/avatar/png-renderer.ts +2 -2
  145. package/src/avatar/resvg-lazy.ts +21 -0
  146. package/src/calls/guardian-dispatch.ts +1 -1
  147. package/src/calls/relay-access-wait.ts +2 -2
  148. package/src/calls/twilio-rest.ts +0 -248
  149. package/src/cli/AGENTS.md +5 -8
  150. package/src/cli/__tests__/notifications.test.ts +5 -5
  151. package/src/cli/commands/avatar.ts +64 -2
  152. package/src/cli/commands/conversations.ts +131 -1
  153. package/src/cli/commands/credentials.ts +2 -0
  154. package/src/cli/commands/notifications.ts +3 -3
  155. package/src/cli.ts +10 -0
  156. package/src/config/bundled-skills/acp/SKILL.md +5 -5
  157. package/src/config/bundled-skills/acp/TOOLS.json +6 -6
  158. package/src/config/bundled-skills/app-builder/SKILL.md +42 -42
  159. package/src/config/bundled-skills/app-builder/TOOLS.json +10 -10
  160. package/src/config/bundled-skills/browser/SKILL.md +15 -15
  161. package/src/config/bundled-skills/browser/TOOLS.json +14 -14
  162. package/src/config/bundled-skills/chatgpt-import/SKILL.md +2 -2
  163. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +1 -1
  164. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
  165. package/src/config/bundled-skills/claude-code/SKILL.md +5 -5
  166. package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
  167. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -15
  168. package/src/config/bundled-skills/contacts/SKILL.md +3 -3
  169. package/src/config/bundled-skills/contacts/TOOLS.json +4 -4
  170. package/src/config/bundled-skills/document/SKILL.md +4 -4
  171. package/src/config/bundled-skills/document/TOOLS.json +2 -2
  172. package/src/config/bundled-skills/followups/TOOLS.json +3 -3
  173. package/src/config/bundled-skills/gmail/SKILL.md +32 -32
  174. package/src/config/bundled-skills/gmail/TOOLS.json +16 -16
  175. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +1 -1
  176. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
  177. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -1
  178. package/src/config/bundled-skills/google-calendar/TOOLS.json +5 -5
  179. package/src/config/bundled-skills/google-calendar/types.ts +1 -1
  180. package/src/config/bundled-skills/heartbeat/SKILL.md +43 -0
  181. package/src/config/bundled-skills/image-studio/SKILL.md +3 -3
  182. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -3
  183. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +16 -12
  184. package/src/config/bundled-skills/media-processing/SKILL.md +40 -40
  185. package/src/config/bundled-skills/media-processing/TOOLS.json +8 -8
  186. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +2 -2
  187. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +1 -1
  188. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +5 -5
  189. package/src/config/bundled-skills/media-processing/services/gemini-video.ts +2 -2
  190. package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -2
  191. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -2
  192. package/src/config/bundled-skills/media-processing/services/reduce.ts +3 -3
  193. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
  194. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +1 -1
  195. package/src/config/bundled-skills/messaging/SKILL.md +29 -25
  196. package/src/config/bundled-skills/messaging/TOOLS.json +11 -11
  197. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +1 -1
  198. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
  199. package/src/config/bundled-skills/notifications/SKILL.md +3 -3
  200. package/src/config/bundled-skills/notifications/TOOLS.json +2 -2
  201. package/src/config/bundled-skills/notifications/tools/send-notification.ts +3 -3
  202. package/src/config/bundled-skills/orchestration/SKILL.md +1 -1
  203. package/src/config/bundled-skills/orchestration/TOOLS.json +1 -1
  204. package/src/config/bundled-skills/phone-calls/SKILL.md +18 -14
  205. package/src/config/bundled-skills/phone-calls/TOOLS.json +3 -3
  206. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +2 -2
  207. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +2 -2
  208. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +1 -1
  209. package/src/config/bundled-skills/playbooks/TOOLS.json +4 -4
  210. package/src/config/bundled-skills/schedule/SKILL.md +26 -26
  211. package/src/config/bundled-skills/schedule/TOOLS.json +5 -5
  212. package/src/config/bundled-skills/screen-watch/SKILL.md +3 -3
  213. package/src/config/bundled-skills/screen-watch/TOOLS.json +1 -1
  214. package/src/config/bundled-skills/sequences/SKILL.md +2 -2
  215. package/src/config/bundled-skills/sequences/TOOLS.json +10 -10
  216. package/src/config/bundled-skills/sequences/tools/sequence-analytics.ts +2 -2
  217. package/src/config/bundled-skills/sequences/tools/sequence-enroll.ts +2 -2
  218. package/src/config/bundled-skills/sequences/tools/sequence-enrollment-list.ts +1 -1
  219. package/src/config/bundled-skills/sequences/tools/sequence-get.ts +1 -1
  220. package/src/config/bundled-skills/sequences/tools/sequence-import.ts +3 -3
  221. package/src/config/bundled-skills/sequences/tools/sequence-list.ts +1 -1
  222. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +1 -1
  223. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  224. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
  225. package/src/config/bundled-skills/skill-management/TOOLS.json +5 -5
  226. package/src/config/bundled-skills/skills-catalog/SKILL.md +84 -0
  227. package/src/config/bundled-skills/slack/SKILL.md +2 -2
  228. package/src/config/bundled-skills/slack/TOOLS.json +8 -8
  229. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +3 -3
  230. package/src/config/bundled-skills/subagent/TOOLS.json +5 -5
  231. package/src/config/bundled-skills/tasks/SKILL.md +1 -1
  232. package/src/config/bundled-skills/tasks/TOOLS.json +9 -9
  233. package/src/config/bundled-skills/transcribe/SKILL.md +5 -5
  234. package/src/config/bundled-skills/transcribe/TOOLS.json +1 -1
  235. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +10 -10
  236. package/src/config/bundled-skills/watcher/SKILL.md +4 -4
  237. package/src/config/bundled-skills/watcher/TOOLS.json +5 -5
  238. package/src/config/feature-flag-registry.json +33 -17
  239. package/src/config/schemas/sandbox.ts +1 -1
  240. package/src/config/schemas/services.ts +13 -3
  241. package/src/config/schemas/timeouts.ts +0 -10
  242. package/src/contacts/contact-store.ts +63 -0
  243. package/src/contacts/contacts-write.ts +1 -1
  244. package/src/daemon/assistant-attachments.ts +2 -2
  245. package/src/daemon/conversation-agent-loop-handlers.ts +2 -2
  246. package/src/daemon/conversation-agent-loop.ts +7 -30
  247. package/src/daemon/conversation-error.ts +24 -0
  248. package/src/daemon/conversation-memory.ts +8 -7
  249. package/src/daemon/conversation-runtime-assembly.ts +139 -274
  250. package/src/daemon/conversation-slash.ts +7 -26
  251. package/src/daemon/conversation-surfaces.ts +14 -0
  252. package/src/daemon/conversation-tool-setup.ts +9 -8
  253. package/src/daemon/conversation.ts +2 -0
  254. package/src/daemon/daemon-control.ts +1 -1
  255. package/src/daemon/date-context.ts +10 -83
  256. package/src/daemon/handlers/config-channels.ts +12 -2
  257. package/src/daemon/handlers/config-slack-channel.ts +7 -1
  258. package/src/daemon/handlers/config-telegram.ts +6 -1
  259. package/src/daemon/handlers/conversations.ts +2 -2
  260. package/src/daemon/handlers/skills.ts +4 -0
  261. package/src/daemon/lifecycle.ts +28 -4
  262. package/src/daemon/providers-setup.ts +1 -1
  263. package/src/daemon/server.ts +1 -5
  264. package/src/daemon/shutdown-handlers.ts +9 -3
  265. package/src/daemon/tool-side-effects.ts +40 -0
  266. package/src/daemon/trace-emitter.ts +25 -2
  267. package/src/events/domain-events.ts +1 -1
  268. package/src/events/tool-permission-telemetry-listener.ts +46 -0
  269. package/src/inbound/platform-callback-registration.ts +0 -18
  270. package/src/media/app-icon-generator.ts +15 -8
  271. package/src/media/avatar-router.ts +15 -8
  272. package/src/media/gemini-image-service.ts +125 -21
  273. package/src/memory/attachments-store.ts +3 -3
  274. package/src/memory/channel-verification-sessions.ts +6 -6
  275. package/src/memory/conversation-crud.ts +196 -1
  276. package/src/memory/{thread-starters-cadence.ts → conversation-starters-cadence.ts} +9 -42
  277. package/src/memory/conversation-title-service.ts +2 -3
  278. package/src/memory/db-init.ts +25 -1
  279. package/src/memory/invite-store.ts +4 -4
  280. package/src/memory/items-extractor.ts +4 -4
  281. package/src/memory/job-handlers/{thread-starters.ts → conversation-starters.ts} +123 -38
  282. package/src/memory/jobs-store.ts +3 -2
  283. package/src/memory/jobs-worker.ts +7 -5
  284. package/src/memory/lifecycle-events-store.ts +63 -0
  285. package/src/memory/migrations/172-rename-created-by-session-id.ts +27 -0
  286. package/src/memory/migrations/173-rename-source-session-id.ts +16 -0
  287. package/src/memory/migrations/174-rename-thread-starters-table.ts +52 -0
  288. package/src/memory/migrations/175-create-lifecycle-events.ts +15 -0
  289. package/src/memory/migrations/176-drop-capability-card-state.ts +36 -0
  290. package/src/memory/migrations/177-create-trace-events-table.ts +40 -0
  291. package/src/memory/migrations/index.ts +6 -0
  292. package/src/memory/migrations/registry.ts +13 -0
  293. package/src/memory/retriever.test.ts +223 -96
  294. package/src/memory/retriever.ts +115 -138
  295. package/src/memory/schema/calls.ts +1 -1
  296. package/src/memory/schema/contacts.ts +1 -1
  297. package/src/memory/schema/infrastructure.ts +29 -0
  298. package/src/memory/schema/memory-core.ts +7 -17
  299. package/src/memory/schema/notifications.ts +1 -1
  300. package/src/memory/search/formatting.ts +23 -6
  301. package/src/memory/search/lexical.ts +2 -0
  302. package/src/memory/search/semantic.ts +2 -0
  303. package/src/memory/search/staleness.ts +1 -0
  304. package/src/memory/search/types.ts +4 -0
  305. package/src/memory/task-memory-cleanup.ts +96 -6
  306. package/src/memory/trace-event-store.ts +148 -0
  307. package/src/notifications/README.md +1 -1
  308. package/src/notifications/decision-engine.ts +2 -2
  309. package/src/notifications/emit-signal.ts +4 -4
  310. package/src/notifications/events-store.ts +4 -4
  311. package/src/notifications/signal.ts +1 -1
  312. package/src/oauth/manual-token-connection.ts +49 -25
  313. package/src/permissions/checker.ts +6 -5
  314. package/src/permissions/defaults.ts +4 -4
  315. package/src/prompts/__tests__/build-cli-reference-section.test.ts +9 -90
  316. package/src/prompts/cache-boundary.ts +8 -0
  317. package/src/prompts/system-prompt.ts +105 -634
  318. package/src/prompts/templates/BOOTSTRAP.md +166 -33
  319. package/src/prompts/templates/IDENTITY.md +8 -23
  320. package/src/prompts/templates/SOUL.md +20 -41
  321. package/src/prompts/templates/USER.md +3 -19
  322. package/src/prompts/user-reference.ts +14 -16
  323. package/src/providers/anthropic/client.ts +46 -2
  324. package/src/providers/gemini/client.ts +6 -9
  325. package/src/providers/managed-proxy/constants.ts +1 -7
  326. package/src/providers/managed-proxy/context.ts +0 -1
  327. package/src/providers/model-intents.ts +5 -5
  328. package/src/providers/openai/client.ts +10 -1
  329. package/src/providers/openrouter/client.ts +1 -0
  330. package/src/providers/ratelimit.ts +0 -35
  331. package/src/providers/registry.ts +3 -5
  332. package/src/providers/retry.ts +18 -1
  333. package/src/runtime/access-request-helper.ts +1 -1
  334. package/src/runtime/auth/route-policy.ts +7 -0
  335. package/src/runtime/channel-verification-service.ts +1 -1
  336. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  337. package/src/runtime/guardian-vellum-migration.ts +63 -1
  338. package/src/runtime/http-server.ts +8 -4
  339. package/src/runtime/migrations/vbundle-builder.ts +212 -32
  340. package/src/runtime/migrations/vbundle-import-analyzer.ts +74 -8
  341. package/src/runtime/migrations/vbundle-importer.ts +66 -1
  342. package/src/runtime/migrations/vbundle-validator.ts +17 -3
  343. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +4 -4
  344. package/src/runtime/routes/attachment-routes.ts +2 -2
  345. package/src/runtime/routes/btw-routes.ts +9 -0
  346. package/src/runtime/routes/channel-verification-routes.ts +19 -2
  347. package/src/runtime/routes/conversation-management-routes.ts +55 -1
  348. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  349. package/src/runtime/routes/conversation-routes.ts +49 -5
  350. package/src/runtime/routes/conversation-starter-routes.ts +207 -0
  351. package/src/runtime/routes/guardian-bootstrap-routes.ts +13 -9
  352. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -1
  353. package/src/runtime/routes/inbound-stages/verification-intercept.ts +1 -1
  354. package/src/runtime/routes/migration-routes.ts +25 -13
  355. package/src/runtime/routes/secret-routes.ts +18 -0
  356. package/src/runtime/routes/settings-routes.ts +8 -8
  357. package/src/runtime/routes/telemetry-routes.ts +53 -0
  358. package/src/runtime/routes/trace-event-routes.ts +62 -0
  359. package/src/runtime/tool-grant-request-helper.ts +1 -1
  360. package/src/runtime/verification-outbound-actions.ts +47 -31
  361. package/src/security/encrypted-store.ts +263 -78
  362. package/src/skills/catalog-install.ts +10 -0
  363. package/src/skills/managed-store.ts +2 -0
  364. package/src/skills/skill-memory.ts +220 -0
  365. package/src/subagent/manager.ts +1 -4
  366. package/src/telemetry/types.ts +10 -1
  367. package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
  368. package/src/telemetry/usage-telemetry-reporter.ts +51 -4
  369. package/src/tools/AGENTS.md +11 -11
  370. package/src/tools/acp/spawn.ts +1 -1
  371. package/src/tools/apps/executors.ts +8 -8
  372. package/src/tools/apps/registry.ts +1 -1
  373. package/src/tools/assets/materialize.ts +6 -6
  374. package/src/tools/assets/search.ts +10 -10
  375. package/src/tools/browser/__tests__/auth-cache.test.ts +2 -2
  376. package/src/tools/browser/__tests__/auth-detector.test.ts +4 -4
  377. package/src/tools/browser/auth-detector.ts +6 -6
  378. package/src/tools/browser/browser-execution.ts +13 -13
  379. package/src/tools/browser/browser-manager.ts +3 -3
  380. package/src/tools/browser/chrome-cdp.ts +5 -5
  381. package/src/tools/browser/jit-auth.ts +2 -2
  382. package/src/tools/browser/network-recorder.test.ts +2 -2
  383. package/src/tools/browser/network-recorder.ts +3 -3
  384. package/src/tools/browser/runtime-check.ts +3 -3
  385. package/src/tools/claude-code/claude-code.ts +2 -2
  386. package/src/tools/computer-use/definitions.ts +18 -18
  387. package/src/tools/credential-execution/make-authenticated-request.ts +4 -4
  388. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -3
  389. package/src/tools/credential-execution/run-authenticated-command.ts +4 -4
  390. package/src/tools/credentials/broker-types.ts +5 -5
  391. package/src/tools/credentials/broker.ts +15 -15
  392. package/src/tools/credentials/metadata-store.ts +2 -2
  393. package/src/tools/credentials/resolve.ts +1 -1
  394. package/src/tools/credentials/selection.ts +1 -1
  395. package/src/tools/credentials/tool-policy.ts +1 -1
  396. package/src/tools/credentials/vault.ts +115 -25
  397. package/src/tools/execution-target.ts +2 -2
  398. package/src/tools/executor.ts +7 -7
  399. package/src/tools/filesystem/edit.ts +2 -2
  400. package/src/tools/filesystem/read.ts +1 -1
  401. package/src/tools/filesystem/write.ts +1 -1
  402. package/src/tools/host-filesystem/edit.ts +2 -1
  403. package/src/tools/host-filesystem/read.ts +2 -1
  404. package/src/tools/host-filesystem/write.ts +1 -1
  405. package/src/tools/host-terminal/host-shell.ts +9 -8
  406. package/src/tools/mcp/mcp-tool-factory.ts +7 -6
  407. package/src/tools/memory/definitions.ts +6 -5
  408. package/src/tools/memory/handlers.test.ts +1 -1
  409. package/src/tools/network/__tests__/web-search.test.ts +3 -3
  410. package/src/tools/network/domain-normalize.ts +2 -2
  411. package/src/tools/network/script-proxy/session-manager.ts +10 -10
  412. package/src/tools/network/web-fetch.ts +1 -1
  413. package/src/tools/network/web-search.ts +3 -3
  414. package/src/tools/permission-checker.ts +8 -8
  415. package/src/tools/registry.ts +7 -7
  416. package/src/tools/schedule/list.ts +2 -2
  417. package/src/tools/schema-transforms.ts +31 -21
  418. package/src/tools/secret-detection-handler.ts +1 -1
  419. package/src/tools/sensitive-output-placeholders.ts +1 -1
  420. package/src/tools/shared/filesystem/edit-engine.ts +1 -1
  421. package/src/tools/shared/filesystem/file-ops-service.ts +3 -3
  422. package/src/tools/shared/filesystem/image-read.ts +25 -5
  423. package/src/tools/shared/filesystem/path-policy.ts +2 -2
  424. package/src/tools/shared/shell-output.ts +1 -1
  425. package/src/tools/side-effects.ts +1 -1
  426. package/src/tools/skills/execute.ts +1 -1
  427. package/src/tools/skills/load.ts +3 -3
  428. package/src/tools/skills/sandbox-runner.ts +3 -3
  429. package/src/tools/subagent/read.ts +1 -1
  430. package/src/tools/subagent/spawn.ts +2 -2
  431. package/src/tools/swarm/delegate.ts +3 -3
  432. package/src/tools/system/request-permission.ts +5 -4
  433. package/src/tools/terminal/backends/native.ts +4 -4
  434. package/src/tools/terminal/parser.ts +6 -6
  435. package/src/tools/terminal/sandbox-diagnostics.ts +1 -1
  436. package/src/tools/terminal/shell.ts +16 -16
  437. package/src/tools/tool-approval-handler.ts +21 -12
  438. package/src/tools/tool-manifest.ts +4 -4
  439. package/src/tools/types.ts +3 -3
  440. package/src/tools/ui-surface/definitions.ts +9 -37
  441. package/src/tools/watcher/list.ts +1 -1
  442. package/src/util/logger.ts +7 -2
  443. package/src/util/retry.ts +29 -1
  444. package/src/workspace/migrations/007-web-search-provider-rename.ts +37 -0
  445. package/src/workspace/migrations/registry.ts +2 -0
  446. package/src/__tests__/cli-help-reference-sync.test.ts +0 -26
  447. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -190
  448. package/src/cli/reference.ts +0 -38
  449. package/src/memory/job-handlers/capability-cards.ts +0 -420
  450. package/src/runtime/routes/thread-starter-routes.ts +0 -294
@@ -0,0 +1,220 @@
1
+ import { and, eq } from "drizzle-orm";
2
+ import { v4 as uuid } from "uuid";
3
+
4
+ import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
5
+ import { getConfig } from "../config/loader.js";
6
+ import { getDb } from "../memory/db.js";
7
+ import { computeMemoryFingerprint } from "../memory/fingerprint.js";
8
+ import { enqueueMemoryJob } from "../memory/jobs-store.js";
9
+ import { memoryItems } from "../memory/schema.js";
10
+ import { getLogger } from "../util/logger.js";
11
+ import { type CatalogSkill, resolveCatalog } from "./catalog-install.js";
12
+
13
+ const log = getLogger("skill-memory");
14
+
15
+ /**
16
+ * Build a semantically rich capability statement from a catalog skill entry.
17
+ * Truncated to 500 chars max (matching the limit used by memory item extraction).
18
+ */
19
+ export function buildCapabilityStatement(entry: CatalogSkill): string {
20
+ const displayName =
21
+ entry.metadata?.vellum?.["display-name"] ?? entry.name;
22
+ const activationHints = entry.metadata?.vellum?.["activation-hints"];
23
+
24
+ let statement = `The "${displayName}" skill (${entry.id}) is available. ${entry.description}.`;
25
+ if (activationHints && activationHints.length > 0) {
26
+ statement += ` Use when: ${activationHints.join("; ")}.`;
27
+ }
28
+
29
+ // Truncate to 500 chars max
30
+ if (statement.length > 500) {
31
+ statement = statement.slice(0, 500);
32
+ }
33
+
34
+ return statement;
35
+ }
36
+
37
+ /**
38
+ * Upsert a capability memory item for a catalog skill.
39
+ * Best-effort: errors are logged but never thrown.
40
+ */
41
+ export function upsertSkillCapabilityMemory(
42
+ skillId: string,
43
+ entry: CatalogSkill,
44
+ ): void {
45
+ try {
46
+ const db = getDb();
47
+ const subject = `skill:${skillId}`;
48
+ const statement = buildCapabilityStatement(entry);
49
+ const kind = "capability";
50
+ const scopeId = "default";
51
+ const confidence = 1.0;
52
+ const importance = 0.7;
53
+ const fingerprint = computeMemoryFingerprint(
54
+ scopeId,
55
+ kind,
56
+ subject,
57
+ statement,
58
+ );
59
+ const now = Date.now();
60
+
61
+ const existing = db
62
+ .select()
63
+ .from(memoryItems)
64
+ .where(
65
+ and(
66
+ eq(memoryItems.kind, kind),
67
+ eq(memoryItems.subject, subject),
68
+ eq(memoryItems.scopeId, scopeId),
69
+ ),
70
+ )
71
+ .get();
72
+
73
+ if (existing) {
74
+ if (existing.status === "active" && existing.fingerprint === fingerprint) {
75
+ // Same content — just touch lastSeenAt
76
+ db.update(memoryItems)
77
+ .set({ lastSeenAt: now })
78
+ .where(eq(memoryItems.id, existing.id))
79
+ .run();
80
+ return;
81
+ }
82
+
83
+ if (existing.status === "active") {
84
+ // Content changed — update statement and fingerprint
85
+ db.update(memoryItems)
86
+ .set({
87
+ statement,
88
+ fingerprint,
89
+ lastSeenAt: now,
90
+ })
91
+ .where(eq(memoryItems.id, existing.id))
92
+ .run();
93
+ enqueueMemoryJob("embed_item", { itemId: existing.id });
94
+ return;
95
+ }
96
+
97
+ // status === "deleted" or other — reactivate
98
+ db.update(memoryItems)
99
+ .set({
100
+ status: "active",
101
+ statement,
102
+ fingerprint,
103
+ lastSeenAt: now,
104
+ firstSeenAt: now,
105
+ })
106
+ .where(eq(memoryItems.id, existing.id))
107
+ .run();
108
+ enqueueMemoryJob("embed_item", { itemId: existing.id });
109
+ return;
110
+ }
111
+
112
+ // No existing — insert new row
113
+ const id = uuid();
114
+ db.insert(memoryItems)
115
+ .values({
116
+ id,
117
+ kind,
118
+ subject,
119
+ statement,
120
+ status: "active",
121
+ confidence,
122
+ importance,
123
+ fingerprint,
124
+ scopeId,
125
+ firstSeenAt: now,
126
+ lastSeenAt: now,
127
+ })
128
+ .run();
129
+ enqueueMemoryJob("embed_item", { itemId: id });
130
+ } catch (err) {
131
+ log.warn({ err, skillId }, "Failed to upsert skill capability memory");
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Soft-delete the capability memory item for a skill.
137
+ * Best-effort: errors are logged but never thrown.
138
+ */
139
+ export function deleteSkillCapabilityMemory(skillId: string): void {
140
+ try {
141
+ const db = getDb();
142
+ const subject = `skill:${skillId}`;
143
+ const now = Date.now();
144
+
145
+ const existing = db
146
+ .select()
147
+ .from(memoryItems)
148
+ .where(
149
+ and(
150
+ eq(memoryItems.kind, "capability"),
151
+ eq(memoryItems.subject, subject),
152
+ eq(memoryItems.scopeId, "default"),
153
+ ),
154
+ )
155
+ .get();
156
+
157
+ if (existing && existing.status !== "deleted") {
158
+ db.update(memoryItems)
159
+ .set({ status: "deleted", lastSeenAt: now })
160
+ .where(eq(memoryItems.id, existing.id))
161
+ .run();
162
+ }
163
+ } catch (err) {
164
+ log.warn({ err, skillId }, "Failed to delete skill capability memory");
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Seed capability memory items for all catalog skills.
170
+ * Prunes stale entries whose skills are no longer in the catalog.
171
+ * Best-effort: errors are logged but never thrown.
172
+ */
173
+ export async function seedCatalogSkillMemories(): Promise<void> {
174
+ try {
175
+ const catalog = await resolveCatalog();
176
+ const config = getConfig();
177
+ const catalogIds = new Set<string>();
178
+
179
+ for (const entry of catalog) {
180
+ // Skip skills whose feature flag is disabled
181
+ const flagId = entry.metadata?.vellum?.["feature-flag"];
182
+ if (flagId) {
183
+ const flagKey = `feature_flags.${flagId}.enabled`;
184
+ if (!isAssistantFeatureFlagEnabled(flagKey, config)) {
185
+ continue;
186
+ }
187
+ }
188
+
189
+ catalogIds.add(entry.id);
190
+ upsertSkillCapabilityMemory(entry.id, entry);
191
+ }
192
+
193
+ // Prune stale capability memories for skills no longer in catalog
194
+ const db = getDb();
195
+ const allCapabilities = db
196
+ .select()
197
+ .from(memoryItems)
198
+ .where(
199
+ and(
200
+ eq(memoryItems.kind, "capability"),
201
+ eq(memoryItems.scopeId, "default"),
202
+ eq(memoryItems.status, "active"),
203
+ ),
204
+ )
205
+ .all();
206
+
207
+ const now = Date.now();
208
+ for (const item of allCapabilities) {
209
+ const itemSkillId = item.subject.replace("skill:", "");
210
+ if (!catalogIds.has(itemSkillId)) {
211
+ db.update(memoryItems)
212
+ .set({ status: "deleted", lastSeenAt: now })
213
+ .where(eq(memoryItems.id, item.id))
214
+ .run();
215
+ }
216
+ }
217
+ } catch (err) {
218
+ log.warn({ err }, "Failed to seed catalog skill memories");
219
+ }
220
+ }
@@ -134,10 +134,7 @@ export class SubagentManager {
134
134
  appConfig.providerOrder,
135
135
  );
136
136
  const { rateLimit } = appConfig;
137
- if (
138
- rateLimit.maxRequestsPerMinute > 0 ||
139
- rateLimit.maxTokensPerSession > 0
140
- ) {
137
+ if (rateLimit.maxRequestsPerMinute > 0) {
141
138
  provider = new RateLimitProvider(
142
139
  provider,
143
140
  rateLimit,
@@ -22,5 +22,14 @@ export interface TurnTelemetryEvent extends TelemetryEventBase {
22
22
  type: "turn";
23
23
  }
24
24
 
25
+ /** Lifecycle event — app_open, hatch, etc. */
26
+ export interface LifecycleTelemetryEvent extends TelemetryEventBase {
27
+ type: "lifecycle";
28
+ event_name: string;
29
+ }
30
+
25
31
  /** Discriminated union of all telemetry event types. */
26
- export type TelemetryEvent = LlmUsageTelemetryEvent | TurnTelemetryEvent;
32
+ export type TelemetryEvent =
33
+ | LlmUsageTelemetryEvent
34
+ | TurnTelemetryEvent
35
+ | LifecycleTelemetryEvent;
@@ -193,7 +193,7 @@ describe("UsageTelemetryReporter", () => {
193
193
 
194
194
  expect(mockFetch).toHaveBeenCalledTimes(1);
195
195
  const [url, opts] = mockFetch.mock.calls[0] as [string, RequestInit];
196
- expect(url).toBe("https://test.vellum.ai/v1/assistants/telemetry/ingest/");
196
+ expect(url).toBe("https://test.vellum.ai/v1/telemetry/ingest/");
197
197
  expect((opts.headers as Record<string, string>)["Authorization"]).toBe(
198
198
  "Api-Key test-key",
199
199
  );
@@ -19,6 +19,7 @@ import {
19
19
  getMemoryCheckpoint,
20
20
  setMemoryCheckpoint,
21
21
  } from "../memory/checkpoints.js";
22
+ import { queryUnreportedLifecycleEvents } from "../memory/lifecycle-events-store.js";
22
23
  import { queryUnreportedUsageEvents } from "../memory/llm-usage-store.js";
23
24
  import { queryUnreportedTurnEvents } from "../memory/turn-events-store.js";
24
25
  import { resolveManagedProxyContext } from "../providers/managed-proxy/context.js";
@@ -37,10 +38,14 @@ const CHECKPOINT_KEY_WATERMARK = "telemetry:usage:last_reported_at";
37
38
  const CHECKPOINT_KEY_WATERMARK_ID = "telemetry:usage:last_reported_id";
38
39
  const CHECKPOINT_KEY_TURN_WATERMARK = "telemetry:turns:last_reported_at";
39
40
  const CHECKPOINT_KEY_TURN_WATERMARK_ID = "telemetry:turns:last_reported_id";
41
+ const CHECKPOINT_KEY_LIFECYCLE_WATERMARK =
42
+ "telemetry:lifecycle:last_reported_at";
43
+ const CHECKPOINT_KEY_LIFECYCLE_WATERMARK_ID =
44
+ "telemetry:lifecycle:last_reported_id";
40
45
  const REPORT_INTERVAL_MS = 5 * 60 * 1000;
41
46
  const BATCH_SIZE = 500;
42
47
  const MAX_CONSECUTIVE_BATCHES = 10;
43
- const TELEMETRY_PATH = "/v1/assistants/telemetry/ingest/";
48
+ const TELEMETRY_PATH = "/v1/telemetry/ingest/";
44
49
 
45
50
  // ---------------------------------------------------------------------------
46
51
  // Reporter
@@ -100,6 +105,13 @@ export class UsageTelemetryReporter {
100
105
  const turnWatermarkId =
101
106
  getMemoryCheckpoint(CHECKPOINT_KEY_TURN_WATERMARK_ID) ?? undefined;
102
107
 
108
+ // Read lifecycle watermark (compound cursor: createdAt + id)
109
+ const lifecycleWatermark = Number(
110
+ getMemoryCheckpoint(CHECKPOINT_KEY_LIFECYCLE_WATERMARK) ?? "0",
111
+ );
112
+ const lifecycleWatermarkId =
113
+ getMemoryCheckpoint(CHECKPOINT_KEY_LIFECYCLE_WATERMARK_ID) ?? undefined;
114
+
103
115
  // Query unreported events
104
116
  const events = queryUnreportedUsageEvents(
105
117
  watermark,
@@ -111,8 +123,18 @@ export class UsageTelemetryReporter {
111
123
  turnWatermarkId,
112
124
  BATCH_SIZE,
113
125
  );
126
+ const lifecycleEvents = queryUnreportedLifecycleEvents(
127
+ lifecycleWatermark,
128
+ lifecycleWatermarkId,
129
+ BATCH_SIZE,
130
+ );
114
131
 
115
- if (events.length === 0 && turnEvents.length === 0) return;
132
+ if (
133
+ events.length === 0 &&
134
+ turnEvents.length === 0 &&
135
+ lifecycleEvents.length === 0
136
+ )
137
+ return;
116
138
 
117
139
  // Resolve auth context — skip flush when neither auth mode is viable
118
140
  const proxyCtx = await resolveManagedProxyContext();
@@ -154,6 +176,14 @@ export class UsageTelemetryReporter {
154
176
  recorded_at: e.createdAt,
155
177
  }),
156
178
  ),
179
+ ...lifecycleEvents.map(
180
+ (e): TelemetryEvent => ({
181
+ type: "lifecycle",
182
+ daemon_event_id: e.id,
183
+ event_name: e.eventName,
184
+ recorded_at: e.createdAt,
185
+ }),
186
+ ),
157
187
  ];
158
188
 
159
189
  const assistantId = getExternalAssistantId() ?? "self";
@@ -207,8 +237,25 @@ export class UsageTelemetryReporter {
207
237
  setMemoryCheckpoint(CHECKPOINT_KEY_TURN_WATERMARK_ID, lastTurn.id);
208
238
  }
209
239
 
210
- // If we got a full batch of either type, there may be more — recurse
211
- if (events.length === BATCH_SIZE || turnEvents.length === BATCH_SIZE) {
240
+ // Advance lifecycle watermark (compound cursor)
241
+ if (lifecycleEvents.length > 0) {
242
+ const lastLifecycle = lifecycleEvents[lifecycleEvents.length - 1];
243
+ setMemoryCheckpoint(
244
+ CHECKPOINT_KEY_LIFECYCLE_WATERMARK,
245
+ String(lastLifecycle.createdAt),
246
+ );
247
+ setMemoryCheckpoint(
248
+ CHECKPOINT_KEY_LIFECYCLE_WATERMARK_ID,
249
+ lastLifecycle.id,
250
+ );
251
+ }
252
+
253
+ // If we got a full batch of any type, there may be more — recurse
254
+ if (
255
+ events.length === BATCH_SIZE ||
256
+ turnEvents.length === BATCH_SIZE ||
257
+ lifecycleEvents.length === BATCH_SIZE
258
+ ) {
212
259
  await this._doFlush(batchCount + 1);
213
260
  }
214
261
  } catch (err) {
@@ -1,4 +1,4 @@
1
- # Tools Agent Instructions
1
+ # Tools - Agent Instructions
2
2
 
3
3
  ## No New Tools Policy
4
4
 
@@ -8,11 +8,11 @@ The tool registration system (`class ... implements Tool` + `registerTool()`) is
8
8
 
9
9
  ## Why This Policy Exists
10
10
 
11
- 1. **Skills are preferred** The project direction is to teach the assistant CLI tools via skills rather than hardcoding tool implementations. Skills are progressively disclosed into context, are more portable, and are often self-contained.
11
+ 1. **Skills are preferred** - The project direction is to teach the assistant CLI tools via skills rather than hardcoding tool implementations. Skills are progressively disclosed into context, are more portable, and are often self-contained.
12
12
 
13
- 2. **Context overhead** Each registered tool adds to the system prompt and increases token usage for every conversation.
13
+ 2. **Context overhead** - Each registered tool adds to the system prompt and increases token usage for every conversation.
14
14
 
15
- 3. **Maintenance burden** Tools require ongoing maintenance, testing, and security review. Skills can be iterated on independently.
15
+ 3. **Maintenance burden** - Tools require ongoing maintenance, testing, and security review. Skills can be iterated on independently.
16
16
 
17
17
  ## What To Do Instead
18
18
 
@@ -20,9 +20,9 @@ Instead of creating a new tool, consider:
20
20
 
21
21
  1. **Create a skill**
22
22
 
23
- 2. **Use existing tools** Many capabilities can be achieved by combining existing tools (bash, file operations, network tools) with skill instructions.
23
+ 2. **Use existing tools** - Many capabilities can be achieved by combining existing tools (bash, file operations, network tools) with skill instructions.
24
24
 
25
- 3. **External CLI tools** If you need new functionality, consider whether it can be exposed as a CLI tool that the assistant can invoke via bash.
25
+ 3. **External CLI tools** - If you need new functionality, consider whether it can be exposed as a CLI tool that the assistant can invoke via bash.
26
26
 
27
27
  ## Approved Exception: Credential Execution Service (CES) Tools
28
28
 
@@ -36,16 +36,16 @@ The following three CES tools are the only approved exception to the no-new-tool
36
36
 
37
37
  These tools exist as `class ... implements Tool` registrations because:
38
38
 
39
- - They enforce hard process-boundary isolation credential values are materialized only inside the CES process (`credential-executor/` package), never in the assistant process
39
+ - They enforce hard process-boundary isolation - credential values are materialized only inside the CES process (`credential-executor/` package), never in the assistant process
40
40
  - Skills run inside the assistant process and cannot provide this isolation guarantee
41
41
  - The tools are thin RPC stubs; actual credential materialization and execution logic lives in the separate `credential-executor/` package
42
42
 
43
43
  **Key constraints**:
44
44
 
45
- - CES is a **separate package and image** no direct source imports from `assistant/` to `credential-executor/` or vice versa
46
- - **Grants and audit logs are CES-owned** durable state the assistant never reads or writes CES grant or audit tables directly
47
- - `host_bash` is **outside the strong CES secrecy guarantee** it does not enforce credential isolation
48
- - Secure generic authenticated HTTP **must not** run through `run_authenticated_command` use `make_authenticated_request` instead, which enforces domain validation and produces structured audit logs
45
+ - CES is a **separate package and image** - no direct source imports from `assistant/` to `credential-executor/` or vice versa
46
+ - **Grants and audit logs are CES-owned** durable state - the assistant never reads or writes CES grant or audit tables directly
47
+ - `host_bash` is **outside the strong CES secrecy guarantee** - it does not enforce credential isolation
48
+ - Secure generic authenticated HTTP **must not** run through `run_authenticated_command` - use `make_authenticated_request` instead, which enforces domain validation and produces structured audit logs
49
49
  - Managed rollout requires a **third runtime image** (alongside assistant and gateway) and `vembda` pod-template changes
50
50
 
51
51
  See [`assistant/docs/credential-execution-service.md`](../../docs/credential-execution-service.md) for the full ADR.
@@ -32,7 +32,7 @@ export async function executeAcpSpawn(
32
32
  | undefined;
33
33
  if (!sendToClient) {
34
34
  return {
35
- content: "No client connected cannot spawn ACP agent.",
35
+ content: "No client connected - cannot spawn ACP agent.",
36
36
  isError: true,
37
37
  };
38
38
  }
@@ -28,7 +28,7 @@ export interface ExecutorResult {
28
28
  }
29
29
 
30
30
  // ---------------------------------------------------------------------------
31
- // Dependency interfaces callers inject these rather than importing the
31
+ // Dependency interfaces - callers inject these rather than importing the
32
32
  // app-store module directly, which makes the executors testable with mocks.
33
33
  // ---------------------------------------------------------------------------
34
34
 
@@ -82,7 +82,7 @@ export type ProxyResolver = (
82
82
  ) => Promise<ExecutorResult>;
83
83
 
84
84
  // ---------------------------------------------------------------------------
85
- // Path resolution multifile apps default to src/ for file operations
85
+ // Path resolution - multifile apps default to src/ for file operations
86
86
  // ---------------------------------------------------------------------------
87
87
 
88
88
  /**
@@ -146,7 +146,7 @@ export async function executeAppCreate(
146
146
  const autoOpen = input.auto_open !== false; // default true
147
147
  const preview = input.preview;
148
148
 
149
- // Validate required fields LLM input is not type-checked at runtime
149
+ // Validate required fields - LLM input is not type-checked at runtime
150
150
  if (typeof name !== "string" || name.trim() === "") {
151
151
  return {
152
152
  content: JSON.stringify({
@@ -168,7 +168,7 @@ export async function executeAppCreate(
168
168
  }
169
169
  }
170
170
 
171
- // Extract icon from preview if provided only persist emoji-like values,
171
+ // Extract icon from preview if provided - only persist emoji-like values,
172
172
  // not URLs which would render as raw strings in UI and bundle manifests.
173
173
  const rawIcon = preview?.icon as string | undefined;
174
174
  const icon = rawIcon && !rawIcon.startsWith("http") ? rawIcon : undefined;
@@ -270,7 +270,7 @@ render(<App />, document.getElementById('app')!);
270
270
  isError: false,
271
271
  };
272
272
  } catch {
273
- // Preview emission failure is non-fatal the app was created successfully.
273
+ // Preview emission failure is non-fatal - the app was created successfully.
274
274
  return {
275
275
  content: JSON.stringify({
276
276
  ...app,
@@ -388,7 +388,7 @@ export function executeAppFileList(
388
388
 
389
389
  if (app && isMultifileApp(app)) {
390
390
  // Separate build output paths from source paths without mutating the
391
- // file path strings consumers need clean paths for subsequent tool calls.
391
+ // file path strings - consumers need clean paths for subsequent tool calls.
392
392
  const buildOutputPaths = files.filter((f) =>
393
393
  f.replace(/\\/g, "/").startsWith("dist/"),
394
394
  );
@@ -557,7 +557,7 @@ export async function executeAppGenerateIcon(
557
557
  );
558
558
 
559
559
  if (existsSync(iconPath)) {
560
- // Success clean up the old icon backup
560
+ // Success - clean up the old icon backup
561
561
  if (existsSync(tempPath)) {
562
562
  unlinkSync(tempPath);
563
563
  }
@@ -567,7 +567,7 @@ export async function executeAppGenerateIcon(
567
567
  };
568
568
  }
569
569
 
570
- // Generation failed restore the previous icon if we had one
570
+ // Generation failed - restore the previous icon if we had one
571
571
  if (existsSync(tempPath)) {
572
572
  renameSync(tempPath, iconPath);
573
573
  }
@@ -2,7 +2,7 @@
2
2
  * Registers app proxy tools with the daemon's tool registry.
3
3
  *
4
4
  * Called once at daemon startup via initializeTools(). Only proxy tools
5
- * (e.g. app_open) are registered here non-proxy data tools are now
5
+ * (e.g. app_open) are registered here - non-proxy data tools are now
6
6
  * provided by the app-builder skill via its TOOLS.json manifest.
7
7
  */
8
8
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * asset_materialize write a stored attachment to a sandbox file path.
2
+ * asset_materialize - write a stored attachment to a sandbox file path.
3
3
  *
4
4
  * Accepts an attachment ID (from asset_search) and a destination path
5
5
  * within the sandbox working directory. Decodes the base64 content and
@@ -31,11 +31,11 @@ import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
31
31
  import { getAttachmentSourceConversations } from "./search.js";
32
32
 
33
33
  // ---------------------------------------------------------------------------
34
- // Size limit prevent materializing excessively large attachments
34
+ // Size limit - prevent materializing excessively large attachments
35
35
  // ---------------------------------------------------------------------------
36
36
 
37
- /** 50 MB ceiling for materialized files. */
38
- export const MAX_MATERIALIZE_BYTES = 50 * 1024 * 1024;
37
+ /** 100 MB ceiling for materialized files. */
38
+ export const MAX_MATERIALIZE_BYTES = 100 * 1024 * 1024;
39
39
 
40
40
  // ---------------------------------------------------------------------------
41
41
  // Helpers
@@ -110,7 +110,7 @@ class AssetMaterializeTool implements Tool {
110
110
  name = "asset_materialize";
111
111
  description = definition.description;
112
112
  category = "assets";
113
- defaultRiskLevel = RiskLevel.Medium;
113
+ defaultRiskLevel = RiskLevel.Low;
114
114
 
115
115
  getDefinition(): ToolDefinition {
116
116
  return definition;
@@ -177,7 +177,7 @@ class AssetMaterializeTool implements Tool {
177
177
  if (sources.length > 0) {
178
178
  const hasStandard = sources.some((s) => s.conversationType !== "private");
179
179
  if (!hasStandard) {
180
- // All sources are private check if the caller is in any of those conversations
180
+ // All sources are private - check if the caller is in any of those conversations
181
181
  const callerInSourceConversation = sources.some((s) =>
182
182
  isAttachmentVisible(
183
183
  { conversationId: s.conversationId, isPrivate: true },
@@ -1,9 +1,9 @@
1
1
  /**
2
- * asset_search cross-conversation attachment metadata search.
2
+ * asset_search - cross-conversation attachment metadata search.
3
3
  *
4
4
  * Queries the attachments store for matching assets by MIME type,
5
5
  * filename, recency, or conversation scope. Returns metadata and
6
- * attachment IDs only never base64 payloads. The IDs can be
6
+ * attachment IDs only - never base64 payloads. The IDs can be
7
7
  * passed to asset_materialize (PR 35) to retrieve actual content.
8
8
  */
9
9
 
@@ -33,7 +33,7 @@ import { registerTool } from "../registry.js";
33
33
  import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
34
34
 
35
35
  // ---------------------------------------------------------------------------
36
- // Recency presets map human-readable labels to epoch-ms cutoff offsets
36
+ // Recency presets - map human-readable labels to epoch-ms cutoff offsets
37
37
  // ---------------------------------------------------------------------------
38
38
 
39
39
  const RECENCY_MS: Record<string, number> = {
@@ -113,7 +113,7 @@ function isAttachmentVisibleFromContext(
113
113
  return true;
114
114
  }
115
115
 
116
- // All sources are private visible only if the caller is in one of those conversations
116
+ // All sources are private - visible only if the caller is in one of those conversations
117
117
  return sources.some((s) =>
118
118
  isAttachmentVisible(
119
119
  { conversationId: s.conversationId, isPrivate: true },
@@ -143,13 +143,13 @@ export function searchAttachments(
143
143
  const db = getDb();
144
144
  const conditions = [];
145
145
 
146
- // MIME type filter supports wildcards like 'image/*' via LIKE
146
+ // MIME type filter - supports wildcards like 'image/*' via LIKE
147
147
  if (params.mime_type) {
148
148
  const mimePattern = params.mime_type.replace(/\*/g, "%");
149
149
  conditions.push(like(attachments.mimeType, mimePattern));
150
150
  }
151
151
 
152
- // Filename filter case-insensitive substring match (escape LIKE wildcards)
152
+ // Filename filter - case-insensitive substring match (escape LIKE wildcards)
153
153
  if (params.filename) {
154
154
  conditions.push(
155
155
  like(
@@ -159,7 +159,7 @@ export function searchAttachments(
159
159
  );
160
160
  }
161
161
 
162
- // Recency filter computed cutoff timestamp
162
+ // Recency filter - computed cutoff timestamp
163
163
  if (params.recency) {
164
164
  const offsetMs = RECENCY_MS[params.recency];
165
165
  if (offsetMs) {
@@ -168,7 +168,7 @@ export function searchAttachments(
168
168
  }
169
169
  }
170
170
 
171
- // Conversation scope join through message_attachments + messages
171
+ // Conversation scope - join through message_attachments + messages
172
172
  if (params.conversation_id) {
173
173
  const linkedIds = db
174
174
  .select({ attachmentId: messageAttachments.attachmentId })
@@ -239,7 +239,7 @@ export function searchAttachments(
239
239
  }));
240
240
  }
241
241
 
242
- // No conversation constraint query attachments table directly
242
+ // No conversation constraint - query attachments table directly
243
243
  const limit = Math.min(params.limit ?? DEFAULT_LIMIT, MAX_RESULTS);
244
244
  const where = conditions.length > 0 ? and(...conditions) : undefined;
245
245
 
@@ -271,7 +271,7 @@ const definition: ToolDefinition = {
271
271
  name: "asset_search",
272
272
  description:
273
273
  "Search for previously uploaded media assets (images, documents, etc.) by metadata. " +
274
- "Returns attachment IDs and metadata not file content. Use the returned IDs with " +
274
+ "Returns attachment IDs and metadata - not file content. Use the returned IDs with " +
275
275
  "asset_materialize to retrieve actual file data.",
276
276
  input_schema: {
277
277
  type: "object",
@@ -157,7 +157,7 @@ describe("AuthSessionCache", () => {
157
157
  ];
158
158
  writeSessionsFile(tmpDir, sessions);
159
159
 
160
- // Create a fresh cache load() has NOT been called
160
+ // Create a fresh cache - load() has NOT been called
161
161
  const cache = new AuthSessionCache(tmpDir);
162
162
 
163
163
  // markAuthenticated should ensureLoaded first, so existing sessions
@@ -192,7 +192,7 @@ describe("AuthSessionCache", () => {
192
192
  ];
193
193
  writeSessionsFile(tmpDir, sessions);
194
194
 
195
- // Create a fresh cache load() has NOT been called
195
+ // Create a fresh cache - load() has NOT been called
196
196
  const cache = new AuthSessionCache(tmpDir);
197
197
 
198
198
  // invalidate should ensureLoaded first, so unrelated sessions