icoa-cli 2.19.419 → 2.19.421
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/exam.js +1 -1
- package/dist/commands/ipynb.js +1 -1
- package/dist/commands/kaggle.js +1 -1
- package/dist/commands/learn.js +1 -1
- package/dist/commands/sprint.d.ts +7 -0
- package/dist/commands/sprint.js +1 -0
- package/dist/data/sprint-cards.json +221 -0
- package/dist/data/sprint-tasks.json +330 -0
- package/dist/index.js +1 -1
- package/dist/lib/commands.d.ts +26 -0
- package/dist/lib/commands.js +1 -0
- package/dist/lib/learn-curricula.d.ts +1 -0
- package/dist/lib/learn-curricula.js +1 -1
- package/dist/repl.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
{
|
|
2
|
+
"track": "IOAI2026-tools",
|
|
3
|
+
"cards": [
|
|
4
|
+
{
|
|
5
|
+
"seq": 1,
|
|
6
|
+
"star": "★ 音频分类=mel 谱当单通道图像,自己写 Dataset 和 torch 训练循环",
|
|
7
|
+
"trap": "!! resnet18 的 conv1 只收 3 通道,换成 1 通道就丢了该层预训练权重",
|
|
8
|
+
"action": "▸ 去做:先用 torchaudio 读一条 wav 走 MelSpectrogram→log 打出 shape,再照着写 Dataset。",
|
|
9
|
+
"meta": "⏱ 参考 25 分钟 · 难度 ★★☆☆☆",
|
|
10
|
+
"note": "288 条训练 9 类,wav 全是 5 秒 44.1kHz,先重采到 16k"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"seq": 2,
|
|
14
|
+
"star": "★ 8 个周期特征先 sin/cos 还原环状结构;t-SNE 只能看,降维不产出答案",
|
|
15
|
+
"trap": "!! cand_0..4 是候选标签不是真标签;簇号要靠簇内候选列求和 argmax 映射",
|
|
16
|
+
"action": "▸ 去做:先看 8 列的 max 定出周期(≈11/13/17/19),sin/cos 编码成 16 维再聚类。",
|
|
17
|
+
"meta": "⏱ 参考 25 分钟 · 难度 ★★☆☆☆",
|
|
18
|
+
"note": "t-SNE 没有 transform;要把 test 映射进来只能用 UMAP"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"seq": 3,
|
|
22
|
+
"star": "★ 四标签各训一个二分类器;LoRA 微调对照 TF-IDF+CatBoost 基线",
|
|
23
|
+
"trap": "!! 四个标签各自调阈值;全用默认 0.5,稀有的 severe_toxic 直接塌",
|
|
24
|
+
"action": "▸ 去做:先 TF-IDF+线性分类器打底,再对每个标签用 precision_recall_curve 找最优阈值。",
|
|
25
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
26
|
+
"note": "满分线各不同:severe_toxic 只需 F1 0.35,toxic 要 0.905"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"seq": 4,
|
|
30
|
+
"star": "★ wav→mel→补裁成定长矩阵→当图像分类:librosa 只负责前两步",
|
|
31
|
+
"trap": "!! 182 条样本摊到 41 个类,split 不 stratify 就有类在验证集挂零",
|
|
32
|
+
"action": "▸ 去做:先统计 train.csv 每类样本数,再定分层切分和 mel 的固定帧数。",
|
|
33
|
+
"meta": "⏱ 参考 25 分钟 · 难度 ★★☆☆☆",
|
|
34
|
+
"note": "官方承认本轮有泄漏:样本 id 的 A_/B_ 前缀本身就带类组信息"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"seq": 5,
|
|
38
|
+
"star": "★ 四选一要手搓 MC 头:4 个选项各前向一次取 logit,再对 4 个分数算 CE",
|
|
39
|
+
"trap": "!! reshape 成 B*4 条各自打分,还原时维度弄反,选项就和 batch 串位",
|
|
40
|
+
"action": "▸ 去做:把 before[SEP]选项[SEP]after 拼成 4 条,先跑一个 batch 打印 logits 形状。",
|
|
41
|
+
"meta": "⏱ 参考 25 分钟 · 难度 ★★☆☆☆",
|
|
42
|
+
"note": "4 选项 × 512 长度 × batch 一起前向,显存是主要瓶颈"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"seq": 6,
|
|
46
|
+
"star": "★ CLIP 当特征提取器,检索=余弦相似;降维只是把 768 维压干净的可选一步",
|
|
47
|
+
"trap": "!! 参考图自己也在图库里,余弦相似度 1.0 必居首;不剔除,top-5 白丢一格",
|
|
48
|
+
"action": "▸ 去做:先算 109×109 相似度矩阵,确认对角线是 1.0,再排除自身取 top-5。",
|
|
49
|
+
"meta": "⏱ 参考 25 分钟 · 难度 ★★☆☆☆",
|
|
50
|
+
"note": "官方解答对 PIL 已是 RGB 的数组又做了一次 BGR2RGB,通道被换错"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"seq": 7,
|
|
54
|
+
"star": "★ 887 条训练数据:LoRA 只训千分之几参数,正好压住过拟合",
|
|
55
|
+
"trap": "!! CONTRADICT 只有 189 条;直接上 CE,macro F1 被这一类拖死",
|
|
56
|
+
"action": "▸ 去做:claim 与 evidence 作两句传给 tokenizer,再用 StratifiedKFold 分折并给类加权。",
|
|
57
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
58
|
+
"note": "用 peft 时别忘 modules_to_save,新分类头否则不会被保存"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"seq": 8,
|
|
62
|
+
"star": "★ 200Hz 采的 20 秒信号,补洞在波形域做;要听就重采到 44.1kHz",
|
|
63
|
+
"trap": "!! 非零位置 Data_X 就等于 Data_y;抄回来,只预测那 20% 的空洞",
|
|
64
|
+
"action": "▸ 去做:先验证 Data_X!=0 的行两列完全相等,再只对 0 位置建模。",
|
|
65
|
+
"meta": "⏱ 参考 50 分钟 · 难度 ★★★★☆",
|
|
66
|
+
"note": "缺失是连续段(单曲约 13 段),datapointID 要写成带引号的 (id, i)"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"seq": 9,
|
|
70
|
+
"star": "★ 70 测试对 70 候选是双射;按行取 logit 最大值必撞车,需全局指派",
|
|
71
|
+
"trap": "!! linear_sum_assignment 求最小代价;分数忘了取负就挑出最差组合",
|
|
72
|
+
"action": "▸ 去做:先打出 70×70 的候选打分矩阵,再交给 scipy 的匈牙利算法解指派。",
|
|
73
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
74
|
+
"note": "训练只有 150 对;item1/item2 互换是免费的对称增强"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"seq": 10,
|
|
78
|
+
"star": "★ 有效信号住在低维流形:PCA 降维再重构,重构误差大的就是噪声",
|
|
79
|
+
"trap": "!! 信号回归要先剔掉噪声行再训;预测还得乘掩码并 clip 到 0~100",
|
|
80
|
+
"action": "▸ 去做:先跑 PCA(15) 画重构误差直方图,找出分开信号与噪声的那道沟。",
|
|
81
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
82
|
+
"note": "三个子任务写进同一个 csv,靠 subtaskID 列区分,缺一问丢一档分"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"seq": 11,
|
|
86
|
+
"star": "★ 检测只换 box_predictor 头微调——和 LoRA 冻主干训小增量同源",
|
|
87
|
+
"trap": "!! 图缩到 224,标注框在 512 画布;提交不乘回 512/224,IoU 直接归零",
|
|
88
|
+
"action": "▸ 去做:先把一张训练图连同它的框画出来,确认坐标系是 512 而不是 224。",
|
|
89
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
90
|
+
"note": "无鬼图的 target 要给空框张量 zeros((0,4)),不是四个 0"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"seq": 12,
|
|
94
|
+
"star": "★ 要还原可听波形就别过 mel——谱图丢相位;直接在波形域上 1D U-Net",
|
|
95
|
+
"trap": "!! 两路输出没有固定归属;普通 MSE 会互相打架,必须 PIT 取两种配对最小",
|
|
96
|
+
"action": "▸ 去做:先写 PIT 损失,把 s1/s2 互换再喂一遍,确认 loss 数值不变。",
|
|
97
|
+
"meta": "⏱ 参考 50 分钟 · 难度 ★★★★☆",
|
|
98
|
+
"note": "提交是 base85 编码的 float32 数组;dtype 写成 float64 长度就翻倍"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"seq": 13,
|
|
102
|
+
"star": "★ 训练集只有 50 行:别训模型,拿冻结 MLM 的 [MASK] logit 当特征",
|
|
103
|
+
"trap": "!! 目标词不在词表就静默变 [UNK],那一列特征全废却不报错",
|
|
104
|
+
"action": "▸ 去做:先查 686 对词里有多少是单个 wordpiece,OOV 的另想打分办法。",
|
|
105
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
106
|
+
"note": "反义前后缀规则(un-/in-/dis-/il-)可直接覆盖一批预测"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"seq": 14,
|
|
110
|
+
"star": "★ 两问两路:旋转分类走 CNN,跨域检索靠描述子降维成嵌入再最近邻",
|
|
111
|
+
"trap": "!! 旋转标签就是数据本身;任何随机翻转/旋转增强都会直接把标签洗掉",
|
|
112
|
+
"action": "▸ 去做:先把旋转四分类推过 macro F1 0.60 这条满分线,再攻检索那 70 分。",
|
|
113
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
114
|
+
"note": "计分是阶梯不是线性:旋转掉到 0.60 以下,30 分直接变 10 分"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"seq": 15,
|
|
118
|
+
"star": "★ 三问串成一条链:框错了像素数必错;主干冻住配轻量头即 LoRA 思路",
|
|
119
|
+
"trap": "!! 同一批特征 SVR 的 RMSE 1217、GBDT 只有 62——SVR 没缩放",
|
|
120
|
+
"action": "▸ 去做:先跑通「有鸭→出框→按框裁剪回归像素数」三步,任一步断链后面全废。",
|
|
121
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
122
|
+
"note": "翻转增强时 bbox 要同步翻(x→W-x2, W-x1),提交是空格分隔的四个数"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"seq": 16,
|
|
126
|
+
"star": "★ 字节码当 token 序列喂 RNN 回归;pad 位必须 mask 掉再池化",
|
|
127
|
+
"trap": "!! pack 序列的 lengths 必须留在 CPU;放到 GPU 上直接报错",
|
|
128
|
+
"action": "▸ 去做:先按 ';' 切 token 建词表,用 pack_padded_sequence 走通一个 batch。",
|
|
129
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
130
|
+
"note": "目标先标准化再训,算 MAE 前反标准化并 rint 取整"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"seq": 17,
|
|
134
|
+
"star": "★ 字符级 TF-IDF 走 SVD 降到 300 维,再用 Ridge 学西→英映射",
|
|
135
|
+
"trap": "!! 两个 SVD 各自 fit,坐标系不通;不学映射直接算 cosine 等于瞎比",
|
|
136
|
+
"action": "▸ 去做:先把 is_food=-1 的平行行挑出来当对齐语料,它们不参与分类训练。",
|
|
137
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
138
|
+
"note": "word 级 TF-IDF 跨语种失效;要 analyzer='char' 才有共享 n-gram"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"seq": 18,
|
|
142
|
+
"star": "★ 先把 pooling 和 instruct 前缀调对再上 LoRA;顺序反了白练",
|
|
143
|
+
"trap": "!! pooling 从 last-token 换成 mean,分数 100 掉到 45",
|
|
144
|
+
"action": "▸ 去做:先用 support_examples 验证 pooling 与前缀选对了,再决定要不要微调。",
|
|
145
|
+
"meta": "⏱ 参考 50 分钟 · 难度 ★★★★☆",
|
|
146
|
+
"note": "查询侧加 Instruct 前缀、语料侧不加;emoji 先 demojize 成英文名更稳"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"seq": 19,
|
|
150
|
+
"star": "★ 别急着写 torch 训练循环:8 个梯度/拉普拉斯统计量喂 RF 就过满分线",
|
|
151
|
+
"trap": "!! 坑数 clip 到 3~8、年龄 clip 到 1~5;不夹住 MAE 直接被拉爆",
|
|
152
|
+
"action": "▸ 去做:先用 cv2 抽出 8 个梯度/拉普拉斯统计量,喂 RandomForest 看 MAE。",
|
|
153
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
154
|
+
"note": "年龄那问占 80 分,满分线 MAE≤0.3,手工特征就够到"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"seq": 20,
|
|
158
|
+
"star": "★ 两个倒数第二层就是两个特征提取器:谁的低维嵌入能线性还原 y,就归谁",
|
|
159
|
+
"trap": "!! 标签是没有的;只比一次全量 ridge 的残差分不开,要 EM 反复加权重拟合",
|
|
160
|
+
"action": "▸ 去做:先用两组权重把 x 前向成 ZA/ZB,各拟合一个 ridge 头看残差分布。",
|
|
161
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
162
|
+
"note": "E 步算软责任时 softmax 记得减 max,否则数值溢出"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"seq": 21,
|
|
166
|
+
"star": "★ 错字与正文等长 ⇒ encoder-only 逐字符分类;LoRA 合回主干零时延",
|
|
167
|
+
"trap": "!! 输入与标签要用同一套 stride 分块;参数差一点两边 chunk 数就错位",
|
|
168
|
+
"action": "▸ 去做:先确认两列字符数完全相等,再定 chunk 长度和 250 秒推理预算。",
|
|
169
|
+
"meta": "⏱ 参考 50 分钟 · 难度 ★★★★☆",
|
|
170
|
+
"note": "官方三坑:局部任务、等长、超默认截断长度的样本超过四分之一"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"seq": 22,
|
|
174
|
+
"star": "★ 翻转让贴纸文字失效:在 torch 里逐维比符号,就能拆开文字维和视觉维",
|
|
175
|
+
"trap": "!! 文件名字典序会排成 1,10,100…;要 key=int(stem),不然整份错位",
|
|
176
|
+
"action": "▸ 去做:先编码原图与水平翻转图,打印逐维乘积里负数占了多少维。",
|
|
177
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
178
|
+
"note": "官方实测约五分之一的维度被贴纸文字劫持;类嵌入也要先归一化"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"seq": 23,
|
|
182
|
+
"star": "★ 第二问训练集根本没有主题标签:只能在 test 上直接聚类,降维图只是给你看",
|
|
183
|
+
"trap": "!! 答案是 SCIENCE/CRIME 这类字符串;簇号随机,要看簇心 top 词映射",
|
|
184
|
+
"action": "▸ 去做:先把 test 里 subtaskID=2 的行单独取出,只在它们上面做聚类。",
|
|
185
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
186
|
+
"note": "第一问 char_wb 的 2-8 gram 比 word 级强很多,满分线 macro F1 0.95"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"seq": 24,
|
|
190
|
+
"star": "★ 冻住 ResNet50 只训一个小头(和 LoRA 同构),力气全花在掐掉捷径上",
|
|
191
|
+
"trap": "!! 红方块只贴在训练集 Earth 图的边缘;不裁边,模型学的是方块不是鸟",
|
|
192
|
+
"action": "▸ 去做:先按蓝通道均值自动标出背景,再把四组(鸟种×背景)的准确率分别打出来。",
|
|
193
|
+
"meta": "⏱ 参考 70 分钟 · 难度 ★★★★★",
|
|
194
|
+
"note": "只按四组里最差那组计分,整体 95% 也可能拿 0;禁止手工标注"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"seq": 25,
|
|
198
|
+
"star": "★ 手写 4 层 CNN 训练循环的底线:15 轮 macro F1 约 0.75",
|
|
199
|
+
"trap": "!! 标签编码器要复用 train 的那个;test 上重新 fit,六类映射就错位",
|
|
200
|
+
"action": "▸ 去做:先跑 15 轮从零 CNN 记下 macro F1,再换预训练 backbone 比涨幅。",
|
|
201
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
202
|
+
"note": "标签形状是 (B,1),喂 CrossEntropyLoss 前要 squeeze"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"seq": 26,
|
|
206
|
+
"star": "★ 把每个模型的预测回归到特征上,15 维系数就是它的低维指纹;干净的聚成一簇",
|
|
207
|
+
"trap": "!! kneighbors 第一个邻居就是它自己;设 5 拿到的是自己加 4 个邻居",
|
|
208
|
+
"action": "▸ 去做:用一次 LinearRegression 多输出拟合 1000 列,系数标准化后找最紧的近邻团。",
|
|
209
|
+
"meta": "⏱ 参考 35 分钟 · 难度 ★★★☆☆",
|
|
210
|
+
"note": "答案只有一行:5 个索引用逗号连成一个字符串写进 answer"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"seq": 27,
|
|
214
|
+
"star": "★ 冻住旧类的 head、只训新类,靠 gate 分流 —— 抗遗忘的标准解",
|
|
215
|
+
"trap": "!! val 从有偏 train 切出,系统性低估旧类;照 val 调参必翻车",
|
|
216
|
+
"action": "▸ 去做:kaggle audio-classifier | 先跑通冻结基线拿到分,再动新类那一侧",
|
|
217
|
+
"meta": "⏱ 参考 50 分钟 · 难度 ★★★★☆",
|
|
218
|
+
"note": "ICOA 自建题(IOAI 真 home task 1),参考解法 A11 实测 LB 0.889"
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
{
|
|
2
|
+
"track": "IOAI2026-tools",
|
|
3
|
+
"n": 27,
|
|
4
|
+
"tasks": [
|
|
5
|
+
{
|
|
6
|
+
"seq": 1,
|
|
7
|
+
"bullseye": "T-torch",
|
|
8
|
+
"title": "Sound of Nature",
|
|
9
|
+
"platform": "aicc",
|
|
10
|
+
"difficulty": 2,
|
|
11
|
+
"data_mb": 112,
|
|
12
|
+
"needs_gpu": false,
|
|
13
|
+
"cli_mode": "kaggle-arena",
|
|
14
|
+
"dir": "sound-of-nature-aicc-round-3",
|
|
15
|
+
"topic_cn": "360 条 5 秒自然/动物声音的多类分类(cat 等类别),官方解答 = mel-spectrogram + CNN + macro F1 选模"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"seq": 2,
|
|
19
|
+
"bullseye": "T-umap",
|
|
20
|
+
"title": "Morty's Time Paradox",
|
|
21
|
+
"platform": "aicc",
|
|
22
|
+
"difficulty": 2,
|
|
23
|
+
"data_mb": 1,
|
|
24
|
+
"needs_gpu": false,
|
|
25
|
+
"cli_mode": "kaggle-arena",
|
|
26
|
+
"dir": "mortys-time-paradox-aicc-round-3",
|
|
27
|
+
"topic_cn": "8 个周期性特征的无标签聚类:先用 sin/cos 周期编码还原结构,再聚类 + 候选标签多数投票定类"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"seq": 3,
|
|
31
|
+
"bullseye": "T-lora",
|
|
32
|
+
"title": "☣️ How Toxic Are You Online? ☣️",
|
|
33
|
+
"platform": "nitro",
|
|
34
|
+
"difficulty": 3,
|
|
35
|
+
"data_mb": 18,
|
|
36
|
+
"needs_gpu": false,
|
|
37
|
+
"cli_mode": "kaggle-arena",
|
|
38
|
+
"dir": "nitro/53_roai-2025_lot-baraj-2_t1_how-toxic-are-you-online",
|
|
39
|
+
"topic_cn": "国家队选拔第2日:四标签毒性多标签分类,逐标签F1线性插值计分,另在30%子集上单独评稳健性;赛中明令禁用transformers"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"seq": 4,
|
|
43
|
+
"bullseye": "T-librosa",
|
|
44
|
+
"title": "Is That Audio?",
|
|
45
|
+
"platform": "aicc",
|
|
46
|
+
"difficulty": 2,
|
|
47
|
+
"data_mb": 9,
|
|
48
|
+
"needs_gpu": false,
|
|
49
|
+
"cli_mode": "kaggle-arena",
|
|
50
|
+
"dir": "is-that-audio-aicc-round-1-2",
|
|
51
|
+
"topic_cn": "260 条 wav 的多类音频分类(A/B 两组前缀),官方解答走 mel-spectrogram + CNN;官方承认该轮数据存在泄漏,定位为教学素材"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"seq": 5,
|
|
55
|
+
"bullseye": "T-torch",
|
|
56
|
+
"title": "Essay Gap",
|
|
57
|
+
"platform": "aicc",
|
|
58
|
+
"difficulty": 2,
|
|
59
|
+
"data_mb": 1,
|
|
60
|
+
"needs_gpu": true,
|
|
61
|
+
"cli_mode": "kaggle-arena",
|
|
62
|
+
"dir": "essay-gap-aicc-round-2",
|
|
63
|
+
"topic_cn": "给出文章缺口的前文/后文与 4 个候选句,选出被挖掉的那一句(BERT 微调四选一)"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"seq": 6,
|
|
67
|
+
"bullseye": "T-umap",
|
|
68
|
+
"title": "Face Matching",
|
|
69
|
+
"platform": "aicc",
|
|
70
|
+
"difficulty": 2,
|
|
71
|
+
"data_mb": 8,
|
|
72
|
+
"needs_gpu": false,
|
|
73
|
+
"cli_mode": "kaggle-arena",
|
|
74
|
+
"dir": "face-matching-aicc-round-2",
|
|
75
|
+
"topic_cn": "109 张人脸图 + 若干张参考图,用 CLIP 嵌入为每张参考图检索最相似的 5 张(提交 top-5 列表)"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"seq": 7,
|
|
79
|
+
"bullseye": "T-lora",
|
|
80
|
+
"title": "Scientific Facts",
|
|
81
|
+
"platform": "aicc",
|
|
82
|
+
"difficulty": 3,
|
|
83
|
+
"data_mb": 1,
|
|
84
|
+
"needs_gpu": true,
|
|
85
|
+
"cli_mode": "kaggle-arena",
|
|
86
|
+
"dir": "scientific-facts-aicc-round-7",
|
|
87
|
+
"topic_cn": "科学论断 × 证据段落的三分类蕴含判断(支持/反驳/信息不足),官方解答 = transformer 微调 + 交叉验证 ensemble,macro F1"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"seq": 8,
|
|
91
|
+
"bullseye": "T-librosa",
|
|
92
|
+
"title": "Spooky Disaster or Creepy Pizza",
|
|
93
|
+
"platform": "nitro",
|
|
94
|
+
"difficulty": 4,
|
|
95
|
+
"data_mb": 63,
|
|
96
|
+
"needs_gpu": false,
|
|
97
|
+
"cli_mode": "kaggle-arena",
|
|
98
|
+
"dir": "nitro/47_nitro_spooky-round-2025_t2_spooky-disaster-or-creepy-pizza",
|
|
99
|
+
"topic_cn": "音频修复:500段声音各4000个采样点,部分片段被填0,重建缺失值(MSE);数据200Hz生成、需重采样到44.1kHz才可听"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"seq": 9,
|
|
103
|
+
"bullseye": "T-torch",
|
|
104
|
+
"title": "Alchemy",
|
|
105
|
+
"platform": "aicc",
|
|
106
|
+
"difficulty": 3,
|
|
107
|
+
"data_mb": 1,
|
|
108
|
+
"needs_gpu": false,
|
|
109
|
+
"cli_mode": "kaggle-arena",
|
|
110
|
+
"dir": "alchemy-aicc-round-4",
|
|
111
|
+
"topic_cn": "「小炼金术」式语义合成:给 item1+item2 预测合成结果(如 bird+fire→phoenix),候选集封闭,官方解答用 BERT 打分 + 匈牙利算法做全局指派"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"seq": 10,
|
|
115
|
+
"bullseye": "T-umap",
|
|
116
|
+
"title": "Hello, Aliens!",
|
|
117
|
+
"platform": "nitro",
|
|
118
|
+
"difficulty": 3,
|
|
119
|
+
"data_mb": 9,
|
|
120
|
+
"needs_gpu": false,
|
|
121
|
+
"cli_mode": "kaggle-arena",
|
|
122
|
+
"dir": "nitro/24_algolymp_algolymp-preojia-xi-xii_t2_hello-aliens",
|
|
123
|
+
"topic_cn": "50维射电频谱:①信号/噪声二分类(F1≥0.98) ②接触概率回归 ③来源三分类;题面明说有效信号只住在低维流形上"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"seq": 11,
|
|
127
|
+
"bullseye": "T-lora",
|
|
128
|
+
"title": "Haunt me! 👻",
|
|
129
|
+
"platform": "nitro",
|
|
130
|
+
"difficulty": 3,
|
|
131
|
+
"data_mb": 66,
|
|
132
|
+
"needs_gpu": true,
|
|
133
|
+
"cli_mode": "kaggle-arena",
|
|
134
|
+
"dir": "nitro/46_nitro_spooky-round-2025_t1_haunt-me",
|
|
135
|
+
"topic_cn": "万圣节鬼影检测:①有无鬼(准确率) ②鬼的边界框(mAP/IoU);官方解答给了naive/ResNet/Faster-RCNN三档"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"seq": 12,
|
|
139
|
+
"bullseye": "T-librosa",
|
|
140
|
+
"title": "Audio Demixing",
|
|
141
|
+
"platform": "aicc",
|
|
142
|
+
"difficulty": 4,
|
|
143
|
+
"data_mb": 927,
|
|
144
|
+
"needs_gpu": true,
|
|
145
|
+
"cli_mode": "learn-card",
|
|
146
|
+
"dir": "audio-demixing-aicc-round-2",
|
|
147
|
+
"topic_cn": "2897 条 5 秒 wav:把混合音轨拆成两路信号,UNet + PIT(置换不变)损失,提交两路波形的 base85 编码"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"seq": 13,
|
|
151
|
+
"bullseye": "T-torch",
|
|
152
|
+
"title": "Polarity",
|
|
153
|
+
"platform": "aicc",
|
|
154
|
+
"difficulty": 3,
|
|
155
|
+
"data_mb": 1,
|
|
156
|
+
"needs_gpu": false,
|
|
157
|
+
"cli_mode": "kaggle-arena",
|
|
158
|
+
"dir": "polarity-aicc-round-7",
|
|
159
|
+
"topic_cn": "判断词对是同义还是反义(cash/money=0,inferior/worse=?)——训练集只有 897 字节(约 40 对),官方解答用掩码语言模型在模板句上取 logit 当特征再训分类器"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"seq": 14,
|
|
163
|
+
"bullseye": "T-umap",
|
|
164
|
+
"title": "Sami, Ofițerul de Conformitate",
|
|
165
|
+
"platform": "nitro",
|
|
166
|
+
"difficulty": 3,
|
|
167
|
+
"data_mb": 1,
|
|
168
|
+
"needs_gpu": false,
|
|
169
|
+
"cli_mode": "kaggle-arena",
|
|
170
|
+
"dir": "nitro/38_decebaltech_decebaltech-ai-challenge_t1_sami-ofiterul-de-conformitate",
|
|
171
|
+
"topic_cn": "仓储合规:①判断商品图被旋转了几个90°(4类macro F1) ②把野拍审计图检索回官方影棚目录图(top-1)"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"seq": 15,
|
|
175
|
+
"bullseye": "T-lora",
|
|
176
|
+
"title": "Find the Ducks",
|
|
177
|
+
"platform": "nitro",
|
|
178
|
+
"difficulty": 3,
|
|
179
|
+
"data_mb": 536,
|
|
180
|
+
"needs_gpu": true,
|
|
181
|
+
"cli_mode": "kaggle-arena",
|
|
182
|
+
"dir": "nitro/74_nitro-2025_nitro-nlp_t3_find-the-ducks",
|
|
183
|
+
"topic_cn": "黑客松:①图里有没有Nitro鸭 ②鸭子占多少像素 ③鸭子的边界框(按IoU给分);鸭子会旋转/翻转/缩放"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"seq": 16,
|
|
187
|
+
"bullseye": "T-torch",
|
|
188
|
+
"title": "Lost Interpreter",
|
|
189
|
+
"platform": "aicc",
|
|
190
|
+
"difficulty": 3,
|
|
191
|
+
"data_mb": 1,
|
|
192
|
+
"needs_gpu": false,
|
|
193
|
+
"cli_mode": "kaggle-arena",
|
|
194
|
+
"dir": "lost-interpreter-aicc-round-5",
|
|
195
|
+
"topic_cn": "给一段自定义字节码程序(OP5 13 ; OP7 -2 ; …)预测其数值输出,官方解答用 LSTM 端到端学「执行」,判分 MAE"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"seq": 17,
|
|
199
|
+
"bullseye": "T-umap",
|
|
200
|
+
"title": "Bazarul lui Riki",
|
|
201
|
+
"platform": "nitro",
|
|
202
|
+
"difficulty": 3,
|
|
203
|
+
"data_mb": 2,
|
|
204
|
+
"needs_gpu": false,
|
|
205
|
+
"cli_mode": "kaggle-arena",
|
|
206
|
+
"dir": "nitro/39_decebaltech_decebaltech-ai-challenge_t2_bazarul-lui-riki",
|
|
207
|
+
"topic_cn": "①英文商品描述判可食用(macro F1) ②西班牙语查询跨语种检索英文商品(top-1);训练集里is_food=-1的行专供跨语种对齐"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"seq": 18,
|
|
211
|
+
"bullseye": "T-lora",
|
|
212
|
+
"title": "The Hieroglyph Hunter",
|
|
213
|
+
"platform": "nitro",
|
|
214
|
+
"difficulty": 4,
|
|
215
|
+
"data_mb": 1,
|
|
216
|
+
"needs_gpu": false,
|
|
217
|
+
"cli_mode": "kaggle-arena",
|
|
218
|
+
"dir": "nitro/30_nitro_pre-iaio-2026_t4_the-hieroglyph-hunter",
|
|
219
|
+
"topic_cn": "emoji序列→英文句子语义检索:1000句语料(含爱丽丝梦游仙境干扰句),查询分字面/习语/网络俚语三档难度,只给少量support示例"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"seq": 19,
|
|
223
|
+
"bullseye": "T-torch",
|
|
224
|
+
"title": "Lunar Craters",
|
|
225
|
+
"platform": "nitro",
|
|
226
|
+
"difficulty": 3,
|
|
227
|
+
"data_mb": 15,
|
|
228
|
+
"needs_gpu": false,
|
|
229
|
+
"cli_mode": "kaggle-arena",
|
|
230
|
+
"dir": "nitro/23_algolymp_algolymp-preojia-xi-xii_t1_lunar-craters",
|
|
231
|
+
"topic_cn": "128×128合成月面图:①数陨石坑个数(MAE) ②估计侵蚀年龄参数1.0-5.0(MAE)"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"seq": 20,
|
|
235
|
+
"bullseye": "T-umap",
|
|
236
|
+
"title": "Latent Model Classification",
|
|
237
|
+
"platform": "aicc",
|
|
238
|
+
"difficulty": 3,
|
|
239
|
+
"data_mb": 5,
|
|
240
|
+
"needs_gpu": false,
|
|
241
|
+
"cli_mode": "kaggle-arena",
|
|
242
|
+
"dir": "latent-model-classification-aicc-round-0",
|
|
243
|
+
"topic_cn": "给出两个模型 A/B 的倒数第二层权重 + 一批潜在向量,判定每个向量出自哪个模型(ridge + ML 理论)"
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"seq": 21,
|
|
247
|
+
"bullseye": "T-lora",
|
|
248
|
+
"title": "Autocorrect",
|
|
249
|
+
"platform": "aicc",
|
|
250
|
+
"difficulty": 4,
|
|
251
|
+
"data_mb": 6,
|
|
252
|
+
"needs_gpu": true,
|
|
253
|
+
"cli_mode": "kaggle-arena",
|
|
254
|
+
"dir": "autocorrect-aicc-round-1-2",
|
|
255
|
+
"topic_cn": "13MB 英文语料的字符级纠错:错字文本与正确文本等长,官方明确提示用 encoder-only 而非 seq2seq,且整段推理必须在 250 秒内跑完"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"seq": 22,
|
|
259
|
+
"bullseye": "T-torch",
|
|
260
|
+
"title": "Sticky Note Blindness",
|
|
261
|
+
"platform": "aicc",
|
|
262
|
+
"difficulty": 3,
|
|
263
|
+
"data_mb": 88,
|
|
264
|
+
"needs_gpu": false,
|
|
265
|
+
"cli_mode": "kaggle-arena",
|
|
266
|
+
"dir": "sticky-note-blindness-aicc-round-4",
|
|
267
|
+
"topic_cn": "CLIP 印刷体攻击(图上贴便利贴写错类名)下的鲁棒分类:官方解答 MirrorCLIP——水平翻转后按维度符号一致性分离「视觉维/文字维」"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"seq": 23,
|
|
271
|
+
"bullseye": "T-umap",
|
|
272
|
+
"title": "🧔 Om vs AI 🤖",
|
|
273
|
+
"platform": "nitro",
|
|
274
|
+
"difficulty": 3,
|
|
275
|
+
"data_mb": 11,
|
|
276
|
+
"needs_gpu": false,
|
|
277
|
+
"cli_mode": "kaggle-arena",
|
|
278
|
+
"dir": "nitro/59_roai-2025_onia_t1_om-vs-ai",
|
|
279
|
+
"topic_cn": "全国赛:①文本是人写还是AI生成(macro F1≥95才满分) ②四大主题分类——但训练集根本没有主题标签,必须零样本/无监督做"
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"seq": 24,
|
|
283
|
+
"bullseye": "T-lora",
|
|
284
|
+
"title": "🐦 Angry Birds 🐦",
|
|
285
|
+
"platform": "nitro",
|
|
286
|
+
"difficulty": 5,
|
|
287
|
+
"data_mb": 159,
|
|
288
|
+
"needs_gpu": true,
|
|
289
|
+
"cli_mode": "kaggle-arena",
|
|
290
|
+
"dir": "nitro/56_roai-2025_lot-baraj-1_t2_angry-birds",
|
|
291
|
+
"topic_cn": "国家队选拔:训练集里土鸟几乎总配陆地背景、水鸟几乎总配水背景;最终按(鸟种×背景)四种组合中最差的一档准确率计分;允许ResNet50"
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"seq": 25,
|
|
295
|
+
"bullseye": "T-torch",
|
|
296
|
+
"title": "Smart Waste Classifier ♻️",
|
|
297
|
+
"platform": "nitro",
|
|
298
|
+
"difficulty": 3,
|
|
299
|
+
"data_mb": 93,
|
|
300
|
+
"needs_gpu": false,
|
|
301
|
+
"cli_mode": "kaggle-arena",
|
|
302
|
+
"dir": "nitro/49_cram-school_cram-school-training-1_t2_smart-waste-classifier",
|
|
303
|
+
"topic_cn": "垃圾图六分类(纸板/塑料/其他/玻璃/金属/纸),macro F1"
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"seq": 26,
|
|
307
|
+
"bullseye": "T-umap",
|
|
308
|
+
"title": "პლანეტა X-ის მოდელის შერჩევა (Planet X Model Selection)",
|
|
309
|
+
"platform": "nitro",
|
|
310
|
+
"difficulty": 3,
|
|
311
|
+
"data_mb": 16,
|
|
312
|
+
"needs_gpu": false,
|
|
313
|
+
"cli_mode": "kaggle-arena",
|
|
314
|
+
"dir": "nitro/34_gaia_ai-league-i_t2_x-planet-x-model-selection",
|
|
315
|
+
"topic_cn": "1000个回归模型里只有5个是在未损坏标签上训出来的,仅凭它们在训练特征上的预测矩阵把这5个揪出来"
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"seq": 27,
|
|
319
|
+
"bullseye": "T-librosa",
|
|
320
|
+
"title": "Audio Classifier · Operation Night Watch",
|
|
321
|
+
"platform": "icoa",
|
|
322
|
+
"difficulty": 4,
|
|
323
|
+
"data_mb": 1900,
|
|
324
|
+
"needs_gpu": true,
|
|
325
|
+
"cli_mode": "kaggle-arena",
|
|
326
|
+
"dir": "audio-classifier",
|
|
327
|
+
"topic_cn": "IOAI 真题:给已部署的音频模型教 13 个新类而不忘旧 16 类(29 类)。评分 0.5·acc_old + 0.5·acc_new"
|
|
328
|
+
}
|
|
329
|
+
]
|
|
330
|
+
}
|
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 a}from"./commands/challenge.js";import{registerDoctorCommand as l}from"./commands/doctor.js";import{registerNoteCommand as m}from"./commands/note.js";import{registerLogCommand as c}from"./commands/log.js";import{registerLangCommand as d}from"./commands/lang.js";import{registerSetupCommand as g}from"./commands/setup.js";import{registerEnvCommand as p}from"./commands/env.js";import{registerAienvCommand as f}from"./commands/aienv.js";import{registerIpynbCommand as y}from"./commands/ipynb.js";import{registerAi4ctfCommand as h}from"./commands/ai4ctf.js";import{registerExamCommand as u}from"./commands/exam.js";import{registerCtf4aiDemoCommand as w}from"./commands/ctf4ai-demo.js";import{registerThemeCommand as b}from"./commands/theme.js";import{registerLearnCommand as
|
|
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 a}from"./commands/challenge.js";import{registerDoctorCommand as l}from"./commands/doctor.js";import{registerNoteCommand as m}from"./commands/note.js";import{registerLogCommand as c}from"./commands/log.js";import{registerLangCommand as d}from"./commands/lang.js";import{registerSetupCommand as g}from"./commands/setup.js";import{registerEnvCommand as p}from"./commands/env.js";import{registerAienvCommand as f}from"./commands/aienv.js";import{registerIpynbCommand as y}from"./commands/ipynb.js";import{registerAi4ctfCommand as h}from"./commands/ai4ctf.js";import{registerExamCommand as u}from"./commands/exam.js";import{registerCtf4aiDemoCommand as w}from"./commands/ctf4ai-demo.js";import{registerThemeCommand as b}from"./commands/theme.js";import{registerLearnCommand as j}from"./commands/learn.js";import{registerCtf4VlaCommand as v}from"./commands/ctf4vla.js";import{registerDemo2Command as T}from"./commands/demo2.js";import{registerDemo4Command as A}from"./commands/demo4.js";import{registerDemo5Command as I}from"./commands/demo5.js";import{registerSimCommand as $}from"./commands/sim.js";import{registerArenaCommand as C}from"./commands/arena.js";import{registerKaggleCommand as E}from"./commands/kaggle.js";import{registerSprintCommand as _}from"./commands/sprint.js";import{registerTeleloadCommand as S}from"./commands/teleload.js";import{registerBoardCommand as x}from"./commands/board.js";import{getConfig as O,saveConfig as L}from"./lib/config.js";import{startRepl as k}from"./repl.js";import{RELAUNCH_CODE as N}from"./lib/menu-nav.js";import{setTerminalTheme as R}from"./lib/theme.js";import{cleanupTerminal as F}from"./lib/terminal-cleanup.js";import{checkForUpdates as U}from"./lib/update-check.js";import{detectIcoaInstalls as P}from"./lib/platform.js";import{ICOA_BIG as M}from"./lib/banner.js";import{readFileSync as G}from"node:fs";import{fileURLToPath as D}from"node:url";import{dirname as H,join as J}from"node:path";const V=H(D(import.meta.url)),Y=JSON.parse(G(J(V,"..","package.json"),"utf-8")).version,W=chalk.cyan(" ─────────────────────────────────────────────────────"),X=`\n${W}\n\n${M.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${Y}`)}\n\n${W}\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){e=0;break}e=r.status,n=!0}while(e===N);F(),process.exit(e??0)}}const q=new o;if(q.name("icoa").version(Y).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=O();R("high-contrast"===e.themeVariant?"high-contrast":"dark"),U(),function(){const o=P();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 n=process.env.LANG||process.env.LC_ALL||process.env.LC_CTYPE||"";if(!/UTF-?8/i.test(n))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=${n||"(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();console.log(X);const s=!!o.resume||!!o.continue;if(process.argv.length<=2||s)return o.continue&&(process.env.ICOA_AUTO_RESUME="1"),s||"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 k(q,s)}),e(q),n(q),s(q),r(q),t(q),i(q),a(q),l(q),m(q),c(q),d(q),g(q),p(q),f(q),y(q),h(q),u(q),w(q),b(q),j(q),v(q),T(q),A(q),I(q),$(q),C(q),E(q),S(q),_(q),x(q),q.command("model",{hidden:!0}).argument("[name]","model name to switch to").action(o=>{const e=O().geminiModel||"gemini-2.5-flash-lite";o?(L({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)))}q.parse();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface IcoaCommand {
|
|
2
|
+
/** The verb a user types. Must be reachable — a name here that dispatches
|
|
3
|
+
* nowhere is a promise the CLI cannot keep. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** Handled by an explicit `input === ...` branch ABOVE the dispatch gate
|
|
6
|
+
* (nav verbs, screen control, background-task panels). Such a verb must
|
|
7
|
+
* stay OUT of knownCommands: the gate never sees it. */
|
|
8
|
+
nav?: true;
|
|
9
|
+
/** Rewrites to a different argv, e.g. sb -> ctf scoreboard. */
|
|
10
|
+
mapsTo?: string[];
|
|
11
|
+
/** Append the user's remaining words to mapsTo. */
|
|
12
|
+
rest?: true;
|
|
13
|
+
/** Second-word Tab completion. Slightly stale entries are harmless — they
|
|
14
|
+
* simply will not dispatch — but these track the real subcommand surface. */
|
|
15
|
+
subs?: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare const REGISTRY: readonly IcoaCommand[];
|
|
18
|
+
/** Everything typeable: Tab completion, the `/cmd` slash layer, typo suggestions. */
|
|
19
|
+
export declare const surface: () => string[];
|
|
20
|
+
/** The dispatch gate. Excludes nav verbs, which are consumed before the gate —
|
|
21
|
+
* listing them here would be harmless but misleading about who handles what. */
|
|
22
|
+
export declare const dispatchable: () => string[];
|
|
23
|
+
/** name -> argv rewrite, with the caller's trailing words appended when `rest`. */
|
|
24
|
+
export declare function shortcutFor(name: string, rest: string[]): string[] | null;
|
|
25
|
+
/** parent -> second-word completions. */
|
|
26
|
+
export declare const subcommandsOf: (name: string) => readonly string[] | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const REGISTRY=[{name:"join",mapsTo:["ctf","join"],rest:!0},{name:"activate",mapsTo:["ctf","activate"],rest:!0},{name:"challenges",mapsTo:["ctf","challenges"]},{name:"ch",mapsTo:["ctf","challenges"]},{name:"open",mapsTo:["ctf","open"],rest:!0},{name:"submit",mapsTo:["ctf","submit"],rest:!0},{name:"flag",mapsTo:["ctf","submit"],rest:!0},{name:"scoreboard",mapsTo:["ctf","scoreboard"],rest:!0},{name:"sb",mapsTo:["ctf","scoreboard"],rest:!0},{name:"status",mapsTo:["ctf","status"]},{name:"time",mapsTo:["ctf","time"]},{name:"ref"},{name:"shell"},{name:"files"},{name:"view"},{name:"connect"},{name:"challenge",subs:["start","stop","status"]},{name:"note"},{name:"notes"},{name:"logbook"},{name:"log"},{name:"man"},{name:"manual"},{name:"lang"},{name:"setup"},{name:"env"},{name:"aienv"},{name:"ipynb"},{name:"kaggle"},{name:"teleload"},{name:"pandahelpme31"},{name:"guide"},{name:"ai4ctf"},{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"]},{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:"ctf4eai"},{name:"ctf4vla"},{name:"theme"},{name:"sim"},{name:"arena",subs:["eai"]},{name:"eai"},{name:"board"},{name:"learn-pull"},{name:"doctor"},{name:"bg",nav:!0},{name:"tasks",nav:!0},{name:"drafts",nav:!0},{name:"help",nav:!0},{name:"menu",nav:!0},{name:"quit",nav:!0},{name:"q",nav:!0},{name:"exit",nav:!0},{name:"back",nav:!0},{name:"resume",nav:!0},{name:"clear",nav:!0},{name:"cls",nav:!0}];export const surface=()=>REGISTRY.map(a=>a.name);export const dispatchable=()=>REGISTRY.filter(a=>!a.nav).map(a=>a.name);export function shortcutFor(a,e){const n=REGISTRY.find(e=>e.name===a&&e.mapsTo);return n?.mapsTo?n.rest?[...n.mapsTo,...e]:[...n.mapsTo]:null}export const subcommandsOf=a=>REGISTRY.find(e=>e.name===a)?.subs;
|