icoa-cli 2.7.2 → 2.8.0
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 +5 -7
- package/dist/repl.js +32 -0
- package/package.json +1 -1
package/dist/commands/exam.js
CHANGED
|
@@ -85,13 +85,9 @@ function printQuestion(q, answer) {
|
|
|
85
85
|
}
|
|
86
86
|
console.log();
|
|
87
87
|
// Navigation hint
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (q.number < total)
|
|
92
|
-
nav.push('exam next');
|
|
93
|
-
nav.push(`exam answer ${q.number} <A-D>`);
|
|
94
|
-
console.log(chalk.gray(` ${nav.join(' · ')}`));
|
|
88
|
+
console.log(chalk.gray(' Type ') + chalk.white('A') + chalk.gray('/') + chalk.white('B') + chalk.gray('/') + chalk.white('C') + chalk.gray('/') + chalk.white('D') + chalk.gray(' to answer') +
|
|
89
|
+
(q.number > 1 ? chalk.gray(' · ') + chalk.white('prev') : '') +
|
|
90
|
+
(q.number < total ? chalk.gray(' · ') + chalk.white('next') : ''));
|
|
95
91
|
}
|
|
96
92
|
export function registerExamCommand(program) {
|
|
97
93
|
const exam = program.command('exam').description('National selection exam');
|
|
@@ -210,6 +206,8 @@ export function registerExamCommand(program) {
|
|
|
210
206
|
printError(`Question ${n} not found (1-${state.questions.length}).`);
|
|
211
207
|
return;
|
|
212
208
|
}
|
|
209
|
+
state._lastQ = num;
|
|
210
|
+
saveExamState(state);
|
|
213
211
|
printQuestion(q, state.answers[num]);
|
|
214
212
|
}
|
|
215
213
|
else {
|
package/dist/repl.js
CHANGED
|
@@ -5,6 +5,7 @@ import { isConnected, getConfig, saveConfig } from './lib/config.js';
|
|
|
5
5
|
import { isActivated, activateToken, isFreeCommand, isDeviceMatch, recordExit, recordResume, isFirstRunOrUpgrade, markVersionSeen } from './lib/access.js';
|
|
6
6
|
import { setReplMode } from './lib/ui.js';
|
|
7
7
|
import { isChatActive, handleChatMessage } from './commands/ai4ctf.js';
|
|
8
|
+
import { getExamState } from './lib/exam-state.js';
|
|
8
9
|
import { resetTerminalTheme } from './lib/theme.js';
|
|
9
10
|
import { ensureSandbox, runInSandbox, isDockerAvailable } from './lib/sandbox.js';
|
|
10
11
|
import { logCommand } from './lib/logger.js';
|
|
@@ -271,6 +272,37 @@ export async function startRepl(program, resumeMode) {
|
|
|
271
272
|
rl.prompt();
|
|
272
273
|
return;
|
|
273
274
|
}
|
|
275
|
+
// ─── Quick exam answer shortcuts ───
|
|
276
|
+
// "A" / "B" / "C" / "D" → answer current question
|
|
277
|
+
// "2 C" / "5 A" → answer specific question
|
|
278
|
+
const examState = getExamState();
|
|
279
|
+
if (examState) {
|
|
280
|
+
const upper = input.toUpperCase().trim();
|
|
281
|
+
// Single letter: A, B, C, D → answer current question
|
|
282
|
+
if (/^[ABCD]$/.test(upper)) {
|
|
283
|
+
const currentQ = examState._lastQ || 1;
|
|
284
|
+
processing = true;
|
|
285
|
+
try {
|
|
286
|
+
await program.parseAsync(['node', 'icoa', 'exam', 'answer', String(currentQ), upper]);
|
|
287
|
+
}
|
|
288
|
+
catch { }
|
|
289
|
+
processing = false;
|
|
290
|
+
rl.prompt();
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
// "N X" pattern: e.g. "2 C", "15 A"
|
|
294
|
+
const match = upper.match(/^(\d+)\s+([ABCD])$/);
|
|
295
|
+
if (match) {
|
|
296
|
+
processing = true;
|
|
297
|
+
try {
|
|
298
|
+
await program.parseAsync(['node', 'icoa', 'exam', 'answer', match[1], match[2]]);
|
|
299
|
+
}
|
|
300
|
+
catch { }
|
|
301
|
+
processing = false;
|
|
302
|
+
rl.prompt();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
274
306
|
const cmd = input.split(/\s+/)[0].toLowerCase();
|
|
275
307
|
// ─── Mode-based command filtering ───
|
|
276
308
|
const selectionCommands = ['join', 'exam', 'demo', 'next', 'prev', 'setup', 'lang', 'ref', 'ctf'];
|