@vellumai/assistant 0.11.2 → 0.11.3-staging.2

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 (720) hide show
  1. package/ARCHITECTURE.md +58 -3
  2. package/docs/trusted-contact-access.md +9 -5
  3. package/docs/vellum-doctor.md +195 -0
  4. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
  5. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
  6. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
  7. package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
  8. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +19 -2
  9. package/node_modules/@vellumai/environments/package.json +2 -1
  10. package/node_modules/@vellumai/environments/src/__tests__/cloud-assistant-hub-url.test.ts +38 -0
  11. package/node_modules/@vellumai/environments/src/__tests__/install-layout.test.ts +98 -0
  12. package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +5 -5
  13. package/node_modules/@vellumai/environments/src/index.ts +17 -6
  14. package/node_modules/@vellumai/environments/src/install-layout.ts +49 -0
  15. package/node_modules/@vellumai/environments/src/seeds.ts +29 -0
  16. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
  17. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
  18. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
  19. package/node_modules/@vellumai/gateway-client/src/index.ts +4 -0
  20. package/node_modules/@vellumai/gateway-client/src/verification-session-contract.ts +91 -6
  21. package/node_modules/@vellumai/ipc-server-utils/src/endpoint.test.ts +36 -0
  22. package/node_modules/@vellumai/ipc-server-utils/src/endpoint.ts +142 -0
  23. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +2 -0
  24. package/node_modules/@vellumai/ipc-server-utils/src/listen-options.ts +3 -0
  25. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +15 -1
  26. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +17 -2
  27. package/node_modules/@vellumai/service-contracts/src/channels.ts +39 -0
  28. package/node_modules/@vellumai/service-contracts/src/ingress.ts +10 -0
  29. package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +6 -0
  30. package/node_modules/@vellumai/slack-text/src/index.ts +16 -2
  31. package/openapi.yaml +589 -30
  32. package/package.json +1 -1
  33. package/src/__tests__/agent-image-optimize.test.ts +4 -4
  34. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +113 -66
  35. package/src/__tests__/agent-loop-override-profile.test.ts +38 -48
  36. package/src/__tests__/agent-loop-subagent-billing-headers.test.ts +166 -0
  37. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  38. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  39. package/src/__tests__/answered-question-persistence.test.ts +240 -0
  40. package/src/__tests__/anthropic-provider.test.ts +165 -30
  41. package/src/__tests__/app-control-flow.test.ts +9 -8
  42. package/src/__tests__/assistant-event-hub.test.ts +48 -0
  43. package/src/__tests__/attachments-store-heic-normalize.test.ts +16 -12
  44. package/src/__tests__/attachments-store.test.ts +130 -68
  45. package/src/__tests__/attachments.test.ts +36 -36
  46. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  47. package/src/__tests__/call-start-guardian-guard.test.ts +18 -4
  48. package/src/__tests__/canned-reply-release.test.ts +86 -0
  49. package/src/__tests__/channel-guardian.test.ts +59 -29
  50. package/src/__tests__/channel-readiness-telegram-remote.test.ts +154 -0
  51. package/src/__tests__/channel-setup-panel-ack.test.ts +6 -5
  52. package/src/__tests__/client-os-metadata-persistence.test.ts +103 -4
  53. package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
  54. package/src/__tests__/consult-deadline.test.ts +65 -0
  55. package/src/__tests__/conversation-agent-loop.test.ts +438 -2
  56. package/src/__tests__/conversation-disk-view-integration.test.ts +5 -1
  57. package/src/__tests__/conversation-disk-view.test.ts +4 -4
  58. package/src/__tests__/conversation-error.test.ts +22 -3
  59. package/src/__tests__/conversation-fork-crud.test.ts +5 -1
  60. package/src/__tests__/conversation-fork-referential.test.ts +352 -0
  61. package/src/__tests__/conversation-fork-retrospective.test.ts +5 -1
  62. package/src/__tests__/conversation-group-tools.test.ts +32 -2
  63. package/src/__tests__/conversation-inference-profile-route.test.ts +27 -1
  64. package/src/__tests__/conversation-initial-prompt.test.ts +51 -22
  65. package/src/__tests__/conversation-key-store-bootstrap-cleanup.test.ts +119 -0
  66. package/src/__tests__/conversation-key-store-origin.test.ts +105 -0
  67. package/src/__tests__/conversation-list-recency-ordering.test.ts +104 -0
  68. package/src/__tests__/conversation-origin-at-creation.test.ts +153 -0
  69. package/src/__tests__/conversation-origin-channel-filter.test.ts +95 -0
  70. package/src/__tests__/conversation-placement-promotion.test.ts +172 -0
  71. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +123 -0
  72. package/src/__tests__/conversation-queue.test.ts +433 -1
  73. package/src/__tests__/conversation-retry-route.test.ts +3 -1
  74. package/src/__tests__/conversation-routes-hidden-queue.test.ts +64 -1
  75. package/src/__tests__/conversation-store-ephemeral.test.ts +4 -0
  76. package/src/__tests__/conversation-store.test.ts +26 -10
  77. package/src/__tests__/conversation-summarize-route.test.ts +1 -1
  78. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +15 -6
  79. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -5
  80. package/src/__tests__/conversation-surfaces-app-control.test.ts +12 -11
  81. package/src/__tests__/conversation-surfaces-app-open.test.ts +11 -5
  82. package/src/__tests__/conversation-surfaces-data-persist.test.ts +5 -4
  83. package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +967 -0
  84. package/src/__tests__/conversation-surfaces-persisted-info.test.ts +312 -0
  85. package/src/__tests__/conversation-surfaces-queued-emit.test.ts +6 -5
  86. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -8
  87. package/src/__tests__/conversation-surfaces-standalone.test.ts +21 -11
  88. package/src/__tests__/conversation-surfaces-state-update.test.ts +7 -11
  89. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -6
  90. package/src/__tests__/conversation-surfaces-task-progress.test.ts +11 -6
  91. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +9 -6
  92. package/src/__tests__/conversation-tool-setup-attribution.test.ts +70 -7
  93. package/src/__tests__/conversation-wait-for-idle.test.ts +6 -11
  94. package/src/__tests__/credential-prompt-route.test.ts +57 -7
  95. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  96. package/src/__tests__/cu-unified-flow.test.ts +89 -28
  97. package/src/__tests__/custom-group-listing-visibility.test.ts +1 -1
  98. package/src/__tests__/db-schedule-syntax-migration.test.ts +4 -1
  99. package/src/__tests__/discord-access-request-privacy.test.ts +366 -0
  100. package/src/__tests__/discord-requester-notice-privacy.test.ts +87 -0
  101. package/src/__tests__/disk-pressure-guard.test.ts +55 -55
  102. package/src/__tests__/disk-pressure-routes.test.ts +10 -10
  103. package/src/__tests__/disk-pressure-tools.test.ts +2 -2
  104. package/src/__tests__/disk-usage.test.ts +35 -20
  105. package/src/__tests__/document-sync-tags.test.ts +379 -0
  106. package/src/__tests__/document-update-default-surface.test.ts +28 -0
  107. package/src/__tests__/dynamic-skill-background-guard.test.ts +2 -2
  108. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -4
  109. package/src/__tests__/ensure-conversation-exists.test.ts +8 -5
  110. package/src/__tests__/events-dev-bypass-actor.test.ts +183 -1
  111. package/src/__tests__/evict-conversations-for-reload.test.ts +90 -0
  112. package/src/__tests__/file-list-tool.test.ts +12 -10
  113. package/src/__tests__/file-ops-service.test.ts +151 -44
  114. package/src/__tests__/file-read-container-boundary.test.ts +137 -0
  115. package/src/__tests__/file-read-tool.test.ts +21 -9
  116. package/src/__tests__/file-url-path-guard.test.ts +83 -0
  117. package/src/__tests__/filesystem-tools.test.ts +82 -66
  118. package/src/__tests__/guardian-outbound-http.test.ts +8 -8
  119. package/src/__tests__/helpers/gateway-verification-sessions-stub.ts +14 -1
  120. package/src/__tests__/helpers/hub-clients.ts +42 -0
  121. package/src/__tests__/helpers/mock-conversation.ts +46 -0
  122. package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +61 -57
  123. package/src/__tests__/history-repair.test.ts +112 -12
  124. package/src/__tests__/host-bash-proxy.test.ts +10 -5
  125. package/src/__tests__/host-bash-routes.test.ts +67 -0
  126. package/src/__tests__/host-browser-proxy.test.ts +2 -2
  127. package/src/__tests__/host-cu-proxy.test.ts +3 -7
  128. package/src/__tests__/host-file-proxy.test.ts +3 -7
  129. package/src/__tests__/host-file-read-tool.test.ts +5 -1
  130. package/src/__tests__/host-transfer-proxy-targeted.test.ts +6 -4
  131. package/src/__tests__/http-conversation-lineage.test.ts +2 -5
  132. package/src/__tests__/http-user-message-parity.test.ts +44 -0
  133. package/src/__tests__/identity-routes.test.ts +13 -13
  134. package/src/__tests__/image-conversion.test.ts +29 -26
  135. package/src/__tests__/image-source-path-reinject.test.ts +2 -2
  136. package/src/__tests__/inference-profile-session-handler.test.ts +95 -0
  137. package/src/__tests__/inference-profile-session-ipc.test.ts +25 -0
  138. package/src/__tests__/introduction-card-resolver.test.ts +6 -1
  139. package/src/__tests__/list-messages-attachments.test.ts +56 -32
  140. package/src/__tests__/list-messages-background-tool-completion.test.ts +4 -4
  141. package/src/__tests__/list-messages-client-message-id.test.ts +2 -2
  142. package/src/__tests__/list-messages-hidden-metadata.test.ts +16 -16
  143. package/src/__tests__/list-messages-page-latest.test.ts +61 -61
  144. package/src/__tests__/list-messages-provider-error.test.ts +6 -6
  145. package/src/__tests__/list-messages-queued.test.ts +49 -6
  146. package/src/__tests__/list-messages-system-card.test.ts +4 -4
  147. package/src/__tests__/list-messages-tool-merge.test.ts +9 -9
  148. package/src/__tests__/llm-resolver-override-or-default.test.ts +141 -0
  149. package/src/__tests__/llm-usage-store.test.ts +55 -0
  150. package/src/__tests__/manual-token-reconciliation.test.ts +45 -0
  151. package/src/__tests__/mcp-tool-annotations-risk.test.ts +133 -0
  152. package/src/__tests__/media-stream-server-integration.test.ts +36 -0
  153. package/src/__tests__/migration-export-http.test.ts +1 -1
  154. package/src/__tests__/migration-import-commit-http.test.ts +1 -1
  155. package/src/__tests__/migration-import-preflight-http.test.ts +1 -1
  156. package/src/__tests__/migration-validate-http.test.ts +1 -1
  157. package/src/__tests__/mtime-cache.test.ts +65 -3
  158. package/src/__tests__/notification-platform-adapter.test.ts +104 -0
  159. package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
  160. package/src/__tests__/oauth-provider-profiles.test.ts +4 -2
  161. package/src/__tests__/oauth-provider-seed-logos.test.ts +65 -0
  162. package/src/__tests__/oauth-provider-serializer.test.ts +17 -0
  163. package/src/__tests__/oauth-providers-routes.test.ts +1 -0
  164. package/src/__tests__/openai-responses-prompt-cache.test.ts +5 -2
  165. package/src/__tests__/path-policy.test.ts +164 -1
  166. package/src/__tests__/persist-media-references.test.ts +2 -2
  167. package/src/__tests__/persist-unsendable-image-downscale.test.ts +5 -5
  168. package/src/__tests__/persist-unsendable-image.test.ts +23 -23
  169. package/src/__tests__/persona-resolver.test.ts +154 -0
  170. package/src/__tests__/plugin-api-webhook-url.test.ts +170 -0
  171. package/src/__tests__/plugin-import-boundary-guard.test.ts +6 -0
  172. package/src/__tests__/processing-flag-persist-failure.test.ts +15 -10
  173. package/src/__tests__/profile-availability-incomplete.test.ts +113 -0
  174. package/src/__tests__/profiler-routes.test.ts +13 -13
  175. package/src/__tests__/prompt-cache-cross-turn-stability.test.ts +593 -0
  176. package/src/__tests__/proxy-approval-callback.test.ts +3 -3
  177. package/src/__tests__/queued-message-cancel-and-steer.test.ts +189 -0
  178. package/src/__tests__/queued-message-steer-actor-scoping.test.ts +164 -0
  179. package/src/__tests__/resolve-trust-class.test.ts +20 -0
  180. package/src/__tests__/run-conversation-turn-persistence.test.ts +1 -1
  181. package/src/__tests__/run-due-schedules.test.ts +174 -0
  182. package/src/__tests__/runtime-attachment-metadata.test.ts +15 -7
  183. package/src/__tests__/scaffold-managed-skill-tool.test.ts +166 -0
  184. package/src/__tests__/schedule-routes.test.ts +730 -8
  185. package/src/__tests__/schedule-store.test.ts +540 -0
  186. package/src/__tests__/schedule-tools.test.ts +103 -0
  187. package/src/__tests__/scheduler-wake.test.ts +5 -0
  188. package/src/__tests__/secret-routes-platform-proxy.test.ts +29 -1
  189. package/src/__tests__/secure-keys.test.ts +91 -0
  190. package/src/__tests__/server-history-render.test.ts +97 -7
  191. package/src/__tests__/size-guard.test.ts +8 -8
  192. package/src/__tests__/skill-docs-sync-guard.test.ts +3 -2
  193. package/src/__tests__/skill-tool-factory.test.ts +247 -0
  194. package/src/__tests__/skills-install-staging.test.ts +15 -6
  195. package/src/__tests__/slack-edit-ordering-characterization.test.ts +103 -0
  196. package/src/__tests__/slack-inbound-verification.test.ts +4 -1
  197. package/src/__tests__/slack-mention-binding-invariance.test.ts +103 -0
  198. package/src/__tests__/slack-mention-provider-leak-audit.test.ts +135 -0
  199. package/src/__tests__/starter-task-flow.test.ts +5 -4
  200. package/src/__tests__/steer-on-enqueue-question.test.ts +3 -2
  201. package/src/__tests__/stt-language-catalog-parity.test.ts +38 -0
  202. package/src/__tests__/subagent-allowlist-validation.test.ts +26 -4
  203. package/src/__tests__/subagent-cron-run-attribution.test.ts +301 -0
  204. package/src/__tests__/subagent-disposal.test.ts +10 -0
  205. package/src/__tests__/subagent-fork-notifications.test.ts +10 -0
  206. package/src/__tests__/subagent-fork-prompt-role.test.ts +85 -11
  207. package/src/__tests__/subagent-fork-spawn.test.ts +15 -7
  208. package/src/__tests__/subagent-manager-notify.test.ts +148 -0
  209. package/src/__tests__/subagent-notify-parent.test.ts +1 -1
  210. package/src/__tests__/subagent-persistence.test.ts +141 -0
  211. package/src/__tests__/subagent-role-registry.test.ts +172 -63
  212. package/src/__tests__/subagent-role-resolution.test.ts +88 -0
  213. package/src/__tests__/subagent-spawn-and-await.test.ts +48 -0
  214. package/src/__tests__/subagent-spawn-tool-fork.test.ts +111 -10
  215. package/src/__tests__/subagent-terminal-message.test.ts +88 -1
  216. package/src/__tests__/subagent-tool-gate-mode.test.ts +225 -10
  217. package/src/__tests__/subagent-tools.test.ts +1901 -108
  218. package/src/__tests__/surface-completion-compaction-boundary.test.ts +124 -0
  219. package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +298 -0
  220. package/src/__tests__/system-prompt.test.ts +82 -7
  221. package/src/__tests__/tool-grant-request-escalation.test.ts +40 -1
  222. package/src/__tests__/tool-result-spool.test.ts +74 -18
  223. package/src/__tests__/tool-side-effects-documents.test.ts +174 -0
  224. package/src/__tests__/tool-side-effects-hook-failures.test.ts +129 -0
  225. package/src/__tests__/tools-audio-read.test.ts +10 -10
  226. package/src/__tests__/tools-get-route.test.ts +85 -12
  227. package/src/__tests__/tools-list-cli.test.ts +171 -0
  228. package/src/__tests__/top-level-renderer.test.ts +54 -1
  229. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +68 -1
  230. package/src/__tests__/trusted-contact-multichannel.test.ts +4 -1
  231. package/src/__tests__/turn-tail-chain.test.ts +135 -0
  232. package/src/__tests__/ui-choice-copy-surfaces.test.ts +6 -4
  233. package/src/__tests__/ui-visual-surface.test.ts +5 -4
  234. package/src/__tests__/ui-work-result-surface.test.ts +5 -4
  235. package/src/__tests__/unified-turn-context-visible-app.test.ts +7 -8
  236. package/src/__tests__/usage-routes.test.ts +62 -0
  237. package/src/__tests__/verification-outbound-delivery.test.ts +176 -0
  238. package/src/__tests__/visible-app-context.test.ts +20 -4
  239. package/src/__tests__/web-search-history.test.ts +96 -0
  240. package/src/__tests__/workspace-migration-139-clear-renamed-cost-profile-label.test.ts +6 -6
  241. package/src/__tests__/workspace-migration-140-repair-seed-pinned-memory-v3-live.test.ts +330 -0
  242. package/src/acp/failure-error.ts +3 -5
  243. package/src/agent/attachments.ts +26 -24
  244. package/src/agent/history-repair/history-repair.ts +27 -26
  245. package/src/agent/image-optimize.ts +6 -6
  246. package/src/agent/loop.ts +40 -22
  247. package/src/agent/message-types.ts +3 -3
  248. package/src/api/constants/document-tools.ts +55 -0
  249. package/src/api/events/question-answered.ts +53 -0
  250. package/src/api/events/tool-result.ts +7 -0
  251. package/src/api/index.ts +13 -0
  252. package/src/api/responses/conversation-message.ts +11 -0
  253. package/src/api/surfaces-oauth-connect.test.ts +96 -0
  254. package/src/api/surfaces.ts +36 -8
  255. package/src/approvals/guardian-channel-delivery.ts +83 -0
  256. package/src/approvals/guardian-expiry-notifier.ts +13 -11
  257. package/src/approvals/guardian-request-resolvers.ts +222 -135
  258. package/src/calls/__tests__/voice-session-bridge.test.ts +50 -0
  259. package/src/calls/media-stream-server.ts +9 -1
  260. package/src/calls/voice-session-bridge.ts +38 -0
  261. package/src/channels/__tests__/gateway-verification-sessions.test.ts +3 -3
  262. package/src/channels/config.ts +7 -2
  263. package/src/channels/gateway-verification-sessions.ts +7 -2
  264. package/src/channels/types.ts +7 -1
  265. package/src/cli/commands/__tests__/cache.test.ts +7 -4
  266. package/src/cli/commands/__tests__/cli-test-harness.ts +82 -0
  267. package/src/cli/commands/__tests__/conversations-wake.test.ts +51 -6
  268. package/src/cli/commands/__tests__/inference-models.test.ts +14 -0
  269. package/src/cli/commands/__tests__/inference-profiles.test.ts +44 -1
  270. package/src/cli/commands/__tests__/inference-providers.test.ts +7 -0
  271. package/src/cli/commands/__tests__/plugins.test.ts +692 -0
  272. package/src/cli/commands/__tests__/schedules.test.ts +136 -37
  273. package/src/cli/commands/conversations.ts +7 -3
  274. package/src/cli/commands/credentials.help.ts +7 -0
  275. package/src/cli/commands/inference-profiles.ts +9 -3
  276. package/src/cli/commands/inference.help.ts +16 -2
  277. package/src/cli/commands/mcp.help.ts +4 -2
  278. package/src/cli/commands/memory/memory-retrospective.ts +18 -0
  279. package/src/cli/commands/notifications.ts +3 -6
  280. package/src/cli/commands/oauth/connect-surface-guidance.test.ts +16 -0
  281. package/src/cli/commands/oauth/connect-surface-guidance.ts +25 -7
  282. package/src/cli/commands/oauth/connect.test.ts +26 -1
  283. package/src/cli/commands/oauth/connect.ts +4 -1
  284. package/src/cli/commands/oauth/index.help.ts +3 -1
  285. package/src/cli/commands/oauth/providers.ts +3 -0
  286. package/src/cli/commands/plugins.help.ts +25 -2
  287. package/src/cli/commands/plugins.ts +289 -10
  288. package/src/cli/commands/schedules.help.ts +14 -12
  289. package/src/cli/commands/schedules.ts +19 -5
  290. package/src/cli/commands/tools.help.ts +4 -2
  291. package/src/cli/commands/tools.ts +38 -0
  292. package/src/cli/lib/__tests__/inspect-plugin.test.ts +1 -0
  293. package/src/cli/lib/__tests__/install-from-github.test.ts +79 -0
  294. package/src/cli/lib/__tests__/install-from-platform.test.ts +47 -1
  295. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +86 -7
  296. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +122 -0
  297. package/src/cli/lib/install-from-github.ts +61 -0
  298. package/src/cli/lib/install-from-platform.ts +13 -2
  299. package/src/cli/lib/plugin-surfaces.ts +124 -4
  300. package/src/cli/lib/upgrade-plugin.ts +18 -0
  301. package/src/cli.ts +1 -1
  302. package/src/config/__tests__/deployment-context-defaults.test.ts +73 -0
  303. package/src/config/__tests__/memory-retrospective-schema.test.ts +40 -0
  304. package/src/config/__tests__/plugin-updates-schema.test.ts +43 -0
  305. package/src/config/__tests__/profile-tool-support.test.ts +131 -0
  306. package/src/config/bundled-skills/AGENTS.md +1 -1
  307. package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
  308. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +3 -3
  309. package/src/config/bundled-skills/schedule/SKILL.md +5 -1
  310. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  311. package/src/config/bundled-skills/settings/TOOLS.json +2 -2
  312. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +1 -0
  313. package/src/config/bundled-skills/subagent/SKILL.md +53 -22
  314. package/src/config/bundled-skills/subagent/TOOLS.json +14 -13
  315. package/src/config/bundled-skills/visualize/SKILL.md +1 -1
  316. package/src/config/default-profile-catalog.ts +6 -2
  317. package/src/config/feature-flag-registry.json +25 -17
  318. package/src/config/llm-resolver.ts +45 -15
  319. package/src/config/loader.ts +70 -1
  320. package/src/config/profile-tool-support.ts +110 -0
  321. package/src/config/sanitize-for-transfer.ts +11 -0
  322. package/src/config/schema.ts +4 -0
  323. package/src/config/schemas/__tests__/stt.test.ts +20 -5
  324. package/src/config/schemas/channels.ts +13 -0
  325. package/src/config/schemas/memory-retrospective.ts +25 -0
  326. package/src/config/schemas/plugin-updates.ts +55 -0
  327. package/src/config/schemas/services.ts +8 -4
  328. package/src/config/schemas/stt.ts +17 -5
  329. package/src/config/schemas/timeouts.ts +1 -1
  330. package/src/contacts/__tests__/guardian-delivery-reader.test.ts +16 -0
  331. package/src/contacts/guardian-delivery-reader.ts +29 -2
  332. package/src/context/compactor.ts +4 -4
  333. package/src/context/post-turn-tool-result-truncation.ts +32 -16
  334. package/src/context/strip-injections.ts +42 -0
  335. package/src/context/tool-result-spool.ts +32 -18
  336. package/src/credential-execution/ces-runtime.ts +3 -0
  337. package/src/credential-execution/client.ts +22 -1
  338. package/src/credential-execution/process-manager.test.ts +99 -0
  339. package/src/credential-execution/process-manager.ts +62 -16
  340. package/src/daemon/__tests__/abort-null-controller.test.ts +141 -5
  341. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +8 -12
  342. package/src/daemon/__tests__/install-assistant-command.test.ts +234 -0
  343. package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +2 -4
  344. package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +20 -29
  345. package/src/daemon/channel-ui-capability.ts +4 -4
  346. package/src/daemon/conversation-agent-loop-handlers.ts +117 -61
  347. package/src/daemon/conversation-agent-loop.ts +318 -148
  348. package/src/daemon/conversation-attachments.ts +1 -1
  349. package/src/daemon/conversation-error.ts +8 -1
  350. package/src/daemon/conversation-initial-prompt.ts +16 -38
  351. package/src/daemon/conversation-lifecycle.ts +154 -32
  352. package/src/daemon/conversation-messaging.ts +106 -43
  353. package/src/daemon/conversation-process.ts +131 -33
  354. package/src/daemon/conversation-queue-manager.ts +10 -0
  355. package/src/daemon/conversation-runtime-assembly.ts +9 -4
  356. package/src/daemon/conversation-store.ts +52 -3
  357. package/src/daemon/conversation-surface-state.ts +9 -0
  358. package/src/daemon/conversation-surfaces.ts +403 -210
  359. package/src/daemon/conversation-tool-setup.ts +56 -7
  360. package/src/daemon/conversation-turn-finalize.ts +134 -89
  361. package/src/daemon/conversation.ts +111 -27
  362. package/src/daemon/disk-pressure-guard-lifecycle.ts +2 -2
  363. package/src/daemon/disk-pressure-guard.ts +3 -3
  364. package/src/daemon/doordash-steps.ts +5 -5
  365. package/src/daemon/external-plugins-bootstrap.ts +7 -1
  366. package/src/daemon/handlers/config-channels.ts +48 -5
  367. package/src/daemon/handlers/conversation-history.ts +1 -1
  368. package/src/daemon/handlers/conversations.ts +62 -17
  369. package/src/daemon/handlers/shared.ts +12 -0
  370. package/src/daemon/handlers/skills.ts +11 -1
  371. package/src/daemon/identity-helpers.ts +38 -10
  372. package/src/daemon/install-assistant-command.ts +322 -0
  373. package/src/daemon/lifecycle.ts +14 -3
  374. package/src/daemon/message-types/conversations.ts +6 -7
  375. package/src/daemon/message-types/sync.ts +1 -0
  376. package/src/daemon/persist-media-references.ts +23 -14
  377. package/src/daemon/process-message.ts +6 -6
  378. package/src/daemon/tool-setup-types.ts +19 -122
  379. package/src/daemon/tool-side-effects.ts +17 -94
  380. package/src/daemon/trust-context-types.ts +39 -0
  381. package/src/daemon/trust-context.ts +14 -6
  382. package/src/daemon/turn-tail-chain.ts +73 -0
  383. package/src/daemon/web-search-history.ts +47 -33
  384. package/src/heartbeat/heartbeat-service.ts +6 -6
  385. package/src/ipc/__tests__/socket-path.test.ts +21 -0
  386. package/src/ipc/assistant-server.ts +17 -10
  387. package/src/ipc/cli-client.ts +10 -1
  388. package/src/ipc/routes/__tests__/documents-sync-ipc-routes.test.ts +56 -0
  389. package/src/ipc/routes/documents-sync-ipc-routes.ts +42 -0
  390. package/src/ipc/socket-cleanup.ts +9 -7
  391. package/src/ipc/socket-path.ts +4 -96
  392. package/src/live-voice/__tests__/live-voice-archive.test.ts +16 -16
  393. package/src/live-voice/__tests__/live-voice-attach-image.test.ts +209 -0
  394. package/src/live-voice/__tests__/live-voice-connection.test.ts +20 -0
  395. package/src/live-voice/__tests__/live-voice-integration.test.ts +7 -5
  396. package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +265 -0
  397. package/src/live-voice/__tests__/live-voice-stt.test.ts +6 -1
  398. package/src/live-voice/__tests__/live-voice-vad.test.ts +35 -15
  399. package/src/live-voice/__tests__/protocol.test.ts +52 -0
  400. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +3 -0
  401. package/src/live-voice/live-voice-archive.ts +13 -13
  402. package/src/live-voice/live-voice-connection.ts +7 -1
  403. package/src/live-voice/live-voice-photo.ts +169 -0
  404. package/src/live-voice/live-voice-session.ts +108 -4
  405. package/src/live-voice/protocol.ts +89 -1
  406. package/src/mcp/client.ts +10 -0
  407. package/src/messaging/providers/__tests__/callback-routing.test.ts +5 -1
  408. package/src/messaging/providers/__tests__/transport-dispatch.test.ts +66 -4
  409. package/src/messaging/providers/callback-routing.ts +1 -0
  410. package/src/messaging/providers/discord/api.ts +312 -0
  411. package/src/messaging/providers/discord/dm-delivery.test.ts +204 -0
  412. package/src/messaging/providers/discord/render.test.ts +204 -0
  413. package/src/messaging/providers/discord/render.ts +195 -0
  414. package/src/messaging/providers/discord/send.test.ts +179 -0
  415. package/src/messaging/providers/discord/send.ts +212 -0
  416. package/src/messaging/providers/discord/transport.ts +81 -0
  417. package/src/messaging/providers/index.ts +3 -1
  418. package/src/messaging/providers/retry-policy.test.ts +247 -0
  419. package/src/messaging/providers/retry-policy.ts +206 -0
  420. package/src/messaging/providers/slack/mention-source.test.ts +285 -0
  421. package/src/messaging/providers/slack/mention-source.ts +287 -0
  422. package/src/messaging/providers/telegram-bot/api.ts +47 -130
  423. package/src/messaging/providers/whatsapp/api.ts +47 -136
  424. package/src/monitoring/__tests__/db-integrity-sample.test.ts +4 -1
  425. package/src/monitoring/__tests__/plugin-auto-update.test.ts +332 -0
  426. package/src/monitoring/db-integrity-sample.ts +6 -1
  427. package/src/monitoring/plugin-auto-update.ts +359 -0
  428. package/src/monitoring/resource-sampler.ts +21 -5
  429. package/src/monitoring/worker.ts +13 -0
  430. package/src/notifications/__tests__/assistant-reply-producer.test.ts +375 -2
  431. package/src/notifications/__tests__/broadcaster.test.ts +37 -1
  432. package/src/notifications/__tests__/copy-composer.test.ts +165 -0
  433. package/src/notifications/__tests__/emit-signal-pipeline-failure.test.ts +205 -0
  434. package/src/notifications/__tests__/notification-utils.test.ts +249 -0
  435. package/src/notifications/adapters/platform.ts +31 -2
  436. package/src/notifications/assistant-reply-producer.ts +79 -32
  437. package/src/notifications/broadcaster.ts +30 -10
  438. package/src/notifications/copy-composer.ts +69 -0
  439. package/src/notifications/emit-signal.ts +82 -15
  440. package/src/notifications/events-store.ts +10 -2
  441. package/src/notifications/home-feed-side-effect.ts +6 -3
  442. package/src/notifications/notification-utils.ts +173 -5
  443. package/src/notifications/signal.ts +12 -0
  444. package/src/oauth/AGENTS.md +4 -2
  445. package/src/oauth/byo-connection.ts +6 -1
  446. package/src/oauth/credential-token-resolver.ts +3 -10
  447. package/src/oauth/manual-token-connection.ts +29 -64
  448. package/src/oauth/manual-token-providers.ts +62 -0
  449. package/src/oauth/provider-serializer.ts +13 -0
  450. package/src/oauth/seed-providers.ts +62 -11
  451. package/src/onboarding/onboarding-events-store.ts +91 -1
  452. package/src/permissions/question-prompter.test.ts +4 -0
  453. package/src/permissions/question-prompter.ts +21 -4
  454. package/src/persistence/__tests__/conversation-lineage.test.ts +248 -0
  455. package/src/persistence/attachments-store.ts +15 -15
  456. package/src/persistence/conversation-attention-store.ts +30 -10
  457. package/src/persistence/conversation-bootstrap.ts +17 -0
  458. package/src/persistence/conversation-crud.ts +363 -97
  459. package/src/persistence/conversation-group-migration.ts +1 -1
  460. package/src/persistence/conversation-key-store.ts +38 -10
  461. package/src/persistence/conversation-lineage.ts +226 -0
  462. package/src/persistence/conversation-plugin-facade.ts +28 -3
  463. package/src/persistence/conversation-queries.ts +207 -33
  464. package/src/persistence/conversation-types.ts +107 -1
  465. package/src/persistence/jobs-store.ts +32 -8
  466. package/src/persistence/llm-usage-store.ts +22 -0
  467. package/src/persistence/migrations/361-normalize-managed-connection-rows.test.ts +168 -0
  468. package/src/persistence/migrations/361-normalize-managed-connection-rows.ts +76 -0
  469. package/src/persistence/migrations/362-add-conversation-subagent-kind.test.ts +187 -0
  470. package/src/persistence/migrations/362-add-conversation-subagent-kind.ts +93 -0
  471. package/src/persistence/migrations/363-backfill-schedule-inference-profile.test.ts +229 -0
  472. package/src/persistence/migrations/363-backfill-schedule-inference-profile.ts +127 -0
  473. package/src/persistence/migrations/364-add-schedule-source-key.test.ts +120 -0
  474. package/src/persistence/migrations/364-add-schedule-source-key.ts +43 -0
  475. package/src/persistence/migrations/365-add-conversation-fork-strategy.ts +27 -0
  476. package/src/persistence/schema/conversations.ts +32 -0
  477. package/src/persistence/schema/infrastructure.ts +3 -0
  478. package/src/persistence/steps.ts +30 -0
  479. package/src/persistence/subagent-store.ts +148 -6
  480. package/src/platform/managed-speech.test.ts +20 -0
  481. package/src/platform/managed-speech.ts +9 -0
  482. package/src/plugin-api/index.ts +8 -0
  483. package/src/plugin-api/webhook-url.ts +151 -0
  484. package/src/plugins/__tests__/installed-plugin-dirs.test.ts +82 -0
  485. package/src/plugins/__tests__/source-fingerprint.test.ts +5 -1
  486. package/src/plugins/collect-source-versions.ts +4 -27
  487. package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +5 -5
  488. package/src/plugins/defaults/exploration-drift/package.json +1 -1
  489. package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +4 -2
  490. package/src/plugins/defaults/image-recovery/recover.ts +67 -57
  491. package/src/plugins/defaults/index.ts +1 -1
  492. package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +64 -18
  493. package/src/plugins/defaults/memory/__tests__/jobs-worker-outcome-contract.test.ts +242 -0
  494. package/src/plugins/defaults/memory/__tests__/jobs-worker-retrospective-sweep.test.ts +24 -1
  495. package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +48 -3
  496. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +511 -19
  497. package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +39 -3
  498. package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +493 -0
  499. package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +5 -4
  500. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +5 -1
  501. package/src/plugins/defaults/memory/job-handlers.ts +87 -5
  502. package/src/plugins/defaults/memory/jobs-worker.ts +60 -6
  503. package/src/plugins/defaults/memory/memory-retrospective-constants.ts +11 -0
  504. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +29 -0
  505. package/src/plugins/defaults/memory/memory-retrospective-job.ts +342 -60
  506. package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +23 -3
  507. package/src/plugins/defaults/memory/substrate/consolidation-lock.ts +9 -4
  508. package/src/plugins/defaults/memory/substrate/sweep-job.ts +7 -0
  509. package/src/plugins/defaults/memory/v1/graph/injection.ts +1 -1
  510. package/src/plugins/defaults/memory/v2/router.ts +8 -0
  511. package/src/plugins/defaults/turn-context/unified-turn-context.ts +1 -2
  512. package/src/plugins/external-plugin-loader.ts +17 -8
  513. package/src/plugins/installed-plugin-dirs.ts +101 -0
  514. package/src/plugins/mtime-cache.ts +34 -22
  515. package/src/plugins/types.ts +69 -8
  516. package/src/prompts/persona-resolver.ts +6 -2
  517. package/src/prompts/system-prompt.ts +72 -17
  518. package/src/providers/__tests__/inference.test.ts +40 -0
  519. package/src/providers/__tests__/preflight-resolved-config.test.ts +58 -1
  520. package/src/providers/__tests__/retry-callsite.test.ts +67 -0
  521. package/src/providers/__tests__/vellum-connection-routing.test.ts +42 -11
  522. package/src/providers/anthropic/client.ts +112 -95
  523. package/src/providers/connection-resolution.ts +35 -1
  524. package/src/providers/gemini/client.ts +5 -5
  525. package/src/providers/inference/adapter-factory.ts +16 -10
  526. package/src/providers/inference/auth.ts +16 -0
  527. package/src/providers/inference/connection-availability.ts +164 -12
  528. package/src/providers/inference/connections.ts +25 -1
  529. package/src/providers/media-resolve.ts +21 -11
  530. package/src/providers/model-catalog.ts +15 -0
  531. package/src/providers/openai/chat-completions-provider.ts +4 -4
  532. package/src/providers/openai/responses-provider.ts +12 -25
  533. package/src/providers/registry.ts +9 -4
  534. package/src/providers/retry.ts +25 -0
  535. package/src/providers/server-tool-pairing.ts +134 -0
  536. package/src/providers/speech-to-text/__tests__/resolve.test.ts +187 -6
  537. package/src/providers/speech-to-text/deepgram.ts +1 -0
  538. package/src/providers/speech-to-text/resolve.ts +80 -10
  539. package/src/providers/speech-to-text/vellum-managed.ts +7 -1
  540. package/src/providers/speech-to-text/vellum-speech-relay-connection.ts +3 -1
  541. package/src/providers/types.ts +26 -6
  542. package/src/providers/vellum-model-routing.ts +6 -7
  543. package/src/runtime/AGENTS.md +2 -0
  544. package/src/runtime/__tests__/agent-wake.test.ts +16 -16
  545. package/src/runtime/__tests__/background-job-runner.test.ts +0 -144
  546. package/src/runtime/__tests__/desktop-presence.test.ts +162 -0
  547. package/src/runtime/agent-wake.ts +63 -24
  548. package/src/runtime/assistant-event-hub.ts +87 -12
  549. package/src/runtime/auth/__tests__/guard-tests.test.ts +2 -0
  550. package/src/runtime/auth/__tests__/scopes.test.ts +20 -0
  551. package/src/runtime/auth/same-actor.ts +56 -8
  552. package/src/runtime/auth/scopes.ts +12 -0
  553. package/src/runtime/auth/types.ts +2 -0
  554. package/src/runtime/background-job-runner.ts +5 -27
  555. package/src/runtime/channel-readiness-service.ts +59 -3
  556. package/src/runtime/channel-readiness-types.ts +18 -0
  557. package/src/runtime/desktop-presence.ts +69 -0
  558. package/src/runtime/http-server.ts +12 -0
  559. package/src/runtime/local-actor-identity.ts +11 -9
  560. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  561. package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
  562. package/src/runtime/routes/__tests__/client-routes.test.ts +186 -14
  563. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +547 -1
  564. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +162 -7
  565. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +14 -10
  566. package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +340 -3
  567. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +28 -1
  568. package/src/runtime/routes/__tests__/plugins-routes.test.ts +173 -1
  569. package/src/runtime/routes/__tests__/question-routes.test.ts +64 -0
  570. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +20 -0
  571. package/src/runtime/routes/__tests__/skill-history-route.test.ts +116 -0
  572. package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +60 -2
  573. package/src/runtime/routes/archive-utils.ts +16 -12
  574. package/src/runtime/routes/attachment-routes.ts +13 -6
  575. package/src/runtime/routes/canned-reply-release.ts +54 -0
  576. package/src/runtime/routes/channel-verification-routes.ts +2 -27
  577. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +5 -0
  578. package/src/runtime/routes/client-routes.ts +114 -2
  579. package/src/runtime/routes/conversation-cli-routes.ts +10 -12
  580. package/src/runtime/routes/conversation-list-routes.ts +59 -10
  581. package/src/runtime/routes/conversation-management-routes.ts +47 -18
  582. package/src/runtime/routes/conversation-query-routes.ts +32 -53
  583. package/src/runtime/routes/conversation-routes.ts +360 -293
  584. package/src/runtime/routes/credential-prompt-routes.ts +23 -2
  585. package/src/runtime/routes/debug-routes.ts +4 -1
  586. package/src/runtime/routes/default-provider-routes.ts +7 -11
  587. package/src/runtime/routes/documents-routes.ts +44 -1
  588. package/src/runtime/routes/events-routes.ts +28 -1
  589. package/src/runtime/routes/host-app-control-routes.ts +2 -0
  590. package/src/runtime/routes/host-bash-routes.ts +2 -0
  591. package/src/runtime/routes/host-browser-routes.ts +2 -0
  592. package/src/runtime/routes/host-cu-routes.ts +2 -0
  593. package/src/runtime/routes/host-file-routes.ts +2 -0
  594. package/src/runtime/routes/host-transfer-routes.ts +4 -0
  595. package/src/runtime/routes/identity-routes.ts +6 -6
  596. package/src/runtime/routes/inbound-message-handler.ts +5 -5
  597. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +7 -3
  598. package/src/runtime/routes/inbound-stages/background-dispatch.ts +14 -0
  599. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -2
  600. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +14 -11
  601. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -17
  602. package/src/runtime/routes/inference-profile-availability-guard.ts +171 -0
  603. package/src/runtime/routes/inference-profile-session-handler.ts +26 -2
  604. package/src/runtime/routes/inference-profile-session-routes.ts +2 -1
  605. package/src/runtime/routes/inference-profiles-routes.ts +152 -73
  606. package/src/runtime/routes/inference-provider-connection-routes.ts +0 -16
  607. package/src/runtime/routes/llm-call-sites-routes.ts +13 -0
  608. package/src/runtime/routes/log-export-routes.ts +1 -1
  609. package/src/runtime/routes/notification-routes.ts +0 -14
  610. package/src/runtime/routes/oauth-providers.ts +1 -0
  611. package/src/runtime/routes/plugins-routes.ts +106 -1
  612. package/src/runtime/routes/profiler-routes.ts +4 -2
  613. package/src/runtime/routes/question-routes.ts +28 -10
  614. package/src/runtime/routes/retrospective-routes.ts +9 -3
  615. package/src/runtime/routes/schedule-routes.ts +210 -12
  616. package/src/runtime/routes/secret-routes.ts +40 -23
  617. package/src/runtime/routes/settings-routes.ts +41 -13
  618. package/src/runtime/routes/skills-routes.ts +79 -0
  619. package/src/runtime/routes/ui-snapshot-routes.ts +1 -0
  620. package/src/runtime/routes/wake-conversation-routes.ts +23 -0
  621. package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
  622. package/src/runtime/services/conversation-serializer.ts +24 -9
  623. package/src/runtime/sync/documents-sidecar-publish.test.ts +101 -0
  624. package/src/runtime/sync/resource-sync-events.ts +79 -1
  625. package/src/runtime/sync/worker-daemon-notify.test.ts +34 -0
  626. package/src/runtime/sync/worker-daemon-notify.ts +44 -6
  627. package/src/runtime/verification-outbound-actions.ts +250 -222
  628. package/src/runtime/verification-templates.ts +41 -30
  629. package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +614 -0
  630. package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1066 -0
  631. package/src/schedule/inference-profile.ts +64 -3
  632. package/src/schedule/plugin-schedule-declarations.ts +518 -0
  633. package/src/schedule/plugin-schedule-reconciler.ts +605 -0
  634. package/src/schedule/plugin-schedules-gate.ts +23 -0
  635. package/src/schedule/schedule-store.ts +520 -26
  636. package/src/schedule/scheduler.ts +38 -0
  637. package/src/security/credential-backend.ts +51 -4
  638. package/src/security/encrypted-store.ts +64 -42
  639. package/src/security/secure-keys.ts +55 -7
  640. package/src/skills/catalog-install.ts +20 -7
  641. package/src/skills/inline-command-runner.ts +2 -7
  642. package/src/skills/skill-history.test.ts +269 -0
  643. package/src/skills/skill-history.ts +250 -0
  644. package/src/skills/skillssh-registry.ts +1 -1
  645. package/src/stt/daemon-batch-transcriber.ts +8 -6
  646. package/src/subagent/__tests__/consult-prompt.test.ts +25 -0
  647. package/src/subagent/consult-prompt.ts +3 -1
  648. package/src/subagent/consult-transcript.ts +1 -1
  649. package/src/subagent/manager.ts +304 -44
  650. package/src/subagent/progress-events.ts +35 -0
  651. package/src/subagent/role-resolution.ts +88 -0
  652. package/src/subagent/types.ts +302 -67
  653. package/src/subagent/validate-allowlists.ts +3 -4
  654. package/src/telegram/__tests__/webhook-health.test.ts +73 -1
  655. package/src/telegram/webhook-health.ts +101 -3
  656. package/src/telemetry/__tests__/telemetry-event-fixtures.ts +2 -0
  657. package/src/telemetry/activation-funnel.ts +6 -1
  658. package/src/telemetry/live-voice-funnel.ts +75 -0
  659. package/src/telemetry/telemetry-event-sources.ts +6 -0
  660. package/src/telemetry/telemetry-wire-source.json +1 -1
  661. package/src/telemetry/telemetry-wire.generated.ts +2 -0
  662. package/src/telemetry/types.ts +23 -4
  663. package/src/telemetry/usage-telemetry-reporter.test.ts +4 -0
  664. package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +1 -1
  665. package/src/tools/ask-question/ask-question-tool.test.ts +118 -3
  666. package/src/tools/ask-question/ask-question-tool.ts +56 -2
  667. package/src/tools/browser/browser-execution.ts +1 -1
  668. package/src/tools/calls/call-start.ts +8 -5
  669. package/src/tools/conversation-groups/move_to_group.ts +10 -12
  670. package/src/tools/document/document-tool.ts +11 -4
  671. package/src/tools/execution-timeout.ts +9 -2
  672. package/src/tools/executor.ts +7 -6
  673. package/src/tools/filesystem/edit.ts +1 -1
  674. package/src/tools/filesystem/list.ts +1 -1
  675. package/src/tools/filesystem/read.ts +7 -13
  676. package/src/tools/filesystem/search.ts +23 -21
  677. package/src/tools/filesystem/write.ts +4 -1
  678. package/src/tools/host-filesystem/edit.ts +7 -2
  679. package/src/tools/host-filesystem/read.ts +21 -8
  680. package/src/tools/host-filesystem/write.ts +10 -2
  681. package/src/tools/host-terminal/host-shell.ts +2 -2
  682. package/src/tools/mcp/mcp-tool-factory.ts +25 -1
  683. package/src/tools/permission-checker.ts +8 -3
  684. package/src/tools/schedule/delete.ts +13 -1
  685. package/src/tools/schedule/list.ts +14 -3
  686. package/src/tools/schedule/update.ts +56 -33
  687. package/src/tools/shared/filesystem/audio-read.ts +6 -4
  688. package/src/tools/shared/filesystem/file-ops-service.ts +176 -116
  689. package/src/tools/shared/filesystem/image-read.ts +12 -12
  690. package/src/tools/shared/filesystem/path-policy.ts +70 -5
  691. package/src/tools/shared/filesystem/size-guard.ts +6 -6
  692. package/src/tools/shared/input-misuse.ts +72 -0
  693. package/src/tools/skills/scaffold-managed.ts +82 -0
  694. package/src/tools/skills/skill-tool-factory.ts +14 -1
  695. package/src/tools/subagent/consult-deadline.ts +12 -7
  696. package/src/tools/subagent/message.ts +3 -1
  697. package/src/tools/subagent/read.ts +66 -4
  698. package/src/tools/subagent/spawn.ts +500 -78
  699. package/src/tools/tool-approval-handler.ts +45 -4
  700. package/src/tools/types.ts +22 -3
  701. package/src/tools/ui-surface/surface-shape-docs.ts +1 -1
  702. package/src/tools/ui-surface/visual-validation.ts +2 -0
  703. package/src/usage/__tests__/subagent-attribution.test.ts +109 -0
  704. package/src/usage/subagent-attribution.ts +108 -0
  705. package/src/util/__tests__/sqlite-retry.test.ts +112 -0
  706. package/src/util/abort-reasons.ts +16 -0
  707. package/src/util/ansi.ts +44 -0
  708. package/src/util/disk-usage.ts +17 -13
  709. package/src/util/image-conversion.ts +20 -13
  710. package/src/util/schedule-source-key.ts +23 -0
  711. package/src/util/worker-process.ts +7 -1
  712. package/src/workspace/git-service.ts +33 -9
  713. package/src/workspace/migrations/140-repair-seed-pinned-memory-v3-live.ts +260 -0
  714. package/src/workspace/migrations/141-stt-english-default-to-multilingual.ts +111 -0
  715. package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +126 -0
  716. package/src/workspace/migrations/registry.ts +4 -0
  717. package/src/workspace/top-level-renderer.ts +15 -2
  718. package/src/__tests__/tool-side-effects-slack-dm.test.ts +0 -357
  719. package/src/daemon/install-symlink.ts +0 -207
  720. package/src/notifications/deferred-emit.ts +0 -147
@@ -7,10 +7,14 @@
7
7
  */
8
8
 
9
9
  import { createRequire } from "node:module";
10
+ import { join } from "node:path";
10
11
 
11
12
  import type { Command } from "commander";
12
13
 
13
14
  import { cliIpcCall } from "../../ipc/cli-client.js";
15
+ import { stripAnsiAndControlChars } from "../../util/ansi.js";
16
+ import { getWorkspacePluginsDir } from "../../util/platform.js";
17
+ import { truncate } from "../../util/truncate.js";
14
18
  import { yellow } from "../lib/cli-colors.js";
15
19
  import { applyCommandHelp, subcommand } from "../lib/cli-command-help.js";
16
20
  import { confirmPrompt } from "../lib/confirm-prompt.js";
@@ -20,6 +24,7 @@ import type {
20
24
  PluginRemoteInfo,
21
25
  } from "../lib/inspect-plugin.js";
22
26
  import type {
27
+ ConfirmStagedInstall,
23
28
  InstallPluginOptions,
24
29
  PluginFetchSource,
25
30
  } from "../lib/install-from-github.js";
@@ -37,6 +42,7 @@ import {
37
42
  } from "../lib/plugin-constants.js";
38
43
  import type { FingerprintComparison } from "../lib/plugin-fingerprint.js";
39
44
  import type { PluginPinHistoryEntry } from "../lib/plugin-pin-history.js";
45
+ import type { PluginScheduleSurface } from "../lib/plugin-surfaces.js";
40
46
  import { runPublish } from "../lib/publish-plugin.js";
41
47
  import { registerCommand } from "../lib/register-command.js";
42
48
  import {
@@ -99,6 +105,11 @@ const libs = {
99
105
  "../lib/search-plugins.js",
100
106
  ) as typeof import("../lib/search-plugins.js");
101
107
  },
108
+ get surfaces() {
109
+ return loadModule(
110
+ "../lib/plugin-surfaces.js",
111
+ ) as typeof import("../lib/plugin-surfaces.js");
112
+ },
102
113
  get uninstall() {
103
114
  return loadModule(
104
115
  "../lib/uninstall-plugin.js",
@@ -157,6 +168,16 @@ export function registerPluginsCommand(program: Command): void {
157
168
  const usesMarketplaceGit =
158
169
  !direct && Boolean(opts.pin || opts.ref || opts.allowUnreviewed);
159
170
 
171
+ // Consent gate the installers run between staging and finalize:
172
+ // a plugin that declares schedules gets them listed and, unless
173
+ // --force, must be confirmed before anything lands on disk that
174
+ // the daemon's schedule reconciler could arm.
175
+ const confirmStaged: ConfirmStagedInstall = (staged) =>
176
+ confirmDeclaredSchedules(staged, "install", {
177
+ force: Boolean(opts.force),
178
+ json: false,
179
+ });
180
+
160
181
  let result;
161
182
  let untrusted = false;
162
183
  if (!direct && !usesMarketplaceGit) {
@@ -167,7 +188,7 @@ export function registerPluginsCommand(program: Command): void {
167
188
  if (libs.catalogLocal.arePlatformFeaturesEnabled()) {
168
189
  result = await libs.installPlatform.installPluginViaPlatform(
169
190
  { name: nameOrUrl, force: opts.force },
170
- { fetch: globalThis.fetch.bind(globalThis) },
191
+ { fetch: globalThis.fetch.bind(globalThis), confirmStaged },
171
192
  );
172
193
  } else {
173
194
  const source =
@@ -190,7 +211,7 @@ export function registerPluginsCommand(program: Command): void {
190
211
  ref: source.ref,
191
212
  },
192
213
  },
193
- { fetch: globalThis.fetch.bind(globalThis) },
214
+ { fetch: globalThis.fetch.bind(globalThis), confirmStaged },
194
215
  );
195
216
  }
196
217
  } else {
@@ -210,6 +231,7 @@ export function registerPluginsCommand(program: Command): void {
210
231
  }
211
232
  result = await libs.installGitHub.installPlugin(installOpts, {
212
233
  fetch: globalThis.fetch.bind(globalThis),
234
+ confirmStaged,
213
235
  });
214
236
  }
215
237
  log.info(
@@ -231,6 +253,11 @@ export function registerPluginsCommand(program: Command): void {
231
253
  `Installed ${label} "${result.name}" (${result.fileCount} file${result.fileCount === 1 ? "" : "s"})${pinned} → ${result.target}`,
232
254
  );
233
255
  } catch (err) {
256
+ if (err instanceof libs.installGitHub.PluginInstallDeclinedError) {
257
+ // The consent gate already printed the outcome and set the exit
258
+ // code; the install was aborted with nothing left on disk.
259
+ return;
260
+ }
234
261
  if (err instanceof libs.installGitHub.PluginAlreadyInstalledError) {
235
262
  console.error(`${err.message}\nPass --force to overwrite.`);
236
263
  process.exitCode = 1;
@@ -407,7 +434,10 @@ export function registerPluginsCommand(program: Command): void {
407
434
  "plugin inspect",
408
435
  );
409
436
 
410
- for (const line of formatInspection(inspection)) {
437
+ const describeCron = inspection.surfaces?.schedules.length
438
+ ? await loadCronDescriber()
439
+ : null;
440
+ for (const line of formatInspection(inspection, describeCron)) {
411
441
  console.log(line);
412
442
  }
413
443
  } catch (err) {
@@ -665,7 +695,12 @@ export function registerPluginsCommand(program: Command): void {
665
695
  subcommand(plugins, "upgrade").action(
666
696
  async (
667
697
  name: string,
668
- opts: { dryRun?: boolean; strategy?: string; json?: boolean },
698
+ opts: {
699
+ dryRun?: boolean;
700
+ strategy?: string;
701
+ json?: boolean;
702
+ force?: boolean;
703
+ },
669
704
  ) => {
670
705
  const strategy = opts.strategy;
671
706
  if (
@@ -682,11 +717,16 @@ export function registerPluginsCommand(program: Command): void {
682
717
  // Prefer the daemon: when the upgrade re-materializes files it runs
683
718
  // the plugin's `shutdown` + `init` hooks in the main process —
684
719
  // symmetric to how install/uninstall run their lifecycle there.
720
+ // The daemon route is unattended (no staging prompt); a schedule
721
+ // the upgraded revision adds is surfaced by the reconciler's
722
+ // `schedule.declared` notification, and mirrored at the terminal
723
+ // by the declared-schedules listing printed after the upgrade.
685
724
  // Fall back to a local upgrade only when the daemon is unreachable
686
725
  // (a transport error carries no `statusCode`); an operator can still
687
726
  // upgrade while it's stopped, and the new code is picked up on the
688
727
  // daemon's next start. A daemon-side decision (not installed, not
689
728
  // upgradable, …) is surfaced rather than silently retried locally.
729
+ const preUpgradeScheduleNames = listInstalledScheduleNames(name);
690
730
  const daemon = await cliIpcCall<PluginUpgradeResult>(
691
731
  "plugins_upgrade",
692
732
  {
@@ -695,20 +735,36 @@ export function registerPluginsCommand(program: Command): void {
695
735
  },
696
736
  );
697
737
  let result: PluginUpgradeResult;
738
+ let upgradedViaDaemon = false;
698
739
  if (daemon.ok && daemon.result) {
699
740
  result = daemon.result;
741
+ upgradedViaDaemon = true;
700
742
  } else if (daemon.statusCode === undefined) {
701
- log.debug(
702
- { name, error: daemon.error },
703
- "upgrade could not reach the daemon; upgrading locally",
704
- );
743
+ // The CLI logger writes debug to stdout, which would corrupt
744
+ // --json output, so under --json the same note goes to stderr.
745
+ // The CLI logger drops structured fields either way.
746
+ const fallbackNote =
747
+ "upgrade could not reach the daemon; upgrading locally";
748
+ if (opts.json) {
749
+ console.error(fallbackNote);
750
+ } else {
751
+ log.debug({ name, error: daemon.error }, fallbackNote);
752
+ }
753
+ // The local path stages in this process, so it gets the same
754
+ // consent gate as install: declared schedules are listed and
755
+ // confirmed (or --force) before the staged tree goes live.
756
+ const confirmStaged: ConfirmStagedInstall = (staged) =>
757
+ confirmDeclaredSchedules(staged, "upgrade", {
758
+ force: Boolean(opts.force),
759
+ json: Boolean(opts.json),
760
+ });
705
761
  result = await libs.upgrade.upgradePlugin(
706
762
  {
707
763
  name,
708
764
  dryRun: opts.dryRun,
709
765
  strategy: strategy as PluginUpgradeStrategy | undefined,
710
766
  },
711
- { fetch: globalThis.fetch.bind(globalThis) },
767
+ { fetch: globalThis.fetch.bind(globalThis), confirmStaged },
712
768
  );
713
769
  } else {
714
770
  console.error(daemon.error ?? "Plugin upgrade failed.");
@@ -736,7 +792,20 @@ export function registerPluginsCommand(program: Command): void {
736
792
  for (const line of formatUpgrade(result)) {
737
793
  console.log(line);
738
794
  }
795
+
796
+ if (upgradedViaDaemon && result.outcome === "upgraded") {
797
+ await printDeclaredSchedulesAfterUpgrade(
798
+ result.name,
799
+ result.target,
800
+ preUpgradeScheduleNames,
801
+ );
802
+ }
739
803
  } catch (err) {
804
+ if (err instanceof libs.installGitHub.PluginInstallDeclinedError) {
805
+ // The consent gate already printed the outcome and set the exit
806
+ // code; the upgrade was aborted with the live install untouched.
807
+ return;
808
+ }
740
809
  if (
741
810
  err instanceof libs.uninstall.PluginNotInstalledError ||
742
811
  err instanceof libs.upgrade.PluginNotUpgradableError ||
@@ -935,6 +1004,209 @@ function printUntrustedPluginWarning(
935
1004
  console.error(yellow(lines.join("\n")));
936
1005
  }
937
1006
 
1007
+ /**
1008
+ * The declared-schedules block for a plugin tree: a heading plus one aligned
1009
+ * row per schedule, or null when the plugin declares none. Callers own the
1010
+ * output stream and any per-row annotation.
1011
+ */
1012
+ async function buildDeclaredScheduleListing(
1013
+ pluginName: string,
1014
+ pluginDir: string,
1015
+ ): Promise<{
1016
+ heading: string;
1017
+ rows: string[];
1018
+ schedules: readonly PluginScheduleSurface[];
1019
+ } | null> {
1020
+ const { schedules } = libs.surfaces.detectPluginSurfaces(pluginDir);
1021
+ if (schedules.length === 0) {
1022
+ return null;
1023
+ }
1024
+ const describeCron = await loadCronDescriber();
1025
+ return {
1026
+ heading: `Plugin "${pluginName}" declares ${schedules.length} schedule${schedules.length === 1 ? "" : "s"}:`,
1027
+ rows: formatScheduleRows(schedules, describeCron),
1028
+ schedules,
1029
+ };
1030
+ }
1031
+
1032
+ /**
1033
+ * List a staged plugin's declared schedules and ask for consent. Schedules run
1034
+ * automatically once armed, so neither an install nor an upgrade may add any
1035
+ * silently: the user either confirms the listing or passes --force. Returns
1036
+ * whether the operation may proceed; a refusal's user-facing outcome (message
1037
+ * + exit code) is fully handled here, so the caller aborts without further
1038
+ * output. `action` selects the install vs upgrade wording.
1039
+ */
1040
+ async function confirmDeclaredSchedules(
1041
+ staged: { name: string; stagingDir: string },
1042
+ action: "install" | "upgrade",
1043
+ opts: { force: boolean; json: boolean },
1044
+ ): Promise<boolean> {
1045
+ const listing = await buildDeclaredScheduleListing(
1046
+ staged.name,
1047
+ staged.stagingDir,
1048
+ );
1049
+ if (!listing) {
1050
+ return true;
1051
+ }
1052
+ // Everything this gate prints is human output: the listing, the prompt
1053
+ // itself, and the cancellation line. Under --json all of it goes to stderr
1054
+ // so it cannot corrupt the JSON document the caller parses off stdout.
1055
+ const write = (line: string): void => {
1056
+ if (opts.json) {
1057
+ console.error(line);
1058
+ } else {
1059
+ console.log(line);
1060
+ }
1061
+ };
1062
+ write(listing.heading);
1063
+ for (const row of listing.rows) {
1064
+ write(` ${row}`);
1065
+ }
1066
+ write(
1067
+ "Schedules run automatically in the background once the plugin is installed.",
1068
+ );
1069
+ if (opts.force) {
1070
+ return true;
1071
+ }
1072
+ const verb = action === "install" ? "Install" : "Upgrade";
1073
+ const result = await confirmPrompt({
1074
+ question: `${verb} "${staged.name}" and allow these schedules? [y/N] `,
1075
+ isTTY: Boolean(process.stdin.isTTY),
1076
+ refuseNonInteractiveMessage: `Refusing to ${action} "${staged.name}" non-interactively: it declares schedules. Pass --force to confirm.`,
1077
+ stdout: opts.json ? process.stderr : undefined,
1078
+ });
1079
+ if (result === "non-interactive") {
1080
+ process.exitCode = 1;
1081
+ return false;
1082
+ }
1083
+ if (result === "denied") {
1084
+ write(`${verb} cancelled.`);
1085
+ return false;
1086
+ }
1087
+ return true;
1088
+ }
1089
+
1090
+ /**
1091
+ * Maximum rendered width of a declared-schedule listing cell. Declaration
1092
+ * strings come from the plugin being installed, so an overlong expression
1093
+ * must not be able to push the consent prompt off-screen.
1094
+ */
1095
+ const MAX_SCHEDULE_CELL_WIDTH = 60;
1096
+
1097
+ /**
1098
+ * Make a plugin-controlled declaration string safe to print next to the
1099
+ * install consent prompt: drop escape sequences and control characters
1100
+ * (which could rewrite or hide the surrounding untrusted-source warning)
1101
+ * and cap the cell width.
1102
+ */
1103
+ function sanitizeScheduleCell(value: string): string {
1104
+ return truncate(stripAnsiAndControlChars(value), MAX_SCHEDULE_CELL_WIDTH);
1105
+ }
1106
+
1107
+ /** Humanizes a cron expression for display; returns the input when unrecognized. */
1108
+ type CronDescriber = (expression: string) => string;
1109
+
1110
+ /**
1111
+ * Load the schedule store's cron humanizer for cadence display. Loaded
1112
+ * lazily inside actions because it lives in the daemon's module graph
1113
+ * (see the `cli/no-daemon-internals` hoisting rule); when it cannot be
1114
+ * loaded, listings fall back to raw expressions.
1115
+ */
1116
+ async function loadCronDescriber(): Promise<CronDescriber | null> {
1117
+ try {
1118
+ const { describeCronExpression } =
1119
+ await import("../../schedule/schedule-store.js");
1120
+ return describeCronExpression;
1121
+ } catch {
1122
+ return null;
1123
+ }
1124
+ }
1125
+
1126
+ /**
1127
+ * Cadence cell for a declared-schedules listing: the humanized cron cadence
1128
+ * with the raw expression kept as ground truth ("Every day at 9:00 AM
1129
+ * (0 9 * * *)"). RRULEs and anything the describer does not recognize stay
1130
+ * as the raw expression alone.
1131
+ */
1132
+ function formatCadenceCell(
1133
+ cadence: string,
1134
+ describeCron: CronDescriber | null,
1135
+ ): string {
1136
+ const described = describeCron?.(cadence);
1137
+ return described && described !== cadence
1138
+ ? `${described} (${cadence})`
1139
+ : cadence;
1140
+ }
1141
+
1142
+ /** Aligned `name cadence (mode)` rows for a declared-schedules listing. */
1143
+ function formatScheduleRows(
1144
+ schedules: readonly PluginScheduleSurface[],
1145
+ describeCron: CronDescriber | null,
1146
+ ): string[] {
1147
+ if (schedules.length === 0) {
1148
+ return [];
1149
+ }
1150
+ const rows = schedules.map((s) => ({
1151
+ name: sanitizeScheduleCell(s.name),
1152
+ cadence: sanitizeScheduleCell(formatCadenceCell(s.cadence, describeCron)),
1153
+ mode: s.mode,
1154
+ }));
1155
+ const nameW = Math.max(...rows.map((r) => r.name.length));
1156
+ const cadenceW = Math.max(...rows.map((r) => r.cadence.length));
1157
+ return rows.map(
1158
+ (r) =>
1159
+ `${r.name.padEnd(nameW)} ${r.cadence.padEnd(cadenceW)} (${r.mode})`,
1160
+ );
1161
+ }
1162
+
1163
+ /**
1164
+ * Names of the schedules the installed copy of a plugin currently declares.
1165
+ * Empty when the plugin (or its schedules/ dir) is absent, or when the
1166
+ * install path cannot be probed at all (for example an unsanitized name);
1167
+ * the upgrade itself surfaces such errors, this snapshot never does.
1168
+ */
1169
+ function listInstalledScheduleNames(name: string): ReadonlySet<string> {
1170
+ try {
1171
+ const surfaces = libs.surfaces.detectPluginSurfaces(
1172
+ join(getWorkspacePluginsDir(), name),
1173
+ );
1174
+ return new Set(surfaces.schedules.map((s) => s.name));
1175
+ } catch {
1176
+ return new Set();
1177
+ }
1178
+ }
1179
+
1180
+ /**
1181
+ * After a daemon-applied upgrade, list the revision's declared schedules with
1182
+ * a `[new]` marker on the ones the previous revision did not declare. The
1183
+ * daemon path has no staging prompt, so this display is how the operator sees
1184
+ * at the terminal what the reconciler's notification says. Display only:
1185
+ * arming decisions stay with the reconciler.
1186
+ */
1187
+ async function printDeclaredSchedulesAfterUpgrade(
1188
+ name: string,
1189
+ target: string,
1190
+ previousNames: ReadonlySet<string>,
1191
+ ): Promise<void> {
1192
+ const listing = await buildDeclaredScheduleListing(name, target);
1193
+ if (!listing) {
1194
+ return;
1195
+ }
1196
+ const { heading, rows, schedules } = listing;
1197
+ console.log("");
1198
+ console.log(heading);
1199
+ schedules.forEach((schedule, index) => {
1200
+ const marker = previousNames.has(schedule.name) ? "" : " [new]";
1201
+ console.log(` ${rows[index]}${marker}`);
1202
+ });
1203
+ if (schedules.some((schedule) => !previousNames.has(schedule.name))) {
1204
+ console.log(
1205
+ "New schedules run automatically in the background. Run 'assistant schedules list' to review them, or 'assistant schedules disable <id>' to turn one off.",
1206
+ );
1207
+ }
1208
+ }
1209
+
938
1210
  /**
939
1211
  * Render a plugin's marketplace-pin history as a table: the pinned commit (short
940
1212
  * SHA), when it was promoted, and a marker for the pin currently active. An
@@ -1059,7 +1331,10 @@ function remoteLocation(remote: PluginRemoteInfo): string {
1059
1331
  * that each carry `timestamp` (the human version), `hash` (the precise id), and
1060
1332
  * `location`, with a `drift` line under the installed copy.
1061
1333
  */
1062
- function formatInspection(inspection: PluginInspection): string[] {
1334
+ function formatInspection(
1335
+ inspection: PluginInspection,
1336
+ describeCron: CronDescriber | null,
1337
+ ): string[] {
1063
1338
  const { name, status, local, remote, remoteError, surfaces } = inspection;
1064
1339
  const lines: string[] = [name, "─".repeat(44)];
1065
1340
  const topRow = (label: string, value: string) =>
@@ -1124,6 +1399,10 @@ function formatInspection(inspection: PluginInspection): string[] {
1124
1399
  surfaceBlock("skills", surfaces.skills);
1125
1400
  surfaceBlock("hooks", surfaces.hooks);
1126
1401
  surfaceBlock("tools", surfaces.tools);
1402
+ surfaceBlock(
1403
+ "schedules",
1404
+ formatScheduleRows(surfaces.schedules, describeCron),
1405
+ );
1127
1406
  }
1128
1407
 
1129
1408
  for (const issue of local?.issues ?? []) {
@@ -68,8 +68,9 @@ Arguments:
68
68
  Behavior:
69
69
  Prints every stored field of the schedule: name, description, mode,
70
70
  expression/syntax, timezone, enabled state, status, next/last run times,
71
- message or script body, inference profile (shown as 'default (mainAgent)'
72
- when none is pinned), routing intent, and retry policy. Works for
71
+ message or script body, inference profile (shown as 'none (mainAgent
72
+ call-site default)' when no named profile resolves), routing intent, and
73
+ retry policy. Works for
73
74
  deferred schedules that 'assistant schedules list' hides by default.
74
75
  Aliased as 'inspect'.
75
76
 
@@ -149,7 +150,7 @@ Examples:
149
150
  {
150
151
  flags: "--profile <name>",
151
152
  description:
152
- "Inference profile (llm.profiles key) the schedule's runs use; defaults to the mainAgent model selection when omitted",
153
+ "Inference profile (llm.profiles key) the schedule's runs use; when omitted the schedule is pinned to your current default profile",
153
154
  },
154
155
  {
155
156
  flags: "--no-enabled",
@@ -170,8 +171,9 @@ Options:
170
171
  --timeout-ms <ms> Script timeout override in ms (--mode script).
171
172
  -t, --timezone <tz> IANA timezone applied to the expression.
172
173
  --profile <name> Inference profile (llm.profiles key) the schedule's
173
- runs use. When omitted, runs use the default
174
- the mainAgent call site's model selection.
174
+ runs use. When omitted, the schedule is pinned to
175
+ your current default profile so its model stays
176
+ put when that default changes.
175
177
  --no-enabled Create the schedule disabled. Defaults to enabled.
176
178
  --json Output the updated schedule list as compact JSON.
177
179
 
@@ -279,12 +281,12 @@ Examples:
279
281
  {
280
282
  flags: "--profile <name>",
281
283
  description:
282
- "Inference profile (llm.profiles key) the schedule's runs use; the default when unset is the mainAgent model selection",
284
+ "Inference profile (llm.profiles key) the schedule's runs use",
283
285
  },
284
286
  {
285
287
  flags: "--clear-profile",
286
288
  description:
287
- "Clear the inference profile and revert to the default mainAgent model selection",
289
+ "Re-pin the schedule to your current default inference profile",
288
290
  },
289
291
  {
290
292
  flags: "--json",
@@ -310,11 +312,11 @@ Options:
310
312
  --clear-timeout Remove the timeout override (mutually exclusive
311
313
  with --timeout-ms).
312
314
  --profile <name> Inference profile (llm.profiles key) the schedule's
313
- runs use. When no profile is set, runs use the
314
- default the mainAgent call site's model selection.
315
- --clear-profile Remove the inference profile and revert to the
316
- default mainAgent model selection (mutually
317
- exclusive with --profile).
315
+ runs use. Every schedule is pinned to one, so its
316
+ model stays put when your default changes.
317
+ --clear-profile Re-pin the schedule to your current default
318
+ inference profile (mutually exclusive with
319
+ --profile).
318
320
  --json Output the updated schedule list as compact JSON.
319
321
 
320
322
  Arguments:
@@ -1,6 +1,7 @@
1
1
  import type { Command } from "commander";
2
2
 
3
3
  import { cliIpcCall, exitFromIpcResult } from "../../ipc/cli-client.js";
4
+ import { describeScheduleSource } from "../../util/schedule-source-key.js";
4
5
  import { applyCommandHelp, subcommand } from "../lib/cli-command-help.js";
5
6
  import { formatCostUsd } from "../lib/cli-output.js";
6
7
  import { confirmPrompt } from "../lib/confirm-prompt.js";
@@ -36,6 +37,8 @@ interface ScheduleRecord {
36
37
  routingIntent: string;
37
38
  reuseConversation: boolean;
38
39
  wakeConversationId: string | null;
40
+ sourceKey: string | null;
41
+ userEnabled: boolean | null;
39
42
  isOneShot: boolean;
40
43
  }
41
44
 
@@ -115,6 +118,7 @@ export function registerSchedulesCommand(program: Command): void {
115
118
  name: schedule.name,
116
119
  enabled: schedule.enabled ? "enabled" : "disabled",
117
120
  mode: schedule.mode,
121
+ source: describeScheduleSource(schedule.sourceKey) ?? "",
118
122
  schedule: describeSchedule(schedule),
119
123
  nextRun: formatTimestamp(schedule.nextRunAt),
120
124
  lastStatus: schedule.lastStatus ?? "—",
@@ -125,6 +129,7 @@ export function registerSchedulesCommand(program: Command): void {
125
129
  "NAME",
126
130
  "ENABLED",
127
131
  "MODE",
132
+ "SOURCE",
128
133
  "SCHEDULE",
129
134
  "NEXT RUN",
130
135
  "LAST STATUS",
@@ -137,6 +142,7 @@ export function registerSchedulesCommand(program: Command): void {
137
142
  headers[4].length,
138
143
  headers[5].length,
139
144
  headers[6].length,
145
+ headers[7].length,
140
146
  ];
141
147
 
142
148
  for (const row of rows) {
@@ -144,9 +150,10 @@ export function registerSchedulesCommand(program: Command): void {
144
150
  widths[1] = Math.max(widths[1], row.name.length);
145
151
  widths[2] = Math.max(widths[2], row.enabled.length);
146
152
  widths[3] = Math.max(widths[3], row.mode.length);
147
- widths[4] = Math.max(widths[4], row.schedule.length);
148
- widths[5] = Math.max(widths[5], row.nextRun.length);
149
- widths[6] = Math.max(widths[6], row.lastStatus.length);
153
+ widths[4] = Math.max(widths[4], row.source.length);
154
+ widths[5] = Math.max(widths[5], row.schedule.length);
155
+ widths[6] = Math.max(widths[6], row.nextRun.length);
156
+ widths[7] = Math.max(widths[7], row.lastStatus.length);
150
157
  }
151
158
 
152
159
  const pad = (value: string, width: number) => value.padEnd(width);
@@ -163,6 +170,7 @@ export function registerSchedulesCommand(program: Command): void {
163
170
  row.name,
164
171
  row.enabled,
165
172
  row.mode,
173
+ row.source,
166
174
  row.schedule,
167
175
  row.nextRun,
168
176
  row.lastStatus,
@@ -203,6 +211,11 @@ export function registerSchedulesCommand(program: Command): void {
203
211
  return;
204
212
  }
205
213
 
214
+ // Lazily loaded so the schedule module stays out of the CLI's
215
+ // static graph (cli/no-daemon-internals).
216
+ const { formatScheduleInferenceProfile } =
217
+ await import("../../schedule/inference-profile.js");
218
+
206
219
  const fields: Array<[string, string]> = [
207
220
  ["ID", schedule.id],
208
221
  ["Name", schedule.name],
@@ -222,7 +235,7 @@ export function registerSchedulesCommand(program: Command): void {
222
235
  ["Script", schedule.script ?? "—"],
223
236
  [
224
237
  "Inference profile",
225
- schedule.inferenceProfile ?? "default (mainAgent)",
238
+ formatScheduleInferenceProfile(schedule.inferenceProfile),
226
239
  ],
227
240
  ["Routing intent", schedule.routingIntent],
228
241
  ["Reuse conversation", schedule.reuseConversation ? "yes" : "no"],
@@ -232,6 +245,7 @@ export function registerSchedulesCommand(program: Command): void {
232
245
  ["Retry backoff", formatDuration(schedule.retryBackoffMs)],
233
246
  ["Timeout", formatDuration(schedule.timeoutMs)],
234
247
  ["Source conversation", schedule.createdFromConversationId ?? "—"],
248
+ ["Plugin", describeScheduleSource(schedule.sourceKey) ?? "-"],
235
249
  ];
236
250
  const labelWidth = Math.max(...fields.map(([label]) => label.length));
237
251
  for (const [label, value] of fields) {
@@ -500,7 +514,7 @@ export function registerSchedulesCommand(program: Command): void {
500
514
 
501
515
  if (opts.clearProfile && opts.profile != null) {
502
516
  fail(
503
- "--profile and --clear-profile are mutually exclusive; pass --profile to set a profile or --clear-profile to revert to the default mainAgent model selection",
517
+ "--profile and --clear-profile are mutually exclusive; pass --profile to pin a specific profile or --clear-profile to re-pin the schedule to your current default profile",
504
518
  );
505
519
  return;
506
520
  }
@@ -28,6 +28,7 @@ Examples:
28
28
  $ assistant tools list --json
29
29
  $ assistant tools list --conversation conv_abc123
30
30
  $ assistant tools list --agent researcher
31
+ $ assistant tools list --agent "a staff security engineer"
31
32
  $ assistant tools list --agent subagent_abc123 --json
32
33
  $ assistant tools run web_fetch --input '{"url":"https://example.com"}'
33
34
  $ assistant tools run file_read --input-file args.json
@@ -39,7 +40,8 @@ Examples:
39
40
  options: [
40
41
  {
41
42
  flags: "--json",
42
- description: "Emit machine-readable JSON instead of a table",
43
+ description:
44
+ "Emit the tool array as machine-readable JSON instead of a table; a note about how --agent resolved goes to stderr so stdout stays pipeable",
43
45
  },
44
46
  {
45
47
  flags: "--conversation <id>",
@@ -49,7 +51,7 @@ Examples:
49
51
  {
50
52
  flags: "--agent <role|subagent-id>",
51
53
  description:
52
- "Show tools available to a subagent role (general, researcher, coder, planner, investigator, advisor) or a live subagent by its id. Simulates the subagent tool projection: role allowlist + subagent-only gating.",
54
+ "Show tools available to a subagent role (researcher, builder, advisor) or a live subagent by its id. Reads the value the way a spawn reads its role: an older name (planner, investigator, coder, general) lists its successor's toolset, and any other text is a persona that lists the researcher toolset. The output names what the value resolved to. Simulates the subagent tool projection: role allowlist + subagent-only gating.",
53
55
  },
54
56
  ],
55
57
  },
@@ -24,10 +24,40 @@ interface ToolListEntry {
24
24
  source: string;
25
25
  }
26
26
 
27
+ /** How the daemon read an `--agent` value, when it read one as a role string. */
28
+ interface ResolvedAgentInfo {
29
+ requested: string;
30
+ role: string;
31
+ alias?: string;
32
+ persona?: string;
33
+ }
34
+
27
35
  interface ToolsGetResponse {
28
36
  names: string[];
29
37
  schemas: Record<string, unknown>;
30
38
  tools: ToolListEntry[];
39
+ agent?: ResolvedAgentInfo;
40
+ }
41
+
42
+ /**
43
+ * What to report when `--agent` landed on a different subagent type than the
44
+ * value asked for, or `undefined` when it named a type outright (or resolved a
45
+ * live subagent id, which carries no resolution block).
46
+ *
47
+ * A listing that came from an older name or from a persona fallback looks
48
+ * exactly like one asked for by name, so without this line a typo reads as a
49
+ * researcher's tool surface with nothing saying the value was not a type. It
50
+ * goes to stderr so it reaches a person without entering the `--json` stream,
51
+ * whose stdout contract is the tool array on its own.
52
+ */
53
+ function agentResolutionLine(agent?: ResolvedAgentInfo): string | undefined {
54
+ if (agent?.alias) {
55
+ return `"${agent.requested}" is an older name for "${agent.role}"; listing the ${agent.role} toolset.`;
56
+ }
57
+ if (agent?.persona) {
58
+ return `"${agent.requested}" is not a subagent type, so it is carried as a persona and runs as a researcher; listing the researcher toolset.`;
59
+ }
60
+ return undefined;
31
61
  }
32
62
 
33
63
  export function registerToolsCommand(program: Command): void {
@@ -61,12 +91,20 @@ export function registerToolsCommand(program: Command): void {
61
91
  }
62
92
 
63
93
  const tools = response.result?.tools ?? [];
94
+ const resolutionLine = agentResolutionLine(response.result?.agent);
64
95
 
65
96
  if (opts.json) {
97
+ if (resolutionLine) {
98
+ console.error(resolutionLine);
99
+ }
66
100
  console.log(JSON.stringify(tools, null, 2));
67
101
  return;
68
102
  }
69
103
 
104
+ if (resolutionLine) {
105
+ console.log(`${resolutionLine}\n`);
106
+ }
107
+
70
108
  if (tools.length === 0) {
71
109
  console.log("No tools registered.");
72
110
  return;