コンテンツにスキップ

.vibe.toml

.vibe.tomlファイルには、通常gitにコミットされてチームで共有される設定が含まれます。

元リポジトリからWorktreeへ個別のファイルをコピー:

[copy]
files = [".env", "config.json"]

files配列はglobパターンに対応しており、柔軟なファイル選択が可能です:

[copy]
files = [
"*.env", # ルートディレクトリの全.envファイル
"**/*.json", # 全JSONファイル(再帰的)
"config/*.txt", # config/内の全.txtファイル
".env.production" # 厳密なパスも引き続き利用可能
]

サポートされるパターン:

パターン 説明
* /以外の任意の文字にマッチ
** /を含む任意の文字にマッチ(再帰的)
? 任意の1文字にマッチ
[abc] ブラケット内の任意の文字にマッチ

files_prependfiles_append(およびdirscopy.symlink[hooks]の全配列に対応する_prepend / _append)は、.vibe.local.tomlだけでなく.vibe.toml自身でも有効です。単一ファイル内での実効値はprepend + フィールド + appendになります:

[copy]
files = [".env"]
files_append = [".env.local"]
# 実効値: [".env", ".env.local"]

2つのファイル間でこれらのフィールドがどう作用するかは.vibe.local.tomlを参照してください。

ディレクトリ全体を再帰的にコピー:

[copy]
dirs = [
"node_modules", # 厳密なディレクトリパス
".cache", # 隠しディレクトリ
"packages/*" # 複数ディレクトリにマッチするGlobパターン
]
Section titled “共有ディレクトリ(symlink) ”

ディレクトリをワークツリーごとにコピーする代わりに、オリジンリポジトリ側の ディレクトリへシンボリックリンクを張って共有できます:

[copy]
dirs = ["node_modules"]
symlink = [".cache", ".turbo"]

理由: APFS/Btrfs/XFS では Copy-on-Write クローンにより dirs は高速ですが、 reflink 非対応のファイルシステム(および Windows)では巨大な依存関係やキャッシュ ツリーの完全コピーは遅く、ディスクを浪費します。そもそもワークツリーごとの分離が 不要なディレクトリもあり、ビルドキャッシュやダウンロードキャッシュは共有した方が 望ましい場合もあります。

ルール:

  • エントリはリポジトリルートからの厳密なディレクトリパスです。Glob パターンは サポートされません(シンボリックリンクは共有する 1 つのディレクトリを指すため)。
  • 実際にリンクが作成された symlink エントリは、同じパスを含む他のあらゆる コピー元より優先されます。files/dirs エントリはもちろん、untrackedmodified で拾われたファイルも同様です。そのパスはコピーではなくリンク されます。この判定は glob 展開のに行われるため、symlink = [".cache"]dirs = [".*"] を併用しても .cache はリンクされ、他のマッチのみがコピー されます。共有ディレクトリの配下のパス(およびその親)も除外されるため、 リンクを経由してオリジンリポジトリへコピーが書き込まれることはありません。 大文字小文字を区別しないファイルシステム(APFS、NTFS)では .Cache.cache は同一のディレクトリエントリなので、除外判定も大文字小文字を無視します。
  • ターゲットはオリジンリポジトリ内に存在し、その内部に収まっている必要があります。 ターゲットが存在しない、リポジトリ外へ脱出する、OS がリンク作成を拒否する (Developer Mode 無効の Windows)場合は警告を出して vibe start は継続します ——ワークツリーは引き続き使用できます。この場合リンクは作られていないため、 同じパスを指す files/dirs エントリは通常どおりコピーされます。
  • ワークツリー内の同じパスに実体のファイルやディレクトリがある場合は置き換え ません。古いシンボリックリンクのみ張り直します。
  • vibe clean はリンクを削除しますが、リンク先のディレクトリは削除しません。

ディレクトリコピーの並列実行数を制御できます:

[copy]
concurrency = 8
  • デフォルト: 4
  • 範囲: 1 から 32
  • 高速なストレージ(NVMe、SSD)を持つシステムでは値を大きくするとコピーが高速化する場合があります
  • 値を小さくするとシステムリソースの使用量が減少します

環境変数によるオーバーライド:

Terminal window
VIBE_COPY_CONCURRENCY=16 vibe start feat/my-feature

環境変数は設定ファイルの値より優先されます。

コピーパフォーマンスの最適化 v0.4.0+

Section titled “コピーパフォーマンスの最適化 ”

vibeはシステムに応じて最適なコピー戦略を自動選択します:

戦略 使用条件 プラットフォーム
Clone (CoW) APFSでのディレクトリコピー macOS
Clone (reflink) Btrfs/XFSでのディレクトリコピー Linux
rsync cloneが利用できない場合のディレクトリコピー macOS/Linux
robocopy (/MT) ディレクトリコピー Windows
Standard ファイルコピー、またはフォールバック 全て

仕組み:

  • ファイルコピー: 単一ファイルの最高パフォーマンスのため、常にネイティブのcopyFile()を使用
  • ディレクトリコピー: 利用可能な最速の方法を自動使用

メリット:

  • Copy-on-Writeは実際のデータではなくメタデータのみをコピーするため非常に高速
  • 設定不要 - 最適な戦略が自動検出されます
  • 自動フォールバックによりコピーは常に動作します

フック設定の詳細はフックを参照してください。

Worktree作成後、親リポジトリのpre_startフックの実行前に、指定した直接サブモジュールの信頼済み.vibe.tomlを読み込みます:

[submodules]
configs = ["libs/foo", "vendor/bar"]
  • デフォルト: []
  • 各エントリは.gitmodules内の直接サブモジュールpathと完全一致する必要があります
  • 新しいWorktree内でgit submodule update --init -- <paths>を実行します
  • 各サブモジュールの.vibe.toml / .vibe.local.tomlは、そのサブモジュール自身のtrust entryで読み込まれます
  • サブモジュール設定内のフックとcopyルールは、サブモジュールルート基準で実行されます
  • --no-hooksはサブモジュールのフックをスキップしますが、サブモジュール初期化はスキップしません
  • --no-copyはサブモジュールのcopyルールをスキップします
  • サブモジュール更新、trust、path検証、setupのいずれかに失敗するとvibe startは中断され、作成済みWorktreeは調査用に残ります

vibe listにSUMMARY列を追加し、自分で用意したコマンドでその内容を埋めます。

[summary]
command = "./examples/summary/last-commit.sh"
timeout_seconds = 30
  • command — シェルのコマンドライン。これが設定されている場合にのみ列が表示されます
  • timeout_seconds — コマンドが強制終了されるまでの実行可能時間。既定値: 30範囲: 13600

列はcommandが設定されていれば必ず表示されます。コマンドが特定のWorktreeについて回答しなかった場合、そのセルは空欄になります。

コマンドは**vibe listごとに1回**、メインWorktreeで実行され、対象Worktreeのバッチがstdinに渡されます。

{
"worktrees": [
{
"name": "feat/login",
"path": "/abs/path/to/wt",
"base": "develop",
"head": "0f1e2d3c…"
}
]
}

namepathは常に文字列です。baseheadは不明な場合nullになります。ここに現れるのは、サマリーがまだキャッシュされていないWorktreeだけです。

コマンドはstdoutに、nameをサマリー文字列へ対応付けるJSONオブジェクトを出力しなければなりません。

{ "feat/login": "ログインフォームを追加" }

コマンドが省略した名前にはサマリーが付かず、キャッシュもされないため、次回の実行で再び問い合わせられます。

Worktreeごとではなくバッチで1回: 実用的なサマリーコマンドはLLM呼び出しやリポジトリ全体への問い合わせであり、N回の呼び出しはN倍のレイテンシを要します。1回の呼び出しであれば、コマンドは全体を見比べたうえで回答することもできます。

名前が重複するWorktreeは除外されます: 回答はnameをキーとしますが、detached HEADのWorktreeは2つがディレクトリのbasenameを共有しうるためです。バッチ内に重複がある場合、該当Worktreeはリクエストから完全に除外されます(--verboseで報告)。サマリーが欠けるほうが、誤った行に表示されるより安全だからです。

コマンドのstdoutは信頼できない入力として扱われ、保存・表示の前に必ず境界が課されます。

制限 挙動
stdout 1 MiB 読み取りが上限で打ち切られ、長すぎる回答は拒否される
stderr 64 KiB 読み取りが上限で打ち切られる(引用は先頭1行のみ)
Worktree 1件あたり4エントリ リクエストに対して過大な回答は拒否される
文字列値のJSONオブジェクト 配列・数値・入れ子オブジェクトは契約違反
先頭1行のみ 複数行のサマリーは最初の改行で切り詰められる
500文字 それより長いテキストは付きで切り詰められる
端末制御文字 ブランチ名と同様に、表示前に無害化される

コマンドが非0で終了した場合、起動できなかった場合、タイムアウトした場合、契約に反する出力をした場合、vibe list警告を出したうえで処理を継続します。以前キャッシュされたサマリーがあれば、空欄ではなくそれが表示されます。多少古い回答でも、何もないよりは情報量があるためです。--jsonモードではペイロードをパース可能に保つため、警告は抑制されます。

サマリーはリポジトリごとに$XDG_CACHE_HOME/vibe/summaries/XDG_CACHE_HOMEが未設定または不正な場合は$HOME/.cache/vibe/summaries/)にキャッシュされます。変更のないリポジトリで2回目のvibe listを実行した場合、コマンドは一切実行されません

キャッシュされたサマリーが無効化されるのは次の場合です。

  • WorktreeのHEADが変わったとき(新規コミット、チェックアウト)
  • Worktreeの未コミット変更が変わったとき(git statusの報告内容が変化)
  • Worktreeのブランチ名が変わったとき(vibe rename
  • Worktreeのbaseが変わったとき(git branch --set-upstream-to
  • [summary] command自体が変わったとき — この場合はエントリが破棄されます。古いコマンドが生成したサマリーは、新しいコマンドの意味について何も語らないためです

timeout_secondsは無効化の対象ではありません。待ち時間を変えるだけで、回答の内容は変えないためです。存在しなくなったWorktreeのエントリは実行のたびに削除され、キャッシュファイルが壊れていたり読めなかったりする場合は単に再生成されます。

すぐ使えるスクリプトがexamples/summary/にあります(Unix向け。各ファイルの冒頭に使い方と[summary]の設定断片が記載されています)。

スクリプト 列に表示される内容 必要なもの
last-commit.sh 各Worktreeの最新コミットのsubject jqgit
note-file.sh 各Worktreeの.vibe/note.txtの先頭1行 jq
claude.sh 各Worktreeが何をしているかのLLMによる説明 jqgitclaude

外部スクリプトを使用してWorktreeディレクトリパスをカスタマイズできます。

Worktreeパスを出力するスクリプトを指定:

[worktree]
path_script = "~/.config/vibe/worktree-path.sh"

スクリプトは以下の環境変数を受け取ります:

環境変数 説明
VIBE_REPO_NAME リポジトリ名 my-project
VIBE_BRANCH_NAME ブランチ名 feat/new-feature
VIBE_SANITIZED_BRANCH サニタイズ済みブランチ名(/- feat-new-feature
VIBE_REPO_ROOT リポジトリルートパス /path/to/repo

スクリプト例:

~/.config/vibe/worktree-path.sh
#!/bin/bash
echo "${HOME}/worktrees/${VIBE_REPO_NAME}-${VIBE_SANITIZED_BRANCH}"
[copy]
files = [
".env",
".env.local",
"**/*.secret"
]
dirs = [
"node_modules",
".cache",
"vendor"
]
concurrency = 8
[hooks]
pre_start = ["echo 'Worktreeを準備中...'"]
post_start = [
"pnpm install",
"pnpm db:migrate",
"pnpm build"
]
pre_clean = ["git stash"]
post_clean = ["echo 'クリーンアップ完了'"]
[submodules]
configs = ["libs/foo"]
[summary]
command = "./examples/summary/last-commit.sh"
timeout_seconds = 30
[worktree]
path_script = "~/.config/vibe/worktree-path.sh"