dsh
Akimiya-z/codex-guard在 DeepSeek Harness 内做提交前的 Pull Request 卫生检查:扫描当前改动中的 TODO 残留、硬编码密钥与非规范提交信息。
DSH 侧边栏的维护者 + 开发者 PR 看板:五状态评审队列(等我 / 等作者 / 可合并 / 已合并 / 待分诊)、三列 issue 看板、跨仓库跟踪自己 PR 的 mine 视图(我的回合 / 等别人 / 已合并),附 CI 汇总徽章与不活跃过滤,点卡片一键打开或新建对应的评审会话。
Maintainer PR review queue board for DeepSeek Harness (DSH). It answers one question: which PRs need me, right now?
一个为 DeepSeek Harness 做的维护者 PR 看板:回答一个问题——现在哪些 PR 在等我?
*The board shown with example data — the repository, authors, PR numbers and titles are all fictional, and the image carries an EXAMPLE stamp. · 图中的仓库、作者、PR 编号与标题均为虚构,图上带有 EXAMPLE 水印。*
*The same example data in the sidebar: one PR row and one indented issue row per repository (me / author / ready / inbox, then me / reporter), plus a mine row for PRs you authored. · 同一套示例数据在侧边栏里的样子:每个仓库一行 PR 计数 + 一行缩进的 issue 计数(等我 / 等作者 / 可合并 / 待分诊,然后是等我 / 等报告者),外加一行 mine 表示你自己提的 PR。*
Reviewing PRs is a queue-management problem. GitHub's native views don't tell you: "the author just pushed a fix after my change request — it's back on your plate". This board classifies every PR you're involved in into five states and detects the moment a PR moves back to you.
Review PR 本质是队列管理。GitHub 原生界面无法直接告诉你"作者刚在你 request changes 之后推了新提交,又该你出手了"。本插件把你参与的每个 PR 归入五种状态,并在 PR 回到你手上的一刻提醒你。
Column / 列 · Meaning / 含义 · How it's decided / 判定依据 Waiting on me 等我行动 · Your move / 该你出手 · Review requested with no substantive word from you yet; or the author pushed/replied after your last action; or new commits landed after your approval. Your own substantive comment holds the ball with the author — emoji-only / "+1"-style comments don't count on either side Waiting on author 等作者行动 · Their move / 等作者 · You (or another maintainer) requested changes and the author has been quiet since; approved but draft or conflicting Ready to merge 可合并 · Green light / 绿灯 · reviewDecision = APPROVED, mergeable, not draft — or in a merge queue, or auto-merge armed with nothing blocking (blocked auto-merge waits on the author) Merged 已合并 · Done / 完成 · Recently merged PRs you reviewed Inbox 新 PR 待分诊 · New & unclaimed · Newest open PRs you haven't touched — one click ("我来 review") adds you as reviewer
Transition detection: when a PR crosses author → you (author responded, or re-requested your review), you get a toast and the sidebar widget pulses. Status-quo polling keeps the board fresh (interval configurable: 1–30 min).
Each monitored repo gets a second sidebar row (indented, iss tag) with issue counters; clicking it opens a three-column issue board: Waiting on me (the reporter replied after your last comment, or you're assigned/mentioned with nothing from you yet), Waiting on reporter (you hold the last word), and Recently closed (closed within 14 days, regression watch). Third-party comments don't pull a thread back to you — only the reporter's do. Card clicks open or start a review conversation exactly like PR cards.
每个监控仓库在侧边栏多一行缩进的 issue 计数(iss 标签),点开是三列 issue 看板:等我行动 / 等报告者 / 最近关闭。只有报告者的回复会把线程拉回 "等我";第三方评论不会。点卡片同样进入/新建对应会话。
状态迁移检测:当 PR 从"等作者"切到"等你"(作者回复 / 重新 request 你 review)时弹 toast 提醒、侧边栏小部件闪烁;轮询间隔 1–30 分钟可配。
gh)installed and authenticated (gh auth login). The plugin shells out to gh for search + GraphQL queries, so it respects your gh token scopes and GitHub's rate limits. If gh is missing or logged out, the board shows a setup hint instead of raw errors.
DSH 宿主机上需安装并登录 gh;插件通过 gh 的 search + GraphQL 查询取数, 速率限制遵循你 gh token 的配额。若 gh 缺失或未登录,看板会显示安装/登录 指引而不是原始报错。
dsh plugin --profile web add github:delock/dsh-pr-board(or publish to npm and dsh plugin --profile web add dsh-pr-board)
Then restart the web profile and refresh the page.
Alt+P). On first open you're prompted to add a repository (owner/name, e.g. octocat/hello-world).
own Me / Author / Ready / Inbox counters. The + button in the widget header (or on the board's tab bar) adds another repo; hovering a tab in the board shows an × to stop monitoring it (removal lives inside the board only). Repos are identified by short name, falling back to the full owner/name when two monitored repos share a name.
gh login account (one identity across all repos).
global default: every repo carries an explicit workspace, and repos without one open their cards on GitHub. When set, clicking a PR card jumps into the matching conversation inside DSH. Sessions are matched through a local PR→session binding table first, then by title search (repo#N, which works once a session's LLM-generated title exists); a miss creates a new session in the configured workspace, binds it, and — unless auto-prompt is off — sends it a first message naming the PR plus the board's own snapshot (state, CI, flags), asking it to summarize what has recently happened on the PR (events and standing, not a code walkthrough) and then ask what you'd like to do. That first message is also what generates the session title. With no workspace set (or via the per-card ↗ button) cards open GitHub.
review workspace, auto-prompt, inactivity window) sync to the host (~/.dsh/pr-board.config.json); each browser keeps only its poll interval. A new device picks the config up on first load; edits converge on every poll.
配置跨设备共享:账号级字段(仓库列表、用户名、review workspace、自动 prompt、不活跃天数)同步到 host(~/.dsh/pr-board.config.json),每个浏览器 只保留自己的轮询间隔。新设备首次打开即继承配置,改动在每次轮询时收敛。
For every open PR you have reviewed / commented on / been requested on, the host fetches via GraphQL: reviewDecision, mergeable, draft flag, last commit time, and the full review + comment timeline. Then:
your OK
对每个你参与过的 open PR,host 端经 GraphQL 取 reviewDecision、mergeable、 draft 标记、最后提交时间及完整 review/评论时间线,据此计算"双方最后动作"、 "批准后有无新提交"、"其他 maintainer 是否提过修改意见"等,得出最终分类。
The Inbox column carries three triage controls at the right end of its header row, after the "Inbox " label — a draft checkbox (uncheck to hide draft PRs), an @author field (login substring, @ optional) and a keyword field (title substring, or a PR number). Sitting inline means they add no vertical space and every column's header and first card stay on one line. They narrow the cards the host already delivered, so typing is instant and costs no GitHub API calls. The header count switches to shown/total while anything is hidden, and the column shows "no match" instead of an empty inbox when everything is filtered away. Filters are a per-browser view preference (like the sort toggle), stored in localStorage; they do not sync to the host and do not change the sidebar counters.
Caveat: the host fetches the newest 100 open PRs as the inbox candidate pool (INBOX_POOL in index.js), so filters refine that pool — they cannot surface a PR outside it. The search API serves 100 per page, so this pool costs exactly one search request per refresh cycle — the same single request the old 40-item pool cost — and it needs no GraphQL detail calls.
Inbox 列的列头行右端、紧跟 "Inbox " 之后有三个分诊控件:draft 勾选框 (取消勾选即隐藏 draft PR)、@author 输入框(作者登录名子串,可省略 @)和 keyword 输入框(标题子串,或 PR 编号)。放在同一行意味着它们不占额外竖向 空间,五列的列头与首张卡片始终对齐。它们只过滤 host 已取回的卡片,输入即时生效、 不消耗 GitHub API。有内容被隐藏时列头计数变成 显示数/总数;全部被过滤掉时 显示 "no match" 而不是空 inbox。过滤条件属于每个浏览器的显示偏好(和排序开关 一样),存在 localStorage,不同步到 host,也不改变侧边栏计数。
注意:host 以最新的 100 个 open PR(index.js 的 INBOX_POOL)作为 inbox 候选池,过滤只在这个池子里收窄,无法捞出池外的 PR。搜索 API 每页最多 100 条, 所以这个池子正好一次 search 请求(和原来 40 条池子一样,不额外多花), 且不需要 GraphQL 详情调用。
All queries run locally through your own gh CLI. No third-party service, no telemetry, no data leaves your machine except GitHub API calls.
所有查询经本机 gh CLI 完成,无第三方服务、无遥测。