icoa-cli 2.19.415 → 2.19.417

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/i18n.js CHANGED
@@ -1 +1 @@
1
- import{getConfig as e}from"./config.js";import{DEMO_AI4CTF_FLAG_B64 as a}from"./demo-flags.js";import{readFileSync as o,existsSync as i}from"node:fs";import{join as n}from"node:path";import{getLangCacheDir as r}from"./translations-fetcher.js";export const EN={howToPlay:"How to play:",htpAnswer:"answer the question",htpHelp:"remove a wrong option",htpNav:"move between questions",htpMoreHelp:"+3 bonus helps",htpBack:"pause and return to menu",htpLang:"view all languages / lang es to switch",egg3:"Sydney Opera House — Great start!",egg5:"A koala says g'day — 1/3 done!",egg7:"Sydney Harbour Bridge — Keep going!",egg9:"A kangaroo hops by — past halfway!",egg11:"Bondi Beach — almost there!",egg13:"Great Barrier Reef — 2 more to go!",egg15:"G'day mate! All done! 🇦🇺",answerThis:"answer this question",helpRemove:"remove a wrong option",helpUsedUp:"used up — type more help for +3",helpAllUsed:"used up",wrong:"wrong",qTutorial:'👉 Try typing "help" to see what happens!',qTutorialBlock:"Try typing help first to see what it does!",qTutorialRequired:"This question requires you to use help before answering.",allAnswered:"🎉 All questions answered!",typeSubmit:"Type exam submit to see your results!",autoSubmitting:"Auto-submitting your demo...",grading:"Grading...",complete:"Complete!",passed:"✓ PASSED",notPassed:"✗ NOT PASSED",score:"Score",incorrectIntro:"incorrect — here are the corrections:",yourAnswer:"Your answer",correct:"Correct",perfectScore:"Perfect score! All answers correct! 🎉",theoryDone:"These were theory questions. In the real ICOA",theoryDone2:"competition, everything happens in this terminal.",didYouKnow:"Did you know?",ctfHistory1:"CTF (Capture The Flag) started at DEF CON 4 in 1996,",ctfHistory2:"Las Vegas. Founded by Jeff Moss (Dark Tangent).",ctfHistory3:"2026 marks 30 years of CTF worldwide.",ctfFlags1:"In a CTF, you solve challenges to find hidden",ctfFlags2:'"flags" — secret codes like:',ctfFlags3:"Find it, submit it, score points!",timeline1:"1996 First CTF @ DEF CON, Las Vegas",timeline2:"2016 DARPA Cyber Grand Challenge — AI enters CTF",timeline3:"2026 ICOA — First AI Security Olympiad, Sydney",twoTracks:"ICOA uses TWO competition tracks:",ai4ctfDesc:"Use AI to help you solve CTF challenges",ai4ctfSub:"AI is your teammate. Chat, ask for hints, work together.",ctf4aiDesc:"Trick the AI (Prompt Injection)",ctf4aiSub:"Can you make the AI break its own safety rules?",wantToContinue:"Want to experience both? Type",orBack:'Or type "back" to return to the main menu.',ai4ctfTitle:"AI4CTF Demo — AI as Your Teammate",ai4ctfSample:"Here's a sample CTF challenge:",ai4ctfChallenge:"Challenge: Hidden Message [Cryptography]",ai4ctfIntercepted:"You intercepted this encoded text:",ai4ctfDecode:"Can you decode it to find the flag?",ai4ctfLevels:"In competition, you get AI help at 3 levels:",ai4ctfHintA:'General guidance — "What type of encoding is this?"',ai4ctfHintAUses:"50 uses per competition. Safe to use freely.",ai4ctfHintB:'Deep analysis — "How do I decode Base64?"',ai4ctfHintBUses:"10 uses. Use when you're stuck.",ai4ctfHintC:"Critical assist — Nearly gives you the answer",ai4ctfHintCUses:"2 uses only. Last resort!",ai4ctfTryNow:"Try now: ask the AI anything about the challenge above.",ai4ctfExample:`Example: "What encoding is ${a}?"`,ai4ctfFreeChat:"Or just chat freely! You can also try hint a, hint b, hint c.",ai4ctfExit:'Type "exit" when done.',ai4ctfReport:"AI4CTF Session Report",ai4ctfTokens:"Tokens used",ai4ctfModel:"AI Model",ai4ctfNext:'Next: try ctf4ai — trick the AI into saying "koala"',tokenLimit:"Token limit reached!",ctf4aiTitle:"CTF4AI Demo — Challenge the AI",ctf4aiChallenge:"Challenge: Make the AI Say a Forbidden Word",ctf4aiIntro1:"In the real world, AI systems have safety rules.",ctf4aiIntro2:"Your job: find a way to trick the AI into breaking them!",ctf4aiRule:'The AI must NEVER say the word "koala".',ctf4aiMission:'Your mission: make it say "koala" anyway!',ctf4aiIdeas:"Ideas to try:",ctf4aiIdea1:"Ask about Australian animals",ctf4aiIdea2:"Ask it to write a story or poem",ctf4aiIdea3:"Ask it to translate or spell something",ctf4aiIdea4:"Be creative — there is no wrong approach!",ctf4aiBudget:"Conversation budget",ctf4aiQuit:'Type "exit" to quit anytime.',ctf4aiSuccess:'🎉 SUCCESS! The AI said "koala"!',ctf4aiDefense:"You broke through the AI's defenses!",ctf4aiInjection:"This is prompt injection — a real AI vulnerability.",ctf4aiHeld:"The AI held its ground this time. 💪",reportTitle:"ICOA Demo — Complete Report",reportStage1:"Stage 1: Theory Exam (15 questions)",reportCompleted:"✓ Completed",reportStage2:"Stage 2: AI4CTF — AI as Your Teammate",reportExperienced:"✓ Experienced",reportStage2Sub:"You used AI to analyze a CTF challenge.",reportStage2Hints:"In competition: hint a (50x) · hint b (10x) · hint c (2x)",reportStage3:"Stage 3: CTF4AI — Trick the AI",reportSolved:'✓ Solved! You made the AI say "koala"',reportNotSolved:"✗ The AI held its ground",reportRecommend:"Recommendations:",reportRec1:"Study cryptography, web security, and networking",reportRec2:"Practice on CTF platforms like picoCTF",reportRec3:"Learn about prompt injection and AI safety",reportRec4:'Explore the 38 reference guides: type "ref"',reportReady:"Ready for the real competition?",reportNations:"View participating countries",reportAbout:"Learn more about ICOA 2026",reportDemo:"Try again",continueTitle:"AI4CTF — AI as Your Teammate",continueLevels:"In AI4CTF, you solve cybersecurity challenges\nwith AI by your side.",continueHints:"In competition, you get AI help at 3 levels:",continueHintA:"General guidance (50 uses)",continueHintB:"Deep analysis (10 uses)",continueHintC:"Critical assist (2 uses)",continueTry:"Try it now! Type:",continueChat:'Chat freely with your AI teammate. Type "exit" when done.',continueAfter:'After ai4ctf, try: ctf4ai — trick the AI into saying "koala"',ai4ctfCommands:"Commands:",ai4ctfSubmitCmd:"Submit your answer (e.g. submit icoa{...})",ai4ctfShellCmd:"Run a shell command (e.g. !echo aWNv... | base64 -d)",ai4ctfEndSession:"End session",ai4ctfCorrectFlag:"🎉 Correct! Flag accepted!",ai4ctfDecoded:"You decoded the Base64 and found the flag.",ai4ctfWouldEarn:"In the real competition, this would earn you points!",ai4ctfWrongFlag:"✗ Incorrect flag. Try again!",ai4ctfFlagHint:"Hint: decode the Base64 string. Flag format: icoa{...}",ai4ctfFoundFlag:"Found a flag? Type: submit <flag>",ai4ctfThinking:"Thinking...",ctf4aiRelaxed:"After 50%, spelled-out variants (K-O-A-L-A) also count!",ctf4aiEnded:"CTF4AI challenge ended.",ctf4aiAlready:'Already in CTF4AI challenge. Type your message or "exit".',ctf4aiPrompt:'Try to make the AI say "koala"...',ctf4aiThinking:"Thinking...",readyToTry:"Ready to try? Type a command:",forNational:"For national selection exams:",viewRegions:"View all participating regions",enterExam:"Enter your country selection exam",htpJump:"jump to a specific question",htpReview:"check progress",htpSubmit:"submit your answers for grading",htpMark:"flag this question to review later",nextLabel:"Next:",reportRetryCta:"Want to nail the ones you missed? Type:",reportRetryWrongN:"retry the {n} wrong question",reportRetryWrongNPlural:"retry the {n} wrong questions",reportBackHint:"return to main menu",reportAboutHint:"Learn more about ICOA 2026",reportExamSetupHint:"next level: prepare tools for national selection",ai4ctfExitNextTitle:"Next:",ai4ctfExitNextSub:"Challenge the AI (Prompt Injection)",ai4ctfExitNextBody:"Can you make an AI violate its own safety rules?",ai4ctfExitCmdNext:"start the next challenge",ai4ctfExitCmdBack:"return to main menu",ai4ctfWelcomeCta:"👉 New here? Start with the hints in order:",ai4ctfHintNudge:"nudge",ai4ctfHintTechnique:"technique",ai4ctfHintPrinciple:"principle + shell reminder",ai4ctfWelcomeNoReveal:"(hints guide you — they never give the answer directly)",ai4ctfOrChat:"Or chat freely with your AI teammate — ask anything",ai4ctfOrChatExample:"about the challenge. Example:",ai4ctfCmdHintLine:"pre-written hints (safe to use)",ai4ctfCmdShellLine:"run a shell command",ai4ctfHintABody:'The string ends with "==" and uses only letters, digits, "+", "/", and "=".\nThat pattern is a fingerprint — you have seen it before.\nWhere is "=" typically used as padding?',ai4ctfHintBBody:"This is Base64 encoded. Decode the string to find the flag.",ai4ctfHintCBody:`Hints never give you the answer directly — they only point you in the right direction.\nFor simple challenges like this one, hint c adds nothing extra:\nhint b already tells you everything you need.\n\nTwo ways forward from here:\n\n 1. Chat with your AI teammate in natural language. Examples:\n what is the base64 command?\n how do I decode Base64 on macOS?\n Just type the question — anything without "!" goes to the AI.\n\n 2. Run a shell command directly. Shell commands inside ai4ctf\n must start with "!", otherwise your text goes to the AI. Example:\n\n !echo ${a} | base64 -d`,ai4ctfHintNextA:"Stuck? Try:",ai4ctfHintNextB:"Really stuck? Try:",ai4ctfHintNextC:"Once you have the flag:",examWaysToSolve:"Ways to solve",examWaysSavedTo:"data saved to",examWaysShell:"shell one-liner (base64 / xxd / strings / grep …)",examWaysPythonRepl:"interactive REPL (base64/re pre-imported)",examWaysRefPython:"python cheat-sheet",examWaysAi4ctf:"ask your AI teammate (knows this file)",examWaysFound:"When you find it:",ai4ctfWrapTitle:"✨ What you just learned",ai4ctfWrapLine1Head:"Need a command?",ai4ctfWrapLine1Body:'Just ask your AI teammate in natural\nlanguage — "how do I decode Base64 on the command line?"\nYou do not need to memorize every tool. The AI era is\nabout {thinking}, not mechanical memorization.',ai4ctfWrapLine2Head:"Need to run something?",ai4ctfWrapLine2Body:'Prefix shell commands with "!":',ai4ctfWrapQuotasTitle:"🎯 Real competition hint quotas",ai4ctfWrapQuotaA:"50 uses per competition",ai4ctfWrapQuotaAHint:"(use freely)",ai4ctfWrapQuotaB:"10 uses",ai4ctfWrapQuotaBHint:"(when stuck)",ai4ctfWrapQuotaC:" 2 uses",ai4ctfWrapQuotaCHint:"(last resort)",ai4ctfWrapQuotaFooter:"Prefer hint a → b → c. And when you just need to look\nsomething up, chat with the AI first — it costs nothing\nagainst your hint quota.",ai4ctfWrapNextTitle:"🔜 Next up:",ai4ctfWrapNextSub:'trick the AI into saying "koala"',ai4ctfWrapNextBody:'This next demo {noProg} — just your\nwit and creativity. Can you make a "safe" AI break its\nown rules?',ai4ctfWrapNoProg:"does not need programming",ai4ctfWrapTypeCtf4ai:"Type:",typeAndEnterToBegin:"Type {cmd} and press ENTER to begin.",ai4ctfRevealTitle:"💡 Out of AI tokens — here is the reveal",ai4ctfRevealBody:"Looks like you have not found the flag yet.\nNo worries — for the demo we will just tell you.\n\nRun this command to decode the Base64 string:",ai4ctfRevealSeeFlag:"You will see the flag:",ai4ctfRevealThenSubmit:"Then submit it:",ai4ctfRevealLockNote:"(AI chat is locked — only shell commands and submit work now.)",ai4ctfLockedTitle:"AI chat is locked — out of tokens.",ai4ctfLockedUse:"Use:",ai4ctfLockedThen:"Then:"};let s=null,c={};function l(e){if("en"===e)return{};try{const a=n(r(e),"ui.json");return i(a)?JSON.parse(o(a,"utf8")):{}}catch{return{}}}export function loadUiPack(e){s=e||"en",c=l(s)}export function t(a){const o=e().language||"en";if(o!==s&&(s=o,c=l(o)),"en"!==o){const e=c[a];if(null!=e)return e}return EN[a]}
1
+ import{getConfig as e}from"./config.js";import{DEMO_AI4CTF_FLAG_B64 as a}from"./demo-flags.js";import{readFileSync as o,existsSync as i}from"node:fs";import{join as n}from"node:path";import{getLangCacheDir as r}from"./translations-fetcher.js";export const EN={howToPlay:"How to play:",htpAnswer:"answer the question",htpHelp:"remove a wrong option",htpNav:"move between questions",htpMoreHelp:"+3 bonus helps",htpBack:"pause and return to menu",htpLang:"view all languages / lang es to switch",egg3:"Sydney Opera House — Great start!",egg5:"A koala says g'day — 1/3 done!",egg7:"Sydney Harbour Bridge — Keep going!",egg9:"A kangaroo hops by — past halfway!",egg11:"Bondi Beach — almost there!",egg13:"Great Barrier Reef — 2 more to go!",egg15:"G'day mate! All done! 🎉",answerThis:"answer this question",helpRemove:"remove a wrong option",helpUsedUp:"used up — type more help for +3",helpAllUsed:"used up",wrong:"wrong",qTutorial:'👉 Try typing "help" to see what happens!',qTutorialBlock:"Try typing help first to see what it does!",qTutorialRequired:"This question requires you to use help before answering.",allAnswered:"🎉 All questions answered!",typeSubmit:"Type exam submit to see your results!",autoSubmitting:"Auto-submitting your demo...",grading:"Grading...",complete:"Complete!",passed:"✓ PASSED",notPassed:"✗ NOT PASSED",score:"Score",incorrectIntro:"incorrect — here are the corrections:",yourAnswer:"Your answer",correct:"Correct",perfectScore:"Perfect score! All answers correct! 🎉",theoryDone:"These were theory questions. In the real ICOA",theoryDone2:"competition, everything happens in this terminal.",didYouKnow:"Did you know?",ctfHistory1:"CTF (Capture The Flag) started at DEF CON 4 in 1996,",ctfHistory2:"Las Vegas. Founded by Jeff Moss (Dark Tangent).",ctfHistory3:"2026 marks 30 years of CTF worldwide.",ctfFlags1:"In a CTF, you solve challenges to find hidden",ctfFlags2:'"flags" — secret codes like:',ctfFlags3:"Find it, submit it, score points!",timeline1:"1996 First CTF @ DEF CON, Las Vegas",timeline2:"2016 DARPA Cyber Grand Challenge — AI enters CTF",timeline3:"2026 ICOA — First AI Security Olympiad, Sydney",twoTracks:"ICOA uses TWO competition tracks:",ai4ctfDesc:"Use AI to help you solve CTF challenges",ai4ctfSub:"AI is your teammate. Chat, ask for hints, work together.",ctf4aiDesc:"Trick the AI (Prompt Injection)",ctf4aiSub:"Can you make the AI break its own safety rules?",wantToContinue:"Want to experience both? Type",orBack:'Or type "back" to return to the main menu.',ai4ctfTitle:"AI4CTF Demo — AI as Your Teammate",ai4ctfSample:"Here's a sample CTF challenge:",ai4ctfChallenge:"Challenge: Hidden Message [Cryptography]",ai4ctfIntercepted:"You intercepted this encoded text:",ai4ctfDecode:"Can you decode it to find the flag?",ai4ctfLevels:"In competition, you get AI help at 3 levels:",ai4ctfHintA:'General guidance — "What type of encoding is this?"',ai4ctfHintAUses:"50 uses per competition. Safe to use freely.",ai4ctfHintB:'Deep analysis — "How do I decode Base64?"',ai4ctfHintBUses:"10 uses. Use when you're stuck.",ai4ctfHintC:"Critical assist — Nearly gives you the answer",ai4ctfHintCUses:"2 uses only. Last resort!",ai4ctfTryNow:"Try now: ask the AI anything about the challenge above.",ai4ctfExample:`Example: "What encoding is ${a}?"`,ai4ctfFreeChat:"Or just chat freely! You can also try hint a, hint b, hint c.",ai4ctfExit:'Type "exit" when done.',ai4ctfReport:"AI4CTF Session Report",ai4ctfTokens:"Tokens used",ai4ctfModel:"AI Model",ai4ctfNext:'Next: try ctf4ai — trick the AI into saying "koala"',tokenLimit:"Token limit reached!",ctf4aiTitle:"CTF4AI Demo — Challenge the AI",ctf4aiChallenge:"Challenge: Make the AI Say a Forbidden Word",ctf4aiIntro1:"In the real world, AI systems have safety rules.",ctf4aiIntro2:"Your job: find a way to trick the AI into breaking them!",ctf4aiRule:'The AI must NEVER say the word "koala".',ctf4aiMission:'Your mission: make it say "koala" anyway!',ctf4aiIdeas:"Ideas to try:",ctf4aiIdea1:"Ask about Australian animals",ctf4aiIdea2:"Ask it to write a story or poem",ctf4aiIdea3:"Ask it to translate or spell something",ctf4aiIdea4:"Be creative — there is no wrong approach!",ctf4aiBudget:"Conversation budget",ctf4aiQuit:'Type "exit" to quit anytime.',ctf4aiSuccess:'🎉 SUCCESS! The AI said "koala"!',ctf4aiDefense:"You broke through the AI's defenses!",ctf4aiInjection:"This is prompt injection — a real AI vulnerability.",ctf4aiHeld:"The AI held its ground this time. 💪",reportTitle:"ICOA Demo — Complete Report",reportStage1:"Stage 1: Theory Exam (15 questions)",reportCompleted:"✓ Completed",reportStage2:"Stage 2: AI4CTF — AI as Your Teammate",reportExperienced:"✓ Experienced",reportStage2Sub:"You used AI to analyze a CTF challenge.",reportStage2Hints:"In competition: hint a (50x) · hint b (10x) · hint c (2x)",reportStage3:"Stage 3: CTF4AI — Trick the AI",reportSolved:'✓ Solved! You made the AI say "koala"',reportNotSolved:"✗ The AI held its ground",reportRecommend:"Recommendations:",reportRec1:"Study cryptography, web security, and networking",reportRec2:"Practice on CTF platforms like picoCTF",reportRec3:"Learn about prompt injection and AI safety",reportRec4:'Explore the 38 reference guides: type "ref"',reportReady:"Ready for the real competition?",reportNations:"View participating countries",reportAbout:"Learn more about ICOA 2026",reportDemo:"Try again",continueTitle:"AI4CTF — AI as Your Teammate",continueLevels:"In AI4CTF, you solve cybersecurity challenges\nwith AI by your side.",continueHints:"In competition, you get AI help at 3 levels:",continueHintA:"General guidance (50 uses)",continueHintB:"Deep analysis (10 uses)",continueHintC:"Critical assist (2 uses)",continueTry:"Try it now! Type:",continueChat:'Chat freely with your AI teammate. Type "exit" when done.',continueAfter:'After ai4ctf, try: ctf4ai — trick the AI into saying "koala"',ai4ctfCommands:"Commands:",ai4ctfSubmitCmd:"Submit your answer (e.g. submit icoa{...})",ai4ctfShellCmd:"Run a shell command (e.g. !echo aWNv... | base64 -d)",ai4ctfEndSession:"End session",ai4ctfCorrectFlag:"🎉 Correct! Flag accepted!",ai4ctfDecoded:"You decoded the Base64 and found the flag.",ai4ctfWouldEarn:"In the real competition, this would earn you points!",ai4ctfWrongFlag:"✗ Incorrect flag. Try again!",ai4ctfFlagHint:"Hint: decode the Base64 string. Flag format: icoa{...}",ai4ctfFoundFlag:"Found a flag? Type: submit <flag>",ai4ctfThinking:"Thinking...",ctf4aiRelaxed:"After 50%, spelled-out variants (K-O-A-L-A) also count!",ctf4aiEnded:"CTF4AI challenge ended.",ctf4aiAlready:'Already in CTF4AI challenge. Type your message or "exit".',ctf4aiPrompt:'Try to make the AI say "koala"...',ctf4aiThinking:"Thinking...",readyToTry:"Ready to try? Type a command:",forNational:"For national selection exams:",viewRegions:"View all participating regions",enterExam:"Enter your country selection exam",htpJump:"jump to a specific question",htpReview:"check progress",htpSubmit:"submit your answers for grading",htpMark:"flag this question to review later",nextLabel:"Next:",reportRetryCta:"Want to nail the ones you missed? Type:",reportRetryWrongN:"retry the {n} wrong question",reportRetryWrongNPlural:"retry the {n} wrong questions",reportBackHint:"return to main menu",reportAboutHint:"Learn more about ICOA 2026",reportExamSetupHint:"next level: prepare tools for national selection",ai4ctfExitNextTitle:"Next:",ai4ctfExitNextSub:"Challenge the AI (Prompt Injection)",ai4ctfExitNextBody:"Can you make an AI violate its own safety rules?",ai4ctfExitCmdNext:"start the next challenge",ai4ctfExitCmdBack:"return to main menu",ai4ctfWelcomeCta:"👉 New here? Start with the hints in order:",ai4ctfHintNudge:"nudge",ai4ctfHintTechnique:"technique",ai4ctfHintPrinciple:"principle + shell reminder",ai4ctfWelcomeNoReveal:"(hints guide you — they never give the answer directly)",ai4ctfOrChat:"Or chat freely with your AI teammate — ask anything",ai4ctfOrChatExample:"about the challenge. Example:",ai4ctfCmdHintLine:"pre-written hints (safe to use)",ai4ctfCmdShellLine:"run a shell command",ai4ctfHintABody:'The string ends with "==" and uses only letters, digits, "+", "/", and "=".\nThat pattern is a fingerprint — you have seen it before.\nWhere is "=" typically used as padding?',ai4ctfHintBBody:"This is Base64 encoded. Decode the string to find the flag.",ai4ctfHintCBody:`Hints never give you the answer directly — they only point you in the right direction.\nFor simple challenges like this one, hint c adds nothing extra:\nhint b already tells you everything you need.\n\nTwo ways forward from here:\n\n 1. Chat with your AI teammate in natural language. Examples:\n what is the base64 command?\n how do I decode Base64 on macOS?\n Just type the question — anything without "!" goes to the AI.\n\n 2. Run a shell command directly. Shell commands inside ai4ctf\n must start with "!", otherwise your text goes to the AI. Example:\n\n !echo ${a} | base64 -d`,ai4ctfHintNextA:"Stuck? Try:",ai4ctfHintNextB:"Really stuck? Try:",ai4ctfHintNextC:"Once you have the flag:",examWaysToSolve:"Ways to solve",examWaysSavedTo:"data saved to",examWaysShell:"shell one-liner (base64 / xxd / strings / grep …)",examWaysPythonRepl:"interactive REPL (base64/re pre-imported)",examWaysRefPython:"python cheat-sheet",examWaysAi4ctf:"ask your AI teammate (knows this file)",examWaysFound:"When you find it:",ai4ctfWrapTitle:"✨ What you just learned",ai4ctfWrapLine1Head:"Need a command?",ai4ctfWrapLine1Body:'Just ask your AI teammate in natural\nlanguage — "how do I decode Base64 on the command line?"\nYou do not need to memorize every tool. The AI era is\nabout {thinking}, not mechanical memorization.',ai4ctfWrapLine2Head:"Need to run something?",ai4ctfWrapLine2Body:'Prefix shell commands with "!":',ai4ctfWrapQuotasTitle:"🎯 Real competition hint quotas",ai4ctfWrapQuotaA:"50 uses per competition",ai4ctfWrapQuotaAHint:"(use freely)",ai4ctfWrapQuotaB:"10 uses",ai4ctfWrapQuotaBHint:"(when stuck)",ai4ctfWrapQuotaC:" 2 uses",ai4ctfWrapQuotaCHint:"(last resort)",ai4ctfWrapQuotaFooter:"Prefer hint a → b → c. And when you just need to look\nsomething up, chat with the AI first — it costs nothing\nagainst your hint quota.",ai4ctfWrapNextTitle:"🔜 Next up:",ai4ctfWrapNextSub:'trick the AI into saying "koala"',ai4ctfWrapNextBody:'This next demo {noProg} — just your\nwit and creativity. Can you make a "safe" AI break its\nown rules?',ai4ctfWrapNoProg:"does not need programming",ai4ctfWrapTypeCtf4ai:"Type:",typeAndEnterToBegin:"Type {cmd} and press ENTER to begin.",ai4ctfRevealTitle:"💡 Out of AI tokens — here is the reveal",ai4ctfRevealBody:"Looks like you have not found the flag yet.\nNo worries — for the demo we will just tell you.\n\nRun this command to decode the Base64 string:",ai4ctfRevealSeeFlag:"You will see the flag:",ai4ctfRevealThenSubmit:"Then submit it:",ai4ctfRevealLockNote:"(AI chat is locked — only shell commands and submit work now.)",ai4ctfLockedTitle:"AI chat is locked — out of tokens.",ai4ctfLockedUse:"Use:",ai4ctfLockedThen:"Then:"};let s=null,c={};function l(e){if("en"===e)return{};try{const a=n(r(e),"ui.json");return i(a)?JSON.parse(o(a,"utf8")):{}}catch{return{}}}export function loadUiPack(e){s=e||"en",c=l(s)}export function t(a){const o=e().language||"en";if(o!==s&&(s=o,c=l(o)),"en"!==o){const e=c[a];if(null!=e)return e}return EN[a]}
@@ -1 +1 @@
1
- const t={ai4ctf:"AI4CTFDEMO01",ctf4ai:"CTF4AIDEMO01",ctf4eai:"LEARNDEMO01","ai4ctf-12":"AI4CTFDEMO01","ctf4ai-12":"CTF4AIDEMO01","ctf4eai-12":"LEARNDEMO01","ioai-jr":"IOAIJRDEMO01","ioai-jr-48":"IOAIJRDEMO01",ioaijr:"IOAIJRDEMO01",junior:"IOAIJRDEMO01",jr:"IOAIJRDEMO01",ioaijrdemo:"IOAIJRDEMO01",ctf4vla:"LEARNDEMO01",vla:"LEARNDEMO01",embodied:"LEARNDEMO01",ai4ctfdemo:"AI4CTFDEMO01",ctf4aidemo:"CTF4AIDEMO01",learndemo:"LEARNDEMO01"},e={1:"AI4CTFDEMO01",2:"CTF4AIDEMO01",3:"LEARNDEMO01"},i=/^[A-Z]{2}[A-Z0-9]{6,}$/,o=/^(AI4CTFDEMO\d+|CTF4AIDEMO\d+|LEARNDEMO\d+)$/;export function resolveLearnInput(n){const a=n.trim();if(!a)return{kind:"back"};const r=a.replace(/^\s*(?:[/>])?\s*(?:icoa\s+)?learn\s+/i,"").trim();if(!r)return{kind:"ambiguous",hint:"Type just the token (e.g. LEARNDEMO01) or one of: ai4ctf / ctf4ai / ctf4eai"};if(e[r])return{kind:"token",token:e[r]};const c=r.toLowerCase();if(t[c])return{kind:"token",token:t[c]};if("demo"===c||"demos"===c)return{kind:"ambiguous",hint:"Which demo? Type: 1 (ai4ctf) / 2 (ctf4ai) / 3 (ctf4eai)"};if(/\s/.test(r))return{kind:"unknown",hint:`Don't recognize "${a}". Try a track name (ai4ctf / ctf4ai / ctf4eai / junior), 1/2/3, a demo id like LEARNDEMO01, or paste your token (2 letters + 8 chars). Blank to go back.`};const E=r.toUpperCase();return o.test(E)||i.test(E)||/^[A-Z0-9]{8,}$/.test(E)?{kind:"token",token:E}:{kind:"unknown",hint:`Don't recognize "${a}". Try one of: ai4ctf / ctf4ai / ctf4eai (for the free demos), 1/2/3, or paste your AC/CA/EA/EI/IO/IA + 8 chars cohort token. Blank to go back.`}}
1
+ const t={ai4ctf:"AI4CTFDEMO01",ctf4ai:"CTF4AIDEMO01",ctf4eai:"LEARNDEMO01","ai4ctf-12":"AI4CTFDEMO01","ctf4ai-12":"CTF4AIDEMO01","ctf4eai-12":"LEARNDEMO01","ioai-jr":"IOAIJRDEMO01","ioai-jr-48":"IOAIJRDEMO01",ioaijr:"IOAIJRDEMO01",junior:"IOAIJRDEMO01",jr:"IOAIJRDEMO01",ioaijrdemo:"IOAIJRDEMO01",ctf4vla:"LEARNDEMO01",vla:"LEARNDEMO01",embodied:"LEARNDEMO01",ai4ctfdemo:"AI4CTFDEMO01",ctf4aidemo:"CTF4AIDEMO01",learndemo:"LEARNDEMO01"},e={1:"AI4CTFDEMO01",2:"CTF4AIDEMO01",3:"LEARNDEMO01"},i=/^[A-Z]{2}[A-Z0-9]{6,}$/,o=/^(AI4CTFDEMO\d+|CTF4AIDEMO\d+|LEARNDEMO\d+)$/;export function resolveLearnInput(n){const a=n.trim();if(!a)return{kind:"back"};if(/^(back|b|quit|q|exit|menu|home)$/i.test(a))return{kind:"back"};const r=a.replace(/^\s*(?:[/>])?\s*(?:icoa\s+)?learn\s+/i,"").trim();if(!r)return{kind:"ambiguous",hint:"Type just the token (e.g. LEARNDEMO01) or one of: ai4ctf / ctf4ai / ctf4eai"};if(e[r])return{kind:"token",token:e[r]};const c=r.toLowerCase();if(t[c])return{kind:"token",token:t[c]};if("demo"===c||"demos"===c)return{kind:"ambiguous",hint:"Which demo? Type: 1 (ai4ctf) / 2 (ctf4ai) / 3 (ctf4eai)"};if(/\s/.test(r))return{kind:"unknown",hint:`Don't recognize "${a}". Try a track name (ai4ctf / ctf4ai / ctf4eai / junior), 1/2/3, a demo id like LEARNDEMO01, or paste your token (2 letters + 8 chars). Blank to go back.`};const E=r.toUpperCase();return o.test(E)||i.test(E)||/^[A-Z0-9]{8,}$/.test(E)?{kind:"token",token:E}:{kind:"unknown",hint:`Don't recognize "${a}". Try one of: ai4ctf / ctf4ai / ctf4eai (for the free demos), 1/2/3, or paste your AC/CA/EA/EI/IO/IA + 8 chars cohort token. Blank to go back.`}}
package/dist/repl.js CHANGED
@@ -1 +1 @@
1
- import{createInterface as o}from"node:readline";import{spawn as e,execSync as t}from"node:child_process";import chalk from"chalk";import{isConnected as n,getConfig as l,saveConfig as a}from"./lib/config.js";import{ensureLangCache as s}from"./lib/translations-fetcher.js";import{loadUiPack as r}from"./lib/i18n.js";import{isActivated as i,activateToken as c,isFreeCommand as g,isDeviceMatch as y,recordExit as m,recordResume as d,isFirstRunOrUpgrade as u,markVersionSeen as p}from"./lib/access.js";import{setReplMode as h}from"./lib/ui.js";import{returnToMainMenu as w,printMenuHint as f,menuHintInline as b}from"./lib/menu-nav.js";import{setMainRl as x}from"./lib/main-rl.js";import{shellSplit as v}from"./lib/shell-split.js";import{isChatActive as k,handleChatMessage as A}from"./commands/ai4ctf.js";import{renderToolMan as C}from"./lib/tool-man.js";import{isCtf4aiActive as I,handleCtf4aiMessage as $}from"./commands/ctf4ai-demo.js";import{isCtf4VlaActive as T,handleCtf4VlaMessage as E}from"./commands/ctf4vla.js";import{isDemo2Active as S}from"./commands/demo2.js";import{isCardDeckActive as O}from"./lib/card-engine.js";import{loadDemo2Progress as j}from"./lib/demo2-progress.js";import{hasAnySimHistory as N,lastArmAt as L,lastBundledAt as D,lastSimAt as P}from"./lib/sim-cooldown.js";import{getExamState as R,getRealExamState as q,getDemoState as F,practicalChatCommand as U}from"./lib/exam-state.js";import{resolveResumePoint as M}from"./lib/resume.js";import{buildStatusLine as _}from"./lib/statusline.js";import{startBgTask as B,startAsyncTask as W,listBgTasks as Q,getBgTask as Y,drainCompleted as X,killAllBgTasks as z,runningCount as J}from"./lib/bgtasks.js";import{computeStart as V,renderStart as G}from"./commands/challenge.js";import{addDraft as H,listDrafts as Z,removeDraft as K,clearDrafts as oo}from"./lib/drafts.js";import{resetTerminalTheme as eo}from"./lib/theme.js";import{ensureSandbox as to,runInSandbox as no,isDockerAvailable as lo}from"./lib/sandbox.js";import{checkShellRisk as ao,logShellAudit as so,getActiveCwd as ro}from"./lib/exam-sandbox.js";import{logCommand as io}from"./lib/logger.js";import{startLogSync as co,stopLogSync as go}from"./lib/log-sync.js";import{installInputDynamics as yo,uninstallInputDynamics as mo,stripPasteMarkers as uo}from"./lib/input-dynamics.js";import{startBroadcastPoll as po,stopBroadcastPoll as ho,showBroadcast as wo,isCompetitionJoined as fo,isMelCompetition as bo,isLeaderAccount as xo,isLeaderSession as vo,fetchPublicScoreboard as ko,isCommsActive as Ao}from"./lib/comms.js";import{enterMemoScreen as Co,enterJuryScreen as Io}from"./commands/comms.js";import{existsSync as $o,mkdirSync as To,readFileSync as Eo,writeFileSync as So}from"node:fs";import{join as Oo}from"node:path";import{homedir as jo}from"node:os";const No="# ICOA exam interactive startup — auto-loaded by PYTHONSTARTUP\nimport base64, struct, hashlib, re, json, os, sys, binascii\ntry: import requests\nexcept ImportError: pass\ntry: from Crypto.Cipher import AES\nexcept ImportError: pass\ntry: from Crypto.Util.Padding import pad, unpad\nexcept ImportError: pass\ntry: from pwn import xor, p32, u32, p64, u64\nexcept ImportError: pass\ntry: import bs4\nexcept ImportError: pass\ntry: import numpy as np\nexcept ImportError: pass\ntry: from PIL import Image\nexcept ImportError: pass\n",Lo=Date.now();function Do(){return bo()?chalk.yellow("icoa 2026> "):q()?chalk.cyan("icoa exam> "):function(){const o=F();return!(!o||"demo-free"!==o.session?.examId)&&new Date(o.session.startedAt||0).getTime()>=Lo}()?chalk.yellow("icoa demo> "):chalk.green("icoa> ")}const Po=Oo(jo(),"icoa-workspace"),Ro=new Set(["sudo","su","doas","pkexec","brew","apt","apt-get","yum","choco","npm","npx","pip","pip3","shutdown","reboot","halt","mkfs","fdisk","dd","iptables","ufw"]),qo="__REPL_NO_EXIT__",Fo="2.5.1",Uo=["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","kaggle","guide","ai4ctf","model","ctf","exam","demo","retry","nations","next","prev","continue","logout","ctf4ai","mark","unmark","review","learn","demo2","demo4","demo5","ctf4eai","ctf4vla","theme","sim","arena","eai","board","learn-pull","doctor","bg","tasks","drafts","help","menu","quit","q","exit","back","resume"],Mo={exam:["list","start","q","answer","submit","review","result","next","prev","mark","unmark","help"],ctf:["challenges","open","submit","scoreboard","status","join","logout","time"],challenge:["start","stop","status"],arena:["eai"],learn:["start","continue"]};function _o(o){const e=o.replace(/^\s+/,"");if(/^\/\S*$/.test(e)){const o=e.slice(1).toLowerCase();return[Uo.filter(e=>e.startsWith(o)).map(o=>`/${o}`),e]}const t=e.split(/\s+/);if(t.length<=1){const o=(t[0]??"").toLowerCase();return[Uo.filter(e=>e.startsWith(o)).slice(),o]}if(2===t.length){const o=Mo[t[0].toLowerCase()];if(o){const e=t[1].toLowerCase();return[o.filter(o=>o.startsWith(e)).slice(),e]}}return[[],o]}async function Bo(o){const e=M();if(!e)return null;const t=process.exit;process.exit=()=>{throw new Error(qo)};try{await o.parseAsync(["node","icoa",...e.command])}catch(o){if(!(o instanceof Error&&o.message===qo))throw o}finally{process.exit=t}return e}function Wo(){console.log(),console.log(` ${chalk.cyan.bold("🎯 ICOA 2026 · National Selection")}`),console.log(),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("ACxxxxxxxx")+chalk.gray(" → ai4ctf-12 (AI as your CTF teammate)")),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("CAxxxxxxxx")+chalk.gray(" → ctf4ai-12 (red-team software AI)")),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("EAxxxxxxxx")+chalk.gray(" → ctf4eai-12 (red-team embodied AI)")),console.log(" "+chalk.bold.cyan("exam ")+chalk.white("<CC>xxxxxxxx")+chalk.gray(" → Paper A/B/C/D/E (country exam token)")),console.log(" "+chalk.bold.cyan("demo")+chalk.gray(" → free practice")),console.log(" "+chalk.bold.cyan("lang")+chalk.white(" es")+chalk.gray(" → switch language")),console.log(" "+chalk.gray("help · menu · quit")),console.log()}export async function startRepl(e,F){process.env.ICOA_INSIDE_REPL="1";let Lo=!1;if(bo()){const o=l().joinedAt,e=o=>new Intl.DateTimeFormat("en-CA",{timeZone:"Australia/Sydney",year:"numeric",month:"2-digit",day:"2-digit"}).format(o);o&&e(new Date(o))===e(new Date)||(a({ctfdUrl:"",token:"",sessionCookie:"",userId:null,userName:"",teamId:null,country:"",joinedAt:""}),Lo=!0)}const Mo=l(),Xo=n(),zo=process.exit.bind(process),Jo=i();if(Mo.language&&"en"!==Mo.language&&(await s(Mo.language,{silent:!0}),r(Mo.language)),Mo.demoCleanedForVersion!==Fo){try{const{existsSync:o,unlinkSync:e}=await import("node:fs"),{join:t}=await import("node:path"),{getIcoaDir:n}=await import("./lib/config.js"),l=t(n(),"demo-state.json");o(l)&&e(l)}catch{}a({demoCleanedForVersion:Fo})}const{select:Vo,confirm:Go}=await import("@inquirer/prompts"),Ho=Mo.mode||"",Zo=""===Ho?"instant":["instant","learn","selection","olympiad"].includes(Ho)?Ho:"selection",Ko=[{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("free demo or team 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"}];""===Ho&&(console.log(chalk.green(" 👋 First time here? ")+chalk.white("Just press ")+chalk.bold.cyan("Enter")+chalk.white(" — you’ll see ICOA in 30 seconds, no signup needed.")),console.log()),console.log(chalk.gray(" Type ")+chalk.bold.cyan("menu")+chalk.gray(" from anywhere to return here.")),console.log();let oe="";for(;!oe;){let o;const e=process.env.ICOA_TEST_BOOT_MODE;if(e&&["instant","learn","selection","olympiad"].includes(e))o=e;else try{o=await Vo({message:"Mode",choices:Ko,default:Zo||"instant"})}catch(o){throw o instanceof Error&&"ExitPromptError"===o.name&&(console.log(),console.log(chalk.gray(" Goodbye.")),process.exit(0)),o}if("about"!==o)oe=o;else{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 · 20+ languages")),console.log(),console.log(chalk.bold.white(" Three Frontiers of AI Security")),console.log(` ${chalk.green.bold("AI4CTF")}${chalk.gray(" AI as teammate — 5 CTF disciplines, 5-hour endurance round")}`),console.log(` ${chalk.red.bold("CTF4AI")}${chalk.gray(" AI as target — the AI system itself is the objective")}`),console.log(` ${chalk.cyan.bold("CTF4EAI")}${chalk.gray(" Embodied-AI Arena — probe robot policies in live simulation")}`),console.log(),console.log(chalk.bold.white(" First Edition — Sydney 2026 ")+chalk.green.bold("✓ held")),console.log(chalk.gray(" · Jun 27 - Jul 2, 2026 · University of Technology Sydney")),console.log(chalk.gray(" · 65 competitors · 20 countries & regions (10 on-site, 10 remote)")),console.log(chalk.gray(" · 36 awards — 6 Gold · 11 Silver · 17 Bronze · 2 Honorable Mentions")),console.log(chalk.gray(" · Champion: Oleg Uteshev · Embodied-AI Arena Gold: Kingsley Lim (AU)")),console.log(chalk.gray(" · Founding Charter signed — ICOA is now a permanent institution")),console.log(),console.log(chalk.bold.white(" Next: ICOA 2027")+chalk.gray(" — 20 more countries already accredited")),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")+chalk.gray(" · press: ")+chalk.cyan.underline("https://icoa2026.au/press/")),console.log(chalk.cyan(" ═══════════════════════════════════════════════════")),console.log();try{const{input:o}=await import("@inquirer/prompts"),e=()=>o({message:chalk.gray("Press Enter to return..."),theme:{prefix:"",style:{message:o=>o}}}),t=Date.now();await e(),Date.now()-t<200&&await e()}catch{}console.clear()}}if("olympiad"===oe&&"olympiad"!==Zo){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||(oe="selection",console.log(chalk.gray(" Switched to National Selection mode.")))}if(oe!==Zo&&a({mode:oe}),console.log(),"olympiad"===oe&&u(Fo)){p(Fo),console.log(chalk.gray(" Checking competition environment..."));const{execSync:o}=await import("node:child_process"),e=[{name:"pwntools",cmd:'python3 -c "import pwn"'},{name:"z3-solver",cmd:'python3 -c "import z3"'},{name:"numpy",cmd:'python3 -c "import numpy"'},{name:"requests",cmd:'python3 -c "import requests"'}];let t=0;for(const n of e)try{o(n.cmd,{stdio:"ignore"})}catch{t++}t>0?(console.log(chalk.yellow(` ${t} core competition libraries missing.`)),console.log(chalk.gray(" Run ")+chalk.white("env setup")+chalk.gray(" when you are ready to install them.")),console.log()):(console.log(chalk.green(" All core libraries ready.")),console.log())}if(F){const o=d();if(o){const e=Math.floor(o.awaySeconds/60),t=o.awaySeconds%60;console.log(chalk.yellow(` Session resumed. Away: ${e}m ${t}s | Total exits: ${o.exitCount}`)),console.log()}}if("selection"===oe)console.log(chalk.gray(" ─── exam hall · 90 min per paper once started · no pause ───")),console.log(),Wo();else if("embodied"===oe)!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=D()>0||P()>0,e=L()>0,t=N(),n=j(),l=null!==n&&"number"==typeof n.completedAt&&n.nextCardIndex>=n.totalCards,a=null!==n&&!l;if(l)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 ✓)")):t?console.log(chalk.bold.yellow(" Next up: ")+(e?chalk.bold.cyan("① sim")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2"):chalk.bold.cyan("② sim arm")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2"))+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01")):console.log(chalk.bold.yellow(" First time? Try in order: ")+chalk.bold.cyan("① sim")+chalk.gray(" → ")+chalk.bold.cyan("② sim arm")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2")+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01"));console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.bold.green(" sim")+chalk.gray(" ")+chalk.bold.cyan("①")+chalk.gray(" ")+chalk.bold.yellow("★ INSTANT")+chalk.gray(" — 9-robot group dance, no wait, no setup")),console.log(chalk.bold.green(" sim arm")+chalk.gray(" ")+chalk.bold.cyan("②")+chalk.gray(" interactive 6-DOF arm sandbox — type joint values, watch")),console.log(chalk.bold.green(" demo2")+chalk.gray(" ")+chalk.bold.cyan("③")+chalk.gray(" ~8 min interactive intro + live MuJoCo sim")),console.log(chalk.bold.green(" learn LEARNDEMO01")+chalk.gray(" ")+chalk.bold.cyan("④")+chalk.gray(" free 11-card intro (paste this command as-is)")),console.log(chalk.bold.green(" learn ")+chalk.bold.yellow("EA")+chalk.gray(" + 8 chars full 96 / 360 curriculum (team-issued)")),console.log(chalk.bold.green(" exam ")+chalk.bold.yellow("PDxxxxxxxx")+chalk.gray(" Paper D (CTF4EAI) — national selection contestants")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(),console.log(chalk.gray(" Three open tiers: ")+chalk.green("free 11")+chalk.gray(" · ")+chalk.yellow("registered 100")+chalk.gray(" · ")+chalk.bold.magenta("national team 480")+chalk.gray(" (PhD-ready)")),console.log(chalk.gray(" Country team contact: ")+chalk.cyan("australia@icoa2026.au")),console.log(),f(),console.log()}();else if("instant"===oe)console.log(chalk.cyan.bold(" [⚡ Try ICOA in 30 seconds — no token needed]")),console.log(),console.log(chalk.gray(" Three 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(chalk.bold.green(" kaggle")+chalk.gray(" ML practice — train a model, real board ")+chalk.bold.magenta("📊 data-science")),console.log(),console.log(chalk.gray(" Type ")+chalk.bold.cyan("demo")+chalk.gray(", ")+chalk.bold.cyan("demo2")+chalk.gray(" or ")+chalk.bold.cyan("kaggle")+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"}),oe="selection";else{if("learn"===oe){console.log(chalk.cyan.bold(" [🧠 Learn]")),console.log(),console.log(chalk.gray(" Three tracks · same difficulty curve.")),console.log(),console.log(chalk.white(" Free 12-card demos — paste the full command:")),console.log(),console.log(chalk.gray(" 🤝 ai4ctf AI as your teammate ")+chalk.bold.yellow("learn AI4CTFDEMO01")),console.log(chalk.gray(" 🔓 ctf4ai AI as your target ")+chalk.bold.yellow("learn CTF4AIDEMO01")),console.log(chalk.gray(" 🤖 ctf4eai Embodied AI Security ")+chalk.bold.yellow("learn LEARNDEMO01")),console.log(),console.log(chalk.gray(" Got a cohort token? Type ")+chalk.bold.yellow("learn <TOKEN>")+chalk.gray(" (e.g. ")+chalk.bold.yellow("learn EAABCD1234")+chalk.gray(").")),console.log();try{const{input:o}=await import("@inquirer/prompts"),{resolveLearnInput:t}=await import("./lib/learn-input.js");console.log(chalk.gray(" Enter a token (or just press Enter to go back).")),console.log();const n=async()=>{try{await o({message:chalk.bold.yellow("Press Enter to return to the menu"),theme:{prefix:"",style:{message:o=>o}}})}catch{}},l=3;for(let s=1;s<=l;s++){const r=await o({message:chalk.bold.cyan("icoa learn>"),theme:{prefix:"",style:{message:o=>o}}}),i=r.trim().toLowerCase();if("ai4ioai"===i||"/ai4ioai"===i){const{runAi4ioaiStandalone:o}=await import("./commands/ai4ioai.js");return await o(),await n(),a({mode:"selection"}),void w()}if("ioailab"===i||"/ioailab"===i){const{runIoailabStandalone:o}=await import("./commands/ioailab.js");return await o(),await n(),a({mode:"selection"}),void w()}const c=t(r);if("back"===c.kind)break;if("ambiguous"===c.kind||"unknown"===c.kind){console.log(),console.log(chalk.yellow(" "+c.hint)),console.log();continue}if(!/^[A-Z0-9]+DEMO01$/i.test(c.token)&&/^[A-Z]{2}[A-Z0-9]{8}$/i.test(c.token)){console.log(),console.log(chalk.gray(" Checking token…"));const{validateEAToken:o}=await import("./lib/learn-curricula.js"),e=await o(c.token);if(!e.ok){if(console.log(),console.log(chalk.red(` ✗ Token check failed: ${e.message||"validation failed"}`)+(e.code?chalk.gray(` [${e.code}]`):"")),"device_bound"===e.code?(console.log(chalk.gray(" This learn token is bound to the first computer it was used on,")),console.log(chalk.gray(" and this is a different computer. Ask the coordinator who issued")),console.log(chalk.gray(" it to move it to this device, then try again."))):"expired"===e.code?console.log(chalk.gray(" This learn token has expired — ask your coordinator for a new one.")):(console.log(chalk.gray(" Possible causes:")),console.log(chalk.gray(" · Typo in token (check 0/O, 1/I/L, V/U)")),console.log(chalk.gray(" · Token expired or revoked")),console.log(chalk.gray(" · Network down (check connection)"))),console.log(),s<l){console.log(chalk.gray(" Try again — or press Enter to go back.")),console.log();continue}await n();break}}console.log(),console.log(chalk.gray(" Opening ")+chalk.bold.cyan("learn")+chalk.gray(`: ${c.token}`)),console.log(),a({mode:"selection"}),process.env.ICOA_LEARN_EMBEDDED="1";const{setLearnSessionStarted:g}=await import("./lib/learn-outcome.js");g(!1);try{await e.parseAsync(["node","icoa","learn",c.token])}catch(o){console.log(),console.log(chalk.red(` ✗ learn failed to start: ${o instanceof Error?o.message:String(o)}`)),console.log()}finally{delete process.env.ICOA_LEARN_EMBEDDED}await n();break}}catch{}return a({mode:"selection"}),void w()}"organizer"===oe?(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(),Xo?(console.log(chalk.green(` Logged in as ${Mo.userName}`)),console.log(chalk.white(" exam list")+chalk.gray(" Manage exams")),console.log(chalk.white(" logout")+chalk.gray(" Disconnect"))):console.log(chalk.white(" join <url>")+chalk.gray(" Connect to manage exams")),console.log(),f(),console.log()):(console.log(` ${chalk.cyan.bold("🏆 ICOA 2026 · International Olympiad")}`),console.log(),Jo&&!y()?(console.log(chalk.red(" Token was activated on a different device.")),console.log(chalk.gray(" Contact organizer for assistance.")),console.log()):Xo?(console.log(chalk.green.bold(` Welcome back, ${Mo.userName}!`)),console.log(chalk.gray(` Connected to ${Mo.ctfdUrl}`)),console.log(chalk.gray(" Not you? Type ")+chalk.cyan("logout")+chalk.gray(" to switch accounts")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" Ready to compete? Start here:")),console.log(),console.log(chalk.bold.cyan(" challenges")+chalk.gray(" Browse challenges by category")),console.log(chalk.white(" status")+chalk.gray(" Your score & timer")),console.log(chalk.white(" scoreboard")+chalk.gray(" Live rankings")),console.log(chalk.white(" memo")+chalk.gray(" Report an issue to organizers (one-way)")),console.log(),console.log(chalk.gray(" Tool environment:")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.bold.yellow(" ★ ")+chalk.bold.cyan("man <tool>")+chalk.gray(" How to USE a tool (steghide, nmap…) · ")+chalk.cyan("man tools")+chalk.gray(" = list")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("help")+chalk.gray(" · ")+b()+chalk.gray(" · ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+chalk.cyan("quit")+chalk.gray(" closes")),console.log()):Jo?($o(Po)||To(Po,{recursive:!0}),console.log(chalk.green.bold(" Welcome, competitor!")),console.log(chalk.gray(` Workspace: ${Po}`)),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" Get started:")),console.log(),console.log(chalk.white(" Step 1 ")+chalk.bold.cyan("join <url>")+chalk.gray(" Connect to competition server")),console.log(chalk.white(" Step 2 ")+chalk.bold.cyan("challenges")+chalk.gray(" Browse & solve challenges")),console.log(chalk.white(" Step 3 ")+chalk.bold.cyan("ai4ctf")+chalk.gray(" Ask AI when stuck")),console.log(),console.log(chalk.gray(" Before Step 1 — make sure your tools are ready:")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.bold.yellow(" ★ ")+chalk.bold.cyan("man <tool>")+chalk.gray(" How to USE a tool (steghide, nmap…) · ")+chalk.cyan("man tools")+chalk.gray(" = list")),console.log(),console.log(chalk.gray(" Also: ")+chalk.white("help")+chalk.gray(" all commands")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+b()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()):(console.log(chalk.bold.yellow(" 🏆 You reached the finals tier.")),console.log(chalk.gray(" Full sandbox · 110 CTF tools · Sydney 2026 · this is where finalists compete.")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" To begin, activate your competition token:")),console.log(),console.log(chalk.bold.cyan(" activate <token>")),console.log(),console.log(chalk.gray(" While waiting, explore:")),console.log(chalk.white(" ref linux")+chalk.gray(" Quick reference for Linux")),console.log(chalk.white(" ref web")+chalk.gray(" Quick reference for Web")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.white(" help")+chalk.gray(" All available commands")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+b()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()))}e.exitOverride(),e.configureOutput({writeErr:()=>{},writeOut:o=>{console.log(o)}});const ee=o({input:process.stdin,output:process.stdout,prompt:Do(),terminal:!0,completer:_o});x(ee),yo(!1!==l().bracketedPaste);let te=!1;if(h(!0),co(),Lo&&(console.log(),console.log(chalk.yellow(" ⏱ A new competition day has started (Sydney time).")),console.log(chalk.gray(" For fairness, yesterday’s sign-in has been cleared. Type ")+chalk.cyan("join <url>")+chalk.gray(" to sign in with your account.")),console.log()),bo()){const o=l().userName||"this account";console.log(),console.log(chalk.yellow(" ⚠ This machine is signed in as ")+chalk.bold.white(o)+chalk.yellow(".")),console.log(chalk.gray(" Press ")+chalk.cyan("Enter")+chalk.gray(` to continue as ${o}, or type `)+chalk.cyan("logout")+chalk.gray(" to switch accounts.")),"logout"===(await new Promise(o=>{ee.question(chalk.white(" > "),e=>o(e.trim()))})).toLowerCase()&&(a({ctfdUrl:"",token:"",sessionCookie:"",userId:null,userName:"",teamId:null,country:""}),console.log(),console.log(chalk.green(" ✓ Logged out. ")+chalk.gray("Run ")+chalk.cyan("join <url>")+chalk.gray(" to sign in with your own account."))),console.log()}fo()&&po(()=>ee.prompt());let ne=null;const le=ee.prompt.bind(ee);ee.prompt=o=>{if(!(k()||I()||T()||S()||O()||Ao()||(ee.setPrompt(Do()),o)))try{for(const o of X()){const e="done"===o.status,t=o.cmd.length>40?`${o.cmd.slice(0,37)}…`:o.cmd,n=o.render?"":chalk.gray(" (")+chalk.white(t)+chalk.gray(") — ")+chalk.cyan(`tasks ${o.id}`);if(console.log((e?chalk.green(" ✓"):chalk.red(" ✗"))+chalk.white(` background task #${o.id} ${o.status}`)+n),o.render)try{o.render()}catch{}}const o=_();o&&o!==ne?(console.log(o),ne=o):o||(ne=null)}catch{}le(o)};const ae=M();ae&&(console.log(chalk.cyan(" ↻ Continue where you left off: ")+chalk.white(ae.label)+(ae.urgent?chalk.yellow(" (exam timer running)"):"")),console.log(chalk.gray(" type ")+chalk.cyan("resume")+chalk.gray(" to jump back in.")),console.log()),ee.prompt(),ee.on("line",async o=>{if(te)return;let a=uo(o.trim());if(!a)return ee.setPrompt(k()?chalk.magenta("icoa ai4ctf> "):Do()),void ee.prompt();if(/^icoa\s+\S/i.test(a)&&(a=a.replace(/^icoa\s+/i,"")),a.startsWith("/")&&!a.startsWith("//")){const o=a.slice(1).split(/\s+/)[0].toLowerCase(),t=a.slice(1+o.length).trim();if("ai"===o)return te=!0,await async function(o,e){if(k())return void(o?await A(o):console.log(chalk.gray(" You are already in the AI chat — just type your message.")));if(I())return void(o?await $(o):console.log(chalk.gray(" You are already in the CTF4AI target chat — just type your message.")));if(T())return void(o?await E(o):console.log(chalk.gray(" You are already in the Embodied-AI chat — just type your message.")));io(o?`/ai ${o}`:"/ai");const t=process.exit;process.exit=()=>{throw new Error(qo)};try{await e.parseAsync(["node","icoa","ai4ctf"])}catch(o){if(!(o instanceof Error&&o.message===qo))throw o}finally{process.exit=t}o&&k()&&await A(o)}(t,e),te=!1,ee.setPrompt(k()?chalk.magenta("icoa ai4ctf> "):Do()),void ee.prompt();!(k()||I()||T()||S()||O()||Ao())&&Uo.includes(o)&&(a=a.slice(1))}if("resume"===a.toLowerCase()){const o=M();return o?(io(`resume → ${o.command.join(" ")}`),te=!0,await Bo(e),te=!1,ee.setPrompt(k()?chalk.magenta("icoa ai4ctf> "):Do()),void ee.prompt()):(console.log(),console.log(chalk.gray(" Nothing to resume yet — start with ")+chalk.cyan("learn")+chalk.gray(" (curriculum) or ")+chalk.cyan("demo")+chalk.gray(" (taste).")),console.log(),void ee.prompt())}const s=k()||I()||T()||S()||O();if(!s&&("bg"===a.toLowerCase()||/^bg\s/i.test(a))){const o=a.replace(/^bg\s*/i,"").trim();if(!o)return console.log(),console.log(chalk.gray(" Usage: ")+chalk.cyan("bg <command>")+chalk.gray(" — run a non-interactive shell command in the background.")),console.log(chalk.gray(" e.g. ")+chalk.cyan("bg nmap -p- 10.0.0.5")+chalk.gray(" · view: ")+chalk.cyan("tasks")),console.log(),void ee.prompt();const e=ro(),t=ao(o);so({cwd:e,input:`bg ${o}`,riskFlags:t}),t.length>0&&q()&&console.log(chalk.yellow(` ⚠ Action flagged: ${t.join(", ")} — logged.`));const n=B(o,e);return console.log(),console.log(chalk.cyan(` ▸ background task #${n.id} started`)+chalk.gray(` (${J()} running)`)),console.log(chalk.gray(" ")+chalk.white(o)),console.log(chalk.gray(" view: ")+chalk.cyan("tasks")+chalk.gray(" · output: ")+chalk.cyan(`tasks ${n.id}`)),console.log(),void ee.prompt()}if(!s&&("tasks"===a.toLowerCase()||/^tasks\s/i.test(a))){const o=a.replace(/^tasks\s*/i,"").trim(),e=Q();if(console.log(),o){const e=Y(Number(o));if(!e||Number.isNaN(Number(o)))console.log(chalk.yellow(` No background task #${o}.`)+chalk.gray(" Type ")+chalk.cyan("tasks")+chalk.gray(" to list them."));else{const o="running"===e.status?chalk.yellow:"done"===e.status?chalk.green:chalk.red;console.log(o(` #${e.id} [${e.status}]`)+chalk.white(` ${e.cmd}`)+(null!==e.exitCode?chalk.gray(` (exit ${e.exitCode})`):"")),console.log(chalk.gray(" ─────────────────────────────────────────────"));const t=e.output.trim();if(t)for(const o of t.split("\n"))console.log(chalk.gray(" ")+chalk.white(o));else console.log(chalk.gray(" (no output yet)"))}}else if(0===e.length)console.log(chalk.gray(" No background tasks. Start one with ")+chalk.cyan("bg <command>")+chalk.gray("."));else{console.log(chalk.bold.white(" Background tasks"));for(const o of e){const e="running"===o.status?chalk.yellow("●"):"done"===o.status?chalk.green("✓"):chalk.red("✗"),t=Math.round(((o.endedAt??Date.now())-o.startedAt)/1e3),n=(o.endedAt?`${t}s`:`${t}s…`).padStart(5),l=o.cmd.length>48?`${o.cmd.slice(0,45)}…`:o.cmd;console.log(` ${e} `+chalk.white(`#${o.id}`)+chalk.gray(` ${n} `)+chalk.white(l))}console.log(chalk.gray(" output: ")+chalk.cyan("tasks <id>"))}return console.log(),void ee.prompt()}if(!s&&/&\s*$/.test(a)&&/^challenge\s+start\s+/i.test(a)){const o=a.replace(/\s*&\s*$/,"").trim().replace(/^challenge\s+start\s+/i,"").trim().split(/\s+/),e=o.some(o=>"-n"===o||"--new"===o),t=o.find(o=>"-n"!==o&&"--new"!==o);if(!t)return console.log(),console.log(chalk.gray(" Usage: ")+chalk.cyan("challenge start <id> &")),console.log(),void ee.prompt();if(!n())return console.log(),console.log(chalk.red(" Not connected. ")+chalk.gray("Run ")+chalk.cyan("join <url>")+chalk.gray(" first.")),console.log(),void ee.prompt();io(`challenge start ${t}${e?" --new":""} & (background)`);const l=W(`challenge start ${t}`,()=>V(t,e),o=>G(t,o));return console.log(),console.log(chalk.cyan(` ▸ background task #${l.id}: `)+chalk.white(`starting ${t}`)+chalk.gray(" — you can keep working; the connection info appears here when it is ready.")),console.log(),void ee.prompt()}if(!s&&a.startsWith("#")){const o=a.slice(1).trim();if(!o)return console.log(),console.log(chalk.gray(" Usage: ")+chalk.cyan("#<candidate answer>")+chalk.gray(" — stage a flag/answer WITHOUT submitting it. Review with ")+chalk.cyan("drafts")+chalk.gray(".")),console.log(),void ee.prompt();const e=R(),t=e?.session?.examId??null,n=e?e._lastQ||1:null,l=H(o,t,n);return io(`draft #${l.id} (not submitted)`),console.log(),console.log(chalk.green(` ✎ draft #${l.id} saved`)+(n?chalk.gray(` (Q${n})`):"")+chalk.yellow(" — NOT submitted.")),console.log(chalk.gray(" review with ")+chalk.cyan("drafts")+chalk.gray("; when sure, submit it the normal way.")),console.log(),void ee.prompt()}if(!s&&("drafts"===a.toLowerCase()||/^drafts\s/i.test(a))){const o=a.replace(/^drafts\s*/i,"").trim().toLowerCase();if("clear"===o){const o=oo();return console.log(),console.log(chalk.gray(` Cleared ${o} draft${1===o?"":"s"}.`)),console.log(),void ee.prompt()}const e=o.match(/^(?:rm|remove|del|delete)\s+(\d+)$/);if(e){const o=K(Number(e[1]));return console.log(),console.log(o?chalk.gray(` Removed draft #${e[1]}.`):chalk.yellow(` No draft #${e[1]}.`)),console.log(),void ee.prompt()}const t=R(),n=Z(t?.session?.examId??null);if(console.log(),0===n.length)console.log(chalk.gray(" No drafts yet. Stage a candidate with ")+chalk.cyan("#ICOA{maybe_this}")+chalk.gray(" — it won’t submit."));else{console.log(chalk.bold.white(" Draft answers")+chalk.gray(" (staged — not submitted)"));for(const o of n){const e=o.q?chalk.cyan(`Q${o.q}`.padStart(4)):chalk.gray(" · ");console.log(chalk.gray(` #${o.id}`)+` ${e} `+chalk.white(o.text.length>56?`${o.text.slice(0,53)}…`:o.text))}console.log(chalk.gray(" remove: ")+chalk.cyan("drafts rm <id>")+chalk.gray(" · clear all: ")+chalk.cyan("drafts clear"))}return console.log(),void ee.prompt()}if("menu"===a||"menu confirm"===a)return q()&&"menu confirm"!==a?(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 ee.prompt()):void w(ee);if(k()){te=!0;const o=await A(a);return te=!1,"exit"===o&&ee.setPrompt(Do()),void ee.prompt()}if(I()){te=!0;const o=await $(a);return te=!1,"exit"!==o&&"solved"!==o||ee.setPrompt(Do()),void ee.prompt()}if(T()){te=!0;const o=await E(a);return te=!1,"exit"===o&&ee.setPrompt(Do()),ee.setPrompt(T()?chalk.bold.cyan("icoa ctf4eai> "):Do()),void ee.prompt()}if(io(a),"exit"===a)return R()?(console.log(),console.log(chalk.yellow(" ⚠ An exam is in progress.")),console.log(chalk.white(" To return to menu without losing progress, type: ")+chalk.bold.cyan("back")),console.log(chalk.white(" To fully close ICOA CLI, type: ")+chalk.bold.cyan("quit")),console.log(chalk.gray(" Your progress is auto-saved either way.")),console.log(),void ee.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"===oe&&Wo(),void ee.prompt());if("quit"===a||"q"===a||"quit confirm"===a){const o=R();return o&&"demo-free"!==o.session.examId&&"quit confirm"!==a?(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 ee.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)."))),go(),mo(),ho(),z(),m(),console.log(chalk.gray(" Session saved. Use ")+chalk.white("icoa --resume")+chalk.gray(" to continue.")),eo(),void zo(0))}if("back"===a){const o=R(),e=o&&"demo-free"!==o.session.examId,t=o&&"demo-free"===o.session.examId&&(()=>{const e=new Date(o.session.startedAt||0).getTime();return Date.now()-e<18e5})();if(e)console.log(),console.log(chalk.gray(" Exam paused. Your progress is saved.")),console.log(chalk.white(" Resume: exam q 1")+chalk.gray(" · ")+chalk.white("exam review")+chalk.gray(" · ")+chalk.white("exam submit")),console.log();else if(t){const e=Object.keys(o.answers).length,t=o.session.questionCount;console.log(),console.log(chalk.gray(` Demo paused (${e}/${t} answered). Resume with: `)+chalk.white("exam q 1")),console.log(chalk.gray(" Or type ")+chalk.white("demo")+chalk.gray(" to restart.")),console.log()}else{if(o&&"demo-free"===o.session.examId){const{clearExamState:o}=await import("./lib/exam-state.js");o("demo-free")}const e=l();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"===oe?Wo():console.log(chalk.gray(" Already at main menu."))}return void ee.prompt()}if("help"===a||"?"===a){if(R()){te=!0;try{await e.parseAsync(["node","icoa","exam","help"])}catch{}return te=!1,void ee.prompt()}return Yo(i(),oe),void ee.prompt()}if("man"===a||"manual"===a)return Yo(i(),oe),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 ee.prompt();if(/^(?:man|manual)\s+\S/i.test(a))return C(a.replace(/^(?:man|manual)\s+/i,"")),void ee.prompt();if("more help"===a.toLowerCase()&&R()){te=!0;try{await e.parseAsync(["node","icoa","exam","more-help"])}catch{}return te=!1,void ee.prompt()}if("continue"===a.toLowerCase())return console.log(),console.log(chalk.green.bold(" ═══ AI4CTF — AI as Your Teammate ═══")),console.log(),console.log(chalk.white(" In AI4CTF, you solve cybersecurity challenges")),console.log(chalk.white(" with AI by your side.")),console.log(),console.log(chalk.white(" In this demo, your AI teammate gives help at 3 levels:")),console.log(chalk.yellow(" hint a")+chalk.gray(" General guidance")),console.log(chalk.yellow(" hint b")+chalk.gray(" Deep analysis")),console.log(chalk.yellow(" hint c")+chalk.gray(" Critical assist")),console.log(),console.log(chalk.white(" Try it now! Type: ")+chalk.bold.green("ai4ctf")),console.log(chalk.gray(' Chat freely with your AI teammate. Type "exit" when done.')),console.log(),console.log(chalk.gray(" After ai4ctf, try: ")+chalk.bold.red("ctf4ai")+chalk.gray(' — trick the AI into saying "koala"')),console.log(),void ee.prompt();if(/^ICOA-[A-Z]{2,3}-\d{1,6}$/i.test(a.trim())){te=!0;try{await e.parseAsync(["node","icoa","exam","token",a.trim()])}catch{}return te=!1,void ee.prompt()}if(/^[A-Z]{2}[0-9A-HJKMNP-TV-Z]{8}$/i.test(a.trim())){te=!0;try{await e.parseAsync(["node","icoa","exam","token",a.trim().toUpperCase()])}catch{}return te=!1,void ee.prompt()}const r=a.match(/^exam\s+([A-Z]{2}[0-9A-HJKMNP-TV-Z]{8})$/i);if(r){te=!0;try{await e.parseAsync(["node","icoa","exam","token",r[1].toUpperCase()])}catch{}return te=!1,void ee.prompt()}const d=a.match(/^exam\s+([A-Z]{2,3})$/i);if(d){te=!0;try{await e.parseAsync(["node","icoa","exam","list",d[1]])}catch{}return te=!1,void ee.prompt()}if("clear"===a||"cls"===a)return console.clear(),void ee.prompt();if("news"===a)return fo()?wo():console.log(chalk.gray(" No competition joined. Use ")+chalk.white("join <url>")+chalk.gray(".")),void ee.prompt();if("memo"===a){if(!fo())return console.log(chalk.gray(" Join a competition first: ")+chalk.white("join <url>")),void ee.prompt();te=!0;try{await Co()}catch{}return void(te=!1)}const u=vo()||xo(l().userName||"");if("jury"===a&&u){te=!0;try{await Io()}catch{}return void(te=!1)}if(u&&vo()&&"scoreboard"===a.split(/\s+/)[0]){te=!0;try{const o=await ko();if(console.log(),0===o.length)console.log(chalk.gray(" Scoreboard is empty."));else{console.log(chalk.bold.white(" Scoreboard"));for(const e of o.slice(0,50))console.log(chalk.gray(` ${String(e.pos).padStart(3)}. `)+chalk.white(e.name.padEnd(28).slice(0,28))+chalk.cyan(String(e.score)))}console.log()}catch{}return te=!1,void ee.prompt()}if(u&&bo()){const o=a.split(/\s+/)[0];if(["challenges","open","submit","hint"].includes(o))return console.log(),console.log(chalk.yellow(" Team-leader account — the challenge bracket is not available here.")),console.log(chalk.gray(" Available: ")+chalk.white("scoreboard")+chalk.gray(" · ")+chalk.white("news")+chalk.gray(" · ")+chalk.white("jury")+chalk.gray(" · ")+chalk.white("time")+chalk.gray(" · ")+chalk.white("status")+chalk.gray(" · ")+chalk.white("logout")),console.log(),void ee.prompt()}if(a.startsWith("activate ")){const o=a.slice(9).trim(),e=c(o);return"ok"===e?console.log(chalk.green(" Access granted! Token bound to this device.")):"already_bound"===e?(console.log(),console.log(chalk.red(" Token already activated on a different device.")),console.log(chalk.gray(" Each token binds to the first device that uses it. If you lost the device,")),console.log(chalk.gray(" contact your proctor to have the token re-issued for a new device."))):(console.log(),console.log(chalk.red(" Token not recognized.")),console.log(chalk.gray(" Possible reasons:")),console.log(chalk.white(" • ")+chalk.gray("Typo — access tokens are case-insensitive and look like ")+chalk.cyan("ICOA-XXXX-XXXX-XXXX")+chalk.gray(" (4-char hex groups, e.g. ICOA-385E-27F2-B21B)")),console.log(chalk.white(" • ")+chalk.gray("Expired — ask your proctor or organizer for a fresh token")),console.log(chalk.white(" • ")+chalk.gray("Network — verify connection to ")+chalk.cyan("practice.icoa2026.au")),console.log(chalk.gray(" Still stuck? type ")+chalk.cyan("help")+chalk.gray(" or try ")+chalk.cyan("exam demo")+chalk.gray(" for a free practice round."))),console.log(),void ee.prompt()}if("activate"===a)return console.log(chalk.gray(" Usage: ")+chalk.white("activate <token>")),console.log(),void ee.prompt();const p=R();if(p){const o=a.toUpperCase().trim(),t=o=>{const e=p.questions.find(e=>e.number===o);return!!e&&("ai4ctf"===e.type||"ctf4ai"===e.type||e.options&&!e.options.A&&!e.options.B)},n=o=>{const e=p.questions.find(e=>e.number===o);return"short_answer"===e?.type},l=o=>{const e="demo-free"!==p.session.examId,t=p.questions.find(e=>e.number===o),n=U(t?.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 a=p._lastQ||1;if(t(a))return l(a),void ee.prompt();if(n(a))return console.log(),console.log(chalk.yellow(` Q${a} 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 ${a} 42`)+chalk.gray(")")),console.log(),void ee.prompt();te=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(a),o])}catch{}return te=!1,void ee.prompt()}if(/^-?\d+$/.test(o)){const t=p._lastQ||1;if(n(t)){te=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(t),o])}catch{}return te=!1,void ee.prompt()}}const s=o.match(/^(\d+)\s+([ABCDE]|-?\d+)$/);if(s){const o=parseInt(s[1],10);if(t(o))return l(o),void ee.prompt();te=!0;try{await e.parseAsync(["node","icoa","exam","answer",s[1],s[2]])}catch{}return te=!1,void ee.prompt()}}const h=a.split(/\s+/)[0].toLowerCase(),f=/^python3?(\.\d+)?$/.test(h),b="ls"===h||"pwd"===h||"tmux"===h,x=a.startsWith("!")||h.startsWith("!")||f||b,j=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"]),N=()=>{console.log(chalk.gray(" Shell commands need ")+chalk.bold.cyan("!")+chalk.gray(" prefix. Try: ")+chalk.bold.cyan(`!${a}`)),console.log()};if("embodied"===oe&&!x&&!["doctor","demo2","learn","exam","ctf4eai","ctf4vla","eai","arena","lang","ref","setup","env","aienv","ipynb","kaggle","guide","sim"].includes(h))return j.has(h)?(N(),void ee.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 ee.prompt());if("selection"===oe&&!x&&!["doctor","exam","demo","demo2","demo4","demo5","retry","nations","next","prev","continue","setup","lang","ref","ai4ctf","ctf4ai","mark","unmark","review","submit","env","aienv","ipynb","kaggle","guide","sim"].includes(h)){if(j.has(h))return N(),void ee.prompt();if(console.log(chalk.gray(" Not available in Selection mode.")),p){const o=p._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 ee.prompt()}if("organizer"===oe&&!["doctor","join","exam","demo","retry","next","prev","logout","setup","lang","ref","ctf","mark","unmark","review","submit","tmux"].includes(h))return console.log(chalk.gray(" Not available in Organizer mode. Switch via: setup")),console.log(),void ee.prompt();if(!("olympiad"!==oe||i()&&y()||g(h)))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 ee.prompt();if(!["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","kaggle","guide","ai4ctf","model","ctf","exam","demo","retry","nations","next","prev","continue","logout","ctf4ai","mark","unmark","review","submit","learn","demo2","demo4","demo5","ctf4eai","ctf4vla","theme","sim","arena","eai","board","learn-pull","doctor"].includes(h)){if("tmux"===h)try{t("command -v tmux",{stdio:"ignore"})}catch{return console.log(chalk.yellow(" tmux is not installed yet.")),console.log(chalk.gray(" Install it with ")+chalk.bold.cyan("env setup")+chalk.gray(" (full toolkit) or ")+chalk.bold.cyan("darwin"===process.platform?"brew install tmux":"sudo apt install tmux")+chalk.gray(".")),console.log(),void ee.prompt()}if(Ro.has(h))return console.log(chalk.yellow(` "${h}" 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(`!${a}`)),console.log(),void ee.prompt();if(/(?:^|\s)(?:\/(?!home\/|Users\/|tmp\/)|\.\.\/|~\/)/.test(a)&&!a.startsWith("cd ")){const o=/(?:^|\s)\/(?!home\/\w+\/icoa-workspace|Users\/\w+\/icoa-workspace|tmp\/)/.test(a),e=/\.\./.test(a);if(o||e)return console.log(chalk.red(" Blocked: access outside workspace is not allowed.")),console.log(chalk.gray(` Workspace: ${Po}`)),console.log(),void ee.prompt()}let o=a.startsWith("!")?a.slice(1).trim():a;if("darwin"===process.platform){const e="/opt/homebrew/opt/python@3.12/bin/python3.12";o=o.replace(/^python3?\s/,`${e} `).replace(/^(python3|python)$/,e)}else if("win32"===process.platform){const e=(()=>{try{return t("py -3 --version",{stdio:["ignore","ignore","ignore"],timeout:1500}),"py -3"}catch{}return"python"})();o=o.replace(/^python3?(\.\d+)?\s/,`${e} `).replace(/^python3?(\.\d+)?$/,e)}else{const e=(()=>{try{return t("which python3.12",{stdio:"ignore"}),"python3.12"}catch{return"python3"}})();o=o.replace(/^python\s/,`${e} `).replace(/^python$/,e)}const e=ro(),n=ao(a);so({cwd:e,input:a,riskFlags:n}),n.length>0&&q()&&(console.log(chalk.yellow(` ⚠ Action flagged: ${n.join(", ")} — logged.`)),console.log()),/^(\S*python3?(\.\d+)?)\s*$/.test(o)&&(o=`PYTHONSTARTUP="${function(){const o=Oo(jo(),".icoa");$o(o)||To(o,{recursive:!0});const e=Oo(o,"python-startup.py");let t="";if($o(e))try{t=Eo(e,"utf-8")}catch{}return t!==No&&So(e,No),e}()}" ${o}`,console.log(),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(chalk.bold.white(" Python ready — ICOA exam toolkit pre-loaded")),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(),console.log(chalk.white(" Already imported: ")+chalk.gray("base64, struct, hashlib, re, json, binascii")),console.log(chalk.white(" Also available: ")+chalk.gray("requests, bs4, numpy, PIL.Image, AES, pad/unpad, xor, p32/u32/p64/u64")),console.log(),console.log(chalk.yellow(" Quick examples:")),console.log(chalk.gray(' base64.b64decode("aGVsbG8=") ')+chalk.gray("# decode base64")),console.log(chalk.gray(' bytes.fromhex("48656c6c6f") ')+chalk.gray("# hex → bytes")),console.log(chalk.gray(' "ICOA{x}".encode() ')+chalk.gray("# str → bytes")),console.log(chalk.gray(" [chr(c) for c in [73,67,79,65]] ")+chalk.gray("# ASCII codes")),console.log(chalk.gray(' xor(bytes.fromhex("0a2b"), b"IC") ')+chalk.gray("# pwntools XOR")),console.log(),console.log(chalk.gray(" Exit: ")+chalk.white("exit()")+chalk.gray(" or Ctrl-D")),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log()),te=!0;try{await lo()&&await to()?await no(o,ee):await Qo(o,ee,e)}catch{console.log(chalk.yellow(` Command failed: ${h}`))}return te=!1,console.log(),void ee.prompt()}te=!0;const L=a.trim(),D=L.toLowerCase();let P,F=null,_="";if(p)if("submit"===D)F="final";else if(D.startsWith("submit ")){let o=L.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)?(F="flag",_=o):o&&/^[ABCDE]$/i.test(o)&&(F="flag",_=o.toUpperCase())}else/^ICOA\{[^}]+\}$/i.test(L)&&(F="flag",_=L);P="final"===F?["exam","submit"]:"flag"===F?["exam","answer",String(p?._lastQ||1),_]:function(o){const e=o.split(/\s+/),t=e[0].toLowerCase(),n=e.slice(1);if("aienv"===t&&["run","python","py"].includes((n[0]??"").toLowerCase()))return v(o);if(("submit"===t||"flag"===t)&&n.length>=2)return["ctf","submit",n[0],n.slice(1).join(" ").trim().replace(/^["'`]+|["'`]+$/g,"")];if("connect"===t&&n.length>=2){const e=v(o);return["connect",e[1]??n[0],e.slice(2).join(" ")]}const l={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 l[t]?l[t]:["ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","kaggle","guide","ai4ctf","model","ctf","exam","ctf4ai","doctor"].includes(t)?[t,...n]:e}(a);const X="ctf"===P[0]&&"join"===P[1];X&&ee.pause(),process.exit=()=>{throw new Error(qo)};try{await e.parseAsync(["node","icoa",...P])}catch(o){const e=o instanceof Error?o.message:String(o);if(e===qo);else if(e.includes("commander.unknownCommand")){const{distance:o}=await import("fastest-levenshtein"),e=["ctf","ref","shell","files","view","connect","challenge","note","notes","logbook","log","manual","lang","setup","env","aienv","ipynb","kaggle","guide","ai4ctf","exam","ctf4ai","theme","eai","board","clear","cls","quit","exit","back","menu","help","continue","activate","demo","challenges","status","scoreboard","join","logout"],t=h.split(/\s+/)[0]||h;let n={word:"",dist:1/0};for(const l of e){const e=o(t.toLowerCase(),l);e<n.dist&&(n={word:l,dist:e})}console.log(chalk.yellow(` Unknown command: ${h}.`)),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"===h||"flag"===h?(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: ${h}`)),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=zo,te=!1,X&&ee.resume()}k()?ee.setPrompt(chalk.magenta("icoa ai4ctf> ")):I()?ee.setPrompt(chalk.red("icoa ctf4ai> ")):T()&&ee.setPrompt(chalk.bold.cyan("icoa ctf4eai> ")),console.log(),ee.prompt()}),ee.on("SIGINT",()=>{if(console.log(),k()||I())console.log(chalk.yellow(" Ctrl+C did not close ICOA CLI — you are still in the AI chat.")),console.log(chalk.white(" Type ")+chalk.bold.cyan("exit")+chalk.white(" to leave the chat and return to the menu."));else if(R()){const o="demo-free"!==R().session.examId;console.log(chalk.yellow(" Ctrl+C did NOT close ICOA CLI.")),console.log(chalk.gray(` Your ${o?"exam":"demo"} is paused and every answer is auto-saved.`)),console.log(),console.log(chalk.white(" Resume: ")+chalk.cyan("exam q 1")+chalk.gray(" · Back to menu: ")+chalk.cyan("back")+chalk.gray(" · Close CLI: ")+chalk.cyan(o?"quit confirm":"quit"))}else console.log(chalk.yellow(" Ctrl+C did not close ICOA CLI — you are still at the ")+chalk.cyan("icoa>")+chalk.yellow(" prompt.")),console.log(chalk.gray(" Keep typing — ")+chalk.cyan("help")+chalk.gray(" lists commands. (Only ")+chalk.cyan("quit")+chalk.gray(" or Ctrl+D actually close the CLI.)"));console.log(),ee.prompt()}),ee.on("close",()=>{go(),mo(),ho(),z(),m(),eo(),zo(0)}),"1"===process.env.ICOA_AUTO_RESUME&&(delete process.env.ICOA_AUTO_RESUME,M()&&(te=!0,await Bo(e),te=!1,ee.setPrompt(k()?chalk.magenta("icoa ai4ctf> "):Do()),ee.prompt()))}function Qo(o,t,n){return new Promise(l=>{const a=process.stdin,s=!!a.isTTY&&!!a.isRaw;if(t.pause(),a.isTTY&&"function"==typeof a.setRawMode)try{a.setRawMode(!1)}catch{}const r=e(o,{shell:!0,stdio:"inherit",cwd:n||process.cwd()}),i=()=>{if(a.isTTY&&"function"==typeof a.setRawMode&&s)try{a.setRawMode(!0)}catch{}t.resume(),l()};r.on("close",i),r.on("error",i)})}function Yo(o,e="olympiad"){return console.log(),"selection"===e||"organizer"===e?(console.log(chalk.bold.white(" Exam")),console.log(chalk.white(" join <url> ")+chalk.gray("Connect to exam server")),console.log(chalk.white(" exam list ")+chalk.gray("Available exams")),console.log(chalk.white(" exam start <id> ")+chalk.gray("Begin an exam")),console.log(chalk.white(" exam q [n] ")+chalk.gray("View questions")),console.log(chalk.white(" exam answer <n> <X> ")+chalk.gray("Answer question")),console.log(chalk.white(" exam review ")+chalk.gray("Review all answers")),console.log(chalk.white(" exam submit ")+chalk.gray("Submit for grading")),console.log(chalk.white(" exam result ")+chalk.gray("View your score")),console.log(),console.log(chalk.bold.white(" System")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference")),console.log(chalk.white(" setup ")+chalk.gray("Settings / switch mode")),console.log(chalk.white(" lang [code] ")+chalk.gray("Switch language")),console.log(chalk.white(" clear ")+chalk.gray("Clear screen")),console.log(chalk.white(" exit ")+chalk.gray("Quit")),void console.log()):o?(console.log(chalk.cyan(" ═══════════════════════════════════════════════")),console.log(chalk.bold.white(" How it works")),console.log(),console.log(chalk.gray(" 1. Browse ")+chalk.white("challenges")+chalk.gray(" and pick one")),console.log(chalk.gray(" 2. ")+chalk.white("open <id>")+chalk.gray(" to read the challenge")),console.log(chalk.gray(" 3. Use ")+chalk.white("ai4ctf")+chalk.gray(" to chat with AI when stuck")),console.log(chalk.gray(" 4. ")+chalk.white("submit <id> <flag>")+chalk.gray(" to score points")),console.log(chalk.gray(" 5. Check ")+chalk.white("scoreboard")+chalk.gray(" to track your rank")),console.log(chalk.cyan(" ═══════════════════════════════════════════════")),console.log(),console.log(chalk.bold.white(" Competition")),console.log(chalk.white(" join <url> ")+chalk.gray("Connect to CTFd")),console.log(chalk.white(" challenges (ch) ")+chalk.gray("List challenges by category")),console.log(chalk.white(" open <id> ")+chalk.gray("Read challenge + get next steps")),console.log(chalk.white(" submit <id> <flag> ")+chalk.gray("Submit a flag")),console.log(chalk.white(" scoreboard (sb) ")+chalk.gray("Live rankings")),console.log(chalk.white(" status ")+chalk.gray("Your score & timer")),console.log(chalk.white(" time ")+chalk.gray("Countdown timer")),console.log(),console.log(chalk.bold.white(" AI Teammate")),console.log(chalk.white(" ai4ctf ")+chalk.gray("Free-chat with your AI teammate")),console.log(),console.log(chalk.bold.white(" Tools")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference (linux, web, crypto...)")),console.log(chalk.white(" shell ")+chalk.gray("Interactive CTF shell (sandbox if present, else host)")),console.log(chalk.white(" files <id> ")+chalk.gray("Download challenge files")),console.log(chalk.white(" connect <id> ")+chalk.gray("Connect to remote target")),console.log(chalk.white(" note [text] ")+chalk.gray("Add a logbook entry (in-exam: tags current Q)")),console.log(chalk.white(" logbook [n] ")+chalk.gray("View your logbook (in-exam: filter by Q)")),console.log(chalk.white(" log ")+chalk.gray("Session history")),console.log(chalk.white(" man <tool> ")+chalk.bold.yellow("★ ")+chalk.gray("How to use a tool (steghide, nmap…); ")+chalk.cyan("man tools")+chalk.gray(" = list. Bare ")+chalk.cyan("man")+chalk.gray(" = this list.")),console.log(),console.log(chalk.bold.white(" System")),console.log(chalk.white(" resume ")+chalk.gray("Continue your last learn card / exam")),console.log(chalk.white(" #<candidate> ")+chalk.gray("Stage a draft answer (never auto-submits)")),console.log(chalk.white(" drafts ")+chalk.gray("Review staged draft answers")),console.log(chalk.white(" bg <command> ")+chalk.gray("Run a shell command in the background")),console.log(chalk.white(" tasks [id] ")+chalk.gray("Background task panel / view output")),console.log(chalk.white(" doctor ")+chalk.gray("Self-check: version, Python, server, tools")),console.log(chalk.white(" setup ")+chalk.gray("Configure settings")),console.log(chalk.white(" lang [code] ")+chalk.gray("Switch language (15 supported)")),console.log(chalk.white(" logout ")+chalk.gray("Disconnect")),console.log(chalk.white(" clear ")+chalk.gray("Clear screen")),console.log(chalk.white(" exit ")+chalk.gray("Quit (session saved)")),void console.log()):(console.log(chalk.bold.yellow(" Restricted Mode — activate with a token to unlock all commands")),console.log(),console.log(chalk.white(" activate <token> ")+chalk.gray("Unlock full access")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference")),console.log(chalk.white(" exit ")+chalk.gray("Quit")),void console.log())}
1
+ import{createInterface as o}from"node:readline";import{spawn as e,execSync as t}from"node:child_process";import chalk from"chalk";import{isConnected as n,getConfig as l,saveConfig as a}from"./lib/config.js";import{ensureLangCache as s}from"./lib/translations-fetcher.js";import{loadUiPack as r}from"./lib/i18n.js";import{isActivated as i,activateToken as c,isFreeCommand as g,isDeviceMatch as y,recordExit as m,recordResume as d,isFirstRunOrUpgrade as u,markVersionSeen as p}from"./lib/access.js";import{setReplMode as h}from"./lib/ui.js";import{returnToMainMenu as w,printMenuHint as f,menuHintInline as b}from"./lib/menu-nav.js";import{setMainRl as x}from"./lib/main-rl.js";import{shellSplit as v}from"./lib/shell-split.js";import{isChatActive as k,handleChatMessage as A}from"./commands/ai4ctf.js";import{renderToolMan as C}from"./lib/tool-man.js";import{isCtf4aiActive as I,handleCtf4aiMessage as $}from"./commands/ctf4ai-demo.js";import{isCtf4VlaActive as T,handleCtf4VlaMessage as E}from"./commands/ctf4vla.js";import{isDemo2Active as S}from"./commands/demo2.js";import{isCardDeckActive as O}from"./lib/card-engine.js";import{loadDemo2Progress as j}from"./lib/demo2-progress.js";import{hasAnySimHistory as N,lastArmAt as L,lastBundledAt as D,lastSimAt as P}from"./lib/sim-cooldown.js";import{getExamState as R,getRealExamState as q,getDemoState as F,practicalChatCommand as U}from"./lib/exam-state.js";import{resolveResumePoint as M}from"./lib/resume.js";import{buildStatusLine as _}from"./lib/statusline.js";import{startBgTask as B,startAsyncTask as W,listBgTasks as Q,getBgTask as Y,drainCompleted as X,killAllBgTasks as z,runningCount as J}from"./lib/bgtasks.js";import{computeStart as V,renderStart as G}from"./commands/challenge.js";import{addDraft as H,listDrafts as Z,removeDraft as K,clearDrafts as oo}from"./lib/drafts.js";import{resetTerminalTheme as eo}from"./lib/theme.js";import{ensureSandbox as to,runInSandbox as no,isDockerAvailable as lo}from"./lib/sandbox.js";import{checkShellRisk as ao,logShellAudit as so,getActiveCwd as ro}from"./lib/exam-sandbox.js";import{logCommand as io}from"./lib/logger.js";import{startLogSync as co,stopLogSync as go}from"./lib/log-sync.js";import{installInputDynamics as yo,uninstallInputDynamics as mo,stripPasteMarkers as uo}from"./lib/input-dynamics.js";import{startBroadcastPoll as po,stopBroadcastPoll as ho,showBroadcast as wo,isCompetitionJoined as fo,isMelCompetition as bo,isLeaderAccount as xo,isLeaderSession as vo,fetchPublicScoreboard as ko,isCommsActive as Ao}from"./lib/comms.js";import{enterMemoScreen as Co,enterJuryScreen as Io}from"./commands/comms.js";import{existsSync as $o,mkdirSync as To,readFileSync as Eo,writeFileSync as So}from"node:fs";import{join as Oo}from"node:path";import{homedir as jo}from"node:os";const No="# ICOA exam interactive startup — auto-loaded by PYTHONSTARTUP\nimport base64, struct, hashlib, re, json, os, sys, binascii\ntry: import requests\nexcept ImportError: pass\ntry: from Crypto.Cipher import AES\nexcept ImportError: pass\ntry: from Crypto.Util.Padding import pad, unpad\nexcept ImportError: pass\ntry: from pwn import xor, p32, u32, p64, u64\nexcept ImportError: pass\ntry: import bs4\nexcept ImportError: pass\ntry: import numpy as np\nexcept ImportError: pass\ntry: from PIL import Image\nexcept ImportError: pass\n",Lo=Date.now();function Do(){return bo()?chalk.yellow("icoa 2026> "):q()?chalk.cyan("icoa exam> "):function(){const o=F();return!(!o||"demo-free"!==o.session?.examId)&&new Date(o.session.startedAt||0).getTime()>=Lo}()?chalk.yellow("icoa demo> "):chalk.green("icoa> ")}const Po=Oo(jo(),"icoa-workspace"),Ro=new Set(["sudo","su","doas","pkexec","brew","apt","apt-get","yum","choco","npm","npx","pip","pip3","shutdown","reboot","halt","mkfs","fdisk","dd","iptables","ufw"]),qo="__REPL_NO_EXIT__",Fo="2.5.1",Uo=["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","kaggle","guide","ai4ctf","model","ctf","exam","demo","retry","nations","next","prev","continue","logout","ctf4ai","mark","unmark","review","learn","demo2","demo4","demo5","ctf4eai","ctf4vla","theme","sim","arena","eai","board","learn-pull","doctor","bg","tasks","drafts","help","menu","quit","q","exit","back","resume"],Mo={exam:["list","start","q","answer","submit","review","result","next","prev","mark","unmark","help"],ctf:["challenges","open","submit","scoreboard","status","join","logout","time"],challenge:["start","stop","status"],arena:["eai"],learn:["start","continue"]};function _o(o){const e=o.replace(/^\s+/,"");if(/^\/\S*$/.test(e)){const o=e.slice(1).toLowerCase();return[Uo.filter(e=>e.startsWith(o)).map(o=>`/${o}`),e]}const t=e.split(/\s+/);if(t.length<=1){const o=(t[0]??"").toLowerCase();return[Uo.filter(e=>e.startsWith(o)).slice(),o]}if(2===t.length){const o=Mo[t[0].toLowerCase()];if(o){const e=t[1].toLowerCase();return[o.filter(o=>o.startsWith(e)).slice(),e]}}return[[],o]}async function Bo(o){const e=M();if(!e)return null;const t=process.exit;process.exit=()=>{throw new Error(qo)};try{await o.parseAsync(["node","icoa",...e.command])}catch(o){if(!(o instanceof Error&&o.message===qo))throw o}finally{process.exit=t}return e}function Wo(){console.log(),console.log(` ${chalk.cyan.bold("🎯 ICOA 2026 · National Selection")}`),console.log(),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("ACxxxxxxxx")+chalk.gray(" → ai4ctf-12 (AI as your CTF teammate)")),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("CAxxxxxxxx")+chalk.gray(" → ctf4ai-12 (red-team software AI)")),console.log(" "+chalk.bold.cyan("learn ")+chalk.white("EAxxxxxxxx")+chalk.gray(" → ctf4eai-12 (red-team embodied AI)")),console.log(" "+chalk.bold.cyan("exam ")+chalk.white("<CC>xxxxxxxx")+chalk.gray(" → Paper A/B/C/D/E (country exam token)")),console.log(" "+chalk.bold.cyan("demo")+chalk.gray(" → free practice")),console.log(" "+chalk.bold.cyan("lang")+chalk.white(" es")+chalk.gray(" → switch language")),console.log(" "+chalk.gray("help · menu · quit")),console.log()}export async function startRepl(e,F){process.env.ICOA_INSIDE_REPL="1";let Lo=!1;if(bo()){const o=l().joinedAt,e=o=>new Intl.DateTimeFormat("en-CA",{timeZone:"Australia/Sydney",year:"numeric",month:"2-digit",day:"2-digit"}).format(o);o&&e(new Date(o))===e(new Date)||(a({ctfdUrl:"",token:"",sessionCookie:"",userId:null,userName:"",teamId:null,country:"",joinedAt:""}),Lo=!0)}const Mo=l(),Xo=n(),zo=process.exit.bind(process),Jo=i();if(Mo.language&&"en"!==Mo.language&&(await s(Mo.language,{silent:!0}),r(Mo.language)),Mo.demoCleanedForVersion!==Fo){try{const{existsSync:o,unlinkSync:e}=await import("node:fs"),{join:t}=await import("node:path"),{getIcoaDir:n}=await import("./lib/config.js"),l=t(n(),"demo-state.json");o(l)&&e(l)}catch{}a({demoCleanedForVersion:Fo})}const{select:Vo,confirm:Go}=await import("@inquirer/prompts"),Ho=Mo.mode||"",Zo=""===Ho?"instant":["instant","learn","selection","olympiad"].includes(Ho)?Ho:"selection",Ko=[{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("free demo or team 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"}];""===Ho&&(console.log(chalk.green(" 👋 First time here? ")+chalk.white("Just press ")+chalk.bold.cyan("Enter")+chalk.white(" — you’ll see ICOA in 30 seconds, no signup needed.")),console.log()),console.log(chalk.gray(" Type ")+chalk.bold.cyan("menu")+chalk.gray(" from anywhere to return here.")),console.log();let oe="";for(;!oe;){let o;const e=process.env.ICOA_TEST_BOOT_MODE;if(e&&["instant","learn","selection","olympiad"].includes(e))o=e;else try{o=await Vo({message:"Mode",choices:Ko,default:Zo||"instant"})}catch(o){throw o instanceof Error&&"ExitPromptError"===o.name&&(console.log(),console.log(chalk.gray(" Goodbye.")),process.exit(0)),o}if("about"!==o)oe=o;else{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 · 20+ languages")),console.log(),console.log(chalk.bold.white(" Three Frontiers of AI Security")),console.log(` ${chalk.green.bold("AI4CTF")}${chalk.gray(" AI as teammate — 5 CTF disciplines, 5-hour endurance round")}`),console.log(` ${chalk.red.bold("CTF4AI")}${chalk.gray(" AI as target — the AI system itself is the objective")}`),console.log(` ${chalk.cyan.bold("CTF4EAI")}${chalk.gray(" Embodied-AI Arena — probe robot policies in live simulation")}`),console.log(),console.log(chalk.bold.white(" First Edition — Sydney 2026 ")+chalk.green.bold("✓ held")),console.log(chalk.gray(" · Jun 27 - Jul 2, 2026 · University of Technology Sydney")),console.log(chalk.gray(" · 65 competitors · 20 countries & regions (10 on-site, 10 remote)")),console.log(chalk.gray(" · 36 awards — 6 Gold · 11 Silver · 17 Bronze · 2 Honorable Mentions")),console.log(chalk.gray(" · Champion: Oleg Uteshev · Embodied-AI Arena Gold: Kingsley Lim (AU)")),console.log(chalk.gray(" · Founding Charter signed — ICOA is now a permanent institution")),console.log(),console.log(chalk.bold.white(" Next: ICOA 2027")+chalk.gray(" — 20 more countries already accredited")),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")+chalk.gray(" · press: ")+chalk.cyan.underline("https://icoa2026.au/press/")),console.log(chalk.cyan(" ═══════════════════════════════════════════════════")),console.log();try{const{input:o}=await import("@inquirer/prompts"),e=()=>o({message:chalk.gray("Press Enter to return..."),theme:{prefix:"",style:{message:o=>o}}}),t=Date.now();await e(),Date.now()-t<200&&await e()}catch{}console.clear()}}if("olympiad"===oe&&"olympiad"!==Zo){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||(oe="selection",console.log(chalk.gray(" Switched to National Selection mode.")))}if(oe!==Zo&&a({mode:oe}),console.log(),"olympiad"===oe&&u(Fo)){p(Fo),console.log(chalk.gray(" Checking competition environment..."));const{execSync:o}=await import("node:child_process"),e=[{name:"pwntools",cmd:'python3 -c "import pwn"'},{name:"z3-solver",cmd:'python3 -c "import z3"'},{name:"numpy",cmd:'python3 -c "import numpy"'},{name:"requests",cmd:'python3 -c "import requests"'}];let t=0;for(const n of e)try{o(n.cmd,{stdio:"ignore"})}catch{t++}t>0?(console.log(chalk.yellow(` ${t} core competition libraries missing.`)),console.log(chalk.gray(" Run ")+chalk.white("env setup")+chalk.gray(" when you are ready to install them.")),console.log()):(console.log(chalk.green(" All core libraries ready.")),console.log())}if(F){const o=d();if(o){const e=Math.floor(o.awaySeconds/60),t=o.awaySeconds%60;console.log(chalk.yellow(` Session resumed. Away: ${e}m ${t}s | Total exits: ${o.exitCount}`)),console.log()}}if("selection"===oe)console.log(chalk.gray(" ─── exam hall · 90 min per paper once started · no pause ───")),console.log(),Wo();else if("embodied"===oe)!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=D()>0||P()>0,e=L()>0,t=N(),n=j(),l=null!==n&&"number"==typeof n.completedAt&&n.nextCardIndex>=n.totalCards,a=null!==n&&!l;if(l)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 ✓)")):t?console.log(chalk.bold.yellow(" Next up: ")+(e?chalk.bold.cyan("① sim")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2"):chalk.bold.cyan("② sim arm")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2"))+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01")):console.log(chalk.bold.yellow(" First time? Try in order: ")+chalk.bold.cyan("① sim")+chalk.gray(" → ")+chalk.bold.cyan("② sim arm")+chalk.gray(" → ")+chalk.bold.cyan("③ demo2")+chalk.gray(" → ")+chalk.bold.cyan("④ learn LEARNDEMO01"));console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.bold.green(" sim")+chalk.gray(" ")+chalk.bold.cyan("①")+chalk.gray(" ")+chalk.bold.yellow("★ INSTANT")+chalk.gray(" — 9-robot group dance, no wait, no setup")),console.log(chalk.bold.green(" sim arm")+chalk.gray(" ")+chalk.bold.cyan("②")+chalk.gray(" interactive 6-DOF arm sandbox — type joint values, watch")),console.log(chalk.bold.green(" demo2")+chalk.gray(" ")+chalk.bold.cyan("③")+chalk.gray(" ~8 min interactive intro + live MuJoCo sim")),console.log(chalk.bold.green(" learn LEARNDEMO01")+chalk.gray(" ")+chalk.bold.cyan("④")+chalk.gray(" free 11-card intro (paste this command as-is)")),console.log(chalk.bold.green(" learn ")+chalk.bold.yellow("EA")+chalk.gray(" + 8 chars full 96 / 360 curriculum (team-issued)")),console.log(chalk.bold.green(" exam ")+chalk.bold.yellow("PDxxxxxxxx")+chalk.gray(" Paper D (CTF4EAI) — national selection contestants")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(),console.log(chalk.gray(" Three open tiers: ")+chalk.green("free 11")+chalk.gray(" · ")+chalk.yellow("registered 100")+chalk.gray(" · ")+chalk.bold.magenta("national team 480")+chalk.gray(" (PhD-ready)")),console.log(chalk.gray(" Country team contact: ")+chalk.cyan("australia@icoa2026.au")),console.log(),f(),console.log()}();else if("instant"===oe)console.log(chalk.cyan.bold(" [⚡ Try ICOA in 30 seconds — no token needed]")),console.log(),console.log(chalk.gray(" Three 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(chalk.bold.green(" kaggle")+chalk.gray(" ML practice — train a model, real board ")+chalk.bold.magenta("📊 data-science")),console.log(),console.log(chalk.gray(" Type ")+chalk.bold.cyan("demo")+chalk.gray(", ")+chalk.bold.cyan("demo2")+chalk.gray(" or ")+chalk.bold.cyan("kaggle")+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"}),oe="selection";else{if("learn"===oe){console.log(chalk.cyan.bold(" [🧠 Learn]")),console.log(),console.log(chalk.gray(" Three tracks · same difficulty curve.")),console.log(),console.log(chalk.white(" Free 12-card demos — paste the full command:")),console.log(),console.log(chalk.gray(" 🤝 ai4ctf AI as your teammate ")+chalk.bold.yellow("learn AI4CTFDEMO01")),console.log(chalk.gray(" 🔓 ctf4ai AI as your target ")+chalk.bold.yellow("learn CTF4AIDEMO01")),console.log(chalk.gray(" 🤖 ctf4eai Embodied AI Security ")+chalk.bold.yellow("learn LEARNDEMO01")),console.log(),console.log(chalk.gray(" Got a cohort token? Type ")+chalk.bold.yellow("learn <TOKEN>")+chalk.gray(" (e.g. ")+chalk.bold.yellow("learn EAABCD1234")+chalk.gray(").")),console.log();try{const{input:o}=await import("@inquirer/prompts"),{resolveLearnInput:t}=await import("./lib/learn-input.js");console.log(chalk.gray(" Enter a token (or just press Enter to go back).")),console.log();const n=async()=>{try{await o({message:chalk.bold.yellow("Press Enter to return to the menu"),theme:{prefix:"",style:{message:o=>o}}})}catch{}},l=3;for(let s=1;s<=l;s++){const r=await o({message:chalk.bold.cyan("icoa learn>"),theme:{prefix:"",style:{message:o=>o}}}),i=r.trim().toLowerCase();if("ai4ioai"===i||"/ai4ioai"===i){const{runAi4ioaiStandalone:o}=await import("./commands/ai4ioai.js");return await o(),await n(),a({mode:"selection"}),void w()}if("ioailab"===i||"/ioailab"===i){const{runIoailabStandalone:o}=await import("./commands/ioailab.js");return await o(),await n(),a({mode:"selection"}),void w()}const c=t(r);if("back"===c.kind)break;if("ambiguous"===c.kind||"unknown"===c.kind){if(console.log(),console.log(chalk.yellow(` ${c.hint}`)),console.log(),s===l){console.log(chalk.gray(` That was attempt ${l} of ${l} — going back to the menu.`)),console.log(chalk.gray(" Your token comes from your country team leader; the free demos need no token.")),console.log(),await n();break}continue}if(!/^[A-Z0-9]+DEMO01$/i.test(c.token)&&/^[A-Z]{2}[A-Z0-9]{8}$/i.test(c.token)){console.log(),console.log(chalk.gray(" Checking token…"));const{validateEAToken:o}=await import("./lib/learn-curricula.js"),e=await o(c.token);if(!e.ok){if(console.log(),console.log(chalk.red(` ✗ Token check failed: ${e.message||"validation failed"}`)+(e.code?chalk.gray(` [${e.code}]`):"")),"device_bound"===e.code?(console.log(chalk.gray(" This learn token is bound to the first computer it was used on,")),console.log(chalk.gray(" and this is a different computer. Ask the coordinator who issued")),console.log(chalk.gray(" it to move it to this device, then try again."))):"expired"===e.code?console.log(chalk.gray(" This learn token has expired — ask your coordinator for a new one.")):(console.log(chalk.gray(" Possible causes:")),console.log(chalk.gray(" · Typo in token (check 0/O, 1/I/L, V/U)")),console.log(chalk.gray(" · Token expired or revoked")),console.log(chalk.gray(" · Network down (check connection)"))),console.log(),s<l){console.log(chalk.gray(" Try again — or press Enter to go back.")),console.log();continue}await n();break}}console.log(),console.log(chalk.gray(" Opening ")+chalk.bold.cyan("learn")+chalk.gray(`: ${c.token}`)),console.log(),a({mode:"selection"}),process.env.ICOA_LEARN_EMBEDDED="1";const{setLearnSessionStarted:g}=await import("./lib/learn-outcome.js");g(!1);try{await e.parseAsync(["node","icoa","learn",c.token])}catch(o){console.log(),console.log(chalk.red(` ✗ learn failed to start: ${o instanceof Error?o.message:String(o)}`)),console.log()}finally{delete process.env.ICOA_LEARN_EMBEDDED}await n();break}}catch{}return a({mode:"selection"}),void w()}"organizer"===oe?(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(),Xo?(console.log(chalk.green(` Logged in as ${Mo.userName}`)),console.log(chalk.white(" exam list")+chalk.gray(" Manage exams")),console.log(chalk.white(" logout")+chalk.gray(" Disconnect"))):console.log(chalk.white(" join <url>")+chalk.gray(" Connect to manage exams")),console.log(),f(),console.log()):(console.log(` ${chalk.cyan.bold("🏆 ICOA 2026 · International Olympiad")}`),console.log(),Jo&&!y()?(console.log(chalk.red(" Token was activated on a different device.")),console.log(chalk.gray(" Contact organizer for assistance.")),console.log()):Xo?(console.log(chalk.green.bold(` Welcome back, ${Mo.userName}!`)),console.log(chalk.gray(` Connected to ${Mo.ctfdUrl}`)),console.log(chalk.gray(" Not you? Type ")+chalk.cyan("logout")+chalk.gray(" to switch accounts")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" Ready to compete? Start here:")),console.log(),console.log(chalk.bold.cyan(" challenges")+chalk.gray(" Browse challenges by category")),console.log(chalk.white(" status")+chalk.gray(" Your score & timer")),console.log(chalk.white(" scoreboard")+chalk.gray(" Live rankings")),console.log(chalk.white(" memo")+chalk.gray(" Report an issue to organizers (one-way)")),console.log(),console.log(chalk.gray(" Tool environment:")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.bold.yellow(" ★ ")+chalk.bold.cyan("man <tool>")+chalk.gray(" How to USE a tool (steghide, nmap…) · ")+chalk.cyan("man tools")+chalk.gray(" = list")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("help")+chalk.gray(" · ")+b()+chalk.gray(" · ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+chalk.cyan("quit")+chalk.gray(" closes")),console.log()):Jo?($o(Po)||To(Po,{recursive:!0}),console.log(chalk.green.bold(" Welcome, competitor!")),console.log(chalk.gray(` Workspace: ${Po}`)),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" Get started:")),console.log(),console.log(chalk.white(" Step 1 ")+chalk.bold.cyan("join <url>")+chalk.gray(" Connect to competition server")),console.log(chalk.white(" Step 2 ")+chalk.bold.cyan("challenges")+chalk.gray(" Browse & solve challenges")),console.log(chalk.white(" Step 3 ")+chalk.bold.cyan("ai4ctf")+chalk.gray(" Ask AI when stuck")),console.log(),console.log(chalk.gray(" Before Step 1 — make sure your tools are ready:")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.bold.yellow(" ★ ")+chalk.bold.cyan("man <tool>")+chalk.gray(" How to USE a tool (steghide, nmap…) · ")+chalk.cyan("man tools")+chalk.gray(" = list")),console.log(),console.log(chalk.gray(" Also: ")+chalk.white("help")+chalk.gray(" all commands")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+b()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()):(console.log(chalk.bold.yellow(" 🏆 You reached the finals tier.")),console.log(chalk.gray(" Full sandbox · 110 CTF tools · Sydney 2026 · this is where finalists compete.")),console.log(),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.white(" To begin, activate your competition token:")),console.log(),console.log(chalk.bold.cyan(" activate <token>")),console.log(),console.log(chalk.gray(" While waiting, explore:")),console.log(chalk.white(" ref linux")+chalk.gray(" Quick reference for Linux")),console.log(chalk.white(" ref web")+chalk.gray(" Quick reference for Web")),console.log(chalk.white(" env")+chalk.gray(" See which of the 110 CTF tools are installed")),console.log(chalk.white(" env setup")+chalk.gray(" Install anything missing (~5 min, one-time)")),console.log(chalk.white(" help")+chalk.gray(" All available commands")),console.log(chalk.gray(" ─────────────────────────────────────────────")),console.log(chalk.gray(" Tip: ")+chalk.cyan("Ctrl+C")+chalk.gray(" pauses · ")+b()+chalk.gray(" · ")+chalk.cyan("quit")+chalk.gray(" closes CLI")),console.log()))}e.exitOverride(),e.configureOutput({writeErr:()=>{},writeOut:o=>{console.log(o)}});const ee=o({input:process.stdin,output:process.stdout,prompt:Do(),terminal:!0,completer:_o});x(ee),yo(!1!==l().bracketedPaste);let te=!1;if(h(!0),co(),Lo&&(console.log(),console.log(chalk.yellow(" ⏱ A new competition day has started (Sydney time).")),console.log(chalk.gray(" For fairness, yesterday’s sign-in has been cleared. Type ")+chalk.cyan("join <url>")+chalk.gray(" to sign in with your account.")),console.log()),bo()){const o=l().userName||"this account";console.log(),console.log(chalk.yellow(" ⚠ This machine is signed in as ")+chalk.bold.white(o)+chalk.yellow(".")),console.log(chalk.gray(" Press ")+chalk.cyan("Enter")+chalk.gray(` to continue as ${o}, or type `)+chalk.cyan("logout")+chalk.gray(" to switch accounts.")),"logout"===(await new Promise(o=>{ee.question(chalk.white(" > "),e=>o(e.trim()))})).toLowerCase()&&(a({ctfdUrl:"",token:"",sessionCookie:"",userId:null,userName:"",teamId:null,country:""}),console.log(),console.log(chalk.green(" ✓ Logged out. ")+chalk.gray("Run ")+chalk.cyan("join <url>")+chalk.gray(" to sign in with your own account."))),console.log()}fo()&&po(()=>ee.prompt());let ne=null;const le=ee.prompt.bind(ee);ee.prompt=o=>{if(!(k()||I()||T()||S()||O()||Ao()||(ee.setPrompt(Do()),o)))try{for(const o of X()){const e="done"===o.status,t=o.cmd.length>40?`${o.cmd.slice(0,37)}…`:o.cmd,n=o.render?"":chalk.gray(" (")+chalk.white(t)+chalk.gray(") — ")+chalk.cyan(`tasks ${o.id}`);if(console.log((e?chalk.green(" ✓"):chalk.red(" ✗"))+chalk.white(` background task #${o.id} ${o.status}`)+n),o.render)try{o.render()}catch{}}const o=_();o&&o!==ne?(console.log(o),ne=o):o||(ne=null)}catch{}le(o)};const ae=M();ae&&(console.log(chalk.cyan(" ↻ Continue where you left off: ")+chalk.white(ae.label)+(ae.urgent?chalk.yellow(" (exam timer running)"):"")),console.log(chalk.gray(" type ")+chalk.cyan("resume")+chalk.gray(" to jump back in.")),console.log()),ee.prompt(),ee.on("line",async o=>{if(te)return;let a=uo(o.trim());if(!a)return ee.setPrompt(k()?chalk.magenta("icoa ai4ctf> "):Do()),void ee.prompt();if(/^icoa\s+\S/i.test(a)&&(a=a.replace(/^icoa\s+/i,"")),a.startsWith("/")&&!a.startsWith("//")){const o=a.slice(1).split(/\s+/)[0].toLowerCase(),t=a.slice(1+o.length).trim();if("ai"===o)return te=!0,await async function(o,e){if(k())return void(o?await A(o):console.log(chalk.gray(" You are already in the AI chat — just type your message.")));if(I())return void(o?await $(o):console.log(chalk.gray(" You are already in the CTF4AI target chat — just type your message.")));if(T())return void(o?await E(o):console.log(chalk.gray(" You are already in the Embodied-AI chat — just type your message.")));io(o?`/ai ${o}`:"/ai");const t=process.exit;process.exit=()=>{throw new Error(qo)};try{await e.parseAsync(["node","icoa","ai4ctf"])}catch(o){if(!(o instanceof Error&&o.message===qo))throw o}finally{process.exit=t}o&&k()&&await A(o)}(t,e),te=!1,ee.setPrompt(k()?chalk.magenta("icoa ai4ctf> "):Do()),void ee.prompt();!(k()||I()||T()||S()||O()||Ao())&&Uo.includes(o)&&(a=a.slice(1))}if("resume"===a.toLowerCase()){const o=M();return o?(io(`resume → ${o.command.join(" ")}`),te=!0,await Bo(e),te=!1,ee.setPrompt(k()?chalk.magenta("icoa ai4ctf> "):Do()),void ee.prompt()):(console.log(),console.log(chalk.gray(" Nothing to resume yet — start with ")+chalk.cyan("learn")+chalk.gray(" (curriculum) or ")+chalk.cyan("demo")+chalk.gray(" (taste).")),console.log(),void ee.prompt())}const s=k()||I()||T()||S()||O();if(!s&&("bg"===a.toLowerCase()||/^bg\s/i.test(a))){const o=a.replace(/^bg\s*/i,"").trim();if(!o)return console.log(),console.log(chalk.gray(" Usage: ")+chalk.cyan("bg <command>")+chalk.gray(" — run a non-interactive shell command in the background.")),console.log(chalk.gray(" e.g. ")+chalk.cyan("bg nmap -p- 10.0.0.5")+chalk.gray(" · view: ")+chalk.cyan("tasks")),console.log(),void ee.prompt();const e=ro(),t=ao(o);so({cwd:e,input:`bg ${o}`,riskFlags:t}),t.length>0&&q()&&console.log(chalk.yellow(` ⚠ Action flagged: ${t.join(", ")} — logged.`));const n=B(o,e);return console.log(),console.log(chalk.cyan(` ▸ background task #${n.id} started`)+chalk.gray(` (${J()} running)`)),console.log(chalk.gray(" ")+chalk.white(o)),console.log(chalk.gray(" view: ")+chalk.cyan("tasks")+chalk.gray(" · output: ")+chalk.cyan(`tasks ${n.id}`)),console.log(),void ee.prompt()}if(!s&&("tasks"===a.toLowerCase()||/^tasks\s/i.test(a))){const o=a.replace(/^tasks\s*/i,"").trim(),e=Q();if(console.log(),o){const e=Y(Number(o));if(!e||Number.isNaN(Number(o)))console.log(chalk.yellow(` No background task #${o}.`)+chalk.gray(" Type ")+chalk.cyan("tasks")+chalk.gray(" to list them."));else{const o="running"===e.status?chalk.yellow:"done"===e.status?chalk.green:chalk.red;console.log(o(` #${e.id} [${e.status}]`)+chalk.white(` ${e.cmd}`)+(null!==e.exitCode?chalk.gray(` (exit ${e.exitCode})`):"")),console.log(chalk.gray(" ─────────────────────────────────────────────"));const t=e.output.trim();if(t)for(const o of t.split("\n"))console.log(chalk.gray(" ")+chalk.white(o));else console.log(chalk.gray(" (no output yet)"))}}else if(0===e.length)console.log(chalk.gray(" No background tasks. Start one with ")+chalk.cyan("bg <command>")+chalk.gray("."));else{console.log(chalk.bold.white(" Background tasks"));for(const o of e){const e="running"===o.status?chalk.yellow("●"):"done"===o.status?chalk.green("✓"):chalk.red("✗"),t=Math.round(((o.endedAt??Date.now())-o.startedAt)/1e3),n=(o.endedAt?`${t}s`:`${t}s…`).padStart(5),l=o.cmd.length>48?`${o.cmd.slice(0,45)}…`:o.cmd;console.log(` ${e} `+chalk.white(`#${o.id}`)+chalk.gray(` ${n} `)+chalk.white(l))}console.log(chalk.gray(" output: ")+chalk.cyan("tasks <id>"))}return console.log(),void ee.prompt()}if(!s&&/&\s*$/.test(a)&&/^challenge\s+start\s+/i.test(a)){const o=a.replace(/\s*&\s*$/,"").trim().replace(/^challenge\s+start\s+/i,"").trim().split(/\s+/),e=o.some(o=>"-n"===o||"--new"===o),t=o.find(o=>"-n"!==o&&"--new"!==o);if(!t)return console.log(),console.log(chalk.gray(" Usage: ")+chalk.cyan("challenge start <id> &")),console.log(),void ee.prompt();if(!n())return console.log(),console.log(chalk.red(" Not connected. ")+chalk.gray("Run ")+chalk.cyan("join <url>")+chalk.gray(" first.")),console.log(),void ee.prompt();io(`challenge start ${t}${e?" --new":""} & (background)`);const l=W(`challenge start ${t}`,()=>V(t,e),o=>G(t,o));return console.log(),console.log(chalk.cyan(` ▸ background task #${l.id}: `)+chalk.white(`starting ${t}`)+chalk.gray(" — you can keep working; the connection info appears here when it is ready.")),console.log(),void ee.prompt()}if(!s&&a.startsWith("#")){const o=a.slice(1).trim();if(!o)return console.log(),console.log(chalk.gray(" Usage: ")+chalk.cyan("#<candidate answer>")+chalk.gray(" — stage a flag/answer WITHOUT submitting it. Review with ")+chalk.cyan("drafts")+chalk.gray(".")),console.log(),void ee.prompt();const e=R(),t=e?.session?.examId??null,n=e?e._lastQ||1:null,l=H(o,t,n);return io(`draft #${l.id} (not submitted)`),console.log(),console.log(chalk.green(` ✎ draft #${l.id} saved`)+(n?chalk.gray(` (Q${n})`):"")+chalk.yellow(" — NOT submitted.")),console.log(chalk.gray(" review with ")+chalk.cyan("drafts")+chalk.gray("; when sure, submit it the normal way.")),console.log(),void ee.prompt()}if(!s&&("drafts"===a.toLowerCase()||/^drafts\s/i.test(a))){const o=a.replace(/^drafts\s*/i,"").trim().toLowerCase();if("clear"===o){const o=oo();return console.log(),console.log(chalk.gray(` Cleared ${o} draft${1===o?"":"s"}.`)),console.log(),void ee.prompt()}const e=o.match(/^(?:rm|remove|del|delete)\s+(\d+)$/);if(e){const o=K(Number(e[1]));return console.log(),console.log(o?chalk.gray(` Removed draft #${e[1]}.`):chalk.yellow(` No draft #${e[1]}.`)),console.log(),void ee.prompt()}const t=R(),n=Z(t?.session?.examId??null);if(console.log(),0===n.length)console.log(chalk.gray(" No drafts yet. Stage a candidate with ")+chalk.cyan("#ICOA{maybe_this}")+chalk.gray(" — it won’t submit."));else{console.log(chalk.bold.white(" Draft answers")+chalk.gray(" (staged — not submitted)"));for(const o of n){const e=o.q?chalk.cyan(`Q${o.q}`.padStart(4)):chalk.gray(" · ");console.log(chalk.gray(` #${o.id}`)+` ${e} `+chalk.white(o.text.length>56?`${o.text.slice(0,53)}…`:o.text))}console.log(chalk.gray(" remove: ")+chalk.cyan("drafts rm <id>")+chalk.gray(" · clear all: ")+chalk.cyan("drafts clear"))}return console.log(),void ee.prompt()}if("menu"===a||"menu confirm"===a)return q()&&"menu confirm"!==a?(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 ee.prompt()):void w(ee);if(k()){te=!0;const o=await A(a);return te=!1,"exit"===o&&ee.setPrompt(Do()),void ee.prompt()}if(I()){te=!0;const o=await $(a);return te=!1,"exit"!==o&&"solved"!==o||ee.setPrompt(Do()),void ee.prompt()}if(T()){te=!0;const o=await E(a);return te=!1,"exit"===o&&ee.setPrompt(Do()),ee.setPrompt(T()?chalk.bold.cyan("icoa ctf4eai> "):Do()),void ee.prompt()}if(io(a),"exit"===a)return R()?(console.log(),console.log(chalk.yellow(" ⚠ An exam is in progress.")),console.log(chalk.white(" To return to menu without losing progress, type: ")+chalk.bold.cyan("back")),console.log(chalk.white(" To fully close ICOA CLI, type: ")+chalk.bold.cyan("quit")),console.log(chalk.gray(" Your progress is auto-saved either way.")),console.log(),void ee.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"===oe&&Wo(),void ee.prompt());if("quit"===a||"q"===a||"quit confirm"===a){const o=R();return o&&"demo-free"!==o.session.examId&&"quit confirm"!==a?(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 ee.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)."))),go(),mo(),ho(),z(),m(),console.log(chalk.gray(" Session saved. Use ")+chalk.white("icoa --resume")+chalk.gray(" to continue.")),eo(),void zo(0))}if("back"===a){const o=R(),e=o&&"demo-free"!==o.session.examId,t=o&&"demo-free"===o.session.examId&&(()=>{const e=new Date(o.session.startedAt||0).getTime();return Date.now()-e<18e5})();if(e)console.log(),console.log(chalk.gray(" Exam paused. Your progress is saved.")),console.log(chalk.white(" Resume: exam q 1")+chalk.gray(" · ")+chalk.white("exam review")+chalk.gray(" · ")+chalk.white("exam submit")),console.log();else if(t){const e=Object.keys(o.answers).length,t=o.session.questionCount;console.log(),console.log(chalk.gray(` Demo paused (${e}/${t} answered). Resume with: `)+chalk.white("exam q 1")),console.log(chalk.gray(" Or type ")+chalk.white("demo")+chalk.gray(" to restart.")),console.log()}else{if(o&&"demo-free"===o.session.examId){const{clearExamState:o}=await import("./lib/exam-state.js");o("demo-free")}const e=l();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"===oe?Wo():console.log(chalk.gray(" Already at main menu."))}return void ee.prompt()}if("help"===a||"?"===a){if(R()){te=!0;try{await e.parseAsync(["node","icoa","exam","help"])}catch{}return te=!1,void ee.prompt()}return Yo(i(),oe),void ee.prompt()}if("man"===a||"manual"===a)return Yo(i(),oe),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 ee.prompt();if(/^(?:man|manual)\s+\S/i.test(a))return C(a.replace(/^(?:man|manual)\s+/i,"")),void ee.prompt();if("more help"===a.toLowerCase()&&R()){te=!0;try{await e.parseAsync(["node","icoa","exam","more-help"])}catch{}return te=!1,void ee.prompt()}if("continue"===a.toLowerCase())return console.log(),console.log(chalk.green.bold(" ═══ AI4CTF — AI as Your Teammate ═══")),console.log(),console.log(chalk.white(" In AI4CTF, you solve cybersecurity challenges")),console.log(chalk.white(" with AI by your side.")),console.log(),console.log(chalk.white(" In this demo, your AI teammate gives help at 3 levels:")),console.log(chalk.yellow(" hint a")+chalk.gray(" General guidance")),console.log(chalk.yellow(" hint b")+chalk.gray(" Deep analysis")),console.log(chalk.yellow(" hint c")+chalk.gray(" Critical assist")),console.log(),console.log(chalk.white(" Try it now! Type: ")+chalk.bold.green("ai4ctf")),console.log(chalk.gray(' Chat freely with your AI teammate. Type "exit" when done.')),console.log(),console.log(chalk.gray(" After ai4ctf, try: ")+chalk.bold.red("ctf4ai")+chalk.gray(' — trick the AI into saying "koala"')),console.log(),void ee.prompt();if(/^ICOA-[A-Z]{2,3}-\d{1,6}$/i.test(a.trim())){te=!0;try{await e.parseAsync(["node","icoa","exam","token",a.trim()])}catch{}return te=!1,void ee.prompt()}if(/^[A-Z]{2}[0-9A-HJKMNP-TV-Z]{8}$/i.test(a.trim())){te=!0;try{await e.parseAsync(["node","icoa","exam","token",a.trim().toUpperCase()])}catch{}return te=!1,void ee.prompt()}const r=a.match(/^exam\s+([A-Z]{2}[0-9A-HJKMNP-TV-Z]{8})$/i);if(r){te=!0;try{await e.parseAsync(["node","icoa","exam","token",r[1].toUpperCase()])}catch{}return te=!1,void ee.prompt()}const d=a.match(/^exam\s+([A-Z]{2,3})$/i);if(d){te=!0;try{await e.parseAsync(["node","icoa","exam","list",d[1]])}catch{}return te=!1,void ee.prompt()}if("clear"===a||"cls"===a)return console.clear(),void ee.prompt();if("news"===a)return fo()?wo():console.log(chalk.gray(" No competition joined. Use ")+chalk.white("join <url>")+chalk.gray(".")),void ee.prompt();if("memo"===a){if(!fo())return console.log(chalk.gray(" Join a competition first: ")+chalk.white("join <url>")),void ee.prompt();te=!0;try{await Co()}catch{}return void(te=!1)}const u=vo()||xo(l().userName||"");if("jury"===a&&u){te=!0;try{await Io()}catch{}return void(te=!1)}if(u&&vo()&&"scoreboard"===a.split(/\s+/)[0]){te=!0;try{const o=await ko();if(console.log(),0===o.length)console.log(chalk.gray(" Scoreboard is empty."));else{console.log(chalk.bold.white(" Scoreboard"));for(const e of o.slice(0,50))console.log(chalk.gray(` ${String(e.pos).padStart(3)}. `)+chalk.white(e.name.padEnd(28).slice(0,28))+chalk.cyan(String(e.score)))}console.log()}catch{}return te=!1,void ee.prompt()}if(u&&bo()){const o=a.split(/\s+/)[0];if(["challenges","open","submit","hint"].includes(o))return console.log(),console.log(chalk.yellow(" Team-leader account — the challenge bracket is not available here.")),console.log(chalk.gray(" Available: ")+chalk.white("scoreboard")+chalk.gray(" · ")+chalk.white("news")+chalk.gray(" · ")+chalk.white("jury")+chalk.gray(" · ")+chalk.white("time")+chalk.gray(" · ")+chalk.white("status")+chalk.gray(" · ")+chalk.white("logout")),console.log(),void ee.prompt()}if(a.startsWith("activate ")){const o=a.slice(9).trim(),e=c(o);return"ok"===e?console.log(chalk.green(" Access granted! Token bound to this device.")):"already_bound"===e?(console.log(),console.log(chalk.red(" Token already activated on a different device.")),console.log(chalk.gray(" Each token binds to the first device that uses it. If you lost the device,")),console.log(chalk.gray(" contact your proctor to have the token re-issued for a new device."))):(console.log(),console.log(chalk.red(" Token not recognized.")),console.log(chalk.gray(" Possible reasons:")),console.log(chalk.white(" • ")+chalk.gray("Typo — access tokens are case-insensitive and look like ")+chalk.cyan("ICOA-XXXX-XXXX-XXXX")+chalk.gray(" (4-char hex groups, e.g. ICOA-385E-27F2-B21B)")),console.log(chalk.white(" • ")+chalk.gray("Expired — ask your proctor or organizer for a fresh token")),console.log(chalk.white(" • ")+chalk.gray("Network — verify connection to ")+chalk.cyan("practice.icoa2026.au")),console.log(chalk.gray(" Still stuck? type ")+chalk.cyan("help")+chalk.gray(" or try ")+chalk.cyan("exam demo")+chalk.gray(" for a free practice round."))),console.log(),void ee.prompt()}if("activate"===a)return console.log(chalk.gray(" Usage: ")+chalk.white("activate <token>")),console.log(),void ee.prompt();const p=R();if(p){const o=a.toUpperCase().trim(),t=o=>{const e=p.questions.find(e=>e.number===o);return!!e&&("ai4ctf"===e.type||"ctf4ai"===e.type||e.options&&!e.options.A&&!e.options.B)},n=o=>{const e=p.questions.find(e=>e.number===o);return"short_answer"===e?.type},l=o=>{const e="demo-free"!==p.session.examId,t=p.questions.find(e=>e.number===o),n=U(t?.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 a=p._lastQ||1;if(t(a))return l(a),void ee.prompt();if(n(a))return console.log(),console.log(chalk.yellow(` Q${a} 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 ${a} 42`)+chalk.gray(")")),console.log(),void ee.prompt();te=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(a),o])}catch{}return te=!1,void ee.prompt()}if(/^-?\d+$/.test(o)){const t=p._lastQ||1;if(n(t)){te=!0;try{await e.parseAsync(["node","icoa","exam","answer",String(t),o])}catch{}return te=!1,void ee.prompt()}}const s=o.match(/^(\d+)\s+([ABCDE]|-?\d+)$/);if(s){const o=parseInt(s[1],10);if(t(o))return l(o),void ee.prompt();te=!0;try{await e.parseAsync(["node","icoa","exam","answer",s[1],s[2]])}catch{}return te=!1,void ee.prompt()}}const h=a.split(/\s+/)[0].toLowerCase(),f=/^python3?(\.\d+)?$/.test(h),b="ls"===h||"pwd"===h||"tmux"===h,x=a.startsWith("!")||h.startsWith("!")||f||b,j=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"]),N=()=>{console.log(chalk.gray(" Shell commands need ")+chalk.bold.cyan("!")+chalk.gray(" prefix. Try: ")+chalk.bold.cyan(`!${a}`)),console.log()};if("embodied"===oe&&!x&&!["doctor","demo2","learn","exam","ctf4eai","ctf4vla","eai","arena","lang","ref","setup","env","aienv","ipynb","kaggle","guide","sim"].includes(h))return j.has(h)?(N(),void ee.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 ee.prompt());if("selection"===oe&&!x&&!["doctor","exam","demo","demo2","demo4","demo5","retry","nations","next","prev","continue","setup","lang","ref","ai4ctf","ctf4ai","mark","unmark","review","submit","env","aienv","ipynb","kaggle","guide","sim"].includes(h)){if(j.has(h))return N(),void ee.prompt();if(console.log(chalk.gray(" Not available in Selection mode.")),p){const o=p._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 ee.prompt()}if("organizer"===oe&&!["doctor","join","exam","demo","retry","next","prev","logout","setup","lang","ref","ctf","mark","unmark","review","submit","tmux"].includes(h))return console.log(chalk.gray(" Not available in Organizer mode. Switch via: setup")),console.log(),void ee.prompt();if(!("olympiad"!==oe||i()&&y()||g(h)))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 ee.prompt();if(!["join","activate","challenges","ch","open","submit","flag","scoreboard","sb","status","time","ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","kaggle","guide","ai4ctf","model","ctf","exam","demo","retry","nations","next","prev","continue","logout","ctf4ai","mark","unmark","review","submit","learn","demo2","demo4","demo5","ctf4eai","ctf4vla","theme","sim","arena","eai","board","learn-pull","doctor"].includes(h)){if("tmux"===h)try{t("command -v tmux",{stdio:"ignore"})}catch{return console.log(chalk.yellow(" tmux is not installed yet.")),console.log(chalk.gray(" Install it with ")+chalk.bold.cyan("env setup")+chalk.gray(" (full toolkit) or ")+chalk.bold.cyan("darwin"===process.platform?"brew install tmux":"sudo apt install tmux")+chalk.gray(".")),console.log(),void ee.prompt()}if(Ro.has(h))return console.log(chalk.yellow(` "${h}" 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(`!${a}`)),console.log(),void ee.prompt();if(/(?:^|\s)(?:\/(?!home\/|Users\/|tmp\/)|\.\.\/|~\/)/.test(a)&&!a.startsWith("cd ")){const o=/(?:^|\s)\/(?!home\/\w+\/icoa-workspace|Users\/\w+\/icoa-workspace|tmp\/)/.test(a),e=/\.\./.test(a);if(o||e)return console.log(chalk.red(" Blocked: access outside workspace is not allowed.")),console.log(chalk.gray(` Workspace: ${Po}`)),console.log(),void ee.prompt()}let o=a.startsWith("!")?a.slice(1).trim():a;if("darwin"===process.platform){const e="/opt/homebrew/opt/python@3.12/bin/python3.12";o=o.replace(/^python3?\s/,`${e} `).replace(/^(python3|python)$/,e)}else if("win32"===process.platform){const e=(()=>{try{return t("py -3 --version",{stdio:["ignore","ignore","ignore"],timeout:1500}),"py -3"}catch{}return"python"})();o=o.replace(/^python3?(\.\d+)?\s/,`${e} `).replace(/^python3?(\.\d+)?$/,e)}else{const e=(()=>{try{return t("which python3.12",{stdio:"ignore"}),"python3.12"}catch{return"python3"}})();o=o.replace(/^python\s/,`${e} `).replace(/^python$/,e)}const e=ro(),n=ao(a);so({cwd:e,input:a,riskFlags:n}),n.length>0&&q()&&(console.log(chalk.yellow(` ⚠ Action flagged: ${n.join(", ")} — logged.`)),console.log()),/^(\S*python3?(\.\d+)?)\s*$/.test(o)&&(o=`PYTHONSTARTUP="${function(){const o=Oo(jo(),".icoa");$o(o)||To(o,{recursive:!0});const e=Oo(o,"python-startup.py");let t="";if($o(e))try{t=Eo(e,"utf-8")}catch{}return t!==No&&So(e,No),e}()}" ${o}`,console.log(),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(chalk.bold.white(" Python ready — ICOA exam toolkit pre-loaded")),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log(),console.log(chalk.white(" Already imported: ")+chalk.gray("base64, struct, hashlib, re, json, binascii")),console.log(chalk.white(" Also available: ")+chalk.gray("requests, bs4, numpy, PIL.Image, AES, pad/unpad, xor, p32/u32/p64/u64")),console.log(),console.log(chalk.yellow(" Quick examples:")),console.log(chalk.gray(' base64.b64decode("aGVsbG8=") ')+chalk.gray("# decode base64")),console.log(chalk.gray(' bytes.fromhex("48656c6c6f") ')+chalk.gray("# hex → bytes")),console.log(chalk.gray(' "ICOA{x}".encode() ')+chalk.gray("# str → bytes")),console.log(chalk.gray(" [chr(c) for c in [73,67,79,65]] ")+chalk.gray("# ASCII codes")),console.log(chalk.gray(' xor(bytes.fromhex("0a2b"), b"IC") ')+chalk.gray("# pwntools XOR")),console.log(),console.log(chalk.gray(" Exit: ")+chalk.white("exit()")+chalk.gray(" or Ctrl-D")),console.log(chalk.cyan(" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")),console.log()),te=!0;try{await lo()&&await to()?await no(o,ee):await Qo(o,ee,e)}catch{console.log(chalk.yellow(` Command failed: ${h}`))}return te=!1,console.log(),void ee.prompt()}te=!0;const L=a.trim(),D=L.toLowerCase();let P,F=null,_="";if(p)if("submit"===D)F="final";else if(D.startsWith("submit ")){let o=L.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)?(F="flag",_=o):o&&/^[ABCDE]$/i.test(o)&&(F="flag",_=o.toUpperCase())}else/^ICOA\{[^}]+\}$/i.test(L)&&(F="flag",_=L);P="final"===F?["exam","submit"]:"flag"===F?["exam","answer",String(p?._lastQ||1),_]:function(o){const e=o.split(/\s+/),t=e[0].toLowerCase(),n=e.slice(1);if("aienv"===t&&["run","python","py"].includes((n[0]??"").toLowerCase()))return v(o);if(("submit"===t||"flag"===t)&&n.length>=2)return["ctf","submit",n[0],n.slice(1).join(" ").trim().replace(/^["'`]+|["'`]+$/g,"")];if("connect"===t&&n.length>=2){const e=v(o);return["connect",e[1]??n[0],e.slice(2).join(" ")]}const l={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 l[t]?l[t]:["ref","shell","files","view","connect","challenge","note","notes","logbook","log","man","manual","lang","setup","env","aienv","ipynb","kaggle","guide","ai4ctf","model","ctf","exam","ctf4ai","doctor"].includes(t)?[t,...n]:e}(a);const X="ctf"===P[0]&&"join"===P[1];X&&ee.pause(),process.exit=()=>{throw new Error(qo)};try{await e.parseAsync(["node","icoa",...P])}catch(o){const e=o instanceof Error?o.message:String(o);if(e===qo);else if(e.includes("commander.unknownCommand")){const{distance:o}=await import("fastest-levenshtein"),e=["ctf","ref","shell","files","view","connect","challenge","note","notes","logbook","log","manual","lang","setup","env","aienv","ipynb","kaggle","guide","ai4ctf","exam","ctf4ai","theme","eai","board","clear","cls","quit","exit","back","menu","help","continue","activate","demo","challenges","status","scoreboard","join","logout"],t=h.split(/\s+/)[0]||h;let n={word:"",dist:1/0};for(const l of e){const e=o(t.toLowerCase(),l);e<n.dist&&(n={word:l,dist:e})}console.log(chalk.yellow(` Unknown command: ${h}.`)),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"===h||"flag"===h?(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: ${h}`)),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=zo,te=!1,X&&ee.resume()}k()?ee.setPrompt(chalk.magenta("icoa ai4ctf> ")):I()?ee.setPrompt(chalk.red("icoa ctf4ai> ")):T()&&ee.setPrompt(chalk.bold.cyan("icoa ctf4eai> ")),console.log(),ee.prompt()}),ee.on("SIGINT",()=>{if(console.log(),k()||I())console.log(chalk.yellow(" Ctrl+C did not close ICOA CLI — you are still in the AI chat.")),console.log(chalk.white(" Type ")+chalk.bold.cyan("exit")+chalk.white(" to leave the chat and return to the menu."));else if(R()){const o="demo-free"!==R().session.examId;console.log(chalk.yellow(" Ctrl+C did NOT close ICOA CLI.")),console.log(chalk.gray(` Your ${o?"exam":"demo"} is paused and every answer is auto-saved.`)),console.log(),console.log(chalk.white(" Resume: ")+chalk.cyan("exam q 1")+chalk.gray(" · Back to menu: ")+chalk.cyan("back")+chalk.gray(" · Close CLI: ")+chalk.cyan(o?"quit confirm":"quit"))}else console.log(chalk.yellow(" Ctrl+C did not close ICOA CLI — you are still at the ")+chalk.cyan("icoa>")+chalk.yellow(" prompt.")),console.log(chalk.gray(" Keep typing — ")+chalk.cyan("help")+chalk.gray(" lists commands. (Only ")+chalk.cyan("quit")+chalk.gray(" or Ctrl+D actually close the CLI.)"));console.log(),ee.prompt()}),ee.on("close",()=>{go(),mo(),ho(),z(),m(),eo(),zo(0)}),"1"===process.env.ICOA_AUTO_RESUME&&(delete process.env.ICOA_AUTO_RESUME,M()&&(te=!0,await Bo(e),te=!1,ee.setPrompt(k()?chalk.magenta("icoa ai4ctf> "):Do()),ee.prompt()))}function Qo(o,t,n){return new Promise(l=>{const a=process.stdin,s=!!a.isTTY&&!!a.isRaw;if(t.pause(),a.isTTY&&"function"==typeof a.setRawMode)try{a.setRawMode(!1)}catch{}const r=e(o,{shell:!0,stdio:"inherit",cwd:n||process.cwd()}),i=()=>{if(a.isTTY&&"function"==typeof a.setRawMode&&s)try{a.setRawMode(!0)}catch{}t.resume(),l()};r.on("close",i),r.on("error",i)})}function Yo(o,e="olympiad"){return console.log(),"selection"===e||"organizer"===e?(console.log(chalk.bold.white(" Exam")),console.log(chalk.white(" join <url> ")+chalk.gray("Connect to exam server")),console.log(chalk.white(" exam list ")+chalk.gray("Available exams")),console.log(chalk.white(" exam start <id> ")+chalk.gray("Begin an exam")),console.log(chalk.white(" exam q [n] ")+chalk.gray("View questions")),console.log(chalk.white(" exam answer <n> <X> ")+chalk.gray("Answer question")),console.log(chalk.white(" exam review ")+chalk.gray("Review all answers")),console.log(chalk.white(" exam submit ")+chalk.gray("Submit for grading")),console.log(chalk.white(" exam result ")+chalk.gray("View your score")),console.log(),console.log(chalk.bold.white(" System")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference")),console.log(chalk.white(" setup ")+chalk.gray("Settings / switch mode")),console.log(chalk.white(" lang [code] ")+chalk.gray("Switch language")),console.log(chalk.white(" clear ")+chalk.gray("Clear screen")),console.log(chalk.white(" exit ")+chalk.gray("Quit")),void console.log()):o?(console.log(chalk.cyan(" ═══════════════════════════════════════════════")),console.log(chalk.bold.white(" How it works")),console.log(),console.log(chalk.gray(" 1. Browse ")+chalk.white("challenges")+chalk.gray(" and pick one")),console.log(chalk.gray(" 2. ")+chalk.white("open <id>")+chalk.gray(" to read the challenge")),console.log(chalk.gray(" 3. Use ")+chalk.white("ai4ctf")+chalk.gray(" to chat with AI when stuck")),console.log(chalk.gray(" 4. ")+chalk.white("submit <id> <flag>")+chalk.gray(" to score points")),console.log(chalk.gray(" 5. Check ")+chalk.white("scoreboard")+chalk.gray(" to track your rank")),console.log(chalk.cyan(" ═══════════════════════════════════════════════")),console.log(),console.log(chalk.bold.white(" Competition")),console.log(chalk.white(" join <url> ")+chalk.gray("Connect to CTFd")),console.log(chalk.white(" challenges (ch) ")+chalk.gray("List challenges by category")),console.log(chalk.white(" open <id> ")+chalk.gray("Read challenge + get next steps")),console.log(chalk.white(" submit <id> <flag> ")+chalk.gray("Submit a flag")),console.log(chalk.white(" scoreboard (sb) ")+chalk.gray("Live rankings")),console.log(chalk.white(" status ")+chalk.gray("Your score & timer")),console.log(chalk.white(" time ")+chalk.gray("Countdown timer")),console.log(),console.log(chalk.bold.white(" AI Teammate")),console.log(chalk.white(" ai4ctf ")+chalk.gray("Free-chat with your AI teammate")),console.log(),console.log(chalk.bold.white(" Tools")),console.log(chalk.white(" ref [topic] ")+chalk.gray("Quick reference (linux, web, crypto...)")),console.log(chalk.white(" shell ")+chalk.gray("Interactive CTF shell (sandbox if present, else host)")),console.log(chalk.white(" files <id> ")+chalk.gray("Download challenge files")),console.log(chalk.white(" connect <id> ")+chalk.gray("Connect to remote target")),console.log(chalk.white(" note [text] ")+chalk.gray("Add a logbook entry (in-exam: tags current Q)")),console.log(chalk.white(" logbook [n] ")+chalk.gray("View your logbook (in-exam: filter by Q)")),console.log(chalk.white(" log ")+chalk.gray("Session history")),console.log(chalk.white(" man <tool> ")+chalk.bold.yellow("★ ")+chalk.gray("How to use a tool (steghide, nmap…); ")+chalk.cyan("man tools")+chalk.gray(" = list. Bare ")+chalk.cyan("man")+chalk.gray(" = this list.")),console.log(),console.log(chalk.bold.white(" System")),console.log(chalk.white(" resume ")+chalk.gray("Continue your last learn card / exam")),console.log(chalk.white(" #<candidate> ")+chalk.gray("Stage a draft answer (never auto-submits)")),console.log(chalk.white(" drafts ")+chalk.gray("Review staged draft answers")),console.log(chalk.white(" bg <command> ")+chalk.gray("Run a shell command in the background")),console.log(chalk.white(" tasks [id] ")+chalk.gray("Background task panel / view output")),console.log(chalk.white(" doctor ")+chalk.gray("Self-check: version, Python, server, tools")),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.415",
3
+ "version": "2.19.417",
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": {