@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.
Files changed (134) hide show
  1. package/README.md +44 -0
  2. package/package.json +16 -58
  3. package/src/config.ts +476 -0
  4. package/src/constants.ts +36 -0
  5. package/src/execution/command.ts +314 -0
  6. package/src/execution/index.ts +73 -0
  7. package/src/execution/runtime.ts +308 -0
  8. package/src/execution/types.ts +379 -0
  9. package/src/execution/validation.ts +508 -0
  10. package/src/index.ts +237 -30
  11. package/src/manifest/index.ts +36 -0
  12. package/src/manifest/loader.ts +187 -0
  13. package/src/manifest/parser.ts +173 -0
  14. package/src/manifest/validator.ts +309 -0
  15. package/src/paths.ts +108 -0
  16. package/src/registry.ts +219 -0
  17. package/src/resolver.ts +345 -0
  18. package/src/types/index.ts +30 -0
  19. package/src/types/manifest.ts +255 -0
  20. package/src/types.ts +5 -188
  21. package/src/utils/fs.ts +281 -0
  22. package/src/utils/logger.ts +270 -59
  23. package/src/utils/version.ts +304 -36
  24. package/tests/config.test.ts +515 -0
  25. package/tests/execution/command.test.ts +317 -0
  26. package/tests/execution/validation.test.ts +384 -0
  27. package/tests/fixtures/invalid-tool.yaml +4 -0
  28. package/tests/fixtures/valid-tool.md +62 -0
  29. package/tests/fixtures/valid-tool.yaml +40 -0
  30. package/tests/index.test.ts +8 -0
  31. package/tests/manifest/loader.test.ts +291 -0
  32. package/tests/manifest/parser.test.ts +345 -0
  33. package/tests/manifest/validator.test.ts +394 -0
  34. package/tests/manifest-types.test.ts +358 -0
  35. package/tests/paths.test.ts +153 -0
  36. package/tests/registry.test.ts +231 -0
  37. package/tests/resolver.test.ts +272 -0
  38. package/tests/utils/fs.test.ts +388 -0
  39. package/tests/utils/logger.test.ts +480 -0
  40. package/tests/utils/version.test.ts +390 -0
  41. package/tsconfig.json +12 -0
  42. package/tsconfig.tsbuildinfo +1 -0
  43. package/dist/LocalToolResolver.d.ts +0 -84
  44. package/dist/LocalToolResolver.js +0 -353
  45. package/dist/api/enact-api.d.ts +0 -130
  46. package/dist/api/enact-api.js +0 -428
  47. package/dist/api/index.d.ts +0 -2
  48. package/dist/api/index.js +0 -2
  49. package/dist/api/types.d.ts +0 -103
  50. package/dist/api/types.js +0 -1
  51. package/dist/constants.d.ts +0 -7
  52. package/dist/constants.js +0 -10
  53. package/dist/core/DaggerExecutionProvider.d.ts +0 -169
  54. package/dist/core/DaggerExecutionProvider.js +0 -1029
  55. package/dist/core/DirectExecutionProvider.d.ts +0 -23
  56. package/dist/core/DirectExecutionProvider.js +0 -406
  57. package/dist/core/EnactCore.d.ts +0 -162
  58. package/dist/core/EnactCore.js +0 -597
  59. package/dist/core/NativeExecutionProvider.d.ts +0 -9
  60. package/dist/core/NativeExecutionProvider.js +0 -16
  61. package/dist/core/index.d.ts +0 -3
  62. package/dist/core/index.js +0 -3
  63. package/dist/exec/index.d.ts +0 -3
  64. package/dist/exec/index.js +0 -3
  65. package/dist/exec/logger.d.ts +0 -11
  66. package/dist/exec/logger.js +0 -57
  67. package/dist/exec/validate.d.ts +0 -5
  68. package/dist/exec/validate.js +0 -167
  69. package/dist/index.d.ts +0 -21
  70. package/dist/index.js +0 -25
  71. package/dist/lib/enact-direct.d.ts +0 -150
  72. package/dist/lib/enact-direct.js +0 -159
  73. package/dist/lib/index.d.ts +0 -1
  74. package/dist/lib/index.js +0 -1
  75. package/dist/security/index.d.ts +0 -3
  76. package/dist/security/index.js +0 -3
  77. package/dist/security/security.d.ts +0 -23
  78. package/dist/security/security.js +0 -137
  79. package/dist/security/sign.d.ts +0 -103
  80. package/dist/security/sign.js +0 -666
  81. package/dist/security/verification-enforcer.d.ts +0 -53
  82. package/dist/security/verification-enforcer.js +0 -204
  83. package/dist/services/McpCoreService.d.ts +0 -98
  84. package/dist/services/McpCoreService.js +0 -124
  85. package/dist/services/index.d.ts +0 -1
  86. package/dist/services/index.js +0 -1
  87. package/dist/types.d.ts +0 -132
  88. package/dist/types.js +0 -3
  89. package/dist/utils/config.d.ts +0 -111
  90. package/dist/utils/config.js +0 -342
  91. package/dist/utils/env-loader.d.ts +0 -54
  92. package/dist/utils/env-loader.js +0 -270
  93. package/dist/utils/help.d.ts +0 -36
  94. package/dist/utils/help.js +0 -248
  95. package/dist/utils/index.d.ts +0 -7
  96. package/dist/utils/index.js +0 -7
  97. package/dist/utils/logger.d.ts +0 -35
  98. package/dist/utils/logger.js +0 -75
  99. package/dist/utils/silent-monitor.d.ts +0 -67
  100. package/dist/utils/silent-monitor.js +0 -242
  101. package/dist/utils/timeout.d.ts +0 -5
  102. package/dist/utils/timeout.js +0 -23
  103. package/dist/utils/version.d.ts +0 -4
  104. package/dist/utils/version.js +0 -35
  105. package/dist/web/env-manager-server.d.ts +0 -29
  106. package/dist/web/env-manager-server.js +0 -367
  107. package/dist/web/index.d.ts +0 -1
  108. package/dist/web/index.js +0 -1
  109. package/src/LocalToolResolver.ts +0 -424
  110. package/src/api/enact-api.ts +0 -604
  111. package/src/api/index.ts +0 -2
  112. package/src/api/types.ts +0 -114
  113. package/src/core/DaggerExecutionProvider.ts +0 -1357
  114. package/src/core/DirectExecutionProvider.ts +0 -484
  115. package/src/core/EnactCore.ts +0 -847
  116. package/src/core/index.ts +0 -3
  117. package/src/exec/index.ts +0 -3
  118. package/src/exec/logger.ts +0 -63
  119. package/src/exec/validate.ts +0 -238
  120. package/src/lib/enact-direct.ts +0 -254
  121. package/src/lib/index.ts +0 -1
  122. package/src/services/McpCoreService.ts +0 -201
  123. package/src/services/index.ts +0 -1
  124. package/src/utils/config.ts +0 -438
  125. package/src/utils/env-loader.ts +0 -370
  126. package/src/utils/help.ts +0 -257
  127. package/src/utils/index.ts +0 -7
  128. package/src/utils/silent-monitor.ts +0 -328
  129. package/src/utils/timeout.ts +0 -26
  130. package/src/web/env-manager-server.ts +0 -465
  131. package/src/web/index.ts +0 -1
  132. package/src/web/static/app.js +0 -663
  133. package/src/web/static/index.html +0 -117
  134. package/src/web/static/style.css +0 -291
@@ -1,353 +0,0 @@
1
- import { promises as fs, readFileSync, writeFileSync } from "fs";
2
- import { join, resolve, basename } from "path";
3
- import * as yaml from "yaml";
4
- import logger from "./exec/logger";
5
- export class LocalToolResolver {
6
- constructor(enactCore, localToolsDir = "./tools", cacheDir = "./.tool-cache") {
7
- this.enactCore = enactCore;
8
- this.toolCache = new Map();
9
- this.aliases = new Map();
10
- this.favorites = new Set();
11
- this.localToolsDir = resolve(localToolsDir);
12
- this.cacheDir = resolve(cacheDir);
13
- this.loadConfiguration();
14
- }
15
- /**
16
- * Main resolution method - checks local first, then registry
17
- */
18
- async resolveTool(toolName) {
19
- // Check aliases first
20
- const resolvedName = this.aliases.get(toolName) || toolName;
21
- // 1. Check local directory first
22
- const localTool = await this.getLocalTool(resolvedName);
23
- if (localTool) {
24
- return {
25
- tool: localTool,
26
- source: "local",
27
- metadata: { path: localTool.path },
28
- };
29
- }
30
- // 2. Check cache for registry tools
31
- const cachedTool = this.toolCache.get(resolvedName);
32
- if (cachedTool && !this.isCacheExpired(cachedTool)) {
33
- return {
34
- tool: cachedTool,
35
- source: "cache",
36
- metadata: { cachedAt: cachedTool.lastModified },
37
- };
38
- }
39
- // 3. Fall back to registry
40
- try {
41
- const registryTool = await this.enactCore.getToolByName(resolvedName);
42
- if (registryTool) {
43
- // Cache the registry tool locally
44
- await this.cacheRegistryTool(resolvedName, registryTool);
45
- return {
46
- tool: registryTool,
47
- source: "registry",
48
- metadata: { cached: true },
49
- };
50
- }
51
- }
52
- catch (error) {
53
- logger.debug(`Registry lookup failed for ${resolvedName}:`, error);
54
- }
55
- return null;
56
- }
57
- /**
58
- * Get tool from local directory
59
- */
60
- async getLocalTool(toolName) {
61
- const possiblePaths = [
62
- join(this.localToolsDir, `${toolName}.yaml`),
63
- join(this.localToolsDir, `${toolName}.yml`),
64
- join(this.localToolsDir, toolName, "tool.yaml"),
65
- join(this.localToolsDir, toolName, "tool.yml"),
66
- join(this.localToolsDir, toolName, `${toolName}.yaml`),
67
- join(this.localToolsDir, toolName, `${toolName}.yml`),
68
- ];
69
- for (const toolPath of possiblePaths) {
70
- try {
71
- const stats = await fs.stat(toolPath);
72
- const content = await fs.readFile(toolPath, "utf-8");
73
- const definition = yaml.parse(content);
74
- if (definition &&
75
- (definition.name === toolName || definition.name === undefined)) {
76
- return {
77
- name: definition.name || toolName,
78
- path: toolPath,
79
- definition,
80
- lastModified: stats.mtime,
81
- cached: false,
82
- };
83
- }
84
- }
85
- catch (error) {
86
- // File doesn't exist or can't be read, continue to next path
87
- continue;
88
- }
89
- }
90
- return null;
91
- }
92
- /**
93
- * Cache a registry tool locally for faster access
94
- */
95
- async cacheRegistryTool(toolName, tool) {
96
- try {
97
- await fs.mkdir(this.cacheDir, { recursive: true });
98
- const cachePath = join(this.cacheDir, `${toolName}.yaml`);
99
- const cacheData = {
100
- ...tool,
101
- _cached: true,
102
- _cachedAt: new Date().toISOString(),
103
- _source: "registry",
104
- };
105
- await fs.writeFile(cachePath, yaml.stringify(cacheData));
106
- this.toolCache.set(toolName, {
107
- name: toolName,
108
- path: cachePath,
109
- definition: tool,
110
- lastModified: new Date(),
111
- cached: true,
112
- });
113
- logger.debug(`Cached registry tool: ${toolName}`);
114
- }
115
- catch (error) {
116
- logger.warn(`Failed to cache tool ${toolName}:`, error);
117
- }
118
- }
119
- /**
120
- * Check if cached tool is expired (24 hours by default)
121
- */
122
- isCacheExpired(tool, maxAge = 24 * 60 * 60 * 1000) {
123
- return Date.now() - tool.lastModified.getTime() > maxAge;
124
- }
125
- /**
126
- * List all available tools from all sources
127
- */
128
- async listAllTools() {
129
- const localTools = await this.scanLocalTools();
130
- const cachedTools = Array.from(this.toolCache.values());
131
- return {
132
- local: localTools,
133
- cached: cachedTools,
134
- favorites: Array.from(this.favorites),
135
- aliases: Object.fromEntries(this.aliases),
136
- };
137
- }
138
- /**
139
- * Scan local tools directory
140
- */
141
- async scanLocalTools() {
142
- const tools = [];
143
- try {
144
- await fs.mkdir(this.localToolsDir, { recursive: true });
145
- const entries = await this.scanDirectory(this.localToolsDir);
146
- for (const entry of entries) {
147
- if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
148
- try {
149
- const content = await fs.readFile(entry, "utf-8");
150
- const definition = yaml.parse(content);
151
- if (definition && (definition.name || definition.command)) {
152
- const stats = await fs.stat(entry);
153
- tools.push({
154
- name: definition.name ||
155
- basename(entry, ".yaml").replace(".yml", ""),
156
- path: entry,
157
- definition,
158
- lastModified: stats.mtime,
159
- cached: false,
160
- });
161
- }
162
- }
163
- catch (error) {
164
- logger.debug(`Skipping invalid tool file ${entry}:`, error);
165
- }
166
- }
167
- }
168
- }
169
- catch (error) {
170
- logger.warn(`Failed to scan local tools directory:`, error);
171
- }
172
- return tools;
173
- }
174
- /**
175
- * Recursively scan directory for tool files
176
- */
177
- async scanDirectory(dir) {
178
- const files = [];
179
- try {
180
- const entries = await fs.readdir(dir, { withFileTypes: true });
181
- for (const entry of entries) {
182
- const fullPath = join(dir, entry.name);
183
- if (entry.isDirectory()) {
184
- const subFiles = await this.scanDirectory(fullPath);
185
- files.push(...subFiles);
186
- }
187
- else if (entry.isFile()) {
188
- files.push(fullPath);
189
- }
190
- }
191
- }
192
- catch (error) {
193
- logger.debug(`Cannot scan directory ${dir}:`, error);
194
- }
195
- return files;
196
- }
197
- /**
198
- * Add a tool to favorites for priority resolution
199
- */
200
- addToFavorites(toolName) {
201
- this.favorites.add(toolName);
202
- this.saveConfiguration();
203
- }
204
- /**
205
- * Add an alias for a tool
206
- */
207
- addAlias(alias, toolName) {
208
- this.aliases.set(alias, toolName);
209
- this.saveConfiguration();
210
- }
211
- /**
212
- * Get suggestions based on partial tool name
213
- */
214
- async getSuggestions(partial) {
215
- const allTools = await this.listAllTools();
216
- const suggestions = new Set();
217
- // Add local tools
218
- allTools.local.forEach((tool) => {
219
- if (tool.name.includes(partial)) {
220
- suggestions.add(tool.name);
221
- }
222
- });
223
- // Add favorites first
224
- this.favorites.forEach((fav) => {
225
- if (fav.includes(partial)) {
226
- suggestions.add(fav);
227
- }
228
- });
229
- // Add aliases
230
- this.aliases.forEach((toolName, alias) => {
231
- if (alias.includes(partial) || toolName.includes(partial)) {
232
- suggestions.add(alias);
233
- }
234
- });
235
- return Array.from(suggestions).slice(0, 10); // Limit suggestions
236
- }
237
- /**
238
- * Clear expired cache entries
239
- */
240
- async cleanupCache() {
241
- let cleaned = 0;
242
- for (const [toolName, tool] of this.toolCache.entries()) {
243
- if (this.isCacheExpired(tool)) {
244
- try {
245
- await fs.unlink(tool.path);
246
- this.toolCache.delete(toolName);
247
- cleaned++;
248
- }
249
- catch (error) {
250
- logger.debug(`Failed to clean cache for ${toolName}:`, error);
251
- }
252
- }
253
- }
254
- logger.info(`Cleaned ${cleaned} expired cache entries`);
255
- return cleaned;
256
- }
257
- /**
258
- * Load configuration from file
259
- */
260
- loadConfiguration() {
261
- try {
262
- const configPath = join(this.localToolsDir, "config.json");
263
- const config = JSON.parse(readFileSync(configPath, "utf-8"));
264
- if (config.aliases) {
265
- this.aliases = new Map(Object.entries(config.aliases));
266
- }
267
- if (config.favorites) {
268
- this.favorites = new Set(config.favorites);
269
- }
270
- }
271
- catch (error) {
272
- // Config file doesn't exist or is invalid, use defaults
273
- logger.debug("No tool configuration found, using defaults");
274
- }
275
- }
276
- /**
277
- * Save configuration to file
278
- */
279
- saveConfiguration() {
280
- try {
281
- const configPath = join(this.localToolsDir, "config.json");
282
- const config = {
283
- aliases: Object.fromEntries(this.aliases),
284
- favorites: Array.from(this.favorites),
285
- lastUpdated: new Date().toISOString(),
286
- };
287
- writeFileSync(configPath, JSON.stringify(config, null, 2));
288
- }
289
- catch (error) {
290
- logger.warn("Failed to save tool configuration:", error);
291
- }
292
- }
293
- /**
294
- * Initialize local tools directory with examples
295
- */
296
- async initialize() {
297
- await fs.mkdir(this.localToolsDir, { recursive: true });
298
- await fs.mkdir(this.cacheDir, { recursive: true });
299
- // Create a sample local tool if directory is empty
300
- const tools = await this.scanLocalTools();
301
- if (tools.length === 0) {
302
- const sampleTool = {
303
- name: "hello-world",
304
- description: "A simple hello world tool",
305
- version: "1.0.0",
306
- command: 'echo "Hello, World!"',
307
- inputSchema: {
308
- properties: {
309
- message: {
310
- type: "string",
311
- description: "Custom message to display",
312
- },
313
- },
314
- },
315
- };
316
- const samplePath = join(this.localToolsDir, "hello-world.yaml");
317
- await fs.writeFile(samplePath, yaml.stringify(sampleTool));
318
- logger.info(`Created sample tool at ${samplePath}`);
319
- }
320
- // Create README
321
- const readmePath = join(this.localToolsDir, "README.md");
322
- const readme = `# Local Tools Directory
323
-
324
- This directory contains your local Enact tools. Tools can be organized as:
325
-
326
- ## File Structure
327
- - \`tool-name.yaml\` - Single tool file
328
- - \`tool-name/tool.yaml\` - Tool in subdirectory
329
- - \`tool-name/tool-name.yaml\` - Named tool in subdirectory
330
-
331
- ## Configuration
332
- - \`config.json\` - Aliases and favorites configuration
333
-
334
- ## Cache
335
- Registry tools are cached in \`.tool-cache/\` for faster access.
336
-
337
- ## Priority Order
338
- 1. Favorites (if name matches)
339
- 2. Local tools
340
- 3. Cached registry tools
341
- 4. Registry lookup
342
-
343
- Use the MCP tools to manage this directory programmatically.
344
- `;
345
- try {
346
- await fs.access(readmePath);
347
- }
348
- catch {
349
- await fs.writeFile(readmePath, readme);
350
- }
351
- }
352
- }
353
- export default LocalToolResolver;
@@ -1,130 +0,0 @@
1
- import { EnactToolDefinition, ToolSignaturePayload, ToolUsage, ToolSearchQuery, CLITokenCreate, OAuthTokenExchange } from "./types";
2
- export declare class EnactApiClient {
3
- baseUrl: string;
4
- supabaseUrl: string;
5
- constructor(baseUrl: string, supabaseUrl: string);
6
- /**
7
- * Create API client with config-based URLs
8
- */
9
- static create(baseUrl?: string, supabaseUrl?: string): Promise<EnactApiClient>;
10
- private makeRequest;
11
- /**
12
- * Get all tools (public, no auth required)
13
- */
14
- getTools(params?: {
15
- limit?: number;
16
- offset?: number;
17
- tags?: string[];
18
- author?: string;
19
- }): Promise<EnactToolDefinition[]>;
20
- /**
21
- * Get specific tool details (public, no auth required)
22
- */
23
- getTool(name: string): Promise<EnactToolDefinition>;
24
- /**
25
- * Get tool usage statistics (public, no auth required)
26
- */
27
- getToolUsage(name: string): Promise<any>;
28
- /**
29
- * Log tool usage (public, no auth required)
30
- */
31
- logToolUsage(name: string, usage: ToolUsage): Promise<any>;
32
- /**
33
- * Search tools with semantic/text search (public, no auth required)
34
- */
35
- searchTools(query: ToolSearchQuery): Promise<EnactToolDefinition[]>;
36
- /**
37
- * Publish/create new tool (requires authentication)
38
- */
39
- publishTool(tool: EnactToolDefinition, token: string, tokenType?: "jwt" | "cli"): Promise<any>;
40
- /**
41
- * Update existing tool (requires authentication, must be owner)
42
- */
43
- updateTool(name: string, tool: EnactToolDefinition, token: string, tokenType?: "jwt" | "cli"): Promise<any>;
44
- /**
45
- * Delete tool (requires authentication, must be owner)
46
- */
47
- deleteTool(name: string, token: string, tokenType?: "jwt" | "cli"): Promise<any>;
48
- /**
49
- * Create new CLI token (requires JWT authentication)
50
- */
51
- createCLIToken(tokenData: CLITokenCreate, jwtToken: string): Promise<{
52
- token: string;
53
- id: string;
54
- name?: string;
55
- }>;
56
- /**
57
- * List user's CLI tokens (requires JWT authentication)
58
- */
59
- getCLITokens(jwtToken: string): Promise<any[]>;
60
- /**
61
- * Delete CLI token (requires JWT authentication, must be owner)
62
- */
63
- deleteCLIToken(tokenId: string, jwtToken: string): Promise<any>;
64
- /**
65
- * Exchange OAuth authorization code for access token
66
- */
67
- exchangeOAuthCode(oauthData: OAuthTokenExchange): Promise<{
68
- access_token: string;
69
- token_type: string;
70
- expires_in: number;
71
- scope?: string;
72
- }>;
73
- /**
74
- * Generate embeddings for tools (requires authentication)
75
- */
76
- generateEmbeddings(data: {
77
- toolId: string;
78
- text: string;
79
- }, token: string, tokenType?: "jwt" | "cli"): Promise<any>;
80
- /**
81
- * Check if a tool exists
82
- */
83
- toolExists(name: string): Promise<boolean>;
84
- /**
85
- * Publish or update tool based on existence
86
- */
87
- publishOrUpdateTool(tool: EnactToolDefinition, token: string, tokenType?: "jwt" | "cli"): Promise<{
88
- isUpdate: boolean;
89
- result: any;
90
- }>;
91
- /**
92
- * Search tools by tags
93
- */
94
- getToolsByTags(tags: string[], limit?: number): Promise<EnactToolDefinition[]>;
95
- /**
96
- * Get tools by author
97
- */
98
- getToolsByAuthor(author: string, limit?: number): Promise<EnactToolDefinition[]>;
99
- /**
100
- * Get a user's public key
101
- */
102
- getUserPublicKey(userId: string): Promise<any>;
103
- signTool(toolId: string, payload: ToolSignaturePayload, token: string, tokenType?: "jwt" | "cli"): Promise<any>;
104
- /**
105
- * Generate OAuth authorization URL
106
- */
107
- generateOAuthUrl(options: {
108
- clientId: string;
109
- redirectUri: string;
110
- scope: string;
111
- state: string;
112
- codeChallenge: string;
113
- codeChallengeMethod: string;
114
- }): string;
115
- /**
116
- * Validate tool definition before publishing
117
- */
118
- validateTool(tool: any): {
119
- valid: boolean;
120
- errors: string[];
121
- };
122
- }
123
- export declare function createDefaultApiClient(): Promise<EnactApiClient>;
124
- export declare const enactApi: EnactApiClient;
125
- export declare class EnactApiError extends Error {
126
- statusCode?: number | undefined;
127
- endpoint?: string | undefined;
128
- constructor(message: string, statusCode?: number | undefined, endpoint?: string | undefined);
129
- }
130
- export declare function createEnactApiClient(baseUrl?: string, supabaseUrl?: string): EnactApiClient;