MCPcopy
hub / github.com/Fission-AI/OpenSpec / runCLI

Function runCLI

test/helpers/run-cli.ts:75–148  ·  view source on GitHub ↗
(args: string[] = [], options: RunCLIOptions = {})

Source from the content-addressed store, hash-verified

73}
74
75export async function runCLI(args: string[] = [], options: RunCLIOptions = {}): Promise<RunCLIResult> {
76 await ensureCliBuilt();
77
78 const finalArgs = Array.isArray(args) ? args : [args];
79 const invocation = [cliEntry, ...finalArgs].join(' ');
80
81 return new Promise<RunCLIResult>((resolve, reject) => {
82 const child = spawn(process.execPath, [cliEntry, ...finalArgs], {
83 cwd: options.cwd ?? projectRoot,
84 env: {
85 ...process.env,
86 OPEN_SPEC_INTERACTIVE: '0',
87 ...options.env,
88 },
89 stdio: ['pipe', 'pipe', 'pipe'],
90 windowsHide: true,
91 });
92
93 // Prevent child process from keeping the event loop alive
94 child.unref();
95
96 let stdout = '';
97 let stderr = '';
98 let timedOut = false;
99
100 const timeout = options.timeoutMs
101 ? setTimeout(() => {
102 timedOut = true;
103 child.kill('SIGKILL');
104 }, options.timeoutMs)
105 : undefined;
106
107 child.stdout?.setEncoding('utf-8');
108 child.stdout?.on('data', (chunk) => {
109 stdout += chunk;
110 });
111
112 child.stderr?.setEncoding('utf-8');
113 child.stderr?.on('data', (chunk) => {
114 stderr += chunk;
115 });
116
117 child.on('error', (error) => {
118 if (timeout) clearTimeout(timeout);
119 // Explicitly destroy streams to prevent hanging handles
120 child.stdout?.destroy();
121 child.stderr?.destroy();
122 child.stdin?.destroy();
123 reject(error);
124 });
125
126 child.on('close', (code, signal) => {
127 if (timeout) clearTimeout(timeout);
128 // Explicitly destroy streams to prevent hanging handles
129 child.stdout?.destroy();
130 child.stderr?.destroy();
131 child.stdin?.destroy();
132 resolve({

Calls 1

ensureCliBuiltFunction · 0.85

Tested by 2

createPlatformFunction · 0.68
createChangeFunction · 0.68