| 48 | } |
| 49 | |
| 50 | public override async run(command: string) { |
| 51 | this.command = command |
| 52 | |
| 53 | const terminal = this.terminal.terminal |
| 54 | |
| 55 | const isShellIntegrationAvailable = terminal.shellIntegration && terminal.shellIntegration.executeCommand |
| 56 | |
| 57 | if (!isShellIntegrationAvailable) { |
| 58 | terminal.sendText(command, true) |
| 59 | |
| 60 | console.warn( |
| 61 | "[TerminalProcess] Shell integration not available. Command sent without knowledge of response.", |
| 62 | ) |
| 63 | |
| 64 | this.emit("no_shell_integration", { |
| 65 | message: "Command was submitted; output is not available, as shell integration is inactive.", |
| 66 | commandSubmitted: true, |
| 67 | }) |
| 68 | |
| 69 | this.emit( |
| 70 | "completed", |
| 71 | "<shell integration is not available, so terminal output and command execution status is unknown>", |
| 72 | ) |
| 73 | |
| 74 | this.emit("continue") |
| 75 | return |
| 76 | } |
| 77 | |
| 78 | // Create a promise that resolves when the stream becomes available |
| 79 | const streamAvailable = new Promise<AsyncIterable<string>>((resolve, reject) => { |
| 80 | const timeoutId = setTimeout(() => { |
| 81 | // Remove event listener to prevent memory leaks |
| 82 | this.removeAllListeners("stream_available") |
| 83 | |
| 84 | // Emit no_shell_integration event with descriptive message |
| 85 | this.emit("no_shell_integration", { |
| 86 | message: `VSCE shell integration stream did not start within ${Terminal.getShellIntegrationTimeout() / 1000} seconds. Terminal problem?`, |
| 87 | commandSubmitted: true, |
| 88 | }) |
| 89 | |
| 90 | // Reject with descriptive error |
| 91 | reject( |
| 92 | new Error( |
| 93 | `VSCE shell integration stream did not start within ${Terminal.getShellIntegrationTimeout() / 1000} seconds.`, |
| 94 | ), |
| 95 | ) |
| 96 | }, Terminal.getShellIntegrationTimeout()) |
| 97 | |
| 98 | // Clean up timeout if stream becomes available |
| 99 | this.once("stream_available", (stream: AsyncIterable<string>) => { |
| 100 | clearTimeout(timeoutId) |
| 101 | resolve(stream) |
| 102 | }) |
| 103 | }) |
| 104 | |
| 105 | // Create promise that resolves when shell execution completes for this terminal |
| 106 | const shellExecutionComplete = new Promise<ExitCodeDetails>((resolve) => { |
| 107 | this.once("shell_execution_complete", (details: ExitCodeDetails) => resolve(details)) |