@enactprotocol/shared 1.2.13 → 2.0.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.
- package/README.md +44 -0
- package/package.json +16 -58
- package/src/config.ts +476 -0
- package/src/constants.ts +36 -0
- package/src/execution/command.ts +314 -0
- package/src/execution/index.ts +73 -0
- package/src/execution/runtime.ts +308 -0
- package/src/execution/types.ts +379 -0
- package/src/execution/validation.ts +508 -0
- package/src/index.ts +237 -30
- package/src/manifest/index.ts +36 -0
- package/src/manifest/loader.ts +187 -0
- package/src/manifest/parser.ts +173 -0
- package/src/manifest/validator.ts +309 -0
- package/src/paths.ts +108 -0
- package/src/registry.ts +219 -0
- package/src/resolver.ts +345 -0
- package/src/types/index.ts +30 -0
- package/src/types/manifest.ts +255 -0
- package/src/types.ts +5 -188
- package/src/utils/fs.ts +281 -0
- package/src/utils/logger.ts +270 -59
- package/src/utils/version.ts +304 -36
- package/tests/config.test.ts +515 -0
- package/tests/execution/command.test.ts +317 -0
- package/tests/execution/validation.test.ts +384 -0
- package/tests/fixtures/invalid-tool.yaml +4 -0
- package/tests/fixtures/valid-tool.md +62 -0
- package/tests/fixtures/valid-tool.yaml +40 -0
- package/tests/index.test.ts +8 -0
- package/tests/manifest/loader.test.ts +291 -0
- package/tests/manifest/parser.test.ts +345 -0
- package/tests/manifest/validator.test.ts +394 -0
- package/tests/manifest-types.test.ts +358 -0
- package/tests/paths.test.ts +153 -0
- package/tests/registry.test.ts +231 -0
- package/tests/resolver.test.ts +272 -0
- package/tests/utils/fs.test.ts +388 -0
- package/tests/utils/logger.test.ts +480 -0
- package/tests/utils/version.test.ts +390 -0
- package/tsconfig.json +12 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/dist/LocalToolResolver.d.ts +0 -84
- package/dist/LocalToolResolver.js +0 -353
- package/dist/api/enact-api.d.ts +0 -130
- package/dist/api/enact-api.js +0 -428
- package/dist/api/index.d.ts +0 -2
- package/dist/api/index.js +0 -2
- package/dist/api/types.d.ts +0 -103
- package/dist/api/types.js +0 -1
- package/dist/constants.d.ts +0 -7
- package/dist/constants.js +0 -10
- package/dist/core/DaggerExecutionProvider.d.ts +0 -169
- package/dist/core/DaggerExecutionProvider.js +0 -1029
- package/dist/core/DirectExecutionProvider.d.ts +0 -23
- package/dist/core/DirectExecutionProvider.js +0 -406
- package/dist/core/EnactCore.d.ts +0 -162
- package/dist/core/EnactCore.js +0 -597
- package/dist/core/NativeExecutionProvider.d.ts +0 -9
- package/dist/core/NativeExecutionProvider.js +0 -16
- package/dist/core/index.d.ts +0 -3
- package/dist/core/index.js +0 -3
- package/dist/exec/index.d.ts +0 -3
- package/dist/exec/index.js +0 -3
- package/dist/exec/logger.d.ts +0 -11
- package/dist/exec/logger.js +0 -57
- package/dist/exec/validate.d.ts +0 -5
- package/dist/exec/validate.js +0 -167
- package/dist/index.d.ts +0 -21
- package/dist/index.js +0 -25
- package/dist/lib/enact-direct.d.ts +0 -150
- package/dist/lib/enact-direct.js +0 -159
- package/dist/lib/index.d.ts +0 -1
- package/dist/lib/index.js +0 -1
- package/dist/security/index.d.ts +0 -3
- package/dist/security/index.js +0 -3
- package/dist/security/security.d.ts +0 -23
- package/dist/security/security.js +0 -137
- package/dist/security/sign.d.ts +0 -103
- package/dist/security/sign.js +0 -666
- package/dist/security/verification-enforcer.d.ts +0 -53
- package/dist/security/verification-enforcer.js +0 -204
- package/dist/services/McpCoreService.d.ts +0 -98
- package/dist/services/McpCoreService.js +0 -124
- package/dist/services/index.d.ts +0 -1
- package/dist/services/index.js +0 -1
- package/dist/types.d.ts +0 -132
- package/dist/types.js +0 -3
- package/dist/utils/config.d.ts +0 -111
- package/dist/utils/config.js +0 -342
- package/dist/utils/env-loader.d.ts +0 -54
- package/dist/utils/env-loader.js +0 -270
- package/dist/utils/help.d.ts +0 -36
- package/dist/utils/help.js +0 -248
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.js +0 -7
- package/dist/utils/logger.d.ts +0 -35
- package/dist/utils/logger.js +0 -75
- package/dist/utils/silent-monitor.d.ts +0 -67
- package/dist/utils/silent-monitor.js +0 -242
- package/dist/utils/timeout.d.ts +0 -5
- package/dist/utils/timeout.js +0 -23
- package/dist/utils/version.d.ts +0 -4
- package/dist/utils/version.js +0 -35
- package/dist/web/env-manager-server.d.ts +0 -29
- package/dist/web/env-manager-server.js +0 -367
- package/dist/web/index.d.ts +0 -1
- package/dist/web/index.js +0 -1
- package/src/LocalToolResolver.ts +0 -424
- package/src/api/enact-api.ts +0 -604
- package/src/api/index.ts +0 -2
- package/src/api/types.ts +0 -114
- package/src/core/DaggerExecutionProvider.ts +0 -1357
- package/src/core/DirectExecutionProvider.ts +0 -484
- package/src/core/EnactCore.ts +0 -847
- package/src/core/index.ts +0 -3
- package/src/exec/index.ts +0 -3
- package/src/exec/logger.ts +0 -63
- package/src/exec/validate.ts +0 -238
- package/src/lib/enact-direct.ts +0 -254
- package/src/lib/index.ts +0 -1
- package/src/services/McpCoreService.ts +0 -201
- package/src/services/index.ts +0 -1
- package/src/utils/config.ts +0 -438
- package/src/utils/env-loader.ts +0 -370
- package/src/utils/help.ts +0 -257
- package/src/utils/index.ts +0 -7
- package/src/utils/silent-monitor.ts +0 -328
- package/src/utils/timeout.ts +0 -26
- package/src/web/env-manager-server.ts +0 -465
- package/src/web/index.ts +0 -1
- package/src/web/static/app.js +0 -663
- package/src/web/static/index.html +0 -117
- package/src/web/static/style.css +0 -291
package/src/LocalToolResolver.ts
DELETED
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
import { EnactCore } from "./core/EnactCore";
|
|
2
|
-
import { promises as fs, readFileSync, writeFileSync, existsSync } from "fs";
|
|
3
|
-
import { join, resolve, basename } from "path";
|
|
4
|
-
import * as yaml from "yaml";
|
|
5
|
-
import logger from "./exec/logger";
|
|
6
|
-
|
|
7
|
-
export interface LocalTool {
|
|
8
|
-
name: string;
|
|
9
|
-
path: string;
|
|
10
|
-
definition: any;
|
|
11
|
-
lastModified: Date;
|
|
12
|
-
cached: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface ToolResolutionResult {
|
|
16
|
-
tool: LocalTool | any;
|
|
17
|
-
source: "local" | "registry" | "cache";
|
|
18
|
-
metadata?: any;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class LocalToolResolver {
|
|
22
|
-
private localToolsDir: string;
|
|
23
|
-
private cacheDir: string;
|
|
24
|
-
private toolCache = new Map<string, LocalTool>();
|
|
25
|
-
private aliases = new Map<string, string>();
|
|
26
|
-
private favorites = new Set<string>();
|
|
27
|
-
|
|
28
|
-
constructor(
|
|
29
|
-
private enactCore: EnactCore,
|
|
30
|
-
localToolsDir: string = "./tools",
|
|
31
|
-
cacheDir: string = "./.tool-cache",
|
|
32
|
-
) {
|
|
33
|
-
this.localToolsDir = resolve(localToolsDir);
|
|
34
|
-
this.cacheDir = resolve(cacheDir);
|
|
35
|
-
this.loadConfiguration();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Main resolution method - checks local first, then registry
|
|
40
|
-
*/
|
|
41
|
-
async resolveTool(toolName: string): Promise<ToolResolutionResult | null> {
|
|
42
|
-
// Check aliases first
|
|
43
|
-
const resolvedName = this.aliases.get(toolName) || toolName;
|
|
44
|
-
|
|
45
|
-
// 1. Check local directory first
|
|
46
|
-
const localTool = await this.getLocalTool(resolvedName);
|
|
47
|
-
if (localTool) {
|
|
48
|
-
return {
|
|
49
|
-
tool: localTool,
|
|
50
|
-
source: "local",
|
|
51
|
-
metadata: { path: localTool.path },
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 2. Check cache for registry tools
|
|
56
|
-
const cachedTool = this.toolCache.get(resolvedName);
|
|
57
|
-
if (cachedTool && !this.isCacheExpired(cachedTool)) {
|
|
58
|
-
return {
|
|
59
|
-
tool: cachedTool,
|
|
60
|
-
source: "cache",
|
|
61
|
-
metadata: { cachedAt: cachedTool.lastModified },
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 3. Fall back to registry
|
|
66
|
-
try {
|
|
67
|
-
const registryTool = await this.enactCore.getToolByName(resolvedName);
|
|
68
|
-
if (registryTool) {
|
|
69
|
-
// Cache the registry tool locally
|
|
70
|
-
await this.cacheRegistryTool(resolvedName, registryTool);
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
tool: registryTool,
|
|
74
|
-
source: "registry",
|
|
75
|
-
metadata: { cached: true },
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
} catch (error) {
|
|
79
|
-
logger.debug(`Registry lookup failed for ${resolvedName}:`, error);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Get tool from local directory
|
|
87
|
-
*/
|
|
88
|
-
private async getLocalTool(toolName: string): Promise<LocalTool | null> {
|
|
89
|
-
const possiblePaths = [
|
|
90
|
-
join(this.localToolsDir, `${toolName}.yaml`),
|
|
91
|
-
join(this.localToolsDir, `${toolName}.yml`),
|
|
92
|
-
join(this.localToolsDir, toolName, "tool.yaml"),
|
|
93
|
-
join(this.localToolsDir, toolName, "tool.yml"),
|
|
94
|
-
join(this.localToolsDir, toolName, `${toolName}.yaml`),
|
|
95
|
-
join(this.localToolsDir, toolName, `${toolName}.yml`),
|
|
96
|
-
];
|
|
97
|
-
|
|
98
|
-
for (const toolPath of possiblePaths) {
|
|
99
|
-
try {
|
|
100
|
-
const stats = await fs.stat(toolPath);
|
|
101
|
-
const content = await fs.readFile(toolPath, "utf-8");
|
|
102
|
-
const definition = yaml.parse(content);
|
|
103
|
-
|
|
104
|
-
if (
|
|
105
|
-
definition &&
|
|
106
|
-
(definition.name === toolName || definition.name === undefined)
|
|
107
|
-
) {
|
|
108
|
-
return {
|
|
109
|
-
name: definition.name || toolName,
|
|
110
|
-
path: toolPath,
|
|
111
|
-
definition,
|
|
112
|
-
lastModified: stats.mtime,
|
|
113
|
-
cached: false,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
} catch (error) {
|
|
117
|
-
// File doesn't exist or can't be read, continue to next path
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Cache a registry tool locally for faster access
|
|
127
|
-
*/
|
|
128
|
-
private async cacheRegistryTool(toolName: string, tool: any): Promise<void> {
|
|
129
|
-
try {
|
|
130
|
-
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
131
|
-
|
|
132
|
-
const cachePath = join(this.cacheDir, `${toolName}.yaml`);
|
|
133
|
-
const cacheData = {
|
|
134
|
-
...tool,
|
|
135
|
-
_cached: true,
|
|
136
|
-
_cachedAt: new Date().toISOString(),
|
|
137
|
-
_source: "registry",
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
await fs.writeFile(cachePath, yaml.stringify(cacheData));
|
|
141
|
-
|
|
142
|
-
this.toolCache.set(toolName, {
|
|
143
|
-
name: toolName,
|
|
144
|
-
path: cachePath,
|
|
145
|
-
definition: tool,
|
|
146
|
-
lastModified: new Date(),
|
|
147
|
-
cached: true,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
logger.debug(`Cached registry tool: ${toolName}`);
|
|
151
|
-
} catch (error) {
|
|
152
|
-
logger.warn(`Failed to cache tool ${toolName}:`, error);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Check if cached tool is expired (24 hours by default)
|
|
158
|
-
*/
|
|
159
|
-
private isCacheExpired(
|
|
160
|
-
tool: LocalTool,
|
|
161
|
-
maxAge: number = 24 * 60 * 60 * 1000,
|
|
162
|
-
): boolean {
|
|
163
|
-
return Date.now() - tool.lastModified.getTime() > maxAge;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* List all available tools from all sources
|
|
168
|
-
*/
|
|
169
|
-
async listAllTools(): Promise<{
|
|
170
|
-
local: LocalTool[];
|
|
171
|
-
cached: LocalTool[];
|
|
172
|
-
favorites: string[];
|
|
173
|
-
aliases: Record<string, string>;
|
|
174
|
-
}> {
|
|
175
|
-
const localTools = await this.scanLocalTools();
|
|
176
|
-
const cachedTools = Array.from(this.toolCache.values());
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
local: localTools,
|
|
180
|
-
cached: cachedTools,
|
|
181
|
-
favorites: Array.from(this.favorites),
|
|
182
|
-
aliases: Object.fromEntries(this.aliases),
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Scan local tools directory
|
|
188
|
-
*/
|
|
189
|
-
private async scanLocalTools(): Promise<LocalTool[]> {
|
|
190
|
-
const tools: LocalTool[] = [];
|
|
191
|
-
|
|
192
|
-
try {
|
|
193
|
-
await fs.mkdir(this.localToolsDir, { recursive: true });
|
|
194
|
-
const entries = await this.scanDirectory(this.localToolsDir);
|
|
195
|
-
|
|
196
|
-
for (const entry of entries) {
|
|
197
|
-
if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
|
|
198
|
-
try {
|
|
199
|
-
const content = await fs.readFile(entry, "utf-8");
|
|
200
|
-
const definition = yaml.parse(content);
|
|
201
|
-
|
|
202
|
-
if (definition && (definition.name || definition.command)) {
|
|
203
|
-
const stats = await fs.stat(entry);
|
|
204
|
-
tools.push({
|
|
205
|
-
name:
|
|
206
|
-
definition.name ||
|
|
207
|
-
basename(entry, ".yaml").replace(".yml", ""),
|
|
208
|
-
path: entry,
|
|
209
|
-
definition,
|
|
210
|
-
lastModified: stats.mtime,
|
|
211
|
-
cached: false,
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
} catch (error) {
|
|
215
|
-
logger.debug(`Skipping invalid tool file ${entry}:`, error);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
} catch (error) {
|
|
220
|
-
logger.warn(`Failed to scan local tools directory:`, error);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return tools;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Recursively scan directory for tool files
|
|
228
|
-
*/
|
|
229
|
-
private async scanDirectory(dir: string): Promise<string[]> {
|
|
230
|
-
const files: string[] = [];
|
|
231
|
-
|
|
232
|
-
try {
|
|
233
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
234
|
-
|
|
235
|
-
for (const entry of entries) {
|
|
236
|
-
const fullPath = join(dir, entry.name);
|
|
237
|
-
|
|
238
|
-
if (entry.isDirectory()) {
|
|
239
|
-
const subFiles = await this.scanDirectory(fullPath);
|
|
240
|
-
files.push(...subFiles);
|
|
241
|
-
} else if (entry.isFile()) {
|
|
242
|
-
files.push(fullPath);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
} catch (error) {
|
|
246
|
-
logger.debug(`Cannot scan directory ${dir}:`, error);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return files;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Add a tool to favorites for priority resolution
|
|
254
|
-
*/
|
|
255
|
-
addToFavorites(toolName: string): void {
|
|
256
|
-
this.favorites.add(toolName);
|
|
257
|
-
this.saveConfiguration();
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Add an alias for a tool
|
|
262
|
-
*/
|
|
263
|
-
addAlias(alias: string, toolName: string): void {
|
|
264
|
-
this.aliases.set(alias, toolName);
|
|
265
|
-
this.saveConfiguration();
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Get suggestions based on partial tool name
|
|
270
|
-
*/
|
|
271
|
-
async getSuggestions(partial: string): Promise<string[]> {
|
|
272
|
-
const allTools = await this.listAllTools();
|
|
273
|
-
const suggestions = new Set<string>();
|
|
274
|
-
|
|
275
|
-
// Add local tools
|
|
276
|
-
allTools.local.forEach((tool) => {
|
|
277
|
-
if (tool.name.includes(partial)) {
|
|
278
|
-
suggestions.add(tool.name);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
// Add favorites first
|
|
283
|
-
this.favorites.forEach((fav) => {
|
|
284
|
-
if (fav.includes(partial)) {
|
|
285
|
-
suggestions.add(fav);
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
// Add aliases
|
|
290
|
-
this.aliases.forEach((toolName, alias) => {
|
|
291
|
-
if (alias.includes(partial) || toolName.includes(partial)) {
|
|
292
|
-
suggestions.add(alias);
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
return Array.from(suggestions).slice(0, 10); // Limit suggestions
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Clear expired cache entries
|
|
301
|
-
*/
|
|
302
|
-
async cleanupCache(): Promise<number> {
|
|
303
|
-
let cleaned = 0;
|
|
304
|
-
|
|
305
|
-
for (const [toolName, tool] of this.toolCache.entries()) {
|
|
306
|
-
if (this.isCacheExpired(tool)) {
|
|
307
|
-
try {
|
|
308
|
-
await fs.unlink(tool.path);
|
|
309
|
-
this.toolCache.delete(toolName);
|
|
310
|
-
cleaned++;
|
|
311
|
-
} catch (error) {
|
|
312
|
-
logger.debug(`Failed to clean cache for ${toolName}:`, error);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
logger.info(`Cleaned ${cleaned} expired cache entries`);
|
|
318
|
-
return cleaned;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Load configuration from file
|
|
323
|
-
*/
|
|
324
|
-
private loadConfiguration(): void {
|
|
325
|
-
try {
|
|
326
|
-
const configPath = join(this.localToolsDir, "config.json");
|
|
327
|
-
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
328
|
-
|
|
329
|
-
if (config.aliases) {
|
|
330
|
-
this.aliases = new Map(Object.entries(config.aliases));
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (config.favorites) {
|
|
334
|
-
this.favorites = new Set(config.favorites);
|
|
335
|
-
}
|
|
336
|
-
} catch (error) {
|
|
337
|
-
// Config file doesn't exist or is invalid, use defaults
|
|
338
|
-
logger.debug("No tool configuration found, using defaults");
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Save configuration to file
|
|
344
|
-
*/
|
|
345
|
-
private saveConfiguration(): void {
|
|
346
|
-
try {
|
|
347
|
-
const configPath = join(this.localToolsDir, "config.json");
|
|
348
|
-
const config = {
|
|
349
|
-
aliases: Object.fromEntries(this.aliases),
|
|
350
|
-
favorites: Array.from(this.favorites),
|
|
351
|
-
lastUpdated: new Date().toISOString(),
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
355
|
-
} catch (error) {
|
|
356
|
-
logger.warn("Failed to save tool configuration:", error);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Initialize local tools directory with examples
|
|
362
|
-
*/
|
|
363
|
-
async initialize(): Promise<void> {
|
|
364
|
-
await fs.mkdir(this.localToolsDir, { recursive: true });
|
|
365
|
-
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
366
|
-
|
|
367
|
-
// Create a sample local tool if directory is empty
|
|
368
|
-
const tools = await this.scanLocalTools();
|
|
369
|
-
if (tools.length === 0) {
|
|
370
|
-
const sampleTool = {
|
|
371
|
-
name: "hello-world",
|
|
372
|
-
description: "A simple hello world tool",
|
|
373
|
-
version: "1.0.0",
|
|
374
|
-
command: 'echo "Hello, World!"',
|
|
375
|
-
inputSchema: {
|
|
376
|
-
properties: {
|
|
377
|
-
message: {
|
|
378
|
-
type: "string",
|
|
379
|
-
description: "Custom message to display",
|
|
380
|
-
},
|
|
381
|
-
},
|
|
382
|
-
},
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
const samplePath = join(this.localToolsDir, "hello-world.yaml");
|
|
386
|
-
await fs.writeFile(samplePath, yaml.stringify(sampleTool));
|
|
387
|
-
logger.info(`Created sample tool at ${samplePath}`);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Create README
|
|
391
|
-
const readmePath = join(this.localToolsDir, "README.md");
|
|
392
|
-
const readme = `# Local Tools Directory
|
|
393
|
-
|
|
394
|
-
This directory contains your local Enact tools. Tools can be organized as:
|
|
395
|
-
|
|
396
|
-
## File Structure
|
|
397
|
-
- \`tool-name.yaml\` - Single tool file
|
|
398
|
-
- \`tool-name/tool.yaml\` - Tool in subdirectory
|
|
399
|
-
- \`tool-name/tool-name.yaml\` - Named tool in subdirectory
|
|
400
|
-
|
|
401
|
-
## Configuration
|
|
402
|
-
- \`config.json\` - Aliases and favorites configuration
|
|
403
|
-
|
|
404
|
-
## Cache
|
|
405
|
-
Registry tools are cached in \`.tool-cache/\` for faster access.
|
|
406
|
-
|
|
407
|
-
## Priority Order
|
|
408
|
-
1. Favorites (if name matches)
|
|
409
|
-
2. Local tools
|
|
410
|
-
3. Cached registry tools
|
|
411
|
-
4. Registry lookup
|
|
412
|
-
|
|
413
|
-
Use the MCP tools to manage this directory programmatically.
|
|
414
|
-
`;
|
|
415
|
-
|
|
416
|
-
try {
|
|
417
|
-
await fs.access(readmePath);
|
|
418
|
-
} catch {
|
|
419
|
-
await fs.writeFile(readmePath, readme);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
export default LocalToolResolver;
|