MCPcopy
hub / github.com/lightningpixel/modly / PythonProcessRunner

Class PythonProcessRunner

electron/main/process-runner.ts:159–250  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

157// Protocol — stdout: JSON lines { type: 'progress'|'log'|'done'|'error', ... }
158
159export class PythonProcessRunner implements IProcessRunner {
160 private pythonExe: string
161 private scriptPath: string
162 private workspaceDir: string
163 private tempDir: string
164
165 constructor(pythonExe: string, extDir: string, entry: string, workspaceDir: string, tempDir: string) {
166 this.pythonExe = pythonExe
167 this.scriptPath = join(extDir, entry)
168 this.workspaceDir = workspaceDir
169 this.tempDir = tempDir
170 }
171
172 async run(
173 input: ProcessInput,
174 params: Record<string, unknown>,
175 onProgress?: (percent: number, label: string) => void,
176 onLog?: (message: string) => void,
177 ): Promise<ProcessResult> {
178 return new Promise((resolve, reject) => {
179 const proc = spawn(this.pythonExe, [this.scriptPath], {
180 stdio: ['pipe', 'pipe', 'pipe'],
181 })
182
183 // Send input as a single JSON line on stdin
184 proc.stdin.write(JSON.stringify({
185 input,
186 params,
187 nodeId: input.nodeId ?? '',
188 workspaceDir: this.workspaceDir,
189 tempDir: this.tempDir,
190 }) + '\n')
191 proc.stdin.end()
192
193 let stdoutBuf = ''
194 let resolved = false
195
196 proc.stdout.on('data', (chunk: Buffer) => {
197 stdoutBuf += chunk.toString()
198 const lines = stdoutBuf.split('\n')
199 stdoutBuf = lines.pop() ?? ''
200
201 for (const line of lines) {
202 const trimmed = line.trim()
203 if (!trimmed) continue
204 try {
205 const msg = JSON.parse(trimmed) as { type: string; percent?: number; label?: string; message?: string; result?: ProcessResult }
206 if (msg.type === 'progress') {
207 onProgress?.(msg.percent ?? 0, msg.label ?? '')
208 } else if (msg.type === 'log') {
209 onLog?.(msg.message ?? '')
210 } else if (msg.type === 'done') {
211 resolved = true
212 resolve(msg.result ?? {})
213 } else if (msg.type === 'error') {
214 resolved = true
215 reject(new Error(msg.message ?? 'Unknown error'))
216 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected