icoa-cli 2.0.0 → 2.0.1

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];
@@ -381,13 +387,20 @@ async function installAll() {
381
387
  console.log(chalk.gray(' Set default: sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1'));
382
388
  }
383
389
  else {
384
- execSync('choco install -y python312', { stdio: 'inherit' });
390
+ // Windows: try winget first, then choco
391
+ try {
392
+ execSync('winget install Python.Python.3.12 --accept-package-agreements --accept-source-agreements', { stdio: 'inherit' });
393
+ }
394
+ catch {
395
+ execSync('choco install -y python312', { stdio: 'inherit' });
396
+ }
385
397
  console.log(chalk.green(' ✓ Python 3.12 installed'));
386
398
  }
387
399
  }
388
400
  catch {
389
401
  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'}`));
402
+ const hint = os === 'darwin' ? 'brew install python@3.12' : os === 'linux' ? 'sudo apt install python3.12' : 'winget install Python.Python.3.12';
403
+ console.log(chalk.gray(` Manual install: ${hint}`));
391
404
  }
392
405
  console.log();
393
406
  }
@@ -395,7 +408,14 @@ async function installAll() {
395
408
  console.log(chalk.green(` ✓ Python 3.12 (${getVersion('python3')})`));
396
409
  console.log();
397
410
  }
398
- // Install system tools via brew (macOS) / apt (Linux) / choco (Windows)
411
+ // Windows: recommend WSL instead of installing tools natively
412
+ if (os === 'win32') {
413
+ console.log(chalk.yellow(' Windows: Most CTF tools require Linux. Recommended:'));
414
+ console.log(chalk.white(' wsl --install'));
415
+ console.log(chalk.gray(' Then run icoa inside WSL Ubuntu for full tool support.'));
416
+ console.log();
417
+ }
418
+ // Install system tools via brew (macOS) / apt (Linux)
399
419
  const missingSystem = [];
400
420
  for (const tool of SYSTEM_TOOLS) {
401
421
  if (!isInstalled(tool.check)) {
@@ -404,8 +424,8 @@ async function installAll() {
404
424
  missingSystem.push(tool);
405
425
  }
406
426
  }
407
- if (missingSystem.length > 0) {
408
- const pmName = os === 'darwin' ? 'brew' : os === 'linux' ? 'apt' : 'choco';
427
+ if (missingSystem.length > 0 && os !== 'win32') {
428
+ const pmName = os === 'darwin' ? 'brew' : 'apt';
409
429
  console.log(chalk.bold.white(` System Tools via ${pmName} (${missingSystem.length} missing)`));
410
430
  console.log(chalk.gray(' ─────────────────────────────────────────────'));
411
431
  for (const tool of missingSystem) {
@@ -456,6 +476,9 @@ async function installAll() {
456
476
  }
457
477
  catch { /* fall back to pip3 */ }
458
478
  }
479
+ else if (os === 'win32') {
480
+ pipCmd = 'pip';
481
+ }
459
482
  // Pre-install system dependencies for packages that need them
460
483
  if (os === 'darwin') {
461
484
  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.1')}
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.1';
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.1",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {