@enactprotocol/shared 1.2.4 → 1.2.6
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/types.d.ts +1 -0
- package/dist/core/DaggerExecutionProvider.d.ts +4 -0
- package/dist/core/DaggerExecutionProvider.js +66 -0
- package/dist/core/EnactCore.d.ts +1 -0
- package/dist/core/EnactCore.js +8 -4
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/api/types.ts +1 -0
- package/src/core/DaggerExecutionProvider.ts +76 -0
- package/src/core/EnactCore.ts +10 -4
- package/src/types.ts +1 -0
package/dist/api/types.d.ts
CHANGED
|
@@ -72,6 +72,10 @@ export declare class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
72
72
|
* Execute command using Dagger connect with proper session management
|
|
73
73
|
*/
|
|
74
74
|
private executeWithConnect;
|
|
75
|
+
/**
|
|
76
|
+
* Setup directory mounting for the container
|
|
77
|
+
*/
|
|
78
|
+
private setupDirectoryMount;
|
|
75
79
|
/**
|
|
76
80
|
* Enhanced container setup with better tool detection and installation
|
|
77
81
|
*/
|
|
@@ -504,6 +504,68 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
504
504
|
});
|
|
505
505
|
});
|
|
506
506
|
}
|
|
507
|
+
/**
|
|
508
|
+
* Setup directory mounting for the container
|
|
509
|
+
*/
|
|
510
|
+
async setupDirectoryMount(client, container, mountSpec) {
|
|
511
|
+
try {
|
|
512
|
+
// Parse mount specification (format: "localPath" or "localPath:containerPath")
|
|
513
|
+
let localPath;
|
|
514
|
+
let containerPath;
|
|
515
|
+
// Handle Windows drive letters (e.g., C:\path) vs mount separator (:)
|
|
516
|
+
const colonIndex = mountSpec.indexOf(':');
|
|
517
|
+
if (colonIndex > 0) {
|
|
518
|
+
// Check if this might be a Windows drive letter (single letter followed by colon)
|
|
519
|
+
const potentialDriveLetter = mountSpec.substring(0, colonIndex);
|
|
520
|
+
const isWindowsDrive = potentialDriveLetter.length === 1 && /[A-Za-z]/.test(potentialDriveLetter);
|
|
521
|
+
if (isWindowsDrive) {
|
|
522
|
+
// Look for the next colon that separates local from container path
|
|
523
|
+
const nextColonIndex = mountSpec.indexOf(':', colonIndex + 1);
|
|
524
|
+
if (nextColonIndex > 0) {
|
|
525
|
+
localPath = mountSpec.substring(0, nextColonIndex);
|
|
526
|
+
containerPath = mountSpec.substring(nextColonIndex + 1);
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
// No container path specified, use default
|
|
530
|
+
localPath = mountSpec;
|
|
531
|
+
containerPath = '/workspace/src';
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
// Regular path:container split
|
|
536
|
+
localPath = mountSpec.substring(0, colonIndex);
|
|
537
|
+
containerPath = mountSpec.substring(colonIndex + 1);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
else if (colonIndex === 0) {
|
|
541
|
+
// Starts with colon (e.g., ":/app")
|
|
542
|
+
localPath = '';
|
|
543
|
+
containerPath = mountSpec.substring(1);
|
|
544
|
+
}
|
|
545
|
+
else {
|
|
546
|
+
localPath = mountSpec;
|
|
547
|
+
containerPath = '/workspace/src'; // Default container path
|
|
548
|
+
}
|
|
549
|
+
// Resolve local path to absolute path
|
|
550
|
+
const path = require('path');
|
|
551
|
+
const resolvedLocalPath = path.resolve(localPath);
|
|
552
|
+
// Check if local directory exists
|
|
553
|
+
const fs = require('fs');
|
|
554
|
+
if (!fs.existsSync(resolvedLocalPath)) {
|
|
555
|
+
throw new Error(`Mount source directory does not exist: ${resolvedLocalPath}`);
|
|
556
|
+
}
|
|
557
|
+
// Create Directory object from local path
|
|
558
|
+
const hostDirectory = client.host().directory(resolvedLocalPath);
|
|
559
|
+
// Mount directory in container using withMountedDirectory for better performance
|
|
560
|
+
container = container.withMountedDirectory(containerPath, hostDirectory);
|
|
561
|
+
logger.debug(`📂 Mounted ${resolvedLocalPath} -> ${containerPath}`);
|
|
562
|
+
return container;
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
logger.error(`Failed to setup directory mount: ${error}`);
|
|
566
|
+
throw error;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
507
569
|
/**
|
|
508
570
|
* Enhanced container setup with better tool detection and installation
|
|
509
571
|
*/
|
|
@@ -517,6 +579,10 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
517
579
|
// Set working directory
|
|
518
580
|
container = container.withWorkdir(this.options.workdir);
|
|
519
581
|
logger.debug(`📁 Working directory set to: ${this.options.workdir}`);
|
|
582
|
+
// Handle directory mounting if specified
|
|
583
|
+
if (environment.mount) {
|
|
584
|
+
container = await this.setupDirectoryMount(client, container, environment.mount);
|
|
585
|
+
}
|
|
520
586
|
// Add environment variables from Enact tool env config
|
|
521
587
|
for (const [key, value] of Object.entries(environment.vars)) {
|
|
522
588
|
container = container.withEnvVariable(key, String(value));
|
package/dist/core/EnactCore.d.ts
CHANGED
package/dist/core/EnactCore.js
CHANGED
|
@@ -288,7 +288,10 @@ export class EnactCore {
|
|
|
288
288
|
throw new Error(`Tool ${tool.name} does not have any signatures`);
|
|
289
289
|
}
|
|
290
290
|
const documentForVerification = {
|
|
291
|
-
command: tool.command
|
|
291
|
+
command: tool.command,
|
|
292
|
+
description: tool.description,
|
|
293
|
+
from: tool.from,
|
|
294
|
+
name: tool.name,
|
|
292
295
|
};
|
|
293
296
|
const referenceSignature = {
|
|
294
297
|
signature: tool.signatures[0].value,
|
|
@@ -297,15 +300,15 @@ export class EnactCore {
|
|
|
297
300
|
timestamp: new Date(tool.signatures[0].created).getTime()
|
|
298
301
|
};
|
|
299
302
|
// Check what canonical document looks like
|
|
300
|
-
const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification, { includeFields: ['command'] });
|
|
303
|
+
const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification, { includeFields: ['command', 'description', 'from', 'name'] });
|
|
301
304
|
const docString = JSON.stringify(canonicalDoc);
|
|
302
305
|
const messageHash = CryptoUtils.hash(docString);
|
|
303
306
|
// Test direct crypto verification
|
|
304
307
|
const directVerify = CryptoUtils.verify(referenceSignature.publicKey, messageHash, referenceSignature.signature);
|
|
305
308
|
// Check trusted keys
|
|
306
309
|
// const trustedKeys = KeyManager.getAllTrustedPublicKeys();
|
|
307
|
-
const isValid = SigningService.verifyDocument(documentForVerification, referenceSignature, { includeFields: ['command'] });
|
|
308
|
-
console.log("Final verification result:", isValid);
|
|
310
|
+
const isValid = SigningService.verifyDocument(documentForVerification, referenceSignature, { includeFields: ['command', 'description', 'from', 'name'] });
|
|
311
|
+
// console.log("Final verification result:", isValid);
|
|
309
312
|
if (!isValid) {
|
|
310
313
|
throw new Error(`Tool ${tool.name} has invalid signatures`);
|
|
311
314
|
}
|
|
@@ -345,6 +348,7 @@ export class EnactCore {
|
|
|
345
348
|
resources: {
|
|
346
349
|
timeout: options.timeout || tool.timeout || this.options.defaultTimeout,
|
|
347
350
|
},
|
|
351
|
+
mount: options.mount,
|
|
348
352
|
});
|
|
349
353
|
}
|
|
350
354
|
catch (error) {
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
package/src/api/types.ts
CHANGED
|
@@ -97,4 +97,5 @@ export interface EnactExecOptions {
|
|
|
97
97
|
verbose?: boolean;
|
|
98
98
|
force?: boolean; // Force execution even if verification fails (legacy)
|
|
99
99
|
dangerouslySkipVerification?: boolean; // Skip all signature verification (DANGEROUS)
|
|
100
|
+
mount?: string; // Mount local directory to container (format: "local:container")
|
|
100
101
|
}
|
|
@@ -702,6 +702,77 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
702
702
|
});
|
|
703
703
|
}
|
|
704
704
|
|
|
705
|
+
/**
|
|
706
|
+
* Setup directory mounting for the container
|
|
707
|
+
*/
|
|
708
|
+
private async setupDirectoryMount(
|
|
709
|
+
client: Client,
|
|
710
|
+
container: Container,
|
|
711
|
+
mountSpec: string,
|
|
712
|
+
): Promise<Container> {
|
|
713
|
+
try {
|
|
714
|
+
// Parse mount specification (format: "localPath" or "localPath:containerPath")
|
|
715
|
+
let localPath: string;
|
|
716
|
+
let containerPath: string;
|
|
717
|
+
|
|
718
|
+
// Handle Windows drive letters (e.g., C:\path) vs mount separator (:)
|
|
719
|
+
const colonIndex = mountSpec.indexOf(':');
|
|
720
|
+
|
|
721
|
+
if (colonIndex > 0) {
|
|
722
|
+
// Check if this might be a Windows drive letter (single letter followed by colon)
|
|
723
|
+
const potentialDriveLetter = mountSpec.substring(0, colonIndex);
|
|
724
|
+
const isWindowsDrive = potentialDriveLetter.length === 1 && /[A-Za-z]/.test(potentialDriveLetter);
|
|
725
|
+
|
|
726
|
+
if (isWindowsDrive) {
|
|
727
|
+
// Look for the next colon that separates local from container path
|
|
728
|
+
const nextColonIndex = mountSpec.indexOf(':', colonIndex + 1);
|
|
729
|
+
if (nextColonIndex > 0) {
|
|
730
|
+
localPath = mountSpec.substring(0, nextColonIndex);
|
|
731
|
+
containerPath = mountSpec.substring(nextColonIndex + 1);
|
|
732
|
+
} else {
|
|
733
|
+
// No container path specified, use default
|
|
734
|
+
localPath = mountSpec;
|
|
735
|
+
containerPath = '/workspace/src';
|
|
736
|
+
}
|
|
737
|
+
} else {
|
|
738
|
+
// Regular path:container split
|
|
739
|
+
localPath = mountSpec.substring(0, colonIndex);
|
|
740
|
+
containerPath = mountSpec.substring(colonIndex + 1);
|
|
741
|
+
}
|
|
742
|
+
} else if (colonIndex === 0) {
|
|
743
|
+
// Starts with colon (e.g., ":/app")
|
|
744
|
+
localPath = '';
|
|
745
|
+
containerPath = mountSpec.substring(1);
|
|
746
|
+
} else {
|
|
747
|
+
localPath = mountSpec;
|
|
748
|
+
containerPath = '/workspace/src'; // Default container path
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Resolve local path to absolute path
|
|
752
|
+
const path = require('path');
|
|
753
|
+
const resolvedLocalPath = path.resolve(localPath);
|
|
754
|
+
|
|
755
|
+
// Check if local directory exists
|
|
756
|
+
const fs = require('fs');
|
|
757
|
+
if (!fs.existsSync(resolvedLocalPath)) {
|
|
758
|
+
throw new Error(`Mount source directory does not exist: ${resolvedLocalPath}`);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// Create Directory object from local path
|
|
762
|
+
const hostDirectory = client.host().directory(resolvedLocalPath);
|
|
763
|
+
|
|
764
|
+
// Mount directory in container using withMountedDirectory for better performance
|
|
765
|
+
container = container.withMountedDirectory(containerPath, hostDirectory);
|
|
766
|
+
|
|
767
|
+
logger.debug(`📂 Mounted ${resolvedLocalPath} -> ${containerPath}`);
|
|
768
|
+
|
|
769
|
+
return container;
|
|
770
|
+
} catch (error) {
|
|
771
|
+
logger.error(`Failed to setup directory mount: ${error}`);
|
|
772
|
+
throw error;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
705
776
|
/**
|
|
706
777
|
* Enhanced container setup with better tool detection and installation
|
|
707
778
|
*/
|
|
@@ -726,6 +797,11 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
726
797
|
container = container.withWorkdir(this.options.workdir!);
|
|
727
798
|
logger.debug(`📁 Working directory set to: ${this.options.workdir}`);
|
|
728
799
|
|
|
800
|
+
// Handle directory mounting if specified
|
|
801
|
+
if (environment.mount) {
|
|
802
|
+
container = await this.setupDirectoryMount(client, container, environment.mount);
|
|
803
|
+
}
|
|
804
|
+
|
|
729
805
|
// Add environment variables from Enact tool env config
|
|
730
806
|
for (const [key, value] of Object.entries(environment.vars)) {
|
|
731
807
|
container = container.withEnvVariable(key, String(value));
|
package/src/core/EnactCore.ts
CHANGED
|
@@ -52,6 +52,7 @@ export interface ToolExecuteOptions {
|
|
|
52
52
|
verbose?: boolean;
|
|
53
53
|
isLocalFile?: boolean;
|
|
54
54
|
dangerouslySkipVerification?: boolean;
|
|
55
|
+
mount?: string; // Mount local directory to container (format: "localPath" or "localPath:containerPath")
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
export class EnactCore {
|
|
@@ -419,7 +420,10 @@ private async verifyTool(tool: EnactTool, dangerouslySkipVerification: boolean =
|
|
|
419
420
|
}
|
|
420
421
|
|
|
421
422
|
const documentForVerification = {
|
|
422
|
-
command: tool.command
|
|
423
|
+
command: tool.command,
|
|
424
|
+
description: tool.description,
|
|
425
|
+
from: tool.from,
|
|
426
|
+
name: tool.name,
|
|
423
427
|
};
|
|
424
428
|
|
|
425
429
|
const referenceSignature = {
|
|
@@ -431,7 +435,8 @@ private async verifyTool(tool: EnactTool, dangerouslySkipVerification: boolean =
|
|
|
431
435
|
|
|
432
436
|
|
|
433
437
|
// Check what canonical document looks like
|
|
434
|
-
const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification,
|
|
438
|
+
const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification, { includeFields: ['command', 'description', 'from', 'name'] }
|
|
439
|
+
);
|
|
435
440
|
|
|
436
441
|
const docString = JSON.stringify(canonicalDoc);
|
|
437
442
|
const messageHash = CryptoUtils.hash(docString);
|
|
@@ -450,10 +455,10 @@ private async verifyTool(tool: EnactTool, dangerouslySkipVerification: boolean =
|
|
|
450
455
|
const isValid = SigningService.verifyDocument(
|
|
451
456
|
documentForVerification,
|
|
452
457
|
referenceSignature,
|
|
453
|
-
|
|
458
|
+
{ includeFields: ['command', 'description', 'from', 'name'] }
|
|
454
459
|
);
|
|
455
460
|
|
|
456
|
-
console.log("Final verification result:", isValid);
|
|
461
|
+
// console.log("Final verification result:", isValid);
|
|
457
462
|
|
|
458
463
|
if (!isValid) {
|
|
459
464
|
throw new Error(`Tool ${tool.name} has invalid signatures`);
|
|
@@ -510,6 +515,7 @@ private async verifyTool(tool: EnactTool, dangerouslySkipVerification: boolean =
|
|
|
510
515
|
resources: {
|
|
511
516
|
timeout: options.timeout || tool.timeout || this.options.defaultTimeout,
|
|
512
517
|
},
|
|
518
|
+
mount: options.mount,
|
|
513
519
|
},
|
|
514
520
|
);
|
|
515
521
|
} catch (error) {
|
package/src/types.ts
CHANGED
|
@@ -162,6 +162,7 @@ export interface ExecutionEnvironment {
|
|
|
162
162
|
timeout?: string;
|
|
163
163
|
};
|
|
164
164
|
namespace?: string; // Environment variable namespace
|
|
165
|
+
mount?: string; // Mount local directory to container (format: "localPath" or "localPath:containerPath")
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
// Updated execution provider interface
|