Lines 1-104javascript
2const { spawnSync } = require('child_process')
3const { join } = require('path')
4const { existsSync, mkdirSync, createWriteStream } = require('fs')
5const https = require('https')
6const os = require('os')
8const REPO = 'Apex-Accelerator/apexcli'
9const VERSION = require('./package.json').releaseVersion || require('./package.json').version
10const isWin = process.platform === 'win32'
11const BIN_DIR = join(os.homedir(), '.apex', 'bin')
12const BIN_PATH = join(BIN_DIR, isWin ? 'apex.exe' : 'apex')
14function getPlatformTarget() {
15 const p = process.platform, a = process.arch
16 if (p === 'linux' && a === 'x64') return 'linux-x64'
17 if (p === 'darwin' && a === 'arm64') return 'darwin-arm64'
18 if (p === 'darwin' && a === 'x64') return 'darwin-x64'
19 if (p === 'win32' && a === 'x64') return 'windows-x64'
20 throw new Error(`Unsupported: ${p}-${a}`)
23function download(url, dest) {
24 return new Promise((resolve, reject) => {
25 const file = createWriteStream(dest)
27 https.get(u, { headers: { 'User-Agent': 'apex-installer' } }, (res) => {
28 if (res.statusCode === 301 || res.statusCode === 302) { req(res.headers.location); return }
29 if (res.statusCode !== 200) { reject(new Error(`HTTP ${res.statusCode}`)); return }
31 file.on('finish', () => { file.close(); resolve() })
32 }).on('error', reject)
38async function ensureBinary() {
39 if (existsSync(BIN_PATH)) return
41 console.log('Downloading Apex Copilot (~114MB), please wait...')
42 const target = getPlatformTarget()
43 const assetName = isWin ? `apex-${target}.exe` : `apex-${target}`
44 const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${assetName}`
46 mkdirSync(BIN_DIR, { recursive: true })
47 await download(url, BIN_PATH)
49 const { chmodSync } = require('fs')
50 if (!isWin) chmodSync(BIN_PATH, 0o755)
MediumAi Review Evidence
The CLI downloads a platform binary from GitHub into the user home directory without an integrity check.
apex.cjsView on unpkg · L41 52 // Windows: download native addon
54 const nativesDir = join(os.homedir(), '.apex', 'natives', '16.3.6')
55 const nodeFile = 'pi_natives.win32-x64-baseline.node'
56 const nodePath = join(nativesDir, nodeFile)
57 if (!existsSync(nodePath)) {
58 console.log('Downloading native addon...')
59 mkdirSync(nativesDir, { recursive: true })
60 await download(`https://github.com/${REPO}/releases/download/v${VERSION}/${nodeFile}`, nodePath)
66 const verifyPath = join(os.homedir(), '.apex', 'apex-verify.exe')
67 const verifyVersionPath = join(os.homedir(), '.apex', '.verify-version-win')
68 let needsUpdate = !existsSync(verifyPath)
71 const saved = require('fs').readFileSync(verifyVersionPath, 'utf8').trim()
72 if (saved !== VERSION) needsUpdate = true
73 } catch { needsUpdate = true }
76 mkdirSync(join(os.homedir(), '.apex'), { recursive: true })
77 await download(`https://github.com/${REPO}/releases/download/v${VERSION}/apex-verify-windows.exe`, verifyPath)
78 require('fs').writeFileSync(verifyVersionPath, VERSION)
82 // Mac: download apex-verify
83 if (process.platform === 'darwin') {
84 const verifyPath = join(os.homedir(), '.apex', 'apex-verify')
85 if (!existsSync(verifyPath)) {
86 mkdirSync(join(os.homedir(), '.apex'), { recursive: true })
87 await download(`https://github.com/${REPO}/releases/download/v${VERSION}/apex-verify-darwin`, verifyPath)
88 require('fs').chmodSync(verifyPath, 0o755)
95ensureBinary().then(() => {
96 const result = spawnSync(BIN_PATH, process.argv.slice(2), {
HighRemote System File Write
Source writes bytes from a remote response into a privileged operating-system path.
apex.cjsView on unpkg · L1 97 stdio: 'inherit', env: process.env
98 })
HighSame File Env Network Execution
A single source file combines environment access, network access, and code or shell execution; review context before blocking.
apex.cjsView on unpkg · L86 99 process.exit(result.status ?? 0)
MediumAi Review Evidence
It marks the downloaded binary executable and launches it with the caller's full environment.
apex.cjsView on unpkg · L95 101 console.error('Failed to download Apex:', err.message)