@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.
@@ -87,4 +87,5 @@ export interface EnactExecOptions {
87
87
  verbose?: boolean;
88
88
  force?: boolean;
89
89
  dangerouslySkipVerification?: boolean;
90
+ mount?: string;
90
91
  }
@@ -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));
@@ -28,6 +28,7 @@ export interface ToolExecuteOptions {
28
28
  verbose?: boolean;
29
29
  isLocalFile?: boolean;
30
30
  dangerouslySkipVerification?: boolean;
31
+ mount?: string;
31
32
  }
32
33
  export declare class EnactCore {
33
34
  private apiClient;
@@ -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
@@ -117,6 +117,7 @@ export interface ExecutionEnvironment {
117
117
  timeout?: string;
118
118
  };
119
119
  namespace?: string;
120
+ mount?: string;
120
121
  }
121
122
  export declare abstract class ExecutionProvider {
122
123
  abstract setup(tool: EnactTool): Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enactprotocol/shared",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Shared utilities and core functionality for Enact Protocol",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
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));
@@ -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, { includeFields: ['command'] });
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
- { includeFields: ['command'] }
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