@vellumai/assistant 0.4.37 → 0.4.40

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 (169) hide show
  1. package/ARCHITECTURE.md +3 -3
  2. package/README.md +13 -13
  3. package/bun.lock +80 -24
  4. package/docs/architecture/integrations.md +126 -128
  5. package/docs/runbook-trusted-contacts.md +1 -1
  6. package/docs/trusted-contact-access.md +12 -12
  7. package/package.json +3 -1
  8. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -14
  9. package/src/__tests__/app-bundler.test.ts +209 -0
  10. package/src/__tests__/app-compiler.test.ts +279 -0
  11. package/src/__tests__/app-executors.test.ts +293 -483
  12. package/src/__tests__/app-migration.test.ts +148 -0
  13. package/src/__tests__/app-routes-csp.test.ts +202 -0
  14. package/src/__tests__/avatar-e2e.test.ts +452 -0
  15. package/src/__tests__/avatar-generator.test.ts +193 -0
  16. package/src/__tests__/avatar-router.test.ts +186 -0
  17. package/src/__tests__/browser-download-timeout.test.ts +28 -0
  18. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +9 -9
  19. package/src/__tests__/call-domain.test.ts +3 -7
  20. package/src/__tests__/credential-security-e2e.test.ts +19 -12
  21. package/src/__tests__/credentials-cli.test.ts +30 -4
  22. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +1 -1
  23. package/src/__tests__/handlers-slack-config.test.ts +0 -72
  24. package/src/__tests__/handlers-telegram-config.test.ts +19 -12
  25. package/src/__tests__/handlers-twitter-config.test.ts +105 -48
  26. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  27. package/src/__tests__/integration-status.test.ts +15 -5
  28. package/src/__tests__/integrations-cli.test.ts +1 -1
  29. package/src/__tests__/invite-redemption-service.test.ts +62 -7
  30. package/src/__tests__/ipc-snapshot.test.ts +0 -8
  31. package/src/__tests__/managed-avatar-client.test.ts +280 -0
  32. package/src/__tests__/mcp-cli.test.ts +3 -3
  33. package/src/__tests__/oauth-cli.test.ts +203 -0
  34. package/src/__tests__/relay-server.test.ts +3 -3
  35. package/src/__tests__/secret-onetime-send.test.ts +19 -12
  36. package/src/__tests__/secure-keys.test.ts +78 -0
  37. package/src/__tests__/session-messaging-secret-redirect.test.ts +3 -0
  38. package/src/__tests__/slack-channel-config.test.ts +23 -16
  39. package/src/__tests__/slack-share-routes.test.ts +263 -0
  40. package/src/__tests__/sms-messaging-provider.test.ts +3 -1
  41. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +7 -7
  42. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  43. package/src/__tests__/trusted-contact-verification.test.ts +10 -10
  44. package/src/__tests__/twilio-config.test.ts +15 -36
  45. package/src/__tests__/twilio-provider.test.ts +4 -0
  46. package/src/__tests__/twitter-auth-handler.test.ts +27 -14
  47. package/src/__tests__/twitter-cli-error-shaping.test.ts +1 -1
  48. package/src/__tests__/twitter-cli-routing.test.ts +38 -53
  49. package/src/__tests__/twitter-oauth-client.test.ts +18 -47
  50. package/src/__tests__/voice-invite-redemption.test.ts +27 -3
  51. package/src/amazon/cart.ts +1 -1
  52. package/src/amazon/client.ts +89 -7
  53. package/src/approvals/guardian-request-resolvers.ts +2 -2
  54. package/src/bundler/app-bundler.ts +77 -32
  55. package/src/bundler/app-compiler.ts +195 -0
  56. package/src/bundler/manifest.ts +1 -1
  57. package/src/bundler/package-resolver.ts +185 -0
  58. package/src/calls/call-domain.ts +4 -14
  59. package/src/calls/relay-server.ts +2 -2
  60. package/src/calls/twilio-config.ts +5 -24
  61. package/src/calls/twilio-rest.ts +19 -5
  62. package/src/cli/amazon.ts +74 -249
  63. package/src/cli/audit.ts +2 -2
  64. package/src/cli/autonomy.ts +9 -9
  65. package/src/cli/channels.ts +5 -5
  66. package/src/cli/completions.ts +27 -27
  67. package/src/cli/config.ts +14 -14
  68. package/src/cli/contacts.ts +27 -27
  69. package/src/cli/credentials.ts +28 -28
  70. package/src/cli/dev.ts +2 -2
  71. package/src/cli/doctor.ts +2 -2
  72. package/src/cli/email.ts +82 -82
  73. package/src/cli/influencer.ts +13 -13
  74. package/src/cli/integrations.ts +19 -144
  75. package/src/cli/keys.ts +10 -10
  76. package/src/cli/map.ts +4 -4
  77. package/src/cli/mcp.ts +17 -17
  78. package/src/cli/memory.ts +18 -18
  79. package/src/cli/notifications.ts +13 -13
  80. package/src/cli/oauth.ts +77 -0
  81. package/src/cli/program.ts +2 -0
  82. package/src/cli/sequence.ts +27 -27
  83. package/src/cli/sessions.ts +12 -12
  84. package/src/cli/trust.ts +8 -8
  85. package/src/cli/twitter.ts +124 -70
  86. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  87. package/src/config/bundled-skills/agentmail/SKILL.md +34 -34
  88. package/src/config/bundled-skills/amazon/SKILL.md +54 -54
  89. package/src/config/bundled-skills/app-builder/SKILL.md +137 -3
  90. package/src/config/bundled-skills/app-builder/tools/app-create.ts +10 -4
  91. package/src/config/bundled-skills/configure-settings/SKILL.md +18 -18
  92. package/src/config/bundled-skills/contacts/SKILL.md +12 -12
  93. package/src/config/bundled-skills/doordash/lib/client.ts +7 -9
  94. package/src/config/bundled-skills/email-setup/SKILL.md +4 -4
  95. package/src/config/bundled-skills/frontend-design/icon.svg +16 -0
  96. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +143 -162
  97. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +4 -4
  98. package/src/config/bundled-skills/influencer/SKILL.md +13 -13
  99. package/src/config/bundled-skills/mcp-setup/SKILL.md +11 -11
  100. package/src/config/bundled-skills/phone-calls/SKILL.md +48 -54
  101. package/src/config/bundled-skills/public-ingress/SKILL.md +6 -6
  102. package/src/config/bundled-skills/slack-app-setup/SKILL.md +1 -1
  103. package/src/config/bundled-skills/sms-setup/SKILL.md +3 -3
  104. package/src/config/bundled-skills/telegram-setup/SKILL.md +2 -2
  105. package/src/config/bundled-skills/twilio-setup/SKILL.md +136 -225
  106. package/src/config/bundled-skills/twitter/SKILL.md +68 -44
  107. package/src/config/bundled-skills/voice-setup/SKILL.md +2 -2
  108. package/src/config/core-schema.ts +26 -0
  109. package/src/config/env.ts +4 -0
  110. package/src/config/feature-flag-registry.json +9 -1
  111. package/src/config/schema.ts +8 -0
  112. package/src/config/system-prompt.ts +6 -3
  113. package/src/config/templates/BOOTSTRAP.md +7 -5
  114. package/src/contacts/contacts-write.ts +5 -1
  115. package/src/daemon/handlers/apps.ts +31 -4
  116. package/src/daemon/handlers/config-ingress.ts +3 -3
  117. package/src/daemon/handlers/config-integrations.ts +120 -49
  118. package/src/daemon/handlers/config-slack-channel.ts +26 -7
  119. package/src/daemon/handlers/config-slack.ts +1 -54
  120. package/src/daemon/handlers/config-telegram.ts +28 -10
  121. package/src/daemon/handlers/config.ts +1 -4
  122. package/src/daemon/handlers/twitter-auth.ts +11 -4
  123. package/src/daemon/ipc-contract/apps.ts +0 -13
  124. package/src/daemon/ipc-contract-inventory.json +0 -2
  125. package/src/daemon/lifecycle.ts +8 -1
  126. package/src/daemon/session-messaging.ts +2 -2
  127. package/src/daemon/tool-side-effects.ts +30 -0
  128. package/src/email/providers/agentmail.ts +1 -1
  129. package/src/email/providers/index.ts +1 -1
  130. package/src/email/service.ts +1 -1
  131. package/src/gallery/default-gallery.ts +538 -0
  132. package/src/gallery/gallery-manifest.ts +5 -1
  133. package/src/influencer/client.ts +8 -6
  134. package/src/mcp/client.ts +1 -1
  135. package/src/media/avatar-router.ts +99 -0
  136. package/src/media/avatar-types.ts +60 -0
  137. package/src/media/managed-avatar-client.ts +189 -0
  138. package/src/memory/app-migration.ts +114 -0
  139. package/src/memory/app-store.ts +11 -0
  140. package/src/memory/qdrant-client.ts +1 -1
  141. package/src/messaging/providers/slack/client.ts +12 -2
  142. package/src/messaging/providers/sms/adapter.ts +6 -10
  143. package/src/migrations/data-layout.ts +8 -1
  144. package/src/oauth/token-persistence.ts +9 -6
  145. package/src/runtime/assistant-scope.ts +5 -0
  146. package/src/runtime/auth/route-policy.ts +4 -0
  147. package/src/runtime/channel-readiness-service.ts +9 -4
  148. package/src/runtime/gateway-internal-client.ts +11 -3
  149. package/src/runtime/http-server.ts +2 -0
  150. package/src/runtime/invite-redemption-service.ts +23 -13
  151. package/src/runtime/middleware/twilio-validation.ts +2 -2
  152. package/src/runtime/routes/app-routes.ts +131 -3
  153. package/src/runtime/routes/inbound-stages/verification-intercept.ts +3 -3
  154. package/src/runtime/routes/integration-routes.ts +2 -2
  155. package/src/runtime/routes/slack-share-routes.ts +235 -0
  156. package/src/runtime/routes/twilio-routes.ts +47 -34
  157. package/src/schedule/integration-status.ts +2 -3
  158. package/src/security/token-manager.ts +11 -3
  159. package/src/tools/apps/executors.ts +116 -8
  160. package/src/tools/browser/browser-manager.ts +30 -2
  161. package/src/tools/browser/chrome-cdp.ts +31 -3
  162. package/src/tools/credentials/vault.ts +9 -7
  163. package/src/tools/executor.ts +4 -0
  164. package/src/tools/system/avatar-generator.ts +55 -34
  165. package/src/twitter/client.ts +1 -1
  166. package/src/twitter/oauth-client.ts +31 -43
  167. package/src/twitter/router.ts +25 -23
  168. package/src/util/platform.ts +5 -0
  169. package/src/slack/slack-webhook.ts +0 -66
@@ -190,7 +190,7 @@ sequenceDiagram
190
190
 
191
191
  #### Dual-Path Operation Architecture
192
192
 
193
- The strategy router (`router.ts`) determines whether to use the OAuth or browser path for each operation. The preferred strategy is read from the `twitterOperationStrategy` config field (default: `auto`).
193
+ The strategy router (`router.ts`) determines whether to use the OAuth or browser path for each operation. The preferred strategy is read from the `twitter.operationStrategy` config field (default: `auto`).
194
194
 
195
195
  ```mermaid
196
196
  flowchart TD
@@ -215,19 +215,19 @@ flowchart TD
215
215
  - **`oauth`**: Uses OAuth exclusively. Fails with an actionable error if credentials are not configured.
216
216
  - **`browser`**: Uses CDP exclusively. Fails with an actionable error if the browser session has expired.
217
217
 
218
- The strategy is persisted in the Vellum config file as `twitterOperationStrategy` and can be changed via `vellum x strategy set <oauth|browser|auto>`.
218
+ The strategy is persisted in the Vellum config file as `twitter.operationStrategy` and can be changed via `vellum x strategy set <oauth|browser|auto>`.
219
219
 
220
220
  #### Twitter OAuth2 Specifics
221
221
 
222
- | Aspect | Detail |
223
- |--------|--------|
224
- | Auth URL | `https://twitter.com/i/oauth2/authorize` (from provider profile) |
225
- | Token URL | `https://api.x.com/2/oauth2/token` (from provider profile) |
226
- | Flow | PKCE (S256), optional client secret, via connect orchestrator |
227
- | Default scopes | `tweet.read`, `tweet.write`, `users.read`, `offline.access` (from provider profile) |
228
- | Identity verification | Provider profile `identityVerifier` → `GET https://api.x.com/2/users/me` with Bearer token |
229
- | Credential names | Canonical: `client_id`, `client_secret`; reads fall back to legacy `oauth_client_id`, `oauth_client_secret` |
230
- | IPC messages | `oauth_connect_start` / `oauth_connect_result` (generic), plus legacy `twitter_auth_start` / `twitter_auth_status` |
222
+ | Aspect | Detail |
223
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------ |
224
+ | Auth URL | `https://twitter.com/i/oauth2/authorize` (from provider profile) |
225
+ | Token URL | `https://api.x.com/2/oauth2/token` (from provider profile) |
226
+ | Flow | PKCE (S256), optional client secret, via connect orchestrator |
227
+ | Default scopes | `tweet.read`, `tweet.write`, `users.read`, `offline.access` (from provider profile) |
228
+ | Identity verification | Provider profile `identityVerifier` → `GET https://api.x.com/2/users/me` with Bearer token |
229
+ | Credential names | Canonical: `client_id`, `client_secret`; reads fall back to legacy `oauth_client_id`, `oauth_client_secret` |
230
+ | IPC messages | `oauth_connect_start` / `oauth_connect_result` (generic), plus legacy `twitter_auth_start` / `twitter_auth_status` |
231
231
 
232
232
  #### Twitter Credential Metadata Structure
233
233
 
@@ -254,73 +254,73 @@ When the OAuth2 flow completes, the handler stores credential metadata at `integ
254
254
 
255
255
  #### Available Twitter Tools
256
256
 
257
- | Tool / Command | Mechanism | Description |
258
- |----------------|-----------|-------------|
259
- | `vellum x post` | Strategy router (OAuth or CDP) | Post a tweet. Uses the configured strategy (`auto` by default). |
260
- | `vellum x reply` | Strategy router (OAuth or CDP) | Reply to a tweet. Uses the configured strategy (`auto` by default). |
261
- | `vellum x timeline` | CDP | Fetch a user's recent tweets. Browser path only. |
262
- | `vellum x search` | CDP | Search tweets. Browser path only. |
263
- | `vellum x home` | CDP | Fetch home timeline. Browser path only. |
264
- | `vellum x notifications` | CDP | Fetch notifications. Browser path only. |
265
- | `vellum x bookmarks` | CDP | Fetch bookmarks. Browser path only. |
266
- | `vellum x likes` | CDP | Fetch a user's liked tweets. Browser path only. |
267
- | `vellum x followers` | CDP | Fetch a user's followers. Browser path only. |
268
- | `vellum x following` | CDP | Fetch who a user follows. Browser path only. |
269
- | `vellum x media` | CDP | Fetch a user's media tweets. Browser path only. |
270
- | `vellum x strategy` | Config | Get or set the operation strategy (`oauth`, `browser`, `auto`). |
271
- | `vellum x status` | IPC + local | Check browser session, OAuth connection, and strategy status. |
257
+ | Tool / Command | Mechanism | Description |
258
+ | ------------------------ | ------------------------------ | ------------------------------------------------------------------- |
259
+ | `vellum x post` | Strategy router (OAuth or CDP) | Post a tweet. Uses the configured strategy (`auto` by default). |
260
+ | `vellum x reply` | Strategy router (OAuth or CDP) | Reply to a tweet. Uses the configured strategy (`auto` by default). |
261
+ | `vellum x timeline` | CDP | Fetch a user's recent tweets. Browser path only. |
262
+ | `vellum x search` | CDP | Search tweets. Browser path only. |
263
+ | `vellum x home` | CDP | Fetch home timeline. Browser path only. |
264
+ | `vellum x notifications` | CDP | Fetch notifications. Browser path only. |
265
+ | `vellum x bookmarks` | CDP | Fetch bookmarks. Browser path only. |
266
+ | `vellum x likes` | CDP | Fetch a user's liked tweets. Browser path only. |
267
+ | `vellum x followers` | CDP | Fetch a user's followers. Browser path only. |
268
+ | `vellum x following` | CDP | Fetch who a user follows. Browser path only. |
269
+ | `vellum x media` | CDP | Fetch a user's media tweets. Browser path only. |
270
+ | `vellum x strategy` | Config | Get or set the operation strategy (`oauth`, `browser`, `auto`). |
271
+ | `vellum x status` | IPC + local | Check browser session, OAuth connection, and strategy status. |
272
272
 
273
273
  Note: OAuth2 scopes (`tweet.read`, `tweet.write`, `users.read`, `offline.access`) are requested during the auth flow. The `post` and `reply` operations use these tokens when the OAuth path is selected. Read operations require the browser path.
274
274
 
275
275
  ### Key Design Decisions
276
276
 
277
- | Decision | Rationale |
278
- |----------|-----------|
279
- | PKCE by default, optional client_secret | Desktop apps prefer PKCE; some providers (Slack) require a secret, which is stored in credential metadata for autonomous refresh |
280
- | Shared connect orchestrator | All OAuth providers route through `orchestrateOAuthConnect()`, which resolves profiles, enforces scope policy, runs the flow, stores tokens, and verifies identity. Adding a provider is a declarative profile entry, not new orchestration code |
281
- | Canonical credential naming | Writes use `client_id`/`client_secret`; reads fall back to legacy `oauth_client_id`/`oauth_client_secret` for backward compatibility |
282
- | Gateway callback transport | OAuth callbacks are now routed through the gateway at `${ingress.publicBaseUrl}/webhooks/oauth/callback` instead of a loopback redirect URI. This enables OAuth flows to work in remote and tunneled deployments. |
283
- | Unified `MessagingProvider` interface | All platforms implement the same contract; generic tools work immediately for new providers |
284
- | Twitter outside unified messaging | Twitter is a broadcast/read platform, not a conversation platform — it doesn't fit the `MessagingProvider` contract |
285
- | Dual-path Twitter strategy | OAuth is more reliable for posting (no browser session dependency) but only supports post/reply. Browser path supports all operations. `auto` strategy gives the best of both: OAuth when possible, browser as fallback. User can override via `vellum x strategy set`. |
286
- | Provider auto-selection | If only one provider is connected, tools skip the `platform` parameter — seamless single-platform UX |
287
- | Token expiry in credential metadata | Reuses existing `CredentialMetadata` store; `expiresAt` field enables proactive refresh with 5min buffer |
288
- | Confidence scores on medium-risk tools | LLM self-reports confidence (0-1); enables future trust calibration without blocking execution |
289
- | Platform-specific extension tools | Operations unique to one platform (e.g. Gmail labels, Slack reactions) are separate tools, not forced into the generic interface |
290
- | Twitter identity verification before token storage | OAuth2 tokens are only persisted after a successful `GET /2/users/me` call, preventing storage of invalid or mismatched credentials |
277
+ | Decision | Rationale |
278
+ | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
279
+ | PKCE by default, optional client_secret | Desktop apps prefer PKCE; some providers (Slack) require a secret, which is stored in credential metadata for autonomous refresh |
280
+ | Shared connect orchestrator | All OAuth providers route through `orchestrateOAuthConnect()`, which resolves profiles, enforces scope policy, runs the flow, stores tokens, and verifies identity. Adding a provider is a declarative profile entry, not new orchestration code |
281
+ | Canonical credential naming | Writes use `client_id`/`client_secret`; reads fall back to legacy `oauth_client_id`/`oauth_client_secret` for backward compatibility |
282
+ | Gateway callback transport | OAuth callbacks are now routed through the gateway at `${ingress.publicBaseUrl}/webhooks/oauth/callback` instead of a loopback redirect URI. This enables OAuth flows to work in remote and tunneled deployments. |
283
+ | Unified `MessagingProvider` interface | All platforms implement the same contract; generic tools work immediately for new providers |
284
+ | Twitter outside unified messaging | Twitter is a broadcast/read platform, not a conversation platform — it doesn't fit the `MessagingProvider` contract |
285
+ | Dual-path Twitter strategy | OAuth is more reliable for posting (no browser session dependency) but only supports post/reply. Browser path supports all operations. `auto` strategy gives the best of both: OAuth when possible, browser as fallback. User can override via `vellum x strategy set`. |
286
+ | Provider auto-selection | If only one provider is connected, tools skip the `platform` parameter — seamless single-platform UX |
287
+ | Token expiry in credential metadata | Reuses existing `CredentialMetadata` store; `expiresAt` field enables proactive refresh with 5min buffer |
288
+ | Confidence scores on medium-risk tools | LLM self-reports confidence (0-1); enables future trust calibration without blocking execution |
289
+ | Platform-specific extension tools | Operations unique to one platform (e.g. Gmail labels, Slack reactions) are separate tools, not forced into the generic interface |
290
+ | Twitter identity verification before token storage | OAuth2 tokens are only persisted after a successful `GET /2/users/me` call, preventing storage of invalid or mismatched credentials |
291
291
 
292
292
  ### Source Files
293
293
 
294
- | File | Role |
295
- |------|------|
296
- | `assistant/src/security/oauth2.ts` | OAuth2 flow: PKCE or client_secret, Bun.serve callback, token exchange |
297
- | `assistant/src/security/token-manager.ts` | `withValidToken()` — auto-refresh, 401 retry, expiry buffer |
298
- | `assistant/src/messaging/provider.ts` | `MessagingProvider` interface |
299
- | `assistant/src/messaging/provider-types.ts` | Platform-agnostic types (Conversation, Message, SearchResult) |
300
- | `assistant/src/messaging/registry.ts` | Provider registry: register, lookup, list connected |
301
- | `assistant/src/messaging/activity-analyzer.ts` | Activity classification for conversations |
302
- | `assistant/src/messaging/style-analyzer.ts` | Writing style extraction from message corpus |
303
- | `assistant/src/messaging/draft-store.ts` | Local draft storage (platform/id JSON files) |
304
- | `assistant/src/messaging/providers/slack/` | Slack adapter, client, types |
305
- | `assistant/src/messaging/providers/gmail/` | Gmail adapter, client, types |
306
- | `assistant/src/config/bundled-skills/messaging/` | Unified messaging skill (SKILL.md, TOOLS.json, tools/) |
307
- | `assistant/src/watcher/providers/slack.ts` | Slack watcher for DMs, mentions, thread replies |
308
- | `assistant/src/watcher/providers/gmail.ts` | Gmail watcher using History API |
309
- | `assistant/src/watcher/providers/github.ts` | GitHub watcher for PRs, issues, review requests, and mentions |
310
- | `assistant/src/watcher/providers/linear.ts` | Linear watcher for assigned issues, status changes, and @mentions |
311
- | `assistant/src/oauth/provider-profiles.ts` | Provider profile registry: auth URLs, token URLs, scopes, policies, identity verifiers |
312
- | `assistant/src/oauth/connect-orchestrator.ts` | Shared OAuth connect orchestrator: profile resolution, scope policy, flow execution, token storage |
313
- | `assistant/src/oauth/scope-policy.ts` | Deterministic scope resolution and policy enforcement |
314
- | `assistant/src/oauth/connect-types.ts` | Shared types: `OAuthProviderProfile`, `OAuthScopePolicy`, `OAuthConnectResult` |
315
- | `assistant/src/oauth/token-persistence.ts` | Token storage helper: persists tokens, metadata, and runs post-connect hooks |
316
- | `assistant/src/daemon/handlers/oauth-connect.ts` | Generic OAuth connect IPC handler (`oauth_connect_start` / `oauth_connect_result`) |
317
- | `assistant/src/daemon/handlers/twitter-auth.ts` | Legacy Twitter OAuth2 flow handlers (`twitter_auth_start`, `twitter_auth_status`) |
318
- | `assistant/src/twitter/client.ts` | Twitter CDP client: GraphQL mutations/queries via Chrome DevTools Protocol |
319
- | `assistant/src/twitter/oauth-client.ts` | OAuth-backed Twitter client: X API v2 post/reply via stored tokens using `withValidToken()` |
320
- | `assistant/src/twitter/router.ts` | Strategy router: selects OAuth or browser path based on `twitterOperationStrategy` config |
321
- | `assistant/src/twitter/session.ts` | Twitter browser session persistence (cookie import/export) |
322
- | `assistant/src/cli/twitter.ts` | `vellum x` CLI command group (post, reply, strategy, refresh, status, login, logout, and read operations) |
323
- | `assistant/src/config/bundled-skills/twitter/SKILL.md` | X (Twitter) bundled skill instructions |
294
+ | File | Role |
295
+ | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
296
+ | `assistant/src/security/oauth2.ts` | OAuth2 flow: PKCE or client_secret, Bun.serve callback, token exchange |
297
+ | `assistant/src/security/token-manager.ts` | `withValidToken()` — auto-refresh, 401 retry, expiry buffer |
298
+ | `assistant/src/messaging/provider.ts` | `MessagingProvider` interface |
299
+ | `assistant/src/messaging/provider-types.ts` | Platform-agnostic types (Conversation, Message, SearchResult) |
300
+ | `assistant/src/messaging/registry.ts` | Provider registry: register, lookup, list connected |
301
+ | `assistant/src/messaging/activity-analyzer.ts` | Activity classification for conversations |
302
+ | `assistant/src/messaging/style-analyzer.ts` | Writing style extraction from message corpus |
303
+ | `assistant/src/messaging/draft-store.ts` | Local draft storage (platform/id JSON files) |
304
+ | `assistant/src/messaging/providers/slack/` | Slack adapter, client, types |
305
+ | `assistant/src/messaging/providers/gmail/` | Gmail adapter, client, types |
306
+ | `assistant/src/config/bundled-skills/messaging/` | Unified messaging skill (SKILL.md, TOOLS.json, tools/) |
307
+ | `assistant/src/watcher/providers/slack.ts` | Slack watcher for DMs, mentions, thread replies |
308
+ | `assistant/src/watcher/providers/gmail.ts` | Gmail watcher using History API |
309
+ | `assistant/src/watcher/providers/github.ts` | GitHub watcher for PRs, issues, review requests, and mentions |
310
+ | `assistant/src/watcher/providers/linear.ts` | Linear watcher for assigned issues, status changes, and @mentions |
311
+ | `assistant/src/oauth/provider-profiles.ts` | Provider profile registry: auth URLs, token URLs, scopes, policies, identity verifiers |
312
+ | `assistant/src/oauth/connect-orchestrator.ts` | Shared OAuth connect orchestrator: profile resolution, scope policy, flow execution, token storage |
313
+ | `assistant/src/oauth/scope-policy.ts` | Deterministic scope resolution and policy enforcement |
314
+ | `assistant/src/oauth/connect-types.ts` | Shared types: `OAuthProviderProfile`, `OAuthScopePolicy`, `OAuthConnectResult` |
315
+ | `assistant/src/oauth/token-persistence.ts` | Token storage helper: persists tokens, metadata, and runs post-connect hooks |
316
+ | `assistant/src/daemon/handlers/oauth-connect.ts` | Generic OAuth connect IPC handler (`oauth_connect_start` / `oauth_connect_result`) |
317
+ | `assistant/src/daemon/handlers/twitter-auth.ts` | Legacy Twitter OAuth2 flow handlers (`twitter_auth_start`, `twitter_auth_status`) |
318
+ | `assistant/src/twitter/client.ts` | Twitter CDP client: GraphQL mutations/queries via Chrome DevTools Protocol |
319
+ | `assistant/src/twitter/oauth-client.ts` | OAuth-backed Twitter client: X API v2 post/reply via stored tokens using `withValidToken()` |
320
+ | `assistant/src/twitter/router.ts` | Strategy router: selects OAuth or browser path based on `twitter.operationStrategy` config |
321
+ | `assistant/src/twitter/session.ts` | Twitter browser session persistence (cookie import/export) |
322
+ | `assistant/src/cli/twitter.ts` | `vellum x` CLI command group (post, reply, strategy, refresh, status, login, logout, and read operations) |
323
+ | `assistant/src/config/bundled-skills/twitter/SKILL.md` | X (Twitter) bundled skill instructions |
324
324
 
325
325
  ---
326
326
 
@@ -332,15 +332,15 @@ The OAuth extensibility layer makes adding a new OAuth provider a declarative op
332
332
 
333
333
  `assistant/src/oauth/provider-profiles.ts` contains the `PROVIDER_PROFILES` map — a canonical registry of well-known OAuth providers. Each profile (`OAuthProviderProfile`) declares:
334
334
 
335
- | Field | Purpose |
336
- |-------|---------|
337
- | `authUrl` / `tokenUrl` | OAuth2 authorization and token endpoints |
338
- | `defaultScopes` | Scopes requested on every connect attempt |
339
- | `scopePolicy` | Controls whether additional scopes are allowed (see Scope Policy below) |
340
- | `callbackTransport` | `'loopback'` (local redirect) or `'gateway'` (public ingress) |
341
- | `identityVerifier` | Async function that fetches human-readable account info (e.g. `@username`, email) after token exchange |
342
- | `setup` | Optional metadata for the generic OAuth setup skill (display name, dashboard URL, app type) |
343
- | `injectionTemplates` | Auto-applied credential injection rules for the script proxy |
335
+ | Field | Purpose |
336
+ | ---------------------- | ------------------------------------------------------------------------------------------------------ |
337
+ | `authUrl` / `tokenUrl` | OAuth2 authorization and token endpoints |
338
+ | `defaultScopes` | Scopes requested on every connect attempt |
339
+ | `scopePolicy` | Controls whether additional scopes are allowed (see Scope Policy below) |
340
+ | `callbackTransport` | `'loopback'` (local redirect) or `'gateway'` (public ingress) |
341
+ | `identityVerifier` | Async function that fetches human-readable account info (e.g. `@username`, email) after token exchange |
342
+ | `setup` | Optional metadata for the generic OAuth setup skill (display name, dashboard URL, app type) |
343
+ | `injectionTemplates` | Auto-applied credential injection rules for the script proxy |
344
344
 
345
345
  Registered providers: `integration:gmail`, `integration:slack`, `integration:notion`, `integration:twitter`. Short aliases (e.g. `gmail`, `twitter`) are resolved via `SERVICE_ALIASES`.
346
346
 
@@ -394,18 +394,17 @@ This replaces provider-specific IPC handlers — any provider in the registry ca
394
394
 
395
395
  ### Key Source Files
396
396
 
397
- | File | Role |
398
- |------|------|
399
- | `assistant/src/oauth/provider-profiles.ts` | Provider profile registry and alias resolution |
400
- | `assistant/src/oauth/scope-policy.ts` | Scope resolution and policy enforcement (pure, no I/O) |
401
- | `assistant/src/oauth/connect-orchestrator.ts` | Shared connect orchestrator (profile → scopes → flow → tokens) |
402
- | `assistant/src/oauth/connect-types.ts` | Shared types (`OAuthProviderProfile`, `OAuthScopePolicy`, `OAuthConnectResult`) |
403
- | `assistant/src/oauth/token-persistence.ts` | Token storage: keychain writes, metadata upsert, post-connect hooks |
404
- | `assistant/src/daemon/handlers/oauth-connect.ts` | Generic `oauth_connect_start` / `oauth_connect_result` IPC handler |
397
+ | File | Role |
398
+ | ------------------------------------------------ | ------------------------------------------------------------------------------- |
399
+ | `assistant/src/oauth/provider-profiles.ts` | Provider profile registry and alias resolution |
400
+ | `assistant/src/oauth/scope-policy.ts` | Scope resolution and policy enforcement (pure, no I/O) |
401
+ | `assistant/src/oauth/connect-orchestrator.ts` | Shared connect orchestrator (profile → scopes → flow → tokens) |
402
+ | `assistant/src/oauth/connect-types.ts` | Shared types (`OAuthProviderProfile`, `OAuthScopePolicy`, `OAuthConnectResult`) |
403
+ | `assistant/src/oauth/token-persistence.ts` | Token storage: keychain writes, metadata upsert, post-connect hooks |
404
+ | `assistant/src/daemon/handlers/oauth-connect.ts` | Generic `oauth_connect_start` / `oauth_connect_result` IPC handler |
405
405
 
406
406
  ---
407
407
 
408
-
409
408
  ---
410
409
 
411
410
  ## Script Proxy — Proxied Bash Execution and Credential Injection
@@ -536,14 +535,14 @@ sequenceDiagram
536
535
 
537
536
  **Policy decisions** are deterministic and structured:
538
537
 
539
- | Decision | Meaning |
540
- |---|---|
541
- | `matched` | Exactly one credential template matches the host — inject it |
542
- | `ambiguous` | Multiple credential templates match — caller must disambiguate |
543
- | `missing` | Credentials exist but none match this host — no rewrite |
544
- | `unauthenticated` | No credentials configured for the session |
538
+ | Decision | Meaning |
539
+ | ------------------------ | -------------------------------------------------------------------------- |
540
+ | `matched` | Exactly one credential template matches the host — inject it |
541
+ | `ambiguous` | Multiple credential templates match — caller must disambiguate |
542
+ | `missing` | Credentials exist but none match this host — no rewrite |
543
+ | `unauthenticated` | No credentials configured for the session |
545
544
  | `ask_missing_credential` | A known template pattern matches but no credential is bound to the session |
546
- | `ask_unauthenticated` | Completely unknown host — prompt for unauthenticated access |
545
+ | `ask_unauthenticated` | Completely unknown host — prompt for unauthenticated access |
547
546
 
548
547
  **Trust rule persistence**: The `createProxyApprovalCallback` in `session-tool-setup.ts` is wired into the session startup path and routes policy "ask" decisions through the existing `PermissionPrompter` UI. Trust rules use the `network_request` tool name (not `proxy:*`) with URL-based scope patterns (e.g., `https://api.example.com/*`), aligning with the `buildCommandCandidates()` allowlist generation in `checker.ts`.
549
548
 
@@ -566,10 +565,10 @@ Each proxy session is bound to a conversation and tracks authorized credential I
566
565
 
567
566
  The proxy generates and manages a local Certificate Authority for MITM interception:
568
567
 
569
- | Component | Location | Purpose |
570
- |---|---|---|
571
- | CA cert | `{dataDir}/proxy-ca/ca.pem` | Self-signed root cert (valid 10 years, permissions 0644) |
572
- | CA key | `{dataDir}/proxy-ca/ca-key.pem` | CA private key (permissions 0600) |
568
+ | Component | Location | Purpose |
569
+ | ---------- | ------------------------------------------ | -------------------------------------------------------- |
570
+ | CA cert | `{dataDir}/proxy-ca/ca.pem` | Self-signed root cert (valid 10 years, permissions 0644) |
571
+ | CA key | `{dataDir}/proxy-ca/ca-key.pem` | CA private key (permissions 0600) |
573
572
  | Leaf certs | `{dataDir}/proxy-ca/issued/{hostname}.pem` | Per-hostname certs (cached, verified against current CA) |
574
573
 
575
574
  `ensureLocalCA()` is idempotent — it only generates the CA if the files do not already exist. Leaf certificates are cached and revalidated via `X509Certificate.checkIssued()` to detect stale certs from a previous CA.
@@ -602,20 +601,20 @@ The proxy subsystem intercepts outbound HTTPS requests and injects stored creden
602
601
 
603
602
  ### Key Source Files
604
603
 
605
- | File | Role |
606
- |---|---|
607
- | `assistant/src/tools/network/script-proxy/server.ts` | Proxy server factory — HTTP forwarding, CONNECT handling, MITM dispatch |
608
- | `assistant/src/tools/network/script-proxy/policy.ts` | Policy engine — evaluates requests against credential templates |
609
- | `assistant/src/tools/network/script-proxy/mitm-handler.ts` | MITM TLS interception — loopback TLS server, request rewrite, upstream forwarding |
610
- | `assistant/src/tools/network/script-proxy/connect-tunnel.ts` | Plain CONNECT tunnel — raw TCP bidirectional pipe |
611
- | `assistant/src/tools/network/script-proxy/http-forwarder.ts` | HTTP proxy forwarder — absolute-URL form forwarding with policy callback |
612
- | `assistant/src/tools/network/script-proxy/session-manager.ts` | Session lifecycle — create, start, stop, idle timeout, env var generation |
613
- | `assistant/src/tools/network/script-proxy/certs.ts` | Local CA management — ensureLocalCA, issueLeafCert, getCAPath |
614
- | `assistant/src/tools/network/script-proxy/logging.ts` | Log sanitization (header/URL redaction) and safe decision trace builders for policy and credential resolution |
615
- | `assistant/src/tools/network/script-proxy/types.ts` | Type definitions — session, policy decisions, approval callback |
616
- | `assistant/src/tools/executor.ts` | `persistentDecisionsAllowed` gate — disables trust rule saving for proxied bash |
617
- | `assistant/src/daemon/session-tool-setup.ts` | `createProxyApprovalCallback` — wired into session startup, uses `network_request` tool name with URL-based trust rules |
618
- | `assistant/src/permissions/checker.ts` | `network_request` trust rule matching and risk classification (Medium) |
604
+ | File | Role |
605
+ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
606
+ | `assistant/src/tools/network/script-proxy/server.ts` | Proxy server factory — HTTP forwarding, CONNECT handling, MITM dispatch |
607
+ | `assistant/src/tools/network/script-proxy/policy.ts` | Policy engine — evaluates requests against credential templates |
608
+ | `assistant/src/tools/network/script-proxy/mitm-handler.ts` | MITM TLS interception — loopback TLS server, request rewrite, upstream forwarding |
609
+ | `assistant/src/tools/network/script-proxy/connect-tunnel.ts` | Plain CONNECT tunnel — raw TCP bidirectional pipe |
610
+ | `assistant/src/tools/network/script-proxy/http-forwarder.ts` | HTTP proxy forwarder — absolute-URL form forwarding with policy callback |
611
+ | `assistant/src/tools/network/script-proxy/session-manager.ts` | Session lifecycle — create, start, stop, idle timeout, env var generation |
612
+ | `assistant/src/tools/network/script-proxy/certs.ts` | Local CA management — ensureLocalCA, issueLeafCert, getCAPath |
613
+ | `assistant/src/tools/network/script-proxy/logging.ts` | Log sanitization (header/URL redaction) and safe decision trace builders for policy and credential resolution |
614
+ | `assistant/src/tools/network/script-proxy/types.ts` | Type definitions — session, policy decisions, approval callback |
615
+ | `assistant/src/tools/executor.ts` | `persistentDecisionsAllowed` gate — disables trust rule saving for proxied bash |
616
+ | `assistant/src/daemon/session-tool-setup.ts` | `createProxyApprovalCallback` — wired into session startup, uses `network_request` tool name with URL-based trust rules |
617
+ | `assistant/src/permissions/checker.ts` | `network_request` trust rule matching and risk classification (Medium) |
619
618
 
620
619
  ### Runtime Wiring Summary
621
620
 
@@ -690,13 +689,13 @@ graph TB
690
689
 
691
690
  ### Search Capabilities
692
691
 
693
- | Parameter | Type | Description |
694
- |---|---|---|
695
- | `mime_type` | string | MIME type filter with wildcard support (`image/*`, `application/pdf`) |
696
- | `filename` | string | Case-insensitive substring match on original filename |
697
- | `recency` | enum | Time-based filter: `last_hour`, `last_24_hours`, `last_7_days`, `last_30_days`, `last_90_days` |
698
- | `conversation_id` | string | Scope results to attachments in a specific conversation |
699
- | `limit` | number | Maximum results (default 20, max 100) |
692
+ | Parameter | Type | Description |
693
+ | ----------------- | ------ | ---------------------------------------------------------------------------------------------- |
694
+ | `mime_type` | string | MIME type filter with wildcard support (`image/*`, `application/pdf`) |
695
+ | `filename` | string | Case-insensitive substring match on original filename |
696
+ | `recency` | enum | Time-based filter: `last_hour`, `last_24_hours`, `last_7_days`, `last_30_days`, `last_90_days` |
697
+ | `conversation_id` | string | Scope results to attachments in a specific conversation |
698
+ | `limit` | number | Maximum results (default 20, max 100) |
700
699
 
701
700
  ### Materialize Safeguards
702
701
 
@@ -707,13 +706,12 @@ graph TB
707
706
 
708
707
  ### Key Source Files
709
708
 
710
- | File | Role |
711
- |---|---|
712
- | `assistant/src/tools/assets/search.ts` | `asset_search` tool — cross-thread attachment metadata search with visibility filtering |
713
- | `assistant/src/tools/assets/materialize.ts` | `asset_materialize` tool — decode and write attachment to sandbox path |
714
- | `assistant/src/daemon/media-visibility-policy.ts` | Pure policy module — `isAttachmentVisible()`, `filterVisibleAttachments()` |
715
- | `assistant/src/memory/schema.ts` | `attachments` and `message_attachments` table schemas |
716
- | `assistant/src/memory/conversation-store.ts` | `getConversationThreadType()` — thread type lookup for visibility context |
709
+ | File | Role |
710
+ | ------------------------------------------------- | --------------------------------------------------------------------------------------- |
711
+ | `assistant/src/tools/assets/search.ts` | `asset_search` tool — cross-thread attachment metadata search with visibility filtering |
712
+ | `assistant/src/tools/assets/materialize.ts` | `asset_materialize` tool — decode and write attachment to sandbox path |
713
+ | `assistant/src/daemon/media-visibility-policy.ts` | Pure policy module — `isAttachmentVisible()`, `filterVisibleAttachments()` |
714
+ | `assistant/src/memory/schema.ts` | `attachments` and `message_attachments` table schemas |
715
+ | `assistant/src/memory/conversation-store.ts` | `getConversationThreadType()` — thread type lookup for visibility context |
717
716
 
718
717
  ---
719
-
@@ -50,7 +50,7 @@ curl -s "$BASE/v1/contacts" \
50
50
  ### Via CLI
51
51
 
52
52
  ```bash
53
- vellum contacts list --role contact
53
+ assistant contacts list --role contact
54
54
  ```
55
55
 
56
56
  Response shape:
@@ -35,7 +35,7 @@ Design doc defining how unknown users gain access to a Vellum assistant via chan
35
35
  5. **Guardian receives the verification code.** The assistant delivers the code to the guardian's verified channel (Telegram chat, SMS, etc.).
36
36
  6. **Guardian gives the code to the requester out-of-band** (in person, text message, phone call, etc.). This out-of-band transfer is the trust anchor: it proves the requester has a real-world relationship with the guardian.
37
37
  7. **Requester enters the code** back to the assistant on the same channel. The inbound message handler intercepts bare 6-digit codes when a pending verification session exists for that channel.
38
- 8. **Assistant verifies the code and activates the user.** `validateAndConsumeChallenge()` hashes the code, matches it against the pending session, verifies identity binding (the code must come from the expected channel identity), consumes the challenge, and calls `upsertMember()` with `status: 'active'` and `policy: 'allow'`.
38
+ 8. **Assistant verifies the code and activates the user.** `validateAndConsumeChallenge()` hashes the code, matches it against the pending session, verifies identity binding (the code must come from the expected channel identity), consumes the challenge, and calls `upsertContactChannel()` with `status: 'active'` and `policy: 'allow'`.
39
39
  9. **All subsequent messages are accepted normally.** The ingress ACL finds an active member record and allows the message through.
40
40
 
41
41
  ## Lifecycle States
@@ -92,11 +92,11 @@ Identity binding ensures the verification code can only be consumed by the inten
92
92
 
93
93
  ### Stage: `active` (code verified, trusted contact created)
94
94
 
95
- | Store | Table | Record |
96
- | --------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
97
- | `contacts-write.ts` | `contacts` / `contact_channels` | Upserted via `upsertMember()`: creates a contact record and a `contact_channels` entry with `status: 'active'`, `policy: 'allow'`, channel type, `externalUserId`, `externalChatId`, `displayName`. |
98
- | `channel-guardian-store.ts` | `channel_guardian_verification_challenges` | Updated to `status: 'consumed'`, `consumedByExternalUserId`, `consumedByChatId` set. |
99
- | `channel-guardian-store.ts` | `channel_guardian_rate_limits` | Reset via `resetRateLimit()` on successful verification. |
95
+ | Store | Table | Record |
96
+ | --------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
97
+ | `contacts-write.ts` | `contacts` / `contact_channels` | Upserted via `upsertContactChannel()`: creates a contact record and a `contact_channels` entry with `status: 'active'`, `policy: 'allow'`, channel type, `externalUserId`, `externalChatId`, `displayName`. |
98
+ | `channel-guardian-store.ts` | `channel_guardian_verification_challenges` | Updated to `status: 'consumed'`, `consumedByExternalUserId`, `consumedByChatId` set. |
99
+ | `channel-guardian-store.ts` | `channel_guardian_rate_limits` | Reset via `resetRateLimit()` on successful verification. |
100
100
 
101
101
  ### Stage: `denied` (guardian rejected)
102
102
 
@@ -132,15 +132,15 @@ Voice calls have a dedicated in-call guardian approval flow that differs from th
132
132
  3. On name capture, `notifyGuardianOfAccessRequest` creates a canonical guardian request (`kind: 'access_request'`) and notifies the guardian.
133
133
  4. Relay transitions to `awaiting_guardian_decision` and polls `canonical_guardian_requests` for status changes.
134
134
  5. Guardian approves or denies via any channel. All decisions route through `applyCanonicalGuardianDecision`.
135
- 6. On approval: the `access_request` resolver directly activates the caller as a trusted contact (`upsertMember` with `status: 'active'`, `policy: 'allow'`) — no verification session needed since the caller is already authenticated by their phone number.
135
+ 6. On approval: the `access_request` resolver directly activates the caller as a trusted contact (`upsertContactChannel` with `status: 'active'`, `policy: 'allow'`) — no verification session needed since the caller is already authenticated by their phone number.
136
136
  7. On denial or timeout: the caller hears a denial message and the call ends.
137
137
 
138
138
  **Key difference from text-channel flow:** Voice approvals skip the verification session step because the caller's phone identity is already known from the active call. Text-channel approvals still mint a 6-digit verification code for out-of-band identity confirmation.
139
139
 
140
- | Store | Table | Record |
141
- | ----------------------------- | ------------------------------- | ------------------------------------------------------------------------------------- |
142
- | `canonical-guardian-store.ts` | `canonical_guardian_requests` | `kind: 'access_request'`, `status: 'pending'` -> `'approved'` or `'denied'` |
143
- | `contacts-write.ts` | `contacts` / `contact_channels` | On approval: upserted via `upsertMember()` with `status: 'active'`, `policy: 'allow'` |
140
+ | Store | Table | Record |
141
+ | ----------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------- |
142
+ | `canonical-guardian-store.ts` | `canonical_guardian_requests` | `kind: 'access_request'`, `status: 'pending'` -> `'approved'` or `'denied'` |
143
+ | `contacts-write.ts` | `contacts` / `contact_channels` | On approval: upserted via `upsertContactChannel()` with `status: 'active'`, `policy: 'allow'` |
144
144
 
145
145
  ## Sequence Diagram
146
146
 
@@ -174,7 +174,7 @@ sequenceDiagram
174
174
  A->>A: validateAndConsumeChallenge()
175
175
  A->>A: Identity check: actorId matches expected
176
176
  A->>A: Hash matches, not expired → consume
177
- A->>A: upsertMember(status: 'active', policy: 'allow')
177
+ A->>A: upsertContactChannel(status: 'active', policy: 'allow')
178
178
  A-->>U: "Verification successful! You now have access."
179
179
 
180
180
  U->>A: Subsequent messages
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/assistant",
3
- "version": "0.4.37",
3
+ "version": "0.4.40",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "assistant": "./src/index.ts"
@@ -39,6 +39,7 @@
39
39
  "croner": "^10.0.1",
40
40
  "dotenv": "^17.3.1",
41
41
  "drizzle-orm": "^0.38.4",
42
+ "esbuild": "^0.24.0",
42
43
  "ink": "^6.7.0",
43
44
  "jszip": "^3.10.1",
44
45
  "minimatch": "^10.2.4",
@@ -46,6 +47,7 @@
46
47
  "pino": "^9.6.0",
47
48
  "pino-pretty": "^13.1.3",
48
49
  "playwright": "^1.58.2",
50
+ "preact": "^10.25.0",
49
51
  "postgres": "^3.4.8",
50
52
  "qrcode": "^1.5.4",
51
53
  "react": "^19.2.4",
@@ -628,13 +628,6 @@ exports[`IPC message snapshots ClientMessage types share_app_cloud serializes to
628
628
  }
629
629
  `;
630
630
 
631
- exports[`IPC message snapshots ClientMessage types share_to_slack serializes to expected JSON 1`] = `
632
- {
633
- "appId": "app-001",
634
- "type": "share_to_slack",
635
- }
636
- `;
637
-
638
631
  exports[`IPC message snapshots ClientMessage types slack_webhook_config serializes to expected JSON 1`] = `
639
632
  {
640
633
  "action": "get",
@@ -2234,13 +2227,6 @@ exports[`IPC message snapshots ServerMessage types share_app_cloud_response seri
2234
2227
  }
2235
2228
  `;
2236
2229
 
2237
- exports[`IPC message snapshots ServerMessage types share_to_slack_response serializes to expected JSON 1`] = `
2238
- {
2239
- "success": true,
2240
- "type": "share_to_slack_response",
2241
- }
2242
- `;
2243
-
2244
2230
  exports[`IPC message snapshots ServerMessage types slack_webhook_config_response serializes to expected JSON 1`] = `
2245
2231
  {
2246
2232
  "success": true,