Files
deepseek-harness/packages/experimental/forge-github/README.zh.md
T
Yichen Jiang d0fc1f6458 feat(forge): show the changes of a Session and of its change requests
The forge panel opens a changes view in the right sidebar for the
checkout's local changes and for the diff of each change request.

- ForgePanelController reads local diffs in the branch, uncommitted,
  unstaged, and staged scopes through Git in the Session's read-only
  sandbox, change request diffs through the forge provider, and the text
  of a changed file to expand unchanged lines. Change request patches stay
  cached by head commit and base branch within maxCachedDiffBytes. A local
  diff over maxDiffBytes fails as forgePanel/diff-too-large, and a provider
  read over its output limit fails as too-large, which the view explains
  with a link to the code host; a gh timeout fails as unavailable.
- forge adds the diff, fileText, and fileUrl provider methods and the
  too-large failure code, and forge-github implements them with gh.
- The panel shows a local changes card that opens the view and asks the
  Agent for a change request. The view collapses files past a line
  budget, draws lines side by side or in one column with optional
  wrapping, expands unchanged lines on request, and collapses or expands
  every file from its toolbar; file headers use a bare chevron.
- The checkout row copies the worktree or project directory path, the
  refresh glyph turns while a refresh runs, change request cards keep
  their actions while collapsed, and the header entry uses the shared
  compact button.
- client-ui-forge classifies changeRequestKey and FsError as
  peer-required Host imports, which keeps forge and dsh-fs as its peers.
2026-10-20 13:34:27 +08:00

6.9 KiB
Raw Blame History

description, kind
description kind
通过宿主上的 GitHub CLI 为实验性 forge 注册表服务 GitHub 主机。 package-reference

@deepseek-ai/dsh-experimental-forge-github

English | 中文

概述

借助宿主上已登录的 GitHub CLI,为 ctx.forge 读取 GitHub 与 GitHub Enterprise 的 pull request。每次轮询对每个主机只发一个 GraphQL 查询,读取所有到期 pull request 的状态、改动行数、检查、评审结论、可合并性与未解决的评审讨论。

目录


使用本包

在 forge 注册表之后挂载提供方,并显式列出每个 GitHub Enterprise 主机。

- name: '@deepseek-ai/dsh-experimental-forge'
- name: '@deepseek-ai/dsh-experimental-forge-github'
  config:
    hosts: [github.com, ghe.example.com]

即使 Session 在其他执行环境中运行命令,提供方也以宿主进程的形式运行 gh。每个主机执行一次 gh auth login --hostname <host> 完成登录。子进程继承的宿主环境去掉了 DSH_* 变量以及名称包含 KEY、PASSWORD、SECRET 或 TOKEN 的变量,因此 GH_TOKEN 与 GITHUB_TOKEN 不会被转发,gh 使用自己的凭据存储。交互提示、更新提醒、分页器与颜色输出均被关闭。ghCommand、hosts、timeoutMs 与 maxOutputBytes 见配置目录。

当主机在配置中时,提供方服务 https、http、ssh、git 形式的远端 URL,以及 [email protected]:owner/name.git 这类 scp 形式。它服务 https://<host>/<owner>/<name>/pull/<number> 形式的 pull request URL,允许其后附带任意路径、查询或片段,并以去掉这些后缀的形式作为规范 URL。就绪探测运行 gh auth status --hostname <host>:退出码为 0 时为 ready,其他退出码为 unauthenticated 并带第一行诊断,gh 无法启动时为 unavailable。按 head 分支查找时,最多返回 20 个以该分支为 head 的打开状态 pull request,按创建时间从新到旧排列,不包含来自 fork 的 pull request;查找默认分支时返回空结果。

检查运行(check run)在完成前映射为 pending,完成后映射为 success、failure(失败、超时、启动失败或需要操作)、cancelled、skipped 或 neutral。检查运行保留其开始与完成时间。提交状态上下文把 SUCCESS 映射为 success,把 FAILURE 与 ERROR 映射为 failure,其余状态均映射为 pending,且不带时间。GraphQL 的 NOT_FOUND 错误转为 not-found 失败。gh 没有输出 JSON 时,提到身份验证或 gh auth login 的诊断转为 unauthenticated,其他诊断转为 unavailable。

pull request 处于打开状态、不是草稿、GitHub 报告其合并状态为 CLEAN、HAS_HOOKS 或 UNSTABLE,且已登录用户具有 write、maintain 或 admin 权限时,mergeReady 为真。mergeMethods 列出仓库允许的压缩合并、合并提交与变基合并方式,用户默认的合并方式排在最前。标记为可评审运行 gh pr ready <number> --repo <host>/<owner>/<name>。合并经 gh api 调用 PUT repos/<owner>/<name>/pulls/<number>/merge,带上合并方式与预期的 head SHA,因此有新提交到达后 GitHub 会拒绝,报告为 stale。与 gh pr merge 不同,它从不启用自动合并、从不加入合并队列,也从不删除 head 分支。被拒绝的操作报告 GitHub 的原因,提到身份验证的诊断转为 unauthenticated。

diff 运行 gh pr diff <number> --repo <host>/<owner>/<name> --color never。fileText 经 gh api 以 raw 媒体类型读取 repos/<owner>/<name>/contents/<path>?ref=<commit>,只接受完整的 40 位或 64 位十六进制提交。fileUrl 返回 https://<host>/<owner>/<name>/blob/<commit>/<path>。两者的路径都逐段做百分号编码。被拒绝的读取在 HTTP 404 时为 not-found,诊断提到身份验证时为 unauthenticated,GitHub 报告 too_large 错误时(diff 超过其自身大小上限即会如此)为 too-large,其余为 unavailable,并带有 GitHub 的原因。输出超过 maxOutputBytes 的读取为 too-large,超过 timeoutMs 的为 unavailable。


了解实现

实现细节——点击展开

一次读取按主机对引用分组,每个主机发送一个 gh api graphql 查询。查询内联经过校验的 owner、name 与编号,并为每个 pull request 设置别名,因此局部 GraphQL 错误只影响对应的别名。出现局部错误时 gh 以非零状态退出,但仍会输出完整响应;提供方先解析该响应,再检查退出码。

源码 职责
src/index.ts 配置校验与提供方注册
src/provider.ts URL 映射、按主机分组与失败分类
src/graphql.ts 构造查询,并校验和映射响应
src/gh.ts 在宿主上执行 gh,清理环境变量并施加限制
src/urls.ts 解析远端 URL 与 pull request URL

深入探索


模型体验

无:提供方为宿主侧监听方读取 pull request 状态,不贡献模型上下文。

KV Cache 影响

无。提供方的输出只到达宿主侧监听方。

已知限制与待办工作

  • 宿主需要 GitHub CLI——必须安装 gh 并为每个已配置主机登录;环境变量中的令牌不会被转发。不在 hosts 中的主机永远不会被读取。
  • 前 100 个检查与评审讨论——head 提交的检查超过上限时以 checksTruncated 标记;前 100 个之后的未解决讨论不计入。
  • 不发现 fork——按 head 分支查找时,不包含 head 位于其他仓库的 pull request。
  • 速率限制——每次轮询都会以已登录账号的速率配额为每个主机消耗一次 GraphQL 查询。
  • 不支持合并队列——要求合并队列的基准分支会拒绝直接合并,提供方也不会把变更请求加入队列。

开发备注

维护者的工作上下文——点击展开

无。