{"id":"fcbe02f9-d79e-4f78-8e68-70ebe449d502","entityType":"agent","slug":"clawhub-yeah526-zentao-bug-analyzer","name":"zentao-bug-analyzer","canonicalUrl":"https://www.xpersona.co/agent/clawhub-yeah526-zentao-bug-analyzer","canonicalPath":"/agent/clawhub-yeah526-zentao-bug-analyzer","generatedAt":"2026-10-10T17:35:38.479Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T13:58:05.692Z","emptyReason":null},"description":"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。 Skill: zentao-bug-analyzer Owner: yeah526 Summary: 禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。 Tags: latest:1.1.0 Version history: v1.1.0 | 2026-07-31T03:34:14.485Z | user **zentao-bug-analyzer v1.1.0** - 增加对 ffmpeg 环境依赖的自动检查，首次运行前强制校验，缺失时提示安装 npm 版本依赖。 - 新增用于视频附件抽帧与图片视觉分析的脚本和工具模块（scripts/zentao-extract-frames.js, scripts/zentao-utils.js）。 - 明确规定所有日志/文件操作必须用 Node.js（解决 Windows PowerShell 输出中文乱码问题）。","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s171jrne9aa0bf40kzgc82gb318a7gba:zentao-bug-analyzer","sourceUrl":"https://clawhub.ai/yeah526/zentao-bug-analyzer","homepage":"https://clawhub.ai/yeah526/skills/zentao-bug-analyzer","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/yeah526/zentao-bug-analyzer","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/yeah526/skills/zentao-bug-analyzer","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。 Skill: zentao-bug-analyzer Owner: yeah526 Summary: 禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwri"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:58:05.692Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:58:05.692Z","emptyReason":null},"stars":null,"forks":null,"downloads":1400,"packageName":null,"latestVersion":"1.1.0","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T13:58:05.692Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T13:58:05.692Z","lastCrawledAt":"2026-10-10T13:58:05.692Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T13:58:05.692Z","lastVerifiedAt":null,"highlights":[{"version":"1.1.0","createdAt":"2026-07-31T03:34:14.485Z","changelog":"**zentao-bug-analyzer v1.1.0** - 增加对 ffmpeg 环境依赖的自动检查，首次运行前强制校验，缺失时提示安装 npm 版本依赖。 - 新增用于视频附件抽帧与图片视觉分析的脚本和工具模块（`scripts/zentao-extract-frames.js`, `scripts/zentao-utils.js`）。 - 明确规定所有日志/文件操作必须用 Node.js（解决 Windows PowerShell 输出中文乱码问题）。 - 代码结构优化：所有与禅道交互的 Playwright 操作强制只允许通过 scripts/ 目录下的 5 个固定脚本实现，显式禁止其他自定义 Playwright 文件。 - 文档细化和更新：补充硬性依赖及必禁项，实现细粒度流程与依赖管控。 - 移除已过时的 skill-card.md 文件。","fileCount":14,"zipByteSize":34909},{"version":"1.0.0","createdAt":"2026-07-22T08:22:21.374Z","changelog":"zentao-bug-analyzer v1.0.0 - Initial release - 自动解析飞书消息中的禅道 Bug 链接，支持邮件转发和自然语言双触发 - 配置驱动的模块分类、分支定位、以及本地代码自动分析 - 附件/日志自动下载、commit id 精确提取和分支确认 - AI 驱动的深度根因分析，支持模块专用分析 Skill - 支持批量分析与多模块/多分支并发隔离 - 分析报告支持自动禅道评论及飞书私聊摘要双通道输出 - 硬性流程与清理措施，保证分析准确性和系统稳定","fileCount":11,"zipByteSize":23440},{"version":"0.0.7","createdAt":"2026-07-22T08:21:06.318Z","changelog":"zentao-bug-analyzer v0.0.7 - No code or documentation changes in this release. - All functionality and behavior remain the same as the previous version.","fileCount":11,"zipByteSize":23545},{"version":"0.0.6","createdAt":"2026-07-22T08:09:15.411Z","changelog":"增加 \u0007uto_comment 配置项，支持分析完成后仅飞书通知、不自动评论禅道（可选，默认自动评论）","fileCount":11,"zipByteSize":23498},{"version":"0.0.5","createdAt":"2026-07-22T08:04:06.712Z","changelog":"- 增加 `auto_comment` 配置项，支持分析完成后仅飞书通知、不自动评论禅道（可选，默认自动评论） - 配置引导流程新增「是否自动评论」选项，支持自定义报告输出行为 - 优化分析报告输出逻辑：根据 `auto_comment` 配置决定是否执行禅道评论步骤 - Android logcat 的 `.gz` 日志解压要求统一为 Node.js zlib 工具，避免因兼容性问题遗漏日志内容 - 移除 skill-card.md 文件，不影响主流程","fileCount":11,"zipByteSize":23563},{"version":"0.0.4","createdAt":"2026-07-22T08:02:09.591Z","changelog":"- 新增 auto_comment 配置项，可控制是否自动将分析报告评论到禅道 Bug 下（true=自动评论，false=仅飞书通知）。 - 步骤 5 输出逻辑调整：根据 auto_comment 开关，允许只飞书通知不评论禅道。 - 首次配置引导流程增加 auto_comment 选项的询问步骤。 - 明确 logcat .gz 文件必须用 Node.js zlib 解压，禁止用 PowerShell/.NET GZipStream，解决日志解压数据缺失问题。 - 移除 skill-card.md 文件，不影响核心功能。","fileCount":11,"zipByteSize":23511},{"version":"0.0.3","createdAt":"2026-07-22T07:45:34.848Z","changelog":"- 新增 `auto_comment` 配置项：支持选择分析完成后是否自动将报告评论到禅道（默认开启）。 - 分析报告输出逻辑调整：根据 `auto_comment` 控制，仅飞书通知或双通道输出（禅道评论+飞书通知）。 - 配置引导流程补充：引导用户确认是否需要自动评论禅道 Bug。 - 步骤4c优化：Android logcat `.gz` 日志必须用 Node.js zlib 解压，禁止 .NET 解压工具，防止内容缺失。 - 移除无关描述文档（删除 skill-card.md，无代码变动）。","fileCount":11,"zipByteSize":23545},{"version":"0.0.2","createdAt":"2026-07-09T07:28:12.083Z","changelog":"删除SKILL.md里的skill:car-settings-analyzer，防止AI幻觉","fileCount":11,"zipByteSize":22748}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171jrne9aa0bf40kzgc82gb318a7gba:zentao-bug-analyzer","setupComplexity":"low","setupSteps":["Node.js workspace detected. Install dependencies securely: run `npm ci --ignore-scripts` to prevent post-install lifecycle triggers from running arbitrary code, then selectively audit the dependency tree.","Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T17:35:38.475Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-yeah526-zentao-bug-analyzer/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T13:58:05.692Z","emptyReason":null},"readme":"Skill: zentao-bug-analyzer\n\nOwner: yeah526\n\nSummary: 禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\n\nTags: latest:1.1.0\n\nVersion history:\n\nv1.1.0 | 2026-07-31T03:34:14.485Z | user\n\n**zentao-bug-analyzer v1.1.0**\n\n- 增加对 ffmpeg 环境依赖的自动检查，首次运行前强制校验，缺失时提示安装 npm 版本依赖。\n- 新增用于视频附件抽帧与图片视觉分析的脚本和工具模块（`scripts/zentao-extract-frames.js`, `scripts/zentao-utils.js`）。\n- 明确规定所有日志/文件操作必须用 Node.js（解决 Windows PowerShell 输出中文乱码问题）。\n- 代码结构优化：所有与禅道交互的 Playwright 操作强制只允许通过 scripts/ 目录下的 5 个固定脚本实现，显式禁止其他自定义 Playwright 文件。\n- 文档细化和更新：补充硬性依赖及必禁项，实现细粒度流程与依赖管控。\n- 移除已过时的 skill-card.md 文件。\n\nv1.0.0 | 2026-07-22T08:22:21.374Z | auto\n\nzentao-bug-analyzer v1.0.0\n\n- Initial release\n- 自动解析飞书消息中的禅道 Bug 链接，支持邮件转发和自然语言双触发\n- 配置驱动的模块分类、分支定位、以及本地代码自动分析\n- 附件/日志自动下载、commit id 精确提取和分支确认\n- AI 驱动的深度根因分析，支持模块专用分析 Skill\n- 支持批量分析与多模块/多分支并发隔离\n- 分析报告支持自动禅道评论及飞书私聊摘要双通道输出\n- 硬性流程与清理措施，保证分析准确性和系统稳定\n\nv0.0.7 | 2026-07-22T08:21:06.318Z | auto\n\nzentao-bug-analyzer v0.0.7\n\n- No code or documentation changes in this release.\n- All functionality and behavior remain the same as the previous version.\n\nv0.0.6 | 2026-07-22T08:09:15.411Z | user\n\n增加 \u0007uto_comment 配置项，支持分析完成后仅飞书通知、不自动评论禅道（可选，默认自动评论）\n\nv0.0.5 | 2026-07-22T08:04:06.712Z | user\n\n- 增加 `auto_comment` 配置项，支持分析完成后仅飞书通知、不自动评论禅道（可选，默认自动评论）\n- 配置引导流程新增「是否自动评论」选项，支持自定义报告输出行为\n- 优化分析报告输出逻辑：根据 `auto_comment` 配置决定是否执行禅道评论步骤\n- Android logcat 的 `.gz` 日志解压要求统一为 Node.js zlib 工具，避免因兼容性问题遗漏日志内容\n- 移除 skill-card.md 文件，不影响主流程\n\nv0.0.4 | 2026-07-22T08:02:09.591Z | user\n\n- 新增 auto_comment 配置项，可控制是否自动将分析报告评论到禅道 Bug 下（true=自动评论，false=仅飞书通知）。\n- 步骤 5 输出逻辑调整：根据 auto_comment 开关，允许只飞书通知不评论禅道。\n- 首次配置引导流程增加 auto_comment 选项的询问步骤。\n- 明确 logcat .gz 文件必须用 Node.js zlib 解压，禁止用 PowerShell/.NET GZipStream，解决日志解压数据缺失问题。\n- 移除 skill-card.md 文件，不影响核心功能。\n\nv0.0.3 | 2026-07-22T07:45:34.848Z | user\n\n- 新增 `auto_comment` 配置项：支持选择分析完成后是否自动将报告评论到禅道（默认开启）。\n- 分析报告输出逻辑调整：根据 `auto_comment` 控制，仅飞书通知或双通道输出（禅道评论+飞书通知）。\n- 配置引导流程补充：引导用户确认是否需要自动评论禅道 Bug。\n- 步骤4c优化：Android logcat `.gz` 日志必须用 Node.js zlib 解压，禁止 .NET 解压工具，防止内容缺失。\n- 移除无关描述文档（删除 skill-card.md，无代码变动）。\n\nv0.0.2 | 2026-07-09T07:28:12.083Z | user\n\n删除SKILL.md里的skill:car-settings-analyzer，防止AI幻觉\n\nv0.0.1 | 2026-07-09T05:51:33.947Z | auto\n\nzentao-bug-analyzer 0.0.1 初始版本发布。\n\n- 实现禅道缺陷分析自动化：飞书消息触发，Bug 模块自动分类、分支定位、代码分析。\n- 全流程脚本化：所有禅道交互统一通过指定 Playwright 脚本，禁止手写脚本。\n- 支持自定义模块配置、分析规则、专用分析 Skill。\n- 分析流程包含日志下载、精确时间确认、commit 提取、隔离代码工作区等环节。\n- 双通道输出：分析结果自动发布到禅道评论，并通过飞书私聊通知。\n- 提供首次配置对话式引导与详细边界情况处理说明。\n\nArchive index:\n\nArchive v1.1.0: 14 files, 34909 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/package.json (324b), scripts/zentao-build-comment.js (7210b), scripts/zentao-download-files.js (6816b), scripts/zentao-extract-frames.js (3427b), scripts/zentao-get-bug.js (4864b), scripts/zentao-login.js (4843b), scripts/zentao-post-comment.js (2844b), scripts/zentao-utils.js (3960b), skill-card.md (2460b), SKILL.checklist.md (2413b), SKILL.md (29179b), TOOLS.md (3875b), _meta.json (138b)\n\nFile v1.1.0:SKILL.md\n\n---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## 环境依赖\n\n本 Skill 依赖以下工具，**环境不具备时立即停止流程并飞书通知用户**，禁止用替代品硬撑：\n\n| 工具 | 用途 | 安装方式 | 验证命令 |\n|------|------|----------|----------|\n| **ffmpeg** | 视频附件抽帧（步骤 4b） | `npm install @ffmpeg-installer/ffmpeg ffprobe-static --no-save` | `node -e \"console.log(require('@ffmpeg-installer/ffmpeg').path)\"` |\n| **Node.js zlib** | 解压 Android logcat `.gz` 日志（步骤 4c） | Node.js 内置，无需安装 | `node -e \"require('zlib')\"` |\n| **Playwright** | 禅道交互（5 个 scripts） | 已有 | — |\n| **视觉模型** | 读取截图/视频帧中的系统时间 + 判断画面中 BUG 现象是否可见（步骤 4b 子步骤 3、4） | 由 AI 代理运行环境提供 | — |\n\n**禁止的替代方案**：\n- ❌ 用 winget 装系统级 ffmpeg（实测 `winget install Gyan.FFmpeg` 超时不可靠）\n- ❌ 用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或 .NET 工具解压 logcat `.gz`（兼容性 bug，会丢失大量日志）\n- ❌ 用 PowerShell/.NET 替代品处理视频（参考 4c 关于 .NET 解压 bug 的教训）\n\n> ⚠️ **视觉模型不可用时**：步骤 4b 子步骤 3、4 无法读取截图/视频帧中的系统时间，降级为跳过图片/视频时间提取，直接进入子步骤 5 飞书询问用户。\n\n**首次运行检查**：执行任何分析前先验证 ffmpeg 可用：\n```bash\nnode -e \"const ff=require('@ffmpeg-installer/ffmpeg');const{execSync}=require('child_process');execSync(`\\\"${ff.path}\\\" -version`);console.log('ffmpeg OK')\"\n```\n失败 → 飞书私聊通知「ffmpeg 环境依赖缺失，请运行 `cd {workspace} && npm install @ffmpeg-installer/ffmpeg ffprobe-static --no-save` 后重试」，流程终止。\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个可执行脚本操作禅道**（不含 `zentao-utils.js` 工具模块），禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不切回原分支（非 worktree 场景）。worktree 场景按步骤 6 清理。\n5. **分析完输出报告**：步骤 4d 产出分析报告后，根据 `auto_comment` 配置决定是否评论禅道：\n   - `auto_comment === true` 或未配置（默认视为 `true`）：运行 `zentao-post-comment.js` 评论 + 飞书摘要\n   - `auto_comment === false`：仅飞书摘要，不评论禅道\n6. **环境依赖缺失立即停止**：ffmpeg / Node.js zlib / Playwright 任一不可用 → 飞书通知用户安装，禁止用替代品硬撑（详见「环境依赖」章节）\n7. **Windows 读取中文文件必须用 Node.js，禁止 PowerShell `Get-Content` / `Select-String`**：\n   - Windows PowerShell 控制台默认 GBK（CP936）编码，读取 UTF-8 中文文件直接显示乱码\n   - ❌ 禁止：`Get-Content xxx.txt -First 5`、`Select-String -Path xxx.txt -Pattern \"中文\"`、`Get-ChildItem | Where-Object Name -like '*.中文.txt'`\n   - ✅ 必须：`node -e \"console.log(require('fs').readFileSync('xxx.txt','utf8').slice(0,500))\"`\n   - 涉及场景：读取日志中的中文 TAG、中文注释、报告 review 时的中文文件名/路径、PowerShell 调用 `node script.js --video=中文.mp4` 时加 `--` 分隔符规避 argv 解析 bug\n   - 例外：`Get-Content` 加上 `-Encoding UTF8` 参数可以读 UTF-8（输出仍可能乱码，但不会被识别为 ANSI）；推荐一律走 Node.js\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"auto_comment\": true,\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}\n```\n\n字段说明：\n- `name`：模块名称\n- `aliases`：模块别名列表（字符串数组），用于精确匹配。**匹配规则**：将 Bug 的 title、module.name、product.name 与所有模块的 name + aliases 做**子串匹配**（忽略大小写），任一命中即判定为该模块。此规则为硬规则，优先于 AI 主观判断\n- `code_dir`：模块本地代码仓库绝对路径\n- `commit_extract`：自然语言，告诉 AI 如何从日志提取 commit id\n- `analyzer`：`\"default\"` | `\"skill:技能名\"`。default 走通用 AI 分析流程；skill:xxx 委派给对应 Skill\n- `analyze_hint`：模块专属分析提示词（可选），无论哪种分析器都会传给分析器\n\n> ⚠️ `auto_comment` 是**根级别**字段（与 `zentao`、`notify`、`modules` 平级），控制全局行为。非 module 级别字段。\n\n### 首次配置引导\n\n配置文件不存在时启动对话式引导。流程：\n\n1. 「请提供禅道的登录账号和密码（用于 Playwright 登录禅道。密码会存储在本地配置文件中，不会泄露）」\n2. 「你负责哪些模块？请列出模块名称（用逗号分隔，如：车机设置, 蓝牙模块, 语音助手）」\n3. 对每个模块依次询问：\n   - 「对于\"{模块名}\"模块，有哪些别名/关键词可以用来识别？（用逗号分隔，如：桌面卡片, systemui, 设置）」\n   - 「对于\"{模块名}\"模块，本地代码目录路径是什么？（请使用绝对路径）」\n   - 「对于\"{模块名}\"模块，日志中如何提取 commit id？请用自然语言描述提取规则」\n   - 「对于\"{模块名}\"模块，是否需要使用专用分析 Skill？（目前可用的 Skill：[列出]。输入 Skill 名或留空走默认分析）」\n   - 「对于\"{模块名}\"模块，有什么分析提示或重点关注方向？（可选，留空则用默认分析策略）」\n4. 「分析完成后，是否需要自动将分析报告评论到禅道 Bug 下？（回复\"是\"=自动评论，\"否\"=仅飞书通知，不评论禅道）」\n5. 「配置完成！请确认你已创建邮件收信规则：当发件人为 `zentao@syncore.space` 时，自动将邮件转发/分享到本 Bot 的对话中。」\n\n---\n\n## 分析流水线\n\n### 步骤 1：消息解析\n\n从消息内容提取禅道 Bug 链接，正则：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 步骤 2：重复分析检查\n\n> ⚠️ 此步骤是强制检查点，无论通过哪种触发方式（邮件转发或自然语言）进入分析流水线，必须先走步骤 2。已评论过的 Bug 绝对不允许直接进入后续步骤。\n\n1. 运行 `scripts/zentao-login.js` 登录禅道，获取 WS endpoint（后续所有脚本复用此 endpoint）\n2. 运行 `scripts/zentao-get-bug.js` 获取 Bug 详情（含评论列表 `comments` 字段，后续步骤复用）\n3. 检查 Bug API 返回的 `comments` 数组中是否已有 `zentao.account` 配置账号的评论（`comments[].author` 字段，不是 `historyChanges` 操作历史）\n\n**已有我的评论**：飞书私聊询问「该 Bug 你已评论过，是否需要重新分析？（回复\"是\"或\"分析\"继续，回复\"否\"或\"取消\"跳过）」\n- 确认「是」→ 继续步骤 3\n- 确认「否」或 5 分钟内未回复 → 流程终止\n\n**没有我的评论**：直接继续步骤 3。\n\n### 步骤 3：模块分类\n\n**匹配规则（优先级从高到低）**：\n\n1. **硬别名匹配（优先）**：遍历配置中每个 module 的 `aliases` 数组，将每个别名与 Bug 的 `title`、`module.name`、`product.name` 做**子串匹配**（忽略大小写）。只要任一副本字段包含任一个别名（或 `name` 本身），即判定命中该模块。\n   - 例如：Bug标题含\"桌面卡片\"，配置别名中有\"桌面卡片\" → 直接命中\n   - ⚠️ 此规则是机械规则，不依赖 AI 判断，直接执行\n2. **AI 语义判断（兜底）**：硬别名未命中时，AI 综合判断 Bug 归属模块，对照配置文件 `modules` 列表\n\n**结果处理**：\n- **在范围**：继续步骤 4\n- **不在范围**：飞书私聊通知（Bug 标题、链接、AI 判断的模块归属），提醒模块确认和手动流转。流程结束\n- **置信度低**：飞书私聊通知（Bug 链接 + 关键信息），告知无法确定模块，请手动确认。流程结束\n\n### 步骤 4：深度分析\n\n#### 4a. 下载附件和日志\n运行 `scripts/zentao-download-files.js` 下载 Bug 所有附件到 `bugs/{bug_id}/`。（script 自动处理大文件分块传输，支持 160MB+ 附件）\n\n> ⚠️ 步骤 4a 完成后必须先执行 4b（确定 Bug 发生时间），再进入 4c。\n\n#### 4b. 确定 Bug 发生时间\n\n> ⚠️ 硬约束：Bug 发生时间必须从可靠来源直接获取，禁止猜测或间接推断。\n> 此步骤是 4c 分支定位的前置条件，时间不准会导致日志定位、Git blame 全部偏移。\n> **经过 3 个真实 Bug 视频（1443538/1443544/1443665）验证**：Android 车机录屏状态下状态栏只显示 HH:MM（无秒），且相机外拍场景下状态栏经常被遮挡；这些坑必须显式处理。\n\n**时间来源优先级（一旦确定后不要再换）**：\n1. **Bug 描述文本中明确记录的时间**（steps / description 字段中出现的 `HH:MM[:SS]` 或 `YYYY-MM-DD HH:MM[:SS]` 格式）\n2. **设备系统状态栏**（手机/车机屏幕顶部实时时间）\n3. **录屏工具水印**（仅参考，水印时钟与设备时钟不同步是常见 bug）\n4. **相机水印 / 文件名时间戳**（仅参考）\n5. **飞书询问用户**（兜底）\n\n**禁止行为**：\n- ❌ 使用**附件文件名中的时间戳**作为时间来源（仅可辅助佐证）\n- ❌ 使用 **Bug 创建时间 / 最后修改时间**作为时间来源\n- ❌ 使用**聊天消息转发时间 / 邮件接收时间**作为时间来源\n- ❌ 使用**附件上传时间、附件最后修改时间**作为时间来源\n- ❌ 在多个来源冲突时擅自挑一个，必须飞书通知用户选择\n- ❌ 在状态栏只读到 HH:MM 时强行猜测秒数\n- ❌ 在视频、描述、用户三处都拿不到时间时，用以上任何间接来源凑数\n\n**子步骤 1：从 Bug 描述文本提取**\n- 解析 Bug `steps` 和 `description` 字段，匹配 `HH:MM[:SS]` 或 `YYYY-MM-DD HH:MM[:SS]` 格式\n- 命中即记录为「描述时间」，进入子步骤 5 的交叉校验\n- 没命中 → 进入子步骤 2\n\n**子步骤 2：枚举附件并按类型分流**\n\n读取步骤 4a 下载到 `bugs/{bug_id}/` 的附件列表，按 MIME/扩展名分流：\n- **图片类**（`.jpg/.jpeg/.png/.webp/.bmp`）→ 子步骤 3\n- **视频类**（`.mp4/.mov/.mkv/.avi/.webm/.3gp`）→ 子步骤 4\n- **其它** → 跳过，进入子步骤 5\n\n**子步骤 3：图片附件直接读取时间**\n\n对每张图片文件，使用视觉能力读取画面中的系统时间（将图片文件路径作为输入，视觉模型自动解析画面内容），**按优先级寻找以下区域**：\n1. **状态栏右上角**（Android 系统时间显示区，最常见）\n2. **状态栏左上角**（部分 ROM 习惯）\n3. **录屏水印**（很多测试工具会在画面角落叠加时间戳）\n4. **锁屏/通知面板**（如截图包含）\n\n读取规则：\n- 接受 **HH:MM 精度**（不强求秒，Android 车机录屏**通常只显示到分钟**）\n- 必须输出**时间所在画面区域**（例如「右上角状态栏」「左下角水印」），便于人工复核\n- 同一 Bug 多张图片时，记录**每张图片独立读出的时间**，不要直接合并\n- 读不出 → 标记「图片无可见时间」，继续下一张\n- ⚠️ **水印与状态栏冲突时，以状态栏为准**（实测验证：水印时钟经常和设备时钟不同步，例如 1443665 视频水印年份显示 `2026`，状态栏为正确日期）\n\n**子步骤 4：视频附件抽帧 + 视觉读取**\n\n> ⚠️ 视频不能直接送视觉模型（容量大、模型处理不了连续帧），必须先抽帧。\n> ⚠️ 工具依赖：本 Skill **强制依赖 ffmpeg**（详见 SKILL.md 开头「环境依赖」章节）。必须使用 `npm install @ffmpeg-installer/ffmpeg ffprobe-static` 提供的 ffmpeg（动态路径通过 `node -e \"console.log(require('@ffmpeg-installer/ffmpeg').path)\"` 获取），**禁止用 PowerShell/.NET 替代品处理视频**（参考 4c 关于 .NET 解压 bug 的教训），禁止用 winget 装系统级 ffmpeg（实测 winget 装 Gyan.FFmpeg 超时不可靠）。\n\n**▸ 粗扫：确认视频里有没有可见 BUG**\n\n> 🆕 此步是前置门槛（验证坑 #4：部分 Bug 视频里根本看不到 BUG 现象）。\n\n1. 用 2 秒 1 帧抽帧（约视频时长一半的张数，80 秒视频约 40 张）：\n   ```bash\n   node scripts/zentao-extract-frames.js --video=<视频路径> --dir=bugs/{bug_id}/frames --mode=coarse\n   ```\n   > 💡 PowerShell 调用时建议加 `--` 分隔符以规避 argv 解析 bug：`node scripts/zentao-extract-frames.js -- --video=xxx.mp4 --mode=coarse`。脚本同时支持 `--key=val` 和 `--key val` 两种参数形式。\n2. 视觉模型扫一遍所有粗帧（将 `coarse_*.png` 文件逐个传入，每次不超过 20 张），判断**画面里有没有 BUG 现象**（错误提示、卡死、空白、花屏、异常弹窗等）\n3. **看得到 BUG** → 进入 4b 精抽\n4. **看不到 BUG** → 视频是「正常录屏，BUG 由其它渠道复现」（日志/用户描述），**跳过视频读时间，直接进入「交叉校验 + 落盘」步骤飞书询问用户**\n   - 在报告里记录「视频未观察到 BUG 现象，跳过视频时间提取」\n\n**▸ 精抽：1 秒 1 帧抽全片**\n\n确认有 BUG 后，抽出全片每秒 1 帧：\n```bash\nnode scripts/zentao-extract-frames.js --video=<视频路径> --dir=bugs/{bug_id}/frames --mode=fine\n```\n> 💡 PowerShell 调用同样推荐加 `--` 分隔符（详见上面粗抽步踩说明）。\n\n> 🔴 不要一次送视觉模型超过 20 张（实测 OpenClaw `image` 工具多张时延不可控）。建议**关键区间（BUG 前后 ±10 秒）1 秒 1 帧抽满后才送视觉模型**，不要全片无脑送。\n\n**▸ 读时：状态栏时间 + 处理遮挡**\n\n视觉模型读取每帧，**优先级**：\n1. **设备状态栏**（最高优先，记录 HH:MM）\n2. **录屏水印**（仅参考，与状态栏冲突时以状态栏为准）\n3. 两者都不可见 → 标记「该帧状态栏不可见」，读前后相邻帧推断大致时间窗\n\n> 🆕 验证坑 #1：状态栏只显示 HH:MM，无秒。**接受 HH:MM 精度**，秒数由日志/描述交叉校验得到，不要强行猜测。\n> 🆕 验证坑 #2：相机外拍场景下，状态栏经常被遮挡（实测 1443544 前 3 秒、1443538 BUG 关键帧都被遮挡）。**被遮挡的帧跳过状态栏，只读水印或前后帧推断**。\n\n**▸ 输出：候选时间 + 证据**\n\n视频起始帧、BUG 首次出现帧、BUG 消失帧各读一次时间，记录到：\n- 候选时间（HH:MM）\n- 对应的帧文件名（例如 `sec_0060.png`）\n- 时间所在画面区域（「右上角状态栏」「左下角水印」「被遮挡」）\n\n**子步骤 5：交叉校验 + 落盘**\n\n把子步骤 1~4 得到的所有候选时间汇总：\n1. **至少 2 个独立来源时间吻合**（例如描述 + 视频起始帧；或视频起始帧 + 结束帧差值符合视频时长）→ 采纳为「Bug 发生时间」\n2. **只有一个来源** → 采纳，但报告里标注「单一来源，建议人工复核」\n3. **多个来源冲突** → 飞书通知列出所有候选时间让用户选，**不要自己挑一个**\n4. **全部子步骤都没拿到时间** → 飞书私聊询问「该 Bug 发生的精确时间是什么？」\n\n**最终落盘**：\n- 在 `bugs/{bug_id}/.time-metadata.json` 写入结构化元数据（供步骤 4d 读取并输出到报告）：\n  - 采纳的时间（含时区，默认 `Asia/Shanghai`）\n  - 时间来源（例如「视频 sec_0060.png 右上角状态栏」）\n  - 证据文件路径（相对 `bugs/{bug_id}/`）\n  - 置信度（高/中/低）\n- 步骤 4d 的日志分析窗口**直接以这个时间为中心 ±5 分钟**，不再二次推断\n- ⚠️ 此步骤不直接写 `report.md`——`### Bug 发生时间` 章节由步骤 4d 统一下读取 `.time-metadata.json` 后输出\n\n#### 4c. 分支定位\n1. 解压并读取日志文件：\n   - Android logcat 的 `.gz` 文件**必须使用 Node.js zlib 解压**。⚠️ 禁止使用 PowerShell `tar` / `System.IO.Compression.GZipStream` 等 .NET 解压工具（兼容性 bug 详见「环境依赖」章节）。推荐命令：\n     ```bash\n     node -e \"const zlib=require('zlib');const fs=require('fs');const buf=fs.readFileSync('<log.gz>');zlib.gunzip(buf,(e,r)=>{if(e){console.error(e);return}const s=r.toString('utf8');/* 搜索 s */})\"\n     ```\n2. 按配置中 `commit_extract` 从日志提取 commit id\n3. `cd {code_dir}` → `git branch --contains <commit-id>` 确认 commit 在哪些分支上。结果写入分析报告的「分支信息」字段（格式：`分支名 | commit-id`）\n4. 分支检出（根据仓库占用情况二选一）：\n   - **仓库空闲**（无其他 Bug 分析占用）：`git checkout <commit-id>`（进入 detached HEAD 是正常行为，分析完成后保持不动即可）+ `git submodule update --init --recursive`\n   - **同模块已有其他分析任务占用**：`git worktree add .claude/worktrees/bug-{bug_id}/ <commit-id>` 创建隔离工作区，在 worktree 内执行 `git submodule update --init --recursive`\n\n**commit id 提取失败**：飞书私聊通知（附带日志片段），流程终止。\n\n> ⚠️ 硬约束：只使用配置中 commit_extract 指定的提取规则，禁止 AI 自行更换搜索关键词（如换 TAG、换正则）。搜不到就是搜不到，不允许\"近似匹配\"或\"换成类似的 TAG 试试\"。\n> Self-Check：若在分析过程中进行了 commit_extract 规则以外的额外搜索，应立即停止、丢弃中间产物，回到步骤 4c 标准路径并报告提取失败。\n\n**commit id 不在任何分支**：飞书私聊通知（附带 commit id），流程终止\n\n> ⚠️ 硬约束：`git checkout <commit-id>` 后必须执行 `git submodule update --init --recursive`，确保所有 submodule 都已 checkout 到对应版本。未 checkout submodule 可能导致分析时缺少依赖代码、漏掉跨仓库 API 不一致问题。\n\n#### 4d. AI 综合深度分析\n\n历史评论已在步骤 2 获取（Bug API 的 `comments` 字段），操作历史（`historyChanges`，包含状态流转、指派人变更、优先级调整等记录）同样已在步骤 2 由 `zentao-get-bug.js` 提取，此处直接使用。\n\n根据 `analyzer` 字段：\n- `\"default\"`：AI 综合 Bug 详情 + 附件/日志 + 历史评论 + 本地代码分析\n- `\"skill:xxx\"`：委派给指定 Skill，传入分析上下文\n\n无论哪种方式，`analyze_hint` 都作为上下文传入。\n\n分析时读取 `bugs/{bug_id}/.time-metadata.json` 中步骤 4b 确定的 Bug 发生时间，以该时间为中心 ±5 分钟缩小日志分析范围，聚焦根因定位。\n\n输出格式（Markdown，AI 直接产出此结构）：\n\n```markdown\n### Bug 发生时间\n- **采纳时间**：yyyy-MM-dd HH:mm (Asia/Shanghai)\n- **时间来源**：视频 sec_0060.png 右上角状态栏\n- **证据文件**：frames/sec_0060.png\n- **置信度**：高/中/低\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 操作历史（如有）\n- **状态流转**：active → resolved → closed\n- **关键变更**：指派人 / 优先级 / 严重程度的变更记录\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**：\n  ```lang\n  // 关键代码\n  ```\n- **判断依据**：（结合日志/历史评论/代码逻辑的推理过程）\n\n### 修复建议\n1. 具体修复方向（可操作步骤，非抽象建议）\n\n### 风险评估\n- **影响范围**：（哪些功能/模块受影响）\n- **严重程度**：（低/中/高/严重 + 理由）\n```\n\n### 步骤 5：结果输出\n\n> ⚠️ **auto_comment 开关**：步骤 4d 已产出 `bugs/{bug_id}/report.md`（无论 `auto_comment` 取值，分析报告始终生成到本地）。步骤 5 仅决定是否将报告发布到禅道：\n> - `auto_comment === false`：跳过禅道评论（步骤 5.1），仅生成 `report.md` + 执行飞书私聊通知（步骤 5.2）\n> - `auto_comment === true` 或未配置：执行完整双通道（禅道评论 + 飞书通知）\n\n1. **禅道评论**（仅在 `auto_comment !== false` 时执行）：\n   a. 确认 `bugs/{bug_id}/report.md` 已生成（步骤 4d 产出），按步骤 4d 输出格式\n   b. 运行 `node scripts/zentao-build-comment.js bugs/{bug_id}/report.md --out bugs/{bug_id}/comment.html` 生成 HTML\n   c. 运行 `node scripts/zentao-post-comment.js --ws=<wsEndpoint> --bug-id=<id> --comment-file=bugs/{bug_id}/comment.html` 发布（**必须用 `--comment-file`，禁止用 `--comment` 传 HTML 内容**）\n   d. ⚠️ `--comment` 参数仅用于极简手动测试（单行纯文本），生产环境严禁使用——shell 转义和 HTML 特殊字符会导致内容截断或损坏\n   e. ⚠️ 禁止手写临时 Playwright 脚本发布评论\n2. **飞书私聊**：简要摘要 + 禅道 Bug 链接\n\n### 步骤 6：清理\n\n分析完成后必须清理残留进程，避免占用系统资源：\n\n1. **杀掉 login 常驻进程（连带 Chrome）**：\n   - Windows: `taskkill /PID <login-PID> /F /T`\n   - macOS/Linux: `kill -9 <login-PID> && pkill -P <login-PID>`（精准终结子进程树，避免误杀用户其他 Chrome 实例）\n   - PID 来自 `zentao-login.js` 输出行 `PID=<value>`（Node.js 进程 PID，`/T` 或 `pkill -P` 会连带终结 Chrome 子进程树）\n2. **清理 git worktree**：`git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove --force .claude/worktrees/bug-{bug_id}/`\n3. **检查残留脚本进程**：\n   - Windows: `Get-Process node` 检查是否还有 `zentao-*.js` 相关进程\n   - macOS/Linux: `ps aux | grep 'zentao-' | grep -v grep`\n   - 有则 `taskkill /F /PID <pid>`（Windows）或 `kill -9 <pid>`（macOS/Linux）\n4. **确认清理完毕**：最终应只剩 OpenClaw 自身的 node 进程（gateway/worker），不应有其他 `zentao-*.js` 残留\n\n> ⚠️ 注意：不要杀掉 OpenClaw 自身的 node 进程（gateway/worker），只清理 `zentao-*.js` 和 Chrome headless 相关进程。\n\n---\n\n## 并发处理\n\n- **不同模块**：代码目录不同，全部并行处理\n  - ⚠️ 并行时每个 Bug 需要独立的 CDP 端口，通过 `zentao-login.js --port=<不同端口>` 避免冲突（如 `--port=9224`、`--port=9225`、`--port=9226`）\n- **同一模块同时分析多个 Bug 时**：用 `git worktree` 为每个 Bug 创建隔离工作区，分析完成后 `git worktree remove` 清理\n- **并发清理**：每个 Bug 分析完成后各自执行步骤 6 清理自己的 login 进程和 worktree，最后确认所有端口对应的 `zentao-*.js` 进程均已终止\n\n---\n\n## 禅道交互方式\n\n> ⚠️ 企业版 12.1 不支持 Bearer Token 认证（`POST /api.php/v1/tokens` 不可用），所有读写操作统一走 Playwright。\n\n### 🔴 铁律：单次 Playwright 会话\n\n**一个 Bug 的分析全程只允许启动一次 Playwright 浏览器**。登录后所有操作（读详情、下载附件、写评论）复用同一会话，禁止：\n\n- ❌ 分多个脚本文件各启动一次 Playwright\n- ❌ 中途关闭浏览器再重新登录\n- ❌ 写评论时用新的浏览器实例\n\n### 🔴 铁律：脚本优先，禁止手写临时 Playwright 脚本\n\n脚本列表、参数和用法详见 [TOOLS.md](TOOLS.md)。核心铁律：\n\n**禁止行为**：\n- ❌ 手写临时 `post_comment.js`、`check_bug.js`、`debug_login.js` 等任何 Playwright 脚本\n- ❌ 在 `bugs/{bug_id}/` 目录下创建任何 `.js` 文件\n- ❌ 用 `page.evaluate`、`page.fill`、`page.click` 等 Playwright API 绕过已有脚本\n- ❌ 禁止用 `--comment` 参数传 HTML 内容发布评论（shell 转义风险），必须用 `--comment-file`\n\n**遇到脚本报错时的正确处理方式**：\n1. 先读脚本源码，理解它依赖的输入（WS endpoint、参数格式等）\n2. 修复输入条件（如重新登录获取有效 WS endpoint），而不是绕过脚本\n3. 如果脚本本身有 bug，修复脚本源码（`scripts/` 目录下），让修复对所有后续分析生效\n\n---\n\n## 边界情况处理\n\n| 场景 | 处理 |\n|------|------|\n| 不含禅道链接 | 「未识别到有效的禅道缺陷链接，请确认消息内容」 |\n| 链接解析失败 | 「无法解析该链接，请确认是否正确转发」 |\n| 禅道 API 请求失败（登录失效/会话过期） | 「无法访问禅道，请检查连接和登录状态」 |\n| 模块分类置信度低 | 飞书通知：Bug 链接+关键信息，请手动确认 |\n| 模块不在负责范围 | 飞书通知：Bug 归属 + 提醒手动流转 |\n| commit id 提取失败 | 飞书通知：日志片段，请手动确认分支 |\n| commit id 不在任何分支 | 飞书通知：commit id，请手动确认 |\n| Bug 发生时间所有来源提取失败 | 飞书私聊询问用户精确时间（见步骤 4b 子步骤 5） |\n| 附件/日志下载失败 | 降级：仅基于 Bug 描述+历史评论+代码分析，评论注明「未能获取附件」，飞书通知 |\n| 本地代码目录不存在 | 降级：跳过代码分析，仅日志+附件+评论，飞书通知检查配置 |\n| 分析过程中断或超时 | 飞书通知进度和失败原因，不留半截评论 |\n| 用户 5 分钟内未回复重新分析确认 | 默认不重新分析，流程终止 |\n| 分析过程中 git worktree 冲突 | 清理残留 worktree 后重试；仍失败则飞书通知 |\n\n---\n\n## 范围约束\n\n- 不自动填写指派人或流转状态\n- 不自动生成修复代码\n- 不做缺陷趋势统计或报表\n- 当前只服务单一用户\n\n---\n\n## 飞书通知模板\n\n所有飞书私聊通知遵循以下统一格式（参考附录模板），各场景按表填充：\n\n```\n【Bug 分析】{状态标签}\n\nBug：#{bug_id} {title}\n链接：{zentao_url}/bug-view-{bug_id}.html\n\n{核心信息}\n\n{操作引导}\n```\n\n| 场景 | 状态标签 | 核心信息 | 操作引导 |\n|------|----------|----------|----------|\n| 环境依赖缺失 | ❌ 环境异常 | 缺失的工具名称 + 安装命令（参考环境依赖章节） | 「安装后重试」 |\n| 未识别有效链接 | ⚠️ 解析失败 | 「未识别到有效的禅道缺陷链接」 | 「请确认消息内容」 |\n| 模块不在范围 | ↩️ 不在范围 | AI 判断的模块归属 | 「请确认模块并手动流转」 |\n| 置信度低 | ❓ 无法确定 | Bug 关键信息（标题、描述摘要） | 「请手动确认模块归属」 |\n| commit 提取失败 | ❌ 分析中断 | 日志片段（前 200 字符） | 「请手动确认分支」 |\n| commit 不在任何分支 | ❌ 分析中断 | commit id | 「请手动确认分支」 |\n| 时间提取失败 | ❓ 需补充信息 | 已尝试的来源汇总 | 「该 Bug 发生的精确时间是什么？」 |\n| 分析完成 | ✅ 分析完成 | 根因摘要（1-2 句）+ report.md 路径 | 「详见禅道评论 / 本地 report.md」 |\n\nFile v1.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"1.1.0\",\n  \"publishedAt\": 1785468854485\n}\n\nFile v1.1.0:references/zentao-api-reference.md\n\n# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |\n\nFile v1.1.0:scripts/package.json\n\n{\n  \"name\": \"zentao-bug-analyzer-scripts\",\n  \"private\": true,\n  \"description\": \"禅道缺陷自动分析 - Playwright 脚本集\",\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"dependencies\": {\n    \"playwright\": \"^1.40.0\"\n  },\n  \"devDependencies\": {\n    \"@ffmpeg-installer/ffmpeg\": \"^1.1.0\",\n    \"ffprobe-static\": \"^3.1.0\"\n  }\n}\n\nFile v1.1.0:skill-card.md\n\n## Description:\n\nAnalyzes ZenTao bug reports from Feishu-triggered links by gathering bug details, attachments, logs, local code context, and producing a root-cause report with optional ZenTao and Feishu updates.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[yeah526](https://clawhub.ai/user/yeah526)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and QA engineers use this skill to triage ZenTao defects, identify the affected module and branch, inspect logs and attachments, and prepare a concise root-cause analysis. It can also format the report for ZenTao comments and send a Feishu summary when configured.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill requires sensitive ZenTao credentials and broad local/browser authority.\n\nMitigation: Use a low-privilege ZenTao account, HTTPS, isolated disposable worktrees or containers, and pinned dependencies; do not store real passwords in workspace config until credential handling and CDP/browser exposure are fixed.\n\nRisk: Automatic ZenTao comments could publish incomplete or incorrect analysis.\n\nMitigation: Review generated reports before posting, and set auto_comment to false when manual approval is required.\n\nRisk: Bug analysis can modify local repository state through checkout or worktree operations.\n\nMitigation: Run analysis in disposable or isolated worktrees and verify cleanup of worktrees, browser sessions, and ZenTao helper processes after each run.\n\n## Reference(s):\n\n- [ZenTao API Reference](artifact/references/zentao-api-reference.md)\n- [ClawHub Skill Page](https://clawhub.ai/yeah526/skills/zentao-bug-analyzer)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown reports with shell command guidance, JSON metadata, HTML comment output, and Feishu-ready text summaries]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May write local bug artifacts such as downloaded attachments, extracted video frames, time metadata, reports, and comment HTML.]\n\n## Skill Version(s):\n\n1.1.0 (source: server release metadata; target metadata agrees)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.1.0:SKILL.checklist.md\n\n# 禅道 Bug 分析执行检查清单\n\n> ⚠️ 硬约束：分析开始前通读本清单，每步必须逐项完成，缺一不可。\n> 详细流程说明见 [SKILL.md](SKILL.md) 对应章节。\n\n## 执行检查清单\n\n- [ ] 步骤 1：消息解析（提取 Bug ID）→ [§步骤 1](SKILL.md#步骤-1消息解析)\n\n- [ ] 步骤 2：重复分析检查 → [§步骤 2](SKILL.md#步骤-2重复分析检查)\n  - 登录禅道（`zentao-login.js`，获取 WS endpoint，一个 Bug 全程复用）\n  - 获取 Bug 详情 + 检查 API `comments` 字段中的重复评论（非 `historyChanges`）\n\n- [ ] 步骤 3：模块分类 → [§步骤 3](SKILL.md#步骤-3模块分类)\n  - 按 config aliases 子串硬匹配，不在范围 → 飞书通知 + 终止\n\n- [ ] 步骤 4a：下载附件（`zentao-download-files.js`）→ [§步骤 4a](SKILL.md#4a-下载附件和日志)\n\n- [ ] 步骤 4b：确定 Bug 发生时间 → [§步骤 4b](SKILL.md#4b-确定-bug-发生时间)\n  - 优先：Bug 描述文本（steps + description）> 附件截图/视频系统时间 > 飞书询问\n  - 禁止：文件名/创建时间/上传时间作为时间来源\n\n- [ ] 步骤 4c-1：按 config commit_extract 规则提取 commit id → [§步骤 4c](SKILL.md#4c-分支定位)\n  - 搜不到 → 飞书通知 + 终止，禁止近似匹配\n\n- [ ] 步骤 4c-2：`git branch --contains <commit-id>` 记录分支信息\n\n- [ ] 步骤 4c-3：分支检出（二选一）：仓库空闲 → `git checkout` + submodule update；被占用 → `git worktree add` 隔离\n\n- [ ] 步骤 4d：AI 深度分析 → [§步骤 4d](SKILL.md#4d-ai-综合深度分析)\n  - 结合 Bug 详情 + 日志 + 代码 + API `comments` 评论\n\n- [ ] 🔴 步骤 5：输出报告 → [§步骤 5](SKILL.md#步骤-5结果输出)\n  - ⚠️ 先检查 config 根级别 `auto_comment` 字段（未配置时默认视为 `true`）\n  - `auto_comment === true` 或未配置：禅道评论（`zentao-build-comment.js` → `zentao-post-comment.js`）+ 飞书摘要\n  - `auto_comment === false`：仅生成 `report.md` + 飞书摘要\n\n- [ ] 🔴 步骤 6：清理 → [§步骤 6](SKILL.md#步骤-6清理)\n  1. 杀 login 进程 + Chrome 树（Windows: `taskkill /PID <PID> /F /T`，macOS/Linux: `kill -9 <PID> && pkill -P <PID>`）\n  2. `git worktree remove --force` 清理 worktree 残留\n  3. 检查无 `zentao-*.js` 残留进程\n  4. 确认只剩 OpenClaw 进程（gateway/worker）\n\nFile v1.1.0:TOOLS.md\n\n# zentao-bug-analyzer 工具与环境\n\n## 环境依赖\n\n- **Node.js** 18+（脚本运行）\n- **Playwright**：`npm install playwright && npx playwright install chromium`\n- **ffmpeg**（视频附件抽帧，步骤 4b）：`npm install @ffmpeg-installer/ffmpeg ffprobe-static --no-save`\n- **Node.js zlib**（解压 Android logcat `.gz` 日志，步骤 4c）：Node.js 内置，无需安装\n- **Git** 2.5+（`git worktree`、`git branch --contains`）\n- **视觉模型**（读取截图/视频帧中的系统时间 + 判断 BUG 现象，步骤 4b）：由 AI 代理运行环境提供\n- 禅道服务器可访问：`http://zentao.gxatek.com:20080`\n\n**禁止的替代方案**：\n- ❌ 用 winget 装系统级 ffmpeg（实测 `winget install Gyan.FFmpeg` 超时不可靠）\n- ❌ 用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或 .NET 工具解压 logcat `.gz`（兼容性 bug，会丢失大量日志）\n- ❌ 用 PowerShell/.NET 替代品处理视频\n\n## 禅道交互 · 统一 Playwright 模式\n\n> 📖 认证方式（企业版 12.1 不支持 Bearer Token）、单会话铁律详见 [SKILL.md § 禅道交互方式](SKILL.md#禅道交互方式) 和 [SKILL.md § 执行守则](SKILL.md#⚠️-执行守则最高优先级)。以下为脚本用法参考。\n\n通过 `scripts/` 下的 5 个固定脚本实现，一个脚本一个功能。\n\n### 脚本\n\n| 脚本 | 功能 | 用法 |\n|------|------|------|\n| `scripts/zentao-login.js` | 登录禅道，输出 WS endpoint | `node scripts/zentao-login.js [--port=9224]` |\n| `scripts/zentao-get-bug.js` | 获取 Bug 详情 JSON + 操作历史 JSON（分隔符输出） | `node scripts/zentao-get-bug.js --ws=<WS> --bug-id=<id>` |\n| `scripts/zentao-download-files.js` | 下载 Bug 附件到本地 | `node scripts/zentao-download-files.js --ws=<WS> --bug-id=<id> --dir=<dir>` |\n| `scripts/zentao-build-comment.js` | Markdown 报告 → HTML 评论 | `node scripts/zentao-build-comment.js <report.md> [--out <output.html>]` |\n| `scripts/zentao-post-comment.js` | 发布 Bug 评论 | `node scripts/zentao-post-comment.js --ws=<WS> --bug-id=<id> --comment-file=<path>` |\n\n> **zentao-get-bug.js 输出格式**：分隔符行包围 JSON，`---BUG_START---` / `---BUG_END---` 包裹 Bug 详情，`---HISTORY_START---` / `---HISTORY_END---` 包裹操作历史数组。调用方须按分隔符解析两段 JSON。\n\n### 典型调用流程\n\n```\n1. node scripts/zentao-login.js --port=9224\n   → WS=ws://localhost:9224/devtools/browser/{id}, PID={pid}\n\n2. node scripts/zentao-get-bug.js --ws={WS} --bug-id=1432606\n   → JSON (stdout)\n\n3. node scripts/zentao-download-files.js --ws={WS} --bug-id=1432606 --dir=bugs/1432606\n   → 文件路径列表 (stdout)\n\n4. node scripts/zentao-build-comment.js bugs/1432606/report.md --out bugs/1432606/comment.html\n   → HTML 文件路径 (stdout)\n\n5. node scripts/zentao-post-comment.js --ws={WS} --bug-id=1432606 --comment-file=bugs/1432606/comment.html\n   → OK / FAIL\n```\n\n### login 脚本输出格式\n\n`zentao-login.js` 输出两行 key=value（可直接 shell `eval`）：\n\n```\nWS=ws://localhost:9224/devtools/browser/{browser-id}\nPID={node-process-pid}\n```\n\n其他脚本通过 `--ws` 参数复用会话。\n\n### 参数说明\n\n- `--ws`：login 脚本返回的 WebSocket endpoint\n- `--bug-id`：禅道 Bug ID（数字）\n- `--dir`：附件下载目标目录（自动创建）\n- `--comment-file`：评论文件路径（推荐，由 build-comment.js 生成的 HTML 文件）\n- `--comment`：评论内容（原始 HTML 字符串。⚠️ 仅用于测试单行纯文本；生产环境必须用 `--comment-file`）\n- `--port`：CDP 调试端口（默认 9224）\n- `--zentao-url`：禅道实例地址（默认 `http://zentao.gxatek.com:20080`）\n\n## 本文件定位\n\nTOOLS.md 仅放环境依赖和脚本用法。完整 API 参考见 `references/zentao-api-reference.md`，流程规范见 `SKILL.md`。\n\nArchive v1.0.0: 11 files, 23440 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/zentao-build-comment.js (3874b), scripts/zentao-download-files.js (5995b), scripts/zentao-get-bug.js (4480b), scripts/zentao-login.js (5070b), scripts/zentao-post-comment.js (3579b), skill-card.md (2479b), SKILL.checklist.md (2082b), SKILL.md (16526b), TOOLS.md (2917b), _meta.json (138b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个脚本操作禅道**，禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不做任何恢复操作。\n5. **分析完输出报告**：步骤 4d 产出分析报告后，根据 `auto_comment` 配置决定是否评论禅道：\n   - `auto_comment === true`：运行 `zentao-post-comment.js` 评论 + 飞书摘要\n   - `auto_comment === false`：仅飞书摘要，不评论禅道\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"auto_comment\": true,\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}\n```\n\n字段说明：\n- `name`：模块名称\n- `aliases`：模块别名列表（字符串数组），用于精确匹配。**匹配规则**：将 Bug 的 title、module.name、product.name 与所有模块的 name + aliases 做**子串匹配**（忽略大小写），任一命中即判定为该模块。此规则为硬规则，优先于 AI 主观判断\n- `code_dir`：模块本地代码仓库绝对路径\n- `commit_extract`：自然语言，告诉 AI 如何从日志提取 commit id\n- `analyzer`：`\"default\"` | `\"skill:技能名\"`。default 走通用 AI 分析流程；skill:xxx 委派给对应 Skill\n- `analyze_hint`：模块专属分析提示词（可选），无论哪种分析器都会传给分析器\n- `auto_comment`：布尔值，控制分析完成后是否自动将报告评论到禅道 Bug 下。`true` = 自动评论（默认行为）；`false` = 仅生成报告 + 飞书通知，不评论禅道\n\n### 首次配置引导\n\n配置文件不存在时启动对话式引导。流程：\n\n1. 「请提供禅道的登录账号和密码（用于 Playwright 登录禅道。密码会存储在本地配置文件中，不会泄露）」\n2. 「你负责哪些模块？请列出模块名称（用逗号分隔，如：车机设置, 蓝牙模块, 语音助手）」\n3. 对每个模块依次询问：\n   - 「对于\"{模块名}\"模块，有哪些别名/关键词可以用来识别？（用逗号分隔，如：桌面卡片, systemui, 设置）」\n   - 「对于\"{模块名}\"模块，本地代码目录路径是什么？（请使用绝对路径）」\n   - 「对于\"{模块名}\"模块，日志中如何提取 commit id？请用自然语言描述提取规则」\n   - 「对于\"{模块名}\"模块，是否需要使用专用分析 Skill？（目前可用的 Skill：[列出]。输入 Skill 名或留空走默认分析）」\n   - 「对于\"{模块名}\"模块，有什么分析提示或重点关注方向？（可选，留空则用默认分析策略）」\n4. 「分析完成后，是否需要自动将分析报告评论到禅道 Bug 下？（回复\"是\"=自动评论，\"否\"=仅飞书通知，不评论禅道）」\n5. 「配置完成！请确认你已创建邮件收信规则：当发件人为 `zentao@syncore.space` 时，自动将邮件转发/分享到本 Bot 的对话中。」\n\n---\n\n## 分析流水线\n\n### 步骤 1：消息解析\n\n从消息内容提取禅道 Bug 链接，正则：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 步骤 2：重复分析检查\n\n> ⚠️ 此步骤是强制检查点，无论通过哪种触发方式（邮件转发或自然语言）进入分析流水线，必须先走步骤 2。已评论过的 Bug 绝对不允许直接进入后续步骤。\n\n1. 运行 `scripts/zentao-get-bug.js` 获取 Bug 详情（含历史评论，后续步骤复用）\n2. 检查历史评论中是否已有 `zentao.account` 配置账号的评论\n\n**已有我的评论**：飞书私聊询问「该 Bug 你已评论过，是否需要重新分析？（回复\"是\"或\"分析\"继续，回复\"否\"或\"取消\"跳过）」\n- 确认「是」→ 继续步骤 3\n- 确认「否」或 5 分钟内未回复 → 流程终止\n\n**没有我的评论**：直接继续步骤 3。\n\n### 步骤 3：模块分类\n\n**匹配规则（优先级从高到低）**：\n\n1. **硬别名匹配（优先）**：遍历配置中每个 module 的 `aliases` 数组，将每个别名与 Bug 的 `title`、`module.name`、`product.name` 做**子串匹配**（忽略大小写）。只要任一副本字段包含任一个别名（或 `name` 本身），即判定命中该模块。\n   - 例如：Bug标题含\"桌面卡片\"，配置别名中有\"桌面卡片\" → 直接命中\n   - ⚠️ 此规则是机械规则，不依赖 AI 判断，直接执行\n2. **AI 语义判断（兜底）**：硬别名未命中时，AI 综合判断 Bug 归属模块，对照配置文件 `modules` 列表\n\n**结果处理**：\n- **在范围**：继续步骤 4\n- **不在范围**：飞书私聊通知（Bug 标题、链接、AI 判断的模块归属），提醒模块确认和手动流转。流程结束\n- **置信度低**：飞书私聊通知（Bug 链接 + 关键信息），告知无法确定模块，请手动确认。流程结束\n\n### 步骤 4：深度分析\n\n#### 4a. 下载附件和日志\n运行 `scripts/zentao-download-files.js` 下载 Bug 所有附件到 `bugs/{bug_id}/`。（script 自动处理大文件分块传输，支持 160MB+ 附件）\n\n> ⚠️ 步骤 4a 完成后必须先执行 4b（确定 Bug 发生时间），再进入 4c。\n\n#### 4b. 确定 Bug 发生时间\n\n> ⚠️ 硬约束：Bug 发生时间必须从可靠来源直接获取，禁止猜测或间接推断。\n\n**获取优先级**：\n1. **Bug 描述文本**中明确写出的时间（如「17:33 复现」「12:05 发现」）\n2. **附件视频/截图**中可见的系统时间（状态栏、水印等），需打开查看\n3. **飞书询问用户**：以上均不可用时，私聊询问「该 Bug 发生的精确时间是什么？」\n\n**禁止行为**：\n- ❌ 用附件文件名中的时间戳猜测\n- ❌ 用 Bug 创建时间、最后修改时间间接推断\n- ❌ 用聊天消息转发时间、邮件接收时间推断\n- ❌ 任何不在上述优先级列表内的间接推演\n\n**时间用于**：\n- 日志分析：定位 Bug 发生时刻前后 ±5 分钟的日志片段\n- Git blame：确定相关代码变更时间线\n- 匹配历史评论中提到的复现时间\n\n#### 4c. 分支定位\n1. 解压并读取日志文件：\n   - Android logcat 的 `.gz` 文件**必须使用 Node.js zlib 解压**，禁止使用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或类似 .NET 解压工具\n   - ⚠️ .NET GZipStream 对 Android logd 生成的某些 gzip 流存在兼容性 bug（提前终止解压，实际 30MB 仅解出 ~65KB），会导致日志内容严重缺失\n   - 推荐命令：`node -e \"const zlib=require('zlib');const fs=require('fs');const buf=fs.readFileSync('<log.gz>');zlib.gunzip(buf,(e,r)=>{if(e){console.error(e);return}const s=r.toString('utf8');/* 搜索/处理 s */})\"`\n2. 按配置中 `commit_extract` 从日志提取 commit id\n3. `cd {code_dir}` → `git branch --contains <commit-id>` 确认 commit 在哪些分支上。结果写入分析报告的「分支信息」字段（格式：`分支名 | commit-id`）\n4. 同模块已有其他分析任务时，用 `git worktree add .claude/worktrees/bug-{bug_id}/ <commit-id>` 创建隔离工作区\n5. `git checkout <commit-id>`（进入 detached HEAD 是正常行为，分析完成后保持不动即可）+ `git submodule update --init --recursive`\n\n**commit id 提取失败**：飞书私聊通知（附带日志片段），流程终止。\n\n> ⚠️ 硬约束：只使用配置中 commit_extract 指定的提取规则，禁止 AI 自行更换搜索关键词（如换 TAG、换正则）。搜不到就是搜不到，不允许\"近似匹配\"或\"换成类似的 TAG 试试\"。\n> Self-Check：若在分析过程中进行了 commit_extract 规则以外的额外搜索，应立即停止、丢弃中间产物，回到步骤 4c 标准路径并报告提取失败。\n\n**commit id 不在任何分支**：飞书私聊通知（附带 commit id），流程终止\n\n> ⚠️ 硬约束：`git checkout <commit-id>` 后必须执行 `git submodule update --init --recursive`，确保所有 submodule 都已 checkout 到对应版本。未 checkout submodule 可能导致分析时缺少依赖代码、漏掉跨仓库 API 不一致问题。\n\n#### 4d. AI 综合深度分析\n\n历史评论已在步骤 2 获取，此处直接使用。\n\n根据 `analyzer` 字段：\n- `\"default\"`：AI 综合 Bug 详情 + 附件/日志 + 历史评论 + 本地代码分析\n- `\"skill:xxx\"`：委派给指定 Skill，传入分析上下文\n\n无论哪种方式，`analyze_hint` 都作为上下文传入。\n\n输出格式（Markdown，AI 直接产出此结构）：\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**：\n  ```lang\n  // 关键代码\n  ```\n- **判断依据**：（结合日志/历史评论/代码逻辑的推理过程）\n\n### 修复建议\n1. 具体修复方向（可操作步骤，非抽象建议）\n\n### 风险评估\n- **影响范围**：（哪些功能/模块受影响）\n- **严重程度**：（低/中/高/严重 + 理由）\n\n### 步骤 5：结果输出\n\n> ⚠️ **auto_comment 开关**：步骤 5 开始前，检查配置文件中 `auto_comment` 字段（默认为 `true`）。\n> - `auto_comment === false`：跳过禅道评论（步骤 5.1），仅生成 `report.md` + 执行飞书私聊通知（步骤 5.2）\n> - `auto_comment === true` 或未配置：执行完整双通道（禅道评论 + 飞书通知）\n\n1. **禅道评论**（仅在 `auto_comment !== false` 时执行）：\n   a. 将分析报告写入 `bugs/{bug_id}/report.md`（按步骤 4d 输出格式）\n   b. 运行 `node scripts/zentao-build-comment.js bugs/{bug_id}/report.md --out bugs/{bug_id}/comment.html` 生成 HTML\n   c. 运行 `node scripts/zentao-post-comment.js --ws=<wsEndpoint> --bug-id=<id> --comment-file=bugs/{bug_id}/comment.html` 发布（**必须用 `--comment-file`，禁止用 `--comment` 传 HTML 内容**）\n   d. ⚠️ 禁止手写临时 Playwright 脚本发布评论\n2. **飞书私聊**：简要摘要 + 禅道 Bug 链接\n\n### 步骤 6：清理\n\n分析完成后必须清理残留进程，避免占用系统资源：\n\n1. **杀掉 login 常驻进程（连带 Chrome）**：`taskkill /PID <login-PID> /F /T`，PID 来自 `zentao-login.js` 输出行 `PID=<value>`。`/T` 会连带终结 Chrome 子进程树\n2. **清理 git worktree**：`git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove .claude/worktrees/bug-{bug_id}/`\n3. **检查残留脚本进程**：`Get-Process node` 检查是否还有 `zentao-*.js` 相关进程，有则 `taskkill /F /PID <pid>` 清理\n4. **确认清理完毕**：最终应只剩 OpenClaw 自身的 node 进程（gateway/worker），不应有其他 `zentao-*.js` 残留\n\n> ⚠️ 注意：不要杀掉 OpenClaw 自身的 node 进程（gateway/worker），只清理 `zentao-*.js` 和 Chrome headless 相关进程。\n\n---\n\n## 并发处理\n\n- **不同模块**：代码目录不同，全部并行处理\n- **同一模块同时分析多个 Bug 时**：用 `git worktree` 为每个 Bug 创建隔离工作区，分析完成后 `git worktree remove` 清理\n\n---\n\n## 禅道交互方式\n\n> ⚠️ 企业版 12.1 不支持 Bearer Token 认证（`POST /api.php/v1/tokens` 不可用），所有读写操作统一走 Playwright。\n\n### 🔴 铁律：单次 Playwright 会话\n\n**一个 Bug 的分析全程只允许启动一次 Playwright 浏览器**。登录后所有操作（读详情、下载附件、写评论）复用同一会话，禁止：\n\n- ❌ 分多个脚本文件各启动一次 Playwright\n- ❌ 中途关闭浏览器再重新登录\n- ❌ 写评论时用新的浏览器实例\n\n### 🔴 铁律：脚本优先，禁止手写临时 Playwright 脚本\n\n**禅道交互只允许使用 `scripts/` 目录下的 5 个固定脚本**：\n\n| 脚本 | 用途 | 关键参数 |\n|------|------|----------|\n| `zentao-login.js` | 登录 | `--port`（默认 9224）|\n| `zentao-get-bug.js` | 获取 Bug 详情 | `--ws`、`--bug-id` |\n| `zentao-download-files.js` | 下载附件 | `--ws`、`--bug-id`、`--dir` |\n| `zentao-build-comment.js` | Markdown → HTML 评论 | `<report.md> [--out <output.html>]` |\n| `zentao-post-comment.js` | 发布评论 | `--ws`、`--bug-id`、`--comment-file=<path>`（推荐）或 `--comment`（原始 HTML）|\n\n**禁止行为**：\n- ❌ 手写临时 `post_comment.js`、`check_bug.js`、`debug_login.js` 等任何 Playwright 脚本\n- ❌ 在 `bugs/{bug_id}/` 目录下创建任何 `.js` 文件\n- ❌ 用 `page.evaluate`、`page.fill`、`page.click` 等 Playwright API 绕过已有脚本\n\n**遇到脚本报错时的正确处理方式**：\n1. 先读脚本源码，理解它依赖的输入（WS endpoint、参数格式等）\n2. 修复输入条件（如重新登录获取有效 WS endpoint），而不是绕过脚本\n3. 如果脚本本身有 bug，修复脚本源码（`scripts/` 目录下），让修复对所有后续分析生效\n\n---\n\n## 边界情况处理\n\n| 场景 | 处理 |\n|------|------|\n| 不含禅道链接 | 「未识别到有效的禅道缺陷链接，请确认消息内容」 |\n| 链接解析失败 | 「无法解析该链接，请确认是否正确转发」 |\n| 禅道 API 请求失败（登录失效/会话过期） | 「无法访问禅道，请检查连接和登录状态」 |\n| 模块分类置信度低 | 飞书通知：Bug 链接+关键信息，请手动确认 |\n| 模块不在负责范围 | 飞书通知：Bug 归属 + 提醒手动流转 |\n| commit id 提取失败 | 飞书通知：日志片段，请手动确认分支 |\n| commit id 不在任何分支 | 飞书通知：commit id，请手动确认 |\n| 附件/日志下载失败 | 降级：仅基于 Bug 描述+历史评论+代码分析，评论注明「未能获取附件」，飞书通知 |\n| 本地代码目录不存在 | 降级：跳过代码分析，仅日志+附件+评论，飞书通知检查配置 |\n| 分析过程中断或超时 | 飞书通知进度和失败原因，不留半截评论 |\n| 用户 5 分钟内未回复重新分析确认 | 默认不重新分析，流程终止 |\n| 分析过程中 git worktree 冲突 | 清理残留 worktree 后重试；仍失败则飞书通知 |\n\n---\n\n## 范围约束\n\n- 不自动填写指派人或流转状态\n- 不自动生成修复代码\n- 不做缺陷趋势统计或报表\n- 当前只服务单一用户\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1784708541374\n}\n\nFile v1.0.0:references/zentao-api-reference.md\n\n# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |\n\nFile v1.0.0:skill-card.md\n\n## Description: <br>\nAnalyzes ZenTao bug reports by extracting Bug links from Feishu messages, collecting issue details and attachments, locating relevant code versions, and producing root-cause reports with optional ZenTao comments and Feishu summaries. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[yeah526](https://clawhub.ai/user/yeah526) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and QA engineers use this skill to triage ZenTao defects, gather logs and attachments, map bugs to configured local code modules, and prepare Markdown root-cause analysis reports for review or posting back to ZenTao. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill uses an authenticated ZenTao session and stores a ZenTao password in local configuration. <br>\nMitigation: Keep bug-analyzer-config.json out of source control, restrict file permissions, use appropriate account access, and clean up the browser session after each run. <br>\nRisk: The skill can automatically post analysis results to ZenTao when auto_comment is enabled. <br>\nMitigation: Set auto_comment to false until reports have been reviewed, then enable posting only for trusted workflows. <br>\nRisk: The workflow checks out commits and may create local worktrees while analyzing code. <br>\nMitigation: Run analysis in an isolated working tree or disposable checkout and confirm the target repository state before reusing it. <br>\n\n\n## Reference(s): <br>\n- [ZenTao API Reference](references/zentao-api-reference.md) <br>\n- [ClawHub Skill Page](https://clawhub.ai/yeah526/skills/zentao-bug-analyzer) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance] <br>\n**Output Format:** [Markdown reports with supporting shell commands, JSON script output, and generated HTML comments] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May write per-bug report and comment files under bugs/<bug_id>/ and may post comments when auto_comment is enabled.] <br>\n\n## Skill Version(s): <br>\n1.0.0 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.0.0:SKILL.checklist.md\n\n# 禅道 Bug 分析执行检查清单\n\n> ⚠️ 硬约束：分析开始前通读本清单，每步必须逐项完成，缺一不可。\n\n## 执行检查清单\n\n- [ ] 步骤 1：消息解析（提取 Bug ID）\n\n- [ ] 步骤 2：重复分析检查\n  - 登录禅道（`zentao-login.js`，获取 WS endpoint，一个 Bug 全程复用）\n  - 获取 Bug 详情 + 检查重复评论（`zentao-get-bug.js`，有我的评论 → 飞书询问是否重新分析）\n\n- [ ] 步骤 3：模块分类（按 config aliases 子串硬匹配，不在范围 → 飞书通知 + 终止）\n\n- [ ] 步骤 4a：下载附件（`zentao-download-files.js`）\n\n- [ ] 步骤 4b：确定 Bug 发生时间（Bug 描述文本 > 附件截图/视频系统时间 > 飞书询问。禁止用文件名/创建时间推断）\n\n- [ ] 步骤 4c-1：按 config commit_extract 规则提取 commit id（搜不到 → 飞书通知 + 终止，禁止近似匹配）\n\n- [ ] 步骤 4c-2：`git branch --contains <commit-id>` 记录分支信息\n\n- [ ] 步骤 4c-3：`git checkout <commit-id>` + `git submodule update --init --recursive`\n\n- [ ] 步骤 4d：AI 深度分析（结合 Bug 详情 + 日志 + 代码 + 历史评论）\n\n- [ ] 🔴 步骤 5：输出报告\n  - ⚠️ 先检查 config 中 `auto_comment` 字段（默认 `true`）\n  - `auto_comment === true` 或未配置：\n    - 步骤 5a：禅道评论（先 `zentao-build-comment.js` 生成 HTML，再 `zentao-post-comment.js --comment-file=<file>` 发布）\n  - `auto_comment === false`：跳过禅道评论，仅生成 `report.md`\n\n- [ ] 步骤 5b：飞书摘要（简要结果 + Bug 链接）\n\n- [ ] 🔴 步骤 6：清理 — 必须完成！\n  1. `taskkill /PID <login-PID> /F /T`（PID 来自 `zentao-login.js` 输出行 `PID=<value>`，`/T` 连带杀 Chrome 子进程树）\n  2. `git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove <path>` 清理\n  3. `Get-Process node` 检查无 `zentao-*.js` 残留进程，有则 `taskkill /F /PID <pid>` 清理\n  4. 确认只剩 OpenClaw 自身 node 进程（gateway/worker）\n\nFile v1.0.0:TOOLS.md\n\n# zentao-bug-analyzer 工具与环境\n\n## 环境依赖\n\n- **Node.js** 18+（脚本运行）\n- **Playwright**：`npm install playwright && npx playwright install chromium`\n- **Git** 2.5+（`git worktree`、`git branch --contains`）\n- 禅道服务器可访问：`http://zentao.gxatek.com:20080`\n\n## 禅道交互 · 统一 Playwright 模式\n\n企业版 12.1 不支持 Bearer Token，所有操作在同一 Playwright 会话中完成。通过 `scripts/` 下的 5 个固定脚本实现，一个脚本一个功能。\n\n### 单会话铁律\n\n一个 Bug 全程只启动一次 Playwright 浏览器。登录后读详情、下载附件、写评论全部复用同一 `browser`/`page`/`context`。\n\n### 脚本\n\n| 脚本 | 功能 | 用法 |\n|------|------|------|\n| `scripts/zentao-login.js` | 登录禅道，输出 WS endpoint | `node scripts/zentao-login.js [--port=9224]` |\n| `scripts/zentao-get-bug.js` | 获取 Bug 详情 JSON | `node scripts/zentao-get-bug.js --ws=<WS> --bug-id=<id>` |\n| `scripts/zentao-download-files.js` | 下载 Bug 附件到本地 | `node scripts/zentao-download-files.js --ws=<WS> --bug-id=<id> --dir=<dir>` |\n| `scripts/zentao-build-comment.js` | Markdown 报告 → HTML 评论 | `node scripts/zentao-build-comment.js <report.md> [--out <output.html>]` |\n| `scripts/zentao-post-comment.js` | 发布 Bug 评论 | `node scripts/zentao-post-comment.js --ws=<WS> --bug-id=<id> --comment-file=<path>` |\n\n### 典型调用流程\n\n```\n1. node scripts/zentao-login.js --port=9224\n   → WS=ws://localhost:9224/devtools/browser/{id}, PID={pid}\n\n2. node scripts/zentao-get-bug.js --ws={WS} --bug-id=1432606\n   → JSON (stdout)\n\n3. node scripts/zentao-download-files.js --ws={WS} --bug-id=1432606 --dir=bugs/1432606\n   → 文件路径列表 (stdout)\n\n4. node scripts/zentao-build-comment.js bugs/1432606/report.md --out bugs/1432606/comment.html\n   → HTML 文件路径 (stdout)\n\n5. node scripts/zentao-post-comment.js --ws={WS} --bug-id=1432606 --comment-file=bugs/1432606/comment.html\n   → OK / FAIL\n```\n\n### login 脚本输出格式\n\n`zentao-login.js` 输出两行 key=value（可直接 shell `eval`）：\n\n```\nWS=ws://localhost:9224/devtools/browser/{browser-id}\nPID={chromium-pid}\n```\n\n其他脚本通过 `--ws` 参数复用会话。\n\n### 参数说明\n\n- `--ws`：login 脚本返回的 WebSocket endpoint\n- `--bug-id`：禅道 Bug ID（数字）\n- `--dir`：附件下载目标目录（自动创建）\n- `--comment-file`：评论文件路径（推荐，由 build-comment.js 生成的 HTML 文件）\n- `--comment`：评论内容（原始 HTML 字符串，脚本自动编码。备选方案，推荐用 `--comment-file`）\n- `--port`：CDP 调试端口（默认 9224）\n- `--zentao-url`：禅道实例地址（默认 `http://zentao.gxatek.com:20080`）\n\n## 本文件定位\n\nTOOLS.md 仅放环境依赖和脚本用法。完整 API 参考见 `references/zentao-api-reference.md`，流程规范见 `SKILL.md`。\n\nArchive v0.0.7: 11 files, 23545 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/zentao-build-comment.js (3874b), scripts/zentao-download-files.js (5995b), scripts/zentao-get-bug.js (4480b), scripts/zentao-login.js (5070b), scripts/zentao-post-comment.js (3579b), skill-card.md (2762b), SKILL.checklist.md (2082b), SKILL.md (16526b), TOOLS.md (2917b), _meta.json (138b)\n\nFile v0.0.7:SKILL.md\n\n---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个脚本操作禅道**，禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不做任何恢复操作。\n5. **分析完输出报告**：步骤 4d 产出分析报告后，根据 `auto_comment` 配置决定是否评论禅道：\n   - `auto_comment === true`：运行 `zentao-post-comment.js` 评论 + 飞书摘要\n   - `auto_comment === false`：仅飞书摘要，不评论禅道\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"auto_comment\": true,\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}\n```\n\n字段说明：\n- `name`：模块名称\n- `aliases`：模块别名列表（字符串数组），用于精确匹配。**匹配规则**：将 Bug 的 title、module.name、product.name 与所有模块的 name + aliases 做**子串匹配**（忽略大小写），任一命中即判定为该模块。此规则为硬规则，优先于 AI 主观判断\n- `code_dir`：模块本地代码仓库绝对路径\n- `commit_extract`：自然语言，告诉 AI 如何从日志提取 commit id\n- `analyzer`：`\"default\"` | `\"skill:技能名\"`。default 走通用 AI 分析流程；skill:xxx 委派给对应 Skill\n- `analyze_hint`：模块专属分析提示词（可选），无论哪种分析器都会传给分析器\n- `auto_comment`：布尔值，控制分析完成后是否自动将报告评论到禅道 Bug 下。`true` = 自动评论（默认行为）；`false` = 仅生成报告 + 飞书通知，不评论禅道\n\n### 首次配置引导\n\n配置文件不存在时启动对话式引导。流程：\n\n1. 「请提供禅道的登录账号和密码（用于 Playwright 登录禅道。密码会存储在本地配置文件中，不会泄露）」\n2. 「你负责哪些模块？请列出模块名称（用逗号分隔，如：车机设置, 蓝牙模块, 语音助手）」\n3. 对每个模块依次询问：\n   - 「对于\"{模块名}\"模块，有哪些别名/关键词可以用来识别？（用逗号分隔，如：桌面卡片, systemui, 设置）」\n   - 「对于\"{模块名}\"模块，本地代码目录路径是什么？（请使用绝对路径）」\n   - 「对于\"{模块名}\"模块，日志中如何提取 commit id？请用自然语言描述提取规则」\n   - 「对于\"{模块名}\"模块，是否需要使用专用分析 Skill？（目前可用的 Skill：[列出]。输入 Skill 名或留空走默认分析）」\n   - 「对于\"{模块名}\"模块，有什么分析提示或重点关注方向？（可选，留空则用默认分析策略）」\n4. 「分析完成后，是否需要自动将分析报告评论到禅道 Bug 下？（回复\"是\"=自动评论，\"否\"=仅飞书通知，不评论禅道）」\n5. 「配置完成！请确认你已创建邮件收信规则：当发件人为 `zentao@syncore.space` 时，自动将邮件转发/分享到本 Bot 的对话中。」\n\n---\n\n## 分析流水线\n\n### 步骤 1：消息解析\n\n从消息内容提取禅道 Bug 链接，正则：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 步骤 2：重复分析检查\n\n> ⚠️ 此步骤是强制检查点，无论通过哪种触发方式（邮件转发或自然语言）进入分析流水线，必须先走步骤 2。已评论过的 Bug 绝对不允许直接进入后续步骤。\n\n1. 运行 `scripts/zentao-get-bug.js` 获取 Bug 详情（含历史评论，后续步骤复用）\n2. 检查历史评论中是否已有 `zentao.account` 配置账号的评论\n\n**已有我的评论**：飞书私聊询问「该 Bug 你已评论过，是否需要重新分析？（回复\"是\"或\"分析\"继续，回复\"否\"或\"取消\"跳过）」\n- 确认「是」→ 继续步骤 3\n- 确认「否」或 5 分钟内未回复 → 流程终止\n\n**没有我的评论**：直接继续步骤 3。\n\n### 步骤 3：模块分类\n\n**匹配规则（优先级从高到低）**：\n\n1. **硬别名匹配（优先）**：遍历配置中每个 module 的 `aliases` 数组，将每个别名与 Bug 的 `title`、`module.name`、`product.name` 做**子串匹配**（忽略大小写）。只要任一副本字段包含任一个别名（或 `name` 本身），即判定命中该模块。\n   - 例如：Bug标题含\"桌面卡片\"，配置别名中有\"桌面卡片\" → 直接命中\n   - ⚠️ 此规则是机械规则，不依赖 AI 判断，直接执行\n2. **AI 语义判断（兜底）**：硬别名未命中时，AI 综合判断 Bug 归属模块，对照配置文件 `modules` 列表\n\n**结果处理**：\n- **在范围**：继续步骤 4\n- **不在范围**：飞书私聊通知（Bug 标题、链接、AI 判断的模块归属），提醒模块确认和手动流转。流程结束\n- **置信度低**：飞书私聊通知（Bug 链接 + 关键信息），告知无法确定模块，请手动确认。流程结束\n\n### 步骤 4：深度分析\n\n#### 4a. 下载附件和日志\n运行 `scripts/zentao-download-files.js` 下载 Bug 所有附件到 `bugs/{bug_id}/`。（script 自动处理大文件分块传输，支持 160MB+ 附件）\n\n> ⚠️ 步骤 4a 完成后必须先执行 4b（确定 Bug 发生时间），再进入 4c。\n\n#### 4b. 确定 Bug 发生时间\n\n> ⚠️ 硬约束：Bug 发生时间必须从可靠来源直接获取，禁止猜测或间接推断。\n\n**获取优先级**：\n1. **Bug 描述文本**中明确写出的时间（如「17:33 复现」「12:05 发现」）\n2. **附件视频/截图**中可见的系统时间（状态栏、水印等），需打开查看\n3. **飞书询问用户**：以上均不可用时，私聊询问「该 Bug 发生的精确时间是什么？」\n\n**禁止行为**：\n- ❌ 用附件文件名中的时间戳猜测\n- ❌ 用 Bug 创建时间、最后修改时间间接推断\n- ❌ 用聊天消息转发时间、邮件接收时间推断\n- ❌ 任何不在上述优先级列表内的间接推演\n\n**时间用于**：\n- 日志分析：定位 Bug 发生时刻前后 ±5 分钟的日志片段\n- Git blame：确定相关代码变更时间线\n- 匹配历史评论中提到的复现时间\n\n#### 4c. 分支定位\n1. 解压并读取日志文件：\n   - Android logcat 的 `.gz` 文件**必须使用 Node.js zlib 解压**，禁止使用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或类似 .NET 解压工具\n   - ⚠️ .NET GZipStream 对 Android logd 生成的某些 gzip 流存在兼容性 bug（提前终止解压，实际 30MB 仅解出 ~65KB），会导致日志内容严重缺失\n   - 推荐命令：`node -e \"const zlib=require('zlib');const fs=require('fs');const buf=fs.readFileSync('<log.gz>');zlib.gunzip(buf,(e,r)=>{if(e){console.error(e);return}const s=r.toString('utf8');/* 搜索/处理 s */})\"`\n2. 按配置中 `commit_extract` 从日志提取 commit id\n3. `cd {code_dir}` → `git branch --contains <commit-id>` 确认 commit 在哪些分支上。结果写入分析报告的「分支信息」字段（格式：`分支名 | commit-id`）\n4. 同模块已有其他分析任务时，用 `git worktree add .claude/worktrees/bug-{bug_id}/ <commit-id>` 创建隔离工作区\n5. `git checkout <commit-id>`（进入 detached HEAD 是正常行为，分析完成后保持不动即可）+ `git submodule update --init --recursive`\n\n**commit id 提取失败**：飞书私聊通知（附带日志片段），流程终止。\n\n> ⚠️ 硬约束：只使用配置中 commit_extract 指定的提取规则，禁止 AI 自行更换搜索关键词（如换 TAG、换正则）。搜不到就是搜不到，不允许\"近似匹配\"或\"换成类似的 TAG 试试\"。\n> Self-Check：若在分析过程中进行了 commit_extract 规则以外的额外搜索，应立即停止、丢弃中间产物，回到步骤 4c 标准路径并报告提取失败。\n\n**commit id 不在任何分支**：飞书私聊通知（附带 commit id），流程终止\n\n> ⚠️ 硬约束：`git checkout <commit-id>` 后必须执行 `git submodule update --init --recursive`，确保所有 submodule 都已 checkout 到对应版本。未 checkout submodule 可能导致分析时缺少依赖代码、漏掉跨仓库 API 不一致问题。\n\n#### 4d. AI 综合深度分析\n\n历史评论已在步骤 2 获取，此处直接使用。\n\n根据 `analyzer` 字段：\n- `\"default\"`：AI 综合 Bug 详情 + 附件/日志 + 历史评论 + 本地代码分析\n- `\"skill:xxx\"`：委派给指定 Skill，传入分析上下文\n\n无论哪种方式，`analyze_hint` 都作为上下文传入。\n\n输出格式（Markdown，AI 直接产出此结构）：\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**：\n  ```lang\n  // 关键代码\n  ```\n- **判断依据**：（结合日志/历史评论/代码逻辑的推理过程）\n\n### 修复建议\n1. 具体修复方向（可操作步骤，非抽象建议）\n\n### 风险评估\n- **影响范围**：（哪些功能/模块受影响）\n- **严重程度**：（低/中/高/严重 + 理由）\n\n### 步骤 5：结果输出\n\n> ⚠️ **auto_comment 开关**：步骤 5 开始前，检查配置文件中 `auto_comment` 字段（默认为 `true`）。\n> - `auto_comment === false`：跳过禅道评论（步骤 5.1），仅生成 `report.md` + 执行飞书私聊通知（步骤 5.2）\n> - `auto_comment === true` 或未配置：执行完整双通道（禅道评论 + 飞书通知）\n\n1. **禅道评论**（仅在 `auto_comment !== false` 时执行）：\n   a. 将分析报告写入 `bugs/{bug_id}/report.md`（按步骤 4d 输出格式）\n   b. 运行 `node scripts/zentao-build-comment.js bugs/{bug_id}/report.md --out bugs/{bug_id}/comment.html` 生成 HTML\n   c. 运行 `node scripts/zentao-post-comment.js --ws=<wsEndpoint> --bug-id=<id> --comment-file=bugs/{bug_id}/comment.html` 发布（**必须用 `--comment-file`，禁止用 `--comment` 传 HTML 内容**）\n   d. ⚠️ 禁止手写临时 Playwright 脚本发布评论\n2. **飞书私聊**：简要摘要 + 禅道 Bug 链接\n\n### 步骤 6：清理\n\n分析完成后必须清理残留进程，避免占用系统资源：\n\n1. **杀掉 login 常驻进程（连带 Chrome）**：`taskkill /PID <login-PID> /F /T`，PID 来自 `zentao-login.js` 输出行 `PID=<value>`。`/T` 会连带终结 Chrome 子进程树\n2. **清理 git worktree**：`git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove .claude/worktrees/bug-{bug_id}/`\n3. **检查残留脚本进程**：`Get-Process node` 检查是否还有 `zentao-*.js` 相关进程，有则 `taskkill /F /PID <pid>` 清理\n4. **确认清理完毕**：最终应只剩 OpenClaw 自身的 node 进程（gateway/worker），不应有其他 `zentao-*.js` 残留\n\n> ⚠️ 注意：不要杀掉 OpenClaw 自身的 node 进程（gateway/worker），只清理 `zentao-*.js` 和 Chrome headless 相关进程。\n\n---\n\n## 并发处理\n\n- **不同模块**：代码目录不同，全部并行处理\n- **同一模块同时分析多个 Bug 时**：用 `git worktree` 为每个 Bug 创建隔离工作区，分析完成后 `git worktree remove` 清理\n\n---\n\n## 禅道交互方式\n\n> ⚠️ 企业版 12.1 不支持 Bearer Token 认证（`POST /api.php/v1/tokens` 不可用），所有读写操作统一走 Playwright。\n\n### 🔴 铁律：单次 Playwright 会话\n\n**一个 Bug 的分析全程只允许启动一次 Playwright 浏览器**。登录后所有操作（读详情、下载附件、写评论）复用同一会话，禁止：\n\n- ❌ 分多个脚本文件各启动一次 Playwright\n- ❌ 中途关闭浏览器再重新登录\n- ❌ 写评论时用新的浏览器实例\n\n### 🔴 铁律：脚本优先，禁止手写临时 Playwright 脚本\n\n**禅道交互只允许使用 `scripts/` 目录下的 5 个固定脚本**：\n\n| 脚本 | 用途 | 关键参数 |\n|------|------|----------|\n| `zentao-login.js` | 登录 | `--port`（默认 9224）|\n| `zentao-get-bug.js` | 获取 Bug 详情 | `--ws`、`--bug-id` |\n| `zentao-download-files.js` | 下载附件 | `--ws`、`--bug-id`、`--dir` |\n| `zentao-build-comment.js` | Markdown → HTML 评论 | `<report.md> [--out <output.html>]` |\n| `zentao-post-comment.js` | 发布评论 | `--ws`、`--bug-id`、`--comment-file=<path>`（推荐）或 `--comment`（原始 HTML）|\n\n**禁止行为**：\n- ❌ 手写临时 `post_comment.js`、`check_bug.js`、`debug_login.js` 等任何 Playwright 脚本\n- ❌ 在 `bugs/{bug_id}/` 目录下创建任何 `.js` 文件\n- ❌ 用 `page.evaluate`、`page.fill`、`page.click` 等 Playwright API 绕过已有脚本\n\n**遇到脚本报错时的正确处理方式**：\n1. 先读脚本源码，理解它依赖的输入（WS endpoint、参数格式等）\n2. 修复输入条件（如重新登录获取有效 WS endpoint），而不是绕过脚本\n3. 如果脚本本身有 bug，修复脚本源码（`scripts/` 目录下），让修复对所有后续分析生效\n\n---\n\n## 边界情况处理\n\n| 场景 | 处理 |\n|------|------|\n| 不含禅道链接 | 「未识别到有效的禅道缺陷链接，请确认消息内容」 |\n| 链接解析失败 | 「无法解析该链接，请确认是否正确转发」 |\n| 禅道 API 请求失败（登录失效/会话过期） | 「无法访问禅道，请检查连接和登录状态」 |\n| 模块分类置信度低 | 飞书通知：Bug 链接+关键信息，请手动确认 |\n| 模块不在负责范围 | 飞书通知：Bug 归属 + 提醒手动流转 |\n| commit id 提取失败 | 飞书通知：日志片段，请手动确认分支 |\n| commit id 不在任何分支 | 飞书通知：commit id，请手动确认 |\n| 附件/日志下载失败 | 降级：仅基于 Bug 描述+历史评论+代码分析，评论注明「未能获取附件」，飞书通知 |\n| 本地代码目录不存在 | 降级：跳过代码分析，仅日志+附件+评论，飞书通知检查配置 |\n| 分析过程中断或超时 | 飞书通知进度和失败原因，不留半截评论 |\n| 用户 5 分钟内未回复重新分析确认 | 默认不重新分析，流程终止 |\n| 分析过程中 git worktree 冲突 | 清理残留 worktree 后重试；仍失败则飞书通知 |\n\n---\n\n## 范围约束\n\n- 不自动填写指派人或流转状态\n- 不自动生成修复代码\n- 不做缺陷趋势统计或报表\n- 当前只服务单一用户\n\nFile v0.0.7:_meta.json\n\n{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"0.0.7\",\n  \"publishedAt\": 1784708466318\n}\n\nFile v0.0.7:references/zentao-api-reference.md\n\n# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |\n\nFile v0.0.7:skill-card.md\n\n## Description: <br>\nAutomates ZenTao defect analysis by parsing Feishu bug links, classifying modules, locating branches and commits, analyzing local code and logs, and optionally publishing reports to ZenTao and Feishu. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[yeah526](https://clawhub.ai/user/yeah526) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and QA engineers use this skill to triage ZenTao defects from Feishu messages, collect bug evidence, locate relevant code revisions, and produce a Markdown analysis report that can be published back to ZenTao and summarized in Feishu. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill uses sensitive ZenTao account access and exposes an authenticated browser WebSocket endpoint during execution. <br>\nMitigation: Install only in a trusted, dedicated workspace, use a least-privilege ZenTao account, avoid plaintext password storage when possible, and do not share the printed WebSocket endpoint. <br>\nRisk: The skill can publish analysis comments to ZenTao automatically. <br>\nMitigation: Set auto_comment to false unless automatic publishing is intended, and review generated reports before enabling comment posting. <br>\nRisk: The skill can change local repository state through checkout, submodule update, worktree creation, and worktree cleanup. <br>\nMitigation: Run it against a dedicated local checkout and review checkout, worktree cleanup, and related repository operations before allowing them. <br>\nRisk: The cleanup workflow can terminate local processes. <br>\nMitigation: Verify process identifiers before allowing process-kill actions, especially on shared workstations. <br>\n\n\n## Reference(s): <br>\n- [ClawHub Skill Page](https://clawhub.ai/yeah526/skills/zentao-bug-analyzer) <br>\n- [ZenTao API Reference](artifact/references/zentao-api-reference.md) <br>\n- [Tooling and Environment](artifact/TOOLS.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Files, Guidance] <br>\n**Output Format:** [Markdown reports, HTML comments, JSON helper-script output, and Feishu summary text.] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May write per-bug report and comment files and may post comments when auto_comment is enabled.] <br>\n\n## Skill Version(s): <br>\n0.0.7 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.0.7:SKILL.checklist.md\n\n# 禅道 Bug 分析执行检查清单\n\n> ⚠️ 硬约束：分析开始前通读本清单，每步必须逐项完成，缺一不可。\n\n## 执行检查清单\n\n- [ ] 步骤 1：消息解析（提取 Bug ID）\n\n- [ ] 步骤 2：重复分析检查\n  - 登录禅道（`zentao-login.js`，获取 WS endpoint，一个 Bug 全程复用）\n  - 获取 Bug 详情 + 检查重复评论（`zentao-get-bug.js`，有我的评论 → 飞书询问是否重新分析）\n\n- [ ] 步骤 3：模块分类（按 config aliases 子串硬匹配，不在范围 → 飞书通知 + 终止）\n\n- [ ] 步骤 4a：下载附件（`zentao-download-files.js`）\n\n- [ ] 步骤 4b：确定 Bug 发生时间（Bug 描述文本 > 附件截图/视频系统时间 > 飞书询问。禁止用文件名/创建时间推断）\n\n- [ ] 步骤 4c-1：按 config commit_extract 规则提取 commit id（搜不到 → 飞书通知 + 终止，禁止近似匹配）\n\n- [ ] 步骤 4c-2：`git branch --contains <commit-id>` 记录分支信息\n\n- [ ] 步骤 4c-3：`git checkout <commit-id>` + `git submodule update --init --recursive`\n\n- [ ] 步骤 4d：AI 深度分析（结合 Bug 详情 + 日志 + 代码 + 历史评论）\n\n- [ ] 🔴 步骤 5：输出报告\n  - ⚠️ 先检查 config 中 `auto_comment` 字段（默认 `true`）\n  - `auto_comment === true` 或未配置：\n    - 步骤 5a：禅道评论（先 `zentao-build-comment.js` 生成 HTML，再 `zentao-post-comment.js --comment-file=<file>` 发布）\n  - `auto_comment === false`：跳过禅道评论，仅生成 `report.md`\n\n- [ ] 步骤 5b：飞书摘要（简要结果 + Bug 链接）\n\n- [ ] 🔴 步骤 6：清理 — 必须完成！\n  1. `taskkill /PID <login-PID> /F /T`（PID 来自 `zentao-login.js` 输出行 `PID=<value>`，`/T` 连带杀 Chrome 子进程树）\n  2. `git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove <path>` 清理\n  3. `Get-Process node` 检查无 `zentao-*.js` 残留进程，有则 `taskkill /F /PID <pid>` 清理\n  4. 确认只剩 OpenClaw 自身 node 进程（gateway/worker）\n\nFile v0.0.7:TOOLS.md\n\n# zentao-bug-analyzer 工具与环境\n\n## 环境依赖\n\n- **Node.js** 18+（脚本运行）\n- **Playwright**：`npm install playwright && npx playwright install chromium`\n- **Git** 2.5+（`git worktree`、`git branch --contains`）\n- 禅道服务器可访问：`http://zentao.gxatek.com:20080`\n\n## 禅道交互 · 统一 Playwright 模式\n\n企业版 12.1 不支持 Bearer Token，所有操作在同一 Playwright 会话中完成。通过 `scripts/` 下的 5 个固定脚本实现，一个脚本一个功能。\n\n### 单会话铁律\n\n一个 Bug 全程只启动一次 Playwright 浏览器。登录后读详情、下载附件、写评论全部复用同一 `browser`/`page`/`context`。\n\n### 脚本\n\n| 脚本 | 功能 | 用法 |\n|------|------|------|\n| `scripts/zentao-login.js` | 登录禅道，输出 WS endpoint | `node scripts/zentao-login.js [--port=9224]` |\n| `scripts/zentao-get-bug.js` | 获取 Bug 详情 JSON | `node scripts/zentao-get-bug.js --ws=<WS> --bug-id=<id>` |\n| `scripts/zentao-download-files.js` | 下载 Bug 附件到本地 | `node scripts/zentao-download-files.js --ws=<WS> --bug-id=<id> --dir=<dir>` |\n| `scripts/zentao-build-comment.js` | Markdown 报告 → HTML 评论 | `node scripts/zentao-build-comment.js <report.md> [--out <output.html>]` |\n| `scripts/zentao-post-comment.js` | 发布 Bug 评论 | `node scripts/zentao-post-comment.js --ws=<WS> --bug-id=<id> --comment-file=<path>` |\n\n### 典型调用流程\n\n```\n1. node scripts/zentao-login.js --port=9224\n   → WS=ws://localhost:9224/devtools/browser/{id}, PID={pid}\n\n2. node scripts/zentao-get-bug.js --ws={WS} --bug-id=1432606\n   → JSON (stdout)\n\n3. node scripts/zentao-download-files.js --ws={WS} --bug-id=1432606 --dir=bugs/1432606\n   → 文件路径列表 (stdout)\n\n4. node scripts/zentao-build-comment.js bugs/1432606/report.md --out bugs/1432606/comment.html\n   → HTML 文件路径 (stdout)\n\n5. node scripts/zentao-post-comment.js --ws={WS} --bug-id=1432606 --comment-file=bugs/1432606/comment.html\n   → OK / FAIL\n```\n\n### login 脚本输出格式\n\n`zentao-login.js` 输出两行 key=value（可直接 shell `eval`）：\n\n```\nWS=ws://localhost:9224/devtools/browser/{browser-id}\nPID={chromium-pid}\n```\n\n其他脚本通过 `--ws` 参数复用会话。\n\n### 参数说明\n\n- `--ws`：login 脚本返回的 WebSocket endpoint\n- `--bug-id`：禅道 Bug ID（数字）\n- `--dir`：附件下载目标目录（自动创建）\n- `--comment-file`：评论文件路径（推荐，由 build-comment.js 生成的 HTML 文件）\n- `--comment`：评论内容（原始 HTML 字符串，脚本自动编码。备选方案，推荐用 `--comment-file`）\n- `--port`：CDP 调试端口（默认 9224）\n- `--zentao-url`：禅道实例地址（默认 `http://zentao.gxatek.com:20080`）\n\n## 本文件定位\n\nTOOLS.md 仅放环境依赖和脚本用法。完整 API 参考见 `references/zentao-api-reference.md`，流程规范见 `SKILL.md`。\n\nArchive v0.0.6: 11 files, 23498 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/zentao-build-comment.js (3874b), scripts/zentao-download-files.js (5995b), scripts/zentao-get-bug.js (4480b), scripts/zentao-login.js (5070b), scripts/zentao-post-comment.js (3579b), skill-card.md (2603b), SKILL.checklist.md (2082b), SKILL.md (16526b), TOOLS.md (2917b), _meta.json (138b)\n\nFile v0.0.6:SKILL.md\n\n---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个脚本操作禅道**，禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不做任何恢复操作。\n5. **分析完输出报告**：步骤 4d 产出分析报告后，根据 `auto_comment` 配置决定是否评论禅道：\n   - `auto_comment === true`：运行 `zentao-post-comment.js` 评论 + 飞书摘要\n   - `auto_comment === false`：仅飞书摘要，不评论禅道\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"auto_comment\": true,\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}\n```\n\n字段说明：\n- `name`：模块名称\n- `aliases`：模块别名列表（字符串数组），用于精确匹配。**匹配规则**：将 Bug 的 title、module.name、product.name 与所有模块的 name + aliases 做**子串匹配**（忽略大小写），任一命中即判定为该模块。此规则为硬规则，优先于 AI 主观判断\n- `code_dir`：模块本地代码仓库绝对路径\n- `commit_extract`：自然语言，告诉 AI 如何从日志提取 commit id\n- `analyzer`：`\"default\"` | `\"skill:技能名\"`。default 走通用 AI 分析流程；skill:xxx 委派给对应 Skill\n- `analyze_hint`：模块专属分析提示词（可选），无论哪种分析器都会传给分析器\n- `auto_comment`：布尔值，控制分析完成后是否自动将报告评论到禅道 Bug 下。`true` = 自动评论（默认行为）；`false` = 仅生成报告 + 飞书通知，不评论禅道\n\n### 首次配置引导\n\n配置文件不存在时启动对话式引导。流程：\n\n1. 「请提供禅道的登录账号和密码（用于 Playwright 登录禅道。密码会存储在本地配置文件中，不会泄露）」\n2. 「你负责哪些模块？请列出模块名称（用逗号分隔，如：车机设置, 蓝牙模块, 语音助手）」\n3. 对每个模块依次询问：\n   - 「对于\"{模块名}\"模块，有哪些别名/关键词可以用来识别？（用逗号分隔，如：桌面卡片, systemui, 设置）」\n   - 「对于\"{模块名}\"模块，本地代码目录路径是什么？（请使用绝对路径）」\n   - 「对于\"{模块名}\"模块，日志中如何提取 commit id？请用自然语言描述提取规则」\n   - 「对于\"{模块名}\"模块，是否需要使用专用分析 Skill？（目前可用的 Skill：[列出]。输入 Skill 名或留空走默认分析）」\n   - 「对于\"{模块名}\"模块，有什么分析提示或重点关注方向？（可选，留空则用默认分析策略）」\n4. 「分析完成后，是否需要自动将分析报告评论到禅道 Bug 下？（回复\"是\"=自动评论，\"否\"=仅飞书通知，不评论禅道）」\n5. 「配置完成！请确认你已创建邮件收信规则：当发件人为 `zentao@syncore.space` 时，自动将邮件转发/分享到本 Bot 的对话中。」\n\n---\n\n## 分析流水线\n\n### 步骤 1：消息解析\n\n从消息内容提取禅道 Bug 链接，正则：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 步骤 2：重复分析检查\n\n> ⚠️ 此步骤是强制检查点，无论通过哪种触发方式（邮件转发或自然语言）进入分析流水线，必须先走步骤 2。已评论过的 Bug 绝对不允许直接进入后续步骤。\n\n1. 运行 `scripts/zentao-get-bug.js` 获取 Bug 详情（含历史评论，后续步骤复用）\n2. 检查历史评论中是否已有 `zentao.account` 配置账号的评论\n\n**已有我的评论**：飞书私聊询问「该 Bug 你已评论过，是否需要重新分析？（回复\"是\"或\"分析\"继续，回复\"否\"或\"取消\"跳过）」\n- 确认「是」→ 继续步骤 3\n- 确认「否」或 5 分钟内未回复 → 流程终止\n\n**没有我的评论**：直接继续步骤 3。\n\n### 步骤 3：模块分类\n\n**匹配规则（优先级从高到低）**：\n\n1. **硬别名匹配（优先）**：遍历配置中每个 module 的 `aliases` 数组，将每个别名与 Bug 的 `title`、`module.name`、`product.name` 做**子串匹配**（忽略大小写）。只要任一副本字段包含任一个别名（或 `name` 本身），即判定命中该模块。\n   - 例如：Bug标题含\"桌面卡片\"，配置别名中有\"桌面卡片\" → 直接命中\n   - ⚠️ 此规则是机械规则，不依赖 AI 判断，直接执行\n2. **AI 语义判断（兜底）**：硬别名未命中时，AI 综合判断 Bug 归属模块，对照配置文件 `modules` 列表\n\n**结果处理**：\n- **在范围**：继续步骤 4\n- **不在范围**：飞书私聊通知（Bug 标题、链接、AI 判断的模块归属），提醒模块确认和手动流转。流程结束\n- **置信度低**：飞书私聊通知（Bug 链接 + 关键信息），告知无法确定模块，请手动确认。流程结束\n\n### 步骤 4：深度分析\n\n#### 4a. 下载附件和日志\n运行 `scripts/zentao-download-files.js` 下载 Bug 所有附件到 `bugs/{bug_id}/`。（script 自动处理大文件分块传输，支持 160MB+ 附件）\n\n> ⚠️ 步骤 4a 完成后必须先执行 4b（确定 Bug 发生时间），再进入 4c。\n\n#### 4b. 确定 Bug 发生时间\n\n> ⚠️ 硬约束：Bug 发生时间必须从可靠来源直接获取，禁止猜测或间接推断。\n\n**获取优先级**：\n1. **Bug 描述文本**中明确写出的时间（如「17:33 复现」「12:05 发现」）\n2. **附件视频/截图**中可见的系统时间（状态栏、水印等），需打开查看\n3. **飞书询问用户**：以上均不可用时，私聊询问「该 Bug 发生的精确时间是什么？」\n\n**禁止行为**：\n- ❌ 用附件文件名中的时间戳猜测\n- ❌ 用 Bug 创建时间、最后修改时间间接推断\n- ❌ 用聊天消息转发时间、邮件接收时间推断\n- ❌ 任何不在上述优先级列表内的间接推演\n\n**时间用于**：\n- 日志分析：定位 Bug 发生时刻前后 ±5 分钟的日志片段\n- Git blame：确定相关代码变更时间线\n- 匹配历史评论中提到的复现时间\n\n#### 4c. 分支定位\n1. 解压并读取日志文件：\n   - Android logcat 的 `.gz` 文件**必须使用 Node.js zlib 解压**，禁止使用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或类似 .NET 解压工具\n   - ⚠️ .NET GZipStream 对 Android logd 生成的某些 gzip 流存在兼容性 bug（提前终止解压，实际 30MB 仅解出 ~65KB），会导致日志内容严重缺失\n   - 推荐命令：`node -e \"const zlib=require('zlib');const fs=require('fs');const buf=fs.readFileSync('<log.gz>');zlib.gunzip(buf,(e,r)=>{if(e){console.error(e);return}const s=r.toString('utf8');/* 搜索/处理 s */})\"`\n2. 按配置中 `commit_extract` 从日志提取 commit id\n3. `cd {code_dir}` → `git branch --contains <commit-id>` 确认 commit 在哪些分支上。结果写入分析报告的「分支信息」字段（格式：`分支名 | commit-id`）\n4. 同模块已有其他分析任务时，用 `git worktree add .claude/worktrees/bug-{bug_id}/ <commit-id>` 创建隔离工作区\n5. `git checkout <commit-id>`（进入 detached HEAD 是正常行为，分析完成后保持不动即可）+ `git submodule update --init --recursive`\n\n**commit id 提取失败**：飞书私聊通知（附带日志片段），流程终止。\n\n> ⚠️ 硬约束：只使用配置中 commit_extract 指定的提取规则，禁止 AI 自行更换搜索关键词（如换 TAG、换正则）。搜不到就是搜不到，不允许\"近似匹配\"或\"换成类似的 TAG 试试\"。\n> Self-Check：若在分析过程中进行了 commit_extract 规则以外的额外搜索，应立即停止、丢弃中间产物，回到步骤 4c 标准路径并报告提取失败。\n\n**commit id 不在任何分支**：飞书私聊通知（附带 commit id），流程终止\n\n> ⚠️ 硬约束：`git checkout <commit-id>` 后必须执行 `git submodule update --init --recursive`，确保所有 submodule 都已 checkout 到对应版本。未 checkout submodule 可能导致分析时缺少依赖代码、漏掉跨仓库 API 不一致问题。\n\n#### 4d. AI 综合深度分析\n\n历史评论已在步骤 2 获取，此处直接使用。\n\n根据 `analyzer` 字段：\n- `\"default\"`：AI 综合 Bug 详情 + 附件/日志 + 历史评论 + 本地代码分析\n- `\"skill:xxx\"`：委派给指定 Skill，传入分析上下文\n\n无论哪种方式，`analyze_hint` 都作为上下文传入。\n\n输出格式（Markdown，AI 直接产出此结构）：\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**：\n  ```lang\n  // 关键代码\n  ```\n- **判断依据**：（结合日志/历史评论/代码逻辑的推理过程）\n\n### 修复建议\n1. 具体修复方向（可操作步骤，非抽象建议）\n\n### 风险评估\n- **影响范围**：（哪些功能/模块受影响）\n- **严重程度**：（低/中/高/严重 + 理由）\n\n### 步骤 5：结果输出\n\n> ⚠️ **auto_comment 开关**：步骤 5 开始前，检查配置文件中 `auto_comment` 字段（默认为 `true`）。\n> - `auto_comment === false`：跳过禅道评论（步骤 5.1），仅生成 `report.md` + 执行飞书私聊通知（步骤 5.2）\n> - `auto_comment === true` 或未配置：执行完整双通道（禅道评论 + 飞书通知）\n\n1. **禅道评论**（仅在 `auto_comment !== false` 时执行）：\n   a. 将分析报告写入 `bugs/{bug_id}/report.md`（按步骤 4d 输出格式）\n   b. 运行 `node scripts/zentao-build-comment.js bugs/{bug_id}/report.md --out bugs/{bug_id}/comment.html` 生成 HTML\n   c. 运行 `node scripts/zentao-post-comment.js --ws=<wsEndpoint> --bug-id=<id> --comment-file=bugs/{bug_id}/comment.html` 发布（**必须用 `--comment-file`，禁止用 `--comment` 传 HTML 内容**）\n   d. ⚠️ 禁止手写临时 Playwright 脚本发布评论\n2. **飞书私聊**：简要摘要 + 禅道 Bug 链接\n\n### 步骤 6：清理\n\n分析完成后必须清理残留进程，避免占用系统资源：\n\n1. **杀掉 login 常驻进程（连带 Chrome）**：`taskkill /PID <login-PID> /F /T`，PID 来自 `zentao-login.js` 输出行 `PID=<value>`。`/T` 会连带终结 Chrome 子进程树\n2. **清理 git worktree**：`git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove .claude/worktrees/bug-{bug_id}/`\n3. **检查残留脚本进程**：`Get-Process node` 检查是否还有 `zentao-*.js` 相关进程，有则 `taskkill /F /PID <pid>` 清理\n4. **确认清理完毕**：最终应只剩 OpenClaw 自身的 node 进程（gateway/worker），不应有其他 `zentao-*.js` 残留\n\n> ⚠️ 注意：不要杀掉 OpenClaw 自身的 node 进程（gateway/worker），只清理 `zentao-*.js` 和 Chrome headless 相关进程。\n\n---\n\n## 并发处理\n\n- **不同模块**：代码目录不同，全部并行处理\n- **同一模块同时分析多个 Bug 时**：用 `git worktree` 为每个 Bug 创建隔离工作区，分析完成后 `git worktree remove` 清理\n\n---\n\n## 禅道交互方式\n\n> ⚠️ 企业版 12.1 不支持 Bearer Token 认证（`POST /api.php/v1/tokens` 不可用），所有读写操作统一走 Playwright。\n\n### 🔴 铁律：单次 Playwright 会话\n\n**一个 Bug 的分析全程只允许启动一次 Playwright 浏览器**。登录后所有操作（读详情、下载附件、写评论）复用同一会话，禁止：\n\n- ❌ 分多个脚本文件各启动一次 Playwright\n- ❌ 中途关闭浏览器再重新登录\n- ❌ 写评论时用新的浏览器实例\n\n### 🔴 铁律：脚本优先，禁止手写临时 Playwright 脚本\n\n**禅道交互只允许使用 `scripts/` 目录下的 5 个固定脚本**：\n\n| 脚本 | 用途 | 关键参数 |\n|------|------|----------|\n| `zentao-login.js` | 登录 | `--port`（默认 9224）|\n| `zentao-get-bug.js` | 获取 Bug 详情 | `--ws`、`--bug-id` |\n| `zentao-download-files.js` | 下载附件 | `--ws`、`--bug-id`、`--dir` |\n| `zentao-build-comment.js` | Markdown → HTML 评论 | `<report.md> [--out <output.html>]` |\n| `zentao-post-comment.js` | 发布评论 | `--ws`、`--bug-id`、`--comment-file=<path>`（推荐）或 `--comment`（原始 HTML）|\n\n**禁止行为**：\n- ❌ 手写临时 `post_comment.js`、`check_bug.js`、`debug_login.js` 等任何 Playwright 脚本\n- ❌ 在 `bugs/{bug_id}/` 目录下创建任何 `.js` 文件\n- ❌ 用 `page.evaluate`、`page.fill`、`page.click` 等 Playwright API 绕过已有脚本\n\n**遇到脚本报错时的正确处理方式**：\n1. 先读脚本源码，理解它依赖的输入（WS endpoint、参数格式等）\n2. 修复输入条件（如重新登录获取有效 WS endpoint），而不是绕过脚本\n3. 如果脚本本身有 bug，修复脚本源码（`scripts/` 目录下），让修复对所有后续分析生效\n\n---\n\n## 边界情况处理\n\n| 场景 | 处理 |\n|------|------|\n| 不含禅道链接 | 「未识别到有效的禅道缺陷链接，请确认消息内容」 |\n| 链接解析失败 | 「无法解析该链接，请确认是否正确转发」 |\n| 禅道 API 请求失败（登录失效/会话过期） | 「无法访问禅道，请检查连接和登录状态」 |\n| 模块分类置信度低 | 飞书通知：Bug 链接+关键信息，请手动确认 |\n| 模块不在负责范围 | 飞书通知：Bug 归属 + 提醒手动流转 |\n| commit id 提取失败 | 飞书通知：日志片段，请手动确认分支 |\n| commit id 不在任何分支 | 飞书通知：commit id，请手动确认 |\n| 附件/日志下载失败 | 降级：仅基于 Bug 描述+历史评论+代码分析，评论注明「未能获取附件」，飞书通知 |\n| 本地代码目录不存在 | 降级：跳过代码分析，仅日志+附件+评论，飞书通知检查配置 |\n| 分析过程中断或超时 | 飞书通知进度和失败原因，不留半截评论 |\n| 用户 5 分钟内未回复重新分析确认 | 默认不重新分析，流程终止 |\n| 分析过程中 git worktree 冲突 | 清理残留 worktree 后重试；仍失败则飞书通知 |\n\n---\n\n## 范围约束\n\n- 不自动填写指派人或流转状态\n- 不自动生成修复代码\n- 不做缺陷趋势统计或报表\n- 当前只服务单一用户\n\nFile v0.0.6:_meta.json\n\n{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"0.0.6\",\n  \"publishedAt\": 1784707755411\n}\n\nFile v0.0.6:references/zentao-api-reference.md\n\n# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |\n\nFile v0.0.6:skill-card.md\n\n## Description: <br>\nAnalyzes ZenTao bug reports from Feishu-triggered links by collecting bug details, attachments, logs, and local code context, then producing a root-cause report with optional ZenTao comments and Feishu notification. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[yeah526](https://clawhub.ai/user/yeah526) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and QA engineers use this skill to automate ZenTao defect triage: parse incoming bug links, classify modules, collect logs and attachments, locate relevant branches or commits, and prepare a structured analysis report. It can optionally publish the analysis back to ZenTao and send a Feishu summary. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill uses ZenTao account access and may rely on locally stored credentials. <br>\nMitigation: Use a least-privilege ZenTao account, protect the local configuration file, and avoid storing plaintext passwords where possible. <br>\nRisk: The default workflow can write analysis comments back to production ZenTao bug records. <br>\nMitigation: Set auto_comment to false until the report has been reviewed and automatic writeback is explicitly desired. <br>\nRisk: The workflow downloads bug attachments and logs and may change local repository checkouts during analysis. <br>\nMitigation: Run the skill in an isolated workspace and confirm local work is committed or backed up before allowing checkout or worktree operations. <br>\n\n\n## Reference(s): <br>\n- [ClawHub Skill Page](https://clawhub.ai/yeah526/skills/zentao-bug-analyzer) <br>\n- [ZenTao API Reference](references/zentao-api-reference.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown analysis report with optional generated HTML comment, Feishu summary text, and command invocations.] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May write bug analysis files under bugs/{bug_id}/, download attachments and logs, use a Playwright browser session, and optionally post comments to ZenTao when auto_comment is enabled.] <br>\n\n## Skill Version(s): <br>\n0.0.6 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.0.6:SKILL.checklist.md\n\n# 禅道 Bug 分析执行检查清单\n\n> ⚠️ 硬约束：分析开始前通读本清单，每步必须逐项完成，缺一不可。\n\n## 执行检查清单\n\n- [ ] 步骤 1：消息解析（提取 Bug ID）\n\n- [ ] 步骤 2：重复分析检查\n  - 登录禅道（`zentao-login.js`，获取 WS endpoint，一个 Bug 全程复用）\n  - 获取 Bug 详情 + 检查重复评论（`zentao-get-bug.js`，有我的评论 → 飞书询问是否重新分析）\n\n- [ ] 步骤 3：模块分类（按 config aliases 子串硬匹配，不在范围 → 飞书通知 + 终止）\n\n- [ ] 步骤 4a：下载附件（`zentao-download-files.js`）\n\n- [ ] 步骤 4b：确定 Bug 发生时间（Bug 描述文本 > 附件截图/视频系统时间 > 飞书询问。禁止用文件名/创建时间推断）\n\n- [ ] 步骤 4c-1：按 config commit_extract 规则提取 commit id（搜不到 → 飞书通知 + 终止，禁止近似匹配）\n\n- [ ] 步骤 4c-2：`git branch --contains <commit-id>` 记录分支信息\n\n- [ ] 步骤 4c-3：`git checkout <commit-id>` + `git submodule update --init --recursive`\n\n- [ ] 步骤 4d：AI 深度分析（结合 Bug 详情 + 日志 + 代码 + 历史评论）\n\n- [ ] 🔴 步骤 5：输出报告\n  - ⚠️ 先检查 config 中 `auto_comment` 字段（默认 `true`）\n  - `auto_comment === true` 或未配置：\n    - 步骤 5a：禅道评论（先 `zentao-build-comment.js` 生成 HTML，再 `zentao-post-comment.js --comment-file=<file>` 发布）\n  - `auto_comment === false`：跳过禅道评论，仅生成 `report.md`\n\n- [ ] 步骤 5b：飞书摘要（简要结果 + Bug 链接）\n\n- [ ] 🔴 步骤 6：清理 — 必须完成！\n  1. `taskkill /PID <login-PID> /F /T`（PID 来自 `zentao-login.js` 输出行 `PID=<value>`，`/T` 连带杀 Chrome 子进程树）\n  2. `git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove <path>` 清理\n  3. `Get-Process node` 检查无 `zentao-*.js` 残留进程，有则 `taskkill /F /PID <pid>` 清理\n  4. 确认只剩 OpenClaw 自身 node 进程（gateway/worker）\n\nFile v0.0.6:TOOLS.md\n\n# zentao-bug-analyzer 工具与环境\n\n## 环境依赖\n\n- **Node.js** 18+（脚本运行）\n- **Playwright**：`npm install playwright && npx playwright install chromium`\n- **Git** 2.5+（`git worktree`、`git branch --contains`）\n- 禅道服务器可访问：`http://zentao.gxatek.com:20080`\n\n## 禅道交互 · 统一 Playwright 模式\n\n企业版 12.1 不支持 Bearer Token，所有操作在同一 Playwright 会话中完成。通过 `scripts/` 下的 5 个固定脚本实现，一个脚本一个功能。\n\n### 单会话铁律\n\n一个 Bug 全程只启动一次 Playwright 浏览器。登录后读详情、下载附件、写评论全部复用同一 `browser`/`page`/`context`。\n\n### 脚本\n\n| 脚本 | 功能 | 用法 |\n|------|------|------|\n| `scripts/zentao-login.js` | 登录禅道，输出 WS endpoint | `node scripts/zentao-login.js [--port=9224]` |\n| `scripts/zentao-get-bug.js` | 获取 Bug 详情 JSON | `node scripts/zentao-get-bug.js --ws=<WS> --bug-id=<id>` |\n| `scripts/zentao-download-files.js` | 下载 Bug 附件到本地 | `node scripts/zentao-download-files.js --ws=<WS> --bug-id=<id> --dir=<dir>` |\n| `scripts/zentao-build-comment.js` | Markdown 报告 → HTML 评论 | `node scripts/zentao-build-comment.js <report.md> [--out <output.html>]` |\n| `scripts/zentao-post-comment.js` | 发布 Bug 评论 | `node scripts/zentao-post-comment.js --ws=<WS> --bug-id=<id> --comment-file=<path>` |\n\n### 典型调用流程\n\n```\n1. node scripts/zentao-login.js --port=9224\n   → WS=ws://localhost:9224/devtools/browser/{id}, PID={pid}\n\n2. node scripts/zentao-get-bug.js --ws={WS} --bug-id=1432606\n   → JSON (stdout)\n\n3. node scripts/zentao-download-files.js --ws={WS} --bug-id=1432606 --dir=bugs/1432606\n   → 文件路径列表 (stdout)\n\n4. node scripts/zentao-build-comment.js bugs/1432606/report.md --out bugs/1432606/comment.html\n   → HTML 文件路径 (stdout)\n\n5. node scripts/zentao-post-comment.js --ws={WS} --bug-id=1432606 --comment-file=bugs/1432606/comment.html\n   → OK / FAIL\n```\n\n### login 脚本输出格式\n\n`zentao-login.js` 输出两行 key=value（可直接 shell `eval`）：\n\n```\nWS=ws://localhost:9224/devtools/browser/{browser-id}\nPID={chromium-pid}\n```\n\n其他脚本通过 `--ws` 参数复用会话。\n\n### 参数说明\n\n- `--ws`：login 脚本返回的 WebSocket endpoint\n- `--bug-id`：禅道 Bug ID（数字）\n- `--dir`：附件下载目标目录（自动创建）\n- `--comment-file`：评论文件路径（推荐，由 build-comment.js 生成的 HTML 文件）\n- `--comment`：评论内容（原始 HTML 字符串，脚本自动编码。备选方案，推荐用 `--comment-file`）\n- `--port`：CDP 调试端口（默认 9224）\n- `--zentao-url`：禅道实例地址（默认 `http://zentao.gxatek.com:20080`）\n\n## 本文件定位\n\nTOOLS.md 仅放环境依赖和脚本用法。完整 API 参考见 `references/zentao-api-reference.md`，流程规范见 `SKILL.md`。\n\nArchive v0.0.5: 11 files, 23563 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/zentao-build-comment.js (3874b), scripts/zentao-download-files.js (5995b), scripts/zentao-get-bug.js (4480b), scripts/zentao-login.js (5070b), scripts/zentao-post-comment.js (3579b), skill-card.md (2782b), SKILL.checklist.md (2082b), SKILL.md (16526b), TOOLS.md (2917b), _meta.json (138b)\n\nFile v0.0.5:SKILL.md\n\n---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个脚本操作禅道**，禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不做任何恢复操作。\n5. **分析完输出报告**：步骤 4d 产出分析报告后，根据 `auto_comment` 配置决定是否评论禅道：\n   - `auto_comment === true`：运行 `zentao-post-comment.js` 评论 + 飞书摘要\n   - `auto_comment === false`：仅飞书摘要，不评论禅道\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"auto_comment\": true,\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}\n```\n\n字段说明：\n- `name`：模块名称\n- `aliases`：模块别名列表（字符串数组），用于精确匹配。**匹配规则**：将 Bug 的 title、module.name、product.name 与所有模块的 name + aliases 做**子串匹配**（忽略大小写），任一命中即判定为该模块。此规则为硬规则，优先于 AI 主观判断\n- `code_dir`：模块本地代码仓库绝对路径\n- `commit_extract`：自然语言，告诉 AI 如何从日志提取 commit id\n- `analyzer`：`\"default\"` | `\"skill:技能名\"`。default 走通用 AI 分析流程；skill:xxx 委派给对应 Skill\n- `analyze_hint`：模块专属分析提示词（可选），无论哪种分析器都会传给分析器\n- `auto_comment`：布尔值，控制分析完成后是否自动将报告评论到禅道 Bug 下。`true` = 自动评论（默认行为）；`false` = 仅生成报告 + 飞书通知，不评论禅道\n\n### 首次配置引导\n\n配置文件不存在时启动对话式引导。流程：\n\n1. 「请提供禅道的登录账号和密码（用于 Playwright 登录禅道。密码会存储在本地配置文件中，不会泄露）」\n2. 「你负责哪些模块？请列出模块名称（用逗号分隔，如：车机设置, 蓝牙模块, 语音助手）」\n3. 对每个模块依次询问：\n   - 「对于\"{模块名}\"模块，有哪些别名/关键词可以用来识别？（用逗号分隔，如：桌面卡片, systemui, 设置）」\n   - 「对于\"{模块名}\"模块，本地代码目录路径是什么？（请使用绝对路径）」\n   - 「对于\"{模块名}\"模块，日志中如何提取 commit id？请用自然语言描述提取规则」\n   - 「对于\"{模块名}\"模块，是否需要使用专用分析 Skill？（目前可用的 Skill：[列出]。输入 Skill 名或留空走默认分析）」\n   - 「对于\"{模块名}\"模块，有什么分析提示或重点关注方向？（可选，留空则用默认分析策略）」\n4. 「分析完成后，是否需要自动将分析报告评论到禅道 Bug 下？（回复\"是\"=自动评论，\"否\"=仅飞书通知，不评论禅道）」\n5. 「配置完成！请确认你已创建邮件收信规则：当发件人为 `zentao@syncore.space` 时，自动将邮件转发/分享到本 Bot 的对话中。」\n\n---\n\n## 分析流水线\n\n### 步骤 1：消息解析\n\n从消息内容提取禅道 Bug 链接，正则：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 步骤 2：重复分析检查\n\n> ⚠️ 此步骤是强制检查点，无论通过哪种触发方式（邮件转发或自然语言）进入分析流水线，必须先走步骤 2。已评论过的 Bug 绝对不允许直接进入后续步骤。\n\n1. 运行 `scripts/zentao-get-bug.js` 获取 Bug 详情（含历史评论，后续步骤复用）\n2. 检查历史评论中是否已有 `zentao.account` 配置账号的评论\n\n**已有我的评论**：飞书私聊询问「该 Bug 你已评论过，是否需要重新分析？（回复\"是\"或\"分析\"继续，回复\"否\"或\"取消\"跳过）」\n- 确认「是」→ 继续步骤 3\n- 确认「否」或 5 分钟内未回复 → 流程终止\n\n**没有我的评论**：直接继续步骤 3。\n\n### 步骤 3：模块分类\n\n**匹配规则（优先级从高到低）**：\n\n1. **硬别名匹配（优先）**：遍历配置中每个 module 的 `aliases` 数组，将每个别名与 Bug 的 `title`、`module.name`、`product.name` 做**子串匹配**（忽略大小写）。只要任一副本字段包含任一个别名（或 `name` 本身），即判定命中该模块。\n   - 例如：Bug标题含\"桌面卡片\"，配置别名中有\"桌面卡片\" → 直接命中\n   - ⚠️ 此规则是机械规则，不依赖 AI 判断，直接执行\n2. **AI 语义判断（兜底）**：硬别名未命中时，AI 综合判断 Bug 归属模块，对照配置文件 `modules` 列表\n\n**结果处理**：\n- **在范围**：继续步骤 4\n- **不在范围**：飞书私聊通知（Bug 标题、链接、AI 判断的模块归属），提醒模块确认和手动流转。流程结束\n- **置信度低**：飞书私聊通知（Bug 链接 + 关键信息），告知无法确定模块，请手动确认。流程结束\n\n### 步骤 4：深度分析\n\n#### 4a. 下载附件和日志\n运行 `scripts/zentao-download-files.js` 下载 Bug 所有附件到 `bugs/{bug_id}/`。（script 自动处理大文件分块传输，支持 160MB+ 附件）\n\n> ⚠️ 步骤 4a 完成后必须先执行 4b（确定 Bug 发生时间），再进入 4c。\n\n#### 4b. 确定 Bug 发生时间\n\n> ⚠️ 硬约束：Bug 发生时间必须从可靠来源直接获取，禁止猜测或间接推断。\n\n**获取优先级**：\n1. **Bug 描述文本**中明确写出的时间（如「17:33 复现」「12:05 发现」）\n2. **附件视频/截图**中可见的系统时间（状态栏、水印等），需打开查看\n3. **飞书询问用户**：以上均不可用时，私聊询问「该 Bug 发生的精确时间是什么？」\n\n**禁止行为**：\n- ❌ 用附件文件名中的时间戳猜测\n- ❌ 用 Bug 创建时间、最后修改时间间接推断\n- ❌ 用聊天消息转发时间、邮件接收时间推断\n- ❌ 任何不在上述优先级列表内的间接推演\n\n**时间用于**：\n- 日志分析：定位 Bug 发生时刻前后 ±5 分钟的日志片段\n- Git blame：确定相关代码变更时间线\n- 匹配历史评论中提到的复现时间\n\n#### 4c. 分支定位\n1. 解压并读取日志文件：\n   - Android logcat 的 `.gz` 文件**必须使用 Node.js zlib 解压**，禁止使用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或类似 .NET 解压工具\n   - ⚠️ .NET GZipStream 对 Android logd 生成的某些 gzip 流存在兼容性 bug（提前终止解压，实际 30MB 仅解出 ~65KB），会导致日志内容严重缺失\n   - 推荐命令：`node -e \"const zlib=require('zlib');const fs=require('fs');const buf=fs.readFileSync('<log.gz>');zlib.gunzip(buf,(e,r)=>{if(e){console.error(e);return}const s=r.toString('utf8');/* 搜索/处理 s */})\"`\n2. 按配置中 `commit_extract` 从日志提取 commit id\n3. `cd {code_dir}` → `git branch --contains <commit-id>` 确认 commit 在哪些分支上。结果写入分析报告的「分支信息」字段（格式：`分支名 | commit-id`）\n4. 同模块已有其他分析任务时，用 `git worktree add .claude/worktrees/bug-{bug_id}/ <commit-id>` 创建隔离工作区\n5. `git checkout <commit-id>`（进入 detached HEAD 是正常行为，分析完成后保持不动即可）+ `git submodule update --init --recursive`\n\n**commit id 提取失败**：飞书私聊通知（附带日志片段），流程终止。\n\n> ⚠️ 硬约束：只使用配置中 commit_extract 指定的提取规则，禁止 AI 自行更换搜索关键词（如换 TAG、换正则）。搜不到就是搜不到，不允许\"近似匹配\"或\"换成类似的 TAG 试试\"。\n> Self-Check：若在分析过程中进行了 commit_extract 规则以外的额外搜索，应立即停止、丢弃中间产物，回到步骤 4c 标准路径并报告提取失败。\n\n**commit id 不在任何分支**：飞书私聊通知（附带 commit id），流程终止\n\n> ⚠️ 硬约束：`git checkout <commit-id>` 后必须执行 `git submodule update --init --recursive`，确保所有 submodule 都已 checkout 到对应版本。未 checkout submodule 可能导致分析时缺少依赖代码、漏掉跨仓库 API 不一致问题。\n\n#### 4d. AI 综合深度分析\n\n历史评论已在步骤 2 获取，此处直接使用。\n\n根据 `analyzer` 字段：\n- `\"default\"`：AI 综合 Bug 详情 + 附件/日志 + 历史评论 + 本地代码分析\n- `\"skill:xxx\"`：委派给指定 Skill，传入分析上下文\n\n无论哪种方式，`analyze_hint` 都作为上下文传入。\n\n输出格式（Markdown，AI 直接产出此结构）：\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**：\n  ```lang\n  // 关键代码\n  ```\n- **判断依据**：（结合日志/历史评论/代码逻辑的推理过程）\n\n### 修复建议\n1. 具体修复方向（可操作步骤，非抽象建议）\n\n### 风险评估\n- **影响范围**：（哪些功能/模块受影响）\n- **严重程度**：（低/中/高/严重 + 理由）\n\n### 步骤 5：结果输出\n\n> ⚠️ **auto_comment 开关**：步骤 5 开始前，检查配置文件中 `auto_comment` 字段（默认为 `true`）。\n> - `auto_comment === false`：跳过禅道评论（步骤 5.1），仅生成 `report.md` + 执行飞书私聊通知（步骤 5.2）\n> - `auto_comment === true` 或未配置：执行完整双通道（禅道评论 + 飞书通知）\n\n1. **禅道评论**（仅在 `auto_comment !== false` 时执行）：\n   a. 将分析报告写入 `bugs/{bug_id}/report.md`（按步骤 4d 输出格式）\n   b. 运行 `node scripts/zentao-build-comment.js bugs/{bug_id}/report.md --out bugs/{bug_id}/comment.html` 生成 HTML\n   c. 运行 `node scripts/zentao-post-comment.js --ws=<wsEndpoint> --bug-id=<id> --comment-file=bugs/{bug_id}/comment.html` 发布（**必须用 `--comment-file`，禁止用 `--comment` 传 HTML 内容**）\n   d. ⚠️ 禁止手写临时 Playwright 脚本发布评论\n2. **飞书私聊**：简要摘要 + 禅道 Bug 链接\n\n### 步骤 6：清理\n\n分析完成后必须清理残留进程，避免占用系统资源：\n\n1. **杀掉 login 常驻进程（连带 Chrome）**：`taskkill /PID <login-PID> /F /T`，PID 来自 `zentao-login.js` 输出行 `PID=<value>`。`/T` 会连带终结 Chrome 子进程树\n2. **清理 git worktree**：`git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove .claude/worktrees/bug-{bug_id}/`\n3. **检查残留脚本进程**：`Get-Process node` 检查是否还有 `zentao-*.js` 相关进程，有则 `taskkill /F /PID <pid>` 清理\n4. **确认清理完毕**：最终应只剩 OpenClaw 自身的 node 进程（gateway/worker），不应有其他 `zentao-*.js` 残留\n\n> ⚠️ 注意：不要杀掉 OpenClaw 自身的 node 进程（gateway/worker），只清理 `zentao-*.js` 和 Chrome headless 相关进程。\n\n---\n\n## 并发处理\n\n- **不同模块**：代码目录不同，全部并行处理\n- **同一模块同时分析多个 Bug 时**：用 `git worktree` 为每个 Bug 创建隔离工作区，分析完成后 `git worktree remove` 清理\n\n---\n\n## 禅道交互方式\n\n> ⚠️ 企业版 12.1 不支持 Bearer Token 认证（`POST /api.php/v1/tokens` 不可用），所有读写操作统一走 Playwright。\n\n### 🔴 铁律：单次 Playwright 会话\n\n**一个 Bug 的分析全程只允许启动一次 Playwright 浏览器**。登录后所有操作（读详情、下载附件、写评论）复用同一会话，禁止：\n\n- ❌ 分多个脚本文件各启动一次 Playwright\n- ❌ 中途关闭浏览器再重新登录\n- ❌ 写评论时用新的浏览器实例\n\n### 🔴 铁律：脚本优先，禁止手写临时 Playwright 脚本\n\n**禅道交互只允许使用 `scripts/` 目录下的 5 个固定脚本**：\n\n| 脚本 | 用途 | 关键参数 |\n|------|------|----------|\n| `zentao-login.js` | 登录 | `--port`（默认 9224）|\n| `zentao-get-bug.js` | 获取 Bug 详情 | `--ws`、`--bug-id` |\n| `zentao-download-files.js` | 下载附件 | `--ws`、`--bug-id`、`--dir` |\n| `zentao-build-comment.js` | Markdown → HTML 评论 | `<report.md> [--out <output.html>]` |\n| `zentao-post-comment.js` | 发布评论 | `--ws`、`--bug-id`、`--comment-file=<path>`（推荐）或 `--comment`（原始 HTML）|\n\n**禁止行为**：\n- ❌ 手写临时 `post_comment.js`、`check_bug.js`、`debug_login.js` 等任何 Playwright 脚本\n- ❌ 在 `bugs/{bug_id}/` 目录下创建任何 `.js` 文件\n- ❌ 用 `page.evaluate`、`page.fill`、`page.click` 等 Playwright API 绕过已有脚本\n\n**遇到脚本报错时的正确处理方式**：\n1. 先读脚本源码，理解它依赖的输入（WS endpoint、参数格式等）\n2. 修复输入条件（如重新登录获取有效 WS endpoint），而不是绕过脚本\n3. 如果脚本本身有 bug，修复脚本源码（`scripts/` 目录下），让修复对所有后续分析生效\n\n---\n\n## 边界情况处理\n\n| 场景 | 处理 |\n|------|------|\n| 不含禅道链接 | 「未识别到有效的禅道缺陷链接，请确认消息内容」 |\n| 链接解析失败 | 「无法解析该链接，请确认是否正确转发」 |\n| 禅道 API 请求失败（登录失效/会话过期） | 「无法访问禅道，请检查连接和登录状态」 |\n| 模块分类置信度低 | 飞书通知：Bug 链接+关键信息，请手动确认 |\n| 模块不在负责范围 | 飞书通知：Bug 归属 + 提醒手动流转 |\n| commit id 提取失败 | 飞书通知：日志片段，请手动确认分支 |\n| commit id 不在任何分支 | 飞书通知：commit id，请手动确认 |\n| 附件/日志下载失败 | 降级：仅基于 Bug 描述+历史评论+代码分析，评论注明「未能获取附件」，飞书通知 |\n| 本地代码目录不存在 | 降级：跳过代码分析，仅日志+附件+评论，飞书通知检查配置 |\n| 分析过程中断或超时 | 飞书通知进度和失败原因，不留半截评论 |\n| 用户 5 分钟内未回复重新分析确认 | 默认不重新分析，流程终止 |\n| 分析过程中 git worktree 冲突 | 清理残留 worktree 后重试；仍失败则飞书通知 |\n\n---\n\n## 范围约束\n\n- 不自动填写指派人或流转状态\n- 不自动生成修复代码\n- 不做缺陷趋势统计或报表\n- 当前只服务单一用户\n\nFile v0.0.5:_meta.json\n\n{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"0.0.5\",\n  \"publishedAt\": 1784707446712\n}\n\nFile v0.0.5:references/zentao-api-reference.md\n\n# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |\n\nFile v0.0.5:skill-card.md\n\n## Description: <br>\nZentao Bug Analyzer helps an agent parse ZenTao bug links from Feishu messages, classify modules, collect bug details and attachments, analyze logs and local code, and produce a defect analysis report with optional ZenTao comments and Feishu notifications. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[yeah526](https://clawhub.ai/user/yeah526) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and QA engineers use this skill to triage ZenTao defects from Feishu-triggered reports, correlate bug details with attachments, logs, branch information, and local source code, and prepare a concise root-cause analysis and repair recommendation. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill handles ZenTao credentials that may be stored in local configuration. <br>\nMitigation: Use a low-privilege ZenTao account where possible, avoid storing a primary password, and restrict access to the configuration file. <br>\nRisk: The skill keeps an authenticated browser debugging endpoint available while analysis scripts run. <br>\nMitigation: Treat the printed WS endpoint as a session secret, avoid sharing logs that contain it, and terminate the login process after the workflow completes. <br>\nRisk: The skill can automatically post analysis output to a business ticketing system. <br>\nMitigation: Set auto_comment to false unless automatic posting is intended, and review generated reports before enabling automatic comments. <br>\nRisk: The workflow can run git checkout, submodule update, and worktree cleanup against configured source directories. <br>\nMitigation: Verify each configured code_dir before execution and use isolated or disposable working copies for analysis. <br>\n\n\n## Reference(s): <br>\n- [ClawHub Skill Page](https://clawhub.ai/yeah526/skills/zentao-bug-analyzer) <br>\n- [ZenTao API Reference](references/zentao-api-reference.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown defect analysis report, optional HTML comment body, shell commands, and Feishu notification text] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May write bug-specific report, downloaded attachment, and comment files under a local bugs/{bug_id}/ directory.] <br>\n\n## Skill Version(s): <br>\n0.0.5 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.0.5:SKILL.checklist.md\n\n# 禅道 Bug 分析执行检查清单\n\n> ⚠️ 硬约束：分析开始前通读本清单，每步必须逐项完成，缺一不可。\n\n## 执行检查清单\n\n- [ ] 步骤 1：消息解析（提取 Bug ID）\n\n- [ ] 步骤 2：重复分析检查\n  - 登录禅道（`zentao-login.js`，获取 WS endpoint，一个 Bug 全程复用）\n  - 获取 Bug 详情 + 检查重复评论（`zentao-get-bug.js`，有我的评论 → 飞书询问是否重新分析）\n\n- [ ] 步骤 3：模块分类（按 config aliases 子串硬匹配，不在范围 → 飞书通知 + 终止）\n\n- [ ] 步骤 4a：下载附件（`zentao-download-files.js`）\n\n- [ ] 步骤 4b：确定 Bug 发生时间（Bug 描述文本 > 附件截图/视频系统时间 > 飞书询问。禁止用文件名/创建时间推断）\n\n- [ ] 步骤 4c-1：按 config commit_extract 规则提取 commit id（搜不到 → 飞书通知 + 终止，禁止近似匹配）\n\n- [ ] 步骤 4c-2：`git branch --contains <commit-id>` 记录分支信息\n\n- [ ] 步骤 4c-3：`git checkout <commit-id>` + `git submodule update --init --recursive`\n\n- [ ] 步骤 4d：AI 深度分析（结合 Bug 详情 + 日志 + 代码 + 历史评论）\n\n- [ ] 🔴 步骤 5：输出报告\n  - ⚠️ 先检查 config 中 `auto_comment` 字段（默认 `true`）\n  - `auto_comment === true` 或未配置：\n    - 步骤 5a：禅道评论（先 `zentao-build-comment.js` 生成 HTML，再 `zentao-post-comment.js --comment-file=<file>` 发布）\n  - `auto_comment === false`：跳过禅道评论，仅生成 `report.md`\n\n- [ ] 步骤 5b：飞书摘要（简要结果 + Bug 链接）\n\n- [ ] 🔴 步骤 6：清理 — 必须完成！\n  1. `taskkill /PID <login-PID> /F /T`（PID 来自 `zentao-login.js` 输出行 `PID=<value>`，`/T` 连带杀 Chrome 子进程树）\n  2. `git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove <path>` 清理\n  3. `Get-Process node` 检查无 `zentao-*.js` 残留进程，有则 `taskkill /F /PID <pid>` 清理\n  4. 确认只剩 OpenClaw 自身 node 进程（gateway/worker）\n\nFile v0.0.5:TOOLS.md\n\n# zentao-bug-analyzer 工具与环境\n\n## 环境依赖\n\n- **Node.js** 18+（脚本运行）\n- **Playwright**：`npm install playwright && npx playwright install chromium`\n- **Git** 2.5+（`git worktree`、`git branch --contains`）\n- 禅道服务器可访问：`http://zentao.gxatek.com:20080`\n\n## 禅道交互 · 统一 Playwright 模式\n\n企业版 12.1 不支持 Bearer Token，所有操作在同一 Playwright 会话中完成。通过 `scripts/` 下的 5 个固定脚本实现，一个脚本一个功能。\n\n### 单会话铁律\n\n一个 Bug 全程只启动一次 Playwright 浏览器。登录后读详情、下载附件、写评论全部复用同一 `browser`/`page`/`context`。\n\n### 脚本\n\n| 脚本 | 功能 | 用法 |\n|------|------|------|\n| `scripts/zentao-login.js` | 登录禅道，输出 WS endpoint | `node scripts/zentao-login.js [--port=9224]` |\n| `scripts/zentao-get-bug.js` | 获取 Bug 详情 JSON | `node scripts/zentao-get-bug.js --ws=<WS> --bug-id=<id>` |\n| `scripts/zentao-download-files.js` | 下载 Bug 附件到本地 | `node scripts/zentao-download-files.js --ws=<WS> --bug-id=<id> --dir=<dir>` |\n| `scripts/zentao-build-comment.js` | Markdown 报告 → HTML 评论 | `node scripts/zentao-build-comment.js <report.md> [--out <output.html>]` |\n| `scripts/zentao-post-comment.js` | 发布 Bug 评论 | `node scripts/zentao-post-comment.js --ws=<WS> --bug-id=<id> --comment-file=<path>` |\n\n### 典型调用流程\n\n```\n1. node scripts/zentao-login.js --port=9224\n   → WS=ws://localhost:9224/devtools/browser/{id}, PID={pid}\n\n2. node scripts/zentao-get-bug.js --ws={WS} --bug-id=1432606\n   → JSON (stdout)\n\n3. node scripts/zentao-download-files.js --ws={WS} --bug-id=1432606 --dir=bugs/1432606\n   → 文件路径列表 (stdout)\n\n4. node scripts/zentao-build-comment.js bugs/1432606/report.md --out bugs/1432606/comment.html\n   → HTML 文件路径 (stdout)\n\n5. node scripts/zentao-post-comment.js --ws={WS} --bug-id=1432606 --comment-file=bugs/1432606/comment.html\n   → OK / FAIL\n```\n\n### login 脚本输出格式\n\n`zentao-login.js` 输出两行 key=value（可直接 shell `eval`）：\n\n```\nWS=ws://localhost:9224/devtools/browser/{browser-id}\nPID={chromium-pid}\n```\n\n其他脚本通过 `--ws` 参数复用会话。\n\n### 参数说明\n\n- `--ws`：login 脚本返回的 WebSocket endpoint\n- `--bug-id`：禅道 Bug ID（数字）\n- `--dir`：附件下载目标目录（自动创建）\n- `--comment-file`：评论文件路径（推荐，由 build-comment.js 生成的 HTML 文件）\n- `--comment`：评论内容（原始 HTML 字符串，脚本自动编码。备选方案，推荐用 `--comment-file`）\n- `--port`：CDP 调试端口（默认 9224）\n- `--zentao-url`：禅道实例地址（默认 `http://zentao.gxatek.com:20080`）\n\n## 本文件定位\n\nTOOLS.md 仅放环境依赖和脚本用法。完整 API 参考见 `references/zentao-api-reference.md`，流程规范见 `SKILL.md`。\n\nArchive v0.0.4: 11 files, 23511 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/zentao-build-comment.js (3874b), scripts/zentao-download-files.js (5995b), scripts/zentao-get-bug.js (4480b), scripts/zentao-login.js (5070b), scripts/zentao-post-comment.js (3579b), skill-card.md (2696b), SKILL.checklist.md (2082b), SKILL.md (16526b), TOOLS.md (2917b), _meta.json (138b)\n\nFile v0.0.4:SKILL.md\n\n---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个脚本操作禅道**，禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不做任何恢复操作。\n5. **分析完输出报告**：步骤 4d 产出分析报告后，根据 `auto_comment` 配置决定是否评论禅道：\n   - `auto_comment === true`：运行 `zentao-post-comment.js` 评论 + 飞书摘要\n   - `auto_comment === false`：仅飞书摘要，不评论禅道\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"auto_comment\": true,\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}\n```\n\n字段说明：\n- `name`：模块名称\n- `aliases`：模块别名列表（字符串数组），用于精确匹配。**匹配规则**：将 Bug 的 title、module.name、product.name 与所有模块的 name + aliases 做**子串匹配**（忽略大小写），任一命中即判定为该模块。此规则为硬规则，优先于 AI 主观判断\n- `code_dir`：模块本地代码仓库绝对路径\n- `commit_extract`：自然语言，告诉 AI 如何从日志提取 commit id\n- `analyzer`：`\"default\"` | `\"skill:技能名\"`。default 走通用 AI 分析流程；skill:xxx 委派给对应 Skill\n- `analyze_hint`：模块专属分析提示词（可选），无论哪种分析器都会传给分析器\n- `auto_comment`：布尔值，控制分析完成后是否自动将报告评论到禅道 Bug 下。`true` = 自动评论（默认行为）；`false` = 仅生成报告 + 飞书通知，不评论禅道\n\n### 首次配置引导\n\n配置文件不存在时启动对话式引导。流程：\n\n1. 「请提供禅道的登录账号和密码（用于 Playwright 登录禅道。密码会存储在本地配置文件中，不会泄露）」\n2. 「你负责哪些模块？请列出模块名称（用逗号分隔，如：车机设置, 蓝牙模块, 语音助手）」\n3. 对每个模块依次询问：\n   - 「对于\"{模块名}\"模块，有哪些别名/关键词可以用来识别？（用逗号分隔，如：桌面卡片, systemui, 设置）」\n   - 「对于\"{模块名}\"模块，本地代码目录路径是什么？（请使用绝对路径）」\n   - 「对于\"{模块名}\"模块，日志中如何提取 commit id？请用自然语言描述提取规则」\n   - 「对于\"{模块名}\"模块，是否需要使用专用分析 Skill？（目前可用的 Skill：[列出]。输入 Skill 名或留空走默认分析）」\n   - 「对于\"{模块名}\"模块，有什么分析提示或重点关注方向？（可选，留空则用默认分析策略）」\n4. 「分析完成后，是否需要自动将分析报告评论到禅道 Bug 下？（回复\"是\"=自动评论，\"否\"=仅飞书通知，不评论禅道）」\n5. 「配置完成！请确认你已创建邮件收信规则：当发件人为 `zentao@syncore.space` 时，自动将邮件转发/分享到本 Bot 的对话中。」\n\n---\n\n## 分析流水线\n\n### 步骤 1：消息解析\n\n从消息内容提取禅道 Bug 链接，正则：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 步骤 2：重复分析检查\n\n> ⚠️ 此步骤是强制检查点，无论通过哪种触发方式（邮件转发或自然语言）进入分析流水线，必须先走步骤 2。已评论过的 Bug 绝对不允许直接进入后续步骤。\n\n1. 运行 `scripts/zentao-get-bug.js` 获取 Bug 详情（含历史评论，后续步骤复用）\n2. 检查历史评论中是否已有 `zentao.account` 配置账号的评论\n\n**已有我的评论**：飞书私聊询问「该 Bug 你已评论过，是否需要重新分析？（回复\"是\"或\"分析\"继续，回复\"否\"或\"取消\"跳过）」\n- 确认「是」→ 继续步骤 3\n- 确认「否」或 5 分钟内未回复 → 流程终止\n\n**没有我的评论**：直接继续步骤 3。\n\n### 步骤 3：模块分类\n\n**匹配规则（优先级从高到低）**：\n\n1. **硬别名匹配（优先）**：遍历配置中每个 module 的 `aliases` 数组，将每个别名与 Bug 的 `title`、`module.name`、`product.name` 做**子串匹配**（忽略大小写）。只要任一副本字段包含任一个别名（或 `name` 本身），即判定命中该模块。\n   - 例如：Bug标题含\"桌面卡片\"，配置别名中有\"桌面卡片\" → 直接命中\n   - ⚠️ 此规则是机械规则，不依赖 AI 判断，直接执行\n2. **AI 语义判断（兜底）**：硬别名未命中时，AI 综合判断 Bug 归属模块，对照配置文件 `modules` 列表\n\n**结果处理**：\n- **在范围**：继续步骤 4\n- **不在范围**：飞书私聊通知（Bug 标题、链接、AI 判断的模块归属），提醒模块确认和手动流转。流程结束\n- **置信度低**：飞书私聊通知（Bug 链接 + 关键信息），告知无法确定模块，请手动确认。流程结束\n\n### 步骤 4：深度分析\n\n#### 4a. 下载附件和日志\n运行 `scripts/zentao-download-files.js` 下载 Bug 所有附件到 `bugs/{bug_id}/`。（script 自动处理大文件分块传输，支持 160MB+ 附件）\n\n> ⚠️ 步骤 4a 完成后必须先执行 4b（确定 Bug 发生时间），再进入 4c。\n\n#### 4b. 确定 Bug 发生时间\n\n> ⚠️ 硬约束：Bug 发生时间必须从可靠来源直接获取，禁止猜测或间接推断。\n\n**获取优先级**：\n1. **Bug 描述文本**中明确写出的时间（如「17:33 复现」「12:05 发现」）\n2. **附件视频/截图**中可见的系统时间（状态栏、水印等），需打开查看\n3. **飞书询问用户**：以上均不可用时，私聊询问「该 Bug 发生的精确时间是什么？」\n\n**禁止行为**：\n- ❌ 用附件文件名中的时间戳猜测\n- ❌ 用 Bug 创建时间、最后修改时间间接推断\n- ❌ 用聊天消息转发时间、邮件接收时间推断\n- ❌ 任何不在上述优先级列表内的间接推演\n\n**时间用于**：\n- 日志分析：定位 Bug 发生时刻前后 ±5 分钟的日志片段\n- Git blame：确定相关代码变更时间线\n- 匹配历史评论中提到的复现时间\n\n#### 4c. 分支定位\n1. 解压并读取日志文件：\n   - Android logcat 的 `.gz` 文件**必须使用 Node.js zlib 解压**，禁止使用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或类似 .NET 解压工具\n   - ⚠️ .NET GZipStream 对 Android logd 生成的某些 gzip 流存在兼容性 bug（提前终止解压，实际 30MB 仅解出 ~65KB），会导致日志内容严重缺失\n   - 推荐命令：`node -e \"const zlib=require('zlib');const fs=require('fs');const buf=fs.readFileSync('<log.gz>');zlib.gunzip(buf,(e,r)=>{if(e){console.error(e);return}const s=r.toString('utf8');/* 搜索/处理 s */})\"`\n2. 按配置中 `commit_extract` 从日志提取 commit id\n3. `cd {code_dir}` → `git branch --contains <commit-id>` 确认 commit 在哪些分支上。结果写入分析报告的「分支信息」字段（格式：`分支名 | commit-id`）\n4. 同模块已有其他分析任务时，用 `git worktree add .claude/worktrees/bug-{bug_id}/ <commit-id>` 创建隔离工作区\n5. `git checkout <commit-id>`（进入 detached HEAD 是正常行为，分析完成后保持不动即可）+ `git submodule update --init --recursive`\n\n**commit id 提取失败**：飞书私聊通知（附带日志片段），流程终止。\n\n> ⚠️ 硬约束：只使用配置中 commit_extract 指定的提取规则，禁止 AI 自行更换搜索关键词（如换 TAG、换正则）。搜不到就是搜不到，不允许\"近似匹配\"或\"换成类似的 TAG 试试\"。\n> Self-Check：若在分析过程中进行了 commit_extract 规则以外的额外搜索，应立即停止、丢弃中间产物，回到步骤 4c 标准路径并报告提取失败。\n\n**commit id 不在任何分支**：飞书私聊通知（附带 commit id），流程终止\n\n> ⚠️ 硬约束：`git checkout <commit-id>` 后必须执行 `git submodule update --init --recursive`，确保所有 submodule 都已 checkout 到对应版本。未 checkout submodule 可能导致分析时缺少依赖代码、漏掉跨仓库 API 不一致问题。\n\n#### 4d. AI 综合深度分析\n\n历史评论已在步骤 2 获取，此处直接使用。\n\n根据 `analyzer` 字段：\n- `\"default\"`：AI 综合 Bug 详情 + 附件/日志 + 历史评论 + 本地代码分析\n- `\"skill:xxx\"`：委派给指定 Skill，传入分析上下文\n\n无论哪种方式，`analyze_hint` 都作为上下文传入。\n\n输出格式（Markdown，AI 直接产出此结构）：\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**：\n  ```lang\n  // 关键代码\n  ```\n- **判断依据**：（结合日志/历史评论/代码逻辑的推理过程）\n\n### 修复建议\n1. 具体修复方向（可操作步骤，非抽象建议）\n\n### 风险评估\n- **影响范围**：（哪些功能/模块受影响）\n- **严重程度**：（低/中/高/严重 + 理由）\n\n### 步骤 5：结果输出\n\n> ⚠️ **auto_comment 开关**：步骤 5 开始前，检查配置文件中 `auto_comment` 字段（默认为 `true`）。\n> - `auto_comment === false`：跳过禅道评论（步骤 5.1），仅生成 `report.md` + 执行飞书私聊通知（步骤 5.2）\n> - `auto_comment === true` 或未配置：执行完整双通道（禅道评论 + 飞书通知）\n\n1. **禅道评论**（仅在 `auto_comment !== false` 时执行）：\n   a. 将分析报告写入 `bugs/{bug_id}/report.md`（按步骤 4d 输出格式）\n   b. 运行 `node scripts/zentao-build-comment.js bugs/{bug_id}/report.md --out bugs/{bug_id}/comment.html` 生成 HTML\n   c. 运行 `node scripts/zentao-post-comment.js --ws=<wsEndpoint> --bug-id=<id> --comment-file=bugs/{bug_id}/comment.html` 发布（**必须用 `--comment-file`，禁止用 `--comment` 传 HTML 内容**）\n   d. ⚠️ 禁止手写临时 Playwright 脚本发布评论\n2. **飞书私聊**：简要摘要 + 禅道 Bug 链接\n\n### 步骤 6：清理\n\n分析完成后必须清理残留进程，避免占用系统资源：\n\n1. **杀掉 login 常驻进程（连带 Chrome）**：`taskkill /PID <login-PID> /F /T`，PID 来自 `zentao-login.js` 输出行 `PID=<value>`。`/T` 会连带终结 Chrome 子进程树\n2. **清理 git worktree**：`git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove .claude/worktrees/bug-{bug_id}/`\n3. **检查残留脚本进程**：`Get-Process node` 检查是否还有 `zentao-*.js` 相关进程，有则 `taskkill /F /PID <pid>` 清理\n4. **确认清理完毕**：最终应只剩 OpenClaw 自身的 node 进程（gateway/worker），不应有其他 `zentao-*.js` 残留\n\n> ⚠️ 注意：不要杀掉 OpenClaw 自身的 node 进程（gateway/worker），只清理 `zentao-*.js` 和 Chrome headless 相关进程。\n\n---\n\n## 并发处理\n\n- **不同模块**：代码目录不同，全部并行处理\n- **同一模块同时分析多个 Bug 时**：用 `git worktree` 为每个 Bug 创建隔离工作区，分析完成后 `git worktree remove` 清理\n\n---\n\n## 禅道交互方式\n\n> ⚠️ 企业版 12.1 不支持 Bearer Token 认证（`POST /api.php/v1/tokens` 不可用），所有读写操作统一走 Playwright。\n\n### 🔴 铁律：单次 Playwright 会话\n\n**一个 Bug 的分析全程只允许启动一次 Playwright 浏览器**。登录后所有操作（读详情、下载附件、写评论）复用同一会话，禁止：\n\n- ❌ 分多个脚本文件各启动一次 Playwright\n- ❌ 中途关闭浏览器再重新登录\n- ❌ 写评论时用新的浏览器实例\n\n### 🔴 铁律：脚本优先，禁止手写临时 Playwright 脚本\n\n**禅道交互只允许使用 `scripts/` 目录下的 5 个固定脚本**：\n\n| 脚本 | 用途 | 关键参数 |\n|------|------|----------|\n| `zentao-login.js` | 登录 | `--port`（默认 9224）|\n| `zentao-get-bug.js` | 获取 Bug 详情 | `--ws`、`--bug-id` |\n| `zentao-download-files.js` | 下载附件 | `--ws`、`--bug-id`、`--dir` |\n| `zentao-build-comment.js` | Markdown → HTML 评论 | `<report.md> [--out <output.html>]` |\n| `zentao-post-comment.js` | 发布评论 | `--ws`、`--bug-id`、`--comment-file=<path>`（推荐）或 `--comment`（原始 HTML）|\n\n**禁止行为**：\n- ❌ 手写临时 `post_comment.js`、`check_bug.js`、`debug_login.js` 等任何 Playwright 脚本\n- ❌ 在 `bugs/{bug_id}/` 目录下创建任何 `.js` 文件\n- ❌ 用 `page.evaluate`、`page.fill`、`page.click` 等 Playwright API 绕过已有脚本\n\n**遇到脚本报错时的正确处理方式**：\n1. 先读脚本源码，理解它依赖的输入（WS endpoint、参数格式等）\n2. 修复输入条件（如重新登录获取有效 WS endpoint），而不是绕过脚本\n3. 如果脚本本身有 bug，修复脚本源码（`scripts/` 目录下），让修复对所有后续分析生效\n\n---\n\n## 边界情况处理\n\n| 场景 | 处理 |\n|------|------|\n| 不含禅道链接 | 「未识别到有效的禅道缺陷链接，请确认消息内容」 |\n| 链接解析失败 | 「无法解析该链接，请确认是否正确转发」 |\n| 禅道 API 请求失败（登录失效/会话过期） | 「无法访问禅道，请检查连接和登录状态」 |\n| 模块分类置信度低 | 飞书通知：Bug 链接+关键信息，请手动确认 |\n| 模块不在负责范围 | 飞书通知：Bug 归属 + 提醒手动流转 |\n| commit id 提取失败 | 飞书通知：日志片段，请手动确认分支 |\n| commit id 不在任何分支 | 飞书通知：commit id，请手动确认 |\n| 附件/日志下载失败 | 降级：仅基于 Bug 描述+历史评论+代码分析，评论注明「未能获取附件」，飞书通知 |\n| 本地代码目录不存在 | 降级：跳过代码分析，仅日志+附件+评论，飞书通知检查配置 |\n| 分析过程中断或超时 | 飞书通知进度和失败原因，不留半截评论 |\n| 用户 5 分钟内未回复重新分析确认 | 默认不重新分析，流程终止 |\n| 分析过程中 git worktree 冲突 | 清理残留 worktree 后重试；仍失败则飞书通知 |\n\n---\n\n## 范围约束\n\n- 不自动填写指派人或流转状态\n- 不自动生成修复代码\n- 不做缺陷趋势统计或报表\n- 当前只服务单一用户\n\nFile v0.0.4:_meta.json\n\n{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"0.0.4\",\n  \"publishedAt\": 1784707329591\n}\n\nFile v0.0.4:references/zentao-api-reference.md\n\n# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |\n\nFile v0.0.4:skill-card.md\n\n## Description: <br>\nAnalyzes Zentao bug links by fetching bug details, attachments, logs, and local code, then producing a root-cause report with optional Zentao commenting and Feishu notification. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[yeah526](https://clawhub.ai/user/yeah526) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers responsible for Zentao-tracked product modules use this skill to triage assigned bugs, identify the affected module and code branch, inspect logs and code, and produce a root-cause analysis report. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill stores a Zentao password in a local plaintext configuration file. <br>\nMitigation: Keep the configuration file protected, avoid shared workspaces, and limit use to machines where local credential storage is acceptable. <br>\nRisk: The skill can automatically use an authenticated session to read bug records and download attachments. <br>\nMitigation: Run it only for authorized Zentao work, review downloaded files carefully, and clean local bug work directories after analysis. <br>\nRisk: The default workflow can post analysis comments back to Zentao bug records. <br>\nMitigation: Set auto_comment to false unless automatic writes are explicitly intended, and review generated reports before posting. <br>\nRisk: The workflow can check out commits and create or remove git worktrees during analysis. <br>\nMitigation: Verify target repositories and worktree cleanup paths before running the workflow in active development directories. <br>\n\n\n## Reference(s): <br>\n- [Zentao API reference](artifact/references/zentao-api-reference.md) <br>\n- [Tool and environment reference](artifact/TOOLS.md) <br>\n- [ClawHub skill page](https://clawhub.ai/yeah526/skills/zentao-bug-analyzer) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown report with optional HTML comment, Feishu summary text, JSON bug data, downloaded attachment files, and shell command invocations.] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May create local bug work directories, report.md, comment.html, and downloaded Zentao attachments.] <br>\n\n## Skill Version(s): <br>\n0.0.4 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.0.4:SKILL.checklist.md\n\n# 禅道 Bug 分析执行检查清单\n\n> ⚠️ 硬约束：分析开始前通读本清单，每步必须逐项完成，缺一不可。\n\n## 执行检查清单\n\n- [ ] 步骤 1：消息解析（提取 Bug ID）\n\n- [ ] 步骤 2：重复分析检查\n  - 登录禅道（`zentao-login.js`，获取 WS endpoint，一个 Bug 全程复用）\n  - 获取 Bug 详情 + 检查重复评论（`zentao-get-bug.js`，有我的评论 → 飞书询问是否重新分析）\n\n- [ ] 步骤 3：模块分类（按 config aliases 子串硬匹配，不在范围 → 飞书通知 + 终止）\n\n- [ ] 步骤 4a：下载附件（`zentao-download-files.js`）\n\n- [ ] 步骤 4b：确定 Bug 发生时间（Bug 描述文本 > 附件截图/视频系统时间 > 飞书询问。禁止用文件名/创建时间推断）\n\n- [ ] 步骤 4c-1：按 config commit_extract 规则提取 commit id（搜不到 → 飞书通知 + 终止，禁止近似匹配）\n\n- [ ] 步骤 4c-2：`git branch --contains <commit-id>` 记录分支信息\n\n- [ ] 步骤 4c-3：`git checkout <commit-id>` + `git submodule update --init --recursive`\n\n- [ ] 步骤 4d：AI 深度分析（结合 Bug 详情 + 日志 + 代码 + 历史评论）\n\n- [ ] 🔴 步骤 5：输出报告\n  - ⚠️ 先检查 config 中 `auto_comment` 字段（默认 `true`）\n  - `auto_comment === true` 或未配置：\n    - 步骤 5a：禅道评论（先 `zentao-build-comment.js` 生成 HTML，再 `zentao-post-comment.js --comment-file=<file>` 发布）\n  - `auto_comment === false`：跳过禅道评论，仅生成 `report.md`\n\n- [ ] 步骤 5b：飞书摘要（简要结果 + Bug 链接）\n\n- [ ] 🔴 步骤 6：清理 — 必须完成！\n  1. `taskkill /PID <login-PID> /F /T`（PID 来自 `zentao-login.js` 输出行 `PID=<value>`，`/T` 连带杀 Chrome 子进程树）\n  2. `git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove <path>` 清理\n  3. `Get-Process node` 检查无 `zentao-*.js` 残留进程，有则 `taskkill /F /PID <pid>` 清理\n  4. 确认只剩 OpenClaw 自身 node 进程（gateway/worker）\n\nFile v0.0.4:TOOLS.md\n\n# zentao-bug-analyzer 工具与环境\n\n## 环境依赖\n\n- **Node.js** 18+（脚本运行）\n- **Playwright**：`npm install playwright && npx playwright install chromium`\n- **Git** 2.5+（`git worktree`、`git branch --contains`）\n- 禅道服务器可访问：`http://zentao.gxatek.com:20080`\n\n## 禅道交互 · 统一 Playwright 模式\n\n企业版 12.1 不支持 Bearer Token，所有操作在同一 Playwright 会话中完成。通过 `scripts/` 下的 5 个固定脚本实现，一个脚本一个功能。\n\n### 单会话铁律\n\n一个 Bug 全程只启动一次 Playwright 浏览器。登录后读详情、下载附件、写评论全部复用同一 `browser`/`page`/`context`。\n\n### 脚本\n\n| 脚本 | 功能 | 用法 |\n|------|------|------|\n| `scripts/zentao-login.js` | 登录禅道，输出 WS endpoint | `node scripts/zentao-login.js [--port=9224]` |\n| `scripts/zentao-get-bug.js` | 获取 Bug 详情 JSON | `node scripts/zentao-get-bug.js --ws=<WS> --bug-id=<id>` |\n| `scripts/zentao-download-files.js` | 下载 Bug 附件到本地 | `node scripts/zentao-download-files.js --ws=<WS> --bug-id=<id> --dir=<dir>` |\n| `scripts/zentao-build-comment.js` | Markdown 报告 → HTML 评论 | `node scripts/zentao-build-comment.js <report.md> [--out <output.html>]` |\n| `scripts/zentao-post-comment.js` | 发布 Bug 评论 | `node scripts/zentao-post-comment.js --ws=<WS> --bug-id=<id> --comment-file=<path>` |\n\n### 典型调用流程\n\n```\n1. node scripts/zentao-login.js --port=9224\n   → WS=ws://localhost:9224/devtools/browser/{id}, PID={pid}\n\n2. node scripts/zentao-get-bug.js --ws={WS} --bug-id=1432606\n   → JSON (stdout)\n\n3. node scripts/zentao-download-files.js --ws={WS} --bug-id=1432606 --dir=bugs/1432606\n   → 文件路径列表 (stdout)\n\n4. node scripts/zentao-build-comment.js bugs/1432606/report.md --out bugs/1432606/comment.html\n   → HTML 文件路径 (stdout)\n\n5. node scripts/zentao-post-comment.js --ws={WS} --bug-id=1432606 --comment-file=bugs/1432606/comment.html\n   → OK / FAIL\n```\n\n### login 脚本输出格式\n\n`zentao-login.js` 输出两行 key=value（可直接 shell `eval`）：\n\n```\nWS=ws://localhost:9224/devtools/browser/{browser-id}\nPID={chromium-pid}\n```\n\n其他脚本通过 `--ws` 参数复用会话。\n\n### 参数说明\n\n- `--ws`：login 脚本返回的 WebSocket endpoint\n- `--bug-id`：禅道 Bug ID（数字）\n- `--dir`：附件下载目标目录（自动创建）\n- `--comment-file`：评论文件路径（推荐，由 build-comment.js 生成的 HTML 文件）\n- `--comment`：评论内容（原始 HTML 字符串，脚本自动编码。备选方案，推荐用 `--comment-file`）\n- `--port`：CDP 调试端口（默认 9224）\n- `--zentao-url`：禅道实例地址（默认 `http://zentao.gxatek.com:20080`）\n\n## 本文件定位\n\nTOOLS.md 仅放环境依赖和脚本用法。完整 API 参考见 `references/zentao-api-reference.md`，流程规范见 `SKILL.md`。\n\nArchive v0.0.3: 11 files, 23545 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/zentao-build-comment.js (3874b), scripts/zentao-download-files.js (5995b), scripts/zentao-get-bug.js (4480b), scripts/zentao-login.js (5070b), scripts/zentao-post-comment.js (3579b), skill-card.md (2744b), SKILL.checklist.md (2082b), SKILL.md (16526b), TOOLS.md (2917b), _meta.json (138b)\n\nFile v0.0.3:SKILL.md\n\n---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个脚本操作禅道**，禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不做任何恢复操作。\n5. **分析完输出报告**：步骤 4d 产出分析报告后，根据 `auto_comment` 配置决定是否评论禅道：\n   - `auto_comment === true`：运行 `zentao-post-comment.js` 评论 + 飞书摘要\n   - `auto_comment === false`：仅飞书摘要，不评论禅道\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"auto_comment\": true,\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}\n```\n\n字段说明：\n- `name`：模块名称\n- `aliases`：模块别名列表（字符串数组），用于精确匹配。**匹配规则**：将 Bug 的 title、module.name、product.name 与所有模块的 name + aliases 做**子串匹配**（忽略大小写），任一命中即判定为该模块。此规则为硬规则，优先于 AI 主观判断\n- `code_dir`：模块本地代码仓库绝对路径\n- `commit_extract`：自然语言，告诉 AI 如何从日志提取 commit id\n- `analyzer`：`\"default\"` | `\"skill:技能名\"`。default 走通用 AI 分析流程；skill:xxx 委派给对应 Skill\n- `analyze_hint`：模块专属分析提示词（可选），无论哪种分析器都会传给分析器\n- `auto_comment`：布尔值，控制分析完成后是否自动将报告评论到禅道 Bug 下。`true` = 自动评论（默认行为）；`false` = 仅生成报告 + 飞书通知，不评论禅道\n\n### 首次配置引导\n\n配置文件不存在时启动对话式引导。流程：\n\n1. 「请提供禅道的登录账号和密码（用于 Playwright 登录禅道。密码会存储在本地配置文件中，不会泄露）」\n2. 「你负责哪些模块？请列出模块名称（用逗号分隔，如：车机设置, 蓝牙模块, 语音助手）」\n3. 对每个模块依次询问：\n   - 「对于\"{模块名}\"模块，有哪些别名/关键词可以用来识别？（用逗号分隔，如：桌面卡片, systemui, 设置）」\n   - 「对于\"{模块名}\"模块，本地代码目录路径是什么？（请使用绝对路径）」\n   - 「对于\"{模块名}\"模块，日志中如何提取 commit id？请用自然语言描述提取规则」\n   - 「对于\"{模块名}\"模块，是否需要使用专用分析 Skill？（目前可用的 Skill：[列出]。输入 Skill 名或留空走默认分析）」\n   - 「对于\"{模块名}\"模块，有什么分析提示或重点关注方向？（可选，留空则用默认分析策略）」\n4. 「分析完成后，是否需要自动将分析报告评论到禅道 Bug 下？（回复\"是\"=自动评论，\"否\"=仅飞书通知，不评论禅道）」\n5. 「配置完成！请确认你已创建邮件收信规则：当发件人为 `zentao@syncore.space` 时，自动将邮件转发/分享到本 Bot 的对话中。」\n\n---\n\n## 分析流水线\n\n### 步骤 1：消息解析\n\n从消息内容提取禅道 Bug 链接，正则：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 步骤 2：重复分析检查\n\n> ⚠️ 此步骤是强制检查点，无论通过哪种触发方式（邮件转发或自然语言）进入分析流水线，必须先走步骤 2。已评论过的 Bug 绝对不允许直接进入后续步骤。\n\n1. 运行 `scripts/zentao-get-bug.js` 获取 Bug 详情（含历史评论，后续步骤复用）\n2. 检查历史评论中是否已有 `zentao.account` 配置账号的评论\n\n**已有我的评论**：飞书私聊询问「该 Bug 你已评论过，是否需要重新分析？（回复\"是\"或\"分析\"继续，回复\"否\"或\"取消\"跳过）」\n- 确认「是」→ 继续步骤 3\n- 确认「否」或 5 分钟内未回复 → 流程终止\n\n**没有我的评论**：直接继续步骤 3。\n\n### 步骤 3：模块分类\n\n**匹配规则（优先级从高到低）**：\n\n1. **硬别名匹配（优先）**：遍历配置中每个 module 的 `aliases` 数组，将每个别名与 Bug 的 `title`、`module.name`、`product.name` 做**子串匹配**（忽略大小写）。只要任一副本字段包含任一个别名（或 `name` 本身），即判定命中该模块。\n   - 例如：Bug标题含\"桌面卡片\"，配置别名中有\"桌面卡片\" → 直接命中\n   - ⚠️ 此规则是机械规则，不依赖 AI 判断，直接执行\n2. **AI 语义判断（兜底）**：硬别名未命中时，AI 综合判断 Bug 归属模块，对照配置文件 `modules` 列表\n\n**结果处理**：\n- **在范围**：继续步骤 4\n- **不在范围**：飞书私聊通知（Bug 标题、链接、AI 判断的模块归属），提醒模块确认和手动流转。流程结束\n- **置信度低**：飞书私聊通知（Bug 链接 + 关键信息），告知无法确定模块，请手动确认。流程结束\n\n### 步骤 4：深度分析\n\n#### 4a. 下载附件和日志\n运行 `scripts/zentao-download-files.js` 下载 Bug 所有附件到 `bugs/{bug_id}/`。（script 自动处理大文件分块传输，支持 160MB+ 附件）\n\n> ⚠️ 步骤 4a 完成后必须先执行 4b（确定 Bug 发生时间），再进入 4c。\n\n#### 4b. 确定 Bug 发生时间\n\n> ⚠️ 硬约束：Bug 发生时间必须从可靠来源直接获取，禁止猜测或间接推断。\n\n**获取优先级**：\n1. **Bug 描述文本**中明确写出的时间（如「17:33 复现」「12:05 发现」）\n2. **附件视频/截图**中可见的系统时间（状态栏、水印等），需打开查看\n3. **飞书询问用户**：以上均不可用时，私聊询问「该 Bug 发生的精确时间是什么？」\n\n**禁止行为**：\n- ❌ 用附件文件名中的时间戳猜测\n- ❌ 用 Bug 创建时间、最后修改时间间接推断\n- ❌ 用聊天消息转发时间、邮件接收时间推断\n- ❌ 任何不在上述优先级列表内的间接推演\n\n**时间用于**：\n- 日志分析：定位 Bug 发生时刻前后 ±5 分钟的日志片段\n- Git blame：确定相关代码变更时间线\n- 匹配历史评论中提到的复现时间\n\n#### 4c. 分支定位\n1. 解压并读取日志文件：\n   - Android logcat 的 `.gz` 文件**必须使用 Node.js zlib 解压**，禁止使用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或类似 .NET 解压工具\n   - ⚠️ .NET GZipStream 对 Android logd 生成的某些 gzip 流存在兼容性 bug（提前终止解压，实际 30MB 仅解出 ~65KB），会导致日志内容严重缺失\n   - 推荐命令：`node -e \"const zlib=require('zlib');const fs=require('fs');const buf=fs.readFileSync('<log.gz>');zlib.gunzip(buf,(e,r)=>{if(e){console.error(e);return}const s=r.toString('utf8');/* 搜索/处理 s */})\"`\n2. 按配置中 `commit_extract` 从日志提取 commit id\n3. `cd {code_dir}` → `git branch --contains <commit-id>` 确认 commit 在哪些分支上。结果写入分析报告的「分支信息」字段（格式：`分支名 | commit-id`）\n4. 同模块已有其他分析任务时，用 `git worktree add .claude/worktrees/bug-{bug_id}/ <commit-id>` 创建隔离工作区\n5. `git checkout <commit-id>`（进入 detached HEAD 是正常行为，分析完成后保持不动即可）+ `git submodule update --init --recursive`\n\n**commit id 提取失败**：飞书私聊通知（附带日志片段），流程终止。\n\n> ⚠️ 硬约束：只使用配置中 commit_extract 指定的提取规则，禁止 AI 自行更换搜索关键词（如换 TAG、换正则）。搜不到就是搜不到，不允许\"近似匹配\"或\"换成类似的 TAG 试试\"。\n> Self-Check：若在分析过程中进行了 commit_extract 规则以外的额外搜索，应立即停止、丢弃中间产物，回到步骤 4c 标准路径并报告提取失败。\n\n**commit id 不在任何分支**：飞书私聊通知（附带 commit id），流程终止\n\n> ⚠️ 硬约束：`git checkout <commit-id>` 后必须执行 `git submodule update --init --recursive`，确保所有 submodule 都已 checkout 到对应版本。未 checkout submodule 可能导致分析时缺少依赖代码、漏掉跨仓库 API 不一致问题。\n\n#### 4d. AI 综合深度分析\n\n历史评论已在步骤 2 获取，此处直接使用。\n\n根据 `analyzer` 字段：\n- `\"default\"`：AI 综合 Bug 详情 + 附件/日志 + 历史评论 + 本地代码分析\n- `\"skill:xxx\"`：委派给指定 Skill，传入分析上下文\n\n无论哪种方式，`analyze_hint` 都作为上下文传入。\n\n输出格式（Markdown，AI 直接产出此结构）：\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**：\n  ```lang\n  // 关键代码\n  ```\n- **判断依据**：（结合日志/历史评论/代码逻辑的推理过程）\n\n### 修复建议\n1. 具体修复方向（可操作步骤，非抽象建议）\n\n### 风险评估\n- **影响范围**：（哪些功能/模块受影响）\n- **严重程度**：（低/中/高/严重 + 理由）\n\n### 步骤 5：结果输出\n\n> ⚠️ **auto_comment 开关**：步骤 5 开始前，检查配置文件中 `auto_comment` 字段（默认为 `true`）。\n> - `auto_comment === false`：跳过禅道评论（步骤 5.1），仅生成 `report.md` + 执行飞书私聊通知（步骤 5.2）\n> - `auto_comment === true` 或未配置：执行完整双通道（禅道评论 + 飞书通知）\n\n1. **禅道评论**（仅在 `auto_comment !== false` 时执行）：\n   a. 将分析报告写入 `bugs/{bug_id}/report.md`（按步骤 4d 输出格式）\n   b. 运行 `node scripts/zentao-build-comment.js bugs/{bug_id}/report.md --out bugs/{bug_id}/comment.html` 生成 HTML\n   c. 运行 `node scripts/zentao-post-comment.js --ws=<wsEndpoint> --bug-id=<id> --comment-file=bugs/{bug_id}/comment.html` 发布（**必须用 `--comment-file`，禁止用 `--comment` 传 HTML 内容**）\n   d. ⚠️ 禁止手写临时 Playwright 脚本发布评论\n2. **飞书私聊**：简要摘要 + 禅道 Bug 链接\n\n### 步骤 6：清理\n\n分析完成后必须清理残留进程，避免占用系统资源：\n\n1. **杀掉 login 常驻进程（连带 Chrome）**：`taskkill /PID <login-PID> /F /T`，PID 来自 `zentao-login.js` 输出行 `PID=<value>`。`/T` 会连带终结 Chrome 子进程树\n2. **清理 git worktree**：`git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove .claude/worktrees/bug-{bug_id}/`\n3. **检查残留脚本进程**：`Get-Process node` 检查是否还有 `zentao-*.js` 相关进程，有则 `taskkill /F /PID <pid>` 清理\n4. **确认清理完毕**：最终应只剩 OpenClaw 自身的 node 进程（gateway/worker），不应有其他 `zentao-*.js` 残留\n\n> ⚠️ 注意：不要杀掉 OpenClaw 自身的 node 进程（gateway/worker），只清理 `zentao-*.js` 和 Chrome headless 相关进程。\n\n---\n\n## 并发处理\n\n- **不同模块**：代码目录不同，全部并行处理\n- **同一模块同时分析多个 Bug 时**：用 `git worktree` 为每个 Bug 创建隔离工作区，分析完成后 `git worktree remove` 清理\n\n---\n\n## 禅道交互方式\n\n> ⚠️ 企业版 12.1 不支持 Bearer Token 认证（`POST /api.php/v1/tokens` 不可用），所有读写操作统一走 Playwright。\n\n### 🔴 铁律：单次 Playwright 会话\n\n**一个 Bug 的分析全程只允许启动一次 Playwright 浏览器**。登录后所有操作（读详情、下载附件、写评论）复用同一会话，禁止：\n\n- ❌ 分多个脚本文件各启动一次 Playwright\n- ❌ 中途关闭浏览器再重新登录\n- ❌ 写评论时用新的浏览器实例\n\n### 🔴 铁律：脚本优先，禁止手写临时 Playwright 脚本\n\n**禅道交互只允许使用 `scripts/` 目录下的 5 个固定脚本**：\n\n| 脚本 | 用途 | 关键参数 |\n|------|------|----------|\n| `zentao-login.js` | 登录 | `--port`（默认 9224）|\n| `zentao-get-bug.js` | 获取 Bug 详情 | `--ws`、`--bug-id` |\n| `zentao-download-files.js` | 下载附件 | `--ws`、`--bug-id`、`--dir` |\n| `zentao-build-comment.js` | Markdown → HTML 评论 | `<report.md> [--out <output.html>]` |\n| `zentao-post-comment.js` | 发布评论 | `--ws`、`--bug-id`、`--comment-file=<path>`（推荐）或 `--comment`（原始 HTML）|\n\n**禁止行为**：\n- ❌ 手写临时 `post_comment.js`、`check_bug.js`、`debug_login.js` 等任何 Playwright 脚本\n- ❌ 在 `bugs/{bug_id}/` 目录下创建任何 `.js` 文件\n- ❌ 用 `page.evaluate`、`page.fill`、`page.click` 等 Playwright API 绕过已有脚本\n\n**遇到脚本报错时的正确处理方式**：\n1. 先读脚本源码，理解它依赖的输入（WS endpoint、参数格式等）\n2. 修复输入条件（如重新登录获取有效 WS endpoint），而不是绕过脚本\n3. 如果脚本本身有 bug，修复脚本源码（`scripts/` 目录下），让修复对所有后续分析生效\n\n---\n\n## 边界情况处理\n\n| 场景 | 处理 |\n|------|------|\n| 不含禅道链接 | 「未识别到有效的禅道缺陷链接，请确认消息内容」 |\n| 链接解析失败 | 「无法解析该链接，请确认是否正确转发」 |\n| 禅道 API 请求失败（登录失效/会话过期） | 「无法访问禅道，请检查连接和登录状态」 |\n| 模块分类置信度低 | 飞书通知：Bug 链接+关键信息，请手动确认 |\n| 模块不在负责范围 | 飞书通知：Bug 归属 + 提醒手动流转 |\n| commit id 提取失败 | 飞书通知：日志片段，请手动确认分支 |\n| commit id 不在任何分支 | 飞书通知：commit id，请手动确认 |\n| 附件/日志下载失败 | 降级：仅基于 Bug 描述+历史评论+代码分析，评论注明「未能获取附件」，飞书通知 |\n| 本地代码目录不存在 | 降级：跳过代码分析，仅日志+附件+评论，飞书通知检查配置 |\n| 分析过程中断或超时 | 飞书通知进度和失败原因，不留半截评论 |\n| 用户 5 分钟内未回复重新分析确认 | 默认不重新分析，流程终止 |\n| 分析过程中 git worktree 冲突 | 清理残留 worktree 后重试；仍失败则飞书通知 |\n\n---\n\n## 范围约束\n\n- 不自动填写指派人或流转状态\n- 不自动生成修复代码\n- 不做缺陷趋势统计或报表\n- 当前只服务单一用户\n\nFile v0.0.3:_meta.json\n\n{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"0.0.3\",\n  \"publishedAt\": 1784706334848\n}\n\nFile v0.0.3:references/zentao-api-reference.md\n\n# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |\n\nFile v0.0.3:skill-card.md\n\n## Description: <br>\nAutomates Zentao bug analysis from Feishu-triggered bug links by classifying modules, locating branches, analyzing code and logs, and producing reports for Zentao comments and Feishu notifications. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[yeah526](https://clawhub.ai/user/yeah526) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and QA engineers use this skill to triage Zentao defects from Feishu messages, gather bug details and attachments, identify the affected module and commit, and draft a root-cause analysis with repair guidance. It can publish the resulting report to Zentao and send a Feishu summary when configured. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Stored Zentao credentials and an authenticated browser control endpoint can expose account or session access. <br>\nMitigation: Use a low-privilege Zentao account, avoid raw password storage where possible, and protect or suppress the browser endpoint output. <br>\nRisk: Automatic commenting can publish an analysis report back to Zentao before a human reviews it. <br>\nMitigation: Set auto_comment to false until reports are reviewed manually, then enable posting only after the report content is approved. <br>\nRisk: Git checkout, worktree cleanup, and process termination steps can affect local repositories or running processes. <br>\nMitigation: Run the skill in a controlled workspace and confirm repository paths, commit IDs, worktree locations, and PIDs before allowing mutation or cleanup steps. <br>\nRisk: Attachment downloads write files from Zentao into the workspace and may influence the analysis. <br>\nMitigation: Keep downloads in a controlled bug-specific directory and review attachments or logs before relying on the generated findings. <br>\n\n\n## Reference(s): <br>\n- [Zentao API Reference](references/zentao-api-reference.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Markdown, Shell commands, Files, Guidance] <br>\n**Output Format:** [Markdown reports, HTML comments, JSON bug data, and script command output] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May write downloaded attachments and report files under a bug-specific workspace path, and may post a Zentao comment when auto_comment is enabled.] <br>\n\n## Skill Version(s): <br>\n0.0.3 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.0.3:SKILL.checklist.md\n\n# 禅道 Bug 分析执行检查清单\n\n> ⚠️ 硬约束：分析开始前通读本清单，每步必须逐项完成，缺一不可。\n\n## 执行检查清单\n\n- [ ] 步骤 1：消息解析（提取 Bug ID）\n\n- [ ] 步骤 2：重复分析检查\n  - 登录禅道（`zentao-login.js`，获取 WS endpoint，一个 Bug 全程复用）\n  - 获取 Bug 详情 + 检查重复评论（`zentao-get-bug.js`，有我的评论 → 飞书询问是否重新分析）\n\n- [ ] 步骤 3：模块分类（按 config aliases 子串硬匹配，不在范围 → 飞书通知 + 终止）\n\n- [ ] 步骤 4a：下载附件（`zentao-download-files.js`）\n\n- [ ] 步骤 4b：确定 Bug 发生时间（Bug 描述文本 > 附件截图/视频系统时间 > 飞书询问。禁止用文件名/创建时间推断）\n\n- [ ] 步骤 4c-1：按 config commit_extract 规则提取 commit id（搜不到 → 飞书通知 + 终止，禁止近似匹配）\n\n- [ ] 步骤 4c-2：`git branch --contains <commit-id>` 记录分支信息\n\n- [ ] 步骤 4c-3：`git checkout <commit-id>` + `git submodule update --init --recursive`\n\n- [ ] 步骤 4d：AI 深度分析（结合 Bug 详情 + 日志 + 代码 + 历史评论）\n\n- [ ] 🔴 步骤 5：输出报告\n  - ⚠️ 先检查 config 中 `auto_comment` 字段（默认 `true`）\n  - `auto_comment === true` 或未配置：\n    - 步骤 5a：禅道评论（先 `zentao-build-comment.js` 生成 HTML，再 `zentao-post-comment.js --comment-file=<file>` 发布）\n  - `auto_comment === false`：跳过禅道评论，仅生成 `report.md`\n\n- [ ] 步骤 5b：飞书摘要（简要结果 + Bug 链接）\n\n- [ ] 🔴 步骤 6：清理 — 必须完成！\n  1. `taskkill /PID <login-PID> /F /T`（PID 来自 `zentao-login.js` 输出行 `PID=<value>`，`/T` 连带杀 Chrome 子进程树）\n  2. `git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove <path>` 清理\n  3. `Get-Process node` 检查无 `zentao-*.js` 残留进程，有则 `taskkill /F /PID <pid>` 清理\n  4. 确认只剩 OpenClaw 自身 node 进程（gateway/worker）\n\nFile v0.0.3:TOOLS.md\n\n# zentao-bug-analyzer 工具与环境\n\n## 环境依赖\n\n- **Node.js** 18+（脚本运行）\n- **Playwright**：`npm install playwright && npx playwright install chromium`\n- **Git** 2.5+（`git worktree`、`git branch --contains`）\n- 禅道服务器可访问：`http://zentao.gxatek.com:20080`\n\n## 禅道交互 · 统一 Playwright 模式\n\n企业版 12.1 不支持 Bearer Token，所有操作在同一 Playwright 会话中完成。通过 `scripts/` 下的 5 个固定脚本实现，一个脚本一个功能。\n\n### 单会话铁律\n\n一个 Bug 全程只启动一次 Playwright 浏览器。登录后读详情、下载附件、写评论全部复用同一 `browser`/`page`/`context`。\n\n### 脚本\n\n| 脚本 | 功能 | 用法 |\n|------|------|------|\n| `scripts/zentao-login.js` | 登录禅道，输出 WS endpoint | `node scripts/zentao-login.js [--port=9224]` |\n| `scripts/zentao-get-bug.js` | 获取 Bug 详情 JSON | `node scripts/zentao-get-bug.js --ws=<WS> --bug-id=<id>` |\n| `scripts/zentao-download-files.js` | 下载 Bug 附件到本地 | `node scripts/zentao-download-files.js --ws=<WS> --bug-id=<id> --dir=<dir>` |\n| `scripts/zentao-build-comment.js` | Markdown 报告 → HTML 评论 | `node scripts/zentao-build-comment.js <report.md> [--out <output.html>]` |\n| `scripts/zentao-post-comment.js` | 发布 Bug 评论 | `node scripts/zentao-post-comment.js --ws=<WS> --bug-id=<id> --comment-file=<path>` |\n\n### 典型调用流程\n\n```\n1. node scripts/zentao-login.js --port=9224\n   → WS=ws://localhost:9224/devtools/browser/{id}, PID={pid}\n\n2. node scripts/zentao-get-bug.js --ws={WS} --bug-id=1432606\n   → JSON (stdout)\n\n3. node scripts/zentao-download-files.js --ws={WS} --bug-id=1432606 --dir=bugs/1432606\n   → 文件路径列表 (stdout)\n\n4. node scripts/zentao-build-comment.js bugs/1432606/report.md --out bugs/1432606/comment.html\n   → HTML 文件路径 (stdout)\n\n5. node scripts/zentao-post-comment.js --ws={WS} --bug-id=1432606 --comment-file=bugs/1432606/comment.html\n   → OK / FAIL\n```\n\n### login 脚本输出格式\n\n`zentao-login.js` 输出两行 key=value（可直接 shell `eval`）：\n\n```\nWS=ws://localhost:9224/devtools/browser/{browser-id}\nPID={chromium-pid}\n```\n\n其他脚本通过 `--ws` 参数复用会话。\n\n### 参数说明\n\n- `--ws`：login 脚本返回的 WebSocket endpoint\n- `--bug-id`：禅道 Bug ID（数字）\n- `--dir`：附件下载目标目录（自动创建）\n- `--comment-file`：评论文件路径（推荐，由 build-comment.js 生成的 HTML 文件）\n- `--comment`：评论内容（原始 HTML 字符串，脚本自动编码。备选方案，推荐用 `--comment-file`）\n- `--port`：CDP 调试端口（默认 9224）\n- `--zentao-url`：禅道实例地址（默认 `http://zentao.gxatek.com:20080`）\n\n## 本文件定位\n\nTOOLS.md 仅放环境依赖和脚本用法。完整 API 参考见 `references/zentao-api-reference.md`，流程规范见 `SKILL.md`。\n\nArchive v0.0.2: 11 files, 22748 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/zentao-build-comment.js (3874b), scripts/zentao-download-files.js (5995b), scripts/zentao-get-bug.js (4480b), scripts/zentao-login.js (5070b), scripts/zentao-post-comment.js (3579b), skill-card.md (2600b), SKILL.checklist.md (1881b), SKILL.md (15107b), TOOLS.md (2917b), _meta.json (138b)\n\nFile v0.0.2:SKILL.md\n\n---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个脚本操作禅道**，禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不做任何恢复操作。\n5. **分析完必须写评论**：步骤 4d 产出分析报告后，必须立即运行 `zentao-post-comment.js` 将报告贴到禅道 Bug 评论，再发飞书摘要。跳过评论 = 分析未完成。\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}\n```\n\n字段说明：\n- `name`：模块名称\n- `aliases`：模块别名列表（字符串数组），用于精确匹配。**匹配规则**：将 Bug 的 title、module.name、product.name 与所有模块的 name + aliases 做**子串匹配**（忽略大小写），任一命中即判定为该模块。此规则为硬规则，优先于 AI 主观判断\n- `code_dir`：模块本地代码仓库绝对路径\n- `commit_extract`：自然语言，告诉 AI 如何从日志提取 commit id\n- `analyzer`：`\"default\"` | `\"skill:技能名\"`。default 走通用 AI 分析流程；skill:xxx 委派给对应 Skill\n- `analyze_hint`：模块专属分析提示词（可选），无论哪种分析器都会传给分析器\n\n### 首次配置引导\n\n配置文件不存在时启动对话式引导。流程：\n\n1. 「请提供禅道的登录账号和密码（用于 Playwright 登录禅道。密码会存储在本地配置文件中，不会泄露）」\n2. 「你负责哪些模块？请列出模块名称（用逗号分隔，如：车机设置, 蓝牙模块, 语音助手）」\n3. 对每个模块依次询问：\n   - 「对于\"{模块名}\"模块，有哪些别名/关键词可以用来识别？（用逗号分隔，如：桌面卡片, systemui, 设置）」\n   - 「对于\"{模块名}\"模块，本地代码目录路径是什么？（请使用绝对路径）」\n   - 「对于\"{模块名}\"模块，日志中如何提取 commit id？请用自然语言描述提取规则」\n   - 「对于\"{模块名}\"模块，是否需要使用专用分析 Skill？（目前可用的 Skill：[列出]。输入 Skill 名或留空走默认分析）」\n   - 「对于\"{模块名}\"模块，有什么分析提示或重点关注方向？（可选，留空则用默认分析策略）」\n4. 「配置完成！请确认你已创建邮件收信规则：当发件人为 `zentao@syncore.space` 时，自动将邮件转发/分享到本 Bot 的对话中。」\n\n---\n\n## 分析流水线\n\n### 步骤 1：消息解析\n\n从消息内容提取禅道 Bug 链接，正则：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 步骤 2：重复分析检查\n\n> ⚠️ 此步骤是强制检查点，无论通过哪种触发方式（邮件转发或自然语言）进入分析流水线，必须先走步骤 2。已评论过的 Bug 绝对不允许直接进入后续步骤。\n\n1. 运行 `scripts/zentao-get-bug.js` 获取 Bug 详情（含历史评论，后续步骤复用）\n2. 检查历史评论中是否已有 `zentao.account` 配置账号的评论\n\n**已有我的评论**：飞书私聊询问「该 Bug 你已评论过，是否需要重新分析？（回复\"是\"或\"分析\"继续，回复\"否\"或\"取消\"跳过）」\n- 确认「是」→ 继续步骤 3\n- 确认「否」或 5 分钟内未回复 → 流程终止\n\n**没有我的评论**：直接继续步骤 3。\n\n### 步骤 3：模块分类\n\n**匹配规则（优先级从高到低）**：\n\n1. **硬别名匹配（优先）**：遍历配置中每个 module 的 `aliases` 数组，将每个别名与 Bug 的 `title`、`module.name`、`product.name` 做**子串匹配**（忽略大小写）。只要任一副本字段包含任一个别名（或 `name` 本身），即判定命中该模块。\n   - 例如：Bug标题含\"桌面卡片\"，配置别名中有\"桌面卡片\" → 直接命中\n   - ⚠️ 此规则是机械规则，不依赖 AI 判断，直接执行\n2. **AI 语义判断（兜底）**：硬别名未命中时，AI 综合判断 Bug 归属模块，对照配置文件 `modules` 列表\n\n**结果处理**：\n- **在范围**：继续步骤 4\n- **不在范围**：飞书私聊通知（Bug 标题、链接、AI 判断的模块归属），提醒模块确认和手动流转。流程结束\n- **置信度低**：飞书私聊通知（Bug 链接 + 关键信息），告知无法确定模块，请手动确认。流程结束\n\n### 步骤 4：深度分析\n\n#### 4a. 下载附件和日志\n运行 `scripts/zentao-download-files.js` 下载 Bug 所有附件到 `bugs/{bug_id}/`。（script 自动处理大文件分块传输，支持 160MB+ 附件）\n\n> ⚠️ 步骤 4a 完成后必须先执行 4b（确定 Bug 发生时间），再进入 4c。\n\n#### 4b. 确定 Bug 发生时间\n\n> ⚠️ 硬约束：Bug 发生时间必须从可靠来源直接获取，禁止猜测或间接推断。\n\n**获取优先级**：\n1. **Bug 描述文本**中明确写出的时间（如「17:33 复现」「12:05 发现」）\n2. **附件视频/截图**中可见的系统时间（状态栏、水印等），需打开查看\n3. **飞书询问用户**：以上均不可用时，私聊询问「该 Bug 发生的精确时间是什么？」\n\n**禁止行为**：\n- ❌ 用附件文件名中的时间戳猜测\n- ❌ 用 Bug 创建时间、最后修改时间间接推断\n- ❌ 用聊天消息转发时间、邮件接收时间推断\n- ❌ 任何不在上述优先级列表内的间接推演\n\n**时间用于**：\n- 日志分析：定位 Bug 发生时刻前后 ±5 分钟的日志片段\n- Git blame：确定相关代码变更时间线\n- 匹配历史评论中提到的复现时间\n\n#### 4c. 分支定位\n1. 读取下载的日志文件\n2. 按配置中 `commit_extract` 从日志提取 commit id\n3. `cd {code_dir}` → `git branch --contains <commit-id>` 确认 commit 在哪些分支上。结果写入分析报告的「分支信息」字段（格式：`分支名 | commit-id`）\n4. 同模块已有其他分析任务时，用 `git worktree add .claude/worktrees/bug-{bug_id}/ <commit-id>` 创建隔离工作区\n5. `git checkout <commit-id>`（进入 detached HEAD 是正常行为，分析完成后保持不动即可）+ `git submodule update --init --recursive`\n\n**commit id 提取失败**：飞书私聊通知（附带日志片段），流程终止。\n\n> ⚠️ 硬约束：只使用配置中 commit_extract 指定的提取规则，禁止 AI 自行更换搜索关键词（如换 TAG、换正则）。搜不到就是搜不到，不允许\"近似匹配\"或\"换成类似的 TAG 试试\"。\n> Self-Check：若在分析过程中进行了 commit_extract 规则以外的额外搜索，应立即停止、丢弃中间产物，回到步骤 4c 标准路径并报告提取失败。\n\n**commit id 不在任何分支**：飞书私聊通知（附带 commit id），流程终止\n\n> ⚠️ 硬约束：`git checkout <commit-id>` 后必须执行 `git submodule update --init --recursive`，确保所有 submodule 都已 checkout 到对应版本。未 checkout submodule 可能导致分析时缺少依赖代码、漏掉跨仓库 API 不一致问题。\n\n#### 4d. AI 综合深度分析\n\n历史评论已在步骤 2 获取，此处直接使用。\n\n根据 `analyzer` 字段：\n- `\"default\"`：AI 综合 Bug 详情 + 附件/日志 + 历史评论 + 本地代码分析\n- `\"skill:xxx\"`：委派给指定 Skill，传入分析上下文\n\n无论哪种方式，`analyze_hint` 都作为上下文传入。\n\n输出格式（Markdown，AI 直接产出此结构）：\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**：\n  ```lang\n  // 关键代码\n  ```\n- **判断依据**：（结合日志/历史评论/代码逻辑的推理过程）\n\n### 修复建议\n1. 具体修复方向（可操作步骤，非抽象建议）\n\n### 风险评估\n- **影响范围**：（哪些功能/模块受影响）\n- **严重程度**：（低/中/高/严重 + 理由）\n\n### 步骤 5：结果输出（双通道）\n\n1. **禅道评论**：\n   a. 将分析报告写入 `bugs/{bug_id}/report.md`（按步骤 4d 输出格式）\n   b. 运行 `node scripts/zentao-build-comment.js bugs/{bug_id}/report.md --out bugs/{bug_id}/comment.html` 生成 HTML\n   c. 运行 `node scripts/zentao-post-comment.js --ws=<wsEndpoint> --bug-id=<id> --comment-file=bugs/{bug_id}/comment.html` 发布（**必须用 `--comment-file`，禁止用 `--comment` 传 HTML 内容**）\n   d. ⚠️ 禁止手写临时 Playwright 脚本发布评论\n2. **飞书私聊**：简要摘要 + 禅道 Bug 链接\n\n### 步骤 6：清理\n\n分析完成后必须清理残留进程，避免占用系统资源：\n\n1. **杀掉 login 常驻进程（连带 Chrome）**：`taskkill /PID <login-PID> /F /T`，PID 来自 `zentao-login.js` 输出行 `PID=<value>`。`/T` 会连带终结 Chrome 子进程树\n2. **清理 git worktree**：`git worktree list` 检查是否有 `.claude/worktrees/bug-{bug_id}/` 残留，有则 `git worktree remove .claude/worktrees/bug-{bug_id}/`\n3. **检查残留脚本进程**：`Get-Process node` 检查是否还有 `zentao-*.js` 相关进程，有则 `taskkill /F /PID <pid>` 清理\n4. **确认清理完毕**：最终应只剩 OpenClaw 自身的 node 进程（gateway/worker），不应有其他 `zentao-*.js` 残留\n\n> ⚠️ 注意：不要杀掉 OpenClaw 自身的 node 进程（gateway/worker），只清理 `zentao-*.js` 和 Chrome headless 相关进程。\n\n---\n\n## 并发处理\n\n- **不同模块**：代码目录不同，全部并行处理\n- **同一模块同时分析多个 Bug 时**：用 `git worktree` 为每个 Bug 创建隔离工作区，分析完成后 `git worktree remove` 清理\n\n---\n\n## 禅道交互方式\n\n> ⚠️ 企业版 12.1 不支持 Bearer Token 认证（`POST /api.php/v1/tokens` 不可用），所有读写操作统一走 Playwright。\n\n### 🔴 铁律：单次 Playwright 会话\n\n**一个 Bug 的分析全程只允许启动一次 Playwright 浏览器**。登录后所有操作（读详情、下载附件、写评论）复用同一会话，禁止：\n\n- ❌ 分多个脚本文件各启动一次 Playwright\n- ❌ 中途关闭浏览器再重新登录\n- ❌ 写评论时用新的浏览器实例\n\n### 🔴 铁律：脚本优先，禁止手写临时 Playwright 脚本\n\n**禅道交互只允许使用 `scripts/` 目录下的 5 个固定脚本**：\n\n| 脚本 | 用途 | 关键参数 |\n|------|------|----------|\n| `zentao-login.js` | 登录 | `--port`（默认 9224）|\n| `zentao-get-bug.js` | 获取 Bug 详情 | `--ws`、`--bug-id` |\n| `zentao-download-files.js` | 下载附件 | `--ws`、`--bug-id`、`--dir` |\n| `zentao-build-comment.js` | Markdown → HTML 评论 | `<report.md> [--out <output.html>]` |\n| `zentao-post-comment.js` | 发布评论 | `--ws`、`--bug-id`、`--comment-file=<path>`（推荐）或 `--comment`（原始 HTML）|\n\n**禁止行为**：\n- ❌ 手写临时 `post_comment.js`、`check_bug.js`、`debug_login.js` 等任何 Playwright 脚本\n- ❌ 在 `bugs/{bug_id}/` 目录下创建任何 `.js` 文件\n- ❌ 用 `page.evaluate`、`page.fill`、`page.click` 等 Playwright API 绕过已有脚本\n\n**遇到脚本报错时的正确处理方式**：\n1. 先读脚本源码，理解它依赖的输入（WS endpoint、参数格式等）\n2. 修复输入条件（如重新登录获取有效 WS endpoint），而不是绕过脚本\n3. 如果脚本本身有 bug，修复脚本源码（`scripts/` 目录下），让修复对所有后续分析生效\n\n---\n\n## 边界情况处理\n\n| 场景 | 处理 |\n|------|------|\n| 不含禅道链接 | 「未识别到有效的禅道缺陷链接，请确认消息内容」 |\n| 链接解析失败 | 「无法解析该链接，请确认是否正确转发」 |\n| 禅道 API 请求失败（登录失效/会话过期） | 「无法访问禅道，请检查连接和登录状态」 |\n| 模块分类置信度低 | 飞书通知：Bug 链接+关键信息，请手动确认 |\n| 模块不在负责范围 | 飞书通知：Bug 归属 + 提醒手动流转 |\n| commit id 提取失败 | 飞书通知：日志片段，请手动确认分支 |\n| commit id 不在任何分支 | 飞书通知：commit id，请手动确认 |\n| 附件/日志下载失败 | 降级：仅基于 Bug 描述+历史评论+代码分析，评论注明「未能获取附件」，飞书通知 |\n| 本地代码目录不存在 | 降级：跳过代码分析，仅日志+附件+评论，飞书通知检查配置 |\n| 分析过程中断或超时 | 飞书通知进度和失败原因，不留半截评论 |\n| 用户 5 分钟内未回复重新分析确认 | 默认不重新分析，流程终止 |\n| 分析过程中 git worktree 冲突 | 清理残留 worktree 后重试；仍失败则飞书通知 |\n\n---\n\n## 范围约束\n\n- 不自动填写指派人或流转状态\n- 不自动生成修复代码\n- 不做缺陷趋势统计或报表\n- 当前只服务单一用户\n\nFile v0.0.2:_meta.json\n\n{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"0.0.2\",\n  \"publishedAt\": 1783582092083\n}\n\nFile v0.0.2:references/zentao-api-reference.md\n\n# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |\n\nFile v0.0.2:skill-card.md\n\n## Description: <br>\nAnalyzes Zentao bug reports from Feishu messages, classifies affected modules, locates relevant branches and commits, reviews local code and logs, then posts a s\n\nArchive v0.0.1: 11 files, 22747 bytes\n\nFiles: references/zentao-api-reference.md (2306b), scripts/zentao-build-comment.js (3874b), scripts/zentao-download-files.js (5995b), scripts/zentao-get-bug.js (4480b), scripts/zentao-login.js (5070b), scripts/zentao-post-comment.js (3579b), skill-card.md (2696b), SKILL.checklist.md (1881b), SKILL.md (15127b), TOOLS.md (2917b), _meta.json (138b)","readmeExcerpt":"Skill: zentao-bug-analyzer Owner: yeah526 Summary: 禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。 Tags: latest:1.1.0 Version history: v1.1.0 | 2026-07-31T03:34:14.485Z | user **zentao-bug-analyzer v1.1.0** - 增加对 ffmpeg 环境依赖的自动检查，首次运行前强制校验，缺失时提示安装 npm 版本依赖。 - 新增用于视频附件抽帧与图片视觉分析的脚本和工具模块（scripts/zentao-extract-frames.js, scripts/zentao-utils.js）。 - 明确规定所有日志/文件操作必须用 Node.js（解决 Windows PowerShell 输出中文乱码问题）。","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"node -e \"const ff=require('@ffmpeg-installer/ffmpeg');const{execSync}=require('child_process');execSync(`\\\"${ff.path}\\\" -version`);console.log('ffmpeg OK')\""},{"language":"jsonc","snippet":"{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek.com:20080\",\n    \"account\": \"wyhe\",\n    \"password\": \"你的禅道登录密码\"\n  },\n  \"notify\": {\n    \"feishu_open_id\": \"飞书私聊通知目标用户 Open ID，步骤 3/4b 等所有飞书通知场景使用\"\n  },\n  \"auto_comment\": true,\n  \"modules\": [\n    {\n      \"name\": \"车机设置\",\n      \"aliases\": [\"桌面卡片\", \"设置\", \"systemui\", \"SystemUI\"],\n      \"code_dir\": \"D:/code/car-settings\",\n      \"commit_extract\": \"日志中以 'Build commit:' 开头的那一行，取后面的 8 位 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"重点关注桌面卡片相关代码，常见问题是侧滑返回时的 Activity 生命周期处理\"\n    },\n    {\n      \"name\": \"蓝牙模块\",\n      \"aliases\": [\"蓝牙\", \"BT\", \"bluetooth\", \"bt-stack\"],\n      \"code_dir\": \"D:/code/bt-stack\",\n      \"commit_extract\": \"日志里搜索 'git_hash='，取等号后面的完整 hash\",\n      \"analyzer\": \"default\",\n      \"analyze_hint\": \"蓝牙相关缺陷通常与连接状态机有关，优先检查 BluetoothManager 的状态流转\"\n    }\n  ]\n}"},{"language":"bash","snippet":"node scripts/zentao-extract-frames.js --video=<视频路径> --dir=bugs/{bug_id}/frames --mode=coarse"},{"language":"bash","snippet":"node scripts/zentao-extract-frames.js --video=<视频路径> --dir=bugs/{bug_id}/frames --mode=fine"},{"language":"bash","snippet":"node -e \"const zlib=require('zlib');const fs=require('fs');const buf=fs.readFileSync('<log.gz>');zlib.gunzip(buf,(e,r)=>{if(e){console.error(e);return}const s=r.toString('utf8');/* 搜索 s */})\""},{"language":"markdown","snippet":"### Bug 发生时间\n- **采纳时间**：yyyy-MM-dd HH:mm (Asia/Shanghai)\n- **时间来源**：视频 sec_0060.png 右上角状态栏\n- **证据文件**：frames/sec_0060.png\n- **置信度**：高/中/低\n\n### 分支信息\n- **commit**: `abc12345`\n- **分支**: `branch/name`\n\n### 操作历史（如有）\n- **状态流转**：active → resolved → closed\n- **关键变更**：指派人 / 优先级 / 严重程度的变更记录\n\n### 根因定位\n- **文件**：`path/to/file.ext:行号`\n- **代码片段**："}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: zentao-bug-analyzer\ndescription: \"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。\"\n---\n\n# 禅道缺陷自动分析 (zentao-bug-analyzer)\n\n禅道实例：`http://zentao.gxatek.com:20080/`（企业版 12.1）\n\n## 环境依赖\n\n本 Skill 依赖以下工具，**环境不具备时立即停止流程并飞书通知用户**，禁止用替代品硬撑：\n\n| 工具 | 用途 | 安装方式 | 验证命令 |\n|------|------|----------|----------|\n| **ffmpeg** | 视频附件抽帧（步骤 4b） | `npm install @ffmpeg-installer/ffmpeg ffprobe-static --no-save` | `node -e \"console.log(require('@ffmpeg-installer/ffmpeg').path)\"` |\n| **Node.js zlib** | 解压 Android logcat `.gz` 日志（步骤 4c） | Node.js 内置，无需安装 | `node -e \"require('zlib')\"` |\n| **Playwright** | 禅道交互（5 个 scripts） | 已有 | — |\n| **视觉模型** | 读取截图/视频帧中的系统时间 + 判断画面中 BUG 现象是否可见（步骤 4b 子步骤 3、4） | 由 AI 代理运行环境提供 | — |\n\n**禁止的替代方案**：\n- ❌ 用 winget 装系统级 ffmpeg（实测 `winget install Gyan.FFmpeg` 超时不可靠）\n- ❌ 用 PowerShell `tar`、`System.IO.Compression.GZipStream` 或 .NET 工具解压 logcat `.gz`（兼容性 bug，会丢失大量日志）\n- ❌ 用 PowerShell/.NET 替代品处理视频（参考 4c 关于 .NET 解压 bug 的教训）\n\n> ⚠️ **视觉模型不可用时**：步骤 4b 子步骤 3、4 无法读取截图/视频帧中的系统时间，降级为跳过图片/视频时间提取，直接进入子步骤 5 飞书询问用户。\n\n**首次运行检查**：执行任何分析前先验证 ffmpeg 可用：\n```bash\nnode -e \"const ff=require('@ffmpeg-installer/ffmpeg');const{execSync}=require('child_process');execSync(`\\\"${ff.path}\\\" -version`);console.log('ffmpeg OK')\"\n```\n失败 → 飞书私聊通知「ffmpeg 环境依赖缺失，请运行 `cd {workspace} && npm install @ffmpeg-installer/ffmpeg ffprobe-static --no-save` 后重试」，流程终止。\n\n## ⚠️ 执行守则（最高优先级）\n\n> 🔴 分析前必须先读完 `SKILL.checklist.md` 的全部检查项，每条逐项完成。\n\n1. **只用 scripts/ 下的 5 个可执行脚本操作禅道**（不含 `zentao-utils.js` 工具模块），禁止手写临时 Playwright 文件\n2. **一个 Bug 只启动一次浏览器**，所有操作复用同一 WS endpoint\n3. **脚本报错 = 诊断脚本的输入条件**（WS 是否有效？参数是否正确？），不是另起炉灶的理由\n4. **分析完成后保持仓库不动**：`git checkout <commit-id>` 分析完后不切回原分支（非 worktree 场景）。worktree 场景按步骤 6 清理。\n5. **分析完输出报告**：步骤 4d 产出分析报告后，根据 `auto_comment` 配置决定是否评论禅道：\n   - `auto_comment === true` 或未配置（默认视为 `true`）：运行 `zentao-post-comment.js` 评论 + 飞书摘要\n   - `auto_comment === false`：仅飞书摘要，不评论禅道\n6. **环境依赖缺失立即停止**：ffmpeg / Node.js zlib / Playwright 任一不可用 → 飞书通知用户安装，禁止用替代品硬撑（详见「环境依赖」章节）\n7. **Windows 读取中文文件必须用 Node.js，禁止 PowerShell `Get-Content` / `Select-String`**：\n   - Windows PowerShell 控制台默认 GBK（CP936）编码，读取 UTF-8 中文文件直接显示乱码\n   - ❌ 禁止：`Get-Content xxx.txt -First 5`、`Select-String -Path xxx.txt -Pattern \"中文\"`、`Get-ChildItem | Where-Object Name -like '*.中文.txt'`\n   - ✅ 必须：`node -e \"console.log(require('fs').readFileSync('xxx.txt','utf8').slice(0,500))\"`\n   - 涉及场景：读取日志中的中文 TAG、中文注释、报告 review 时的中文文件名/路径、PowerShell 调用 `node script.js --video=中文.mp4` 时加 `--` 分隔符规避 argv 解析 bug\n   - 例外：`Get-Content` 加上 `-Encoding UTF8` 参数可以读 UTF-8（输出仍可能乱码，但不会被识别为 ANSI）；推荐一律走 Node.js\n\n## 触发方式\n\n### 方式一：邮件转发触发\n飞书 Bot 收到包含禅道 Bug 链接的消息时自动触发。\n\n正则模式：`zentao\\.gxatek\\.com:20080/bug-view-(\\d+)\\.html`\n\n### 方式二：自然语言触发\n用户直接在飞书对话中：\n- 发送禅道 Bug 链接\n- 「帮我分析我名下所有未解决的缺陷」\n- 「分析最近 3 天指派给我的严重缺陷」\n\n**批量分析**：批量触发时，先通过 Playwright 会话查询 Bug 列表，每个 Bug 独立走完整流水线。不同 Bug 按第三章并发规则处理。\n\n**无有效链接时**：飞书私聊回复「未识别到有效的禅道缺陷链接，请确认消息内容」。\n\n---\n\n## 配置文件\n\n依赖 `{workspace}/bug-analyzer-config.json`。\n\n```jsonc\n{\n  \"zentao\": {\n    \"url\": \"http://zentao.gxatek"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7e1qtrtwmpapjt5hy2e9s4998a6wgq\",\n  \"slug\": \"zentao-bug-analyzer\",\n  \"version\": \"1.1.0\",\n  \"publishedAt\": 1785468854485\n}"},{"path":"references/zentao-api-reference.md","content":"# 禅道 API 参考\n\n> 企业版 12.1 实例：`http://zentao.gxatek.com:20080/`\n> 本文件为 API 字段/参数/错误码参考。实现示例见 `TOOLS.md`。\n\n## 认证方式\n\n企业版 12.1 不支持 Bearer Token（`POST /api.php/v1/tokens` 不可用）。所有操作统一通过 Playwright 登录获取 session cookie，后续请求在 `page.evaluate` 中用 `credentials: 'include'` 发起。\n\n## Bug 详情\n\n```\nGET /api.php/v1/bugs/{bugId}\n```\n\n返回关键字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| id | int | Bug ID |\n| title | string | 标题（HTML） |\n| description | string | 详细描述（HTML） |\n| severity | int | 严重程度 1~4 |\n| priority | int | 优先级 1~4 |\n| product | object | `{ id, name }` |\n| project | object | `{ id, name }` |\n| module | object | `{ id, name }` |\n| status | string | active / resolved / closed |\n| openedBy | object | `{ id, account, name }` |\n| assignedTo | object | `{ id, account, name }` |\n| steps | string | 复现步骤（HTML） |\n| files | array | 附件列表 `[{ id, title, extension, size }]` |\n| comments | array | 评论列表 `[{ id, author, comment, date }]`，author 为 account 字符串 |\n\n## Bug 列表\n\n```\nGET /api.php/v1/bugs?product={productId}&assignedTo={account}&limit=20&status=active\n```\n\n常用过滤参数：\n\n| 参数 | 说明 |\n|------|------|\n| product | 产品 ID |\n| assignedTo | 指派人账号 |\n| status | active / resolved / closed |\n| severity | 1~4 |\n| limit | 分页条数 |\n| offset | 分页偏移 |\n\n## 产品列表\n\n```\nGET /api.php/v1/products\n```\n\n## 写评论\n\n通过 `scripts/zentao-post-comment.js` 完成。POST `{zentao_url}/action-comment-bug-{bugId}.html`，Content-Type: `application/x-www-form-urlencoded`，body: `comment={URL-encoded HTML}`。传入原始 HTML 即可，脚本自动编码。\n\n## 附件下载\n\n附件 URL: `{zentao_url}/file-download-{fileId}.json`。下载通过 `scripts/zentao-download-files.js` 完成（内部使用 page.evaluate + exposeFunction 分块传输，支持 160MB+ 大文件）。\n\n## 错误码\n\n| 状态码 | 含义 | 处理 |\n|--------|------|------|\n| 200 | 成功 | — |\n| 401 | Session 过期 | 重新 Playwright 登录 |\n| 404 | 资源不存在 | 通知用户检查 ID |\n| 500 | 服务端错误 | 通知用户检查禅道状态 |"},{"path":"scripts/package.json","content":"{\n  \"name\": \"zentao-bug-analyzer-scripts\",\n  \"private\": true,\n  \"description\": \"禅道缺陷自动分析 - Playwright 脚本集\",\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"dependencies\": {\n    \"playwright\": \"^1.40.0\"\n  },\n  \"devDependencies\": {\n    \"@ffmpeg-installer/ffmpeg\": \"^1.1.0\",\n    \"ffprobe-static\": \"^3.1.0\"\n  }\n}"},{"path":"skill-card.md","content":"## Description:\n\nAnalyzes ZenTao bug reports from Feishu-triggered links by gathering bug details, attachments, logs, local code context, and producing a root-cause report with optional ZenTao and Feishu updates.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[yeah526](https://clawhub.ai/user/yeah526)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and QA engineers use this skill to triage ZenTao defects, identify the affected module and branch, inspect logs and attachments, and prepare a concise root-cause analysis. It can also format the report for ZenTao comments and send a Feishu summary when configured.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill requires sensitive ZenTao credentials and broad local/browser authority.\n\nMitigation: Use a low-privilege ZenTao account, HTTPS, isolated disposable worktrees or containers, and pinned dependencies; do not store real passwords in workspace config until credential handling and CDP/browser exposure are fixed.\n\nRisk: Automatic ZenTao comments could publish incomplete or incorrect analysis.\n\nMitigation: Review generated reports before posting, and set auto_comment to false when manual approval is required.\n\nRisk: Bug analysis can modify local repository state through checkout or worktree operations.\n\nMitigation: Run analysis in disposable or isolated worktrees and verify cleanup of worktrees, browser sessions, and ZenTao helper processes after each run.\n\n## Reference(s):\n\n- [ZenTao API Reference](artifact/references/zentao-api-reference.md)\n- [ClawHub Skill Page](https://clawhub.ai/yeah526/skills/zentao-bug-analyzer)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown reports with shell command guidance, JSON metadata, HTML comment output, and Feishu-ready text summaries]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May write local bug artifacts such as downloaded attachments, extracted video frames, time metadata, reports, and comment HTML.]\n\n## Skill Version(s):\n\n1.1.0 (source: server release metadata; target metadata agrees)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。 Skill: zentao-bug-analyzer Owner: yeah526 Summary: 禅道缺陷自动分析：从飞书消息解析Bug链接，自动模块分类+分支定位+代码分析，Playwright评论+飞书通知双通道输出。 Tags: latest:1.1.0 Version history: v1.1.0 | 2026-07-31T03:34:14.485Z | user **zentao-bug-analyzer v1.1.0** - 增加对 ffmpeg 环境依赖的自动检查，首次运行前强制校验，缺失时提示安装 npm 版本依赖。 - 新增用于视频附件抽帧与图片视觉分析的脚本和工具模块（scripts/zentao-extract-frames.js, scripts/zentao-utils.js）。 - 明确规定所有日志/文件操作必须用 Node.js（解决 Windows PowerShell 输出中文乱码问题）。","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1115,"uniquenessScore":52,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:58:05.692Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T13:58:05.692Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T17:35:38.479Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}