# asrch
`asrch` is a search CLI for coding agents. It is designed to prevent large
search results from consuming agent context and token budgets.
See the [Japanese section](#日本語) for the Japanese version.
## Requirements
- Rust 1.85 or later
- `rg` (`ripgrep`) available in `PATH`
## Installation
```sh
cargo install asrch
```
## Codex Plugin
The CLI is published through crates.io. The Codex workflow is distributed as a
plugin in this repository.
After adding this repository as a Codex plugin marketplace, install the
`asrch-search` plugin from the plugin browser:
```sh
codex plugin marketplace add rnisi621/asrch
```
The marketplace catalog is [.agents/plugins/marketplace.json](.agents/plugins/marketplace.json),
and the plugin bundle is [plugins/asrch-search](plugins/asrch-search).
## Basic Workflow
`asrch` narrows a search in stages instead of printing large amounts of matched
text immediately.
1. `survey`: compare candidate terms and candidate paths.
2. `scout`: inspect the directory and file distribution of one selected term.
3. `sample`: inspect nearby match cluster ranges in one explicit file.
4. `show`: print snippets from one explicit file or context around one line.
For source code, symbol tools such as Serena are normally preferred.
For source code, the expected workflow is to identify candidate files with
`sample` and then use Serena's symbol tools instead of repeatedly calling
`show`. `asrch` handles broad exploration and narrowing, Serena handles
functions, types, and references, and `show` handles documentation,
configuration, and other files that cannot be inspected as symbols.
`survey` and `scout` use a compact TOON
(Token-oriented object notation)-like output.
```sh
asrch survey \
--term AuthConfig \
--term auth_config \
--term load_config \
--term token \
src tests docs \
--identifier
```
Example output:
```text
survey:
terms: 4
paths: 3
mode: identifier
overall[term,matches,files,dominant_path]:
AuthConfig,8,3,src
auth_config,5,2,src
load_config,2,1,src
token,14,6,src
by_path:
src[term,matches,files,top_directory]:
AuthConfig,8,3,auth
auth_config,5,2,auth
load_config,2,1,config
token,10,4,auth
tests[term,matches,files,top_directory]:
token,4,2,auth
next: choose one useful term and path, then run asrch scout
```
This result suggests `AuthConfig` and `src/auth`, so the next command uses one
term and one path.
```sh
asrch scout AuthConfig src/auth --identifier
```
Example output:
```text
scout:
query: AuthConfig
path: src/auth
mode: identifier
matches: 8
files: 3
top_directories[path,matches]:
.,8
top_files[path,matches]:
config.rs,4
session.rs,3
mod.rs,1
next: narrow the path, then use asrch sample
```
Inspect cluster ranges to select a file and line to read.
```sh
asrch sample AuthConfig src/auth/config.rs --identifier --clusters 3 --page 1
```
Example output:
```text
sample: query="AuthConfig" path=src/auth/config.rs mode=identifier matches=4 files=1 clusters=2 page=1/1 selected=2
clusters[index,range,hits,first,last]:
1,12..12,1,src/auth/config.rs:12:12,src/auth/config.rs:12:12
cluster 1 first:
-- src/auth/config.rs:12:12
11 |
> 12 | pub struct AuthConfig {
13 | pub token_ttl_seconds: u64,
cluster 2 first:
-- src/auth/config.rs:44:21
43 | impl AuthConfig {
> 44 | pub fn from_env() -> Self {
45 | Self::load()
```
For source code, use Serena's `get_symbols_overview`, `find_symbol`, and
`find_referencing_symbols` at this point to inspect functions and types. Use
`show` for documentation, configuration, or files that Serena cannot handle.
```sh
asrch show AuthConfig docs/authentication.md --identifier --line 18 --context 2
```
Example output:
```text
show: query="AuthConfig" file=docs/authentication.md mode=identifier matches=2 context=2
-- docs/authentication.md:18:5
16 | ## Configuration
17 |
> 18 | AuthConfig controls token lifetime and refresh behavior.
19 | It is loaded during service startup.
20 |
```
## Commands
| Command | Purpose |
| --- | --- |
| `survey --term ... [path ...]` | Compare up to 12 terms across up to 8 paths without printing matches. |
| `scout <query> [path]` | Summarize match counts, top directories, and top files. |
| `sample <query> <file>` | Page through nearby match ranges and short context from one explicit file. |
| `show <query> <file>` | Show small snippets from one explicit file or context around one line. |
## Search Modes
Queries are fixed strings by default. Regex search is enabled only with
`--regex`.
| Option | Meaning |
| --- | --- |
| none | Fixed-string substring search |
| `--identifier` | ASCII identifier-boundary search |
| `--word` | Word-boundary fixed-string search |
| `--regex` | Regex search for single-query commands |
`scout`, `sample`, and `show` reject unescaped OR regexes. Use `survey --term`
to evaluate candidate terms before continuing with `scout`.
## Safety Rules
- The CLI is read-only and does not modify searched repositories.
- Every output line is clipped to 800 bytes.
- Output volume is structurally bounded:
- `survey` accepts at most 12 terms and 8 paths and prints counts only.
- `scout` prints matching-line counts for the top five directories and files
in the selected path.
- `sample` clusters matches and prints at most 5 clusters per page. Use
`--page` to select another page.
- `show` is limited to one explicit file, at most 20 matching lines, and at
most 5 context lines. With `--line N`, only context around that line is
shown.
- Without `--line N`, `show` attempts to print all selected matches, but prints
no snippets if there are more than 20 matching lines or the internal scan
limit is reached.
- `sample` reports each cluster's range, hit count, first match, and last match.
Use `show --line N --context M` to inspect the middle of a long cluster.
- `scout`, `sample`, and `show` reject queries containing an unescaped `|` when
`--regex` is used.
- `.git`, `target`, `node_modules`, logs, JSONL/XML files, generated files, and
scratch directories are excluded by default.
## Documentation
- CLI behavior: [Japanese](docs/cli_behavior.md) / [English](docs/cli_behavior.en.md)
- Agent skill: [skills/asrch-search/SKILL.md](skills/asrch-search/SKILL.md)
## Development
```sh
cargo fmt --all -- --check
cargo test
cargo clippy --all-targets -- -D warnings
```
---
# 日本語
`asrch` は、コーディングエージェント向けの安全な検索 CLI です。大量の検索結果がコンテキストへ流れることによるトークンの浪費を防ぐように設計しています。
## 要件
- Rust 1.85 以降
- `rg` (`ripgrep`) が `PATH` に存在すること
## インストール
```sh
cargo install asrch
```
## Codex Plugin
CLI 本体は crates.io で配布します。Codex 用の workflow は、このリポジトリ内の plugin として配布します。
このリポジトリを Codex plugin marketplace として追加した後、plugin browser から `asrch-search` をインストールしてください。
```sh
codex plugin marketplace add rnisi621/asrch
```
marketplace catalog は [.agents/plugins/marketplace.json](.agents/plugins/marketplace.json)、plugin bundle は [plugins/asrch-search](plugins/asrch-search) です。
## 基本ワークフロー
`asrch` は、検索結果の本文をいきなり大量に出すのではなく、次の順序で探索範囲を狭めるための CLI です。
1. `survey` : 複数の候補語と候補パスを比較
2. `scout` : 選んだ 1 語についてディレクトリ・ファイル分布を確認
3. `sample` : 明示した 1 ファイルから近接一致クラスタの範囲を確認
4. `show` : 指定した 1 ファイルの snippet、または指定行周辺を表示(通常serena等を優先して使用)
ソースコードを読む場合、`show` を繰り返すより、`sample` で候補ファイルを見つけた後に Serena の symbol ツールへ進むことを想定しています。`asrch` は広い探索と候補の絞り込み、Serena は関数・型・参照の読解、`show` は docs や設定ファイルなど symbol 化できない対象の確認に向いています。
`survey` と `scout` は、トークン消費を抑えるため TOON (Token-oriented object notation) ライクな形式で出力します。
```sh
asrch survey \
--term AuthConfig \
--term auth_config \
--term load_config \
--term token \
src tests docs \
--identifier
```
出力例:
```text
survey:
terms: 4
paths: 3
mode: identifier
overall[term,matches,files,dominant_path]:
AuthConfig,8,3,src
auth_config,5,2,src
load_config,2,1,src
token,14,6,src
by_path:
src[term,matches,files,top_directory]:
AuthConfig,8,3,auth
auth_config,5,2,auth
load_config,2,1,config
token,10,4,auth
tests[term,matches,files,top_directory]:
token,4,2,auth
next: choose one useful term and path, then run asrch scout
```
ここでは `AuthConfig` と `src/auth` が有望だと分かるので、単一語・単一パスに狭めます。
```sh
asrch scout AuthConfig src/auth --identifier
```
出力例:
```text
scout:
query: AuthConfig
path: src/auth
mode: identifier
matches: 8
files: 3
top_directories[path,matches]:
.,8
top_files[path,matches]:
config.rs,4
session.rs,3
mod.rs,1
next: narrow the path, then use asrch sample
```
近接一致クラスタの範囲だけを見て、読むべきファイルと行を決めます。
```sh
asrch sample AuthConfig src/auth/config.rs --identifier --clusters 3 --page 1
```
出力例:
```text
sample: query="AuthConfig" path=src/auth/config.rs mode=identifier matches=4 files=1 clusters=2 page=1/1 selected=2
clusters[index,range,hits,first,last]:
1,12..12,1,src/auth/config.rs:12:12,src/auth/config.rs:12:12
cluster 1 first:
-- src/auth/config.rs:12:12
11 |
> 12 | pub struct AuthConfig {
13 | pub token_ttl_seconds: u64,
cluster 2 first:
-- src/auth/config.rs:44:21
43 | impl AuthConfig {
> 44 | pub fn from_env() -> Self {
45 | Self::load()
```
コードファイルであれば、この段階で Serena の `get_symbols_overview`、`find_symbol`、`find_referencing_symbols` を使って関数・型単位で読む方が高効率です。docs、設定ファイル、または Serena が扱えないファイルでは `show` を使います。
```sh
asrch show AuthConfig docs/authentication.md --identifier --line 18 --context 2
```
出力例:
```text
show: query="AuthConfig" file=docs/authentication.md mode=identifier matches=2 context=2
-- docs/authentication.md:18:5
16 | ## Configuration
17 |
> 18 | AuthConfig controls token lifetime and refresh behavior.
19 | It is loaded during service startup.
20 |
```
## コマンド
| コマンド | 目的 |
| --- | --- |
| `survey --term ... [path ...]` | 最大 12 語を最大 8 パスで比較し、一致本文は表示しない |
| `scout <query> [path]` | 一致件数、上位ディレクトリ、上位ファイルを要約する |
| `sample <query> <file>` | 明示した 1 ファイルから、近接一致クラスタの範囲と短い文脈をページ表示する |
| `show <query> <file>` | 明示した 1 ファイルから小さな snippet、または指定行周辺を表示する |
## 検索モード
検索語は既定で固定文字列として扱います。正規表現は `--regex` を明示した場合だけ使います。
| オプション | 意味 |
| --- | --- |
| なし | 固定文字列の部分一致 |
| `--identifier` | ASCII 識別子境界付き検索 |
| `--word` | 単語境界付き固定文字列検索 |
| `--regex` | 単一クエリ系コマンドの正規表現検索 |
`scout`、`sample`、`show` はエスケープされていない OR 正規表現を拒否します。`survey --term` を使って候補語の有効度を推定してから `scout` 以降に進む設計です。
## 安全性
- CLI は read-only で、検索対象のリポジトリを変更しません。
- すべての出力行は最大 800 バイトに切り詰めます。
- 出力されるテキストの量は構造的に抑えられます。
- `survey` では最大 12 語 / 8 パスを受け取って出現回数のみ出力します。
- `scout` では指定パス内の上位 5 ディレクトリ / 5 ファイルについて、一致行数を出力します。
- `sample` では出現箇所をクラスタリングし、最大 5 クラスタずつ出力します。別な箇所を見たいときは `--page` で指定可能です。
- `show` は明示ファイル、最大 20 一致行、最大 5 context 行で構造的に出力量を抑えます。`--line N` 指定時は指定行周辺だけを表示します。
- `show` は `--line N` を指定しない場合全てを出力しようとします。ただし、一致が 20 行を超える場合、または内部走査上限に達した場合、snippet を表示しません。
- `sample` は各クラスタの行範囲、ヒット数、先頭・末尾一致を表示します。長いクラスタの途中を見たい場合は、範囲内の行を `show --line N --context M` で開きます。
- `scout`、`sample`、`show` は、`--regex` 指定時にエスケープされていない `|` を含む OR 正規表現を拒否します。
- `.git`、`target`、`node_modules`、ログ、JSONL/XML、生成物、scratch 領域などを既定で除外します。
## ドキュメント
- CLI の挙動: [日本語](docs/cli_behavior.md) / [English](docs/cli_behavior.en.md)
- Agent Skill: [skills/asrch-search/SKILL.md](skills/asrch-search/SKILL.md)