@enactprotocol/shared 1.2.13 → 2.0.1

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 (207) hide show
  1. package/README.md +44 -0
  2. package/dist/config.d.ts +164 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +386 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/constants.d.ts +15 -5
  7. package/dist/constants.d.ts.map +1 -0
  8. package/dist/constants.js +24 -8
  9. package/dist/constants.js.map +1 -0
  10. package/dist/execution/command.d.ts +102 -0
  11. package/dist/execution/command.d.ts.map +1 -0
  12. package/dist/execution/command.js +262 -0
  13. package/dist/execution/command.js.map +1 -0
  14. package/dist/execution/index.d.ts +12 -0
  15. package/dist/execution/index.d.ts.map +1 -0
  16. package/dist/execution/index.js +17 -0
  17. package/dist/execution/index.js.map +1 -0
  18. package/dist/execution/runtime.d.ts +82 -0
  19. package/dist/execution/runtime.d.ts.map +1 -0
  20. package/dist/execution/runtime.js +273 -0
  21. package/dist/execution/runtime.js.map +1 -0
  22. package/dist/execution/types.d.ts +306 -0
  23. package/dist/execution/types.d.ts.map +1 -0
  24. package/dist/execution/types.js +14 -0
  25. package/dist/execution/types.js.map +1 -0
  26. package/dist/execution/validation.d.ts +43 -0
  27. package/dist/execution/validation.d.ts.map +1 -0
  28. package/dist/execution/validation.js +430 -0
  29. package/dist/execution/validation.js.map +1 -0
  30. package/dist/index.d.ts +21 -21
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +49 -25
  33. package/dist/index.js.map +1 -0
  34. package/dist/manifest/index.d.ts +7 -0
  35. package/dist/manifest/index.d.ts.map +1 -0
  36. package/dist/manifest/index.js +10 -0
  37. package/dist/manifest/index.js.map +1 -0
  38. package/dist/manifest/loader.d.ts +76 -0
  39. package/dist/manifest/loader.d.ts.map +1 -0
  40. package/dist/manifest/loader.js +146 -0
  41. package/dist/manifest/loader.js.map +1 -0
  42. package/dist/manifest/parser.d.ts +64 -0
  43. package/dist/manifest/parser.d.ts.map +1 -0
  44. package/dist/manifest/parser.js +135 -0
  45. package/dist/manifest/parser.js.map +1 -0
  46. package/dist/manifest/validator.d.ts +95 -0
  47. package/dist/manifest/validator.d.ts.map +1 -0
  48. package/dist/manifest/validator.js +258 -0
  49. package/dist/manifest/validator.js.map +1 -0
  50. package/dist/paths.d.ts +57 -0
  51. package/dist/paths.d.ts.map +1 -0
  52. package/dist/paths.js +93 -0
  53. package/dist/paths.js.map +1 -0
  54. package/dist/registry.d.ts +73 -0
  55. package/dist/registry.d.ts.map +1 -0
  56. package/dist/registry.js +147 -0
  57. package/dist/registry.js.map +1 -0
  58. package/dist/resolver.d.ts +89 -0
  59. package/dist/resolver.d.ts.map +1 -0
  60. package/dist/resolver.js +282 -0
  61. package/dist/resolver.js.map +1 -0
  62. package/dist/types/index.d.ts +6 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/index.js +5 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/dist/types/manifest.d.ts +201 -0
  67. package/dist/types/manifest.d.ts.map +1 -0
  68. package/dist/types/manifest.js +13 -0
  69. package/dist/types/manifest.js.map +1 -0
  70. package/dist/types.d.ts +5 -132
  71. package/dist/types.d.ts.map +1 -0
  72. package/dist/types.js +5 -3
  73. package/dist/types.js.map +1 -0
  74. package/dist/utils/fs.d.ts +105 -0
  75. package/dist/utils/fs.d.ts.map +1 -0
  76. package/dist/utils/fs.js +233 -0
  77. package/dist/utils/fs.js.map +1 -0
  78. package/dist/utils/logger.d.ts +102 -25
  79. package/dist/utils/logger.d.ts.map +1 -0
  80. package/dist/utils/logger.js +214 -57
  81. package/dist/utils/logger.js.map +1 -0
  82. package/dist/utils/version.d.ts +60 -2
  83. package/dist/utils/version.d.ts.map +1 -0
  84. package/dist/utils/version.js +255 -31
  85. package/dist/utils/version.js.map +1 -0
  86. package/package.json +16 -58
  87. package/src/config.ts +510 -0
  88. package/src/constants.ts +36 -0
  89. package/src/execution/command.ts +314 -0
  90. package/src/execution/index.ts +73 -0
  91. package/src/execution/runtime.ts +308 -0
  92. package/src/execution/types.ts +379 -0
  93. package/src/execution/validation.ts +508 -0
  94. package/src/index.ts +238 -30
  95. package/src/manifest/index.ts +36 -0
  96. package/src/manifest/loader.ts +187 -0
  97. package/src/manifest/parser.ts +173 -0
  98. package/src/manifest/validator.ts +309 -0
  99. package/src/paths.ts +108 -0
  100. package/src/registry.ts +219 -0
  101. package/src/resolver.ts +345 -0
  102. package/src/types/index.ts +30 -0
  103. package/src/types/manifest.ts +255 -0
  104. package/src/types.ts +5 -188
  105. package/src/utils/fs.ts +281 -0
  106. package/src/utils/logger.ts +270 -59
  107. package/src/utils/version.ts +304 -36
  108. package/tests/config.test.ts +515 -0
  109. package/tests/execution/command.test.ts +317 -0
  110. package/tests/execution/validation.test.ts +384 -0
  111. package/tests/fixtures/invalid-tool.yaml +4 -0
  112. package/tests/fixtures/valid-tool.md +62 -0
  113. package/tests/fixtures/valid-tool.yaml +40 -0
  114. package/tests/index.test.ts +8 -0
  115. package/tests/manifest/loader.test.ts +291 -0
  116. package/tests/manifest/parser.test.ts +345 -0
  117. package/tests/manifest/validator.test.ts +394 -0
  118. package/tests/manifest-types.test.ts +358 -0
  119. package/tests/paths.test.ts +153 -0
  120. package/tests/registry.test.ts +231 -0
  121. package/tests/resolver.test.ts +272 -0
  122. package/tests/utils/fs.test.ts +388 -0
  123. package/tests/utils/logger.test.ts +480 -0
  124. package/tests/utils/version.test.ts +390 -0
  125. package/tsconfig.json +12 -0
  126. package/dist/LocalToolResolver.d.ts +0 -84
  127. package/dist/LocalToolResolver.js +0 -353
  128. package/dist/api/enact-api.d.ts +0 -130
  129. package/dist/api/enact-api.js +0 -428
  130. package/dist/api/index.d.ts +0 -2
  131. package/dist/api/index.js +0 -2
  132. package/dist/api/types.d.ts +0 -103
  133. package/dist/api/types.js +0 -1
  134. package/dist/core/DaggerExecutionProvider.d.ts +0 -169
  135. package/dist/core/DaggerExecutionProvider.js +0 -1029
  136. package/dist/core/DirectExecutionProvider.d.ts +0 -23
  137. package/dist/core/DirectExecutionProvider.js +0 -406
  138. package/dist/core/EnactCore.d.ts +0 -162
  139. package/dist/core/EnactCore.js +0 -597
  140. package/dist/core/NativeExecutionProvider.d.ts +0 -9
  141. package/dist/core/NativeExecutionProvider.js +0 -16
  142. package/dist/core/index.d.ts +0 -3
  143. package/dist/core/index.js +0 -3
  144. package/dist/exec/index.d.ts +0 -3
  145. package/dist/exec/index.js +0 -3
  146. package/dist/exec/logger.d.ts +0 -11
  147. package/dist/exec/logger.js +0 -57
  148. package/dist/exec/validate.d.ts +0 -5
  149. package/dist/exec/validate.js +0 -167
  150. package/dist/lib/enact-direct.d.ts +0 -150
  151. package/dist/lib/enact-direct.js +0 -159
  152. package/dist/lib/index.d.ts +0 -1
  153. package/dist/lib/index.js +0 -1
  154. package/dist/security/index.d.ts +0 -3
  155. package/dist/security/index.js +0 -3
  156. package/dist/security/security.d.ts +0 -23
  157. package/dist/security/security.js +0 -137
  158. package/dist/security/sign.d.ts +0 -103
  159. package/dist/security/sign.js +0 -666
  160. package/dist/security/verification-enforcer.d.ts +0 -53
  161. package/dist/security/verification-enforcer.js +0 -204
  162. package/dist/services/McpCoreService.d.ts +0 -98
  163. package/dist/services/McpCoreService.js +0 -124
  164. package/dist/services/index.d.ts +0 -1
  165. package/dist/services/index.js +0 -1
  166. package/dist/utils/config.d.ts +0 -111
  167. package/dist/utils/config.js +0 -342
  168. package/dist/utils/env-loader.d.ts +0 -54
  169. package/dist/utils/env-loader.js +0 -270
  170. package/dist/utils/help.d.ts +0 -36
  171. package/dist/utils/help.js +0 -248
  172. package/dist/utils/index.d.ts +0 -7
  173. package/dist/utils/index.js +0 -7
  174. package/dist/utils/silent-monitor.d.ts +0 -67
  175. package/dist/utils/silent-monitor.js +0 -242
  176. package/dist/utils/timeout.d.ts +0 -5
  177. package/dist/utils/timeout.js +0 -23
  178. package/dist/web/env-manager-server.d.ts +0 -29
  179. package/dist/web/env-manager-server.js +0 -367
  180. package/dist/web/index.d.ts +0 -1
  181. package/dist/web/index.js +0 -1
  182. package/src/LocalToolResolver.ts +0 -424
  183. package/src/api/enact-api.ts +0 -604
  184. package/src/api/index.ts +0 -2
  185. package/src/api/types.ts +0 -114
  186. package/src/core/DaggerExecutionProvider.ts +0 -1357
  187. package/src/core/DirectExecutionProvider.ts +0 -484
  188. package/src/core/EnactCore.ts +0 -847
  189. package/src/core/index.ts +0 -3
  190. package/src/exec/index.ts +0 -3
  191. package/src/exec/logger.ts +0 -63
  192. package/src/exec/validate.ts +0 -238
  193. package/src/lib/enact-direct.ts +0 -254
  194. package/src/lib/index.ts +0 -1
  195. package/src/services/McpCoreService.ts +0 -201
  196. package/src/services/index.ts +0 -1
  197. package/src/utils/config.ts +0 -438
  198. package/src/utils/env-loader.ts +0 -370
  199. package/src/utils/help.ts +0 -257
  200. package/src/utils/index.ts +0 -7
  201. package/src/utils/silent-monitor.ts +0 -328
  202. package/src/utils/timeout.ts +0 -26
  203. package/src/web/env-manager-server.ts +0 -465
  204. package/src/web/index.ts +0 -1
  205. package/src/web/static/app.js +0 -663
  206. package/src/web/static/index.html +0 -117
  207. package/src/web/static/style.css +0 -291
@@ -1,484 +0,0 @@
1
- // src/core/DirectExecutionProvider.ts - Direct execution provider that doesn't use external CLI
2
- import { spawn } from "child_process";
3
- import {
4
- ExecutionProvider,
5
- type EnactTool,
6
- type ExecutionEnvironment,
7
- type ExecutionResult,
8
- } from "../types.js";
9
- import logger from "../exec/logger.js";
10
- import { parseTimeout } from "../utils/timeout.js";
11
-
12
- export class DirectExecutionProvider extends ExecutionProvider {
13
- async resolveEnvironmentVariables(
14
- envConfig: Record<string, any>,
15
- namespace?: string,
16
- ): Promise<Record<string, any>> {
17
- const resolved: Record<string, any> = {};
18
-
19
- for (const [key, config] of Object.entries(envConfig)) {
20
- if (typeof config === "object" && config.source) {
21
- // Handle different sources
22
- switch (config.source) {
23
- case "env":
24
- resolved[key] = process.env[key] || config.default;
25
- break;
26
- case "user":
27
- // Could get from user config file
28
- resolved[key] = config.default;
29
- break;
30
- default:
31
- resolved[key] = config.default;
32
- }
33
- } else {
34
- // Direct value
35
- resolved[key] = config;
36
- }
37
- }
38
-
39
- return resolved;
40
- }
41
-
42
- async executeCommand(
43
- command: string,
44
- inputs: Record<string, any>,
45
- environment: ExecutionEnvironment,
46
- timeout?: string,
47
- options?: {
48
- verbose?: boolean;
49
- showSpinner?: boolean;
50
- streamOutput?: boolean;
51
- },
52
- ): Promise<{ stdout: string; stderr: string; exitCode: number }> {
53
- return new Promise((resolve, reject) => {
54
- let stdout = "";
55
- let stderr = "";
56
-
57
- // UI Setup
58
- const verbose = options?.verbose ?? false;
59
- const showSpinner = options?.showSpinner ?? false;
60
- const streamOutput = options?.streamOutput ?? true;
61
-
62
- let spinner: any = null;
63
-
64
- if (showSpinner) {
65
- // Dynamic import to avoid dependency issues when not needed
66
- try {
67
- const p = require("@clack/prompts");
68
- spinner = p.spinner();
69
- spinner.start("Executing tool...");
70
- } catch (e) {
71
- // Fallback if @clack/prompts not available
72
- console.log("Executing tool...");
73
- }
74
- }
75
-
76
- if (verbose) {
77
- try {
78
- const pc = require("picocolors");
79
- console.error(pc.cyan("\n🚀 Executing command:"));
80
- console.error(pc.white(command));
81
- } catch (e) {
82
- console.error("\n🚀 Executing command:");
83
- console.error(command);
84
- }
85
- }
86
-
87
- // Substitute template variables in command with input values
88
- let substitutedCommand = command;
89
- for (const [key, value] of Object.entries(inputs)) {
90
- const templateVar = `\${${key}}`;
91
- // Handle different value types
92
- let substitutionValue: string;
93
- if (typeof value === "string") {
94
- substitutionValue = value;
95
- } else if (typeof value === "object") {
96
- substitutionValue = JSON.stringify(value);
97
- } else {
98
- substitutionValue = String(value);
99
- }
100
- substitutedCommand = substitutedCommand.replace(
101
- new RegExp(`\\$\\{${key}\\}`, "g"),
102
- substitutionValue,
103
- );
104
- }
105
-
106
- // Prepare environment
107
- const env = {
108
- ...process.env,
109
- ...environment.vars,
110
- };
111
-
112
- // Parse command and arguments properly handling quoted strings
113
- const commandParts = this.parseCommand(substitutedCommand);
114
- const cmd = commandParts[0];
115
- const args = commandParts.slice(1);
116
-
117
- logger.info(`Executing command: ${command}`);
118
-
119
- try {
120
- const proc = spawn(cmd, args, {
121
- env,
122
- stdio: ["pipe", "pipe", "pipe"],
123
- // Create a new process group for better cleanup of child processes
124
- detached: process.platform !== "win32",
125
- });
126
-
127
- // Cleanup function to ensure process and children are properly terminated
128
- let isCleanedUp = false;
129
- let cleanupTimer: ReturnType<typeof setTimeout> | null = null;
130
-
131
- const cleanup = () => {
132
- if (isCleanedUp) return;
133
- isCleanedUp = true;
134
-
135
- // Clear any pending cleanup timer
136
- if (cleanupTimer) {
137
- clearTimeout(cleanupTimer);
138
- cleanupTimer = null;
139
- }
140
-
141
- if (proc && !proc.killed) {
142
- try {
143
- logger.debug(`Cleaning up process PID: ${proc.pid}`);
144
- // For Dagger and other tools that may spawn child processes
145
- if (process.platform === "win32") {
146
- proc.kill("SIGKILL");
147
- } else {
148
- // Try graceful termination first
149
- proc.kill("SIGTERM");
150
- // Set a cleanup timer for force kill if needed
151
- cleanupTimer = setTimeout(() => { if (!proc.killed && !isCleanedUp) {
152
- logger.debug(
153
- `Force killing process PID: ${proc.pid}`,
154
- );
155
- try {
156
- proc.kill("SIGKILL");
157
- } catch (killError) {
158
- // Process might already be dead, ignore
159
- logger.debug(
160
- `Force kill error (likely harmless): ${killError}`,
161
- );
162
- }
163
- }
164
- cleanupTimer = null;
165
- }, 1000); // Reduced from 2000ms to 1000ms
166
- }
167
- } catch (killError) {
168
- // Process might already be dead, ignore
169
- logger.debug(
170
- `Process cleanup error (likely harmless): ${killError}`,
171
- );
172
- }
173
- }
174
- };
175
-
176
- // Collect stdout and stream it in real-time
177
- proc.stdout.on("data", (data: Buffer) => {
178
- const chunk = data.toString();
179
- stdout += chunk;
180
- // Stream stdout to console in real-time if enabled
181
- if (streamOutput) {
182
- process.stdout.write(chunk);
183
- }
184
- });
185
-
186
- // Collect stderr and stream it in real-time
187
- proc.stderr.on("data", (data: Buffer) => {
188
- const chunk = data.toString();
189
- stderr += chunk;
190
- // Stream stderr to console in real-time if enabled
191
- if (streamOutput) {
192
- process.stderr.write(chunk);
193
- }
194
- });
195
- // Handle process completion with more robust cleanup
196
- proc.on("close", (code: number) => {
197
- logger.debug(
198
- `Process closed with code: ${code}, PID: ${proc.pid}`,
199
- );
200
- // Force cleanup any remaining resources
201
- cleanup();
202
-
203
- // Handle spinner cleanup and success/error messaging
204
- if (spinner) {
205
- spinner.stop("Execution completed");
206
- }
207
-
208
- if (code === 0) {
209
- if (showSpinner || verbose) {
210
- try {
211
- const pc = require("picocolors");
212
- console.error(pc.green("\n✅ Tool executed successfully"));
213
- if (stdout.trim() && !streamOutput) {
214
- console.error(pc.cyan("\n📤 Output:"));
215
- console.error(stdout.trim());
216
- }
217
- } catch (e) {
218
- console.error("\n✅ Tool executed successfully");
219
- if (stdout.trim() && !streamOutput) {
220
- console.error("\n📤 Output:");
221
- console.error(stdout.trim());
222
- }
223
- }
224
- }
225
- } else {
226
- if (showSpinner || verbose) {
227
- try {
228
- const pc = require("picocolors");
229
- console.error(
230
- pc.red(`\n❌ Tool execution failed (exit code: ${code})`),
231
- );
232
- if (stderr.trim() && !streamOutput) {
233
- console.error(pc.red("\n📤 Error output:"));
234
- console.error(stderr.trim());
235
- }
236
- if (stdout.trim() && !streamOutput) {
237
- console.error(pc.yellow("\n📤 Standard output:"));
238
- console.error(stdout.trim());
239
- }
240
- } catch (e) {
241
- console.error(
242
- `\n❌ Tool execution failed (exit code: ${code})`,
243
- );
244
- if (stderr.trim() && !streamOutput) {
245
- console.error("\n📤 Error output:");
246
- console.error(stderr.trim());
247
- }
248
- if (stdout.trim() && !streamOutput) {
249
- console.error("\n📤 Standard output:");
250
- console.error(stdout.trim());
251
- }
252
- }
253
- }
254
- }
255
-
256
- resolve({
257
- stdout: stdout.trim(),
258
- stderr: stderr.trim(),
259
- exitCode: code || 0,
260
- });
261
- });
262
-
263
- // Handle process errors
264
- proc.on("error", (error: Error) => {
265
- cleanup();
266
- if (spinner) {
267
- spinner.stop("Execution failed");
268
- }
269
-
270
- if (showSpinner || verbose) {
271
- try {
272
- const pc = require("picocolors");
273
- console.error(
274
- pc.red(`\n❌ Failed to execute command: ${error.message}`),
275
- );
276
- } catch (e) {
277
- console.error(`\n❌ Failed to execute command: ${error.message}`);
278
- }
279
- }
280
-
281
- reject(new Error(`Command execution error: ${error.message}`));
282
- });
283
-
284
- // Set timeout if specified
285
- if (timeout) {
286
- const timeoutMs = parseTimeout(timeout);
287
- setTimeout(() => {
288
- cleanup();
289
- if (spinner) {
290
- spinner.stop("Execution failed");
291
- }
292
- reject(new Error(`Command timed out after ${timeout}`));
293
- }, timeoutMs);
294
- }
295
- } catch (spawnError) {
296
- reject(new Error(`Failed to spawn command: ${spawnError}`));
297
- }
298
- });
299
- }
300
-
301
- /**
302
- * Execute command with exec.ts compatible interface
303
- * This method provides the same interface as the exec.ts executeCommand function
304
- */
305
- async executeCommandExecStyle(
306
- command: string,
307
- timeout: string,
308
- verbose: boolean = false,
309
- envVars: Record<string, string> = {},
310
- ): Promise<void> {
311
- const environment: ExecutionEnvironment = {
312
- vars: envVars,
313
- resources: { timeout },
314
- };
315
-
316
- const result = await this.executeCommand(
317
- command,
318
- {}, // No template substitution needed for this interface
319
- environment,
320
- timeout,
321
- {
322
- verbose,
323
- showSpinner: true,
324
- streamOutput: false, // Don't stream since exec.ts shows output at the end
325
- },
326
- );
327
-
328
- if (result.exitCode !== 0) {
329
- throw new Error(`Command failed with exit code ${result.exitCode}`);
330
- }
331
- }
332
-
333
- async setup(tool: EnactTool): Promise<boolean> {
334
- // No special setup needed for direct execution
335
- logger.debug(`Setting up direct execution for tool: ${tool.name}`);
336
- return true;
337
- }
338
-
339
- async execute(
340
- tool: EnactTool,
341
- inputs: Record<string, any>,
342
- environment: ExecutionEnvironment,
343
- ): Promise<ExecutionResult> {
344
- const executionId = this.generateExecutionId();
345
- const timeout = tool.timeout || environment.resources?.timeout;
346
-
347
- // Substitute template variables in command with input values
348
- let substitutedCommand = tool.command;
349
- for (const [key, value] of Object.entries(inputs)) {
350
- const templateVar = `\${${key}}`;
351
- // Handle different value types
352
- let substitutionValue: string;
353
- if (typeof value === "string") {
354
- substitutionValue = value;
355
- } else if (typeof value === "object") {
356
- substitutionValue = JSON.stringify(value);
357
- } else {
358
- substitutionValue = String(value);
359
- }
360
- substitutedCommand = substitutedCommand.replace(
361
- new RegExp(`\\$\\{${key}\\}`, "g"),
362
- substitutionValue,
363
- );
364
- }
365
-
366
- try {
367
- // Execute the command
368
- const result = await this.executeCommand(
369
- substitutedCommand,
370
- inputs,
371
- environment,
372
- timeout,
373
- );
374
-
375
- // Parse output
376
- let parsedOutput: any;
377
- try {
378
- // Try to parse as JSON first
379
- parsedOutput = JSON.parse(result.stdout);
380
- } catch {
381
- // If not JSON, return structured output
382
- parsedOutput = {
383
- stdout: result.stdout,
384
- stderr: result.stderr,
385
- };
386
- }
387
-
388
- return {
389
- success: result.exitCode === 0,
390
- output: parsedOutput,
391
- ...(result.exitCode !== 0 && {
392
- error: {
393
- message: `Command failed with exit code ${result.exitCode}`,
394
- code: "COMMAND_FAILED",
395
- details: {
396
- stdout: result.stdout,
397
- stderr: result.stderr,
398
- command: substitutedCommand, // Show the substituted command
399
- exitCode: result.exitCode,
400
- },
401
- },
402
- }),
403
- metadata: {
404
- executionId,
405
- toolName: tool.name,
406
- version: tool.version,
407
- executedAt: new Date().toISOString(),
408
- environment: "direct",
409
- timeout,
410
- command: substitutedCommand, // Show the substituted command in metadata
411
- },
412
- };
413
- } catch (error) {
414
- return {
415
- success: false,
416
- error: {
417
- message: (error as Error).message,
418
- code: "EXECUTION_ERROR",
419
- details: error,
420
- },
421
- metadata: {
422
- executionId,
423
- toolName: tool.name,
424
- version: tool.version,
425
- executedAt: new Date().toISOString(),
426
- environment: "direct",
427
- },
428
- };
429
- }
430
- }
431
-
432
- async cleanup(): Promise<boolean> {
433
- // No cleanup needed for direct execution
434
- return true;
435
- }
436
-
437
- private generateExecutionId(): string {
438
- return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
439
- }
440
-
441
- private parseCommand(command: string): string[] {
442
- const parts: string[] = [];
443
- let current = "";
444
- let inQuotes = false;
445
- let quoteChar = "";
446
- let i = 0;
447
-
448
- while (i < command.length) {
449
- const char = command[i];
450
-
451
- if (!inQuotes && (char === '"' || char === "'")) {
452
- // Start of quoted section
453
- inQuotes = true;
454
- quoteChar = char;
455
- } else if (inQuotes && char === quoteChar) {
456
- // End of quoted section
457
- inQuotes = false;
458
- quoteChar = "";
459
- } else if (!inQuotes && char === " ") {
460
- // Space outside quotes - end current part
461
- if (current.length > 0) {
462
- parts.push(current);
463
- current = "";
464
- }
465
- // Skip whitespace
466
- while (i + 1 < command.length && command[i + 1] === " ") {
467
- i++;
468
- }
469
- } else {
470
- // Regular character or space inside quotes
471
- current += char;
472
- }
473
-
474
- i++;
475
- }
476
-
477
- // Add the last part if it exists
478
- if (current.length > 0) {
479
- parts.push(current);
480
- }
481
-
482
- return parts;
483
- }
484
- }