@nick848/sf-cli 1.0.10 → 1.0.12

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/index.js CHANGED
@@ -1794,14 +1794,17 @@ async function handleNew(args, ctx) {
1794
1794
  const requirement = args.join(" ").trim();
1795
1795
  if (!requirement) {
1796
1796
  return {
1797
- output: chalk9__default.default.red("\u8BF7\u8F93\u5165\u9700\u6C42\u63CF\u8FF0") + chalk9__default.default.gray("\n\u7528\u6CD5: /new <\u9700\u6C42\u63CF\u8FF0>")
1797
+ output: chalk9__default.default.red("\u8BF7\u8F93\u5165\u9700\u6C42\u63CF\u8FF0") + chalk9__default.default.gray("\n\u7528\u6CD5: /new <\u9700\u6C42\u63CF\u8FF0>") + chalk9__default.default.gray("\n\n\u793A\u4F8B:") + chalk9__default.default.gray("\n /new \u5B9E\u73B0\u7528\u6237\u767B\u5F55\u529F\u80FD") + chalk9__default.default.gray("\n /new \u6DFB\u52A0\u6570\u636E\u5BFC\u51FA\u4E3AExcel\u7684\u529F\u80FD")
1798
1798
  };
1799
1799
  }
1800
1800
  activeSession = {
1801
1801
  id: generateSessionId(),
1802
1802
  requirement,
1803
+ refinedRequirement: requirement,
1803
1804
  phase: "context",
1804
1805
  context: null,
1806
+ clarityScore: 0,
1807
+ clarificationQuestions: [],
1805
1808
  complexity: 0,
1806
1809
  bddScenarios: [],
1807
1810
  specItems: [],
@@ -1819,10 +1822,13 @@ function handleActiveSession(ctx) {
1819
1822
  const lines = [];
1820
1823
  lines.push(chalk9__default.default.cyan("\u{1F4CB} \u5F53\u524D\u5DE5\u4F5C\u6D41\u72B6\u6001"));
1821
1824
  lines.push("");
1822
- lines.push(chalk9__default.default.white(`\u9700\u6C42: ${activeSession.requirement}`));
1825
+ lines.push(chalk9__default.default.white(`\u9700\u6C42: ${activeSession.requirement.slice(0, 60)}${activeSession.requirement.length > 60 ? "..." : ""}`));
1823
1826
  lines.push(chalk9__default.default.gray(`\u9636\u6BB5: ${getPhaseLabel(activeSession.phase)}`));
1824
1827
  lines.push("");
1825
- if (activeSession.phase === "spec") {
1828
+ if (activeSession.phase === "clarify") {
1829
+ lines.push(chalk9__default.default.yellow("\u23F8\uFE0F \u7B49\u5F85\u9700\u6C42\u6F84\u6E05"));
1830
+ lines.push(chalk9__default.default.gray('\u8BF7\u56DE\u7B54\u4E0A\u8FF0\u95EE\u9898\uFF0C\u6216\u8F93\u5165 "done" \u8868\u793A\u56DE\u7B54\u5B8C\u6210'));
1831
+ } else if (activeSession.phase === "spec") {
1826
1832
  lines.push(chalk9__default.default.yellow("\u23F8\uFE0F \u7B49\u5F85\u89C4\u683C\u786E\u8BA4"));
1827
1833
  lines.push("");
1828
1834
  lines.push(chalk9__default.default.green(" y - \u786E\u8BA4\u89C4\u683C\uFF0C\u7EE7\u7EED\u5DE5\u4F5C\u6D41"));
@@ -1841,7 +1847,7 @@ async function executeWorkflow(ctx) {
1841
1847
  const lines = [];
1842
1848
  try {
1843
1849
  if (activeSession.phase === "context") {
1844
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/7: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
1850
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/8: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
1845
1851
  lines.push("");
1846
1852
  activeSession.context = await readProjectContext(ctx.options.workingDirectory);
1847
1853
  lines.push(chalk9__default.default.gray(` \u9879\u76EE: ${activeSession.context.name}`));
@@ -1851,13 +1857,46 @@ async function executeWorkflow(ctx) {
1851
1857
  if (activeSession.context.devStandards) {
1852
1858
  lines.push(chalk9__default.default.green(" \u2713 \u5DF2\u8BFB\u53D6\u5F00\u53D1\u89C4\u8303"));
1853
1859
  }
1860
+ activeSession.phase = "clarify";
1861
+ }
1862
+ if (activeSession.phase === "clarify") {
1863
+ lines.push("");
1864
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/8: \u9700\u6C42\u6F84\u6E05 \u2501\u2501\u2501"));
1865
+ lines.push("");
1866
+ const clarityResult = analyzeRequirementClarity(
1867
+ activeSession.requirement,
1868
+ activeSession.context
1869
+ );
1870
+ activeSession.clarityScore = clarityResult.score;
1871
+ activeSession.clarificationQuestions = clarityResult.questions;
1872
+ lines.push(chalk9__default.default.gray(` \u9700\u6C42\u6E05\u6670\u5EA6: ${Math.round(clarityResult.score * 100)}%`));
1873
+ lines.push("");
1874
+ if (clarityResult.score < CLARITY_THRESHOLD && clarityResult.questions.length > 0) {
1875
+ lines.push(chalk9__default.default.yellow(" \u9700\u6C42\u4E0D\u591F\u660E\u786E\uFF0C\u8BF7\u8865\u5145\u4EE5\u4E0B\u4FE1\u606F\uFF1A"));
1876
+ lines.push("");
1877
+ const unansweredQuestions = clarityResult.questions.filter((q) => !q.answered);
1878
+ for (let i = 0; i < Math.min(unansweredQuestions.length, 3); i++) {
1879
+ const q = unansweredQuestions[i];
1880
+ lines.push(chalk9__default.default.white(` ${i + 1}. ${q.question}`));
1881
+ }
1882
+ if (unansweredQuestions.length > 3) {
1883
+ lines.push(chalk9__default.default.gray(` ... \u8FD8\u6709 ${unansweredQuestions.length - 3} \u4E2A\u95EE\u9898`));
1884
+ }
1885
+ lines.push("");
1886
+ lines.push(chalk9__default.default.gray(' \u8BF7\u8F93\u5165\u56DE\u7B54\uFF0C\u6216\u8F93\u5165 "done" \u8DF3\u8FC7\u6F84\u6E05'));
1887
+ return { output: lines.join("\n") };
1888
+ }
1889
+ lines.push(chalk9__default.default.green(" \u2713 \u9700\u6C42\u6E05\u6670\uFF0C\u7EE7\u7EED\u4E0B\u4E00\u6B65"));
1854
1890
  activeSession.phase = "analysis";
1855
1891
  }
1856
1892
  if (activeSession.phase === "analysis") {
1857
1893
  lines.push("");
1858
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/7: \u590D\u6742\u5EA6\u8BC4\u4F30 \u2501\u2501\u2501"));
1894
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 3/8: \u590D\u6742\u5EA6\u8BC4\u4F30 \u2501\u2501\u2501"));
1859
1895
  lines.push("");
1860
- activeSession.complexity = analyzeComplexity(activeSession.requirement, activeSession.context);
1896
+ activeSession.complexity = analyzeComplexity(
1897
+ activeSession.refinedRequirement,
1898
+ activeSession.context
1899
+ );
1861
1900
  const complexityBar = generateComplexityBar(activeSession.complexity);
1862
1901
  lines.push(chalk9__default.default.gray(` \u590D\u6742\u5EA6: ${complexityBar} ${activeSession.complexity}/10`));
1863
1902
  if (activeSession.complexity >= COMPLEXITY_THRESHOLD) {
@@ -1869,9 +1908,13 @@ async function executeWorkflow(ctx) {
1869
1908
  }
1870
1909
  if (activeSession.phase === "bdd") {
1871
1910
  lines.push("");
1872
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 3/7: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
1911
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 4/8: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
1873
1912
  lines.push("");
1874
- activeSession.bddScenarios = generateBDDScenarios(activeSession.requirement, activeSession.context);
1913
+ activeSession.bddScenarios = generateBDDScenarios(
1914
+ activeSession.refinedRequirement,
1915
+ activeSession.context,
1916
+ activeSession.clarificationQuestions
1917
+ );
1875
1918
  for (const scenario of activeSession.bddScenarios) {
1876
1919
  lines.push(chalk9__default.default.white(` Feature: ${scenario.feature}`));
1877
1920
  for (const s of scenario.scenarios.slice(0, 3)) {
@@ -1885,9 +1928,14 @@ async function executeWorkflow(ctx) {
1885
1928
  }
1886
1929
  if (activeSession.phase === "spec") {
1887
1930
  lines.push("");
1888
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 4/7: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
1931
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/8: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
1889
1932
  lines.push("");
1890
- activeSession.specItems = generateSpecItems(activeSession.requirement, activeSession.context, activeSession.bddScenarios);
1933
+ activeSession.specItems = generateSpecItems(
1934
+ activeSession.refinedRequirement,
1935
+ activeSession.context,
1936
+ activeSession.bddScenarios,
1937
+ activeSession.clarificationQuestions
1938
+ );
1891
1939
  const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
1892
1940
  lines.push(chalk9__default.default.green(" \u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u751F\u6210"));
1893
1941
  lines.push(chalk9__default.default.gray(` \u8DEF\u5F84: ${specPath}`));
@@ -1910,7 +1958,7 @@ async function executeWorkflow(ctx) {
1910
1958
  }
1911
1959
  if (activeSession.phase === "tdd") {
1912
1960
  lines.push("");
1913
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/7: TDD \u6D4B\u8BD5\u751F\u6210 \u2501\u2501\u2501"));
1961
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/8: TDD \u6D4B\u8BD5\u751F\u6210 \u2501\u2501\u2501"));
1914
1962
  lines.push("");
1915
1963
  activeSession.testFiles = await generateTests(ctx.options.workingDirectory, activeSession);
1916
1964
  lines.push(chalk9__default.default.green(" \u2713 \u6D4B\u8BD5\u6587\u4EF6\u5DF2\u751F\u6210"));
@@ -1921,20 +1969,69 @@ async function executeWorkflow(ctx) {
1921
1969
  }
1922
1970
  if (activeSession.phase === "develop") {
1923
1971
  lines.push("");
1924
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/7: \u5F00\u53D1\u5B9E\u73B0 \u2501\u2501\u2501"));
1972
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 7/8: \u5F00\u53D1\u5B9E\u73B0 \u2501\u2501\u2501"));
1925
1973
  lines.push("");
1926
- lines.push(chalk9__default.default.yellow(" \u{1F4DD} \u5F00\u53D1\u9636\u6BB5"));
1927
- lines.push(chalk9__default.default.gray(" \u8BF7\u8C03\u7528 $frontend-dev \u6267\u884C\u5F00\u53D1\u4EFB\u52A1"));
1928
- lines.push(chalk9__default.default.gray(" \u6216\u624B\u52A8\u5B9E\u73B0\u4EE3\u7801\u540E\u8F93\u5165 continue \u7EE7\u7EED"));
1929
- return { output: lines.join("\n") };
1974
+ lines.push(chalk9__default.default.yellow(" \u{1F680} \u6B63\u5728\u8C03\u7528 AI \u751F\u6210\u4EE3\u7801..."));
1975
+ try {
1976
+ const developResult = await executeDevelopment(ctx, activeSession);
1977
+ if (developResult.success) {
1978
+ lines.push(chalk9__default.default.green(" \u2713 \u4EE3\u7801\u751F\u6210\u5B8C\u6210"));
1979
+ for (const file of developResult.files) {
1980
+ lines.push(chalk9__default.default.gray(` - ${file}`));
1981
+ }
1982
+ activeSession.implFiles = developResult.files;
1983
+ activeSession.phase = "review";
1984
+ } else {
1985
+ lines.push(chalk9__default.default.red(` \u2717 \u4EE3\u7801\u751F\u6210\u5931\u8D25: ${developResult.error}`));
1986
+ lines.push(chalk9__default.default.gray(" \u8BF7\u624B\u52A8\u5B9E\u73B0\u4EE3\u7801\u540E\u8F93\u5165 continue \u7EE7\u7EED"));
1987
+ return { output: lines.join("\n") };
1988
+ }
1989
+ } catch (error) {
1990
+ lines.push(chalk9__default.default.red(` \u2717 \u5F00\u53D1\u9636\u6BB5\u51FA\u9519: ${error.message}`));
1991
+ lines.push(chalk9__default.default.gray(" \u8BF7\u624B\u52A8\u5B9E\u73B0\u4EE3\u7801\u540E\u8F93\u5165 continue \u7EE7\u7EED"));
1992
+ return { output: lines.join("\n") };
1993
+ }
1930
1994
  }
1931
1995
  if (activeSession.phase === "review") {
1932
1996
  lines.push("");
1933
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 7/7: \u4EE3\u7801\u5BA1\u6838 \u2501\u2501\u2501"));
1997
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 8/8: \u4EE3\u7801\u5BA1\u6838 \u2501\u2501\u2501"));
1934
1998
  lines.push("");
1935
- lines.push(chalk9__default.default.yellow(" \u{1F50D} \u4EE3\u7801\u5BA1\u6838\u9636\u6BB5"));
1936
- lines.push(chalk9__default.default.gray(" \u8BF7\u8C03\u7528 $code-reviewer \u6267\u884C\u4EE3\u7801\u5BA1\u6838"));
1937
- lines.push(chalk9__default.default.gray(" \u6216\u8F93\u5165 review \u5B8C\u6210\u5BA1\u6838"));
1999
+ lines.push(chalk9__default.default.yellow(" \u{1F50D} \u6B63\u5728\u8FDB\u884C\u4EE3\u7801\u5BA1\u6838..."));
2000
+ try {
2001
+ const reviewResult = await executeReview(ctx, activeSession);
2002
+ if (reviewResult.passed) {
2003
+ lines.push(chalk9__default.default.green(" \u2713 \u4EE3\u7801\u5BA1\u6838\u901A\u8FC7"));
2004
+ if (reviewResult.suggestions.length > 0) {
2005
+ lines.push(chalk9__default.default.gray(" \u5EFA\u8BAE:"));
2006
+ for (const s of reviewResult.suggestions.slice(0, 3)) {
2007
+ lines.push(chalk9__default.default.gray(` - ${s}`));
2008
+ }
2009
+ }
2010
+ await archiveWorkflow(ctx.options.workingDirectory);
2011
+ const summary = activeSession.refinedRequirement;
2012
+ activeSession = null;
2013
+ lines.push("");
2014
+ lines.push(chalk9__default.default.green.bold("\u{1F389} \u5DE5\u4F5C\u6D41\u5DF2\u5B8C\u6210\uFF01"));
2015
+ lines.push(chalk9__default.default.gray(`\u9700\u6C42: ${summary.slice(0, 60)}${summary.length > 60 ? "..." : ""}`));
2016
+ lines.push("");
2017
+ lines.push(chalk9__default.default.cyan("\u4F7F\u7528 /new <\u9700\u6C42> \u5F00\u59CB\u65B0\u7684\u5DE5\u4F5C\u6D41"));
2018
+ return { output: lines.join("\n") };
2019
+ } else {
2020
+ lines.push(chalk9__default.default.red(" \u2717 \u4EE3\u7801\u5BA1\u6838\u672A\u901A\u8FC7"));
2021
+ lines.push(chalk9__default.default.gray(" \u95EE\u9898:"));
2022
+ for (const issue of reviewResult.issues.slice(0, 5)) {
2023
+ lines.push(chalk9__default.default.red(` - ${issue}`));
2024
+ }
2025
+ lines.push("");
2026
+ lines.push(chalk9__default.default.yellow(" \u8BF7\u4FEE\u590D\u95EE\u9898\u540E\u8F93\u5165 y \u91CD\u65B0\u5BA1\u6838"));
2027
+ lines.push(chalk9__default.default.gray(" \u6216\u8F93\u5165 n \u56DE\u9000\u5230\u89C4\u683C\u9636\u6BB5"));
2028
+ return { output: lines.join("\n") };
2029
+ }
2030
+ } catch (error) {
2031
+ lines.push(chalk9__default.default.red(` \u2717 \u5BA1\u6838\u9636\u6BB5\u51FA\u9519: ${error.message}`));
2032
+ lines.push(chalk9__default.default.gray(" \u8F93\u5165 pass \u5F3A\u5236\u901A\u8FC7\uFF0C\u6216 fix \u4FEE\u590D\u95EE\u9898"));
2033
+ return { output: lines.join("\n") };
2034
+ }
1938
2035
  }
1939
2036
  return { output: lines.join("\n") };
1940
2037
  } catch (error) {
@@ -1951,14 +2048,58 @@ async function handleWorkflowInput(input, ctx) {
1951
2048
  output: chalk9__default.default.yellow("\u2713 \u5DE5\u4F5C\u6D41\u5DF2\u53D6\u6D88")
1952
2049
  };
1953
2050
  }
2051
+ if (activeSession.phase === "clarify") {
2052
+ if (trimmed === "done" || trimmed === "\u5B8C\u6210" || trimmed === "\u8DF3\u8FC7" || trimmed === "skip") {
2053
+ activeSession.refinedRequirement = buildRefinedRequirement(activeSession);
2054
+ activeSession.phase = "analysis";
2055
+ return executeWorkflow(ctx);
2056
+ }
2057
+ activeSession.clarificationQuestions.filter((q) => q.answered).length;
2058
+ const unansweredQuestions = activeSession.clarificationQuestions.filter((q) => !q.answered);
2059
+ if (unansweredQuestions.length > 0) {
2060
+ const question = unansweredQuestions[0];
2061
+ question.answer = input.trim();
2062
+ question.answered = true;
2063
+ activeSession.refinedRequirement = buildRefinedRequirement(activeSession);
2064
+ const remaining = activeSession.clarificationQuestions.filter((q) => !q.answered);
2065
+ if (remaining.length > 0) {
2066
+ activeSession.clarityScore = calculateClarityScore(activeSession.clarificationQuestions);
2067
+ const lines = [];
2068
+ lines.push(chalk9__default.default.green(" \u2713 \u5DF2\u8BB0\u5F55"));
2069
+ lines.push("");
2070
+ lines.push(chalk9__default.default.yellow(" \u7EE7\u7EED\u56DE\u7B54\uFF1A"));
2071
+ for (let i = 0; i < Math.min(remaining.length, 3); i++) {
2072
+ const q = remaining[i];
2073
+ lines.push(chalk9__default.default.white(` ${i + 1}. ${q.question}`));
2074
+ }
2075
+ lines.push("");
2076
+ lines.push(chalk9__default.default.gray(' \u8F93\u5165\u56DE\u7B54\uFF0C\u6216 "done" \u8DF3\u8FC7'));
2077
+ return { output: lines.join("\n") };
2078
+ }
2079
+ activeSession.clarityScore = 1;
2080
+ activeSession.phase = "analysis";
2081
+ return executeWorkflow(ctx);
2082
+ }
2083
+ activeSession.phase = "analysis";
2084
+ return executeWorkflow(ctx);
2085
+ }
1954
2086
  if (activeSession.phase === "spec") {
1955
2087
  if (trimmed === "y" || trimmed === "yes" || trimmed === "\u786E\u8BA4") {
1956
2088
  activeSession.phase = "tdd";
1957
2089
  return executeWorkflow(ctx);
1958
2090
  }
1959
2091
  if (trimmed === "n" || trimmed === "no" || trimmed === "\u91CD\u65B0") {
1960
- activeSession.bddScenarios = generateBDDScenarios(activeSession.requirement, activeSession.context);
1961
- activeSession.specItems = generateSpecItems(activeSession.requirement, activeSession.context, activeSession.bddScenarios);
2092
+ activeSession.bddScenarios = generateBDDScenarios(
2093
+ activeSession.refinedRequirement,
2094
+ activeSession.context,
2095
+ activeSession.clarificationQuestions
2096
+ );
2097
+ activeSession.specItems = generateSpecItems(
2098
+ activeSession.refinedRequirement,
2099
+ activeSession.context,
2100
+ activeSession.bddScenarios,
2101
+ activeSession.clarificationQuestions
2102
+ );
1962
2103
  const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
1963
2104
  return {
1964
2105
  output: chalk9__default.default.cyan("\u{1F504} \u89C4\u683C\u5DF2\u91CD\u65B0\u751F\u6210") + chalk9__default.default.gray(`
@@ -1973,24 +2114,347 @@ async function handleWorkflowInput(input, ctx) {
1973
2114
  }
1974
2115
  }
1975
2116
  if (activeSession.phase === "review") {
1976
- if (trimmed === "review" || trimmed === "\u5BA1\u6838" || trimmed === "pass" || trimmed === "\u901A\u8FC7") {
2117
+ if (trimmed === "pass" || trimmed === "\u901A\u8FC7" || trimmed === "\u5F3A\u5236\u901A\u8FC7") {
1977
2118
  await archiveWorkflow(ctx.options.workingDirectory);
1978
- const summary = activeSession.requirement;
2119
+ const summary = activeSession.refinedRequirement;
1979
2120
  activeSession = null;
1980
2121
  return {
1981
2122
  output: chalk9__default.default.green("\u2713 \u5DE5\u4F5C\u6D41\u5DF2\u5B8C\u6210") + chalk9__default.default.gray(`
1982
- \u9700\u6C42: ${summary}`) + chalk9__default.default.cyan("\n\n\u4F7F\u7528 /new <\u9700\u6C42> \u5F00\u59CB\u65B0\u7684\u5DE5\u4F5C\u6D41")
2123
+ \u9700\u6C42: ${summary.slice(0, 60)}${summary.length > 60 ? "..." : ""}`) + chalk9__default.default.cyan("\n\n\u4F7F\u7528 /new <\u9700\u6C42> \u5F00\u59CB\u65B0\u7684\u5DE5\u4F5C\u6D41")
1983
2124
  };
1984
2125
  }
1985
- if (trimmed === "fail" || trimmed === "\u5931\u8D25" || trimmed === "reject" || trimmed === "\u62D2\u7EDD") {
2126
+ if (trimmed === "y" || trimmed === "yes" || trimmed === "\u91CD\u65B0\u5BA1\u6838" || trimmed === "retry") {
2127
+ return executeWorkflow(ctx);
2128
+ }
2129
+ if (trimmed === "n" || trimmed === "no" || trimmed === "\u56DE\u9000" || trimmed === "rollback") {
1986
2130
  activeSession.phase = "spec";
2131
+ return executeWorkflow(ctx);
2132
+ }
2133
+ if (trimmed === "fix" || trimmed === "\u4FEE\u590D") {
1987
2134
  return {
1988
- output: chalk9__default.default.yellow("\u21A9\uFE0F \u5BA1\u6838\u672A\u901A\u8FC7\uFF0C\u56DE\u9000\u5230\u89C4\u683C\u9636\u6BB5") + chalk9__default.default.gray("\n\u8BF7\u91CD\u65B0\u786E\u8BA4\u6216\u4FEE\u6539\u89C4\u683C") + chalk9__default.default.yellow("\n\n\u4F7F\u7528 y \u786E\u8BA4\uFF0Cn \u91CD\u65B0\u751F\u6210")
2135
+ output: chalk9__default.default.yellow("\u{1F4DD} \u8BF7\u624B\u52A8\u4FEE\u590D\u4EE3\u7801\u95EE\u9898") + chalk9__default.default.gray("\n\u4FEE\u590D\u5B8C\u6210\u540E\u8F93\u5165 y \u91CD\u65B0\u5BA1\u6838") + chalk9__default.default.gray("\n\u6216\u8F93\u5165 n \u56DE\u9000\u5230\u89C4\u683C\u9636\u6BB5")
1989
2136
  };
1990
2137
  }
1991
2138
  }
1992
2139
  return null;
1993
2140
  }
2141
+ function analyzeRequirementClarity(requirement, context) {
2142
+ const questions = [];
2143
+ let score = 0.5;
2144
+ if (requirement.length < 10) {
2145
+ score -= 0.2;
2146
+ questions.push({
2147
+ id: "q-length",
2148
+ question: "\u9700\u6C42\u63CF\u8FF0\u8F83\u77ED\uFF0C\u80FD\u5426\u8BE6\u7EC6\u8BF4\u660E\u5177\u4F53\u8981\u5B9E\u73B0\u4EC0\u4E48\u529F\u80FD\uFF1F",
2149
+ category: "scope",
2150
+ answered: false
2151
+ });
2152
+ } else if (requirement.length >= 50) {
2153
+ score += 0.1;
2154
+ }
2155
+ const actionKeywords = ["\u5B9E\u73B0", "\u6DFB\u52A0", "\u4FEE\u6539", "\u5220\u9664", "\u4F18\u5316", "\u4FEE\u590D", "\u91CD\u6784", "\u5F00\u53D1", "\u521B\u5EFA", "\u8BBE\u8BA1"];
2156
+ const hasAction = actionKeywords.some((kw) => requirement.includes(kw));
2157
+ if (!hasAction) {
2158
+ score -= 0.15;
2159
+ questions.push({
2160
+ id: "q-action",
2161
+ question: "\u8FD9\u662F\u4E00\u4E2A\u65B0\u529F\u80FD\u3001\u4FEE\u6539\u8FD8\u662F\u4FEE\u590D\uFF1F\u8BF7\u8BF4\u660E\u5177\u4F53\u8981\u505A\u4EC0\u4E48\u3002",
2162
+ category: "scope",
2163
+ answered: false
2164
+ });
2165
+ } else {
2166
+ score += 0.1;
2167
+ }
2168
+ if (requirement.match(/界面|页面|组件|按钮|表单|弹窗|布局|样式|UI/)) {
2169
+ score += 0.1;
2170
+ if (!requirement.match(/在.*页面|在.*位置|显示在|位于/)) {
2171
+ questions.push({
2172
+ id: "q-ui-position",
2173
+ question: "\u8FD9\u4E2A\u529F\u80FD\u5E94\u8BE5\u653E\u5728\u54EA\u4E2A\u9875\u9762\u6216\u4F4D\u7F6E\uFF1F",
2174
+ category: "ui",
2175
+ answered: false
2176
+ });
2177
+ }
2178
+ } else {
2179
+ questions.push({
2180
+ id: "q-ui-need",
2181
+ question: "\u8FD9\u4E2A\u529F\u80FD\u9700\u8981\u7528\u6237\u754C\u9762\u5417\uFF1F\u5982\u679C\u9700\u8981\uFF0C\u5927\u6982\u957F\u4EC0\u4E48\u6837\uFF1F",
2182
+ category: "ui",
2183
+ answered: false
2184
+ });
2185
+ }
2186
+ if (requirement.match(/数据|存储|保存|读取|API|接口|数据库|缓存/)) {
2187
+ score += 0.1;
2188
+ if (!requirement.match(/从.*获取|调用.*接口|读取.*数据|来源/)) {
2189
+ questions.push({
2190
+ id: "q-data-source",
2191
+ question: "\u6570\u636E\u4ECE\u54EA\u91CC\u6765\uFF1F\u662F\u8C03\u7528API\u3001\u672C\u5730\u5B58\u50A8\u8FD8\u662F\u5176\u4ED6\u6765\u6E90\uFF1F",
2192
+ category: "data",
2193
+ answered: false
2194
+ });
2195
+ }
2196
+ }
2197
+ if (requirement.match(/点击|输入|选择|拖动|滑动|交互|操作/)) {
2198
+ score += 0.1;
2199
+ } else {
2200
+ if (hasAction && requirement.match(/功能|特性|模块/)) {
2201
+ questions.push({
2202
+ id: "q-interaction",
2203
+ question: "\u7528\u6237\u5982\u4F55\u64CD\u4F5C\u8FD9\u4E2A\u529F\u80FD\uFF1F\u6709\u4EC0\u4E48\u4EA4\u4E92\u6D41\u7A0B\uFF1F",
2204
+ category: "interaction",
2205
+ answered: false
2206
+ });
2207
+ }
2208
+ }
2209
+ if (requirement.match(/异常|错误|失败|边界|特殊情况|空值|验证/)) {
2210
+ score += 0.15;
2211
+ } else {
2212
+ if (requirement.match(/功能|输入|表单|数据/)) {
2213
+ questions.push({
2214
+ id: "q-edge",
2215
+ question: "\u6709\u4EC0\u4E48\u7279\u6B8A\u60C5\u51B5\u6216\u8FB9\u754C\u6761\u4EF6\u9700\u8981\u5904\u7406\uFF1F\u6BD4\u5982\u8F93\u5165\u4E3A\u7A7A\u3001\u6570\u636E\u52A0\u8F7D\u5931\u8D25\u7B49\u3002",
2216
+ category: "edge",
2217
+ answered: false
2218
+ });
2219
+ }
2220
+ }
2221
+ if (requirement.match(/https?:\/\/|参考|参照|类似/)) {
2222
+ score += 0.15;
2223
+ }
2224
+ if (context.framework) {
2225
+ score += 0.05;
2226
+ }
2227
+ const limitedQuestions = questions.slice(0, 5);
2228
+ score = Math.max(0, Math.min(1, score));
2229
+ return { score, questions: limitedQuestions };
2230
+ }
2231
+ function calculateClarityScore(questions) {
2232
+ const answered = questions.filter((q) => q.answered).length;
2233
+ if (questions.length === 0) return 1;
2234
+ return 0.5 + answered / questions.length * 0.5;
2235
+ }
2236
+ function buildRefinedRequirement(session) {
2237
+ const parts = [session.requirement];
2238
+ for (const q of session.clarificationQuestions) {
2239
+ if (q.answered && q.answer) {
2240
+ parts.push(`
2241
+ \u3010${getCategoryLabel(q.category)}\u3011${q.answer}`);
2242
+ }
2243
+ }
2244
+ return parts.join("");
2245
+ }
2246
+ function getCategoryLabel(category) {
2247
+ const labels = {
2248
+ scope: "\u8303\u56F4",
2249
+ ui: "\u754C\u9762",
2250
+ data: "\u6570\u636E",
2251
+ interaction: "\u4EA4\u4E92",
2252
+ edge: "\u8FB9\u754C",
2253
+ tech: "\u6280\u672F"
2254
+ };
2255
+ return labels[category] || category;
2256
+ }
2257
+ async function executeDevelopment(ctx, session) {
2258
+ const workingDir = ctx.options.workingDirectory;
2259
+ const files = [];
2260
+ try {
2261
+ const systemPrompt = buildDevelopmentPrompt(session);
2262
+ const messages = [
2263
+ {
2264
+ role: "system",
2265
+ content: `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u524D\u7AEF\u5F00\u53D1\u5DE5\u7A0B\u5E08\u3002\u8BF7\u6839\u636E\u9700\u6C42\u89C4\u683C\u751F\u6210\u4EE3\u7801\u5B9E\u73B0\u3002
2266
+
2267
+ \u8981\u6C42\uFF1A
2268
+ 1. \u751F\u6210\u5B8C\u6574\u3001\u53EF\u8FD0\u884C\u7684\u4EE3\u7801
2269
+ 2. \u9075\u5FAA\u9879\u76EE\u73B0\u6709\u7684\u4EE3\u7801\u98CE\u683C\u548C\u89C4\u8303
2270
+ 3. \u4F7F\u7528\u9879\u76EE\u6307\u5B9A\u7684\u6280\u672F\u6808
2271
+ 4. \u4EE3\u7801\u8981\u6709\u9002\u5F53\u7684\u6CE8\u91CA
2272
+ 5. \u8FD4\u56DE\u683C\u5F0F\uFF1A\u6BCF\u4E2A\u6587\u4EF6\u7528 \`\`\`filename \u4EE3\u7801 \`\`\` \u5305\u88F9
2273
+
2274
+ \u9879\u76EE\u4FE1\u606F\uFF1A
2275
+ - \u540D\u79F0: ${session.context?.name}
2276
+ - \u6846\u67B6: ${session.context?.framework || "\u672A\u6307\u5B9A"}
2277
+ - \u6280\u672F\u6808: ${session.context?.techStack.join(", ") || "\u672A\u6307\u5B9A"}
2278
+
2279
+ ${session.context?.devStandards ? `\u5F00\u53D1\u89C4\u8303\uFF1A
2280
+ ${session.context.devStandards.slice(0, 2e3)}` : ""}`
2281
+ },
2282
+ {
2283
+ role: "user",
2284
+ content: systemPrompt
2285
+ }
2286
+ ];
2287
+ const response = await ctx.modelService.sendMessage(messages, {
2288
+ temperature: 0.3,
2289
+ maxTokens: 8e3,
2290
+ agent: "frontend-dev"
2291
+ });
2292
+ const codeBlocks = parseCodeBlocks(response.content);
2293
+ for (const block of codeBlocks) {
2294
+ const filePath = path7__namespace.join(workingDir, block.filename);
2295
+ const dir = path7__namespace.dirname(filePath);
2296
+ await fs7__namespace.mkdir(dir, { recursive: true });
2297
+ await fs7__namespace.writeFile(filePath, block.code, "utf-8");
2298
+ files.push(block.filename);
2299
+ }
2300
+ if (files.length === 0) {
2301
+ const implDir = path7__namespace.join(workingDir, "src", "features");
2302
+ await fs7__namespace.mkdir(implDir, { recursive: true });
2303
+ const featureName = session.specItems[0]?.title || "feature";
2304
+ const fileName = `${featureName.replace(/[^a-zA-Z0-9]/g, "_")}.ts`;
2305
+ const filePath = path7__namespace.join(implDir, fileName);
2306
+ const stubCode = `/**
2307
+ * ${session.requirement}
2308
+ *
2309
+ * TODO: \u6B64\u6587\u4EF6\u7531 AI \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u6839\u636E\u9700\u6C42\u5B8C\u5584\u5B9E\u73B0
2310
+ */
2311
+
2312
+ export function ${featureName.replace(/[^a-zA-Z0-9]/g, "")}() {
2313
+ // TODO: \u5B9E\u73B0\u529F\u80FD
2314
+ console.log('${featureName} - \u5F85\u5B9E\u73B0');
2315
+ }
2316
+ `;
2317
+ await fs7__namespace.writeFile(filePath, stubCode, "utf-8");
2318
+ files.push(`src/features/${fileName}`);
2319
+ }
2320
+ return { success: true, files };
2321
+ } catch (error) {
2322
+ return {
2323
+ success: false,
2324
+ files: [],
2325
+ error: error.message
2326
+ };
2327
+ }
2328
+ }
2329
+ function buildDevelopmentPrompt(session) {
2330
+ const lines = [];
2331
+ lines.push("## \u9700\u6C42\u63CF\u8FF0");
2332
+ lines.push(session.refinedRequirement);
2333
+ lines.push("");
2334
+ lines.push("## BDD \u573A\u666F");
2335
+ for (const scenario of session.bddScenarios) {
2336
+ lines.push(`### ${scenario.feature}`);
2337
+ for (const s of scenario.scenarios) {
2338
+ lines.push(`- ${s.name}`);
2339
+ }
2340
+ }
2341
+ lines.push("");
2342
+ lines.push("## \u4EFB\u52A1\u5217\u8868");
2343
+ for (const item of session.specItems) {
2344
+ lines.push(`- [${item.id}] ${item.title}: ${item.description}`);
2345
+ }
2346
+ lines.push("");
2347
+ lines.push("\u8BF7\u6839\u636E\u4EE5\u4E0A\u9700\u6C42\u89C4\u683C\u751F\u6210\u4EE3\u7801\u5B9E\u73B0\u3002");
2348
+ return lines.join("\n");
2349
+ }
2350
+ function parseCodeBlocks(content) {
2351
+ const blocks = [];
2352
+ const regex = /```(\S+)\n([\s\S]*?)```/g;
2353
+ let match;
2354
+ while ((match = regex.exec(content)) !== null) {
2355
+ const filename = match[1];
2356
+ const code = match[2].trim();
2357
+ if (["text", "json", "markdown", "md"].includes(filename.toLowerCase())) {
2358
+ continue;
2359
+ }
2360
+ blocks.push({ filename, code });
2361
+ }
2362
+ return blocks;
2363
+ }
2364
+ async function executeReview(ctx, session) {
2365
+ const workingDir = ctx.options.workingDirectory;
2366
+ const issues = [];
2367
+ const suggestions = [];
2368
+ try {
2369
+ const codeContents = [];
2370
+ for (const file of session.implFiles) {
2371
+ try {
2372
+ const content = await fs7__namespace.readFile(path7__namespace.join(workingDir, file), "utf-8");
2373
+ codeContents.push(`// ${file}
2374
+ ${content}`);
2375
+ } catch {
2376
+ }
2377
+ }
2378
+ const testContents = [];
2379
+ for (const file of session.testFiles) {
2380
+ try {
2381
+ const content = await fs7__namespace.readFile(path7__namespace.join(workingDir, file), "utf-8");
2382
+ testContents.push(`// ${file}
2383
+ ${content}`);
2384
+ } catch {
2385
+ }
2386
+ }
2387
+ const messages = [
2388
+ {
2389
+ role: "system",
2390
+ content: `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u4EE3\u7801\u5BA1\u6838\u4E13\u5BB6\u3002\u8BF7\u5BA1\u6838\u4EE5\u4E0B\u4EE3\u7801\u5B9E\u73B0\u662F\u5426\u7B26\u5408\u9700\u6C42\u89C4\u683C\u3002
2391
+
2392
+ \u5BA1\u6838\u6807\u51C6\uFF1A
2393
+ 1. \u4EE3\u7801\u662F\u5426\u6B63\u786E\u5B9E\u73B0\u4E86\u9700\u6C42\u89C4\u683C\u4E2D\u7684\u529F\u80FD
2394
+ 2. \u4EE3\u7801\u8D28\u91CF\uFF08\u53EF\u8BFB\u6027\u3001\u53EF\u7EF4\u62A4\u6027\uFF09
2395
+ 3. \u6F5C\u5728\u7684 bug \u548C\u8FB9\u754C\u60C5\u51B5\u5904\u7406
2396
+ 4. \u4EE3\u7801\u98CE\u683C\u662F\u5426\u7B26\u5408\u9879\u76EE\u89C4\u8303
2397
+ 5. \u6D4B\u8BD5\u8986\u76D6\u662F\u5426\u5145\u5206
2398
+
2399
+ \u8FD4\u56DE\u683C\u5F0F\uFF1A
2400
+ - \u5982\u679C\u901A\u8FC7\u5BA1\u6838\uFF0C\u8FD4\u56DE "\u5BA1\u6838\u901A\u8FC7" \u5E76\u5217\u51FA\u6539\u8FDB\u5EFA\u8BAE
2401
+ - \u5982\u679C\u4E0D\u901A\u8FC7\uFF0C\u5217\u51FA\u5177\u4F53\u95EE\u9898
2402
+
2403
+ \u9879\u76EE\u4FE1\u606F\uFF1A
2404
+ - \u6846\u67B6: ${session.context?.framework || "\u672A\u6307\u5B9A"}
2405
+ - \u6280\u672F\u6808: ${session.context?.techStack.join(", ") || "\u672A\u6307\u5B9A"}
2406
+
2407
+ ${session.context?.devStandards ? `\u5F00\u53D1\u89C4\u8303\uFF1A
2408
+ ${session.context.devStandards.slice(0, 1e3)}` : ""}`
2409
+ },
2410
+ {
2411
+ role: "user",
2412
+ content: `## \u9700\u6C42\u89C4\u683C
2413
+ ${session.refinedRequirement}
2414
+
2415
+ ## \u4EFB\u52A1\u5217\u8868
2416
+ ${session.specItems.map((item) => `- [${item.id}] ${item.title}`).join("\n")}
2417
+
2418
+ ## \u5B9E\u73B0\u4EE3\u7801
2419
+ ${codeContents.join("\n\n") || "\uFF08\u65E0\u4EE3\u7801\u6587\u4EF6\uFF09"}
2420
+
2421
+ ## \u6D4B\u8BD5\u4EE3\u7801
2422
+ ${testContents.join("\n\n") || "\uFF08\u65E0\u6D4B\u8BD5\u6587\u4EF6\uFF09"}
2423
+
2424
+ \u8BF7\u5BA1\u6838\u4EE5\u4E0A\u4EE3\u7801\u5B9E\u73B0\u3002`
2425
+ }
2426
+ ];
2427
+ const response = await ctx.modelService.sendMessage(messages, {
2428
+ temperature: 0.2,
2429
+ maxTokens: 2e3,
2430
+ agent: "code-reviewer"
2431
+ });
2432
+ const result = response.content;
2433
+ const passed = result.includes("\u5BA1\u6838\u901A\u8FC7") || result.includes("\u901A\u8FC7") || !result.includes("\u4E0D\u901A\u8FC7");
2434
+ const issueMatches = result.match(/问题[::]\s*([\s\S]*?)(?=建议|$)/i);
2435
+ if (issueMatches) {
2436
+ const issueList = issueMatches[1].split(/[\n-]/).filter((s) => s.trim());
2437
+ issues.push(...issueList.map((s) => s.trim()).filter((s) => s));
2438
+ }
2439
+ const suggestionMatches = result.match(/建议[::]\s*([\s\S]*?)$/i);
2440
+ if (suggestionMatches) {
2441
+ const suggestionList = suggestionMatches[1].split(/[\n-]/).filter((s) => s.trim());
2442
+ suggestions.push(...suggestionList.map((s) => s.trim()).filter((s) => s));
2443
+ }
2444
+ if (issues.length === 0 && !passed) {
2445
+ const lines = result.split("\n").filter((l) => l.includes("\u95EE\u9898") || l.includes("\u9519\u8BEF") || l.includes("\u7F3A\u9677"));
2446
+ issues.push(...lines.map((l) => l.replace(/^[-*]\s*/, "").trim()).filter((l) => l));
2447
+ }
2448
+ if (suggestions.length === 0) {
2449
+ const lines = result.split("\n").filter((l) => l.includes("\u5EFA\u8BAE") || l.includes("\u6539\u8FDB") || l.includes("\u4F18\u5316"));
2450
+ suggestions.push(...lines.map((l) => l.replace(/^[-*]\s*/, "").trim()).filter((l) => l));
2451
+ }
2452
+ return { passed, issues, suggestions };
2453
+ } catch (error) {
2454
+ suggestions.push(`\u5BA1\u6838\u8FC7\u7A0B\u51FA\u9519: ${error.message}`);
2455
+ return { passed: true, issues, suggestions };
2456
+ }
2457
+ }
1994
2458
  async function readProjectContext(workingDir) {
1995
2459
  const context = {
1996
2460
  name: path7__namespace.basename(workingDir),
@@ -2072,8 +2536,11 @@ function analyzeComplexity(requirement, context) {
2072
2536
  if (!context.framework) score += 0.5;
2073
2537
  return Math.max(1, Math.min(10, Math.round(score)));
2074
2538
  }
2075
- function generateBDDScenarios(requirement, context) {
2539
+ function generateBDDScenarios(requirement, context, questions) {
2076
2540
  const scenarios = [];
2541
+ questions.find((q) => q.category === "ui" && q.answered)?.answer;
2542
+ const interactionAnswer = questions.find((q) => q.category === "interaction" && q.answered)?.answer;
2543
+ const edgeAnswer = questions.find((q) => q.category === "edge" && q.answered)?.answer;
2077
2544
  const features = extractFeatures(requirement);
2078
2545
  for (const feature of features) {
2079
2546
  const scenario = {
@@ -2087,12 +2554,20 @@ function generateBDDScenarios(requirement, context) {
2087
2554
  when: [`\u7528\u6237\u6267\u884C "${feature.title}" \u64CD\u4F5C`],
2088
2555
  then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u5E76\u8FD4\u56DE\u9884\u671F\u7ED3\u679C`]
2089
2556
  });
2090
- if (feature.hasInput) {
2557
+ if (interactionAnswer) {
2091
2558
  scenario.scenarios.push({
2092
- name: `\u8FB9\u754C\u60C5\u51B5: \u8F93\u5165\u9A8C\u8BC1`,
2093
- given: [`\u7528\u6237\u8FDB\u5165\u8F93\u5165\u754C\u9762`],
2094
- when: [`\u7528\u6237\u8F93\u5165\u8FB9\u754C\u503C\u6216\u7A7A\u503C`],
2095
- then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u8FB9\u754C\u60C5\u51B5`]
2559
+ name: `\u4EA4\u4E92\u6D41\u7A0B: \u7528\u6237\u64CD\u4F5C`,
2560
+ given: [`\u7528\u6237\u8FDB\u5165\u529F\u80FD\u754C\u9762`],
2561
+ when: [`\u7528\u6237\u6309\u7167\u4EE5\u4E0B\u6D41\u7A0B\u64CD\u4F5C: ${interactionAnswer}`],
2562
+ then: [`\u7CFB\u7EDF\u54CD\u5E94\u5E76\u5B8C\u6210\u529F\u80FD`]
2563
+ });
2564
+ }
2565
+ if (feature.hasInput || edgeAnswer) {
2566
+ scenario.scenarios.push({
2567
+ name: `\u8FB9\u754C\u60C5\u51B5: \u5F02\u5E38\u5904\u7406`,
2568
+ given: [`\u7528\u6237\u8FDB\u5165\u529F\u80FD\u754C\u9762`],
2569
+ when: [`\u53D1\u751F\u5F02\u5E38\u60C5\u51B5${edgeAnswer ? `: ${edgeAnswer}` : ""}`],
2570
+ then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u5F02\u5E38\u5E76\u7ED9\u51FA\u63D0\u793A`]
2096
2571
  });
2097
2572
  }
2098
2573
  scenarios.push(scenario);
@@ -2139,7 +2614,7 @@ function extractFeatures(requirement) {
2139
2614
  }
2140
2615
  return features;
2141
2616
  }
2142
- function generateSpecItems(requirement, context, bddScenarios) {
2617
+ function generateSpecItems(requirement, context, bddScenarios, questions) {
2143
2618
  const items = [];
2144
2619
  let id = 1;
2145
2620
  for (const scenario of bddScenarios) {
@@ -2176,11 +2651,33 @@ function formatSpecFile(session) {
2176
2651
  lines.push(`# \u9700\u6C42\u89C4\u683C: ${session.requirement.slice(0, 50)}`);
2177
2652
  lines.push("");
2178
2653
  lines.push(`> \u53D8\u66F4ID: ${session.id}`);
2654
+ lines.push(`> \u9700\u6C42\u6E05\u6670\u5EA6: ${Math.round(session.clarityScore * 100)}%`);
2179
2655
  lines.push(`> \u590D\u6742\u5EA6: ${session.complexity}/10`);
2180
2656
  lines.push(`> \u751F\u6210\u65F6\u95F4: ${session.createdAt.toISOString()}`);
2181
2657
  lines.push("");
2182
2658
  lines.push("---");
2183
2659
  lines.push("");
2660
+ if (session.refinedRequirement !== session.requirement) {
2661
+ lines.push("## \u9700\u6C42\u8BE6\u60C5");
2662
+ lines.push("");
2663
+ lines.push(session.refinedRequirement);
2664
+ lines.push("");
2665
+ lines.push("---");
2666
+ lines.push("");
2667
+ }
2668
+ if (session.clarificationQuestions.some((q) => q.answered)) {
2669
+ lines.push("## \u9700\u6C42\u6F84\u6E05");
2670
+ lines.push("");
2671
+ for (const q of session.clarificationQuestions) {
2672
+ if (q.answered) {
2673
+ lines.push(`**Q: ${q.question}**`);
2674
+ lines.push(`A: ${q.answer}`);
2675
+ lines.push("");
2676
+ }
2677
+ }
2678
+ lines.push("---");
2679
+ lines.push("");
2680
+ }
2184
2681
  lines.push("## BDD \u573A\u666F");
2185
2682
  lines.push("");
2186
2683
  for (const scenario of session.bddScenarios) {
@@ -2244,11 +2741,17 @@ async function archiveWorkflow(workingDir) {
2244
2741
  const content = `# \u5F52\u6863: ${activeSession.requirement.slice(0, 50)}
2245
2742
 
2246
2743
  > \u5F52\u6863\u65F6\u95F4: ${(/* @__PURE__ */ new Date()).toISOString()}
2744
+ > \u9700\u6C42\u6E05\u6670\u5EA6: ${Math.round(activeSession.clarityScore * 100)}%
2247
2745
  > \u590D\u6742\u5EA6: ${activeSession.complexity}/10
2248
2746
 
2747
+ ## \u9700\u6C42\u8BE6\u60C5
2748
+
2749
+ ${activeSession.refinedRequirement}
2750
+
2249
2751
  ## \u5B8C\u6210\u60C5\u51B5
2250
2752
 
2251
2753
  - [x] \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6
2754
+ - [x] \u9700\u6C42\u6F84\u6E05
2252
2755
  - [x] \u590D\u6742\u5EA6\u8BC4\u4F30
2253
2756
  - [x] BDD \u573A\u666F\u62C6\u89E3
2254
2757
  - [x] OpenSpec \u89C4\u683C
@@ -2275,6 +2778,7 @@ function generateComplexityBar(score) {
2275
2778
  function getPhaseLabel(phase) {
2276
2779
  const labels = {
2277
2780
  context: "\u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6",
2781
+ clarify: "\u9700\u6C42\u6F84\u6E05",
2278
2782
  analysis: "\u590D\u6742\u5EA6\u8BC4\u4F30",
2279
2783
  bdd: "BDD \u573A\u666F\u62C6\u89E3",
2280
2784
  spec: "OpenSpec \u89C4\u683C",
@@ -2290,12 +2794,13 @@ function getActiveSession() {
2290
2794
  function clearActiveSession() {
2291
2795
  activeSession = null;
2292
2796
  }
2293
- var MAX_FILE_SIZE2, COMPLEXITY_THRESHOLD, activeSession, new_default;
2797
+ var MAX_FILE_SIZE2, COMPLEXITY_THRESHOLD, CLARITY_THRESHOLD, activeSession, new_default;
2294
2798
  var init_new = __esm({
2295
2799
  "src/commands/new.ts"() {
2296
2800
  init_cjs_shims();
2297
2801
  MAX_FILE_SIZE2 = 1024 * 1024;
2298
2802
  COMPLEXITY_THRESHOLD = 6;
2803
+ CLARITY_THRESHOLD = 0.6;
2299
2804
  activeSession = null;
2300
2805
  new_default = handleNew;
2301
2806
  }
@@ -6879,6 +7384,7 @@ var STEP_DISPLAY_NAMES = {
6879
7384
  "apply": "\u5BA1\u67E5",
6880
7385
  "archive": "\u5F52\u6863",
6881
7386
  "context": "\u4E0A\u4E0B\u6587",
7387
+ "clarify": "\u6F84\u6E05",
6882
7388
  "analysis": "\u5206\u6790",
6883
7389
  "bdd": "BDD",
6884
7390
  "spec": "\u89C4\u683C",
@@ -6894,6 +7400,7 @@ var STEP_COLORS = {
6894
7400
  "apply": chalk9__default.default.yellow,
6895
7401
  "archive": chalk9__default.default.gray,
6896
7402
  "context": chalk9__default.default.magenta,
7403
+ "clarify": chalk9__default.default.yellow,
6897
7404
  "analysis": chalk9__default.default.blue,
6898
7405
  "bdd": chalk9__default.default.cyan,
6899
7406
  "spec": chalk9__default.default.green,