icoa-cli 2.19.27 → 2.19.28

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.
@@ -2,10 +2,13 @@ import chalk from 'chalk';
2
2
  import { logCommand } from '../lib/logger.js';
3
3
  import { printError } from '../lib/ui.js';
4
4
  import { getConfig } from '../lib/config.js';
5
+ import { getRetryQueue } from '../lib/demo-stats.js';
5
6
  import { t } from '../lib/i18n.js';
6
7
  function printDemoReport(ctf4aiSolved, ctf4aiTokens) {
7
8
  const config = getConfig();
8
9
  const modelName = config.geminiModel || 'gemma-4-31b-it';
10
+ const retryQueue = getRetryQueue();
11
+ const hasWrongAnswers = !!(retryQueue && retryQueue.length > 0);
9
12
  console.log();
10
13
  console.log(chalk.cyan(' ═══════════════════════════════════════════════'));
11
14
  console.log(chalk.bold.white(` ${t('reportTitle')}`));
@@ -40,10 +43,25 @@ function printDemoReport(ctf4aiSolved, ctf4aiTokens) {
40
43
  console.log();
41
44
  console.log(chalk.cyan(' ─────────────────────────────────────────────'));
42
45
  console.log();
46
+ // Context framing (moved here from stage 1 end — user has now lived through
47
+ // all three stages, so the "theory vs real competition" callout lands with
48
+ // real meaning).
49
+ console.log(chalk.white(` ${t('theoryDone')}`));
50
+ console.log(chalk.white(` ${t('theoryDone2')}`));
51
+ console.log();
52
+ if (hasWrongAnswers) {
53
+ console.log(chalk.white(' 💪 Want to nail the ones you missed? Type: ') + chalk.bold.cyan('retry'));
54
+ console.log();
55
+ }
56
+ console.log(chalk.cyan(' ─────────────────────────────────────────────'));
43
57
  console.log(chalk.white(` ${t('reportReady')}`));
58
+ if (hasWrongAnswers) {
59
+ console.log(chalk.cyan(' retry') + chalk.gray(` retry the ${retryQueue.length} wrong question${retryQueue.length > 1 ? 's' : ''}`));
60
+ }
61
+ console.log(chalk.white(' back') + chalk.gray(` return to main menu`));
62
+ console.log(chalk.white(' demo') + chalk.gray(` ${t('reportDemo')}`));
44
63
  console.log(chalk.white(' nations') + chalk.gray(` ${t('reportNations')}`));
45
64
  console.log(chalk.white(' about') + chalk.gray(` ${t('reportAbout')}`));
46
- console.log(chalk.white(' demo') + chalk.gray(` ${t('reportDemo')}`));
47
65
  console.log();
48
66
  console.log(chalk.yellow(' ICOA 2026 · Sydney, Australia · Jun 27 - Jul 2'));
49
67
  console.log(chalk.cyan.underline(' https://icoa2026.au'));
@@ -904,39 +904,17 @@ export function registerExamCommand(program) {
904
904
  console.log();
905
905
  console.log(chalk.green(` ${t('perfectScore')}`));
906
906
  }
907
- // Offer retry wrong only
908
- if (wrongQuestions.length > 0) {
909
- console.log();
910
- console.log(chalk.white(' 💪 Want to nail the ones you missed? Type: ') + chalk.bold.cyan('retry'));
911
- }
912
- await sleep(3000);
913
- console.log();
914
- // ─── What is CTF + Dual-track introduction ───
915
- console.log(chalk.white(` ${t('theoryDone')}`));
916
- console.log(chalk.white(` ${t('theoryDone2')}`));
917
- console.log();
918
- console.log(chalk.yellow(` ${t('didYouKnow')}`));
919
- console.log(chalk.gray(` ${t('ctfFlags1')}`));
920
- console.log(chalk.gray(` ${t('ctfFlags2')}`));
921
- console.log(chalk.green(' icoa{example_flag_here}'));
922
- console.log(chalk.gray(` ${t('ctfFlags3')}`));
907
+ // Stage 1 ends here. Retry hint, CTF intro, and dual-track overview
908
+ // are deferred to the final report printed after ctf4ai so the flow
909
+ // feels: theory → ai4ctf → ctf4ai → one combined report + retry/back.
910
+ // The retry queue was already persisted above, so the final report
911
+ // can surface it later via getRetryQueue().
912
+ await sleep(2000);
923
913
  console.log();
924
- console.log(chalk.white(` ${t('twoTracks')}`));
925
- console.log();
926
- console.log(chalk.green.bold(' AI4CTF') + chalk.white(` — ${t('ai4ctfDesc')}`));
914
+ console.log(chalk.cyan(' ─────────────────────────────────────────────'));
915
+ console.log(chalk.white(' Next: ') + chalk.bold.green('ai4ctf') + chalk.gray(` — ${t('ai4ctfDesc')}`));
927
916
  console.log(chalk.gray(` ${t('ai4ctfSub')}`));
928
- console.log();
929
- console.log(chalk.red.bold(' CTF4AI') + chalk.white(` — ${t('ctf4aiDesc')}`));
930
- console.log(chalk.gray(` ${t('ctf4aiSub')}`));
931
- console.log();
932
917
  console.log(chalk.cyan(' ─────────────────────────────────────────────'));
933
- console.log(chalk.white(` ${t('readyToTry')}`));
934
- console.log(chalk.green.bold(' ai4ctf') + chalk.gray(` ${t('ai4ctfDesc')}`));
935
- console.log(chalk.red.bold(' ctf4ai') + chalk.gray(` ${t('ctf4aiDesc')}`));
936
- console.log();
937
- console.log(chalk.gray(` ${t('forNational')}`));
938
- console.log(chalk.white(' nations') + chalk.gray(` ${t('viewRegions')}`));
939
- console.log(chalk.white(' exam AU') + chalk.gray(` ${t('enterExam')}`));
940
918
  console.log();
941
919
  }
942
920
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "2.19.27",
3
+ "version": "2.19.28",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {