Skip to main content

Fast, dependency-free workspace search, read, and list exploration for coding-agent tools with Rust backend

Project description

codetool-explore

codetool-explore is a workspace exploration library built for coding-agent harnesses: fast content search, fast filename/path discovery, read-only file viewing, compact structured results, and predictable token usage.

  • Agent-first API: one public explore() call with target="content", "path", "content_or_path", "read", or "list".
  • Performance-oriented: dependency-free Python fallback plus optional Rust CLI acceleration for literal and regex content/path search.
  • Token-compressed output: compact result keys by default for search, tree-compressed text by default for list, plain text by default for read, result_format="text" for raw RTK-style text, and result_format="full" for the uncompressed backend shape.
from codetool_explore import explore

content = explore("UserService", root=".", mode="files")
paths = explore("service", root=".", target="path", glob="*.py")
mixed = explore("UserService", root=".", target="content_or_path")
scoped = explore("search_workspace", root=["src", "webapp", "tests"], regex=False)
snippet = explore("README.md", root=".", target="read", start_line=20, limit=40)
listing = explore("src", root=".", target="list", limit=100)

Patterns are regexes by default, so alternation works without extra flags:

explore("Maximum number of results|Text or regex pattern", root="tests")

Pass regex=False for exact literal matching.

For maximum token compression, request raw text:

print(explore("UserService", root=".", regex=False, result_format="text"))

Raw text omits backend/totals metadata, groups repeated path prefixes in a small tree, crops long snippets/context aggressively, and prints No Match for empty results. It includes a compact pagination header only when another page exists:

-- more: cursor=50
src/
 a.py

Raw mode grammar:

  • mode="files": matching filenames only.
  • mode="count": path xN, where N is the per-file count.
  • mode="snippets": path:line:text without context, or tree-grouped files where line:text marks a match and other indented text is surrounding context. With target="content_or_path", path-only matches are returned as filename rows.

API

explore(
    pattern,
    root=".",               # path, file, or non-empty list/tuple of paths
    target="content",       # "content", "path", "content_or_path", "read", or "list"
    regex=True,             # set False for literal search
    path_scope="path",      # "path" or "basename" for path matching
    glob=None,
    exclude=None,
    case="smart",
    mode="files",          # "files", "snippets", or "count"
    context_lines=0,
    limit=50,
    cursor=None,
    start_line=1,           # first line for target="read"
    backend="auto",        # "auto", "python", "rust"/"native"
    result_format=None,     # default compressed for search, text for read, tree text for list
)

target="content" searches file contents. target="path" searches relative file paths without opening file contents. target="content_or_path" returns files matching either target and marks each row with its match kind. mode="snippets" supports target="content" and target="content_or_path"; path-only rows under target="content_or_path" are returned without line/snippet fields.

target="read" treats pattern as one known file path, resolves relative paths under each root, and returns plain text with no line-number prefixes. When more than one file is read, each file is prefixed by a compact path: header. Use start_line and limit to cap the returned line range; if more lines remain, text output starts with -- more: cursor=N. CSV files are read as ordinary text. Binary-looking, missing, unreadable, or directory paths fail with controlled ExploreError subclasses. If root is already a file, target="read" reads that file directly, so accidental search-like pattern values from tool calls still produce the requested line range.

target="list" treats pattern as one file/directory path and returns one directory level under each root. Text output uses the same compact tree display as raw search output when that saves tokens, appending each root's listing in root order. Directories end with /; file paths are returned as one entry. It honors multi-root common-base paths, glob, exclude, ignore files, limit, and cursor. Read/list use the pure-Python stdlib implementation even when backend="auto" or "rust" is requested.

backend="auto" uses the Rust helper when present, then falls back to pure Python. Regex searches use Rust when supported by its regex engine and fall back to Python for compatibility, including Python re.finditer counts for patterns that can match empty spans.

root accepts str | os.PathLike | Sequence[str | os.PathLike]. It may be a workspace directory, a single file, or a non-empty list/tuple of directories and files:

explore("search_workspace", root=["src", "webapp", "tests"], regex=False)

When calling through JSON/tool schemas, pass multi-root values as a JSON array, for example "root": ["src", "webapp", "tests"]. For resilience with coding agents, a space-delimited string such as "root": "src webapp tests" is also treated as multiple roots when that exact path does not exist and every split token is an existing file or directory. Existing paths with spaces still take priority; quote individual spaced paths if combining them in one string.

File roots search/read only that file and report paths relative to the file's parent directory; listing a file path returns one file entry. Multi-root searches/reads/listings report paths relative to the roots' common base, so sibling roots keep prefixes such as src/... and tests/...; this also lets exclude=["src/generated/**"] target one root.

Controlled failures raise ExploreError subclasses:

  • ExploreArgumentError for invalid arguments.
  • ExplorePatternError for invalid/unsupported patterns.
  • ExploreRootError for missing or unsearchable roots.
  • ExploreBackendError for backend runtime failures.

CLI

codetool-explore "UserService" . --literal --format text
codetool-explore "service" . --target path --literal
codetool-explore "User(Service|Repository)" --root src --mode snippets --raw
codetool-explore "search_workspace" --root src --root webapp --root tests --literal
codetool-explore --read README.md --start-line 20 --limit 40
codetool-explore --read settings.py --root src --root tests
codetool-explore --list . --root src --root tests --glob "*.py"

The CLI defaults to compact JSON for search, plain text for --read, and tree-compressed text for --list. Use --format text or --raw for raw search text; no search matches print No Match. Repeat --root for multiple search/read/list roots. A single quoted space-delimited --root is accepted as a compatibility fallback when it can be split into existing roots.

Install

uv install codetool-explore

Wheels can include a platform-specific Rust helper. Without it, the package still works through the Python stdlib backend.

Benchmarks

Reproduce and refresh the generated README data:

cargo build --release --manifest-path rust/Cargo.toml
uv run python benchmarks/benchmark_search.py \
  --output reports/search_benchmark.json \
  --update-readme
uv run python benchmarks/benchmark_output_lengths.py \
  --output reports/rtk_vs_codetool_output_lengths.json
uv run python scripts/update_readme_benchmarks.py \
  --performance reports/search_benchmark.json \
  --tokens reports/rtk_vs_codetool_output_lengths.json

Execution performance

Mean of median wall-clock timings across 5 corpora × 7 scenarios, 5 measured rounds after 1 warmup.

Tool Mean median time Chart
codetool-explore 127.0 ms ███████████░░░░░░░
rg 138.2 ms ████████████░░░░░░
rtk 199.7 ms ██████████████████

codetool-explore is the fastest tool in this run.

Source: reports/search_benchmark.json.

Token compression

Token counts use tiktoken when available. The table compares output across 7 RTK-corpus scenarios.

Output Tokens Bytes Chart
codetool-explore 11,008 34.3 KB ██░░░░░░░░░░░░░░░░
rtk grep stdout 19,646 60.1 KB ███░░░░░░░░░░░░░░░
rg stdout 129,775 402.4 KB ██████████████████

codetool-explore is raw text from explore(..., result_format="text"); it omits backend/totals metadata, includes only a cursor hint when truncated, and prints No Match for empty pages. It is 0.56× the rtk grep token count in this run.

Source: reports/rtk_vs_codetool_output_lengths.json.

Development

uv run pytest
uv run python scripts/package_rust_binary.py
uv build --wheel

Release wheels are built in CI with the staged Rust helper for each target platform.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codetool_explore-0.7.1.tar.gz (107.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

codetool_explore-0.7.1-py3-none-win_arm64.whl (861.7 kB view details)

Uploaded Python 3Windows ARM64

codetool_explore-0.7.1-py3-none-win_amd64.whl (929.6 kB view details)

Uploaded Python 3Windows x86-64

codetool_explore-0.7.1-py3-none-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

codetool_explore-0.7.1-py3-none-macosx_10_12_x86_64.whl (1.1 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file codetool_explore-0.7.1.tar.gz.

File metadata

  • Download URL: codetool_explore-0.7.1.tar.gz
  • Upload date:
  • Size: 107.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for codetool_explore-0.7.1.tar.gz
Algorithm Hash digest
SHA256 8f14588378b17cccad0d3eb25c98149700bd870f52359f0da35ff09aed44f9f9
MD5 ad4771be0ed88376070ee7937b8f52ea
BLAKE2b-256 52bd0595788b435b3abe07f4f1a69f41f348ad26f19d9b963472d22f35e85eaf

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.1.tar.gz:

Publisher: release.yml on pbi-agent/codetool-explore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codetool_explore-0.7.1-py3-none-win_arm64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.1-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 42cf451869ed9231fb3fc7ce763dae2af023b9c88668f8a43a0f486570895bf0
MD5 100845a50fdedaef32ffcb473875d6b5
BLAKE2b-256 e76009cc394d1a7d6a648fa4750f48af7b56152abba2f9f824cd222f6cfe9233

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.1-py3-none-win_arm64.whl:

Publisher: release.yml on pbi-agent/codetool-explore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codetool_explore-0.7.1-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 dd7d88676b7fe28c1f5d900216f18027279936c7eff264b432e54907d8a79cd1
MD5 c2b5678a58df48b989f40b1a95567f3f
BLAKE2b-256 74b4959976aba7ac5b8cc5b0ca1212794df8f68b69de5476b6463b79b57d74de

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.1-py3-none-win_amd64.whl:

Publisher: release.yml on pbi-agent/codetool-explore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codetool_explore-0.7.1-py3-none-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.1-py3-none-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d176e36afee92a3736da799bbd3b53e26684b00a2c1b0b9b11ee8f77ab49ad77
MD5 db278a19854c44a3ebab6262d6a7d4d1
BLAKE2b-256 9a28d42a83d0114779c2af3d9b5de1a7aea65e5480b051d7e55b552db3919212

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.1-py3-none-manylinux2014_x86_64.whl:

Publisher: release.yml on pbi-agent/codetool-explore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codetool_explore-0.7.1-py3-none-manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.1-py3-none-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2d84673cb91bfca54a3dca8e2626deeaeccaf960045b009b963a79289ebf2bd0
MD5 3ab5fa8c885c473f0cdd35ef656b4e7d
BLAKE2b-256 0ed72ff2ff80e3ddcd135c537799cd379fb53f000e8bff6dedb743ab0bdf4941

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.1-py3-none-manylinux2014_aarch64.whl:

Publisher: release.yml on pbi-agent/codetool-explore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codetool_explore-0.7.1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 aed7ac8926d7f8fcd56dda1d408da4a702b66d4c0dac6f93833725bd3a7dc121
MD5 4315b5dedc9d0ac13b9f97b38ca73dc8
BLAKE2b-256 2ba6772613ed25cc7d0a9be2f0b3400ef59b1df6a1be8ab2d5957b241bf388bb

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.1-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on pbi-agent/codetool-explore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codetool_explore-0.7.1-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 43eebd6a0ffe68e1efd1d8fc5ef59e8f4fb0d8260fb3dd7afc953148d1d245a1
MD5 dc7a5f110855d12db60d6ae86afc3565
BLAKE2b-256 77334a6696124ce2fbb936c2403db8530690836989bd53ba6ed0cb1534175c02

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.1-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on pbi-agent/codetool-explore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page