图像与设计
当用户给 GitHub PR 链接并要求审查/走查/总结时…
针对 GitHub PR,抓取 PR 数据并生成带注释、伪代码摘要、折叠机械改动和自动 diff 渲染的交互式 HTML review 走查页。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
当用户给 GitHub PR 链接并要求特定
解决思路
- 触发:当用户粘贴 GitHub PR URL 并要求 review、walkthrough、summary,或说 'review this PR' 时,使用本技能生成交互式 HTML 审查走查页。
- 第 1 步:并行运行这些 gh api 调用抓取 PR 数据:`gh api repos/{owner}/{repo}/pulls/{number} --jq '{title, body, user: .user.login, state, additions, deletions, changed_files, base: .base.ref, head: .head.ref}'`。
- 同上:`gh api repos/{owner}/{repo}/pulls/{number}/files --paginate --jq '.[] | {filename, status, additions, deletions, patch}'`。
- 同上:`gh api repos/{owner}/{repo}/pulls/{number}/comments --jq '.[] | {user: .user.login, body, path, line}'`。
- 第 2 步:阅读 diff,理解 PR,然后直接把 `<body>` 内容写成 HTML;有完全创作自由,目标是向 reviewer 清楚解释 PR;使用最适合该 PR 的结构。
- 典型结构:Header 含 title、PR number、author、stats;Summary box 用 plain English 解释 PR 做什么;core file sections 带 annotations 和 diffs;mechanical/boilerplate files 默认折叠;底部 review checklist。
- 可添加 pseudocode summaries:对 verbose code 用 plain English 或短 pseudocode 展示算法,真实 diff 折叠在下方;用 `.bp-section` 卡片并标注 `Show full implementation`,适用于 150 行 retry/backoff/error-handling 实际只是 'fetch with exponential backoff and circuit breaker' 的情况。
- Pseudocode 模式示例做法:用 `.file-card` 包裹文件;`.file-hdr` 放文件名和增删统计并 `onclick="toggle(this)"`;`.file-body.open` 内放 `.file-note`,其中用 `<pre>` 写 plain English pseudocode;下方放 `.bp-section`,`.bp-hdr` 用 `onclick="toggleBP(this)"`,`.bp-body` 内放 `<div data-diff="retryClient"></div>`。
- 还可添加:inline SVG、通过 CDN 的 mermaid、`<pre>` 中的 ASCII art 图表;before/after 控制流 flowchart;old vs new behavior 对比表;warning/question/gotcha callout boxes;有帮助的 interactive widgets;以及任何让 review 更清楚的内容。
- 第 3 步:从技能目录读取 `styles.css` 和 `renderer.js`;它们提供预置 dark-themed toolkit;把它们原样注入 `template.html`。
- 可用 CSS classes:`.header`、`.header h1`、`.header-meta` 用于 page header。
- `.pill.add`、`.pill.del`、`.pill.files` 用于 stat badges(+N、-N、N files)。
- `.content` 用于居中内容 wrapper(max 900px)。
- `.summary` 用于 Summary/TL;DR box。
- `.section-title` 用于带 bottom border 的 section heading。
- `.ic` 用于 inline code reference(mono、blue、dark bg)。
- `.file-card`、`.file-hdr`、`.file-body` 用于 collapsible file card(在 `.file-hdr` 上用 `onclick="toggle(this)"`)。
- `.file-note` 用于 file card 内 sticky reviewer annotation。
- `.bp-section`、`.bp-hdr`、`.bp-body` 用于 collapsed boilerplate card(用 `onclick="toggleBP(this)"`)。
- `.bp-note` 用于 boilerplate card 内 note;`.verdict` 用于 review checklist box。
- 可用 JS functions:`toggle(hdrElement)` 切换 `.file-body` 开/关;`toggleBP(hdrElement)` 切换 `.bp-body` 开/关;`renderDiff(target, diffInput)` 渲染 unified diff;`target` 可为 DOM element、string ID 或 CSS selector;`diffInput` 可为 raw patch string 或 lines array;它会自动过滤 imports、折叠 whitespace-only changes、检测 moved code(blue/purple tint);`esc(string)` HTML-escape 字符串。
- 渲染 diffs:用 `data-diff` attributes 和 auto-discovery;在 body HTML 中放 `<div data-diff="KEY"></div>` placeholders;renderer 在 DOM load 后自动查找并从 `template.html` 中的 `<script id="pr-diffs-json" type="application/json">` 元素填充。
- CRITICAL:patch strings 可能包含 `</script>`、newlines、backslashes、quotes;即使 `json.dumps(...)` 也不够,如果直接粘贴 raw output 到 executable `<script>`,HTML parsing 可能提前终止 tag;绝不手动把 patch strings 嵌入 JS/JSON。
- 安全做法 1:在 fetch 阶段用 `jq` 保存 patches 到 JSON 文件:`gh api repos/{owner}/{repo}/pulls/{number}/files --paginate --jq '[.[] | {key: (.filename | gsub("[^a-zA-Z0-9]"; "_")), value: (.patch // "")}] | from_entries' > /tmp/pr-patches-{number}.json`。
- 安全做法 2:在 assembly 阶段用 Python 安全注入 JSON 到 `template.html`:读取 `/tmp/pr-patches-{number}.json`、`/tmp/pr-review-{number}-body.html`、技能目录的 `styles.css`、`renderer.js`、`template.html`;用 `json.dumps(patches)` 生成 JSON,并把 `<`、`>`、`&` 替换为 script-safe 的 Unicode escape;用 `replace` 替换 `/* INJECT_CSS */`、`/* INJECT_JS */`、`<!-- INJECT_BODY -->`、`{"__PR_DIFFS_PLACEHOLDER__":true}`;写出 `/tmp/pr-review-{number}.html`。
- 这样做保证 valid JSON 和 script-safe HTML embedding;agent 把 body HTML 写到 temp file,然后 Python 安全组装所有内容。
- diff data keys 应匹配 HTML 中 `data-diff` attribute values,例如 `<div data-diff="path_to_file_ts"></div>`。
- 因为 `renderer.js` 在 `<head>` 加载,也可以从 inline `<script>` 直接调用 `renderDiff(target, lines)` 用于自定义场景;target 接受 DOM element、ID string 或 CSS selector;lines 接受 string 或 array。
- 不限于这些预置件;可以添加自己的 inline `<style>` blocks、`<script>` blocks、SVGs、diagrams 或其他任何内容;预置件节省时间但不约束你。
- 第 4 步:写 body HTML(放入 `<body>` 的所有内容)到 `/tmp/pr-review-{number}-body.html`。
- 第 4 步:用上面的 `jq` 命令把 patches 保存到 `/tmp/pr-patches-{number}.json`。
- 第 4 步:运行上面的 Python assembly script(从技能目录读取 `styles.css`、`renderer.js`、`template.html`,安全注入 body + patches,写出 final HTML)。
- 第 4 步:启动本地 server 到固定端口:`cd /tmp && python3 -m http.server 8432 --bind 127.0.0.1`;后台运行,然后在 in-app browser 导航到 `http://127.0.0.1:8432/pr-review-{number}.html`。
- 为什么固定端口和 `cd /tmp`:background shells 没有 TTY,所以 Python 会无限缓冲启动消息 `Serving HTTP on...`;用 port 0 会导致永远读不到选中的端口;`--directory /tmp` 可用但 `cd /tmp` 在不同 Python 版本更稳健;如果 port 8432 被占用,试 8433、8434 等。
- Diff features 由 `renderer.js` 自动处理:过滤 import-only lines;把 whitespace-only changes 折叠为 context lines;检测 moved code blocks(3+ consecutive lines deleted in one place and added identically elsewhere),用 blue/purple 而不是 red/green 渲染;near-matches(moved + small edit)用不同的 purple tint。
- Style notes:dark theme 使用 `#1a1a1a` background、Inter body font、IBM Plex Mono for code。
- Style notes:用 `var(--warning)` 表示 orange、`var(--success)` 表示 green、`var(--danger)` 表示 red、`var(--accent)` 表示 blue。
- Style notes:sticky file headers(`position: sticky; top: 0`)和 notes(`top: 35px`)在滚动时固定。
- Style notes:core files 默认展开(`.file-body.open`),mechanical files 默认折叠。
适用边界 · 注意事项
- 不适用于非 GitHub PR、没有 PR URL、或无法访问 GitHub API 的场景。
- 不适用于未安装或未认证 `gh` CLI 的环境。
- 不适用于只需要纯文本评论/摘要、不需要交互式 HTML 或本地 server 的场景。