<p align="center">
  <img src="docs/assets/logo.svg" width="128" alt="Repo Scout logo">
</p>

<h1 align="center">Repo Scout — 裝忙 Skills</h1>

<p align="center">
  <b>從 source code 找出真正值得做的工程工作，而不是為了湊數製造 issues。</b><br>
  <sub>給 <b>Claude Code</b>、<b>Codex CLI</b>、<b>Grok Build</b> 用的 agent skill · <a href="https://iml1s.github.io/repo-scout/">網站</a> · <a href="README.md">English</a></sub>
</p>

<p align="center">
  <a href="https://github.com/ImL1s/repo-scout/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/ImL1s/repo-scout/actions/workflows/ci.yml/badge.svg"></a>
  <a href="https://github.com/ImL1s/repo-scout/releases"><img alt="Release" src="https://img.shields.io/github/v/release/ImL1s/repo-scout?display_name=tag&color=7C3AED"></a>
  <img alt="Python 3.10+" src="https://img.shields.io/badge/python-3.10%2B-3776AB?logo=python&logoColor=white">
  <a href="LICENSE"><img alt="GPL-3.0-or-later" src="https://img.shields.io/badge/license-GPL--3.0--or--later-blue"></a>
</p>

---

一般「幫我 review」看的是 diff；**Repo Scout 看的是整個 repo**——架構、前端、後端、mobile、底層、安全、測試、CI、文件、AI agent 程式——然後產出一份**有證據、有優先順序的工程待辦**。

它刻意排斥裝忙：

| 一般 AI review | Repo Scout |
| --- | --- |
| 掃最近的 diff | 先建立模組、資料流、信任邊界的全貌 |
| 什麼「看起來怪」都列 | 把**已重現 bug**、**程式邏輯證實的問題**、**待驗證風險**、**可選改善**分開 |
| 每次固定擠 N 條 | **零項是合法結果。** 上限是天花板，不是配額 |
| 「建議改微服務」 | monolith、長檔案、舊依賴只是線索，不是缺陷 |
| 說「測試通過」 | 記錄指令、cwd、commit、exit code——否則寫 **NOT RUN** |
| 說「沒有重複」 | 沒有 issue 存取權時說「去重未完成」 |

## 流程

```text
盤點專案 → 選適用的檢查 lane → 找候選問題 → 主動找反證
        → 分級驗證 → 對既有 issues/PR 去重 → 排序 → 可稽核的報告
```

每個保留的項目都帶程式位置、觸發條件、影響、**證據等級（E0–E3）**、已檢查的替代解釋、最小修改方向、驗收標準與驗證狀態。報告最後有 **coverage matrix**：哪些範圍已檢查、部分檢查、受阻、略過——沒說話的地方也能被信任。

### 檢查 lane

| Lane | 找什麼 |
| --- | --- |
| **架構與跨層** | 模組邊界、狀態所有權、取消／錯誤傳遞、前後端合約不一致 |
| **Web／前端** | loading／empty／error／retry 狀態、重複送出、導航、無障礙、語系、尺寸 |
| **後端／資料** | 權限、交易、冪等重試、分頁、migration、備份還原、背景工作 |
| **Mobile** | Android、iOS、Flutter、RN、KMP；生命週期、process death、離線、權限、平台差異 |
| **Systems** | Desktop／CLI 退出碼與路徑、library／FFI、嵌入式協定、錢包合約、遊戲 |
| **安全／隱私** | 信任邊界、租戶隔離、日誌洩密、供應鏈、prompt injection 面 |
| **測試／交付** | 測試是否真的有跑、缺的回歸案例、CI wiring、README 與實作落差、發版 |
| **AI agents／MCP／skills** | 工具權限、重複副作用、子代理交接、重試、預算、注入 |

Lane 從 `skills/repo-scout/references/` 按需載入，不相關的 checklist 不會灌進去。

### 證據等級

| 等級 | 意思 |
| --- | --- |
| **E0** | 從名稱／pattern 來的線索——絕不當成已確認 |
| **E1** | 程式可達且有反證檢查的疑慮；殘餘假設要標出 |
| **E2** | source-level 證明違反不變量，但明講沒有 runtime 重現 |
| **E3** | 在記錄的環境重現，附指令與實際輸出 |

嚴重度和確定度分開追蹤：高影響的 E1 也可以是 P0 先查。

## 從官方目錄取得

| Host | 位置 | 狀態 |
| --- | --- | --- |
| Codex / ChatGPT | [OpenAI Plugins Directory](https://chatgpt.com/plugins/plugins_6aa0595d1d1881918d6321ebc0d66b91) | 已發布（0.1.0） |
| Claude Code | `anthropics/claude-plugins-community` | 已送審，等待 Anthropic 審核 |
| Grok Build | [xai-org/plugin-marketplace PR #622](https://github.com/xai-org/plugin-marketplace/pull/622) | PR 審核中 |

目錄尚未上架前，下面的安裝方式都可直接從本 repo 使用。

## 安裝

需要 **Python 3.10+**，沒有其他依賴。安裝器**預設 dry-run**、**絕不覆蓋**既有 skill：0.1.2 起會先把副本 staging 在目的地旁邊、寫入含每個檔案 SHA-256 的 `.repo-scout-install.json` 標記，再用 no-replace rename 發布（原語不可用時直接失敗，不退回會覆蓋的搬移）。所用原語為 Linux 的 `renameat2(RENAME_NOREPLACE)`、macOS 的 `renamex_np(RENAME_EXCL)`、Windows 不帶 replace 的 `MoveFileEx`；部分網路、FUSE 或 overlay 檔案系統與過舊的核心／C 函式庫會拒絕它，此時安裝器直接以明確錯誤停止，目的地維持原樣。

```bash
git clone https://github.com/ImL1s/repo-scout.git
cd repo-scout
python3 install.py --agent claude --apply   # → ~/.claude/skills/repo-scout
python3 install.py --agent codex  --apply   # → ~/.agents/skills/repo-scout
```

<details>
<summary><b>升級既有副本（安裝器絕不覆蓋）</b></summary>

1. 把舊副本移到**所有 skill 探索目錄之外**，例如 `mv ~/.claude/skills/repo-scout ~/repo-scout-backup-$(date +%F)`，確保沒有 host 還載得到它。
2. 安裝新版：`python3 install.py --agent claude --apply`。
3. 開一個**新的** host session 確認 `/repo-scout` 載入；`python3 install.py doctor` 應顯示該副本為 `managed`、`intact`、新版本號。
4. 確認無誤後再人工處理備份。目前沒有 `uninstall`：只因為有標記就刪目錄，可能刪掉你後來新增或修改的檔案。
</details>

<details>
<summary><b>裝了哪些副本？<code>install.py doctor</code></b></summary>

```bash
python3 install.py doctor                          # user scope：~/.claude、~/.agents、~/.grok
python3 install.py doctor --project /path/to/repo  # 連同該專案的 .claude/.agents/.grok 一起掃
```

只讀不寫。對每個文件化的根目錄回報：副本是否存在、是否 `managed`（帶有 0.1.2+ 寫入的 `.repo-scout-install.json` 標記）、版本——`version_observed`（副本的 `VERSION` 檔）與 `version_recorded`（標記記錄的值）加上 `version_mismatch` 旗標（`version` 兩者都有時取觀察值，否則取標記值，再不然是 `unknown`）、SKILL.md 與整包 payload 的 SHA-256、對照標記的完整性（`intact`；`modified` 並列出缺少／修改／多出／不規則的項目；或 `incomplete`——副本有一部分讀不到，此時 payload 摘要與原始碼比對都是 `null`）、是否與你執行它的那份原始碼一致，以及殘留的 staging 目錄。symlink 與 Windows junction 絕不跟隨：出現在 `.claude`、`skills` 或 `repo-scout` 這些路徑元件時回報為 `symlink-not-followed`，出現在副本內部時列為不規則項目，副本就不會被判定為 `intact`。它**只掃已知根目錄**，無法判定 host 實際載入的是哪一份（`active_copy: unknown`）；那要在新 session 看 host 自己的 skill 清單。
</details>

<details>
<summary><b>Claude Code — 用 <code>/plugin</code> 安裝</b></summary>

```text
/plugin marketplace add ImL1s/repo-scout
/plugin install repo-scout@repo-scout
```

plugin 形式的指令是 `/repo-scout:repo-scout`，standalone skill 是 `/repo-scout`。二選一，不要同時裝。
</details>

<details>
<summary><b>Codex CLI — 從本 repo 的 marketplace 裝成 plugin</b></summary>

```bash
codex plugin marketplace add https://github.com/ImL1s/repo-scout.git
codex plugin add repo-scout@repo-scout
```

用 `$repo-scout` 呼叫。plugin 與 standalone skill 二選一。
</details>

<details>
<summary><b>Grok Build</b></summary>

裝成 plugin：

```bash
grok plugin marketplace add ImL1s/repo-scout
grok plugin install repo-scout --trust
```

Grok Build 也會自動讀 Claude Code 的 skills。已用 `--agent claude` 裝好的話，**不用再裝**——`/repo-scout` 已經在選單裡（Grok Build 1.0.13 實測；再裝一份到 `~/.grok/skills` 選單可能出現兩個）。

沒裝 Claude Code 版本時：

```bash
python3 install.py --agent grok --apply     # → ~/.grok/skills/repo-scout
# 或（Grok 文件寫法，本專案未實測）：grok plugin install ImL1s/repo-scout
```
</details>

<details>
<summary><b>Codex CLI — 專案內安裝</b></summary>

```bash
python3 install.py --agent codex --scope project --project /path/to/repo --apply
# → /path/to/repo/.agents/skills/repo-scout（commit 進去就能跟團隊共用）
```
</details>

<details>
<summary><b>Grok Bot</b></summary>

Grok Bot 的技能走它自己的 private skill 流程，不是本機目錄。把 `skills/repo-scout` 提供給 Bot，用 [`examples/grok-bot-setup.zh-TW.md`](examples/grok-bot-setup.zh-TW.md) 的提示請它存成可重用的 private skill。這條路徑**有文件但尚未端到端驗證**。
</details>

## 使用

Claude Code／Grok Build：

```text
/repo-scout mode=scan scope=all
先盤點所有 first-party modules、技術棧、平台和外部合約，再做風險導向 review。
包含 architecture、frontend、backend/data、mobile、security、tests/CI、docs。
不要改碼、不要跑專案腳本、不要開 issues、不要啟動 CI。
每項附程式位置、影響、證據等級、反證檢查、驗收標準與未驗證範圍。
最多保留 10 項，數量不是目標。
```

Codex：

```text
$repo-scout mode=scan scope=all
盤點此 repo 並產生待辦草稿。疑似問題與已證實問題分開，零項也可以。
```

`mode=scan | verify | plan | publish | fix` 與 `scope=all | changed | <path>` 是這個 skill 的**自然語言約定**，不是 CLI flags。`scan` 是預設，不寫檔、不跑專案指令、不發佈、不花錢；其他模式都要明確授權，而且真正的邊界仍是 host 的權限系統。

更多情境（聚焦 mobile、從報告寫計畫、授權本機驗證）：[`examples/usage.zh-TW.md`](examples/usage.zh-TW.md)。

## 它不會做的事

- 把檔名盤點當成 review。`scripts/inventory.py` **只讀檔名**——不讀原始碼、不讀 manifest、不跑 git、不連網——而且自己的輸出會這樣寫。
- 宣稱「支援所有語言」。流程是語言無關的；解析器與 runtime 檢查用的是你 repo 既有的工具，未知技術棧會做通用審查並明確標出缺口。
- 用讀 source 代替 iOS／UI／硬體驗證。沒有 Xcode 就是 *blocked*，不是 *passed*。
- 自己變成排程器、issue 發佈器或修 bug 機器人。那些需要有 scoped 憑證、狀態帳本與發佈閘門的 host runner（見 [`docs/roadmap.md`](docs/roadmap.md)）。

## 目前已驗證

| Host | 版本 | 載入與 reference 解析 | 行為準確率 |
| --- | --- | --- | --- |
| Claude Code | 2.1.263 | ✅ `claude -p "/repo-scout …"` | ⏳ 尚未量測 |
| Codex CLI | 0.153.0 | ✅ `codex exec '$repo-scout …'` | ⏳ 尚未量測 |
| Grok Build | 1.0.13 | ✅ 直接讀 Claude Code 的 skill 目錄 | ⏳ 尚未量測 |
| Grok Bot | — | 📝 有手動移植文件 | ⏳ |

套件測試：**103 個單元測試**，CI 在 Linux／macOS／Windows × Python 3.10–3.14 上執行，涵蓋盤點上限、排除規則、symlink 與 Windows junction、敏感檔名、安裝 staging／no-replace 發布／中途強制終止、`doctor` 診斷，以及 release acceptance 腳本對刻意損壞的發行資產集的拒絕。細節與 smoke test 摘要：[`TEST-RESULTS.txt`](TEST-RESULTS.txt)。含「不用 skill 對照組」的評估計畫：[`docs/evaluation.md`](docs/evaluation.md)。

## 目錄結構

```text
skills/repo-scout/
├── SKILL.md                     # 共用流程（每個 host 載入的就是它）
├── references/                  # 每個 lane 一份 + 證據契約 + 工具選擇
├── assets/finding.template.json # finding 的機器可讀形狀（範例，非強制 schema）
├── scripts/inventory.py         # 只讀、只看檔名、有上限的盤點工具
├── VERSION                      # 隨每份安裝副本一起走的版本資料
└── agents/openai.yaml           # Codex 顯示資訊，關閉隱式觸發
install.py                       # 安裝（no-replace 發布 + 標記）或 `doctor`（只讀盤點）
scripts/                         # build_plugin_zip.py 與 release_acceptance.py（bundle 與其驗收）
tests/                           # 盤點工具、安裝器、套件完整性的單元測試
.claude-plugin/ .codex-plugin/ .grok-plugin/ .agents/   # 各 host 的 plugin + marketplace manifest
assets/                          # 目錄上架用的 logo 與 composer icon
site/                            # 網站（GitHub Pages）：首頁、privacy、terms、support
submission/                      # 上架草稿、審核測試案例與 fixtures
docs/                            # 相容性、評估計畫、roadmap、外部審查
examples/                        # 常見情境提示與 Grok Bot 移植
```

## 開發

```bash
python3 -m unittest discover -s tests -v          # 或 python3 -m pytest -q tests
python3 skills/repo-scout/scripts/inventory.py .  # exit 0 = 完整，2 = partial
python3 skills/repo-scout/scripts/inventory.py . --include build/gen --exclude docs   # 範圍旗標（見下）
python3 install.py --agent claude                 # dry-run：只印計畫，不寫檔
python3 install.py doctor                         # 只讀：已知 host 根目錄下的每一份副本
python3 scripts/release_acceptance.py             # 建置、解壓、安裝並實跑 bundle
claude plugin validate .                          # manifest 檢查（需 Claude Code CLI）
```

盤點工具的範圍旗標可重複、必須是 repo 相對路徑、以 `/` 分隔（不接受絕對路徑與 `..`；`foo` 不會匹配到 `foobar`）。優先序由高到低：根目錄邊界、symlink 與 Windows junction（絕不跟隨）、非一般檔案與硬性敏感名稱（`.ssh`、`.aws`、`.secrets`、`.gnupg`、`.env*`、金鑰檔）> `--exclude` > `--include` > `node_modules`、`build`、`dist`、`vendor` 這類便利性排除。`--include` 是**額外納入**：只穿過必要的祖先目錄，把便利性排除目錄底下的某個檔案或子樹重新納入。`--include DIR` 納入整個子樹；`--include DIR/file` 只納入該檔案，途經的便利性排除祖先目錄裡其餘項目會回報為 `outside-include-scope`。一般目錄不受影響（`--include src/gen.py` 不會藏起 `src/other.py`）。沒有匹配到任何東西的旗標會列在 `scope.include_unmatched` 與 `scope.exclude_unmatched`。反斜線只在 Windows 上視為分隔符。路徑元件照字面解讀：開頭或結尾帶空白的元件會被拒絕而不是被修剪，所以 `--exclude " private "` 是錯誤，絕不會悄悄變成排除 `private`（結尾的 `/` 仍可接受）。include 落在 exclude 之下、或指向敏感目錄／檔案，會在一開始就被拒絕。永遠不讀 `.gitignore`，輸出會明講（`gitignore_respected: false`）。

CI 在 Linux／macOS／Windows × Python 3.10–3.14 跑測試、驗證 plugin manifest，並從解壓後的 bundle 跑 release acceptance。打 `vX.Y.Z` tag（需與 `.claude-plugin/plugin.json` 及 `skills/repo-scout/VERSION` 一致）會先等該 commit 的 CI 綠燈，再建置原始碼封存檔（內嵌 `MANIFEST.sha256`）與 bundle、對這組資產完整跑 acceptance，發布前重新解析遠端 tag、確認它仍指向通過 CI 的那個 commit（否則拒絕發布），最後以 `gh release create --verify-tag` 連同 `SHA256SUMS` 發布 release。

acceptance 腳本驗證的是 release job 剛建置出來的資產是否與被打 tag 的 commit 一致（原始碼封存檔等於該 commit 的 tree、plugin bundle 是它的 hash 相等子集、skill 在三個封存檔中逐位元相同、沒有 bytecode、沒有目錄項、沒有 extra field、每個 local header 指向同一個成員）。它不是通用的 ZIP 消毒器：它像 `zipfile` 一樣信任 central directory，且只比對每個 local header 的名稱與 extra field 長度，所以刻意做成 local record 不一致的封存檔（壓縮方法、CRC 或大小不符、孤兒或串接的 record、mode bits）仍可能被其他解壓工具讀成不同內容或亂碼。下載資產時請驗證 `repo-scout-vX.Y.Z.zip.sha256` 與 `SHA256SUMS`，那才是完整性的依據。

## Roadmap

- **v0.1.2**（已出）— 帶標記的 no-replace 安裝器、`install.py doctor`、額外納入式的 `--include`／`--exclude` 範圍旗標（刻意不解析 `.gitignore`）、從解壓 bundle 做 release acceptance。`uninstall` 仍延後。
- **v0.2** — 在植入缺陷的 fixture 上做行為評估，附不用 skill 的對照組；證據綁定快照／內容 hash；一個真實專案案例。
- **v0.3** — 可選的持續模式：run ledger、增量範圍、重疊鎖、成本上限、發佈對帳。

完整理由見 [`docs/roadmap.md`](docs/roadmap.md)。

## 貢獻

歡迎 issue 與 PR。請守住核心精神：**不製造 finding、不做沒驗證的成功宣稱。** 新增 lane 或檢查時，一併加上讓它保持誠實的反證問題。

## 授權

[GPL-3.0-or-later](LICENSE) © 2026 ImL1s

Repo Scout 是自由軟體：你可以依照自由軟體基金會發布的 GNU 通用公眾授權條款第 3 版，或（依你的選擇）任何更新版本，重新散布或修改它。v0.1.0 以前（含該 tag、release zip 與 OpenAI 目錄上的 0.1.0 bundle）以 MIT 授權發布並持續有效；從這個 commit 起皆為 GPL-3.0-or-later。
