icoa-cli 2.19.64 → 2.19.66
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/ai4ctf.js +4 -1
- package/dist/commands/ctf4ai-demo.js +4 -1
- package/dist/index.js +35 -1
- package/package.json +1 -1
package/dist/commands/ai4ctf.js
CHANGED
|
@@ -610,7 +610,10 @@ export function registerAi4ctfCommand(program) {
|
|
|
610
610
|
// token budget tracked in state.aiUsage.ai4ctf.
|
|
611
611
|
const { getRealExamState } = await import('../lib/exam-state.js');
|
|
612
612
|
const realExam = getRealExamState();
|
|
613
|
-
if (
|
|
613
|
+
// Only treat as real exam if state actually has the AI4CTF section (Q31-38).
|
|
614
|
+
// Stale/broken state with truncated questions falls back to demo behavior.
|
|
615
|
+
const hasAi4ctfSection = realExam && realExam.questions.some((qq) => qq.number >= 31 && qq.number <= 38);
|
|
616
|
+
if (realExam && hasAi4ctfSection) {
|
|
614
617
|
const currentQ = realExam._lastQ || 1;
|
|
615
618
|
if (currentQ < 31 || currentQ > 38) {
|
|
616
619
|
console.log();
|
|
@@ -460,7 +460,10 @@ export function registerCtf4aiDemoCommand(program) {
|
|
|
460
460
|
// tracked in state.aiUsage.ctf4ai.
|
|
461
461
|
const { getRealExamState } = await import('../lib/exam-state.js');
|
|
462
462
|
const realExam = getRealExamState();
|
|
463
|
-
if (
|
|
463
|
+
// Only treat as real exam if state actually has the CTF4AI section (Q39-40).
|
|
464
|
+
// Stale/broken state with truncated questions falls back to demo behavior.
|
|
465
|
+
const hasCtf4aiSection = realExam && realExam.questions.some((qq) => qq.number >= 39 && qq.number <= 40);
|
|
466
|
+
if (realExam && hasCtf4aiSection) {
|
|
464
467
|
const currentQ = realExam._lastQ || 1;
|
|
465
468
|
if (currentQ < 39) {
|
|
466
469
|
console.log();
|
package/dist/index.js
CHANGED
|
@@ -65,19 +65,53 @@ process.on('unhandledRejection', (reason) => {
|
|
|
65
65
|
console.error(chalk.red('Error:'), msg);
|
|
66
66
|
process.exit(1);
|
|
67
67
|
});
|
|
68
|
+
// Pause for ms, skippable by any key press (so users can read the banner)
|
|
69
|
+
async function pauseWithSkip(ms) {
|
|
70
|
+
const stdin = process.stdin;
|
|
71
|
+
if (!stdin.isTTY || typeof stdin.setRawMode !== 'function') {
|
|
72
|
+
await new Promise((r) => setTimeout(r, ms));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
return new Promise((resolve) => {
|
|
76
|
+
let done = false;
|
|
77
|
+
const finish = () => {
|
|
78
|
+
if (done)
|
|
79
|
+
return;
|
|
80
|
+
done = true;
|
|
81
|
+
stdin.removeListener('data', onKey);
|
|
82
|
+
try {
|
|
83
|
+
stdin.setRawMode(false);
|
|
84
|
+
}
|
|
85
|
+
catch { }
|
|
86
|
+
stdin.pause();
|
|
87
|
+
resolve();
|
|
88
|
+
};
|
|
89
|
+
const onKey = () => finish();
|
|
90
|
+
stdin.setRawMode(true);
|
|
91
|
+
stdin.resume();
|
|
92
|
+
stdin.once('data', onKey);
|
|
93
|
+
console.log(chalk.gray(' (press any key to continue...)'));
|
|
94
|
+
setTimeout(finish, ms);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
68
97
|
const program = new Command();
|
|
69
98
|
program
|
|
70
99
|
.name('icoa')
|
|
71
100
|
.version('1.2.0')
|
|
72
101
|
.description('ICOA CLI — CLI-Native CTF Competition Terminal')
|
|
73
102
|
.option('--resume', 'Resume previous session')
|
|
74
|
-
.action((opts) => {
|
|
103
|
+
.action(async (opts) => {
|
|
75
104
|
// Force hacker theme: black background + green text
|
|
76
105
|
setTerminalTheme();
|
|
77
106
|
checkForUpdates();
|
|
78
107
|
console.log(BANNER);
|
|
79
108
|
// If running interactively (no extra args or --resume), start REPL
|
|
80
109
|
if (process.argv.length <= 2 || opts.resume) {
|
|
110
|
+
// Brief pause so users can read the banner + logo before mode selector appears
|
|
111
|
+
// Skip on --resume (user is coming back, doesn't need the intro)
|
|
112
|
+
if (!opts.resume) {
|
|
113
|
+
await pauseWithSkip(3000);
|
|
114
|
+
}
|
|
81
115
|
startRepl(program, !!opts.resume);
|
|
82
116
|
return;
|
|
83
117
|
}
|