mcp-probe-kit 1.11.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -21
- package/build/index.js +21 -1
- package/build/schemas/index.d.ts +234 -0
- package/build/schemas/index.js +4 -0
- package/build/schemas/interview-tools.d.ts +72 -0
- package/build/schemas/interview-tools.js +64 -0
- package/build/schemas/orchestration-tools.d.ts +58 -0
- package/build/schemas/orchestration-tools.js +59 -0
- package/build/schemas/ui-ux-schemas.d.ts +248 -0
- package/build/schemas/ui-ux-schemas.js +147 -0
- package/build/tools/__tests__/start_ui.integration.test.d.ts +6 -0
- package/build/tools/__tests__/start_ui.integration.test.js +179 -0
- package/build/tools/__tests__/start_ui.property.test.d.ts +6 -0
- package/build/tools/__tests__/start_ui.property.test.js +263 -0
- package/build/tools/__tests__/start_ui.unit.test.d.ts +6 -0
- package/build/tools/__tests__/start_ui.unit.test.js +109 -0
- package/build/tools/ask_user.d.ts +17 -0
- package/build/tools/ask_user.js +124 -0
- package/build/tools/index.d.ts +7 -0
- package/build/tools/index.js +9 -0
- package/build/tools/init_component_catalog.d.ts +22 -0
- package/build/tools/init_component_catalog.js +809 -0
- package/build/tools/interview.d.ts +18 -0
- package/build/tools/interview.js +418 -0
- package/build/tools/render_ui.d.ts +22 -0
- package/build/tools/render_ui.js +384 -0
- package/build/tools/start_ralph.d.ts +16 -0
- package/build/tools/start_ralph.js +779 -0
- package/build/tools/start_ui.d.ts +25 -0
- package/build/tools/start_ui.js +299 -0
- package/build/tools/ui-ux-tools.d.ts +116 -0
- package/build/tools/ui-ux-tools.js +756 -0
- package/build/tools/ui-ux-tools.test.d.ts +6 -0
- package/build/tools/ui-ux-tools.test.js +132 -0
- package/build/utils/ascii-box-formatter.d.ts +29 -0
- package/build/utils/ascii-box-formatter.js +195 -0
- package/build/utils/bm25.d.ts +60 -0
- package/build/utils/bm25.js +139 -0
- package/build/utils/cache-manager.d.ts +65 -0
- package/build/utils/cache-manager.js +156 -0
- package/build/utils/design-docs-generator.d.ts +1 -0
- package/build/utils/design-docs-generator.js +1 -0
- package/build/utils/design-reasoning-engine.d.ts +158 -0
- package/build/utils/design-reasoning-engine.js +363 -0
- package/build/utils/design-system-json-formatter.d.ts +41 -0
- package/build/utils/design-system-json-formatter.js +165 -0
- package/build/utils/ui-data-loader.d.ts +56 -0
- package/build/utils/ui-data-loader.js +164 -0
- package/build/utils/ui-search-engine.d.ts +57 -0
- package/build/utils/ui-search-engine.js +123 -0
- package/build/utils/ui-sync.d.ts +13 -0
- package/build/utils/ui-sync.js +241 -0
- package/docs/BEST_PRACTICES.md +456 -6
- package/docs/HOW_TO_TRIGGER.md +195 -64
- package/docs/MCP-Probe-Kit-/344/275/277/347/224/250/346/211/213/345/206/214.html +158 -63
- package/docs/MCP-Probe-Kit-/344/275/277/347/224/250/346/211/213/345/206/214.md +872 -34
- package/package.json +18 -5
- package/docs/HOW_TO_TRIGGER.html +0 -243
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* interview - 需求访谈工具
|
|
3
|
+
* 在开发前通过结构化访谈澄清需求,避免理解偏差
|
|
4
|
+
* 生成访谈记录文件,供后续 start_feature/add_feature 使用
|
|
5
|
+
*/
|
|
6
|
+
export declare function interview(args: any): Promise<{
|
|
7
|
+
content: {
|
|
8
|
+
type: string;
|
|
9
|
+
text: string;
|
|
10
|
+
}[];
|
|
11
|
+
isError?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
content: {
|
|
14
|
+
type: string;
|
|
15
|
+
text: string;
|
|
16
|
+
}[];
|
|
17
|
+
isError: boolean;
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* interview - 需求访谈工具
|
|
3
|
+
* 在开发前通过结构化访谈澄清需求,避免理解偏差
|
|
4
|
+
* 生成访谈记录文件,供后续 start_feature/add_feature 使用
|
|
5
|
+
*/
|
|
6
|
+
import { parseArgs } from "../utils/parseArgs.js";
|
|
7
|
+
// 访谈问题模板(仅支持 feature 类型)
|
|
8
|
+
const FEATURE_INTERVIEW_TEMPLATE = {
|
|
9
|
+
title: "新功能需求访谈",
|
|
10
|
+
description: "通过结构化提问,帮助澄清功能需求,避免理解偏差和返工",
|
|
11
|
+
phases: [
|
|
12
|
+
{
|
|
13
|
+
name: "背景理解",
|
|
14
|
+
questions: [
|
|
15
|
+
{
|
|
16
|
+
id: "pain_point",
|
|
17
|
+
question: "这个功能要解决什么问题?用户的痛点是什么?",
|
|
18
|
+
required: true,
|
|
19
|
+
placeholder: "例如:用户需要频繁登录,体验不好",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "target_users",
|
|
23
|
+
question: "目标用户是谁?他们的使用场景是什么?",
|
|
24
|
+
required: true,
|
|
25
|
+
placeholder: "例如:C端用户,在移动端和PC端使用",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "business_driver",
|
|
29
|
+
question: "为什么现在需要这个功能?有什么业务驱动因素吗?",
|
|
30
|
+
required: false,
|
|
31
|
+
placeholder: "例如:竞品都有,用户反馈强烈",
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "功能边界",
|
|
37
|
+
questions: [
|
|
38
|
+
{
|
|
39
|
+
id: "core_value",
|
|
40
|
+
question: "这个功能的核心价值是什么?(用一句话描述)",
|
|
41
|
+
required: true,
|
|
42
|
+
placeholder: "例如:让用户能够安全便捷地访问系统",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "scope_include",
|
|
46
|
+
question: "功能范围包括哪些?",
|
|
47
|
+
required: true,
|
|
48
|
+
placeholder: "例如:邮箱登录、手机号登录、记住我、忘记密码",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "scope_exclude",
|
|
52
|
+
question: "功能范围不包括哪些?(明确边界)",
|
|
53
|
+
required: false,
|
|
54
|
+
placeholder: "例如:不包括第三方登录、不包括多因素认证",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "input_output",
|
|
58
|
+
question: "预期的输入和输出是什么?",
|
|
59
|
+
required: false,
|
|
60
|
+
placeholder: "例如:输入用户名密码,输出JWT token",
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "技术约束",
|
|
66
|
+
questions: [
|
|
67
|
+
{
|
|
68
|
+
id: "tech_stack",
|
|
69
|
+
question: "有什么技术栈或框架的限制吗?",
|
|
70
|
+
required: false,
|
|
71
|
+
placeholder: "例如:必须使用 React + TypeScript",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "performance",
|
|
75
|
+
question: "性能要求是什么?(响应时间、并发量等)",
|
|
76
|
+
required: false,
|
|
77
|
+
placeholder: "例如:登录响应时间 < 500ms,支持1000并发",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: "compatibility",
|
|
81
|
+
question: "需要考虑哪些兼容性问题?",
|
|
82
|
+
required: false,
|
|
83
|
+
placeholder: "例如:兼容 IE11、Safari、微信浏览器",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: "security",
|
|
87
|
+
question: "有安全或合规要求吗?",
|
|
88
|
+
required: false,
|
|
89
|
+
placeholder: "例如:密码加密存储、防暴力破解、GDPR合规",
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "验收标准",
|
|
95
|
+
questions: [
|
|
96
|
+
{
|
|
97
|
+
id: "success_criteria",
|
|
98
|
+
question: "如何判断这个功能是成功的?",
|
|
99
|
+
required: true,
|
|
100
|
+
placeholder: "例如:用户能够成功登录,登录成功率 > 99%",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "test_scenarios",
|
|
104
|
+
question: "有哪些关键的测试场景?",
|
|
105
|
+
required: false,
|
|
106
|
+
placeholder: "例如:正常登录、密码错误、账号不存在、网络异常",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: "metrics",
|
|
110
|
+
question: "上线后如何衡量效果?",
|
|
111
|
+
required: false,
|
|
112
|
+
placeholder: "例如:登录成功率、登录耗时、用户留存率",
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
// 辅助函数:从描述中提取功能名称
|
|
119
|
+
function extractFeatureName(description) {
|
|
120
|
+
// 移除常见的前缀词
|
|
121
|
+
let name = description
|
|
122
|
+
.toLowerCase()
|
|
123
|
+
.replace(/^(实现|开发|做|创建|添加|新增|构建)\s*/g, "")
|
|
124
|
+
.replace(/功能$/, "")
|
|
125
|
+
.trim();
|
|
126
|
+
// 转换为 kebab-case
|
|
127
|
+
name = name
|
|
128
|
+
.replace(/[\s_]+/g, "-")
|
|
129
|
+
.replace(/[^\w\u4e00-\u9fa5-]/g, "")
|
|
130
|
+
.slice(0, 50);
|
|
131
|
+
return name || "new-feature";
|
|
132
|
+
}
|
|
133
|
+
// 生成访谈问题列表
|
|
134
|
+
function generateInterviewQuestions(featureName) {
|
|
135
|
+
const lines = [];
|
|
136
|
+
const template = FEATURE_INTERVIEW_TEMPLATE;
|
|
137
|
+
lines.push("# 📋 需求访谈 - 新功能开发");
|
|
138
|
+
lines.push("");
|
|
139
|
+
lines.push("**核心理念**: 先慢下来,把问题想清楚,反而能更快地交付正确的解决方案。");
|
|
140
|
+
lines.push("");
|
|
141
|
+
lines.push(`**功能名称**: \`${featureName}\``);
|
|
142
|
+
lines.push("");
|
|
143
|
+
lines.push("---");
|
|
144
|
+
lines.push("");
|
|
145
|
+
lines.push("## 📝 访谈说明");
|
|
146
|
+
lines.push("");
|
|
147
|
+
lines.push("请回答以下问题,帮助我们更好地理解你的需求:");
|
|
148
|
+
lines.push("");
|
|
149
|
+
lines.push("- **[必答]** 标记的问题请务必回答");
|
|
150
|
+
lines.push("- **[可选]** 标记的问题可以跳过或回答\"不确定\"");
|
|
151
|
+
lines.push("- 你可以一次性回答所有问题,也可以分批回答");
|
|
152
|
+
lines.push("- 回答越详细,生成的需求文档越准确");
|
|
153
|
+
lines.push("");
|
|
154
|
+
lines.push("---");
|
|
155
|
+
lines.push("");
|
|
156
|
+
let questionNumber = 1;
|
|
157
|
+
for (const phase of template.phases) {
|
|
158
|
+
lines.push(`## ${phase.name}`);
|
|
159
|
+
lines.push("");
|
|
160
|
+
for (const q of phase.questions) {
|
|
161
|
+
const required = q.required ? "**[必答]**" : "_[可选]_";
|
|
162
|
+
lines.push(`### Q${questionNumber}. ${q.question} ${required}`);
|
|
163
|
+
lines.push("");
|
|
164
|
+
if (q.placeholder) {
|
|
165
|
+
lines.push(`_提示: ${q.placeholder}_`);
|
|
166
|
+
lines.push("");
|
|
167
|
+
}
|
|
168
|
+
lines.push("**你的回答**:");
|
|
169
|
+
lines.push("");
|
|
170
|
+
lines.push("");
|
|
171
|
+
lines.push("");
|
|
172
|
+
questionNumber++;
|
|
173
|
+
}
|
|
174
|
+
lines.push("---");
|
|
175
|
+
lines.push("");
|
|
176
|
+
}
|
|
177
|
+
lines.push("## 💡 下一步");
|
|
178
|
+
lines.push("");
|
|
179
|
+
lines.push("回答完问题后,我会:");
|
|
180
|
+
lines.push("1. 生成访谈记录文件 `docs/interviews/${featureName}-interview.md`");
|
|
181
|
+
lines.push("2. 你可以选择:");
|
|
182
|
+
lines.push(` - 立即开发: \`start_feature --from-interview ${featureName}\``);
|
|
183
|
+
lines.push(` - 生成规格: \`add_feature --from-interview ${featureName}\``);
|
|
184
|
+
lines.push(" - 稍后再说: 访谈记录已保存,随时可用");
|
|
185
|
+
lines.push("");
|
|
186
|
+
lines.push("**请开始回答上面的问题吧!**");
|
|
187
|
+
return lines.join("\n");
|
|
188
|
+
}
|
|
189
|
+
// 生成访谈记录文件内容
|
|
190
|
+
function generateInterviewRecord(featureName, answers) {
|
|
191
|
+
const lines = [];
|
|
192
|
+
const template = FEATURE_INTERVIEW_TEMPLATE;
|
|
193
|
+
const timestamp = new Date().toISOString().split("T")[0];
|
|
194
|
+
lines.push(`# 功能访谈记录 - ${featureName}`);
|
|
195
|
+
lines.push("");
|
|
196
|
+
lines.push(`**访谈时间**: ${timestamp}`);
|
|
197
|
+
lines.push(`**功能名称**: ${featureName}`);
|
|
198
|
+
lines.push(`**访谈类型**: feature`);
|
|
199
|
+
lines.push("");
|
|
200
|
+
lines.push("---");
|
|
201
|
+
lines.push("");
|
|
202
|
+
for (const phase of template.phases) {
|
|
203
|
+
lines.push(`## ${phase.name}`);
|
|
204
|
+
lines.push("");
|
|
205
|
+
for (const q of phase.questions) {
|
|
206
|
+
lines.push(`### ${q.question}`);
|
|
207
|
+
lines.push("");
|
|
208
|
+
const answer = answers[q.id] || "_未提供_";
|
|
209
|
+
lines.push(answer);
|
|
210
|
+
lines.push("");
|
|
211
|
+
}
|
|
212
|
+
lines.push("---");
|
|
213
|
+
lines.push("");
|
|
214
|
+
}
|
|
215
|
+
lines.push("## AI 总结");
|
|
216
|
+
lines.push("");
|
|
217
|
+
lines.push("基于以上访谈,AI 理解的需求摘要:");
|
|
218
|
+
lines.push("");
|
|
219
|
+
lines.push("**核心功能**: " + (answers.core_value || "待补充"));
|
|
220
|
+
lines.push("");
|
|
221
|
+
lines.push("**目标用户**: " + (answers.target_users || "待补充"));
|
|
222
|
+
lines.push("");
|
|
223
|
+
lines.push("**功能范围**:");
|
|
224
|
+
lines.push("- 包括: " + (answers.scope_include || "待补充"));
|
|
225
|
+
lines.push("- 不包括: " + (answers.scope_exclude || "待补充"));
|
|
226
|
+
lines.push("");
|
|
227
|
+
lines.push("**关键约束**:");
|
|
228
|
+
if (answers.tech_stack)
|
|
229
|
+
lines.push("- 技术栈: " + answers.tech_stack);
|
|
230
|
+
if (answers.performance)
|
|
231
|
+
lines.push("- 性能: " + answers.performance);
|
|
232
|
+
if (answers.security)
|
|
233
|
+
lines.push("- 安全: " + answers.security);
|
|
234
|
+
if (!answers.tech_stack && !answers.performance && !answers.security) {
|
|
235
|
+
lines.push("- 无特殊约束");
|
|
236
|
+
}
|
|
237
|
+
lines.push("");
|
|
238
|
+
lines.push("**验收标准**: " + (answers.success_criteria || "待补充"));
|
|
239
|
+
lines.push("");
|
|
240
|
+
lines.push("---");
|
|
241
|
+
lines.push("");
|
|
242
|
+
lines.push("## 下一步");
|
|
243
|
+
lines.push("");
|
|
244
|
+
lines.push("**立即开发**:");
|
|
245
|
+
lines.push("```");
|
|
246
|
+
lines.push(`start_feature --from-interview ${featureName}`);
|
|
247
|
+
lines.push("```");
|
|
248
|
+
lines.push("");
|
|
249
|
+
lines.push("**生成规格文档**:");
|
|
250
|
+
lines.push("```");
|
|
251
|
+
lines.push(`add_feature --from-interview ${featureName}`);
|
|
252
|
+
lines.push("```");
|
|
253
|
+
lines.push("");
|
|
254
|
+
lines.push("---");
|
|
255
|
+
lines.push("");
|
|
256
|
+
lines.push("_由 MCP Probe Kit interview 工具生成_");
|
|
257
|
+
return lines.join("\n");
|
|
258
|
+
}
|
|
259
|
+
export async function interview(args) {
|
|
260
|
+
try {
|
|
261
|
+
// 解析参数
|
|
262
|
+
const parsed = parseArgs(args, {
|
|
263
|
+
primaryField: "description",
|
|
264
|
+
fieldAliases: {
|
|
265
|
+
description: ["desc", "topic", "feature"],
|
|
266
|
+
feature_name: ["featureName", "name"],
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
const description = parsed.description || parsed.topic || "";
|
|
270
|
+
const featureName = parsed.feature_name || parsed.featureName || "";
|
|
271
|
+
const answers = parsed.answers;
|
|
272
|
+
// 场景1: 无参数调用 - 显示使用说明
|
|
273
|
+
if (!description && !featureName) {
|
|
274
|
+
return {
|
|
275
|
+
content: [
|
|
276
|
+
{
|
|
277
|
+
type: "text",
|
|
278
|
+
text: `# 📋 需求访谈工具
|
|
279
|
+
|
|
280
|
+
## 功能说明
|
|
281
|
+
|
|
282
|
+
在开发新功能前,通过结构化访谈澄清需求,避免理解偏差和返工。
|
|
283
|
+
|
|
284
|
+
**核心理念**: 先慢下来,把问题想清楚,反而能更快地交付正确的解决方案。
|
|
285
|
+
|
|
286
|
+
## 使用方法
|
|
287
|
+
|
|
288
|
+
### 开始访谈
|
|
289
|
+
\`\`\`
|
|
290
|
+
interview "实现用户登录功能"
|
|
291
|
+
interview --feature-name user-login "实现用户登录功能"
|
|
292
|
+
\`\`\`
|
|
293
|
+
|
|
294
|
+
### 提交访谈回答
|
|
295
|
+
\`\`\`
|
|
296
|
+
interview --feature-name user-login --answers {...}
|
|
297
|
+
\`\`\`
|
|
298
|
+
|
|
299
|
+
## 工作流程
|
|
300
|
+
|
|
301
|
+
\`\`\`
|
|
302
|
+
1. 用户: "我想做登录功能"
|
|
303
|
+
↓
|
|
304
|
+
2. AI 调用: interview "登录功能"
|
|
305
|
+
↓
|
|
306
|
+
3. 生成: 访谈问题列表(12-15个问题)
|
|
307
|
+
↓
|
|
308
|
+
4. 用户: 回答所有问题
|
|
309
|
+
↓
|
|
310
|
+
5. AI 生成: docs/interviews/user-login-interview.md
|
|
311
|
+
↓
|
|
312
|
+
6. 用户选择:
|
|
313
|
+
- 立即开发: start_feature --from-interview user-login
|
|
314
|
+
- 生成规格: add_feature --from-interview user-login
|
|
315
|
+
- 稍后开发: 访谈记录已保存,随时可用
|
|
316
|
+
\`\`\`
|
|
317
|
+
|
|
318
|
+
## 访谈内容
|
|
319
|
+
|
|
320
|
+
访谈分为 4 个阶段,共 12-15 个问题:
|
|
321
|
+
|
|
322
|
+
1. **背景理解** - 痛点、用户、业务驱动
|
|
323
|
+
2. **功能边界** - 核心价值、范围、输入输出
|
|
324
|
+
3. **技术约束** - 技术栈、性能、兼容性、安全
|
|
325
|
+
4. **验收标准** - 成功标准、测试场景、效果衡量
|
|
326
|
+
|
|
327
|
+
## 为什么需要访谈?
|
|
328
|
+
|
|
329
|
+
- ✅ 澄清需求,避免理解偏差
|
|
330
|
+
- ✅ 发现隐藏的约束和依赖
|
|
331
|
+
- ✅ 减少返工,提高交付质量
|
|
332
|
+
- ✅ 形成清晰的需求文档
|
|
333
|
+
|
|
334
|
+
**先慢下来,反而能更快。**`,
|
|
335
|
+
},
|
|
336
|
+
],
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
// 场景2: 开始访谈 - 生成问题列表
|
|
340
|
+
if (description && !answers) {
|
|
341
|
+
const name = featureName || extractFeatureName(description);
|
|
342
|
+
const questions = generateInterviewQuestions(name);
|
|
343
|
+
return {
|
|
344
|
+
content: [{ type: "text", text: questions }],
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
// 场景3: 提交回答 - 生成访谈记录
|
|
348
|
+
if (answers && featureName) {
|
|
349
|
+
const record = generateInterviewRecord(featureName, answers);
|
|
350
|
+
const filePath = `docs/interviews/${featureName}-interview.md`;
|
|
351
|
+
const lines = [];
|
|
352
|
+
lines.push("# ✅ 访谈完成");
|
|
353
|
+
lines.push("");
|
|
354
|
+
lines.push("感谢你的详细回答!我已经整理好访谈记录。");
|
|
355
|
+
lines.push("");
|
|
356
|
+
lines.push("## 📄 请创建访谈记录文件");
|
|
357
|
+
lines.push("");
|
|
358
|
+
lines.push(`**文件路径**: \`${filePath}\``);
|
|
359
|
+
lines.push("");
|
|
360
|
+
lines.push("**文件内容**:");
|
|
361
|
+
lines.push("");
|
|
362
|
+
lines.push("```markdown");
|
|
363
|
+
lines.push(record);
|
|
364
|
+
lines.push("```");
|
|
365
|
+
lines.push("");
|
|
366
|
+
lines.push("---");
|
|
367
|
+
lines.push("");
|
|
368
|
+
lines.push("## 🚀 下一步");
|
|
369
|
+
lines.push("");
|
|
370
|
+
lines.push("访谈记录已生成,你可以选择:");
|
|
371
|
+
lines.push("");
|
|
372
|
+
lines.push("### 选项 1: 立即开始开发");
|
|
373
|
+
lines.push("```");
|
|
374
|
+
lines.push(`start_feature --from-interview ${featureName}`);
|
|
375
|
+
lines.push("```");
|
|
376
|
+
lines.push("这会:");
|
|
377
|
+
lines.push("- 读取访谈记录");
|
|
378
|
+
lines.push("- 生成完整的功能规格文档");
|
|
379
|
+
lines.push("- 估算开发工作量");
|
|
380
|
+
lines.push("");
|
|
381
|
+
lines.push("### 选项 2: 只生成规格文档");
|
|
382
|
+
lines.push("```");
|
|
383
|
+
lines.push(`add_feature --from-interview ${featureName}`);
|
|
384
|
+
lines.push("```");
|
|
385
|
+
lines.push("这会:");
|
|
386
|
+
lines.push("- 读取访谈记录");
|
|
387
|
+
lines.push("- 生成功能规格文档");
|
|
388
|
+
lines.push("- 不估算工作量");
|
|
389
|
+
lines.push("");
|
|
390
|
+
lines.push("### 选项 3: 稍后再说");
|
|
391
|
+
lines.push("访谈记录已保存在 `docs/interviews/` 目录,随时可以使用。");
|
|
392
|
+
lines.push("");
|
|
393
|
+
lines.push("---");
|
|
394
|
+
lines.push("");
|
|
395
|
+
lines.push("💡 **提示**: 建议先创建访谈记录文件,然后再决定下一步。");
|
|
396
|
+
return {
|
|
397
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
// 其他情况 - 错误提示
|
|
401
|
+
return {
|
|
402
|
+
content: [
|
|
403
|
+
{
|
|
404
|
+
type: "text",
|
|
405
|
+
text: "❌ 参数错误。请使用 `interview` 查看使用说明。",
|
|
406
|
+
},
|
|
407
|
+
],
|
|
408
|
+
isError: true,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
413
|
+
return {
|
|
414
|
+
content: [{ type: "text", text: `❌ 访谈失败: ${errorMsg}` }],
|
|
415
|
+
isError: true,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI 渲染工具
|
|
3
|
+
*
|
|
4
|
+
* 将 JSON 模板渲染为最终代码
|
|
5
|
+
* 自动应用设计规范,确保样式统一
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* UI 渲染工具
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderUi(args: any): Promise<{
|
|
11
|
+
content: {
|
|
12
|
+
type: string;
|
|
13
|
+
text: string;
|
|
14
|
+
}[];
|
|
15
|
+
isError: boolean;
|
|
16
|
+
} | {
|
|
17
|
+
content: {
|
|
18
|
+
type: string;
|
|
19
|
+
text: string;
|
|
20
|
+
}[];
|
|
21
|
+
isError?: undefined;
|
|
22
|
+
}>;
|