@ghyper9023/pi-dev-workflow 0.2.0 → 0.3.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 +101 -2
- package/agents/git-agent.md +16 -25
- package/agents/review-agent.md +5 -3
- package/extensions/dev-prompts.ts +320 -26
- package/extensions/git-commands.ts +5 -2
- package/extensions/grill-me-agent.ts +687 -0
- package/extensions/sub-agents.ts +54 -33
- package/package.json +1 -1
- package/skills/grill-with-docs/ADR-FORMAT.md +47 -0
- package/skills/grill-with-docs/CONTEXT-FORMAT.md +77 -0
- package/skills/grill-with-docs/SKILL.md +88 -0
- package/skills/review-html/SKILL.md +36 -25
- package/skills/to-prd/SKILL.md +74 -0
- package/ai/346/217/220/347/244/272/350/257/215/344/274/230/345/214/226.md +0 -341
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
27
|
+
import { runGrillPhase, runPRDPhase, type AgentDef, type GrillOptions } from "./grill-me-agent";
|
|
27
28
|
|
|
28
29
|
// ── Helpers ──────────────────────────────────────────────────
|
|
29
30
|
|
|
@@ -135,7 +136,7 @@ function assembleDocPrompt(f: DocFields): string {
|
|
|
135
136
|
}
|
|
136
137
|
lines.push("**任务**:");
|
|
137
138
|
lines.push("1. 提取核心要点,按逻辑结构重组(概述 → 快速开始 → 详细说明 → 常见问题)。");
|
|
138
|
-
lines.push(`2. 添加至少
|
|
139
|
+
lines.push(`2. 添加至少 1 个真实可运行的示例(使用 ${wrap(f.language)} 语法高亮)。`);
|
|
139
140
|
lines.push("3. 如存在争议点,列出不同观点并注明\"无共识\"。");
|
|
140
141
|
if (!isEmpty(f.existingMaterial)) {
|
|
141
142
|
lines.push(`**已有材料**:${f.existingMaterial!.trim()}`);
|
|
@@ -161,7 +162,7 @@ function assembleRefactorPrompt(f: RefactorFields): string {
|
|
|
161
162
|
lines.push("");
|
|
162
163
|
lines.push(`**背景**:当前代码存在 ${wrap(f.problems)}。`);
|
|
163
164
|
lines.push("**任务**:");
|
|
164
|
-
lines.push("1.
|
|
165
|
+
lines.push("1. 识别主要问题。");
|
|
165
166
|
lines.push("2. 提出重构方案,说明改动前后差异。");
|
|
166
167
|
lines.push("3. 输出重构后的完整版本。");
|
|
167
168
|
lines.push("**硬性约束**:");
|
|
@@ -350,8 +351,215 @@ function assembleComparePrompt(f: CompareFields): string {
|
|
|
350
351
|
return lines.join("\n");
|
|
351
352
|
}
|
|
352
353
|
|
|
354
|
+
// ── Specialized Agent Definitions for Grill ─────────────────
|
|
355
|
+
|
|
356
|
+
/** Bug fix root cause analysis & reproduction review. */
|
|
357
|
+
const FIX_GRILL_AGENT_DEF: AgentDef = {
|
|
358
|
+
name: "fix-grill-agent",
|
|
359
|
+
description: "Bug fix review agent — challenges the developer on understanding the bug root cause",
|
|
360
|
+
tools: ["read", "bash"],
|
|
361
|
+
systemPrompt: [
|
|
362
|
+
"You are an expert debugger reviewing a bug fix plan. Interview the developer relentlessly.",
|
|
363
|
+
"",
|
|
364
|
+
"## Rules",
|
|
365
|
+
"- For EACH question, provide recommended answer OPTIONS (a/b/c format)",
|
|
366
|
+
"- Focus on: reproduction steps, environment conditions, input variations, error messages, logs, attempted fixes",
|
|
367
|
+
"- Push for precise root cause identification — ask 'why' at least 3 levels deep",
|
|
368
|
+
"- Check if the developer has considered: edge cases in inputs, race conditions, state leakage, timeout, memory",
|
|
369
|
+
"- Verify the proposed fix addresses the root cause, not just the symptom",
|
|
370
|
+
"- If the codebase has logs/metrics available, suggest checking specific patterns",
|
|
371
|
+
"- Stress-test regression risk: could the fix break other parts of the system?",
|
|
372
|
+
"- Explore the codebase (use read/bash tools) when a question can be answered by looking at existing code",
|
|
373
|
+
"",
|
|
374
|
+
"## Output format",
|
|
375
|
+
"Output ALL questions in ONE JSON response. No preamble or explanation.",
|
|
376
|
+
'Only output the JSON object: { "questions": [{ "id": 1, "question": "...", "options": ["..."] }] }',
|
|
377
|
+
"",
|
|
378
|
+
"## Quantity",
|
|
379
|
+
"Ask 5-15 questions — enough to thoroughly understand the root cause before committing to a fix.",
|
|
380
|
+
"",
|
|
381
|
+
"## Language",
|
|
382
|
+
"Questions and options should be in the same language as the bug report (default: Chinese).",
|
|
383
|
+
].join("\n"),
|
|
384
|
+
timeoutMs: 300_000,
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
/** Document outline & structure review. */
|
|
388
|
+
const DOC_GRILL_AGENT_DEF: AgentDef = {
|
|
389
|
+
name: "doc-grill-agent",
|
|
390
|
+
description: "Documentation review agent — reviews document outline before writing",
|
|
391
|
+
tools: ["read", "bash"],
|
|
392
|
+
systemPrompt: [
|
|
393
|
+
"You are an expert technical writer reviewing a documentation plan. Interview the developer.",
|
|
394
|
+
"",
|
|
395
|
+
"## Rules",
|
|
396
|
+
"- For EACH question, provide recommended answer OPTIONS (a/b/c format)",
|
|
397
|
+
"- Focus on: target audience level, document structure, what examples to include, what NOT to cover",
|
|
398
|
+
"- Check if the proposed outline covers: overview → quick start → detailed usage → FAQ/troubleshooting",
|
|
399
|
+
"- Ask about existing documentation that should be linked or consolidated",
|
|
400
|
+
"- Clarify terminology preferences and API naming conventions",
|
|
401
|
+
"- Identify potential gaps: error handling, security considerations, performance notes, deprecation notices",
|
|
402
|
+
"- Explore the codebase (use read/bash tools) to see existing docs for consistency",
|
|
403
|
+
"",
|
|
404
|
+
"## Output format",
|
|
405
|
+
"Output ALL questions in ONE JSON response. No preamble or explanation.",
|
|
406
|
+
'Only output the JSON object: { "questions": [{ "id": 1, "question": "...", "options": ["..."] }] }',
|
|
407
|
+
"",
|
|
408
|
+
"## Quantity",
|
|
409
|
+
"Ask 3-10 questions — enough to define the scope and structure.",
|
|
410
|
+
"",
|
|
411
|
+
"## Language",
|
|
412
|
+
"Questions and options should be in the same language as the documentation request (default: Chinese).",
|
|
413
|
+
].join("\n"),
|
|
414
|
+
timeoutMs: 300_000,
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
/** Refactoring plan review. */
|
|
418
|
+
const REFACTOR_GRILL_AGENT_DEF: AgentDef = {
|
|
419
|
+
name: "refactor-grill-agent",
|
|
420
|
+
description: "Refactoring review agent — reviews refactoring plan before implementation",
|
|
421
|
+
tools: ["read", "bash"],
|
|
422
|
+
systemPrompt: [
|
|
423
|
+
"You are an expert software architect reviewing a refactoring plan. Interview the developer.",
|
|
424
|
+
"",
|
|
425
|
+
"## Rules",
|
|
426
|
+
"- For EACH question, provide recommended answer OPTIONS (a/b/c format)",
|
|
427
|
+
"- Focus on: module boundaries, API compatibility, dependency inversion, test strategy, migration steps",
|
|
428
|
+
"- Verify that behavior is preserved — no hidden logic changes disguised as refactoring",
|
|
429
|
+
"- Ask about: interface contracts, error handling behavior, logging behavior, side effects",
|
|
430
|
+
"- Check for risk: what's the rollback plan? Can we refactor incrementally?",
|
|
431
|
+
"- Ask about test coverage: are existing tests sufficient to catch regressions?",
|
|
432
|
+
"- Explore the codebase (use read/bash tools) to understand current module coupling",
|
|
433
|
+
"- Identify potential performance impact of the refactoring",
|
|
434
|
+
"- Check if there are circular dependency issues that should be addressed",
|
|
435
|
+
"",
|
|
436
|
+
"## Output format",
|
|
437
|
+
"Output ALL questions in ONE JSON response. No preamble or explanation.",
|
|
438
|
+
'Only output the JSON object: { "questions": [{ "id": 1, "question": "...", "options": ["..."] }] }',
|
|
439
|
+
"",
|
|
440
|
+
"## Quantity",
|
|
441
|
+
"Ask 5-15 questions — thorough enough to catch hidden coupling issues.",
|
|
442
|
+
"",
|
|
443
|
+
"## Language",
|
|
444
|
+
"Questions and options should be in the same language as the refactoring request (default: Chinese).",
|
|
445
|
+
].join("\n"),
|
|
446
|
+
timeoutMs: 300_000,
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
/** Test plan coverage review. */
|
|
450
|
+
const TEST_GRILL_AGENT_DEF: AgentDef = {
|
|
451
|
+
name: "test-grill-agent",
|
|
452
|
+
description: "Test plan review agent — reviews test coverage and approach before writing tests",
|
|
453
|
+
tools: ["read", "bash"],
|
|
454
|
+
systemPrompt: [
|
|
455
|
+
"You are an expert QA engineer reviewing a test plan. Interview the developer.",
|
|
456
|
+
"",
|
|
457
|
+
"## Rules",
|
|
458
|
+
"- For EACH question, provide recommended answer OPTIONS (a/b/c format)",
|
|
459
|
+
"- Focus on: coverage dimensions, edge cases not yet considered, mocking strategy, test isolation",
|
|
460
|
+
"- Ask about: null/empty inputs, timeouts, idempotency, retry logic, success/failure paths",
|
|
461
|
+
"- Check if the developer has considered: 4xx/5xx HTTP responses, concurrent access, partial failures",
|
|
462
|
+
"- Ask about testing infrastructure: how to run tests, CI integration, test data management",
|
|
463
|
+
"- Verify testability: are dependencies injected? Can we mock external services?",
|
|
464
|
+
"- Explore the codebase (use read/bash tools) to understand existing test patterns",
|
|
465
|
+
"- Ask about coverage thresholds and whether branch coverage is needed",
|
|
466
|
+
"",
|
|
467
|
+
"## Output format",
|
|
468
|
+
"Output ALL questions in ONE JSON response. No preamble or explanation.",
|
|
469
|
+
'Only output the JSON object: { "questions": [{ "id": 1, "question": "...", "options": ["..."] }] }',
|
|
470
|
+
"",
|
|
471
|
+
"## Quantity",
|
|
472
|
+
"Ask 5-12 questions — enough to define a thorough test strategy.",
|
|
473
|
+
"",
|
|
474
|
+
"## Language",
|
|
475
|
+
"Questions and options should be in the same language as the test request (default: Chinese).",
|
|
476
|
+
].join("\n"),
|
|
477
|
+
timeoutMs: 300_000,
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
/** Performance optimization plan review. */
|
|
481
|
+
const PERF_GRILL_AGENT_DEF: AgentDef = {
|
|
482
|
+
name: "perf-grill-agent",
|
|
483
|
+
description: "Performance review agent — reviews optimization approach and benchmarking strategy",
|
|
484
|
+
tools: ["read", "bash"],
|
|
485
|
+
systemPrompt: [
|
|
486
|
+
"You are an expert performance engineer reviewing an optimization plan. Interview the developer.",
|
|
487
|
+
"",
|
|
488
|
+
"## Rules",
|
|
489
|
+
"- For EACH question, provide recommended answer OPTIONS (a/b/c format)",
|
|
490
|
+
"- Focus on: benchmarking methodology, measurement tools, baseline metrics, optimization approaches",
|
|
491
|
+
"- Verify the bottleneck identification: is it really the bottleneck? What's the evidence?",
|
|
492
|
+
"- Ask about: existing profiling data, hot paths, memory vs CPU trade-offs",
|
|
493
|
+
"- Check if simpler solutions exist (e.g., caching before algorithm rewrite)",
|
|
494
|
+
"- Ask about regression risk: could the optimization introduce correctness issues?",
|
|
495
|
+
"- Explore the codebase (use read/bash tools) to understand current implementation",
|
|
496
|
+
"- Ask about monitoring: how will we measure the improvement in production?",
|
|
497
|
+
"- Challenge assumptions: is this optimization premature? What's the user-facing impact?",
|
|
498
|
+
"",
|
|
499
|
+
"## Output format",
|
|
500
|
+
"Output ALL questions in ONE JSON response. No preamble or explanation.",
|
|
501
|
+
'Only output the JSON object: { "questions": [{ "id": 1, "question": "...", "options": ["..."] }] }',
|
|
502
|
+
"",
|
|
503
|
+
"## Quantity",
|
|
504
|
+
"Ask 5-12 questions — enough to validate the approach before implementation.",
|
|
505
|
+
"",
|
|
506
|
+
"## Language",
|
|
507
|
+
"Questions and options should be in the same language as the optimization request (default: Chinese).",
|
|
508
|
+
].join("\n"),
|
|
509
|
+
timeoutMs: 300_000,
|
|
510
|
+
};
|
|
511
|
+
|
|
353
512
|
// ── Command runner ───────────────────────────────────────────
|
|
354
513
|
|
|
514
|
+
/**
|
|
515
|
+
* Run a wizard with an optional Grill phase:
|
|
516
|
+
* Wizard → Assemble → (Grill?) → Send
|
|
517
|
+
*/
|
|
518
|
+
async function runWizardWithGrill(
|
|
519
|
+
ctx: ExtensionCommandContext,
|
|
520
|
+
pi: ExtensionAPI,
|
|
521
|
+
type: string,
|
|
522
|
+
label: string,
|
|
523
|
+
questions: Array<{ label: string; placeholder: string; key: string }>,
|
|
524
|
+
assembler: (answers: Record<string, string>) => string,
|
|
525
|
+
grillOptions?: GrillOptions,
|
|
526
|
+
): Promise<void> {
|
|
527
|
+
ctx.ui.notify(`📋 /dev-${type} — ${label},请逐项填写以下信息(留空跳过对应段落,Esc 取消)`, "info");
|
|
528
|
+
|
|
529
|
+
const answers: Record<string, string> = {};
|
|
530
|
+
for (const q of questions) {
|
|
531
|
+
const val = await ask(ctx, q.label, q.placeholder);
|
|
532
|
+
if (val === undefined) {
|
|
533
|
+
ctx.ui.notify("❌ 已取消", "warning");
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
answers[q.key] = val;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const basePrompt = assembler(answers);
|
|
540
|
+
|
|
541
|
+
// ── Grill phase (if agentDef provided) ────────────────────
|
|
542
|
+
let finalPrompt = basePrompt;
|
|
543
|
+
if (grillOptions) {
|
|
544
|
+
const grillResult = await runGrillPhase(basePrompt, ctx, {
|
|
545
|
+
agentDef: grillOptions.agentDef,
|
|
546
|
+
title: grillOptions.title,
|
|
547
|
+
description: grillOptions.description,
|
|
548
|
+
questionTitle: grillOptions.questionTitle,
|
|
549
|
+
loaderLabel: grillOptions.loaderLabel,
|
|
550
|
+
});
|
|
551
|
+
if (grillResult.cancelled) {
|
|
552
|
+
ctx.ui.notify("❌ 操作已取消", "warning");
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
finalPrompt = grillResult.enhancedPrompt;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
ctx.ui.notify(`✅ 提示词已组装完成,正在发送给主代理...`, "success");
|
|
559
|
+
pi.sendUserMessage(finalPrompt);
|
|
560
|
+
ctx.ui.notify(`📝 /dev-${type} 提示词已投递,主代理正在处理`, "info");
|
|
561
|
+
}
|
|
562
|
+
|
|
355
563
|
/**
|
|
356
564
|
* Run a wizard: ask questions, assemble prompt, send to agent.
|
|
357
565
|
* @param ctx Command context
|
|
@@ -414,7 +622,7 @@ const FIX_QUESTIONS = [
|
|
|
414
622
|
];
|
|
415
623
|
|
|
416
624
|
const DOC_QUESTIONS = [
|
|
417
|
-
{ label: "模块/API 名称", placeholder: "如 AuthService, REST API v2...", key: "moduleName" },
|
|
625
|
+
{ label: "模块/API/doc 名称", placeholder: "如 AuthService, REST API v2...", key: "moduleName" },
|
|
418
626
|
{ label: "目标受众", placeholder: "如 小白 / 前端开发者 / 架构师", key: "audience" },
|
|
419
627
|
{ label: "关键信息点", placeholder: "他们需要了解如何使用认证接口", key: "keyInfo" },
|
|
420
628
|
{ label: "示例语言", placeholder: "如 TypeScript, Python, curl...", key: "language" },
|
|
@@ -482,64 +690,150 @@ const COMPARE_QUESTIONS = [
|
|
|
482
690
|
export default function (pi: ExtensionAPI) {
|
|
483
691
|
// ── /dev-feat ──────────────────────────────────────────────
|
|
484
692
|
pi.registerCommand("dev-feat", {
|
|
485
|
-
description: "(prompt wizard) 新功能/创意生成 —
|
|
486
|
-
handler: async (
|
|
487
|
-
|
|
693
|
+
description: "(prompt wizard) 新功能/创意生成 — 支持设计评审 (Grill) + PRD 生成",
|
|
694
|
+
handler: async (_args, ctx) => {
|
|
695
|
+
// ── Phase 1: Wizard ──────────────────────────────────
|
|
696
|
+
ctx.ui.notify("📋 /dev-feat — 新功能/创意生成,请逐项填写以下信息(留空跳过对应段落,Esc 取消)", "info");
|
|
697
|
+
|
|
698
|
+
const answers: Record<string, string> = {};
|
|
699
|
+
for (const q of FEAT_QUESTIONS) {
|
|
700
|
+
const val = await ask(ctx, q.label, q.placeholder);
|
|
701
|
+
if (val === undefined) {
|
|
702
|
+
ctx.ui.notify("❌ 已取消", "warning");
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
answers[q.key] = val;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// ── Phase 2: Assemble base prompt ───────────────────
|
|
709
|
+
const basePrompt = assembleFeatPrompt(answers as FeatFields);
|
|
710
|
+
ctx.ui.notify(`✅ 基本信息已收集,共 ${FEAT_QUESTIONS.length} 项`, "success");
|
|
711
|
+
|
|
712
|
+
// ── Phase 3: Grill (设计评审) ───────────────────────
|
|
713
|
+
const grillResult = await runGrillPhase(basePrompt, ctx);
|
|
714
|
+
if (grillResult.cancelled) {
|
|
715
|
+
ctx.ui.notify("❌ 操作已取消", "warning");
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
const finalPrompt = grillResult.enhancedPrompt;
|
|
719
|
+
|
|
720
|
+
// ── Phase 4: Send to main agent ─────────────────────
|
|
721
|
+
ctx.ui.notify(`✅ 提示词已组装完成,正在发送给主代理...`, "success");
|
|
722
|
+
pi.sendUserMessage(finalPrompt);
|
|
723
|
+
ctx.ui.notify(`📝 /dev-feat 提示词已投递,主代理正在处理`, "info");
|
|
724
|
+
|
|
725
|
+
// ── Phase 5: Wait for agent to finish ───────────────
|
|
726
|
+
await ctx.waitForIdle();
|
|
727
|
+
|
|
728
|
+
// ── Phase 6: PRD generation ─────────────────────────
|
|
729
|
+
const moduleHint = (answers as FeatFields).module || "feature";
|
|
730
|
+
const grillContext = finalPrompt;
|
|
731
|
+
await runPRDPhase(grillContext, moduleHint, pi, ctx);
|
|
488
732
|
},
|
|
489
733
|
});
|
|
490
734
|
|
|
491
735
|
// ── /dev-fix ───────────────────────────────────────────────
|
|
492
736
|
pi.registerCommand("dev-fix", {
|
|
493
|
-
description: "(prompt wizard) 问题排查/错误修正 —
|
|
494
|
-
handler: async (
|
|
495
|
-
await
|
|
737
|
+
description: "(prompt wizard) 问题排查/错误修正 — 支持根因分析评审 (Grill)",
|
|
738
|
+
handler: async (_args, ctx) => {
|
|
739
|
+
await runWizardWithGrill(
|
|
740
|
+
ctx, pi, "fix", "问题排查/错误修正",
|
|
741
|
+
FIX_QUESTIONS, assembleFixPrompt,
|
|
742
|
+
{
|
|
743
|
+
agentDef: FIX_GRILL_AGENT_DEF,
|
|
744
|
+
title: "🐛 Bug 根因分析评审",
|
|
745
|
+
description: "是否进入 Bug 根因分析评审 (Grill) 模式?\nAI 会从复现条件、根因推理、修复方案、回归风险等维度挑战你的理解。",
|
|
746
|
+
questionTitle: "Bug 根因分析",
|
|
747
|
+
loaderLabel: "🧠 AI 正在分析代码并生成根因评审问题...",
|
|
748
|
+
},
|
|
749
|
+
);
|
|
496
750
|
},
|
|
497
751
|
});
|
|
498
752
|
|
|
499
753
|
// ── /dev-doc ───────────────────────────────────────────────
|
|
500
754
|
pi.registerCommand("dev-doc", {
|
|
501
|
-
description: "(prompt wizard) 文档生成/总结 —
|
|
502
|
-
handler: async (
|
|
503
|
-
await
|
|
755
|
+
description: "(prompt wizard) 文档生成/总结 — 支持大纲评审 (Grill)",
|
|
756
|
+
handler: async (_args, ctx) => {
|
|
757
|
+
await runWizardWithGrill(
|
|
758
|
+
ctx, pi, "doc", "文档生成/总结",
|
|
759
|
+
DOC_QUESTIONS, assembleDocPrompt,
|
|
760
|
+
{
|
|
761
|
+
agentDef: DOC_GRILL_AGENT_DEF,
|
|
762
|
+
title: "📄 文档大纲评审",
|
|
763
|
+
description: "是否进入文档大纲评审 (Grill) 模式?\nAI 会从受众定位、结构安排、示例选择等维度审视你的文档计划。",
|
|
764
|
+
questionTitle: "文档大纲评审",
|
|
765
|
+
loaderLabel: "🧠 AI 正在分析并生成文档大纲评审问题...",
|
|
766
|
+
},
|
|
767
|
+
);
|
|
504
768
|
},
|
|
505
769
|
});
|
|
506
770
|
|
|
507
771
|
// ── /dev-refactor ──────────────────────────────────────────
|
|
508
772
|
pi.registerCommand("dev-refactor", {
|
|
509
|
-
description: "(prompt wizard) 重构/优化现有结构 —
|
|
510
|
-
handler: async (
|
|
511
|
-
await
|
|
773
|
+
description: "(prompt wizard) 重构/优化现有结构 — 支持重构计划评审 (Grill)",
|
|
774
|
+
handler: async (_args, ctx) => {
|
|
775
|
+
await runWizardWithGrill(
|
|
776
|
+
ctx, pi, "refactor", "重构/优化",
|
|
777
|
+
REFACTOR_QUESTIONS, assembleRefactorPrompt,
|
|
778
|
+
{
|
|
779
|
+
agentDef: REFACTOR_GRILL_AGENT_DEF,
|
|
780
|
+
title: "🔧 重构方案评审",
|
|
781
|
+
description: "是否进入重构方案评审 (Grill) 模式?\nAI 会从模块边界、API 兼容性、测试策略、迁移风险等维度审视你的重构计划。",
|
|
782
|
+
questionTitle: "重构方案评审",
|
|
783
|
+
loaderLabel: "🧠 AI 正在分析代码并生成重构评审问题...",
|
|
784
|
+
},
|
|
785
|
+
);
|
|
512
786
|
},
|
|
513
787
|
});
|
|
514
788
|
|
|
515
789
|
// ── /dev-test ──────────────────────────────────────────────
|
|
516
790
|
pi.registerCommand("dev-test", {
|
|
517
|
-
description: "(prompt wizard) 测试用例生成 —
|
|
518
|
-
handler: async (
|
|
519
|
-
await
|
|
791
|
+
description: "(prompt wizard) 测试用例生成 — 支持测试计划评审 (Grill)",
|
|
792
|
+
handler: async (_args, ctx) => {
|
|
793
|
+
await runWizardWithGrill(
|
|
794
|
+
ctx, pi, "test", "测试用例/评估",
|
|
795
|
+
TEST_QUESTIONS, assembleTestPrompt,
|
|
796
|
+
{
|
|
797
|
+
agentDef: TEST_GRILL_AGENT_DEF,
|
|
798
|
+
title: "🧪 测试计划评审",
|
|
799
|
+
description: "是否进入测试计划评审 (Grill) 模式?\nAI 会从覆盖维度、边界条件、模拟策略等角度审视你的测试方案。",
|
|
800
|
+
questionTitle: "测试计划评审",
|
|
801
|
+
loaderLabel: "🧠 AI 正在分析并生成测试评审问题...",
|
|
802
|
+
},
|
|
803
|
+
);
|
|
520
804
|
},
|
|
521
805
|
});
|
|
522
806
|
|
|
523
807
|
// ── /dev-chore ─────────────────────────────────────────────
|
|
524
808
|
pi.registerCommand("dev-chore", {
|
|
525
809
|
description: "(prompt wizard) 日常维护/杂项自动化 — 交互填写后发送优化提示词给主代理",
|
|
526
|
-
handler: async (
|
|
810
|
+
handler: async (_args, ctx) => {
|
|
527
811
|
await runWizard(ctx, pi, "chore", "日常维护/自动化", CHORE_QUESTIONS, assembleChorePrompt);
|
|
528
812
|
},
|
|
529
813
|
});
|
|
530
814
|
|
|
531
815
|
// ── /dev-perf ──────────────────────────────────────────────
|
|
532
816
|
pi.registerCommand("dev-perf", {
|
|
533
|
-
description: "(prompt wizard) 性能优化 —
|
|
534
|
-
handler: async (
|
|
535
|
-
await
|
|
817
|
+
description: "(prompt wizard) 性能优化 — 支持优化方案评审 (Grill)",
|
|
818
|
+
handler: async (_args, ctx) => {
|
|
819
|
+
await runWizardWithGrill(
|
|
820
|
+
ctx, pi, "perf", "性能优化",
|
|
821
|
+
PERF_QUESTIONS, assemblePerfPrompt,
|
|
822
|
+
{
|
|
823
|
+
agentDef: PERF_GRILL_AGENT_DEF,
|
|
824
|
+
title: "⚡ 性能优化方案评审",
|
|
825
|
+
description: "是否进入性能优化方案评审 (Grill) 模式?\nAI 会从基准测试方法、优化方向、回归风险等维度审视你的方案。",
|
|
826
|
+
questionTitle: "性能优化方案评审",
|
|
827
|
+
loaderLabel: "🧠 AI 正在分析并生成性能优化评审问题...",
|
|
828
|
+
},
|
|
829
|
+
);
|
|
536
830
|
},
|
|
537
831
|
});
|
|
538
832
|
|
|
539
833
|
// ── /dev-style ─────────────────────────────────────────────
|
|
540
834
|
pi.registerCommand("dev-style", {
|
|
541
835
|
description: "(prompt wizard) 风格/格式调整 — 交互填写后发送优化提示词给主代理",
|
|
542
|
-
handler: async (
|
|
836
|
+
handler: async (_args, ctx) => {
|
|
543
837
|
await runWizard(ctx, pi, "style", "风格/格式调整", STYLE_QUESTIONS, assembleStylePrompt);
|
|
544
838
|
},
|
|
545
839
|
});
|
|
@@ -547,7 +841,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
547
841
|
// ── /dev-security ──────────────────────────────────────────
|
|
548
842
|
pi.registerCommand("dev-security", {
|
|
549
843
|
description: "(prompt wizard) 安全审查 — 交互填写后发送优化提示词给主代理",
|
|
550
|
-
handler: async (
|
|
844
|
+
handler: async (_args, ctx) => {
|
|
551
845
|
await runWizard(ctx, pi, "security", "安全审查", SECURITY_QUESTIONS, assembleSecurityPrompt);
|
|
552
846
|
},
|
|
553
847
|
});
|
|
@@ -555,7 +849,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
555
849
|
// ── /dev-explain ───────────────────────────────────────────
|
|
556
850
|
pi.registerCommand("dev-explain", {
|
|
557
851
|
description: "(prompt wizard) 概念解释 — 交互填写后发送优化提示词给主代理",
|
|
558
|
-
handler: async (
|
|
852
|
+
handler: async (_args, ctx) => {
|
|
559
853
|
await runWizard(ctx, pi, "explain", "概念解释", EXPLAIN_QUESTIONS, assembleExplainPrompt);
|
|
560
854
|
},
|
|
561
855
|
});
|
|
@@ -563,7 +857,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
563
857
|
// ── /dev-compare ───────────────────────────────────────────
|
|
564
858
|
pi.registerCommand("dev-compare", {
|
|
565
859
|
description: "(prompt wizard) 对比评估 — 交互填写后发送优化提示词给主代理",
|
|
566
|
-
handler: async (
|
|
860
|
+
handler: async (_args, ctx) => {
|
|
567
861
|
await runWizard(ctx, pi, "compare", "对比评估", COMPARE_QUESTIONS, assembleComparePrompt);
|
|
568
862
|
},
|
|
569
863
|
});
|
|
@@ -47,11 +47,14 @@ function parseGitOutput(output: string): GitSummary {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// Parse <summary>...</summary>
|
|
50
|
-
|
|
50
|
+
// Anchor to start of line (^ with m flag) to avoid matching a nested
|
|
51
|
+
// <summary> tag inside <details> content before the real top-level summary.
|
|
52
|
+
const summaryMatch = output.match(/^<summary>([\s\S]*?)<\/summary>/m);
|
|
51
53
|
if (summaryMatch) result.summary = summaryMatch[1].trim();
|
|
52
54
|
|
|
53
55
|
// Parse <details>...</details> → extract each line
|
|
54
|
-
|
|
56
|
+
// Anchor to start of line to avoid matching nested <details> inside content.
|
|
57
|
+
const detailsMatch = output.match(/^<details>([\s\S]*?)<\/details>/m);
|
|
55
58
|
if (detailsMatch) {
|
|
56
59
|
const lines = detailsMatch[1]
|
|
57
60
|
.split("\n")
|