yg-team-cli 2.6.2 → 2.6.3

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/cli.js CHANGED
@@ -460,6 +460,121 @@ var init_utils = __esm({
460
460
  }
461
461
  return milestones;
462
462
  }
463
+ /**
464
+ * 解析增强版里程碑信息(支持 [F]/[B]/[I] 前缀分类)
465
+ */
466
+ static parseMilestonesEnhanced(content) {
467
+ const milestones = [];
468
+ const lines = content.split("\n");
469
+ let currentMilestone = null;
470
+ let inMilestone = false;
471
+ for (const line of lines) {
472
+ if (line.match(/^###\s+Milestone\s+\d+:/)) {
473
+ if (currentMilestone) {
474
+ currentMilestone.totalCount = currentMilestone.todos.length;
475
+ milestones.push(currentMilestone);
476
+ }
477
+ const title = line.replace(/^###\s+/, "").trim();
478
+ currentMilestone = {
479
+ title,
480
+ todos: [],
481
+ frontendTodos: [],
482
+ backendTodos: [],
483
+ integrationTodos: [],
484
+ generalTodos: [],
485
+ completedCount: 0,
486
+ totalCount: 0
487
+ };
488
+ inMilestone = true;
489
+ continue;
490
+ }
491
+ if (inMilestone && currentMilestone) {
492
+ if (line.match(/^###\s+Milestone/)) {
493
+ currentMilestone.totalCount = currentMilestone.todos.length;
494
+ milestones.push(currentMilestone);
495
+ currentMilestone = null;
496
+ const title = line.replace(/^###\s+/, "").trim();
497
+ currentMilestone = {
498
+ title,
499
+ todos: [],
500
+ frontendTodos: [],
501
+ backendTodos: [],
502
+ integrationTodos: [],
503
+ generalTodos: [],
504
+ completedCount: 0,
505
+ totalCount: 0
506
+ };
507
+ continue;
508
+ }
509
+ const todoMatch = line.match(/^-\s+\[([ xX])\]\s*(\[[FBIN]\])?\s*(.+)/);
510
+ if (todoMatch) {
511
+ const isCompleted = todoMatch[1].toLowerCase() === "x";
512
+ const prefix = todoMatch[2]?.trim() || "";
513
+ const rawContent = todoMatch[3].trim();
514
+ let type = "general";
515
+ let apiAssociation;
516
+ let dependencies;
517
+ if (prefix === "[F]") {
518
+ type = "frontend";
519
+ } else if (prefix === "[B]") {
520
+ type = "backend";
521
+ const apiMatch = rawContent.match(/\(关联 API:\s*`([^`]+)`\)/);
522
+ if (apiMatch) {
523
+ apiAssociation = apiMatch[1];
524
+ }
525
+ } else if (prefix === "[I]") {
526
+ type = "integration";
527
+ const depMatch = rawContent.match(/\(依赖:\s*([^)]+)\)/);
528
+ if (depMatch) {
529
+ dependencies = depMatch[1].split(",").map((d) => d.trim()).filter((d) => d.length > 0);
530
+ }
531
+ }
532
+ const todoItem = {
533
+ raw: line.trim(),
534
+ content: rawContent.replace(/\s*\(关联 API:\s*`[^`]+`\)/, "").replace(/\s*\(依赖:\s*[^)]+\)/, "").trim(),
535
+ type,
536
+ apiAssociation,
537
+ dependencies,
538
+ isCompleted
539
+ };
540
+ currentMilestone.todos.push(todoItem);
541
+ if (isCompleted) {
542
+ currentMilestone.completedCount++;
543
+ }
544
+ switch (type) {
545
+ case "frontend":
546
+ currentMilestone.frontendTodos.push(todoItem);
547
+ break;
548
+ case "backend":
549
+ currentMilestone.backendTodos.push(todoItem);
550
+ break;
551
+ case "integration":
552
+ currentMilestone.integrationTodos.push(todoItem);
553
+ break;
554
+ default:
555
+ currentMilestone.generalTodos.push(todoItem);
556
+ }
557
+ }
558
+ }
559
+ }
560
+ if (currentMilestone) {
561
+ currentMilestone.totalCount = currentMilestone.todos.length;
562
+ milestones.push(currentMilestone);
563
+ }
564
+ return milestones;
565
+ }
566
+ /**
567
+ * 解析增强版里程碑(向后兼容版 - 优先尝试增强解析,失败回退到简单解析)
568
+ */
569
+ static parseMilestonesEnhancedWithFallback(content) {
570
+ const enhanced = this.parseMilestonesEnhanced(content);
571
+ const hasEnhancedFormat = enhanced.some(
572
+ (m) => m.todos.some(
573
+ (t) => t.type !== "general" || t.apiAssociation || t.dependencies
574
+ )
575
+ );
576
+ return { enhanced, isEnhanced: hasEnhancedFormat };
577
+ }
463
578
  /**
464
579
  * 解析 spec 状态(基于进度动态推导)
465
580
  */
@@ -1633,22 +1748,22 @@ var init_gitlab_api = __esm({
1633
1748
  * 从 Git URL 中提取项目路径
1634
1749
  */
1635
1750
  static parseProjectPath(repository) {
1636
- let path20 = repository;
1637
- if (path20.startsWith("git@")) {
1638
- path20 = path20.replace(/^git@/, "");
1639
- const colonIndex = path20.indexOf(":");
1751
+ let path21 = repository;
1752
+ if (path21.startsWith("git@")) {
1753
+ path21 = path21.replace(/^git@/, "");
1754
+ const colonIndex = path21.indexOf(":");
1640
1755
  if (colonIndex !== -1) {
1641
- path20 = path20.substring(colonIndex + 1);
1756
+ path21 = path21.substring(colonIndex + 1);
1642
1757
  }
1643
1758
  } else {
1644
- path20 = path20.replace(/^https?:\/\//, "");
1645
- const parts = path20.split("/");
1759
+ path21 = path21.replace(/^https?:\/\//, "");
1760
+ const parts = path21.split("/");
1646
1761
  if (parts.length > 1) {
1647
- path20 = parts.slice(1).join("/");
1762
+ path21 = parts.slice(1).join("/");
1648
1763
  }
1649
1764
  }
1650
- path20 = path20.replace(/\.git$/, "");
1651
- return path20;
1765
+ path21 = path21.replace(/\.git$/, "");
1766
+ return path21;
1652
1767
  }
1653
1768
  /**
1654
1769
  * 编码项目路径用于 API 请求
@@ -2667,7 +2782,7 @@ ${cleanedMilestones}`;
2667
2782
  function buildBreakdownPrompt(specContent) {
2668
2783
  return `Role: Senior Technical Lead and Agile Coach
2669
2784
 
2670
- Task: Break down the following feature spec into milestones and todo lists.
2785
+ Task: Break down the following feature spec into milestones with frontend, backend, and integration tasks.
2671
2786
 
2672
2787
  Context:
2673
2788
  - Read TECH_STACK.md for technology constraints
@@ -2683,13 +2798,18 @@ ${specContent}
2683
2798
  Output Requirements:
2684
2799
  1. Parse the existing spec content and identify technical requirements.
2685
2800
  2. Break it down into 2-5 milestones.
2686
- 3. Each milestone should have:
2687
- - Clear name and objective
2688
- - Estimated days (1-3 days per milestone)
2689
- - Todo list with 3-8 actionable items
2801
+ 3. Each milestone must have three sections:
2802
+ - **\u524D\u7AEF\u4EFB\u52A1**: Frontend tasks marked with [F] prefix
2803
+ - **\u540E\u7AEF\u4EFB\u52A1**: Backend tasks marked with [B] prefix, include API associations
2804
+ - **\u8054\u8C03\u4EFB\u52A1**: Integration tasks marked with [I] prefix, include dependencies
2690
2805
  4. Todo items should be:
2691
- - Concrete, specific, and testable.
2692
- - Independent as much as possible.
2806
+ - Concrete, specific, and testable
2807
+ - Independent as much as possible
2808
+
2809
+ Task Prefix Format:
2810
+ - Frontend: \`- [ ] [F] \u5177\u4F53\u7684\u524D\u7AEF\u4EFB\u52A1\u63CF\u8FF0\`
2811
+ - Backend: \`- [ ] [B] \u5177\u4F53\u7684\u540E\u7AEF\u4EFB\u52A1\u63CF\u8FF0 (\u5173\u8054 API: \`METHOD /api/path\`)\`
2812
+ - Integration: \`- [ ] [I] \u8054\u8C03\u4EFB\u52A1\u63CF\u8FF0 (\u4F9D\u8D56: F-x, B-y)\`
2693
2813
 
2694
2814
  IMPORTANT:
2695
2815
  - Output ONLY the "## \u91CC\u7A0B\u7891 (Milestones)" section.
@@ -2704,9 +2824,16 @@ IMPORTANT:
2704
2824
  **\u76EE\u6807**: [\u7B80\u77ED\u63CF\u8FF0\u8FD9\u4E2A\u91CC\u7A0B\u7891\u7684\u76EE\u6807]
2705
2825
  **\u9884\u4F30**: 2 \u5929
2706
2826
 
2707
- - [ ] Todo 1 - \u5177\u4F53\u53EF\u6267\u884C\u7684\u4EFB\u52A1
2708
- - [ ] Todo 2 - \u5177\u4F53\u53EF\u6267\u884C\u7684\u4EFB\u52A1
2709
- - [ ] Todo 3 - \u5177\u4F53\u53EF\u6267\u884C\u7684\u4EFB\u52A1
2827
+ **\u524D\u7AEF\u4EFB\u52A1**:
2828
+ - [ ] [F] \u524D\u7AEF\u4EFB\u52A1\u63CF\u8FF0 1
2829
+ - [ ] [F] \u524D\u7AEF\u4EFB\u52A1\u63CF\u8FF0 2
2830
+
2831
+ **\u540E\u7AEF\u4EFB\u52A1**:
2832
+ - [ ] [B] \u540E\u7AEF\u4EFB\u52A1\u63CF\u8FF0 1 (\u5173\u8054 API: \`POST /api/xxx\`)
2833
+ - [ ] [B] \u540E\u7AEF\u4EFB\u52A1\u63CF\u8FF0 2 (\u5173\u8054 API: \`GET /api/yyy\`)
2834
+
2835
+ **\u8054\u8C03\u4EFB\u52A1**:
2836
+ - [ ] [I] \u8054\u8C03\u4EFB\u52A1\u63CF\u8FF0 1 (\u4F9D\u8D56: F-1, B-1)
2710
2837
 
2711
2838
  ### Milestone 2: [\u91CC\u7A0B\u7891\u540D\u79F0]
2712
2839
  ...
@@ -2899,8 +3026,8 @@ async function selectMilestone(specFile) {
2899
3026
  logger.step("\u6B65\u9AA4 2/3: \u89E3\u6790 milestones...");
2900
3027
  logger.newLine();
2901
3028
  const specContent = await FileUtils.read(specFile);
2902
- const milestones = SpecUtils.parseMilestones(specContent);
2903
- if (milestones.length === 0) {
3029
+ const { enhanced, isEnhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);
3030
+ if (enhanced.length === 0) {
2904
3031
  logger.info("\u8BE5 spec \u5C1A\u672A\u62C6\u5206 milestones");
2905
3032
  const { breakdownNow } = await inquirer3.prompt([
2906
3033
  {
@@ -2918,19 +3045,32 @@ async function selectMilestone(specFile) {
2918
3045
  return "\u6574\u4E2A spec";
2919
3046
  }
2920
3047
  }
2921
- const choices = milestones.map((m, idx) => {
2922
- const isDone = m.completedCount === m.todos.length && m.todos.length > 0;
3048
+ const choices = enhanced.map((m, idx) => {
3049
+ const isDone = m.completedCount === m.totalCount && m.totalCount > 0;
2923
3050
  const statusIcon = isDone ? "\u2713" : m.completedCount > 0 ? "\u27F3" : "\u25CB";
2924
- const progress = `[${m.completedCount}/${m.todos.length}]`;
3051
+ const progress = `[${m.completedCount}/${m.totalCount}]`;
2925
3052
  const label = isDone ? `\u2713 ${m.title}` : `${statusIcon} ${progress} ${m.title}`;
3053
+ let detailInfo = `(${m.totalCount} \u4E2A\u4EFB\u52A1)`;
3054
+ if (isEnhanced) {
3055
+ const fCount = m.frontendTodos.filter((t) => !t.isCompleted).length;
3056
+ const bCount = m.backendTodos.filter((t) => !t.isCompleted).length;
3057
+ const iCount = m.integrationTodos.filter((t) => !t.isCompleted).length;
3058
+ const details = [];
3059
+ if (fCount > 0) details.push(`\u524D\u7AEF:${fCount}`);
3060
+ if (bCount > 0) details.push(`\u540E\u7AEF:${bCount}`);
3061
+ if (iCount > 0) details.push(`\u8054\u8C03:${iCount}`);
3062
+ if (details.length > 0) {
3063
+ detailInfo = `(${details.join(", ")} \u672A\u5B8C\u6210)`;
3064
+ }
3065
+ }
2926
3066
  return {
2927
- name: `${idx + 1}. ${label} (${m.todos.length} \u4E2A\u4EFB\u52A1)`,
3067
+ name: `${idx + 1}. ${label} ${detailInfo}`,
2928
3068
  value: m.title,
2929
3069
  short: m.title
2930
3070
  };
2931
3071
  });
2932
3072
  choices.push({
2933
- name: `${milestones.length + 1}. \u6574\u4E2A spec (\u5168\u90E8 milestones)`,
3073
+ name: `${enhanced.length + 1}. \u6574\u4E2A spec (\u5168\u90E8 milestones)`,
2934
3074
  value: "\u6574\u4E2A spec",
2935
3075
  short: "\u6574\u4E2A spec"
2936
3076
  });
@@ -2951,6 +3091,79 @@ async function selectTodo(specFile, milestone) {
2951
3091
  logger.newLine();
2952
3092
  logger.step("\u6B65\u9AA4 3/3: \u9009\u62E9 todo \u4EFB\u52A1...");
2953
3093
  logger.newLine();
3094
+ const specContent = await FileUtils.read(specFile);
3095
+ const { enhanced, isEnhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);
3096
+ const targetMilestone = enhanced.find((m) => m.title === milestone);
3097
+ if (!targetMilestone || !isEnhanced) {
3098
+ return await selectTodoSimple(specFile, milestone);
3099
+ }
3100
+ return await selectTodoEnhanced(targetMilestone);
3101
+ }
3102
+ async function selectTodoEnhanced(milestone) {
3103
+ const choices = [];
3104
+ if (milestone.frontendTodos.length > 0) {
3105
+ choices.push({ name: `\u2501\u2501 \u524D\u7AEF\u4EFB\u52A1 (${milestone.frontendTodos.length}) \u2501\u2501`, disabled: true });
3106
+ milestone.frontendTodos.forEach((todo2, idx) => {
3107
+ const icon = todo2.isCompleted ? "[x]" : "[ ]";
3108
+ choices.push({
3109
+ name: ` [F] ${icon} ${todo2.content}`,
3110
+ value: todo2.content,
3111
+ short: `[F] ${todo2.content}`
3112
+ });
3113
+ });
3114
+ }
3115
+ if (milestone.backendTodos.length > 0) {
3116
+ choices.push({ name: `\u2501\u2501 \u540E\u7AEF\u4EFB\u52A1 (${milestone.backendTodos.length}) \u2501\u2501`, disabled: true });
3117
+ milestone.backendTodos.forEach((todo2, idx) => {
3118
+ const icon = todo2.isCompleted ? "[x]" : "[ ]";
3119
+ const apiInfo = todo2.apiAssociation ? ` (${todo2.apiAssociation})` : "";
3120
+ choices.push({
3121
+ name: ` [B] ${icon} ${todo2.content}${apiInfo}`,
3122
+ value: todo2.content,
3123
+ short: `[B] ${todo2.content}`
3124
+ });
3125
+ });
3126
+ }
3127
+ if (milestone.integrationTodos.length > 0) {
3128
+ choices.push({ name: `\u2501\u2501 \u8054\u8C03\u4EFB\u52A1 (${milestone.integrationTodos.length}) \u2501\u2501`, disabled: true });
3129
+ milestone.integrationTodos.forEach((todo2, idx) => {
3130
+ const icon = todo2.isCompleted ? "[x]" : "[ ]";
3131
+ const depsInfo = todo2.dependencies ? ` (\u4F9D\u8D56: ${todo2.dependencies.join(", ")})` : "";
3132
+ choices.push({
3133
+ name: ` [I] ${icon} ${todo2.content}${depsInfo}`,
3134
+ value: todo2.content,
3135
+ short: `[I] ${todo2.content}`
3136
+ });
3137
+ });
3138
+ }
3139
+ if (milestone.generalTodos.length > 0) {
3140
+ choices.push({ name: `\u2501\u2501 \u901A\u7528\u4EFB\u52A1 (${milestone.generalTodos.length}) \u2501\u2501`, disabled: true });
3141
+ milestone.generalTodos.forEach((todo2, idx) => {
3142
+ const icon = todo2.isCompleted ? "[x]" : "[ ]";
3143
+ choices.push({
3144
+ name: ` ${icon} ${todo2.content}`,
3145
+ value: todo2.content,
3146
+ short: todo2.content
3147
+ });
3148
+ });
3149
+ }
3150
+ choices.push({ name: "\u2501\u2501 \u5176\u4ED6 \u2501\u2501", disabled: true });
3151
+ choices.push({
3152
+ name: `\u5168\u90E8\u4EFB\u52A1 (\u6574\u4E2A milestone)`,
3153
+ value: "\u5168\u90E8\u4EFB\u52A1",
3154
+ short: "\u5168\u90E8\u4EFB\u52A1"
3155
+ });
3156
+ const { todo } = await inquirer3.prompt([
3157
+ {
3158
+ type: "list",
3159
+ name: "todo",
3160
+ message: "\u9009\u62E9 todo \u4EFB\u52A1:",
3161
+ choices
3162
+ }
3163
+ ]);
3164
+ return todo;
3165
+ }
3166
+ async function selectTodoSimple(specFile, milestone) {
2954
3167
  const specContent = await FileUtils.read(specFile);
2955
3168
  const milestones = SpecUtils.parseMilestones(specContent);
2956
3169
  const targetMilestone = milestones.find((m) => m.title === milestone);
@@ -3178,10 +3391,14 @@ async function askAndUpdateSpecStatus(specFile, milestone, todo) {
3178
3391
  break;
3179
3392
  }
3180
3393
  if (todo !== "\u5168\u90E8\u529F\u80FD" && todo !== "\u5168\u90E8\u4EFB\u52A1") {
3181
- const todoMatch = line.match(/^-\s+\[[ x ]\]\s*(.+)/);
3182
- if (todoMatch && todoMatch[1].trim() === todo) {
3183
- targetTodoIndex = i;
3184
- break;
3394
+ const todoMatch = line.match(/^-\s+\[ \]\s*(\[[FBIN]\]\s*)?(.+)/);
3395
+ if (todoMatch) {
3396
+ const todoContent = todoMatch[2].trim();
3397
+ const cleanContent = todoContent.replace(/\s*\(关联 API:\s*`[^`]+`\)/, "").replace(/\s*\(依赖:\s*[^)]+\)/, "").trim();
3398
+ if (cleanContent === todo) {
3399
+ targetTodoIndex = i;
3400
+ break;
3401
+ }
3185
3402
  }
3186
3403
  }
3187
3404
  }
@@ -4467,8 +4684,597 @@ Temporary solution: ${answers.solution}`
4467
4684
  }
4468
4685
  });
4469
4686
 
4470
- // src/commands/lint.ts
4687
+ // src/commands/accept.ts
4471
4688
  import { Command as Command7 } from "commander";
4689
+ import inquirer6 from "inquirer";
4690
+ import path13 from "path";
4691
+ async function selectSpec2(defaultSpec) {
4692
+ logger.step("\u6B65\u9AA4 1/4: \u9009\u62E9 spec \u6587\u4EF6...");
4693
+ logger.newLine();
4694
+ const specDir = "docs/specs";
4695
+ const exists = await FileUtils.exists(specDir);
4696
+ if (!exists) {
4697
+ throw new Error("docs/specs \u76EE\u5F55\u4E0D\u5B58\u5728");
4698
+ }
4699
+ const files = await FileUtils.findFiles("*.md", specDir);
4700
+ const specFiles = files.filter((f) => !f.includes("template"));
4701
+ if (specFiles.length === 0) {
4702
+ throw new Error("\u672A\u627E\u5230 spec \u6587\u4EF6");
4703
+ }
4704
+ if (defaultSpec) {
4705
+ const fullPath = defaultSpec.startsWith("docs/specs/") ? defaultSpec : path13.join(specDir, defaultSpec);
4706
+ const exists2 = await FileUtils.exists(fullPath);
4707
+ if (!exists2) {
4708
+ throw new Error(`Spec \u6587\u4EF6\u4E0D\u5B58\u5728: ${defaultSpec}`);
4709
+ }
4710
+ logger.success(`\u5DF2\u9009\u62E9: ${fullPath}`);
4711
+ return fullPath;
4712
+ }
4713
+ const specs = [];
4714
+ for (const file of specFiles) {
4715
+ const fullPath = path13.join(specDir, file);
4716
+ const content = await FileUtils.read(fullPath);
4717
+ const status = SpecUtils.parseSpecStatus(content);
4718
+ specs.push({ file: fullPath, name: file, status });
4719
+ }
4720
+ const activeSpecs = specs.filter(
4721
+ (s) => s.status === "\u5DF2\u62C6\u5206" || s.status === "\u8FDB\u884C\u4E2D" || s.status === "\u5DF2\u5B8C\u6210"
4722
+ );
4723
+ if (activeSpecs.length === 0) {
4724
+ logger.warn("\u6CA1\u6709\u53EF\u9A8C\u6536\u7684 spec \u6587\u4EF6");
4725
+ const { continueAnyway } = await inquirer6.prompt([
4726
+ {
4727
+ type: "confirm",
4728
+ name: "continueAnyway",
4729
+ message: "\u662F\u5426\u7EE7\u7EED\u67E5\u770B\u6240\u6709 spec?",
4730
+ default: true
4731
+ }
4732
+ ]);
4733
+ if (!continueAnyway) {
4734
+ process.exit(0);
4735
+ }
4736
+ }
4737
+ const targetSpecs = activeSpecs.length > 0 ? activeSpecs : specs;
4738
+ const choices = targetSpecs.map((spec) => ({
4739
+ name: `[${spec.status}] ${spec.name}`,
4740
+ value: spec.file,
4741
+ short: spec.name
4742
+ }));
4743
+ const { selectedFile } = await inquirer6.prompt([
4744
+ {
4745
+ type: "list",
4746
+ name: "selectedFile",
4747
+ message: "\u9009\u62E9\u8981\u9A8C\u6536\u7684 spec:",
4748
+ choices
4749
+ }
4750
+ ]);
4751
+ logger.success(`\u5DF2\u9009\u62E9: ${selectedFile}`);
4752
+ return selectedFile;
4753
+ }
4754
+ async function selectMilestone2(specFile) {
4755
+ logger.newLine();
4756
+ logger.step("\u6B65\u9AA4 2/4: \u89E3\u6790 milestones...");
4757
+ logger.newLine();
4758
+ const specContent = await FileUtils.read(specFile);
4759
+ const { enhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);
4760
+ if (enhanced.length === 0) {
4761
+ throw new Error("\u8BE5 spec \u5C1A\u672A\u62C6\u5206 milestones\uFF0C\u65E0\u6CD5\u8FDB\u884C\u9A8C\u6536");
4762
+ }
4763
+ const choices = enhanced.map((m, idx) => {
4764
+ const isDone = m.completedCount === m.totalCount;
4765
+ const statusIcon = isDone ? "\u2713" : m.completedCount > 0 ? "\u27F3" : "\u25CB";
4766
+ const progress = `[${m.completedCount}/${m.totalCount}]`;
4767
+ return {
4768
+ name: `${idx + 1}. ${statusIcon} ${progress} ${m.title}`,
4769
+ value: m.title,
4770
+ short: m.title
4771
+ };
4772
+ });
4773
+ const { milestone } = await inquirer6.prompt([
4774
+ {
4775
+ type: "list",
4776
+ name: "milestone",
4777
+ message: "\u9009\u62E9\u8981\u9A8C\u6536\u7684 milestone:",
4778
+ choices
4779
+ }
4780
+ ]);
4781
+ return milestone;
4782
+ }
4783
+ async function runAcceptanceCheck(specFile, milestone) {
4784
+ logger.newLine();
4785
+ logger.step("\u6B65\u9AA4 3/4: \u6267\u884C\u9A8C\u6536\u68C0\u67E5...");
4786
+ logger.newLine();
4787
+ const specContent = await FileUtils.read(specFile);
4788
+ const { enhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specFile);
4789
+ const targetMilestone = enhanced.find((m) => m.title === milestone);
4790
+ if (!targetMilestone) {
4791
+ throw new Error(`\u672A\u627E\u5230 milestone: ${milestone}`);
4792
+ }
4793
+ const result = {
4794
+ specFile,
4795
+ milestone,
4796
+ checkTime: (/* @__PURE__ */ new Date()).toLocaleString("zh-CN"),
4797
+ frontendTasks: { total: 0, completed: 0, items: [] },
4798
+ backendTasks: { total: 0, completed: 0, items: [] },
4799
+ apiVerification: { total: 0, verified: 0, items: [] },
4800
+ integrationTasks: { total: 0, completed: 0, items: [] },
4801
+ issues: []
4802
+ };
4803
+ logger.info("\u68C0\u67E5\u524D\u7AEF\u4EFB\u52A1...");
4804
+ for (const todo of targetMilestone.frontendTodos) {
4805
+ const checkResult = await checkFrontendTask(todo);
4806
+ result.frontendTasks.items.push(checkResult);
4807
+ if (checkResult.status === "pass") {
4808
+ result.frontendTasks.completed++;
4809
+ }
4810
+ result.frontendTasks.total++;
4811
+ const icon = checkResult.status === "pass" ? "\u2713" : checkResult.status === "fail" ? "\u2717" : "\u25CB";
4812
+ logger.info(` ${icon} [F] ${todo.content}${checkResult.filePath ? ` - ${checkResult.filePath}` : ""}`);
4813
+ }
4814
+ logger.info("\u68C0\u67E5\u540E\u7AEF\u4EFB\u52A1...");
4815
+ for (const todo of targetMilestone.backendTodos) {
4816
+ const checkResult = await checkBackendTask(todo);
4817
+ result.backendTasks.items.push(checkResult);
4818
+ if (checkResult.status === "pass") {
4819
+ result.backendTasks.completed++;
4820
+ }
4821
+ result.backendTasks.total++;
4822
+ const icon = checkResult.status === "pass" ? "\u2713" : checkResult.status === "fail" ? "\u2717" : "\u25CB";
4823
+ logger.info(` ${icon} [B] ${todo.content}${checkResult.filePath ? ` - ${checkResult.filePath}` : ""}`);
4824
+ }
4825
+ logger.info("\u9A8C\u8BC1 API \u5B9E\u73B0...");
4826
+ for (const todo of targetMilestone.backendTodos) {
4827
+ if (todo.apiAssociation) {
4828
+ const checkResult = await verifyApiImplementation(todo);
4829
+ result.apiVerification.items.push(checkResult);
4830
+ if (checkResult.status === "pass") {
4831
+ result.apiVerification.verified++;
4832
+ }
4833
+ result.apiVerification.total++;
4834
+ const icon = checkResult.status === "pass" ? "\u2713" : checkResult.status === "fail" ? "\u2717" : "\u25CB";
4835
+ logger.info(` ${icon} ${todo.apiAssociation}${checkResult.filePath ? ` - ${checkResult.filePath}` : ""}`);
4836
+ }
4837
+ }
4838
+ logger.info("\u68C0\u67E5\u8054\u8C03\u4EFB\u52A1...");
4839
+ for (const todo of targetMilestone.integrationTodos) {
4840
+ const checkResult = await checkIntegrationTask(todo);
4841
+ result.integrationTasks.items.push(checkResult);
4842
+ if (checkResult.status === "pass") {
4843
+ result.integrationTasks.completed++;
4844
+ }
4845
+ result.integrationTasks.total++;
4846
+ const icon = checkResult.status === "pass" ? "\u2713" : checkResult.status === "fail" ? "\u2717" : "\u25CB";
4847
+ logger.info(` ${icon} [I] ${todo.content}`);
4848
+ }
4849
+ return result;
4850
+ }
4851
+ async function checkFrontendTask(todo) {
4852
+ const frontendPaths = [
4853
+ `frontend/src/pages/${todo.content}.tsx`,
4854
+ `frontend/src/components/${todo.content}.tsx`,
4855
+ `frontend/src/components/${todo.content.replace(/\s+/g, "")}.tsx`,
4856
+ `frontend/src/views/${todo.content}.vue`,
4857
+ `frontend/src/components/${todo.content}.vue`
4858
+ ];
4859
+ for (const fp of frontendPaths) {
4860
+ if (await FileUtils.exists(fp)) {
4861
+ return {
4862
+ description: `[F] ${todo.content}`,
4863
+ status: "pass",
4864
+ details: "\u524D\u7AEF\u4EE3\u7801\u5B58\u5728",
4865
+ filePath: fp
4866
+ };
4867
+ }
4868
+ }
4869
+ const pathMatch = todo.content.match(/\s*-\s*(.+?\.(tsx|vue|js|jsx))\s*/);
4870
+ if (pathMatch) {
4871
+ const filePath = pathMatch[1];
4872
+ if (await FileUtils.exists(filePath)) {
4873
+ return {
4874
+ description: `[F] ${todo.content}`,
4875
+ status: "pass",
4876
+ details: "\u524D\u7AEF\u4EE3\u7801\u5B58\u5728",
4877
+ filePath
4878
+ };
4879
+ }
4880
+ }
4881
+ return {
4882
+ description: `[F] ${todo.content}`,
4883
+ status: "fail",
4884
+ details: "\u524D\u7AEF\u4EE3\u7801\u4E0D\u5B58\u5728\u6216\u8DEF\u5F84\u65E0\u6CD5\u9A8C\u8BC1"
4885
+ };
4886
+ }
4887
+ async function checkBackendTask(todo) {
4888
+ const backendPaths = [
4889
+ `backend/src/main/java/${todo.content.replace(/\s+/g, "/")}.java`,
4890
+ `backend/src/${todo.content.toLowerCase().replace(/\s+/g, "/")}.java`
4891
+ ];
4892
+ for (const fp of backendPaths) {
4893
+ if (await FileUtils.exists(fp)) {
4894
+ return {
4895
+ description: `[B] ${todo.content}`,
4896
+ status: "pass",
4897
+ details: "\u540E\u7AEF\u4EE3\u7801\u5B58\u5728",
4898
+ filePath: fp
4899
+ };
4900
+ }
4901
+ }
4902
+ const pathMatch = todo.content.match(/\s*-\s*(.+?\.(java|kt|py|go))\s*/);
4903
+ if (pathMatch) {
4904
+ const filePath = pathMatch[1];
4905
+ if (await FileUtils.exists(filePath)) {
4906
+ return {
4907
+ description: `[B] ${todo.content}`,
4908
+ status: "pass",
4909
+ details: "\u540E\u7AEF\u4EE3\u7801\u5B58\u5728",
4910
+ filePath
4911
+ };
4912
+ }
4913
+ }
4914
+ return {
4915
+ description: `[B] ${todo.content}`,
4916
+ status: "fail",
4917
+ details: "\u540E\u7AEF\u4EE3\u7801\u4E0D\u5B58\u5728\u6216\u8DEF\u5F84\u65E0\u6CD5\u9A8C\u8BC1"
4918
+ };
4919
+ }
4920
+ async function verifyApiImplementation(todo) {
4921
+ if (!todo.apiAssociation) {
4922
+ return {
4923
+ description: todo.apiAssociation || "API \u9A8C\u8BC1",
4924
+ status: "pending",
4925
+ details: "\u65E0 API \u5173\u8054\u4FE1\u606F"
4926
+ };
4927
+ }
4928
+ const apiMatch = todo.apiAssociation.match(/^(GET|POST|PUT|DELETE|PATCH)\s+\/(.+)$/);
4929
+ if (!apiMatch) {
4930
+ return {
4931
+ description: todo.apiAssociation,
4932
+ status: "pending",
4933
+ details: "\u65E0\u6CD5\u89E3\u6790 API \u683C\u5F0F"
4934
+ };
4935
+ }
4936
+ const method = apiMatch[1];
4937
+ const apiPath = apiMatch[2];
4938
+ const controllerPaths = [
4939
+ `backend/src/main/java/**/*Controller.java`,
4940
+ `backend/src/**/*Controller.java`
4941
+ ];
4942
+ const controllerFiles = await FileUtils.findFiles("**/*Controller.java", "backend/src");
4943
+ for (const cf of controllerFiles) {
4944
+ const content = await FileUtils.read(cf);
4945
+ if (content.includes(apiPath) || content.includes(`"${apiPath}"`)) {
4946
+ const methodAnnotations = {
4947
+ GET: ["@GetMapping", "@RequestMapping(method = RequestMethod.GET)"],
4948
+ POST: ["@PostMapping", "@RequestMapping(method = RequestMethod.POST)"],
4949
+ PUT: ["@PutMapping", "@RequestMapping(method = RequestMethod.PUT)"],
4950
+ DELETE: ["@DeleteMapping", "@RequestMapping(method = RequestMethod.DELETE)"],
4951
+ PATCH: ["@PatchMapping", "@RequestMapping(method = RequestMethod.PATCH)"]
4952
+ };
4953
+ for (const annotation of methodAnnotations[method] || []) {
4954
+ if (content.includes(annotation)) {
4955
+ return {
4956
+ description: todo.apiAssociation,
4957
+ status: "pass",
4958
+ details: "API Controller \u5B9E\u73B0\u5B58\u5728",
4959
+ filePath: cf
4960
+ };
4961
+ }
4962
+ }
4963
+ }
4964
+ }
4965
+ return {
4966
+ description: todo.apiAssociation,
4967
+ status: "fail",
4968
+ details: "API Controller \u672A\u5B9E\u73B0"
4969
+ };
4970
+ }
4971
+ async function checkIntegrationTask(todo) {
4972
+ const integrationEvidence = [
4973
+ "**/*integration*.test.*",
4974
+ "**/*e2e*.test.*",
4975
+ "**/*IT.java",
4976
+ "docs/integration-test-results.md",
4977
+ "docs/session-logs/**"
4978
+ ];
4979
+ const sessionDir = "docs/sessions";
4980
+ if (await FileUtils.exists(sessionDir)) {
4981
+ const sessionFiles = await FileUtils.findFiles("*.md", sessionDir);
4982
+ const hasRecentSession = sessionFiles.some(
4983
+ (sf) => sf.includes("integration") || sf.includes("\u8054\u8C03")
4984
+ );
4985
+ if (hasRecentSession) {
4986
+ return {
4987
+ description: `[I] ${todo.content}`,
4988
+ status: "pass",
4989
+ details: "\u8054\u8C03\u8BC1\u636E\u5B58\u5728\uFF08session \u65E5\u5FD7\uFF09"
4990
+ };
4991
+ }
4992
+ }
4993
+ return {
4994
+ description: `[I] ${todo.content}`,
4995
+ status: "pending",
4996
+ details: "\u5EFA\u8BAE\u4EBA\u5DE5\u9A8C\u8BC1\u8054\u8C03\u7ED3\u679C"
4997
+ };
4998
+ }
4999
+ async function generateAcceptanceReport(result) {
5000
+ logger.newLine();
5001
+ logger.step("\u6B65\u9AA4 4/4: \u751F\u6210\u9A8C\u6536\u62A5\u544A...");
5002
+ logger.newLine();
5003
+ const reportDir = "docs/acceptance-reports";
5004
+ await FileUtils.ensureDir(reportDir);
5005
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5006
+ const specName = path13.basename(result.specFile, ".md");
5007
+ const milestoneSafe = result.milestone.replace(/[^a-zA-Z0-9]/g, "-");
5008
+ const reportFile = path13.join(reportDir, `${timestamp}_${specName}_${milestoneSafe}.md`);
5009
+ const report = generateMarkdownReport(result);
5010
+ await FileUtils.write(reportFile, report);
5011
+ logger.success(`\u9A8C\u6536\u62A5\u544A\u5DF2\u751F\u6210: ${reportFile}`);
5012
+ logger.newLine();
5013
+ console.log(generateConsoleReport(result));
5014
+ }
5015
+ function generateMarkdownReport(result) {
5016
+ const lines = [];
5017
+ lines.push("# \u9A8C\u6536\u62A5\u544A");
5018
+ lines.push("");
5019
+ lines.push(`**Spec \u6587\u4EF6**: ${result.specFile}`);
5020
+ lines.push(`**Milestone**: ${result.milestone}`);
5021
+ lines.push(`**\u9A8C\u6536\u65F6\u95F4**: ${result.checkTime}`);
5022
+ lines.push("");
5023
+ lines.push("## \u68C0\u67E5\u7ED3\u679C\u6C47\u603B");
5024
+ lines.push("");
5025
+ lines.push("| \u68C0\u67E5\u9879 | \u72B6\u6001 |");
5026
+ lines.push("|--------|------|");
5027
+ lines.push(
5028
+ `| \u524D\u7AEF\u4EFB\u52A1 | ${result.frontendTasks.completed}/${result.frontendTasks.total} \u5B8C\u6210 |`
5029
+ );
5030
+ lines.push(
5031
+ `| \u540E\u7AEF\u4EFB\u52A1 | ${result.backendTasks.completed}/${result.backendTasks.total} \u5B8C\u6210 |`
5032
+ );
5033
+ lines.push(`| API \u9A8C\u8BC1 | ${result.apiVerification.verified}/${result.apiVerification.total} \u5B9E\u73B0 |`);
5034
+ lines.push(
5035
+ `| \u8054\u8C03\u4EFB\u52A1 | ${result.integrationTasks.completed}/${result.integrationTasks.total} \u5B8C\u6210 |`
5036
+ );
5037
+ lines.push("");
5038
+ lines.push("## \u8BE6\u7EC6\u8BB0\u5F55");
5039
+ lines.push("");
5040
+ lines.push("### \u524D\u7AEF\u4EFB\u52A1");
5041
+ lines.push("");
5042
+ for (const item of result.frontendTasks.items) {
5043
+ const icon = item.status === "pass" ? "\u2713" : item.status === "fail" ? "\u2717" : "\u25CB";
5044
+ lines.push(`- ${icon} ${item.description} - ${item.details || ""} ${item.filePath ? `(\`${item.filePath}\`)` : ""}`);
5045
+ }
5046
+ lines.push("");
5047
+ lines.push("### \u540E\u7AEF\u4EFB\u52A1");
5048
+ lines.push("");
5049
+ for (const item of result.backendTasks.items) {
5050
+ const icon = item.status === "pass" ? "\u2713" : item.status === "fail" ? "\u2717" : "\u25CB";
5051
+ lines.push(`- ${icon} ${item.description} - ${item.details || ""} ${item.filePath ? `(\`${item.filePath}\`)` : ""}`);
5052
+ }
5053
+ lines.push("");
5054
+ lines.push("### API \u9A8C\u8BC1");
5055
+ lines.push("");
5056
+ for (const item of result.apiVerification.items) {
5057
+ const icon = item.status === "pass" ? "\u2713" : item.status === "fail" ? "\u2717" : "\u25CB";
5058
+ lines.push(`- ${icon} ${item.description} - ${item.details || ""} ${item.filePath ? `(\`${item.filePath}\`)` : ""}`);
5059
+ }
5060
+ lines.push("");
5061
+ lines.push("### \u8054\u8C03\u4EFB\u52A1");
5062
+ lines.push("");
5063
+ for (const item of result.integrationTasks.items) {
5064
+ const icon = item.status === "pass" ? "\u2713" : item.status === "fail" ? "\u2717" : "\u26A0";
5065
+ lines.push(`- ${icon} ${item.description} - ${item.details || ""}`);
5066
+ }
5067
+ lines.push("");
5068
+ if (result.issues.length > 0) {
5069
+ lines.push("## \u53D1\u73B0\u7684\u95EE\u9898");
5070
+ lines.push("");
5071
+ lines.push("| \u95EE\u9898 | \u7C7B\u578B | \u4E25\u91CD\u7A0B\u5EA6 | \u72B6\u6001 |");
5072
+ lines.push("|------|------|---------|------|");
5073
+ for (const issue of result.issues) {
5074
+ lines.push(`| ${issue.title} | ${issue.type} | ${issue.severity} | ${issue.status} |`);
5075
+ }
5076
+ lines.push("");
5077
+ lines.push("**\u64CD\u4F5C**:");
5078
+ lines.push(`- \u8FD0\u884C \`team-cli bugfix ${result.specFile}\` \u67E5\u770B\u8BE6\u60C5`);
5079
+ lines.push("- \u6216\u8FD0\u884C `team-cli hotfix` \u7ACB\u5373\u4FEE\u590D");
5080
+ lines.push("");
5081
+ }
5082
+ lines.push("## \u4E0B\u4E00\u6B65\u5EFA\u8BAE");
5083
+ lines.push("");
5084
+ if (result.issues.length > 0) {
5085
+ lines.push("- [ ] \u4FEE\u590D\u53D1\u73B0\u7684\u95EE\u9898");
5086
+ }
5087
+ lines.push("- [ ] \u8FD0\u884C `team-cli dev` \u7EE7\u7EED\u5F00\u53D1");
5088
+ lines.push("- [ ] \u8FD0\u884C `team-cli accept` \u91CD\u65B0\u9A8C\u6536");
5089
+ lines.push("");
5090
+ return lines.join("\n");
5091
+ }
5092
+ function generateConsoleReport(result) {
5093
+ const lines = [];
5094
+ lines.push("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
5095
+ lines.push("\u2502 \u9A8C \u6536 \u7ED3 \u679C \u6458 \u8981 \u2502");
5096
+ lines.push("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
5097
+ lines.push(`\u2502 Spec: ${result.specFile.padEnd(40)}\u2502`);
5098
+ lines.push(`\u2502 Milestone: ${result.milestone.padEnd(37)}\u2502`);
5099
+ lines.push("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
5100
+ lines.push(
5101
+ `\u2502 \u524D\u7AEF\u4EFB\u52A1: ${result.frontendTasks.completed}/${result.frontendTasks.total} \u5B8C\u6210`.padEnd(47) + "\u2502"
5102
+ );
5103
+ lines.push(
5104
+ `\u2502 \u540E\u7AEF\u4EFB\u52A1: ${result.backendTasks.completed}/${result.backendTasks.total} \u5B8C\u6210`.padEnd(47) + "\u2502"
5105
+ );
5106
+ lines.push(
5107
+ `\u2502 API \u9A8C\u8BC1: ${result.apiVerification.verified}/${result.apiVerification.total} \u5B9E\u73B0`.padEnd(47) + "\u2502"
5108
+ );
5109
+ lines.push(
5110
+ `\u2502 \u8054\u8C03\u4EFB\u52A1: ${result.integrationTasks.completed}/${result.integrationTasks.total} \u5B8C\u6210`.padEnd(47) + "\u2502"
5111
+ );
5112
+ lines.push("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
5113
+ const totalIssues = result.issues.length;
5114
+ if (totalIssues > 0) {
5115
+ lines.push(`\u2502 \u26A0 \u53D1\u73B0\u95EE\u9898: ${totalIssues} \u4E2A`.padEnd(47) + "\u2502");
5116
+ } else {
5117
+ lines.push(`\u2502 \u2713 \u9A8C\u6536\u901A\u8FC7`.padEnd(47) + "\u2502");
5118
+ }
5119
+ lines.push("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
5120
+ return lines.join("\n");
5121
+ }
5122
+ async function handleIssues(result) {
5123
+ logger.newLine();
5124
+ logger.warn(`\u53D1\u73B0 ${result.issues.length} \u4E2A\u95EE\u9898\u9700\u8981\u5904\u7406`);
5125
+ const bugfixDir = "docs/bugfixes";
5126
+ await FileUtils.ensureDir(bugfixDir);
5127
+ for (const issue of result.issues) {
5128
+ const bugfixFile = path13.join(
5129
+ bugfixDir,
5130
+ `${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}_${issue.id}.md`
5131
+ );
5132
+ const bugfixContent = generateBugfixContent(result, issue);
5133
+ await FileUtils.write(bugfixFile, bugfixContent);
5134
+ logger.info(` \u5DF2\u521B\u5EFA Bugfix \u8BB0\u5F55: ${bugfixFile}`);
5135
+ }
5136
+ logger.newLine();
5137
+ const { fixNow } = await inquirer6.prompt([
5138
+ {
5139
+ type: "confirm",
5140
+ name: "fixNow",
5141
+ message: "\u662F\u5426\u7ACB\u5373\u4FEE\u590D\u53D1\u73B0\u7684\u95EE\u9898?",
5142
+ default: false
5143
+ }
5144
+ ]);
5145
+ if (fixNow) {
5146
+ logger.info("\u8BF7\u8FD0\u884C `team-cli hotfix` \u7ACB\u5373\u4FEE\u590D\u95EE\u9898");
5147
+ } else {
5148
+ logger.info(`\u95EE\u9898\u8BB0\u5F55\u5DF2\u4FDD\u5B58\u5230 ${bugfixDir} \u76EE\u5F55`);
5149
+ logger.info("\u8FD0\u884C `team-cli bugfix` \u67E5\u770B\u6240\u6709\u95EE\u9898\u8BB0\u5F55");
5150
+ }
5151
+ }
5152
+ function generateBugfixContent(result, issue) {
5153
+ const lines = [];
5154
+ lines.push("# Bugfix \u8BB0\u5F55");
5155
+ lines.push("");
5156
+ lines.push(`**ID**: ${issue.id}`);
5157
+ lines.push(`**\u521B\u5EFA\u65F6\u95F4**: ${issue.createdAt}`);
5158
+ lines.push(`**\u72B6\u6001**: ${issue.status}`);
5159
+ lines.push("");
5160
+ lines.push("## \u95EE\u9898\u63CF\u8FF0");
5161
+ lines.push("");
5162
+ lines.push(issue.description);
5163
+ lines.push("");
5164
+ lines.push("## \u6240\u5C5E\u8303\u56F4");
5165
+ lines.push("");
5166
+ lines.push(`- Spec: ${result.specFile}`);
5167
+ lines.push(`- Milestone: ${result.milestone}`);
5168
+ if (issue.todo) {
5169
+ lines.push(`- Todo: ${issue.todo}`);
5170
+ }
5171
+ lines.push("");
5172
+ lines.push("## \u4E25\u91CD\u7A0B\u5EA6");
5173
+ lines.push("");
5174
+ lines.push(`- ${issue.severity.toUpperCase()}`);
5175
+ lines.push("");
5176
+ lines.push("## \u95EE\u9898\u7C7B\u578B");
5177
+ lines.push("");
5178
+ lines.push(`- ${issue.type}`);
5179
+ lines.push("");
5180
+ lines.push("## \u89E3\u51B3\u65B9\u6848");
5181
+ lines.push("");
5182
+ lines.push("<!-- TODO: \u586B\u5199\u89E3\u51B3\u65B9\u6848 -->");
5183
+ lines.push("");
5184
+ lines.push("## \u9A8C\u8BC1\u6B65\u9AA4");
5185
+ lines.push("");
5186
+ lines.push("1. ");
5187
+ lines.push("2. ");
5188
+ lines.push("3. ");
5189
+ lines.push("");
5190
+ return lines.join("\n");
5191
+ }
5192
+ async function syncSpecStatus(specFile, result) {
5193
+ const content = await FileUtils.read(specFile);
5194
+ const lines = content.split("\n");
5195
+ let inTargetMilestone = false;
5196
+ let milestoneIndex = -1;
5197
+ for (let i = 0; i < lines.length; i++) {
5198
+ const line = lines[i];
5199
+ if (line.includes(result.milestone)) {
5200
+ inTargetMilestone = true;
5201
+ milestoneIndex = i;
5202
+ continue;
5203
+ }
5204
+ if (inTargetMilestone && line.match(/^###\s+Milestone/)) {
5205
+ break;
5206
+ }
5207
+ }
5208
+ if (milestoneIndex !== -1) {
5209
+ let completedTasks = 0;
5210
+ let totalTasks = 0;
5211
+ for (let i = milestoneIndex + 1; i < lines.length; i++) {
5212
+ const line = lines[i];
5213
+ if (line.match(/^###\s+Milestone/)) {
5214
+ break;
5215
+ }
5216
+ if (line.match(/^-\s+\[/)) {
5217
+ totalTasks++;
5218
+ if (line.match(/^-\s+\[x\]/)) {
5219
+ completedTasks++;
5220
+ }
5221
+ }
5222
+ }
5223
+ const progressLine = `${result.milestone} [${completedTasks}/${totalTasks}]`;
5224
+ const linesBefore = lines.slice(0, milestoneIndex);
5225
+ const linesAfter = lines.slice(milestoneIndex + 1);
5226
+ if (!lines[milestoneIndex].includes(`[${completedTasks}/${totalTasks}]`)) {
5227
+ const updatedMilestoneLine = lines[milestoneIndex].replace(
5228
+ /(\s*\[\d+\/\d+\])?$/,
5229
+ ` [${completedTasks}/${totalTasks}]`
5230
+ );
5231
+ lines[milestoneIndex] = updatedMilestoneLine;
5232
+ await FileUtils.write(specFile, lines.join("\n"));
5233
+ logger.info(`\u5DF2\u540C\u6B65\u91CC\u7A0B\u7891\u8FDB\u5EA6: [${completedTasks}/${totalTasks}]`);
5234
+ }
5235
+ }
5236
+ }
5237
+ var acceptCommand;
5238
+ var init_accept = __esm({
5239
+ "src/commands/accept.ts"() {
5240
+ "use strict";
5241
+ init_esm_shims();
5242
+ init_utils();
5243
+ init_logger();
5244
+ acceptCommand = new Command7("accept").argument("[spec-file]", "Spec \u6587\u4EF6\u8DEF\u5F84").description("\u9A8C\u6536\u529F\u80FD - \u8D70\u67E5\u6240\u6709\u9700\u6C42\uFF0C\u9A8C\u8BC1\u8054\u8C03\u662F\u5426\u5B8C\u6210").action(async (specFile) => {
5245
+ try {
5246
+ logger.header("\u9A8C\u6536\u6A21\u5F0F");
5247
+ logger.newLine();
5248
+ const hasTechStack = await FileUtils.exists("TECH_STACK.md");
5249
+ if (!hasTechStack) {
5250
+ logger.error("\u5F53\u524D\u76EE\u5F55\u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684 team-cli \u9879\u76EE");
5251
+ logger.info("\u8BF7\u5148\u8FD0\u884C 'team-cli init <project-name>' \u6216\u5207\u6362\u5230\u9879\u76EE\u76EE\u5F55");
5252
+ process.exit(1);
5253
+ }
5254
+ logger.success("\u68C0\u6D4B\u5230\u9879\u76EE\u4E0A\u4E0B\u6587");
5255
+ const selectedSpec = await selectSpec2(specFile);
5256
+ const selectedMilestone = await selectMilestone2(selectedSpec);
5257
+ const result = await runAcceptanceCheck(selectedSpec, selectedMilestone);
5258
+ await generateAcceptanceReport(result);
5259
+ if (result.issues.length > 0) {
5260
+ await handleIssues(result);
5261
+ }
5262
+ await syncSpecStatus(selectedSpec, result);
5263
+ logger.header("\u9A8C\u6536\u5B8C\u6210!");
5264
+ logger.newLine();
5265
+ } catch (error) {
5266
+ logger.error(`\u9A8C\u6536\u5931\u8D25: ${error.message}`);
5267
+ if (process.env.DEBUG) {
5268
+ console.error(error);
5269
+ }
5270
+ process.exit(1);
5271
+ }
5272
+ });
5273
+ }
5274
+ });
5275
+
5276
+ // src/commands/lint.ts
5277
+ import { Command as Command8 } from "commander";
4472
5278
  import { execa as execa3 } from "execa";
4473
5279
  var lintCommand;
4474
5280
  var init_lint = __esm({
@@ -4477,7 +5283,7 @@ var init_lint = __esm({
4477
5283
  init_esm_shims();
4478
5284
  init_utils();
4479
5285
  init_logger();
4480
- lintCommand = new Command7("lint").option("--fix", "\u81EA\u52A8\u4FEE\u590D\u95EE\u9898").option("--no-type-check", "\u8DF3\u8FC7 TypeScript \u7C7B\u578B\u68C0\u67E5").description("\u4EE3\u7801\u8D28\u91CF\u68C0\u67E5 (\u524D\u7AEF + \u540E\u7AEF)").action(async (options) => {
5286
+ lintCommand = new Command8("lint").option("--fix", "\u81EA\u52A8\u4FEE\u590D\u95EE\u9898").option("--no-type-check", "\u8DF3\u8FC7 TypeScript \u7C7B\u578B\u68C0\u67E5").description("\u4EE3\u7801\u8D28\u91CF\u68C0\u67E5 (\u524D\u7AEF + \u540E\u7AEF)").action(async (options) => {
4481
5287
  try {
4482
5288
  logger.header("\u4EE3\u7801\u8D28\u91CF\u68C0\u67E5");
4483
5289
  logger.newLine();
@@ -4611,8 +5417,8 @@ var init_lint = __esm({
4611
5417
  });
4612
5418
 
4613
5419
  // src/commands/status.ts
4614
- import { Command as Command8 } from "commander";
4615
- import path13 from "path";
5420
+ import { Command as Command9 } from "commander";
5421
+ import path14 from "path";
4616
5422
  async function displayProjectInfo() {
4617
5423
  logger.info("\u9879\u76EE\u4FE1\u606F:");
4618
5424
  logger.newLine();
@@ -4648,7 +5454,7 @@ async function displayFeatureInventory() {
4648
5454
  }
4649
5455
  const inventory = [];
4650
5456
  for (const file of specs) {
4651
- const filePath = path13.join(specDir, file);
5457
+ const filePath = path14.join(specDir, file);
4652
5458
  const content = await FileUtils.read(filePath);
4653
5459
  const status = SpecUtils.parseSpecStatus(content);
4654
5460
  const statusWithIcon = SpecUtils.getStatusWithIcon(status);
@@ -4708,7 +5514,7 @@ async function displayRecentActivity() {
4708
5514
  }
4709
5515
  const sorted = files.sort().reverse().slice(0, 5);
4710
5516
  for (const file of sorted) {
4711
- const filePath = path13.join(sessionDir, file);
5517
+ const filePath = path14.join(sessionDir, file);
4712
5518
  const stat = await FileUtils.read(filePath);
4713
5519
  const specMatch = stat.match(/\*\*Spec\*\*:\s*(.+)/);
4714
5520
  const spec = specMatch ? specMatch[1].trim() : "\u672A\u77E5";
@@ -4729,7 +5535,7 @@ var init_status = __esm({
4729
5535
  init_esm_shims();
4730
5536
  init_utils();
4731
5537
  init_logger();
4732
- statusCommand = new Command8("status").description("\u67E5\u770B\u9879\u76EE\u72B6\u6001").action(async () => {
5538
+ statusCommand = new Command9("status").description("\u67E5\u770B\u9879\u76EE\u72B6\u6001").action(async () => {
4733
5539
  try {
4734
5540
  logger.header("\u9879\u76EE\u72B6\u6001");
4735
5541
  logger.newLine();
@@ -4755,14 +5561,14 @@ var init_status = __esm({
4755
5561
  });
4756
5562
 
4757
5563
  // src/commands/detect-deps.ts
4758
- import { Command as Command9 } from "commander";
4759
- import path14 from "path";
4760
- import inquirer6 from "inquirer";
5564
+ import { Command as Command10 } from "commander";
5565
+ import path15 from "path";
5566
+ import inquirer7 from "inquirer";
4761
5567
  async function detectDependencies(specFile) {
4762
5568
  logger.step("\u81EA\u52A8\u68C0\u6D4B\u4F9D\u8D56\u5173\u7CFB...");
4763
5569
  const projectDir = ".";
4764
5570
  const allDeps = /* @__PURE__ */ new Set();
4765
- const backendDir = path14.join(projectDir, "backend");
5571
+ const backendDir = path15.join(projectDir, "backend");
4766
5572
  const backendExists = await FileUtils.exists(backendDir);
4767
5573
  if (backendExists) {
4768
5574
  const apiDeps = await scanBackendApiCalls(backendDir);
@@ -4772,7 +5578,7 @@ async function detectDependencies(specFile) {
4772
5578
  const serviceDeps = await scanBackendServiceRefs(backendDir);
4773
5579
  serviceDeps.forEach((d) => allDeps.add(d));
4774
5580
  }
4775
- const frontendDir = path14.join(projectDir, "frontend");
5581
+ const frontendDir = path15.join(projectDir, "frontend");
4776
5582
  const frontendExists = await FileUtils.exists(frontendDir);
4777
5583
  if (frontendExists) {
4778
5584
  const frontendDeps = await scanFrontendApiCalls(frontendDir);
@@ -4798,7 +5604,7 @@ async function detectDependencies(specFile) {
4798
5604
  logger.step(`- ${spec}`);
4799
5605
  }
4800
5606
  logger.newLine();
4801
- const answers = await inquirer6.prompt([
5607
+ const answers = await inquirer7.prompt([
4802
5608
  {
4803
5609
  type: "confirm",
4804
5610
  name: "autoUpdate",
@@ -4813,11 +5619,11 @@ async function detectDependencies(specFile) {
4813
5619
  }
4814
5620
  async function scanBackendApiCalls(backendDir) {
4815
5621
  const deps = [];
4816
- const srcDir = path14.join(backendDir, "src");
5622
+ const srcDir = path15.join(backendDir, "src");
4817
5623
  try {
4818
5624
  const javaFiles = await FileUtils.findFiles("*.java", srcDir);
4819
5625
  for (const file of javaFiles) {
4820
- const filePath = path14.join(srcDir, file);
5626
+ const filePath = path15.join(srcDir, file);
4821
5627
  const content = await FileUtils.read(filePath);
4822
5628
  const pathRegex = /"(\/api\/[^"]+)"/g;
4823
5629
  let match;
@@ -4835,11 +5641,11 @@ async function scanBackendApiCalls(backendDir) {
4835
5641
  }
4836
5642
  async function scanBackendEntityRelations(backendDir) {
4837
5643
  const deps = [];
4838
- const srcDir = path14.join(backendDir, "src");
5644
+ const srcDir = path15.join(backendDir, "src");
4839
5645
  try {
4840
5646
  const javaFiles = await FileUtils.findFiles("*.java", srcDir);
4841
5647
  for (const file of javaFiles) {
4842
- const filePath = path14.join(srcDir, file);
5648
+ const filePath = path15.join(srcDir, file);
4843
5649
  const content = await FileUtils.read(filePath);
4844
5650
  if (content.includes("@JoinColumn") || content.includes("@ManyToOne") || content.includes("@OneToMany")) {
4845
5651
  const typeRegex = /type\s*=\s*(\w+)/g;
@@ -4855,11 +5661,11 @@ async function scanBackendEntityRelations(backendDir) {
4855
5661
  }
4856
5662
  async function scanBackendServiceRefs(backendDir) {
4857
5663
  const deps = [];
4858
- const srcDir = path14.join(backendDir, "src");
5664
+ const srcDir = path15.join(backendDir, "src");
4859
5665
  try {
4860
5666
  const javaFiles = await FileUtils.findFiles("*.java", srcDir);
4861
5667
  for (const file of javaFiles) {
4862
- const filePath = path14.join(srcDir, file);
5668
+ const filePath = path15.join(srcDir, file);
4863
5669
  const content = await FileUtils.read(filePath);
4864
5670
  const serviceRegex = /private\s+(\w+)Service/g;
4865
5671
  let match;
@@ -4875,11 +5681,11 @@ async function scanBackendServiceRefs(backendDir) {
4875
5681
  }
4876
5682
  async function scanFrontendApiCalls(frontendDir) {
4877
5683
  const deps = [];
4878
- const srcDir = path14.join(frontendDir, "src");
5684
+ const srcDir = path15.join(frontendDir, "src");
4879
5685
  try {
4880
5686
  const tsFiles = await FileUtils.findFiles("*.{ts,tsx,js,jsx}", srcDir);
4881
5687
  for (const file of tsFiles) {
4882
- const filePath = path14.join(srcDir, file);
5688
+ const filePath = path15.join(srcDir, file);
4883
5689
  const content = await FileUtils.read(filePath);
4884
5690
  const pathRegex = /"(\/api\/[^"]+)"/g;
4885
5691
  let match;
@@ -4970,7 +5776,7 @@ var init_detect_deps = __esm({
4970
5776
  init_esm_shims();
4971
5777
  init_utils();
4972
5778
  init_logger();
4973
- detectDepsCommand = new Command9("detect-deps").argument("[spec-file]", "Spec \u6587\u4EF6\u8DEF\u5F84").description("\u68C0\u6D4B\u4F9D\u8D56\u5173\u7CFB").action(async (specFile) => {
5779
+ detectDepsCommand = new Command10("detect-deps").argument("[spec-file]", "Spec \u6587\u4EF6\u8DEF\u5F84").description("\u68C0\u6D4B\u4F9D\u8D56\u5173\u7CFB").action(async (specFile) => {
4974
5780
  try {
4975
5781
  logger.header("\u68C0\u6D4B\u4F9D\u8D56\u5173\u7CFB");
4976
5782
  logger.newLine();
@@ -4996,7 +5802,7 @@ var init_detect_deps = __esm({
4996
5802
  process.exit(1);
4997
5803
  }
4998
5804
  for (const spec of specs) {
4999
- const specPath = path14.join(specsDir, spec);
5805
+ const specPath = path15.join(specsDir, spec);
5000
5806
  logger.step(`\u5904\u7406: ${spec}`);
5001
5807
  await detectDependencies(specPath);
5002
5808
  logger.newLine();
@@ -5022,11 +5828,11 @@ var init_detect_deps = __esm({
5022
5828
  });
5023
5829
 
5024
5830
  // src/commands/sync-memory.ts
5025
- import { Command as Command10 } from "commander";
5026
- import path15 from "path";
5831
+ import { Command as Command11 } from "commander";
5832
+ import path16 from "path";
5027
5833
  async function syncFeatureInventory(aiMemoryFile, projectDir) {
5028
5834
  logger.step("\u540C\u6B65\u529F\u80FD\u6E05\u5355...");
5029
- const specsDir = path15.join(projectDir, "docs/specs");
5835
+ const specsDir = path16.join(projectDir, "docs/specs");
5030
5836
  const exists = await FileUtils.exists(specsDir);
5031
5837
  if (!exists) {
5032
5838
  return;
@@ -5041,7 +5847,7 @@ async function syncFeatureInventory(aiMemoryFile, projectDir) {
5041
5847
  for (const specFile of specs) {
5042
5848
  const name = specFile.replace(".md", "");
5043
5849
  const displayName = name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
5044
- const specPath = path15.join(specsDir, specFile);
5850
+ const specPath = path16.join(specsDir, specFile);
5045
5851
  const content = await FileUtils.read(specPath);
5046
5852
  const status = SpecUtils.parseSpecStatus(content);
5047
5853
  const statusWithIcon = SpecUtils.getStatusWithIcon(status);
@@ -5060,7 +5866,7 @@ async function syncFeatureInventory(aiMemoryFile, projectDir) {
5060
5866
  }
5061
5867
  async function syncApiInventory(aiMemoryFile, projectDir) {
5062
5868
  logger.step("\u540C\u6B65 API \u5217\u8868...");
5063
- const backendDir = path15.join(projectDir, "backend");
5869
+ const backendDir = path16.join(projectDir, "backend");
5064
5870
  const exists = await FileUtils.exists(backendDir);
5065
5871
  if (!exists) {
5066
5872
  return;
@@ -5070,13 +5876,13 @@ async function syncApiInventory(aiMemoryFile, projectDir) {
5070
5876
  lines.push("");
5071
5877
  lines.push("> \u672C\u90E8\u5206\u7531 team-cli \u81EA\u52A8\u626B\u63CF\u540E\u7AEF Controller \u751F\u6210");
5072
5878
  lines.push("");
5073
- const srcDir = path15.join(backendDir, "src");
5879
+ const srcDir = path16.join(backendDir, "src");
5074
5880
  const controllers = await FileUtils.findFiles("*Controller.java", srcDir);
5075
5881
  if (controllers.length === 0) {
5076
5882
  lines.push("\u6682\u65E0 API");
5077
5883
  } else {
5078
5884
  for (const controllerFile of controllers) {
5079
- const controllerPath = path15.join(srcDir, controllerFile);
5885
+ const controllerPath = path16.join(srcDir, controllerFile);
5080
5886
  const controllerName = controllerFile.replace(".java", "");
5081
5887
  const module = controllerName.replace(/Controller$/, "").toLowerCase();
5082
5888
  lines.push(`### ${module} \u6A21\u5757`);
@@ -5153,7 +5959,7 @@ function extractMethodComment(content, methodName) {
5153
5959
  }
5154
5960
  async function syncDataModels(aiMemoryFile, projectDir) {
5155
5961
  logger.step("\u540C\u6B65\u6570\u636E\u6A21\u578B...");
5156
- const backendDir = path15.join(projectDir, "backend");
5962
+ const backendDir = path16.join(projectDir, "backend");
5157
5963
  const exists = await FileUtils.exists(backendDir);
5158
5964
  if (!exists) {
5159
5965
  return;
@@ -5163,7 +5969,7 @@ async function syncDataModels(aiMemoryFile, projectDir) {
5163
5969
  lines.push("");
5164
5970
  lines.push("> \u672C\u90E8\u5206\u7531 team-cli \u81EA\u52A8\u626B\u63CF\u540E\u7AEF Entity \u751F\u6210");
5165
5971
  lines.push("");
5166
- const srcDir = path15.join(backendDir, "src");
5972
+ const srcDir = path16.join(backendDir, "src");
5167
5973
  const entities = await FileUtils.findFiles("*Entity.java", srcDir);
5168
5974
  if (entities.length === 0) {
5169
5975
  lines.push("\u6682\u65E0\u6570\u636E\u6A21\u578B");
@@ -5171,7 +5977,7 @@ async function syncDataModels(aiMemoryFile, projectDir) {
5171
5977
  lines.push("| \u6A21\u578B | \u8BF4\u660E | \u5B57\u6BB5 | \u5173\u8054 |");
5172
5978
  lines.push("|------|------|------|------|");
5173
5979
  for (const entityFile of entities) {
5174
- const entityPath = path15.join(srcDir, entityFile);
5980
+ const entityPath = path16.join(srcDir, entityFile);
5175
5981
  const entityName = entityFile.replace(".java", "").replace(/Entity$/, "");
5176
5982
  const displayName = entityName.split(/(?=[A-Z])/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
5177
5983
  const content = await FileUtils.read(entityPath);
@@ -5273,15 +6079,15 @@ async function syncTemplateVersions(aiMemoryFile, projectDir) {
5273
6079
  await replaceOrInsertSection(aiMemoryFile, "## \u6A21\u677F\u7248\u672C\u4FE1\u606F", newContent);
5274
6080
  }
5275
6081
  function extractRepoName(repository) {
5276
- let path20 = repository;
5277
- path20 = path20.replace(/^https?:\/\//, "");
5278
- path20 = path20.replace(/^git@/, "");
5279
- const parts = path20.split("/");
6082
+ let path21 = repository;
6083
+ path21 = path21.replace(/^https?:\/\//, "");
6084
+ path21 = path21.replace(/^git@/, "");
6085
+ const parts = path21.split("/");
5280
6086
  if (parts.length > 1) {
5281
- path20 = parts.slice(1).join("/");
6087
+ path21 = parts.slice(1).join("/");
5282
6088
  }
5283
- path20 = path20.replace(/\.git$/, "");
5284
- return path20;
6089
+ path21 = path21.replace(/\.git$/, "");
6090
+ return path21;
5285
6091
  }
5286
6092
  var syncMemoryCommand;
5287
6093
  var init_sync_memory = __esm({
@@ -5291,7 +6097,7 @@ var init_sync_memory = __esm({
5291
6097
  init_utils();
5292
6098
  init_logger();
5293
6099
  init_template_version();
5294
- syncMemoryCommand = new Command10("sync-memory").description("\u540C\u6B65 AI_MEMORY.md").action(async () => {
6100
+ syncMemoryCommand = new Command11("sync-memory").description("\u540C\u6B65 AI_MEMORY.md").action(async () => {
5295
6101
  try {
5296
6102
  logger.header("\u540C\u6B65 AI_MEMORY.md");
5297
6103
  logger.newLine();
@@ -5325,12 +6131,12 @@ var init_sync_memory = __esm({
5325
6131
  });
5326
6132
 
5327
6133
  // src/commands/check-api.ts
5328
- import { Command as Command11 } from "commander";
5329
- import path16 from "path";
5330
- import inquirer7 from "inquirer";
6134
+ import { Command as Command12 } from "commander";
6135
+ import path17 from "path";
6136
+ import inquirer8 from "inquirer";
5331
6137
  import { Listr as Listr6 } from "listr2";
5332
6138
  async function checkApiConflicts(projectDir) {
5333
- const backendDir = path16.join(projectDir, "backend");
6139
+ const backendDir = path17.join(projectDir, "backend");
5334
6140
  const exists = await FileUtils.exists(backendDir);
5335
6141
  if (!exists) {
5336
6142
  logger.info("\u672A\u627E\u5230\u540E\u7AEF\u9879\u76EE");
@@ -5339,10 +6145,10 @@ async function checkApiConflicts(projectDir) {
5339
6145
  logger.step("\u626B\u63CF\u540E\u7AEF API...");
5340
6146
  logger.newLine();
5341
6147
  const apiMap = /* @__PURE__ */ new Map();
5342
- const srcDir = path16.join(backendDir, "src");
6148
+ const srcDir = path17.join(backendDir, "src");
5343
6149
  const controllers = await FileUtils.findFiles("*Controller.java", srcDir);
5344
6150
  for (const controllerFile of controllers) {
5345
- const controllerPath = path16.join(srcDir, controllerFile);
6151
+ const controllerPath = path17.join(srcDir, controllerFile);
5346
6152
  const apis = await extractApisFromController(controllerPath);
5347
6153
  for (const api of apis) {
5348
6154
  const key = `${api.method}:${api.path}`;
@@ -5373,8 +6179,8 @@ async function checkApiConflicts(projectDir) {
5373
6179
  }
5374
6180
  }
5375
6181
  async function detectApiChanges(projectDir) {
5376
- const backendDir = path16.join(projectDir, "backend");
5377
- const registryFile = path16.join(projectDir, "docs/api-registry.md");
6182
+ const backendDir = path17.join(projectDir, "backend");
6183
+ const registryFile = path17.join(projectDir, "docs/api-registry.md");
5378
6184
  const registryExists = await FileUtils.exists(registryFile);
5379
6185
  if (!registryExists) {
5380
6186
  logger.info("API Registry \u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u53D8\u66F4\u68C0\u6D4B");
@@ -5386,10 +6192,10 @@ async function detectApiChanges(projectDir) {
5386
6192
  const registryContent = await FileUtils.read(registryFile);
5387
6193
  const existingApis = extractApisFromRegistry(registryContent);
5388
6194
  const currentApis = /* @__PURE__ */ new Map();
5389
- const srcDir = path16.join(backendDir, "src");
6195
+ const srcDir = path17.join(backendDir, "src");
5390
6196
  const controllers = await FileUtils.findFiles("*Controller.java", srcDir);
5391
6197
  for (const controllerFile of controllers) {
5392
- const controllerPath = path16.join(srcDir, controllerFile);
6198
+ const controllerPath = path17.join(srcDir, controllerFile);
5393
6199
  const apis = await extractApisFromController(controllerPath);
5394
6200
  for (const api of apis) {
5395
6201
  const key = `${api.method}:${api.path}`;
@@ -5451,9 +6257,9 @@ async function detectApiChanges(projectDir) {
5451
6257
  }
5452
6258
  }
5453
6259
  async function generateApiRegistry(projectDir) {
5454
- const registryFile = path16.join(projectDir, "docs/api-registry.md");
6260
+ const registryFile = path17.join(projectDir, "docs/api-registry.md");
5455
6261
  logger.step("\u626B\u63CF\u5E76\u751F\u6210 API Registry...");
5456
- await FileUtils.ensureDir(path16.dirname(registryFile));
6262
+ await FileUtils.ensureDir(path17.dirname(registryFile));
5457
6263
  const header = `# API Registry
5458
6264
 
5459
6265
  > \u672C\u6587\u4EF6\u8BB0\u5F55\u6240\u6709 API \u7684\u5B9A\u4E49\u3001\u7248\u672C\u548C\u53D8\u66F4\u5386\u53F2
@@ -5482,14 +6288,14 @@ async function generateApiRegistry(projectDir) {
5482
6288
  *\u6700\u540E\u66F4\u65B0: ${DateUtils.format(/* @__PURE__ */ new Date(), "YYYY-MM-DD HH:mm:ss")}*
5483
6289
  `;
5484
6290
  let content = header;
5485
- const backendDir = path16.join(projectDir, "backend");
6291
+ const backendDir = path17.join(projectDir, "backend");
5486
6292
  const exists = await FileUtils.exists(backendDir);
5487
6293
  if (exists) {
5488
- const srcDir = path16.join(backendDir, "src");
6294
+ const srcDir = path17.join(backendDir, "src");
5489
6295
  const controllers = await FileUtils.findFiles("*Controller.java", srcDir);
5490
6296
  const moduleMap = /* @__PURE__ */ new Map();
5491
6297
  for (const controllerFile of controllers) {
5492
- const controllerPath = path16.join(srcDir, controllerFile);
6298
+ const controllerPath = path17.join(srcDir, controllerFile);
5493
6299
  const controllerName = controllerFile.replace(".java", "");
5494
6300
  const module = controllerName.replace(/Controller$/, "").toLowerCase();
5495
6301
  if (!moduleMap.has(module)) {
@@ -5573,10 +6379,10 @@ function extractApisFromRegistry(registryContent) {
5573
6379
  let match;
5574
6380
  while ((match = apiRegex.exec(registryContent)) !== null) {
5575
6381
  const method = match[1];
5576
- const path20 = match[2].trim();
6382
+ const path21 = match[2].trim();
5577
6383
  const description = match[3].trim();
5578
- const key = `${method}:${path20}`;
5579
- apis.set(key, { method, path: path20, description });
6384
+ const key = `${method}:${path21}`;
6385
+ apis.set(key, { method, path: path21, description });
5580
6386
  }
5581
6387
  return apis;
5582
6388
  }
@@ -5599,7 +6405,7 @@ var init_check_api = __esm({
5599
6405
  init_esm_shims();
5600
6406
  init_utils();
5601
6407
  init_logger();
5602
- checkApiCommand = new Command11("check-api").description("API \u68C0\u67E5\uFF08\u51B2\u7A81/\u53D8\u66F4/Registry\uFF09").action(async () => {
6408
+ checkApiCommand = new Command12("check-api").description("API \u68C0\u67E5\uFF08\u51B2\u7A81/\u53D8\u66F4/Registry\uFF09").action(async () => {
5603
6409
  try {
5604
6410
  logger.header("API \u68C0\u67E5");
5605
6411
  logger.newLine();
@@ -5609,7 +6415,7 @@ var init_check_api = __esm({
5609
6415
  logger.info("\u8BF7\u5148\u8FD0\u884C 'team-cli init <project-name>' \u6216\u5207\u6362\u5230\u9879\u76EE\u76EE\u5F55");
5610
6416
  process.exit(1);
5611
6417
  }
5612
- const answers = await inquirer7.prompt([
6418
+ const answers = await inquirer8.prompt([
5613
6419
  {
5614
6420
  type: "list",
5615
6421
  name: "checkType",
@@ -5663,16 +6469,16 @@ var init_check_api = __esm({
5663
6469
  });
5664
6470
 
5665
6471
  // src/commands/logs.ts
5666
- import { Command as Command12 } from "commander";
5667
- import path17 from "path";
5668
- import inquirer8 from "inquirer";
6472
+ import { Command as Command13 } from "commander";
6473
+ import path18 from "path";
6474
+ import inquirer9 from "inquirer";
5669
6475
  async function collectLogFiles(targetDir) {
5670
6476
  const logs = [];
5671
6477
  try {
5672
6478
  const allFiles = await FileUtils.findFiles("*.md", targetDir);
5673
6479
  const filtered = allFiles.filter((f) => f !== "index.md");
5674
6480
  for (const file of filtered) {
5675
- const filePath = path17.join(targetDir, file);
6481
+ const filePath = path18.join(targetDir, file);
5676
6482
  const stat = await FileUtils.exists(filePath);
5677
6483
  if (stat) {
5678
6484
  logs.push(filePath);
@@ -5689,7 +6495,7 @@ var init_logs = __esm({
5689
6495
  init_esm_shims();
5690
6496
  init_utils();
5691
6497
  init_logger();
5692
- logsCommand = new Command12("logs").argument("[filter]", "\u8FC7\u6EE4\u5668 (today, --all, \u6216\u65E5\u671F YYYY-MM-DD)").description("\u67E5\u770B\u4F1A\u8BDD\u65E5\u5FD7").action(async (filter = "today") => {
6498
+ logsCommand = new Command13("logs").argument("[filter]", "\u8FC7\u6EE4\u5668 (today, --all, \u6216\u65E5\u671F YYYY-MM-DD)").description("\u67E5\u770B\u4F1A\u8BDD\u65E5\u5FD7").action(async (filter = "today") => {
5693
6499
  try {
5694
6500
  logger.header("\u4F1A\u8BDD\u65E5\u5FD7");
5695
6501
  logger.newLine();
@@ -5712,7 +6518,7 @@ var init_logs = __esm({
5712
6518
  case "":
5713
6519
  case "today": {
5714
6520
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
5715
- targetDir = path17.join(sessionsDir, today);
6521
+ targetDir = path18.join(sessionsDir, today);
5716
6522
  const todayExists = await FileUtils.exists(targetDir);
5717
6523
  if (!todayExists) {
5718
6524
  logger.info("\u4ECA\u65E5\u6682\u65E0\u4F1A\u8BDD\u65E5\u5FD7");
@@ -5728,7 +6534,7 @@ var init_logs = __esm({
5728
6534
  break;
5729
6535
  }
5730
6536
  default: {
5731
- targetDir = path17.join(sessionsDir, filter);
6537
+ targetDir = path18.join(sessionsDir, filter);
5732
6538
  const dateExists = await FileUtils.exists(targetDir);
5733
6539
  if (!dateExists) {
5734
6540
  logger.error(`\u672A\u627E\u5230\u65E5\u671F '${filter}' \u7684\u65E5\u5FD7`);
@@ -5752,11 +6558,11 @@ var init_logs = __esm({
5752
6558
  process.exit(0);
5753
6559
  }
5754
6560
  for (let i = 0; i < logs.length; i++) {
5755
- const relPath = path17.relative(sessionsDir, logs[i]);
6561
+ const relPath = path18.relative(sessionsDir, logs[i]);
5756
6562
  logger.step(`${i + 1}) ${relPath}`);
5757
6563
  }
5758
6564
  logger.newLine();
5759
- const answers = await inquirer8.prompt([
6565
+ const answers = await inquirer9.prompt([
5760
6566
  {
5761
6567
  type: "input",
5762
6568
  name: "selection",
@@ -5791,10 +6597,10 @@ var init_logs = __esm({
5791
6597
  });
5792
6598
 
5793
6599
  // src/commands/update.ts
5794
- import { Command as Command13 } from "commander";
5795
- import path18 from "path";
6600
+ import { Command as Command14 } from "commander";
6601
+ import path19 from "path";
5796
6602
  import { execa as execa4 } from "execa";
5797
- import inquirer9 from "inquirer";
6603
+ import inquirer10 from "inquirer";
5798
6604
  import fs4 from "fs-extra";
5799
6605
  async function performUpdate(projectPath, updates) {
5800
6606
  logger.newLine();
@@ -5802,7 +6608,7 @@ async function performUpdate(projectPath, updates) {
5802
6608
  for (const update of updates) {
5803
6609
  const { type, info, updateOptions } = update;
5804
6610
  const targetDir = type === "frontend" ? "frontend" : "backend";
5805
- const targetPath = path18.join(projectPath, targetDir);
6611
+ const targetPath = path19.join(projectPath, targetDir);
5806
6612
  logger.newLine();
5807
6613
  logger.step(`\u66F4\u65B0 ${type === "frontend" ? "\u524D\u7AEF" : "\u540E\u7AEF"}\u6A21\u677F...`);
5808
6614
  if (updateOptions?.tag || updateOptions?.branch) {
@@ -5833,8 +6639,8 @@ async function performUpdate(projectPath, updates) {
5833
6639
  }
5834
6640
  }
5835
6641
  const ref = updateOptions?.tag || updateOptions?.branch || "HEAD";
5836
- const backupDir = path18.join(projectPath, `.backup-${Date.now()}`);
5837
- await fs4.copy(targetPath, path18.join(backupDir, targetDir));
6642
+ const backupDir = path19.join(projectPath, `.backup-${Date.now()}`);
6643
+ await fs4.copy(targetPath, path19.join(backupDir, targetDir));
5838
6644
  logger.info(`\u5DF2\u521B\u5EFA\u5907\u4EFD: ${backupDir}`);
5839
6645
  if (updateOptions?.dryRun) {
5840
6646
  logger.info("[Dry Run] \u5C06\u4F1A\u66F4\u65B0\u5230\u4EE5\u4E0B\u7248\u672C:");
@@ -5844,7 +6650,7 @@ async function performUpdate(projectPath, updates) {
5844
6650
  continue;
5845
6651
  }
5846
6652
  try {
5847
- const tempDir = path18.join(projectPath, `.template-update-${Date.now()}`);
6653
+ const tempDir = path19.join(projectPath, `.template-update-${Date.now()}`);
5848
6654
  await execa4("git", ["clone", "--depth=1", "--branch", ref, info.repository, tempDir], {
5849
6655
  stdio: "pipe"
5850
6656
  });
@@ -5861,7 +6667,7 @@ async function performUpdate(projectPath, updates) {
5861
6667
  const currentFiles = await FileUtils.findFiles("*", targetPath);
5862
6668
  for (const file of currentFiles) {
5863
6669
  if (!keepFiles.includes(file)) {
5864
- const filePath = path18.join(targetPath, file);
6670
+ const filePath = path19.join(targetPath, file);
5865
6671
  try {
5866
6672
  await fs4.remove(filePath);
5867
6673
  } catch {
@@ -5883,7 +6689,7 @@ async function performUpdate(projectPath, updates) {
5883
6689
  logger.error(`\u66F4\u65B0\u5931\u8D25: ${error.message}`);
5884
6690
  logger.info("\u6B63\u5728\u6062\u590D\u5907\u4EFD...");
5885
6691
  await fs4.remove(targetPath);
5886
- await fs4.copy(path18.join(backupDir, targetDir), targetPath);
6692
+ await fs4.copy(path19.join(backupDir, targetDir), targetPath);
5887
6693
  await fs4.remove(backupDir);
5888
6694
  logger.info("\u5DF2\u6062\u590D\u5230\u66F4\u65B0\u524D\u7684\u72B6\u6001");
5889
6695
  }
@@ -5906,7 +6712,7 @@ var init_update = __esm({
5906
6712
  init_template_version();
5907
6713
  init_logger();
5908
6714
  init_utils();
5909
- updateCommand = new Command13("update").description("\u68C0\u67E5\u5E76\u66F4\u65B0\u6A21\u677F\u7248\u672C").option("-f, --frontend", "\u68C0\u67E5\u524D\u7AEF\u6A21\u677F\u66F4\u65B0").option("-b, --backend", "\u68C0\u67E5\u540E\u7AEF\u6A21\u677F\u66F4\u65B0").option("-a, --all", "\u68C0\u67E5\u6240\u6709\u6A21\u677F (\u9ED8\u8BA4)").option("-t, --tag <tag>", "\u66F4\u65B0\u5230\u6307\u5B9A\u6807\u7B7E").option("-B, --branch <branch>", "\u66F4\u65B0\u5230\u6307\u5B9A\u5206\u652F").option("--dry-run", "\u9884\u89C8\u66F4\u65B0\uFF0C\u4E0D\u5B9E\u9645\u6267\u884C").action(async (options) => {
6715
+ updateCommand = new Command14("update").description("\u68C0\u67E5\u5E76\u66F4\u65B0\u6A21\u677F\u7248\u672C").option("-f, --frontend", "\u68C0\u67E5\u524D\u7AEF\u6A21\u677F\u66F4\u65B0").option("-b, --backend", "\u68C0\u67E5\u540E\u7AEF\u6A21\u677F\u66F4\u65B0").option("-a, --all", "\u68C0\u67E5\u6240\u6709\u6A21\u677F (\u9ED8\u8BA4)").option("-t, --tag <tag>", "\u66F4\u65B0\u5230\u6307\u5B9A\u6807\u7B7E").option("-B, --branch <branch>", "\u66F4\u65B0\u5230\u6307\u5B9A\u5206\u652F").option("--dry-run", "\u9884\u89C8\u66F4\u65B0\uFF0C\u4E0D\u5B9E\u9645\u6267\u884C").action(async (options) => {
5910
6716
  try {
5911
6717
  logger.header("\u6A21\u677F\u7248\u672C\u68C0\u67E5");
5912
6718
  logger.newLine();
@@ -5978,7 +6784,7 @@ var init_update = __esm({
5978
6784
  logger.info("Dry run \u6A21\u5F0F\uFF0C\u4E0D\u6267\u884C\u5B9E\u9645\u66F4\u65B0");
5979
6785
  return;
5980
6786
  }
5981
- const answers = await inquirer9.prompt([
6787
+ const answers = await inquirer10.prompt([
5982
6788
  {
5983
6789
  type: "confirm",
5984
6790
  name: "shouldUpdate",
@@ -6003,8 +6809,8 @@ var init_update = __esm({
6003
6809
  });
6004
6810
 
6005
6811
  // src/commands/config.ts
6006
- import { Command as Command14 } from "commander";
6007
- import inquirer10 from "inquirer";
6812
+ import { Command as Command15 } from "commander";
6813
+ import inquirer11 from "inquirer";
6008
6814
  import chalk2 from "chalk";
6009
6815
  var setTokenCommand, showConfigCommand, removeConfigCommand, validateTokenCommand, configCommand;
6010
6816
  var init_config = __esm({
@@ -6014,13 +6820,13 @@ var init_config = __esm({
6014
6820
  init_user_config();
6015
6821
  init_gitlab_api();
6016
6822
  init_logger();
6017
- setTokenCommand = new Command14("set-token").description("\u8BBE\u7F6E GitLab Access Token").option("-t, --token <token>", "Access Token").option("-u, --url <url>", "GitLab Base URL", "https://gitlab.com").action(async (options) => {
6823
+ setTokenCommand = new Command15("set-token").description("\u8BBE\u7F6E GitLab Access Token").option("-t, --token <token>", "Access Token").option("-u, --url <url>", "GitLab Base URL", "https://gitlab.com").action(async (options) => {
6018
6824
  try {
6019
6825
  logger.header("GitLab Access Token \u914D\u7F6E");
6020
6826
  logger.newLine();
6021
6827
  let { token, url } = options;
6022
6828
  if (!token) {
6023
- const answers = await inquirer10.prompt([
6829
+ const answers = await inquirer11.prompt([
6024
6830
  {
6025
6831
  type: "password",
6026
6832
  name: "token",
@@ -6082,7 +6888,7 @@ var init_config = __esm({
6082
6888
  process.exit(1);
6083
6889
  }
6084
6890
  });
6085
- showConfigCommand = new Command14("show").description("\u663E\u793A\u5F53\u524D\u914D\u7F6E").action(async () => {
6891
+ showConfigCommand = new Command15("show").description("\u663E\u793A\u5F53\u524D\u914D\u7F6E").action(async () => {
6086
6892
  try {
6087
6893
  logger.header("GitLab \u914D\u7F6E");
6088
6894
  logger.newLine();
@@ -6121,14 +6927,14 @@ var init_config = __esm({
6121
6927
  process.exit(1);
6122
6928
  }
6123
6929
  });
6124
- removeConfigCommand = new Command14("remove").alias("rm").description("\u5220\u9664 GitLab \u914D\u7F6E").action(async () => {
6930
+ removeConfigCommand = new Command15("remove").alias("rm").description("\u5220\u9664 GitLab \u914D\u7F6E").action(async () => {
6125
6931
  try {
6126
6932
  const hasConfig = await userConfigManager.hasConfig();
6127
6933
  if (!hasConfig) {
6128
6934
  logger.warn("\u672A\u914D\u7F6E GitLab Access Token");
6129
6935
  return;
6130
6936
  }
6131
- const answers = await inquirer10.prompt([
6937
+ const answers = await inquirer11.prompt([
6132
6938
  {
6133
6939
  type: "confirm",
6134
6940
  name: "confirm",
@@ -6150,7 +6956,7 @@ var init_config = __esm({
6150
6956
  process.exit(1);
6151
6957
  }
6152
6958
  });
6153
- validateTokenCommand = new Command14("validate").alias("test").description("\u9A8C\u8BC1\u5F53\u524D Token \u662F\u5426\u6709\u6548").action(async () => {
6959
+ validateTokenCommand = new Command15("validate").alias("test").description("\u9A8C\u8BC1\u5F53\u524D Token \u662F\u5426\u6709\u6548").action(async () => {
6154
6960
  try {
6155
6961
  logger.header("\u9A8C\u8BC1 GitLab Token");
6156
6962
  logger.newLine();
@@ -6180,12 +6986,12 @@ var init_config = __esm({
6180
6986
  process.exit(1);
6181
6987
  }
6182
6988
  });
6183
- configCommand = new Command14("config").description("\u7BA1\u7406 GitLab \u914D\u7F6E").addCommand(setTokenCommand).addCommand(showConfigCommand).addCommand(removeConfigCommand).addCommand(validateTokenCommand);
6989
+ configCommand = new Command15("config").description("\u7BA1\u7406 GitLab \u914D\u7F6E").addCommand(setTokenCommand).addCommand(showConfigCommand).addCommand(removeConfigCommand).addCommand(validateTokenCommand);
6184
6990
  }
6185
6991
  });
6186
6992
 
6187
6993
  // src/commands/diff.ts
6188
- import { Command as Command15 } from "commander";
6994
+ import { Command as Command16 } from "commander";
6189
6995
  import chalk3 from "chalk";
6190
6996
  async function compareTemplate(projectPath, type, localConfig, remoteTag, remoteBranch, gitlabConfig) {
6191
6997
  try {
@@ -6364,7 +7170,7 @@ var init_diff = __esm({
6364
7170
  init_utils();
6365
7171
  init_user_config();
6366
7172
  init_gitlab_api();
6367
- diffCommand = new Command15("diff").description("\u5BF9\u6BD4\u672C\u5730\u4E0E\u8FDC\u7A0B\u6A21\u677F\u5DEE\u5F02").option("-f, --frontend", "\u5BF9\u6BD4\u524D\u7AEF\u6A21\u677F").option("-b, --backend", "\u5BF9\u6BD4\u540E\u7AEF\u6A21\u677F").option("-t, --tag <tag>", "\u6307\u5B9A\u8FDC\u7A0B\u6807\u7B7E").option("-B, --branch <branch>", "\u6307\u5B9A\u8FDC\u7A0B\u5206\u652F").option("-o, --output <format>", "\u8F93\u51FA\u683C\u5F0F (table|json|diff)", "table").action(async (options) => {
7173
+ diffCommand = new Command16("diff").description("\u5BF9\u6BD4\u672C\u5730\u4E0E\u8FDC\u7A0B\u6A21\u677F\u5DEE\u5F02").option("-f, --frontend", "\u5BF9\u6BD4\u524D\u7AEF\u6A21\u677F").option("-b, --backend", "\u5BF9\u6BD4\u540E\u7AEF\u6A21\u677F").option("-t, --tag <tag>", "\u6307\u5B9A\u8FDC\u7A0B\u6807\u7B7E").option("-B, --branch <branch>", "\u6307\u5B9A\u8FDC\u7A0B\u5206\u652F").option("-o, --output <format>", "\u8F93\u51FA\u683C\u5F0F (table|json|diff)", "table").action(async (options) => {
6368
7174
  try {
6369
7175
  logger.header("\u6A21\u677F\u7248\u672C\u5BF9\u6BD4");
6370
7176
  logger.newLine();
@@ -6486,10 +7292,10 @@ var init_diff = __esm({
6486
7292
 
6487
7293
  // src/index.ts
6488
7294
  var index_exports = {};
6489
- import { Command as Command16 } from "commander";
7295
+ import { Command as Command17 } from "commander";
6490
7296
  import chalk4 from "chalk";
6491
7297
  import fs5 from "fs-extra";
6492
- import path19 from "path";
7298
+ import path20 from "path";
6493
7299
  import { fileURLToPath as fileURLToPath2 } from "url";
6494
7300
  function showHelp() {
6495
7301
  console.log("");
@@ -6500,7 +7306,8 @@ function showHelp() {
6500
7306
  console.log(" team-cli split-prd <prd-folder> \u5C06 PRD \u62C6\u5206\u6210\u591A\u4E2A specs");
6501
7307
  console.log(" team-cli breakdown [spec-file] \u5C06 spec \u62C6\u5206\u4E3A milestones \u548C todos");
6502
7308
  console.log(" team-cli dev \u5F00\u53D1\u6A21\u5F0F\uFF0C\u6267\u884C\u5177\u4F53\u4EFB\u52A1");
6503
- console.log(" team-cli add-feature <name> \u6DFB\u52A0\u65B0\u529F\u80FD");
7309
+ console.log(" team-cli accept [spec-file] \u9A8C\u6536\u529F\u80FD\uFF0C\u8D70\u67E5\u6240\u6709\u9700\u6C42");
7310
+ console.log(" team-cli add-feature <name> \u6DFB\u52A0\u65B0\u529F\u80FD");
6504
7311
  console.log(" team-cli bugfix \u521B\u5EFA Bugfix \u8BB0\u5F55");
6505
7312
  console.log(" team-cli hotfix \u521B\u5EFA Hotfix");
6506
7313
  console.log(" team-cli detect-deps [spec] \u68C0\u6D4B\u4F9D\u8D56\u5173\u7CFB");
@@ -6525,6 +7332,7 @@ function showHelp() {
6525
7332
  console.log(" 1. PRD \u2192 specs (split-prd)");
6526
7333
  console.log(" 2. spec \u2192 milestones + todos (breakdown)");
6527
7334
  console.log(" 3. \u9009\u62E9 milestone/todo \u2192 \u5B9E\u73B0 (dev)");
7335
+ console.log(" 4. \u9A8C\u6536 (accept) \u2192 \u9A8C\u8BC1\u8054\u8C03\u662F\u5426\u5B8C\u6210");
6528
7336
  console.log("");
6529
7337
  console.log(chalk4.bold("\u8FED\u4EE3\u6D41\u7A0B:"));
6530
7338
  console.log(" team-cli add-feature <name> # \u6DFB\u52A0\u65B0\u529F\u80FD");
@@ -6558,6 +7366,7 @@ var init_index = __esm({
6558
7366
  init_split_prd();
6559
7367
  init_bugfix();
6560
7368
  init_bugfix();
7369
+ init_accept();
6561
7370
  init_lint();
6562
7371
  init_status();
6563
7372
  init_detect_deps();
@@ -6567,9 +7376,9 @@ var init_index = __esm({
6567
7376
  init_update();
6568
7377
  init_config();
6569
7378
  init_diff();
6570
- __dirname2 = path19.dirname(fileURLToPath2(import.meta.url));
6571
- pkg = fs5.readJsonSync(path19.join(__dirname2, "../package.json"));
6572
- program = new Command16();
7379
+ __dirname2 = path20.dirname(fileURLToPath2(import.meta.url));
7380
+ pkg = fs5.readJsonSync(path20.join(__dirname2, "../package.json"));
7381
+ program = new Command17();
6573
7382
  program.name("team-cli").description("AI-Native \u56E2\u961F\u7814\u53D1\u811A\u624B\u67B6").version(pkg.version);
6574
7383
  program.option("-v, --verbose", "\u8BE6\u7EC6\u8F93\u51FA\u6A21\u5F0F").option("--debug", "\u8C03\u8BD5\u6A21\u5F0F");
6575
7384
  program.addCommand(initCommand);
@@ -6579,6 +7388,7 @@ var init_index = __esm({
6579
7388
  program.addCommand(addFeatureCommand);
6580
7389
  program.addCommand(bugfixCommand);
6581
7390
  program.addCommand(hotfixCommand);
7391
+ program.addCommand(acceptCommand);
6582
7392
  program.addCommand(lintCommand);
6583
7393
  program.addCommand(statusCommand);
6584
7394
  program.addCommand(detectDepsCommand);