icoa-cli 2.19.542 → 2.19.544
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/env.js +1 -1
- package/dist/commands/exam.js +1 -1
- package/dist/commands/gpufortask.js +1 -0
- package/dist/commands/learn.js +1 -1
- package/dist/commands/python.js +1 -0
- package/dist/index.js +1 -1
- package/dist/lib/aienv.js +1 -1
- package/dist/lib/commands.js +1 -1
- package/dist/lib/python-setup.js +1 -0
- package/dist/repl.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createInterface as e,Interface as o}from"node:readline";import chalk from"chalk";import{getDeviceFingerprint as t}from"../lib/access.js";import{getMainRl as n}from"../lib/main-rl.js";const s=(process.env.ICOA_GPUTASK_SERVER||"https://practice.icoa2026.au").replace(/\/$/,"");let i=[],a=null,l=null;function r(o){return new Promise(t=>{const s=n();if(s)return l=t,s.setPrompt(o),void s.prompt();const i=e({input:process.stdin,output:process.stdout});i.question(o,e=>{i.close(),t(e)})})}let c="en";const g={banner:{en:"[🧪 Committee GPU sandbox — clean 40-pkg IOAI environment]",zh:"[🧪 命题组 GPU 沙箱 — 纯净 40 包 IOAI 标准环境]"},langTip:{en:"Tip: type lang zh anytime to switch to 中文 (default English).",zh:"提示:随时输入 lang en 切回英文。"},tokenAsk:{en:"Enter your committee access token: ",zh:"请输入命题组访问 token:"},tokenBad:{en:"Token not recognised — check for typos and try again.",zh:"token 无效 — 请检查拼写后重试。"},tokenDevice:{en:"This token is bound to another computer. One token = one device — use your own token on this machine.",zh:"这枚 token 已绑定在另一台电脑上。一枚 token 只绑一台设备 — 请在本机使用你自己的 token。"},tokenGiveUp:{en:"Three failed attempts — ask your coordinator to verify your token.",zh:"连续三次失败 — 请联系协调人核对你的 token。"},hoursAsk:{en:"Session length? [1] 1 hour [2] 2 hours [3] 3 hours [5] 5 hours: ",zh:"选择时长? [1] 1 小时 [2] 2 小时 [3] 3 小时 [5] 5 小时:"},hoursBad:{en:"Please type 1, 2, 3 or 5.",zh:"请输入 1、2、3 或 5。"},seatsBusy:{en:"All 3 committee seats are in use right now — try again in a little while.",zh:"3 个并发席位当前全部占用 — 请稍后再试。"},already:{en:"You already have an active session — reconnecting to it.",zh:"你已有一个进行中的 session — 正在接回。"},deploying:{en:"⏳ Deploying a clean v2 box (pure 40-pkg IOAI standard env, RTX 4000 Ada) — about 13 min…",zh:"⏳ 正在部署纯净 v2 箱(40 包 IOAI 标准环境,RTX 4000 Ada)— 约 13 分钟…"},stCreating:{en:"creating the instance…",zh:"正在创建实例…"},stBooting:{en:"image restored — booting + kernel fix…",zh:"镜像展开完成 — 启动中 + 内核修正…"},stVerifying:{en:"box is up — verifying the 40-package environment…",zh:"机器已启动 — 正在校验 40 包环境…"},failed:{en:"Deployment failed: ",zh:"部署失败:"},readyTitle:{en:"✓ Your GPU box is ready (RTX 4000 Ada · 20 GB VRAM · 8 vCPU · 32 GB RAM · 512 GB disk)",zh:"✓ GPU 箱已就绪 (RTX 4000 Ada · 20 GB 显存 · 8 vCPU · 32 GB 内存 · 512 GB 磁盘)"},loginHow:{en:"Log in (password shown once — testing use, fine to display):",zh:"登录方式(密码一次性、每次不同 — 测试用,明示无妨):"},pkgsOk:{en:"✓ 40/40 IOAI-standard packages verified (per the IOAI 2026 official environment list):",zh:"✓ 40/40 个 IOAI 标准包校验通过(依据 IOAI 2026 官方环境清单):"},pkgsFree:{en:"You may pip-install anything on top — egress is open, the venv is writable, you are root.",zh:"可以随意 pip 安装任何包 — 外网开放、venv 可写、root 权限。"},killLine1:{en:"⏱ Auto-destroy at ",zh:"⏱ 自动销毁时间:"},killLine2:{en:"Everything on the box is DELETED then — copy out anything you need before that.",zh:"届时机器上的一切数据将被删除 — 需要的文件请提前拷出。"},footer:{en:"Commands: status time left · stats live GPU/RAM/disk usage · stop end early · lang zh · quit leave (box keeps running)",zh:"命令:status 剩余时间 · stats 显存/内存/磁盘占用率 · stop 提前结束 · lang en · quit 退出(机器继续运行)"},weekly:{en:"Heads-up: the committee has used {H}h of GPU since Monday — no limit, just so you know. Thanks for all the work! 🙂",zh:"小提示:命题组本周一以来累计已用 {H} 小时 GPU — 没有限制,纯提示。辛苦了 🙂"},warn10:{en:"⚠ 10 minutes left — the box auto-destroys soon. Copy out anything you need NOW.",zh:"⚠ 剩余 10 分钟 — 机器即将自动销毁,请立刻拷出需要的数据。"},stopAsk:{en:"End the session and destroy the box now? Everything on it is lost. (y/n): ",zh:"确认立即结束并销毁机器?数据将全部丢失。(y/n):"},stopping:{en:"Stopping — the box will be destroyed within a minute.",zh:"正在结束 — 机器将在一分钟内销毁。"},quitNote:{en:"Leaving this screen — your box KEEPS RUNNING until its auto-destroy time. Type gpufortask to reconnect.",zh:"已退出此界面 — 机器会继续运行到自动销毁时间。再次输入 gpufortask 可接回。"},destroyed:{en:"Session ended — the box has been destroyed.",zh:"session 已结束 — 机器已销毁。"},noStats:{en:"No utilisation sample yet — try again in ~30 s.",zh:"还没有采样数据 — 约 30 秒后再试。"},minLeft:{en:"min left",zh:"分钟剩余"},netErr:{en:"Cannot reach the broker right now — check your network and try again.",zh:"暂时连不上服务器 — 请检查网络后重试。"}},u=e=>g[e]?.[c]??e;async function d(e,o){try{const t=await fetch(`${s}/api/icoa/gputask/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o),signal:AbortSignal.timeout(15e3)}),n=await t.json();return n.data??n}catch{return null}}function y(e){const o=e.stats;if(!o)return void console.log(chalk.gray(` ${u("noStats")}`));const t=Math.max(0,Math.round(Date.now()/1e3-Number(o.at||0)));console.log(chalk.bold.cyan("zh"===c?" 实时占用":" Live utilisation")+chalk.gray(` (${t}s ago)`)),console.log(chalk.white(` GPU ${String(o.gpu_util_pct).padStart(3)}%`)+chalk.gray(" · ")+chalk.white(`VRAM ${o.vram_used_mb}/${o.vram_total_mb} MB`)+chalk.gray(" · ")+chalk.white(`${o.temp_c}°C · ${o.power_w} W`)),console.log(chalk.white(` RAM ${o.ram_used_mb}/${o.ram_total_mb} MB`)+chalk.gray(" · ")+chalk.white(`disk ${o.disk_used}/${o.disk_total} (${o.disk_pct})`)),console.log(chalk.bold.cyan("zh"===c?" RTX 4000 Ada 规格":" RTX 4000 Ada — card specs")),console.log(chalk.gray(" CUDA cores 6144 · Compute Capability 8.9 (sm_89) · FP32 ~26.7 TFLOPS")),console.log(chalk.gray(" VRAM 20 GB GDDR6 ECC · bandwidth ~360 GB/s · TDP 130 W · CUDA 12.6 (cu126 wheels)")),console.log(chalk.gray("zh"===c?" 整机:8 vCPU · 32 GB 内存 · 512 GB 磁盘 · Ubuntu 25.10 · Python 3.13":" Box: 8 vCPU · 32 GB RAM · 512 GB disk · Ubuntu 25.10 · Python 3.13"))}function h(e){console.log(),console.log(chalk.bold.green(` ${u("readyTitle")}`)),console.log(),console.log(chalk.white(` ${u("loginHow")}`)),console.log(chalk.bold.cyan(` ssh root@${e.ip}`)),console.log(chalk.bold.white(" password: ")+chalk.bold.yellow(e.root_pass??"?")),console.log(),console.log(chalk.green(` ${u("pkgsOk")}`)),function(e){const o=Math.min(process.stdout.columns||120,120),t=o>=100?3:o>=66?2:1,n=Math.floor((o-4)/t)-2,s=Math.ceil(e.length/t);for(let o=0;o<s;o++){let i=" ";for(let a=0;a<t;a++){const t=e[a*s+o];t&&(i+=t.padEnd(n).slice(0,n)+" ")}console.log(chalk.white(i.trimEnd()))}}(e.pkgs??[]),console.log(chalk.gray(` ${u("pkgsFree")}`)),console.log();const o=Math.round((e.seconds_left??0)/60);var t;console.log(chalk.yellow(` ${u("killLine1")}${t=e.kill_at??0,new Intl.DateTimeFormat("en-AU",{hour:"numeric",minute:"2-digit",hour12:!0,timeZone:"Australia/Sydney"}).format(new Date(1e3*t))} Sydney · ${o} ${u("minLeft")}`)),console.log(chalk.yellow(` ${u("killLine2")}`)),e.weekly_soft_over&&(console.log(),console.log(chalk.gray(` ${u("weekly").replace("{H}",String(e.weekly_hours??0))}`))),console.log(),console.log(chalk.gray(` ${u("footer")}`))}export function registerGpuForTaskCommand(e){e.command("gpufortask",{hidden:!0}).description("Committee GPU sandbox — clean 40-pkg IOAI environment (hidden)").action(async()=>{try{await async function(){c="en",function(){const e=n();e&&(i=e.listeners("line").slice(),e.removeAllListeners("line"),a=e.prompt.bind(e),e.prompt=o.prototype.prompt.bind(e),e.on("line",e=>{const o=l;l=null,o&&o(e)}))}();let e=null;try{console.log(),console.log(chalk.cyan.bold(` ${u("banner")}`)),console.log(chalk.gray(` ${u("langTip")}`)),console.log();const e=t();let o="";for(let t=0;t<3;){const n=(await r(chalk.cyan(` ${u("tokenAsk")}`))).trim(),i=n.toLowerCase();if("lang zh"===i){c="zh";continue}if("lang en"===i){c="en";continue}if("quit"===i||"back"===i||""===n){if(""===n)continue;return}const a=n.toUpperCase().replace(/\s+/g,""),l=await d("status",{token:a,fp:e});if(null===l)return void console.log(chalk.yellow(` ${u("netErr")}`));if("token_device_mismatch"!==l.error){if(!l.error){if(o=a,"none"!==l.state)return console.log(chalk.gray(` ${u("already")}`)),void await s(o,e,l);break}console.log(chalk.yellow(` ${u("tokenBad")}`)),t++}else console.log(chalk.yellow(` ${u("tokenDevice")}`)),t++}if(!o)return void console.log(chalk.yellow(` ${u("tokenGiveUp")}`));let n=0;for(;0===n;){const e=(await r(chalk.cyan(` ${u("hoursAsk")}`))).trim().toLowerCase();if("lang zh"===e){c="zh";continue}if("lang en"===e){c="en";continue}if("quit"===e||"back"===e)return;const o=Number.parseInt(e.replace(/\D/g,""),10);[1,2,3,5].includes(o)?n=o:console.log(chalk.yellow(` ${u("hoursBad")}`))}const i=await d("start",{token:o,fp:e,hours:n});if(null===i)return void console.log(chalk.yellow(` ${u("netErr")}`));if("all_seats_busy"===i.error)return void console.log(chalk.yellow(` ${u("seatsBusy")}`));if("session_already_active"===i.error){const t=await d("status",{token:o,fp:e});return void(t&&await s(o,e,t))}console.log(chalk.gray(` ${u("deploying")}`)),await s(o,e,i)}finally{e&&clearInterval(e),function(){const e=n();if(e){e.removeAllListeners("line"),a&&(e.prompt=a);for(const o of i)e.on("line",o);i=[],a=null,l=null}}()}async function s(o,t,n){let s=n,i="";const a=Date.now();for(;s&&"ready"!==s.state;){if("failed"===s.state||"destroyed"===s.state)return void console.log(chalk.red(` ${u("failed")}${s.fail_reason??s.state}`));const e="pending"===s.state||"creating"===s.state?u("stCreating"):"booting"===s.state?u("stBooting"):u("stVerifying");if(e!==i){const o=Math.round((Date.now()-a)/6e4);console.log(chalk.gray(` [${o}m] ${e}`)),i=e}await new Promise(e=>setTimeout(e,1e4)),s=await d("status",{token:o,fp:t})}if(!s)return void console.log(chalk.yellow(` ${u("netErr")}`));h(s);let l=!1;for(e=setInterval(async()=>{const e=await d("status",{token:o,fp:t});e&&!l&&"ready"===e.state&&(e.seconds_left??0)>0&&(e.seconds_left??0)<=600&&(l=!0,console.log(),console.log(chalk.bold.yellow(` ${u("warn10")}`)))},6e4);;){const e=(await r(chalk.cyan("icoa gpufortask> "))).trim().toLowerCase();if(""!==e)if("lang zh"!==e)if("lang en"!==e){if("quit"===e||"back"===e||"exit"===e)return void console.log(chalk.gray(` ${u("quitNote")}`));if("status"===e||"s"===e||"time"===e){const e=await d("status",{token:o,fp:t});if(e){if("ready"!==e.state)return void console.log(chalk.gray(` ${u("destroyed")}`));h(e)}else console.log(chalk.yellow(` ${u("netErr")}`));continue}if("stats"===e||"stat"===e||"usage"===e||"top"===e){const e=await d("status",{token:o,fp:t});if(e){if("ready"!==e.state)return void console.log(chalk.gray(` ${u("destroyed")}`));y(e)}else console.log(chalk.yellow(` ${u("netErr")}`));continue}if("stop"===e||"end"===e||"destroy"===e){const e=(await r(chalk.yellow(` ${u("stopAsk")}`))).trim().toLowerCase();if("y"===e||"yes"===e)return await d("stop",{token:o,fp:t}),void console.log(chalk.green(` ${u("stopping")}`));continue}console.log(chalk.gray(` ${u("footer")}`))}else c="en",console.log(chalk.gray(` ${u("footer")}`));else c="zh",console.log(chalk.gray(` ${u("footer")}`))}}}()}catch(e){const o=e instanceof Error?e.message:String(e);if("__REPL_NO_EXIT__"===o)throw e;console.log(chalk.yellow("\n gpufortask ended: "+o))}})}
|