@enactprotocol/shared 1.2.13 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/config.d.ts +164 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +386 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +15 -5
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +24 -8
- package/dist/constants.js.map +1 -0
- package/dist/execution/command.d.ts +102 -0
- package/dist/execution/command.d.ts.map +1 -0
- package/dist/execution/command.js +262 -0
- package/dist/execution/command.js.map +1 -0
- package/dist/execution/index.d.ts +12 -0
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +17 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/execution/runtime.d.ts +82 -0
- package/dist/execution/runtime.d.ts.map +1 -0
- package/dist/execution/runtime.js +273 -0
- package/dist/execution/runtime.js.map +1 -0
- package/dist/execution/types.d.ts +306 -0
- package/dist/execution/types.d.ts.map +1 -0
- package/dist/execution/types.js +14 -0
- package/dist/execution/types.js.map +1 -0
- package/dist/execution/validation.d.ts +43 -0
- package/dist/execution/validation.d.ts.map +1 -0
- package/dist/execution/validation.js +430 -0
- package/dist/execution/validation.js.map +1 -0
- package/dist/index.d.ts +21 -21
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -25
- package/dist/index.js.map +1 -0
- package/dist/manifest/index.d.ts +7 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +10 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/loader.d.ts +76 -0
- package/dist/manifest/loader.d.ts.map +1 -0
- package/dist/manifest/loader.js +146 -0
- package/dist/manifest/loader.js.map +1 -0
- package/dist/manifest/parser.d.ts +64 -0
- package/dist/manifest/parser.d.ts.map +1 -0
- package/dist/manifest/parser.js +135 -0
- package/dist/manifest/parser.js.map +1 -0
- package/dist/manifest/validator.d.ts +95 -0
- package/dist/manifest/validator.d.ts.map +1 -0
- package/dist/manifest/validator.js +258 -0
- package/dist/manifest/validator.js.map +1 -0
- package/dist/paths.d.ts +57 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +93 -0
- package/dist/paths.js.map +1 -0
- package/dist/registry.d.ts +73 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +147 -0
- package/dist/registry.js.map +1 -0
- package/dist/resolver.d.ts +89 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +282 -0
- package/dist/resolver.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/manifest.d.ts +201 -0
- package/dist/types/manifest.d.ts.map +1 -0
- package/dist/types/manifest.js +13 -0
- package/dist/types/manifest.js.map +1 -0
- package/dist/types.d.ts +5 -132
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -3
- package/dist/types.js.map +1 -0
- package/dist/utils/fs.d.ts +105 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +233 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +102 -25
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +214 -57
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/version.d.ts +60 -2
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +255 -31
- package/dist/utils/version.js.map +1 -0
- package/package.json +16 -58
- package/src/config.ts +510 -0
- package/src/constants.ts +36 -0
- package/src/execution/command.ts +314 -0
- package/src/execution/index.ts +73 -0
- package/src/execution/runtime.ts +308 -0
- package/src/execution/types.ts +379 -0
- package/src/execution/validation.ts +508 -0
- package/src/index.ts +238 -30
- package/src/manifest/index.ts +36 -0
- package/src/manifest/loader.ts +187 -0
- package/src/manifest/parser.ts +173 -0
- package/src/manifest/validator.ts +309 -0
- package/src/paths.ts +108 -0
- package/src/registry.ts +219 -0
- package/src/resolver.ts +345 -0
- package/src/types/index.ts +30 -0
- package/src/types/manifest.ts +255 -0
- package/src/types.ts +5 -188
- package/src/utils/fs.ts +281 -0
- package/src/utils/logger.ts +270 -59
- package/src/utils/version.ts +304 -36
- package/tests/config.test.ts +515 -0
- package/tests/execution/command.test.ts +317 -0
- package/tests/execution/validation.test.ts +384 -0
- package/tests/fixtures/invalid-tool.yaml +4 -0
- package/tests/fixtures/valid-tool.md +62 -0
- package/tests/fixtures/valid-tool.yaml +40 -0
- package/tests/index.test.ts +8 -0
- package/tests/manifest/loader.test.ts +291 -0
- package/tests/manifest/parser.test.ts +345 -0
- package/tests/manifest/validator.test.ts +394 -0
- package/tests/manifest-types.test.ts +358 -0
- package/tests/paths.test.ts +153 -0
- package/tests/registry.test.ts +231 -0
- package/tests/resolver.test.ts +272 -0
- package/tests/utils/fs.test.ts +388 -0
- package/tests/utils/logger.test.ts +480 -0
- package/tests/utils/version.test.ts +390 -0
- package/tsconfig.json +12 -0
- package/dist/LocalToolResolver.d.ts +0 -84
- package/dist/LocalToolResolver.js +0 -353
- package/dist/api/enact-api.d.ts +0 -130
- package/dist/api/enact-api.js +0 -428
- package/dist/api/index.d.ts +0 -2
- package/dist/api/index.js +0 -2
- package/dist/api/types.d.ts +0 -103
- package/dist/api/types.js +0 -1
- package/dist/core/DaggerExecutionProvider.d.ts +0 -169
- package/dist/core/DaggerExecutionProvider.js +0 -1029
- package/dist/core/DirectExecutionProvider.d.ts +0 -23
- package/dist/core/DirectExecutionProvider.js +0 -406
- package/dist/core/EnactCore.d.ts +0 -162
- package/dist/core/EnactCore.js +0 -597
- package/dist/core/NativeExecutionProvider.d.ts +0 -9
- package/dist/core/NativeExecutionProvider.js +0 -16
- package/dist/core/index.d.ts +0 -3
- package/dist/core/index.js +0 -3
- package/dist/exec/index.d.ts +0 -3
- package/dist/exec/index.js +0 -3
- package/dist/exec/logger.d.ts +0 -11
- package/dist/exec/logger.js +0 -57
- package/dist/exec/validate.d.ts +0 -5
- package/dist/exec/validate.js +0 -167
- package/dist/lib/enact-direct.d.ts +0 -150
- package/dist/lib/enact-direct.js +0 -159
- package/dist/lib/index.d.ts +0 -1
- package/dist/lib/index.js +0 -1
- package/dist/security/index.d.ts +0 -3
- package/dist/security/index.js +0 -3
- package/dist/security/security.d.ts +0 -23
- package/dist/security/security.js +0 -137
- package/dist/security/sign.d.ts +0 -103
- package/dist/security/sign.js +0 -666
- package/dist/security/verification-enforcer.d.ts +0 -53
- package/dist/security/verification-enforcer.js +0 -204
- package/dist/services/McpCoreService.d.ts +0 -98
- package/dist/services/McpCoreService.js +0 -124
- package/dist/services/index.d.ts +0 -1
- package/dist/services/index.js +0 -1
- package/dist/utils/config.d.ts +0 -111
- package/dist/utils/config.js +0 -342
- package/dist/utils/env-loader.d.ts +0 -54
- package/dist/utils/env-loader.js +0 -270
- package/dist/utils/help.d.ts +0 -36
- package/dist/utils/help.js +0 -248
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.js +0 -7
- package/dist/utils/silent-monitor.d.ts +0 -67
- package/dist/utils/silent-monitor.js +0 -242
- package/dist/utils/timeout.d.ts +0 -5
- package/dist/utils/timeout.js +0 -23
- package/dist/web/env-manager-server.d.ts +0 -29
- package/dist/web/env-manager-server.js +0 -367
- package/dist/web/index.d.ts +0 -1
- package/dist/web/index.js +0 -1
- package/src/LocalToolResolver.ts +0 -424
- package/src/api/enact-api.ts +0 -604
- package/src/api/index.ts +0 -2
- package/src/api/types.ts +0 -114
- package/src/core/DaggerExecutionProvider.ts +0 -1357
- package/src/core/DirectExecutionProvider.ts +0 -484
- package/src/core/EnactCore.ts +0 -847
- package/src/core/index.ts +0 -3
- package/src/exec/index.ts +0 -3
- package/src/exec/logger.ts +0 -63
- package/src/exec/validate.ts +0 -238
- package/src/lib/enact-direct.ts +0 -254
- package/src/lib/index.ts +0 -1
- package/src/services/McpCoreService.ts +0 -201
- package/src/services/index.ts +0 -1
- package/src/utils/config.ts +0 -438
- package/src/utils/env-loader.ts +0 -370
- package/src/utils/help.ts +0 -257
- package/src/utils/index.ts +0 -7
- package/src/utils/silent-monitor.ts +0 -328
- package/src/utils/timeout.ts +0 -26
- package/src/web/env-manager-server.ts +0 -465
- package/src/web/index.ts +0 -1
- package/src/web/static/app.js +0 -663
- package/src/web/static/index.html +0 -117
- package/src/web/static/style.css +0 -291
|
@@ -1,465 +0,0 @@
|
|
|
1
|
-
// src/web/env-manager-server.ts - Web server for managing environment variables
|
|
2
|
-
import { createServer, IncomingMessage, ServerResponse } 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
|
-
|
|
11
|
-
// Get the directory of this module
|
|
12
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
-
const __dirname = dirname(__filename);
|
|
14
|
-
|
|
15
|
-
// Configuration paths
|
|
16
|
-
const CONFIG_DIR = join(homedir(), ".enact");
|
|
17
|
-
const ENV_BASE_DIR = join(CONFIG_DIR, "env");
|
|
18
|
-
|
|
19
|
-
// Find static files - try multiple locations
|
|
20
|
-
function findStaticDir(): string {
|
|
21
|
-
const candidates = [
|
|
22
|
-
join(__dirname, "web", "static"), // If running from built package (dist/web/static)
|
|
23
|
-
join(__dirname, "static"), // If running from source
|
|
24
|
-
join(__dirname, "..", "src", "web", "static"), // If bundled in dist
|
|
25
|
-
join(__dirname, "..", "..", "src", "web", "static"), // If nested deeper
|
|
26
|
-
join(process.cwd(), "src", "web", "static"), // From project root
|
|
27
|
-
// When installed via npm, static files are in the package root
|
|
28
|
-
join(__dirname, "..", "..", "..", "src", "web", "static"), // node_modules/enact-cli/src/web/static from node_modules/enact-cli/dist/web/
|
|
29
|
-
join(__dirname, "..", "..", "src", "web", "static"), // node_modules/enact-cli/src/web/static from node_modules/enact-cli/dist/
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
for (const candidate of candidates) {
|
|
33
|
-
if (existsSync(join(candidate, "index.html"))) {
|
|
34
|
-
logger.debug(`Found static directory: ${candidate}`);
|
|
35
|
-
return candidate;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
throw new Error(
|
|
40
|
-
"Could not find static directory. Tried: " + candidates.join(", "),
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const STATIC_DIR = findStaticDir();
|
|
45
|
-
|
|
46
|
-
interface PackageEnvInfo {
|
|
47
|
-
namespace: string;
|
|
48
|
-
path: string;
|
|
49
|
-
variables: Record<string, string>;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Parse simple .env file format (KEY=value)
|
|
54
|
-
*/
|
|
55
|
-
function parseDotEnv(content: string): Record<string, string> {
|
|
56
|
-
const vars: Record<string, string> = {};
|
|
57
|
-
const lines = content.split("\n");
|
|
58
|
-
|
|
59
|
-
for (const line of lines) {
|
|
60
|
-
const trimmed = line.trim();
|
|
61
|
-
if (!trimmed || trimmed.startsWith("#")) {
|
|
62
|
-
continue; // Skip empty lines and comments
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const equalIndex = trimmed.indexOf("=");
|
|
66
|
-
if (equalIndex === -1) {
|
|
67
|
-
continue; // Skip lines without '='
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const key = trimmed.slice(0, equalIndex).trim();
|
|
71
|
-
let value = trimmed.slice(equalIndex + 1).trim();
|
|
72
|
-
|
|
73
|
-
// Remove quotes if present
|
|
74
|
-
if (
|
|
75
|
-
(value.startsWith('"') && value.endsWith('"')) ||
|
|
76
|
-
(value.startsWith("'") && value.endsWith("'"))
|
|
77
|
-
) {
|
|
78
|
-
value = value.slice(1, -1);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (key) {
|
|
82
|
-
vars[key] = value;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return vars;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Convert environment variables to .env file format
|
|
91
|
-
*/
|
|
92
|
-
function generateDotEnv(vars: Record<string, string>): string {
|
|
93
|
-
return (
|
|
94
|
-
Object.entries(vars)
|
|
95
|
-
.map(([key, value]) => {
|
|
96
|
-
// Escape value if it contains special characters
|
|
97
|
-
const needsQuotes =
|
|
98
|
-
value.includes(" ") ||
|
|
99
|
-
value.includes("\t") ||
|
|
100
|
-
value.includes("\n") ||
|
|
101
|
-
value.includes('"');
|
|
102
|
-
const escapedValue = needsQuotes
|
|
103
|
-
? `"${value.replace(/"/g, '\\"')}"`
|
|
104
|
-
: value;
|
|
105
|
-
return `${key}=${escapedValue}`;
|
|
106
|
-
})
|
|
107
|
-
.join("\n") + "\n"
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Get all package namespaces with environment variables
|
|
113
|
-
*/
|
|
114
|
-
async function getAllPackageNamespaces(): Promise<PackageEnvInfo[]> {
|
|
115
|
-
const packages: PackageEnvInfo[] = [];
|
|
116
|
-
|
|
117
|
-
if (!existsSync(ENV_BASE_DIR)) {
|
|
118
|
-
return packages;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
await scanDirectory(ENV_BASE_DIR, "", packages);
|
|
123
|
-
} catch (error) {
|
|
124
|
-
logger.error("Failed to scan env directory:", error);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return packages;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Recursively scan directory for .env files
|
|
132
|
-
*/
|
|
133
|
-
async function scanDirectory(
|
|
134
|
-
dir: string,
|
|
135
|
-
relativePath: string,
|
|
136
|
-
packages: PackageEnvInfo[],
|
|
137
|
-
): Promise<void> {
|
|
138
|
-
try {
|
|
139
|
-
const entries = await readdir(dir);
|
|
140
|
-
|
|
141
|
-
for (const entry of entries) {
|
|
142
|
-
const fullPath = join(dir, entry);
|
|
143
|
-
const stats = await stat(fullPath);
|
|
144
|
-
|
|
145
|
-
if (stats.isDirectory()) {
|
|
146
|
-
// Recursively scan subdirectories
|
|
147
|
-
const newRelativePath = relativePath
|
|
148
|
-
? `${relativePath}/${entry}`
|
|
149
|
-
: entry;
|
|
150
|
-
await scanDirectory(fullPath, newRelativePath, packages);
|
|
151
|
-
} else if (entry === ".env") {
|
|
152
|
-
// Found a .env file
|
|
153
|
-
const namespace = relativePath || "root";
|
|
154
|
-
try {
|
|
155
|
-
const content = await readFile(fullPath, "utf8");
|
|
156
|
-
const variables = parseDotEnv(content);
|
|
157
|
-
|
|
158
|
-
packages.push({
|
|
159
|
-
namespace,
|
|
160
|
-
path: fullPath,
|
|
161
|
-
variables,
|
|
162
|
-
});
|
|
163
|
-
} catch (error) {
|
|
164
|
-
logger.error(`Failed to read .env file at ${fullPath}:`, error);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
} catch (error) {
|
|
169
|
-
logger.error(`Failed to scan directory ${dir}:`, error);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Get environment variables for a specific package namespace
|
|
175
|
-
*/
|
|
176
|
-
async function getPackageEnvVars(
|
|
177
|
-
namespace: string,
|
|
178
|
-
): Promise<Record<string, string>> {
|
|
179
|
-
const envFile = join(ENV_BASE_DIR, namespace, ".env");
|
|
180
|
-
|
|
181
|
-
if (!existsSync(envFile)) {
|
|
182
|
-
return {};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
const content = await readFile(envFile, "utf8");
|
|
187
|
-
return parseDotEnv(content);
|
|
188
|
-
} catch (error) {
|
|
189
|
-
logger.error(`Failed to read env file for ${namespace}:`, error);
|
|
190
|
-
return {};
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Set environment variable for a package namespace
|
|
196
|
-
*/
|
|
197
|
-
async function setPackageEnvVar(
|
|
198
|
-
namespace: string,
|
|
199
|
-
key: string,
|
|
200
|
-
value: string,
|
|
201
|
-
): Promise<void> {
|
|
202
|
-
const envFile = join(ENV_BASE_DIR, namespace, ".env");
|
|
203
|
-
const envDir = dirname(envFile);
|
|
204
|
-
|
|
205
|
-
// Ensure directory exists
|
|
206
|
-
if (!existsSync(envDir)) {
|
|
207
|
-
await mkdir(envDir, { recursive: true });
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Read existing variables
|
|
211
|
-
const existingVars = await getPackageEnvVars(namespace);
|
|
212
|
-
|
|
213
|
-
// Update variables
|
|
214
|
-
existingVars[key] = value;
|
|
215
|
-
|
|
216
|
-
// Write back to file
|
|
217
|
-
const envContent = generateDotEnv(existingVars);
|
|
218
|
-
await writeFile(envFile, envContent, "utf8");
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Delete environment variable for a package namespace
|
|
223
|
-
*/
|
|
224
|
-
async function deletePackageEnvVar(
|
|
225
|
-
namespace: string,
|
|
226
|
-
key: string,
|
|
227
|
-
): Promise<void> {
|
|
228
|
-
const existingVars = await getPackageEnvVars(namespace);
|
|
229
|
-
|
|
230
|
-
if (!(key in existingVars)) {
|
|
231
|
-
throw new Error(
|
|
232
|
-
`Environment variable '${key}' not found in package '${namespace}'`,
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
delete existingVars[key];
|
|
237
|
-
|
|
238
|
-
const envFile = join(ENV_BASE_DIR, namespace, ".env");
|
|
239
|
-
const envContent = generateDotEnv(existingVars);
|
|
240
|
-
await writeFile(envFile, envContent, "utf8");
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Serve static files
|
|
245
|
-
*/
|
|
246
|
-
async function serveStaticFile(
|
|
247
|
-
filePath: string,
|
|
248
|
-
res: ServerResponse,
|
|
249
|
-
): Promise<void> {
|
|
250
|
-
try {
|
|
251
|
-
const content = await readFile(filePath, "utf8");
|
|
252
|
-
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
253
|
-
|
|
254
|
-
let contentType = "text/plain";
|
|
255
|
-
switch (ext) {
|
|
256
|
-
case "html":
|
|
257
|
-
contentType = "text/html";
|
|
258
|
-
break;
|
|
259
|
-
case "css":
|
|
260
|
-
contentType = "text/css";
|
|
261
|
-
break;
|
|
262
|
-
case "js":
|
|
263
|
-
contentType = "application/javascript";
|
|
264
|
-
break;
|
|
265
|
-
case "json":
|
|
266
|
-
contentType = "application/json";
|
|
267
|
-
break;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
res.writeHead(200, { "Content-Type": contentType });
|
|
271
|
-
res.end(content);
|
|
272
|
-
} catch (error) {
|
|
273
|
-
logger.error("Error serving static file:", error);
|
|
274
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
275
|
-
res.end("File not found");
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Handle HTTP requests
|
|
281
|
-
*/
|
|
282
|
-
async function handleRequest(
|
|
283
|
-
req: IncomingMessage,
|
|
284
|
-
res: ServerResponse,
|
|
285
|
-
): Promise<void> {
|
|
286
|
-
const urlParts = parse(req.url || "", true);
|
|
287
|
-
const pathname = urlParts.pathname || "/";
|
|
288
|
-
const method = req.method || "GET";
|
|
289
|
-
|
|
290
|
-
// Set CORS headers
|
|
291
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
292
|
-
res.setHeader(
|
|
293
|
-
"Access-Control-Allow-Methods",
|
|
294
|
-
"GET, POST, PUT, DELETE, OPTIONS",
|
|
295
|
-
);
|
|
296
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
297
|
-
|
|
298
|
-
if (method === "OPTIONS") {
|
|
299
|
-
res.writeHead(200);
|
|
300
|
-
res.end();
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
try {
|
|
305
|
-
if (pathname === "/") {
|
|
306
|
-
// Serve main HTML page
|
|
307
|
-
await serveStaticFile(join(STATIC_DIR, "index.html"), res);
|
|
308
|
-
} else if (pathname === "/style.css") {
|
|
309
|
-
// Serve CSS file
|
|
310
|
-
await serveStaticFile(join(STATIC_DIR, "style.css"), res);
|
|
311
|
-
} else if (pathname === "/app.js") {
|
|
312
|
-
// Serve JavaScript file
|
|
313
|
-
await serveStaticFile(join(STATIC_DIR, "app.js"), res);
|
|
314
|
-
} else if (pathname === "/favicon.ico") {
|
|
315
|
-
// Serve a simple SVG favicon
|
|
316
|
-
const favicon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">🌐</text></svg>`;
|
|
317
|
-
res.writeHead(200, { "Content-Type": "image/svg+xml" });
|
|
318
|
-
res.end(favicon);
|
|
319
|
-
} else if (pathname === "/api/packages" && method === "GET") {
|
|
320
|
-
// Get all packages
|
|
321
|
-
const packages = await getAllPackageNamespaces();
|
|
322
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
323
|
-
res.end(JSON.stringify({ packages }));
|
|
324
|
-
} else if (pathname === "/api/packages" && method === "POST") {
|
|
325
|
-
// Create new package
|
|
326
|
-
const body = await getRequestBody(req);
|
|
327
|
-
const { namespace } = JSON.parse(body);
|
|
328
|
-
|
|
329
|
-
if (!namespace) {
|
|
330
|
-
res.writeHead(400, { "Content-Type": "application/json" });
|
|
331
|
-
res.end(JSON.stringify({ error: "Namespace is required" }));
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const envDir = join(ENV_BASE_DIR, namespace);
|
|
336
|
-
const envFile = join(envDir, ".env");
|
|
337
|
-
|
|
338
|
-
if (!existsSync(envDir)) {
|
|
339
|
-
await mkdir(envDir, { recursive: true });
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
if (!existsSync(envFile)) {
|
|
343
|
-
await writeFile(envFile, "", "utf8");
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
347
|
-
res.end(JSON.stringify({ success: true }));
|
|
348
|
-
} else if (pathname?.startsWith("/api/packages/") && method === "GET") {
|
|
349
|
-
// Get specific package variables
|
|
350
|
-
const namespace = decodeURIComponent(
|
|
351
|
-
pathname.replace("/api/packages/", ""),
|
|
352
|
-
);
|
|
353
|
-
const variables = await getPackageEnvVars(namespace);
|
|
354
|
-
|
|
355
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
356
|
-
res.end(JSON.stringify({ namespace, variables }));
|
|
357
|
-
} else if (
|
|
358
|
-
pathname?.startsWith("/api/packages/") &&
|
|
359
|
-
pathname.endsWith("/variables") &&
|
|
360
|
-
method === "POST"
|
|
361
|
-
) {
|
|
362
|
-
// Add/update variable
|
|
363
|
-
const namespace = decodeURIComponent(
|
|
364
|
-
pathname.replace("/api/packages/", "").replace("/variables", ""),
|
|
365
|
-
);
|
|
366
|
-
const body = await getRequestBody(req);
|
|
367
|
-
const { key, value } = JSON.parse(body);
|
|
368
|
-
|
|
369
|
-
if (!key || value === undefined) {
|
|
370
|
-
res.writeHead(400, { "Content-Type": "application/json" });
|
|
371
|
-
res.end(JSON.stringify({ error: "Key and value are required" }));
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
await setPackageEnvVar(namespace, key, value);
|
|
376
|
-
|
|
377
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
378
|
-
res.end(JSON.stringify({ success: true }));
|
|
379
|
-
} else if (pathname?.includes("/variables/") && method === "DELETE") {
|
|
380
|
-
// Delete variable
|
|
381
|
-
const pathParts = pathname.split("/");
|
|
382
|
-
const variableIndex = pathParts.indexOf("variables");
|
|
383
|
-
const namespace = decodeURIComponent(
|
|
384
|
-
pathParts.slice(3, variableIndex).join("/"),
|
|
385
|
-
);
|
|
386
|
-
const key = decodeURIComponent(pathParts[variableIndex + 1]);
|
|
387
|
-
|
|
388
|
-
await deletePackageEnvVar(namespace, key);
|
|
389
|
-
|
|
390
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
391
|
-
res.end(JSON.stringify({ success: true }));
|
|
392
|
-
} else {
|
|
393
|
-
// 404 Not Found
|
|
394
|
-
res.writeHead(404, { "Content-Type": "application/json" });
|
|
395
|
-
res.end(JSON.stringify({ error: "Not found" }));
|
|
396
|
-
}
|
|
397
|
-
} catch (error) {
|
|
398
|
-
logger.error("Web server error:", error);
|
|
399
|
-
res.writeHead(500, { "Content-Type": "application/json" });
|
|
400
|
-
res.end(
|
|
401
|
-
JSON.stringify({
|
|
402
|
-
error: error instanceof Error ? error.message : "Internal server error",
|
|
403
|
-
}),
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Get request body as string
|
|
410
|
-
*/
|
|
411
|
-
function getRequestBody(req: IncomingMessage): Promise<string> {
|
|
412
|
-
return new Promise((resolve, reject) => {
|
|
413
|
-
let body = "";
|
|
414
|
-
req.on("data", (chunk) => {
|
|
415
|
-
body += chunk.toString();
|
|
416
|
-
});
|
|
417
|
-
req.on("end", () => {
|
|
418
|
-
resolve(body);
|
|
419
|
-
});
|
|
420
|
-
req.on("error", reject);
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* Start the web server
|
|
426
|
-
*/
|
|
427
|
-
export function startEnvManagerServer(
|
|
428
|
-
port: number = 5555,
|
|
429
|
-
): Promise<{ server: any; port: number }> {
|
|
430
|
-
return new Promise((resolve, reject) => {
|
|
431
|
-
const server = createServer(handleRequest);
|
|
432
|
-
|
|
433
|
-
// Try to start on the specified port, fallback to a random port if unavailable
|
|
434
|
-
server.listen(port, () => {
|
|
435
|
-
const actualPort = (server.address() as any)?.port || port;
|
|
436
|
-
logger.info(
|
|
437
|
-
`🌐 Environment Manager web server started on http://localhost:${actualPort}`,
|
|
438
|
-
);
|
|
439
|
-
resolve({ server, port: actualPort });
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
server.on("error", (error: any) => {
|
|
443
|
-
if (error.code === "EADDRINUSE") {
|
|
444
|
-
// Port is in use, try a random port
|
|
445
|
-
server.listen(0, () => {
|
|
446
|
-
const actualPort = (server.address() as any)?.port;
|
|
447
|
-
logger.info(
|
|
448
|
-
`🌐 Environment Manager web server started on http://localhost:${actualPort} (port ${port} was in use)`,
|
|
449
|
-
);
|
|
450
|
-
resolve({ server, port: actualPort });
|
|
451
|
-
});
|
|
452
|
-
} else {
|
|
453
|
-
reject(error);
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Export additional functions for use by MCP tools
|
|
460
|
-
export {
|
|
461
|
-
getAllPackageNamespaces,
|
|
462
|
-
getPackageEnvVars,
|
|
463
|
-
setPackageEnvVar,
|
|
464
|
-
deletePackageEnvVar,
|
|
465
|
-
};
|
package/src/web/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './env-manager-server';
|