@herdctl/core 1.3.0 → 2.0.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.
Files changed (181) hide show
  1. package/dist/config/__tests__/agent.test.js +12 -12
  2. package/dist/config/__tests__/agent.test.js.map +1 -1
  3. package/dist/config/__tests__/loader.test.js +201 -4
  4. package/dist/config/__tests__/loader.test.js.map +1 -1
  5. package/dist/config/__tests__/merge.test.js +29 -4
  6. package/dist/config/__tests__/merge.test.js.map +1 -1
  7. package/dist/config/__tests__/parser.test.js +13 -13
  8. package/dist/config/__tests__/parser.test.js.map +1 -1
  9. package/dist/config/__tests__/schema.test.js +10 -10
  10. package/dist/config/__tests__/schema.test.js.map +1 -1
  11. package/dist/config/index.d.ts +1 -1
  12. package/dist/config/index.d.ts.map +1 -1
  13. package/dist/config/index.js +2 -2
  14. package/dist/config/index.js.map +1 -1
  15. package/dist/config/loader.d.ts.map +1 -1
  16. package/dist/config/loader.js +71 -0
  17. package/dist/config/loader.js.map +1 -1
  18. package/dist/config/merge.d.ts +4 -1
  19. package/dist/config/merge.d.ts.map +1 -1
  20. package/dist/config/merge.js +16 -0
  21. package/dist/config/merge.js.map +1 -1
  22. package/dist/config/schema.d.ts +906 -89
  23. package/dist/config/schema.d.ts.map +1 -1
  24. package/dist/config/schema.js +109 -7
  25. package/dist/config/schema.js.map +1 -1
  26. package/dist/fleet-manager/__tests__/coverage.test.js +25 -24
  27. package/dist/fleet-manager/__tests__/coverage.test.js.map +1 -1
  28. package/dist/fleet-manager/__tests__/discord-manager.test.js +9 -2
  29. package/dist/fleet-manager/__tests__/discord-manager.test.js.map +1 -1
  30. package/dist/fleet-manager/__tests__/integration.test.js +27 -0
  31. package/dist/fleet-manager/__tests__/integration.test.js.map +1 -1
  32. package/dist/fleet-manager/__tests__/job-control.test.js +66 -0
  33. package/dist/fleet-manager/__tests__/job-control.test.js.map +1 -1
  34. package/dist/fleet-manager/__tests__/status-queries.test.js +12 -11
  35. package/dist/fleet-manager/__tests__/status-queries.test.js.map +1 -1
  36. package/dist/fleet-manager/config-reload.js +9 -9
  37. package/dist/fleet-manager/config-reload.js.map +1 -1
  38. package/dist/fleet-manager/discord-manager.d.ts.map +1 -1
  39. package/dist/fleet-manager/discord-manager.js +27 -4
  40. package/dist/fleet-manager/discord-manager.js.map +1 -1
  41. package/dist/fleet-manager/fleet-manager.d.ts +11 -0
  42. package/dist/fleet-manager/fleet-manager.d.ts.map +1 -1
  43. package/dist/fleet-manager/fleet-manager.js +27 -0
  44. package/dist/fleet-manager/fleet-manager.js.map +1 -1
  45. package/dist/fleet-manager/job-control.d.ts +1 -1
  46. package/dist/fleet-manager/job-control.d.ts.map +1 -1
  47. package/dist/fleet-manager/job-control.js +36 -14
  48. package/dist/fleet-manager/job-control.js.map +1 -1
  49. package/dist/fleet-manager/schedule-executor.d.ts +1 -1
  50. package/dist/fleet-manager/schedule-executor.d.ts.map +1 -1
  51. package/dist/fleet-manager/schedule-executor.js +11 -14
  52. package/dist/fleet-manager/schedule-executor.js.map +1 -1
  53. package/dist/fleet-manager/status-queries.js +7 -7
  54. package/dist/fleet-manager/status-queries.js.map +1 -1
  55. package/dist/fleet-manager/types.d.ts +10 -2
  56. package/dist/fleet-manager/types.d.ts.map +1 -1
  57. package/dist/fleet-manager/working-directory-helper.d.ts +29 -0
  58. package/dist/fleet-manager/working-directory-helper.d.ts.map +1 -0
  59. package/dist/fleet-manager/working-directory-helper.js +36 -0
  60. package/dist/fleet-manager/working-directory-helper.js.map +1 -0
  61. package/dist/index.d.ts +2 -1
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +4 -1
  64. package/dist/index.js.map +1 -1
  65. package/dist/runner/__tests__/job-executor.test.js +449 -118
  66. package/dist/runner/__tests__/job-executor.test.js.map +1 -1
  67. package/dist/runner/__tests__/sdk-adapter.test.js +147 -23
  68. package/dist/runner/__tests__/sdk-adapter.test.js.map +1 -1
  69. package/dist/runner/index.d.ts +2 -0
  70. package/dist/runner/index.d.ts.map +1 -1
  71. package/dist/runner/index.js +1 -0
  72. package/dist/runner/index.js.map +1 -1
  73. package/dist/runner/job-executor.d.ts +12 -8
  74. package/dist/runner/job-executor.d.ts.map +1 -1
  75. package/dist/runner/job-executor.js +257 -126
  76. package/dist/runner/job-executor.js.map +1 -1
  77. package/dist/runner/runtime/__tests__/cli-session-path.test.d.ts +2 -0
  78. package/dist/runner/runtime/__tests__/cli-session-path.test.d.ts.map +1 -0
  79. package/dist/runner/runtime/__tests__/cli-session-path.test.js +150 -0
  80. package/dist/runner/runtime/__tests__/cli-session-path.test.js.map +1 -0
  81. package/dist/runner/runtime/__tests__/docker-config.test.d.ts +2 -0
  82. package/dist/runner/runtime/__tests__/docker-config.test.d.ts.map +1 -0
  83. package/dist/runner/runtime/__tests__/docker-config.test.js +352 -0
  84. package/dist/runner/runtime/__tests__/docker-config.test.js.map +1 -0
  85. package/dist/runner/runtime/__tests__/docker-security.test.d.ts +2 -0
  86. package/dist/runner/runtime/__tests__/docker-security.test.d.ts.map +1 -0
  87. package/dist/runner/runtime/__tests__/docker-security.test.js +384 -0
  88. package/dist/runner/runtime/__tests__/docker-security.test.js.map +1 -0
  89. package/dist/runner/runtime/__tests__/factory.test.d.ts +2 -0
  90. package/dist/runner/runtime/__tests__/factory.test.d.ts.map +1 -0
  91. package/dist/runner/runtime/__tests__/factory.test.js +149 -0
  92. package/dist/runner/runtime/__tests__/factory.test.js.map +1 -0
  93. package/dist/runner/runtime/__tests__/integration.test.d.ts +2 -0
  94. package/dist/runner/runtime/__tests__/integration.test.d.ts.map +1 -0
  95. package/dist/runner/runtime/__tests__/integration.test.js +274 -0
  96. package/dist/runner/runtime/__tests__/integration.test.js.map +1 -0
  97. package/dist/runner/runtime/cli-runtime.d.ts +107 -0
  98. package/dist/runner/runtime/cli-runtime.d.ts.map +1 -0
  99. package/dist/runner/runtime/cli-runtime.js +335 -0
  100. package/dist/runner/runtime/cli-runtime.js.map +1 -0
  101. package/dist/runner/runtime/cli-session-path.d.ts +108 -0
  102. package/dist/runner/runtime/cli-session-path.d.ts.map +1 -0
  103. package/dist/runner/runtime/cli-session-path.js +173 -0
  104. package/dist/runner/runtime/cli-session-path.js.map +1 -0
  105. package/dist/runner/runtime/cli-session-watcher.d.ts +55 -0
  106. package/dist/runner/runtime/cli-session-watcher.d.ts.map +1 -0
  107. package/dist/runner/runtime/cli-session-watcher.js +187 -0
  108. package/dist/runner/runtime/cli-session-watcher.js.map +1 -0
  109. package/dist/runner/runtime/container-manager.d.ts +76 -0
  110. package/dist/runner/runtime/container-manager.d.ts.map +1 -0
  111. package/dist/runner/runtime/container-manager.js +229 -0
  112. package/dist/runner/runtime/container-manager.js.map +1 -0
  113. package/dist/runner/runtime/container-runner.d.ts +62 -0
  114. package/dist/runner/runtime/container-runner.d.ts.map +1 -0
  115. package/dist/runner/runtime/container-runner.js +235 -0
  116. package/dist/runner/runtime/container-runner.js.map +1 -0
  117. package/dist/runner/runtime/docker-config.d.ts +100 -0
  118. package/dist/runner/runtime/docker-config.d.ts.map +1 -0
  119. package/dist/runner/runtime/docker-config.js +98 -0
  120. package/dist/runner/runtime/docker-config.js.map +1 -0
  121. package/dist/runner/runtime/factory.d.ts +63 -0
  122. package/dist/runner/runtime/factory.d.ts.map +1 -0
  123. package/dist/runner/runtime/factory.js +68 -0
  124. package/dist/runner/runtime/factory.js.map +1 -0
  125. package/dist/runner/runtime/index.d.ts +20 -0
  126. package/dist/runner/runtime/index.d.ts.map +1 -0
  127. package/dist/runner/runtime/index.js +21 -0
  128. package/dist/runner/runtime/index.js.map +1 -0
  129. package/dist/runner/runtime/interface.d.ts +59 -0
  130. package/dist/runner/runtime/interface.d.ts.map +1 -0
  131. package/dist/runner/runtime/interface.js +12 -0
  132. package/dist/runner/runtime/interface.js.map +1 -0
  133. package/dist/runner/runtime/sdk-runtime.d.ts +46 -0
  134. package/dist/runner/runtime/sdk-runtime.d.ts.map +1 -0
  135. package/dist/runner/runtime/sdk-runtime.js +63 -0
  136. package/dist/runner/runtime/sdk-runtime.js.map +1 -0
  137. package/dist/runner/sdk-adapter.d.ts +4 -0
  138. package/dist/runner/sdk-adapter.d.ts.map +1 -1
  139. package/dist/runner/sdk-adapter.js +35 -16
  140. package/dist/runner/sdk-adapter.js.map +1 -1
  141. package/dist/runner/types.d.ts +12 -6
  142. package/dist/runner/types.d.ts.map +1 -1
  143. package/dist/scheduler/__tests__/schedule-runner.test.js +61 -50
  144. package/dist/scheduler/__tests__/schedule-runner.test.js.map +1 -1
  145. package/dist/scheduler/schedule-runner.d.ts +1 -4
  146. package/dist/scheduler/schedule-runner.d.ts.map +1 -1
  147. package/dist/scheduler/schedule-runner.js +40 -8
  148. package/dist/scheduler/schedule-runner.js.map +1 -1
  149. package/dist/state/__tests__/session-schema.test.js +4 -0
  150. package/dist/state/__tests__/session-schema.test.js.map +1 -1
  151. package/dist/state/__tests__/session-validation.test.d.ts +2 -0
  152. package/dist/state/__tests__/session-validation.test.d.ts.map +1 -0
  153. package/dist/state/__tests__/session-validation.test.js +446 -0
  154. package/dist/state/__tests__/session-validation.test.js.map +1 -0
  155. package/dist/state/__tests__/session.test.js +68 -0
  156. package/dist/state/__tests__/session.test.js.map +1 -1
  157. package/dist/state/__tests__/working-directory-validation.test.d.ts +5 -0
  158. package/dist/state/__tests__/working-directory-validation.test.d.ts.map +1 -0
  159. package/dist/state/__tests__/working-directory-validation.test.js +101 -0
  160. package/dist/state/__tests__/working-directory-validation.test.js.map +1 -0
  161. package/dist/state/index.d.ts +2 -0
  162. package/dist/state/index.d.ts.map +1 -1
  163. package/dist/state/index.js +4 -0
  164. package/dist/state/index.js.map +1 -1
  165. package/dist/state/schemas/session-info.d.ts +32 -0
  166. package/dist/state/schemas/session-info.d.ts.map +1 -1
  167. package/dist/state/schemas/session-info.js +22 -0
  168. package/dist/state/schemas/session-info.js.map +1 -1
  169. package/dist/state/session-validation.d.ts +202 -0
  170. package/dist/state/session-validation.d.ts.map +1 -0
  171. package/dist/state/session-validation.js +407 -0
  172. package/dist/state/session-validation.js.map +1 -0
  173. package/dist/state/session.d.ts +23 -3
  174. package/dist/state/session.d.ts.map +1 -1
  175. package/dist/state/session.js +41 -6
  176. package/dist/state/session.js.map +1 -1
  177. package/dist/state/working-directory-validation.d.ts +52 -0
  178. package/dist/state/working-directory-validation.d.ts.map +1 -0
  179. package/dist/state/working-directory-validation.js +81 -0
  180. package/dist/state/working-directory-validation.js.map +1 -0
  181. package/package.json +7 -2
@@ -0,0 +1,384 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { execSync } from "node:child_process";
3
+ import { mkdir, rm, realpath } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+ import { promisify } from "node:util";
7
+ import { exec } from "node:child_process";
8
+ import { buildContainerMounts, buildContainerEnv, } from "../container-manager.js";
9
+ import { resolveDockerConfig } from "../docker-config.js";
10
+ const execAsync = promisify(exec);
11
+ // =============================================================================
12
+ // Environment Detection
13
+ // =============================================================================
14
+ function isDockerAvailable() {
15
+ try {
16
+ execSync("docker info", { stdio: "ignore" });
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ const DOCKER_AVAILABLE = isDockerAvailable();
24
+ // Skip entire file if Docker not available
25
+ const describeDocker = DOCKER_AVAILABLE ? describe : describe.skip;
26
+ // =============================================================================
27
+ // Test Helpers
28
+ // =============================================================================
29
+ async function createTempDir() {
30
+ const baseDir = join(tmpdir(), `herdctl-docker-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
31
+ await mkdir(baseDir, { recursive: true });
32
+ return await realpath(baseDir);
33
+ }
34
+ function createTestAgent(overrides = {}) {
35
+ return {
36
+ name: "test-agent",
37
+ configPath: "/path/to/agent.yaml",
38
+ working_directory: "/workspace/project",
39
+ ...overrides,
40
+ };
41
+ }
42
+ async function inspectContainer(containerId) {
43
+ const { stdout } = await execAsync(`docker inspect ${containerId}`);
44
+ return JSON.parse(stdout)[0];
45
+ }
46
+ async function removeContainer(containerId) {
47
+ try {
48
+ await execAsync(`docker rm -f ${containerId}`);
49
+ }
50
+ catch {
51
+ // Ignore if already removed
52
+ }
53
+ }
54
+ // =============================================================================
55
+ // Docker Security Tests
56
+ // =============================================================================
57
+ describeDocker("Docker Security Hardening", () => {
58
+ let tempDir;
59
+ const containers = [];
60
+ beforeEach(async () => {
61
+ tempDir = await createTempDir();
62
+ });
63
+ afterEach(async () => {
64
+ // Clean up containers
65
+ for (const id of containers) {
66
+ await removeContainer(id);
67
+ }
68
+ containers.length = 0;
69
+ // Clean up temp dir
70
+ await rm(tempDir, { recursive: true, force: true });
71
+ });
72
+ describe("buildContainerMounts", () => {
73
+ it("includes workspace mount", () => {
74
+ const agent = createTestAgent();
75
+ const dockerConfig = resolveDockerConfig({
76
+ enabled: true,
77
+ workspace_mode: "rw",
78
+ });
79
+ const mounts = buildContainerMounts(agent, dockerConfig, tempDir);
80
+ const workspaceMount = mounts.find((m) => m.containerPath === "/workspace");
81
+ expect(workspaceMount).toBeDefined();
82
+ expect(workspaceMount?.mode).toBe("rw");
83
+ });
84
+ it("mounts workspace read-only when workspace_mode is ro", () => {
85
+ const agent = createTestAgent();
86
+ const dockerConfig = resolveDockerConfig({
87
+ enabled: true,
88
+ workspace_mode: "ro",
89
+ });
90
+ const mounts = buildContainerMounts(agent, dockerConfig, tempDir);
91
+ const workspaceMount = mounts.find((m) => m.containerPath === "/workspace");
92
+ expect(workspaceMount?.mode).toBe("ro");
93
+ });
94
+ it("does not mount auth files (uses ANTHROPIC_API_KEY instead)", () => {
95
+ const agent = createTestAgent();
96
+ const dockerConfig = resolveDockerConfig({ enabled: true });
97
+ const mounts = buildContainerMounts(agent, dockerConfig, tempDir);
98
+ // Auth should NOT be mounted - we use ANTHROPIC_API_KEY env var instead
99
+ const authMount = mounts.find((m) => m.containerPath?.includes(".claude") && m.hostPath?.includes(".claude"));
100
+ expect(authMount).toBeUndefined();
101
+ });
102
+ it("includes docker-sessions directory mount at Claude session path", () => {
103
+ const agent = createTestAgent();
104
+ const dockerConfig = resolveDockerConfig({ enabled: true });
105
+ const mounts = buildContainerMounts(agent, dockerConfig, tempDir);
106
+ // Session mount at Claude CLI session location (encoded path: /workspace → -workspace)
107
+ const sessionMount = mounts.find((m) => m.containerPath === "/home/claude/.claude/projects/-workspace");
108
+ expect(sessionMount).toBeDefined();
109
+ expect(sessionMount?.mode).toBe("rw");
110
+ });
111
+ it("includes additional volumes from config", () => {
112
+ const agent = createTestAgent();
113
+ const dockerConfig = resolveDockerConfig({
114
+ enabled: true,
115
+ volumes: ["/data:/data:ro"],
116
+ });
117
+ const mounts = buildContainerMounts(agent, dockerConfig, tempDir);
118
+ const dataMount = mounts.find((m) => m.containerPath === "/data");
119
+ expect(dataMount).toBeDefined();
120
+ expect(dataMount?.mode).toBe("ro");
121
+ });
122
+ it("handles agent workspace as string", () => {
123
+ const agent = createTestAgent({
124
+ working_directory: "/path/to/workspace",
125
+ });
126
+ const dockerConfig = resolveDockerConfig({ enabled: true });
127
+ const mounts = buildContainerMounts(agent, dockerConfig, tempDir);
128
+ const workspaceMount = mounts.find((m) => m.containerPath === "/workspace");
129
+ expect(workspaceMount).toBeDefined();
130
+ expect(workspaceMount?.hostPath).toBe("/path/to/workspace");
131
+ });
132
+ it("handles agent workspace as object with root", () => {
133
+ const agent = createTestAgent({
134
+ working_directory: {
135
+ root: "/path/to/workspace",
136
+ auto_clone: true,
137
+ clone_depth: 1,
138
+ default_branch: "main",
139
+ },
140
+ });
141
+ const dockerConfig = resolveDockerConfig({ enabled: true });
142
+ const mounts = buildContainerMounts(agent, dockerConfig, tempDir);
143
+ const workspaceMount = mounts.find((m) => m.containerPath === "/workspace");
144
+ expect(workspaceMount).toBeDefined();
145
+ expect(workspaceMount?.hostPath).toBe("/path/to/workspace");
146
+ });
147
+ });
148
+ describe("buildContainerEnv", () => {
149
+ it("includes HOME environment variable", () => {
150
+ const agent = createTestAgent();
151
+ const env = buildContainerEnv(agent);
152
+ expect(env).toContain("HOME=/home/claude");
153
+ });
154
+ it("includes TERM environment variable", () => {
155
+ const agent = createTestAgent();
156
+ const env = buildContainerEnv(agent);
157
+ const termEnv = env.find((e) => e.startsWith("TERM="));
158
+ expect(termEnv).toBeDefined();
159
+ });
160
+ it("includes ANTHROPIC_API_KEY if set in process.env", () => {
161
+ const originalKey = process.env.ANTHROPIC_API_KEY;
162
+ process.env.ANTHROPIC_API_KEY = "test-key-123";
163
+ const agent = createTestAgent();
164
+ const env = buildContainerEnv(agent);
165
+ expect(env).toContain("ANTHROPIC_API_KEY=test-key-123");
166
+ // Restore
167
+ if (originalKey) {
168
+ process.env.ANTHROPIC_API_KEY = originalKey;
169
+ }
170
+ else {
171
+ delete process.env.ANTHROPIC_API_KEY;
172
+ }
173
+ });
174
+ it("does not include ANTHROPIC_API_KEY if not set", () => {
175
+ const originalKey = process.env.ANTHROPIC_API_KEY;
176
+ delete process.env.ANTHROPIC_API_KEY;
177
+ const agent = createTestAgent();
178
+ const env = buildContainerEnv(agent);
179
+ const apiKeyEnv = env.find((e) => e.startsWith("ANTHROPIC_API_KEY="));
180
+ expect(apiKeyEnv).toBeUndefined();
181
+ // Restore
182
+ if (originalKey) {
183
+ process.env.ANTHROPIC_API_KEY = originalKey;
184
+ }
185
+ });
186
+ it("includes custom env vars from docker config", () => {
187
+ const agent = createTestAgent();
188
+ const dockerConfig = resolveDockerConfig({
189
+ enabled: true,
190
+ env: {
191
+ GITHUB_TOKEN: "ghp_test123",
192
+ CUSTOM_VAR: "custom_value",
193
+ },
194
+ });
195
+ const env = buildContainerEnv(agent, dockerConfig);
196
+ expect(env).toContain("GITHUB_TOKEN=ghp_test123");
197
+ expect(env).toContain("CUSTOM_VAR=custom_value");
198
+ });
199
+ it("works without docker config (backwards compatible)", () => {
200
+ const agent = createTestAgent();
201
+ const env = buildContainerEnv(agent);
202
+ // Should still include basic env vars
203
+ expect(env).toContain("HOME=/home/claude");
204
+ expect(env.find((e) => e.startsWith("TERM="))).toBeDefined();
205
+ });
206
+ });
207
+ describe("Container Configuration", () => {
208
+ it("applies no-new-privileges security option", async () => {
209
+ // Create a container to inspect (don't start it)
210
+ const { stdout } = await execAsync(`docker create --security-opt=no-new-privileges alpine:latest sleep 1`);
211
+ const containerId = stdout.trim();
212
+ containers.push(containerId);
213
+ const inspection = await inspectContainer(containerId);
214
+ // Verify security options are applied
215
+ expect(inspection.HostConfig.SecurityOpt).toContain("no-new-privileges");
216
+ });
217
+ it("drops all capabilities", async () => {
218
+ const { stdout } = await execAsync(`docker create --cap-drop=ALL alpine:latest sleep 1`);
219
+ const containerId = stdout.trim();
220
+ containers.push(containerId);
221
+ const inspection = await inspectContainer(containerId);
222
+ expect(inspection.HostConfig.CapDrop).toContain("ALL");
223
+ });
224
+ it("sets memory limits", async () => {
225
+ const memoryLimit = 512 * 1024 * 1024; // 512MB
226
+ const { stdout } = await execAsync(`docker create --memory=${memoryLimit} alpine:latest sleep 1`);
227
+ const containerId = stdout.trim();
228
+ containers.push(containerId);
229
+ const inspection = await inspectContainer(containerId);
230
+ expect(inspection.HostConfig.Memory).toBe(memoryLimit);
231
+ });
232
+ it("sets user to non-root", async () => {
233
+ const { stdout } = await execAsync(`docker create --user=1000:1000 alpine:latest sleep 1`);
234
+ const containerId = stdout.trim();
235
+ containers.push(containerId);
236
+ const inspection = await inspectContainer(containerId);
237
+ expect(inspection.Config.User).toBe("1000:1000");
238
+ });
239
+ it("applies network mode", async () => {
240
+ const { stdout } = await execAsync(`docker create --network=bridge alpine:latest sleep 1`);
241
+ const containerId = stdout.trim();
242
+ containers.push(containerId);
243
+ const inspection = await inspectContainer(containerId);
244
+ expect(inspection.HostConfig.NetworkMode).toBe("bridge");
245
+ });
246
+ it("mounts with read-only flag when specified", async () => {
247
+ await mkdir(join(tempDir, "data"), { recursive: true });
248
+ const { stdout } = await execAsync(`docker create -v ${tempDir}/data:/data:ro alpine:latest sleep 1`);
249
+ const containerId = stdout.trim();
250
+ containers.push(containerId);
251
+ const inspection = await inspectContainer(containerId);
252
+ const dataMount = inspection.Mounts.find((m) => m.Destination === "/data");
253
+ expect(dataMount?.RW).toBe(false);
254
+ });
255
+ it("sets AutoRemove when ephemeral is true", async () => {
256
+ const { stdout } = await execAsync(`docker create --rm alpine:latest sleep 1`);
257
+ const containerId = stdout.trim();
258
+ containers.push(containerId);
259
+ const inspection = await inspectContainer(containerId);
260
+ expect(inspection.HostConfig.AutoRemove).toBe(true);
261
+ });
262
+ it("does not set AutoRemove when ephemeral is false", async () => {
263
+ const { stdout } = await execAsync(`docker create alpine:latest sleep 1`);
264
+ const containerId = stdout.trim();
265
+ containers.push(containerId);
266
+ const inspection = await inspectContainer(containerId);
267
+ expect(inspection.HostConfig.AutoRemove).toBe(false);
268
+ });
269
+ it("sets memory and swap limit to same value (no swap)", async () => {
270
+ const memoryLimit = 1024 * 1024 * 1024; // 1GB
271
+ const { stdout } = await execAsync(`docker create --memory=${memoryLimit} --memory-swap=${memoryLimit} alpine:latest sleep 1`);
272
+ const containerId = stdout.trim();
273
+ containers.push(containerId);
274
+ const inspection = await inspectContainer(containerId);
275
+ expect(inspection.HostConfig.Memory).toBe(memoryLimit);
276
+ expect(inspection.HostConfig.MemorySwap).toBe(memoryLimit);
277
+ });
278
+ it("sets CPU shares for resource limits", async () => {
279
+ const cpuShares = 512;
280
+ const { stdout } = await execAsync(`docker create --cpu-shares=${cpuShares} alpine:latest sleep 1`);
281
+ const containerId = stdout.trim();
282
+ containers.push(containerId);
283
+ const inspection = await inspectContainer(containerId);
284
+ expect(inspection.HostConfig.CpuShares).toBe(cpuShares);
285
+ });
286
+ });
287
+ });
288
+ // =============================================================================
289
+ // Docker Config Resolution Tests (don't need Docker running)
290
+ // =============================================================================
291
+ describe("Docker Config Security Defaults", () => {
292
+ it("defaults to bridge network (not none)", () => {
293
+ const config = resolveDockerConfig({ enabled: true });
294
+ expect(config.network).toBe("bridge");
295
+ });
296
+ it("defaults to 2GB memory", () => {
297
+ const config = resolveDockerConfig({ enabled: true });
298
+ expect(config.memoryBytes).toBe(2 * 1024 * 1024 * 1024);
299
+ });
300
+ it("defaults to host user UID:GID", () => {
301
+ const config = resolveDockerConfig({ enabled: true });
302
+ expect(config.user).toMatch(/^\d+:\d+$/);
303
+ });
304
+ it("defaults workspace to read-write", () => {
305
+ const config = resolveDockerConfig({ enabled: true });
306
+ expect(config.workspaceMode).toBe("rw");
307
+ });
308
+ it("defaults ephemeral to true", () => {
309
+ const config = resolveDockerConfig({ enabled: true });
310
+ expect(config.ephemeral).toBe(true);
311
+ });
312
+ it("defaults max_containers to 5", () => {
313
+ const config = resolveDockerConfig({ enabled: true });
314
+ expect(config.maxContainers).toBe(5);
315
+ });
316
+ it("allows custom network mode", () => {
317
+ const config = resolveDockerConfig({
318
+ enabled: true,
319
+ network: "host",
320
+ });
321
+ expect(config.network).toBe("host");
322
+ });
323
+ it("allows custom memory limit", () => {
324
+ const config = resolveDockerConfig({
325
+ enabled: true,
326
+ memory: "512m",
327
+ });
328
+ expect(config.memoryBytes).toBe(512 * 1024 * 1024);
329
+ });
330
+ it("allows custom user", () => {
331
+ const config = resolveDockerConfig({
332
+ enabled: true,
333
+ user: "1001:1001",
334
+ });
335
+ expect(config.user).toBe("1001:1001");
336
+ });
337
+ it("allows custom workspace mode", () => {
338
+ const config = resolveDockerConfig({
339
+ enabled: true,
340
+ workspace_mode: "ro",
341
+ });
342
+ expect(config.workspaceMode).toBe("ro");
343
+ });
344
+ it("allows ephemeral mode", () => {
345
+ const config = resolveDockerConfig({
346
+ enabled: true,
347
+ ephemeral: true,
348
+ });
349
+ expect(config.ephemeral).toBe(true);
350
+ });
351
+ it("allows custom max_containers", () => {
352
+ const config = resolveDockerConfig({
353
+ enabled: true,
354
+ max_containers: 10,
355
+ });
356
+ expect(config.maxContainers).toBe(10);
357
+ });
358
+ it("parses additional volumes correctly", () => {
359
+ const config = resolveDockerConfig({
360
+ enabled: true,
361
+ volumes: ["/host/path:/container/path:ro"],
362
+ });
363
+ expect(config.volumes).toHaveLength(1);
364
+ expect(config.volumes[0].hostPath).toBe("/host/path");
365
+ expect(config.volumes[0].containerPath).toBe("/container/path");
366
+ expect(config.volumes[0].mode).toBe("ro");
367
+ });
368
+ it("uses base_image if image not specified", () => {
369
+ const config = resolveDockerConfig({
370
+ enabled: true,
371
+ base_image: "custom:latest",
372
+ });
373
+ expect(config.image).toBe("custom:latest");
374
+ });
375
+ it("prefers image over base_image", () => {
376
+ const config = resolveDockerConfig({
377
+ enabled: true,
378
+ image: "specific:latest",
379
+ base_image: "fallback:latest",
380
+ });
381
+ expect(config.image).toBe("specific:latest");
382
+ });
383
+ });
384
+ //# sourceMappingURL=docker-security.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-security.test.js","sourceRoot":"","sources":["../../../../src/runner/runtime/__tests__/docker-security.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=factory.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.test.d.ts","sourceRoot":"","sources":["../../../../src/runner/runtime/__tests__/factory.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,149 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { RuntimeFactory } from "../factory.js";
3
+ // =============================================================================
4
+ // Test Helpers
5
+ // =============================================================================
6
+ function createTestAgent(overrides = {}) {
7
+ return {
8
+ name: "test-agent",
9
+ configPath: "/path/to/agent.yaml",
10
+ ...overrides,
11
+ };
12
+ }
13
+ // =============================================================================
14
+ // RuntimeFactory Tests
15
+ // =============================================================================
16
+ describe("RuntimeFactory", () => {
17
+ describe("runtime type selection", () => {
18
+ it("defaults to SDK runtime when runtime not specified", () => {
19
+ const agent = createTestAgent();
20
+ const runtime = RuntimeFactory.create(agent);
21
+ // Verify it's SDKRuntime by checking constructor name
22
+ expect(runtime.constructor.name).toBe("SDKRuntime");
23
+ });
24
+ it("creates SDK runtime for runtime: sdk", () => {
25
+ const agent = createTestAgent({ runtime: "sdk" });
26
+ const runtime = RuntimeFactory.create(agent);
27
+ expect(runtime.constructor.name).toBe("SDKRuntime");
28
+ });
29
+ it("creates CLI runtime for runtime: cli", () => {
30
+ const agent = createTestAgent({ runtime: "cli" });
31
+ const runtime = RuntimeFactory.create(agent);
32
+ expect(runtime.constructor.name).toBe("CLIRuntime");
33
+ });
34
+ it("throws for unknown runtime type", () => {
35
+ const agent = createTestAgent({ runtime: "unknown" });
36
+ expect(() => RuntimeFactory.create(agent)).toThrow("Unknown runtime type: unknown");
37
+ expect(() => RuntimeFactory.create(agent)).toThrow("Supported types: 'sdk' (default), 'cli'");
38
+ });
39
+ });
40
+ describe("Docker wrapping", () => {
41
+ it("returns base runtime when docker not enabled", () => {
42
+ const agent = createTestAgent({
43
+ runtime: "sdk",
44
+ docker: { enabled: false },
45
+ });
46
+ const runtime = RuntimeFactory.create(agent);
47
+ // Should be SDKRuntime, not ContainerRunner
48
+ expect(runtime.constructor.name).toBe("SDKRuntime");
49
+ });
50
+ it("returns base runtime when docker undefined", () => {
51
+ const agent = createTestAgent({
52
+ runtime: "sdk",
53
+ // No docker config at all
54
+ });
55
+ const runtime = RuntimeFactory.create(agent);
56
+ expect(runtime.constructor.name).toBe("SDKRuntime");
57
+ });
58
+ it("wraps with ContainerRunner when docker.enabled is true", () => {
59
+ const agent = createTestAgent({
60
+ runtime: "sdk",
61
+ docker: { enabled: true },
62
+ });
63
+ const runtime = RuntimeFactory.create(agent, {
64
+ stateDir: "/test/.herdctl",
65
+ });
66
+ // Should be wrapped with ContainerRunner
67
+ expect(runtime.constructor.name).toBe("ContainerRunner");
68
+ });
69
+ it("passes stateDir to ContainerRunner", () => {
70
+ const agent = createTestAgent({
71
+ runtime: "sdk",
72
+ docker: { enabled: true },
73
+ });
74
+ const customStateDir = "/custom/state/dir";
75
+ const runtime = RuntimeFactory.create(agent, {
76
+ stateDir: customStateDir,
77
+ });
78
+ expect(runtime.constructor.name).toBe("ContainerRunner");
79
+ // ContainerRunner has a stateDir property we can check
80
+ expect(runtime.stateDir).toBe(customStateDir);
81
+ });
82
+ it("uses default stateDir when not provided", () => {
83
+ const agent = createTestAgent({
84
+ runtime: "sdk",
85
+ docker: { enabled: true },
86
+ });
87
+ const runtime = RuntimeFactory.create(agent);
88
+ expect(runtime.constructor.name).toBe("ContainerRunner");
89
+ // Default should be {cwd}/.herdctl
90
+ const expectedDefault = process.cwd() + "/.herdctl";
91
+ expect(runtime.stateDir).toBe(expectedDefault);
92
+ });
93
+ });
94
+ describe("combined scenarios", () => {
95
+ it("wraps SDK with Docker", () => {
96
+ const agent = createTestAgent({
97
+ runtime: "sdk",
98
+ docker: { enabled: true },
99
+ });
100
+ const runtime = RuntimeFactory.create(agent, {
101
+ stateDir: "/test/.herdctl",
102
+ });
103
+ // Should be wrapped with ContainerRunner
104
+ expect(runtime.constructor.name).toBe("ContainerRunner");
105
+ // Has execute method from RuntimeInterface
106
+ expect(typeof runtime.execute).toBe("function");
107
+ });
108
+ it("wraps CLI with Docker", () => {
109
+ const agent = createTestAgent({
110
+ runtime: "cli",
111
+ docker: { enabled: true },
112
+ });
113
+ const runtime = RuntimeFactory.create(agent, {
114
+ stateDir: "/test/.herdctl",
115
+ });
116
+ // Should be wrapped with ContainerRunner
117
+ expect(runtime.constructor.name).toBe("ContainerRunner");
118
+ // Has execute method from RuntimeInterface
119
+ expect(typeof runtime.execute).toBe("function");
120
+ });
121
+ it("CLI without Docker is unwrapped", () => {
122
+ const agent = createTestAgent({
123
+ runtime: "cli",
124
+ docker: { enabled: false },
125
+ });
126
+ const runtime = RuntimeFactory.create(agent);
127
+ expect(runtime.constructor.name).toBe("CLIRuntime");
128
+ });
129
+ it("handles complex Docker config", () => {
130
+ const agent = createTestAgent({
131
+ runtime: "sdk",
132
+ docker: {
133
+ enabled: true,
134
+ image: "custom:latest",
135
+ network: "none",
136
+ memory: "4g",
137
+ ephemeral: true,
138
+ },
139
+ });
140
+ const runtime = RuntimeFactory.create(agent, {
141
+ stateDir: "/test/.herdctl",
142
+ });
143
+ // Verify it creates ContainerRunner (config is private, we can't test it directly)
144
+ expect(runtime.constructor.name).toBe("ContainerRunner");
145
+ expect(typeof runtime.execute).toBe("function");
146
+ });
147
+ });
148
+ });
149
+ //# sourceMappingURL=factory.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.test.js","sourceRoot":"","sources":["../../../../src/runner/runtime/__tests__/factory.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../../../src/runner/runtime/__tests__/integration.test.ts"],"names":[],"mappings":""}