@enactprotocol/mcp-server 1.2.4 → 1.2.5
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/dist/index.js +626 -574
- package/dist/index.js.bak +626 -574
- package/package.json +2 -5
package/dist/index.js.bak
CHANGED
|
@@ -235540,6 +235540,49 @@ class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
235540
235540
|
});
|
|
235541
235541
|
});
|
|
235542
235542
|
}
|
|
235543
|
+
async setupDirectoryMount(client, container, mountSpec) {
|
|
235544
|
+
try {
|
|
235545
|
+
let localPath2;
|
|
235546
|
+
let containerPath;
|
|
235547
|
+
const colonIndex = mountSpec.indexOf(":");
|
|
235548
|
+
if (colonIndex > 0) {
|
|
235549
|
+
const potentialDriveLetter = mountSpec.substring(0, colonIndex);
|
|
235550
|
+
const isWindowsDrive = potentialDriveLetter.length === 1 && /[A-Za-z]/.test(potentialDriveLetter);
|
|
235551
|
+
if (isWindowsDrive) {
|
|
235552
|
+
const nextColonIndex = mountSpec.indexOf(":", colonIndex + 1);
|
|
235553
|
+
if (nextColonIndex > 0) {
|
|
235554
|
+
localPath2 = mountSpec.substring(0, nextColonIndex);
|
|
235555
|
+
containerPath = mountSpec.substring(nextColonIndex + 1);
|
|
235556
|
+
} else {
|
|
235557
|
+
localPath2 = mountSpec;
|
|
235558
|
+
containerPath = "/workspace/src";
|
|
235559
|
+
}
|
|
235560
|
+
} else {
|
|
235561
|
+
localPath2 = mountSpec.substring(0, colonIndex);
|
|
235562
|
+
containerPath = mountSpec.substring(colonIndex + 1);
|
|
235563
|
+
}
|
|
235564
|
+
} else if (colonIndex === 0) {
|
|
235565
|
+
localPath2 = "";
|
|
235566
|
+
containerPath = mountSpec.substring(1);
|
|
235567
|
+
} else {
|
|
235568
|
+
localPath2 = mountSpec;
|
|
235569
|
+
containerPath = "/workspace/src";
|
|
235570
|
+
}
|
|
235571
|
+
const path7 = __require("path");
|
|
235572
|
+
const resolvedLocalPath = path7.resolve(localPath2);
|
|
235573
|
+
const fs4 = __require("fs");
|
|
235574
|
+
if (!fs4.existsSync(resolvedLocalPath)) {
|
|
235575
|
+
throw new Error(`Mount source directory does not exist: ${resolvedLocalPath}`);
|
|
235576
|
+
}
|
|
235577
|
+
const hostDirectory = client.host().directory(resolvedLocalPath);
|
|
235578
|
+
container = container.withMountedDirectory(containerPath, hostDirectory);
|
|
235579
|
+
logger_default.debug(`\uD83D\uDCC2 Mounted ${resolvedLocalPath} -> ${containerPath}`);
|
|
235580
|
+
return container;
|
|
235581
|
+
} catch (error) {
|
|
235582
|
+
logger_default.error(`Failed to setup directory mount: ${error}`);
|
|
235583
|
+
throw error;
|
|
235584
|
+
}
|
|
235585
|
+
}
|
|
235543
235586
|
async setupContainer(client, environment, inputs, tool) {
|
|
235544
235587
|
const containerImage = tool?.from || this.options.baseImage;
|
|
235545
235588
|
logger_default.debug(`\uD83D\uDE80 Setting up container with image: ${containerImage}${tool?.from ? " (from tool.from)" : " (default baseImage)"}`);
|
|
@@ -235547,6 +235590,9 @@ class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
235547
235590
|
logger_default.debug("\uD83D\uDCE6 Base container created");
|
|
235548
235591
|
container = container.withWorkdir(this.options.workdir);
|
|
235549
235592
|
logger_default.debug(`\uD83D\uDCC1 Working directory set to: ${this.options.workdir}`);
|
|
235593
|
+
if (environment.mount) {
|
|
235594
|
+
container = await this.setupDirectoryMount(client, container, environment.mount);
|
|
235595
|
+
}
|
|
235550
235596
|
for (const [key, value] of Object.entries(environment.vars)) {
|
|
235551
235597
|
container = container.withEnvVariable(key, String(value));
|
|
235552
235598
|
}
|
|
@@ -238994,7 +239040,6 @@ class EnactCore {
|
|
|
238994
239040
|
const messageHash = CryptoUtils.hash(docString);
|
|
238995
239041
|
const directVerify = CryptoUtils.verify(referenceSignature.publicKey, messageHash, referenceSignature.signature);
|
|
238996
239042
|
const isValid2 = SigningService.verifyDocument(documentForVerification, referenceSignature, { includeFields: ["command"] });
|
|
238997
|
-
console.log("Final verification result:", isValid2);
|
|
238998
239043
|
if (!isValid2) {
|
|
238999
239044
|
throw new Error(`Tool ${tool.name} has invalid signatures`);
|
|
239000
239045
|
}
|
|
@@ -239024,7 +239069,8 @@ class EnactCore {
|
|
|
239024
239069
|
vars: { ...envVars, ...validatedInputs },
|
|
239025
239070
|
resources: {
|
|
239026
239071
|
timeout: options.timeout || tool.timeout || this.options.defaultTimeout
|
|
239027
|
-
}
|
|
239072
|
+
},
|
|
239073
|
+
mount: options.mount
|
|
239028
239074
|
});
|
|
239029
239075
|
} catch (error) {
|
|
239030
239076
|
return {
|
|
@@ -239180,577 +239226,154 @@ class EnactCore {
|
|
|
239180
239226
|
return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
239181
239227
|
}
|
|
239182
239228
|
}
|
|
239183
|
-
// ../shared/dist/
|
|
239184
|
-
var
|
|
239185
|
-
|
|
239186
|
-
|
|
239187
|
-
|
|
239188
|
-
|
|
239189
|
-
|
|
239190
|
-
|
|
239191
|
-
|
|
239192
|
-
|
|
239193
|
-
|
|
239194
|
-
|
|
239195
|
-
|
|
239196
|
-
class McpSilentOperationMonitor {
|
|
239197
|
-
getOriginalConsoleError() {
|
|
239198
|
-
return this.originalConsoleError;
|
|
239199
|
-
}
|
|
239200
|
-
constructor() {
|
|
239201
|
-
this.isMonitoring = false;
|
|
239202
|
-
this.violations = [];
|
|
239203
|
-
this.consoleOutput = [];
|
|
239204
|
-
this.processExitAttempts = 0;
|
|
239205
|
-
this.readlineUsageDetected = false;
|
|
239206
|
-
this.startTime = 0;
|
|
239207
|
-
this.originalConsoleLog = console.log;
|
|
239208
|
-
this.originalConsoleError = console.error;
|
|
239209
|
-
this.originalConsoleWarn = console.warn;
|
|
239210
|
-
this.originalConsoleInfo = console.info;
|
|
239211
|
-
this.originalProcessExit = process.exit;
|
|
239212
|
-
this.originalStdoutWrite = process.stdout.write;
|
|
239213
|
-
this.originalStderrWrite = process.stderr.write;
|
|
239229
|
+
// ../shared/dist/LocalToolResolver.js
|
|
239230
|
+
var yaml2 = __toESM(require_dist3(), 1);
|
|
239231
|
+
import { promises as fs5, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
239232
|
+
import { join as join4, resolve, basename as basename2 } from "path";
|
|
239233
|
+
class LocalToolResolver {
|
|
239234
|
+
constructor(enactCore, localToolsDir = "./tools", cacheDir = "./.tool-cache") {
|
|
239235
|
+
this.enactCore = enactCore;
|
|
239236
|
+
this.toolCache = new Map;
|
|
239237
|
+
this.aliases = new Map;
|
|
239238
|
+
this.favorites = new Set;
|
|
239239
|
+
this.localToolsDir = resolve(localToolsDir);
|
|
239240
|
+
this.cacheDir = resolve(cacheDir);
|
|
239241
|
+
this.loadConfiguration();
|
|
239214
239242
|
}
|
|
239215
|
-
|
|
239216
|
-
|
|
239217
|
-
|
|
239243
|
+
async resolveTool(toolName) {
|
|
239244
|
+
const resolvedName = this.aliases.get(toolName) || toolName;
|
|
239245
|
+
const localTool = await this.getLocalTool(resolvedName);
|
|
239246
|
+
if (localTool) {
|
|
239247
|
+
return {
|
|
239248
|
+
tool: localTool,
|
|
239249
|
+
source: "local",
|
|
239250
|
+
metadata: { path: localTool.path }
|
|
239251
|
+
};
|
|
239218
239252
|
}
|
|
239219
|
-
|
|
239220
|
-
this.
|
|
239221
|
-
|
|
239222
|
-
|
|
239223
|
-
|
|
239224
|
-
|
|
239225
|
-
|
|
239226
|
-
|
|
239227
|
-
|
|
239228
|
-
this.
|
|
239229
|
-
|
|
239230
|
-
|
|
239231
|
-
|
|
239232
|
-
|
|
239233
|
-
|
|
239234
|
-
|
|
239235
|
-
|
|
239236
|
-
const message = args.join(" ");
|
|
239237
|
-
this.consoleOutput.push(`[WARN] ${message}`);
|
|
239238
|
-
this.violations.push(`Console.warn called: ${message}`);
|
|
239239
|
-
};
|
|
239240
|
-
console.info = (...args) => {
|
|
239241
|
-
const message = args.join(" ");
|
|
239242
|
-
this.consoleOutput.push(`[INFO] ${message}`);
|
|
239243
|
-
this.violations.push(`Console.info called: ${message}`);
|
|
239244
|
-
};
|
|
239245
|
-
process.exit = (code) => {
|
|
239246
|
-
this.processExitAttempts++;
|
|
239247
|
-
this.violations.push(`Process.exit called with code: ${code}`);
|
|
239248
|
-
throw new Error(`Process exit intercepted: ${code}`);
|
|
239249
|
-
};
|
|
239250
|
-
process.stdout.write = (chunk, ...args) => {
|
|
239251
|
-
if (typeof chunk === "string" && chunk.trim()) {
|
|
239252
|
-
this.consoleOutput.push(`[STDOUT] ${chunk}`);
|
|
239253
|
-
this.violations.push(`Process.stdout.write called: ${chunk.substring(0, 100)}...`);
|
|
239254
|
-
}
|
|
239255
|
-
return true;
|
|
239256
|
-
};
|
|
239257
|
-
process.stderr.write = (chunk, ...args) => {
|
|
239258
|
-
if (typeof chunk === "string" && chunk.trim()) {
|
|
239259
|
-
this.consoleOutput.push(`[STDERR] ${chunk}`);
|
|
239260
|
-
this.violations.push(`Process.stderr.write called: ${chunk.substring(0, 100)}...`);
|
|
239261
|
-
}
|
|
239262
|
-
return true;
|
|
239263
|
-
};
|
|
239264
|
-
const originalRequire = __require;
|
|
239265
|
-
const monitor = this;
|
|
239266
|
-
global.require = function(id) {
|
|
239267
|
-
if (id === "readline" || id.includes("readline")) {
|
|
239268
|
-
monitor.readlineUsageDetected = true;
|
|
239269
|
-
monitor.violations.push("Readline module usage detected");
|
|
239253
|
+
const cachedTool = this.toolCache.get(resolvedName);
|
|
239254
|
+
if (cachedTool && !this.isCacheExpired(cachedTool)) {
|
|
239255
|
+
return {
|
|
239256
|
+
tool: cachedTool,
|
|
239257
|
+
source: "cache",
|
|
239258
|
+
metadata: { cachedAt: cachedTool.lastModified }
|
|
239259
|
+
};
|
|
239260
|
+
}
|
|
239261
|
+
try {
|
|
239262
|
+
const registryTool = await this.enactCore.getToolByName(resolvedName);
|
|
239263
|
+
if (registryTool) {
|
|
239264
|
+
await this.cacheRegistryTool(resolvedName, registryTool);
|
|
239265
|
+
return {
|
|
239266
|
+
tool: registryTool,
|
|
239267
|
+
source: "registry",
|
|
239268
|
+
metadata: { cached: true }
|
|
239269
|
+
};
|
|
239270
239270
|
}
|
|
239271
|
-
|
|
239272
|
-
|
|
239273
|
-
}
|
|
239274
|
-
stopMonitoring() {
|
|
239275
|
-
if (!this.isMonitoring) {
|
|
239276
|
-
throw new Error("Monitor is not currently running");
|
|
239271
|
+
} catch (error) {
|
|
239272
|
+
logger_default.debug(`Registry lookup failed for ${resolvedName}:`, error);
|
|
239277
239273
|
}
|
|
239278
|
-
|
|
239279
|
-
console.error = this.originalConsoleError;
|
|
239280
|
-
console.warn = this.originalConsoleWarn;
|
|
239281
|
-
console.info = this.originalConsoleInfo;
|
|
239282
|
-
process.exit = this.originalProcessExit;
|
|
239283
|
-
process.stdout.write = this.originalStdoutWrite;
|
|
239284
|
-
process.stderr.write = this.originalStderrWrite;
|
|
239285
|
-
global.require = __require;
|
|
239286
|
-
this.isMonitoring = false;
|
|
239287
|
-
return {
|
|
239288
|
-
violations: [...this.violations],
|
|
239289
|
-
consoleOutputDetected: [...this.consoleOutput],
|
|
239290
|
-
processExitAttempts: this.processExitAttempts,
|
|
239291
|
-
readlineUsageDetected: this.readlineUsageDetected,
|
|
239292
|
-
duration: Date.now() - this.startTime,
|
|
239293
|
-
timestamp: new Date().toISOString()
|
|
239294
|
-
};
|
|
239274
|
+
return null;
|
|
239295
239275
|
}
|
|
239296
|
-
|
|
239297
|
-
|
|
239276
|
+
async getLocalTool(toolName) {
|
|
239277
|
+
const possiblePaths = [
|
|
239278
|
+
join4(this.localToolsDir, `${toolName}.yaml`),
|
|
239279
|
+
join4(this.localToolsDir, `${toolName}.yml`),
|
|
239280
|
+
join4(this.localToolsDir, toolName, "tool.yaml"),
|
|
239281
|
+
join4(this.localToolsDir, toolName, "tool.yml"),
|
|
239282
|
+
join4(this.localToolsDir, toolName, `${toolName}.yaml`),
|
|
239283
|
+
join4(this.localToolsDir, toolName, `${toolName}.yml`)
|
|
239284
|
+
];
|
|
239285
|
+
for (const toolPath of possiblePaths) {
|
|
239286
|
+
try {
|
|
239287
|
+
const stats = await fs5.stat(toolPath);
|
|
239288
|
+
const content = await fs5.readFile(toolPath, "utf-8");
|
|
239289
|
+
const definition = yaml2.parse(content);
|
|
239290
|
+
if (definition && (definition.name === toolName || definition.name === undefined)) {
|
|
239291
|
+
return {
|
|
239292
|
+
name: definition.name || toolName,
|
|
239293
|
+
path: toolPath,
|
|
239294
|
+
definition,
|
|
239295
|
+
lastModified: stats.mtime,
|
|
239296
|
+
cached: false
|
|
239297
|
+
};
|
|
239298
|
+
}
|
|
239299
|
+
} catch (error) {
|
|
239300
|
+
continue;
|
|
239301
|
+
}
|
|
239302
|
+
}
|
|
239303
|
+
return null;
|
|
239298
239304
|
}
|
|
239299
|
-
|
|
239300
|
-
|
|
239305
|
+
async cacheRegistryTool(toolName, tool) {
|
|
239306
|
+
try {
|
|
239307
|
+
await fs5.mkdir(this.cacheDir, { recursive: true });
|
|
239308
|
+
const cachePath = join4(this.cacheDir, `${toolName}.yaml`);
|
|
239309
|
+
const cacheData = {
|
|
239310
|
+
...tool,
|
|
239311
|
+
_cached: true,
|
|
239312
|
+
_cachedAt: new Date().toISOString(),
|
|
239313
|
+
_source: "registry"
|
|
239314
|
+
};
|
|
239315
|
+
await fs5.writeFile(cachePath, yaml2.stringify(cacheData));
|
|
239316
|
+
this.toolCache.set(toolName, {
|
|
239317
|
+
name: toolName,
|
|
239318
|
+
path: cachePath,
|
|
239319
|
+
definition: tool,
|
|
239320
|
+
lastModified: new Date,
|
|
239321
|
+
cached: true
|
|
239322
|
+
});
|
|
239323
|
+
logger_default.debug(`Cached registry tool: ${toolName}`);
|
|
239324
|
+
} catch (error) {
|
|
239325
|
+
logger_default.warn(`Failed to cache tool ${toolName}:`, error);
|
|
239326
|
+
}
|
|
239301
239327
|
}
|
|
239302
|
-
|
|
239303
|
-
|
|
239304
|
-
function validateSilentEnvironment() {
|
|
239305
|
-
const issues = [];
|
|
239306
|
-
if (process.env.CI !== "true") {
|
|
239307
|
-
issues.push('CI environment variable not set to "true"');
|
|
239328
|
+
isCacheExpired(tool, maxAge = 24 * 60 * 60 * 1000) {
|
|
239329
|
+
return Date.now() - tool.lastModified.getTime() > maxAge;
|
|
239308
239330
|
}
|
|
239309
|
-
|
|
239310
|
-
|
|
239331
|
+
async listAllTools() {
|
|
239332
|
+
const localTools = await this.scanLocalTools();
|
|
239333
|
+
const cachedTools = Array.from(this.toolCache.values());
|
|
239334
|
+
return {
|
|
239335
|
+
local: localTools,
|
|
239336
|
+
cached: cachedTools,
|
|
239337
|
+
favorites: Array.from(this.favorites),
|
|
239338
|
+
aliases: Object.fromEntries(this.aliases)
|
|
239339
|
+
};
|
|
239311
239340
|
}
|
|
239312
|
-
|
|
239313
|
-
|
|
239314
|
-
|
|
239315
|
-
|
|
239316
|
-
|
|
239317
|
-
|
|
239318
|
-
|
|
239319
|
-
|
|
239320
|
-
|
|
239321
|
-
|
|
239322
|
-
|
|
239323
|
-
|
|
239324
|
-
|
|
239325
|
-
|
|
239326
|
-
|
|
239327
|
-
|
|
239328
|
-
|
|
239329
|
-
|
|
239330
|
-
|
|
239331
|
-
|
|
239332
|
-
|
|
239333
|
-
|
|
239334
|
-
|
|
239335
|
-
|
|
239336
|
-
|
|
239337
|
-
|
|
239338
|
-
|
|
239339
|
-
|
|
239340
|
-
|
|
239341
|
-
join4(__dirname3, "..", "src", "web", "static"),
|
|
239342
|
-
join4(__dirname3, "..", "..", "src", "web", "static"),
|
|
239343
|
-
join4(process.cwd(), "src", "web", "static"),
|
|
239344
|
-
join4(__dirname3, "..", "..", "..", "src", "web", "static"),
|
|
239345
|
-
join4(__dirname3, "..", "..", "src", "web", "static")
|
|
239346
|
-
];
|
|
239347
|
-
for (const candidate of candidates) {
|
|
239348
|
-
if (existsSync4(join4(candidate, "index.html"))) {
|
|
239349
|
-
logger_default.debug(`Found static directory: ${candidate}`);
|
|
239350
|
-
return candidate;
|
|
239351
|
-
}
|
|
239352
|
-
}
|
|
239353
|
-
throw new Error("Could not find static directory. Tried: " + candidates.join(", "));
|
|
239354
|
-
}
|
|
239355
|
-
var STATIC_DIR = findStaticDir();
|
|
239356
|
-
function parseDotEnv(content) {
|
|
239357
|
-
const vars = {};
|
|
239358
|
-
const lines = content.split(`
|
|
239359
|
-
`);
|
|
239360
|
-
for (const line of lines) {
|
|
239361
|
-
const trimmed = line.trim();
|
|
239362
|
-
if (!trimmed || trimmed.startsWith("#")) {
|
|
239363
|
-
continue;
|
|
239364
|
-
}
|
|
239365
|
-
const equalIndex = trimmed.indexOf("=");
|
|
239366
|
-
if (equalIndex === -1) {
|
|
239367
|
-
continue;
|
|
239368
|
-
}
|
|
239369
|
-
const key = trimmed.slice(0, equalIndex).trim();
|
|
239370
|
-
let value = trimmed.slice(equalIndex + 1).trim();
|
|
239371
|
-
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
239372
|
-
value = value.slice(1, -1);
|
|
239373
|
-
}
|
|
239374
|
-
if (key) {
|
|
239375
|
-
vars[key] = value;
|
|
239376
|
-
}
|
|
239377
|
-
}
|
|
239378
|
-
return vars;
|
|
239379
|
-
}
|
|
239380
|
-
function generateDotEnv(vars) {
|
|
239381
|
-
return Object.entries(vars).map(([key, value]) => {
|
|
239382
|
-
const needsQuotes = value.includes(" ") || value.includes("\t") || value.includes(`
|
|
239383
|
-
`) || value.includes('"');
|
|
239384
|
-
const escapedValue = needsQuotes ? `"${value.replace(/"/g, "\\\"")}"` : value;
|
|
239385
|
-
return `${key}=${escapedValue}`;
|
|
239386
|
-
}).join(`
|
|
239387
|
-
`) + `
|
|
239388
|
-
`;
|
|
239389
|
-
}
|
|
239390
|
-
async function getAllPackageNamespaces() {
|
|
239391
|
-
const packages = [];
|
|
239392
|
-
if (!existsSync4(ENV_BASE_DIR)) {
|
|
239393
|
-
return packages;
|
|
239394
|
-
}
|
|
239395
|
-
try {
|
|
239396
|
-
await scanDirectory(ENV_BASE_DIR, "", packages);
|
|
239397
|
-
} catch (error) {
|
|
239398
|
-
logger_default.error("Failed to scan env directory:", error);
|
|
239399
|
-
}
|
|
239400
|
-
return packages;
|
|
239401
|
-
}
|
|
239402
|
-
async function scanDirectory(dir, relativePath, packages) {
|
|
239403
|
-
try {
|
|
239404
|
-
const entries = await readdir(dir);
|
|
239405
|
-
for (const entry of entries) {
|
|
239406
|
-
const fullPath = join4(dir, entry);
|
|
239407
|
-
const stats = await stat2(fullPath);
|
|
239408
|
-
if (stats.isDirectory()) {
|
|
239409
|
-
const newRelativePath = relativePath ? `${relativePath}/${entry}` : entry;
|
|
239410
|
-
await scanDirectory(fullPath, newRelativePath, packages);
|
|
239411
|
-
} else if (entry === ".env") {
|
|
239412
|
-
const namespace = relativePath || "root";
|
|
239413
|
-
try {
|
|
239414
|
-
const content = await readFile3(fullPath, "utf8");
|
|
239415
|
-
const variables = parseDotEnv(content);
|
|
239416
|
-
packages.push({
|
|
239417
|
-
namespace,
|
|
239418
|
-
path: fullPath,
|
|
239419
|
-
variables
|
|
239420
|
-
});
|
|
239421
|
-
} catch (error) {
|
|
239422
|
-
logger_default.error(`Failed to read .env file at ${fullPath}:`, error);
|
|
239423
|
-
}
|
|
239424
|
-
}
|
|
239425
|
-
}
|
|
239426
|
-
} catch (error) {
|
|
239427
|
-
logger_default.error(`Failed to scan directory ${dir}:`, error);
|
|
239428
|
-
}
|
|
239429
|
-
}
|
|
239430
|
-
async function getPackageEnvVars(namespace) {
|
|
239431
|
-
const envFile = join4(ENV_BASE_DIR, namespace, ".env");
|
|
239432
|
-
if (!existsSync4(envFile)) {
|
|
239433
|
-
return {};
|
|
239434
|
-
}
|
|
239435
|
-
try {
|
|
239436
|
-
const content = await readFile3(envFile, "utf8");
|
|
239437
|
-
return parseDotEnv(content);
|
|
239438
|
-
} catch (error) {
|
|
239439
|
-
logger_default.error(`Failed to read env file for ${namespace}:`, error);
|
|
239440
|
-
return {};
|
|
239441
|
-
}
|
|
239442
|
-
}
|
|
239443
|
-
async function setPackageEnvVar(namespace, key, value) {
|
|
239444
|
-
const envFile = join4(ENV_BASE_DIR, namespace, ".env");
|
|
239445
|
-
const envDir = dirname3(envFile);
|
|
239446
|
-
if (!existsSync4(envDir)) {
|
|
239447
|
-
await mkdir2(envDir, { recursive: true });
|
|
239448
|
-
}
|
|
239449
|
-
const existingVars = await getPackageEnvVars(namespace);
|
|
239450
|
-
existingVars[key] = value;
|
|
239451
|
-
const envContent = generateDotEnv(existingVars);
|
|
239452
|
-
await writeFile2(envFile, envContent, "utf8");
|
|
239453
|
-
}
|
|
239454
|
-
async function deletePackageEnvVar(namespace, key) {
|
|
239455
|
-
const existingVars = await getPackageEnvVars(namespace);
|
|
239456
|
-
if (!(key in existingVars)) {
|
|
239457
|
-
throw new Error(`Environment variable '${key}' not found in package '${namespace}'`);
|
|
239458
|
-
}
|
|
239459
|
-
delete existingVars[key];
|
|
239460
|
-
const envFile = join4(ENV_BASE_DIR, namespace, ".env");
|
|
239461
|
-
const envContent = generateDotEnv(existingVars);
|
|
239462
|
-
await writeFile2(envFile, envContent, "utf8");
|
|
239463
|
-
}
|
|
239464
|
-
async function serveStaticFile(filePath, res) {
|
|
239465
|
-
try {
|
|
239466
|
-
const content = await readFile3(filePath, "utf8");
|
|
239467
|
-
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
239468
|
-
let contentType = "text/plain";
|
|
239469
|
-
switch (ext) {
|
|
239470
|
-
case "html":
|
|
239471
|
-
contentType = "text/html";
|
|
239472
|
-
break;
|
|
239473
|
-
case "css":
|
|
239474
|
-
contentType = "text/css";
|
|
239475
|
-
break;
|
|
239476
|
-
case "js":
|
|
239477
|
-
contentType = "application/javascript";
|
|
239478
|
-
break;
|
|
239479
|
-
case "json":
|
|
239480
|
-
contentType = "application/json";
|
|
239481
|
-
break;
|
|
239482
|
-
}
|
|
239483
|
-
res.writeHead(200, { "Content-Type": contentType });
|
|
239484
|
-
res.end(content);
|
|
239485
|
-
} catch (error) {
|
|
239486
|
-
logger_default.error("Error serving static file:", error);
|
|
239487
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
239488
|
-
res.end("File not found");
|
|
239489
|
-
}
|
|
239490
|
-
}
|
|
239491
|
-
async function handleRequest(req, res) {
|
|
239492
|
-
const urlParts = parse3(req.url || "", true);
|
|
239493
|
-
const pathname = urlParts.pathname || "/";
|
|
239494
|
-
const method = req.method || "GET";
|
|
239495
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
239496
|
-
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
239497
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
239498
|
-
if (method === "OPTIONS") {
|
|
239499
|
-
res.writeHead(200);
|
|
239500
|
-
res.end();
|
|
239501
|
-
return;
|
|
239502
|
-
}
|
|
239503
|
-
try {
|
|
239504
|
-
if (pathname === "/") {
|
|
239505
|
-
await serveStaticFile(join4(STATIC_DIR, "index.html"), res);
|
|
239506
|
-
} else if (pathname === "/style.css") {
|
|
239507
|
-
await serveStaticFile(join4(STATIC_DIR, "style.css"), res);
|
|
239508
|
-
} else if (pathname === "/app.js") {
|
|
239509
|
-
await serveStaticFile(join4(STATIC_DIR, "app.js"), res);
|
|
239510
|
-
} else if (pathname === "/favicon.ico") {
|
|
239511
|
-
const favicon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">\uD83C\uDF10</text></svg>`;
|
|
239512
|
-
res.writeHead(200, { "Content-Type": "image/svg+xml" });
|
|
239513
|
-
res.end(favicon);
|
|
239514
|
-
} else if (pathname === "/api/packages" && method === "GET") {
|
|
239515
|
-
const packages = await getAllPackageNamespaces();
|
|
239516
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239517
|
-
res.end(JSON.stringify({ packages }));
|
|
239518
|
-
} else if (pathname === "/api/packages" && method === "POST") {
|
|
239519
|
-
const body = await getRequestBody(req);
|
|
239520
|
-
const { namespace } = JSON.parse(body);
|
|
239521
|
-
if (!namespace) {
|
|
239522
|
-
res.writeHead(400, { "Content-Type": "application/json" });
|
|
239523
|
-
res.end(JSON.stringify({ error: "Namespace is required" }));
|
|
239524
|
-
return;
|
|
239525
|
-
}
|
|
239526
|
-
const envDir = join4(ENV_BASE_DIR, namespace);
|
|
239527
|
-
const envFile = join4(envDir, ".env");
|
|
239528
|
-
if (!existsSync4(envDir)) {
|
|
239529
|
-
await mkdir2(envDir, { recursive: true });
|
|
239530
|
-
}
|
|
239531
|
-
if (!existsSync4(envFile)) {
|
|
239532
|
-
await writeFile2(envFile, "", "utf8");
|
|
239533
|
-
}
|
|
239534
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239535
|
-
res.end(JSON.stringify({ success: true }));
|
|
239536
|
-
} else if (pathname?.startsWith("/api/packages/") && method === "GET") {
|
|
239537
|
-
const namespace = decodeURIComponent(pathname.replace("/api/packages/", ""));
|
|
239538
|
-
const variables = await getPackageEnvVars(namespace);
|
|
239539
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239540
|
-
res.end(JSON.stringify({ namespace, variables }));
|
|
239541
|
-
} else if (pathname?.startsWith("/api/packages/") && pathname.endsWith("/variables") && method === "POST") {
|
|
239542
|
-
const namespace = decodeURIComponent(pathname.replace("/api/packages/", "").replace("/variables", ""));
|
|
239543
|
-
const body = await getRequestBody(req);
|
|
239544
|
-
const { key, value } = JSON.parse(body);
|
|
239545
|
-
if (!key || value === undefined) {
|
|
239546
|
-
res.writeHead(400, { "Content-Type": "application/json" });
|
|
239547
|
-
res.end(JSON.stringify({ error: "Key and value are required" }));
|
|
239548
|
-
return;
|
|
239549
|
-
}
|
|
239550
|
-
await setPackageEnvVar(namespace, key, value);
|
|
239551
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239552
|
-
res.end(JSON.stringify({ success: true }));
|
|
239553
|
-
} else if (pathname?.includes("/variables/") && method === "DELETE") {
|
|
239554
|
-
const pathParts = pathname.split("/");
|
|
239555
|
-
const variableIndex = pathParts.indexOf("variables");
|
|
239556
|
-
const namespace = decodeURIComponent(pathParts.slice(3, variableIndex).join("/"));
|
|
239557
|
-
const key = decodeURIComponent(pathParts[variableIndex + 1]);
|
|
239558
|
-
await deletePackageEnvVar(namespace, key);
|
|
239559
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239560
|
-
res.end(JSON.stringify({ success: true }));
|
|
239561
|
-
} else {
|
|
239562
|
-
res.writeHead(404, { "Content-Type": "application/json" });
|
|
239563
|
-
res.end(JSON.stringify({ error: "Not found" }));
|
|
239564
|
-
}
|
|
239565
|
-
} catch (error) {
|
|
239566
|
-
logger_default.error("Web server error:", error);
|
|
239567
|
-
res.writeHead(500, { "Content-Type": "application/json" });
|
|
239568
|
-
res.end(JSON.stringify({
|
|
239569
|
-
error: error instanceof Error ? error.message : "Internal server error"
|
|
239570
|
-
}));
|
|
239571
|
-
}
|
|
239572
|
-
}
|
|
239573
|
-
function getRequestBody(req) {
|
|
239574
|
-
return new Promise((resolve, reject) => {
|
|
239575
|
-
let body = "";
|
|
239576
|
-
req.on("data", (chunk) => {
|
|
239577
|
-
body += chunk.toString();
|
|
239578
|
-
});
|
|
239579
|
-
req.on("end", () => {
|
|
239580
|
-
resolve(body);
|
|
239581
|
-
});
|
|
239582
|
-
req.on("error", reject);
|
|
239583
|
-
});
|
|
239584
|
-
}
|
|
239585
|
-
function startEnvManagerServer(port = 5555) {
|
|
239586
|
-
return new Promise((resolve, reject) => {
|
|
239587
|
-
const server2 = createServer(handleRequest);
|
|
239588
|
-
server2.listen(port, () => {
|
|
239589
|
-
const actualPort = server2.address()?.port || port;
|
|
239590
|
-
logger_default.info(`\uD83C\uDF10 Environment Manager web server started on http://localhost:${actualPort}`);
|
|
239591
|
-
resolve({ server: server2, port: actualPort });
|
|
239592
|
-
});
|
|
239593
|
-
server2.on("error", (error) => {
|
|
239594
|
-
if (error.code === "EADDRINUSE") {
|
|
239595
|
-
server2.listen(0, () => {
|
|
239596
|
-
const actualPort = server2.address()?.port;
|
|
239597
|
-
logger_default.info(`\uD83C\uDF10 Environment Manager web server started on http://localhost:${actualPort} (port ${port} was in use)`);
|
|
239598
|
-
resolve({ server: server2, port: actualPort });
|
|
239599
|
-
});
|
|
239600
|
-
} else {
|
|
239601
|
-
reject(error);
|
|
239602
|
-
}
|
|
239603
|
-
});
|
|
239604
|
-
});
|
|
239605
|
-
}
|
|
239606
|
-
// ../shared/dist/LocalToolResolver.js
|
|
239607
|
-
var yaml2 = __toESM(require_dist3(), 1);
|
|
239608
|
-
import { promises as fs5, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
239609
|
-
import { join as join5, resolve, basename as basename2 } from "path";
|
|
239610
|
-
class LocalToolResolver {
|
|
239611
|
-
constructor(enactCore, localToolsDir = "./tools", cacheDir = "./.tool-cache") {
|
|
239612
|
-
this.enactCore = enactCore;
|
|
239613
|
-
this.toolCache = new Map;
|
|
239614
|
-
this.aliases = new Map;
|
|
239615
|
-
this.favorites = new Set;
|
|
239616
|
-
this.localToolsDir = resolve(localToolsDir);
|
|
239617
|
-
this.cacheDir = resolve(cacheDir);
|
|
239618
|
-
this.loadConfiguration();
|
|
239619
|
-
}
|
|
239620
|
-
async resolveTool(toolName) {
|
|
239621
|
-
const resolvedName = this.aliases.get(toolName) || toolName;
|
|
239622
|
-
const localTool = await this.getLocalTool(resolvedName);
|
|
239623
|
-
if (localTool) {
|
|
239624
|
-
return {
|
|
239625
|
-
tool: localTool,
|
|
239626
|
-
source: "local",
|
|
239627
|
-
metadata: { path: localTool.path }
|
|
239628
|
-
};
|
|
239629
|
-
}
|
|
239630
|
-
const cachedTool = this.toolCache.get(resolvedName);
|
|
239631
|
-
if (cachedTool && !this.isCacheExpired(cachedTool)) {
|
|
239632
|
-
return {
|
|
239633
|
-
tool: cachedTool,
|
|
239634
|
-
source: "cache",
|
|
239635
|
-
metadata: { cachedAt: cachedTool.lastModified }
|
|
239636
|
-
};
|
|
239637
|
-
}
|
|
239638
|
-
try {
|
|
239639
|
-
const registryTool = await this.enactCore.getToolByName(resolvedName);
|
|
239640
|
-
if (registryTool) {
|
|
239641
|
-
await this.cacheRegistryTool(resolvedName, registryTool);
|
|
239642
|
-
return {
|
|
239643
|
-
tool: registryTool,
|
|
239644
|
-
source: "registry",
|
|
239645
|
-
metadata: { cached: true }
|
|
239646
|
-
};
|
|
239647
|
-
}
|
|
239648
|
-
} catch (error) {
|
|
239649
|
-
logger_default.debug(`Registry lookup failed for ${resolvedName}:`, error);
|
|
239650
|
-
}
|
|
239651
|
-
return null;
|
|
239652
|
-
}
|
|
239653
|
-
async getLocalTool(toolName) {
|
|
239654
|
-
const possiblePaths = [
|
|
239655
|
-
join5(this.localToolsDir, `${toolName}.yaml`),
|
|
239656
|
-
join5(this.localToolsDir, `${toolName}.yml`),
|
|
239657
|
-
join5(this.localToolsDir, toolName, "tool.yaml"),
|
|
239658
|
-
join5(this.localToolsDir, toolName, "tool.yml"),
|
|
239659
|
-
join5(this.localToolsDir, toolName, `${toolName}.yaml`),
|
|
239660
|
-
join5(this.localToolsDir, toolName, `${toolName}.yml`)
|
|
239661
|
-
];
|
|
239662
|
-
for (const toolPath of possiblePaths) {
|
|
239663
|
-
try {
|
|
239664
|
-
const stats = await fs5.stat(toolPath);
|
|
239665
|
-
const content = await fs5.readFile(toolPath, "utf-8");
|
|
239666
|
-
const definition = yaml2.parse(content);
|
|
239667
|
-
if (definition && (definition.name === toolName || definition.name === undefined)) {
|
|
239668
|
-
return {
|
|
239669
|
-
name: definition.name || toolName,
|
|
239670
|
-
path: toolPath,
|
|
239671
|
-
definition,
|
|
239672
|
-
lastModified: stats.mtime,
|
|
239673
|
-
cached: false
|
|
239674
|
-
};
|
|
239675
|
-
}
|
|
239676
|
-
} catch (error) {
|
|
239677
|
-
continue;
|
|
239678
|
-
}
|
|
239679
|
-
}
|
|
239680
|
-
return null;
|
|
239681
|
-
}
|
|
239682
|
-
async cacheRegistryTool(toolName, tool) {
|
|
239683
|
-
try {
|
|
239684
|
-
await fs5.mkdir(this.cacheDir, { recursive: true });
|
|
239685
|
-
const cachePath = join5(this.cacheDir, `${toolName}.yaml`);
|
|
239686
|
-
const cacheData = {
|
|
239687
|
-
...tool,
|
|
239688
|
-
_cached: true,
|
|
239689
|
-
_cachedAt: new Date().toISOString(),
|
|
239690
|
-
_source: "registry"
|
|
239691
|
-
};
|
|
239692
|
-
await fs5.writeFile(cachePath, yaml2.stringify(cacheData));
|
|
239693
|
-
this.toolCache.set(toolName, {
|
|
239694
|
-
name: toolName,
|
|
239695
|
-
path: cachePath,
|
|
239696
|
-
definition: tool,
|
|
239697
|
-
lastModified: new Date,
|
|
239698
|
-
cached: true
|
|
239699
|
-
});
|
|
239700
|
-
logger_default.debug(`Cached registry tool: ${toolName}`);
|
|
239701
|
-
} catch (error) {
|
|
239702
|
-
logger_default.warn(`Failed to cache tool ${toolName}:`, error);
|
|
239703
|
-
}
|
|
239704
|
-
}
|
|
239705
|
-
isCacheExpired(tool, maxAge = 24 * 60 * 60 * 1000) {
|
|
239706
|
-
return Date.now() - tool.lastModified.getTime() > maxAge;
|
|
239707
|
-
}
|
|
239708
|
-
async listAllTools() {
|
|
239709
|
-
const localTools = await this.scanLocalTools();
|
|
239710
|
-
const cachedTools = Array.from(this.toolCache.values());
|
|
239711
|
-
return {
|
|
239712
|
-
local: localTools,
|
|
239713
|
-
cached: cachedTools,
|
|
239714
|
-
favorites: Array.from(this.favorites),
|
|
239715
|
-
aliases: Object.fromEntries(this.aliases)
|
|
239716
|
-
};
|
|
239717
|
-
}
|
|
239718
|
-
async scanLocalTools() {
|
|
239719
|
-
const tools = [];
|
|
239720
|
-
try {
|
|
239721
|
-
await fs5.mkdir(this.localToolsDir, { recursive: true });
|
|
239722
|
-
const entries = await this.scanDirectory(this.localToolsDir);
|
|
239723
|
-
for (const entry of entries) {
|
|
239724
|
-
if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
|
|
239725
|
-
try {
|
|
239726
|
-
const content = await fs5.readFile(entry, "utf-8");
|
|
239727
|
-
const definition = yaml2.parse(content);
|
|
239728
|
-
if (definition && (definition.name || definition.command)) {
|
|
239729
|
-
const stats = await fs5.stat(entry);
|
|
239730
|
-
tools.push({
|
|
239731
|
-
name: definition.name || basename2(entry, ".yaml").replace(".yml", ""),
|
|
239732
|
-
path: entry,
|
|
239733
|
-
definition,
|
|
239734
|
-
lastModified: stats.mtime,
|
|
239735
|
-
cached: false
|
|
239736
|
-
});
|
|
239737
|
-
}
|
|
239738
|
-
} catch (error) {
|
|
239739
|
-
logger_default.debug(`Skipping invalid tool file ${entry}:`, error);
|
|
239740
|
-
}
|
|
239741
|
-
}
|
|
239742
|
-
}
|
|
239743
|
-
} catch (error) {
|
|
239744
|
-
logger_default.warn(`Failed to scan local tools directory:`, error);
|
|
239745
|
-
}
|
|
239746
|
-
return tools;
|
|
239341
|
+
async scanLocalTools() {
|
|
239342
|
+
const tools = [];
|
|
239343
|
+
try {
|
|
239344
|
+
await fs5.mkdir(this.localToolsDir, { recursive: true });
|
|
239345
|
+
const entries = await this.scanDirectory(this.localToolsDir);
|
|
239346
|
+
for (const entry of entries) {
|
|
239347
|
+
if (entry.endsWith(".yaml") || entry.endsWith(".yml")) {
|
|
239348
|
+
try {
|
|
239349
|
+
const content = await fs5.readFile(entry, "utf-8");
|
|
239350
|
+
const definition = yaml2.parse(content);
|
|
239351
|
+
if (definition && (definition.name || definition.command)) {
|
|
239352
|
+
const stats = await fs5.stat(entry);
|
|
239353
|
+
tools.push({
|
|
239354
|
+
name: definition.name || basename2(entry, ".yaml").replace(".yml", ""),
|
|
239355
|
+
path: entry,
|
|
239356
|
+
definition,
|
|
239357
|
+
lastModified: stats.mtime,
|
|
239358
|
+
cached: false
|
|
239359
|
+
});
|
|
239360
|
+
}
|
|
239361
|
+
} catch (error) {
|
|
239362
|
+
logger_default.debug(`Skipping invalid tool file ${entry}:`, error);
|
|
239363
|
+
}
|
|
239364
|
+
}
|
|
239365
|
+
}
|
|
239366
|
+
} catch (error) {
|
|
239367
|
+
logger_default.warn(`Failed to scan local tools directory:`, error);
|
|
239368
|
+
}
|
|
239369
|
+
return tools;
|
|
239747
239370
|
}
|
|
239748
239371
|
async scanDirectory(dir) {
|
|
239749
239372
|
const files = [];
|
|
239750
239373
|
try {
|
|
239751
239374
|
const entries = await fs5.readdir(dir, { withFileTypes: true });
|
|
239752
239375
|
for (const entry of entries) {
|
|
239753
|
-
const fullPath =
|
|
239376
|
+
const fullPath = join4(dir, entry.name);
|
|
239754
239377
|
if (entry.isDirectory()) {
|
|
239755
239378
|
const subFiles = await this.scanDirectory(fullPath);
|
|
239756
239379
|
files.push(...subFiles);
|
|
@@ -239809,13 +239432,13 @@ class LocalToolResolver {
|
|
|
239809
239432
|
}
|
|
239810
239433
|
loadConfiguration() {
|
|
239811
239434
|
try {
|
|
239812
|
-
const configPath =
|
|
239813
|
-
const
|
|
239814
|
-
if (
|
|
239815
|
-
this.aliases = new Map(Object.entries(
|
|
239435
|
+
const configPath = join4(this.localToolsDir, "config.json");
|
|
239436
|
+
const config = JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
239437
|
+
if (config.aliases) {
|
|
239438
|
+
this.aliases = new Map(Object.entries(config.aliases));
|
|
239816
239439
|
}
|
|
239817
|
-
if (
|
|
239818
|
-
this.favorites = new Set(
|
|
239440
|
+
if (config.favorites) {
|
|
239441
|
+
this.favorites = new Set(config.favorites);
|
|
239819
239442
|
}
|
|
239820
239443
|
} catch (error) {
|
|
239821
239444
|
logger_default.debug("No tool configuration found, using defaults");
|
|
@@ -239823,13 +239446,13 @@ class LocalToolResolver {
|
|
|
239823
239446
|
}
|
|
239824
239447
|
saveConfiguration() {
|
|
239825
239448
|
try {
|
|
239826
|
-
const configPath =
|
|
239827
|
-
const
|
|
239449
|
+
const configPath = join4(this.localToolsDir, "config.json");
|
|
239450
|
+
const config = {
|
|
239828
239451
|
aliases: Object.fromEntries(this.aliases),
|
|
239829
239452
|
favorites: Array.from(this.favorites),
|
|
239830
239453
|
lastUpdated: new Date().toISOString()
|
|
239831
239454
|
};
|
|
239832
|
-
writeFileSync(configPath, JSON.stringify(
|
|
239455
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
239833
239456
|
} catch (error) {
|
|
239834
239457
|
logger_default.warn("Failed to save tool configuration:", error);
|
|
239835
239458
|
}
|
|
@@ -239853,11 +239476,11 @@ class LocalToolResolver {
|
|
|
239853
239476
|
}
|
|
239854
239477
|
}
|
|
239855
239478
|
};
|
|
239856
|
-
const samplePath =
|
|
239479
|
+
const samplePath = join4(this.localToolsDir, "hello-world.yaml");
|
|
239857
239480
|
await fs5.writeFile(samplePath, yaml2.stringify(sampleTool));
|
|
239858
239481
|
logger_default.info(`Created sample tool at ${samplePath}`);
|
|
239859
239482
|
}
|
|
239860
|
-
const readmePath =
|
|
239483
|
+
const readmePath = join4(this.localToolsDir, "README.md");
|
|
239861
239484
|
const readme = `# Local Tools Directory
|
|
239862
239485
|
|
|
239863
239486
|
This directory contains your local Enact tools. Tools can be organized as:
|
|
@@ -239889,6 +239512,148 @@ Use the MCP tools to manage this directory programmatically.
|
|
|
239889
239512
|
}
|
|
239890
239513
|
}
|
|
239891
239514
|
var LocalToolResolver_default = LocalToolResolver;
|
|
239515
|
+
// ../shared/dist/utils/help.js
|
|
239516
|
+
var __dirname = "/Users/keithgroves/projects/enact/enact-cli/packages/shared/dist/utils";
|
|
239517
|
+
// ../shared/dist/utils/version.js
|
|
239518
|
+
var __filename = "/Users/keithgroves/projects/enact/enact-cli/packages/shared/dist/utils/version.js";
|
|
239519
|
+
// ../shared/dist/utils/logger.js
|
|
239520
|
+
var LogLevel;
|
|
239521
|
+
(function(LogLevel2) {
|
|
239522
|
+
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
239523
|
+
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
239524
|
+
LogLevel2[LogLevel2["SUCCESS"] = 2] = "SUCCESS";
|
|
239525
|
+
LogLevel2[LogLevel2["WARN"] = 3] = "WARN";
|
|
239526
|
+
LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR";
|
|
239527
|
+
})(LogLevel || (LogLevel = {}));
|
|
239528
|
+
var currentLogLevel = LogLevel.INFO;
|
|
239529
|
+
// ../shared/dist/utils/silent-monitor.js
|
|
239530
|
+
class McpSilentOperationMonitor {
|
|
239531
|
+
getOriginalConsoleError() {
|
|
239532
|
+
return this.originalConsoleError;
|
|
239533
|
+
}
|
|
239534
|
+
constructor() {
|
|
239535
|
+
this.isMonitoring = false;
|
|
239536
|
+
this.violations = [];
|
|
239537
|
+
this.consoleOutput = [];
|
|
239538
|
+
this.processExitAttempts = 0;
|
|
239539
|
+
this.readlineUsageDetected = false;
|
|
239540
|
+
this.startTime = 0;
|
|
239541
|
+
this.originalConsoleLog = console.log;
|
|
239542
|
+
this.originalConsoleError = console.error;
|
|
239543
|
+
this.originalConsoleWarn = console.warn;
|
|
239544
|
+
this.originalConsoleInfo = console.info;
|
|
239545
|
+
this.originalProcessExit = process.exit;
|
|
239546
|
+
this.originalStdoutWrite = process.stdout.write;
|
|
239547
|
+
this.originalStderrWrite = process.stderr.write;
|
|
239548
|
+
}
|
|
239549
|
+
startMonitoring() {
|
|
239550
|
+
if (this.isMonitoring) {
|
|
239551
|
+
return;
|
|
239552
|
+
}
|
|
239553
|
+
this.isMonitoring = true;
|
|
239554
|
+
this.violations = [];
|
|
239555
|
+
this.consoleOutput = [];
|
|
239556
|
+
this.processExitAttempts = 0;
|
|
239557
|
+
this.readlineUsageDetected = false;
|
|
239558
|
+
this.startTime = Date.now();
|
|
239559
|
+
console.log = (...args) => {
|
|
239560
|
+
const message = args.join(" ");
|
|
239561
|
+
this.consoleOutput.push(`[LOG] ${message}`);
|
|
239562
|
+
this.violations.push(`Console.log called: ${message}`);
|
|
239563
|
+
};
|
|
239564
|
+
console.error = (...args) => {
|
|
239565
|
+
const message = args.join(" ");
|
|
239566
|
+
this.consoleOutput.push(`[ERROR] ${message}`);
|
|
239567
|
+
this.violations.push(`Console.error called: ${message}`);
|
|
239568
|
+
};
|
|
239569
|
+
console.warn = (...args) => {
|
|
239570
|
+
const message = args.join(" ");
|
|
239571
|
+
this.consoleOutput.push(`[WARN] ${message}`);
|
|
239572
|
+
this.violations.push(`Console.warn called: ${message}`);
|
|
239573
|
+
};
|
|
239574
|
+
console.info = (...args) => {
|
|
239575
|
+
const message = args.join(" ");
|
|
239576
|
+
this.consoleOutput.push(`[INFO] ${message}`);
|
|
239577
|
+
this.violations.push(`Console.info called: ${message}`);
|
|
239578
|
+
};
|
|
239579
|
+
process.exit = (code) => {
|
|
239580
|
+
this.processExitAttempts++;
|
|
239581
|
+
this.violations.push(`Process.exit called with code: ${code}`);
|
|
239582
|
+
throw new Error(`Process exit intercepted: ${code}`);
|
|
239583
|
+
};
|
|
239584
|
+
process.stdout.write = (chunk, ...args) => {
|
|
239585
|
+
if (typeof chunk === "string" && chunk.trim()) {
|
|
239586
|
+
this.consoleOutput.push(`[STDOUT] ${chunk}`);
|
|
239587
|
+
this.violations.push(`Process.stdout.write called: ${chunk.substring(0, 100)}...`);
|
|
239588
|
+
}
|
|
239589
|
+
return true;
|
|
239590
|
+
};
|
|
239591
|
+
process.stderr.write = (chunk, ...args) => {
|
|
239592
|
+
if (typeof chunk === "string" && chunk.trim()) {
|
|
239593
|
+
this.consoleOutput.push(`[STDERR] ${chunk}`);
|
|
239594
|
+
this.violations.push(`Process.stderr.write called: ${chunk.substring(0, 100)}...`);
|
|
239595
|
+
}
|
|
239596
|
+
return true;
|
|
239597
|
+
};
|
|
239598
|
+
const originalRequire = __require;
|
|
239599
|
+
const monitor = this;
|
|
239600
|
+
global.require = function(id) {
|
|
239601
|
+
if (id === "readline" || id.includes("readline")) {
|
|
239602
|
+
monitor.readlineUsageDetected = true;
|
|
239603
|
+
monitor.violations.push("Readline module usage detected");
|
|
239604
|
+
}
|
|
239605
|
+
return originalRequire.apply(this, arguments);
|
|
239606
|
+
};
|
|
239607
|
+
}
|
|
239608
|
+
stopMonitoring() {
|
|
239609
|
+
if (!this.isMonitoring) {
|
|
239610
|
+
throw new Error("Monitor is not currently running");
|
|
239611
|
+
}
|
|
239612
|
+
console.log = this.originalConsoleLog;
|
|
239613
|
+
console.error = this.originalConsoleError;
|
|
239614
|
+
console.warn = this.originalConsoleWarn;
|
|
239615
|
+
console.info = this.originalConsoleInfo;
|
|
239616
|
+
process.exit = this.originalProcessExit;
|
|
239617
|
+
process.stdout.write = this.originalStdoutWrite;
|
|
239618
|
+
process.stderr.write = this.originalStderrWrite;
|
|
239619
|
+
global.require = __require;
|
|
239620
|
+
this.isMonitoring = false;
|
|
239621
|
+
return {
|
|
239622
|
+
violations: [...this.violations],
|
|
239623
|
+
consoleOutputDetected: [...this.consoleOutput],
|
|
239624
|
+
processExitAttempts: this.processExitAttempts,
|
|
239625
|
+
readlineUsageDetected: this.readlineUsageDetected,
|
|
239626
|
+
duration: Date.now() - this.startTime,
|
|
239627
|
+
timestamp: new Date().toISOString()
|
|
239628
|
+
};
|
|
239629
|
+
}
|
|
239630
|
+
isCurrentlyMonitoring() {
|
|
239631
|
+
return this.isMonitoring;
|
|
239632
|
+
}
|
|
239633
|
+
getViolations() {
|
|
239634
|
+
return [...this.violations];
|
|
239635
|
+
}
|
|
239636
|
+
}
|
|
239637
|
+
var globalMonitor = new McpSilentOperationMonitor;
|
|
239638
|
+
function validateSilentEnvironment() {
|
|
239639
|
+
const issues = [];
|
|
239640
|
+
if (process.env.CI !== "true") {
|
|
239641
|
+
issues.push('CI environment variable not set to "true"');
|
|
239642
|
+
}
|
|
239643
|
+
if (process.env.ENACT_SKIP_INTERACTIVE !== "true") {
|
|
239644
|
+
issues.push('ENACT_SKIP_INTERACTIVE not set to "true"');
|
|
239645
|
+
}
|
|
239646
|
+
if (process.env.DEBUG === "true" || process.env.VERBOSE === "true") {
|
|
239647
|
+
issues.push("DEBUG or VERBOSE environment variables are enabled");
|
|
239648
|
+
}
|
|
239649
|
+
if (process.stdin.isTTY) {
|
|
239650
|
+
issues.push("Process is running in TTY mode (potentially interactive)");
|
|
239651
|
+
}
|
|
239652
|
+
return {
|
|
239653
|
+
valid: issues.length === 0,
|
|
239654
|
+
issues
|
|
239655
|
+
};
|
|
239656
|
+
}
|
|
239892
239657
|
// ../shared/dist/services/McpCoreService.js
|
|
239893
239658
|
class McpCoreService {
|
|
239894
239659
|
constructor(options) {
|
|
@@ -239968,6 +239733,287 @@ class McpCoreService {
|
|
|
239968
239733
|
}
|
|
239969
239734
|
}
|
|
239970
239735
|
var mcpCoreService = new McpCoreService;
|
|
239736
|
+
// ../shared/dist/web/env-manager-server.js
|
|
239737
|
+
import { createServer } from "http";
|
|
239738
|
+
import { parse as parse4 } from "url";
|
|
239739
|
+
import { readFile as readFile3, writeFile as writeFile2, mkdir as mkdir2, readdir, stat as stat2 } from "fs/promises";
|
|
239740
|
+
import { existsSync as existsSync4 } from "fs";
|
|
239741
|
+
import { join as join5, dirname as dirname3 } from "path";
|
|
239742
|
+
import { homedir as homedir4 } from "os";
|
|
239743
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
239744
|
+
var __filename3 = fileURLToPath4(import.meta.url);
|
|
239745
|
+
var __dirname3 = dirname3(__filename3);
|
|
239746
|
+
var CONFIG_DIR3 = join5(homedir4(), ".enact");
|
|
239747
|
+
var ENV_BASE_DIR = join5(CONFIG_DIR3, "env");
|
|
239748
|
+
function findStaticDir() {
|
|
239749
|
+
const candidates = [
|
|
239750
|
+
join5(__dirname3, "web", "static"),
|
|
239751
|
+
join5(__dirname3, "static"),
|
|
239752
|
+
join5(__dirname3, "..", "src", "web", "static"),
|
|
239753
|
+
join5(__dirname3, "..", "..", "src", "web", "static"),
|
|
239754
|
+
join5(process.cwd(), "src", "web", "static"),
|
|
239755
|
+
join5(__dirname3, "..", "..", "..", "src", "web", "static"),
|
|
239756
|
+
join5(__dirname3, "..", "..", "src", "web", "static")
|
|
239757
|
+
];
|
|
239758
|
+
for (const candidate of candidates) {
|
|
239759
|
+
if (existsSync4(join5(candidate, "index.html"))) {
|
|
239760
|
+
logger_default.debug(`Found static directory: ${candidate}`);
|
|
239761
|
+
return candidate;
|
|
239762
|
+
}
|
|
239763
|
+
}
|
|
239764
|
+
throw new Error("Could not find static directory. Tried: " + candidates.join(", "));
|
|
239765
|
+
}
|
|
239766
|
+
var STATIC_DIR = findStaticDir();
|
|
239767
|
+
function parseDotEnv(content) {
|
|
239768
|
+
const vars = {};
|
|
239769
|
+
const lines = content.split(`
|
|
239770
|
+
`);
|
|
239771
|
+
for (const line of lines) {
|
|
239772
|
+
const trimmed = line.trim();
|
|
239773
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
239774
|
+
continue;
|
|
239775
|
+
}
|
|
239776
|
+
const equalIndex = trimmed.indexOf("=");
|
|
239777
|
+
if (equalIndex === -1) {
|
|
239778
|
+
continue;
|
|
239779
|
+
}
|
|
239780
|
+
const key = trimmed.slice(0, equalIndex).trim();
|
|
239781
|
+
let value = trimmed.slice(equalIndex + 1).trim();
|
|
239782
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
239783
|
+
value = value.slice(1, -1);
|
|
239784
|
+
}
|
|
239785
|
+
if (key) {
|
|
239786
|
+
vars[key] = value;
|
|
239787
|
+
}
|
|
239788
|
+
}
|
|
239789
|
+
return vars;
|
|
239790
|
+
}
|
|
239791
|
+
function generateDotEnv(vars) {
|
|
239792
|
+
return Object.entries(vars).map(([key, value]) => {
|
|
239793
|
+
const needsQuotes = value.includes(" ") || value.includes("\t") || value.includes(`
|
|
239794
|
+
`) || value.includes('"');
|
|
239795
|
+
const escapedValue = needsQuotes ? `"${value.replace(/"/g, "\\\"")}"` : value;
|
|
239796
|
+
return `${key}=${escapedValue}`;
|
|
239797
|
+
}).join(`
|
|
239798
|
+
`) + `
|
|
239799
|
+
`;
|
|
239800
|
+
}
|
|
239801
|
+
async function getAllPackageNamespaces() {
|
|
239802
|
+
const packages = [];
|
|
239803
|
+
if (!existsSync4(ENV_BASE_DIR)) {
|
|
239804
|
+
return packages;
|
|
239805
|
+
}
|
|
239806
|
+
try {
|
|
239807
|
+
await scanDirectory(ENV_BASE_DIR, "", packages);
|
|
239808
|
+
} catch (error) {
|
|
239809
|
+
logger_default.error("Failed to scan env directory:", error);
|
|
239810
|
+
}
|
|
239811
|
+
return packages;
|
|
239812
|
+
}
|
|
239813
|
+
async function scanDirectory(dir, relativePath, packages) {
|
|
239814
|
+
try {
|
|
239815
|
+
const entries = await readdir(dir);
|
|
239816
|
+
for (const entry of entries) {
|
|
239817
|
+
const fullPath = join5(dir, entry);
|
|
239818
|
+
const stats = await stat2(fullPath);
|
|
239819
|
+
if (stats.isDirectory()) {
|
|
239820
|
+
const newRelativePath = relativePath ? `${relativePath}/${entry}` : entry;
|
|
239821
|
+
await scanDirectory(fullPath, newRelativePath, packages);
|
|
239822
|
+
} else if (entry === ".env") {
|
|
239823
|
+
const namespace = relativePath || "root";
|
|
239824
|
+
try {
|
|
239825
|
+
const content = await readFile3(fullPath, "utf8");
|
|
239826
|
+
const variables = parseDotEnv(content);
|
|
239827
|
+
packages.push({
|
|
239828
|
+
namespace,
|
|
239829
|
+
path: fullPath,
|
|
239830
|
+
variables
|
|
239831
|
+
});
|
|
239832
|
+
} catch (error) {
|
|
239833
|
+
logger_default.error(`Failed to read .env file at ${fullPath}:`, error);
|
|
239834
|
+
}
|
|
239835
|
+
}
|
|
239836
|
+
}
|
|
239837
|
+
} catch (error) {
|
|
239838
|
+
logger_default.error(`Failed to scan directory ${dir}:`, error);
|
|
239839
|
+
}
|
|
239840
|
+
}
|
|
239841
|
+
async function getPackageEnvVars(namespace) {
|
|
239842
|
+
const envFile = join5(ENV_BASE_DIR, namespace, ".env");
|
|
239843
|
+
if (!existsSync4(envFile)) {
|
|
239844
|
+
return {};
|
|
239845
|
+
}
|
|
239846
|
+
try {
|
|
239847
|
+
const content = await readFile3(envFile, "utf8");
|
|
239848
|
+
return parseDotEnv(content);
|
|
239849
|
+
} catch (error) {
|
|
239850
|
+
logger_default.error(`Failed to read env file for ${namespace}:`, error);
|
|
239851
|
+
return {};
|
|
239852
|
+
}
|
|
239853
|
+
}
|
|
239854
|
+
async function setPackageEnvVar(namespace, key, value) {
|
|
239855
|
+
const envFile = join5(ENV_BASE_DIR, namespace, ".env");
|
|
239856
|
+
const envDir = dirname3(envFile);
|
|
239857
|
+
if (!existsSync4(envDir)) {
|
|
239858
|
+
await mkdir2(envDir, { recursive: true });
|
|
239859
|
+
}
|
|
239860
|
+
const existingVars = await getPackageEnvVars(namespace);
|
|
239861
|
+
existingVars[key] = value;
|
|
239862
|
+
const envContent = generateDotEnv(existingVars);
|
|
239863
|
+
await writeFile2(envFile, envContent, "utf8");
|
|
239864
|
+
}
|
|
239865
|
+
async function deletePackageEnvVar(namespace, key) {
|
|
239866
|
+
const existingVars = await getPackageEnvVars(namespace);
|
|
239867
|
+
if (!(key in existingVars)) {
|
|
239868
|
+
throw new Error(`Environment variable '${key}' not found in package '${namespace}'`);
|
|
239869
|
+
}
|
|
239870
|
+
delete existingVars[key];
|
|
239871
|
+
const envFile = join5(ENV_BASE_DIR, namespace, ".env");
|
|
239872
|
+
const envContent = generateDotEnv(existingVars);
|
|
239873
|
+
await writeFile2(envFile, envContent, "utf8");
|
|
239874
|
+
}
|
|
239875
|
+
async function serveStaticFile(filePath, res) {
|
|
239876
|
+
try {
|
|
239877
|
+
const content = await readFile3(filePath, "utf8");
|
|
239878
|
+
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
239879
|
+
let contentType = "text/plain";
|
|
239880
|
+
switch (ext) {
|
|
239881
|
+
case "html":
|
|
239882
|
+
contentType = "text/html";
|
|
239883
|
+
break;
|
|
239884
|
+
case "css":
|
|
239885
|
+
contentType = "text/css";
|
|
239886
|
+
break;
|
|
239887
|
+
case "js":
|
|
239888
|
+
contentType = "application/javascript";
|
|
239889
|
+
break;
|
|
239890
|
+
case "json":
|
|
239891
|
+
contentType = "application/json";
|
|
239892
|
+
break;
|
|
239893
|
+
}
|
|
239894
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
239895
|
+
res.end(content);
|
|
239896
|
+
} catch (error) {
|
|
239897
|
+
logger_default.error("Error serving static file:", error);
|
|
239898
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
239899
|
+
res.end("File not found");
|
|
239900
|
+
}
|
|
239901
|
+
}
|
|
239902
|
+
async function handleRequest(req, res) {
|
|
239903
|
+
const urlParts = parse4(req.url || "", true);
|
|
239904
|
+
const pathname = urlParts.pathname || "/";
|
|
239905
|
+
const method = req.method || "GET";
|
|
239906
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
239907
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
239908
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
239909
|
+
if (method === "OPTIONS") {
|
|
239910
|
+
res.writeHead(200);
|
|
239911
|
+
res.end();
|
|
239912
|
+
return;
|
|
239913
|
+
}
|
|
239914
|
+
try {
|
|
239915
|
+
if (pathname === "/") {
|
|
239916
|
+
await serveStaticFile(join5(STATIC_DIR, "index.html"), res);
|
|
239917
|
+
} else if (pathname === "/style.css") {
|
|
239918
|
+
await serveStaticFile(join5(STATIC_DIR, "style.css"), res);
|
|
239919
|
+
} else if (pathname === "/app.js") {
|
|
239920
|
+
await serveStaticFile(join5(STATIC_DIR, "app.js"), res);
|
|
239921
|
+
} else if (pathname === "/favicon.ico") {
|
|
239922
|
+
const favicon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">\uD83C\uDF10</text></svg>`;
|
|
239923
|
+
res.writeHead(200, { "Content-Type": "image/svg+xml" });
|
|
239924
|
+
res.end(favicon);
|
|
239925
|
+
} else if (pathname === "/api/packages" && method === "GET") {
|
|
239926
|
+
const packages = await getAllPackageNamespaces();
|
|
239927
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239928
|
+
res.end(JSON.stringify({ packages }));
|
|
239929
|
+
} else if (pathname === "/api/packages" && method === "POST") {
|
|
239930
|
+
const body = await getRequestBody(req);
|
|
239931
|
+
const { namespace } = JSON.parse(body);
|
|
239932
|
+
if (!namespace) {
|
|
239933
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
239934
|
+
res.end(JSON.stringify({ error: "Namespace is required" }));
|
|
239935
|
+
return;
|
|
239936
|
+
}
|
|
239937
|
+
const envDir = join5(ENV_BASE_DIR, namespace);
|
|
239938
|
+
const envFile = join5(envDir, ".env");
|
|
239939
|
+
if (!existsSync4(envDir)) {
|
|
239940
|
+
await mkdir2(envDir, { recursive: true });
|
|
239941
|
+
}
|
|
239942
|
+
if (!existsSync4(envFile)) {
|
|
239943
|
+
await writeFile2(envFile, "", "utf8");
|
|
239944
|
+
}
|
|
239945
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239946
|
+
res.end(JSON.stringify({ success: true }));
|
|
239947
|
+
} else if (pathname?.startsWith("/api/packages/") && method === "GET") {
|
|
239948
|
+
const namespace = decodeURIComponent(pathname.replace("/api/packages/", ""));
|
|
239949
|
+
const variables = await getPackageEnvVars(namespace);
|
|
239950
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239951
|
+
res.end(JSON.stringify({ namespace, variables }));
|
|
239952
|
+
} else if (pathname?.startsWith("/api/packages/") && pathname.endsWith("/variables") && method === "POST") {
|
|
239953
|
+
const namespace = decodeURIComponent(pathname.replace("/api/packages/", "").replace("/variables", ""));
|
|
239954
|
+
const body = await getRequestBody(req);
|
|
239955
|
+
const { key, value } = JSON.parse(body);
|
|
239956
|
+
if (!key || value === undefined) {
|
|
239957
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
239958
|
+
res.end(JSON.stringify({ error: "Key and value are required" }));
|
|
239959
|
+
return;
|
|
239960
|
+
}
|
|
239961
|
+
await setPackageEnvVar(namespace, key, value);
|
|
239962
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239963
|
+
res.end(JSON.stringify({ success: true }));
|
|
239964
|
+
} else if (pathname?.includes("/variables/") && method === "DELETE") {
|
|
239965
|
+
const pathParts = pathname.split("/");
|
|
239966
|
+
const variableIndex = pathParts.indexOf("variables");
|
|
239967
|
+
const namespace = decodeURIComponent(pathParts.slice(3, variableIndex).join("/"));
|
|
239968
|
+
const key = decodeURIComponent(pathParts[variableIndex + 1]);
|
|
239969
|
+
await deletePackageEnvVar(namespace, key);
|
|
239970
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
239971
|
+
res.end(JSON.stringify({ success: true }));
|
|
239972
|
+
} else {
|
|
239973
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
239974
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
239975
|
+
}
|
|
239976
|
+
} catch (error) {
|
|
239977
|
+
logger_default.error("Web server error:", error);
|
|
239978
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
239979
|
+
res.end(JSON.stringify({
|
|
239980
|
+
error: error instanceof Error ? error.message : "Internal server error"
|
|
239981
|
+
}));
|
|
239982
|
+
}
|
|
239983
|
+
}
|
|
239984
|
+
function getRequestBody(req) {
|
|
239985
|
+
return new Promise((resolve2, reject) => {
|
|
239986
|
+
let body = "";
|
|
239987
|
+
req.on("data", (chunk) => {
|
|
239988
|
+
body += chunk.toString();
|
|
239989
|
+
});
|
|
239990
|
+
req.on("end", () => {
|
|
239991
|
+
resolve2(body);
|
|
239992
|
+
});
|
|
239993
|
+
req.on("error", reject);
|
|
239994
|
+
});
|
|
239995
|
+
}
|
|
239996
|
+
function startEnvManagerServer(port = 5555) {
|
|
239997
|
+
return new Promise((resolve2, reject) => {
|
|
239998
|
+
const server2 = createServer(handleRequest);
|
|
239999
|
+
server2.listen(port, () => {
|
|
240000
|
+
const actualPort = server2.address()?.port || port;
|
|
240001
|
+
logger_default.info(`\uD83C\uDF10 Environment Manager web server started on http://localhost:${actualPort}`);
|
|
240002
|
+
resolve2({ server: server2, port: actualPort });
|
|
240003
|
+
});
|
|
240004
|
+
server2.on("error", (error) => {
|
|
240005
|
+
if (error.code === "EADDRINUSE") {
|
|
240006
|
+
server2.listen(0, () => {
|
|
240007
|
+
const actualPort = server2.address()?.port;
|
|
240008
|
+
logger_default.info(`\uD83C\uDF10 Environment Manager web server started on http://localhost:${actualPort} (port ${port} was in use)`);
|
|
240009
|
+
resolve2({ server: server2, port: actualPort });
|
|
240010
|
+
});
|
|
240011
|
+
} else {
|
|
240012
|
+
reject(error);
|
|
240013
|
+
}
|
|
240014
|
+
});
|
|
240015
|
+
});
|
|
240016
|
+
}
|
|
239971
240017
|
// ../shared/dist/lib/enact-direct.js
|
|
239972
240018
|
class EnactDirect {
|
|
239973
240019
|
constructor(options = {}) {
|
|
@@ -240140,7 +240186,8 @@ server2.registerTool("execute-tool-by-name", {
|
|
|
240140
240186
|
dryRun: exports_external.boolean().optional().describe("Dry run mode"),
|
|
240141
240187
|
verbose: exports_external.boolean().optional().describe("Verbose output"),
|
|
240142
240188
|
async: exports_external.boolean().optional().describe("Run in background for long operations"),
|
|
240143
|
-
forceRegistry: exports_external.boolean().optional().describe("Skip local resolution and go straight to registry")
|
|
240189
|
+
forceRegistry: exports_external.boolean().optional().describe("Skip local resolution and go straight to registry"),
|
|
240190
|
+
mount: exports_external.string().optional().describe("Mount local directory to container (format: 'localPath' or 'localPath:containerPath')")
|
|
240144
240191
|
}
|
|
240145
240192
|
}, async (params) => {
|
|
240146
240193
|
const {
|
|
@@ -240152,7 +240199,8 @@ server2.registerTool("execute-tool-by-name", {
|
|
|
240152
240199
|
dryRun,
|
|
240153
240200
|
verbose,
|
|
240154
240201
|
async = false,
|
|
240155
|
-
forceRegistry = false
|
|
240202
|
+
forceRegistry = false,
|
|
240203
|
+
mount
|
|
240156
240204
|
} = params;
|
|
240157
240205
|
try {
|
|
240158
240206
|
logger_default.info(`Executing tool: ${name} (localFile: ${localFile}, async: ${async})`);
|
|
@@ -240243,7 +240291,7 @@ ${suggestions.map((s2) => ` • ${s2}`).join(`
|
|
|
240243
240291
|
}
|
|
240244
240292
|
const isLongRunning = toolToExecute.name.includes("dagger") || toolToExecute.name.includes("docker") || toolToExecute.name.includes("build") || async;
|
|
240245
240293
|
if (isLongRunning) {
|
|
240246
|
-
const operationId = `${toolToExecute.name}-${Date.now()}-${Math.random().toString(36).
|
|
240294
|
+
const operationId = `${toolToExecute.name}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
240247
240295
|
let executionPromise;
|
|
240248
240296
|
if (isLocalFile) {
|
|
240249
240297
|
const yamlContent = await import("fs/promises").then((fs6) => fs6.readFile(toolToExecute.path, "utf-8"));
|
|
@@ -240252,6 +240300,7 @@ ${suggestions.map((s2) => ` • ${s2}`).join(`
|
|
|
240252
240300
|
force: dangerouslySkipVerification || true,
|
|
240253
240301
|
dryRun,
|
|
240254
240302
|
verbose,
|
|
240303
|
+
mount,
|
|
240255
240304
|
isLocalFile: true
|
|
240256
240305
|
});
|
|
240257
240306
|
} else {
|
|
@@ -240260,6 +240309,7 @@ ${suggestions.map((s2) => ` • ${s2}`).join(`
|
|
|
240260
240309
|
force: dangerouslySkipVerification,
|
|
240261
240310
|
dryRun,
|
|
240262
240311
|
verbose,
|
|
240312
|
+
mount,
|
|
240263
240313
|
isLocalFile: false
|
|
240264
240314
|
});
|
|
240265
240315
|
}
|
|
@@ -240302,14 +240352,16 @@ Operation ID: ${operationId}
|
|
|
240302
240352
|
timeout: timeout3 || "120s",
|
|
240303
240353
|
force: dangerouslySkipVerification || true,
|
|
240304
240354
|
dryRun,
|
|
240305
|
-
verbose
|
|
240355
|
+
verbose,
|
|
240356
|
+
mount
|
|
240306
240357
|
});
|
|
240307
240358
|
} else {
|
|
240308
240359
|
result = await enactCore.executeToolByName(toolToExecute.name || name, inputs, {
|
|
240309
240360
|
timeout: timeout3 || "120s",
|
|
240310
240361
|
force: dangerouslySkipVerification,
|
|
240311
240362
|
dryRun,
|
|
240312
|
-
verbose
|
|
240363
|
+
verbose,
|
|
240364
|
+
mount
|
|
240313
240365
|
});
|
|
240314
240366
|
}
|
|
240315
240367
|
if (!result.success) {
|