@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,367 +0,0 @@
1
- // src/web/env-manager-server.ts - Web server for managing environment variables
2
- import { createServer } from "http";
3
- import { parse } from "url";
4
- import { readFile, writeFile, mkdir, readdir, stat } from "fs/promises";
5
- import { existsSync } from "fs";
6
- import { join, dirname } from "path";
7
- import { homedir } from "os";
8
- import { fileURLToPath } from "url";
9
- import logger from "../exec/logger";
10
- // Get the directory of this module
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = dirname(__filename);
13
- // Configuration paths
14
- const CONFIG_DIR = join(homedir(), ".enact");
15
- const ENV_BASE_DIR = join(CONFIG_DIR, "env");
16
- // Find static files - try multiple locations
17
- function findStaticDir() {
18
- const candidates = [
19
- join(__dirname, "web", "static"), // If running from built package (dist/web/static)
20
- join(__dirname, "static"), // If running from source
21
- join(__dirname, "..", "src", "web", "static"), // If bundled in dist
22
- join(__dirname, "..", "..", "src", "web", "static"), // If nested deeper
23
- join(process.cwd(), "src", "web", "static"), // From project root
24
- // When installed via npm, static files are in the package root
25
- join(__dirname, "..", "..", "..", "src", "web", "static"), // node_modules/enact-cli/src/web/static from node_modules/enact-cli/dist/web/
26
- join(__dirname, "..", "..", "src", "web", "static"), // node_modules/enact-cli/src/web/static from node_modules/enact-cli/dist/
27
- ];
28
- for (const candidate of candidates) {
29
- if (existsSync(join(candidate, "index.html"))) {
30
- logger.debug(`Found static directory: ${candidate}`);
31
- return candidate;
32
- }
33
- }
34
- throw new Error("Could not find static directory. Tried: " + candidates.join(", "));
35
- }
36
- const STATIC_DIR = findStaticDir();
37
- /**
38
- * Parse simple .env file format (KEY=value)
39
- */
40
- function parseDotEnv(content) {
41
- const vars = {};
42
- const lines = content.split("\n");
43
- for (const line of lines) {
44
- const trimmed = line.trim();
45
- if (!trimmed || trimmed.startsWith("#")) {
46
- continue; // Skip empty lines and comments
47
- }
48
- const equalIndex = trimmed.indexOf("=");
49
- if (equalIndex === -1) {
50
- continue; // Skip lines without '='
51
- }
52
- const key = trimmed.slice(0, equalIndex).trim();
53
- let value = trimmed.slice(equalIndex + 1).trim();
54
- // Remove quotes if present
55
- if ((value.startsWith('"') && value.endsWith('"')) ||
56
- (value.startsWith("'") && value.endsWith("'"))) {
57
- value = value.slice(1, -1);
58
- }
59
- if (key) {
60
- vars[key] = value;
61
- }
62
- }
63
- return vars;
64
- }
65
- /**
66
- * Convert environment variables to .env file format
67
- */
68
- function generateDotEnv(vars) {
69
- return (Object.entries(vars)
70
- .map(([key, value]) => {
71
- // Escape value if it contains special characters
72
- const needsQuotes = value.includes(" ") ||
73
- value.includes("\t") ||
74
- value.includes("\n") ||
75
- value.includes('"');
76
- const escapedValue = needsQuotes
77
- ? `"${value.replace(/"/g, '\\"')}"`
78
- : value;
79
- return `${key}=${escapedValue}`;
80
- })
81
- .join("\n") + "\n");
82
- }
83
- /**
84
- * Get all package namespaces with environment variables
85
- */
86
- async function getAllPackageNamespaces() {
87
- const packages = [];
88
- if (!existsSync(ENV_BASE_DIR)) {
89
- return packages;
90
- }
91
- try {
92
- await scanDirectory(ENV_BASE_DIR, "", packages);
93
- }
94
- catch (error) {
95
- logger.error("Failed to scan env directory:", error);
96
- }
97
- return packages;
98
- }
99
- /**
100
- * Recursively scan directory for .env files
101
- */
102
- async function scanDirectory(dir, relativePath, packages) {
103
- try {
104
- const entries = await readdir(dir);
105
- for (const entry of entries) {
106
- const fullPath = join(dir, entry);
107
- const stats = await stat(fullPath);
108
- if (stats.isDirectory()) {
109
- // Recursively scan subdirectories
110
- const newRelativePath = relativePath
111
- ? `${relativePath}/${entry}`
112
- : entry;
113
- await scanDirectory(fullPath, newRelativePath, packages);
114
- }
115
- else if (entry === ".env") {
116
- // Found a .env file
117
- const namespace = relativePath || "root";
118
- try {
119
- const content = await readFile(fullPath, "utf8");
120
- const variables = parseDotEnv(content);
121
- packages.push({
122
- namespace,
123
- path: fullPath,
124
- variables,
125
- });
126
- }
127
- catch (error) {
128
- logger.error(`Failed to read .env file at ${fullPath}:`, error);
129
- }
130
- }
131
- }
132
- }
133
- catch (error) {
134
- logger.error(`Failed to scan directory ${dir}:`, error);
135
- }
136
- }
137
- /**
138
- * Get environment variables for a specific package namespace
139
- */
140
- async function getPackageEnvVars(namespace) {
141
- const envFile = join(ENV_BASE_DIR, namespace, ".env");
142
- if (!existsSync(envFile)) {
143
- return {};
144
- }
145
- try {
146
- const content = await readFile(envFile, "utf8");
147
- return parseDotEnv(content);
148
- }
149
- catch (error) {
150
- logger.error(`Failed to read env file for ${namespace}:`, error);
151
- return {};
152
- }
153
- }
154
- /**
155
- * Set environment variable for a package namespace
156
- */
157
- async function setPackageEnvVar(namespace, key, value) {
158
- const envFile = join(ENV_BASE_DIR, namespace, ".env");
159
- const envDir = dirname(envFile);
160
- // Ensure directory exists
161
- if (!existsSync(envDir)) {
162
- await mkdir(envDir, { recursive: true });
163
- }
164
- // Read existing variables
165
- const existingVars = await getPackageEnvVars(namespace);
166
- // Update variables
167
- existingVars[key] = value;
168
- // Write back to file
169
- const envContent = generateDotEnv(existingVars);
170
- await writeFile(envFile, envContent, "utf8");
171
- }
172
- /**
173
- * Delete environment variable for a package namespace
174
- */
175
- async function deletePackageEnvVar(namespace, key) {
176
- const existingVars = await getPackageEnvVars(namespace);
177
- if (!(key in existingVars)) {
178
- throw new Error(`Environment variable '${key}' not found in package '${namespace}'`);
179
- }
180
- delete existingVars[key];
181
- const envFile = join(ENV_BASE_DIR, namespace, ".env");
182
- const envContent = generateDotEnv(existingVars);
183
- await writeFile(envFile, envContent, "utf8");
184
- }
185
- /**
186
- * Serve static files
187
- */
188
- async function serveStaticFile(filePath, res) {
189
- try {
190
- const content = await readFile(filePath, "utf8");
191
- const ext = filePath.split(".").pop()?.toLowerCase();
192
- let contentType = "text/plain";
193
- switch (ext) {
194
- case "html":
195
- contentType = "text/html";
196
- break;
197
- case "css":
198
- contentType = "text/css";
199
- break;
200
- case "js":
201
- contentType = "application/javascript";
202
- break;
203
- case "json":
204
- contentType = "application/json";
205
- break;
206
- }
207
- res.writeHead(200, { "Content-Type": contentType });
208
- res.end(content);
209
- }
210
- catch (error) {
211
- logger.error("Error serving static file:", error);
212
- res.writeHead(404, { "Content-Type": "text/plain" });
213
- res.end("File not found");
214
- }
215
- }
216
- /**
217
- * Handle HTTP requests
218
- */
219
- async function handleRequest(req, res) {
220
- const urlParts = parse(req.url || "", true);
221
- const pathname = urlParts.pathname || "/";
222
- const method = req.method || "GET";
223
- // Set CORS headers
224
- res.setHeader("Access-Control-Allow-Origin", "*");
225
- res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
226
- res.setHeader("Access-Control-Allow-Headers", "Content-Type");
227
- if (method === "OPTIONS") {
228
- res.writeHead(200);
229
- res.end();
230
- return;
231
- }
232
- try {
233
- if (pathname === "/") {
234
- // Serve main HTML page
235
- await serveStaticFile(join(STATIC_DIR, "index.html"), res);
236
- }
237
- else if (pathname === "/style.css") {
238
- // Serve CSS file
239
- await serveStaticFile(join(STATIC_DIR, "style.css"), res);
240
- }
241
- else if (pathname === "/app.js") {
242
- // Serve JavaScript file
243
- await serveStaticFile(join(STATIC_DIR, "app.js"), res);
244
- }
245
- else if (pathname === "/favicon.ico") {
246
- // Serve a simple SVG favicon
247
- const favicon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">🌐</text></svg>`;
248
- res.writeHead(200, { "Content-Type": "image/svg+xml" });
249
- res.end(favicon);
250
- }
251
- else if (pathname === "/api/packages" && method === "GET") {
252
- // Get all packages
253
- const packages = await getAllPackageNamespaces();
254
- res.writeHead(200, { "Content-Type": "application/json" });
255
- res.end(JSON.stringify({ packages }));
256
- }
257
- else if (pathname === "/api/packages" && method === "POST") {
258
- // Create new package
259
- const body = await getRequestBody(req);
260
- const { namespace } = JSON.parse(body);
261
- if (!namespace) {
262
- res.writeHead(400, { "Content-Type": "application/json" });
263
- res.end(JSON.stringify({ error: "Namespace is required" }));
264
- return;
265
- }
266
- const envDir = join(ENV_BASE_DIR, namespace);
267
- const envFile = join(envDir, ".env");
268
- if (!existsSync(envDir)) {
269
- await mkdir(envDir, { recursive: true });
270
- }
271
- if (!existsSync(envFile)) {
272
- await writeFile(envFile, "", "utf8");
273
- }
274
- res.writeHead(200, { "Content-Type": "application/json" });
275
- res.end(JSON.stringify({ success: true }));
276
- }
277
- else if (pathname?.startsWith("/api/packages/") && method === "GET") {
278
- // Get specific package variables
279
- const namespace = decodeURIComponent(pathname.replace("/api/packages/", ""));
280
- const variables = await getPackageEnvVars(namespace);
281
- res.writeHead(200, { "Content-Type": "application/json" });
282
- res.end(JSON.stringify({ namespace, variables }));
283
- }
284
- else if (pathname?.startsWith("/api/packages/") &&
285
- pathname.endsWith("/variables") &&
286
- method === "POST") {
287
- // Add/update variable
288
- const namespace = decodeURIComponent(pathname.replace("/api/packages/", "").replace("/variables", ""));
289
- const body = await getRequestBody(req);
290
- const { key, value } = JSON.parse(body);
291
- if (!key || value === undefined) {
292
- res.writeHead(400, { "Content-Type": "application/json" });
293
- res.end(JSON.stringify({ error: "Key and value are required" }));
294
- return;
295
- }
296
- await setPackageEnvVar(namespace, key, value);
297
- res.writeHead(200, { "Content-Type": "application/json" });
298
- res.end(JSON.stringify({ success: true }));
299
- }
300
- else if (pathname?.includes("/variables/") && method === "DELETE") {
301
- // Delete variable
302
- const pathParts = pathname.split("/");
303
- const variableIndex = pathParts.indexOf("variables");
304
- const namespace = decodeURIComponent(pathParts.slice(3, variableIndex).join("/"));
305
- const key = decodeURIComponent(pathParts[variableIndex + 1]);
306
- await deletePackageEnvVar(namespace, key);
307
- res.writeHead(200, { "Content-Type": "application/json" });
308
- res.end(JSON.stringify({ success: true }));
309
- }
310
- else {
311
- // 404 Not Found
312
- res.writeHead(404, { "Content-Type": "application/json" });
313
- res.end(JSON.stringify({ error: "Not found" }));
314
- }
315
- }
316
- catch (error) {
317
- logger.error("Web server error:", error);
318
- res.writeHead(500, { "Content-Type": "application/json" });
319
- res.end(JSON.stringify({
320
- error: error instanceof Error ? error.message : "Internal server error",
321
- }));
322
- }
323
- }
324
- /**
325
- * Get request body as string
326
- */
327
- function getRequestBody(req) {
328
- return new Promise((resolve, reject) => {
329
- let body = "";
330
- req.on("data", (chunk) => {
331
- body += chunk.toString();
332
- });
333
- req.on("end", () => {
334
- resolve(body);
335
- });
336
- req.on("error", reject);
337
- });
338
- }
339
- /**
340
- * Start the web server
341
- */
342
- export function startEnvManagerServer(port = 5555) {
343
- return new Promise((resolve, reject) => {
344
- const server = createServer(handleRequest);
345
- // Try to start on the specified port, fallback to a random port if unavailable
346
- server.listen(port, () => {
347
- const actualPort = server.address()?.port || port;
348
- logger.info(`🌐 Environment Manager web server started on http://localhost:${actualPort}`);
349
- resolve({ server, port: actualPort });
350
- });
351
- server.on("error", (error) => {
352
- if (error.code === "EADDRINUSE") {
353
- // Port is in use, try a random port
354
- server.listen(0, () => {
355
- const actualPort = server.address()?.port;
356
- logger.info(`🌐 Environment Manager web server started on http://localhost:${actualPort} (port ${port} was in use)`);
357
- resolve({ server, port: actualPort });
358
- });
359
- }
360
- else {
361
- reject(error);
362
- }
363
- });
364
- });
365
- }
366
- // Export additional functions for use by MCP tools
367
- export { getAllPackageNamespaces, getPackageEnvVars, setPackageEnvVar, deletePackageEnvVar, };
@@ -1 +0,0 @@
1
- export * from './env-manager-server';
package/dist/web/index.js DELETED
@@ -1 +0,0 @@
1
- export * from './env-manager-server';