Entire を Claude Code Web で動かす ― プロキシの壁を pushInsteadOf で突破する

に公開

はじめに

前回の記事で、AIコーディングセッション記録ツール Entire CLI が husky と競合する問題とそのワークアラウンドを紹介した。

その記事の末尾で「Claude Code Web(以下 ccweb)ではさらに別の問題がある」と触れたが、今回はその ccweb 固有の問題を掘り下げ、実際に動く解決策 を示す。

具体的には、ccweb 環境で Entire を使おうとした時に立ちはだかる 2つの壁 と、それぞれをどう突破するかを解説する。解決策は npm パッケージ entire-setup-ccweb として公開した。

Entire のおさらい

詳しくは前回の記事を参照してほしいが、要点だけ振り返る。

Entire は、Claude Code や Gemini CLI によるコーディングセッションを Git 履歴と紐付けて記録 するツールである。コミットやプッシュのタイミングで Git フックが発火し、セッションの対話ログやファイル変更をチェックポイントとして entire/checkpoints/v1 ブランチに保存する。

ポイントは、チェックポイントデータはコードとは別のブランチ(シャドウブランチ)に push される という点である。これにより、コードのコミット履歴を汚さずにセッション情報を永続化できる。

ccweb の仕組み

ccweb(claude.ai/code から起動するクラウドセッション)の内部動作を理解しておくと、問題の本質が見えやすい。

ccweb でタスクを開始すると、以下のことが起きる。

  1. リポジトリのクローン … 対象リポジトリが Anthropic が管理する隔離された VM にクローンされる
  2. 環境のセットアップ … 主要な言語・ツールがプリインストールされたユニバーサルイメージ上で動作する
  3. ネットワーク設定 … Git の origin リモートはセキュリティプロキシ経由に設定される
  4. タスク実行 … Claude Code がコードを分析・変更し、テストを実行する
  5. 結果の反映 … 変更がブランチに push され、PR 作成が可能になる

重要なのは 3. ネットワーク設定 と、Git 操作に関する以下の制約である。

Git プロキシ

ccweb 環境では、Git の origin URL が ローカルプロキシ を指している。

origin  http://local_proxy@127.0.0.1:XXXXX/git/<owner>/<repo> (fetch)
origin  http://local_proxy@127.0.0.1:XXXXX/git/<owner>/<repo> (push)

公式ドキュメントによると、このプロキシは以下の役割を担う。

  • GitHub 認証の安全な管理(サンドボックス内のスコープされた認証情報をプロキシが検証し、実際の GitHub トークンに変換する)
  • git push 操作を現在のワーキングブランチに制限する
  • クローン・フェッチ・PR 操作はシームレスに通す

2つ目が今回の問題の核心である。

壁1: entire バイナリがない

ccweb のユニバーサルイメージには Go ランタイムはプリインストールされているが、Entire CLI は入っていない。entire コマンドが存在しなければ当然セッション記録は機能しない。

さらに、Entire CLI の go.mod が要求する Go バージョンが ccweb 環境にプリインストールされているものより新しい場合、go install 自体が失敗する。実際、執筆時点で Entire は Go 1.25.6 を要求しており、ccweb 環境の Go では対応できない。

解決策: セッション開始時に GitHub Releases からプリビルドバイナリをダウンロードし、entire enable まで自動実行する。SHA256 チェックサムによる検証も行う。

if ! command -v entire >/dev/null 2>&1; then
  # プラットフォーム検出
  _os=$(uname -s | tr '[:upper:]' '[:lower:]')
  _arch=$(uname -m)
  case "$_arch" in
    x86_64)  _arch="amd64" ;;
    aarch64) _arch="arm64" ;;
  esac
  _asset="entire_${_os}_${_arch}.tar.gz"

  # GitHub API で最新リリースタグを取得
  _tag=$(curl -fsSL -H "Authorization: token ${GITHUB_TOKEN}" \
    "https://api.github.com/repos/entireio/cli/releases/latest" \
    | grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')

  _base="https://github.com/entireio/cli/releases/download/${_tag}"
  _tmp=$(mktemp -d)

  # バイナリとチェックサムをダウンロード
  curl -fsSL -H "Authorization: token ${GITHUB_TOKEN}" -o "${_tmp}/${_asset}" -L "${_base}/${_asset}"
  curl -fsSL -H "Authorization: token ${GITHUB_TOKEN}" -o "${_tmp}/checksums.txt" -L "${_base}/checksums.txt"

  # SHA256 検証
  (cd "$_tmp" && grep "$_asset" checksums.txt | sha256sum -c -)

  # 展開・インストール
  tar -xzf "${_tmp}/${_asset}" -C "$_tmp"
  mv "${_tmp}/entire" "${GOPATH:-$HOME/go}/bin/entire"
  rm -rf "$_tmp"

  # 未 enable なら非対話モードで enable
  if ! entire status 2>/dev/null | grep -q "^Enabled"; then
    entire enable --agent claude-code
  fi
fi

Go のバージョンに依存せず、ネットワークアクセスさえあれば確実にインストールできる。ccweb の環境設定で「信頼済み」(Trusted) 以上のネットワークアクセスを選択しておく必要がある。

これは比較的単純な問題だ。本当に厄介なのは次の壁である。

壁2: シャドウブランチを push できない

これが本題。

Entire はチェックポイントデータを entire/checkpoints/v1 ブランチに push する。しかし、ccweb のプロキシは 現在のワーキングブランチ以外への push を拒否 する。

ccweb でのワーキングブランチは通常 claude/<task>-<session-id> のような形式である。entire/checkpoints/v1 はワーキングブランチではないので、プロキシのフィルタに引っかかり HTTP 403 で弾かれる。

# プロキシが許可する push:
claude/fix-auth-bug-abc123  → ✅ (ワーキングブランチ)

# プロキシが拒否する push:
entire/checkpoints/v1       → ❌ (ワーキングブランチではない)
main                        → ❌

つまり、Entire のチェックポイント機能はプロキシの設計と根本的に相容れない

解決策: プロキシを迂回する

前回の記事では「Entire 側のブランチプレフィクスをカスタマイズ可能にする」「Claude Code 側で entire/ を許可リストに追加する」という2つの方向性を挙げた。

しかし、どちらもツール側の対応待ちである。今すぐ使いたい場合、第3の道がある

pushInsteadOf という Git の機能

Git には url.<base>.pushInsteadOf という設定がある。これは push 時のみ URL を書き換える機能だ。

git config --global url."https://github.com/".pushInsteadOf "http://proxy.example.com/git/"

この設定をすると、以下のように動作する。

  • fetch: http://proxy.example.com/git/owner/repo → そのまま(プロキシ経由)
  • push: http://proxy.example.com/git/owner/repohttps://github.com/owner/repo(直接 GitHub へ)

つまり、fetch はプロキシ経由のまま、push だけ GitHub に直接向ける ことができる。

認証: GITHUB_TOKEN

プロキシを通さず GitHub に直接 push するには、別途認証が必要になる。ccweb の環境変数に GITHUB_TOKEN(Personal Access Token)を設定し、push URL に埋め込む。

git config --global \
  url."https://x-access-token:${GITHUB_TOKEN}@github.com/".pushInsteadOf \
  "$PROXY_BASE_URL"

$PROXY_BASE_URLorigin の URL から自動検出する。

# origin URL: http://local_proxy@127.0.0.1:XXXXX/git/owner/repo
# ↓ sed で /git/ より前のベース部分を抽出
PROXY_URL=$(git remote get-url origin | sed 's|\(.*\)/git/.*|\1/git/|')
# → http://local_proxy@127.0.0.1:XXXXX/git/

これで、Entire が entire/checkpoints/v1 に push しようとすると、プロキシを迂回して直接 GitHub に到達する。

安全策: pre-push フィルタ

ただし、「push が直接 GitHub に行く」というのは諸刃の剣でもある。万が一 Claude が意図しないブランチに push しようとした場合、プロキシのフィルタが無い分、そのまま通ってしまう。

そこで、.git/hooks/pre-push にフィルタを設置し、許可されたプレフィクスのブランチ以外への push をブロック する。

#!/bin/sh
ALLOWED_PREFIXES="entire/"
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)

while read local_ref local_sha remote_ref remote_sha; do
  branch="${remote_ref#refs/heads/}"
  # 現在のワーキングブランチは常に許可
  if [ "$branch" = "$CURRENT_BRANCH" ]; then
    continue
  fi
  allowed=false
  for prefix in $ALLOWED_PREFIXES; do
    case "$branch" in
      "$prefix"*) allowed=true; break ;;
    esac
  done
  if [ "$allowed" = false ]; then
    echo "[pre-push] blocked: $branch (allowed: $ALLOWED_PREFIXES + current branch)" >&2
    exit 1
  fi
done

これにより、直接 GitHub に push できるのは以下のブランチだけに制限される。

  • entire/ で始まるブランチ(Entire のシャドウブランチ)
  • 現在のワーキングブランチ(ccweb が割り当てたブランチ)

main や他の保護されたブランチへの push は、プロキシの制限と同等の安全性でブロックされる。

全体像: SessionStart フック

ここまでの解決策を ccweb のセッション開始時に自動で適用 するために、Claude Code の SessionStart フック を使う。

.claude/settings.json に以下を登録しておく。

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "sh .claude/scripts/setup-env.sh"
          }
        ]
      }
    ]
  }
}

setup-env.sh は先頭で環境チェックを行い、ccweb 環境でのみ 処理を実行する。

if [ "$CLAUDE_CODE_REMOTE" != "true" ]; then
  exit 0
fi

CLAUDE_CODE_REMOTE は ccweb 環境で自動的に true に設定される環境変数である。ローカルで Claude Code を使う場合はこのスクリプトは何もせずに終了する。

処理の流れ

ccweb セッション開始

  ├─ SessionStart フック発火
  │   └─ sh .claude/scripts/setup-env.sh
  │       │
  │       ├─ CLAUDE_CODE_REMOTE=true ? → No → exit 0
  │       │
  │       ├─ 1. entire バイナリのインストール & enable
  │       │   ├─ GitHub Releases からダウンロード(SHA256 検証付き)
  │       │   └─ entire enable --agent claude-code
  │       │
  │       ├─ 2. pushInsteadOf の設定
  │       │   └─ GITHUB_TOKEN があれば push を GitHub 直通に
  │       │
  │       └─ 3. pre-push フィルタの設置
  │           └─ entire/ と現在ブランチのみ許可

  └─ タスク実行開始

セットアップ手順

以上の仕組みを手動で設定するのは面倒なので、npm パッケージにまとめた。

前提条件

  • ccweb の環境設定でネットワークアクセスが「信頼済み」(Trusted) 以上であること

1. ローカルでセットアップを実行

npx entire-setup-ccweb@latest

リポジトリ内のどのディレクトリから実行しても、git rev-parse --show-toplevel でルートを自動検出する。

実行すると以下の2つが行われる。

  • .claude/settings.json に SessionStart フックを追加(既存のフックは保持、重複チェック付き)
  • .claude/scripts/setup-env.sh を作成(既にあればスキップ)

2. GITHUB_TOKEN を取得

  1. GitHub > Settings > Developer settings > Personal access tokens を開く
  2. Fine-grained tokens → 「Generate new token」
    • Repository access: 対象リポジトリを選択
    • Permissions → Repository permissions → Contents: Read and write
  3. トークンをコピー

Classic token の場合は repo スコープを付与する。

3. ccweb の環境変数とネットワークアクセスを設定

claude.ai の Settings > Claude Code から環境を編集し、以下の2つを設定する。

  1. ネットワークアクセス: 「信頼済み」(Trusted) 以上を選択(バイナリのダウンロードや GitHub への直接 push に必要)
  2. 環境変数: GITHUB_TOKEN を追加
GITHUB_TOKEN=ghp_xxxxx

4. コミット & プッシュ

git add .claude/
git commit -m "Add ccweb setup for Entire CLI"
git push

5. ccweb でリポジトリを開く

ccweb でセッションを開始すると、SessionStart フックにより自動的に Entire CLI のインストールと push 設定が行われる。

push プレフィクスのカスタマイズ

デフォルトでは entire/ プレフィクスのブランチのみ直接 push が許可される。変更するには .claude/scripts/setup-env.sh の先頭を編集する。

# スペース区切りで複数指定可能
ALLOWED_PUSH_PREFIXES="entire/ claude/"

GITHUB_TOKEN を設定しない場合

GITHUB_TOKEN を設定しなくても、Entire CLI 自体はインストールされる。ただし、pushInsteadOf が設定されないため、シャドウブランチの push はプロキシに弾かれ、チェックポイントがリモートに記録されない。

ローカルでのセッション記録は機能するが、entire.io での閲覧や他のセッションからの entire rewind には使えない状態になる。

GITHUB_TOKEN のセキュリティに関する注意

このやり方は GITHUB_TOKEN 生成時に指定した権限をエージェントに渡すことになるため、セキュリティ上の懸念がある。万が一トークンが漏洩した場合や、エージェントが意図しない操作を行った場合の影響範囲を最小化するため、以下の点に留意してトークンを運用すること。

  • 対象リポジトリの最小化 … Fine-grained token の Repository access で、必要なリポジトリだけを選択する。「All repositories」は避ける
  • 権限の最小化 … Contents の Read and write のみを付与し、それ以外の権限は付けない
  • 有効期限の最小化 … トークンの有効期限をできるだけ短く設定し、定期的に再生成する

まとめ

ccweb で Entire を使う際の障壁は以下の2つである。

  1. entire バイナリが存在しない → GitHub Releases からプリビルドバイナリをダウンロード(SHA256 検証付き)
  2. プロキシがシャドウブランチへの push を拒否するpushInsteadOf でプロキシを迂回し、pre-push フィルタで安全性を確保

解決のポイントは、Git の pushInsteadOf を使って fetch はプロキシ経由のまま、push だけ直接 GitHub に向ける という分離にある。プロキシの制限をすべて迂回するのではなく、Entire が必要とする push 操作だけをバイパスすることで、ccweb のセキュリティモデルとの両立を図っている。

Discussion