icoa-cli 2.19.45 → 2.19.47

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.
@@ -235,7 +235,14 @@ export async function handleChatMessage(input) {
235
235
  console.log(chalk.gray(` ${t('ai4ctfModel')}: Google Gemma 4 (gemma-4-31b-it)`));
236
236
  console.log(chalk.gray(' ─────────────────────────────────────────'));
237
237
  console.log();
238
- console.log(chalk.white(` ${t('ai4ctfNext')}`));
238
+ // Prominent transition to CTF4AI — same style as exam → ai4ctf handoff.
239
+ console.log(chalk.cyan(' ─────────────────────────────────────────────'));
240
+ console.log(chalk.white(` ${t('ai4ctfExitNextTitle')} `) + chalk.bold.red('ctf4ai') + chalk.white(` — ${t('ai4ctfExitNextSub')}`));
241
+ console.log(chalk.gray(` ${t('ai4ctfExitNextBody')}`));
242
+ console.log(chalk.cyan(' ─────────────────────────────────────────────'));
243
+ console.log();
244
+ console.log(chalk.bold.red(' ctf4ai') + chalk.gray(` ${t('ai4ctfExitCmdNext')}`));
245
+ console.log(chalk.white(' back') + chalk.gray(` ${t('ai4ctfExitCmdBack')}`));
239
246
  console.log();
240
247
  return 'exit';
241
248
  }
@@ -61,9 +61,9 @@ function printDemoReport(ctf4aiSolved, ctf4aiTokens) {
61
61
  const tmpl = n === 1 ? t('reportRetryWrongN') : t('reportRetryWrongNPlural');
62
62
  console.log(chalk.cyan(' retry') + chalk.gray(` ${tmpl.replace('{n}', String(n))}`));
63
63
  }
64
+ console.log(chalk.cyan(' exam setup') + chalk.gray(` ${t('reportExamSetupHint')}`));
64
65
  console.log(chalk.white(' back') + chalk.gray(` ${t('reportBackHint')}`));
65
66
  console.log(chalk.white(' demo') + chalk.gray(` ${t('reportDemo')}`));
66
- console.log(chalk.white(' nations') + chalk.gray(` ${t('reportNations')}`));
67
67
  console.log(chalk.white(' about') + chalk.gray(` ${t('reportAboutHint')}`));
68
68
  console.log();
69
69
  console.log(chalk.yellow(' ICOA 2026 · Sydney, Australia · Jun 27 - Jul 2'));
@@ -147,6 +147,12 @@ export declare const EN: {
147
147
  reportRetryWrongNPlural: string;
148
148
  reportBackHint: string;
149
149
  reportAboutHint: string;
150
+ reportExamSetupHint: string;
151
+ ai4ctfExitNextTitle: string;
152
+ ai4ctfExitNextSub: string;
153
+ ai4ctfExitNextBody: string;
154
+ ai4ctfExitCmdNext: string;
155
+ ai4ctfExitCmdBack: string;
150
156
  ai4ctfWelcomeCta: string;
151
157
  ai4ctfHintNudge: string;
152
158
  ai4ctfHintTechnique: string;
package/dist/lib/i18n.js CHANGED
@@ -163,6 +163,13 @@ export const EN = {
163
163
  reportRetryWrongNPlural: 'retry the {n} wrong questions',
164
164
  reportBackHint: 'return to main menu',
165
165
  reportAboutHint: 'Learn more about ICOA 2026',
166
+ reportExamSetupHint: 'next level: prepare tools for national selection',
167
+ // AI4CTF exit → CTF4AI transition (v2.19.47)
168
+ ai4ctfExitNextTitle: 'Next:',
169
+ ai4ctfExitNextSub: 'Challenge the AI (Prompt Injection)',
170
+ ai4ctfExitNextBody: 'Can you make an AI violate its own safety rules?',
171
+ ai4ctfExitCmdNext: 'start the next challenge',
172
+ ai4ctfExitCmdBack: 'return to main menu',
166
173
  // ai4ctf welcome / CTA (v2.19.30–32)
167
174
  ai4ctfWelcomeCta: '👉 New here? Start with the hints in order:',
168
175
  ai4ctfHintNudge: 'nudge',
package/dist/repl.js CHANGED
@@ -32,6 +32,23 @@ const BLOCKED_COMMANDS = new Set([
32
32
  ]);
33
33
  const INTERCEPT = '__REPL_NO_EXIT__';
34
34
  const VERSION = '2.5.1';
35
+ // National Selection main menu — shown on REPL entry and when user types `back`
36
+ // after finishing the demo flow.
37
+ function printSelectionMenu() {
38
+ console.log();
39
+ console.log(' ' + chalk.cyan.bold('[Selection Mode]'));
40
+ console.log();
41
+ console.log(chalk.white(' Ready to start? Just type ') + chalk.bold.cyan('demo') + chalk.white(' and press ') + chalk.yellow('Enter') + chalk.white('!'));
42
+ console.log();
43
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
44
+ console.log(chalk.bold.cyan(' demo') + chalk.gray(' Free practice exam (15 questions)'));
45
+ console.log(chalk.white(' exam setup') + chalk.gray(' Prepare tools for national selection'));
46
+ console.log(chalk.white(' exam <token>') + chalk.gray(' Enter exam with access token'));
47
+ console.log(chalk.white(' lang es') + chalk.gray(' Switch language (15 supported)'));
48
+ console.log(chalk.gray(' e.g. lang es (Español), lang zh, lang fr'));
49
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
50
+ console.log();
51
+ }
35
52
  export async function startRepl(program, resumeMode) {
36
53
  const config = getConfig();
37
54
  const connected = isConnected();
@@ -173,18 +190,7 @@ export async function startRepl(program, resumeMode) {
173
190
  }
174
191
  // ─── Mode-specific welcome ───
175
192
  if (mode === 'selection') {
176
- const modeLabel = chalk.cyan.bold('[Selection Mode]');
177
- console.log(' ' + modeLabel);
178
- console.log();
179
- console.log(chalk.white(' Ready to start? Just type ') + chalk.bold.cyan('demo') + chalk.white(' and press ') + chalk.yellow('Enter') + chalk.white('!'));
180
- console.log();
181
- console.log(chalk.gray(' ─────────────────────────────────────────────'));
182
- console.log(chalk.bold.cyan(' demo') + chalk.gray(' Free practice exam (15 questions)'));
183
- console.log(chalk.white(' exam <token>') + chalk.gray(' Enter exam with access token'));
184
- console.log(chalk.white(' lang es') + chalk.gray(' Switch language (15 supported)'));
185
- console.log(chalk.gray(' e.g. lang es (Español), lang zh, lang fr'));
186
- console.log(chalk.gray(' ─────────────────────────────────────────────'));
187
- console.log();
193
+ printSelectionMenu();
188
194
  }
189
195
  else if (mode === 'organizer') {
190
196
  console.log(chalk.yellow.bold(' [National/Regional Partner]'));
@@ -374,7 +380,14 @@ export async function startRepl(program, resumeMode) {
374
380
  }),
375
381
  signal: AbortSignal.timeout(5000),
376
382
  }).catch(() => { });
377
- console.log(chalk.gray(' Already at main menu.'));
383
+ // Show the National Selection menu so the user always knows what
384
+ // commands are available (demo / exam setup / exam <token>).
385
+ if (mode === 'selection') {
386
+ printSelectionMenu();
387
+ }
388
+ else {
389
+ console.log(chalk.gray(' Already at main menu.'));
390
+ }
378
391
  }
379
392
  rl.prompt();
380
393
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "2.19.45",
3
+ "version": "2.19.47",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {