@enactprotocol/shared 1.0.12

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.
Files changed (97) hide show
  1. package/dist/LocalToolResolver.d.ts +84 -0
  2. package/dist/LocalToolResolver.js +353 -0
  3. package/dist/api/enact-api.d.ts +124 -0
  4. package/dist/api/enact-api.js +406 -0
  5. package/dist/api/index.d.ts +2 -0
  6. package/dist/api/index.js +2 -0
  7. package/dist/api/types.d.ts +83 -0
  8. package/dist/api/types.js +1 -0
  9. package/dist/core/DaggerExecutionProvider.d.ts +169 -0
  10. package/dist/core/DaggerExecutionProvider.js +996 -0
  11. package/dist/core/DirectExecutionProvider.d.ts +23 -0
  12. package/dist/core/DirectExecutionProvider.js +406 -0
  13. package/dist/core/EnactCore.d.ts +138 -0
  14. package/dist/core/EnactCore.js +609 -0
  15. package/dist/core/index.d.ts +3 -0
  16. package/dist/core/index.js +3 -0
  17. package/dist/exec/index.d.ts +3 -0
  18. package/dist/exec/index.js +3 -0
  19. package/dist/exec/logger.d.ts +11 -0
  20. package/dist/exec/logger.js +57 -0
  21. package/dist/exec/validate.d.ts +5 -0
  22. package/dist/exec/validate.js +167 -0
  23. package/dist/index.d.ts +25 -0
  24. package/dist/index.js +29 -0
  25. package/dist/lib/enact-direct.d.ts +156 -0
  26. package/dist/lib/enact-direct.js +158 -0
  27. package/dist/lib/index.d.ts +1 -0
  28. package/dist/lib/index.js +1 -0
  29. package/dist/security/index.d.ts +3 -0
  30. package/dist/security/index.js +3 -0
  31. package/dist/security/security.d.ts +23 -0
  32. package/dist/security/security.js +137 -0
  33. package/dist/security/sign.d.ts +103 -0
  34. package/dist/security/sign.js +532 -0
  35. package/dist/security/verification-enforcer.d.ts +41 -0
  36. package/dist/security/verification-enforcer.js +181 -0
  37. package/dist/services/McpCoreService.d.ts +102 -0
  38. package/dist/services/McpCoreService.js +120 -0
  39. package/dist/services/index.d.ts +1 -0
  40. package/dist/services/index.js +1 -0
  41. package/dist/types.d.ts +130 -0
  42. package/dist/types.js +3 -0
  43. package/dist/utils/config.d.ts +32 -0
  44. package/dist/utils/config.js +78 -0
  45. package/dist/utils/env-loader.d.ts +54 -0
  46. package/dist/utils/env-loader.js +270 -0
  47. package/dist/utils/help.d.ts +36 -0
  48. package/dist/utils/help.js +248 -0
  49. package/dist/utils/index.d.ts +7 -0
  50. package/dist/utils/index.js +7 -0
  51. package/dist/utils/logger.d.ts +35 -0
  52. package/dist/utils/logger.js +75 -0
  53. package/dist/utils/silent-monitor.d.ts +67 -0
  54. package/dist/utils/silent-monitor.js +242 -0
  55. package/dist/utils/timeout.d.ts +5 -0
  56. package/dist/utils/timeout.js +23 -0
  57. package/dist/utils/version.d.ts +4 -0
  58. package/dist/utils/version.js +14 -0
  59. package/dist/web/env-manager-server.d.ts +29 -0
  60. package/dist/web/env-manager-server.js +367 -0
  61. package/dist/web/index.d.ts +1 -0
  62. package/dist/web/index.js +1 -0
  63. package/package.json +79 -0
  64. package/src/LocalToolResolver.ts +424 -0
  65. package/src/api/enact-api.ts +569 -0
  66. package/src/api/index.ts +2 -0
  67. package/src/api/types.ts +93 -0
  68. package/src/core/DaggerExecutionProvider.ts +1308 -0
  69. package/src/core/DirectExecutionProvider.ts +484 -0
  70. package/src/core/EnactCore.ts +833 -0
  71. package/src/core/index.ts +3 -0
  72. package/src/exec/index.ts +3 -0
  73. package/src/exec/logger.ts +63 -0
  74. package/src/exec/validate.ts +238 -0
  75. package/src/index.ts +42 -0
  76. package/src/lib/enact-direct.ts +258 -0
  77. package/src/lib/index.ts +1 -0
  78. package/src/security/index.ts +3 -0
  79. package/src/security/security.ts +188 -0
  80. package/src/security/sign.ts +797 -0
  81. package/src/security/verification-enforcer.ts +268 -0
  82. package/src/services/McpCoreService.ts +203 -0
  83. package/src/services/index.ts +1 -0
  84. package/src/types.ts +190 -0
  85. package/src/utils/config.ts +97 -0
  86. package/src/utils/env-loader.ts +370 -0
  87. package/src/utils/help.ts +257 -0
  88. package/src/utils/index.ts +7 -0
  89. package/src/utils/logger.ts +83 -0
  90. package/src/utils/silent-monitor.ts +328 -0
  91. package/src/utils/timeout.ts +26 -0
  92. package/src/utils/version.ts +16 -0
  93. package/src/web/env-manager-server.ts +465 -0
  94. package/src/web/index.ts +1 -0
  95. package/src/web/static/app.js +663 -0
  96. package/src/web/static/index.html +117 -0
  97. package/src/web/static/style.css +291 -0
@@ -0,0 +1,181 @@
1
+ // src/security/verification-enforcer.ts - Mandatory signature verification enforcement
2
+ import { verifyTool, VERIFICATION_POLICIES, } from "./sign";
3
+ import logger from "../exec/logger";
4
+ /**
5
+ * Enforce mandatory signature verification for tool execution
6
+ * This is the central function that should be called before ANY tool execution
7
+ */
8
+ export async function enforceSignatureVerification(tool, options = {}) {
9
+ const toolName = tool.name || "unknown";
10
+ // Check if verification is explicitly skipped
11
+ if (options.skipVerification) {
12
+ logger.warn(`🚨 SECURITY WARNING: Signature verification skipped for tool: ${toolName}`);
13
+ logger.warn(` This bypasses security measures and is NOT recommended for production use!`);
14
+ return {
15
+ allowed: true,
16
+ reason: `Verification skipped by request for tool: ${toolName}`,
17
+ verificationResult: {
18
+ isValid: false,
19
+ message: "Verification skipped",
20
+ validSignatures: 0,
21
+ totalSignatures: 0,
22
+ verifiedSigners: [],
23
+ errors: ["Signature verification was explicitly skipped"],
24
+ },
25
+ };
26
+ }
27
+ // Check if tool has any signatures
28
+ const hasSignatures = !!(tool.signatures && Object.keys(tool.signatures).length > 0) ||
29
+ !!tool.signature;
30
+ if (!hasSignatures) {
31
+ logger.warn(`⚠️ Tool has no signatures: ${toolName}`);
32
+ // Only allow unsigned tools if explicitly permitted (for development/testing)
33
+ if (options.allowUnsigned) {
34
+ logger.warn(` Allowing unsigned tool execution due to allowUnsigned flag (DEV/TEST ONLY)`);
35
+ return {
36
+ allowed: true,
37
+ reason: `Unsigned tool allowed by explicit permission: ${toolName}`,
38
+ verificationResult: {
39
+ isValid: false,
40
+ message: "No signatures found, but execution allowed",
41
+ validSignatures: 0,
42
+ totalSignatures: 0,
43
+ verifiedSigners: [],
44
+ errors: [
45
+ "Tool has no signatures but execution was explicitly allowed",
46
+ ],
47
+ },
48
+ };
49
+ }
50
+ // Reject unsigned tools by default
51
+ return {
52
+ allowed: false,
53
+ reason: `Tool has no signatures and unsigned execution is not permitted: ${toolName}`,
54
+ error: {
55
+ message: `Tool "${toolName}" has no cryptographic signatures. For security, only signed tools can be executed.`,
56
+ code: "NO_SIGNATURES_FOUND",
57
+ details: {
58
+ toolName,
59
+ hasSignature: !!tool.signature,
60
+ hasSignatures: !!tool.signatures,
61
+ signatureCount: tool.signatures
62
+ ? Object.keys(tool.signatures).length
63
+ : 0,
64
+ },
65
+ },
66
+ };
67
+ }
68
+ // Perform signature verification
69
+ try {
70
+ logger.info(`🔐 Verifying signatures for tool: ${toolName}`);
71
+ // Determine verification policy
72
+ const policyKey = (options.verifyPolicy || "permissive").toUpperCase();
73
+ const policy = VERIFICATION_POLICIES[policyKey] || VERIFICATION_POLICIES.PERMISSIVE;
74
+ logger.info(` Using verification policy: ${policyKey.toLowerCase()}`);
75
+ if (policy.minimumSignatures) {
76
+ logger.info(` Minimum signatures required: ${policy.minimumSignatures}`);
77
+ }
78
+ if (policy.requireRoles) {
79
+ logger.info(` Required roles: ${policy.requireRoles.join(", ")}`);
80
+ }
81
+ // Verify the tool
82
+ const verificationResult = await verifyTool(tool, policy);
83
+ if (verificationResult.isValid) {
84
+ logger.info(`✅ Signature verification passed for tool: ${toolName}`);
85
+ logger.info(` Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}`);
86
+ if (verificationResult.verifiedSigners.length > 0) {
87
+ logger.info(` Verified signers: ${verificationResult.verifiedSigners
88
+ .map((s) => `${s.signer}${s.role ? ` (${s.role})` : ""}`)
89
+ .join(", ")}`);
90
+ }
91
+ return {
92
+ allowed: true,
93
+ reason: `Tool signature verification passed: ${verificationResult.message}`,
94
+ verificationResult,
95
+ };
96
+ }
97
+ else {
98
+ logger.error(`❌ Signature verification failed for tool: ${toolName}`);
99
+ logger.error(` Policy: ${policyKey.toLowerCase()}`);
100
+ logger.error(` Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}`);
101
+ if (verificationResult.errors.length > 0) {
102
+ logger.error(` Errors:`);
103
+ verificationResult.errors.forEach((error) => logger.error(` - ${error}`));
104
+ }
105
+ return {
106
+ allowed: false,
107
+ reason: `Tool signature verification failed: ${verificationResult.message}`,
108
+ verificationResult,
109
+ error: {
110
+ message: `Tool "${toolName}" failed signature verification. ${verificationResult.message}`,
111
+ code: "SIGNATURE_VERIFICATION_FAILED",
112
+ details: {
113
+ toolName,
114
+ policy: policyKey.toLowerCase(),
115
+ validSignatures: verificationResult.validSignatures,
116
+ totalSignatures: verificationResult.totalSignatures,
117
+ errors: verificationResult.errors,
118
+ verifiedSigners: verificationResult.verifiedSigners,
119
+ },
120
+ },
121
+ };
122
+ }
123
+ }
124
+ catch (error) {
125
+ const errorMessage = error instanceof Error ? error.message : "Unknown verification error";
126
+ logger.error(`💥 Signature verification error for tool: ${toolName} - ${errorMessage}`);
127
+ return {
128
+ allowed: false,
129
+ reason: `Signature verification error: ${errorMessage}`,
130
+ error: {
131
+ message: `Signature verification failed due to error: ${errorMessage}`,
132
+ code: "VERIFICATION_ERROR",
133
+ details: { toolName, originalError: error },
134
+ },
135
+ };
136
+ }
137
+ }
138
+ /**
139
+ * Create an execution result for verification failure
140
+ */
141
+ export function createVerificationFailureResult(tool, verificationResult, executionId) {
142
+ return {
143
+ success: false,
144
+ error: verificationResult.error || {
145
+ message: verificationResult.reason,
146
+ code: "VERIFICATION_FAILED",
147
+ },
148
+ metadata: {
149
+ executionId,
150
+ toolName: tool.name || "unknown",
151
+ version: tool.version,
152
+ executedAt: new Date().toISOString(),
153
+ environment: "direct",
154
+ command: tool.command,
155
+ },
156
+ };
157
+ }
158
+ /**
159
+ * Log security audit information for tool execution
160
+ */
161
+ export function logSecurityAudit(tool, verificationResult, executionAllowed, options) {
162
+ const auditLog = {
163
+ timestamp: new Date().toISOString(),
164
+ tool: tool.name || "unknown",
165
+ version: tool.version,
166
+ command: tool.command,
167
+ executionAllowed,
168
+ verificationSkipped: options.skipVerification || false,
169
+ verificationPolicy: options.verifyPolicy || "permissive",
170
+ verificationResult: verificationResult.verificationResult
171
+ ? {
172
+ isValid: verificationResult.verificationResult.isValid,
173
+ validSignatures: verificationResult.verificationResult.validSignatures,
174
+ totalSignatures: verificationResult.verificationResult.totalSignatures,
175
+ verifiedSigners: verificationResult.verificationResult.verifiedSigners,
176
+ }
177
+ : null,
178
+ errors: verificationResult.error ? [verificationResult.error.message] : [],
179
+ };
180
+ logger.info(`🔍 Security Audit Log:`, auditLog);
181
+ }
@@ -0,0 +1,102 @@
1
+ import type { EnactTool, ExecutionResult } from "../types";
2
+ export declare class McpCoreService {
3
+ private core;
4
+ constructor(options?: {
5
+ apiUrl?: string;
6
+ supabaseUrl?: string;
7
+ authToken?: string;
8
+ });
9
+ /**
10
+ * Set authentication token
11
+ */
12
+ setAuthToken(token: string): void;
13
+ /**
14
+ * Search for tools
15
+ */
16
+ searchTools(query: string, options?: {
17
+ limit?: number;
18
+ tags?: string[];
19
+ author?: string;
20
+ }): Promise<EnactTool[]>;
21
+ /**
22
+ * Get a specific tool by name
23
+ */
24
+ getToolInfo(name: string): Promise<EnactTool | null>;
25
+ /**
26
+ * Execute a tool by name
27
+ */
28
+ executeToolByName(name: string, inputs?: Record<string, any>, options?: {
29
+ timeout?: string;
30
+ verifyPolicy?: "permissive" | "enterprise" | "paranoid";
31
+ skipVerification?: boolean;
32
+ force?: boolean;
33
+ dryRun?: boolean;
34
+ }): Promise<ExecutionResult>;
35
+ /**
36
+ * Execute a tool from raw YAML definition
37
+ */
38
+ executeRawTool(toolYaml: string, inputs?: Record<string, any>, options?: {
39
+ timeout?: string;
40
+ skipVerification?: boolean;
41
+ force?: boolean;
42
+ dryRun?: boolean;
43
+ }): Promise<ExecutionResult>;
44
+ /**
45
+ * Verify a tool's signature
46
+ */
47
+ verifyTool(name: string, policy?: string): Promise<{
48
+ verified: boolean;
49
+ signatures: any[];
50
+ policy: string;
51
+ errors?: string[];
52
+ }>;
53
+ /**
54
+ * Check if a tool exists
55
+ */
56
+ toolExists(name: string): Promise<boolean>;
57
+ /**
58
+ * Get tools by tags
59
+ */
60
+ getToolsByTags(tags: string[], limit?: number): Promise<EnactTool[]>;
61
+ /**
62
+ * Get tools by author
63
+ */
64
+ getToolsByAuthor(author: string, limit?: number): Promise<EnactTool[]>;
65
+ /**
66
+ * Get all tools with filters
67
+ */
68
+ getTools(options?: {
69
+ limit?: number;
70
+ offset?: number;
71
+ tags?: string[];
72
+ author?: string;
73
+ }): Promise<EnactTool[]>;
74
+ /**
75
+ * Get authentication status
76
+ */
77
+ getAuthStatus(): Promise<{
78
+ authenticated: boolean;
79
+ user?: string;
80
+ server?: string;
81
+ }>;
82
+ /**
83
+ * Check if service is available (always true for core service)
84
+ */
85
+ isAvailable(): Promise<boolean>;
86
+ /**
87
+ * Get service path info (not applicable for core service)
88
+ */
89
+ getPathInfo(): Promise<{
90
+ detectedPath: string | null;
91
+ isAvailable: boolean;
92
+ version?: string;
93
+ }>;
94
+ /**
95
+ * Publish a tool (requires authentication)
96
+ */
97
+ publishTool(tool: EnactTool): Promise<{
98
+ success: boolean;
99
+ message: string;
100
+ }>;
101
+ }
102
+ export declare const mcpCoreService: McpCoreService;
@@ -0,0 +1,120 @@
1
+ // src/services/McpCoreService.ts - Direct core integration for MCP server
2
+ import { EnactCore } from "../core/EnactCore";
3
+ export class McpCoreService {
4
+ constructor(options) {
5
+ this.core = new EnactCore({
6
+ apiUrl: options?.apiUrl || "https://enact.tools",
7
+ supabaseUrl: options?.supabaseUrl || "https://xjnhhxwxovjifdxdwzih.supabase.co",
8
+ authToken: options?.authToken,
9
+ });
10
+ }
11
+ /**
12
+ * Set authentication token
13
+ */
14
+ setAuthToken(token) {
15
+ this.core.setAuthToken(token);
16
+ }
17
+ /**
18
+ * Search for tools
19
+ */
20
+ async searchTools(query, options) {
21
+ const searchOptions = {
22
+ query,
23
+ limit: options?.limit,
24
+ tags: options?.tags,
25
+ author: options?.author,
26
+ };
27
+ return await this.core.searchTools(searchOptions);
28
+ }
29
+ /**
30
+ * Get a specific tool by name
31
+ */
32
+ async getToolInfo(name) {
33
+ return await this.core.getToolByName(name);
34
+ }
35
+ /**
36
+ * Execute a tool by name
37
+ */
38
+ async executeToolByName(name, inputs = {}, options) {
39
+ const executeOptions = {
40
+ timeout: options?.timeout,
41
+ verifyPolicy: options?.verifyPolicy,
42
+ skipVerification: options?.skipVerification,
43
+ force: options?.force,
44
+ dryRun: options?.dryRun,
45
+ };
46
+ return await this.core.executeToolByName(name, inputs, executeOptions);
47
+ }
48
+ /**
49
+ * Execute a tool from raw YAML definition
50
+ */
51
+ async executeRawTool(toolYaml, inputs = {}, options) {
52
+ const executeOptions = {
53
+ timeout: options?.timeout,
54
+ skipVerification: options?.skipVerification,
55
+ force: options?.force,
56
+ dryRun: options?.dryRun,
57
+ };
58
+ return await this.core.executeRawTool(toolYaml, inputs, executeOptions);
59
+ }
60
+ /**
61
+ * Verify a tool's signature
62
+ */
63
+ async verifyTool(name, policy) {
64
+ return await this.core.verifyTool(name, policy);
65
+ }
66
+ /**
67
+ * Check if a tool exists
68
+ */
69
+ async toolExists(name) {
70
+ return await this.core.toolExists(name);
71
+ }
72
+ /**
73
+ * Get tools by tags
74
+ */
75
+ async getToolsByTags(tags, limit = 20) {
76
+ return await this.core.getToolsByTags(tags, limit);
77
+ }
78
+ /**
79
+ * Get tools by author
80
+ */
81
+ async getToolsByAuthor(author, limit = 20) {
82
+ return await this.core.getToolsByAuthor(author, limit);
83
+ }
84
+ /**
85
+ * Get all tools with filters
86
+ */
87
+ async getTools(options) {
88
+ return await this.core.getTools(options);
89
+ }
90
+ /**
91
+ * Get authentication status
92
+ */
93
+ async getAuthStatus() {
94
+ return await this.core.getAuthStatus();
95
+ }
96
+ /**
97
+ * Check if service is available (always true for core service)
98
+ */
99
+ async isAvailable() {
100
+ return true;
101
+ }
102
+ /**
103
+ * Get service path info (not applicable for core service)
104
+ */
105
+ async getPathInfo() {
106
+ return {
107
+ detectedPath: "core-library",
108
+ isAvailable: true,
109
+ version: "2.0.0-core",
110
+ };
111
+ }
112
+ /**
113
+ * Publish a tool (requires authentication)
114
+ */
115
+ async publishTool(tool) {
116
+ return await this.core.publishTool(tool);
117
+ }
118
+ }
119
+ // Create and export singleton instance
120
+ export const mcpCoreService = new McpCoreService();
@@ -0,0 +1 @@
1
+ export * from './McpCoreService';
@@ -0,0 +1 @@
1
+ export * from './McpCoreService';
@@ -0,0 +1,130 @@
1
+ export interface EnactTool {
2
+ name: string;
3
+ description: string;
4
+ command: string;
5
+ timeout?: string;
6
+ tags?: string[];
7
+ license?: string;
8
+ outputSchema?: JSONSchemaDefinition;
9
+ enact?: string;
10
+ version?: string;
11
+ namespace?: string;
12
+ resources?: {
13
+ memory?: string;
14
+ gpu?: string;
15
+ disk?: string;
16
+ };
17
+ env?: Record<string, {
18
+ description: string;
19
+ source: string;
20
+ required: boolean;
21
+ default?: string;
22
+ }>;
23
+ inputSchema?: JSONSchemaDefinition;
24
+ doc?: string;
25
+ authors?: Array<{
26
+ name: string;
27
+ email?: string;
28
+ url?: string;
29
+ }>;
30
+ examples?: Array<{
31
+ input: Record<string, any>;
32
+ output?: any;
33
+ description?: string;
34
+ }>;
35
+ annotations?: {
36
+ title?: string;
37
+ readOnlyHint?: boolean;
38
+ destructiveHint?: boolean;
39
+ idempotentHint?: boolean;
40
+ openWorldHint?: boolean;
41
+ };
42
+ signature?: {
43
+ algorithm: string;
44
+ type: string;
45
+ signer: string;
46
+ created: string;
47
+ value: string;
48
+ role?: string;
49
+ };
50
+ signatures?: Record<string, {
51
+ algorithm: string;
52
+ type: string;
53
+ signer: string;
54
+ created: string;
55
+ value: string;
56
+ role?: string;
57
+ }>;
58
+ [key: string]: any;
59
+ }
60
+ export interface JSONSchemaDefinition {
61
+ type?: string | string[];
62
+ description?: string;
63
+ format?: string;
64
+ default?: any;
65
+ enum?: any[];
66
+ const?: any;
67
+ pattern?: string;
68
+ minLength?: number;
69
+ maxLength?: number;
70
+ minimum?: number;
71
+ maximum?: number;
72
+ exclusiveMinimum?: number;
73
+ exclusiveMaximum?: number;
74
+ multipleOf?: number;
75
+ items?: JSONSchemaDefinition | JSONSchemaDefinition[];
76
+ minItems?: number;
77
+ maxItems?: number;
78
+ uniqueItems?: boolean;
79
+ properties?: Record<string, JSONSchemaDefinition>;
80
+ required?: string[];
81
+ additionalProperties?: JSONSchemaDefinition | boolean;
82
+ allOf?: JSONSchemaDefinition[];
83
+ anyOf?: JSONSchemaDefinition[];
84
+ oneOf?: JSONSchemaDefinition[];
85
+ not?: JSONSchemaDefinition;
86
+ definitions?: Record<string, JSONSchemaDefinition>;
87
+ $ref?: string;
88
+ $id?: string;
89
+ $schema?: string;
90
+ [key: string]: any;
91
+ }
92
+ export interface ExecutionResult {
93
+ success: boolean;
94
+ output?: any;
95
+ error?: {
96
+ message: string;
97
+ code?: string;
98
+ details?: any;
99
+ };
100
+ metadata: {
101
+ executionId: string;
102
+ toolName: string;
103
+ version?: string;
104
+ executedAt: string;
105
+ environment: string;
106
+ timeout?: string;
107
+ command?: string;
108
+ };
109
+ }
110
+ export interface ExecutionEnvironment {
111
+ vars: Record<string, any>;
112
+ resources?: {
113
+ memory?: string;
114
+ gpu?: string;
115
+ disk?: string;
116
+ timeout?: string;
117
+ };
118
+ namespace?: string;
119
+ }
120
+ export declare abstract class ExecutionProvider {
121
+ abstract setup(tool: EnactTool): Promise<boolean>;
122
+ abstract execute(tool: EnactTool, inputs: Record<string, any>, environment: ExecutionEnvironment): Promise<ExecutionResult>;
123
+ abstract cleanup(): Promise<boolean>;
124
+ abstract resolveEnvironmentVariables(envConfig: Record<string, any>, namespace?: string): Promise<Record<string, any>>;
125
+ abstract executeCommand(command: string, inputs: Record<string, any>, environment: ExecutionEnvironment, timeout?: string): Promise<{
126
+ stdout: string;
127
+ stderr: string;
128
+ exitCode: number;
129
+ }>;
130
+ }
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ // Updated execution provider interface
2
+ export class ExecutionProvider {
3
+ }
@@ -0,0 +1,32 @@
1
+ export interface EnactConfig {
2
+ defaultUrl?: string;
3
+ history?: string[];
4
+ }
5
+ /**
6
+ * Ensure config directory and file exist
7
+ */
8
+ export declare function ensureConfig(): Promise<void>;
9
+ /**
10
+ * Read the config file
11
+ */
12
+ export declare function readConfig(): Promise<EnactConfig>;
13
+ /**
14
+ * Write to the config file
15
+ */
16
+ export declare function writeConfig(config: EnactConfig): Promise<void>;
17
+ /**
18
+ * Add a file to the publish history
19
+ */
20
+ export declare function addToHistory(filePath: string): Promise<void>;
21
+ /**
22
+ * Get the publish history
23
+ */
24
+ export declare function getHistory(): Promise<string[]>;
25
+ /**
26
+ * Set the default publish URL
27
+ */
28
+ export declare function setDefaultUrl(url: string): Promise<void>;
29
+ /**
30
+ * Get the default publish URL
31
+ */
32
+ export declare function getDefaultUrl(): Promise<string | undefined>;
@@ -0,0 +1,78 @@
1
+ // src/utils/config.ts
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ import { existsSync } from "fs";
5
+ import { mkdir, readFile, writeFile } from "fs/promises";
6
+ // Define config paths
7
+ const CONFIG_DIR = join(homedir(), ".enact");
8
+ const CONFIG_FILE = join(CONFIG_DIR, "config.json");
9
+ /**
10
+ * Ensure config directory and file exist
11
+ */
12
+ export async function ensureConfig() {
13
+ if (!existsSync(CONFIG_DIR)) {
14
+ await mkdir(CONFIG_DIR, { recursive: true });
15
+ }
16
+ if (!existsSync(CONFIG_FILE)) {
17
+ await writeConfig({ history: [] });
18
+ }
19
+ }
20
+ /**
21
+ * Read the config file
22
+ */
23
+ export async function readConfig() {
24
+ await ensureConfig();
25
+ try {
26
+ const data = await readFile(CONFIG_FILE, "utf8");
27
+ return JSON.parse(data);
28
+ }
29
+ catch (error) {
30
+ console.error("Failed to read config:", error.message);
31
+ return { history: [] };
32
+ }
33
+ }
34
+ /**
35
+ * Write to the config file
36
+ */
37
+ export async function writeConfig(config) {
38
+ await ensureConfig();
39
+ await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2));
40
+ }
41
+ /**
42
+ * Add a file to the publish history
43
+ */
44
+ export async function addToHistory(filePath) {
45
+ const config = await readConfig();
46
+ if (!config.history) {
47
+ config.history = [];
48
+ }
49
+ // Add to history if not already there
50
+ if (!config.history.includes(filePath)) {
51
+ config.history.unshift(filePath);
52
+ // Keep history to a reasonable size
53
+ config.history = config.history.slice(0, 10);
54
+ await writeConfig(config);
55
+ }
56
+ }
57
+ /**
58
+ * Get the publish history
59
+ */
60
+ export async function getHistory() {
61
+ const config = await readConfig();
62
+ return config.history || [];
63
+ }
64
+ /**
65
+ * Set the default publish URL
66
+ */
67
+ export async function setDefaultUrl(url) {
68
+ const config = await readConfig();
69
+ config.defaultUrl = url;
70
+ await writeConfig(config);
71
+ }
72
+ /**
73
+ * Get the default publish URL
74
+ */
75
+ export async function getDefaultUrl() {
76
+ const config = await readConfig();
77
+ return config.defaultUrl;
78
+ }