+75
| #!/usr/bin/env node | ||
| /** | ||
| * CodexCTL Runner - Downloads binary on first run if not present | ||
| */ | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| const os = require('os'); | ||
| const { spawn } = require('child_process'); | ||
| 'use strict'; | ||
| const VERSION = '0.4.4'; | ||
| const PLATFORMS = { | ||
| 'linux-x64': { url: 'codexctl-x86_64-unknown-linux-gnu.tar.gz', ext: '.tar.gz' }, | ||
| 'linux-arm64': { url: 'codexctl-aarch64-unknown-linux-gnu.tar.gz', ext: '.tar.gz' }, | ||
| 'darwin-x64': { url: 'codexctl-x86_64-apple-darwin.tar.gz', ext: '.tar.gz' }, | ||
| 'darwin-arm64': { url: 'codexctl-aarch64-apple-darwin.tar.gz', ext: '.tar.gz' }, | ||
| 'win32-x64': { url: 'codexctl-x86_64-pc-windows-msvc.zip', ext: '.zip' } | ||
| }; | ||
| function getPlatform() { | ||
| const key = `${os.platform()}-${os.arch()}`; | ||
| return PLATFORMS[key] || PLATFORMS['linux-x64']; | ||
| } | ||
| const binDir = path.join(__dirname, 'bin'); | ||
| const platform = getPlatform(); | ||
| const binName = platform.ext === '.zip' ? 'codexctl.exe' : 'codexctl'; | ||
| const binPath = path.join(binDir, binName); | ||
| async function download() { | ||
| if (!fs.existsSync(binDir)) fs.mkdirSync(binDir, { recursive: true }); | ||
| if (fs.existsSync(binPath)) return; | ||
| const https = require('https'); | ||
| const url = `https://github.com/repohelper/codexctl/releases/download/v${VERSION}/${platform.url}`; | ||
| console.log(`Downloading codexctl ${VERSION} for ${os.platform()}-${os.arch()}...`); | ||
| return new Promise((resolve, reject) => { | ||
| https.get(url, (res) => { | ||
| if (res.statusCode === 302 || res.statusCode === 301) { | ||
| download(res.headers.location).then(resolve).catch(reject); | ||
| return; | ||
| } | ||
| const file = fs.createWriteStream(path.join(binDir, 'download' + platform.ext)); | ||
| res.pipe(file); | ||
| file.on('finish', () => { | ||
| if (platform.ext === '.zip') { | ||
| const { execSync } = require('child_process'); | ||
| execSync(`powershell -Command "Expand-Archive -Path '${file.path}' -DestinationPath '${binDir}' -Force"`); | ||
| } else { | ||
| const { execSync } = require('child_process'); | ||
| execSync(`tar -xzf '${file.path}' -C '${binDir}'`); | ||
| } | ||
| fs.unlinkSync(file.path); | ||
| resolve(); | ||
| }); | ||
| }).on('error', reject); | ||
| }); | ||
| } | ||
| async function main() { | ||
| await download(); | ||
| if (os.platform() !== 'win32') { | ||
| try { fs.chmodSync(binPath, 0o755); } catch {} | ||
| } | ||
| const child = spawn(binPath, process.argv.slice(2), { stdio: 'inherit', windowsHide: true }); | ||
| child.on('exit', (code) => process.exit(code ?? 0)); | ||
| } | ||
| main().catch((err) => { console.error(err.message); process.exit(1); }); |
+4
-3
| { | ||
| "name": "codexctl", | ||
| "version": "0.4.4", | ||
| "version": "0.4.5", | ||
| "description": "Codex CLI Profile Manager - Manage multiple AI CLI accounts", | ||
| "main": "index.js", | ||
| "bin": { | ||
| "codexctl": "./run.js", | ||
| "cdx": "./run.js" | ||
| "codexctl": "./codexctl.js", | ||
| "cdx": "./codexctl.js" | ||
| }, | ||
@@ -29,2 +29,3 @@ "scripts": { | ||
| "run.js", | ||
| "codexctl.js", | ||
| "index.js", | ||
@@ -31,0 +32,0 @@ "README.md", |
8061
47.8%6
20%127
92.42%3
50%8
100%