icoa-cli 2.19.8 → 2.19.10
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/ctf.js +73 -9
- package/dist/commands/env.js +24 -0
- package/dist/commands/hint.js +24 -12
- package/dist/index.js +2 -1
- package/dist/repl.js +65 -43
- package/package.json +1 -1
package/dist/commands/ctf.js
CHANGED
|
@@ -151,10 +151,29 @@ export function registerCtfCommands(program) {
|
|
|
151
151
|
console.log();
|
|
152
152
|
printSuccess('Connection saved. You are ready!');
|
|
153
153
|
console.log();
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
const currentMode = getConfig().mode || '';
|
|
155
|
+
if (currentMode === 'olympiad') {
|
|
156
|
+
// Olympiad: guided step-by-step walkthrough
|
|
157
|
+
console.log(chalk.cyan(' ─────────────────────────────────────────────'));
|
|
158
|
+
console.log(chalk.bold.white(' How to compete:'));
|
|
159
|
+
console.log();
|
|
160
|
+
console.log(chalk.white(' Step 1 ') + chalk.bold.cyan('challenges') + chalk.gray(' Browse all challenges'));
|
|
161
|
+
console.log(chalk.white(' Step 2 ') + chalk.bold.cyan('open <id>') + chalk.gray(' Read challenge details'));
|
|
162
|
+
console.log(chalk.white(' Step 3 ') + chalk.bold.cyan('hint "your question"') + chalk.gray(' Ask AI for help'));
|
|
163
|
+
console.log(chalk.white(' Step 4 ') + chalk.bold.cyan('submit <id> <flag>') + chalk.gray(' Submit your answer'));
|
|
164
|
+
console.log();
|
|
165
|
+
console.log(chalk.gray(' More:'));
|
|
166
|
+
console.log(chalk.white(' scoreboard') + chalk.gray(' Live rankings'));
|
|
167
|
+
console.log(chalk.white(' status') + chalk.gray(' Your score & hint budget'));
|
|
168
|
+
console.log(chalk.white(' ai4ctf') + chalk.gray(' Free-chat with AI teammate'));
|
|
169
|
+
console.log(chalk.cyan(' ─────────────────────────────────────────────'));
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
console.log(chalk.gray(' Next:'));
|
|
173
|
+
console.log(chalk.white(' exam list ') + chalk.gray('View available exams'));
|
|
174
|
+
console.log(chalk.white(' challenges ') + chalk.gray('View CTF challenges'));
|
|
175
|
+
console.log(chalk.white(' status ') + chalk.gray('Check score & budget'));
|
|
176
|
+
}
|
|
158
177
|
}
|
|
159
178
|
catch (err) {
|
|
160
179
|
spinner2.fail('Connection test failed');
|
|
@@ -181,6 +200,11 @@ export function registerCtfCommands(program) {
|
|
|
181
200
|
country: '',
|
|
182
201
|
});
|
|
183
202
|
printSuccess('Logged out. Credentials cleared.');
|
|
203
|
+
console.log();
|
|
204
|
+
console.log(chalk.gray(' What now?'));
|
|
205
|
+
console.log(chalk.white(' join <url>') + chalk.gray(' Re-connect to competition'));
|
|
206
|
+
console.log(chalk.white(' setup') + chalk.gray(' Switch mode'));
|
|
207
|
+
console.log(chalk.white(' exit') + chalk.gray(' Quit ICOA CLI'));
|
|
184
208
|
});
|
|
185
209
|
// ─── icoa ctf activate <code> ───
|
|
186
210
|
ctf
|
|
@@ -251,24 +275,54 @@ export function registerCtfCommands(program) {
|
|
|
251
275
|
}
|
|
252
276
|
const solved = challenges.filter((c) => c.solved_by_me).length;
|
|
253
277
|
printHeader(`Challenges (${solved}/${challenges.length} solved)`);
|
|
278
|
+
// Category descriptions for beginners
|
|
279
|
+
const catDesc = {
|
|
280
|
+
'Web': 'Find vulnerabilities in websites',
|
|
281
|
+
'Crypto': 'Break ciphers & encryption',
|
|
282
|
+
'Reversing': 'Analyze compiled programs',
|
|
283
|
+
'Rev': 'Analyze compiled programs',
|
|
284
|
+
'Pwn': 'Exploit binary vulnerabilities',
|
|
285
|
+
'Forensics': 'Investigate digital evidence',
|
|
286
|
+
'Misc': 'Creative & mixed challenges',
|
|
287
|
+
'OSINT': 'Open-source intelligence gathering',
|
|
288
|
+
'AI': 'AI security & adversarial ML',
|
|
289
|
+
};
|
|
290
|
+
// Difficulty based on points
|
|
291
|
+
const difficulty = (pts) => {
|
|
292
|
+
if (pts <= 100)
|
|
293
|
+
return chalk.green('Easy');
|
|
294
|
+
if (pts <= 250)
|
|
295
|
+
return chalk.yellow('Medium');
|
|
296
|
+
if (pts <= 500)
|
|
297
|
+
return chalk.red('Hard');
|
|
298
|
+
return chalk.magenta('Expert');
|
|
299
|
+
};
|
|
254
300
|
// Sort categories and display
|
|
255
301
|
const rows = [...byCategory.entries()]
|
|
256
302
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
257
303
|
.flatMap(([category, challs]) => {
|
|
258
|
-
const
|
|
304
|
+
const desc = catDesc[category] || '';
|
|
305
|
+
const catLabel = desc
|
|
306
|
+
? chalk.cyan.bold(`── ${category} ──`) + ' ' + chalk.gray(desc)
|
|
307
|
+
: chalk.cyan.bold(`── ${category} ──`);
|
|
308
|
+
const catRow = [catLabel, '', '', '', ''];
|
|
259
309
|
const challRows = challs
|
|
260
310
|
.sort((a, b) => a.value - b.value)
|
|
261
311
|
.map((c) => [
|
|
262
312
|
String(c.id),
|
|
263
313
|
c.solved_by_me ? chalk.gray.strikethrough(c.name) : c.name,
|
|
264
|
-
chalk.gray(c.category),
|
|
265
314
|
c.solved_by_me ? chalk.gray(String(c.value)) : chalk.yellow(String(c.value)),
|
|
315
|
+
c.solved_by_me ? chalk.gray('--') : difficulty(c.value),
|
|
266
316
|
c.solved_by_me ? chalk.green('✓') : chalk.gray('○'),
|
|
267
317
|
]);
|
|
268
318
|
return [catRow, ...challRows];
|
|
269
319
|
});
|
|
270
|
-
printTable(['#', 'Name', '
|
|
320
|
+
printTable(['#', 'Name', 'Points', 'Difficulty', 'Solved'], rows);
|
|
271
321
|
console.log(chalk.gray(` ${challenges.length} challenges, ${solved} solved`));
|
|
322
|
+
if (solved === 0) {
|
|
323
|
+
console.log();
|
|
324
|
+
console.log(chalk.gray(' Tip: Start with ') + chalk.green('Easy') + chalk.gray(' challenges! Type ') + chalk.white('open <id>') + chalk.gray(' to read one.'));
|
|
325
|
+
}
|
|
272
326
|
}
|
|
273
327
|
catch (err) {
|
|
274
328
|
spinner.fail('Failed to load challenges');
|
|
@@ -325,9 +379,19 @@ export function registerCtfCommands(program) {
|
|
|
325
379
|
console.log();
|
|
326
380
|
printInfo(`Quick connect: ${chalk.white(`connect ${id}`)}`);
|
|
327
381
|
}
|
|
328
|
-
// Show
|
|
382
|
+
// Show guided next actions
|
|
329
383
|
console.log();
|
|
330
|
-
console.log(chalk.gray(
|
|
384
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
385
|
+
console.log(chalk.bold.white(' What to do next:'));
|
|
386
|
+
console.log(chalk.white(` hint "how to start?"`) + chalk.gray(' Ask AI for guidance (Level A)'));
|
|
387
|
+
if (challenge.files && challenge.files.length > 0) {
|
|
388
|
+
console.log(chalk.white(` files ${id}`) + chalk.gray(' Download challenge files'));
|
|
389
|
+
}
|
|
390
|
+
if (challenge.connection_info) {
|
|
391
|
+
console.log(chalk.white(` connect ${id}`) + chalk.gray(' Connect to target'));
|
|
392
|
+
}
|
|
393
|
+
console.log(chalk.white(` submit ${id} icoa{flag}`) + chalk.gray(' Submit your answer'));
|
|
394
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
331
395
|
}
|
|
332
396
|
catch (err) {
|
|
333
397
|
spinner.fail('Failed to load challenge');
|
package/dist/commands/env.js
CHANGED
|
@@ -280,6 +280,19 @@ function showStatus() {
|
|
|
280
280
|
const pm = os === 'darwin' ? 'brew' : os === 'linux' ? 'apt' : 'winget';
|
|
281
281
|
console.log(chalk.bold.white(' ICOA Competition Environment'));
|
|
282
282
|
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
283
|
+
console.log();
|
|
284
|
+
console.log(chalk.gray(' These tools power your CTF competition environment.'));
|
|
285
|
+
console.log(chalk.gray(' Not all are required — here\'s what matters:'));
|
|
286
|
+
console.log();
|
|
287
|
+
console.log(chalk.green(' Essential') + chalk.gray(' pwntools, z3, requests, numpy'));
|
|
288
|
+
console.log(chalk.gray(' You need these for most challenges'));
|
|
289
|
+
console.log(chalk.yellow(' Recommended') + chalk.gray(' pycryptodome, beautifulsoup4, scapy, sympy'));
|
|
290
|
+
console.log(chalk.gray(' Covers Web, Crypto, and Forensics'));
|
|
291
|
+
console.log(chalk.gray(' Full (109) All tools for every category'));
|
|
292
|
+
console.log();
|
|
293
|
+
console.log(chalk.gray(' Missing tools? Run ') + chalk.bold.cyan('env setup') + chalk.gray(' to install everything.'));
|
|
294
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
295
|
+
console.log();
|
|
283
296
|
console.log(chalk.gray(' OS: ') + chalk.white(getOsInfo()));
|
|
284
297
|
console.log(chalk.gray(' Node: ') + chalk.white(getNodeInfo()));
|
|
285
298
|
console.log(chalk.gray(' Package: ') + chalk.white(pm));
|
|
@@ -382,6 +395,17 @@ async function installAll() {
|
|
|
382
395
|
console.log();
|
|
383
396
|
const os = platform();
|
|
384
397
|
const pipFlag = os === 'darwin' || os === 'linux' ? '--break-system-packages' : '';
|
|
398
|
+
console.log(chalk.bold.white(' ICOA Environment Setup'));
|
|
399
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
400
|
+
console.log(chalk.gray(' This will install:'));
|
|
401
|
+
console.log(chalk.white(' Python 3.12') + chalk.gray(' Runtime for CTF tools'));
|
|
402
|
+
console.log(chalk.white(` ${PYTHON_LIBS.length} Python libraries`) + chalk.gray(' pwntools, z3, crypto...'));
|
|
403
|
+
console.log(chalk.white(` ${SYSTEM_TOOLS.length} system tools`) + chalk.gray(' gcc, gdb, nmap, wireshark...'));
|
|
404
|
+
console.log();
|
|
405
|
+
console.log(chalk.gray(' Estimated: ~500 MB disk, 5-15 min (depends on network)'));
|
|
406
|
+
console.log(chalk.gray(' Already installed tools will be skipped.'));
|
|
407
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
408
|
+
console.log();
|
|
385
409
|
// Node.js version check
|
|
386
410
|
const nodeVer = process.versions.node;
|
|
387
411
|
if (nodeVer === NODE_EXACT) {
|
package/dist/commands/hint.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { confirm } from '@inquirer/prompts';
|
|
3
2
|
import { generateHint } from '../lib/gemini.js';
|
|
4
3
|
import { checkBudget, deductBudget, getBudgetDisplay, isTokenCapReached } from '../lib/budget.js';
|
|
5
4
|
import { getConfig } from '../lib/config.js';
|
|
6
5
|
import { logHint } from '../lib/logger.js';
|
|
7
|
-
import { printError,
|
|
6
|
+
import { printError, printMarkdown, printHeader, createSpinner } from '../lib/ui.js';
|
|
8
7
|
function getChallengeContext() {
|
|
9
8
|
const config = getConfig();
|
|
10
9
|
if (config.currentChallengeName && config.currentChallengeCategory) {
|
|
@@ -28,16 +27,9 @@ async function handleHint(level, question) {
|
|
|
28
27
|
printError(`Level ${level} hint budget exhausted (0 remaining).`);
|
|
29
28
|
return;
|
|
30
29
|
}
|
|
31
|
-
// Level C
|
|
30
|
+
// Level C warning (no confirm — crashes REPL)
|
|
32
31
|
if (level === 'C') {
|
|
33
|
-
|
|
34
|
-
message: `This will consume 1 of your ${remaining} remaining Critical Assists. Continue?`,
|
|
35
|
-
default: false,
|
|
36
|
-
});
|
|
37
|
-
if (!proceed) {
|
|
38
|
-
printInfo('Cancelled.');
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
32
|
+
console.log(chalk.red.bold(` Warning: Using 1 of ${remaining} Critical Assists remaining.`));
|
|
41
33
|
}
|
|
42
34
|
// Log BEFORE API call
|
|
43
35
|
logHint(level, question, config.currentChallengeId || undefined);
|
|
@@ -56,8 +48,23 @@ async function handleHint(level, question) {
|
|
|
56
48
|
deductBudget(level, result.tokensUsed);
|
|
57
49
|
printHeader(`Level ${level} Hint — ${levelNames[level]}`);
|
|
58
50
|
printMarkdown(result.text);
|
|
51
|
+
// Budget summary after hint
|
|
52
|
+
const afterBudget = checkBudget(level);
|
|
59
53
|
console.log();
|
|
60
|
-
console.log(chalk.gray(
|
|
54
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
55
|
+
console.log(chalk.gray(` Tokens used: ${result.tokensUsed} | Level ${level} remaining: ${afterBudget.remaining}`));
|
|
56
|
+
// Suggest next level if stuck
|
|
57
|
+
if (level === 'A') {
|
|
58
|
+
const bBudget = checkBudget('B');
|
|
59
|
+
console.log(chalk.gray(' Need more detail? ') + chalk.white('hint-b "your question"') + chalk.gray(` (${bBudget.remaining} left)`));
|
|
60
|
+
}
|
|
61
|
+
else if (level === 'B') {
|
|
62
|
+
const cBudget = checkBudget('C');
|
|
63
|
+
if (cBudget.remaining > 0) {
|
|
64
|
+
console.log(chalk.gray(' Still stuck? ') + chalk.white('hint-c "your question"') + chalk.gray(` (${cBudget.remaining} Critical Assists left)`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
61
68
|
console.log();
|
|
62
69
|
}
|
|
63
70
|
catch (err) {
|
|
@@ -69,6 +76,11 @@ function showBudget() {
|
|
|
69
76
|
printHeader('Hint Budget');
|
|
70
77
|
console.log(getBudgetDisplay());
|
|
71
78
|
console.log();
|
|
79
|
+
console.log(chalk.gray(' How to use hints:'));
|
|
80
|
+
console.log(chalk.white(' hint "what is XSS?"') + chalk.gray(' Level A — General guidance'));
|
|
81
|
+
console.log(chalk.white(' hint-b "analyze this code"') + chalk.gray(' Level B — Deep analysis'));
|
|
82
|
+
console.log(chalk.white(' hint-c "I\'m completely stuck"') + chalk.gray(' Level C — Critical assist'));
|
|
83
|
+
console.log();
|
|
72
84
|
}
|
|
73
85
|
export function registerHintCommands(program) {
|
|
74
86
|
// ─── icoa hint <question> ───
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,8 @@ ${LINE}
|
|
|
35
35
|
${chalk.bold.white('╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝')}
|
|
36
36
|
|
|
37
37
|
${chalk.yellow('International Cyber Olympiad in AI 2026')}
|
|
38
|
-
${chalk.bold.magenta("The World's First AI
|
|
38
|
+
${chalk.bold.magenta("The World's First AI-Native CLI Operating System")}
|
|
39
|
+
${chalk.bold.magenta("for Cybersecurity & AI Security Competition")}
|
|
39
40
|
|
|
40
41
|
${chalk.green.bold('AI4CTF')}${chalk.gray('[Day 1]')} ${chalk.white('AI as your teammate')}
|
|
41
42
|
${chalk.red.bold('CTF4AI')}${chalk.gray('[Day 2]')} ${chalk.white('Hack & evaluate AI systems')}
|
package/dist/repl.js
CHANGED
|
@@ -66,18 +66,20 @@ export async function startRepl(program, resumeMode) {
|
|
|
66
66
|
console.log(chalk.bold.white(' ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝'));
|
|
67
67
|
console.log();
|
|
68
68
|
console.log(chalk.bold.yellow(' The World\'s First'));
|
|
69
|
-
console.log(chalk.bold.white(' AI-Native CLI
|
|
70
|
-
console.log(chalk.bold.white(' Cybersecurity
|
|
69
|
+
console.log(chalk.bold.white(' AI-Native CLI Operating System for'));
|
|
70
|
+
console.log(chalk.bold.white(' Cybersecurity & AI Security Competition'));
|
|
71
71
|
console.log();
|
|
72
72
|
console.log(chalk.white(' One terminal. 15 languages. 15,000 concurrent participants.'));
|
|
73
|
+
console.log(chalk.white(' 109 pre-configured CTF tools. Zero browser required.'));
|
|
73
74
|
console.log();
|
|
74
75
|
console.log(chalk.cyan(' ─────────────────────────────────────────────────'));
|
|
75
76
|
console.log();
|
|
76
77
|
console.log(chalk.bold.white(' What Makes ICOA Different'));
|
|
77
|
-
console.log(chalk.gray(' · AI-
|
|
78
|
-
console.log(chalk.gray(' · CLI
|
|
78
|
+
console.log(chalk.gray(' · AI-native AI teammate, AI adversary, AI translation'));
|
|
79
|
+
console.log(chalk.gray(' · CLI OS Complete competition environment in terminal'));
|
|
80
|
+
console.log(chalk.gray(' · 109 tools pwntools, z3, gdb, nmap... pre-configured'));
|
|
79
81
|
console.log(chalk.gray(' · Global scale 15,000+ concurrent exams, single server'));
|
|
80
|
-
console.log(chalk.gray(' · 15 languages Real-time AI translation for all
|
|
82
|
+
console.log(chalk.gray(' · 15 languages Real-time AI translation for all content'));
|
|
81
83
|
console.log();
|
|
82
84
|
console.log(chalk.bold.white(' Competition Format'));
|
|
83
85
|
console.log(chalk.green.bold(' AI4CTF') + chalk.gray(' [Day 1] AI as your teammate — 5hr jeopardy CTF'));
|
|
@@ -199,6 +201,8 @@ export async function startRepl(program, resumeMode) {
|
|
|
199
201
|
console.log(chalk.bold.white(' ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝'));
|
|
200
202
|
console.log();
|
|
201
203
|
console.log(chalk.yellow(' International Cyber Olympiad in AI 2026'));
|
|
204
|
+
console.log(chalk.bold.magenta(' The World\'s First AI-Native CLI Operating System'));
|
|
205
|
+
console.log(chalk.bold.magenta(' for Cybersecurity & AI Security Competition'));
|
|
202
206
|
console.log(chalk.gray(' Sydney, Australia · Jun 27 - Jul 2, 2026'));
|
|
203
207
|
console.log();
|
|
204
208
|
console.log(chalk.white(' Vision'));
|
|
@@ -236,34 +240,49 @@ export async function startRepl(program, resumeMode) {
|
|
|
236
240
|
console.log();
|
|
237
241
|
}
|
|
238
242
|
else if (connected) {
|
|
239
|
-
console.log(chalk.green(` Welcome back, ${config.userName}!`));
|
|
243
|
+
console.log(chalk.green.bold(` Welcome back, ${config.userName}!`));
|
|
240
244
|
console.log(chalk.gray(` Connected to ${config.ctfdUrl}`));
|
|
241
|
-
console.log(
|
|
245
|
+
console.log();
|
|
246
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
247
|
+
console.log(chalk.white(' Ready to compete? Start here:'));
|
|
248
|
+
console.log();
|
|
249
|
+
console.log(chalk.bold.cyan(' challenges') + chalk.gray(' Browse challenges by category'));
|
|
250
|
+
console.log(chalk.white(' status') + chalk.gray(' Your score & hint budget'));
|
|
251
|
+
console.log(chalk.white(' scoreboard') + chalk.gray(' Live rankings'));
|
|
252
|
+
console.log(chalk.white(' help') + chalk.gray(' Full command list'));
|
|
253
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
242
254
|
console.log();
|
|
243
255
|
}
|
|
244
256
|
else if (activated) {
|
|
245
257
|
ensureWorkspace();
|
|
246
|
-
console.log(chalk.green(' Welcome, competitor!
|
|
258
|
+
console.log(chalk.green.bold(' Welcome, competitor!'));
|
|
247
259
|
console.log(chalk.gray(` Workspace: ${WORKSPACE}`));
|
|
248
260
|
console.log();
|
|
249
|
-
console.log(chalk.gray('
|
|
250
|
-
console.log(chalk.
|
|
251
|
-
console.log(
|
|
252
|
-
console.log(chalk.white('
|
|
253
|
-
console.log(chalk.white('
|
|
254
|
-
console.log(chalk.white('
|
|
255
|
-
console.log(
|
|
261
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
262
|
+
console.log(chalk.white(' Get started:'));
|
|
263
|
+
console.log();
|
|
264
|
+
console.log(chalk.white(' Step 1 ') + chalk.bold.cyan('join <url>') + chalk.gray(' Connect to competition server'));
|
|
265
|
+
console.log(chalk.white(' Step 2 ') + chalk.bold.cyan('challenges') + chalk.gray(' Browse & solve challenges'));
|
|
266
|
+
console.log(chalk.white(' Step 3 ') + chalk.bold.cyan('hint') + chalk.gray(' Ask AI when stuck'));
|
|
267
|
+
console.log();
|
|
268
|
+
console.log(chalk.gray(' Also: ') + chalk.white('env') + chalk.gray(' check tools ') + chalk.white('help') + chalk.gray(' all commands'));
|
|
269
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
256
270
|
console.log();
|
|
257
271
|
}
|
|
258
272
|
else {
|
|
259
|
-
console.log(chalk.white(' Welcome to ICOA CLI
|
|
273
|
+
console.log(chalk.bold.white(' Welcome to ICOA CLI — International Olympiad'));
|
|
274
|
+
console.log();
|
|
275
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
276
|
+
console.log(chalk.white(' To begin, activate your competition token:'));
|
|
260
277
|
console.log();
|
|
261
|
-
console.log(chalk.
|
|
262
|
-
console.log(
|
|
263
|
-
console.log(chalk.
|
|
264
|
-
console.log(chalk.white('
|
|
265
|
-
console.log(chalk.white('
|
|
266
|
-
console.log(chalk.white('
|
|
278
|
+
console.log(chalk.bold.cyan(' activate <token>'));
|
|
279
|
+
console.log();
|
|
280
|
+
console.log(chalk.gray(' While waiting, explore:'));
|
|
281
|
+
console.log(chalk.white(' ref linux') + chalk.gray(' Quick reference for Linux'));
|
|
282
|
+
console.log(chalk.white(' ref web') + chalk.gray(' Quick reference for Web'));
|
|
283
|
+
console.log(chalk.white(' env') + chalk.gray(' Check your tools'));
|
|
284
|
+
console.log(chalk.white(' help') + chalk.gray(' All available commands'));
|
|
285
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────'));
|
|
267
286
|
console.log();
|
|
268
287
|
}
|
|
269
288
|
}
|
|
@@ -729,33 +748,35 @@ function printReplHelp(activated, mode = 'olympiad') {
|
|
|
729
748
|
console.log();
|
|
730
749
|
return;
|
|
731
750
|
}
|
|
751
|
+
// How it works — workflow overview
|
|
752
|
+
console.log(chalk.cyan(' ═══════════════════════════════════════════════'));
|
|
753
|
+
console.log(chalk.bold.white(' How it works'));
|
|
754
|
+
console.log();
|
|
755
|
+
console.log(chalk.gray(' 1. Browse ') + chalk.white('challenges') + chalk.gray(' and pick one'));
|
|
756
|
+
console.log(chalk.gray(' 2. ') + chalk.white('open <id>') + chalk.gray(' to read the challenge'));
|
|
757
|
+
console.log(chalk.gray(' 3. Use ') + chalk.white('hint') + chalk.gray(' / ') + chalk.white('hint-b') + chalk.gray(' / ') + chalk.white('hint-c') + chalk.gray(' when stuck'));
|
|
758
|
+
console.log(chalk.gray(' 4. ') + chalk.white('submit <id> icoa{flag}') + chalk.gray(' to score points'));
|
|
759
|
+
console.log(chalk.gray(' 5. Check ') + chalk.white('scoreboard') + chalk.gray(' to track your rank'));
|
|
760
|
+
console.log(chalk.cyan(' ═══════════════════════════════════════════════'));
|
|
761
|
+
console.log();
|
|
732
762
|
console.log(chalk.bold.white(' Competition'));
|
|
733
763
|
console.log(chalk.white(' join <url> ') + chalk.gray('Connect to CTFd'));
|
|
734
|
-
console.log(chalk.white(' challenges (ch) ') + chalk.gray('List challenges'));
|
|
735
|
-
console.log(chalk.white(' open <id> ') + chalk.gray('
|
|
764
|
+
console.log(chalk.white(' challenges (ch) ') + chalk.gray('List challenges by category'));
|
|
765
|
+
console.log(chalk.white(' open <id> ') + chalk.gray('Read challenge + get next steps'));
|
|
736
766
|
console.log(chalk.white(' submit <id> <flag> ') + chalk.gray('Submit a flag'));
|
|
737
|
-
console.log(chalk.white(' scoreboard (sb) ') + chalk.gray('
|
|
738
|
-
console.log(chalk.white(' status ') + chalk.gray('
|
|
767
|
+
console.log(chalk.white(' scoreboard (sb) ') + chalk.gray('Live rankings'));
|
|
768
|
+
console.log(chalk.white(' status ') + chalk.gray('Your score, budget & timer'));
|
|
739
769
|
console.log(chalk.white(' time ') + chalk.gray('Countdown timer'));
|
|
740
770
|
console.log();
|
|
741
|
-
console.log(chalk.bold.white('
|
|
742
|
-
console.log(chalk.white('
|
|
743
|
-
console.log(chalk.white('
|
|
744
|
-
console.log(chalk.white('
|
|
745
|
-
console.log(chalk.white('
|
|
746
|
-
console.log(chalk.white('
|
|
747
|
-
console.log(chalk.white(' exam submit ') + chalk.gray('Submit for grading'));
|
|
748
|
-
console.log(chalk.white(' exam result ') + chalk.gray('View your score'));
|
|
749
|
-
console.log();
|
|
750
|
-
console.log(chalk.bold.white(' AI'));
|
|
751
|
-
console.log(chalk.white(' ai4ctf ') + chalk.gray('Chat with your AI teammate'));
|
|
752
|
-
console.log(chalk.white(' hint <question> ') + chalk.gray('Level A — General guidance'));
|
|
753
|
-
console.log(chalk.white(' hint-b <question> ') + chalk.gray('Level B — Deep analysis'));
|
|
754
|
-
console.log(chalk.white(' hint-c <question> ') + chalk.gray('Level C — Critical assist'));
|
|
755
|
-
console.log(chalk.white(' hint budget ') + chalk.gray('Check remaining budget'));
|
|
771
|
+
console.log(chalk.bold.white(' AI Teammate') + chalk.gray(' — 3 levels, use wisely'));
|
|
772
|
+
console.log(chalk.white(' hint "question" ') + chalk.gray('Level A — General guidance (50 uses)'));
|
|
773
|
+
console.log(chalk.white(' hint-b "question" ') + chalk.gray('Level B — Deep analysis (10 uses)'));
|
|
774
|
+
console.log(chalk.white(' hint-c "question" ') + chalk.gray('Level C — Critical assist (2 uses)'));
|
|
775
|
+
console.log(chalk.white(' hint budget ') + chalk.gray('Check remaining uses'));
|
|
776
|
+
console.log(chalk.white(' ai4ctf ') + chalk.gray('Free-chat with AI (no limit)'));
|
|
756
777
|
console.log();
|
|
757
778
|
console.log(chalk.bold.white(' Tools'));
|
|
758
|
-
console.log(chalk.white(' ref [topic] ') + chalk.gray('Quick reference'));
|
|
779
|
+
console.log(chalk.white(' ref [topic] ') + chalk.gray('Quick reference (linux, web, crypto...)'));
|
|
759
780
|
console.log(chalk.white(' shell ') + chalk.gray('Docker sandbox'));
|
|
760
781
|
console.log(chalk.white(' files <id> ') + chalk.gray('Download challenge files'));
|
|
761
782
|
console.log(chalk.white(' connect <id> ') + chalk.gray('Connect to remote target'));
|
|
@@ -764,7 +785,8 @@ function printReplHelp(activated, mode = 'olympiad') {
|
|
|
764
785
|
console.log();
|
|
765
786
|
console.log(chalk.bold.white(' System'));
|
|
766
787
|
console.log(chalk.white(' setup ') + chalk.gray('Configure settings'));
|
|
767
|
-
console.log(chalk.white(' lang [code] ') + chalk.gray('Switch language'));
|
|
788
|
+
console.log(chalk.white(' lang [code] ') + chalk.gray('Switch language (15 supported)'));
|
|
789
|
+
console.log(chalk.white(' logout ') + chalk.gray('Disconnect'));
|
|
768
790
|
console.log(chalk.white(' clear ') + chalk.gray('Clear screen'));
|
|
769
791
|
console.log(chalk.white(' exit ') + chalk.gray('Quit (session saved)'));
|
|
770
792
|
console.log();
|