@enactprotocol/cli 1.2.3 → 1.2.4
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 +566 -166
- package/dist/index.js.bak +566 -166
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -158,31 +158,52 @@ var require_src = __commonJS((exports, module) => {
|
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
// ../shared/dist/utils/config.js
|
|
161
|
-
import { homedir
|
|
162
|
-
import { join
|
|
163
|
-
import { existsSync
|
|
164
|
-
import { mkdir
|
|
161
|
+
import { homedir } from "os";
|
|
162
|
+
import { join } from "path";
|
|
163
|
+
import { existsSync } from "fs";
|
|
164
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
165
165
|
async function ensureConfig() {
|
|
166
|
-
if (!
|
|
167
|
-
await
|
|
166
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
167
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
168
168
|
}
|
|
169
|
-
if (!
|
|
170
|
-
|
|
169
|
+
if (!existsSync(CONFIG_FILE)) {
|
|
170
|
+
const defaultConfig = {
|
|
171
|
+
history: [],
|
|
172
|
+
urls: {
|
|
173
|
+
frontend: DEFAULT_FRONTEND_URL,
|
|
174
|
+
api: DEFAULT_API_URL
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
await writeFile(CONFIG_FILE, JSON.stringify(defaultConfig, null, 2));
|
|
171
178
|
}
|
|
172
179
|
}
|
|
173
180
|
async function readConfig() {
|
|
174
181
|
await ensureConfig();
|
|
175
182
|
try {
|
|
176
|
-
const data = await
|
|
177
|
-
|
|
183
|
+
const data = await readFile(CONFIG_FILE, "utf8");
|
|
184
|
+
const config = JSON.parse(data);
|
|
185
|
+
if (!config.urls) {
|
|
186
|
+
config.urls = {
|
|
187
|
+
frontend: DEFAULT_FRONTEND_URL,
|
|
188
|
+
api: DEFAULT_API_URL
|
|
189
|
+
};
|
|
190
|
+
await writeConfig(config);
|
|
191
|
+
}
|
|
192
|
+
return config;
|
|
178
193
|
} catch (error) {
|
|
179
194
|
console.error("Failed to read config:", error.message);
|
|
180
|
-
return {
|
|
195
|
+
return {
|
|
196
|
+
history: [],
|
|
197
|
+
urls: {
|
|
198
|
+
frontend: DEFAULT_FRONTEND_URL,
|
|
199
|
+
api: DEFAULT_API_URL
|
|
200
|
+
}
|
|
201
|
+
};
|
|
181
202
|
}
|
|
182
203
|
}
|
|
183
204
|
async function writeConfig(config) {
|
|
184
205
|
await ensureConfig();
|
|
185
|
-
await
|
|
206
|
+
await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
186
207
|
}
|
|
187
208
|
async function addToHistory(filePath) {
|
|
188
209
|
const config = await readConfig();
|
|
@@ -208,10 +229,190 @@ async function getDefaultUrl() {
|
|
|
208
229
|
const config = await readConfig();
|
|
209
230
|
return config.defaultUrl;
|
|
210
231
|
}
|
|
211
|
-
|
|
232
|
+
async function getFrontendUrl() {
|
|
233
|
+
if (process.env.ENACT_FRONTEND_URL) {
|
|
234
|
+
return process.env.ENACT_FRONTEND_URL;
|
|
235
|
+
}
|
|
236
|
+
const config = await readConfig();
|
|
237
|
+
if (config.urls?.frontend) {
|
|
238
|
+
return config.urls.frontend;
|
|
239
|
+
}
|
|
240
|
+
return DEFAULT_FRONTEND_URL;
|
|
241
|
+
}
|
|
242
|
+
async function getApiUrl() {
|
|
243
|
+
if (process.env.ENACT_API_URL) {
|
|
244
|
+
return process.env.ENACT_API_URL;
|
|
245
|
+
}
|
|
246
|
+
const config = await readConfig();
|
|
247
|
+
if (config.urls?.api) {
|
|
248
|
+
return config.urls.api;
|
|
249
|
+
}
|
|
250
|
+
return DEFAULT_API_URL;
|
|
251
|
+
}
|
|
252
|
+
async function setFrontendUrl(url) {
|
|
253
|
+
const config = await readConfig();
|
|
254
|
+
if (!config.urls) {
|
|
255
|
+
config.urls = {};
|
|
256
|
+
}
|
|
257
|
+
config.urls.frontend = url;
|
|
258
|
+
await writeConfig(config);
|
|
259
|
+
}
|
|
260
|
+
async function setApiUrl(url) {
|
|
261
|
+
const config = await readConfig();
|
|
262
|
+
if (!config.urls) {
|
|
263
|
+
config.urls = {};
|
|
264
|
+
}
|
|
265
|
+
config.urls.api = url;
|
|
266
|
+
await writeConfig(config);
|
|
267
|
+
}
|
|
268
|
+
async function resetUrls() {
|
|
269
|
+
const config = await readConfig();
|
|
270
|
+
if (config.urls) {
|
|
271
|
+
delete config.urls.frontend;
|
|
272
|
+
delete config.urls.api;
|
|
273
|
+
}
|
|
274
|
+
await writeConfig(config);
|
|
275
|
+
}
|
|
276
|
+
async function getUrlConfig() {
|
|
277
|
+
const config = await readConfig();
|
|
278
|
+
let frontendValue = DEFAULT_FRONTEND_URL;
|
|
279
|
+
let frontendSource = "default";
|
|
280
|
+
if (config.urls?.frontend) {
|
|
281
|
+
frontendValue = config.urls.frontend;
|
|
282
|
+
frontendSource = "config";
|
|
283
|
+
}
|
|
284
|
+
if (process.env.ENACT_FRONTEND_URL) {
|
|
285
|
+
frontendValue = process.env.ENACT_FRONTEND_URL;
|
|
286
|
+
frontendSource = "environment";
|
|
287
|
+
}
|
|
288
|
+
let apiValue = DEFAULT_API_URL;
|
|
289
|
+
let apiSource = "default";
|
|
290
|
+
if (config.urls?.api) {
|
|
291
|
+
apiValue = config.urls.api;
|
|
292
|
+
apiSource = "config";
|
|
293
|
+
}
|
|
294
|
+
if (process.env.ENACT_API_URL) {
|
|
295
|
+
apiValue = process.env.ENACT_API_URL;
|
|
296
|
+
apiSource = "environment";
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
frontend: { value: frontendValue, source: frontendSource },
|
|
300
|
+
api: { value: apiValue, source: apiSource }
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
async function ensureTrustedKeysDir() {
|
|
304
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
305
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
306
|
+
}
|
|
307
|
+
if (!existsSync(TRUSTED_KEYS_DIR)) {
|
|
308
|
+
await mkdir(TRUSTED_KEYS_DIR, { recursive: true });
|
|
309
|
+
}
|
|
310
|
+
const defaultKeyFile = join(TRUSTED_KEYS_DIR, "enact-protocol-official.pem");
|
|
311
|
+
const defaultMetaFile = join(TRUSTED_KEYS_DIR, "enact-protocol-official.meta");
|
|
312
|
+
if (!existsSync(defaultKeyFile)) {
|
|
313
|
+
await writeFile(defaultKeyFile, DEFAULT_ENACT_PUBLIC_KEY);
|
|
314
|
+
}
|
|
315
|
+
if (!existsSync(defaultMetaFile)) {
|
|
316
|
+
const defaultMeta = {
|
|
317
|
+
name: "Enact Protocol Official",
|
|
318
|
+
description: "Official Enact Protocol signing key for verified tools",
|
|
319
|
+
addedAt: new Date().toISOString(),
|
|
320
|
+
source: "default",
|
|
321
|
+
keyFile: "enact-protocol-official.pem"
|
|
322
|
+
};
|
|
323
|
+
await writeFile(defaultMetaFile, JSON.stringify(defaultMeta, null, 2));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
async function getTrustedKeys() {
|
|
327
|
+
await ensureTrustedKeysDir();
|
|
328
|
+
const keys = [];
|
|
329
|
+
try {
|
|
330
|
+
const { readdir } = await import("fs/promises");
|
|
331
|
+
const files = await readdir(TRUSTED_KEYS_DIR);
|
|
332
|
+
const pemFiles = files.filter((f) => f.endsWith(".pem"));
|
|
333
|
+
for (const pemFile of pemFiles) {
|
|
334
|
+
try {
|
|
335
|
+
const keyId = pemFile.replace(".pem", "");
|
|
336
|
+
const keyPath = join(TRUSTED_KEYS_DIR, pemFile);
|
|
337
|
+
const metaPath = join(TRUSTED_KEYS_DIR, `${keyId}.meta`);
|
|
338
|
+
const publicKey = await readFile(keyPath, "utf8");
|
|
339
|
+
let meta = {
|
|
340
|
+
name: keyId,
|
|
341
|
+
addedAt: new Date().toISOString(),
|
|
342
|
+
source: "user",
|
|
343
|
+
keyFile: pemFile
|
|
344
|
+
};
|
|
345
|
+
if (existsSync(metaPath)) {
|
|
346
|
+
try {
|
|
347
|
+
const metaData = await readFile(metaPath, "utf8");
|
|
348
|
+
meta = { ...meta, ...JSON.parse(metaData) };
|
|
349
|
+
} catch {}
|
|
350
|
+
}
|
|
351
|
+
keys.push({
|
|
352
|
+
id: keyId,
|
|
353
|
+
name: meta.name,
|
|
354
|
+
publicKey: publicKey.trim(),
|
|
355
|
+
description: meta.description,
|
|
356
|
+
addedAt: meta.addedAt,
|
|
357
|
+
source: meta.source,
|
|
358
|
+
keyFile: pemFile
|
|
359
|
+
});
|
|
360
|
+
} catch (error) {
|
|
361
|
+
console.warn(`Warning: Could not read key file ${pemFile}:`, error);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
} catch (error) {
|
|
365
|
+
console.error("Failed to read trusted keys directory:", error);
|
|
366
|
+
}
|
|
367
|
+
return keys;
|
|
368
|
+
}
|
|
369
|
+
async function addTrustedKey(keyData) {
|
|
370
|
+
await ensureTrustedKeysDir();
|
|
371
|
+
const keyFile = `${keyData.id}.pem`;
|
|
372
|
+
const metaFile = `${keyData.id}.meta`;
|
|
373
|
+
const keyPath = join(TRUSTED_KEYS_DIR, keyFile);
|
|
374
|
+
const metaPath = join(TRUSTED_KEYS_DIR, metaFile);
|
|
375
|
+
if (existsSync(keyPath)) {
|
|
376
|
+
throw new Error(`Key with ID '${keyData.id}' already exists`);
|
|
377
|
+
}
|
|
378
|
+
await writeFile(keyPath, keyData.publicKey);
|
|
379
|
+
const meta = {
|
|
380
|
+
name: keyData.name,
|
|
381
|
+
description: keyData.description,
|
|
382
|
+
addedAt: new Date().toISOString(),
|
|
383
|
+
source: keyData.source || "user",
|
|
384
|
+
keyFile
|
|
385
|
+
};
|
|
386
|
+
await writeFile(metaPath, JSON.stringify(meta, null, 2));
|
|
387
|
+
}
|
|
388
|
+
async function removeTrustedKey(keyId) {
|
|
389
|
+
const keyPath = join(TRUSTED_KEYS_DIR, `${keyId}.pem`);
|
|
390
|
+
const metaPath = join(TRUSTED_KEYS_DIR, `${keyId}.meta`);
|
|
391
|
+
if (!existsSync(keyPath)) {
|
|
392
|
+
throw new Error(`Trusted key '${keyId}' not found`);
|
|
393
|
+
}
|
|
394
|
+
const { unlink } = await import("fs/promises");
|
|
395
|
+
await unlink(keyPath);
|
|
396
|
+
if (existsSync(metaPath)) {
|
|
397
|
+
await unlink(metaPath);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
async function getTrustedKey(keyId) {
|
|
401
|
+
const keys = await getTrustedKeys();
|
|
402
|
+
return keys.find((k3) => k3.id === keyId) || null;
|
|
403
|
+
}
|
|
404
|
+
async function isKeyTrusted(publicKey) {
|
|
405
|
+
const keys = await getTrustedKeys();
|
|
406
|
+
return keys.some((k3) => k3.publicKey.trim() === publicKey.trim());
|
|
407
|
+
}
|
|
408
|
+
var CONFIG_DIR, CONFIG_FILE, TRUSTED_KEYS_DIR, DEFAULT_FRONTEND_URL = "https://enact.tools", DEFAULT_API_URL = "https://xjnhhxwxovjifdxdwzih.supabase.co", DEFAULT_ENACT_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
409
|
+
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8VyE3jGm5yT2mKnPx1dQF7q8Z2Kv
|
|
410
|
+
7mX9YnE2mK8vF3tY9pL6xH2dF8sK3mN7wQ5vT2gR8sL4xN6pM9uE3wF2Qw==
|
|
411
|
+
-----END PUBLIC KEY-----`;
|
|
212
412
|
var init_config = __esm(() => {
|
|
213
|
-
|
|
214
|
-
CONFIG_FILE =
|
|
413
|
+
CONFIG_DIR = join(homedir(), ".enact");
|
|
414
|
+
CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
415
|
+
TRUSTED_KEYS_DIR = join(CONFIG_DIR, "trusted-keys");
|
|
215
416
|
});
|
|
216
417
|
|
|
217
418
|
// ../../node_modules/dotenv/package.json
|
|
@@ -289,7 +490,7 @@ var require_main = __commonJS((exports, module) => {
|
|
|
289
490
|
var packageJson = require_package();
|
|
290
491
|
var version = packageJson.version;
|
|
291
492
|
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
292
|
-
function
|
|
493
|
+
function parse(src) {
|
|
293
494
|
const obj = {};
|
|
294
495
|
let lines = src.toString();
|
|
295
496
|
lines = lines.replace(/\r\n?/mg, `
|
|
@@ -557,7 +758,7 @@ var require_main = __commonJS((exports, module) => {
|
|
|
557
758
|
_parseVault,
|
|
558
759
|
config,
|
|
559
760
|
decrypt,
|
|
560
|
-
parse
|
|
761
|
+
parse,
|
|
561
762
|
populate
|
|
562
763
|
};
|
|
563
764
|
exports.configDotenv = DotenvModule.configDotenv;
|
|
@@ -571,10 +772,10 @@ var require_main = __commonJS((exports, module) => {
|
|
|
571
772
|
});
|
|
572
773
|
|
|
573
774
|
// ../shared/dist/utils/env-loader.js
|
|
574
|
-
import { join as
|
|
575
|
-
import { homedir as
|
|
576
|
-
import { existsSync as
|
|
577
|
-
import { readFile as
|
|
775
|
+
import { join as join2 } from "path";
|
|
776
|
+
import { homedir as homedir2 } from "os";
|
|
777
|
+
import { existsSync as existsSync2 } from "fs";
|
|
778
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
578
779
|
function extractPackageNamespace(toolName) {
|
|
579
780
|
const parts = toolName.split("/");
|
|
580
781
|
if (parts.length < 2) {
|
|
@@ -586,7 +787,7 @@ function extractPackageNamespace(toolName) {
|
|
|
586
787
|
return parts[0];
|
|
587
788
|
}
|
|
588
789
|
function getPackageEnvPath(packageNamespace) {
|
|
589
|
-
return
|
|
790
|
+
return join2(CONFIG_DIR2, "env", packageNamespace, ".env");
|
|
590
791
|
}
|
|
591
792
|
function decryptValue(encryptedValue) {
|
|
592
793
|
try {
|
|
@@ -597,11 +798,11 @@ function decryptValue(encryptedValue) {
|
|
|
597
798
|
}
|
|
598
799
|
async function readPackageEnvConfig(packageNamespace) {
|
|
599
800
|
const envFile = getPackageEnvPath(packageNamespace);
|
|
600
|
-
if (!
|
|
801
|
+
if (!existsSync2(envFile)) {
|
|
601
802
|
return { variables: {} };
|
|
602
803
|
}
|
|
603
804
|
try {
|
|
604
|
-
const data = await
|
|
805
|
+
const data = await readFile2(envFile, "utf8");
|
|
605
806
|
if (data.trim().startsWith("{")) {
|
|
606
807
|
return JSON.parse(data);
|
|
607
808
|
} else {
|
|
@@ -630,7 +831,7 @@ function loadPackageEnvFile(toolName) {
|
|
|
630
831
|
try {
|
|
631
832
|
const packageNamespace = extractPackageNamespace(toolName);
|
|
632
833
|
const packageEnvPath = getPackageEnvPath(packageNamespace);
|
|
633
|
-
if (!
|
|
834
|
+
if (!existsSync2(packageEnvPath)) {
|
|
634
835
|
return {};
|
|
635
836
|
}
|
|
636
837
|
const result = import_dotenv.config({ path: packageEnvPath });
|
|
@@ -741,10 +942,10 @@ function generateConfigLink(missingVars, toolName) {
|
|
|
741
942
|
const encodedPackage = encodeURIComponent(packageNamespace);
|
|
742
943
|
return `${webUrl}/?vars=${encodedVars}&package=${encodedPackage}`;
|
|
743
944
|
}
|
|
744
|
-
var import_dotenv,
|
|
945
|
+
var import_dotenv, CONFIG_DIR2;
|
|
745
946
|
var init_env_loader = __esm(() => {
|
|
746
947
|
import_dotenv = __toESM(require_main(), 1);
|
|
747
|
-
|
|
948
|
+
CONFIG_DIR2 = join2(homedir2(), ".enact");
|
|
748
949
|
import_dotenv.config();
|
|
749
950
|
});
|
|
750
951
|
|
|
@@ -820,10 +1021,10 @@ var require_picocolors2 = __commonJS((exports, module) => {
|
|
|
820
1021
|
|
|
821
1022
|
// ../shared/dist/utils/help.js
|
|
822
1023
|
import { readFileSync } from "fs";
|
|
823
|
-
import { join as
|
|
1024
|
+
import { join as join3 } from "path";
|
|
824
1025
|
function getVersion() {
|
|
825
1026
|
try {
|
|
826
|
-
const packageJsonPath =
|
|
1027
|
+
const packageJsonPath = join3(__dirname, "../../package.json");
|
|
827
1028
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
828
1029
|
return packageJson.version || "0.1.0";
|
|
829
1030
|
} catch (error) {
|
|
@@ -833,47 +1034,47 @@ function getVersion() {
|
|
|
833
1034
|
function showHelp() {
|
|
834
1035
|
const version = getVersion();
|
|
835
1036
|
console.error(`
|
|
836
|
-
${
|
|
837
|
-
${
|
|
838
|
-
|
|
839
|
-
${
|
|
840
|
-
${
|
|
841
|
-
|
|
842
|
-
${
|
|
843
|
-
${
|
|
844
|
-
${
|
|
845
|
-
${
|
|
846
|
-
${
|
|
847
|
-
${
|
|
848
|
-
${
|
|
849
|
-
${
|
|
850
|
-
${
|
|
851
|
-
${
|
|
852
|
-
${
|
|
853
|
-
|
|
854
|
-
${
|
|
855
|
-
${
|
|
856
|
-
${
|
|
857
|
-
|
|
858
|
-
${
|
|
859
|
-
${
|
|
860
|
-
${
|
|
861
|
-
${
|
|
862
|
-
${
|
|
863
|
-
${
|
|
864
|
-
${
|
|
865
|
-
${
|
|
866
|
-
${
|
|
867
|
-
${
|
|
868
|
-
${
|
|
869
|
-
|
|
870
|
-
${
|
|
871
|
-
${
|
|
1037
|
+
${import_picocolors3.default.bold("Enact CLI")} ${import_picocolors3.default.dim(`v${version}`)}
|
|
1038
|
+
${import_picocolors3.default.dim("A CLI tool for managing and publishing Enact tools")}
|
|
1039
|
+
|
|
1040
|
+
${import_picocolors3.default.bold("Usage:")}
|
|
1041
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("<command>")} [options]
|
|
1042
|
+
|
|
1043
|
+
${import_picocolors3.default.bold("Commands:")}
|
|
1044
|
+
${import_picocolors3.default.green("auth")} Manage authentication (login, logout, status, token)
|
|
1045
|
+
${import_picocolors3.default.green("env")} Manage environment variables (set, get, list, delete)
|
|
1046
|
+
${import_picocolors3.default.green("exec")} Execute a tool by fetching and running it
|
|
1047
|
+
${import_picocolors3.default.green("init")} Create a new tool definition
|
|
1048
|
+
${import_picocolors3.default.green("mcp")} MCP client integration (install, list, status)
|
|
1049
|
+
${import_picocolors3.default.green("publish")} Publish a tool to the registry
|
|
1050
|
+
${import_picocolors3.default.green("search")} Search for tools in the registry
|
|
1051
|
+
${import_picocolors3.default.green("sign")} Sign and verify tools with cryptographic signatures
|
|
1052
|
+
${import_picocolors3.default.green("remote")} Manage remote servers (add, list, remove)
|
|
1053
|
+
${import_picocolors3.default.green("user")} User operations (get public key)
|
|
1054
|
+
|
|
1055
|
+
${import_picocolors3.default.bold("Global Options:")}
|
|
1056
|
+
${import_picocolors3.default.yellow("--help, -h")} Show help message
|
|
1057
|
+
${import_picocolors3.default.yellow("--version, -v")} Show version information
|
|
1058
|
+
|
|
1059
|
+
${import_picocolors3.default.bold("Examples:")}
|
|
1060
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.dim("# Interactive mode")}
|
|
1061
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("search")} ${import_picocolors3.default.yellow("--tags")} web,api ${import_picocolors3.default.dim("# Search tools by tags")}
|
|
1062
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("exec")} enact/text/slugify ${import_picocolors3.default.dim("# Execute a tool")}
|
|
1063
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("mcp")} install ${import_picocolors3.default.yellow("--client")} claude-desktop ${import_picocolors3.default.dim("# Install MCP server")}
|
|
1064
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("mcp")} install ${import_picocolors3.default.yellow("--client")} goose ${import_picocolors3.default.dim("# Install for Goose AI")}
|
|
1065
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("env")} set API_KEY --encrypt ${import_picocolors3.default.dim("# Set encrypted env var")}
|
|
1066
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("sign")} verify my-tool.yaml ${import_picocolors3.default.dim("# Verify tool signatures")}
|
|
1067
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("publish")} my-tool.yaml ${import_picocolors3.default.dim("# Publish a tool")}
|
|
1068
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("auth")} login ${import_picocolors3.default.dim("# Login with OAuth")}
|
|
1069
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("init")} ${import_picocolors3.default.yellow("--minimal")} ${import_picocolors3.default.dim("# Create minimal tool template")}
|
|
1070
|
+
|
|
1071
|
+
${import_picocolors3.default.bold("More Help:")}
|
|
1072
|
+
${import_picocolors3.default.cyan("enact")} ${import_picocolors3.default.green("<command>")} ${import_picocolors3.default.yellow("--help")} ${import_picocolors3.default.dim("# Show command-specific help")}
|
|
872
1073
|
`);
|
|
873
1074
|
}
|
|
874
|
-
var
|
|
1075
|
+
var import_picocolors3, __dirname = "/Users/keithgroves/projects/enact/enact-cli/packages/shared/dist/utils";
|
|
875
1076
|
var init_help = __esm(() => {
|
|
876
|
-
|
|
1077
|
+
import_picocolors3 = __toESM(require_picocolors2(), 1);
|
|
877
1078
|
});
|
|
878
1079
|
|
|
879
1080
|
// ../shared/dist/utils/logger.js
|
|
@@ -882,29 +1083,29 @@ function setLogLevel(level) {
|
|
|
882
1083
|
}
|
|
883
1084
|
function debug(message) {
|
|
884
1085
|
if (currentLogLevel <= LogLevel.DEBUG) {
|
|
885
|
-
console.error(
|
|
1086
|
+
console.error(import_picocolors4.default.dim(`\uD83D\uDD0D ${message}`));
|
|
886
1087
|
}
|
|
887
1088
|
}
|
|
888
1089
|
function info(message) {
|
|
889
1090
|
if (currentLogLevel <= LogLevel.INFO) {
|
|
890
|
-
console.error(
|
|
1091
|
+
console.error(import_picocolors4.default.blue(`ℹ️ ${message}`));
|
|
891
1092
|
}
|
|
892
1093
|
}
|
|
893
1094
|
function success(message) {
|
|
894
1095
|
if (currentLogLevel <= LogLevel.SUCCESS) {
|
|
895
|
-
console.error(
|
|
1096
|
+
console.error(import_picocolors4.default.green(`✓ ${message}`));
|
|
896
1097
|
}
|
|
897
1098
|
}
|
|
898
1099
|
function warn(message) {
|
|
899
1100
|
if (currentLogLevel <= LogLevel.WARN) {
|
|
900
|
-
console.error(
|
|
1101
|
+
console.error(import_picocolors4.default.yellow(`⚠️ ${message}`));
|
|
901
1102
|
}
|
|
902
1103
|
}
|
|
903
1104
|
function error(message, details) {
|
|
904
1105
|
if (currentLogLevel <= LogLevel.ERROR) {
|
|
905
|
-
console.error(
|
|
1106
|
+
console.error(import_picocolors4.default.red(`✗ Error: ${message}`));
|
|
906
1107
|
if (details && currentLogLevel === LogLevel.DEBUG) {
|
|
907
|
-
console.error(
|
|
1108
|
+
console.error(import_picocolors4.default.dim("Details:"));
|
|
908
1109
|
console.error(details);
|
|
909
1110
|
}
|
|
910
1111
|
}
|
|
@@ -918,9 +1119,9 @@ function table(data, columns) {
|
|
|
918
1119
|
}
|
|
919
1120
|
}
|
|
920
1121
|
}
|
|
921
|
-
var
|
|
1122
|
+
var import_picocolors4, LogLevel, currentLogLevel;
|
|
922
1123
|
var init_logger = __esm(() => {
|
|
923
|
-
|
|
1124
|
+
import_picocolors4 = __toESM(require_picocolors2(), 1);
|
|
924
1125
|
(function(LogLevel2) {
|
|
925
1126
|
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
926
1127
|
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
@@ -1156,7 +1357,7 @@ function parseTimeout(timeout) {
|
|
|
1156
1357
|
|
|
1157
1358
|
// ../shared/dist/utils/version.js
|
|
1158
1359
|
import { readFileSync as readFileSync2 } from "fs";
|
|
1159
|
-
import { join as
|
|
1360
|
+
import { join as join4, dirname } from "path";
|
|
1160
1361
|
import { fileURLToPath } from "url";
|
|
1161
1362
|
function showVersion() {
|
|
1162
1363
|
let version = "0.0.1-dev";
|
|
@@ -1166,7 +1367,7 @@ function showVersion() {
|
|
|
1166
1367
|
} else {
|
|
1167
1368
|
const currentFile = typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url);
|
|
1168
1369
|
const sharedDir = dirname(dirname(dirname(currentFile)));
|
|
1169
|
-
const packageJsonPath =
|
|
1370
|
+
const packageJsonPath = join4(sharedDir, "package.json");
|
|
1170
1371
|
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
1171
1372
|
version = packageJson.version;
|
|
1172
1373
|
}
|
|
@@ -1175,13 +1376,13 @@ function showVersion() {
|
|
|
1175
1376
|
}
|
|
1176
1377
|
const versionText = `v${version}`;
|
|
1177
1378
|
console.error(`
|
|
1178
|
-
${
|
|
1179
|
-
${
|
|
1379
|
+
${import_picocolors5.default.bold("Enact CLI")} ${import_picocolors5.default.cyan(versionText)}
|
|
1380
|
+
${import_picocolors5.default.dim("A tool to create and publish enact documents.")}
|
|
1180
1381
|
`);
|
|
1181
1382
|
}
|
|
1182
|
-
var
|
|
1383
|
+
var import_picocolors5, __filename = "/Users/keithgroves/projects/enact/enact-cli/packages/shared/dist/utils/version.js";
|
|
1183
1384
|
var init_version = __esm(() => {
|
|
1184
|
-
|
|
1385
|
+
import_picocolors5 = __toESM(require_picocolors2(), 1);
|
|
1185
1386
|
});
|
|
1186
1387
|
|
|
1187
1388
|
// ../shared/dist/utils/index.js
|
|
@@ -1198,23 +1399,34 @@ __export(exports_utils, {
|
|
|
1198
1399
|
showVersion: () => showVersion,
|
|
1199
1400
|
showHelp: () => showHelp,
|
|
1200
1401
|
setLogLevel: () => setLogLevel,
|
|
1402
|
+
setFrontendUrl: () => setFrontendUrl,
|
|
1201
1403
|
setDefaultUrl: () => setDefaultUrl,
|
|
1404
|
+
setApiUrl: () => setApiUrl,
|
|
1202
1405
|
resolveToolEnvironmentVariables: () => resolveToolEnvironmentVariables,
|
|
1406
|
+
resetUrls: () => resetUrls,
|
|
1407
|
+
removeTrustedKey: () => removeTrustedKey,
|
|
1203
1408
|
readConfig: () => readConfig,
|
|
1204
1409
|
parseTimeout: () => parseTimeout,
|
|
1205
1410
|
loadPackageEnvironmentVariables: () => loadPackageEnvironmentVariables,
|
|
1411
|
+
isKeyTrusted: () => isKeyTrusted,
|
|
1206
1412
|
info: () => info,
|
|
1207
1413
|
globalMonitor: () => globalMonitor,
|
|
1208
1414
|
getWebServerUrl: () => getWebServerUrl,
|
|
1415
|
+
getUrlConfig: () => getUrlConfig,
|
|
1416
|
+
getTrustedKeys: () => getTrustedKeys,
|
|
1417
|
+
getTrustedKey: () => getTrustedKey,
|
|
1209
1418
|
getPackageEnvironmentVariables: () => getPackageEnvironmentVariables,
|
|
1210
1419
|
getHistory: () => getHistory,
|
|
1420
|
+
getFrontendUrl: () => getFrontendUrl,
|
|
1211
1421
|
getDefaultUrl: () => getDefaultUrl,
|
|
1422
|
+
getApiUrl: () => getApiUrl,
|
|
1212
1423
|
generateConfigLink: () => generateConfigLink,
|
|
1213
1424
|
extractPackageNamespace: () => extractPackageNamespace,
|
|
1214
1425
|
error: () => error,
|
|
1215
1426
|
ensureSilent: () => ensureSilent,
|
|
1216
1427
|
ensureConfig: () => ensureConfig,
|
|
1217
1428
|
debug: () => debug,
|
|
1429
|
+
addTrustedKey: () => addTrustedKey,
|
|
1218
1430
|
addToHistory: () => addToHistory,
|
|
1219
1431
|
McpSilentOperationMonitor: () => McpSilentOperationMonitor,
|
|
1220
1432
|
LogLevel: () => LogLevel
|
|
@@ -214303,11 +214515,11 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
214303
214515
|
};
|
|
214304
214516
|
|
|
214305
214517
|
// src/commands/auth.ts
|
|
214306
|
-
var
|
|
214307
|
-
import { existsSync } from "fs";
|
|
214308
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
214309
|
-
import { join } from "path";
|
|
214310
|
-
import { homedir } from "os";
|
|
214518
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
214519
|
+
import { existsSync as existsSync3 } from "fs";
|
|
214520
|
+
import { readFile as readFile3, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
214521
|
+
import { join as join5 } from "path";
|
|
214522
|
+
import { homedir as homedir3 } from "os";
|
|
214311
214523
|
import { createServer } from "http";
|
|
214312
214524
|
import { parse } from "url";
|
|
214313
214525
|
import { randomBytes, createHash } from "crypto";
|
|
@@ -214315,11 +214527,18 @@ import { exec } from "child_process";
|
|
|
214315
214527
|
import { promisify } from "util";
|
|
214316
214528
|
|
|
214317
214529
|
// ../shared/dist/api/enact-api.js
|
|
214530
|
+
init_config();
|
|
214531
|
+
|
|
214318
214532
|
class EnactApiClient {
|
|
214319
|
-
constructor(baseUrl
|
|
214533
|
+
constructor(baseUrl, supabaseUrl) {
|
|
214320
214534
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
214321
214535
|
this.supabaseUrl = supabaseUrl.replace(/\/$/, "");
|
|
214322
214536
|
}
|
|
214537
|
+
static async create(baseUrl, supabaseUrl) {
|
|
214538
|
+
const frontendUrl = baseUrl || await getFrontendUrl();
|
|
214539
|
+
const apiUrl = supabaseUrl || await getApiUrl();
|
|
214540
|
+
return new EnactApiClient(frontendUrl, apiUrl);
|
|
214541
|
+
}
|
|
214323
214542
|
async makeRequest(endpoint, options = {}, token, tokenType = "jwt") {
|
|
214324
214543
|
const url = endpoint.startsWith("http") ? endpoint : `${this.supabaseUrl}${endpoint}`;
|
|
214325
214544
|
const headers = {
|
|
@@ -214601,7 +214820,7 @@ class EnactApiClient {
|
|
|
214601
214820
|
};
|
|
214602
214821
|
}
|
|
214603
214822
|
}
|
|
214604
|
-
var enactApi = new EnactApiClient;
|
|
214823
|
+
var enactApi = new EnactApiClient("https://enact.tools", "https://xjnhhxwxovjifdxdwzih.supabase.co");
|
|
214605
214824
|
|
|
214606
214825
|
class EnactApiError extends Error {
|
|
214607
214826
|
constructor(message, statusCode, endpoint) {
|
|
@@ -214612,14 +214831,17 @@ class EnactApiError extends Error {
|
|
|
214612
214831
|
}
|
|
214613
214832
|
}
|
|
214614
214833
|
function createEnactApiClient(baseUrl, supabaseUrl) {
|
|
214615
|
-
|
|
214834
|
+
const defaultFrontend = "https://enact.tools";
|
|
214835
|
+
const defaultApi = "https://xjnhhxwxovjifdxdwzih.supabase.co";
|
|
214836
|
+
return new EnactApiClient(baseUrl || defaultFrontend, supabaseUrl || defaultApi);
|
|
214616
214837
|
}
|
|
214617
214838
|
// src/commands/auth.ts
|
|
214839
|
+
init_utils();
|
|
214618
214840
|
var execAsync = promisify(exec);
|
|
214619
|
-
var
|
|
214620
|
-
var AUTH_FILE =
|
|
214621
|
-
var DEFAULT_SERVER = "https://enact.tools";
|
|
214841
|
+
var CONFIG_DIR3 = join5(homedir3(), ".enact");
|
|
214842
|
+
var AUTH_FILE = join5(CONFIG_DIR3, "auth.json");
|
|
214622
214843
|
async function handleAuthCommand(args, options) {
|
|
214844
|
+
const defaultServer = await getFrontendUrl();
|
|
214623
214845
|
if (options.help || !args[0]) {
|
|
214624
214846
|
console.error(`
|
|
214625
214847
|
Usage: enact auth <subcommand> [options]
|
|
@@ -214634,16 +214856,16 @@ Subcommands:
|
|
|
214634
214856
|
|
|
214635
214857
|
Options:
|
|
214636
214858
|
--help, -h Show this help message
|
|
214637
|
-
--server <url> Specify the enact server URL (default: ${
|
|
214859
|
+
--server <url> Specify the enact server URL (default: ${defaultServer})
|
|
214638
214860
|
--port <number> Local callback port for OAuth (default: 8080)
|
|
214639
214861
|
`);
|
|
214640
214862
|
return;
|
|
214641
214863
|
}
|
|
214642
214864
|
const subCommand = args[0];
|
|
214643
|
-
const serverUrl = options.server ||
|
|
214865
|
+
const serverUrl = options.server || defaultServer;
|
|
214644
214866
|
const callbackPort = options.port || 8080;
|
|
214645
214867
|
await ensureAuthConfig();
|
|
214646
|
-
Ie(
|
|
214868
|
+
Ie(import_picocolors6.default.bgBlue(import_picocolors6.default.white(" Enact Authentication ")));
|
|
214647
214869
|
switch (subCommand) {
|
|
214648
214870
|
case "login": {
|
|
214649
214871
|
await handleLogin(serverUrl, callbackPort);
|
|
@@ -214662,7 +214884,7 @@ Options:
|
|
|
214662
214884
|
break;
|
|
214663
214885
|
}
|
|
214664
214886
|
default:
|
|
214665
|
-
Se(
|
|
214887
|
+
Se(import_picocolors6.default.red(`✗ Unknown auth subcommand "${subCommand}"`));
|
|
214666
214888
|
return;
|
|
214667
214889
|
}
|
|
214668
214890
|
}
|
|
@@ -214674,7 +214896,7 @@ async function handleLogin(serverUrl, callbackPort) {
|
|
|
214674
214896
|
message: "You are already authenticated. Continue with new login?"
|
|
214675
214897
|
});
|
|
214676
214898
|
if (!useExisting) {
|
|
214677
|
-
Se(
|
|
214899
|
+
Se(import_picocolors6.default.yellow("Login cancelled"));
|
|
214678
214900
|
return;
|
|
214679
214901
|
}
|
|
214680
214902
|
}
|
|
@@ -214696,14 +214918,14 @@ async function handleLogin(serverUrl, callbackPort) {
|
|
|
214696
214918
|
try {
|
|
214697
214919
|
server2 = await startCallbackServerWithFallback(callbackPort, serverUrl, codeVerifier, state);
|
|
214698
214920
|
s.stop("OAuth server started");
|
|
214699
|
-
} catch (
|
|
214921
|
+
} catch (error2) {
|
|
214700
214922
|
s.stop("OAuth server could not start, using manual mode");
|
|
214701
214923
|
server2 = null;
|
|
214702
214924
|
}
|
|
214703
214925
|
Me(`Opening browser to: ${authUrl}`, "OAuth Login");
|
|
214704
214926
|
try {
|
|
214705
214927
|
await openBrowser(authUrl);
|
|
214706
|
-
} catch (
|
|
214928
|
+
} catch (error2) {
|
|
214707
214929
|
Me(`Please open this URL in your browser: ${authUrl}`, "Manual Browser Open Required");
|
|
214708
214930
|
}
|
|
214709
214931
|
if (server2) {
|
|
@@ -214730,14 +214952,14 @@ async function handleLogin(serverUrl, callbackPort) {
|
|
|
214730
214952
|
}
|
|
214731
214953
|
});
|
|
214732
214954
|
if (typeof authCode === "symbol") {
|
|
214733
|
-
Se(
|
|
214955
|
+
Se(import_picocolors6.default.yellow("Login cancelled"));
|
|
214734
214956
|
return;
|
|
214735
214957
|
}
|
|
214736
214958
|
await exchangeCodeForToken(authCode, redirectUri, codeVerifier, serverUrl);
|
|
214737
214959
|
}
|
|
214738
|
-
Se(
|
|
214739
|
-
} catch (
|
|
214740
|
-
Se(
|
|
214960
|
+
Se(import_picocolors6.default.green("✓ Successfully authenticated with Enact!"));
|
|
214961
|
+
} catch (error2) {
|
|
214962
|
+
Se(import_picocolors6.default.red(`✗ Login failed: ${error2.message}`));
|
|
214741
214963
|
} finally {
|
|
214742
214964
|
process.exit(0);
|
|
214743
214965
|
}
|
|
@@ -214751,13 +214973,13 @@ async function startCallbackServerWithFallback(port, serverUrl, codeVerifier, st
|
|
|
214751
214973
|
const {
|
|
214752
214974
|
code,
|
|
214753
214975
|
state: returnedState,
|
|
214754
|
-
error,
|
|
214976
|
+
error: error2,
|
|
214755
214977
|
error_description
|
|
214756
214978
|
} = parsedUrl.query;
|
|
214757
214979
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
214758
214980
|
res.setHeader("Content-Type", "text/html");
|
|
214759
|
-
if (
|
|
214760
|
-
const errorMsg = error_description ||
|
|
214981
|
+
if (error2) {
|
|
214982
|
+
const errorMsg = error_description || error2;
|
|
214761
214983
|
res.writeHead(400);
|
|
214762
214984
|
res.end(`
|
|
214763
214985
|
<html>
|
|
@@ -214816,19 +215038,19 @@ async function startCallbackServerWithFallback(port, serverUrl, codeVerifier, st
|
|
|
214816
215038
|
`);
|
|
214817
215039
|
server2.close();
|
|
214818
215040
|
server2.emit("authComplete");
|
|
214819
|
-
} catch (
|
|
214820
|
-
console.error("Token exchange error:",
|
|
215041
|
+
} catch (error3) {
|
|
215042
|
+
console.error("Token exchange error:", error3);
|
|
214821
215043
|
res.writeHead(500);
|
|
214822
215044
|
res.end(`
|
|
214823
215045
|
<html>
|
|
214824
215046
|
<body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
|
|
214825
215047
|
<h1 style="color: red;">❌ Authentication Failed</h1>
|
|
214826
|
-
<p><strong>Error:</strong> ${
|
|
215048
|
+
<p><strong>Error:</strong> ${error3.message}</p>
|
|
214827
215049
|
<p>You can close this window and check your terminal for more details.</p>
|
|
214828
215050
|
</body>
|
|
214829
215051
|
</html>
|
|
214830
215052
|
`);
|
|
214831
|
-
server2.emit("authError",
|
|
215053
|
+
server2.emit("authError", error3);
|
|
214832
215054
|
}
|
|
214833
215055
|
} else {
|
|
214834
215056
|
res.writeHead(404);
|
|
@@ -214847,11 +215069,11 @@ async function startCallbackServerWithFallback(port, serverUrl, codeVerifier, st
|
|
|
214847
215069
|
console.error(`OAuth callback server listening on http://localhost:${port}`);
|
|
214848
215070
|
resolve(server2);
|
|
214849
215071
|
});
|
|
214850
|
-
server2.on("error", (
|
|
214851
|
-
if (
|
|
215072
|
+
server2.on("error", (error2) => {
|
|
215073
|
+
if (error2.code === "EADDRINUSE") {
|
|
214852
215074
|
reject(new Error(`Port ${port} is already in use`));
|
|
214853
215075
|
} else {
|
|
214854
|
-
reject(
|
|
215076
|
+
reject(error2);
|
|
214855
215077
|
}
|
|
214856
215078
|
});
|
|
214857
215079
|
});
|
|
@@ -214880,11 +215102,11 @@ async function exchangeCodeForToken(code, redirectUri, codeVerifier, serverUrl)
|
|
|
214880
215102
|
server: serverUrl
|
|
214881
215103
|
});
|
|
214882
215104
|
console.error("✓ Token stored successfully");
|
|
214883
|
-
} catch (
|
|
214884
|
-
if (
|
|
214885
|
-
throw new Error(`Token exchange failed: ${
|
|
215105
|
+
} catch (error2) {
|
|
215106
|
+
if (error2 instanceof EnactApiError) {
|
|
215107
|
+
throw new Error(`Token exchange failed: ${error2.message}`);
|
|
214886
215108
|
}
|
|
214887
|
-
throw
|
|
215109
|
+
throw error2;
|
|
214888
215110
|
}
|
|
214889
215111
|
}
|
|
214890
215112
|
async function handleLogout() {
|
|
@@ -214898,45 +215120,45 @@ async function handleLogout() {
|
|
|
214898
215120
|
message: "Are you sure you want to logout?"
|
|
214899
215121
|
});
|
|
214900
215122
|
if (!shouldLogout) {
|
|
214901
|
-
Se(
|
|
215123
|
+
Se(import_picocolors6.default.yellow("Logout cancelled"));
|
|
214902
215124
|
return;
|
|
214903
215125
|
}
|
|
214904
215126
|
const s = Y2();
|
|
214905
215127
|
s.start("Logging out...");
|
|
214906
215128
|
await writeAuthConfig({});
|
|
214907
215129
|
s.stop("Logged out successfully");
|
|
214908
|
-
Se(
|
|
215130
|
+
Se(import_picocolors6.default.green("✓ You have been logged out"));
|
|
214909
215131
|
}
|
|
214910
215132
|
async function handleStatus() {
|
|
214911
215133
|
const currentAuth = await readAuthConfig();
|
|
214912
215134
|
if (!currentAuth.token) {
|
|
214913
215135
|
Me("Not authenticated", "Status");
|
|
214914
|
-
Se(
|
|
215136
|
+
Se(import_picocolors6.default.yellow('Run "enact auth login" to authenticate'));
|
|
214915
215137
|
return;
|
|
214916
215138
|
}
|
|
214917
215139
|
const isExpired = currentAuth.expiresAt && new Date(currentAuth.expiresAt) <= new Date;
|
|
214918
215140
|
if (isExpired) {
|
|
214919
215141
|
Me("Token has expired", "Status");
|
|
214920
|
-
Se(
|
|
215142
|
+
Se(import_picocolors6.default.yellow('Run "enact auth login" to re-authenticate'));
|
|
214921
215143
|
return;
|
|
214922
215144
|
}
|
|
214923
215145
|
const expiresIn = currentAuth.expiresAt ? Math.round((new Date(currentAuth.expiresAt).getTime() - Date.now()) / 1000 / 60 / 60) : "unknown";
|
|
214924
215146
|
Me(`Authenticated
|
|
214925
215147
|
Expires: ${currentAuth.expiresAt || "unknown"}
|
|
214926
215148
|
Expires in: ${expiresIn} hours`, "Status");
|
|
214927
|
-
Se(
|
|
215149
|
+
Se(import_picocolors6.default.green("✓ Authentication valid"));
|
|
214928
215150
|
}
|
|
214929
215151
|
async function handleShowToken() {
|
|
214930
215152
|
const currentAuth = await readAuthConfig();
|
|
214931
215153
|
if (!currentAuth.token) {
|
|
214932
215154
|
Me("Not authenticated", "Status");
|
|
214933
|
-
Se(
|
|
215155
|
+
Se(import_picocolors6.default.yellow('Run "enact auth login" to authenticate'));
|
|
214934
215156
|
return;
|
|
214935
215157
|
}
|
|
214936
215158
|
const isExpired = currentAuth.expiresAt && new Date(currentAuth.expiresAt) <= new Date;
|
|
214937
215159
|
if (isExpired) {
|
|
214938
215160
|
Me("Token has expired", "Status");
|
|
214939
|
-
Se(
|
|
215161
|
+
Se(import_picocolors6.default.yellow('Run "enact auth login" to re-authenticate'));
|
|
214940
215162
|
return;
|
|
214941
215163
|
}
|
|
214942
215164
|
const maskedToken = currentAuth.token.length > 12 ? `${currentAuth.token.slice(0, 8)}...${currentAuth.token.slice(-4)}` : currentAuth.token;
|
|
@@ -214971,23 +215193,23 @@ async function openBrowser(url) {
|
|
|
214971
215193
|
await execAsync(command);
|
|
214972
215194
|
}
|
|
214973
215195
|
async function ensureAuthConfig() {
|
|
214974
|
-
if (!
|
|
214975
|
-
await
|
|
215196
|
+
if (!existsSync3(CONFIG_DIR3)) {
|
|
215197
|
+
await mkdir2(CONFIG_DIR3, { recursive: true });
|
|
214976
215198
|
}
|
|
214977
|
-
if (!
|
|
215199
|
+
if (!existsSync3(AUTH_FILE)) {
|
|
214978
215200
|
await writeAuthConfig({});
|
|
214979
215201
|
}
|
|
214980
215202
|
}
|
|
214981
215203
|
async function readAuthConfig() {
|
|
214982
215204
|
try {
|
|
214983
|
-
const text = await
|
|
215205
|
+
const text = await readFile3(AUTH_FILE, "utf8");
|
|
214984
215206
|
return JSON.parse(text);
|
|
214985
215207
|
} catch (e2) {
|
|
214986
215208
|
return {};
|
|
214987
215209
|
}
|
|
214988
215210
|
}
|
|
214989
|
-
async function writeAuthConfig(
|
|
214990
|
-
await
|
|
215211
|
+
async function writeAuthConfig(config2) {
|
|
215212
|
+
await writeFile2(AUTH_FILE, JSON.stringify(config2, null, 2), "utf8");
|
|
214991
215213
|
}
|
|
214992
215214
|
async function getCurrentToken() {
|
|
214993
215215
|
try {
|
|
@@ -214999,7 +215221,7 @@ async function getCurrentToken() {
|
|
|
214999
215221
|
return null;
|
|
215000
215222
|
}
|
|
215001
215223
|
return auth.token;
|
|
215002
|
-
} catch (
|
|
215224
|
+
} catch (error2) {
|
|
215003
215225
|
return null;
|
|
215004
215226
|
}
|
|
215005
215227
|
}
|
|
@@ -216537,6 +216759,7 @@ async function checkMcpServerInstalled(client, serverType = "main") {
|
|
|
216537
216759
|
|
|
216538
216760
|
// src/commands/config.ts
|
|
216539
216761
|
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
216762
|
+
init_utils();
|
|
216540
216763
|
import fs from "fs/promises";
|
|
216541
216764
|
import path from "path";
|
|
216542
216765
|
import { existsSync as existsSync8 } from "fs";
|
|
@@ -216724,6 +216947,13 @@ function showConfigHelp() {
|
|
|
216724
216947
|
console.log(" get <key> Get specific configuration value");
|
|
216725
216948
|
console.log(" set <key> <value> Set configuration value");
|
|
216726
216949
|
console.log(" reset Reset to default configuration");
|
|
216950
|
+
console.log(" urls Show current URL configuration");
|
|
216951
|
+
console.log(" set-frontend-url Set frontend URL (for OAuth, registry)");
|
|
216952
|
+
console.log(" set-api-url Set API URL (for backend calls)");
|
|
216953
|
+
console.log(" reset-urls Reset URLs to defaults");
|
|
216954
|
+
console.log(" keys Show trusted public keys");
|
|
216955
|
+
console.log(" add-key Add a trusted public key");
|
|
216956
|
+
console.log(" remove-key <id> Remove a trusted public key");
|
|
216727
216957
|
console.log(`
|
|
216728
216958
|
Options:`);
|
|
216729
216959
|
console.log(" --global Use global configuration (~/.enact-config.json)");
|
|
@@ -216744,6 +216974,160 @@ Examples:`);
|
|
|
216744
216974
|
console.log(" enact config set daggerOptions.baseImage ubuntu:22.04");
|
|
216745
216975
|
console.log(" enact config get executionProvider");
|
|
216746
216976
|
console.log(" enact config list --global");
|
|
216977
|
+
console.log(" enact config urls");
|
|
216978
|
+
console.log(" enact config set-frontend-url https://my-instance.example.com");
|
|
216979
|
+
console.log(" enact config set-api-url https://api.example.com");
|
|
216980
|
+
console.log(" enact config keys");
|
|
216981
|
+
console.log(" enact config add-key");
|
|
216982
|
+
console.log(" enact config remove-key my-org-key");
|
|
216983
|
+
}
|
|
216984
|
+
async function showUrls() {
|
|
216985
|
+
const urlConfig = await getUrlConfig();
|
|
216986
|
+
console.log(import_picocolors12.default.cyan(`
|
|
216987
|
+
\uD83C\uDF10 URL Configuration:
|
|
216988
|
+
`));
|
|
216989
|
+
console.log(import_picocolors12.default.white("Frontend URL:"));
|
|
216990
|
+
console.log(` ${import_picocolors12.default.green(urlConfig.frontend.value)} ${import_picocolors12.default.gray(`(${urlConfig.frontend.source})`)}`);
|
|
216991
|
+
console.log(import_picocolors12.default.white("API URL:"));
|
|
216992
|
+
console.log(` ${import_picocolors12.default.green(urlConfig.api.value)} ${import_picocolors12.default.gray(`(${urlConfig.api.source})`)}`);
|
|
216993
|
+
console.log(import_picocolors12.default.gray(`
|
|
216994
|
+
Sources: default < config < environment`));
|
|
216995
|
+
}
|
|
216996
|
+
async function setUrl(type, url) {
|
|
216997
|
+
try {
|
|
216998
|
+
if (type === "frontend") {
|
|
216999
|
+
await setFrontendUrl(url);
|
|
217000
|
+
console.log(import_picocolors12.default.green(`✅ Frontend URL set to: ${url}`));
|
|
217001
|
+
} else {
|
|
217002
|
+
await setApiUrl(url);
|
|
217003
|
+
console.log(import_picocolors12.default.green(`✅ API URL set to: ${url}`));
|
|
217004
|
+
}
|
|
217005
|
+
console.log(import_picocolors12.default.gray("Use 'enact config urls' to view current configuration"));
|
|
217006
|
+
} catch (error2) {
|
|
217007
|
+
console.error(import_picocolors12.default.red(`Error setting ${type} URL: ${error2}`));
|
|
217008
|
+
process.exit(1);
|
|
217009
|
+
}
|
|
217010
|
+
}
|
|
217011
|
+
async function resetUrlsConfig() {
|
|
217012
|
+
try {
|
|
217013
|
+
await resetUrls();
|
|
217014
|
+
console.log(import_picocolors12.default.green("✅ URLs reset to defaults"));
|
|
217015
|
+
await showUrls();
|
|
217016
|
+
} catch (error2) {
|
|
217017
|
+
console.error(import_picocolors12.default.red(`Error resetting URLs: ${error2}`));
|
|
217018
|
+
process.exit(1);
|
|
217019
|
+
}
|
|
217020
|
+
}
|
|
217021
|
+
async function showTrustedKeys() {
|
|
217022
|
+
try {
|
|
217023
|
+
const keys = await getTrustedKeys();
|
|
217024
|
+
console.log(import_picocolors12.default.cyan(`
|
|
217025
|
+
\uD83D\uDD10 Trusted Keys:
|
|
217026
|
+
`));
|
|
217027
|
+
if (keys.length === 0) {
|
|
217028
|
+
console.log(import_picocolors12.default.gray("No trusted keys found"));
|
|
217029
|
+
return;
|
|
217030
|
+
}
|
|
217031
|
+
for (const key of keys) {
|
|
217032
|
+
const sourceColor = key.source === "default" ? import_picocolors12.default.blue : key.source === "organization" ? import_picocolors12.default.yellow : import_picocolors12.default.green;
|
|
217033
|
+
console.log(import_picocolors12.default.white(`${key.name} (${key.id})`));
|
|
217034
|
+
console.log(` ${sourceColor(`[${key.source}]`)} ${import_picocolors12.default.gray(`Added: ${new Date(key.addedAt).toLocaleDateString()}`)}`);
|
|
217035
|
+
if (key.description) {
|
|
217036
|
+
console.log(` ${import_picocolors12.default.gray(key.description)}`);
|
|
217037
|
+
}
|
|
217038
|
+
console.log(` ${import_picocolors12.default.gray(`Key: ${key.publicKey.substring(0, 50)}...`)}`);
|
|
217039
|
+
console.log();
|
|
217040
|
+
}
|
|
217041
|
+
} catch (error2) {
|
|
217042
|
+
console.error(import_picocolors12.default.red(`Error reading trusted keys: ${error2}`));
|
|
217043
|
+
process.exit(1);
|
|
217044
|
+
}
|
|
217045
|
+
}
|
|
217046
|
+
async function addTrustedKeyInteractive() {
|
|
217047
|
+
try {
|
|
217048
|
+
console.log(import_picocolors12.default.cyan(`
|
|
217049
|
+
\uD83D\uDD10 Add Trusted Key
|
|
217050
|
+
`));
|
|
217051
|
+
const id = await he({
|
|
217052
|
+
message: "Key ID (unique identifier):",
|
|
217053
|
+
placeholder: "my-org-key",
|
|
217054
|
+
validate: (value) => {
|
|
217055
|
+
if (!value)
|
|
217056
|
+
return "ID is required";
|
|
217057
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(value))
|
|
217058
|
+
return "ID must contain only letters, numbers, hyphens, and underscores";
|
|
217059
|
+
}
|
|
217060
|
+
});
|
|
217061
|
+
const name = await he({
|
|
217062
|
+
message: "Key name (display name):",
|
|
217063
|
+
placeholder: "My Organization Key",
|
|
217064
|
+
validate: (value) => value ? undefined : "Name is required"
|
|
217065
|
+
});
|
|
217066
|
+
const description = await he({
|
|
217067
|
+
message: "Description (optional):",
|
|
217068
|
+
placeholder: "Key for verifying my organization's tools"
|
|
217069
|
+
});
|
|
217070
|
+
const publicKey = await he({
|
|
217071
|
+
message: "Public key (PEM format):",
|
|
217072
|
+
placeholder: "-----BEGIN PUBLIC KEY-----\\n...\\n-----END PUBLIC KEY-----",
|
|
217073
|
+
validate: (value) => {
|
|
217074
|
+
if (!value)
|
|
217075
|
+
return "Public key is required";
|
|
217076
|
+
if (!value.includes("BEGIN PUBLIC KEY"))
|
|
217077
|
+
return "Invalid PEM format";
|
|
217078
|
+
}
|
|
217079
|
+
});
|
|
217080
|
+
const source = await ve({
|
|
217081
|
+
message: "Key source:",
|
|
217082
|
+
options: [
|
|
217083
|
+
{ value: "user", label: "Personal key" },
|
|
217084
|
+
{ value: "organization", label: "Organization key" }
|
|
217085
|
+
]
|
|
217086
|
+
});
|
|
217087
|
+
const keyData = {
|
|
217088
|
+
id,
|
|
217089
|
+
name,
|
|
217090
|
+
publicKey: publicKey.replace(/\\n/g, `
|
|
217091
|
+
`),
|
|
217092
|
+
description: description || undefined,
|
|
217093
|
+
source
|
|
217094
|
+
};
|
|
217095
|
+
await addTrustedKey(keyData);
|
|
217096
|
+
console.log(import_picocolors12.default.green(`✅ Trusted key '${keyData.name}' added successfully`));
|
|
217097
|
+
} catch (error2) {
|
|
217098
|
+
console.error(import_picocolors12.default.red(`Error adding trusted key: ${error2}`));
|
|
217099
|
+
process.exit(1);
|
|
217100
|
+
}
|
|
217101
|
+
}
|
|
217102
|
+
async function removeTrustedKeyById(keyId) {
|
|
217103
|
+
try {
|
|
217104
|
+
const key = await getTrustedKey(keyId);
|
|
217105
|
+
if (!key) {
|
|
217106
|
+
console.error(import_picocolors12.default.red(`Trusted key '${keyId}' not found`));
|
|
217107
|
+
process.exit(1);
|
|
217108
|
+
}
|
|
217109
|
+
let confirmMessage = `Remove trusted key '${key.name}' (${keyId})?`;
|
|
217110
|
+
if (keyId === "enact-protocol-official") {
|
|
217111
|
+
confirmMessage = `${import_picocolors12.default.yellow("⚠️ Warning:")} You are about to remove the default Enact Protocol key. This may prevent verification of official tools.
|
|
217112
|
+
|
|
217113
|
+
Remove trusted key '${key.name}' (${keyId})?`;
|
|
217114
|
+
}
|
|
217115
|
+
const confirm = await ye({
|
|
217116
|
+
message: confirmMessage
|
|
217117
|
+
});
|
|
217118
|
+
if (!confirm) {
|
|
217119
|
+
console.log(import_picocolors12.default.yellow("Operation cancelled"));
|
|
217120
|
+
return;
|
|
217121
|
+
}
|
|
217122
|
+
await removeTrustedKey(keyId);
|
|
217123
|
+
console.log(import_picocolors12.default.green(`✅ Trusted key '${key.name}' removed successfully`));
|
|
217124
|
+
if (keyId === "enact-protocol-official") {
|
|
217125
|
+
console.log(import_picocolors12.default.yellow("\uD83D\uDCA1 You can re-add the Enact Protocol key anytime with 'enact config add-key'"));
|
|
217126
|
+
}
|
|
217127
|
+
} catch (error2) {
|
|
217128
|
+
console.error(import_picocolors12.default.red(`Error removing trusted key: ${error2}`));
|
|
217129
|
+
process.exit(1);
|
|
217130
|
+
}
|
|
216747
217131
|
}
|
|
216748
217132
|
async function handleConfigCommand(args, options) {
|
|
216749
217133
|
if (options.help) {
|
|
@@ -216778,6 +217162,42 @@ async function handleConfigCommand(args, options) {
|
|
|
216778
217162
|
case "reset":
|
|
216779
217163
|
await resetConfig(global2);
|
|
216780
217164
|
break;
|
|
217165
|
+
case "urls":
|
|
217166
|
+
await showUrls();
|
|
217167
|
+
break;
|
|
217168
|
+
case "set-frontend-url":
|
|
217169
|
+
if (!args[1]) {
|
|
217170
|
+
console.error(import_picocolors12.default.red("Error: Missing URL"));
|
|
217171
|
+
console.log("Usage: enact config set-frontend-url <url>");
|
|
217172
|
+
process.exit(1);
|
|
217173
|
+
}
|
|
217174
|
+
await setUrl("frontend", args[1]);
|
|
217175
|
+
break;
|
|
217176
|
+
case "set-api-url":
|
|
217177
|
+
if (!args[1]) {
|
|
217178
|
+
console.error(import_picocolors12.default.red("Error: Missing URL"));
|
|
217179
|
+
console.log("Usage: enact config set-api-url <url>");
|
|
217180
|
+
process.exit(1);
|
|
217181
|
+
}
|
|
217182
|
+
await setUrl("api", args[1]);
|
|
217183
|
+
break;
|
|
217184
|
+
case "reset-urls":
|
|
217185
|
+
await resetUrlsConfig();
|
|
217186
|
+
break;
|
|
217187
|
+
case "keys":
|
|
217188
|
+
await showTrustedKeys();
|
|
217189
|
+
break;
|
|
217190
|
+
case "add-key":
|
|
217191
|
+
await addTrustedKeyInteractive();
|
|
217192
|
+
break;
|
|
217193
|
+
case "remove-key":
|
|
217194
|
+
if (!args[1]) {
|
|
217195
|
+
console.error(import_picocolors12.default.red("Error: Missing key ID"));
|
|
217196
|
+
console.log("Usage: enact config remove-key <key-id>");
|
|
217197
|
+
process.exit(1);
|
|
217198
|
+
}
|
|
217199
|
+
await removeTrustedKeyById(args[1]);
|
|
217200
|
+
break;
|
|
216781
217201
|
default:
|
|
216782
217202
|
if (!subcommand) {
|
|
216783
217203
|
await interactiveConfig(global2);
|
|
@@ -226299,37 +226719,6 @@ class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
226299
226719
|
process.exit(1);
|
|
226300
226720
|
}
|
|
226301
226721
|
}
|
|
226302
|
-
forceCleanup() {
|
|
226303
|
-
if (this.isShuttingDown)
|
|
226304
|
-
return;
|
|
226305
|
-
try {
|
|
226306
|
-
logger_default.info("\uD83D\uDD04 Force cleaning up Dagger engines...");
|
|
226307
|
-
const result = spawnSync("docker", [
|
|
226308
|
-
"ps",
|
|
226309
|
-
"--all",
|
|
226310
|
-
"--filter",
|
|
226311
|
-
"name=dagger-engine",
|
|
226312
|
-
"--format",
|
|
226313
|
-
"{{.Names}}"
|
|
226314
|
-
], {
|
|
226315
|
-
encoding: "utf8",
|
|
226316
|
-
timeout: 5000
|
|
226317
|
-
});
|
|
226318
|
-
if (result.stdout) {
|
|
226319
|
-
const names = result.stdout.trim().split(`
|
|
226320
|
-
`).filter((n) => n.trim());
|
|
226321
|
-
if (names.length > 0) {
|
|
226322
|
-
logger_default.info(`Found ${names.length} engine containers, force removing...`);
|
|
226323
|
-
for (const name of names) {
|
|
226324
|
-
spawnSync("docker", ["rm", "-f", name.trim()], { timeout: 3000 });
|
|
226325
|
-
}
|
|
226326
|
-
logger_default.info("✅ Force cleanup completed");
|
|
226327
|
-
}
|
|
226328
|
-
}
|
|
226329
|
-
} catch (error2) {
|
|
226330
|
-
logger_default.debug("Force cleanup failed (this is usually fine):", error2);
|
|
226331
|
-
}
|
|
226332
|
-
}
|
|
226333
226722
|
getEngineStatus() {
|
|
226334
226723
|
return {
|
|
226335
226724
|
health: { ...this.engineHealth },
|
|
@@ -229063,6 +229452,8 @@ class SigningService {
|
|
|
229063
229452
|
}
|
|
229064
229453
|
|
|
229065
229454
|
// ../shared/dist/core/EnactCore.js
|
|
229455
|
+
init_config();
|
|
229456
|
+
|
|
229066
229457
|
class EnactCore {
|
|
229067
229458
|
constructor(options = {}) {
|
|
229068
229459
|
this.options = {
|
|
@@ -229075,6 +229466,15 @@ class EnactCore {
|
|
|
229075
229466
|
this.apiClient = new EnactApiClient(this.options.apiUrl, this.options.supabaseUrl);
|
|
229076
229467
|
this.executionProvider = this.createExecutionProvider();
|
|
229077
229468
|
}
|
|
229469
|
+
static async create(options = {}) {
|
|
229470
|
+
const frontendUrl = options.apiUrl || await getFrontendUrl();
|
|
229471
|
+
const apiUrl = options.supabaseUrl || await getApiUrl();
|
|
229472
|
+
return new EnactCore({
|
|
229473
|
+
...options,
|
|
229474
|
+
apiUrl: frontendUrl,
|
|
229475
|
+
supabaseUrl: apiUrl
|
|
229476
|
+
});
|
|
229477
|
+
}
|
|
229078
229478
|
setAuthToken(token) {
|
|
229079
229479
|
this.options.authToken = token;
|
|
229080
229480
|
}
|
|
@@ -229628,7 +230028,7 @@ ${import_picocolors13.default.bold("EXAMPLES:")}
|
|
|
229628
230028
|
author,
|
|
229629
230029
|
format
|
|
229630
230030
|
};
|
|
229631
|
-
const apiClient =
|
|
230031
|
+
const apiClient = await EnactApiClient.create();
|
|
229632
230032
|
const searchResults = await apiClient.searchTools(searchOptions);
|
|
229633
230033
|
const results = [];
|
|
229634
230034
|
for (const result of searchResults) {
|
|
@@ -229886,7 +230286,7 @@ Examples:
|
|
|
229886
230286
|
toolDefinition = await loadLocalTool(toolIdentifier);
|
|
229887
230287
|
spinner.stop("Local tool definition loaded");
|
|
229888
230288
|
} else {
|
|
229889
|
-
const apiClient =
|
|
230289
|
+
const apiClient = await EnactApiClient.create();
|
|
229890
230290
|
toolDefinition = await apiClient.getTool(toolIdentifier);
|
|
229891
230291
|
spinner.stop("Tool definition fetched");
|
|
229892
230292
|
}
|
|
@@ -230114,7 +230514,7 @@ Environment variables:`));
|
|
|
230114
230514
|
}
|
|
230115
230515
|
if (!isLocalFile) {
|
|
230116
230516
|
try {
|
|
230117
|
-
const apiClient =
|
|
230517
|
+
const apiClient = await EnactApiClient.create();
|
|
230118
230518
|
await apiClient.logToolUsage(toolIdentifier, {
|
|
230119
230519
|
action: "execute",
|
|
230120
230520
|
metadata: {
|
|
@@ -230217,7 +230617,7 @@ ${import_picocolors13.default.bold("EXAMPLES:")}
|
|
|
230217
230617
|
Ie(import_picocolors13.default.bgBlue(import_picocolors13.default.black(" Getting Tool Info ")));
|
|
230218
230618
|
const spinner = Y2();
|
|
230219
230619
|
spinner.start(`Fetching ${toolName}...`);
|
|
230220
|
-
const apiClient =
|
|
230620
|
+
const apiClient = await EnactApiClient.create();
|
|
230221
230621
|
const toolDefinition = await apiClient.getTool(toolName);
|
|
230222
230622
|
if (!toolDefinition) {
|
|
230223
230623
|
spinner.stop("Tool not found");
|