vellum 0.0.16 → 0.2.0

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 (838) hide show
  1. package/.dockerignore +27 -0
  2. package/.env.example +22 -0
  3. package/Dockerfile +99 -0
  4. package/Dockerfile.sandbox +5 -0
  5. package/README.md +150 -3
  6. package/bun.lock +1768 -0
  7. package/bunfig.toml +2 -0
  8. package/docs/skills.md +158 -0
  9. package/drizzle/0000_dizzy_maggott.sql +301 -0
  10. package/drizzle/meta/0000_snapshot.json +1999 -0
  11. package/drizzle/meta/_journal.json +13 -0
  12. package/drizzle.config.ts +7 -0
  13. package/eslint.config.mjs +17 -0
  14. package/hook-templates/debug-prompt-logger/hook.json +7 -0
  15. package/hook-templates/debug-prompt-logger/run.sh +68 -0
  16. package/knip.json +9 -0
  17. package/package.json +60 -10
  18. package/scripts/ipc/check-contract-inventory.ts +104 -0
  19. package/scripts/ipc/check-swift-decoder-drift.ts +163 -0
  20. package/scripts/ipc/generate-swift.ts +492 -0
  21. package/scripts/test-filesystem-tools.sh +48 -0
  22. package/scripts/test.sh +122 -0
  23. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +2079 -0
  24. package/src/__tests__/account-registry.test.ts +244 -0
  25. package/src/__tests__/active-skill-tools.test.ts +378 -0
  26. package/src/__tests__/agent-loop-thinking.test.ts +81 -0
  27. package/src/__tests__/agent-loop.test.ts +1135 -0
  28. package/src/__tests__/anthropic-provider.test.ts +778 -0
  29. package/src/__tests__/app-builder-tool-scripts.test.ts +290 -0
  30. package/src/__tests__/app-bundler.test.ts +313 -0
  31. package/src/__tests__/app-executors.test.ts +613 -0
  32. package/src/__tests__/app-open-proxy.test.ts +62 -0
  33. package/src/__tests__/asset-materialize-tool.test.ts +451 -0
  34. package/src/__tests__/asset-search-tool.test.ts +476 -0
  35. package/src/__tests__/assistant-attachment-directive.test.ts +401 -0
  36. package/src/__tests__/assistant-attachments.test.ts +437 -0
  37. package/src/__tests__/assistant-event-hub.test.ts +226 -0
  38. package/src/__tests__/assistant-event.test.ts +123 -0
  39. package/src/__tests__/attachments-store.test.ts +547 -0
  40. package/src/__tests__/attachments.test.ts +134 -0
  41. package/src/__tests__/audit-log-rotation.test.ts +154 -0
  42. package/src/__tests__/browser-fill-credential.test.ts +309 -0
  43. package/src/__tests__/browser-manager.test.ts +203 -0
  44. package/src/__tests__/browser-runtime-check.test.ts +55 -0
  45. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +67 -0
  46. package/src/__tests__/browser-skill-endstate.test.ts +198 -0
  47. package/src/__tests__/bundle-scanner.test.ts +313 -0
  48. package/src/__tests__/checker.test.ts +3856 -0
  49. package/src/__tests__/clarification-resolver.test.ts +159 -0
  50. package/src/__tests__/classifier.test.ts +67 -0
  51. package/src/__tests__/claude-code-skill-regression.test.ts +127 -0
  52. package/src/__tests__/claude-code-tool-profiles.test.ts +88 -0
  53. package/src/__tests__/cli-discover.test.ts +85 -0
  54. package/src/__tests__/cli.test.ts +81 -0
  55. package/src/__tests__/clipboard.test.ts +80 -0
  56. package/src/__tests__/commit-guarantee.test.ts +335 -0
  57. package/src/__tests__/computer-use-session-compaction.test.ts +132 -0
  58. package/src/__tests__/computer-use-session-lifecycle.test.ts +293 -0
  59. package/src/__tests__/computer-use-session-working-dir.test.ts +117 -0
  60. package/src/__tests__/computer-use-skill-baseline.test.ts +74 -0
  61. package/src/__tests__/computer-use-skill-endstate.test.ts +89 -0
  62. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +217 -0
  63. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +107 -0
  64. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +54 -0
  65. package/src/__tests__/config-schema.test.ts +720 -0
  66. package/src/__tests__/conflict-store.test.ts +329 -0
  67. package/src/__tests__/connection-policy.test.ts +102 -0
  68. package/src/__tests__/context-memory-e2e.test.ts +434 -0
  69. package/src/__tests__/context-token-estimator.test.ts +135 -0
  70. package/src/__tests__/context-window-manager.test.ts +376 -0
  71. package/src/__tests__/contradiction-checker.test.ts +216 -0
  72. package/src/__tests__/conversation-store.test.ts +614 -0
  73. package/src/__tests__/credential-broker-browser-fill.test.ts +517 -0
  74. package/src/__tests__/credential-broker-server-use.test.ts +554 -0
  75. package/src/__tests__/credential-broker.test.ts +167 -0
  76. package/src/__tests__/credential-host-pattern-match.test.ts +104 -0
  77. package/src/__tests__/credential-metadata-store.test.ts +779 -0
  78. package/src/__tests__/credential-policy-validate.test.ts +121 -0
  79. package/src/__tests__/credential-resolve.test.ts +328 -0
  80. package/src/__tests__/credential-security-e2e.test.ts +352 -0
  81. package/src/__tests__/credential-security-invariants.test.ts +563 -0
  82. package/src/__tests__/credential-selection.test.ts +354 -0
  83. package/src/__tests__/credential-vault.test.ts +852 -0
  84. package/src/__tests__/daemon-assistant-events.test.ts +164 -0
  85. package/src/__tests__/daemon-server-session-init.test.ts +522 -0
  86. package/src/__tests__/delete-managed-skill-tool.test.ts +97 -0
  87. package/src/__tests__/diff.test.ts +121 -0
  88. package/src/__tests__/domain-normalize.test.ts +112 -0
  89. package/src/__tests__/domain-policy.test.ts +124 -0
  90. package/src/__tests__/doordash-client.test.ts +186 -0
  91. package/src/__tests__/doordash-session.test.ts +143 -0
  92. package/src/__tests__/dynamic-page-surface.test.ts +91 -0
  93. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +132 -0
  94. package/src/__tests__/edit-engine.test.ts +180 -0
  95. package/src/__tests__/email-cli.test.ts +283 -0
  96. package/src/__tests__/encrypted-store.test.ts +332 -0
  97. package/src/__tests__/entity-extractor.test.ts +190 -0
  98. package/src/__tests__/ephemeral-permissions.test.ts +312 -0
  99. package/src/__tests__/evaluate-typescript-tool.test.ts +286 -0
  100. package/src/__tests__/event-bus.test.ts +222 -0
  101. package/src/__tests__/file-edit-tool.test.ts +122 -0
  102. package/src/__tests__/file-ops-service.test.ts +330 -0
  103. package/src/__tests__/file-read-tool.test.ts +75 -0
  104. package/src/__tests__/file-write-tool.test.ts +113 -0
  105. package/src/__tests__/fixtures/credential-security-fixtures.ts +181 -0
  106. package/src/__tests__/fixtures/media-reuse-fixtures.ts +126 -0
  107. package/src/__tests__/fixtures/mock-signup-server.ts +387 -0
  108. package/src/__tests__/fixtures/proxy-fixtures.ts +147 -0
  109. package/src/__tests__/fuzzy-match-property.test.ts +216 -0
  110. package/src/__tests__/fuzzy-match.test.ts +138 -0
  111. package/src/__tests__/gemini-image-service.test.ts +261 -0
  112. package/src/__tests__/gemini-provider.test.ts +651 -0
  113. package/src/__tests__/get-weather.test.ts +318 -0
  114. package/src/__tests__/gmail-integration.test.ts +73 -0
  115. package/src/__tests__/handlers-cu-observation-blob.test.ts +351 -0
  116. package/src/__tests__/handlers-ipc-blob-probe.test.ts +190 -0
  117. package/src/__tests__/handlers-slack-config.test.ts +199 -0
  118. package/src/__tests__/handlers-task-submit-slash.test.ts +38 -0
  119. package/src/__tests__/headless-browser-interactions.test.ts +536 -0
  120. package/src/__tests__/headless-browser-navigate.test.ts +211 -0
  121. package/src/__tests__/headless-browser-read-tools.test.ts +261 -0
  122. package/src/__tests__/headless-browser-snapshot.test.ts +185 -0
  123. package/src/__tests__/history-repair-observability.test.ts +56 -0
  124. package/src/__tests__/history-repair.test.ts +510 -0
  125. package/src/__tests__/home-base-bootstrap.test.ts +77 -0
  126. package/src/__tests__/hooks-blocking.test.ts +128 -0
  127. package/src/__tests__/hooks-cli.test.ts +144 -0
  128. package/src/__tests__/hooks-config.test.ts +93 -0
  129. package/src/__tests__/hooks-discovery.test.ts +199 -0
  130. package/src/__tests__/hooks-integration.test.ts +189 -0
  131. package/src/__tests__/hooks-manager.test.ts +187 -0
  132. package/src/__tests__/hooks-runner.test.ts +178 -0
  133. package/src/__tests__/hooks-settings.test.ts +154 -0
  134. package/src/__tests__/hooks-templates.test.ts +137 -0
  135. package/src/__tests__/hooks-ts-runner.test.ts +125 -0
  136. package/src/__tests__/hooks-watch.test.ts +100 -0
  137. package/src/__tests__/host-file-edit-tool.test.ts +104 -0
  138. package/src/__tests__/host-file-read-tool.test.ts +61 -0
  139. package/src/__tests__/host-file-write-tool.test.ts +77 -0
  140. package/src/__tests__/host-shell-tool.test.ts +311 -0
  141. package/src/__tests__/intent-routing.test.ts +255 -0
  142. package/src/__tests__/ipc-blob-store.test.ts +315 -0
  143. package/src/__tests__/ipc-contract-inventory.test.ts +54 -0
  144. package/src/__tests__/ipc-contract.test.ts +74 -0
  145. package/src/__tests__/ipc-protocol.test.ts +113 -0
  146. package/src/__tests__/ipc-snapshot.test.ts +1560 -0
  147. package/src/__tests__/ipc-validate.test.ts +357 -0
  148. package/src/__tests__/key-migration.test.ts +183 -0
  149. package/src/__tests__/keychain.test.ts +258 -0
  150. package/src/__tests__/llm-usage-store.test.ts +226 -0
  151. package/src/__tests__/managed-skill-lifecycle.test.ts +257 -0
  152. package/src/__tests__/managed-store.test.ts +608 -0
  153. package/src/__tests__/media-generate-image.test.ts +238 -0
  154. package/src/__tests__/media-reuse-story.e2e.test.ts +676 -0
  155. package/src/__tests__/media-visibility-policy.test.ts +141 -0
  156. package/src/__tests__/memory-context-benchmark.test.ts +235 -0
  157. package/src/__tests__/memory-lifecycle-e2e.test.ts +481 -0
  158. package/src/__tests__/memory-query-builder.test.ts +59 -0
  159. package/src/__tests__/memory-recall-quality.test.ts +846 -0
  160. package/src/__tests__/memory-regressions.experimental.test.ts +538 -0
  161. package/src/__tests__/memory-regressions.test.ts +4238 -0
  162. package/src/__tests__/memory-retrieval-budget.test.ts +49 -0
  163. package/src/__tests__/migration-cli-flows.test.ts +169 -0
  164. package/src/__tests__/migration-ordering.test.ts +249 -0
  165. package/src/__tests__/mock-signup-server.test.ts +528 -0
  166. package/src/__tests__/onboarding-starter-tasks.test.ts +166 -0
  167. package/src/__tests__/onboarding-template-contract.test.ts +58 -0
  168. package/src/__tests__/openai-provider.test.ts +753 -0
  169. package/src/__tests__/parser.test.ts +472 -0
  170. package/src/__tests__/path-classifier.test.ts +73 -0
  171. package/src/__tests__/path-policy.test.ts +435 -0
  172. package/src/__tests__/platform-move-helper.test.ts +99 -0
  173. package/src/__tests__/platform-socket-path.test.ts +52 -0
  174. package/src/__tests__/platform-workspace-migration.test.ts +1000 -0
  175. package/src/__tests__/platform.test.ts +131 -0
  176. package/src/__tests__/prebuilt-home-base-seed.test.ts +71 -0
  177. package/src/__tests__/pricing.test.ts +256 -0
  178. package/src/__tests__/profile-compiler.test.ts +373 -0
  179. package/src/__tests__/provider-registry-ollama.test.ts +16 -0
  180. package/src/__tests__/proxy-approval-callback.test.ts +601 -0
  181. package/src/__tests__/ratelimit.test.ts +297 -0
  182. package/src/__tests__/registry.test.ts +487 -0
  183. package/src/__tests__/reminder-store.test.ts +220 -0
  184. package/src/__tests__/reminder.test.ts +263 -0
  185. package/src/__tests__/request-file-tool.test.ts +158 -0
  186. package/src/__tests__/run-orchestrator.test.ts +200 -0
  187. package/src/__tests__/runtime-attachment-metadata.test.ts +190 -0
  188. package/src/__tests__/runtime-runs-http.test.ts +451 -0
  189. package/src/__tests__/runtime-runs.test.ts +273 -0
  190. package/src/__tests__/sandbox-diagnostics.test.ts +408 -0
  191. package/src/__tests__/sandbox-host-parity.test.ts +950 -0
  192. package/src/__tests__/scaffold-managed-skill-tool.test.ts +253 -0
  193. package/src/__tests__/script-proxy-certs.test.ts +90 -0
  194. package/src/__tests__/script-proxy-connect-tunnel.test.ts +177 -0
  195. package/src/__tests__/script-proxy-decision-trace.test.ts +156 -0
  196. package/src/__tests__/script-proxy-http-forwarder.test.ts +281 -0
  197. package/src/__tests__/script-proxy-injection-runtime.test.ts +401 -0
  198. package/src/__tests__/script-proxy-mitm-handler.test.ts +407 -0
  199. package/src/__tests__/script-proxy-policy-runtime.test.ts +287 -0
  200. package/src/__tests__/script-proxy-policy.test.ts +310 -0
  201. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +135 -0
  202. package/src/__tests__/script-proxy-router.test.ts +180 -0
  203. package/src/__tests__/script-proxy-session-manager.test.ts +382 -0
  204. package/src/__tests__/script-proxy-session-runtime.test.ts +113 -0
  205. package/src/__tests__/secret-allowlist.test.ts +229 -0
  206. package/src/__tests__/secret-ingress-handler.test.ts +99 -0
  207. package/src/__tests__/secret-onetime-send.test.ts +130 -0
  208. package/src/__tests__/secret-prompt-log-hygiene.test.ts +106 -0
  209. package/src/__tests__/secret-response-routing.test.ts +93 -0
  210. package/src/__tests__/secret-scanner-executor.test.ts +348 -0
  211. package/src/__tests__/secret-scanner.test.ts +857 -0
  212. package/src/__tests__/secure-keys.test.ts +323 -0
  213. package/src/__tests__/server-history-render.test.ts +430 -0
  214. package/src/__tests__/session-abort-tool-results.test.ts +240 -0
  215. package/src/__tests__/session-conflict-gate.test.ts +697 -0
  216. package/src/__tests__/session-error.test.ts +341 -0
  217. package/src/__tests__/session-evictor.test.ts +188 -0
  218. package/src/__tests__/session-load-history-repair.test.ts +222 -0
  219. package/src/__tests__/session-pre-run-repair.test.ts +213 -0
  220. package/src/__tests__/session-profile-injection.test.ts +444 -0
  221. package/src/__tests__/session-provider-retry-repair.test.ts +306 -0
  222. package/src/__tests__/session-queue.test.ts +1462 -0
  223. package/src/__tests__/session-runtime-assembly.test.ts +315 -0
  224. package/src/__tests__/session-runtime-workspace.test.ts +183 -0
  225. package/src/__tests__/session-skill-tools.test.ts +2431 -0
  226. package/src/__tests__/session-slash-known.test.ts +368 -0
  227. package/src/__tests__/session-slash-queue.test.ts +288 -0
  228. package/src/__tests__/session-slash-unknown.test.ts +271 -0
  229. package/src/__tests__/session-tool-setup-app-refresh.test.ts +473 -0
  230. package/src/__tests__/session-tool-setup-memory-scope.test.ts +140 -0
  231. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +140 -0
  232. package/src/__tests__/session-undo.test.ts +75 -0
  233. package/src/__tests__/session-workspace-cache-state.test.ts +246 -0
  234. package/src/__tests__/session-workspace-injection.test.ts +327 -0
  235. package/src/__tests__/session-workspace-tool-tracking.test.ts +240 -0
  236. package/src/__tests__/shared-filesystem-errors.test.ts +78 -0
  237. package/src/__tests__/shell-credential-ref.test.ts +187 -0
  238. package/src/__tests__/shell-parser-fuzz.test.ts +544 -0
  239. package/src/__tests__/shell-parser-property.test.ts +433 -0
  240. package/src/__tests__/shell-tool-proxy-mode.test.ts +272 -0
  241. package/src/__tests__/signup-e2e.test.ts +352 -0
  242. package/src/__tests__/size-guard.test.ts +117 -0
  243. package/src/__tests__/skill-include-graph.test.ts +303 -0
  244. package/src/__tests__/skill-load-tool.test.ts +409 -0
  245. package/src/__tests__/skill-script-runner-host.test.ts +489 -0
  246. package/src/__tests__/skill-script-runner-sandbox.test.ts +349 -0
  247. package/src/__tests__/skill-tool-factory.test.ts +252 -0
  248. package/src/__tests__/skill-tool-manifest.test.ts +658 -0
  249. package/src/__tests__/skill-version-hash.test.ts +182 -0
  250. package/src/__tests__/skills.test.ts +597 -0
  251. package/src/__tests__/slash-commands-catalog.test.ts +86 -0
  252. package/src/__tests__/slash-commands-parser.test.ts +119 -0
  253. package/src/__tests__/slash-commands-resolver.test.ts +193 -0
  254. package/src/__tests__/slash-commands-rewrite.test.ts +39 -0
  255. package/src/__tests__/starter-bundle.test.ts +136 -0
  256. package/src/__tests__/starter-task-flow.test.ts +143 -0
  257. package/src/__tests__/subagent-manager-notify.test.ts +372 -0
  258. package/src/__tests__/subagent-tools.test.ts +118 -0
  259. package/src/__tests__/subagent-types.test.ts +78 -0
  260. package/src/__tests__/swarm-orchestrator.test.ts +428 -0
  261. package/src/__tests__/swarm-plan-validator.test.ts +330 -0
  262. package/src/__tests__/swarm-recursion.test.ts +165 -0
  263. package/src/__tests__/swarm-router-planner.test.ts +208 -0
  264. package/src/__tests__/swarm-session-integration.test.ts +274 -0
  265. package/src/__tests__/swarm-tool.test.ts +145 -0
  266. package/src/__tests__/swarm-worker-backend.test.ts +129 -0
  267. package/src/__tests__/swarm-worker-runner.test.ts +272 -0
  268. package/src/__tests__/system-prompt.test.ts +461 -0
  269. package/src/__tests__/task-compiler.test.ts +283 -0
  270. package/src/__tests__/task-runner.test.ts +215 -0
  271. package/src/__tests__/task-scheduler.test.ts +216 -0
  272. package/src/__tests__/task-tools.test.ts +602 -0
  273. package/src/__tests__/terminal-sandbox-docker.test.ts +1064 -0
  274. package/src/__tests__/terminal-sandbox.integration.test.ts +178 -0
  275. package/src/__tests__/terminal-sandbox.test.ts +202 -0
  276. package/src/__tests__/test-support/browser-skill-harness.ts +90 -0
  277. package/src/__tests__/test-support/computer-use-skill-harness.ts +45 -0
  278. package/src/__tests__/tool-audit-listener.test.ts +112 -0
  279. package/src/__tests__/tool-domain-event-publisher.test.ts +251 -0
  280. package/src/__tests__/tool-executor-lifecycle-events.test.ts +516 -0
  281. package/src/__tests__/tool-executor-redaction.test.ts +289 -0
  282. package/src/__tests__/tool-executor.test.ts +1971 -0
  283. package/src/__tests__/tool-metrics-listener.test.ts +225 -0
  284. package/src/__tests__/tool-notification-listener.test.ts +49 -0
  285. package/src/__tests__/tool-policy.test.ts +54 -0
  286. package/src/__tests__/tool-profiling-listener.test.ts +268 -0
  287. package/src/__tests__/tool-result-truncation.test.ts +217 -0
  288. package/src/__tests__/tool-trace-listener.test.ts +226 -0
  289. package/src/__tests__/top-level-renderer.test.ts +121 -0
  290. package/src/__tests__/top-level-scanner.test.ts +141 -0
  291. package/src/__tests__/trace-emitter.test.ts +173 -0
  292. package/src/__tests__/trust-store.test.ts +2030 -0
  293. package/src/__tests__/turn-commit.test.ts +219 -0
  294. package/src/__tests__/url-safety.test.ts +418 -0
  295. package/src/__tests__/weather-skill-regression.test.ts +225 -0
  296. package/src/__tests__/web-fetch.test.ts +869 -0
  297. package/src/__tests__/web-search.test.ts +584 -0
  298. package/src/__tests__/workspace-git-service.test.ts +750 -0
  299. package/src/__tests__/workspace-heartbeat-service.test.ts +347 -0
  300. package/src/__tests__/workspace-lifecycle.test.ts +292 -0
  301. package/src/agent/attachments.ts +35 -0
  302. package/src/agent/loop.ts +500 -0
  303. package/src/agent/message-types.ts +17 -0
  304. package/src/autonomy/autonomy-resolver.ts +60 -0
  305. package/src/autonomy/autonomy-store.ts +122 -0
  306. package/src/autonomy/disposition-mapper.ts +31 -0
  307. package/src/autonomy/index.ts +11 -0
  308. package/src/autonomy/types.ts +39 -0
  309. package/src/bundler/app-bundler.ts +274 -0
  310. package/src/bundler/bundle-scanner.ts +535 -0
  311. package/src/bundler/bundle-signer.ts +124 -0
  312. package/src/bundler/manifest.ts +21 -0
  313. package/src/bundler/signature-verifier.ts +184 -0
  314. package/src/cli/autonomy.ts +188 -0
  315. package/src/cli/contacts.ts +149 -0
  316. package/src/cli/doordash.ts +824 -0
  317. package/src/cli/email-guardrails.ts +200 -0
  318. package/src/cli/email.ts +405 -0
  319. package/src/cli/main-screen.tsx +155 -0
  320. package/src/cli.ts +935 -0
  321. package/src/config/bundled-skills/.gitkeep +0 -0
  322. package/src/config/bundled-skills/agentmail/SKILL.md +128 -0
  323. package/src/config/bundled-skills/agentmail/icon.svg +21 -0
  324. package/src/config/bundled-skills/app-builder/SKILL.md +1348 -0
  325. package/src/config/bundled-skills/app-builder/TOOLS.json +279 -0
  326. package/src/config/bundled-skills/app-builder/icon.svg +9 -0
  327. package/src/config/bundled-skills/app-builder/tools/app-create.ts +15 -0
  328. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +10 -0
  329. package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +11 -0
  330. package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +10 -0
  331. package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +18 -0
  332. package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +11 -0
  333. package/src/config/bundled-skills/app-builder/tools/app-list.ts +10 -0
  334. package/src/config/bundled-skills/app-builder/tools/app-query.ts +10 -0
  335. package/src/config/bundled-skills/app-builder/tools/app-update.ts +20 -0
  336. package/src/config/bundled-skills/browser/SKILL.md +28 -0
  337. package/src/config/bundled-skills/browser/TOOLS.json +234 -0
  338. package/src/config/bundled-skills/browser/tools/browser-click.ts +9 -0
  339. package/src/config/bundled-skills/browser/tools/browser-close.ts +9 -0
  340. package/src/config/bundled-skills/browser/tools/browser-extract.ts +9 -0
  341. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +9 -0
  342. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +9 -0
  343. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +9 -0
  344. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +9 -0
  345. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +9 -0
  346. package/src/config/bundled-skills/browser/tools/browser-type.ts +9 -0
  347. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +9 -0
  348. package/src/config/bundled-skills/claude-code/SKILL.md +50 -0
  349. package/src/config/bundled-skills/claude-code/TOOLS.json +40 -0
  350. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +9 -0
  351. package/src/config/bundled-skills/computer-use/SKILL.md +17 -0
  352. package/src/config/bundled-skills/computer-use/TOOLS.json +326 -0
  353. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +9 -0
  354. package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +9 -0
  355. package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +9 -0
  356. package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +9 -0
  357. package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +9 -0
  358. package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +9 -0
  359. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +9 -0
  360. package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +9 -0
  361. package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +9 -0
  362. package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +9 -0
  363. package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +9 -0
  364. package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +9 -0
  365. package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +9 -0
  366. package/src/config/bundled-skills/google-calendar/SKILL.md +51 -0
  367. package/src/config/bundled-skills/google-calendar/TOOLS.json +108 -0
  368. package/src/config/bundled-skills/google-calendar/calendar-client.ts +165 -0
  369. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +21 -0
  370. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +42 -0
  371. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +13 -0
  372. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +30 -0
  373. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +41 -0
  374. package/src/config/bundled-skills/google-calendar/tools/shared.ts +18 -0
  375. package/src/config/bundled-skills/google-calendar/types.ts +97 -0
  376. package/src/config/bundled-skills/image-studio/SKILL.md +32 -0
  377. package/src/config/bundled-skills/image-studio/TOOLS.json +42 -0
  378. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +137 -0
  379. package/src/config/bundled-skills/messaging/SKILL.md +126 -0
  380. package/src/config/bundled-skills/messaging/TOOLS.json +357 -0
  381. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +23 -0
  382. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +23 -0
  383. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +25 -0
  384. package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +26 -0
  385. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +25 -0
  386. package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +23 -0
  387. package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +84 -0
  388. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +18 -0
  389. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +124 -0
  390. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +16 -0
  391. package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +49 -0
  392. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +21 -0
  393. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +25 -0
  394. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +28 -0
  395. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +29 -0
  396. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +22 -0
  397. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +27 -0
  398. package/src/config/bundled-skills/messaging/tools/shared.ts +71 -0
  399. package/src/config/bundled-skills/messaging/tools/slack-add-reaction.ts +25 -0
  400. package/src/config/bundled-skills/messaging/tools/slack-leave-channel.ts +23 -0
  401. package/src/config/bundled-skills/self-upgrade/SKILL.md +74 -0
  402. package/src/config/bundled-skills/start-the-day/SKILL.md +70 -0
  403. package/src/config/bundled-skills/start-the-day/icon.svg +13 -0
  404. package/src/config/bundled-skills/weather/SKILL.md +37 -0
  405. package/src/config/bundled-skills/weather/TOOLS.json +32 -0
  406. package/src/config/bundled-skills/weather/icon.svg +24 -0
  407. package/src/config/bundled-skills/weather/tools/get-weather.ts +9 -0
  408. package/src/config/computer-use-prompt.ts +97 -0
  409. package/src/config/defaults.ts +186 -0
  410. package/src/config/loader.ts +336 -0
  411. package/src/config/schema.ts +1004 -0
  412. package/src/config/skill-state.ts +95 -0
  413. package/src/config/skills.ts +972 -0
  414. package/src/config/system-prompt.ts +927 -0
  415. package/src/config/templates/BOOTSTRAP.md +70 -0
  416. package/src/config/templates/IDENTITY.md +18 -0
  417. package/src/config/templates/LOOKS.md +25 -0
  418. package/src/config/templates/SOUL.md +37 -0
  419. package/src/config/templates/USER.md +19 -0
  420. package/src/config/types.ts +32 -0
  421. package/src/config/vellum-skills/deploy-fullstack-vercel/SKILL.md +179 -0
  422. package/src/config/vellum-skills/document-writer/SKILL.md +195 -0
  423. package/src/config/vellum-skills/google-oauth-setup/SKILL.md +194 -0
  424. package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +147 -0
  425. package/src/config/vellum-skills/telegram-setup/SKILL.md +105 -0
  426. package/src/contacts/contact-store.ts +410 -0
  427. package/src/contacts/index.ts +11 -0
  428. package/src/contacts/types.ts +28 -0
  429. package/src/context/token-estimator.ts +108 -0
  430. package/src/context/tool-result-truncation.ts +128 -0
  431. package/src/context/window-manager.ts +531 -0
  432. package/src/daemon/assistant-attachments.ts +679 -0
  433. package/src/daemon/classifier.ts +108 -0
  434. package/src/daemon/computer-use-session.ts +900 -0
  435. package/src/daemon/connection-policy.ts +41 -0
  436. package/src/daemon/handlers/apps.ts +446 -0
  437. package/src/daemon/handlers/computer-use.ts +181 -0
  438. package/src/daemon/handlers/config.ts +434 -0
  439. package/src/daemon/handlers/diagnostics.ts +334 -0
  440. package/src/daemon/handlers/documents.ts +184 -0
  441. package/src/daemon/handlers/home-base.ts +73 -0
  442. package/src/daemon/handlers/index.ts +355 -0
  443. package/src/daemon/handlers/misc.ts +323 -0
  444. package/src/daemon/handlers/open-bundle-handler.ts +80 -0
  445. package/src/daemon/handlers/publish.ts +182 -0
  446. package/src/daemon/handlers/sessions.ts +486 -0
  447. package/src/daemon/handlers/shared.ts +533 -0
  448. package/src/daemon/handlers/skills.ts +487 -0
  449. package/src/daemon/handlers/subagents.ts +122 -0
  450. package/src/daemon/handlers/work-items.ts +176 -0
  451. package/src/daemon/handlers.ts +17 -0
  452. package/src/daemon/history-repair.ts +214 -0
  453. package/src/daemon/ipc-blob-store.ts +231 -0
  454. package/src/daemon/ipc-contract-inventory.json +407 -0
  455. package/src/daemon/ipc-contract-inventory.ts +126 -0
  456. package/src/daemon/ipc-contract.ts +2102 -0
  457. package/src/daemon/ipc-protocol.ts +70 -0
  458. package/src/daemon/ipc-validate.ts +171 -0
  459. package/src/daemon/lifecycle.ts +503 -0
  460. package/src/daemon/main.ts +15 -0
  461. package/src/daemon/media-visibility-policy.ts +57 -0
  462. package/src/daemon/ride-shotgun-handler.ts +244 -0
  463. package/src/daemon/server.ts +1085 -0
  464. package/src/daemon/session-attachments.ts +173 -0
  465. package/src/daemon/session-conflict-gate.ts +219 -0
  466. package/src/daemon/session-dynamic-profile.ts +63 -0
  467. package/src/daemon/session-error.ts +269 -0
  468. package/src/daemon/session-evictor.ts +196 -0
  469. package/src/daemon/session-history.ts +437 -0
  470. package/src/daemon/session-memory.ts +212 -0
  471. package/src/daemon/session-process.ts +264 -0
  472. package/src/daemon/session-queue-manager.ts +81 -0
  473. package/src/daemon/session-runtime-assembly.ts +395 -0
  474. package/src/daemon/session-skill-tools.ts +237 -0
  475. package/src/daemon/session-slash.ts +302 -0
  476. package/src/daemon/session-surfaces.ts +624 -0
  477. package/src/daemon/session-tool-setup.ts +286 -0
  478. package/src/daemon/session-usage.ts +74 -0
  479. package/src/daemon/session-workspace.ts +19 -0
  480. package/src/daemon/session.ts +1651 -0
  481. package/src/daemon/trace-emitter.ts +82 -0
  482. package/src/daemon/watch-handler.ts +274 -0
  483. package/src/doordash/client.ts +905 -0
  484. package/src/doordash/queries.ts +1312 -0
  485. package/src/doordash/query-extractor.ts +93 -0
  486. package/src/doordash/session.ts +82 -0
  487. package/src/email/provider.ts +117 -0
  488. package/src/email/providers/agentmail.ts +317 -0
  489. package/src/email/providers/index.ts +58 -0
  490. package/src/email/service.ts +303 -0
  491. package/src/email/types.ts +126 -0
  492. package/src/events/bus.ts +157 -0
  493. package/src/events/domain-events.ts +83 -0
  494. package/src/events/index.ts +18 -0
  495. package/src/events/tool-audit-listener.ts +80 -0
  496. package/src/events/tool-domain-event-publisher.ts +111 -0
  497. package/src/events/tool-metrics-listener.ts +159 -0
  498. package/src/events/tool-notification-listener.ts +17 -0
  499. package/src/events/tool-profiling-listener.ts +158 -0
  500. package/src/events/tool-trace-listener.ts +75 -0
  501. package/src/export/formatter.ts +96 -0
  502. package/src/followups/followup-store.ts +166 -0
  503. package/src/followups/index.ts +10 -0
  504. package/src/followups/types.ts +23 -0
  505. package/src/gallery/default-gallery.ts +795 -0
  506. package/src/gallery/gallery-manifest.ts +24 -0
  507. package/src/home-base/app-link-store.ts +82 -0
  508. package/src/home-base/bootstrap.ts +66 -0
  509. package/src/home-base/prebuilt/index.html +662 -0
  510. package/src/home-base/prebuilt/seed-metadata.json +21 -0
  511. package/src/home-base/prebuilt/seed.ts +101 -0
  512. package/src/home-base/prebuilt-home-base-updater.ts +30 -0
  513. package/src/hooks/cli.ts +163 -0
  514. package/src/hooks/config.ts +88 -0
  515. package/src/hooks/discovery.ts +110 -0
  516. package/src/hooks/manager.ts +128 -0
  517. package/src/hooks/runner.ts +123 -0
  518. package/src/hooks/templates.ts +52 -0
  519. package/src/hooks/types.ts +72 -0
  520. package/src/index.ts +1194 -0
  521. package/src/instrument.ts +60 -0
  522. package/src/logfire.ts +99 -0
  523. package/src/media/gemini-image-service.ts +136 -0
  524. package/src/memory/account-store.ts +108 -0
  525. package/src/memory/admin.ts +211 -0
  526. package/src/memory/app-store.ts +556 -0
  527. package/src/memory/attachments-store.ts +453 -0
  528. package/src/memory/channel-delivery-store.ts +368 -0
  529. package/src/memory/checkpoints.ts +52 -0
  530. package/src/memory/clarification-resolver.ts +297 -0
  531. package/src/memory/conflict-store.ts +342 -0
  532. package/src/memory/contradiction-checker.ts +329 -0
  533. package/src/memory/conversation-key-store.ts +127 -0
  534. package/src/memory/conversation-store.ts +469 -0
  535. package/src/memory/db.ts +1105 -0
  536. package/src/memory/embedding-backend.ts +229 -0
  537. package/src/memory/embedding-gemini.ts +52 -0
  538. package/src/memory/embedding-local.ts +75 -0
  539. package/src/memory/embedding-ollama.ts +55 -0
  540. package/src/memory/embedding-openai.ts +25 -0
  541. package/src/memory/entity-extractor.ts +471 -0
  542. package/src/memory/fingerprint.ts +20 -0
  543. package/src/memory/indexer.ts +156 -0
  544. package/src/memory/items-extractor.ts +460 -0
  545. package/src/memory/job-handlers/backfill.ts +139 -0
  546. package/src/memory/job-handlers/cleanup.ts +58 -0
  547. package/src/memory/job-handlers/conflict.ts +99 -0
  548. package/src/memory/job-handlers/embedding.ts +61 -0
  549. package/src/memory/job-handlers/extraction.ts +123 -0
  550. package/src/memory/job-handlers/index-maintenance.ts +54 -0
  551. package/src/memory/job-handlers/summarization.ts +286 -0
  552. package/src/memory/job-utils.ts +170 -0
  553. package/src/memory/jobs-store.ts +400 -0
  554. package/src/memory/jobs-worker.ts +274 -0
  555. package/src/memory/llm-request-log-store.ts +45 -0
  556. package/src/memory/llm-usage-store.ts +62 -0
  557. package/src/memory/message-content.ts +54 -0
  558. package/src/memory/profile-compiler.ts +160 -0
  559. package/src/memory/published-pages-store.ts +137 -0
  560. package/src/memory/qdrant-client.ts +366 -0
  561. package/src/memory/qdrant-manager.ts +242 -0
  562. package/src/memory/query-builder.ts +45 -0
  563. package/src/memory/retrieval-budget.ts +30 -0
  564. package/src/memory/retriever.ts +653 -0
  565. package/src/memory/runs-store.ts +211 -0
  566. package/src/memory/schema.ts +529 -0
  567. package/src/memory/search/entity.ts +298 -0
  568. package/src/memory/search/formatting.ts +207 -0
  569. package/src/memory/search/lexical.ts +227 -0
  570. package/src/memory/search/ranking.ts +401 -0
  571. package/src/memory/search/semantic.ts +121 -0
  572. package/src/memory/search/types.ts +137 -0
  573. package/src/memory/segmenter.ts +68 -0
  574. package/src/memory/shared-app-links-store.ts +138 -0
  575. package/src/memory/tool-usage-store.ts +62 -0
  576. package/src/messaging/activity-analyzer.ts +76 -0
  577. package/src/messaging/draft-store.ts +88 -0
  578. package/src/messaging/index.ts +3 -0
  579. package/src/messaging/provider-types.ts +80 -0
  580. package/src/messaging/provider.ts +43 -0
  581. package/src/messaging/providers/gmail/adapter.ts +193 -0
  582. package/src/messaging/providers/gmail/client.ts +204 -0
  583. package/src/messaging/providers/gmail/types.ts +90 -0
  584. package/src/messaging/providers/slack/adapter.ts +202 -0
  585. package/src/messaging/providers/slack/client.ts +198 -0
  586. package/src/messaging/providers/slack/types.ts +119 -0
  587. package/src/messaging/registry.ts +34 -0
  588. package/src/messaging/style-analyzer.ts +158 -0
  589. package/src/messaging/thread-summarizer.ts +310 -0
  590. package/src/messaging/triage-engine.ts +321 -0
  591. package/src/messaging/types.ts +55 -0
  592. package/src/permissions/checker.ts +636 -0
  593. package/src/permissions/defaults.ts +243 -0
  594. package/src/permissions/prompter.ts +102 -0
  595. package/src/permissions/secret-prompter.ts +114 -0
  596. package/src/permissions/trust-store.ts +584 -0
  597. package/src/permissions/types.ts +62 -0
  598. package/src/playbooks/index.ts +2 -0
  599. package/src/playbooks/playbook-compiler.ts +90 -0
  600. package/src/playbooks/types.ts +55 -0
  601. package/src/providers/anthropic/client.ts +751 -0
  602. package/src/providers/failover.ts +129 -0
  603. package/src/providers/fireworks/client.ts +20 -0
  604. package/src/providers/gemini/client.ts +285 -0
  605. package/src/providers/ollama/client.ts +30 -0
  606. package/src/providers/openai/client.ts +337 -0
  607. package/src/providers/ratelimit.ts +93 -0
  608. package/src/providers/registry.ts +138 -0
  609. package/src/providers/retry.ts +106 -0
  610. package/src/providers/stream-timeout.ts +38 -0
  611. package/src/providers/types.ts +109 -0
  612. package/src/runtime/assistant-event-hub.ts +120 -0
  613. package/src/runtime/assistant-event.ts +82 -0
  614. package/src/runtime/http-server.ts +478 -0
  615. package/src/runtime/http-types.ts +68 -0
  616. package/src/runtime/routes/app-routes.ts +174 -0
  617. package/src/runtime/routes/attachment-routes.ts +134 -0
  618. package/src/runtime/routes/channel-routes.ts +342 -0
  619. package/src/runtime/routes/conversation-routes.ts +349 -0
  620. package/src/runtime/routes/run-routes.ts +223 -0
  621. package/src/runtime/routes/secret-routes.ts +76 -0
  622. package/src/runtime/run-orchestrator.ts +206 -0
  623. package/src/schedule/schedule-store.ts +452 -0
  624. package/src/schedule/scheduler.ts +168 -0
  625. package/src/security/encrypted-store.ts +238 -0
  626. package/src/security/keychain.ts +252 -0
  627. package/src/security/oauth2.ts +241 -0
  628. package/src/security/redaction.ts +89 -0
  629. package/src/security/secret-allowlist.ts +118 -0
  630. package/src/security/secret-ingress.ts +57 -0
  631. package/src/security/secret-scanner.ts +543 -0
  632. package/src/security/secure-keys.ts +180 -0
  633. package/src/security/token-manager.ts +141 -0
  634. package/src/services/published-app-updater.ts +69 -0
  635. package/src/services/vercel-deploy.ts +73 -0
  636. package/src/skills/active-skill-tools.ts +81 -0
  637. package/src/skills/clawhub.ts +414 -0
  638. package/src/skills/include-graph.ts +146 -0
  639. package/src/skills/managed-store.ts +233 -0
  640. package/src/skills/path-classifier.ts +128 -0
  641. package/src/skills/slash-commands.ts +174 -0
  642. package/src/skills/tool-manifest.ts +165 -0
  643. package/src/skills/version-hash.ts +110 -0
  644. package/src/slack/slack-webhook.ts +61 -0
  645. package/src/subagent/index.ts +19 -0
  646. package/src/subagent/manager.ts +477 -0
  647. package/src/subagent/types.ts +69 -0
  648. package/src/swarm/backend-claude-code.ts +90 -0
  649. package/src/swarm/index.ts +44 -0
  650. package/src/swarm/limits.ts +37 -0
  651. package/src/swarm/orchestrator.ts +279 -0
  652. package/src/swarm/plan-validator.ts +151 -0
  653. package/src/swarm/router-planner.ts +100 -0
  654. package/src/swarm/router-prompts.ts +36 -0
  655. package/src/swarm/synthesizer.ts +62 -0
  656. package/src/swarm/types.ts +62 -0
  657. package/src/swarm/worker-backend.ts +121 -0
  658. package/src/swarm/worker-prompts.ts +78 -0
  659. package/src/swarm/worker-runner.ts +164 -0
  660. package/src/tasks/SPEC.md +133 -0
  661. package/src/tasks/candidate-store.ts +86 -0
  662. package/src/tasks/ephemeral-permissions.ts +41 -0
  663. package/src/tasks/task-compiler.ts +198 -0
  664. package/src/tasks/task-runner.ts +85 -0
  665. package/src/tasks/task-scheduler.ts +20 -0
  666. package/src/tasks/task-store.ts +127 -0
  667. package/src/tools/apps/definitions.ts +59 -0
  668. package/src/tools/apps/executors.ts +313 -0
  669. package/src/tools/apps/open-proxy.ts +43 -0
  670. package/src/tools/apps/registry.ts +16 -0
  671. package/src/tools/assets/materialize.ts +218 -0
  672. package/src/tools/assets/search.ts +396 -0
  673. package/src/tools/browser/__tests__/auth-cache.test.ts +219 -0
  674. package/src/tools/browser/__tests__/auth-detector.test.ts +362 -0
  675. package/src/tools/browser/__tests__/jit-auth.test.ts +189 -0
  676. package/src/tools/browser/auth-cache.ts +149 -0
  677. package/src/tools/browser/auth-detector.ts +347 -0
  678. package/src/tools/browser/browser-execution.ts +979 -0
  679. package/src/tools/browser/browser-handoff.ts +79 -0
  680. package/src/tools/browser/browser-manager.ts +715 -0
  681. package/src/tools/browser/browser-screencast.ts +217 -0
  682. package/src/tools/browser/headless-browser.ts +450 -0
  683. package/src/tools/browser/jit-auth.ts +51 -0
  684. package/src/tools/browser/network-recorder.ts +348 -0
  685. package/src/tools/browser/network-recording-types.ts +49 -0
  686. package/src/tools/browser/recording-store.ts +49 -0
  687. package/src/tools/browser/runtime-check.ts +43 -0
  688. package/src/tools/claude-code/claude-code.ts +232 -0
  689. package/src/tools/computer-use/definitions.ts +443 -0
  690. package/src/tools/computer-use/registry.ts +22 -0
  691. package/src/tools/computer-use/request-computer-control.ts +53 -0
  692. package/src/tools/computer-use/skill-proxy-bridge.ts +28 -0
  693. package/src/tools/contacts/contact-merge.ts +87 -0
  694. package/src/tools/contacts/contact-search.ts +102 -0
  695. package/src/tools/contacts/contact-upsert.ts +137 -0
  696. package/src/tools/contacts/index.ts +4 -0
  697. package/src/tools/credentials/account-registry.ts +127 -0
  698. package/src/tools/credentials/broker-types.ts +107 -0
  699. package/src/tools/credentials/broker.ts +372 -0
  700. package/src/tools/credentials/domain-policy.ts +51 -0
  701. package/src/tools/credentials/host-pattern-match.ts +60 -0
  702. package/src/tools/credentials/metadata-store.ts +335 -0
  703. package/src/tools/credentials/policy-types.ts +52 -0
  704. package/src/tools/credentials/policy-validate.ts +80 -0
  705. package/src/tools/credentials/resolve.ts +122 -0
  706. package/src/tools/credentials/selection.ts +159 -0
  707. package/src/tools/credentials/tool-policy.ts +25 -0
  708. package/src/tools/credentials/vault.ts +641 -0
  709. package/src/tools/document/document-tool.ts +165 -0
  710. package/src/tools/document/editor-template.ts +237 -0
  711. package/src/tools/document/index.ts +5 -0
  712. package/src/tools/executor.ts +825 -0
  713. package/src/tools/filesystem/edit.ts +127 -0
  714. package/src/tools/filesystem/fuzzy-match.ts +202 -0
  715. package/src/tools/filesystem/read.ts +71 -0
  716. package/src/tools/filesystem/view-image.ts +199 -0
  717. package/src/tools/filesystem/write.ts +79 -0
  718. package/src/tools/followups/followup_create.ts +118 -0
  719. package/src/tools/followups/followup_list.ts +100 -0
  720. package/src/tools/followups/followup_resolve.ts +91 -0
  721. package/src/tools/followups/index.ts +3 -0
  722. package/src/tools/host-filesystem/edit.ts +125 -0
  723. package/src/tools/host-filesystem/read.ts +80 -0
  724. package/src/tools/host-filesystem/write.ts +76 -0
  725. package/src/tools/host-terminal/cli-discover.ts +179 -0
  726. package/src/tools/host-terminal/host-shell.ts +181 -0
  727. package/src/tools/memory/definitions.ts +69 -0
  728. package/src/tools/memory/handlers.ts +245 -0
  729. package/src/tools/memory/register.ts +66 -0
  730. package/src/tools/network/domain-normalize.ts +85 -0
  731. package/src/tools/network/script-proxy/certs.ts +237 -0
  732. package/src/tools/network/script-proxy/connect-tunnel.ts +82 -0
  733. package/src/tools/network/script-proxy/http-forwarder.ts +151 -0
  734. package/src/tools/network/script-proxy/index.ts +28 -0
  735. package/src/tools/network/script-proxy/logging.ts +196 -0
  736. package/src/tools/network/script-proxy/mitm-handler.ts +269 -0
  737. package/src/tools/network/script-proxy/policy.ts +152 -0
  738. package/src/tools/network/script-proxy/router.ts +60 -0
  739. package/src/tools/network/script-proxy/server.ts +136 -0
  740. package/src/tools/network/script-proxy/session-manager.ts +534 -0
  741. package/src/tools/network/script-proxy/types.ts +125 -0
  742. package/src/tools/network/url-safety.ts +227 -0
  743. package/src/tools/network/web-fetch.ts +701 -0
  744. package/src/tools/network/web-search.ts +319 -0
  745. package/src/tools/playbooks/index.ts +5 -0
  746. package/src/tools/playbooks/playbook-create.ts +140 -0
  747. package/src/tools/playbooks/playbook-delete.ts +76 -0
  748. package/src/tools/playbooks/playbook-list.ts +101 -0
  749. package/src/tools/playbooks/playbook-update.ts +159 -0
  750. package/src/tools/registry.ts +297 -0
  751. package/src/tools/reminder/reminder-store.ts +148 -0
  752. package/src/tools/reminder/reminder.ts +153 -0
  753. package/src/tools/schedule/create.ts +86 -0
  754. package/src/tools/schedule/delete.ts +54 -0
  755. package/src/tools/schedule/list.ts +88 -0
  756. package/src/tools/schedule/update.ts +97 -0
  757. package/src/tools/shared/filesystem/edit-engine.ts +56 -0
  758. package/src/tools/shared/filesystem/errors.ts +85 -0
  759. package/src/tools/shared/filesystem/file-ops-service.ts +215 -0
  760. package/src/tools/shared/filesystem/format-diff.ts +35 -0
  761. package/src/tools/shared/filesystem/path-policy.ts +125 -0
  762. package/src/tools/shared/filesystem/size-guard.ts +41 -0
  763. package/src/tools/shared/filesystem/types.ts +80 -0
  764. package/src/tools/shared/shell-output.ts +52 -0
  765. package/src/tools/skills/delete-managed.ts +60 -0
  766. package/src/tools/skills/load.ts +139 -0
  767. package/src/tools/skills/sandbox-runner.ts +279 -0
  768. package/src/tools/skills/scaffold-managed.ts +150 -0
  769. package/src/tools/skills/script-contract.ts +6 -0
  770. package/src/tools/skills/skill-script-runner.ts +86 -0
  771. package/src/tools/skills/skill-tool-factory.ts +64 -0
  772. package/src/tools/skills/vellum-catalog.ts +217 -0
  773. package/src/tools/subagent/abort.ts +62 -0
  774. package/src/tools/subagent/index.ts +5 -0
  775. package/src/tools/subagent/message.ts +72 -0
  776. package/src/tools/subagent/read.ts +98 -0
  777. package/src/tools/subagent/spawn.ts +85 -0
  778. package/src/tools/subagent/status.ts +74 -0
  779. package/src/tools/swarm/delegate.ts +182 -0
  780. package/src/tools/system/request-permission.ts +98 -0
  781. package/src/tools/tasks/index.ts +25 -0
  782. package/src/tools/tasks/task-delete.ts +69 -0
  783. package/src/tools/tasks/task-list.ts +65 -0
  784. package/src/tools/tasks/task-run.ts +125 -0
  785. package/src/tools/tasks/task-save.ts +79 -0
  786. package/src/tools/tasks/work-item-enqueue.ts +176 -0
  787. package/src/tools/tasks/work-item-list.ts +86 -0
  788. package/src/tools/terminal/backends/docker.ts +372 -0
  789. package/src/tools/terminal/backends/native.ts +188 -0
  790. package/src/tools/terminal/backends/types.ts +26 -0
  791. package/src/tools/terminal/evaluate-typescript.ts +275 -0
  792. package/src/tools/terminal/parser.ts +393 -0
  793. package/src/tools/terminal/safe-env.ts +37 -0
  794. package/src/tools/terminal/sandbox-diagnostics.ts +149 -0
  795. package/src/tools/terminal/sandbox.ts +44 -0
  796. package/src/tools/terminal/shell.ts +257 -0
  797. package/src/tools/tool-manifest.ts +250 -0
  798. package/src/tools/types.ts +177 -0
  799. package/src/tools/ui-surface/definitions.ts +232 -0
  800. package/src/tools/ui-surface/registry.ts +14 -0
  801. package/src/tools/watch/screen-watch.ts +128 -0
  802. package/src/tools/watch/watch-state.ts +119 -0
  803. package/src/tools/watcher/create.ts +110 -0
  804. package/src/tools/watcher/delete.ts +53 -0
  805. package/src/tools/watcher/digest.ts +84 -0
  806. package/src/tools/watcher/list.ts +90 -0
  807. package/src/tools/watcher/update.ts +102 -0
  808. package/src/tools/weather/service.ts +551 -0
  809. package/src/usage/actors.ts +24 -0
  810. package/src/usage/types.ts +38 -0
  811. package/src/util/clipboard.ts +33 -0
  812. package/src/util/content-id.ts +16 -0
  813. package/src/util/diff.ts +181 -0
  814. package/src/util/errors.ts +129 -0
  815. package/src/util/logger.ts +243 -0
  816. package/src/util/platform.ts +607 -0
  817. package/src/util/pricing.ts +150 -0
  818. package/src/util/spinner.ts +51 -0
  819. package/src/util/time.ts +16 -0
  820. package/src/util/xml.ts +4 -0
  821. package/src/version.ts +3 -0
  822. package/src/watcher/constants.ts +11 -0
  823. package/src/watcher/engine.ts +199 -0
  824. package/src/watcher/provider-registry.ts +15 -0
  825. package/src/watcher/provider-types.ts +48 -0
  826. package/src/watcher/providers/gmail.ts +198 -0
  827. package/src/watcher/providers/google-calendar.ts +228 -0
  828. package/src/watcher/providers/slack.ts +128 -0
  829. package/src/watcher/watcher-store.ts +418 -0
  830. package/src/work-items/work-item-store.ts +91 -0
  831. package/src/workspace/git-service.ts +620 -0
  832. package/src/workspace/heartbeat-service.ts +288 -0
  833. package/src/workspace/top-level-renderer.ts +19 -0
  834. package/src/workspace/top-level-scanner.ts +41 -0
  835. package/src/workspace/turn-commit.ts +122 -0
  836. package/tsconfig.json +21 -0
  837. package/LICENSE +0 -674
  838. package/dist/cli.js +0 -569
@@ -0,0 +1,133 @@
1
+ # One-Shot Tasks — Design Spec
2
+
3
+ One-shot tasks are user-defined, reusable prompt templates that run as
4
+ self-contained LLM invocations. A user creates a task once (template + input
5
+ schema), then triggers it with concrete inputs whenever needed. Each run
6
+ produces a result in an isolated background thread.
7
+
8
+ ---
9
+
10
+ ## 1. Template Format (v1)
11
+
12
+ A task definition consists of two parts:
13
+
14
+ ### Prompt template
15
+
16
+ A plain-text string with `{{placeholder}}` markers. When a task is run, every
17
+ placeholder is replaced with the corresponding user-supplied value, and the
18
+ resulting string is sent to the LLM as the user message.
19
+
20
+ ```
21
+ Summarize the following meeting notes in {{style}} format:
22
+
23
+ {{notes}}
24
+ ```
25
+
26
+ Placeholder names must match `[a-zA-Z_][a-zA-Z0-9_]*`.
27
+
28
+ ### Input schema
29
+
30
+ A JSON Schema object that describes every placeholder variable — its type,
31
+ description, and any validation constraints. This serves double duty: it
32
+ drives input validation before the run starts, and it provides enough metadata
33
+ for a UI to render an input form automatically.
34
+
35
+ ```json
36
+ {
37
+ "type": "object",
38
+ "properties": {
39
+ "style": {
40
+ "type": "string",
41
+ "enum": ["bullet", "narrative", "executive"],
42
+ "description": "Output format for the summary"
43
+ },
44
+ "notes": {
45
+ "type": "string",
46
+ "description": "Raw meeting transcript or notes"
47
+ }
48
+ },
49
+ "required": ["style", "notes"]
50
+ }
51
+ ```
52
+
53
+ **Why this design:** A single text template is the simplest possible v1 — no
54
+ multi-message choreography, no branching, no tool-use orchestration. It covers
55
+ the most common use case (structured prompt with variable inputs) while leaving
56
+ room to extend later (e.g., multi-step chains, tool-enabled tasks).
57
+
58
+ ---
59
+
60
+ ## 2. Memory Isolation Policy
61
+
62
+ Each task's memory is scoped by its task ID:
63
+
64
+ ```
65
+ scope_id = "task:{task_id}"
66
+ ```
67
+
68
+ This means:
69
+
70
+ - **Cross-run learning**: All runs of the same task share the same memory
71
+ scope. The LLM can accumulate knowledge about the task across invocations
72
+ (e.g., learning the user's preferred summary style over time).
73
+ - **Isolation from default scope**: Task memory is completely separate from the
74
+ user's main conversation memory (`scope_id = "default"`). A task cannot read
75
+ or pollute the user's chat history, and vice versa.
76
+ - **Per-task boundaries**: Different tasks have different scopes and cannot see
77
+ each other's memory.
78
+
79
+ This mirrors the existing `private:{id}` scoping pattern used by private
80
+ threads (see `conversation-store.ts`), extended to a new `task:` namespace.
81
+
82
+ ---
83
+
84
+ ## 3. Run Surface
85
+
86
+ Each task run creates a new conversation thread with `threadType: 'background'`.
87
+
88
+ ### Lifecycle
89
+
90
+ 1. **Start**: The daemon creates a `background` thread, substitutes template
91
+ placeholders, and sends the prompt to the LLM. An IPC notification
92
+ (`task_run_started`) is broadcast to all connected clients with the run ID,
93
+ task ID, and thread ID.
94
+ 2. **Completion**: When the LLM response is received and stored, the daemon
95
+ broadcasts a `task_run_completed` notification with the run ID, task ID,
96
+ thread ID, and a status (`success` | `error`).
97
+ 3. **Visibility**: Background threads are excluded from the default thread list
98
+ (existing behavior in `conversation-store.ts`). Clients can query for them
99
+ explicitly to surface task results in a dedicated UI.
100
+
101
+ **Why background threads:** Reuses the existing `threadType: 'background'`
102
+ infrastructure. Task runs don't interrupt the user's current conversation, and
103
+ clients can choose how and when to display results (toast, panel, separate
104
+ tab).
105
+
106
+ ---
107
+
108
+ ## 4. Safety Invariants
109
+
110
+ - **No auto-execution**: Tasks are never triggered automatically. Every run
111
+ requires an explicit user action (CLI command, API call, or UI button press).
112
+ - **Ephemeral permission bundles**: If a task is configured with tool access,
113
+ the permission grants are scoped to the single run and discarded afterward.
114
+ No persistent allowlist entries are created on behalf of a task.
115
+ - **High-risk tools always prompt**: Regardless of any task-level permission
116
+ configuration, tools classified as `RiskLevel.High` (destructive shell
117
+ commands, private-network fetches, etc.) always require interactive user
118
+ confirmation. This invariant cannot be overridden by task definitions.
119
+
120
+ ---
121
+
122
+ ## 5. PR Dependency Chain
123
+
124
+ Implementation is split into sequential PRs, each building on the previous:
125
+
126
+ | PR | Title | What it delivers |
127
+ |----|-------|------------------|
128
+ | 0 | Spec decisions | This document. |
129
+ | 1 | Schema + storage | `tasks` and `task_runs` tables, Drizzle schema, migration in `db.ts`, CRUD functions in `task-store.ts`. |
130
+ | 2 | Template engine | `renderTemplate()` — placeholder substitution with input validation against the JSON Schema. |
131
+ | 3 | Run executor | `executeTaskRun()` — creates background thread, calls LLM, writes result, broadcasts IPC notifications (`task_run_started`, `task_run_completed`). |
132
+ | 4 | CLI surface | `vellum task create`, `vellum task run`, `vellum task list` commands. |
133
+ | 5 | IPC + macOS integration | Wire up IPC message types; macOS client displays task run results. |
@@ -0,0 +1,86 @@
1
+ import { eq, desc, isNull } from 'drizzle-orm';
2
+ import { getDb } from '../memory/db.js';
3
+ import { taskCandidates } from '../memory/schema.js';
4
+
5
+ // ── Types ────────────────────────────────────────────────────────────
6
+
7
+ export interface TaskCandidate {
8
+ id: string;
9
+ sourceConversationId: string;
10
+ compiledTemplate: string;
11
+ confidence: number | null;
12
+ requiredTools: string[] | null;
13
+ createdAt: number;
14
+ promotedTaskId: string | null;
15
+ }
16
+
17
+ // ── Helpers ──────────────────────────────────────────────────────────
18
+
19
+ /** Convert a raw DB row to a TaskCandidate, deserializing the JSON requiredTools field. */
20
+ function rowToCandidate(row: typeof taskCandidates.$inferSelect): TaskCandidate {
21
+ return {
22
+ id: row.id,
23
+ sourceConversationId: row.sourceConversationId,
24
+ compiledTemplate: row.compiledTemplate,
25
+ confidence: row.confidence,
26
+ requiredTools: row.requiredTools ? JSON.parse(row.requiredTools) : null,
27
+ createdAt: row.createdAt,
28
+ promotedTaskId: row.promotedTaskId,
29
+ };
30
+ }
31
+
32
+ // ── CRUD ─────────────────────────────────────────────────────────────
33
+
34
+ /** Record a new task candidate from a conversation. */
35
+ export function createCandidate(opts: {
36
+ sourceConversationId: string;
37
+ compiledTemplate: string;
38
+ confidence?: number;
39
+ requiredTools?: string[];
40
+ }): TaskCandidate {
41
+ const db = getDb();
42
+ const now = Date.now();
43
+ const id = crypto.randomUUID();
44
+ const row = {
45
+ id,
46
+ sourceConversationId: opts.sourceConversationId,
47
+ compiledTemplate: opts.compiledTemplate,
48
+ confidence: opts.confidence ?? null,
49
+ requiredTools: opts.requiredTools ? JSON.stringify(opts.requiredTools) : null,
50
+ createdAt: now,
51
+ promotedTaskId: null,
52
+ };
53
+ db.insert(taskCandidates).values(row).run();
54
+ return {
55
+ ...row,
56
+ requiredTools: opts.requiredTools ?? null,
57
+ };
58
+ }
59
+
60
+ /** List unpromoted candidates (most recent first). */
61
+ export function listUnpromotedCandidates(limit?: number): TaskCandidate[] {
62
+ const db = getDb();
63
+ const query = db
64
+ .select()
65
+ .from(taskCandidates)
66
+ .where(isNull(taskCandidates.promotedTaskId))
67
+ .orderBy(desc(taskCandidates.createdAt));
68
+ const rows = limit ? query.limit(limit).all() : query.all();
69
+ return rows.map(rowToCandidate);
70
+ }
71
+
72
+ /** Mark a candidate as promoted to a real task. */
73
+ export function promoteCandidate(candidateId: string, taskId: string): void {
74
+ const db = getDb();
75
+ db.update(taskCandidates)
76
+ .set({ promotedTaskId: taskId })
77
+ .where(eq(taskCandidates.id, candidateId))
78
+ .run();
79
+ }
80
+
81
+ /** Get a candidate by ID. */
82
+ export function getCandidate(id: string): TaskCandidate | undefined {
83
+ const db = getDb();
84
+ const row = db.select().from(taskCandidates).where(eq(taskCandidates.id, id)).get();
85
+ return row ? rowToCandidate(row) : undefined;
86
+ }
@@ -0,0 +1,41 @@
1
+ import type { TrustRule } from '../permissions/types.js';
2
+
3
+ // In-memory map: task_run_id -> ephemeral rules
4
+ const activeTaskRules = new Map<string, TrustRule[]>();
5
+
6
+ /** Register ephemeral permission rules for a task run. */
7
+ export function setTaskRunRules(taskRunId: string, rules: TrustRule[]): void {
8
+ activeTaskRules.set(taskRunId, rules);
9
+ }
10
+
11
+ /** Get ephemeral rules for a task run (returns empty array if none). */
12
+ export function getTaskRunRules(taskRunId: string): TrustRule[] {
13
+ return activeTaskRules.get(taskRunId) ?? [];
14
+ }
15
+
16
+ /** Remove ephemeral rules when a task run ends. */
17
+ export function clearTaskRunRules(taskRunId: string): void {
18
+ activeTaskRules.delete(taskRunId);
19
+ }
20
+
21
+ /**
22
+ * Build ephemeral TrustRule entries from a task's required_tools list.
23
+ *
24
+ * Each rule allows the specified tool with a wildcard pattern scoped to the
25
+ * given working directory. Priority is set to 50 — lower than user rules (100)
26
+ * so that user deny rules still take precedence. `allowHighRisk` is NOT set,
27
+ * so high-risk operations continue to prompt for approval.
28
+ */
29
+ export function buildTaskRules(taskRunId: string, requiredTools: string[], workingDir: string): TrustRule[] {
30
+ return requiredTools.map((tool) => ({
31
+ id: `ephemeral:${taskRunId}:${tool}`,
32
+ tool,
33
+ pattern: '**',
34
+ scope: workingDir,
35
+ decision: 'allow' as const,
36
+ priority: 50,
37
+ createdAt: Date.now(),
38
+ principalKind: 'task',
39
+ principalId: taskRunId,
40
+ }));
41
+ }
@@ -0,0 +1,198 @@
1
+ import { eq } from 'drizzle-orm';
2
+ import { getDb } from '../memory/db.js';
3
+ import { messages as messagesTable } from '../memory/schema.js';
4
+ import { createTask } from './task-store.js';
5
+ import type { Task } from './task-store.js';
6
+
7
+ /** Output schema for the task compiler. */
8
+ export interface CompiledTask {
9
+ title: string;
10
+ template: string;
11
+ inputSchema: Record<string, unknown> | null;
12
+ contextFlags: string[];
13
+ requiredTools: string[];
14
+ }
15
+
16
+ /**
17
+ * Extract a task template (reusable definition) from a conversation's message history.
18
+ *
19
+ * Pattern-based extraction (v1) that:
20
+ * 1. Reads the conversation messages
21
+ * 2. Identifies the user's original request (first user message)
22
+ * 3. Identifies which tools were used (from assistant tool_use messages)
23
+ * 4. Builds a template from the original request
24
+ * 5. Extracts likely input variables (file paths, URLs, quoted strings)
25
+ */
26
+ export function compileTaskFromConversation(conversationId: string): CompiledTask {
27
+ const db = getDb();
28
+ const msgs = db
29
+ .select()
30
+ .from(messagesTable)
31
+ .where(eq(messagesTable.conversationId, conversationId))
32
+ .all();
33
+
34
+ if (msgs.length === 0) {
35
+ throw new Error(`No messages found for conversation: ${conversationId}`);
36
+ }
37
+
38
+ // Find the first user message to use as the template basis
39
+ const firstUserMsg = msgs.find((m) => m.role === 'user');
40
+ if (!firstUserMsg) {
41
+ throw new Error(`No user messages found in conversation: ${conversationId}`);
42
+ }
43
+
44
+ // Extract user message text content
45
+ const userText = extractTextContent(firstUserMsg.content);
46
+
47
+ // Extract unique tool names from assistant messages
48
+ const requiredTools = extractToolNames(msgs);
49
+
50
+ // Build template with placeholder substitutions
51
+ const { template, properties } = buildTemplate(userText);
52
+
53
+ // Build JSON Schema for extracted placeholders
54
+ const inputSchema =
55
+ Object.keys(properties).length > 0
56
+ ? { type: 'object' as const, properties }
57
+ : null;
58
+
59
+ // Derive title from the first user message (truncated to 60 chars)
60
+ const title = deriveTitle(userText);
61
+
62
+ return {
63
+ title,
64
+ template,
65
+ inputSchema,
66
+ contextFlags: [],
67
+ requiredTools,
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Save a compiled task to the database.
73
+ */
74
+ export function saveCompiledTask(compiled: CompiledTask, conversationId: string): Task {
75
+ return createTask({
76
+ title: compiled.title,
77
+ template: compiled.template,
78
+ inputSchema: compiled.inputSchema ?? undefined,
79
+ contextFlags: compiled.contextFlags,
80
+ requiredTools: compiled.requiredTools,
81
+ createdFromConversationId: conversationId,
82
+ });
83
+ }
84
+
85
+ // ── Internal helpers ────────────────────────────────────────────────
86
+
87
+ /**
88
+ * Extract plain text from a message content field. Content may be a plain
89
+ * string or a JSON array of Anthropic content blocks.
90
+ */
91
+ function extractTextContent(content: string): string {
92
+ try {
93
+ const parsed = JSON.parse(content);
94
+ if (Array.isArray(parsed)) {
95
+ return parsed
96
+ .filter((block: Record<string, unknown>) => block.type === 'text')
97
+ .map((block: Record<string, unknown>) => block.text as string)
98
+ .join('\n');
99
+ }
100
+ // If it parsed but isn't an array, treat as plain text
101
+ return content;
102
+ } catch {
103
+ // Not JSON — it's a plain text message
104
+ return content;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Extract unique tool names from assistant messages that contain tool_use blocks.
110
+ */
111
+ function extractToolNames(
112
+ msgs: { role: string; content: string }[],
113
+ ): string[] {
114
+ const tools = new Set<string>();
115
+
116
+ for (const msg of msgs) {
117
+ if (msg.role !== 'assistant') continue;
118
+
119
+ try {
120
+ const parsed = JSON.parse(msg.content);
121
+ if (!Array.isArray(parsed)) continue;
122
+
123
+ for (const block of parsed) {
124
+ if (
125
+ block &&
126
+ typeof block === 'object' &&
127
+ block.type === 'tool_use' &&
128
+ typeof block.name === 'string'
129
+ ) {
130
+ tools.add(block.name);
131
+ }
132
+ }
133
+ } catch {
134
+ // Not JSON content — skip
135
+ }
136
+ }
137
+
138
+ return [...tools];
139
+ }
140
+
141
+ /**
142
+ * Build a template from user text by replacing variable-looking parts
143
+ * with mustache-style placeholders.
144
+ *
145
+ * Returns the template string and a map of property schemas for the
146
+ * identified placeholders.
147
+ */
148
+ function buildTemplate(text: string): {
149
+ template: string;
150
+ properties: Record<string, { type: string; description: string }>;
151
+ } {
152
+ const properties: Record<string, { type: string; description: string }> = {};
153
+ let template = text;
154
+ let urlIndex = 0;
155
+ let filePathIndex = 0;
156
+
157
+ // Replace URLs first so they don't get partially matched by file path regex
158
+ template = template.replace(
159
+ /https?:\/\/[^\s)>]+/g,
160
+ () => {
161
+ const key = urlIndex === 0 ? 'url' : `url_${urlIndex}`;
162
+ urlIndex++;
163
+ properties[key] = {
164
+ type: 'string',
165
+ description: 'The URL to use',
166
+ };
167
+ return `{{${key}}}`;
168
+ },
169
+ );
170
+
171
+ // Replace absolute file paths (e.g. /Users/foo/bar.txt, ~/docs/file)
172
+ // Only match paths starting with / or ~/ that have at least two segments
173
+ template = template.replace(
174
+ /(?:~\/|\/(?:[a-zA-Z0-9._-]+\/)+[a-zA-Z0-9._-]+)/g,
175
+ () => {
176
+ const key = filePathIndex === 0 ? 'file_path' : `file_path_${filePathIndex}`;
177
+ filePathIndex++;
178
+ properties[key] = {
179
+ type: 'string',
180
+ description: 'The file path to operate on',
181
+ };
182
+ return `{{${key}}}`;
183
+ },
184
+ );
185
+
186
+ return { template, properties };
187
+ }
188
+
189
+ /**
190
+ * Derive a short title from the user's first message.
191
+ * Truncates to 60 characters with ellipsis if needed.
192
+ */
193
+ function deriveTitle(text: string): string {
194
+ // Take the first line and trim whitespace
195
+ const firstLine = text.split('\n')[0].trim();
196
+ if (firstLine.length <= 60) return firstLine;
197
+ return firstLine.slice(0, 57) + '...';
198
+ }
@@ -0,0 +1,85 @@
1
+ import { getLogger } from '../util/logger.js';
2
+ import { createConversation } from '../memory/conversation-store.js';
3
+ import { getTask, createTaskRun, updateTaskRun } from './task-store.js';
4
+ import { buildTaskRules, setTaskRunRules, clearTaskRunRules } from './ephemeral-permissions.js';
5
+
6
+ const log = getLogger('task-runner');
7
+
8
+ export interface TaskRunOptions {
9
+ taskId: string;
10
+ inputs?: Record<string, string>;
11
+ workingDir: string;
12
+ }
13
+
14
+ export interface TaskRunResult {
15
+ taskRunId: string;
16
+ conversationId: string;
17
+ status: 'completed' | 'failed';
18
+ error?: string;
19
+ }
20
+
21
+ /** Replace {{key}} placeholders in template with values from inputs. */
22
+ export function renderTemplate(template: string, inputs: Record<string, string>): string {
23
+ return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
24
+ if (key in inputs) return inputs[key];
25
+ return match;
26
+ });
27
+ }
28
+
29
+ /**
30
+ * Execute a task: create a run, set up ephemeral permissions,
31
+ * render the template, and process it as a message.
32
+ */
33
+ export async function runTask(
34
+ opts: TaskRunOptions,
35
+ processMessage: (conversationId: string, message: string) => Promise<void>,
36
+ ): Promise<TaskRunResult> {
37
+ const task = getTask(opts.taskId);
38
+ if (!task) {
39
+ throw new Error(`Task not found: ${opts.taskId}`);
40
+ }
41
+
42
+ const run = createTaskRun(task.id);
43
+ const conversation = createConversation({ title: `Task: ${task.title}`, threadType: 'background' });
44
+
45
+ updateTaskRun(run.id, {
46
+ conversationId: conversation.id,
47
+ memoryScopeId: `task:${task.id}`,
48
+ });
49
+
50
+ // Build and register ephemeral permission rules from the task's required tools
51
+ const requiredTools: string[] = task.requiredTools ? JSON.parse(task.requiredTools) : [];
52
+ const rules = buildTaskRules(run.id, requiredTools, opts.workingDir);
53
+ setTaskRunRules(run.id, rules);
54
+
55
+ try {
56
+ const renderedTemplate = renderTemplate(task.template, opts.inputs ?? {});
57
+
58
+ updateTaskRun(run.id, { status: 'running', startedAt: Date.now() });
59
+
60
+ log.info({ taskId: task.id, taskRunId: run.id, conversationId: conversation.id }, 'Executing task');
61
+ await processMessage(conversation.id, renderedTemplate);
62
+
63
+ updateTaskRun(run.id, { status: 'completed', finishedAt: Date.now() });
64
+
65
+ return {
66
+ taskRunId: run.id,
67
+ conversationId: conversation.id,
68
+ status: 'completed',
69
+ };
70
+ } catch (err) {
71
+ const errorMessage = err instanceof Error ? err.message : String(err);
72
+ log.warn({ err, taskId: task.id, taskRunId: run.id }, 'Task execution failed');
73
+
74
+ updateTaskRun(run.id, { status: 'failed', error: errorMessage, finishedAt: Date.now() });
75
+
76
+ return {
77
+ taskRunId: run.id,
78
+ conversationId: conversation.id,
79
+ status: 'failed',
80
+ error: errorMessage,
81
+ };
82
+ } finally {
83
+ clearTaskRunRules(run.id);
84
+ }
85
+ }
@@ -0,0 +1,20 @@
1
+ import { createSchedule } from '../schedule/schedule-store.js';
2
+
3
+ /**
4
+ * Create a schedule that runs a task on a cron expression.
5
+ * The scheduler detects the `run_task:<taskId>` message format
6
+ * and delegates to runTask() instead of processMessage().
7
+ */
8
+ export function scheduleTask(opts: {
9
+ taskId: string;
10
+ name: string;
11
+ cronExpression: string;
12
+ timezone?: string;
13
+ }): ReturnType<typeof createSchedule> {
14
+ return createSchedule({
15
+ name: opts.name,
16
+ cronExpression: opts.cronExpression,
17
+ timezone: opts.timezone ?? null,
18
+ message: `run_task:${opts.taskId}`,
19
+ });
20
+ }
@@ -0,0 +1,127 @@
1
+ import { eq, desc, inArray } from 'drizzle-orm';
2
+ import { getDb } from '../memory/db.js';
3
+ import { tasks, taskRuns, workItems } from '../memory/schema.js';
4
+
5
+ // ── Types ────────────────────────────────────────────────────────────
6
+
7
+ export interface Task {
8
+ id: string;
9
+ title: string;
10
+ template: string;
11
+ inputSchema: string | null;
12
+ contextFlags: string | null;
13
+ requiredTools: string | null;
14
+ createdFromConversationId: string | null;
15
+ status: string;
16
+ createdAt: number;
17
+ updatedAt: number;
18
+ }
19
+
20
+ export interface TaskRun {
21
+ id: string;
22
+ taskId: string;
23
+ conversationId: string | null;
24
+ status: string;
25
+ startedAt: number | null;
26
+ finishedAt: number | null;
27
+ error: string | null;
28
+ principalId: string | null;
29
+ memoryScopeId: string | null;
30
+ createdAt: number;
31
+ }
32
+
33
+ // ── Task CRUD ────────────────────────────────────────────────────────
34
+
35
+ export function createTask(opts: {
36
+ title: string;
37
+ template: string;
38
+ inputSchema?: object;
39
+ contextFlags?: string[];
40
+ requiredTools?: string[];
41
+ createdFromConversationId?: string;
42
+ }): Task {
43
+ const db = getDb();
44
+ const now = Date.now();
45
+ const id = crypto.randomUUID();
46
+ const task: Task = {
47
+ id,
48
+ title: opts.title,
49
+ template: opts.template,
50
+ inputSchema: opts.inputSchema ? JSON.stringify(opts.inputSchema) : null,
51
+ contextFlags: opts.contextFlags ? JSON.stringify(opts.contextFlags) : null,
52
+ requiredTools: opts.requiredTools ? JSON.stringify(opts.requiredTools) : null,
53
+ createdFromConversationId: opts.createdFromConversationId ?? null,
54
+ status: 'active',
55
+ createdAt: now,
56
+ updatedAt: now,
57
+ };
58
+ db.insert(tasks).values(task).run();
59
+ return task;
60
+ }
61
+
62
+ export function getTask(id: string): Task | undefined {
63
+ const db = getDb();
64
+ return db.select().from(tasks).where(eq(tasks.id, id)).get();
65
+ }
66
+
67
+ export function listTasks(): Task[] {
68
+ const db = getDb();
69
+ return db.select().from(tasks).orderBy(desc(tasks.createdAt)).all();
70
+ }
71
+
72
+ export function deleteTask(id: string): boolean {
73
+ const db = getDb();
74
+ const existing = db.select().from(tasks).where(eq(tasks.id, id)).get();
75
+ if (!existing) return false;
76
+ db.delete(workItems).where(eq(workItems.taskId, id)).run();
77
+ db.delete(taskRuns).where(eq(taskRuns.taskId, id)).run();
78
+ db.delete(tasks).where(eq(tasks.id, id)).run();
79
+ return true;
80
+ }
81
+
82
+ export function deleteTasks(ids: string[]): number {
83
+ if (ids.length === 0) return 0;
84
+ const db = getDb();
85
+ const existing = db.select().from(tasks).where(inArray(tasks.id, ids)).all();
86
+ if (existing.length === 0) return 0;
87
+ const foundIds = existing.map((t) => t.id);
88
+ db.delete(workItems).where(inArray(workItems.taskId, foundIds)).run();
89
+ db.delete(taskRuns).where(inArray(taskRuns.taskId, foundIds)).run();
90
+ db.delete(tasks).where(inArray(tasks.id, foundIds)).run();
91
+ return existing.length;
92
+ }
93
+
94
+ // ── TaskRun CRUD ─────────────────────────────────────────────────────
95
+
96
+ export function createTaskRun(taskId: string): TaskRun {
97
+ const db = getDb();
98
+ const now = Date.now();
99
+ const id = crypto.randomUUID();
100
+ const run: TaskRun = {
101
+ id,
102
+ taskId,
103
+ conversationId: null,
104
+ status: 'pending',
105
+ startedAt: null,
106
+ finishedAt: null,
107
+ error: null,
108
+ principalId: null,
109
+ memoryScopeId: null,
110
+ createdAt: now,
111
+ };
112
+ db.insert(taskRuns).values(run).run();
113
+ return run;
114
+ }
115
+
116
+ export function updateTaskRun(
117
+ id: string,
118
+ updates: Partial<Pick<TaskRun, 'status' | 'conversationId' | 'error' | 'principalId' | 'memoryScopeId' | 'startedAt' | 'finishedAt'>>,
119
+ ): void {
120
+ const db = getDb();
121
+ db.update(taskRuns).set(updates).where(eq(taskRuns.id, id)).run();
122
+ }
123
+
124
+ export function getTaskRun(id: string): TaskRun | undefined {
125
+ const db = getDb();
126
+ return db.select().from(taskRuns).where(eq(taskRuns.id, id)).get();
127
+ }