icoa-cli 2.19.630 → 2.19.632
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/ai4ctf.js +1 -1
- package/dist/commands/ctf4ai-demo.js +1 -1
- package/dist/commands/ctf4vla.js +1 -1
- package/dist/commands/demo3.js +1 -0
- package/dist/commands/exam.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/algo-replay.js +1 -1
- package/dist/lib/card-engine.js +1 -1
- package/dist/lib/commands.js +1 -1
- package/dist/repl.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as o}from"commander";import chalk from"chalk";import{registerCtfCommands as e}from"./commands/ctf.js";import{registerRefCommand as n}from"./commands/ref.js";import{registerShellCommand as s}from"./commands/shell.js";import{registerFilesCommand as r}from"./commands/files.js";import{registerViewCommand as t}from"./commands/view.js";import{registerConnectCommand as i}from"./commands/connect.js";import{registerChallengeCommand as l}from"./commands/challenge.js";import{registerDoctorCommand as a}from"./commands/doctor.js";import{registerUpgradeCommand as m}from"./commands/upgrade.js";import{registerNoteCommand as c}from"./commands/note.js";import{registerLogCommand as g}from"./commands/log.js";import{registerLangCommand as d}from"./commands/lang.js";import{registerSetupCommand as p}from"./commands/setup.js";import{registerEnvCommand as y}from"./commands/env.js";import{registerAienvCommand as h}from"./commands/aienv.js";import{registerPythonCommands as f}from"./commands/python.js";import{registerMujocoCommands as u}from"./commands/mujoco.js";import{registerDuckCommand as w}from"./commands/duck.js";import{registerIpynbCommand as b}from"./commands/ipynb.js";import{registerAi4ctfCommand as j}from"./commands/ai4ctf.js";import{registerExamCommand as v}from"./commands/exam.js";import{registerCtf4aiDemoCommand as $}from"./commands/ctf4ai-demo.js";import{registerThemeCommand as T}from"./commands/theme.js";import{registerLearnCommand as A}from"./commands/learn.js";import{registerCtf4VlaCommand as I}from"./commands/ctf4vla.js";import{registerDemo2Command as E}from"./commands/demo2.js";import{registerDemo4Command as C}from"./commands/demo4.js";import{registerDemo5Command as x}from"./commands/demo5.js";import{registerGfssmCommand as _}from"./commands/gfssm.js";import{registerGpuForTaskCommand as k}from"./commands/gpufortask.js";import{registerSimCommand as S}from"./commands/sim.js";import{registerArenaCommand as L}from"./commands/arena.js";import{registerKaggleCommand as R}from"./commands/kaggle.js";import{registerSprintCommand as O}from"./commands/sprint.js";import{registerTeleloadCommand as F}from"./commands/teleload.js";import{registerBoardCommand as N}from"./commands/board.js";import{registerTypeCommand as U}from"./commands/type.js";import{registerBattleCommand as P}from"./commands/battle.js";import{registerWmCommand as M}from"./commands/wm.js";import{getConfig as D,saveConfig as G}from"./lib/config.js";import{registerMicroduckCommand as W}from"./commands/microduck.js";import{startRepl as H}from"./repl.js";import{RELAUNCH_CODE as Y}from"./lib/menu-nav.js";import{setTerminalTheme as J}from"./lib/theme.js";import{cleanupTerminal as V}from"./lib/terminal-cleanup.js";import{checkForUpdates as X,runUpgrade as q,bootUpgradeEligible as z,startBootCheck as K,printUpdateHint as B}from"./lib/update-check.js";import{detectIcoaInstalls as Q,isWindowsBuildInWslShell as Z}from"./lib/platform.js";import{ICOA_BIG as oo}from"./lib/banner.js";import{readFileSync as eo}from"node:fs";import{fileURLToPath as no}from"node:url";import{dirname as so,join as ro}from"node:path";import{setDefaultResultOrder as to}from"node:dns";import{setDefaultAutoSelectFamilyAttemptTimeout as io}from"node:net";to("ipv4first"),io(4e3);const lo=so(no(import.meta.url)),ao=JSON.parse(eo(ro(lo,"..","package.json"),"utf-8")).version,mo=chalk.cyan(" ─────────────────────────────────────────────────────"),co=`\n${mo}\n\n${oo.map(o=>` ${chalk.bold.white(o)}`).join("\n")}\n\n ${chalk.yellow("International Cyber Olympiad in AI 2026")}\n ${chalk.bold.magenta("The World's First AI-Native CLI Operating System")}\n ${chalk.bold.magenta("for Cybersecurity & AI Security Competition")}\n ${chalk.bold.magenta("and Olympiad for K-12")}\n\n ${chalk.green.bold("AI4CTF")} ${chalk.gray("[Day 1]")} ${chalk.white("AI as your teammate")}\n ${chalk.red.bold("CTF4AI")} ${chalk.gray("[Day 2]")} ${chalk.white("Challenge & evaluate AI systems")}\n ${chalk.cyan.bold("CTF4EAI")} ${chalk.gray("[Pioneer]")} ${chalk.white("Embodied AI security")}\n ${chalk.bold.yellow("AI is your teammate. AI is your target. AI is embodied.")}\n\n ${chalk.white("Sydney, Australia")} ${chalk.gray("Jun 27 - Jul 2, 2026")}\n ${chalk.cyan.underline("https://icoa2026.au")}\n\n ${chalk.gray(`CLI-Native Competition Terminal v${ao}`)}\n\n${mo}\n`;process.on("uncaughtException",o=>{"__REPL_NO_EXIT__"!==o.message&&(console.error(chalk.red("Error:"),o.message),process.exit(1))}),process.on("unhandledRejection",o=>{const e=o instanceof Error?o.message:String(o);"__REPL_NO_EXIT__"!==e&&(console.error(chalk.red("Error:"),e),process.exit(1))});{const o=process.argv.slice(2).some(o=>["-V","--version","-h","--help"].includes(o));if(!0===process.stdin.isTTY&&"1"!==process.env.ICOA_SUPERVISED&&!o){const{spawnSync:o}=await import("node:child_process");process.on("SIGINT",()=>{}),process.on("SIGTERM",()=>{});let e=0,n=!1;do{const s=n?process.argv.slice(1,2):process.argv.slice(1),r=o(process.execPath,s,{stdio:"inherit",env:{...process.env,ICOA_SUPERVISED:"1",...n?{ICOA_RELAUNCH:"1"}:{}}});if(r.signal){const{appendExitLog:o}=await import("./lib/exit-log.js");o("worker-signal",`signal=${r.signal}`),console.log(),console.log(chalk.yellow(` ⚠ icoa was stopped by signal ${r.signal}`)+chalk.gray(" — another process killed it (not a crash). Run icoa --resume to continue.")),e=0;break}if(e=r.status,0!==e&&e!==Y){const{appendExitLog:o}=await import("./lib/exit-log.js");o("worker-exit",`code=${e}`);const n=null!==e&&e>128?e-128:0;console.log(),console.log(n?chalk.yellow(` ⚠ icoa was stopped by signal ${n}`)+chalk.gray(" — another process killed it (not a crash). Run icoa --resume to continue."):chalk.yellow(` ⚠ icoa exited unexpectedly (code ${e})`)+chalk.gray(" — see ~/.icoa/exit.log · run icoa --resume to continue."))}n=!0}while(e===Y);V(),process.exit(e??0)}}const go=new o;if(go.name("icoa").version(ao).description("ICOA CLI — CLI-Native CTF Competition Terminal").option("--resume","Resume previous session").option("--continue","Continue where you left off — jump straight to your last learn card / exam").action(async o=>{const e=D();J("high-contrast"===e.themeVariant?"high-contrast":"dark");const n=!!o.resume||!!o.continue,s=z(n)&&process.argv.length<=2;s?K():X(),function(){const o=Q();if(o.length<=1)return;const e=o[0];if([...o.map(o=>o.version||"0.0.0")].sort((o,e)=>function(o,e){const n=o.split(".").map(o=>parseInt(o,10)||0),s=e.split(".").map(o=>parseInt(o,10)||0);for(let o=0;o<3;o++)if((n[o]||0)!==(s[o]||0))return(n[o]||0)-(s[o]||0);return 0}(e,o))[0]!==e.version){console.log(),console.log(chalk.yellow.bold(" ⚠ Multiple icoa installations detected on PATH:"));for(let e=0;e<o.length;e++){const n=o[e],s=n.version?`v${n.version}`:"(version unreadable)",r=0===e?chalk.yellow("→"):" ",t=0===e?chalk.gray(" ← currently running (older — shadowing newer install)"):chalk.gray(" ← shadowed");console.log(` ${r} ${chalk.cyan(n.path.padEnd(28))} ${chalk.white(s)}${t}`)}console.log(),console.log(chalk.yellow(" The first install on PATH wins. To use the newer one, remove the older:")),console.log(),e.pkgDir?console.log(` ${chalk.bold.cyan(`sudo rm -rf ${e.pkgDir} ${e.path}`)}`):console.log(` ${chalk.bold.cyan(`sudo rm -rf ${e.path} # also delete its node_modules dir`)}`),console.log(),console.log(chalk.gray(" Then re-run icoa to confirm version banner shows the newer release.")),console.log()}}();const r=process.env.LANG||process.env.LC_ALL||process.env.LC_CTYPE||"";if(!/UTF-?8/i.test(r))if("win32"===process.platform){let o="";try{const{execFileSync:e}=await import("node:child_process");o=e("chcp.com",[],{encoding:"utf-8",timeout:1500,stdio:["ignore","pipe","ignore"]}).trim()}catch{}o.includes("65001")||(console.log(chalk.yellow(`⚠ Windows terminal is not using UTF-8 (current: ${o||"unknown"}).`)),console.log(chalk.gray(' Non-English text (Ukrainian, Chinese, Japanese, etc.) may show as "?" or garbled glyphs.')),console.log(chalk.gray(" Fix (run before ")+chalk.cyan("icoa")+chalk.gray("): ")+chalk.cyan("chcp 65001")),console.log(chalk.gray(" Or stay in English inside the CLI: ")+chalk.cyan("lang en")),console.log())}else console.log(chalk.yellow(`⚠ Your terminal locale is not UTF-8 (LANG=${r||"(unset)"}).`)),console.log(chalk.gray(' Non-English text and box characters may display as "?" or garbled glyphs.')),console.log(chalk.gray(" Fix: ")+chalk.cyan("export LANG=en_US.UTF-8")+chalk.gray(" (or your locale, e.g. ")+chalk.cyan("zh_CN.UTF-8")+chalk.gray(", ")+chalk.cyan("uk_UA.UTF-8")+chalk.gray(")")),console.log();if(console.log(co),s?"upgraded"===await q({ask:!0})&&(console.log(chalk.gray(" restarting icoa …")),process.exit(Y)):B(),process.argv.length<=2||n)return o.continue&&(process.env.ICOA_AUTO_RESUME="1"),n||"1"===process.env.ICOA_RELAUNCH||await async function(){const o=process.stdin;if(o.isTTY&&"function"==typeof o.setRawMode)return new Promise(e=>{let n=!1;const s=()=>{if(!n){n=!0,o.removeListener("data",r);try{o.setRawMode(!1)}catch{}o.pause(),e()}},r=()=>s();o.setRawMode(!0),o.resume(),o.once("data",r),console.log(chalk.gray(" (press any key to continue...)")),setTimeout(s,3e3)});await new Promise(o=>setTimeout(o,3e3))}(),void H(go,n)}),e(go),n(go),s(go),r(go),t(go),i(go),l(go),a(go),m(go),c(go),g(go),d(go),p(go),y(go),h(go),f(go),u(go),w(go),b(go),j(go),v(go),$(go),T(go),A(go),I(go),E(go),C(go),x(go),_(go),k(go),S(go),L(go),R(go),F(go),O(go),N(go),M(go),U(go),P(go),W(go),go.command("model",{hidden:!0}).argument("[name]","model name to switch to").action(o=>{const e=D().geminiModel||"gemini-2.5-flash-lite";o?(G({geminiModel:o}),console.log(),console.log(chalk.green(" Model switched: ")+chalk.gray(e)+chalk.white(" -> ")+chalk.bold.white(o)),console.log()):(console.log(),console.log(chalk.gray(" Current model: ")+chalk.white(e)),console.log(),console.log(chalk.gray(" Available models:")),console.log(chalk.bold.white(" Gemini 3.x (Latest)")),console.log(chalk.white(" model gemini-3.5-flash ")+chalk.gray("Newest stable, paid Tier 1+")),console.log(chalk.white(" model gemini-3-flash-preview ")+chalk.gray("Preview")),console.log(chalk.bold.white(" Gemini 2.5 (Stable)")),console.log(chalk.white(" model gemini-2.5-flash-lite ")+chalk.gray("Fastest, default, free tier")),console.log(chalk.white(" model gemini-2.5-flash ")+chalk.gray("Heavier, thinking enabled")),console.log(chalk.white(" model gemini-2.5-pro ")+chalk.gray("Strong reasoning, paid")),console.log(chalk.bold.white(" Open Source")),console.log(chalk.white(" model gemma-4-31b-it ")+chalk.gray("Free, open-source")),console.log(chalk.white(" model <any-model-id> ")+chalk.gray("Custom model")),console.log(),console.log(chalk.gray(" Translation uses gemini-3.5-flash for best quality.")),console.log())}),"1"===process.env.ICOA_RESET_STATE)try{const{clearExamState:o}=await import("./lib/exam-state.js");o(),console.log(chalk.yellow("⚠ ICOA_RESET_STATE=1 — local exam state wiped.")),console.log(chalk.gray(" (Token NOT revoked server-side. Re-enter a fresh token with `exam <token>`.)")),console.log()}catch(o){console.log(chalk.red("⚠ ICOA_RESET_STATE: could not clear state — ")+chalk.gray(String(o)))}go.hook("preAction",()=>{!function(){if(!Z())return;const o="─".repeat(Math.max(24,Math.min(52,(process.stdout.columns||80)-4)));console.log(),console.log(chalk.yellow(` ${o}`)),console.log(chalk.yellow.bold(" ⚠ You ARE inside Ubuntu — but this icoa")),console.log(chalk.yellow.bold(" is the WINDOWS build.")),console.log(),console.log(chalk.gray(" WSL appends the Windows PATH, so ")+chalk.cyan("icoa")),console.log(chalk.gray(" found the Windows copy first. Almost")),console.log(chalk.gray(" nothing will work: no vi, no python3,")),console.log(chalk.gray(" env setup cannot install.")),console.log(),console.log(chalk.gray(" Running: ")+chalk.white(process.execPath)),console.log(),console.log(chalk.white(" Fix — inside Ubuntu, check npm is Linux FIRST:")),console.log(` ${chalk.bold.cyan("which npm")}${chalk.gray(" → must not be /mnt/c/...")}`),console.log(` ${chalk.bold.cyan("sudo npm install -g icoa-cli")}`),console.log(` ${chalk.bold.cyan("hash -r")}${chalk.gray(" → bash caches the old path")}`),console.log(chalk.gray(" Then restart icoa and check ")+chalk.bold.cyan("which icoa")),console.log(chalk.yellow(` ${o}`)),console.log()}()}),go.parse();
|
|
2
|
+
import{Command as o}from"commander";import chalk from"chalk";import{registerCtfCommands as e}from"./commands/ctf.js";import{registerRefCommand as n}from"./commands/ref.js";import{registerShellCommand as s}from"./commands/shell.js";import{registerFilesCommand as r}from"./commands/files.js";import{registerViewCommand as t}from"./commands/view.js";import{registerConnectCommand as i}from"./commands/connect.js";import{registerChallengeCommand as l}from"./commands/challenge.js";import{registerDoctorCommand as a}from"./commands/doctor.js";import{registerUpgradeCommand as m}from"./commands/upgrade.js";import{registerNoteCommand as c}from"./commands/note.js";import{registerLogCommand as g}from"./commands/log.js";import{registerLangCommand as d}from"./commands/lang.js";import{registerSetupCommand as p}from"./commands/setup.js";import{registerEnvCommand as y}from"./commands/env.js";import{registerAienvCommand as h}from"./commands/aienv.js";import{registerPythonCommands as f}from"./commands/python.js";import{registerMujocoCommands as u}from"./commands/mujoco.js";import{registerDuckCommand as w}from"./commands/duck.js";import{registerIpynbCommand as b}from"./commands/ipynb.js";import{registerAi4ctfCommand as j}from"./commands/ai4ctf.js";import{registerExamCommand as v}from"./commands/exam.js";import{registerCtf4aiDemoCommand as $}from"./commands/ctf4ai-demo.js";import{registerThemeCommand as T}from"./commands/theme.js";import{registerLearnCommand as A}from"./commands/learn.js";import{registerCtf4VlaCommand as I}from"./commands/ctf4vla.js";import{registerDemo2Command as E}from"./commands/demo2.js";import{registerDemo3Command as C}from"./commands/demo3.js";import{registerDemo4Command as x}from"./commands/demo4.js";import{registerDemo5Command as _}from"./commands/demo5.js";import{registerGfssmCommand as k}from"./commands/gfssm.js";import{registerGpuForTaskCommand as S}from"./commands/gpufortask.js";import{registerSimCommand as L}from"./commands/sim.js";import{registerArenaCommand as R}from"./commands/arena.js";import{registerKaggleCommand as O}from"./commands/kaggle.js";import{registerSprintCommand as F}from"./commands/sprint.js";import{registerTeleloadCommand as N}from"./commands/teleload.js";import{registerBoardCommand as U}from"./commands/board.js";import{registerTypeCommand as P}from"./commands/type.js";import{registerBattleCommand as M}from"./commands/battle.js";import{registerWmCommand as D}from"./commands/wm.js";import{getConfig as G,saveConfig as W}from"./lib/config.js";import{registerMicroduckCommand as H}from"./commands/microduck.js";import{startRepl as Y}from"./repl.js";import{RELAUNCH_CODE as J}from"./lib/menu-nav.js";import{setTerminalTheme as V}from"./lib/theme.js";import{cleanupTerminal as X}from"./lib/terminal-cleanup.js";import{checkForUpdates as q,runUpgrade as z,bootUpgradeEligible as K,startBootCheck as B,printUpdateHint as Q}from"./lib/update-check.js";import{detectIcoaInstalls as Z,isWindowsBuildInWslShell as oo}from"./lib/platform.js";import{ICOA_BIG as eo}from"./lib/banner.js";import{readFileSync as no}from"node:fs";import{fileURLToPath as so}from"node:url";import{dirname as ro,join as to}from"node:path";import{setDefaultResultOrder as io}from"node:dns";import{setDefaultAutoSelectFamilyAttemptTimeout as lo}from"node:net";io("ipv4first"),lo(4e3);const ao=ro(so(import.meta.url)),mo=JSON.parse(no(to(ao,"..","package.json"),"utf-8")).version,co=chalk.cyan(" ─────────────────────────────────────────────────────"),go=`\n${co}\n\n${eo.map(o=>` ${chalk.bold.white(o)}`).join("\n")}\n\n ${chalk.yellow("International Cyber Olympiad in AI 2026")}\n ${chalk.bold.magenta("The World's First AI-Native CLI Operating System")}\n ${chalk.bold.magenta("for Cybersecurity & AI Security Competition")}\n ${chalk.bold.magenta("and Olympiad for K-12")}\n\n ${chalk.green.bold("AI4CTF")} ${chalk.gray("[Day 1]")} ${chalk.white("AI as your teammate")}\n ${chalk.red.bold("CTF4AI")} ${chalk.gray("[Day 2]")} ${chalk.white("Challenge & evaluate AI systems")}\n ${chalk.cyan.bold("CTF4EAI")} ${chalk.gray("[Pioneer]")} ${chalk.white("Embodied AI security")}\n ${chalk.bold.yellow("AI is your teammate. AI is your target. AI is embodied.")}\n\n ${chalk.white("Sydney, Australia")} ${chalk.gray("Jun 27 - Jul 2, 2026")}\n ${chalk.cyan.underline("https://icoa2026.au")}\n\n ${chalk.gray(`CLI-Native Competition Terminal v${mo}`)}\n\n${co}\n`;process.on("uncaughtException",o=>{"__REPL_NO_EXIT__"!==o.message&&(console.error(chalk.red("Error:"),o.message),process.exit(1))}),process.on("unhandledRejection",o=>{const e=o instanceof Error?o.message:String(o);"__REPL_NO_EXIT__"!==e&&(console.error(chalk.red("Error:"),e),process.exit(1))});{const o=process.argv.slice(2).some(o=>["-V","--version","-h","--help"].includes(o));if(!0===process.stdin.isTTY&&"1"!==process.env.ICOA_SUPERVISED&&!o){const{spawnSync:o}=await import("node:child_process");process.on("SIGINT",()=>{}),process.on("SIGTERM",()=>{});let e=0,n=!1;do{const s=n?process.argv.slice(1,2):process.argv.slice(1),r=o(process.execPath,s,{stdio:"inherit",env:{...process.env,ICOA_SUPERVISED:"1",...n?{ICOA_RELAUNCH:"1"}:{}}});if(r.signal){const{appendExitLog:o}=await import("./lib/exit-log.js");o("worker-signal",`signal=${r.signal}`),console.log(),console.log(chalk.yellow(` ⚠ icoa was stopped by signal ${r.signal}`)+chalk.gray(" — another process killed it (not a crash). Run icoa --resume to continue.")),e=0;break}if(e=r.status,0!==e&&e!==J){const{appendExitLog:o}=await import("./lib/exit-log.js");o("worker-exit",`code=${e}`);const n=null!==e&&e>128?e-128:0;console.log(),console.log(n?chalk.yellow(` ⚠ icoa was stopped by signal ${n}`)+chalk.gray(" — another process killed it (not a crash). Run icoa --resume to continue."):chalk.yellow(` ⚠ icoa exited unexpectedly (code ${e})`)+chalk.gray(" — see ~/.icoa/exit.log · run icoa --resume to continue."))}n=!0}while(e===J);X(),process.exit(e??0)}}const po=new o;if(po.name("icoa").version(mo).description("ICOA CLI — CLI-Native CTF Competition Terminal").option("--resume","Resume previous session").option("--continue","Continue where you left off — jump straight to your last learn card / exam").action(async o=>{const e=G();V("high-contrast"===e.themeVariant?"high-contrast":"dark");const n=!!o.resume||!!o.continue,s=K(n)&&process.argv.length<=2;s?B():q(),function(){const o=Z();if(o.length<=1)return;const e=o[0];if([...o.map(o=>o.version||"0.0.0")].sort((o,e)=>function(o,e){const n=o.split(".").map(o=>parseInt(o,10)||0),s=e.split(".").map(o=>parseInt(o,10)||0);for(let o=0;o<3;o++)if((n[o]||0)!==(s[o]||0))return(n[o]||0)-(s[o]||0);return 0}(e,o))[0]!==e.version){console.log(),console.log(chalk.yellow.bold(" ⚠ Multiple icoa installations detected on PATH:"));for(let e=0;e<o.length;e++){const n=o[e],s=n.version?`v${n.version}`:"(version unreadable)",r=0===e?chalk.yellow("→"):" ",t=0===e?chalk.gray(" ← currently running (older — shadowing newer install)"):chalk.gray(" ← shadowed");console.log(` ${r} ${chalk.cyan(n.path.padEnd(28))} ${chalk.white(s)}${t}`)}console.log(),console.log(chalk.yellow(" The first install on PATH wins. To use the newer one, remove the older:")),console.log(),e.pkgDir?console.log(` ${chalk.bold.cyan(`sudo rm -rf ${e.pkgDir} ${e.path}`)}`):console.log(` ${chalk.bold.cyan(`sudo rm -rf ${e.path} # also delete its node_modules dir`)}`),console.log(),console.log(chalk.gray(" Then re-run icoa to confirm version banner shows the newer release.")),console.log()}}();const r=process.env.LANG||process.env.LC_ALL||process.env.LC_CTYPE||"";if(!/UTF-?8/i.test(r))if("win32"===process.platform){let o="";try{const{execFileSync:e}=await import("node:child_process");o=e("chcp.com",[],{encoding:"utf-8",timeout:1500,stdio:["ignore","pipe","ignore"]}).trim()}catch{}o.includes("65001")||(console.log(chalk.yellow(`⚠ Windows terminal is not using UTF-8 (current: ${o||"unknown"}).`)),console.log(chalk.gray(' Non-English text (Ukrainian, Chinese, Japanese, etc.) may show as "?" or garbled glyphs.')),console.log(chalk.gray(" Fix (run before ")+chalk.cyan("icoa")+chalk.gray("): ")+chalk.cyan("chcp 65001")),console.log(chalk.gray(" Or stay in English inside the CLI: ")+chalk.cyan("lang en")),console.log())}else console.log(chalk.yellow(`⚠ Your terminal locale is not UTF-8 (LANG=${r||"(unset)"}).`)),console.log(chalk.gray(' Non-English text and box characters may display as "?" or garbled glyphs.')),console.log(chalk.gray(" Fix: ")+chalk.cyan("export LANG=en_US.UTF-8")+chalk.gray(" (or your locale, e.g. ")+chalk.cyan("zh_CN.UTF-8")+chalk.gray(", ")+chalk.cyan("uk_UA.UTF-8")+chalk.gray(")")),console.log();if(console.log(go),s?"upgraded"===await z({ask:!0})&&(console.log(chalk.gray(" restarting icoa …")),process.exit(J)):Q(),process.argv.length<=2||n)return o.continue&&(process.env.ICOA_AUTO_RESUME="1"),n||"1"===process.env.ICOA_RELAUNCH||await async function(){const o=process.stdin;if(o.isTTY&&"function"==typeof o.setRawMode)return new Promise(e=>{let n=!1;const s=()=>{if(!n){n=!0,o.removeListener("data",r);try{o.setRawMode(!1)}catch{}o.pause(),e()}},r=()=>s();o.setRawMode(!0),o.resume(),o.once("data",r),console.log(chalk.gray(" (press any key to continue...)")),setTimeout(s,3e3)});await new Promise(o=>setTimeout(o,3e3))}(),void Y(po,n)}),e(po),n(po),s(po),r(po),t(po),i(po),l(po),a(po),m(po),c(po),g(po),d(po),p(po),y(po),h(po),f(po),u(po),w(po),b(po),j(po),v(po),$(po),T(po),A(po),I(po),E(po),C(po),x(po),_(po),k(po),S(po),L(po),R(po),O(po),N(po),F(po),U(po),D(po),P(po),M(po),H(po),po.command("model",{hidden:!0}).argument("[name]","model name to switch to").action(o=>{const e=G().geminiModel||"gemini-2.5-flash-lite";o?(W({geminiModel:o}),console.log(),console.log(chalk.green(" Model switched: ")+chalk.gray(e)+chalk.white(" -> ")+chalk.bold.white(o)),console.log()):(console.log(),console.log(chalk.gray(" Current model: ")+chalk.white(e)),console.log(),console.log(chalk.gray(" Available models:")),console.log(chalk.bold.white(" Gemini 3.x (Latest)")),console.log(chalk.white(" model gemini-3.5-flash ")+chalk.gray("Newest stable, paid Tier 1+")),console.log(chalk.white(" model gemini-3-flash-preview ")+chalk.gray("Preview")),console.log(chalk.bold.white(" Gemini 2.5 (Stable)")),console.log(chalk.white(" model gemini-2.5-flash-lite ")+chalk.gray("Fastest, default, free tier")),console.log(chalk.white(" model gemini-2.5-flash ")+chalk.gray("Heavier, thinking enabled")),console.log(chalk.white(" model gemini-2.5-pro ")+chalk.gray("Strong reasoning, paid")),console.log(chalk.bold.white(" Open Source")),console.log(chalk.white(" model gemma-4-31b-it ")+chalk.gray("Free, open-source")),console.log(chalk.white(" model <any-model-id> ")+chalk.gray("Custom model")),console.log(),console.log(chalk.gray(" Translation uses gemini-3.5-flash for best quality.")),console.log())}),"1"===process.env.ICOA_RESET_STATE)try{const{clearExamState:o}=await import("./lib/exam-state.js");o(),console.log(chalk.yellow("⚠ ICOA_RESET_STATE=1 — local exam state wiped.")),console.log(chalk.gray(" (Token NOT revoked server-side. Re-enter a fresh token with `exam <token>`.)")),console.log()}catch(o){console.log(chalk.red("⚠ ICOA_RESET_STATE: could not clear state — ")+chalk.gray(String(o)))}po.hook("preAction",()=>{!function(){if(!oo())return;const o="─".repeat(Math.max(24,Math.min(52,(process.stdout.columns||80)-4)));console.log(),console.log(chalk.yellow(` ${o}`)),console.log(chalk.yellow.bold(" ⚠ You ARE inside Ubuntu — but this icoa")),console.log(chalk.yellow.bold(" is the WINDOWS build.")),console.log(),console.log(chalk.gray(" WSL appends the Windows PATH, so ")+chalk.cyan("icoa")),console.log(chalk.gray(" found the Windows copy first. Almost")),console.log(chalk.gray(" nothing will work: no vi, no python3,")),console.log(chalk.gray(" env setup cannot install.")),console.log(),console.log(chalk.gray(" Running: ")+chalk.white(process.execPath)),console.log(),console.log(chalk.white(" Fix — inside Ubuntu, check npm is Linux FIRST:")),console.log(` ${chalk.bold.cyan("which npm")}${chalk.gray(" → must not be /mnt/c/...")}`),console.log(` ${chalk.bold.cyan("sudo npm install -g icoa-cli")}`),console.log(` ${chalk.bold.cyan("hash -r")}${chalk.gray(" → bash caches the old path")}`),console.log(chalk.gray(" Then restart icoa and check ")+chalk.bold.cyan("which icoa")),console.log(chalk.yellow(` ${o}`)),console.log()}()}),po.parse();
|
package/dist/lib/algo-replay.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import chalk from"chalk";import{lazyJson as t}from"./lazy-assets.js";export function replayKey(t){if("number"==typeof t)return Number.isInteger(t)&&t>0?`aio${t}`:null;const e=t.trim();if(/^PY\d{4}$/i.test(e))return e.toUpperCase();const s=/^aio(\d+)$/i.exec(e);return s&&Number(s[1])>0?`aio${Number(s[1])}`:null}export function replayAssetName(t){const e=replayKey(t);return e?`replays/${e}.json`:null}export async function loadReplay(e){const s=replayAssetName(e);if(!s)return null;const
|
|
1
|
+
import chalk from"chalk";import{lazyJson as t}from"./lazy-assets.js";export function replayKey(t){if("number"==typeof t)return Number.isInteger(t)&&t>0?`aio${t}`:null;const e=t.trim();if(/^PY\d{4}$/i.test(e))return e.toUpperCase();const s=/^aio(\d+)$/i.exec(e);return s&&Number(s[1])>0?`aio${Number(s[1])}`:null}export function replayAssetName(t){const e=replayKey(t);return e?`replays/${e}.json`:null}export async function loadReplay(e){const s=replayAssetName(e);if(!s)return null;const i=await t(s,8e3);return i&&1===i.v&&Array.isArray(i.frames)&&i.frames.length>0?i:null}let e=null,s=null;export function warmReplayIndex(){return s||(s=t("replays/index.json",5e3,{force:!0}).then(t=>{t&&Array.isArray(t.ids)&&(e=new Set(t.ids.filter(t=>"string"==typeof t)))}).catch(()=>{})),s}export function hasReplay(t){const s=replayKey(t);return Boolean(s&&e?.has(s))}export function setReplayIndexForTest(t){e=t?new Set(t):null,s=Promise.resolve()}export const REPLAY_MIN_COLS=120;const i=new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`,"g"),n=(t,e)=>t+" ".repeat(Math.max(0,e-(t=>[...t.replace(i,"")].length)(t))),r=(t,e)=>{const s=[];let i="";for(const n of t.split(/\s+/).filter(Boolean))i&&i.length+1+n.length>e?(s.push(i),i=n):i=i?`${i} ${n}`:n;return i&&s.push(i),s};export class ReplayPlayer{doc;opts;i=0;lang="python";steps;extra=null;exit;constructor(t,e){this.doc=t,this.opts=e,this.exit=e.exitLabel??"back to the card",this.steps=[...t.frames],t.summary?.idea?.length&&this.steps.push({left:[],line:null,vars:{},verdict:"ok",summary:!0,key:"Last step — the whole idea on one screen, key lines marked ◆. Ask about anything: /ai what does line 5 do"})}static tooNarrow(){return(process.stdout.columns??120)<120}start(t){"cpp"===t&&this.doc.code.cpp&&(this.lang="cpp"),this.render()}code(){return"cpp"===this.lang&&this.doc.code.cpp?this.doc.code.cpp:this.doc.code.python}highlight(t){return null==t.line?new Set:"cpp"===this.lang?new Set((this.doc.map[String(t.line+1)]??[]).map(t=>t-1)):new Set([t.line])}keyLines(){return("cpp"===this.lang?this.doc.summary?.cpp:this.doc.summary?.python)??[]}drawSummary(){const t=[chalk.bold.green("SUMMARY")+chalk.gray(" the idea")];for(const e of this.doc.summary.idea){const s=r(e,59);t.push(chalk.green("• ")+chalk.white(s[0]??""),...s.slice(1).map(t=>` ${chalk.white(t)}`),"")}t.push(chalk.bold.green("THE CODE")+chalk.gray(" what makes it work in "+("cpp"===this.lang?"C++":"Python")));for(const[e,s]of this.keyLines()){const i=r(s,52);t.push(`${chalk.green("◆ ")}${chalk.bold.cyan(`line ${String(e).padEnd(2)}`)} ${chalk.white(i[0]??"")}`,...i.slice(1).map(t=>` ${chalk.white(t)}`))}return t}rightPanel(t,e,s){const i=this.code(),n=this.highlight(t),r=t.summary?new Set(this.keyLines().map(([t])=>t-1)):new Set,o=[...n.size?n:r].sort((t,e)=>t-e);let h=0,a=i.length;if(s&&i.length>s){const t=o.length?Math.floor(((o[0]??0)+(o[o.length-1]??0))/2):0;h=Math.max(0,Math.min(t-Math.floor(s/2),i.length-s)),a=h+s}const l="cpp"===this.lang?"C++":"Python",c=[chalk.gray("─ ")+chalk.bold.white(l)+chalk.gray(` ${"─".repeat(54-l.length-3)}`)];h>0&&c.push(chalk.gray(` ⋮ ${h} line${h>1?"s":""} above`));for(let t=h;t<a;t++){const e=`${String(t+1).padStart(2)} `,s=i[t]??"";n.has(t)?c.push(chalk.bold.yellow(`▸${e}${s}`)):r.has(t)?c.push(chalk.green("◆")+chalk.bold.cyan(e)+chalk.white(s)):c.push(chalk.gray(` ${e}${s}`))}a<i.length&&c.push(chalk.gray(` ⋮ ${i.length-a} more line${i.length-a>1?"s":""}`));const p=t.vars??{},d=Object.keys(p);if(d.length){c.push(chalk.gray(`─ variables ${"─".repeat(42)}`));for(const t of d){let s=String(p[t]);s.length>54-t.length-6&&(s=`${s.slice(0,54-t.length-9)}...`);const i=null!==e&&(!(t in(e.vars??{}))||e.vars[t]!==p[t]);c.push(` ${chalk.cyan(t)} = ${i?chalk.yellow(s):chalk.white(s)}`)}}return c}footer(){const t=this.i===this.steps.length-1,e=[chalk.bold.green("[Enter]")+chalk.gray(t?" finish":" next"),chalk.bold.cyan("[b]")+chalk.gray(" back")];return this.doc.code.cpp&&e.push("cpp"===this.lang?chalk.bold.cyan("[p]")+chalk.gray(" Python code"):chalk.bold.cyan("[c]")+chalk.gray(" C++ code")),e.push(chalk.bold.magenta("[/ai]")+chalk.gray(" 🐼 ask about this step or a line")),e.push(chalk.bold.cyan("[q]")+chalk.gray(` ${this.exit}`)),e.join(" ")}render(){const t=this.steps[this.i],e=this.i>0?this.steps[this.i-1]:null,s=t.summary?this.drawSummary():[...t.left],i=r(t.key,116),o=Object.keys(t.vars??{}).length,h=this.extra?this.extra.length+2:0,a=process.stdout.rows??0,l=a?Math.max(8,a-2-1-i.length-1-2-1-h-(o?o+1:0)-3):null,c=this.rightPanel(t,e,l),p=Math.max(s.length,c.length);for(;s.length<p;)s.push("");for(;c.length<p;)c.push("");const d=this.steps.length,u=Math.round(12*(this.i+1)/d),y=chalk.white(`step ${this.i+1}/${d} `)+chalk.green("▰".repeat(u))+chalk.gray("▱".repeat(12-u))+(t.summary?chalk.bold.green(" summary"):""),g=/(.*?card \d+)/.exec(this.doc.source)?.[1]??this.doc.source,m=[`${chalk.bold.white(this.doc.title)}${chalk.gray(` ${g}`)} ${y}`,""];for(let t=0;t<p;t++)m.push(`${n(s[t]??"",62)} ${c[t]??""}`);m.push("");const f="ok"===t.verdict?chalk.green:"no"===t.verdict?chalk.red:chalk.white;for(const[t,e]of i.entries())m.push(chalk.bold.yellow(0===t?"▸ ":" ")+f(e));if(this.extra){m.push("");for(const t of this.extra)m.push(` ${chalk.white(t)}`)}m.push("",this.footer()),process.stdout.isTTY&&process.stdout.write("[2J[H"),console.log(m.join("\n")),this.extra=null}async handle(t){const e=t.trim(),s=e.toLowerCase();if(["q","quit","exit","back to card","card"].includes(s))return"done";if(s.startsWith("/ai")||s.startsWith("ai ")){const t=e.replace(/^\/?ai\s*/i,"");return t?(await this.opts.ask(t,this.context(t)),console.log(chalk.gray(" ▸ ")+chalk.bold.green("Enter")+chalk.gray(` next step · b back · q ${this.exit}`)),"input"):(this.extra=["Ask about this step or any line of the code on screen, for example:"," /ai what does line 5 do /ai why is this step red"],this.render(),"input")}if("c"===s||"c++"===s||"cpp"===s)this.doc.code.cpp?"cpp"===this.lang?this.extra=["Already showing C++. Press p for Python."]:this.lang="cpp":this.extra=["No C++ view for this replay yet."];else if("p"===s||"py"===s||"python"===s)"python"===this.lang?this.extra=["Already showing Python."+(this.doc.code.cpp?" Press c for C++.":"")]:this.lang="python";else if("b"===s||"back"===s)0===this.i&&(this.extra=[`This is the first step. q = ${this.exit}.`]),this.i=Math.max(0,this.i-1);else if(""===s||"n"===s||"next"===s||"ok"===s){if(this.i>=this.steps.length-1)return"done";this.i++}else this.extra=[`"${e}" is not a replay key. Enter next · b back · ${"cpp"===this.lang?"p Python":"c C++"} · /ai <question> · q ${this.exit}`];return this.render(),"input"}context(t){const e=this.steps[this.i],s=this.code(),i=new Set,n=t=>{Number.isInteger(t)&&t>=1&&t<=s.length&&i.add(t)};for(const e of t.matchAll(/(?:line|l|第)\s*(\d+)/gi))n(Number(e[1]));for(const t of[...this.highlight(e)].sort((t,e)=>t-e))n(t+1);if(e.summary)for(const[t]of this.keyLines())n(t);const r=("cpp"===this.lang?this.doc.notes?.cpp:this.doc.notes?.python)??{};return{id:replayKey(this.doc.id)??String(this.doc.id),title:this.doc.title,source:this.doc.source,lang:this.lang,step:this.i+1,total:this.steps.length,key:e.key,lines:[...i].slice(0,8).sort((t,e)=>t-e).map(t=>({n:t,code:(s[t-1]??"").trim(),note:r[String(t)]??""})),idea:(this.doc.summary?.idea??[]).slice(0,3)}}}
|
package/dist/lib/card-engine.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createInterface as o}from"node:readline";import{Interface as e}from"node:readline";import chalk from"chalk";import{getMainRl as
|
|
1
|
+
import{createInterface as o}from"node:readline";import{Interface as e}from"node:readline";import chalk from"chalk";import{getMainRl as t}from"./main-rl.js";let n=[],l=null,r=null,c=!1;export function isCardDeckActive(){return c}export function startCapture(){c=!0;const o=t();o&&(n=o.listeners("line").slice(),o.removeAllListeners("line"),l=o.prompt.bind(o),o.prompt=e.prototype.prompt.bind(o),o.on("line",o=>{const e=r;r=null,e&&e(o)}))}export function endCapture(){c=!1;const o=t();if(o){o.removeAllListeners("line"),l&&(o.prompt=l);for(const e of n)o.on("line",e);n=[],l=null,r=null}}export function ask(e){return new Promise(n=>{const l=t();if(l)return r=n,l.setPrompt(e),void l.prompt();const c=o({input:process.stdin,output:process.stdout});c.question(e,o=>{c.close(),n(o)})})}function s(o){return chalk[o.accent]}function i(o,e="─"){return s(o)(" "+e.repeat(62))}function a(o,e,t){const n=s(o);if(console.log(),console.log(n(" ┌─ ")+chalk.bold.white(`${t+1}/${o.cards.length} ${e.title}`)),console.log(n(" │")),e.chartart){for(const o of e.chartart)console.log(n(" │ ")+chalk.white(o));console.log(n(" │"))}for(const o of e.body)console.log(n(" │ ")+chalk.white(o));console.log(n(" │"));for(const o of e.choices)console.log(n(" │ ")+chalk.bold.cyan(o.key+")")+chalk.white(" "+o.text));console.log(n(" └─")),console.log()}const f=new Set(["quit","q","exit","menu","back"]);export async function runDeckPack(o,e){startCapture();let t=e.toLowerCase().startsWith("zh")?"zh":"en";try{for(;;){const e=await g("zh"===t?o.zh:o.en,t);if("done"===e)break;t=e}}finally{endCapture()}}async function g(o,e){const t="zh"===e;!function(o){console.clear(),console.log(),console.log(i(o,"═")),console.log(chalk.bold.white(" "+o.title)),console.log(chalk.gray(" "+o.tagline)),console.log(i(o,"═")),console.log()}(o);const n=t?" 输入选项字母作答 · quit 退出 · lang en 切英文":" Type the option letter · quit to leave · lang zh for Chinese";console.log(chalk.gray(n));for(let n=0;n<o.cards.length;n++){const l=o.cards[n];for(a(o,l,n);;){const r=(await ask(chalk.bold.cyan(`icoa ${o.id}> `))).trim().toLowerCase(),c=r.startsWith("lang ")?r.slice(5).trim():r;if(f.has(r))return console.log(),console.log(chalk.gray(t?" 已退出。":" Left the deck.")),console.log(),"done";if("zh"!==c&&"en"!==c){if(o.cards[n].choices.find(o=>o.key===r)){if(console.log(),r===l.correct)console.log(chalk.bold.green(t?" ✓ 正确":" ✓ Correct"));else{const o=l.choices.find(o=>o.key===l.correct);console.log(chalk.bold.yellow(t?" ✗ 不对 — 正确答案是 ":" ✗ Not it — the answer was ")+chalk.bold.cyan(l.correct+")")+chalk.white(" "+(o?o.text:"")))}for(const o of l.reveal)console.log(chalk.gray(" "+o));console.log();break}console.log(chalk.yellow(t?" 请输入选项字母(或 quit 退出)。":" Type an option letter (or quit to leave)."))}else if(c!==e)return c}}console.log(i(o)),await o.finale(),console.log();for(const e of o.outro)console.log(chalk.gray(" "+e));return console.log(),"done"}
|
package/dist/lib/commands.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const REGISTRY=[{name:"join",mapsTo:["ctf","join"],rest:!0,help:{order:0,section:"Competition",label:"join <url>",text:"Connect to CTFd"}},{name:"activate",mapsTo:["ctf","activate"],rest:!0},{name:"challenges",mapsTo:["ctf","challenges"],help:{order:1,section:"Competition",label:"challenges (ch)",text:"List challenges by category"}},{name:"ch",mapsTo:["ctf","challenges"]},{name:"open",mapsTo:["ctf","open"],rest:!0,help:{order:2,section:"Competition",label:"open <id>",text:"Read challenge + get next steps"}},{name:"submit",mapsTo:["ctf","submit"],rest:!0,help:{order:3,section:"Competition",label:"submit <id> <flag>",text:"Submit a flag"}},{name:"flag",mapsTo:["ctf","submit"],rest:!0},{name:"scoreboard",mapsTo:["ctf","scoreboard"],rest:!0,help:{order:4,section:"Competition",label:"scoreboard (sb)",text:"Live rankings"}},{name:"sb",mapsTo:["ctf","scoreboard"],rest:!0},{name:"status",mapsTo:["ctf","status"],help:{order:5,section:"Competition",label:"status",text:"Your score & timer"}},{name:"time",mapsTo:["ctf","time"],help:{order:6,section:"Competition",label:"time",text:"Countdown timer"}},{name:"ref",help:{order:8,section:"Tools",label:"ref [topic]",text:"Quick reference (linux, web, crypto...)"}},{name:"shell",help:{order:9,section:"Tools",label:"shell",text:"Interactive CTF shell (sandbox if present, else host)"}},{name:"files",help:{order:10,section:"Tools",label:"files <id>",text:"Download challenge files"}},{name:"view"},{name:"connect",help:{order:11,section:"Tools",label:"connect <id>",text:"Connect to remote target"}},{name:"challenge",subs:["start","stop","status"]},{name:"note",help:{order:12,section:"Tools",label:"note [text]",text:"Add a logbook entry (in-exam: tags current Q)"}},{name:"notes"},{name:"logbook",help:{order:13,section:"Tools",label:"logbook [n]",text:"View your logbook (in-exam: filter by Q)"}},{name:"log",help:{order:14,section:"Tools",label:"log",text:"Session history"}},{name:"man"},{name:"manual"},{name:"lang",help:{order:21,section:"System",label:"lang [code]",text:"Switch language (15 supported)"}},{name:"setup"},{name:"env"},{name:"aienv"},{name:"python",subs:["setup","status"]},{name:"mujoco",subs:["setup","status"]},{name:"mojoco",mapsTo:["mujoco"],rest:!0},{name:"ipynb"},{name:"kaggle"},{name:"teleload"},{name:"pandahelpme31"},{name:"gpufortask"},{name:"guide"},{name:"ai4ctf",help:{order:7,section:"AI Teammate",label:"ai4ctf",text:"Free-chat with your AI teammate"}},{name:"model"},{name:"ctf",subs:["challenges","open","submit","scoreboard","status","join","logout","time"]},{name:"exam",subs:["list","start","q","answer","submit","review","result","next","prev","mark","unmark","help"]},{name:"demo",mapsTo:["exam","demo"]},{name:"retry",mapsTo:["exam","demo-retry"]},{name:"nations",mapsTo:["exam","nations"]},{name:"next",mapsTo:["exam","next"]},{name:"prev",mapsTo:["exam","prev"]},{name:"continue"},{name:"logout",mapsTo:["ctf","logout"],help:{order:22,section:"System",label:"logout",text:"Disconnect"}},{name:"ctf4ai"},{name:"mark",mapsTo:["exam","mark"],rest:!0},{name:"unmark",mapsTo:["exam","unmark"],rest:!0},{name:"review",mapsTo:["exam","review"]},{name:"learn",subs:["start","continue"]},{name:"demo2"},{name:"demo4"},{name:"demo5"},{name:"gfssm"},{name:"ctf4eai"},{name:"ctf4vla"},{name:"theme"},{name:"sim"},{name:"arena",subs:["eai"]},{name:"eai"},{name:"wm"},{name:"microduck"},{name:"battle",subs:["edit","syntax","play","replay","submit","status","bots"]},{name:"duck",subs:["edit","syntax","run","replay","submit","board","scenarios","status"]},{name:"type",subs:["15","30","60","words","python","shell","history"],help:{order:15,section:"Tools",label:"type [30]",text:"Typing speed trainer — WPM, live colours, no token"}},{name:"board"},{name:"learn-pull"},{name:"doctor",help:{order:19,section:"System",label:"doctor",text:"Self-check: version, Python, network/firewall, server"}},{name:"upgrade",help:{order:20,section:"System",label:"upgrade",text:"Install the newest icoa and restart into it"}},{name:"update"},{name:"bg",nav:!0,help:{order:17,section:"System",label:"bg <command>",text:"Run a shell command in the background"}},{name:"tasks",nav:!0,help:{order:18,section:"System",label:"tasks [id]",text:"Background task panel / view output"}},{name:"drafts",nav:!0,help:{order:16,section:"System",label:"drafts",text:"Review staged draft answers"}},{name:"help",nav:!0},{name:"menu",nav:!0},{name:"quit",nav:!0},{name:"q",nav:!0},{name:"exit",nav:!0,help:{order:24,section:"System",label:"exit",text:"Quit (session saved)"}},{name:"back",nav:!0},{name:"resume",nav:!0,help:{order:15,section:"System",label:"resume",text:"Continue your last learn card / exam"}},{name:"clear",nav:!0,help:{order:23,section:"System",label:"clear",text:"Clear screen"}},{name:"cls",nav:!0}];export const surface=()=>REGISTRY.map(e=>e.name);export const dispatchable=()=>REGISTRY.filter(e=>!e.nav).map(e=>e.name);export function shortcutFor(e,t){const a=REGISTRY.find(t=>t.name===e&&t.mapsTo);return a?.mapsTo?a.rest?[...a.mapsTo,...t]:[...a.mapsTo]:null}export const subcommandsOf=e=>REGISTRY.find(t=>t.name===e)?.subs;export const helpRows=e=>REGISTRY.filter(t=>t.help?.section===e).sort((e,t)=>e.help.order-t.help.order).map(e=>({label:e.help.label,text:e.help.text}));
|
|
1
|
+
export const REGISTRY=[{name:"join",mapsTo:["ctf","join"],rest:!0,help:{order:0,section:"Competition",label:"join <url>",text:"Connect to CTFd"}},{name:"activate",mapsTo:["ctf","activate"],rest:!0},{name:"challenges",mapsTo:["ctf","challenges"],help:{order:1,section:"Competition",label:"challenges (ch)",text:"List challenges by category"}},{name:"ch",mapsTo:["ctf","challenges"]},{name:"open",mapsTo:["ctf","open"],rest:!0,help:{order:2,section:"Competition",label:"open <id>",text:"Read challenge + get next steps"}},{name:"submit",mapsTo:["ctf","submit"],rest:!0,help:{order:3,section:"Competition",label:"submit <id> <flag>",text:"Submit a flag"}},{name:"flag",mapsTo:["ctf","submit"],rest:!0},{name:"scoreboard",mapsTo:["ctf","scoreboard"],rest:!0,help:{order:4,section:"Competition",label:"scoreboard (sb)",text:"Live rankings"}},{name:"sb",mapsTo:["ctf","scoreboard"],rest:!0},{name:"status",mapsTo:["ctf","status"],help:{order:5,section:"Competition",label:"status",text:"Your score & timer"}},{name:"time",mapsTo:["ctf","time"],help:{order:6,section:"Competition",label:"time",text:"Countdown timer"}},{name:"ref",help:{order:8,section:"Tools",label:"ref [topic]",text:"Quick reference (linux, web, crypto...)"}},{name:"shell",help:{order:9,section:"Tools",label:"shell",text:"Interactive CTF shell (sandbox if present, else host)"}},{name:"files",help:{order:10,section:"Tools",label:"files <id>",text:"Download challenge files"}},{name:"view"},{name:"connect",help:{order:11,section:"Tools",label:"connect <id>",text:"Connect to remote target"}},{name:"challenge",subs:["start","stop","status"]},{name:"note",help:{order:12,section:"Tools",label:"note [text]",text:"Add a logbook entry (in-exam: tags current Q)"}},{name:"notes"},{name:"logbook",help:{order:13,section:"Tools",label:"logbook [n]",text:"View your logbook (in-exam: filter by Q)"}},{name:"log",help:{order:14,section:"Tools",label:"log",text:"Session history"}},{name:"man"},{name:"manual"},{name:"lang",help:{order:21,section:"System",label:"lang [code]",text:"Switch language (15 supported)"}},{name:"setup"},{name:"env"},{name:"aienv"},{name:"python",subs:["setup","status"]},{name:"mujoco",subs:["setup","status"]},{name:"mojoco",mapsTo:["mujoco"],rest:!0},{name:"ipynb"},{name:"kaggle"},{name:"teleload"},{name:"pandahelpme31"},{name:"gpufortask"},{name:"guide"},{name:"ai4ctf",help:{order:7,section:"AI Teammate",label:"ai4ctf",text:"Free-chat with your AI teammate"}},{name:"model"},{name:"ctf",subs:["challenges","open","submit","scoreboard","status","join","logout","time"]},{name:"exam",subs:["list","start","q","answer","submit","review","result","next","prev","mark","unmark","help"]},{name:"demo",mapsTo:["exam","demo"]},{name:"retry",mapsTo:["exam","demo-retry"]},{name:"nations",mapsTo:["exam","nations"]},{name:"next",mapsTo:["exam","next"]},{name:"prev",mapsTo:["exam","prev"]},{name:"continue"},{name:"logout",mapsTo:["ctf","logout"],help:{order:22,section:"System",label:"logout",text:"Disconnect"}},{name:"ctf4ai"},{name:"mark",mapsTo:["exam","mark"],rest:!0},{name:"unmark",mapsTo:["exam","unmark"],rest:!0},{name:"review",mapsTo:["exam","review"]},{name:"learn",subs:["start","continue"]},{name:"demo2"},{name:"demo3"},{name:"demo4"},{name:"demo5"},{name:"gfssm"},{name:"ctf4eai"},{name:"ctf4vla"},{name:"theme"},{name:"sim"},{name:"arena",subs:["eai"]},{name:"eai"},{name:"wm"},{name:"microduck"},{name:"battle",subs:["edit","syntax","play","replay","submit","status","bots"]},{name:"duck",subs:["edit","syntax","run","replay","submit","board","scenarios","status"]},{name:"type",subs:["15","30","60","words","python","shell","history"],help:{order:15,section:"Tools",label:"type [30]",text:"Typing speed trainer — WPM, live colours, no token"}},{name:"board"},{name:"learn-pull"},{name:"doctor",help:{order:19,section:"System",label:"doctor",text:"Self-check: version, Python, network/firewall, server"}},{name:"upgrade",help:{order:20,section:"System",label:"upgrade",text:"Install the newest icoa and restart into it"}},{name:"update"},{name:"bg",nav:!0,help:{order:17,section:"System",label:"bg <command>",text:"Run a shell command in the background"}},{name:"tasks",nav:!0,help:{order:18,section:"System",label:"tasks [id]",text:"Background task panel / view output"}},{name:"drafts",nav:!0,help:{order:16,section:"System",label:"drafts",text:"Review staged draft answers"}},{name:"help",nav:!0},{name:"menu",nav:!0},{name:"quit",nav:!0},{name:"q",nav:!0},{name:"exit",nav:!0,help:{order:24,section:"System",label:"exit",text:"Quit (session saved)"}},{name:"back",nav:!0},{name:"resume",nav:!0,help:{order:15,section:"System",label:"resume",text:"Continue your last learn card / exam"}},{name:"clear",nav:!0,help:{order:23,section:"System",label:"clear",text:"Clear screen"}},{name:"cls",nav:!0}];export const surface=()=>REGISTRY.map(e=>e.name);export const dispatchable=()=>REGISTRY.filter(e=>!e.nav).map(e=>e.name);export function shortcutFor(e,t){const a=REGISTRY.find(t=>t.name===e&&t.mapsTo);return a?.mapsTo?a.rest?[...a.mapsTo,...t]:[...a.mapsTo]:null}export const subcommandsOf=e=>REGISTRY.find(t=>t.name===e)?.subs;export const helpRows=e=>REGISTRY.filter(t=>t.help?.section===e).sort((e,t)=>e.help.order-t.help.order).map(e=>({label:e.help.label,text:e.help.text}));
|