[[📒Articles]] > [[📒2025 Articles]] ![[2025-06-15.webp|cover-picture]] [[Claude Code]]を使って[[Agentic Coding]]してみたら、想定を遥かに上回る良い体験ができたので導入から実践的な開発完了までの記録を記してみました。 > [!note] > 機能が動作するかを確認する前にコードをレビューしていることから、[[Vibe Coding]]ではなく[[Agentic Coding]]という用語を使用しています。 ## 対象リポジトリ この手の話をすると ``` またテトリスやTODOリストを作った話ですか? ``` と思われそうなので、先に対象リポジトリを紹介します。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" /> <span class="link-card-v2-site-name">GitHub</span> </div> <div class="link-card-v2-title"> GitHub - tadashi-aikawa/obsidian-another-quick-switcher: This is an Obsidian plugin which is another choice of Quick switcher. </div> <div class="link-card-v2-content"> This is an Obsidian plugin which is another choice of Quick switcher. - tadashi-aikawa/obsidian-another-quick-sw ... </div> <img class="link-card-v2-image" src="https://opengraph.githubassets.com/60df2174a72c433e4748bf8cd8ede632f35472c98023ba6a7c9ff2d4d66fe266/tadashi-aikawa/obsidian-another-quick-switcher" /> <a href="https://github.com/tadashi-aikawa/obsidian-another-quick-switcher"></a> </div> [[🦉Another Quick Switcher]]。[[Obsidian]]の[[コミュニティプラグイン]]として公開しており、私のリポジトリでは2番目にスターが多いです。 #2025/06/15 時点でのデータは以下の通りです。 | 項目 | 値 | | -------------------------------- | ----- | | インストール数 (versionユニーク) | 89519 | | ダウンロード数 | 230K | | リリース回数 | 205 | | コミット数 | 866 | | issue総数 | 230 | | closeしたissue総数 | 191 | | ファイル数 | 70 | | 行数 | 15323 | 対応してもらったのは『[[Custom searches]]で入力されたクエリを引き継ぎ、[[Grep command]]を実行する』という機能です。 ![[20250615_14_51_51.mp4|frame]] *実装してもらったコマンドのデモ動画* もし私が対応していたら、おそらく30分から1時間くらい必要だったと思います。 ## なぜClaude Codeを試してみたのか? 順序は前後しますが、経緯の紹介です。これまでずっと私はアンチ[[Agentic Coding]]でした。そのため、[[Cursor]]や[[Cline]]、[[Roo Code]]、[[GitHub Copilot]]などの[[Agentic Coding]]記事を見ても **『[[OSS]]開発や仕事で実用するには至らないだろう』** と冷めた目で見ていました。 しかし、この2週間ほどで気が変わりました。**『今、[[Claude Code]]を始めなければ時代の変化に取り残されるのでは...』** と私の中の第六感が訴えてきたのです。 ### 観測範囲のエンジニアがこぞって利用し始めている 第六感とは言いましたが、根拠はあります。[[SNS]]で腕に覚えのあるエンジニアの方々が揃って **『[[Claude Code]]を取り入れている』** という事実を観測しています。以前から[[Agentic Coding]]に肯定的な方もいれば、[[Claude Code]]で[[Agentic Coding]]への評価が変わった方もいらっしゃいます。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://cdn.rebuild.fm/images/icon240.png" /> <span class="link-card-v2-site-name">Rebuild</span> </div> <div class="link-card-v2-title"> Rebuild: 408: Democratize Coding for $200 a Month (yuka) </div> <div class="link-card-v2-content"> Yuka Ohishi さんをゲストに迎えて、Google I/O, Android XR, MCP, Claude Code, Vibe Coding, WWDC などについて話しました。 ... </div> <img class="link-card-v2-image" src="https://cdn.rebuild.fm/images/icon240.png" /> <a href="https://rebuild.fm/408/"></a> </div> ![](https://www.youtube.com/watch?v=nir1IeOJTk8) <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://static.zenn.studio/images/logo-transparent.png" /> <span class="link-card-v2-site-name">Zenn</span> </div> <div class="link-card-v2-title"> Claude Code による技術的特異点を見届けろ </div> <img class="link-card-v2-image" src="https://res.cloudinary.com/zenn/image/upload/s--0gY0jgcX--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:Claude%2520Code%2520%25E3%2581%25AB%25E3%2582%2588%25E3%2582%258B%25E6%258A%2580%25E8%25A1%2593%25E7%259A%2584%25E7%2589%25B9%25E7%2595%25B0%25E7%2582%25B9%25E3%2582%2592%25E8%25A6%258B%25E5%25B1%258A%25E3%2581%2591%25E3%2582%258D%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:mizchi%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EtL0FPaDE0R2liclRHT052Z3d3ay1fNGxlcVk4TGNGSlNuX0FoWnpEWVlKaXJNcWc9czI1MC1j%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png" /> <a href="https://zenn.dev/mizchi/articles/claude-code-singularity-point"></a> </div> <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://syu-m-5151.hatenablog.com/icon/favicon" /> <span class="link-card-v2-site-name">じゃあ、おうちで学べる </span> </div> <div class="link-card-v2-title"> Claude Code を利用しようと思っているのでvimmer が住む村に帰ろうと思います。 - じゃあ、おうちで学べる </div> <div class="link-card-v2-content"> はじめに 前回、「NeovimをCursorのように進化させる - yetone/avante.nvim の導入」を書いた。あの記事では、まるで自分だけの剣を鍛え上げていくように、エディターと共に成長していくPDEの哲学につ ... </div> <img class="link-card-v2-image" src="https://ogimage.blog.st-hatena.com/8454420450094081900/6802418398452607898/1748669195" /> <a href="https://syu-m-5151.hatenablog.com/entry/2025/05/30/180912"></a> </div> ![](https://x.com/ryoppippi/status/1926280251996295532) 繰り返しますが、重要なことは **このタイミングで腕に覚えのある多くのエンジニアが[[Claude Code]]を取り入れて、[[Agentic Coding]]を試している** ということです。このビッグウェーブに乗らないわけにはいかないでしょう。 ### Vimmerからの評判が良さそう [[Claude Code]]は[[ターミナル]]で完結することもあり、[[Vimmer]]からの評判がすこぶる良いです。私も一時は[[VSCode]]に乗り換えるべきかを真剣に考えたこともありました。その結果、今後のことも考え、[[VSCode]]と[[Neovim]]の二刀流で生きていくことを決めました。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" /> <span class="link-card-v2-site-name">Minerva</span> </div> <div class="link-card-v2-title"> 📘目指せ二刀流! VSCodeをNeovim色にコーディネートしてみた </div> <div class="link-card-v2-content">VSCodeのNeovim風カスタマイズ、キーボード操作やUIのシンプル化、VSCode Neovim拡張の導入方法などを、NeovimちゃんとVSCodeちゃんが対話形式でお届けします。</div> <img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/%F0%9F%93%98Articles/attachments/2025-06-02.webp" /> <a data-href="📘目指せ二刀流! VSCodeをNeovim色にコーディネートしてみた" class="internal-link"></a> </div> %%[[📘目指せ二刀流! VSCodeをNeovim色にコーディネートしてみた]]%% <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" /> <span class="link-card-v2-site-name">Minerva</span> </div> <div class="link-card-v2-title"> 📘目指せ二刀流! VSCodeをNeovim色にコーディネートしてみた -後編- </div> <div class="link-card-v2-content">VSCodeをNeovim風にカスタマイズする方法を後編で解説。Lazygitやoil.nvim風エクスプローラー、TODOコメントのハイライト、ファジーファインダーや全文検索のプレビューなど、拡張機能や設定例を詳しく紹介しています。VSCodeとNeovimの二刀流を目指す方や、エディタのカスタマイズに興味がある方はぜひご覧ください。</div> <img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/%F0%9F%93%98Articles/attachments/2025-06-15-1.webp" /> <a data-href="📘目指せ二刀流! VSCodeをNeovim色にコーディネートしてみた -後編-" class="internal-link"></a> </div> %%[[📘目指せ二刀流! VSCodeをNeovim色にコーディネートしてみた -後編-]]%% おかげで快適な[[VSCode]]を手にしましたが、[[Neovim]]の利用機会が増えるならその方が嬉しいに決まっています。[[Claude Code]]が利用できれば、[[GitHub Copilot]]のために[[VSCode]]を使い続ける必要もないのです。 ### 職場での導入可能性がゼロではなさそう [[AI]]導入に関しては、データを預かるベンダー選定に結構慎重です。そのため、[[OpenAI]]ですら承諾が出ません。しかし、風の噂で **『[[Anthropic]]の[[Claude]]ならいいのではないか?』** という話を耳にしました。今、[[Claude Code]]をキャッチアップしてその体験が素晴らしいものであれば、プッシュするチャンスにもなり得ます。 ## 環境 | 対象 | バージョン | | --------------- | ------- | | [[macOS]] | 15.5 | | [[Ghostty]] | 1.1.3 | | [[Neovim]] | 0.11.2 | | [[Node.js]] | 22.15.0 | | [[Claude Code]] | 1.0.24 | ## 契約 ### プランの選定 従量課金制にするか、月額のサブスクリプションにするか、少し悩みました。最初は従量課金制にして様子見したほうがいいかも...と思っていたところ、以下の記事を見かけました。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://static.zenn.studio/images/logo-transparent.png" /> <span class="link-card-v2-site-name">Zenn</span> </div> <div class="link-card-v2-title"> Claude Pro($20)プランでゼロから始めるClaude Code </div> <img class="link-card-v2-image" src="https://res.cloudinary.com/zenn/image/upload/s--o927mcY9--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:Claude%2520Pro%25EF%25BC%2588%252420%25EF%25BC%2589%25E3%2583%2597%25E3%2583%25A9%25E3%2583%25B3%25E3%2581%25A7%25E3%2582%25BC%25E3%2583%25AD%25E3%2581%258B%25E3%2582%2589%25E5%25A7%258B%25E3%2582%2581%25E3%2582%258BClaude%2520Code%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:asap%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyL2VhYjVhYTQ1MTkuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png" /> <a href="https://zenn.dev/asap/articles/700168965fdb7b"></a> </div> その結果、[[Claude Pro]]のサブスクリプション契約をすることにしました。 ### 登録作業 以下のページから[[Claude Pro]]を契約します。認証は[[Google]]を使います。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://cdn.prod.website-files.com/67ce28cfec624e2b733f8a52/681d52619fec35886a7f1a70_favicon.png" /> <span class="link-card-v2-site-name">www.anthropic.com</span> </div> <div class="link-card-v2-title"> Pricing \ Anthropic </div> <div class="link-card-v2-content"> Anthropic is an AI safety and research company that's working to build reliable, interpretable, and steerable AI ... </div> <img class="link-card-v2-image" src="https://cdn.prod.website-files.com/67ce28cfec624e2b733f8a52/68309ab48369f7ad9b4a40e1_open-graph.jpg" /> <a href="https://www.anthropic.com/pricing"></a> </div> 何度かポチポチしたところ、チャットのトップページが表示されます。 ![[2025-06-14-18-11-44.avif]] ただ、この時点では[[Claude Pro]]プランにはなっていません。[[Claude Opus 4]]をモデルとして選択することで登録画面に進みます。 ![[2025-06-14-18-12-50.avif]] 『月額』を選択します。 ![[2025-06-14-18-13-56.avif|frame]] *デフォルトは『年額』なので注意* 登録が完了すると、ダッシュボードの『請求』画面がこのようになります。 ![[2025-06-14-18-28-00.avif]] ## [[Claude Code]]のインストール ドキュメントに従って進めていきます。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://mintlify.s3-us-west-1.amazonaws.com/anthropic/_generated/favicon/favicon-32x32.png?v=3" /> <span class="link-card-v2-site-name">docs.anthropic.com</span> </div> <div class="link-card-v2-title"> Getting started with Claude Code - Anthropic </div> <div class="link-card-v2-content"> Learn how to install, authenticate, and start using Claude Code. </div> <img class="link-card-v2-image" src="https://anthropic.mintlify.app/_next/image?url=%2Fapi%2Fog%3Fdivision%3DDocumentation%26mode%3Dlight%26title%3DGetting%2Bstarted%2Bwith%2BClaude%2BCode%26description%3DLearn%2Bhow%2Bto%2Binstall%252C%2Bauthenticate%252C%2Band%2Bstart%2Busing%2BClaude%2BCode.%26logoLight%3Dhttps%253A%252F%252Fmintlify.s3.us-west-1.amazonaws.com%252Fanthropic%252Flogo%252Flight.svg%26logoDark%3Dhttps%253A%252F%252Fmintlify.s3.us-west-1.amazonaws.com%252Fanthropic%252Flogo%252Fdark.svg%26primaryColor%3D%25230E0E0E%26lightColor%3D%2523D4A27F%26darkColor%3D%25230E0E0E&w=1200&q=100" /> <a href="https://docs.anthropic.com/en/docs/claude-code/getting-started"></a> </div> [[npm]]でグローバルインストールします。 ```console npm install -g @anthropic-ai/claude-code ``` ## 設定 プロジェクトに移動して `claude` コマンドを実行します。ここでは[[🦉Another Quick Switcher]]に移動しました。 ```console cd github.com/tadashi-aikawa/obsidian-another-quick-switcher claude ``` > [!warning] コマンド実行時に `bash` は不要 > 上記ドキュメントには `bash` からコマンドが開始されていますが、これはドキュメント生成バグである可能性が高いと思います。他のページでは直接 `claude` のようにコマンドが書かれていました。 > > ![[2025-06-14-18-44-39.avif]] ### 差分の見た目 `Dark mode` が一番見やすそうなので、1を選択したまま進みます。 ![[2025-06-14-18-47-47.avif]] ### ログイン方法 ログイン方法を選択します。[[Claude Pro]]はサブスクリプションなので1を選択したまま進みます。 ![[2025-06-14-18-48-58.avif]] ブラウザで承認を求められます。承認したら完了です。 ### 注意事項の確認 注意書きが表示されます。 ![[2025-06-14-18-50-32.avif]] 端的に言うと 1. [[AI]]は完全に信用するな 2. 信頼できるツールを使え ということです。詳細は公式ドキュメントの `Security` セクションを確認しましょう。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://mintlify.s3-us-west-1.amazonaws.com/anthropic/_generated/favicon/favicon-32x32.png?v=3" /> <span class="link-card-v2-site-name">docs.anthropic.com</span> </div> <div class="link-card-v2-title"> Manage permissions and security - Anthropic </div> <div class="link-card-v2-content"> Learn about Claude Code's permission system, tools access, and security safeguards. </div> <img class="link-card-v2-image" src="https://anthropic.mintlify.app/_next/image?url=%2Fapi%2Fog%3Fdivision%3DDocumentation%26mode%3Dlight%26title%3DManage%2Bpermissions%2Band%2Bsecurity%26description%3DLearn%2Babout%2BClaude%2BCode%2527s%2Bpermission%2Bsystem%252C%2Btools%2Baccess%252C%2Band%2Bsecurity%2Bsafeguards.%26logoLight%3Dhttps%253A%252F%252Fmintlify.s3.us-west-1.amazonaws.com%252Fanthropic%252Flogo%252Flight.svg%26logoDark%3Dhttps%253A%252F%252Fmintlify.s3.us-west-1.amazonaws.com%252Fanthropic%252Flogo%252Fdark.svg%26primaryColor%3D%25230E0E0E%26lightColor%3D%2523D4A27F%26darkColor%3D%25230E0E0E&w=1200&q=100" /> <a href="https://docs.anthropic.com/en/docs/claude-code/security"></a> </div> いくつかのツールはユーザーに許可を求めての利用となるため、知らないうちに勝手に使われることはなさそうです。 - [[Bash]] - ファイル編集 - Webデータ取得 - Web検索 - ファイルの書き込み 逆に以下のツールは許可なく利用されます。**秘密情報があるディレクトリでは使わない方**がいいでしょう。 - Grep - ファイル読み込み ### ターミナルセットアップ プロンプトでの改行を `Shift+Enter` など馴染のものに設定してくれるようです。 ![[2025-06-14-18-56-00.avif]] [[ChatGPT]]に聞いてみたところ『[[Ghostty]]はまだ対応されてなさそう』との結果が返ってきました。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://cdn.oaistatic.com/assets/favicon-miwirzcw.ico" /> <span class="link-card-v2-site-name">ChatGPT</span> </div> <div class="link-card-v2-title"> ChatGPT - Claude Code ターミナル設定 </div> <div class="link-card-v2-content"> Shared via ChatGPT </div> <img class="link-card-v2-image" src="https://cdn.oaistatic.com/assets/chatgpt-share-og-u7j5uyao.webp" /> <a href="https://chatgpt.com/share/684d48ef-be40-800a-9abc-868636273897"></a> </div> 私は[[Ghostty]]を使っているので、ここは2を選択して進めます。複数行のプロンプトを書きたい場合は[[Neovim]]などで書いたものをコピペで貼り付ければ十分でしょう。 ![[2025-06-14-19-04-31.avif]] ### 信頼できるディレクトリかどうかの確認 念のため確認されます。問題なければ1を選択したまま進めます。 ![[2025-06-14-19-05-52.avif]] ## プロジェクトのセットアップ プロンプトを立ち上げて `/init` コマンドを実行すると、プロジェクトが[[Claude Code]]用にセットアップされます。 ![[2025-06-14-19-07-44.avif|frame]] *コマンドの補完が入力欄の下に出現して快適* 1分30秒ほどプロジェクトの解析が行われました。トークン消費量は5万トークン弱でした。 ``` ⏺ Task(Analyze project architecture) ⎿  Done (17 tool uses · 48.6k tokens · 1m 23.7s) ``` 解析した結果を `CLAUDE.md` に保存していいのか確認されますので、`1. Yes` を選択したままEnterを押します。 ![[2025-06-14-19-11-50.avif]] `CLAUDE.md` が作成されました。 > [!code]- `CLAUDE.md` > > ```markdown > # CLAUDE.md > > This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. > > ## Project Overview > > This is an Obsidian plugin called "Another Quick Switcher" that provides advanced file and content navigation capabilities. It offers multiple search modes including file search, grep, header navigation, backlinks, and custom search commands. > > ## Development Commands > > - `bun i` - Install dependencies > - `bun dev` - Development build with watch mode > - `bun run build` - Production build with TypeScript check > - `bun run test` - Run Jest tests > - `bun run ci` - Full CI pipeline (lint, build, test) > - `biome check src *.mts` - Lint TypeScript files > - `tsc -noEmit -skipLibCheck` - Type checking only > > ## Architecture > > ### Core Components > > **Main Plugin Structure:** > - `src/main.ts` - Plugin entry point, lifecycle management, command registration > - `src/settings.ts` - Comprehensive settings system with 200+ configuration options > - `src/commands.ts` - Command factory functions for different search modes > - `src/app-helper.ts` - Abstraction layer over Obsidian APIs > > **Modal System:** > - `src/ui/AnotherQuickSwitcherModal.ts` - Main configurable search modal > - `src/ui/GrepModal.ts` - Text content search using ripgrep > - `src/ui/BacklinkModal.ts` - Backlink navigation > - `src/ui/LinkModal.ts` - Outgoing link navigation > - `src/ui/HeaderModal.ts` - In-file header navigation > - `src/ui/InFileModal.ts` - In-file text search > - `src/ui/FolderModal.ts` & `MoveModal.ts` - File system operations > > **Core Systems:** > - `src/matcher.ts` - Text matching and scoring algorithms > - `src/sorters.ts` - 20+ configurable sort priorities > - `src/transformer.ts` - Data transformation for search results > > ### Key Patterns > > 1. **Command-Based Architecture** - All functionality exposed through registered Obsidian commands > 2. **Settings-Driven Configuration** - Highly customizable behavior through comprehensive settings > 3. **Modal Specialization** - Different modal classes for specific search types > 4. **External Tool Integration** - Uses ripgrep and fd for performance-critical operations > > ### External Dependencies > > - **ripgrep** - Required for grep functionality, set path in "Ripgrep command" setting > - **fd** - Optional for file name search in grep mode, enable "Include file name in search" > > ## Development Notes > > - Uses Bun as package manager and build tool > - TypeScript with strict mode enabled > - Biome for linting and formatting (spaces, not tabs) > - Jest for testing with esbuild transformer > - Obsidian plugin API version 1.7.2+ > > ## Settings Architecture > > The plugin has a complex settings system supporting: > - Custom search commands with configurable targets and sorting > - Per-modal hotkey customization > - Path filtering and exclusions > - Search behavior customization (fuzzy matching, prefix matching, etc.) > > Settings are deeply merged on load and heavily validated in the UI. > > ## Testing > > Tests are located alongside source files with `.test.ts` suffix. Focus on: > - `transformer.test.ts` - Data transformation logic > - `collection-helper.test.ts` - Utility functions > - `math.test.ts` - Scoring calculations > - `path.test.ts` - Path manipulation > - `strings.test.ts` - String processing > > Run tests before any significant changes to ensure compatibility. > ``` ## 機能追加をしてみる ここから[[Claude Code]]と会話をしながら機能追加をしていきます。 ### やりとりの表現 順調にいけば、出力は[[Claude Code]]の途中経過と確認だけになります... が、実際は確認の回答に `No` と言う場面も多いです。そのようなメッセージのやりとりを本記事では[[ミネルヴァ]]さんと[[Claudeさん]]の対話として表現します。 > [!right-bubble] ![[minerva-face-right.webp]] > > 私が打ち込んだ内容はこちら。 > [!left-bubble] ![[claude-san-face.webp]] > > [[Claude Code]]からの返答はこちら。 ### はじめてのオーダー それでは最初のお願いをしてみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > AnotherQuickSwitcherModal にてクエリを入力した状態から、クエリを引き継いでGrepModalを起動し、そのまま検索できる機能を追加して。 > [!left-bubble] ![[claude-san-face.webp]] > > AnotherQuickSwitcherModalからクエリを引き継いでGrepModalを起動する機能を追加します。 **自発的にTODOリストを定義して、進捗を共有しながら**1つずつタスクを進めてくれます。エージェント感半端ない。 ![[2025-06-14-19-24-35.avif]] 実装前の調査は終わったみたいです。実際の開発でも大事なステップですね。 ![[2025-06-14-19-25-17.avif]] ### GrepModal起動用のホットキー設定を追加 2分ほど経過したら、初めての差分確認リクエストが表示されました。[[Neovim]]を開いて確認したところ問題なかったので次に進みます。 ![[2025-06-14-19-27-08.avif]] 次の差分確認リクエストです。 ![[2025-06-14-19-29-41.avif]] 修正箇所は問題ありませんが、新規追加するコマンドにはデフォルトショートカットキーを設定しない方針にしています。`3` を選択してその旨を伝えます。 ![[2025-06-14-19-31-58.avif]] > [!right-bubble] ![[minerva-face-right.webp]] > > 新しく追加するコマンドにはデフォルトショートカットキーを割り当てないようにしています。 > [!left-bubble] ![[claude-san-face.webp]] > > 了解しました。デフォルトショートカットキーを割り当てずに実装を進めます。 方針を伝えるだけで命令しなくてもしっかり理解してくれます。次の差分確認リクエストでは期待通りのコードになっていました。 ![[2025-06-14-19-32-45.avif]] ### クエリ引き継ぎ機能をAnotherQuickSwitcherModalに実装 しばらくして、次の差分確認リクエストです。エラー出力が気になりましたが、importの追加自体には問題なさそうです。 ![[2025-06-14-19-37-17.avif]] その後、今までよりも多めの差分確認リクエストがきました。 ![[2025-06-14-19-38-34.avif]] 処理としては動きそうですが、`AnotherQuickSwitcherModal.ts` の中で `GrepModal` の[[DOM]]を読み込むのは責務を超えすぎなので許容できません。 > [!right-bubble] ![[minerva-face-right.webp]] > > `AnotherQuickSwitcherModal.ts` の中で `GrepModal` のDOMを読み込むのは流石にやりすぎです。GrepModalのコンストラクタにinitialQueryを任意指定できるようにしてください。コンストラクタ内の `this.setHotkeys()` にそれを渡せば、DOMの初期化時にクエリを流し込めると思います。 > [!left-bubble] ![[claude-san-face.webp]] > > 承知しました。より適切な方法でGrepModalのコンストラクタにinitialQueryパラメータを追加します。 しっかり意図を理解し、コンストラクタへ引数を追加する方針に切り替えてくれました。 ![[2025-06-14-19-49-44.avif]] `onOpen` で初期クエリを設定するため[[フィールド (TypeScript)|フィールド]]を追加する差分確認リクエストがきました。 ![[2025-06-14-19-52-22.avif]] [[コンストラクタ (TypeScript)|コンストラクタ]]ではなく、`onOpen` へ実装することが妥当なのか気になったので確認してみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > constructor の最後の `this.setHotkeys()` にクエリを流し込めばいけると思ったのですが、onOpenでの設定が必要だと考えた理由を教えてもらえますか? ダメ出しをしているわけでなく、私の考慮漏れがありそうだと思ったので。 > [!left-bubble] ![[claude-san-face.webp]] > > 良い質問ですね。私の判断を説明します。 `GrepModal.ts` の実装を念入りに確認した上で、返答がきました。 > [!left-bubble] ![[claude-san-face.webp]] > > あなたの考えが正しいと思います。私の判断が間違っていました。 理由を説明します。 > > **私がonOpenでの設定が必要だと考えた理由(間違った判断):** > 1. `this.inputEl`がObsidianのSuggestModalの仕組みでonOpen後に初期化されると思い込んでいた > 2. DOM要素の準備ができてからでないと値を設定できないと考えていた > > **しかし、実際には:** > 1. `SuggestModal`を継承しているので、`this.inputEl`はコンストラクタ完了時点で既に利用可能 > 2. `setHotkeys()`の時点で`this.inputEl`に初期値を設定すれば、モーダルが開いた時に既にその値が表示される > 3. コードを見ると、onOpenでは主にGrepModal特有のpathInputElの設定をしているだけ > > **あなたのアプローチの方が正しい理由:** > - より直接的でシンプル > - DOM操作のタイミングを気にする必要がない > - constructor内で初期化が完了する > > constructorの最後で初期クエリを設定する方法で進めましょう。私の判断ミスでした。 ![[2025-06-14-19-56-33.avif]] 『判断ミス』は言い過ぎだと思いますが、こちらの意見を良しとしてもらったのでそのまま進めてもらいます。 > [!right-bubble] ![[minerva-face-right.webp]] > > 了解です。それでお願いします。 しかし、引き続き[[フィールド (TypeScript)|フィールド]]の追加を要求されました。 ![[2025-06-14-19-57-16.avif]] [[コンストラクタ (TypeScript)|コンストラクタ]]内での実装なら、[[フィールド (TypeScript)|フィールド]]は不要だと思ったので確認してみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > クエリの初期値は初期化のときに設定するだけなので、フィールドを追加して状態としてもたせる必要はないように思えました。もし、必要と考えた理由があれば教えて下さい。 > [!left-bubble] ![[claude-san-face.webp]] > > おっしゃる通りです。初期化時にのみ使用するパラメータなので、インスタンスフィールドとして保持する必要はありませんね。 [[コンストラクタ (TypeScript)|コンストラクタ]]の中には実装してもらえましたが、`this.inputEl` への代入は恐らくバグになります。それを指摘します。 ![[2025-06-14-19-59-54.avif]] > [!right-bubble] ![[minerva-face-right.webp]] > > this.inputEl に直接代入してしまうと、見た目上はクエリが空に見えてしまうと思いますが大丈夫ですか? 詳しくは setHotkeys関数 の実装を読んでみてください。 > [!left-bubble] ![[claude-san-face.webp]] > > 良い指摘ですね。setHotkeys関数の実装を確認します。 紹介した `setHotkeys` 関数を読んでもらったところ... > [!left-bubble] ![[claude-san-face.webp]] > > なるほど!よくわかりました。GrepModalでは入力要素がクローン化されて置き換えられているため、直接`this.inputEl.value`を設定しても表示されないんですね。 > > 正しい方法でinitialQueryを設定します: ![[2025-06-14-20-06-19.avif]] フィードバックを元に的確な実装をしてくれました。 もう1つ、`this.setHotkeys()` の中に追加しなかった理由が気になったので、聞いてみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > 処理としては良さそうです。参考までに `this.setHotkeys()` の中でなく、外に実装した理由があれば教えてください。 > [!left-bubble] ![[claude-san-face.webp]] > > 良い質問ですね。私がsetHotkeys()の外に実装した理由を説明します: > > **私の判断理由:** > 1. **責務の分離**: setHotkeys()はホットキーの設定が主目的で、初期クエリ設定は別の関心事 > 2. **可読性**: constructorの最後で初期化処理が明確に見える > 3. **依存関係**: setHotkeys()でclonedInputElが作成されるので、その後に実行する必要がある > > **しかし、setHotkeys()内に入れる方が良い理由もあります:** > > 1. **カプセル化**: 入力要素の初期化がsetHotkeys()内で完結する > 2. **一貫性**: clonedInputElの作成と初期値設定が同じ場所にある > 3. **保守性**: 入力要素関連の処理が一箇所にまとまる > > **どちらでも動作しますが、**setHotkeys()内に入れる方がより良い設計だと思います。GrepModal特有の複雑な入力要素の仕組み(クローン化)を考えると、その初期化処理も同じ場所にある方が理解しやすいですね。 > > どちらの実装をお好みでしょうか? ![[2025-06-14-20-08-58.avif]] [[Claude Code]]案の方が良さそうなので、そのように回答します。 > [!right-bubble] ![[minerva-face-right.webp]] > > setHotkeysで初期クエリの設定があるのは変なので、あなたの設計案の方がいいと思います。そちらでお願いします。(どちらにしてもどこかが複雑になってしまうので...) > [!left-bubble] ![[claude-san-face.webp]] > > 承知しました。setHotkeys()の後に初期クエリ設定を行う方法で実装します。 ![[2025-06-14-20-11-29.avif]] そのまま承認したら、その他の修正に入りました。 > [!left-bubble] ![[claude-san-face.webp]] > > 次に、commands.tsのshowGrepDialog関数を更新してinitialQueryパラメータを受け取れるようにします: ![[2025-06-14-20-12-28.avif]] 差分確認リクエストがいくつか来るので、すべて承認しました。そして、最後はホットキーの設定に関する確認リクエストが来ました。 > [!left-bubble] ![[claude-san-face.webp]] > > 最後に、AnotherQuickSwitcherModalにホットキーハンドラーを追加します: ![[2025-06-14-20-16-01.avif]] 一見良さそうに見えますが、他にも選択肢がいくつかあったため、その実装を選んだ意図を聞いてみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > close系のメソッドは `this.close()` 以外にも `this.silentClose()` や `this.safeClose()` という選択肢もあると思います。`this.close()` が適切と判断した理由を、各メソッドの実装を確認したうえで教えて下さい。 > [!left-bubble] ![[claude-san-face.webp]] > > 良い指摘ですね。各closeメソッドの実装を確認して適切な選択をする必要があります。 ここでなぜかファイル読み込むの承認を求められました。リポジトリ内のファイルであれば、承認せずに読み込めるはず... 現にこれまでは承認していません。 ![[2025-06-14-20-19-18.avif]] よく見ると**パスが変**ですね。`opensidian-another-quick-switcher` ??? > [!right-bubble] ![[minerva-face-right.webp]] > > opensidian-another-quick-switcher なんてディレクトリはないと思いますが... > [!left-bubble] ![[claude-san-face.webp]] > > すみません、タイポでした。正しいパスで確認します。 > [!right-bubble] ![[minerva-face-right.webp]] > > (えっ!?) ![[2025-06-14-20-25-43.avif]] リポジトリ内を全文検索しても `opensidian` という[[Typo]]はありませんでしたので、なぜこの[[Typo]]が発生したのかは謎でした。。。 該当ファイルを確認の上、しばらくしてから返答がきました。 > [!left-bubble] ![[claude-san-face.webp]] > > ありがとうございます!各メソッドの実装を確認した結果、`silentClose()`が最も適切だと判断します。 > > **理由:** > > 1. **既存パターンの踏襲**: コードベース内で他のモーダルへの遷移時(966行、1016行など)に`silentClose()`が使われている > 2. **状態復元の回避**: `willSilentClose`フラグによって`onClose()`での状態復元処理をスキップし、新しいGrepModalとの干渉を防ぐ > 3. **クリーンな遷移**: 不要な副作用なしでモーダル間の遷移を実現 > > `silentClose()`で実装します: ![[2025-06-14-20-26-26.avif]] 非常に考えられていると思いましたが、動作に不安があったので確認してみました。[[🦉Another Quick Switcher]]のダイアログクローズはかなり複雑な処理なので、難易度は高いと思います。 > [!right-bubble] ![[minerva-face-right.webp]] > > しかし、`silentClose()` をしてしまうと、`AnotherQuickSwitcherModal` で本来戻すべき状態を戻せない可能性はないだろうか。`GrepModal` の `onClose` では `AnotherQuickSwitcherModal` のリストア処理は実行されないだろうし、`setHotkeys.navigate` 関数のように `siletClose()` した後すぐに `AnotherQuickSwitcherModal`を開いているわけでもない。 > [!left-bubble] ![[claude-san-face.webp]] > > 素晴らしい指摘です!おっしゃる通り、`silentClose()`を使うとAnotherQuickSwitcherModalの状態復元処理がスキップされてしまい、問題が生じる可能性があります。 少しファイルを確認後、長めの回答がきました。 > [!left-bubble] ![[claude-san-face.webp]] > > 確認した通り、`silentClose()`を使うと以下の重要な処理がスキップされます: > > 1. **入力クエリの保存**(227-229行):`command.restoreLastInput`が有効な場合の次回起動時の入力復元 > 2. **状態復元**(231-233行):`stateToRestore`による元の状態(カーソル位置等)の復元 > > **問題点:** > - GrepModalから戻った時に、元のファイルのカーソル位置などが復元されない > - 次回AnotherQuickSwitcherModalを開いた時に入力が復元されない可能性 > > **解決策:** > `safeClose()`を使用するのが適切だと思います。これにより: > 1. 状態復元処理が正常に実行される > 2. Promise化されているので、GrepModal起動前にcloseが完了することを保証できる > > 正しい実装は: > > ```typescript > this.registerKeys("launch grep", async () => { > const currentQuery = this.inputEl.value.trim(); > await this.safeClose(); > await showGrepDialog(this.app, this.settings, currentQuery || undefined); > }); > ``` > > この方法でよろしいでしょうか? ![[2025-06-14-20-33-21.avif]] ここは非常に重要であり、本対応の難しいところです。慎重に確認してみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > > 2. Promise化されているので、GrepModal起動前にcloseが完了することを保証できる > > とありますが、GrepModal起動前にcloseしてしまうと見た目がおかしくなったりしませんか? 逆にGrepModalが起動してからcloseだと悪影響があるのであれば知りたいです。 > [!left-bubble] ![[claude-san-face.webp]] > > とても良い質問ですね!順序による見た目や動作への影響を考える必要があります。 全文検索をするため[[ripgrep]]コマンドの利用承認がきました。 ![[2025-06-14-20-36-05.avif]] 真面目に影響範囲を確認してくれています。 ![[2025-06-14-20-37-10.avif]] 都度承認するのが面倒なので、[[🦉Another Quick Switcher]]に対する[[ripgrep]]コマンドの実行は常に許可するよう `2` を選びました。 ![[2025-06-14-20-38-22.avif]] しばらく待つと回答がきました。 > [!left-bubble] ![[claude-san-face.webp]] > > 分析結果から、現在のコードベースでは**「close-before-open」**パターンが一貫して使われており、これには技術的・UX的な理由があります。 > > **なぜclose-before-openが使われているか:** > > 1. **フォーカス管理**: 複数のモーダルが同時に開いているとフォーカスの競合が起きる > 2. **z-indexの問題回避**: モーダルの重なり順の問題を避ける > 3. **リソース管理**: 古いモーダルを先に閉じることでメモリとイベントリスナーを適切に解放 > 4. **視覚的な一貫性**: モーダルの重複表示を避けてクリーンな遷移を実現 > > **見た目への影響について:** > - 確かに一瞬のギャップが生じる可能性はありますが、それよりも複数モーダルが重複することの方が問題 > - Obsidianのモーダルシステム自体がこのパターンを前提に設計されている > > **推奨実装:** > 既存パターンに従い、`safeClose()`でclose-before-openパターンを使用: > > ```typescript > this.registerKeys("launch grep", async () => { > const currentQuery = this.inputEl.value.trim(); > await this.safeClose(); // 状態復元も含めて適切にclose > await showGrepDialog(this.app, this.settings, currentQuery || undefined); > }); > ``` > > この方法で実装してよろしいでしょうか? ![[2025-06-14-20-42-30.avif]] めちゃくちゃ的確な提案ですね! 素晴らしい! > [!right-bubble] ![[minerva-face-right.webp]] > > OKです! 完全同意 ![[2025-06-14-20-43-08.avif]] これで実装は完了です。 ## 動作確認する ついに最後のタスクです。 > [!left-bubble] ![[claude-san-face.webp]] > > 実装が完了しました!最後にテストのためビルドを実行してエラーがないか確認します: ![[2025-06-14-20-44-08.avif]] ただ、今回の機能はそもそもテストができないと思っていました。『テスト』という言葉の意図を確認します。 > [!right-bubble] ![[minerva-face-right.webp]] > > 『機能をテスト』とは何を指していますか? 『テストコードを書いてテストする』ことを指しているのであれば、それは不要です(今回の修正を確認できるテストコードベースがない)。 > > 逆に、『実際に起動・操作して動作すること』の確認であれば、どう実現するのかが気になっています。 > > もし私の方で動作確認したほうがよければ言ってください。`bun dev` を実行するとhot reload有効な状態になるので、今Obsidianを開いているから確認できます。 > [!left-bubble] ![[claude-san-face.webp]] > > 「機能をテスト」というのは「実際に起動・操作して動作確認」を想定していましたが、おっしゃる通りClaude Codeでは実際のObsidianプラグインの動作確認はできません。 > > ユーザー側で動作確認していただくのが最適です。`bun dev`でhot reloadが有効であれば、すぐに確認できますね。 話が通じたので『機能をテストして動作確認』はタスクリストから削除されました。 > [!left-bubble] ![[claude-san-face.webp]] > > ## 実装完了 > > AnotherQuickSwitcherModalからクエリを引き継いでGrepModalを起動する機能を実装しました: > > **実装内容:** > 1. **設定にホットキー追加**: `main`セクションに`"launch grep"`を追加(デフォルトキーなし) > 2. **GrepModal拡張**: コンストラクタに`initialQuery?`パラメータを追加し、初期化時にクエリを設定 > 3. **commands.ts更新**: `showGrepDialog`に`initialQuery?`パラメータを追加 > 4. **AnotherQuickSwitcherModal拡張**: `"launch grep"`ホットキーハンドラーを追加し、`safeClose()`で適切な状態復元を実行 > > **動作確認すべき点:** > - AnotherQuickSwitcherModalでクエリ入力後、設定したホットキーでGrepModalが起動 > - GrepModalに入力クエリが引き継がれて表示される > - AnotherQuickSwitcherModalの状態が適切に復元される > > 動作確認をお願いできますでしょうか? ![[2025-06-14-20-47-41.avif]] 動作確認依頼がきたので確認してみます。設定はちゃんと追加されていたので[[ホットキー (Obsidian)|ホットキー]]を設定します。 ![[2025-06-14-20-49-22.avif|frame]] Grepのダイアログは表示されましたが、`searching` が表示されたままで、検索結果は表示されませんでした。 ![[2025-06-14-20-51-30.avif]] ### 検索中のままエラーになってしまう [[Chrome devtools]]を確認するとエラーが出ていました。 ```error 2 plugin:obsidian-another-quick-switcher:4211 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'split') at normalizeRelativePath (plugin:obsidian-another-quick-switcher:4211:8) at GrepModal.searchSuggestions (plugin:obsidian-another-quick-switcher:8687:34) at GrepModal.getSuggestions (plugin:obsidian-another-quick-switcher:8773:37) at t.updateSuggestions (app.js:1:1795889) at t.onInput (app.js:1:1795788) at new GrepModal (plugin:obsidian-another-quick-switcher:8576:20) at showGrepDialog (plugin:obsidian-another-quick-switcher:10201:17) at async eval (plugin:obsidian-another-quick-switcher:7958:7) ``` 厳しいかな...と思いつつ[[Claude Code]]に投げてみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > "lauch grep" を実行しました。GrepModalは開けましたし、見た目上はクエリも入っています。しかし検索結果が表示されません。 > > - 右上に "searching..." が出たまま > - 結果は "No results found." のまま > > DevtoolsのConsoleを確認したところ以下のエラーが出ていました。 > > ``` > 2 plugin:obsidian-another-quick-switcher:4211 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'split') > at normalizeRelativePath (plugin:obsidian-another-quick-switcher:4211:8) > at GrepModal.searchSuggestions (plugin:obsidian-another-quick-switcher:8687:34) > at GrepModal.getSuggestions (plugin:obsidian-another-quick-switcher:8773:37) > at t.updateSuggestions (app.js:1:1795889) > at t.onInput (app.js:1:1795788) > at new GrepModal (plugin:obsidian-another-quick-switcher:8576:20) > at showGrepDialog (plugin:obsidian-another-quick-switcher:10201:17) > at async eval (plugin:obsidian-another-quick-switcher:7958:7) > ``` > > 問題の見当つきますか? > [!left-bubble] ![[claude-san-face.webp]] > > エラーメッセージから、`normalizeRelativePath`関数で`undefined`の`split`メソッドを呼び出そうとして失敗していることがわかります。これはGrepModalの初期化時に`this.inputEl.dispatchEvent(new Event("input"))`が呼ばれることで検索が開始されるものの、必要な値が未初期化のために起きています。 > [!left-bubble] ![[claude-san-face.webp]] > > 問題は`normalizeRelativePath`の`base`パラメータが`undefined`になっていることです。GrepModalの初期化順序を確認しましょう: > [!left-bubble] ![[claude-san-face.webp]] > > 問題が見つかりました!`this.basePath`の初期化が`onOpen()`で行われているのに、コンストラクタでinputイベントを発火させているため、`this.basePath`が未定義のままで検索処理が実行されてしまっています。 > > 修正方法は、初期クエリの設定を`onOpen()`に移動することです: ![[2025-06-14-20-58-44.avif]] 序盤に[[Claude Code]]から提案してもらった `onOpen()` で初期クエリの設定を行う方針を再提案されました。自信がありそうだったのでお任せしてみます。 > [!left-bubble] ![[claude-san-face.webp]] > > 次に、initialQueryフィールドを追加する必要があります: > [!left-bubble] ![[claude-san-face.webp]] > > 最後に、`onOpen()`で`basePath`の初期化後に初期クエリを設定します: > [!left-bubble] ![[claude-san-face.webp]] > > 修正完了です。問題は`this.basePath`が初期化される前に検索処理が実行されたことでした。これで`onOpen()`で`basePath`初期化後に初期クエリが設定されるため、正常に動作するはずです。 > > 修正内容: > 1. コンストラクタでは`initialQuery`をフィールドに保存するだけ > 2. `onOpen()`で`basePath`初期化後に初期クエリを設定して検索実行 > > 再度テストしてみてください。 ![[2025-06-14-20-59-59.avif]] これで動いたら、最初から[[Claude Code]]の言う事を聞いておけばよかったということになり、私はいらなかったことになります。**そして動きました😱**。 ## ドキュメントを書いてもらう > [!right-bubble] ![[minerva-face-right.webp]] > > 期待通り動きました! そうだ、READMEにも今回追加した機能の説明を簡単に追加しておいてもらえますか?(ちょうどいいあたりに) > [!left-bubble] ![[claude-san-face.webp]] > > Grepセクションに機能説明を追加するのが適切だと思います: 普段からドキュメントの英語翻訳はAIに頼りっきりなので、流石の精度です。 ![[2025-06-14-21-05-36.avif]] ![[2025-06-14-21-06-37.avif]] > [!left-bubble] ![[claude-san-face.webp]] > > 完了です!READMEのGrepセクションに新機能の説明を追加しました。この場所が適切だと思います: > > - Grepの基本機能説明の後 > - 技術的なNoteの前 > - ユーザーが実際に使う機能として分かりやすい位置 > > 説明内容: > - Quick SwitcherからGrepダイアログを直接起動できること > - クエリが自動的に引き継がれること > - ホットキー設定が必要であること > > これで実装とドキュメント更新が完了しました! 楽ちんですね☺️ ## コミットしてもらう せっかくなのでコミットもお願いしてみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > 最後にコミットもお願いします。 > > GitHubのissuesを確認し、今回の機能で解消できそうなissueがあったら、そのissue番号も紐づけるようにしてください。(こういう要望があった記憶があるので) > [!left-bubble] ![[claude-san-face.webp]] > > GitHubのissuesを確認して、今回の機能に関連するissueを探します。 [[GitHub]]とのやりとりをするため、[[GitHub CLI]]コマンドの実行要請がきました。 ![[2025-06-14-21-10-34.avif]] ### [[GitHub CLI]]のインストールと初期設定 [[mise]]でインストールします。 ```console mise use -g gh ``` 認証もすませておきます。 ```console $ gh auth login ? Where do you use GitHub? GitHub.com ? What is your preferred protocol for Git operations on this host? SSH ? Upload your SSH public key to your GitHub account? Skip ? How would you like to authenticate GitHub CLI? Login with a web browser ! First copy your one-time code: Press Enter to open https://github.com/login/device in your browser... ✓ Authentication complete. - gh config set -h github.com git_protocol ssh ✓ Configured git protocol ✓ Logged in as tadashi-aikawa ``` 以下コマンドの結果が返却されることを確認しました。 ```console gh issue list --state all --limit 50 --json number,title,body ``` ### ghコマンドが見つからない [[GitHub CLI]]の設定はシェル再起動しないと有効にならないので、`gh`コマンドの実行はエラーになっていました。すると... > [!left-bubble] ![[claude-san-face.webp]] > > issuesページを直接確認してより詳細な情報を取得します。 ![[2025-06-14-21-18-52.avif]] 気を利かせてWebから情報を取得しようと試みてくれました。ただ、`gh`コマンドを利用できない理由は分かっているので、`3` を選択して以下を共有します。 > [!right-bubble] ![[minerva-face-right.webp]] > > 許可する前に共有です。 > > ghコマンドが使えないのは、先程利用要請されてから別のターミナルタブでインストール(mise use -g gh)し、`gh auth login` を行ったからだと思います。その設定がおそらく反映されていないということですよね? > [!left-bubble] ![[claude-san-face.webp]] > > はい、その通りです。別のターミナルタブでインストール・認証設定を行った場合、現在のClaude Codeセッションには反映されていない可能性が高いです。 > > 以下の方法で確認・解決できます: > > 1. **環境変数の再読み込み**:`source ~/.bashrc` や `source ~/.zshrc` > 2. **パスの確認**:`which gh` でghコマンドが見つかるか確認 > 3. **認証状態の確認**:`gh auth status` で認証できているか確認 > > もしくは、WebFetchでGitHubのissuesページを確認する方法もあります。どちらの方法でissueを調べてcommitメッセージに含めたいですか? ![[2025-06-14-21-21-36.avif]] 自律性が凄いですね。。 > [!right-bubble] ![[minerva-face-right.webp]] > > まずは提示してもらった確認・解決を試してみてください。 > [!left-bubble] ![[claude-san-face.webp]] > > ghが見つからないですね。miseの管理下にあるツールは見えていますが、ghが含まれていません。 ![[2025-06-14-21-22-53.avif]] 『ログインシェルで[[mise]]が初期化されていないなら、コマンド実行のたびに初期化をすればいいじゃない』とでも言わんばかりの適応力です。 > [!left-bubble] ![[claude-san-face.webp]] > > 素晴らしい!ghコマンドが使えるようになりました。これでissuesを確認できます: > [!right-bubble] ![[minerva-face-right.webp]] > > (素晴らしいのは貴方の方だ...!!) ![[2025-06-14-21-23-54.avif]] > [!left-bubble] ![[claude-san-face.webp]] > > 今度はより具体的に「launch」や「switch」に関連するissueを詳細確認します: > [!left-bubble] ![[claude-san-face.webp]] > > これは今回の機能とは関係ないようです。もう少し詳しく「Quick Switcher」から「Grep」への遷移に関連するissueを探してみます: > [!left-bubble] ![[claude-san-face.webp]] > > 直接的な関連issueが見つからないので、最近のdiscussionsも確認してみます: ![[2025-06-14-21-27-22.avif]] 関連するissuesが見つからないからと、[[GitHub Discussions]]まで確認しにいってくれるようです。気が利きますね! > [!left-bubble] ![[claude-san-face.webp]] > > 直接的に今回実装した機能(Quick SwitcherからGrepへの遷移機能)を要求するissueは見つからないようですが、グレップ機能の改善要求は複数あります。一般的なワークフロー改善として commit を作成しましょう: ![[2025-06-14-21-32-59.avif]] 該当issueやdiscussionは見つからなかったので単なる新機能としてコミットすることになりました。ただ、コミットメッセージが長すぎるので何点かフィードバックします。 > [!right-bubble] ![[minerva-face-right.webp]] > > コミットメッセージに実装内容は不要です。Conventional Commitの内容はSemantic Releaseで生成されるリリースノートとして直接利用されます。なので > > - 1行目だけでユーザーに伝わる内容にする ("launch grep" コマンドも含めて) > - 3行目以降は補足があれば箇条書きで1~2つ程度 (通常は不要) > > としてください。また、 "feat:" は "feat(main/grep):" でお願いします。 > [!left-bubble] ![[claude-san-face.webp]] > > 了解しました。よりシンプルで適切なコミットメッセージで作成します: > [!right-bubble] ![[minerva-face-right.webp]] > > Claude Codeが生成した旨のメッセージはコミットメッセージに含めないでください。本質的な情報ではないので。 > [!left-bubble] ![[claude-san-face.webp]] > > 了解しました。Claude Code生成の記載を除いてコミットします: ![[2025-06-14-21-37-13.avif]] さらに少し調整してもらい、無事にコミットが完了しました。 > [!left-bubble] ![[claude-san-face.webp]] > > コミット完了しました! > > - 1行目:ユーザーに伝わりやすい機能説明(\"launch grep\"ホットキーでクエリ転送) > - 3行目:設定方法の補足説明 > - 6ファイル変更、118行追加、7行削除 > - CLAUDE.mdも新規作成として含まれています > > 機能実装とドキュメント更新、そしてコミットまで完了です。 ## クロージング 実際にタスクを完遂してもらったわけですが、[[Claude Code]]を使う上で最後にやっておいたほうがいいことを聞いてみます。 > [!right-bubble] ![[minerva-face-right.webp]] > > 私はClaude Codeを使うのはこれが初めてです。 > > タスクを完了してもらったあとに、今後のClaude Codeとの連携をスムーズにするためやっておいたほうが良い作業はありますか? あるならばお願いしたいと思っています。 > [!left-bubble] ![[claude-san-face.webp]] > > Claude Code初回利用お疲れさまでした!今後のスムーズな連携のために、以下の作業をお勧めします: > > ## 1. CLAUDE.mdの内容確認・改善 > > 作成したCLAUDE.mdを実際の開発で使ってみて、不足している情報があれば追加してください。特に: > - よく使うコマンドの追加 > - プロジェクト固有の開発ルール > - 重要な設計判断の記録 > > ## 2. 開発環境の最適化 > > ghコマンドがmise環境でうまく動作するよう、以下を`.zshrc`などに追加することをお勧めします: ![[2025-06-14-21-40-53.avif]] ![[2025-06-14-21-42-51.avif]] [[GitHub CLI]]と[[mise]]は若干イレギュラーなので対応は見送ります。 > [!right-bubble] ![[minerva-face-right.webp]] > > それは結構です。今回のケースが特殊だったので。。 > [!left-bubble] ![[claude-san-face.webp]] > > 承知しました。Claude Code初回利用での推奨事項は以下です: > > ## 今後のスムーズな連携のために > > ### 1. CLAUDE.mdの活用 > - 今回作成したCLAUDE.mdを実際の開発で試して、不足情報があれば追加 > - プロジェクト固有のルールや重要な設計判断を記録 > > ### 2. コミット履歴の活用 > - 今回のコミット形式(Conventional Commits)が参考になるので保持 > - Claude Codeは過去のコミットから開発パターンを学習します > > ### 3. プロジェクト構造の理解 > - 今回のようにClaude Codeがコードベースを分析した結果は、今後の作業でも活用されます > - 大きな設計変更があった場合はCLAUDE.mdを更新 > > ### 4. 作業パターンの確立 > - 今回の「分析→設計→実装→テスト→ドキュメント→コミット」の流れが効果的でした > - 複雑な機能追加時はTodoリストを活用して進捗管理 > > 特別な環境設定は不要で、今回作成したCLAUDE.mdが最も重要な資産です。これにより次回以降のClaude Codeセッションがより効率的になります。 > > 何か他にご質問はありますか? ![[2025-06-14-21-43-55.avif]] `CLAUDE.md` は更新したほうがいいのでは...と思ったので、念のため確認します。 > [!right-bubble] ![[minerva-face-right.webp]] > > CLAUDE.md については今の内容のままで問題ないですか? もし加筆修正など必要であれば。 > [!left-bubble] ![[claude-san-face.webp]] > > 現在のCLAUDE.mdは良い内容ですが、今回の開発経験を踏まえていくつか改善提案があります: ![[2025-06-14-21-45-24.avif]] なるほど。これがコーディングスタイルのドキュメンテーション化というやつなのですね。 ![[2025-06-14-21-46-36.avif]] > [!left-bubble] ![[claude-san-face.webp]] > > CLAUDE.mdを改善しました!今回の開発経験で学んだ重要な知見を追加: > > **新しく追加した内容:** > 1. **Modal Development Guidelines** - 今回学んだmodal開発のベストプラクティス > 2. **Commit Guidelines** - プロジェクトのコミット規則とSemantic Release対応 > > これで次回のClaude Codeセッションで、同様の問題を避けて効率的に開発できるようになります。特に: > - モーダル遷移は`safeClose()`を使う > - 新機能のホットキーはデフォルト空配列 > - GrepModalの初期化タイミング > - コミットメッセージの形式 > > などの重要な学習内容が記録されています。 > [!right-bubble] ![[minerva-face-right.webp]] > > コミットもお願いします。 > [!left-bubble] ![[claude-san-face.webp]] > > コミット完了しました! > > CLAUDE.mdの改善内容: > - モーダル開発ガイドライン追加(今回の実装で学んだベストプラクティス) > - コミットガイドライン追加(Conventional Commits形式とSemantic Release対応) > > これで今後のClaude Codeセッションがより効率的になります。お疲れさまでした! ![[2025-06-14-21-48-37.avif]] 頼んでばかりで、ダメ人間になりそうです😇 ## 費用の確認 > [!right-bubble] ![[minerva-face-right.webp]] > > 最後に... 今回の対応に対する > > - メッセージ数 > - プロンプト数 > - トークン数 > - 費やした時間 > > を知りたいです。今はProプランを使っているので、制限があとどれくらいでかかるのかが気になってまして...。 > [!left-bubble] ![[claude-san-face.webp]] > > 申し訳ありませんが、Claude Code側ではそれらの詳細な使用量情報(メッセージ数、プロンプト数、トークン数、費やした時間)にアクセスすることができません。 > > **確認できる方法:** > > 1. **Claude.ai Web interface** - ブラウザでclaude.aiにアクセスすると、右上のプロフィールエリアで使用量が確認できるはずです > > 2. **Anthropic Console** - https://console.anthropic.com でより詳細な使用統計が見られる可能性があります > > **推定(参考程度):** > - 今回のセッションは約1-2時間程度 > - メッセージ数は約50-60回のやり取り > - 複数のファイル読み込みとコード生成を含む比較的重い作業 > > Proプランの制限については、Anthropicの公式ドキュメントや実際のダッシュボードで確認されることをお勧めします。Claude Codeは便利ですが、確かに使用量が気になりますね。 > > 具体的な使用量は上記の方法で確認してみてください! ![[2025-06-14-21-52-28.avif]] そこまで万能ではないみたいですが、案内はしてもらえました。ただ、定額のsubscriptionだと https://console.anthropic.com/ も `/cost` コマンドも対応していなそうでした。 ![[2025-06-14-21-56-53.avif]] `/status` でもダメだったので諦めかけていたところ、[[👤ryoppippi]]さんが[[ccusage]]の宣伝していたのを思いだしました。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://static.zenn.studio/images/logo-transparent.png" /> <span class="link-card-v2-site-name">Zenn</span> </div> <div class="link-card-v2-title"> Claude Codeの使用料金を可視化するCLIツール「ccusage」を作った </div> <img class="link-card-v2-image" src="https://res.cloudinary.com/zenn/image/upload/s--H7dC8_h---/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:Claude%2520Code%25E3%2581%25AE%25E4%25BD%25BF%25E7%2594%25A8%25E6%2596%2599%25E9%2587%2591%25E3%2582%2592%25E5%258F%25AF%25E8%25A6%2596%25E5%258C%2596%25E3%2581%2599%25E3%2582%258BCLI%25E3%2583%2584%25E3%2583%25BC%25E3%2583%25AB%25E3%2580%258Cccusage%25E3%2580%258D%25E3%2582%2592%25E4%25BD%259C%25E3%2581%25A3%25E3%2581%259F%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:ryoppippi%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyL2MzNDU0MTQ1MTMuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png" /> <a href="https://zenn.dev/ryoppippi/articles/6c9a8fe6629cd6"></a> </div> こちらを使ってみたところ、`bunx ccusage` コマンドを打つだけでコストを表示できました。 ![[2025-06-14-22-20-33.avif]] 日本円にして738円ほど。2時間30分くらいやりとりしていたので、人件費と考えれば安いものです。ただ、自分でやれば40分くらいでできた気がするので、時間的に急いでいるときは自分でやったほうがいいかもしれません。張り付いてフォローする手間も必要ですし。 > [!note] > > [[Docker]]などで隔離されたサンドボックス環境を作れるのであれば、`--dangerously-skip-permissions` が使えるので張り付いてフォローする必要はなくなりますが、それでも意図通りに最後までタスクを進めてもらえるかは不確実性が高いと思っています。タスクを確認しながら安心してお願いできるのが、[[Claude Code]]の大きなメリットだと思いますし。 どれくらい使うと制限がかかるかの目安について、[[ChatGPT]]に聞いてみました。今回のような使い方なら割と普通に使えそうです。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://cdn.oaistatic.com/assets/favicon-miwirzcw.ico" /> <span class="link-card-v2-site-name">ChatGPT</span> </div> <div class="link-card-v2-title"> ChatGPT - Claude Pro制限予測 </div> <div class="link-card-v2-content"> Shared via ChatGPT </div> <img class="link-card-v2-image" src="https://cdn.oaistatic.com/assets/chatgpt-share-og-u7j5uyao.webp" /> <a href="https://chatgpt.com/share/684d786f-1178-800a-800a-21adba7d9cf2"></a> </div> [公式情報](https://support.anthropic.com/ja/articles/11145838-pro%E3%81%BE%E3%81%9F%E3%81%AFmax%E3%83%97%E3%83%A9%E3%83%B3%E3%81%A7claude-code%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B#h_cc89d53563) では以下のように説明されていました。 > **Pro(月額$20):** 平均的なユーザーは、5時間ごとにClaudeで約45メッセージを送信、またはClaude Codeで約10-40プロンプトを送信できます。 内容にもよると思いますので、使っていく中で感覚を見極めていきたいと思います。 ## その他 ### `.claude` ディレクトリがバージョン管理下にない理由 [[Claude Code]]に聞いてみたところ `~/.config/git/ignore` が作成されてそこに追加されているのを発見しました。 ![[2025-06-15-12-45-19.avif]] ### ユーザー単位のsettings.json 確認不要でよく使うコマンドはユーザーレベルで設定しておきたいので `~/.claude/settings.json` を作成してみました。 ```json { "permissions": { "allow": [ "Bash(rg:*)", "Bash(bun pre:push:*)", "Bash(bun biome format:*)", "Bash(git add:*)", "WebFetch(domain:docs.anthropic.com)" ], "deny": [] }, "includeCoAuthoredBy": false } ``` それが適応されているかも[[Claude Code]]に聞いてみました。 > [!right-bubble] ![[minerva-face-right.webp]] > > ユーザー設定としてsettings.jsonを設定してみたつもりです。反映されていますかね? > [!left-bubble] ![[claude-san-face.webp]] > > 設定の反映を確認するために、テストコミットを作成してみましょう。 > [!left-bubble] ![[claude-san-face.webp]] > > はい。設定が反映されています!テストコミットにClaude関連のメッセージ (Co-Authored-Byなど) が追加されていませんでした。 > includeCoAuthoredBy: falseの設定が正しく動作しており、今後のコミットではClaude関連のメッセージが自動追加されなくなります。 ![[2025-06-15-14-27-58.avif]] コミットして実際に動作を確かめ、問題なければ `git reset` で元に戻してくれました。推測だけでなく事実確認する姿勢が素晴らしいですね。 ### push & Issueにコメントしてもらう > [!right-bubble] ![[minerva-face-right.webp]] > > 今ってpushしていないコミット何がありましたっけ? > [!left-bubble] ![[claude-san-face.webp]] > > 現在pushしていないコミットは4つあります: > > 1. `8feaca9` - **feat(grep): Add default folder setting for grep searches (#288)** (今回実装した機能) > 2. `9bbe018` - docs: Add modal development guidelines and commit rules to CLAUDE.md > 3. `b4be2a0` - feat(main/grep): Add \"launch grep\" hotkey to transfer query from Quick Switcher to Grep modal > 4. `153d584` - feat(grep): Highlight hit locations in title > > 一番上が今回のissue #288 の対応分です。 > [!right-bubble] ![[minerva-face-right.webp]] > > pushしてもらえますか? > [!left-bubble] ![[claude-san-face.webp]] > > pushが完了しました。4つのコミットがリモートリポジトリに送信されました。 > [!right-bubble] ![[minerva-face-right.webp]] > > issue 288 の対応について、『この対応はClaude Codeのみで実施しました』という旨の英語メッセージを投稿してください。 > [!right-bubble] ![[minerva-face-right.webp]] > > 加えて『この投稿はClaude Codeから自動でされました』という一文も。絵文字を添えて > [!left-bubble] ![[claude-san-face.webp]] > > GitHub issue #288 にコメントを投稿しました。実装が完了したことと、Claude Codeで対応したことを報告しています。 ![[2025-06-15-14-36-52.avif]] ### リリースをお願いする なんとリリースまで勝手にやってくれます。 > [!right-bubble] ![[minerva-face-right.webp]] > > リリースジョブを実行してもらえますか? やり方わかります? > [!left-bubble] ![[claude-san-face.webp]] > > リリースジョブの実行方法を確認させてください。GitHub Actionsのワークフローを確認してみます。 > [!left-bubble] ![[claude-san-face.webp]] > > リリースワークフローは`workflow_dispatch`で手動実行できるように設定されています。GitHub CLIを使って実行できます: ![[2025-06-15-14-37-26.avif]] > [!left-bubble] ![[claude-san-face.webp]] > > リリースジョブを実行しました。GitHub Actionsでセマンティックリリースが開始されているはずです。 > > 実行状況を確認するには: > [!left-bubble] ![[claude-san-face.webp]] > > リリースワークフローが現在実行中(`in_progress`)です。セマンティックリリースにより、新しいバージョンタグとリリースが自動的に作成されます。 > [!right-bubble] ![[minerva-face-right.webp]] > > リリースが終わったら教えて下さい。 > [!left-bubble] ![[claude-san-face.webp]] > > リリースの完了を確認します。 > [!left-bubble] ![[claude-san-face.webp]] > > まだ実行中です。もう少し待ってから再度確認します。 > [!left-bubble] ![[claude-san-face.webp]] > > リリースが完了しました!ステータスが`completed`で`success`になっています。 > > 最新のリリースを確認してみましょう: > [!left-bubble] ![[claude-san-face.webp]] > > 🎉 リリースが完了しました! > > **バージョン 13.5.0** がリリースされ、今回実装したgrep検索のデフォルトフォルダ設定機能が含まれています。ユーザーは新しいバージョンでissue #288 の機能を利用できるようになりました。 ![[2025-06-15-14-40-26.avif]] リリースのお願い + 終わったら教えて だけでリリースしてくれました☺️ ## リリース内容と動画 以下を御覧ください。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" /> <span class="link-card-v2-site-name">GitHub</span> </div> <div class="link-card-v2-title"> Release 13.5.0 · tadashi-aikawa/obsidian-another-quick-switcher </div> <div class="link-card-v2-content"> 13.5.0 (2025-06-15)✨ Features🎥 main/grep: Add "launch grep" hotkey to transfer query from Quick Switcher to Gre ... </div> <img class="link-card-v2-image" src="https://opengraph.githubassets.com/be3b84a0757a02d35f19f5e2313a0fb8702997ce59145a4c97ee2ee7fa4d68ca/tadashi-aikawa/obsidian-another-quick-switcher/releases/tag/13.5.0" /> <a href="https://github.com/tadashi-aikawa/obsidian-another-quick-switcher/releases/tag/13.5.0"></a> </div> ## まとめ [[🦉Another Quick Switcher]]の実践的な新機能追加対応を[[Claude Code]]を使って[[Agentic Coding]]してみました。 開始前はそれなりに期待していましたが、それを考慮しても **期待以上に素晴らしかった** です。[[Claude Code]]と[[Agentic Coding]]をするのであれば、アンチ[[Agentic Coding]]どころか、逆に[[Agentic Coding]]を推進したくなりました。 しばらくは[[Claude Pro]]で試しながら、必要になれば[[Claude Max]]も選択肢に入れて[[Agentic Coding]]力を上げていきたいと思います。