Open10

aqua で ripgrep をインストールすると Claude Code でファイル名の補完が効かない件の調査

Shunsuke SuzukiShunsuke Suzuki

https://zenn.dev/budougumi617/articles/claudecode-failed-autocomplete-with-aqaua-rg

再現できた

ripgrep を aqua でインストール

  • ripgrep は AQUA_GLOBAL_CONFIG でインストール
$ aqua -v
aqua version 2.51.2

$ which rg
/Users/shunsukesuzuki/.local/share/aquaproj-aqua/bin/rg

$ aqua which -v rg     
14.1.1

$ rg --version
ripgrep 14.1.1 (rev 4649aa9700)

features:+pcre2
simd(compile):+NEON
simd(runtime):+NEON

PCRE2 10.43 is available (JIT is available)

補完が効かない

  • ~/.claude/settings.json はなし
  • claude を terminal で起動して @ を入力しても補完が効かない

USE_BUILTIN_RIPGREP": 1 を設定すると補完が効く

  • ~/.claude/settings.json を作って "USE_BUILTIN_RIPGREP": 1 を設定すると補完が効く

aqua を使わずに ripgrep をインストールしてみる

brew install ripgrep
rm ~/.local/share/aquaproj-aqua/bin/rg
$ which rg
/opt/homebrew/bin/rg

$ rg --version
ripgrep 14.1.1

features:+pcre2
simd(compile):+NEON
simd(runtime):+NEON

PCRE2 10.43 is available (JIT is available)

USE_BUILTIN_RIPGREP": 1 を設定しなくても補完が効いた。

AQUA_GLOBAL_CONFIG を設定してみるも効果なし

~/.claude/settings.json
    "env": {
        "AQUA_GLOBAL_CONFIG": "/Users/shunsukesuzuki/repos/src/github.com/aquaproj/aqua-registry/aqua-all.yaml"
    }
Shunsuke SuzukiShunsuke Suzuki

恐らく claude-code は OSS ではないのでコードを読んで調べたりはできない。
https://github.com/anthropics/claude-code
問い合わせてみるのはあり。

Homebrew で ripgrep をインストールした場合、 rg はシンボリックリンクであるが、それでも動くので、 symbolic link なのが原因ではない。

$ ls -lh /opt/homebrew/bin/rg
lrwxr-xr-x 1 shunsukesuzuki admin 31  6  8 10:38 /opt/homebrew/bin/rg -> ../Cellar/ripgrep/14.1.1/bin/rg

ただ aqua の場合 aqua-proxy と aqua を介して ripgrep が実行されるのでそれが関係しているかも。
エラーでも吐いてくれたら手がかりになるんだけど、なんのエラーも吐かれないので調査が難しい。

Shunsuke SuzukiShunsuke Suzuki

debug mode で起動したが何も変わらない

claude -d

allow に追加したけど効果なし

    "permissions": {
        "allow": [
            "Read(~/.zshrc)",
            "Bash(aqua:*)",
            "Bash(aqua-proxy:*)"
        ],

$(aqua root-dir)/bin/rg を rg への直リンクに変えたら成功 (それはそう)

p=$(which rg)
rm "$p"
ln -s "$(aqua which rg)" "$p"
Shunsuke SuzukiShunsuke Suzuki

shell script なら動いた

~/bin/rg
#!/usr/bin/env bash

/Users/shunsukesuzuki/.local/share/aquaproj-aqua/pkgs/github_release/github.com/BurntSushi/ripgrep/14.1.1/ripgrep-14.1.1-aarch64-apple-darwin.tar.gz/ripgrep-14.1.1-aarch64-apple-darwin/rg "$@"

aqua exec しても動いた。

#!/usr/bin/env bash

aqua exec -- rg "$@"
Shunsuke SuzukiShunsuke Suzuki

aqua の場合 $(aqua root-dir)/bin 配下のバイナリは aqua-proxy へのシンボリックリンク。

$ ls -lh ~/.local/share/aquaproj-aqua/bin/rg
lrwxr-xr-x 1 shunsukesuzuki staff 13  6  8 11:19 /Users/shunsukesuzuki/.local/share/aquaproj-aqua/bin/rg -> ../aqua-proxy

なので symbolic link を解決して aqua-proxy を実行してもそれは動かない。
もしかするとこれが原因かもしれないが、ただ Claude Code がどのように rg を実行しているかよくわかってない。

Claude Code は Node.js で実装されていて、読むことができるが、難読化されている。

code "$(which claude)"

なんか findActualExecutable という関数で rg のパスを取得しているように見える。この際に symbolic link を解決していると動かないはず。

let{cmd:A}=tLA.findActualExecutable("rg",[])

そうだとすると aqua 側で問題を解決するのは難しい。
hard link にすると解決する??

Shunsuke SuzukiShunsuke Suzuki

正直言うと "USE_BUILTIN_RIPGREP": 1 すれば特に困らない

    "env": {
        "USE_BUILTIN_RIPGREP": 1
    }

これを設定すれば別に aqua で ripgrep を管理していても補完は効くしコンフリクトしたりしない。
Claude Code 以外では aqua で管理した ripgrep が使える。
USE_BUILTIN_RIPGREP は Claude Code の builtin の ripgrep を使うはずで、ユーザーが明示的にインストールする必要もない。

Shunsuke SuzukiShunsuke Suzuki

これの続き

p=$(which rg)
rm "$p"
ln "$(aqua root-dir)/aqua-proxy" "$p" # -s はいらない。 hard link を作る

選択肢:

とりあえず registry 側で ripgrep を hardlink にすれば問題は解決する気がする。

Shunsuke SuzukiShunsuke Suzuki

全部 hardlink にする で良い気がしている。
Claude Code に限らず一部のツールは依存するコマンドのパスを symbolic link を解決した状態で取得してから実行する。
その場合、現状 aqua でインストールしたツールは動かない。
なぜなら aqua-proxy は実行時のコマンド名 ($0)で対象のコマンド名を取得するから。
hardlink にすればこの問題は起こらなくなる。

hardlink にした場合のデメリットは今回の場合特にない気がしている。
ファイルシステムをまたぐことは基本ないし ($(aqua root-dir) 内でまたぐのはやめてくださいで済む話) 、 directory にリンクすることはないので困らない。

いや、と思ったけど aqua-proxy が更新されたときに hardlink だとそれが反映されないので困るな。
aqua-proxy が更新されたタイミングで bin 配下のリンクを全部作り直す必要がある。
それに symlink じゃないと現在の aqua-proxy のバージョンがわからないので作り直すべきかの判断が難しい。

bin 配下のファイルの作り直しは一瞬そのコマンドが実行不可能になるのもちょっと嫌。
とはいえ一瞬なので許容範囲な気はする。