#!/usr/bin/env node 'use strict'; const { spawn, spawnSync } = require('node:child_process'); const args = process.argv.slice(2); if (args.length === 0) { console.error('Usage: node scripts/run-python.js [args...]'); process.exit(1); } function uniqueCandidates(candidates) { const seen = new Set(); const unique = []; for (const candidate of candidates) { const key = candidate.join('\u0000'); if (!seen.has(key)) { seen.add(key); unique.push(candidate); } } return unique; } function getPythonCandidates() { // Optional override for CI/local pinning without editing scripts. const configuredPython = process.env.ANTIGRAVITY_PYTHON || process.env.npm_config_python; const candidates = [ configuredPython ? [configuredPython] : null, // Keep this ordered list easy to update if project requirements change. ['python3'], ['python'], ['py', '-3'], ].filter(Boolean); return uniqueCandidates(candidates); } function canRun(candidate) { const [command, ...baseArgs] = candidate; const probe = spawnSync( command, [...baseArgs, '-c', 'import sys; raise SystemExit(0 if sys.version_info[0] == 3 else 1)'], { stdio: 'ignore', shell: false, }, ); return probe.error == null && probe.status === 0; } const pythonCandidates = getPythonCandidates(); const selected = pythonCandidates.find(canRun); if (!selected) { console.error( 'Unable to find a Python 3 interpreter. Tried: python3, python, py -3', ); process.exit(1); } const [command, ...baseArgs] = selected; const child = spawn(command, [...baseArgs, ...args], { stdio: 'inherit', shell: false, }); child.on('error', (error) => { console.error(`Failed to start Python interpreter "${command}": ${error.message}`); process.exit(1); }); child.on('exit', (code, signal) => { if (signal) { try { process.kill(process.pid, signal); } catch { process.exit(1); } return; } process.exit(code ?? 1); });