@vellumai/cli 0.6.5 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -2
- package/package.json +1 -1
- package/src/__tests__/assistant-config.test.ts +1 -7
- package/src/__tests__/config-utils.test.ts +159 -0
- package/src/__tests__/env-drift.test.ts +10 -32
- package/src/__tests__/llm-provider-env-var-parity.test.ts +1 -21
- package/src/__tests__/multi-local.test.ts +0 -5
- package/src/__tests__/sleep.test.ts +1 -2
- package/src/__tests__/teleport.test.ts +919 -1255
- package/src/commands/env.ts +93 -0
- package/src/commands/events.ts +2 -0
- package/src/commands/exec.ts +40 -8
- package/src/commands/hatch.ts +6 -2
- package/src/commands/login.ts +89 -6
- package/src/commands/ps.ts +104 -20
- package/src/commands/retire.ts +23 -0
- package/src/commands/sleep.ts +5 -2
- package/src/commands/ssh.ts +15 -2
- package/src/commands/teleport.ts +447 -583
- package/src/commands/terminal.ts +225 -0
- package/src/commands/wake.ts +2 -1
- package/src/components/DefaultMainScreen.tsx +304 -152
- package/src/index.ts +6 -0
- package/src/lib/__tests__/docker.test.ts +50 -74
- package/src/lib/__tests__/job-polling.test.ts +278 -0
- package/src/lib/__tests__/local-runtime-client.test.ts +383 -0
- package/src/lib/__tests__/platform-client-signed-url.test.ts +405 -0
- package/src/lib/assistant-config.ts +12 -8
- package/src/lib/client-identity.ts +67 -0
- package/src/lib/config-utils.ts +97 -1
- package/src/lib/docker.ts +73 -75
- package/src/lib/environments/__tests__/paths.test.ts +2 -0
- package/src/lib/environments/resolve.ts +89 -7
- package/src/lib/environments/seeds.ts +8 -5
- package/src/lib/environments/types.ts +10 -0
- package/src/lib/hatch-local.ts +15 -120
- package/src/lib/health-check.ts +98 -0
- package/src/lib/job-polling.ts +195 -0
- package/src/lib/local-runtime-client.ts +178 -0
- package/src/lib/local.ts +139 -15
- package/src/lib/orphan-detection.ts +2 -35
- package/src/lib/platform-client.ts +215 -0
- package/src/lib/retire-local.ts +6 -2
- package/src/lib/terminal-client.ts +177 -0
- package/src/lib/terminal-session.ts +457 -0
- package/src/shared/provider-env-vars.ts +2 -3
- package/src/__tests__/orphan-detection.test.ts +0 -214
package/AGENTS.md
CHANGED
|
@@ -41,6 +41,12 @@ Every command must have high-quality `--help` output. Follow the same standards
|
|
|
41
41
|
AI agents parse help text to decide which command to run and how. Avoid vague
|
|
42
42
|
language — say exactly what the command does and where state is stored.
|
|
43
43
|
|
|
44
|
+
## Boundary: No integration-specific references
|
|
45
|
+
|
|
46
|
+
The CLI is a generic lifecycle manager. It must **never** contain references to specific skills, integrations, or features (e.g. "Meet", "Slack", "Telegram"). Environment variables, volume mounts, and device passthroughs defined here must use generic names (e.g. `VELLUM_AVATAR_DEVICE`, not `VELLUM_MEET_AVATAR_DEVICE`). The skill that uses a resource decides how to interpret it — the CLI just passes it through.
|
|
47
|
+
|
|
48
|
+
Cross-package imports into `skills/` are forbidden. The CLI is distributed as an npm package; anything outside `cli/` is not included in the tarball and will fail to resolve at runtime.
|
|
49
|
+
|
|
44
50
|
## Boundary: No `.vellum/` directory access
|
|
45
51
|
|
|
46
52
|
The CLI must **never** read from or write to the `.vellum/` directory (e.g. `~/.vellum/protected/`, `<instanceDir>/.vellum/`). That directory structure is an **assistant daemon / gateway implementation detail**. The CLI's job is to spawn those processes and pass configuration via environment variables — not to reach into their internal storage.
|
|
@@ -62,9 +68,9 @@ The CLI creates and manages Docker volumes for containerized instances. See the
|
|
|
62
68
|
**Meet Docker-in-Docker support** (assistant container only): The assistant container runs an inner `dockerd` that hosts the Meet-bot containers as nested children. The CLI supports this by:
|
|
63
69
|
|
|
64
70
|
- Creating a dedicated `<name>-dockerd-data` volume mounted at `/var/lib/docker` so pulled images and container state persist across assistant restarts.
|
|
65
|
-
- Running the assistant container with
|
|
71
|
+
- Running the assistant container with `CAP_SYS_ADMIN` + `CAP_NET_ADMIN` plus `--security-opt seccomp=unconfined` + `--security-opt apparmor=unconfined` so the inner dockerd can configure cgroups, overlay mounts, and container networking without the default seccomp profile blocking clone/unshare/pivot_root syscalls or the default AppArmor profile denying its mount operations. `--privileged` is deliberately avoided — dropping it shrinks the escape surface by withholding the rest of the host capability set and access to host device nodes.
|
|
66
72
|
- No longer bind-mounting the host's `/var/run/docker.sock`; Meet-bot spawning happens entirely inside the assistant container.
|
|
67
73
|
|
|
68
74
|
Both are wired in `serviceDockerRunArgs()` in `lib/docker.ts`.
|
|
69
75
|
|
|
70
|
-
|
|
76
|
+
This capability + security-opt set is acceptable for single-user local deployments. Managed/multi-tenant mode needs a different spawn model (e.g. a Kubernetes job runner) and is out of scope for this CLI.
|
package/package.json
CHANGED
|
@@ -216,7 +216,7 @@ describe("migrateLegacyEntry", () => {
|
|
|
216
216
|
test("synthesises full resources when none exist", () => {
|
|
217
217
|
/**
|
|
218
218
|
* Tests that a legacy local entry with no resources object gets a
|
|
219
|
-
* complete resources object synthesised with default ports
|
|
219
|
+
* complete resources object synthesised with default ports.
|
|
220
220
|
*/
|
|
221
221
|
|
|
222
222
|
// GIVEN a local entry with no resources
|
|
@@ -239,7 +239,6 @@ describe("migrateLegacyEntry", () => {
|
|
|
239
239
|
expect(resources.gatewayPort).toBe(7830);
|
|
240
240
|
expect(resources.qdrantPort).toBe(6333);
|
|
241
241
|
expect(resources.cesPort).toBe(8090);
|
|
242
|
-
expect(resources.pidFile).toContain("vellum.pid");
|
|
243
242
|
});
|
|
244
243
|
|
|
245
244
|
test("infers gateway port from runtimeUrl", () => {
|
|
@@ -312,7 +311,6 @@ describe("migrateLegacyEntry", () => {
|
|
|
312
311
|
expect(resources.gatewayPort).toBe(7830);
|
|
313
312
|
expect(resources.qdrantPort).toBe(6333);
|
|
314
313
|
expect(resources.cesPort).toBe(8090);
|
|
315
|
-
expect(resources.pidFile).toBe("/custom/path/.vellum/vellum.pid");
|
|
316
314
|
});
|
|
317
315
|
|
|
318
316
|
test("does not overwrite existing resources fields", () => {
|
|
@@ -331,7 +329,6 @@ describe("migrateLegacyEntry", () => {
|
|
|
331
329
|
gatewayPort: 8001,
|
|
332
330
|
qdrantPort: 8002,
|
|
333
331
|
cesPort: 8003,
|
|
334
|
-
pidFile: "/my/path/.vellum/vellum.pid",
|
|
335
332
|
},
|
|
336
333
|
};
|
|
337
334
|
|
|
@@ -366,7 +363,6 @@ describe("migrateLegacyEntry", () => {
|
|
|
366
363
|
daemonPort: 7821,
|
|
367
364
|
gatewayPort: 7830,
|
|
368
365
|
qdrantPort: 6333,
|
|
369
|
-
pidFile: "/new/path/.vellum/vellum.pid",
|
|
370
366
|
},
|
|
371
367
|
};
|
|
372
368
|
|
|
@@ -393,7 +389,6 @@ describe("migrateLegacyEntry", () => {
|
|
|
393
389
|
daemonPort: 7821,
|
|
394
390
|
gatewayPort: 7830,
|
|
395
391
|
qdrantPort: 6333,
|
|
396
|
-
pidFile: "/custom/path/.vellum/vellum.pid",
|
|
397
392
|
},
|
|
398
393
|
};
|
|
399
394
|
// WHEN we migrate the entry
|
|
@@ -415,7 +410,6 @@ describe("migrateLegacyEntry", () => {
|
|
|
415
410
|
gatewayPort: 8001,
|
|
416
411
|
qdrantPort: 8002,
|
|
417
412
|
cesPort: 9090,
|
|
418
|
-
pidFile: "/my/path/.vellum/vellum.pid",
|
|
419
413
|
},
|
|
420
414
|
};
|
|
421
415
|
const changed = migrateLegacyEntry(entry);
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { buildInitialConfig, buildNestedConfig } from "../lib/config-utils.js";
|
|
4
|
+
|
|
5
|
+
describe("config-utils", () => {
|
|
6
|
+
test("buildNestedConfig only converts dot-notation values", () => {
|
|
7
|
+
expect(
|
|
8
|
+
buildNestedConfig({
|
|
9
|
+
"llm.default.provider": "anthropic",
|
|
10
|
+
"llm.default.model": "claude-sonnet-4-6",
|
|
11
|
+
}),
|
|
12
|
+
).toEqual({
|
|
13
|
+
llm: {
|
|
14
|
+
default: {
|
|
15
|
+
provider: "anthropic",
|
|
16
|
+
model: "claude-sonnet-4-6",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("buildInitialConfig seeds mainAgent callSite for Anthropic default", () => {
|
|
23
|
+
expect(
|
|
24
|
+
buildInitialConfig({
|
|
25
|
+
"llm.default.provider": "anthropic",
|
|
26
|
+
"llm.default.model": "claude-opus-4-7",
|
|
27
|
+
}),
|
|
28
|
+
).toEqual({
|
|
29
|
+
llm: {
|
|
30
|
+
default: {
|
|
31
|
+
provider: "anthropic",
|
|
32
|
+
model: "claude-opus-4-7",
|
|
33
|
+
},
|
|
34
|
+
callSites: {
|
|
35
|
+
mainAgent: {
|
|
36
|
+
model: "claude-opus-4-7",
|
|
37
|
+
maxTokens: 32000,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("buildInitialConfig seeds Opus when provider falls back to Anthropic", () => {
|
|
45
|
+
expect(
|
|
46
|
+
buildInitialConfig({
|
|
47
|
+
"services.inference.mode": "managed",
|
|
48
|
+
}),
|
|
49
|
+
).toEqual({
|
|
50
|
+
services: {
|
|
51
|
+
inference: {
|
|
52
|
+
mode: "managed",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
llm: {
|
|
56
|
+
callSites: {
|
|
57
|
+
mainAgent: {
|
|
58
|
+
model: "claude-opus-4-7",
|
|
59
|
+
maxTokens: 32000,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("buildInitialConfig preserves explicit mainAgent overrides", () => {
|
|
67
|
+
expect(
|
|
68
|
+
buildInitialConfig({
|
|
69
|
+
"llm.default.provider": "anthropic",
|
|
70
|
+
"llm.default.model": "claude-opus-4-7",
|
|
71
|
+
"llm.callSites.mainAgent.model": "claude-haiku-4-5-20251001",
|
|
72
|
+
}),
|
|
73
|
+
).toEqual({
|
|
74
|
+
llm: {
|
|
75
|
+
default: {
|
|
76
|
+
provider: "anthropic",
|
|
77
|
+
model: "claude-opus-4-7",
|
|
78
|
+
},
|
|
79
|
+
callSites: {
|
|
80
|
+
mainAgent: {
|
|
81
|
+
model: "claude-haiku-4-5-20251001",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("buildInitialConfig respects explicit non-default Anthropic models", () => {
|
|
89
|
+
expect(
|
|
90
|
+
buildInitialConfig({
|
|
91
|
+
"llm.default.provider": "anthropic",
|
|
92
|
+
"llm.default.model": "claude-haiku-4-5-20251001",
|
|
93
|
+
}),
|
|
94
|
+
).toEqual({
|
|
95
|
+
llm: {
|
|
96
|
+
default: {
|
|
97
|
+
provider: "anthropic",
|
|
98
|
+
model: "claude-haiku-4-5-20251001",
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("buildInitialConfig respects active profile provider overrides", () => {
|
|
105
|
+
expect(
|
|
106
|
+
buildInitialConfig({
|
|
107
|
+
"llm.activeProfile": "fast",
|
|
108
|
+
"llm.profiles.fast.provider": "openai",
|
|
109
|
+
"llm.profiles.fast.model": "gpt-5.5",
|
|
110
|
+
}),
|
|
111
|
+
).toEqual({
|
|
112
|
+
llm: {
|
|
113
|
+
activeProfile: "fast",
|
|
114
|
+
profiles: {
|
|
115
|
+
fast: {
|
|
116
|
+
provider: "openai",
|
|
117
|
+
model: "gpt-5.5",
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("buildInitialConfig uses active profile model when deciding to seed", () => {
|
|
125
|
+
expect(
|
|
126
|
+
buildInitialConfig({
|
|
127
|
+
"llm.activeProfile": "fast",
|
|
128
|
+
"llm.profiles.fast.provider": "anthropic",
|
|
129
|
+
"llm.profiles.fast.model": "claude-haiku-4-5-20251001",
|
|
130
|
+
}),
|
|
131
|
+
).toEqual({
|
|
132
|
+
llm: {
|
|
133
|
+
activeProfile: "fast",
|
|
134
|
+
profiles: {
|
|
135
|
+
fast: {
|
|
136
|
+
provider: "anthropic",
|
|
137
|
+
model: "claude-haiku-4-5-20251001",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("buildInitialConfig does not seed Opus for non-Anthropic providers", () => {
|
|
145
|
+
expect(
|
|
146
|
+
buildInitialConfig({
|
|
147
|
+
"llm.default.provider": "openai",
|
|
148
|
+
"llm.default.model": "gpt-5.5",
|
|
149
|
+
}),
|
|
150
|
+
).toEqual({
|
|
151
|
+
llm: {
|
|
152
|
+
default: {
|
|
153
|
+
provider: "openai",
|
|
154
|
+
model: "gpt-5.5",
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
@@ -4,25 +4,21 @@ import { join } from "node:path";
|
|
|
4
4
|
|
|
5
5
|
import { SEEDS } from "../lib/environments/seeds.js";
|
|
6
6
|
|
|
7
|
-
// Drift guard for the
|
|
8
|
-
//
|
|
7
|
+
// Drift guard for the TypeScript sites that hardcode the set of known
|
|
8
|
+
// environment names:
|
|
9
9
|
//
|
|
10
|
-
// 1. cli/src/lib/environments/seeds.ts
|
|
11
|
-
// 2. assistant/src/util/platform.ts
|
|
12
|
-
// 3. clients/chrome-extension/native-host/
|
|
13
|
-
// src/lockfile.ts — NON_PRODUCTION_ENVIRONMENTS set
|
|
10
|
+
// 1. cli/src/lib/environments/seeds.ts — SEEDS record (source of truth)
|
|
11
|
+
// 2. assistant/src/util/platform.ts — KNOWN_ENVIRONMENTS set
|
|
14
12
|
//
|
|
15
13
|
// Cross-package relative imports don't work here: assistant's tsconfig
|
|
16
|
-
// restricts `include` to its own src tree
|
|
17
|
-
//
|
|
18
|
-
// literal sets out of the two external files and asserts they agree with
|
|
19
|
-
// CLI's SEEDS.
|
|
14
|
+
// restricts `include` to its own src tree. So this test parses the literal
|
|
15
|
+
// set out of the external file and asserts it agrees with CLI's SEEDS.
|
|
20
16
|
//
|
|
21
17
|
// FOLLOW-UP: split the env name list into a shared `packages/environments`
|
|
22
|
-
// package (mirroring `packages/
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
18
|
+
// package (mirroring `packages/service-contracts`, `credential-storage`) so
|
|
19
|
+
// both sites can `import { KNOWN_ENVIRONMENTS }` from one place and this
|
|
20
|
+
// drift guard becomes a compile-time check. Planned alongside CLI-driven
|
|
21
|
+
// context support — see the "Environments" design doc.
|
|
26
22
|
|
|
27
23
|
const REPO_ROOT = join(import.meta.dir, "..", "..", "..");
|
|
28
24
|
const ASSISTANT_PLATFORM = join(
|
|
@@ -32,14 +28,6 @@ const ASSISTANT_PLATFORM = join(
|
|
|
32
28
|
"util",
|
|
33
29
|
"platform.ts",
|
|
34
30
|
);
|
|
35
|
-
const NATIVE_HOST_LOCKFILE = join(
|
|
36
|
-
REPO_ROOT,
|
|
37
|
-
"clients",
|
|
38
|
-
"chrome-extension",
|
|
39
|
-
"native-host",
|
|
40
|
-
"src",
|
|
41
|
-
"lockfile.ts",
|
|
42
|
-
);
|
|
43
31
|
|
|
44
32
|
/**
|
|
45
33
|
* Extract the string literals from a Set constructor body in a TS source
|
|
@@ -74,14 +62,4 @@ describe("KNOWN_ENVIRONMENTS drift guard (TS-side)", () => {
|
|
|
74
62
|
);
|
|
75
63
|
expect([...assistantNames].sort()).toEqual([...seedNames].sort());
|
|
76
64
|
});
|
|
77
|
-
|
|
78
|
-
test("native-host/src/lockfile.ts NON_PRODUCTION_ENVIRONMENTS matches CLI SEEDS minus production", () => {
|
|
79
|
-
const source = readFileSync(NATIVE_HOST_LOCKFILE, "utf8");
|
|
80
|
-
const nativeNames = new Set(
|
|
81
|
-
extractSetLiterals(source, "NON_PRODUCTION_ENVIRONMENTS"),
|
|
82
|
-
);
|
|
83
|
-
const expected = new Set(seedNames);
|
|
84
|
-
expected.delete("production");
|
|
85
|
-
expect([...nativeNames].sort()).toEqual([...expected].sort());
|
|
86
|
-
});
|
|
87
65
|
});
|
|
@@ -2,10 +2,7 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { describe, expect, test } from "bun:test";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
LLM_PROVIDER_ENV_VAR_NAMES,
|
|
7
|
-
SEARCH_PROVIDER_ENV_VAR_NAMES,
|
|
8
|
-
} from "../shared/provider-env-vars.js";
|
|
5
|
+
import { LLM_PROVIDER_ENV_VAR_NAMES } from "../shared/provider-env-vars.js";
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* Drift guard for the CLI-side LLM provider env-var mirror.
|
|
@@ -16,8 +13,6 @@ import {
|
|
|
16
13
|
* `meta/llm-provider-catalog.json` — which is kept in sync with
|
|
17
14
|
* `PROVIDER_CATALOG` by `assistant/src/__tests__/llm-catalog-parity.test.ts` —
|
|
18
15
|
* and asserts the CLI's mirror matches the catalog's `envVar` entries.
|
|
19
|
-
*
|
|
20
|
-
* It also asserts the search-provider mirror matches `meta/provider-env-vars.json`.
|
|
21
16
|
*/
|
|
22
17
|
|
|
23
18
|
const REPO_ROOT = join(import.meta.dir, "..", "..", "..");
|
|
@@ -32,21 +27,11 @@ interface LlmCatalog {
|
|
|
32
27
|
providers: LlmCatalogEntry[];
|
|
33
28
|
}
|
|
34
29
|
|
|
35
|
-
interface SearchProviderRegistry {
|
|
36
|
-
version: number;
|
|
37
|
-
providers: Record<string, string>;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
30
|
function loadLlmCatalog(): LlmCatalog {
|
|
41
31
|
const path = join(REPO_ROOT, "meta", "llm-provider-catalog.json");
|
|
42
32
|
return JSON.parse(readFileSync(path, "utf-8"));
|
|
43
33
|
}
|
|
44
34
|
|
|
45
|
-
function loadSearchProviderRegistry(): SearchProviderRegistry {
|
|
46
|
-
const path = join(REPO_ROOT, "meta", "provider-env-vars.json");
|
|
47
|
-
return JSON.parse(readFileSync(path, "utf-8"));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
35
|
describe("CLI provider env-var parity", () => {
|
|
51
36
|
test("LLM_PROVIDER_ENV_VAR_NAMES matches meta/llm-provider-catalog.json entries with envVar", () => {
|
|
52
37
|
const catalog = loadLlmCatalog();
|
|
@@ -56,9 +41,4 @@ describe("CLI provider env-var parity", () => {
|
|
|
56
41
|
}
|
|
57
42
|
expect(LLM_PROVIDER_ENV_VAR_NAMES).toEqual(expected);
|
|
58
43
|
});
|
|
59
|
-
|
|
60
|
-
test("SEARCH_PROVIDER_ENV_VAR_NAMES matches meta/provider-env-vars.json", () => {
|
|
61
|
-
const registry = loadSearchProviderRegistry();
|
|
62
|
-
expect(SEARCH_PROVIDER_ENV_VAR_NAMES).toEqual(registry.providers);
|
|
63
|
-
});
|
|
64
44
|
});
|
|
@@ -114,11 +114,6 @@ describe("multi-local", () => {
|
|
|
114
114
|
expect(res.daemonPort).toBe(DEFAULT_DAEMON_PORT);
|
|
115
115
|
expect(res.gatewayPort).toBe(DEFAULT_GATEWAY_PORT);
|
|
116
116
|
expect(res.qdrantPort).toBe(DEFAULT_QDRANT_PORT);
|
|
117
|
-
|
|
118
|
-
// AND the PID file is under the instance's .vellum/
|
|
119
|
-
expect(res.pidFile).toBe(
|
|
120
|
-
join(res.instanceDir, ".vellum", "vellum.pid"),
|
|
121
|
-
);
|
|
122
117
|
} finally {
|
|
123
118
|
if (prevXdg !== undefined) {
|
|
124
119
|
process.env.XDG_DATA_HOME = prevXdg;
|
|
@@ -52,7 +52,6 @@ function writeLockfile(): void {
|
|
|
52
52
|
daemonPort: DEFAULT_DAEMON_PORT,
|
|
53
53
|
gatewayPort: DEFAULT_GATEWAY_PORT,
|
|
54
54
|
qdrantPort: DEFAULT_QDRANT_PORT,
|
|
55
|
-
pidFile: join(assistantRootDir, "vellum.pid"),
|
|
56
55
|
},
|
|
57
56
|
},
|
|
58
57
|
],
|
|
@@ -158,7 +157,7 @@ describe("sleep command", () => {
|
|
|
158
157
|
expect(stopProcessByPidFileMock).toHaveBeenCalledTimes(2);
|
|
159
158
|
expect(stopProcessByPidFileMock).toHaveBeenNthCalledWith(
|
|
160
159
|
1,
|
|
161
|
-
join(assistantRootDir, "vellum.pid"),
|
|
160
|
+
join(assistantRootDir, "workspace", "vellum.pid"),
|
|
162
161
|
"assistant",
|
|
163
162
|
);
|
|
164
163
|
expect(stopProcessByPidFileMock).toHaveBeenNthCalledWith(
|