@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
@@ -18,15 +18,9 @@ mock.module("../util/logger.js", () => ({
18
18
  }),
19
19
  }));
20
20
 
21
- import { ScaffoldManagedSkillTool } from "../tools/skills/scaffold-managed.js";
21
+ import { executeScaffoldManagedSkill } from "../tools/skills/scaffold-managed.js";
22
22
  import type { ToolContext } from "../tools/types.js";
23
23
 
24
- // Use internal class directly to avoid registry side effects
25
-
26
- const tool = new (ScaffoldManagedSkillTool as any)() as InstanceType<
27
- typeof ScaffoldManagedSkillTool
28
- >;
29
-
30
24
  function makeContext(): ToolContext {
31
25
  return {
32
26
  workingDir: "/tmp",
@@ -47,7 +41,7 @@ afterEach(() => {
47
41
 
48
42
  describe("scaffold_managed_skill tool", () => {
49
43
  test("creates a valid skill and index entry", async () => {
50
- const result = await tool.execute(
44
+ const result = await executeScaffoldManagedSkill(
51
45
  {
52
46
  skill_id: "test-skill",
53
47
  name: "Test Skill",
@@ -76,7 +70,7 @@ describe("scaffold_managed_skill tool", () => {
76
70
  });
77
71
 
78
72
  test("rejects duplicate unless overwrite=true", async () => {
79
- await tool.execute(
73
+ await executeScaffoldManagedSkill(
80
74
  {
81
75
  skill_id: "dupe",
82
76
  name: "Original",
@@ -86,7 +80,7 @@ describe("scaffold_managed_skill tool", () => {
86
80
  makeContext(),
87
81
  );
88
82
 
89
- const result2 = await tool.execute(
83
+ const result2 = await executeScaffoldManagedSkill(
90
84
  {
91
85
  skill_id: "dupe",
92
86
  name: "Duplicate",
@@ -98,7 +92,7 @@ describe("scaffold_managed_skill tool", () => {
98
92
  expect(result2.isError).toBe(true);
99
93
  expect(result2.content).toContain("already exists");
100
94
 
101
- const result3 = await tool.execute(
95
+ const result3 = await executeScaffoldManagedSkill(
102
96
  {
103
97
  skill_id: "dupe",
104
98
  name: "Overwritten",
@@ -120,13 +114,13 @@ describe("scaffold_managed_skill tool", () => {
120
114
  ];
121
115
 
122
116
  for (const input of cases) {
123
- const result = await tool.execute(input, makeContext());
117
+ const result = await executeScaffoldManagedSkill(input, makeContext());
124
118
  expect(result.isError).toBe(true);
125
119
  }
126
120
  });
127
121
 
128
122
  test("sanitizes embedded newlines in name/description/emoji to prevent frontmatter injection", async () => {
129
- const result = await tool.execute(
123
+ const result = await executeScaffoldManagedSkill(
130
124
  {
131
125
  skill_id: "inject-test",
132
126
  name: 'Test\ninjected_field: "evil"',
@@ -143,17 +137,20 @@ describe("scaffold_managed_skill tool", () => {
143
137
 
144
138
  // Newlines must not appear inside frontmatter values
145
139
  const frontmatter = content.split("---")[1];
146
- const fmLines = frontmatter.split("\n").filter((l) => l.trim());
147
- // Each frontmatter line must start with a known key -- no injected keys
140
+ // Only check top-level (non-indented) keys — nested YAML under metadata: is expected
141
+ const fmLines = frontmatter
142
+ .split("\n")
143
+ .filter((l) => l.trim() && !l.match(/^\s/));
144
+ // Each top-level frontmatter line must start with a known key -- no injected keys
148
145
  for (const line of fmLines) {
149
146
  expect(line).toMatch(
150
- /^(name|description|emoji|user-invocable|disable-model-invocation|metadata):\s/,
147
+ /^(name|description|emoji|user-invocable|disable-model-invocation|metadata)(:\s|:$)/,
151
148
  );
152
149
  }
153
150
  });
154
151
 
155
152
  test("creates a skill with includes metadata", async () => {
156
- const result = await tool.execute(
153
+ const result = await executeScaffoldManagedSkill(
157
154
  {
158
155
  skill_id: "parent-skill",
159
156
  name: "Parent",
@@ -167,11 +164,13 @@ describe("scaffold_managed_skill tool", () => {
167
164
  expect(result.isError).toBe(false);
168
165
  const skillFile = join(TEST_DIR, "skills", "parent-skill", "SKILL.md");
169
166
  const content = readFileSync(skillFile, "utf-8");
170
- expect(content).toContain('"includes":["child-a","child-b"]');
167
+ expect(content).toContain(" includes:");
168
+ expect(content).toContain(" - child-a");
169
+ expect(content).toContain(" - child-b");
171
170
  });
172
171
 
173
172
  test("normalizes includes — trims and deduplicates", async () => {
174
- const result = await tool.execute(
173
+ const result = await executeScaffoldManagedSkill(
175
174
  {
176
175
  skill_id: "norm-skill",
177
176
  name: "Normalized",
@@ -185,11 +184,13 @@ describe("scaffold_managed_skill tool", () => {
185
184
  expect(result.isError).toBe(false);
186
185
  const skillFile = join(TEST_DIR, "skills", "norm-skill", "SKILL.md");
187
186
  const content = readFileSync(skillFile, "utf-8");
188
- expect(content).toContain('"includes":["child-a","child-b"]');
187
+ expect(content).toContain(" includes:");
188
+ expect(content).toContain(" - child-a");
189
+ expect(content).toContain(" - child-b");
189
190
  });
190
191
 
191
192
  test("rejects includes with non-string elements", async () => {
192
- const result = await tool.execute(
193
+ const result = await executeScaffoldManagedSkill(
193
194
  {
194
195
  skill_id: "bad-includes",
195
196
  name: "Bad",
@@ -205,7 +206,7 @@ describe("scaffold_managed_skill tool", () => {
205
206
  });
206
207
 
207
208
  test("rejects includes with empty string elements", async () => {
208
- const result = await tool.execute(
209
+ const result = await executeScaffoldManagedSkill(
209
210
  {
210
211
  skill_id: "empty-includes",
211
212
  name: "Empty",
@@ -221,7 +222,7 @@ describe("scaffold_managed_skill tool", () => {
221
222
  });
222
223
 
223
224
  test("rejects includes with whitespace-only elements", async () => {
224
- const result = await tool.execute(
225
+ const result = await executeScaffoldManagedSkill(
225
226
  {
226
227
  skill_id: "ws-includes",
227
228
  name: "Whitespace",
@@ -237,7 +238,7 @@ describe("scaffold_managed_skill tool", () => {
237
238
  });
238
239
 
239
240
  test("omits includes when not provided", async () => {
240
- const result = await tool.execute(
241
+ const result = await executeScaffoldManagedSkill(
241
242
  {
242
243
  skill_id: "no-includes",
243
244
  name: "Solo",
@@ -254,7 +255,7 @@ describe("scaffold_managed_skill tool", () => {
254
255
  });
255
256
 
256
257
  test("rejects invalid skill_id", async () => {
257
- const result = await tool.execute(
258
+ const result = await executeScaffoldManagedSkill(
258
259
  {
259
260
  skill_id: "../escape",
260
261
  name: "Bad",
@@ -269,7 +270,7 @@ describe("scaffold_managed_skill tool", () => {
269
270
  });
270
271
 
271
272
  test("e2e: scaffold child then parent with includes, verify files and index", async () => {
272
- const childResult = await tool.execute(
273
+ const childResult = await executeScaffoldManagedSkill(
273
274
  {
274
275
  skill_id: "e2e-child",
275
276
  name: "E2E Child",
@@ -280,7 +281,7 @@ describe("scaffold_managed_skill tool", () => {
280
281
  );
281
282
  expect(childResult.isError).toBe(false);
282
283
 
283
- const parentResult = await tool.execute(
284
+ const parentResult = await executeScaffoldManagedSkill(
284
285
  {
285
286
  skill_id: "e2e-parent",
286
287
  name: "E2E Parent",
@@ -295,7 +296,8 @@ describe("scaffold_managed_skill tool", () => {
295
296
  const parentSkillFile = join(TEST_DIR, "skills", "e2e-parent", "SKILL.md");
296
297
  expect(existsSync(parentSkillFile)).toBe(true);
297
298
  const parentContent = readFileSync(parentSkillFile, "utf-8");
298
- expect(parentContent).toContain('"includes":["e2e-child"]');
299
+ expect(parentContent).toContain(" includes:");
300
+ expect(parentContent).toContain(" - e2e-child");
299
301
 
300
302
  const indexContent = readFileSync(
301
303
  join(TEST_DIR, "skills", "SKILLS.md"),
@@ -11,7 +11,6 @@ mock.module("../util/platform.js", () => ({
11
11
  isMacOS: () => process.platform === "darwin",
12
12
  isLinux: () => process.platform === "linux",
13
13
  isWindows: () => process.platform === "win32",
14
- getSocketPath: () => join(testDir, "test.sock"),
15
14
  getPidPath: () => join(testDir, "test.pid"),
16
15
  getDbPath: () => join(testDir, "test.db"),
17
16
  getLogPath: () => join(testDir, "test.log"),
@@ -29,9 +28,14 @@ mock.module("../util/logger.js", () => ({
29
28
 
30
29
  import { getDb, initializeDb, resetDb } from "../memory/db.js";
31
30
  import {
31
+ cancelSchedule,
32
32
  claimDueSchedules,
33
+ completeOneShot,
33
34
  createSchedule,
35
+ describeCronExpression,
36
+ failOneShot,
34
37
  getSchedule,
38
+ listSchedules,
35
39
  updateSchedule,
36
40
  } from "../schedule/schedule-store.js";
37
41
 
@@ -569,3 +573,439 @@ describe("claimDueSchedules", () => {
569
573
  expect(second.length).toBe(0);
570
574
  });
571
575
  });
576
+
577
+ // ── One-shot schedules ──────────────────────────────────────────────
578
+
579
+ describe("createSchedule (one-shot)", () => {
580
+ beforeEach(() => {
581
+ const db = getDb();
582
+ db.run("DELETE FROM cron_runs");
583
+ db.run("DELETE FROM cron_jobs");
584
+ });
585
+
586
+ test("creates a one-shot schedule with no expression", () => {
587
+ const fireAt = Date.now() + 60_000;
588
+ const job = createSchedule({
589
+ name: "Remind me",
590
+ message: "take out the trash",
591
+ nextRunAt: fireAt,
592
+ });
593
+
594
+ expect(job.expression).toBeNull();
595
+ expect(job.cronExpression).toBeNull();
596
+ expect(job.nextRunAt).toBe(fireAt);
597
+ expect(job.enabled).toBe(true);
598
+ expect(job.status).toBe("active");
599
+ expect(job.mode).toBe("execute");
600
+ expect(job.routingIntent).toBe("all_channels");
601
+ expect(job.routingHints).toEqual({});
602
+ });
603
+
604
+ test("creates a one-shot schedule with notify mode and routing", () => {
605
+ const fireAt = Date.now() + 60_000;
606
+ const hints = { preferredChannel: "slack", threadId: "abc123" };
607
+ const job = createSchedule({
608
+ name: "Notify me",
609
+ message: "meeting in 5",
610
+ nextRunAt: fireAt,
611
+ mode: "notify",
612
+ routingIntent: "single_channel",
613
+ routingHints: hints,
614
+ });
615
+
616
+ expect(job.mode).toBe("notify");
617
+ expect(job.routingIntent).toBe("single_channel");
618
+ expect(job.routingHints).toEqual(hints);
619
+ expect(job.expression).toBeNull();
620
+ expect(job.status).toBe("active");
621
+ });
622
+
623
+ test("rejects one-shot schedule without nextRunAt", () => {
624
+ expect(() =>
625
+ createSchedule({
626
+ name: "Bad one-shot",
627
+ message: "no time",
628
+ }),
629
+ ).toThrow("One-shot schedules (no expression) require nextRunAt");
630
+ });
631
+
632
+ test("one-shot schedule persists and round-trips correctly", () => {
633
+ const fireAt = Date.now() + 120_000;
634
+ const hints = { channel: "telegram" };
635
+ const job = createSchedule({
636
+ name: "Persist test",
637
+ message: "round trip",
638
+ nextRunAt: fireAt,
639
+ mode: "notify",
640
+ routingIntent: "multi_channel",
641
+ routingHints: hints,
642
+ });
643
+
644
+ const retrieved = getSchedule(job.id);
645
+ expect(retrieved).not.toBeNull();
646
+ expect(retrieved!.expression).toBeNull();
647
+ expect(retrieved!.cronExpression).toBeNull();
648
+ expect(retrieved!.nextRunAt).toBe(fireAt);
649
+ expect(retrieved!.mode).toBe("notify");
650
+ expect(retrieved!.routingIntent).toBe("multi_channel");
651
+ expect(retrieved!.routingHints).toEqual(hints);
652
+ expect(retrieved!.status).toBe("active");
653
+ });
654
+ });
655
+
656
+ // ── One-shot claiming ───────────────────────────────────────────────
657
+
658
+ describe("claimDueSchedules (one-shot)", () => {
659
+ beforeEach(() => {
660
+ const db = getDb();
661
+ db.run("DELETE FROM cron_runs");
662
+ db.run("DELETE FROM cron_jobs");
663
+ });
664
+
665
+ test("claims one-shot schedules whose nextRunAt <= now", () => {
666
+ const job = createSchedule({
667
+ name: "Due one-shot",
668
+ message: "fire now",
669
+ nextRunAt: Date.now() - 1000,
670
+ });
671
+
672
+ const claimed = claimDueSchedules(Date.now());
673
+ expect(claimed.length).toBe(1);
674
+ expect(claimed[0].id).toBe(job.id);
675
+ expect(claimed[0].expression).toBeNull();
676
+ expect(claimed[0].status).toBe("firing");
677
+ });
678
+
679
+ test("does not claim one-shot schedules that are not yet due", () => {
680
+ createSchedule({
681
+ name: "Future one-shot",
682
+ message: "not yet",
683
+ nextRunAt: Date.now() + 60_000,
684
+ });
685
+
686
+ const claimed = claimDueSchedules(Date.now());
687
+ expect(claimed.length).toBe(0);
688
+ });
689
+
690
+ test("does not double-claim one-shot schedules", () => {
691
+ createSchedule({
692
+ name: "Once only",
693
+ message: "no double",
694
+ nextRunAt: Date.now() - 1000,
695
+ });
696
+
697
+ const first = claimDueSchedules(Date.now());
698
+ expect(first.length).toBe(1);
699
+
700
+ // Second claim should find nothing since status is now 'firing'
701
+ const second = claimDueSchedules(Date.now());
702
+ expect(second.length).toBe(0);
703
+ });
704
+
705
+ test("claims both recurring and one-shot schedules in the same tick", () => {
706
+ const recurring = createSchedule({
707
+ name: "Recurring",
708
+ cronExpression: "* * * * *",
709
+ message: "recurring",
710
+ syntax: "cron",
711
+ });
712
+ getRawDb().run("UPDATE cron_jobs SET next_run_at = ? WHERE id = ?", [
713
+ Date.now() - 1000,
714
+ recurring.id,
715
+ ]);
716
+
717
+ createSchedule({
718
+ name: "One-shot",
719
+ message: "one-shot",
720
+ nextRunAt: Date.now() - 1000,
721
+ });
722
+
723
+ const claimed = claimDueSchedules(Date.now());
724
+ expect(claimed.length).toBe(2);
725
+ const expressions = claimed.map((c) => c.expression);
726
+ expect(expressions).toContain(null); // one-shot
727
+ expect(expressions.some(Boolean)).toBe(true); // recurring
728
+ });
729
+ });
730
+
731
+ // ── One-shot lifecycle (complete, fail, cancel) ─────────────────────
732
+
733
+ describe("completeOneShot", () => {
734
+ beforeEach(() => {
735
+ const db = getDb();
736
+ db.run("DELETE FROM cron_runs");
737
+ db.run("DELETE FROM cron_jobs");
738
+ });
739
+
740
+ test("transitions firing -> fired", () => {
741
+ const job = createSchedule({
742
+ name: "Complete me",
743
+ message: "done",
744
+ nextRunAt: Date.now() - 1000,
745
+ });
746
+
747
+ // Claim first to get to 'firing' state
748
+ claimDueSchedules(Date.now());
749
+
750
+ completeOneShot(job.id);
751
+
752
+ const retrieved = getSchedule(job.id);
753
+ expect(retrieved!.status).toBe("fired");
754
+ expect(retrieved!.enabled).toBe(false);
755
+ });
756
+
757
+ test("does not transition if not in firing state", () => {
758
+ const job = createSchedule({
759
+ name: "Not firing",
760
+ message: "still active",
761
+ nextRunAt: Date.now() + 60_000,
762
+ });
763
+
764
+ completeOneShot(job.id);
765
+
766
+ const retrieved = getSchedule(job.id);
767
+ expect(retrieved!.status).toBe("active"); // unchanged
768
+ expect(retrieved!.enabled).toBe(true);
769
+ });
770
+ });
771
+
772
+ describe("failOneShot", () => {
773
+ beforeEach(() => {
774
+ const db = getDb();
775
+ db.run("DELETE FROM cron_runs");
776
+ db.run("DELETE FROM cron_jobs");
777
+ });
778
+
779
+ test("transitions firing -> active for retry", () => {
780
+ const job = createSchedule({
781
+ name: "Fail me",
782
+ message: "retry",
783
+ nextRunAt: Date.now() - 1000,
784
+ });
785
+
786
+ // Claim to get to 'firing'
787
+ claimDueSchedules(Date.now());
788
+
789
+ failOneShot(job.id);
790
+
791
+ const retrieved = getSchedule(job.id);
792
+ expect(retrieved!.status).toBe("active");
793
+ expect(retrieved!.enabled).toBe(true); // still enabled for retry
794
+ });
795
+
796
+ test("can be re-claimed after failing", () => {
797
+ const job = createSchedule({
798
+ name: "Retry",
799
+ message: "try again",
800
+ nextRunAt: Date.now() - 1000,
801
+ });
802
+
803
+ claimDueSchedules(Date.now());
804
+ failOneShot(job.id);
805
+
806
+ // Should be claimable again
807
+ const claimed = claimDueSchedules(Date.now());
808
+ expect(claimed.length).toBe(1);
809
+ expect(claimed[0].id).toBe(job.id);
810
+ });
811
+ });
812
+
813
+ describe("cancelSchedule", () => {
814
+ beforeEach(() => {
815
+ const db = getDb();
816
+ db.run("DELETE FROM cron_runs");
817
+ db.run("DELETE FROM cron_jobs");
818
+ });
819
+
820
+ test("cancels an active one-shot schedule", () => {
821
+ const job = createSchedule({
822
+ name: "Cancel me",
823
+ message: "never fire",
824
+ nextRunAt: Date.now() + 60_000,
825
+ });
826
+
827
+ const result = cancelSchedule(job.id);
828
+ expect(result).toBe(true);
829
+
830
+ const retrieved = getSchedule(job.id);
831
+ expect(retrieved!.status).toBe("cancelled");
832
+ expect(retrieved!.enabled).toBe(false);
833
+ });
834
+
835
+ test("returns false for non-active schedule", () => {
836
+ const job = createSchedule({
837
+ name: "Already done",
838
+ message: "completed",
839
+ nextRunAt: Date.now() - 1000,
840
+ });
841
+
842
+ // Claim and complete it
843
+ claimDueSchedules(Date.now());
844
+ completeOneShot(job.id);
845
+
846
+ const result = cancelSchedule(job.id);
847
+ expect(result).toBe(false);
848
+ });
849
+
850
+ test("cancelled schedule is not claimable", () => {
851
+ const job = createSchedule({
852
+ name: "Cancelled",
853
+ message: "should not fire",
854
+ nextRunAt: Date.now() - 1000,
855
+ });
856
+
857
+ cancelSchedule(job.id);
858
+
859
+ const claimed = claimDueSchedules(Date.now());
860
+ expect(claimed.length).toBe(0);
861
+ });
862
+ });
863
+
864
+ // ── Routing and mode round-trip ─────────────────────────────────────
865
+
866
+ describe("routing and mode fields", () => {
867
+ beforeEach(() => {
868
+ const db = getDb();
869
+ db.run("DELETE FROM cron_runs");
870
+ db.run("DELETE FROM cron_jobs");
871
+ });
872
+
873
+ test("recurring schedule defaults to execute mode and all_channels", () => {
874
+ const job = createSchedule({
875
+ name: "Defaults",
876
+ cronExpression: "0 9 * * *",
877
+ message: "check defaults",
878
+ syntax: "cron",
879
+ });
880
+
881
+ expect(job.mode).toBe("execute");
882
+ expect(job.routingIntent).toBe("all_channels");
883
+ expect(job.routingHints).toEqual({});
884
+ expect(job.status).toBe("active");
885
+ });
886
+
887
+ test("routing hints round-trip through create/read", () => {
888
+ const hints = { channels: ["slack", "discord"], priority: 1 };
889
+ const job = createSchedule({
890
+ name: "Routed",
891
+ cronExpression: "0 9 * * *",
892
+ message: "routed msg",
893
+ syntax: "cron",
894
+ routingIntent: "multi_channel",
895
+ routingHints: hints,
896
+ mode: "notify",
897
+ });
898
+
899
+ const retrieved = getSchedule(job.id);
900
+ expect(retrieved!.routingIntent).toBe("multi_channel");
901
+ expect(retrieved!.routingHints).toEqual(hints);
902
+ expect(retrieved!.mode).toBe("notify");
903
+ });
904
+
905
+ test("routing hints round-trip through DB raw query", () => {
906
+ const hints = { target: "sms" };
907
+ const job = createSchedule({
908
+ name: "Raw round-trip",
909
+ message: "check raw",
910
+ nextRunAt: Date.now() + 60_000,
911
+ routingIntent: "single_channel",
912
+ routingHints: hints,
913
+ });
914
+
915
+ const raw = getRawDb()
916
+ .query(
917
+ "SELECT mode, routing_intent, routing_hints_json, status FROM cron_jobs WHERE id = ?",
918
+ )
919
+ .get(job.id) as {
920
+ mode: string;
921
+ routing_intent: string;
922
+ routing_hints_json: string;
923
+ status: string;
924
+ } | null;
925
+ expect(raw).not.toBeNull();
926
+ expect(raw!.mode).toBe("execute");
927
+ expect(raw!.routing_intent).toBe("single_channel");
928
+ expect(JSON.parse(raw!.routing_hints_json)).toEqual(hints);
929
+ expect(raw!.status).toBe("active");
930
+ });
931
+
932
+ test("updateSchedule updates mode and routing fields", () => {
933
+ const job = createSchedule({
934
+ name: "Update routing",
935
+ cronExpression: "0 9 * * *",
936
+ message: "update routing",
937
+ syntax: "cron",
938
+ });
939
+
940
+ const updated = updateSchedule(job.id, {
941
+ mode: "notify",
942
+ routingIntent: "single_channel",
943
+ routingHints: { channel: "telegram" },
944
+ });
945
+
946
+ expect(updated).not.toBeNull();
947
+ expect(updated!.mode).toBe("notify");
948
+ expect(updated!.routingIntent).toBe("single_channel");
949
+ expect(updated!.routingHints).toEqual({ channel: "telegram" });
950
+ });
951
+ });
952
+
953
+ // ── listSchedules filters ───────────────────────────────────────────
954
+
955
+ describe("listSchedules filters", () => {
956
+ beforeEach(() => {
957
+ const db = getDb();
958
+ db.run("DELETE FROM cron_runs");
959
+ db.run("DELETE FROM cron_jobs");
960
+ });
961
+
962
+ test("oneShotOnly filter returns only one-shot schedules", () => {
963
+ createSchedule({
964
+ name: "Recurring",
965
+ cronExpression: "0 9 * * *",
966
+ message: "recurring",
967
+ syntax: "cron",
968
+ });
969
+ createSchedule({
970
+ name: "One-shot",
971
+ message: "one-shot",
972
+ nextRunAt: Date.now() + 60_000,
973
+ });
974
+
975
+ const oneShots = listSchedules({ oneShotOnly: true });
976
+ expect(oneShots.length).toBe(1);
977
+ expect(oneShots[0].name).toBe("One-shot");
978
+ expect(oneShots[0].expression).toBeNull();
979
+ });
980
+
981
+ test("recurringOnly filter returns only recurring schedules", () => {
982
+ createSchedule({
983
+ name: "Recurring",
984
+ cronExpression: "0 9 * * *",
985
+ message: "recurring",
986
+ syntax: "cron",
987
+ });
988
+ createSchedule({
989
+ name: "One-shot",
990
+ message: "one-shot",
991
+ nextRunAt: Date.now() + 60_000,
992
+ });
993
+
994
+ const recurring = listSchedules({ recurringOnly: true });
995
+ expect(recurring.length).toBe(1);
996
+ expect(recurring[0].name).toBe("Recurring");
997
+ expect(recurring[0].expression).not.toBeNull();
998
+ });
999
+ });
1000
+
1001
+ // ── describeCronExpression ──────────────────────────────────────────
1002
+
1003
+ describe("describeCronExpression", () => {
1004
+ test("returns 'One-time' for null expression", () => {
1005
+ expect(describeCronExpression(null)).toBe("One-time");
1006
+ });
1007
+
1008
+ test("returns description for valid cron expression", () => {
1009
+ expect(describeCronExpression("0 9 * * *")).toBe("Every day at 9:00 AM");
1010
+ });
1011
+ });