@icyfenix-dmla/cli 2026.5.2-1955 → 2026.5.2-2022

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icyfenix-dmla/cli",
3
- "version": "2026.5.2-1955",
3
+ "version": "2026.5.2-2022",
4
4
  "description": "DMLA 沙箱服务命令行工具",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -208,9 +208,8 @@ async function showMainMenu(dataPath) {
208
208
  { name: '2', message: '下载数据集' },
209
209
  { name: '3', message: '查看数据集列表' },
210
210
  { name: '4', message: '清空数据内容' },
211
- { name: '5', message: '显示实际路径' },
212
- { name: '6', message: '删除数据卷' },
213
- { name: '7', message: '退出' }
211
+ { name: '5', message: '删除数据卷' },
212
+ { name: '6', message: '退出' }
214
213
  ]
215
214
 
216
215
  const { action } = await prompt({
@@ -277,35 +276,6 @@ async function mountPath() {
277
276
  console.log(chalk.yellow('提示: 需要重启沙箱服务才能生效 (dmla stop && dmla start)'))
278
277
  }
279
278
 
280
- /**
281
- * 显示实际路径
282
- */
283
- function showPath() {
284
- const dataPath = getDataVolumePath()
285
- const stats = getDirectoryStats(dataPath)
286
-
287
- console.log()
288
- console.log(chalk.bold('数据卷信息'))
289
- console.log()
290
- console.log(chalk.gray(`挂载路径: ${dataPath}`))
291
- console.log(chalk.gray(`存在状态: ${fs.existsSync(dataPath) ? '已创建' : '未创建'}`))
292
- console.log(chalk.gray(`数据集数量: ${stats.datasets}`))
293
- console.log(chalk.gray(`模型数量: ${stats.models}`))
294
- console.log()
295
-
296
- // 显示子目录
297
- if (fs.existsSync(dataPath)) {
298
- console.log(chalk.bold('目录结构:'))
299
- const subDirs = ['datasets', 'models', 'outputs', 'cache']
300
- for (const dir of subDirs) {
301
- const fullPath = path.join(dataPath, dir)
302
- const exists = fs.existsSync(fullPath)
303
- console.log(chalk.gray(` ${dir}/ ${exists ? '(已存在)' : '(不存在)'}`))
304
- }
305
- }
306
- console.log()
307
- }
308
-
309
279
  /**
310
280
  * 清空数据内容
311
281
  */
@@ -419,54 +389,87 @@ async function downloadDatasets() {
419
389
  return
420
390
  }
421
391
 
422
- // 显示可用数据集
423
- console.log('可用数据集:')
424
- console.log()
392
+ // 检查 Git 环境
393
+ try {
394
+ execSync('git --version', { stdio: 'pipe' })
395
+ } catch {
396
+ console.log(chalk.red('❌ Git 未安装'))
397
+ console.log(chalk.yellow('下载数据集需要 Git,请先安装: https://git-scm.com/downloads'))
398
+ return
399
+ }
425
400
 
426
- for (let i = 0; i < DATASETS.length; i++) {
427
- const dataset = DATASETS[i]
401
+ // 构建选项列表
402
+ const choices = DATASETS.map((dataset, index) => {
428
403
  const downloaded = isDatasetDownloaded(dataPath, dataset.id)
429
- const status = downloaded ? chalk.green('[x]') : chalk.gray('[ ]')
430
- const downloadedTag = downloaded ? chalk.gray(' (已下载)') : chalk.gray(` (${dataset.size})`)
431
- console.log(` ${i + 1}. ${status} ${dataset.name}${downloadedTag}`)
432
- }
404
+ const isMnist = dataset.id === 'mnist'
433
405
 
434
- console.log()
435
- console.log(chalk.gray('提示: 输入序号选择数据集,q 返回'))
436
- console.log()
406
+ let message = `${dataset.name} (${dataset.size})`
407
+ if (downloaded) {
408
+ message += ' [已下载]'
409
+ } else if (isMnist) {
410
+ message += ' [训练时自动下载]'
411
+ }
437
412
 
438
- const { selection } = await prompt({
439
- type: 'input',
440
- name: 'selection',
441
- message: '选择要下载的数据集序号'
413
+ return {
414
+ name: index.toString(),
415
+ message,
416
+ disabled: downloaded || isMnist
417
+ }
442
418
  })
443
419
 
444
- if (selection.toLowerCase() === 'q') {
445
- return
446
- }
420
+ // 操作提示
421
+ console.log(chalk.gray('操作: 上下键移动,空格勾选/取消,回车确认,ESC 返回'))
422
+ console.log()
447
423
 
448
- const index = parseInt(selection) - 1
449
- if (index < 0 || index >= DATASETS.length) {
450
- console.log(chalk.yellow('无效的选择'))
451
- return
452
- }
424
+ try {
425
+ const { selected } = await prompt({
426
+ type: 'multiselect',
427
+ name: 'selected',
428
+ message: '选择要下载的数据集',
429
+ choices,
430
+ hint: '空格选择,回车确认下载',
431
+ warn: '已下载或自动下载类型'
432
+ })
453
433
 
454
- const dataset = DATASETS[index]
434
+ if (!selected || selected.length === 0) {
435
+ console.log(chalk.yellow('未选择任何数据集'))
436
+ return
437
+ }
455
438
 
456
- // 检查是否已下载
457
- if (isDatasetDownloaded(dataPath, dataset.id)) {
458
- console.log(chalk.yellow(`${dataset.name} 已下载`))
459
- return
460
- }
439
+ // 下载选中的数据集
440
+ for (const indexStr of selected) {
441
+ const index = parseInt(indexStr)
442
+ const dataset = DATASETS[index]
461
443
 
462
- // MNIST 使用特殊处理
463
- if (dataset.id === 'mnist') {
464
- console.log(chalk.yellow('MNIST 数据集将在训练时通过 torchvision 自动下载'))
465
- return
444
+ console.log()
445
+ console.log(chalk.cyan(`────────────────────────────────────`))
446
+
447
+ // MNIST 特殊处理
448
+ if (dataset.id === 'mnist') {
449
+ console.log(chalk.yellow('MNIST 数据集将在训练时通过 torchvision 自动下载'))
450
+ continue
451
+ }
452
+
453
+ // 检查是否已下载
454
+ if (isDatasetDownloaded(dataPath, dataset.id)) {
455
+ console.log(chalk.yellow(`${dataset.name} 已下载,跳过`))
456
+ continue
457
+ }
458
+
459
+ await downloadDataset(dataPath, dataset)
466
460
  }
467
461
 
468
- // 开始下载
469
- await downloadDataset(dataPath, dataset)
462
+ console.log()
463
+ console.log(chalk.cyan(`────────────────────────────────────`))
464
+ console.log(chalk.green('所有选中的数据集已处理完成'))
465
+ } catch (error) {
466
+ // 用户按 ESC 或 Ctrl+C 取消
467
+ if (error.message && error.message.includes('cancel')) {
468
+ console.log(chalk.gray('返回上一级'))
469
+ return
470
+ }
471
+ throw error
472
+ }
470
473
  }
471
474
 
472
475
  /**
@@ -653,12 +656,9 @@ export async function runDataTUI() {
653
656
  await clearData()
654
657
  break
655
658
  case 5:
656
- showPath()
657
- break
658
- case 6:
659
659
  await removeData()
660
660
  break
661
- case 7:
661
+ case 6:
662
662
  console.log()
663
663
  console.log(chalk.gray('已退出数据管理'))
664
664
  console.log()