icoa-cli 2.19.8 → 2.19.10

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.
@@ -151,10 +151,29 @@ export function registerCtfCommands(program) {
151
151
  console.log();
152
152
  printSuccess('Connection saved. You are ready!');
153
153
  console.log();
154
- console.log(chalk.gray(' Next:'));
155
- console.log(chalk.white(' exam list ') + chalk.gray('View available exams'));
156
- console.log(chalk.white(' challenges ') + chalk.gray('View CTF challenges'));
157
- console.log(chalk.white(' status ') + chalk.gray('Check score & budget'));
154
+ const currentMode = getConfig().mode || '';
155
+ if (currentMode === 'olympiad') {
156
+ // Olympiad: guided step-by-step walkthrough
157
+ console.log(chalk.cyan(' ─────────────────────────────────────────────'));
158
+ console.log(chalk.bold.white(' How to compete:'));
159
+ console.log();
160
+ console.log(chalk.white(' Step 1 ') + chalk.bold.cyan('challenges') + chalk.gray(' Browse all challenges'));
161
+ console.log(chalk.white(' Step 2 ') + chalk.bold.cyan('open <id>') + chalk.gray(' Read challenge details'));
162
+ console.log(chalk.white(' Step 3 ') + chalk.bold.cyan('hint "your question"') + chalk.gray(' Ask AI for help'));
163
+ console.log(chalk.white(' Step 4 ') + chalk.bold.cyan('submit <id> <flag>') + chalk.gray(' Submit your answer'));
164
+ console.log();
165
+ console.log(chalk.gray(' More:'));
166
+ console.log(chalk.white(' scoreboard') + chalk.gray(' Live rankings'));
167
+ console.log(chalk.white(' status') + chalk.gray(' Your score & hint budget'));
168
+ console.log(chalk.white(' ai4ctf') + chalk.gray(' Free-chat with AI teammate'));
169
+ console.log(chalk.cyan(' ─────────────────────────────────────────────'));
170
+ }
171
+ else {
172
+ console.log(chalk.gray(' Next:'));
173
+ console.log(chalk.white(' exam list ') + chalk.gray('View available exams'));
174
+ console.log(chalk.white(' challenges ') + chalk.gray('View CTF challenges'));
175
+ console.log(chalk.white(' status ') + chalk.gray('Check score & budget'));
176
+ }
158
177
  }
159
178
  catch (err) {
160
179
  spinner2.fail('Connection test failed');
@@ -181,6 +200,11 @@ export function registerCtfCommands(program) {
181
200
  country: '',
182
201
  });
183
202
  printSuccess('Logged out. Credentials cleared.');
203
+ console.log();
204
+ console.log(chalk.gray(' What now?'));
205
+ console.log(chalk.white(' join <url>') + chalk.gray(' Re-connect to competition'));
206
+ console.log(chalk.white(' setup') + chalk.gray(' Switch mode'));
207
+ console.log(chalk.white(' exit') + chalk.gray(' Quit ICOA CLI'));
184
208
  });
185
209
  // ─── icoa ctf activate <code> ───
186
210
  ctf
@@ -251,24 +275,54 @@ export function registerCtfCommands(program) {
251
275
  }
252
276
  const solved = challenges.filter((c) => c.solved_by_me).length;
253
277
  printHeader(`Challenges (${solved}/${challenges.length} solved)`);
278
+ // Category descriptions for beginners
279
+ const catDesc = {
280
+ 'Web': 'Find vulnerabilities in websites',
281
+ 'Crypto': 'Break ciphers & encryption',
282
+ 'Reversing': 'Analyze compiled programs',
283
+ 'Rev': 'Analyze compiled programs',
284
+ 'Pwn': 'Exploit binary vulnerabilities',
285
+ 'Forensics': 'Investigate digital evidence',
286
+ 'Misc': 'Creative & mixed challenges',
287
+ 'OSINT': 'Open-source intelligence gathering',
288
+ 'AI': 'AI security & adversarial ML',
289
+ };
290
+ // Difficulty based on points
291
+ const difficulty = (pts) => {
292
+ if (pts <= 100)
293
+ return chalk.green('Easy');
294
+ if (pts <= 250)
295
+ return chalk.yellow('Medium');
296
+ if (pts <= 500)
297
+ return chalk.red('Hard');
298
+ return chalk.magenta('Expert');
299
+ };
254
300
  // Sort categories and display
255
301
  const rows = [...byCategory.entries()]
256
302
  .sort(([a], [b]) => a.localeCompare(b))
257
303
  .flatMap(([category, challs]) => {
258
- const catRow = [chalk.cyan.bold(`── ${category} ──`), '', '', '', ''];
304
+ const desc = catDesc[category] || '';
305
+ const catLabel = desc
306
+ ? chalk.cyan.bold(`── ${category} ──`) + ' ' + chalk.gray(desc)
307
+ : chalk.cyan.bold(`── ${category} ──`);
308
+ const catRow = [catLabel, '', '', '', ''];
259
309
  const challRows = challs
260
310
  .sort((a, b) => a.value - b.value)
261
311
  .map((c) => [
262
312
  String(c.id),
263
313
  c.solved_by_me ? chalk.gray.strikethrough(c.name) : c.name,
264
- chalk.gray(c.category),
265
314
  c.solved_by_me ? chalk.gray(String(c.value)) : chalk.yellow(String(c.value)),
315
+ c.solved_by_me ? chalk.gray('--') : difficulty(c.value),
266
316
  c.solved_by_me ? chalk.green('✓') : chalk.gray('○'),
267
317
  ]);
268
318
  return [catRow, ...challRows];
269
319
  });
270
- printTable(['#', 'Name', 'Category', 'Points', 'Solved'], rows);
320
+ printTable(['#', 'Name', 'Points', 'Difficulty', 'Solved'], rows);
271
321
  console.log(chalk.gray(` ${challenges.length} challenges, ${solved} solved`));
322
+ if (solved === 0) {
323
+ console.log();
324
+ console.log(chalk.gray(' Tip: Start with ') + chalk.green('Easy') + chalk.gray(' challenges! Type ') + chalk.white('open <id>') + chalk.gray(' to read one.'));
325
+ }
272
326
  }
273
327
  catch (err) {
274
328
  spinner.fail('Failed to load challenges');
@@ -325,9 +379,19 @@ export function registerCtfCommands(program) {
325
379
  console.log();
326
380
  printInfo(`Quick connect: ${chalk.white(`connect ${id}`)}`);
327
381
  }
328
- // Show helpful next actions
382
+ // Show guided next actions
329
383
  console.log();
330
- console.log(chalk.gray(` Next: hint "how to approach this?" | submit ${id} "icoa{flag}"`));
384
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
385
+ console.log(chalk.bold.white(' What to do next:'));
386
+ console.log(chalk.white(` hint "how to start?"`) + chalk.gray(' Ask AI for guidance (Level A)'));
387
+ if (challenge.files && challenge.files.length > 0) {
388
+ console.log(chalk.white(` files ${id}`) + chalk.gray(' Download challenge files'));
389
+ }
390
+ if (challenge.connection_info) {
391
+ console.log(chalk.white(` connect ${id}`) + chalk.gray(' Connect to target'));
392
+ }
393
+ console.log(chalk.white(` submit ${id} icoa{flag}`) + chalk.gray(' Submit your answer'));
394
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
331
395
  }
332
396
  catch (err) {
333
397
  spinner.fail('Failed to load challenge');
@@ -280,6 +280,19 @@ function showStatus() {
280
280
  const pm = os === 'darwin' ? 'brew' : os === 'linux' ? 'apt' : 'winget';
281
281
  console.log(chalk.bold.white(' ICOA Competition Environment'));
282
282
  console.log(chalk.gray(' ─────────────────────────────────────────────'));
283
+ console.log();
284
+ console.log(chalk.gray(' These tools power your CTF competition environment.'));
285
+ console.log(chalk.gray(' Not all are required — here\'s what matters:'));
286
+ console.log();
287
+ console.log(chalk.green(' Essential') + chalk.gray(' pwntools, z3, requests, numpy'));
288
+ console.log(chalk.gray(' You need these for most challenges'));
289
+ console.log(chalk.yellow(' Recommended') + chalk.gray(' pycryptodome, beautifulsoup4, scapy, sympy'));
290
+ console.log(chalk.gray(' Covers Web, Crypto, and Forensics'));
291
+ console.log(chalk.gray(' Full (109) All tools for every category'));
292
+ console.log();
293
+ console.log(chalk.gray(' Missing tools? Run ') + chalk.bold.cyan('env setup') + chalk.gray(' to install everything.'));
294
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
295
+ console.log();
283
296
  console.log(chalk.gray(' OS: ') + chalk.white(getOsInfo()));
284
297
  console.log(chalk.gray(' Node: ') + chalk.white(getNodeInfo()));
285
298
  console.log(chalk.gray(' Package: ') + chalk.white(pm));
@@ -382,6 +395,17 @@ async function installAll() {
382
395
  console.log();
383
396
  const os = platform();
384
397
  const pipFlag = os === 'darwin' || os === 'linux' ? '--break-system-packages' : '';
398
+ console.log(chalk.bold.white(' ICOA Environment Setup'));
399
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
400
+ console.log(chalk.gray(' This will install:'));
401
+ console.log(chalk.white(' Python 3.12') + chalk.gray(' Runtime for CTF tools'));
402
+ console.log(chalk.white(` ${PYTHON_LIBS.length} Python libraries`) + chalk.gray(' pwntools, z3, crypto...'));
403
+ console.log(chalk.white(` ${SYSTEM_TOOLS.length} system tools`) + chalk.gray(' gcc, gdb, nmap, wireshark...'));
404
+ console.log();
405
+ console.log(chalk.gray(' Estimated: ~500 MB disk, 5-15 min (depends on network)'));
406
+ console.log(chalk.gray(' Already installed tools will be skipped.'));
407
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
408
+ console.log();
385
409
  // Node.js version check
386
410
  const nodeVer = process.versions.node;
387
411
  if (nodeVer === NODE_EXACT) {
@@ -1,10 +1,9 @@
1
1
  import chalk from 'chalk';
2
- import { confirm } from '@inquirer/prompts';
3
2
  import { generateHint } from '../lib/gemini.js';
4
3
  import { checkBudget, deductBudget, getBudgetDisplay, isTokenCapReached } from '../lib/budget.js';
5
4
  import { getConfig } from '../lib/config.js';
6
5
  import { logHint } from '../lib/logger.js';
7
- import { printError, printInfo, printMarkdown, printHeader, createSpinner } from '../lib/ui.js';
6
+ import { printError, printMarkdown, printHeader, createSpinner } from '../lib/ui.js';
8
7
  function getChallengeContext() {
9
8
  const config = getConfig();
10
9
  if (config.currentChallengeName && config.currentChallengeCategory) {
@@ -28,16 +27,9 @@ async function handleHint(level, question) {
28
27
  printError(`Level ${level} hint budget exhausted (0 remaining).`);
29
28
  return;
30
29
  }
31
- // Level C confirmation
30
+ // Level C warning (no confirm — crashes REPL)
32
31
  if (level === 'C') {
33
- const proceed = await confirm({
34
- message: `This will consume 1 of your ${remaining} remaining Critical Assists. Continue?`,
35
- default: false,
36
- });
37
- if (!proceed) {
38
- printInfo('Cancelled.');
39
- return;
40
- }
32
+ console.log(chalk.red.bold(` Warning: Using 1 of ${remaining} Critical Assists remaining.`));
41
33
  }
42
34
  // Log BEFORE API call
43
35
  logHint(level, question, config.currentChallengeId || undefined);
@@ -56,8 +48,23 @@ async function handleHint(level, question) {
56
48
  deductBudget(level, result.tokensUsed);
57
49
  printHeader(`Level ${level} Hint — ${levelNames[level]}`);
58
50
  printMarkdown(result.text);
51
+ // Budget summary after hint
52
+ const afterBudget = checkBudget(level);
59
53
  console.log();
60
- console.log(chalk.gray(` Tokens used: ${result.tokensUsed} | Level ${level} remaining: ${checkBudget(level).remaining}`));
54
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
55
+ console.log(chalk.gray(` Tokens used: ${result.tokensUsed} | Level ${level} remaining: ${afterBudget.remaining}`));
56
+ // Suggest next level if stuck
57
+ if (level === 'A') {
58
+ const bBudget = checkBudget('B');
59
+ console.log(chalk.gray(' Need more detail? ') + chalk.white('hint-b "your question"') + chalk.gray(` (${bBudget.remaining} left)`));
60
+ }
61
+ else if (level === 'B') {
62
+ const cBudget = checkBudget('C');
63
+ if (cBudget.remaining > 0) {
64
+ console.log(chalk.gray(' Still stuck? ') + chalk.white('hint-c "your question"') + chalk.gray(` (${cBudget.remaining} Critical Assists left)`));
65
+ }
66
+ }
67
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
61
68
  console.log();
62
69
  }
63
70
  catch (err) {
@@ -69,6 +76,11 @@ function showBudget() {
69
76
  printHeader('Hint Budget');
70
77
  console.log(getBudgetDisplay());
71
78
  console.log();
79
+ console.log(chalk.gray(' How to use hints:'));
80
+ console.log(chalk.white(' hint "what is XSS?"') + chalk.gray(' Level A — General guidance'));
81
+ console.log(chalk.white(' hint-b "analyze this code"') + chalk.gray(' Level B — Deep analysis'));
82
+ console.log(chalk.white(' hint-c "I\'m completely stuck"') + chalk.gray(' Level C — Critical assist'));
83
+ console.log();
72
84
  }
73
85
  export function registerHintCommands(program) {
74
86
  // ─── icoa hint <question> ───
package/dist/index.js CHANGED
@@ -35,7 +35,8 @@ ${LINE}
35
35
  ${chalk.bold.white('╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝')}
36
36
 
37
37
  ${chalk.yellow('International Cyber Olympiad in AI 2026')}
38
- ${chalk.bold.magenta("The World's First AI Security Olympiad")}
38
+ ${chalk.bold.magenta("The World's First AI-Native CLI Operating System")}
39
+ ${chalk.bold.magenta("for Cybersecurity & AI Security Competition")}
39
40
 
40
41
  ${chalk.green.bold('AI4CTF')}${chalk.gray('[Day 1]')} ${chalk.white('AI as your teammate')}
41
42
  ${chalk.red.bold('CTF4AI')}${chalk.gray('[Day 2]')} ${chalk.white('Hack & evaluate AI systems')}
package/dist/repl.js CHANGED
@@ -66,18 +66,20 @@ export async function startRepl(program, resumeMode) {
66
66
  console.log(chalk.bold.white(' ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝'));
67
67
  console.log();
68
68
  console.log(chalk.bold.yellow(' The World\'s First'));
69
- console.log(chalk.bold.white(' AI-Native CLI Platform for Global'));
70
- console.log(chalk.bold.white(' Cybersecurity Education & Competition'));
69
+ console.log(chalk.bold.white(' AI-Native CLI Operating System for'));
70
+ console.log(chalk.bold.white(' Cybersecurity & AI Security Competition'));
71
71
  console.log();
72
72
  console.log(chalk.white(' One terminal. 15 languages. 15,000 concurrent participants.'));
73
+ console.log(chalk.white(' 109 pre-configured CTF tools. Zero browser required.'));
73
74
  console.log();
74
75
  console.log(chalk.cyan(' ─────────────────────────────────────────────────'));
75
76
  console.log();
76
77
  console.log(chalk.bold.white(' What Makes ICOA Different'));
77
- console.log(chalk.gray(' · AI-powered Gemini 3.1 translation, AI teammate, smart hints'));
78
- console.log(chalk.gray(' · CLI-native Zero browser, 100x less bandwidth'));
78
+ console.log(chalk.gray(' · AI-native AI teammate, AI adversary, AI translation'));
79
+ console.log(chalk.gray(' · CLI OS Complete competition environment in terminal'));
80
+ console.log(chalk.gray(' · 109 tools pwntools, z3, gdb, nmap... pre-configured'));
79
81
  console.log(chalk.gray(' · Global scale 15,000+ concurrent exams, single server'));
80
- console.log(chalk.gray(' · 15 languages Real-time AI translation for all challenges'));
82
+ console.log(chalk.gray(' · 15 languages Real-time AI translation for all content'));
81
83
  console.log();
82
84
  console.log(chalk.bold.white(' Competition Format'));
83
85
  console.log(chalk.green.bold(' AI4CTF') + chalk.gray(' [Day 1] AI as your teammate — 5hr jeopardy CTF'));
@@ -199,6 +201,8 @@ export async function startRepl(program, resumeMode) {
199
201
  console.log(chalk.bold.white(' ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝'));
200
202
  console.log();
201
203
  console.log(chalk.yellow(' International Cyber Olympiad in AI 2026'));
204
+ console.log(chalk.bold.magenta(' The World\'s First AI-Native CLI Operating System'));
205
+ console.log(chalk.bold.magenta(' for Cybersecurity & AI Security Competition'));
202
206
  console.log(chalk.gray(' Sydney, Australia · Jun 27 - Jul 2, 2026'));
203
207
  console.log();
204
208
  console.log(chalk.white(' Vision'));
@@ -236,34 +240,49 @@ export async function startRepl(program, resumeMode) {
236
240
  console.log();
237
241
  }
238
242
  else if (connected) {
239
- console.log(chalk.green(` Welcome back, ${config.userName}!`));
243
+ console.log(chalk.green.bold(` Welcome back, ${config.userName}!`));
240
244
  console.log(chalk.gray(` Connected to ${config.ctfdUrl}`));
241
- console.log(chalk.gray(' logout to disconnect'));
245
+ console.log();
246
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
247
+ console.log(chalk.white(' Ready to compete? Start here:'));
248
+ console.log();
249
+ console.log(chalk.bold.cyan(' challenges') + chalk.gray(' Browse challenges by category'));
250
+ console.log(chalk.white(' status') + chalk.gray(' Your score & hint budget'));
251
+ console.log(chalk.white(' scoreboard') + chalk.gray(' Live rankings'));
252
+ console.log(chalk.white(' help') + chalk.gray(' Full command list'));
253
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
242
254
  console.log();
243
255
  }
244
256
  else if (activated) {
245
257
  ensureWorkspace();
246
- console.log(chalk.green(' Welcome, competitor! Ready to hack.'));
258
+ console.log(chalk.green.bold(' Welcome, competitor!'));
247
259
  console.log(chalk.gray(` Workspace: ${WORKSPACE}`));
248
260
  console.log();
249
- console.log(chalk.gray(' Quick Start'));
250
- console.log(chalk.gray(' ─────────────'));
251
- console.log(chalk.white(' join <url> ') + chalk.gray('Connect to competition'));
252
- console.log(chalk.white(' challenges ') + chalk.gray('View challenges'));
253
- console.log(chalk.white(' hint <question> ') + chalk.gray('Ask AI for help'));
254
- console.log(chalk.white(' env ') + chalk.gray('Check your tools'));
255
- console.log(chalk.white(' help ') + chalk.gray('All commands'));
261
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
262
+ console.log(chalk.white(' Get started:'));
263
+ console.log();
264
+ console.log(chalk.white(' Step 1 ') + chalk.bold.cyan('join <url>') + chalk.gray(' Connect to competition server'));
265
+ console.log(chalk.white(' Step 2 ') + chalk.bold.cyan('challenges') + chalk.gray(' Browse & solve challenges'));
266
+ console.log(chalk.white(' Step 3 ') + chalk.bold.cyan('hint') + chalk.gray(' Ask AI when stuck'));
267
+ console.log();
268
+ console.log(chalk.gray(' Also: ') + chalk.white('env') + chalk.gray(' check tools ') + chalk.white('help') + chalk.gray(' all commands'));
269
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
256
270
  console.log();
257
271
  }
258
272
  else {
259
- console.log(chalk.white(' Welcome to ICOA CLI!'));
273
+ console.log(chalk.bold.white(' Welcome to ICOA CLI — International Olympiad'));
274
+ console.log();
275
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
276
+ console.log(chalk.white(' To begin, activate your competition token:'));
260
277
  console.log();
261
- console.log(chalk.gray(' Quick Start'));
262
- console.log(chalk.gray(' ─────────────'));
263
- console.log(chalk.white(' activate <token> ') + chalk.gray('Unlock with your access token'));
264
- console.log(chalk.white(' ref <topic> ') + chalk.gray('Browse tool references'));
265
- console.log(chalk.white(' env ') + chalk.gray('Check your tools'));
266
- console.log(chalk.white(' help ') + chalk.gray('All commands'));
278
+ console.log(chalk.bold.cyan(' activate <token>'));
279
+ console.log();
280
+ console.log(chalk.gray(' While waiting, explore:'));
281
+ console.log(chalk.white(' ref linux') + chalk.gray(' Quick reference for Linux'));
282
+ console.log(chalk.white(' ref web') + chalk.gray(' Quick reference for Web'));
283
+ console.log(chalk.white(' env') + chalk.gray(' Check your tools'));
284
+ console.log(chalk.white(' help') + chalk.gray(' All available commands'));
285
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
267
286
  console.log();
268
287
  }
269
288
  }
@@ -729,33 +748,35 @@ function printReplHelp(activated, mode = 'olympiad') {
729
748
  console.log();
730
749
  return;
731
750
  }
751
+ // How it works — workflow overview
752
+ console.log(chalk.cyan(' ═══════════════════════════════════════════════'));
753
+ console.log(chalk.bold.white(' How it works'));
754
+ console.log();
755
+ console.log(chalk.gray(' 1. Browse ') + chalk.white('challenges') + chalk.gray(' and pick one'));
756
+ console.log(chalk.gray(' 2. ') + chalk.white('open <id>') + chalk.gray(' to read the challenge'));
757
+ console.log(chalk.gray(' 3. Use ') + chalk.white('hint') + chalk.gray(' / ') + chalk.white('hint-b') + chalk.gray(' / ') + chalk.white('hint-c') + chalk.gray(' when stuck'));
758
+ console.log(chalk.gray(' 4. ') + chalk.white('submit <id> icoa{flag}') + chalk.gray(' to score points'));
759
+ console.log(chalk.gray(' 5. Check ') + chalk.white('scoreboard') + chalk.gray(' to track your rank'));
760
+ console.log(chalk.cyan(' ═══════════════════════════════════════════════'));
761
+ console.log();
732
762
  console.log(chalk.bold.white(' Competition'));
733
763
  console.log(chalk.white(' join <url> ') + chalk.gray('Connect to CTFd'));
734
- console.log(chalk.white(' challenges (ch) ') + chalk.gray('List challenges'));
735
- console.log(chalk.white(' open <id> ') + chalk.gray('View challenge details'));
764
+ console.log(chalk.white(' challenges (ch) ') + chalk.gray('List challenges by category'));
765
+ console.log(chalk.white(' open <id> ') + chalk.gray('Read challenge + get next steps'));
736
766
  console.log(chalk.white(' submit <id> <flag> ') + chalk.gray('Submit a flag'));
737
- console.log(chalk.white(' scoreboard (sb) ') + chalk.gray('View scoreboard'));
738
- console.log(chalk.white(' status ') + chalk.gray('Competition status'));
767
+ console.log(chalk.white(' scoreboard (sb) ') + chalk.gray('Live rankings'));
768
+ console.log(chalk.white(' status ') + chalk.gray('Your score, budget & timer'));
739
769
  console.log(chalk.white(' time ') + chalk.gray('Countdown timer'));
740
770
  console.log();
741
- console.log(chalk.bold.white(' Exam'));
742
- console.log(chalk.white(' exam list ') + chalk.gray('Available exams'));
743
- console.log(chalk.white(' exam start <id> ') + chalk.gray('Begin an exam'));
744
- console.log(chalk.white(' exam q [n] ') + chalk.gray('View questions'));
745
- console.log(chalk.white(' exam answer <n> <X> ') + chalk.gray('Answer question'));
746
- console.log(chalk.white(' exam review ') + chalk.gray('Review all answers'));
747
- console.log(chalk.white(' exam submit ') + chalk.gray('Submit for grading'));
748
- console.log(chalk.white(' exam result ') + chalk.gray('View your score'));
749
- console.log();
750
- console.log(chalk.bold.white(' AI'));
751
- console.log(chalk.white(' ai4ctf ') + chalk.gray('Chat with your AI teammate'));
752
- console.log(chalk.white(' hint <question> ') + chalk.gray('Level A — General guidance'));
753
- console.log(chalk.white(' hint-b <question> ') + chalk.gray('Level B — Deep analysis'));
754
- console.log(chalk.white(' hint-c <question> ') + chalk.gray('Level C — Critical assist'));
755
- console.log(chalk.white(' hint budget ') + chalk.gray('Check remaining budget'));
771
+ console.log(chalk.bold.white(' AI Teammate') + chalk.gray(' — 3 levels, use wisely'));
772
+ console.log(chalk.white(' hint "question" ') + chalk.gray('Level A — General guidance (50 uses)'));
773
+ console.log(chalk.white(' hint-b "question" ') + chalk.gray('Level B — Deep analysis (10 uses)'));
774
+ console.log(chalk.white(' hint-c "question" ') + chalk.gray('Level C — Critical assist (2 uses)'));
775
+ console.log(chalk.white(' hint budget ') + chalk.gray('Check remaining uses'));
776
+ console.log(chalk.white(' ai4ctf ') + chalk.gray('Free-chat with AI (no limit)'));
756
777
  console.log();
757
778
  console.log(chalk.bold.white(' Tools'));
758
- console.log(chalk.white(' ref [topic] ') + chalk.gray('Quick reference'));
779
+ console.log(chalk.white(' ref [topic] ') + chalk.gray('Quick reference (linux, web, crypto...)'));
759
780
  console.log(chalk.white(' shell ') + chalk.gray('Docker sandbox'));
760
781
  console.log(chalk.white(' files <id> ') + chalk.gray('Download challenge files'));
761
782
  console.log(chalk.white(' connect <id> ') + chalk.gray('Connect to remote target'));
@@ -764,7 +785,8 @@ function printReplHelp(activated, mode = 'olympiad') {
764
785
  console.log();
765
786
  console.log(chalk.bold.white(' System'));
766
787
  console.log(chalk.white(' setup ') + chalk.gray('Configure settings'));
767
- console.log(chalk.white(' lang [code] ') + chalk.gray('Switch language'));
788
+ console.log(chalk.white(' lang [code] ') + chalk.gray('Switch language (15 supported)'));
789
+ console.log(chalk.white(' logout ') + chalk.gray('Disconnect'));
768
790
  console.log(chalk.white(' clear ') + chalk.gray('Clear screen'));
769
791
  console.log(chalk.white(' exit ') + chalk.gray('Quit (session saved)'));
770
792
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "2.19.8",
3
+ "version": "2.19.10",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {