@vellumai/assistant 0.5.16 → 0.6.1
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/AGENTS.md +4 -0
- package/ARCHITECTURE.md +69 -16
- package/Dockerfile +2 -5
- package/bun.lock +6 -2
- package/docker-entrypoint.sh +32 -1
- package/docs/architecture/integrations.md +1 -1
- package/docs/architecture/memory.md +21 -24
- package/knip.json +2 -1
- package/openapi.yaml +1198 -83
- package/package.json +5 -1
- package/src/__tests__/actor-token-service.test.ts +68 -0
- package/src/__tests__/agent-loop.test.ts +0 -32
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/anthropic-provider.test.ts +217 -98
- package/src/__tests__/app-compiler.test.ts +120 -0
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +47 -1
- package/src/__tests__/app-source-watcher.test.ts +159 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/call-conversation-messages.test.ts +2 -6
- package/src/__tests__/call-domain.test.ts +2 -6
- package/src/__tests__/call-pointer-messages.test.ts +2 -14
- package/src/__tests__/call-recovery.test.ts +2 -6
- package/src/__tests__/call-routes-http.test.ts +2 -6
- package/src/__tests__/call-store.test.ts +2 -6
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
- package/src/__tests__/canonical-guardian-store.test.ts +2 -6
- package/src/__tests__/channel-delivery-store.test.ts +2 -6
- package/src/__tests__/channel-retry-sweep.test.ts +2 -6
- package/src/__tests__/checker.test.ts +63 -9
- package/src/__tests__/clawhub.test.ts +54 -24
- package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
- package/src/__tests__/config-schema.test.ts +6 -1
- package/src/__tests__/config-set-platform-guard.test.ts +302 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
- package/src/__tests__/contacts-tools.test.ts +31 -0
- package/src/__tests__/context-overflow-reducer.test.ts +86 -0
- package/src/__tests__/context-token-estimator.test.ts +175 -10
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +13 -6
- package/src/__tests__/conversation-agent-loop.test.ts +13 -51
- package/src/__tests__/conversation-attachments.test.ts +2 -6
- package/src/__tests__/conversation-attention-store.test.ts +2 -6
- package/src/__tests__/conversation-clear-safety.test.ts +2 -6
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
- package/src/__tests__/conversation-disk-view.test.ts +2 -6
- package/src/__tests__/conversation-error.test.ts +33 -2
- package/src/__tests__/conversation-fork-crud.test.ts +2 -6
- package/src/__tests__/conversation-history-web-search.test.ts +6 -1
- package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
- package/src/__tests__/conversation-media-retry.test.ts +91 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
- package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
- package/src/__tests__/conversation-starter-routes.test.ts +20 -11
- package/src/__tests__/conversation-store.test.ts +2 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
- package/src/__tests__/conversation-usage.test.ts +2 -6
- package/src/__tests__/conversation-wipe.test.ts +13 -414
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
- package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
- package/src/__tests__/credential-security-e2e.test.ts +2 -0
- package/src/__tests__/date-context.test.ts +76 -210
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
- package/src/__tests__/file-list-tool.test.ts +219 -0
- package/src/__tests__/first-greeting.test.ts +1 -1
- package/src/__tests__/followup-tools.test.ts +2 -6
- package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
- package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
- package/src/__tests__/guardian-action-store.test.ts +2 -6
- package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
- package/src/__tests__/guardian-dispatch.test.ts +2 -6
- package/src/__tests__/guardian-grant-minting.test.ts +2 -14
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
- package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
- package/src/__tests__/guardian-routing-state.test.ts +2 -6
- package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
- package/src/__tests__/heartbeat-service.test.ts +180 -3
- package/src/__tests__/identity-routes.test.ts +328 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
- package/src/__tests__/injection-block.test.ts +178 -0
- package/src/__tests__/install-meta.test.ts +506 -0
- package/src/__tests__/install-skill-routing.test.ts +293 -0
- package/src/__tests__/invite-redemption-service.test.ts +2 -6
- package/src/__tests__/invite-routes-http.test.ts +2 -6
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +17 -28
- package/src/__tests__/list-messages-attachments.test.ts +2 -6
- package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
- package/src/__tests__/llm-context-normalization.test.ts +18 -18
- package/src/__tests__/llm-context-route-provider.test.ts +103 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +164 -6
- package/src/__tests__/llm-usage-store.test.ts +2 -6
- package/src/__tests__/log-export-workspace.test.ts +74 -111
- package/src/__tests__/managed-store.test.ts +38 -11
- package/src/__tests__/mcp-abort-signal.test.ts +5 -0
- package/src/__tests__/mcp-client-auth.test.ts +5 -0
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
- package/src/__tests__/memory-recall-log-store.test.ts +134 -6
- package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
- package/src/__tests__/migration-export-streaming.test.ts +304 -0
- package/src/__tests__/migration-import-commit-http.test.ts +11 -10
- package/src/__tests__/mock-fetch.ts +87 -0
- package/src/__tests__/non-member-access-request.test.ts +2 -6
- package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
- package/src/__tests__/notification-guardian-path.test.ts +2 -6
- package/src/__tests__/oauth-cli.test.ts +364 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
- package/src/__tests__/onboarding-template-contract.test.ts +62 -14
- package/src/__tests__/outlook-attachments.test.ts +301 -0
- package/src/__tests__/outlook-automation-tools.test.ts +425 -0
- package/src/__tests__/outlook-categories.test.ts +212 -0
- package/src/__tests__/outlook-client-automation.test.ts +246 -0
- package/src/__tests__/outlook-compose-tools.test.ts +325 -0
- package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
- package/src/__tests__/outlook-email-watcher.test.ts +322 -0
- package/src/__tests__/outlook-follow-up.test.ts +196 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
- package/src/__tests__/outlook-trash.test.ts +77 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
- package/src/__tests__/parser.test.ts +32 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
- package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
- package/src/__tests__/permission-mode-sse.test.ts +418 -0
- package/src/__tests__/permission-mode-store.test.ts +277 -0
- package/src/__tests__/permission-mode.test.ts +101 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
- package/src/__tests__/platform-callback-registration.test.ts +4 -4
- package/src/__tests__/playbook-execution.test.ts +76 -80
- package/src/__tests__/playbook-tools.test.ts +5 -7
- package/src/__tests__/profiler-routes.test.ts +502 -0
- package/src/__tests__/profiler-run-store.test.ts +441 -0
- package/src/__tests__/provider-error-scenarios.test.ts +21 -0
- package/src/__tests__/proxy-approval-callback.test.ts +4 -75
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
- package/src/__tests__/registry.test.ts +3 -3
- package/src/__tests__/require-fresh-approval.test.ts +64 -2
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
- package/src/__tests__/runtime-events-sse.test.ts +2 -6
- package/src/__tests__/sandbox-host-parity.test.ts +5 -4
- package/src/__tests__/schedule-store.test.ts +2 -6
- package/src/__tests__/schedule-tools.test.ts +2 -6
- package/src/__tests__/scheduler-recurrence.test.ts +1 -5
- package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
- package/src/__tests__/scoped-approval-grants.test.ts +2 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
- package/src/__tests__/search-skills-unified.test.ts +422 -0
- package/src/__tests__/secret-onetime-send.test.ts +2 -0
- package/src/__tests__/send-endpoint-busy.test.ts +44 -9
- package/src/__tests__/sequence-store.test.ts +2 -6
- package/src/__tests__/server-history-render.test.ts +2 -6
- package/src/__tests__/set-permission-mode.test.ts +274 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +23 -11
- package/src/__tests__/skill-memory.test.ts +2 -741
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +1 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -6
- package/src/__tests__/strip-memory-injections.test.ts +187 -0
- package/src/__tests__/subagent-detail.test.ts +84 -0
- package/src/__tests__/subagent-disposal.test.ts +308 -0
- package/src/__tests__/subagent-manager-notify.test.ts +19 -10
- package/src/__tests__/subagent-notify-parent.test.ts +390 -0
- package/src/__tests__/subagent-role-registry.test.ts +108 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
- package/src/__tests__/subagent-tools.test.ts +464 -4
- package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
- package/src/__tests__/task-compiler.test.ts +2 -6
- package/src/__tests__/task-management-tools.test.ts +2 -6
- package/src/__tests__/task-memory-cleanup.test.ts +185 -241
- package/src/__tests__/task-runner.test.ts +2 -6
- package/src/__tests__/task-scheduler.test.ts +2 -6
- package/src/__tests__/terminal-tools.test.ts +17 -27
- package/src/__tests__/test-preload.ts +7 -0
- package/src/__tests__/tool-approval-handler.test.ts +2 -6
- package/src/__tests__/tool-executor.test.ts +4 -26
- package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +277 -0
- package/src/__tests__/top-level-renderer.test.ts +10 -13
- package/src/__tests__/trust-store.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +118 -8
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
- package/src/__tests__/trusted-contact-verification.test.ts +2 -6
- package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
- package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
- package/src/__tests__/usage-routes.test.ts +2 -6
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +2 -6
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
- package/src/__tests__/voice-session-bridge.test.ts +2 -6
- package/src/__tests__/volume-security-guard.test.ts +2 -0
- package/src/__tests__/workspace-lifecycle.test.ts +29 -1
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
- package/src/__tests__/workspace-policy.test.ts +1 -1
- package/src/agent/attachments.ts +7 -2
- package/src/agent/image-optimize.ts +165 -0
- package/src/agent/loop.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +24 -0
- package/src/avatar/traits-png-sync.ts +3 -3
- package/src/bundler/app-compiler.ts +179 -2
- package/src/bundler/package-resolver.ts +3 -5
- package/src/cli/__tests__/notifications.test.ts +1 -2
- package/src/cli/__tests__/run-assistant-command.ts +29 -0
- package/src/cli/commands/__tests__/email-download.test.ts +245 -0
- package/src/cli/commands/__tests__/email-list.test.ts +192 -0
- package/src/cli/commands/__tests__/email-register.test.ts +186 -0
- package/src/cli/commands/__tests__/email-send.test.ts +291 -0
- package/src/cli/commands/__tests__/email-status.test.ts +181 -0
- package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
- package/src/cli/commands/__tests__/routes.test.ts +562 -0
- package/src/cli/commands/avatar.ts +3 -3
- package/src/cli/commands/config.ts +26 -13
- package/src/cli/commands/conversations.ts +1 -8
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/email.ts +584 -835
- package/src/cli/commands/memory.ts +37 -84
- package/src/cli/commands/notifications.ts +7 -2
- package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
- package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
- package/src/cli/commands/oauth/connect.ts +25 -11
- package/src/cli/commands/oauth/mode.ts +7 -0
- package/src/cli/commands/oauth/shared.ts +39 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
- package/src/cli/commands/platform/index.ts +16 -16
- package/src/cli/commands/routes.ts +396 -0
- package/src/cli/commands/skills.ts +218 -36
- package/src/cli/commands/trust.ts +2 -2
- package/src/cli/lib/daemon-credential-client.ts +2 -3
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +1 -120
- package/src/config/bundled-skills/acp/TOOLS.json +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +4 -1
- package/src/config/bundled-skills/contacts/SKILL.md +0 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
- package/src/config/bundled-skills/gmail/SKILL.md +4 -12
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
- package/src/config/bundled-skills/messaging/SKILL.md +17 -18
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
- package/src/config/bundled-skills/outlook/SKILL.md +189 -0
- package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
- package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
- package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
- package/src/config/bundled-skills/schedule/SKILL.md +22 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
- package/src/config/bundled-skills/slack/SKILL.md +3 -7
- package/src/config/bundled-skills/subagent/SKILL.md +43 -3
- package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
- package/src/config/bundled-tool-registry.ts +56 -4
- package/src/config/env-registry.ts +78 -8
- package/src/config/feature-flag-registry.json +38 -125
- package/src/config/schema.ts +8 -0
- package/src/config/schemas/filing.ts +51 -0
- package/src/config/schemas/heartbeat.ts +15 -12
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/security.ts +14 -0
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/config/skills.ts +18 -7
- package/src/context/token-estimator.ts +25 -18
- package/src/context/window-manager.ts +6 -2
- package/src/credential-execution/process-manager.ts +3 -1
- package/src/daemon/app-source-watcher.ts +93 -0
- package/src/daemon/config-watcher.ts +79 -1
- package/src/daemon/context-overflow-reducer.ts +46 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +143 -82
- package/src/daemon/conversation-agent-loop.ts +236 -108
- package/src/daemon/conversation-error.ts +31 -8
- package/src/daemon/conversation-history.ts +4 -19
- package/src/daemon/conversation-lifecycle.ts +36 -9
- package/src/daemon/conversation-media-retry.ts +85 -7
- package/src/daemon/conversation-notifiers.ts +4 -1
- package/src/daemon/conversation-process.ts +13 -7
- package/src/daemon/conversation-runtime-assembly.ts +305 -306
- package/src/daemon/conversation-tool-setup.ts +44 -14
- package/src/daemon/conversation-workspace.ts +1 -2
- package/src/daemon/conversation.ts +59 -2
- package/src/daemon/daemon-control.ts +8 -2
- package/src/daemon/date-context.ts +26 -53
- package/src/daemon/first-greeting.ts +1 -1
- package/src/daemon/handlers/conversations.ts +4 -7
- package/src/daemon/handlers/shared.test.ts +143 -0
- package/src/daemon/handlers/shared.ts +85 -17
- package/src/daemon/handlers/skills.ts +416 -209
- package/src/daemon/lifecycle.ts +212 -131
- package/src/daemon/main.ts +5 -1
- package/src/daemon/message-types/conversations.ts +29 -7
- package/src/daemon/message-types/messages.ts +12 -2
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/settings.ts +6 -0
- package/src/daemon/message-types/skills.ts +97 -36
- package/src/daemon/profiler-run-store.ts +557 -0
- package/src/daemon/providers-setup.ts +5 -0
- package/src/daemon/server.ts +100 -11
- package/src/daemon/shutdown-handlers.ts +5 -0
- package/src/daemon/tool-side-effects.ts +50 -8
- package/src/export/transcript-formatter.ts +148 -0
- package/src/filing/filing-service.ts +228 -0
- package/src/heartbeat/heartbeat-service.ts +97 -7
- package/src/hooks/cli.ts +2 -2
- package/src/hooks/runner.ts +15 -38
- package/src/inbound/platform-callback-registration.ts +14 -14
- package/src/mcp/client.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +149 -27
- package/src/memory/admin.ts +42 -75
- package/src/memory/app-store.ts +69 -0
- package/src/memory/conversation-bootstrap.ts +3 -1
- package/src/memory/conversation-crud.ts +211 -288
- package/src/memory/conversation-group-migration.ts +157 -0
- package/src/memory/conversation-queries.ts +61 -13
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/db-init.ts +194 -361
- package/src/memory/embed.ts +73 -0
- package/src/memory/embedding-backend.ts +8 -14
- package/src/memory/embedding-runtime-manager.ts +12 -114
- package/src/memory/fingerprint.ts +2 -2
- package/src/memory/graph/bootstrap.ts +521 -0
- package/src/memory/graph/capability-seed.ts +449 -0
- package/src/memory/graph/consolidation.ts +725 -0
- package/src/memory/graph/conversation-graph-memory.ts +659 -0
- package/src/memory/graph/decay.test.ts +208 -0
- package/src/memory/graph/decay.ts +195 -0
- package/src/memory/graph/extraction-job.ts +74 -0
- package/src/memory/graph/extraction.test.ts +936 -0
- package/src/memory/graph/extraction.ts +1297 -0
- package/src/memory/graph/graph-memory-state-store.ts +37 -0
- package/src/memory/graph/graph-search.ts +280 -0
- package/src/memory/graph/image-ref-utils.ts +29 -0
- package/src/memory/graph/injection.test.ts +513 -0
- package/src/memory/graph/injection.ts +469 -0
- package/src/memory/graph/inspect.ts +543 -0
- package/src/memory/graph/narrative.ts +267 -0
- package/src/memory/graph/pattern-scan.ts +269 -0
- package/src/memory/graph/retriever.ts +1111 -0
- package/src/memory/graph/scoring.test.ts +548 -0
- package/src/memory/graph/scoring.ts +232 -0
- package/src/memory/graph/serendipity.ts +65 -0
- package/src/memory/graph/store.test.ts +1098 -0
- package/src/memory/graph/store.ts +838 -0
- package/src/memory/graph/tool-handlers.ts +301 -0
- package/src/memory/graph/tools.ts +97 -0
- package/src/memory/graph/triggers.test.ts +487 -0
- package/src/memory/graph/triggers.ts +223 -0
- package/src/memory/graph/types.ts +295 -0
- package/src/memory/group-crud.ts +191 -0
- package/src/memory/indexer.ts +37 -19
- package/src/memory/job-handlers/cleanup.ts +32 -42
- package/src/memory/job-handlers/conversation-starters.ts +91 -53
- package/src/memory/job-handlers/embedding.ts +5 -31
- package/src/memory/job-handlers/index-maintenance.ts +23 -11
- package/src/memory/job-handlers/summarization.ts +32 -17
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +21 -31
- package/src/memory/jobs-worker.ts +180 -129
- package/src/memory/llm-request-log-store.ts +96 -12
- package/src/memory/memory-recall-log-store.ts +49 -5
- package/src/memory/message-content.ts +1 -0
- package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
- package/src/memory/migrations/203-drop-memory-items-tables.ts +55 -0
- package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
- package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
- package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
- package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
- package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
- package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
- package/src/memory/migrations/index.ts +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-client.ts +44 -17
- package/src/memory/schema/conversations.ts +14 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/infrastructure.ts +8 -1
- package/src/memory/schema/memory-core.ts +0 -51
- package/src/memory/schema/memory-graph.ts +154 -0
- package/src/memory/search/semantic.ts +47 -91
- package/src/memory/task-memory-cleanup.ts +58 -61
- package/src/messaging/providers/outlook/adapter.ts +8 -1
- package/src/messaging/providers/outlook/client.ts +299 -0
- package/src/messaging/providers/outlook/types.ts +118 -0
- package/src/notifications/adapters/macos.ts +1 -0
- package/src/notifications/copy-composer.ts +95 -0
- package/src/notifications/decision-engine.ts +35 -0
- package/src/notifications/signal.ts +16 -0
- package/src/oauth/seed-providers.ts +2 -1
- package/src/permissions/checker.ts +36 -4
- package/src/permissions/defaults.ts +4 -4
- package/src/permissions/permission-mode-store.ts +180 -0
- package/src/permissions/permission-mode.ts +31 -0
- package/src/permissions/workspace-policy.ts +10 -1
- package/src/playbooks/playbook-compiler.ts +19 -18
- package/src/playbooks/types.ts +4 -3
- package/src/prompts/system-prompt.ts +62 -36
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
- package/src/prompts/templates/BOOTSTRAP.md +70 -165
- package/src/prompts/templates/HEARTBEAT.md +3 -1
- package/src/prompts/templates/SOUL.md +25 -4
- package/src/prompts/templates/UPDATES.md +8 -0
- package/src/providers/anthropic/client.ts +136 -220
- package/src/providers/gemini/client.ts +1 -1
- package/src/providers/openai/client.ts +1 -1
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +19 -3
- package/src/runtime/actor-trust-resolver.ts +5 -1
- package/src/runtime/auth/route-policy.ts +30 -0
- package/src/runtime/guardian-reply-router.ts +5 -1
- package/src/runtime/http-server.ts +55 -5
- package/src/runtime/http-types.ts +12 -1
- package/src/runtime/middleware/auth.ts +20 -0
- package/src/runtime/migrations/vbundle-builder.ts +389 -3
- package/src/runtime/migrations/vbundle-importer.ts +8 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
- package/src/runtime/routes/app-management-routes.ts +1 -11
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
- package/src/runtime/routes/archive-utils.ts +29 -0
- package/src/runtime/routes/attachment-routes.test.ts +106 -0
- package/src/runtime/routes/attachment-routes.ts +106 -16
- package/src/runtime/routes/avatar-routes.ts +2 -9
- package/src/runtime/routes/brain-graph-routes.ts +21 -22
- package/src/runtime/routes/btw-routes.ts +22 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
- package/src/runtime/routes/conversation-management-routes.ts +3 -14
- package/src/runtime/routes/conversation-query-routes.ts +49 -3
- package/src/runtime/routes/conversation-routes.ts +264 -44
- package/src/runtime/routes/conversation-starter-routes.ts +2 -2
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/global-search-routes.ts +21 -19
- package/src/runtime/routes/group-routes.ts +207 -0
- package/src/runtime/routes/guardian-action-routes.ts +21 -10
- package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
- package/src/runtime/routes/heartbeat-routes.ts +4 -10
- package/src/runtime/routes/identity-routes.ts +53 -18
- package/src/runtime/routes/inbound-message-handler.ts +19 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
- package/src/runtime/routes/llm-context-normalization.ts +14 -10
- package/src/runtime/routes/log-export-routes.ts +23 -275
- package/src/runtime/routes/memory-item-routes.test.ts +170 -247
- package/src/runtime/routes/memory-item-routes.ts +341 -388
- package/src/runtime/routes/migration-routes.ts +18 -7
- package/src/runtime/routes/profiler-routes.ts +350 -0
- package/src/runtime/routes/schedule-routes.ts +28 -11
- package/src/runtime/routes/settings-routes.ts +95 -8
- package/src/runtime/routes/skills-routes.ts +103 -37
- package/src/runtime/routes/subagents-routes.ts +28 -7
- package/src/runtime/routes/user-route-dispatcher.ts +223 -0
- package/src/runtime/routes/user-routes.ts +41 -0
- package/src/runtime/routes/work-items-routes.test.ts +2 -6
- package/src/runtime/routes/workspace-routes.ts +0 -1
- package/src/schedule/schedule-store.ts +30 -0
- package/src/schedule/scheduler.ts +52 -18
- package/src/security/oauth2.ts +1 -1
- package/src/security/secure-keys.ts +4 -8
- package/src/shared/provider-env-vars.ts +19 -0
- package/src/skills/catalog-cache.ts +5 -0
- package/src/skills/catalog-install.ts +25 -16
- package/src/skills/clawhub.ts +134 -154
- package/src/skills/install-meta.ts +208 -0
- package/src/skills/managed-store.ts +29 -18
- package/src/skills/skill-memory.ts +12 -229
- package/src/skills/skillssh-registry.ts +19 -17
- package/src/subagent/index.ts +13 -3
- package/src/subagent/manager.ts +308 -29
- package/src/subagent/types.ts +68 -0
- package/src/tasks/task-runner.ts +7 -5
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
- package/src/tools/apps/executors.ts +29 -4
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/filesystem/list.ts +93 -0
- package/src/tools/memory/register.ts +63 -46
- package/src/tools/permission-checker.ts +85 -1
- package/src/tools/registry.ts +4 -0
- package/src/tools/schedule/create.ts +3 -0
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +6 -0
- package/src/tools/shared/filesystem/errors.ts +5 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
- package/src/tools/shared/filesystem/image-read.ts +22 -85
- package/src/tools/shared/filesystem/types.ts +17 -0
- package/src/tools/shared/shell-output.ts +31 -2
- package/src/tools/subagent/abort.ts +12 -2
- package/src/tools/subagent/message.ts +9 -2
- package/src/tools/subagent/notify-parent.ts +79 -0
- package/src/tools/subagent/read.ts +29 -8
- package/src/tools/subagent/resolve.ts +21 -0
- package/src/tools/subagent/spawn.ts +2 -0
- package/src/tools/subagent/status.ts +11 -1
- package/src/tools/system/avatar-generator.ts +3 -3
- package/src/tools/system/register.ts +23 -0
- package/src/tools/system/set-permission-mode.ts +103 -0
- package/src/tools/terminal/parser.ts +30 -5
- package/src/tools/terminal/safe-env.ts +17 -1
- package/src/tools/tool-manifest.ts +9 -3
- package/src/tools/types.ts +2 -0
- package/src/util/browser.ts +25 -10
- package/src/util/bun-runtime.ts +172 -0
- package/src/util/logger.ts +1 -1
- package/src/util/platform.ts +50 -17
- package/src/watcher/providers/outlook-calendar.ts +343 -0
- package/src/watcher/providers/outlook.ts +198 -0
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
- package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
- package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
- package/src/workspace/migrations/029-seed-pkb.ts +84 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/top-level-renderer.ts +5 -9
- package/src/__tests__/cli-memory.test.ts +0 -372
- package/src/__tests__/clipboard.test.ts +0 -88
- package/src/__tests__/context-memory-e2e.test.ts +0 -415
- package/src/__tests__/journal-context.test.ts +0 -268
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
- package/src/__tests__/memory-query-builder.test.ts +0 -59
- package/src/__tests__/memory-recall-quality.test.ts +0 -1046
- package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
- package/src/__tests__/memory-regressions.test.ts +0 -3696
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
- package/src/cli/cli-memory.ts +0 -176
- package/src/daemon/conversation-memory.ts +0 -207
- package/src/memory/conversation-starters-cadence.ts +0 -74
- package/src/memory/items-extractor.ts +0 -860
- package/src/memory/job-handlers/batch-extraction.ts +0 -753
- package/src/memory/job-handlers/extraction.ts +0 -40
- package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
- package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
- package/src/memory/journal-memory.ts +0 -224
- package/src/memory/query-builder.ts +0 -47
- package/src/memory/query-expansion.ts +0 -83
- package/src/memory/retriever.test.ts +0 -1592
- package/src/memory/retriever.ts +0 -1331
- package/src/memory/search/formatting.test.ts +0 -140
- package/src/memory/search/formatting.ts +0 -262
- package/src/memory/search/mmr.ts +0 -139
- package/src/memory/search/ranking.ts +0 -15
- package/src/memory/search/staleness.ts +0 -40
- package/src/memory/search/tier-classifier.ts +0 -18
- package/src/memory/search/types.ts +0 -121
- package/src/prompts/journal-context.ts +0 -154
- package/src/tools/memory/definitions.ts +0 -69
- package/src/tools/memory/handlers.test.ts +0 -562
- package/src/tools/memory/handlers.ts +0 -434
- package/src/util/clipboard.ts +0 -34
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import {
|
|
3
|
+
existsSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
readdirSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
renameSync,
|
|
8
|
+
statSync,
|
|
9
|
+
writeFileSync,
|
|
10
|
+
} from "node:fs";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
|
|
13
|
+
// ─── SkillInstallMeta type ──────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
export interface SkillInstallMeta {
|
|
16
|
+
origin: "vellum" | "clawhub" | "skillssh" | "custom";
|
|
17
|
+
installedAt: string; // ISO 8601
|
|
18
|
+
installedBy?: string; // actorPrincipalId from auth context (identifies who initiated the install)
|
|
19
|
+
backfilledBy?: string; // set by migration that backfilled this file (e.g. "migration-026")
|
|
20
|
+
version?: string; // semver if known
|
|
21
|
+
slug?: string; // registry slug
|
|
22
|
+
sourceRepo?: string; // GitHub repo (e.g. "vercel-labs/agent-skills")
|
|
23
|
+
contentHash?: string; // SHA-256 content hash (v2:hex format)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ─── Atomic write helper ────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
function atomicWriteFile(filePath: string, content: string): void {
|
|
29
|
+
const dir = dirname(filePath);
|
|
30
|
+
mkdirSync(dir, { recursive: true });
|
|
31
|
+
const tmpPath = join(dir, `.tmp-${randomUUID()}`);
|
|
32
|
+
writeFileSync(tmpPath, content, "utf-8");
|
|
33
|
+
renameSync(tmpPath, filePath);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ─── Write install-meta.json ────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
const INSTALL_META_FILENAME = "install-meta.json";
|
|
39
|
+
const LEGACY_VERSION_FILENAME = "version.json";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Atomically write `install-meta.json` inside the skill directory.
|
|
43
|
+
*/
|
|
44
|
+
export function writeInstallMeta(
|
|
45
|
+
skillDir: string,
|
|
46
|
+
meta: SkillInstallMeta,
|
|
47
|
+
): void {
|
|
48
|
+
const filePath = join(skillDir, INSTALL_META_FILENAME);
|
|
49
|
+
atomicWriteFile(filePath, JSON.stringify(meta, null, 2) + "\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ─── Read install-meta.json (with legacy fallback) ──────────────────────────
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Reads `install-meta.json` from the skill directory. If not found, falls
|
|
56
|
+
* back to reading legacy `version.json` and inferring the origin:
|
|
57
|
+
*
|
|
58
|
+
* - Has `origin: "skills.sh"` -> `origin: "skillssh"`, copies `source` as
|
|
59
|
+
* `sourceRepo` and `skillSlug` as `slug`.
|
|
60
|
+
* - Has `version` but no `origin` field -> `origin: "vellum"`.
|
|
61
|
+
* - Otherwise -> `origin: "custom"`.
|
|
62
|
+
*
|
|
63
|
+
* Legacy files never have `installedBy`, so it will be `undefined` for
|
|
64
|
+
* backfilled skills.
|
|
65
|
+
*
|
|
66
|
+
* If neither file exists, returns `null`.
|
|
67
|
+
*/
|
|
68
|
+
export function readInstallMeta(skillDir: string): SkillInstallMeta | null {
|
|
69
|
+
// Try install-meta.json first
|
|
70
|
+
const metaPath = join(skillDir, INSTALL_META_FILENAME);
|
|
71
|
+
if (existsSync(metaPath)) {
|
|
72
|
+
try {
|
|
73
|
+
return JSON.parse(readFileSync(metaPath, "utf-8")) as SkillInstallMeta;
|
|
74
|
+
} catch {
|
|
75
|
+
// Malformed install-meta.json (partial write, manual edit, etc.) —
|
|
76
|
+
// fall through to the legacy version.json path so we don't lose
|
|
77
|
+
// provenance info when a valid legacy file exists.
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Fall back to legacy version.json
|
|
82
|
+
const legacyPath = join(skillDir, LEGACY_VERSION_FILENAME);
|
|
83
|
+
if (!existsSync(legacyPath)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const raw = JSON.parse(readFileSync(legacyPath, "utf-8")) as Record<
|
|
89
|
+
string,
|
|
90
|
+
unknown
|
|
91
|
+
>;
|
|
92
|
+
return inferFromLegacyVersionJson(raw);
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Infer a SkillInstallMeta from a legacy version.json object.
|
|
100
|
+
*/
|
|
101
|
+
function inferFromLegacyVersionJson(
|
|
102
|
+
raw: Record<string, unknown>,
|
|
103
|
+
): SkillInstallMeta {
|
|
104
|
+
// skills.sh origin: has `origin: "skills.sh"`
|
|
105
|
+
if (raw.origin === "skills.sh") {
|
|
106
|
+
return {
|
|
107
|
+
origin: "skillssh",
|
|
108
|
+
installedAt:
|
|
109
|
+
typeof raw.installedAt === "string"
|
|
110
|
+
? raw.installedAt
|
|
111
|
+
: new Date().toISOString(),
|
|
112
|
+
sourceRepo: typeof raw.source === "string" ? raw.source : undefined,
|
|
113
|
+
slug: typeof raw.skillSlug === "string" ? raw.skillSlug : undefined,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Vellum (first-party catalog) origin: has `version` but no `origin` field
|
|
118
|
+
if (typeof raw.version === "string" && !("origin" in raw)) {
|
|
119
|
+
return {
|
|
120
|
+
origin: "vellum",
|
|
121
|
+
installedAt:
|
|
122
|
+
typeof raw.installedAt === "string"
|
|
123
|
+
? raw.installedAt
|
|
124
|
+
: new Date().toISOString(),
|
|
125
|
+
version: raw.version,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Unknown format -> custom
|
|
130
|
+
return {
|
|
131
|
+
origin: "custom",
|
|
132
|
+
installedAt:
|
|
133
|
+
typeof raw.installedAt === "string"
|
|
134
|
+
? raw.installedAt
|
|
135
|
+
: new Date().toISOString(),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ─── Content hash computation ───────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Metadata files excluded from content hashing. These are written by the
|
|
143
|
+
* installer and must not contribute to the content hash — otherwise the hash
|
|
144
|
+
* stored inside `install-meta.json` would change after writing the file.
|
|
145
|
+
*/
|
|
146
|
+
const METADATA_FILENAMES = new Set([
|
|
147
|
+
INSTALL_META_FILENAME, // install-meta.json
|
|
148
|
+
LEGACY_VERSION_FILENAME, // version.json
|
|
149
|
+
]);
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Collect all file contents in a directory tree, sorted by relative path
|
|
153
|
+
* for determinism. Metadata files (`install-meta.json`, `version.json`) at
|
|
154
|
+
* the root level are excluded so the content hash covers only actual skill
|
|
155
|
+
* content.
|
|
156
|
+
*/
|
|
157
|
+
export function collectFileContents(
|
|
158
|
+
dir: string,
|
|
159
|
+
prefix = "",
|
|
160
|
+
): Array<{ relPath: string; content: Buffer }> {
|
|
161
|
+
const results: Array<{ relPath: string; content: Buffer }> = [];
|
|
162
|
+
if (!existsSync(dir)) return results;
|
|
163
|
+
|
|
164
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
165
|
+
for (const entry of entries) {
|
|
166
|
+
// Exclude metadata files at the root level (prefix === "").
|
|
167
|
+
// Only exclude actual files — a directory with a metadata name should
|
|
168
|
+
// still be traversed so nested content contributes to the hash.
|
|
169
|
+
if (!prefix && entry.isFile() && METADATA_FILENAMES.has(entry.name))
|
|
170
|
+
continue;
|
|
171
|
+
|
|
172
|
+
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
173
|
+
const fullPath = join(dir, entry.name);
|
|
174
|
+
if (entry.isDirectory()) {
|
|
175
|
+
results.push(...collectFileContents(fullPath, relPath));
|
|
176
|
+
} else if (entry.isFile()) {
|
|
177
|
+
results.push({ relPath, content: readFileSync(fullPath) });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return results.sort((a, b) => a.relPath.localeCompare(b.relPath));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Compute a SHA-256 hash over all files in a skill directory.
|
|
185
|
+
* Returns format: "v2:sha256hex" (version prefix added to support hash format
|
|
186
|
+
* evolution).
|
|
187
|
+
*
|
|
188
|
+
* This is the content hash used by the integrity manifest (trust-on-first-use).
|
|
189
|
+
* It differs from `computeSkillVersionHash` in `version-hash.ts`, which uses a
|
|
190
|
+
* different hashing strategy (v1: prefix) for version identity.
|
|
191
|
+
*/
|
|
192
|
+
export function computeSkillHash(skillDir: string): string | null {
|
|
193
|
+
if (!existsSync(skillDir) || !statSync(skillDir).isDirectory()) return null;
|
|
194
|
+
|
|
195
|
+
const files = collectFileContents(skillDir);
|
|
196
|
+
if (files.length === 0) return null;
|
|
197
|
+
|
|
198
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
199
|
+
for (const file of files) {
|
|
200
|
+
// Length-prefix each segment to prevent boundary ambiguity collisions
|
|
201
|
+
const pathBuf = Buffer.from(file.relPath, "utf-8");
|
|
202
|
+
hasher.update(`${pathBuf.length}:`);
|
|
203
|
+
hasher.update(pathBuf);
|
|
204
|
+
hasher.update(`${file.content.length}:`);
|
|
205
|
+
hasher.update(file.content);
|
|
206
|
+
}
|
|
207
|
+
return `v2:${hasher.digest("hex")}`;
|
|
208
|
+
}
|
|
@@ -11,9 +11,10 @@ import { dirname, join } from "node:path";
|
|
|
11
11
|
|
|
12
12
|
import { stringify as stringifyYaml } from "yaml";
|
|
13
13
|
|
|
14
|
+
import { deleteSkillCapabilityNode } from "../memory/graph/capability-seed.js";
|
|
14
15
|
import { getLogger } from "../util/logger.js";
|
|
15
16
|
import { getWorkspaceSkillsDir } from "../util/platform.js";
|
|
16
|
-
import {
|
|
17
|
+
import { writeInstallMeta } from "./install-meta.js";
|
|
17
18
|
|
|
18
19
|
const log = getLogger("managed-store");
|
|
19
20
|
|
|
@@ -165,15 +166,20 @@ function getVersionMetaPath(id: string): string {
|
|
|
165
166
|
return join(getManagedSkillDir(id), "version.json");
|
|
166
167
|
}
|
|
167
168
|
|
|
168
|
-
function writeVersionMeta(id: string, version: string): void {
|
|
169
|
-
const meta: SkillVersionMeta = {
|
|
170
|
-
version,
|
|
171
|
-
installedAt: new Date().toISOString(),
|
|
172
|
-
};
|
|
173
|
-
atomicWriteFile(getVersionMetaPath(id), JSON.stringify(meta, null, 2) + "\n");
|
|
174
|
-
}
|
|
175
|
-
|
|
176
169
|
export function readSkillVersion(id: string): string | null {
|
|
170
|
+
// Try install-meta.json first (new format)
|
|
171
|
+
const installMetaPath = join(getManagedSkillDir(id), "install-meta.json");
|
|
172
|
+
if (existsSync(installMetaPath)) {
|
|
173
|
+
try {
|
|
174
|
+
const raw = readFileSync(installMetaPath, "utf-8");
|
|
175
|
+
const meta = JSON.parse(raw) as { version?: string };
|
|
176
|
+
if (meta.version) return meta.version;
|
|
177
|
+
} catch {
|
|
178
|
+
// Fall through to legacy path
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Fall back to legacy version.json
|
|
177
183
|
const metaPath = getVersionMetaPath(id);
|
|
178
184
|
if (!existsSync(metaPath)) return null;
|
|
179
185
|
try {
|
|
@@ -197,6 +203,7 @@ interface CreateManagedSkillParams {
|
|
|
197
203
|
addToIndex?: boolean;
|
|
198
204
|
includes?: string[];
|
|
199
205
|
version?: string;
|
|
206
|
+
contactId?: string;
|
|
200
207
|
}
|
|
201
208
|
|
|
202
209
|
interface CreateManagedSkillResult {
|
|
@@ -259,14 +266,18 @@ export function createManagedSkill(
|
|
|
259
266
|
mkdirSync(skillDir, { recursive: true });
|
|
260
267
|
atomicWriteFile(skillFilePath, content);
|
|
261
268
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
// Write install metadata
|
|
270
|
+
writeInstallMeta(skillDir, {
|
|
271
|
+
origin: "custom",
|
|
272
|
+
installedAt: new Date().toISOString(),
|
|
273
|
+
...(params.version ? { version: params.version } : {}),
|
|
274
|
+
...(params.contactId ? { installedBy: params.contactId } : {}),
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Clean up legacy version.json if present (superseded by install-meta.json)
|
|
278
|
+
const metaPath = getVersionMetaPath(params.id);
|
|
279
|
+
if (existsSync(metaPath)) {
|
|
280
|
+
rmSync(metaPath);
|
|
270
281
|
}
|
|
271
282
|
|
|
272
283
|
log.info(
|
|
@@ -308,7 +319,7 @@ export function deleteManagedSkill(
|
|
|
308
319
|
}
|
|
309
320
|
|
|
310
321
|
rmSync(skillDir, { recursive: true });
|
|
311
|
-
|
|
322
|
+
deleteSkillCapabilityNode(id);
|
|
312
323
|
log.info({ id, path: skillDir }, "Deleted managed skill");
|
|
313
324
|
|
|
314
325
|
let indexUpdated = false;
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { getConfig } from "../config/loader.js";
|
|
5
|
-
import { resolveSkillStates } from "../config/skill-state.js";
|
|
6
|
-
import { loadSkillCatalog, type SkillSummary } from "../config/skills.js";
|
|
7
|
-
import { getDb } from "../memory/db.js";
|
|
8
|
-
import { computeMemoryFingerprint } from "../memory/fingerprint.js";
|
|
9
|
-
import { enqueueMemoryJob } from "../memory/jobs-store.js";
|
|
10
|
-
import { memoryItems } from "../memory/schema.js";
|
|
11
|
-
import { getLogger } from "../util/logger.js";
|
|
12
|
-
|
|
13
|
-
const log = getLogger("skill-memory");
|
|
1
|
+
import type { SkillSummary } from "../config/skills.js";
|
|
2
|
+
import type { CatalogSkill } from "./catalog-install.js";
|
|
14
3
|
|
|
15
4
|
/**
|
|
16
5
|
* Generic input for building capability statements.
|
|
@@ -40,222 +29,16 @@ export function fromSkillSummary(entry: SkillSummary): SkillCapabilityInput {
|
|
|
40
29
|
}
|
|
41
30
|
|
|
42
31
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*/
|
|
46
|
-
export function buildCapabilityStatement(input: SkillCapabilityInput): string {
|
|
47
|
-
const { displayName, activationHints, avoidWhen } = input;
|
|
48
|
-
|
|
49
|
-
let statement = `The "${displayName}" skill (${input.id}) is available. ${input.description}.`;
|
|
50
|
-
if (activationHints && activationHints.length > 0) {
|
|
51
|
-
statement += ` Use when: ${activationHints.join("; ")}.`;
|
|
52
|
-
}
|
|
53
|
-
if (avoidWhen && avoidWhen.length > 0) {
|
|
54
|
-
statement += ` Avoid when: ${avoidWhen.join("; ")}.`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Truncate to 500 chars max
|
|
58
|
-
if (statement.length > 500) {
|
|
59
|
-
statement = statement.slice(0, 500);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return statement;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Upsert a capability memory item for a skill.
|
|
67
|
-
* Best-effort: errors are logged but never thrown.
|
|
68
|
-
*/
|
|
69
|
-
export function upsertSkillCapabilityMemory(
|
|
70
|
-
skillId: string,
|
|
71
|
-
input: SkillCapabilityInput,
|
|
72
|
-
): void {
|
|
73
|
-
try {
|
|
74
|
-
const db = getDb();
|
|
75
|
-
const subject = `skill:${skillId}`;
|
|
76
|
-
const statement = buildCapabilityStatement(input);
|
|
77
|
-
const kind = "capability";
|
|
78
|
-
const scopeId = "default";
|
|
79
|
-
const confidence = 1.0;
|
|
80
|
-
const importance = 0.7;
|
|
81
|
-
const fingerprint = computeMemoryFingerprint(
|
|
82
|
-
scopeId,
|
|
83
|
-
kind,
|
|
84
|
-
subject,
|
|
85
|
-
statement,
|
|
86
|
-
);
|
|
87
|
-
const now = Date.now();
|
|
88
|
-
|
|
89
|
-
const existing = db
|
|
90
|
-
.select()
|
|
91
|
-
.from(memoryItems)
|
|
92
|
-
.where(
|
|
93
|
-
and(
|
|
94
|
-
eq(memoryItems.kind, kind),
|
|
95
|
-
eq(memoryItems.subject, subject),
|
|
96
|
-
eq(memoryItems.scopeId, scopeId),
|
|
97
|
-
),
|
|
98
|
-
)
|
|
99
|
-
.get();
|
|
100
|
-
|
|
101
|
-
if (existing) {
|
|
102
|
-
if (
|
|
103
|
-
existing.status === "active" &&
|
|
104
|
-
existing.fingerprint === fingerprint
|
|
105
|
-
) {
|
|
106
|
-
// Same content — just touch lastSeenAt
|
|
107
|
-
db.update(memoryItems)
|
|
108
|
-
.set({ lastSeenAt: now })
|
|
109
|
-
.where(eq(memoryItems.id, existing.id))
|
|
110
|
-
.run();
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (existing.status === "active") {
|
|
115
|
-
// Content changed — update statement and fingerprint
|
|
116
|
-
db.update(memoryItems)
|
|
117
|
-
.set({
|
|
118
|
-
statement,
|
|
119
|
-
fingerprint,
|
|
120
|
-
lastSeenAt: now,
|
|
121
|
-
})
|
|
122
|
-
.where(eq(memoryItems.id, existing.id))
|
|
123
|
-
.run();
|
|
124
|
-
enqueueMemoryJob("embed_item", { itemId: existing.id });
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// status === "deleted" or other — reactivate
|
|
129
|
-
db.update(memoryItems)
|
|
130
|
-
.set({
|
|
131
|
-
status: "active",
|
|
132
|
-
statement,
|
|
133
|
-
fingerprint,
|
|
134
|
-
lastSeenAt: now,
|
|
135
|
-
firstSeenAt: now,
|
|
136
|
-
})
|
|
137
|
-
.where(eq(memoryItems.id, existing.id))
|
|
138
|
-
.run();
|
|
139
|
-
enqueueMemoryJob("embed_item", { itemId: existing.id });
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// No existing — insert new row
|
|
144
|
-
const id = uuid();
|
|
145
|
-
db.insert(memoryItems)
|
|
146
|
-
.values({
|
|
147
|
-
id,
|
|
148
|
-
kind,
|
|
149
|
-
subject,
|
|
150
|
-
statement,
|
|
151
|
-
status: "active",
|
|
152
|
-
confidence,
|
|
153
|
-
importance,
|
|
154
|
-
fingerprint,
|
|
155
|
-
sourceType: "extraction",
|
|
156
|
-
scopeId,
|
|
157
|
-
firstSeenAt: now,
|
|
158
|
-
lastSeenAt: now,
|
|
159
|
-
})
|
|
160
|
-
.run();
|
|
161
|
-
enqueueMemoryJob("embed_item", { itemId: id });
|
|
162
|
-
} catch (err) {
|
|
163
|
-
log.warn({ err, skillId }, "Failed to upsert skill capability memory");
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Soft-delete the capability memory item for a skill.
|
|
169
|
-
* Best-effort: errors are logged but never thrown.
|
|
32
|
+
* Convert a CatalogSkill to a SkillCapabilityInput.
|
|
33
|
+
* CatalogSkill stores display-name and hints inside nested metadata.
|
|
170
34
|
*/
|
|
171
|
-
export function
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
.from(memoryItems)
|
|
180
|
-
.where(
|
|
181
|
-
and(
|
|
182
|
-
eq(memoryItems.kind, "capability"),
|
|
183
|
-
eq(memoryItems.subject, subject),
|
|
184
|
-
eq(memoryItems.scopeId, "default"),
|
|
185
|
-
),
|
|
186
|
-
)
|
|
187
|
-
.get();
|
|
188
|
-
|
|
189
|
-
if (existing && existing.status !== "deleted") {
|
|
190
|
-
db.update(memoryItems)
|
|
191
|
-
.set({ status: "deleted", lastSeenAt: now })
|
|
192
|
-
.where(eq(memoryItems.id, existing.id))
|
|
193
|
-
.run();
|
|
194
|
-
}
|
|
195
|
-
} catch (err) {
|
|
196
|
-
log.warn({ err, skillId }, "Failed to delete skill capability memory");
|
|
197
|
-
}
|
|
35
|
+
export function fromCatalogSkill(entry: CatalogSkill): SkillCapabilityInput {
|
|
36
|
+
return {
|
|
37
|
+
id: entry.id,
|
|
38
|
+
displayName: entry.metadata?.vellum?.["display-name"] ?? entry.name,
|
|
39
|
+
description: entry.description,
|
|
40
|
+
activationHints: entry.metadata?.vellum?.["activation-hints"],
|
|
41
|
+
avoidWhen: entry.metadata?.vellum?.["avoid-when"],
|
|
42
|
+
};
|
|
198
43
|
}
|
|
199
44
|
|
|
200
|
-
/**
|
|
201
|
-
* Seed capability memory items for all enabled skills (bundled, managed, workspace, extra).
|
|
202
|
-
* Prunes stale entries whose skills are no longer in the enabled set.
|
|
203
|
-
* Best-effort: errors are logged but never thrown.
|
|
204
|
-
*/
|
|
205
|
-
export function seedCatalogSkillMemories(): void {
|
|
206
|
-
try {
|
|
207
|
-
const catalog = loadSkillCatalog();
|
|
208
|
-
const config = getConfig();
|
|
209
|
-
const resolved = resolveSkillStates(catalog, config);
|
|
210
|
-
const enabled = resolved.filter((r) => r.state === "enabled");
|
|
211
|
-
|
|
212
|
-
const catalogIds = new Set<string>();
|
|
213
|
-
for (const { summary } of enabled) {
|
|
214
|
-
catalogIds.add(summary.id);
|
|
215
|
-
const input = fromSkillSummary(summary);
|
|
216
|
-
|
|
217
|
-
// Enrich mcp-setup description with configured server names
|
|
218
|
-
if (summary.id === "mcp-setup") {
|
|
219
|
-
const servers = config.mcp?.servers;
|
|
220
|
-
if (servers) {
|
|
221
|
-
const names = Object.keys(servers).filter(
|
|
222
|
-
(name) => servers[name]?.enabled !== false,
|
|
223
|
-
);
|
|
224
|
-
if (names.length > 0) {
|
|
225
|
-
input.description += ` Configured: ${names.join(", ")}`;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
upsertSkillCapabilityMemory(summary.id, input);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// Prune stale capability memories for skills no longer in the enabled set
|
|
234
|
-
const db = getDb();
|
|
235
|
-
const allCapabilities = db
|
|
236
|
-
.select()
|
|
237
|
-
.from(memoryItems)
|
|
238
|
-
.where(
|
|
239
|
-
and(
|
|
240
|
-
eq(memoryItems.kind, "capability"),
|
|
241
|
-
eq(memoryItems.scopeId, "default"),
|
|
242
|
-
eq(memoryItems.status, "active"),
|
|
243
|
-
),
|
|
244
|
-
)
|
|
245
|
-
.all();
|
|
246
|
-
|
|
247
|
-
const now = Date.now();
|
|
248
|
-
for (const item of allCapabilities) {
|
|
249
|
-
if (!item.subject.startsWith("skill:")) continue;
|
|
250
|
-
const itemSkillId = item.subject.replace("skill:", "");
|
|
251
|
-
if (!catalogIds.has(itemSkillId)) {
|
|
252
|
-
db.update(memoryItems)
|
|
253
|
-
.set({ status: "deleted", lastSeenAt: now })
|
|
254
|
-
.where(eq(memoryItems.id, item.id))
|
|
255
|
-
.run();
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
} catch (err) {
|
|
259
|
-
log.warn({ err }, "Failed to seed catalog skill memories");
|
|
260
|
-
}
|
|
261
|
-
}
|
|
@@ -5,6 +5,7 @@ import { dirname, join, resolve, sep } from "node:path";
|
|
|
5
5
|
|
|
6
6
|
import { getWorkspaceSkillsDir } from "../util/platform.js";
|
|
7
7
|
import { upsertSkillsIndex } from "./catalog-install.js";
|
|
8
|
+
import { computeSkillHash, writeInstallMeta } from "./install-meta.js";
|
|
8
9
|
|
|
9
10
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
10
11
|
|
|
@@ -434,9 +435,12 @@ export function validateSkillSlug(slug: string): void {
|
|
|
434
435
|
* 1. Validates the skill slug for path safety
|
|
435
436
|
* 2. Fetches all files from `skills/<skillSlug>/` in the source repo
|
|
436
437
|
* 3. Writes them to `<workspace>/skills/<skillSlug>/` with path traversal protection
|
|
437
|
-
* 4. Writes `
|
|
438
|
-
* 5.
|
|
439
|
-
* 6.
|
|
438
|
+
* 4. Writes `install-meta.json` with origin metadata
|
|
439
|
+
* 5. Installs npm dependencies (if package.json exists)
|
|
440
|
+
* 6. Updates SKILLS.md index
|
|
441
|
+
*
|
|
442
|
+
* Auto-enable and memory seeding are handled by the caller (e.g.
|
|
443
|
+
* `postInstallSkill()` in the daemon, or left to the user for CLI installs).
|
|
440
444
|
*/
|
|
441
445
|
export async function installExternalSkill(
|
|
442
446
|
owner: string,
|
|
@@ -444,6 +448,7 @@ export async function installExternalSkill(
|
|
|
444
448
|
skillSlug: string,
|
|
445
449
|
overwrite: boolean,
|
|
446
450
|
ref?: string,
|
|
451
|
+
contactId?: string,
|
|
447
452
|
): Promise<void> {
|
|
448
453
|
// Validate slug before using in filesystem paths
|
|
449
454
|
validateSkillSlug(skillSlug);
|
|
@@ -480,20 +485,19 @@ export async function installExternalSkill(
|
|
|
480
485
|
writeFileSync(destPath, content, "utf-8");
|
|
481
486
|
}
|
|
482
487
|
|
|
483
|
-
// Write
|
|
484
|
-
|
|
485
|
-
origin: "
|
|
486
|
-
|
|
487
|
-
|
|
488
|
+
// Write install metadata
|
|
489
|
+
writeInstallMeta(skillDir, {
|
|
490
|
+
origin: "skillssh",
|
|
491
|
+
slug: skillSlug,
|
|
492
|
+
sourceRepo: `${owner}/${repo}`,
|
|
488
493
|
installedAt: new Date().toISOString(),
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
JSON.stringify(meta, null, 2) + "\n",
|
|
493
|
-
"utf-8",
|
|
494
|
-
);
|
|
494
|
+
...(contactId ? { installedBy: contactId } : {}),
|
|
495
|
+
contentHash: computeSkillHash(skillDir) ?? undefined,
|
|
496
|
+
});
|
|
495
497
|
|
|
496
|
-
//
|
|
498
|
+
// Post-install: install dependencies first, then index the skill.
|
|
499
|
+
// Running bun install before upsertSkillsIndex ensures we don't index a
|
|
500
|
+
// skill whose dependencies failed to install.
|
|
497
501
|
if (existsSync(join(skillDir, "package.json"))) {
|
|
498
502
|
const bunPath = `${homedir()}/.bun/bin`;
|
|
499
503
|
execSync("bun install", {
|
|
@@ -502,7 +506,5 @@ export async function installExternalSkill(
|
|
|
502
506
|
env: { ...process.env, PATH: `${bunPath}:${process.env.PATH}` },
|
|
503
507
|
});
|
|
504
508
|
}
|
|
505
|
-
|
|
506
|
-
// Register in SKILLS.md only after files are written and deps installed
|
|
507
509
|
upsertSkillsIndex(skillSlug);
|
|
508
510
|
}
|
package/src/subagent/index.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
export { SubagentManager } from "./manager.js";
|
|
2
|
-
export type {
|
|
3
|
-
|
|
1
|
+
export { mergeSkillIds, SubagentManager } from "./manager.js";
|
|
2
|
+
export type {
|
|
3
|
+
SubagentConfig,
|
|
4
|
+
SubagentRole,
|
|
5
|
+
SubagentRoleConfig,
|
|
6
|
+
SubagentState,
|
|
7
|
+
SubagentStatus,
|
|
8
|
+
} from "./types.js";
|
|
9
|
+
export {
|
|
10
|
+
SUBAGENT_LIMITS,
|
|
11
|
+
SUBAGENT_ROLE_REGISTRY,
|
|
12
|
+
TERMINAL_STATUSES,
|
|
13
|
+
} from "./types.js";
|
|
4
14
|
|
|
5
15
|
import { SubagentManager } from "./manager.js";
|
|
6
16
|
|