icoa-cli 2.19.291 → 2.19.293

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{mkdtempSync as t,mkdirSync as e,existsSync as o,appendFileSync as s,statSync as i}from"node:fs";import{execFileSync as n}from"node:child_process";import{tmpdir as r,homedir as a,platform as c}from"node:os";import{join as p,delimiter as l}from"node:path";import{getIcoaDir as d,getConfig as u}from"./config.js";import{getRealExamState as h}from"./exam-state.js";const m=["claude","cursor-agent","aider","codex","ollama","llm","cody","continue","windsurf","mods","gemini","q"];function f(t){const e=process.env.PATH||"",o="win32"===c()?(process.env.PATHEXT||".EXE;.CMD;.BAT").split(";"):[""];for(const s of e.split(l))if(s)for(const e of o){const o=p(s,t+e);try{if(i(o).isFile())return!0}catch{}}return!1}export function scanForAIBinaries(){const t=[];for(const e of m)f(e)&&t.push(e);if(f("gh"))try{const e=n("gh",["extension","list"],{encoding:"utf-8",timeout:2e3,stdio:["ignore","pipe","ignore"]});/copilot/i.test(e)&&t.push("gh-copilot")}catch{}return t}const g=[{pattern:/(?:^|[\s|;&`$(])(?:cat|less|more|head|tail|bat)\s+(?:~|\$HOME|\/home\/[^/\s]+|\/Users\/[^/\s]+)/,label:"reads home directory"},{pattern:/\.bash_history|\.zsh_history|\.fish_history|\.python_history/,label:"reads shell history"},{pattern:/(?:^|[\s|;&`$(])(?:find|grep\s+-[rR]\S*|rg|fd|ack)\s+(?:~|\$HOME|\/home|\/Users)/,label:"searches home directory"},{pattern:/(?:^|[\s|;&`$(])(?:claude|cursor-agent|aider|codex|ollama|llm|cody|continue|windsurf|mods|gemini)\b/,label:"invokes AI agent CLI"},{pattern:/(?:^|[\s|;&`$(])gh\s+copilot\b/,label:"invokes gh copilot"},{pattern:/(?:^|[\s|;&`$(])history\b/,label:"inspects shell history"},{pattern:/(?:^|[\s|;&`$(])cd\s+(?:~|\$HOME|\/home|\/Users|\/etc|\/var)/,label:"cd outside exam workspace"}];export function checkShellRisk(t){const e=[];for(const{pattern:o,label:s}of g)o.test(t)&&e.push(s);return e}export function auditIdentity(){const t={},e=u();e.deviceFingerprint&&(t.deviceFingerprint=e.deviceFingerprint);const o=h();return o?.session?.token?t.examToken=o.session.token:e.ctfdUrl&&e.token&&e.userName&&(t.account=e.userName),t}export function logShellAudit(t){const e=h();if(!e)return;const o=JSON.stringify({ts:(new Date).toISOString(),examId:e.session.examId,country:e.session.country,...auditIdentity(),cwd:t.cwd,input:t.input.slice(0,500),riskFlags:t.riskFlags});try{s(p(d(),"exam-audit.log"),`${o}\n`)}catch{}fetch("https://practice.icoa2026.au/api/icoa/exam-audit",{method:"POST",headers:{"Content-Type":"application/json"},body:o,signal:AbortSignal.timeout(3e3)}).catch(()=>{})}export function reportAIBinaryDetection(t){if(0===t.length)return;const e=h(),o=JSON.stringify({ts:(new Date).toISOString(),examId:e?.session.examId??"(pre-start)",country:e?.session.country??"(pre-start)",...auditIdentity(),binaries:t,platform:process.platform});fetch("https://practice.icoa2026.au/api/icoa/exam-ai-binaries",{method:"POST",headers:{"Content-Type":"application/json"},body:o,signal:AbortSignal.timeout(3e3)}).catch(()=>{})}export function createExamWorkspace(e){const o=e.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32);return t(p(r(),`icoa-exam-${o}-`))}const y=p(a(),"icoa-workspace");export function getActiveCwd(){const t=h(),s=t?.session?.workspaceDir;return s&&o(s)?s:(o(y)||e(y,{recursive:!0}),y)}
1
+ import{mkdtempSync as t,mkdirSync as e,existsSync as o,appendFileSync as s,statSync as i}from"node:fs";import{execFileSync as n}from"node:child_process";import{tmpdir as r,homedir as a,platform as c}from"node:os";import{join as p,delimiter as l}from"node:path";import{getIcoaDir as d,getConfig as h}from"./config.js";import{getRealExamState as u}from"./exam-state.js";const m=["claude","cursor-agent","aider","codex","ollama","llm","cody","continue","windsurf","mods","gemini","q","chatgpt","sgpt","aichat","copilot"];function f(t){const e=process.env.PATH||"",o="win32"===c()?(process.env.PATHEXT||".EXE;.CMD;.BAT").split(";"):[""];for(const s of e.split(l))if(s)for(const e of o){const o=p(s,t+e);try{if(i(o).isFile())return!0}catch{}}return!1}export function scanForAIBinaries(){const t=[];for(const e of m)f(e)&&t.push(e);if(f("gh"))try{const e=n("gh",["extension","list"],{encoding:"utf-8",timeout:2e3,stdio:["ignore","pipe","ignore"]});/copilot/i.test(e)&&t.push("gh-copilot")}catch{}return t}const g=[{pattern:/(?:^|[\s|;&`$(!])(?:cat|less|more|head|tail|bat)\s+(?:~|\$HOME|\/home\/[^/\s]+|\/Users\/[^/\s]+)/,label:"reads home directory"},{pattern:/\.bash_history|\.zsh_history|\.fish_history|\.python_history/,label:"reads shell history"},{pattern:/(?:^|[\s|;&`$(!])(?:find|grep\s+-[rR]\S*|rg|fd|ack)\s+(?:~|\$HOME|\/home|\/Users)/,label:"searches home directory"},{pattern:/(?:^|[\s|;&`$(!])(?:claude|cursor-agent|aider|codex|ollama|llm|cody|continue|windsurf|mods|gemini|chatgpt|sgpt|aichat|copilot)\b/,label:"invokes AI agent CLI"},{pattern:/(?:^|[;&|]\s*)!?\s*q\b/,label:"invokes AI agent CLI"},{pattern:/(?:^|[\s|;&`$(!])gh\s+copilot\b/,label:"invokes gh copilot"},{pattern:/(?:^|[\s|;&`$(!])history\b/,label:"inspects shell history"},{pattern:/(?:^|[\s|;&`$(!])cd\s+(?:~|\$HOME|\/home|\/Users|\/etc|\/var)/,label:"cd outside exam workspace"}];export function checkShellRisk(t){const e=[];for(const{pattern:o,label:s}of g)o.test(t)&&e.push(s);return e}export function auditIdentity(){const t={},e=h();e.deviceFingerprint&&(t.deviceFingerprint=e.deviceFingerprint);const o=u();return o?.session?.token?t.examToken=o.session.token:e.ctfdUrl&&e.token&&e.userName&&(t.account=e.userName),t}export function logShellAudit(t){const e=u();if(!e)return;const o=JSON.stringify({ts:(new Date).toISOString(),examId:e.session.examId,country:e.session.country,...auditIdentity(),cwd:t.cwd,input:t.input.slice(0,500),riskFlags:t.riskFlags});try{s(p(d(),"exam-audit.log"),`${o}\n`)}catch{}fetch("https://practice.icoa2026.au/api/icoa/exam-audit",{method:"POST",headers:{"Content-Type":"application/json"},body:o,signal:AbortSignal.timeout(3e3)}).catch(()=>{})}export function reportAIBinaryDetection(t){if(0===t.length)return;const e=u(),o=JSON.stringify({ts:(new Date).toISOString(),examId:e?.session.examId??"(pre-start)",country:e?.session.country??"(pre-start)",...auditIdentity(),binaries:t,platform:process.platform});fetch("https://practice.icoa2026.au/api/icoa/exam-ai-binaries",{method:"POST",headers:{"Content-Type":"application/json"},body:o,signal:AbortSignal.timeout(3e3)}).catch(()=>{})}export function createExamWorkspace(e){const o=e.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32);return t(p(r(),`icoa-exam-${o}-`))}const y=p(a(),"icoa-workspace");export function getActiveCwd(){const t=u(),s=t?.session?.workspaceDir;return s&&o(s)?s:(o(y)||e(y,{recursive:!0}),y)}
@@ -1 +1 @@
1
- (function(a,b){const v=a0b,c=a();while(!![]){try{const d=-parseInt(v(0xc5))/(-0x1a06+0x1e4e+-0x447)*(-parseInt(v(0xcb))/(0x110+-0x4c1*0x7+0x2039*0x1))+-parseInt(v(0xba))/(-0x160d+0x26e+0x13a2)*(parseInt(v(0xc9))/(-0x22*-0x4d+-0x12d2+0x89c*0x1))+parseInt(v(0xb9))/(0x2*0x20b+0x1669+-0x1a7a)+parseInt(v(0xcc))/(-0x1*-0x1a1+-0x119b+0x1000)*(-parseInt(v(0xbc))/(-0x1f0d*0x1+-0x6*0x59f+0x40ce))+parseInt(v(0xbb))/(0xfcf+-0x3e6*0xa+0x1735)*(parseInt(v(0xc4))/(-0x1a*0x158+-0x4e6+0x27df))+-parseInt(v(0xbf))/(0x1940+0x2177+-0x138f*0x3)+parseInt(v(0xc3))/(-0x454+0x2e*-0x1a+0x90b)*(parseInt(v(0xcd))/(0x10*-0xd7+-0x17*0x6d+0x1747));if(d===b)break;else c['push'](c['shift']());}catch(e){c['push'](c['shift']());}}}(a0a,0x3107*0x25+-0x17*-0x2cf3+0x16242));function a0b(a,b){a=a-(-0x2*0x144+0x4*-0x815+0x7*0x515);const c=a0a();let d=c[a];if(a0b['chPdJE']===undefined){var e=function(i){const j='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let l='',m='';for(let n=-0xf7*-0x1a+0x1*0x181d+0x9d7*-0x5,o,p,q=0x130d*0x2+0x23bc+-0x49d6;p=i['charAt'](q++);~p&&(o=n%(-0x2bb*-0x9+0x32*-0x17+0xb*-0x1d3)?o*(0x1fce+-0x12d*-0x15+0x77*-0x79)+p:p,n++%(0x176a+-0x10a*-0xa+-0xad*0x32))?l+=String['fromCharCode'](-0x1*-0x44c+-0x1764+0x1417*0x1&o>>(-(0x2405+0x24d7*0x1+0x32*-0x175)*n&-0x95f+0x5b2+0x3b3*0x1)):-0x1f49*-0x1+-0x1c*-0x147+-0x430d){p=j['indexOf'](p);}for(let r=-0x873+0x3*0xc77+-0x1cf2,s=l['length'];r<s;r++){m+='%'+('00'+l['charCodeAt'](r)['toString'](-0x1ab0*0x1+0x89a*0x3+0xf2))['slice'](-(-0x846*0x1+0xe83*0x1+-0x63b));}return decodeURIComponent(m);};a0b['KeWgUA']=e,a0b['KOgbwO']={},a0b['chPdJE']=!![];}const f=c[0x2*-0x109d+-0xac4+0x2bfe],g=a+f,h=a0b['KOgbwO'][g];return!h?(d=a0b['KeWgUA'](d),a0b['KOgbwO'][g]=d):d=h,d;}import{getConfig as a0c}from'./config.js';function a0a(){const x=['yxbWBgLJyxrPB24VANnVBG','odK0mtC5mezYwxPrzG','AgLUDcbbueKGDw5YzwfJAgfIBgu','CxvLC3rPB24','C3rHDhvZ','ndy0ndm2nxb0zLjxyq','ovLqtfbduG','mtqXnKjnDerIEa','oJKWotaVyxbPl2LJB2eVzxHHBxmV','zxHHBuLK','BwvZC2fNzq','ntC0mZq2oePhEgLswq','AwnVys1JBgK','nJe2ufnvwfnN','mJuWotCYmLfJvfP0za','ndHiwNntuMC','Bgv2zwW','C3vJy2vZCW','AgLUDcbYzxf1zxn0igzHAwXLzcaO','l2fWAs9Py29Hl2v4yw1ZlW','BgfUz3vHz2u','BMv0D29YAYbLCNjVCG','l2HPBNq','y2f0y2G','mZy4mZCZmgfsvND1sG','m1LWD3vzEa','mtiZndmYodHUDgXIr08','mJfZvuT5AMS','ue9tva'];a0a=function(){return x;};return a0a();}export async function requestHint(d){const w=a0b,f=a0c(),g=f['ctfdUrl']||'https://practice.icoa2026.au',h=d['lang']||f[w(0xd2)]||'en',j=d['timeoutMs']??-0x2de*-0xe+0x53*0x77+0x2f79*-0x1,k=[g+w(0xd1)+d[w(0xc7)]+w(0xb7),g+w(0xc6)+d[w(0xc7)]+w(0xb7)];let l=null;for(const p of k)try{const q=await fetch(p,{'method':w(0xbd),'headers':{'Content-Type':w(0xbe),'User-Agent':w(0xca)},'body':JSON['stringify']({'token':d['token'],'question':d[w(0xc1)],'level':d[w(0xce)],'lang':h}),'signal':AbortSignal['timeout'](j)}),r=await q['json']()[w(0xb8)](()=>({}));if(!q['ok']||!(0x130d*0x2+0x23bc+-0x49d5)===r[w(0xcf)]){if(l={'status':q[w(0xc2)],'message':r?.[w(0xc8)]||w(0xd0)+q[w(0xc2)]+')'},q['status']>=-0x2bb*-0x9+0x32*-0x17+0xb*-0x1af&&q[w(0xc2)]<0x1fce+-0x12d*-0x15+0x1*-0x368b)throw l;continue;}return r['data'];}catch(u){if(u&&'object'==typeof u&&w(0xc2)in u)throw u;l={'status':0x0,'message':u?.[w(0xc8)]||w(0xd3)};}const m={};m[w(0xc2)]=0x0,m[w(0xc8)]=w(0xc0);throw l||m;}
1
+ (function(a,b){const v=a0b,c=a();while(!![]){try{const d=-parseInt(v(0xc6))/(-0x2*-0x66a+-0x772*0x4+-0x10f5*-0x1)+-parseInt(v(0xbc))/(-0x35*-0x61+-0x4*0x2a1+-0x1*0x98f)*(-parseInt(v(0xae))/(0x2593+-0x22a0+-0x2f0))+parseInt(v(0xc0))/(0x8*-0x140+-0xd*-0x277+0x1607*-0x1)*(parseInt(v(0xbd))/(0xbd*0x30+0x26f6*-0x1+0x38b))+parseInt(v(0xb6))/(-0x1*-0x26c9+0x14da+-0x3b9d)*(-parseInt(v(0xc8))/(0x1*-0x779+-0x2552+0x2cd2))+-parseInt(v(0xb0))/(0x2*-0x3c1+-0x35e+0x1*0xae8)+-parseInt(v(0xcb))/(0x1b2+-0x1*-0x171+-0x18d*0x2)+parseInt(v(0xaf))/(-0x24c9+0x351+0x2182)*(parseInt(v(0xc2))/(-0x16ec+-0x9b1+0x20a8));if(d===b)break;else c['push'](c['shift']());}catch(e){c['push'](c['shift']());}}}(a0a,0x3bc05*0x2+0x404e4+-0x6f6eb));function a0b(a,b){a=a-(0x376*-0x1+-0x561+0x4c2*0x2);const c=a0a();let d=c[a];if(a0b['JRjqGP']===undefined){var e=function(i){const j='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let l='',m='';for(let n=0x21f3+0x2191+0x10e1*-0x4,o,p,q=0xc8e+0x1*-0x26a7+0x1a19;p=i['charAt'](q++);~p&&(o=n%(0x2183+-0x30e+-0x1e71)?o*(0xa97*0x2+-0x1*-0x1d34+-0x3222)+p:p,n++%(-0xc50+-0x14a*-0xe+0x6*-0xf4))?l+=String['fromCharCode'](0x467*-0x5+-0x25e3+0x3ce5&o>>(-(-0x9*0x3ad+0x158*-0x8+0x2bd7*0x1)*n&0x199*-0x18+-0x214f*0x1+0x47ad)):-0x4*0x3d7+-0x712+0x166e){p=j['indexOf'](p);}for(let r=0x8db*-0x3+0x11*-0x233+-0xffd*-0x4,s=l['length'];r<s;r++){m+='%'+('00'+l['charCodeAt'](r)['toString'](0xd9b+0x484+-0x120f))['slice'](-(0x2694+0xce5*0x1+-0x3377));}return decodeURIComponent(m);};a0b['URBhPB']=e,a0b['mPgOia']={},a0b['JRjqGP']=!![];}const f=c[0x1afe+0x1273+0x1*-0x2d71],g=a+f,h=a0b['mPgOia'][g];return!h?(d=a0b['URBhPB'](d),a0b['mPgOia'][g]=d):d=h,d;}import{getConfig as a0c}from'./config.js';function a0a(){const x=['C3vJy2vZCW','y3rMzfvYBa','mNjRDMLItq','nZbTufLYuK0','Ahr0Chm6lY9WCMfJDgLJzs5Py29HmJaYnI5HDq','C3rYAw5NAwz5','mtq3otu2rhf5B1Pj','l2fWAs9Py29Hl2v4yw1ZlW','mJjttwjLy24','l2HPBNq','y2f0y2G','BMv0D29YAYbLCNjVCG','ntC1mdq4uwLNChzq','DgLTzw91Da','n2z5u3vpEa','CxvLC3rPB24','AgLUDcbYzxf1zxn0igzHAwXLzcaO','nduXodK3mKvWsejeqq','BgfUzW','mtq3nJmWou9hsKrTsG','mZeWodGZmhDwshjusG','mtyZnJe3nLf3vLLAqG','BwvZC2fNzq','Dg9Rzw4','DgLTzw91De1Z','Bgv2zwW','yxbWBgLJyxrPB24VANnVBG','mZiXnte2D25pthbw','ANnVBG','C3rHDhvZ','AgLUDcbbueKGDw5YzwfJAgfIBgu'];a0a=function(){return x;};return a0a();}export async function requestHint(d){const w=a0b,f=a0c(),g=f[w(0xbb)]||w(0xbe),h=d[w(0xad)]||f['language']||'en',j=d[w(0xb3)]??0x35b4+0x69f*-0x5+-0xaa7*-0x1,k=[g+w(0xc1)+d['examId']+w(0xc3),g+':9090/api/icoa/exams/'+d['examId']+w(0xc3)];let l=null;for(const p of k)try{const q=await fetch(p,{'method':'POST','headers':{'Content-Type':w(0xb5),'User-Agent':'icoa-cli'},'body':JSON[w(0xbf)]({'token':d[w(0xb2)],'question':d[w(0xc9)],'level':d[w(0xb4)],'lang':h}),'signal':AbortSignal[w(0xc7)](j)}),r=await q[w(0xb7)]()[w(0xc4)](()=>({}));if(!q['ok']||!(-0x1ab1*0x1+-0x1*-0x20dd+-0x62b)===r[w(0xba)]){if(l={'status':q['status'],'message':r?.['message']||w(0xca)+q[w(0xb8)]+')'},q[w(0xb8)]>=0x1d6*-0xa+0xb0*-0x28+-0x1*-0x2f6c&&q[w(0xb8)]<-0x3f5*0x9+-0x314*0x4+0x1*0x31e1)throw l;continue;}return r['data'];}catch(u){if(u&&'object'==typeof u&&w(0xb8)in u)throw u;l={'status':0x0,'message':u?.['message']||w(0xc5)};}const m={};m['status']=0x0,m[w(0xb1)]=w(0xb9);throw l||m;}
@@ -0,0 +1,11 @@
1
+ export interface ToolDoc {
2
+ name: string;
3
+ aliases?: string[];
4
+ cat: string;
5
+ summary: string;
6
+ /** [command, note] — real CTF invocations */
7
+ ex: Array<[string, string]>;
8
+ }
9
+ export declare const TOOL_DOCS: ToolDoc[];
10
+ /** Render `man <query>`: empty/"tools"/"list" → index; a tool → its sheet; else nearest hints. */
11
+ export declare function renderToolMan(query: string): void;
@@ -0,0 +1 @@
1
+ import chalk from"chalk";export const TOOL_DOCS=[{name:"file",cat:"Forensics",summary:"identify a file type (always step 1)",ex:[["file mystery","what is this really? (extension lies)"]]},{name:"strings",cat:"Forensics",summary:"pull printable text out of any binary",ex:[["strings -n 8 bin","runs ≥8 chars (cuts noise)"],["strings bin | grep -i flag","hunt the flag directly"],["strings -e l bin","16-bit little-endian (wide) strings"]]},{name:"xxd",cat:"Data",summary:"hex dump / reverse hex back to bytes",ex:[["xxd file | head","inspect magic bytes / header"],["xxd -r hex.txt out.bin","rebuild a file from a hex dump"],["xxd -s 0x100 -l 64 file","dump 64 bytes from offset 0x100"]]},{name:"hexdump",aliases:["od"],cat:"Data",summary:"byte/octal dump (od is the BSD cousin)",ex:[["hexdump -C file | head","canonical hex+ASCII view"],["od -An -tx1 file","raw hex bytes, no offsets"]]},{name:"binwalk",cat:"Forensics",summary:"find + extract files embedded in files",ex:[["binwalk file","scan for embedded signatures"],["binwalk -e file","auto-extract everything it finds"],['binwalk --dd=".*" file',"carve every match (greedy)"]]},{name:"foremost",cat:"Forensics",summary:"carve files by header (recover deleted/hidden)",ex:[["foremost -i disk.img -o out/","recover into out/ by type"]]},{name:"steghide",cat:"Forensics",summary:"hide/extract data in JPG/BMP/WAV/AU (passphrase)",ex:[["steghide info cat.jpg","is anything embedded?"],["steghide extract -sf cat.jpg","pull it out (asks passphrase; blank often works)"]]},{name:"exiftool",cat:"Forensics",summary:"read/write image & doc metadata (flags hide here)",ex:[["exiftool pic.png","dump all metadata"],["exiftool -Comment pic.png","one specific tag"]]},{name:"pngcheck",cat:"Forensics",summary:"validate PNG chunks (find tampering / appended data)",ex:[["pngcheck -v flag.png","verbose chunk-by-chunk check"]]},{name:"pdftotext",cat:"Data",summary:"extract text (and hidden layers) from a PDF",ex:[["pdftotext doc.pdf -","print extracted text to stdout"]]},{name:"sleuthkit",aliases:["mmls","fls","icat","tsk"],cat:"Forensics",summary:"disk-image forensics (partition → files → recover)",ex:[["mmls disk.img","list partitions + offsets"],["fls -o 2048 -r disk.img","list files (use the partition offset)"],["icat -o 2048 disk.img 12 > out","dump file by inode number"]]},{name:"volatility3",aliases:["vol","volatility"],cat:"Forensics",summary:"memory-dump analysis",ex:[["vol -f mem.raw windows.pslist","list processes"],["vol -f mem.raw windows.cmdline","recover command lines"]]},{name:"openssl",cat:"Crypto",summary:"swiss-army crypto (decode, hash, enc/dec, certs)",ex:[["openssl enc -d -aes-256-cbc -in f -k pass","decrypt AES"],["openssl x509 -in cert.pem -text -noout","read a certificate"],["echo -n txt | openssl dgst -sha256","hash it"]]},{name:"john",aliases:["john-the-ripper"],cat:"Crypto",summary:"crack password hashes (CPU)",ex:[["john --wordlist=rockyou.txt hashes","dictionary attack"],["zip2john x.zip > h ; john h","crack a zip password"],["john --show hashes","print cracked results"]]},{name:"hashcat",cat:"Crypto",summary:"fast hash cracker (modes by -m)",ex:[["hashcat -m 0 -a 0 hash rockyou.txt","MD5 dictionary (-m 0 = MD5)"]]},{name:"gpg",cat:"Crypto",summary:"PGP decrypt / symmetric decrypt",ex:[["gpg -d secret.gpg","decrypt (prompts for passphrase/key)"]]},{name:"base64",aliases:["base32"],cat:"Data",summary:"decode/encode base64 (base32 alike)",ex:[["echo -n SGk= | base64 -d","decode"],["base64 -d f.txt","decode a file blob"]]},{name:"nmap",cat:"Networking",summary:"port/service scan a target host",ex:[["nmap -sV -p- host","all ports + version detection"],["nmap -sC -p 80,443 host","default scripts on web ports"]]},{name:"nc",aliases:["netcat","ncat"],cat:"Networking",summary:"raw TCP/UDP connect (talk to a service)",ex:[["nc host 1337","connect to a challenge service"],["nc -lvnp 4444","listen (catch a callback)"]]},{name:"socat",cat:"Networking",summary:"flexible socket relay (TLS, pty, bridging)",ex:[["socat - OPENSSL:host:443","connect over TLS interactively"]]},{name:"curl",cat:"Web",summary:"HTTP client — the web-CTF workhorse",ex:[["curl -i url","show response headers"],['curl -b "session=..." url',"send a cookie"],['curl -X POST -d "a=1" url',"POST form data"]]},{name:"wget",cat:"Web",summary:"download files / mirror a site",ex:[["wget -r url","recursive download"]]},{name:"tshark",aliases:["wireshark-cli"],cat:"Networking",summary:"CLI Wireshark — read/filter pcaps",ex:[["tshark -r cap.pcap -Y http","show only HTTP packets"],["tshark -r cap.pcap -T fields -e data","dump a field across packets"]]},{name:"tcpdump",cat:"Networking",summary:"capture/read packets (pcap)",ex:[["tcpdump -r cap.pcap -A","print packets as ASCII"]]},{name:"dig",aliases:["whois"],cat:"Networking",summary:"DNS lookups (whois = registration data)",ex:[["dig TXT domain","read TXT records (flags hide here)"],["whois domain","ownership info"]]},{name:"sqlmap",cat:"Web",summary:"automated SQL-injection exploitation",ex:[['sqlmap -u "url?id=1" --dbs',"enumerate databases"],["sqlmap -u url --dump -T users","dump a table"]]},{name:"radare2",aliases:["r2"],cat:"Reverse Engineering",summary:"interactive RE framework (disasm/debug)",ex:[["r2 -A bin","open + auto-analyze"],["(in r2) afl ; pdf @ main","list funcs; disasm main"]]},{name:"rabin2",cat:"Reverse Engineering",summary:"binary info (radare2 family)",ex:[["rabin2 -z bin","list strings + offsets"],["rabin2 -I bin","arch/bits/protections"]]},{name:"objdump",cat:"Reverse Engineering",summary:"disassemble / inspect object files",ex:[["objdump -d -M intel bin","Intel-syntax disassembly"]]},{name:"readelf",cat:"Reverse Engineering",summary:"ELF header / sections / symbols",ex:[["readelf -a bin","everything"],["readelf -d bin","dynamic section / RPATH"]]},{name:"gdb",aliases:["pwndbg"],cat:"Debuggers",summary:"debugger (pwndbg plugin preloaded for pwn)",ex:[["gdb ./bin","start; then: break main / run / info registers"],["(pwndbg) checksec","show binary mitigations"],["(pwndbg) cyclic 200","gen pattern to find offset"]]},{name:"ltrace",aliases:["strace"],cat:"Debuggers",summary:"trace library (ltrace) / syscalls (strace)",ex:[["ltrace ./bin","watch libc calls (e.g. strcmp the flag)"],["strace ./bin","watch syscalls"]]},{name:"upx",cat:"Reverse Engineering",summary:"un/pack executables",ex:[["upx -d packed","unpack before analyzing"]]},{name:"pwntools",aliases:["pwn"],cat:"CTF Core",summary:"Python exploit framework (+ pwn CLI)",ex:[["pwn checksec ./bin","show mitigations"],["pwn cyclic 100 / pwn cyclic -l 0x6161","pattern + find offset"],['python3: from pwn import *; p=process("./bin")',"scripting entrypoint"]]},{name:"ROPgadget",aliases:["ropper"],cat:"Binary & RE",summary:"find ROP gadgets in a binary",ex:[['ROPgadget --binary bin | grep "pop rdi"',"find a gadget"],['ropper -f bin --search "pop rdi"',"ropper equivalent"]]},{name:"jq",cat:"Data",summary:"slice/query JSON",ex:[["curl url | jq .","pretty-print"],['jq -r ".data[].flag" f.json',"extract a field"]]},{name:"sqlite3",cat:"Data",summary:"open/query a SQLite DB file",ex:[['sqlite3 app.db ".tables"',"list tables"],['sqlite3 app.db "select * from users"',"query"]]}];const e=new Map;for(const a of TOOL_DOCS){e.set(a.name.toLowerCase(),a);for(const s of a.aliases??[])e.set(s.toLowerCase(),a)}export function renderToolMan(a){const s=(a||"").trim().toLowerCase();if(!s||"tools"===s||"list"===s||"all"===s)return void function(){const e=new Map;for(const a of TOOL_DOCS){const s=a.cat;e.has(s)||e.set(s,[]),e.get(s).push(a)}console.log(),console.log(chalk.bold.yellow(" ★ Tool cheatsheet")+chalk.gray(" — type ")+chalk.cyan("man <tool>")+chalk.gray(" for usage, e.g. ")+chalk.cyan("man steghide")),console.log();for(const[a,s]of e)console.log(" "+chalk.bold.white(a)),console.log(" "+chalk.cyan(s.map(e=>e.name).join(" ")));console.log(),console.log(chalk.gray(" These are the frozen sandbox tools — no pip/apt install. ")+chalk.cyan("env")+chalk.gray(" shows what is installed.")),console.log()}();const t=e.get(s);if(t)return void function(e){const a=e.aliases?.length?chalk.gray(" ("+e.aliases.join(", ")+")"):"";console.log(),console.log(" "+chalk.bold.cyan(e.name)+a+chalk.gray(" · "+e.cat)),console.log(" "+chalk.white(e.summary)),console.log();for(const[a,s]of e.ex)console.log(" "+chalk.cyan(a)),console.log(" "+chalk.gray(s));console.log(),console.log(chalk.gray(" More: ")+chalk.cyan("man tools")+chalk.gray(" · not a real judge — verify your own output.")),console.log()}(t);const n=[...e.keys()],o=n.filter(e=>e.startsWith(s)).concat(n.filter(e=>e.includes(s)&&!e.startsWith(s))),r=[...new Set(o.map(a=>e.get(a).name))].slice(0,5);console.log(),console.log(chalk.yellow(` No cheatsheet for "${a}".`)),r.length&&console.log(chalk.gray(" Did you mean: ")+chalk.cyan(r.join(" "))+"?"),console.log(chalk.gray(" Type ")+chalk.cyan("man tools")+chalk.gray(" for the full list.")),console.log()}
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{isActivated as s,activateToken as r,isFreeCommand as i,isDeviceMatch as c,recordExit as g,recordResume as y,isFirstRunOrUpgrade as m,markVersionSeen as d}from"./lib/access.js";import{setReplMode as p}from"./lib/ui.js";import{returnToMainMenu as u,printMenuHint as h,menuHintInline as w}from"./lib/menu-nav.js";import{setMainRl as f}from"./lib/main-rl.js";import{isChatActive as b,handleChatMessage as x}from"./commands/ai4ctf.js";import{isCtf4aiActive as v,handleCtf4aiMessage as A}from"./commands/ctf4ai-demo.js";import{isCtf4VlaActive as C,handleCtf4VlaMessage as I}from"./commands/ctf4vla.js";import{isDemo2Active as k}from"./commands/demo2.js";import{loadDemo2Progress as T}from"./lib/demo2-progress.js";import{hasAnySimHistory as E,lastArmAt as S,lastBundledAt as $,lastSimAt as O}from"./lib/sim-cooldown.js";import{getExamState as D,getRealExamState as L,getDemoState as R,practicalChatCommand as j}from"./lib/exam-state.js";import{resetTerminalTheme as q}from"./lib/theme.js";import{ensureSandbox as N,runInSandbox as P,isDockerAvailable as F}from"./lib/sandbox.js";import{checkShellRisk as M,logShellAudit as B,getActiveCwd as _}from"./lib/exam-sandbox.js";import{logCommand as Q}from"./lib/logger.js";import{startLogSync as U,stopLogSync as W}from"./lib/log-sync.js";import{existsSync as X,mkdirSync as Y,writeFileSync as z}from"node:fs";import{join as G}from"node:path";import{homedir as V}from"node:os";const J=Date.now();function H(){return L()?chalk.cyan("icoa exam> "):function(){const o=R();return!(!o||"demo-free"!==o.session?.examId)&&new Date(o.session.startedAt||0).getTime()>=J}()?chalk.yellow("icoa demo> "):chalk.green("icoa> ")}const K=G(V(),"icoa-workspace"),Z=new Set(["sudo","su","doas","pkexec","brew","apt","apt-get","yum","choco","npm","npx","pip","pip3","shutdown","reboot","halt","mkfs","fdisk","dd","iptables","ufw"]),oo="__REPL_NO_EXIT__",eo="2.5.1";function lo(){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,R){process.env.ICOA_INSIDE_REPL="1";const J=t(),ao=n(),so=process.exit.bind(process),ro=s();if(J.demoCleanedForVersion!==eo){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:eo})}const{select:io,confirm:co}=await import("@inquirer/prompts"),go=J.mode||"",yo=""===go?"instant":["instant","learn","selection","olympiad"].includes(go)?go:"selection",mo=[{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 po="";for(;!po;){let o;try{o=await io({message:"Mode",choices:mo,default:yo||"instant"})}catch(o){throw o instanceof Error&&"ExitPromptError"===o.name&&(console.log(),console.log(chalk.gray(" Goodbye.")),process.exit(0)),o}"about"!==o?po=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"===po&&"olympiad"!==yo){console.log(),console.log(chalk.yellow(" This mode will download ~500MB of CTF tools and AI models."));let o=!0;try{o=await co({message:"Continue?",default:!0})}catch(e){if(!(e instanceof Error&&"ExitPromptError"===e.name))throw e;o=!1}o||(po="selection",console.log(chalk.gray(" Switched to National Selection mode.")))}if(po!==yo&&a({mode:po}),console.log(),"olympiad"===po&&m(eo)){d(eo),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(R){const o=y();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"===po)console.log(chalk.gray(" ─── exam hall · 90 min per paper once started · no pause ───")),console.log(),lo();else if("embodied"===po)!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=$()>0||O()>0,e=S()>0,l=E(),n=T(),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(),h(),console.log()}();else if("instant"===po)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"}),po="selection";else{if("learn"===po){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 u()}"organizer"===po?(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(),ao?(console.log(chalk.green(` Logged in as ${J.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(),h(),console.log()):(console.log(` ${chalk.cyan.bold("🏆 ICOA 2026 · International Olympiad")}`),console.log(),ro&&!c()?(console.log(chalk.red(" Token was activated on a different device.")),console.log(chalk.gray(" Contact organizer for assistance.")),console.log()):ao?(console.log(chalk.green.bold(` Welcome back, ${J.userName}!`)),console.log(chalk.gray(` Connected to ${J.ctfdUrl}`)),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 & hint budget")),console.log(chalk.white(" scoreboard")+chalk.gray(" Live rankings")),console.log(chalk.white(" help")+chalk.gray(" Full command list")),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.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("help")+chalk.gray(" · ")+w()+chalk.gray(" · ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+chalk.cyan("quit")+chalk.gray(" closes")),console.log()):ro?(X(K)||Y(K,{recursive:!0}),console.log(chalk.green.bold(" Welcome, competitor!")),console.log(chalk.gray(` Workspace: ${K}`)),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(),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 · ")+w()+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 · ")+w()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()))}e.exitOverride(),e.configureOutput({writeErr:()=>{},writeOut:o=>{console.log(o)}});const uo=o({input:process.stdin,output:process.stdout,prompt:H(),terminal:!0});f(uo);let ho=!1;p(!0),U();const wo=uo.prompt.bind(uo);uo.prompt=o=>{b()||v()||C()||k()||uo.setPrompt(H()),wo(o)},uo.prompt(),uo.on("line",async o=>{if(ho)return;const n=o.trim();if(!n)return uo.setPrompt(b()?chalk.magenta("icoa ai4ctf> "):H()),void uo.prompt();if("menu"===n||"menu confirm"===n)return L()&&"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 uo.prompt()):void u(uo);if(b()){ho=!0;const o=await x(n);return ho=!1,"exit"===o&&uo.setPrompt(H()),void uo.prompt()}if(v()){ho=!0;const o=await A(n);return ho=!1,"exit"!==o&&"solved"!==o||uo.setPrompt(H()),void uo.prompt()}if(C()){ho=!0;const o=await I(n);return ho=!1,"exit"===o&&uo.setPrompt(H()),uo.setPrompt(C()?chalk.bold.cyan("icoa ctf4eai> "):H()),void uo.prompt()}if(Q(n),"exit"===n)return D()?(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 uo.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"===po&&lo(),void uo.prompt());if("quit"===n||"q"===n||"quit confirm"===n){const o=D();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 uo.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)."))),W(),g(),console.log(chalk.gray(" Session saved. Use ")+chalk.white("icoa --resume")+chalk.gray(" to continue.")),q(),void so(0))}if("back"===n){const o=D(),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"===po?lo():console.log(chalk.gray(" Already at main menu."))}return void uo.prompt()}if("help"===n||"?"===n){if(D()){ho=!0;try{await e.parseAsync(["node","icoa","exam","help"])}catch{}return ho=!1,void uo.prompt()}return to(s(),po),void uo.prompt()}if("man"===n||"manual"===n)return to(s(),po),void uo.prompt();if("more help"===n.toLowerCase()&&D()){ho=!0;try{await e.parseAsync(["node","icoa","exam","more-help"])}catch{}return ho=!1,void uo.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 competition, you get AI help at 3 levels:")),console.log(chalk.yellow(" hint a")+chalk.gray(" General guidance (50 uses)")),console.log(chalk.yellow(" hint b")+chalk.gray(" Deep analysis (10 uses)")),console.log(chalk.yellow(" hint c")+chalk.gray(" Critical assist (2 uses)")),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 uo.prompt();if(/^ICOA-[A-Z]{2,3}-\d{1,6}$/i.test(n.trim())){ho=!0;try{await e.parseAsync(["node","icoa","exam","token",n.trim()])}catch{}return ho=!1,void uo.prompt()}if(/^[A-Z]{2}[0-9A-HJKMNP-TV-Z]{8}$/i.test(n.trim())){ho=!0;try{await e.parseAsync(["node","icoa","exam","token",n.trim().toUpperCase()])}catch{}return ho=!1,void uo.prompt()}const a=n.match(/^exam\s+([A-Z]{2}[0-9A-HJKMNP-TV-Z]{8})$/i);if(a){ho=!0;try{await e.parseAsync(["node","icoa","exam","token",a[1].toUpperCase()])}catch{}return ho=!1,void uo.prompt()}const y=n.match(/^exam\s+([A-Z]{2,3})$/i);if(y){ho=!0;try{await e.parseAsync(["node","icoa","exam","list",y[1]])}catch{}return ho=!1,void uo.prompt()}if("clear"===n||"cls"===n)return console.clear(),void uo.prompt();if(n.startsWith("activate ")){const o=n.slice(9).trim(),e=r(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 uo.prompt()}if("activate"===n)return console.log(chalk.gray(" Usage: ")+chalk.white("activate <token>")),console.log(),void uo.prompt();const m=D();if(m){const o=n.toUpperCase().trim(),l=o=>{const e=m.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=m.questions.find(e=>e.number===o);return"short_answer"===e?.type},a=o=>{const e="demo-free"!==m.session.examId,l=m.questions.find(e=>e.number===o),n=j(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=m._lastQ||1;if(l(n))return a(n),void uo.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 uo.prompt();ho=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(n),o])}catch{}return ho=!1,void uo.prompt()}if(/^-?\d+$/.test(o)){const l=m._lastQ||1;if(t(l)){ho=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(l),o])}catch{}return ho=!1,void uo.prompt()}}const s=o.match(/^(\d+)\s+([ABCDE]|-?\d+)$/);if(s){const o=parseInt(s[1],10);if(l(o))return a(o),void uo.prompt();ho=!0;try{await e.parseAsync(["node","icoa","exam","answer",s[1],s[2]])}catch{}return ho=!1,void uo.prompt()}}const d=n.split(/\s+/)[0].toLowerCase(),p=/^python3?(\.\d+)?$/.test(d),h="ls"===d||"pwd"===d,w=n.startsWith("!")||d.startsWith("!")||p||h,f=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"]),k=()=>{console.log(chalk.gray(" Shell commands need ")+chalk.bold.cyan("!")+chalk.gray(" prefix. Try: ")+chalk.bold.cyan(`!${n}`)),console.log()};if("embodied"===po&&!w&&!["demo2","learn","exam","ctf4eai","ctf4vla","lang","ref","setup","env","aienv","ipynb","sim"].includes(d))return f.has(d)?(k(),void uo.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 uo.prompt());if("selection"===po&&!w&&!["exam","demo","demo2","retry","nations","next","prev","continue","setup","lang","ref","ai4ctf","ctf4ai","mark","unmark","review","submit","env","aienv","ipynb","sim"].includes(d)){if(f.has(d))return k(),void uo.prompt();if(console.log(chalk.gray(" Not available in Selection mode.")),m){const o=m._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 uo.prompt()}if("organizer"===po&&!["join","exam","demo","retry","next","prev","logout","setup","lang","ref","ctf","mark","unmark","review","submit"].includes(d))return console.log(chalk.gray(" Not available in Organizer mode. Switch via: setup")),console.log(),void uo.prompt();if(!("olympiad"!==po||s()&&c()||i(d)))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 uo.prompt();if(!["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","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"].includes(d)){if(Z.has(d))return console.log(chalk.yellow(` "${d}" 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 uo.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: ${K}`)),console.log(),void uo.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=_(),t=M(n);B({cwd:e,input:n,riskFlags:t}),t.length>0&&L()&&(console.log(chalk.yellow(` ⚠ Action flagged: ${t.join(", ")} — logged.`)),console.log()),/^(\S*python3?(\.\d+)?)\s*$/.test(o)&&(o=`PYTHONSTARTUP="${function(){const o=G(V(),".icoa");X(o)||Y(o,{recursive:!0});const e=G(o,"python-startup.py");return X(e)||z(e,"# 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\n"),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, 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()),ho=!0;try{F()&&await N()?await P(o,uo):await no(o,uo,e)}catch{console.log(chalk.yellow(` Command failed: ${d}`))}return ho=!1,console.log(),void uo.prompt()}ho=!0;const T=n.trim(),E=T.toLowerCase();let S,$=null,O="";if(m)if("submit"===E)$="final";else if(E.startsWith("submit ")){let o=T.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)?($="flag",O=o):o&&/^[ABCDE]$/i.test(o)&&($="flag",O=o.toUpperCase())}else/^ICOA\{[^}]+\}$/i.test(T)&&($="flag",O=T);S="final"===$?["exam","submit"]:"flag"===$?["exam","answer",String(m?._lastQ||1),O]:function(o){const e=o.split(/\s+/),l=e[0].toLowerCase(),n=e.slice(1);if(("submit"===l||"flag"===l)&&n.length>=2)return["ctf","submit",n[0],n.slice(1).join(" ").trim().replace(/^["'`]+|["'`]+$/g,"")];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","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","ai4ctf","model","ctf","exam","ctf4ai"].includes(l)?[l,...n]:e}(n);const R="ctf"===S[0]&&"join"===S[1];R&&uo.pause(),process.exit=()=>{throw new Error(oo)};try{await e.parseAsync(["node","icoa",...S])}catch(o){const e=o instanceof Error?o.message:String(o);if(e===oo);else if(e.includes("commander.unknownCommand")){const{distance:o}=await import("fastest-levenshtein"),e=["ctf","ref","shell","files","view","connect","note","notes","logbook","log","manual","lang","setup","env","aienv","ipynb","ai4ctf","exam","ctf4ai","theme","clear","cls","quit","exit","back","menu","help","continue","activate","demo","challenges","status","scoreboard","join","logout"],l=d.split(/\s+/)[0]||d;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: ${d}.`)),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"===d||"flag"===d?(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: ${d}`)),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=so,ho=!1,R&&uo.resume()}b()?uo.setPrompt(chalk.magenta("icoa ai4ctf> ")):v()?uo.setPrompt(chalk.red("icoa ctf4ai> ")):C()&&uo.setPrompt(chalk.bold.cyan("icoa ctf4eai> ")),console.log(),uo.prompt()}),uo.on("SIGINT",()=>{if(console.log(),b()||v())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(D()){const o="demo-free"!==D().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(),uo.prompt()}),uo.on("close",()=>{W(),g(),q(),so(0)})}function no(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 to(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, budget & timer")),console.log(chalk.white(" time ")+chalk.gray("Countdown timer")),console.log(),console.log(chalk.bold.white(" AI Teammate")+chalk.gray(" — 3 levels, use wisely")),console.log(chalk.white(' hint "question" ')+chalk.gray("Level A — General guidance (50 uses)")),console.log(chalk.white(' hint-b "question" ')+chalk.gray("Level B — Deep analysis (10 uses)")),console.log(chalk.white(' hint-c "question" ')+chalk.gray("Level C — Critical assist (2 uses)")),console.log(chalk.white(" hint budget ")+chalk.gray("Check remaining uses")),console.log(chalk.white(" ai4ctf ")+chalk.gray("Free-chat with AI (no limit)")),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("Docker sandbox")),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 / manual ")+chalk.gray("Show this command list (works in exam too, does not burn elimination)")),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 l}from"node:child_process";import chalk from"chalk";import{isConnected as n,getConfig as t,saveConfig as a}from"./lib/config.js";import{isActivated as s,activateToken as r,isFreeCommand as i,isDeviceMatch as c,recordExit as g,recordResume as y,isFirstRunOrUpgrade as m,markVersionSeen as d}from"./lib/access.js";import{setReplMode as p}from"./lib/ui.js";import{returnToMainMenu as u,printMenuHint as h,menuHintInline as w}from"./lib/menu-nav.js";import{setMainRl as f}from"./lib/main-rl.js";import{isChatActive as b,handleChatMessage as x}from"./commands/ai4ctf.js";import{renderToolMan as v}from"./lib/tool-man.js";import{isCtf4aiActive as A,handleCtf4aiMessage as C}from"./commands/ctf4ai-demo.js";import{isCtf4VlaActive as I,handleCtf4VlaMessage as k}from"./commands/ctf4vla.js";import{isDemo2Active as T}from"./commands/demo2.js";import{loadDemo2Progress as E}from"./lib/demo2-progress.js";import{hasAnySimHistory as S,lastArmAt as $,lastBundledAt as O,lastSimAt as D}from"./lib/sim-cooldown.js";import{getExamState as L,getRealExamState as j,getDemoState as R,practicalChatCommand as q}from"./lib/exam-state.js";import{resetTerminalTheme as N}from"./lib/theme.js";import{ensureSandbox as P,runInSandbox as F,isDockerAvailable as M}from"./lib/sandbox.js";import{checkShellRisk as B,logShellAudit as _,getActiveCwd as U}from"./lib/exam-sandbox.js";import{logCommand as Q}from"./lib/logger.js";import{startLogSync as W,stopLogSync as X}from"./lib/log-sync.js";import{existsSync as Y,mkdirSync as z,writeFileSync as G}from"node:fs";import{join as V}from"node:path";import{homedir as J}from"node:os";const H=Date.now();function K(){return j()?chalk.cyan("icoa exam> "):function(){const o=R();return!(!o||"demo-free"!==o.session?.examId)&&new Date(o.session.startedAt||0).getTime()>=H}()?chalk.yellow("icoa demo> "):chalk.green("icoa> ")}const Z=V(J(),"icoa-workspace"),oo=new Set(["sudo","su","doas","pkexec","brew","apt","apt-get","yum","choco","npm","npx","pip","pip3","shutdown","reboot","halt","mkfs","fdisk","dd","iptables","ufw"]),eo="__REPL_NO_EXIT__",lo="2.5.1";function no(){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,R){process.env.ICOA_INSIDE_REPL="1";const H=t(),so=n(),ro=process.exit.bind(process),io=s();if(H.demoCleanedForVersion!==lo){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:lo})}const{select:co,confirm:go}=await import("@inquirer/prompts"),yo=H.mode||"",mo=""===yo?"instant":["instant","learn","selection","olympiad"].includes(yo)?yo:"selection",po=[{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 uo="";for(;!uo;){let o;try{o=await co({message:"Mode",choices:po,default:mo||"instant"})}catch(o){throw o instanceof Error&&"ExitPromptError"===o.name&&(console.log(),console.log(chalk.gray(" Goodbye.")),process.exit(0)),o}"about"!==o?uo=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"===uo&&"olympiad"!==mo){console.log(),console.log(chalk.yellow(" This mode will download ~500MB of CTF tools and AI models."));let o=!0;try{o=await go({message:"Continue?",default:!0})}catch(e){if(!(e instanceof Error&&"ExitPromptError"===e.name))throw e;o=!1}o||(uo="selection",console.log(chalk.gray(" Switched to National Selection mode.")))}if(uo!==mo&&a({mode:uo}),console.log(),"olympiad"===uo&&m(lo)){d(lo),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(R){const o=y();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"===uo)console.log(chalk.gray(" ─── exam hall · 90 min per paper once started · no pause ───")),console.log(),no();else if("embodied"===uo)!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=O()>0||D()>0,e=$()>0,l=S(),n=E(),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(),h(),console.log()}();else if("instant"===uo)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"}),uo="selection";else{if("learn"===uo){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 u()}"organizer"===uo?(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(),so?(console.log(chalk.green(` Logged in as ${H.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(),h(),console.log()):(console.log(` ${chalk.cyan.bold("🏆 ICOA 2026 · International Olympiad")}`),console.log(),io&&!c()?(console.log(chalk.red(" Token was activated on a different device.")),console.log(chalk.gray(" Contact organizer for assistance.")),console.log()):so?(console.log(chalk.green.bold(` Welcome back, ${H.userName}!`)),console.log(chalk.gray(` Connected to ${H.ctfdUrl}`)),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 & hint budget")),console.log(chalk.white(" scoreboard")+chalk.gray(" Live rankings")),console.log(chalk.white(" help")+chalk.gray(" Full command list")),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(" · ")+w()+chalk.gray(" · ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+chalk.cyan("quit")+chalk.gray(" closes")),console.log()):io?(Y(Z)||z(Z,{recursive:!0}),console.log(chalk.green.bold(" Welcome, competitor!")),console.log(chalk.gray(` Workspace: ${Z}`)),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 · ")+w()+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 · ")+w()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()))}e.exitOverride(),e.configureOutput({writeErr:()=>{},writeOut:o=>{console.log(o)}});const ho=o({input:process.stdin,output:process.stdout,prompt:K(),terminal:!0});f(ho);let wo=!1;p(!0),W();const fo=ho.prompt.bind(ho);ho.prompt=o=>{b()||A()||I()||T()||ho.setPrompt(K()),fo(o)},ho.prompt(),ho.on("line",async o=>{if(wo)return;const n=o.trim();if(!n)return ho.setPrompt(b()?chalk.magenta("icoa ai4ctf> "):K()),void ho.prompt();if("menu"===n||"menu confirm"===n)return j()&&"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 ho.prompt()):void u(ho);if(b()){wo=!0;const o=await x(n);return wo=!1,"exit"===o&&ho.setPrompt(K()),void ho.prompt()}if(A()){wo=!0;const o=await C(n);return wo=!1,"exit"!==o&&"solved"!==o||ho.setPrompt(K()),void ho.prompt()}if(I()){wo=!0;const o=await k(n);return wo=!1,"exit"===o&&ho.setPrompt(K()),ho.setPrompt(I()?chalk.bold.cyan("icoa ctf4eai> "):K()),void ho.prompt()}if(Q(n),"exit"===n)return L()?(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 ho.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"===uo&&no(),void ho.prompt());if("quit"===n||"q"===n||"quit confirm"===n){const o=L();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 ho.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)."))),X(),g(),console.log(chalk.gray(" Session saved. Use ")+chalk.white("icoa --resume")+chalk.gray(" to continue.")),N(),void ro(0))}if("back"===n){const o=L(),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"===uo?no():console.log(chalk.gray(" Already at main menu."))}return void ho.prompt()}if("help"===n||"?"===n){if(L()){wo=!0;try{await e.parseAsync(["node","icoa","exam","help"])}catch{}return wo=!1,void ho.prompt()}return ao(s(),uo),void ho.prompt()}if("man"===n||"manual"===n)return ao(s(),uo),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 ho.prompt();if(/^(?:man|manual)\s+\S/i.test(n))return v(n.replace(/^(?:man|manual)\s+/i,"")),void ho.prompt();if("more help"===n.toLowerCase()&&L()){wo=!0;try{await e.parseAsync(["node","icoa","exam","more-help"])}catch{}return wo=!1,void ho.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 competition, you get AI help at 3 levels:")),console.log(chalk.yellow(" hint a")+chalk.gray(" General guidance (50 uses)")),console.log(chalk.yellow(" hint b")+chalk.gray(" Deep analysis (10 uses)")),console.log(chalk.yellow(" hint c")+chalk.gray(" Critical assist (2 uses)")),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 ho.prompt();if(/^ICOA-[A-Z]{2,3}-\d{1,6}$/i.test(n.trim())){wo=!0;try{await e.parseAsync(["node","icoa","exam","token",n.trim()])}catch{}return wo=!1,void ho.prompt()}if(/^[A-Z]{2}[0-9A-HJKMNP-TV-Z]{8}$/i.test(n.trim())){wo=!0;try{await e.parseAsync(["node","icoa","exam","token",n.trim().toUpperCase()])}catch{}return wo=!1,void ho.prompt()}const a=n.match(/^exam\s+([A-Z]{2}[0-9A-HJKMNP-TV-Z]{8})$/i);if(a){wo=!0;try{await e.parseAsync(["node","icoa","exam","token",a[1].toUpperCase()])}catch{}return wo=!1,void ho.prompt()}const y=n.match(/^exam\s+([A-Z]{2,3})$/i);if(y){wo=!0;try{await e.parseAsync(["node","icoa","exam","list",y[1]])}catch{}return wo=!1,void ho.prompt()}if("clear"===n||"cls"===n)return console.clear(),void ho.prompt();if(n.startsWith("activate ")){const o=n.slice(9).trim(),e=r(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 ho.prompt()}if("activate"===n)return console.log(chalk.gray(" Usage: ")+chalk.white("activate <token>")),console.log(),void ho.prompt();const m=L();if(m){const o=n.toUpperCase().trim(),l=o=>{const e=m.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=m.questions.find(e=>e.number===o);return"short_answer"===e?.type},a=o=>{const e="demo-free"!==m.session.examId,l=m.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=m._lastQ||1;if(l(n))return a(n),void ho.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 ho.prompt();wo=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(n),o])}catch{}return wo=!1,void ho.prompt()}if(/^-?\d+$/.test(o)){const l=m._lastQ||1;if(t(l)){wo=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(l),o])}catch{}return wo=!1,void ho.prompt()}}const s=o.match(/^(\d+)\s+([ABCDE]|-?\d+)$/);if(s){const o=parseInt(s[1],10);if(l(o))return a(o),void ho.prompt();wo=!0;try{await e.parseAsync(["node","icoa","exam","answer",s[1],s[2]])}catch{}return wo=!1,void ho.prompt()}}const d=n.split(/\s+/)[0].toLowerCase(),p=/^python3?(\.\d+)?$/.test(d),h="ls"===d||"pwd"===d,w=n.startsWith("!")||d.startsWith("!")||p||h,f=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"]),T=()=>{console.log(chalk.gray(" Shell commands need ")+chalk.bold.cyan("!")+chalk.gray(" prefix. Try: ")+chalk.bold.cyan(`!${n}`)),console.log()};if("embodied"===uo&&!w&&!["demo2","learn","exam","ctf4eai","ctf4vla","lang","ref","setup","env","aienv","ipynb","sim"].includes(d))return f.has(d)?(T(),void ho.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 ho.prompt());if("selection"===uo&&!w&&!["exam","demo","demo2","retry","nations","next","prev","continue","setup","lang","ref","ai4ctf","ctf4ai","mark","unmark","review","submit","env","aienv","ipynb","sim"].includes(d)){if(f.has(d))return T(),void ho.prompt();if(console.log(chalk.gray(" Not available in Selection mode.")),m){const o=m._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 ho.prompt()}if("organizer"===uo&&!["join","exam","demo","retry","next","prev","logout","setup","lang","ref","ctf","mark","unmark","review","submit"].includes(d))return console.log(chalk.gray(" Not available in Organizer mode. Switch via: setup")),console.log(),void ho.prompt();if(!("olympiad"!==uo||s()&&c()||i(d)))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 ho.prompt();if(!["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","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"].includes(d)){if(oo.has(d))return console.log(chalk.yellow(` "${d}" 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 ho.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: ${Z}`)),console.log(),void ho.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=U(),t=B(n);_({cwd:e,input:n,riskFlags:t}),t.length>0&&j()&&(console.log(chalk.yellow(` ⚠ Action flagged: ${t.join(", ")} — logged.`)),console.log()),/^(\S*python3?(\.\d+)?)\s*$/.test(o)&&(o=`PYTHONSTARTUP="${function(){const o=V(J(),".icoa");Y(o)||z(o,{recursive:!0});const e=V(o,"python-startup.py");return Y(e)||G(e,"# 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\n"),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, 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()),wo=!0;try{M()&&await P()?await F(o,ho):await to(o,ho,e)}catch{console.log(chalk.yellow(` Command failed: ${d}`))}return wo=!1,console.log(),void ho.prompt()}wo=!0;const E=n.trim(),S=E.toLowerCase();let $,O=null,D="";if(m)if("submit"===S)O="final";else if(S.startsWith("submit ")){let o=E.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)?(O="flag",D=o):o&&/^[ABCDE]$/i.test(o)&&(O="flag",D=o.toUpperCase())}else/^ICOA\{[^}]+\}$/i.test(E)&&(O="flag",D=E);$="final"===O?["exam","submit"]:"flag"===O?["exam","answer",String(m?._lastQ||1),D]:function(o){const e=o.split(/\s+/),l=e[0].toLowerCase(),n=e.slice(1);if(("submit"===l||"flag"===l)&&n.length>=2)return["ctf","submit",n[0],n.slice(1).join(" ").trim().replace(/^["'`]+|["'`]+$/g,"")];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","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","ai4ctf","model","ctf","exam","ctf4ai"].includes(l)?[l,...n]:e}(n);const R="ctf"===$[0]&&"join"===$[1];R&&ho.pause(),process.exit=()=>{throw new Error(eo)};try{await e.parseAsync(["node","icoa",...$])}catch(o){const e=o instanceof Error?o.message:String(o);if(e===eo);else if(e.includes("commander.unknownCommand")){const{distance:o}=await import("fastest-levenshtein"),e=["ctf","ref","shell","files","view","connect","note","notes","logbook","log","manual","lang","setup","env","aienv","ipynb","ai4ctf","exam","ctf4ai","theme","clear","cls","quit","exit","back","menu","help","continue","activate","demo","challenges","status","scoreboard","join","logout"],l=d.split(/\s+/)[0]||d;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: ${d}.`)),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"===d||"flag"===d?(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: ${d}`)),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=ro,wo=!1,R&&ho.resume()}b()?ho.setPrompt(chalk.magenta("icoa ai4ctf> ")):A()?ho.setPrompt(chalk.red("icoa ctf4ai> ")):I()&&ho.setPrompt(chalk.bold.cyan("icoa ctf4eai> ")),console.log(),ho.prompt()}),ho.on("SIGINT",()=>{if(console.log(),b()||A())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(L()){const o="demo-free"!==L().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(),ho.prompt()}),ho.on("close",()=>{X(),g(),N(),ro(0)})}function to(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, budget & timer")),console.log(chalk.white(" time ")+chalk.gray("Countdown timer")),console.log(),console.log(chalk.bold.white(" AI Teammate")+chalk.gray(" — 3 levels, use wisely")),console.log(chalk.white(' hint "question" ')+chalk.gray("Level A — General guidance (50 uses)")),console.log(chalk.white(' hint-b "question" ')+chalk.gray("Level B — Deep analysis (10 uses)")),console.log(chalk.white(' hint-c "question" ')+chalk.gray("Level C — Critical assist (2 uses)")),console.log(chalk.white(" hint budget ")+chalk.gray("Check remaining uses")),console.log(chalk.white(" ai4ctf ")+chalk.gray("Free-chat with AI (no limit)")),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("Docker sandbox")),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.291",
3
+ "version": "2.19.293",
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": {