## 概要
[[GitHub Copilot CLI]]で[[AI]]レビューをしている。
- レビュー対象は[[Git]]の[[ワークツリー]]で作成
- ホストマシンで[[カスタムエージェント (GitHub Copilot CLI)|カスタムエージェント]]と[[スキル (GitHub Copilot)|スキル]]を使ってレビュー
- [[サブエージェント (GitHub Copilot CLI)|サブエージェント]]は未使用 (不安定なので)
- [[cmux]]で[[ワークスペース (cmux)|ワークスペース]]を立ち上げて実行
ただ、以下の課題がある。
- コマンドの承認が面倒
- とはいえ [[--allow-all-tools]] は恐い
- 隔離環境として[[コンテナ (Docker)|コンテナ]]を使うしかない...
というわけで[[Docker]]を使った環境構築についてチャレンジしてみる。
## 対象リポジトリ
- [[🦉GitHub Copilot CLI Sandbox]]
## やること
- [x] [[Docker]]を使って[[GitHub Copilot CLI]]を実行してみる
- [x] 認証が通るか?
- [x] [[cmux]]での見え方はどうなるか?
- 中の通知は流石にこなそう
# Ph1: まずやってみる
## [[Docker]]を使って[[GitHub Copilot CLI]]を実行してみる
`Dockerfile`
```docker
FROM node:24-bookworm-slim
# 必要最低限のツール
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
bash \
ca-certificates \
ripgrep \
fd-find \
less \
procps \
&& rm -rf /var/lib/apt/lists/*
# Copilot CLI
RUN npm install -g @github/copilot
# 任意: fd コマンド名を揃える
RUN ln -s /usr/bin/fdfind /usr/local/bin/fd || true
# Copilot の設定場所
ENV COPILOT_HOME=/root/.copilot
WORKDIR /work
CMD ["copilot"]
```
ビルドする。
```console
docker build -t safe-copilot-cli .
```
実行する。
```console
docker run --rm -it \
-v "$HOME/.copilot:/root/.copilot" \
-v "$PWD:/work" \
-w /work \
safe-copilot-cli
```
トークン指定がないと通らない。
## トークンの作成と設定
[[COPILOT_GITHUB_TOKEN]]に[[Personal Access Token (GitHub)|Personal Access Token]]を設定する必要があるため作成する。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
Build software better, together
</div>
<div class="link-card-v2-content">
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute ...
</div>
<img class="link-card-v2-image" src="https://github.githubassets.com/assets/github-logo-55c5b9a1fe52.png" />
<a href="https://github.com/settings/personal-access-tokens"></a>
</div>
![[2026-04-01-20-57-28.avif]]
以下を実行したところ、認証状態が反映された。
```console
docker run --rm -it \
-e COPILOT_GITHUB_TOKEN="$COPILOT_GITHUB_TOKEN" \
-v "$HOME/.copilot:/root/.copilot" \
-v "$PWD:/work" \
-w /work \
safe-copilot-cli
```
## 権限を緩くする
せっかくのsandbox環境なのでツールの許可設定を緩める。コマンドもあらかじめ入力しておく。
```console
docker run --rm -it \
-e COPILOT_GITHUB_TOKEN="$COPILOT_GITHUB_TOKEN" \
-v "$HOME/.copilot:/root/.copilot:ro" \
-v "$PWD:/work" \
-w /work \
safe-copilot-cli \
copilot --yolo -i "/review"
```
> [!danger]
> [[--allow-all|--yolo]] は [[--allow-all-tools]] に加えて、すべてのpath, urlに対する実行を許可するため非常に危険。乗っ取られても問題ない隔離環境でのみ実行すること。
## ホストの設定を同期する
`~/.copilot` の設定を同期する。自分の環境ではシンボリックリンクを多用しているため、気合でマウントする必要があるが、`docker run` コマンドで制御できるので大きな問題ではない。
```console
docker run --rm -it \
-e COPILOT_GITHUB_TOKEN="$COPILOT_GITHUB_TOKEN" \
-v "$HOME/.copilot:/root/.copilot:ro" \
-v "$HOME/.copilot/copilot-instructions.md:/root/.copilot/copilot-instructions.md:ro" \
-v "$HOME/.claude/skills:/root/.claude/skills:ro" \
-v "$PWD:/work" \
-w /work \
safe-copilot-cli \
copilot --yolo -i "/task レビュー"
```
## [[macOS]]専用コマンドが実行できない
たとえば、[[GitHub Copilot CLI]]の中で[[cmux]]の操作や[[Obsidian]]を変更するコマンドは実行できない。[[Jenkins]]などのCIでも当然同じなので、この要件は諦めたほうがいい。
言い方を変えると、これらのジョブ(と呼ぶ)の実行状態は気にせず、終わったら[[Slack]]通知などの手段で伝える方がいい。
# Ph2: 設定やコマンドの見直し
## Dockerfileの設定しなおし
不要設定削除とrootユーザーの利用をやめる。
`Dockerfile`
```docker
FROM node:24-bookworm-slim
# less: ページャー用, procps: ps等のプロセス確認用
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
bash \
ca-certificates \
ripgrep \
fd-find \
less \
procps \
&& rm -rf /var/lib/apt/lists/*
RUN npm install -g --no-fund @github/
[email protected]
RUN [ ! -e /usr/local/bin/fd ] && ln -s /usr/bin/fdfind /usr/local/bin/fd
RUN mkdir -p /work && chown node:node /work
USER node
WORKDIR /work
CMD ["copilot"]
```
## コマンドの見直し
[[#macOS 専用コマンドが実行できない]] で見つめ直した結果、設定なども独立した環境の方が良さそうなので、コマンドをシンプルにする。
```
docker run --rm -it \
-e COPILOT_GITHUB_TOKEN="$COPILOT_GITHUB_TOKEN" \
--tmpfs /home/node/.copilot \
-v "$HOME/.copilot/session-state:/home/node/.copilot/session-state" \
-v "$PWD:/work" \
-w /work \
safe-copilot-cli \
copilot --no-auto-update --yolo -p "このリポジトリは何をやっている?"
```
- **`session-state` だけ同期**
- あとで対話を再開したい( = 追加質問したい)ときのため
- **`--tmpfs` 指定**
- [[GitHub Copilot CLI]]起動前に `.copilot` ディレクトリが存在しないことによるマウントエラーを防ぐため。
# Ph3: 前後のホスト処理
[[AI]]への依頼部分は1コマンドで実行できるようになったので、前後に必要な処理を入れる。基本的には[[cmux]]。
| No | 手順 | マシン | スコープ |
| --- | -------------------------------- | ---- | ---- |
| 1 | [[ワークスペース (cmux) \| ワークスペース]]の追加 | ホスト | 個人 |
| 2 | [[cmux]]の操作 (`ss`) | ホスト | 個人 |
| 3 | 引数(PR URLなど)の解析 | ホスト | チーム |
| 4 | [[ワークツリー]]の作成 | ホスト | チーム |
| 5 | [[Docker]]で処理 | コンテナ | チーム |
| 6 | [[cmux]]の操作 (`ss`) | ホスト | 個人 |
| 7 | 通知 | ホスト | 個人 |
- 3~5 は必須の共通処理
1は保留して、一旦2,5,6,7をやってみる。
```bash
#!/bin/bash
notify() {
local title="$1"
local body="$2"
printf '\e]777;notify;%s;%s\a' "$title" "$body"
}
ss progress 0.5 レビュー中
docker run --rm -it \
-e COPILOT_GITHUB_TOKEN="$COPILOT_GITHUB_TOKEN" \
--tmpfs /home/node/.copilot \
-v "$HOME/.copilot/session-state:/home/node/.copilot/session-state" \
-v "$PWD:/work" \
-w /work \
safe-copilot-cli \
copilot --no-auto-update --yolo -p "このリポジトリは何をやっている?"
ss wait
notify "レビューが完了しました"
```