@vellumai/assistant 0.4.43 → 0.4.45

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 (713) hide show
  1. package/.prettierignore +4 -0
  2. package/ARCHITECTURE.md +46 -44
  3. package/README.md +15 -16
  4. package/bun.lock +10 -35
  5. package/docs/architecture/integrations.md +102 -215
  6. package/docs/architecture/keychain-broker.md +1 -1
  7. package/docs/architecture/memory.md +2 -2
  8. package/docs/architecture/scheduling.md +1 -1
  9. package/docs/architecture/security.md +11 -11
  10. package/docs/error-handling.md +1 -1
  11. package/docs/trusted-contact-access.md +3 -3
  12. package/drizzle/meta/0000_snapshot.json +34 -100
  13. package/drizzle/meta/_journal.json +1 -1
  14. package/drizzle.config.ts +4 -4
  15. package/package.json +3 -2
  16. package/scripts/capture-x-graphql.ts +237 -141
  17. package/scripts/generate-bundled-tool-registry.ts +223 -0
  18. package/src/__tests__/access-request-decision.test.ts +0 -1
  19. package/src/__tests__/actor-token-service.test.ts +23 -24
  20. package/src/__tests__/agent-loop.test.ts +0 -131
  21. package/src/__tests__/always-loaded-tools-guard.test.ts +71 -0
  22. package/src/__tests__/amazon-cdp-integration.test.ts +11 -9
  23. package/src/__tests__/approval-primitive.test.ts +0 -1
  24. package/src/__tests__/approval-routes-http.test.ts +11 -3
  25. package/src/__tests__/asset-materialize-tool.test.ts +0 -1
  26. package/src/__tests__/asset-search-tool.test.ts +0 -1
  27. package/src/__tests__/assistant-attachment-directive.test.ts +1 -1
  28. package/src/__tests__/assistant-events-sse-hardening.test.ts +0 -1
  29. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +70 -18
  31. package/src/__tests__/assistant-id-boundary-guard.test.ts +6 -6
  32. package/src/__tests__/attachments-store.test.ts +0 -1
  33. package/src/__tests__/avatar-e2e.test.ts +74 -115
  34. package/src/__tests__/avatar-router.test.ts +25 -62
  35. package/src/__tests__/browser-manager.test.ts +24 -0
  36. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +4 -3
  37. package/src/__tests__/browser-skill-endstate.test.ts +8 -11
  38. package/src/__tests__/btw-routes.test.ts +326 -0
  39. package/src/__tests__/bundled-asset.test.ts +1 -1
  40. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +23 -9
  41. package/src/__tests__/call-controller.test.ts +0 -1
  42. package/src/__tests__/call-conversation-messages.test.ts +0 -1
  43. package/src/__tests__/call-domain.test.ts +0 -1
  44. package/src/__tests__/call-pointer-messages.test.ts +0 -1
  45. package/src/__tests__/call-recovery.test.ts +0 -1
  46. package/src/__tests__/call-routes-http.test.ts +0 -1
  47. package/src/__tests__/call-store.test.ts +0 -1
  48. package/src/__tests__/canonical-guardian-store.test.ts +0 -1
  49. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  50. package/src/__tests__/channel-approvals.test.ts +1 -1
  51. package/src/__tests__/channel-delivery-store.test.ts +0 -1
  52. package/src/__tests__/channel-guardian.test.ts +5 -7
  53. package/src/__tests__/channel-retry-sweep.test.ts +0 -1
  54. package/src/__tests__/checker.test.ts +32 -36
  55. package/src/__tests__/compaction.benchmark.test.ts +16 -14
  56. package/src/__tests__/computer-use-session-lifecycle.test.ts +10 -11
  57. package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
  58. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +2 -5
  59. package/src/__tests__/computer-use-tools.test.ts +35 -31
  60. package/src/__tests__/config-schema.test.ts +11 -15
  61. package/src/__tests__/config-watcher.test.ts +0 -1
  62. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  63. package/src/__tests__/conflict-store.test.ts +0 -1
  64. package/src/__tests__/connection-policy.test.ts +4 -7
  65. package/src/__tests__/contacts-tools.test.ts +0 -1
  66. package/src/__tests__/context-memory-e2e.test.ts +2 -4
  67. package/src/__tests__/context-overflow-reducer.test.ts +2 -4
  68. package/src/__tests__/context-window-manager.test.ts +147 -60
  69. package/src/__tests__/contradiction-checker.test.ts +0 -1
  70. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  71. package/src/__tests__/conversation-attention-telegram.test.ts +1 -1
  72. package/src/__tests__/conversation-pairing.test.ts +2 -2
  73. package/src/__tests__/conversation-routes-guardian-reply.test.ts +31 -7
  74. package/src/__tests__/conversation-routes-slash-commands.test.ts +381 -0
  75. package/src/__tests__/conversation-store.test.ts +0 -1
  76. package/src/__tests__/conversation-unread-route.test.ts +1 -2
  77. package/src/__tests__/credential-security-invariants.test.ts +8 -8
  78. package/src/__tests__/cross-provider-web-search.test.ts +353 -0
  79. package/src/__tests__/daemon-assistant-events.test.ts +6 -7
  80. package/src/__tests__/db-schedule-syntax-migration.test.ts +15 -3
  81. package/src/__tests__/delete-managed-skill-tool.test.ts +5 -9
  82. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
  83. package/src/__tests__/diagnostics-export.test.ts +189 -0
  84. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  85. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
  86. package/src/__tests__/entity-extractor.test.ts +0 -1
  87. package/src/__tests__/entity-search.test.ts +0 -1
  88. package/src/__tests__/ephemeral-permissions.test.ts +2 -4
  89. package/src/__tests__/error-handler-friendly-messages.test.ts +46 -0
  90. package/src/__tests__/file-read-tool.test.ts +86 -0
  91. package/src/__tests__/followup-tools.test.ts +0 -1
  92. package/src/__tests__/frontmatter.test.ts +77 -34
  93. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  94. package/src/__tests__/gateway-only-guard.test.ts +1 -1
  95. package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -1
  96. package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
  97. package/src/__tests__/guardian-action-followup-store.test.ts +0 -1
  98. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  99. package/src/__tests__/guardian-action-late-reply.test.ts +0 -1
  100. package/src/__tests__/guardian-action-store.test.ts +0 -1
  101. package/src/__tests__/guardian-action-sweep.test.ts +0 -1
  102. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  103. package/src/__tests__/guardian-dispatch.test.ts +1 -2
  104. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  105. package/src/__tests__/guardian-outbound-http.test.ts +0 -1
  106. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -1
  107. package/src/__tests__/guardian-routing-invariants.test.ts +1 -1
  108. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  109. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  110. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +3 -5
  111. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +28 -426
  112. package/src/__tests__/host-bash-proxy.test.ts +335 -0
  113. package/src/__tests__/host-file-proxy.test.ts +374 -0
  114. package/src/__tests__/host-shell-tool.test.ts +147 -1
  115. package/src/__tests__/http-user-message-parity.test.ts +361 -0
  116. package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
  117. package/src/__tests__/integration-status.test.ts +3 -8
  118. package/src/__tests__/intent-routing.test.ts +7 -46
  119. package/src/__tests__/invite-redemption-service.test.ts +0 -1
  120. package/src/__tests__/invite-routes-http.test.ts +0 -1
  121. package/src/__tests__/llm-usage-store.test.ts +0 -1
  122. package/src/__tests__/managed-avatar-client.test.ts +101 -55
  123. package/src/__tests__/managed-skill-lifecycle.test.ts +9 -18
  124. package/src/__tests__/managed-store.test.ts +94 -21
  125. package/src/__tests__/media-reuse-story.e2e.test.ts +0 -1
  126. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +2 -4
  127. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -1
  128. package/src/__tests__/memory-recall-quality.test.ts +0 -1
  129. package/src/__tests__/memory-regressions.experimental.test.ts +0 -1
  130. package/src/__tests__/memory-regressions.test.ts +0 -1
  131. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -1
  132. package/src/__tests__/memory-upsert-concurrency.test.ts +0 -1
  133. package/src/__tests__/messaging-send-tool.test.ts +35 -0
  134. package/src/__tests__/messaging-skill-split.test.ts +138 -0
  135. package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1
  136. package/src/__tests__/migration-export-http.test.ts +2 -3
  137. package/src/__tests__/migration-import-commit-http.test.ts +1 -2
  138. package/src/__tests__/migration-import-preflight-http.test.ts +1 -2
  139. package/src/__tests__/migration-validate-http.test.ts +1 -2
  140. package/src/__tests__/native-web-search.test.ts +475 -0
  141. package/src/__tests__/navigate-settings-tab.test.ts +84 -0
  142. package/src/__tests__/non-member-access-request.test.ts +0 -1
  143. package/src/__tests__/notification-broadcaster.test.ts +15 -15
  144. package/src/__tests__/notification-decision-strategy.test.ts +6 -6
  145. package/src/__tests__/notification-deep-link.test.ts +7 -7
  146. package/src/__tests__/notification-guardian-path.test.ts +2 -3
  147. package/src/__tests__/notification-telegram-adapter.test.ts +1 -1
  148. package/src/__tests__/notification-thread-candidates.test.ts +4 -4
  149. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  150. package/src/__tests__/onboarding-template-contract.test.ts +0 -10
  151. package/src/__tests__/playbook-execution.test.ts +0 -1
  152. package/src/__tests__/playbook-tools.test.ts +0 -1
  153. package/src/__tests__/profile-compiler.test.ts +0 -1
  154. package/src/__tests__/provider-fail-open-selection.test.ts +12 -2
  155. package/src/__tests__/provider-managed-proxy-integration.test.ts +25 -0
  156. package/src/__tests__/qdrant-collection-migration.test.ts +223 -0
  157. package/src/__tests__/recording-handler.test.ts +30 -94
  158. package/src/__tests__/registry.test.ts +28 -35
  159. package/src/__tests__/relay-server.test.ts +0 -1
  160. package/src/__tests__/ride-shotgun-handler.test.ts +4 -20
  161. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  162. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  163. package/src/__tests__/runtime-events-sse.test.ts +0 -1
  164. package/src/__tests__/sandbox-diagnostics.test.ts +0 -1
  165. package/src/__tests__/scaffold-managed-skill-tool.test.ts +30 -28
  166. package/src/__tests__/schedule-store.test.ts +441 -1
  167. package/src/__tests__/schedule-tools.test.ts +468 -7
  168. package/src/__tests__/scheduler-recurrence.test.ts +196 -23
  169. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  170. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  171. package/src/__tests__/secret-prompt-log-hygiene.test.ts +6 -3
  172. package/src/__tests__/secret-response-routing.test.ts +4 -1
  173. package/src/__tests__/send-endpoint-busy.test.ts +14 -5
  174. package/src/__tests__/send-notification-tool.test.ts +0 -7
  175. package/src/__tests__/sequence-store.test.ts +0 -1
  176. package/src/__tests__/server-history-render.test.ts +1 -2
  177. package/src/__tests__/session-abort-tool-results.test.ts +0 -1
  178. package/src/__tests__/session-agent-loop.test.ts +46 -6
  179. package/src/__tests__/session-confirmation-signals.test.ts +7 -46
  180. package/src/__tests__/session-conflict-gate.test.ts +2 -6
  181. package/src/__tests__/session-error.test.ts +5 -14
  182. package/src/__tests__/session-init.benchmark.test.ts +3 -5
  183. package/src/__tests__/session-load-history-repair.test.ts +0 -1
  184. package/src/__tests__/session-media-retry.test.ts +12 -74
  185. package/src/__tests__/session-pre-run-repair.test.ts +0 -1
  186. package/src/__tests__/session-profile-injection.test.ts +2 -6
  187. package/src/__tests__/session-provider-retry-repair.test.ts +2 -6
  188. package/src/__tests__/session-queue.test.ts +94 -139
  189. package/src/__tests__/session-skill-tools.test.ts +115 -115
  190. package/src/__tests__/session-slash-known.test.ts +0 -1
  191. package/src/__tests__/session-slash-queue.test.ts +0 -1
  192. package/src/__tests__/session-slash-unknown.test.ts +0 -1
  193. package/src/__tests__/session-surfaces-task-progress.test.ts +34 -0
  194. package/src/__tests__/session-usage.test.ts +0 -1
  195. package/src/__tests__/session-workspace-cache-state.test.ts +2 -6
  196. package/src/__tests__/session-workspace-injection.test.ts +2 -6
  197. package/src/__tests__/session-workspace-tool-tracking.test.ts +2 -6
  198. package/src/__tests__/skill-feature-flags-integration.test.ts +180 -184
  199. package/src/__tests__/skill-feature-flags.test.ts +125 -18
  200. package/src/__tests__/skill-load-feature-flag.test.ts +1 -2
  201. package/src/__tests__/skill-load-tool.test.ts +194 -2
  202. package/src/__tests__/skill-projection-feature-flag.test.ts +27 -16
  203. package/src/__tests__/skill-projection.benchmark.test.ts +15 -14
  204. package/src/__tests__/skills.test.ts +14 -53
  205. package/src/__tests__/slack-channel-config.test.ts +0 -1
  206. package/src/__tests__/slack-inbound-verification.test.ts +0 -1
  207. package/src/__tests__/slack-skill.test.ts +1 -1
  208. package/src/__tests__/starter-task-flow.test.ts +9 -19
  209. package/src/__tests__/subagent-tools.test.ts +2 -2
  210. package/src/__tests__/system-prompt.test.ts +7 -7
  211. package/src/__tests__/task-compiler.test.ts +0 -1
  212. package/src/__tests__/task-management-tools.test.ts +0 -1
  213. package/src/__tests__/task-memory-cleanup.test.ts +0 -1
  214. package/src/__tests__/task-runner.test.ts +0 -1
  215. package/src/__tests__/task-scheduler.test.ts +0 -1
  216. package/src/__tests__/terminal-tools.test.ts +0 -1
  217. package/src/__tests__/test-support/computer-use-skill-harness.ts +2 -4
  218. package/src/__tests__/thread-seed-composer.test.ts +5 -5
  219. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  220. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  221. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  222. package/src/__tests__/tool-executor.test.ts +8 -86
  223. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  224. package/src/__tests__/tool-notification-listener.test.ts +1 -1
  225. package/src/__tests__/tool-preview-lifecycle.test.ts +416 -0
  226. package/src/__tests__/trust-store.test.ts +84 -8
  227. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  228. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  229. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -1
  230. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  231. package/src/__tests__/trusted-contact-verification.test.ts +0 -1
  232. package/src/__tests__/twilio-provider.test.ts +0 -1
  233. package/src/__tests__/twilio-routes.test.ts +0 -1
  234. package/src/__tests__/{request-file-tool.test.ts → ui-file-upload-surface.test.ts} +11 -72
  235. package/src/__tests__/update-bulletin.test.ts +0 -1
  236. package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -1
  237. package/src/__tests__/usage-routes.test.ts +0 -1
  238. package/src/__tests__/verification-control-plane-policy.test.ts +4 -4
  239. package/src/__tests__/voice-invite-redemption.test.ts +0 -1
  240. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  241. package/src/__tests__/voice-session-bridge.test.ts +9 -1
  242. package/src/__tests__/web-fetch.test.ts +57 -0
  243. package/src/__tests__/workspace-git-service.test.ts +5 -14
  244. package/src/__tests__/workspace-policy.test.ts +0 -1
  245. package/src/agent/loop.ts +22 -34
  246. package/src/bundler/bundle-signer.ts +4 -4
  247. package/src/calls/call-controller.ts +1 -1
  248. package/src/calls/relay-server.ts +1 -1
  249. package/src/calls/twilio-rest.ts +1 -1
  250. package/src/calls/voice-session-bridge.ts +3 -1
  251. package/src/cli/__tests__/notifications.test.ts +3 -4
  252. package/src/cli/commands/map.ts +2 -6
  253. package/src/cli/commands/mcp.ts +73 -15
  254. package/src/cli/commands/notifications.ts +4 -4
  255. package/src/cli/commands/sessions.ts +9 -1
  256. package/src/cli/commands/skills.ts +6 -10
  257. package/src/cli/http-client.ts +2 -3
  258. package/src/cli/main-screen.tsx +10 -10
  259. package/src/cli/program.ts +0 -4
  260. package/src/cli/reference.ts +0 -2
  261. package/src/cli.ts +15 -9
  262. package/src/config/__tests__/bundled-tool-registry-guard.test.ts +120 -0
  263. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +11 -0
  264. package/src/config/bundled-skills/app-builder/SKILL.md +6 -7
  265. package/src/config/bundled-skills/app-builder/TOOLS.json +0 -4
  266. package/src/config/bundled-skills/browser/SKILL.md +6 -1
  267. package/src/config/bundled-skills/chatgpt-import/SKILL.md +5 -1
  268. package/src/config/bundled-skills/claude-code/SKILL.md +5 -1
  269. package/src/config/bundled-skills/computer-use/SKILL.md +6 -1
  270. package/src/config/bundled-skills/computer-use/TOOLS.json +6 -69
  271. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +10 -1
  272. package/src/config/bundled-skills/contacts/SKILL.md +10 -1
  273. package/src/config/bundled-skills/contacts/TOOLS.json +35 -0
  274. package/src/config/bundled-skills/{messaging → contacts}/tools/google-contacts.ts +9 -2
  275. package/src/config/bundled-skills/document/SKILL.md +4 -1
  276. package/src/config/bundled-skills/doordash/SKILL.md +8 -2
  277. package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +1 -82
  278. package/src/config/bundled-skills/doordash/doordash-cli.ts +17 -28
  279. package/src/config/bundled-skills/doordash/lib/session.ts +21 -17
  280. package/src/config/bundled-skills/doordash/lib/shared/platform.ts +4 -1
  281. package/src/config/bundled-skills/followups/SKILL.md +4 -1
  282. package/src/config/bundled-skills/gmail/SKILL.md +180 -0
  283. package/src/config/bundled-skills/gmail/TOOLS.json +506 -0
  284. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +149 -0
  285. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +110 -0
  286. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-draft.ts +1 -1
  287. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-filters.ts +1 -1
  288. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-follow-up.ts +1 -1
  289. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-forward.ts +1 -1
  290. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +50 -0
  291. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-outreach-scan.ts +8 -90
  292. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-send-draft.ts +1 -1
  293. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-sender-digest.ts +2 -2
  294. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-trash.ts +1 -1
  295. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-unsubscribe.ts +1 -1
  296. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-vacation.ts +1 -1
  297. package/src/config/bundled-skills/gmail/tools/shared.ts +47 -0
  298. package/src/config/bundled-skills/google-calendar/SKILL.md +5 -1
  299. package/src/config/bundled-skills/image-studio/SKILL.md +5 -1
  300. package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -1
  301. package/src/config/bundled-skills/media-processing/SKILL.md +7 -13
  302. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -22
  303. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +12 -1
  304. package/src/config/bundled-skills/messaging/SKILL.md +23 -139
  305. package/src/config/bundled-skills/messaging/TOOLS.json +33 -1215
  306. package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +42 -0
  307. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +165 -2
  308. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +1 -13
  309. package/src/config/bundled-skills/messaging/tools/shared.ts +81 -34
  310. package/src/config/bundled-skills/notifications/SKILL.md +5 -1
  311. package/src/config/bundled-skills/orchestration/SKILL.md +30 -0
  312. package/src/config/bundled-skills/orchestration/TOOLS.json +35 -0
  313. package/src/config/bundled-skills/{reminder/tools/reminder-cancel.ts → orchestration/tools/swarm-delegate.ts} +3 -3
  314. package/src/config/bundled-skills/phone-calls/SKILL.md +9 -1
  315. package/src/config/bundled-skills/playbooks/SKILL.md +4 -1
  316. package/src/config/bundled-skills/schedule/SKILL.md +70 -9
  317. package/src/config/bundled-skills/schedule/TOOLS.json +38 -6
  318. package/src/config/bundled-skills/screen-watch/SKILL.md +28 -0
  319. package/src/config/bundled-skills/screen-watch/TOOLS.json +35 -0
  320. package/src/config/bundled-skills/{reminder/tools/reminder-create.ts → screen-watch/tools/start-screen-watch.ts} +3 -3
  321. package/src/config/bundled-skills/sequences/SKILL.md +47 -0
  322. package/src/config/bundled-skills/sequences/TOOLS.json +340 -0
  323. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +128 -0
  324. package/src/config/bundled-skills/sequences/tools/shared.ts +9 -0
  325. package/src/config/bundled-skills/settings/SKILL.md +12 -0
  326. package/src/config/bundled-skills/settings/TOOLS.json +112 -0
  327. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +43 -0
  328. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +52 -0
  329. package/src/config/bundled-skills/{computer-use/tools/computer-use-right-click.ts → settings/tools/set-avatar.ts} +2 -6
  330. package/src/{tools/system/voice-config.ts → config/bundled-skills/settings/tools/voice-config-update.ts} +59 -96
  331. package/src/config/bundled-skills/skill-management/SKILL.md +18 -0
  332. package/src/config/bundled-skills/skill-management/TOOLS.json +90 -0
  333. package/src/config/bundled-skills/{computer-use/tools/computer-use-double-click.ts → skill-management/tools/delete-managed.ts} +2 -6
  334. package/src/config/bundled-skills/skill-management/tools/scaffold-managed.ts +12 -0
  335. package/src/config/bundled-skills/slack/SKILL.md +5 -1
  336. package/src/config/bundled-skills/subagent/SKILL.md +4 -1
  337. package/src/config/bundled-skills/tasks/SKILL.md +5 -2
  338. package/src/config/bundled-skills/transcribe/SKILL.md +4 -1
  339. package/src/config/bundled-skills/watcher/SKILL.md +4 -1
  340. package/src/config/bundled-tool-registry.ts +118 -107
  341. package/src/config/env.ts +5 -2
  342. package/src/config/feature-flag-registry.json +33 -9
  343. package/src/config/loader.ts +10 -2
  344. package/src/config/schema.ts +19 -16
  345. package/src/config/schemas/inference.ts +12 -22
  346. package/src/config/schemas/memory-storage.ts +19 -1
  347. package/src/config/schemas/platform.ts +0 -16
  348. package/src/config/skill-state.ts +11 -8
  349. package/src/config/skills.ts +83 -32
  350. package/src/context/token-estimator.ts +11 -0
  351. package/src/context/window-manager.ts +180 -151
  352. package/src/daemon/computer-use-session.ts +11 -43
  353. package/src/daemon/daemon-control.ts +4 -1
  354. package/src/daemon/handlers/config-channels.ts +5 -9
  355. package/src/daemon/handlers/config-ingress.ts +0 -4
  356. package/src/daemon/handlers/config-model.ts +7 -13
  357. package/src/daemon/handlers/config-telegram.ts +4 -8
  358. package/src/daemon/handlers/config-voice.ts +2 -5
  359. package/src/daemon/handlers/dictation.ts +2 -12
  360. package/src/daemon/handlers/identity.ts +0 -105
  361. package/src/daemon/handlers/recording.ts +3 -23
  362. package/src/daemon/handlers/session-history.ts +42 -10
  363. package/src/daemon/handlers/sessions.ts +53 -72
  364. package/src/daemon/handlers/shared.ts +7 -28
  365. package/src/daemon/handlers/skills.ts +31 -27
  366. package/src/daemon/host-bash-proxy.ts +148 -0
  367. package/src/daemon/host-file-proxy.ts +135 -0
  368. package/src/daemon/lifecycle.ts +53 -41
  369. package/src/daemon/mcp-reload-service.ts +123 -0
  370. package/src/daemon/message-protocol.ts +6 -0
  371. package/src/daemon/message-types/apps.ts +0 -25
  372. package/src/daemon/message-types/browser.ts +1 -1
  373. package/src/daemon/message-types/computer-use.ts +1 -4
  374. package/src/daemon/message-types/guardian-actions.ts +1 -1
  375. package/src/daemon/message-types/host-bash.ts +18 -0
  376. package/src/daemon/message-types/host-file.ts +44 -0
  377. package/src/daemon/message-types/integrations.ts +1 -73
  378. package/src/daemon/message-types/messages.ts +15 -0
  379. package/src/daemon/message-types/schedules.ts +11 -27
  380. package/src/daemon/message-types/sessions.ts +8 -2
  381. package/src/daemon/message-types/settings.ts +1 -1
  382. package/src/daemon/message-types/shared.ts +1 -1
  383. package/src/daemon/message-types/surfaces.ts +2 -0
  384. package/src/daemon/ride-shotgun-handler.ts +35 -43
  385. package/src/daemon/seed-files.ts +3 -27
  386. package/src/daemon/server.ts +45 -28
  387. package/src/daemon/session-agent-loop-handlers.ts +72 -9
  388. package/src/daemon/session-agent-loop.ts +97 -66
  389. package/src/daemon/session-attachments.ts +1 -1
  390. package/src/daemon/session-error.ts +17 -16
  391. package/src/daemon/session-lifecycle.ts +20 -1
  392. package/src/daemon/session-media-retry.ts +1 -15
  393. package/src/daemon/session-messaging.ts +14 -6
  394. package/src/daemon/session-process.ts +36 -7
  395. package/src/daemon/session-queue-manager.ts +62 -103
  396. package/src/daemon/session-runtime-assembly.ts +27 -7
  397. package/src/daemon/session-skill-tools.ts +12 -11
  398. package/src/daemon/session-slash.ts +7 -0
  399. package/src/daemon/session-surfaces.ts +192 -118
  400. package/src/daemon/session-tool-setup.ts +146 -6
  401. package/src/daemon/session.ts +75 -37
  402. package/src/errors.ts +0 -2
  403. package/src/export/formatter.ts +6 -0
  404. package/src/mcp/mcp-oauth-provider.ts +1 -3
  405. package/src/media/avatar-router.ts +20 -28
  406. package/src/media/avatar-types.ts +7 -14
  407. package/src/media/managed-avatar-client.ts +70 -34
  408. package/src/memory/app-store.ts +0 -18
  409. package/src/memory/conversation-title-service.ts +1 -2
  410. package/src/memory/db-init.ts +16 -0
  411. package/src/memory/embedding-backend.ts +129 -27
  412. package/src/memory/embedding-gemini.test.ts +256 -0
  413. package/src/memory/embedding-gemini.ts +47 -13
  414. package/src/memory/embedding-local.ts +14 -2
  415. package/src/memory/embedding-ollama.ts +15 -2
  416. package/src/memory/embedding-openai.ts +15 -2
  417. package/src/memory/embedding-types.test.ts +116 -0
  418. package/src/memory/embedding-types.ts +61 -0
  419. package/src/memory/fingerprint.ts +1 -1
  420. package/src/memory/indexer.ts +25 -1
  421. package/src/memory/job-handlers/embedding.test.ts +258 -0
  422. package/src/memory/job-handlers/embedding.ts +81 -1
  423. package/src/memory/job-handlers/index-maintenance.ts +35 -1
  424. package/src/memory/job-handlers/media-processing.ts +11 -1
  425. package/src/memory/job-utils.ts +21 -6
  426. package/src/memory/jobs-store.ts +5 -1
  427. package/src/memory/jobs-worker.ts +8 -0
  428. package/src/memory/message-content.ts +66 -0
  429. package/src/memory/migrations/100-core-tables.ts +1 -31
  430. package/src/memory/migrations/104-core-indexes.ts +0 -11
  431. package/src/memory/migrations/145-drop-accounts-table.ts +19 -0
  432. package/src/memory/migrations/146-schedule-oneshot-routing.ts +94 -0
  433. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +129 -0
  434. package/src/memory/migrations/148-drop-reminders-table.ts +18 -0
  435. package/src/memory/migrations/index.ts +4 -0
  436. package/src/memory/migrations/registry.ts +19 -0
  437. package/src/memory/qdrant-client.ts +158 -43
  438. package/src/memory/retriever.test.ts +0 -1
  439. package/src/memory/retriever.ts +12 -2
  440. package/src/memory/schema/infrastructure.ts +5 -37
  441. package/src/memory/search/formatting.ts +34 -9
  442. package/src/memory/search/semantic.ts +57 -2
  443. package/src/memory/search/types.ts +2 -1
  444. package/src/notifications/AGENTS.md +2 -2
  445. package/src/notifications/README.md +59 -58
  446. package/src/notifications/adapters/macos.ts +1 -1
  447. package/src/notifications/broadcaster.ts +5 -5
  448. package/src/notifications/copy-composer.ts +1 -1
  449. package/src/notifications/decision-engine.ts +2 -2
  450. package/src/notifications/destination-resolver.ts +2 -2
  451. package/src/notifications/emit-signal.ts +8 -8
  452. package/src/notifications/signal.ts +1 -1
  453. package/src/notifications/thread-seed-composer.ts +1 -1
  454. package/src/oauth/connect-orchestrator.ts +1 -1
  455. package/src/oauth/token-persistence.ts +1 -1
  456. package/src/permissions/checker.ts +12 -1
  457. package/src/permissions/defaults.ts +13 -17
  458. package/src/permissions/trust-store.ts +37 -0
  459. package/src/permissions/workspace-policy.ts +0 -1
  460. package/src/prompts/__tests__/build-cli-reference-section.test.ts +11 -0
  461. package/src/prompts/computer-use-prompt.ts +1 -1
  462. package/src/prompts/system-prompt.ts +33 -35
  463. package/src/prompts/templates/BOOTSTRAP.md +0 -3
  464. package/src/prompts/templates/SOUL.md +1 -2
  465. package/src/prompts/templates/UPDATES.md +16 -7
  466. package/src/providers/anthropic/client.ts +87 -33
  467. package/src/providers/gemini/client.ts +6 -0
  468. package/src/providers/managed-proxy/constants.ts +5 -0
  469. package/src/providers/openai/client.ts +15 -0
  470. package/src/providers/registry.ts +4 -6
  471. package/src/providers/types.ts +24 -2
  472. package/src/runtime/AGENTS.md +18 -0
  473. package/src/runtime/assistant-event-hub.ts +2 -3
  474. package/src/runtime/assistant-event.ts +4 -4
  475. package/src/runtime/auth/__tests__/context.test.ts +5 -5
  476. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  477. package/src/runtime/auth/__tests__/guard-tests.test.ts +3 -2
  478. package/src/runtime/auth/__tests__/{ipc-auth-context.test.ts → local-auth-context.test.ts} +21 -21
  479. package/src/runtime/auth/__tests__/route-policy.test.ts +2 -2
  480. package/src/runtime/auth/__tests__/scopes.test.ts +9 -8
  481. package/src/runtime/auth/__tests__/subject.test.ts +8 -8
  482. package/src/runtime/auth/__tests__/token-service.test.ts +0 -1
  483. package/src/runtime/auth/route-policy.ts +8 -8
  484. package/src/runtime/auth/scopes.ts +2 -1
  485. package/src/runtime/auth/subject.ts +4 -4
  486. package/src/runtime/auth/token-service.ts +1 -24
  487. package/src/runtime/auth/types.ts +3 -3
  488. package/src/runtime/guardian-action-followup-executor.ts +1 -1
  489. package/src/runtime/guardian-action-grant-minter.ts +1 -1
  490. package/src/runtime/guardian-action-service.ts +3 -3
  491. package/src/runtime/http-server.ts +15 -2
  492. package/src/runtime/http-types.ts +10 -0
  493. package/src/runtime/invite-service.ts +3 -3
  494. package/src/runtime/local-actor-identity.ts +17 -22
  495. package/src/runtime/middleware/error-handler.ts +14 -1
  496. package/src/runtime/pending-interactions.ts +21 -9
  497. package/src/runtime/routes/app-management-routes.ts +63 -67
  498. package/src/runtime/routes/approval-routes.ts +1 -3
  499. package/src/runtime/routes/brain-graph/brain-graph.html +1845 -0
  500. package/src/runtime/routes/brain-graph-routes.ts +4 -42
  501. package/src/runtime/routes/btw-routes.ts +155 -0
  502. package/src/runtime/routes/computer-use-routes.ts +77 -31
  503. package/src/runtime/routes/conversation-routes.ts +234 -47
  504. package/src/runtime/routes/diagnostics-routes.ts +154 -43
  505. package/src/runtime/routes/documents-routes.ts +2 -2
  506. package/src/runtime/routes/global-search-routes.ts +1 -1
  507. package/src/runtime/routes/host-bash-routes.ts +83 -0
  508. package/src/runtime/routes/host-file-routes.ts +79 -0
  509. package/src/runtime/routes/integrations/slack/share.ts +1 -1
  510. package/src/runtime/routes/log-export-routes.ts +120 -0
  511. package/src/runtime/routes/mcp-routes.ts +20 -0
  512. package/src/runtime/routes/migration-routes.ts +3 -3
  513. package/src/runtime/routes/pairing-routes.ts +1 -1
  514. package/src/runtime/routes/recording-routes.ts +6 -4
  515. package/src/runtime/routes/schedule-routes.ts +31 -5
  516. package/src/runtime/routes/session-management-routes.ts +2 -6
  517. package/src/runtime/routes/session-query-routes.ts +18 -15
  518. package/src/runtime/routes/settings-routes.ts +7 -351
  519. package/src/runtime/routes/skills-routes.ts +7 -6
  520. package/src/runtime/routes/subagents-routes.ts +4 -10
  521. package/src/runtime/routes/surface-action-routes.ts +3 -14
  522. package/src/runtime/routes/surface-content-routes.ts +22 -5
  523. package/src/runtime/routes/work-items-routes.ts +21 -25
  524. package/src/runtime/routes/workspace-routes.test.ts +3 -3
  525. package/src/runtime/routes/workspace-utils.ts +1 -1
  526. package/src/runtime/telegram-streaming-delivery.ts +3 -0
  527. package/src/runtime/verification-outbound-actions.ts +2 -2
  528. package/src/schedule/integration-status.ts +0 -6
  529. package/src/schedule/schedule-store.ts +234 -43
  530. package/src/schedule/scheduler.ts +73 -74
  531. package/src/security/oauth2.ts +1 -1
  532. package/src/sequence/store.ts +12 -2
  533. package/src/skills/frontmatter.ts +19 -77
  534. package/src/skills/managed-store.ts +11 -2
  535. package/src/subagent/manager.ts +5 -3
  536. package/src/tasks/ephemeral-permissions.ts +3 -5
  537. package/src/tools/AGENTS.md +37 -0
  538. package/src/tools/apps/executors.ts +0 -6
  539. package/src/tools/browser/browser-manager.ts +17 -11
  540. package/src/tools/browser/jit-auth.ts +4 -1
  541. package/src/tools/claude-code/claude-code.ts +1 -1
  542. package/src/tools/computer-use/definitions.ts +48 -60
  543. package/src/tools/document/document-tool.ts +6 -6
  544. package/src/tools/document/editor-template.ts +10 -8
  545. package/src/tools/filesystem/edit.ts +2 -1
  546. package/src/tools/filesystem/read.ts +20 -2
  547. package/src/tools/filesystem/write.ts +2 -1
  548. package/src/tools/host-filesystem/edit.ts +17 -1
  549. package/src/tools/host-filesystem/read.ts +16 -1
  550. package/src/tools/host-filesystem/write.ts +15 -1
  551. package/src/tools/host-terminal/host-shell.ts +24 -0
  552. package/src/tools/memory/definitions.ts +45 -81
  553. package/src/tools/memory/handlers.test.ts +0 -1
  554. package/src/tools/memory/handlers.ts +1 -1
  555. package/src/tools/memory/register.ts +26 -60
  556. package/src/tools/network/script-proxy/session-manager.ts +6 -8
  557. package/src/tools/network/web-fetch.ts +7 -1
  558. package/src/tools/network/web-search.ts +2 -1
  559. package/src/tools/registry.ts +23 -0
  560. package/src/tools/schedule/create.ts +113 -5
  561. package/src/tools/schedule/list.ts +57 -15
  562. package/src/tools/schedule/update.ts +73 -3
  563. package/src/tools/shared/filesystem/image-read.ts +192 -0
  564. package/src/tools/side-effects.ts +1 -7
  565. package/src/tools/skills/delete-managed.ts +27 -64
  566. package/src/tools/skills/execute.ts +54 -0
  567. package/src/tools/skills/load.ts +127 -5
  568. package/src/tools/skills/scaffold-managed.ts +93 -172
  569. package/src/tools/subagent/message.ts +0 -7
  570. package/src/tools/subagent/spawn.ts +1 -1
  571. package/src/tools/swarm/delegate.ts +0 -3
  572. package/src/tools/system/avatar-generator.ts +13 -19
  573. package/src/tools/system/request-permission.ts +2 -1
  574. package/src/tools/terminal/safe-env.ts +1 -0
  575. package/src/tools/tool-manifest.ts +41 -47
  576. package/src/tools/types.ts +6 -2
  577. package/src/tools/ui-surface/definitions.ts +0 -55
  578. package/src/util/errors.ts +12 -10
  579. package/src/workspace/git-service.ts +0 -2
  580. package/src/__tests__/account-registry.test.ts +0 -258
  581. package/src/__tests__/email-classifier.test.ts +0 -25
  582. package/src/__tests__/gmail-integration.test.ts +0 -97
  583. package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -172
  584. package/src/__tests__/home-base-bootstrap.test.ts +0 -84
  585. package/src/__tests__/managed-twitter-guardrails.test.ts +0 -353
  586. package/src/__tests__/prebuilt-home-base-seed.test.ts +0 -79
  587. package/src/__tests__/recording-intent-fallback.test.ts +0 -199
  588. package/src/__tests__/recording-intent.test.ts +0 -985
  589. package/src/__tests__/recording-state-machine.test.ts +0 -1574
  590. package/src/__tests__/reminder-store.test.ts +0 -350
  591. package/src/__tests__/reminder.test.ts +0 -337
  592. package/src/__tests__/scan-result-store.test.ts +0 -121
  593. package/src/__tests__/twitter-platform-proxy-client.test.ts +0 -450
  594. package/src/__tests__/view-image-tool.test.ts +0 -241
  595. package/src/cli/commands/amazon/cart.ts +0 -513
  596. package/src/cli/commands/amazon/checkout.ts +0 -394
  597. package/src/cli/commands/amazon/client.ts +0 -513
  598. package/src/cli/commands/amazon/index.ts +0 -920
  599. package/src/cli/commands/amazon/product-details.ts +0 -145
  600. package/src/cli/commands/amazon/request-extractor.ts +0 -187
  601. package/src/cli/commands/amazon/search.ts +0 -76
  602. package/src/cli/commands/amazon/session.ts +0 -116
  603. package/src/cli/commands/twitter/__tests__/cli-error-shaping.test.ts +0 -265
  604. package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +0 -483
  605. package/src/cli/commands/twitter/__tests__/cli-routing.test.ts +0 -412
  606. package/src/cli/commands/twitter/__tests__/oauth-client.test.ts +0 -197
  607. package/src/cli/commands/twitter/client.ts +0 -989
  608. package/src/cli/commands/twitter/index.ts +0 -1160
  609. package/src/cli/commands/twitter/oauth-client.ts +0 -94
  610. package/src/cli/commands/twitter/router.ts +0 -396
  611. package/src/cli/commands/twitter/session.ts +0 -121
  612. package/src/config/bundled-skills/agentmail/SKILL.md +0 -132
  613. package/src/config/bundled-skills/agentmail/icon.svg +0 -21
  614. package/src/config/bundled-skills/amazon/SKILL.md +0 -137
  615. package/src/config/bundled-skills/amazon/icon.svg +0 -13
  616. package/src/config/bundled-skills/api-mapping/SKILL.md +0 -78
  617. package/src/config/bundled-skills/api-mapping/icon.svg +0 -18
  618. package/src/config/bundled-skills/cli-discover/SKILL.md +0 -68
  619. package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +0 -179
  620. package/src/config/bundled-skills/document-writer/SKILL.md +0 -195
  621. package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +0 -140
  622. package/src/config/bundled-skills/email-setup/SKILL.md +0 -68
  623. package/src/config/bundled-skills/frontend-design/SKILL.md +0 -44
  624. package/src/config/bundled-skills/frontend-design/icon.svg +0 -16
  625. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +0 -452
  626. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +0 -203
  627. package/src/config/bundled-skills/influencer/SKILL.md +0 -144
  628. package/src/config/bundled-skills/influencer/scripts/client.ts +0 -1269
  629. package/src/config/bundled-skills/influencer/scripts/influencer.ts +0 -267
  630. package/src/config/bundled-skills/macos-automation/SKILL.md +0 -65
  631. package/src/config/bundled-skills/macos-automation/icon.svg +0 -12
  632. package/src/config/bundled-skills/mcp-setup/SKILL.md +0 -75
  633. package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +0 -184
  634. package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +0 -80
  635. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +0 -29
  636. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +0 -56
  637. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +0 -34
  638. package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +0 -47
  639. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +0 -31
  640. package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +0 -67
  641. package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +0 -97
  642. package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +0 -87
  643. package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +0 -135
  644. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +0 -24
  645. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +0 -201
  646. package/src/config/bundled-skills/messaging/tools/send-notification.ts +0 -1
  647. package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +0 -27
  648. package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +0 -48
  649. package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +0 -27
  650. package/src/config/bundled-skills/messaging/tools/sequence-update.ts +0 -56
  651. package/src/config/bundled-skills/notion/SKILL.md +0 -240
  652. package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +0 -126
  653. package/src/config/bundled-skills/oauth-setup/SKILL.md +0 -143
  654. package/src/config/bundled-skills/public-ingress/SKILL.md +0 -258
  655. package/src/config/bundled-skills/reminder/SKILL.md +0 -79
  656. package/src/config/bundled-skills/reminder/TOOLS.json +0 -89
  657. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +0 -12
  658. package/src/config/bundled-skills/restaurant-reservation/SKILL.md +0 -141
  659. package/src/config/bundled-skills/screen-recording/SKILL.md +0 -148
  660. package/src/config/bundled-skills/self-upgrade/SKILL.md +0 -69
  661. package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -78
  662. package/src/config/bundled-skills/slack-app-setup/SKILL.md +0 -178
  663. package/src/config/bundled-skills/slack-digest-setup/SKILL.md +0 -163
  664. package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +0 -157
  665. package/src/config/bundled-skills/start-the-day/SKILL.md +0 -70
  666. package/src/config/bundled-skills/start-the-day/icon.svg +0 -13
  667. package/src/config/bundled-skills/telegram-setup/SKILL.md +0 -105
  668. package/src/config/bundled-skills/time-based-actions/SKILL.md +0 -142
  669. package/src/config/bundled-skills/twilio-setup/SKILL.md +0 -232
  670. package/src/config/bundled-skills/twitter/SKILL.md +0 -319
  671. package/src/config/bundled-skills/twitter/icon.svg +0 -14
  672. package/src/config/bundled-skills/typescript-eval/SKILL.md +0 -60
  673. package/src/config/bundled-skills/vercel-token-setup/SKILL.md +0 -214
  674. package/src/config/bundled-skills/voice-setup/SKILL.md +0 -131
  675. package/src/config/bundled-skills/voice-setup/icon.svg +0 -20
  676. package/src/daemon/handlers/pairing.ts +0 -119
  677. package/src/daemon/handlers/session-user-message.ts +0 -961
  678. package/src/daemon/recording-executor.ts +0 -180
  679. package/src/daemon/recording-intent-fallback.ts +0 -162
  680. package/src/daemon/recording-intent.ts +0 -493
  681. package/src/home-base/app-link-store.ts +0 -78
  682. package/src/home-base/bootstrap.ts +0 -74
  683. package/src/home-base/prebuilt/brain-graph.html +0 -1483
  684. package/src/home-base/prebuilt/index.html +0 -702
  685. package/src/home-base/prebuilt/seed-metadata.json +0 -21
  686. package/src/home-base/prebuilt/seed.ts +0 -122
  687. package/src/home-base/prebuilt-home-base-updater.ts +0 -36
  688. package/src/memory/account-store.ts +0 -117
  689. package/src/messaging/activity-analyzer.ts +0 -76
  690. package/src/messaging/email-classifier.ts +0 -208
  691. package/src/messaging/index.ts +0 -2
  692. package/src/messaging/outreach-classifier.ts +0 -185
  693. package/src/messaging/thread-summarizer.ts +0 -346
  694. package/src/messaging/types.ts +0 -17
  695. package/src/tools/browser/x-auto-navigate.ts +0 -254
  696. package/src/tools/credentials/account-registry.ts +0 -144
  697. package/src/tools/filesystem/view-image.ts +0 -244
  698. package/src/tools/reminder/reminder-store.ts +0 -194
  699. package/src/tools/reminder/reminder.ts +0 -158
  700. package/src/tools/system/navigate-settings.ts +0 -74
  701. package/src/tools/system/open-system-settings.ts +0 -85
  702. package/src/tools/system/version.ts +0 -54
  703. package/src/twitter/platform-proxy-client.ts +0 -405
  704. package/src/util/cookie-session.ts +0 -98
  705. /package/src/config/bundled-skills/{messaging → gmail}/tools/scan-result-store.ts +0 -0
  706. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-analytics.ts +0 -0
  707. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-create.ts +0 -0
  708. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-delete.ts +0 -0
  709. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enroll.ts +0 -0
  710. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enrollment-list.ts +0 -0
  711. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-get.ts +0 -0
  712. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-import.ts +0 -0
  713. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-list.ts +0 -0
@@ -1,989 +0,0 @@
1
- /**
2
- * Twitter API client.
3
- * Executes GraphQL queries through Chrome's CDP (Runtime.evaluate) so requests
4
- * go through the browser's authenticated session.
5
- */
6
-
7
- import { loadSession, type TwitterSession } from "./session.js";
8
-
9
- class ProviderError extends Error {
10
- constructor(
11
- message: string,
12
- public readonly provider: string,
13
- public readonly statusCode?: number,
14
- ) {
15
- super(message);
16
- this.name = "ProviderError";
17
- }
18
- }
19
-
20
- const CDP_BASE = "http://localhost:9222";
21
-
22
- /** Static bearer token used by x.com for all GraphQL requests. */
23
- const BEARER_TOKEN =
24
- "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA";
25
-
26
- // ─── Query IDs (captured from x.com) ─────────────────────────────────────────
27
-
28
- const QUERY_IDS = {
29
- CreateTweet: "Ah3G_byjEDs_HSlgU0PyZw",
30
- UserByScreenName: "AWbeRIdkLtqTRN7yL_H8yw",
31
- UserTweets: "N2tFDY-MlrLxXJ9F_ZxJGA",
32
- TweetDetail: "YCNdW_ZytXfV9YR3cJK9kw",
33
- SearchTimeline: "ML-n2SfAxx5S_9QMqNejbg",
34
- Bookmarks: "toTC7lB_mQm5fuBE5yyEJw",
35
- HomeTimeline: "nn16KxqX3E1OdE7WlHB5LA",
36
- NotificationsTimeline: "saZw4lppu6QzMEiRUCYurg",
37
- Likes: "Pcw-j9lrSeDMmkgnIejJiQ",
38
- Followers: "P7m4Qr-rJEB8KUluOenU6A",
39
- Following: "T5wihsMTYHncY7BB4YxHSg",
40
- UserMedia: "xLCC9bG_VqHfXXgq8jPoCg",
41
- } as const;
42
-
43
- /** Feature flags shared by all GraphQL endpoints. */
44
- const FEATURES: Record<string, boolean> = {
45
- rweb_video_screen_enabled: false,
46
- profile_label_improvements_pcf_label_in_post_enabled: true,
47
- responsive_web_profile_redirect_enabled: false,
48
- rweb_tipjar_consumption_enabled: false,
49
- verified_phone_label_enabled: false,
50
- creator_subscriptions_tweet_preview_api_enabled: true,
51
- responsive_web_graphql_timeline_navigation_enabled: true,
52
- responsive_web_graphql_skip_user_profile_image_extensions_enabled: false,
53
- premium_content_api_read_enabled: false,
54
- communities_web_enable_tweet_community_results_fetch: true,
55
- c9s_tweet_anatomy_moderator_badge_enabled: true,
56
- responsive_web_grok_analyze_button_fetch_trends_enabled: false,
57
- responsive_web_grok_analyze_post_followups_enabled: true,
58
- responsive_web_jetfuel_frame: true,
59
- responsive_web_grok_share_attachment_enabled: true,
60
- responsive_web_grok_annotations_enabled: true,
61
- articles_preview_enabled: true,
62
- responsive_web_edit_tweet_api_enabled: true,
63
- graphql_is_translatable_rweb_tweet_is_translatable_enabled: true,
64
- view_counts_everywhere_api_enabled: true,
65
- longform_notetweets_consumption_enabled: true,
66
- responsive_web_twitter_article_tweet_consumption_enabled: true,
67
- tweet_awards_web_tipping_enabled: false,
68
- responsive_web_grok_show_grok_translated_post: true,
69
- responsive_web_grok_analysis_button_from_backend: true,
70
- post_ctas_fetch_enabled: true,
71
- freedom_of_speech_not_reach_fetch_enabled: true,
72
- standardized_nudges_misinfo: true,
73
- tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true,
74
- longform_notetweets_rich_text_read_enabled: true,
75
- longform_notetweets_inline_media_enabled: true,
76
- responsive_web_grok_image_annotation_enabled: true,
77
- responsive_web_grok_imagine_annotation_enabled: true,
78
- responsive_web_grok_community_note_auto_translation_is_enabled: false,
79
- responsive_web_enhance_cards_enabled: false,
80
- };
81
-
82
- // ─── Errors ──────────────────────────────────────────────────────────────────
83
-
84
- /** Thrown when the session is missing or expired. */
85
- export class SessionExpiredError extends Error {
86
- constructor(reason: string) {
87
- super(reason);
88
- this.name = "SessionExpiredError";
89
- }
90
- }
91
-
92
- async function requireSession(): Promise<TwitterSession> {
93
- const session = await loadSession();
94
- if (!session) {
95
- throw new SessionExpiredError("No Twitter session found.");
96
- }
97
- return session;
98
- }
99
-
100
- // ─── CDP transport ───────────────────────────────────────────────────────────
101
-
102
- async function findTwitterTab(): Promise<string> {
103
- const res = await fetch(`${CDP_BASE}/json/list`).catch(() => null);
104
- if (!res?.ok) {
105
- throw new SessionExpiredError(
106
- "Chrome CDP not available. Run `assistant twitter refresh` first.",
107
- );
108
- }
109
- const targets = (await res.json()) as Array<{
110
- type: string;
111
- url: string;
112
- webSocketDebuggerUrl: string;
113
- }>;
114
- const tab = targets.find(
115
- (t) =>
116
- t.type === "page" &&
117
- (t.url.includes("x.com") || t.url.includes("twitter.com")),
118
- );
119
- if (!tab?.webSocketDebuggerUrl) {
120
- throw new SessionExpiredError(
121
- "No x.com tab found in Chrome. Open x.com and try again.",
122
- );
123
- }
124
- return tab.webSocketDebuggerUrl;
125
- }
126
-
127
- /** Standard headers for X API requests (as a JS expression for Runtime.evaluate). */
128
- const API_HEADERS_GET = `{
129
- 'authorization': 'Bearer ${BEARER_TOKEN}',
130
- 'x-csrf-token': csrf,
131
- 'x-twitter-auth-type': 'OAuth2Session',
132
- 'x-twitter-active-user': 'yes',
133
- 'x-twitter-client-language': 'en',
134
- }`;
135
-
136
- const API_HEADERS_POST = `{
137
- 'Content-Type': 'application/json',
138
- 'authorization': 'Bearer ${BEARER_TOKEN}',
139
- 'x-csrf-token': csrf,
140
- 'x-twitter-auth-type': 'OAuth2Session',
141
- 'x-twitter-active-user': 'yes',
142
- 'x-twitter-client-language': 'en',
143
- }`;
144
-
145
- /** Execute a POST fetch inside Chrome via CDP Runtime.evaluate. */
146
- async function cdpFetch(
147
- wsUrl: string,
148
- url: string,
149
- body: string,
150
- ): Promise<unknown> {
151
- return cdpEval(
152
- wsUrl,
153
- `
154
- (function() {
155
- var csrf = (document.cookie.match(/ct0=([^;]+)/) || [])[1] || '';
156
- return fetch(${JSON.stringify(url)}, {
157
- method: 'POST',
158
- headers: ${API_HEADERS_POST},
159
- body: ${JSON.stringify(body)},
160
- credentials: 'include',
161
- })
162
- .then(function(r) {
163
- if (!r.ok) return r.text().then(function(t) {
164
- return JSON.stringify({ __status: r.status, __error: true, __body: t.substring(0, 500) });
165
- });
166
- return r.text();
167
- })
168
- .catch(function(e) { return JSON.stringify({ __error: true, __message: e.message }); });
169
- })()
170
- `,
171
- );
172
- }
173
-
174
- /** Execute a GET fetch inside Chrome via CDP Runtime.evaluate. */
175
- async function cdpGet(wsUrl: string, url: string): Promise<unknown> {
176
- return cdpEval(
177
- wsUrl,
178
- `
179
- (function() {
180
- var csrf = (document.cookie.match(/ct0=([^;]+)/) || [])[1] || '';
181
- return fetch(${JSON.stringify(url)}, {
182
- method: 'GET',
183
- headers: ${API_HEADERS_GET},
184
- credentials: 'include',
185
- })
186
- .then(function(r) {
187
- if (!r.ok) return r.text().then(function(t) {
188
- return JSON.stringify({ __status: r.status, __error: true, __body: t.substring(0, 500) });
189
- });
190
- return r.text();
191
- })
192
- .catch(function(e) { return JSON.stringify({ __error: true, __message: e.message }); });
193
- })()
194
- `,
195
- );
196
- }
197
-
198
- /**
199
- * Navigate Chrome to a URL and capture the response body of a specific GraphQL query.
200
- * This works for endpoints that require X's client-generated transaction ID (e.g. Search, Followers)
201
- * because the browser's own JavaScript generates the correct headers.
202
- */
203
- async function cdpNavigateAndCapture(
204
- wsUrl: string,
205
- pageUrl: string,
206
- queryName: string,
207
- ): Promise<unknown> {
208
- return new Promise((resolve, reject) => {
209
- const ws = new WebSocket(wsUrl);
210
- let nextId = 1;
211
- const callbacks = new Map<number, (v: unknown) => void>();
212
- const pendingRequestIds = new Set<string>();
213
-
214
- const timeout = setTimeout(() => {
215
- ws.close();
216
- reject(
217
- new Error(`CDP navigate+capture timed out waiting for ${queryName}`),
218
- );
219
- }, 30000);
220
-
221
- function send(
222
- method: string,
223
- params?: Record<string, unknown>,
224
- ): Promise<unknown> {
225
- const id = nextId++;
226
- return new Promise((r) => {
227
- callbacks.set(id, r);
228
- ws.send(JSON.stringify({ id, method, params }));
229
- });
230
- }
231
-
232
- ws.onmessage = (event) => {
233
- const msg = JSON.parse(typeof event.data === "string" ? event.data : "");
234
-
235
- // Handle command responses
236
- if (msg.id != null && callbacks.has(msg.id)) {
237
- callbacks.get(msg.id)!(msg.result ?? msg.error);
238
- callbacks.delete(msg.id);
239
- return;
240
- }
241
-
242
- // Track GraphQL requests matching our query name
243
- if (msg.method === "Network.requestWillBeSent") {
244
- const req = msg.params?.request;
245
- const url = req?.url as string | undefined;
246
- if (url?.includes(`/graphql/`) && url?.includes(`/${queryName}`)) {
247
- pendingRequestIds.add(msg.params.requestId as string);
248
- }
249
- }
250
-
251
- // Capture response when loading finishes
252
- if (msg.method === "Network.loadingFinished") {
253
- const requestId = msg.params?.requestId as string;
254
- if (!pendingRequestIds.has(requestId)) return;
255
- pendingRequestIds.delete(requestId);
256
-
257
- send("Network.getResponseBody", { requestId })
258
- .then((result) => {
259
- const body = (result as Record<string, unknown>)?.body as string;
260
- if (!body) return;
261
- try {
262
- const json = JSON.parse(body);
263
- clearTimeout(timeout);
264
- ws.close();
265
- if (json.errors?.length) {
266
- reject(
267
- new Error(
268
- `X API errors: ${json.errors.map((e: { message: string }) => e.message).join("; ")}`,
269
- ),
270
- );
271
- } else {
272
- resolve(json);
273
- }
274
- } catch {
275
- /* not JSON, skip */
276
- }
277
- })
278
- .catch(() => {
279
- /* ignore */
280
- });
281
- }
282
- };
283
-
284
- ws.onerror = () => {
285
- clearTimeout(timeout);
286
- reject(new SessionExpiredError("CDP connection failed."));
287
- };
288
-
289
- ws.onopen = async () => {
290
- await send("Network.enable");
291
- await send("Page.enable");
292
- await send("Page.navigate", { url: pageUrl });
293
- };
294
- });
295
- }
296
-
297
- /** Shared CDP evaluate helper. */
298
- async function cdpEval(wsUrl: string, expression: string): Promise<unknown> {
299
- return new Promise((resolve, reject) => {
300
- const ws = new WebSocket(wsUrl);
301
- const id = 1;
302
-
303
- const timeout = setTimeout(() => {
304
- ws.close();
305
- reject(new Error("CDP fetch timed out after 30s"));
306
- }, 30000);
307
-
308
- ws.onopen = () => {
309
- ws.send(
310
- JSON.stringify({
311
- id,
312
- method: "Runtime.evaluate",
313
- params: { expression, awaitPromise: true, returnByValue: true },
314
- }),
315
- );
316
- };
317
-
318
- ws.onmessage = (event) => {
319
- try {
320
- const msg = JSON.parse(
321
- typeof event.data === "string" ? event.data : "",
322
- );
323
- if (msg.id === id) {
324
- clearTimeout(timeout);
325
- ws.close();
326
-
327
- if (msg.error) {
328
- reject(new Error(`CDP error: ${msg.error.message}`));
329
- return;
330
- }
331
-
332
- const value = msg.result?.result?.value;
333
- if (!value) {
334
- reject(new Error("Empty CDP response"));
335
- return;
336
- }
337
-
338
- const parsed = typeof value === "string" ? JSON.parse(value) : value;
339
- if (parsed.__error) {
340
- if (parsed.__status === 403 || parsed.__status === 401) {
341
- reject(new SessionExpiredError("Twitter session has expired."));
342
- } else {
343
- reject(
344
- new Error(
345
- parsed.__message ??
346
- `HTTP ${parsed.__status}: ${parsed.__body ?? ""}`,
347
- ),
348
- );
349
- }
350
- return;
351
- }
352
- resolve(parsed);
353
- }
354
- } catch (err) {
355
- clearTimeout(timeout);
356
- ws.close();
357
- reject(err);
358
- }
359
- };
360
-
361
- ws.onerror = () => {
362
- clearTimeout(timeout);
363
- reject(new SessionExpiredError("CDP connection failed."));
364
- };
365
- });
366
- }
367
-
368
- // ─── GraphQL helpers ─────────────────────────────────────────────────────────
369
-
370
- /** Build a GraphQL GET URL with encoded variables and features. */
371
- function graphqlUrl(
372
- queryId: string,
373
- queryName: string,
374
- variables: Record<string, unknown>,
375
- ): string {
376
- const v = encodeURIComponent(JSON.stringify(variables));
377
- const f = encodeURIComponent(JSON.stringify(FEATURES));
378
- return `https://x.com/i/api/graphql/${queryId}/${queryName}?variables=${v}&features=${f}`;
379
- }
380
-
381
- /** Execute a GraphQL GET query and return the parsed response. */
382
- async function graphqlGet(
383
- queryId: string,
384
- queryName: string,
385
- variables: Record<string, unknown>,
386
- ): Promise<unknown> {
387
- await requireSession();
388
- const wsUrl = await findTwitterTab();
389
- const url = graphqlUrl(queryId, queryName, variables);
390
- const json = (await cdpGet(wsUrl, url)) as {
391
- errors?: Array<{ message: string }>;
392
- };
393
- if (json.errors?.length) {
394
- throw new ProviderError(
395
- `X API errors: ${json.errors.map((e) => e.message).join("; ")}`,
396
- "x",
397
- );
398
- }
399
- return json;
400
- }
401
-
402
- // ─── Twitter API response types ──────────────────────────────────────────────
403
-
404
- interface TwitterUserLegacy {
405
- screen_name?: string;
406
- name?: string;
407
- }
408
-
409
- interface TwitterUserCore {
410
- screen_name?: string;
411
- name?: string;
412
- }
413
-
414
- interface TwitterUserResult {
415
- rest_id?: string;
416
- legacy?: TwitterUserLegacy;
417
- core?: TwitterUserCore;
418
- }
419
-
420
- interface TwitterUserResults {
421
- result?: TwitterUserResult;
422
- }
423
-
424
- interface TweetLegacy {
425
- full_text?: string;
426
- created_at?: string;
427
- }
428
-
429
- interface TweetResult {
430
- __typename?: string;
431
- rest_id?: string;
432
- legacy?: TweetLegacy;
433
- core?: { user_results?: TwitterUserResults };
434
- tweet?: TweetResult;
435
- }
436
-
437
- interface TweetResults {
438
- result?: TweetResult;
439
- }
440
-
441
- interface TimelineItemContent {
442
- __typename?: string;
443
- tweet_results?: TweetResults;
444
- user_results?: TwitterUserResults;
445
- // Notification-specific fields
446
- id?: string;
447
- rich_message?: { text?: string };
448
- notification_text?: { text?: string };
449
- timestamp_ms?: string;
450
- notification_url?: { url?: string };
451
- }
452
-
453
- interface TimelineModuleItem {
454
- item?: { itemContent?: TimelineItemContent };
455
- }
456
-
457
- interface TimelineEntryContent {
458
- itemContent?: TimelineItemContent;
459
- items?: TimelineModuleItem[];
460
- }
461
-
462
- interface TimelineEntry {
463
- entryId?: string;
464
- content?: TimelineEntryContent;
465
- }
466
-
467
- interface TimelineInstruction {
468
- entries?: TimelineEntry[];
469
- }
470
-
471
- interface TimelineContainer {
472
- instructions?: TimelineInstruction[];
473
- }
474
-
475
- interface TimelineWrapper {
476
- timeline?: TimelineContainer;
477
- }
478
-
479
- interface TwitterApiError {
480
- message: string;
481
- }
482
-
483
- /** Response from CreateTweet mutation. */
484
- interface CreateTweetResponse {
485
- errors?: TwitterApiError[];
486
- data?: {
487
- create_tweet?: {
488
- tweet_results?: TweetResults;
489
- };
490
- };
491
- }
492
-
493
- /** Response from UserByScreenName query. */
494
- interface UserByScreenNameResponse {
495
- data?: {
496
- user?: {
497
- result?: TwitterUserResult;
498
- };
499
- };
500
- }
501
-
502
- /** Response from UserTweets query. */
503
- interface UserTweetsResponse {
504
- data?: {
505
- user?: {
506
- result?: {
507
- timeline_v2?: TimelineWrapper;
508
- timeline?: TimelineWrapper;
509
- };
510
- };
511
- };
512
- }
513
-
514
- /** Response from TweetDetail query. */
515
- interface TweetDetailResponse {
516
- data?: {
517
- threaded_conversation_with_injections_v2?: TimelineContainer;
518
- };
519
- }
520
-
521
- /** Response from SearchTimeline query. */
522
- interface SearchTimelineResponse {
523
- data?: {
524
- search_by_raw_query?: {
525
- search_timeline?: TimelineWrapper;
526
- };
527
- };
528
- }
529
-
530
- /** Response from Bookmarks query. */
531
- interface BookmarksResponse {
532
- data?: {
533
- bookmark_timeline_v2?: TimelineWrapper;
534
- };
535
- }
536
-
537
- /** Response from HomeTimeline query. */
538
- interface HomeTimelineResponse {
539
- data?: {
540
- home?: {
541
- home_timeline_urt?: TimelineContainer;
542
- };
543
- };
544
- }
545
-
546
- /** Response from NotificationsTimeline query. */
547
- interface NotificationsTimelineResponse {
548
- data?: {
549
- viewer_v2?: {
550
- user_results?: {
551
- result?: {
552
- notification_timeline?: TimelineWrapper;
553
- };
554
- };
555
- };
556
- };
557
- }
558
-
559
- /** Response from Likes / Following / Followers / UserMedia queries. */
560
- interface UserTimelineResponse {
561
- data?: {
562
- user?: {
563
- result?: {
564
- timeline?: TimelineWrapper;
565
- };
566
- };
567
- };
568
- }
569
-
570
- // ─── Tweet extraction helpers ────────────────────────────────────────────────
571
-
572
- function extractScreenName(tweetResult: TweetResult): string {
573
- return (
574
- tweetResult?.core?.user_results?.result?.legacy?.screen_name ??
575
- tweetResult?.core?.user_results?.result?.core?.screen_name ??
576
- "i"
577
- );
578
- }
579
-
580
- /** Extract tweets from a timeline instructions array (shared by most endpoints). */
581
- function extractTweetsFromInstructions(
582
- instructions: TimelineInstruction[],
583
- ): TweetEntry[] {
584
- const tweets: TweetEntry[] = [];
585
- for (const instruction of instructions) {
586
- // Handle both array-style entries and direct entries
587
- const entries = instruction.entries ?? [];
588
- for (const entry of entries) {
589
- // Standard tweet entry
590
- let tweetResult = entry.content?.itemContent?.tweet_results?.result;
591
- // Some results wrap in __typename: "TweetWithVisibilityResults"
592
- if (tweetResult?.__typename === "TweetWithVisibilityResults") {
593
- tweetResult = tweetResult.tweet;
594
- }
595
- if (tweetResult?.rest_id) {
596
- tweets.push({
597
- tweetId: tweetResult.rest_id,
598
- text: tweetResult.legacy?.full_text ?? "",
599
- url: `https://x.com/${extractScreenName(tweetResult)}/status/${tweetResult.rest_id}`,
600
- createdAt: tweetResult.legacy?.created_at ?? "",
601
- });
602
- }
603
-
604
- // Search results can have TimelineTimelineModule with nested items
605
- if (entry.content?.items) {
606
- for (const item of entry.content.items) {
607
- let tr = item.item?.itemContent?.tweet_results?.result;
608
- if (tr?.__typename === "TweetWithVisibilityResults") tr = tr.tweet;
609
- if (tr?.rest_id) {
610
- tweets.push({
611
- tweetId: tr.rest_id,
612
- text: tr.legacy?.full_text ?? "",
613
- url: `https://x.com/${extractScreenName(tr)}/status/${tr.rest_id}`,
614
- createdAt: tr.legacy?.created_at ?? "",
615
- });
616
- }
617
- }
618
- }
619
- }
620
- }
621
- return tweets;
622
- }
623
-
624
- /** Extract users from a timeline instructions array (Followers/Following). */
625
- function extractUsersFromInstructions(
626
- instructions: TimelineInstruction[],
627
- ): UserInfo[] {
628
- const users: UserInfo[] = [];
629
- for (const instruction of instructions) {
630
- for (const entry of instruction.entries ?? []) {
631
- const userResult = entry.content?.itemContent?.user_results?.result;
632
- if (userResult?.rest_id) {
633
- users.push({
634
- userId: userResult.rest_id,
635
- screenName:
636
- userResult.legacy?.screen_name ??
637
- userResult.core?.screen_name ??
638
- "",
639
- name: userResult.legacy?.name ?? userResult.core?.name ?? "",
640
- });
641
- }
642
- }
643
- }
644
- return users;
645
- }
646
-
647
- // ─── Public types ────────────────────────────────────────────────────────────
648
-
649
- export interface PostTweetResult {
650
- tweetId: string;
651
- text: string;
652
- url: string;
653
- }
654
-
655
- export interface UserInfo {
656
- userId: string;
657
- screenName: string;
658
- name: string;
659
- }
660
-
661
- export interface TweetEntry {
662
- tweetId: string;
663
- text: string;
664
- url: string;
665
- createdAt: string;
666
- }
667
-
668
- export interface NotificationEntry {
669
- id: string;
670
- message: string;
671
- timestamp: string;
672
- url?: string;
673
- }
674
-
675
- // ─── Write operations ────────────────────────────────────────────────────────
676
-
677
- export async function postTweet(
678
- text: string,
679
- opts?: { inReplyToTweetId?: string },
680
- ): Promise<PostTweetResult> {
681
- await requireSession();
682
-
683
- const wsUrl = await findTwitterTab();
684
- const url = `https://x.com/i/api/graphql/${QUERY_IDS.CreateTweet}/CreateTweet`;
685
- const variables: Record<string, unknown> = {
686
- tweet_text: text,
687
- dark_request: false,
688
- media: {
689
- media_entities: [],
690
- possibly_sensitive: false,
691
- },
692
- semantic_annotation_ids: [],
693
- disallowed_reply_options: null,
694
- };
695
- if (opts?.inReplyToTweetId) {
696
- variables.reply = {
697
- in_reply_to_tweet_id: opts.inReplyToTweetId,
698
- exclude_reply_user_ids: [],
699
- };
700
- }
701
- const body = JSON.stringify({
702
- variables,
703
- features: FEATURES,
704
- queryId: QUERY_IDS.CreateTweet,
705
- });
706
-
707
- const json = (await cdpFetch(wsUrl, url, body)) as CreateTweetResponse;
708
-
709
- if (json.errors?.length) {
710
- throw new ProviderError(
711
- `X API errors: ${json.errors.map((e) => e.message).join("; ")}`,
712
- "x",
713
- );
714
- }
715
-
716
- const tweetResults = json.data?.create_tweet?.tweet_results;
717
- const result = tweetResults?.result;
718
- if (!result?.rest_id) {
719
- if (tweetResults && !result) {
720
- throw new ProviderError(
721
- "X rejected this post — it may be a duplicate of a recent post. Try different text.",
722
- "x",
723
- );
724
- }
725
- throw new ProviderError(
726
- `Unexpected response from X API. Response: ${JSON.stringify(json).slice(0, 500)}`,
727
- "x",
728
- );
729
- }
730
-
731
- return {
732
- tweetId: result.rest_id,
733
- text,
734
- url: `https://x.com/${extractScreenName(result)}/status/${result.rest_id}`,
735
- };
736
- }
737
-
738
- // ─── User lookup ─────────────────────────────────────────────────────────────
739
-
740
- export async function getUserByScreenName(
741
- screenName: string,
742
- ): Promise<UserInfo> {
743
- const json = (await graphqlGet(
744
- QUERY_IDS.UserByScreenName,
745
- "UserByScreenName",
746
- {
747
- screen_name: screenName,
748
- withGrokTranslatedBio: true,
749
- },
750
- )) as UserByScreenNameResponse;
751
-
752
- const user = json.data?.user?.result;
753
- if (!user?.rest_id) {
754
- throw new ProviderError(`User @${screenName} not found`, "x");
755
- }
756
-
757
- return {
758
- userId: user.rest_id,
759
- screenName: user.legacy?.screen_name ?? screenName,
760
- name: user.legacy?.name ?? screenName,
761
- };
762
- }
763
-
764
- // ─── User tweets ─────────────────────────────────────────────────────────────
765
-
766
- export async function getUserTweets(
767
- userId: string,
768
- count = 20,
769
- ): Promise<TweetEntry[]> {
770
- const json = (await graphqlGet(QUERY_IDS.UserTweets, "UserTweets", {
771
- userId,
772
- count,
773
- includePromotedContent: true,
774
- withQuickPromoteEligibilityTweetFields: true,
775
- withVoice: true,
776
- })) as UserTweetsResponse;
777
-
778
- // Response path: data.user.result.timeline_v2.timeline.instructions[]
779
- // Fallback to data.user.result.timeline.timeline.instructions[]
780
- const timelineData =
781
- json.data?.user?.result?.timeline_v2 ?? json.data?.user?.result?.timeline;
782
- const instructions = timelineData?.timeline?.instructions ?? [];
783
- return extractTweetsFromInstructions(instructions);
784
- }
785
-
786
- // ─── Tweet detail ────────────────────────────────────────────────────────────
787
-
788
- export async function getTweetDetail(tweetId: string): Promise<TweetEntry[]> {
789
- const json = (await graphqlGet(QUERY_IDS.TweetDetail, "TweetDetail", {
790
- focalTweetId: tweetId,
791
- referrer: "tweet",
792
- with_rux_injections: false,
793
- rankingMode: "Relevance",
794
- includePromotedContent: true,
795
- withCommunity: true,
796
- withQuickPromoteEligibilityTweetFields: true,
797
- withBirdwatchNotes: true,
798
- withVoice: true,
799
- })) as TweetDetailResponse;
800
-
801
- // Response path: data.threaded_conversation_with_injections_v2.instructions[]
802
- const instructions =
803
- json.data?.threaded_conversation_with_injections_v2?.instructions ?? [];
804
- return extractTweetsFromInstructions(instructions);
805
- }
806
-
807
- // ─── Search ──────────────────────────────────────────────────────────────────
808
-
809
- export async function searchTweets(
810
- query: string,
811
- product: "Top" | "Latest" | "People" | "Media" = "Top",
812
- ): Promise<TweetEntry[]> {
813
- await requireSession();
814
- const wsUrl = await findTwitterTab();
815
-
816
- // Search requires X's client-generated transaction ID, so we navigate Chrome
817
- // to the search page and capture the response from network events.
818
- const productParam = product === "Top" ? "" : `&f=${product.toLowerCase()}`;
819
- const pageUrl = `https://x.com/search?q=${encodeURIComponent(query)}&src=typed_query${productParam}`;
820
- const json = (await cdpNavigateAndCapture(
821
- wsUrl,
822
- pageUrl,
823
- "SearchTimeline",
824
- )) as SearchTimelineResponse;
825
-
826
- const instructions =
827
- json.data?.search_by_raw_query?.search_timeline?.timeline?.instructions ??
828
- [];
829
- return extractTweetsFromInstructions(instructions);
830
- }
831
-
832
- // ─── Bookmarks ───────────────────────────────────────────────────────────────
833
-
834
- export async function getBookmarks(count = 20): Promise<TweetEntry[]> {
835
- const json = (await graphqlGet(QUERY_IDS.Bookmarks, "Bookmarks", {
836
- count,
837
- includePromotedContent: true,
838
- })) as BookmarksResponse;
839
-
840
- // Response path: data.bookmark_timeline_v2.timeline.instructions[]
841
- const instructions =
842
- json.data?.bookmark_timeline_v2?.timeline?.instructions ?? [];
843
- return extractTweetsFromInstructions(instructions);
844
- }
845
-
846
- // ─── Home timeline ───────────────────────────────────────────────────────────
847
-
848
- export async function getHomeTimeline(count = 20): Promise<TweetEntry[]> {
849
- const json = (await graphqlGet(QUERY_IDS.HomeTimeline, "HomeTimeline", {
850
- count,
851
- includePromotedContent: true,
852
- requestContext: "launch",
853
- withCommunity: true,
854
- })) as HomeTimelineResponse;
855
-
856
- // Response path: data.home.home_timeline_urt.instructions[]
857
- const instructions = json.data?.home?.home_timeline_urt?.instructions ?? [];
858
- return extractTweetsFromInstructions(instructions);
859
- }
860
-
861
- // ─── Notifications ───────────────────────────────────────────────────────────
862
-
863
- export async function getNotifications(
864
- count = 20,
865
- ): Promise<NotificationEntry[]> {
866
- const json = (await graphqlGet(
867
- QUERY_IDS.NotificationsTimeline,
868
- "NotificationsTimeline",
869
- {
870
- timeline_type: "All",
871
- count,
872
- },
873
- )) as NotificationsTimelineResponse;
874
-
875
- // Response path: data.viewer_v2.user_results.result.notification_timeline.timeline.instructions[]
876
- const instructions =
877
- json.data?.viewer_v2?.user_results?.result?.notification_timeline?.timeline
878
- ?.instructions ?? [];
879
-
880
- const notifications: NotificationEntry[] = [];
881
- for (const instruction of instructions) {
882
- for (const entry of instruction.entries ?? []) {
883
- const ic = entry.content?.itemContent;
884
- if (ic?.__typename !== "TimelineNotification") continue;
885
- notifications.push({
886
- id: ic.id ?? entry.entryId ?? "",
887
- message: ic.rich_message?.text ?? ic.notification_text?.text ?? "",
888
- timestamp: ic.timestamp_ms ?? "",
889
- url: ic.notification_url?.url,
890
- });
891
- }
892
- }
893
- return notifications;
894
- }
895
-
896
- // ─── Likes ───────────────────────────────────────────────────────────────────
897
-
898
- export async function getLikes(
899
- userId: string,
900
- count = 20,
901
- ): Promise<TweetEntry[]> {
902
- const json = (await graphqlGet(QUERY_IDS.Likes, "Likes", {
903
- userId,
904
- count,
905
- includePromotedContent: false,
906
- withClientEventToken: false,
907
- withBirdwatchNotes: false,
908
- withVoice: true,
909
- })) as UserTimelineResponse;
910
-
911
- // Response path: data.user.result.timeline.timeline.instructions[]
912
- const instructions =
913
- json.data?.user?.result?.timeline?.timeline?.instructions ?? [];
914
- return extractTweetsFromInstructions(instructions);
915
- }
916
-
917
- // ─── Followers ───────────────────────────────────────────────────────────────
918
-
919
- export async function getFollowers(
920
- userId: string,
921
- screenName?: string,
922
- ): Promise<UserInfo[]> {
923
- // Followers requires X's client-generated transaction ID.
924
- // Navigate to the followers page and capture via CDP.
925
- if (screenName) {
926
- await requireSession();
927
- const wsUrl = await findTwitterTab();
928
- const json = (await cdpNavigateAndCapture(
929
- wsUrl,
930
- `https://x.com/${screenName}/followers`,
931
- "Followers",
932
- )) as UserTimelineResponse;
933
- const instructions =
934
- json.data?.user?.result?.timeline?.timeline?.instructions ?? [];
935
- return extractUsersFromInstructions(instructions);
936
- }
937
-
938
- const json = (await graphqlGet(QUERY_IDS.Followers, "Followers", {
939
- userId,
940
- count: 20,
941
- includePromotedContent: false,
942
- withGrokTranslatedBio: false,
943
- })) as UserTimelineResponse;
944
-
945
- const instructions =
946
- json.data?.user?.result?.timeline?.timeline?.instructions ?? [];
947
- return extractUsersFromInstructions(instructions);
948
- }
949
-
950
- // ─── Following ───────────────────────────────────────────────────────────────
951
-
952
- export async function getFollowing(
953
- userId: string,
954
- count = 20,
955
- ): Promise<UserInfo[]> {
956
- const json = (await graphqlGet(QUERY_IDS.Following, "Following", {
957
- userId,
958
- count,
959
- includePromotedContent: false,
960
- withGrokTranslatedBio: false,
961
- })) as UserTimelineResponse;
962
-
963
- // Response path: data.user.result.timeline.timeline.instructions[]
964
- const instructions =
965
- json.data?.user?.result?.timeline?.timeline?.instructions ?? [];
966
- return extractUsersFromInstructions(instructions);
967
- }
968
-
969
- // ─── User media ──────────────────────────────────────────────────────────────
970
-
971
- export async function getUserMedia(
972
- userId: string,
973
- count = 20,
974
- ): Promise<TweetEntry[]> {
975
- const json = (await graphqlGet(QUERY_IDS.UserMedia, "UserMedia", {
976
- userId,
977
- count,
978
- includePromotedContent: false,
979
- withClientEventToken: false,
980
- withBirdwatchNotes: false,
981
- withVoice: true,
982
- })) as UserTimelineResponse;
983
-
984
- // Response path: data.user.result.timeline.timeline.instructions[]
985
- // (same as Likes — contains tweets that have media)
986
- const instructions =
987
- json.data?.user?.result?.timeline?.timeline?.instructions ?? [];
988
- return extractTweetsFromInstructions(instructions);
989
- }