mcpField
G
greenlight

greenlight

本地服务
github.com/CloudCorpRecords版本控制01 天前更新

关于 greenlight

greenlight 是面向开源贡献者、AI 编码 Agent 和维护者的 GitHub 贡献协调工具,可在选题、提交前检查及 PR 分流中提供依据明确的判断。

主要功能

  1. 01检查 Issue 是否可贡献、已被认领或受门槛限制
  2. 02扫描并排序适合处理的 Issue
  3. 03检查仓库规则与贡献门槛
  4. 04本地运行 PR 检查并分析 CI
  5. 05追踪认领并识别重复 PR

适用场景

  1. 01开工前确认 Issue 是否已有进行中的 PR
  2. 02提交前运行测试、Lint 和仓库规范检查
  3. 03维护者筛查新 PR 和重复变更
  4. 04为贡献活动挑选可处理的 Issue

MCP 相关

通过 stdio 提供 MCP 服务,将 33 个工具开放给编码 Agent,涵盖 Issue 预检、PR 检查与贡献协调。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"cloudcorprecords-greenlight": {
"command": "npx",
"args": [
"-y",
"@reneturcios/greenlight"
]
}
}
}
启动命令npx -y @reneturcios/greenlight

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@reneturcios/greenlight0.23.0
ocighcr.io/cloudcorprecords/greenlight:0.23.0

工具

9

收录的工具列表 · 更新于 今天

参数类型必填说明
issue_urlstring是完整的 GitHub issue URL,例如 https://github.com/owner/repo/issues/123

详细介绍

Greenlight

Greenlight 是开源贡献的前期准备与协调层:它是外部贡献者(越来越多是 AI Agent)与公共代码仓库维护者之间的软件,并能回答其他工具无法回答的问题。我能在这里贡献吗?这个议题是否已被人悄悄认领?这里有哪些规矩?还有谁在和我竞争?对维护者来说:是谁在大量涌入我的队列?哪些内容可以安全合并?

为什么需要这一层

跟着风险投资的资金流向,你就会发现它没有流向哪里。Cognition(Devin)融资约 20 亿美元,估值达 480 亿美元;Factory 融资 2 亿美元,估值达 50 亿美元,目的是在企业自己的代码仓库中运行自主编码 Agent。CodeRabbit 融资 8,800 万美元(估值接近 5.5 亿美元),Graphite 在被 Cursor 收购前完成了 5,200 万美元的 B 轮融资,Greptile 则完成了 2,500 万美元的 A 轮融资;它们审查的都是团队自己的拉取请求。OpenHands 是一个 Agent 运行时。每家获得融资的厂商都假定你身处组织内部。

没有人负责这条边界。没有获得风投支持的工具能回答外部贡献者的问题:我能在这里贡献吗?这个议题是否已被人悄悄认领?这个代码仓库有哪些门槛和 AI 政策?还有谁在和我竞争?也没有获得风投支持的工具能回答维护者的问题:这 30 个未关闭的 PR 中,哪些是重复的?谁认领了什么?哪些认领已经过期?哪些由 Agent 编写的 PR 可以安全合并?Greenlight 就是这一层,它是在每周通过实际贡献活动不断运行和打磨的。

问题所在

AI 让编写代码变得廉价。贡献协调如今成了瓶颈,而且会以具体、反复出现的方式出问题:

  • 隐形竞争。 议题列表视图会误导人。在对 usebruno/bruno 进行的一次人工审核重点环节中,7 个看似有希望的议题里有 6 个已被悄悄认领,相关 PR 只显示在议题时间线中,列表视图和搜索结果中都看不到。你可能花上一个周末做的工作,早已被人完成。
  • 门槛与禁令。 Greenlight 自己的 Agent 政策索引现在追踪 505 个代码仓库:其中 127 个(25%)设有贡献门槛,19 个明确禁止 Agent 贡献。整个代码仓库(nuxt、uv、Gradio、Activepieces)都对外部 PR 关上了大门。没人告诉你;规定写在 AGENTS.md 里。
  • 重复的 AI PR。 多位贡献者(人类或 Agent)争相处理同一个议题时,维护者会收到三个内容重叠的 PR,却没有办法进行协调。GitHub 没有认领系统,只有评论。
  • 四处散落的规矩。 CLA、DCO 签署、changeset、提交格式、申请分配。每个代码仓库都有自己的一套规矩,把它们藏在不同文件里,还会因为细枝末节拒绝你的 PR。

这些都是协调问题,不是编程问题。代码 Agent 越来越强,边界却越来越混乱。Greenlight 负责处理这条边界。

Greenlight 的功能

三个层次,从决策到解决,再到协调:

层次回答的问题旗舰命令
决策这个问题该由我来处理吗?这个仓库值得我投入时间吗?check、scan、friction、xray、racecheck、wave、preflight
解决我的 PR 会通过吗?哪里出了问题?接下来该做什么?ci-prep、ci、review、brief、verify、autopilot、babysit、evidence
协调谁在做什么,由谁解决冲突?claim(加上 Claim Protocol)、guard、radar、digest、passport
  • 决策。 check 会读取问题、相关评论、关联和提及的 PR(时间线、搜索结果和评论引用),以及仓库规则,然后用通俗语言给出结论:GO、RISKY、TAKEN、GATED 或 STALE。scan 会为仓库的未关闭问题排序,让你优先选择胜算较大的问题。friction 会以 0 到 100 分评估实际合并 PR 的难度,每个门槛都会引用其证据来源文件。xray(Timeline X-Ray)会在你开始编写代码前,深入核查候选问题的时间线,发现隐藏的进行中 PR,包括由问题报告者提交的修复 PR;scan --deep 会先将已被认领的问题降级,再展示列表。racecheck(Keyword Race Check)能发现 X-Ray 看不到的竞争:有未关闭 PR 修复了相同问题,却从未关联该问题。它会根据问题关键词(文件名、标识符、特征词)而不是链接来查找,并给出 RACE / SUSPECT / CLEAR 判定及引用的关键词证据;scan --deep 和 xray 会自动调用它。v0.20.1 的精度改进确保它在真实仓库中保持准确:GitHub 标签名、URL 路径片段和仓库模板中的样板内容(通过对扫描的 PR 队列进行文档频率抑制)都不会被视为证据;基于术语判为 RACE 必须使用从标题提取的术语;共享的变更文件还必须有显著的共同命中,因此仅有相邻关系会判为 SUSPECT,而不是 RACE。wave 可通过一条命令将 Agent Policy Index 转换为构建队列:筛选出胜算较大的未关闭仓库和经 X-Ray 核查的入门问题,并排除带行为门槛的问题。
  • 解决。 ci-prep 会在推送前于本地运行仓库自身的拉取请求检查(测试、lint、类型检查,以及变更日志、提交格式、DCO 等规范),避免本可避免的 CI 失败出现在维护者面前。ci 会根据基分支历史,将未通过检查的 PR 分类为已有问题、可能由你引入的问题或外部阻塞因素。review 会将每个审查讨论线程分类为可能是真问题、可能是噪声或需要决策,并起草回复。verify 会如实报告你的更改对测试通过与失败情况的影响。autopilot 会根据代码当前版本核实 Bot 的发现,并自行修复机械性问题(处理 DCO、重新合并冲突、格式化)。brief 会为任意 PR 汇总一份经过核实的单屏简报:按领域和风险说明更改概况、根据基分支历史分类 CI 状态、依据证据将发现归类为真问题或误报、标明是否有测试证据(若没有则明确注明)、列出合并阻塞因素,并给出一句优先查看事项。babysit 会监控你未关闭的 PR,并报告一份按优先级排列的行动清单。
  • 协调。 claim 会发布协议认领(含过期租约、公开队列、心跳;完整规范见 protocol/SPEC.md),并提供通过 --via-api 使用托管应用客户端的选项。guard 会为维护者分析收到的 PR:是否有竞争性修复、是否有先前认领、是否缺少必要材料,以及贡献者是否为首次参与。digest 会报告仓库中的 PR 竞争、被他人认领的冲突、过期认领和分配门槛冲突。radar 会扫描整个未关闭 PR 队列,根据证据将竞争或重复的 PR 分组,并建议保留哪个;它会明确标注这只是启发式结果,而非定论。passport 会汇总贡献者已合并的工作和认领记录。

每个判定和每份报告都会引用证据:被引用的政策条款、认领评论 URL、PR 编号或失败的检查。任何结论都不会在缺少来源的情况下提出。

面向对象

  • 贡献者(人类)。 在 issue 上花一晚之前,先运行 check。挑选要处理的任务时,运行 scan。推送前,运行 ci-prep。
  • AI Agent 和编码工具。 运行一条命令(init --agent claude-code,也支持 cursor、copilot、windsurf、cline),即可安装 MCP 配置和唯一一条行为规则:打开 PR 前先检查 Greenlight。Agent 最浪费 token 的情况,就是去修复已经有人接手的 issue;33 个 MCP 工具让整个引擎在运行过程中都能使用。
  • 维护者。 对每个新收到的 PR 运行 guard,用 radar 扫描所有未关闭的任务队列,用 digest 进行每周分流,并通过下方路线图管理控制室:清理过期认领、执行策略、过滤 AI PR。

明确列出实证

  • 1194 项测试全部通过,包括一个基于真实活动案例固定下来的测试夹具集(已被接手的 issue、内容不足的 PR 提及、先认领再通过的门槛、范围限定的认领、未完成交付的 issue、过期认领、暂停 PR 的工作流)。
  • 在真实活动中使用过:该工具包已在数十个公开开源仓库中创建了 80 多个拉取请求。每项功能都源于一次真实贡献因缺少它而失败。
  • 在受众常去的所有地方都可获取:npm(@reneturcios/greenlight)、MCP Registry 和 GHCR(ghcr.io/cloudcorprecords/greenlight),另有 Docker 和直接 MCP stdio。
  • 随附两个持续更新的数据集:贡献摩擦指数(data/friction-index.json)和 Agent 策略指数(505 个仓库、127 个设有门槛、19 个禁止 Agent,发布于 docs/policy.html);两者都基于真实活动实地工作构建,而非抓取得来的猜测。

看它如何运作

Greenlight 演示

59 秒演示:在真实仓库中检查真实 issue、AI 发现隐藏认领、发现禁止 Agent 的 GATED 状态、活动任务侦察,以及认领看护工具。完整解说视频。

安装

npx @reneturcios/greenlight check <issue-url>

设置 AI 编码工具并验证设置:

npx @reneturcios/greenlight init --agent claude-code   # one-command MCP setup (cursor, copilot, windsurf, cline work too)
npx @reneturcios/greenlight doctor                     # checks Node version, token, GitHub quota, cache

或者从源代码安装:

npm install
npm run build

设置 GITHUB_TOKEN(经典个人访问令牌;访问公开仓库不需要任何权限范围),即可将 GitHub API 速率限制从每小时 60 次提高到 5000 次。Greenlight 会将 API 响应缓存到 ~/.cache/greenlight。

通过 npx @reneturcios/greenlight mcp(stdio)运行 MCP 服务,或者让 Agent 使用 greenlight 命令,并将 mcp 作为唯一参数。

使用 Docker 运行

Greenlight 也提供 GHCR 容器映像:ghcr.io/cloudcorprecords/greenlight。

将其用作 stdio MCP 服务:

docker run -i ghcr.io/cloudcorprecords/greenlight

可以在映像名称后传入任何 CLI 命令,替代默认的 mcp 参数:

docker run ghcr.io/cloudcorprecords/greenlight check <issue-url>
docker run ghcr.io/cloudcorprecords/greenlight --version

在 AI 编码工具中使用

运行一条命令即可完成设置:

npx @reneturcios/greenlight init --agent claude-code

(也支持 cursor、copilot、windsurf、cline;如需设置多个工具,可重复使用 --agent)。Init 会将 MCP 配置复制到项目中,并安装工作流指令片段,教会 Agent 唯一一条行为规则:打开 PR 前先检查 Greenlight。 更喜欢手动设置?integrations/ 集成包提供了可直接复制的 MCP 配置,以及相同的指令片段。然后通过“列出你的 MCP 工具”提示词进行验证;greenlight 服务包含 33 个工具(见下方列表)。

CLI

# One-command setup for your AI coding tool (cursor, copilot, windsurf, cline work too)
npx @reneturcios/greenlight init --agent claude-code

# Verify the setup: Node version, token, GitHub quota, cache (exit 1 when anything fails)
npx @reneturcios/greenlight doctor

# Help: overview, one command's flags, or the version
npx @reneturcios/greenlight help check
npx @reneturcios/greenlight --version

# Verdict for one issue
npx @reneturcios/greenlight check https://github.com/batrapulkit/squidbrake/issues/74

# [GO] batrapulkit/squidbrake#74
#   Taint: tell the approver when an agent edits its own setup right after reading outside content
#   - open, unassigned, no linked PRs, no claim signals, no blocking gates

# Rank a repo's starter issues, GO first (falls back to recent open
# unassigned issues when the repo does not use those labels; --no-fallback to opt out)
npx @reneturcios/greenlight scan PrefectHQ/fastmcp

# Deep-verify candidates against their timelines first (catches hidden in-flight PRs)
npx @reneturcios/greenlight xray usebruno/bruno --issues 8149,9319
npx @reneturcios/greenlight scan usebruno/bruno --deep

# Keyword race check: is an open PR already fixing this issue without
# ever linking it? (link-based checks cannot see it; exit 1 on RACE)
npx @reneturcios/greenlight racecheck sveltejs/kit 17465

# Scans stop on a wall-time budget (default 600s; override with --max-time <seconds>).
# A scan that hits the budget returns the results gathered so far, labeled partial:
# --json gains partial: true, partial_reason ("scan time budget 600s reached; evaluated
# K of M candidates"), evaluated, and candidates; the human output prints the results
# plus a "Partial scan:" line naming the budget. Partial scans still exit 0.
npx @reneturcios/greenlight scan PrefectHQ/prefect --max-time 300

# Friction score for a repo
npx @reneturcios/greenlight friction triggerdotdev/trigger.dev

# CI triage for a red PR: is each failing check yours or pre-existing?
npx @reneturcios/greenlight ci https://github.com/reticlehq/reticle/pull/1620

# [pre-existing] install-gate (windows-latest)
#   same check failing on base: 2 of 3 recent base runs, last at 2026-10-14T10:00:00Z

# [external-blocker] Vercel - Authorization required
#   check name matches the Vercel deploy/auth pattern; this failure is infrastructure, not the PR

# JSON output for scripting
npx @reneturcios/greenlight ci <pr-url> --json

# CI pre-flight: run a repo's own PR checks locally before pushing (exit 1 on NO-GO)
npx @reneturcios/greenlight ci-prep ~/work/bruno

# [PASS] tests (workflow ci, job build)
# [SKIPPED] publish (workflow release, job release) - publishes a package
# [PASS] convention: DCO sign-off
# Verdict: GO

# Review triage for a PR with review feedback: which comments need you?
npx @reneturcios/greenlight review https://github.com/n8n-io/n8n/pull/41235

# Verified review brief for any PR: change shape by area and risk, CI
# triaged against base-branch history, findings classified with evidence,
# test evidence present or explicitly marked absent, merge blockers, and
# a one-line look-at-this-first
npx @reneturcios/greenlight brief https://github.com/usebruno/bruno/pull/9569

# Brief: 4 files (+335/-11), 2 source + 2 tests
# CI: code checks green; external blockers named (fork workflows require maintainer approval)
# review: NO FINDINGS
# blockers: none
# lookFirst: No blockers or real findings. Start here: 2 source files carry the change.

# Campaign scout: rank repo targets, dedupe against the campaign file, append as SCOUTED
npx @reneturcios/greenlight scout --repos acme/widgets,acme/gadgets --campaign campaign.json --write

# Babysit your registered claims: linked, linked-dead, healthy-active, heartbeat-due, expiring, unlinked-stale, queue-lost
npx @reneturcios/greenlight babysit --claims-only
# A claim whose linked PR closed unmerged reads linked-dead, with a release
# prompt: the issue is free, but the stale marker needs an explicit release.

# Pacing: claim posts never trip GitHub's anti-spam flag
# Every post attempt is ledgered at ~/.greenlight/posting-ledger.json
# (timestamp, kind, target, outcome). Claim posts enforce a minimum
# interval (default 90s, jittered; GREENLIGHT_CLAIM_MIN_INTERVAL_S, or
# --min-interval) and a daily soft cap (default 25 per rolling day;
# GREENLIGHT_CLAIM_DAILY_CAP, 0 disables). A post that fails with a block
# or an uncertain network error is marked UNCONFIRMED; the tool re-reads
# the target against the API before ever posting to it again, so a
# "failed" post that actually landed is marked confirmed and never
# reposted. --force overrides any pacing refusal, and the override is
# ledgered. greenlight status shows your pacing posture.
npx @reneturcios/greenlight status https://github.com/owner/repo/issues/123

# Maintainer guard for an incoming PR: competing fix, prior claims, missing
# artifacts (changeset / DCO / CLA), first-time contributor. Renders markdown
# ready to post as one comment; Greenlight itself never posts.
npx @reneturcios/greenlight guard https://github.com/owner/repo/pull/123

# Greenlight guard: 1 thing to check
#   - Missing release-note file (repo uses .changes/): expected .changes/123-slug.md
npx @reneturcios/greenlight guard <pr-url> --quiet   # exit 3 when flagged, silent otherwise

# Duplicate/competing PR radar for the whole queue: clusters PRs fixing the
# same issue or touching the same files, with evidence and a suggested keep
# per cluster (always labeled a heuristic, never a verdict)
npx @reneturcios/greenlight radar usebruno/bruno --limit 100

# 100 open PRs scanned in 6 API calls: 3 competing clusters, 94 unclustered
# cluster (same issue #5011): #5016 "Fix: Param table UI breaks bug" ~ #5074 "fix: Param Table UI Breaks on resize" - suggested keep #5016 (heuristic)
# cluster (file overlap, 100% Jaccard in packages/): #3484 ~ #5747 - suggested keep #3484 (heuristic)

# Verified comment for a maintainer-only repo: the issue takes no outside
# PRs (inspector, servers), so the contribution is a detailed, verified
# comment. Assembles from your notes or a markdown file; sections you
# leave empty render as explicit gaps, never filler. Never posts.
npx @reneturcios/greenlight verify-comment https://github.com/modelcontextprotocol/inspector/issues/2723 \
  --claim "TUI tests append to the developer's real ~/.mcp-inspector/auth.log" \
  --env "modelcontextprotocol/inspector @ 3a4b5c6, 2026-10-15" \
  --repro $'point HOME at a scratch dir\nrun: vitest run __tests__/App.test.tsx' \
  --observed "155 lines appear in the scratch HOME's auth.log" \
  --expected "test runs leave the developer's home directory untouched" \
  --root-cause "clients/tui/__tests__/setup.ts does not isolate the log dir" \
  --fix "per-test-file temp dir via fs.mkdtempSync, set MCP_INSPECTOR_LOG_DIR, remove on exit" \
  --ran "vitest run __tests__/App.test.tsx: 130 passed" \
  --by "@CloudCorpRecords"
# or: greenlight verify-comment <issue-url> --from-file notes.md

# Honest red-green test delta, in your repo checkout: runs the detected
# test command on a base worktree and your working tree, and reports what
# your change actually did: newly passing (fixed), newly failing (yours),
# still failing (pre-existing, not yours). Says "unverifiable" with the
# reason instead of guessing when it cannot run or parse.
cd your-repo && npx @reneturcios/greenlight verify --base origin/main
# exit 3 when new failures exist, 1 when unverifiable

# PR babysitter: one prioritized action list across your open PRs --
# needs you now, waiting on them, quiet. Reruns report what changed.
npx @reneturcios/greenlight babysit --mine --repos acme/widgets,acme/gadgets
# or: greenlight babysit --prs <url1>,<url2> --fail-on-action   (exit 3 when action is needed)

# Verified PR evidence pack: guard + CI triage + review triage + protocol
# status of linked issues, in one markdown document where every claim
# cites its source. The test delta comes from a verify report you pass in.
npx @reneturcios/greenlight evidence https://github.com/acme/widgets/pull/42 --out EVIDENCE.md
# or: greenlight evidence <pr-url> --verify-json verify.json

# Contributor passport: protocol claims from the public Claim Ledger plus
# merged PRs from GitHub. No Ledger file yet? It says so plainly.
npx @reneturcios/greenlight passport CloudCorpRecords

# The proxy, for authenticated reads (60/hr anonymous -> 5000/hr token):
# reads GITHUB_TOKEN once at startup, attaches it server-side, binds
# 127.0.0.1 only, and refuses to start without a token.
export GITHUB_TOKEN=<your-classic-token> && greenlight proxy &
export GREENLIGHT_GITHUB_BASE_URL=http://127.0.0.1:8792 GITHUB_TOKEN=proxy

# Verify every link of a release chain (tag, commit, release, npm, registry)
npx @reneturcios/greenlight shipcheck <owner/repo> --version x.y.z

我们的审核实例:

  • batrapulkit/squidbrake#74 得分为 GO:0 条评论,标记为 help wanted,没有认领,没有门槛。
  • shadcn-labs/pdfcn#58 得分为 RISKY(已认领标记):我们审核的当天就有志愿者请求分配任务。
  • langchain-ai/langchain#41185 得分为 TAKEN(认领竞争):仍处于“未分配”状态时,已有 3 位有力认领者。
  • PrefectHQ/fastmcp#5718 得分为 GATED:FastMCP 要求先分配任务,或添加“prs welcome”标签,才能提交 PR。
  • triggerdotdev/trigger.dev#5016 得分为 GATED:未经背书的作者提交的 PR 会被自动关闭,必须先申请背书。

MCP 服务

同一引擎也通过 stdio 向编码 Agent(Claude、Cursor、Cline)开放。切入点:Agent 浪费的 token 大多用于修复已被接手的问题。让 Agent 在编写代码前先检查问题。

{
  "mcpServers": {
    "greenlight": {
      "command": "npx",
      "args": ["-y", "@reneturcios/greenlight", "mcp"],
      "env": { "GITHUB_TOKEN": "your-token" }
    }
  }
}

工具(33 个):

  • check_issue - 单个问题 URL 的评估结果
  • scan_repo - 对仓库中待处理问题排序,GO 优先(先选带标签的入门问题,若无则选近期未分配的待处理问题;deep: true 会先对候选问题进行时间线透视)
  • xray_issues - 时间线透视:根据时间线深度核验候选问题(隐藏的进行中 PR、报告者自行提交的修复 PR、评论中的声明);逐个问题给出 GO / RISKY / TAKEN,并附上 PR 证据
  • racecheck_issue - 单个问题的关键词竞速检查:查找修复同一问题但从未链接该问题的待处理 PR(如 sveltejs/kit #17465 与 PR #17453 的情况);逐个 PR 引用匹配到的关键词,并给出 RACE / SUSPECT / CLEAR
  • repo_friction - 仓库的摩擦评分
  • wave_queue - 一次调用构建队列:从 Agent Policy Index 中筛选有胜算的待处理仓库,对入门问题进行透视(CLEAR / RISKY / TAKEN),排除行为门槛,并跳过你已有待处理 PR 的仓库
  • verify - 针对已检出的仓库,诚实呈现基准版本与当前版本的测试差异(先检查失败项,绝不只报原始数量)
  • shipcheck - 发布就绪检查:GitHub release、npm 版本、注册表记录和 GHCR 标签;逐项给出 GO / NO-GO
  • passport - GitHub 登录名对应的贡献者通行证:账本资料、已合并 PR 数量、信誉比率
  • bounty_check - 单个问题的悬赏有效性分类:有效平台、无法核实的声明或已失效平台
  • claim_issue - 由评估结果控制的问题认领评论(除非 execute: true,否则仅试运行)
  • prep_issue - 检查 Fork 和分支,并根据仓库已学习到的约定生成本地 PREP.md 清单(除非 execute: true,否则仅试运行)
  • open_pr - 从 Fork 分支创建 PR,并处理 DCO(除非 execute: true,否则仅试运行)
  • ci_prep - 推送前在本地运行仓库自身的 PR 检查(结果为 NO-GO 时退出码为 1)
  • ci_triage - 将 PR 上的每项失败检查分类为已有问题、可能由你引起、无法确定(并说明倾向)或外部阻塞;依据基准分支近期的检查历史进行比较
  • review_triage - 对你 PR 的审查反馈进行分类:每项发现都标为可能属实 / 可能是噪声 / 需要决定,并附原因和回复草稿(绝不会将人类评审标为噪声;只生成草稿,不会发布)
  • pr_brief - 任意 PR 的已核实审查简报:按领域 / 风险分组的文件、根据基准分支历史进行的 CI 分类、有证据支持的真实 / 误报发现分类、测试证据(若不存在则明确标注)、合并阻塞项,以及一句「优先查看此项」提示(绝不编造发现)
  • guard_pr - 维护者侧对新收到的 PR 进行分析:竞争性修复、非作者提出的先前认领、缺失的材料(changeset / DCO / CLA)、首次贡献者。返回可直接用于评论的 Markdown(绝不发布)
  • repo_digest - 仓库级维护者报告:PR 竞速及先认领仲裁、他人已认领的冲突、过期认领、分配门槛冲突、被分流流程暂扣的问题(绝不发布)
  • pr_radar - 维护者侧的重复 / 竞争 PR 雷达:将仓库的待处理 PR 聚类为竞争组(目标问题相同,或变更文件高度重叠),为每组提供证据并建议保留项(始终标注为启发式判断,绝非定论;绝不发布)
  • claim_status - 单个问题的 Claim Protocol 预检:由谁认领、认领期限、排队者、竞争 PR、门槛,以及仓库是否遵守该协议
  • preflight - 一次调用即可获得结论:claim_status 加仓库摩擦摘要
  • verify_comment - 为仅限维护者操作的仓库起草已核实发现评论(仅起草,绝不发布)
  • babysit_prs - 监控待处理 PR 并生成一份按优先级排序的操作清单(现在需要你处理、等待对方处理、暂时无事),与已存储的水位线进行差异比较;同时监控 my-claims 注册表(已关联、活跃且状态良好、需要发送心跳、即将过期、未关联且过期、队列中丢失)
  • evidence_pack - 单个 PR 的已核实 PR 证据包:guard 评估结果、CI 分类、审查分类、已关联问题的协议状态,以及每项认领及其来源
  • scout_campaign - 活动模式:为仓库目标排序,与活动文件去重,并在 API 预算耗尽后恢复
  • my_claims - 认领注册表:已关联、活跃且状态良好、需要发送心跳、即将过期、未关联且过期、队列中丢失
  • sync_campaign - 根据 API 实际状态协调本地跟踪数据(偏差、状态不匹配、过期认领)
  • campaign_portfolio - 一屏式活动摘要:统计数量、按状态分类的认领、待处理队列、偏差数量
  • autopilot_report - 按 PR 分类反馈(只读;核验机器人发现、分类 CI,并将机械性修复列为计划)
  • api_status - 托管认领 API 状态
  • claim_via_api - 通过托管认领 API 认领问题
  • heartbeat_via_api - 通过托管认领 API 发送心跳 在本地运行:npm run dev(MCP 入口是 src/index.ts;CLI 是 src/cli.ts)。

评分方式

判定引擎是确定性的(不使用 LLM),并按以下顺序检查:

  1. 已关闭的问题:TAKEN(绝不可认领)。
  2. 有任何受指派人:TAKEN。
  3. 有一个关联的开放 PR,且该 PR 会关闭此问题:TAKEN。仅仅提及问题编号的 PR(例如 pdfcn 的 PR #91,它会关闭 #70,但在正文中列出了相关问题)只会添加 weak-pr-mention 标记,并将原本为 GO 的判定降级为 RISKY。如果问题被标记为某个已关闭且已完成问题的重复项:判定为 RISKY,并添加 duplicate-of-closed 标记(工作已经交付;若重复项目标仍开放,则仅添加带其 URL 的 duplicate-of-open 警告)。
  4. 有两个或更多强认领者:TAKEN(认领竞争)。
  5. 有一个新的强认领,且针对整个问题(未满 45 天):判定为 RISKY,并添加 claimed 标记。若新的认领只针对问题的一部分(“接手剩余的 fallback 需求”):判定为 RISKY,并添加 claimed 和 partial-claim 标记;原因需指出认领者及其认领范围,绝不判定为 TAKEN。
  6. 有一个超过 45 天、且没有关闭 PR 的强认领:判定为 RISKY,并添加 stale_claim 标记。认领者可能已经放弃,但无法确定。过时的部分认领也按相同方式处理。超过 180 天且没有关闭 PR 的认领则视为衰减:通过 stale-signal 标记披露,并给出降低权重的原因,但本身绝不会阻止认领(两条很久以前的认领不再构成认领竞争,单条很久以前的认领也不再降低干净问题的评级)。
  7. 有硬性门槛(指派、背书、仅限协作者、暂停非应邀 PR、工作流自动关闭外部 PR),且无人被指派:GATED。最后两种情况来自 CONTRIBUTING 中的说明(“已暂停非应邀拉取请求”)以及对 .github/workflows 中自动关闭外部 PR 的工作流的扫描。
  8. 180 天或更久没有活动:STALE。
  9. 软性“先认领”门槛(仓库要求贡献者开始工作前先评论,例如 pdfcn):绝不判定为 GATED;它会将原本为 GO 的判定最高限制为 RISKY,并附带说明,降级方式与弱 PR 提及相同。
  10. 其他情况:GO。
  11. 非作者评论中提及的开放 PR,且其标题或正文提到了问题编号:会将原本为 GO 的判定降级为 RISKY,并添加 comment-mentioned-pr 标记(“可能已经涵盖此问题的一部分”)。这两种情况都不会导致 TAKEN;只有会关闭问题的 PR 才会如此。修复公告评论("/attempt #N" 命令,或“已为……提交修复,见 ”这类说明,通常会链接到相关仓库中的 PR)也会按相同方式降级,但会使用自己的原因并引用 PR URL,同时添加 attempt-linked-pr 标记,即使该 PR 从未提及此问题。/attempt 评论也会登记为强认领。
  12. 部分已解决:提及问题编号的已合并 PR(通过评论提及或关联),或表明部分工作已经交付的维护者评论(“由 #905 完成了一半,因此仍保持开放以处理 B 部分”,“已在 v3.1.0 中发布”,且旁边提及该问题)。仅给出 GO 会掩盖需要限定范围的工作,因此会添加 partially-addressed 标记,并将原本为 GO 的判定最高限制为 RISKY,原因示例:“此问题已有部分内容交付(PR #905,已合并);请将工作范围限定为剩余部分”。绝不判定为 TAKEN。 摩擦分从 100 开始,扣除各项门槛的权重(需完成指派 −25、需担保 −35、仅限协作者 −50、暂停非主动 PR −40、范围受限的暂停 −20、外部 PR 自动关闭 −50、先讨论 −10、先认领 −5、CLA/DCO 各 −5、检测到行为门槛 −20);在可计算时,根据外部 PR 合并率以及审核和响应时间进行调整;对于开放的 good-first-issue,最多加 +10。未知信号保持为 null 并跳过,绝不猜测。当经典入门标签的数量恰好为 0 时,摩擦分会在标签数量旁显示一个仅供参考的候选估算值(在更广泛的入门标签集合中查找开放且未指派的问题,例如 "beginner friendly"、"easy"、"first-timers-only");此估算值绝不计分,也不会并入标签数量。确切公式见 src/friction.ts。

行为门槛不是政策文件,而是根据维护者的实际做法判断。friction 会遍历已关闭 PR 列表,直到找到最近 12 个月内已关闭但未合并的 15 个 PR(超出时间范围的已关闭 PR 会被排除;如果最新关闭的 PR 本身也早于时间范围上限,则会附上“信号过时”说明),然后读取维护者一侧的评论,以查找拒绝 AI 的证据(提及 AI 并带有拒绝措辞、明确使用 "AI slop" 之类的短语,或提及已援引的 "AI policy";而 "AI-assisted PRs are welcome" 等欢迎 AI 的表述会抑制该信号)。两个独立 PR 即可判定仓库存在行为门槛;单个较弱信号会作为警告保留,单个明确的拒绝短语则足以独立触发检测。friction --json 会将其报告在顶层 behavioral_gate 字段中(包括 detected、strength、threshold、包含 PR 编号、引文和 URL 的 evidence,以及 notes);该字段是规范位置,signals.behavioralGate 则作为相同镜像保留,以兼容索引流水线。重新基线等索引流水线会读取规范字段,以重新归类书面政策未作说明、但实际做法带有敌意的仓库。API 调用成本上限为 48 次:最多调用 3 次列表接口以收集 15 个已关闭但未合并的 PR,再为每个 PR 最多获取 3 个证据页面(issue 评论、审核、审核评论);使用 --no-behavioral 可跳过此项。

friction --lite 是规范的轻量摩擦度计算方式:仅考虑政策门槛。它会获取政策来源(根目录、.github/ 和 docs/ 下的 CONTRIBUTING 变体、AGENTS.md、CLAUDE.md 和 AI_POLICY.md,以及组织级 AI_POLICY.md),从中解析门槛,应用 detectRepoPolicy 检测到的仅限协作者推送策略(目前不调用 API),并按精确的文档公式计算分数:从 100 开始,加上门槛权重(使用相同的 GATE_WEIGHTS),然后将结果限制在 [0, 100]。它会跳过行为门槛检测、合并速度(以及其中的外部 PR 合并率项)、首次审核和问题响应时间,以及 good-first-issue 加分:所有结果信号都保持为 null 并跳过,绝不猜测;signals.note 的值为 "lite",报告中则包含 lite: true。gates 和 score 字段的结构与完整摩擦分相同,因此 Agent Policy Index 扫描器可以将 --lite 用作统一的轻量摩擦分实现,而不必自行维护一套实现。

每份摩擦报告(轻量和完整)还包含 policy_provenance:针对每个探测过的政策来源,记录其已读取、不存在或获取失败,从此不会再把“没有政策文件”和“政策获取失败”混为一谈(此前两者显示相同)。在人类可读的输出中,这会呈现为一行摘要,例如:policy sources: 2 read (CONTRIBUTING.md, AGENTS.md), 3 absent, 0 fetch errors。 wave 可通过一条命令将 Agent Policy Index 转换为构建队列:使用现有的 xray 引擎对符合条件的开源仓库进行检查,这些仓库须有外部贡献者合并占比、星标数区间和入门问题(结果为 CLEAR / RISKY / TAKEN,并列出竞争中的 PR);排除检测到行为门槛的仓库,跳过你已提交未关闭 PR 的仓库;当核心 API 预算低于下限(默认 800)或触发搜索限流时,运行会停止并标记部分结果。支持人类可读输出和 --json;每个阶段都会报告所用的 API 调用次数。默认按可胜任度排序候选项(先看外部贡献者合并占比,再看阻碍程度,最后看星标数);--sort stars 可恢复旧的排序方式。

有一种范围限定的接收暂停(“not accepting pull requests that add new formatting options”),它属于独立的门槛类型(scoped_prs_paused),造成的阻碍程度只有全面暂停的一半,也不会直接决定判定结果:check 和 scan 会标记此类暂停,并将结果上限设为 RISKY,同时引用被拒绝的范围。

Autopilot 会持续维护分支健康看板:每个 PR 的可合并状态、mergeable_state、基础 SHA 和落后提交数都会在运行之间保存在其状态中,显示在报告输出里,并包含在 autopilot_report MCP 工具中(branch_health、branch_board)。

还有四个可由 Agent 调用的 CLI 命令会作为 MCP 工具提供:verify(如实对比基础版本与头部版本的测试变化)、shipcheck(发布、npm、注册表和 GHCR 就绪情况)、passport(基于声明记录的贡献者档案)和 bounty(单个问题的赏金活跃度)。

Agent 政策门槛与分诊暂缓

政策文件会从仓库实际存放的位置读取:仓库根目录、.github/ 和 docs/ 中的 AGENTS.md、CLAUDE.md、CONTRIBUTING.md 和 AI_POLICY.md(每个文件名只取首次命中),以及组织级的 .github/AI_POLICY.md。两种门槛类型会解析 Agent 规则:

  • agents_banned 是硬性门槛:禁止自主 Agent 贡献的仓库会被判为 GATED,并以引用的政策原文作为证据;除非使用 --force,否则 claim 会像处理 TAKEN 一样拒绝该仓库。
  • agents_disclosure 是标记,不会改变判定结果:对于要求使用 AI 前缀或披露的仓库,prep 和 check 会给出具体的必要操作。

机器人分诊通知(“wait until maintainers remove the triage or approval label before opening a pull request”)或分诊标签会将问题标记为暂缓:check 会指出暂缓原因,并将原本为 GO 的判定上限设为 RISKY,附加 triage-hold 标记(不会变为 TAKEN);scan 会将暂缓的问题排在无阻碍问题之后。暂缓问题属于未来工作,而非当前工作。

可选的 AI 认领检测

模式匹配层无法识别所有人类表达“我来处理”的方式(有一次,它漏掉了真实问题中的一句“I'm looking into contributing a fix here”)。设置 FIREWORKS_API_KEY 后,check 会增加一道可选的复核:由 Fireworks 的低成本模型读取符合条件的评论(排除机器人和问题作者,与模式匹配使用相同的评论集合),并标记模式匹配漏掉的认领意向表述。

治理规则很明确:

  • 默认关闭。 未设置密钥时不会发起调用,输出与仅使用模式匹配引擎时逐字节一致。
  • 模式匹配优先,成本更低。 只有在模式匹配未发现强烈认领信号时,才会运行 AI 检测。
  • 只添加标记,不改变判定。 AI 标记会添加 llm-claim 标记,并以准确引文作为证据;如果原判定为 GO,则会降级为 RISKY。它永远不会判为 TAKEN,也不会覆盖 GATED。判定结果仍保持确定性。
  • 不允许编造证据。 引文必须是评论正文中的精确子字符串;否则会在影响判定前被丢弃。
  • 失败时静默处理。 超时、非 200 响应或无法解析的回复都不会返回信号,也不会将错误传入 check 流程。分类结果会按评论 ID 和模型 ID 缓存,因此重复检查不会产生额外成本。

greenlight doctor 会报告该层是否已配置(绝不会显示密钥)。

自动化

Greenlight 将其作者手动完成的贡献流程自动化。作者曾为四个真实 PR(shadcn-labs/pdfcn #92-#95)手动完成整个流程:给出判定、发表评论认领、创建 fork 分支并发起 PR,同时全程考虑 DCO。

# 1. Claim the issue: verdict first, comment shaped by the repo's gates
greenlight claim https://github.com/shadcn-labs/pdfcn/issues/65

# 2. Prepare: fork/branch check (learning the repo's branch convention) plus a PREP.md checklist
greenlight prep https://github.com/shadcn-labs/pdfcn/issues/65 --dir /tmp/prep65

# 3. Open the PR from your fork branch (verifies DCO sign-off on DCO repos)
greenlight pr https://github.com/shadcn-labs/pdfcn/issues/65 --branch feat/quarterly-report-block

安全默认设置,而且这是一个特性:

  • 默认试运行。 三个命令都会准确打印将要发布或创建的内容,然后退出。除非使用 --yes(CLI)或 execute: true(MCP),否则不会发布或创建任何内容。
  • 写入需要令牌。 无需令牌即可执行读取操作。写入操作需要 GITHUB_TOKEN(或 GH_TOKEN);若未设置,命令会打印一条明确指出环境变量名称的错误,然后以非零状态退出。
  • 由判定结果控制。 除非使用 --force,否则 claim 会拒绝 TAKEN 或 STALE 判定;对于必须获得背书的仓库,则会直接拒绝(背书无法自动化)。对于必须先分配任务的仓库,会改为发送任务分配请求,而非发布意向评论;对于必须先认领的仓库(开始工作前先评论),则会发布标准意向评论,满足这一流程要求。
  • 根据仓库调整分支名称。 prep 会读取近期已关闭 PR 的头部分支,并遵循占主导地位的命名惯例(pdfcn 的 feat/<slug>-block),同时仍会显示默认名称 feat/<slug>-<number>。
  • 考虑 DCO。 对于采用 DCO 的仓库,pr 会验证分支上的每个提交是否都包含 Signed-off-by: 行;若有提交缺少该行,命令会列出这些提交并拒绝继续。
  • 根据仓库调整准备流程。 prep 还会了解仓库的贡献流程要求,并将其纳入 PREP.md 检查清单:存在哪些项目规则文件、这些文件要求使用什么验证命令(例如 pnpm verify)、仓库是否从 .changes/ 目录汇总变更日志、根目录 package.json 中有哪些脚本,以及近期提交是否遵循 Conventional Commits。约束性规则越来越多地写在 AGENTS.md 而非 CONTRIBUTING 中,prep 也会读取这些文件。

工具集

Greenlight 是一个面向开源贡献工作的四工具生命周期的入口,所有工具均发布在同一个 npm 作用域下,并彼此打通:

  1. gatefile(npx @reneturcios/gatefile extract owner/repo)会提取仓库的贡献门槛,并将其保存到已提交的 contribution-gates.json 文件中。Greenlight 可直接读取此文件:运行 greenlight check <issue-url> --gates-file contribution-gates.json,或在该文件位于工作目录时自动读取。这样只需回答一次门槛问题,即可重复使用,而无需每次都从文本中重新推导。
  2. greenlight 可给出判定、扫描、认领、准备并发起 PR(即本工具)。
  3. claimcheck(npx @reneturcios/claimcheck claims owner/repo)会监控已认领的问题,发现认领过期,以及已完成的修复仍留在 fork 上的情况;这是已认领工作悄无声息地中断的两种原因。
  4. prwatch(npx @reneturcios/prwatch attention --user you)会按你当前需要处理的事项,对你发起的开放 PR 进行分流:评审讨论串、未通过的检查、冲突以及评审者未回应。

每个工具都提供 CLI 和 MCP 服务(<tool> mcp)。

摩擦指数

data/friction-index.json 是一个已检入且持续扩充的评分仓库数据集。它最初包含我们于 2026-10-13 手动审核过的 MCP/AI 生态项目(FastMCP、trigger.dev、langchain、deepagents、openclaw、squidbrake、reticle、pdfcn、chatflow-agent,以及三个 MCP SDK 仓库)。运行 npm run index 可重新生成该数据集。

标记为 hand-verified 2026-10-13 的条目来自手动阅读仓库的实际政策和问题追踪器。标记为 live 的条目则是从实时项目规则文件(CONTRIBUTING 的各种变体、AGENTS.md、CLAUDE.md)解析而来。每项门槛都会记录其证据来源文件。计算得出的结果字段(合并率、评审耗时)会保持为 null,直至我们能够如实计算;绝不伪造。

已发布页面(cloudcorprecords.github.io/greenlight)还提供 Agent Policy Index:对 505 个仓库的贡献门槛和 AI 政策进行评估,并为每个条目引用证据。没有其他人发布过这份索引。

开发

npm test    # tsx --test, includes fixture tests that reproduce our real verdicts
npm run build
发布检查清单

每次升级版本都必须更新以下所有内容,否则发布的内容会过时:

  • package.json 版本
  • package-lock.json 版本
  • server.json:顶层的 version、npm 包的 version,以及 OCI 的 identifier 标签。该标签必须与包版本一致 (ghcr.io/cloudcorprecords/greenlight:<version>);如果标签不一致,test/packaging.test.ts 会导致构建失败
  • src/index.ts 版本
  • examples/guard-workflow.yml 固定的版本
  • 测试套件通过后,运行 npm run readme:count,以便根据实际运行结果重新生成 README 中的测试数量,切勿手动填写 (如果未记录此步骤,test/packaging.test.ts 会导致构建失败)

路线图

明确标记:这些功能尚未发布。(v0.15.0 将两项路线图功能纳入产品:radar 用于聚类重复或相互竞争的 PR,brief 则为任意 PR 提供经过验证的评审简报。)

  • 维护者控制室。 guard 按 PR 运行,radar 对队列进行聚类(两者均已发布);控制室是在此基础上构建的托管式仓库专属界面:清理过期认领,支持一键申请释放认领;提供首次贡献者风险说明和每周维护者摘要。引擎组件已经就绪;产品需要将其整合并提供托管服务。
  • 策略执行包。 仓库总是在重复制定相同的规则(必须提供 changeset、必须提供发布说明、DCO、AI 披露)。一种基于 gatefile 输出构建的策略包格式,让维护者只需在一个文件中启用策略包,即可由 Action 以相同的引用证据风格强制执行。
  • 防御 AI PR 泛滥。 要过滤,而不是禁止:由 guard 对传入 PR 的认领合理性、复现证据和测试差异进行评分,让维护者既能接纳优质 Agent 提交的工作,又能过滤垃圾内容。活动数据(拒绝的认领、诚实验证、证据包)就是验证依据。
  • 认领仲裁即服务。 两项认领、一个队列、公开排序、维护者可覆盖:实时仲裁相互竞争的认领,这是维护者无法自行构建的功能。
  • 在 github.com 上以内嵌方式为问题评分的浏览器扩展。
  • 已搁置修复的检测和自动提醒:扫描 Fork,查找引用未关闭问题的分支,并在满足门槛时发送提醒。

完整的发布历史见 CHANGELOG.md。

许可证

MIT。请参阅 LICENSE。


由 Rene Turcios 构建——一位在 SF 公开开发的氛围编程者 / Agent 原生开发者。如果 Greenlight 为你省下了一个周末,请为此仓库点星,并关注 @CloudCorpRecords,了解下一个工具。 这一系列工具:prwatch · claimcheck · gatefile · hookcheck · injectcheck · actionpin——均已发布到 npm,包名位于 @reneturcios/ 命名空间下,并收录于官方 MCP Registry。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。