icoa-cli 2.15.2 → 2.15.4
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/commands/exam.js +11 -8
- package/dist/repl.js +26 -1
- package/package.json +1 -1
package/dist/commands/exam.js
CHANGED
|
@@ -85,6 +85,8 @@ function printQuestion(q, answer) {
|
|
|
85
85
|
const answered = Object.keys(state?.answers || {}).length;
|
|
86
86
|
const help = getHelpState(state);
|
|
87
87
|
const eliminated = help.eliminated[q.number] || [];
|
|
88
|
+
// Top hint
|
|
89
|
+
console.log(chalk.gray(' Type "back" to pause · Don\'t type "exit" (it quits CLI)'));
|
|
88
90
|
// Progress bar
|
|
89
91
|
printQuestionProgress(q.number, total, answered);
|
|
90
92
|
// Easter egg
|
|
@@ -110,14 +112,15 @@ function printQuestion(q, answer) {
|
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
console.log();
|
|
113
|
-
//
|
|
115
|
+
// Bottom navigation
|
|
114
116
|
const remaining = help.max - help.used;
|
|
115
117
|
const helpHint = remaining > 0
|
|
116
118
|
? chalk.yellow('help') + chalk.gray(` (${remaining}/${help.max})`)
|
|
117
119
|
: (help.max < 8 ? chalk.gray('help 0/5 — type ') + chalk.yellow('more help') : chalk.gray('help 0/8'));
|
|
118
|
-
console.log(chalk.gray('
|
|
120
|
+
console.log(chalk.gray(' ') + chalk.white('A') + chalk.gray('/') + chalk.white('B') + chalk.gray('/') + chalk.white('C') + chalk.gray('/') + chalk.white('D') + chalk.gray(' to answer · ') + helpHint +
|
|
119
121
|
(q.number > 1 ? chalk.gray(' · ') + chalk.white('prev') : '') +
|
|
120
|
-
(q.number < total ? chalk.gray(' · ') + chalk.white('next') : '')
|
|
122
|
+
(q.number < total ? chalk.gray(' · ') + chalk.white('next') : '') +
|
|
123
|
+
chalk.gray(' · ') + chalk.white('back'));
|
|
121
124
|
}
|
|
122
125
|
export function registerExamCommand(program) {
|
|
123
126
|
const exam = program.command('exam').description('National selection exam');
|
|
@@ -128,7 +131,7 @@ export function registerExamCommand(program) {
|
|
|
128
131
|
.action(() => {
|
|
129
132
|
logCommand('exam nations');
|
|
130
133
|
console.log();
|
|
131
|
-
printHeader('ICOA Participating Countries');
|
|
134
|
+
printHeader('ICOA Participating Countries and Regions');
|
|
132
135
|
console.log();
|
|
133
136
|
const nations = [
|
|
134
137
|
['AU', 'Australia'], ['BR', 'Brazil'], ['CN', 'China'],
|
|
@@ -146,8 +149,8 @@ export function registerExamCommand(program) {
|
|
|
146
149
|
console.log(row);
|
|
147
150
|
}
|
|
148
151
|
console.log();
|
|
149
|
-
console.log(chalk.gray(' 40+ countries and regions
|
|
150
|
-
console.log(chalk.gray(' New
|
|
152
|
+
console.log(chalk.gray(' 40+ countries and regions represented'));
|
|
153
|
+
console.log(chalk.gray(' New member? Contact: accreditation@icoa2026.au'));
|
|
151
154
|
console.log();
|
|
152
155
|
console.log(chalk.white(' Check exams for your country:'));
|
|
153
156
|
console.log(chalk.cyan(' exam list AU') + chalk.gray(' exam list PE') + chalk.gray(' exam list CN'));
|
|
@@ -212,7 +215,7 @@ export function registerExamCommand(program) {
|
|
|
212
215
|
];
|
|
213
216
|
});
|
|
214
217
|
const countries = [...new Set(exams.map((e) => e.country))];
|
|
215
|
-
printHeader(country ? `Exams — ${country.toUpperCase()}` : `Available Exams (${countries.length}
|
|
218
|
+
printHeader(country ? `Exams — ${country.toUpperCase()}` : `Available Exams (${countries.length} regions)`);
|
|
216
219
|
printTable(['ID', 'Name', 'Country', 'Questions', 'Duration', 'Status'], rows);
|
|
217
220
|
console.log();
|
|
218
221
|
console.log(chalk.gray(' Start: exam start <id>'));
|
|
@@ -671,7 +674,7 @@ export function registerExamCommand(program) {
|
|
|
671
674
|
console.log(chalk.red.bold(' ctf4ai') + chalk.gray(' Trick the AI — make it say "koala"'));
|
|
672
675
|
console.log();
|
|
673
676
|
console.log(chalk.gray(' For national selection exams:'));
|
|
674
|
-
console.log(chalk.white(' nations') + chalk.gray(' View all
|
|
677
|
+
console.log(chalk.white(' nations') + chalk.gray(' View all participating regions'));
|
|
675
678
|
console.log(chalk.white(' exam AU') + chalk.gray(' Enter Australia selection exam'));
|
|
676
679
|
console.log();
|
|
677
680
|
}
|
package/dist/repl.js
CHANGED
|
@@ -84,7 +84,7 @@ export async function startRepl(program, resumeMode) {
|
|
|
84
84
|
console.log(chalk.red.bold(' CTF4AI') + chalk.gray(' [Day 2] Hack & evaluate AI — adversarial ML, red-teaming'));
|
|
85
85
|
console.log();
|
|
86
86
|
console.log(chalk.white(' Sydney, Australia') + chalk.gray(' · Jun 27 - Jul 2, 2026'));
|
|
87
|
-
console.log(chalk.gray(' 40+
|
|
87
|
+
console.log(chalk.gray(' 40+ countries and regions represented'));
|
|
88
88
|
console.log();
|
|
89
89
|
console.log(chalk.cyan(' ─────────────────────────────────────────────────'));
|
|
90
90
|
console.log();
|
|
@@ -318,6 +318,16 @@ export async function startRepl(program, resumeMode) {
|
|
|
318
318
|
logCommand(input);
|
|
319
319
|
// Exit — record, reset terminal colors, and quit
|
|
320
320
|
if (input === 'exit' || input === 'quit' || input === 'q') {
|
|
321
|
+
// During exam, warn and suggest back instead
|
|
322
|
+
if (getExamState()) {
|
|
323
|
+
console.log();
|
|
324
|
+
console.log(chalk.yellow(' ⚠ "exit" will close ICOA CLI entirely.'));
|
|
325
|
+
console.log(chalk.white(' To return to menu without quitting, type: ') + chalk.bold.cyan('back'));
|
|
326
|
+
console.log(chalk.gray(' Your exam progress is auto-saved.'));
|
|
327
|
+
console.log();
|
|
328
|
+
rl.prompt();
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
321
331
|
// stopLogSync();
|
|
322
332
|
recordExit();
|
|
323
333
|
console.log(chalk.gray(' Session saved. Use ') + chalk.white('icoa --resume') + chalk.gray(' to continue.'));
|
|
@@ -325,6 +335,21 @@ export async function startRepl(program, resumeMode) {
|
|
|
325
335
|
realExit(0);
|
|
326
336
|
return;
|
|
327
337
|
}
|
|
338
|
+
// "back" — return to main menu (clear exam state for demo, keep for real)
|
|
339
|
+
if (input === 'back') {
|
|
340
|
+
const state = getExamState();
|
|
341
|
+
if (state) {
|
|
342
|
+
console.log();
|
|
343
|
+
console.log(chalk.gray(' Exam paused. Your progress is saved.'));
|
|
344
|
+
console.log(chalk.white(' Resume: exam q 1') + chalk.gray(' · ') + chalk.white('exam review') + chalk.gray(' · ') + chalk.white('exam submit'));
|
|
345
|
+
console.log();
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
console.log(chalk.gray(' Already at main menu.'));
|
|
349
|
+
}
|
|
350
|
+
rl.prompt();
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
328
353
|
// Help — during exam, route to exam help; otherwise show REPL help
|
|
329
354
|
if (input === 'help' || input === '?') {
|
|
330
355
|
if (getExamState()) {
|