icoa-cli 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -274,13 +274,19 @@ export function registerEnvCommand(program) {
274
274
  function showStatus() {
275
275
  console.log();
276
276
  const os = platform();
277
- const pm = os === 'darwin' ? 'brew' : os === 'linux' ? 'apt' : 'choco';
277
+ const pm = os === 'darwin' ? 'brew' : os === 'linux' ? 'apt' : 'winget';
278
278
  console.log(chalk.bold.white(' ICOA Competition Environment'));
279
279
  console.log(chalk.gray(' ─────────────────────────────────────────────'));
280
280
  console.log(chalk.gray(' OS: ') + chalk.white(getOsInfo()));
281
281
  console.log(chalk.gray(' Node: ') + chalk.white(getNodeInfo()));
282
282
  console.log(chalk.gray(' Package: ') + chalk.white(pm));
283
283
  console.log(chalk.gray(' Target: ') + chalk.white(`Python ${PYTHON_TARGET}.x`));
284
+ if (os === 'win32') {
285
+ console.log();
286
+ console.log(chalk.yellow(' Windows: recommend WSL (Ubuntu) for full CTF tool support'));
287
+ console.log(chalk.gray(' Install WSL: ') + chalk.white('wsl --install'));
288
+ console.log(chalk.gray(' Then run icoa inside WSL for 100% tool compatibility'));
289
+ }
284
290
  console.log(chalk.gray(' ─────────────────────────────────────────────'));
285
291
  // Python version check — use brew 3.12 on macOS
286
292
  const pyVer = getPythonMajorMinor();
@@ -316,7 +322,7 @@ function showStatus() {
316
322
  }
317
323
  }
318
324
  currentCategory = '';
319
- const pipExe = os === 'darwin' ? '/opt/homebrew/opt/python@3.12/bin/pip3.12' : 'pip3';
325
+ const pipExe = os === 'darwin' ? '/opt/homebrew/opt/python@3.12/bin/pip3.12' : os === 'win32' ? 'pip' : 'pip3';
320
326
  for (const lib of PYTHON_LIBS) {
321
327
  if (lib.category !== currentCategory) {
322
328
  currentCategory = lib.category;
@@ -324,12 +330,12 @@ function showStatus() {
324
330
  }
325
331
  const ok = isInstalled(lib.check);
326
332
  if (ok) {
327
- // Get actual installed version — try pip3.12, then pip3
333
+ // Get actual installed version
328
334
  let ver = '';
329
- for (const pip of [pipExe, 'pip3']) {
335
+ for (const pip of [pipExe, 'pip3', 'pip']) {
330
336
  try {
331
- const pkgName = lib.name.replace('python-magic', 'python_magic').replace('beautifulsoup4', 'beautifulsoup4');
332
- const out = execSync(`${pip} show ${pkgName} 2>/dev/null | grep Version`, { encoding: 'utf-8', timeout: 3000 });
337
+ const pkgName = lib.name.replace('python-magic', 'python_magic');
338
+ const out = execSync(`${pip} show ${pkgName}`, { encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'ignore'] });
333
339
  const m = out.match(/Version:\s*(\S+)/);
334
340
  if (m) {
335
341
  ver = m[1];
@@ -376,18 +382,37 @@ async function installAll() {
376
382
  console.log(chalk.gray(' Or: brew link --overwrite python@3.12'));
377
383
  }
378
384
  else if (os === 'linux') {
379
- execSync('sudo apt-get update && sudo apt-get install -y python3.12 python3.12-venv python3.12-dev', { stdio: 'inherit' });
385
+ // Add deadsnakes PPA for older Ubuntu (22.04 etc.)
386
+ try {
387
+ execSync('sudo apt-get install -y software-properties-common', { stdio: 'inherit' });
388
+ execSync('sudo add-apt-repository -y ppa:deadsnakes/ppa', { stdio: 'inherit' });
389
+ execSync('sudo apt-get update', { stdio: 'inherit' });
390
+ }
391
+ catch { /* PPA may already exist or not needed on newer Ubuntu */ }
392
+ execSync('sudo apt-get install -y python3.12 python3.12-venv python3.12-dev', { stdio: 'inherit' });
393
+ // Install pip for 3.12
394
+ try {
395
+ execSync('curl -sS https://bootstrap.pypa.io/get-pip.py | sudo python3.12', { stdio: 'inherit' });
396
+ }
397
+ catch { /* ok */ }
380
398
  console.log(chalk.green(' ✓ Python 3.12 installed'));
381
399
  console.log(chalk.gray(' Set default: sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1'));
382
400
  }
383
401
  else {
384
- execSync('choco install -y python312', { stdio: 'inherit' });
402
+ // Windows: try winget first, then choco
403
+ try {
404
+ execSync('winget install Python.Python.3.12 --accept-package-agreements --accept-source-agreements', { stdio: 'inherit' });
405
+ }
406
+ catch {
407
+ execSync('choco install -y python312', { stdio: 'inherit' });
408
+ }
385
409
  console.log(chalk.green(' ✓ Python 3.12 installed'));
386
410
  }
387
411
  }
388
412
  catch {
389
413
  console.log(chalk.red(' ✗ Failed to install Python 3.12'));
390
- console.log(chalk.gray(` Manual install: ${os === 'darwin' ? 'brew install python@3.12' : os === 'linux' ? 'sudo apt install python3.12' : 'choco install python312'}`));
414
+ const hint = os === 'darwin' ? 'brew install python@3.12' : os === 'linux' ? 'sudo apt install python3.12' : 'winget install Python.Python.3.12';
415
+ console.log(chalk.gray(` Manual install: ${hint}`));
391
416
  }
392
417
  console.log();
393
418
  }
@@ -395,7 +420,14 @@ async function installAll() {
395
420
  console.log(chalk.green(` ✓ Python 3.12 (${getVersion('python3')})`));
396
421
  console.log();
397
422
  }
398
- // Install system tools via brew (macOS) / apt (Linux) / choco (Windows)
423
+ // Windows: recommend WSL instead of installing tools natively
424
+ if (os === 'win32') {
425
+ console.log(chalk.yellow(' Windows: Most CTF tools require Linux. Recommended:'));
426
+ console.log(chalk.white(' wsl --install'));
427
+ console.log(chalk.gray(' Then run icoa inside WSL Ubuntu for full tool support.'));
428
+ console.log();
429
+ }
430
+ // Install system tools via brew (macOS) / apt (Linux)
399
431
  const missingSystem = [];
400
432
  for (const tool of SYSTEM_TOOLS) {
401
433
  if (!isInstalled(tool.check)) {
@@ -404,8 +436,8 @@ async function installAll() {
404
436
  missingSystem.push(tool);
405
437
  }
406
438
  }
407
- if (missingSystem.length > 0) {
408
- const pmName = os === 'darwin' ? 'brew' : os === 'linux' ? 'apt' : 'choco';
439
+ if (missingSystem.length > 0 && os !== 'win32') {
440
+ const pmName = os === 'darwin' ? 'brew' : 'apt';
409
441
  console.log(chalk.bold.white(` System Tools via ${pmName} (${missingSystem.length} missing)`));
410
442
  console.log(chalk.gray(' ─────────────────────────────────────────────'));
411
443
  for (const tool of missingSystem) {
@@ -456,6 +488,9 @@ async function installAll() {
456
488
  }
457
489
  catch { /* fall back to pip3 */ }
458
490
  }
491
+ else if (os === 'win32') {
492
+ pipCmd = 'pip';
493
+ }
459
494
  // Pre-install system dependencies for packages that need them
460
495
  if (os === 'darwin') {
461
496
  console.log(chalk.gray(' Installing build dependencies...'));
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ ${LINE}
36
36
  ${chalk.white('Sydney, Australia')} ${chalk.gray('Jun 27 - Jul 2, 2026')}
37
37
  ${chalk.cyan.underline('https://icoa2026.au')}
38
38
 
39
- ${chalk.gray('CLI-Native Competition Terminal v2.0.0')}
39
+ ${chalk.gray('CLI-Native Competition Terminal v2.0.2')}
40
40
 
41
41
  ${LINE}
42
42
  `;
@@ -143,10 +143,8 @@ function getDeviceFingerprint() {
143
143
  }
144
144
  }
145
145
  else if (platform() === 'win32') {
146
- const out = execSync('wmic csproduct get uuid', { encoding: 'utf-8' });
147
- const lines = out.trim().split('\n');
148
- if (lines.length > 1)
149
- parts.push(lines[1].trim());
146
+ const out = execSync('powershell -Command "(Get-CimInstance Win32_ComputerSystemProduct).UUID"', { encoding: 'utf-8' });
147
+ parts.push(out.trim());
150
148
  }
151
149
  }
152
150
  catch {
package/dist/repl.js CHANGED
@@ -27,7 +27,7 @@ const BLOCKED_COMMANDS = new Set([
27
27
  'iptables', 'ufw', // firewall
28
28
  ]);
29
29
  const INTERCEPT = '__REPL_NO_EXIT__';
30
- const VERSION = '2.0.0';
30
+ const VERSION = '2.0.2';
31
31
  export async function startRepl(program, resumeMode) {
32
32
  const config = getConfig();
33
33
  const connected = isConnected();
@@ -67,7 +67,9 @@ export async function startRepl(program, resumeMode) {
67
67
  console.log();
68
68
  // Trigger env setup
69
69
  const { execSync: ex } = await import('node:child_process');
70
- ex('node ' + new URL('../index.js', import.meta.url).pathname + ' env setup', { stdio: 'inherit' });
70
+ const { fileURLToPath } = await import('node:url');
71
+ const indexPath = fileURLToPath(new URL('../index.js', import.meta.url));
72
+ ex(`node "${indexPath}" env setup`, { stdio: 'inherit' });
71
73
  }
72
74
  }
73
75
  catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {