icoa-cli 2.19.356 → 2.19.358

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.
@@ -1 +1 @@
1
- import{execSync as o,spawnSync as e}from"node:child_process";import chalk from"chalk";import{printInfo as n,printSuccess as r}from"../lib/ui.js";import{logCommand as s}from"../lib/logger.js";import{getActiveCwd as t}from"../lib/exam-sandbox.js";export function resolveShellLaunch(o){return o.dockerAvailable?{mode:"docker",command:"docker"}:{mode:"host",command:"win32"===o.platform?o.comspecEnv||"cmd.exe":o.shellEnv||"/bin/bash"}}export{SANDBOX_IMAGES,resolveSandboxImage}from"../lib/sandbox.js";import{SANDBOX_IMAGES as i,resolveSandboxImage as l}from"../lib/sandbox.js";export function buildSandboxRunArgs(o){return["run","--rm","-it","--name",o.containerName,"--network=host","-v",`${o.cwd}:/work`,"-w","/work","-v","icoa-aienv:/root/.icoa",o.image,"/bin/bash"]}function a(){const e=t(),{command:s}=resolveShellLaunch({dockerAvailable:!1,platform:process.platform,shellEnv:process.env.SHELL,comspecEnv:process.env.COMSPEC});n("Docker not found — opening a host shell."),console.log(chalk.gray(" All 110 CTF tools run on your host. If any are missing, run ")+chalk.cyan("env setup")+chalk.gray(".")),console.log(chalk.gray(" Type 'exit' to return to ICOA CLI.")),console.log();try{o(s,{stdio:"inherit",cwd:e}),console.log(),r("Shell session ended.")}catch{console.log(),n("Shell session ended.")}}export function registerShellCommand(c){c.command("shell").description("Open an interactive CTF shell (Docker sandbox if available, else host)").action(async()=>{if(s("shell"),!function(){try{return o("docker info",{stdio:"ignore"}),!0}catch{return!1}}())return void a();const c=l(e=>{try{return o(`docker image inspect ${e}`,{stdio:"ignore"}),!0}catch{return!1}},e=>{n(`Pulling ${e}...`);try{return o(`docker pull ${e}`,{stdio:"inherit"}),!0}catch{return!1}});if(null===c)return n("Could not pull a sandbox image — using your host shell instead."),void a();const d=t();r("Launching sandbox..."),console.log(chalk.gray(" Your folder is mounted at ")+chalk.cyan("/work")+chalk.gray(" — files there persist on your host.")),c===i[0]?console.log(chalk.gray(" ML venv: ")+chalk.cyan("~/.icoa/aienv/bin/python")+chalk.gray(" (sklearn / jupyter / mujoco) — its pip installs persist across sessions.")):console.log(chalk.gray(" This image has no ML venv — get the newer one with ")+chalk.cyan(`docker pull ${i[0]}`)),console.log(chalk.gray(" Type 'exit' to return to ICOA CLI.")),console.log();const m=`icoa-sandbox-${Date.now()}`,u=e("docker",buildSandboxRunArgs({cwd:d,image:c,containerName:m}),{stdio:"inherit"});console.log(),u.error?n("Sandbox session ended."):r("Sandbox session ended.")})}
1
+ import{execSync as o,spawnSync as e}from"node:child_process";import chalk from"chalk";import{printInfo as n,printSuccess as r}from"../lib/ui.js";import{logCommand as s}from"../lib/logger.js";import{getActiveCwd as i}from"../lib/exam-sandbox.js";import{isDockerRunning as l}from"../lib/docker-probe.js";export function resolveShellLaunch(o){return o.dockerAvailable?{mode:"docker",command:"docker"}:{mode:"host",command:"win32"===o.platform?o.comspecEnv||"cmd.exe":o.shellEnv||"/bin/bash"}}export{SANDBOX_IMAGES,resolveSandboxImage}from"../lib/sandbox.js";import{SANDBOX_IMAGES as t,resolveSandboxImage as a}from"../lib/sandbox.js";export function buildSandboxRunArgs(o){return["run","--rm","-it","--name",o.containerName,"--network=host","-v",`${o.cwd}:/work`,"-w","/work","-v","icoa-aienv:/root/.icoa",o.image,"/bin/bash"]}function c(){const e=i(),{command:s}=resolveShellLaunch({dockerAvailable:!1,platform:process.platform,shellEnv:process.env.SHELL,comspecEnv:process.env.COMSPEC});n("Docker not found — opening a host shell."),console.log(chalk.gray(" All 110 CTF tools run on your host. If any are missing, run ")+chalk.cyan("env setup")+chalk.gray(".")),console.log(chalk.gray(" Type 'exit' to return to ICOA CLI.")),console.log();try{o(s,{stdio:"inherit",cwd:e}),console.log(),r("Shell session ended.")}catch{console.log(),n("Shell session ended.")}}export function registerShellCommand(d){d.command("shell").description("Open an interactive CTF shell (Docker sandbox if available, else host)").action(async()=>{if(s("shell"),!await l())return void c();const d=a(e=>{try{return o(`docker image inspect ${e}`,{stdio:"ignore"}),!0}catch{return!1}},e=>{n(`Pulling ${e}...`);try{return o(`docker pull ${e}`,{stdio:"inherit"}),!0}catch{return!1}});if(null===d)return n("Could not pull a sandbox image — using your host shell instead."),void c();const m=i();r("Launching sandbox..."),console.log(chalk.gray(" Your folder is mounted at ")+chalk.cyan("/work")+chalk.gray(" — files there persist on your host.")),d===t[0]?console.log(chalk.gray(" ML venv: ")+chalk.cyan("~/.icoa/aienv/bin/python")+chalk.gray(" (sklearn / jupyter / mujoco) — its pip installs persist across sessions.")):console.log(chalk.gray(" This image has no ML venv — get the newer one with ")+chalk.cyan(`docker pull ${t[0]}`)),console.log(chalk.gray(" Type 'exit' to return to ICOA CLI.")),console.log();const u=`icoa-sandbox-${Date.now()}`,g=e("docker",buildSandboxRunArgs({cwd:m,image:d,containerName:u}),{stdio:"inherit"});console.log(),g.error?n("Sandbox session ended."):r("Sandbox session ended.")})}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Detect whether the Docker daemon is running WITHOUT waking it.
3
+ *
4
+ * The `docker` CLI is the trigger: on macOS, running any `docker` command
5
+ * (including `docker info`) can auto-launch Docker Desktop. The old probe
6
+ * shelled out to `docker info`, so every REPL shell-out and every `shell`
7
+ * invocation kept starting Docker on the user's Mac even though the sandbox is
8
+ * OPTIONAL and the host-shell fallback is the norm (2026-07 feedback).
9
+ *
10
+ * This probes the daemon's listening SOCKET directly (Node `net`) and never
11
+ * invokes the `docker` binary. Docker already up → the socket connects → we use
12
+ * the sandbox. Docker down → connection refused → we silently use the host
13
+ * shell, and Docker is never started.
14
+ */
15
+ export type DockerProbeKind = 'unix' | 'tcp' | 'npipe';
16
+ export interface DockerProbeTarget {
17
+ kind: DockerProbeKind;
18
+ /** unix/npipe: a filesystem/pipe path. tcp: "host:port". */
19
+ target: string;
20
+ }
21
+ /**
22
+ * Ordered daemon endpoints to probe. A `DOCKER_HOST` (unix://, tcp://, npipe://)
23
+ * overrides everything — it's the user's explicit daemon. Otherwise fall back to
24
+ * the well-known per-platform sockets, most-specific first. Pure + testable:
25
+ * platform/env/home are all injected.
26
+ */
27
+ export declare function dockerProbeTargets(platform: NodeJS.Platform, env: NodeJS.ProcessEnv, home: string): DockerProbeTarget[];
28
+ /**
29
+ * True if ANY target accepts a connection, probing in order and stopping at the
30
+ * first hit. `connect` is injected (returns whether a target is reachable) so
31
+ * the ordering/short-circuit is unit-tested without real sockets.
32
+ */
33
+ export declare function anyReachable(targets: DockerProbeTarget[], connect: (t: DockerProbeTarget) => Promise<boolean>): Promise<boolean>;
34
+ /**
35
+ * True iff `raw` is a Docker Engine `/_ping` response from a LIVE daemon — an
36
+ * HTTP 200. A bare connect isn't enough: after Docker Desktop quits, a lingering
37
+ * helper can keep the socket connectable while the daemon is down, so we require
38
+ * the daemon to actually answer the API. Pure + tested.
39
+ */
40
+ export declare function isDockerPingResponse(raw: string): boolean;
41
+ /**
42
+ * The public check: is a Docker daemon reachable right now, without starting it?
43
+ * platform/env/home are injectable for tests; production uses process defaults.
44
+ */
45
+ export declare function isDockerRunning(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv, home?: string): Promise<boolean>;
@@ -0,0 +1 @@
1
+ import t from"node:net";export function dockerProbeTargets(t,e,n){const r=e.DOCKER_HOST?.trim();if(r){if(r.startsWith("unix://"))return[{kind:"unix",target:r.slice(7)}];if(r.startsWith("tcp://"))return[{kind:"tcp",target:r.slice(6)}];if(r.startsWith("npipe://"))return[{kind:"npipe",target:r.slice(8)}]}if("win32"===t)return[{kind:"npipe",target:"\\\\.\\pipe\\docker_engine"}];if("darwin"===t)return[{kind:"unix",target:`${n}/.docker/run/docker.sock`},{kind:"unix",target:"/var/run/docker.sock"}];const o=[{kind:"unix",target:"/var/run/docker.sock"}],i=e.XDG_RUNTIME_DIR?.trim();return i&&o.push({kind:"unix",target:`${i}/docker.sock`}),o.push({kind:"unix",target:`${n}/.docker/run/docker.sock`}),o}export async function anyReachable(t,e){for(const n of t)if(await e(n))return!0;return!1}export function isDockerPingResponse(t){return/^HTTP\/1\.[01] 200\b/.test(t.trimStart())}function e(e,n=600){return new Promise(r=>{let o=!1,i="";const c=t=>{if(!o){o=!0;try{s.destroy()}catch{}r(t)}},s="tcp"===e.kind?t.connect({host:e.target.split(":")[0],port:Number(e.target.split(":")[1])}):t.connect(e.target);s.setTimeout(n),s.once("connect",()=>s.write("GET /_ping HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n")),s.on("data",t=>{i+=t.toString("utf8"),(i.includes("\n")||i.length>15)&&c(isDockerPingResponse(i))}),s.once("timeout",()=>c(!1)),s.once("error",()=>c(!1)),s.once("close",()=>c(isDockerPingResponse(i)))})}export async function isDockerRunning(t=process.platform,n=process.env,r=process.env.HOME||process.env.USERPROFILE||""){return anyReachable(dockerProbeTargets(t,n,r),e)}
@@ -16,7 +16,13 @@ export declare const SANDBOX_IMAGES: readonly ["icoa/sandbox:2026.1", "icoa/sand
16
16
  * live in test/shell-sandbox-mounts.test.js via the shell.ts re-export).
17
17
  */
18
18
  export declare function resolveSandboxImage(hasLocal: (image: string) => boolean, pull: (image: string) => boolean, images?: readonly string[]): string | null;
19
- export declare function isDockerAvailable(): boolean;
19
+ /**
20
+ * Is Docker usable right now? Probes the daemon socket directly (never the
21
+ * `docker` CLI) so a stopped Docker Desktop is NOT auto-started — the sandbox
22
+ * is optional and the host shell is the fallback, so merely *checking* must not
23
+ * wake Docker. See lib/docker-probe.ts.
24
+ */
25
+ export declare function isDockerAvailable(): Promise<boolean>;
20
26
  export declare function ensureSandbox(): Promise<boolean>;
21
27
  export declare function runInSandbox(command: string, rl: {
22
28
  pause: () => void;
@@ -1 +1 @@
1
- import{execSync as o,spawn as e}from"node:child_process";import chalk from"chalk";export const SANDBOX_IMAGES=["icoa/sandbox:2026.1","icoa/sandbox:2026"];export function resolveSandboxImage(o,e,r=SANDBOX_IMAGES){for(const e of r)if(o(e))return e;for(const o of r)if(e(o))return o;return null}const r="icoa-sandbox";export function isDockerAvailable(){try{return o("docker info",{stdio:"ignore"}),!0}catch{return!1}}export async function ensureSandbox(){if(!isDockerAvailable())return console.log(chalk.yellow(" Docker not found. Install Docker Desktop to use sandbox tools.")),console.log(chalk.gray(" https://www.docker.com/products/docker-desktop")),!1;if(function(){try{return"true"===o(`docker inspect -f '{{.State.Running}}' ${r} 2>/dev/null`,{encoding:"utf-8"}).trim()}catch{return!1}}())return!0;try{return o(`docker start ${r}`,{stdio:"ignore"}),!0}catch{}let e=resolveSandboxImage(e=>{try{return o(`docker image inspect ${e}`,{stdio:"ignore"}),!0}catch{return!1}},e=>{console.log(chalk.gray(` Pulling ${e} (first time only)...`));try{return o(`docker pull ${e}`,{stdio:"inherit"}),!0}catch{return!1}});if(!e){console.log(chalk.gray(" Building sandbox from local Dockerfile.aienv..."));try{const r=new URL("../../docker",import.meta.url).pathname;o(`docker build -f ${r}/Dockerfile.aienv -t ${SANDBOX_IMAGES[0]} ${r}`,{stdio:"inherit"}),e=SANDBOX_IMAGES[0]}catch{return console.log(chalk.red(" Failed to set up sandbox.")),!1}}try{return o(`docker run -d --name ${r} -v icoa-challenges:/home/competitor/challenges --network bridge ${e} sleep infinity`,{stdio:"ignore"}),!0}catch{return console.log(chalk.red(" Failed to start sandbox container.")),!1}}export function runInSandbox(o,t){return new Promise(n=>{t.pause();const c=e("docker",["exec","-it",r,"bash","-c",o],{stdio:"inherit",shell:!0});c.on("close",()=>{t.resume(),n()}),c.on("error",()=>{t.resume(),n()})})}
1
+ import{execSync as o,spawn as e}from"node:child_process";import chalk from"chalk";import{isDockerRunning as r}from"./docker-probe.js";export const SANDBOX_IMAGES=["icoa/sandbox:2026.1","icoa/sandbox:2026"];export function resolveSandboxImage(o,e,r=SANDBOX_IMAGES){for(const e of r)if(o(e))return e;for(const o of r)if(e(o))return o;return null}const t="icoa-sandbox";export async function isDockerAvailable(){return r()}export async function ensureSandbox(){if(!await isDockerAvailable())return console.log(chalk.yellow(" Docker not found. Install Docker Desktop to use sandbox tools.")),console.log(chalk.gray(" https://www.docker.com/products/docker-desktop")),!1;if(function(){try{return"true"===o(`docker inspect -f '{{.State.Running}}' ${t} 2>/dev/null`,{encoding:"utf-8"}).trim()}catch{return!1}}())return!0;try{return o(`docker start ${t}`,{stdio:"ignore"}),!0}catch{}let e=resolveSandboxImage(e=>{try{return o(`docker image inspect ${e}`,{stdio:"ignore"}),!0}catch{return!1}},e=>{console.log(chalk.gray(` Pulling ${e} (first time only)...`));try{return o(`docker pull ${e}`,{stdio:"inherit"}),!0}catch{return!1}});if(!e){console.log(chalk.gray(" Building sandbox from local Dockerfile.aienv..."));try{const r=new URL("../../docker",import.meta.url).pathname;o(`docker build -f ${r}/Dockerfile.aienv -t ${SANDBOX_IMAGES[0]} ${r}`,{stdio:"inherit"}),e=SANDBOX_IMAGES[0]}catch{return console.log(chalk.red(" Failed to set up sandbox.")),!1}}try{return o(`docker run -d --name ${t} -v icoa-challenges:/home/competitor/challenges --network bridge ${e} sleep infinity`,{stdio:"ignore"}),!0}catch{return console.log(chalk.red(" Failed to start sandbox container.")),!1}}export function runInSandbox(o,r){return new Promise(n=>{r.pause();const c=e("docker",["exec","-it",t,"bash","-c",o],{stdio:"inherit",shell:!0});c.on("close",()=>{r.resume(),n()}),c.on("error",()=>{r.resume(),n()})})}
package/dist/repl.js CHANGED
@@ -1 +1 @@
1
- import{createInterface as o}from"node:readline";import{spawn as e,execSync as l}from"node:child_process";import chalk from"chalk";import{isConnected as n,getConfig as t,saveConfig as a}from"./lib/config.js";import{ensureLangCache as s}from"./lib/translations-fetcher.js";import{loadUiPack as r}from"./lib/i18n.js";import{isActivated as i,activateToken as c,isFreeCommand as g,isDeviceMatch as y,recordExit as m,recordResume as d,isFirstRunOrUpgrade as p,markVersionSeen as u}from"./lib/access.js";import{setReplMode as h}from"./lib/ui.js";import{returnToMainMenu as w,printMenuHint as f,menuHintInline as b}from"./lib/menu-nav.js";import{setMainRl as x}from"./lib/main-rl.js";import{shellSplit as v}from"./lib/shell-split.js";import{isChatActive as A,handleChatMessage as C}from"./commands/ai4ctf.js";import{renderToolMan as I}from"./lib/tool-man.js";import{isCtf4aiActive as k,handleCtf4aiMessage as T}from"./commands/ctf4ai-demo.js";import{isCtf4VlaActive as E,handleCtf4VlaMessage as S}from"./commands/ctf4vla.js";import{isDemo2Active as $}from"./commands/demo2.js";import{loadDemo2Progress as O}from"./lib/demo2-progress.js";import{hasAnySimHistory as j,lastArmAt as D,lastBundledAt as L,lastSimAt as N}from"./lib/sim-cooldown.js";import{getExamState as R,getRealExamState as P,getDemoState as F,practicalChatCommand as q}from"./lib/exam-state.js";import{resetTerminalTheme as M}from"./lib/theme.js";import{ensureSandbox as B,runInSandbox as U,isDockerAvailable as _}from"./lib/sandbox.js";import{checkShellRisk as Q,logShellAudit as z,getActiveCwd as W}from"./lib/exam-sandbox.js";import{logCommand as X}from"./lib/logger.js";import{startLogSync as Y,stopLogSync as J}from"./lib/log-sync.js";import{startBroadcastPoll as V,stopBroadcastPoll as G,showBroadcast as H,isCompetitionJoined as Z,isMelCompetition as K,isLeaderAccount as oo,isLeaderSession as eo,fetchPublicScoreboard as lo,isCommsActive as no}from"./lib/comms.js";import{enterMemoScreen as to,enterJuryScreen as ao}from"./commands/comms.js";import{existsSync as so,mkdirSync as ro,readFileSync as io,writeFileSync as co}from"node:fs";import{join as go}from"node:path";import{homedir as yo}from"node:os";const mo="# ICOA exam interactive startup — auto-loaded by PYTHONSTARTUP\nimport base64, struct, hashlib, re, json, os, sys, binascii\ntry: import requests\nexcept ImportError: pass\ntry: from Crypto.Cipher import AES\nexcept ImportError: pass\ntry: from Crypto.Util.Padding import pad, unpad\nexcept ImportError: pass\ntry: from pwn import xor, p32, u32, p64, u64\nexcept ImportError: pass\ntry: import bs4\nexcept ImportError: pass\ntry: import numpy as np\nexcept ImportError: pass\ntry: from PIL import Image\nexcept ImportError: pass\n",po=Date.now();function uo(){return K()?chalk.yellow("icoa 2026> "):P()?chalk.cyan("icoa exam> "):function(){const o=F();return!(!o||"demo-free"!==o.session?.examId)&&new Date(o.session.startedAt||0).getTime()>=po}()?chalk.yellow("icoa demo> "):chalk.green("icoa> ")}const ho=go(yo(),"icoa-workspace"),wo=new Set(["sudo","su","doas","pkexec","brew","apt","apt-get","yum","choco","npm","npx","pip","pip3","shutdown","reboot","halt","mkfs","fdisk","dd","iptables","ufw"]),fo="__REPL_NO_EXIT__",bo="2.5.1";function xo(){console.log(),console.log(` ${chalk.cyan.bold("🎯 ICOA 2026 · National Selection")}`),console.log(),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("ACxxxxxxxx")+chalk.gray(" → ai4ctf-12 (AI as your CTF teammate)")),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("CAxxxxxxxx")+chalk.gray(" → ctf4ai-12 (red-team software AI)")),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("EAxxxxxxxx")+chalk.gray(" → ctf4eai-12 (red-team embodied AI)")),console.log(" "+chalk.bold.cyan("exam ")+chalk.white("<CC>xxxxxxxx")+chalk.gray(" → Paper A/B/C/D/E (country exam token)")),console.log(" "+chalk.bold.cyan("demo")+chalk.gray(" → free practice")),console.log(" "+chalk.bold.cyan("lang")+chalk.white(" es")+chalk.gray(" → switch language")),console.log(" "+chalk.gray("help · menu · quit")),console.log()}export async function startRepl(e,F){process.env.ICOA_INSIDE_REPL="1";let po=!1;if(K()){const o=t().joinedAt,e=o=>new Intl.DateTimeFormat("en-CA",{timeZone:"Australia/Sydney",year:"numeric",month:"2-digit",day:"2-digit"}).format(o);o&&e(new Date(o))===e(new Date)||(a({ctfdUrl:"",token:"",sessionCookie:"",userId:null,userName:"",teamId:null,country:"",joinedAt:""}),po=!0)}const Co=t(),Io=n(),ko=process.exit.bind(process),To=i();if(Co.language&&"en"!==Co.language&&(await s(Co.language,{silent:!0}),r(Co.language)),Co.demoCleanedForVersion!==bo){try{const{existsSync:o,unlinkSync:e}=await import("node:fs"),{join:l}=await import("node:path"),{getIcoaDir:n}=await import("./lib/config.js"),t=l(n(),"demo-state.json");o(t)&&e(t)}catch{}a({demoCleanedForVersion:bo})}const{select:Eo,confirm:So}=await import("@inquirer/prompts"),$o=Co.mode||"",Oo=""===$o?"instant":["instant","learn","selection","olympiad"].includes($o)?$o:"selection",jo=[{name:` ${chalk.bold("⚡ Try ICOA in 30 seconds")} ${chalk.gray("—")} ${chalk.gray("watch · no token needed")}`,value:"instant"},{name:` ${chalk.bold("🧠 Learn")} ${chalk.gray("—")} ${chalk.gray("AC / CA / EA token · skill up")}`,value:"learn"},{name:` ${chalk.bold("🎯 National Selection")} ${chalk.gray("—")} ${chalk.gray("country exam token · aim for finals")}`,value:"selection"},{name:` ${chalk.bold("🏆 International Olympiad")} ${chalk.gray("—")} ${chalk.gray("finals stage · Sydney 2026 · full sandbox")}`,value:"olympiad"},{name:` ${chalk.gray("ℹ️ About ICOA")} ${chalk.gray("·")} ${chalk.gray("what this is · how to join")}`,value:"about"}];console.log(chalk.gray(" Type ")+chalk.bold.cyan("menu")+chalk.gray(" from anywhere to return here.")),console.log();let Do="";for(;!Do;){let o;try{o=await Eo({message:"Mode",choices:jo,default:Oo||"instant"})}catch(o){throw o instanceof Error&&"ExitPromptError"===o.name&&(console.log(),console.log(chalk.gray(" Goodbye.")),process.exit(0)),o}"about"!==o?Do=o:(console.clear(),console.log(),console.log(chalk.cyan(" ═══════════════════════════════════════════════════")),console.log(chalk.bold.yellow(" ICOA")+chalk.white(" — AI-Native CLI OS for Cyber & AI Security")),console.log(chalk.gray(" Olympiad & Competition · K-12 to University")),console.log(chalk.cyan(" ───────────────────────────────────────────────────")),console.log(),console.log(chalk.bold.white(" What Makes ICOA Different")),console.log(chalk.gray(" · AI-native AI teammate, AI adversary, AI translation")),console.log(chalk.gray(" · CLI OS Complete competition environment in terminal")),console.log(chalk.gray(" · 110 tools pwntools, z3, gdb, nmap, sleuthkit... pre-configured")),console.log(chalk.gray(" · Global scale 15,000+ concurrent exams · 15 languages")),console.log(),console.log(chalk.bold.white(" Competition Format (2-day standard + 1-day Pioneer)")),console.log(` ${chalk.green.bold("AI4CTF")}${chalk.gray(" [Day 1] AI as teammate — speed track, dynamic decay + top-3 bonus")}`),console.log(` ${chalk.red.bold("CTF4AI")}${chalk.gray(" [Day 2] AI as target — knowledge track, static value per challenge")}`),console.log(` ${chalk.cyan.bold("CTF4EAI")}${chalk.gray(" [Pioneer / Practical Round] Embodied AI — VLA + world models + sim-to-real")}`),console.log(),console.log(chalk.bold.white(" Scoring (in brief)")),console.log(chalk.gray(" · Standard medals: AI4CTF + CTF4AI combined · 1/12 Gold · 2/12 Silver · 3/12 Bronze")),console.log(chalk.gray(" · HMA: top 50% on either day, total below bronze cutoff")),console.log(chalk.gray(" · CTF4EAI: separate 15-finalist pool, G/S/B + 12 Finalist Awards")),console.log(),console.log(chalk.white(" Sydney, Australia")+chalk.gray(" · Jun 27 - Jul 2, 2026")),console.log(),console.log(chalk.bold.white(" Organized by")+chalk.gray(" ASRA (Australia) · ICO Foundation Inc")),console.log(chalk.bold.white(" Contact ")+chalk.cyan(" australia@icoa2026.au · accreditation@icoa2026.au")),console.log(chalk.bold.white(" Website ")+chalk.cyan.underline(" https://icoa2026.au")),console.log(chalk.cyan(" ═══════════════════════════════════════════════════")),console.log(),console.log(chalk.gray(" Press ")+chalk.yellow("Enter")+chalk.gray(" to return...")),await new Promise(o=>{const e=l=>{process.stdin.removeListener("data",e),process.stdin.isTTY&&process.stdin.setRawMode&&process.stdin.setRawMode(!1),process.stdin.pause(),o()};process.stdin.isTTY&&process.stdin.setRawMode&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.once("data",e)}),console.clear())}if("olympiad"===Do&&"olympiad"!==Oo){console.log(),console.log(chalk.yellow(" This mode will download ~500MB of CTF tools and AI models."));let o=!0;try{o=await So({message:"Continue?",default:!0})}catch(e){if(!(e instanceof Error&&"ExitPromptError"===e.name))throw e;o=!1}o||(Do="selection",console.log(chalk.gray(" Switched to National Selection mode.")))}if(Do!==Oo&&a({mode:Do}),console.log(),"olympiad"===Do&&p(bo)){u(bo),console.log(chalk.gray(" Checking competition environment..."));const{execSync:o}=await import("node:child_process"),e=[{name:"pwntools",cmd:'python3 -c "import pwn"'},{name:"z3-solver",cmd:'python3 -c "import z3"'},{name:"numpy",cmd:'python3 -c "import numpy"'},{name:"requests",cmd:'python3 -c "import requests"'}];let l=0;for(const n of e)try{o(n.cmd,{stdio:"ignore"})}catch{l++}l>0?(console.log(chalk.yellow(` ${l} core competition libraries missing.`)),console.log(chalk.gray(" Run ")+chalk.white("env setup")+chalk.gray(" when you are ready to install them.")),console.log()):(console.log(chalk.green(" All core libraries ready.")),console.log())}if(F){const o=d();if(o){const e=Math.floor(o.awaySeconds/60),l=o.awaySeconds%60;console.log(chalk.yellow(` Session resumed. Away: ${e}m ${l}s | Total exits: ${o.exitCount}`)),console.log()}}if("selection"===Do)console.log(chalk.gray(" ─── exam hall · 90 min per paper once started · no pause ───")),console.log(),xo();else if("embodied"===Do)!function(){console.log(chalk.cyan.bold(" [🤖 ctf4eai — Embodied AI Security]")),console.log(),console.log(chalk.bold.cyan(" CTF4EAI")+chalk.gray(" — ICOA 2026's ")+chalk.bold.white("Pioneer Round")),console.log(chalk.gray(" an independent parallel track alongside the scored main events: ")+chalk.green("AI4CTF")+chalk.gray(" (Day 1) and ")+chalk.red("CTF4AI")+chalk.gray(" (Day 2)")),console.log(),console.log(chalk.white(" Embodied AI is at its ImageNet moment.")),console.log(chalk.gray(" VLA models, MuJoCo physics, real robot arms.")),console.log(chalk.gray(" Real models, real physics, real attack surfaces.")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────"));const o=L()>0||N()>0,e=D()>0,l=j(),n=O(),t=null!==n&&"number"==typeof n.completedAt&&n.nextCardIndex>=n.totalCards,a=null!==n&&!t;if(t)console.log(chalk.bold.yellow(" Continue: ")+chalk.bold.cyan("④ learn LEARNDEMO01")+chalk.gray(" (demo2 ✓ · sim")+(e?chalk.gray(" ✓ · sim arm ✓)"):chalk.gray(")")));else if(a){const o=`${n.nextCardIndex} / ${n.totalCards}`;console.log(chalk.bold.yellow(" Continue: ")+chalk.bold.cyan("③ demo2")+chalk.gray(" (last left at card ")+chalk.bold.yellow(o)+chalk.gray(")"))}else o&&e?console.log(chalk.bold.yellow(" Next up: ")+chalk.bold.cyan("③ demo2")+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01")+chalk.gray(" (sim ✓ · sim arm ✓)")):l?console.log(chalk.bold.yellow(" Next up: ")+(e?chalk.bold.cyan("① sim")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2"):chalk.bold.cyan("② sim arm")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2"))+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01")):console.log(chalk.bold.yellow(" First time? Try in order: ")+chalk.bold.cyan("① sim")+chalk.gray(" → ")+chalk.bold.cyan("② sim arm")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2")+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01"));console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.bold.green(" sim")+chalk.gray(" ")+chalk.bold.cyan("①")+chalk.gray(" ")+chalk.bold.yellow("★ INSTANT")+chalk.gray(" — 9-robot group dance, no wait, no setup")),console.log(chalk.bold.green(" sim arm")+chalk.gray(" ")+chalk.bold.cyan("②")+chalk.gray(" interactive 6-DOF arm sandbox — type joint values, watch")),console.log(chalk.bold.green(" demo2")+chalk.gray(" ")+chalk.bold.cyan("③")+chalk.gray(" ~8 min interactive intro + live MuJoCo sim")),console.log(chalk.bold.green(" learn LEARNDEMO01")+chalk.gray(" ")+chalk.bold.cyan("④")+chalk.gray(" free 11-card intro (paste this command as-is)")),console.log(chalk.bold.green(" learn ")+chalk.bold.yellow("EA")+chalk.gray(" + 8 chars full 96 / 360 curriculum (team-issued)")),console.log(chalk.bold.green(" exam ")+chalk.bold.yellow("PDxxxxxxxx")+chalk.gray(" Paper D (CTF4EAI) — national selection contestants")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(),console.log(chalk.gray(" Three open tiers: ")+chalk.green("free 11")+chalk.gray(" · ")+chalk.yellow("registered 100")+chalk.gray(" · ")+chalk.bold.magenta("national team 480")+chalk.gray(" (PhD-ready)")),console.log(chalk.gray(" Country team contact: ")+chalk.cyan("australia@icoa2026.au")),console.log(),f(),console.log()}();else if("instant"===Do)console.log(chalk.cyan.bold(" [⚡ Try ICOA in 30 seconds — no token needed]")),console.log(),console.log(chalk.gray(" Two free tastes — just type the word and press Enter:")),console.log(),console.log(chalk.bold.green(" demo ")+chalk.gray(" Paper A/B/C taste — 10 MCQs, no timer ")+chalk.bold.cyan("🎯 selection-style")),console.log(chalk.bold.green(" demo2")+chalk.gray(" Embodied-AI mini-demo — robots & MuJoCo ")+chalk.bold.yellow("🤖 hands-on")),console.log(),console.log(chalk.gray(" Type ")+chalk.bold.cyan("demo")+chalk.gray(" or ")+chalk.bold.cyan("demo2")+chalk.gray(" to start · ")+chalk.bold.cyan("menu")+chalk.gray(" to go back · ")+chalk.bold.cyan("quit")+chalk.gray(" to exit")),console.log(),a({mode:"selection"}),Do="selection";else{if("learn"===Do){console.log(chalk.cyan.bold(" [🧠 Learn]")),console.log(),console.log(chalk.gray(" Three tracks · same difficulty curve.")),console.log(),console.log(chalk.white(" Free 12-card demos — paste the full command:")),console.log(),console.log(chalk.gray(" 🤝 ai4ctf AI as your teammate ")+chalk.bold.yellow("learn AI4CTFDEMO01")),console.log(chalk.gray(" 🔓 ctf4ai AI as your target ")+chalk.bold.yellow("learn CTF4AIDEMO01")),console.log(chalk.gray(" 🤖 ctf4eai Embodied AI Security ")+chalk.bold.yellow("learn LEARNDEMO01")),console.log(),console.log(chalk.gray(" Got a cohort token? Type ")+chalk.bold.yellow("learn <TOKEN>")+chalk.gray(" (e.g. ")+chalk.bold.yellow("learn EAABCD1234")+chalk.gray(").")),console.log();try{const{input:o}=await import("@inquirer/prompts"),{resolveLearnInput:l}=await import("./lib/learn-input.js");console.log(chalk.gray(" Enter a token (or just press Enter to go back).")),console.log();const n=l(await o({message:chalk.bold.cyan("icoa learn>"),theme:{prefix:"",style:{message:o=>o}}}));if("token"===n.kind){console.log(),console.log(chalk.gray(" Opening ")+chalk.bold.cyan("learn")+chalk.gray(`: ${n.token}`)),console.log(),a({mode:"selection"}),process.env.ICOA_LEARN_EMBEDDED="1";try{await e.parseAsync(["node","icoa","learn",n.token])}finally{delete process.env.ICOA_LEARN_EMBEDDED}}else"ambiguous"!==n.kind&&"unknown"!==n.kind||(console.log(),console.log(chalk.yellow(" "+n.hint)),console.log(chalk.gray(" Returning to main menu — pick 🧠 Learn again to retry.")),console.log())}catch{}return a({mode:"selection"}),void w()}"organizer"===Do?(console.log(chalk.yellow.bold(" [National/Regional Partner]")),console.log(),console.log(chalk.bold.white(" ██╗ ██████╗ ██████╗ █████╗")),console.log(chalk.bold.white(" ██║██╔════╝██╔═══██╗██╔══██╗")),console.log(chalk.bold.white(" ██║██║ ██║ ██║███████║")),console.log(chalk.bold.white(" ██║██║ ██║ ██║██╔══██║")),console.log(chalk.bold.white(" ██║╚██████╗╚██████╔╝██║ ██║")),console.log(chalk.bold.white(" ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝")),console.log(),console.log(chalk.yellow(" International Cyber Olympiad in AI 2026")),console.log(chalk.bold.magenta(" The World's First AI-Native CLI Operating System")),console.log(chalk.bold.magenta(" for Cybersecurity & AI Security Competition")),console.log(chalk.bold.magenta(" and Olympiad for K-12")),console.log(chalk.gray(" Sydney, Australia · Jun 27 - Jul 2, 2026")),console.log(),console.log(chalk.white(" Vision")),console.log(chalk.gray(" Building a global pipeline for youth cyber & AI")),console.log(chalk.gray(" security talent through education and competition.")),console.log(),console.log(chalk.white(" Capacity")),console.log(chalk.gray(" 15,000+ concurrent online examinations")),console.log(chalk.gray(" National selection, training, and education support")),console.log(),console.log(chalk.white(" Olympic Spirit")),console.log(chalk.gray(" Excellence · Friendship · Respect")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" New country accreditation & support:")),console.log(chalk.cyan(" australia@icoa2026.au")),console.log(chalk.cyan(" accreditation@icoa2026.au")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(),Io?(console.log(chalk.green(` Logged in as ${Co.userName}`)),console.log(chalk.white(" exam list")+chalk.gray(" Manage exams")),console.log(chalk.white(" logout")+chalk.gray(" Disconnect"))):console.log(chalk.white(" join <url>")+chalk.gray(" Connect to manage exams")),console.log(),f(),console.log()):(console.log(` ${chalk.cyan.bold("🏆 ICOA 2026 · International Olympiad")}`),console.log(),To&&!y()?(console.log(chalk.red(" Token was activated on a different device.")),console.log(chalk.gray(" Contact organizer for assistance.")),console.log()):Io?(console.log(chalk.green.bold(` Welcome back, ${Co.userName}!`)),console.log(chalk.gray(` Connected to ${Co.ctfdUrl}`)),console.log(chalk.gray(" Not you? Type ")+chalk.cyan("logout")+chalk.gray(" to switch accounts")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" Ready to compete? Start here:")),console.log(),console.log(chalk.bold.cyan(" challenges")+chalk.gray(" Browse challenges by category")),console.log(chalk.white(" status")+chalk.gray(" Your score & timer")),console.log(chalk.white(" scoreboard")+chalk.gray(" Live rankings")),console.log(chalk.white(" memo")+chalk.gray(" Report an issue to organizers (one-way)")),console.log(),console.log(chalk.gray(" Tool environment:")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.bold.yellow(" ★ ")+chalk.bold.cyan("man <tool>")+chalk.gray(" How to USE a tool (steghide, nmap…) · ")+chalk.cyan("man tools")+chalk.gray(" = list")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("help")+chalk.gray(" · ")+b()+chalk.gray(" · ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+chalk.cyan("quit")+chalk.gray(" closes")),console.log()):To?(so(ho)||ro(ho,{recursive:!0}),console.log(chalk.green.bold(" Welcome, competitor!")),console.log(chalk.gray(` Workspace: ${ho}`)),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" Get started:")),console.log(),console.log(chalk.white(" Step 1 ")+chalk.bold.cyan("join <url>")+chalk.gray(" Connect to competition server")),console.log(chalk.white(" Step 2 ")+chalk.bold.cyan("challenges")+chalk.gray(" Browse & solve challenges")),console.log(chalk.white(" Step 3 ")+chalk.bold.cyan("ai4ctf")+chalk.gray(" Ask AI when stuck")),console.log(),console.log(chalk.gray(" Before Step 1 — make sure your tools are ready:")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.bold.yellow(" ★ ")+chalk.bold.cyan("man <tool>")+chalk.gray(" How to USE a tool (steghide, nmap…) · ")+chalk.cyan("man tools")+chalk.gray(" = list")),console.log(),console.log(chalk.gray(" Also: ")+chalk.white("help")+chalk.gray(" all commands")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+b()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()):(console.log(chalk.bold.yellow(" 🏆 You reached the finals tier.")),console.log(chalk.gray(" Full sandbox · 110 CTF tools · Sydney 2026 · this is where finalists compete.")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" To begin, activate your competition token:")),console.log(),console.log(chalk.bold.cyan(" activate <token>")),console.log(),console.log(chalk.gray(" While waiting, explore:")),console.log(chalk.white(" ref linux")+chalk.gray(" Quick reference for Linux")),console.log(chalk.white(" ref web")+chalk.gray(" Quick reference for Web")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.white(" help")+chalk.gray(" All available commands")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+b()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()))}e.exitOverride(),e.configureOutput({writeErr:()=>{},writeOut:o=>{console.log(o)}});const Lo=o({input:process.stdin,output:process.stdout,prompt:uo(),terminal:!0});x(Lo);let No=!1;if(h(!0),Y(),po&&(console.log(),console.log(chalk.yellow(" ⏱ A new competition day has started (Sydney time).")),console.log(chalk.gray(" For fairness, yesterday’s sign-in has been cleared. Type ")+chalk.cyan("join <url>")+chalk.gray(" to sign in with your account.")),console.log()),K()){const o=t().userName||"this account";console.log(),console.log(chalk.yellow(" ⚠ This machine is signed in as ")+chalk.bold.white(o)+chalk.yellow(".")),console.log(chalk.gray(" Press ")+chalk.cyan("Enter")+chalk.gray(` to continue as ${o}, or type `)+chalk.cyan("logout")+chalk.gray(" to switch accounts.")),"logout"===(await new Promise(o=>{Lo.question(chalk.white(" > "),e=>o(e.trim()))})).toLowerCase()&&(a({ctfdUrl:"",token:"",sessionCookie:"",userId:null,userName:"",teamId:null,country:""}),console.log(),console.log(chalk.green(" ✓ Logged out. ")+chalk.gray("Run ")+chalk.cyan("join <url>")+chalk.gray(" to sign in with your own account."))),console.log()}Z()&&V(()=>Lo.prompt());const Ro=Lo.prompt.bind(Lo);Lo.prompt=o=>{A()||k()||E()||$()||no()||Lo.setPrompt(uo()),Ro(o)},Lo.prompt(),Lo.on("line",async o=>{if(No)return;const n=o.trim();if(!n)return Lo.setPrompt(A()?chalk.magenta("icoa ai4ctf> "):uo()),void Lo.prompt();if("menu"===n||"menu confirm"===n)return P()&&"menu confirm"!==n?(console.log(),console.log(chalk.yellow(" Real exam active. Progress is auto-saved.")),console.log(chalk.gray(" To return to main menu anyway, type ")+chalk.white("menu confirm")),console.log(),void Lo.prompt()):void w(Lo);if(A()){No=!0;const o=await C(n);return No=!1,"exit"===o&&Lo.setPrompt(uo()),void Lo.prompt()}if(k()){No=!0;const o=await T(n);return No=!1,"exit"!==o&&"solved"!==o||Lo.setPrompt(uo()),void Lo.prompt()}if(E()){No=!0;const o=await S(n);return No=!1,"exit"===o&&Lo.setPrompt(uo()),Lo.setPrompt(E()?chalk.bold.cyan("icoa ctf4eai> "):uo()),void Lo.prompt()}if(X(n),"exit"===n)return R()?(console.log(),console.log(chalk.yellow(" ⚠ An exam is in progress.")),console.log(chalk.white(" To return to menu without losing progress, type: ")+chalk.bold.cyan("back")),console.log(chalk.white(" To fully close ICOA CLI, type: ")+chalk.bold.cyan("quit")),console.log(chalk.gray(" Your progress is auto-saved either way.")),console.log(),void Lo.prompt()):(console.log(),console.log(chalk.gray(" ")+chalk.white("exit")+chalk.gray(" returns to the main menu. To fully close ICOA CLI, type ")+chalk.bold.cyan("quit")+chalk.gray(".")),"selection"===Do&&xo(),void Lo.prompt());if("quit"===n||"q"===n||"quit confirm"===n){const o=R();return o&&"demo-free"!==o.session.examId&&"quit confirm"!==n?(console.log(),console.log(chalk.yellow(" ⚠ A real exam is in progress.")),console.log(chalk.gray(" Your answers are auto-saved on the server, but the exam timer keeps ticking")),console.log(chalk.gray(" on the server side even if you close the CLI.")),console.log(),console.log(chalk.white(" To leave the CLI but keep the exam alive, type: ")+chalk.bold.cyan("back")),console.log(chalk.gray(" (recommended — you can resume with ")+chalk.cyan("exam q 1")+chalk.gray(" after relaunching icoa)")),console.log(),console.log(chalk.white(" To really close ICOA CLI, type: ")+chalk.bold.cyan("quit confirm")),console.log(),void Lo.prompt()):(o&&"demo-free"===o.session.examId&&(console.log(),console.log(chalk.gray(" Demo paused. Resume with: ")+chalk.white("demo")+chalk.gray(" (fresh) or ")+chalk.white("exam q 1")+chalk.gray(" (continue)."))),J(),G(),m(),console.log(chalk.gray(" Session saved. Use ")+chalk.white("icoa --resume")+chalk.gray(" to continue.")),M(),void ko(0))}if("back"===n){const o=R(),e=o&&"demo-free"!==o.session.examId,l=o&&"demo-free"===o.session.examId&&(()=>{const e=new Date(o.session.startedAt||0).getTime();return Date.now()-e<18e5})();if(e)console.log(),console.log(chalk.gray(" Exam paused. Your progress is saved.")),console.log(chalk.white(" Resume: exam q 1")+chalk.gray(" · ")+chalk.white("exam review")+chalk.gray(" · ")+chalk.white("exam submit")),console.log();else if(l){const e=Object.keys(o.answers).length,l=o.session.questionCount;console.log(),console.log(chalk.gray(` Demo paused (${e}/${l} answered). Resume with: `)+chalk.white("exam q 1")),console.log(chalk.gray(" Or type ")+chalk.white("demo")+chalk.gray(" to restart.")),console.log()}else{if(o&&"demo-free"===o.session.examId){const{clearExamState:o}=await import("./lib/exam-state.js");o("demo-free")}const e=t();fetch("https://practice.icoa2026.au/api/icoa/demo-stats",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:"post-report-back",lang:e.language||"en",timestamp:(new Date).toISOString()}),signal:AbortSignal.timeout(5e3)}).catch(()=>{}),"selection"===Do?xo():console.log(chalk.gray(" Already at main menu."))}return void Lo.prompt()}if("help"===n||"?"===n){if(R()){No=!0;try{await e.parseAsync(["node","icoa","exam","help"])}catch{}return No=!1,void Lo.prompt()}return Ao(i(),Do),void Lo.prompt()}if("man"===n||"manual"===n)return Ao(i(),Do),console.log(),console.log(chalk.bold.yellow(" ★ Stuck on a tool? ")+chalk.bold.cyan("man <tool>")+chalk.gray(" e.g. ")+chalk.cyan("man steghide")+chalk.gray(" · ")+chalk.cyan("man tools")+chalk.gray(" = full list")),void Lo.prompt();if(/^(?:man|manual)\s+\S/i.test(n))return I(n.replace(/^(?:man|manual)\s+/i,"")),void Lo.prompt();if("more help"===n.toLowerCase()&&R()){No=!0;try{await e.parseAsync(["node","icoa","exam","more-help"])}catch{}return No=!1,void Lo.prompt()}if("continue"===n.toLowerCase())return console.log(),console.log(chalk.green.bold(" ═══ AI4CTF — AI as Your Teammate ═══")),console.log(),console.log(chalk.white(" In AI4CTF, you solve cybersecurity challenges")),console.log(chalk.white(" with AI by your side.")),console.log(),console.log(chalk.white(" In this demo, your AI teammate gives help at 3 levels:")),console.log(chalk.yellow(" hint a")+chalk.gray(" General guidance")),console.log(chalk.yellow(" hint b")+chalk.gray(" Deep analysis")),console.log(chalk.yellow(" hint c")+chalk.gray(" Critical assist")),console.log(),console.log(chalk.white(" Try it now! Type: ")+chalk.bold.green("ai4ctf")),console.log(chalk.gray(' Chat freely with your AI teammate. Type "exit" when done.')),console.log(),console.log(chalk.gray(" After ai4ctf, try: ")+chalk.bold.red("ctf4ai")+chalk.gray(' — trick the AI into saying "koala"')),console.log(),void Lo.prompt();if(/^ICOA-[A-Z]{2,3}-\d{1,6}$/i.test(n.trim())){No=!0;try{await e.parseAsync(["node","icoa","exam","token",n.trim()])}catch{}return No=!1,void Lo.prompt()}if(/^[A-Z]{2}[0-9A-HJKMNP-TV-Z]{8}$/i.test(n.trim())){No=!0;try{await e.parseAsync(["node","icoa","exam","token",n.trim().toUpperCase()])}catch{}return No=!1,void Lo.prompt()}const a=n.match(/^exam\s+([A-Z]{2}[0-9A-HJKMNP-TV-Z]{8})$/i);if(a){No=!0;try{await e.parseAsync(["node","icoa","exam","token",a[1].toUpperCase()])}catch{}return No=!1,void Lo.prompt()}const s=n.match(/^exam\s+([A-Z]{2,3})$/i);if(s){No=!0;try{await e.parseAsync(["node","icoa","exam","list",s[1]])}catch{}return No=!1,void Lo.prompt()}if("clear"===n||"cls"===n)return console.clear(),void Lo.prompt();if("news"===n)return Z()?H():console.log(chalk.gray(" No competition joined. Use ")+chalk.white("join <url>")+chalk.gray(".")),void Lo.prompt();if("memo"===n){if(!Z())return console.log(chalk.gray(" Join a competition first: ")+chalk.white("join <url>")),void Lo.prompt();No=!0;try{await to()}catch{}return void(No=!1)}const r=eo()||oo(t().userName||"");if("jury"===n&&r){No=!0;try{await ao()}catch{}return void(No=!1)}if(r&&eo()&&"scoreboard"===n.split(/\s+/)[0]){No=!0;try{const o=await lo();if(console.log(),0===o.length)console.log(chalk.gray(" Scoreboard is empty."));else{console.log(chalk.bold.white(" Scoreboard"));for(const e of o.slice(0,50))console.log(chalk.gray(` ${String(e.pos).padStart(3)}. `)+chalk.white(e.name.padEnd(28).slice(0,28))+chalk.cyan(String(e.score)))}console.log()}catch{}return No=!1,void Lo.prompt()}if(r&&K()){const o=n.split(/\s+/)[0];if(["challenges","open","submit","hint"].includes(o))return console.log(),console.log(chalk.yellow(" Team-leader account — the challenge bracket is not available here.")),console.log(chalk.gray(" Available: ")+chalk.white("scoreboard")+chalk.gray(" · ")+chalk.white("news")+chalk.gray(" · ")+chalk.white("jury")+chalk.gray(" · ")+chalk.white("time")+chalk.gray(" · ")+chalk.white("status")+chalk.gray(" · ")+chalk.white("logout")),console.log(),void Lo.prompt()}if(n.startsWith("activate ")){const o=n.slice(9).trim(),e=c(o);return"ok"===e?console.log(chalk.green(" Access granted! Token bound to this device.")):"already_bound"===e?(console.log(),console.log(chalk.red(" Token already activated on a different device.")),console.log(chalk.gray(" Each token binds to the first device that uses it. If you lost the device,")),console.log(chalk.gray(" contact your proctor to have the token re-issued for a new device."))):(console.log(),console.log(chalk.red(" Token not recognized.")),console.log(chalk.gray(" Possible reasons:")),console.log(chalk.white(" • ")+chalk.gray("Typo — access tokens are case-insensitive and look like ")+chalk.cyan("ICOA-XXXX-XXXX-XXXX")+chalk.gray(" (4-char hex groups, e.g. ICOA-385E-27F2-B21B)")),console.log(chalk.white(" • ")+chalk.gray("Expired — ask your proctor or organizer for a fresh token")),console.log(chalk.white(" • ")+chalk.gray("Network — verify connection to ")+chalk.cyan("practice.icoa2026.au")),console.log(chalk.gray(" Still stuck? type ")+chalk.cyan("help")+chalk.gray(" or try ")+chalk.cyan("exam demo")+chalk.gray(" for a free practice round."))),console.log(),void Lo.prompt()}if("activate"===n)return console.log(chalk.gray(" Usage: ")+chalk.white("activate <token>")),console.log(),void Lo.prompt();const d=R();if(d){const o=n.toUpperCase().trim(),l=o=>{const e=d.questions.find(e=>e.number===o);return!!e&&("ai4ctf"===e.type||"ctf4ai"===e.type||e.options&&!e.options.A&&!e.options.B)},t=o=>{const e=d.questions.find(e=>e.number===o);return"short_answer"===e?.type},a=o=>{const e="demo-free"!==d.session.examId,l=d.questions.find(e=>e.number===o),n=q(l?.type,e);console.log(),console.log(chalk.yellow(` Q${o} is a practical question — letters (A/B/C/D) don't apply here.`)),n?(console.log(chalk.white(" Enter the AI chat for this question: ")+chalk.bold.cyan(n)),console.log(chalk.gray(" Or submit a flag directly: ")+chalk.green(`exam answer ${o} ICOA{your_flag}`))):console.log(chalk.gray(" Submit a flag: ")+chalk.green(`exam answer ${o} ICOA{your_flag}`)),console.log()};if(/^[ABCDE]$/.test(o)){const n=d._lastQ||1;if(l(n))return a(n),void Lo.prompt();if(t(n))return console.log(),console.log(chalk.yellow(` Q${n} is a short-answer question — type a number, not a letter.`)),console.log(chalk.gray(" Example: ")+chalk.green("42")+chalk.gray(" (or ")+chalk.green(`exam answer ${n} 42`)+chalk.gray(")")),console.log(),void Lo.prompt();No=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(n),o])}catch{}return No=!1,void Lo.prompt()}if(/^-?\d+$/.test(o)){const l=d._lastQ||1;if(t(l)){No=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(l),o])}catch{}return No=!1,void Lo.prompt()}}const s=o.match(/^(\d+)\s+([ABCDE]|-?\d+)$/);if(s){const o=parseInt(s[1],10);if(l(o))return a(o),void Lo.prompt();No=!0;try{await e.parseAsync(["node","icoa","exam","answer",s[1],s[2]])}catch{}return No=!1,void Lo.prompt()}}const p=n.split(/\s+/)[0].toLowerCase(),u=/^python3?(\.\d+)?$/.test(p),h="ls"===p||"pwd"===p,f=n.startsWith("!")||p.startsWith("!")||u||h,b=new Set(["nano","vi","vim","emacs","pico","ed","code","cat","less","more","head","tail","ls","pwd","cd","base64","xxd","hexdump","od","openssl","md5sum","sha256sum","grep","find","awk","sed","strings","file","curl","wget","nc","ping","nmap","echo","bash","sh","zsh","pip","pip3","node","npm"]),x=()=>{console.log(chalk.gray(" Shell commands need ")+chalk.bold.cyan("!")+chalk.gray(" prefix. Try: ")+chalk.bold.cyan(`!${n}`)),console.log()};if("embodied"===Do&&!f&&!["demo2","learn","exam","ctf4eai","ctf4vla","eai","arena","lang","ref","setup","env","aienv","ipynb","sim"].includes(p))return b.has(p)?(x(),void Lo.prompt()):(console.log(chalk.gray(" Not available in Embodied AI Security mode.")),console.log(chalk.white(" Try ")+chalk.bold.cyan("demo2")+chalk.gray(" (intro) · ")+chalk.bold.cyan("learn")+chalk.gray(" (curriculum) · ")+chalk.bold.cyan("exam <PD-token>")+chalk.gray(" (Paper D)")),console.log(),void Lo.prompt());if("selection"===Do&&!f&&!["exam","demo","demo2","retry","nations","next","prev","continue","setup","lang","ref","ai4ctf","ctf4ai","mark","unmark","review","submit","env","aienv","ipynb","sim"].includes(p)){if(b.has(p))return x(),void Lo.prompt();if(console.log(chalk.gray(" Not available in Selection mode.")),d){const o=d._lastQ||1;console.log(chalk.white(` Resume exam: exam q ${o}`)+chalk.gray(" · ")+chalk.white("A/B/C/D")+chalk.gray(" to answer"))}else console.log(chalk.gray(" Try: demo · setup to switch mode"));return console.log(),void Lo.prompt()}if("organizer"===Do&&!["join","exam","demo","retry","next","prev","logout","setup","lang","ref","ctf","mark","unmark","review","submit"].includes(p))return console.log(chalk.gray(" Not available in Organizer mode. Switch via: setup")),console.log(),void Lo.prompt();if(!("olympiad"!==Do||i()&&y()||g(p)))return console.log(chalk.yellow(" Restricted mode. ")+chalk.gray("Enter your access token:")),console.log(chalk.white(" activate <token>")),console.log(),console.log(chalk.gray(" Free commands: ")+chalk.white("ref [topic]")+chalk.gray(", ")+chalk.white("help")+chalk.gray(", ")+chalk.white("exit")),console.log(),void Lo.prompt();if(!["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","ai4ctf","model","ctf","exam","demo","retry","nations","next","prev","continue","logout","ctf4ai","mark","unmark","review","submit","learn","demo2","ctf4eai","ctf4vla","theme","sim","arena","eai","learn-pull"].includes(p)){if(wo.has(p))return console.log(chalk.yellow(` "${p}" is a shell command — the ICOA prompt isn't a shell.`)),console.log(chalk.gray(" In real-exam mode, prefix with ! to run inside the sandbox: ")+chalk.cyan(`!${n}`)),console.log(),void Lo.prompt();if(/(?:^|\s)(?:\/(?!home\/|Users\/|tmp\/)|\.\.\/|~\/)/.test(n)&&!n.startsWith("cd ")){const o=/(?:^|\s)\/(?!home\/\w+\/icoa-workspace|Users\/\w+\/icoa-workspace|tmp\/)/.test(n),e=/\.\./.test(n);if(o||e)return console.log(chalk.red(" Blocked: access outside workspace is not allowed.")),console.log(chalk.gray(` Workspace: ${ho}`)),console.log(),void Lo.prompt()}let o=n.startsWith("!")?n.slice(1).trim():n;if("darwin"===process.platform){const e="/opt/homebrew/opt/python@3.12/bin/python3.12";o=o.replace(/^python3?\s/,`${e} `).replace(/^(python3|python)$/,e)}else if("win32"===process.platform){const e=(()=>{try{return l("py -3 --version",{stdio:["ignore","ignore","ignore"],timeout:1500}),"py -3"}catch{}return"python"})();o=o.replace(/^python3?(\.\d+)?\s/,`${e} `).replace(/^python3?(\.\d+)?$/,e)}else{const e=(()=>{try{return l("which python3.12",{stdio:"ignore"}),"python3.12"}catch{return"python3"}})();o=o.replace(/^python\s/,`${e} `).replace(/^python$/,e)}const e=W(),t=Q(n);z({cwd:e,input:n,riskFlags:t}),t.length>0&&P()&&(console.log(chalk.yellow(` ⚠ Action flagged: ${t.join(", ")} — logged.`)),console.log()),/^(\S*python3?(\.\d+)?)\s*$/.test(o)&&(o=`PYTHONSTARTUP="${function(){const o=go(yo(),".icoa");so(o)||ro(o,{recursive:!0});const e=go(o,"python-startup.py");let l="";if(so(e))try{l=io(e,"utf-8")}catch{}return l!==mo&&co(e,mo),e}()}" ${o}`,console.log(),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(chalk.bold.white(" Python ready — ICOA exam toolkit pre-loaded")),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(),console.log(chalk.white(" Already imported: ")+chalk.gray("base64, struct, hashlib, re, json, binascii")),console.log(chalk.white(" Also available: ")+chalk.gray("requests, bs4, numpy, PIL.Image, AES, pad/unpad, xor, p32/u32/p64/u64")),console.log(),console.log(chalk.yellow(" Quick examples:")),console.log(chalk.gray(' base64.b64decode("aGVsbG8=") ')+chalk.gray("# decode base64")),console.log(chalk.gray(' bytes.fromhex("48656c6c6f") ')+chalk.gray("# hex → bytes")),console.log(chalk.gray(' "ICOA{x}".encode() ')+chalk.gray("# str → bytes")),console.log(chalk.gray(" [chr(c) for c in [73,67,79,65]] ")+chalk.gray("# ASCII codes")),console.log(chalk.gray(' xor(bytes.fromhex("0a2b"), b"IC") ')+chalk.gray("# pwntools XOR")),console.log(),console.log(chalk.gray(" Exit: ")+chalk.white("exit()")+chalk.gray(" or Ctrl-D")),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log()),No=!0;try{_()&&await B()?await U(o,Lo):await vo(o,Lo,e)}catch{console.log(chalk.yellow(` Command failed: ${p}`))}return No=!1,console.log(),void Lo.prompt()}No=!0;const $=n.trim(),O=$.toLowerCase();let j,D=null,L="";if(d)if("submit"===O)D="final";else if(O.startsWith("submit ")){let o=$.slice(7).trim();/^submit\s+/i.test(o)&&(o=o.replace(/^submit\s+/i,"").trim()),o=o.replace(/^["'`]+|["'`]+$/g,"").trim(),o&&/^ICOA\{[^}]*\}?$/i.test(o)?(D="flag",L=o):o&&/^[ABCDE]$/i.test(o)&&(D="flag",L=o.toUpperCase())}else/^ICOA\{[^}]+\}$/i.test($)&&(D="flag",L=$);j="final"===D?["exam","submit"]:"flag"===D?["exam","answer",String(d?._lastQ||1),L]:function(o){const e=o.split(/\s+/),l=e[0].toLowerCase(),n=e.slice(1);if("aienv"===l&&["run","python","py"].includes((n[0]??"").toLowerCase()))return v(o);if(("submit"===l||"flag"===l)&&n.length>=2)return["ctf","submit",n[0],n.slice(1).join(" ").trim().replace(/^["'`]+|["'`]+$/g,"")];if("connect"===l&&n.length>=2){const e=v(o);return["connect",e[1]??n[0],e.slice(2).join(" ")]}const t={demo:["exam","demo"],retry:["exam","demo-retry"],nations:["exam","nations"],next:["exam","next"],prev:["exam","prev"],mark:["exam","mark",...n],unmark:["exam","unmark",...n],review:["exam","review"],logout:["ctf","logout"],join:["ctf","join",...n],activate:["ctf","activate",...n],challenges:["ctf","challenges"],ch:["ctf","challenges"],open:["ctf","open",...n],submit:["ctf","submit",...n],flag:["ctf","submit",...n],scoreboard:["ctf","scoreboard",...n],sb:["ctf","scoreboard",...n],status:["ctf","status"],time:["ctf","time"]};return t[l]?t[l]:["ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","ai4ctf","model","ctf","exam","ctf4ai"].includes(l)?[l,...n]:e}(n);const N="ctf"===j[0]&&"join"===j[1];N&&Lo.pause(),process.exit=()=>{throw new Error(fo)};try{await e.parseAsync(["node","icoa",...j])}catch(o){const e=o instanceof Error?o.message:String(o);if(e===fo);else if(e.includes("commander.unknownCommand")){const{distance:o}=await import("fastest-levenshtein"),e=["ctf","ref","shell","files","view","connect","challenge","note","notes","logbook","log","manual","lang","setup","env","aienv","ipynb","ai4ctf","exam","ctf4ai","theme","eai","clear","cls","quit","exit","back","menu","help","continue","activate","demo","challenges","status","scoreboard","join","logout"],l=p.split(/\s+/)[0]||p;let n={word:"",dist:1/0};for(const t of e){const e=o(l.toLowerCase(),t);e<n.dist&&(n={word:t,dist:e})}console.log(chalk.yellow(` Unknown command: ${p}.`)),n.dist>0&&n.dist<=2&&console.log(chalk.gray(" Did you mean: ")+chalk.bold.cyan(n.word)+chalk.gray("?")),console.log(chalk.gray(" Type ")+chalk.cyan("help")+chalk.gray(" for the full command list."))}else e.includes("commander.missingArgument")||"commander.missingArgument"===o?.code?"submit"===p||"flag"===p?(console.log(chalk.yellow(" Incomplete — usage: ")+chalk.cyan("submit <challenge#> <flag>")),console.log(chalk.gray(" Put the number AND the flag on one line, e.g. ")+chalk.cyan("submit 44 pecan{...}"))):(console.log(chalk.yellow(` Incomplete command: ${p}`)),console.log(chalk.gray(" Type ")+chalk.cyan("help")+chalk.gray(" for usage."))):e.includes("commander.")||(e.includes("fetch failed")||e.includes("ECONNREFUSED")||e.includes("ETIMEDOUT"))&&console.log(chalk.yellow(" Network error. Check your connection."))}finally{process.exit=ko,No=!1,N&&Lo.resume()}A()?Lo.setPrompt(chalk.magenta("icoa ai4ctf> ")):k()?Lo.setPrompt(chalk.red("icoa ctf4ai> ")):E()&&Lo.setPrompt(chalk.bold.cyan("icoa ctf4eai> ")),console.log(),Lo.prompt()}),Lo.on("SIGINT",()=>{if(console.log(),A()||k())console.log(chalk.yellow(" Ctrl+C did not close ICOA CLI — you are still in the AI chat.")),console.log(chalk.white(" Type ")+chalk.bold.cyan("exit")+chalk.white(" to leave the chat and return to the menu."));else if(R()){const o="demo-free"!==R().session.examId;console.log(chalk.yellow(" Ctrl+C did NOT close ICOA CLI.")),console.log(chalk.gray(` Your ${o?"exam":"demo"} is paused and every answer is auto-saved.`)),console.log(),console.log(chalk.white(" Resume: ")+chalk.cyan("exam q 1")+chalk.gray(" · Back to menu: ")+chalk.cyan("back")+chalk.gray(" · Close CLI: ")+chalk.cyan(o?"quit confirm":"quit"))}else console.log(chalk.yellow(" Ctrl+C did not close ICOA CLI — you are still at the ")+chalk.cyan("icoa>")+chalk.yellow(" prompt.")),console.log(chalk.gray(" Keep typing — ")+chalk.cyan("help")+chalk.gray(" lists commands. (Only ")+chalk.cyan("quit")+chalk.gray(" or Ctrl+D actually close the CLI.)"));console.log(),Lo.prompt()}),Lo.on("close",()=>{J(),G(),m(),M(),ko(0)})}function vo(o,l,n){return new Promise(t=>{const a=process.stdin,s=!!a.isTTY&&!!a.isRaw;if(l.pause(),a.isTTY&&"function"==typeof a.setRawMode)try{a.setRawMode(!1)}catch{}const r=e(o,{shell:!0,stdio:"inherit",cwd:n||process.cwd()}),i=()=>{if(a.isTTY&&"function"==typeof a.setRawMode&&s)try{a.setRawMode(!0)}catch{}l.resume(),t()};r.on("close",i),r.on("error",i)})}function Ao(o,e="olympiad"){return console.log(),"selection"===e||"organizer"===e?(console.log(chalk.bold.white(" Exam")),console.log(chalk.white(" join <url> ")+chalk.gray("Connect to exam server")),console.log(chalk.white(" exam list ")+chalk.gray("Available exams")),console.log(chalk.white(" exam start <id> ")+chalk.gray("Begin an exam")),console.log(chalk.white(" exam q [n] ")+chalk.gray("View questions")),console.log(chalk.white(" exam answer <n> <X> ")+chalk.gray("Answer question")),console.log(chalk.white(" exam review ")+chalk.gray("Review all answers")),console.log(chalk.white(" exam submit ")+chalk.gray("Submit for grading")),console.log(chalk.white(" exam result ")+chalk.gray("View your score")),console.log(),console.log(chalk.bold.white(" System")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference")),console.log(chalk.white(" setup ")+chalk.gray("Settings / switch mode")),console.log(chalk.white(" lang [code] ")+chalk.gray("Switch language")),console.log(chalk.white(" clear ")+chalk.gray("Clear screen")),console.log(chalk.white(" exit ")+chalk.gray("Quit")),void console.log()):o?(console.log(chalk.cyan(" ═══════════════════════════════════════════════")),console.log(chalk.bold.white(" How it works")),console.log(),console.log(chalk.gray(" 1. Browse ")+chalk.white("challenges")+chalk.gray(" and pick one")),console.log(chalk.gray(" 2. ")+chalk.white("open <id>")+chalk.gray(" to read the challenge")),console.log(chalk.gray(" 3. Use ")+chalk.white("ai4ctf")+chalk.gray(" to chat with AI when stuck")),console.log(chalk.gray(" 4. ")+chalk.white("submit <id> <flag>")+chalk.gray(" to score points")),console.log(chalk.gray(" 5. Check ")+chalk.white("scoreboard")+chalk.gray(" to track your rank")),console.log(chalk.cyan(" ═══════════════════════════════════════════════")),console.log(),console.log(chalk.bold.white(" Competition")),console.log(chalk.white(" join <url> ")+chalk.gray("Connect to CTFd")),console.log(chalk.white(" challenges (ch) ")+chalk.gray("List challenges by category")),console.log(chalk.white(" open <id> ")+chalk.gray("Read challenge + get next steps")),console.log(chalk.white(" submit <id> <flag> ")+chalk.gray("Submit a flag")),console.log(chalk.white(" scoreboard (sb) ")+chalk.gray("Live rankings")),console.log(chalk.white(" status ")+chalk.gray("Your score & timer")),console.log(chalk.white(" time ")+chalk.gray("Countdown timer")),console.log(),console.log(chalk.bold.white(" AI Teammate")),console.log(chalk.white(" ai4ctf ")+chalk.gray("Free-chat with your AI teammate")),console.log(),console.log(chalk.bold.white(" Tools")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference (linux, web, crypto...)")),console.log(chalk.white(" shell ")+chalk.gray("Interactive CTF shell (sandbox if present, else host)")),console.log(chalk.white(" files <id> ")+chalk.gray("Download challenge files")),console.log(chalk.white(" connect <id> ")+chalk.gray("Connect to remote target")),console.log(chalk.white(" note [text] ")+chalk.gray("Add a logbook entry (in-exam: tags current Q)")),console.log(chalk.white(" logbook [n] ")+chalk.gray("View your logbook (in-exam: filter by Q)")),console.log(chalk.white(" log ")+chalk.gray("Session history")),console.log(chalk.white(" man <tool> ")+chalk.bold.yellow("★ ")+chalk.gray("How to use a tool (steghide, nmap…); ")+chalk.cyan("man tools")+chalk.gray(" = list. Bare ")+chalk.cyan("man")+chalk.gray(" = this list.")),console.log(),console.log(chalk.bold.white(" System")),console.log(chalk.white(" setup ")+chalk.gray("Configure settings")),console.log(chalk.white(" lang [code] ")+chalk.gray("Switch language (15 supported)")),console.log(chalk.white(" logout ")+chalk.gray("Disconnect")),console.log(chalk.white(" clear ")+chalk.gray("Clear screen")),console.log(chalk.white(" exit ")+chalk.gray("Quit (session saved)")),void console.log()):(console.log(chalk.bold.yellow(" Restricted Mode — activate with a token to unlock all commands")),console.log(),console.log(chalk.white(" activate <token> ")+chalk.gray("Unlock full access")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference")),console.log(chalk.white(" exit ")+chalk.gray("Quit")),void console.log())}
1
+ import{createInterface as o}from"node:readline";import{spawn as e,execSync as t}from"node:child_process";import chalk from"chalk";import{isConnected as l,getConfig as n,saveConfig as a}from"./lib/config.js";import{ensureLangCache as s}from"./lib/translations-fetcher.js";import{loadUiPack as r}from"./lib/i18n.js";import{isActivated as i,activateToken as c,isFreeCommand as g,isDeviceMatch as y,recordExit as m,recordResume as d,isFirstRunOrUpgrade as p,markVersionSeen as u}from"./lib/access.js";import{setReplMode as h}from"./lib/ui.js";import{returnToMainMenu as w,printMenuHint as f,menuHintInline as b}from"./lib/menu-nav.js";import{setMainRl as x}from"./lib/main-rl.js";import{shellSplit as v}from"./lib/shell-split.js";import{isChatActive as A,handleChatMessage as C}from"./commands/ai4ctf.js";import{renderToolMan as I}from"./lib/tool-man.js";import{isCtf4aiActive as k,handleCtf4aiMessage as T}from"./commands/ctf4ai-demo.js";import{isCtf4VlaActive as E,handleCtf4VlaMessage as S}from"./commands/ctf4vla.js";import{isDemo2Active as $}from"./commands/demo2.js";import{loadDemo2Progress as O}from"./lib/demo2-progress.js";import{hasAnySimHistory as j,lastArmAt as D,lastBundledAt as L,lastSimAt as N}from"./lib/sim-cooldown.js";import{getExamState as P,getRealExamState as R,getDemoState as q,practicalChatCommand as F}from"./lib/exam-state.js";import{resetTerminalTheme as M}from"./lib/theme.js";import{ensureSandbox as B,runInSandbox as U,isDockerAvailable as _}from"./lib/sandbox.js";import{checkShellRisk as W,logShellAudit as Q,getActiveCwd as Y}from"./lib/exam-sandbox.js";import{logCommand as z}from"./lib/logger.js";import{startLogSync as X,stopLogSync as J}from"./lib/log-sync.js";import{startBroadcastPoll as V,stopBroadcastPoll as G,showBroadcast as H,isCompetitionJoined as Z,isMelCompetition as K,isLeaderAccount as oo,isLeaderSession as eo,fetchPublicScoreboard as to,isCommsActive as lo}from"./lib/comms.js";import{enterMemoScreen as no,enterJuryScreen as ao}from"./commands/comms.js";import{existsSync as so,mkdirSync as ro,readFileSync as io,writeFileSync as co}from"node:fs";import{join as go}from"node:path";import{homedir as yo}from"node:os";const mo="# ICOA exam interactive startup — auto-loaded by PYTHONSTARTUP\nimport base64, struct, hashlib, re, json, os, sys, binascii\ntry: import requests\nexcept ImportError: pass\ntry: from Crypto.Cipher import AES\nexcept ImportError: pass\ntry: from Crypto.Util.Padding import pad, unpad\nexcept ImportError: pass\ntry: from pwn import xor, p32, u32, p64, u64\nexcept ImportError: pass\ntry: import bs4\nexcept ImportError: pass\ntry: import numpy as np\nexcept ImportError: pass\ntry: from PIL import Image\nexcept ImportError: pass\n",po=Date.now();function uo(){return K()?chalk.yellow("icoa 2026> "):R()?chalk.cyan("icoa exam> "):function(){const o=q();return!(!o||"demo-free"!==o.session?.examId)&&new Date(o.session.startedAt||0).getTime()>=po}()?chalk.yellow("icoa demo> "):chalk.green("icoa> ")}const ho=go(yo(),"icoa-workspace"),wo=new Set(["sudo","su","doas","pkexec","brew","apt","apt-get","yum","choco","npm","npx","pip","pip3","shutdown","reboot","halt","mkfs","fdisk","dd","iptables","ufw"]),fo="__REPL_NO_EXIT__",bo="2.5.1",xo=["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","ai4ctf","model","ctf","exam","demo","retry","nations","next","prev","continue","logout","ctf4ai","mark","unmark","review","learn","demo2","ctf4eai","ctf4vla","theme","sim","arena","eai","learn-pull","help","menu","quit","q","exit","back"],vo={exam:["list","start","q","answer","submit","review","result","next","prev","mark","unmark","help"],ctf:["challenges","open","submit","scoreboard","status","join","logout","time"],challenge:["start","stop","status"],arena:["eai"],learn:["start","continue"]};function Ao(o){const e=o.replace(/^\s+/,"");if(/^\/\S*$/.test(e)){const o=e.slice(1).toLowerCase();return[xo.filter(e=>e.startsWith(o)).map(o=>`/${o}`),e]}const t=e.split(/\s+/);if(t.length<=1){const o=(t[0]??"").toLowerCase();return[xo.filter(e=>e.startsWith(o)).slice(),o]}if(2===t.length){const o=vo[t[0].toLowerCase()];if(o){const e=t[1].toLowerCase();return[o.filter(o=>o.startsWith(e)).slice(),e]}}return[[],o]}function Co(){console.log(),console.log(` ${chalk.cyan.bold("🎯 ICOA 2026 · National Selection")}`),console.log(),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("ACxxxxxxxx")+chalk.gray(" → ai4ctf-12 (AI as your CTF teammate)")),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("CAxxxxxxxx")+chalk.gray(" → ctf4ai-12 (red-team software AI)")),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("EAxxxxxxxx")+chalk.gray(" → ctf4eai-12 (red-team embodied AI)")),console.log(" "+chalk.bold.cyan("exam ")+chalk.white("<CC>xxxxxxxx")+chalk.gray(" → Paper A/B/C/D/E (country exam token)")),console.log(" "+chalk.bold.cyan("demo")+chalk.gray(" → free practice")),console.log(" "+chalk.bold.cyan("lang")+chalk.white(" es")+chalk.gray(" → switch language")),console.log(" "+chalk.gray("help · menu · quit")),console.log()}export async function startRepl(e,q){process.env.ICOA_INSIDE_REPL="1";let po=!1;if(K()){const o=n().joinedAt,e=o=>new Intl.DateTimeFormat("en-CA",{timeZone:"Australia/Sydney",year:"numeric",month:"2-digit",day:"2-digit"}).format(o);o&&e(new Date(o))===e(new Date)||(a({ctfdUrl:"",token:"",sessionCookie:"",userId:null,userName:"",teamId:null,country:"",joinedAt:""}),po=!0)}const vo=n(),To=l(),Eo=process.exit.bind(process),So=i();if(vo.language&&"en"!==vo.language&&(await s(vo.language,{silent:!0}),r(vo.language)),vo.demoCleanedForVersion!==bo){try{const{existsSync:o,unlinkSync:e}=await import("node:fs"),{join:t}=await import("node:path"),{getIcoaDir:l}=await import("./lib/config.js"),n=t(l(),"demo-state.json");o(n)&&e(n)}catch{}a({demoCleanedForVersion:bo})}const{select:$o,confirm:Oo}=await import("@inquirer/prompts"),jo=vo.mode||"",Do=""===jo?"instant":["instant","learn","selection","olympiad"].includes(jo)?jo:"selection",Lo=[{name:` ${chalk.bold("⚡ Try ICOA in 30 seconds")} ${chalk.gray("—")} ${chalk.gray("watch · no token needed")}`,value:"instant"},{name:` ${chalk.bold("🧠 Learn")} ${chalk.gray("—")} ${chalk.gray("AC / CA / EA token · skill up")}`,value:"learn"},{name:` ${chalk.bold("🎯 National Selection")} ${chalk.gray("—")} ${chalk.gray("country exam token · aim for finals")}`,value:"selection"},{name:` ${chalk.bold("🏆 International Olympiad")} ${chalk.gray("—")} ${chalk.gray("finals stage · Sydney 2026 · full sandbox")}`,value:"olympiad"},{name:` ${chalk.gray("ℹ️ About ICOA")} ${chalk.gray("·")} ${chalk.gray("what this is · how to join")}`,value:"about"}];console.log(chalk.gray(" Type ")+chalk.bold.cyan("menu")+chalk.gray(" from anywhere to return here.")),console.log();let No="";for(;!No;){let o;try{o=await $o({message:"Mode",choices:Lo,default:Do||"instant"})}catch(o){throw o instanceof Error&&"ExitPromptError"===o.name&&(console.log(),console.log(chalk.gray(" Goodbye.")),process.exit(0)),o}"about"!==o?No=o:(console.clear(),console.log(),console.log(chalk.cyan(" ═══════════════════════════════════════════════════")),console.log(chalk.bold.yellow(" ICOA")+chalk.white(" — AI-Native CLI OS for Cyber & AI Security")),console.log(chalk.gray(" Olympiad & Competition · K-12 to University")),console.log(chalk.cyan(" ───────────────────────────────────────────────────")),console.log(),console.log(chalk.bold.white(" What Makes ICOA Different")),console.log(chalk.gray(" · AI-native AI teammate, AI adversary, AI translation")),console.log(chalk.gray(" · CLI OS Complete competition environment in terminal")),console.log(chalk.gray(" · 110 tools pwntools, z3, gdb, nmap, sleuthkit... pre-configured")),console.log(chalk.gray(" · Global scale 15,000+ concurrent exams · 15 languages")),console.log(),console.log(chalk.bold.white(" Competition Format (2-day standard + 1-day Pioneer)")),console.log(` ${chalk.green.bold("AI4CTF")}${chalk.gray(" [Day 1] AI as teammate — speed track, dynamic decay + top-3 bonus")}`),console.log(` ${chalk.red.bold("CTF4AI")}${chalk.gray(" [Day 2] AI as target — knowledge track, static value per challenge")}`),console.log(` ${chalk.cyan.bold("CTF4EAI")}${chalk.gray(" [Pioneer / Practical Round] Embodied AI — VLA + world models + sim-to-real")}`),console.log(),console.log(chalk.bold.white(" Scoring (in brief)")),console.log(chalk.gray(" · Standard medals: AI4CTF + CTF4AI combined · 1/12 Gold · 2/12 Silver · 3/12 Bronze")),console.log(chalk.gray(" · HMA: top 50% on either day, total below bronze cutoff")),console.log(chalk.gray(" · CTF4EAI: separate 15-finalist pool, G/S/B + 12 Finalist Awards")),console.log(),console.log(chalk.white(" Sydney, Australia")+chalk.gray(" · Jun 27 - Jul 2, 2026")),console.log(),console.log(chalk.bold.white(" Organized by")+chalk.gray(" ASRA (Australia) · ICO Foundation Inc")),console.log(chalk.bold.white(" Contact ")+chalk.cyan(" australia@icoa2026.au · accreditation@icoa2026.au")),console.log(chalk.bold.white(" Website ")+chalk.cyan.underline(" https://icoa2026.au")),console.log(chalk.cyan(" ═══════════════════════════════════════════════════")),console.log(),console.log(chalk.gray(" Press ")+chalk.yellow("Enter")+chalk.gray(" to return...")),await new Promise(o=>{const e=t=>{process.stdin.removeListener("data",e),process.stdin.isTTY&&process.stdin.setRawMode&&process.stdin.setRawMode(!1),process.stdin.pause(),o()};process.stdin.isTTY&&process.stdin.setRawMode&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.once("data",e)}),console.clear())}if("olympiad"===No&&"olympiad"!==Do){console.log(),console.log(chalk.yellow(" This mode will download ~500MB of CTF tools and AI models."));let o=!0;try{o=await Oo({message:"Continue?",default:!0})}catch(e){if(!(e instanceof Error&&"ExitPromptError"===e.name))throw e;o=!1}o||(No="selection",console.log(chalk.gray(" Switched to National Selection mode.")))}if(No!==Do&&a({mode:No}),console.log(),"olympiad"===No&&p(bo)){u(bo),console.log(chalk.gray(" Checking competition environment..."));const{execSync:o}=await import("node:child_process"),e=[{name:"pwntools",cmd:'python3 -c "import pwn"'},{name:"z3-solver",cmd:'python3 -c "import z3"'},{name:"numpy",cmd:'python3 -c "import numpy"'},{name:"requests",cmd:'python3 -c "import requests"'}];let t=0;for(const l of e)try{o(l.cmd,{stdio:"ignore"})}catch{t++}t>0?(console.log(chalk.yellow(` ${t} core competition libraries missing.`)),console.log(chalk.gray(" Run ")+chalk.white("env setup")+chalk.gray(" when you are ready to install them.")),console.log()):(console.log(chalk.green(" All core libraries ready.")),console.log())}if(q){const o=d();if(o){const e=Math.floor(o.awaySeconds/60),t=o.awaySeconds%60;console.log(chalk.yellow(` Session resumed. Away: ${e}m ${t}s | Total exits: ${o.exitCount}`)),console.log()}}if("selection"===No)console.log(chalk.gray(" ─── exam hall · 90 min per paper once started · no pause ───")),console.log(),Co();else if("embodied"===No)!function(){console.log(chalk.cyan.bold(" [🤖 ctf4eai — Embodied AI Security]")),console.log(),console.log(chalk.bold.cyan(" CTF4EAI")+chalk.gray(" — ICOA 2026's ")+chalk.bold.white("Pioneer Round")),console.log(chalk.gray(" an independent parallel track alongside the scored main events: ")+chalk.green("AI4CTF")+chalk.gray(" (Day 1) and ")+chalk.red("CTF4AI")+chalk.gray(" (Day 2)")),console.log(),console.log(chalk.white(" Embodied AI is at its ImageNet moment.")),console.log(chalk.gray(" VLA models, MuJoCo physics, real robot arms.")),console.log(chalk.gray(" Real models, real physics, real attack surfaces.")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────"));const o=L()>0||N()>0,e=D()>0,t=j(),l=O(),n=null!==l&&"number"==typeof l.completedAt&&l.nextCardIndex>=l.totalCards,a=null!==l&&!n;if(n)console.log(chalk.bold.yellow(" Continue: ")+chalk.bold.cyan("④ learn LEARNDEMO01")+chalk.gray(" (demo2 ✓ · sim")+(e?chalk.gray(" ✓ · sim arm ✓)"):chalk.gray(")")));else if(a){const o=`${l.nextCardIndex} / ${l.totalCards}`;console.log(chalk.bold.yellow(" Continue: ")+chalk.bold.cyan("③ demo2")+chalk.gray(" (last left at card ")+chalk.bold.yellow(o)+chalk.gray(")"))}else o&&e?console.log(chalk.bold.yellow(" Next up: ")+chalk.bold.cyan("③ demo2")+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01")+chalk.gray(" (sim ✓ · sim arm ✓)")):t?console.log(chalk.bold.yellow(" Next up: ")+(e?chalk.bold.cyan("① sim")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2"):chalk.bold.cyan("② sim arm")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2"))+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01")):console.log(chalk.bold.yellow(" First time? Try in order: ")+chalk.bold.cyan("① sim")+chalk.gray(" → ")+chalk.bold.cyan("② sim arm")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2")+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01"));console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.bold.green(" sim")+chalk.gray(" ")+chalk.bold.cyan("①")+chalk.gray(" ")+chalk.bold.yellow("★ INSTANT")+chalk.gray(" — 9-robot group dance, no wait, no setup")),console.log(chalk.bold.green(" sim arm")+chalk.gray(" ")+chalk.bold.cyan("②")+chalk.gray(" interactive 6-DOF arm sandbox — type joint values, watch")),console.log(chalk.bold.green(" demo2")+chalk.gray(" ")+chalk.bold.cyan("③")+chalk.gray(" ~8 min interactive intro + live MuJoCo sim")),console.log(chalk.bold.green(" learn LEARNDEMO01")+chalk.gray(" ")+chalk.bold.cyan("④")+chalk.gray(" free 11-card intro (paste this command as-is)")),console.log(chalk.bold.green(" learn ")+chalk.bold.yellow("EA")+chalk.gray(" + 8 chars full 96 / 360 curriculum (team-issued)")),console.log(chalk.bold.green(" exam ")+chalk.bold.yellow("PDxxxxxxxx")+chalk.gray(" Paper D (CTF4EAI) — national selection contestants")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(),console.log(chalk.gray(" Three open tiers: ")+chalk.green("free 11")+chalk.gray(" · ")+chalk.yellow("registered 100")+chalk.gray(" · ")+chalk.bold.magenta("national team 480")+chalk.gray(" (PhD-ready)")),console.log(chalk.gray(" Country team contact: ")+chalk.cyan("australia@icoa2026.au")),console.log(),f(),console.log()}();else if("instant"===No)console.log(chalk.cyan.bold(" [⚡ Try ICOA in 30 seconds — no token needed]")),console.log(),console.log(chalk.gray(" Two free tastes — just type the word and press Enter:")),console.log(),console.log(chalk.bold.green(" demo ")+chalk.gray(" Paper A/B/C taste — 10 MCQs, no timer ")+chalk.bold.cyan("🎯 selection-style")),console.log(chalk.bold.green(" demo2")+chalk.gray(" Embodied-AI mini-demo — robots & MuJoCo ")+chalk.bold.yellow("🤖 hands-on")),console.log(),console.log(chalk.gray(" Type ")+chalk.bold.cyan("demo")+chalk.gray(" or ")+chalk.bold.cyan("demo2")+chalk.gray(" to start · ")+chalk.bold.cyan("menu")+chalk.gray(" to go back · ")+chalk.bold.cyan("quit")+chalk.gray(" to exit")),console.log(),a({mode:"selection"}),No="selection";else{if("learn"===No){console.log(chalk.cyan.bold(" [🧠 Learn]")),console.log(),console.log(chalk.gray(" Three tracks · same difficulty curve.")),console.log(),console.log(chalk.white(" Free 12-card demos — paste the full command:")),console.log(),console.log(chalk.gray(" 🤝 ai4ctf AI as your teammate ")+chalk.bold.yellow("learn AI4CTFDEMO01")),console.log(chalk.gray(" 🔓 ctf4ai AI as your target ")+chalk.bold.yellow("learn CTF4AIDEMO01")),console.log(chalk.gray(" 🤖 ctf4eai Embodied AI Security ")+chalk.bold.yellow("learn LEARNDEMO01")),console.log(),console.log(chalk.gray(" Got a cohort token? Type ")+chalk.bold.yellow("learn <TOKEN>")+chalk.gray(" (e.g. ")+chalk.bold.yellow("learn EAABCD1234")+chalk.gray(").")),console.log();try{const{input:o}=await import("@inquirer/prompts"),{resolveLearnInput:t}=await import("./lib/learn-input.js");console.log(chalk.gray(" Enter a token (or just press Enter to go back).")),console.log();const l=t(await o({message:chalk.bold.cyan("icoa learn>"),theme:{prefix:"",style:{message:o=>o}}}));if("token"===l.kind){console.log(),console.log(chalk.gray(" Opening ")+chalk.bold.cyan("learn")+chalk.gray(`: ${l.token}`)),console.log(),a({mode:"selection"}),process.env.ICOA_LEARN_EMBEDDED="1";try{await e.parseAsync(["node","icoa","learn",l.token])}finally{delete process.env.ICOA_LEARN_EMBEDDED}}else"ambiguous"!==l.kind&&"unknown"!==l.kind||(console.log(),console.log(chalk.yellow(" "+l.hint)),console.log(chalk.gray(" Returning to main menu — pick 🧠 Learn again to retry.")),console.log())}catch{}return a({mode:"selection"}),void w()}"organizer"===No?(console.log(chalk.yellow.bold(" [National/Regional Partner]")),console.log(),console.log(chalk.bold.white(" ██╗ ██████╗ ██████╗ █████╗")),console.log(chalk.bold.white(" ██║██╔════╝██╔═══██╗██╔══██╗")),console.log(chalk.bold.white(" ██║██║ ██║ ██║███████║")),console.log(chalk.bold.white(" ██║██║ ██║ ██║██╔══██║")),console.log(chalk.bold.white(" ██║╚██████╗╚██████╔╝██║ ██║")),console.log(chalk.bold.white(" ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝")),console.log(),console.log(chalk.yellow(" International Cyber Olympiad in AI 2026")),console.log(chalk.bold.magenta(" The World's First AI-Native CLI Operating System")),console.log(chalk.bold.magenta(" for Cybersecurity & AI Security Competition")),console.log(chalk.bold.magenta(" and Olympiad for K-12")),console.log(chalk.gray(" Sydney, Australia · Jun 27 - Jul 2, 2026")),console.log(),console.log(chalk.white(" Vision")),console.log(chalk.gray(" Building a global pipeline for youth cyber & AI")),console.log(chalk.gray(" security talent through education and competition.")),console.log(),console.log(chalk.white(" Capacity")),console.log(chalk.gray(" 15,000+ concurrent online examinations")),console.log(chalk.gray(" National selection, training, and education support")),console.log(),console.log(chalk.white(" Olympic Spirit")),console.log(chalk.gray(" Excellence · Friendship · Respect")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" New country accreditation & support:")),console.log(chalk.cyan(" australia@icoa2026.au")),console.log(chalk.cyan(" accreditation@icoa2026.au")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(),To?(console.log(chalk.green(` Logged in as ${vo.userName}`)),console.log(chalk.white(" exam list")+chalk.gray(" Manage exams")),console.log(chalk.white(" logout")+chalk.gray(" Disconnect"))):console.log(chalk.white(" join <url>")+chalk.gray(" Connect to manage exams")),console.log(),f(),console.log()):(console.log(` ${chalk.cyan.bold("🏆 ICOA 2026 · International Olympiad")}`),console.log(),So&&!y()?(console.log(chalk.red(" Token was activated on a different device.")),console.log(chalk.gray(" Contact organizer for assistance.")),console.log()):To?(console.log(chalk.green.bold(` Welcome back, ${vo.userName}!`)),console.log(chalk.gray(` Connected to ${vo.ctfdUrl}`)),console.log(chalk.gray(" Not you? Type ")+chalk.cyan("logout")+chalk.gray(" to switch accounts")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" Ready to compete? Start here:")),console.log(),console.log(chalk.bold.cyan(" challenges")+chalk.gray(" Browse challenges by category")),console.log(chalk.white(" status")+chalk.gray(" Your score & timer")),console.log(chalk.white(" scoreboard")+chalk.gray(" Live rankings")),console.log(chalk.white(" memo")+chalk.gray(" Report an issue to organizers (one-way)")),console.log(),console.log(chalk.gray(" Tool environment:")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.bold.yellow(" ★ ")+chalk.bold.cyan("man <tool>")+chalk.gray(" How to USE a tool (steghide, nmap…) · ")+chalk.cyan("man tools")+chalk.gray(" = list")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("help")+chalk.gray(" · ")+b()+chalk.gray(" · ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+chalk.cyan("quit")+chalk.gray(" closes")),console.log()):So?(so(ho)||ro(ho,{recursive:!0}),console.log(chalk.green.bold(" Welcome, competitor!")),console.log(chalk.gray(` Workspace: ${ho}`)),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" Get started:")),console.log(),console.log(chalk.white(" Step 1 ")+chalk.bold.cyan("join <url>")+chalk.gray(" Connect to competition server")),console.log(chalk.white(" Step 2 ")+chalk.bold.cyan("challenges")+chalk.gray(" Browse & solve challenges")),console.log(chalk.white(" Step 3 ")+chalk.bold.cyan("ai4ctf")+chalk.gray(" Ask AI when stuck")),console.log(),console.log(chalk.gray(" Before Step 1 — make sure your tools are ready:")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.bold.yellow(" ★ ")+chalk.bold.cyan("man <tool>")+chalk.gray(" How to USE a tool (steghide, nmap…) · ")+chalk.cyan("man tools")+chalk.gray(" = list")),console.log(),console.log(chalk.gray(" Also: ")+chalk.white("help")+chalk.gray(" all commands")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+b()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()):(console.log(chalk.bold.yellow(" 🏆 You reached the finals tier.")),console.log(chalk.gray(" Full sandbox · 110 CTF tools · Sydney 2026 · this is where finalists compete.")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" To begin, activate your competition token:")),console.log(),console.log(chalk.bold.cyan(" activate <token>")),console.log(),console.log(chalk.gray(" While waiting, explore:")),console.log(chalk.white(" ref linux")+chalk.gray(" Quick reference for Linux")),console.log(chalk.white(" ref web")+chalk.gray(" Quick reference for Web")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.white(" help")+chalk.gray(" All available commands")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+b()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()))}e.exitOverride(),e.configureOutput({writeErr:()=>{},writeOut:o=>{console.log(o)}});const Po=o({input:process.stdin,output:process.stdout,prompt:uo(),terminal:!0,completer:Ao});x(Po);let Ro=!1;if(h(!0),X(),po&&(console.log(),console.log(chalk.yellow(" ⏱ A new competition day has started (Sydney time).")),console.log(chalk.gray(" For fairness, yesterday’s sign-in has been cleared. Type ")+chalk.cyan("join <url>")+chalk.gray(" to sign in with your account.")),console.log()),K()){const o=n().userName||"this account";console.log(),console.log(chalk.yellow(" ⚠ This machine is signed in as ")+chalk.bold.white(o)+chalk.yellow(".")),console.log(chalk.gray(" Press ")+chalk.cyan("Enter")+chalk.gray(` to continue as ${o}, or type `)+chalk.cyan("logout")+chalk.gray(" to switch accounts.")),"logout"===(await new Promise(o=>{Po.question(chalk.white(" > "),e=>o(e.trim()))})).toLowerCase()&&(a({ctfdUrl:"",token:"",sessionCookie:"",userId:null,userName:"",teamId:null,country:""}),console.log(),console.log(chalk.green(" ✓ Logged out. ")+chalk.gray("Run ")+chalk.cyan("join <url>")+chalk.gray(" to sign in with your own account."))),console.log()}Z()&&V(()=>Po.prompt());const qo=Po.prompt.bind(Po);Po.prompt=o=>{A()||k()||E()||$()||lo()||Po.setPrompt(uo()),qo(o)},Po.prompt(),Po.on("line",async o=>{if(Ro)return;let l=o.trim();if(!l)return Po.setPrompt(A()?chalk.magenta("icoa ai4ctf> "):uo()),void Po.prompt();if(l.startsWith("/")&&!l.startsWith("//")){const o=l.slice(1).split(/\s+/)[0].toLowerCase(),t=l.slice(1+o.length).trim();if("ai"===o)return Ro=!0,await async function(o,e){if(A())return void(o?await C(o):console.log(chalk.gray(" You are already in the AI chat — just type your message.")));if(k())return void(o?await T(o):console.log(chalk.gray(" You are already in the CTF4AI target chat — just type your message.")));if(E())return void(o?await S(o):console.log(chalk.gray(" You are already in the Embodied-AI chat — just type your message.")));z(o?`/ai ${o}`:"/ai");const t=process.exit;process.exit=()=>{throw new Error(fo)};try{await e.parseAsync(["node","icoa","ai4ctf"])}catch(o){if(!(o instanceof Error&&o.message===fo))throw o}finally{process.exit=t}o&&A()&&await C(o)}(t,e),Ro=!1,Po.setPrompt(A()?chalk.magenta("icoa ai4ctf> "):uo()),void Po.prompt();!(A()||k()||E()||$()||lo())&&xo.includes(o)&&(l=l.slice(1))}if("menu"===l||"menu confirm"===l)return R()&&"menu confirm"!==l?(console.log(),console.log(chalk.yellow(" Real exam active. Progress is auto-saved.")),console.log(chalk.gray(" To return to main menu anyway, type ")+chalk.white("menu confirm")),console.log(),void Po.prompt()):void w(Po);if(A()){Ro=!0;const o=await C(l);return Ro=!1,"exit"===o&&Po.setPrompt(uo()),void Po.prompt()}if(k()){Ro=!0;const o=await T(l);return Ro=!1,"exit"!==o&&"solved"!==o||Po.setPrompt(uo()),void Po.prompt()}if(E()){Ro=!0;const o=await S(l);return Ro=!1,"exit"===o&&Po.setPrompt(uo()),Po.setPrompt(E()?chalk.bold.cyan("icoa ctf4eai> "):uo()),void Po.prompt()}if(z(l),"exit"===l)return P()?(console.log(),console.log(chalk.yellow(" ⚠ An exam is in progress.")),console.log(chalk.white(" To return to menu without losing progress, type: ")+chalk.bold.cyan("back")),console.log(chalk.white(" To fully close ICOA CLI, type: ")+chalk.bold.cyan("quit")),console.log(chalk.gray(" Your progress is auto-saved either way.")),console.log(),void Po.prompt()):(console.log(),console.log(chalk.gray(" ")+chalk.white("exit")+chalk.gray(" returns to the main menu. To fully close ICOA CLI, type ")+chalk.bold.cyan("quit")+chalk.gray(".")),"selection"===No&&Co(),void Po.prompt());if("quit"===l||"q"===l||"quit confirm"===l){const o=P();return o&&"demo-free"!==o.session.examId&&"quit confirm"!==l?(console.log(),console.log(chalk.yellow(" ⚠ A real exam is in progress.")),console.log(chalk.gray(" Your answers are auto-saved on the server, but the exam timer keeps ticking")),console.log(chalk.gray(" on the server side even if you close the CLI.")),console.log(),console.log(chalk.white(" To leave the CLI but keep the exam alive, type: ")+chalk.bold.cyan("back")),console.log(chalk.gray(" (recommended — you can resume with ")+chalk.cyan("exam q 1")+chalk.gray(" after relaunching icoa)")),console.log(),console.log(chalk.white(" To really close ICOA CLI, type: ")+chalk.bold.cyan("quit confirm")),console.log(),void Po.prompt()):(o&&"demo-free"===o.session.examId&&(console.log(),console.log(chalk.gray(" Demo paused. Resume with: ")+chalk.white("demo")+chalk.gray(" (fresh) or ")+chalk.white("exam q 1")+chalk.gray(" (continue)."))),J(),G(),m(),console.log(chalk.gray(" Session saved. Use ")+chalk.white("icoa --resume")+chalk.gray(" to continue.")),M(),void Eo(0))}if("back"===l){const o=P(),e=o&&"demo-free"!==o.session.examId,t=o&&"demo-free"===o.session.examId&&(()=>{const e=new Date(o.session.startedAt||0).getTime();return Date.now()-e<18e5})();if(e)console.log(),console.log(chalk.gray(" Exam paused. Your progress is saved.")),console.log(chalk.white(" Resume: exam q 1")+chalk.gray(" · ")+chalk.white("exam review")+chalk.gray(" · ")+chalk.white("exam submit")),console.log();else if(t){const e=Object.keys(o.answers).length,t=o.session.questionCount;console.log(),console.log(chalk.gray(` Demo paused (${e}/${t} answered). Resume with: `)+chalk.white("exam q 1")),console.log(chalk.gray(" Or type ")+chalk.white("demo")+chalk.gray(" to restart.")),console.log()}else{if(o&&"demo-free"===o.session.examId){const{clearExamState:o}=await import("./lib/exam-state.js");o("demo-free")}const e=n();fetch("https://practice.icoa2026.au/api/icoa/demo-stats",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:"post-report-back",lang:e.language||"en",timestamp:(new Date).toISOString()}),signal:AbortSignal.timeout(5e3)}).catch(()=>{}),"selection"===No?Co():console.log(chalk.gray(" Already at main menu."))}return void Po.prompt()}if("help"===l||"?"===l){if(P()){Ro=!0;try{await e.parseAsync(["node","icoa","exam","help"])}catch{}return Ro=!1,void Po.prompt()}return ko(i(),No),void Po.prompt()}if("man"===l||"manual"===l)return ko(i(),No),console.log(),console.log(chalk.bold.yellow(" ★ Stuck on a tool? ")+chalk.bold.cyan("man <tool>")+chalk.gray(" e.g. ")+chalk.cyan("man steghide")+chalk.gray(" · ")+chalk.cyan("man tools")+chalk.gray(" = full list")),void Po.prompt();if(/^(?:man|manual)\s+\S/i.test(l))return I(l.replace(/^(?:man|manual)\s+/i,"")),void Po.prompt();if("more help"===l.toLowerCase()&&P()){Ro=!0;try{await e.parseAsync(["node","icoa","exam","more-help"])}catch{}return Ro=!1,void Po.prompt()}if("continue"===l.toLowerCase())return console.log(),console.log(chalk.green.bold(" ═══ AI4CTF — AI as Your Teammate ═══")),console.log(),console.log(chalk.white(" In AI4CTF, you solve cybersecurity challenges")),console.log(chalk.white(" with AI by your side.")),console.log(),console.log(chalk.white(" In this demo, your AI teammate gives help at 3 levels:")),console.log(chalk.yellow(" hint a")+chalk.gray(" General guidance")),console.log(chalk.yellow(" hint b")+chalk.gray(" Deep analysis")),console.log(chalk.yellow(" hint c")+chalk.gray(" Critical assist")),console.log(),console.log(chalk.white(" Try it now! Type: ")+chalk.bold.green("ai4ctf")),console.log(chalk.gray(' Chat freely with your AI teammate. Type "exit" when done.')),console.log(),console.log(chalk.gray(" After ai4ctf, try: ")+chalk.bold.red("ctf4ai")+chalk.gray(' — trick the AI into saying "koala"')),console.log(),void Po.prompt();if(/^ICOA-[A-Z]{2,3}-\d{1,6}$/i.test(l.trim())){Ro=!0;try{await e.parseAsync(["node","icoa","exam","token",l.trim()])}catch{}return Ro=!1,void Po.prompt()}if(/^[A-Z]{2}[0-9A-HJKMNP-TV-Z]{8}$/i.test(l.trim())){Ro=!0;try{await e.parseAsync(["node","icoa","exam","token",l.trim().toUpperCase()])}catch{}return Ro=!1,void Po.prompt()}const a=l.match(/^exam\s+([A-Z]{2}[0-9A-HJKMNP-TV-Z]{8})$/i);if(a){Ro=!0;try{await e.parseAsync(["node","icoa","exam","token",a[1].toUpperCase()])}catch{}return Ro=!1,void Po.prompt()}const s=l.match(/^exam\s+([A-Z]{2,3})$/i);if(s){Ro=!0;try{await e.parseAsync(["node","icoa","exam","list",s[1]])}catch{}return Ro=!1,void Po.prompt()}if("clear"===l||"cls"===l)return console.clear(),void Po.prompt();if("news"===l)return Z()?H():console.log(chalk.gray(" No competition joined. Use ")+chalk.white("join <url>")+chalk.gray(".")),void Po.prompt();if("memo"===l){if(!Z())return console.log(chalk.gray(" Join a competition first: ")+chalk.white("join <url>")),void Po.prompt();Ro=!0;try{await no()}catch{}return void(Ro=!1)}const r=eo()||oo(n().userName||"");if("jury"===l&&r){Ro=!0;try{await ao()}catch{}return void(Ro=!1)}if(r&&eo()&&"scoreboard"===l.split(/\s+/)[0]){Ro=!0;try{const o=await to();if(console.log(),0===o.length)console.log(chalk.gray(" Scoreboard is empty."));else{console.log(chalk.bold.white(" Scoreboard"));for(const e of o.slice(0,50))console.log(chalk.gray(` ${String(e.pos).padStart(3)}. `)+chalk.white(e.name.padEnd(28).slice(0,28))+chalk.cyan(String(e.score)))}console.log()}catch{}return Ro=!1,void Po.prompt()}if(r&&K()){const o=l.split(/\s+/)[0];if(["challenges","open","submit","hint"].includes(o))return console.log(),console.log(chalk.yellow(" Team-leader account — the challenge bracket is not available here.")),console.log(chalk.gray(" Available: ")+chalk.white("scoreboard")+chalk.gray(" · ")+chalk.white("news")+chalk.gray(" · ")+chalk.white("jury")+chalk.gray(" · ")+chalk.white("time")+chalk.gray(" · ")+chalk.white("status")+chalk.gray(" · ")+chalk.white("logout")),console.log(),void Po.prompt()}if(l.startsWith("activate ")){const o=l.slice(9).trim(),e=c(o);return"ok"===e?console.log(chalk.green(" Access granted! Token bound to this device.")):"already_bound"===e?(console.log(),console.log(chalk.red(" Token already activated on a different device.")),console.log(chalk.gray(" Each token binds to the first device that uses it. If you lost the device,")),console.log(chalk.gray(" contact your proctor to have the token re-issued for a new device."))):(console.log(),console.log(chalk.red(" Token not recognized.")),console.log(chalk.gray(" Possible reasons:")),console.log(chalk.white(" • ")+chalk.gray("Typo — access tokens are case-insensitive and look like ")+chalk.cyan("ICOA-XXXX-XXXX-XXXX")+chalk.gray(" (4-char hex groups, e.g. ICOA-385E-27F2-B21B)")),console.log(chalk.white(" • ")+chalk.gray("Expired — ask your proctor or organizer for a fresh token")),console.log(chalk.white(" • ")+chalk.gray("Network — verify connection to ")+chalk.cyan("practice.icoa2026.au")),console.log(chalk.gray(" Still stuck? type ")+chalk.cyan("help")+chalk.gray(" or try ")+chalk.cyan("exam demo")+chalk.gray(" for a free practice round."))),console.log(),void Po.prompt()}if("activate"===l)return console.log(chalk.gray(" Usage: ")+chalk.white("activate <token>")),console.log(),void Po.prompt();const d=P();if(d){const o=l.toUpperCase().trim(),t=o=>{const e=d.questions.find(e=>e.number===o);return!!e&&("ai4ctf"===e.type||"ctf4ai"===e.type||e.options&&!e.options.A&&!e.options.B)},n=o=>{const e=d.questions.find(e=>e.number===o);return"short_answer"===e?.type},a=o=>{const e="demo-free"!==d.session.examId,t=d.questions.find(e=>e.number===o),l=F(t?.type,e);console.log(),console.log(chalk.yellow(` Q${o} is a practical question — letters (A/B/C/D) don't apply here.`)),l?(console.log(chalk.white(" Enter the AI chat for this question: ")+chalk.bold.cyan(l)),console.log(chalk.gray(" Or submit a flag directly: ")+chalk.green(`exam answer ${o} ICOA{your_flag}`))):console.log(chalk.gray(" Submit a flag: ")+chalk.green(`exam answer ${o} ICOA{your_flag}`)),console.log()};if(/^[ABCDE]$/.test(o)){const l=d._lastQ||1;if(t(l))return a(l),void Po.prompt();if(n(l))return console.log(),console.log(chalk.yellow(` Q${l} is a short-answer question — type a number, not a letter.`)),console.log(chalk.gray(" Example: ")+chalk.green("42")+chalk.gray(" (or ")+chalk.green(`exam answer ${l} 42`)+chalk.gray(")")),console.log(),void Po.prompt();Ro=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(l),o])}catch{}return Ro=!1,void Po.prompt()}if(/^-?\d+$/.test(o)){const t=d._lastQ||1;if(n(t)){Ro=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(t),o])}catch{}return Ro=!1,void Po.prompt()}}const s=o.match(/^(\d+)\s+([ABCDE]|-?\d+)$/);if(s){const o=parseInt(s[1],10);if(t(o))return a(o),void Po.prompt();Ro=!0;try{await e.parseAsync(["node","icoa","exam","answer",s[1],s[2]])}catch{}return Ro=!1,void Po.prompt()}}const p=l.split(/\s+/)[0].toLowerCase(),u=/^python3?(\.\d+)?$/.test(p),h="ls"===p||"pwd"===p,f=l.startsWith("!")||p.startsWith("!")||u||h,b=new Set(["nano","vi","vim","emacs","pico","ed","code","cat","less","more","head","tail","ls","pwd","cd","base64","xxd","hexdump","od","openssl","md5sum","sha256sum","grep","find","awk","sed","strings","file","curl","wget","nc","ping","nmap","echo","bash","sh","zsh","pip","pip3","node","npm"]),x=()=>{console.log(chalk.gray(" Shell commands need ")+chalk.bold.cyan("!")+chalk.gray(" prefix. Try: ")+chalk.bold.cyan(`!${l}`)),console.log()};if("embodied"===No&&!f&&!["demo2","learn","exam","ctf4eai","ctf4vla","eai","arena","lang","ref","setup","env","aienv","ipynb","sim"].includes(p))return b.has(p)?(x(),void Po.prompt()):(console.log(chalk.gray(" Not available in Embodied AI Security mode.")),console.log(chalk.white(" Try ")+chalk.bold.cyan("demo2")+chalk.gray(" (intro) · ")+chalk.bold.cyan("learn")+chalk.gray(" (curriculum) · ")+chalk.bold.cyan("exam <PD-token>")+chalk.gray(" (Paper D)")),console.log(),void Po.prompt());if("selection"===No&&!f&&!["exam","demo","demo2","retry","nations","next","prev","continue","setup","lang","ref","ai4ctf","ctf4ai","mark","unmark","review","submit","env","aienv","ipynb","sim"].includes(p)){if(b.has(p))return x(),void Po.prompt();if(console.log(chalk.gray(" Not available in Selection mode.")),d){const o=d._lastQ||1;console.log(chalk.white(` Resume exam: exam q ${o}`)+chalk.gray(" · ")+chalk.white("A/B/C/D")+chalk.gray(" to answer"))}else console.log(chalk.gray(" Try: demo · setup to switch mode"));return console.log(),void Po.prompt()}if("organizer"===No&&!["join","exam","demo","retry","next","prev","logout","setup","lang","ref","ctf","mark","unmark","review","submit"].includes(p))return console.log(chalk.gray(" Not available in Organizer mode. Switch via: setup")),console.log(),void Po.prompt();if(!("olympiad"!==No||i()&&y()||g(p)))return console.log(chalk.yellow(" Restricted mode. ")+chalk.gray("Enter your access token:")),console.log(chalk.white(" activate <token>")),console.log(),console.log(chalk.gray(" Free commands: ")+chalk.white("ref [topic]")+chalk.gray(", ")+chalk.white("help")+chalk.gray(", ")+chalk.white("exit")),console.log(),void Po.prompt();if(!["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","ai4ctf","model","ctf","exam","demo","retry","nations","next","prev","continue","logout","ctf4ai","mark","unmark","review","submit","learn","demo2","ctf4eai","ctf4vla","theme","sim","arena","eai","learn-pull"].includes(p)){if(wo.has(p))return console.log(chalk.yellow(` "${p}" is a shell command — the ICOA prompt isn't a shell.`)),console.log(chalk.gray(" In real-exam mode, prefix with ! to run inside the sandbox: ")+chalk.cyan(`!${l}`)),console.log(),void Po.prompt();if(/(?:^|\s)(?:\/(?!home\/|Users\/|tmp\/)|\.\.\/|~\/)/.test(l)&&!l.startsWith("cd ")){const o=/(?:^|\s)\/(?!home\/\w+\/icoa-workspace|Users\/\w+\/icoa-workspace|tmp\/)/.test(l),e=/\.\./.test(l);if(o||e)return console.log(chalk.red(" Blocked: access outside workspace is not allowed.")),console.log(chalk.gray(` Workspace: ${ho}`)),console.log(),void Po.prompt()}let o=l.startsWith("!")?l.slice(1).trim():l;if("darwin"===process.platform){const e="/opt/homebrew/opt/python@3.12/bin/python3.12";o=o.replace(/^python3?\s/,`${e} `).replace(/^(python3|python)$/,e)}else if("win32"===process.platform){const e=(()=>{try{return t("py -3 --version",{stdio:["ignore","ignore","ignore"],timeout:1500}),"py -3"}catch{}return"python"})();o=o.replace(/^python3?(\.\d+)?\s/,`${e} `).replace(/^python3?(\.\d+)?$/,e)}else{const e=(()=>{try{return t("which python3.12",{stdio:"ignore"}),"python3.12"}catch{return"python3"}})();o=o.replace(/^python\s/,`${e} `).replace(/^python$/,e)}const e=Y(),n=W(l);Q({cwd:e,input:l,riskFlags:n}),n.length>0&&R()&&(console.log(chalk.yellow(` ⚠ Action flagged: ${n.join(", ")} — logged.`)),console.log()),/^(\S*python3?(\.\d+)?)\s*$/.test(o)&&(o=`PYTHONSTARTUP="${function(){const o=go(yo(),".icoa");so(o)||ro(o,{recursive:!0});const e=go(o,"python-startup.py");let t="";if(so(e))try{t=io(e,"utf-8")}catch{}return t!==mo&&co(e,mo),e}()}" ${o}`,console.log(),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(chalk.bold.white(" Python ready — ICOA exam toolkit pre-loaded")),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(),console.log(chalk.white(" Already imported: ")+chalk.gray("base64, struct, hashlib, re, json, binascii")),console.log(chalk.white(" Also available: ")+chalk.gray("requests, bs4, numpy, PIL.Image, AES, pad/unpad, xor, p32/u32/p64/u64")),console.log(),console.log(chalk.yellow(" Quick examples:")),console.log(chalk.gray(' base64.b64decode("aGVsbG8=") ')+chalk.gray("# decode base64")),console.log(chalk.gray(' bytes.fromhex("48656c6c6f") ')+chalk.gray("# hex → bytes")),console.log(chalk.gray(' "ICOA{x}".encode() ')+chalk.gray("# str → bytes")),console.log(chalk.gray(" [chr(c) for c in [73,67,79,65]] ")+chalk.gray("# ASCII codes")),console.log(chalk.gray(' xor(bytes.fromhex("0a2b"), b"IC") ')+chalk.gray("# pwntools XOR")),console.log(),console.log(chalk.gray(" Exit: ")+chalk.white("exit()")+chalk.gray(" or Ctrl-D")),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log()),Ro=!0;try{await _()&&await B()?await U(o,Po):await Io(o,Po,e)}catch{console.log(chalk.yellow(` Command failed: ${p}`))}return Ro=!1,console.log(),void Po.prompt()}Ro=!0;const O=l.trim(),j=O.toLowerCase();let D,L=null,N="";if(d)if("submit"===j)L="final";else if(j.startsWith("submit ")){let o=O.slice(7).trim();/^submit\s+/i.test(o)&&(o=o.replace(/^submit\s+/i,"").trim()),o=o.replace(/^["'`]+|["'`]+$/g,"").trim(),o&&/^ICOA\{[^}]*\}?$/i.test(o)?(L="flag",N=o):o&&/^[ABCDE]$/i.test(o)&&(L="flag",N=o.toUpperCase())}else/^ICOA\{[^}]+\}$/i.test(O)&&(L="flag",N=O);D="final"===L?["exam","submit"]:"flag"===L?["exam","answer",String(d?._lastQ||1),N]:function(o){const e=o.split(/\s+/),t=e[0].toLowerCase(),l=e.slice(1);if("aienv"===t&&["run","python","py"].includes((l[0]??"").toLowerCase()))return v(o);if(("submit"===t||"flag"===t)&&l.length>=2)return["ctf","submit",l[0],l.slice(1).join(" ").trim().replace(/^["'`]+|["'`]+$/g,"")];if("connect"===t&&l.length>=2){const e=v(o);return["connect",e[1]??l[0],e.slice(2).join(" ")]}const n={demo:["exam","demo"],retry:["exam","demo-retry"],nations:["exam","nations"],next:["exam","next"],prev:["exam","prev"],mark:["exam","mark",...l],unmark:["exam","unmark",...l],review:["exam","review"],logout:["ctf","logout"],join:["ctf","join",...l],activate:["ctf","activate",...l],challenges:["ctf","challenges"],ch:["ctf","challenges"],open:["ctf","open",...l],submit:["ctf","submit",...l],flag:["ctf","submit",...l],scoreboard:["ctf","scoreboard",...l],sb:["ctf","scoreboard",...l],status:["ctf","status"],time:["ctf","time"]};return n[t]?n[t]:["ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","ai4ctf","model","ctf","exam","ctf4ai"].includes(t)?[t,...l]:e}(l);const q="ctf"===D[0]&&"join"===D[1];q&&Po.pause(),process.exit=()=>{throw new Error(fo)};try{await e.parseAsync(["node","icoa",...D])}catch(o){const e=o instanceof Error?o.message:String(o);if(e===fo);else if(e.includes("commander.unknownCommand")){const{distance:o}=await import("fastest-levenshtein"),e=["ctf","ref","shell","files","view","connect","challenge","note","notes","logbook","log","manual","lang","setup","env","aienv","ipynb","ai4ctf","exam","ctf4ai","theme","eai","clear","cls","quit","exit","back","menu","help","continue","activate","demo","challenges","status","scoreboard","join","logout"],t=p.split(/\s+/)[0]||p;let l={word:"",dist:1/0};for(const n of e){const e=o(t.toLowerCase(),n);e<l.dist&&(l={word:n,dist:e})}console.log(chalk.yellow(` Unknown command: ${p}.`)),l.dist>0&&l.dist<=2&&console.log(chalk.gray(" Did you mean: ")+chalk.bold.cyan(l.word)+chalk.gray("?")),console.log(chalk.gray(" Type ")+chalk.cyan("help")+chalk.gray(" for the full command list."))}else e.includes("commander.missingArgument")||"commander.missingArgument"===o?.code?"submit"===p||"flag"===p?(console.log(chalk.yellow(" Incomplete — usage: ")+chalk.cyan("submit <challenge#> <flag>")),console.log(chalk.gray(" Put the number AND the flag on one line, e.g. ")+chalk.cyan("submit 44 pecan{...}"))):(console.log(chalk.yellow(` Incomplete command: ${p}`)),console.log(chalk.gray(" Type ")+chalk.cyan("help")+chalk.gray(" for usage."))):e.includes("commander.")||(e.includes("fetch failed")||e.includes("ECONNREFUSED")||e.includes("ETIMEDOUT"))&&console.log(chalk.yellow(" Network error. Check your connection."))}finally{process.exit=Eo,Ro=!1,q&&Po.resume()}A()?Po.setPrompt(chalk.magenta("icoa ai4ctf> ")):k()?Po.setPrompt(chalk.red("icoa ctf4ai> ")):E()&&Po.setPrompt(chalk.bold.cyan("icoa ctf4eai> ")),console.log(),Po.prompt()}),Po.on("SIGINT",()=>{if(console.log(),A()||k())console.log(chalk.yellow(" Ctrl+C did not close ICOA CLI — you are still in the AI chat.")),console.log(chalk.white(" Type ")+chalk.bold.cyan("exit")+chalk.white(" to leave the chat and return to the menu."));else if(P()){const o="demo-free"!==P().session.examId;console.log(chalk.yellow(" Ctrl+C did NOT close ICOA CLI.")),console.log(chalk.gray(` Your ${o?"exam":"demo"} is paused and every answer is auto-saved.`)),console.log(),console.log(chalk.white(" Resume: ")+chalk.cyan("exam q 1")+chalk.gray(" · Back to menu: ")+chalk.cyan("back")+chalk.gray(" · Close CLI: ")+chalk.cyan(o?"quit confirm":"quit"))}else console.log(chalk.yellow(" Ctrl+C did not close ICOA CLI — you are still at the ")+chalk.cyan("icoa>")+chalk.yellow(" prompt.")),console.log(chalk.gray(" Keep typing — ")+chalk.cyan("help")+chalk.gray(" lists commands. (Only ")+chalk.cyan("quit")+chalk.gray(" or Ctrl+D actually close the CLI.)"));console.log(),Po.prompt()}),Po.on("close",()=>{J(),G(),m(),M(),Eo(0)})}function Io(o,t,l){return new Promise(n=>{const a=process.stdin,s=!!a.isTTY&&!!a.isRaw;if(t.pause(),a.isTTY&&"function"==typeof a.setRawMode)try{a.setRawMode(!1)}catch{}const r=e(o,{shell:!0,stdio:"inherit",cwd:l||process.cwd()}),i=()=>{if(a.isTTY&&"function"==typeof a.setRawMode&&s)try{a.setRawMode(!0)}catch{}t.resume(),n()};r.on("close",i),r.on("error",i)})}function ko(o,e="olympiad"){return console.log(),"selection"===e||"organizer"===e?(console.log(chalk.bold.white(" Exam")),console.log(chalk.white(" join <url> ")+chalk.gray("Connect to exam server")),console.log(chalk.white(" exam list ")+chalk.gray("Available exams")),console.log(chalk.white(" exam start <id> ")+chalk.gray("Begin an exam")),console.log(chalk.white(" exam q [n] ")+chalk.gray("View questions")),console.log(chalk.white(" exam answer <n> <X> ")+chalk.gray("Answer question")),console.log(chalk.white(" exam review ")+chalk.gray("Review all answers")),console.log(chalk.white(" exam submit ")+chalk.gray("Submit for grading")),console.log(chalk.white(" exam result ")+chalk.gray("View your score")),console.log(),console.log(chalk.bold.white(" System")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference")),console.log(chalk.white(" setup ")+chalk.gray("Settings / switch mode")),console.log(chalk.white(" lang [code] ")+chalk.gray("Switch language")),console.log(chalk.white(" clear ")+chalk.gray("Clear screen")),console.log(chalk.white(" exit ")+chalk.gray("Quit")),void console.log()):o?(console.log(chalk.cyan(" ═══════════════════════════════════════════════")),console.log(chalk.bold.white(" How it works")),console.log(),console.log(chalk.gray(" 1. Browse ")+chalk.white("challenges")+chalk.gray(" and pick one")),console.log(chalk.gray(" 2. ")+chalk.white("open <id>")+chalk.gray(" to read the challenge")),console.log(chalk.gray(" 3. Use ")+chalk.white("ai4ctf")+chalk.gray(" to chat with AI when stuck")),console.log(chalk.gray(" 4. ")+chalk.white("submit <id> <flag>")+chalk.gray(" to score points")),console.log(chalk.gray(" 5. Check ")+chalk.white("scoreboard")+chalk.gray(" to track your rank")),console.log(chalk.cyan(" ═══════════════════════════════════════════════")),console.log(),console.log(chalk.bold.white(" Competition")),console.log(chalk.white(" join <url> ")+chalk.gray("Connect to CTFd")),console.log(chalk.white(" challenges (ch) ")+chalk.gray("List challenges by category")),console.log(chalk.white(" open <id> ")+chalk.gray("Read challenge + get next steps")),console.log(chalk.white(" submit <id> <flag> ")+chalk.gray("Submit a flag")),console.log(chalk.white(" scoreboard (sb) ")+chalk.gray("Live rankings")),console.log(chalk.white(" status ")+chalk.gray("Your score & timer")),console.log(chalk.white(" time ")+chalk.gray("Countdown timer")),console.log(),console.log(chalk.bold.white(" AI Teammate")),console.log(chalk.white(" ai4ctf ")+chalk.gray("Free-chat with your AI teammate")),console.log(),console.log(chalk.bold.white(" Tools")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference (linux, web, crypto...)")),console.log(chalk.white(" shell ")+chalk.gray("Interactive CTF shell (sandbox if present, else host)")),console.log(chalk.white(" files <id> ")+chalk.gray("Download challenge files")),console.log(chalk.white(" connect <id> ")+chalk.gray("Connect to remote target")),console.log(chalk.white(" note [text] ")+chalk.gray("Add a logbook entry (in-exam: tags current Q)")),console.log(chalk.white(" logbook [n] ")+chalk.gray("View your logbook (in-exam: filter by Q)")),console.log(chalk.white(" log ")+chalk.gray("Session history")),console.log(chalk.white(" man <tool> ")+chalk.bold.yellow("★ ")+chalk.gray("How to use a tool (steghide, nmap…); ")+chalk.cyan("man tools")+chalk.gray(" = list. Bare ")+chalk.cyan("man")+chalk.gray(" = this list.")),console.log(),console.log(chalk.bold.white(" System")),console.log(chalk.white(" setup ")+chalk.gray("Configure settings")),console.log(chalk.white(" lang [code] ")+chalk.gray("Switch language (15 supported)")),console.log(chalk.white(" logout ")+chalk.gray("Disconnect")),console.log(chalk.white(" clear ")+chalk.gray("Clear screen")),console.log(chalk.white(" exit ")+chalk.gray("Quit (session saved)")),void console.log()):(console.log(chalk.bold.yellow(" Restricted Mode — activate with a token to unlock all commands")),console.log(),console.log(chalk.white(" activate <token> ")+chalk.gray("Unlock full access")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference")),console.log(chalk.white(" exit ")+chalk.gray("Quit")),void console.log())}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "2.19.356",
3
+ "version": "2.19.358",
4
4
  "description": "ICOA CLI — The world's first CLI-native cyber & AI security olympiad terminal: AI4CTF (Day 1), CTF4AI (Day 2), VLA4CTF (Pioneer Round — embodied AI)",
5
5
  "type": "module",
6
6
  "bin": {