@enactprotocol/cli 2.3.7 → 2.3.8
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/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +94 -46
- package/dist/commands/init/index.js.map +1 -1
- package/dist/commands/init/templates/agent-agents.d.ts +1 -1
- package/dist/commands/init/templates/agent-agents.d.ts.map +1 -1
- package/dist/commands/init/templates/agent-agents.js +1 -1
- package/dist/commands/init/templates/default-skill-package.d.ts +5 -0
- package/dist/commands/init/templates/default-skill-package.d.ts.map +1 -0
- package/dist/commands/init/templates/default-skill-package.js +13 -0
- package/dist/commands/init/templates/default-skill-package.js.map +1 -0
- package/dist/commands/init/templates/default-skill-script.d.ts +5 -0
- package/dist/commands/init/templates/default-skill-script.d.ts.map +1 -0
- package/dist/commands/init/templates/default-skill-script.js +11 -0
- package/dist/commands/init/templates/default-skill-script.js.map +1 -0
- package/dist/commands/init/templates/index.d.ts +2 -0
- package/dist/commands/init/templates/index.d.ts.map +1 -1
- package/dist/commands/init/templates/index.js +2 -0
- package/dist/commands/init/templates/index.js.map +1 -1
- package/dist/commands/install/index.d.ts +2 -2
- package/dist/commands/install/index.js +18 -18
- package/dist/commands/install/index.js.map +1 -1
- package/dist/commands/list/index.d.ts +2 -2
- package/dist/commands/list/index.js +3 -3
- package/dist/commands/list/index.js.map +1 -1
- package/dist/commands/search/index.js +2 -2
- package/dist/commands/search/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +6 -6
- package/src/commands/init/index.ts +103 -46
- package/src/commands/init/templates/agent-agents.ts +1 -1
- package/src/commands/init/templates/default-skill-package.ts +12 -0
- package/src/commands/init/templates/default-skill-script.ts +10 -0
- package/src/commands/init/templates/index.ts +2 -0
- package/src/commands/install/README.md +1 -1
- package/src/commands/install/index.ts +18 -18
- package/src/commands/list/index.ts +3 -3
- package/src/commands/search/index.ts +2 -2
- package/src/index.ts +1 -1
- package/tests/commands/cache.test.ts +2 -2
- package/tests/commands/init.test.ts +66 -55
- package/tests/commands/install-integration.test.ts +6 -6
- package/tests/e2e.test.ts +10 -10
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -107,7 +107,7 @@ describe("init command", () => {
|
|
|
107
107
|
}
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
-
test("default mode creates
|
|
110
|
+
test("default mode creates skill.package.yaml", async () => {
|
|
111
111
|
const program = new Command();
|
|
112
112
|
program.exitOverride();
|
|
113
113
|
configureInitCommand(program);
|
|
@@ -116,27 +116,23 @@ describe("init command", () => {
|
|
|
116
116
|
process.chdir(testDir);
|
|
117
117
|
|
|
118
118
|
try {
|
|
119
|
-
await program.parseAsync(["node", "test", "init"]);
|
|
119
|
+
await program.parseAsync(["node", "test", "init", "--name", "test/my-tool"]);
|
|
120
120
|
} catch {
|
|
121
121
|
// Command may throw due to exitOverride
|
|
122
122
|
} finally {
|
|
123
123
|
process.chdir(originalCwd);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
const
|
|
127
|
-
expect(existsSync(
|
|
126
|
+
const packagePath = join(testDir, "skill.package.yaml");
|
|
127
|
+
expect(existsSync(packagePath)).toBe(true);
|
|
128
128
|
|
|
129
|
-
const content = readFileSync(
|
|
130
|
-
expect(content).toContain("
|
|
131
|
-
expect(content).toContain("enact
|
|
132
|
-
expect(content).toContain("
|
|
133
|
-
|
|
134
|
-
// Should NOT create enact.md in default mode
|
|
135
|
-
const manifestPath = join(testDir, "enact.md");
|
|
136
|
-
expect(existsSync(manifestPath)).toBe(false);
|
|
129
|
+
const content = readFileSync(packagePath, "utf-8");
|
|
130
|
+
expect(content).toContain("name: test/my-tool");
|
|
131
|
+
expect(content).toContain("enact:");
|
|
132
|
+
expect(content).toContain("scripts:");
|
|
137
133
|
});
|
|
138
134
|
|
|
139
|
-
test("default mode creates .
|
|
135
|
+
test("default mode creates hello.py", async () => {
|
|
140
136
|
const program = new Command();
|
|
141
137
|
program.exitOverride();
|
|
142
138
|
configureInitCommand(program);
|
|
@@ -145,18 +141,19 @@ describe("init command", () => {
|
|
|
145
141
|
process.chdir(testDir);
|
|
146
142
|
|
|
147
143
|
try {
|
|
148
|
-
await program.parseAsync(["node", "test", "init"]);
|
|
144
|
+
await program.parseAsync(["node", "test", "init", "--name", "test/my-tool"]);
|
|
149
145
|
} catch {
|
|
150
146
|
// Command may throw due to exitOverride
|
|
151
147
|
} finally {
|
|
152
148
|
process.chdir(originalCwd);
|
|
153
149
|
}
|
|
154
150
|
|
|
155
|
-
const
|
|
156
|
-
expect(existsSync(
|
|
151
|
+
const scriptPath = join(testDir, "hello.py");
|
|
152
|
+
expect(existsSync(scriptPath)).toBe(true);
|
|
157
153
|
|
|
158
|
-
const content =
|
|
159
|
-
expect(content).
|
|
154
|
+
const content = readFileSync(scriptPath, "utf-8");
|
|
155
|
+
expect(content).toContain("json.dumps");
|
|
156
|
+
expect(content).toContain("Hello");
|
|
160
157
|
});
|
|
161
158
|
|
|
162
159
|
test("--tool mode creates SKILL.md", async () => {
|
|
@@ -267,7 +264,7 @@ describe("init command", () => {
|
|
|
267
264
|
expect(existsSync(join(testDir, "AGENTS.md"))).toBe(false);
|
|
268
265
|
});
|
|
269
266
|
|
|
270
|
-
test("--agent mode creates
|
|
267
|
+
test("--agent mode creates agents/skills.json", async () => {
|
|
271
268
|
const program = new Command();
|
|
272
269
|
program.exitOverride();
|
|
273
270
|
configureInitCommand(program);
|
|
@@ -283,14 +280,14 @@ describe("init command", () => {
|
|
|
283
280
|
process.chdir(originalCwd);
|
|
284
281
|
}
|
|
285
282
|
|
|
286
|
-
const
|
|
287
|
-
expect(existsSync(
|
|
283
|
+
const skillsJsonPath = join(testDir, "agents", "skills.json");
|
|
284
|
+
expect(existsSync(skillsJsonPath)).toBe(true);
|
|
288
285
|
|
|
289
|
-
const content = JSON.parse(readFileSync(
|
|
286
|
+
const content = JSON.parse(readFileSync(skillsJsonPath, "utf-8"));
|
|
290
287
|
expect(content).toEqual({ tools: {} });
|
|
291
288
|
});
|
|
292
289
|
|
|
293
|
-
test("--claude mode creates
|
|
290
|
+
test("--claude mode creates agents/skills.json", async () => {
|
|
294
291
|
const program = new Command();
|
|
295
292
|
program.exitOverride();
|
|
296
293
|
configureInitCommand(program);
|
|
@@ -306,20 +303,20 @@ describe("init command", () => {
|
|
|
306
303
|
process.chdir(originalCwd);
|
|
307
304
|
}
|
|
308
305
|
|
|
309
|
-
const
|
|
310
|
-
expect(existsSync(
|
|
306
|
+
const skillsJsonPath = join(testDir, "agents", "skills.json");
|
|
307
|
+
expect(existsSync(skillsJsonPath)).toBe(true);
|
|
311
308
|
|
|
312
|
-
const content = JSON.parse(readFileSync(
|
|
309
|
+
const content = JSON.parse(readFileSync(skillsJsonPath, "utf-8"));
|
|
313
310
|
expect(content).toEqual({ tools: {} });
|
|
314
311
|
});
|
|
315
312
|
|
|
316
|
-
test("--agent mode with --force overwrites existing
|
|
317
|
-
// Create existing
|
|
318
|
-
const
|
|
319
|
-
mkdirSync(
|
|
320
|
-
const
|
|
313
|
+
test("--agent mode with --force overwrites existing agents/skills.json", async () => {
|
|
314
|
+
// Create existing agents/skills.json with some content
|
|
315
|
+
const agentsDir = join(testDir, "agents");
|
|
316
|
+
mkdirSync(agentsDir, { recursive: true });
|
|
317
|
+
const skillsJsonPath = join(agentsDir, "skills.json");
|
|
321
318
|
const existingContent = { tools: { "some/tool": "1.0.0" } };
|
|
322
|
-
writeFileSync(
|
|
319
|
+
writeFileSync(skillsJsonPath, JSON.stringify(existingContent));
|
|
323
320
|
|
|
324
321
|
const program = new Command();
|
|
325
322
|
program.exitOverride();
|
|
@@ -336,17 +333,17 @@ describe("init command", () => {
|
|
|
336
333
|
process.chdir(originalCwd);
|
|
337
334
|
}
|
|
338
335
|
|
|
339
|
-
const content = JSON.parse(readFileSync(
|
|
336
|
+
const content = JSON.parse(readFileSync(skillsJsonPath, "utf-8"));
|
|
340
337
|
expect(content).toEqual({ tools: {} });
|
|
341
338
|
});
|
|
342
339
|
|
|
343
|
-
test("--agent mode preserves existing
|
|
344
|
-
// Create existing
|
|
345
|
-
const
|
|
346
|
-
mkdirSync(
|
|
347
|
-
const
|
|
340
|
+
test("--agent mode preserves existing agents/skills.json without --force", async () => {
|
|
341
|
+
// Create existing agents/skills.json with some content
|
|
342
|
+
const agentsDir = join(testDir, "agents");
|
|
343
|
+
mkdirSync(agentsDir, { recursive: true });
|
|
344
|
+
const skillsJsonPath = join(agentsDir, "skills.json");
|
|
348
345
|
const existingContent = { tools: { "some/tool": "1.0.0" } };
|
|
349
|
-
writeFileSync(
|
|
346
|
+
writeFileSync(skillsJsonPath, JSON.stringify(existingContent));
|
|
350
347
|
|
|
351
348
|
// Also create AGENTS.md so the command doesn't fail early
|
|
352
349
|
writeFileSync(join(testDir, "AGENTS.md"), "existing");
|
|
@@ -359,10 +356,6 @@ describe("init command", () => {
|
|
|
359
356
|
process.chdir(testDir);
|
|
360
357
|
|
|
361
358
|
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
359
|
await program.parseAsync(["node", "test", "init", "--agent"]);
|
|
367
360
|
} catch {
|
|
368
361
|
// Command may throw due to exitOverride or warning about existing file
|
|
@@ -370,12 +363,12 @@ describe("init command", () => {
|
|
|
370
363
|
process.chdir(originalCwd);
|
|
371
364
|
}
|
|
372
365
|
|
|
373
|
-
//
|
|
374
|
-
const content = JSON.parse(readFileSync(
|
|
366
|
+
// skills.json should be preserved since AGENTS.md existed and no --force was used
|
|
367
|
+
const content = JSON.parse(readFileSync(skillsJsonPath, "utf-8"));
|
|
375
368
|
expect(content).toEqual(existingContent);
|
|
376
369
|
});
|
|
377
370
|
|
|
378
|
-
test("--tool mode does NOT create
|
|
371
|
+
test("--tool mode does NOT create agents/skills.json", async () => {
|
|
379
372
|
const program = new Command();
|
|
380
373
|
program.exitOverride();
|
|
381
374
|
configureInitCommand(program);
|
|
@@ -391,8 +384,8 @@ describe("init command", () => {
|
|
|
391
384
|
process.chdir(originalCwd);
|
|
392
385
|
}
|
|
393
386
|
|
|
394
|
-
const
|
|
395
|
-
expect(existsSync(
|
|
387
|
+
const skillsJsonPath = join(testDir, "agents", "skills.json");
|
|
388
|
+
expect(existsSync(skillsJsonPath)).toBe(false);
|
|
396
389
|
});
|
|
397
390
|
|
|
398
391
|
test("SKILL.md contains valid YAML frontmatter", async () => {
|
|
@@ -481,21 +474,39 @@ describe("init command", () => {
|
|
|
481
474
|
expect(content).toContain("enact search");
|
|
482
475
|
expect(content).toContain("enact install");
|
|
483
476
|
expect(content).toContain("enact list");
|
|
484
|
-
expect(content).toContain("
|
|
477
|
+
expect(content).toContain("agents/skills.json");
|
|
485
478
|
});
|
|
486
479
|
});
|
|
487
480
|
|
|
488
481
|
describe("option conflicts", () => {
|
|
489
|
-
test("
|
|
482
|
+
test("default mode creates a skill when no mode specified", async () => {
|
|
490
483
|
const program = new Command();
|
|
484
|
+
program.exitOverride();
|
|
491
485
|
configureInitCommand(program);
|
|
492
486
|
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
487
|
+
const testDir = join(import.meta.dir, ".test-init-default");
|
|
488
|
+
if (existsSync(testDir)) {
|
|
489
|
+
rmSync(testDir, { recursive: true });
|
|
490
|
+
}
|
|
491
|
+
mkdirSync(testDir, { recursive: true });
|
|
492
|
+
|
|
493
|
+
const originalCwd = process.cwd();
|
|
494
|
+
process.chdir(testDir);
|
|
495
|
+
|
|
496
|
+
try {
|
|
497
|
+
await program.parseAsync(["node", "test", "init", "--name", "test/tool"]);
|
|
498
|
+
} catch {
|
|
499
|
+
// Command may throw due to exitOverride
|
|
500
|
+
} finally {
|
|
501
|
+
process.chdir(originalCwd);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Default should create skill files, not AGENTS.md
|
|
505
|
+
expect(existsSync(join(testDir, "skill.package.yaml"))).toBe(true);
|
|
506
|
+
expect(existsSync(join(testDir, "hello.py"))).toBe(true);
|
|
507
|
+
expect(existsSync(join(testDir, "AGENTS.md"))).toBe(false);
|
|
496
508
|
|
|
497
|
-
|
|
498
|
-
expect(agentOpt?.description).toContain("default");
|
|
509
|
+
rmSync(testDir, { recursive: true });
|
|
499
510
|
});
|
|
500
511
|
});
|
|
501
512
|
|
|
@@ -167,9 +167,9 @@ describe("install integration", () => {
|
|
|
167
167
|
test("global install extracts to skills path", async () => {
|
|
168
168
|
const { getToolCachePath } = await import("@enactprotocol/shared");
|
|
169
169
|
|
|
170
|
-
// Verify skill path structure (~/.
|
|
170
|
+
// Verify skill path structure (~/.agents/skills/{name}/, no version subdir)
|
|
171
171
|
const skillPath = getToolCachePath("test/sample-tool", "1.0.0");
|
|
172
|
-
expect(skillPath).toContain(".
|
|
172
|
+
expect(skillPath).toContain(".agents");
|
|
173
173
|
expect(skillPath).toContain("skills");
|
|
174
174
|
expect(skillPath).toContain("test/sample-tool");
|
|
175
175
|
});
|
|
@@ -260,7 +260,7 @@ describe("tools.json edge cases", () => {
|
|
|
260
260
|
const EDGE_TEST_DIR = join(TEST_BASE, "edge-cases");
|
|
261
261
|
|
|
262
262
|
beforeAll(() => {
|
|
263
|
-
mkdirSync(join(EDGE_TEST_DIR, "
|
|
263
|
+
mkdirSync(join(EDGE_TEST_DIR, "agents"), { recursive: true });
|
|
264
264
|
});
|
|
265
265
|
|
|
266
266
|
afterAll(() => {
|
|
@@ -270,10 +270,10 @@ describe("tools.json edge cases", () => {
|
|
|
270
270
|
});
|
|
271
271
|
|
|
272
272
|
beforeEach(() => {
|
|
273
|
-
// Ensure
|
|
274
|
-
mkdirSync(join(EDGE_TEST_DIR, "
|
|
273
|
+
// Ensure agents directory exists
|
|
274
|
+
mkdirSync(join(EDGE_TEST_DIR, "agents"), { recursive: true });
|
|
275
275
|
|
|
276
|
-
const jsonPath = join(EDGE_TEST_DIR, "
|
|
276
|
+
const jsonPath = join(EDGE_TEST_DIR, "agents", "skills.json");
|
|
277
277
|
if (existsSync(jsonPath)) {
|
|
278
278
|
rmSync(jsonPath);
|
|
279
279
|
}
|
package/tests/e2e.test.ts
CHANGED
|
@@ -119,8 +119,8 @@ describe("E2E: Tool Installation Flow", () => {
|
|
|
119
119
|
}
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
-
test("installs tool to project
|
|
123
|
-
const destBase = join(tempDir, "
|
|
122
|
+
test("installs tool to project agents/skills directory", () => {
|
|
123
|
+
const destBase = join(tempDir, "agents", "skills");
|
|
124
124
|
const { manifest, destPath } = installTool(GREETER_TOOL, destBase);
|
|
125
125
|
|
|
126
126
|
expect(manifest.name).toBe("test/greeter");
|
|
@@ -138,7 +138,7 @@ describe("E2E: Tool Installation Flow", () => {
|
|
|
138
138
|
});
|
|
139
139
|
|
|
140
140
|
test("installs markdown tool correctly", () => {
|
|
141
|
-
const destBase = join(tempDir, "
|
|
141
|
+
const destBase = join(tempDir, "agents", "skills");
|
|
142
142
|
const { manifest, destPath } = installTool(ECHO_TOOL, destBase);
|
|
143
143
|
|
|
144
144
|
expect(manifest.name).toBe("test/echo-tool");
|
|
@@ -146,7 +146,7 @@ describe("E2E: Tool Installation Flow", () => {
|
|
|
146
146
|
});
|
|
147
147
|
|
|
148
148
|
test("installs multiple tools without conflict", () => {
|
|
149
|
-
const destBase = join(tempDir, "
|
|
149
|
+
const destBase = join(tempDir, "agents", "skills");
|
|
150
150
|
|
|
151
151
|
const result1 = installTool(GREETER_TOOL, destBase);
|
|
152
152
|
const result2 = installTool(ECHO_TOOL, destBase);
|
|
@@ -163,7 +163,7 @@ describe("E2E: Tool Installation Flow", () => {
|
|
|
163
163
|
});
|
|
164
164
|
|
|
165
165
|
test("overwrites existing tool on reinstall", () => {
|
|
166
|
-
const destBase = join(tempDir, "
|
|
166
|
+
const destBase = join(tempDir, "agents", "skills");
|
|
167
167
|
|
|
168
168
|
// First install
|
|
169
169
|
const result1 = installTool(GREETER_TOOL, destBase);
|
|
@@ -192,7 +192,7 @@ describe("E2E: Tool Resolution Flow", () => {
|
|
|
192
192
|
mkdirSync(resolveTempDir, { recursive: true });
|
|
193
193
|
|
|
194
194
|
// Install tools
|
|
195
|
-
const destBase = join(resolveTempDir, "
|
|
195
|
+
const destBase = join(resolveTempDir, "agents", "skills");
|
|
196
196
|
installTool(GREETER_TOOL, destBase);
|
|
197
197
|
installTool(ECHO_TOOL, destBase);
|
|
198
198
|
installTool(CALCULATOR_TOOL, destBase);
|
|
@@ -212,7 +212,7 @@ describe("E2E: Tool Resolution Flow", () => {
|
|
|
212
212
|
|
|
213
213
|
test("resolves tool by path", () => {
|
|
214
214
|
// Resolve from installed location
|
|
215
|
-
const toolPath = join(resolveTempDir, "
|
|
215
|
+
const toolPath = join(resolveTempDir, "agents", "skills", "test", "greeter");
|
|
216
216
|
const resolution = tryResolveTool(toolPath);
|
|
217
217
|
expect(resolution).not.toBeNull();
|
|
218
218
|
expect(resolution?.manifest.name).toBe("test/greeter");
|
|
@@ -483,7 +483,7 @@ describe("E2E: Full Workflow", () => {
|
|
|
483
483
|
|
|
484
484
|
test("complete install -> resolve -> validate -> prepare flow (scripts)", () => {
|
|
485
485
|
// 1. Install tool
|
|
486
|
-
const destBase = join(tempDir, "
|
|
486
|
+
const destBase = join(tempDir, "agents", "skills");
|
|
487
487
|
const { manifest } = installTool(GREETER_TOOL, destBase);
|
|
488
488
|
expect(manifest.name).toBe("test/greeter");
|
|
489
489
|
|
|
@@ -509,7 +509,7 @@ describe("E2E: Full Workflow", () => {
|
|
|
509
509
|
|
|
510
510
|
test("complete calculator workflow (scripts)", () => {
|
|
511
511
|
// 1. Install tool
|
|
512
|
-
const destBase = join(tempDir, "
|
|
512
|
+
const destBase = join(tempDir, "agents", "skills");
|
|
513
513
|
const { manifest } = installTool(CALCULATOR_TOOL, destBase);
|
|
514
514
|
|
|
515
515
|
// 2. Resolve tool
|
|
@@ -544,7 +544,7 @@ describe("E2E: Full Workflow", () => {
|
|
|
544
544
|
|
|
545
545
|
test("handles markdown tool workflow (scripts)", () => {
|
|
546
546
|
// Install markdown-based tool
|
|
547
|
-
const destBase = join(tempDir, "
|
|
547
|
+
const destBase = join(tempDir, "agents", "skills");
|
|
548
548
|
const { manifest } = installTool(ECHO_TOOL, destBase);
|
|
549
549
|
expect(manifest.name).toBe("test/echo-tool");
|
|
550
550
|
|