@vellumai/assistant 0.5.16 → 0.6.1

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 (592) hide show
  1. package/AGENTS.md +4 -0
  2. package/ARCHITECTURE.md +69 -16
  3. package/Dockerfile +2 -5
  4. package/bun.lock +6 -2
  5. package/docker-entrypoint.sh +32 -1
  6. package/docs/architecture/integrations.md +1 -1
  7. package/docs/architecture/memory.md +21 -24
  8. package/knip.json +2 -1
  9. package/openapi.yaml +1198 -83
  10. package/package.json +5 -1
  11. package/src/__tests__/actor-token-service.test.ts +68 -0
  12. package/src/__tests__/agent-loop.test.ts +0 -32
  13. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  14. package/src/__tests__/anthropic-provider.test.ts +217 -98
  15. package/src/__tests__/app-compiler.test.ts +120 -0
  16. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  17. package/src/__tests__/app-executors.test.ts +47 -1
  18. package/src/__tests__/app-source-watcher.test.ts +159 -0
  19. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  20. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  21. package/src/__tests__/call-domain.test.ts +2 -6
  22. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  23. package/src/__tests__/call-recovery.test.ts +2 -6
  24. package/src/__tests__/call-routes-http.test.ts +2 -6
  25. package/src/__tests__/call-store.test.ts +2 -6
  26. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  27. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  28. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  29. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  30. package/src/__tests__/checker.test.ts +63 -9
  31. package/src/__tests__/clawhub.test.ts +54 -24
  32. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  33. package/src/__tests__/config-schema.test.ts +6 -1
  34. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  35. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  36. package/src/__tests__/contacts-tools.test.ts +31 -0
  37. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  38. package/src/__tests__/context-token-estimator.test.ts +175 -10
  39. package/src/__tests__/conversation-agent-loop-overflow.test.ts +13 -6
  40. package/src/__tests__/conversation-agent-loop.test.ts +13 -51
  41. package/src/__tests__/conversation-attachments.test.ts +2 -6
  42. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  43. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  44. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  45. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  46. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  47. package/src/__tests__/conversation-error.test.ts +33 -2
  48. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  49. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  50. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  51. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  52. package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
  53. package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
  54. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  55. package/src/__tests__/conversation-store.test.ts +2 -6
  56. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
  57. package/src/__tests__/conversation-usage.test.ts +2 -6
  58. package/src/__tests__/conversation-wipe.test.ts +13 -414
  59. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
  60. package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
  61. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  62. package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
  63. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  64. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  65. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  66. package/src/__tests__/date-context.test.ts +76 -210
  67. package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
  68. package/src/__tests__/file-list-tool.test.ts +219 -0
  69. package/src/__tests__/first-greeting.test.ts +1 -1
  70. package/src/__tests__/followup-tools.test.ts +2 -6
  71. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  72. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  73. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  74. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  75. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  76. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  77. package/src/__tests__/guardian-action-store.test.ts +2 -6
  78. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  79. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  80. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  81. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  82. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  83. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  84. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  85. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  86. package/src/__tests__/heartbeat-service.test.ts +180 -3
  87. package/src/__tests__/identity-routes.test.ts +328 -0
  88. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  89. package/src/__tests__/injection-block.test.ts +178 -0
  90. package/src/__tests__/install-meta.test.ts +506 -0
  91. package/src/__tests__/install-skill-routing.test.ts +293 -0
  92. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  93. package/src/__tests__/invite-routes-http.test.ts +2 -6
  94. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +17 -28
  95. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  96. package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
  97. package/src/__tests__/llm-context-normalization.test.ts +18 -18
  98. package/src/__tests__/llm-context-route-provider.test.ts +103 -6
  99. package/src/__tests__/llm-request-log-turn-query.test.ts +164 -6
  100. package/src/__tests__/llm-usage-store.test.ts +2 -6
  101. package/src/__tests__/log-export-workspace.test.ts +74 -111
  102. package/src/__tests__/managed-store.test.ts +38 -11
  103. package/src/__tests__/mcp-abort-signal.test.ts +5 -0
  104. package/src/__tests__/mcp-client-auth.test.ts +5 -0
  105. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  106. package/src/__tests__/memory-recall-log-store.test.ts +134 -6
  107. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  108. package/src/__tests__/migration-export-streaming.test.ts +304 -0
  109. package/src/__tests__/migration-import-commit-http.test.ts +11 -10
  110. package/src/__tests__/mock-fetch.ts +87 -0
  111. package/src/__tests__/non-member-access-request.test.ts +2 -6
  112. package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
  113. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  114. package/src/__tests__/oauth-cli.test.ts +364 -2
  115. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  116. package/src/__tests__/onboarding-template-contract.test.ts +62 -14
  117. package/src/__tests__/outlook-attachments.test.ts +301 -0
  118. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  119. package/src/__tests__/outlook-categories.test.ts +212 -0
  120. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  121. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  122. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  123. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  124. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  125. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  126. package/src/__tests__/outlook-trash.test.ts +77 -0
  127. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  128. package/src/__tests__/parser.test.ts +32 -0
  129. package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
  130. package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
  131. package/src/__tests__/permission-mode-sse.test.ts +418 -0
  132. package/src/__tests__/permission-mode-store.test.ts +277 -0
  133. package/src/__tests__/permission-mode.test.ts +101 -0
  134. package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
  135. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  136. package/src/__tests__/playbook-execution.test.ts +76 -80
  137. package/src/__tests__/playbook-tools.test.ts +5 -7
  138. package/src/__tests__/profiler-routes.test.ts +502 -0
  139. package/src/__tests__/profiler-run-store.test.ts +441 -0
  140. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  141. package/src/__tests__/proxy-approval-callback.test.ts +4 -75
  142. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  143. package/src/__tests__/registry.test.ts +3 -3
  144. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  145. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  146. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  147. package/src/__tests__/sandbox-host-parity.test.ts +5 -4
  148. package/src/__tests__/schedule-store.test.ts +2 -6
  149. package/src/__tests__/schedule-tools.test.ts +2 -6
  150. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  151. package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
  152. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  153. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  154. package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
  155. package/src/__tests__/search-skills-unified.test.ts +422 -0
  156. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  157. package/src/__tests__/send-endpoint-busy.test.ts +44 -9
  158. package/src/__tests__/sequence-store.test.ts +2 -6
  159. package/src/__tests__/server-history-render.test.ts +2 -6
  160. package/src/__tests__/set-permission-mode.test.ts +274 -0
  161. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  162. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  163. package/src/__tests__/skill-load-feature-flag.test.ts +23 -11
  164. package/src/__tests__/skill-memory.test.ts +2 -741
  165. package/src/__tests__/skills-uninstall.test.ts +2 -2
  166. package/src/__tests__/skills.test.ts +1 -1
  167. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  168. package/src/__tests__/strip-memory-injections.test.ts +187 -0
  169. package/src/__tests__/subagent-detail.test.ts +84 -0
  170. package/src/__tests__/subagent-disposal.test.ts +308 -0
  171. package/src/__tests__/subagent-manager-notify.test.ts +19 -10
  172. package/src/__tests__/subagent-notify-parent.test.ts +390 -0
  173. package/src/__tests__/subagent-role-registry.test.ts +108 -0
  174. package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
  175. package/src/__tests__/subagent-tools.test.ts +464 -4
  176. package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
  177. package/src/__tests__/task-compiler.test.ts +2 -6
  178. package/src/__tests__/task-management-tools.test.ts +2 -6
  179. package/src/__tests__/task-memory-cleanup.test.ts +185 -241
  180. package/src/__tests__/task-runner.test.ts +2 -6
  181. package/src/__tests__/task-scheduler.test.ts +2 -6
  182. package/src/__tests__/terminal-tools.test.ts +17 -27
  183. package/src/__tests__/test-preload.ts +7 -0
  184. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  185. package/src/__tests__/tool-executor.test.ts +4 -26
  186. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  187. package/src/__tests__/tool-side-effects-slack-dm.test.ts +277 -0
  188. package/src/__tests__/top-level-renderer.test.ts +10 -13
  189. package/src/__tests__/trust-store.test.ts +1 -1
  190. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  191. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +118 -8
  192. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  193. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  194. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  195. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  196. package/src/__tests__/usage-routes.test.ts +2 -6
  197. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  198. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  199. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  200. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  201. package/src/__tests__/volume-security-guard.test.ts +2 -0
  202. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  203. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  204. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  205. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  206. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
  207. package/src/__tests__/workspace-policy.test.ts +1 -1
  208. package/src/agent/attachments.ts +7 -2
  209. package/src/agent/image-optimize.ts +165 -0
  210. package/src/agent/loop.ts +7 -15
  211. package/src/approvals/guardian-request-resolvers.ts +24 -0
  212. package/src/avatar/traits-png-sync.ts +3 -3
  213. package/src/bundler/app-compiler.ts +179 -2
  214. package/src/bundler/package-resolver.ts +3 -5
  215. package/src/cli/__tests__/notifications.test.ts +1 -2
  216. package/src/cli/__tests__/run-assistant-command.ts +29 -0
  217. package/src/cli/commands/__tests__/email-download.test.ts +245 -0
  218. package/src/cli/commands/__tests__/email-list.test.ts +192 -0
  219. package/src/cli/commands/__tests__/email-register.test.ts +186 -0
  220. package/src/cli/commands/__tests__/email-send.test.ts +291 -0
  221. package/src/cli/commands/__tests__/email-status.test.ts +181 -0
  222. package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
  223. package/src/cli/commands/__tests__/routes.test.ts +562 -0
  224. package/src/cli/commands/avatar.ts +3 -3
  225. package/src/cli/commands/config.ts +26 -13
  226. package/src/cli/commands/conversations.ts +1 -8
  227. package/src/cli/commands/doctor.ts +2 -2
  228. package/src/cli/commands/email.ts +584 -835
  229. package/src/cli/commands/memory.ts +37 -84
  230. package/src/cli/commands/notifications.ts +7 -2
  231. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  232. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  233. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  234. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  235. package/src/cli/commands/oauth/connect.ts +25 -11
  236. package/src/cli/commands/oauth/mode.ts +7 -0
  237. package/src/cli/commands/oauth/shared.ts +39 -3
  238. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  239. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  240. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  241. package/src/cli/commands/platform/index.ts +16 -16
  242. package/src/cli/commands/routes.ts +396 -0
  243. package/src/cli/commands/skills.ts +218 -36
  244. package/src/cli/commands/trust.ts +2 -2
  245. package/src/cli/lib/daemon-credential-client.ts +2 -3
  246. package/src/cli/program.ts +2 -0
  247. package/src/cli.ts +1 -120
  248. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  249. package/src/config/bundled-skills/app-builder/SKILL.md +4 -1
  250. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  251. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  252. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  253. package/src/config/bundled-skills/gmail/SKILL.md +4 -12
  254. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  255. package/src/config/bundled-skills/messaging/SKILL.md +17 -18
  256. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  257. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  258. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  259. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  260. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  261. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  262. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  263. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  264. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  265. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  266. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  267. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  268. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  269. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  270. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  271. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  272. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  273. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  274. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  275. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  276. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  277. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  278. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  279. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  280. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  281. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  282. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  283. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  284. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  285. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  286. package/src/config/bundled-skills/schedule/SKILL.md +22 -2
  287. package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
  288. package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
  289. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
  290. package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
  291. package/src/config/bundled-skills/slack/SKILL.md +3 -7
  292. package/src/config/bundled-skills/subagent/SKILL.md +43 -3
  293. package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
  294. package/src/config/bundled-tool-registry.ts +56 -4
  295. package/src/config/env-registry.ts +78 -8
  296. package/src/config/feature-flag-registry.json +38 -125
  297. package/src/config/schema.ts +8 -0
  298. package/src/config/schemas/filing.ts +51 -0
  299. package/src/config/schemas/heartbeat.ts +15 -12
  300. package/src/config/schemas/memory-lifecycle.ts +12 -0
  301. package/src/config/schemas/platform.ts +8 -0
  302. package/src/config/schemas/security.ts +14 -0
  303. package/src/config/schemas/timeouts.ts +1 -1
  304. package/src/config/skills.ts +18 -7
  305. package/src/context/token-estimator.ts +25 -18
  306. package/src/context/window-manager.ts +6 -2
  307. package/src/credential-execution/process-manager.ts +3 -1
  308. package/src/daemon/app-source-watcher.ts +93 -0
  309. package/src/daemon/config-watcher.ts +79 -1
  310. package/src/daemon/context-overflow-reducer.ts +46 -2
  311. package/src/daemon/conversation-agent-loop-handlers.ts +143 -82
  312. package/src/daemon/conversation-agent-loop.ts +236 -108
  313. package/src/daemon/conversation-error.ts +31 -8
  314. package/src/daemon/conversation-history.ts +4 -19
  315. package/src/daemon/conversation-lifecycle.ts +36 -9
  316. package/src/daemon/conversation-media-retry.ts +85 -7
  317. package/src/daemon/conversation-notifiers.ts +4 -1
  318. package/src/daemon/conversation-process.ts +13 -7
  319. package/src/daemon/conversation-runtime-assembly.ts +305 -306
  320. package/src/daemon/conversation-tool-setup.ts +44 -14
  321. package/src/daemon/conversation-workspace.ts +1 -2
  322. package/src/daemon/conversation.ts +59 -2
  323. package/src/daemon/daemon-control.ts +8 -2
  324. package/src/daemon/date-context.ts +26 -53
  325. package/src/daemon/first-greeting.ts +1 -1
  326. package/src/daemon/handlers/conversations.ts +4 -7
  327. package/src/daemon/handlers/shared.test.ts +143 -0
  328. package/src/daemon/handlers/shared.ts +85 -17
  329. package/src/daemon/handlers/skills.ts +416 -209
  330. package/src/daemon/lifecycle.ts +212 -131
  331. package/src/daemon/main.ts +5 -1
  332. package/src/daemon/message-types/conversations.ts +29 -7
  333. package/src/daemon/message-types/messages.ts +12 -2
  334. package/src/daemon/message-types/schedules.ts +1 -0
  335. package/src/daemon/message-types/settings.ts +6 -0
  336. package/src/daemon/message-types/skills.ts +97 -36
  337. package/src/daemon/profiler-run-store.ts +557 -0
  338. package/src/daemon/providers-setup.ts +5 -0
  339. package/src/daemon/server.ts +100 -11
  340. package/src/daemon/shutdown-handlers.ts +5 -0
  341. package/src/daemon/tool-side-effects.ts +50 -8
  342. package/src/export/transcript-formatter.ts +148 -0
  343. package/src/filing/filing-service.ts +228 -0
  344. package/src/heartbeat/heartbeat-service.ts +97 -7
  345. package/src/hooks/cli.ts +2 -2
  346. package/src/hooks/runner.ts +15 -38
  347. package/src/inbound/platform-callback-registration.ts +14 -14
  348. package/src/mcp/client.ts +6 -0
  349. package/src/mcp/mcp-oauth-provider.ts +149 -27
  350. package/src/memory/admin.ts +42 -75
  351. package/src/memory/app-store.ts +69 -0
  352. package/src/memory/conversation-bootstrap.ts +3 -1
  353. package/src/memory/conversation-crud.ts +211 -288
  354. package/src/memory/conversation-group-migration.ts +157 -0
  355. package/src/memory/conversation-queries.ts +61 -13
  356. package/src/memory/conversation-title-service.ts +1 -0
  357. package/src/memory/db-init.ts +194 -361
  358. package/src/memory/embed.ts +73 -0
  359. package/src/memory/embedding-backend.ts +8 -14
  360. package/src/memory/embedding-runtime-manager.ts +12 -114
  361. package/src/memory/fingerprint.ts +2 -2
  362. package/src/memory/graph/bootstrap.ts +521 -0
  363. package/src/memory/graph/capability-seed.ts +449 -0
  364. package/src/memory/graph/consolidation.ts +725 -0
  365. package/src/memory/graph/conversation-graph-memory.ts +659 -0
  366. package/src/memory/graph/decay.test.ts +208 -0
  367. package/src/memory/graph/decay.ts +195 -0
  368. package/src/memory/graph/extraction-job.ts +74 -0
  369. package/src/memory/graph/extraction.test.ts +936 -0
  370. package/src/memory/graph/extraction.ts +1297 -0
  371. package/src/memory/graph/graph-memory-state-store.ts +37 -0
  372. package/src/memory/graph/graph-search.ts +280 -0
  373. package/src/memory/graph/image-ref-utils.ts +29 -0
  374. package/src/memory/graph/injection.test.ts +513 -0
  375. package/src/memory/graph/injection.ts +469 -0
  376. package/src/memory/graph/inspect.ts +543 -0
  377. package/src/memory/graph/narrative.ts +267 -0
  378. package/src/memory/graph/pattern-scan.ts +269 -0
  379. package/src/memory/graph/retriever.ts +1111 -0
  380. package/src/memory/graph/scoring.test.ts +548 -0
  381. package/src/memory/graph/scoring.ts +232 -0
  382. package/src/memory/graph/serendipity.ts +65 -0
  383. package/src/memory/graph/store.test.ts +1098 -0
  384. package/src/memory/graph/store.ts +838 -0
  385. package/src/memory/graph/tool-handlers.ts +301 -0
  386. package/src/memory/graph/tools.ts +97 -0
  387. package/src/memory/graph/triggers.test.ts +487 -0
  388. package/src/memory/graph/triggers.ts +223 -0
  389. package/src/memory/graph/types.ts +295 -0
  390. package/src/memory/group-crud.ts +191 -0
  391. package/src/memory/indexer.ts +37 -19
  392. package/src/memory/job-handlers/cleanup.ts +32 -42
  393. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  394. package/src/memory/job-handlers/embedding.ts +5 -31
  395. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  396. package/src/memory/job-handlers/summarization.ts +32 -17
  397. package/src/memory/job-utils.ts +1 -1
  398. package/src/memory/jobs-store.ts +21 -31
  399. package/src/memory/jobs-worker.ts +180 -129
  400. package/src/memory/llm-request-log-store.ts +96 -12
  401. package/src/memory/memory-recall-log-store.ts +49 -5
  402. package/src/memory/message-content.ts +1 -0
  403. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  404. package/src/memory/migrations/203-drop-memory-items-tables.ts +55 -0
  405. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  406. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  407. package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
  408. package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
  409. package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
  410. package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
  411. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
  412. package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
  413. package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
  414. package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
  415. package/src/memory/migrations/index.ts +12 -0
  416. package/src/memory/migrations/registry.ts +16 -0
  417. package/src/memory/qdrant-client.ts +44 -17
  418. package/src/memory/schema/conversations.ts +14 -0
  419. package/src/memory/schema/index.ts +1 -0
  420. package/src/memory/schema/infrastructure.ts +8 -1
  421. package/src/memory/schema/memory-core.ts +0 -51
  422. package/src/memory/schema/memory-graph.ts +154 -0
  423. package/src/memory/search/semantic.ts +47 -91
  424. package/src/memory/task-memory-cleanup.ts +58 -61
  425. package/src/messaging/providers/outlook/adapter.ts +8 -1
  426. package/src/messaging/providers/outlook/client.ts +299 -0
  427. package/src/messaging/providers/outlook/types.ts +118 -0
  428. package/src/notifications/adapters/macos.ts +1 -0
  429. package/src/notifications/copy-composer.ts +95 -0
  430. package/src/notifications/decision-engine.ts +35 -0
  431. package/src/notifications/signal.ts +16 -0
  432. package/src/oauth/seed-providers.ts +2 -1
  433. package/src/permissions/checker.ts +36 -4
  434. package/src/permissions/defaults.ts +4 -4
  435. package/src/permissions/permission-mode-store.ts +180 -0
  436. package/src/permissions/permission-mode.ts +31 -0
  437. package/src/permissions/workspace-policy.ts +10 -1
  438. package/src/playbooks/playbook-compiler.ts +19 -18
  439. package/src/playbooks/types.ts +4 -3
  440. package/src/prompts/system-prompt.ts +62 -36
  441. package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
  442. package/src/prompts/templates/BOOTSTRAP.md +70 -165
  443. package/src/prompts/templates/HEARTBEAT.md +3 -1
  444. package/src/prompts/templates/SOUL.md +25 -4
  445. package/src/prompts/templates/UPDATES.md +8 -0
  446. package/src/providers/anthropic/client.ts +136 -220
  447. package/src/providers/gemini/client.ts +1 -1
  448. package/src/providers/openai/client.ts +1 -1
  449. package/src/providers/registry.ts +1 -1
  450. package/src/providers/retry.ts +19 -3
  451. package/src/runtime/actor-trust-resolver.ts +5 -1
  452. package/src/runtime/auth/route-policy.ts +30 -0
  453. package/src/runtime/guardian-reply-router.ts +5 -1
  454. package/src/runtime/http-server.ts +55 -5
  455. package/src/runtime/http-types.ts +12 -1
  456. package/src/runtime/middleware/auth.ts +20 -0
  457. package/src/runtime/migrations/vbundle-builder.ts +389 -3
  458. package/src/runtime/migrations/vbundle-importer.ts +8 -6
  459. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
  460. package/src/runtime/routes/app-management-routes.ts +1 -11
  461. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
  462. package/src/runtime/routes/archive-utils.ts +29 -0
  463. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  464. package/src/runtime/routes/attachment-routes.ts +106 -16
  465. package/src/runtime/routes/avatar-routes.ts +2 -9
  466. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  467. package/src/runtime/routes/btw-routes.ts +22 -1
  468. package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
  469. package/src/runtime/routes/conversation-management-routes.ts +3 -14
  470. package/src/runtime/routes/conversation-query-routes.ts +49 -3
  471. package/src/runtime/routes/conversation-routes.ts +264 -44
  472. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  473. package/src/runtime/routes/debug-routes.ts +1 -1
  474. package/src/runtime/routes/global-search-routes.ts +21 -19
  475. package/src/runtime/routes/group-routes.ts +207 -0
  476. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  477. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  478. package/src/runtime/routes/heartbeat-routes.ts +4 -10
  479. package/src/runtime/routes/identity-routes.ts +53 -18
  480. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  481. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  482. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  483. package/src/runtime/routes/llm-context-normalization.ts +14 -10
  484. package/src/runtime/routes/log-export-routes.ts +23 -275
  485. package/src/runtime/routes/memory-item-routes.test.ts +170 -247
  486. package/src/runtime/routes/memory-item-routes.ts +341 -388
  487. package/src/runtime/routes/migration-routes.ts +18 -7
  488. package/src/runtime/routes/profiler-routes.ts +350 -0
  489. package/src/runtime/routes/schedule-routes.ts +28 -11
  490. package/src/runtime/routes/settings-routes.ts +95 -8
  491. package/src/runtime/routes/skills-routes.ts +103 -37
  492. package/src/runtime/routes/subagents-routes.ts +28 -7
  493. package/src/runtime/routes/user-route-dispatcher.ts +223 -0
  494. package/src/runtime/routes/user-routes.ts +41 -0
  495. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  496. package/src/runtime/routes/workspace-routes.ts +0 -1
  497. package/src/schedule/schedule-store.ts +30 -0
  498. package/src/schedule/scheduler.ts +52 -18
  499. package/src/security/oauth2.ts +1 -1
  500. package/src/security/secure-keys.ts +4 -8
  501. package/src/shared/provider-env-vars.ts +19 -0
  502. package/src/skills/catalog-cache.ts +5 -0
  503. package/src/skills/catalog-install.ts +25 -16
  504. package/src/skills/clawhub.ts +134 -154
  505. package/src/skills/install-meta.ts +208 -0
  506. package/src/skills/managed-store.ts +29 -18
  507. package/src/skills/skill-memory.ts +12 -229
  508. package/src/skills/skillssh-registry.ts +19 -17
  509. package/src/subagent/index.ts +13 -3
  510. package/src/subagent/manager.ts +308 -29
  511. package/src/subagent/types.ts +68 -0
  512. package/src/tasks/task-runner.ts +7 -5
  513. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  514. package/src/tools/apps/executors.ts +29 -4
  515. package/src/tools/browser/runtime-check.ts +3 -1
  516. package/src/tools/filesystem/list.ts +93 -0
  517. package/src/tools/memory/register.ts +63 -46
  518. package/src/tools/permission-checker.ts +85 -1
  519. package/src/tools/registry.ts +4 -0
  520. package/src/tools/schedule/create.ts +3 -0
  521. package/src/tools/schedule/list.ts +1 -0
  522. package/src/tools/schedule/update.ts +6 -0
  523. package/src/tools/shared/filesystem/errors.ts +5 -0
  524. package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
  525. package/src/tools/shared/filesystem/image-read.ts +22 -85
  526. package/src/tools/shared/filesystem/types.ts +17 -0
  527. package/src/tools/shared/shell-output.ts +31 -2
  528. package/src/tools/subagent/abort.ts +12 -2
  529. package/src/tools/subagent/message.ts +9 -2
  530. package/src/tools/subagent/notify-parent.ts +79 -0
  531. package/src/tools/subagent/read.ts +29 -8
  532. package/src/tools/subagent/resolve.ts +21 -0
  533. package/src/tools/subagent/spawn.ts +2 -0
  534. package/src/tools/subagent/status.ts +11 -1
  535. package/src/tools/system/avatar-generator.ts +3 -3
  536. package/src/tools/system/register.ts +23 -0
  537. package/src/tools/system/set-permission-mode.ts +103 -0
  538. package/src/tools/terminal/parser.ts +30 -5
  539. package/src/tools/terminal/safe-env.ts +17 -1
  540. package/src/tools/tool-manifest.ts +9 -3
  541. package/src/tools/types.ts +2 -0
  542. package/src/util/browser.ts +25 -10
  543. package/src/util/bun-runtime.ts +172 -0
  544. package/src/util/logger.ts +1 -1
  545. package/src/util/platform.ts +50 -17
  546. package/src/watcher/providers/outlook-calendar.ts +343 -0
  547. package/src/watcher/providers/outlook.ts +198 -0
  548. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
  549. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
  550. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  551. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  552. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  553. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
  554. package/src/workspace/migrations/029-seed-pkb.ts +84 -0
  555. package/src/workspace/migrations/registry.ts +10 -0
  556. package/src/workspace/top-level-renderer.ts +5 -9
  557. package/src/__tests__/cli-memory.test.ts +0 -372
  558. package/src/__tests__/clipboard.test.ts +0 -88
  559. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  560. package/src/__tests__/journal-context.test.ts +0 -268
  561. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  562. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  563. package/src/__tests__/memory-query-builder.test.ts +0 -59
  564. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  565. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  566. package/src/__tests__/memory-regressions.test.ts +0 -3696
  567. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  568. package/src/cli/cli-memory.ts +0 -176
  569. package/src/daemon/conversation-memory.ts +0 -207
  570. package/src/memory/conversation-starters-cadence.ts +0 -74
  571. package/src/memory/items-extractor.ts +0 -860
  572. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  573. package/src/memory/job-handlers/extraction.ts +0 -40
  574. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  575. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  576. package/src/memory/journal-memory.ts +0 -224
  577. package/src/memory/query-builder.ts +0 -47
  578. package/src/memory/query-expansion.ts +0 -83
  579. package/src/memory/retriever.test.ts +0 -1592
  580. package/src/memory/retriever.ts +0 -1331
  581. package/src/memory/search/formatting.test.ts +0 -140
  582. package/src/memory/search/formatting.ts +0 -262
  583. package/src/memory/search/mmr.ts +0 -139
  584. package/src/memory/search/ranking.ts +0 -15
  585. package/src/memory/search/staleness.ts +0 -40
  586. package/src/memory/search/tier-classifier.ts +0 -18
  587. package/src/memory/search/types.ts +0 -121
  588. package/src/prompts/journal-context.ts +0 -154
  589. package/src/tools/memory/definitions.ts +0 -69
  590. package/src/tools/memory/handlers.test.ts +0 -562
  591. package/src/tools/memory/handlers.ts +0 -434
  592. package/src/util/clipboard.ts +0 -34
@@ -1,6 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
+ import { ensureBun } from "../../util/bun-runtime.js";
4
5
  import { getExternalDir } from "../../util/platform.js";
5
6
 
6
7
  export interface BrowserRuntimeStatus {
@@ -83,7 +84,8 @@ export async function importPlaywright(): Promise<typeof import("playwright")> {
83
84
  if (!existsSync(join(externalDir, "package.json"))) {
84
85
  writeFileSync(join(externalDir, "package.json"), '{"private":true}\n');
85
86
  }
86
- const proc = Bun.spawn(["bun", "add", "playwright"], {
87
+ const bunPath = await ensureBun();
88
+ const proc = Bun.spawn([bunPath, "add", "playwright"], {
87
89
  cwd: externalDir,
88
90
  stdout: "pipe",
89
91
  stderr: "pipe",
@@ -0,0 +1,93 @@
1
+ import { RiskLevel } from "../../permissions/types.js";
2
+ import type { ToolDefinition } from "../../providers/types.js";
3
+ import { registerTool } from "../registry.js";
4
+ import { FileSystemOps } from "../shared/filesystem/file-ops-service.js";
5
+ import { sandboxPolicy } from "../shared/filesystem/path-policy.js";
6
+ import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
7
+
8
+ class FileListTool implements Tool {
9
+ name = "file_list";
10
+ description =
11
+ "List the contents of a directory. Returns file and subdirectory names with type indicators and sizes.";
12
+ category = "filesystem";
13
+ defaultRiskLevel = RiskLevel.Low;
14
+
15
+ getDefinition(): ToolDefinition {
16
+ return {
17
+ name: this.name,
18
+ description: this.description,
19
+ input_schema: {
20
+ type: "object",
21
+ properties: {
22
+ path: {
23
+ type: "string",
24
+ description: "The directory path to list",
25
+ },
26
+ glob: {
27
+ type: "string",
28
+ description: "Filter entries by glob pattern, e.g. '*.md'",
29
+ },
30
+ activity: {
31
+ type: "string",
32
+ description:
33
+ "Brief non-technical explanation of what you are doing and why, shown to the user as a status update.",
34
+ },
35
+ },
36
+ required: ["path", "activity"],
37
+ },
38
+ };
39
+ }
40
+
41
+ async execute(
42
+ input: Record<string, unknown>,
43
+ context: ToolContext,
44
+ ): Promise<ToolExecutionResult> {
45
+ const rawPath = input.path as string;
46
+ if (!rawPath || typeof rawPath !== "string") {
47
+ return {
48
+ content: "Error: path is required and must be a string",
49
+ isError: true,
50
+ };
51
+ }
52
+
53
+ const ops = new FileSystemOps((path, opts) =>
54
+ sandboxPolicy(path, context.workingDir, opts),
55
+ );
56
+
57
+ const result = ops.listDirSafe({
58
+ path: rawPath,
59
+ glob: typeof input.glob === "string" ? input.glob : undefined,
60
+ });
61
+
62
+ if (!result.ok) {
63
+ const { error } = result;
64
+ switch (error.code) {
65
+ case "NOT_A_DIRECTORY":
66
+ return {
67
+ content: `Error: ${error.path} is not a directory`,
68
+ isError: true,
69
+ };
70
+ case "NOT_FOUND":
71
+ return {
72
+ content: `Error: directory not found: ${error.path}`,
73
+ isError: true,
74
+ };
75
+ default: {
76
+ const hint =
77
+ error.code === "PATH_OUT_OF_BOUNDS"
78
+ ? ". To list files outside the workspace, use the host_bash tool instead."
79
+ : "";
80
+ return {
81
+ content: `Error: ${error.message}${hint}`,
82
+ isError: true,
83
+ };
84
+ }
85
+ }
86
+ }
87
+
88
+ return { content: result.value.listing, isError: false };
89
+ }
90
+ }
91
+
92
+ export const fileListTool = new FileListTool();
93
+ registerTool(fileListTool);
@@ -1,67 +1,56 @@
1
1
  import { getConfig } from "../../config/loader.js";
2
+ import {
3
+ handleRecall,
4
+ handleRemember,
5
+ type RecallInput,
6
+ type RememberInput,
7
+ } from "../../memory/graph/tool-handlers.js";
8
+ import {
9
+ graphRecallDefinition,
10
+ graphRememberDefinition,
11
+ } from "../../memory/graph/tools.js";
2
12
  import { RiskLevel } from "../../permissions/types.js";
3
13
  import type { ToolDefinition } from "../../providers/types.js";
4
14
  import type { Tool, ToolContext, ToolExecutionResult } from "../types.js";
5
- import {
6
- memoryManageDefinition,
7
- memoryRecallDefinition,
8
- } from "./definitions.js";
9
- import {
10
- handleMemoryDelete,
11
- handleMemoryRecall,
12
- handleMemorySave,
13
- handleMemoryUpdate,
14
- } from "./handlers.js";
15
15
 
16
- // ── memory_manage ────────────────────────────────────────────────────
16
+ // ── remember ────────────────────────────────────────────────────────
17
17
 
18
- class MemoryManageTool implements Tool {
19
- name = "memory_manage";
20
- description = memoryManageDefinition.description;
18
+ class RememberTool implements Tool {
19
+ name = "remember";
20
+ description = graphRememberDefinition.description;
21
21
  category = "memory";
22
22
  defaultRiskLevel = RiskLevel.Low;
23
23
 
24
24
  getDefinition(): ToolDefinition {
25
- return memoryManageDefinition;
25
+ return graphRememberDefinition;
26
26
  }
27
27
 
28
28
  async execute(
29
29
  input: Record<string, unknown>,
30
30
  context: ToolContext,
31
31
  ): Promise<ToolExecutionResult> {
32
- const config = getConfig();
33
- switch (input.op) {
34
- case "save":
35
- return handleMemorySave(
36
- input,
37
- config,
38
- context.conversationId,
39
- context.requestId,
40
- context.memoryScopeId,
41
- );
42
- case "update":
43
- return handleMemoryUpdate(input, config, context.memoryScopeId);
44
- case "delete":
45
- return handleMemoryDelete(input, config, context.memoryScopeId);
46
- default:
47
- return {
48
- content: `Error: unknown op "${input.op}". Must be one of: save, update, delete`,
49
- isError: true,
50
- };
51
- }
32
+ const result = handleRemember(
33
+ input as unknown as RememberInput,
34
+ context.conversationId,
35
+ context.memoryScopeId ?? "default",
36
+ );
37
+ return {
38
+ content: result.message,
39
+ isError: !result.success,
40
+ };
52
41
  }
53
42
  }
54
43
 
55
- // ── memory_recall ────────────────────────────────────────────────────
44
+ // ── recall ──────────────────────────────────────────────────────────
56
45
 
57
- class MemoryRecallTool implements Tool {
58
- name = "memory_recall";
59
- description = memoryRecallDefinition.description;
46
+ class RecallTool implements Tool {
47
+ name = "recall";
48
+ description = graphRecallDefinition.description;
60
49
  category = "memory";
61
50
  defaultRiskLevel = RiskLevel.Low;
62
51
 
63
52
  getDefinition(): ToolDefinition {
64
- return memoryRecallDefinition;
53
+ return graphRecallDefinition;
65
54
  }
66
55
 
67
56
  async execute(
@@ -69,16 +58,44 @@ class MemoryRecallTool implements Tool {
69
58
  context: ToolContext,
70
59
  ): Promise<ToolExecutionResult> {
71
60
  const config = getConfig();
72
- return handleMemoryRecall(
73
- input,
61
+ const result = await handleRecall(
62
+ input as unknown as RecallInput,
74
63
  config,
75
- context.memoryScopeId,
76
- context.conversationId,
64
+ context.memoryScopeId ?? "default",
77
65
  );
66
+
67
+ if (result.results.length === 0) {
68
+ return { content: "No results found.", isError: false };
69
+ }
70
+
71
+ const formatted = result.results
72
+ .map((r) => {
73
+ const ts = formatTimestamp(r.created);
74
+ const meta =
75
+ result.mode === "memory"
76
+ ? `[${r.type}] ${ts} (confidence: ${r.confidence.toFixed(2)}, score: ${r.score.toFixed(3)})`
77
+ : `[archive] ${ts}`;
78
+ return `${meta}\n${r.content}`;
79
+ })
80
+ .join("\n\n---\n\n");
81
+
82
+ return { content: formatted, isError: false };
78
83
  }
79
84
  }
80
85
 
86
+ // ── Helpers ─────────────────────────────────────────────────────────
87
+
88
+ function formatTimestamp(epochMs: number): string {
89
+ const d = new Date(epochMs);
90
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
91
+ const dd = String(d.getDate()).padStart(2, "0");
92
+ const yy = String(d.getFullYear()).slice(-2);
93
+ const hh = String(d.getHours()).padStart(2, "0");
94
+ const min = String(d.getMinutes()).padStart(2, "0");
95
+ return `${mm}/${dd}/${yy} ${hh}:${min}`;
96
+ }
97
+
81
98
  // ── Exported tool instances ──────────────────────────────────────────
82
99
 
83
- export const memoryManageTool = new MemoryManageTool();
84
- export const memoryRecallTool = new MemoryRecallTool();
100
+ export const rememberTool = new RememberTool();
101
+ export const recallTool = new RecallTool();
@@ -1,3 +1,4 @@
1
+ import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
1
2
  import { getConfig } from "../config/loader.js";
2
3
  import { getHookManager } from "../hooks/manager.js";
3
4
  import {
@@ -6,8 +7,11 @@ import {
6
7
  generateAllowlistOptions,
7
8
  generateScopeOptions,
8
9
  } from "../permissions/checker.js";
10
+ import { getMode } from "../permissions/permission-mode-store.js";
9
11
  import type { PermissionPrompter } from "../permissions/prompter.js";
10
12
  import { addRule } from "../permissions/trust-store.js";
13
+ import { RiskLevel } from "../permissions/types.js";
14
+ import { isHostTool } from "../permissions/workspace-policy.js";
11
15
  import {
12
16
  getEffectiveMode,
13
17
  setConversationMode,
@@ -64,6 +68,52 @@ export class PermissionChecker {
64
68
  }
65
69
  | undefined,
66
70
  ): Promise<PermissionDecision> {
71
+ // ── permission-controls-v2 early gate ──────────────────────────────
72
+ // When the v2 flag is enabled, replace the entire risk-classification
73
+ // path with a simple binary check: is it a host tool + is host access
74
+ // enabled? Certain security gates (requireFreshApproval,
75
+ // forcePromptSideEffects, hostAccess=false) fall through to the v1
76
+ // prompt flow so the interactive prompter is engaged.
77
+ const cfg = getConfig();
78
+ let v2ForcePrompt = false;
79
+ if (isAssistantFeatureFlagEnabled("permission-controls-v2", cfg)) {
80
+ // requireFreshApproval demands an interactive prompt every time —
81
+ // fall through to v1 so the prompter is engaged.
82
+ const needsFreshApproval = !!context.requireFreshApproval;
83
+
84
+ // forcePromptSideEffects (private conversations, untrusted actors)
85
+ // requires explicit approval for side-effect tools.
86
+ const needsSideEffectPrompt =
87
+ !!context.forcePromptSideEffects && isSideEffectTool(name, input);
88
+
89
+ if (!needsFreshApproval && !needsSideEffectPrompt) {
90
+ if (isHostTool(name)) {
91
+ const mode = getMode();
92
+ if (mode.hostAccess) {
93
+ return {
94
+ allowed: true,
95
+ decision: "allow",
96
+ riskLevel: RiskLevel.Low,
97
+ };
98
+ }
99
+ // Host tool with hostAccess disabled — fall through to v1 so the
100
+ // interactive prompter is engaged (returning allowed:false here
101
+ // would surface an error string instead of a permission dialog).
102
+ // The v2ForcePrompt flag ensures check()'s allow decision is
103
+ // promoted to prompt so the user sees a permission dialog.
104
+ v2ForcePrompt = true;
105
+ } else {
106
+ // Non-host tools are auto-allowed when v2 is on
107
+ return {
108
+ allowed: true,
109
+ decision: "allow",
110
+ riskLevel: RiskLevel.Low,
111
+ };
112
+ }
113
+ }
114
+ // Falls through to the v1 risk-classification + prompter path
115
+ }
116
+
67
117
  const risk = await classifyRisk(
68
118
  name,
69
119
  input,
@@ -113,6 +163,14 @@ export class PermissionChecker {
113
163
  "Fresh approval required: per-invocation human review enforced";
114
164
  }
115
165
 
166
+ // v2 host-access-disabled: the v2 gate fell through because
167
+ // hostAccess is off. Promote allow → prompt so the user sees an
168
+ // interactive permission dialog instead of an error string.
169
+ if (v2ForcePrompt && result.decision === "allow") {
170
+ result.decision = "prompt";
171
+ result.reason = "Host access disabled: requires explicit approval";
172
+ }
173
+
116
174
  if (result.decision === "deny") {
117
175
  const durationMs = Date.now() - startTime;
118
176
  emitLifecycleEvent({
@@ -136,6 +194,26 @@ export class PermissionChecker {
136
194
  };
137
195
  }
138
196
 
197
+ // Platform-hosted mode: auto-approve sandboxed bash for guardians.
198
+ // The sandbox provides the security boundary — prompting is unnecessary
199
+ // friction. host_bash is excluded because it runs unsandboxed on the
200
+ // user's machine and warrants explicit approval.
201
+ // Deny rules are still respected (checked above). requireFreshApproval
202
+ // is preserved as a belt-and-suspenders guard.
203
+ if (
204
+ result.decision === "prompt" &&
205
+ context.isPlatformHosted &&
206
+ name === "bash" &&
207
+ context.trustClass === "guardian" &&
208
+ !context.requireFreshApproval
209
+ ) {
210
+ log.info(
211
+ { toolName: name, riskLevel },
212
+ "Auto-approving bash tool for platform-hosted guardian session",
213
+ );
214
+ return { allowed: true, decision: "platform_auto_approve", riskLevel };
215
+ }
216
+
139
217
  if (result.decision === "prompt") {
140
218
  // Guardian-trust sessions (e.g. scheduled jobs, reminders) should be
141
219
  // able to use bundled tools without interactive approval. The guardian
@@ -145,6 +223,10 @@ export class PermissionChecker {
145
223
  // Exception: inline-command skill loads (skill_load_dynamic:*) must
146
224
  // never be silently auto-approved — they execute embedded commands
147
225
  // and require explicit human review or a pinned trust rule.
226
+ // Exception: high-risk tools (e.g. destructive shell commands, writes
227
+ // to sensitive paths) are denied — unattended sessions must not
228
+ // auto-approve operations that could cause significant damage if
229
+ // triggered by prompt injection from untrusted content.
148
230
  const isDynamicSkillLoad =
149
231
  result.matchedRule?.pattern.startsWith("skill_load_dynamic:") ===
150
232
  true;
@@ -152,7 +234,9 @@ export class PermissionChecker {
152
234
  context.isInteractive === false &&
153
235
  context.trustClass === "guardian" &&
154
236
  !context.requireFreshApproval &&
155
- !isDynamicSkillLoad
237
+ !isDynamicSkillLoad &&
238
+ !v2ForcePrompt &&
239
+ riskLevel !== RiskLevel.High
156
240
  ) {
157
241
  log.info(
158
242
  { toolName: name, riskLevel },
@@ -7,6 +7,8 @@ import { hostFileEditTool } from "./host-filesystem/edit.js";
7
7
  import { hostFileReadTool } from "./host-filesystem/read.js";
8
8
  import { hostFileWriteTool } from "./host-filesystem/write.js";
9
9
  import { hostShellTool } from "./host-terminal/host-shell.js";
10
+ import { registerSystemTools } from "./system/register.js";
11
+ import { setPermissionModeTool } from "./system/set-permission-mode.js";
10
12
  import type { Tool } from "./types.js";
11
13
  import { allUiSurfaceTools } from "./ui-surface/definitions.js";
12
14
  import { registerUiSurfaceTools } from "./ui-surface/registry.js";
@@ -264,6 +266,7 @@ export async function initializeTools(): Promise<void> {
264
266
 
265
267
  registerUiSurfaceTools();
266
268
  registerAppTools();
269
+ registerSystemTools();
267
270
 
268
271
  // Snapshot core tools for __resetRegistryForTesting(). We include every
269
272
  // non-skill tool that was registered by the manifest, while excluding
@@ -282,6 +285,7 @@ export async function initializeTools(): Promise<void> {
282
285
  ...allComputerUseTools.map((t: Tool) => t.name),
283
286
  ...allUiSurfaceTools.map((t: Tool) => t.name),
284
287
  ...coreAppProxyTools.map((t: Tool) => t.name),
288
+ setPermissionModeTool.name,
285
289
  ]);
286
290
 
287
291
  coreToolsSnapshot = new Map<string, Tool>();
@@ -42,6 +42,7 @@ export async function executeScheduleCreate(
42
42
  | Record<string, unknown>
43
43
  | undefined;
44
44
  const quiet = (input.quiet as boolean) ?? false;
45
+ const reuseConversation = (input.reuse_conversation as boolean) ?? false;
45
46
 
46
47
  if (!name || typeof name !== "string") {
47
48
  return {
@@ -114,6 +115,7 @@ export async function executeScheduleCreate(
114
115
  routingIntent: routingIntent as RoutingIntent | undefined,
115
116
  routingHints,
116
117
  quiet,
118
+ reuseConversation,
117
119
  });
118
120
 
119
121
  const fireDate = formatLocalDate(job.nextRunAt);
@@ -190,6 +192,7 @@ export async function executeScheduleCreate(
190
192
  routingIntent: routingIntent as RoutingIntent | undefined,
191
193
  routingHints,
192
194
  quiet,
195
+ reuseConversation,
193
196
  });
194
197
 
195
198
  const scheduleDescription =
@@ -65,6 +65,7 @@ export async function executeScheduleList(
65
65
  lines.push(
66
66
  ` Enabled: ${job.enabled}`,
67
67
  ` Quiet: ${job.quiet}`,
68
+ ` Reuse conversation: ${job.reuseConversation}`,
68
69
  ` Message: ${job.message}`,
69
70
  );
70
71
 
@@ -102,6 +102,11 @@ export async function executeScheduleUpdate(
102
102
  updates.quiet = input.quiet;
103
103
  }
104
104
 
105
+ // Conversation reuse
106
+ if (input.reuse_conversation !== undefined) {
107
+ updates.reuseConversation = input.reuse_conversation;
108
+ }
109
+
105
110
  // Auto-detect syntax when expression changes without explicit syntax
106
111
  if (input.expression !== undefined || input.syntax !== undefined) {
107
112
  const resolved = normalizeScheduleSyntax({
@@ -165,6 +170,7 @@ export async function executeScheduleUpdate(
165
170
  routingIntent?: RoutingIntent;
166
171
  routingHints?: Record<string, unknown>;
167
172
  quiet?: boolean;
173
+ reuseConversation?: boolean;
168
174
  },
169
175
  );
170
176
 
@@ -8,6 +8,7 @@ export type FsErrorCode =
8
8
  | "PATH_NOT_ABSOLUTE"
9
9
  | "NOT_FOUND"
10
10
  | "NOT_A_FILE"
11
+ | "NOT_A_DIRECTORY"
11
12
  | "SIZE_LIMIT_EXCEEDED"
12
13
  | "MATCH_NOT_FOUND"
13
14
  | "MATCH_AMBIGUOUS"
@@ -56,6 +57,10 @@ export function notAFile(path: string): FsError {
56
57
  return { code: "NOT_A_FILE", message: `Not a regular file: ${path}`, path };
57
58
  }
58
59
 
60
+ export function notADirectory(path: string): FsError {
61
+ return { code: "NOT_A_DIRECTORY", message: `Not a directory: ${path}`, path };
62
+ }
63
+
59
64
  export function sizeLimitExceeded(path: string, detail: string): FsError {
60
65
  return {
61
66
  code: "SIZE_LIMIT_EXCEEDED",
@@ -1,5 +1,13 @@
1
- import { readFileSync, statSync, writeFileSync } from "node:fs";
2
- import { dirname } from "node:path";
1
+ import {
2
+ lstatSync,
3
+ readdirSync,
4
+ readFileSync,
5
+ statSync,
6
+ writeFileSync,
7
+ } from "node:fs";
8
+ import { dirname, join } from "node:path";
9
+
10
+ import { minimatch } from "minimatch";
3
11
 
4
12
  import { ensureDir, pathExists } from "../../../util/fs.js";
5
13
  import { applyEdit } from "./edit-engine.js";
@@ -9,6 +17,8 @@ import { checkContentSize, checkFileSizeOnDisk } from "./size-guard.js";
9
17
  import type {
10
18
  EditInput,
11
19
  EditResult,
20
+ ListInput,
21
+ ListResult,
12
22
  ReadInput,
13
23
  ReadResult,
14
24
  WriteInput,
@@ -237,4 +247,82 @@ export class FileSystemOps {
237
247
  },
238
248
  };
239
249
  }
250
+
251
+ // -------------------------------------------------------------------------
252
+ // List
253
+ // -------------------------------------------------------------------------
254
+
255
+ listDirSafe(input: ListInput): ListResult {
256
+ const pathCheck = this.policy(input.path, { mustExist: true });
257
+ if (!pathCheck.ok) {
258
+ return {
259
+ ok: false,
260
+ error: pathError(input.path, pathCheck.reason, pathCheck.error),
261
+ };
262
+ }
263
+ const resolved = pathCheck.resolved;
264
+
265
+ if (!pathExists(resolved)) {
266
+ return { ok: false, error: Err.notFound(resolved) };
267
+ }
268
+
269
+ const stat = statSync(resolved);
270
+ if (!stat.isDirectory()) {
271
+ return { ok: false, error: Err.notADirectory(resolved) };
272
+ }
273
+
274
+ try {
275
+ let entries = readdirSync(resolved, { withFileTypes: true });
276
+
277
+ if (input.glob) {
278
+ const pattern = input.glob;
279
+ entries = entries.filter((e) => minimatch(e.name, pattern));
280
+ }
281
+
282
+ // Sort: directories first (alphabetical), then files (alphabetical)
283
+ const dirs = entries
284
+ .filter((e) => e.isDirectory())
285
+ .sort((a, b) => a.name.localeCompare(b.name));
286
+ const files = entries
287
+ .filter((e) => !e.isDirectory())
288
+ .sort((a, b) => a.name.localeCompare(b.name));
289
+ const sorted = [...dirs, ...files];
290
+
291
+ const MAX_ENTRIES = 500;
292
+ const truncated = sorted.length > MAX_ENTRIES;
293
+ const visible = sorted.slice(0, MAX_ENTRIES);
294
+
295
+ const lines = visible.map((entry) => {
296
+ if (entry.isDirectory()) {
297
+ return `${entry.name}/`;
298
+ }
299
+ if (entry.isSymbolicLink()) {
300
+ return `${entry.name}@`;
301
+ }
302
+ const fileStat = lstatSync(join(resolved, entry.name));
303
+ return `${entry.name} ${formatSize(fileStat.size)}`;
304
+ });
305
+
306
+ if (truncated) {
307
+ lines.push(
308
+ `\n... and ${sorted.length - MAX_ENTRIES} more entries (use glob to filter)`,
309
+ );
310
+ }
311
+
312
+ return { ok: true, value: { listing: lines.join("\n") } };
313
+ } catch (err) {
314
+ const msg = err instanceof Error ? err.message : String(err);
315
+ return { ok: false, error: Err.ioError(resolved, msg) };
316
+ }
317
+ }
318
+ }
319
+
320
+ // ---------------------------------------------------------------------------
321
+ // Helpers
322
+ // ---------------------------------------------------------------------------
323
+
324
+ function formatSize(bytes: number): string {
325
+ if (bytes < 1024) return `${bytes} B`;
326
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
327
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
240
328
  }