icoa-cli 2.2.1 → 2.2.3

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.
@@ -21,7 +21,12 @@ export function registerCtfCommands(program) {
21
21
  ctf
22
22
  .command('join <url>')
23
23
  .description('Connect to a CTFd instance')
24
- .action(async (url) => {
24
+ .action(async (rawUrl) => {
25
+ // Auto-add https:// if missing
26
+ let url = rawUrl.trim().replace(/\/+$/, '');
27
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
28
+ url = 'https://' + url;
29
+ }
25
30
  logCommand(`ctf join ${url}`);
26
31
  console.log();
27
32
  printInfo(`Connecting to ${chalk.bold(url)}`);
@@ -1,9 +1,11 @@
1
1
  import chalk from 'chalk';
2
2
  import { execSync } from 'node:child_process';
3
3
  import { platform } from 'node:os';
4
- // Target Python version for full compatibility
4
+ // Target versions for full compatibility
5
5
  const PYTHON_TARGET = '3.12';
6
6
  const PYTHON_EXACT = '3.12.13';
7
+ const NODE_TARGET = '22';
8
+ const NODE_EXACT = '22.22.2';
7
9
  // ══════════════════════════════════════════════════════════
8
10
  // 27 Python Libraries — ALL LOCKED VERSIONS
9
11
  // Tested on Python 3.12.x (recommended)
@@ -281,7 +283,7 @@ function showStatus() {
281
283
  console.log(chalk.gray(' OS: ') + chalk.white(getOsInfo()));
282
284
  console.log(chalk.gray(' Node: ') + chalk.white(getNodeInfo()));
283
285
  console.log(chalk.gray(' Package: ') + chalk.white(pm));
284
- console.log(chalk.gray(' Target: ') + chalk.white(`Python ${PYTHON_TARGET}.x`));
286
+ console.log(chalk.gray(' Target: ') + chalk.white(`Node ${NODE_EXACT} | Python ${PYTHON_EXACT}`));
285
287
  if (os === 'win32') {
286
288
  console.log();
287
289
  console.log(chalk.yellow(' Windows: recommend WSL (Ubuntu) for full CTF tool support'));
@@ -289,15 +291,16 @@ function showStatus() {
289
291
  console.log(chalk.gray(' Then run icoa inside WSL for 100% tool compatibility'));
290
292
  }
291
293
  console.log(chalk.gray(' ─────────────────────────────────────────────'));
292
- // Node.js version check
294
+ // Node.js version check — >= 22.22.2
293
295
  const nodeVer = process.versions.node;
294
- const nodeMajor = parseInt(nodeVer.split('.')[0]);
295
- if (nodeMajor >= 20) {
296
- console.log(chalk.green(` ✓ Node.js ${nodeVer}`));
296
+ const nodeParts = nodeVer.split('.').map(Number);
297
+ const nodeOk = nodeParts[0] > 22 || (nodeParts[0] === 22 && nodeParts[1] > 22) || (nodeParts[0] === 22 && nodeParts[1] === 22 && nodeParts[2] >= 2);
298
+ if (nodeOk) {
299
+ console.log(chalk.green(` ✓ Node.js ${nodeVer}`) + chalk.gray(` (>= ${NODE_EXACT})`));
297
300
  }
298
301
  else {
299
- console.log(chalk.red(` ✗ Node.js ${nodeVer}`) + chalk.gray(' (v20+ required)'));
300
- console.log(chalk.gray(' Upgrade: https://nodejs.org/ or nvm install 22'));
302
+ console.log(chalk.red(` ✗ Node.js ${nodeVer}`) + chalk.gray(` (>= ${NODE_EXACT} required)`));
303
+ console.log(chalk.gray(' Install: nvm install 22 or visit https://nodejs.org/'));
301
304
  }
302
305
  // Python version check
303
306
  const pyVer = getPythonMajorMinor();
@@ -379,6 +382,31 @@ async function installAll() {
379
382
  console.log();
380
383
  const os = platform();
381
384
  const pipFlag = os === 'darwin' || os === 'linux' ? '--break-system-packages' : '';
385
+ // Node.js version check
386
+ const nodeVer = process.versions.node;
387
+ if (nodeVer === NODE_EXACT) {
388
+ console.log(chalk.green(` ✓ Node.js ${NODE_EXACT}`));
389
+ }
390
+ else {
391
+ console.log(chalk.yellow(` Node.js ${nodeVer} — installing ${NODE_EXACT}...`));
392
+ try {
393
+ if (os === 'darwin') {
394
+ execSync(`brew install node@22`, { stdio: 'inherit' });
395
+ }
396
+ else if (os === 'linux') {
397
+ execSync(`curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs`, { stdio: 'inherit' });
398
+ }
399
+ else {
400
+ execSync(`winget install OpenJS.NodeJS.LTS --version ${NODE_EXACT}`, { stdio: 'inherit' });
401
+ }
402
+ console.log(chalk.green(` ✓ Node.js ${NODE_EXACT} installed`));
403
+ console.log(chalk.gray(' Restart icoa to use the new version.'));
404
+ }
405
+ catch {
406
+ console.log(chalk.yellow(` ~ Node.js upgrade skipped. Install manually: nvm install ${NODE_EXACT}`));
407
+ }
408
+ }
409
+ console.log();
382
410
  // Python version check — install 3.12.13 if needed
383
411
  const pyVer = getPythonMajorMinor();
384
412
  const currentFullVer = getPythonFullVersion();
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.2.1')}
39
+ ${chalk.gray('CLI-Native Competition Terminal v2.2.3')}
40
40
 
41
41
  ${LINE}
42
42
  `;
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.2.1';
30
+ const VERSION = '2.2.3';
31
31
  export async function startRepl(program, resumeMode) {
32
32
  const config = getConfig();
33
33
  const connected = isConnected();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {