mcpField
I
islandiguana

islandiguana

github.com/gkwa生産性080 回インストール2 日前に更新
リポジトリ

islandiguana について

islandiguanaは、Obsidian Vaultを検索・編集するコマンドラインツールです。yq式でMarkdownファイルのYAML front matterを絞り込み、標準入力のファイルパスやripgrepの検索結果も扱えます。

主な機能

  1. 01front matter式による絞り込み
  2. 02Markdownファイルの再帰検索
  3. 03標準入力からパスを取得
  4. 04front matterのインプレース編集
  5. 05null区切り出力とキャッシュ制御

活用シーン

  1. 01タグやステータスでノートを検索
  2. 02ripgrepの検索結果を絞り込み
  3. 03メタデータを一括更新・削除

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/gkwa/volcanicviper --skill islandiguana

インストール後、Claude Code で/islandiguanaを入力して読み込まれたか確認します。

同梱ファイルtile.json

詳細

islandiguana で Obsidian Vault を検索する

islandiguana は yq の式構文を使い、Markdown ファイルを YAML フロントマターに基づいて再帰的に検索します。

バイナリ:/Users/mtm/go/bin/islandiguana

Vault のパス:/Users/mtm/Documents/Obsidian Vault

基本的な使い方
# find files where tags include "python"
islandiguana "/Users/mtm/Documents/Obsidian Vault" '.tags[] == "python"'

# find files where status is draft
islandiguana "/Users/mtm/Documents/Obsidian Vault" '.status == "draft"'

# find files that have a specific front matter key (any value)
islandiguana "/Users/mtm/Documents/Obsidian Vault" 'has("filetype")'

# find files with no author set
islandiguana "/Users/mtm/Documents/Obsidian Vault" '.author == null'

# find markdown files with no front matter (or front matter but no tags)
islandiguana "/Users/mtm/Documents/Obsidian Vault" '(.tags // []) | length == 0'

# find files whose title matches a regex (case-insensitive)
islandiguana "/Users/mtm/Documents/Obsidian Vault" '.title | test("(?i)kubernetes")'

# find files tagged with either "python" or "ruby"
islandiguana "/Users/mtm/Documents/Obsidian Vault" '(.tags[] == "python") or (.tags[] == "ruby")'

# find files with a priority field greater than 3
islandiguana "/Users/mtm/Documents/Obsidian Vault" '.priority > 3'

# limit search depth
islandiguana --max-depth 1 "/Users/mtm/Documents/Obsidian Vault" '.tags[] == "python"'
ripgrep との組み合わせ(stdin モード)

ディレクトリ引数を指定しない場合、islandiguana は stdin からファイルパスを読み込みます。 パイプされた stdin とともにディレクトリ引数も指定すると、両方の入力元が統合され、重複が除去されます。

# filter by front matter among files matching a text search
rg -l "Expresso" "/Users/mtm/Documents/Obsidian Vault" | islandiguana '.tags[] == "coffee"'

# combine ripgrep results with a full vault walk (merged, deduplicated)
rg -l "Expresso" "/Users/mtm/Documents/Obsidian Vault" --null | islandiguana "/Users/mtm/Documents/Obsidian Vault" --null-input '.tags[] == "coffee"'
フロントマターをその場で変更する

--mutate と yq 式を使って、該当するファイルを編集します。

# delete a front matter key from matched files
islandiguana "/Users/mtm/Documents/Obsidian Vault" '.filetype == "product"' --mutate 'del(.filetype)'

# update a field on matched files
islandiguana "/Users/mtm/Documents/Obsidian Vault" '.status == "draft"' --mutate '.status = "published"'

# append a tag idempotently (creates frontmatter if the file has none)
islandiguana "/Users/mtm/Documents/Obsidian Vault" --mutate '.tags = ((.tags // []) + ["mytag"] | unique)'

# tag all notes mentioning a term — stdin only (ripgrep finds files, islandiguana tags them)
rg -l 'some-term' "/Users/mtm/Documents/Obsidian Vault" --null | islandiguana --null-input --mutate '.tags = ((.tags // []) + ["some-term"] | unique)'
出力オプション
# null-delimited output for safe piping to xargs
islandiguana -0 "/Users/mtm/Documents/Obsidian Vault" '.tags[] == "python"' | xargs -0 grep -l TODO

# skip the disk cache (always parse fresh)
islandiguana --no-cache "/Users/mtm/Documents/Obsidian Vault" '.priority > 3'
ワークフロー

Vault の内容に関する質問に答えるには、Bash 経由で islandiguana を実行し、その後、返されたファイルを Read します。

Vault のパスにはスペースが含まれるため、必ず引用符で囲んでください。

クエリには yq の式構文を使います。 式は常に最後の位置引数です(省略可能なディレクトリの後)。

ripgrep との組み合わせ

トピックを検索するときは、自由形式のテキスト検索に ripgrep を使い、フロントマターのタグフィルターに islandiguana を組み合わせてください。これにより、タグを絞り込みレイヤーとして利用できます。

ノートでは、トピックに軽く触れているだけの場合もあります。たとえば、ある製品のノートに ## [[Chef's Store]] セクションが含まれていると、テキストのみの検索結果にノイズが混入します。タグはノートの目的を示すため、タグで絞り込めばそのノイズを取り除けます。

テキスト内で何かに言及しているものの、product タグが付いていないノートを検索するには、次のようにします。

rg -l -i "search term" "/Users/mtm/Documents/Obsidian Vault" | islandiguana '(.tags // []) | map(. == "product") | any | not'

まず、タグがない場合は空の配列に置き換えてください。単独の not (.tags[] == "product") は、タグが null または存在しないファイルで失敗します。そのため、タグを除外するときは常に (.tags // []) | map | any | not のイディオムを使ってください。

コメント