oh-my-pi 编码代理 GitHub 工具深度指南:op 操作、pr:// 协议与 Actions 监控实战
【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi
本篇技术指南围绕 oh-my-pi(⌥ Coding agent with the IDE wired in)编码代理内置的github工具展开,完整讲解其基于ghCLI 的 op 操作封装(仓库/文件访问、PR 创建与 worktree 检出、多维度搜索、Actions 运行监控)、issue:///pr://内部 URL 协议,以及配套的搜索时间语法与安全边界。读完本文,你将掌握如何让 Agent 在不触碰工作树的前提下安全地读写 GitHub 仓库、审阅 PR diff、推送分支并实时观察 CI 结果,并理解每一层设计背后的源码依据。
一、工具定位与能力总览
github是 oh-my-pi 编码代理中通过 github.md 定义能力边界的工具描述文档,其实现位于 gh.ts 的GithubTool类。它是一层薄薄的ghCLI op 包装器("ghop wrapper"),覆盖六大能力域:
- 仓库与文件:
repo_view、file_read - 拉取请求:
pr_create、pr_checkout、pr_push - 搜索:
search_issues、search_prs、search_commits、search_repos、search_code - Actions 监控:
run_watch - Issue/PR 读取:通过
issue://<N>、pr://<N>内部 URL - PR 差异审阅:
pr://<N>/diff、pr://<N>/diff/<i>、pr://<N>/diff/all
工具通过op参数分派执行,schema 定义在 gh.ts,全部入参如下:
| 参数 | 类型 | 说明 |
|---|---|---|
op | 字符串字面量 | 11 种操作之一(见下) |
repo | string? | owner/repo,可带host/前缀 |
branch | string? | 目标分支 |
path | string? | 仓库相对路径(file_read用) |
pr | string | string[] | PR 编号、URL 或分支名;数组可批量 checkout |
force | boolean? | 重置已存在的本地分支(pr_checkout) |
forceWithLease | boolean? | --force-with-lease推送(pr_push) |
title/body/base/head/draft/fill | string/boolean? | pr_create参数;fill为 true 时从 commits 自动填充标题与正文 |
reviewer/assignee/label | string[]? | 创建 PR 时附加的评审者、指派者、标签 |
query | string? | 搜索查询(search_code必填) |
since/until | string? | 时间下界 / 上界过滤 |
dateField | 'created' | 'updated'? | 按创建时间或更新时间过滤 |
limit | number? | 结果条数上限 |
run | string? | Actions run ID 或完整 URL |
tail | number? | 每个失败 job 抓取的日志行数 |
从源码结构看,execute()是一个纯switch分派器(gh.ts),每个 op 对应一个独立的执行模块:repo_view→ gh-view.ts、file_read→ gh.ts、pr_*→ gh-pr-checkout.ts、search_*→ gh-search.ts、run_watch→ gh-run-watch.ts。
二、issue://与pr://内部 URL 协议
github.md明确声明:读取 Issue 与 PR 使用issue://<N>/pr://<N>形式的内部 URL,PR 差异则使用pr://<N>/diff家族。这套协议的解析器位于 issue-pr-protocol.ts,其注释(L9-L21)完整定义了 URL 形状:
| URL 形状 | 含义 |
|---|---|
issue:///pr:// | 列出当前默认仓库最近的条目 |
issue://owner/repo/pr://owner/repo | 列出指定仓库的条目 |
issue://123/pr://123 | 读取单个条目,仓库从会话 cwd 推导 |
issue://owner/repo/123/pr://owner/repo/123 | 完整限定单个条目 |
pr://ghe.example.com/owner/repo/123 | GitHub Enterprise 主机上的条目;任意形状都可带<host>/前缀 |
issue://owner/repo/123?comments=0 | 单条目、隐藏评论 |
issue://owner/repo?state=closed&limit=20 | 列表选项透传给gh |
2.1 diff 家族:/diff、/diff/<i>、/diff/all
PR 差异读取有三种模式(issue-pr-protocol.ts):
pr://<N>/diff:列出PR 变更的文件清单,每个文件带+增 -删统计与变更类型(add/modify/delete/rename/binary),并给出可直接跳转的pr://<repo>/<N>/diff/<i>子链接;pr://<N>/diff/<i>:读取第 i 个文件的 diff 切片,索引从 1 开始;越界会明确报错并提示合法范围(L467-L476);pr://<N>/diff/all:读取完整 unified diff。
切片实现基于 gh-pr-diff.ts 解析出的文件偏移区间,从完整 unified diff 中精确截取(L478)。协议层对格式校验非常严格:issue://上出现/diff会被拒绝(Issue 没有 diff,提示改用pr://),非法子路径(既不是all也不是正整数)会直接报错,而不是静默回退(L196-L207)。
2.2 默认仓库解析与会话隔离
短格式issue://N/pr://N的仓库归属按顺序解析(L248-L255):调用方context.cwd→ 已注册会话的 cwd →process.cwd()。这保证了多会话并发时短格式读取不会串到错误的仓库。列表与单条目读取均经由 SQLite 背书的github-cache缓存,跨会话共享渲染结果;列表则是实时gh issue list/gh pr list。相关协议行为有完整测试覆盖,见 issue-pr-protocol.test.ts。
三、仓库与文件访问:repo_view与file_read
repo_view与file_read的repo缺省语义一致:省略repo即作用于当前 checkout;file_read省略branch时读取默认分支(github.mdL6-7)。repo_view通过gh repo view --json拉取名称、描述、默认分支、Star/Fork 数、主题标签、归档状态、可见性、当前用户权限等字段(gh-view.ts)。
file_read的实现(gh.ts)值得注意的细节:
- 路径必须是仓库相对路径,以
/开头的绝对路径会被拒绝(L268-L270); - 走
gh api /repos/{owner}/{repo}/contents/{path},base64 解码后做三级内容探测(L315-L349):图片(解析元数据后以图像附件注入,遵循images.autoResize等设置)、二进制嗅探(前若干字节非 UTF-8/含 NUL 则提示用浏览器打开)、最后才是严格 UTF-8 文本解码; github.md的<critical>段落特别强调:GitHub 托管仓库的文件必须用file_read读取,严禁curl/wget。这既保证鉴权与缓存正确性,也避免绕过工具自身的类型探测与超链接(sourceUrl)注入。
四、PR 全生命周期:创建、worktree 检出与推送
4.1 创建 PR:pr_create
head缺省为当前分支(github.mdL8)。除title/body/base/head/draft外,schema 还支持reviewer/assignee/label数组以及fill(从提交自动生成标题正文)。校验规则(gh-pr-checkout.ts):fill与显式title/body互斥;fill=false且无title时直接报错。body 通过临时文件传入(--body-file)以规避 argv 长度与 shell 转义问题,无 body 时显式传空串防止gh落入交互式编辑器(L631-L645)。创建成功后返回 PR 号、状态、base/head、作者、标签与完整正文等摘要。
4.2 检出 PR:pr_checkout与 dedicated worktree
pr_checkout是整套工具中最讲究安全性的设计:PR 检出永远落在独立的 git worktree,绝不触碰工作树(github.mdL9)。这意味着 Agent 可以并行检出一个或多个 PR 而不会干扰正在编辑的主工作区。实现要点(gh-pr-checkout.ts):
pr接受 PR 编号、URL 或分支名;传数组时一次调用批量检出多个 PR(prRefs.map(checkoutPullRequest)),支持部分成功——失败项与成功项会分开汇报(L324-L352);- 本地分支命名
pr-<number>,worktree 目录基于getWorktreeDir(<number>-<hashPath>)生成;若pr-N分支已存在且指向不同提交,默认报错,需显式force=true重置(L453-L472); - 跨仓库(fork)PR会自动为 head 仓库添加
fork-<owner>形式的 remote(若 URL 重复则复用已有 remote,名称冲突自动加后缀),再从该 remote fetch head 分支(L146-L206); - 检出后把
branch.<name>.ompPrHeadRef、ompPrUrl、ompPrIsCrossRepository、ompPrMaintainerCanModify等元数据写入 git config,作为后续pr_push的凭据(L475-L490); - 所有 git 变更在 per-repo 锁(
withRepoLock)内执行,避免并发 checkout 对共享的.git/config、packed-refs等文件的锁竞争(L427-L435);worktree 路径冲突时会尝试-2、-3…后缀直到WORKTREE_PATH_MAX_SUFFIX=100(L96-L117)。
worktree 默认是否克隆由设置worktree.clone控制,后端由isolation.backend决定(L497-L506),克隆失败会回退为普通 checkout 并告警。
4.3 推送回 PR:pr_push的前置依赖
pr_push必须先在pr_checkout中检出过对应分支(github.mdL10),因为推送目标信息全部来自 checkout 时写入的branch.<name>.ompPrHeadRef等元数据;没有元数据的分支会被明确拒绝("check it out via op: pr_checkout first",gh-pr-checkout.ts)。推送支持forceWithLease,成功后会使对应pr://N与pr://N/diff的缓存失效,保证"推送 → 重读 diff"链路看到的是新数据(L571-L577)。
五、多维搜索:search_*与时间语法
5.1 五种搜索与各自约束
| op | query | since/until | 默认 scope |
|---|---|---|---|
search_issues | 可选 | 支持 | 当前 checkout 的owner/repo |
search_prs | 可选 | 支持 | 同上 |
search_commits | 可选 | 支持 | 同上 |
search_repos | 可选 | 支持(忽略repo参数) | 全站,用org:/language:限定 |
search_code | 必填 | 拒绝(GitHub 代码搜索无日期限定符) | 当前 checkout 的owner/repo |
- 省略
query仅保留since/until时,退化为纯日期过滤(github.mdL11); - 搜索结果条数上限:默认 10、最大 50(gh-search.ts);
- 想搜索其他范围,直接在
query内使用repo:/org:/user:限定符即可,工具检测到显式 scope 限定符后不会再叠加默认repo:(L261-L280);企业版主机则以独立--hostname传给gh api(L287-L291)。
5.2since/until时间语法(github.mdL13)
时间边界支持三种写法(解析实现见 gh-search.ts):
- 相对时长:
<n>+ 单位m(分钟)/h(小时)/d(天)/w(周)/mo(月)/y(年),例如3d、2w; - ISO 日期:
YYYY-MM-DD; - ISO 日期时间:完整 datetime(会自动剥离毫秒,因为 GitHub 搜索限定符只接受秒级精度)。
dateField决定按哪个时间过滤(L131-L143):
- 默认
created:按创建时间; - 指定
"updated":issues/PRs 按更新时间,repos 按推送时间(pushed); - commits 恒用
committer-date; - 关键语义(
github.mdL13):dateField: "updated"时永远不是创建时间。
限定符最终组合为created:>=2026-09-01、created:<=...或区间created:start..end(L111-L129)。search_code使用Accept: application/vnd.github.text-match+json额外获取匹配片段,输出首个匹配行的片段预览(L473-L476)。
六、Actions 监控:run_watch
run_watch用于轮询 GitHub Actions 运行状态(github.mdL14):省略run时监控当前 HEAD 的所有 workflow run,branch缺省为当前分支,且遇到第一个失败 job 立即快速失败(fast-fail),而不是等整个 run 跑完。
6.1 两种监控模式
- 指定 run:
run传数字 ID 或完整 Actions run URL(gh-run-watch.ts),轮询该 run 直至完成; - 按提交监控:省略
run时,以当前 checkout(或显式branch)的 HEAD SHA 拉取该提交的全部 workflow runs。此处有个反直觉细节:只按head_sha过滤、不按分支过滤,否则会漏掉 tag 触发或 PR 触发的 run(其head_branch与本地分支不一致,L593-L604)。
6.2 轮询策略与失败处理
- 前 60 秒以 3s 间隔快速轮询,之后退避到 15s,兼顾响应速度与共享鉴权配额的消耗(
RUN_WATCH_INTERVAL_DEFAULT=3/RUN_WATCH_INTERVAL_SLOW=15,L43-L50); - 检出失败后等待 5s 宽限期(
grace)再抓日志,以捕获并发失败(如多个 job 同时崩);限流(rate limit / HTTP 429 / abuse detection)会被退避重试而非直接放弃(L192-L200); - 失败时按
tail(默认 15、最大 200 行)抓取每个失败 job 的日志尾部;完整失败日志会保存为 session artifact(github.mdL18),工具结果同时携带 run/workflow/job 的明细与链接; - 仓库未配置 Actions 或 Actions 被禁用时,90 秒内未见到任何 run 会明确给出放弃提示而非无限轮询(L1015-L1026)。
6.3 输出约定
每个 op 返回精炼摘要(github.mdL17-18):run 状态、conclusion、分支、提交、各 job 状态与耗时;失败场景下失败日志 tail 以 text 代码块内嵌,完整日志进 artifact。
七、安全边界与前置条件
7.1 只读 vs 执行
GithubTool.approval依据 op 归类审批等级(gh.ts):repo_view、file_read、五个search_*与run_watch属于只读(read),直接放行;pr_create、pr_checkout、pr_push属于执行(exec),需要审批确认。配合pr_checkout永不触碰工作树的 worktree 策略,构成了"读可自动、写须确认、工作区零污染"的安全模型。
7.2 运行前提
- 机器上需安装并认证GitHub CLI(
gh);工具在gh不可用时不会注册(GithubTool.createIf返回 null,gh.ts); - 未认证时(
gh auth login/ not logged into any GitHub hosts)会得到明确的认证指引,见 utils/github.ts; - 多实例部署时可用
GH_HOST等环境变量指定默认主机;repo参数支持[host/]owner/repo形式——对于不在当前 checkout 所属 GitHub 实例上的仓库,必须显式限定 host(github.mdL5),解析逻辑见 gh-common.ts。
7.3 已知限制(以当前仓库为准)
search_code不支持since/until(GitHub 代码搜索本身没有日期限定符);search_repos忽略repo参数,只能靠query中的org:/language:等限定符圈定范围;- 搜索
limit上限 50、列表limit上限 100(issue-pr-protocol.ts)、tail上限 200。
八、小结
oh-my-pi 的github工具把日常 GitHub 操作收敛为 11 个 op 加上issue:///pr://内部 URL 协议:读取仓库文件有统一的类型探测与缓存,PR 审阅有"清单 → 单文件切片 → 全文"三档 diff 入口,PR 协作有 worktree 隔离 + 元数据驱动的安全推送,CI 观察有 fast-fail 与 artifact 日志兜底。其全部行为都可回溯到 github.md 的定义与 gh.ts、gh-pr-checkout.ts、gh-search.ts、gh-run-watch.ts、issue-pr-protocol.ts 等源码模块,是一套"Agent 友好、可验证、可审计"的 GitHub 操作范式。
【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考