Skip to content
4 changes: 3 additions & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"Bash(locate:*)",
"Bash(mlocate:*)",
"Bash(mdfind:*)",
"Bash(cdidx:*)"
"Bash(cdidx:*)",
"Bash(~/.local/bin/cdidx:*)",
"Bash($HOME/.local/bin/cdidx:*)"
]
}
}
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
### [Unreleased]

#### Added
- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Contributors who intentionally want shell-level access to any of these commands can allow-list them in their own untracked `.claude/settings.local.json`. Affected: `.claude/settings.json`.
- **Tracked `.claude/settings.json` enforces cdidx-first code search for Claude Code agents** — Ship a repo-tracked Claude Code permissions file that denies the full set of code-search / file-discovery shell commands AI agents typically reach for: `Bash(rg:*)`, `Bash(grep:*)`, `Bash(egrep:*)`, `Bash(fgrep:*)`, `Bash(zgrep:*)`, `Bash(rgrep:*)`, `Bash(ripgrep:*)`, `Bash(ag:*)`, `Bash(ack:*)`, `Bash(ack-grep:*)`, `Bash(git grep:*)`, `Bash(find:*)`, `Bash(locate:*)`, `Bash(mlocate:*)`, `Bash(mdfind:*)`, and `Bash(cdidx:*)`. SELF_IMPROVEMENT.md already told contributors to use the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` instead of ripgrep / grep / the globally installed `cdidx`, but nothing enforced it at the harness level — agents could still silently fall back to whichever search tool happened to be installed, or to a stale global `cdidx` whose DB schema and extraction rules lag this branch. The new settings file turns that guidance into a hard gate so agents are forced to use the Grep / Glob built-ins or the freshly built local binary. Observed Claude Code behavior is that tracked `deny` is not overridden by `.claude/settings.local.json` allows (not confirmed against a public spec — treat as an observed workaround). Contributors who intentionally need shell-level access should edit the workspace copy of `.claude/settings.json` for that session only and not commit the change. The deny list adds `Bash(~/.local/bin/cdidx:*)` and `Bash($HOME/.local/bin/cdidx:*)` to cover the tilde- and `$HOME`-spelled absolute paths used by `install.sh` on Linux / macOS. CLAUDE.md, README, and this entry are reframed to describe the deny list as a **best-effort tripwire** rather than a hard guard: fully expanded absolute paths (e.g. `/Users/alice/.local/bin/cdidx`), `command cdidx`, `env cdidx`, and similar alternate spellings are not blocked because Claude Code permission matching is textual. The authoritative rule remains the written guidance (use Grep / Glob built-ins and the locally built `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll`). README's `# Code Search Rules` template is updated in both languages so the last-resort fallback no longer tells Claude Code sessions to run shell `rg` / `grep` / `find` — it points at built-in Grep / Glob instead. `CLOUD_BOOTSTRAP_PROMPT.md` gains a Step 1.5 instructing cloud sessions to invoke the installed binary via its fully expanded absolute path (`readlink -f "$HOME/.local/bin/cdidx"`), which the tripwire's textual matching does not catch. Editing the tracked `.claude/settings.json` is explicitly rejected in that step because it would dirty the worktree (breaking `git_is_dirty` as a trust signal) and risk an accidental commit that weakens the tripwire for every other contributor. Affected: `.claude/settings.json`, `CLOUD_BOOTSTRAP_PROMPT.md`, `CLAUDE.md`.
- **`--exact` extended to `definition` / `references` / `callers` / `callees` / `inspect` (#83)** — The case-insensitive exact-match semantic introduced in #81 now also applies to `cdidx definition`, `cdidx references`, `cdidx callers`, `cdidx callees`, `cdidx inspect`, and their MCP tool counterparts (`analyze_symbol` included) via an `exact` boolean. `inspect` / `analyze_symbol` propagates `exact` into every bundled sub-query (definitions, references, callers, callees) so the one-round-trip AI workflow keeps the same precision contract as the leaf commands — `inspect Run --exact` no longer pulls `RunAsync` / `RunImpact` into the bundled response. Predicates use `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE`, backed by new `idx_symbol_refs_name_nocase` and `idx_symbol_refs_container_nocase` covering indexes on `symbol_references` so multi-exact lookups stay SARGable. Closes the round-trip gap where an AI client had `symbols --exact` for name resolution but still had to fall back to substring matching for the follow-up definition / reference / call graph calls. ASCII-only NOCASE limitation from #81 still applies (non-ASCII casing is not folded; Unicode folding tracked in #86). Affected: `src/CodeIndex/Database/DbReader.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`, `CLAUDE.md`. Closes #83.
- **`--exact` on `symbols` for precise name resolution (#81)** — `cdidx symbols` and MCP `symbols` now accept `--exact` / `exact: true` to match symbol names by case-insensitive equality instead of `LIKE %...%` substring. When AI clients pass a resolved candidate list from an earlier `map` / `inspect` / `search` call, querying `Run` no longer also returns `RunAsync`, `RunImpact`, etc., saving a client-side filter pass and reducing token output. Composes with repeated `--name` / positional names (OR-joined per-name equality), and with all existing filters (`--kind`, `--lang`, `--path`, `--exclude-path`, `--exclude-tests`, `--since`, `--limit`). Default behavior (substring) is unchanged. The exact-match predicate uses `s.name = @q COLLATE NOCASE` (not `lower(col) = lower(@q)`) backed by a new `idx_symbols_name_nocase` covering index so multi-name exact lookups stay O(log n) per name instead of a full-table scan. Case-insensitivity follows SQLite's `NOCASE` collation (ASCII only) — non-ASCII casing pairs such as `Ä` / `ä` are not folded; pass the exact casing for non-ASCII identifiers. Unicode folding is tracked in #86. Affected: `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Database/DbContext.cs`, `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Cli/ConsoleUi.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #81.
- **Multi-name `symbols` query (#69)** — `symbols` now accepts multiple names in a single call so AI clients can resolve a candidate list without issuing one command per name. Supported forms: repeatable positional (`cdidx symbols A B C`) and repeatable `--name` flag (`--name A --name B`). Names are OR-joined server-side with per-name candidate fetch + round-robin merge under the user's `--limit` cap (so a popular name cannot starve others, and `--limit` still bounds total results). `|` is treated as a literal name character so operator symbols such as `operator |` remain searchable. All existing filters (`--kind`, `--lang`, `--path`, `--exclude-tests`, `--since`) still apply, and MCP `symbols` gains a parallel `names` array. Fully additive — single-name calls behave identically. Affected: `src/CodeIndex/Cli/QueryCommandRunner.cs`, `src/CodeIndex/Database/DbSymbolReader.cs`, `src/CodeIndex/Mcp/McpToolHandlers.cs`, `src/CodeIndex/Mcp/McpToolDefinitions.cs`, `tests/CodeIndex.Tests/DbReaderTests.cs`, `README.md`. Closes #69.
Expand Down Expand Up @@ -601,7 +601,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
### [Unreleased]

#### 追加
- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。shell レベルでこれらのコマンドを使いたい貢献者は、個人ごとの追跡外 `.claude/settings.local.json` で allow-list すれば引き続き使える。対象: `.claude/settings.json`。
- **リポジトリ追跡の `.claude/settings.json` で cdidx 最優先のコード検索を強制** — AI エージェントが代用しがちなコード検索/ファイル探索系のシェルコマンドを網羅的に deny するリポジトリ追跡版 Claude Code 権限ファイルを追加(`Bash(rg:*)`、`Bash(grep:*)`、`Bash(egrep:*)`、`Bash(fgrep:*)`、`Bash(zgrep:*)`、`Bash(rgrep:*)`、`Bash(ripgrep:*)`、`Bash(ag:*)`、`Bash(ack:*)`、`Bash(ack-grep:*)`、`Bash(git grep:*)`、`Bash(find:*)`、`Bash(locate:*)`、`Bash(mlocate:*)`、`Bash(mdfind:*)`、`Bash(cdidx:*)`)。SELF_IMPROVEMENT.md では「ripgrep / grep / グローバル `cdidx` ではなく、ローカルビルドした `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う」ルールを既に定義していたが、harness レベルで強制する仕組みが無く、エージェントが黙ってインストール済みの検索ツールや、ブランチ差分を反映しない古い DB スキーマ・抽出ルールのグローバル `cdidx` にフォールバックできてしまっていた。この設定ファイルで、そのガイドラインをハード gate に昇格し、Grep / Glob 組み込みツールか新しくビルドしたローカルバイナリの使用を強制する。観測された Claude Code の挙動として、追跡された `deny` は `.claude/settings.local.json` の allow では上書きされない(公開仕様で裏を取った記述ではないため、観測ベースの運用指針として扱う)。shell レベルで使いたい貢献者は、そのセッションに限りワークスペース上の `.claude/settings.json` を編集してコミットしない運用を取ること。deny リストには Linux / macOS の `install.sh` が配置する絶対パス系(チルダ形・`$HOME` 形)を塞ぐ `Bash(~/.local/bin/cdidx:*)` と `Bash($HOME/.local/bin/cdidx:*)` を追加する。CLAUDE.md、README、および本エントリを再構成し、deny リストはハードな gate ではなく**ベストエフォートのトリップワイヤ**として位置づけ直した: Claude Code の permission matching はテキスト一致のため、完全展開絶対パス(例: `/Users/alice/.local/bin/cdidx`)、`command cdidx`、`env cdidx` などの別スペルは塞げない。強制ルールの本体は文面そのもの(組み込み Grep / Glob とローカルビルドの `dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll` を使う)。README の `# コードベース検索ルール` テンプレートも英日両方で更新し、最終手段のフォールバックが Claude Code セッションで shell `rg` / `grep` / `find` を使うよう促さないようにした(代わりに組み込み Grep / Glob を案内)。`CLOUD_BOOTSTRAP_PROMPT.md` に Step 1.5 を追加し、Cloud セッションはインストール済みバイナリを完全展開した絶対パス(`readlink -f "$HOME/.local/bin/cdidx"`)経由で呼び出す運用を明記した — tripwire のテキスト一致はその形を塞げない。追跡対象の `.claude/settings.json` を編集する案は同じ Step で明示的に非推奨とした: worktree が dirty になり `git_is_dirty` の信頼指標性が失われ、誤コミットで全貢献者向けの tripwire を弱めるリスクがあるため。対象: `.claude/settings.json`、`CLOUD_BOOTSTRAP_PROMPT.md`、`CLAUDE.md`。
- **`--exact` を `definition` / `references` / `callers` / `callees` / `inspect` にも拡張 (#83)** — #81 で symbols に入れた大文字小文字無視の完全一致セマンティクスを、`cdidx definition`、`cdidx references`、`cdidx callers`、`cdidx callees`、`cdidx inspect` と対応する MCP ツール(`analyze_symbol` を含む)にも `exact` boolean として展開。`inspect` / `analyze_symbol` は bundle 内の全 sub-query(定義、参照、caller、callee)に `exact` を伝播するため、一発解決の AI ワークフローも leaf コマンドと同じ precision contract を維持する — `inspect Run --exact` が `RunAsync` / `RunImpact` を含んだ bundle を返すことは無い。述語は `s.name = @q COLLATE NOCASE` / `r.symbol_name = @q COLLATE NOCASE` / `r.container_name = @q COLLATE NOCASE` を使い、新規の `idx_symbol_refs_name_nocase` / `idx_symbol_refs_container_nocase` covering index を貼ることで multi-exact 検索も SARGable に保つ。AI クライアントが `symbols --exact` で名前を解決した後、definition / reference / call graph の追撃で substring に戻らざるを得なかった往復ロスを解消する。#81 の ASCII NOCASE 限定は引き続き適用される(非 ASCII の casing は畳み込まれず、Unicode fold は #86 で追跡)。対象: `src/CodeIndex/Database/DbReader.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`、`CLAUDE.md`。Closes #83.
- **`symbols` に `--exact` を追加し名前の正確な解決を可能に (#81)** — `cdidx symbols` と MCP の `symbols` が `--exact` / `exact: true` を受け付け、`LIKE %...%` の部分一致ではなく大文字小文字を無視した名前の完全一致で検索するようになった。AI クライアントが先行の `map` / `inspect` / `search` 結果から解決済みの候補リストを渡す場合、`Run` を指定しても `RunAsync` / `RunImpact` 等に広がらないため、クライアント側での後段フィルタが不要になりトークン出力も減る。繰り返しの `--name` や positional 名と組み合わせれば名前ごとの完全一致を OR 結合でき、既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-path`、`--exclude-tests`、`--since`、`--limit`)もそのまま適用される。既定挙動(部分一致)は変わらない。完全一致述語は `lower(col) = lower(@q)` ではなく `s.name = @q COLLATE NOCASE` を使い、新規の `idx_symbols_name_nocase` covering index を貼ることで multi-name exact 時にもフルスキャンにならず O(log n) × 名前数で解決する。大文字小文字無視は SQLite の `NOCASE`(ASCII 限定)に従うため、`Ä` / `ä` のような非 ASCII の casing 差分は畳み込まれない — 非 ASCII 識別子はインデックス時と同じ casing を渡すこと。Unicode fold の対応は #86 で追跡。対象: `src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Database/DbContext.cs`、`src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Cli/ConsoleUi.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #81.
- **`symbols` の複数名クエリ (#69)** — `symbols` が 1 回の呼び出しで複数のシンボル名を解決できるようになり、AI クライアントが候補リストをコマンドごとに分けて問い合わせる必要がなくなった。対応形式: 繰り返しの positional(`cdidx symbols A B C`)、繰り返しの `--name` フラグ(`--name A --name B`)。名前はサーバー側で OR 結合され、名前ごとの候補取得 + round-robin マージを `--limit` の範囲内で行うため、人気名が他を押し出すことなく `--limit` は従来どおり合計の上限として働く。`|` はシンボル名の文字として扱うので `operator |` のような演算子シンボルも検索可能。既存フィルタ(`--kind`、`--lang`、`--path`、`--exclude-tests`、`--since`)はそのまま適用される。MCP の `symbols` にも `names` 配列を追加。単一名呼び出しは従来どおり動作する完全な追加変更。対象: `src/CodeIndex/Cli/QueryCommandRunner.cs`、`src/CodeIndex/Database/DbSymbolReader.cs`、`src/CodeIndex/Mcp/McpToolHandlers.cs`、`src/CodeIndex/Mcp/McpToolDefinitions.cs`、`tests/CodeIndex.Tests/DbReaderTests.cs`、`README.md`。Closes #69.
Expand Down
Loading
Loading