@vellumai/assistant 0.4.46 → 0.4.49

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 (382) hide show
  1. package/ARCHITECTURE.md +7 -7
  2. package/README.md +2 -23
  3. package/docs/architecture/integrations.md +45 -41
  4. package/docs/architecture/keychain-broker.md +3 -3
  5. package/docs/architecture/security.md +5 -5
  6. package/docs/runbook-trusted-contacts.md +3 -8
  7. package/hook-templates/debug-prompt-logger/hook.json +1 -1
  8. package/hook-templates/debug-prompt-logger/run.sh +1 -3
  9. package/package.json +1 -1
  10. package/src/__tests__/actor-token-service.test.ts +0 -1
  11. package/src/__tests__/anthropic-provider.test.ts +156 -0
  12. package/src/__tests__/approval-cascade.test.ts +810 -0
  13. package/src/__tests__/approval-primitive.test.ts +0 -1
  14. package/src/__tests__/approval-routes-http.test.ts +2 -0
  15. package/src/__tests__/assistant-attachments.test.ts +12 -34
  16. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
  17. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
  18. package/src/__tests__/browser-fill-credential.test.ts +5 -2
  19. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
  20. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -1
  21. package/src/__tests__/channel-guardian.test.ts +0 -2
  22. package/src/__tests__/channel-readiness-routes.test.ts +35 -25
  23. package/src/__tests__/channel-readiness-service.test.ts +10 -9
  24. package/src/__tests__/checker.test.ts +9 -29
  25. package/src/__tests__/cli.test.ts +23 -0
  26. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
  27. package/src/__tests__/computer-use-tools.test.ts +2 -19
  28. package/src/__tests__/config-watcher.test.ts +0 -1
  29. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  30. package/src/__tests__/context-image-dimensions.test.ts +332 -0
  31. package/src/__tests__/context-token-estimator.test.ts +196 -13
  32. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  33. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  34. package/src/__tests__/conversation-routes-guardian-reply.test.ts +144 -0
  35. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  36. package/src/__tests__/credential-broker-browser-fill.test.ts +23 -22
  37. package/src/__tests__/credential-broker-server-use.test.ts +22 -21
  38. package/src/__tests__/credential-broker.test.ts +2 -1
  39. package/src/__tests__/credential-metadata-store.test.ts +239 -26
  40. package/src/__tests__/credential-resolve.test.ts +5 -4
  41. package/src/__tests__/credential-security-e2e.test.ts +8 -8
  42. package/src/__tests__/credential-security-invariants.test.ts +111 -7
  43. package/src/__tests__/credential-vault-unit.test.ts +287 -54
  44. package/src/__tests__/credential-vault.test.ts +406 -12
  45. package/src/__tests__/credentials-cli.test.ts +82 -6
  46. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  47. package/src/__tests__/ephemeral-permissions.test.ts +3 -3
  48. package/src/__tests__/gateway-only-enforcement.test.ts +4 -2
  49. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  50. package/src/__tests__/gemini-image-service.test.ts +75 -45
  51. package/src/__tests__/gemini-provider.test.ts +9 -6
  52. package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -33
  53. package/src/__tests__/guardian-action-copy-generator.test.ts +0 -20
  54. package/src/__tests__/guardian-action-followup-executor.test.ts +1 -28
  55. package/src/__tests__/guardian-action-followup-store.test.ts +1 -1
  56. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  57. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  58. package/src/__tests__/guardian-grant-minting.test.ts +35 -0
  59. package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
  60. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  61. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
  62. package/src/__tests__/heartbeat-service.test.ts +0 -1
  63. package/src/__tests__/host-cu-proxy.test.ts +629 -0
  64. package/src/__tests__/host-shell-tool.test.ts +27 -15
  65. package/src/__tests__/http-user-message-parity.test.ts +1 -0
  66. package/src/__tests__/ingress-url-consistency.test.ts +14 -21
  67. package/src/__tests__/integration-status.test.ts +38 -25
  68. package/src/__tests__/intent-routing.test.ts +0 -1
  69. package/src/__tests__/invite-routes-http.test.ts +10 -9
  70. package/src/__tests__/keychain-broker-client.test.ts +11 -43
  71. package/src/__tests__/managed-proxy-context.test.ts +5 -3
  72. package/src/__tests__/media-generate-image.test.ts +63 -2
  73. package/src/__tests__/media-reuse-story.e2e.test.ts +7 -3
  74. package/src/__tests__/messaging-send-tool.test.ts +4 -6
  75. package/src/__tests__/notification-routing-intent.test.ts +0 -1
  76. package/src/__tests__/oauth-cli.test.ts +373 -14
  77. package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
  78. package/src/__tests__/oauth-scope-policy.test.ts +4 -6
  79. package/src/__tests__/oauth-store.test.ts +756 -0
  80. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  81. package/src/__tests__/provider-error-scenarios.test.ts +0 -1
  82. package/src/__tests__/provider-fail-open-selection.test.ts +3 -1
  83. package/src/__tests__/provider-managed-proxy-integration.test.ts +70 -6
  84. package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
  85. package/src/__tests__/public-ingress-urls.test.ts +15 -21
  86. package/src/__tests__/recording-handler.test.ts +3 -4
  87. package/src/__tests__/registry.test.ts +2 -2
  88. package/src/__tests__/runtime-events-sse.test.ts +55 -7
  89. package/src/__tests__/schedule-store.test.ts +0 -1
  90. package/src/__tests__/scheduler-recurrence.test.ts +0 -1
  91. package/src/__tests__/schema-transforms.test.ts +226 -0
  92. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  93. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  94. package/src/__tests__/script-proxy-injection-runtime.test.ts +23 -13
  95. package/src/__tests__/script-proxy-policy-runtime.test.ts +1 -1
  96. package/src/__tests__/script-proxy-session-manager.test.ts +1 -1
  97. package/src/__tests__/secret-ingress-handler.test.ts +0 -1
  98. package/src/__tests__/secret-onetime-send.test.ts +5 -3
  99. package/src/__tests__/send-endpoint-busy.test.ts +21 -6
  100. package/src/__tests__/sequence-store.test.ts +0 -1
  101. package/src/__tests__/session-init.benchmark.test.ts +4 -5
  102. package/src/__tests__/session-messaging-secret-redirect.test.ts +5 -4
  103. package/src/__tests__/skill-include-graph.test.ts +66 -0
  104. package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
  105. package/src/__tests__/skill-load-tool.test.ts +149 -1
  106. package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
  107. package/src/__tests__/skills-uninstall.test.ts +3 -3
  108. package/src/__tests__/skills.test.ts +3 -12
  109. package/src/__tests__/slack-channel-config.test.ts +76 -11
  110. package/src/__tests__/slack-share-routes.test.ts +17 -14
  111. package/src/__tests__/system-prompt.test.ts +0 -1
  112. package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -0
  113. package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
  114. package/src/__tests__/terminal-tools.test.ts +4 -3
  115. package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
  116. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  117. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  118. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  119. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
  120. package/src/__tests__/tool-executor.test.ts +0 -1
  121. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  122. package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
  123. package/src/__tests__/trust-store.test.ts +1 -22
  124. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  125. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  126. package/src/__tests__/twilio-config.test.ts +2 -1
  127. package/src/__tests__/twilio-provider.test.ts +4 -2
  128. package/src/__tests__/twilio-routes.test.ts +5 -20
  129. package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
  130. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  131. package/src/agent/ax-tree-compaction.test.ts +235 -0
  132. package/src/agent/loop.ts +76 -130
  133. package/src/calls/call-domain.ts +8 -10
  134. package/src/calls/relay-server.ts +9 -13
  135. package/src/calls/twilio-config.ts +4 -8
  136. package/src/calls/twilio-provider.ts +2 -1
  137. package/src/calls/twilio-rest.ts +2 -1
  138. package/src/calls/twilio-routes.ts +1 -2
  139. package/src/calls/voice-ingress-preflight.ts +1 -1
  140. package/src/cli/commands/browser-relay.ts +46 -15
  141. package/src/cli/commands/completions.ts +0 -3
  142. package/src/cli/commands/credentials.ts +110 -23
  143. package/src/cli/commands/oauth/apps.ts +255 -0
  144. package/src/cli/commands/oauth/connections.ts +299 -0
  145. package/src/cli/commands/oauth/index.ts +52 -0
  146. package/src/cli/commands/oauth/providers.ts +242 -0
  147. package/src/cli/commands/skills.ts +4 -338
  148. package/src/cli/program.ts +1 -5
  149. package/src/cli/reference.ts +1 -3
  150. package/src/cli.ts +3 -2
  151. package/src/config/assistant-feature-flags.ts +0 -3
  152. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  153. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -4
  154. package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
  155. package/src/config/bundled-skills/computer-use/TOOLS.json +22 -4
  156. package/src/config/bundled-skills/contacts/tools/google-contacts.ts +29 -32
  157. package/src/config/bundled-skills/gmail/SKILL.md +4 -4
  158. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +54 -61
  159. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +25 -28
  160. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +14 -17
  161. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +39 -44
  162. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +61 -58
  163. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +50 -49
  164. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +11 -13
  165. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +148 -146
  166. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +4 -7
  167. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +175 -173
  168. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +4 -7
  169. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +71 -76
  170. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +32 -38
  171. package/src/config/bundled-skills/google-calendar/SKILL.md +2 -2
  172. package/src/config/bundled-skills/google-calendar/calendar-client.ts +90 -44
  173. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +9 -10
  174. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +5 -6
  175. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +4 -5
  176. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +14 -15
  177. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +37 -37
  178. package/src/config/bundled-skills/google-calendar/tools/shared.ts +4 -9
  179. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +24 -3
  180. package/src/config/bundled-skills/messaging/SKILL.md +6 -6
  181. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +62 -63
  182. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +15 -16
  183. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +4 -5
  184. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +6 -7
  185. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +4 -5
  186. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +14 -15
  187. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +4 -5
  188. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +128 -128
  189. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +33 -34
  190. package/src/config/bundled-skills/messaging/tools/shared.ts +12 -15
  191. package/src/config/bundled-skills/settings/SKILL.md +1 -1
  192. package/src/config/bundled-skills/settings/TOOLS.json +2 -8
  193. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
  194. package/src/config/bundled-skills/slack/tools/shared.ts +4 -10
  195. package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +4 -5
  196. package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +15 -16
  197. package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +4 -5
  198. package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +4 -5
  199. package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +4 -5
  200. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +95 -92
  201. package/src/config/env-registry.ts +14 -83
  202. package/src/config/env.ts +11 -50
  203. package/src/config/feature-flag-registry.json +16 -16
  204. package/src/config/schema.ts +3 -1
  205. package/src/config/skills.ts +21 -2
  206. package/src/context/image-dimensions.ts +229 -0
  207. package/src/context/token-estimator.ts +75 -12
  208. package/src/context/window-manager.ts +49 -10
  209. package/src/daemon/assistant-attachments.ts +1 -13
  210. package/src/daemon/guardian-action-generators.ts +4 -5
  211. package/src/daemon/handlers/config-ingress.ts +8 -33
  212. package/src/daemon/handlers/config-slack-channel.ts +76 -56
  213. package/src/daemon/handlers/config-telegram.ts +53 -24
  214. package/src/daemon/handlers/sessions.ts +10 -24
  215. package/src/daemon/handlers/shared.ts +0 -130
  216. package/src/daemon/host-cu-proxy.ts +401 -0
  217. package/src/daemon/lifecycle.ts +39 -63
  218. package/src/daemon/message-protocol.ts +3 -0
  219. package/src/daemon/message-types/computer-use.ts +2 -119
  220. package/src/daemon/message-types/host-cu.ts +19 -0
  221. package/src/daemon/message-types/integrations.ts +1 -0
  222. package/src/daemon/message-types/messages.ts +3 -0
  223. package/src/daemon/server.ts +14 -21
  224. package/src/daemon/session-agent-loop-handlers.ts +2 -0
  225. package/src/daemon/session-attachments.ts +1 -2
  226. package/src/daemon/session-messaging.ts +3 -1
  227. package/src/daemon/session-slash.ts +1 -1
  228. package/src/daemon/session-surfaces.ts +40 -28
  229. package/src/daemon/session-tool-setup.ts +20 -11
  230. package/src/daemon/session.ts +139 -16
  231. package/src/daemon/tool-side-effects.ts +2 -8
  232. package/src/daemon/watch-handler.ts +2 -2
  233. package/src/email/providers/index.ts +2 -1
  234. package/src/events/tool-metrics-listener.ts +2 -2
  235. package/src/hooks/manager.ts +1 -4
  236. package/src/inbound/public-ingress-urls.ts +7 -7
  237. package/src/instrument.ts +15 -1
  238. package/src/logfire.ts +16 -5
  239. package/src/media/app-icon-generator.ts +30 -4
  240. package/src/media/avatar-router.ts +26 -3
  241. package/src/media/gemini-image-service.ts +28 -2
  242. package/src/memory/conversation-key-store.ts +21 -0
  243. package/src/memory/db-init.ts +4 -0
  244. package/src/memory/guardian-action-store.ts +1 -1
  245. package/src/memory/migrations/149-oauth-tables.ts +60 -0
  246. package/src/memory/migrations/index.ts +1 -0
  247. package/src/memory/schema/guardian.ts +1 -1
  248. package/src/memory/schema/index.ts +1 -0
  249. package/src/memory/schema/oauth.ts +65 -0
  250. package/src/messaging/provider.ts +19 -13
  251. package/src/messaging/providers/gmail/adapter.ts +40 -23
  252. package/src/messaging/providers/gmail/client.ts +283 -122
  253. package/src/messaging/providers/gmail/people-client.ts +32 -24
  254. package/src/messaging/providers/slack/adapter.ts +29 -19
  255. package/src/messaging/providers/slack/client.ts +265 -78
  256. package/src/messaging/providers/telegram-bot/adapter.ts +19 -18
  257. package/src/messaging/providers/whatsapp/adapter.ts +17 -11
  258. package/src/messaging/registry.ts +2 -31
  259. package/src/notifications/copy-composer.ts +0 -5
  260. package/src/notifications/signal.ts +4 -5
  261. package/src/oauth/byo-connection.test.ts +537 -0
  262. package/src/oauth/byo-connection.ts +128 -0
  263. package/src/oauth/connect-orchestrator.ts +139 -56
  264. package/src/oauth/connect-types.ts +17 -23
  265. package/src/oauth/connection-resolver.ts +58 -0
  266. package/src/oauth/connection.ts +38 -0
  267. package/src/oauth/manual-token-connection.ts +104 -0
  268. package/src/oauth/oauth-store.ts +496 -0
  269. package/src/oauth/platform-connection.test.ts +192 -0
  270. package/src/oauth/platform-connection.ts +111 -0
  271. package/src/oauth/provider-behaviors.ts +124 -0
  272. package/src/oauth/scope-policy.ts +9 -2
  273. package/src/oauth/seed-providers.ts +161 -0
  274. package/src/oauth/token-persistence.ts +74 -78
  275. package/src/permissions/checker.ts +8 -4
  276. package/src/permissions/defaults.ts +0 -1
  277. package/src/permissions/prompter.ts +10 -1
  278. package/src/permissions/trust-store.ts +13 -0
  279. package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
  280. package/src/prompts/system-prompt.ts +70 -45
  281. package/src/providers/anthropic/client.ts +133 -24
  282. package/src/providers/gemini/client.ts +15 -6
  283. package/src/providers/managed-proxy/constants.ts +2 -2
  284. package/src/providers/managed-proxy/context.ts +5 -1
  285. package/src/providers/ratelimit.ts +17 -0
  286. package/src/providers/registry.ts +2 -2
  287. package/src/providers/retry.ts +1 -27
  288. package/src/runtime/AGENTS.md +17 -0
  289. package/src/runtime/auth/route-policy.ts +0 -3
  290. package/src/runtime/channel-invite-transports/telegram.ts +2 -1
  291. package/src/runtime/channel-readiness-service.ts +168 -195
  292. package/src/runtime/channel-readiness-types.ts +4 -0
  293. package/src/runtime/channel-reply-delivery.ts +0 -40
  294. package/src/runtime/gateway-client.ts +0 -7
  295. package/src/runtime/guardian-action-conversation-turn.ts +1 -3
  296. package/src/runtime/guardian-action-followup-executor.ts +1 -1
  297. package/src/runtime/guardian-action-message-composer.ts +3 -23
  298. package/src/runtime/http-server.ts +17 -10
  299. package/src/runtime/http-types.ts +2 -3
  300. package/src/runtime/middleware/rate-limiter.ts +74 -20
  301. package/src/runtime/middleware/twilio-validation.ts +1 -11
  302. package/src/runtime/pending-interactions.ts +14 -12
  303. package/src/runtime/routes/channel-delivery-routes.ts +0 -1
  304. package/src/runtime/routes/channel-readiness-routes.ts +2 -0
  305. package/src/runtime/routes/conversation-routes.ts +73 -19
  306. package/src/runtime/routes/diagnostics-routes.ts +11 -9
  307. package/src/runtime/routes/events-routes.ts +21 -11
  308. package/src/runtime/routes/guardian-approval-interception.ts +20 -5
  309. package/src/runtime/routes/host-cu-routes.ts +97 -0
  310. package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
  311. package/src/runtime/routes/integrations/slack/share.ts +6 -6
  312. package/src/runtime/routes/integrations/twilio.ts +6 -5
  313. package/src/runtime/routes/log-export-routes.ts +126 -8
  314. package/src/runtime/routes/secret-routes.ts +3 -2
  315. package/src/runtime/routes/settings-routes.ts +113 -48
  316. package/src/runtime/routes/surface-action-routes.ts +1 -1
  317. package/src/runtime/routes/watch-routes.ts +128 -0
  318. package/src/schedule/integration-status.ts +10 -8
  319. package/src/security/credential-key.ts +14 -0
  320. package/src/security/keychain-broker-client.ts +5 -6
  321. package/src/security/oauth2.ts +1 -1
  322. package/src/security/token-manager.ts +145 -43
  323. package/src/skills/catalog-install.ts +358 -0
  324. package/src/skills/include-graph.ts +32 -0
  325. package/src/telegram/bot-username.ts +2 -3
  326. package/src/tools/apps/definitions.ts +0 -5
  327. package/src/tools/assets/materialize.ts +0 -5
  328. package/src/tools/assets/search.ts +0 -5
  329. package/src/tools/browser/headless-browser.ts +1 -67
  330. package/src/tools/browser/network-recorder.ts +1 -1
  331. package/src/tools/browser/network-recording-types.ts +1 -1
  332. package/src/tools/claude-code/claude-code.ts +0 -5
  333. package/src/tools/computer-use/definitions.ts +46 -11
  334. package/src/tools/computer-use/registry.ts +4 -5
  335. package/src/tools/credentials/broker.ts +5 -4
  336. package/src/tools/credentials/metadata-store.ts +22 -74
  337. package/src/tools/credentials/resolve.ts +2 -1
  338. package/src/tools/credentials/vault.ts +139 -151
  339. package/src/tools/filesystem/edit.ts +1 -6
  340. package/src/tools/filesystem/read.ts +0 -5
  341. package/src/tools/filesystem/write.ts +1 -6
  342. package/src/tools/host-filesystem/edit.ts +1 -6
  343. package/src/tools/host-filesystem/read.ts +1 -6
  344. package/src/tools/host-filesystem/write.ts +1 -6
  345. package/src/tools/mcp/mcp-tool-factory.ts +18 -1
  346. package/src/tools/memory/definitions.ts +0 -5
  347. package/src/tools/network/web-fetch.ts +0 -5
  348. package/src/tools/network/web-search.ts +0 -5
  349. package/src/tools/registry.ts +2 -7
  350. package/src/tools/schema-transforms.ts +99 -0
  351. package/src/tools/skills/load.ts +62 -8
  352. package/src/tools/swarm/delegate.ts +0 -5
  353. package/src/tools/system/avatar-generator.ts +0 -5
  354. package/src/tools/ui-surface/definitions.ts +0 -15
  355. package/src/tools/watch/screen-watch.ts +0 -5
  356. package/src/tools/watch/watch-state.ts +0 -12
  357. package/src/util/logger.ts +7 -41
  358. package/src/util/platform.ts +9 -28
  359. package/src/version.ts +10 -0
  360. package/src/watcher/providers/github.ts +51 -52
  361. package/src/watcher/providers/gmail.ts +88 -80
  362. package/src/watcher/providers/google-calendar.ts +94 -86
  363. package/src/watcher/providers/linear.ts +87 -93
  364. package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
  365. package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
  366. package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
  367. package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
  368. package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
  369. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
  370. package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
  371. package/src/cli/commands/dev.ts +0 -129
  372. package/src/cli/commands/map.ts +0 -391
  373. package/src/cli/commands/oauth.ts +0 -77
  374. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -16
  375. package/src/daemon/computer-use-session.ts +0 -1020
  376. package/src/daemon/ride-shotgun-handler.ts +0 -567
  377. package/src/oauth/provider-profiles.ts +0 -192
  378. package/src/prompts/computer-use-prompt.ts +0 -98
  379. package/src/runtime/routes/computer-use-routes.ts +0 -641
  380. package/src/runtime/telegram-streaming-delivery.test.ts +0 -597
  381. package/src/runtime/telegram-streaming-delivery.ts +0 -383
  382. package/src/tools/computer-use/request-computer-control.ts +0 -61
@@ -0,0 +1,255 @@
1
+ import type { Command } from "commander";
2
+
3
+ import {
4
+ deleteApp,
5
+ getApp,
6
+ getAppByProviderAndClientId,
7
+ getMostRecentAppByProvider,
8
+ listApps,
9
+ upsertApp,
10
+ } from "../../../oauth/oauth-store.js";
11
+ import { getCliLogger } from "../../logger.js";
12
+ import { shouldOutputJson, writeOutput } from "../../output.js";
13
+
14
+ const log = getCliLogger("cli");
15
+
16
+ /** Format an app row for output, converting timestamps to ISO strings. */
17
+ function formatAppRow(row: {
18
+ id: string;
19
+ providerKey: string;
20
+ clientId: string;
21
+ createdAt: number;
22
+ updatedAt: number;
23
+ }) {
24
+ return {
25
+ id: row.id,
26
+ providerKey: row.providerKey,
27
+ clientId: row.clientId,
28
+ createdAt: new Date(row.createdAt).toISOString(),
29
+ updatedAt: new Date(row.updatedAt).toISOString(),
30
+ };
31
+ }
32
+
33
+ export function registerAppCommands(oauth: Command): void {
34
+ const apps = oauth
35
+ .command("apps")
36
+ .description("Manage OAuth app registrations (client IDs and secrets)");
37
+
38
+ apps.addHelpText(
39
+ "after",
40
+ `
41
+ Apps represent OAuth client registrations — a client_id and optional
42
+ client_secret linked to a provider. Each provider can have multiple apps
43
+ (e.g. different client IDs for different environments).
44
+
45
+ Examples:
46
+ $ assistant oauth apps list
47
+ $ assistant oauth apps get --id <uuid>
48
+ $ assistant oauth apps get --provider integration:gmail
49
+ $ assistant oauth apps upsert --provider integration:gmail --client-id abc123
50
+ $ assistant oauth apps delete <id>`,
51
+ );
52
+
53
+ // ---------------------------------------------------------------------------
54
+ // apps list
55
+ // ---------------------------------------------------------------------------
56
+
57
+ apps
58
+ .command("list")
59
+ .description("List all OAuth app registrations")
60
+ .addHelpText(
61
+ "after",
62
+ `
63
+ Returns all registered OAuth apps with their provider key, client ID, and
64
+ timestamps. Output is an array of app objects.
65
+
66
+ In JSON mode (--json), returns the array directly. In human mode, logs a
67
+ summary count and prints the formatted list.
68
+
69
+ Examples:
70
+ $ assistant oauth apps list
71
+ $ assistant oauth apps list --json`,
72
+ )
73
+ .action((_opts: unknown, cmd: Command) => {
74
+ try {
75
+ const rows = listApps().map(formatAppRow);
76
+
77
+ if (!shouldOutputJson(cmd)) {
78
+ log.info(`Found ${rows.length} app(s)`);
79
+ }
80
+
81
+ writeOutput(cmd, rows);
82
+ } catch (err) {
83
+ const message = err instanceof Error ? err.message : String(err);
84
+ writeOutput(cmd, { ok: false, error: message });
85
+ process.exitCode = 1;
86
+ }
87
+ });
88
+
89
+ // ---------------------------------------------------------------------------
90
+ // apps get
91
+ // ---------------------------------------------------------------------------
92
+
93
+ apps
94
+ .command("get")
95
+ .description(
96
+ "Look up an OAuth app by ID, provider + client-id, or provider",
97
+ )
98
+ .option("--id <id>", "App ID (UUID)")
99
+ .option("--provider <key>", "Provider key (e.g. integration:gmail)")
100
+ .option("--client-id <id>", "OAuth client ID (requires --provider)")
101
+ .addHelpText(
102
+ "after",
103
+ `
104
+ Three lookup modes are supported:
105
+
106
+ 1. By app ID:
107
+ $ assistant oauth apps get --id <uuid>
108
+
109
+ 2. By provider + client ID (exact match):
110
+ $ assistant oauth apps get --provider integration:gmail --client-id abc123
111
+
112
+ 3. By provider only (returns the most recently created app):
113
+ $ assistant oauth apps get --provider integration:gmail
114
+
115
+ At least --id or --provider must be specified.`,
116
+ )
117
+ .action(
118
+ (
119
+ opts: { id?: string; provider?: string; clientId?: string },
120
+ cmd: Command,
121
+ ) => {
122
+ try {
123
+ let row;
124
+
125
+ if (opts.id) {
126
+ row = getApp(opts.id);
127
+ } else if (opts.provider && opts.clientId) {
128
+ row = getAppByProviderAndClientId(opts.provider, opts.clientId);
129
+ } else if (opts.provider) {
130
+ row = getMostRecentAppByProvider(opts.provider);
131
+ } else {
132
+ writeOutput(cmd, {
133
+ ok: false,
134
+ error: "Provide --id, --provider, or --provider + --client-id",
135
+ });
136
+ process.exitCode = 1;
137
+ return;
138
+ }
139
+
140
+ if (!row) {
141
+ writeOutput(cmd, { ok: false, error: "App not found" });
142
+ process.exitCode = 1;
143
+ return;
144
+ }
145
+
146
+ writeOutput(cmd, formatAppRow(row));
147
+ } catch (err) {
148
+ const message = err instanceof Error ? err.message : String(err);
149
+ writeOutput(cmd, { ok: false, error: message });
150
+ process.exitCode = 1;
151
+ }
152
+ },
153
+ );
154
+
155
+ // ---------------------------------------------------------------------------
156
+ // apps upsert
157
+ // ---------------------------------------------------------------------------
158
+
159
+ apps
160
+ .command("upsert")
161
+ .description("Create or return an existing OAuth app registration")
162
+ .requiredOption("--provider <key>", "Provider key (e.g. integration:gmail)")
163
+ .requiredOption("--client-id <id>", "OAuth client ID")
164
+ .option(
165
+ "--client-secret <secret>",
166
+ "OAuth client secret (stored in secure keychain)",
167
+ )
168
+ .addHelpText(
169
+ "after",
170
+ `
171
+ Creates a new app registration or returns the existing one if an app with the
172
+ same provider and client ID already exists. The client secret, if provided, is
173
+ stored in the secure system keychain — not in the database.
174
+
175
+ When an existing app is matched and a --client-secret is provided, the stored
176
+ secret is updated. The app row itself is returned as-is.
177
+
178
+ Examples:
179
+ $ assistant oauth apps upsert --provider integration:gmail --client-id abc123
180
+ $ assistant oauth apps upsert --provider integration:slack --client-id def456 --client-secret s3cret
181
+ $ assistant oauth apps upsert --provider integration:gmail --client-id abc123 --json`,
182
+ )
183
+ .action(
184
+ async (
185
+ opts: { provider: string; clientId: string; clientSecret?: string },
186
+ cmd: Command,
187
+ ) => {
188
+ try {
189
+ const row = await upsertApp(
190
+ opts.provider,
191
+ opts.clientId,
192
+ opts.clientSecret,
193
+ );
194
+
195
+ if (!shouldOutputJson(cmd)) {
196
+ log.info(`Upserted app: ${row.id} (provider: ${row.providerKey})`);
197
+ }
198
+
199
+ writeOutput(cmd, formatAppRow(row));
200
+ } catch (err) {
201
+ const message = err instanceof Error ? err.message : String(err);
202
+ writeOutput(cmd, { ok: false, error: message });
203
+ process.exitCode = 1;
204
+ }
205
+ },
206
+ );
207
+
208
+ // ---------------------------------------------------------------------------
209
+ // apps delete <id>
210
+ // ---------------------------------------------------------------------------
211
+
212
+ apps
213
+ .command("delete <id>")
214
+ .description("Delete an OAuth app registration by ID")
215
+ .addHelpText(
216
+ "after",
217
+ `
218
+ Arguments:
219
+ id The app UUID to delete (as returned by "apps list" or "apps get")
220
+
221
+ Permanently removes the app registration and its stored client secret from
222
+ the keychain. Any OAuth connections that reference this app will no longer be
223
+ able to refresh tokens.
224
+
225
+ Exits with code 1 if the app ID is not found.
226
+
227
+ Examples:
228
+ $ assistant oauth apps delete 550e8400-e29b-41d4-a716-446655440000
229
+ $ assistant oauth apps delete 550e8400-e29b-41d4-a716-446655440000 --json`,
230
+ )
231
+ .action(async (id: string, _opts: unknown, cmd: Command) => {
232
+ try {
233
+ const deleted = await deleteApp(id);
234
+
235
+ if (!deleted) {
236
+ writeOutput(cmd, {
237
+ ok: false,
238
+ error: `App not found: ${id}`,
239
+ });
240
+ process.exitCode = 1;
241
+ return;
242
+ }
243
+
244
+ if (!shouldOutputJson(cmd)) {
245
+ log.info(`Deleted app: ${id}`);
246
+ }
247
+
248
+ writeOutput(cmd, { ok: true, id });
249
+ } catch (err) {
250
+ const message = err instanceof Error ? err.message : String(err);
251
+ writeOutput(cmd, { ok: false, error: message });
252
+ process.exitCode = 1;
253
+ }
254
+ });
255
+ }
@@ -0,0 +1,299 @@
1
+ import type { Command } from "commander";
2
+
3
+ import {
4
+ disconnectOAuthProvider,
5
+ getConnection,
6
+ getConnectionByProvider,
7
+ listConnections,
8
+ } from "../../../oauth/oauth-store.js";
9
+ import { credentialKey } from "../../../security/credential-key.js";
10
+ import { deleteSecureKeyAsync } from "../../../security/secure-keys.js";
11
+ import { withValidToken } from "../../../security/token-manager.js";
12
+ import {
13
+ assertMetadataWritable,
14
+ deleteCredentialMetadata,
15
+ } from "../../../tools/credentials/metadata-store.js";
16
+ import { getCliLogger } from "../../logger.js";
17
+ import { shouldOutputJson, writeOutput } from "../../output.js";
18
+
19
+ const log = getCliLogger("cli");
20
+
21
+ /**
22
+ * Keys that may contain secrets in an OAuth token endpoint response.
23
+ * These are stripped from the `metadata` field before CLI output to prevent
24
+ * token leakage via shell history, logs, or agent transcript capture.
25
+ */
26
+ const REDACTED_METADATA_KEYS = new Set([
27
+ "access_token",
28
+ "refresh_token",
29
+ "id_token",
30
+ ]);
31
+
32
+ /** Recursively strip secret-bearing keys from a parsed metadata object. */
33
+ function redactMetadata(obj: Record<string, unknown>): Record<string, unknown> {
34
+ const result: Record<string, unknown> = {};
35
+ for (const [key, value] of Object.entries(obj)) {
36
+ if (REDACTED_METADATA_KEYS.has(key)) {
37
+ result[key] = "[REDACTED]";
38
+ } else if (value && typeof value === "object" && !Array.isArray(value)) {
39
+ result[key] = redactMetadata(value as Record<string, unknown>);
40
+ } else {
41
+ result[key] = value;
42
+ }
43
+ }
44
+ return result;
45
+ }
46
+
47
+ /** Parse stored JSON string fields and convert timestamps for a connection row. */
48
+ function formatConnectionRow(row: ReturnType<typeof getConnection>) {
49
+ if (!row) return row;
50
+ const parsed = row.metadata ? JSON.parse(row.metadata) : null;
51
+ return {
52
+ ...row,
53
+ grantedScopes: row.grantedScopes ? JSON.parse(row.grantedScopes) : [],
54
+ metadata: parsed ? redactMetadata(parsed) : null,
55
+ hasRefreshToken: row.hasRefreshToken === 1,
56
+ createdAt: new Date(row.createdAt).toISOString(),
57
+ updatedAt: new Date(row.updatedAt).toISOString(),
58
+ expiresAt: row.expiresAt ? new Date(row.expiresAt).toISOString() : null,
59
+ };
60
+ }
61
+
62
+ export function registerConnectionCommands(oauth: Command): void {
63
+ const connections = oauth
64
+ .command("connections")
65
+ .description("Manage OAuth connections (active tokens and refresh state)");
66
+
67
+ connections.addHelpText(
68
+ "after",
69
+ `
70
+ Connections represent active OAuth sessions — an access token bound to a
71
+ provider through an app registration. Each connection tracks granted scopes,
72
+ token expiry, refresh token availability, account info, and status.
73
+
74
+ Examples:
75
+ $ assistant oauth connections list
76
+ $ assistant oauth connections list --provider integration:gmail
77
+ $ assistant oauth connections get --id <uuid>
78
+ $ assistant oauth connections get --provider integration:gmail
79
+ $ assistant oauth connections token integration:twitter`,
80
+ );
81
+
82
+ // ---------------------------------------------------------------------------
83
+ // connections list
84
+ // ---------------------------------------------------------------------------
85
+
86
+ connections
87
+ .command("list")
88
+ .description("List all OAuth connections")
89
+ .option(
90
+ "--provider <key>",
91
+ "Filter by provider key (e.g. integration:gmail)",
92
+ )
93
+ .addHelpText(
94
+ "after",
95
+ `
96
+ Lists all OAuth connections, optionally filtered by provider key.
97
+
98
+ Each connection shows its ID, provider, account info, granted scopes, token
99
+ expiry, refresh token availability, and status.
100
+
101
+ Examples:
102
+ $ assistant oauth connections list
103
+ $ assistant oauth connections list --provider integration:gmail`,
104
+ )
105
+ .action((opts: { provider?: string }, cmd: Command) => {
106
+ try {
107
+ const rows = listConnections(opts.provider).map(formatConnectionRow);
108
+
109
+ if (!shouldOutputJson(cmd)) {
110
+ log.info(`Found ${rows.length} connection(s)`);
111
+ }
112
+
113
+ writeOutput(cmd, rows);
114
+ } catch (err) {
115
+ const message = err instanceof Error ? err.message : String(err);
116
+ writeOutput(cmd, { ok: false, error: message });
117
+ process.exitCode = 1;
118
+ }
119
+ });
120
+
121
+ // ---------------------------------------------------------------------------
122
+ // connections get
123
+ // ---------------------------------------------------------------------------
124
+
125
+ connections
126
+ .command("get")
127
+ .description("Look up an OAuth connection by ID or provider")
128
+ .option("--id <id>", "Connection ID (UUID)")
129
+ .option(
130
+ "--provider <key>",
131
+ "Provider key (returns most recent active connection)",
132
+ )
133
+ .addHelpText(
134
+ "after",
135
+ `
136
+ Two lookup modes are supported:
137
+
138
+ 1. By connection ID:
139
+ $ assistant oauth connections get --id <uuid>
140
+
141
+ 2. By provider (returns the most recent active connection):
142
+ $ assistant oauth connections get --provider integration:gmail
143
+
144
+ At least --id or --provider must be specified.`,
145
+ )
146
+ .action((opts: { id?: string; provider?: string }, cmd: Command) => {
147
+ try {
148
+ let row;
149
+
150
+ if (opts.id) {
151
+ row = getConnection(opts.id);
152
+ } else if (opts.provider) {
153
+ row = getConnectionByProvider(opts.provider);
154
+ } else {
155
+ writeOutput(cmd, {
156
+ ok: false,
157
+ error: "Provide --id or --provider",
158
+ });
159
+ process.exitCode = 1;
160
+ return;
161
+ }
162
+
163
+ if (!row) {
164
+ writeOutput(cmd, { ok: false, error: "Connection not found" });
165
+ process.exitCode = 1;
166
+ return;
167
+ }
168
+
169
+ writeOutput(cmd, formatConnectionRow(row));
170
+ } catch (err) {
171
+ const message = err instanceof Error ? err.message : String(err);
172
+ writeOutput(cmd, { ok: false, error: message });
173
+ process.exitCode = 1;
174
+ }
175
+ });
176
+
177
+ // ---------------------------------------------------------------------------
178
+ // connections token <provider-key>
179
+ // ---------------------------------------------------------------------------
180
+
181
+ connections
182
+ .command("token <provider-key>")
183
+ .description(
184
+ "Print a valid OAuth access token for a provider, refreshing if expired",
185
+ )
186
+ .addHelpText(
187
+ "after",
188
+ `
189
+ Arguments:
190
+ provider-key Provider key (e.g. integration:gmail, integration:twitter)
191
+
192
+ Returns a valid OAuth access token for the given provider. If the stored token
193
+ is expired or near-expiry, it is refreshed automatically before being returned.
194
+
195
+ In human mode, prints the bare token to stdout (suitable for shell substitution).
196
+ In JSON mode (--json), prints {"ok": true, "token": "..."}.
197
+
198
+ Exits with code 1 if no access token exists or refresh fails.
199
+
200
+ Examples:
201
+ $ assistant oauth connections token integration:twitter
202
+ $ assistant oauth connections token integration:gmail --json`,
203
+ )
204
+ .action(async (providerKey: string, _opts: unknown, cmd: Command) => {
205
+ try {
206
+ const token = await withValidToken(providerKey, async (t) => t);
207
+ if (shouldOutputJson(cmd)) {
208
+ writeOutput(cmd, { ok: true, token });
209
+ } else {
210
+ process.stdout.write(token + "\n");
211
+ }
212
+ } catch (err) {
213
+ const message = err instanceof Error ? err.message : String(err);
214
+ writeOutput(cmd, { ok: false, error: message });
215
+ process.exitCode = 1;
216
+ }
217
+ });
218
+
219
+ // ---------------------------------------------------------------------------
220
+ // connections disconnect <provider-key>
221
+ // ---------------------------------------------------------------------------
222
+
223
+ connections
224
+ .command("disconnect <provider-key>")
225
+ .description(
226
+ "Disconnect an OAuth integration and remove all associated credentials",
227
+ )
228
+ .addHelpText(
229
+ "after",
230
+ `
231
+ Arguments:
232
+ provider-key The full provider key (e.g. integration:gmail, integration:slack)
233
+
234
+ Removes the OAuth connection, tokens, and any legacy credential metadata for
235
+ the provider. The <provider-key> argument is the full provider key as-is — it
236
+ is not parsed through service:field splitting.
237
+
238
+ Legacy credential keys for common fields (access_token, refresh_token,
239
+ client_id, client_secret) are also cleaned up if present.
240
+
241
+ Examples:
242
+ $ assistant oauth connections disconnect integration:gmail
243
+ $ assistant oauth connections disconnect integration:slack`,
244
+ )
245
+ .action(async (providerKey: string, _opts: unknown, cmd: Command) => {
246
+ try {
247
+ assertMetadataWritable();
248
+
249
+ let cleanedUp = false;
250
+
251
+ // 1. Disconnect the OAuth connection (new-format keys + connection row)
252
+ const oauthResult = await disconnectOAuthProvider(providerKey);
253
+ if (oauthResult === "error") {
254
+ writeOutput(cmd, {
255
+ ok: false,
256
+ error: `Failed to disconnect OAuth provider "${providerKey}" — please try again`,
257
+ });
258
+ process.exitCode = 1;
259
+ return;
260
+ }
261
+ if (oauthResult === "disconnected") cleanedUp = true;
262
+
263
+ // 2. Clean up legacy credential keys for common fields
264
+ const legacyFields = [
265
+ "access_token",
266
+ "refresh_token",
267
+ "client_id",
268
+ "client_secret",
269
+ ];
270
+ for (const field of legacyFields) {
271
+ const key = credentialKey(providerKey, field);
272
+ const result = await deleteSecureKeyAsync(key);
273
+ if (result === "deleted") cleanedUp = true;
274
+
275
+ const metaDeleted = deleteCredentialMetadata(providerKey, field);
276
+ if (metaDeleted) cleanedUp = true;
277
+ }
278
+
279
+ if (!cleanedUp) {
280
+ writeOutput(cmd, {
281
+ ok: false,
282
+ error: `No OAuth connection or credentials found for "${providerKey}"`,
283
+ });
284
+ process.exitCode = 1;
285
+ return;
286
+ }
287
+
288
+ writeOutput(cmd, { ok: true, service: providerKey });
289
+
290
+ if (!shouldOutputJson(cmd)) {
291
+ log.info(`Disconnected ${providerKey}`);
292
+ }
293
+ } catch (err) {
294
+ const message = err instanceof Error ? err.message : String(err);
295
+ writeOutput(cmd, { ok: false, error: message });
296
+ process.exitCode = 1;
297
+ }
298
+ });
299
+ }
@@ -0,0 +1,52 @@
1
+ import type { Command } from "commander";
2
+
3
+ import { registerAppCommands } from "./apps.js";
4
+ import { registerConnectionCommands } from "./connections.js";
5
+ import { registerProviderCommands } from "./providers.js";
6
+
7
+ export function registerOAuthCommand(program: Command): void {
8
+ const oauth = program
9
+ .command("oauth")
10
+ .description("Manage OAuth providers, apps, connections, and tokens")
11
+ .option("--json", "Machine-readable compact JSON output");
12
+
13
+ oauth.addHelpText(
14
+ "after",
15
+ `
16
+ The oauth command group manages the full OAuth lifecycle:
17
+
18
+ providers Protocol-level configurations (auth URLs, scopes, endpoints)
19
+ apps Client credentials (client ID / secret pairs)
20
+ connections Active token grants per provider (list, get, token)
21
+
22
+ Providers are seeded on startup for built-in integrations. Apps and connections
23
+ are created during the OAuth authorization flow or can be managed manually via
24
+ their respective subcommands.
25
+
26
+ Examples:
27
+ $ assistant oauth connections token integration:twitter
28
+ $ assistant oauth connections list
29
+ $ assistant oauth connections get --provider integration:gmail
30
+ $ assistant oauth providers list
31
+ $ assistant oauth providers get integration:gmail
32
+ $ assistant oauth providers register --provider-key custom:myapi --auth-url https://example.com/auth --token-url https://example.com/token`,
33
+ );
34
+
35
+ // ---------------------------------------------------------------------------
36
+ // providers — subcommand group
37
+ // ---------------------------------------------------------------------------
38
+
39
+ registerProviderCommands(oauth);
40
+
41
+ // ---------------------------------------------------------------------------
42
+ // apps — subcommand group
43
+ // ---------------------------------------------------------------------------
44
+
45
+ registerAppCommands(oauth);
46
+
47
+ // ---------------------------------------------------------------------------
48
+ // connections — subcommand group (includes token)
49
+ // ---------------------------------------------------------------------------
50
+
51
+ registerConnectionCommands(oauth);
52
+ }