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.0.tar.gz (106.7 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.0-py3-none-win_arm64.whl (867.5 kB view details)

Uploaded Python 3Windows ARM64

codetool_explore-0.7.0-py3-none-win_amd64.whl (932.8 kB view details)

Uploaded Python 3Windows x86-64

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

Uploaded Python 3macOS 11.0+ ARM64

codetool_explore-0.7.0-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.0.tar.gz.

File metadata

  • Download URL: codetool_explore-0.7.0.tar.gz
  • Upload date:
  • Size: 106.7 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.0.tar.gz
Algorithm Hash digest
SHA256 69d64e991c65f3329a1e490283fa8338c0c381db18e5e94c2230dce01042ea0b
MD5 04611e3750070dc378ede9e3767dd1a4
BLAKE2b-256 e9767dc005076203bcb715e3bcb1c5122ba73529f2769589afa66d74eb881126

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.0.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.0-py3-none-win_arm64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 ee027c6ae8c34dff2312c3f518255ab75511f2a60d53ff2c9c91b85a8287b305
MD5 e1ea3d49b9197e9403283f7d3668835d
BLAKE2b-256 d817d8673c237f94fc69ff7e004075de9ebb932bb95f214247f6d9710ccd6009

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.0-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.0-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 d17b09d4b737609d424b17a6c7ff929367f9a3c0b2b79be400fd991d8755fc2b
MD5 64f56d1254f93d85cc66ddbdeb128cf5
BLAKE2b-256 6fda5a74d807d2453c82716654d3ffd6ea3e7dcf5bd225cb66aa6d68475df3a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.0-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.0-py3-none-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.0-py3-none-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c4e8f840b01a417dea8351ea2bc55ade5e22015bc1e6c06d459c9cad3e1c8851
MD5 662a835c5ffa321aa11314365953fb57
BLAKE2b-256 b5517a4df9c69dc30d7fb3a585160b55b6491d5a10c44a2a942e629601ac360e

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.0-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.0-py3-none-manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.0-py3-none-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d5f5ad4784fcacf12d4f81a4eead0fc9d0e89f8fcbcb1e8e568e415e9073fe98
MD5 7eb44f25a22f387c3eb8e65f5572003c
BLAKE2b-256 0fad555c422b25abd7c10d5693e6fa4363801e91da3f4d3646b176a274238b8e

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.0-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.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 854845f65c2cbce1be9b1364e74ad8f96bfa01152be1d1d9c2aa601a3c64edcf
MD5 b65adf9773584aff6b18dde930b9e420
BLAKE2b-256 5e4eb177d60934f3f10d2d67ba3b0d79107c54f79d4763adde377c5f3f089e22

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.0-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.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for codetool_explore-0.7.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0eea181d0cc614b90aee96978280f08b70253c162e1b8cd1a6bbe32c620a8d60
MD5 c314bec631f7bb392d0fa38c64fc5d8b
BLAKE2b-256 af3eaed80c81bdd02446cdb91b82bd9b938837928e622fd2a55d33d5074d3bd6

See more details on using hashes here.

Provenance

The following attestation bundles were made for codetool_explore-0.7.0-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