初始化
This commit is contained in:
184
.cursor/skills/debugging/SKILL.md
Normal file
184
.cursor/skills/debugging/SKILL.md
Normal file
@@ -0,0 +1,184 @@
|
||||
---
|
||||
name: debugging
|
||||
version: 2.0.0
|
||||
description: "七步法系统化调试工作流。当用户报告 Bug、错误、异常、截图指出界面问题或功能与预期不符时使用。含信号解析和结构化调试报告。"
|
||||
---
|
||||
|
||||
> ⚠️ 核心执行流程已在 `.cursor/rules/skill-debugging.mdc` 中由 Cursor 自动注入。
|
||||
> 本文件提供完整模板、代码示例和边缘场景处理,供 Agent 按需深入 Read。
|
||||
|
||||
# Debugging Workflow
|
||||
|
||||
## 触发条件
|
||||
|
||||
用户报告错误、异常、意外行为,或请求排查问题。包含但不限于:
|
||||
|
||||
| 来源 | 典型表现 | 示例 |
|
||||
|---|---|---|
|
||||
| 运行时错误 | 控制台报错、崩溃、白屏 | "点击按钮报 500" |
|
||||
| 视觉/UI 异常 | 组件显示与预期不符 | "暗色模式下输入框是白色" |
|
||||
| 截图指出问题 | 用户提供截图标注异常区域 | 附图 + "这里不对" |
|
||||
| 功能失效 | 操作无响应或结果错误 | "筛选没有效果" |
|
||||
| 样式回归 | 改动后样式错乱 | "更新后布局乱了" |
|
||||
|
||||
> ⚠️ **截图 = Bug 报告**:用户提供截图并指出问题,本质是视觉 Bug 报告,必须激活本技能。
|
||||
|
||||
## 七步法
|
||||
|
||||
### -1. 截图前置守卫 (Screenshot Guard)
|
||||
|
||||
收到用户消息时,**先检查输入形式**,再分析文字意图:
|
||||
|
||||
| 输入形式 | 问题关键词 | 判定 |
|
||||
|---------|-----------|------|
|
||||
| 包含截图/图片 | 不合理 / 不对 / 有问题 / 调整 / 修复 / 偏了 / 太大 / 太小 / 空白 / 溢出 / 错位 | → 视觉 Bug,激活完整调试流程 |
|
||||
| 包含截图/图片 | 新增 / 添加 / 改为 / 参考这个 / 照着做 | → 需求变更,走正常开发流程 |
|
||||
|
||||
**硬规则**:无论判定结果是哪条路径,都**必须在回复开头输出守卫判定块**:
|
||||
|
||||
```
|
||||
## 截图守卫判定
|
||||
- 输入形式:包含截图 ✓
|
||||
- 关键词扫描:「XXX」→ 命中 [视觉 Bug / 需求变更] 类
|
||||
- 判定:[激活调试流程 / 走正常开发流程]
|
||||
```
|
||||
|
||||
**视觉 Bug 路径规则**:
|
||||
- 截图 + 问题描述 = 视觉 Bug,**不得降级为 L1 直接执行**,最低 L2
|
||||
- 必须走完信号解析 → 修复 → 回归验证(含 chrome-devtools 截图对比)全流程
|
||||
|
||||
**需求变更路径规则**:
|
||||
- 截图用于"参考设计"或"说明改动目标",走正常开发流程
|
||||
- 复杂度按 001-workflow 标准判定(可为 L1)
|
||||
|
||||
### 0. 信号解析 (Parse Signals)
|
||||
|
||||
从用户描述中**主动提取**以下关键信号(缺失的主动追问):
|
||||
|
||||
| 信号 | 来源 | 重要性 |
|
||||
|---|---|---|
|
||||
| 错误消息 / 堆栈追踪 | 控制台、日志、浏览器 DevTools | 🔴 必需 |
|
||||
| 复现步骤 | 用户操作序列 | 🔴 必需 |
|
||||
| 截图标注的异常区域 | 用户截图 + 文字描述 | 🔴 必需(有截图时) |
|
||||
| 影响区域 | 后端服务 / 前端组件 / API / DB | 🟠 重要 |
|
||||
| 环境信息 | PHP 版本 / 浏览器 / OS | 🟡 有用 |
|
||||
| 上次正常的时间/版本 | Git log / 部署记录 | 🟡 有用 |
|
||||
| 偶发 vs 稳定 | 复现概率 | 🟡 有用 |
|
||||
|
||||
### 0.5 路由到调试策略 (Route to Debug Strategy)
|
||||
|
||||
根据影响区域选择最高效的调试工具:
|
||||
|
||||
| 影响区域 | 首选调试方式 | 测试工具 | 关键位置 |
|
||||
|---|---|---|---|
|
||||
| PHP Service 逻辑 | 断点 + 日志 | PHPUnit | `Case-Database-Backend/test/Unit/` |
|
||||
| API 端点 | Postman / curl + 日志 | Hyperf HttpClient | `Case-Database-Backend/test/Feature/` |
|
||||
| 数据库查询 | SQL 日志 + `EXPLAIN` | PHPUnit + SQLite | `Case-Database-Backend/test/Unit/` |
|
||||
| Vue 组件渲染 | Vue DevTools | Vitest + VTU | `frontend-*/src/**/*.test.ts` |
|
||||
| Vue 状态管理 | Pinia DevTools | Vitest | `frontend-*/src/**/*.test.ts` |
|
||||
| API 请求/响应 | 浏览器 Network 面板 | Mock + Vitest | `frontend-*/src/**/*.test.ts` |
|
||||
| 样式/布局 | Chrome DevTools Elements | 视觉回归 | — |
|
||||
| Swoole 协程 | `var_dump` + Hyperf 日志 | PHPUnit | `Case-Database-Backend/test/` |
|
||||
| WebSocket | 浏览器 WS 面板 + 服务端日志 | Swoole Testing | `Case-Database-Backend/test/` |
|
||||
|
||||
### 1. 复现 (Reproduce)
|
||||
|
||||
- 获取准确的错误信息、堆栈追踪
|
||||
- 确认可稳定复现的步骤
|
||||
- 确认环境:浏览器/Node 版本、OS
|
||||
- **关键**:如果无法稳定复现,记录复现概率和条件
|
||||
|
||||
### 2. 收集 (Collect)
|
||||
|
||||
- 读取相关源码文件
|
||||
- 检查最近的 git 变更:`git log --oneline -10 -- <affected-path>`
|
||||
- 查看相关日志
|
||||
- 检查环境变量配置
|
||||
- **新增**:查看该区域的已有测试,了解预期行为
|
||||
|
||||
### 3. 假设 (Hypothesize)
|
||||
|
||||
列出 2-3 个最可能的原因,按概率排序:
|
||||
```
|
||||
假设 A (70%): <描述> — 因为 <证据>
|
||||
假设 B (20%): <描述> — 因为 <证据>
|
||||
假设 C (10%): <描述> — 因为 <证据>
|
||||
```
|
||||
|
||||
每个假设必须指向**具体文件和代码行**。
|
||||
|
||||
### 4. 验证 (Verify)
|
||||
|
||||
从最高概率假设开始验证。每次只验证一个假设:
|
||||
- 添加 `console.log` / 断点 / Hyperf 日志
|
||||
- 写最小复现测试用例(参考 `bug-reproduce` 技能)
|
||||
- 检查相关数据状态
|
||||
|
||||
### 5. 修复 (Fix)
|
||||
|
||||
- 修复根因,不是症状
|
||||
- 修改尽可能小
|
||||
- 添加防御性代码防止复发
|
||||
|
||||
### 6. 回归 (Regress)
|
||||
|
||||
- 确认原始问题已修复
|
||||
- 运行相关测试套件
|
||||
- 检查是否引入新问题
|
||||
- **新增**:编写回归测试防止复发
|
||||
|
||||
## 硬停止条件
|
||||
|
||||
遇到以下情况时**立即停止调试**,告知用户需要额外条件:
|
||||
|
||||
| 条件 | 原因 | 建议 |
|
||||
|---|---|---|
|
||||
| 需要真实第三方 API 凭证 | 无法在本地模拟 | 提供测试凭证或 Mock 服务 |
|
||||
| 竞态条件/时序依赖 | 不可靠的复现 | 添加日志收集并发数据 |
|
||||
| 需要生产数据 | 本地无法重建状态 | 导出脱敏数据子集 |
|
||||
| 需要特定基础设施 | 本地无法模拟 | 在测试环境调试 |
|
||||
| 超过 3 次假设全部否定 | 信息不足 | 收集更多日志和上下文 |
|
||||
|
||||
## 调试报告模板
|
||||
|
||||
```markdown
|
||||
## 🔧 调试报告
|
||||
|
||||
**问题**: [一句话描述]
|
||||
**状态**: ✅ 已修复 | ⏳ 进行中 | ❌ 需要更多信息
|
||||
|
||||
### 信号
|
||||
- 错误: [错误消息]
|
||||
- 区域: [影响区域]
|
||||
- 复现: [步骤]
|
||||
|
||||
### 根因
|
||||
[1-2 句话解释 Bug 产生的机制]
|
||||
|
||||
### 修复
|
||||
| 文件 | 修改 |
|
||||
|---|---|
|
||||
| `path/to/file` | [修改说明] |
|
||||
|
||||
### 回归测试
|
||||
- `path/to/test` — [测试说明]
|
||||
|
||||
### 验证
|
||||
- [ ] 原始问题已修复
|
||||
- [ ] 回归测试通过
|
||||
- [ ] 无新问题引入
|
||||
```
|
||||
|
||||
## 常见问题速查
|
||||
|
||||
详见 `references/common-errors.md`。
|
||||
|
||||
## 验证
|
||||
|
||||
1. [ ] 提取了所有关键信号(错误消息、复现步骤、影响区域)
|
||||
2. [ ] 选择了正确的调试策略和工具
|
||||
3. [ ] 原始问题已修复
|
||||
4. [ ] 所有现有测试通过
|
||||
5. [ ] 添加了防止复发的回归测试
|
||||
6. [ ] 修复范围最小化
|
||||
7. [ ] 输出了结构化调试报告
|
||||
37
.cursor/skills/debugging/references/common-errors.md
Normal file
37
.cursor/skills/debugging/references/common-errors.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 常见错误速查表
|
||||
|
||||
## Vue 3
|
||||
|
||||
| 错误 | 原因 | 修复 |
|
||||
|------|------|------|
|
||||
| `[Vue warn] Missing required prop` | 必填 prop 未传入 | 检查父组件传参或设置默认值 |
|
||||
| `Maximum recursive updates` | 响应式数据在 watch 中循环修改 | 添加条件判断或用 `watchEffect` 替代 |
|
||||
| `inject() can only be called inside setup()` | 依赖注入在非 setup 中调用 | 移入 `<script setup>` 或 `setup()` 函数 |
|
||||
| `Extraneous non-props attributes` | 组件未声明 `inheritAttrs: false` | 添加 `defineOptions({ inheritAttrs: false })` |
|
||||
| `Component is missing template` | 组件缺少 template 或 render | 检查 .vue 文件是否有 `<template>` |
|
||||
|
||||
## TypeScript
|
||||
|
||||
| 错误 | 原因 | 修复 |
|
||||
|------|------|------|
|
||||
| `Cannot read properties of undefined` | 访问未定义对象属性 | 增加空值判断或使用可选链 `?.` |
|
||||
| `Unexpected token 'export'` | 运行环境与模块格式不匹配 | 检查 ESM/CJS 配置与运行命令 |
|
||||
| `x is not a function` | 导入或变量类型错误 | 检查导出方式与调用处参数 |
|
||||
|
||||
## PHP Hyperf
|
||||
|
||||
| 错误 | 原因 | 修复 |
|
||||
|------|------|------|
|
||||
| `Class not found` | DI 容器未注册或命名空间错误 | 检查 namespace、运行 `composer dump-autoload` |
|
||||
| `Connection pool exhausted` | 连接池已满,协程等待超时 | 增大 `max_connections` 或减少连接占用时间 |
|
||||
| `Coroutine context destroyed` | 在协程外访问协程上下文 | 使用 `Context::get()` 前确保在协程环境 |
|
||||
| `Table not found` | 迁移未执行 | 运行 `php bin/hyperf.php migrate` |
|
||||
| `Allowed memory exhausted` | 内存泄漏或大数据未分块 | 使用 `chunk()` 处理大数据集 |
|
||||
|
||||
## MySQL
|
||||
|
||||
| 错误 | 原因 | 修复 |
|
||||
|------|------|------|
|
||||
| Duplicate entry (1062) | 插入重复唯一键数据 | 用 `INSERT ... ON DUPLICATE KEY UPDATE` 或先查询 |
|
||||
| Lock wait timeout (1205) | 事务死锁或长事务 | 缩短事务范围,添加合适索引 |
|
||||
| Too many connections (1040) | 连接数超限 | 检查连接池配置,增大 `max_connections` |
|
||||
Reference in New Issue
Block a user