@vellumai/assistant 0.5.10 → 0.5.12

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 (395) hide show
  1. package/AGENTS.md +8 -0
  2. package/ARCHITECTURE.md +43 -43
  3. package/Dockerfile +3 -0
  4. package/docs/architecture/integrations.md +37 -42
  5. package/docs/architecture/memory.md +7 -12
  6. package/docs/credential-execution-service.md +9 -9
  7. package/docs/skills.md +1 -1
  8. package/node_modules/@vellumai/ces-contracts/src/__tests__/grants.test.ts +7 -7
  9. package/node_modules/@vellumai/ces-contracts/src/handles.ts +5 -4
  10. package/node_modules/@vellumai/credential-storage/src/index.ts +3 -3
  11. package/node_modules/@vellumai/credential-storage/src/static-credentials.ts +1 -1
  12. package/openapi.yaml +7208 -0
  13. package/package.json +2 -1
  14. package/scripts/generate-openapi.ts +562 -0
  15. package/src/__tests__/acp-session.test.ts +239 -44
  16. package/src/__tests__/assistant-feature-flag-guard.test.ts +8 -8
  17. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +5 -86
  18. package/src/__tests__/assistant-feature-flags-integration.test.ts +7 -14
  19. package/src/__tests__/browser-skill-endstate.test.ts +1 -1
  20. package/src/__tests__/btw-routes.test.ts +8 -0
  21. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +10 -10
  22. package/src/__tests__/catalog-cache.test.ts +164 -0
  23. package/src/__tests__/catalog-search.test.ts +61 -0
  24. package/src/__tests__/channel-approvals.test.ts +7 -7
  25. package/src/__tests__/channel-readiness-service.test.ts +41 -0
  26. package/src/__tests__/cli-command-risk-guard.test.ts +181 -6
  27. package/src/__tests__/config-schema.test.ts +10 -2
  28. package/src/__tests__/context-memory-e2e.test.ts +2 -6
  29. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +396 -0
  30. package/src/__tests__/conversation-error.test.ts +3 -2
  31. package/src/__tests__/conversation-skill-tools.test.ts +1 -3
  32. package/src/__tests__/conversation-title-service.test.ts +2 -15
  33. package/src/__tests__/credential-execution-feature-gates.test.ts +4 -8
  34. package/src/__tests__/credential-execution-managed-contract.test.ts +8 -8
  35. package/src/__tests__/credential-security-e2e.test.ts +4 -4
  36. package/src/__tests__/credential-security-invariants.test.ts +12 -18
  37. package/src/__tests__/credential-vault-unit.test.ts +32 -34
  38. package/src/__tests__/credential-vault.test.ts +25 -33
  39. package/src/__tests__/credentials-cli.test.ts +3 -3
  40. package/src/__tests__/daemon-credential-client.test.ts +2 -2
  41. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -1
  42. package/src/__tests__/gateway-only-guard.test.ts +3 -0
  43. package/src/__tests__/heartbeat-service.test.ts +35 -0
  44. package/src/__tests__/host-bash-proxy.test.ts +79 -0
  45. package/src/__tests__/host-cu-proxy.test.ts +90 -0
  46. package/src/__tests__/host-file-proxy.test.ts +89 -0
  47. package/src/__tests__/host-shell-tool.test.ts +1 -1
  48. package/src/__tests__/inline-skill-load-permissions.test.ts +3 -3
  49. package/src/__tests__/integration-status.test.ts +5 -5
  50. package/src/__tests__/list-messages-attachments.test.ts +171 -0
  51. package/src/__tests__/llm-request-log-turn-query.test.ts +64 -0
  52. package/src/__tests__/log-export-workspace.test.ts +1 -1
  53. package/src/__tests__/mcp-abort-signal.test.ts +205 -0
  54. package/src/__tests__/mcp-client-auth.test.ts +1 -1
  55. package/src/__tests__/memory-lifecycle-e2e.test.ts +2 -2
  56. package/src/__tests__/memory-recall-log-store.test.ts +182 -0
  57. package/src/__tests__/memory-recall-quality.test.ts +6 -8
  58. package/src/__tests__/memory-regressions.test.ts +53 -42
  59. package/src/__tests__/memory-retrieval.benchmark.test.ts +5 -9
  60. package/src/__tests__/messaging-send-tool.test.ts +5 -5
  61. package/src/__tests__/messaging-skill-split.test.ts +2 -17
  62. package/src/__tests__/notification-telegram-adapter.test.ts +125 -0
  63. package/src/__tests__/oauth-cli.test.ts +203 -649
  64. package/src/__tests__/oauth-provider-profiles.test.ts +55 -20
  65. package/src/__tests__/oauth-scope-policy.test.ts +4 -6
  66. package/src/__tests__/onboarding-template-contract.test.ts +2 -2
  67. package/src/__tests__/platform-callback-registration.test.ts +119 -0
  68. package/src/__tests__/secret-ingress-channel.test.ts +261 -0
  69. package/src/__tests__/secret-ingress-cli.test.ts +201 -0
  70. package/src/__tests__/secret-ingress-http.test.ts +312 -0
  71. package/src/__tests__/secret-ingress.test.ts +283 -0
  72. package/src/__tests__/secret-onetime-send.test.ts +4 -4
  73. package/src/__tests__/secret-routes-managed-proxy.test.ts +78 -0
  74. package/src/__tests__/secure-keys-managed-failover.test.ts +73 -0
  75. package/src/__tests__/skill-feature-flags-integration.test.ts +4 -4
  76. package/src/__tests__/skill-feature-flags.test.ts +11 -19
  77. package/src/__tests__/skill-load-feature-flag.test.ts +1 -1
  78. package/src/__tests__/skill-load-inline-command.test.ts +3 -3
  79. package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
  80. package/src/__tests__/skill-memory.test.ts +2 -4
  81. package/src/__tests__/skill-projection-feature-flag.test.ts +2 -4
  82. package/src/__tests__/skill-projection.benchmark.test.ts +1 -3
  83. package/src/__tests__/skills-uninstall.test.ts +2 -2
  84. package/src/__tests__/skills.test.ts +16 -2
  85. package/src/__tests__/slack-channel-config.test.ts +1 -1
  86. package/src/__tests__/slack-messaging-token-resolution.test.ts +22 -24
  87. package/src/__tests__/slack-share-routes.test.ts +5 -5
  88. package/src/__tests__/slack-skill.test.ts +5 -69
  89. package/src/__tests__/system-prompt.test.ts +39 -0
  90. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -1
  91. package/src/__tests__/workspace-migration-018-rekey-compound-credential-keys.test.ts +181 -0
  92. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +5 -4
  93. package/src/acp/client-handler.ts +113 -31
  94. package/src/acp/session-manager.ts +29 -27
  95. package/src/approvals/guardian-request-resolvers.ts +1 -1
  96. package/src/cli/AGENTS.md +113 -0
  97. package/src/cli/commands/autonomy.ts +3 -5
  98. package/src/cli/commands/browser-relay.ts +2 -17
  99. package/src/cli/commands/contacts.ts +6 -4
  100. package/src/cli/commands/conversations.ts +13 -1
  101. package/src/cli/commands/credential-execution.ts +17 -3
  102. package/src/cli/commands/credentials.ts +2 -8
  103. package/src/cli/commands/memory.ts +2 -3
  104. package/src/cli/commands/oauth/__tests__/connect.test.ts +706 -0
  105. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +686 -0
  106. package/src/cli/commands/oauth/__tests__/mode.test.ts +625 -0
  107. package/src/cli/commands/oauth/__tests__/ping.test.ts +631 -0
  108. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +574 -0
  109. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +416 -0
  110. package/src/cli/commands/oauth/__tests__/status.test.ts +551 -0
  111. package/src/cli/commands/oauth/__tests__/token.test.ts +420 -0
  112. package/src/cli/commands/oauth/apps.ts +87 -50
  113. package/src/cli/commands/oauth/connect.ts +405 -0
  114. package/src/cli/commands/oauth/disconnect.ts +285 -0
  115. package/src/cli/commands/oauth/index.ts +62 -20
  116. package/src/cli/commands/oauth/mode.ts +251 -0
  117. package/src/cli/commands/oauth/ping.ts +196 -0
  118. package/src/cli/commands/oauth/providers.ts +589 -55
  119. package/src/cli/commands/oauth/request.ts +564 -0
  120. package/src/cli/commands/oauth/shared.ts +114 -0
  121. package/src/cli/commands/oauth/status.ts +191 -0
  122. package/src/cli/commands/oauth/token.ts +150 -0
  123. package/src/cli/commands/platform/connect.ts +104 -0
  124. package/src/cli/commands/platform/disconnect.ts +118 -0
  125. package/src/cli/commands/platform/index.ts +252 -0
  126. package/src/cli/commands/sequence.ts +5 -4
  127. package/src/cli/commands/shotgun.ts +16 -0
  128. package/src/cli/commands/skills.ts +173 -41
  129. package/src/cli/commands/usage.ts +5 -11
  130. package/src/cli/lib/daemon-credential-client.ts +22 -38
  131. package/src/cli/program.ts +1 -1
  132. package/src/cli.ts +82 -17
  133. package/src/config/assistant-feature-flags.ts +77 -18
  134. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  135. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -1
  136. package/src/config/bundled-skills/contacts/tools/google-contacts.ts +1 -1
  137. package/src/config/bundled-skills/conversations/SKILL.md +20 -0
  138. package/src/config/bundled-skills/conversations/TOOLS.json +23 -0
  139. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +66 -0
  140. package/src/config/bundled-skills/gmail/SKILL.md +13 -13
  141. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +3 -3
  142. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +2 -2
  143. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +1 -1
  144. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +1 -1
  145. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +1 -1
  146. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +1 -1
  147. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +2 -2
  148. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +1 -1
  149. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +1 -1
  150. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
  151. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +1 -1
  152. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +1 -1
  153. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +1 -1
  154. package/src/config/bundled-skills/google-calendar/SKILL.md +10 -4
  155. package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
  156. package/src/config/bundled-skills/messaging/SKILL.md +19 -42
  157. package/src/config/bundled-skills/messaging/TOOLS.json +9 -9
  158. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
  159. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -2
  160. package/src/config/bundled-skills/messaging/tools/shared.ts +5 -6
  161. package/src/config/bundled-skills/notifications/SKILL.md +1 -1
  162. package/src/config/bundled-skills/schedule/SKILL.md +2 -2
  163. package/src/config/bundled-skills/settings/SKILL.md +5 -3
  164. package/src/config/bundled-skills/settings/TOOLS.json +17 -0
  165. package/src/config/bundled-skills/settings/tools/avatar-get.ts +50 -0
  166. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +7 -0
  167. package/src/config/bundled-skills/settings/tools/avatar-update.ts +6 -1
  168. package/src/config/bundled-skills/settings/tools/identity-avatar.ts +55 -0
  169. package/src/config/bundled-skills/skills-catalog/SKILL.md +3 -3
  170. package/src/config/bundled-skills/slack/SKILL.md +58 -44
  171. package/src/config/bundled-tool-registry.ts +7 -19
  172. package/src/config/env.ts +5 -1
  173. package/src/config/feature-flag-registry.json +58 -42
  174. package/src/config/loader.ts +4 -0
  175. package/src/config/schemas/platform.ts +0 -8
  176. package/src/config/schemas/security.ts +9 -1
  177. package/src/config/schemas/services.ts +1 -1
  178. package/src/config/skill-state.ts +1 -3
  179. package/src/config/skills.ts +2 -4
  180. package/src/credential-execution/client.ts +1 -1
  181. package/src/credential-execution/feature-gates.ts +9 -16
  182. package/src/credential-execution/process-manager.ts +12 -0
  183. package/src/daemon/config-watcher.ts +4 -0
  184. package/src/daemon/conversation-agent-loop-handlers.ts +10 -0
  185. package/src/daemon/conversation-agent-loop.ts +51 -2
  186. package/src/daemon/conversation-error.ts +36 -6
  187. package/src/daemon/conversation-memory.ts +0 -1
  188. package/src/daemon/conversation-messaging.ts +9 -0
  189. package/src/daemon/conversation-runtime-assembly.ts +33 -0
  190. package/src/daemon/conversation-surfaces.ts +120 -14
  191. package/src/daemon/conversation.ts +5 -0
  192. package/src/daemon/handlers/config-slack-channel.ts +43 -1
  193. package/src/daemon/handlers/conversations.ts +41 -33
  194. package/src/daemon/handlers/skills.ts +148 -3
  195. package/src/daemon/host-bash-proxy.ts +16 -0
  196. package/src/daemon/host-cu-proxy.ts +16 -0
  197. package/src/daemon/host-file-proxy.ts +16 -0
  198. package/src/daemon/lifecycle.ts +73 -3
  199. package/src/daemon/message-types/acp.ts +0 -15
  200. package/src/daemon/message-types/conversations.ts +1 -0
  201. package/src/daemon/message-types/guardian-actions.ts +2 -0
  202. package/src/daemon/message-types/host-bash.ts +6 -1
  203. package/src/daemon/message-types/host-cu.ts +6 -1
  204. package/src/daemon/message-types/host-file.ts +6 -1
  205. package/src/daemon/message-types/integrations.ts +0 -1
  206. package/src/daemon/message-types/memory.ts +0 -1
  207. package/src/daemon/message-types/messages.ts +9 -1
  208. package/src/daemon/message-types/schedules.ts +9 -0
  209. package/src/daemon/server.ts +48 -9
  210. package/src/email/feature-gate.ts +3 -3
  211. package/src/heartbeat/heartbeat-service.ts +48 -0
  212. package/src/hooks/cli.ts +74 -0
  213. package/src/inbound/platform-callback-registration.ts +68 -19
  214. package/src/mcp/client.ts +6 -1
  215. package/src/mcp/manager.ts +2 -1
  216. package/src/mcp/mcp-oauth-provider.ts +3 -3
  217. package/src/memory/app-store.ts +3 -3
  218. package/src/memory/conversation-crud.ts +213 -0
  219. package/src/memory/conversation-key-store.ts +26 -0
  220. package/src/memory/conversation-title-service.ts +7 -17
  221. package/src/memory/db-init.ts +24 -0
  222. package/src/memory/embedding-local.ts +47 -2
  223. package/src/memory/indexer.ts +13 -10
  224. package/src/memory/items-extractor.ts +12 -4
  225. package/src/memory/job-utils.ts +5 -0
  226. package/src/memory/jobs-store.ts +10 -2
  227. package/src/memory/journal-memory.ts +6 -2
  228. package/src/memory/llm-request-log-store.ts +88 -21
  229. package/src/memory/memory-recall-log-store.ts +128 -0
  230. package/src/memory/migrations/194-memory-recall-logs.ts +50 -0
  231. package/src/memory/migrations/195-oauth-providers-ping-config.ts +23 -0
  232. package/src/memory/migrations/196-messages-conversation-created-at-index.ts +9 -0
  233. package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +186 -0
  234. package/src/memory/migrations/197-oauth-providers-behavior-columns.ts +29 -0
  235. package/src/memory/migrations/198-drop-setup-skill-id-column.ts +11 -0
  236. package/src/memory/migrations/index.ts +6 -0
  237. package/src/memory/migrations/registry.ts +8 -0
  238. package/src/memory/retriever.test.ts +4 -5
  239. package/src/memory/schema/infrastructure.ts +31 -0
  240. package/src/memory/schema/oauth.ts +14 -0
  241. package/src/messaging/provider.ts +13 -12
  242. package/src/messaging/providers/gmail/adapter.ts +44 -35
  243. package/src/messaging/providers/slack/adapter.ts +63 -33
  244. package/src/messaging/providers/telegram-bot/adapter.ts +7 -9
  245. package/src/messaging/providers/whatsapp/adapter.ts +6 -8
  246. package/src/notifications/adapters/telegram.ts +78 -2
  247. package/src/oauth/__tests__/identity-verifier.test.ts +464 -0
  248. package/src/oauth/byo-connection.test.ts +22 -24
  249. package/src/oauth/connect-orchestrator.ts +79 -64
  250. package/src/oauth/connect-types.ts +7 -65
  251. package/src/oauth/connection-resolver.test.ts +13 -13
  252. package/src/oauth/connection-resolver.ts +3 -4
  253. package/src/oauth/identity-verifier.ts +177 -0
  254. package/src/oauth/manual-token-connection.ts +5 -5
  255. package/src/oauth/oauth-store.ts +251 -5
  256. package/src/oauth/platform-connection.test.ts +56 -6
  257. package/src/oauth/platform-connection.ts +8 -1
  258. package/src/oauth/seed-providers.ts +256 -34
  259. package/src/permissions/checker.ts +129 -3
  260. package/src/permissions/trust-client.ts +2 -2
  261. package/src/platform/client.ts +2 -2
  262. package/src/prompts/journal-context.ts +6 -1
  263. package/src/prompts/system-prompt.ts +43 -9
  264. package/src/prompts/templates/BOOTSTRAP.md +16 -5
  265. package/src/providers/anthropic/client.ts +139 -28
  266. package/src/runtime/auth/__tests__/middleware.test.ts +19 -0
  267. package/src/runtime/auth/route-policy.ts +0 -1
  268. package/src/runtime/btw-sidechain.ts +7 -1
  269. package/src/runtime/channel-approvals.ts +2 -2
  270. package/src/runtime/channel-readiness-service.ts +30 -7
  271. package/src/runtime/guardian-action-service.ts +7 -2
  272. package/src/runtime/http-router.ts +31 -0
  273. package/src/runtime/http-server.ts +26 -7
  274. package/src/runtime/http-types.ts +9 -0
  275. package/src/runtime/pending-interactions.ts +21 -3
  276. package/src/runtime/routes/acp-routes.ts +46 -28
  277. package/src/runtime/routes/app-management-routes.ts +123 -0
  278. package/src/runtime/routes/app-routes.ts +31 -0
  279. package/src/runtime/routes/approval-routes.ts +108 -3
  280. package/src/runtime/routes/attachment-routes.ts +45 -0
  281. package/src/runtime/routes/avatar-routes.ts +16 -0
  282. package/src/runtime/routes/brain-graph-routes.ts +18 -0
  283. package/src/runtime/routes/btw-routes.ts +20 -0
  284. package/src/runtime/routes/call-routes.ts +81 -0
  285. package/src/runtime/routes/channel-readiness-routes.ts +48 -7
  286. package/src/runtime/routes/channel-routes.ts +18 -0
  287. package/src/runtime/routes/channel-verification-routes.ts +49 -1
  288. package/src/runtime/routes/contact-routes.ts +77 -0
  289. package/src/runtime/routes/conversation-attention-routes.ts +37 -0
  290. package/src/runtime/routes/conversation-management-routes.ts +125 -0
  291. package/src/runtime/routes/conversation-query-routes.ts +78 -0
  292. package/src/runtime/routes/conversation-routes.ts +191 -39
  293. package/src/runtime/routes/conversation-starter-routes.ts +29 -0
  294. package/src/runtime/routes/debug-routes.ts +23 -0
  295. package/src/runtime/routes/diagnostics-routes.ts +30 -0
  296. package/src/runtime/routes/documents-routes.ts +42 -0
  297. package/src/runtime/routes/events-routes.ts +10 -0
  298. package/src/runtime/routes/global-search-routes.ts +35 -0
  299. package/src/runtime/routes/guardian-action-routes.ts +61 -3
  300. package/src/runtime/routes/guardian-approval-prompt.ts +77 -2
  301. package/src/runtime/routes/heartbeat-routes.ts +278 -0
  302. package/src/runtime/routes/host-bash-routes.ts +16 -1
  303. package/src/runtime/routes/host-cu-routes.ts +23 -1
  304. package/src/runtime/routes/host-file-routes.ts +18 -1
  305. package/src/runtime/routes/identity-routes.ts +35 -0
  306. package/src/runtime/routes/inbound-message-handler.ts +46 -25
  307. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -8
  308. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +30 -2
  309. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +1 -2
  310. package/src/runtime/routes/integrations/slack/share.ts +1 -1
  311. package/src/runtime/routes/integrations/twilio.ts +32 -22
  312. package/src/runtime/routes/invite-routes.ts +83 -0
  313. package/src/runtime/routes/log-export-routes.ts +14 -0
  314. package/src/runtime/routes/memory-item-routes.ts +99 -1
  315. package/src/runtime/routes/migration-rollback-routes.ts +25 -0
  316. package/src/runtime/routes/migration-routes.ts +40 -0
  317. package/src/runtime/routes/notification-routes.ts +20 -0
  318. package/src/runtime/routes/oauth-apps.ts +13 -4
  319. package/src/runtime/routes/pairing-routes.ts +15 -0
  320. package/src/runtime/routes/recording-routes.ts +72 -0
  321. package/src/runtime/routes/schedule-routes.ts +77 -5
  322. package/src/runtime/routes/secret-routes.ts +99 -14
  323. package/src/runtime/routes/settings-routes.ts +102 -19
  324. package/src/runtime/routes/skills-routes.ts +141 -18
  325. package/src/runtime/routes/subagents-routes.ts +38 -3
  326. package/src/runtime/routes/surface-action-routes.ts +66 -24
  327. package/src/runtime/routes/surface-content-routes.ts +20 -0
  328. package/src/runtime/routes/telemetry-routes.ts +12 -0
  329. package/src/runtime/routes/trace-event-routes.ts +25 -0
  330. package/src/runtime/routes/trust-rules-routes.ts +46 -0
  331. package/src/runtime/routes/tts-routes.ts +15 -4
  332. package/src/runtime/routes/upgrade-broadcast-routes.ts +38 -0
  333. package/src/runtime/routes/usage-routes.ts +59 -0
  334. package/src/runtime/routes/watch-routes.ts +28 -0
  335. package/src/runtime/routes/work-items-routes.ts +59 -0
  336. package/src/runtime/routes/workspace-commit-routes.ts +12 -0
  337. package/src/runtime/routes/workspace-routes.ts +102 -0
  338. package/src/schedule/integration-status.ts +2 -2
  339. package/src/schedule/scheduler.ts +7 -1
  340. package/src/security/AGENTS.md +7 -0
  341. package/src/security/ces-rpc-credential-backend.ts +19 -16
  342. package/src/security/credential-backend.ts +1 -1
  343. package/src/security/encrypted-store.ts +3 -3
  344. package/src/security/oauth-completion-page.ts +153 -0
  345. package/src/security/oauth2.ts +58 -17
  346. package/src/security/secret-ingress.ts +174 -0
  347. package/src/security/secret-patterns.ts +133 -0
  348. package/src/security/secret-scanner.ts +28 -117
  349. package/src/security/secure-keys.ts +207 -7
  350. package/src/security/token-manager.ts +3 -6
  351. package/src/signals/bash.ts +6 -1
  352. package/src/signals/confirm.ts +12 -8
  353. package/src/signals/user-message.ts +18 -3
  354. package/src/skills/catalog-cache.ts +44 -0
  355. package/src/skills/catalog-search.ts +18 -0
  356. package/src/skills/skill-memory.ts +1 -2
  357. package/src/tasks/task-runner.ts +7 -1
  358. package/src/tools/credentials/broker.ts +1 -1
  359. package/src/tools/credentials/metadata-store.ts +1 -1
  360. package/src/tools/credentials/post-connect-hooks.ts +1 -1
  361. package/src/tools/credentials/vault.ts +36 -48
  362. package/src/tools/host-terminal/host-shell.ts +16 -3
  363. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  364. package/src/tools/memory/definitions.ts +1 -1
  365. package/src/tools/memory/handlers.test.ts +2 -4
  366. package/src/tools/skills/load.ts +1 -1
  367. package/src/tools/skills/sandbox-runner.ts +16 -3
  368. package/src/tools/terminal/safe-env.ts +7 -0
  369. package/src/tools/terminal/shell.ts +16 -3
  370. package/src/tools/tool-manifest.ts +1 -1
  371. package/src/util/log-redact.ts +9 -34
  372. package/src/util/logger.ts +11 -1
  373. package/src/util/sentry-log-stream.ts +51 -0
  374. package/src/watcher/providers/github.ts +2 -2
  375. package/src/watcher/providers/gmail.ts +1 -1
  376. package/src/watcher/providers/google-calendar.ts +1 -1
  377. package/src/watcher/providers/linear.ts +2 -2
  378. package/src/workspace/migrations/011-backfill-installation-id.ts +5 -3
  379. package/src/workspace/migrations/020-rename-oauth-skill-dirs.ts +119 -0
  380. package/src/workspace/migrations/registry.ts +2 -0
  381. package/docs/architecture/keychain-broker.md +0 -68
  382. package/src/cli/commands/oauth/connections.ts +0 -734
  383. package/src/cli/commands/oauth/platform.ts +0 -525
  384. package/src/cli/commands/platform.ts +0 -176
  385. package/src/config/bundled-skills/slack/TOOLS.json +0 -272
  386. package/src/config/bundled-skills/slack/tools/shared.ts +0 -34
  387. package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +0 -27
  388. package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +0 -38
  389. package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +0 -146
  390. package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +0 -105
  391. package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +0 -26
  392. package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +0 -27
  393. package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +0 -25
  394. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +0 -372
  395. package/src/oauth/provider-behaviors.ts +0 -634
@@ -25,6 +25,9 @@ import {
25
25
  userMessage,
26
26
  } from "../../providers/provider-send-message.js";
27
27
  import { isTextMimeType as isTextMime } from "../../runtime/routes/workspace-utils.js";
28
+ import { getCatalog } from "../../skills/catalog-cache.js";
29
+ import { installSkillLocally } from "../../skills/catalog-install.js";
30
+ import { filterByQuery } from "../../skills/catalog-search.js";
28
31
  import {
29
32
  clawhubCheckUpdates,
30
33
  clawhubInspect,
@@ -232,8 +235,9 @@ export interface SkillListItem {
232
235
  description: string;
233
236
  emoji?: string;
234
237
  homepage?: string;
235
- source: "bundled" | "managed" | "workspace" | "clawhub" | "extra";
238
+ source: "bundled" | "managed" | "workspace" | "clawhub" | "extra" | "catalog";
236
239
  state: "enabled" | "disabled";
240
+ installStatus: "bundled" | "installed" | "available";
237
241
  updateAvailable: boolean;
238
242
  provenance: SkillProvenance;
239
243
  }
@@ -259,6 +263,9 @@ export function listSkills(_ctx: SkillOperationContext): SkillListItem[] {
259
263
  homepage: r.summary.homepage,
260
264
  source: r.summary.source,
261
265
  state: r.state,
266
+ installStatus: (r.summary.source === "bundled"
267
+ ? "bundled"
268
+ : "installed") as SkillListItem["installStatus"],
262
269
  updateAvailable: false,
263
270
  provenance: resolveProvenance(r.summary),
264
271
  }));
@@ -275,6 +282,54 @@ export function listSkills(_ctx: SkillOperationContext): SkillListItem[] {
275
282
  return items;
276
283
  }
277
284
 
285
+ /**
286
+ * List installed skills merged with available catalog skills.
287
+ * Installed skills take precedence when deduplicating by ID.
288
+ */
289
+ export async function listSkillsWithCatalog(
290
+ ctx: SkillOperationContext,
291
+ ): Promise<SkillListItem[]> {
292
+ const installed = listSkills(ctx);
293
+ const installedIds = new Set(installed.map((s) => s.id));
294
+
295
+ let catalogSkills: import("../../skills/catalog-install.js").CatalogSkill[];
296
+ try {
297
+ catalogSkills = await getCatalog();
298
+ } catch {
299
+ // If catalog fetch fails, return installed-only
300
+ return installed;
301
+ }
302
+
303
+ // All entries from the Vellum platform API are first-party.
304
+ // Create SkillListItems for catalog skills not already installed.
305
+ const available: SkillListItem[] = catalogSkills
306
+ .filter((cs) => !installedIds.has(cs.id))
307
+ .map((cs) => ({
308
+ id: cs.id,
309
+ name: cs.metadata?.vellum?.["display-name"] ?? cs.name,
310
+ description: cs.description,
311
+ emoji: cs.emoji,
312
+ homepage: undefined,
313
+ source: "catalog" as const,
314
+ state: "disabled" as const,
315
+ installStatus: "available" as const,
316
+ updateAvailable: false,
317
+ provenance: { kind: "first-party" as const, provider: "Vellum" },
318
+ }));
319
+
320
+ const merged = [...installed, ...available];
321
+
322
+ // Sort using the same provenance sort + alphabetical
323
+ merged.sort((a, b) => {
324
+ const rankDiff =
325
+ provenanceSortRank(a.provenance) - provenanceSortRank(b.provenance);
326
+ if (rankDiff !== 0) return rankDiff;
327
+ return a.name.localeCompare(b.name);
328
+ });
329
+
330
+ return merged;
331
+ }
332
+
278
333
  /** Look up a single skill by ID from the resolved catalog, returning its SkillListItem. */
279
334
  function findSkillById(
280
335
  skillId: string,
@@ -294,6 +349,7 @@ function findSkillById(
294
349
  homepage: r.summary.homepage,
295
350
  source: r.summary.source,
296
351
  state: r.state,
352
+ installStatus: r.summary.source === "bundled" ? "bundled" : "installed",
297
353
  updateAvailable: false,
298
354
  provenance: resolveProvenance(r.summary),
299
355
  };
@@ -519,6 +575,43 @@ export async function installSkill(
519
575
  return { success: true };
520
576
  }
521
577
 
578
+ // Check the Vellum catalog (first-party skills hosted on the platform)
579
+ try {
580
+ const vellumCatalog = await getCatalog();
581
+ const catalogEntry = vellumCatalog.find((s) => s.id === spec.slug);
582
+ if (catalogEntry) {
583
+ await installSkillLocally(spec.slug, catalogEntry, true);
584
+
585
+ // Reload skill catalog so the newly installed skill is picked up
586
+ loadSkillCatalog();
587
+
588
+ // Auto-enable the newly installed catalog skill
589
+ try {
590
+ const raw = loadRawConfig();
591
+ ensureSkillEntry(raw, spec.slug).enabled = true;
592
+ saveConfigWithSuppression(raw, ctx);
593
+ ctx.broadcast({
594
+ type: "skills_state_changed",
595
+ name: spec.slug,
596
+ state: "enabled",
597
+ });
598
+ } catch (err) {
599
+ log.warn(
600
+ { err, skillId: spec.slug },
601
+ "Failed to auto-enable installed catalog skill",
602
+ );
603
+ }
604
+
605
+ return { success: true };
606
+ }
607
+ } catch (err) {
608
+ // If catalog lookup/install fails, fall through to clawhub
609
+ log.warn(
610
+ { err, skillId: spec.slug },
611
+ "Vellum catalog install failed, falling back to community registry",
612
+ );
613
+ }
614
+
522
615
  // Install from clawhub (community)
523
616
  const result = await clawhubInstall(spec.slug, { version: spec.version });
524
617
  if (!result.success) {
@@ -660,8 +753,60 @@ export async function searchSkills(
660
753
  { success: true; data: unknown } | { success: false; error: string }
661
754
  > {
662
755
  try {
663
- const result = await clawhubSearch(query);
664
- return { success: true, data: result };
756
+ // Search the loaded skill catalog (bundled + installed) for matches
757
+ const catalog = loadSkillCatalog();
758
+ const catalogMatches = filterByQuery(catalog, query, [
759
+ (s) => s.id,
760
+ (s) => s.displayName,
761
+ (s) => s.description,
762
+ ]);
763
+
764
+ // Shape that matches ClawhubSearchResultItem so the client
765
+ // (Swift ClawhubSkillItem) can decode results uniformly.
766
+ interface SearchItem {
767
+ name: string;
768
+ slug: string;
769
+ description: string;
770
+ author: string;
771
+ stars: number;
772
+ installs: number;
773
+ version: string;
774
+ createdAt: number;
775
+ source: "vellum" | "clawhub";
776
+ }
777
+
778
+ const catalogItems: SearchItem[] = catalogMatches.map((s) => ({
779
+ name: s.displayName,
780
+ slug: s.id,
781
+ description: s.description,
782
+ author: "Vellum",
783
+ stars: 0,
784
+ installs: 0,
785
+ version: "",
786
+ createdAt: 0,
787
+ source: "vellum" as const,
788
+ }));
789
+
790
+ // Search the community registry (non-fatal on failure)
791
+ let communitySkills: SearchItem[] = [];
792
+ try {
793
+ const communityResult = await clawhubSearch(query);
794
+ communitySkills = communityResult.skills;
795
+ } catch (err) {
796
+ log.warn(
797
+ { err },
798
+ "clawhub search failed, returning catalog-only results",
799
+ );
800
+ }
801
+
802
+ // Deduplicate: catalog takes precedence when slugs collide
803
+ const catalogSlugs = new Set(catalogItems.map((s) => s.slug));
804
+ const deduped = communitySkills.filter((s) => !catalogSlugs.has(s.slug));
805
+
806
+ return {
807
+ success: true,
808
+ data: { skills: [...catalogItems, ...deduped] },
809
+ };
665
810
  } catch (err) {
666
811
  const message = err instanceof Error ? err.message : String(err);
667
812
  log.error({ err }, "Failed to search skills");
@@ -86,6 +86,14 @@ export class HostBashProxy {
86
86
  clearTimeout(timer);
87
87
  this.pending.delete(requestId);
88
88
  this.onInternalResolve?.(requestId);
89
+ try {
90
+ this.sendToClient({
91
+ type: "host_bash_cancel",
92
+ requestId,
93
+ } as ServerMessage);
94
+ } catch {
95
+ // Best-effort cancel notification — connection may already be closed.
96
+ }
89
97
  resolve(formatShellOutput("", "Aborted", null, false, 0));
90
98
  }
91
99
  };
@@ -144,6 +152,14 @@ export class HostBashProxy {
144
152
  for (const [requestId, entry] of this.pending) {
145
153
  clearTimeout(entry.timer);
146
154
  this.onInternalResolve?.(requestId);
155
+ try {
156
+ this.sendToClient({
157
+ type: "host_bash_cancel",
158
+ requestId,
159
+ } as ServerMessage);
160
+ } catch {
161
+ // Best-effort cancel notification — connection may already be closed.
162
+ }
147
163
  entry.reject(
148
164
  new AssistantError(
149
165
  "Host bash proxy disposed",
@@ -170,6 +170,14 @@ export class HostCuProxy {
170
170
  clearTimeout(timer);
171
171
  this.pending.delete(requestId);
172
172
  this.onInternalResolve?.(requestId);
173
+ try {
174
+ this.sendToClient({
175
+ type: "host_cu_cancel",
176
+ requestId,
177
+ } as ServerMessage);
178
+ } catch {
179
+ // Best-effort cancel notification — connection may already be closed.
180
+ }
173
181
  resolve({ content: "Aborted", isError: true });
174
182
  }
175
183
  };
@@ -381,6 +389,14 @@ export class HostCuProxy {
381
389
  for (const [requestId, entry] of this.pending) {
382
390
  clearTimeout(entry.timer);
383
391
  this.onInternalResolve?.(requestId);
392
+ try {
393
+ this.sendToClient({
394
+ type: "host_cu_cancel",
395
+ requestId,
396
+ } as ServerMessage);
397
+ } catch {
398
+ // Best-effort cancel notification — connection may already be closed.
399
+ }
384
400
  entry.reject(
385
401
  new AssistantError("Host CU proxy disposed", ErrorCode.INTERNAL_ERROR),
386
402
  );
@@ -82,6 +82,14 @@ export class HostFileProxy {
82
82
  clearTimeout(timer);
83
83
  this.pending.delete(requestId);
84
84
  this.onInternalResolve?.(requestId);
85
+ try {
86
+ this.sendToClient({
87
+ type: "host_file_cancel",
88
+ requestId,
89
+ } as ServerMessage);
90
+ } catch {
91
+ // Best-effort cancel notification — connection may already be closed.
92
+ }
85
93
  resolve({ content: "Aborted", isError: true });
86
94
  }
87
95
  };
@@ -123,6 +131,14 @@ export class HostFileProxy {
123
131
  for (const [requestId, entry] of this.pending) {
124
132
  clearTimeout(entry.timer);
125
133
  this.onInternalResolve?.(requestId);
134
+ try {
135
+ this.sendToClient({
136
+ type: "host_file_cancel",
137
+ requestId,
138
+ } as ServerMessage);
139
+ } catch {
140
+ // Best-effort cancel notification — connection may already be closed.
141
+ }
126
142
  entry.reject(
127
143
  new AssistantError(
128
144
  "Host file proxy disposed",
@@ -77,7 +77,11 @@ import {
77
77
  import { ensureVellumGuardianBinding } from "../runtime/guardian-vellum-migration.js";
78
78
  import { RuntimeHttpServer } from "../runtime/http-server.js";
79
79
  import { startScheduler } from "../schedule/scheduler.js";
80
- import { setCesClient } from "../security/secure-keys.js";
80
+ import {
81
+ onCesClientChanged,
82
+ setCesClient,
83
+ setCesReconnect,
84
+ } from "../security/secure-keys.js";
81
85
  import { seedCatalogSkillMemories } from "../skills/skill-memory.js";
82
86
  import { UsageTelemetryReporter } from "../telemetry/usage-telemetry-reporter.js";
83
87
  import { getDeviceId } from "../util/device-id.js";
@@ -109,6 +113,7 @@ import {
109
113
  createGuardianActionCopyGenerator,
110
114
  createGuardianFollowUpConversationGenerator,
111
115
  } from "./guardian-action-generators.js";
116
+ import { backfillSlackInjectionTemplates } from "./handlers/config-slack-channel.js";
112
117
  import {
113
118
  cancelGeneration,
114
119
  clearAllConversations,
@@ -282,7 +287,7 @@ export async function runDaemon(): Promise<void> {
282
287
  log.info("Daemon startup: workspace migrations complete");
283
288
 
284
289
  // Backfill oauth_connection rows for manual-token providers (Telegram,
285
- // Slack channel) that already have keychain credentials from before the
290
+ // Slack channel) that already have stored credentials from before the
286
291
  // oauth_connection migration. Safe to call on every startup.
287
292
  //
288
293
  // Must run AFTER workspace migrations.
@@ -297,6 +302,17 @@ export async function runDaemon(): Promise<void> {
297
302
  );
298
303
  }
299
304
 
305
+ // Backfill injection templates on Slack bot token credentials so the
306
+ // credential proxy can inject Authorization headers. Safe on every startup.
307
+ try {
308
+ backfillSlackInjectionTemplates();
309
+ } catch (err) {
310
+ log.warn(
311
+ { err },
312
+ "Slack injection template backfill failed — continuing startup",
313
+ );
314
+ }
315
+
300
316
  // Now that workspace migrations have run (including 003-seed-device-id
301
317
  // which may copy the legacy installationId into device.json), it is safe
302
318
  // to read the device ID and set the Sentry tag.
@@ -483,6 +499,41 @@ export async function runDaemon(): Promise<void> {
483
499
  setCesClient(client);
484
500
  }
485
501
  }
502
+
503
+ // Register CES reconnection callback so the credential layer can
504
+ // re-establish the connection when the transport dies, instead of
505
+ // falling back to the encrypted file store.
506
+ if (cesResult.processManager) {
507
+ const pm = cesResult.processManager;
508
+ setCesReconnect(async () => {
509
+ try {
510
+ await pm.stop();
511
+ const transport = await pm.start();
512
+ const newClient = createCesClient(transport);
513
+ const proxyCtx = await resolveManagedProxyContext();
514
+ const { accepted, reason } = await newClient.handshake(
515
+ proxyCtx.assistantApiKey
516
+ ? { assistantApiKey: proxyCtx.assistantApiKey }
517
+ : undefined,
518
+ );
519
+ if (accepted) {
520
+ log.info("CES reconnection handshake accepted");
521
+ return newClient;
522
+ }
523
+ log.warn({ reason }, "CES reconnection handshake rejected");
524
+ newClient.close();
525
+ await pm.stop().catch(() => {});
526
+ return undefined;
527
+ } catch (err) {
528
+ log.warn(
529
+ { error: err instanceof Error ? err.message : String(err) },
530
+ "CES reconnection attempt failed",
531
+ );
532
+ await pm.stop().catch(() => {});
533
+ return undefined;
534
+ }
535
+ });
536
+ }
486
537
  }
487
538
 
488
539
  await initializeProvidersAndTools(config);
@@ -492,6 +543,11 @@ export async function runDaemon(): Promise<void> {
492
543
  log.info("Daemon startup: starting DaemonServer");
493
544
  const server = new DaemonServer();
494
545
  server.setCes(await cesStartupPromise);
546
+
547
+ // Keep the server's CES client ref in sync after reconnection so that
548
+ // secret routes and new conversations use the fresh client.
549
+ onCesClientChanged((client) => server.updateCesClient(client));
550
+
495
551
  await server.start();
496
552
  log.info("Daemon startup: DaemonServer started");
497
553
 
@@ -839,6 +895,9 @@ export async function runDaemon(): Promise<void> {
839
895
  getHandlerContext: () => server.getHandlerContext(),
840
896
  }),
841
897
  getCesClient: () => server.getCesClient(),
898
+ onProviderCredentialsChanged: () =>
899
+ server.refreshConversationsForProviderChange(),
900
+ getHeartbeatService: () => server.getHeartbeatService(),
842
901
  });
843
902
 
844
903
  // Inject voice bridge deps BEFORE attempting to start the HTTP server.
@@ -1092,8 +1151,19 @@ export async function runDaemon(): Promise<void> {
1092
1151
  const heartbeatConfig = config.heartbeat;
1093
1152
  const heartbeat = new HeartbeatService({
1094
1153
  processMessage: (conversationId, content) =>
1095
- server.processMessage(conversationId, content),
1154
+ server.processMessage(conversationId, content, undefined, {
1155
+ trustContext: {
1156
+ sourceChannel: "vellum",
1157
+ trustClass: "guardian",
1158
+ },
1159
+ }),
1096
1160
  alerter: (alert) => server.broadcast(alert),
1161
+ onConversationCreated: (info) =>
1162
+ server.broadcast({
1163
+ type: "heartbeat_conversation_created",
1164
+ conversationId: info.conversationId,
1165
+ title: info.title,
1166
+ }),
1097
1167
  });
1098
1168
  heartbeat.start();
1099
1169
  server.setHeartbeatService(heartbeat);
@@ -25,20 +25,6 @@ export interface AcpSessionUpdate {
25
25
  toolStatus?: string;
26
26
  }
27
27
 
28
- export interface AcpPermissionRequest {
29
- type: "acp_permission_request";
30
- acpSessionId: string;
31
- requestId: string;
32
- toolTitle: string;
33
- toolKind: string;
34
- rawInput?: unknown;
35
- options: Array<{
36
- optionId: string;
37
- name: string;
38
- kind: "allow_once" | "allow_always" | "reject_once" | "reject_always";
39
- }>;
40
- }
41
-
42
28
  export interface AcpSessionCompleted {
43
29
  type: "acp_session_completed";
44
30
  acpSessionId: string;
@@ -61,6 +47,5 @@ export interface AcpSessionError {
61
47
  export type _AcpServerMessages =
62
48
  | AcpSessionSpawned
63
49
  | AcpSessionUpdate
64
- | AcpPermissionRequest
65
50
  | AcpSessionCompleted
66
51
  | AcpSessionError;
@@ -372,6 +372,7 @@ export type ConversationErrorCode =
372
372
  | "PROVIDER_ORDERING"
373
373
  | "PROVIDER_WEB_SEARCH"
374
374
  | "PROVIDER_NOT_CONFIGURED"
375
+ | "MANAGED_KEY_INVALID"
375
376
  | "CONTEXT_TOO_LARGE"
376
377
  | "CONVERSATION_ABORTED"
377
378
  | "CONVERSATION_PROCESSING_FAILED"
@@ -47,6 +47,8 @@ export interface GuardianActionDecisionResponse {
47
47
  resolverFailureReason?: string;
48
48
  requestId?: string;
49
49
  userText?: string;
50
+ /** Resolver reply text for the guardian (e.g. verification code for access requests). */
51
+ replyText?: string;
50
52
  }
51
53
 
52
54
  // --- Domain-level union aliases (consumed by the barrel file) ---
@@ -15,6 +15,11 @@ export interface HostBashRequest {
15
15
  env?: Record<string, string>;
16
16
  }
17
17
 
18
+ export interface HostBashCancelRequest {
19
+ type: "host_bash_cancel";
20
+ requestId: string;
21
+ }
22
+
18
23
  // --- Domain-level union aliases (consumed by the barrel file) ---
19
24
 
20
- export type _HostBashServerMessages = HostBashRequest;
25
+ export type _HostBashServerMessages = HostBashRequest | HostBashCancelRequest;
@@ -14,6 +14,11 @@ export interface HostCuRequest {
14
14
  reasoning?: string;
15
15
  }
16
16
 
17
+ export interface HostCuCancelRequest {
18
+ type: "host_cu_cancel";
19
+ requestId: string;
20
+ }
21
+
17
22
  // --- Domain-level union aliases (consumed by the barrel file) ---
18
23
 
19
- export type _HostCuServerMessages = HostCuRequest;
24
+ export type _HostCuServerMessages = HostCuRequest | HostCuCancelRequest;
@@ -39,6 +39,11 @@ export type HostFileRequest =
39
39
  | HostFileWriteRequest
40
40
  | HostFileEditRequest;
41
41
 
42
+ export interface HostFileCancelRequest {
43
+ type: "host_file_cancel";
44
+ requestId: string;
45
+ }
46
+
42
47
  // --- Domain-level union aliases (consumed by the barrel file) ---
43
48
 
44
- export type _HostFileServerMessages = HostFileRequest;
49
+ export type _HostFileServerMessages = HostFileRequest | HostFileCancelRequest;
@@ -188,7 +188,6 @@ export interface IntegrationConnectResult {
188
188
  accountInfo?: string | null;
189
189
  error?: string | null;
190
190
  setupRequired?: boolean;
191
- setupSkillId?: string;
192
191
  setupHint?: string;
193
192
  }
194
193
 
@@ -21,7 +21,6 @@ export interface MemoryRecalled {
21
21
  model: string;
22
22
  degradation?: MemoryRecalledDegradation;
23
23
  semanticHits: number;
24
- recencyHits: number;
25
24
  tier1Count: number;
26
25
  tier2Count: number;
27
26
  hybridSearchLatencyMs: number;
@@ -44,7 +44,7 @@ export interface SecretResponse {
44
44
  type: "secret_response";
45
45
  requestId: string;
46
46
  value?: string; // undefined = user cancelled
47
- /** How the secret should be delivered: 'store' persists to keychain (default), 'transient_send' for one-time use without persisting. */
47
+ /** How the secret should be delivered: 'store' persists to credential store (default), 'transient_send' for one-time use without persisting. */
48
48
  delivery?: "store" | "transient_send";
49
49
  }
50
50
 
@@ -156,6 +156,14 @@ export interface ConfirmationRequest {
156
156
  temporaryOptionsAvailable?: Array<"allow_10m" | "allow_conversation">;
157
157
  /** The tool_use block ID for client-side correlation with specific tool calls. */
158
158
  toolUseId?: string;
159
+ /** ACP tool kind from the agent (e.g. "read", "edit", "execute"). Present only for ACP permission requests. */
160
+ acpToolKind?: string;
161
+ /** ACP permission options from the agent. Present only for ACP permission requests. Clients should use these to render the correct buttons. */
162
+ acpOptions?: Array<{
163
+ optionId: string;
164
+ name: string;
165
+ kind: "allow_once" | "allow_always" | "reject_once" | "reject_always";
166
+ }>;
159
167
  }
160
168
 
161
169
  export interface SecretRequest {
@@ -84,6 +84,13 @@ export interface HeartbeatAlert {
84
84
  body: string;
85
85
  }
86
86
 
87
+ /** Server push — broadcast when a heartbeat creates a conversation. */
88
+ export interface HeartbeatConversationCreated {
89
+ type: "heartbeat_conversation_created";
90
+ conversationId: string;
91
+ title: string;
92
+ }
93
+
87
94
  export interface HeartbeatConfigResponse {
88
95
  type: "heartbeat_config_response";
89
96
  enabled: boolean;
@@ -91,6 +98,7 @@ export interface HeartbeatConfigResponse {
91
98
  activeHoursStart: number | null;
92
99
  activeHoursEnd: number | null;
93
100
  nextRunAt: number | null;
101
+ lastRunAt: number | null;
94
102
  success: boolean;
95
103
  error?: string;
96
104
  }
@@ -141,6 +149,7 @@ export type _SchedulesClientMessages =
141
149
  export type _SchedulesServerMessages =
142
150
  | SchedulesListResponse
143
151
  | HeartbeatAlert
152
+ | HeartbeatConversationCreated
144
153
  | HeartbeatConfigResponse
145
154
  | HeartbeatRunsListResponse
146
155
  | HeartbeatRunNowResponse