@vellumai/assistant 0.4.41 → 0.4.43

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 (843) hide show
  1. package/.env.example +1 -6
  2. package/.prettierignore +3 -0
  3. package/ARCHITECTURE.md +131 -393
  4. package/Dockerfile +0 -1
  5. package/README.md +73 -83
  6. package/bun.lock +8 -2
  7. package/docs/architecture/integrations.md +16 -21
  8. package/docs/architecture/memory.md +1 -1
  9. package/docs/architecture/scheduling.md +63 -63
  10. package/docs/architecture/security.md +3 -3
  11. package/docs/runbook-trusted-contacts.md +11 -12
  12. package/docs/trusted-contact-access.md +39 -39
  13. package/package.json +5 -8
  14. package/src/__tests__/access-request-decision.test.ts +4 -4
  15. package/src/__tests__/active-skill-tools.test.ts +49 -34
  16. package/src/__tests__/actor-token-service.test.ts +55 -85
  17. package/src/__tests__/amazon-cdp-integration.test.ts +14 -26
  18. package/src/__tests__/app-bundler.test.ts +14 -368
  19. package/src/__tests__/app-compiler.test.ts +0 -1
  20. package/src/__tests__/app-executors.test.ts +10 -1
  21. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
  22. package/src/__tests__/approval-primitive.test.ts +2 -4
  23. package/src/__tests__/approval-routes-http.test.ts +1 -1
  24. package/src/__tests__/asset-materialize-tool.test.ts +1 -4
  25. package/src/__tests__/asset-search-tool.test.ts +1 -4
  26. package/src/__tests__/assistant-attachments.test.ts +23 -0
  27. package/src/__tests__/assistant-feature-flags-integration.test.ts +4 -8
  28. package/src/__tests__/assistant-id-boundary-guard.test.ts +5 -5
  29. package/src/__tests__/attachments-store.test.ts +1 -4
  30. package/src/__tests__/avatar-e2e.test.ts +43 -23
  31. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  32. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -9
  33. package/src/__tests__/call-controller.test.ts +4 -8
  34. package/src/__tests__/call-conversation-messages.test.ts +1 -1
  35. package/src/__tests__/call-domain.test.ts +250 -8
  36. package/src/__tests__/call-pointer-message-composer.test.ts +14 -14
  37. package/src/__tests__/call-pointer-messages.test.ts +7 -11
  38. package/src/__tests__/call-recovery.test.ts +47 -0
  39. package/src/__tests__/call-routes-http.test.ts +13 -0
  40. package/src/__tests__/call-start-guardian-guard.test.ts +1 -1
  41. package/src/__tests__/callback-handoff-copy.test.ts +5 -5
  42. package/src/__tests__/canonical-guardian-store.test.ts +3 -3
  43. package/src/__tests__/channel-approval-routes.test.ts +101 -134
  44. package/src/__tests__/channel-approval.test.ts +0 -201
  45. package/src/__tests__/channel-approvals.test.ts +2 -2
  46. package/src/__tests__/channel-delivery-store.test.ts +16 -24
  47. package/src/__tests__/channel-guardian.test.ts +641 -740
  48. package/src/__tests__/channel-invite-transport.test.ts +1 -2
  49. package/src/__tests__/channel-policy.test.ts +9 -12
  50. package/src/__tests__/channel-readiness-service.test.ts +156 -45
  51. package/src/__tests__/channel-reply-delivery.test.ts +3 -3
  52. package/src/__tests__/channel-retry-sweep.test.ts +7 -7
  53. package/src/__tests__/checker.test.ts +10 -7
  54. package/src/__tests__/chrome-cdp.test.ts +57 -17
  55. package/src/__tests__/cli-help-reference-sync.test.ts +26 -0
  56. package/src/__tests__/compaction.benchmark.test.ts +25 -5
  57. package/src/__tests__/computer-use-session-lifecycle.test.ts +1 -1
  58. package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
  59. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +1 -1
  60. package/src/__tests__/config-loader-backfill.test.ts +310 -0
  61. package/src/__tests__/config-watcher.test.ts +1 -5
  62. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +3 -5
  63. package/src/__tests__/connection-policy.test.ts +3 -62
  64. package/src/__tests__/contacts-tools.test.ts +0 -2
  65. package/src/__tests__/context-memory-e2e.test.ts +11 -7
  66. package/src/__tests__/context-overflow-policy.test.ts +2 -2
  67. package/src/__tests__/context-window-manager.test.ts +220 -61
  68. package/src/__tests__/conversation-attention-store.test.ts +178 -2
  69. package/src/__tests__/conversation-attention-telegram.test.ts +8 -11
  70. package/src/__tests__/conversation-pairing.test.ts +14 -14
  71. package/src/__tests__/conversation-routes-guardian-reply.test.ts +1 -1
  72. package/src/__tests__/conversation-store.test.ts +2 -2
  73. package/src/__tests__/conversation-unread-route.test.ts +155 -0
  74. package/src/__tests__/credential-metadata-store.test.ts +0 -2
  75. package/src/__tests__/credential-security-invariants.test.ts +9 -16
  76. package/src/__tests__/credentials-cli.test.ts +49 -5
  77. package/src/__tests__/daemon-assistant-events.test.ts +4 -22
  78. package/src/__tests__/db-migration-rollback.test.ts +2 -2
  79. package/src/__tests__/deterministic-verification-control-plane.test.ts +19 -19
  80. package/src/__tests__/dictation-mode-detection.test.ts +1 -1
  81. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  82. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -6
  83. package/src/__tests__/email-cli.test.ts +12 -12
  84. package/src/__tests__/email-service-config-fallback.test.ts +1 -1
  85. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -18
  86. package/src/__tests__/event-bus.test.ts +0 -1
  87. package/src/__tests__/followup-tools.test.ts +0 -2
  88. package/src/__tests__/gateway-client-managed-outbound.test.ts +6 -6
  89. package/src/__tests__/gateway-only-enforcement.test.ts +13 -77
  90. package/src/__tests__/gateway-only-guard.test.ts +5 -0
  91. package/src/__tests__/guardian-action-conversation-turn.test.ts +3 -3
  92. package/src/__tests__/guardian-action-followup-executor.test.ts +29 -94
  93. package/src/__tests__/guardian-action-followup-store.test.ts +2 -12
  94. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +48 -194
  95. package/src/__tests__/guardian-action-late-reply.test.ts +12 -12
  96. package/src/__tests__/guardian-action-store.test.ts +2 -2
  97. package/src/__tests__/guardian-action-sweep.test.ts +5 -5
  98. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -3
  99. package/src/__tests__/guardian-dispatch.test.ts +5 -46
  100. package/src/__tests__/guardian-grant-minting.test.ts +5 -44
  101. package/src/__tests__/guardian-outbound-http.test.ts +95 -114
  102. package/src/__tests__/guardian-question-mode.test.ts +1 -4
  103. package/src/__tests__/guardian-routing-invariants.test.ts +5 -13
  104. package/src/__tests__/guardian-routing-state.test.ts +3 -3
  105. package/src/__tests__/guardian-verification-voice-binding.test.ts +64 -7
  106. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +2 -2
  107. package/src/__tests__/handle-user-message-secret-resume.test.ts +3 -5
  108. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +16 -34
  109. package/src/__tests__/headless-browser-interactions.test.ts +1 -1
  110. package/src/__tests__/headless-browser-navigate.test.ts +1 -1
  111. package/src/__tests__/headless-browser-read-tools.test.ts +1 -1
  112. package/src/__tests__/headless-browser-snapshot.test.ts +1 -1
  113. package/src/__tests__/heartbeat-service.test.ts +1 -1
  114. package/src/__tests__/home-base-bootstrap.test.ts +0 -2
  115. package/src/__tests__/host-shell-tool.test.ts +3 -12
  116. package/src/__tests__/inbound-invite-redemption.test.ts +2 -2
  117. package/src/__tests__/ingress-url-consistency.test.ts +0 -64
  118. package/src/__tests__/integration-status.test.ts +8 -8
  119. package/src/__tests__/intent-routing.test.ts +9 -13
  120. package/src/__tests__/invite-redemption-service.test.ts +4 -4
  121. package/src/__tests__/invite-routes-http.test.ts +10 -10
  122. package/src/__tests__/llm-usage-store.test.ts +45 -9
  123. package/src/__tests__/local-gateway-health.test.ts +209 -0
  124. package/src/__tests__/managed-avatar-client.test.ts +23 -12
  125. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -2
  126. package/src/__tests__/managed-store.test.ts +29 -12
  127. package/src/__tests__/managed-twitter-guardrails.test.ts +353 -0
  128. package/src/__tests__/mcp-cli.test.ts +1 -1
  129. package/src/__tests__/mcp-health-check.test.ts +1 -1
  130. package/src/__tests__/media-generate-image.test.ts +1 -1
  131. package/src/__tests__/media-reuse-story.e2e.test.ts +1 -4
  132. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +9 -6
  133. package/src/__tests__/memory-regressions.test.ts +1 -166
  134. package/src/__tests__/messaging-send-tool.test.ts +8 -4
  135. package/src/__tests__/migration-export-http.test.ts +2 -2
  136. package/src/__tests__/migration-transport.test.ts +44 -0
  137. package/src/__tests__/non-member-access-request.test.ts +49 -36
  138. package/src/__tests__/notification-broadcaster.test.ts +15 -15
  139. package/src/__tests__/notification-decision-fallback.test.ts +2 -2
  140. package/src/__tests__/notification-decision-strategy.test.ts +4 -4
  141. package/src/__tests__/notification-deep-link.test.ts +3 -3
  142. package/src/__tests__/notification-guardian-path.test.ts +6 -44
  143. package/src/__tests__/notification-routing-intent.test.ts +11 -7
  144. package/src/__tests__/oauth-cli.test.ts +1 -1
  145. package/src/__tests__/onboarding-starter-tasks.test.ts +2 -6
  146. package/src/__tests__/onboarding-template-contract.test.ts +2 -2
  147. package/src/__tests__/platform.test.ts +168 -5
  148. package/src/__tests__/playbook-execution.test.ts +0 -2
  149. package/src/__tests__/playbook-tools.test.ts +0 -2
  150. package/src/__tests__/pricing.test.ts +125 -0
  151. package/src/__tests__/provider-error-scenarios.test.ts +9 -3
  152. package/src/__tests__/recording-handler.test.ts +46 -80
  153. package/src/__tests__/recording-state-machine.test.ts +112 -183
  154. package/src/__tests__/registry.test.ts +1 -1
  155. package/src/__tests__/relay-server.test.ts +69 -71
  156. package/src/__tests__/reminder-store.test.ts +3 -3
  157. package/src/__tests__/request-file-tool.test.ts +2 -2
  158. package/src/__tests__/ride-shotgun-handler.test.ts +2 -33
  159. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -3
  160. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  161. package/src/__tests__/scaffold-managed-skill-tool.test.ts +4 -4
  162. package/src/__tests__/schedule-store.test.ts +13 -4
  163. package/src/__tests__/schedule-tools.test.ts +0 -2
  164. package/src/__tests__/scheduler-recurrence.test.ts +3 -4
  165. package/src/__tests__/scoped-approval-grants.test.ts +3 -5
  166. package/src/__tests__/scoped-grant-security-matrix.test.ts +6 -8
  167. package/src/__tests__/secret-prompt-log-hygiene.test.ts +1 -1
  168. package/src/__tests__/secret-response-routing.test.ts +1 -1
  169. package/src/__tests__/send-endpoint-busy.test.ts +1 -1
  170. package/src/__tests__/sequence-store.test.ts +0 -2
  171. package/src/__tests__/server-history-render.test.ts +2 -199
  172. package/src/__tests__/session-abort-tool-results.test.ts +9 -3
  173. package/src/__tests__/session-agent-loop.test.ts +107 -3
  174. package/src/__tests__/session-confirmation-signals.test.ts +10 -4
  175. package/src/__tests__/session-conflict-gate.test.ts +9 -3
  176. package/src/__tests__/session-init.benchmark.test.ts +22 -13
  177. package/src/__tests__/session-load-history-repair.test.ts +6 -3
  178. package/src/__tests__/session-pre-run-repair.test.ts +9 -3
  179. package/src/__tests__/session-profile-injection.test.ts +9 -3
  180. package/src/__tests__/session-provider-retry-repair.test.ts +10 -4
  181. package/src/__tests__/session-queue.test.ts +10 -4
  182. package/src/__tests__/session-runtime-assembly.test.ts +28 -18
  183. package/src/__tests__/session-skill-tools.test.ts +2 -3
  184. package/src/__tests__/session-slash-known.test.ts +11 -4
  185. package/src/__tests__/session-slash-queue.test.ts +11 -4
  186. package/src/__tests__/session-slash-unknown.test.ts +12 -4
  187. package/src/__tests__/session-surfaces-deselection.test.ts +2 -2
  188. package/src/__tests__/session-surfaces-task-progress.test.ts +3 -3
  189. package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -1
  190. package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -1
  191. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -1
  192. package/src/__tests__/session-usage.test.ts +180 -0
  193. package/src/__tests__/session-workspace-cache-state.test.ts +8 -2
  194. package/src/__tests__/session-workspace-injection.test.ts +8 -2
  195. package/src/__tests__/session-workspace-tool-tracking.test.ts +8 -2
  196. package/src/__tests__/skill-feature-flags-integration.test.ts +5 -11
  197. package/src/__tests__/skill-feature-flags.test.ts +1 -0
  198. package/src/__tests__/skill-include-graph.test.ts +1 -0
  199. package/src/__tests__/skill-load-feature-flag.test.ts +3 -9
  200. package/src/__tests__/skill-load-tool.test.ts +90 -12
  201. package/src/__tests__/skill-projection-feature-flag.test.ts +14 -15
  202. package/src/__tests__/skills-uninstall.test.ts +131 -0
  203. package/src/__tests__/skills.test.ts +32 -16
  204. package/src/__tests__/slack-block-formatting.test.ts +1 -1
  205. package/src/__tests__/slack-channel-config.test.ts +71 -12
  206. package/src/__tests__/slack-inbound-verification.test.ts +7 -7
  207. package/src/__tests__/slack-share-routes.test.ts +1 -1
  208. package/src/__tests__/slack-skill.test.ts +2 -2
  209. package/src/__tests__/slash-commands-catalog.test.ts +1 -0
  210. package/src/__tests__/slash-commands-resolver.test.ts +1 -0
  211. package/src/__tests__/starter-task-flow.test.ts +1 -1
  212. package/src/__tests__/subagent-manager-notify.test.ts +1 -1
  213. package/src/__tests__/subagent-tools.test.ts +2 -2
  214. package/src/__tests__/system-prompt.test.ts +4 -8
  215. package/src/__tests__/task-compiler.test.ts +0 -2
  216. package/src/__tests__/task-management-tools.test.ts +0 -2
  217. package/src/__tests__/task-runner.test.ts +0 -2
  218. package/src/__tests__/task-scheduler.test.ts +2 -2
  219. package/src/__tests__/telegram-bot-username-resolution.test.ts +46 -44
  220. package/src/__tests__/terminal-tools.test.ts +1 -11
  221. package/src/__tests__/thread-seed-composer.test.ts +3 -1
  222. package/src/__tests__/tool-approval-handler.test.ts +5 -7
  223. package/src/__tests__/tool-executor.test.ts +2 -2
  224. package/src/__tests__/tool-grant-request-escalation.test.ts +3 -5
  225. package/src/__tests__/tool-notification-listener.test.ts +1 -1
  226. package/src/__tests__/tool-profiling-listener.test.ts +1 -1
  227. package/src/__tests__/tool-trace-listener.test.ts +1 -2
  228. package/src/__tests__/trace-emitter.test.ts +1 -1
  229. package/src/__tests__/trust-context-guards.test.ts +1 -1
  230. package/src/__tests__/trust-store.test.ts +44 -395
  231. package/src/__tests__/trusted-contact-approval-notifier.test.ts +6 -8
  232. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +5 -7
  233. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +6 -6
  234. package/src/__tests__/trusted-contact-multichannel.test.ts +54 -47
  235. package/src/__tests__/trusted-contact-verification.test.ts +12 -12
  236. package/src/__tests__/twilio-config.test.ts +11 -2
  237. package/src/__tests__/twilio-provider.test.ts +6 -4
  238. package/src/__tests__/twilio-routes.test.ts +408 -86
  239. package/src/__tests__/twitter-platform-proxy-client.test.ts +450 -0
  240. package/src/__tests__/update-bulletin-format.test.ts +1 -1
  241. package/src/__tests__/update-bulletin-state.test.ts +1 -1
  242. package/src/__tests__/update-bulletin.test.ts +4 -8
  243. package/src/__tests__/update-template-contract.test.ts +1 -1
  244. package/src/__tests__/usage-cache-backfill-migration.test.ts +406 -0
  245. package/src/__tests__/usage-routes.test.ts +23 -5
  246. package/src/__tests__/user-reference.test.ts +1 -1
  247. package/src/__tests__/{guardian-control-plane-policy.test.ts → verification-control-plane-policy.test.ts} +142 -170
  248. package/src/__tests__/{guardian-verification-intent-routing.test.ts → verification-session-intent-routing.test.ts} +16 -16
  249. package/src/__tests__/view-image-tool.test.ts +0 -2
  250. package/src/__tests__/voice-ingress-preflight.test.ts +36 -0
  251. package/src/__tests__/voice-invite-redemption.test.ts +18 -18
  252. package/src/__tests__/voice-scoped-grant-consumer.test.ts +7 -7
  253. package/src/__tests__/voice-session-bridge.test.ts +14 -16
  254. package/src/__tests__/workspace-policy.test.ts +1 -1
  255. package/src/approvals/AGENTS.md +4 -4
  256. package/src/approvals/approval-primitive.ts +2 -2
  257. package/src/approvals/guardian-decision-primitive.ts +1 -1
  258. package/src/approvals/guardian-request-resolvers.ts +3 -4
  259. package/src/bundler/app-bundler.ts +29 -217
  260. package/src/bundler/app-compiler.ts +131 -103
  261. package/src/bundler/compiler-tools.ts +248 -0
  262. package/src/calls/active-call-lease.ts +207 -0
  263. package/src/calls/call-constants.ts +0 -7
  264. package/src/calls/call-controller.ts +1 -1
  265. package/src/calls/call-conversation-messages.ts +6 -6
  266. package/src/calls/call-domain.ts +73 -38
  267. package/src/calls/call-pointer-message-composer.ts +6 -6
  268. package/src/calls/call-pointer-messages.ts +14 -13
  269. package/src/calls/call-recovery.ts +2 -0
  270. package/src/calls/call-store.ts +21 -28
  271. package/src/calls/guardian-action-sweep.ts +6 -8
  272. package/src/calls/guardian-dispatch.ts +2 -6
  273. package/src/calls/relay-access-wait.ts +4 -4
  274. package/src/calls/relay-server.ts +69 -80
  275. package/src/calls/relay-setup-router.ts +16 -21
  276. package/src/calls/relay-verification.ts +27 -28
  277. package/src/calls/twilio-config.ts +28 -3
  278. package/src/calls/twilio-provider.ts +5 -5
  279. package/src/calls/twilio-rest.ts +26 -27
  280. package/src/calls/twilio-routes.ts +67 -54
  281. package/src/calls/types.ts +8 -8
  282. package/src/calls/voice-ingress-preflight.ts +110 -0
  283. package/src/calls/voice-session-bridge.ts +7 -7
  284. package/src/channels/config.ts +1 -10
  285. package/src/{config/channel-permission-profiles.ts → channels/permission-profiles.ts} +1 -1
  286. package/src/channels/types.ts +2 -13
  287. package/src/cli/__tests__/notifications.test.ts +1 -1
  288. package/src/{amazon → cli/commands/amazon}/client.ts +99 -42
  289. package/src/cli/{amazon.ts → commands/amazon/index.ts} +12 -17
  290. package/src/{amazon → cli/commands/amazon}/request-extractor.ts +39 -3
  291. package/src/cli/commands/amazon/session.ts +116 -0
  292. package/src/cli/{audit.ts → commands/audit.ts} +2 -4
  293. package/src/cli/{autonomy.ts → commands/autonomy.ts} +1 -3
  294. package/src/cli/commands/browser-relay.ts +520 -0
  295. package/src/cli/commands/channel-verification-sessions.ts +442 -0
  296. package/src/cli/{completions.ts → commands/completions.ts} +1 -3
  297. package/src/cli/{config.ts → commands/config.ts} +3 -5
  298. package/src/cli/{contacts.ts → commands/contacts.ts} +263 -16
  299. package/src/cli/{credentials.ts → commands/credentials.ts} +9 -10
  300. package/src/cli/{default-action.ts → commands/default-action.ts} +3 -3
  301. package/src/cli/{dev.ts → commands/dev.ts} +4 -6
  302. package/src/cli/{doctor.ts → commands/doctor.ts} +36 -60
  303. package/src/cli/{email.ts → commands/email.ts} +2 -2
  304. package/src/cli/{keys.ts → commands/keys.ts} +6 -6
  305. package/src/cli/{map.ts → commands/map.ts} +85 -93
  306. package/src/cli/{mcp.ts → commands/mcp.ts} +5 -7
  307. package/src/cli/{memory.ts → commands/memory.ts} +6 -7
  308. package/src/cli/{notifications.ts → commands/notifications.ts} +8 -10
  309. package/src/cli/{oauth.ts → commands/oauth.ts} +2 -2
  310. package/src/cli/commands/platform.ts +176 -0
  311. package/src/cli/{sequence.ts → commands/sequence.ts} +3 -3
  312. package/src/cli/{sessions.ts → commands/sessions.ts} +32 -52
  313. package/src/cli/commands/skills.ts +498 -0
  314. package/src/cli/{trust.ts → commands/trust.ts} +2 -4
  315. package/src/{__tests__/twitter-cli-error-shaping.test.ts → cli/commands/twitter/__tests__/cli-error-shaping.test.ts} +43 -2
  316. package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +483 -0
  317. package/src/{__tests__/twitter-cli-routing.test.ts → cli/commands/twitter/__tests__/cli-routing.test.ts} +130 -4
  318. package/src/{__tests__/twitter-oauth-client.test.ts → cli/commands/twitter/__tests__/oauth-client.test.ts} +2 -2
  319. package/src/{twitter → cli/commands/twitter}/client.ts +17 -7
  320. package/src/cli/{twitter.ts → commands/twitter/index.ts} +322 -273
  321. package/src/cli/commands/twitter/router.ts +396 -0
  322. package/src/cli/commands/twitter/session.ts +121 -0
  323. package/src/cli/db.ts +1 -0
  324. package/src/cli/http-client.ts +87 -0
  325. package/src/cli/logger.ts +6 -0
  326. package/src/cli/main-screen.tsx +4 -3
  327. package/src/cli/output.ts +19 -0
  328. package/src/cli/program.ts +29 -27
  329. package/src/cli/reference.ts +27 -37
  330. package/src/cli.ts +452 -240
  331. package/src/config/assistant-feature-flags.ts +3 -15
  332. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +3 -6
  333. package/src/config/bundled-skills/agentmail/SKILL.md +4 -4
  334. package/src/config/bundled-skills/amazon/SKILL.md +15 -5
  335. package/src/config/bundled-skills/api-mapping/SKILL.md +4 -4
  336. package/src/config/bundled-skills/app-builder/SKILL.md +21 -6
  337. package/src/config/bundled-skills/browser/SKILL.md +4 -5
  338. package/src/config/bundled-skills/chatgpt-import/SKILL.md +4 -4
  339. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
  340. package/src/config/bundled-skills/claude-code/SKILL.md +4 -4
  341. package/src/config/bundled-skills/cli-discover/SKILL.md +4 -4
  342. package/src/config/bundled-skills/computer-use/SKILL.md +4 -4
  343. package/src/config/bundled-skills/contacts/SKILL.md +87 -229
  344. package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +4 -4
  345. package/src/config/bundled-skills/document/SKILL.md +4 -3
  346. package/src/config/bundled-skills/document-writer/SKILL.md +4 -4
  347. package/src/config/bundled-skills/doordash/SKILL.md +4 -11
  348. package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +8 -16
  349. package/src/config/bundled-skills/doordash/doordash-cli.ts +120 -86
  350. package/src/config/bundled-skills/doordash/lib/session.ts +1 -2
  351. package/src/config/bundled-skills/doordash/lib/shared/platform.ts +26 -9
  352. package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +140 -0
  353. package/src/config/bundled-skills/email-setup/SKILL.md +4 -4
  354. package/src/config/bundled-skills/followups/SKILL.md +4 -3
  355. package/src/config/bundled-skills/frontend-design/SKILL.md +2 -0
  356. package/src/config/bundled-skills/google-calendar/SKILL.md +4 -4
  357. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +4 -6
  358. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +26 -41
  359. package/src/config/bundled-skills/image-studio/SKILL.md +4 -5
  360. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -1
  361. package/src/config/bundled-skills/influencer/SKILL.md +19 -19
  362. package/src/{influencer → config/bundled-skills/influencer/scripts}/client.ts +73 -56
  363. package/src/config/bundled-skills/influencer/scripts/influencer.ts +267 -0
  364. package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -2
  365. package/src/config/bundled-skills/macos-automation/SKILL.md +4 -5
  366. package/src/config/bundled-skills/mcp-setup/SKILL.md +4 -4
  367. package/src/config/bundled-skills/media-processing/SKILL.md +3 -2
  368. package/src/config/bundled-skills/messaging/SKILL.md +6 -33
  369. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -5
  370. package/src/config/bundled-skills/notifications/SKILL.md +4 -4
  371. package/src/config/bundled-skills/notion/SKILL.md +4 -4
  372. package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +4 -5
  373. package/src/config/bundled-skills/oauth-setup/SKILL.md +4 -5
  374. package/src/config/bundled-skills/phone-calls/SKILL.md +24 -458
  375. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +83 -0
  376. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +57 -0
  377. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +67 -0
  378. package/src/config/bundled-skills/playbooks/SKILL.md +4 -3
  379. package/src/config/bundled-skills/public-ingress/SKILL.md +65 -14
  380. package/src/config/bundled-skills/reminder/SKILL.md +4 -3
  381. package/src/config/bundled-skills/restaurant-reservation/SKILL.md +4 -6
  382. package/src/config/bundled-skills/schedule/SKILL.md +4 -3
  383. package/src/config/bundled-skills/screen-recording/SKILL.md +4 -3
  384. package/src/config/bundled-skills/self-upgrade/SKILL.md +4 -4
  385. package/src/config/bundled-skills/skills-catalog/SKILL.md +4 -4
  386. package/src/config/bundled-skills/slack/SKILL.md +4 -8
  387. package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +1 -1
  388. package/src/config/bundled-skills/slack-app-setup/SKILL.md +66 -88
  389. package/src/config/bundled-skills/slack-digest-setup/SKILL.md +4 -5
  390. package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +4 -5
  391. package/src/config/bundled-skills/start-the-day/SKILL.md +4 -4
  392. package/src/config/bundled-skills/subagent/SKILL.md +4 -3
  393. package/src/config/bundled-skills/tasks/SKILL.md +4 -3
  394. package/src/config/bundled-skills/telegram-setup/SKILL.md +63 -112
  395. package/src/config/bundled-skills/time-based-actions/SKILL.md +4 -3
  396. package/src/config/bundled-skills/transcribe/SKILL.md +4 -3
  397. package/src/config/bundled-skills/twilio-setup/SKILL.md +23 -50
  398. package/src/config/bundled-skills/twitter/SKILL.md +56 -14
  399. package/src/config/bundled-skills/typescript-eval/SKILL.md +4 -4
  400. package/src/config/bundled-skills/vercel-token-setup/SKILL.md +4 -5
  401. package/src/config/bundled-skills/voice-setup/SKILL.md +19 -45
  402. package/src/config/bundled-skills/watcher/SKILL.md +4 -3
  403. package/src/config/env-registry.ts +1 -10
  404. package/src/config/feature-flag-registry.json +0 -16
  405. package/src/config/loader.ts +78 -38
  406. package/src/config/schema.ts +143 -106
  407. package/src/config/schemas/channels.ts +80 -0
  408. package/src/config/schemas/heartbeat.ts +51 -0
  409. package/src/config/schemas/inference.ts +136 -0
  410. package/src/config/schemas/ingress.ts +81 -0
  411. package/src/config/schemas/logging.ts +21 -0
  412. package/src/config/schemas/memory-lifecycle.ts +67 -0
  413. package/src/config/schemas/memory-processing.ts +215 -0
  414. package/src/config/schemas/memory-retrieval.ts +222 -0
  415. package/src/config/schemas/memory-storage.ts +83 -0
  416. package/src/config/schemas/memory.ts +58 -0
  417. package/src/config/schemas/platform.ts +64 -0
  418. package/src/config/schemas/security.ts +54 -0
  419. package/src/config/schemas/swarm.ts +50 -0
  420. package/src/config/schemas/timeouts.ts +47 -0
  421. package/src/config/{agent-schema.ts → schemas/workspace-git.ts} +0 -97
  422. package/src/config/skill-state.ts +3 -13
  423. package/src/config/skills.ts +233 -75
  424. package/src/config/types.ts +1 -20
  425. package/src/contacts/contact-store.ts +12 -49
  426. package/src/contacts/contacts-write.ts +1 -5
  427. package/src/contacts/index.ts +0 -2
  428. package/src/contacts/types.ts +0 -8
  429. package/src/context/window-manager.ts +73 -14
  430. package/src/daemon/assistant-attachments.ts +9 -0
  431. package/src/daemon/computer-use-session.ts +3 -3
  432. package/src/daemon/connection-policy.ts +6 -21
  433. package/src/daemon/context-overflow-policy.ts +1 -1
  434. package/src/daemon/daemon-control.ts +46 -54
  435. package/src/daemon/doordash-steps.ts +1 -1
  436. package/src/daemon/handlers/config-channels.ts +407 -71
  437. package/src/daemon/handlers/config-ingress.ts +17 -85
  438. package/src/daemon/handlers/config-model.ts +145 -123
  439. package/src/daemon/handlers/config-slack-channel.ts +43 -29
  440. package/src/daemon/handlers/config-telegram.ts +32 -27
  441. package/src/daemon/handlers/config-voice.ts +1 -4
  442. package/src/daemon/handlers/dictation.ts +11 -16
  443. package/src/daemon/handlers/identity.ts +5 -6
  444. package/src/daemon/handlers/pairing.ts +5 -13
  445. package/src/daemon/handlers/recording.ts +97 -199
  446. package/src/daemon/handlers/session-history.ts +110 -96
  447. package/src/daemon/handlers/session-user-message.ts +29 -57
  448. package/src/daemon/handlers/sessions.ts +240 -137
  449. package/src/daemon/handlers/shared.ts +62 -95
  450. package/src/daemon/handlers/skills.ts +492 -543
  451. package/src/daemon/lifecycle.ts +168 -55
  452. package/src/daemon/main.ts +1 -0
  453. package/src/daemon/{ipc-contract.ts → message-protocol.ts} +49 -49
  454. package/src/daemon/{ipc-contract → message-types}/computer-use.ts +0 -3
  455. package/src/daemon/{ipc-contract → message-types}/diagnostics.ts +0 -16
  456. package/src/daemon/{ipc-contract → message-types}/integrations.ts +29 -13
  457. package/src/daemon/{ipc-contract → message-types}/memory.ts +8 -0
  458. package/src/daemon/{ipc-contract → message-types}/notifications.ts +15 -1
  459. package/src/daemon/{ipc-contract → message-types}/sessions.ts +1 -0
  460. package/src/daemon/{ipc-contract → message-types}/shared.ts +0 -8
  461. package/src/daemon/{ipc-contract → message-types}/workspace.ts +2 -2
  462. package/src/daemon/providers-setup.ts +0 -5
  463. package/src/daemon/recording-executor.ts +0 -7
  464. package/src/daemon/ride-shotgun-handler.ts +9 -13
  465. package/src/daemon/server.ts +136 -510
  466. package/src/daemon/session-agent-loop-handlers.ts +22 -7
  467. package/src/daemon/session-agent-loop.ts +86 -24
  468. package/src/daemon/session-attachments.ts +1 -1
  469. package/src/daemon/session-error.ts +1 -1
  470. package/src/daemon/session-history.ts +20 -15
  471. package/src/daemon/session-lifecycle.ts +9 -7
  472. package/src/daemon/session-memory.ts +15 -1
  473. package/src/daemon/session-messaging.ts +10 -6
  474. package/src/daemon/session-notifiers.ts +10 -8
  475. package/src/daemon/session-process.ts +34 -25
  476. package/src/daemon/session-queue-manager.ts +1 -1
  477. package/src/daemon/session-runtime-assembly.ts +6 -25
  478. package/src/daemon/session-surfaces.ts +2 -2
  479. package/src/daemon/session-tool-setup.ts +1 -1
  480. package/src/daemon/session-usage.ts +119 -18
  481. package/src/daemon/session.ts +13 -9
  482. package/src/daemon/tool-side-effects.ts +6 -5
  483. package/src/daemon/trace-emitter.ts +1 -1
  484. package/src/daemon/{guardian-verification-intent.ts → verification-session-intent.ts} +16 -16
  485. package/src/daemon/watch-handler.ts +2 -5
  486. package/src/email/service.ts +8 -8
  487. package/src/events/domain-events.ts +0 -1
  488. package/src/events/tool-notification-listener.ts +1 -1
  489. package/src/followups/followup-store.ts +1 -2
  490. package/src/followups/types.ts +0 -6
  491. package/src/heartbeat/heartbeat-service.ts +1 -1
  492. package/src/inbound/platform-callback-registration.ts +1 -1
  493. package/src/inbound/public-ingress-urls.ts +0 -8
  494. package/src/index.ts +12 -0
  495. package/src/mcp/client.ts +1 -1
  496. package/src/mcp/manager.ts +1 -1
  497. package/src/memory/app-store.ts +1 -42
  498. package/src/memory/{guardian-verification.ts → channel-verification-sessions.ts} +110 -93
  499. package/src/memory/conversation-attention-store.ts +154 -0
  500. package/src/memory/conversation-bootstrap.ts +1 -1
  501. package/src/memory/conversation-crud.ts +53 -1
  502. package/src/memory/conversation-display-order-migration.ts +2 -3
  503. package/src/memory/conversation-queries.ts +1 -29
  504. package/src/memory/conversation-title-service.ts +26 -21
  505. package/src/memory/db-connection.ts +1 -8
  506. package/src/memory/db-init.ts +20 -0
  507. package/src/memory/delivery-crud.ts +4 -34
  508. package/src/memory/external-conversation-store.ts +1 -1
  509. package/src/memory/format-recall.ts +47 -0
  510. package/src/memory/guardian-action-store.ts +4 -5
  511. package/src/memory/guardian-rate-limits.ts +0 -3
  512. package/src/memory/invite-store.ts +1 -1
  513. package/src/memory/job-handlers/backfill.ts +9 -2
  514. package/src/memory/job-handlers/extraction.ts +2 -7
  515. package/src/memory/job-handlers/summarization.ts +1 -1
  516. package/src/memory/llm-usage-store.ts +11 -0
  517. package/src/memory/migrations/114-notifications.ts +12 -40
  518. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +357 -0
  519. package/src/memory/migrations/141-rename-verification-table.ts +55 -0
  520. package/src/memory/migrations/142-rename-verification-session-id-column.ts +32 -0
  521. package/src/memory/migrations/143-rename-guardian-verification-values.ts +48 -0
  522. package/src/memory/migrations/144-rename-voice-to-phone.ts +147 -0
  523. package/src/memory/migrations/index.ts +5 -0
  524. package/src/memory/migrations/registry.ts +30 -0
  525. package/src/memory/qdrant-circuit-breaker.ts +5 -0
  526. package/src/memory/retriever.test.ts +707 -0
  527. package/src/memory/retriever.ts +120 -116
  528. package/src/memory/schema/calls.ts +3 -7
  529. package/src/memory/schema/guardian.ts +2 -2
  530. package/src/memory/search/lexical.ts +4 -1
  531. package/src/memory/search/query-expansion.test.ts +70 -0
  532. package/src/memory/search/query-expansion.ts +118 -0
  533. package/src/memory/search/types.ts +18 -17
  534. package/src/messaging/providers/telegram-bot/adapter.ts +1 -1
  535. package/src/messaging/providers/whatsapp/adapter.ts +1 -4
  536. package/src/messaging/registry.ts +0 -1
  537. package/src/notifications/README.md +13 -22
  538. package/src/notifications/adapters/macos.ts +1 -1
  539. package/src/notifications/conversation-pairing.ts +2 -2
  540. package/src/notifications/copy-composer.ts +2 -2
  541. package/src/notifications/decision-engine.ts +1 -10
  542. package/src/notifications/destination-resolver.ts +2 -3
  543. package/src/notifications/emit-signal.ts +2 -8
  544. package/src/notifications/guardian-question-mode.ts +5 -8
  545. package/src/notifications/signal.ts +1 -2
  546. package/src/notifications/types.ts +1 -1
  547. package/src/oauth/token-persistence.ts +25 -1
  548. package/src/permissions/checker.ts +4 -29
  549. package/src/permissions/defaults.ts +6 -6
  550. package/src/permissions/prompter.ts +1 -1
  551. package/src/permissions/secret-prompter.ts +1 -1
  552. package/src/permissions/shell-identity.ts +1 -1
  553. package/src/permissions/trust-store.ts +13 -76
  554. package/src/permissions/workspace-policy.ts +1 -1
  555. package/src/{config → prompts}/computer-use-prompt.ts +1 -1
  556. package/src/{config → prompts}/system-prompt.ts +40 -21
  557. package/src/runtime/AGENTS.md +6 -8
  558. package/src/runtime/access-request-helper.ts +36 -55
  559. package/src/runtime/actor-trust-resolver.ts +1 -24
  560. package/src/runtime/approval-message-composer.ts +6 -2
  561. package/src/runtime/assistant-event.ts +1 -1
  562. package/src/runtime/auth/__tests__/ipc-auth-context.test.ts +1 -1
  563. package/src/runtime/auth/__tests__/subject.test.ts +32 -0
  564. package/src/runtime/auth/route-policy.ts +140 -24
  565. package/src/runtime/auth/subject.ts +9 -0
  566. package/src/runtime/auth/token-service.ts +11 -0
  567. package/src/runtime/auth/types.ts +1 -1
  568. package/src/runtime/channel-approval-types.ts +1 -1
  569. package/src/runtime/channel-approvals.ts +1 -1
  570. package/src/runtime/channel-invite-transport.ts +0 -2
  571. package/src/runtime/channel-invite-transports/slack.ts +5 -19
  572. package/src/runtime/channel-invite-transports/telegram.ts +17 -34
  573. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  574. package/src/runtime/channel-readiness-service.ts +24 -159
  575. package/src/runtime/channel-readiness-types.ts +5 -1
  576. package/src/runtime/channel-reply-delivery.ts +43 -3
  577. package/src/runtime/channel-retry-sweep.ts +14 -22
  578. package/src/runtime/{channel-guardian-service.ts → channel-verification-service.ts} +50 -53
  579. package/src/runtime/confirmation-request-guardian-bridge.ts +2 -3
  580. package/src/runtime/gateway-client.ts +12 -15
  581. package/src/runtime/guardian-action-followup-executor.ts +8 -73
  582. package/src/runtime/guardian-action-grant-minter.ts +45 -61
  583. package/src/runtime/guardian-action-message-composer.ts +4 -4
  584. package/src/runtime/guardian-reply-router.ts +3 -3
  585. package/src/runtime/http-server.ts +133 -24
  586. package/src/runtime/http-types.ts +34 -1
  587. package/src/runtime/invite-instruction-generator.ts +1 -3
  588. package/src/runtime/invite-redemption-service.ts +5 -5
  589. package/src/runtime/invite-service.ts +7 -7
  590. package/src/runtime/local-actor-identity.ts +28 -2
  591. package/src/runtime/local-gateway-health.ts +275 -0
  592. package/src/runtime/middleware/twilio-validation.ts +3 -3
  593. package/src/runtime/migrations/migration-transport.ts +18 -3
  594. package/src/runtime/migrations/rebind-secrets-screen.ts +2 -2
  595. package/src/runtime/nl-approval-parser.ts +2 -3
  596. package/src/runtime/routes/access-request-decision.ts +2 -2
  597. package/src/runtime/routes/app-management-routes.ts +921 -0
  598. package/src/runtime/routes/approval-routes.ts +76 -7
  599. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +38 -203
  600. package/src/runtime/routes/channel-delivery-routes.ts +5 -4
  601. package/src/runtime/routes/channel-route-shared.ts +1 -3
  602. package/src/runtime/routes/channel-routes.ts +1 -4
  603. package/src/runtime/routes/channel-verification-routes.ts +257 -0
  604. package/src/runtime/routes/computer-use-routes.ts +595 -0
  605. package/src/runtime/routes/contact-routes.ts +1 -317
  606. package/src/runtime/routes/conversation-attention-routes.ts +6 -5
  607. package/src/runtime/routes/conversation-routes.ts +11 -18
  608. package/src/runtime/routes/debug-routes.ts +1 -1
  609. package/src/runtime/routes/diagnostics-routes.ts +813 -0
  610. package/src/runtime/routes/documents-routes.ts +227 -0
  611. package/src/runtime/routes/guardian-approval-interception.ts +25 -48
  612. package/src/runtime/routes/guardian-bootstrap-routes.ts +3 -3
  613. package/src/runtime/routes/guardian-expiry-sweep.ts +2 -2
  614. package/src/runtime/routes/guardian-refresh-routes.ts +11 -6
  615. package/src/runtime/routes/inbound-conversation.ts +3 -10
  616. package/src/runtime/routes/inbound-message-handler.ts +7 -6
  617. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +22 -22
  618. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +44 -0
  619. package/src/runtime/routes/inbound-stages/background-dispatch.ts +140 -22
  620. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +4 -4
  621. package/src/runtime/routes/inbound-stages/edit-intercept.ts +5 -5
  622. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +3 -3
  623. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
  624. package/src/runtime/routes/inbound-stages/verification-intercept.ts +13 -14
  625. package/src/runtime/routes/integrations/slack/channel.ts +72 -0
  626. package/src/runtime/routes/{slack-share-routes.ts → integrations/slack/share.ts} +9 -9
  627. package/src/runtime/routes/integrations/telegram.ts +111 -0
  628. package/src/runtime/routes/integrations/twilio.ts +451 -0
  629. package/src/runtime/routes/invite-routes.ts +2 -2
  630. package/src/runtime/routes/pairing-routes.ts +1 -1
  631. package/src/runtime/routes/recording-routes.ts +332 -0
  632. package/src/{daemon/handlers/config-scheduling.ts → runtime/routes/schedule-routes.ts} +91 -106
  633. package/src/runtime/routes/session-management-routes.ts +167 -0
  634. package/src/runtime/routes/session-query-routes.ts +204 -0
  635. package/src/runtime/routes/settings-routes.ts +977 -0
  636. package/src/runtime/routes/skills-routes.ts +266 -0
  637. package/src/runtime/routes/subagents-routes.ts +246 -0
  638. package/src/runtime/routes/surface-action-routes.ts +100 -10
  639. package/src/runtime/routes/surface-content-routes.ts +1 -1
  640. package/src/runtime/routes/work-items-routes.ts +809 -0
  641. package/src/runtime/routes/workspace-routes.test.ts +778 -0
  642. package/src/runtime/routes/workspace-routes.ts +410 -0
  643. package/src/runtime/routes/workspace-utils.ts +88 -0
  644. package/src/runtime/telegram-streaming-delivery.test.ts +597 -0
  645. package/src/runtime/telegram-streaming-delivery.ts +380 -0
  646. package/src/runtime/tool-grant-request-helper.ts +1 -2
  647. package/src/runtime/trust-context-resolver.ts +0 -1
  648. package/src/runtime/{guardian-outbound-actions.ts → verification-outbound-actions.ts} +23 -188
  649. package/src/runtime/verification-rate-limiter.ts +2 -2
  650. package/src/runtime/{guardian-verification-templates.ts → verification-templates.ts} +2 -28
  651. package/src/schedule/integration-status.ts +2 -2
  652. package/src/schedule/schedule-store.ts +7 -9
  653. package/src/sequence/engine.ts +1 -1
  654. package/src/skills/active-skill-tools.ts +0 -8
  655. package/src/skills/clawhub.ts +1 -10
  656. package/src/skills/managed-store.ts +14 -4
  657. package/src/skills/slash-commands.ts +1 -1
  658. package/src/subagent/manager.ts +1 -1
  659. package/src/subagent/types.ts +1 -1
  660. package/src/tasks/SPEC.md +10 -10
  661. package/src/tasks/task-scheduler.ts +1 -1
  662. package/src/telegram/bot-username.ts +13 -0
  663. package/src/tools/assets/materialize.ts +1 -1
  664. package/src/tools/assets/search.ts +1 -1
  665. package/src/tools/browser/browser-execution.ts +2 -2
  666. package/src/tools/browser/browser-manager.ts +88 -11
  667. package/src/tools/browser/browser-screencast.ts +1 -1
  668. package/src/tools/browser/headless-browser.ts +0 -17
  669. package/src/tools/browser/jit-auth.ts +1 -1
  670. package/src/tools/browser/recording-store.ts +19 -1
  671. package/src/tools/browser/runtime-check.ts +4 -2
  672. package/src/tools/calls/call-start.ts +3 -3
  673. package/src/tools/credentials/metadata-store.ts +0 -13
  674. package/src/tools/credentials/vault.ts +7 -31
  675. package/src/tools/followups/followup_create.ts +0 -8
  676. package/src/tools/mcp/mcp-tool-factory.ts +1 -1
  677. package/src/tools/memory/definitions.ts +32 -10
  678. package/src/tools/memory/handlers.test.ts +573 -0
  679. package/src/tools/memory/handlers.ts +222 -65
  680. package/src/tools/memory/register.ts +53 -24
  681. package/src/tools/network/script-proxy/session-manager.ts +1 -12
  682. package/src/tools/schedule/update.ts +0 -8
  683. package/src/tools/skills/load.ts +3 -3
  684. package/src/tools/subagent/read.ts +1 -1
  685. package/src/tools/system/voice-config.ts +2 -14
  686. package/src/tools/terminal/safe-env.ts +5 -18
  687. package/src/tools/tool-approval-handler.ts +4 -4
  688. package/src/tools/tool-manifest.ts +4 -2
  689. package/src/tools/types.ts +1 -1
  690. package/src/tools/{guardian-control-plane-policy.ts → verification-control-plane-policy.ts} +37 -39
  691. package/src/twitter/platform-proxy-client.ts +405 -0
  692. package/src/usage/types.ts +21 -0
  693. package/src/util/canonicalize-identity.ts +2 -6
  694. package/src/util/cookie-session.ts +35 -51
  695. package/src/util/platform.ts +93 -86
  696. package/src/util/pricing.ts +180 -43
  697. package/src/work-items/work-item-runner.ts +1 -1
  698. package/scripts/ipc/check-contract-inventory.ts +0 -107
  699. package/scripts/ipc/check-swift-decoder-drift.ts +0 -184
  700. package/scripts/ipc/generate-swift.ts +0 -528
  701. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -3043
  702. package/src/__tests__/app-migration.test.ts +0 -148
  703. package/src/__tests__/config-loader-migration.test.ts +0 -85
  704. package/src/__tests__/daemon-lifecycle.test.ts +0 -715
  705. package/src/__tests__/daemon-server-session-init.test.ts +0 -864
  706. package/src/__tests__/guardian-actions-endpoint.test.ts +0 -1452
  707. package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +0 -228
  708. package/src/__tests__/handlers-cu-observation-blob.test.ts +0 -397
  709. package/src/__tests__/handlers-ipc-blob-probe.test.ts +0 -218
  710. package/src/__tests__/handlers-slack-config.test.ts +0 -140
  711. package/src/__tests__/handlers-telegram-config.test.ts +0 -1317
  712. package/src/__tests__/handlers-twitter-config.test.ts +0 -1145
  713. package/src/__tests__/ingress-reconcile.test.ts +0 -606
  714. package/src/__tests__/integrations-cli.test.ts +0 -232
  715. package/src/__tests__/ipc-blob-store.test.ts +0 -329
  716. package/src/__tests__/ipc-contract-inventory.test.ts +0 -69
  717. package/src/__tests__/ipc-contract.test.ts +0 -76
  718. package/src/__tests__/ipc-protocol.test.ts +0 -120
  719. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +0 -250
  720. package/src/__tests__/ipc-snapshot.test.ts +0 -2197
  721. package/src/__tests__/ipc-validate.test.ts +0 -471
  722. package/src/__tests__/migration-cli-flows.test.ts +0 -186
  723. package/src/__tests__/migration-ordering.test.ts +0 -267
  724. package/src/__tests__/oauth-connect-handler.test.ts +0 -361
  725. package/src/__tests__/platform-move-helper.test.ts +0 -108
  726. package/src/__tests__/platform-socket-path.test.ts +0 -52
  727. package/src/__tests__/platform-workspace-migration.test.ts +0 -1051
  728. package/src/__tests__/recording-intent-handler.test.ts +0 -1155
  729. package/src/__tests__/script-proxy-profile-template-fallback.test.ts +0 -127
  730. package/src/__tests__/sms-messaging-provider.test.ts +0 -156
  731. package/src/__tests__/tool-permission-simulate-handler.test.ts +0 -367
  732. package/src/__tests__/twitter-auth-handler.test.ts +0 -561
  733. package/src/__tests__/work-item-output.test.ts +0 -150
  734. package/src/amazon/session.ts +0 -58
  735. package/src/cli/channels.ts +0 -51
  736. package/src/cli/influencer.ts +0 -319
  737. package/src/cli/integrations.ts +0 -372
  738. package/src/cli/ipc-client.ts +0 -88
  739. package/src/config/bundled-skills/configure-settings/SKILL.md +0 -86
  740. package/src/config/bundled-skills/doordash/lib/shared/ipc.ts +0 -32
  741. package/src/config/bundled-skills/sms-setup/SKILL.md +0 -210
  742. package/src/config/core-schema.ts +0 -434
  743. package/src/config/memory-schema.ts +0 -617
  744. package/src/daemon/auth-manager.ts +0 -106
  745. package/src/daemon/handlers/apps.ts +0 -758
  746. package/src/daemon/handlers/avatar.ts +0 -73
  747. package/src/daemon/handlers/browser.ts +0 -3
  748. package/src/daemon/handlers/computer-use.ts +0 -231
  749. package/src/daemon/handlers/config-dispatch.ts +0 -29
  750. package/src/daemon/handlers/config-heartbeat.ts +0 -299
  751. package/src/daemon/handlers/config-inbox.ts +0 -457
  752. package/src/daemon/handlers/config-integrations.ts +0 -409
  753. package/src/daemon/handlers/config-platform.ts +0 -77
  754. package/src/daemon/handlers/config-slack.ts +0 -41
  755. package/src/daemon/handlers/config-tools.ts +0 -226
  756. package/src/daemon/handlers/config-trust.ts +0 -135
  757. package/src/daemon/handlers/config.ts +0 -64
  758. package/src/daemon/handlers/contacts.ts +0 -193
  759. package/src/daemon/handlers/diagnostics.ts +0 -382
  760. package/src/daemon/handlers/documents.ts +0 -188
  761. package/src/daemon/handlers/guardian-actions.ts +0 -82
  762. package/src/daemon/handlers/home-base.ts +0 -82
  763. package/src/daemon/handlers/index.ts +0 -222
  764. package/src/daemon/handlers/misc.ts +0 -1139
  765. package/src/daemon/handlers/navigate-settings.ts +0 -29
  766. package/src/daemon/handlers/oauth-connect.ts +0 -202
  767. package/src/daemon/handlers/open-bundle-handler.ts +0 -88
  768. package/src/daemon/handlers/publish.ts +0 -176
  769. package/src/daemon/handlers/signing.ts +0 -56
  770. package/src/daemon/handlers/subagents.ts +0 -286
  771. package/src/daemon/handlers/twitter-auth.ts +0 -220
  772. package/src/daemon/handlers/work-items.ts +0 -796
  773. package/src/daemon/handlers/workspace-files.ts +0 -84
  774. package/src/daemon/handlers.ts +0 -16
  775. package/src/daemon/ipc-blob-store.ts +0 -246
  776. package/src/daemon/ipc-contract-inventory.json +0 -348
  777. package/src/daemon/ipc-contract-inventory.ts +0 -202
  778. package/src/daemon/ipc-handler.ts +0 -120
  779. package/src/daemon/ipc-protocol.ts +0 -85
  780. package/src/daemon/ipc-validate.ts +0 -254
  781. package/src/memory/app-migration.ts +0 -114
  782. package/src/memory/channel-delivery-store.ts +0 -40
  783. package/src/memory/channel-guardian-store.ts +0 -83
  784. package/src/memory/conversation-store.ts +0 -102
  785. package/src/memory/schema-migration.ts +0 -38
  786. package/src/messaging/providers/sms/adapter.ts +0 -232
  787. package/src/messaging/providers/sms/client.ts +0 -93
  788. package/src/messaging/providers/sms/types.ts +0 -7
  789. package/src/migrations/config-merge.ts +0 -62
  790. package/src/migrations/data-layout.ts +0 -89
  791. package/src/migrations/data-merge.ts +0 -44
  792. package/src/migrations/hooks-merge.ts +0 -118
  793. package/src/migrations/index.ts +0 -6
  794. package/src/migrations/log.ts +0 -28
  795. package/src/migrations/skills-merge.ts +0 -44
  796. package/src/migrations/workspace-layout.ts +0 -94
  797. package/src/notifications/adapters/sms.ts +0 -94
  798. package/src/runtime/channel-approval-parser.ts +0 -123
  799. package/src/runtime/channel-invite-transports/sms.ts +0 -53
  800. package/src/runtime/routes/approval-strategies/guardian-legacy-fallback-strategy.ts +0 -82
  801. package/src/runtime/routes/integration-routes.ts +0 -381
  802. package/src/runtime/routes/twilio-routes.ts +0 -1251
  803. package/src/twitter/router.ts +0 -131
  804. package/src/twitter/session.ts +0 -54
  805. package/src/watcher/providers/slack.ts +0 -282
  806. /package/src/{amazon → cli/commands/amazon}/cart.ts +0 -0
  807. /package/src/{amazon → cli/commands/amazon}/checkout.ts +0 -0
  808. /package/src/{amazon → cli/commands/amazon}/product-details.ts +0 -0
  809. /package/src/{amazon → cli/commands/amazon}/search.ts +0 -0
  810. /package/src/{twitter → cli/commands/twitter}/oauth-client.ts +0 -0
  811. /package/src/config/{calls-schema.ts → schemas/calls.ts} +0 -0
  812. /package/src/config/{elevenlabs-schema.ts → schemas/elevenlabs.ts} +0 -0
  813. /package/src/config/{mcp-schema.ts → schemas/mcp.ts} +0 -0
  814. /package/src/config/{notifications-schema.ts → schemas/notifications.ts} +0 -0
  815. /package/src/config/{sandbox-schema.ts → schemas/sandbox.ts} +0 -0
  816. /package/src/config/{skills-schema.ts → schemas/skills.ts} +0 -0
  817. /package/src/daemon/{ipc-contract → message-types}/apps.ts +0 -0
  818. /package/src/daemon/{ipc-contract → message-types}/browser.ts +0 -0
  819. /package/src/daemon/{ipc-contract → message-types}/contacts.ts +0 -0
  820. /package/src/daemon/{ipc-contract → message-types}/documents.ts +0 -0
  821. /package/src/daemon/{ipc-contract → message-types}/guardian-actions.ts +0 -0
  822. /package/src/daemon/{ipc-contract → message-types}/inbox.ts +0 -0
  823. /package/src/daemon/{ipc-contract → message-types}/messages.ts +0 -0
  824. /package/src/daemon/{ipc-contract → message-types}/pairing.ts +0 -0
  825. /package/src/daemon/{ipc-contract → message-types}/schedules.ts +0 -0
  826. /package/src/daemon/{ipc-contract → message-types}/settings.ts +0 -0
  827. /package/src/daemon/{ipc-contract → message-types}/skills.ts +0 -0
  828. /package/src/daemon/{ipc-contract → message-types}/subagents.ts +0 -0
  829. /package/src/daemon/{ipc-contract → message-types}/surfaces.ts +0 -0
  830. /package/src/daemon/{ipc-contract → message-types}/trust.ts +0 -0
  831. /package/src/daemon/{ipc-contract → message-types}/work-items.ts +0 -0
  832. /package/src/{cli/email-guardrails.ts → email/guardrails.ts} +0 -0
  833. /package/src/{config → prompts}/__tests__/build-cli-reference-section.test.ts +0 -0
  834. /package/src/{config → prompts}/templates/BOOTSTRAP.md +0 -0
  835. /package/src/{config → prompts}/templates/IDENTITY.md +0 -0
  836. /package/src/{config → prompts}/templates/SOUL.md +0 -0
  837. /package/src/{config → prompts}/templates/UPDATES.md +0 -0
  838. /package/src/{config → prompts}/templates/USER.md +0 -0
  839. /package/src/{config → prompts}/update-bulletin-format.ts +0 -0
  840. /package/src/{config → prompts}/update-bulletin-state.ts +0 -0
  841. /package/src/{config → prompts}/update-bulletin-template-path.ts +0 -0
  842. /package/src/{config → prompts}/update-bulletin.ts +0 -0
  843. /package/src/{config → prompts}/user-reference.ts +0 -0
@@ -1,7 +1,5 @@
1
- import { chmodSync, existsSync, readFileSync, statSync } from "node:fs";
2
- import * as net from "node:net";
1
+ import { existsSync, readFileSync } from "node:fs";
3
2
  import { join } from "node:path";
4
- import * as tls from "node:tls";
5
3
 
6
4
  import {
7
5
  createAssistantMessage,
@@ -14,7 +12,6 @@ import {
14
12
  parseInterfaceId,
15
13
  } from "../channels/types.js";
16
14
  import { getConfig } from "../config/loader.js";
17
- import { buildSystemPrompt } from "../config/system-prompt.js";
18
15
  import { onContactChange } from "../contacts/contact-events.js";
19
16
  import type { HeartbeatService } from "../heartbeat/heartbeat-service.js";
20
17
  import { bootstrapHomeBaseAppLink } from "../home-base/bootstrap.js";
@@ -23,52 +20,44 @@ import {
23
20
  createCanonicalGuardianRequest,
24
21
  generateCanonicalRequestCode,
25
22
  } from "../memory/canonical-guardian-store.js";
26
- import * as conversationStore from "../memory/conversation-store.js";
27
- import { provenanceFromTrustContext } from "../memory/conversation-store.js";
23
+ import {
24
+ addMessage,
25
+ getConversationMemoryScopeId,
26
+ getConversationThreadType,
27
+ provenanceFromTrustContext,
28
+ setConversationOriginChannelIfUnset,
29
+ setConversationOriginInterfaceIfUnset,
30
+ } from "../memory/conversation-crud.js";
31
+ import { buildSystemPrompt } from "../prompts/system-prompt.js";
28
32
  import { RateLimitProvider } from "../providers/ratelimit.js";
29
33
  import {
30
34
  getFailoverProvider,
31
35
  initializeProviders,
32
36
  } from "../providers/registry.js";
37
+ import { buildAssistantEvent } from "../runtime/assistant-event.js";
38
+ import { assistantEventHub } from "../runtime/assistant-event-hub.js";
33
39
  import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
40
+ import { getSigningKeyFingerprint } from "../runtime/auth/token-service.js";
34
41
  import { bridgeConfirmationRequestToGuardian } from "../runtime/confirmation-request-guardian-bridge.js";
35
42
  import * as pendingInteractions from "../runtime/pending-interactions.js";
36
43
  import { checkIngressForSecrets } from "../security/secret-ingress.js";
37
44
  import { getSubagentManager } from "../subagent/index.js";
38
45
  import { IngressBlockedError } from "../util/errors.js";
39
46
  import { getLogger } from "../util/logger.js";
40
- import { getLocalIPv4 } from "../util/network-info.js";
41
47
  import {
42
48
  getSandboxWorkingDir,
43
- getSocketPath,
44
- getTCPHost,
45
- getTCPPort,
46
49
  getWorkspacePromptPath,
47
- isIOSPairingEnabled,
48
- isTCPEnabled,
49
- removeSocketFile,
50
50
  } from "../util/platform.js";
51
51
  import { registerDaemonCallbacks } from "../work-items/work-item-runner.js";
52
- import { AuthManager } from "./auth-manager.js";
53
52
  import { ComputerUseSession } from "./computer-use-session.js";
54
53
  import { ConfigWatcher } from "./config-watcher.js";
55
- import {
56
- handleMessage,
57
- type HandlerContext,
58
- type SessionCreateOptions,
59
- } from "./handlers.js";
60
54
  import { parseIdentityFields } from "./handlers/identity.js";
61
- import { cleanupRecordingsOnDisconnect } from "./handlers/recording.js";
62
- import { ensureBlobDir, sweepStaleBlobs } from "./ipc-blob-store.js";
63
- import { IpcSender } from "./ipc-handler.js";
64
- import {
65
- createMessageParser,
66
- MAX_LINE_SIZE,
67
- normalizeThreadType,
68
- serialize,
69
- type ServerMessage,
70
- } from "./ipc-protocol.js";
71
- import { validateClientMessage } from "./ipc-validate.js";
55
+ import type {
56
+ HandlerContext,
57
+ SessionCreateOptions,
58
+ } from "./handlers/shared.js";
59
+ import type { SkillOperationContext } from "./handlers/skills.js";
60
+ import type { ServerMessage } from "./message-protocol.js";
72
61
  import {
73
62
  DEFAULT_MEMORY_POLICY,
74
63
  Session,
@@ -77,7 +66,6 @@ import {
77
66
  import { SessionEvictor } from "./session-evictor.js";
78
67
  import { resolveChannelCapabilities } from "./session-runtime-assembly.js";
79
68
  import { resolveSlash } from "./session-slash.js";
80
- import { ensureTlsCert } from "./tls-certs.js";
81
69
 
82
70
  const log = getLogger("server");
83
71
 
@@ -132,7 +120,7 @@ function resolveTurnInterface(sourceInterface?: string): InterfaceId {
132
120
  function resolveCanonicalRequestSourceType(
133
121
  sourceChannel: string | undefined,
134
122
  ): "desktop" | "channel" | "voice" {
135
- if (sourceChannel === "voice") {
123
+ if (sourceChannel === "phone") {
136
124
  return "voice";
137
125
  }
138
126
  if (sourceChannel === "vellum") {
@@ -168,7 +156,7 @@ function makePendingInteractionRegistrar(
168
156
  },
169
157
  });
170
158
 
171
- // Create a canonical guardian request so IPC/HTTP handlers can find it
159
+ // Create a canonical guardian request so HTTP handlers can find it
172
160
  // via applyCanonicalGuardianDecision.
173
161
  try {
174
162
  const trustContext = session.trustContext;
@@ -217,29 +205,19 @@ function makePendingInteractionRegistrar(
217
205
  }
218
206
 
219
207
  export class DaemonServer {
220
- private server: net.Server | null = null;
221
- private tcpServer: tls.Server | null = null;
222
208
  private sessions = new Map<string, Session>();
223
- private socketToSession = new Map<net.Socket, string>();
224
209
  private cuSessions = new Map<string, ComputerUseSession>();
225
- private socketToCuSession = new Map<net.Socket, Set<string>>();
226
- private connectedSockets = new Set<net.Socket>();
227
- private socketSandboxOverride = new Map<net.Socket, boolean>();
228
210
  private cuObservationParseSequence = new Map<string, number>();
229
211
  private sessionOptions = new Map<string, SessionCreateOptions>();
230
212
  private sessionCreating = new Map<string, Promise<Session>>();
231
213
  private sharedRequestTimestamps: number[] = [];
232
- private socketPath: string;
233
214
  private httpPort: number | undefined;
234
- private blobSweepTimer: ReturnType<typeof setInterval> | null = null;
235
215
  private unsubscribeContactChange: (() => void) | null = null;
236
- private static readonly MAX_CONNECTIONS = 50;
237
216
  private evictor: SessionEvictor;
217
+ private _hubChain: Promise<void> = Promise.resolve();
238
218
 
239
219
  // Composed subsystems
240
- private auth = new AuthManager();
241
220
  private configWatcher = new ConfigWatcher();
242
- private ipc = new IpcSender();
243
221
 
244
222
  /**
245
223
  * Logical assistant identifier used when publishing to the assistant-events hub.
@@ -254,11 +232,10 @@ export class DaemonServer {
254
232
  }
255
233
 
256
234
  private deriveMemoryPolicy(conversationId: string): SessionMemoryPolicy {
257
- const threadType =
258
- conversationStore.getConversationThreadType(conversationId);
235
+ const threadType = getConversationThreadType(conversationId);
259
236
  if (threadType === "private") {
260
237
  return {
261
- scopeId: conversationStore.getConversationMemoryScopeId(conversationId),
238
+ scopeId: getConversationMemoryScopeId(conversationId),
262
239
  includeDefaultFallback: true,
263
240
  strictSideEffects: true,
264
241
  };
@@ -279,7 +256,6 @@ export class DaemonServer {
279
256
  }
280
257
 
281
258
  constructor() {
282
- this.socketPath = getSocketPath();
283
259
  this.evictor = new SessionEvictor(this.sessions);
284
260
  getSubagentManager().sharedRequestTimestamps = this.sharedRequestTimestamps;
285
261
  this.evictor.onEvict = (sessionId: string) => {
@@ -342,20 +318,32 @@ export class DaemonServer {
342
318
  };
343
319
  }
344
320
 
345
- // ── Send / Broadcast wrappers ───────────────────────────────────────
321
+ // ── Broadcast / Event publishing ──────────────────────────────────
346
322
 
347
- private send(socket: net.Socket, msg: ServerMessage): void {
348
- this.ipc.send(socket, msg, this.socketToSession, this.assistantId);
323
+ /**
324
+ * Publish `msg` as an `AssistantEvent` to the process-level hub.
325
+ * Publications are serialized via a promise chain so subscribers
326
+ * always observe events in send order.
327
+ */
328
+ private publishAssistantEvent(
329
+ msg: ServerMessage,
330
+ sessionId?: string,
331
+ ): void {
332
+ const id = this.assistantId ?? "default";
333
+ const event = buildAssistantEvent(id, msg, sessionId);
334
+ this._hubChain = this._hubChain
335
+ .then(() => assistantEventHub.publish(event))
336
+ .catch((err: unknown) => {
337
+ log.warn(
338
+ { err },
339
+ "assistant-events hub subscriber threw during broadcast",
340
+ );
341
+ });
349
342
  }
350
343
 
351
- broadcast(msg: ServerMessage, excludeSocket?: net.Socket): void {
352
- this.ipc.broadcast(
353
- this.auth.getAuthenticatedSockets(),
354
- msg,
355
- this.socketToSession,
356
- this.assistantId,
357
- excludeSocket,
358
- );
344
+ broadcast(msg: ServerMessage): void {
345
+ const sessionId = extractSessionId(msg);
346
+ this.publishAssistantEvent(msg, sessionId);
359
347
  }
360
348
 
361
349
  private broadcastIdentityChanged(): void {
@@ -381,8 +369,6 @@ export class DaemonServer {
381
369
  // ── Server lifecycle ────────────────────────────────────────────────
382
370
 
383
371
  async start(): Promise<void> {
384
- removeSocketFile(this.socketPath);
385
-
386
372
  const config = getConfig();
387
373
  initializeProviders(config);
388
374
  this.configWatcher.initFingerprint(config);
@@ -404,16 +390,6 @@ export class DaemonServer {
404
390
  broadcast: (msg) => this.broadcast(msg),
405
391
  });
406
392
 
407
- ensureBlobDir();
408
- this.blobSweepTimer = setInterval(
409
- () => {
410
- sweepStaleBlobs(30 * 60 * 1000).catch((err) => {
411
- log.warn({ err }, "Blob sweep failed");
412
- });
413
- },
414
- 5 * 60 * 1000,
415
- );
416
-
417
393
  this.configWatcher.start(
418
394
  () => this.evictSessionsForReload(),
419
395
  () => this.broadcastIdentityChanged(),
@@ -424,140 +400,17 @@ export class DaemonServer {
424
400
  this.broadcast({ type: "contacts_changed" });
425
401
  });
426
402
 
427
- this.auth.initToken();
428
-
429
- let tlsCreds: { cert: string; key: string; fingerprint: string } | null =
430
- null;
431
- if (isTCPEnabled()) {
432
- try {
433
- tlsCreds = await ensureTlsCert();
434
- } catch (err) {
435
- log.error(
436
- { err },
437
- "Failed to generate TLS certificate — TCP listener will not start",
438
- );
439
- }
440
- }
441
-
442
- return new Promise((resolve, reject) => {
443
- this.server = net.createServer((socket) => {
444
- this.handleConnection(socket);
445
- });
446
-
447
- const oldUmask = process.umask(0o177);
448
-
449
- this.server.once("error", (err) => {
450
- process.umask(oldUmask);
451
- log.error(
452
- { err, socketPath: this.socketPath },
453
- "Server failed to start (is another daemon already running?)",
454
- );
455
- reject(err);
456
- });
457
-
458
- this.server.listen(this.socketPath, () => {
459
- process.umask(oldUmask);
460
- this.server!.removeAllListeners("error");
461
- this.server!.on("error", (err) => {
462
- log.error(
463
- { err, socketPath: this.socketPath },
464
- "Server socket error while running",
465
- );
466
- });
467
- chmodSync(this.socketPath, 0o600);
468
- // Validate the chmod actually took effect — some filesystems
469
- // (e.g. FAT32 mounts, container overlays) silently ignore chmod.
470
- const socketStat = statSync(this.socketPath);
471
- if ((socketStat.mode & 0o077) !== 0) {
472
- const actual = "0o" + (socketStat.mode & 0o777).toString(8);
473
- log.error(
474
- { socketPath: this.socketPath, mode: actual },
475
- "IPC socket is accessible by other users (expected 0600) — filesystem may not support Unix permissions",
476
- );
477
- }
478
- log.info({ socketPath: this.socketPath }, "Daemon server listening");
479
-
480
- if (tlsCreds) {
481
- const tcpPort = getTCPPort();
482
- const tcpHost = getTCPHost();
483
- this.tcpServer = tls.createServer(
484
- { cert: tlsCreds.cert, key: tlsCreds.key },
485
- (socket) => {
486
- this.handleConnection(socket);
487
- },
488
- );
489
- this.tcpServer.on("error", (err) => {
490
- log.error({ err, tcpPort }, "TLS TCP server error");
491
- });
492
- const fingerprint = tlsCreds.fingerprint;
493
- this.tcpServer.listen(tcpPort, tcpHost, () => {
494
- const localIP = getLocalIPv4();
495
- log.info(
496
- {
497
- tcpPort,
498
- tcpHost,
499
- fingerprint,
500
- localIP,
501
- iosPairing: isIOSPairingEnabled(),
502
- },
503
- "TLS TCP listener started",
504
- );
505
- if (isIOSPairingEnabled() && localIP) {
506
- log.warn(
507
- { localIP, tcpPort },
508
- "iOS pairing enabled — daemon is reachable on the local network at %s:%d",
509
- localIP,
510
- tcpPort,
511
- );
512
- }
513
- });
514
- }
515
-
516
- resolve();
517
- });
518
- });
403
+ log.info("DaemonServer started (HTTP-only mode)");
519
404
  }
520
405
 
521
406
  async stop(): Promise<void> {
522
407
  getSubagentManager().disposeAll();
523
408
  this.evictor.stop();
524
- if (this.blobSweepTimer) {
525
- clearInterval(this.blobSweepTimer);
526
- this.blobSweepTimer = null;
527
- }
528
409
  this.configWatcher.stop();
529
410
  if (this.unsubscribeContactChange) {
530
411
  this.unsubscribeContactChange();
531
412
  this.unsubscribeContactChange = null;
532
413
  }
533
- this.auth.cleanupAll();
534
-
535
- const serverClosed = new Promise<void>((resolve) => {
536
- if (this.server) {
537
- this.server.close(() => {
538
- try {
539
- removeSocketFile(this.socketPath);
540
- } catch (err) {
541
- log.warn(
542
- { err, socketPath: this.socketPath },
543
- "Failed to remove socket file during shutdown",
544
- );
545
- }
546
- resolve();
547
- });
548
- } else {
549
- resolve();
550
- }
551
- });
552
-
553
- const tcpServerClosed = new Promise<void>((resolve) => {
554
- if (this.tcpServer) {
555
- this.tcpServer.close(() => resolve());
556
- this.tcpServer = null;
557
- } else {
558
- resolve();
559
- }
560
- });
561
414
 
562
415
  for (const session of this.sessions.values()) {
563
416
  session.dispose();
@@ -568,225 +421,10 @@ export class DaemonServer {
568
421
  cuSession.abort();
569
422
  }
570
423
  this.cuSessions.clear();
571
- this.socketToCuSession.clear();
572
424
 
573
- for (const socket of this.connectedSockets) {
574
- socket.destroy();
575
- }
576
- this.connectedSockets.clear();
577
- this.socketToSession.clear();
578
- this.socketSandboxOverride.clear();
579
- this.cuObservationParseSequence.clear();
580
-
581
- await Promise.all([serverClosed, tcpServerClosed]);
582
425
  log.info("Daemon server stopped");
583
426
  }
584
427
 
585
- // ── Connection handling ─────────────────────────────────────────────
586
-
587
- private handleConnection(socket: net.Socket): void {
588
- if (this.connectedSockets.size >= DaemonServer.MAX_CONNECTIONS) {
589
- log.warn(
590
- {
591
- current: this.connectedSockets.size,
592
- max: DaemonServer.MAX_CONNECTIONS,
593
- },
594
- "Connection limit reached, rejecting client",
595
- );
596
- socket.once("error", (err) => {
597
- log.error({ err }, "Socket error while rejecting connection");
598
- });
599
- socket.write(
600
- serialize({
601
- type: "error",
602
- message: `Connection limit reached (max ${DaemonServer.MAX_CONNECTIONS})`,
603
- }),
604
- );
605
- socket.destroy();
606
- return;
607
- }
608
-
609
- log.info("Client connected");
610
- this.connectedSockets.add(socket);
611
- const parser = createMessageParser({ maxLineSize: MAX_LINE_SIZE });
612
-
613
- if (this.auth.shouldAutoAuth()) {
614
- this.auth.markAuthenticated(socket);
615
- log.warn(
616
- "Auto-authenticated client (VELLUM_DAEMON_NOAUTH is set — token auth bypassed)",
617
- );
618
- this.send(socket, { type: "auth_result", success: true });
619
- this.sendInitialSession(socket).catch((err) => {
620
- log.error(
621
- { err },
622
- "Failed to send initial session info after auto-auth",
623
- );
624
- });
625
- }
626
-
627
- this.auth.startTimeout(socket, () => {
628
- this.send(socket, { type: "error", message: "Authentication timeout" });
629
- socket.destroy();
630
- });
631
-
632
- socket.on("data", (data) => {
633
- const chunkReceivedAtMs = Date.now();
634
- const parseStartNs = process.hrtime.bigint();
635
- let parsed;
636
- try {
637
- parsed = parser.feedRaw(data.toString());
638
- } catch (err) {
639
- log.error(
640
- { err },
641
- "IPC parse error (malformed JSON or message exceeded size limit), dropping client",
642
- );
643
- socket.write(
644
- serialize({
645
- type: "error",
646
- message: `IPC parse error: ${(err as Error).message}`,
647
- }),
648
- );
649
- socket.destroy();
650
- return;
651
- }
652
- const parsedAtMs = Date.now();
653
- const parseDurationMs =
654
- Number(process.hrtime.bigint() - parseStartNs) / 1_000_000;
655
- for (const entry of parsed) {
656
- const msg = entry.msg;
657
- if (
658
- typeof msg === "object" &&
659
- msg != null &&
660
- (msg as { type?: unknown }).type === "cu_observation"
661
- ) {
662
- const maybeSessionId = (msg as { sessionId?: unknown }).sessionId;
663
- const sessionId =
664
- typeof maybeSessionId === "string" ? maybeSessionId : "unknown";
665
- const previousSequence =
666
- this.cuObservationParseSequence.get(sessionId) ?? 0;
667
- const sequence = previousSequence + 1;
668
- this.cuObservationParseSequence.set(sessionId, sequence);
669
- log.info(
670
- {
671
- sessionId,
672
- sequence,
673
- chunkReceivedAtMs,
674
- parsedAtMs,
675
- parseDurationMs,
676
- messageBytes: entry.rawByteLength,
677
- },
678
- "IPC_METRIC cu_observation_parse",
679
- );
680
- }
681
- const result = validateClientMessage(msg);
682
- if (!result.valid) {
683
- log.warn(
684
- { reason: result.reason },
685
- "Invalid IPC message, dropping client",
686
- );
687
- socket.write(
688
- serialize({
689
- type: "error",
690
- message: `Invalid message: ${result.reason}`,
691
- }),
692
- );
693
- socket.destroy();
694
- return;
695
- }
696
-
697
- // Auth gate
698
- if (!this.auth.isAuthenticated(socket)) {
699
- this.auth.clearTimeout(socket);
700
-
701
- if (result.message.type === "auth") {
702
- const authMsg = result.message as { type: "auth"; token: string };
703
- if (this.auth.authenticate(socket, authMsg.token)) {
704
- this.send(socket, { type: "auth_result", success: true });
705
- this.sendInitialSession(socket).catch((err) => {
706
- log.error(
707
- { err },
708
- "Failed to send initial session info after auth",
709
- );
710
- });
711
- } else {
712
- this.send(socket, {
713
- type: "auth_result",
714
- success: false,
715
- message: "Invalid token",
716
- });
717
- socket.destroy();
718
- }
719
- continue;
720
- }
721
-
722
- log.warn(
723
- { type: result.message.type },
724
- "Unauthenticated client sent non-auth message, disconnecting",
725
- );
726
- this.send(socket, {
727
- type: "error",
728
- message: "Authentication required",
729
- });
730
- socket.destroy();
731
- return;
732
- }
733
-
734
- // Already-authenticated socket sending auth (e.g. auto-auth'd + local token)
735
- if (result.message.type === "auth") {
736
- this.send(socket, { type: "auth_result", success: true });
737
- continue;
738
- }
739
-
740
- this.dispatchMessage(result.message, socket);
741
- }
742
- });
743
-
744
- socket.on("close", () => {
745
- this.auth.cleanupSocket(socket);
746
- this.connectedSockets.delete(socket);
747
- this.socketSandboxOverride.delete(socket);
748
- const sessionId = this.socketToSession.get(socket);
749
- if (sessionId) {
750
- const session = this.sessions.get(sessionId);
751
- if (session) {
752
- session.abort();
753
- }
754
- getSubagentManager().abortAllForParent(sessionId);
755
- }
756
- // Clean up recording state for recordings whose owning conversation is
757
- // bound to the disconnecting socket. Runs outside the sessionId check
758
- // because recordings may be keyed to a different conversation than the
759
- // socket's current session.
760
- cleanupRecordingsOnDisconnect(socket, (convId) => {
761
- for (const [s, sid] of this.socketToSession.entries()) {
762
- if (sid === convId) return s;
763
- }
764
- return undefined;
765
- });
766
- this.socketToSession.delete(socket);
767
- const cuSessionIds = this.socketToCuSession.get(socket);
768
- if (cuSessionIds) {
769
- for (const cuSessionId of cuSessionIds) {
770
- this.cuObservationParseSequence.delete(cuSessionId);
771
- const cuSession = this.cuSessions.get(cuSessionId);
772
- if (cuSession) {
773
- cuSession.abort();
774
- this.cuSessions.delete(cuSessionId);
775
- }
776
- }
777
- }
778
- this.socketToCuSession.delete(socket);
779
- log.info("Client disconnected");
780
- });
781
-
782
- socket.on("error", (err) => {
783
- log.error(
784
- { err, remoteAddress: socket.remoteAddress },
785
- "Client socket error",
786
- );
787
- });
788
- }
789
-
790
428
  // ── Session management ──────────────────────────────────────────────
791
429
 
792
430
  setHttpPort(port: number): void {
@@ -795,6 +433,7 @@ export class DaemonServer {
795
433
  type: "daemon_status",
796
434
  httpPort: port,
797
435
  version: daemonVersion,
436
+ keyFingerprint: getSigningKeyFingerprint(),
798
437
  });
799
438
  }
800
439
 
@@ -841,49 +480,12 @@ export class DaemonServer {
841
480
  return changed;
842
481
  }
843
482
 
844
- private async sendInitialSession(socket: net.Socket): Promise<void> {
845
- const conversation = conversationStore.getLatestConversation();
846
- if (!conversation) {
847
- this.send(socket, {
848
- type: "daemon_status",
849
- httpPort: this.httpPort,
850
- version: daemonVersion,
851
- });
852
- return;
853
- }
854
-
855
- await this.getOrCreateSession(conversation.id, undefined, false);
856
-
857
- this.send(socket, {
858
- type: "session_info",
859
- sessionId: conversation.id,
860
- title: conversation.title ?? "New Conversation",
861
- threadType: normalizeThreadType(conversation.threadType),
862
- });
863
-
864
- this.send(socket, {
865
- type: "daemon_status",
866
- httpPort: this.httpPort,
867
- version: daemonVersion,
868
- });
869
- }
870
-
871
483
  private async getOrCreateSession(
872
484
  conversationId: string,
873
- socket?: net.Socket,
874
- rebindClient = true,
875
485
  options?: SessionCreateOptions,
876
486
  ): Promise<Session> {
877
487
  let session = this.sessions.get(conversationId);
878
- const sendToClient = socket
879
- ? (msg: ServerMessage) => this.send(socket, msg)
880
- : () => {};
881
- const maybeBindClient = (target: Session): void => {
882
- if (!rebindClient || !socket) return;
883
- target.updateClient(sendToClient);
884
- target.setSandboxOverride(this.socketSandboxOverride.get(socket));
885
- getSubagentManager().updateParentSender(conversationId, sendToClient);
886
- };
488
+ const sendToClient = () => {};
887
489
 
888
490
  if (options && Object.values(options).some((v) => v !== undefined)) {
889
491
  this.sessionOptions.set(conversationId, {
@@ -901,7 +503,6 @@ export class DaemonServer {
901
503
  const pending = this.sessionCreating.get(conversationId);
902
504
  if (pending) {
903
505
  session = await pending;
904
- maybeBindClient(session);
905
506
  return session;
906
507
  }
907
508
 
@@ -936,19 +537,14 @@ export class DaemonServer {
936
537
  provider,
937
538
  systemPrompt,
938
539
  maxTokens,
939
- rebindClient ? sendToClient : () => {},
540
+ sendToClient,
940
541
  workingDir,
941
- (msg) => this.broadcast(msg, socket),
542
+ (msg) => this.broadcast(msg),
942
543
  memoryPolicy,
943
544
  );
944
- if (!socket) {
945
- newSession.updateClient(sendToClient, true);
946
- }
545
+ newSession.updateClient(sendToClient, true);
947
546
  await newSession.loadFromDb();
948
547
  this.applyTransportMetadata(newSession, storedOptions);
949
- if (rebindClient && socket) {
950
- newSession.setSandboxOverride(this.socketSandboxOverride.get(socket));
951
- }
952
548
  this.sessions.set(conversationId, newSession);
953
549
  return newSession;
954
550
  })();
@@ -961,23 +557,19 @@ export class DaemonServer {
961
557
  }
962
558
  this.evictor.touch(conversationId);
963
559
  } else {
964
- maybeBindClient(session);
965
560
  this.applyTransportMetadata(session, options);
966
561
  this.evictor.touch(conversationId);
967
562
  }
968
563
  return session;
969
564
  }
970
565
 
971
- // ── Message dispatch ────────────────────────────────────────────────
566
+ // ── Handler context ────────────────────────────────────────────────
972
567
 
973
568
  private handlerContext(): HandlerContext {
974
569
  return {
975
570
  sessions: this.sessions,
976
- socketToSession: this.socketToSession,
977
571
  cuSessions: this.cuSessions,
978
- socketToCuSession: this.socketToCuSession,
979
572
  cuObservationParseSequence: this.cuObservationParseSequence,
980
- socketSandboxOverride: this.socketSandboxOverride,
981
573
  sharedRequestTimestamps: this.sharedRequestTimestamps,
982
574
  debounceTimers: this.configWatcher.timers,
983
575
  suppressConfigReload: this.configWatcher.suppressConfigReload,
@@ -987,39 +579,28 @@ export class DaemonServer {
987
579
  updateConfigFingerprint: () => {
988
580
  this.configWatcher.updateFingerprint();
989
581
  },
990
- send: (socket, msg) => this.send(socket, msg),
582
+ send: (msg) => this.broadcast(msg),
991
583
  broadcast: (msg) => this.broadcast(msg),
992
584
  clearAllSessions: () => this.clearAllSessions(),
993
- getOrCreateSession: (id, socket?, rebind?, options?) =>
994
- this.getOrCreateSession(id, socket, rebind, options),
585
+ getOrCreateSession: (id, options?) =>
586
+ this.getOrCreateSession(id, options),
995
587
  touchSession: (id) => this.evictor.touch(id),
996
588
  heartbeatService: this._heartbeatService,
997
589
  };
998
590
  }
999
591
 
1000
- private dispatchMessage(
1001
- msg: Parameters<typeof handleMessage>[0],
1002
- socket: net.Socket,
1003
- ): void {
1004
- if (msg.type !== "ping") {
1005
- const now = Date.now();
1006
- if (
1007
- now - this.configWatcher.lastConfigRefreshTime >=
1008
- ConfigWatcher.REFRESH_INTERVAL_MS
1009
- ) {
1010
- try {
1011
- const changed = this.configWatcher.refreshConfigFromSources();
1012
- if (changed) this.evictSessionsForReload();
1013
- this.configWatcher.lastConfigRefreshTime = now;
1014
- } catch (err) {
1015
- log.warn(
1016
- { err },
1017
- "Failed to refresh config from secure sources before handling IPC message",
1018
- );
1019
- }
1020
- }
1021
- }
1022
- handleMessage(msg, socket, this.handlerContext());
592
+ /** Public subset of handler context for skill management HTTP routes. */
593
+ getSkillContext(): SkillOperationContext {
594
+ return {
595
+ debounceTimers: this.configWatcher.timers,
596
+ setSuppressConfigReload: (value: boolean) => {
597
+ this.configWatcher.suppressConfigReload = value;
598
+ },
599
+ updateConfigFingerprint: () => {
600
+ this.configWatcher.updateFingerprint();
601
+ },
602
+ broadcast: (msg) => this.broadcast(msg),
603
+ };
1023
604
  }
1024
605
 
1025
606
  // ── HTTP message processing ─────────────────────────────────────────
@@ -1050,8 +631,6 @@ export class DaemonServer {
1050
631
 
1051
632
  const session = await this.getOrCreateSession(
1052
633
  conversationId,
1053
- undefined,
1054
- true,
1055
634
  options,
1056
635
  );
1057
636
 
@@ -1121,12 +700,21 @@ export class DaemonServer {
1121
700
 
1122
701
  // Register pending interactions so channel approval interception can
1123
702
  // find the session by requestId when confirmation/secret events fire.
1124
- const onEvent = makePendingInteractionRegistrar(session, conversationId);
703
+ const registrar = makePendingInteractionRegistrar(session, conversationId);
704
+ const onEvent = options?.onEvent
705
+ ? (msg: ServerMessage) => {
706
+ registrar(msg);
707
+ try {
708
+ options.onEvent!(msg);
709
+ } catch (err) {
710
+ log.error(
711
+ { err, conversationId },
712
+ "onEvent callback failed; continuing agent loop",
713
+ );
714
+ }
715
+ }
716
+ : registrar;
1125
717
  if (options?.isInteractive === true) {
1126
- // Interactive HTTP paths (e.g. channel ingress) still run without an IPC
1127
- // socket. Route prompter events through the registrar callback so
1128
- // confirmation_request/secret_request events are tracked, and mark the
1129
- // session interactive so prompt decisions are not auto-denied.
1130
718
  session.updateClient(onEvent, false);
1131
719
  }
1132
720
 
@@ -1136,8 +724,6 @@ export class DaemonServer {
1136
724
  isUserMessage: true,
1137
725
  })
1138
726
  .finally(() => {
1139
- // Only reset if no other caller (e.g. a real IPC client) has rebound
1140
- // the session's sender while the agent loop was running.
1141
727
  if (
1142
728
  options?.isInteractive === true &&
1143
729
  session.getCurrentSender() === onEvent
@@ -1192,7 +778,7 @@ export class DaemonServer {
1192
778
  : {}),
1193
779
  };
1194
780
  const userMsg = createUserMessage(content, attachments);
1195
- const persisted = await conversationStore.addMessage(
781
+ const persisted = await addMessage(
1196
782
  conversationId,
1197
783
  "user",
1198
784
  JSON.stringify(userMsg.content),
@@ -1202,7 +788,7 @@ export class DaemonServer {
1202
788
 
1203
789
  if (serverTurnCtx) {
1204
790
  try {
1205
- conversationStore.setConversationOriginChannelIfUnset(
791
+ setConversationOriginChannelIfUnset(
1206
792
  conversationId,
1207
793
  serverTurnCtx.userMessageChannel,
1208
794
  );
@@ -1215,7 +801,7 @@ export class DaemonServer {
1215
801
  }
1216
802
  if (serverInterfaceCtx) {
1217
803
  try {
1218
- conversationStore.setConversationOriginInterfaceIfUnset(
804
+ setConversationOriginInterfaceIfUnset(
1219
805
  conversationId,
1220
806
  serverInterfaceCtx.userMessageInterface,
1221
807
  );
@@ -1228,7 +814,7 @@ export class DaemonServer {
1228
814
  }
1229
815
 
1230
816
  const assistantMsg = createAssistantMessage(slashResult.message);
1231
- await conversationStore.addMessage(
817
+ await addMessage(
1232
818
  conversationId,
1233
819
  "assistant",
1234
820
  JSON.stringify(assistantMsg.content),
@@ -1259,12 +845,21 @@ export class DaemonServer {
1259
845
 
1260
846
  // Register pending interactions so channel approval interception can
1261
847
  // find the session by requestId when confirmation/secret events fire.
1262
- const onEvent = makePendingInteractionRegistrar(session, conversationId);
848
+ const registrar = makePendingInteractionRegistrar(session, conversationId);
849
+ const onEvent = options?.onEvent
850
+ ? (msg: ServerMessage) => {
851
+ registrar(msg);
852
+ try {
853
+ options.onEvent!(msg);
854
+ } catch (err) {
855
+ log.error(
856
+ { err, conversationId },
857
+ "onEvent callback failed; continuing agent loop",
858
+ );
859
+ }
860
+ }
861
+ : registrar;
1263
862
  if (options?.isInteractive === true) {
1264
- // Interactive HTTP paths (e.g. channel ingress) still run without an IPC
1265
- // socket. Route prompter events through the registrar callback so
1266
- // confirmation_request/secret_request events are tracked, and mark the
1267
- // session interactive so prompt decisions are not auto-denied.
1268
863
  session.updateClient(onEvent, false);
1269
864
  }
1270
865
 
@@ -1274,8 +869,6 @@ export class DaemonServer {
1274
869
  isUserMessage: true,
1275
870
  });
1276
871
  } finally {
1277
- // Only reset if no other caller (e.g. a real IPC client) has rebound
1278
- // the session's sender while the agent loop was running.
1279
872
  if (
1280
873
  options?.isInteractive === true &&
1281
874
  session.getCurrentSender() === onEvent
@@ -1292,15 +885,48 @@ export class DaemonServer {
1292
885
  * The handler manages busy-state checking and queueing itself.
1293
886
  */
1294
887
  async getSessionForMessages(conversationId: string): Promise<Session> {
1295
- return this.getOrCreateSession(conversationId, undefined, true);
888
+ return this.getOrCreateSession(conversationId);
1296
889
  }
1297
890
 
1298
891
  /**
1299
892
  * Look up an active session by ID without creating one.
1300
893
  * Checks both normal sessions and computer-use sessions so the HTTP
1301
- * surface-action path is consistent with IPC dispatch.
894
+ * surface-action path is consistent with dispatch.
1302
895
  */
1303
896
  findSession(sessionId: string): Session | ComputerUseSession | undefined {
1304
897
  return this.cuSessions.get(sessionId) ?? this.sessions.get(sessionId);
1305
898
  }
899
+
900
+ /**
901
+ * Look up an active session that owns a given surfaceId.
902
+ * Falls back across both normal and computer-use sessions.
903
+ */
904
+ findSessionBySurfaceId(
905
+ surfaceId: string,
906
+ ): Session | ComputerUseSession | undefined {
907
+ for (const s of this.cuSessions.values()) {
908
+ if (s.surfaceState.has(surfaceId)) return s;
909
+ }
910
+ for (const s of this.sessions.values()) {
911
+ if (s.surfaceState.has(surfaceId)) return s;
912
+ }
913
+ return undefined;
914
+ }
915
+
916
+ /**
917
+ * Expose the handler context for use by session management HTTP routes.
918
+ * The context is built on-the-fly so it always reflects the current server state.
919
+ */
920
+ getHandlerContext(): HandlerContext {
921
+ return this.handlerContext();
922
+ }
923
+ }
924
+
925
+ /** Extract sessionId from a ServerMessage if present. */
926
+ function extractSessionId(msg: ServerMessage): string | undefined {
927
+ const record = msg as unknown as Record<string, unknown>;
928
+ if ("sessionId" in msg && typeof record.sessionId === "string") {
929
+ return record.sessionId as string;
930
+ }
931
+ return undefined;
1306
932
  }