Repository navigation
Issue 98
- 类型:功能
- 状态:已实现,待合并
- Issue:https://github.com/ShaoClean/Alune/issues/98
- PR:https://github.com/ShaoClean/Alune/pull/105(草稿)
- 最近更新:2026-09-26
- 代码基线:
f6ce4ac;实现:90a15dc,分支codex/issue-98-pull-requests
在 Alune 的远程 Git 工作区内查看仓库收到的合并请求,避免先离开工作区查找对应的托管平台。Issue 原先只记录方向;本次明确首版范围并实现可验证的完整查询路径。
仓库工具条新增 PR/MR 视图,沿用现有自适应标签布局。默认选择可解析的 origin;缺少时依次选择已识别的平台、其他可解析远端或第一个远端。用户可明确切换任意配置的远端。使用 fetch 地址,push 地址不参与目标选择,多个平台的结果不混合。
查询所选仓库收到的全部目标分支的 PR/MR;Fork 的外发请求需要切换到对应的上游远端查看。默认“开放中”(包括草稿),可切换“全部状态”,后者区分开放、关闭与已合并。每页 30 条,按最近更新时间倒序。列表显示标题、编号、作者、来源与目标分支、状态、草稿标记及更新时间。
点击标题在系统浏览器打开平台详情。支持上一页、下一页、手动刷新和工具条刷新;刷新先重读 Git 配置。不自动轮询,不提供创建、评审、关闭、合并、检出等写操作。分页期间远端数据可能变化,必要时回到第一页刷新。
| 平台 | 支持范围 | 认证 |
|---|---|---|
| GitHub | github.com,HTTPS / SSH / SCP 地址;暂不支持 Enterprise | 公开仓库匿名读取;细粒度令牌需要目标仓库 Pull requests 读取权限,经典令牌需要 repo;组织可能要求 SSO |
| GitLab | gitlab.com 自动识别;自建主机由用户显式选择 GitLab;支持多级群组 | 公开项目匿名读取;私有项目使用具有项目访问权且包含 read_api 或 api 的个人、项目或群组访问令牌 |
自建实例要求本机可达且证书受信任的 HTTPS,并部署在域名根路径。HTTPS URL 的显式端口保留,SSH 端口不推断为 HTTPS 端口。暂不支持 HTTP、路径前缀部署和 SSH 主机别名。
令牌通过密码输入框显式应用,仅保留在当前视图内存中;可主动清除,切换远端、仓库、视图或重载页面后清除。发送主机在界面中显示。服务端只对本次请求使用令牌,不保存到磁盘、数据库、浏览器存储或全局状态,不读取远端 Git 凭据或 AI 密钥。
- 浏览器调用
GET /api/repositories/:id/pull-requests/remotes,通过已登记仓库及 SSH 执行只读git remote -v,返回去除凭据后的远端描述。 - 浏览器调用只读
POST /api/repositories/:id/pull-requests/list,在请求体中携带远端名、预期地址、平台、状态、页码和可选临时令牌。使用 POST 避免将令牌放入 URL;响应设置Cache-Control: no-store。 - 服务端重读 Git 配置,校验目标仍与用户选择一致。远端已删除返回 404,地址已变化返回 409,平台不匹配返回 400,校验失败不发送令牌。
- 托管平台 API 由运行 Alune 的本机访问:GitHub REST
/repos/{owner}/{repo}/pulls或 GitLab REST/api/v4/projects/{encodedPath}/merge_requests。不依赖远端安装 gh/glab,不跟随 API 重定向或分页中的任意 URL。 - 每次查询包含 SSH 和 HTTP 的总时限为 20 秒,超时取消该 Git 命令或 HTTP 请求;平台响应上限为 2 MiB。Git 输出也有大小上限,Windows 使用既有编码 PowerShell 参数构建器。
- 将返回数据统一为只读列表,外链由已校验的仓库地址与请求编号构造,不信任 API 提供的任意链接。前端取消旧请求,避免切换筛选、远端或仓库后的迟到结果覆盖当前视图。
空列表、无远端、不支持的地址分别展示。401 提示认证失效,403 提示权限或组织授权,404 提示不存在或私有权限,429/限流提示稍后重试,502/504 提示网络、平台或超时。错误不回显原始远端输出、上游正文或令牌。刷新失败保留上一次同一查询的列表,并明确标为上次结果;初次失败不显示为空列表。
- 工具条提供直接入口,窄窗口保留入口与可访问名称。
- GitHub、GitLab 和自建 GitLab 的支持边界、获取方向和认证方式明确。
- 正确选择 fetch 远端;支持多远端、SSH/HTTPS/SCP、多级群组和端口区分。
- 可读取公开 PR/MR,并展示开放、关闭、合并、草稿、分支、作者及更新信息。
- 状态筛选、分页、刷新、空结果和可重试错误有明确行为。
- 私有令牌只用于当前目标;服务端拒绝目标变更,前端切换后清除。
- 查询有超时和响应上限;不执行 Git 或平台写操作。
- 自动化测试覆盖认证、权限、限流、分页、非法输入、超时和真实 SSH 查询。
环境:macOS arm64,Node.js 25.5.0,2026-09-26。所有 Git / SQLite / SSH 集成数据均来自临时隔离目录。
| 检查 | 结果 |
|---|---|
npm test -w server -- --runInBand |
14 套、150 项通过,其中新增 PR/MR 47 项 |
npm test -w web |
140 项通过,包含列表内容、XSS 转义、远端选择及工具条回归 |
npm test -w @alune/ssh-client |
76 项通过;2 项 Windows 原生环境测试在 macOS 跳过 |
npm run desktop:test:unit |
42 项通过 |
node --test apps/web/tests/pull-requests.integration.cjs |
真实 Nest HTTP、SQLite、SSH 和 Git 通过;仅托管平台响应模拟;验证无缓存、分页、认证、远端变更拦截、无远端及工作区未被修改 |
| GitHub CI | Ubuntu 22.04 / Node 22.22.0:PR 与分支 push 的 server、web、ssh-client、desktop 及 commitlint 检查全部通过(运行记录) |
npm run build |
5 个工作区构建成功,包含桌面应用暂存与原生模块;保留原有前端大包提示 |
| GitHub 公开 API | 使用生产服务读取 ShaoClean/Alune,返回 30 条,分页和状态映射正常 |
| GitLab 公开 API | 使用生产服务读取 gitlab-org/cli,返回 30 条,开放/关闭/合并状态与分页正常 |
| Ego Lite 浏览器验收 | 分页、全部状态、自建 GitLab 手动识别、认证应用与清除、跨远端令牌隔离、浏览器存储无令牌、刷新失败保留结果、重试、迟到响应隔离、不支持远端、无远端均通过;560px 窄屏没有页面横向溢出,浅色/深色可读 |
复验页面:构建后运行 node apps/web/tests/pull-requests-fixture.cjs,打开输出的 URL。Fixture 使用真实本地 SSH 与服务端路径,GitLab 认证场景接受测试用非空令牌,绝不接触真实私有凭据。
真实私有 GitHub/GitLab 账号、自建实例、组织 SSO 和 Windows/Linux 桌面真机未验收;相关协议、错误及认证隔离已由模拟平台与真实 SSH 的集成用例覆盖。需要本机访问托管平台的网络能力。新功能没有数据库迁移或凭据持久化;回退代码提交即可移除入口,Wiki 历史独立保留。
前后截图使用同一组隔离演示仓库。修改前前端由 f6ce4ac 源码独立构建;修改后来自实现分支。1440×900 浅色/深色以及 560×800 窄屏,截图不包含真实账号、私有地址或令牌。
修改前,“远程”仅展示 fetch/push 地址,工具条没有 PR/MR 入口:

修改后,可直接查看 PR/MR 状态与元数据:


自建 GitLab 的平台选择与临时认证;输入框在应用后清空,截图只显示“已应用”:

窄屏保留入口、筛选与可滚动列表:

新增跨仓库中心的方案、验证范围和截图见 PR/MR 中心,关联 PR #212。本节补充后续能力,不替换上文历史验收记录。
设计文档首页 · Alune 品牌说明 · 维护约定 · 代码仓库