@ghyper9023/pi-dev-workflow 0.1.7 → 0.2.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
CHANGED
|
@@ -34,6 +34,8 @@ pi-package/
|
|
|
34
34
|
│ └── review-html/
|
|
35
35
|
│ └── SKILL.md # 代码审查 → 输出交互式 HTML 报告
|
|
36
36
|
├── extensions/
|
|
37
|
+
│ ├── dev-prompts.ts # 提示词优化向导(/dev-* 命令)
|
|
38
|
+
│ ├── git-commands.ts # git-sub-agent 命令
|
|
37
39
|
│ └── sub-agents.ts # 子代理系统:git-sub-agent + review-sub-agent
|
|
38
40
|
└── themes/
|
|
39
41
|
└── claude-code-theme.json # Claude Code CLI 风格主题
|
|
@@ -85,6 +87,75 @@ LLM 也可以直接调用 `subagent` 工具委派任务给任意子代理:
|
|
|
85
87
|
|---|---|
|
|
86
88
|
| **claude-code-theme** | 仿 Claude Code CLI 配色:深色底 + 琥珀金主色 + 紫罗兰辅色 |
|
|
87
89
|
|
|
90
|
+
## Dev Prompts(提示词优化向导)
|
|
91
|
+
|
|
92
|
+
基于 [ai提示词优化.md](./ai%E6%8F%90%E7%A4%BA%E8%AF%8D%E4%BC%98%E5%8C%96.md) 中的优质模板,通过交互式问答引导你填写 `[xxx]` 占位符,组装完整的高质量提示词后直接投递给主代理执行。
|
|
93
|
+
|
|
94
|
+
### 命令一览
|
|
95
|
+
|
|
96
|
+
| 命令 | 用途 | 对应模板类型 |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| `/dev-feat` | 新功能/创意生成 | `feat` |
|
|
99
|
+
| `/dev-fix` | 问题排查/错误修正 | `fix` |
|
|
100
|
+
| `/dev-doc` | 文档生成/总结 | `doc` |
|
|
101
|
+
| `/dev-refactor` | 重构/优化现有结构 | `refactor` |
|
|
102
|
+
| `/dev-test` | 测试用例生成 | `test` |
|
|
103
|
+
| `/dev-chore` | 日常维护/自动化 | `chore` |
|
|
104
|
+
| `/dev-perf` | 性能优化 | `perf` |
|
|
105
|
+
| `/dev-style` | 风格/格式调整 | `style` |
|
|
106
|
+
| `/dev-security` | 安全审查 | `security` |
|
|
107
|
+
| `/dev-explain` | 概念解释 | `explain` |
|
|
108
|
+
| `/dev-compare` | 对比评估 | `compare` |
|
|
109
|
+
|
|
110
|
+
### 使用方法
|
|
111
|
+
|
|
112
|
+
输入任意 `/dev-*` 命令进入向导,按提示逐项填写字段:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
# 示例:/dev-feat
|
|
116
|
+
📋 /dev-feat — 新功能/创意生成,请逐项填写以下信息(留空跳过对应段落,Esc 取消)
|
|
117
|
+
|
|
118
|
+
编程语言/框架? TypeScript
|
|
119
|
+
技术栈? NestJS + Prisma
|
|
120
|
+
目标模块/文件名? src/auth/login.ts
|
|
121
|
+
核心功能描述? 用户可以通过邮箱+密码注册并登录
|
|
122
|
+
...
|
|
123
|
+
✅ 提示词已组装完成,正在发送给主代理...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**交互规则**:
|
|
127
|
+
- **留空(直接回车)** — 该字段标记为「无」,对应的模板段落整段跳过
|
|
128
|
+
- **输入「无」** — 与留空效果相同,明确表示不需要该段内容
|
|
129
|
+
- **按 Esc** — 随时退出向导,不产生任何输出
|
|
130
|
+
- **填写后** — 自动用 `pi.sendUserMessage()` 投递给主代理,立即开始执行
|
|
131
|
+
|
|
132
|
+
### 示例 1:用 `/dev-fix` 修 Bug
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
/dev-fix
|
|
136
|
+
文件路径? src/api/users.ts
|
|
137
|
+
行号? 42
|
|
138
|
+
Bug 描述? 创建用户成功后返回 201,但实际上返回了 500
|
|
139
|
+
输入/现象? POST /api/users 正确参数返回 Internal Server Error
|
|
140
|
+
预期行为? 返回 201 + 用户数据
|
|
141
|
+
当前错误? 500 Internal Server Error
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
组装后的提示词包含:根因诊断 → 修复方案 → 测试复现 → diff 输出。
|
|
145
|
+
|
|
146
|
+
### 示例 2:用 `/dev-doc` 写文档
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
/dev-doc
|
|
150
|
+
模块/API 名称? AuthService REST API
|
|
151
|
+
目标受众? 前端开发者和后端集成方
|
|
152
|
+
关键信息点? 注册、登录、刷新 token、登出四个接口的用法
|
|
153
|
+
示例语言? TypeScript, curl
|
|
154
|
+
已有材料? (留空跳过,从零生成)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
组装后的提示词包含:角色(技术文档工程师)→ 大纲先行 → Markdown 层级文档 → 2 个可运行示例。
|
|
158
|
+
|
|
88
159
|
## Skills
|
|
89
160
|
|
|
90
161
|
| Skill | 来源 | 说明 |
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# 🧠 AI 编程提示词模板库(按 Git Commit 类型分类)
|
|
2
|
+
|
|
3
|
+
> 融合 **Anthropic / Claude Code 官方最佳实践**、**OpenAI Codex CLI 文档**、**社区 1000+ 提示词审查** 以及 **吴恩达提示词工程课程** 的核心原则,提供可直接复制、填充的提示词模板。
|
|
4
|
+
> 覆盖 `feat` `fix` `doc` `refactor` `test` `chore` `perf` `style`,并补充 `security` 等高频类型。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 🧩 通用骨架(适用于所有类型)
|
|
9
|
+
|
|
10
|
+
每个高质量提示词都应包含以下结构,优先保证 **角色 + 任务 + 上下文** 清晰:
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
[类型] 简短标题(≤50字符)
|
|
14
|
+
|
|
15
|
+
**角色**:你是一个资深 [语言/框架/领域] 工程师/专家。
|
|
16
|
+
**背景/上下文**:项目技术栈、关键约束、当前现状、目标受众。
|
|
17
|
+
**具体任务**:明确要做什么,精确到文件/函数/行号。
|
|
18
|
+
**输出格式**:指定 diff / Markdown / 表格 / 列表 / 代码块等。
|
|
19
|
+
**验证指令**:要求 AI 提供自检方法(测试命令、预期输出、性能基准)。
|
|
20
|
+
**硬性约束**:禁止的行为(NEVER)、必须保持的规则、最小改动原则。
|
|
21
|
+
**深度思考**:对复杂问题要求列出权衡方案,客观分析利弊,避免谄媚。
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> ⚠️ 关键原则:**上下文精准 · 验证驱动 · 极简主义 · Plan 先行 · 硬性约束 · 对抗谄媚**
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 1. `feat` — 新功能 / 创意生成
|
|
29
|
+
|
|
30
|
+
> 核心口诀:**Plan 先行,验证兜底**
|
|
31
|
+
> 适合场景:头脑风暴新方案、功能设计、产品创意、模块开发
|
|
32
|
+
|
|
33
|
+
### 📝 详细版模板
|
|
34
|
+
```text
|
|
35
|
+
[feat] 在 [模块/文件] 中实现 [功能描述]
|
|
36
|
+
|
|
37
|
+
**角色**:你是一个资深 [TypeScript / Python / Rust] 工程师。
|
|
38
|
+
**背景**:项目使用 [技术栈,如 NestJS + Prisma],当前缺少 [具体能力],用户痛点是 [具体痛点]。
|
|
39
|
+
**任务**:
|
|
40
|
+
1. 先分析代码库结构,给出逐步实施计划(列出要修改/创建的文件、数据库迁移、对现有代码的假设)。
|
|
41
|
+
2. 计划经我确认后再编写代码。
|
|
42
|
+
3. 实现后编写测试用例验证核心逻辑,并运行 [测试命令] 确认通过。
|
|
43
|
+
**输出**:提供 unified diff 和两句话的变更说明。
|
|
44
|
+
**约束**:禁止顺手重构无关代码;保持所有公共 API 签名兼容;不要为假设性需求添加抽象层。
|
|
45
|
+
**验证**:运行 [npm test / cargo test] 确保无回归。
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### ⚡ 精简版模板
|
|
49
|
+
```text
|
|
50
|
+
Plan first — no code yet.
|
|
51
|
+
Implement [功能] in @file:[路径]。
|
|
52
|
+
Tech: [框架/库]。
|
|
53
|
+
Write a test to verify, then run [命令]。
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 🔑 关键提示
|
|
57
|
+
- 涉及 >2 个文件时,必须先进入 **Plan Mode**,Review 计划后动手。
|
|
58
|
+
- 明确 **角色 + 任务 + 上下文**,开局第一句话决定成败。
|
|
59
|
+
- 要求 AI 提供 **验证自己工作的方法**(测试、截图、预期输出),这是最高杠杆的实践。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 2. `fix` — 问题排查 / 错误修正
|
|
64
|
+
|
|
65
|
+
> 核心口诀:**根因修复,不消除症状**
|
|
66
|
+
> 适合场景:调试代码、修正逻辑错误、分析失败原因
|
|
67
|
+
|
|
68
|
+
### 📝 详细版模板
|
|
69
|
+
```text
|
|
70
|
+
[fix] 修复 @file:[文件路径] #L[行号] 中的 [Bug 描述]
|
|
71
|
+
|
|
72
|
+
**背景**:
|
|
73
|
+
- 输入:[粘贴出错内容或描述现象]
|
|
74
|
+
- 预期行为:[正确的结果]
|
|
75
|
+
- 当前错误:[错误信息/不符合预期的输出]
|
|
76
|
+
**任务**:
|
|
77
|
+
1. 不要仅仅消除报错(Suppress),要解决根本原因。
|
|
78
|
+
2. 先读取相关代码和日志,诊断根因(多步推理,不要先给结论)。
|
|
79
|
+
3. 提供至少一种修复方案,并说明为什么这样做。
|
|
80
|
+
4. 编写测试用例复现该 Bug 并确认修复有效。
|
|
81
|
+
**输出**:提供 diff 和两句话的根因分析。
|
|
82
|
+
**约束**:只修 bug,不做重构;最小化改动;不要假设错误是微不足道的。
|
|
83
|
+
**验证**:运行 [测试命令] 确认修复。
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### ⚡ 精简版模板
|
|
87
|
+
```text
|
|
88
|
+
Fix root cause, not the symptom.
|
|
89
|
+
@file:[路径] #L[行号] — [Bug 简述]。
|
|
90
|
+
Diagnose before patching. Minimum change only.
|
|
91
|
+
Write a test to verify.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 🔑 关键提示
|
|
95
|
+
- 明确 **诊断先于修补**,防止 AI 用 try-catch 吞掉错误。
|
|
96
|
+
- 精确指定 **文件和行号**,避免 AI 通读整个仓库。
|
|
97
|
+
- 要求 **编写测试** 来复现 Bug,确保修复有效且不会回归。
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 3. `doc` — 文档生成 / 总结
|
|
102
|
+
|
|
103
|
+
> 核心口诀:**面向读者,结构优先**
|
|
104
|
+
> 适合场景:撰写说明、注释、会议纪要、API 文档、README
|
|
105
|
+
|
|
106
|
+
### 📝 详细版模板
|
|
107
|
+
```text
|
|
108
|
+
[doc] 为 [模块/API] 撰写一份 [用户手册 / API 文档 / 决策报告]
|
|
109
|
+
|
|
110
|
+
**角色**:你是一位技术文档工程师。
|
|
111
|
+
**背景**:目标受众是 [小白 / 前端开发者 / 架构师],他们需要了解 [关键信息点]。
|
|
112
|
+
**已有材料**:[上传文件 / 粘贴原始笔记]
|
|
113
|
+
**任务**:
|
|
114
|
+
1. 提取核心要点,按逻辑结构重组(概述 → 快速开始 → 详细说明 → 常见问题)。
|
|
115
|
+
2. 添加至少 2 个真实可运行的示例(使用 [语言] 语法高亮)。
|
|
116
|
+
3. 如存在争议点,列出不同观点并注明“无共识”。
|
|
117
|
+
**输出格式**:Markdown 层级标题,必要时插入表格/列表。
|
|
118
|
+
**约束**:避免空洞词汇(如“细致入微”“深入探究”);每段都应有实质信息;保持原意,不添加原文没有的事实。
|
|
119
|
+
**验证**:请先提供大纲,经我确认后再扩展。
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### ⚡ 精简版模板
|
|
123
|
+
```text
|
|
124
|
+
Document [模块/API] for [目标读者].
|
|
125
|
+
Structure: overview → quickstart → API reference → ≥2 real examples.
|
|
126
|
+
Ensure code examples are runnable. Output Markdown.
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 🔑 关键提示
|
|
130
|
+
- 明确 **目标受众** 和 **输出格式**,让文档可落地。
|
|
131
|
+
- 要求 **先出大纲**,避免一次性生成冗长且离题的内容。
|
|
132
|
+
- 强调 **示例可运行**,提升文档的实用性。
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 4. `refactor` — 重构 / 优化现有结构
|
|
137
|
+
|
|
138
|
+
> 核心口诀:**手术式修改,行为不变**
|
|
139
|
+
> 适合场景:改进代码结构、拆分模块、改善可读性/可维护性
|
|
140
|
+
|
|
141
|
+
### 📝 详细版模板
|
|
142
|
+
```text
|
|
143
|
+
[refactor] 对 @file:[文件路径](约 [行数] 行)进行重构,提升 [可读性 / 可维护性]
|
|
144
|
+
|
|
145
|
+
**背景**:当前代码存在 [具体问题,如重复逻辑、耦合度高]。
|
|
146
|
+
**任务**:
|
|
147
|
+
1. 识别 3 个主要问题。
|
|
148
|
+
2. 提出重构方案,说明改动前后差异。
|
|
149
|
+
3. 输出重构后的完整版本。
|
|
150
|
+
**硬性约束**:
|
|
151
|
+
- 不改变任何行为,保留所有公共 API 签名不变。
|
|
152
|
+
- 禁止顺手优化、禁止添加新功能、禁止修改业务逻辑。
|
|
153
|
+
- 拆分后运行 [测试命令] 确认无回归。
|
|
154
|
+
**输出**:提供 diff 和新模块的依赖关系图。
|
|
155
|
+
**验证**:运行 [测试命令] 并确保全部通过。
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### ⚡ 精简版模板
|
|
159
|
+
```text
|
|
160
|
+
Surgical changes only.
|
|
161
|
+
Refactor @file:[路径] — [目标]。
|
|
162
|
+
Zero behavior change. Keep all public API signatures.
|
|
163
|
+
Run [测试命令] after. No optimization.
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### 🔑 关键提示
|
|
167
|
+
- 遵循 **Andrej Karpathy 的 “Surgical Changes”** 原则,只改必须改的地方。
|
|
168
|
+
- 明确“**不改变任何行为**”并用测试证明,是区分熟练使用者和新手的关键习惯。
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 5. `test` — 测试用例 / 评估
|
|
173
|
+
|
|
174
|
+
> 核心口诀:**表驱动,先红后绿**
|
|
175
|
+
> 适合场景:生成测试数据、编写单元/集成测试、设计验证标准
|
|
176
|
+
|
|
177
|
+
### 📝 详细版模板
|
|
178
|
+
```text
|
|
179
|
+
[test] 为 @file:[文件路径] 中的变更生成表驱动测试
|
|
180
|
+
|
|
181
|
+
**角色**:你是一个资深测试工程师。
|
|
182
|
+
**背景**:使用 [Jest / Vitest / pytest] 框架,追求 ≥[90]% 分支覆盖率。
|
|
183
|
+
**任务**:
|
|
184
|
+
1. 覆盖维度:null 值、空值、超时、幂等性、重试、成功路径、4xx/5xx 错误、边界条件 [列举具体边界]。
|
|
185
|
+
2. 优先让测试先失败(红),再提供补丁使其通过(绿)。
|
|
186
|
+
**输出格式**:表格列出场景 → 预期结果 → 权重,末尾附评分模板。
|
|
187
|
+
**约束**:评分准则必须无歧义;不要假设输入总是合法的。
|
|
188
|
+
**验证**:运行 [测试命令] 并展示覆盖率报告。
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### ⚡ 精简版模板
|
|
192
|
+
```text
|
|
193
|
+
Table-driven tests for @file:[路径].
|
|
194
|
+
Cover: nulls, timeouts, idempotency, edge cases.
|
|
195
|
+
Fail first, then pass. Use [框架]. Target ≥[90]% coverage.
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 🔑 关键提示
|
|
199
|
+
- **表驱动测试**(Table-Driven Tests)能覆盖更多边界条件。
|
|
200
|
+
- **先红后绿**(让测试先失败再通过)是验证测试有效性的最佳方式。
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 6. `chore` — 日常维护 / 杂项自动化
|
|
205
|
+
|
|
206
|
+
> 核心口诀:**只做必须,禁止顺手**
|
|
207
|
+
> 适合场景:依赖更新、构建配置、CI 调整、批量重命名、环境配置
|
|
208
|
+
|
|
209
|
+
### 📝 详细版模板
|
|
210
|
+
```text
|
|
211
|
+
[chore] 在 @file:[配置文件路径] 中 [更新依赖 / 修改构建脚本 / 调整 CI]
|
|
212
|
+
|
|
213
|
+
**角色**:你是一个 DevOps 工程师。
|
|
214
|
+
**背景**:当前环境 [描述],目标版本 [版本号]。
|
|
215
|
+
**任务**:
|
|
216
|
+
1. 只做 [具体任务],不做任何其他改动。
|
|
217
|
+
2. 改动后运行 [验证命令] 确认无破坏性变更。
|
|
218
|
+
**硬性约束**:
|
|
219
|
+
- NEVER 修改生产环境配置文件(如 config/production.yml)。
|
|
220
|
+
- NEVER 运行任何部署命令(除非用户明确要求)。
|
|
221
|
+
- 禁止顺手升级无关依赖、禁止修改代码逻辑。
|
|
222
|
+
**输出**:提供变更前后对比和影响说明。
|
|
223
|
+
**验证**:运行 [验证命令] 并展示结果。
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### ⚡ 精简版模板
|
|
227
|
+
```text
|
|
228
|
+
Only [具体任务] — no other changes.
|
|
229
|
+
@file:[路径] — [操作描述]。
|
|
230
|
+
NEVER touch production configs.
|
|
231
|
+
Run [验证命令] after.
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### 🔑 关键提示
|
|
235
|
+
- 使用 **NEVER + 明确豁免条件** 来锁死危险行为,比“尽量不要”有效得多。
|
|
236
|
+
- 明确 **“只做必须的”**,防止 AI 在杂务中顺手“优化”导致 CI 崩溃。
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## 7. `perf` — 性能优化
|
|
241
|
+
|
|
242
|
+
> 核心口诀:**先测量,后优化**
|
|
243
|
+
> 适合场景:查询优化、缓存策略、算法改进、减少 token 消耗
|
|
244
|
+
|
|
245
|
+
### 📝 详细版模板
|
|
246
|
+
```text
|
|
247
|
+
[perf] 优化 @file:[文件路径] 中的 [瓶颈描述]
|
|
248
|
+
|
|
249
|
+
**角色**:你是一位性能优化专家。
|
|
250
|
+
**背景**:当前执行耗时约 [X 秒] / 成本约 $Y,用户可接受的延迟为 [Z ms]。
|
|
251
|
+
**任务**:
|
|
252
|
+
1. Think deeply about this performance issue.
|
|
253
|
+
2. 先分析当前性能数据,给出基准指标。
|
|
254
|
+
3. 列出 ≥2 种优化方案,分析每个方案的预估提升幅度、实现复杂度、潜在风险。
|
|
255
|
+
4. 选择推荐方案并实现。优化后运行 [基准测试命令] 对比前后数据。
|
|
256
|
+
**输出**:提供 before/after 性能对比表格。
|
|
257
|
+
**约束**:不要牺牲核心准确性;优先给出低风险改动;不为了微优化牺牲可读性。
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### ⚡ 精简版模板
|
|
261
|
+
```text
|
|
262
|
+
Think deeply.
|
|
263
|
+
Optimize @file:[路径] — [瓶颈]。
|
|
264
|
+
≥2 approaches with trade-offs. Benchmark before & after.
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### 🔑 关键提示
|
|
268
|
+
- **“Think deeply”** 能触发 AI 的权衡分析,避免表面答案。
|
|
269
|
+
- **必须提供基准对比**,数据驱动决策,拒绝凭感觉优化。
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## 8. `style` — 风格 / 格式调整
|
|
274
|
+
|
|
275
|
+
> 核心口诀:**保持原意,统一规范**
|
|
276
|
+
> 适合场景:改写语气、统一术语、格式化代码、调整注释风格
|
|
277
|
+
|
|
278
|
+
### 📝 详细版模板
|
|
279
|
+
```text
|
|
280
|
+
[style] 将以下 [代码/文本] 调整为 [正式商务 / 幽默 / 简洁要点式 / Prettier 规范]
|
|
281
|
+
|
|
282
|
+
**原文**:[粘贴内容]
|
|
283
|
+
**任务**:
|
|
284
|
+
1. 保持原意和信息完整,仅改变表达风格 / 代码格式。
|
|
285
|
+
2. 术语统一为 [术语表,可选]。
|
|
286
|
+
3. 输出两种备选风格供我对比。
|
|
287
|
+
**约束**:不要添加原文没有的新事实,不要改变关键数据和逻辑;同时指出原文中可能存在的歧义表达。
|
|
288
|
+
**验证**:对代码运行 [linter / formatter 检查命令] 确保符合规范。
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### ⚡ 精简版模板
|
|
292
|
+
```text
|
|
293
|
+
Reformat [代码/文本] to [风格]。
|
|
294
|
+
Keep original meaning. Provide 2 style options for comparison.
|
|
295
|
+
Run [linter] after if code.
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### 🔑 关键提示
|
|
299
|
+
- 明确 **风格目标** 和 **术语表**,避免 AI 自由发挥。
|
|
300
|
+
- 对代码风格调整,务必配合 **自动化格式化工具** 验证。
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 🛡️ 补充类型
|
|
305
|
+
|
|
306
|
+
| 类型 | 用途 | 核心口诀 | 示例场景 |
|
|
307
|
+
| ---------- | -------- | ---------------------- | -------------------------------------- |
|
|
308
|
+
| `security` | 安全审查 | 独立审查,逐项排查 | 检查代码漏洞、提示词注入风险、密钥泄露 |
|
|
309
|
+
| `explain` | 概念解释 | 类比引导,由浅入深 | 向小白讲解复杂原理 |
|
|
310
|
+
| `compare` | 对比评估 | 多维矩阵,客观打分 | 多产品/多方案的优劣势分析 |
|
|
311
|
+
| `forecast` | 预测趋势 | 数据驱动,标明不确定性 | 基于数据预测未来走向 |
|
|
312
|
+
|
|
313
|
+
### `security` 详细模板
|
|
314
|
+
```text
|
|
315
|
+
[security] 对 @file:[文件路径] 运行安全审查
|
|
316
|
+
|
|
317
|
+
**角色**:你是一名安全审计专家(独立于编写代码的 Agent)。
|
|
318
|
+
**任务**:
|
|
319
|
+
1. 审查清单:认证边界、注入漏洞、敏感数据暴露、CSRF/CORS 配置、权限校验缺失。
|
|
320
|
+
2. 提供带行号的修复方案及理由。
|
|
321
|
+
3. 只审查不修改,输出审查报告。
|
|
322
|
+
**硬性约束**:在隔离上下文中运行,不继承主 Agent 的记忆。
|
|
323
|
+
**输出**:Markdown 报告,每个问题包含严重级别、行号、风险描述、修复建议。
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## 🧪 使用建议(融合最佳实践)
|
|
329
|
+
|
|
330
|
+
1. **启动新话题** — 清空无关上下文,每次新会话用 `Resume project X` 恢复状态(依赖 SESSION.md)。
|
|
331
|
+
2. **Plan 先行** — 对复杂任务(涉及 >2 个文件),先让 AI 输出计划,Review 后再编码。
|
|
332
|
+
3. **对抗谄媚** — 在约束中写明:“请客观评价,不要只说优点。若有不足,请明确指出。”
|
|
333
|
+
4. **渐进迭代** — 先让 AI 输出大纲/问题列表,反馈确认后再生成最终结果。
|
|
334
|
+
5. **多模型验证** — 将同一提示词发给 ChatGPT、Claude、Gemini,选出最佳输出。
|
|
335
|
+
6. **持久化规则** — 将团队规范、构建命令、常见陷阱写入 `CLAUDE.md` 或 `AGENTS.md`,每次会话自动加载。
|
|
336
|
+
7. **新会话 = 新开始** — 避免超长对话,上下文压缩风险在新会话中降至零。
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
> 💡 **核心原则**:上下文精准 · 验证驱动 · 极简主义 · Plan 先行 · 硬性约束 · 深度思考
|
|
341
|
+
> 模板中的 `[ ]` 为必填占位符,直接替换即可使用。
|
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev Prompts Extension
|
|
3
|
+
*
|
|
4
|
+
* Registers /dev-* commands that interactively collect missing context for
|
|
5
|
+
* high-quality prompt templates (from ai提示词优化.md) and send the assembled
|
|
6
|
+
* prompt directly to the main agent.
|
|
7
|
+
*
|
|
8
|
+
* Commands:
|
|
9
|
+
* /dev-feat - New feature / creative generation
|
|
10
|
+
* /dev-fix - Bug fix / error troubleshooting
|
|
11
|
+
* /dev-doc - Documentation generation
|
|
12
|
+
* /dev-refactor - Code refactoring
|
|
13
|
+
* /dev-test - Test case generation
|
|
14
|
+
* /dev-chore - Maintenance / automation
|
|
15
|
+
* /dev-perf - Performance optimization
|
|
16
|
+
* /dev-style - Style / format adjustment
|
|
17
|
+
* /dev-security - Security review
|
|
18
|
+
* /dev-explain - Concept explanation
|
|
19
|
+
* /dev-compare - Comparison evaluation
|
|
20
|
+
*
|
|
21
|
+
* Usage: type /dev-<type> and follow the wizard.
|
|
22
|
+
* Leave a field empty (Enter) to skip its section.
|
|
23
|
+
* Press Esc to cancel the entire wizard.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
27
|
+
|
|
28
|
+
// ── Helpers ──────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
/** Ask a single question. Returns `undefined` on cancel (Esc). */
|
|
31
|
+
async function ask(
|
|
32
|
+
ctx: ExtensionCommandContext,
|
|
33
|
+
label: string,
|
|
34
|
+
placeholder: string,
|
|
35
|
+
): Promise<string | undefined> {
|
|
36
|
+
return ctx.ui.input(label, { placeholder, required: false });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Check if a field value is empty or explicitly "无". */
|
|
40
|
+
function isEmpty(val: string | undefined): boolean {
|
|
41
|
+
return !val || val.trim() === "" || val.trim() === "无";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Wrap a non-empty value for template insertion. */
|
|
45
|
+
function wrap(val: string | undefined, fallback = "..."): string {
|
|
46
|
+
if (isEmpty(val)) return fallback;
|
|
47
|
+
return val!.trim();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ── Template Assemblers ──────────────────────────────────────
|
|
51
|
+
|
|
52
|
+
interface FeatFields {
|
|
53
|
+
language: string;
|
|
54
|
+
techStack: string;
|
|
55
|
+
module: string;
|
|
56
|
+
description: string;
|
|
57
|
+
painPoint: string;
|
|
58
|
+
testCmd: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function assembleFeatPrompt(f: FeatFields): string {
|
|
62
|
+
const lines: string[] = [];
|
|
63
|
+
lines.push(`[feat] 在 ${wrap(f.module)} 中实现 ${wrap(f.description)}`);
|
|
64
|
+
lines.push("");
|
|
65
|
+
lines.push(`**角色**:你是一个资深 ${wrap(f.language)} 工程师。`);
|
|
66
|
+
if (!isEmpty(f.techStack) || !isEmpty(f.painPoint)) {
|
|
67
|
+
lines.push(
|
|
68
|
+
`**背景**:项目使用 ${wrap(f.techStack)},当前缺少 ${wrap(f.description)}` +
|
|
69
|
+
(isEmpty(f.painPoint) ? "。" : `,用户痛点是 ${f.painPoint!.trim()}。`),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
lines.push("**任务**:");
|
|
73
|
+
lines.push("1. 先分析代码库结构,给出逐步实施计划(列出要修改/创建的文件、数据库迁移、对现有代码的假设)。");
|
|
74
|
+
lines.push("2. 计划经我确认后再编写代码。");
|
|
75
|
+
if (!isEmpty(f.testCmd)) {
|
|
76
|
+
lines.push(`3. 实现后编写测试用例验证核心逻辑,并运行 ${f.testCmd!.trim()} 确认通过。`);
|
|
77
|
+
} else {
|
|
78
|
+
lines.push("3. 实现后编写测试用例验证核心逻辑。");
|
|
79
|
+
}
|
|
80
|
+
lines.push("**输出**:提供 unified diff 和两句话的变更说明。");
|
|
81
|
+
lines.push("**约束**:禁止顺手重构无关代码;保持所有公共 API 签名兼容;不要为假设性需求添加抽象层。");
|
|
82
|
+
if (!isEmpty(f.testCmd)) {
|
|
83
|
+
lines.push(`**验证**:运行 ${f.testCmd!.trim()} 确保无回归。`);
|
|
84
|
+
}
|
|
85
|
+
return lines.join("\n");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface FixFields {
|
|
89
|
+
filePath: string;
|
|
90
|
+
lineNumber: string;
|
|
91
|
+
bugDesc: string;
|
|
92
|
+
inputDesc: string;
|
|
93
|
+
expected: string;
|
|
94
|
+
actualError: string;
|
|
95
|
+
testCmd: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function assembleFixPrompt(f: FixFields): string {
|
|
99
|
+
const lines: string[] = [];
|
|
100
|
+
const loc = isEmpty(f.lineNumber) ? f.filePath.trim() : `${f.filePath.trim()} #L${f.lineNumber!.trim()}`;
|
|
101
|
+
lines.push(`[fix] 修复 ${loc} 中的 ${wrap(f.bugDesc)}`);
|
|
102
|
+
lines.push("");
|
|
103
|
+
lines.push("**背景**:");
|
|
104
|
+
lines.push(`- 输入:${isEmpty(f.inputDesc) ? "见代码上下文" : f.inputDesc!.trim()}`);
|
|
105
|
+
lines.push(`- 预期行为:${wrap(f.expected, "请描述预期结果")}`);
|
|
106
|
+
lines.push(`- 当前错误:${wrap(f.actualError, "请描述当前错误")}`);
|
|
107
|
+
lines.push("**任务**:");
|
|
108
|
+
lines.push("1. 不要仅仅消除报错(Suppress),要解决根本原因。");
|
|
109
|
+
lines.push("2. 先读取相关代码和日志,诊断根因(多步推理,不要先给结论)。");
|
|
110
|
+
lines.push("3. 提供至少一种修复方案,并说明为什么这样做。");
|
|
111
|
+
lines.push("4. 编写测试用例复现该 Bug 并确认修复有效。");
|
|
112
|
+
lines.push("**输出**:提供 diff 和两句话的根因分析。");
|
|
113
|
+
lines.push("**约束**:只修 bug,不做重构;最小化改动;不要假设错误是微不足道的。");
|
|
114
|
+
if (!isEmpty(f.testCmd)) {
|
|
115
|
+
lines.push(`**验证**:运行 ${f.testCmd!.trim()} 确认修复。`);
|
|
116
|
+
}
|
|
117
|
+
return lines.join("\n");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
interface DocFields {
|
|
121
|
+
moduleName: string;
|
|
122
|
+
audience: string;
|
|
123
|
+
keyInfo: string;
|
|
124
|
+
language: string;
|
|
125
|
+
existingMaterial: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function assembleDocPrompt(f: DocFields): string {
|
|
129
|
+
const lines: string[] = [];
|
|
130
|
+
lines.push(`[doc] 为 ${wrap(f.moduleName)} 撰写一份文档`);
|
|
131
|
+
lines.push("");
|
|
132
|
+
lines.push("**角色**:你是一位技术文档工程师。");
|
|
133
|
+
if (!isEmpty(f.audience) || !isEmpty(f.keyInfo)) {
|
|
134
|
+
lines.push(`**背景**:目标受众是 ${wrap(f.audience)},他们需要了解 ${wrap(f.keyInfo)}。`);
|
|
135
|
+
}
|
|
136
|
+
lines.push("**任务**:");
|
|
137
|
+
lines.push("1. 提取核心要点,按逻辑结构重组(概述 → 快速开始 → 详细说明 → 常见问题)。");
|
|
138
|
+
lines.push(`2. 添加至少 2 个真实可运行的示例(使用 ${wrap(f.language)} 语法高亮)。`);
|
|
139
|
+
lines.push("3. 如存在争议点,列出不同观点并注明\"无共识\"。");
|
|
140
|
+
if (!isEmpty(f.existingMaterial)) {
|
|
141
|
+
lines.push(`**已有材料**:${f.existingMaterial!.trim()}`);
|
|
142
|
+
}
|
|
143
|
+
lines.push("**输出格式**:Markdown 层级标题,必要时插入表格/列表。");
|
|
144
|
+
lines.push("**约束**:避免空洞词汇(如\"细致入微\"\"深入探究\");每段都应有实质信息;保持原意,不添加原文没有的事实。");
|
|
145
|
+
lines.push("**验证**:请先提供大纲,经我确认后再扩展。");
|
|
146
|
+
return lines.join("\n");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
interface RefactorFields {
|
|
150
|
+
filePath: string;
|
|
151
|
+
lineCount: string;
|
|
152
|
+
problems: string;
|
|
153
|
+
goal: string;
|
|
154
|
+
testCmd: string;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function assembleRefactorPrompt(f: RefactorFields): string {
|
|
158
|
+
const lines: string[] = [];
|
|
159
|
+
const loc = isEmpty(f.lineCount) ? f.filePath.trim() : `${f.filePath.trim()}(约 ${f.lineCount!.trim()} 行)`;
|
|
160
|
+
lines.push(`[refactor] 对 ${loc} 进行重构,提升 ${wrap(f.goal, "可读性 / 可维护性")}`);
|
|
161
|
+
lines.push("");
|
|
162
|
+
lines.push(`**背景**:当前代码存在 ${wrap(f.problems)}。`);
|
|
163
|
+
lines.push("**任务**:");
|
|
164
|
+
lines.push("1. 识别 3 个主要问题。");
|
|
165
|
+
lines.push("2. 提出重构方案,说明改动前后差异。");
|
|
166
|
+
lines.push("3. 输出重构后的完整版本。");
|
|
167
|
+
lines.push("**硬性约束**:");
|
|
168
|
+
lines.push("- 不改变任何行为,保留所有公共 API 签名不变。");
|
|
169
|
+
lines.push("- 禁止顺手优化、禁止添加新功能、禁止修改业务逻辑。");
|
|
170
|
+
if (!isEmpty(f.testCmd)) {
|
|
171
|
+
lines.push(`- 拆分后运行 ${f.testCmd!.trim()} 确认无回归。`);
|
|
172
|
+
}
|
|
173
|
+
lines.push("**输出**:提供 diff 和新模块的依赖关系图。");
|
|
174
|
+
if (!isEmpty(f.testCmd)) {
|
|
175
|
+
lines.push(`**验证**:运行 ${f.testCmd!.trim()} 并确保全部通过。`);
|
|
176
|
+
}
|
|
177
|
+
return lines.join("\n");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
interface TestFields {
|
|
181
|
+
filePath: string;
|
|
182
|
+
framework: string;
|
|
183
|
+
coverage: string;
|
|
184
|
+
edgeCases: string;
|
|
185
|
+
testCmd: string;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function assembleTestPrompt(f: TestFields): string {
|
|
189
|
+
const lines: string[] = [];
|
|
190
|
+
lines.push(`[test] 为 ${wrap(f.filePath)} 中的变更生成表驱动测试`);
|
|
191
|
+
lines.push("");
|
|
192
|
+
lines.push(`**角色**:你是一个资深测试工程师。`);
|
|
193
|
+
lines.push(`**背景**:使用 ${wrap(f.framework)} 框架,追求 ≥${wrap(f.coverage, "90")}% 分支覆盖率。`);
|
|
194
|
+
lines.push("**任务**:");
|
|
195
|
+
lines.push(`1. 覆盖维度:${isEmpty(f.edgeCases) ? "null 值、空值、超时、幂等性、重试、成功路径、4xx/5xx 错误、边界条件" : f.edgeCases!.trim()}。`);
|
|
196
|
+
lines.push("2. 优先让测试先失败(红),再提供补丁使其通过(绿)。");
|
|
197
|
+
lines.push("**输出格式**:表格列出场景 → 预期结果 → 权重,末尾附评分模板。");
|
|
198
|
+
lines.push("**约束**:评分准则必须无歧义;不要假设输入总是合法的。");
|
|
199
|
+
if (!isEmpty(f.testCmd)) {
|
|
200
|
+
lines.push(`**验证**:运行 ${f.testCmd!.trim()} 并展示覆盖率报告。`);
|
|
201
|
+
}
|
|
202
|
+
return lines.join("\n");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
interface ChoreFields {
|
|
206
|
+
configPath: string;
|
|
207
|
+
task: string;
|
|
208
|
+
envDesc: string;
|
|
209
|
+
targetVersion: string;
|
|
210
|
+
verifyCmd: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function assembleChorePrompt(f: ChoreFields): string {
|
|
214
|
+
const lines: string[] = [];
|
|
215
|
+
lines.push(`[chore] 在 ${wrap(f.configPath)} 中 ${wrap(f.task)}`);
|
|
216
|
+
lines.push("");
|
|
217
|
+
lines.push("**角色**:你是一个 DevOps 工程师。");
|
|
218
|
+
lines.push(`**背景**:当前环境 ${wrap(f.envDesc)},目标版本 ${wrap(f.targetVersion)}。`);
|
|
219
|
+
lines.push("**任务**:");
|
|
220
|
+
lines.push(`1. 只做 ${wrap(f.task)},不做任何其他改动。`);
|
|
221
|
+
if (!isEmpty(f.verifyCmd)) {
|
|
222
|
+
lines.push(`2. 改动后运行 ${f.verifyCmd!.trim()} 确认无破坏性变更。`);
|
|
223
|
+
}
|
|
224
|
+
lines.push("**硬性约束**:");
|
|
225
|
+
lines.push("- NEVER 修改生产环境配置文件(如 config/production.yml)。");
|
|
226
|
+
lines.push("- NEVER 运行任何部署命令(除非用户明确要求)。");
|
|
227
|
+
lines.push("- 禁止顺手升级无关依赖、禁止修改代码逻辑。");
|
|
228
|
+
lines.push("**输出**:提供变更前后对比和影响说明。");
|
|
229
|
+
if (!isEmpty(f.verifyCmd)) {
|
|
230
|
+
lines.push(`**验证**:运行 ${f.verifyCmd!.trim()} 并展示结果。`);
|
|
231
|
+
}
|
|
232
|
+
return lines.join("\n");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
interface PerfFields {
|
|
236
|
+
filePath: string;
|
|
237
|
+
bottleneck: string;
|
|
238
|
+
currentCost: string;
|
|
239
|
+
targetLatency: string;
|
|
240
|
+
benchCmd: string;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function assemblePerfPrompt(f: PerfFields): string {
|
|
244
|
+
const lines: string[] = [];
|
|
245
|
+
lines.push(`[perf] 优化 ${wrap(f.filePath)} 中的 ${wrap(f.bottleneck)}`);
|
|
246
|
+
lines.push("");
|
|
247
|
+
lines.push("**角色**:你是一位性能优化专家。");
|
|
248
|
+
lines.push(`**背景**:当前执行耗时约 ${wrap(f.currentCost)},用户可接受的延迟为 ${wrap(f.targetLatency)}。`);
|
|
249
|
+
lines.push("**任务**:");
|
|
250
|
+
lines.push("1. Think deeply about this performance issue.");
|
|
251
|
+
lines.push("2. 先分析当前性能数据,给出基准指标。");
|
|
252
|
+
lines.push("3. 列出 ≥2 种优化方案,分析每个方案的预估提升幅度、实现复杂度、潜在风险。");
|
|
253
|
+
if (!isEmpty(f.benchCmd)) {
|
|
254
|
+
lines.push(`4. 选择推荐方案并实现。优化后运行 ${f.benchCmd!.trim()} 对比前后数据。`);
|
|
255
|
+
} else {
|
|
256
|
+
lines.push("4. 选择推荐方案并实现。优化后运行基准测试对比前后数据。");
|
|
257
|
+
}
|
|
258
|
+
lines.push("**输出**:提供 before/after 性能对比表格。");
|
|
259
|
+
lines.push("**约束**:不要牺牲核心准确性;优先给出低风险改动;不为了微优化牺牲可读性。");
|
|
260
|
+
return lines.join("\n");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
interface StyleFields {
|
|
264
|
+
targetStyle: string;
|
|
265
|
+
description: string;
|
|
266
|
+
terms: string;
|
|
267
|
+
lintCmd: string;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function assembleStylePrompt(f: StyleFields): string {
|
|
271
|
+
const lines: string[] = [];
|
|
272
|
+
lines.push(`[style] 将以下内容调整为 ${wrap(f.targetStyle)}`);
|
|
273
|
+
lines.push("");
|
|
274
|
+
lines.push("**角色**:你是一个代码风格专家。");
|
|
275
|
+
lines.push(`**原文**:${wrap(f.description, "(见当前上下文)")}`);
|
|
276
|
+
lines.push("**任务**:");
|
|
277
|
+
lines.push("1. 保持原意和信息完整,仅改变表达风格/代码格式。");
|
|
278
|
+
if (!isEmpty(f.terms)) {
|
|
279
|
+
lines.push(`2. 术语统一为:${f.terms!.trim()}。`);
|
|
280
|
+
lines.push("3. 输出两种备选风格供我对比。");
|
|
281
|
+
} else {
|
|
282
|
+
lines.push("2. 输出两种备选风格供我对比。");
|
|
283
|
+
}
|
|
284
|
+
lines.push("**约束**:不要添加原文没有的新事实,不要改变关键数据和逻辑;同时指出原文中可能存在的歧义表达。");
|
|
285
|
+
if (!isEmpty(f.lintCmd)) {
|
|
286
|
+
lines.push(`**验证**:对代码运行 ${f.lintCmd!.trim()} 确保符合规范。`);
|
|
287
|
+
}
|
|
288
|
+
return lines.join("\n");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
interface SecurityFields {
|
|
292
|
+
filePath: string;
|
|
293
|
+
focus: string;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function assembleSecurityPrompt(f: SecurityFields): string {
|
|
297
|
+
const lines: string[] = [];
|
|
298
|
+
lines.push(`[security] 对 ${wrap(f.filePath)} 运行安全审查`);
|
|
299
|
+
lines.push("");
|
|
300
|
+
lines.push("**角色**:你是一名安全审计专家(独立于编写代码的 Agent)。");
|
|
301
|
+
lines.push("**任务**:");
|
|
302
|
+
lines.push(`1. 审查清单:${isEmpty(f.focus) ? "认证边界、注入漏洞、敏感数据暴露、CSRF/CORS 配置、权限校验缺失" : f.focus!.trim()}。`);
|
|
303
|
+
lines.push("2. 提供带行号的修复方案及理由。");
|
|
304
|
+
lines.push("3. 只审查不修改,输出审查报告。");
|
|
305
|
+
lines.push("**硬性约束**:在隔离上下文中运行,不继承主 Agent 的记忆。");
|
|
306
|
+
lines.push("**输出**:Markdown 报告,每个问题包含严重级别、行号、风险描述、修复建议。");
|
|
307
|
+
return lines.join("\n");
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
interface ExplainFields {
|
|
311
|
+
concept: string;
|
|
312
|
+
audience: string;
|
|
313
|
+
depth: string;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function assembleExplainPrompt(f: ExplainFields): string {
|
|
317
|
+
const lines: string[] = [];
|
|
318
|
+
lines.push(`[explain] 解释 ${wrap(f.concept)}`);
|
|
319
|
+
lines.push("");
|
|
320
|
+
lines.push("**角色**:你是一位资深技术导师,擅长用类比引导初学者理解复杂概念。");
|
|
321
|
+
lines.push(`**背景**:目标受众是 ${wrap(f.audience)},需要理解 ${wrap(f.concept)} 的 ${wrap(f.depth, "基础")} 层面。`);
|
|
322
|
+
lines.push("**任务**:");
|
|
323
|
+
lines.push("1. 用生活化的类比引入概念,建立直觉。");
|
|
324
|
+
lines.push("2. 由浅入深逐步展开,先给大局观再进入细节。");
|
|
325
|
+
lines.push("3. 提供至少一个真实世界的应用场景。");
|
|
326
|
+
lines.push("4. 如有常见误区,明确指出。");
|
|
327
|
+
lines.push("**输出格式**:Markdown,必要时插入图示描述。");
|
|
328
|
+
lines.push("**验证**:请先给出一句话总结,经我确认后再展开。");
|
|
329
|
+
return lines.join("\n");
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
interface CompareFields {
|
|
333
|
+
itemA: string;
|
|
334
|
+
itemB: string;
|
|
335
|
+
dimensions: string;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function assembleComparePrompt(f: CompareFields): string {
|
|
339
|
+
const lines: string[] = [];
|
|
340
|
+
lines.push(`[compare] 对比 ${wrap(f.itemA)} 与 ${wrap(f.itemB)}`);
|
|
341
|
+
lines.push("");
|
|
342
|
+
lines.push("**角色**:你是一位客观中立的评测专家。");
|
|
343
|
+
lines.push(`**背景**:需要从 ${wrap(f.dimensions, "多个方面")} 对 ${wrap(f.itemA)} 和 ${wrap(f.itemB)} 进行全面对比。`);
|
|
344
|
+
lines.push("**任务**:");
|
|
345
|
+
lines.push("1. 构建多维度评估矩阵,量化或半量化评分。");
|
|
346
|
+
lines.push("2. 分析各维度的权衡(Trade-offs),说明在什么场景下哪个更优。");
|
|
347
|
+
lines.push("3. 给出综合结论和建议。");
|
|
348
|
+
lines.push("**输出格式**:Markdown 表格 + 简短分析。");
|
|
349
|
+
lines.push("**约束**:客观中立,不偏袒任何一方,明确标注不确定的结论。");
|
|
350
|
+
return lines.join("\n");
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// ── Command runner ───────────────────────────────────────────
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Run a wizard: ask questions, assemble prompt, send to agent.
|
|
357
|
+
* @param ctx Command context
|
|
358
|
+
* @param pi Extension API (for sendUserMessage)
|
|
359
|
+
* @param type Display name of the prompt type (e.g. "feat")
|
|
360
|
+
* @param label Friendly label (e.g. "新功能/创意生成")
|
|
361
|
+
* @param questions Array of [label, placeholder] pairs
|
|
362
|
+
* @param assembler Function that takes answers and returns the prompt string
|
|
363
|
+
*/
|
|
364
|
+
async function runWizard(
|
|
365
|
+
ctx: ExtensionCommandContext,
|
|
366
|
+
pi: ExtensionAPI,
|
|
367
|
+
type: string,
|
|
368
|
+
label: string,
|
|
369
|
+
questions: Array<{ label: string; placeholder: string; key: string }>,
|
|
370
|
+
assembler: (answers: Record<string, string>) => string,
|
|
371
|
+
): Promise<void> {
|
|
372
|
+
ctx.ui.notify(`📋 /dev-${type} — ${label},请逐项填写以下信息(留空跳过对应段落,Esc 取消)`, "info");
|
|
373
|
+
|
|
374
|
+
const answers: Record<string, string> = {};
|
|
375
|
+
|
|
376
|
+
for (const q of questions) {
|
|
377
|
+
const val = await ask(ctx, q.label, q.placeholder);
|
|
378
|
+
if (val === undefined) {
|
|
379
|
+
ctx.ui.notify("❌ 已取消", "warning");
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
answers[q.key] = val;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const prompt = assembler(answers);
|
|
386
|
+
ctx.ui.notify(`✅ 提示词已组装完成,正在发送给主代理...`, "success");
|
|
387
|
+
|
|
388
|
+
// Send the assembled prompt to the main agent
|
|
389
|
+
pi.sendUserMessage(prompt);
|
|
390
|
+
|
|
391
|
+
// Also show the prompt in a notification for reference
|
|
392
|
+
ctx.ui.notify(`📝 /dev-${type} 提示词已投递,主代理正在处理`, "info");
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// ── Questions for each command ────────────────────────────────
|
|
396
|
+
|
|
397
|
+
const FEAT_QUESTIONS = [
|
|
398
|
+
{ label: "编程语言/框架", placeholder: "如 TypeScript, Python, Rust...", key: "language" },
|
|
399
|
+
{ label: "技术栈", placeholder: "如 NestJS + Prisma, React + Express...", key: "techStack" },
|
|
400
|
+
{ label: "目标模块/文件名", placeholder: "如 src/auth/login.ts", key: "module" },
|
|
401
|
+
{ label: "核心功能描述", placeholder: "用户可以通过邮箱+密码注册并登录", key: "description" },
|
|
402
|
+
{ label: "用户痛点/当前缺少", placeholder: "当前缺少用户认证系统,每次手动校验身份", key: "painPoint" },
|
|
403
|
+
{ label: "测试命令(可选)", placeholder: "如 npm test, cargo test, go test...", key: "testCmd" },
|
|
404
|
+
];
|
|
405
|
+
|
|
406
|
+
const FIX_QUESTIONS = [
|
|
407
|
+
{ label: "文件路径", placeholder: "如 src/auth/login.ts", key: "filePath" },
|
|
408
|
+
{ label: "行号(可选)", placeholder: "如 42,留空则扫描整个文件", key: "lineNumber" },
|
|
409
|
+
{ label: "Bug 描述", placeholder: "登录接口在密码正确时返回 401", key: "bugDesc" },
|
|
410
|
+
{ label: "输入/现象", placeholder: "输入正确邮箱和密码,返回 401 错误", key: "inputDesc" },
|
|
411
|
+
{ label: "预期行为", placeholder: "应返回 200 和 token", key: "expected" },
|
|
412
|
+
{ label: "当前错误信息", placeholder: "Unauthorized (401) - 不符合预期的输出", key: "actualError" },
|
|
413
|
+
{ label: "测试命令(可选)", placeholder: "如 npm test, go test...", key: "testCmd" },
|
|
414
|
+
];
|
|
415
|
+
|
|
416
|
+
const DOC_QUESTIONS = [
|
|
417
|
+
{ label: "模块/API 名称", placeholder: "如 AuthService, REST API v2...", key: "moduleName" },
|
|
418
|
+
{ label: "目标受众", placeholder: "如 小白 / 前端开发者 / 架构师", key: "audience" },
|
|
419
|
+
{ label: "关键信息点", placeholder: "他们需要了解如何使用认证接口", key: "keyInfo" },
|
|
420
|
+
{ label: "示例语言", placeholder: "如 TypeScript, Python, curl...", key: "language" },
|
|
421
|
+
{ label: "已有材料(可选)", placeholder: "现有 README、笔记、文件路径等,留空则从零生成", key: "existingMaterial" },
|
|
422
|
+
];
|
|
423
|
+
|
|
424
|
+
const REFACTOR_QUESTIONS = [
|
|
425
|
+
{ label: "文件路径", placeholder: "如 src/auth/login.ts", key: "filePath" },
|
|
426
|
+
{ label: "代码行数(可选)", placeholder: "如 200 行", key: "lineCount" },
|
|
427
|
+
{ label: "具体问题", placeholder: "如 重复逻辑、耦合度高、可读性差", key: "problems" },
|
|
428
|
+
{ label: "重构目标", placeholder: "如 可读性 / 可维护性 / 模块化", key: "goal" },
|
|
429
|
+
{ label: "测试命令(可选)", placeholder: "如 npm test, cargo test...", key: "testCmd" },
|
|
430
|
+
];
|
|
431
|
+
|
|
432
|
+
const TEST_QUESTIONS = [
|
|
433
|
+
{ label: "文件路径", placeholder: "如 src/auth/login.ts", key: "filePath" },
|
|
434
|
+
{ label: "测试框架", placeholder: "如 Jest / Vitest / pytest / Go test", key: "framework" },
|
|
435
|
+
{ label: "目标覆盖率", placeholder: "如 90,留空默认 90%", key: "coverage" },
|
|
436
|
+
{ label: "边界条件", placeholder: "如 null 值、空值、超时、幂等性、4xx/5xx 错误", key: "edgeCases" },
|
|
437
|
+
{ label: "测试命令(可选)", placeholder: "如 npm test -- --coverage", key: "testCmd" },
|
|
438
|
+
];
|
|
439
|
+
|
|
440
|
+
const CHORE_QUESTIONS = [
|
|
441
|
+
{ label: "配置文件/目标路径", placeholder: "如 package.json, .github/workflows/ci.yml", key: "configPath" },
|
|
442
|
+
{ label: "具体任务", placeholder: "如 更新依赖、修改构建脚本、调整 CI 配置", key: "task" },
|
|
443
|
+
{ label: "当前环境描述", placeholder: "如 Node 18, pnpm 8", key: "envDesc" },
|
|
444
|
+
{ label: "目标版本", placeholder: "如 Node 20, pnpm 9", key: "targetVersion" },
|
|
445
|
+
{ label: "验证命令(可选)", placeholder: "如 npm run build, pnpm test...", key: "verifyCmd" },
|
|
446
|
+
];
|
|
447
|
+
|
|
448
|
+
const PERF_QUESTIONS = [
|
|
449
|
+
{ label: "文件路径", placeholder: "如 src/services/query.ts", key: "filePath" },
|
|
450
|
+
{ label: "瓶颈描述", placeholder: "如 数据库查询延迟过高、内存泄漏", key: "bottleneck" },
|
|
451
|
+
{ label: "当前执行耗时", placeholder: "如 5 秒 / 成本 $0.02/次", key: "currentCost" },
|
|
452
|
+
{ label: "目标延迟", placeholder: "如 200ms", key: "targetLatency" },
|
|
453
|
+
{ label: "基准测试命令(可选)", placeholder: "如 npm run bench, go test -bench=.", key: "benchCmd" },
|
|
454
|
+
];
|
|
455
|
+
|
|
456
|
+
const STYLE_QUESTIONS = [
|
|
457
|
+
{ label: "目标风格", placeholder: "如 正式商务 / 幽默 / 简洁要点式 / Prettier 规范", key: "targetStyle" },
|
|
458
|
+
{ label: "待调整内容描述", placeholder: "如 以下函数需要调整命名风格,或粘贴文本", key: "description" },
|
|
459
|
+
{ label: "术语统一(可选)", placeholder: "如 API → 接口, user → 用户", key: "terms" },
|
|
460
|
+
{ label: "Linter/格式化命令(可选)", placeholder: "如 npx prettier --check, npm run lint", key: "lintCmd" },
|
|
461
|
+
];
|
|
462
|
+
|
|
463
|
+
const SECURITY_QUESTIONS = [
|
|
464
|
+
{ label: "文件路径", placeholder: "如 src/api/auth.ts", key: "filePath" },
|
|
465
|
+
{ label: "审查重点(可选)", placeholder: "如 认证边界、注入漏洞、敏感数据暴露、CSRF/CORS、权限校验", key: "focus" },
|
|
466
|
+
];
|
|
467
|
+
|
|
468
|
+
const EXPLAIN_QUESTIONS = [
|
|
469
|
+
{ label: "概念名称", placeholder: "如 React Server Component, HTTP/3", key: "concept" },
|
|
470
|
+
{ label: "目标受众", placeholder: "如 小白 / 开发者 / 架构师", key: "audience" },
|
|
471
|
+
{ label: "理解深度(可选)", placeholder: "如 基础 / 进阶,留空默认基础", key: "depth" },
|
|
472
|
+
];
|
|
473
|
+
|
|
474
|
+
const COMPARE_QUESTIONS = [
|
|
475
|
+
{ label: "对比对象 A", placeholder: "如 Vue 3, Next.js, PostgreSQL...", key: "itemA" },
|
|
476
|
+
{ label: "对比对象 B", placeholder: "如 React 18, Nuxt 3, MySQL...", key: "itemB" },
|
|
477
|
+
{ label: "评估维度(可选)", placeholder: "如 性能、生态、学习曲线、社区支持", key: "dimensions" },
|
|
478
|
+
];
|
|
479
|
+
|
|
480
|
+
// ── Extension ────────────────────────────────────────────────
|
|
481
|
+
|
|
482
|
+
export default function (pi: ExtensionAPI) {
|
|
483
|
+
// ── /dev-feat ──────────────────────────────────────────────
|
|
484
|
+
pi.registerCommand("dev-feat", {
|
|
485
|
+
description: "(prompt wizard) 新功能/创意生成 — 交互填写后发送优化提示词给主代理",
|
|
486
|
+
handler: async (args, ctx) => {
|
|
487
|
+
await runWizard(ctx, pi, "feat", "新功能/创意生成", FEAT_QUESTIONS, assembleFeatPrompt);
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
// ── /dev-fix ───────────────────────────────────────────────
|
|
492
|
+
pi.registerCommand("dev-fix", {
|
|
493
|
+
description: "(prompt wizard) 问题排查/错误修正 — 交互填写后发送优化提示词给主代理",
|
|
494
|
+
handler: async (args, ctx) => {
|
|
495
|
+
await runWizard(ctx, pi, "fix", "问题排查/错误修正", FIX_QUESTIONS, assembleFixPrompt);
|
|
496
|
+
},
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
// ── /dev-doc ───────────────────────────────────────────────
|
|
500
|
+
pi.registerCommand("dev-doc", {
|
|
501
|
+
description: "(prompt wizard) 文档生成/总结 — 交互填写后发送优化提示词给主代理",
|
|
502
|
+
handler: async (args, ctx) => {
|
|
503
|
+
await runWizard(ctx, pi, "doc", "文档生成/总结", DOC_QUESTIONS, assembleDocPrompt);
|
|
504
|
+
},
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
// ── /dev-refactor ──────────────────────────────────────────
|
|
508
|
+
pi.registerCommand("dev-refactor", {
|
|
509
|
+
description: "(prompt wizard) 重构/优化现有结构 — 交互填写后发送优化提示词给主代理",
|
|
510
|
+
handler: async (args, ctx) => {
|
|
511
|
+
await runWizard(ctx, pi, "refactor", "重构/优化", REFACTOR_QUESTIONS, assembleRefactorPrompt);
|
|
512
|
+
},
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// ── /dev-test ──────────────────────────────────────────────
|
|
516
|
+
pi.registerCommand("dev-test", {
|
|
517
|
+
description: "(prompt wizard) 测试用例生成 — 交互填写后发送优化提示词给主代理",
|
|
518
|
+
handler: async (args, ctx) => {
|
|
519
|
+
await runWizard(ctx, pi, "test", "测试用例/评估", TEST_QUESTIONS, assembleTestPrompt);
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
// ── /dev-chore ─────────────────────────────────────────────
|
|
524
|
+
pi.registerCommand("dev-chore", {
|
|
525
|
+
description: "(prompt wizard) 日常维护/杂项自动化 — 交互填写后发送优化提示词给主代理",
|
|
526
|
+
handler: async (args, ctx) => {
|
|
527
|
+
await runWizard(ctx, pi, "chore", "日常维护/自动化", CHORE_QUESTIONS, assembleChorePrompt);
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// ── /dev-perf ──────────────────────────────────────────────
|
|
532
|
+
pi.registerCommand("dev-perf", {
|
|
533
|
+
description: "(prompt wizard) 性能优化 — 交互填写后发送优化提示词给主代理",
|
|
534
|
+
handler: async (args, ctx) => {
|
|
535
|
+
await runWizard(ctx, pi, "perf", "性能优化", PERF_QUESTIONS, assemblePerfPrompt);
|
|
536
|
+
},
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// ── /dev-style ─────────────────────────────────────────────
|
|
540
|
+
pi.registerCommand("dev-style", {
|
|
541
|
+
description: "(prompt wizard) 风格/格式调整 — 交互填写后发送优化提示词给主代理",
|
|
542
|
+
handler: async (args, ctx) => {
|
|
543
|
+
await runWizard(ctx, pi, "style", "风格/格式调整", STYLE_QUESTIONS, assembleStylePrompt);
|
|
544
|
+
},
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
// ── /dev-security ──────────────────────────────────────────
|
|
548
|
+
pi.registerCommand("dev-security", {
|
|
549
|
+
description: "(prompt wizard) 安全审查 — 交互填写后发送优化提示词给主代理",
|
|
550
|
+
handler: async (args, ctx) => {
|
|
551
|
+
await runWizard(ctx, pi, "security", "安全审查", SECURITY_QUESTIONS, assembleSecurityPrompt);
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
// ── /dev-explain ───────────────────────────────────────────
|
|
556
|
+
pi.registerCommand("dev-explain", {
|
|
557
|
+
description: "(prompt wizard) 概念解释 — 交互填写后发送优化提示词给主代理",
|
|
558
|
+
handler: async (args, ctx) => {
|
|
559
|
+
await runWizard(ctx, pi, "explain", "概念解释", EXPLAIN_QUESTIONS, assembleExplainPrompt);
|
|
560
|
+
},
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
// ── /dev-compare ───────────────────────────────────────────
|
|
564
|
+
pi.registerCommand("dev-compare", {
|
|
565
|
+
description: "(prompt wizard) 对比评估 — 交互填写后发送优化提示词给主代理",
|
|
566
|
+
handler: async (args, ctx) => {
|
|
567
|
+
await runWizard(ctx, pi, "compare", "对比评估", COMPARE_QUESTIONS, assembleComparePrompt);
|
|
568
|
+
},
|
|
569
|
+
});
|
|
570
|
+
}
|