vellum 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2
- package/bun.lock +5 -2
- package/package.json +4 -2
- package/scripts/capture-x-graphql.ts +562 -0
- package/scripts/ipc/check-swift-decoder-drift.ts +2 -1
- package/scripts/test.sh +5 -0
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +161 -34
- package/src/__tests__/account-registry.test.ts +2 -1
- package/src/__tests__/agent-heartbeat-service.test.ts +250 -0
- package/src/__tests__/app-bundler.test.ts +12 -33
- package/src/__tests__/asset-materialize-tool.test.ts +16 -15
- package/src/__tests__/asset-search-tool.test.ts +23 -22
- package/src/__tests__/attachments-store.test.ts +56 -127
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +5 -4
- package/src/__tests__/browser-skill-endstate.test.ts +5 -8
- package/src/__tests__/call-bridge.test.ts +385 -0
- package/src/__tests__/call-constants.test.ts +40 -0
- package/src/__tests__/call-orchestrator.test.ts +454 -0
- package/src/__tests__/call-recovery.test.ts +518 -0
- package/src/__tests__/call-routes-http.test.ts +459 -0
- package/src/__tests__/call-state-machine.test.ts +143 -0
- package/src/__tests__/call-state.test.ts +133 -0
- package/src/__tests__/call-store.test.ts +691 -0
- package/src/__tests__/cli-discover.test.ts +1 -1
- package/src/__tests__/commit-message-enrichment-service.test.ts +550 -0
- package/src/__tests__/compaction.benchmark.test.ts +176 -0
- package/src/__tests__/computer-use-tools.test.ts +250 -0
- package/src/__tests__/config-schema.test.ts +348 -3
- package/src/__tests__/conflict-store.test.ts +2 -1
- package/src/__tests__/contacts-tools.test.ts +331 -0
- package/src/__tests__/conversation-store.test.ts +30 -32
- package/src/__tests__/credential-security-invariants.test.ts +4 -0
- package/src/__tests__/date-context.test.ts +373 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +129 -0
- package/src/__tests__/doordash-session.test.ts +9 -0
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +3 -3
- package/src/__tests__/followup-tools.test.ts +303 -0
- package/src/__tests__/handlers-twitter-config.test.ts +718 -0
- package/src/__tests__/intent-routing.test.ts +64 -57
- package/src/__tests__/ipc-roundtrip.benchmark.test.ts +237 -0
- package/src/__tests__/ipc-snapshot.test.ts +96 -28
- package/src/__tests__/llm-usage-store.test.ts +3 -8
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -7
- package/src/__tests__/memory-retrieval.benchmark.test.ts +430 -0
- package/src/__tests__/parallel-tool.benchmark.test.ts +294 -0
- package/src/__tests__/playbook-tools.test.ts +342 -0
- package/src/__tests__/profile-compiler.test.ts +2 -1
- package/src/__tests__/provider-streaming.benchmark.test.ts +773 -0
- package/src/__tests__/recurrence-engine-rruleset.test.ts +78 -0
- package/src/__tests__/recurrence-engine.test.ts +69 -0
- package/src/__tests__/recurrence-types.test.ts +71 -0
- package/src/__tests__/registry.test.ts +17 -10
- package/src/__tests__/relay-server.test.ts +633 -0
- package/src/__tests__/reminder-store.test.ts +6 -3
- package/src/__tests__/reminder.test.ts +43 -77
- package/src/__tests__/run-orchestrator-assistant-events.test.ts +222 -0
- package/src/__tests__/run-orchestrator.test.ts +7 -7
- package/src/__tests__/runtime-attachment-metadata.test.ts +19 -20
- package/src/__tests__/runtime-runs-http.test.ts +5 -23
- package/src/__tests__/runtime-runs.test.ts +11 -11
- package/src/__tests__/schedule-store.test.ts +482 -0
- package/src/__tests__/schedule-tools.test.ts +700 -0
- package/src/__tests__/scheduler-recurrence.test.ts +329 -0
- package/src/__tests__/server-history-render.test.ts +14 -13
- package/src/__tests__/session-error.test.ts +28 -0
- package/src/__tests__/session-init.benchmark.test.ts +462 -0
- package/src/__tests__/session-queue.test.ts +89 -16
- package/src/__tests__/session-runtime-assembly.test.ts +161 -0
- package/src/__tests__/session-surfaces-task-progress.test.ts +104 -0
- package/src/__tests__/signup-e2e.test.ts +2 -1
- package/src/__tests__/skill-projection.benchmark.test.ts +328 -0
- package/src/__tests__/skill-script-runner.test.ts +159 -0
- package/src/__tests__/speaker-identification.test.ts +52 -0
- package/src/__tests__/subagent-manager-notify.test.ts +42 -10
- package/src/__tests__/subagent-tools.test.ts +141 -41
- package/src/__tests__/task-compiler.test.ts +2 -1
- package/src/__tests__/task-runner.test.ts +2 -1
- package/src/__tests__/task-scheduler.test.ts +2 -1
- package/src/__tests__/task-tools.test.ts +49 -56
- package/src/__tests__/tool-audit-listener.test.ts +1 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +2 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +500 -0
- package/src/__tests__/tool-executor.test.ts +13 -17
- package/src/__tests__/turn-commit.test.ts +273 -2
- package/src/__tests__/twilio-provider.test.ts +143 -0
- package/src/__tests__/twilio-routes.test.ts +789 -0
- package/src/__tests__/twitter-auth-handler.test.ts +581 -0
- package/src/__tests__/view-image-tool.test.ts +217 -0
- package/src/__tests__/workspace-git-service.test.ts +403 -0
- package/src/__tests__/workspace-heartbeat-service.test.ts +141 -2
- package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
- package/src/bundler/app-bundler.ts +35 -14
- package/src/calls/call-bridge.ts +95 -0
- package/src/calls/call-constants.ts +48 -0
- package/src/calls/call-domain.ts +276 -0
- package/src/calls/call-orchestrator.ts +390 -0
- package/src/calls/call-recovery.ts +207 -0
- package/src/calls/call-state-machine.ts +68 -0
- package/src/calls/call-state.ts +64 -0
- package/src/calls/call-store.ts +416 -0
- package/src/calls/relay-server.ts +335 -0
- package/src/calls/speaker-identification.ts +213 -0
- package/src/calls/twilio-config.ts +34 -0
- package/src/calls/twilio-provider.ts +173 -0
- package/src/calls/twilio-routes.ts +250 -0
- package/src/calls/types.ts +37 -0
- package/src/calls/voice-provider.ts +14 -0
- package/src/cli/config-commands.ts +334 -0
- package/src/cli/core-commands.ts +776 -0
- package/src/cli/doordash.ts +256 -25
- package/src/cli/ipc-client.ts +82 -0
- package/src/cli/map.ts +246 -0
- package/src/cli/twitter.ts +575 -0
- package/src/cli.ts +7 -5
- package/src/commands/__tests__/cc-command-registry.test.ts +319 -0
- package/src/commands/cc-command-registry.ts +209 -0
- package/src/config/bundled-skills/contacts/SKILL.md +39 -0
- package/src/config/bundled-skills/contacts/TOOLS.json +122 -0
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +9 -0
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +9 -0
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +9 -0
- package/src/config/bundled-skills/document/SKILL.md +18 -0
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-create.ts +9 -0
- package/src/config/bundled-skills/document/tools/document-update.ts +9 -0
- package/src/config/bundled-skills/doordash/SKILL.md +163 -0
- package/src/config/bundled-skills/followups/SKILL.md +32 -0
- package/src/config/bundled-skills/followups/TOOLS.json +100 -0
- package/src/config/bundled-skills/followups/tools/followup-create.ts +9 -0
- package/src/config/bundled-skills/followups/tools/followup-list.ts +9 -0
- package/src/config/bundled-skills/followups/tools/followup-resolve.ts +9 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -24
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -1
- package/src/config/bundled-skills/playbooks/SKILL.md +31 -0
- package/src/config/bundled-skills/playbooks/TOOLS.json +126 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +9 -0
- package/src/config/bundled-skills/reminder/SKILL.md +20 -0
- package/src/config/bundled-skills/reminder/TOOLS.json +67 -0
- package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +9 -0
- package/src/config/bundled-skills/reminder/tools/reminder-create.ts +9 -0
- package/src/config/bundled-skills/reminder/tools/reminder-list.ts +9 -0
- package/src/config/bundled-skills/schedule/SKILL.md +74 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +135 -0
- package/src/config/bundled-skills/schedule/tools/schedule-create.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-list.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-update.ts +9 -0
- package/src/config/bundled-skills/subagent/SKILL.md +25 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +107 -0
- package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-message.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-read.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-status.ts +9 -0
- package/src/config/bundled-skills/tasks/SKILL.md +28 -0
- package/src/config/bundled-skills/tasks/TOOLS.json +256 -0
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-run.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-save.ts +9 -0
- package/src/config/bundled-skills/twitter/SKILL.md +134 -0
- package/src/config/bundled-skills/watcher/SKILL.md +27 -0
- package/src/config/bundled-skills/watcher/TOOLS.json +147 -0
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +9 -0
- package/src/config/defaults.ts +44 -0
- package/src/config/loader.ts +4 -1
- package/src/config/schema.ts +218 -1
- package/src/config/system-prompt.ts +100 -6
- package/src/config/templates/IDENTITY.md +7 -0
- package/src/config/types.ts +5 -0
- package/src/contacts/contact-store.ts +4 -4
- package/src/daemon/assistant-attachments.ts +10 -0
- package/src/daemon/classifier.ts +3 -1
- package/src/daemon/computer-use-session.ts +3 -1
- package/src/daemon/date-context.ts +136 -0
- package/src/daemon/handlers/apps.ts +16 -1
- package/src/daemon/handlers/browser.ts +54 -0
- package/src/daemon/handlers/computer-use.ts +7 -1
- package/src/daemon/handlers/config.ts +192 -4
- package/src/daemon/handlers/diagnostics.ts +5 -1
- package/src/daemon/handlers/documents.ts +18 -29
- package/src/daemon/handlers/home-base.ts +5 -1
- package/src/daemon/handlers/index.ts +40 -271
- package/src/daemon/handlers/misc.ts +9 -1
- package/src/daemon/handlers/publish.ts +6 -1
- package/src/daemon/handlers/sessions.ts +65 -12
- package/src/daemon/handlers/shared.ts +36 -1
- package/src/daemon/handlers/signing.ts +37 -0
- package/src/daemon/handlers/skills.ts +20 -6
- package/src/daemon/handlers/subagents.ts +8 -3
- package/src/daemon/handlers/twitter-auth.ts +169 -0
- package/src/daemon/handlers/work-items.ts +495 -39
- package/src/daemon/ipc-contract-inventory.json +40 -4
- package/src/daemon/ipc-contract.ts +185 -37
- package/src/daemon/ipc-protocol.ts +7 -2
- package/src/daemon/lifecycle.ts +48 -5
- package/src/daemon/main.ts +10 -4
- package/src/daemon/ride-shotgun-handler.ts +74 -10
- package/src/daemon/server.ts +144 -29
- package/src/daemon/session-agent-loop.ts +887 -0
- package/src/daemon/session-attachments.ts +28 -5
- package/src/daemon/session-error.ts +24 -3
- package/src/daemon/session-lifecycle.ts +147 -0
- package/src/daemon/session-media-retry.ts +147 -0
- package/src/daemon/session-messaging.ts +145 -0
- package/src/daemon/session-notifiers.ts +164 -0
- package/src/daemon/session-process.ts +2 -2
- package/src/daemon/session-queue-manager.ts +1 -0
- package/src/daemon/session-runtime-assembly.ts +52 -0
- package/src/daemon/session-skill-tools.ts +124 -5
- package/src/daemon/session-slash.ts +3 -0
- package/src/daemon/session-surfaces.ts +77 -2
- package/src/daemon/session-tool-setup.ts +222 -2
- package/src/daemon/session-usage.ts +0 -2
- package/src/daemon/session.ts +114 -1365
- package/src/daemon/video-thumbnail.ts +60 -0
- package/src/doordash/client.ts +121 -27
- package/src/doordash/queries.ts +1 -2
- package/src/export/formatter.ts +3 -1
- package/src/followups/followup-store.ts +4 -2
- package/src/followups/types.ts +6 -0
- package/src/hooks/templates.ts +1 -1
- package/src/index.ts +32 -1151
- package/src/media/gemini-image-service.ts +1 -1
- package/src/memory/attachments-store.ts +28 -83
- package/src/memory/channel-delivery-store.ts +7 -21
- package/src/memory/clarification-resolver.ts +6 -5
- package/src/memory/contradiction-checker.ts +3 -2
- package/src/memory/conversation-key-store.ts +10 -29
- package/src/memory/conversation-store.ts +2 -1
- package/src/memory/db.ts +362 -2
- package/src/memory/entity-extractor.ts +6 -3
- package/src/memory/items-extractor.ts +5 -4
- package/src/memory/jobs-store.ts +3 -2
- package/src/memory/llm-usage-store.ts +1 -2
- package/src/memory/runs-store.ts +1 -2
- package/src/memory/schema.ts +65 -2
- package/src/messaging/style-analyzer.ts +3 -2
- package/src/messaging/thread-summarizer.ts +8 -12
- package/src/messaging/triage-engine.ts +4 -2
- package/src/providers/openrouter/client.ts +20 -0
- package/src/providers/registry.ts +8 -0
- package/src/runtime/http-server.ts +277 -25
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/routes/attachment-routes.ts +5 -6
- package/src/runtime/routes/call-routes.ts +140 -0
- package/src/runtime/routes/channel-routes.ts +12 -19
- package/src/runtime/routes/conversation-routes.ts +5 -9
- package/src/runtime/routes/run-routes.ts +4 -8
- package/src/runtime/run-orchestrator.ts +39 -6
- package/src/schedule/recurrence-engine.ts +138 -0
- package/src/schedule/recurrence-types.ts +67 -0
- package/src/schedule/schedule-store.ts +102 -57
- package/src/schedule/scheduler.ts +9 -6
- package/src/security/oauth2.ts +29 -4
- package/src/security/secret-allowlist.ts +46 -0
- package/src/skills/clawhub.ts +1 -1
- package/src/subagent/manager.ts +40 -8
- package/src/swarm/backend-claude-code.ts +64 -9
- package/src/swarm/worker-prompts.ts +2 -1
- package/src/tasks/SPEC.md +34 -28
- package/src/tasks/ephemeral-permissions.ts +16 -7
- package/src/tasks/task-compiler.ts +5 -4
- package/src/tasks/task-runner.ts +10 -5
- package/src/tasks/task-scheduler.ts +1 -1
- package/src/tasks/tool-sanitizer.ts +36 -0
- package/src/tools/assets/search.ts +4 -4
- package/src/tools/browser/api-map.ts +220 -0
- package/src/tools/browser/auto-navigate.ts +270 -0
- package/src/tools/browser/browser-execution.ts +2 -1
- package/src/tools/browser/browser-manager.ts +2 -2
- package/src/tools/browser/network-recorder.ts +5 -4
- package/src/tools/browser/x-auto-navigate.ts +207 -0
- package/src/tools/calls/call-end.ts +67 -0
- package/src/tools/calls/call-start.ts +73 -0
- package/src/tools/calls/call-status.ts +81 -0
- package/src/tools/claude-code/claude-code.ts +77 -11
- package/src/tools/contacts/contact-merge.ts +46 -78
- package/src/tools/contacts/contact-search.ts +35 -79
- package/src/tools/contacts/contact-upsert.ts +35 -108
- package/src/tools/credentials/vault.ts +21 -5
- package/src/tools/document/document-tool.ts +71 -144
- package/src/tools/executor.ts +129 -10
- package/src/tools/followups/followup_create.ts +46 -88
- package/src/tools/followups/followup_list.ts +34 -74
- package/src/tools/followups/followup_resolve.ts +31 -66
- package/src/tools/host-terminal/cli-discover.ts +2 -1
- package/src/tools/host-terminal/host-shell.ts +10 -0
- package/src/tools/memory/handlers.ts +5 -4
- package/src/tools/network/__tests__/web-search.test.ts +427 -0
- package/src/tools/network/script-proxy/__tests__/logging.test.ts +248 -0
- package/src/tools/network/script-proxy/__tests__/policy.test.ts +234 -0
- package/src/tools/network/script-proxy/__tests__/router.test.ts +76 -0
- package/src/tools/network/web-fetch.ts +18 -6
- package/src/tools/playbooks/index.ts +4 -5
- package/src/tools/playbooks/playbook-create.ts +3 -47
- package/src/tools/playbooks/playbook-delete.ts +1 -25
- package/src/tools/playbooks/playbook-list.ts +1 -28
- package/src/tools/playbooks/playbook-update.ts +3 -51
- package/src/tools/registry.ts +2 -4
- package/src/tools/reminder/reminder.ts +5 -78
- package/src/tools/schedule/create.ts +69 -74
- package/src/tools/schedule/delete.ts +21 -47
- package/src/tools/schedule/list.ts +55 -74
- package/src/tools/schedule/update.ts +77 -84
- package/src/tools/subagent/abort.ts +29 -58
- package/src/tools/subagent/message.ts +30 -63
- package/src/tools/subagent/read.ts +53 -84
- package/src/tools/subagent/spawn.ts +43 -82
- package/src/tools/subagent/status.ts +42 -71
- package/src/tools/swarm/delegate.ts +2 -1
- package/src/tools/tasks/index.ts +8 -6
- package/src/tools/tasks/task-delete.ts +69 -56
- package/src/tools/tasks/task-list.ts +31 -52
- package/src/tools/tasks/task-run.ts +74 -102
- package/src/tools/tasks/task-save.ts +33 -65
- package/src/tools/tasks/work-item-enqueue.ts +192 -134
- package/src/tools/tasks/work-item-list.ts +33 -78
- package/src/tools/tasks/work-item-remove.ts +60 -0
- package/src/tools/tasks/work-item-update.ts +114 -0
- package/src/tools/terminal/backends/native.ts +3 -1
- package/src/tools/tool-manifest.ts +20 -74
- package/src/tools/types.ts +6 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tools/watch/screen-watch.ts +3 -1
- package/src/tools/watcher/create.ts +52 -98
- package/src/tools/watcher/delete.ts +20 -46
- package/src/tools/watcher/digest.ts +36 -70
- package/src/tools/watcher/list.ts +49 -79
- package/src/tools/watcher/update.ts +45 -91
- package/src/twitter/client.ts +690 -0
- package/src/twitter/session.ts +91 -0
- package/src/usage/types.ts +0 -1
- package/src/util/truncate.ts +6 -0
- package/src/watcher/providers/slack.ts +2 -1
- package/src/watcher/watcher-store.ts +3 -2
- package/src/work-items/work-item-store.ts +236 -2
- package/src/workspace/commit-message-enrichment-service.ts +284 -0
- package/src/workspace/commit-message-provider.ts +95 -0
- package/src/workspace/git-service.ts +272 -52
- package/src/workspace/heartbeat-service.ts +70 -13
- package/src/workspace/provider-commit-message-generator.ts +242 -0
- package/src/workspace/turn-commit.ts +100 -51
- package/src/tools/contacts/index.ts +0 -4
- package/src/tools/document/index.ts +0 -5
- package/src/tools/followups/index.ts +0 -3
- package/src/tools/subagent/index.ts +0 -5
- /package/src/__tests__/{memory-context-benchmark.test.ts → memory-context-benchmark.benchmark.test.ts} +0 -0
|
@@ -9,6 +9,8 @@ import type { SandboxBackend, SandboxResult } from './types.js';
|
|
|
9
9
|
|
|
10
10
|
const log = getLogger('sandbox');
|
|
11
11
|
|
|
12
|
+
const HASH_DISPLAY_LENGTH = 12;
|
|
13
|
+
|
|
12
14
|
/**
|
|
13
15
|
* macOS sandbox-exec profile that restricts shell commands:
|
|
14
16
|
* - Denies all by default
|
|
@@ -81,7 +83,7 @@ function getProfilePath(workingDir: string): string {
|
|
|
81
83
|
if (!existsSync(dir)) {
|
|
82
84
|
mkdirSync(dir, { recursive: true });
|
|
83
85
|
}
|
|
84
|
-
const hash = createHash('sha256').update(workingDir).digest('hex').slice(0,
|
|
86
|
+
const hash = createHash('sha256').update(workingDir).digest('hex').slice(0, HASH_DISPLAY_LENGTH);
|
|
85
87
|
const path = join(dir, `sandbox-profile-${hash}.sb`);
|
|
86
88
|
|
|
87
89
|
const profile = SANDBOX_PROFILE.replace(/__WORKING_DIR__/g, workingDir);
|
|
@@ -12,54 +12,30 @@ import type { Tool } from './types.js';
|
|
|
12
12
|
import { memorySearchTool, memorySaveTool, memoryUpdateTool } from './memory/register.js';
|
|
13
13
|
import { credentialStoreTool } from './credentials/vault.js';
|
|
14
14
|
import { accountManageTool } from './credentials/account-registry.js';
|
|
15
|
-
import { reminderTool } from './reminder/reminder.js';
|
|
16
15
|
import { screenWatchTool } from './watch/screen-watch.js';
|
|
17
16
|
import { vellumSkillsCatalogTool } from './skills/vellum-catalog.js';
|
|
18
|
-
import { documentCreateTool, documentUpdateTool } from './document/index.js';
|
|
19
17
|
import { cliDiscoverTool } from './host-terminal/cli-discover.js';
|
|
20
|
-
import { followupCreateTool, followupListTool, followupResolveTool } from './followups/index.js';
|
|
21
|
-
import { taskSaveTool, taskRunTool, taskListTool, taskDeleteTool, taskListShowTool, taskListAddTool } from './tasks/index.js';
|
|
22
|
-
import {
|
|
23
|
-
subagentSpawnTool,
|
|
24
|
-
subagentStatusTool,
|
|
25
|
-
subagentAbortTool,
|
|
26
|
-
subagentMessageTool,
|
|
27
|
-
subagentReadTool,
|
|
28
|
-
} from './subagent/index.js';
|
|
29
18
|
|
|
30
19
|
// ── Eager side-effect modules ───────────────────────────────────────
|
|
31
20
|
// Importing these modules triggers a top-level `registerTool()` call.
|
|
32
21
|
|
|
33
|
-
export
|
|
34
|
-
'./filesystem/read.js'
|
|
35
|
-
'./filesystem/write.js'
|
|
36
|
-
'./filesystem/edit.js'
|
|
37
|
-
'./network/web-search.js'
|
|
38
|
-
'./network/web-fetch.js'
|
|
39
|
-
'./skills/load.js'
|
|
40
|
-
'./skills/scaffold-managed.js'
|
|
41
|
-
'./skills/delete-managed.js'
|
|
42
|
-
'./system/request-permission.js'
|
|
43
|
-
'./
|
|
44
|
-
'./
|
|
45
|
-
'./
|
|
46
|
-
'./
|
|
47
|
-
'./
|
|
48
|
-
'./
|
|
49
|
-
|
|
50
|
-
'./watcher/delete.js',
|
|
51
|
-
'./watcher/digest.js',
|
|
52
|
-
'./playbooks/playbook-create.js',
|
|
53
|
-
'./playbooks/playbook-list.js',
|
|
54
|
-
'./playbooks/playbook-update.js',
|
|
55
|
-
'./playbooks/playbook-delete.js',
|
|
56
|
-
'./contacts/contact-upsert.js',
|
|
57
|
-
'./contacts/contact-search.js',
|
|
58
|
-
'./contacts/contact-merge.js',
|
|
59
|
-
'./assets/search.js',
|
|
60
|
-
'./assets/materialize.js',
|
|
61
|
-
'./filesystem/view-image.js',
|
|
62
|
-
];
|
|
22
|
+
export async function loadEagerModules(): Promise<void> {
|
|
23
|
+
await import('./filesystem/read.js');
|
|
24
|
+
await import('./filesystem/write.js');
|
|
25
|
+
await import('./filesystem/edit.js');
|
|
26
|
+
await import('./network/web-search.js');
|
|
27
|
+
await import('./network/web-fetch.js');
|
|
28
|
+
await import('./skills/load.js');
|
|
29
|
+
await import('./skills/scaffold-managed.js');
|
|
30
|
+
await import('./skills/delete-managed.js');
|
|
31
|
+
await import('./system/request-permission.js');
|
|
32
|
+
await import('./assets/search.js');
|
|
33
|
+
await import('./assets/materialize.js');
|
|
34
|
+
await import('./filesystem/view-image.js');
|
|
35
|
+
await import('./calls/call-start.js');
|
|
36
|
+
await import('./calls/call-status.js');
|
|
37
|
+
await import('./calls/call-end.js');
|
|
38
|
+
}
|
|
63
39
|
|
|
64
40
|
// Tool names registered by the eager modules above. Listed explicitly so
|
|
65
41
|
// initializeTools() can recognise ESM-cached eager-module tools that were
|
|
@@ -75,25 +51,12 @@ export const eagerModuleToolNames: string[] = [
|
|
|
75
51
|
'scaffold_managed_skill',
|
|
76
52
|
'delete_managed_skill',
|
|
77
53
|
'request_system_permission',
|
|
78
|
-
'schedule_create',
|
|
79
|
-
'schedule_list',
|
|
80
|
-
'schedule_update',
|
|
81
|
-
'schedule_delete',
|
|
82
|
-
'watcher_create',
|
|
83
|
-
'watcher_list',
|
|
84
|
-
'watcher_update',
|
|
85
|
-
'watcher_delete',
|
|
86
|
-
'watcher_digest',
|
|
87
|
-
'playbook_create',
|
|
88
|
-
'playbook_list',
|
|
89
|
-
'playbook_update',
|
|
90
|
-
'playbook_delete',
|
|
91
|
-
'contact_upsert',
|
|
92
|
-
'contact_search',
|
|
93
|
-
'contact_merge',
|
|
94
54
|
'asset_search',
|
|
95
55
|
'asset_materialize',
|
|
96
56
|
'view_image',
|
|
57
|
+
'call_start',
|
|
58
|
+
'call_status',
|
|
59
|
+
'call_end',
|
|
97
60
|
];
|
|
98
61
|
|
|
99
62
|
// ── Explicit tool instances ─────────────────────────────────────────
|
|
@@ -106,26 +69,9 @@ export const explicitTools: Tool[] = [
|
|
|
106
69
|
memoryUpdateTool,
|
|
107
70
|
credentialStoreTool,
|
|
108
71
|
accountManageTool,
|
|
109
|
-
reminderTool,
|
|
110
72
|
screenWatchTool,
|
|
111
73
|
vellumSkillsCatalogTool,
|
|
112
|
-
documentCreateTool,
|
|
113
|
-
documentUpdateTool,
|
|
114
74
|
cliDiscoverTool,
|
|
115
|
-
followupCreateTool,
|
|
116
|
-
followupListTool,
|
|
117
|
-
followupResolveTool,
|
|
118
|
-
taskSaveTool,
|
|
119
|
-
taskRunTool,
|
|
120
|
-
taskListTool,
|
|
121
|
-
taskDeleteTool,
|
|
122
|
-
taskListShowTool,
|
|
123
|
-
taskListAddTool,
|
|
124
|
-
subagentSpawnTool,
|
|
125
|
-
subagentStatusTool,
|
|
126
|
-
subagentAbortTool,
|
|
127
|
-
subagentMessageTool,
|
|
128
|
-
subagentReadTool,
|
|
129
75
|
];
|
|
130
76
|
|
|
131
77
|
// ── Lazy tool descriptors ───────────────────────────────────────────
|
package/src/tools/types.ts
CHANGED
|
@@ -52,6 +52,8 @@ export interface ToolExecutedEvent extends ToolLifecycleEventBase {
|
|
|
52
52
|
result: ToolExecutionResult;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
export type ErrorCategory = 'permission_denied' | 'auth' | 'tool_failure' | 'unexpected';
|
|
56
|
+
|
|
55
57
|
export interface ToolExecutionErrorEvent extends ToolLifecycleEventBase {
|
|
56
58
|
type: 'error';
|
|
57
59
|
riskLevel: string;
|
|
@@ -59,6 +61,8 @@ export interface ToolExecutionErrorEvent extends ToolLifecycleEventBase {
|
|
|
59
61
|
durationMs: number;
|
|
60
62
|
errorMessage: string;
|
|
61
63
|
isExpected: boolean;
|
|
64
|
+
/** Classifies the error for downstream consumers (audit, alerting, monitoring). */
|
|
65
|
+
errorCategory: ErrorCategory;
|
|
62
66
|
errorName?: string;
|
|
63
67
|
errorStack?: string;
|
|
64
68
|
}
|
|
@@ -89,6 +93,8 @@ export interface ToolContext {
|
|
|
89
93
|
workingDir: string;
|
|
90
94
|
sessionId: string;
|
|
91
95
|
conversationId: string;
|
|
96
|
+
/** When set, the tool execution is part of a task run. Used to retrieve ephemeral permission rules. */
|
|
97
|
+
taskRunId?: string;
|
|
92
98
|
/** Per-message request ID for log correlation across session/connection boundaries. */
|
|
93
99
|
requestId?: string;
|
|
94
100
|
/** Optional callback for streaming incremental output to the client. */
|
|
@@ -35,6 +35,9 @@ export const uiShowTool: Tool = {
|
|
|
35
35
|
'templateData shape: { location: string, currentTemp: number, feelsLike: number, unit: "F"|"C", condition: string, humidity: number, windSpeed: number, windDirection: string, ' +
|
|
36
36
|
'hourly: Array<{ time: string, icon: string (SF Symbol name), temp: number }>, ' +
|
|
37
37
|
'forecast: Array<{ day: string, icon: string (SF Symbol name), low: number, high: number, precip: number|null, condition: string }> }\n' +
|
|
38
|
+
' Template "task_progress": renders a live-updating task progress widget showing structured step-by-step progress. ' +
|
|
39
|
+
'templateData shape: { title: string, status: "in_progress"|"completed"|"failed", ' +
|
|
40
|
+
'steps: Array<{ label: string, status: "pending"|"in_progress"|"completed"|"failed", detail?: string }> }\n' +
|
|
38
41
|
'- table: Data table with columns, selectable rows, and action buttons. ' +
|
|
39
42
|
'data shape: { columns: Array<{ id: string, label: string }>, rows: Array<{ id: string, cells: Record<string, string>, selectable?: boolean, selected?: boolean }>, selectionMode?: "none"|"single"|"multiple", caption?: string }\n' +
|
|
40
43
|
'- form: Input form with typed fields. ' +
|
|
@@ -117,7 +120,9 @@ export const uiShowTool: Tool = {
|
|
|
117
120
|
|
|
118
121
|
export const uiUpdateTool: Tool = {
|
|
119
122
|
name: 'ui_update',
|
|
120
|
-
description:
|
|
123
|
+
description:
|
|
124
|
+
"Update an existing surface's data. The provided data object is merged into the surface's current data.\n" +
|
|
125
|
+
'For card templates (for example `task_progress`), update nested fields under `data.templateData` rather than sending template fields at the top level.',
|
|
121
126
|
category: 'ui-surface',
|
|
122
127
|
defaultRiskLevel: RiskLevel.Low,
|
|
123
128
|
executionMode: 'proxy',
|
|
@@ -13,6 +13,8 @@ import type { WatchSession } from './watch-state.js';
|
|
|
13
13
|
|
|
14
14
|
const log = getLogger('screen-watch');
|
|
15
15
|
|
|
16
|
+
const SHORT_HASH_LENGTH = 8;
|
|
17
|
+
|
|
16
18
|
class ScreenWatchTool implements Tool {
|
|
17
19
|
name = 'start_screen_watch';
|
|
18
20
|
description = 'Start observing the screen at regular intervals for a specified duration. Captures OCR text from the active window and provides periodic commentary.';
|
|
@@ -77,7 +79,7 @@ class ScreenWatchTool implements Tool {
|
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
// Generate watchId
|
|
80
|
-
const watchId = crypto.randomUUID().slice(0,
|
|
82
|
+
const watchId = crypto.randomUUID().slice(0, SHORT_HASH_LENGTH);
|
|
81
83
|
const now = Date.now();
|
|
82
84
|
const durationSeconds = durationMinutes * 60;
|
|
83
85
|
|
|
@@ -1,110 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
|
|
3
|
-
import type { ToolDefinition } from '../../providers/types.js';
|
|
4
|
-
import { registerTool } from '../registry.js';
|
|
1
|
+
import type { ToolContext, ToolExecutionResult } from '../types.js';
|
|
5
2
|
import { createWatcher } from '../../watcher/watcher-store.js';
|
|
6
3
|
import { getWatcherProvider, listWatcherProviders } from '../../watcher/provider-registry.js';
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
export async function executeWatcherCreate(
|
|
6
|
+
input: Record<string, unknown>,
|
|
7
|
+
_context: ToolContext,
|
|
8
|
+
): Promise<ToolExecutionResult> {
|
|
9
|
+
const name = input.name as string;
|
|
10
|
+
const providerId = input.provider as string;
|
|
11
|
+
const actionPrompt = input.action_prompt as string;
|
|
12
|
+
const pollIntervalMs = (input.poll_interval_ms as number) ?? undefined;
|
|
13
|
+
const config = input.config as Record<string, unknown> | undefined;
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
type: 'string',
|
|
23
|
-
description: 'A human-readable name for this watcher (e.g. "My Gmail")',
|
|
24
|
-
},
|
|
25
|
-
provider: {
|
|
26
|
-
type: 'string',
|
|
27
|
-
description: 'The provider to poll (e.g. "gmail")',
|
|
28
|
-
},
|
|
29
|
-
action_prompt: {
|
|
30
|
-
type: 'string',
|
|
31
|
-
description: 'Instructions for the LLM on how to handle detected events. This prompt is sent along with event data to a background conversation.',
|
|
32
|
-
},
|
|
33
|
-
poll_interval_ms: {
|
|
34
|
-
type: 'number',
|
|
35
|
-
description: 'How often to poll in milliseconds. Defaults to 60000 (1 minute). Minimum 15000.',
|
|
36
|
-
},
|
|
37
|
-
credential_service: {
|
|
38
|
-
type: 'string',
|
|
39
|
-
description: 'Override the credential service to use. Defaults to the provider\'s required service.',
|
|
40
|
-
},
|
|
41
|
-
config: {
|
|
42
|
-
type: 'object',
|
|
43
|
-
description: 'Provider-specific configuration (e.g. filter criteria)',
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
required: ['name', 'provider', 'action_prompt'],
|
|
47
|
-
},
|
|
48
|
-
};
|
|
15
|
+
if (!name || typeof name !== 'string') {
|
|
16
|
+
return { content: 'Error: name is required and must be a string', isError: true };
|
|
17
|
+
}
|
|
18
|
+
if (!providerId || typeof providerId !== 'string') {
|
|
19
|
+
return { content: 'Error: provider is required and must be a string', isError: true };
|
|
20
|
+
}
|
|
21
|
+
if (!actionPrompt || typeof actionPrompt !== 'string') {
|
|
22
|
+
return { content: 'Error: action_prompt is required and must be a string', isError: true };
|
|
49
23
|
}
|
|
50
24
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const config = input.config as Record<string, unknown> | undefined;
|
|
57
|
-
|
|
58
|
-
if (!name || typeof name !== 'string') {
|
|
59
|
-
return { content: 'Error: name is required and must be a string', isError: true };
|
|
60
|
-
}
|
|
61
|
-
if (!providerId || typeof providerId !== 'string') {
|
|
62
|
-
return { content: 'Error: provider is required and must be a string', isError: true };
|
|
63
|
-
}
|
|
64
|
-
if (!actionPrompt || typeof actionPrompt !== 'string') {
|
|
65
|
-
return { content: 'Error: action_prompt is required and must be a string', isError: true };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const provider = getWatcherProvider(providerId);
|
|
69
|
-
if (!provider) {
|
|
70
|
-
const available = listWatcherProviders().map((p) => p.id).join(', ') || 'none';
|
|
71
|
-
return { content: `Error: Unknown provider "${providerId}". Available: ${available}`, isError: true };
|
|
72
|
-
}
|
|
25
|
+
const provider = getWatcherProvider(providerId);
|
|
26
|
+
if (!provider) {
|
|
27
|
+
const available = listWatcherProviders().map((p) => p.id).join(', ') || 'none';
|
|
28
|
+
return { content: `Error: Unknown provider "${providerId}". Available: ${available}`, isError: true };
|
|
29
|
+
}
|
|
73
30
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
31
|
+
if (pollIntervalMs !== undefined && pollIntervalMs < 15000) {
|
|
32
|
+
return { content: 'Error: poll_interval_ms must be at least 15000 (15 seconds)', isError: true };
|
|
33
|
+
}
|
|
77
34
|
|
|
78
|
-
|
|
35
|
+
const credentialService = (input.credential_service as string) ?? provider.requiredCredentialService;
|
|
79
36
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
37
|
+
try {
|
|
38
|
+
const watcher = createWatcher({
|
|
39
|
+
name,
|
|
40
|
+
providerId,
|
|
41
|
+
actionPrompt,
|
|
42
|
+
credentialService,
|
|
43
|
+
pollIntervalMs,
|
|
44
|
+
configJson: config ? JSON.stringify(config) : null,
|
|
45
|
+
});
|
|
89
46
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
47
|
+
const intervalSec = Math.round(watcher.pollIntervalMs / 1000);
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
'Watcher created successfully.',
|
|
51
|
+
` Name: ${watcher.name}`,
|
|
52
|
+
` Provider: ${provider.displayName}`,
|
|
53
|
+
` Poll interval: ${intervalSec}s`,
|
|
54
|
+
` Credential: ${watcher.credentialService}`,
|
|
55
|
+
` Status: ${watcher.status}`,
|
|
56
|
+
` ID: ${watcher.id}`,
|
|
57
|
+
].join('\n'),
|
|
58
|
+
isError: false,
|
|
59
|
+
};
|
|
60
|
+
} catch (err) {
|
|
61
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62
|
+
return { content: `Error creating watcher: ${msg}`, isError: true };
|
|
107
63
|
}
|
|
108
64
|
}
|
|
109
|
-
|
|
110
|
-
registerTool(new WatcherCreateTool());
|
|
@@ -1,53 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
|
|
3
|
-
import type { ToolDefinition } from '../../providers/types.js';
|
|
4
|
-
import { registerTool } from '../registry.js';
|
|
1
|
+
import type { ToolContext, ToolExecutionResult } from '../types.js';
|
|
5
2
|
import { getWatcher, deleteWatcher } from '../../watcher/watcher-store.js';
|
|
6
3
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
name: this.name,
|
|
16
|
-
description: this.description,
|
|
17
|
-
input_schema: {
|
|
18
|
-
type: 'object',
|
|
19
|
-
properties: {
|
|
20
|
-
watcher_id: {
|
|
21
|
-
type: 'string',
|
|
22
|
-
description: 'The ID of the watcher to delete',
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
required: ['watcher_id'],
|
|
26
|
-
},
|
|
27
|
-
};
|
|
4
|
+
export async function executeWatcherDelete(
|
|
5
|
+
input: Record<string, unknown>,
|
|
6
|
+
_context: ToolContext,
|
|
7
|
+
): Promise<ToolExecutionResult> {
|
|
8
|
+
const watcherId = input.watcher_id as string;
|
|
9
|
+
if (!watcherId || typeof watcherId !== 'string') {
|
|
10
|
+
return { content: 'Error: watcher_id is required', isError: true };
|
|
28
11
|
}
|
|
29
12
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const watcher = getWatcher(watcherId);
|
|
37
|
-
if (!watcher) {
|
|
38
|
-
return { content: `Error: Watcher not found: ${watcherId}`, isError: true };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const deleted = deleteWatcher(watcherId);
|
|
42
|
-
if (!deleted) {
|
|
43
|
-
return { content: `Error: Failed to delete watcher: ${watcherId}`, isError: true };
|
|
44
|
-
}
|
|
13
|
+
const watcher = getWatcher(watcherId);
|
|
14
|
+
if (!watcher) {
|
|
15
|
+
return { content: `Error: Watcher not found: ${watcherId}`, isError: true };
|
|
16
|
+
}
|
|
45
17
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
};
|
|
18
|
+
const deleted = deleteWatcher(watcherId);
|
|
19
|
+
if (!deleted) {
|
|
20
|
+
return { content: `Error: Failed to delete watcher: ${watcherId}`, isError: true };
|
|
50
21
|
}
|
|
51
|
-
}
|
|
52
22
|
|
|
53
|
-
|
|
23
|
+
return {
|
|
24
|
+
content: `Watcher deleted: "${watcher.name}"`,
|
|
25
|
+
isError: false,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -1,84 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Tool, ToolContext, ToolExecutionResult } from '../types.js';
|
|
3
|
-
import type { ToolDefinition } from '../../providers/types.js';
|
|
4
|
-
import { registerTool } from '../registry.js';
|
|
1
|
+
import type { ToolContext, ToolExecutionResult } from '../types.js';
|
|
5
2
|
import { listWatchers, listWatcherEvents } from '../../watcher/watcher-store.js';
|
|
6
3
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
export async function executeWatcherDigest(
|
|
5
|
+
input: Record<string, unknown>,
|
|
6
|
+
_context: ToolContext,
|
|
7
|
+
): Promise<ToolExecutionResult> {
|
|
8
|
+
const watcherId = input.watcher_id as string | undefined;
|
|
9
|
+
const hours = (input.hours as number) ?? 24;
|
|
10
|
+
const limit = (input.limit as number) ?? 50;
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
name: this.name,
|
|
16
|
-
description: this.description,
|
|
17
|
-
input_schema: {
|
|
18
|
-
type: 'object',
|
|
19
|
-
properties: {
|
|
20
|
-
watcher_id: {
|
|
21
|
-
type: 'string',
|
|
22
|
-
description: 'Filter to events from a specific watcher. If omitted, shows events from all watchers.',
|
|
23
|
-
},
|
|
24
|
-
hours: {
|
|
25
|
-
type: 'number',
|
|
26
|
-
description: 'How many hours back to look. Defaults to 24.',
|
|
27
|
-
},
|
|
28
|
-
limit: {
|
|
29
|
-
type: 'number',
|
|
30
|
-
description: 'Maximum number of events to return. Defaults to 50.',
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
required: [],
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async execute(input: Record<string, unknown>, _context: ToolContext): Promise<ToolExecutionResult> {
|
|
39
|
-
const watcherId = input.watcher_id as string | undefined;
|
|
40
|
-
const hours = (input.hours as number) ?? 24;
|
|
41
|
-
const limit = (input.limit as number) ?? 50;
|
|
42
|
-
|
|
43
|
-
const since = Date.now() - hours * 60 * 60 * 1000;
|
|
12
|
+
const since = Date.now() - hours * 60 * 60 * 1000;
|
|
44
13
|
|
|
45
|
-
|
|
14
|
+
const events = listWatcherEvents({ watcherId, limit, since });
|
|
46
15
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
16
|
+
if (events.length === 0) {
|
|
17
|
+
const period = hours === 24 ? 'today' : `the last ${hours} hours`;
|
|
18
|
+
return { content: `No watcher events detected ${period}.`, isError: false };
|
|
19
|
+
}
|
|
51
20
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
21
|
+
// Group events by watcher
|
|
22
|
+
const watcherMap = new Map<string, typeof events>();
|
|
23
|
+
for (const event of events) {
|
|
24
|
+
const existing = watcherMap.get(event.watcherId) ?? [];
|
|
25
|
+
existing.push(event);
|
|
26
|
+
watcherMap.set(event.watcherId, existing);
|
|
27
|
+
}
|
|
59
28
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
29
|
+
// Get watcher names
|
|
30
|
+
const allWatchers = listWatchers();
|
|
31
|
+
const nameMap = new Map(allWatchers.map((w) => [w.id, w.name]));
|
|
63
32
|
|
|
64
|
-
|
|
33
|
+
const lines = [`Watcher activity (last ${hours}h, ${events.length} events):`];
|
|
65
34
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
35
|
+
for (const [wId, wEvents] of watcherMap) {
|
|
36
|
+
const name = nameMap.get(wId) ?? wId;
|
|
37
|
+
lines.push('', `${name} (${wEvents.length} events):`);
|
|
69
38
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
39
|
+
for (const event of wEvents) {
|
|
40
|
+
const time = new Date(event.createdAt).toLocaleString();
|
|
41
|
+
const disposition = event.disposition !== 'pending' ? ` [${event.disposition}]` : '';
|
|
42
|
+
lines.push(` - ${event.summary}${disposition} (${time})`);
|
|
43
|
+
if (event.llmAction) {
|
|
44
|
+
lines.push(` Action: ${event.llmAction}`);
|
|
77
45
|
}
|
|
78
46
|
}
|
|
79
|
-
|
|
80
|
-
return { content: lines.join('\n'), isError: false };
|
|
81
47
|
}
|
|
82
|
-
}
|
|
83
48
|
|
|
84
|
-
|
|
49
|
+
return { content: lines.join('\n'), isError: false };
|
|
50
|
+
}
|