vellum 0.2.1 → 0.2.7

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 (361) hide show
  1. package/README.md +15 -2
  2. package/bun.lock +71 -100
  3. package/package.json +5 -3
  4. package/scripts/capture-x-graphql.ts +562 -0
  5. package/scripts/ipc/check-swift-decoder-drift.ts +2 -1
  6. package/scripts/test.sh +5 -0
  7. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +133 -34
  8. package/src/__tests__/account-registry.test.ts +2 -1
  9. package/src/__tests__/agent-heartbeat-service.test.ts +250 -0
  10. package/src/__tests__/asset-materialize-tool.test.ts +16 -15
  11. package/src/__tests__/asset-search-tool.test.ts +23 -22
  12. package/src/__tests__/attachments-store.test.ts +56 -127
  13. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +5 -4
  14. package/src/__tests__/browser-skill-endstate.test.ts +4 -3
  15. package/src/__tests__/call-bridge.test.ts +385 -0
  16. package/src/__tests__/call-constants.test.ts +40 -0
  17. package/src/__tests__/call-orchestrator.test.ts +130 -4
  18. package/src/__tests__/call-recovery.test.ts +518 -0
  19. package/src/__tests__/call-routes-http.test.ts +459 -0
  20. package/src/__tests__/call-state-machine.test.ts +143 -0
  21. package/src/__tests__/call-store.test.ts +216 -1
  22. package/src/__tests__/cli-discover.test.ts +1 -1
  23. package/src/__tests__/commit-message-enrichment-service.test.ts +148 -7
  24. package/src/__tests__/compaction.benchmark.test.ts +176 -0
  25. package/src/__tests__/computer-use-tools.test.ts +250 -0
  26. package/src/__tests__/config-schema.test.ts +305 -3
  27. package/src/__tests__/conflict-store.test.ts +2 -1
  28. package/src/__tests__/contacts-tools.test.ts +331 -0
  29. package/src/__tests__/conversation-store.test.ts +30 -32
  30. package/src/__tests__/credential-security-invariants.test.ts +4 -0
  31. package/src/__tests__/date-context.test.ts +373 -0
  32. package/src/__tests__/db-schedule-syntax-migration.test.ts +129 -0
  33. package/src/__tests__/fixtures/media-reuse-fixtures.ts +3 -3
  34. package/src/__tests__/followup-tools.test.ts +303 -0
  35. package/src/__tests__/handlers-twilio-config.test.ts +221 -0
  36. package/src/__tests__/handlers-twitter-config.test.ts +718 -0
  37. package/src/__tests__/intent-routing.test.ts +64 -57
  38. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +237 -0
  39. package/src/__tests__/ipc-snapshot.test.ts +71 -28
  40. package/src/__tests__/llm-usage-store.test.ts +3 -8
  41. package/src/__tests__/media-generate-image.test.ts +1 -1
  42. package/src/__tests__/media-reuse-story.e2e.test.ts +7 -7
  43. package/src/__tests__/memory-regressions.test.ts +100 -2
  44. package/src/__tests__/memory-retrieval.benchmark.test.ts +430 -0
  45. package/src/__tests__/parallel-tool.benchmark.test.ts +294 -0
  46. package/src/__tests__/playbook-tools.test.ts +342 -0
  47. package/src/__tests__/profile-compiler.test.ts +2 -1
  48. package/src/__tests__/provider-commit-message-generator.test.ts +303 -0
  49. package/src/__tests__/provider-streaming.benchmark.test.ts +773 -0
  50. package/src/__tests__/recurrence-engine-rruleset.test.ts +78 -0
  51. package/src/__tests__/recurrence-engine.test.ts +69 -0
  52. package/src/__tests__/recurrence-types.test.ts +71 -0
  53. package/src/__tests__/registry.test.ts +5 -3
  54. package/src/__tests__/relay-server.test.ts +633 -0
  55. package/src/__tests__/reminder-store.test.ts +6 -3
  56. package/src/__tests__/reminder.test.ts +43 -77
  57. package/src/__tests__/run-orchestrator-assistant-events.test.ts +8 -4
  58. package/src/__tests__/run-orchestrator.test.ts +4 -4
  59. package/src/__tests__/runtime-attachment-metadata.test.ts +7 -6
  60. package/src/__tests__/runtime-runs-http.test.ts +4 -4
  61. package/src/__tests__/runtime-runs.test.ts +4 -4
  62. package/src/__tests__/schedule-store.test.ts +482 -0
  63. package/src/__tests__/schedule-tools.test.ts +700 -0
  64. package/src/__tests__/scheduler-recurrence.test.ts +329 -0
  65. package/src/__tests__/server-history-render.test.ts +14 -13
  66. package/src/__tests__/session-conflict-gate.test.ts +28 -25
  67. package/src/__tests__/session-error.test.ts +28 -0
  68. package/src/__tests__/session-init.benchmark.test.ts +462 -0
  69. package/src/__tests__/session-queue.test.ts +71 -48
  70. package/src/__tests__/session-runtime-assembly.test.ts +161 -0
  71. package/src/__tests__/session-surfaces-task-progress.test.ts +104 -0
  72. package/src/__tests__/signup-e2e.test.ts +2 -1
  73. package/src/__tests__/skill-projection.benchmark.test.ts +328 -0
  74. package/src/__tests__/skill-script-runner.test.ts +159 -0
  75. package/src/__tests__/speaker-identification.test.ts +52 -0
  76. package/src/__tests__/subagent-manager-notify.test.ts +42 -10
  77. package/src/__tests__/subagent-tools.test.ts +141 -41
  78. package/src/__tests__/task-compiler.test.ts +2 -1
  79. package/src/__tests__/task-runner.test.ts +2 -1
  80. package/src/__tests__/task-scheduler.test.ts +2 -1
  81. package/src/__tests__/task-tools.test.ts +49 -56
  82. package/src/__tests__/tool-audit-listener.test.ts +1 -0
  83. package/src/__tests__/tool-domain-event-publisher.test.ts +2 -0
  84. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +500 -0
  85. package/src/__tests__/tool-executor.test.ts +13 -17
  86. package/src/__tests__/turn-commit.test.ts +218 -3
  87. package/src/__tests__/twilio-provider.test.ts +143 -0
  88. package/src/__tests__/twilio-routes.test.ts +789 -0
  89. package/src/__tests__/twitter-auth-handler.test.ts +581 -0
  90. package/src/__tests__/view-image-tool.test.ts +217 -0
  91. package/src/__tests__/workspace-git-service.test.ts +186 -0
  92. package/src/__tests__/workspace-heartbeat-service.test.ts +13 -3
  93. package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
  94. package/src/bundler/app-bundler.ts +12 -8
  95. package/src/calls/__tests__/twilio-webhook-urls.test.ts +162 -0
  96. package/src/calls/call-bridge.ts +95 -0
  97. package/src/calls/call-constants.ts +43 -5
  98. package/src/calls/call-domain.ts +276 -0
  99. package/src/calls/call-orchestrator.ts +43 -17
  100. package/src/calls/call-recovery.ts +207 -0
  101. package/src/calls/call-state-machine.ts +68 -0
  102. package/src/calls/call-store.ts +192 -5
  103. package/src/calls/relay-server.ts +41 -4
  104. package/src/calls/speaker-identification.ts +213 -0
  105. package/src/calls/twilio-config.ts +8 -8
  106. package/src/calls/twilio-provider.ts +13 -9
  107. package/src/calls/twilio-routes.ts +90 -76
  108. package/src/calls/twilio-webhook-urls.ts +50 -0
  109. package/src/calls/types.ts +1 -1
  110. package/src/cli/config-commands.ts +334 -0
  111. package/src/cli/core-commands.ts +776 -0
  112. package/src/cli/doordash.ts +251 -1
  113. package/src/cli/ipc-client.ts +82 -0
  114. package/src/cli/map.ts +270 -0
  115. package/src/cli/twitter.ts +575 -0
  116. package/src/cli.ts +7 -5
  117. package/src/commands/__tests__/cc-command-registry.test.ts +319 -0
  118. package/src/commands/cc-command-registry.ts +209 -0
  119. package/src/config/bundled-skills/contacts/SKILL.md +39 -0
  120. package/src/config/bundled-skills/contacts/TOOLS.json +122 -0
  121. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +9 -0
  122. package/src/config/bundled-skills/contacts/tools/contact-search.ts +9 -0
  123. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +9 -0
  124. package/src/config/bundled-skills/document/SKILL.md +18 -0
  125. package/src/config/bundled-skills/document/TOOLS.json +53 -0
  126. package/src/config/bundled-skills/document/tools/document-create.ts +9 -0
  127. package/src/config/bundled-skills/document/tools/document-update.ts +9 -0
  128. package/src/config/bundled-skills/doordash/SKILL.md +82 -23
  129. package/src/config/bundled-skills/followups/SKILL.md +32 -0
  130. package/src/config/bundled-skills/followups/TOOLS.json +100 -0
  131. package/src/config/bundled-skills/followups/tools/followup-create.ts +9 -0
  132. package/src/config/bundled-skills/followups/tools/followup-list.ts +9 -0
  133. package/src/config/bundled-skills/followups/tools/followup-resolve.ts +9 -0
  134. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -23
  135. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -1
  136. package/src/config/bundled-skills/playbooks/SKILL.md +31 -0
  137. package/src/config/bundled-skills/playbooks/TOOLS.json +126 -0
  138. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +9 -0
  139. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +9 -0
  140. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +9 -0
  141. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +9 -0
  142. package/src/config/bundled-skills/reminder/SKILL.md +20 -0
  143. package/src/config/bundled-skills/reminder/TOOLS.json +67 -0
  144. package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +9 -0
  145. package/src/config/bundled-skills/reminder/tools/reminder-create.ts +9 -0
  146. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +9 -0
  147. package/src/config/bundled-skills/schedule/SKILL.md +74 -0
  148. package/src/config/bundled-skills/schedule/TOOLS.json +135 -0
  149. package/src/config/bundled-skills/schedule/tools/schedule-create.ts +9 -0
  150. package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +9 -0
  151. package/src/config/bundled-skills/schedule/tools/schedule-list.ts +9 -0
  152. package/src/config/bundled-skills/schedule/tools/schedule-update.ts +9 -0
  153. package/src/config/bundled-skills/subagent/SKILL.md +25 -0
  154. package/src/config/bundled-skills/subagent/TOOLS.json +107 -0
  155. package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +9 -0
  156. package/src/config/bundled-skills/subagent/tools/subagent-message.ts +9 -0
  157. package/src/config/bundled-skills/subagent/tools/subagent-read.ts +9 -0
  158. package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +9 -0
  159. package/src/config/bundled-skills/subagent/tools/subagent-status.ts +9 -0
  160. package/src/config/bundled-skills/tasks/SKILL.md +28 -0
  161. package/src/config/bundled-skills/tasks/TOOLS.json +256 -0
  162. package/src/config/bundled-skills/tasks/tools/task-delete.ts +9 -0
  163. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +9 -0
  164. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +9 -0
  165. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +9 -0
  166. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +9 -0
  167. package/src/config/bundled-skills/tasks/tools/task-list.ts +9 -0
  168. package/src/config/bundled-skills/tasks/tools/task-run.ts +9 -0
  169. package/src/config/bundled-skills/tasks/tools/task-save.ts +9 -0
  170. package/src/config/bundled-skills/twitter/SKILL.md +134 -0
  171. package/src/config/bundled-skills/watcher/SKILL.md +27 -0
  172. package/src/config/bundled-skills/watcher/TOOLS.json +147 -0
  173. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +9 -0
  174. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +9 -0
  175. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +9 -0
  176. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +9 -0
  177. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +9 -0
  178. package/src/config/defaults.ts +34 -0
  179. package/src/config/loader.ts +4 -1
  180. package/src/config/schema.ts +165 -1
  181. package/src/config/system-prompt.ts +61 -16
  182. package/src/config/templates/IDENTITY.md +7 -0
  183. package/src/config/types.ts +4 -0
  184. package/src/config/vellum-skills/telegram-setup/SKILL.md +1 -5
  185. package/src/contacts/contact-store.ts +4 -4
  186. package/src/daemon/assistant-attachments.ts +10 -0
  187. package/src/daemon/classifier.ts +3 -1
  188. package/src/daemon/computer-use-session.ts +3 -1
  189. package/src/daemon/date-context.ts +136 -0
  190. package/src/daemon/handlers/apps.ts +16 -1
  191. package/src/daemon/handlers/browser.ts +54 -0
  192. package/src/daemon/handlers/computer-use.ts +7 -1
  193. package/src/daemon/handlers/config.ts +205 -5
  194. package/src/daemon/handlers/diagnostics.ts +5 -1
  195. package/src/daemon/handlers/documents.ts +18 -29
  196. package/src/daemon/handlers/home-base.ts +5 -1
  197. package/src/daemon/handlers/index.ts +40 -277
  198. package/src/daemon/handlers/misc.ts +9 -1
  199. package/src/daemon/handlers/publish.ts +6 -1
  200. package/src/daemon/handlers/sessions.ts +65 -12
  201. package/src/daemon/handlers/shared.ts +36 -1
  202. package/src/daemon/handlers/signing.ts +37 -0
  203. package/src/daemon/handlers/skills.ts +20 -6
  204. package/src/daemon/handlers/subagents.ts +8 -3
  205. package/src/daemon/handlers/twitter-auth.ts +169 -0
  206. package/src/daemon/handlers/work-items.ts +384 -68
  207. package/src/daemon/ipc-contract-inventory.json +32 -4
  208. package/src/daemon/ipc-contract.ts +156 -37
  209. package/src/daemon/ipc-protocol.ts +7 -2
  210. package/src/daemon/lifecycle.ts +21 -0
  211. package/src/daemon/main.ts +10 -4
  212. package/src/daemon/ride-shotgun-handler.ts +75 -10
  213. package/src/daemon/server.ts +143 -26
  214. package/src/daemon/session-agent-loop.ts +922 -0
  215. package/src/daemon/session-attachments.ts +28 -5
  216. package/src/daemon/session-conflict-gate.ts +18 -109
  217. package/src/daemon/session-error.ts +24 -3
  218. package/src/daemon/session-lifecycle.ts +147 -0
  219. package/src/daemon/session-media-retry.ts +147 -0
  220. package/src/daemon/session-messaging.ts +145 -0
  221. package/src/daemon/session-notifiers.ts +164 -0
  222. package/src/daemon/session-process.ts +2 -2
  223. package/src/daemon/session-queue-manager.ts +1 -0
  224. package/src/daemon/session-runtime-assembly.ts +52 -0
  225. package/src/daemon/session-skill-tools.ts +124 -5
  226. package/src/daemon/session-slash.ts +3 -0
  227. package/src/daemon/session-surfaces.ts +77 -2
  228. package/src/daemon/session-tool-setup.ts +216 -2
  229. package/src/daemon/session-usage.ts +0 -2
  230. package/src/daemon/session.ts +114 -1404
  231. package/src/daemon/video-thumbnail.ts +60 -0
  232. package/src/doordash/client.ts +121 -27
  233. package/src/doordash/queries.ts +1 -2
  234. package/src/export/formatter.ts +3 -1
  235. package/src/followups/followup-store.ts +4 -2
  236. package/src/followups/types.ts +6 -0
  237. package/src/hooks/templates.ts +1 -1
  238. package/src/index.ts +32 -1153
  239. package/src/memory/attachments-store.ts +28 -83
  240. package/src/memory/channel-delivery-store.ts +7 -21
  241. package/src/memory/clarification-resolver.ts +6 -5
  242. package/src/memory/conflict-intent.ts +114 -0
  243. package/src/memory/contradiction-checker.ts +3 -2
  244. package/src/memory/conversation-key-store.ts +10 -29
  245. package/src/memory/conversation-store.ts +2 -1
  246. package/src/memory/db.ts +96 -2
  247. package/src/memory/entity-extractor.ts +6 -3
  248. package/src/memory/items-extractor.ts +5 -4
  249. package/src/memory/job-handlers/conflict.ts +23 -1
  250. package/src/memory/jobs-store.ts +3 -2
  251. package/src/memory/llm-usage-store.ts +1 -2
  252. package/src/memory/runs-store.ts +1 -2
  253. package/src/memory/schema.ts +23 -2
  254. package/src/messaging/style-analyzer.ts +3 -2
  255. package/src/messaging/thread-summarizer.ts +8 -12
  256. package/src/messaging/triage-engine.ts +4 -2
  257. package/src/providers/openrouter/client.ts +20 -0
  258. package/src/providers/registry.ts +8 -0
  259. package/src/runtime/gateway-client.ts +36 -0
  260. package/src/runtime/http-server.ts +166 -22
  261. package/src/runtime/routes/attachment-routes.ts +2 -3
  262. package/src/runtime/routes/call-routes.ts +140 -0
  263. package/src/runtime/routes/channel-routes.ts +125 -88
  264. package/src/runtime/routes/conversation-routes.ts +5 -5
  265. package/src/runtime/routes/run-routes.ts +2 -2
  266. package/src/runtime/run-orchestrator.ts +9 -3
  267. package/src/schedule/recurrence-engine.ts +138 -0
  268. package/src/schedule/recurrence-types.ts +67 -0
  269. package/src/schedule/schedule-store.ts +102 -57
  270. package/src/schedule/scheduler.ts +9 -6
  271. package/src/security/oauth2.ts +29 -4
  272. package/src/security/secret-allowlist.ts +46 -0
  273. package/src/skills/clawhub.ts +1 -1
  274. package/src/subagent/manager.ts +40 -8
  275. package/src/swarm/backend-claude-code.ts +64 -9
  276. package/src/swarm/worker-prompts.ts +2 -1
  277. package/src/tasks/SPEC.md +34 -28
  278. package/src/tasks/ephemeral-permissions.ts +16 -7
  279. package/src/tasks/task-compiler.ts +5 -4
  280. package/src/tasks/task-runner.ts +10 -5
  281. package/src/tasks/task-scheduler.ts +1 -1
  282. package/src/tasks/tool-sanitizer.ts +36 -0
  283. package/src/tools/assets/search.ts +4 -4
  284. package/src/tools/browser/api-map.ts +293 -0
  285. package/src/tools/browser/auto-navigate.ts +270 -0
  286. package/src/tools/browser/browser-execution.ts +2 -1
  287. package/src/tools/browser/browser-manager.ts +2 -2
  288. package/src/tools/browser/network-recorder.ts +5 -4
  289. package/src/tools/browser/x-auto-navigate.ts +207 -0
  290. package/src/tools/calls/call-end.ts +17 -67
  291. package/src/tools/calls/call-start.ts +24 -85
  292. package/src/tools/calls/call-status.ts +35 -51
  293. package/src/tools/claude-code/claude-code.ts +207 -11
  294. package/src/tools/contacts/contact-merge.ts +46 -78
  295. package/src/tools/contacts/contact-search.ts +35 -79
  296. package/src/tools/contacts/contact-upsert.ts +35 -108
  297. package/src/tools/credentials/vault.ts +20 -4
  298. package/src/tools/document/document-tool.ts +71 -144
  299. package/src/tools/executor.ts +129 -10
  300. package/src/tools/followups/followup_create.ts +46 -88
  301. package/src/tools/followups/followup_list.ts +34 -74
  302. package/src/tools/followups/followup_resolve.ts +31 -66
  303. package/src/tools/host-terminal/cli-discover.ts +2 -1
  304. package/src/tools/host-terminal/host-shell.ts +10 -0
  305. package/src/tools/memory/handlers.ts +5 -4
  306. package/src/tools/network/__tests__/web-search.test.ts +427 -0
  307. package/src/tools/network/script-proxy/__tests__/logging.test.ts +248 -0
  308. package/src/tools/network/script-proxy/__tests__/policy.test.ts +234 -0
  309. package/src/tools/network/script-proxy/__tests__/router.test.ts +76 -0
  310. package/src/tools/network/web-fetch.ts +18 -6
  311. package/src/tools/playbooks/index.ts +4 -5
  312. package/src/tools/playbooks/playbook-create.ts +3 -47
  313. package/src/tools/playbooks/playbook-delete.ts +1 -25
  314. package/src/tools/playbooks/playbook-list.ts +1 -28
  315. package/src/tools/playbooks/playbook-update.ts +3 -51
  316. package/src/tools/reminder/reminder.ts +5 -78
  317. package/src/tools/schedule/create.ts +69 -74
  318. package/src/tools/schedule/delete.ts +21 -47
  319. package/src/tools/schedule/list.ts +55 -74
  320. package/src/tools/schedule/update.ts +77 -84
  321. package/src/tools/subagent/abort.ts +29 -58
  322. package/src/tools/subagent/message.ts +30 -63
  323. package/src/tools/subagent/read.ts +53 -84
  324. package/src/tools/subagent/spawn.ts +43 -82
  325. package/src/tools/subagent/status.ts +42 -71
  326. package/src/tools/swarm/delegate.ts +2 -1
  327. package/src/tools/tasks/index.ts +8 -8
  328. package/src/tools/tasks/task-delete.ts +60 -88
  329. package/src/tools/tasks/task-list.ts +31 -52
  330. package/src/tools/tasks/task-run.ts +72 -108
  331. package/src/tools/tasks/task-save.ts +33 -65
  332. package/src/tools/tasks/work-item-enqueue.ts +183 -215
  333. package/src/tools/tasks/work-item-list.ts +33 -63
  334. package/src/tools/tasks/work-item-remove.ts +45 -97
  335. package/src/tools/tasks/work-item-update.ts +91 -163
  336. package/src/tools/terminal/backends/native.ts +3 -1
  337. package/src/tools/tool-manifest.ts +0 -62
  338. package/src/tools/types.ts +6 -0
  339. package/src/tools/ui-surface/definitions.ts +3 -1
  340. package/src/tools/watch/screen-watch.ts +3 -1
  341. package/src/tools/watcher/create.ts +52 -98
  342. package/src/tools/watcher/delete.ts +20 -46
  343. package/src/tools/watcher/digest.ts +36 -70
  344. package/src/tools/watcher/list.ts +49 -79
  345. package/src/tools/watcher/update.ts +45 -91
  346. package/src/twitter/client.ts +690 -0
  347. package/src/twitter/session.ts +91 -0
  348. package/src/usage/types.ts +0 -1
  349. package/src/util/truncate.ts +6 -0
  350. package/src/watcher/providers/slack.ts +2 -1
  351. package/src/watcher/watcher-store.ts +3 -2
  352. package/src/work-items/work-item-store.ts +27 -2
  353. package/src/workspace/commit-message-enrichment-service.ts +31 -7
  354. package/src/workspace/git-service.ts +87 -22
  355. package/src/workspace/provider-commit-message-generator.ts +269 -0
  356. package/src/workspace/turn-commit.ts +62 -3
  357. package/src/tools/contacts/index.ts +0 -4
  358. package/src/tools/document/index.ts +0 -5
  359. package/src/tools/followups/index.ts +0 -3
  360. package/src/tools/subagent/index.ts +0 -5
  361. /package/src/__tests__/{memory-context-benchmark.test.ts → memory-context-benchmark.benchmark.test.ts} +0 -0
@@ -1,98 +1,67 @@
1
- /**
2
- * subagent_read tool — read the full output from a completed subagent's conversation.
3
- */
4
-
5
- import { RiskLevel } from '../../permissions/types.js';
6
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
7
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
8
2
  import { getSubagentManager, TERMINAL_STATUSES } from '../../subagent/index.js';
9
3
  import { getMessages } from '../../memory/conversation-store.js';
10
4
 
11
- const definition: ToolDefinition = {
12
- name: 'subagent_read',
13
- description:
14
- 'Read the full conversation output from a subagent. ' +
15
- 'Use this after a subagent completes to retrieve its full work product.',
16
- input_schema: {
17
- type: 'object',
18
- properties: {
19
- subagent_id: {
20
- type: 'string',
21
- description: 'The ID of the subagent whose output to read.',
22
- },
23
- },
24
- required: ['subagent_id'],
25
- },
26
- };
27
-
28
- export const subagentReadTool: Tool = {
29
- name: 'subagent_read',
30
- description: definition.description,
31
- category: 'orchestration',
32
- defaultRiskLevel: RiskLevel.Low,
33
-
34
- getDefinition(): ToolDefinition {
35
- return definition;
36
- },
37
-
38
- async execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult> {
39
- const subagentId = input.subagent_id as string;
40
- if (!subagentId) {
41
- return { content: '"subagent_id" is required.', isError: true };
42
- }
5
+ export async function executeSubagentRead(
6
+ input: Record<string, unknown>,
7
+ context: ToolContext,
8
+ ): Promise<ToolExecutionResult> {
9
+ const subagentId = input.subagent_id as string;
10
+ if (!subagentId) {
11
+ return { content: '"subagent_id" is required.', isError: true };
12
+ }
43
13
 
44
- const manager = getSubagentManager();
45
- const state = manager.getState(subagentId);
46
- if (!state) {
47
- return { content: `No subagent found with ID "${subagentId}".`, isError: true };
48
- }
14
+ const manager = getSubagentManager();
15
+ const state = manager.getState(subagentId);
16
+ if (!state) {
17
+ return { content: `No subagent found with ID "${subagentId}".`, isError: true };
18
+ }
49
19
 
50
- // Ownership check: only the parent session can read a subagent's output.
51
- if (state.config.parentSessionId !== context.sessionId) {
52
- return { content: `No subagent found with ID "${subagentId}".`, isError: true };
53
- }
20
+ // Ownership check: only the parent session can read a subagent's output.
21
+ if (state.config.parentSessionId !== context.sessionId) {
22
+ return { content: `No subagent found with ID "${subagentId}".`, isError: true };
23
+ }
54
24
 
55
- if (!TERMINAL_STATUSES.has(state.status)) {
56
- return {
57
- content: `Subagent "${state.config.label}" is still ${state.status}. Wait for it to finish.`,
58
- isError: false,
59
- };
60
- }
25
+ if (!TERMINAL_STATUSES.has(state.status)) {
26
+ return {
27
+ content: `Subagent "${state.config.label}" is still ${state.status}. Wait for it to finish.`,
28
+ isError: false,
29
+ };
30
+ }
61
31
 
62
- // Read the subagent's conversation messages from DB.
63
- const dbMessages = getMessages(state.conversationId);
64
- if (!dbMessages || dbMessages.length === 0) {
65
- return { content: 'No messages found in subagent conversation.', isError: true };
66
- }
32
+ // Read the subagent's conversation messages from DB.
33
+ const dbMessages = getMessages(state.conversationId);
34
+ if (!dbMessages || dbMessages.length === 0) {
35
+ return { content: 'No messages found in subagent conversation.', isError: true };
36
+ }
67
37
 
68
- // Extract assistant messages only — that's the subagent's output.
69
- const output: string[] = [];
70
- for (const msg of dbMessages) {
71
- if (msg.role !== 'assistant') continue;
72
- try {
73
- const content = JSON.parse(msg.content);
74
- if (Array.isArray(content)) {
75
- for (const block of content) {
76
- if (block.type === 'text' && typeof block.text === 'string') {
77
- output.push(block.text);
78
- }
38
+ // Extract assistant messages only — that's the subagent's output.
39
+ const output: string[] = [];
40
+ for (const msg of dbMessages) {
41
+ if (msg.role !== 'assistant') continue;
42
+ try {
43
+ const content = JSON.parse(msg.content);
44
+ if (Array.isArray(content)) {
45
+ for (const block of content) {
46
+ if (block.type === 'text' && typeof block.text === 'string') {
47
+ output.push(block.text);
79
48
  }
80
- } else if (typeof content === 'string') {
81
- output.push(content);
82
49
  }
83
- } catch {
84
- // Content might be plain text.
85
- output.push(msg.content);
50
+ } else if (typeof content === 'string') {
51
+ output.push(content);
86
52
  }
53
+ } catch {
54
+ // Content might be plain text.
55
+ output.push(msg.content);
87
56
  }
57
+ }
88
58
 
89
- if (output.length === 0) {
90
- return { content: 'Subagent produced no text output.', isError: false };
91
- }
59
+ if (output.length === 0) {
60
+ return { content: 'Subagent produced no text output.', isError: false };
61
+ }
92
62
 
93
- return {
94
- content: output.join('\n\n'),
95
- isError: false,
96
- };
97
- },
98
- };
63
+ return {
64
+ content: output.join('\n\n'),
65
+ isError: false,
66
+ };
67
+ }
@@ -1,85 +1,46 @@
1
- /**
2
- * subagent_spawn tool — lets the parent LLM spawn an autonomous subagent.
3
- */
4
-
5
- import { RiskLevel } from '../../permissions/types.js';
6
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
7
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
8
2
  import { getSubagentManager } from '../../subagent/index.js';
9
3
 
10
- const definition: ToolDefinition = {
11
- name: 'subagent_spawn',
12
- description:
13
- 'Spawn an independent subagent to work on a task in parallel. ' +
14
- 'The subagent runs autonomously and its results are reported back when complete.',
15
- input_schema: {
16
- type: 'object',
17
- properties: {
18
- label: {
19
- type: 'string',
20
- description: 'Short human-readable label for this subagent (e.g. "Research competitor pricing")',
21
- },
22
- objective: {
23
- type: 'string',
24
- description: 'The task objective — what the subagent should accomplish',
25
- },
26
- context: {
27
- type: 'string',
28
- description: 'Optional additional context to pass to the subagent',
4
+ export async function executeSubagentSpawn(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ const label = input.label as string;
9
+ const objective = input.objective as string;
10
+ const extraContext = input.context as string | undefined;
11
+
12
+ if (!label || !objective) {
13
+ return { content: 'Both "label" and "objective" are required.', isError: true };
14
+ }
15
+
16
+ const manager = getSubagentManager();
17
+ const sendToClient = context.sendToClient as ((msg: { type: string; [key: string]: unknown }) => void) | undefined;
18
+ if (!sendToClient) {
19
+ return { content: 'No IPC client connected — cannot spawn subagent.', isError: true };
20
+ }
21
+
22
+ try {
23
+ const subagentId = await manager.spawn(
24
+ {
25
+ parentSessionId: context.sessionId,
26
+ label,
27
+ objective,
28
+ context: extraContext,
29
29
  },
30
- },
31
- required: ['label', 'objective'],
32
- },
33
- };
34
-
35
- export const subagentSpawnTool: Tool = {
36
- name: 'subagent_spawn',
37
- description: definition.description,
38
- category: 'orchestration',
39
- defaultRiskLevel: RiskLevel.Low,
40
-
41
- getDefinition(): ToolDefinition {
42
- return definition;
43
- },
44
-
45
- async execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult> {
46
- const label = input.label as string;
47
- const objective = input.objective as string;
48
- const extraContext = input.context as string | undefined;
49
-
50
- if (!label || !objective) {
51
- return { content: 'Both "label" and "objective" are required.', isError: true };
52
- }
53
-
54
- const manager = getSubagentManager();
55
- const sendToClient = context.sendToClient as ((msg: { type: string; [key: string]: unknown }) => void) | undefined;
56
- if (!sendToClient) {
57
- return { content: 'No IPC client connected — cannot spawn subagent.', isError: true };
58
- }
59
-
60
- try {
61
- const subagentId = await manager.spawn(
62
- {
63
- parentSessionId: context.sessionId,
64
- label,
65
- objective,
66
- context: extraContext,
67
- },
68
- sendToClient as (msg: unknown) => void,
69
- );
70
-
71
- return {
72
- content: JSON.stringify({
73
- subagentId,
74
- label,
75
- status: 'pending',
76
- message: `Subagent "${label}" spawned. You will be notified automatically when it completes or fails — do NOT poll subagent_status. Continue the conversation normally.`,
77
- }),
78
- isError: false,
79
- };
80
- } catch (err) {
81
- const msg = err instanceof Error ? err.message : String(err);
82
- return { content: `Failed to spawn subagent: ${msg}`, isError: true };
83
- }
84
- },
85
- };
30
+ sendToClient as (msg: unknown) => void,
31
+ );
32
+
33
+ return {
34
+ content: JSON.stringify({
35
+ subagentId,
36
+ label,
37
+ status: 'pending',
38
+ message: `Subagent "${label}" spawned. You will be notified automatically when it completes or fails — do NOT poll subagent_status. Continue the conversation normally.`,
39
+ }),
40
+ isError: false,
41
+ };
42
+ } catch (err) {
43
+ const msg = err instanceof Error ? err.message : String(err);
44
+ return { content: `Failed to spawn subagent: ${msg}`, isError: true };
45
+ }
46
+ }
@@ -1,74 +1,45 @@
1
- /**
2
- * subagent_status tool — query the status of one or all subagents.
3
- */
4
-
5
- import { RiskLevel } from '../../permissions/types.js';
6
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
7
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
8
2
  import { getSubagentManager } from '../../subagent/index.js';
9
3
 
10
- const definition: ToolDefinition = {
11
- name: 'subagent_status',
12
- description: 'Get the status of a specific subagent or list all subagents for the current session. Only use this when the user explicitly asks about subagent status — do NOT poll automatically, as you will be notified when subagents complete.',
13
- input_schema: {
14
- type: 'object',
15
- properties: {
16
- subagent_id: {
17
- type: 'string',
18
- description: 'Optional subagent ID to query. If omitted, returns all subagents for this session.',
19
- },
20
- },
21
- required: [],
22
- },
23
- };
24
-
25
- export const subagentStatusTool: Tool = {
26
- name: 'subagent_status',
27
- description: definition.description,
28
- category: 'orchestration',
29
- defaultRiskLevel: RiskLevel.Low,
30
-
31
- getDefinition(): ToolDefinition {
32
- return definition;
33
- },
34
-
35
- async execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult> {
36
- const subagentId = input.subagent_id as string | undefined;
37
- const manager = getSubagentManager();
38
-
39
- if (subagentId) {
40
- const state = manager.getState(subagentId);
41
- if (!state || state.config.parentSessionId !== context.sessionId) {
42
- return { content: `No subagent found with ID "${subagentId}".`, isError: true };
43
- }
44
- return {
45
- content: JSON.stringify({
46
- subagentId: state.config.id,
47
- label: state.config.label,
48
- status: state.status,
49
- error: state.error,
50
- createdAt: state.createdAt,
51
- startedAt: state.startedAt,
52
- completedAt: state.completedAt,
53
- usage: state.usage,
54
- }),
55
- isError: false,
56
- };
4
+ export async function executeSubagentStatus(
5
+ input: Record<string, unknown>,
6
+ context: ToolContext,
7
+ ): Promise<ToolExecutionResult> {
8
+ const subagentId = input.subagent_id as string | undefined;
9
+ const manager = getSubagentManager();
10
+
11
+ if (subagentId) {
12
+ const state = manager.getState(subagentId);
13
+ if (!state || state.config.parentSessionId !== context.sessionId) {
14
+ return { content: `No subagent found with ID "${subagentId}".`, isError: true };
57
15
  }
58
-
59
- // List all subagents for this parent session.
60
- const children = manager.getChildrenOf(context.sessionId);
61
- if (children.length === 0) {
62
- return { content: 'No subagents found for this session.', isError: false };
63
- }
64
-
65
- const summary = children.map((s) => ({
66
- subagentId: s.config.id,
67
- label: s.config.label,
68
- status: s.status,
69
- error: s.error,
70
- }));
71
-
72
- return { content: JSON.stringify(summary), isError: false };
73
- },
74
- };
16
+ return {
17
+ content: JSON.stringify({
18
+ subagentId: state.config.id,
19
+ label: state.config.label,
20
+ status: state.status,
21
+ error: state.error,
22
+ createdAt: state.createdAt,
23
+ startedAt: state.startedAt,
24
+ completedAt: state.completedAt,
25
+ usage: state.usage,
26
+ }),
27
+ isError: false,
28
+ };
29
+ }
30
+
31
+ // List all subagents for this parent session.
32
+ const children = manager.getChildrenOf(context.sessionId);
33
+ if (children.length === 0) {
34
+ return { content: 'No subagents found for this session.', isError: false };
35
+ }
36
+
37
+ const summary = children.map((s) => ({
38
+ subagentId: s.config.id,
39
+ label: s.config.label,
40
+ status: s.status,
41
+ error: s.error,
42
+ }));
43
+
44
+ return { content: JSON.stringify(summary), isError: false };
45
+ }
@@ -3,6 +3,7 @@ import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
3
3
  import type { ToolDefinition } from '../../providers/types.js';
4
4
  import { getConfig } from '../../config/loader.js';
5
5
  import { getLogger } from '../../util/logger.js';
6
+ import { truncate } from '../../util/truncate.js';
6
7
  import { getFailoverProvider } from '../../providers/registry.js';
7
8
  import { resolveSwarmLimits } from '../../swarm/limits.js';
8
9
  import { generatePlan } from '../../swarm/router-planner.js';
@@ -94,7 +95,7 @@ export const swarmDelegateTool: Tool = {
94
95
 
95
96
  context.onOutput?.(`Plan: ${plan.tasks.length} tasks\n`);
96
97
  for (const task of plan.tasks) {
97
- context.onOutput?.(` - [${task.role}] ${task.id}: ${task.objective.slice(0, 80)}\n`);
98
+ context.onOutput?.(` - [${task.role}] ${task.id}: ${truncate(task.objective, 80)}\n`);
98
99
  }
99
100
  context.onOutput?.('\nExecuting...\n');
100
101
 
@@ -17,11 +17,11 @@
17
17
  * comments, logs, and developer-facing docs.
18
18
  */
19
19
 
20
- export { taskSaveTool } from './task-save.js';
21
- export { taskRunTool } from './task-run.js';
22
- export { taskListTool } from './task-list.js';
23
- export { taskDeleteTool } from './task-delete.js';
24
- export { taskListShowTool } from './work-item-list.js';
25
- export { taskListAddTool } from './work-item-enqueue.js';
26
- export { taskListUpdateTool } from './work-item-update.js';
27
- export { taskListRemoveTool } from './work-item-remove.js';
20
+ export { executeTaskSave } from './task-save.js';
21
+ export { executeTaskRun } from './task-run.js';
22
+ export { executeTaskList } from './task-list.js';
23
+ export { executeTaskDelete } from './task-delete.js';
24
+ export { executeTaskListShow } from './work-item-list.js';
25
+ export { executeTaskListAdd } from './work-item-enqueue.js';
26
+ export { executeTaskListUpdate } from './work-item-update.js';
27
+ export { executeTaskListRemove } from './work-item-remove.js';
@@ -1,110 +1,82 @@
1
- import { RiskLevel } from '../../permissions/types.js';
2
- import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
3
- import type { ToolDefinition } from '../../providers/types.js';
1
+ import type { ToolContext, ToolExecutionResult } from '../types.js';
4
2
  import { deleteTask, deleteTasks, getTask } from '../../tasks/task-store.js';
5
3
  import { removeWorkItemFromQueue } from '../../work-items/work-item-store.js';
6
4
  import { getLogger } from '../../util/logger.js';
7
5
 
8
6
  const log = getLogger('task-delete');
9
7
 
10
- const definition: ToolDefinition = {
11
- name: 'task_delete',
12
- description: 'Delete one or more task templates by ID. Also removes associated task runs and work items (Tasks).',
13
- input_schema: {
14
- type: 'object',
15
- properties: {
16
- task_ids: {
17
- type: 'array',
18
- items: { type: 'string' },
19
- description: 'One or more task IDs to delete.',
20
- },
21
- },
22
- required: ['task_ids'],
23
- },
24
- };
25
-
26
- class TaskDeleteTool implements Tool {
27
- name = 'task_delete';
28
- description = definition.description;
29
- category = 'tasks';
30
- defaultRiskLevel = RiskLevel.Medium;
31
-
32
- getDefinition(): ToolDefinition {
33
- return definition;
8
+ export async function executeTaskDelete(
9
+ input: Record<string, unknown>,
10
+ _context: ToolContext,
11
+ ): Promise<ToolExecutionResult> {
12
+ const raw = input.task_ids;
13
+ if (!Array.isArray(raw) || raw.length === 0) {
14
+ return { content: 'Error: task_ids must be a non-empty array of task ID strings', isError: true };
15
+ }
16
+ const ids = raw.filter((v): v is string => typeof v === 'string' && v.trim().length > 0);
17
+ if (ids.length === 0) {
18
+ return { content: 'Error: task_ids must contain at least one non-empty string', isError: true };
34
19
  }
35
20
 
36
- async execute(input: Record<string, unknown>, _context: ToolContext): Promise<ToolExecutionResult> {
37
- const raw = input.task_ids;
38
- if (!Array.isArray(raw) || raw.length === 0) {
39
- return { content: 'Error: task_ids must be a non-empty array of task ID strings', isError: true };
40
- }
41
- const ids = raw.filter((v): v is string => typeof v === 'string' && v.trim().length > 0);
42
- if (ids.length === 0) {
43
- return { content: 'Error: task_ids must contain at least one non-empty string', isError: true };
44
- }
45
-
46
- try {
47
- if (ids.length === 1) {
48
- const task = getTask(ids[0]);
49
- const deleted = deleteTask(ids[0]);
50
- if (!deleted) {
51
- // The LLM may pass a work item ID instead of a task template ID.
52
- // Fall back to removing from the task queue so the user's intent succeeds.
53
- const result = removeWorkItemFromQueue(ids[0]);
54
- if (result.success) {
55
- log.info({ inputId: ids[0], fallback: true, deletedCount: 1 }, 'deleted via work item fallback');
56
- return { content: result.message, isError: false };
57
- }
58
- log.warn({ inputId: ids[0] }, 'no task or work item found for deletion');
59
- return { content: `No task template or work item found with ID "${ids[0]}". Use task_list to see task templates or task_list_show to see work items in the queue.`, isError: true };
21
+ try {
22
+ if (ids.length === 1) {
23
+ const task = getTask(ids[0]);
24
+ const deleted = deleteTask(ids[0]);
25
+ if (!deleted) {
26
+ // The LLM may pass a work item ID instead of a task template ID.
27
+ // Fall back to removing from the task queue so the user's intent succeeds.
28
+ const result = removeWorkItemFromQueue(ids[0]);
29
+ if (result.success) {
30
+ log.info({ inputId: ids[0], fallback: true, deletedCount: 1 }, 'deleted via work item fallback');
31
+ return { content: result.message, isError: false };
60
32
  }
61
- log.info({ taskId: ids[0], title: task?.title, deletedCount: 1 }, 'task deleted');
62
- return { content: `Deleted task: ${task?.title ?? ids[0]}`, isError: false };
33
+ log.warn({ inputId: ids[0] }, 'no task or work item found for deletion');
34
+ return { content: `No task template or work item found with ID "${ids[0]}". Use task_list to see task templates or task_list_show to see work items in the queue.`, isError: true };
63
35
  }
36
+ log.info({ taskId: ids[0], title: task?.title, deletedCount: 1 }, 'task deleted');
37
+ return { content: `Deleted task: ${task?.title ?? ids[0]}`, isError: false };
38
+ }
64
39
 
65
- const taskIds: string[] = [];
66
- const taskTitles: string[] = [];
67
- const workItemTitles: string[] = [];
40
+ const taskIds: string[] = [];
41
+ const taskTitles: string[] = [];
42
+ const workItemTitles: string[] = [];
68
43
 
69
- for (const id of ids) {
70
- const task = getTask(id);
71
- if (task) {
72
- taskIds.push(id);
73
- taskTitles.push(task.title);
44
+ for (const id of ids) {
45
+ const task = getTask(id);
46
+ if (task) {
47
+ taskIds.push(id);
48
+ taskTitles.push(task.title);
49
+ } else {
50
+ const result = removeWorkItemFromQueue(id);
51
+ if (result.success) {
52
+ log.info({ inputId: id, fallback: true }, 'deleted work item in batch (fallback)');
53
+ workItemTitles.push(result.title);
74
54
  } else {
75
- const result = removeWorkItemFromQueue(id);
76
- if (result.success) {
77
- log.info({ inputId: id, fallback: true }, 'deleted work item in batch (fallback)');
78
- workItemTitles.push(result.title);
79
- } else {
80
- log.warn({ inputId: id }, 'batch delete: no task or work item found');
81
- }
55
+ log.warn({ inputId: id }, 'batch delete: no task or work item found');
82
56
  }
83
57
  }
58
+ }
84
59
 
85
- const taskCount = taskIds.length > 0 ? deleteTasks(taskIds) : 0;
60
+ const taskCount = taskIds.length > 0 ? deleteTasks(taskIds) : 0;
86
61
 
87
- if (taskCount === 0 && workItemTitles.length === 0) {
88
- log.warn({ inputIds: ids }, 'no matching tasks found to delete');
89
- return { content: 'No matching tasks found to delete.', isError: true };
90
- }
62
+ if (taskCount === 0 && workItemTitles.length === 0) {
63
+ log.warn({ inputIds: ids }, 'no matching tasks found to delete');
64
+ return { content: 'No matching tasks found to delete.', isError: true };
65
+ }
91
66
 
92
- log.info({ deletedTasks: taskCount, deletedWorkItems: workItemTitles.length, totalInput: ids.length }, 'batch delete completed');
67
+ log.info({ deletedTasks: taskCount, deletedWorkItems: workItemTitles.length, totalInput: ids.length }, 'batch delete completed');
93
68
 
94
- const lines: string[] = [];
95
- if (taskCount > 0) {
96
- lines.push(`Deleted ${taskCount} task(s):`, ...taskTitles.map((t) => `- ${t}`));
97
- }
98
- if (workItemTitles.length > 0) {
99
- lines.push(`Removed ${workItemTitles.length} item(s) from the task queue:`, ...workItemTitles.map((t) => `- ${t}`));
100
- }
101
- return { content: lines.join('\n'), isError: false };
102
- } catch (err) {
103
- const msg = err instanceof Error ? err.message : String(err);
104
- log.error({ inputIds: ids, error: msg }, 'delete failed');
105
- return { content: `Error: ${msg}`, isError: true };
69
+ const lines: string[] = [];
70
+ if (taskCount > 0) {
71
+ lines.push(`Deleted ${taskCount} task(s):`, ...taskTitles.map((t) => `- ${t}`));
72
+ }
73
+ if (workItemTitles.length > 0) {
74
+ lines.push(`Removed ${workItemTitles.length} item(s) from the task queue:`, ...workItemTitles.map((t) => `- ${t}`));
106
75
  }
76
+ return { content: lines.join('\n'), isError: false };
77
+ } catch (err) {
78
+ const msg = err instanceof Error ? err.message : String(err);
79
+ log.error({ inputIds: ids, error: msg }, 'delete failed');
80
+ return { content: `Error: ${msg}`, isError: true };
107
81
  }
108
82
  }
109
-
110
- export const taskDeleteTool = new TaskDeleteTool();