@enactprotocol/shared 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/src/index.ts CHANGED
@@ -24,6 +24,8 @@ export {
24
24
  export {
25
25
  getEnactHome,
26
26
  getProjectEnactDir,
27
+ getProjectAgentsDir,
28
+ getProjectRoot,
27
29
  getToolsDir,
28
30
  getSkillsDir,
29
31
  getCacheDir,
@@ -133,7 +133,7 @@ export function getMcpToolVersion(toolName: string): string | null {
133
133
 
134
134
  /**
135
135
  * Get the install path for an MCP tool
136
- * Skills are stored at ~/.agent/skills/{name}/ (flat, no version subdirectory)
136
+ * Skills are stored at ~/.agents/skills/{name}/ (flat, no version subdirectory)
137
137
  */
138
138
  function getMcpToolCachePath(toolName: string, _version: string): string {
139
139
  const skillsDir = getCacheDir();
package/src/paths.ts CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { existsSync } from "node:fs";
6
6
  import { homedir } from "node:os";
7
- import { join, resolve } from "node:path";
7
+ import { dirname, join, resolve } from "node:path";
8
8
 
9
9
  /**
10
10
  * Scope for tool directories
@@ -48,44 +48,81 @@ export function getProjectEnactDir(startDir?: string): string | null {
48
48
  return null;
49
49
  }
50
50
 
51
+ /**
52
+ * Get the project-level agents directory
53
+ * Searches up from current working directory to find agents/
54
+ * @param startDir - Directory to start searching from (defaults to cwd)
55
+ * @returns Absolute path to agents/ or null if not found
56
+ */
57
+ export function getProjectAgentsDir(startDir?: string): string | null {
58
+ let currentDir = resolve(startDir ?? process.cwd());
59
+ const root = resolve("/");
60
+
61
+ while (currentDir !== root) {
62
+ const agentsDir = join(currentDir, "agents");
63
+ if (existsSync(agentsDir)) {
64
+ return agentsDir;
65
+ }
66
+ const parentDir = resolve(currentDir, "..");
67
+ if (parentDir === currentDir) {
68
+ break;
69
+ }
70
+ currentDir = parentDir;
71
+ }
72
+
73
+ return null;
74
+ }
75
+
76
+ /**
77
+ * Get the project root directory by searching for agents/ directory
78
+ * @param startDir - Directory to start searching from (defaults to cwd)
79
+ * @returns Absolute path to the project root or the startDir/cwd as fallback
80
+ */
81
+ export function getProjectRoot(startDir?: string): string {
82
+ const agentsDir = getProjectAgentsDir(startDir);
83
+ if (agentsDir) {
84
+ return dirname(agentsDir);
85
+ }
86
+ return resolve(startDir ?? process.cwd());
87
+ }
88
+
51
89
  /**
52
90
  * Get the tools directory for specified scope
53
91
  *
54
92
  * NOTE: For global scope ("user"), this is DEPRECATED.
55
- * Global tools are now tracked in ~/.enact/tools.json and stored in cache.
93
+ * Global tools are now tracked in ~/.enact/tools.json and stored in cache (~/.agents/skills/).
56
94
  * Use getToolsJsonPath("global") and getToolCachePath() from ./registry instead.
57
95
  *
58
- * For project scope, this returns .enact/tools/ where project tools are copied.
96
+ * For project scope, this returns agents/skills/ where project tools are installed.
59
97
  *
60
- * @param scope - 'user' for ~/.enact/tools/ (deprecated) or 'project' for .enact/tools/
98
+ * @param scope - 'user' for ~/.agents/skills/ or 'project' for agents/skills/
61
99
  * @param startDir - For project scope, directory to start searching from
62
100
  * @returns Absolute path to tools directory or null if project scope and not found
63
101
  * @deprecated Use registry.ts functions for global tools
64
102
  */
65
103
  export function getToolsDir(scope: ToolScope, startDir?: string): string | null {
66
104
  if (scope === "user") {
67
- // DEPRECATED: Global tools now use tools.json + cache
68
- // This path is kept for backward compatibility during migration
69
- return join(getEnactHome(), "tools");
105
+ // Global tools use ~/.agents/skills/
106
+ return getSkillsDir();
70
107
  }
71
108
 
72
- const projectDir = getProjectEnactDir(startDir);
73
- return projectDir ? join(projectDir, "tools") : null;
109
+ const agentsDir = getProjectAgentsDir(startDir);
110
+ return agentsDir ? join(agentsDir, "skills") : null;
74
111
  }
75
112
 
76
113
  /**
77
- * Get the skills directory (~/.agent/skills/)
114
+ * Get the skills directory (~/.agents/skills/)
78
115
  * This is the standard Agent Skills location for installed skills.
79
- * @returns Absolute path to ~/.agent/skills/
116
+ * @returns Absolute path to ~/.agents/skills/
80
117
  */
81
118
  export function getSkillsDir(): string {
82
- return join(homedir(), ".agent", "skills");
119
+ return join(homedir(), ".agents", "skills");
83
120
  }
84
121
 
85
122
  /**
86
- * Get the cache directory (~/.agent/skills/)
123
+ * Get the cache directory (~/.agents/skills/)
87
124
  * @deprecated Use getSkillsDir() instead
88
- * @returns Absolute path to ~/.agent/skills/
125
+ * @returns Absolute path to ~/.agents/skills/
89
126
  */
90
127
  export function getCacheDir(): string {
91
128
  return getSkillsDir();
package/src/registry.ts CHANGED
@@ -1,17 +1,16 @@
1
1
  /**
2
2
  * Local tool registry management
3
3
  *
4
- * Manages tools.json files for tracking installed tools:
4
+ * Manages skills.json files for tracking installed tools:
5
5
  * - Global: ~/.enact/tools.json (installed with -g)
6
- * - Project: .enact/tools.json (project dependencies)
6
+ * - Project: agents/skills.json (project dependencies)
7
7
  *
8
- * Tools are stored in cache and referenced by version in tools.json.
9
- * This eliminates the need for a separate ~/.enact/tools/ directory.
8
+ * Tools are stored in cache and referenced by version in the registry.
10
9
  */
11
10
 
12
11
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
13
- import { dirname, join } from "node:path";
14
- import { getCacheDir, getEnactHome, getProjectEnactDir } from "./paths";
12
+ import { dirname, join, resolve } from "node:path";
13
+ import { getCacheDir, getEnactHome, getProjectAgentsDir } from "./paths";
15
14
 
16
15
  /**
17
16
  * Structure of tools.json file
@@ -39,15 +38,17 @@ export interface InstalledToolInfo {
39
38
  }
40
39
 
41
40
  /**
42
- * Get the path to tools.json for the specified scope
41
+ * Get the path to the registry file for the specified scope
42
+ * - Global: ~/.enact/tools.json
43
+ * - Project: agents/skills.json
43
44
  */
44
45
  export function getToolsJsonPath(scope: RegistryScope, startDir?: string): string | null {
45
46
  if (scope === "global") {
46
47
  return join(getEnactHome(), "tools.json");
47
48
  }
48
49
 
49
- const projectDir = getProjectEnactDir(startDir);
50
- return projectDir ? join(projectDir, "tools.json") : null;
50
+ const agentsDir = getProjectAgentsDir(startDir);
51
+ return agentsDir ? join(agentsDir, "skills.json") : null;
51
52
  }
52
53
 
53
54
  /**
@@ -84,12 +85,12 @@ export function saveToolsRegistry(
84
85
  ): void {
85
86
  let registryPath = getToolsJsonPath(scope, startDir);
86
87
 
87
- // For project scope, create .enact/ directory if it doesn't exist
88
+ // For project scope, create agents/ directory if it doesn't exist
88
89
  if (!registryPath && scope === "project") {
89
- const projectRoot = startDir ?? process.cwd();
90
- const enactDir = join(projectRoot, ".enact");
91
- mkdirSync(enactDir, { recursive: true });
92
- registryPath = join(enactDir, "tools.json");
90
+ const projectRoot = resolve(startDir ?? process.cwd());
91
+ const agentsDir = join(projectRoot, "agents");
92
+ mkdirSync(agentsDir, { recursive: true });
93
+ registryPath = join(agentsDir, "skills.json");
93
94
  }
94
95
 
95
96
  if (!registryPath) {
@@ -166,7 +167,7 @@ export function getInstalledVersion(
166
167
 
167
168
  /**
168
169
  * Get the install path for a skill
169
- * Skills are stored at ~/.agent/skills/{name}/ (flat, no version subdirectory)
170
+ * Skills are stored at ~/.agents/skills/{name}/ (flat, no version subdirectory)
170
171
  */
171
172
  export function getToolCachePath(toolName: string, _version: string): string {
172
173
  const skillsDir = getCacheDir();
package/src/resolver.ts CHANGED
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * Resolution order:
5
5
  * 1. Direct file path (if provided path exists)
6
- * 2. Project tools (.enact/tools/{name}/)
7
- * 3. Global tools (via ~/.enact/tools.json → ~/.agent/skills/)
8
- * 4. Skills directory (~/.agent/skills/{name}/)
6
+ * 2. Project skills (agents/skills/{name}/)
7
+ * 3. Global tools (via ~/.enact/tools.json → ~/.agents/skills/)
8
+ * 4. Skills directory (~/.agents/skills/{name}/)
9
9
  */
10
10
 
11
11
  import { existsSync } from "node:fs";
@@ -18,7 +18,7 @@ import {
18
18
  loadManifestFromDir,
19
19
  } from "./manifest/loader";
20
20
  import { manifestScriptsToActionsManifest } from "./manifest/scripts";
21
- import { getProjectEnactDir, getSkillsDir } from "./paths";
21
+ import { getProjectAgentsDir, getSkillsDir } from "./paths";
22
22
  import { getInstalledVersion, getToolCachePath, resolveAlias } from "./registry";
23
23
  import type { ToolLocation, ToolResolution } from "./types/manifest";
24
24
 
@@ -336,12 +336,12 @@ export function resolveTool(toolName: string, options: ResolveOptions = {}): Too
336
336
  }
337
337
  }
338
338
 
339
- // 1. Try project tools (.enact/tools/{name}/)
339
+ // 1. Try project skills (agents/skills/{name}/)
340
340
  if (!options.skipProject) {
341
- const projectDir = getProjectEnactDir(options.startDir);
342
- if (projectDir) {
343
- const projectToolsDir = join(projectDir, "tools");
344
- const toolDir = getToolPath(projectToolsDir, normalizedName);
341
+ const agentsDir = getProjectAgentsDir(options.startDir);
342
+ if (agentsDir) {
343
+ const projectSkillsDir = join(agentsDir, "skills");
344
+ const toolDir = getToolPath(projectSkillsDir, normalizedName);
345
345
  searchedLocations.push(toolDir);
346
346
 
347
347
  const result = tryLoadFromDir(toolDir, "project");
@@ -351,7 +351,7 @@ export function resolveTool(toolName: string, options: ResolveOptions = {}): Too
351
351
  }
352
352
  }
353
353
 
354
- // 2. Try global tools (via ~/.enact/tools.json → ~/.agent/skills/)
354
+ // 2. Try global tools (via ~/.enact/tools.json → ~/.agents/skills/)
355
355
  if (!options.skipUser) {
356
356
  const globalVersion = getInstalledVersion(normalizedName, "global");
357
357
  if (globalVersion) {
@@ -365,7 +365,7 @@ export function resolveTool(toolName: string, options: ResolveOptions = {}): Too
365
365
  }
366
366
  }
367
367
 
368
- // 3. Try skills directory (~/.agent/skills/{name}/)
368
+ // 3. Try skills directory (~/.agents/skills/{name}/)
369
369
  if (!options.skipCache) {
370
370
  const skillsDir = getSkillsDir();
371
371
  const skillDir = getToolPath(skillsDir, normalizedName);
@@ -561,11 +561,11 @@ export function getToolSearchPaths(toolName: string, options: ResolveOptions = {
561
561
  const normalizedName = normalizeToolName(toolName);
562
562
  const paths: string[] = [];
563
563
 
564
- // Project tools
564
+ // Project skills
565
565
  if (!options.skipProject) {
566
- const projectDir = getProjectEnactDir(options.startDir);
567
- if (projectDir) {
568
- paths.push(join(projectDir, "tools", toolNameToPath(normalizedName)));
566
+ const agentsDir = getProjectAgentsDir(options.startDir);
567
+ if (agentsDir) {
568
+ paths.push(join(agentsDir, "skills", toolNameToPath(normalizedName)));
569
569
  }
570
570
  }
571
571
 
@@ -534,7 +534,7 @@ describe("configuration manager", () => {
534
534
  expect(existsSync(enactHome)).toBe(true);
535
535
  });
536
536
 
537
- test("creates ~/.agent/skills/ directory", () => {
537
+ test("creates ~/.agents/skills/ directory", () => {
538
538
  const enactHome = getEnactHome();
539
539
  const cacheDir = getCacheDir();
540
540
 
@@ -21,6 +21,7 @@ describe("path utilities", () => {
21
21
  // Create test directory structure
22
22
  mkdirSync(NESTED_DIR, { recursive: true });
23
23
  mkdirSync(join(TEST_DIR, ".enact"), { recursive: true });
24
+ mkdirSync(join(TEST_DIR, "agents"), { recursive: true });
24
25
  });
25
26
 
26
27
  afterAll(() => {
@@ -81,36 +82,35 @@ describe("path utilities", () => {
81
82
  });
82
83
 
83
84
  describe("getToolsDir", () => {
84
- test("returns ~/.enact/tools/ for user scope", () => {
85
+ test("returns ~/.agents/skills/ for user scope", () => {
85
86
  const result = getToolsDir("user");
86
- const expected = join(homedir(), ".enact", "tools");
87
+ const expected = join(homedir(), ".agents", "skills");
87
88
  expect(result).toBe(expected);
88
89
  });
89
90
 
90
- test("returns .enact/tools/ for project scope", () => {
91
+ test("returns agents/skills/ for project scope", () => {
91
92
  const result = getToolsDir("project", TEST_DIR);
92
- expect(result).toBe(join(TEST_DIR, ".enact", "tools"));
93
+ expect(result).toBe(join(TEST_DIR, "agents", "skills"));
93
94
  });
94
95
 
95
96
  test("finds project tools in parent directory", () => {
96
97
  const result = getToolsDir("project", NESTED_DIR);
97
- expect(result).toBe(join(TEST_DIR, ".enact", "tools"));
98
+ expect(result).toBe(join(TEST_DIR, "agents", "skills"));
98
99
  });
99
100
 
100
- test("returns null for project scope when .enact not found", () => {
101
- // Similar to above - may find ~/.enact/ if it exists
102
- const result = getToolsDir("project", "/tmp/no-enact-unlikely-path");
103
- // Result will be null or a valid tools directory
101
+ test("returns null for project scope when agents/ not found", () => {
102
+ const result = getToolsDir("project", "/tmp/no-agents-unlikely-path");
103
+ // Result will be null or a valid skills directory
104
104
  if (result !== null) {
105
- expect(result.endsWith("tools")).toBe(true);
105
+ expect(result.endsWith("skills")).toBe(true);
106
106
  }
107
107
  });
108
108
  });
109
109
 
110
110
  describe("getSkillsDir", () => {
111
- test("returns ~/.agent/skills/ path", () => {
111
+ test("returns ~/.agents/skills/ path", () => {
112
112
  const result = getSkillsDir();
113
- const expected = join(homedir(), ".agent", "skills");
113
+ const expected = join(homedir(), ".agents", "skills");
114
114
  expect(result).toBe(expected);
115
115
  });
116
116
  });
@@ -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.package.yml"),
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
@@ -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