icoa-cli 2.19.610 → 2.19.612
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/arena-eai.js +1 -1
- package/dist/commands/battle.js +1 -1
- package/dist/commands/ctf4ai-demo.js +1 -1
- package/dist/commands/ctf4vla.js +1 -1
- package/dist/commands/duck.js +1 -1
- package/dist/commands/exam.js +1 -1
- package/dist/commands/learn.js +1 -1
- package/dist/lib/learn-state.js +1 -1
- package/package.json +2 -2
package/dist/lib/learn-state.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join as e}from"node:path";import{getIcoaDir as t,getInstallSalt as
|
|
1
|
+
import{join as e}from"node:path";import{getIcoaDir as t,getInstallSalt as r}from"./config.js";import{deriveFileKey as n,readSignedFile as s,writeSignedFile as c,recordVerdict as o}from"./secure-store.js";const a="learn-state";function u(){return e(t(),"learn-state.json")}function i(){return n(r(),a)}const m="learn-sessions";function d(e){return(e.cardsCompleted?.length??0)>0||(e.currentCard??1)>1}export const CONTINUE_LIST_MAX=5;function l(){return e(t(),"learn-sessions.json")}function p(){return n(r(),m)}function k(){const{data:e,verdict:t}=s(l(),p());if(o(m,t),!e||"object"!=typeof e)return{};const r={};for(const[t,n]of Object.entries(e))n&&"object"==typeof n&&"string"==typeof n.token&&"string"==typeof n.curriculumId&&(r[t]=n);return r}export function listLearnSessions(){const e=loadLearnState(),t=[];e?.token&&e.curriculumId&&t.push(e);for(const[r,n]of Object.entries(k()))r!==e?.token&&t.push(n);return t.sort((e,t)=>(t.lastSeenAt??"").localeCompare(e.lastSeenAt??""))}export function activateSession(e){const t=loadLearnState(),r=k();t?.token&&t.curriculumId&&t.token!==e&&(r[t.token]=t);const n=r[e]??null;return function(e){const t=Object.keys(e);if(t.length>200){const r=t.sort((t,r)=>{const n=d(e[t])?1:0,s=d(e[r])?1:0;return n!==s?n-s:(e[t].lastSeenAt??"").localeCompare(e[r].lastSeenAt??"")}).slice(0,t.length-200);for(const t of r)delete e[t]}c(l(),e,p())}(r),n}export function loadLearnState(){const{data:e,verdict:t}=s(u(),i());return o(a,t),e}export function saveLearnState(e){e.lastSeenAt=(new Date).toISOString(),c(u(),e,i())}export function newLearnState(e,t,r){const n=(new Date).toISOString();return{token:e,curriculumId:t,currentCard:1,totalCards:r,startedAt:n,lastSeenAt:n,streakDays:1,longestStreak:1,cardsCompleted:[],mcqResults:{},checkResults:{},practicalsCompleted:[],bookmarks:[],achievements:[],totalSecondsActive:0}}export function stateFromServerEvents(e,t,r,n){const s=newLearnState(e,t,r),c=new Set;let o="";for(const e of n){const t=Number(e.card_number);!Number.isInteger(t)||t<1||t>r||("check_answered"!==e.event_type||"y"!==e.check_answer&&"n"!==e.check_answer?"mcq_answered"===e.event_type&&e.mcq_answer&&/^[ABCD]$/.test(e.mcq_answer)?(s.mcqResults[String(t)]={answer:e.mcq_answer,correct:!!e.mcq_correct,submittedAt:e.timestamp},c.add(t)):"viewed"===e.event_type?c.add(t):"practical_done"===e.event_type?(s.practicalsCompleted.push(t),c.add(t)):"bookmarked"===e.event_type&&s.bookmarks.push(t):(s.checkResults[String(t)]={answer:e.check_answer,correct:!!e.check_correct,submittedAt:e.timestamp},c.add(t)),e.timestamp&&(!o||e.timestamp<o)&&(o=e.timestamp))}return 0===c.size?null:(s.cardsCompleted=[...c].sort((e,t)=>e-t),s.currentCard=Math.min(r,Math.max(...c)+1),o&&(s.startedAt=o),s)}export function mergeServerProgress(e,t,r){if(!r||0===r.length)return;const n=new Set(e.cardsCompleted??[]);let s=0;for(const c of r){const r=Number(c.card_number);if(!Number.isInteger(r)||r<1||r>t)continue;const o=String(r);"check_answered"!==c.event_type||"y"!==c.check_answer&&"n"!==c.check_answer?"mcq_answered"===c.event_type&&c.mcq_answer&&/^[ABCD]$/.test(c.mcq_answer)?(e.mcqResults[o]||(e.mcqResults[o]={answer:c.mcq_answer,correct:!!c.mcq_correct,submittedAt:c.timestamp}),n.add(r)):"viewed"===c.event_type?n.add(r):"practical_done"===c.event_type?(e.practicalsCompleted.includes(r)||e.practicalsCompleted.push(r),n.add(r)):"bookmarked"===c.event_type&&(e.bookmarks.includes(r)||e.bookmarks.push(r)):(e.checkResults||(e.checkResults={}),e.checkResults[o]||(e.checkResults[o]={answer:c.check_answer,correct:!!c.check_correct,submittedAt:c.timestamp}),n.add(r)),n.has(r)&&(s=Math.max(s,r))}if(0===n.size)return;e.cardsCompleted=[...n].sort((e,t)=>e-t);const c=Math.min(t,s+1);c>(e.currentCard??1)&&(e.currentCard=c)}export function updateStreak(e){const t=new Date(e.lastSeenAt),r=new Date,n=Math.floor(t.getTime()/864e5),s=Math.floor(r.getTime()/864e5)-n;0!==s&&(1===s?(e.streakDays+=1,e.streakDays>e.longestStreak&&(e.longestStreak=e.streakDays)):e.streakDays=1)}export function markCardComplete(e,t){e.cardsCompleted.includes(t)||e.cardsCompleted.push(t)}export function recordMCQ(e,t,r){e.mcqResults[String(t)]=r}export function recordCheck(e,t,r){e.checkResults||(e.checkResults={}),e.checkResults[String(t)]=r}export function markPracticalComplete(e,t){e.practicalsCompleted.includes(t)||e.practicalsCompleted.push(t)}export function addAchievement(e,t){e.achievements.includes(t)||e.achievements.push(t)}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "icoa-cli",
|
|
3
|
-
"version": "2.19.
|
|
4
|
-
"description": "ICOA CLI
|
|
3
|
+
"version": "2.19.612",
|
|
4
|
+
"description": "ICOA CLI \u2014 AI-native competition runtime of the International Cyber Olympiad in AI: learn, practise, and compete in AI & cybersecurity from the terminal (AI4CTF \u00b7 CTF4AI \u00b7 CTF4EAI)",
|
|
5
5
|
"author": "Charlie Zhu",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|