icoa-cli 2.19.12 → 2.19.13
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 +39 -38
- package/dist/commands/ctf4ai-demo.js +46 -45
- package/dist/commands/exam.js +18 -23
- package/dist/lib/gemini.js +7 -6
- package/dist/lib/i18n.d.ts +20 -0
- package/dist/lib/i18n.js +56 -13
- package/package.json +1 -1
package/dist/commands/ai4ctf.js
CHANGED
|
@@ -4,6 +4,7 @@ import { addTokenUsage } from '../lib/budget.js';
|
|
|
4
4
|
import { getConfig } from '../lib/config.js';
|
|
5
5
|
import { logCommand } from '../lib/logger.js';
|
|
6
6
|
import { printMarkdown, printError } from '../lib/ui.js';
|
|
7
|
+
import { t } from '../lib/i18n.js';
|
|
7
8
|
function getChallengeContext() {
|
|
8
9
|
const config = getConfig();
|
|
9
10
|
if (config.currentChallengeName && config.currentChallengeCategory) {
|
|
@@ -40,11 +41,11 @@ export async function handleChatMessage(input) {
|
|
|
40
41
|
if (flag === DEMO_FLAG) {
|
|
41
42
|
console.log();
|
|
42
43
|
console.log(chalk.green.bold(' ════════════════════════════════════'));
|
|
43
|
-
console.log(chalk.green.bold(
|
|
44
|
+
console.log(chalk.green.bold(` ${t('ai4ctfCorrectFlag')}`));
|
|
44
45
|
console.log(chalk.green.bold(' ════════════════════════════════════'));
|
|
45
46
|
console.log();
|
|
46
|
-
console.log(chalk.white(
|
|
47
|
-
console.log(chalk.gray(
|
|
47
|
+
console.log(chalk.white(` ${t('ai4ctfDecoded')}`));
|
|
48
|
+
console.log(chalk.gray(` ${t('ai4ctfWouldEarn')}`));
|
|
48
49
|
console.log();
|
|
49
50
|
drawTokenBar();
|
|
50
51
|
chatActive = false;
|
|
@@ -55,14 +56,14 @@ export async function handleChatMessage(input) {
|
|
|
55
56
|
body: JSON.stringify({ type: 'ai4ctf', solved: true, tokensUsed: chatTokensUsed, timestamp: new Date().toISOString() }),
|
|
56
57
|
signal: AbortSignal.timeout(5000),
|
|
57
58
|
}).catch(() => { });
|
|
58
|
-
console.log(chalk.white(
|
|
59
|
+
console.log(chalk.white(` ${t('ai4ctfNext')}`));
|
|
59
60
|
console.log();
|
|
60
61
|
return 'exit';
|
|
61
62
|
}
|
|
62
63
|
else {
|
|
63
64
|
console.log();
|
|
64
|
-
console.log(chalk.red(
|
|
65
|
-
console.log(chalk.gray(
|
|
65
|
+
console.log(chalk.red(` ${t('ai4ctfWrongFlag')}`));
|
|
66
|
+
console.log(chalk.gray(` ${t('ai4ctfFlagHint')}`));
|
|
66
67
|
console.log();
|
|
67
68
|
return 'continue';
|
|
68
69
|
}
|
|
@@ -79,7 +80,7 @@ export async function handleChatMessage(input) {
|
|
|
79
80
|
console.log(chalk.gray(' $ ') + chalk.white(cmd));
|
|
80
81
|
console.log(chalk.white(' ' + output.split('\n').join('\n ')));
|
|
81
82
|
console.log();
|
|
82
|
-
console.log(chalk.gray(
|
|
83
|
+
console.log(chalk.gray(` ${t('ai4ctfFoundFlag')}`));
|
|
83
84
|
console.log();
|
|
84
85
|
}
|
|
85
86
|
catch (err) {
|
|
@@ -101,12 +102,12 @@ export async function handleChatMessage(input) {
|
|
|
101
102
|
}).catch(() => { });
|
|
102
103
|
console.log();
|
|
103
104
|
console.log(chalk.gray(' ─────────────────────────────────────────'));
|
|
104
|
-
console.log(chalk.white(
|
|
105
|
-
console.log(chalk.gray(`
|
|
106
|
-
console.log(chalk.gray(`
|
|
105
|
+
console.log(chalk.white(` ${t('ai4ctfReport')}`));
|
|
106
|
+
console.log(chalk.gray(` ${t('ai4ctfTokens')}: ${chatTokensUsed}/${DEMO_TOKEN_CAP}`));
|
|
107
|
+
console.log(chalk.gray(` ${t('ai4ctfModel')}: Google Gemma 4 (gemma-4-31b-it)`));
|
|
107
108
|
console.log(chalk.gray(' ─────────────────────────────────────────'));
|
|
108
109
|
console.log();
|
|
109
|
-
console.log(chalk.white(
|
|
110
|
+
console.log(chalk.white(` ${t('ai4ctfNext')}`));
|
|
110
111
|
console.log();
|
|
111
112
|
return 'exit';
|
|
112
113
|
}
|
|
@@ -114,21 +115,21 @@ export async function handleChatMessage(input) {
|
|
|
114
115
|
chatActive = false;
|
|
115
116
|
chatSession = null;
|
|
116
117
|
console.log();
|
|
117
|
-
console.log(chalk.yellow(
|
|
118
|
+
console.log(chalk.yellow(` ${t('tokenLimit')}`));
|
|
118
119
|
drawTokenBar();
|
|
119
120
|
console.log();
|
|
120
121
|
console.log(chalk.gray(' ─────────────────────────────────────────'));
|
|
121
|
-
console.log(chalk.white(
|
|
122
|
-
console.log(chalk.gray(`
|
|
123
|
-
console.log(chalk.gray(`
|
|
122
|
+
console.log(chalk.white(` ${t('ai4ctfReport')}`));
|
|
123
|
+
console.log(chalk.gray(` ${t('ai4ctfTokens')}: ${chatTokensUsed}/${DEMO_TOKEN_CAP}`));
|
|
124
|
+
console.log(chalk.gray(` ${t('ai4ctfModel')}: Google Gemma 4 (gemma-4-31b-it)`));
|
|
124
125
|
console.log(chalk.gray(' ─────────────────────────────────────────'));
|
|
125
126
|
console.log();
|
|
126
|
-
console.log(chalk.white(
|
|
127
|
+
console.log(chalk.white(` ${t('ai4ctfNext')}`));
|
|
127
128
|
console.log();
|
|
128
129
|
return 'exit';
|
|
129
130
|
}
|
|
130
131
|
logCommand(`ai4ctf: ${input}`);
|
|
131
|
-
console.log(chalk.gray(
|
|
132
|
+
console.log(chalk.gray(` ${t('ai4ctfThinking')}`));
|
|
132
133
|
try {
|
|
133
134
|
const response = await chatSession.sendMessage(input);
|
|
134
135
|
process.stdout.write('\x1b[1A\x1b[2K');
|
|
@@ -170,42 +171,42 @@ export function registerAi4ctfCommand(program) {
|
|
|
170
171
|
chatTokensUsed = 0;
|
|
171
172
|
// Guided welcome
|
|
172
173
|
console.log();
|
|
173
|
-
console.log(chalk.green.bold(
|
|
174
|
+
console.log(chalk.green.bold(` ═══ ${t('ai4ctfTitle')} ═══`));
|
|
174
175
|
console.log();
|
|
175
|
-
console.log(chalk.white(
|
|
176
|
+
console.log(chalk.white(` ${t('ai4ctfSample')}`));
|
|
176
177
|
console.log();
|
|
177
178
|
console.log(chalk.cyan(' ┌─────────────────────────────────────────────────┐'));
|
|
178
|
-
console.log(chalk.cyan(' │') + chalk.bold.white(
|
|
179
|
+
console.log(chalk.cyan(' │') + chalk.bold.white(` ${t('ai4ctfChallenge')}`.padEnd(50)) + chalk.cyan('│'));
|
|
179
180
|
console.log(chalk.cyan(' │') + chalk.white(' ') + chalk.cyan('│'));
|
|
180
|
-
console.log(chalk.cyan(' │') + chalk.white(
|
|
181
|
+
console.log(chalk.cyan(' │') + chalk.white(` ${t('ai4ctfIntercepted')}`.padEnd(50)) + chalk.cyan('│'));
|
|
181
182
|
console.log(chalk.cyan(' │') + chalk.green(' aWNvYXt3M2xjMG1lXzJfYWk0Y3RmfQ== ') + chalk.cyan('│'));
|
|
182
183
|
console.log(chalk.cyan(' │') + chalk.white(' ') + chalk.cyan('│'));
|
|
183
|
-
console.log(chalk.cyan(' │') + chalk.white(
|
|
184
|
+
console.log(chalk.cyan(' │') + chalk.white(` ${t('ai4ctfDecode')}`.padEnd(50)) + chalk.cyan('│'));
|
|
184
185
|
console.log(chalk.cyan(' │') + chalk.gray(' Flag format: icoa{...} ') + chalk.cyan('│'));
|
|
185
186
|
console.log(chalk.cyan(' └─────────────────────────────────────────────────┘'));
|
|
186
187
|
console.log();
|
|
187
|
-
console.log(chalk.white(
|
|
188
|
+
console.log(chalk.white(` ${t('ai4ctfLevels')}`));
|
|
188
189
|
console.log();
|
|
189
|
-
console.log(chalk.yellow(' hint a') + chalk.gray(
|
|
190
|
-
console.log(chalk.gray(
|
|
191
|
-
console.log(chalk.yellow(' hint b') + chalk.gray(
|
|
192
|
-
console.log(chalk.gray(
|
|
193
|
-
console.log(chalk.yellow(' hint c') + chalk.gray(
|
|
194
|
-
console.log(chalk.gray(
|
|
190
|
+
console.log(chalk.yellow(' hint a') + chalk.gray(` ${t('ai4ctfHintA')}`));
|
|
191
|
+
console.log(chalk.gray(` ${t('ai4ctfHintAUses')}`));
|
|
192
|
+
console.log(chalk.yellow(' hint b') + chalk.gray(` ${t('ai4ctfHintB')}`));
|
|
193
|
+
console.log(chalk.gray(` ${t('ai4ctfHintBUses')}`));
|
|
194
|
+
console.log(chalk.yellow(' hint c') + chalk.gray(` ${t('ai4ctfHintC')}`));
|
|
195
|
+
console.log(chalk.gray(` ${t('ai4ctfHintCUses')}`));
|
|
195
196
|
console.log();
|
|
196
197
|
console.log(chalk.gray(' ─────────────────────────────────────────'));
|
|
197
|
-
console.log(chalk.white(
|
|
198
|
-
console.log(chalk.gray(
|
|
199
|
-
console.log(chalk.gray(
|
|
198
|
+
console.log(chalk.white(` ${t('ai4ctfTryNow')}`));
|
|
199
|
+
console.log(chalk.gray(` ${t('ai4ctfExample')}`));
|
|
200
|
+
console.log(chalk.gray(` ${t('ai4ctfFreeChat')}`));
|
|
200
201
|
console.log();
|
|
201
|
-
console.log(chalk.yellow(
|
|
202
|
-
console.log(chalk.white(' submit <flag>') + chalk.gray(
|
|
203
|
-
console.log(chalk.white(' !<command>') + chalk.gray(
|
|
204
|
-
console.log(chalk.gray(
|
|
202
|
+
console.log(chalk.yellow(` ${t('ai4ctfCommands')}`));
|
|
203
|
+
console.log(chalk.white(' submit <flag>') + chalk.gray(` ${t('ai4ctfSubmitCmd')}`));
|
|
204
|
+
console.log(chalk.white(' !<command>') + chalk.gray(` ${t('ai4ctfShellCmd')}`));
|
|
205
|
+
console.log(chalk.gray(` exit ${t('ai4ctfEndSession')}`));
|
|
205
206
|
console.log();
|
|
206
207
|
drawTokenBar();
|
|
207
|
-
console.log(chalk.gray(`
|
|
208
|
-
console.log(chalk.gray(
|
|
208
|
+
console.log(chalk.gray(` ${t('ai4ctfModel')}: Google Gemma 4 (${modelName})`));
|
|
209
|
+
console.log(chalk.gray(` ${t('ai4ctfExit')}`));
|
|
209
210
|
console.log();
|
|
210
211
|
});
|
|
211
212
|
}
|
|
@@ -2,47 +2,48 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { logCommand } from '../lib/logger.js';
|
|
3
3
|
import { printError } from '../lib/ui.js';
|
|
4
4
|
import { getConfig } from '../lib/config.js';
|
|
5
|
+
import { t } from '../lib/i18n.js';
|
|
5
6
|
function printDemoReport(ctf4aiSolved, ctf4aiTokens) {
|
|
6
7
|
const config = getConfig();
|
|
7
8
|
const modelName = config.geminiModel || 'gemma-4-31b-it';
|
|
8
9
|
console.log();
|
|
9
10
|
console.log(chalk.cyan(' ═══════════════════════════════════════════════'));
|
|
10
|
-
console.log(chalk.bold.white(
|
|
11
|
+
console.log(chalk.bold.white(` ${t('reportTitle')}`));
|
|
11
12
|
console.log(chalk.cyan(' ═══════════════════════════════════════════════'));
|
|
12
13
|
console.log();
|
|
13
|
-
console.log(chalk.white(
|
|
14
|
-
console.log(chalk.green(
|
|
14
|
+
console.log(chalk.white(` ${t('reportStage1')}`));
|
|
15
|
+
console.log(chalk.green(` ${t('reportCompleted')}`));
|
|
15
16
|
console.log();
|
|
16
|
-
console.log(chalk.white(
|
|
17
|
-
console.log(chalk.green(
|
|
18
|
-
console.log(chalk.gray(
|
|
19
|
-
console.log(chalk.gray(
|
|
17
|
+
console.log(chalk.white(` ${t('reportStage2')}`));
|
|
18
|
+
console.log(chalk.green(` ${t('reportExperienced')}`));
|
|
19
|
+
console.log(chalk.gray(` ${t('reportStage2Sub')}`));
|
|
20
|
+
console.log(chalk.gray(` ${t('reportStage2Hints')}`));
|
|
20
21
|
console.log();
|
|
21
|
-
console.log(chalk.white(
|
|
22
|
+
console.log(chalk.white(` ${t('reportStage3')}`));
|
|
22
23
|
if (ctf4aiSolved) {
|
|
23
|
-
console.log(chalk.green(
|
|
24
|
+
console.log(chalk.green(` ${t('reportSolved')}`));
|
|
24
25
|
}
|
|
25
26
|
else {
|
|
26
|
-
console.log(chalk.yellow(
|
|
27
|
+
console.log(chalk.yellow(` ${t('reportNotSolved')}`));
|
|
27
28
|
}
|
|
28
|
-
console.log(chalk.gray(`
|
|
29
|
+
console.log(chalk.gray(` ${t('ai4ctfTokens')}: ${ctf4aiTokens}/${CTF4AI_TOKEN_LIMIT}`));
|
|
29
30
|
console.log();
|
|
30
31
|
console.log(chalk.cyan(' ─────────────────────────────────────────────'));
|
|
31
32
|
console.log();
|
|
32
|
-
console.log(chalk.bold.white(
|
|
33
|
-
console.log(chalk.gray(
|
|
34
|
-
console.log(chalk.gray(
|
|
35
|
-
console.log(chalk.gray(
|
|
36
|
-
console.log(chalk.gray(
|
|
33
|
+
console.log(chalk.bold.white(` ${t('reportRecommend')}`));
|
|
34
|
+
console.log(chalk.gray(` · ${t('reportRec1')}`));
|
|
35
|
+
console.log(chalk.gray(` · ${t('reportRec2')}`));
|
|
36
|
+
console.log(chalk.gray(` · ${t('reportRec3')}`));
|
|
37
|
+
console.log(chalk.gray(` · ${t('reportRec4')}`));
|
|
37
38
|
console.log();
|
|
38
|
-
console.log(chalk.gray(`
|
|
39
|
+
console.log(chalk.gray(` ${t('ai4ctfModel')}: Google Gemma 4 (${modelName})`));
|
|
39
40
|
console.log();
|
|
40
41
|
console.log(chalk.cyan(' ─────────────────────────────────────────────'));
|
|
41
42
|
console.log();
|
|
42
|
-
console.log(chalk.white(
|
|
43
|
-
console.log(chalk.white(' nations') + chalk.gray(
|
|
44
|
-
console.log(chalk.white(' about') + chalk.gray(
|
|
45
|
-
console.log(chalk.white(' demo') + chalk.gray(
|
|
43
|
+
console.log(chalk.white(` ${t('reportReady')}`));
|
|
44
|
+
console.log(chalk.white(' nations') + chalk.gray(` ${t('reportNations')}`));
|
|
45
|
+
console.log(chalk.white(' about') + chalk.gray(` ${t('reportAbout')}`));
|
|
46
|
+
console.log(chalk.white(' demo') + chalk.gray(` ${t('reportDemo')}`));
|
|
46
47
|
console.log();
|
|
47
48
|
console.log(chalk.yellow(' ICOA 2026 · Sydney, Australia · Jun 27 - Jul 2'));
|
|
48
49
|
console.log(chalk.cyan.underline(' https://icoa2026.au'));
|
|
@@ -80,14 +81,14 @@ export async function handleCtf4aiMessage(input) {
|
|
|
80
81
|
signal: AbortSignal.timeout(5000),
|
|
81
82
|
}).catch(() => { });
|
|
82
83
|
console.log();
|
|
83
|
-
console.log(chalk.gray(
|
|
84
|
+
console.log(chalk.gray(` ${t('ctf4aiEnded')}`));
|
|
84
85
|
printDemoReport(false, ctf4aiTokens);
|
|
85
86
|
return 'exit';
|
|
86
87
|
}
|
|
87
88
|
if (ctf4aiTokens >= CTF4AI_TOKEN_LIMIT) {
|
|
88
89
|
console.log();
|
|
89
|
-
console.log(chalk.yellow(
|
|
90
|
-
console.log(chalk.white(
|
|
90
|
+
console.log(chalk.yellow(` ${t('tokenLimit')}`));
|
|
91
|
+
console.log(chalk.white(` ${t('ctf4aiHeld')}`));
|
|
91
92
|
ctf4aiActive = false;
|
|
92
93
|
ctf4aiSession = null;
|
|
93
94
|
fetch('https://practice.icoa2026.au/api/icoa/demo-stats', {
|
|
@@ -101,7 +102,7 @@ export async function handleCtf4aiMessage(input) {
|
|
|
101
102
|
}
|
|
102
103
|
logCommand(`ctf4ai: ${input}`);
|
|
103
104
|
try {
|
|
104
|
-
console.log(chalk.gray(
|
|
105
|
+
console.log(chalk.gray(` ${t('ctf4aiThinking')}`));
|
|
105
106
|
const { text, tokensUsed } = await ctf4aiSession.sendMessage(input);
|
|
106
107
|
ctf4aiTokens += tokensUsed;
|
|
107
108
|
// Clear "Thinking..." line
|
|
@@ -117,11 +118,11 @@ export async function handleCtf4aiMessage(input) {
|
|
|
117
118
|
if (strictMatch || spelledMatch) {
|
|
118
119
|
console.log();
|
|
119
120
|
console.log(chalk.green.bold(' ════════════════════════════════════'));
|
|
120
|
-
console.log(chalk.green.bold(
|
|
121
|
+
console.log(chalk.green.bold(` ${t('ctf4aiSuccess')}`));
|
|
121
122
|
console.log(chalk.green.bold(' ════════════════════════════════════'));
|
|
122
123
|
console.log();
|
|
123
|
-
console.log(chalk.white(
|
|
124
|
-
console.log(chalk.gray(
|
|
124
|
+
console.log(chalk.white(` ${t('ctf4aiDefense')}`));
|
|
125
|
+
console.log(chalk.gray(` ${t('ctf4aiInjection')}`));
|
|
125
126
|
ctf4aiActive = false;
|
|
126
127
|
ctf4aiSession = null;
|
|
127
128
|
fetch('https://practice.icoa2026.au/api/icoa/demo-stats', {
|
|
@@ -147,34 +148,34 @@ export function registerCtf4aiDemoCommand(program) {
|
|
|
147
148
|
.action(async () => {
|
|
148
149
|
logCommand('ctf4ai');
|
|
149
150
|
if (ctf4aiActive) {
|
|
150
|
-
console.log(chalk.gray(
|
|
151
|
+
console.log(chalk.gray(` ${t('ctf4aiAlready')}`));
|
|
151
152
|
return;
|
|
152
153
|
}
|
|
153
154
|
const config = getConfig();
|
|
154
155
|
const modelName = config.geminiModel || 'gemma-4-31b-it';
|
|
155
156
|
console.log();
|
|
156
|
-
console.log(chalk.red.bold(
|
|
157
|
+
console.log(chalk.red.bold(` ═══ ${t('ctf4aiTitle')} ═══`));
|
|
157
158
|
console.log();
|
|
158
|
-
console.log(chalk.white(
|
|
159
|
+
console.log(chalk.white(` ${t('ctf4aiChallenge')}`));
|
|
159
160
|
console.log();
|
|
160
|
-
console.log(chalk.gray(
|
|
161
|
-
console.log(chalk.gray(
|
|
161
|
+
console.log(chalk.gray(` ${t('ctf4aiIntro1')}`));
|
|
162
|
+
console.log(chalk.gray(` ${t('ctf4aiIntro2')}`));
|
|
162
163
|
console.log();
|
|
163
164
|
console.log(chalk.gray(' ┌─────────────────────────────────────────────────┐'));
|
|
164
|
-
console.log(chalk.gray(' │') + chalk.white(
|
|
165
|
-
console.log(chalk.gray(' │') + chalk.white(
|
|
165
|
+
console.log(chalk.gray(' │') + chalk.white(` ${t('ctf4aiRule')}`.padEnd(50)) + chalk.gray('│'));
|
|
166
|
+
console.log(chalk.gray(' │') + chalk.white(` ${t('ctf4aiMission')}`.padEnd(50)) + chalk.gray('│'));
|
|
166
167
|
console.log(chalk.gray(' │') + chalk.white(' ') + chalk.gray('│'));
|
|
167
|
-
console.log(chalk.gray(' │') + chalk.yellow(
|
|
168
|
-
console.log(chalk.gray(' │') + chalk.gray(
|
|
169
|
-
console.log(chalk.gray(' │') + chalk.gray(
|
|
170
|
-
console.log(chalk.gray(' │') + chalk.gray(
|
|
171
|
-
console.log(chalk.gray(' │') + chalk.gray(
|
|
168
|
+
console.log(chalk.gray(' │') + chalk.yellow(` ${t('ctf4aiIdeas')}`.padEnd(50)) + chalk.gray('│'));
|
|
169
|
+
console.log(chalk.gray(' │') + chalk.gray(` · ${t('ctf4aiIdea1')}`.padEnd(50)) + chalk.gray('│'));
|
|
170
|
+
console.log(chalk.gray(' │') + chalk.gray(` · ${t('ctf4aiIdea2')}`.padEnd(50)) + chalk.gray('│'));
|
|
171
|
+
console.log(chalk.gray(' │') + chalk.gray(` · ${t('ctf4aiIdea3')}`.padEnd(50)) + chalk.gray('│'));
|
|
172
|
+
console.log(chalk.gray(' │') + chalk.gray(` · ${t('ctf4aiIdea4')}`.padEnd(50)) + chalk.gray('│'));
|
|
172
173
|
console.log(chalk.gray(' └─────────────────────────────────────────────────┘'));
|
|
173
174
|
console.log();
|
|
174
|
-
console.log(chalk.gray(`
|
|
175
|
-
console.log(chalk.gray(
|
|
176
|
-
console.log(chalk.gray(`
|
|
177
|
-
console.log(chalk.gray(
|
|
175
|
+
console.log(chalk.gray(` ${t('ctf4aiBudget')}: ~${Math.round(CTF4AI_TOKEN_LIMIT / 4)} words (${CTF4AI_TOKEN_LIMIT} tokens)`));
|
|
176
|
+
console.log(chalk.gray(` ${t('ctf4aiRelaxed')}`));
|
|
177
|
+
console.log(chalk.gray(` ${t('ai4ctfModel')}: Google Gemma 4 (${modelName})`));
|
|
178
|
+
console.log(chalk.gray(` ${t('ctf4aiQuit')}`));
|
|
178
179
|
console.log();
|
|
179
180
|
try {
|
|
180
181
|
// Create chat with restrictive system prompt
|
|
@@ -196,7 +197,7 @@ export function registerCtf4aiDemoCommand(program) {
|
|
|
196
197
|
};
|
|
197
198
|
ctf4aiActive = true;
|
|
198
199
|
ctf4aiTokens = 0;
|
|
199
|
-
console.log(chalk.red(' ctf4ai> ') + chalk.gray('
|
|
200
|
+
console.log(chalk.red(' ctf4ai> ') + chalk.gray(`${t('ctf4aiPrompt')}`));
|
|
200
201
|
console.log();
|
|
201
202
|
}
|
|
202
203
|
catch (err) {
|
package/dist/commands/exam.js
CHANGED
|
@@ -739,36 +739,31 @@ export function registerExamCommand(program) {
|
|
|
739
739
|
}
|
|
740
740
|
console.log();
|
|
741
741
|
// ─── What is CTF + Dual-track introduction ───
|
|
742
|
-
console.log(chalk.white(
|
|
742
|
+
console.log(chalk.white(` ${t('theoryDone')}`));
|
|
743
|
+
console.log(chalk.white(` ${t('theoryDone2')}`));
|
|
743
744
|
console.log();
|
|
744
|
-
console.log(chalk.yellow(
|
|
745
|
-
console.log(chalk.gray(
|
|
746
|
-
console.log(chalk.gray(
|
|
747
|
-
console.log(chalk.
|
|
748
|
-
console.log(chalk.gray(
|
|
745
|
+
console.log(chalk.yellow(` ${t('didYouKnow')}`));
|
|
746
|
+
console.log(chalk.gray(` ${t('ctfFlags1')}`));
|
|
747
|
+
console.log(chalk.gray(` ${t('ctfFlags2')}`));
|
|
748
|
+
console.log(chalk.green(' icoa{example_flag_here}'));
|
|
749
|
+
console.log(chalk.gray(` ${t('ctfFlags3')}`));
|
|
749
750
|
console.log();
|
|
750
|
-
console.log(chalk.white(
|
|
751
|
+
console.log(chalk.white(` ${t('twoTracks')}`));
|
|
751
752
|
console.log();
|
|
752
|
-
console.log(chalk.green.bold(' AI4CTF') + chalk.white(
|
|
753
|
-
console.log(chalk.gray(
|
|
754
|
-
console.log(chalk.gray(' and work together to crack cybersecurity puzzles.'));
|
|
753
|
+
console.log(chalk.green.bold(' AI4CTF') + chalk.white(` — ${t('ai4ctfDesc')}`));
|
|
754
|
+
console.log(chalk.gray(` ${t('ai4ctfSub')}`));
|
|
755
755
|
console.log();
|
|
756
|
-
console.log(chalk.red.bold(' CTF4AI') + chalk.white(
|
|
757
|
-
console.log(chalk.gray(
|
|
758
|
-
console.log(chalk.gray(' This is a real skill used to test AI security.'));
|
|
756
|
+
console.log(chalk.red.bold(' CTF4AI') + chalk.white(` — ${t('ctf4aiDesc')}`));
|
|
757
|
+
console.log(chalk.gray(` ${t('ctf4aiSub')}`));
|
|
759
758
|
console.log();
|
|
760
759
|
console.log(chalk.cyan(' ─────────────────────────────────────────────'));
|
|
761
|
-
console.log(chalk.
|
|
762
|
-
console.log(chalk.
|
|
763
|
-
console.log(chalk.
|
|
764
|
-
console.log();
|
|
765
|
-
console.log(chalk.white(' Ready to try? Type a command:'));
|
|
766
|
-
console.log(chalk.green.bold(' ai4ctf') + chalk.gray(' Chat with AI teammate (start here!)'));
|
|
767
|
-
console.log(chalk.red.bold(' ctf4ai') + chalk.gray(' Trick the AI — make it say "koala"'));
|
|
760
|
+
console.log(chalk.white(` ${t('readyToTry')}`));
|
|
761
|
+
console.log(chalk.green.bold(' ai4ctf') + chalk.gray(` ${t('ai4ctfDesc')}`));
|
|
762
|
+
console.log(chalk.red.bold(' ctf4ai') + chalk.gray(` ${t('ctf4aiDesc')}`));
|
|
768
763
|
console.log();
|
|
769
|
-
console.log(chalk.gray(
|
|
770
|
-
console.log(chalk.white(' nations') + chalk.gray(
|
|
771
|
-
console.log(chalk.white(' exam AU') + chalk.gray(
|
|
764
|
+
console.log(chalk.gray(` ${t('forNational')}`));
|
|
765
|
+
console.log(chalk.white(' nations') + chalk.gray(` ${t('viewRegions')}`));
|
|
766
|
+
console.log(chalk.white(' exam AU') + chalk.gray(` ${t('enterExam')}`));
|
|
772
767
|
console.log();
|
|
773
768
|
}
|
|
774
769
|
catch (err) {
|
package/dist/lib/gemini.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GoogleGenAI } from '@google/genai';
|
|
2
|
+
import chalk from 'chalk';
|
|
2
3
|
import { getConfig, saveConfig } from './config.js';
|
|
3
4
|
const SYSTEM_PROMPTS = {
|
|
4
5
|
A: `You are an AI assistant in a cybersecurity CTF competition called ICOA.
|
|
@@ -60,14 +61,14 @@ export async function generateHint(level, question, context) {
|
|
|
60
61
|
try {
|
|
61
62
|
const { input } = await import('@inquirer/prompts');
|
|
62
63
|
console.log();
|
|
63
|
-
console.log(' Gemini API key not configured.');
|
|
64
|
-
console.log(' Get one free at: https://aistudio.google.com/apikey');
|
|
64
|
+
console.log(chalk.yellow(' Gemini API key not configured.'));
|
|
65
|
+
console.log(chalk.gray(' Get one free at: ') + chalk.cyan('https://aistudio.google.com/apikey'));
|
|
65
66
|
console.log();
|
|
66
67
|
apiKey = await input({ message: 'Enter your Gemini API Key:' });
|
|
67
68
|
if (apiKey.trim()) {
|
|
68
69
|
apiKey = apiKey.trim();
|
|
69
70
|
saveConfig({ geminiApiKey: apiKey });
|
|
70
|
-
console.log(' Key saved for future use.');
|
|
71
|
+
console.log(chalk.green(' Key saved for future use.'));
|
|
71
72
|
console.log();
|
|
72
73
|
}
|
|
73
74
|
else {
|
|
@@ -146,14 +147,14 @@ export async function createChatSession(context) {
|
|
|
146
147
|
try {
|
|
147
148
|
const { input } = await import('@inquirer/prompts');
|
|
148
149
|
console.log();
|
|
149
|
-
console.log(' Gemini API key not configured.');
|
|
150
|
-
console.log(' Get one free at: https://aistudio.google.com/apikey');
|
|
150
|
+
console.log(chalk.yellow(' Gemini API key not configured.'));
|
|
151
|
+
console.log(chalk.gray(' Get one free at: ') + chalk.cyan('https://aistudio.google.com/apikey'));
|
|
151
152
|
console.log();
|
|
152
153
|
apiKey = await input({ message: 'Enter your Gemini API Key:' });
|
|
153
154
|
if (apiKey.trim()) {
|
|
154
155
|
apiKey = apiKey.trim();
|
|
155
156
|
saveConfig({ geminiApiKey: apiKey });
|
|
156
|
-
console.log(' Key saved for future use.');
|
|
157
|
+
console.log(chalk.green(' Key saved for future use.'));
|
|
157
158
|
console.log();
|
|
158
159
|
}
|
|
159
160
|
else {
|
package/dist/lib/i18n.d.ts
CHANGED
|
@@ -119,6 +119,26 @@ declare const EN: {
|
|
|
119
119
|
continueTry: string;
|
|
120
120
|
continueChat: string;
|
|
121
121
|
continueAfter: string;
|
|
122
|
+
ai4ctfCommands: string;
|
|
123
|
+
ai4ctfSubmitCmd: string;
|
|
124
|
+
ai4ctfShellCmd: string;
|
|
125
|
+
ai4ctfEndSession: string;
|
|
126
|
+
ai4ctfCorrectFlag: string;
|
|
127
|
+
ai4ctfDecoded: string;
|
|
128
|
+
ai4ctfWouldEarn: string;
|
|
129
|
+
ai4ctfWrongFlag: string;
|
|
130
|
+
ai4ctfFlagHint: string;
|
|
131
|
+
ai4ctfFoundFlag: string;
|
|
132
|
+
ai4ctfThinking: string;
|
|
133
|
+
ctf4aiRelaxed: string;
|
|
134
|
+
ctf4aiEnded: string;
|
|
135
|
+
ctf4aiAlready: string;
|
|
136
|
+
ctf4aiPrompt: string;
|
|
137
|
+
ctf4aiThinking: string;
|
|
138
|
+
readyToTry: string;
|
|
139
|
+
forNational: string;
|
|
140
|
+
viewRegions: string;
|
|
141
|
+
enterExam: string;
|
|
122
142
|
};
|
|
123
143
|
export declare function t(key: keyof Strings): string;
|
|
124
144
|
export declare function hasFullTranslation(lang: string): boolean;
|