@enactprotocol/shared 1.2.2 → 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.
@@ -2,7 +2,11 @@ import { EnactToolDefinition, ToolUsage, ToolSearchQuery, CLITokenCreate, OAuthT
2
2
  export declare class EnactApiClient {
3
3
  baseUrl: string;
4
4
  supabaseUrl: string;
5
- constructor(baseUrl?: string, supabaseUrl?: string);
5
+ constructor(baseUrl: string, supabaseUrl: string);
6
+ /**
7
+ * Create API client with config-based URLs
8
+ */
9
+ static create(baseUrl?: string, supabaseUrl?: string): Promise<EnactApiClient>;
6
10
  private makeRequest;
7
11
  /**
8
12
  * Get all tools (public, no auth required)
@@ -115,6 +119,7 @@ export declare class EnactApiClient {
115
119
  errors: string[];
116
120
  };
117
121
  }
122
+ export declare function createDefaultApiClient(): Promise<EnactApiClient>;
118
123
  export declare const enactApi: EnactApiClient;
119
124
  export declare class EnactApiError extends Error {
120
125
  statusCode?: number | undefined;
@@ -1,8 +1,17 @@
1
+ import { getFrontendUrl, getApiUrl } from "../utils/config";
1
2
  export class EnactApiClient {
2
- constructor(baseUrl = "https://enact.tools", supabaseUrl = "https://xjnhhxwxovjifdxdwzih.supabase.co") {
3
+ constructor(baseUrl, supabaseUrl) {
3
4
  this.baseUrl = baseUrl.replace(/\/$/, ""); // Remove trailing slash
4
5
  this.supabaseUrl = supabaseUrl.replace(/\/$/, "");
5
6
  }
7
+ /**
8
+ * Create API client with config-based URLs
9
+ */
10
+ static async create(baseUrl, supabaseUrl) {
11
+ const frontendUrl = baseUrl || await getFrontendUrl();
12
+ const apiUrl = supabaseUrl || await getApiUrl();
13
+ return new EnactApiClient(frontendUrl, apiUrl);
14
+ }
6
15
  // Helper method to make authenticated requests
7
16
  async makeRequest(endpoint, options = {}, token, tokenType = "jwt") {
8
17
  const url = endpoint.startsWith("http")
@@ -389,8 +398,12 @@ export class EnactApiClient {
389
398
  };
390
399
  }
391
400
  }
392
- // Export a default instance
393
- export const enactApi = new EnactApiClient();
401
+ // Export a default instance factory
402
+ export async function createDefaultApiClient() {
403
+ return await EnactApiClient.create();
404
+ }
405
+ // Keep backward compatibility with sync usage
406
+ export const enactApi = new EnactApiClient("https://enact.tools", "https://xjnhhxwxovjifdxdwzih.supabase.co");
394
407
  // Export error types for better error handling
395
408
  export class EnactApiError extends Error {
396
409
  constructor(message, statusCode, endpoint) {
@@ -402,5 +415,7 @@ export class EnactApiError extends Error {
402
415
  }
403
416
  // Helper function to create API client with custom configuration
404
417
  export function createEnactApiClient(baseUrl, supabaseUrl) {
405
- return new EnactApiClient(baseUrl, supabaseUrl);
418
+ const defaultFrontend = "https://enact.tools";
419
+ const defaultApi = "https://xjnhhxwxovjifdxdwzih.supabase.co";
420
+ return new EnactApiClient(baseUrl || defaultFrontend, supabaseUrl || defaultApi);
406
421
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Shared constants for Enact CLI
3
+ */
4
+ export declare const DEFAULT_FRONTEND_URL = "https://enact.tools";
5
+ export declare const DEFAULT_API_URL = "https://xjnhhxwxovjifdxdwzih.supabase.co";
6
+ export declare const ENV_FRONTEND_URL = "ENACT_FRONTEND_URL";
7
+ export declare const ENV_API_URL = "ENACT_API_URL";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared constants for Enact CLI
3
+ */
4
+ // Frontend URL - used for OAuth redirects, registry browsing, documentation links
5
+ export const DEFAULT_FRONTEND_URL = "https://enact.tools";
6
+ // Backend API URL - used for all API calls (search, publish, etc.)
7
+ export const DEFAULT_API_URL = "https://xjnhhxwxovjifdxdwzih.supabase.co";
8
+ // Environment variable names for overriding defaults
9
+ export const ENV_FRONTEND_URL = "ENACT_FRONTEND_URL";
10
+ export const ENV_API_URL = "ENACT_API_URL";
@@ -145,10 +145,6 @@ export declare class DaggerExecutionProvider extends ExecutionProvider {
145
145
  * Graceful shutdown with proper async cleanup
146
146
  */
147
147
  private gracefulShutdown;
148
- /**
149
- * Enhanced force cleanup for synchronous exit handlers
150
- */
151
- private forceCleanup;
152
148
  /**
153
149
  * Get current engine status for debugging
154
150
  */
@@ -935,43 +935,6 @@ export class DaggerExecutionProvider extends ExecutionProvider {
935
935
  process.exit(1);
936
936
  }
937
937
  }
938
- /**
939
- * Enhanced force cleanup for synchronous exit handlers
940
- */
941
- forceCleanup() {
942
- if (this.isShuttingDown)
943
- return;
944
- try {
945
- logger.info("🔄 Force cleaning up Dagger engines...");
946
- const result = spawnSync("docker", [
947
- "ps",
948
- "--all",
949
- "--filter",
950
- "name=dagger-engine",
951
- "--format",
952
- "{{.Names}}",
953
- ], {
954
- encoding: "utf8",
955
- timeout: 5000,
956
- });
957
- if (result.stdout) {
958
- const names = result.stdout
959
- .trim()
960
- .split("\n")
961
- .filter((n) => n.trim());
962
- if (names.length > 0) {
963
- logger.info(`Found ${names.length} engine containers, force removing...`);
964
- for (const name of names) {
965
- spawnSync("docker", ["rm", "-f", name.trim()], { timeout: 3000 });
966
- }
967
- logger.info("✅ Force cleanup completed");
968
- }
969
- }
970
- }
971
- catch (error) {
972
- logger.debug("Force cleanup failed (this is usually fine):", error);
973
- }
974
- }
975
938
  /**
976
939
  * Get current engine status for debugging
977
940
  */
@@ -34,6 +34,10 @@ export declare class EnactCore {
34
34
  private executionProvider;
35
35
  private options;
36
36
  constructor(options?: EnactCoreOptions);
37
+ /**
38
+ * Create EnactCore with config-based URLs
39
+ */
40
+ static create(options?: EnactCoreOptions): Promise<EnactCore>;
37
41
  /**
38
42
  * Set authentication token for API operations
39
43
  */
@@ -5,12 +5,13 @@ import { DaggerExecutionProvider } from "./DaggerExecutionProvider.js";
5
5
  import { resolveToolEnvironmentVariables } from "../utils/env-loader.js";
6
6
  import logger from "../exec/logger.js";
7
7
  import yaml from "yaml";
8
- import { CryptoUtils, KeyManager, SecurityConfigManager, SigningService } from "@enactprotocol/security";
8
+ import { CryptoUtils, SecurityConfigManager, SigningService } from "@enactprotocol/security";
9
+ import { getFrontendUrl, getApiUrl } from "../utils/config";
9
10
  export class EnactCore {
10
11
  constructor(options = {}) {
11
12
  this.options = {
12
- apiUrl: "https://enact.tools",
13
- supabaseUrl: "https://xjnhhxwxovjifdxdwzih.supabase.co",
13
+ apiUrl: "https://enact.tools", // Default, will be overridden by factory
14
+ supabaseUrl: "https://xjnhhxwxovjifdxdwzih.supabase.co", // Default, will be overridden by factory
14
15
  executionProvider: "dagger",
15
16
  defaultTimeout: "30s",
16
17
  ...options,
@@ -19,6 +20,18 @@ export class EnactCore {
19
20
  // Initialize the appropriate execution provider
20
21
  this.executionProvider = this.createExecutionProvider();
21
22
  }
23
+ /**
24
+ * Create EnactCore with config-based URLs
25
+ */
26
+ static async create(options = {}) {
27
+ const frontendUrl = options.apiUrl || await getFrontendUrl();
28
+ const apiUrl = options.supabaseUrl || await getApiUrl();
29
+ return new EnactCore({
30
+ ...options,
31
+ apiUrl: frontendUrl,
32
+ supabaseUrl: apiUrl,
33
+ });
34
+ }
22
35
  /**
23
36
  * Set authentication token for API operations
24
37
  */
@@ -266,7 +279,6 @@ export class EnactCore {
266
279
  }
267
280
  }
268
281
  async verifyTool(tool, dangerouslySkipVerification = false) {
269
- console.log("=== VERIFY TOOL CALLED ===", tool.name, "skipVerification:", dangerouslySkipVerification);
270
282
  if (dangerouslySkipVerification) {
271
283
  logger.warn(`Skipping signature verification for tool: ${tool.name}`);
272
284
  return;
@@ -275,9 +287,6 @@ export class EnactCore {
275
287
  if (!tool.signatures || tool.signatures.length === 0) {
276
288
  throw new Error(`Tool ${tool.name} does not have any signatures`);
277
289
  }
278
- console.log("=== TOOL SIGNATURE DATA ===");
279
- console.log("Tool signatures from database:", JSON.stringify(tool.signatures, null, 2));
280
- console.log("Tool command:", tool.command);
281
290
  const documentForVerification = {
282
291
  command: tool.command
283
292
  };
@@ -289,22 +298,12 @@ export class EnactCore {
289
298
  };
290
299
  // Check what canonical document looks like
291
300
  const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification, { includeFields: ['command'] });
292
- console.log("=== SIGNATURE VERIFICATION DEBUG ===");
293
- console.log("Original document for verification:", JSON.stringify(documentForVerification, null, 2));
294
- console.log("Canonical document:", JSON.stringify(canonicalDoc, null, 2));
295
301
  const docString = JSON.stringify(canonicalDoc);
296
302
  const messageHash = CryptoUtils.hash(docString);
297
- console.log("Document string:", docString);
298
- console.log("Message hash:", messageHash);
299
- console.log("Reference signature object:", JSON.stringify(referenceSignature, null, 2));
300
303
  // Test direct crypto verification
301
304
  const directVerify = CryptoUtils.verify(referenceSignature.publicKey, messageHash, referenceSignature.signature);
302
- console.log("KEITH DEBUG - Direct crypto verification result:", directVerify, "publicKey:", referenceSignature.publicKey);
303
305
  // Check trusted keys
304
- const trustedKeys = KeyManager.getAllTrustedPublicKeys();
305
- console.log("Trusted keys:", trustedKeys);
306
- console.log("Our referenceSignature.publicKey:", JSON.stringify(referenceSignature.publicKey));
307
- console.log("Is our public key trusted?", trustedKeys.includes(referenceSignature.publicKey));
306
+ // const trustedKeys = KeyManager.getAllTrustedPublicKeys();
308
307
  const isValid = SigningService.verifyDocument(documentForVerification, referenceSignature, { includeFields: ['command'] });
309
308
  console.log("Final verification result:", isValid);
310
309
  if (!isValid) {
@@ -14,6 +14,15 @@ export declare class EnactDirect {
14
14
  authToken?: string;
15
15
  defaultTimeout?: string;
16
16
  });
17
+ /**
18
+ * Create EnactDirect with config-based URLs
19
+ */
20
+ static create(options?: {
21
+ apiUrl?: string;
22
+ supabaseUrl?: string;
23
+ authToken?: string;
24
+ defaultTimeout?: string;
25
+ }): Promise<EnactDirect>;
17
26
  /**
18
27
  * Execute a tool by name with inputs
19
28
  *
@@ -1,5 +1,6 @@
1
1
  // src/lib/enact-direct.ts - Library interface for direct usage by MCP servers
2
2
  import { EnactCore, } from "../core/EnactCore";
3
+ import { getFrontendUrl, getApiUrl } from "../utils/config";
3
4
  /**
4
5
  * Direct Enact Library Interface
5
6
  *
@@ -8,16 +9,27 @@ import { EnactCore, } from "../core/EnactCore";
8
9
  */
9
10
  export class EnactDirect {
10
11
  constructor(options = {}) {
12
+ // We need to handle async config loading in a factory method
11
13
  this.core = new EnactCore({
12
- apiUrl: options.apiUrl || process.env.ENACT_API_URL || "https://enact.tools",
13
- supabaseUrl: options.supabaseUrl ||
14
- process.env.ENACT_SUPABASE_URL ||
15
- "https://xjnhhxwxovjifdxdwzih.supabase.co",
14
+ apiUrl: options.apiUrl || process.env.ENACT_FRONTEND_URL || "https://enact.tools",
15
+ supabaseUrl: options.supabaseUrl || process.env.ENACT_API_URL || "https://xjnhhxwxovjifdxdwzih.supabase.co",
16
16
  executionProvider: "direct",
17
17
  authToken: options.authToken || process.env.ENACT_AUTH_TOKEN,
18
18
  defaultTimeout: options.defaultTimeout || "30s",
19
19
  });
20
20
  }
21
+ /**
22
+ * Create EnactDirect with config-based URLs
23
+ */
24
+ static async create(options = {}) {
25
+ const frontendUrl = options.apiUrl || process.env.ENACT_FRONTEND_URL || await getFrontendUrl();
26
+ const apiUrl = options.supabaseUrl || process.env.ENACT_API_URL || await getApiUrl();
27
+ return new EnactDirect({
28
+ ...options,
29
+ apiUrl: frontendUrl,
30
+ supabaseUrl: apiUrl,
31
+ });
32
+ }
21
33
  /**
22
34
  * Execute a tool by name with inputs
23
35
  *
@@ -6,6 +6,14 @@ export declare class McpCoreService {
6
6
  supabaseUrl?: string;
7
7
  authToken?: string;
8
8
  });
9
+ /**
10
+ * Create McpCoreService with config-based URLs
11
+ */
12
+ static create(options?: {
13
+ apiUrl?: string;
14
+ supabaseUrl?: string;
15
+ authToken?: string;
16
+ }): Promise<McpCoreService>;
9
17
  /**
10
18
  * Set authentication token
11
19
  */
@@ -1,5 +1,6 @@
1
1
  // src/services/McpCoreService.ts - Direct core integration for MCP server
2
2
  import { EnactCore } from "../core/EnactCore";
3
+ import { getFrontendUrl, getApiUrl } from "../utils/config";
3
4
  export class McpCoreService {
4
5
  constructor(options) {
5
6
  this.core = new EnactCore({
@@ -8,6 +9,18 @@ export class McpCoreService {
8
9
  authToken: options?.authToken,
9
10
  });
10
11
  }
12
+ /**
13
+ * Create McpCoreService with config-based URLs
14
+ */
15
+ static async create(options) {
16
+ const frontendUrl = options?.apiUrl || await getFrontendUrl();
17
+ const apiUrl = options?.supabaseUrl || await getApiUrl();
18
+ return new McpCoreService({
19
+ ...options,
20
+ apiUrl: frontendUrl,
21
+ supabaseUrl: apiUrl,
22
+ });
23
+ }
11
24
  /**
12
25
  * Set authentication token
13
26
  */
@@ -1,6 +1,10 @@
1
1
  export interface EnactConfig {
2
2
  defaultUrl?: string;
3
3
  history?: string[];
4
+ urls?: {
5
+ frontend?: string;
6
+ api?: string;
7
+ };
4
8
  }
5
9
  /**
6
10
  * Ensure config directory and file exist
@@ -30,3 +34,78 @@ export declare function setDefaultUrl(url: string): Promise<void>;
30
34
  * Get the default publish URL
31
35
  */
32
36
  export declare function getDefaultUrl(): Promise<string | undefined>;
37
+ export interface TrustedKeyMeta {
38
+ name: string;
39
+ description?: string;
40
+ addedAt: string;
41
+ source: "default" | "user" | "organization";
42
+ keyFile: string;
43
+ }
44
+ export interface TrustedKey {
45
+ id: string;
46
+ name: string;
47
+ publicKey: string;
48
+ description?: string;
49
+ addedAt: string;
50
+ source: "default" | "user" | "organization";
51
+ keyFile: string;
52
+ }
53
+ /**
54
+ * Get the frontend URL with fallbacks
55
+ */
56
+ export declare function getFrontendUrl(): Promise<string>;
57
+ /**
58
+ * Get the API URL with fallbacks
59
+ */
60
+ export declare function getApiUrl(): Promise<string>;
61
+ /**
62
+ * Set the frontend URL in config
63
+ */
64
+ export declare function setFrontendUrl(url: string): Promise<void>;
65
+ /**
66
+ * Set the API URL in config
67
+ */
68
+ export declare function setApiUrl(url: string): Promise<void>;
69
+ /**
70
+ * Reset URLs to defaults
71
+ */
72
+ export declare function resetUrls(): Promise<void>;
73
+ /**
74
+ * Get current URL configuration
75
+ */
76
+ export declare function getUrlConfig(): Promise<{
77
+ frontend: {
78
+ value: string;
79
+ source: string;
80
+ };
81
+ api: {
82
+ value: string;
83
+ source: string;
84
+ };
85
+ }>;
86
+ /**
87
+ * Read all trusted keys from directory
88
+ */
89
+ export declare function getTrustedKeys(): Promise<TrustedKey[]>;
90
+ /**
91
+ * Add a trusted key
92
+ */
93
+ export declare function addTrustedKey(keyData: {
94
+ id: string;
95
+ name: string;
96
+ publicKey: string;
97
+ description?: string;
98
+ source?: "user" | "organization";
99
+ }): Promise<void>;
100
+ /**
101
+ * Remove a trusted key
102
+ */
103
+ export declare function removeTrustedKey(keyId: string): Promise<void>;
104
+ /**
105
+ * Get a specific trusted key
106
+ */
107
+ export declare function getTrustedKey(keyId: string): Promise<TrustedKey | null>;
108
+ /**
109
+ * Check if a public key is trusted
110
+ */
111
+ export declare function isKeyTrusted(publicKey: string): Promise<boolean>;