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.
- package/.dockerignore +27 -0
- package/.env.example +22 -0
- package/Dockerfile +99 -0
- package/Dockerfile.sandbox +5 -0
- package/README.md +150 -3
- package/bun.lock +1768 -0
- package/bunfig.toml +2 -0
- package/docs/skills.md +158 -0
- package/drizzle/0000_dizzy_maggott.sql +301 -0
- package/drizzle/meta/0000_snapshot.json +1999 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +7 -0
- package/eslint.config.mjs +17 -0
- package/hook-templates/debug-prompt-logger/hook.json +7 -0
- package/hook-templates/debug-prompt-logger/run.sh +68 -0
- package/knip.json +9 -0
- package/package.json +60 -10
- package/scripts/ipc/check-contract-inventory.ts +104 -0
- package/scripts/ipc/check-swift-decoder-drift.ts +163 -0
- package/scripts/ipc/generate-swift.ts +492 -0
- package/scripts/test-filesystem-tools.sh +48 -0
- package/scripts/test.sh +122 -0
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +2079 -0
- package/src/__tests__/account-registry.test.ts +244 -0
- package/src/__tests__/active-skill-tools.test.ts +378 -0
- package/src/__tests__/agent-loop-thinking.test.ts +81 -0
- package/src/__tests__/agent-loop.test.ts +1135 -0
- package/src/__tests__/anthropic-provider.test.ts +778 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +290 -0
- package/src/__tests__/app-bundler.test.ts +313 -0
- package/src/__tests__/app-executors.test.ts +613 -0
- package/src/__tests__/app-open-proxy.test.ts +62 -0
- package/src/__tests__/asset-materialize-tool.test.ts +451 -0
- package/src/__tests__/asset-search-tool.test.ts +476 -0
- package/src/__tests__/assistant-attachment-directive.test.ts +401 -0
- package/src/__tests__/assistant-attachments.test.ts +437 -0
- package/src/__tests__/assistant-event-hub.test.ts +226 -0
- package/src/__tests__/assistant-event.test.ts +123 -0
- package/src/__tests__/attachments-store.test.ts +547 -0
- package/src/__tests__/attachments.test.ts +134 -0
- package/src/__tests__/audit-log-rotation.test.ts +154 -0
- package/src/__tests__/browser-fill-credential.test.ts +309 -0
- package/src/__tests__/browser-manager.test.ts +203 -0
- package/src/__tests__/browser-runtime-check.test.ts +55 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +67 -0
- package/src/__tests__/browser-skill-endstate.test.ts +198 -0
- package/src/__tests__/bundle-scanner.test.ts +313 -0
- package/src/__tests__/checker.test.ts +3856 -0
- package/src/__tests__/clarification-resolver.test.ts +159 -0
- package/src/__tests__/classifier.test.ts +67 -0
- package/src/__tests__/claude-code-skill-regression.test.ts +127 -0
- package/src/__tests__/claude-code-tool-profiles.test.ts +88 -0
- package/src/__tests__/cli-discover.test.ts +85 -0
- package/src/__tests__/cli.test.ts +81 -0
- package/src/__tests__/clipboard.test.ts +80 -0
- package/src/__tests__/commit-guarantee.test.ts +335 -0
- package/src/__tests__/computer-use-session-compaction.test.ts +132 -0
- package/src/__tests__/computer-use-session-lifecycle.test.ts +293 -0
- package/src/__tests__/computer-use-session-working-dir.test.ts +117 -0
- package/src/__tests__/computer-use-skill-baseline.test.ts +74 -0
- package/src/__tests__/computer-use-skill-endstate.test.ts +89 -0
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +217 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +107 -0
- package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +54 -0
- package/src/__tests__/config-schema.test.ts +720 -0
- package/src/__tests__/conflict-store.test.ts +329 -0
- package/src/__tests__/connection-policy.test.ts +102 -0
- package/src/__tests__/context-memory-e2e.test.ts +434 -0
- package/src/__tests__/context-token-estimator.test.ts +135 -0
- package/src/__tests__/context-window-manager.test.ts +376 -0
- package/src/__tests__/contradiction-checker.test.ts +216 -0
- package/src/__tests__/conversation-store.test.ts +614 -0
- package/src/__tests__/credential-broker-browser-fill.test.ts +517 -0
- package/src/__tests__/credential-broker-server-use.test.ts +554 -0
- package/src/__tests__/credential-broker.test.ts +167 -0
- package/src/__tests__/credential-host-pattern-match.test.ts +104 -0
- package/src/__tests__/credential-metadata-store.test.ts +779 -0
- package/src/__tests__/credential-policy-validate.test.ts +121 -0
- package/src/__tests__/credential-resolve.test.ts +328 -0
- package/src/__tests__/credential-security-e2e.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +563 -0
- package/src/__tests__/credential-selection.test.ts +354 -0
- package/src/__tests__/credential-vault.test.ts +852 -0
- package/src/__tests__/daemon-assistant-events.test.ts +164 -0
- package/src/__tests__/daemon-server-session-init.test.ts +522 -0
- package/src/__tests__/delete-managed-skill-tool.test.ts +97 -0
- package/src/__tests__/diff.test.ts +121 -0
- package/src/__tests__/domain-normalize.test.ts +112 -0
- package/src/__tests__/domain-policy.test.ts +124 -0
- package/src/__tests__/doordash-client.test.ts +186 -0
- package/src/__tests__/doordash-session.test.ts +143 -0
- package/src/__tests__/dynamic-page-surface.test.ts +91 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +132 -0
- package/src/__tests__/edit-engine.test.ts +180 -0
- package/src/__tests__/email-cli.test.ts +283 -0
- package/src/__tests__/encrypted-store.test.ts +332 -0
- package/src/__tests__/entity-extractor.test.ts +190 -0
- package/src/__tests__/ephemeral-permissions.test.ts +312 -0
- package/src/__tests__/evaluate-typescript-tool.test.ts +286 -0
- package/src/__tests__/event-bus.test.ts +222 -0
- package/src/__tests__/file-edit-tool.test.ts +122 -0
- package/src/__tests__/file-ops-service.test.ts +330 -0
- package/src/__tests__/file-read-tool.test.ts +75 -0
- package/src/__tests__/file-write-tool.test.ts +113 -0
- package/src/__tests__/fixtures/credential-security-fixtures.ts +181 -0
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +126 -0
- package/src/__tests__/fixtures/mock-signup-server.ts +387 -0
- package/src/__tests__/fixtures/proxy-fixtures.ts +147 -0
- package/src/__tests__/fuzzy-match-property.test.ts +216 -0
- package/src/__tests__/fuzzy-match.test.ts +138 -0
- package/src/__tests__/gemini-image-service.test.ts +261 -0
- package/src/__tests__/gemini-provider.test.ts +651 -0
- package/src/__tests__/get-weather.test.ts +318 -0
- package/src/__tests__/gmail-integration.test.ts +73 -0
- package/src/__tests__/handlers-cu-observation-blob.test.ts +351 -0
- package/src/__tests__/handlers-ipc-blob-probe.test.ts +190 -0
- package/src/__tests__/handlers-slack-config.test.ts +199 -0
- package/src/__tests__/handlers-task-submit-slash.test.ts +38 -0
- package/src/__tests__/headless-browser-interactions.test.ts +536 -0
- package/src/__tests__/headless-browser-navigate.test.ts +211 -0
- package/src/__tests__/headless-browser-read-tools.test.ts +261 -0
- package/src/__tests__/headless-browser-snapshot.test.ts +185 -0
- package/src/__tests__/history-repair-observability.test.ts +56 -0
- package/src/__tests__/history-repair.test.ts +510 -0
- package/src/__tests__/home-base-bootstrap.test.ts +77 -0
- package/src/__tests__/hooks-blocking.test.ts +128 -0
- package/src/__tests__/hooks-cli.test.ts +144 -0
- package/src/__tests__/hooks-config.test.ts +93 -0
- package/src/__tests__/hooks-discovery.test.ts +199 -0
- package/src/__tests__/hooks-integration.test.ts +189 -0
- package/src/__tests__/hooks-manager.test.ts +187 -0
- package/src/__tests__/hooks-runner.test.ts +178 -0
- package/src/__tests__/hooks-settings.test.ts +154 -0
- package/src/__tests__/hooks-templates.test.ts +137 -0
- package/src/__tests__/hooks-ts-runner.test.ts +125 -0
- package/src/__tests__/hooks-watch.test.ts +100 -0
- package/src/__tests__/host-file-edit-tool.test.ts +104 -0
- package/src/__tests__/host-file-read-tool.test.ts +61 -0
- package/src/__tests__/host-file-write-tool.test.ts +77 -0
- package/src/__tests__/host-shell-tool.test.ts +311 -0
- package/src/__tests__/intent-routing.test.ts +255 -0
- package/src/__tests__/ipc-blob-store.test.ts +315 -0
- package/src/__tests__/ipc-contract-inventory.test.ts +54 -0
- package/src/__tests__/ipc-contract.test.ts +74 -0
- package/src/__tests__/ipc-protocol.test.ts +113 -0
- package/src/__tests__/ipc-snapshot.test.ts +1560 -0
- package/src/__tests__/ipc-validate.test.ts +357 -0
- package/src/__tests__/key-migration.test.ts +183 -0
- package/src/__tests__/keychain.test.ts +258 -0
- package/src/__tests__/llm-usage-store.test.ts +226 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +257 -0
- package/src/__tests__/managed-store.test.ts +608 -0
- package/src/__tests__/media-generate-image.test.ts +238 -0
- package/src/__tests__/media-reuse-story.e2e.test.ts +676 -0
- package/src/__tests__/media-visibility-policy.test.ts +141 -0
- package/src/__tests__/memory-context-benchmark.test.ts +235 -0
- package/src/__tests__/memory-lifecycle-e2e.test.ts +481 -0
- package/src/__tests__/memory-query-builder.test.ts +59 -0
- package/src/__tests__/memory-recall-quality.test.ts +846 -0
- package/src/__tests__/memory-regressions.experimental.test.ts +538 -0
- package/src/__tests__/memory-regressions.test.ts +4238 -0
- package/src/__tests__/memory-retrieval-budget.test.ts +49 -0
- package/src/__tests__/migration-cli-flows.test.ts +169 -0
- package/src/__tests__/migration-ordering.test.ts +249 -0
- package/src/__tests__/mock-signup-server.test.ts +528 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +166 -0
- package/src/__tests__/onboarding-template-contract.test.ts +58 -0
- package/src/__tests__/openai-provider.test.ts +753 -0
- package/src/__tests__/parser.test.ts +472 -0
- package/src/__tests__/path-classifier.test.ts +73 -0
- package/src/__tests__/path-policy.test.ts +435 -0
- package/src/__tests__/platform-move-helper.test.ts +99 -0
- package/src/__tests__/platform-socket-path.test.ts +52 -0
- package/src/__tests__/platform-workspace-migration.test.ts +1000 -0
- package/src/__tests__/platform.test.ts +131 -0
- package/src/__tests__/prebuilt-home-base-seed.test.ts +71 -0
- package/src/__tests__/pricing.test.ts +256 -0
- package/src/__tests__/profile-compiler.test.ts +373 -0
- package/src/__tests__/provider-registry-ollama.test.ts +16 -0
- package/src/__tests__/proxy-approval-callback.test.ts +601 -0
- package/src/__tests__/ratelimit.test.ts +297 -0
- package/src/__tests__/registry.test.ts +487 -0
- package/src/__tests__/reminder-store.test.ts +220 -0
- package/src/__tests__/reminder.test.ts +263 -0
- package/src/__tests__/request-file-tool.test.ts +158 -0
- package/src/__tests__/run-orchestrator.test.ts +200 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +190 -0
- package/src/__tests__/runtime-runs-http.test.ts +451 -0
- package/src/__tests__/runtime-runs.test.ts +273 -0
- package/src/__tests__/sandbox-diagnostics.test.ts +408 -0
- package/src/__tests__/sandbox-host-parity.test.ts +950 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +253 -0
- package/src/__tests__/script-proxy-certs.test.ts +90 -0
- package/src/__tests__/script-proxy-connect-tunnel.test.ts +177 -0
- package/src/__tests__/script-proxy-decision-trace.test.ts +156 -0
- package/src/__tests__/script-proxy-http-forwarder.test.ts +281 -0
- package/src/__tests__/script-proxy-injection-runtime.test.ts +401 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +407 -0
- package/src/__tests__/script-proxy-policy-runtime.test.ts +287 -0
- package/src/__tests__/script-proxy-policy.test.ts +310 -0
- package/src/__tests__/script-proxy-rewrite-specificity.test.ts +135 -0
- package/src/__tests__/script-proxy-router.test.ts +180 -0
- package/src/__tests__/script-proxy-session-manager.test.ts +382 -0
- package/src/__tests__/script-proxy-session-runtime.test.ts +113 -0
- package/src/__tests__/secret-allowlist.test.ts +229 -0
- package/src/__tests__/secret-ingress-handler.test.ts +99 -0
- package/src/__tests__/secret-onetime-send.test.ts +130 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +106 -0
- package/src/__tests__/secret-response-routing.test.ts +93 -0
- package/src/__tests__/secret-scanner-executor.test.ts +348 -0
- package/src/__tests__/secret-scanner.test.ts +857 -0
- package/src/__tests__/secure-keys.test.ts +323 -0
- package/src/__tests__/server-history-render.test.ts +430 -0
- package/src/__tests__/session-abort-tool-results.test.ts +240 -0
- package/src/__tests__/session-conflict-gate.test.ts +697 -0
- package/src/__tests__/session-error.test.ts +341 -0
- package/src/__tests__/session-evictor.test.ts +188 -0
- package/src/__tests__/session-load-history-repair.test.ts +222 -0
- package/src/__tests__/session-pre-run-repair.test.ts +213 -0
- package/src/__tests__/session-profile-injection.test.ts +444 -0
- package/src/__tests__/session-provider-retry-repair.test.ts +306 -0
- package/src/__tests__/session-queue.test.ts +1462 -0
- package/src/__tests__/session-runtime-assembly.test.ts +315 -0
- package/src/__tests__/session-runtime-workspace.test.ts +183 -0
- package/src/__tests__/session-skill-tools.test.ts +2431 -0
- package/src/__tests__/session-slash-known.test.ts +368 -0
- package/src/__tests__/session-slash-queue.test.ts +288 -0
- package/src/__tests__/session-slash-unknown.test.ts +271 -0
- package/src/__tests__/session-tool-setup-app-refresh.test.ts +473 -0
- package/src/__tests__/session-tool-setup-memory-scope.test.ts +140 -0
- package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +140 -0
- package/src/__tests__/session-undo.test.ts +75 -0
- package/src/__tests__/session-workspace-cache-state.test.ts +246 -0
- package/src/__tests__/session-workspace-injection.test.ts +327 -0
- package/src/__tests__/session-workspace-tool-tracking.test.ts +240 -0
- package/src/__tests__/shared-filesystem-errors.test.ts +78 -0
- package/src/__tests__/shell-credential-ref.test.ts +187 -0
- package/src/__tests__/shell-parser-fuzz.test.ts +544 -0
- package/src/__tests__/shell-parser-property.test.ts +433 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +272 -0
- package/src/__tests__/signup-e2e.test.ts +352 -0
- package/src/__tests__/size-guard.test.ts +117 -0
- package/src/__tests__/skill-include-graph.test.ts +303 -0
- package/src/__tests__/skill-load-tool.test.ts +409 -0
- package/src/__tests__/skill-script-runner-host.test.ts +489 -0
- package/src/__tests__/skill-script-runner-sandbox.test.ts +349 -0
- package/src/__tests__/skill-tool-factory.test.ts +252 -0
- package/src/__tests__/skill-tool-manifest.test.ts +658 -0
- package/src/__tests__/skill-version-hash.test.ts +182 -0
- package/src/__tests__/skills.test.ts +597 -0
- package/src/__tests__/slash-commands-catalog.test.ts +86 -0
- package/src/__tests__/slash-commands-parser.test.ts +119 -0
- package/src/__tests__/slash-commands-resolver.test.ts +193 -0
- package/src/__tests__/slash-commands-rewrite.test.ts +39 -0
- package/src/__tests__/starter-bundle.test.ts +136 -0
- package/src/__tests__/starter-task-flow.test.ts +143 -0
- package/src/__tests__/subagent-manager-notify.test.ts +372 -0
- package/src/__tests__/subagent-tools.test.ts +118 -0
- package/src/__tests__/subagent-types.test.ts +78 -0
- package/src/__tests__/swarm-orchestrator.test.ts +428 -0
- package/src/__tests__/swarm-plan-validator.test.ts +330 -0
- package/src/__tests__/swarm-recursion.test.ts +165 -0
- package/src/__tests__/swarm-router-planner.test.ts +208 -0
- package/src/__tests__/swarm-session-integration.test.ts +274 -0
- package/src/__tests__/swarm-tool.test.ts +145 -0
- package/src/__tests__/swarm-worker-backend.test.ts +129 -0
- package/src/__tests__/swarm-worker-runner.test.ts +272 -0
- package/src/__tests__/system-prompt.test.ts +461 -0
- package/src/__tests__/task-compiler.test.ts +283 -0
- package/src/__tests__/task-runner.test.ts +215 -0
- package/src/__tests__/task-scheduler.test.ts +216 -0
- package/src/__tests__/task-tools.test.ts +602 -0
- package/src/__tests__/terminal-sandbox-docker.test.ts +1064 -0
- package/src/__tests__/terminal-sandbox.integration.test.ts +178 -0
- package/src/__tests__/terminal-sandbox.test.ts +202 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +90 -0
- package/src/__tests__/test-support/computer-use-skill-harness.ts +45 -0
- package/src/__tests__/tool-audit-listener.test.ts +112 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +251 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +516 -0
- package/src/__tests__/tool-executor-redaction.test.ts +289 -0
- package/src/__tests__/tool-executor.test.ts +1971 -0
- package/src/__tests__/tool-metrics-listener.test.ts +225 -0
- package/src/__tests__/tool-notification-listener.test.ts +49 -0
- package/src/__tests__/tool-policy.test.ts +54 -0
- package/src/__tests__/tool-profiling-listener.test.ts +268 -0
- package/src/__tests__/tool-result-truncation.test.ts +217 -0
- package/src/__tests__/tool-trace-listener.test.ts +226 -0
- package/src/__tests__/top-level-renderer.test.ts +121 -0
- package/src/__tests__/top-level-scanner.test.ts +141 -0
- package/src/__tests__/trace-emitter.test.ts +173 -0
- package/src/__tests__/trust-store.test.ts +2030 -0
- package/src/__tests__/turn-commit.test.ts +219 -0
- package/src/__tests__/url-safety.test.ts +418 -0
- package/src/__tests__/weather-skill-regression.test.ts +225 -0
- package/src/__tests__/web-fetch.test.ts +869 -0
- package/src/__tests__/web-search.test.ts +584 -0
- package/src/__tests__/workspace-git-service.test.ts +750 -0
- package/src/__tests__/workspace-heartbeat-service.test.ts +347 -0
- package/src/__tests__/workspace-lifecycle.test.ts +292 -0
- package/src/agent/attachments.ts +35 -0
- package/src/agent/loop.ts +500 -0
- package/src/agent/message-types.ts +17 -0
- package/src/autonomy/autonomy-resolver.ts +60 -0
- package/src/autonomy/autonomy-store.ts +122 -0
- package/src/autonomy/disposition-mapper.ts +31 -0
- package/src/autonomy/index.ts +11 -0
- package/src/autonomy/types.ts +39 -0
- package/src/bundler/app-bundler.ts +274 -0
- package/src/bundler/bundle-scanner.ts +535 -0
- package/src/bundler/bundle-signer.ts +124 -0
- package/src/bundler/manifest.ts +21 -0
- package/src/bundler/signature-verifier.ts +184 -0
- package/src/cli/autonomy.ts +188 -0
- package/src/cli/contacts.ts +149 -0
- package/src/cli/doordash.ts +824 -0
- package/src/cli/email-guardrails.ts +200 -0
- package/src/cli/email.ts +405 -0
- package/src/cli/main-screen.tsx +155 -0
- package/src/cli.ts +935 -0
- package/src/config/bundled-skills/.gitkeep +0 -0
- package/src/config/bundled-skills/agentmail/SKILL.md +128 -0
- package/src/config/bundled-skills/agentmail/icon.svg +21 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +1348 -0
- package/src/config/bundled-skills/app-builder/TOOLS.json +279 -0
- package/src/config/bundled-skills/app-builder/icon.svg +9 -0
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +15 -0
- package/src/config/bundled-skills/app-builder/tools/app-delete.ts +10 -0
- package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +11 -0
- package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +10 -0
- package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +18 -0
- package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +11 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +10 -0
- package/src/config/bundled-skills/app-builder/tools/app-query.ts +10 -0
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +20 -0
- package/src/config/bundled-skills/browser/SKILL.md +28 -0
- package/src/config/bundled-skills/browser/TOOLS.json +234 -0
- package/src/config/bundled-skills/browser/tools/browser-click.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-close.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-type.ts +9 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +9 -0
- package/src/config/bundled-skills/claude-code/SKILL.md +50 -0
- package/src/config/bundled-skills/claude-code/TOOLS.json +40 -0
- package/src/config/bundled-skills/claude-code/tools/claude-code.ts +9 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +17 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +326 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +9 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +9 -0
- package/src/config/bundled-skills/google-calendar/SKILL.md +51 -0
- package/src/config/bundled-skills/google-calendar/TOOLS.json +108 -0
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +165 -0
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +21 -0
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +42 -0
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +13 -0
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +30 -0
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +41 -0
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +18 -0
- package/src/config/bundled-skills/google-calendar/types.ts +97 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +32 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +42 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +137 -0
- package/src/config/bundled-skills/messaging/SKILL.md +126 -0
- package/src/config/bundled-skills/messaging/TOOLS.json +357 -0
- package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +23 -0
- package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +23 -0
- package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +25 -0
- package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +26 -0
- package/src/config/bundled-skills/messaging/tools/gmail-label.ts +25 -0
- package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +23 -0
- package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +84 -0
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +18 -0
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +124 -0
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +16 -0
- package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +49 -0
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +21 -0
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +25 -0
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +28 -0
- package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +29 -0
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +22 -0
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +27 -0
- package/src/config/bundled-skills/messaging/tools/shared.ts +71 -0
- package/src/config/bundled-skills/messaging/tools/slack-add-reaction.ts +25 -0
- package/src/config/bundled-skills/messaging/tools/slack-leave-channel.ts +23 -0
- package/src/config/bundled-skills/self-upgrade/SKILL.md +74 -0
- package/src/config/bundled-skills/start-the-day/SKILL.md +70 -0
- package/src/config/bundled-skills/start-the-day/icon.svg +13 -0
- package/src/config/bundled-skills/weather/SKILL.md +37 -0
- package/src/config/bundled-skills/weather/TOOLS.json +32 -0
- package/src/config/bundled-skills/weather/icon.svg +24 -0
- package/src/config/bundled-skills/weather/tools/get-weather.ts +9 -0
- package/src/config/computer-use-prompt.ts +97 -0
- package/src/config/defaults.ts +186 -0
- package/src/config/loader.ts +336 -0
- package/src/config/schema.ts +1004 -0
- package/src/config/skill-state.ts +95 -0
- package/src/config/skills.ts +972 -0
- package/src/config/system-prompt.ts +927 -0
- package/src/config/templates/BOOTSTRAP.md +70 -0
- package/src/config/templates/IDENTITY.md +18 -0
- package/src/config/templates/LOOKS.md +25 -0
- package/src/config/templates/SOUL.md +37 -0
- package/src/config/templates/USER.md +19 -0
- package/src/config/types.ts +32 -0
- package/src/config/vellum-skills/deploy-fullstack-vercel/SKILL.md +179 -0
- package/src/config/vellum-skills/document-writer/SKILL.md +195 -0
- package/src/config/vellum-skills/google-oauth-setup/SKILL.md +194 -0
- package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +147 -0
- package/src/config/vellum-skills/telegram-setup/SKILL.md +105 -0
- package/src/contacts/contact-store.ts +410 -0
- package/src/contacts/index.ts +11 -0
- package/src/contacts/types.ts +28 -0
- package/src/context/token-estimator.ts +108 -0
- package/src/context/tool-result-truncation.ts +128 -0
- package/src/context/window-manager.ts +531 -0
- package/src/daemon/assistant-attachments.ts +679 -0
- package/src/daemon/classifier.ts +108 -0
- package/src/daemon/computer-use-session.ts +900 -0
- package/src/daemon/connection-policy.ts +41 -0
- package/src/daemon/handlers/apps.ts +446 -0
- package/src/daemon/handlers/computer-use.ts +181 -0
- package/src/daemon/handlers/config.ts +434 -0
- package/src/daemon/handlers/diagnostics.ts +334 -0
- package/src/daemon/handlers/documents.ts +184 -0
- package/src/daemon/handlers/home-base.ts +73 -0
- package/src/daemon/handlers/index.ts +355 -0
- package/src/daemon/handlers/misc.ts +323 -0
- package/src/daemon/handlers/open-bundle-handler.ts +80 -0
- package/src/daemon/handlers/publish.ts +182 -0
- package/src/daemon/handlers/sessions.ts +486 -0
- package/src/daemon/handlers/shared.ts +533 -0
- package/src/daemon/handlers/skills.ts +487 -0
- package/src/daemon/handlers/subagents.ts +122 -0
- package/src/daemon/handlers/work-items.ts +176 -0
- package/src/daemon/handlers.ts +17 -0
- package/src/daemon/history-repair.ts +214 -0
- package/src/daemon/ipc-blob-store.ts +231 -0
- package/src/daemon/ipc-contract-inventory.json +407 -0
- package/src/daemon/ipc-contract-inventory.ts +126 -0
- package/src/daemon/ipc-contract.ts +2102 -0
- package/src/daemon/ipc-protocol.ts +70 -0
- package/src/daemon/ipc-validate.ts +171 -0
- package/src/daemon/lifecycle.ts +503 -0
- package/src/daemon/main.ts +15 -0
- package/src/daemon/media-visibility-policy.ts +57 -0
- package/src/daemon/ride-shotgun-handler.ts +244 -0
- package/src/daemon/server.ts +1085 -0
- package/src/daemon/session-attachments.ts +173 -0
- package/src/daemon/session-conflict-gate.ts +219 -0
- package/src/daemon/session-dynamic-profile.ts +63 -0
- package/src/daemon/session-error.ts +269 -0
- package/src/daemon/session-evictor.ts +196 -0
- package/src/daemon/session-history.ts +437 -0
- package/src/daemon/session-memory.ts +212 -0
- package/src/daemon/session-process.ts +264 -0
- package/src/daemon/session-queue-manager.ts +81 -0
- package/src/daemon/session-runtime-assembly.ts +395 -0
- package/src/daemon/session-skill-tools.ts +237 -0
- package/src/daemon/session-slash.ts +302 -0
- package/src/daemon/session-surfaces.ts +624 -0
- package/src/daemon/session-tool-setup.ts +286 -0
- package/src/daemon/session-usage.ts +74 -0
- package/src/daemon/session-workspace.ts +19 -0
- package/src/daemon/session.ts +1651 -0
- package/src/daemon/trace-emitter.ts +82 -0
- package/src/daemon/watch-handler.ts +274 -0
- package/src/doordash/client.ts +905 -0
- package/src/doordash/queries.ts +1312 -0
- package/src/doordash/query-extractor.ts +93 -0
- package/src/doordash/session.ts +82 -0
- package/src/email/provider.ts +117 -0
- package/src/email/providers/agentmail.ts +317 -0
- package/src/email/providers/index.ts +58 -0
- package/src/email/service.ts +303 -0
- package/src/email/types.ts +126 -0
- package/src/events/bus.ts +157 -0
- package/src/events/domain-events.ts +83 -0
- package/src/events/index.ts +18 -0
- package/src/events/tool-audit-listener.ts +80 -0
- package/src/events/tool-domain-event-publisher.ts +111 -0
- package/src/events/tool-metrics-listener.ts +159 -0
- package/src/events/tool-notification-listener.ts +17 -0
- package/src/events/tool-profiling-listener.ts +158 -0
- package/src/events/tool-trace-listener.ts +75 -0
- package/src/export/formatter.ts +96 -0
- package/src/followups/followup-store.ts +166 -0
- package/src/followups/index.ts +10 -0
- package/src/followups/types.ts +23 -0
- package/src/gallery/default-gallery.ts +795 -0
- package/src/gallery/gallery-manifest.ts +24 -0
- package/src/home-base/app-link-store.ts +82 -0
- package/src/home-base/bootstrap.ts +66 -0
- package/src/home-base/prebuilt/index.html +662 -0
- package/src/home-base/prebuilt/seed-metadata.json +21 -0
- package/src/home-base/prebuilt/seed.ts +101 -0
- package/src/home-base/prebuilt-home-base-updater.ts +30 -0
- package/src/hooks/cli.ts +163 -0
- package/src/hooks/config.ts +88 -0
- package/src/hooks/discovery.ts +110 -0
- package/src/hooks/manager.ts +128 -0
- package/src/hooks/runner.ts +123 -0
- package/src/hooks/templates.ts +52 -0
- package/src/hooks/types.ts +72 -0
- package/src/index.ts +1194 -0
- package/src/instrument.ts +60 -0
- package/src/logfire.ts +99 -0
- package/src/media/gemini-image-service.ts +136 -0
- package/src/memory/account-store.ts +108 -0
- package/src/memory/admin.ts +211 -0
- package/src/memory/app-store.ts +556 -0
- package/src/memory/attachments-store.ts +453 -0
- package/src/memory/channel-delivery-store.ts +368 -0
- package/src/memory/checkpoints.ts +52 -0
- package/src/memory/clarification-resolver.ts +297 -0
- package/src/memory/conflict-store.ts +342 -0
- package/src/memory/contradiction-checker.ts +329 -0
- package/src/memory/conversation-key-store.ts +127 -0
- package/src/memory/conversation-store.ts +469 -0
- package/src/memory/db.ts +1105 -0
- package/src/memory/embedding-backend.ts +229 -0
- package/src/memory/embedding-gemini.ts +52 -0
- package/src/memory/embedding-local.ts +75 -0
- package/src/memory/embedding-ollama.ts +55 -0
- package/src/memory/embedding-openai.ts +25 -0
- package/src/memory/entity-extractor.ts +471 -0
- package/src/memory/fingerprint.ts +20 -0
- package/src/memory/indexer.ts +156 -0
- package/src/memory/items-extractor.ts +460 -0
- package/src/memory/job-handlers/backfill.ts +139 -0
- package/src/memory/job-handlers/cleanup.ts +58 -0
- package/src/memory/job-handlers/conflict.ts +99 -0
- package/src/memory/job-handlers/embedding.ts +61 -0
- package/src/memory/job-handlers/extraction.ts +123 -0
- package/src/memory/job-handlers/index-maintenance.ts +54 -0
- package/src/memory/job-handlers/summarization.ts +286 -0
- package/src/memory/job-utils.ts +170 -0
- package/src/memory/jobs-store.ts +400 -0
- package/src/memory/jobs-worker.ts +274 -0
- package/src/memory/llm-request-log-store.ts +45 -0
- package/src/memory/llm-usage-store.ts +62 -0
- package/src/memory/message-content.ts +54 -0
- package/src/memory/profile-compiler.ts +160 -0
- package/src/memory/published-pages-store.ts +137 -0
- package/src/memory/qdrant-client.ts +366 -0
- package/src/memory/qdrant-manager.ts +242 -0
- package/src/memory/query-builder.ts +45 -0
- package/src/memory/retrieval-budget.ts +30 -0
- package/src/memory/retriever.ts +653 -0
- package/src/memory/runs-store.ts +211 -0
- package/src/memory/schema.ts +529 -0
- package/src/memory/search/entity.ts +298 -0
- package/src/memory/search/formatting.ts +207 -0
- package/src/memory/search/lexical.ts +227 -0
- package/src/memory/search/ranking.ts +401 -0
- package/src/memory/search/semantic.ts +121 -0
- package/src/memory/search/types.ts +137 -0
- package/src/memory/segmenter.ts +68 -0
- package/src/memory/shared-app-links-store.ts +138 -0
- package/src/memory/tool-usage-store.ts +62 -0
- package/src/messaging/activity-analyzer.ts +76 -0
- package/src/messaging/draft-store.ts +88 -0
- package/src/messaging/index.ts +3 -0
- package/src/messaging/provider-types.ts +80 -0
- package/src/messaging/provider.ts +43 -0
- package/src/messaging/providers/gmail/adapter.ts +193 -0
- package/src/messaging/providers/gmail/client.ts +204 -0
- package/src/messaging/providers/gmail/types.ts +90 -0
- package/src/messaging/providers/slack/adapter.ts +202 -0
- package/src/messaging/providers/slack/client.ts +198 -0
- package/src/messaging/providers/slack/types.ts +119 -0
- package/src/messaging/registry.ts +34 -0
- package/src/messaging/style-analyzer.ts +158 -0
- package/src/messaging/thread-summarizer.ts +310 -0
- package/src/messaging/triage-engine.ts +321 -0
- package/src/messaging/types.ts +55 -0
- package/src/permissions/checker.ts +636 -0
- package/src/permissions/defaults.ts +243 -0
- package/src/permissions/prompter.ts +102 -0
- package/src/permissions/secret-prompter.ts +114 -0
- package/src/permissions/trust-store.ts +584 -0
- package/src/permissions/types.ts +62 -0
- package/src/playbooks/index.ts +2 -0
- package/src/playbooks/playbook-compiler.ts +90 -0
- package/src/playbooks/types.ts +55 -0
- package/src/providers/anthropic/client.ts +751 -0
- package/src/providers/failover.ts +129 -0
- package/src/providers/fireworks/client.ts +20 -0
- package/src/providers/gemini/client.ts +285 -0
- package/src/providers/ollama/client.ts +30 -0
- package/src/providers/openai/client.ts +337 -0
- package/src/providers/ratelimit.ts +93 -0
- package/src/providers/registry.ts +138 -0
- package/src/providers/retry.ts +106 -0
- package/src/providers/stream-timeout.ts +38 -0
- package/src/providers/types.ts +109 -0
- package/src/runtime/assistant-event-hub.ts +120 -0
- package/src/runtime/assistant-event.ts +82 -0
- package/src/runtime/http-server.ts +478 -0
- package/src/runtime/http-types.ts +68 -0
- package/src/runtime/routes/app-routes.ts +174 -0
- package/src/runtime/routes/attachment-routes.ts +134 -0
- package/src/runtime/routes/channel-routes.ts +342 -0
- package/src/runtime/routes/conversation-routes.ts +349 -0
- package/src/runtime/routes/run-routes.ts +223 -0
- package/src/runtime/routes/secret-routes.ts +76 -0
- package/src/runtime/run-orchestrator.ts +206 -0
- package/src/schedule/schedule-store.ts +452 -0
- package/src/schedule/scheduler.ts +168 -0
- package/src/security/encrypted-store.ts +238 -0
- package/src/security/keychain.ts +252 -0
- package/src/security/oauth2.ts +241 -0
- package/src/security/redaction.ts +89 -0
- package/src/security/secret-allowlist.ts +118 -0
- package/src/security/secret-ingress.ts +57 -0
- package/src/security/secret-scanner.ts +543 -0
- package/src/security/secure-keys.ts +180 -0
- package/src/security/token-manager.ts +141 -0
- package/src/services/published-app-updater.ts +69 -0
- package/src/services/vercel-deploy.ts +73 -0
- package/src/skills/active-skill-tools.ts +81 -0
- package/src/skills/clawhub.ts +414 -0
- package/src/skills/include-graph.ts +146 -0
- package/src/skills/managed-store.ts +233 -0
- package/src/skills/path-classifier.ts +128 -0
- package/src/skills/slash-commands.ts +174 -0
- package/src/skills/tool-manifest.ts +165 -0
- package/src/skills/version-hash.ts +110 -0
- package/src/slack/slack-webhook.ts +61 -0
- package/src/subagent/index.ts +19 -0
- package/src/subagent/manager.ts +477 -0
- package/src/subagent/types.ts +69 -0
- package/src/swarm/backend-claude-code.ts +90 -0
- package/src/swarm/index.ts +44 -0
- package/src/swarm/limits.ts +37 -0
- package/src/swarm/orchestrator.ts +279 -0
- package/src/swarm/plan-validator.ts +151 -0
- package/src/swarm/router-planner.ts +100 -0
- package/src/swarm/router-prompts.ts +36 -0
- package/src/swarm/synthesizer.ts +62 -0
- package/src/swarm/types.ts +62 -0
- package/src/swarm/worker-backend.ts +121 -0
- package/src/swarm/worker-prompts.ts +78 -0
- package/src/swarm/worker-runner.ts +164 -0
- package/src/tasks/SPEC.md +133 -0
- package/src/tasks/candidate-store.ts +86 -0
- package/src/tasks/ephemeral-permissions.ts +41 -0
- package/src/tasks/task-compiler.ts +198 -0
- package/src/tasks/task-runner.ts +85 -0
- package/src/tasks/task-scheduler.ts +20 -0
- package/src/tasks/task-store.ts +127 -0
- package/src/tools/apps/definitions.ts +59 -0
- package/src/tools/apps/executors.ts +313 -0
- package/src/tools/apps/open-proxy.ts +43 -0
- package/src/tools/apps/registry.ts +16 -0
- package/src/tools/assets/materialize.ts +218 -0
- package/src/tools/assets/search.ts +396 -0
- package/src/tools/browser/__tests__/auth-cache.test.ts +219 -0
- package/src/tools/browser/__tests__/auth-detector.test.ts +362 -0
- package/src/tools/browser/__tests__/jit-auth.test.ts +189 -0
- package/src/tools/browser/auth-cache.ts +149 -0
- package/src/tools/browser/auth-detector.ts +347 -0
- package/src/tools/browser/browser-execution.ts +979 -0
- package/src/tools/browser/browser-handoff.ts +79 -0
- package/src/tools/browser/browser-manager.ts +715 -0
- package/src/tools/browser/browser-screencast.ts +217 -0
- package/src/tools/browser/headless-browser.ts +450 -0
- package/src/tools/browser/jit-auth.ts +51 -0
- package/src/tools/browser/network-recorder.ts +348 -0
- package/src/tools/browser/network-recording-types.ts +49 -0
- package/src/tools/browser/recording-store.ts +49 -0
- package/src/tools/browser/runtime-check.ts +43 -0
- package/src/tools/claude-code/claude-code.ts +232 -0
- package/src/tools/computer-use/definitions.ts +443 -0
- package/src/tools/computer-use/registry.ts +22 -0
- package/src/tools/computer-use/request-computer-control.ts +53 -0
- package/src/tools/computer-use/skill-proxy-bridge.ts +28 -0
- package/src/tools/contacts/contact-merge.ts +87 -0
- package/src/tools/contacts/contact-search.ts +102 -0
- package/src/tools/contacts/contact-upsert.ts +137 -0
- package/src/tools/contacts/index.ts +4 -0
- package/src/tools/credentials/account-registry.ts +127 -0
- package/src/tools/credentials/broker-types.ts +107 -0
- package/src/tools/credentials/broker.ts +372 -0
- package/src/tools/credentials/domain-policy.ts +51 -0
- package/src/tools/credentials/host-pattern-match.ts +60 -0
- package/src/tools/credentials/metadata-store.ts +335 -0
- package/src/tools/credentials/policy-types.ts +52 -0
- package/src/tools/credentials/policy-validate.ts +80 -0
- package/src/tools/credentials/resolve.ts +122 -0
- package/src/tools/credentials/selection.ts +159 -0
- package/src/tools/credentials/tool-policy.ts +25 -0
- package/src/tools/credentials/vault.ts +641 -0
- package/src/tools/document/document-tool.ts +165 -0
- package/src/tools/document/editor-template.ts +237 -0
- package/src/tools/document/index.ts +5 -0
- package/src/tools/executor.ts +825 -0
- package/src/tools/filesystem/edit.ts +127 -0
- package/src/tools/filesystem/fuzzy-match.ts +202 -0
- package/src/tools/filesystem/read.ts +71 -0
- package/src/tools/filesystem/view-image.ts +199 -0
- package/src/tools/filesystem/write.ts +79 -0
- package/src/tools/followups/followup_create.ts +118 -0
- package/src/tools/followups/followup_list.ts +100 -0
- package/src/tools/followups/followup_resolve.ts +91 -0
- package/src/tools/followups/index.ts +3 -0
- package/src/tools/host-filesystem/edit.ts +125 -0
- package/src/tools/host-filesystem/read.ts +80 -0
- package/src/tools/host-filesystem/write.ts +76 -0
- package/src/tools/host-terminal/cli-discover.ts +179 -0
- package/src/tools/host-terminal/host-shell.ts +181 -0
- package/src/tools/memory/definitions.ts +69 -0
- package/src/tools/memory/handlers.ts +245 -0
- package/src/tools/memory/register.ts +66 -0
- package/src/tools/network/domain-normalize.ts +85 -0
- package/src/tools/network/script-proxy/certs.ts +237 -0
- package/src/tools/network/script-proxy/connect-tunnel.ts +82 -0
- package/src/tools/network/script-proxy/http-forwarder.ts +151 -0
- package/src/tools/network/script-proxy/index.ts +28 -0
- package/src/tools/network/script-proxy/logging.ts +196 -0
- package/src/tools/network/script-proxy/mitm-handler.ts +269 -0
- package/src/tools/network/script-proxy/policy.ts +152 -0
- package/src/tools/network/script-proxy/router.ts +60 -0
- package/src/tools/network/script-proxy/server.ts +136 -0
- package/src/tools/network/script-proxy/session-manager.ts +534 -0
- package/src/tools/network/script-proxy/types.ts +125 -0
- package/src/tools/network/url-safety.ts +227 -0
- package/src/tools/network/web-fetch.ts +701 -0
- package/src/tools/network/web-search.ts +319 -0
- package/src/tools/playbooks/index.ts +5 -0
- package/src/tools/playbooks/playbook-create.ts +140 -0
- package/src/tools/playbooks/playbook-delete.ts +76 -0
- package/src/tools/playbooks/playbook-list.ts +101 -0
- package/src/tools/playbooks/playbook-update.ts +159 -0
- package/src/tools/registry.ts +297 -0
- package/src/tools/reminder/reminder-store.ts +148 -0
- package/src/tools/reminder/reminder.ts +153 -0
- package/src/tools/schedule/create.ts +86 -0
- package/src/tools/schedule/delete.ts +54 -0
- package/src/tools/schedule/list.ts +88 -0
- package/src/tools/schedule/update.ts +97 -0
- package/src/tools/shared/filesystem/edit-engine.ts +56 -0
- package/src/tools/shared/filesystem/errors.ts +85 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +215 -0
- package/src/tools/shared/filesystem/format-diff.ts +35 -0
- package/src/tools/shared/filesystem/path-policy.ts +125 -0
- package/src/tools/shared/filesystem/size-guard.ts +41 -0
- package/src/tools/shared/filesystem/types.ts +80 -0
- package/src/tools/shared/shell-output.ts +52 -0
- package/src/tools/skills/delete-managed.ts +60 -0
- package/src/tools/skills/load.ts +139 -0
- package/src/tools/skills/sandbox-runner.ts +279 -0
- package/src/tools/skills/scaffold-managed.ts +150 -0
- package/src/tools/skills/script-contract.ts +6 -0
- package/src/tools/skills/skill-script-runner.ts +86 -0
- package/src/tools/skills/skill-tool-factory.ts +64 -0
- package/src/tools/skills/vellum-catalog.ts +217 -0
- package/src/tools/subagent/abort.ts +62 -0
- package/src/tools/subagent/index.ts +5 -0
- package/src/tools/subagent/message.ts +72 -0
- package/src/tools/subagent/read.ts +98 -0
- package/src/tools/subagent/spawn.ts +85 -0
- package/src/tools/subagent/status.ts +74 -0
- package/src/tools/swarm/delegate.ts +182 -0
- package/src/tools/system/request-permission.ts +98 -0
- package/src/tools/tasks/index.ts +25 -0
- package/src/tools/tasks/task-delete.ts +69 -0
- package/src/tools/tasks/task-list.ts +65 -0
- package/src/tools/tasks/task-run.ts +125 -0
- package/src/tools/tasks/task-save.ts +79 -0
- package/src/tools/tasks/work-item-enqueue.ts +176 -0
- package/src/tools/tasks/work-item-list.ts +86 -0
- package/src/tools/terminal/backends/docker.ts +372 -0
- package/src/tools/terminal/backends/native.ts +188 -0
- package/src/tools/terminal/backends/types.ts +26 -0
- package/src/tools/terminal/evaluate-typescript.ts +275 -0
- package/src/tools/terminal/parser.ts +393 -0
- package/src/tools/terminal/safe-env.ts +37 -0
- package/src/tools/terminal/sandbox-diagnostics.ts +149 -0
- package/src/tools/terminal/sandbox.ts +44 -0
- package/src/tools/terminal/shell.ts +257 -0
- package/src/tools/tool-manifest.ts +250 -0
- package/src/tools/types.ts +177 -0
- package/src/tools/ui-surface/definitions.ts +232 -0
- package/src/tools/ui-surface/registry.ts +14 -0
- package/src/tools/watch/screen-watch.ts +128 -0
- package/src/tools/watch/watch-state.ts +119 -0
- package/src/tools/watcher/create.ts +110 -0
- package/src/tools/watcher/delete.ts +53 -0
- package/src/tools/watcher/digest.ts +84 -0
- package/src/tools/watcher/list.ts +90 -0
- package/src/tools/watcher/update.ts +102 -0
- package/src/tools/weather/service.ts +551 -0
- package/src/usage/actors.ts +24 -0
- package/src/usage/types.ts +38 -0
- package/src/util/clipboard.ts +33 -0
- package/src/util/content-id.ts +16 -0
- package/src/util/diff.ts +181 -0
- package/src/util/errors.ts +129 -0
- package/src/util/logger.ts +243 -0
- package/src/util/platform.ts +607 -0
- package/src/util/pricing.ts +150 -0
- package/src/util/spinner.ts +51 -0
- package/src/util/time.ts +16 -0
- package/src/util/xml.ts +4 -0
- package/src/version.ts +3 -0
- package/src/watcher/constants.ts +11 -0
- package/src/watcher/engine.ts +199 -0
- package/src/watcher/provider-registry.ts +15 -0
- package/src/watcher/provider-types.ts +48 -0
- package/src/watcher/providers/gmail.ts +198 -0
- package/src/watcher/providers/google-calendar.ts +228 -0
- package/src/watcher/providers/slack.ts +128 -0
- package/src/watcher/watcher-store.ts +418 -0
- package/src/work-items/work-item-store.ts +91 -0
- package/src/workspace/git-service.ts +620 -0
- package/src/workspace/heartbeat-service.ts +288 -0
- package/src/workspace/top-level-renderer.ts +19 -0
- package/src/workspace/top-level-scanner.ts +41 -0
- package/src/workspace/turn-commit.ts +122 -0
- package/tsconfig.json +21 -0
- package/LICENSE +0 -674
- 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
|
+
}
|