@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
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Route handlers for conversation group management.
3
+ *
4
+ * GET /v1/groups — list all groups
5
+ * POST /v1/groups — create a custom group
6
+ * PATCH /v1/groups/:groupId — update a group
7
+ * DELETE /v1/groups/:groupId — delete a group
8
+ * POST /v1/groups/reorder — reorder groups
9
+ */
10
+
11
+ import { z } from "zod";
12
+
13
+ import {
14
+ createGroup,
15
+ deleteGroup,
16
+ getGroup,
17
+ listGroups,
18
+ reorderGroups,
19
+ updateGroup,
20
+ } from "../../memory/group-crud.js";
21
+ import { httpError } from "../http-errors.js";
22
+ import type { RouteDefinition } from "../http-router.js";
23
+
24
+ function serializeGroup(group: ReturnType<typeof getGroup>) {
25
+ if (!group) return null;
26
+ return {
27
+ id: group.id,
28
+ name: group.name,
29
+ sortPosition: group.sortPosition,
30
+ isSystemGroup: group.isSystemGroup,
31
+ };
32
+ }
33
+
34
+ export function groupRouteDefinitions(): RouteDefinition[] {
35
+ return [
36
+ {
37
+ endpoint: "groups",
38
+ method: "GET",
39
+ policyKey: "groups",
40
+ summary: "List groups",
41
+ description: "Return all conversation groups.",
42
+ tags: ["groups"],
43
+ handler: () => {
44
+ const groups = listGroups();
45
+ return Response.json({
46
+ groups: groups.map(serializeGroup),
47
+ });
48
+ },
49
+ },
50
+ {
51
+ endpoint: "groups",
52
+ method: "POST",
53
+ policyKey: "groups",
54
+ summary: "Create group",
55
+ description:
56
+ "Create a new custom conversation group. Server assigns sort_position.",
57
+ tags: ["groups"],
58
+ requestBody: z.object({
59
+ name: z.string().describe("Group name"),
60
+ }),
61
+ handler: async ({ req }) => {
62
+ const body = (await req.json()) as { name?: string };
63
+ if (!body.name || typeof body.name !== "string") {
64
+ return httpError("BAD_REQUEST", "Missing or invalid name", 400);
65
+ }
66
+ const group = createGroup(body.name);
67
+ return Response.json(serializeGroup(group), { status: 201 });
68
+ },
69
+ },
70
+ {
71
+ endpoint: "groups/:groupId",
72
+ method: "PATCH",
73
+ policyKey: "groups",
74
+ summary: "Update group",
75
+ description: "Update a conversation group's name or sort position.",
76
+ tags: ["groups"],
77
+ requestBody: z.object({
78
+ name: z.string().optional(),
79
+ sortPosition: z.number().optional(),
80
+ }),
81
+ handler: async ({ req, params }) => {
82
+ const groupId = params.groupId;
83
+ const existing = getGroup(groupId);
84
+ if (!existing) {
85
+ return httpError("NOT_FOUND", "Group not found", 404);
86
+ }
87
+ const body = (await req.json()) as {
88
+ name?: string;
89
+ sortPosition?: number;
90
+ };
91
+ if (body.name !== undefined && typeof body.name !== "string") {
92
+ return httpError("BAD_REQUEST", "name must be a string", 400);
93
+ }
94
+ if (
95
+ body.sortPosition !== undefined &&
96
+ typeof body.sortPosition !== "number"
97
+ ) {
98
+ return httpError("BAD_REQUEST", "sortPosition must be a number", 400);
99
+ }
100
+ // System groups allow name changes but block sortPosition/delete.
101
+ if (existing.isSystemGroup && body.sortPosition !== undefined) {
102
+ return httpError(
103
+ "FORBIDDEN",
104
+ "System group sort position cannot be changed",
105
+ 403,
106
+ );
107
+ }
108
+ // Custom group sort_position must be >= 3
109
+ if (
110
+ body.sortPosition !== undefined &&
111
+ (typeof body.sortPosition !== "number" ||
112
+ !isFinite(body.sortPosition) ||
113
+ body.sortPosition < 3)
114
+ ) {
115
+ return httpError(
116
+ "BAD_REQUEST",
117
+ "Custom group sort_position must be >= 3",
118
+ 400,
119
+ );
120
+ }
121
+ const updated = updateGroup(groupId, {
122
+ name: body.name,
123
+ sortPosition: body.sortPosition,
124
+ });
125
+ if (!updated) {
126
+ return httpError("NOT_FOUND", "Group not found", 404);
127
+ }
128
+ return Response.json(serializeGroup(updated));
129
+ },
130
+ },
131
+ {
132
+ endpoint: "groups/:groupId",
133
+ method: "DELETE",
134
+ policyKey: "groups",
135
+ summary: "Delete group",
136
+ description: "Delete a custom conversation group.",
137
+ tags: ["groups"],
138
+ handler: ({ params }) => {
139
+ const groupId = params.groupId;
140
+ const existing = getGroup(groupId);
141
+ if (!existing) {
142
+ return httpError("NOT_FOUND", "Group not found", 404);
143
+ }
144
+ // System groups cannot be deleted
145
+ if (existing.isSystemGroup) {
146
+ return httpError("FORBIDDEN", "System groups cannot be deleted", 403);
147
+ }
148
+ deleteGroup(groupId);
149
+ return new Response(null, { status: 204 });
150
+ },
151
+ },
152
+ {
153
+ endpoint: "groups/reorder",
154
+ method: "POST",
155
+ policyKey: "groups/reorder",
156
+ summary: "Reorder groups",
157
+ description: "Batch-update sort positions for conversation groups.",
158
+ tags: ["groups"],
159
+ requestBody: z.object({
160
+ updates: z
161
+ .array(
162
+ z.object({
163
+ groupId: z.string(),
164
+ sortPosition: z.number(),
165
+ }),
166
+ )
167
+ .describe("Array of { groupId, sortPosition } objects"),
168
+ }),
169
+ handler: async ({ req }) => {
170
+ const body = (await req.json()) as {
171
+ updates?: Array<{
172
+ groupId: string;
173
+ sortPosition: number;
174
+ }>;
175
+ };
176
+ if (!Array.isArray(body.updates)) {
177
+ return httpError("BAD_REQUEST", "Missing updates array", 400);
178
+ }
179
+ // Validate: no system group reordering, no sort_position < 3 for custom groups
180
+ for (const update of body.updates) {
181
+ const group = getGroup(update.groupId);
182
+ if (!group) continue;
183
+ if (group.isSystemGroup) {
184
+ return httpError(
185
+ "FORBIDDEN",
186
+ `Cannot reorder system group: ${update.groupId}`,
187
+ 403,
188
+ );
189
+ }
190
+ if (
191
+ typeof update.sortPosition !== "number" ||
192
+ !isFinite(update.sortPosition) ||
193
+ update.sortPosition < 3
194
+ ) {
195
+ return httpError(
196
+ "BAD_REQUEST",
197
+ `Custom group sort_position must be >= 3 (got ${update.sortPosition} for ${update.groupId})`,
198
+ 400,
199
+ );
200
+ }
201
+ }
202
+ reorderGroups(body.updates);
203
+ return Response.json({ ok: true });
204
+ },
205
+ },
206
+ ];
207
+ }
@@ -23,7 +23,10 @@ import { requireBoundGuardian } from "../auth/require-bound-guardian.js";
23
23
  import type { AuthContext } from "../auth/types.js";
24
24
  import { processGuardianDecision } from "../guardian-action-service.js";
25
25
  import type { GuardianDecisionPrompt } from "../guardian-decision-types.js";
26
- import { buildDecisionActions } from "../guardian-decision-types.js";
26
+ import {
27
+ buildDecisionActions,
28
+ GUARDIAN_DECISION_ACTIONS,
29
+ } from "../guardian-decision-types.js";
27
30
  import { httpError } from "../http-errors.js";
28
31
  import type { RouteDefinition } from "../http-router.js";
29
32
 
@@ -190,13 +193,15 @@ export function listGuardianDecisionPrompts(params: {
190
193
  * Map a canonical guardian request to the client-facing prompt format.
191
194
  *
192
195
  * Generates kind-specific questionText and action sets:
193
- * - `tool_approval`: "Approve tool: <name>" with approve/reject actions
194
- * - `pending_question`: voice-originated question with approve/reject actions
195
- * - `access_request`: explicit "Access Request" label with approve/reject actions
196
- * and text fallback instructions (request code + "open invite flow")
196
+ * - `tool_approval`: temporal modes (approve_once, approve_10m, approve_conversation) + reject
197
+ * - `pending_question`: approve_once + reject only
198
+ * - `access_request`: approve_once + reject only, with text fallback instructions
199
+ * (request code + "open invite flow")
200
+ * - `tool_grant_request`: approve_once + reject only
197
201
  *
198
- * All kinds use `forGuardianOnBehalf: true` (no approve_always) since the
199
- * guardian is acting on behalf of a requester.
202
+ * Only `tool_approval` receives temporal modes because time-scoped grants
203
+ * are meaningful only for tool execution. All other kinds get a simple
204
+ * approve_once/reject pair.
200
205
  */
201
206
  function mapCanonicalRequestToPrompt(
202
207
  req: CanonicalGuardianRequest,
@@ -204,9 +209,15 @@ function mapCanonicalRequestToPrompt(
204
209
  ): GuardianDecisionPrompt {
205
210
  const questionText = buildKindAwareQuestionText(req);
206
211
 
207
- // Guardian-on-behalf prompts include approve_once, temporal modes
208
- // (approve_10m, approve_conversation), and reject but not approve_always.
209
- const actions = buildDecisionActions({ forGuardianOnBehalf: true });
212
+ // Only tool_approval gets temporal modes (approve_10m, approve_conversation);
213
+ // all other kinds get a simple approve_once + reject pair.
214
+ const actions =
215
+ req.kind === "tool_approval"
216
+ ? buildDecisionActions({ forGuardianOnBehalf: true })
217
+ : [
218
+ GUARDIAN_DECISION_ACTIONS.approve_once,
219
+ GUARDIAN_DECISION_ACTIONS.reject,
220
+ ];
210
221
 
211
222
  const expiresAt = req.expiresAt
212
223
  ? new Date(req.expiresAt).getTime()
@@ -19,7 +19,7 @@ import { getLogger } from "../../util/logger.js";
19
19
  import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
20
20
  import { mintCredentialPair } from "../auth/credential-service.js";
21
21
  import { httpError } from "../http-errors.js";
22
- import { isPrivateAddress } from "../middleware/auth.js";
22
+ import { isLoopbackAddress, isPrivateAddress } from "../middleware/auth.js";
23
23
 
24
24
  /** Bun server shape needed for requestIP -- avoids importing the full Bun type. */
25
25
  type ServerWithRequestIP = {
@@ -87,30 +87,34 @@ export async function handleGuardianBootstrap(
87
87
  req: Request,
88
88
  server: ServerWithRequestIP,
89
89
  ): Promise<Response> {
90
- // Reject non-private-network peers (allows loopback, Docker bridge, etc.)
90
+ // In non-containerized (bare-metal) mode, restrict to loopback only
91
+ // the runtime binds to localhost and LAN peers should not be able to
92
+ // bootstrap even if they somehow reach the endpoint.
93
+ // In containerized (Docker) mode, accept any private-network peer because
94
+ // the gateway connects over the Docker bridge (e.g. 172.17.0.1) and the
95
+ // GUARDIAN_BOOTSTRAP_SECRET enforced at the gateway layer provides the
96
+ // real authentication.
91
97
  const peerIp = server.requestIP(req)?.address;
92
- if ((!peerIp || !isPrivateAddress(peerIp)) && !isHttpAuthDisabled()) {
98
+ const containerized = getIsContainerized();
99
+ const peerAllowed = containerized
100
+ ? isPrivateAddress(peerIp ?? "")
101
+ : isLoopbackAddress(peerIp ?? "");
102
+ if (!peerAllowed && !isHttpAuthDisabled()) {
93
103
  return httpError("FORBIDDEN", "Bootstrap endpoint is local-only", 403);
94
104
  }
95
105
 
96
- // Reject requests forwarded from public networks. The gateway sets
97
- // x-forwarded-for to the real client IP; if that IP is on a private
98
- // network (loopback, Docker bridge, RFC 1918) the request is still
99
- // considered local. Only reject when the forwarded IP is public.
106
+ // In non-containerized mode, any x-forwarded-for header means the request
107
+ // came through the gateway from a non-loopback client. Legitimate bare-metal
108
+ // bootstrap clients connect from localhost; the gateway does not inject
109
+ // x-forwarded-for for loopback peers (see gateway/src/index.ts). Reject
110
+ // forwarded requests to prevent LAN-adjacent clients from bootstrapping.
100
111
  //
101
- // Skip this check when running in a container: the peer IP was already
102
- // validated above (Docker bridge network = private), so the request
103
- // reached us through a co-located gateway. The x-forwarded-for header
104
- // reflects the original external client (e.g. platform proxy) and is
105
- // not meaningful for local-only enforcement in this topology.
112
+ // In containerized mode, skip this check: the peer IP was already validated
113
+ // above (Docker bridge network = private), and the x-forwarded-for header
114
+ // reflects the original external client which is not meaningful for
115
+ // local-only enforcement in this topology.
106
116
  const forwarded = req.headers.get("x-forwarded-for");
107
- const forwardedIp = forwarded ? forwarded.split(",")[0].trim() : null;
108
- if (
109
- forwardedIp &&
110
- !isPrivateAddress(forwardedIp) &&
111
- !isHttpAuthDisabled() &&
112
- !getIsContainerized()
113
- ) {
117
+ if (forwarded && !isHttpAuthDisabled() && !getIsContainerized()) {
114
118
  return httpError("FORBIDDEN", "Bootstrap endpoint is local-only", 403);
115
119
  }
116
120
 
@@ -47,16 +47,10 @@ function handleUpdateConfig(
47
47
  if (typeof body.enabled === "boolean") heartbeat.enabled = body.enabled;
48
48
  if (typeof body.intervalMs === "number")
49
49
  heartbeat.intervalMs = body.intervalMs;
50
- if ("activeHoursStart" in body) {
51
- heartbeat.activeHoursStart =
52
- typeof body.activeHoursStart === "number"
53
- ? body.activeHoursStart
54
- : undefined;
55
- }
56
- if ("activeHoursEnd" in body) {
57
- heartbeat.activeHoursEnd =
58
- typeof body.activeHoursEnd === "number" ? body.activeHoursEnd : undefined;
59
- }
50
+ if (typeof body.activeHoursStart === "number")
51
+ heartbeat.activeHoursStart = body.activeHoursStart;
52
+ if (typeof body.activeHoursEnd === "number")
53
+ heartbeat.activeHoursEnd = body.activeHoursEnd;
60
54
 
61
55
  try {
62
56
  saveConfig({ ...config, heartbeat });
@@ -10,6 +10,7 @@ import { fileURLToPath } from "node:url";
10
10
  import { z } from "zod";
11
11
 
12
12
  import { parseIdentityFields } from "../../daemon/handlers/identity.js";
13
+ import { getProfilerRuntimeStatus } from "../../daemon/profiler-run-store.js";
13
14
  import { getMaxMigrationVersion } from "../../memory/migrations/registry.js";
14
15
  import {
15
16
  getWorkspaceDir,
@@ -144,6 +145,13 @@ export function handleHealth(): Response {
144
145
  }
145
146
 
146
147
  export function handleDetailedHealth(): Response {
148
+ let profiler: ReturnType<typeof getProfilerRuntimeStatus> | undefined;
149
+ try {
150
+ profiler = getProfilerRuntimeStatus();
151
+ } catch {
152
+ // Profiler status is non-critical — omit on error
153
+ }
154
+
147
155
  return Response.json({
148
156
  status: "healthy",
149
157
  timestamp: new Date().toISOString(),
@@ -156,6 +164,7 @@ export function handleDetailedHealth(): Response {
156
164
  lastWorkspaceMigrationId:
157
165
  getLastWorkspaceMigrationId(WORKSPACE_MIGRATIONS),
158
166
  },
167
+ ...(profiler ? { profiler } : {}),
159
168
  });
160
169
  }
161
170
 
@@ -239,6 +248,48 @@ export function handleGetIdentityIntro(): Response {
239
248
  return Response.json({ text: cached.text });
240
249
  }
241
250
 
251
+ // ---------------------------------------------------------------------------
252
+ // Zod schemas for profiler health metadata
253
+ // ---------------------------------------------------------------------------
254
+
255
+ const profilerBudgetSchema = z.object({
256
+ maxBytes: z.number(),
257
+ remainingBytes: z.number(),
258
+ minFreeMb: z.number(),
259
+ freeMb: z.number(),
260
+ overBudget: z.boolean(),
261
+ });
262
+
263
+ const profilerLastCompletedRunSchema = z.object({
264
+ runId: z.string(),
265
+ totalBytes: z.number(),
266
+ artifactCount: z.number(),
267
+ hasSummaries: z.boolean(),
268
+ completedAt: z.string(),
269
+ });
270
+
271
+ const profilerStatusSchema = z.object({
272
+ enabled: z.boolean(),
273
+ mode: z.string().nullable(),
274
+ runId: z.string().nullable(),
275
+ runDir: z.string().nullable(),
276
+ totalBytes: z.number(),
277
+ artifactCount: z.number(),
278
+ budget: profilerBudgetSchema.nullable(),
279
+ lastCompletedRun: profilerLastCompletedRunSchema.nullable(),
280
+ });
281
+
282
+ const detailedHealthSchema = z.object({
283
+ status: z.string(),
284
+ timestamp: z.string(),
285
+ version: z.string(),
286
+ disk: z.object({}).passthrough(),
287
+ memory: z.object({}).passthrough(),
288
+ cpu: z.object({}).passthrough(),
289
+ migrations: z.object({}).passthrough(),
290
+ profiler: profilerStatusSchema.optional(),
291
+ });
292
+
242
293
  // ---------------------------------------------------------------------------
243
294
  // Route definitions
244
295
  // ---------------------------------------------------------------------------
@@ -253,15 +304,7 @@ export function identityRouteDefinitions(): RouteDefinition[] {
253
304
  description:
254
305
  "Returns runtime health including version, disk, memory, CPU, and migration status.",
255
306
  tags: ["system"],
256
- responseBody: z.object({
257
- status: z.string(),
258
- timestamp: z.string(),
259
- version: z.string(),
260
- disk: z.object({}).passthrough(),
261
- memory: z.object({}).passthrough(),
262
- cpu: z.object({}).passthrough(),
263
- migrations: z.object({}).passthrough(),
264
- }),
307
+ responseBody: detailedHealthSchema,
265
308
  },
266
309
  {
267
310
  endpoint: "healthz",
@@ -272,15 +315,7 @@ export function identityRouteDefinitions(): RouteDefinition[] {
272
315
  description:
273
316
  "Alias for /v1/health. Returns runtime health including version, disk, memory, CPU, and migration status.",
274
317
  tags: ["system"],
275
- responseBody: z.object({
276
- status: z.string(),
277
- timestamp: z.string(),
278
- version: z.string(),
279
- disk: z.object({}).passthrough(),
280
- memory: z.object({}).passthrough(),
281
- cpu: z.object({}).passthrough(),
282
- migrations: z.object({}).passthrough(),
283
- }),
318
+ responseBody: detailedHealthSchema,
284
319
  },
285
320
  {
286
321
  endpoint: "identity",
@@ -44,6 +44,7 @@ import { processChannelMessageInBackground } from "./inbound-stages/background-d
44
44
  import { handleBootstrapIntercept } from "./inbound-stages/bootstrap-intercept.js";
45
45
  import { handleEditIntercept } from "./inbound-stages/edit-intercept.js";
46
46
  import { handleEscalationIntercept } from "./inbound-stages/escalation-intercept.js";
47
+ import { handleGuardianActivationIntercept } from "./inbound-stages/guardian-activation-intercept.js";
47
48
  import { handleGuardianReplyIntercept } from "./inbound-stages/guardian-reply-intercept.js";
48
49
  import { runSecretIngressCheck } from "./inbound-stages/secret-ingress-check.js";
49
50
  import { tryTranscribeAudioAttachments } from "./inbound-stages/transcribe-audio.js";
@@ -199,6 +200,24 @@ export async function handleChannelInbound(
199
200
  // ACL deny path rather than bypassing it.
200
201
  const hasSenderIdentityClaim = rawSenderId !== undefined;
201
202
 
203
+ // ── Guardian channel activation ──
204
+ // When a bare /start arrives on a channel with no guardian, auto-initiate
205
+ // guardian verification so the first user can claim the channel.
206
+ const guardianActivationResponse = await handleGuardianActivationIntercept({
207
+ sourceChannel,
208
+ conversationExternalId,
209
+ rawSenderId,
210
+ canonicalSenderId,
211
+ actorDisplayName: body.actorDisplayName,
212
+ actorUsername: body.actorUsername,
213
+ sourceMetadata: body.sourceMetadata,
214
+ replyCallbackUrl: body.replyCallbackUrl,
215
+ mintBearerToken,
216
+ assistantId,
217
+ externalMessageId,
218
+ });
219
+ if (guardianActivationResponse) return guardianActivationResponse;
220
+
202
221
  // ── Ingress ACL enforcement ──
203
222
  const aclResult = await enforceIngressAcl({
204
223
  canonicalSenderId,