# PJ2026-010606 GitHub入口

## 修改历史

| 版本 | 对应 commit id | 更新日期 | 变更说明 |
| --- | --- | --- | --- |

当前正文仍在规格治理草稿中；未定稿前不新增版本号，不为单次编辑追加 `待提交` 版本。

## 正文

## PJ2026-010606 GitHub入口需求规格

## 1. 文档控制

| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-010606 |
| 短名 | GitHub入口 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-25-gh-split |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-0106 平台运维](PJ2026-0106-platform-ops.md) |
| 关联规格 | [PJ2026-010602 源码同步](PJ2026-010602-source-sync.md)、[PJ2026-010601 发布流水](PJ2026-010601-controlled-release.md)、[规格治理](spec-governance.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |

本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版：正文只保留 UniDesk GitHub 受控入口的稳定使命、范围、术语、系统边界、内部分工和原子需求。

## 2. 目的和范围

### 2.1 目的

GitHub入口负责为 UniDesk/HWLAB 执行过程提供受控 GitHub issue、PR、正文 patch、附件、看板、预检和 merge 操作面，使 agent 和维护者通过同一条 `bun scripts/cli.ts gh ...` 路径完成正式读写，不绕过 body guard、并发 guard、merge guard、敏感输出约束和中文写入规则。

本课题的目标状态是：`scripts/src/gh.ts` 只保留兼容入口和 public exports，GitHub REST/GraphQL client、option parsing、正文输入、body guard、issue/PR 命令、board mutation、附件下载、escape scan、help 和 dispatch 分布在 `scripts/src/gh/` 子模块中；后续新增 GitHub 子命令必须进入对应模块，不继续堆叠到根入口文件。

### 2.2 范围内

- `bun scripts/cli.ts gh ...` 的 GitHub issue/PR/list/read/write/comment/close/reopen/merge/preflight 等受控命令。
- GitHub Actions run、job、日志诊断和 `github-action-benchmark`
  Pages 导出物的有界只读查询。
- `trans gh:/owner/repo/...` 虚拟文件写回所依赖的 issue/PR body read、body patch、sha guard 和 update guard。
- GitHub REST/GraphQL token resolution、request、错误分类、rate/repo/issue 探测和脱敏输出。
- issue/PR 正文 stdin/file/patch 输入、短 body safety、profile guard、body sha、updatedAt 和 comment concurrency guard。
- PR closeout/preflight、merge method、delete branch guard 和 merge 后状态表达。
- board table parse、board-row mutation plan/dry-run、stale-close、escape scan、attachment list/download dry-run 和下载边界。
- 默认低噪声摘要、`--json`、`--raw`、`--full`、scoped help 和 bounded dump 行为。

### 2.3 范围外

- GitHub issue/PR 的项目需求正文归对应 OA 规格和执行 issue；GitHub入口只保证读写路径受控，不定义业务需求。
- Git remote、mirror、source truth 和 GitOps artifact 归 [源码同步](PJ2026-010602-source-sync.md)。
- CI/CD、发布候选、rollout 和 runtime 验收归 [发布流水](PJ2026-010601-controlled-release.md)。
- `trans` 的 SSH、k3s、文件系统和 apply-patch v2 通用路由归 UniDesk CLI/route 参考，不在本规格复写。
- 原生 `gh` binary、手写 GitHub API、raw `curl` 和一次性脚本不能作为正式 GitHub 写入入口。

## 3. 术语表

| 术语 | 定义 |
| --- | --- |
| GitHub入口 | UniDesk 通过 `bun scripts/cli.ts gh ...` 暴露的 GitHub issue/PR 受控读写命令面。 |
| body guard | 写入 issue/PR/comment 正文前执行的正文长度、安全 profile、body sha、updatedAt 和并发保护。 |
| merge guard | PR 合并前的 state、draft、conflict、mergeable、status check 和 closeout 预检。 |
| `trans gh:` | 把 GitHub issue/PR 正文映射为虚拟文件的 route，最终仍调用 UniDesk GitHub入口写回。 |
| scoped help | `gh issue --help`、`gh pr merge --help` 这类按命令前缀过滤的有界帮助输出。 |
| bounded dump | CLI 输出超过全局阈值时写入临时 dump，并在 stdout 返回摘要和读取命令。 |
| benchmark 导出物 | `github-action-benchmark` 发布到 GitHub Pages 的 `data.js` 历史数据；它是 Action 产出的只读性能记录，不等同于 job 日志。 |

## 4. 系统边界和接口

| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | 维护者、agent、项目治理流程、PR closeout 流程和 `trans gh:` 路由。 |
| 外部输入 | GitHub token 来源、owner/repo、issue/PR number、正文、patch、commentId、board row、attachment 选择、merge method、Actions run/job、benchmark Pages URL 和输出模式。 |
| 受控资源 | `scripts/src/gh.ts` 兼容入口、`scripts/src/gh/` 子模块、GitHub REST/GraphQL request、body guard、merge guard、board mutation plan、attachment 下载和 help/dispatch。 |
| 外部输出 | GitHub 资源摘要、受控写入结果、body sha、comment id、PR preflight、merge 状态、Actions 状态、benchmark 历史摘要、bounded dump、错误分类和后续 drill-down 命令。 |
| 用户接口 | `bun scripts/cli.ts gh ...`、`bun scripts/cli.ts help` 中的 gh 入口、`trans gh:/owner/repo/...`。 |
| 系统边界 | GitHub入口负责 GitHub 读写路径、保护策略、输出契约和模块边界；不拥有业务 issue 的需求内容、Git source truth 或发布判定。 |

## 5. 内部分工与规格索引

| 编号 | 模块或课题 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
| --- | --- | --- | --- | --- | --- |
| PJ2026-01060601 | 入口兼容 | 本规格 6.1 | `gh.ts` 薄入口、public exports、help/dispatch 兼容 | UniDesk CLI root | 全部 gh 命令 |
| PJ2026-01060602 | 请求与选项 | 本规格 6.2 | token、REST/GraphQL、repo/number/options/json fields | GitHub API、token source | issue/PR/board/attachment |
| PJ2026-01060603 | 正文保护 | 本规格 6.3 | stdin/file/patch、body sha、profile、concurrency guard | GitHub issue/comment body | issue/PR/comment 写入 |
| PJ2026-01060604 | Issue与PR | 本规格 6.4 | issue/PR CRUD、comment lifecycle、preflight、merge guard | 请求与正文保护 | 项目治理、PR closeout |
| PJ2026-01060605 | Board附件扫描 | 本规格 6.5 | board-row plan、attachment list/download、escape scan、stale close | GitHub issue/read model | 看板维护、污染排查 |
| PJ2026-01060606 | 输出帮助 | 本规格 6.6 | 默认摘要、JSON/raw/full、bounded dump、scoped help | 全部命令结果 | 维护者和 agent |

### 5.1 目标架构图

```mermaid
flowchart LR
  CLI[bun scripts/cli.ts gh] --> Root[scripts/src/gh.ts thin entry]
  Root --> Dispatch[scripts/src/gh/index.ts dispatch]
  Dispatch --> Opt[options/refs]
  Dispatch --> Client[client/auth]
  Dispatch --> Body[body-input/body-guards]
  Dispatch --> Issue[issue modules]
  Dispatch --> PR[pr modules]
  Dispatch --> Board[board modules]
  Dispatch --> Attach[attachments]
  Dispatch --> Scan[escape-scan]
  Dispatch --> Help[help/render]
  Trans[trans gh:] --> Body
  Body --> Client
  Issue --> Client
  PR --> Client
  Board --> Client
  Attach --> Client
  Scan --> Client
  Client --> GH[(GitHub REST/GraphQL)]
```

### 5.2 数据流图

```mermaid
flowchart TD
  Args[CLI args] --> Parse[parse options and target]
  Parse --> Auth[token probe]
  Auth --> Read[read current GitHub resource]
  Read --> Guard[body/profile/concurrency guard]
  Guard --> Plan[write or dry-run plan]
  Plan --> Request[REST/GraphQL request]
  Request --> Render[bounded summary/json/raw/full]
  Render --> User[agent or maintainer]
```

### 5.3 `trans gh:` 写回时序

```mermaid
sequenceDiagram
  participant A as Agent
  participant T as trans gh route
  participant G as UniDesk gh command
  participant B as body guard
  participant H as GitHub API
  A->>T: apply-patch body.md
  T->>G: gh issue/pr read
  G->>H: GET body and metadata
  H-->>G: body, sha, updatedAt
  T->>B: apply patch and validate
  B->>G: gh issue/pr update with guard
  G->>H: PATCH body
  H-->>G: updated resource
  G-->>T: compact result
  T-->>A: write summary and next command
```

## 6. 原子需求

### 6.1 OPS-GH-REQ-001 入口兼容与模块边界

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-GH-REQ-001 | 入口兼容 | PJ2026-01060601 入口兼容 | UniDesk CLI root、`trans gh:` |

GitHub入口应保持 `bun scripts/cli.ts gh ...`、`ghHelp`、`ghScopedHelp`、`runGhCommand` 和 `commanderBriefDiff` 的 public import 兼容。`scripts/src/gh.ts` 只保留 SPEC 标注、兼容 re-export 和薄入口，不承载 GitHub 业务实现。

拆分后的 `scripts/src/gh/` 子模块应按职责维护。单文件超过 3000 行时必须继续拆分；新增 GitHub 子命令必须落到对应模块或新增同级模块，不能重新堆入根入口。

### 6.2 OPS-GH-REQ-002 请求与选项解析

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-GH-REQ-002 | 请求选项 | PJ2026-01060602 请求与选项 | [源码同步](PJ2026-010602-source-sync.md) |

GitHub入口应集中处理 token resolution、REST/GraphQL request、公开 GitHub Pages 读取、错误分类、owner/repo、issue/PR number、URL/shorthand、JSON fields、known option validation 和 read/view target resolution。认证失败、repo 不存在、权限不足、GitHub transient、Pages 导出无效和 unsupported command 必须结构化输出，不得静默 fallback 到原生 `gh`、raw `curl` 或裸 API 调用。

GitHub Pages 读取只接受 HTTPS URL，拒绝 URL credential，并对响应体设置有界字节预算。`github-action-benchmark` 页面 URL 可以解析到同目录 `data.js`；CLI 必须验证导出 schema，再按 limit 或 commit 选择记录，不能执行导出文件中的 JavaScript。

### 6.3 OPS-GH-REQ-003 正文保护与并发 guard

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-GH-REQ-003 | 正文保护 | PJ2026-01060603 正文保护 | 规格治理、`trans gh:` |

GitHub入口应把 stdin、body file、inline short body、body patch、comment patch、profile guard、short body safety、body sha 和 updatedAt concurrency guard 收敛到正文保护模块。任何 issue/PR/comment 正式写入都必须经过该模块或等价共享 guard；dry-run 必须显示将要写入的目标、保护摘要和不会写入 GitHub 的结论。

### 6.4 OPS-GH-REQ-004 Issue/PR 命令与 merge guard

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-GH-REQ-004 | IssuePR | PJ2026-01060604 Issue与PR | [发布流水](PJ2026-010601-controlled-release.md) |

GitHub入口应提供 issue/PR list/read/view/create/update/patch/comment/close/reopen、PR files、preflight、create、comment、update、close/reopen 和 merge 受控命令。PR merge 必须先执行 state/draft/conflict/mergeable/status check closeout 预检；`already merged`、不可合并和检查失败必须可见，不能直接调用不受控 merge。

### 6.5 OPS-GH-REQ-005 Board、附件和污染扫描

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-GH-REQ-005 | Board附件 | PJ2026-01060605 Board附件扫描 | 项目治理、看板维护 |

GitHub入口应支持 board table parse、board-row list/get/update/add/upsert/move/delete dry-run/guarded mutation、attachment list/download dry-run、安全下载大小边界、stale-close 和 escape scan。默认输出必须有界，完整正文、附件内容和大扫描结果只能通过显式文件、dump 或 drill-down 展开。

### 6.6 OPS-GH-REQ-006 输出、帮助和渐进披露

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-GH-REQ-006 | 输出帮助 | PJ2026-01060606 输出帮助 | UniDesk CLI root |

GitHub入口应保持低噪声默认输出、稳定 `--json` 字段选择、`--raw`、`--full`、bounded dump 和 scoped help 行为。`gh --help`、`gh issue --help`、`gh pr --help` 和子命令 help 必须快速返回有界 JSON，不因拆分丢失 usage、notes 或 next command。

Actions benchmark 默认输出只能展示有界提交摘要和最近记录的测量表；结构化模式返回已经筛选的 entries 和 measurements，不回显完整 `data.js`。结果必须披露 source URL、导出更新时间、总记录数、返回记录数和 mutation=false，使调用方能判断数据新鲜度与裁剪范围。

## 7. 过程控制

本规格的执行 issue 为 [#906](https://github.com/pikasTech/unidesk/issues/906)。后续影响 GitHub入口稳定契约、模块边界、body guard、merge guard 或 `trans gh:` 写回语义的变更，应先更新本规格或在对应 issue 中说明为何不改变规格。
