icoa-cli 2.19.28 → 2.19.30

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.
@@ -31,9 +31,57 @@ function drawTokenBar() {
31
31
  console.log(chalk.gray(' Tokens: ') + color('█'.repeat(filled)) + chalk.gray('░'.repeat(empty)) + chalk.gray(` ${used}/${cap} (${pct}%)`));
32
32
  }
33
33
  const DEMO_FLAG = 'icoa{w3lc0me_2_ai4ctf}';
34
+ // Scripted hints for the built-in Base64 demo challenge. These mirror the
35
+ // three real-competition hint tiers (nudge → technique → near-answer) so
36
+ // the user can feel what `hint a/b/c` will be like in the actual event.
37
+ const DEMO_HINTS = {
38
+ a: [
39
+ 'The string ends with `==` and contains only letters, digits, `+`, `/`, and `=`.',
40
+ 'That pattern is a fingerprint — you have seen it before. Think about where `=` is used as *padding*.',
41
+ ],
42
+ b: [
43
+ 'That is **Base64**. The `==` is padding; the character set (A–Z, a–z, 0–9, +, /) confirms it.',
44
+ 'You can decode it right in this shell — try:',
45
+ ' !echo aWNvYXt3M2xjMG1lXzJfYWk0Y3RmfQ== | base64 -d',
46
+ 'Or just ask the AI: "decode this for me".',
47
+ ],
48
+ c: [
49
+ 'The decoded value is `icoa{w3lc0me_2_ai4ctf}`.',
50
+ 'Submit it with:',
51
+ ' submit icoa{w3lc0me_2_ai4ctf}',
52
+ ],
53
+ };
54
+ function showDemoHint(tier) {
55
+ const title = tier === 'a' ? t('ai4ctfHintA') : tier === 'b' ? t('ai4ctfHintB') : t('ai4ctfHintC');
56
+ const tierLabel = `Hint ${tier.toUpperCase()}`;
57
+ const color = tier === 'a' ? chalk.green : tier === 'b' ? chalk.yellow : chalk.red;
58
+ console.log();
59
+ console.log(color.bold(` ▸ ${tierLabel} `) + chalk.gray(title));
60
+ console.log();
61
+ for (const line of DEMO_HINTS[tier]) {
62
+ console.log(chalk.white(' ' + line));
63
+ }
64
+ console.log();
65
+ const nextTier = tier === 'a' ? 'b' : tier === 'b' ? 'c' : null;
66
+ if (nextTier) {
67
+ console.log(chalk.gray(` Need more? Type: `) + chalk.cyan(`hint ${nextTier}`));
68
+ }
69
+ else {
70
+ console.log(chalk.gray(' That is the deepest hint. Try: ') + chalk.cyan('submit icoa{w3lc0me_2_ai4ctf}'));
71
+ }
72
+ console.log();
73
+ }
34
74
  export async function handleChatMessage(input) {
35
75
  if (!chatSession)
36
76
  return 'exit';
77
+ // Scripted demo hints — intercept before the AI chat so that typing
78
+ // `hint a` / `hint b` / `hint c` behaves like a real competition command
79
+ // instead of becoming a generic AI chat turn.
80
+ const hintMatch = input.trim().toLowerCase().match(/^hint\s+([abc])$/);
81
+ if (hintMatch) {
82
+ showDemoHint(hintMatch[1]);
83
+ return 'continue';
84
+ }
37
85
  // Flag submission
38
86
  const submitMatch = input.match(/^submit\s+(.+)/i);
39
87
  if (submitMatch) {
@@ -175,15 +223,17 @@ export function registerAi4ctfCommand(program) {
175
223
  console.log();
176
224
  console.log(chalk.white(` ${t('ai4ctfSample')}`));
177
225
  console.log();
178
- console.log(chalk.cyan(' ┌─────────────────────────────────────────────────┐'));
179
- console.log(chalk.cyan(' │') + chalk.bold.white(` ${t('ai4ctfChallenge')}`.padEnd(50)) + chalk.cyan('│'));
180
- console.log(chalk.cyan(' ') + chalk.white(' ') + chalk.cyan('│'));
181
- console.log(chalk.cyan(' │') + chalk.white(` ${t('ai4ctfIntercepted')}`.padEnd(50)) + chalk.cyan('│'));
182
- console.log(chalk.cyan(' │') + chalk.green(' aWNvYXt3M2xjMG1lXzJfYWk0Y3RmfQ== ') + chalk.cyan('│'));
183
- console.log(chalk.cyan(' │') + chalk.white(' ') + chalk.cyan(''));
184
- console.log(chalk.cyan(' │') + chalk.white(` ${t('ai4ctfDecode')}`.padEnd(50)) + chalk.cyan(''));
185
- console.log(chalk.cyan(' │') + chalk.gray(' Flag format: icoa{...} ') + chalk.cyan('│'));
186
- console.log(chalk.cyan(' └─────────────────────────────────────────────────┘'));
226
+ // Left gutter only — right border dropped because CJK/emoji widths
227
+ // broke `padEnd` alignment across the 16 supported languages.
228
+ console.log(chalk.cyan(' ┌─────────────────────────────────────────────'));
229
+ console.log(chalk.cyan(' │ ') + chalk.bold.white(t('ai4ctfChallenge')));
230
+ console.log(chalk.cyan(' │'));
231
+ console.log(chalk.cyan(' │ ') + chalk.white(t('ai4ctfIntercepted')));
232
+ console.log(chalk.cyan(' │ ') + chalk.green('aWNvYXt3M2xjMG1lXzJfYWk0Y3RmfQ=='));
233
+ console.log(chalk.cyan(' │'));
234
+ console.log(chalk.cyan(' ') + chalk.white(t('ai4ctfDecode')));
235
+ console.log(chalk.cyan(' │ ') + chalk.gray('Flag format: icoa{...}'));
236
+ console.log(chalk.cyan(' └─────────────────────────────────────────────'));
187
237
  console.log();
188
238
  console.log(chalk.white(` ${t('ai4ctfLevels')}`));
189
239
  console.log();
@@ -195,13 +245,19 @@ export function registerAi4ctfCommand(program) {
195
245
  console.log(chalk.gray(` ${t('ai4ctfHintCUses')}`));
196
246
  console.log();
197
247
  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')}`));
248
+ console.log(chalk.bold.white(' 👉 New here? Start with the hints in order:'));
249
+ console.log(' ' + chalk.cyan('hint a') + chalk.gray(' → nudge'));
250
+ console.log(' ' + chalk.cyan('hint b') + chalk.gray(' → technique'));
251
+ console.log(' ' + chalk.cyan('hint c') + chalk.gray(' → near-answer'));
252
+ console.log();
253
+ console.log(chalk.white(' Or chat freely with your AI teammate — ask anything'));
254
+ console.log(chalk.gray(' about the challenge. Example: ') + chalk.white('"what encoding is this?"'));
201
255
  console.log();
202
256
  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')}`));
257
+ console.log(chalk.white(' hint a / b / c ') + chalk.gray('pre-written hints (safe to use)'));
258
+ console.log(chalk.white(' submit <flag> ') + chalk.gray(t('ai4ctfSubmitCmd')));
259
+ console.log(chalk.white(' !<shell cmd> ') + chalk.gray('run a shell command'));
260
+ console.log(chalk.gray(' e.g. ') + chalk.white('!echo aWNv... | base64 -d'));
205
261
  console.log(chalk.gray(` exit ${t('ai4ctfEndSession')}`));
206
262
  console.log();
207
263
  drawTokenBar();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "2.19.28",
3
+ "version": "2.19.30",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {