yg-team-cli 2.5.6 → 2.5.8

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/README.md CHANGED
@@ -61,6 +61,14 @@
61
61
  - **改进**: 调整交互式会话参数顺序,确保任务指令在启动时 100% 被加载
62
62
  - **清理**: 移除控制台冗余的 Prompt 打印信息,实现更清爽的界面切换
63
63
 
64
+ **v2.5.7** - 修复 Claude CLI 可能重复启动的问题
65
+ - **修复**: 优化内部检查逻辑,使用更轻量的 `which` 进行环境检查,避免因 `--version` 检查逻辑导致的潜在多次触发
66
+ - **优化**: 简化 `runTerminal` 传参逻辑,移除冗余参数,确保单次稳定启动交互式会话
67
+
68
+ **v2.5.8** - Milestone 选择样式优化
69
+ - **新增**: `team-cli dev` 选择里程碑时,现在会直观显示已完成、进行中和未开始的状态图标及进度 (如 `[4/7]`)
70
+ - **改进**: 增强了 Spec 文件的解析逻辑,能够更准确地识别已标记为 `[x]` 的任务项
71
+
64
72
  **v2.4.10** - 修复 Claude 返回权限确认而非实际内容问题
65
73
  - **修复**: 添加 `--dangerously-skip-permissions` 参数跳过权限确认
66
74
  - **问题**: v2.4.9 中 Claude CLI 在新目录首次运行时返回权限确认提示而非 spec 内容
package/dist/cli.js CHANGED
@@ -454,13 +454,10 @@ var init_claude = __esm({
454
454
  constructor(verbose = false) {
455
455
  this.verbose = verbose;
456
456
  }
457
- /**
458
- * 检查 Claude CLI 是否已安装
459
- */
460
457
  async checkInstalled() {
461
458
  try {
462
- await execa("claude", ["--version"], { stdio: "pipe" });
463
- return true;
459
+ const { exitCode } = await execa("which", ["claude"], { stdio: "ignore", reject: false });
460
+ return exitCode === 0;
464
461
  } catch {
465
462
  return false;
466
463
  }
@@ -547,12 +544,10 @@ ${promptText}`;
547
544
  /**
548
545
  * 启动交互式会话
549
546
  */
550
- async runTerminal(promptText, _options) {
547
+ async runTerminal(promptText) {
551
548
  logger.info("\u6B63\u5728\u542F\u52A8\u4EA4\u4E92\u5F0F Claude \u4F1A\u8BDD...");
552
- const args = ["--dangerously-skip-permissions"];
553
- args.push("--add-dir", process.cwd());
554
549
  try {
555
- await execa("claude", [promptText, ...args], {
550
+ await execa("claude", ["--dangerously-skip-permissions", promptText], {
556
551
  stdio: "inherit",
557
552
  env: { ...process.env, FORCE_COLOR: "1" }
558
553
  });
@@ -562,9 +557,6 @@ ${promptText}`;
562
557
  }
563
558
  }
564
559
  }
565
- /**
566
- * 发送对话(支持上下文)
567
- */
568
560
  /**
569
561
  * 发送对话(支持上下文)
570
562
  */
@@ -2844,11 +2836,17 @@ async function selectMilestone(specFile) {
2844
2836
  return "\u6574\u4E2A spec";
2845
2837
  }
2846
2838
  }
2847
- const choices = milestones.map((m, idx) => ({
2848
- name: `${idx + 1}. ${m.title} (${m.todos.length} \u4E2A\u4EFB\u52A1)`,
2849
- value: m.title,
2850
- short: m.title
2851
- }));
2839
+ const choices = milestones.map((m, idx) => {
2840
+ const isDone = m.completedCount === m.todos.length && m.todos.length > 0;
2841
+ const statusIcon = isDone ? "\u2713" : m.completedCount > 0 ? "\u27F3" : "\u25CB";
2842
+ const progress = `[${m.completedCount}/${m.todos.length}]`;
2843
+ const label = isDone ? `\u2713 ${m.title}` : `${statusIcon} ${progress} ${m.title}`;
2844
+ return {
2845
+ name: `${idx + 1}. ${label} (${m.todos.length} \u4E2A\u4EFB\u52A1)`,
2846
+ value: m.title,
2847
+ short: m.title
2848
+ };
2849
+ });
2852
2850
  choices.push({
2853
2851
  name: `${milestones.length + 1}. \u6574\u4E2A spec (\u5168\u90E8 milestones)`,
2854
2852
  value: "\u6574\u4E2A spec",
@@ -2932,9 +2930,7 @@ async function executeDevelopment(specFile, milestone, todo) {
2932
2930
  logger.info(' 2. \u6309 "a" \u63A5\u53D7\u6240\u6709\u7F16\u8F91\u5EFA\u8BAE\uFF0C\u6216\u9010\u4E2A\u9009\u62E9');
2933
2931
  logger.info(" 3. \u5B8C\u6210\u540E\u4F7F\u7528 Ctrl+D \u6216\u8F93\u5165 :exit \u9000\u51FA Claude");
2934
2932
  logger.newLine();
2935
- await claudeAI.runTerminal(prompt, {
2936
- contextFiles: ["TECH_STACK.md", "CONVENTIONS.md", "AI_MEMORY.md", specFile]
2937
- });
2933
+ await claudeAI.runTerminal(prompt);
2938
2934
  logger.newLine();
2939
2935
  logger.separator("\u2500", 60);
2940
2936
  logger.newLine();
@@ -2991,7 +2987,7 @@ function parseMilestones(spec) {
2991
2987
  milestones.push(currentMilestone);
2992
2988
  }
2993
2989
  const title = line.replace(/^###\s+/, "").trim();
2994
- currentMilestone = { title, todos: [] };
2990
+ currentMilestone = { title, todos: [], completedCount: 0 };
2995
2991
  inMilestone = true;
2996
2992
  continue;
2997
2993
  }
@@ -3001,9 +2997,13 @@ function parseMilestones(spec) {
3001
2997
  currentMilestone = null;
3002
2998
  continue;
3003
2999
  }
3004
- const todoMatch = line.match(/^-\s+\[[ x ]\]\s*(.+)/);
3000
+ const todoMatch = line.match(/^-\s+\[([ xX])\]\s*(.+)/);
3005
3001
  if (todoMatch) {
3006
- currentMilestone.todos.push(todoMatch[1].trim());
3002
+ const isCompleted = todoMatch[1].toLowerCase() === "x";
3003
+ if (isCompleted) {
3004
+ currentMilestone.completedCount++;
3005
+ }
3006
+ currentMilestone.todos.push(todoMatch[2].trim());
3007
3007
  }
3008
3008
  }
3009
3009
  }