@vellumai/assistant 0.4.44 → 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 (681) hide show
  1. package/.prettierignore +4 -0
  2. package/ARCHITECTURE.md +34 -31
  3. package/README.md +4 -4
  4. package/bun.lock +10 -35
  5. package/docs/architecture/integrations.md +102 -197
  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 -1
  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-skill-retrieval-guard.test.ts +23 -9
  40. package/src/__tests__/call-controller.test.ts +0 -1
  41. package/src/__tests__/call-conversation-messages.test.ts +0 -1
  42. package/src/__tests__/call-domain.test.ts +0 -1
  43. package/src/__tests__/call-pointer-messages.test.ts +0 -1
  44. package/src/__tests__/call-recovery.test.ts +0 -1
  45. package/src/__tests__/call-routes-http.test.ts +0 -1
  46. package/src/__tests__/call-store.test.ts +0 -1
  47. package/src/__tests__/canonical-guardian-store.test.ts +0 -1
  48. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  49. package/src/__tests__/channel-approvals.test.ts +1 -1
  50. package/src/__tests__/channel-delivery-store.test.ts +0 -1
  51. package/src/__tests__/channel-guardian.test.ts +5 -7
  52. package/src/__tests__/channel-retry-sweep.test.ts +0 -1
  53. package/src/__tests__/checker.test.ts +4 -11
  54. package/src/__tests__/compaction.benchmark.test.ts +16 -14
  55. package/src/__tests__/computer-use-session-lifecycle.test.ts +10 -11
  56. package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
  57. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +2 -5
  58. package/src/__tests__/computer-use-tools.test.ts +35 -31
  59. package/src/__tests__/config-schema.test.ts +11 -15
  60. package/src/__tests__/config-watcher.test.ts +0 -1
  61. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  62. package/src/__tests__/conflict-store.test.ts +0 -1
  63. package/src/__tests__/connection-policy.test.ts +4 -7
  64. package/src/__tests__/contacts-tools.test.ts +0 -1
  65. package/src/__tests__/context-memory-e2e.test.ts +2 -4
  66. package/src/__tests__/context-overflow-reducer.test.ts +2 -4
  67. package/src/__tests__/context-window-manager.test.ts +147 -60
  68. package/src/__tests__/contradiction-checker.test.ts +0 -1
  69. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  70. package/src/__tests__/conversation-attention-telegram.test.ts +1 -1
  71. package/src/__tests__/conversation-pairing.test.ts +2 -2
  72. package/src/__tests__/conversation-routes-guardian-reply.test.ts +25 -1
  73. package/src/__tests__/conversation-routes-slash-commands.test.ts +381 -0
  74. package/src/__tests__/conversation-store.test.ts +0 -1
  75. package/src/__tests__/conversation-unread-route.test.ts +1 -2
  76. package/src/__tests__/credential-security-invariants.test.ts +7 -8
  77. package/src/__tests__/cross-provider-web-search.test.ts +353 -0
  78. package/src/__tests__/daemon-assistant-events.test.ts +6 -7
  79. package/src/__tests__/db-schedule-syntax-migration.test.ts +15 -3
  80. package/src/__tests__/delete-managed-skill-tool.test.ts +5 -9
  81. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
  82. package/src/__tests__/diagnostics-export.test.ts +189 -0
  83. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  84. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
  85. package/src/__tests__/entity-extractor.test.ts +0 -1
  86. package/src/__tests__/entity-search.test.ts +0 -1
  87. package/src/__tests__/ephemeral-permissions.test.ts +2 -4
  88. package/src/__tests__/file-read-tool.test.ts +86 -0
  89. package/src/__tests__/followup-tools.test.ts +0 -1
  90. package/src/__tests__/frontmatter.test.ts +77 -34
  91. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  92. package/src/__tests__/gateway-only-guard.test.ts +1 -1
  93. package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -1
  94. package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
  95. package/src/__tests__/guardian-action-followup-store.test.ts +0 -1
  96. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  97. package/src/__tests__/guardian-action-late-reply.test.ts +0 -1
  98. package/src/__tests__/guardian-action-store.test.ts +0 -1
  99. package/src/__tests__/guardian-action-sweep.test.ts +0 -1
  100. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  101. package/src/__tests__/guardian-dispatch.test.ts +1 -2
  102. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  103. package/src/__tests__/guardian-outbound-http.test.ts +0 -1
  104. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -1
  105. package/src/__tests__/guardian-routing-invariants.test.ts +1 -1
  106. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  107. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  108. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +3 -5
  109. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +28 -426
  110. package/src/__tests__/host-bash-proxy.test.ts +335 -0
  111. package/src/__tests__/host-file-proxy.test.ts +374 -0
  112. package/src/__tests__/host-shell-tool.test.ts +147 -1
  113. package/src/__tests__/http-user-message-parity.test.ts +361 -0
  114. package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
  115. package/src/__tests__/integration-status.test.ts +3 -8
  116. package/src/__tests__/intent-routing.test.ts +7 -46
  117. package/src/__tests__/invite-redemption-service.test.ts +0 -1
  118. package/src/__tests__/invite-routes-http.test.ts +0 -1
  119. package/src/__tests__/llm-usage-store.test.ts +0 -1
  120. package/src/__tests__/managed-avatar-client.test.ts +101 -55
  121. package/src/__tests__/managed-skill-lifecycle.test.ts +9 -18
  122. package/src/__tests__/managed-store.test.ts +94 -21
  123. package/src/__tests__/media-reuse-story.e2e.test.ts +0 -1
  124. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +2 -4
  125. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -1
  126. package/src/__tests__/memory-recall-quality.test.ts +0 -1
  127. package/src/__tests__/memory-regressions.experimental.test.ts +0 -1
  128. package/src/__tests__/memory-regressions.test.ts +0 -1
  129. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -1
  130. package/src/__tests__/memory-upsert-concurrency.test.ts +0 -1
  131. package/src/__tests__/messaging-send-tool.test.ts +35 -0
  132. package/src/__tests__/messaging-skill-split.test.ts +138 -0
  133. package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1
  134. package/src/__tests__/migration-export-http.test.ts +2 -3
  135. package/src/__tests__/migration-import-commit-http.test.ts +1 -2
  136. package/src/__tests__/migration-import-preflight-http.test.ts +1 -2
  137. package/src/__tests__/migration-validate-http.test.ts +1 -2
  138. package/src/__tests__/native-web-search.test.ts +475 -0
  139. package/src/__tests__/navigate-settings-tab.test.ts +84 -0
  140. package/src/__tests__/non-member-access-request.test.ts +0 -1
  141. package/src/__tests__/notification-broadcaster.test.ts +15 -15
  142. package/src/__tests__/notification-decision-strategy.test.ts +6 -6
  143. package/src/__tests__/notification-deep-link.test.ts +7 -7
  144. package/src/__tests__/notification-guardian-path.test.ts +2 -3
  145. package/src/__tests__/notification-telegram-adapter.test.ts +1 -1
  146. package/src/__tests__/notification-thread-candidates.test.ts +4 -4
  147. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  148. package/src/__tests__/playbook-execution.test.ts +0 -1
  149. package/src/__tests__/playbook-tools.test.ts +0 -1
  150. package/src/__tests__/profile-compiler.test.ts +0 -1
  151. package/src/__tests__/provider-managed-proxy-integration.test.ts +25 -0
  152. package/src/__tests__/qdrant-collection-migration.test.ts +223 -0
  153. package/src/__tests__/recording-handler.test.ts +30 -94
  154. package/src/__tests__/registry.test.ts +28 -35
  155. package/src/__tests__/relay-server.test.ts +0 -1
  156. package/src/__tests__/ride-shotgun-handler.test.ts +4 -20
  157. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  158. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  159. package/src/__tests__/runtime-events-sse.test.ts +0 -1
  160. package/src/__tests__/sandbox-diagnostics.test.ts +0 -1
  161. package/src/__tests__/scaffold-managed-skill-tool.test.ts +30 -28
  162. package/src/__tests__/schedule-store.test.ts +441 -1
  163. package/src/__tests__/schedule-tools.test.ts +468 -7
  164. package/src/__tests__/scheduler-recurrence.test.ts +196 -23
  165. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  166. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  167. package/src/__tests__/secret-prompt-log-hygiene.test.ts +6 -3
  168. package/src/__tests__/secret-response-routing.test.ts +4 -1
  169. package/src/__tests__/send-endpoint-busy.test.ts +14 -2
  170. package/src/__tests__/send-notification-tool.test.ts +0 -7
  171. package/src/__tests__/sequence-store.test.ts +0 -1
  172. package/src/__tests__/server-history-render.test.ts +1 -2
  173. package/src/__tests__/session-abort-tool-results.test.ts +0 -1
  174. package/src/__tests__/session-agent-loop.test.ts +46 -6
  175. package/src/__tests__/session-confirmation-signals.test.ts +0 -1
  176. package/src/__tests__/session-conflict-gate.test.ts +2 -6
  177. package/src/__tests__/session-error.test.ts +5 -14
  178. package/src/__tests__/session-init.benchmark.test.ts +3 -5
  179. package/src/__tests__/session-load-history-repair.test.ts +0 -1
  180. package/src/__tests__/session-media-retry.test.ts +12 -74
  181. package/src/__tests__/session-pre-run-repair.test.ts +0 -1
  182. package/src/__tests__/session-profile-injection.test.ts +2 -6
  183. package/src/__tests__/session-provider-retry-repair.test.ts +2 -6
  184. package/src/__tests__/session-queue.test.ts +94 -139
  185. package/src/__tests__/session-skill-tools.test.ts +115 -115
  186. package/src/__tests__/session-slash-known.test.ts +0 -1
  187. package/src/__tests__/session-slash-queue.test.ts +0 -1
  188. package/src/__tests__/session-slash-unknown.test.ts +0 -1
  189. package/src/__tests__/session-surfaces-task-progress.test.ts +34 -0
  190. package/src/__tests__/session-usage.test.ts +0 -1
  191. package/src/__tests__/session-workspace-cache-state.test.ts +2 -6
  192. package/src/__tests__/session-workspace-injection.test.ts +2 -6
  193. package/src/__tests__/session-workspace-tool-tracking.test.ts +2 -6
  194. package/src/__tests__/skill-feature-flags-integration.test.ts +180 -184
  195. package/src/__tests__/skill-feature-flags.test.ts +125 -18
  196. package/src/__tests__/skill-load-feature-flag.test.ts +1 -2
  197. package/src/__tests__/skill-load-tool.test.ts +194 -2
  198. package/src/__tests__/skill-projection-feature-flag.test.ts +27 -16
  199. package/src/__tests__/skill-projection.benchmark.test.ts +15 -14
  200. package/src/__tests__/skills.test.ts +14 -53
  201. package/src/__tests__/slack-channel-config.test.ts +0 -1
  202. package/src/__tests__/slack-inbound-verification.test.ts +0 -1
  203. package/src/__tests__/slack-skill.test.ts +1 -1
  204. package/src/__tests__/subagent-tools.test.ts +2 -2
  205. package/src/__tests__/system-prompt.test.ts +4 -3
  206. package/src/__tests__/task-compiler.test.ts +0 -1
  207. package/src/__tests__/task-management-tools.test.ts +0 -1
  208. package/src/__tests__/task-memory-cleanup.test.ts +0 -1
  209. package/src/__tests__/task-runner.test.ts +0 -1
  210. package/src/__tests__/task-scheduler.test.ts +0 -1
  211. package/src/__tests__/terminal-tools.test.ts +0 -1
  212. package/src/__tests__/test-support/computer-use-skill-harness.ts +2 -4
  213. package/src/__tests__/thread-seed-composer.test.ts +5 -5
  214. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  215. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  216. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  217. package/src/__tests__/tool-executor.test.ts +8 -86
  218. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  219. package/src/__tests__/tool-notification-listener.test.ts +1 -1
  220. package/src/__tests__/tool-preview-lifecycle.test.ts +416 -0
  221. package/src/__tests__/trust-store.test.ts +80 -4
  222. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  223. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  224. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -1
  225. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  226. package/src/__tests__/trusted-contact-verification.test.ts +0 -1
  227. package/src/__tests__/twilio-provider.test.ts +0 -1
  228. package/src/__tests__/twilio-routes.test.ts +0 -1
  229. package/src/__tests__/{request-file-tool.test.ts → ui-file-upload-surface.test.ts} +11 -72
  230. package/src/__tests__/update-bulletin.test.ts +0 -1
  231. package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -1
  232. package/src/__tests__/usage-routes.test.ts +0 -1
  233. package/src/__tests__/verification-control-plane-policy.test.ts +4 -4
  234. package/src/__tests__/voice-invite-redemption.test.ts +0 -1
  235. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  236. package/src/__tests__/voice-session-bridge.test.ts +9 -1
  237. package/src/__tests__/web-fetch.test.ts +57 -0
  238. package/src/__tests__/workspace-git-service.test.ts +5 -14
  239. package/src/__tests__/workspace-policy.test.ts +0 -1
  240. package/src/agent/loop.ts +22 -34
  241. package/src/bundler/bundle-signer.ts +4 -4
  242. package/src/calls/call-controller.ts +1 -1
  243. package/src/calls/relay-server.ts +1 -1
  244. package/src/calls/twilio-rest.ts +1 -1
  245. package/src/calls/voice-session-bridge.ts +3 -1
  246. package/src/cli/__tests__/notifications.test.ts +3 -4
  247. package/src/cli/commands/map.ts +2 -6
  248. package/src/cli/commands/mcp.ts +73 -15
  249. package/src/cli/commands/notifications.ts +4 -4
  250. package/src/cli/commands/sessions.ts +9 -1
  251. package/src/cli/commands/skills.ts +6 -10
  252. package/src/cli/http-client.ts +2 -3
  253. package/src/cli/main-screen.tsx +10 -10
  254. package/src/cli/program.ts +0 -4
  255. package/src/cli/reference.ts +0 -2
  256. package/src/cli.ts +15 -9
  257. package/src/config/__tests__/bundled-tool-registry-guard.test.ts +120 -0
  258. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +11 -0
  259. package/src/config/bundled-skills/app-builder/SKILL.md +6 -1
  260. package/src/config/bundled-skills/browser/SKILL.md +6 -1
  261. package/src/config/bundled-skills/chatgpt-import/SKILL.md +5 -1
  262. package/src/config/bundled-skills/claude-code/SKILL.md +5 -1
  263. package/src/config/bundled-skills/computer-use/SKILL.md +6 -1
  264. package/src/config/bundled-skills/computer-use/TOOLS.json +6 -69
  265. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +10 -1
  266. package/src/config/bundled-skills/contacts/SKILL.md +10 -1
  267. package/src/config/bundled-skills/contacts/TOOLS.json +35 -0
  268. package/src/config/bundled-skills/{messaging → contacts}/tools/google-contacts.ts +9 -2
  269. package/src/config/bundled-skills/document/SKILL.md +4 -1
  270. package/src/config/bundled-skills/doordash/SKILL.md +8 -1
  271. package/src/config/bundled-skills/doordash/lib/shared/platform.ts +4 -1
  272. package/src/config/bundled-skills/followups/SKILL.md +4 -1
  273. package/src/config/bundled-skills/gmail/SKILL.md +180 -0
  274. package/src/config/bundled-skills/gmail/TOOLS.json +506 -0
  275. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +149 -0
  276. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +110 -0
  277. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-draft.ts +1 -1
  278. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-filters.ts +1 -1
  279. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-follow-up.ts +1 -1
  280. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-forward.ts +1 -1
  281. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +50 -0
  282. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-outreach-scan.ts +8 -90
  283. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-send-draft.ts +1 -1
  284. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-sender-digest.ts +2 -2
  285. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-trash.ts +1 -1
  286. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-unsubscribe.ts +1 -1
  287. package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-vacation.ts +1 -1
  288. package/src/config/bundled-skills/gmail/tools/shared.ts +47 -0
  289. package/src/config/bundled-skills/google-calendar/SKILL.md +5 -1
  290. package/src/config/bundled-skills/image-studio/SKILL.md +5 -1
  291. package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -1
  292. package/src/config/bundled-skills/media-processing/SKILL.md +7 -13
  293. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -22
  294. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +12 -1
  295. package/src/config/bundled-skills/messaging/SKILL.md +23 -139
  296. package/src/config/bundled-skills/messaging/TOOLS.json +33 -1215
  297. package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +42 -0
  298. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +165 -2
  299. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +1 -13
  300. package/src/config/bundled-skills/messaging/tools/shared.ts +81 -34
  301. package/src/config/bundled-skills/notifications/SKILL.md +5 -1
  302. package/src/config/bundled-skills/orchestration/SKILL.md +30 -0
  303. package/src/config/bundled-skills/orchestration/TOOLS.json +35 -0
  304. package/src/config/bundled-skills/{reminder/tools/reminder-create.ts → orchestration/tools/swarm-delegate.ts} +3 -3
  305. package/src/config/bundled-skills/phone-calls/SKILL.md +9 -1
  306. package/src/config/bundled-skills/playbooks/SKILL.md +4 -1
  307. package/src/config/bundled-skills/schedule/SKILL.md +70 -9
  308. package/src/config/bundled-skills/schedule/TOOLS.json +38 -6
  309. package/src/config/bundled-skills/screen-watch/SKILL.md +28 -0
  310. package/src/config/bundled-skills/screen-watch/TOOLS.json +35 -0
  311. package/src/config/bundled-skills/{reminder/tools/reminder-cancel.ts → screen-watch/tools/start-screen-watch.ts} +3 -3
  312. package/src/config/bundled-skills/sequences/SKILL.md +47 -0
  313. package/src/config/bundled-skills/sequences/TOOLS.json +340 -0
  314. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +128 -0
  315. package/src/config/bundled-skills/sequences/tools/shared.ts +9 -0
  316. package/src/config/bundled-skills/settings/SKILL.md +12 -0
  317. package/src/config/bundled-skills/settings/TOOLS.json +112 -0
  318. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +43 -0
  319. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +52 -0
  320. package/src/config/bundled-skills/{computer-use/tools/computer-use-right-click.ts → settings/tools/set-avatar.ts} +2 -6
  321. package/src/{tools/system/voice-config.ts → config/bundled-skills/settings/tools/voice-config-update.ts} +59 -96
  322. package/src/config/bundled-skills/skill-management/SKILL.md +18 -0
  323. package/src/config/bundled-skills/skill-management/TOOLS.json +90 -0
  324. package/src/config/bundled-skills/{computer-use/tools/computer-use-double-click.ts → skill-management/tools/delete-managed.ts} +2 -6
  325. package/src/config/bundled-skills/skill-management/tools/scaffold-managed.ts +12 -0
  326. package/src/config/bundled-skills/slack/SKILL.md +5 -1
  327. package/src/config/bundled-skills/subagent/SKILL.md +4 -1
  328. package/src/config/bundled-skills/tasks/SKILL.md +5 -2
  329. package/src/config/bundled-skills/transcribe/SKILL.md +4 -1
  330. package/src/config/bundled-skills/watcher/SKILL.md +4 -1
  331. package/src/config/bundled-tool-registry.ts +118 -107
  332. package/src/config/env.ts +5 -2
  333. package/src/config/feature-flag-registry.json +25 -9
  334. package/src/config/loader.ts +10 -2
  335. package/src/config/schema.ts +19 -16
  336. package/src/config/schemas/inference.ts +12 -22
  337. package/src/config/schemas/memory-storage.ts +19 -1
  338. package/src/config/schemas/platform.ts +0 -16
  339. package/src/config/skill-state.ts +11 -8
  340. package/src/config/skills.ts +83 -32
  341. package/src/context/token-estimator.ts +11 -0
  342. package/src/context/window-manager.ts +180 -151
  343. package/src/daemon/computer-use-session.ts +11 -43
  344. package/src/daemon/daemon-control.ts +4 -1
  345. package/src/daemon/handlers/config-channels.ts +5 -9
  346. package/src/daemon/handlers/config-ingress.ts +0 -4
  347. package/src/daemon/handlers/config-model.ts +7 -13
  348. package/src/daemon/handlers/config-telegram.ts +4 -8
  349. package/src/daemon/handlers/config-voice.ts +2 -5
  350. package/src/daemon/handlers/dictation.ts +2 -12
  351. package/src/daemon/handlers/identity.ts +0 -105
  352. package/src/daemon/handlers/recording.ts +3 -23
  353. package/src/daemon/handlers/session-history.ts +1 -1
  354. package/src/daemon/handlers/sessions.ts +53 -72
  355. package/src/daemon/handlers/shared.ts +7 -28
  356. package/src/daemon/handlers/skills.ts +31 -27
  357. package/src/daemon/host-bash-proxy.ts +148 -0
  358. package/src/daemon/host-file-proxy.ts +135 -0
  359. package/src/daemon/lifecycle.ts +49 -24
  360. package/src/daemon/mcp-reload-service.ts +123 -0
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/browser.ts +1 -1
  363. package/src/daemon/message-types/computer-use.ts +1 -4
  364. package/src/daemon/message-types/guardian-actions.ts +1 -1
  365. package/src/daemon/message-types/host-bash.ts +18 -0
  366. package/src/daemon/message-types/host-file.ts +44 -0
  367. package/src/daemon/message-types/integrations.ts +1 -67
  368. package/src/daemon/message-types/messages.ts +15 -0
  369. package/src/daemon/message-types/schedules.ts +11 -27
  370. package/src/daemon/message-types/sessions.ts +2 -1
  371. package/src/daemon/message-types/settings.ts +1 -1
  372. package/src/daemon/message-types/shared.ts +1 -1
  373. package/src/daemon/ride-shotgun-handler.ts +2 -42
  374. package/src/daemon/server.ts +43 -10
  375. package/src/daemon/session-agent-loop-handlers.ts +48 -7
  376. package/src/daemon/session-agent-loop.ts +97 -66
  377. package/src/daemon/session-attachments.ts +1 -1
  378. package/src/daemon/session-error.ts +17 -16
  379. package/src/daemon/session-lifecycle.ts +20 -1
  380. package/src/daemon/session-media-retry.ts +1 -15
  381. package/src/daemon/session-messaging.ts +14 -6
  382. package/src/daemon/session-process.ts +36 -7
  383. package/src/daemon/session-queue-manager.ts +62 -103
  384. package/src/daemon/session-runtime-assembly.ts +27 -0
  385. package/src/daemon/session-skill-tools.ts +12 -11
  386. package/src/daemon/session-slash.ts +7 -0
  387. package/src/daemon/session-surfaces.ts +19 -97
  388. package/src/daemon/session-tool-setup.ts +146 -6
  389. package/src/daemon/session.ts +77 -13
  390. package/src/errors.ts +0 -2
  391. package/src/export/formatter.ts +6 -0
  392. package/src/mcp/mcp-oauth-provider.ts +1 -3
  393. package/src/media/avatar-router.ts +20 -28
  394. package/src/media/avatar-types.ts +7 -14
  395. package/src/media/managed-avatar-client.ts +70 -34
  396. package/src/memory/conversation-title-service.ts +1 -2
  397. package/src/memory/db-init.ts +16 -0
  398. package/src/memory/embedding-backend.ts +129 -27
  399. package/src/memory/embedding-gemini.test.ts +256 -0
  400. package/src/memory/embedding-gemini.ts +47 -13
  401. package/src/memory/embedding-local.ts +14 -2
  402. package/src/memory/embedding-ollama.ts +15 -2
  403. package/src/memory/embedding-openai.ts +15 -2
  404. package/src/memory/embedding-types.test.ts +116 -0
  405. package/src/memory/embedding-types.ts +61 -0
  406. package/src/memory/fingerprint.ts +1 -1
  407. package/src/memory/indexer.ts +25 -1
  408. package/src/memory/job-handlers/embedding.test.ts +258 -0
  409. package/src/memory/job-handlers/embedding.ts +81 -1
  410. package/src/memory/job-handlers/index-maintenance.ts +35 -1
  411. package/src/memory/job-handlers/media-processing.ts +11 -1
  412. package/src/memory/job-utils.ts +21 -6
  413. package/src/memory/jobs-store.ts +5 -1
  414. package/src/memory/jobs-worker.ts +8 -0
  415. package/src/memory/message-content.ts +66 -0
  416. package/src/memory/migrations/100-core-tables.ts +1 -31
  417. package/src/memory/migrations/104-core-indexes.ts +0 -11
  418. package/src/memory/migrations/145-drop-accounts-table.ts +19 -0
  419. package/src/memory/migrations/146-schedule-oneshot-routing.ts +94 -0
  420. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +129 -0
  421. package/src/memory/migrations/148-drop-reminders-table.ts +18 -0
  422. package/src/memory/migrations/index.ts +4 -0
  423. package/src/memory/migrations/registry.ts +19 -0
  424. package/src/memory/qdrant-client.ts +158 -43
  425. package/src/memory/retriever.test.ts +0 -1
  426. package/src/memory/retriever.ts +12 -2
  427. package/src/memory/schema/infrastructure.ts +5 -29
  428. package/src/memory/search/formatting.ts +34 -9
  429. package/src/memory/search/semantic.ts +57 -2
  430. package/src/memory/search/types.ts +2 -1
  431. package/src/notifications/AGENTS.md +2 -2
  432. package/src/notifications/README.md +59 -58
  433. package/src/notifications/adapters/macos.ts +1 -1
  434. package/src/notifications/broadcaster.ts +5 -5
  435. package/src/notifications/copy-composer.ts +1 -1
  436. package/src/notifications/decision-engine.ts +2 -2
  437. package/src/notifications/destination-resolver.ts +2 -2
  438. package/src/notifications/emit-signal.ts +8 -8
  439. package/src/notifications/signal.ts +1 -1
  440. package/src/notifications/thread-seed-composer.ts +1 -1
  441. package/src/oauth/connect-orchestrator.ts +1 -1
  442. package/src/oauth/token-persistence.ts +1 -1
  443. package/src/permissions/checker.ts +12 -1
  444. package/src/permissions/defaults.ts +10 -14
  445. package/src/permissions/trust-store.ts +37 -0
  446. package/src/permissions/workspace-policy.ts +0 -1
  447. package/src/prompts/__tests__/build-cli-reference-section.test.ts +11 -0
  448. package/src/prompts/computer-use-prompt.ts +1 -1
  449. package/src/prompts/system-prompt.ts +29 -30
  450. package/src/prompts/templates/SOUL.md +1 -2
  451. package/src/prompts/templates/UPDATES.md +16 -7
  452. package/src/providers/anthropic/client.ts +87 -33
  453. package/src/providers/gemini/client.ts +6 -0
  454. package/src/providers/managed-proxy/constants.ts +5 -0
  455. package/src/providers/openai/client.ts +15 -0
  456. package/src/providers/registry.ts +2 -2
  457. package/src/providers/types.ts +24 -2
  458. package/src/runtime/AGENTS.md +18 -0
  459. package/src/runtime/assistant-event-hub.ts +2 -3
  460. package/src/runtime/assistant-event.ts +4 -4
  461. package/src/runtime/auth/__tests__/context.test.ts +5 -5
  462. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  463. package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -2
  464. package/src/runtime/auth/__tests__/{ipc-auth-context.test.ts → local-auth-context.test.ts} +21 -21
  465. package/src/runtime/auth/__tests__/route-policy.test.ts +2 -2
  466. package/src/runtime/auth/__tests__/scopes.test.ts +7 -7
  467. package/src/runtime/auth/__tests__/subject.test.ts +8 -8
  468. package/src/runtime/auth/__tests__/token-service.test.ts +0 -1
  469. package/src/runtime/auth/route-policy.ts +8 -4
  470. package/src/runtime/auth/scopes.ts +1 -1
  471. package/src/runtime/auth/subject.ts +4 -4
  472. package/src/runtime/auth/token-service.ts +0 -23
  473. package/src/runtime/auth/types.ts +3 -3
  474. package/src/runtime/guardian-action-followup-executor.ts +1 -1
  475. package/src/runtime/guardian-action-grant-minter.ts +1 -1
  476. package/src/runtime/guardian-action-service.ts +3 -3
  477. package/src/runtime/http-server.ts +15 -2
  478. package/src/runtime/invite-service.ts +3 -3
  479. package/src/runtime/local-actor-identity.ts +17 -22
  480. package/src/runtime/pending-interactions.ts +21 -9
  481. package/src/runtime/routes/app-management-routes.ts +2 -3
  482. package/src/runtime/routes/approval-routes.ts +1 -3
  483. package/src/runtime/routes/btw-routes.ts +155 -0
  484. package/src/runtime/routes/computer-use-routes.ts +77 -31
  485. package/src/runtime/routes/conversation-routes.ts +230 -46
  486. package/src/runtime/routes/diagnostics-routes.ts +63 -29
  487. package/src/runtime/routes/documents-routes.ts +2 -2
  488. package/src/runtime/routes/global-search-routes.ts +1 -1
  489. package/src/runtime/routes/host-bash-routes.ts +83 -0
  490. package/src/runtime/routes/host-file-routes.ts +79 -0
  491. package/src/runtime/routes/integrations/slack/share.ts +1 -1
  492. package/src/runtime/routes/log-export-routes.ts +120 -0
  493. package/src/runtime/routes/mcp-routes.ts +20 -0
  494. package/src/runtime/routes/migration-routes.ts +3 -3
  495. package/src/runtime/routes/pairing-routes.ts +1 -1
  496. package/src/runtime/routes/recording-routes.ts +6 -4
  497. package/src/runtime/routes/schedule-routes.ts +31 -5
  498. package/src/runtime/routes/session-management-routes.ts +2 -6
  499. package/src/runtime/routes/session-query-routes.ts +18 -15
  500. package/src/runtime/routes/settings-routes.ts +7 -261
  501. package/src/runtime/routes/skills-routes.ts +7 -6
  502. package/src/runtime/routes/subagents-routes.ts +4 -10
  503. package/src/runtime/routes/surface-action-routes.ts +3 -14
  504. package/src/runtime/routes/surface-content-routes.ts +22 -5
  505. package/src/runtime/routes/work-items-routes.ts +21 -25
  506. package/src/runtime/routes/workspace-routes.test.ts +3 -3
  507. package/src/runtime/routes/workspace-utils.ts +1 -1
  508. package/src/runtime/telegram-streaming-delivery.ts +3 -0
  509. package/src/runtime/verification-outbound-actions.ts +2 -2
  510. package/src/schedule/integration-status.ts +0 -6
  511. package/src/schedule/schedule-store.ts +234 -43
  512. package/src/schedule/scheduler.ts +73 -74
  513. package/src/security/oauth2.ts +1 -1
  514. package/src/sequence/store.ts +12 -2
  515. package/src/skills/frontmatter.ts +19 -77
  516. package/src/skills/managed-store.ts +11 -2
  517. package/src/subagent/manager.ts +5 -3
  518. package/src/tasks/ephemeral-permissions.ts +3 -5
  519. package/src/tools/AGENTS.md +0 -1
  520. package/src/tools/browser/browser-manager.ts +17 -11
  521. package/src/tools/browser/jit-auth.ts +4 -1
  522. package/src/tools/claude-code/claude-code.ts +1 -1
  523. package/src/tools/computer-use/definitions.ts +48 -60
  524. package/src/tools/document/document-tool.ts +6 -6
  525. package/src/tools/filesystem/edit.ts +2 -1
  526. package/src/tools/filesystem/read.ts +20 -2
  527. package/src/tools/filesystem/write.ts +2 -1
  528. package/src/tools/host-filesystem/edit.ts +17 -1
  529. package/src/tools/host-filesystem/read.ts +16 -1
  530. package/src/tools/host-filesystem/write.ts +15 -1
  531. package/src/tools/host-terminal/host-shell.ts +24 -0
  532. package/src/tools/memory/definitions.ts +45 -81
  533. package/src/tools/memory/handlers.test.ts +0 -1
  534. package/src/tools/memory/handlers.ts +1 -1
  535. package/src/tools/memory/register.ts +26 -60
  536. package/src/tools/network/script-proxy/session-manager.ts +6 -8
  537. package/src/tools/network/web-fetch.ts +7 -1
  538. package/src/tools/network/web-search.ts +2 -1
  539. package/src/tools/registry.ts +23 -0
  540. package/src/tools/schedule/create.ts +113 -5
  541. package/src/tools/schedule/list.ts +57 -15
  542. package/src/tools/schedule/update.ts +73 -3
  543. package/src/tools/shared/filesystem/image-read.ts +192 -0
  544. package/src/tools/side-effects.ts +1 -7
  545. package/src/tools/skills/delete-managed.ts +27 -64
  546. package/src/tools/skills/execute.ts +54 -0
  547. package/src/tools/skills/load.ts +127 -5
  548. package/src/tools/skills/scaffold-managed.ts +93 -172
  549. package/src/tools/subagent/message.ts +0 -7
  550. package/src/tools/subagent/spawn.ts +1 -1
  551. package/src/tools/swarm/delegate.ts +0 -3
  552. package/src/tools/system/avatar-generator.ts +13 -19
  553. package/src/tools/system/request-permission.ts +2 -1
  554. package/src/tools/terminal/safe-env.ts +1 -0
  555. package/src/tools/tool-manifest.ts +41 -47
  556. package/src/tools/types.ts +6 -2
  557. package/src/tools/ui-surface/definitions.ts +0 -55
  558. package/src/util/errors.ts +0 -10
  559. package/src/workspace/git-service.ts +0 -2
  560. package/src/__tests__/account-registry.test.ts +0 -258
  561. package/src/__tests__/email-classifier.test.ts +0 -25
  562. package/src/__tests__/gmail-integration.test.ts +0 -97
  563. package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -172
  564. package/src/__tests__/managed-twitter-guardrails.test.ts +0 -357
  565. package/src/__tests__/recording-intent-fallback.test.ts +0 -199
  566. package/src/__tests__/recording-intent.test.ts +0 -985
  567. package/src/__tests__/recording-state-machine.test.ts +0 -1574
  568. package/src/__tests__/reminder-store.test.ts +0 -350
  569. package/src/__tests__/reminder.test.ts +0 -337
  570. package/src/__tests__/scan-result-store.test.ts +0 -121
  571. package/src/__tests__/twitter-platform-proxy-client.test.ts +0 -475
  572. package/src/__tests__/view-image-tool.test.ts +0 -241
  573. package/src/cli/commands/amazon/cart.ts +0 -513
  574. package/src/cli/commands/amazon/checkout.ts +0 -394
  575. package/src/cli/commands/amazon/client.ts +0 -513
  576. package/src/cli/commands/amazon/index.ts +0 -885
  577. package/src/cli/commands/amazon/product-details.ts +0 -145
  578. package/src/cli/commands/amazon/request-extractor.ts +0 -187
  579. package/src/cli/commands/amazon/search.ts +0 -76
  580. package/src/cli/commands/amazon/session.ts +0 -108
  581. package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +0 -345
  582. package/src/cli/commands/twitter/__tests__/cli-routing.test.ts +0 -252
  583. package/src/cli/commands/twitter/__tests__/oauth-client.test.ts +0 -151
  584. package/src/cli/commands/twitter/index.ts +0 -420
  585. package/src/cli/commands/twitter/oauth-client.ts +0 -60
  586. package/src/cli/commands/twitter/router.ts +0 -351
  587. package/src/cli/commands/twitter/types.ts +0 -30
  588. package/src/config/bundled-skills/agentmail/SKILL.md +0 -132
  589. package/src/config/bundled-skills/agentmail/icon.svg +0 -21
  590. package/src/config/bundled-skills/amazon/SKILL.md +0 -136
  591. package/src/config/bundled-skills/amazon/icon.svg +0 -13
  592. package/src/config/bundled-skills/api-mapping/SKILL.md +0 -78
  593. package/src/config/bundled-skills/api-mapping/icon.svg +0 -18
  594. package/src/config/bundled-skills/cli-discover/SKILL.md +0 -68
  595. package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +0 -179
  596. package/src/config/bundled-skills/document-writer/SKILL.md +0 -195
  597. package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +0 -140
  598. package/src/config/bundled-skills/email-setup/SKILL.md +0 -68
  599. package/src/config/bundled-skills/frontend-design/SKILL.md +0 -44
  600. package/src/config/bundled-skills/frontend-design/icon.svg +0 -16
  601. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +0 -452
  602. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +0 -203
  603. package/src/config/bundled-skills/influencer/SKILL.md +0 -144
  604. package/src/config/bundled-skills/influencer/scripts/client.ts +0 -1269
  605. package/src/config/bundled-skills/influencer/scripts/influencer.ts +0 -267
  606. package/src/config/bundled-skills/macos-automation/SKILL.md +0 -65
  607. package/src/config/bundled-skills/macos-automation/icon.svg +0 -12
  608. package/src/config/bundled-skills/mcp-setup/SKILL.md +0 -75
  609. package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +0 -184
  610. package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +0 -80
  611. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +0 -29
  612. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +0 -56
  613. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +0 -34
  614. package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +0 -47
  615. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +0 -31
  616. package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +0 -67
  617. package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +0 -97
  618. package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +0 -87
  619. package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +0 -135
  620. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +0 -24
  621. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +0 -201
  622. package/src/config/bundled-skills/messaging/tools/send-notification.ts +0 -1
  623. package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +0 -27
  624. package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +0 -48
  625. package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +0 -27
  626. package/src/config/bundled-skills/messaging/tools/sequence-update.ts +0 -56
  627. package/src/config/bundled-skills/notion/SKILL.md +0 -240
  628. package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +0 -126
  629. package/src/config/bundled-skills/oauth-setup/SKILL.md +0 -143
  630. package/src/config/bundled-skills/public-ingress/SKILL.md +0 -258
  631. package/src/config/bundled-skills/reminder/SKILL.md +0 -79
  632. package/src/config/bundled-skills/reminder/TOOLS.json +0 -89
  633. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +0 -12
  634. package/src/config/bundled-skills/restaurant-reservation/SKILL.md +0 -141
  635. package/src/config/bundled-skills/screen-recording/SKILL.md +0 -148
  636. package/src/config/bundled-skills/self-upgrade/SKILL.md +0 -69
  637. package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -78
  638. package/src/config/bundled-skills/slack-app-setup/SKILL.md +0 -178
  639. package/src/config/bundled-skills/slack-digest-setup/SKILL.md +0 -163
  640. package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +0 -157
  641. package/src/config/bundled-skills/start-the-day/SKILL.md +0 -70
  642. package/src/config/bundled-skills/start-the-day/icon.svg +0 -13
  643. package/src/config/bundled-skills/telegram-setup/SKILL.md +0 -105
  644. package/src/config/bundled-skills/time-based-actions/SKILL.md +0 -142
  645. package/src/config/bundled-skills/twilio-setup/SKILL.md +0 -232
  646. package/src/config/bundled-skills/twitter/SKILL.md +0 -206
  647. package/src/config/bundled-skills/twitter/icon.svg +0 -14
  648. package/src/config/bundled-skills/typescript-eval/SKILL.md +0 -60
  649. package/src/config/bundled-skills/vercel-token-setup/SKILL.md +0 -214
  650. package/src/config/bundled-skills/voice-setup/SKILL.md +0 -131
  651. package/src/config/bundled-skills/voice-setup/icon.svg +0 -20
  652. package/src/daemon/handlers/pairing.ts +0 -119
  653. package/src/daemon/handlers/session-user-message.ts +0 -961
  654. package/src/daemon/recording-executor.ts +0 -180
  655. package/src/daemon/recording-intent-fallback.ts +0 -162
  656. package/src/daemon/recording-intent.ts +0 -493
  657. package/src/memory/account-store.ts +0 -117
  658. package/src/messaging/activity-analyzer.ts +0 -76
  659. package/src/messaging/email-classifier.ts +0 -208
  660. package/src/messaging/index.ts +0 -2
  661. package/src/messaging/outreach-classifier.ts +0 -185
  662. package/src/messaging/thread-summarizer.ts +0 -346
  663. package/src/messaging/types.ts +0 -17
  664. package/src/tools/browser/x-auto-navigate.ts +0 -254
  665. package/src/tools/credentials/account-registry.ts +0 -144
  666. package/src/tools/filesystem/view-image.ts +0 -244
  667. package/src/tools/reminder/reminder-store.ts +0 -194
  668. package/src/tools/reminder/reminder.ts +0 -158
  669. package/src/tools/system/navigate-settings.ts +0 -74
  670. package/src/tools/system/open-system-settings.ts +0 -85
  671. package/src/tools/system/version.ts +0 -54
  672. package/src/twitter/platform-proxy-client.ts +0 -408
  673. /package/src/config/bundled-skills/{messaging → gmail}/tools/scan-result-store.ts +0 -0
  674. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-analytics.ts +0 -0
  675. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-create.ts +0 -0
  676. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-delete.ts +0 -0
  677. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enroll.ts +0 -0
  678. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enrollment-list.ts +0 -0
  679. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-get.ts +0 -0
  680. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-import.ts +0 -0
  681. /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-list.ts +0 -0
@@ -5,7 +5,8 @@ import type { AssistantConfig } from "../config/schema.js";
5
5
  import { resolveSkillStates, skillFlagKey } from "../config/skill-state.js";
6
6
  import type { SkillSummary } from "../config/skills.js";
7
7
 
8
- const DECLARED_FLAG_KEY = "feature_flags.hatch-new-assistant.enabled";
8
+ const DECLARED_FLAG_ID = "hatch-new-assistant";
9
+ const DECLARED_FLAG_KEY = `feature_flags.${DECLARED_FLAG_ID}.enabled`;
9
10
  const DECLARED_SKILL_ID = "hatch-new-assistant";
10
11
  // ---------------------------------------------------------------------------
11
12
  // Helpers
@@ -37,6 +38,7 @@ function makeConfig(overrides: Partial<AssistantConfig> = {}): AssistantConfig {
37
38
  function makeSkill(
38
39
  id: string,
39
40
  source: "bundled" | "managed" = "bundled",
41
+ featureFlag?: string,
40
42
  ): SkillSummary {
41
43
  return {
42
44
  id,
@@ -49,9 +51,32 @@ function makeSkill(
49
51
  userInvocable: true,
50
52
  disableModelInvocation: false,
51
53
  source,
54
+ featureFlag,
52
55
  };
53
56
  }
54
57
 
58
+ // ---------------------------------------------------------------------------
59
+ // skillFlagKey — unit tests
60
+ // ---------------------------------------------------------------------------
61
+
62
+ describe("skillFlagKey", () => {
63
+ test("returns canonical key when featureFlag is present", () => {
64
+ expect(skillFlagKey({ featureFlag: "my-flag" })).toBe(
65
+ "feature_flags.my-flag.enabled",
66
+ );
67
+ });
68
+
69
+ test("returns undefined when featureFlag is undefined", () => {
70
+ expect(skillFlagKey({ featureFlag: undefined })).toBeUndefined();
71
+ });
72
+
73
+ test("returns undefined when featureFlag field is absent", () => {
74
+ expect(
75
+ skillFlagKey({} as Pick<SkillSummary, "featureFlag">),
76
+ ).toBeUndefined();
77
+ });
78
+ });
79
+
55
80
  // ---------------------------------------------------------------------------
56
81
  // isAssistantFeatureFlagEnabled with skillFlagKey (canonical path)
57
82
  // ---------------------------------------------------------------------------
@@ -60,7 +85,10 @@ describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
60
85
  test("returns false when no flag overrides (registry default is false)", () => {
61
86
  const config = makeConfig();
62
87
  expect(
63
- isAssistantFeatureFlagEnabled(skillFlagKey(DECLARED_SKILL_ID), config),
88
+ isAssistantFeatureFlagEnabled(
89
+ skillFlagKey({ featureFlag: DECLARED_FLAG_ID })!,
90
+ config,
91
+ ),
64
92
  ).toBe(false);
65
93
  });
66
94
 
@@ -69,7 +97,10 @@ describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
69
97
  assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: true },
70
98
  });
71
99
  expect(
72
- isAssistantFeatureFlagEnabled(skillFlagKey(DECLARED_SKILL_ID), config),
100
+ isAssistantFeatureFlagEnabled(
101
+ skillFlagKey({ featureFlag: DECLARED_FLAG_ID })!,
102
+ config,
103
+ ),
73
104
  ).toBe(true);
74
105
  });
75
106
 
@@ -78,7 +109,10 @@ describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
78
109
  assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: false },
79
110
  });
80
111
  expect(
81
- isAssistantFeatureFlagEnabled(skillFlagKey(DECLARED_SKILL_ID), config),
112
+ isAssistantFeatureFlagEnabled(
113
+ skillFlagKey({ featureFlag: DECLARED_FLAG_ID })!,
114
+ config,
115
+ ),
82
116
  ).toBe(false);
83
117
  });
84
118
  });
@@ -137,11 +171,14 @@ describe("isAssistantFeatureFlagEnabled", () => {
137
171
 
138
172
  describe("resolveSkillStates with feature flags", () => {
139
173
  test("flag OFF skill does not appear in resolved list", () => {
140
- const catalog = [makeSkill(DECLARED_SKILL_ID), makeSkill("twitter")];
174
+ const catalog = [
175
+ makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID),
176
+ makeSkill("browser", "bundled", "browser"),
177
+ ];
141
178
  const config = makeConfig({
142
179
  assistantFeatureFlagValues: {
143
180
  [DECLARED_FLAG_KEY]: false,
144
- "feature_flags.twitter.enabled": true,
181
+ "feature_flags.browser.enabled": true,
145
182
  },
146
183
  });
147
184
 
@@ -149,15 +186,18 @@ describe("resolveSkillStates with feature flags", () => {
149
186
  const ids = resolved.map((r) => r.summary.id);
150
187
 
151
188
  expect(ids).not.toContain(DECLARED_SKILL_ID);
152
- expect(ids).toContain("twitter");
189
+ expect(ids).toContain("browser");
153
190
  });
154
191
 
155
192
  test("flag ON skill appears normally", () => {
156
- const catalog = [makeSkill(DECLARED_SKILL_ID), makeSkill("twitter")];
193
+ const catalog = [
194
+ makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID),
195
+ makeSkill("browser", "bundled", "browser"),
196
+ ];
157
197
  const config = makeConfig({
158
198
  assistantFeatureFlagValues: {
159
199
  [DECLARED_FLAG_KEY]: true,
160
- "feature_flags.twitter.enabled": true,
200
+ "feature_flags.browser.enabled": true,
161
201
  },
162
202
  });
163
203
 
@@ -165,11 +205,11 @@ describe("resolveSkillStates with feature flags", () => {
165
205
  const ids = resolved.map((r) => r.summary.id);
166
206
 
167
207
  expect(ids).toContain(DECLARED_SKILL_ID);
168
- expect(ids).toContain("twitter");
208
+ expect(ids).toContain("browser");
169
209
  });
170
210
 
171
211
  test("declared flag key defaults to registry value (false)", () => {
172
- const catalog = [makeSkill(DECLARED_SKILL_ID)];
212
+ const catalog = [makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID)];
173
213
  const config = makeConfig();
174
214
 
175
215
  const resolved = resolveSkillStates(catalog, config);
@@ -177,8 +217,19 @@ describe("resolveSkillStates with feature flags", () => {
177
217
  expect(resolved.length).toBe(0);
178
218
  });
179
219
 
220
+ test("skill without featureFlag is never flag-gated", () => {
221
+ const catalog = [makeSkill("no-flag-skill")];
222
+ const config = makeConfig();
223
+
224
+ const resolved = resolveSkillStates(catalog, config);
225
+ const ids = resolved.map((r) => r.summary.id);
226
+
227
+ // Skills without featureFlag are never gated — always pass through
228
+ expect(ids).toContain("no-flag-skill");
229
+ });
230
+
180
231
  test("feature flag OFF takes precedence over user-enabled config entry", () => {
181
- const catalog = [makeSkill(DECLARED_SKILL_ID)];
232
+ const catalog = [makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID)];
182
233
  const config = makeConfig({
183
234
  assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: false },
184
235
  skills: {
@@ -205,14 +256,14 @@ describe("resolveSkillStates with feature flags", () => {
205
256
 
206
257
  test("multiple skills with mixed flags — persisted overrides respected", () => {
207
258
  const catalog = [
208
- makeSkill(DECLARED_SKILL_ID),
209
- makeSkill("twitter"),
210
- makeSkill("deploy"),
259
+ makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID),
260
+ makeSkill("browser", "bundled", "browser"),
261
+ makeSkill("deploy", "bundled", "deploy"),
211
262
  ];
212
263
  const config = makeConfig({
213
264
  assistantFeatureFlagValues: {
214
265
  [DECLARED_FLAG_KEY]: false,
215
- "feature_flags.twitter.enabled": true,
266
+ "feature_flags.browser.enabled": true,
216
267
  "feature_flags.deploy.enabled": false,
217
268
  },
218
269
  });
@@ -220,7 +271,63 @@ describe("resolveSkillStates with feature flags", () => {
220
271
  const resolved = resolveSkillStates(catalog, config);
221
272
  const ids = resolved.map((r) => r.summary.id);
222
273
 
223
- // hatch-new-assistant and deploy explicitly false; twitter explicitly true
224
- expect(ids).toEqual(["twitter"]);
274
+ // hatch-new-assistant and deploy explicitly false; browser explicitly true
275
+ expect(ids).toEqual(["browser"]);
276
+ });
277
+ });
278
+
279
+ // ---------------------------------------------------------------------------
280
+ // resolveSkillStates — frontmatter featureFlag gating
281
+ // ---------------------------------------------------------------------------
282
+
283
+ describe("resolveSkillStates with frontmatter featureFlag", () => {
284
+ test("skill with featureFlag (defaultEnabled: false) is filtered when no config override", () => {
285
+ // hatch-new-assistant has defaultEnabled: false in the registry
286
+ const catalog = [makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID)];
287
+ const config = makeConfig();
288
+
289
+ const resolved = resolveSkillStates(catalog, config);
290
+ // No override, registry default is false → filtered out
291
+ expect(resolved.length).toBe(0);
292
+ });
293
+
294
+ test("skill with featureFlag is included when config override enables it", () => {
295
+ const catalog = [makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID)];
296
+ const config = makeConfig({
297
+ assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: true },
298
+ });
299
+
300
+ const resolved = resolveSkillStates(catalog, config);
301
+ const ids = resolved.map((r) => r.summary.id);
302
+ expect(ids).toContain(DECLARED_SKILL_ID);
303
+ });
304
+
305
+ test("skill without featureFlag is NEVER filtered by the flag system", () => {
306
+ const catalog = [makeSkill("no-flag-skill")];
307
+ const config = makeConfig();
308
+
309
+ const resolved = resolveSkillStates(catalog, config);
310
+ const ids = resolved.map((r) => r.summary.id);
311
+
312
+ // No featureFlag declared → always passes through regardless of any flags
313
+ expect(ids).toContain("no-flag-skill");
314
+ });
315
+
316
+ test("skill without featureFlag passes through even when feature_flags.<skillId>.enabled is explicitly false", () => {
317
+ // This proves the implicit skillId→flag mapping is gone:
318
+ // setting feature_flags.my-skill.enabled = false has no effect
319
+ // when the skill itself does not declare a featureFlag.
320
+ const catalog = [makeSkill("my-skill")];
321
+ const config = makeConfig({
322
+ assistantFeatureFlagValues: {
323
+ "feature_flags.my-skill.enabled": false,
324
+ },
325
+ });
326
+
327
+ const resolved = resolveSkillStates(catalog, config);
328
+ const ids = resolved.map((r) => r.summary.id);
329
+
330
+ // The skill has no featureFlag field, so it is never gated
331
+ expect(ids).toContain("my-skill");
225
332
  });
226
333
  });
@@ -21,7 +21,6 @@ const platformOverrides: Record<string, (...args: unknown[]) => unknown> = {
21
21
  getRootDir: () => TEST_DIR,
22
22
  getDataDir: () => TEST_DIR,
23
23
  ensureDataDir: () => {},
24
- getSocketPath: () => join(TEST_DIR, "vellum.sock"),
25
24
  getPidPath: () => join(TEST_DIR, "vellum.pid"),
26
25
  getDbPath: () => join(TEST_DIR, "data", "assistant.db"),
27
26
  getLogPath: () => join(TEST_DIR, "logs", "vellum.log"),
@@ -93,7 +92,7 @@ function writeSkill(
93
92
  mkdirSync(skillDir, { recursive: true });
94
93
  writeFileSync(
95
94
  join(skillDir, "SKILL.md"),
96
- `---\nname: "${name}"\ndescription: "${description}"\n---\n\n${body}\n`,
95
+ `---\nname: "${name}"\ndescription: "${description}"\nmetadata: {"vellum":{"feature-flag":"${skillId}"}}\n---\n\n${body}\n`,
97
96
  );
98
97
  }
99
98
 
@@ -1,4 +1,10 @@
1
- import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
1
+ import {
2
+ existsSync,
3
+ mkdirSync,
4
+ rmSync,
5
+ symlinkSync,
6
+ writeFileSync,
7
+ } from "node:fs";
2
8
  import { tmpdir } from "node:os";
3
9
  import { join } from "node:path";
4
10
  import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
@@ -14,7 +20,6 @@ const platformOverrides: Record<string, (...args: unknown[]) => unknown> = {
14
20
  getRootDir: () => TEST_DIR,
15
21
  getDataDir: () => TEST_DIR,
16
22
  ensureDataDir: () => {},
17
- getSocketPath: () => join(TEST_DIR, "vellum.sock"),
18
23
  getPidPath: () => join(TEST_DIR, "vellum.pid"),
19
24
  getDbPath: () => join(TEST_DIR, "data", "assistant.db"),
20
25
  getLogPath: () => join(TEST_DIR, "logs", "vellum.log"),
@@ -93,6 +98,35 @@ function writeSkillWithIncludes(
93
98
  );
94
99
  }
95
100
 
101
+ function writeToolsJson(
102
+ skillId: string,
103
+ tools: Array<{
104
+ name: string;
105
+ description: string;
106
+ category?: string;
107
+ risk?: string;
108
+ input_schema?: Record<string, unknown>;
109
+ executor?: string;
110
+ execution_target?: string;
111
+ }>,
112
+ ): void {
113
+ const skillDir = join(TEST_DIR, "skills", skillId);
114
+ mkdirSync(skillDir, { recursive: true });
115
+ const manifest = {
116
+ version: 1,
117
+ tools: tools.map((t) => ({
118
+ name: t.name,
119
+ description: t.description,
120
+ category: t.category ?? "general",
121
+ risk: t.risk ?? "low",
122
+ input_schema: t.input_schema ?? { type: "object", properties: {} },
123
+ executor: t.executor ?? "scripts/run.sh",
124
+ execution_target: t.execution_target ?? "host",
125
+ })),
126
+ };
127
+ writeFileSync(join(skillDir, "TOOLS.json"), JSON.stringify(manifest));
128
+ }
129
+
96
130
  async function executeSkillLoad(
97
131
  input: Record<string, unknown>,
98
132
  ): Promise<{ content: string; isError: boolean }> {
@@ -614,6 +648,33 @@ describe("skill_load tool", () => {
614
648
  expect(result.content).not.toContain("--- Reference:");
615
649
  });
616
650
 
651
+ test("references/ directory skips symlinked markdown files that escape the skill directory", async () => {
652
+ if (process.platform === "win32") {
653
+ // Symlink creation is not consistently available in Windows test environments.
654
+ return;
655
+ }
656
+
657
+ const skillDir = join(TEST_DIR, "skills", "refs-symlink");
658
+ mkdirSync(skillDir, { recursive: true });
659
+ mkdirSync(join(skillDir, "references"), { recursive: true });
660
+ writeFileSync(
661
+ join(skillDir, "SKILL.md"),
662
+ '---\nname: "Refs Symlink"\ndescription: "Skips symlinks"\n---\n\nBody.\n',
663
+ );
664
+
665
+ const outsideSecretPath = join(TEST_DIR, "outside-secret.md");
666
+ writeFileSync(outsideSecretPath, "TOP_SECRET_DO_NOT_LOAD");
667
+ symlinkSync(outsideSecretPath, join(skillDir, "references", "secret.md"));
668
+
669
+ writeFileSync(join(TEST_DIR, "skills", "SKILLS.md"), "- refs-symlink\n");
670
+
671
+ const result = await executeSkillLoad({ skill: "refs-symlink" });
672
+ expect(result.isError).toBe(false);
673
+ expect(result.content).toContain("Body.");
674
+ expect(result.content).not.toContain("--- Reference: Secret ---");
675
+ expect(result.content).not.toContain("TOP_SECRET_DO_NOT_LOAD");
676
+ });
677
+
617
678
  test("references/ directory ignores non-markdown files", async () => {
618
679
  const skillDir = join(TEST_DIR, "skills", "refs-filter");
619
680
  mkdirSync(skillDir, { recursive: true });
@@ -658,4 +719,135 @@ describe("skill_load tool", () => {
658
719
  /<loaded_skill id="empty-includes" version="v1:[a-f0-9]{64}" \/>/,
659
720
  );
660
721
  });
722
+
723
+ test("skill with TOOLS.json includes tool schemas section in output", async () => {
724
+ writeSkill(
725
+ "skill-with-tools",
726
+ "Skill With Tools",
727
+ "Has tools",
728
+ "Main body.",
729
+ );
730
+ writeToolsJson("skill-with-tools", [
731
+ {
732
+ name: "deploy_app",
733
+ description: "Deploy the application to production",
734
+ input_schema: {
735
+ type: "object",
736
+ properties: {
737
+ environment: {
738
+ type: "string",
739
+ description: "Target environment",
740
+ },
741
+ force: {
742
+ type: "boolean",
743
+ description: "Force deploy even if checks fail",
744
+ },
745
+ },
746
+ required: ["environment"],
747
+ },
748
+ },
749
+ {
750
+ name: "rollback_app",
751
+ description: "Rollback to previous version",
752
+ input_schema: {
753
+ type: "object",
754
+ properties: {
755
+ version: {
756
+ type: "string",
757
+ description: "Version to rollback to",
758
+ },
759
+ },
760
+ required: ["version"],
761
+ },
762
+ },
763
+ ]);
764
+ writeFileSync(
765
+ join(TEST_DIR, "skills", "SKILLS.md"),
766
+ "- skill-with-tools\n",
767
+ );
768
+
769
+ const result = await executeSkillLoad({ skill: "skill-with-tools" });
770
+ expect(result.isError).toBe(false);
771
+
772
+ // Should contain the Available Tools section header
773
+ expect(result.content).toContain("## Available Tools");
774
+
775
+ // Should instruct the LLM to use skill_execute
776
+ expect(result.content).toContain(
777
+ "Use `skill_execute` to call these tools.",
778
+ );
779
+
780
+ // Should contain tool names as headings
781
+ expect(result.content).toContain("### deploy_app");
782
+ expect(result.content).toContain("### rollback_app");
783
+
784
+ // Should contain tool descriptions
785
+ expect(result.content).toContain("Deploy the application to production");
786
+ expect(result.content).toContain("Rollback to previous version");
787
+
788
+ // Should list parameters with types and required/optional markers
789
+ expect(result.content).toContain(
790
+ "- environment (string, required): Target environment",
791
+ );
792
+ expect(result.content).toContain(
793
+ "- force (boolean, optional): Force deploy even if checks fail",
794
+ );
795
+ expect(result.content).toContain(
796
+ "- version (string, required): Version to rollback to",
797
+ );
798
+ });
799
+
800
+ test("skill without TOOLS.json does not include tool schemas section", async () => {
801
+ writeSkill("no-tools", "No Tools", "No tools manifest", "Body.");
802
+ writeFileSync(join(TEST_DIR, "skills", "SKILLS.md"), "- no-tools\n");
803
+
804
+ const result = await executeSkillLoad({ skill: "no-tools" });
805
+ expect(result.isError).toBe(false);
806
+ expect(result.content).not.toContain("## Available Tools");
807
+ expect(result.content).not.toContain("skill_execute");
808
+ });
809
+
810
+ test("included child skill with TOOLS.json has its tool schemas in output", async () => {
811
+ writeSkillWithIncludes(
812
+ "parent-tools",
813
+ "Parent Tools",
814
+ "Parent with tooled child",
815
+ "Parent body.",
816
+ ["child-tools"],
817
+ );
818
+ writeSkill("child-tools", "Child Tools", "Child with tools", "Child body.");
819
+ writeToolsJson("child-tools", [
820
+ {
821
+ name: "child_action",
822
+ description: "A child tool action",
823
+ input_schema: {
824
+ type: "object",
825
+ properties: {
826
+ target: {
827
+ type: "string",
828
+ description: "Action target",
829
+ },
830
+ },
831
+ required: ["target"],
832
+ },
833
+ },
834
+ ]);
835
+ writeFileSync(
836
+ join(TEST_DIR, "skills", "SKILLS.md"),
837
+ "- parent-tools\n- child-tools\n",
838
+ );
839
+
840
+ const result = await executeSkillLoad({ skill: "parent-tools" });
841
+ expect(result.isError).toBe(false);
842
+
843
+ // The child skill's tool schemas should appear (#### level under ### Tools from …)
844
+ expect(result.content).toContain("#### child_action");
845
+ expect(result.content).toContain("A child tool action");
846
+ expect(result.content).toContain(
847
+ "- target (string, required): Action target",
848
+ );
849
+ expect(result.content).toContain(
850
+ "Use `skill_execute` to call these tools.",
851
+ );
852
+ });
661
853
  });
@@ -58,7 +58,10 @@ mock.module("../config/assistant-feature-flags.js", () => ({
58
58
  }));
59
59
 
60
60
  mock.module("../config/skill-state.js", () => ({
61
- skillFlagKey: (skillId: string) => `feature_flags.${skillId}.enabled`,
61
+ skillFlagKey: (skill: { featureFlag?: string }) =>
62
+ skill.featureFlag
63
+ ? `feature_flags.${skill.featureFlag}.enabled`
64
+ : undefined,
62
65
  }));
63
66
 
64
67
  mock.module("../skills/active-skill-tools.js", () => {
@@ -221,7 +224,7 @@ const { projectSkillTools, resetSkillToolProjection } =
221
224
  // Helpers
222
225
  // ---------------------------------------------------------------------------
223
226
 
224
- function makeSkill(id: string): SkillSummary {
227
+ function makeSkill(id: string, featureFlag?: string): SkillSummary {
225
228
  return {
226
229
  id,
227
230
  name: id,
@@ -232,6 +235,7 @@ function makeSkill(id: string): SkillSummary {
232
235
  userInvocable: true,
233
236
  disableModelInvocation: false,
234
237
  source: "managed",
238
+ featureFlag,
235
239
  };
236
240
  }
237
241
 
@@ -293,7 +297,7 @@ describe("projectSkillTools feature flag enforcement", () => {
293
297
  });
294
298
 
295
299
  test("no skill tools projected for flag OFF skill even with old markers", () => {
296
- mockCatalog = [makeSkill(DECLARED_SKILL_ID)];
300
+ mockCatalog = [makeSkill(DECLARED_SKILL_ID, DECLARED_SKILL_ID)];
297
301
  mockManifests = {
298
302
  [DECLARED_SKILL_ID]: makeManifest(["browser_navigate", "browser_click"]),
299
303
  };
@@ -317,7 +321,7 @@ describe("projectSkillTools feature flag enforcement", () => {
317
321
  });
318
322
 
319
323
  test("skill tools projected normally when flag is ON", () => {
320
- mockCatalog = [makeSkill(DECLARED_SKILL_ID)];
324
+ mockCatalog = [makeSkill(DECLARED_SKILL_ID, DECLARED_SKILL_ID)];
321
325
  mockManifests = {
322
326
  [DECLARED_SKILL_ID]: makeManifest(["browser_navigate", "browser_click"]),
323
327
  };
@@ -334,34 +338,41 @@ describe("projectSkillTools feature flag enforcement", () => {
334
338
  previouslyActiveSkillIds: prevActive,
335
339
  });
336
340
 
337
- expect(result.toolDefinitions).toHaveLength(2);
341
+ // Tool definitions are no longer returned (dispatched via skill_execute),
342
+ // but allowedToolNames should contain the registered tool names.
343
+ expect(result.toolDefinitions).toHaveLength(0);
344
+ expect(result.allowedToolNames.size).toBe(2);
338
345
  expect(result.allowedToolNames.has("browser_navigate")).toBe(true);
339
346
  expect(result.allowedToolNames.has("browser_click")).toBe(true);
340
347
  });
341
348
 
342
- test("skill tools projected normally when flag key is absent (defaults to enabled)", () => {
349
+ test("skill tools projected normally when no featureFlag declared (never gated)", () => {
343
350
  mockCatalog = [makeSkill(DECLARED_SKILL_ID)];
344
351
  mockManifests = { [DECLARED_SKILL_ID]: makeManifest(["browser_navigate"]) };
345
352
 
346
353
  const history = buildHistoryWithMarker(DECLARED_SKILL_ID);
347
354
  const prevActive = new Map<string, string>();
348
355
 
349
- // No overrides — should default to enabled
356
+ // No overrides — skill has no featureFlag so it's never gated
350
357
  currentConfig = {};
351
358
 
352
359
  const result = projectSkillTools(history, {
353
360
  previouslyActiveSkillIds: prevActive,
354
361
  });
355
362
 
356
- expect(result.toolDefinitions).toHaveLength(1);
363
+ expect(result.toolDefinitions).toHaveLength(0);
364
+ expect(result.allowedToolNames.size).toBe(1);
357
365
  expect(result.allowedToolNames.has("browser_navigate")).toBe(true);
358
366
  });
359
367
 
360
368
  test("mixed flag-on and flag-off skills — only flag-on tools projected", () => {
361
- mockCatalog = [makeSkill(DECLARED_SKILL_ID), makeSkill("twitter")];
369
+ mockCatalog = [
370
+ makeSkill(DECLARED_SKILL_ID, DECLARED_SKILL_ID),
371
+ makeSkill("plain-skill"),
372
+ ];
362
373
  mockManifests = {
363
374
  [DECLARED_SKILL_ID]: makeManifest(["browser_navigate"]),
364
- twitter: makeManifest(["twitter_post"]),
375
+ "plain-skill": makeManifest(["plain_action"]),
365
376
  };
366
377
 
367
378
  const history: Message[] = [
@@ -393,7 +404,7 @@ describe("projectSkillTools feature flag enforcement", () => {
393
404
  type: "tool_use",
394
405
  id: "tu-2",
395
406
  name: "skill_load",
396
- input: { skill: "twitter" },
407
+ input: { skill: "plain-skill" },
397
408
  },
398
409
  ],
399
410
  },
@@ -404,14 +415,14 @@ describe("projectSkillTools feature flag enforcement", () => {
404
415
  type: "tool_result",
405
416
  tool_use_id: "tu-2",
406
417
  content:
407
- '<loaded_skill id="twitter" version="v1:default-hash-twitter" />',
418
+ '<loaded_skill id="plain-skill" version="v1:default-hash-plain-skill" />',
408
419
  },
409
420
  ],
410
421
  },
411
422
  ];
412
423
  const prevActive = new Map<string, string>();
413
424
 
414
- // Declared skill is OFF, twitter is undeclared with no persisted override so remains ON.
425
+ // Declared skill is OFF, plain-skill is undeclared with no persisted override so remains ON.
415
426
  currentConfig = {
416
427
  assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: false },
417
428
  };
@@ -420,8 +431,8 @@ describe("projectSkillTools feature flag enforcement", () => {
420
431
  previouslyActiveSkillIds: prevActive,
421
432
  });
422
433
 
423
- const toolNames = result.toolDefinitions.map((t) => t.name);
424
- expect(toolNames).toContain("twitter_post");
425
- expect(toolNames).not.toContain("browser_navigate");
434
+ // Tool definitions are no longer returned; check allowedToolNames instead
435
+ expect(result.allowedToolNames.has("plain_action")).toBe(true);
436
+ expect(result.allowedToolNames.has("browser_navigate")).toBe(false);
426
437
  });
427
438
  });
@@ -68,7 +68,10 @@ mock.module("../config/skills.js", () => ({
68
68
  // Mock skill-state.js to break the transitive import chain — the benchmark
69
69
  // only needs skillFlagKey and doesn't exercise resolveSkillStates.
70
70
  mock.module("../config/skill-state.js", () => ({
71
- skillFlagKey: (id: string) => `feature_flags.${id}.enabled`,
71
+ skillFlagKey: (skill: { featureFlag?: string }) =>
72
+ skill.featureFlag
73
+ ? `feature_flags.${skill.featureFlag}.enabled`
74
+ : undefined,
72
75
  resolveSkillStates: () => [],
73
76
  }));
74
77
 
@@ -276,7 +279,6 @@ describe("Skill projection benchmark", () => {
276
279
 
277
280
  const elapsed = timeMs(() => {
278
281
  const result = projectSkillTools(history);
279
- expect(result.toolDefinitions.length).toBeGreaterThan(0);
280
282
  expect(result.allowedToolNames.size).toBeGreaterThan(0);
281
283
  });
282
284
 
@@ -327,12 +329,12 @@ describe("Skill projection benchmark", () => {
327
329
  expect(cache.derived!.entries.length).toBe(entriesCountAfterWarm);
328
330
  expect(cache.derived!.seenIds.size).toBe(seenIdsSizeAfterWarm);
329
331
 
330
- // Assert tool definitions are identical between warm and cached calls
331
- expect(cachedResult!.toolDefinitions.length).toBe(
332
- warmResult.toolDefinitions.length,
332
+ // Assert allowed tool names are identical between warm and cached calls
333
+ expect(cachedResult!.allowedToolNames.size).toBe(
334
+ warmResult.allowedToolNames.size,
333
335
  );
334
- const warmNames = warmResult.toolDefinitions.map((t) => t.name).sort();
335
- const cachedNames = cachedResult!.toolDefinitions.map((t) => t.name).sort();
336
+ const warmNames = [...warmResult.allowedToolNames].sort();
337
+ const cachedNames = [...cachedResult!.allowedToolNames].sort();
336
338
  expect(cachedNames).toEqual(warmNames);
337
339
 
338
340
  console.log(` Cached projection (no change): ${elapsed.toFixed(2)}ms`);
@@ -373,12 +375,12 @@ describe("Skill projection benchmark", () => {
373
375
  expect(cache.derived!.entries.length).toBe(snapshotEntriesCount);
374
376
  expect(cache.derived!.seenIds.size).toBe(snapshotSeenIdsSize);
375
377
 
376
- // Tool definitions must match the first call exactly
377
- expect(result.toolDefinitions.length).toBe(
378
- firstResult.toolDefinitions.length,
378
+ // Allowed tool names must match the first call exactly
379
+ expect(result.allowedToolNames.size).toBe(
380
+ firstResult.allowedToolNames.size,
379
381
  );
380
- expect(result.toolDefinitions.map((t) => t.name).sort()).toEqual(
381
- firstResult.toolDefinitions.map((t) => t.name).sort(),
382
+ expect([...result.allowedToolNames].sort()).toEqual(
383
+ [...firstResult.allowedToolNames].sort(),
382
384
  );
383
385
  }
384
386
  });
@@ -396,7 +398,6 @@ describe("Skill projection benchmark", () => {
396
398
 
397
399
  const elapsed = timeMs(() => {
398
400
  const result = projectSkillTools(history);
399
- expect(result.toolDefinitions.length).toBeGreaterThan(0);
400
401
  expect(result.allowedToolNames.size).toBeGreaterThan(0);
401
402
  });
402
403
 
@@ -429,7 +430,7 @@ describe("Skill projection benchmark", () => {
429
430
  cache,
430
431
  previouslyActiveSkillIds: prevActive,
431
432
  });
432
- expect(result.toolDefinitions.length).toBeGreaterThan(0);
433
+ expect(result.allowedToolNames.size).toBeGreaterThan(0);
433
434
  });
434
435
 
435
436
  console.log(` Incremental scan (10 new msgs): ${elapsed.toFixed(2)}ms`);