@enactprotocol/shared 2.3.5 → 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.
Files changed (58) hide show
  1. package/README.md +1 -1
  2. package/dist/config.js +1 -1
  3. package/dist/config.js.map +1 -1
  4. package/dist/index.d.ts +3 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/manifest/loader.d.ts +5 -5
  9. package/dist/manifest/loader.d.ts.map +1 -1
  10. package/dist/manifest/loader.js +15 -9
  11. package/dist/manifest/loader.js.map +1 -1
  12. package/dist/manifest/parser.d.ts +1 -1
  13. package/dist/manifest/parser.js +1 -1
  14. package/dist/manifest/validator.d.ts +4 -0
  15. package/dist/manifest/validator.d.ts.map +1 -1
  16. package/dist/manifest/validator.js +6 -0
  17. package/dist/manifest/validator.js.map +1 -1
  18. package/dist/mcp-registry.js +1 -1
  19. package/dist/paths.d.ts +20 -7
  20. package/dist/paths.d.ts.map +1 -1
  21. package/dist/paths.js +47 -14
  22. package/dist/paths.js.map +1 -1
  23. package/dist/registry.d.ts +7 -6
  24. package/dist/registry.d.ts.map +1 -1
  25. package/dist/registry.js +16 -15
  26. package/dist/registry.js.map +1 -1
  27. package/dist/resolver.d.ts +6 -5
  28. package/dist/resolver.d.ts.map +1 -1
  29. package/dist/resolver.js +20 -19
  30. package/dist/resolver.js.map +1 -1
  31. package/dist/types/manifest.d.ts +4 -4
  32. package/dist/types/manifest.d.ts.map +1 -1
  33. package/dist/types/manifest.js +4 -3
  34. package/dist/types/manifest.js.map +1 -1
  35. package/dist/types/organization.d.ts +49 -0
  36. package/dist/types/organization.d.ts.map +1 -0
  37. package/dist/types/organization.js +13 -0
  38. package/dist/types/organization.js.map +1 -0
  39. package/package.json +2 -2
  40. package/src/config.ts +1 -1
  41. package/src/index.ts +12 -0
  42. package/src/manifest/loader.ts +15 -9
  43. package/src/manifest/parser.ts +1 -1
  44. package/src/manifest/validator.ts +7 -0
  45. package/src/mcp-registry.ts +1 -1
  46. package/src/paths.ts +51 -14
  47. package/src/registry.ts +16 -15
  48. package/src/resolver.ts +20 -19
  49. package/src/types/manifest.ts +5 -4
  50. package/src/types/organization.ts +55 -0
  51. package/tests/config.test.ts +1 -1
  52. package/tests/manifest/loader.test.ts +50 -9
  53. package/tests/manifest/parser.test.ts +4 -3
  54. package/tests/manifest-types.test.ts +5 -4
  55. package/tests/paths.test.ts +12 -12
  56. package/tests/registry.test.ts +30 -30
  57. package/tests/resolver.test.ts +11 -11
  58. package/tsconfig.tsbuildinfo +1 -1
@@ -24,12 +24,12 @@ import {
24
24
 
25
25
  const TEST_DIR = join(import.meta.dir, "temp-registry-test");
26
26
  const PROJECT_DIR = join(TEST_DIR, "project");
27
- const PROJECT_ENACT_DIR = join(PROJECT_DIR, ".enact");
27
+ const PROJECT_AGENTS_DIR = join(PROJECT_DIR, "agents");
28
28
 
29
29
  describe("registry", () => {
30
30
  beforeAll(() => {
31
31
  // Create test directory structure
32
- mkdirSync(PROJECT_ENACT_DIR, { recursive: true });
32
+ mkdirSync(PROJECT_AGENTS_DIR, { recursive: true });
33
33
  });
34
34
 
35
35
  afterAll(() => {
@@ -47,14 +47,14 @@ describe("registry", () => {
47
47
  expect(path).toEndWith("tools.json");
48
48
  });
49
49
 
50
- test("returns path for project scope when .enact exists", () => {
50
+ test("returns path for project scope when agents/ exists", () => {
51
51
  const path = getToolsJsonPath("project", PROJECT_DIR);
52
52
  expect(path).not.toBeNull();
53
- expect(path).toContain(PROJECT_ENACT_DIR);
54
- expect(path).toEndWith("tools.json");
53
+ expect(path).toContain(PROJECT_AGENTS_DIR);
54
+ expect(path).toEndWith("skills.json");
55
55
  });
56
56
 
57
- test("returns null for project scope when no .enact", () => {
57
+ test("returns null for project scope when no agents/", () => {
58
58
  const path = getToolsJsonPath("project", "/tmp/nonexistent-test-path");
59
59
  expect(path).toBeNull();
60
60
  });
@@ -63,7 +63,7 @@ describe("registry", () => {
63
63
  describe("loadToolsRegistry", () => {
64
64
  test("returns empty registry when file does not exist", () => {
65
65
  // Ensure tools.json doesn't exist from previous tests
66
- const toolsJsonPath = join(PROJECT_ENACT_DIR, "tools.json");
66
+ const toolsJsonPath = join(PROJECT_AGENTS_DIR, "skills.json");
67
67
  if (existsSync(toolsJsonPath)) {
68
68
  rmSync(toolsJsonPath);
69
69
  }
@@ -73,7 +73,7 @@ describe("registry", () => {
73
73
 
74
74
  test("loads existing registry", () => {
75
75
  // Create a test registry file
76
- const registryPath = join(PROJECT_ENACT_DIR, "tools.json");
76
+ const registryPath = join(PROJECT_AGENTS_DIR, "skills.json");
77
77
  writeFileSync(
78
78
  registryPath,
79
79
  JSON.stringify({
@@ -93,7 +93,7 @@ describe("registry", () => {
93
93
  });
94
94
 
95
95
  test("returns empty registry on parse error", () => {
96
- const registryPath = join(PROJECT_ENACT_DIR, "tools.json");
96
+ const registryPath = join(PROJECT_AGENTS_DIR, "skills.json");
97
97
  writeFileSync(registryPath, "invalid json");
98
98
 
99
99
  const registry = loadToolsRegistry("project", PROJECT_DIR);
@@ -114,7 +114,7 @@ describe("registry", () => {
114
114
 
115
115
  saveToolsRegistry(registry, "project", PROJECT_DIR);
116
116
 
117
- const registryPath = join(PROJECT_ENACT_DIR, "tools.json");
117
+ const registryPath = join(PROJECT_AGENTS_DIR, "skills.json");
118
118
  expect(existsSync(registryPath)).toBe(true);
119
119
 
120
120
  const loaded = loadToolsRegistry("project", PROJECT_DIR);
@@ -133,7 +133,7 @@ describe("registry", () => {
133
133
  expect(registry.tools["test/add"]).toBe("1.0.0");
134
134
 
135
135
  // Clean up
136
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
136
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
137
137
  });
138
138
 
139
139
  test("updates existing tool version", () => {
@@ -144,7 +144,7 @@ describe("registry", () => {
144
144
  expect(registry.tools["test/update"]).toBe("2.0.0");
145
145
 
146
146
  // Clean up
147
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
147
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
148
148
  });
149
149
  });
150
150
 
@@ -159,7 +159,7 @@ describe("registry", () => {
159
159
  expect(registry.tools["test/remove"]).toBeUndefined();
160
160
 
161
161
  // Clean up
162
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
162
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
163
163
  });
164
164
 
165
165
  test("returns false for non-existent tool", () => {
@@ -174,7 +174,7 @@ describe("registry", () => {
174
174
  expect(isToolInstalled("test/installed", "project", PROJECT_DIR)).toBe(true);
175
175
 
176
176
  // Clean up
177
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
177
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
178
178
  });
179
179
 
180
180
  test("returns false for non-installed tool", () => {
@@ -189,7 +189,7 @@ describe("registry", () => {
189
189
  expect(version).toBe("3.0.0");
190
190
 
191
191
  // Clean up
192
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
192
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
193
193
  });
194
194
 
195
195
  test("returns null for non-installed tool", () => {
@@ -199,9 +199,9 @@ describe("registry", () => {
199
199
  });
200
200
 
201
201
  describe("getToolCachePath", () => {
202
- test("returns skill path under ~/.agent/skills/", () => {
202
+ test("returns skill path under ~/.agents/skills/", () => {
203
203
  const path = getToolCachePath("org/tool", "1.0.0");
204
- expect(path).toContain(".agent");
204
+ expect(path).toContain(".agents");
205
205
  expect(path).toContain("skills");
206
206
  expect(path).toContain("org/tool");
207
207
  // No version subdirectory in new layout
@@ -226,7 +226,7 @@ describe("registry", () => {
226
226
  expect(tools.find((t) => t.name === "test/list2")).toBeTruthy();
227
227
 
228
228
  // Clean up
229
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
229
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
230
230
  });
231
231
 
232
232
  test("returns empty list when no tools installed", () => {
@@ -244,7 +244,7 @@ describe("registry", () => {
244
244
  expect(registry.aliases?.mytool).toBe("test/aliased-tool");
245
245
 
246
246
  // Clean up
247
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
247
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
248
248
  });
249
249
 
250
250
  test("throws error when alias already exists for different tool", () => {
@@ -257,7 +257,7 @@ describe("registry", () => {
257
257
  }).toThrow('Alias "shared" already exists for tool "test/tool1"');
258
258
 
259
259
  // Clean up
260
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
260
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
261
261
  });
262
262
 
263
263
  test("allows adding same alias for same tool (idempotent)", () => {
@@ -270,7 +270,7 @@ describe("registry", () => {
270
270
  }).not.toThrow();
271
271
 
272
272
  // Clean up
273
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
273
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
274
274
  });
275
275
  });
276
276
 
@@ -286,7 +286,7 @@ describe("registry", () => {
286
286
  expect(registry.aliases?.removeme).toBeUndefined();
287
287
 
288
288
  // Clean up
289
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
289
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
290
290
  });
291
291
 
292
292
  test("returns false for non-existent alias", () => {
@@ -304,7 +304,7 @@ describe("registry", () => {
304
304
  expect(resolved).toBe("org/full-name");
305
305
 
306
306
  // Clean up
307
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
307
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
308
308
  });
309
309
 
310
310
  test("returns null for non-existent alias", () => {
@@ -325,7 +325,7 @@ describe("registry", () => {
325
325
  expect(aliases.length).toBe(2);
326
326
 
327
327
  // Clean up
328
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
328
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
329
329
  });
330
330
 
331
331
  test("returns empty array for tool without aliases", () => {
@@ -335,7 +335,7 @@ describe("registry", () => {
335
335
  expect(aliases).toEqual([]);
336
336
 
337
337
  // Clean up
338
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
338
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
339
339
  });
340
340
  });
341
341
 
@@ -353,7 +353,7 @@ describe("registry", () => {
353
353
  expect(registry.aliases?.cleanup2).toBeUndefined();
354
354
 
355
355
  // Clean up
356
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
356
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
357
357
  });
358
358
 
359
359
  test("returns 0 for tool without aliases", () => {
@@ -363,7 +363,7 @@ describe("registry", () => {
363
363
  expect(removed).toBe(0);
364
364
 
365
365
  // Clean up
366
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
366
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
367
367
  });
368
368
 
369
369
  test("does not remove aliases for other tools", () => {
@@ -379,13 +379,13 @@ describe("registry", () => {
379
379
  expect(registry.aliases?.removeme).toBeUndefined();
380
380
 
381
381
  // Clean up
382
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"));
382
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"));
383
383
  });
384
384
  });
385
385
 
386
386
  describe("loadToolsRegistry with aliases", () => {
387
387
  test("loads existing registry with aliases", () => {
388
- const registryPath = join(PROJECT_ENACT_DIR, "tools.json");
388
+ const registryPath = join(PROJECT_AGENTS_DIR, "skills.json");
389
389
  writeFileSync(
390
390
  registryPath,
391
391
  JSON.stringify({
@@ -407,7 +407,7 @@ describe("registry", () => {
407
407
  });
408
408
 
409
409
  test("returns empty aliases when not present in file", () => {
410
- const registryPath = join(PROJECT_ENACT_DIR, "tools.json");
410
+ const registryPath = join(PROJECT_AGENTS_DIR, "skills.json");
411
411
  writeFileSync(
412
412
  registryPath,
413
413
  JSON.stringify({
@@ -16,16 +16,16 @@ import {
16
16
 
17
17
  const TEST_DIR = join(import.meta.dir, "temp-resolver-test");
18
18
  const PROJECT_DIR = join(TEST_DIR, "project");
19
- const PROJECT_ENACT_DIR = join(PROJECT_DIR, ".enact");
19
+ const PROJECT_AGENTS_DIR = join(PROJECT_DIR, "agents");
20
20
 
21
21
  describe("tool resolver", () => {
22
22
  beforeAll(() => {
23
23
  // Create test directories
24
- mkdirSync(join(PROJECT_ENACT_DIR, "tools", "test", "project-tool"), { recursive: true });
24
+ mkdirSync(join(PROJECT_AGENTS_DIR, "skills", "test", "project-tool"), { recursive: true });
25
25
 
26
26
  // Create a project-level tool
27
27
  writeFileSync(
28
- join(PROJECT_ENACT_DIR, "tools", "test", "project-tool", "skill.yaml"),
28
+ join(PROJECT_AGENTS_DIR, "skills", "test", "project-tool", "skill.package.yml"),
29
29
  `
30
30
  name: test/project-tool
31
31
  description: A project-level test tool
@@ -37,7 +37,7 @@ version: "1.0.0"
37
37
  // Create a direct tool directory for path-based resolution
38
38
  mkdirSync(join(TEST_DIR, "direct-tool"), { recursive: true });
39
39
  writeFileSync(
40
- join(TEST_DIR, "direct-tool", "skill.yaml"),
40
+ join(TEST_DIR, "direct-tool", "skill.package.yml"),
41
41
  `
42
42
  name: test/direct-tool
43
43
  description: A directly referenced tool
@@ -91,8 +91,8 @@ Documentation here.
91
91
  expect(toolNameToPath("acme/greeter")).toBe("acme/greeter");
92
92
  });
93
93
 
94
- test("strips @ prefix for disk paths", () => {
95
- expect(toolNameToPath("@acme/greeter")).toBe("acme/greeter");
94
+ test("preserves @ prefix for npm-style disk layout", () => {
95
+ expect(toolNameToPath("@acme/greeter")).toBe("@acme/greeter");
96
96
  });
97
97
 
98
98
  test("normalizes backslashes", () => {
@@ -146,7 +146,7 @@ Documentation here.
146
146
  });
147
147
 
148
148
  test("resolves tool from manifest file directly", () => {
149
- const manifestPath = join(TEST_DIR, "direct-tool", "skill.yaml");
149
+ const manifestPath = join(TEST_DIR, "direct-tool", "skill.package.yml");
150
150
  const result = resolveToolFromPath(manifestPath);
151
151
 
152
152
  expect(result.manifest.name).toBe("test/direct-tool");
@@ -289,7 +289,7 @@ Documentation here.
289
289
  } finally {
290
290
  // Clean up
291
291
  removeAlias("pt", "project", PROJECT_DIR);
292
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"), { force: true });
292
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"), { force: true });
293
293
  }
294
294
  });
295
295
 
@@ -311,7 +311,7 @@ Documentation here.
311
311
  expect(mixedResult.manifest.name).toBe("test/project-tool");
312
312
  } finally {
313
313
  removeAlias("mytool", "project", PROJECT_DIR);
314
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"), { force: true });
314
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"), { force: true });
315
315
  }
316
316
  });
317
317
 
@@ -326,7 +326,7 @@ Documentation here.
326
326
  expect(result.manifest.name).toBe("test/project-tool");
327
327
  } finally {
328
328
  removeAlias("test/project-tool", "project", PROJECT_DIR);
329
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"), { force: true });
329
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"), { force: true });
330
330
  }
331
331
  });
332
332
 
@@ -340,7 +340,7 @@ Documentation here.
340
340
  expect(result?.manifest.name).toBe("test/project-tool");
341
341
  } finally {
342
342
  removeAlias("try-alias", "project", PROJECT_DIR);
343
- rmSync(join(PROJECT_ENACT_DIR, "tools.json"), { force: true });
343
+ rmSync(join(PROJECT_AGENTS_DIR, "skills.json"), { force: true });
344
344
  }
345
345
  });
346
346