@vellumai/assistant 0.5.15 → 0.5.16
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/ARCHITECTURE.md +2 -2
- package/docs/architecture/integrations.md +15 -14
- package/knip.json +3 -1
- package/openapi.yaml +11 -43
- package/package.json +1 -1
- package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -375
- package/src/__tests__/ces-rpc-credential-backend.test.ts +4 -1
- package/src/__tests__/checker.test.ts +59 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +98 -10
- package/src/__tests__/cli-memory.test.ts +372 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -2
- package/src/__tests__/config-schema.test.ts +0 -2
- package/src/__tests__/config-watcher-feature-flags.test.ts +211 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +2 -6
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -1
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +7 -73
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -7
- package/src/__tests__/guardian-routing-invariants.test.ts +151 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -3
- package/src/__tests__/intent-routing.test.ts +6 -18
- package/src/__tests__/log-export-workspace.test.ts +2 -28
- package/src/__tests__/managed-skill-lifecycle.test.ts +7 -37
- package/src/__tests__/managed-store.test.ts +2 -10
- package/src/__tests__/messaging-send-tool.test.ts +6 -6
- package/src/__tests__/migration-cross-version-compatibility.test.ts +1 -29
- package/src/__tests__/migration-export-http.test.ts +3 -34
- package/src/__tests__/migration-import-commit-http.test.ts +1 -29
- package/src/__tests__/migration-import-preflight-http.test.ts +3 -34
- package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +2 -1
- package/src/__tests__/oauth-apps-routes.test.ts +120 -10
- package/src/__tests__/oauth-connect-orchestrator.test.ts +709 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +2 -1
- package/src/__tests__/oauth-provider-visibility.test.ts +149 -0
- package/src/__tests__/oauth-providers-routes.test.ts +5 -2
- package/src/__tests__/oauth-store.test.ts +0 -5
- package/src/__tests__/outlook-messaging-provider.test.ts +576 -0
- package/src/__tests__/path-policy.test.ts +2 -17
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/platform-callback-registration.test.ts +3 -7
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +0 -2
- package/src/__tests__/qdrant-manager.test.ts +68 -21
- package/src/__tests__/require-fresh-approval.test.ts +0 -1
- package/src/__tests__/sandbox-diagnostics.test.ts +20 -29
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +2 -10
- package/src/__tests__/secret-allowlist.test.ts +20 -35
- package/src/__tests__/shell-credential-ref.test.ts +0 -5
- package/src/__tests__/skill-load-feature-flag.test.ts +2 -43
- package/src/__tests__/skill-load-inline-command.test.ts +3 -65
- package/src/__tests__/skill-load-inline-includes.test.ts +3 -65
- package/src/__tests__/skill-load-tool.test.ts +3 -67
- package/src/__tests__/skill-memory.test.ts +362 -119
- package/src/__tests__/skills.test.ts +22 -49
- package/src/__tests__/slack-channel-config.test.ts +2 -21
- package/src/__tests__/starter-bundle.test.ts +2 -8
- package/src/__tests__/stt-hints.test.ts +7 -2
- package/src/__tests__/system-prompt.test.ts +25 -45
- package/src/__tests__/task-compiler.test.ts +0 -21
- package/src/__tests__/task-management-tools.test.ts +0 -21
- package/src/__tests__/task-memory-cleanup.test.ts +0 -21
- package/src/__tests__/task-runner.test.ts +0 -21
- package/src/__tests__/task-scheduler.test.ts +0 -21
- package/src/__tests__/terminal-tools.test.ts +1 -17
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +0 -79
- package/src/__tests__/tool-approval-handler.test.ts +1 -20
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +2 -11
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -25
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -20
- package/src/__tests__/tool-preview-lifecycle.test.ts +0 -20
- package/src/__tests__/trust-store.test.ts +9 -41
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -30
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -21
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -22
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -22
- package/src/__tests__/trusted-contact-verification.test.ts +0 -22
- package/src/__tests__/turn-boundary-resolution.test.ts +0 -28
- package/src/__tests__/twilio-provider.test.ts +0 -16
- package/src/__tests__/twilio-routes-twiml.test.ts +7 -12
- package/src/__tests__/twilio-routes.test.ts +0 -24
- package/src/__tests__/update-bulletin.test.ts +17 -89
- package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -20
- package/src/__tests__/usage-routes.test.ts +0 -21
- package/src/__tests__/user-reference.test.ts +1 -5
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +4 -34
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -53
- package/src/__tests__/voice-invite-redemption.test.ts +0 -21
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -24
- package/src/__tests__/voice-session-bridge.test.ts +0 -21
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -23
- package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +2 -2
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -23
- package/src/__tests__/workspace-migration-down-functions.test.ts +0 -6
- package/src/acp/client-handler.ts +1 -2
- package/src/cli/__tests__/notifications.test.ts +0 -22
- package/src/cli/cli-memory.ts +176 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +15 -0
- package/src/cli/commands/oauth/providers.ts +49 -42
- package/src/cli/commands/platform/__tests__/connect.test.ts +2 -48
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +2 -48
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -50
- package/src/config/bundled-skills/computer-use/TOOLS.json +7 -7
- package/src/config/bundled-skills/messaging/SKILL.md +17 -2
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/loader.ts +4 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +8 -0
- package/src/context/window-manager.ts +28 -9
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/daemon/config-watcher.ts +51 -0
- package/src/daemon/conversation-agent-loop.ts +3 -2
- package/src/daemon/conversation-process.ts +1 -0
- package/src/daemon/conversation-usage.ts +1 -0
- package/src/daemon/handlers/skills.ts +9 -1
- package/src/daemon/lifecycle.ts +13 -4
- package/src/daemon/message-types/conversations.ts +1 -0
- package/src/daemon/providers-setup.ts +2 -0
- package/src/daemon/server.ts +26 -22
- package/src/events/domain-events.ts +1 -2
- package/src/memory/db-init.ts +9 -0
- package/src/memory/job-handlers/batch-extraction.ts +16 -4
- package/src/memory/job-handlers/embedding.test.ts +3 -27
- package/src/memory/job-handlers/journal-carry-forward.test.ts +1 -29
- package/src/memory/llm-usage-store.ts +35 -2
- package/src/memory/migrations/201-oauth-providers-feature-flag.ts +11 -0
- package/src/memory/migrations/202-drop-callback-transport-column.ts +13 -0
- package/src/memory/migrations/index.ts +2 -0
- package/src/memory/qdrant-manager.ts +26 -5
- package/src/memory/query-expansion.ts +1 -1
- package/src/memory/retriever.test.ts +22 -20
- package/src/memory/retriever.ts +10 -2
- package/src/memory/schema/oauth.ts +1 -1
- package/src/memory/search/mmr.ts +8 -5
- package/src/memory/slack-thread-store.ts +17 -0
- package/src/messaging/providers/outlook/adapter.ts +193 -0
- package/src/messaging/providers/outlook/client.ts +311 -0
- package/src/messaging/providers/outlook/types.ts +83 -0
- package/src/notifications/adapters/slack.ts +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +1 -1
- package/src/oauth/connect-orchestrator.ts +10 -3
- package/src/oauth/oauth-store.ts +10 -11
- package/src/oauth/provider-serializer.ts +3 -0
- package/src/oauth/provider-visibility.ts +16 -0
- package/src/oauth/seed-providers.ts +49 -17
- package/src/permissions/checker.ts +39 -7
- package/src/permissions/types.ts +2 -4
- package/src/prompts/journal-context.ts +9 -11
- package/src/prompts/system-prompt.ts +3 -64
- package/src/prompts/templates/UPDATES.md +6 -0
- package/src/runtime/auth/__tests__/credential-service.test.ts +1 -27
- package/src/runtime/auth/__tests__/token-service.test.ts +1 -25
- package/src/runtime/auth/route-policy.ts +0 -4
- package/src/runtime/guardian-reply-router.ts +6 -2
- package/src/runtime/routes/conversation-query-routes.ts +2 -58
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +43 -2
- package/src/runtime/routes/memory-item-routes.test.ts +0 -17
- package/src/runtime/routes/memory-item-routes.ts +103 -12
- package/src/runtime/routes/oauth-apps.ts +18 -1
- package/src/runtime/routes/oauth-providers.ts +13 -1
- package/src/runtime/routes/settings-routes.ts +1 -0
- package/src/runtime/routes/usage-routes.ts +19 -2
- package/src/runtime/routes/work-items-routes.test.ts +0 -21
- package/src/runtime/routes/workspace-routes.test.ts +3 -27
- package/src/security/secret-allowlist.ts +4 -4
- package/src/skills/skill-memory.ts +62 -23
- package/src/tools/memory/handlers.test.ts +1 -29
- package/src/tools/permission-checker.ts +0 -18
- package/src/tools/skills/skill-script-runner.ts +1 -1
- package/src/util/device-id.ts +3 -65
- package/src/workspace/git-service.ts +27 -6
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
} from "node:fs";
|
|
14
14
|
import { tmpdir } from "node:os";
|
|
15
15
|
import { join } from "node:path";
|
|
16
|
-
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
16
|
+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
17
|
+
|
|
17
18
|
// ── Shared mock setup ────────────────────────────────────────────────────────
|
|
18
19
|
// Config mock must be declared before importing tool modules so that the
|
|
19
20
|
// mock.module calls are hoisted above the dynamic imports.
|
|
20
|
-
import { mock } from "bun:test";
|
|
21
21
|
|
|
22
22
|
mock.module("../config/loader.js", () => ({
|
|
23
23
|
getConfig: () => ({
|
|
@@ -75,15 +75,6 @@ mock.module("../tools/network/script-proxy/index.js", () => ({
|
|
|
75
75
|
getSessionEnv: () => ({}),
|
|
76
76
|
}));
|
|
77
77
|
|
|
78
|
-
mock.module("../util/platform.js", () => ({
|
|
79
|
-
getProtectedDir: () => "/tmp/protected",
|
|
80
|
-
getDataDir: () => "/tmp",
|
|
81
|
-
getWorkspaceDir: () => "/tmp/workspace",
|
|
82
|
-
getConversationsDir: () => "/tmp/workspace/conversations",
|
|
83
|
-
getDbPath: () => "/tmp/assistant.db",
|
|
84
|
-
ensureDataDir: () => {},
|
|
85
|
-
}));
|
|
86
|
-
|
|
87
78
|
mock.module("../tools/credentials/resolve.js", () => ({
|
|
88
79
|
resolveCredentialRef: () => null,
|
|
89
80
|
}));
|
|
@@ -15,30 +15,14 @@
|
|
|
15
15
|
* - Secret scanning < 50ms for large outputs (100KB)
|
|
16
16
|
* - ToolExecutor overhead < 20ms regardless of tool execution time
|
|
17
17
|
*/
|
|
18
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
19
|
-
import { tmpdir } from "node:os";
|
|
20
|
-
import { join } from "node:path";
|
|
21
|
-
import { afterAll, beforeAll, describe, expect, mock, test } from "bun:test";
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
import { beforeAll, describe, expect, mock, test } from "bun:test";
|
|
24
20
|
|
|
25
21
|
// Local registry for ToolExecutor tests — the mock delegates to this map
|
|
26
22
|
// so that registerTool/getTool/getAllTools work for our benchmark tools.
|
|
27
23
|
const localRegistry = new Map<string, import("../tools/types.js").Tool>();
|
|
28
24
|
|
|
29
25
|
// Mocks must precede imports of modules under test.
|
|
30
|
-
mock.module("../util/platform.js", () => ({
|
|
31
|
-
getDataDir: () => testDir,
|
|
32
|
-
isMacOS: () => process.platform === "darwin",
|
|
33
|
-
isLinux: () => process.platform === "linux",
|
|
34
|
-
isWindows: () => process.platform === "win32",
|
|
35
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
36
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
37
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
38
|
-
ensureDataDir: () => {},
|
|
39
|
-
getHooksDir: () => join(testDir, "hooks"),
|
|
40
|
-
}));
|
|
41
|
-
|
|
42
26
|
mock.module("../util/logger.js", () => ({
|
|
43
27
|
getLogger: () =>
|
|
44
28
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -192,14 +176,6 @@ describe("Tool execution pipeline benchmark", () => {
|
|
|
192
176
|
}
|
|
193
177
|
});
|
|
194
178
|
|
|
195
|
-
afterAll(() => {
|
|
196
|
-
try {
|
|
197
|
-
rmSync(testDir, { recursive: true });
|
|
198
|
-
} catch {
|
|
199
|
-
// best effort cleanup
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
|
|
203
179
|
test("classifyRisk: low-risk tool (file_read) is fast", async () => {
|
|
204
180
|
const { timings } = await benchmarkAsync(
|
|
205
181
|
() => classifyRisk("file_read", { path: "/tmp/test.ts" }, "/tmp"),
|
|
@@ -8,23 +8,9 @@
|
|
|
8
8
|
* 5. Inline wait-and-resume for trusted-contact grant-gated tools
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
12
|
-
import { tmpdir } from "node:os";
|
|
13
|
-
import { join } from "node:path";
|
|
14
11
|
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
15
12
|
|
|
16
|
-
const testDir =
|
|
17
|
-
|
|
18
|
-
mock.module("../util/platform.js", () => ({
|
|
19
|
-
getDataDir: () => testDir,
|
|
20
|
-
isMacOS: () => process.platform === "darwin",
|
|
21
|
-
isLinux: () => process.platform === "linux",
|
|
22
|
-
isWindows: () => process.platform === "win32",
|
|
23
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
24
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
25
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
26
|
-
ensureDataDir: () => {},
|
|
27
|
-
}));
|
|
13
|
+
const testDir = process.env.VELLUM_WORKSPACE_DIR!;
|
|
28
14
|
|
|
29
15
|
mock.module("../util/logger.js", () => ({
|
|
30
16
|
getLogger: () =>
|
|
@@ -146,11 +132,6 @@ function resetTables(): void {
|
|
|
146
132
|
|
|
147
133
|
afterAll(() => {
|
|
148
134
|
resetDb();
|
|
149
|
-
try {
|
|
150
|
-
rmSync(testDir, { recursive: true });
|
|
151
|
-
} catch {
|
|
152
|
-
/* best effort */
|
|
153
|
-
}
|
|
154
135
|
});
|
|
155
136
|
|
|
156
137
|
// ---------------------------------------------------------------------------
|
|
@@ -8,29 +8,9 @@
|
|
|
8
8
|
* - handleToolResult includes toolUseId in emitted tool_result
|
|
9
9
|
* - Event ordering: tool_use_preview_start → input_json_delta → tool_use
|
|
10
10
|
*/
|
|
11
|
-
import { join } from "node:path";
|
|
12
11
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
13
12
|
|
|
14
13
|
// ── Mock platform (must precede imports that read it) ─────────────────────────
|
|
15
|
-
mock.module("../util/platform.js", () => ({
|
|
16
|
-
getSessionTokenPath: () => "/tmp/test-token",
|
|
17
|
-
getProtectedDir: () => join("/tmp/test", "protected"),
|
|
18
|
-
getDataDir: () => "/tmp/test",
|
|
19
|
-
getWorkspaceDir: () => "/tmp/test/workspace",
|
|
20
|
-
getWorkspaceSkillsDir: () => "/tmp/test/skills",
|
|
21
|
-
getSandboxWorkingDir: () => "/tmp/test/sandbox",
|
|
22
|
-
getTCPPort: () => undefined,
|
|
23
|
-
getTCPHost: () => "127.0.0.1",
|
|
24
|
-
isTCPEnabled: () => false,
|
|
25
|
-
isMacOS: () => false,
|
|
26
|
-
isLinux: () => true,
|
|
27
|
-
isWindows: () => false,
|
|
28
|
-
getPidPath: () => "/tmp/test.pid",
|
|
29
|
-
getLogPath: () => "/tmp/test.log",
|
|
30
|
-
getDbPath: () => "/tmp/test.db",
|
|
31
|
-
ensureDataDir: () => {},
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
14
|
mock.module("../util/logger.js", () => ({
|
|
35
15
|
getLogger: () =>
|
|
36
16
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
mkdirSync,
|
|
3
|
-
mkdtempSync,
|
|
4
|
-
readFileSync,
|
|
5
|
-
rmSync,
|
|
6
|
-
writeFileSync,
|
|
7
|
-
} from "node:fs";
|
|
8
|
-
import { tmpdir } from "node:os";
|
|
1
|
+
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
9
2
|
import { dirname, join } from "node:path";
|
|
10
3
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
11
4
|
|
|
12
5
|
// Create a temp directory for the trust file
|
|
13
|
-
const testDir =
|
|
6
|
+
const testDir = process.env.VELLUM_WORKSPACE_DIR!;
|
|
14
7
|
|
|
15
8
|
// Point the file-based trust backend at the test temp dir so
|
|
16
9
|
// getGatewaySecurityDir() (which checks this env var first) writes
|
|
@@ -18,19 +11,6 @@ const testDir = mkdtempSync(join(tmpdir(), "trust-store-test-"));
|
|
|
18
11
|
process.env.GATEWAY_SECURITY_DIR = join(testDir, "protected");
|
|
19
12
|
|
|
20
13
|
// Mock platform module so trust-store writes to temp dir instead of ~/.vellum
|
|
21
|
-
mock.module("../util/platform.js", () => ({
|
|
22
|
-
getProtectedDir: () => join(testDir, "protected"),
|
|
23
|
-
getWorkspaceDir: () => join(testDir, "workspace"),
|
|
24
|
-
getDataDir: () => testDir,
|
|
25
|
-
isMacOS: () => process.platform === "darwin",
|
|
26
|
-
isLinux: () => process.platform === "linux",
|
|
27
|
-
isWindows: () => process.platform === "win32",
|
|
28
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
29
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
30
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
31
|
-
ensureDataDir: () => {},
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
14
|
// Mock logger to suppress output during tests
|
|
35
15
|
mock.module("../util/logger.js", () => ({
|
|
36
16
|
getLogger: () => ({
|
|
@@ -744,7 +724,7 @@ describe("Trust Store", () => {
|
|
|
744
724
|
rule.id === "default:allow-bash-rm-bootstrap" ||
|
|
745
725
|
rule.id === "default:allow-bash-rm-updates"
|
|
746
726
|
) {
|
|
747
|
-
expect(rule.scope).toBe(
|
|
727
|
+
expect(rule.scope).toBe(testDir);
|
|
748
728
|
} else {
|
|
749
729
|
expect(rule.scope).toBe("everywhere");
|
|
750
730
|
}
|
|
@@ -917,7 +897,7 @@ describe("Trust Store", () => {
|
|
|
917
897
|
});
|
|
918
898
|
|
|
919
899
|
test("bootstrap delete rule matches only when workingDir is the workspace dir", () => {
|
|
920
|
-
const workspaceDir =
|
|
900
|
+
const workspaceDir = testDir;
|
|
921
901
|
// Should match when workingDir is the workspace directory — the bootstrap
|
|
922
902
|
// rule (priority 100) outranks the global default allow (priority 50).
|
|
923
903
|
const match = findHighestPriorityRule(
|
|
@@ -940,7 +920,7 @@ describe("Trust Store", () => {
|
|
|
940
920
|
});
|
|
941
921
|
|
|
942
922
|
test("updates delete rule matches only when workingDir is the workspace dir", () => {
|
|
943
|
-
const workspaceDir =
|
|
923
|
+
const workspaceDir = testDir;
|
|
944
924
|
const match = findHighestPriorityRule(
|
|
945
925
|
"bash",
|
|
946
926
|
["rm UPDATES.md"],
|
|
@@ -1028,7 +1008,7 @@ describe("Trust Store", () => {
|
|
|
1028
1008
|
expect(managed!.tool).toBe("file_write");
|
|
1029
1009
|
expect(managed!.decision).toBe("ask");
|
|
1030
1010
|
expect(managed!.priority).toBe(50);
|
|
1031
|
-
expect(managed!.pattern).toContain("
|
|
1011
|
+
expect(managed!.pattern).toContain("skills/**");
|
|
1032
1012
|
|
|
1033
1013
|
const bundled = rules.find(
|
|
1034
1014
|
(r) => r.id === "default:ask-file_write-bundled-skills",
|
|
@@ -1048,7 +1028,7 @@ describe("Trust Store", () => {
|
|
|
1048
1028
|
expect(managed!.tool).toBe("file_edit");
|
|
1049
1029
|
expect(managed!.decision).toBe("ask");
|
|
1050
1030
|
expect(managed!.priority).toBe(50);
|
|
1051
|
-
expect(managed!.pattern).toContain("
|
|
1031
|
+
expect(managed!.pattern).toContain("skills/**");
|
|
1052
1032
|
|
|
1053
1033
|
const bundled = rules.find(
|
|
1054
1034
|
(r) => r.id === "default:ask-file_edit-bundled-skills",
|
|
@@ -1159,13 +1139,7 @@ describe("Trust Store", () => {
|
|
|
1159
1139
|
});
|
|
1160
1140
|
|
|
1161
1141
|
test("findHighestPriorityRule matches default ask for file_write on managed skill path", () => {
|
|
1162
|
-
const skillFile = join(
|
|
1163
|
-
testDir,
|
|
1164
|
-
"workspace",
|
|
1165
|
-
"skills",
|
|
1166
|
-
"my-skill",
|
|
1167
|
-
"SKILL.md",
|
|
1168
|
-
);
|
|
1142
|
+
const skillFile = join(testDir, "skills", "my-skill", "SKILL.md");
|
|
1169
1143
|
const match = findHighestPriorityRule(
|
|
1170
1144
|
"file_write",
|
|
1171
1145
|
[`file_write:${skillFile}`],
|
|
@@ -1177,13 +1151,7 @@ describe("Trust Store", () => {
|
|
|
1177
1151
|
});
|
|
1178
1152
|
|
|
1179
1153
|
test("findHighestPriorityRule matches default ask for file_edit on managed skill path", () => {
|
|
1180
|
-
const skillFile = join(
|
|
1181
|
-
testDir,
|
|
1182
|
-
"workspace",
|
|
1183
|
-
"skills",
|
|
1184
|
-
"my-skill",
|
|
1185
|
-
"tools.ts",
|
|
1186
|
-
);
|
|
1154
|
+
const skillFile = join(testDir, "skills", "my-skill", "tools.ts");
|
|
1187
1155
|
const match = findHighestPriorityRule(
|
|
1188
1156
|
"file_edit",
|
|
1189
1157
|
[`file_edit:${skillFile}`],
|
|
@@ -9,30 +9,9 @@
|
|
|
9
9
|
* 5. Delivery failures allow retry on next poll
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import { tmpdir } from "node:os";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
16
|
-
|
|
17
|
-
const testDir = mkdtempSync(join(tmpdir(), "tc-approval-notifier-test-"));
|
|
12
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
18
13
|
|
|
19
14
|
// ── Platform mock ──
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
|
-
const realPlatform = require("../util/platform.js");
|
|
22
|
-
mock.module("../util/platform.js", () => ({
|
|
23
|
-
...realPlatform,
|
|
24
|
-
getDataDir: () => testDir,
|
|
25
|
-
isMacOS: () => process.platform === "darwin",
|
|
26
|
-
isLinux: () => process.platform === "linux",
|
|
27
|
-
isWindows: () => process.platform === "win32",
|
|
28
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
29
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
30
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
31
|
-
ensureDataDir: () => {},
|
|
32
|
-
normalizeAssistantId: (id: string) =>
|
|
33
|
-
id === "self" || id === "" ? "self" : id,
|
|
34
|
-
}));
|
|
35
|
-
|
|
36
15
|
// ── Logger mock ──
|
|
37
16
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
17
|
const realLogger = require("../util/logger.js");
|
|
@@ -255,14 +234,6 @@ describe("trusted-contact pending-approval notifier", () => {
|
|
|
255
234
|
mockGuardianContact = null;
|
|
256
235
|
});
|
|
257
236
|
|
|
258
|
-
afterAll(() => {
|
|
259
|
-
try {
|
|
260
|
-
rmSync(testDir, { recursive: true });
|
|
261
|
-
} catch {
|
|
262
|
-
/* best effort */
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
|
|
266
237
|
test("sends waiting message to trusted contact when pending approval exists", async () => {
|
|
267
238
|
mockPendingApprovals = [
|
|
268
239
|
{
|
|
@@ -17,29 +17,14 @@
|
|
|
17
17
|
* f. Timeout/stale flow: guardian decision after prompt timeout produces deterministic outcome
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
21
|
-
import { tmpdir } from "node:os";
|
|
22
|
-
import { join } from "node:path";
|
|
23
20
|
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
24
21
|
|
|
25
|
-
const testDir =
|
|
22
|
+
const testDir = process.env.VELLUM_WORKSPACE_DIR!;
|
|
26
23
|
|
|
27
24
|
// ---------------------------------------------------------------------------
|
|
28
25
|
// Mocks — must be set before any production imports
|
|
29
26
|
// ---------------------------------------------------------------------------
|
|
30
27
|
|
|
31
|
-
mock.module("../util/platform.js", () => ({
|
|
32
|
-
getDataDir: () => testDir,
|
|
33
|
-
getProtectedDir: () => join(testDir, "protected"),
|
|
34
|
-
isMacOS: () => process.platform === "darwin",
|
|
35
|
-
isLinux: () => process.platform === "linux",
|
|
36
|
-
isWindows: () => process.platform === "win32",
|
|
37
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
38
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
39
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
40
|
-
ensureDataDir: () => {},
|
|
41
|
-
}));
|
|
42
|
-
|
|
43
28
|
mock.module("../util/logger.js", () => ({
|
|
44
29
|
getLogger: () =>
|
|
45
30
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -205,11 +190,6 @@ function resetTables(): void {
|
|
|
205
190
|
|
|
206
191
|
afterAll(() => {
|
|
207
192
|
resetDb();
|
|
208
|
-
try {
|
|
209
|
-
rmSync(testDir, { recursive: true });
|
|
210
|
-
} catch {
|
|
211
|
-
/* best effort */
|
|
212
|
-
}
|
|
213
193
|
});
|
|
214
194
|
|
|
215
195
|
// ---------------------------------------------------------------------------
|
|
@@ -11,29 +11,12 @@
|
|
|
11
11
|
* 4. activated — when the trusted contact successfully verifies
|
|
12
12
|
* 5. denied — when the guardian denies the request
|
|
13
13
|
*/
|
|
14
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
15
|
-
import { tmpdir } from "node:os";
|
|
16
|
-
import { join } from "node:path";
|
|
17
14
|
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
18
15
|
|
|
19
16
|
// ---------------------------------------------------------------------------
|
|
20
17
|
// Test isolation: in-memory SQLite via temp directory
|
|
21
18
|
// ---------------------------------------------------------------------------
|
|
22
19
|
|
|
23
|
-
const testDir = mkdtempSync(join(tmpdir(), "trusted-contact-lifecycle-notif-"));
|
|
24
|
-
|
|
25
|
-
mock.module("../util/platform.js", () => ({
|
|
26
|
-
getProtectedDir: () => join(testDir, "protected"),
|
|
27
|
-
getDataDir: () => testDir,
|
|
28
|
-
isMacOS: () => process.platform === "darwin",
|
|
29
|
-
isLinux: () => process.platform === "linux",
|
|
30
|
-
isWindows: () => process.platform === "win32",
|
|
31
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
32
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
33
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
34
|
-
ensureDataDir: () => {},
|
|
35
|
-
}));
|
|
36
|
-
|
|
37
20
|
mock.module("../util/logger.js", () => ({
|
|
38
21
|
getLogger: () =>
|
|
39
22
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -96,11 +79,6 @@ initializeDb();
|
|
|
96
79
|
|
|
97
80
|
afterAll(() => {
|
|
98
81
|
resetDb();
|
|
99
|
-
try {
|
|
100
|
-
rmSync(testDir, { recursive: true });
|
|
101
|
-
} catch {
|
|
102
|
-
/* best effort */
|
|
103
|
-
}
|
|
104
82
|
});
|
|
105
83
|
|
|
106
84
|
// ---------------------------------------------------------------------------
|
|
@@ -6,29 +6,12 @@
|
|
|
6
6
|
* These tests confirm no channel-specific assumptions leaked into the
|
|
7
7
|
* trusted contact code paths.
|
|
8
8
|
*/
|
|
9
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
10
|
-
import { tmpdir } from "node:os";
|
|
11
|
-
import { join } from "node:path";
|
|
12
9
|
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
13
10
|
|
|
14
11
|
// ---------------------------------------------------------------------------
|
|
15
12
|
// Test isolation: in-memory SQLite via temp directory
|
|
16
13
|
// ---------------------------------------------------------------------------
|
|
17
14
|
|
|
18
|
-
const testDir = mkdtempSync(join(tmpdir(), "trusted-contact-multichannel-"));
|
|
19
|
-
|
|
20
|
-
mock.module("../util/platform.js", () => ({
|
|
21
|
-
getProtectedDir: () => join(testDir, "protected"),
|
|
22
|
-
getDataDir: () => testDir,
|
|
23
|
-
isMacOS: () => process.platform === "darwin",
|
|
24
|
-
isLinux: () => process.platform === "linux",
|
|
25
|
-
isWindows: () => process.platform === "win32",
|
|
26
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
27
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
28
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
29
|
-
ensureDataDir: () => {},
|
|
30
|
-
}));
|
|
31
|
-
|
|
32
15
|
mock.module("../util/logger.js", () => ({
|
|
33
16
|
getLogger: () =>
|
|
34
17
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -106,11 +89,6 @@ initializeDb();
|
|
|
106
89
|
|
|
107
90
|
afterAll(() => {
|
|
108
91
|
resetDb();
|
|
109
|
-
try {
|
|
110
|
-
rmSync(testDir, { recursive: true });
|
|
111
|
-
} catch {
|
|
112
|
-
/* best effort */
|
|
113
|
-
}
|
|
114
92
|
});
|
|
115
93
|
|
|
116
94
|
// ---------------------------------------------------------------------------
|
|
@@ -9,29 +9,12 @@
|
|
|
9
9
|
* 4. Reactivate previously revoked members on re-verification
|
|
10
10
|
* 5. NOT create a guardian binding (trusted contacts are not guardians)
|
|
11
11
|
*/
|
|
12
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
13
|
-
import { tmpdir } from "node:os";
|
|
14
|
-
import { join } from "node:path";
|
|
15
12
|
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
16
13
|
|
|
17
14
|
// ---------------------------------------------------------------------------
|
|
18
15
|
// Test isolation: in-memory SQLite via temp directory
|
|
19
16
|
// ---------------------------------------------------------------------------
|
|
20
17
|
|
|
21
|
-
const testDir = mkdtempSync(join(tmpdir(), "trusted-contact-verify-test-"));
|
|
22
|
-
|
|
23
|
-
mock.module("../util/platform.js", () => ({
|
|
24
|
-
getProtectedDir: () => join(testDir, "protected"),
|
|
25
|
-
getDataDir: () => testDir,
|
|
26
|
-
isMacOS: () => process.platform === "darwin",
|
|
27
|
-
isLinux: () => process.platform === "linux",
|
|
28
|
-
isWindows: () => process.platform === "win32",
|
|
29
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
30
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
31
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
32
|
-
ensureDataDir: () => {},
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
18
|
mock.module("../util/logger.js", () => ({
|
|
36
19
|
getLogger: () =>
|
|
37
20
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -59,11 +42,6 @@ initializeDb();
|
|
|
59
42
|
|
|
60
43
|
afterAll(() => {
|
|
61
44
|
resetDb();
|
|
62
|
-
try {
|
|
63
|
-
rmSync(testDir, { recursive: true });
|
|
64
|
-
} catch {
|
|
65
|
-
/* best effort */
|
|
66
|
-
}
|
|
67
45
|
});
|
|
68
46
|
|
|
69
47
|
// ---------------------------------------------------------------------------
|
|
@@ -1,28 +1,5 @@
|
|
|
1
|
-
import { mkdtempSync, realpathSync, rmSync } from "node:fs";
|
|
2
|
-
import { tmpdir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
1
|
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
5
2
|
|
|
6
|
-
const testDir = realpathSync(
|
|
7
|
-
mkdtempSync(join(tmpdir(), "turn-boundary-resolution-test-")),
|
|
8
|
-
);
|
|
9
|
-
const workspaceDir = join(testDir, ".vellum", "workspace");
|
|
10
|
-
const conversationsDir = join(workspaceDir, "conversations");
|
|
11
|
-
|
|
12
|
-
mock.module("../util/platform.js", () => ({
|
|
13
|
-
getProtectedDir: () => join(join(testDir, ".vellum"), "protected"),
|
|
14
|
-
getDataDir: () => join(workspaceDir, "data"),
|
|
15
|
-
getWorkspaceDir: () => workspaceDir,
|
|
16
|
-
getConversationsDir: () => conversationsDir,
|
|
17
|
-
isMacOS: () => process.platform === "darwin",
|
|
18
|
-
isLinux: () => process.platform === "linux",
|
|
19
|
-
isWindows: () => process.platform === "win32",
|
|
20
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
21
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
22
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
23
|
-
ensureDataDir: () => {},
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
3
|
mock.module("../util/logger.js", () => ({
|
|
27
4
|
getLogger: () =>
|
|
28
5
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -74,11 +51,6 @@ function toolResultContent(toolUseIds: string[]): string {
|
|
|
74
51
|
|
|
75
52
|
afterAll(() => {
|
|
76
53
|
resetDb();
|
|
77
|
-
try {
|
|
78
|
-
rmSync(testDir, { recursive: true, force: true });
|
|
79
|
-
} catch {
|
|
80
|
-
/* best effort */
|
|
81
|
-
}
|
|
82
54
|
});
|
|
83
55
|
|
|
84
56
|
describe("getAssistantMessageIdsInTurn", () => {
|
|
@@ -3,26 +3,10 @@
|
|
|
3
3
|
* fail-closed auth token behavior, and caller ID eligibility checks.
|
|
4
4
|
*/
|
|
5
5
|
import { createHmac } from "node:crypto";
|
|
6
|
-
import { mkdtempSync } from "node:fs";
|
|
7
|
-
import { tmpdir } from "node:os";
|
|
8
|
-
import { join } from "node:path";
|
|
9
6
|
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
10
7
|
|
|
11
8
|
import { credentialKey } from "../security/credential-key.js";
|
|
12
9
|
|
|
13
|
-
const testDir = mkdtempSync(join(tmpdir(), "twilio-provider-test-"));
|
|
14
|
-
|
|
15
|
-
mock.module("../util/platform.js", () => ({
|
|
16
|
-
getDataDir: () => testDir,
|
|
17
|
-
isMacOS: () => process.platform === "darwin",
|
|
18
|
-
isLinux: () => process.platform === "linux",
|
|
19
|
-
isWindows: () => process.platform === "win32",
|
|
20
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
21
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
22
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
23
|
-
ensureDataDir: () => {},
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
10
|
mock.module("../util/logger.js", () => ({
|
|
27
11
|
getLogger: () =>
|
|
28
12
|
new Proxy({} as Record<string, unknown>, {
|
|
@@ -175,18 +175,13 @@ describe("generateTwiML with voice quality profile", () => {
|
|
|
175
175
|
|
|
176
176
|
expect(twimlMedium).toContain('interruptSensitivity="medium"');
|
|
177
177
|
|
|
178
|
-
const twimlHigh = generateTwiML(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
ttsProvider: "Google",
|
|
186
|
-
voice: "Google.en-US-Journey-O",
|
|
187
|
-
interruptSensitivity: "high",
|
|
188
|
-
},
|
|
189
|
-
);
|
|
178
|
+
const twimlHigh = generateTwiML(callSessionId, relayUrl, welcomeGreeting, {
|
|
179
|
+
language: "en-US",
|
|
180
|
+
transcriptionProvider: "Deepgram",
|
|
181
|
+
ttsProvider: "Google",
|
|
182
|
+
voice: "Google.en-US-Journey-O",
|
|
183
|
+
interruptSensitivity: "high",
|
|
184
|
+
});
|
|
190
185
|
|
|
191
186
|
expect(twimlHigh).toContain('interruptSensitivity="high"');
|
|
192
187
|
});
|
|
@@ -12,9 +12,6 @@
|
|
|
12
12
|
* - Voice webhook TwiML relay URL generation
|
|
13
13
|
* - Handler-level idempotency concurrency (concurrent duplicates, failure-retry)
|
|
14
14
|
*/
|
|
15
|
-
import { mkdtempSync, realpathSync, rmSync } from "node:fs";
|
|
16
|
-
import { tmpdir } from "node:os";
|
|
17
|
-
import { join } from "node:path";
|
|
18
15
|
import {
|
|
19
16
|
afterAll,
|
|
20
17
|
beforeEach,
|
|
@@ -84,22 +81,6 @@ mock.module("../config/env.js", () => ({
|
|
|
84
81
|
},
|
|
85
82
|
}));
|
|
86
83
|
|
|
87
|
-
const testDir = realpathSync(
|
|
88
|
-
mkdtempSync(join(tmpdir(), "twilio-routes-test-")),
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
mock.module("../util/platform.js", () => ({
|
|
92
|
-
getProtectedDir: () => join(testDir, "protected"),
|
|
93
|
-
getDataDir: () => testDir,
|
|
94
|
-
isMacOS: () => process.platform === "darwin",
|
|
95
|
-
isLinux: () => process.platform === "linux",
|
|
96
|
-
isWindows: () => process.platform === "win32",
|
|
97
|
-
getPidPath: () => join(testDir, "test.pid"),
|
|
98
|
-
getDbPath: () => join(testDir, "test.db"),
|
|
99
|
-
getLogPath: () => join(testDir, "test.log"),
|
|
100
|
-
ensureDataDir: () => {},
|
|
101
|
-
}));
|
|
102
|
-
|
|
103
84
|
mock.module("../util/logger.js", () => ({
|
|
104
85
|
getLogger: () => ({
|
|
105
86
|
info: () => {},
|
|
@@ -442,11 +423,6 @@ describe("twilio webhook routes", () => {
|
|
|
442
423
|
afterAll(() => {
|
|
443
424
|
globalThis.fetch = originalFetch;
|
|
444
425
|
resetDb();
|
|
445
|
-
try {
|
|
446
|
-
rmSync(testDir, { recursive: true, force: true });
|
|
447
|
-
} catch {
|
|
448
|
-
/* best effort */
|
|
449
|
-
}
|
|
450
426
|
});
|
|
451
427
|
|
|
452
428
|
// ── Callback idempotency / replay tests ───────────────────────────
|