Claude Code

VS Code の Chronicle 機能が結構便利だった

TL;DR — Chronicle は Copilot Chat のチャット履歴をローカルで記録・分析する実験的機能。/chronicle:standup でその日の作業サマリー、/chronicle:tips で自分の使い方フィードバックが出せる。これがなかなか良い。Claude にはこういう公式機能はないけど、自宅では QMD で履歴検索は実現してる。

職場で VS Code を使っていて、ふと試してみた機能の話。

Chronicle とは

VS Code v1.118 で実験的に追加された GitHub Copilot Chat の機能。Copilot とのやり取り、編集したファイル、参照した PR や Issue あたりをローカルの SQLite データベースに記録しておいて、あとから振り返ったり分析したりできる。

で、早速使ってみた。

有効化は github.copilot.chat.localIndex.enabledtrue にするだけ。

GUI の設定じゃないのはまだプレビュー段階だからかな。

使えるコマンドは主に 3 つ。

/chronicle:standup 過去 24 時間の作業内容をまとめてくれる。「このブランチでこのファイル触って、この PR を参照した」みたいな感じで出てくる。朝会の準備が秒で終わるらしい(使ったことはない)。

/chronicle:tips 7 日間の使い方を分析して、「お前こういうプロンプトの書き方してるけど、こうしたほうが良くね?」みたいなフィードバックをくれる。自分の癖を指摘してもらえるのがおもしろいし、フィードバックがまあまあためになる。これはよき。

/chronicle [query] 自然言語で過去の履歴を検索できる。「先週やってたあれ、なんだっけ」が出てくる。

試してよかったのは tips

「同じような質問を繰り返してる」とか「毎回コンテキストを初めから説明してる」みたいな自分のパターンを指摘してくれる。ほう、わかってんじゃねーかこいつ…

Copilot との対話の仕方に改善余地があると気づかせてくれるのが嬉しい。

やるじゃん。

Claude だと?

で、家で使ってる Claude Code でこういう機能があるかというと、公式にはない。 そこんとこどうなんよ?と Claude さんに聞いてみた結果が以下。

QMD の MCP サーバーをやめて Bash で直接叩くようにした

TL;DR — QMD の MCP サーバーが重すぎたので、プラグインを削除して qmd query --no-rerank を Bash で直接呼ぶ運用に切り替えた。リランカーなしでも BM25 + ベクトル検索の組み合わせで十分実用的。

以前の記事で QMD を MCP サーバーとして導入した話を書いた。

その後、重さが気になり過ぎて運用を見直した話。

いや、本気で重かったのよ。全然結果が返ってこない。

なにこれとか思って調べたら GPU なしだとこんなもんだろうとのこと。

そうですかぁ…

今の運用

ということでどうしたかというと、Claude さんが過去セッションを検索するときは、MCP ツールではなく Bash コマンドを直接叩くようになった。

qmd query --no-rerank "調べたいキーワード"

CLAUDE.md に「QMD は qmd query --no-rerank で使う」と書いてあるので、Claude さんが自動でこの形式で呼ぶ。settings.jsonpermissions.allow には Bash(qmd *) を追加済み。

なぜ重かったか

以下 Claude さんの解説。

QMD は内部で 2 つのローカル ML モデルを動かしている。

モデルサイズ用途
embeddinggemma-300M-Q8_0.gguf314 MBベクトル埋め込み生成
Qwen3-Reranker-0.6B-Q8_0.gguf610 MB検索結果のリランキング

自分の環境は専用 GPU がなく CPU 推論になるので、2 モデル合計で 924 MB がオンメモリに乗る。MCP サーバーとして常駐させていると、起動のたびにこれをロードして複数プロセスを spawn する。qmd query(MCP が使う推奨コマンド)はさらにリランキングまで走らせるので、検索 1 回に数分かかることもあった。

NanoClaw のアップデートで RTK が pnpm test を素通りしてた話

TL;DR — RTK の rewrite は pnpm run build を圧縮するが pnpm test(実体は vitest run)は素通り。加えて /update-nanoclaw/update-skills を同一コンテキストで自動呼び出ししていた。SKILL.md を2行変えて解決。

NanoClaw の大型アップデート来ましたね。かなり中身が変わっていてローカルでのマージにものすごく時間がかかりました。最終的には、

「もう俺の作ったスキルさえ無事なら後はどうでもいいから全部上書きしちゃって!」

と雑な投げ方をしてアップデートをしてもらいました。

無事(一部無事じゃなかったけど git のログから復旧した)終わったんだけど、後日再度 /update-nanoclaw を実行した時の話です。

/update-nanoclaw を実行したら5時間制限の40%くらいを1回で使い切ってしまった。なにこれ、と思って Claude さんに調べてもらった。

以前 RTK を入れた記事を書いたとき、「効果はこれからに期待」と書いたんだけど、うまく行かなかったようで…

以下は、Claude さんに解説してもらった文章です。

RTK の仕組みをおさらい

RTK は Claude Code の PreToolUse hook として動く。Bash ツールが呼ばれるたびに rtk hook claude が起動し、rtk rewrite "<コマンド>" でコマンドを書き換えられるか確認する。

  • 書き換えできる(exit 3)→ rtk <subcommand> が代わりに実行され、出力が圧縮される
  • 書き換えできない(exit 1)→ 元のコマンドがそのまま実行される(RTK はノータッチ)

何が素通りしていたか

rtk rewrite "pnpm run build"
# → rtk pnpm run build(exit 3: 書き換え成功)

rtk rewrite "pnpm test"
# → (何も出力なし、exit 1: 書き換えなし)

pnpm run build は圧縮される。でも pnpm test は exit 1 で素通り。

Claude Code のセッション履歴をベクトル検索できる QMD を入れた

TL;DR — QMD は BM25 + ベクトル検索でローカル Markdown を横断検索できる MCP ツール。Stop hook で Claude Code セッション終了時に自動インデックス化することで、複数リポジトリのセッション履歴を横断検索できる。

nanoclaw(Claude Code の fork)をアップデートしているとき、内部で QMD が使われているのを見かけた。調べてみたら「お、これ良さそう」となったので入れた。

QMD とは

QMD は、ローカルの Markdown ファイルを対象に検索エンジンを立てる CLI ツール兼 MCP サーバー。単純な grep と違うのは、BM25(キーワード検索)とベクトル検索を組み合わせて意味的に近いドキュメントを引けること。検索用の埋め込みモデルもローカルで動く(GPU がなくても動作する、が後ほど書くけど CPU だとクソ重い処理が一回だけある)。

インストール

本体は以下のように、npm でインストール。

npm install -g @tobilu/qmd

Claude Code はプラグインとして追加する。

claude plugin marketplace add tobi/qmd
claude plugin install qmd@qmd

今回やりたかったことと設定

自分は複数のリポジトリで Claude Code を使っていて、技術的な会話もリポジトリをまたいでいる。そこで、QMD のコレクションに全リポジトリのセッション Markdown を入れておけば、「あのリポジトリでやった話、なんだったっけ」を後から引ける。

同じようなことを実現できるものとして、claude-mem がある。

そもそもこれ入れればいいじゃんって話もあるけど、なんか分からんけど直感で QMD いいかもって思ってしまったので仕方ない。直感で突き進みます。

まずは、Claude のセッションをマークダウンに変換するスクリプト convert-sessions.js を用意して、~/.claude/hooks 配下に配置。

Claude Code の git push がまた壊れた:sandbox と credential helper のサブプロセス問題

TL;DR — Claude Code の sandbox が GNOME keyring への D-Bus アクセスをブロックするため git push が失敗する。gh auth login --insecure-storage でトークンをファイルに保存すれば回避したがこれでいいのか若干不安。

以前も同じ目に遭った。

そしてまた再現。今回はrtk 導入の記事をプッシュしようとしたら同じ目にあったよ。

またかよ、おい…

とりあえず Claude さんと一緒に解決したけど、これでいいのか正直わからん。

というか、公式で sandbox 関連の特集記事とか出してくれないかな。

以下、Claude さんの解説と俺の感想です。

TL;DR

内容
根本原因gh auth git-credentialgit push のサブプロセス)が GNOME keyring に D-Bus 経由でアクセスできない
なぜsandbox が Unix ソケットをブロックしている
excludedCommands: ["gh *"] が効かない理由Claude Code が直接呼ぶコマンドにしか効かず、サブプロセスには届かない
回避策gh auth login --insecure-storage でトークンをファイルに保存

何が起きたか

git push origin main を実行すると以下で失敗する。

fatal: could not read Username for 'https://github.com': No such device or address

まず excludedCommands"gh *" を追加してみたが効果なし。

Claude Code のトークンを節約する RTK を入れた

TL;DR — RTK(Rust Token Killer)は Claude Code の bash 出力をフィルタして LLM へのトークン消費を削減するプロキシ。rtk init -g だけで自動設定される。

ちょっと仕事が忙しくて疲弊してたんだけど、気分転換に前から気になってたツールを入れてみた。

効果はこれからに期待。

RTK とは

RTK (Rust Token Killer) は、Claude Code などの AI アシスタントが bash コマンドを実行したときの出力をフィルタして、LLM に渡るトークン数を削減する CLI プロキシ。git logls の出力って、そのまま渡すと無駄に長いことが多い。RTK はそれをコンパクトにまとめてから Claude のコンテキストに入れてくれる。公称で 60〜90% の節約効果があるらしい。

インストール

brew install rtk
rtk init -g

rtk init -g を叩くだけで、以下が自動設定される:

  • ~/.claude/RTK.md の生成(Claude Code に RTK の使い方を教えるファイル)
  • ~/.claude/settings.json への hook 追記(PreToolUse/Bashrtk hook claude が入る)

これ以降、Claude Code が bash を呼ぶたびに透過的に RTK を通るようになる。ユーザー側で何か変えなくていい。

dotfiles に埋まってた GNOME 拡張を GitHub リポジトリに切り出した

TL;DR — dotfiles に埋まっていた GNOME Shell 拡張を独立リポジトリに切り出して GitHub で公開した。uuid を 拡張名@ドメイン 形式に変更し、インストール先ディレクトリ名も合わせる必要がある。

以前の記事で作った IME インジケーター拡張を、dotfiles から独立したリポジトリに切り出した。

背景:GNOME Extensions への公開は見送り

GNOME Extensions に登録しようかと思ったけど、ポリシーを Claude さんに確認してもらって、それを自分なりに解釈した結果、「AI で生成したコードはいいけど、自分で説明できないならリジェクトね」っていうことらしい(たぶん)。

「GNOME + fcitx5 + Mozc + 入力モードが視覚的にわからなくてつらい人」というターゲットの少なさも考えると、ひとまず GitHub に public リポジトリを作ることにした。
そんな見る人もいないからいいよね。俺得だし。

やったこと

リポジトリ自体は空で作ってあったので、ファイルをコピーして移植する作業を Claude Code に任せた。

uuid と metadata.json の整備

dotfiles 版は ime-indicator@local という uuid を使っていた。GNOME 拡張の uuid は慣習的に 拡張名@ドメイン の形式をとるので、[email protected] に変更し、あわせて GitHub リポジトリの URL も追記。

{
  // Before
  "uuid": "ime-indicator@local"
}
{
  // After
  "uuid": "[email protected]",
  "url": "https://github.com/devmasa/gnome-ime-indicator"
}

uuid を変えるとインストール先のディレクトリ名も変わるので、既存環境では入れ直しが必要。まあ自分しか使ってないので問題なし。

Claude Code の git push が壊れた日:バイナリ解析よりリリースノートを先に読め

TL;DR — Claude Code で git push が v2.1.91 のアップデートで壊れた原因は excludedCommands のマッチング修正。"git""git *" に変えれば直る。

Claude Code で git push できなくなった。原因調査の過程を Claude とのやりとりで再現する。結論を先に言うと、リリースノートを最初に見ていれば 5 分で終わった話だった。

TL;DR

根本原因: v2.1.91 で excludedCommands のマッチング挙動が修正された

バージョンexcludedCommands: ["git"] の動作
v2.1.90 以前バグで git push origin main にもマッチ → sandbox 完全 bypass
v2.1.91 以降仕様通りに修正。"git" は bare git のみにマッチ → sandbox 適用 → 認証情報へのアクセスがブロックされ失敗

修正した設定:

{
  // Before
  "excludedCommands": ["git"]
}
{
  // After
  "excludedCommands": ["git *"]
}

今回は俺と Claude さんの会話を再現してます。一部省略。

VSCode Copilot Chat と Claude Code、bash の扱いが違う

TL;DR — oh-my-posh v28.1.1 以降は VSCode Shell Integration と競合してエージェントモードが固まる。.bashrc$TERM_PROGRAM=vscode の早期リターンを入れれば解決。Claude Code の PATH は .profile 経由で解決している。

午前中、Copilot Chat のエージェントモードでコマンド実行したら止まるという事象が頻発した。.bashrc に仕掛け作って凌いだ。定時過ぎに Claude Code の仕組みを調べたらなんか知らんけど上手く動いてた、という一日の話。

午前:Copilot Chat のエージェントモードでコマンド実行すると以後進まない

VSCode の Copilot Chat をエージェントモードで使っていたら、コマンドを実行させるとそこで「Preparing」が点滅し続けてそこから進まなくなった。

なんだよこれと思って調べてみると、oh-my-posh が原因。oh-my-posh v28.1.1 以降で VSCode Shell Integration と競合するようになったらしく、エージェントが叩いた bash がそのまま固まる。

解決策として .bashrc に VSCode 向けの早期リターンを仕込んだ。$TERM_PROGRAM は VSCode が統合ターミナルを開くときにセットする変数で、WSL・ネイティブ Ubuntu どちらでも vscode になる。

# mise shims(全環境で必要)
eval "$(mise activate bash --shims)"

# VSCode 統合ターミナルはここで早期リターン
if [[ "$TERM_PROGRAM" == "vscode" ]]; then
  return
fi

# 以降はインタラクティブ専用(Tabby / GNOME Terminal など)
eval "$(oh-my-posh init bash ...)"
# ghq, fzf など...

これで Copilot Chat のエージェントモードは直った。さくさく進むようになった。でも午前の業務は溶けた。う○こですよ。