icoa-cli 2.19.47 → 2.19.48
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.
- package/dist/repl.js +47 -10
- package/package.json +1 -1
package/dist/repl.js
CHANGED
|
@@ -7,6 +7,9 @@ import { setReplMode } from './lib/ui.js';
|
|
|
7
7
|
import { isChatActive, handleChatMessage } from './commands/ai4ctf.js';
|
|
8
8
|
import { isCtf4aiActive, handleCtf4aiMessage } from './commands/ctf4ai-demo.js';
|
|
9
9
|
import { getExamState } from './lib/exam-state.js';
|
|
10
|
+
import { getDemoStats } from './lib/demo-stats.js';
|
|
11
|
+
import { isExamSetupComplete } from './lib/exam-setup.js';
|
|
12
|
+
import { DEMO_PICK_SIZE, DEMO_POOL_SIZE } from './lib/demo-exam.js';
|
|
10
13
|
import { resetTerminalTheme } from './lib/theme.js';
|
|
11
14
|
import { ensureSandbox, runInSandbox, isDockerAvailable } from './lib/sandbox.js';
|
|
12
15
|
import { logCommand } from './lib/logger.js';
|
|
@@ -33,20 +36,54 @@ const BLOCKED_COMMANDS = new Set([
|
|
|
33
36
|
const INTERCEPT = '__REPL_NO_EXIT__';
|
|
34
37
|
const VERSION = '2.5.1';
|
|
35
38
|
// National Selection main menu — shown on REPL entry and when user types `back`
|
|
36
|
-
// after finishing the demo flow.
|
|
39
|
+
// after finishing the demo flow. Progressive onboarding per spec
|
|
40
|
+
// docs/superpowers/specs/2026-04-13-exam-national-selection-design.md §4.1:
|
|
41
|
+
// State 0 (no demo yet): recommend demo, hide exam setup / exam <token>
|
|
42
|
+
// State 1 (demo done, no setup): show demo completion + setup CTA, hide token
|
|
43
|
+
// State 2 (demo done + setup done): show token entry CTA
|
|
37
44
|
function printSelectionMenu() {
|
|
45
|
+
const stats = getDemoStats();
|
|
46
|
+
const setupDone = isExamSetupComplete();
|
|
47
|
+
const demoLine = `Free practice — ${DEMO_PICK_SIZE} questions (from pool of ${DEMO_POOL_SIZE})`;
|
|
38
48
|
console.log();
|
|
39
49
|
console.log(' ' + chalk.cyan.bold('[Selection Mode]'));
|
|
40
50
|
console.log();
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
if (stats.attempts === 0) {
|
|
52
|
+
// State 0: brand new user. Only demo matters right now.
|
|
53
|
+
console.log(chalk.white(' New here? Start with ') + chalk.bold.cyan('demo') + chalk.white(' — it takes a few minutes.'));
|
|
54
|
+
console.log();
|
|
55
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
56
|
+
console.log(chalk.bold.cyan(' demo') + chalk.gray(` ${demoLine}`));
|
|
57
|
+
console.log(chalk.white(' lang es') + chalk.gray(' Switch language (17 supported)'));
|
|
58
|
+
console.log(chalk.gray(' e.g. lang es (Español), lang zh, lang fr'));
|
|
59
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
60
|
+
}
|
|
61
|
+
else if (!setupDone) {
|
|
62
|
+
// State 1: demo done at least once, but exam environment not installed.
|
|
63
|
+
const plural = stats.attempts === 1 ? 'attempt' : 'attempts';
|
|
64
|
+
console.log(chalk.green(' ✓ Demo completed ') + chalk.gray(`(${stats.attempts} ${plural}${stats.bestPercentage > 0 ? ` · best ${stats.bestPercentage}%` : ''})`));
|
|
65
|
+
console.log(chalk.yellow(' → Next: prepare your environment for the real exam.'));
|
|
66
|
+
console.log();
|
|
67
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
68
|
+
console.log(chalk.white(' demo') + chalk.gray(` ${demoLine}`));
|
|
69
|
+
console.log(chalk.bold.yellow(' exam setup') + chalk.gray(' Install tools for national selection (~150MB)'));
|
|
70
|
+
console.log(chalk.white(' lang es') + chalk.gray(' Switch language (17 supported)'));
|
|
71
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// State 2: fully prepared. Show the token entry CTA.
|
|
75
|
+
const plural = stats.attempts === 1 ? 'attempt' : 'attempts';
|
|
76
|
+
console.log(chalk.green(' ✓ Demo completed ') + chalk.gray(`(${stats.attempts} ${plural})`));
|
|
77
|
+
console.log(chalk.green(' ✓ Environment ready'));
|
|
78
|
+
console.log(chalk.yellow(' → Enter your exam token to begin.'));
|
|
79
|
+
console.log();
|
|
80
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
81
|
+
console.log(chalk.white(' demo') + chalk.gray(` ${demoLine}`));
|
|
82
|
+
console.log(chalk.bold.yellow(' exam <token>') + chalk.gray(' Enter exam with access token'));
|
|
83
|
+
console.log(chalk.white(' exam setup') + chalk.gray(' Re-verify tool environment'));
|
|
84
|
+
console.log(chalk.white(' lang es') + chalk.gray(' Switch language (17 supported)'));
|
|
85
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
86
|
+
}
|
|
50
87
|
console.log();
|
|
51
88
|
}
|
|
52
89
|
export async function startRepl(program, resumeMode) {
|