import { CODEX_LINK_RESPONSE_BYTES, parseControlResponse, validateControlRequest } from '../codex-link-control' import type { CodexLinkControlResponse } from '../codex-link-control.types' import { type AiturkCliRunnerDeps, resolveAiturkCliPath } from './aiturk-login' type Dependencies = AiturkCliRunnerDeps // Only the fixed entrypoint and fixed arguments go through cmd.exe. All values travel on stdin. // eslint-disable-next-line no-control-regex -- Reject control bytes in executable paths before cmd parsing. const UNSAFE_PATH = /["%^!\u0000-\u001f]/ const ABSOLUTE_PATH = /^[A-Za-z]:\\/ export function createCodexLinkClient(deps: Dependencies) { const setTimer = deps.setTimer ?? ((fn, ms) => setTimeout(fn, ms)) const clearTimer = deps.clearTimer ?? (timer => clearTimeout(timer as ReturnType)) return async function control(raw: unknown): Promise { validateControlRequest(raw) const cli = resolveAiturkCliPath(deps) if (!cli) { throw new Error('codex-link:cli_unavailable') } const systemRoot = String(deps.env.SystemRoot || deps.env.SYSTEMROOT || 'C:\\Windows').replace(/[\\/]+$/, '') if (UNSAFE_PATH.test(cli) || UNSAFE_PATH.test(systemRoot) || !ABSOLUTE_PATH.test(systemRoot)) { throw new Error('codex-link:invalid_entrypoint') } return new Promise((resolve, reject) => { let settled = false let timer: unknown let bytes = 0 const chunks: Buffer[] = [] let child: any const finish = (error?: Error, response?: CodexLinkControlResponse) => { if (settled) { return } settled = true if (timer !== undefined) { clearTimer(timer) } error ? reject(error) : resolve(response!) } try { child = deps.spawn( `${systemRoot}\\System32\\cmd.exe`, ['/d', '/s', '/c', `""${cli}" codex-link control --stdin"`], { shell: false, windowsHide: true, windowsVerbatimArguments: true, stdio: ['pipe', 'pipe', 'pipe'] } ) } catch { finish(new Error('codex-link:cli_unavailable')) return } timer = setTimer(() => { // The durable manager may have accepted a write. Never repeat it under a new ID. finish(new Error('codex-link:outcome_unknown')) try { child.kill() } catch { /* proxy already exited; manager is independent */ } }, deps.timeoutMs ?? 30_000) child.stdout.on('data', (chunk: Buffer) => { if (settled) { return } bytes += chunk.length if (bytes > CODEX_LINK_RESPONSE_BYTES) { finish(new Error('codex-link:outcome_unknown')) try { child.kill() } catch { /* no process tree termination */ } } else { chunks.push(Buffer.from(chunk)) } }) // Drain concurrently, with no history, paths, credentials or uncontrolled diagnostics logged. child.stderr.on('data', () => {}) child.stdin.on('error', () => {}) child.once('error', () => finish(new Error('codex-link:outcome_unknown'))) child.once('close', (code: number | null) => { if (settled) { return } if (code !== 0 && code !== 1) { finish(new Error('codex-link:outcome_unknown')) return } try { const response = parseControlResponse(Buffer.concat(chunks), raw) if (code === 1 && response.kind !== 'control_error') { finish(new Error('codex-link:outcome_unknown')) } else { finish(undefined, response) } } catch { finish(new Error('codex-link:outcome_unknown')) } }) try { child.stdin.end(JSON.stringify(raw) + '\n') } catch { finish(new Error('codex-link:outcome_unknown')) } }) } }