MCPcopy
hub / github.com/coder/mux / streamCoderCommand

Function streamCoderCommand

src/node/services/coderService.ts:141–257  ·  view source on GitHub ↗

* Stream output from a coder CLI command line by line. * Yields lines as they arrive from stdout/stderr. * Throws on non-zero exit with stderr content in the error message. * * @param args Command arguments (e.g., ["start", "-y", "my-ws"]) * @param errorPrefix Prefix for error messages (e.g., "

(
  args: string[],
  errorPrefix: string,
  abortSignal?: AbortSignal,
  abortMessage = "Coder command aborted"
)

Source from the content-addressed store, hash-verified

139 * @param abortMessage Message to throw when aborted
140 */
141async function* streamCoderCommand(
142 args: string[],
143 errorPrefix: string,
144 abortSignal?: AbortSignal,
145 abortMessage = "Coder command aborted"
146): AsyncGenerator<string, void, unknown> {
147 if (abortSignal?.aborted) {
148 throw new Error(abortMessage);
149 }
150
151 // Yield the command we're about to run so it's visible in UI
152 yield `$ coder ${args.join(" ")}`;
153
154 const child = spawn("coder", args, {
155 stdio: ["ignore", "pipe", "pipe"],
156 });
157
158 const exitPromise = new Promise<number | null>((resolve) => {
159 child.on("close", resolve);
160 child.on("error", () => resolve(null));
161 });
162
163 const terminator = createGracefulTerminator(child);
164
165 const abortHandler = () => {
166 terminator.terminate();
167 };
168 abortSignal?.addEventListener("abort", abortHandler, { once: true });
169 if (abortSignal?.aborted) {
170 abortHandler();
171 }
172
173 try {
174 // Use an async queue to stream lines as they arrive
175 const lineQueue: string[] = [];
176 const stderrLines: string[] = [];
177 let streamsDone = false;
178 let resolveNext: (() => void) | null = null;
179
180 const pushLine = (line: string) => {
181 lineQueue.push(line);
182 if (resolveNext) {
183 resolveNext();
184 resolveNext = null;
185 }
186 };
187
188 let pending = 2;
189 const markDone = () => {
190 pending--;
191 if (pending === 0) {
192 streamsDone = true;
193 if (resolveNext) {
194 resolveNext();
195 resolveNext = null;
196 }
197 }
198 };

Callers 2

waitForStartupScriptsMethod · 0.85
createWorkspaceMethod · 0.85

Calls 8

createGracefulTerminatorFunction · 0.85
processStreamFunction · 0.85
onMethod · 0.80
removeEventListenerMethod · 0.80
resolveFunction · 0.70
abortHandlerFunction · 0.70
cleanupMethod · 0.65
addEventListenerMethod · 0.45

Tested by

no test coverage detected