herdctl 1.3.10 → 1.4.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 (39) hide show
  1. package/dist/commands/__tests__/agent.test.d.ts +2 -0
  2. package/dist/commands/__tests__/agent.test.d.ts.map +1 -0
  3. package/dist/commands/__tests__/agent.test.js +1461 -0
  4. package/dist/commands/__tests__/agent.test.js.map +1 -0
  5. package/dist/commands/__tests__/init-agent.test.d.ts +2 -0
  6. package/dist/commands/__tests__/init-agent.test.d.ts.map +1 -0
  7. package/dist/commands/__tests__/init-agent.test.js +363 -0
  8. package/dist/commands/__tests__/init-agent.test.js.map +1 -0
  9. package/dist/commands/__tests__/init-fleet.test.d.ts +2 -0
  10. package/dist/commands/__tests__/init-fleet.test.d.ts.map +1 -0
  11. package/dist/commands/__tests__/init-fleet.test.js +154 -0
  12. package/dist/commands/__tests__/init-fleet.test.js.map +1 -0
  13. package/dist/commands/__tests__/init.test.js +43 -213
  14. package/dist/commands/__tests__/init.test.js.map +1 -1
  15. package/dist/commands/agent.d.ts +143 -0
  16. package/dist/commands/agent.d.ts.map +1 -0
  17. package/dist/commands/agent.js +845 -0
  18. package/dist/commands/agent.js.map +1 -0
  19. package/dist/commands/init-agent.d.ts +22 -0
  20. package/dist/commands/init-agent.d.ts.map +1 -0
  21. package/dist/commands/init-agent.js +273 -0
  22. package/dist/commands/init-agent.js.map +1 -0
  23. package/dist/commands/init-fleet.d.ts +13 -0
  24. package/dist/commands/init-fleet.d.ts.map +1 -0
  25. package/dist/commands/init-fleet.js +91 -0
  26. package/dist/commands/init-fleet.js.map +1 -0
  27. package/dist/commands/init-utils.d.ts +8 -0
  28. package/dist/commands/init-utils.d.ts.map +1 -0
  29. package/dist/commands/init-utils.js +24 -0
  30. package/dist/commands/init-utils.js.map +1 -0
  31. package/dist/commands/init.d.ts +9 -9
  32. package/dist/commands/init.d.ts.map +1 -1
  33. package/dist/commands/init.js +30 -289
  34. package/dist/commands/init.js.map +1 -1
  35. package/dist/index.d.ts +3 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +131 -8
  38. package/dist/index.js.map +1 -1
  39. package/package.json +6 -5
@@ -0,0 +1,154 @@
1
+ import * as fs from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import * as path from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { initFleetCommand } from "../init-fleet.js";
6
+ function createTempDir() {
7
+ const baseDir = path.join(tmpdir(), `herdctl-fleet-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
8
+ fs.mkdirSync(baseDir, { recursive: true });
9
+ return fs.realpathSync(baseDir);
10
+ }
11
+ function cleanupTempDir(dir) {
12
+ fs.rmSync(dir, { recursive: true, force: true });
13
+ }
14
+ describe("initFleetCommand", () => {
15
+ let tempDir;
16
+ let originalCwd;
17
+ let consoleLogs;
18
+ let consoleErrors;
19
+ let originalConsoleLog;
20
+ let originalConsoleError;
21
+ let originalProcessExit;
22
+ let exitCode;
23
+ beforeEach(() => {
24
+ tempDir = createTempDir();
25
+ originalCwd = process.cwd();
26
+ process.chdir(tempDir);
27
+ consoleLogs = [];
28
+ consoleErrors = [];
29
+ originalConsoleLog = console.log;
30
+ originalConsoleError = console.error;
31
+ console.log = (...args) => consoleLogs.push(args.join(" "));
32
+ console.error = (...args) => consoleErrors.push(args.join(" "));
33
+ exitCode = undefined;
34
+ originalProcessExit = process.exit;
35
+ process.exit = ((code) => {
36
+ exitCode = code ?? 0;
37
+ throw new Error(`process.exit(${code})`);
38
+ });
39
+ vi.clearAllMocks();
40
+ });
41
+ afterEach(() => {
42
+ process.chdir(originalCwd);
43
+ cleanupTempDir(tempDir);
44
+ console.log = originalConsoleLog;
45
+ console.error = originalConsoleError;
46
+ process.exit = originalProcessExit;
47
+ });
48
+ describe("file creation", () => {
49
+ it("creates herdctl.yaml with fleet name from --name", async () => {
50
+ await initFleetCommand({ name: "my-fleet" });
51
+ const configPath = path.join(tempDir, "herdctl.yaml");
52
+ expect(fs.existsSync(configPath)).toBe(true);
53
+ const content = fs.readFileSync(configPath, "utf-8");
54
+ expect(content).toContain("version: 1");
55
+ expect(content).toContain("name: my-fleet");
56
+ });
57
+ it("creates herdctl.yaml with directory basename when no --name", async () => {
58
+ await initFleetCommand({});
59
+ const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
60
+ expect(content).toContain(`name: ${path.basename(tempDir)}`);
61
+ });
62
+ it("does NOT create agents/ directory", async () => {
63
+ await initFleetCommand({});
64
+ const agentsDir = path.join(tempDir, "agents");
65
+ expect(fs.existsSync(agentsDir)).toBe(false);
66
+ });
67
+ it("creates .herdctl/ directory", async () => {
68
+ await initFleetCommand({});
69
+ const stateDir = path.join(tempDir, ".herdctl");
70
+ expect(fs.existsSync(stateDir)).toBe(true);
71
+ expect(fs.statSync(stateDir).isDirectory()).toBe(true);
72
+ });
73
+ });
74
+ describe("template content", () => {
75
+ it("includes version: 1", async () => {
76
+ await initFleetCommand({});
77
+ const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
78
+ expect(content).toContain("version: 1");
79
+ });
80
+ it("includes commented-out defaults section", async () => {
81
+ await initFleetCommand({});
82
+ const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
83
+ expect(content).toContain("# defaults:");
84
+ expect(content).toContain("# permission_mode: default");
85
+ });
86
+ it("enables web dashboard by default", async () => {
87
+ await initFleetCommand({});
88
+ const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
89
+ expect(content).toContain("web:");
90
+ expect(content).toContain("enabled: true");
91
+ expect(content).toContain("port: 3232");
92
+ });
93
+ it("includes commented-out fleets section", async () => {
94
+ await initFleetCommand({});
95
+ const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
96
+ expect(content).toContain("# fleets:");
97
+ });
98
+ it("includes empty agents array with init agent hint", async () => {
99
+ await initFleetCommand({});
100
+ const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
101
+ expect(content).toContain("agents: []");
102
+ expect(content).toContain("herdctl init agent");
103
+ });
104
+ });
105
+ describe("error handling", () => {
106
+ it("errors if herdctl.yaml already exists", async () => {
107
+ fs.writeFileSync(path.join(tempDir, "herdctl.yaml"), "version: 1");
108
+ await initFleetCommand({});
109
+ expect(process.exitCode).toBe(1);
110
+ });
111
+ it("overwrites with --force", async () => {
112
+ fs.writeFileSync(path.join(tempDir, "herdctl.yaml"), "version: 1\nfleet:\n name: old-fleet");
113
+ await initFleetCommand({ force: true, name: "new-fleet" });
114
+ const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
115
+ expect(content).toContain("name: new-fleet");
116
+ expect(content).not.toContain("old-fleet");
117
+ });
118
+ });
119
+ describe(".gitignore handling", () => {
120
+ it("updates existing .gitignore to include .herdctl/", async () => {
121
+ fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules/\n");
122
+ await initFleetCommand({});
123
+ const gitignore = fs.readFileSync(path.join(tempDir, ".gitignore"), "utf-8");
124
+ expect(gitignore).toContain(".herdctl/");
125
+ expect(gitignore).toContain("node_modules/");
126
+ });
127
+ it("does not duplicate .herdctl/ in .gitignore", async () => {
128
+ fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules/\n.herdctl/\n");
129
+ await initFleetCommand({});
130
+ const gitignore = fs.readFileSync(path.join(tempDir, ".gitignore"), "utf-8");
131
+ const count = (gitignore.match(/\.herdctl\//g) || []).length;
132
+ expect(count).toBe(1);
133
+ });
134
+ it("does not create .gitignore if it does not exist", async () => {
135
+ await initFleetCommand({});
136
+ expect(fs.existsSync(path.join(tempDir, ".gitignore"))).toBe(false);
137
+ });
138
+ });
139
+ describe("output", () => {
140
+ it("prints success message", async () => {
141
+ await initFleetCommand({});
142
+ expect(consoleLogs.some((log) => log.includes("Initialized herdctl fleet"))).toBe(true);
143
+ });
144
+ it("prints next steps including herdctl init agent", async () => {
145
+ await initFleetCommand({});
146
+ expect(consoleLogs.some((log) => log.includes("herdctl init agent"))).toBe(true);
147
+ });
148
+ it("prints herdctl start as next step", async () => {
149
+ await initFleetCommand({});
150
+ expect(consoleLogs.some((log) => log.includes("herdctl start"))).toBe(true);
151
+ });
152
+ });
153
+ });
154
+ //# sourceMappingURL=init-fleet.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-fleet.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/init-fleet.test.ts"],"names":[],"mappings":"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"}
@@ -1,248 +1,78 @@
1
- import * as fs from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import * as path from "node:path";
4
1
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
- import { initCommand } from "../init.js";
6
2
  // Mock @inquirer/prompts
7
3
  vi.mock("@inquirer/prompts", () => ({
8
4
  input: vi.fn(),
9
5
  confirm: vi.fn(),
10
6
  select: vi.fn(),
11
7
  }));
12
- import { confirm, input, select } from "@inquirer/prompts";
13
- const mockedInput = vi.mocked(input);
14
- const mockedConfirm = vi.mocked(confirm);
8
+ // Mock subcommands
9
+ vi.mock("../init-fleet.js", () => ({
10
+ initFleetCommand: vi.fn(),
11
+ }));
12
+ vi.mock("../init-agent.js", () => ({
13
+ initAgentCommand: vi.fn(),
14
+ }));
15
+ import { select } from "@inquirer/prompts";
16
+ import { initRouterAction } from "../init.js";
17
+ import { initAgentCommand } from "../init-agent.js";
18
+ import { initFleetCommand } from "../init-fleet.js";
15
19
  const mockedSelect = vi.mocked(select);
16
- // Helper to create a temp directory
17
- function createTempDir() {
18
- const baseDir = path.join(tmpdir(), `herdctl-cli-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
19
- fs.mkdirSync(baseDir, { recursive: true });
20
- return fs.realpathSync(baseDir);
21
- }
22
- // Helper to clean up temp directory
23
- function cleanupTempDir(dir) {
24
- fs.rmSync(dir, { recursive: true, force: true });
25
- }
26
- describe("initCommand", () => {
27
- let tempDir;
28
- let originalCwd;
29
- let consoleLogs;
20
+ const mockedInitFleet = vi.mocked(initFleetCommand);
21
+ const mockedInitAgent = vi.mocked(initAgentCommand);
22
+ describe("initRouterAction", () => {
30
23
  let consoleErrors;
31
- let originalConsoleLog;
32
24
  let originalConsoleError;
33
25
  let originalProcessExit;
34
26
  let exitCode;
35
27
  beforeEach(() => {
36
- tempDir = createTempDir();
37
- originalCwd = process.cwd();
38
- process.chdir(tempDir);
39
- // Capture console output
40
- consoleLogs = [];
41
28
  consoleErrors = [];
42
- originalConsoleLog = console.log;
43
29
  originalConsoleError = console.error;
44
- console.log = (...args) => consoleLogs.push(args.join(" "));
45
30
  console.error = (...args) => consoleErrors.push(args.join(" "));
46
- // Mock process.exit
47
31
  exitCode = undefined;
48
32
  originalProcessExit = process.exit;
49
33
  process.exit = ((code) => {
50
34
  exitCode = code ?? 0;
51
35
  throw new Error(`process.exit(${code})`);
52
36
  });
53
- // Reset mocks
54
37
  vi.clearAllMocks();
55
38
  });
56
39
  afterEach(() => {
57
- process.chdir(originalCwd);
58
- cleanupTempDir(tempDir);
59
- console.log = originalConsoleLog;
60
40
  console.error = originalConsoleError;
61
41
  process.exit = originalProcessExit;
62
42
  });
63
- describe("with --yes flag (non-interactive)", () => {
64
- it("creates herdctl.yaml with default fleet name from directory", async () => {
65
- await initCommand({ yes: true });
66
- const configPath = path.join(tempDir, "herdctl.yaml");
67
- expect(fs.existsSync(configPath)).toBe(true);
68
- const content = fs.readFileSync(configPath, "utf-8");
69
- expect(content).toContain("version: 1");
70
- expect(content).toContain(`name: ${path.basename(tempDir)}`);
71
- });
72
- it("creates agents/ directory", async () => {
73
- await initCommand({ yes: true });
74
- const agentsDir = path.join(tempDir, "agents");
75
- expect(fs.existsSync(agentsDir)).toBe(true);
76
- expect(fs.statSync(agentsDir).isDirectory()).toBe(true);
77
- });
78
- it("creates .herdctl/ directory", async () => {
79
- await initCommand({ yes: true });
80
- const stateDir = path.join(tempDir, ".herdctl");
81
- expect(fs.existsSync(stateDir)).toBe(true);
82
- expect(fs.statSync(stateDir).isDirectory()).toBe(true);
83
- });
84
- it("creates example agent file with simple template", async () => {
85
- await initCommand({ yes: true });
86
- const agentPath = path.join(tempDir, "agents", "example-agent.yaml");
87
- expect(fs.existsSync(agentPath)).toBe(true);
88
- const content = fs.readFileSync(agentPath, "utf-8");
89
- expect(content).toContain("name: example-agent");
90
- expect(content).toContain("schedules:");
91
- });
92
- it("uses provided --name option", async () => {
93
- await initCommand({ yes: true, name: "my-fleet" });
94
- const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
95
- expect(content).toContain("name: my-fleet");
96
- });
97
- it("shows success message and next steps", async () => {
98
- await initCommand({ yes: true });
99
- expect(consoleLogs.some((log) => log.includes("Initialized herdctl project"))).toBe(true);
100
- expect(consoleLogs.some((log) => log.includes("Next steps"))).toBe(true);
101
- expect(consoleLogs.some((log) => log.includes("herdctl start"))).toBe(true);
102
- });
103
- });
104
- describe("template selection", () => {
105
- it("uses simple template by default", async () => {
106
- await initCommand({ yes: true });
107
- const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
108
- expect(content).toContain("defaults:");
109
- expect(content).toContain("max_turns: 50");
110
- expect(content).not.toContain("model:"); // model should not be set - SDK uses its own default
111
- const agentPath = path.join(tempDir, "agents", "example-agent.yaml");
112
- expect(fs.existsSync(agentPath)).toBe(true);
113
- });
114
- it("uses quickstart template with --example quickstart", async () => {
115
- await initCommand({ yes: true, example: "quickstart" });
116
- const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
117
- expect(content).not.toContain("defaults:");
118
- const agentPath = path.join(tempDir, "agents", "hello-agent.yaml");
119
- expect(fs.existsSync(agentPath)).toBe(true);
120
- const agentContent = fs.readFileSync(agentPath, "utf-8");
121
- expect(agentContent).toContain("name: hello-agent");
122
- expect(agentContent).toContain("interval: 30s");
123
- });
124
- it("uses github template with --example github", async () => {
125
- await initCommand({ yes: true, example: "github" });
126
- const agentPath = path.join(tempDir, "agents", "github-agent.yaml");
127
- expect(fs.existsSync(agentPath)).toBe(true);
128
- const agentContent = fs.readFileSync(agentPath, "utf-8");
129
- expect(agentContent).toContain("name: github-agent");
130
- expect(agentContent).toContain("github_issues");
131
- });
132
- it("exits with error for unknown template", async () => {
133
- await expect(initCommand({ yes: true, example: "nonexistent" })).rejects.toThrow("process.exit");
134
- expect(exitCode).toBe(1);
135
- expect(consoleErrors.some((e) => e.includes("Unknown example template"))).toBe(true);
136
- });
137
- });
138
- describe("error handling", () => {
139
- it("exits with error if herdctl.yaml already exists", async () => {
140
- fs.writeFileSync(path.join(tempDir, "herdctl.yaml"), "version: 1");
141
- await expect(initCommand({ yes: true })).rejects.toThrow("process.exit");
142
- expect(exitCode).toBe(1);
143
- expect(consoleErrors.some((e) => e.includes("herdctl.yaml already exists"))).toBe(true);
144
- });
145
- it("overwrites existing config with --force", async () => {
146
- fs.writeFileSync(path.join(tempDir, "herdctl.yaml"), "version: 1\nfleet:\n name: old-fleet");
147
- await initCommand({ yes: true, force: true, name: "new-fleet" });
148
- const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
149
- expect(content).toContain("name: new-fleet");
150
- expect(content).not.toContain("old-fleet");
151
- });
43
+ it("shows select prompt when invoked without --yes", async () => {
44
+ mockedSelect.mockResolvedValueOnce("fleet");
45
+ mockedInitFleet.mockResolvedValueOnce(undefined);
46
+ await initRouterAction({});
47
+ expect(mockedSelect).toHaveBeenCalledWith(expect.objectContaining({
48
+ message: "What would you like to initialize?",
49
+ }));
152
50
  });
153
- describe(".gitignore handling", () => {
154
- it("updates existing .gitignore to include .herdctl/", async () => {
155
- fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules/\n");
156
- await initCommand({ yes: true });
157
- const gitignore = fs.readFileSync(path.join(tempDir, ".gitignore"), "utf-8");
158
- expect(gitignore).toContain(".herdctl/");
159
- expect(gitignore).toContain("node_modules/");
160
- });
161
- it("does not duplicate .herdctl/ in .gitignore", async () => {
162
- fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules/\n.herdctl/\n");
163
- await initCommand({ yes: true });
164
- const gitignore = fs.readFileSync(path.join(tempDir, ".gitignore"), "utf-8");
165
- const count = (gitignore.match(/\.herdctl\//g) || []).length;
166
- expect(count).toBe(1);
167
- });
168
- it("does not create .gitignore if it does not exist", async () => {
169
- await initCommand({ yes: true });
170
- // .gitignore should not be created
171
- expect(fs.existsSync(path.join(tempDir, ".gitignore"))).toBe(false);
172
- });
51
+ it("routes to fleet init when Fleet is selected", async () => {
52
+ mockedSelect.mockResolvedValueOnce("fleet");
53
+ mockedInitFleet.mockResolvedValueOnce(undefined);
54
+ await initRouterAction({});
55
+ expect(mockedInitFleet).toHaveBeenCalledWith({ force: undefined });
56
+ expect(mockedInitAgent).not.toHaveBeenCalled();
173
57
  });
174
- describe("interactive mode", () => {
175
- it("prompts for fleet name when not provided", async () => {
176
- mockedInput.mockResolvedValueOnce("prompted-fleet"); // fleet name
177
- mockedInput.mockResolvedValueOnce("A test fleet"); // description
178
- mockedSelect.mockResolvedValueOnce("simple"); // template
179
- mockedConfirm.mockResolvedValueOnce(true); // proceed
180
- await initCommand({});
181
- expect(mockedInput).toHaveBeenCalledWith(expect.objectContaining({
182
- message: "Fleet name:",
183
- }));
184
- const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
185
- expect(content).toContain("name: prompted-fleet");
186
- });
187
- it("uses provided name in interactive mode", async () => {
188
- mockedInput.mockResolvedValueOnce("A test fleet"); // description
189
- mockedSelect.mockResolvedValueOnce("simple"); // template
190
- mockedConfirm.mockResolvedValueOnce(true); // proceed
191
- await initCommand({ name: "my-preset-fleet" });
192
- // Should not prompt for fleet name
193
- expect(mockedInput).not.toHaveBeenCalledWith(expect.objectContaining({
194
- message: "Fleet name:",
195
- }));
196
- const content = fs.readFileSync(path.join(tempDir, "herdctl.yaml"), "utf-8");
197
- expect(content).toContain("name: my-preset-fleet");
198
- });
199
- it("aborts when user declines confirmation", async () => {
200
- mockedInput.mockResolvedValueOnce("test-fleet"); // fleet name
201
- mockedInput.mockResolvedValueOnce(""); // description
202
- mockedSelect.mockResolvedValueOnce("simple"); // template
203
- mockedConfirm.mockResolvedValueOnce(false); // decline
204
- await expect(initCommand({})).rejects.toThrow("process.exit");
205
- expect(exitCode).toBe(0);
206
- expect(consoleLogs.some((log) => log.includes("Aborted"))).toBe(true);
207
- // Should not create any files
208
- expect(fs.existsSync(path.join(tempDir, "herdctl.yaml"))).toBe(false);
209
- });
210
- it("skips template prompt when --example is provided", async () => {
211
- mockedInput.mockResolvedValueOnce("test-fleet"); // fleet name
212
- mockedInput.mockResolvedValueOnce(""); // description
213
- mockedConfirm.mockResolvedValueOnce(true); // proceed
214
- await initCommand({ example: "quickstart" });
215
- // Should not prompt for template
216
- expect(mockedSelect).not.toHaveBeenCalled();
217
- });
58
+ it("routes to agent init when Agent is selected", async () => {
59
+ mockedSelect.mockResolvedValueOnce("agent");
60
+ mockedInitAgent.mockResolvedValueOnce(undefined);
61
+ await initRouterAction({});
62
+ expect(mockedInitAgent).toHaveBeenCalledWith(undefined, { force: undefined });
63
+ expect(mockedInitFleet).not.toHaveBeenCalled();
218
64
  });
219
- describe("agents directory behavior", () => {
220
- it("does not overwrite existing agent file without --force", async () => {
221
- fs.mkdirSync(path.join(tempDir, "agents"), { recursive: true });
222
- fs.writeFileSync(path.join(tempDir, "agents", "example-agent.yaml"), "name: existing-agent");
223
- await initCommand({ yes: true, force: true });
224
- const content = fs.readFileSync(path.join(tempDir, "agents", "example-agent.yaml"), "utf-8");
225
- // With force, it should be overwritten
226
- expect(content).toContain("name: example-agent");
227
- });
228
- it("preserves existing agent file without --force", async () => {
229
- fs.mkdirSync(path.join(tempDir, "agents"), { recursive: true });
230
- fs.writeFileSync(path.join(tempDir, "agents", "example-agent.yaml"), "name: existing-agent");
231
- // Need force to overwrite herdctl.yaml, but agent file should be preserved
232
- // Actually this is a new init, so let's test differently
233
- // First create config, then try init with force
234
- fs.writeFileSync(path.join(tempDir, "herdctl.yaml"), "version: 1");
235
- await initCommand({ yes: true, force: true });
236
- // Agent file should be overwritten with --force
237
- const content = fs.readFileSync(path.join(tempDir, "agents", "example-agent.yaml"), "utf-8");
238
- expect(content).toContain("name: example-agent");
239
- });
65
+ it("passes force option through to subcommands", async () => {
66
+ mockedSelect.mockResolvedValueOnce("fleet");
67
+ mockedInitFleet.mockResolvedValueOnce(undefined);
68
+ await initRouterAction({ force: true });
69
+ expect(mockedInitFleet).toHaveBeenCalledWith({ force: true });
240
70
  });
241
- describe("github template specific output", () => {
242
- it("shows github-specific instructions", async () => {
243
- await initCommand({ yes: true, example: "github" });
244
- expect(consoleLogs.some((log) => log.includes("GITHUB_TOKEN"))).toBe(true);
245
- });
71
+ it("errors with --yes and no subcommand", async () => {
72
+ await expect(initRouterAction({ yes: true })).rejects.toThrow("process.exit");
73
+ expect(exitCode).toBe(1);
74
+ expect(consoleErrors.some((e) => e.includes("specify a subcommand"))).toBe(true);
75
+ expect(mockedSelect).not.toHaveBeenCalled();
246
76
  });
247
77
  });
248
78
  //# sourceMappingURL=init.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/init.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/init.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * herdctl agent commands
3
+ *
4
+ * Commands for managing installed agents:
5
+ * - herdctl agent add <source> Install an agent from GitHub or local path
6
+ * - herdctl agent list List all discovered agents in the fleet
7
+ * - herdctl agent info <name> Show detailed information about an agent
8
+ * - herdctl agent remove <name> Remove an installed agent
9
+ *
10
+ * The add command orchestrates the full agent installation flow:
11
+ * 1. Parse source specifier (github:user/repo[@ref] or ./local/path)
12
+ * 2. Fetch repository to temp directory
13
+ * 3. Validate agent repository structure
14
+ * 4. Install files to ./agents/<name>/
15
+ * 5. Update herdctl.yaml with agent reference
16
+ * 6. Scan and display required environment variables
17
+ */
18
+ import { type ResolvedAgent } from "@herdctl/core";
19
+ export interface AgentAddOptions {
20
+ /** Override the target installation directory */
21
+ path?: string;
22
+ /** Show what would happen without making changes */
23
+ dryRun?: boolean;
24
+ /** Overwrite existing agent directory */
25
+ force?: boolean;
26
+ /** Path to config file or directory */
27
+ config?: string;
28
+ }
29
+ export interface AgentRemoveOptions {
30
+ /** Skip confirmation (no-op for now, reserved for future interactive confirmation) */
31
+ force?: boolean;
32
+ /** Preserve workspace directory contents */
33
+ keepWorkspace?: boolean;
34
+ /** Path to config file or directory */
35
+ config?: string;
36
+ }
37
+ /**
38
+ * Install an agent from a source specifier
39
+ *
40
+ * Orchestrates the full installation flow:
41
+ * 1. Parse source specifier
42
+ * 2. Fetch repository
43
+ * 3. Validate repository
44
+ * 4. Install files (unless dry-run)
45
+ * 5. Update fleet config (unless dry-run)
46
+ * 6. Scan and display env variables
47
+ * 7. Cleanup temp directory
48
+ *
49
+ * @param source - Source specifier (e.g., "github:user/repo", "./local/path")
50
+ * @param options - Command options
51
+ */
52
+ export declare function agentAddCommand(source: string, options: AgentAddOptions): Promise<void>;
53
+ export interface AgentListOptions {
54
+ /** Output as JSON for scripting */
55
+ json?: boolean;
56
+ /** Path to config file or directory */
57
+ config?: string;
58
+ }
59
+ /**
60
+ * Maximum number of agents before switching to summary mode.
61
+ * When total agents exceed this threshold, fleet-level counts are shown
62
+ * instead of individual agent names to avoid overwhelming output.
63
+ */
64
+ export declare const TREE_AGENT_THRESHOLD = 200;
65
+ /**
66
+ * Tree node representing a fleet or agent in the hierarchy
67
+ */
68
+ export interface FleetTreeNode {
69
+ name: string;
70
+ description?: string;
71
+ agents: string[];
72
+ children: FleetTreeNode[];
73
+ }
74
+ /**
75
+ * Build a tree structure from a flat array of resolved agents.
76
+ *
77
+ * Groups agents by their fleetPath hierarchy. Root-level agents (empty fleetPath)
78
+ * go directly under the root node. Sub-fleet agents are nested under their
79
+ * respective fleet nodes.
80
+ */
81
+ export declare function buildFleetTree(agents: ResolvedAgent[], rootName: string, rootDescription?: string): FleetTreeNode;
82
+ /**
83
+ * Render a fleet tree with box-drawing characters.
84
+ *
85
+ * Uses standard Unicode box-drawing characters for the tree structure:
86
+ * - Connector for intermediate items
87
+ * - End connector for last items
88
+ * - Vertical bar for continuing branches
89
+ *
90
+ * @param node - The tree node to render
91
+ * @param prefix - Current indentation prefix
92
+ * @param isLast - Whether this node is the last child of its parent
93
+ * @param isRoot - Whether this is the root node
94
+ * @param summaryMode - When true, show agent counts instead of names
95
+ */
96
+ export declare function renderFleetTree(node: FleetTreeNode, prefix?: string, isLast?: boolean, isRoot?: boolean, summaryMode?: boolean): string[];
97
+ /**
98
+ * List all agents in the fleet
99
+ *
100
+ * Discovers agents from the fleet configuration and displays them.
101
+ * When sub-fleets exist, displays a tree view showing agents grouped by fleet hierarchy.
102
+ * When no sub-fleets exist, displays a flat table (original behavior).
103
+ *
104
+ * If total agents across the hierarchy exceed 200, shows fleet-level summary counts
105
+ * instead of individual agent names.
106
+ *
107
+ * @param options - Command options
108
+ */
109
+ export declare function agentListCommand(options: AgentListOptions): Promise<void>;
110
+ export interface AgentInfoOptions {
111
+ /** Output as JSON for scripting */
112
+ json?: boolean;
113
+ /** Path to config file or directory */
114
+ config?: string;
115
+ }
116
+ /**
117
+ * Get detailed information about a specific agent
118
+ *
119
+ * Shows comprehensive agent information including:
120
+ * - Basic info (name, description, status)
121
+ * - Source and installation details
122
+ * - Environment variables
123
+ * - Schedules
124
+ * - Files in the agent directory
125
+ *
126
+ * @param name - Agent name to look up
127
+ * @param options - Command options
128
+ */
129
+ export declare function agentInfoCommand(name: string, options: AgentInfoOptions): Promise<void>;
130
+ /**
131
+ * Remove an agent from the fleet
132
+ *
133
+ * This command:
134
+ * 1. Finds the agent by name in the fleet configuration
135
+ * 2. Deletes the agent directory (optionally preserving workspace)
136
+ * 3. Removes the agent reference from herdctl.yaml
137
+ * 4. Reports environment variables that were used (for cleanup reference)
138
+ *
139
+ * @param name - Agent name to remove
140
+ * @param options - Command options
141
+ */
142
+ export declare function agentRemoveCommand(name: string, options: AgentRemoveOptions): Promise<void>;
143
+ //# sourceMappingURL=agent.d.ts.map