Claude Media
CLAUDE_CODE_SYNC_SKILLSの2つのタイムアウト変数を使い分ける

CLAUDE_CODE_SYNC_SKILLSの2つのタイムアウト変数を使い分ける

CLAUDE_CODE_SYNC_SKILLS_INSTALL_TIMEOUT_MSとCLAUDE_CODE_SYNC_SKILLS_WAIT_TIMEOUT_MSは効く局面が違います。既定値と超過時の挙動を分けて見ます。

CLAUDE_CODE_SYNC_SKILLSの2つの子変数

CLAUDE_CODE_SYNC_SKILLSは、非対話モード(-pフラグ)でclaude.aiアカウントに有効化されているSkillsをダウンロードし、最初のクエリを実行する前にその一覧を待つ設定です。claude.ai認証が前提になります。

この待機には、性質の異なる2つのタイムアウトが関わります。

くらべる

どちらの局面を待つ変数か

既定 5000ミリ秒

WAIT_TIMEOUT_MS

CLAUDE_CODE_SYNC_SKILLS_WAIT_TIMEOUT_MSは、CLAUDE_CODE_SYNC_SKILLSを設定した-p実行で、最初のクエリがSkills一覧を待つ上限です。超過すると、到着済みのSkillsだけで最初のクエリを実行します。

既定 30000ミリ秒

INSTALL_TIMEOUT_MS

CLAUDE_CODE_SYNC_SKILLS_INSTALL_TIMEOUT_MSは、Agent SDK上に構築したアプリがセッション途中でSkillsを再読み込みするときの、再同期を待つ上限です。超過すると、到着済みのSkillsだけで再読み込みを続けます。

名前が似ているので、取り違えに注意します。

どちらも、タイムアウトを過ぎてもダウンロード自体はバックグラウンドで続きます。そのSkillを実際に呼び出す時点でダウンロードが終わっていなければ、Claude Codeはそこで完了を待ちます。タイムアウトは一覧が揃うまで待つ上限であって、ダウンロードの制限時間ではありません。

変数を設定する方法

シェルで直接設定する場合です。

export CLAUDE_CODE_SYNC_SKILLS=1
export CLAUDE_CODE_SYNC_SKILLS_WAIT_TIMEOUT_MS=8000
export CLAUDE_CODE_SYNC_SKILLS_INSTALL_TIMEOUT_MS=45000
claude -p "レビューを実行して"

.claude/settings.jsonのenvブロックに書く場合も同じキー名を使います。

{
  "env": {
    "CLAUDE_CODE_SYNC_SKILLS": "1",
    "CLAUDE_CODE_SYNC_SKILLS_WAIT_TIMEOUT_MS": "8000",
    "CLAUDE_CODE_SYNC_SKILLS_INSTALL_TIMEOUT_MS": "45000"
  }
}

同期の挙動は、環境変数と、後述するsyncClaudeAiSkills設定で決まります。

Pluginsの同期待ちには既定のタイムアウトが無い

env-varsのリファレンスには、Pluginsのインストールを待つためのCLAUDE_CODE_SYNC_PLUGIN_INSTALLとCLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MSという一対の変数も載っています。CLAUDE_CODE_SYNC_PLUGIN_INSTALLを非対話モードで1にすると、最初のクエリの前にPluginsのインストール完了を待ちます。設定しなければPluginsはバックグラウンドでインストールされ、最初のターンでは使えないことがあります。

対応するタイムアウト変数を超過すると、Claude CodeはPluginsなしで処理を進め、エラーを記録します。この変数に既定値はなく、設定しない限り同期インストールは完了まで待ち続けます。

Skills側は5秒と30秒の既定値があるのに対し、Plugins側は無期限です。Skills用に決めた値をPluginsの設定へ移すときは、この差に注意が要ります。

Agent SDKのミッドセッション再読み込みで効くのはINSTALL側

CLAUDE_CODE_SYNC_SKILLS_INSTALL_TIMEOUT_MSが対象にするのは、env-varsのリファレンスが「Agent SDK上に構築したアプリがセッションの途中でSkillsを再読み込みする」と説明する処理です。ターミナルでclaude.aiアカウントにログインしたセッションは、この変数を設定していなくても~/.claude/skills/synced/へSkillsをダウンロードし、約10分ごとに再同期します。

この再読み込みは、TypeScript版Agent SDKのQueryオブジェクトにあるreloadSkills()(v0.3.163以降)を呼んだときに走ります。ディスク上のSkillsを読み直し、セッション途中で追加・編集したSkillsを実行中のセッションで使えるようにするメソッドです。

syncedというフォルダ名は、この同期のために予約されています。v2.1.227より前はSkillsが~/.claude/skills/へ直接ダウンロードされていましたが、それ以降は~/.claude/skills/synced/が専用の置き場所です。

v2.1.273より前は、ターミナルセッションでのSkillsダウンロードはCLAUDE_CODE_SYNC_SKILLSを設定した-p実行に限られていました。現在は、claude.aiアカウントでログインしたセッションなら、この変数の有無にかかわらずバックグラウンドでの自動ダウンロードと定期再同期が動きます。CLAUDE_CODE_SYNC_SKILLSを設定する意味は、最初のクエリの前に一覧が揃っているかどうかを保証したい場面に絞られます。

同期されたSkillsはローカルのSkillsと扱いが違う

タイムアウトを調整する前に、同期されたSkillsが何を受け取り、何を受け取らないかも押さえておくと、挙動の食い違いを読み違えにくくなります。同期されたSkillsには、通常のターミナルセッションで次の3つの追加ルールがかかります。

  • 本文中の!コマンドを実行しない
  • @参照によるファイル添付をしない
  • ${CLAUDE_PROJECT_DIR}と${CLAUDE_SESSION_ID}のプレースホルダーを置換しない

いずれもClaudeにはそのまま文字列として渡ります。frontmatterのallowed-toolsは通常どおり権限フローに入り、descriptionなど表示用のテキストは制御文字が除去され、山括弧がエスケープされます。

もう一つ、同期は一方向です。~/.claude/skills/synced/の中のファイルを自分やClaudeが編集しても、変更はclaude.aiアカウントに保存されません。次の同期で上書きや削除が起きることもあるため、Skillを直すときはclaude.ai側で更新し、次の同期を待ちます。

過去のセッションで同期済みのSkillsはディスクに残り、同じアカウントで入った後のセッションで、claude.aiに届かなくても読み込まれます。同期状態は/skillsを開くと確かめられ、一覧ではclaude.ai syncの見出しの下に並びます。

同期そのものを止める設定もある

ユーザー設定のsyncClaudeAiSkillsをfalseにすると、Claude Codeはダウンロードを止めます。次の起動時に、すでに同期済みのSkillsは~/.claude/skills/.trash/へ移され、読み込まれなくなります。

{
  "syncClaudeAiSkills": false
}

この設定は、ユーザー設定・ローカル設定・管理設定のいずれにも置けます。組織側は、claude.aiでSkillsをオフにするか、管理設定に同じキーを置くことで、Skillsを有効にしたまま同期だけを止められます。同期を止めた環境では、2つのタイムアウト変数を設定しても待つ対象がありません。

対話セッションでは2つの変数を設定しても挙動が変わらない

通常のターミナルで対話的にclaudeを起動し、claude.aiアカウントでログインしている場合は、これらの変数を設定しなくても~/.claude/skills/synced/へのダウンロードと再同期がバックグラウンドで動きます。リファレンスの説明では、この同期が起動を遅らせることはなく、Claudeがダウンロードを待つのはSkillを呼び出したときだけです。

短い非対話の-p実行は、追加したばかりのSkillがダウンロードされる前に終わることがあり、その場合は次回以降のセッションで取得されます。CLAUDE_CODE_SYNC_SKILLSが役立つのは、この取りこぼしを避けたいCI・バッチ処理の局面です。

対話的な利用だけで-p実行もAgent SDKアプリもなければ、2つの変数を設定する意味はありません。

値を伸ばしても変わらないときの切り分け

手順

タイムアウトを伸ばしても症状が変わらないとき

  1. 1

    claude.aiアカウントで認証しているか

    /loginで保存したサインインを使わないセッションは同期されません。APIキーで認証している場合のほか、ANTHROPIC_AUTH_TOKEN・CLAUDE_CODE_OAUTH_TOKEN・apiKeyHelperで認証情報を渡すCI構成も該当します。

    bareモードのセッションや--safe-modeで起動したセッションも同期しません。管理設定がSkillsをプラグイン由来に限定している場合や、--setting-sourcesからuserを外した場合も同じです。セッション中に/loginした場合は、Claude Codeを再起動すると同期が始まります。

  2. 2

    フィーチャーフラグの取得が省かれていないか

    Claude Codeは、Anthropicからフィーチャーフラグを取得して一部の機能を有効にします。DISABLE_GROWTHBOOK・DISABLE_TELEMETRY・DO_NOT_TRACK・CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICのいずれかを設定したセッションでは、この取得が省かれます。Amazon BedrockやGoogle CloudのAgent Platformなどサードパーティ経由のセッション(ホスト側がCLAUDE_CODE_PROVIDER_MANAGED_BY_HOSTを設定していない場合)と、Claude apps gatewayのセッションも同じです。取得が省かれると、claude.aiアカウントのSkillsとPluginsをターミナルセッションへ同期する機能が使えません。

  3. 3

    syncClaudeAiSkillsがfalseになっていないか

    ユーザー設定・ローカル設定・管理設定のどこかでfalseにされていると、ダウンロード自体が止まっています。

  4. 4

    狙った局面と変数が合っているか

    セッション開始時の遅延ならWAIT_TIMEOUT_MS、Agent SDKのミッドセッション再読み込みならINSTALL_TIMEOUT_MSです。

CIとSDKアプリでの調整の向き

セッション開始時の待機は、-p実行の最初のクエリをブロックします。バッチ処理やCIパイプラインでは、この待ち時間が処理全体の所要時間にそのまま上乗せされます。起動を急ぎたい場面ならWAIT_TIMEOUT_MSを短く、最初のクエリでSkillsを確実に使いたい場面なら長くします。

Agent SDKアプリでSkillsの取りこぼしを避けたいなら、INSTALL_TIMEOUT_MSを長めにする選択肢があります。2つを同じ値に揃えると、片方の局面では過剰に待ち、もう片方では足りないという組み合わせになりやすいため、局面ごとに別の値を置きます。

Skillsがそもそも見つからない症状は、タイムアウトとは別の問題です。Skillsが検出されないときの切り分けで先に原因を絞るのが手戻りの少ない順序で、SDK経由の扱い全般はAgent SDK経由のSkillsにあります。

Cowork・クラウドセッションはローカルのSkillsを読まない

Coworkセッションとクラウドセッション(routinesを含む)は、手元の~/.claude/skills/を読みません。どちらもclaude.aiアカウントで有効にしたSkillsをセッション開始時に同期して使い、クラウドセッションは加えて、クローンしたリポジトリの.claude/skills/にコミットされたプロジェクトSkillsも読み込みます。

同期されたSkillsの名前は、他のコマンドと衝突しないかぎり短い名前で呼べます。衝突したときは/anthropic-skills:<name>の完全名でだけ動き、anthropic-skillsは同期用に予約された名前空間です。ローカルにdeploy、同期側にもdeployがあれば、/deployはローカル側、/anthropic-skills:deployが同期側を動かします。

まとめ

CIで最初に決める値はWAIT_TIMEOUT_MSで、INSTALL_TIMEOUT_MSが効くのはreloadSkills()を呼ぶSDKアプリだけです。Plugins側には既定のタイムアウトがないため、同期インストールを待たせるなら上限を別に置きます。

この記事を共有:XはてブLinkedIn