@agile-team/robot-cli 1.1.0 → 1.1.2

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.
Files changed (2) hide show
  1. package/lib/create.js +235 -47
  2. package/package.json +1 -1
package/lib/create.js CHANGED
@@ -1,4 +1,4 @@
1
- // lib/create.js - 简化版,移除缓存功能
1
+ // lib/create.js - 完整优化版,移除缓存功能 + 美化展示
2
2
  import fs from "fs-extra";
3
3
  import path from "path";
4
4
  import chalk from "chalk";
@@ -129,20 +129,57 @@ async function selectTemplate(templateOption) {
129
129
  }
130
130
 
131
131
  /**
132
- * 选择模板方式
132
+ * 选择模板方式 - 优化主菜单
133
133
  */
134
134
  async function selectTemplateMethod() {
135
+ console.log();
136
+ console.log(chalk.blue.bold("🎯 选择模板创建方式"));
137
+ console.log(chalk.dim("请选择最适合你的模板浏览方式"));
138
+ console.log();
139
+
135
140
  const { selectionMode } = await inquirer.prompt([
136
141
  {
137
142
  type: "list",
138
143
  name: "selectionMode",
139
- message: "请选择模板选择方式:",
144
+ message: "模板选择方式:",
140
145
  choices: [
141
- { name: "🎯 推荐模板 (常用模板快速选择)", value: "recommended" },
142
- { name: "📁 分类模板 (按项目类型分类选择)", value: "category" },
143
- { name: "🔍 搜索模板 (关键词搜索)", value: "search" },
144
- { name: "📋 全部模板 (查看所有可用模板)", value: "all" },
146
+ {
147
+ name: `🎯 ${chalk.bold('推荐模板')} ${chalk.dim('(常用模板快速选择)')}
148
+ ${chalk.dim('- 基于团队使用频率推荐的热门模板')}`,
149
+ value: "recommended"
150
+ },
151
+ {
152
+ name: "",
153
+ value: "spacer1",
154
+ disabled: true
155
+ },
156
+ {
157
+ name: `📁 ${chalk.bold('分类模板')} ${chalk.dim('(按项目类型分类选择)')}
158
+ ${chalk.dim('- 前端、后端、移动端、桌面端分类浏览')}`,
159
+ value: "category"
160
+ },
161
+ {
162
+ name: "",
163
+ value: "spacer2",
164
+ disabled: true
165
+ },
166
+ {
167
+ name: `🔍 ${chalk.bold('搜索模板')} ${chalk.dim('(关键词搜索)')}
168
+ ${chalk.dim('- 通过技术栈、功能特性等关键词快速查找')}`,
169
+ value: "search"
170
+ },
171
+ {
172
+ name: "",
173
+ value: "spacer3",
174
+ disabled: true
175
+ },
176
+ {
177
+ name: `📋 ${chalk.bold('全部模板')} ${chalk.dim('(查看所有可用模板)')}
178
+ ${chalk.dim('- 按分类展示所有可用的项目模板')}`,
179
+ value: "all"
180
+ },
145
181
  ],
182
+ pageSize: 12
146
183
  },
147
184
  ]);
148
185
 
@@ -161,7 +198,7 @@ async function selectTemplateMethod() {
161
198
  }
162
199
 
163
200
  /**
164
- * 从推荐模板中选择
201
+ * 从推荐模板中选择 - 优化后的展示
165
202
  */
166
203
  async function selectFromRecommended() {
167
204
  const recommended = getRecommendedTemplates();
@@ -172,17 +209,34 @@ async function selectFromRecommended() {
172
209
  }
173
210
 
174
211
  console.log();
175
- console.log(chalk.blue("🎯 推荐模板 (基于团队使用频率)"));
212
+ console.log(chalk.blue.bold("🎯 推荐模板"));
213
+ console.log(chalk.dim("基于团队使用频率和项目成熟度推荐"));
176
214
  console.log();
177
215
 
178
- const choices = Object.entries(recommended).map(([key, template]) => ({
179
- name: `${template.name} - ${chalk.dim(template.description)}`,
180
- value: { key, ...template },
181
- short: template.name,
182
- }));
216
+ // 创建更美观的选择项
217
+ const choices = Object.entries(recommended).map(([key, template]) => {
218
+ // 构建特性标签
219
+ const featureTags = template.features.slice(0, 3).map(f =>
220
+ chalk.cyan(`[${f}]`)
221
+ ).join(' ');
222
+
223
+ // 版本标签 - 只保留方括号内的版本
224
+ const versionTag = template.version === 'full' ?
225
+ chalk.green('[完整版]') :
226
+ chalk.yellow('[精简版]');
227
+
228
+ return {
229
+ name: `${chalk.bold.white(template.name)} ${versionTag}
230
+ ${chalk.dim(template.description)}
231
+ ${featureTags}${template.features.length > 3 ? chalk.dim(` +${template.features.length - 3}more`) : ''}
232
+ ${chalk.dim('━'.repeat(60))}`,
233
+ value: { key, ...template },
234
+ short: template.name,
235
+ };
236
+ });
183
237
 
184
238
  choices.push({
185
- name: chalk.dim("返回选择其他方式"),
239
+ name: chalk.dim("⬅️ 返回选择其他方式"),
186
240
  value: "back",
187
241
  });
188
242
 
@@ -192,7 +246,8 @@ async function selectFromRecommended() {
192
246
  name: "selectedTemplate",
193
247
  message: "选择推荐模板:",
194
248
  choices,
195
- pageSize: 10,
249
+ pageSize: 8,
250
+ loop: false
196
251
  },
197
252
  ]);
198
253
 
@@ -412,7 +467,7 @@ async function selectSpecificTemplate(categoryKey, stackKey, patternKey) {
412
467
  }
413
468
 
414
469
  /**
415
- * 搜索选择模板
470
+ * 搜索选择模板 - 优化结果展示
416
471
  */
417
472
  async function selectBySearch() {
418
473
  while (true) {
@@ -428,7 +483,9 @@ async function selectBySearch() {
428
483
  const results = searchTemplates(keyword);
429
484
 
430
485
  if (Object.keys(results).length === 0) {
486
+ console.log();
431
487
  console.log(chalk.yellow("🔍 没有找到匹配的模板"));
488
+ console.log(chalk.dim(`搜索关键词: "${keyword}"`));
432
489
  console.log();
433
490
 
434
491
  const { action } = await inquirer.prompt([
@@ -438,39 +495,57 @@ async function selectBySearch() {
438
495
  message: "请选择下一步操作:",
439
496
  choices: [
440
497
  { name: "🔍 重新搜索", value: "retry" },
441
- { name: "返回模板选择方式", value: "back" },
498
+ { name: "⬅️ 返回模板选择方式", value: "back" },
442
499
  ],
443
500
  },
444
501
  ]);
445
502
 
446
503
  if (action === "retry") {
447
- continue; // 重新搜索
504
+ continue;
448
505
  } else {
449
- return await selectTemplateMethod(); // 返回模板选择方式
506
+ return await selectTemplateMethod();
450
507
  }
451
508
  }
452
509
 
453
510
  console.log();
454
- console.log(
455
- chalk.green(`🔍 找到 ${Object.keys(results).length} 个匹配的模板:`)
456
- );
511
+ console.log(chalk.green.bold(`🔍 搜索结果`));
512
+ console.log(chalk.dim(`关键词: "${keyword}" • 找到 ${Object.keys(results).length} 个匹配模板`));
457
513
  console.log();
458
514
 
459
- const choices = Object.entries(results).map(([key, template]) => ({
460
- name: `${template.name} - ${chalk.dim(template.description)}`,
461
- value: { key, ...template },
462
- short: template.name,
463
- }));
515
+ const choices = Object.entries(results).map(([key, template]) => {
516
+ // 高亮匹配的关键词
517
+ const highlightText = (text) => {
518
+ const regex = new RegExp(`(${keyword})`, 'gi');
519
+ return text.replace(regex, chalk.bgYellow.black('$1'));
520
+ };
521
+
522
+ const techInfo = template.features.slice(0, 2).join(' • ');
523
+ const versionTag = template.version === 'full' ?
524
+ chalk.green('[完整版]') : chalk.yellow('[精简版]');
525
+
526
+ return {
527
+ name: `${chalk.bold(highlightText(template.name))} ${versionTag}
528
+ ${chalk.dim(highlightText(template.description))}
529
+ ${chalk.blue(techInfo)} ${chalk.gray(`• 模板key: ${key}`)}
530
+ ${chalk.dim('─'.repeat(60))}`,
531
+ value: { key, ...template },
532
+ short: template.name,
533
+ };
534
+ });
464
535
 
465
- // 添加操作选项
466
536
  choices.push(
467
537
  {
468
- name: chalk.dim("─────────────────────"),
538
+ name: "",
539
+ value: "spacer",
540
+ disabled: true
541
+ },
542
+ {
543
+ name: chalk.dim("━".repeat(70)),
469
544
  value: "separator",
470
545
  disabled: true,
471
546
  },
472
547
  { name: "🔍 重新搜索", value: "search_again" },
473
- { name: "返回模板选择方式", value: "back_to_mode" }
548
+ { name: "⬅️ 返回模板选择方式", value: "back_to_mode" }
474
549
  );
475
550
 
476
551
  const { selectedTemplate } = await inquirer.prompt([
@@ -480,13 +555,14 @@ async function selectBySearch() {
480
555
  message: "选择模板:",
481
556
  choices,
482
557
  pageSize: 15,
558
+ loop: false
483
559
  },
484
560
  ]);
485
561
 
486
562
  if (selectedTemplate === "search_again") {
487
- continue; // 重新搜索
563
+ continue;
488
564
  } else if (selectedTemplate === "back_to_mode") {
489
- return await selectTemplateMethod(); // 返回模板选择方式
565
+ return await selectTemplateMethod();
490
566
  } else {
491
567
  return selectedTemplate;
492
568
  }
@@ -494,31 +570,142 @@ async function selectBySearch() {
494
570
  }
495
571
 
496
572
  /**
497
- * 从全部模板中选择
573
+ * 从全部模板中选择 - 优化后的展示
498
574
  */
499
575
  async function selectFromAll() {
500
576
  const allTemplates = getAllTemplates();
501
577
 
502
578
  console.log();
503
- console.log(
504
- chalk.blue(`📋 全部模板 (共 ${Object.keys(allTemplates).length} )`)
505
- );
579
+ console.log(chalk.blue.bold(`📋 所有可用模板`));
580
+ console.log(chalk.dim(`共 ${Object.keys(allTemplates).length} 个模板可选`));
506
581
  console.log();
507
582
 
508
- const choices = Object.entries(allTemplates).map(([key, template]) => ({
509
- name: `${template.name} - ${chalk.dim(template.description)}`,
510
- value: { key, ...template },
511
- short: template.name,
512
- }));
583
+ // 按分类组织模板
584
+ const categorizedChoices = [];
585
+
586
+ // 前端模板
587
+ categorizedChoices.push({
588
+ name: chalk.yellow.bold("🎨 前端项目"),
589
+ value: "frontend_header",
590
+ disabled: true
591
+ });
592
+
593
+ Object.entries(allTemplates)
594
+ .filter(([key]) => key.includes('admin') || key.includes('react') || key.includes('micro'))
595
+ .forEach(([key, template]) => {
596
+ const techStack = key.includes('admin') ? 'Vue3' :
597
+ key.includes('react') ? 'React' : 'Vue3';
598
+ const versionTag = template.version === 'full' ?
599
+ chalk.green('[完整版]') : chalk.yellow('[精简版]');
600
+
601
+ categorizedChoices.push({
602
+ name: ` ● ${chalk.bold(template.name)} ${versionTag}
603
+ ${chalk.dim(template.description)}
604
+ ${chalk.blue(`技术栈: ${techStack}`)} ${chalk.gray(`• 命令: robot create my-app -t ${key}`)}`,
605
+ value: { key, ...template },
606
+ short: template.name
607
+ });
608
+ });
609
+
610
+ // 移动端模板
611
+ categorizedChoices.push({
612
+ name: "",
613
+ value: "spacer1",
614
+ disabled: true
615
+ });
616
+ categorizedChoices.push({
617
+ name: chalk.yellow.bold("📱 移动端项目"),
618
+ value: "mobile_header",
619
+ disabled: true
620
+ });
621
+
622
+ Object.entries(allTemplates)
623
+ .filter(([key]) => key.includes('uniapp') || key.includes('tarao'))
624
+ .forEach(([key, template]) => {
625
+ const versionTag = template.version === 'full' ?
626
+ chalk.green('[完整版]') : chalk.yellow('[精简版]');
627
+
628
+ categorizedChoices.push({
629
+ name: ` ● ${chalk.bold(template.name)} ${versionTag}
630
+ ${chalk.dim(template.description)}
631
+ ${chalk.blue('跨平台: 小程序/H5/App')} ${chalk.gray(`• 命令: robot create my-app -t ${key}`)}`,
632
+ value: { key, ...template },
633
+ short: template.name
634
+ });
635
+ });
636
+
637
+ // 后端模板
638
+ categorizedChoices.push({
639
+ name: "",
640
+ value: "spacer2",
641
+ disabled: true
642
+ });
643
+ categorizedChoices.push({
644
+ name: chalk.yellow.bold("🚀 后端项目"),
645
+ value: "backend_header",
646
+ disabled: true
647
+ });
648
+
649
+ Object.entries(allTemplates)
650
+ .filter(([key]) => key.includes('nest') || key.includes('koa'))
651
+ .forEach(([key, template]) => {
652
+ const framework = key.includes('nest') ? 'NestJS' : 'Koa3';
653
+ const versionTag = template.version === 'full' ?
654
+ chalk.green('[完整版]') : chalk.yellow('[精简版]');
655
+
656
+ categorizedChoices.push({
657
+ name: ` ● ${chalk.bold(template.name)} ${versionTag}
658
+ ${chalk.dim(template.description)}
659
+ ${chalk.blue(`框架: ${framework}`)} ${chalk.gray(`• 命令: robot create my-app -t ${key}`)}`,
660
+ value: { key, ...template },
661
+ short: template.name
662
+ });
663
+ });
664
+
665
+ // 桌面端模板
666
+ categorizedChoices.push({
667
+ name: "",
668
+ value: "spacer3",
669
+ disabled: true
670
+ });
671
+ categorizedChoices.push({
672
+ name: chalk.yellow.bold("💻 桌面端项目"),
673
+ value: "desktop_header",
674
+ disabled: true
675
+ });
676
+
677
+ Object.entries(allTemplates)
678
+ .filter(([key]) => key.includes('electron') || key.includes('tauri'))
679
+ .forEach(([key, template]) => {
680
+ const framework = key.includes('electron') ? 'Electron' : 'Tauri';
681
+ const versionTag = template.version === 'full' ?
682
+ chalk.green('[完整版]') : chalk.yellow('[精简版]');
683
+
684
+ categorizedChoices.push({
685
+ name: ` ● ${chalk.bold(template.name)} ${versionTag}
686
+ ${chalk.dim(template.description)}
687
+ ${chalk.blue(`框架: ${framework}`)} ${chalk.gray(`• 命令: robot create my-app -t ${key}`)}`,
688
+ value: { key, ...template },
689
+ short: template.name
690
+ });
691
+ });
513
692
 
514
693
  // 添加返回选项
515
- choices.push(
694
+ categorizedChoices.push(
516
695
  {
517
- name: chalk.dim("─────────────────────"),
696
+ name: "",
697
+ value: "spacer_end",
698
+ disabled: true
699
+ },
700
+ {
701
+ name: chalk.dim("━".repeat(70)),
518
702
  value: "separator",
519
703
  disabled: true,
520
704
  },
521
- { name: "← 返回模板选择方式", value: "back_to_mode" }
705
+ {
706
+ name: chalk.dim("⬅️ 返回模板选择方式"),
707
+ value: "back_to_mode"
708
+ }
522
709
  );
523
710
 
524
711
  const { selectedTemplate } = await inquirer.prompt([
@@ -526,8 +713,9 @@ async function selectFromAll() {
526
713
  type: "list",
527
714
  name: "selectedTemplate",
528
715
  message: "选择模板:",
529
- choices,
530
- pageSize: 15,
716
+ choices: categorizedChoices,
717
+ pageSize: 20,
718
+ loop: false
531
719
  },
532
720
  ]);
533
721
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agile-team/robot-cli",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "🤖 现代化项目脚手架工具,支持多技术栈快速创建项目 - 总是下载最新版本",
5
5
  "type": "module",
6
6
  "bin": {