@enactprotocol/shared 1.0.14 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/enact-api.js +2 -2
- package/dist/api/types.d.ts +10 -3
- package/dist/core/DaggerExecutionProvider.d.ts +1 -1
- package/dist/core/DaggerExecutionProvider.js +23 -19
- package/dist/core/EnactCore.d.ts +36 -19
- package/dist/core/EnactCore.js +157 -219
- package/dist/core/NativeExecutionProvider.d.ts +9 -0
- package/dist/core/NativeExecutionProvider.js +16 -0
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -4
- package/dist/lib/enact-direct.d.ts +0 -15
- package/dist/lib/enact-direct.js +0 -11
- package/dist/security/sign.d.ts +5 -5
- package/dist/security/sign.js +247 -113
- package/dist/security/verification-enforcer.d.ts +12 -0
- package/dist/security/verification-enforcer.js +26 -3
- package/dist/services/McpCoreService.d.ts +0 -12
- package/dist/services/McpCoreService.js +0 -9
- package/dist/types.d.ts +5 -4
- package/dist/utils/config.js +1 -1
- package/package.json +3 -6
- package/src/api/enact-api.ts +2 -2
- package/src/api/types.ts +11 -4
- package/src/core/DaggerExecutionProvider.ts +26 -13
- package/src/core/EnactCore.ts +226 -270
- package/src/index.ts +0 -5
- package/src/lib/enact-direct.ts +0 -21
- package/src/services/McpCoreService.ts +0 -20
- package/src/types.ts +10 -12
- package/src/utils/config.ts +1 -1
- package/src/security/index.ts +0 -3
- package/src/security/security.ts +0 -188
- package/src/security/sign.ts +0 -797
- package/src/security/verification-enforcer.ts +0 -268
package/dist/core/EnactCore.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { EnactApiClient } from "../api/enact-api.js";
|
|
2
|
-
import {
|
|
3
|
-
import { validateToolStructure, validateInputs, validateOutput, } from "../exec/validate.js";
|
|
2
|
+
import { validateToolStructure, validateInputs, } from "../exec/validate.js";
|
|
4
3
|
import { DirectExecutionProvider } from "./DirectExecutionProvider.js";
|
|
5
4
|
import { DaggerExecutionProvider } from "./DaggerExecutionProvider.js";
|
|
6
5
|
import { resolveToolEnvironmentVariables } from "../utils/env-loader.js";
|
|
7
6
|
import logger from "../exec/logger.js";
|
|
8
7
|
import yaml from "yaml";
|
|
9
|
-
import {
|
|
10
|
-
import { enforceSignatureVerification, createVerificationFailureResult, logSecurityAudit, } from "../security/verification-enforcer.js";
|
|
11
|
-
import fs from "fs";
|
|
12
|
-
import path from "path";
|
|
8
|
+
import { CryptoUtils, KeyManager, SigningService } from "@enactprotocol/security";
|
|
13
9
|
export class EnactCore {
|
|
14
10
|
constructor(options = {}) {
|
|
15
11
|
this.options = {
|
|
@@ -17,7 +13,6 @@ export class EnactCore {
|
|
|
17
13
|
supabaseUrl: "https://xjnhhxwxovjifdxdwzih.supabase.co",
|
|
18
14
|
executionProvider: "dagger",
|
|
19
15
|
defaultTimeout: "30s",
|
|
20
|
-
verificationPolicy: "permissive",
|
|
21
16
|
...options,
|
|
22
17
|
};
|
|
23
18
|
this.apiClient = new EnactApiClient(this.options.apiUrl, this.options.supabaseUrl);
|
|
@@ -31,9 +26,10 @@ export class EnactCore {
|
|
|
31
26
|
this.options.authToken = token;
|
|
32
27
|
}
|
|
33
28
|
/**
|
|
34
|
-
*
|
|
29
|
+
* Static method to search for tools (no execution provider needed)
|
|
35
30
|
*/
|
|
36
|
-
async searchTools(options) {
|
|
31
|
+
static async searchTools(options, coreOptions = {}) {
|
|
32
|
+
const apiClient = new EnactApiClient(coreOptions.apiUrl || "https://enact.tools", coreOptions.supabaseUrl || "https://xjnhhxwxovjifdxdwzih.supabase.co");
|
|
37
33
|
try {
|
|
38
34
|
logger.info(`Searching for tools with query: "${options.query}"`);
|
|
39
35
|
const searchParams = {
|
|
@@ -41,13 +37,13 @@ export class EnactCore {
|
|
|
41
37
|
limit: options.limit,
|
|
42
38
|
tags: options.tags,
|
|
43
39
|
};
|
|
44
|
-
const results = await
|
|
40
|
+
const results = await apiClient.searchTools(searchParams);
|
|
45
41
|
// Parse and validate results
|
|
46
42
|
const tools = [];
|
|
47
43
|
for (const result of results) {
|
|
48
44
|
if (result.name) {
|
|
49
45
|
try {
|
|
50
|
-
const tool = await
|
|
46
|
+
const tool = await EnactCore.getToolByName(result.name, undefined, coreOptions);
|
|
51
47
|
if (tool) {
|
|
52
48
|
tools.push(tool);
|
|
53
49
|
}
|
|
@@ -65,19 +61,26 @@ export class EnactCore {
|
|
|
65
61
|
// If it's a 502 error (API server issue), try fallback to local filtering
|
|
66
62
|
if (error instanceof Error && error.message.includes("502")) {
|
|
67
63
|
logger.info("Search API unavailable, trying fallback to local filtering...");
|
|
68
|
-
return
|
|
64
|
+
return EnactCore.searchToolsFallback(options, coreOptions);
|
|
69
65
|
}
|
|
70
66
|
throw new Error(`Search failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
71
67
|
}
|
|
72
68
|
}
|
|
73
69
|
/**
|
|
74
|
-
*
|
|
70
|
+
* Instance method wrapper for backward compatibility
|
|
71
|
+
*/
|
|
72
|
+
async searchTools(options) {
|
|
73
|
+
return EnactCore.searchTools(options, this.options);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Static fallback search method that gets all tools and filters locally
|
|
75
77
|
*/
|
|
76
|
-
async searchToolsFallback(options) {
|
|
78
|
+
static async searchToolsFallback(options, coreOptions = {}) {
|
|
79
|
+
const apiClient = new EnactApiClient(coreOptions.apiUrl || "https://enact.tools", coreOptions.supabaseUrl || "https://xjnhhxwxovjifdxdwzih.supabase.co");
|
|
77
80
|
try {
|
|
78
81
|
logger.info("Using fallback search method...");
|
|
79
82
|
// Get all tools (limited to avoid overwhelming the API)
|
|
80
|
-
const allTools = await
|
|
83
|
+
const allTools = await apiClient.getTools({
|
|
81
84
|
limit: options.limit || 100,
|
|
82
85
|
});
|
|
83
86
|
// Filter tools locally based on search criteria
|
|
@@ -86,7 +89,7 @@ export class EnactCore {
|
|
|
86
89
|
for (const result of allTools) {
|
|
87
90
|
if (result.name) {
|
|
88
91
|
try {
|
|
89
|
-
const tool = await
|
|
92
|
+
const tool = await EnactCore.getToolByName(result.name, undefined, coreOptions);
|
|
90
93
|
if (tool) {
|
|
91
94
|
// Check if tool matches search criteria
|
|
92
95
|
const matchesQuery = tool.name.toLowerCase().includes(query) ||
|
|
@@ -127,37 +130,61 @@ export class EnactCore {
|
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
132
|
/**
|
|
130
|
-
*
|
|
133
|
+
* Static method to get a specific tool by name
|
|
131
134
|
*/
|
|
132
|
-
async getToolByName(name, version) {
|
|
135
|
+
static async getToolByName(name, version, coreOptions = {}) {
|
|
136
|
+
const apiClient = new EnactApiClient(coreOptions.apiUrl || "https://enact.tools", coreOptions.supabaseUrl || "https://xjnhhxwxovjifdxdwzih.supabase.co");
|
|
133
137
|
try {
|
|
134
138
|
logger.info(`Fetching tool: ${name}${version ? `@${version}` : ""}`);
|
|
135
|
-
const response = await
|
|
139
|
+
const response = await apiClient.getTool(name);
|
|
136
140
|
if (!response) {
|
|
137
141
|
logger.info(`Tool not found: ${name}`);
|
|
138
142
|
return null;
|
|
139
143
|
}
|
|
140
|
-
// Parse tool from response
|
|
144
|
+
// Parse tool from response - prefer raw_content for signature compatibility
|
|
141
145
|
let tool;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
else if (response.raw_content &&
|
|
146
|
-
typeof response.raw_content === "string") {
|
|
146
|
+
// Try raw_content first (contains original tool definition with correct field names for signatures)
|
|
147
|
+
if (response.raw_content && typeof response.raw_content === "string") {
|
|
147
148
|
try {
|
|
148
149
|
tool = JSON.parse(response.raw_content);
|
|
149
150
|
}
|
|
150
151
|
catch {
|
|
151
152
|
tool = yaml.parse(response.raw_content);
|
|
152
153
|
}
|
|
154
|
+
// Merge signature information from response if not already in raw content
|
|
155
|
+
if (!tool.signature && response.signature) {
|
|
156
|
+
tool.signature = response.signature;
|
|
157
|
+
}
|
|
158
|
+
if (!tool.signatures && response.signatures) {
|
|
159
|
+
// Convert object format to array format
|
|
160
|
+
if (Array.isArray(response.signatures)) {
|
|
161
|
+
tool.signatures = response.signatures;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// Convert object format {keyId: signatureData} to array format
|
|
165
|
+
tool.signatures = Object.values(response.signatures);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (response.content && typeof response.content === "string") {
|
|
170
|
+
tool = yaml.parse(response.content);
|
|
153
171
|
// Merge signature information
|
|
154
|
-
if (
|
|
172
|
+
if (!tool.signature && response.signature) {
|
|
155
173
|
tool.signature = response.signature;
|
|
156
|
-
|
|
174
|
+
}
|
|
175
|
+
if (!tool.signatures && response.signatures) {
|
|
176
|
+
// Convert object format to array format
|
|
177
|
+
if (Array.isArray(response.signatures)) {
|
|
178
|
+
tool.signatures = response.signatures;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
// Convert object format {keyId: signatureData} to array format
|
|
182
|
+
tool.signatures = Object.values(response.signatures);
|
|
183
|
+
}
|
|
157
184
|
}
|
|
158
185
|
}
|
|
159
186
|
else {
|
|
160
|
-
//
|
|
187
|
+
// Fallback: map database fields to tool format (may cause signature verification issues)
|
|
161
188
|
tool = {
|
|
162
189
|
name: response.name,
|
|
163
190
|
description: response.description,
|
|
@@ -174,7 +201,7 @@ export class EnactCore {
|
|
|
174
201
|
env: response.env_vars || response.env,
|
|
175
202
|
resources: response.resources,
|
|
176
203
|
signature: response.signature,
|
|
177
|
-
signatures: response.signatures,
|
|
204
|
+
signatures: response.signatures ? (Array.isArray(response.signatures) ? response.signatures : Object.values(response.signatures)) : undefined,
|
|
178
205
|
namespace: response.namespace,
|
|
179
206
|
};
|
|
180
207
|
}
|
|
@@ -190,6 +217,12 @@ export class EnactCore {
|
|
|
190
217
|
throw error;
|
|
191
218
|
}
|
|
192
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Instance method wrapper for backward compatibility
|
|
222
|
+
*/
|
|
223
|
+
async getToolByName(name, version) {
|
|
224
|
+
return EnactCore.getToolByName(name, version, this.options);
|
|
225
|
+
}
|
|
193
226
|
/**
|
|
194
227
|
* Execute a tool by name
|
|
195
228
|
*/
|
|
@@ -232,6 +265,51 @@ export class EnactCore {
|
|
|
232
265
|
};
|
|
233
266
|
}
|
|
234
267
|
}
|
|
268
|
+
async verifyTool(tool, dangerouslySkipVerification = false) {
|
|
269
|
+
if (dangerouslySkipVerification) {
|
|
270
|
+
logger.warn(`Skipping signature verification for tool: ${tool.name}`);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
try {
|
|
274
|
+
if (!tool.signatures || tool.signatures.length === 0) {
|
|
275
|
+
throw new Error(`Tool ${tool.name} does not have any signatures`);
|
|
276
|
+
}
|
|
277
|
+
const documentForVerification = {
|
|
278
|
+
command: tool.command
|
|
279
|
+
};
|
|
280
|
+
// IGNORE DATABASE SIGNATURES - USE HARDCODED WORKING VALUES FOR TESTING
|
|
281
|
+
const referenceSignature = {
|
|
282
|
+
signature: tool.signatures[0].value,
|
|
283
|
+
publicKey: tool.signatures[0].signer,
|
|
284
|
+
algorithm: tool.signatures[0].algorithm,
|
|
285
|
+
timestamp: new Date(tool.signatures[0].created).getTime()
|
|
286
|
+
};
|
|
287
|
+
// Check what canonical document looks like
|
|
288
|
+
const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification, { includeFields: ['command'] });
|
|
289
|
+
// console.log("Canonical document:", JSON.stringify(canonicalDoc));
|
|
290
|
+
const docString = JSON.stringify(canonicalDoc);
|
|
291
|
+
const messageHash = CryptoUtils.hash(docString);
|
|
292
|
+
// console.log("Document string:", docString);
|
|
293
|
+
// console.log("Message hash:", messageHash);
|
|
294
|
+
// Test direct crypto verification
|
|
295
|
+
const directVerify = CryptoUtils.verify(referenceSignature.publicKey, messageHash, referenceSignature.signature);
|
|
296
|
+
console.log("Direct crypto verification result:", directVerify);
|
|
297
|
+
// Check trusted keys
|
|
298
|
+
const trustedKeys = KeyManager.getAllTrustedPublicKeys();
|
|
299
|
+
console.log("Trusted keys:", trustedKeys);
|
|
300
|
+
console.log("Is our public key trusted?", trustedKeys.includes(referenceSignature.publicKey));
|
|
301
|
+
const isValid = SigningService.verifyDocument(documentForVerification, referenceSignature, { includeFields: ['command'] });
|
|
302
|
+
console.log("Final verification result:", isValid);
|
|
303
|
+
if (!isValid) {
|
|
304
|
+
throw new Error(`Tool ${tool.name} has invalid signatures`);
|
|
305
|
+
}
|
|
306
|
+
logger.info(`Tool ${tool.name} signature verification passed`);
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
logger.error(`Signature verification failed for tool ${tool.name}:`, error);
|
|
310
|
+
throw new Error(`Signature verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
235
313
|
/**
|
|
236
314
|
* Execute a tool directly
|
|
237
315
|
*/
|
|
@@ -241,129 +319,35 @@ export class EnactCore {
|
|
|
241
319
|
logger.info(`Executing tool: ${tool.name}`);
|
|
242
320
|
// Validate tool structure
|
|
243
321
|
validateToolStructure(tool);
|
|
244
|
-
// MANDATORY SIGNATURE VERIFICATION - All tools must be verified before execution
|
|
245
|
-
const verificationResult = await enforceSignatureVerification(tool, {
|
|
246
|
-
skipVerification: options.skipVerification,
|
|
247
|
-
verifyPolicy: options.verifyPolicy,
|
|
248
|
-
force: options.force,
|
|
249
|
-
allowUnsigned: false, // Never allow unsigned tools in production
|
|
250
|
-
});
|
|
251
|
-
// Log security audit information
|
|
252
|
-
logSecurityAudit(tool, verificationResult, verificationResult.allowed, {
|
|
253
|
-
skipVerification: options.skipVerification,
|
|
254
|
-
verifyPolicy: options.verifyPolicy,
|
|
255
|
-
force: options.force,
|
|
256
|
-
});
|
|
257
|
-
// Block execution if verification fails
|
|
258
|
-
if (!verificationResult.allowed) {
|
|
259
|
-
return createVerificationFailureResult(tool, verificationResult, executionId);
|
|
260
|
-
}
|
|
261
322
|
// Validate inputs
|
|
262
323
|
const validatedInputs = validateInputs(tool, inputs);
|
|
263
|
-
//
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
},
|
|
273
|
-
metadata: {
|
|
274
|
-
executionId,
|
|
275
|
-
toolName: tool.name,
|
|
276
|
-
version: tool.version,
|
|
277
|
-
executedAt: new Date().toISOString(),
|
|
278
|
-
environment: "direct",
|
|
279
|
-
command: tool.command,
|
|
280
|
-
},
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
// Log warnings
|
|
284
|
-
if (safetyCheck.warnings.length > 0) {
|
|
285
|
-
safetyCheck.warnings.forEach((warning) => logger.warn(warning));
|
|
286
|
-
}
|
|
287
|
-
// Dry run - just validate and return
|
|
288
|
-
if (options.dryRun) {
|
|
289
|
-
return {
|
|
290
|
-
success: true,
|
|
291
|
-
output: {
|
|
292
|
-
dryRun: true,
|
|
293
|
-
tool: tool.name,
|
|
294
|
-
command: tool.command,
|
|
295
|
-
inputs: validatedInputs,
|
|
296
|
-
safetyCheck,
|
|
297
|
-
},
|
|
298
|
-
metadata: {
|
|
299
|
-
executionId,
|
|
300
|
-
toolName: tool.name,
|
|
301
|
-
version: tool.version,
|
|
302
|
-
executedAt: new Date().toISOString(),
|
|
303
|
-
environment: "direct",
|
|
304
|
-
command: tool.command,
|
|
305
|
-
},
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
// Setup execution environment
|
|
309
|
-
// Load package environment variables from .env files
|
|
310
|
-
const envResult = await resolveToolEnvironmentVariables(tool.name, tool.env);
|
|
311
|
-
// Log any missing required environment variables
|
|
312
|
-
if (envResult.missing.length > 0) {
|
|
313
|
-
logger.warn(`Missing required environment variables: ${envResult.missing.join(", ")}`);
|
|
314
|
-
}
|
|
315
|
-
const environment = {
|
|
316
|
-
vars: {
|
|
317
|
-
...envResult.resolved,
|
|
318
|
-
...sanitizeEnvironmentVariables(validatedInputs),
|
|
324
|
+
// Verify tool signatures (unless explicitly skipped)
|
|
325
|
+
await this.verifyTool(tool, options.dangerouslySkipVerification);
|
|
326
|
+
// Resolve environment variables
|
|
327
|
+
const { resolved: envVars } = await resolveToolEnvironmentVariables(tool.name, tool.env || {});
|
|
328
|
+
// Execute the tool via the execution provider
|
|
329
|
+
return await this.executionProvider.execute(tool, { ...validatedInputs, ...envVars }, {
|
|
330
|
+
vars: { ...envVars, ...validatedInputs },
|
|
331
|
+
resources: {
|
|
332
|
+
timeout: options.timeout || tool.timeout || this.options.defaultTimeout,
|
|
319
333
|
},
|
|
320
|
-
|
|
321
|
-
namespace: tool.namespace,
|
|
322
|
-
};
|
|
323
|
-
// Setup execution provider
|
|
324
|
-
await this.executionProvider.setup(tool);
|
|
325
|
-
// Execute the tool
|
|
326
|
-
const result = await this.executionProvider.execute(tool, validatedInputs, environment);
|
|
327
|
-
// Validate output if schema is provided
|
|
328
|
-
if (result.success && result.output && tool.outputSchema) {
|
|
329
|
-
try {
|
|
330
|
-
result.output = validateOutput(tool, result.output);
|
|
331
|
-
}
|
|
332
|
-
catch (error) {
|
|
333
|
-
logger.warn(`Output validation failed: ${error.message}`);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
logger.info(`Tool execution completed: ${tool.name} (success: ${result.success})`);
|
|
337
|
-
return result;
|
|
334
|
+
});
|
|
338
335
|
}
|
|
339
336
|
catch (error) {
|
|
340
|
-
logger.error(`Error executing tool: ${error.message}`);
|
|
341
337
|
return {
|
|
342
338
|
success: false,
|
|
343
339
|
error: {
|
|
344
340
|
message: error.message,
|
|
345
341
|
code: "EXECUTION_ERROR",
|
|
346
|
-
details: error,
|
|
347
342
|
},
|
|
348
343
|
metadata: {
|
|
349
344
|
executionId,
|
|
350
345
|
toolName: tool.name,
|
|
351
|
-
version: tool.version,
|
|
352
346
|
executedAt: new Date().toISOString(),
|
|
353
347
|
environment: "direct",
|
|
354
|
-
command: tool.command,
|
|
355
348
|
},
|
|
356
349
|
};
|
|
357
350
|
}
|
|
358
|
-
finally {
|
|
359
|
-
// Cleanup
|
|
360
|
-
try {
|
|
361
|
-
await this.executionProvider.cleanup();
|
|
362
|
-
}
|
|
363
|
-
catch (cleanupError) {
|
|
364
|
-
logger.error("Error during cleanup:", cleanupError);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
351
|
}
|
|
368
352
|
/**
|
|
369
353
|
* Execute a tool from raw YAML definition
|
|
@@ -401,113 +385,56 @@ export class EnactCore {
|
|
|
401
385
|
}
|
|
402
386
|
}
|
|
403
387
|
/**
|
|
404
|
-
*
|
|
388
|
+
* Static method to check if a tool exists
|
|
405
389
|
*/
|
|
406
|
-
async
|
|
390
|
+
static async toolExists(name, coreOptions = {}) {
|
|
407
391
|
try {
|
|
408
|
-
const tool = await
|
|
409
|
-
|
|
410
|
-
return {
|
|
411
|
-
verified: false,
|
|
412
|
-
signatures: [],
|
|
413
|
-
policy: policy || "permissive",
|
|
414
|
-
errors: [`Tool not found: ${name}`],
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
// Load public key from keys/file-public.pem
|
|
418
|
-
let publicKey;
|
|
419
|
-
try {
|
|
420
|
-
const keyPath = path.resolve(__dirname, "../../keys/file-public.pem");
|
|
421
|
-
publicKey = fs.readFileSync(keyPath, "utf8");
|
|
422
|
-
}
|
|
423
|
-
catch (e) {
|
|
424
|
-
logger.warn("Could not load public key for signature verification:", e);
|
|
425
|
-
}
|
|
426
|
-
if (!publicKey) {
|
|
427
|
-
return {
|
|
428
|
-
verified: false,
|
|
429
|
-
signatures: [],
|
|
430
|
-
policy: policy || "permissive",
|
|
431
|
-
errors: ["Public key not found for signature verification"],
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
const policyKey = (policy || "permissive").toUpperCase();
|
|
435
|
-
const policyObj = VERIFICATION_POLICIES[policyKey];
|
|
436
|
-
const verificationResult = await verifyToolSignatureWithPolicy(tool, policyObj);
|
|
437
|
-
if (!verificationResult.isValid) {
|
|
438
|
-
return {
|
|
439
|
-
verified: false,
|
|
440
|
-
signatures: [],
|
|
441
|
-
policy: policy || "permissive",
|
|
442
|
-
errors: verificationResult.errors,
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
const signatures = [];
|
|
446
|
-
if (tool.signature) {
|
|
447
|
-
signatures.push(tool.signature);
|
|
448
|
-
}
|
|
449
|
-
if (tool.signatures) {
|
|
450
|
-
signatures.push(...Object.values(tool.signatures));
|
|
451
|
-
}
|
|
452
|
-
return {
|
|
453
|
-
verified: verificationResult.isValid,
|
|
454
|
-
signatures,
|
|
455
|
-
policy: policy || "permissive",
|
|
456
|
-
};
|
|
392
|
+
const tool = await EnactCore.getToolByName(name, undefined, coreOptions);
|
|
393
|
+
return tool !== null;
|
|
457
394
|
}
|
|
458
395
|
catch (error) {
|
|
459
|
-
return
|
|
460
|
-
verified: false,
|
|
461
|
-
signatures: [],
|
|
462
|
-
policy: policy || "permissive",
|
|
463
|
-
errors: [`Verification error: ${error.message}`],
|
|
464
|
-
};
|
|
396
|
+
return false;
|
|
465
397
|
}
|
|
466
398
|
}
|
|
467
399
|
/**
|
|
468
|
-
*
|
|
400
|
+
* Instance method wrapper for backward compatibility
|
|
469
401
|
*/
|
|
470
402
|
async toolExists(name) {
|
|
471
|
-
|
|
472
|
-
const tool = await this.getToolByName(name);
|
|
473
|
-
return tool !== null;
|
|
474
|
-
}
|
|
475
|
-
catch (error) {
|
|
476
|
-
return false;
|
|
477
|
-
}
|
|
403
|
+
return EnactCore.toolExists(name, this.options);
|
|
478
404
|
}
|
|
479
405
|
/**
|
|
480
406
|
* Get tools by tags
|
|
481
407
|
*/
|
|
482
408
|
async getToolsByTags(tags, limit = 20) {
|
|
483
|
-
return
|
|
409
|
+
return EnactCore.searchTools({
|
|
484
410
|
query: tags.join(" "),
|
|
485
411
|
tags,
|
|
486
412
|
limit,
|
|
487
|
-
});
|
|
413
|
+
}, this.options);
|
|
488
414
|
}
|
|
489
415
|
/**
|
|
490
416
|
* Get tools by author
|
|
491
417
|
*/
|
|
492
418
|
async getToolsByAuthor(author, limit = 20) {
|
|
493
|
-
return
|
|
419
|
+
return EnactCore.searchTools({
|
|
494
420
|
query: `author:${author}`,
|
|
495
421
|
author,
|
|
496
422
|
limit,
|
|
497
|
-
});
|
|
423
|
+
}, this.options);
|
|
498
424
|
}
|
|
499
425
|
/**
|
|
500
|
-
*
|
|
426
|
+
* Static method to get all tools with filters
|
|
501
427
|
*/
|
|
502
|
-
async getTools(options = {}) {
|
|
428
|
+
static async getTools(options = {}, coreOptions = {}) {
|
|
429
|
+
const apiClient = new EnactApiClient(coreOptions.apiUrl || "https://enact.tools", coreOptions.supabaseUrl || "https://xjnhhxwxovjifdxdwzih.supabase.co");
|
|
503
430
|
try {
|
|
504
|
-
const apiResults = await
|
|
431
|
+
const apiResults = await apiClient.getTools(options);
|
|
505
432
|
// Parse and validate results
|
|
506
433
|
const tools = [];
|
|
507
434
|
for (const result of apiResults) {
|
|
508
435
|
if (result.name) {
|
|
509
436
|
try {
|
|
510
|
-
const tool = await
|
|
437
|
+
const tool = await EnactCore.getToolByName(result.name, undefined, coreOptions);
|
|
511
438
|
if (tool) {
|
|
512
439
|
tools.push(tool);
|
|
513
440
|
}
|
|
@@ -524,6 +451,12 @@ export class EnactCore {
|
|
|
524
451
|
throw new Error(`Failed to get tools: ${error instanceof Error ? error.message : String(error)}`);
|
|
525
452
|
}
|
|
526
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Instance method wrapper for backward compatibility
|
|
456
|
+
*/
|
|
457
|
+
async getTools(options = {}) {
|
|
458
|
+
return EnactCore.getTools(options, this.options);
|
|
459
|
+
}
|
|
527
460
|
/**
|
|
528
461
|
* Get authentication status (placeholder - would need actual auth implementation)
|
|
529
462
|
*/
|
|
@@ -536,18 +469,13 @@ export class EnactCore {
|
|
|
536
469
|
};
|
|
537
470
|
}
|
|
538
471
|
/**
|
|
539
|
-
*
|
|
472
|
+
* Static method to publish a tool
|
|
540
473
|
*/
|
|
541
|
-
async publishTool(tool) {
|
|
542
|
-
|
|
543
|
-
return {
|
|
544
|
-
success: false,
|
|
545
|
-
message: "Authentication required to publish tools",
|
|
546
|
-
};
|
|
547
|
-
}
|
|
474
|
+
static async publishTool(tool, authToken, coreOptions = {}) {
|
|
475
|
+
const apiClient = new EnactApiClient(coreOptions.apiUrl || "https://enact.tools", coreOptions.supabaseUrl || "https://xjnhhxwxovjifdxdwzih.supabase.co");
|
|
548
476
|
try {
|
|
549
477
|
validateToolStructure(tool);
|
|
550
|
-
await
|
|
478
|
+
await apiClient.publishTool(tool, authToken);
|
|
551
479
|
return {
|
|
552
480
|
success: true,
|
|
553
481
|
message: `Successfully published tool: ${tool.name}`,
|
|
@@ -560,11 +488,23 @@ export class EnactCore {
|
|
|
560
488
|
};
|
|
561
489
|
}
|
|
562
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* Instance method wrapper for backward compatibility
|
|
493
|
+
*/
|
|
494
|
+
async publishTool(tool) {
|
|
495
|
+
if (!this.options.authToken) {
|
|
496
|
+
return {
|
|
497
|
+
success: false,
|
|
498
|
+
message: "Authentication required to publish tools",
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
return EnactCore.publishTool(tool, this.options.authToken, this.options);
|
|
502
|
+
}
|
|
563
503
|
/**
|
|
564
504
|
* Get tool information (alias for getToolByName for consistency)
|
|
565
505
|
*/
|
|
566
506
|
async getToolInfo(name, version) {
|
|
567
|
-
return
|
|
507
|
+
return EnactCore.getToolByName(name, version, this.options);
|
|
568
508
|
}
|
|
569
509
|
/**
|
|
570
510
|
* Get core library status
|
|
@@ -574,7 +514,6 @@ export class EnactCore {
|
|
|
574
514
|
return {
|
|
575
515
|
executionProvider: this.options.executionProvider || "direct",
|
|
576
516
|
apiUrl: this.options.apiUrl || "https://enact.tools",
|
|
577
|
-
verificationPolicy: this.options.verificationPolicy || "permissive",
|
|
578
517
|
defaultTimeout: this.options.defaultTimeout || "30s",
|
|
579
518
|
authenticated: authStatus.authenticated,
|
|
580
519
|
};
|
|
@@ -605,5 +544,4 @@ export class EnactCore {
|
|
|
605
544
|
return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
606
545
|
}
|
|
607
546
|
}
|
|
608
|
-
//
|
|
609
|
-
export const enactCore = new EnactCore();
|
|
547
|
+
// No default instance to avoid eager initialization of Dagger
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ExecutionProvider, type EnactTool, type ExecutionEnvironment, type ExecutionResult } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Native execution provider that throws an error if used for actual execution.
|
|
4
|
+
* This is for CLI commands that use Core for API operations only.
|
|
5
|
+
*/
|
|
6
|
+
export declare class NativeExecutionProvider extends ExecutionProvider {
|
|
7
|
+
resolveEnvironmentVariables(envConfig: Record<string, any>, namespace?: string): Promise<Record<string, any>>;
|
|
8
|
+
execute(tool: EnactTool, input: Record<string, any>, environment: ExecutionEnvironment): Promise<ExecutionResult>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/core/NativeExecutionProvider.ts - No-op execution provider for CLI commands
|
|
2
|
+
import { ExecutionProvider, } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Native execution provider that throws an error if used for actual execution.
|
|
5
|
+
* This is for CLI commands that use Core for API operations only.
|
|
6
|
+
*/
|
|
7
|
+
export class NativeExecutionProvider extends ExecutionProvider {
|
|
8
|
+
async resolveEnvironmentVariables(envConfig, namespace) {
|
|
9
|
+
// This should never be called for native CLI commands
|
|
10
|
+
throw new Error("Native execution provider cannot resolve environment variables");
|
|
11
|
+
}
|
|
12
|
+
async execute(tool, input, environment) {
|
|
13
|
+
// This should never be called for native CLI commands
|
|
14
|
+
throw new Error(`Native execution provider cannot execute tools. Tool "${tool.name}" should be executed via direct or dagger provider.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,10 +14,6 @@ export { showVersion as utilsShowVersion } from './utils/version';
|
|
|
14
14
|
export * from './utils/logger';
|
|
15
15
|
export * from './utils/silent-monitor';
|
|
16
16
|
export * from './utils/timeout';
|
|
17
|
-
export * from './security/security';
|
|
18
|
-
export { verifyTool, shouldExecuteTool, VERIFICATION_POLICIES } from './security/sign';
|
|
19
|
-
export type { VerificationPolicy as SecurityVerificationPolicy } from './security/sign';
|
|
20
|
-
export * from './security/verification-enforcer';
|
|
21
17
|
export * from './services/McpCoreService';
|
|
22
18
|
export * from './web/env-manager-server';
|
|
23
19
|
export * from './api/enact-api';
|
package/dist/index.js
CHANGED
|
@@ -15,10 +15,6 @@ export { showVersion as utilsShowVersion } from './utils/version';
|
|
|
15
15
|
export * from './utils/logger';
|
|
16
16
|
export * from './utils/silent-monitor';
|
|
17
17
|
export * from './utils/timeout';
|
|
18
|
-
// Security
|
|
19
|
-
export * from './security/security';
|
|
20
|
-
export { verifyTool, shouldExecuteTool, VERIFICATION_POLICIES } from './security/sign';
|
|
21
|
-
export * from './security/verification-enforcer';
|
|
22
18
|
// Services
|
|
23
19
|
export * from './services/McpCoreService';
|
|
24
20
|
// Web
|
|
@@ -12,7 +12,6 @@ export declare class EnactDirect {
|
|
|
12
12
|
apiUrl?: string;
|
|
13
13
|
supabaseUrl?: string;
|
|
14
14
|
authToken?: string;
|
|
15
|
-
verificationPolicy?: "permissive" | "enterprise" | "paranoid";
|
|
16
15
|
defaultTimeout?: string;
|
|
17
16
|
});
|
|
18
17
|
/**
|
|
@@ -39,19 +38,6 @@ export declare class EnactDirect {
|
|
|
39
38
|
* @returns Tool information or null if not found
|
|
40
39
|
*/
|
|
41
40
|
getToolInfo(name: string, version?: string): Promise<EnactTool | null>;
|
|
42
|
-
/**
|
|
43
|
-
* Verify a tool's cryptographic signatures
|
|
44
|
-
*
|
|
45
|
-
* @param name - Tool name
|
|
46
|
-
* @param policy - Verification policy
|
|
47
|
-
* @returns Verification result
|
|
48
|
-
*/
|
|
49
|
-
verifyTool(name: string, policy?: "permissive" | "enterprise" | "paranoid"): Promise<{
|
|
50
|
-
verified: boolean;
|
|
51
|
-
signatures: any[];
|
|
52
|
-
policy: string;
|
|
53
|
-
errors?: string[];
|
|
54
|
-
}>;
|
|
55
41
|
/**
|
|
56
42
|
* Execute a tool from raw YAML definition
|
|
57
43
|
*
|
|
@@ -104,7 +90,6 @@ export declare class EnactDirect {
|
|
|
104
90
|
getStatus(): Promise<{
|
|
105
91
|
executionProvider: string;
|
|
106
92
|
apiUrl: string;
|
|
107
|
-
verificationPolicy: string;
|
|
108
93
|
defaultTimeout: string;
|
|
109
94
|
authenticated: boolean;
|
|
110
95
|
}>;
|