icoa-cli 1.5.2 → 1.6.0

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.
Files changed (3) hide show
  1. package/dist/index.js +23 -33
  2. package/dist/repl.js +26 -16
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14,40 +14,31 @@ import { registerSetupCommand } from './commands/setup.js';
14
14
  import { registerEnvCommand } from './commands/env.js';
15
15
  import { getConfig, saveConfig } from './lib/config.js';
16
16
  import { startRepl } from './repl.js';
17
- import { checkTerminal } from './lib/terminal.js';
18
17
  import { setTerminalTheme } from './lib/theme.js';
19
- // Banner: padded programmatically for perfect alignment
20
- const W = 58; // inner width between ║ ║
21
- function pad(text, visible) {
22
- return text + ' '.repeat(Math.max(0, W - visible));
23
- }
24
- const B = chalk.cyan('║');
25
- const TOP = chalk.cyan('╔' + '═'.repeat(W) + '╗');
26
- const BOT = chalk.cyan('╚' + '═'.repeat(W) + '╝');
27
- const EMPTY = B + ' '.repeat(W) + B;
18
+ const LINE = chalk.cyan(' ─────────────────────────────────────────────────────');
28
19
  const BANNER = `
29
- ${TOP}
30
- ${EMPTY}
31
- ${B}${pad(' ' + chalk.bold.white('██╗ ██████╗ ██████╗ █████╗'), 31)}${B}
32
- ${B}${pad(' ' + chalk.bold.white('██║██╔════╝██╔═══██╗██╔══██╗'), 32)}${B}
33
- ${B}${pad(' ' + chalk.bold.white('██║██║ ██║ ██║███████║'), 32)}${B}
34
- ${B}${pad(' ' + chalk.bold.white('██║██║ ██║ ██║██╔══██║'), 32)}${B}
35
- ${B}${pad(' ' + chalk.bold.white('██║╚██████╗╚██████╔╝██║ ██║'), 32)}${B}
36
- ${B}${pad(' ' + chalk.bold.white('╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝'), 33)}${B}
37
- ${EMPTY}
38
- ${B}${pad(' ' + chalk.yellow('International Cyber Olympiad in AI 2026'), 42)}${B}
39
- ${B}${pad(' ' + chalk.bold.magenta("The World's First AI Security Olympiad"), 41)}${B}
40
- ${EMPTY}
41
- ${B}${pad(' ' + chalk.green.bold('AI4CTF') + ' ' + chalk.gray('AI as your teammate'), 29)}${B}
42
- ${B}${pad(' ' + chalk.red.bold('CTF4AI') + ' ' + chalk.gray('Hack & evaluate AI systems'), 36)}${B}
43
- ${B}${pad(' ' + chalk.bold.white('AI is your ally. AI is your target.'), 38)}${B}
44
- ${EMPTY}
45
- ${B}${pad(' ' + chalk.white('Sydney, Australia') + ' ' + chalk.gray('Jun 27 - Jul 2, 2026'), 42)}${B}
46
- ${B}${pad(' ' + chalk.cyan.underline('https://icoa2026.au'), 22)}${B}
47
- ${EMPTY}
48
- ${B}${pad(' ' + chalk.gray('CLI-Native Competition Terminal v1.5.2'), 42)}${B}
49
- ${EMPTY}
50
- ${BOT}
20
+ ${LINE}
21
+
22
+ ${chalk.bold.white('██╗ ██████╗ ██████╗ █████╗')}
23
+ ${chalk.bold.white('██║██╔════╝██╔═══██╗██╔══██╗')}
24
+ ${chalk.bold.white('██║██║ ██║ ██║███████║')}
25
+ ${chalk.bold.white('██║██║ ██║ ██║██╔══██║')}
26
+ ${chalk.bold.white('██║╚██████╗╚██████╔╝██║ ██║')}
27
+ ${chalk.bold.white('╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝')}
28
+
29
+ ${chalk.yellow('International Cyber Olympiad in AI 2026')}
30
+ ${chalk.bold.magenta("The World's First AI Security Olympiad")}
31
+
32
+ ${chalk.green.bold('AI4CTF')}${chalk.gray('[Day 1]')} ${chalk.white('AI as your teammate')}
33
+ ${chalk.red.bold('CTF4AI')}${chalk.gray('[Day 2]')} ${chalk.white('Hack & evaluate AI systems')}
34
+ ${chalk.bold.yellow('AI is your ally. AI is your target.')}
35
+
36
+ ${chalk.white('Sydney, Australia')} ${chalk.gray('Jun 27 - Jul 2, 2026')}
37
+ ${chalk.cyan.underline('https://icoa2026.au')}
38
+
39
+ ${chalk.gray('CLI-Native Competition Terminal v1.6.0')}
40
+
41
+ ${LINE}
51
42
  `;
52
43
  // Global error handlers
53
44
  process.on('uncaughtException', (err) => {
@@ -73,7 +64,6 @@ program
73
64
  // Force hacker theme: black background + green text
74
65
  setTerminalTheme();
75
66
  console.log(BANNER);
76
- checkTerminal();
77
67
  // If running interactively (no extra args or --resume), start REPL
78
68
  if (process.argv.length <= 2 || opts.resume) {
79
69
  startRepl(program, !!opts.resume);
package/dist/repl.js CHANGED
@@ -17,34 +17,44 @@ export function startRepl(program, resumeMode) {
17
17
  if (info) {
18
18
  const mins = Math.floor(info.awaySeconds / 60);
19
19
  const secs = info.awaySeconds % 60;
20
- console.log(chalk.yellow(` Session resumed. Away: ${mins}m ${secs}s | Total exits: ${info.exitCount}`));
21
- }
22
- else {
23
- console.log(chalk.gray(' No previous session to resume.'));
20
+ console.log(chalk.yellow(` Session resumed. Away: ${mins}m ${secs}s | Total exits: ${info.exitCount}`));
21
+ console.log();
24
22
  }
25
- console.log();
26
23
  }
27
24
  // Device mismatch check
28
25
  if (activated && !isDeviceMatch()) {
29
- console.log(chalk.red(' Token was activated on a different device. Access denied.'));
30
- console.log(chalk.gray(' Contact organizer for assistance.'));
26
+ console.log(chalk.red(' Token was activated on a different device.'));
27
+ console.log(chalk.gray(' Contact organizer for assistance.'));
31
28
  console.log();
32
- // Fall through to restricted mode
33
29
  }
34
30
  else if (connected) {
35
- console.log(chalk.gray(' Connected to: ') + chalk.white(config.ctfdUrl));
36
- console.log(chalk.gray(' User: ') + chalk.white(config.userName));
31
+ console.log(chalk.green(` Welcome back, ${config.userName}!`));
32
+ console.log(chalk.gray(` Connected to ${config.ctfdUrl}`));
33
+ console.log();
37
34
  }
38
35
  else if (activated) {
39
- console.log(chalk.green(' Access granted. ') + chalk.gray('Type: ') + chalk.white('join <url>') + chalk.gray(' to connect.'));
36
+ console.log(chalk.green(' Welcome, competitor! Ready to hack.'));
37
+ console.log();
38
+ console.log(chalk.gray(' Quick Start'));
39
+ console.log(chalk.gray(' ─────────────'));
40
+ console.log(chalk.white(' join <url> ') + chalk.gray('Connect to competition'));
41
+ console.log(chalk.white(' challenges ') + chalk.gray('View challenges'));
42
+ console.log(chalk.white(' hint <question> ') + chalk.gray('Ask AI for help'));
43
+ console.log(chalk.white(' env ') + chalk.gray('Check your tools'));
44
+ console.log(chalk.white(' help ') + chalk.gray('All commands'));
45
+ console.log();
40
46
  }
41
47
  else {
42
- console.log(chalk.yellow(' Restricted mode. ') + chalk.gray('Type: ') + chalk.white('activate <token>') + chalk.gray(' to unlock.'));
43
- console.log(chalk.gray(' Available: ') + chalk.white('ref [topic]') + chalk.gray(', ') + chalk.white('help') + chalk.gray(', ') + chalk.white('exit'));
48
+ console.log(chalk.white(' Welcome to ICOA CLI!'));
49
+ console.log();
50
+ console.log(chalk.gray(' Quick Start'));
51
+ console.log(chalk.gray(' ─────────────'));
52
+ console.log(chalk.white(' activate <token> ') + chalk.gray('Unlock with your access token'));
53
+ console.log(chalk.white(' ref <topic> ') + chalk.gray('Browse tool references'));
54
+ console.log(chalk.white(' env ') + chalk.gray('Check your tools'));
55
+ console.log(chalk.white(' help ') + chalk.gray('All commands'));
56
+ console.log();
44
57
  }
45
- console.log();
46
- console.log(chalk.gray(' Type ') + chalk.white('help') + chalk.gray(' for commands, ') + chalk.white('exit') + chalk.gray(' to quit.'));
47
- console.log();
48
58
  program.exitOverride();
49
59
  program.configureOutput({
50
60
  writeErr: () => { },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "1.5.2",
3
+ "version": "1.6.0",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {