[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M77RDMF31WV81MBMCPXDCP2G":3,"skill-same:01M77RDMF31WV81MBMCPXDCP2G":45},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":14,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":29,"updatedAt":30,"install":31,"resources":44},"01M77RDMF31WV81MBMCPXDCP2G","pr-verify",null,"PR Verification & Merge: verify bot:ready-to-merge PRs with impact analysis, test supplementation, and one-click merge.\nUse when: (1) User says \"\u002Fpr-verify\", (2) User wants to verify and merge ready PRs.","finewood2008\u002Fcentaurai-team","finewood2008","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F212194470?v=4","01M75HGRZJ31P9W3T90VHFS1X8","Finewood","01M77RC50EAM5Q4E71MX8JRG7P",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team\u002Fblob\u002Fteam\u002F.claude\u002Fskills\u002Fpr-verify\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: pr-verify\ndescription: |\n  PR Verification & Merge: verify bot:ready-to-merge PRs with impact analysis, test supplementation, and one-click merge.\n  Use when: (1) User says \"\u002Fpr-verify\", (2) User wants to verify and merge ready PRs.\n---\n\n# PR Verification & Merge\n\nInteractive workflow to verify `bot:ready-to-merge` PRs — displays impact analysis, supplements tests, and provides one-click merge with confidence scoring.\n\n**Announce at start:** \"I'm using pr-verify skill to verify and merge ready PRs.\"\n\n## Usage\n\n```\n\u002Fpr-verify [pr_number]\n```\n\n`$ARGUMENTS` may contain an optional PR number.\n\n- Without argument: display list of `bot:ready-to-merge` PRs for selection\n- With argument: skip list, go directly to that PR number\n\n---\n\n## Configuration\n\n```\nPR_DAYS_LOOKBACK: env var (default: 7) — lookback window for PR list\nCRITICAL_PATH_PATTERN: env var — pattern to detect critical file paths\n```\n\n**REPO** is detected automatically at runtime — do not hardcode it:\n\n```bash\nREPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')\n```\n\n**Worktree path:** always `\u002Ftmp\u002Faionui-verify-\u003CPR_NUMBER>` — never use `\u002Ftmp\u002Faionui-pr-*` (reserved for pr-automation\u002Fpr-fix).\n\n---\n\n## Steps\n\n### Step 1 — PR List Display\n\nParse `$ARGUMENTS` for an optional PR number.\n\n**If a PR number is provided:** skip the list, jump directly to Step 2 with that PR number.\n\n**If no argument provided:** query `bot:ready-to-merge` PRs from the last `PR_DAYS_LOOKBACK` days (default 7):\n\n```bash\nDAYS=${PR_DAYS_LOOKBACK:-7}\ngh pr list \\\n  --state open \\\n  --label \"bot:ready-to-merge\" \\\n  --search \"created:>=$(date -v-${DAYS}d '+%Y-%m-%d' 2>\u002Fdev\u002Fnull || date -d \"${DAYS} days ago\" '+%Y-%m-%d') -is:draft\" \\\n  --json number,title,labels,changedFiles,additions,deletions,headRefName,baseRefName,commits,createdAt,author \\\n  --limit 50\n```\n\nIf the result is empty: display `没有找到 bot:ready-to-merge 的 PR。` and exit.\n\nFor each PR, infer the type from the first commit message prefix:\n\n| Prefix pattern | Type     |\n| -------------- | -------- |\n| `fix(`         | bugfix   |\n| `feat(`        | feature  |\n| `refactor(`    | refactor |\n| `chore(`       | chore    |\n| `docs(`        | docs     |\n| `perf(`        | perf     |\n| `test(`        | test     |\n| other          | misc     |\n\nDisplay as a numbered table:\n\n```\n# | PR   | 标题                              | 变更          | 类型\n--|------|-----------------------------------|---------------|--------\n1 | #123 | fix(auth): handle token expiry    | +45 \u002F -12     | bugfix\n2 | #124 | feat(ui): add dark mode toggle    | +230 \u002F -18    | feature\n```\n\nThen prompt:\n\n> 请输入序号选择 PR，或输入 q 退出：\n\n- User inputs a number → use that PR\n- User inputs `q` → exit\n\nSave the selected PR number as `PR_NUMBER` for all subsequent steps.\n\n---\n\n### Step 2 — Pre-flight Checks\n\nRun three checks in order. A failure in any check presents the user with an action choice.\n\n#### Check 1 — New Commits Since Ready-to-Merge Label\n\n```bash\n# Time when bot:ready-to-merge label was last set (infer from bot comment)\nLABEL_SET_TIME=$(gh pr view $PR_NUMBER --json comments \\\n  --jq '[.comments[] | select(.body | test(\"\u003C!-- pr-automation-bot -->\") and (test(\"bot:ready-to-merge\") or test(\"已自动 review\") or test(\"已自动修复\")))] | last | .createdAt \u002F\u002F \"\"')\n\nLATEST_COMMIT_TIME=$(gh pr view $PR_NUMBER --json commits \\\n  --jq '.commits | last | .committedDate')\n```\n\nIf `LATEST_COMMIT_TIME > LABEL_SET_TIME` (new commits after the label was set), prompt:\n\n> ⚠️ 该 PR 在标记 bot:ready-to-merge 后有新提交（最新提交：`\u003CLATEST_COMMIT_TIME>`，标签时间：`\u003CLABEL_SET_TIME>`）。\n> 建议重新 review 后再合并。请选择：\n> r - 移除 bot:ready-to-merge 标签，触发重新 review\n> c - 忽略并继续验证\n\n- `r` → remove `bot:ready-to-merge` label:\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\"\n  ```\n  Display `已移除标签，PR 将在下一轮自动化中重新 review。` and return to list (Step 1).\n- `c` → continue to Check 2.\n\n#### Check 2 — CI Status\n\n```bash\ngh pr view $PR_NUMBER --json statusCheckRollup \\\n  --jq '.statusCheckRollup[] | {name: .name, status: .status, conclusion: .conclusion}'\n```\n\nRequired jobs: `Code Quality`, `Unit Tests (ubuntu-latest)`, `Unit Tests (macos-14)`, `Unit Tests (windows-2022)`, `Coverage Test`, `i18n-check`\n\nInformational exclusions: `codecov\u002Fpatch` and `codecov\u002Fproject` are informational — exclude them from all failure checks.\n\n| Condition                                                | Action              |\n| -------------------------------------------------------- | ------------------- |\n| All required jobs SUCCESS, no non-informational failures | Continue to Check 3 |\n| Any required job QUEUED or IN_PROGRESS                   | Prompt (see below)  |\n| Any non-informational job FAILURE or CANCELLED           | Prompt (see below)  |\n\n**CI still running prompt:**\n\n> ⏳ 以下 CI job 尚未完成：[job 列表]\n> 请选择：\n> w - 等待 CI 完成后继续（推出，请稍后重新运行）\n> c - 忽略，继续验证\n\n- `w` → exit\n- `c` → continue to Check 3\n\n**CI failed prompt:**\n\n> ❌ 以下 CI job 未通过：[job 列表及结论]\n> 请选择：\n> s - 跳过此 PR\n> c - 忽略失败，继续验证\n\n- `s` → remove `bot:ready-to-merge` label (let pr-automation re-process next round), return to list (Step 1):\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\"\n  ```\n- `c` → continue to Check 3\n\n#### Check 3 — Merge Conflicts\n\n```bash\ngh pr view $PR_NUMBER \\\n  --json mergeable,mergeStateStatus,headRefName,baseRefName \\\n  --jq '{mergeable, mergeStateStatus, head: .headRefName, base: .baseRefName}'\n```\n\n| `mergeable`   | Action                                                                 |\n| ------------- | ---------------------------------------------------------------------- |\n| `MERGEABLE`   | Continue to Step 3                                                     |\n| `UNKNOWN`     | Skip this PR (return to list), log: `mergeability unknown, will retry` |\n| `CONFLICTING` | Attempt auto-merge (see below)                                         |\n\n**Auto-merge attempt on conflict:**\n\n> **Why merge instead of rebase?** Since we squash-merge all PRs, the intermediate commit\n> history is irrelevant. `git merge` produces exactly the conflicts GitHub shows (one pass\n> over the final diff), while `git rebase` replays each commit individually, often creating\n> extra conflicts in files that GitHub reports as clean. Always use merge for conflict\n> resolution in this workflow.\n\n```bash\nREPO_ROOT=$(git rev-parse --show-toplevel)\nWORKTREE_DIR=\"\u002Ftmp\u002Faionui-verify-${PR_NUMBER}\"\n\n# Clean up any stale worktree\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n\n# Detect fork vs same-repo PR\nHEAD_OWNER=$(gh pr view $PR_NUMBER --json headRepositoryOwner --jq '.headRepositoryOwner.login')\nREPO_OWNER=$(gh repo view --json owner --jq '.owner.login')\nIS_FORK=$( [ \"$HEAD_OWNER\" != \"$REPO_OWNER\" ] && echo true || echo false )\n\n# Fetch PR head into a named ref (avoids FETCH_HEAD overwrite)\ngit fetch origin pull\u002F${PR_NUMBER}\u002Fhead:refs\u002Fpr\u002F${PR_NUMBER}\ngit worktree add \"$WORKTREE_DIR\" refs\u002Fpr\u002F${PR_NUMBER} --detach\n\nln -sf \"$REPO_ROOT\u002Fnode_modules\" \"$WORKTREE_DIR\u002Fnode_modules\"\n\ncd \"$WORKTREE_DIR\"\ngit fetch origin \u003Cbase_branch>\ngit merge origin\u002F\u003Cbase_branch> --no-edit\n```\n\nIf merge **succeeds** (no conflicts):\n\n```bash\n# Determine push target\nif [ \"$IS_FORK\" = \"true\" ]; then\n  FORK_URL=\"https:\u002F\u002Fgithub.com\u002F${HEAD_OWNER}\u002F$(gh repo view --json name --jq '.name').git\"\n  git remote add fork-target \"$FORK_URL\" 2>\u002Fdev\u002Fnull || true\n  git fetch fork-target \u003Chead_branch>\n  git push fork-target HEAD:refs\u002Fheads\u002F\u003Chead_branch> --force-with-lease\nelse\n  git push origin HEAD:refs\u002Fheads\u002F\u003Chead_branch> --force-with-lease\nfi\n\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n\ngh pr merge $PR_NUMBER --squash --auto\n```\n\nDisplay `已自动解决冲突并推送，PR 已设置 auto-merge，等待 CI 通过后自动合并。` and skip to next PR (return to Step 1).\n\nIf merge **has conflicts**, attempt manual resolution:\n\nRead each conflicting file and resolve the conflicts by understanding both sides of the change. After resolving all conflicts:\n\n```bash\ncd \"$WORKTREE_DIR\"\ngit add \u003Cresolved_files>\ngit commit --no-edit\n```\n\nIf resolution succeeds → push (same fork-aware logic as above) and set `--squash --auto`.\n\nIf resolution fails or conflicts are too complex:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nPrompt:\n\n> ❌ 合并冲突无法自动解决。请选择：\n> m - 提示作者手动解决冲突\n> s - 跳过此 PR\n> r - 标记为 bot:needs-human-review\n\n- `m` → post comment to PR:\n\n  ```bash\n  gh pr comment $PR_NUMBER --body \"\u003C!-- pr-verify-bot -->\n\n  ## 合并冲突（无法自动解决）\n\n  本 PR 与目标分支存在冲突，无法自动解决。请手动 merge 或 rebase 后重新 push：\n\n  \\`\\`\\`bash\n  git fetch origin\n  git merge origin\u002F\u003Cbase_branch>\n  # 解决冲突后\n  git push\n  \\`\\`\\`\"\n  ```\n\n  Then add label:\n\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\" --add-label \"bot:needs-rebase\"\n  ```\n\n  Return to list (Step 1).\n\n- `s` → add `bot:needs-rebase` label and comment, return to list (Step 1):\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\" --add-label \"bot:needs-rebase\"\n  gh pr comment $PR_NUMBER --body \"\u003C!-- pr-verify-bot -->\n  PR 存在合并冲突，无法自动解决。请作者手动解决后重新 push。\"\n  ```\n- `r` → add label and return to list:\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\" --add-label \"bot:needs-human-review\"\n  ```\n  Return to list (Step 1).\n\n---\n\n### Step 3 — Review Summary Display\n\nFetch and display a concise summary of the existing review.\n\n```bash\n# Fetch review comment(s)\ngh pr view $PR_NUMBER --json comments \\\n  --jq '[.comments[] | select(.body | startswith(\"\u003C!-- pr-review-bot -->\"))] | last | .body'\n```\n\nParse from the review comment:\n\n- **结论** (APPROVED \u002F CONDITIONAL \u002F review conclusion line)\n- **问题数量** per severity level (CRITICAL \u002F HIGH \u002F MEDIUM \u002F LOW)\n- If a `\u003C!-- pr-fix-verification -->` comment exists, also parse fix results\n\n```bash\n# Fetch fix verification comment if present\ngh pr view $PR_NUMBER --json comments \\\n  --jq '[.comments[] | select(.body | startswith(\"\u003C!-- pr-fix-verification -->\"))] | last | .body'\n```\n\nFetch changed files:\n\n```bash\ngh pr view $PR_NUMBER --json files \\\n  --jq '.files[] | {path: .path, additions: .additions, deletions: .deletions, status: .changeType}'\n```\n\nCheck critical path:\n\n```bash\nif [ -n \"$CRITICAL_PATH_PATTERN\" ]; then\n  CRITICAL_FILES=$(gh pr view $PR_NUMBER --json files \\\n    --jq '[.files[].path]' | jq -r '.[]' | grep -E \"$CRITICAL_PATH_PATTERN\" || true)\n  [ -n \"$CRITICAL_FILES\" ] && HAS_CRITICAL_PATH=true || HAS_CRITICAL_PATH=false\nelse\n  HAS_CRITICAL_PATH=false\n  CRITICAL_FILES=\"\"\nfi\n```\n\nDisplay concise summary:\n\n```\n=== PR #\u003CPR_NUMBER>: \u003C标题> ===\n\n作者: \u003Cauthor>  |  基分支: \u003Cbase>  |  变更: +\u003Cadd> \u002F -\u003Cdel>\n\nReview 结论: ✅ 批准合并 \u002F ⚠️ 有条件批准 \u002F ❌ 需要修改\n问题数量: CRITICAL(0) HIGH(1) MEDIUM(2) LOW(3)\n修复状态: ✅ 已修复 2 个 \u002F ⏭️ 驳回 1 个  [若有 pr-fix 报告]\n\n变更文件 (N 个):\n  src\u002Frenderer\u002Ffeatures\u002Fauth\u002FAuthModal.tsx  +45 \u002F -12\n  src\u002Fcommon\u002Futils\u002Ftoken.ts                 +23 \u002F -5\n  ...\n\n核心路径: ⚠️ 涉及核心路径文件  [若 HAS_CRITICAL_PATH=true]\n           src\u002Fprocess\u002Fchannels\u002Fauth.ts\n```\n\nThen prompt:\n\n> d - 查看完整 review 报告 | 回车继续影响分析\n\n- `d` → display full review comment text, then re-show this prompt\n- Enter → continue to Step 4\n\nIf no `\u003C!-- pr-review-bot -->` comment found, display:\n\n> ⚠️ 未找到 review 报告。该 PR 可能未经过自动化 review 流程。\n\nAnd continue to Step 4.\n\n---\n\n### Step 4 — Impact Analysis + Test Supplementation\n\n#### 4a — Worktree Setup\n\nCreate worktree at `\u002Ftmp\u002Faionui-verify-\u003CPR_NUMBER>` (reuse if already created in Step 2):\n\n```bash\nREPO_ROOT=$(git rev-parse --show-toplevel)\nWORKTREE_DIR=\"\u002Ftmp\u002Faionui-verify-${PR_NUMBER}\"\n\n# Reuse existing worktree if present, otherwise create\nif [ ! -d \"$WORKTREE_DIR\" ]; then\n  # Use a named ref to avoid FETCH_HEAD being overwritten by subsequent fetches\n  git fetch origin pull\u002F${PR_NUMBER}\u002Fhead:refs\u002Fpr\u002F${PR_NUMBER}\n  git worktree add \"$WORKTREE_DIR\" refs\u002Fpr\u002F${PR_NUMBER} --detach\n  ln -sf \"$REPO_ROOT\u002Fnode_modules\" \"$WORKTREE_DIR\u002Fnode_modules\"\nfi\n```\n\n#### 4b — Impact Analysis\n\nParse changed files from the worktree:\n\n```bash\ncd \"$WORKTREE_DIR\"\nBASE_REF=$(gh pr view $PR_NUMBER --json baseRefName --jq '.baseRefName')\nCHANGED_FILES=$(git diff origin\u002F${BASE_REF}...HEAD --name-only)\n```\n\nFor each changed file, trace upstream dependencies (up to 2 levels):\n\n- Read the changed file, identify what it exports (functions, components, constants, types)\n- Search for files that import from this changed file:\n  ```bash\n  cd \"$WORKTREE_DIR\"\n  # Level 1 — direct importers\n  grep -rl \"from.*\u003Crelative_module_path>\" src\u002F --include=\"*.ts\" --include=\"*.tsx\" 2>\u002Fdev\u002Fnull\n  ```\n- For each Level 1 importer, find Level 2 importers similarly\n\nBuild an impact map:\n\n```\nChanged:   src\u002Fcommon\u002Futils\u002Ftoken.ts\n  ↳ L1: src\u002Frenderer\u002Ffeatures\u002Fauth\u002FAuthModal.tsx\n         src\u002Fprocess\u002Fchannels\u002Fauth.ts\n  ↳ L2: src\u002Frenderer\u002Fapp\u002FApp.tsx (via AuthModal)\n         src\u002Fprocess\u002Fmain.ts (via auth channel)\n```\n\n**UI rendering impact detection:** flag any changed files in `src\u002Frenderer\u002F` or any L1\u002FL2 impacted files that are React components (contain JSX or `export default function`\u002F`export const ... = () =>`).\n\n**Test coverage check per path:**\n\n```bash\ncd \"$WORKTREE_DIR\"\n# Check if test files exist for each changed file\nfor FILE in $CHANGED_FILES; do\n  BASENAME=$(basename \"$FILE\" | sed 's\u002F\\.[^.]*$\u002F\u002F')\n  DIRNAME=$(dirname \"$FILE\")\n  # Look for co-located tests or __tests__ directory\n  TEST_EXISTS=$(find \"$WORKTREE_DIR\u002F$DIRNAME\" -name \"${BASENAME}.test.*\" -o -name \"${BASENAME}.spec.*\" 2>\u002Fdev\u002Fnull | head -1)\n  TESTS_DIR=$(find \"$WORKTREE_DIR\u002F$DIRNAME\u002F__tests__\" -name \"${BASENAME}*\" 2>\u002Fdev\u002Fnull | head -1)\ndone\n```\n\n#### 4c — Test Supplementation\n\nFor changed files with coverage gaps, write supplemental tests in the worktree. Do NOT commit or push these tests automatically — they are written to the worktree only for local validation.\n\n**Test writing rules:**\n\n- Each test file goes in `\u003Coriginal_dir>\u002F__tests__\u002F\u003Cbasename>.verify.test.ts`\n- Tests needing external API keys use `test.skipIf(!process.env.KEY)` guard\n- Each test is annotated in a comment:\n  - `\u002F\u002F [commit]` — this test fills a genuine coverage gap and should be committed\n  - `\u002F\u002F [skip]` — this test is verification-only, not needed in the PR\n- Test style matches existing tests in the project (Vitest, no `.only`, proper cleanup)\n\nExample supplemental test structure:\n\n```typescript\nimport { describe, it, expect, vi } from 'vitest';\nimport { functionUnderTest } from '..\u002Ftoken';\n\ndescribe('token (supplemental verify)', () => {\n  \u002F\u002F [commit] fills coverage gap: expiry edge case not tested\n  it('returns null when token is expired', () => {\n    \u002F\u002F ...\n  });\n\n  \u002F\u002F [skip] integration path requires running process — verify only\n  it.skipIf(!process.env.INTEGRATION_TEST)('round-trips through IPC', () => {\n    \u002F\u002F ...\n  });\n});\n```\n\n#### 4d — Run Test Suite\n\n```bash\ncd \"$WORKTREE_DIR\"\nbun run test\n```\n\nCapture test results: total, passed, failed, skipped. If tests fail, note which files are failing.\n\n---\n\n### Step 5 — Verification Report\n\nCalculate confidence level based on impact analysis and test results:\n\n| Condition                                                                                                             | Confidence |\n| --------------------------------------------------------------------------------------------------------------------- | ---------- |\n| Local changes only, all tests pass, no UI impact                                                                      | 🟢 HIGH    |\n| Coverage gaps supplemented and all supplemental tests pass; OR UI rendering impact detected                           | 🟡 MEDIUM  |\n| Core shared logic (touches `src\u002Fcommon\u002F` or `src\u002Fprocess\u002F`), large impact spread (L2 > 5 files), or any test failures | 🔴 LOW     |\n\nDisplay the full verification report:\n\n```\n=== 验证报告：PR #\u003CPR_NUMBER> ===\n\n## 影响分析\n\n变更文件 (N 个):\n  [list of changed files]\n\n上游影响:\n  L1 直接依赖: N 个文件\n  L2 间接依赖: N 个文件\n  [impact map summary]\n\nUI 渲染影响: ✅ 无 \u002F ⚠️ 涉及 N 个组件\n\n核心路径: ✅ 未涉及 \u002F ⚠️ 涉及 [file list]\n\n## 测试结果\n\n全量测试: ✅ 通过 \u002F ❌ 失败\n  通过: N  |  失败: N  |  跳过: N\n\n覆盖情况:\n  [list files with\u002Fwithout tests]\n\n补充测试建议 (N 个):\n  ✅ [commit] src\u002Fcommon\u002Futils\u002F__tests__\u002Ftoken.verify.test.ts — 3 个用例覆盖 expiry 边界\n  ⏭️ [skip]  src\u002Fcommon\u002Futils\u002F__tests__\u002Ftoken.verify.test.ts — 1 个集成用例，仅本地验证\n\n## 综合置信度\n\n🟢 HIGH \u002F 🟡 MEDIUM \u002F 🔴 LOW\n[1 句话说明原因]\n```\n\nThen display action menu:\n\n```\n请选择操作：\n  m  - 直接合并（squash merge）\n  mt - 提交补充测试后合并\n  v  - 手动验证（在本地运行应用后决策）\n  r  - 拒绝合并（标记 bot:needs-human-review）\n  s  - 跳过（不修改标签，返回列表）\n  d  - 查看完整 review 报告\n```\n\n---\n\n### Step 6 — Action Execution\n\n#### `m` — Direct Merge\n\n```bash\ngh pr merge $PR_NUMBER --squash\n```\n\nClean up worktree:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nDisplay `✅ PR #\u003CPR_NUMBER> 已合并。` then return to list (Step 1).\n\n#### `mt` — Merge with Supplemental Tests\n\nFirst, commit recommended tests (`[commit]`-annotated only) to the PR branch:\n\n```bash\n# Get head branch name\nHEAD_BRANCH=$(gh pr view $PR_NUMBER --json headRefName --jq '.headRefName')\n\ncd \"$WORKTREE_DIR\"\n# Stage only [commit]-annotated test files\ngit add \u003Ccommit-annotated test files>\n\n# Infer scope from changed files (use first changed file's directory segment)\nSCOPE=$(echo \"$CHANGED_FILES\" | head -1 | cut -d'\u002F' -f3)\n\ngit commit -m \"test(${SCOPE}): add supplemental tests for PR #${PR_NUMBER}\"\n```\n\n> **Important:** commit message must NOT contain `Co-Authored-By` or any AI signature.\n\nPush to the PR head branch (fork-aware):\n\n```bash\ncd \"$WORKTREE_DIR\"\n\n# Detect fork vs same-repo PR\nHEAD_OWNER=$(gh pr view $PR_NUMBER --json headRepositoryOwner --jq '.headRepositoryOwner.login')\nREPO_OWNER=$(gh repo view --json owner --jq '.owner.login')\n\nif [ \"$HEAD_OWNER\" != \"$REPO_OWNER\" ]; then\n  FORK_URL=\"https:\u002F\u002Fgithub.com\u002F${HEAD_OWNER}\u002F$(gh repo view --json name --jq '.name').git\"\n  git remote add fork-target \"$FORK_URL\" 2>\u002Fdev\u002Fnull || true\n  git fetch fork-target \"$HEAD_BRANCH\"\n  git push fork-target HEAD:refs\u002Fheads\u002F${HEAD_BRANCH} --force-with-lease\nelse\n  git push origin HEAD:refs\u002Fheads\u002F${HEAD_BRANCH} --force-with-lease\nfi\n```\n\nThen enable auto-merge (CI will re-run with the new test commit):\n\n```bash\ngh pr merge $PR_NUMBER --squash --auto\n```\n\nClean up worktree:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nDisplay `✅ 已推送补充测试并设置 auto-merge。CI 通过后 PR #\u003CPR_NUMBER> 将自动合并。` then return to list (Step 1).\n\n#### `v` — Manual Verification\n\nDisplay the command for the user to run in another terminal:\n\n```\n在另一个终端中运行以下命令启动应用进行验证：\n\n  cd \u002Ftmp\u002Faionui-verify-\u003CPR_NUMBER> && bun run start\n\n验证完成后，请在此选择：\n  m  - 合并\n  mt - 提交补充测试后合并\n  r  - 拒绝合并\n  s  - 跳过\n```\n\nWait for user input and execute the corresponding action as defined in this step.\n\n#### `r` — Reject\n\nPrompt for reason:\n\n> 请输入拒绝原因（将写入 PR 评论）：\n\nRead reason from user input.\n\nUpdate labels:\n\n```bash\ngh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\" --add-label \"bot:needs-human-review\"\n```\n\nPost rejection comment:\n\n```bash\ngh pr comment $PR_NUMBER --body \"\u003C!-- pr-verify-bot -->\n\n## 人工验证：未通过\n\n本 PR 在 pr-verify 验证阶段被拒绝，需要人工 review。\n\n**拒绝原因：** \u003Cuser-provided reason>\n\n**验证详情：**\n- 置信度：🟢 HIGH \u002F 🟡 MEDIUM \u002F 🔴 LOW\n- 测试结果：通过 N \u002F 失败 N \u002F 跳过 N\n- 影响范围：L1 N 个文件，L2 N 个文件\"\n```\n\nClean up worktree:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nDisplay `已标记 bot:needs-human-review，PR #\u003CPR_NUMBER> 已移交人工处理。` then return to list (Step 1).\n\n#### `s` — Skip\n\nNo label change. Clean up worktree:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nReturn to list (Step 1).\n\n#### `d` — View Full Review\n\nFetch and display the full content of the `\u003C!-- pr-review-bot -->` comment. Stay on the current PR — re-show the action menu after displaying.\n\n---\n\n### Step 7 — Cleanup and Session Summary\n\nWhen user inputs `q` at the PR list, or the PR list is empty, or all PRs have been processed:\n\n**Clean up all verify worktrees:**\n\n```bash\nfor dir in \u002Ftmp\u002Faionui-verify-*; do\n  [ -d \"$dir\" ] && git -C \"$(git rev-parse --show-toplevel)\" worktree remove \"$dir\" --force 2>\u002Fdev\u002Fnull || true\ndone\n```\n\n**Display session summary:**\n\n```\n=== pr-verify 会话总结 ===\n\n✅ 已合并:        [#123 fix(auth): handle token expiry, ...]\n🔄 Auto-merge 中: [#124 feat(ui): add dark mode toggle, ...]\n❌ 已拒绝:        [#125 refactor(db): restructure schema, ...]\n⏭️ 已跳过:        [#126 chore: update deps, ...]\n\n共处理 N 个 PR。\n```\n\n---\n\n## Mandatory Rules\n\n- **Worktree path** — always `\u002Ftmp\u002Faionui-verify-\u003CPR_NUMBER>`; never use `\u002Ftmp\u002Faionui-pr-*` (reserved for pr-automation\u002Fpr-fix)\n- **No AI signature** — no `Co-Authored-By`, no `Generated with` in any commit or comment\n- **Merge strategy** — always `--squash`; never `--merge` or `--rebase`\n- **Comment marker** — use `\u003C!-- pr-verify-bot -->` (distinct from `\u003C!-- pr-review-bot -->` and `\u003C!-- pr-automation-bot -->`)\n- **REPO detection** — `REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')` — never hardcode\n- **Test push only on mt** — supplemental tests are written to worktree only; never pushed unless user chooses `mt`\n- **Worktree reuse** — if Step 2 auto-merge already created a worktree, reuse it in Step 4 instead of recreating\n- **Label atomicity** — when swapping labels, do both in a single `gh pr edit` call\n- **Named refs over FETCH_HEAD** — never rely on `FETCH_HEAD` (it is overwritten by every `git fetch`); always use `refs\u002Fpr\u002F\u003CPR_NUMBER>` or explicit branch names\n- **Merge over rebase for conflicts** — use `git merge` (not `git rebase`) to resolve conflicts; rebase replays commits individually and creates spurious conflicts that GitHub does not show\n- **Fork-aware push** — always detect fork PRs (`headRepositoryOwner != repo owner`) and push to the fork remote; never push fork branches to `origin`\n- **Fetch before force-with-lease** — always `git fetch \u003Cremote> \u003Cbranch>` before `--force-with-lease` to avoid \"stale info\" errors on new remotes\n- **Full refspec for push** — always use `HEAD:refs\u002Fheads\u002F\u003Cbranch>` (not `HEAD:\u003Cbranch>`) to avoid \"not a full refname\" errors on detached HEAD worktrees\n\n---\n\n## Quick Reference\n\n```\n 1. Parse $ARGUMENTS → PR number or display bot:ready-to-merge list for selection\n 2. Pre-flight (3 checks):\n    a. New commits since ready-to-merge? → ask re-review or continue\n    b. CI status? → all pass \u002F running (ask wait\u002Fcontinue) \u002F failed (ask skip\u002Fcontinue)\n    c. Mergeable? → MERGEABLE (continue) \u002F UNKNOWN (skip) \u002F CONFLICTING (auto-merge or prompt)\n 3. Review summary → parse pr-review-bot comment, show concise summary, d for full report\n 4. Impact analysis + test supplementation:\n    a. Create worktree at \u002Ftmp\u002Faionui-verify-\u003CPR> (reuse if from Step 2)\n    b. Trace changed files → L1\u002FL2 upstream deps → UI rendering impact\n    c. Write supplemental tests in worktree (annotate [commit] vs [skip])\n    d. bun run test in worktree\n 5. Verification report → impact map, test results, supplemental test recs, confidence (🟢\u002F🟡\u002F🔴)\n    Action menu: m \u002F mt \u002F v \u002F r \u002F s \u002F d\n 6. Action execution:\n    m  → gh pr merge --squash, cleanup, back to list\n    mt → commit [commit] tests, push to head branch, gh pr merge --squash --auto, cleanup, back to list\n    v  → show bun run start command, wait for user, then m\u002Fmt\u002Fr\u002Fs menu\n    r  → ask reason, remove bot:ready-to-merge + add bot:needs-human-review, post pr-verify-bot comment, cleanup\n    s  → no label change, cleanup, back to list\n    d  → show full review comment, re-show action menu\n 7. Cleanup all \u002Ftmp\u002Faionui-verify-* worktrees → session summary (merged\u002Fauto-merge\u002Frejected\u002Fskipped)\n```\n","# PR Verification & Merge\n\nInteractive workflow to verify `bot:ready-to-merge` PRs — displays impact analysis, supplements tests, and provides one-click merge with confidence scoring.\n\n**Announce at start:** \"I'm using pr-verify skill to verify and merge ready PRs.\"\n\n## Usage\n\n```\n\u002Fpr-verify [pr_number]\n```\n\n`$ARGUMENTS` may contain an optional PR number.\n\n- Without argument: display list of `bot:ready-to-merge` PRs for selection\n- With argument: skip list, go directly to that PR number\n\n---\n\n## Configuration\n\n```\nPR_DAYS_LOOKBACK: env var (default: 7) — lookback window for PR list\nCRITICAL_PATH_PATTERN: env var — pattern to detect critical file paths\n```\n\n**REPO** is detected automatically at runtime — do not hardcode it:\n\n```bash\nREPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')\n```\n\n**Worktree path:** always `\u002Ftmp\u002Faionui-verify-\u003CPR_NUMBER>` — never use `\u002Ftmp\u002Faionui-pr-*` (reserved for pr-automation\u002Fpr-fix).\n\n---\n\n## Steps\n\n### Step 1 — PR List Display\n\nParse `$ARGUMENTS` for an optional PR number.\n\n**If a PR number is provided:** skip the list, jump directly to Step 2 with that PR number.\n\n**If no argument provided:** query `bot:ready-to-merge` PRs from the last `PR_DAYS_LOOKBACK` days (default 7):\n\n```bash\nDAYS=${PR_DAYS_LOOKBACK:-7}\ngh pr list \\\n  --state open \\\n  --label \"bot:ready-to-merge\" \\\n  --search \"created:>=$(date -v-${DAYS}d '+%Y-%m-%d' 2>\u002Fdev\u002Fnull || date -d \"${DAYS} days ago\" '+%Y-%m-%d') -is:draft\" \\\n  --json number,title,labels,changedFiles,additions,deletions,headRefName,baseRefName,commits,createdAt,author \\\n  --limit 50\n```\n\nIf the result is empty: display `没有找到 bot:ready-to-merge 的 PR。` and exit.\n\nFor each PR, infer the type from the first commit message prefix:\n\n| Prefix pattern | Type     |\n| -------------- | -------- |\n| `fix(`         | bugfix   |\n| `feat(`        | feature  |\n| `refactor(`    | refactor |\n| `chore(`       | chore    |\n| `docs(`        | docs     |\n| `perf(`        | perf     |\n| `test(`        | test     |\n| other          | misc     |\n\nDisplay as a numbered table:\n\n```\n# | PR   | 标题                              | 变更          | 类型\n--|------|-----------------------------------|---------------|--------\n1 | #123 | fix(auth): handle token expiry    | +45 \u002F -12     | bugfix\n2 | #124 | feat(ui): add dark mode toggle    | +230 \u002F -18    | feature\n```\n\nThen prompt:\n\n> 请输入序号选择 PR，或输入 q 退出：\n\n- User inputs a number → use that PR\n- User inputs `q` → exit\n\nSave the selected PR number as `PR_NUMBER` for all subsequent steps.\n\n---\n\n### Step 2 — Pre-flight Checks\n\nRun three checks in order. A failure in any check presents the user with an action choice.\n\n#### Check 1 — New Commits Since Ready-to-Merge Label\n\n```bash\n# Time when bot:ready-to-merge label was last set (infer from bot comment)\nLABEL_SET_TIME=$(gh pr view $PR_NUMBER --json comments \\\n  --jq '[.comments[] | select(.body | test(\"\u003C!-- pr-automation-bot -->\") and (test(\"bot:ready-to-merge\") or test(\"已自动 review\") or test(\"已自动修复\")))] | last | .createdAt \u002F\u002F \"\"')\n\nLATEST_COMMIT_TIME=$(gh pr view $PR_NUMBER --json commits \\\n  --jq '.commits | last | .committedDate')\n```\n\nIf `LATEST_COMMIT_TIME > LABEL_SET_TIME` (new commits after the label was set), prompt:\n\n> ⚠️ 该 PR 在标记 bot:ready-to-merge 后有新提交（最新提交：`\u003CLATEST_COMMIT_TIME>`，标签时间：`\u003CLABEL_SET_TIME>`）。\n> 建议重新 review 后再合并。请选择：\n> r - 移除 bot:ready-to-merge 标签，触发重新 review\n> c - 忽略并继续验证\n\n- `r` → remove `bot:ready-to-merge` label:\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\"\n  ```\n  Display `已移除标签，PR 将在下一轮自动化中重新 review。` and return to list (Step 1).\n- `c` → continue to Check 2.\n\n#### Check 2 — CI Status\n\n```bash\ngh pr view $PR_NUMBER --json statusCheckRollup \\\n  --jq '.statusCheckRollup[] | {name: .name, status: .status, conclusion: .conclusion}'\n```\n\nRequired jobs: `Code Quality`, `Unit Tests (ubuntu-latest)`, `Unit Tests (macos-14)`, `Unit Tests (windows-2022)`, `Coverage Test`, `i18n-check`\n\nInformational exclusions: `codecov\u002Fpatch` and `codecov\u002Fproject` are informational — exclude them from all failure checks.\n\n| Condition                                                | Action              |\n| -------------------------------------------------------- | ------------------- |\n| All required jobs SUCCESS, no non-informational failures | Continue to Check 3 |\n| Any required job QUEUED or IN_PROGRESS                   | Prompt (see below)  |\n| Any non-informational job FAILURE or CANCELLED           | Prompt (see below)  |\n\n**CI still running prompt:**\n\n> ⏳ 以下 CI job 尚未完成：[job 列表]\n> 请选择：\n> w - 等待 CI 完成后继续（推出，请稍后重新运行）\n> c - 忽略，继续验证\n\n- `w` → exit\n- `c` → continue to Check 3\n\n**CI failed prompt:**\n\n> ❌ 以下 CI job 未通过：[job 列表及结论]\n> 请选择：\n> s - 跳过此 PR\n> c - 忽略失败，继续验证\n\n- `s` → remove `bot:ready-to-merge` label (let pr-automation re-process next round), return to list (Step 1):\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\"\n  ```\n- `c` → continue to Check 3\n\n#### Check 3 — Merge Conflicts\n\n```bash\ngh pr view $PR_NUMBER \\\n  --json mergeable,mergeStateStatus,headRefName,baseRefName \\\n  --jq '{mergeable, mergeStateStatus, head: .headRefName, base: .baseRefName}'\n```\n\n| `mergeable`   | Action                                                                 |\n| ------------- | ---------------------------------------------------------------------- |\n| `MERGEABLE`   | Continue to Step 3                                                     |\n| `UNKNOWN`     | Skip this PR (return to list), log: `mergeability unknown, will retry` |\n| `CONFLICTING` | Attempt auto-merge (see below)                                         |\n\n**Auto-merge attempt on conflict:**\n\n> **Why merge instead of rebase?** Since we squash-merge all PRs, the intermediate commit\n> history is irrelevant. `git merge` produces exactly the conflicts GitHub shows (one pass\n> over the final diff), while `git rebase` replays each commit individually, often creating\n> extra conflicts in files that GitHub reports as clean. Always use merge for conflict\n> resolution in this workflow.\n\n```bash\nREPO_ROOT=$(git rev-parse --show-toplevel)\nWORKTREE_DIR=\"\u002Ftmp\u002Faionui-verify-${PR_NUMBER}\"\n\n# Clean up any stale worktree\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n\n# Detect fork vs same-repo PR\nHEAD_OWNER=$(gh pr view $PR_NUMBER --json headRepositoryOwner --jq '.headRepositoryOwner.login')\nREPO_OWNER=$(gh repo view --json owner --jq '.owner.login')\nIS_FORK=$( [ \"$HEAD_OWNER\" != \"$REPO_OWNER\" ] && echo true || echo false )\n\n# Fetch PR head into a named ref (avoids FETCH_HEAD overwrite)\ngit fetch origin pull\u002F${PR_NUMBER}\u002Fhead:refs\u002Fpr\u002F${PR_NUMBER}\ngit worktree add \"$WORKTREE_DIR\" refs\u002Fpr\u002F${PR_NUMBER} --detach\n\nln -sf \"$REPO_ROOT\u002Fnode_modules\" \"$WORKTREE_DIR\u002Fnode_modules\"\n\ncd \"$WORKTREE_DIR\"\ngit fetch origin \u003Cbase_branch>\ngit merge origin\u002F\u003Cbase_branch> --no-edit\n```\n\nIf merge **succeeds** (no conflicts):\n\n```bash\n# Determine push target\nif [ \"$IS_FORK\" = \"true\" ]; then\n  FORK_URL=\"https:\u002F\u002Fgithub.com\u002F${HEAD_OWNER}\u002F$(gh repo view --json name --jq '.name').git\"\n  git remote add fork-target \"$FORK_URL\" 2>\u002Fdev\u002Fnull || true\n  git fetch fork-target \u003Chead_branch>\n  git push fork-target HEAD:refs\u002Fheads\u002F\u003Chead_branch> --force-with-lease\nelse\n  git push origin HEAD:refs\u002Fheads\u002F\u003Chead_branch> --force-with-lease\nfi\n\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n\ngh pr merge $PR_NUMBER --squash --auto\n```\n\nDisplay `已自动解决冲突并推送，PR 已设置 auto-merge，等待 CI 通过后自动合并。` and skip to next PR (return to Step 1).\n\nIf merge **has conflicts**, attempt manual resolution:\n\nRead each conflicting file and resolve the conflicts by understanding both sides of the change. After resolving all conflicts:\n\n```bash\ncd \"$WORKTREE_DIR\"\ngit add \u003Cresolved_files>\ngit commit --no-edit\n```\n\nIf resolution succeeds → push (same fork-aware logic as above) and set `--squash --auto`.\n\nIf resolution fails or conflicts are too complex:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nPrompt:\n\n> ❌ 合并冲突无法自动解决。请选择：\n> m - 提示作者手动解决冲突\n> s - 跳过此 PR\n> r - 标记为 bot:needs-human-review\n\n- `m` → post comment to PR:\n\n  ```bash\n  gh pr comment $PR_NUMBER --body \"\u003C!-- pr-verify-bot -->\n\n  ## 合并冲突（无法自动解决）\n\n  本 PR 与目标分支存在冲突，无法自动解决。请手动 merge 或 rebase 后重新 push：\n\n  \\`\\`\\`bash\n  git fetch origin\n  git merge origin\u002F\u003Cbase_branch>\n  # 解决冲突后\n  git push\n  \\`\\`\\`\"\n  ```\n\n  Then add label:\n\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\" --add-label \"bot:needs-rebase\"\n  ```\n\n  Return to list (Step 1).\n\n- `s` → add `bot:needs-rebase` label and comment, return to list (Step 1):\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\" --add-label \"bot:needs-rebase\"\n  gh pr comment $PR_NUMBER --body \"\u003C!-- pr-verify-bot -->\n  PR 存在合并冲突，无法自动解决。请作者手动解决后重新 push。\"\n  ```\n- `r` → add label and return to list:\n  ```bash\n  gh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\" --add-label \"bot:needs-human-review\"\n  ```\n  Return to list (Step 1).\n\n---\n\n### Step 3 — Review Summary Display\n\nFetch and display a concise summary of the existing review.\n\n```bash\n# Fetch review comment(s)\ngh pr view $PR_NUMBER --json comments \\\n  --jq '[.comments[] | select(.body | startswith(\"\u003C!-- pr-review-bot -->\"))] | last | .body'\n```\n\nParse from the review comment:\n\n- **结论** (APPROVED \u002F CONDITIONAL \u002F review conclusion line)\n- **问题数量** per severity level (CRITICAL \u002F HIGH \u002F MEDIUM \u002F LOW)\n- If a `\u003C!-- pr-fix-verification -->` comment exists, also parse fix results\n\n```bash\n# Fetch fix verification comment if present\ngh pr view $PR_NUMBER --json comments \\\n  --jq '[.comments[] | select(.body | startswith(\"\u003C!-- pr-fix-verification -->\"))] | last | .body'\n```\n\nFetch changed files:\n\n```bash\ngh pr view $PR_NUMBER --json files \\\n  --jq '.files[] | {path: .path, additions: .additions, deletions: .deletions, status: .changeType}'\n```\n\nCheck critical path:\n\n```bash\nif [ -n \"$CRITICAL_PATH_PATTERN\" ]; then\n  CRITICAL_FILES=$(gh pr view $PR_NUMBER --json files \\\n    --jq '[.files[].path]' | jq -r '.[]' | grep -E \"$CRITICAL_PATH_PATTERN\" || true)\n  [ -n \"$CRITICAL_FILES\" ] && HAS_CRITICAL_PATH=true || HAS_CRITICAL_PATH=false\nelse\n  HAS_CRITICAL_PATH=false\n  CRITICAL_FILES=\"\"\nfi\n```\n\nDisplay concise summary:\n\n```\n=== PR #\u003CPR_NUMBER>: \u003C标题> ===\n\n作者: \u003Cauthor>  |  基分支: \u003Cbase>  |  变更: +\u003Cadd> \u002F -\u003Cdel>\n\nReview 结论: ✅ 批准合并 \u002F ⚠️ 有条件批准 \u002F ❌ 需要修改\n问题数量: CRITICAL(0) HIGH(1) MEDIUM(2) LOW(3)\n修复状态: ✅ 已修复 2 个 \u002F ⏭️ 驳回 1 个  [若有 pr-fix 报告]\n\n变更文件 (N 个):\n  src\u002Frenderer\u002Ffeatures\u002Fauth\u002FAuthModal.tsx  +45 \u002F -12\n  src\u002Fcommon\u002Futils\u002Ftoken.ts                 +23 \u002F -5\n  ...\n\n核心路径: ⚠️ 涉及核心路径文件  [若 HAS_CRITICAL_PATH=true]\n           src\u002Fprocess\u002Fchannels\u002Fauth.ts\n```\n\nThen prompt:\n\n> d - 查看完整 review 报告 | 回车继续影响分析\n\n- `d` → display full review comment text, then re-show this prompt\n- Enter → continue to Step 4\n\nIf no `\u003C!-- pr-review-bot -->` comment found, display:\n\n> ⚠️ 未找到 review 报告。该 PR 可能未经过自动化 review 流程。\n\nAnd continue to Step 4.\n\n---\n\n### Step 4 — Impact Analysis + Test Supplementation\n\n#### 4a — Worktree Setup\n\nCreate worktree at `\u002Ftmp\u002Faionui-verify-\u003CPR_NUMBER>` (reuse if already created in Step 2):\n\n```bash\nREPO_ROOT=$(git rev-parse --show-toplevel)\nWORKTREE_DIR=\"\u002Ftmp\u002Faionui-verify-${PR_NUMBER}\"\n\n# Reuse existing worktree if present, otherwise create\nif [ ! -d \"$WORKTREE_DIR\" ]; then\n  # Use a named ref to avoid FETCH_HEAD being overwritten by subsequent fetches\n  git fetch origin pull\u002F${PR_NUMBER}\u002Fhead:refs\u002Fpr\u002F${PR_NUMBER}\n  git worktree add \"$WORKTREE_DIR\" refs\u002Fpr\u002F${PR_NUMBER} --detach\n  ln -sf \"$REPO_ROOT\u002Fnode_modules\" \"$WORKTREE_DIR\u002Fnode_modules\"\nfi\n```\n\n#### 4b — Impact Analysis\n\nParse changed files from the worktree:\n\n```bash\ncd \"$WORKTREE_DIR\"\nBASE_REF=$(gh pr view $PR_NUMBER --json baseRefName --jq '.baseRefName')\nCHANGED_FILES=$(git diff origin\u002F${BASE_REF}...HEAD --name-only)\n```\n\nFor each changed file, trace upstream dependencies (up to 2 levels):\n\n- Read the changed file, identify what it exports (functions, components, constants, types)\n- Search for files that import from this changed file:\n  ```bash\n  cd \"$WORKTREE_DIR\"\n  # Level 1 — direct importers\n  grep -rl \"from.*\u003Crelative_module_path>\" src\u002F --include=\"*.ts\" --include=\"*.tsx\" 2>\u002Fdev\u002Fnull\n  ```\n- For each Level 1 importer, find Level 2 importers similarly\n\nBuild an impact map:\n\n```\nChanged:   src\u002Fcommon\u002Futils\u002Ftoken.ts\n  ↳ L1: src\u002Frenderer\u002Ffeatures\u002Fauth\u002FAuthModal.tsx\n         src\u002Fprocess\u002Fchannels\u002Fauth.ts\n  ↳ L2: src\u002Frenderer\u002Fapp\u002FApp.tsx (via AuthModal)\n         src\u002Fprocess\u002Fmain.ts (via auth channel)\n```\n\n**UI rendering impact detection:** flag any changed files in `src\u002Frenderer\u002F` or any L1\u002FL2 impacted files that are React components (contain JSX or `export default function`\u002F`export const ... = () =>`).\n\n**Test coverage check per path:**\n\n```bash\ncd \"$WORKTREE_DIR\"\n# Check if test files exist for each changed file\nfor FILE in $CHANGED_FILES; do\n  BASENAME=$(basename \"$FILE\" | sed 's\u002F\\.[^.]*$\u002F\u002F')\n  DIRNAME=$(dirname \"$FILE\")\n  # Look for co-located tests or __tests__ directory\n  TEST_EXISTS=$(find \"$WORKTREE_DIR\u002F$DIRNAME\" -name \"${BASENAME}.test.*\" -o -name \"${BASENAME}.spec.*\" 2>\u002Fdev\u002Fnull | head -1)\n  TESTS_DIR=$(find \"$WORKTREE_DIR\u002F$DIRNAME\u002F__tests__\" -name \"${BASENAME}*\" 2>\u002Fdev\u002Fnull | head -1)\ndone\n```\n\n#### 4c — Test Supplementation\n\nFor changed files with coverage gaps, write supplemental tests in the worktree. Do NOT commit or push these tests automatically — they are written to the worktree only for local validation.\n\n**Test writing rules:**\n\n- Each test file goes in `\u003Coriginal_dir>\u002F__tests__\u002F\u003Cbasename>.verify.test.ts`\n- Tests needing external API keys use `test.skipIf(!process.env.KEY)` guard\n- Each test is annotated in a comment:\n  - `\u002F\u002F [commit]` — this test fills a genuine coverage gap and should be committed\n  - `\u002F\u002F [skip]` — this test is verification-only, not needed in the PR\n- Test style matches existing tests in the project (Vitest, no `.only`, proper cleanup)\n\nExample supplemental test structure:\n\n```typescript\nimport { describe, it, expect, vi } from 'vitest';\nimport { functionUnderTest } from '..\u002Ftoken';\n\ndescribe('token (supplemental verify)', () => {\n  \u002F\u002F [commit] fills coverage gap: expiry edge case not tested\n  it('returns null when token is expired', () => {\n    \u002F\u002F ...\n  });\n\n  \u002F\u002F [skip] integration path requires running process — verify only\n  it.skipIf(!process.env.INTEGRATION_TEST)('round-trips through IPC', () => {\n    \u002F\u002F ...\n  });\n});\n```\n\n#### 4d — Run Test Suite\n\n```bash\ncd \"$WORKTREE_DIR\"\nbun run test\n```\n\nCapture test results: total, passed, failed, skipped. If tests fail, note which files are failing.\n\n---\n\n### Step 5 — Verification Report\n\nCalculate confidence level based on impact analysis and test results:\n\n| Condition                                                                                                             | Confidence |\n| --------------------------------------------------------------------------------------------------------------------- | ---------- |\n| Local changes only, all tests pass, no UI impact                                                                      | 🟢 HIGH    |\n| Coverage gaps supplemented and all supplemental tests pass; OR UI rendering impact detected                           | 🟡 MEDIUM  |\n| Core shared logic (touches `src\u002Fcommon\u002F` or `src\u002Fprocess\u002F`), large impact spread (L2 > 5 files), or any test failures | 🔴 LOW     |\n\nDisplay the full verification report:\n\n```\n=== 验证报告：PR #\u003CPR_NUMBER> ===\n\n## 影响分析\n\n变更文件 (N 个):\n  [list of changed files]\n\n上游影响:\n  L1 直接依赖: N 个文件\n  L2 间接依赖: N 个文件\n  [impact map summary]\n\nUI 渲染影响: ✅ 无 \u002F ⚠️ 涉及 N 个组件\n\n核心路径: ✅ 未涉及 \u002F ⚠️ 涉及 [file list]\n\n## 测试结果\n\n全量测试: ✅ 通过 \u002F ❌ 失败\n  通过: N  |  失败: N  |  跳过: N\n\n覆盖情况:\n  [list files with\u002Fwithout tests]\n\n补充测试建议 (N 个):\n  ✅ [commit] src\u002Fcommon\u002Futils\u002F__tests__\u002Ftoken.verify.test.ts — 3 个用例覆盖 expiry 边界\n  ⏭️ [skip]  src\u002Fcommon\u002Futils\u002F__tests__\u002Ftoken.verify.test.ts — 1 个集成用例，仅本地验证\n\n## 综合置信度\n\n🟢 HIGH \u002F 🟡 MEDIUM \u002F 🔴 LOW\n[1 句话说明原因]\n```\n\nThen display action menu:\n\n```\n请选择操作：\n  m  - 直接合并（squash merge）\n  mt - 提交补充测试后合并\n  v  - 手动验证（在本地运行应用后决策）\n  r  - 拒绝合并（标记 bot:needs-human-review）\n  s  - 跳过（不修改标签，返回列表）\n  d  - 查看完整 review 报告\n```\n\n---\n\n### Step 6 — Action Execution\n\n#### `m` — Direct Merge\n\n```bash\ngh pr merge $PR_NUMBER --squash\n```\n\nClean up worktree:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nDisplay `✅ PR #\u003CPR_NUMBER> 已合并。` then return to list (Step 1).\n\n#### `mt` — Merge with Supplemental Tests\n\nFirst, commit recommended tests (`[commit]`-annotated only) to the PR branch:\n\n```bash\n# Get head branch name\nHEAD_BRANCH=$(gh pr view $PR_NUMBER --json headRefName --jq '.headRefName')\n\ncd \"$WORKTREE_DIR\"\n# Stage only [commit]-annotated test files\ngit add \u003Ccommit-annotated test files>\n\n# Infer scope from changed files (use first changed file's directory segment)\nSCOPE=$(echo \"$CHANGED_FILES\" | head -1 | cut -d'\u002F' -f3)\n\ngit commit -m \"test(${SCOPE}): add supplemental tests for PR #${PR_NUMBER}\"\n```\n\n> **Important:** commit message must NOT contain `Co-Authored-By` or any AI signature.\n\nPush to the PR head branch (fork-aware):\n\n```bash\ncd \"$WORKTREE_DIR\"\n\n# Detect fork vs same-repo PR\nHEAD_OWNER=$(gh pr view $PR_NUMBER --json headRepositoryOwner --jq '.headRepositoryOwner.login')\nREPO_OWNER=$(gh repo view --json owner --jq '.owner.login')\n\nif [ \"$HEAD_OWNER\" != \"$REPO_OWNER\" ]; then\n  FORK_URL=\"https:\u002F\u002Fgithub.com\u002F${HEAD_OWNER}\u002F$(gh repo view --json name --jq '.name').git\"\n  git remote add fork-target \"$FORK_URL\" 2>\u002Fdev\u002Fnull || true\n  git fetch fork-target \"$HEAD_BRANCH\"\n  git push fork-target HEAD:refs\u002Fheads\u002F${HEAD_BRANCH} --force-with-lease\nelse\n  git push origin HEAD:refs\u002Fheads\u002F${HEAD_BRANCH} --force-with-lease\nfi\n```\n\nThen enable auto-merge (CI will re-run with the new test commit):\n\n```bash\ngh pr merge $PR_NUMBER --squash --auto\n```\n\nClean up worktree:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nDisplay `✅ 已推送补充测试并设置 auto-merge。CI 通过后 PR #\u003CPR_NUMBER> 将自动合并。` then return to list (Step 1).\n\n#### `v` — Manual Verification\n\nDisplay the command for the user to run in another terminal:\n\n```\n在另一个终端中运行以下命令启动应用进行验证：\n\n  cd \u002Ftmp\u002Faionui-verify-\u003CPR_NUMBER> && bun run start\n\n验证完成后，请在此选择：\n  m  - 合并\n  mt - 提交补充测试后合并\n  r  - 拒绝合并\n  s  - 跳过\n```\n\nWait for user input and execute the corresponding action as defined in this step.\n\n#### `r` — Reject\n\nPrompt for reason:\n\n> 请输入拒绝原因（将写入 PR 评论）：\n\nRead reason from user input.\n\nUpdate labels:\n\n```bash\ngh pr edit $PR_NUMBER --remove-label \"bot:ready-to-merge\" --add-label \"bot:needs-human-review\"\n```\n\nPost rejection comment:\n\n```bash\ngh pr comment $PR_NUMBER --body \"\u003C!-- pr-verify-bot -->\n\n## 人工验证：未通过\n\n本 PR 在 pr-verify 验证阶段被拒绝，需要人工 review。\n\n**拒绝原因：** \u003Cuser-provided reason>\n\n**验证详情：**\n- 置信度：🟢 HIGH \u002F 🟡 MEDIUM \u002F 🔴 LOW\n- 测试结果：通过 N \u002F 失败 N \u002F 跳过 N\n- 影响范围：L1 N 个文件，L2 N 个文件\"\n```\n\nClean up worktree:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nDisplay `已标记 bot:needs-human-review，PR #\u003CPR_NUMBER> 已移交人工处理。` then return to list (Step 1).\n\n#### `s` — Skip\n\nNo label change. Clean up worktree:\n\n```bash\ncd \"$REPO_ROOT\"\ngit worktree remove \"$WORKTREE_DIR\" --force 2>\u002Fdev\u002Fnull || true\n```\n\nReturn to list (Step 1).\n\n#### `d` — View Full Review\n\nFetch and display the full content of the `\u003C!-- pr-review-bot -->` comment. Stay on the current PR — re-show the action menu after displaying.\n\n---\n\n### Step 7 — Cleanup and Session Summary\n\nWhen user inputs `q` at the PR list, or the PR list is empty, or all PRs have been processed:\n\n**Clean up all verify worktrees:**\n\n```bash\nfor dir in \u002Ftmp\u002Faionui-verify-*; do\n  [ -d \"$dir\" ] && git -C \"$(git rev-parse --show-toplevel)\" worktree remove \"$dir\" --force 2>\u002Fdev\u002Fnull || true\ndone\n```\n\n**Display session summary:**\n\n```\n=== pr-verify 会话总结 ===\n\n✅ 已合并:        [#123 fix(auth): handle token expiry, ...]\n🔄 Auto-merge 中: [#124 feat(ui): add dark mode toggle, ...]\n❌ 已拒绝:        [#125 refactor(db): restructure schema, ...]\n⏭️ 已跳过:        [#126 chore: update deps, ...]\n\n共处理 N 个 PR。\n```\n\n---\n\n## Mandatory Rules\n\n- **Worktree path** — always `\u002Ftmp\u002Faionui-verify-\u003CPR_NUMBER>`; never use `\u002Ftmp\u002Faionui-pr-*` (reserved for pr-automation\u002Fpr-fix)\n- **No AI signature** — no `Co-Authored-By`, no `Generated with` in any commit or comment\n- **Merge strategy** — always `--squash`; never `--merge` or `--rebase`\n- **Comment marker** — use `\u003C!-- pr-verify-bot -->` (distinct from `\u003C!-- pr-review-bot -->` and `\u003C!-- pr-automation-bot -->`)\n- **REPO detection** — `REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')` — never hardcode\n- **Test push only on mt** — supplemental tests are written to worktree only; never pushed unless user chooses `mt`\n- **Worktree reuse** — if Step 2 auto-merge already created a worktree, reuse it in Step 4 instead of recreating\n- **Label atomicity** — when swapping labels, do both in a single `gh pr edit` call\n- **Named refs over FETCH_HEAD** — never rely on `FETCH_HEAD` (it is overwritten by every `git fetch`); always use `refs\u002Fpr\u002F\u003CPR_NUMBER>` or explicit branch names\n- **Merge over rebase for conflicts** — use `git merge` (not `git rebase`) to resolve conflicts; rebase replays commits individually and creates spurious conflicts that GitHub does not show\n- **Fork-aware push** — always detect fork PRs (`headRepositoryOwner != repo owner`) and push to the fork remote; never push fork branches to `origin`\n- **Fetch before force-with-lease** — always `git fetch \u003Cremote> \u003Cbranch>` before `--force-with-lease` to avoid \"stale info\" errors on new remotes\n- **Full refspec for push** — always use `HEAD:refs\u002Fheads\u002F\u003Cbranch>` (not `HEAD:\u003Cbranch>`) to avoid \"not a full refname\" errors on detached HEAD worktrees\n\n---\n\n## Quick Reference\n\n```\n 1. Parse $ARGUMENTS → PR number or display bot:ready-to-merge list for selection\n 2. Pre-flight (3 checks):\n    a. New commits since ready-to-merge? → ask re-review or continue\n    b. CI status? → all pass \u002F running (ask wait\u002Fcontinue) \u002F failed (ask skip\u002Fcontinue)\n    c. Mergeable? → MERGEABLE (continue) \u002F UNKNOWN (skip) \u002F CONFLICTING (auto-merge or prompt)\n 3. Review summary → parse pr-review-bot comment, show concise summary, d for full report\n 4. Impact analysis + test supplementation:\n    a. Create worktree at \u002Ftmp\u002Faionui-verify-\u003CPR> (reuse if from Step 2)\n    b. Trace changed files → L1\u002FL2 upstream deps → UI rendering impact\n    c. Write supplemental tests in worktree (annotate [commit] vs [skip])\n    d. bun run test in worktree\n 5. Verification report → impact map, test results, supplemental test recs, confidence (🟢\u002F🟡\u002F🔴)\n    Action menu: m \u002F mt \u002F v \u002F r \u002F s \u002F d\n 6. Action execution:\n    m  → gh pr merge --squash, cleanup, back to list\n    mt → commit [commit] tests, push to head branch, gh pr merge --squash --auto, cleanup, back to list\n    v  → show bun run start command, wait for user, then m\u002Fmt\u002Fr\u002Fs menu\n    r  → ask reason, remove bot:ready-to-merge + add bot:needs-human-review, post pr-verify-bot comment, cleanup\n    s  → no label change, cleanup, back to list\n    d  → show full review comment, re-show action menu\n 7. Cleanup all \u002Ftmp\u002Faionui-verify-* worktrees → session summary (merged\u002Fauto-merge\u002Frejected\u002Fskipped)\n```\n",{"name":5,"description":7},"team","a9a9464c62247a811d9231c636a0941e0fd9ae05",".claude\u002Fskills\u002Fpr-verify","https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team","https:\u002F\u002Fgithub.com\u002Ffinewood2008","Founder & CEO of Centaur AI · Humans lead, AI executes — the Centaur Loop is the smallest work unit for building AI employees.","2026-07-14 22:41:28",{"source":8,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add finewood2008\u002Fcentaurai-team --skill pr-verify",{"tool":37,"command":38},"bunx","bunx skills add finewood2008\u002Fcentaurai-team --skill pr-verify",{"tool":40,"command":41},"pnpm","pnpm dlx skills add finewood2008\u002Fcentaurai-team --skill pr-verify","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team\u002Fblob\u002Fteam\u002F.claude\u002Fskills\u002Fpr-verify\u002FSKILL.md",true,[],[46,54,61,68,75,82],{"skillNo":47,"name":48,"nameZh":6,"description":49,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":50,"licenseFileUrl":6,"sourceHtmlUrl":51,"categories":52,"keywords":53,"publishedAt":19},"01M77RFHB8MZ42KXGPY38CXCAQ","团队周报","Use when generating structured weekly team reports from git commits, task boards, and meeting notes. Auto-aggregates work done, work planned, blockers, and metrics. Chinese output by default. Trigger on: weekly report, 周报, sprint review, 本周总结, team update, status report.","MIT","https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team\u002Fblob\u002Fteam\u002Fskills\u002Fbuiltin\u002Fteam\u002Fteam-weekly-report\u002FSKILL.md",[],[],{"skillNo":55,"name":56,"nameZh":6,"description":57,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":50,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":60,"publishedAt":19},"01M77RFBY70Q5R4YN8A3JD7X5G","中英互译","Use when translating content between Chinese and English for business, technical, or marketing purposes. Handles docs, emails, UI strings, marketing copy, and technical documentation with domain-aware terminology. Trigger on: 翻译, translate, 中译英, 英译中, i18n, localization, English version, 中文版.","https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team\u002Fblob\u002Fteam\u002Fskills\u002Fbuiltin\u002Fteam\u002Fteam-translation\u002FSKILL.md",[],[],{"skillNo":62,"name":63,"nameZh":6,"description":64,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":50,"licenseFileUrl":6,"sourceHtmlUrl":65,"categories":66,"keywords":67,"publishedAt":19},"01M77RF6YBVG39A4QQQEGY8Q6N","社媒规划","Use when planning, drafting, or scheduling social media content for WeChat Official Account, Twitter\u002FX, and Xiaohongshu. Generates content calendars with platform-adapted copy, publishing schedules, and performance tracking. Trigger on: social media, 公众号, 推文, content calendar, 社媒, 发布计划.","https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team\u002Fblob\u002Fteam\u002Fskills\u002Fbuiltin\u002Fteam\u002Fteam-social-planner\u002FSKILL.md",[],[],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":50,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":74,"publishedAt":19},"01M77RF2JR9BZ9QKXY101Z80F8","项目任务看板","Use when managing team projects, tasks, or sprint tracking with a lightweight markdown kanban board. Create, update, assign, and track tasks across team members without external tools. Trigger on: task board, kanban, sprint planning, assign task, task status, project progress.","https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team\u002Fblob\u002Fteam\u002Fskills\u002Fbuiltin\u002Fteam\u002Fteam-project-tracker\u002FSKILL.md",[],[],{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":50,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":19},"01M77REYK38P4W54XQVFFV0GF2","新人入职","Use when onboarding a new team member to the company, project, or development environment. Covers environment setup, account provisioning, access permissions, first-day tasks, and knowledge base orientation. Trigger on: onboarding, 入职, new employee, 新人, setup workstation, 环境配置, first day.","https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team\u002Fblob\u002Fteam\u002Fskills\u002Fbuiltin\u002Fteam\u002Fteam-onboarding\u002FSKILL.md",[],[],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":50,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":19},"01M77RESXY98BF66BSTPZADB4W","会议纪要","Use when recording, structuring, or extracting action items from team meetings. Creates standardized meeting minutes with decisions, action items with owners and deadlines, and follow-up tracking. Trigger on: meeting notes, 会议纪要, meeting minutes, 开会记录, standup notes, decision log, 会议记录.","https:\u002F\u002Fgithub.com\u002Ffinewood2008\u002Fcentaurai-team\u002Fblob\u002Fteam\u002Fskills\u002Fbuiltin\u002Fteam\u002Fteam-meeting-minutes\u002FSKILL.md",[],[]]