@vellumai/assistant 0.3.19 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/ARCHITECTURE.md +151 -15
  2. package/Dockerfile +1 -0
  3. package/README.md +40 -4
  4. package/bun.lock +139 -2
  5. package/docs/architecture/integrations.md +7 -11
  6. package/package.json +2 -1
  7. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +54 -0
  8. package/src/__tests__/approval-primitive.test.ts +540 -0
  9. package/src/__tests__/assistant-feature-flag-guard.test.ts +206 -0
  10. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +198 -0
  11. package/src/__tests__/assistant-feature-flags-integration.test.ts +272 -0
  12. package/src/__tests__/call-controller.test.ts +439 -108
  13. package/src/__tests__/channel-invite-transport.test.ts +264 -0
  14. package/src/__tests__/cli.test.ts +42 -1
  15. package/src/__tests__/config-schema.test.ts +11 -127
  16. package/src/__tests__/config-watcher.test.ts +0 -8
  17. package/src/__tests__/daemon-lifecycle.test.ts +1 -0
  18. package/src/__tests__/daemon-server-session-init.test.ts +8 -2
  19. package/src/__tests__/diff.test.ts +22 -0
  20. package/src/__tests__/guardian-action-copy-generator.test.ts +5 -0
  21. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +300 -32
  22. package/src/__tests__/guardian-action-late-reply.test.ts +546 -1
  23. package/src/__tests__/guardian-actions-endpoint.test.ts +774 -0
  24. package/src/__tests__/guardian-control-plane-policy.test.ts +36 -3
  25. package/src/__tests__/guardian-dispatch.test.ts +124 -0
  26. package/src/__tests__/guardian-grant-minting.test.ts +6 -17
  27. package/src/__tests__/inbound-invite-redemption.test.ts +367 -0
  28. package/src/__tests__/invite-redemption-service.test.ts +306 -0
  29. package/src/__tests__/ipc-snapshot.test.ts +57 -0
  30. package/src/__tests__/notification-decision-fallback.test.ts +88 -0
  31. package/src/__tests__/sandbox-diagnostics.test.ts +6 -249
  32. package/src/__tests__/sandbox-host-parity.test.ts +6 -13
  33. package/src/__tests__/scoped-approval-grants.test.ts +6 -6
  34. package/src/__tests__/scoped-grant-security-matrix.test.ts +5 -4
  35. package/src/__tests__/script-proxy-session-manager.test.ts +1 -19
  36. package/src/__tests__/session-load-history-repair.test.ts +169 -2
  37. package/src/__tests__/session-runtime-assembly.test.ts +33 -5
  38. package/src/__tests__/skill-feature-flags-integration.test.ts +171 -0
  39. package/src/__tests__/skill-feature-flags.test.ts +188 -0
  40. package/src/__tests__/skill-load-feature-flag.test.ts +141 -0
  41. package/src/__tests__/skill-mirror-parity.test.ts +1 -0
  42. package/src/__tests__/skill-projection-feature-flag.test.ts +363 -0
  43. package/src/__tests__/system-prompt.test.ts +1 -1
  44. package/src/__tests__/terminal-sandbox.test.ts +142 -9
  45. package/src/__tests__/terminal-tools.test.ts +2 -93
  46. package/src/__tests__/thread-seed-composer.test.ts +18 -0
  47. package/src/__tests__/tool-approval-handler.test.ts +350 -0
  48. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +8 -10
  49. package/src/__tests__/voice-scoped-grant-consumer.test.ts +46 -84
  50. package/src/agent/loop.ts +36 -1
  51. package/src/approvals/approval-primitive.ts +381 -0
  52. package/src/approvals/guardian-decision-primitive.ts +191 -0
  53. package/src/calls/call-controller.ts +252 -209
  54. package/src/calls/call-domain.ts +44 -6
  55. package/src/calls/guardian-dispatch.ts +48 -0
  56. package/src/calls/types.ts +1 -1
  57. package/src/calls/voice-session-bridge.ts +46 -30
  58. package/src/cli/core-commands.ts +0 -4
  59. package/src/cli/mcp.ts +58 -0
  60. package/src/cli.ts +76 -34
  61. package/src/config/__tests__/feature-flag-registry-guard.test.ts +179 -0
  62. package/src/config/assistant-feature-flags.ts +162 -0
  63. package/src/config/bundled-skills/api-mapping/icon.svg +18 -0
  64. package/src/config/bundled-skills/messaging/TOOLS.json +30 -0
  65. package/src/config/bundled-skills/messaging/tools/slack-delete-message.ts +24 -0
  66. package/src/config/bundled-skills/notifications/SKILL.md +1 -1
  67. package/src/config/bundled-skills/reminder/SKILL.md +49 -2
  68. package/src/config/bundled-skills/time-based-actions/SKILL.md +49 -2
  69. package/src/config/bundled-skills/voice-setup/SKILL.md +122 -0
  70. package/src/config/core-schema.ts +1 -1
  71. package/src/config/env-registry.ts +10 -0
  72. package/src/config/feature-flag-registry.json +61 -0
  73. package/src/config/loader.ts +22 -1
  74. package/src/config/mcp-schema.ts +46 -0
  75. package/src/config/sandbox-schema.ts +0 -39
  76. package/src/config/schema.ts +18 -2
  77. package/src/config/skill-state.ts +34 -0
  78. package/src/config/skills-schema.ts +0 -1
  79. package/src/config/skills.ts +9 -0
  80. package/src/config/system-prompt.ts +110 -46
  81. package/src/config/templates/SOUL.md +1 -1
  82. package/src/config/types.ts +19 -1
  83. package/src/config/vellum-skills/catalog.json +1 -1
  84. package/src/config/vellum-skills/guardian-verify-setup/SKILL.md +1 -0
  85. package/src/config/vellum-skills/sms-setup/SKILL.md +1 -1
  86. package/src/config/vellum-skills/telegram-setup/SKILL.md +6 -5
  87. package/src/config/vellum-skills/trusted-contacts/SKILL.md +105 -3
  88. package/src/config/vellum-skills/twilio-setup/SKILL.md +1 -1
  89. package/src/daemon/config-watcher.ts +0 -1
  90. package/src/daemon/daemon-control.ts +1 -1
  91. package/src/daemon/guardian-invite-intent.ts +124 -0
  92. package/src/daemon/handlers/avatar.ts +68 -0
  93. package/src/daemon/handlers/browser.ts +2 -2
  94. package/src/daemon/handlers/guardian-actions.ts +120 -0
  95. package/src/daemon/handlers/index.ts +4 -0
  96. package/src/daemon/handlers/sessions.ts +19 -0
  97. package/src/daemon/handlers/shared.ts +3 -1
  98. package/src/daemon/install-cli-launchers.ts +58 -13
  99. package/src/daemon/ipc-contract/guardian-actions.ts +53 -0
  100. package/src/daemon/ipc-contract/sessions.ts +8 -2
  101. package/src/daemon/ipc-contract/settings.ts +25 -2
  102. package/src/daemon/ipc-contract-inventory.json +10 -0
  103. package/src/daemon/ipc-contract.ts +4 -0
  104. package/src/daemon/lifecycle.ts +14 -2
  105. package/src/daemon/main.ts +1 -0
  106. package/src/daemon/providers-setup.ts +26 -1
  107. package/src/daemon/server.ts +1 -0
  108. package/src/daemon/session-lifecycle.ts +52 -7
  109. package/src/daemon/session-memory.ts +45 -0
  110. package/src/daemon/session-process.ts +258 -432
  111. package/src/daemon/session-runtime-assembly.ts +12 -0
  112. package/src/daemon/session-skill-tools.ts +14 -1
  113. package/src/daemon/session-tool-setup.ts +5 -0
  114. package/src/daemon/session.ts +11 -0
  115. package/src/daemon/shutdown-handlers.ts +11 -0
  116. package/src/daemon/tool-side-effects.ts +35 -9
  117. package/src/index.ts +2 -2
  118. package/src/mcp/client.ts +152 -0
  119. package/src/mcp/manager.ts +139 -0
  120. package/src/memory/conversation-display-order-migration.ts +44 -0
  121. package/src/memory/conversation-queries.ts +2 -0
  122. package/src/memory/conversation-store.ts +91 -0
  123. package/src/memory/db-init.ts +5 -1
  124. package/src/memory/embedding-local.ts +13 -8
  125. package/src/memory/guardian-action-store.ts +125 -2
  126. package/src/memory/ingress-invite-store.ts +95 -1
  127. package/src/memory/migrations/035-guardian-action-supersession.ts +23 -0
  128. package/src/memory/migrations/index.ts +2 -1
  129. package/src/memory/schema.ts +5 -1
  130. package/src/memory/scoped-approval-grants.ts +14 -5
  131. package/src/messaging/providers/slack/client.ts +12 -0
  132. package/src/messaging/providers/slack/types.ts +5 -0
  133. package/src/notifications/decision-engine.ts +49 -12
  134. package/src/notifications/emit-signal.ts +7 -0
  135. package/src/notifications/signal.ts +7 -0
  136. package/src/notifications/thread-seed-composer.ts +2 -1
  137. package/src/runtime/channel-approval-types.ts +16 -6
  138. package/src/runtime/channel-approvals.ts +19 -15
  139. package/src/runtime/channel-invite-transport.ts +85 -0
  140. package/src/runtime/channel-invite-transports/telegram.ts +105 -0
  141. package/src/runtime/guardian-action-grant-minter.ts +92 -35
  142. package/src/runtime/guardian-action-message-composer.ts +30 -0
  143. package/src/runtime/guardian-decision-types.ts +91 -0
  144. package/src/runtime/http-server.ts +23 -1
  145. package/src/runtime/ingress-service.ts +22 -0
  146. package/src/runtime/invite-redemption-service.ts +181 -0
  147. package/src/runtime/invite-redemption-templates.ts +39 -0
  148. package/src/runtime/routes/call-routes.ts +2 -1
  149. package/src/runtime/routes/guardian-action-routes.ts +206 -0
  150. package/src/runtime/routes/guardian-approval-interception.ts +66 -190
  151. package/src/runtime/routes/identity-routes.ts +73 -0
  152. package/src/runtime/routes/inbound-message-handler.ts +486 -394
  153. package/src/runtime/routes/pairing-routes.ts +4 -0
  154. package/src/security/encrypted-store.ts +31 -17
  155. package/src/security/keychain.ts +176 -2
  156. package/src/security/secure-keys.ts +97 -0
  157. package/src/security/tool-approval-digest.ts +1 -1
  158. package/src/tools/browser/browser-execution.ts +2 -2
  159. package/src/tools/browser/browser-manager.ts +46 -32
  160. package/src/tools/browser/browser-screencast.ts +2 -2
  161. package/src/tools/calls/call-start.ts +1 -1
  162. package/src/tools/executor.ts +22 -17
  163. package/src/tools/mcp/mcp-tool-factory.ts +100 -0
  164. package/src/tools/network/script-proxy/session-manager.ts +1 -5
  165. package/src/tools/registry.ts +64 -1
  166. package/src/tools/skills/load.ts +22 -8
  167. package/src/tools/system/avatar-generator.ts +119 -0
  168. package/src/tools/system/navigate-settings.ts +65 -0
  169. package/src/tools/system/open-system-settings.ts +75 -0
  170. package/src/tools/system/voice-config.ts +121 -32
  171. package/src/tools/terminal/backends/native.ts +40 -19
  172. package/src/tools/terminal/backends/types.ts +3 -3
  173. package/src/tools/terminal/parser.ts +1 -1
  174. package/src/tools/terminal/sandbox-diagnostics.ts +6 -87
  175. package/src/tools/terminal/sandbox.ts +1 -12
  176. package/src/tools/terminal/shell.ts +3 -31
  177. package/src/tools/tool-approval-handler.ts +141 -3
  178. package/src/tools/tool-manifest.ts +6 -0
  179. package/src/tools/types.ts +10 -2
  180. package/src/util/diff.ts +36 -13
  181. package/Dockerfile.sandbox +0 -5
  182. package/src/__tests__/doordash-client.test.ts +0 -187
  183. package/src/__tests__/doordash-session.test.ts +0 -154
  184. package/src/__tests__/signup-e2e.test.ts +0 -354
  185. package/src/__tests__/terminal-sandbox-docker.test.ts +0 -1065
  186. package/src/__tests__/terminal-sandbox.integration.test.ts +0 -180
  187. package/src/cli/doordash.ts +0 -1057
  188. package/src/config/bundled-skills/doordash/SKILL.md +0 -163
  189. package/src/config/templates/LOOKS.md +0 -25
  190. package/src/doordash/cart-queries.ts +0 -787
  191. package/src/doordash/client.ts +0 -1016
  192. package/src/doordash/order-queries.ts +0 -85
  193. package/src/doordash/queries.ts +0 -13
  194. package/src/doordash/query-extractor.ts +0 -94
  195. package/src/doordash/search-queries.ts +0 -203
  196. package/src/doordash/session.ts +0 -84
  197. package/src/doordash/store-queries.ts +0 -246
  198. package/src/doordash/types.ts +0 -367
  199. package/src/tools/terminal/backends/docker.ts +0 -379
@@ -1,180 +0,0 @@
1
- /**
2
- * Runtime-gated Docker integration tests.
3
- *
4
- * These tests run real Docker containers — they are skipped automatically
5
- * when Docker is not available or the sandbox image is not pulled locally.
6
- * To run them locally:
7
- * 1. Install Docker Desktop / Docker Engine
8
- * 2. docker pull <configured sandbox image>
9
- * 3. bun test src/__tests__/terminal-sandbox.integration.test.ts
10
- */
11
-
12
- import { execFileSync, spawnSync } from 'node:child_process';
13
- import {
14
- existsSync,
15
- mkdirSync,
16
- mkdtempSync,
17
- readFileSync,
18
- realpathSync,
19
- rmSync,
20
- statSync,
21
- writeFileSync,
22
- } from 'node:fs';
23
- import { join } from 'node:path';
24
-
25
- import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
26
-
27
- import { DEFAULT_CONFIG } from '../config/defaults.js';
28
- import { getSandboxWorkingDir } from '../util/platform.js';
29
-
30
- // ---------------------------------------------------------------------------
31
- // Runtime gate: skip entire file if Docker is not usable
32
- // ---------------------------------------------------------------------------
33
-
34
- function dockerAvailable(): boolean {
35
- try {
36
- execFileSync('docker', ['info'], { stdio: 'ignore', timeout: 10000 });
37
- return true;
38
- } catch {
39
- return false;
40
- }
41
- }
42
-
43
- const IMAGE = DEFAULT_CONFIG.sandbox.docker.image;
44
-
45
- function imageAvailable(): boolean {
46
- try {
47
- execFileSync('docker', ['image', 'inspect', IMAGE], {
48
- stdio: 'ignore',
49
- timeout: 10000,
50
- });
51
- return true;
52
- } catch {
53
- return false;
54
- }
55
- }
56
-
57
- const DOCKER_OK = dockerAvailable() && imageAvailable();
58
-
59
- // ---------------------------------------------------------------------------
60
- // Helpers
61
- // ---------------------------------------------------------------------------
62
-
63
- let sandboxRoot: string;
64
-
65
- beforeAll(() => {
66
- if (!DOCKER_OK) return;
67
- const parent = getSandboxWorkingDir();
68
- if (!existsSync(parent)) {
69
- mkdirSync(parent, { recursive: true });
70
- }
71
- sandboxRoot = realpathSync(mkdtempSync(join(parent, 'docker-integ-')));
72
- });
73
-
74
- afterAll(() => {
75
- if (sandboxRoot && existsSync(sandboxRoot)) {
76
- rmSync(sandboxRoot, { recursive: true, force: true });
77
- }
78
- });
79
-
80
- interface DockerRunOptions {
81
- /** Run as root instead of the host UID:GID. Useful for testing filesystem-level protections. */
82
- asRoot?: boolean;
83
- }
84
-
85
- /** Run a command inside a Docker container with the sandbox root mounted. */
86
- function dockerRun(cmd: string, opts?: DockerRunOptions): { stdout: string; exitCode: number } {
87
- const uid = process.getuid?.() ?? 1000;
88
- const gid = process.getgid?.() ?? 1000;
89
- const userArgs = opts?.asRoot ? ['--user', '0:0'] : ['--user', `${uid}:${gid}`];
90
- const result = spawnSync('docker', [
91
- 'run', '--rm',
92
- '--network=none',
93
- '--cap-drop=ALL',
94
- '--security-opt=no-new-privileges',
95
- '--read-only',
96
- '--tmpfs', '/tmp:rw,nosuid,nodev,noexec',
97
- '--mount', `type=bind,src=${sandboxRoot},dst=/workspace`,
98
- '--workdir', '/workspace',
99
- ...userArgs,
100
- IMAGE,
101
- 'bash', '-c', cmd,
102
- ], { timeout: 30000, encoding: 'utf-8' });
103
- return {
104
- stdout: (result.stdout ?? '').trim(),
105
- exitCode: result.status ?? -1,
106
- };
107
- }
108
-
109
- // ---------------------------------------------------------------------------
110
- // Tests
111
- // ---------------------------------------------------------------------------
112
-
113
- describe.skipIf(!DOCKER_OK)('Docker integration: write inside sandbox', () => {
114
- test('writing a file inside /workspace succeeds', () => {
115
- const { exitCode } = dockerRun('echo "hello" > /workspace/test-write.txt && cat /workspace/test-write.txt');
116
- expect(exitCode).toBe(0);
117
- // Verify the file appeared on the host
118
- const hostPath = join(sandboxRoot, 'test-write.txt');
119
- expect(existsSync(hostPath)).toBe(true);
120
- expect(readFileSync(hostPath, 'utf-8').trim()).toBe('hello');
121
- });
122
-
123
- test('creating nested directories inside /workspace succeeds', () => {
124
- const { exitCode, stdout } = dockerRun('mkdir -p /workspace/a/b/c && echo ok');
125
- expect(exitCode).toBe(0);
126
- expect(stdout).toBe('ok');
127
- expect(existsSync(join(sandboxRoot, 'a/b/c'))).toBe(true);
128
- });
129
- });
130
-
131
- describe.skipIf(!DOCKER_OK)('Docker integration: write outside workspace fails', () => {
132
- // Run as root so Unix permissions are not a factor — the read-only
133
- // filesystem mount is the only thing preventing these writes.
134
- test('writing to /etc inside container fails (read-only root)', () => {
135
- const { exitCode } = dockerRun('touch /etc/evil 2>/dev/null', { asRoot: true });
136
- expect(exitCode).not.toBe(0);
137
- });
138
-
139
- test('writing to /home inside container fails (read-only root)', () => {
140
- const { exitCode } = dockerRun('touch /home/evil 2>/dev/null', { asRoot: true });
141
- expect(exitCode).not.toBe(0);
142
- });
143
-
144
- test('writing to /tmp succeeds (tmpfs mount)', () => {
145
- // /tmp is an explicit tmpfs mount so writes should work
146
- const { exitCode, stdout } = dockerRun('echo ok > /tmp/test.txt && cat /tmp/test.txt');
147
- expect(exitCode).toBe(0);
148
- expect(stdout).toBe('ok');
149
- });
150
- });
151
-
152
- describe.skipIf(!DOCKER_OK)('Docker integration: host-writable files', () => {
153
- test('files created in container are owned by host UID:GID', () => {
154
- const filename = 'host-owner-test.txt';
155
- dockerRun(`echo "owned" > /workspace/${filename}`);
156
- const hostPath = join(sandboxRoot, filename);
157
- expect(existsSync(hostPath)).toBe(true);
158
- const stat = statSync(hostPath);
159
- const expectedUid = process.getuid?.() ?? 1000;
160
- const expectedGid = process.getgid?.() ?? 1000;
161
- expect(stat.uid).toBe(expectedUid);
162
- expect(stat.gid).toBe(expectedGid);
163
- });
164
-
165
- test('host can read files created by container', () => {
166
- const filename = 'host-readable-test.txt';
167
- const content = 'container-created-content';
168
- dockerRun(`echo "${content}" > /workspace/${filename}`);
169
- const hostPath = join(sandboxRoot, filename);
170
- expect(readFileSync(hostPath, 'utf-8').trim()).toBe(content);
171
- });
172
-
173
- test('container can read files created by host', () => {
174
- const filename = 'host-created.txt';
175
- writeFileSync(join(sandboxRoot, filename), 'from-host');
176
- const { stdout, exitCode } = dockerRun(`cat /workspace/${filename}`);
177
- expect(exitCode).toBe(0);
178
- expect(stdout).toBe('from-host');
179
- });
180
- });