@enactprotocol/cli 2.1.6 → 2.1.7

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
6
- import { existsSync, mkdirSync, readFileSync, rmSync } from "node:fs";
6
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
7
7
  import { join } from "node:path";
8
8
  import { Command } from "commander";
9
9
  import { configureInitCommand } from "../../src/commands/init";
@@ -107,7 +107,59 @@ describe("init command", () => {
107
107
  }
108
108
  });
109
109
 
110
- test("default mode creates enact.md", async () => {
110
+ test("default mode creates AGENTS.md for tool consumers", async () => {
111
+ const program = new Command();
112
+ program.exitOverride();
113
+ configureInitCommand(program);
114
+
115
+ const originalCwd = process.cwd();
116
+ process.chdir(testDir);
117
+
118
+ try {
119
+ await program.parseAsync(["node", "test", "init"]);
120
+ } catch {
121
+ // Command may throw due to exitOverride
122
+ } finally {
123
+ process.chdir(originalCwd);
124
+ }
125
+
126
+ const agentsPath = join(testDir, "AGENTS.md");
127
+ expect(existsSync(agentsPath)).toBe(true);
128
+
129
+ const content = readFileSync(agentsPath, "utf-8");
130
+ expect(content).toContain("enact search");
131
+ expect(content).toContain("enact install");
132
+ expect(content).toContain("Finding & Installing Tools");
133
+
134
+ // Should NOT create enact.md in default mode
135
+ const manifestPath = join(testDir, "enact.md");
136
+ expect(existsSync(manifestPath)).toBe(false);
137
+ });
138
+
139
+ test("default mode creates .enact/tools.json", async () => {
140
+ const program = new Command();
141
+ program.exitOverride();
142
+ configureInitCommand(program);
143
+
144
+ const originalCwd = process.cwd();
145
+ process.chdir(testDir);
146
+
147
+ try {
148
+ await program.parseAsync(["node", "test", "init"]);
149
+ } catch {
150
+ // Command may throw due to exitOverride
151
+ } finally {
152
+ process.chdir(originalCwd);
153
+ }
154
+
155
+ const toolsJsonPath = join(testDir, ".enact", "tools.json");
156
+ expect(existsSync(toolsJsonPath)).toBe(true);
157
+
158
+ const content = JSON.parse(readFileSync(toolsJsonPath, "utf-8"));
159
+ expect(content).toEqual({ tools: {} });
160
+ });
161
+
162
+ test("--tool mode creates enact.md", async () => {
111
163
  const program = new Command();
112
164
  program.exitOverride(); // Prevent process.exit
113
165
  configureInitCommand(program);
@@ -117,7 +169,7 @@ describe("init command", () => {
117
169
  process.chdir(testDir);
118
170
 
119
171
  try {
120
- await program.parseAsync(["node", "test", "init", "--name", "test/my-tool"]);
172
+ await program.parseAsync(["node", "test", "init", "--tool", "--name", "test/my-tool"]);
121
173
  } catch {
122
174
  // Command may throw due to exitOverride
123
175
  } finally {
@@ -133,7 +185,7 @@ describe("init command", () => {
133
185
  expect(content).toContain("command:");
134
186
  });
135
187
 
136
- test("default mode creates AGENTS.md for tool development", async () => {
188
+ test("--tool mode creates AGENTS.md for tool development", async () => {
137
189
  const program = new Command();
138
190
  program.exitOverride();
139
191
  configureInitCommand(program);
@@ -142,7 +194,7 @@ describe("init command", () => {
142
194
  process.chdir(testDir);
143
195
 
144
196
  try {
145
- await program.parseAsync(["node", "test", "init", "--name", "test/my-tool"]);
197
+ await program.parseAsync(["node", "test", "init", "--tool", "--name", "test/my-tool"]);
146
198
  } catch {
147
199
  // Command may throw due to exitOverride
148
200
  } finally {
@@ -215,6 +267,134 @@ describe("init command", () => {
215
267
  expect(existsSync(join(testDir, "AGENTS.md"))).toBe(false);
216
268
  });
217
269
 
270
+ test("--agent mode creates .enact/tools.json", async () => {
271
+ const program = new Command();
272
+ program.exitOverride();
273
+ configureInitCommand(program);
274
+
275
+ const originalCwd = process.cwd();
276
+ process.chdir(testDir);
277
+
278
+ try {
279
+ await program.parseAsync(["node", "test", "init", "--agent"]);
280
+ } catch {
281
+ // Command may throw due to exitOverride
282
+ } finally {
283
+ process.chdir(originalCwd);
284
+ }
285
+
286
+ const toolsJsonPath = join(testDir, ".enact", "tools.json");
287
+ expect(existsSync(toolsJsonPath)).toBe(true);
288
+
289
+ const content = JSON.parse(readFileSync(toolsJsonPath, "utf-8"));
290
+ expect(content).toEqual({ tools: {} });
291
+ });
292
+
293
+ test("--claude mode creates .enact/tools.json", async () => {
294
+ const program = new Command();
295
+ program.exitOverride();
296
+ configureInitCommand(program);
297
+
298
+ const originalCwd = process.cwd();
299
+ process.chdir(testDir);
300
+
301
+ try {
302
+ await program.parseAsync(["node", "test", "init", "--claude"]);
303
+ } catch {
304
+ // Command may throw due to exitOverride
305
+ } finally {
306
+ process.chdir(originalCwd);
307
+ }
308
+
309
+ const toolsJsonPath = join(testDir, ".enact", "tools.json");
310
+ expect(existsSync(toolsJsonPath)).toBe(true);
311
+
312
+ const content = JSON.parse(readFileSync(toolsJsonPath, "utf-8"));
313
+ expect(content).toEqual({ tools: {} });
314
+ });
315
+
316
+ test("--agent mode with --force overwrites existing .enact/tools.json", async () => {
317
+ // Create existing .enact/tools.json with some content
318
+ const enactDir = join(testDir, ".enact");
319
+ mkdirSync(enactDir, { recursive: true });
320
+ const toolsJsonPath = join(enactDir, "tools.json");
321
+ const existingContent = { tools: { "some/tool": "1.0.0" } };
322
+ writeFileSync(toolsJsonPath, JSON.stringify(existingContent));
323
+
324
+ const program = new Command();
325
+ program.exitOverride();
326
+ configureInitCommand(program);
327
+
328
+ const originalCwd = process.cwd();
329
+ process.chdir(testDir);
330
+
331
+ try {
332
+ await program.parseAsync(["node", "test", "init", "--agent", "--force"]);
333
+ } catch {
334
+ // Command may throw due to exitOverride
335
+ } finally {
336
+ process.chdir(originalCwd);
337
+ }
338
+
339
+ const content = JSON.parse(readFileSync(toolsJsonPath, "utf-8"));
340
+ expect(content).toEqual({ tools: {} });
341
+ });
342
+
343
+ test("--agent mode preserves existing .enact/tools.json without --force", async () => {
344
+ // Create existing .enact/tools.json with some content
345
+ const enactDir = join(testDir, ".enact");
346
+ mkdirSync(enactDir, { recursive: true });
347
+ const toolsJsonPath = join(enactDir, "tools.json");
348
+ const existingContent = { tools: { "some/tool": "1.0.0" } };
349
+ writeFileSync(toolsJsonPath, JSON.stringify(existingContent));
350
+
351
+ // Also create AGENTS.md so the command doesn't fail early
352
+ writeFileSync(join(testDir, "AGENTS.md"), "existing");
353
+
354
+ const program = new Command();
355
+ program.exitOverride();
356
+ configureInitCommand(program);
357
+
358
+ const originalCwd = process.cwd();
359
+ process.chdir(testDir);
360
+
361
+ try {
362
+ // Without --force, AGENTS.md check will fail and return early
363
+ // So we need to test with --force on AGENTS.md but not tools.json
364
+ // Actually the --force flag applies to both, so let's just verify
365
+ // tools.json is preserved when it exists and no --force
366
+ await program.parseAsync(["node", "test", "init", "--agent"]);
367
+ } catch {
368
+ // Command may throw due to exitOverride or warning about existing file
369
+ } finally {
370
+ process.chdir(originalCwd);
371
+ }
372
+
373
+ // tools.json should be preserved since AGENTS.md existed and no --force was used
374
+ const content = JSON.parse(readFileSync(toolsJsonPath, "utf-8"));
375
+ expect(content).toEqual(existingContent);
376
+ });
377
+
378
+ test("--tool mode does NOT create .enact/tools.json", async () => {
379
+ const program = new Command();
380
+ program.exitOverride();
381
+ configureInitCommand(program);
382
+
383
+ const originalCwd = process.cwd();
384
+ process.chdir(testDir);
385
+
386
+ try {
387
+ await program.parseAsync(["node", "test", "init", "--tool", "--name", "test/my-tool"]);
388
+ } catch {
389
+ // Command may throw due to exitOverride
390
+ } finally {
391
+ process.chdir(originalCwd);
392
+ }
393
+
394
+ const toolsJsonPath = join(testDir, ".enact", "tools.json");
395
+ expect(existsSync(toolsJsonPath)).toBe(false);
396
+ });
397
+
218
398
  test("enact.md contains valid YAML frontmatter", async () => {
219
399
  const program = new Command();
220
400
  program.exitOverride();
@@ -224,7 +404,14 @@ describe("init command", () => {
224
404
  process.chdir(testDir);
225
405
 
226
406
  try {
227
- await program.parseAsync(["node", "test", "init", "--name", "myorg/utils/greeter"]);
407
+ await program.parseAsync([
408
+ "node",
409
+ "test",
410
+ "init",
411
+ "--tool",
412
+ "--name",
413
+ "myorg/utils/greeter",
414
+ ]);
228
415
  } catch {
229
416
  // Command may throw due to exitOverride
230
417
  } finally {
@@ -255,7 +442,7 @@ describe("init command", () => {
255
442
  process.chdir(testDir);
256
443
 
257
444
  try {
258
- await program.parseAsync(["node", "test", "init", "--name", "test/tool"]);
445
+ await program.parseAsync(["node", "test", "init", "--tool", "--name", "test/tool"]);
259
446
  } catch {
260
447
  // Command may throw due to exitOverride
261
448
  } finally {
@@ -299,16 +486,16 @@ describe("init command", () => {
299
486
  });
300
487
 
301
488
  describe("option conflicts", () => {
302
- test("--tool is the default when no mode specified", () => {
489
+ test("--agent is the default when no mode specified", () => {
303
490
  const program = new Command();
304
491
  configureInitCommand(program);
305
492
 
306
493
  const initCmd = program.commands.find((cmd) => cmd.name() === "init");
307
494
  const opts = initCmd?.options ?? [];
308
- const toolOpt = opts.find((o) => o.long === "--tool");
495
+ const agentOpt = opts.find((o) => o.long === "--agent");
309
496
 
310
497
  // Description should indicate it's the default
311
- expect(toolOpt?.description).toContain("default");
498
+ expect(agentOpt?.description).toContain("default");
312
499
  });
313
500
  });
314
501
 
@@ -328,7 +515,7 @@ describe("init command", () => {
328
515
  process.chdir(testDir);
329
516
 
330
517
  try {
331
- await program.parseAsync(["node", "test", "init", "--name", "test/tool"]);
518
+ await program.parseAsync(["node", "test", "init", "--tool", "--name", "test/tool"]);
332
519
  } catch {
333
520
  // Command may throw due to exitOverride
334
521
  } finally {
@@ -367,7 +554,7 @@ describe("init command", () => {
367
554
  process.chdir(testDir);
368
555
 
369
556
  try {
370
- await program.parseAsync(["node", "test", "init", "--name", "test/tool"]);
557
+ await program.parseAsync(["node", "test", "init", "--tool", "--name", "test/tool"]);
371
558
  } catch {
372
559
  // Command may throw due to exitOverride
373
560
  } finally {