Skip to main content
CodeSearch

Task-aware code search for coding agents

Explainable evidence. Scoped context. No runtime model.

CI PyPI Apache-2.0 license Python 3.11+ Agent Skill installers for seven agents Experimental status

English | 简体中文 | 日本語 | 한국어 | Русский


Code Search is a task-aware retrieval CLI for coding agents. It returns a concise, verifiable set of source evidence for an engineering task, not only a list of similar snippets.

The current version is an independently implemented, fully model-free MVP: no embeddings, no GPU, no server, and no network calls. It can read a working tree or any Git revision and returns source locations, ranking reasons, structural evidence roles, provenance, categorical confidence, and payload statistics.

Search less. Hand the agent the evidence it needs to act.

Quick start

Install from PyPI

uv tool install code-search-cli
code-search --version

The distribution is named code-search-cli; the installed command remains code-search.

Install from this checkout

cd /path/to/code-search
uv tool install .
code-search --version

Retrieve evidence for a task

code-search retrieve \
  --repo /path/to/repository \
  --task "Fix dependency injection order so startup events are not missed"

The command is read-only. It does not check out revisions, modify the target repository, or create an index inside it. It incrementally maintains a per-user SQLite index under the operating-system cache directory, honors Git ignore rules for working trees, and uses code-search clean to remove the cached source snapshot and derived metadata.

Optional agent integration

code-search install                  # Codex remains the default
code-search install --target cursor  # Or select one target explicitly

The bundled code-search Agent Skill can be installed for Codex, Claude Code, Cursor, Gemini CLI, OpenCode, GitHub Copilot, or Kiro. Installation is user-level and idempotent. It tracks hashes of the files it installed, so an untouched older release can upgrade safely while a locally modified skill is still protected unless --force is supplied. Add --dry-run to preview the operation. The CLI remains the primary interface; installing the skill adds neither an MCP server nor a runtime model.

Why there is no model underneath

Retrieval is deterministic, auditable, and runs entirely on lexical and structural signals: stemmed term matching, file-name coverage, structural expansion, and task-role inference. The same query on the same tree returns the same evidence, every result explains why it was included, and nothing is downloaded at runtime. Model-backed products appear in the public benchmark only as separately versioned comparison methods; they are not Code Search runtime dependencies.

What you get

  • A concise, de-duplicated evidence set instead of an unbounded list of matches.
  • Source locations, scores, inclusion reasons, evidence roles, provenance, categorical confidence, and estimated token cost for every result.
  • Lightweight structural obligations for lifecycle, event, dependency-ordering, and test evidence.
  • Direct reads from a working tree or historical Git revision without changing the checkout.
  • A persistent incremental index that verifies content hashes and reuses unchanged source terms and structural boundaries.
  • Optional code, tests, or config scope filters when a task does not need the whole repository.
  • Source indexing across C/C++, C#, Elixir, Go, Haskell, Java, JavaScript/TypeScript, Kotlin, Lua, PHP, Python, Ruby, Rust, Scala, shell/Bats, Swift, Zig, and common configuration formats.
  • Model-free structural extraction for Java/Kotlin/Scala, Python, and JavaScript/TypeScript on the default path.
  • Compact exact-symbol windows across all indexed source formats when the whole task is an identifier or qualified name.
  • A bundled Agent Skill, with user-level filesystem installers for Codex, Claude Code, Cursor, Gemini CLI, OpenCode, GitHub Copilot, and Kiro, that teaches the agent when to retrieve, expand, or fall back to exact rg. Their paths, dry-run behavior, idempotence, safe upgrades, and file-protection behavior have automated coverage.

Task evidence beyond ranked matches

A flat result list may return both a target function and a similar working function. For the callback patterns it currently supports, Code Search compares them and can label the behavior that is present in one path but absent from the other. For supported lifecycle patterns, it can also keep separate repair responsibilities in one evidence bundle.

Synthetic case Code Search task-evidence schema Neutral flat-result schema
Python callback using emit missing-behavior + comparison with reasons, provenance, and confidence source spans + score
TypeScript callback using dispatchEvent missing-behavior + comparison with reasons, provenance, and confidence source spans + score
Java/Spring-style startup lifecycle two explicit required repair site responsibilities + subscriber registration source spans + score

From a source checkout, run the synthetic fixtures:

uv run python scripts/showcase_evidence.py

The task-evidence contract documents the fixture and its generated output. This is a regression check, not a held-out quality benchmark or a patch-success claim.

CLI

Read a historical revision:

code-search retrieve \
  --repo /path/to/repository \
  --ref HEAD~1 \
  --task "Resolve NullPointerException in scheduled dump" \
  --format json

Limit a focused query to conventional test paths and filenames:

code-search retrieve \
  --repo /path/to/repository \
  --task "Find regression tests for field naming" \
  --scope tests

--scope accepts all (the default), code, tests, or config. It filters files before ranking; leave it at all when a task crosses production code, configuration, and tests.

Expand a known anchor to its enclosing unit, siblings, or references:

code-search expand \
  --repo /path/to/repository \
  --path src/main/java/example/Service.java \
  --line 120 \
  --relation enclosing

Manage the optional Agent Skill:

code-search install                                  # Codex
code-search install --target claude-code
code-search install --target cursor
code-search install --target gemini
code-search install --target opencode
code-search install --target github-copilot
code-search install --target kiro
code-search install --target detected                # Best-effort convenience selector
code-search install --target detected --dry-run      # Preview without writing
code-search uninstall --target cursor
code-search uninstall --target detected

The installer writes only managed Skill files and its hash manifest inside the selected agent's user configuration:

--target User-level destination
codex $CODEX_HOME/skills/code-search/ when set; otherwise ~/.agents/skills/code-search/
claude-code $CLAUDE_CONFIG_DIR/skills/code-search/ when set; otherwise ~/.claude/skills/code-search/
cursor ~/.cursor/skills/code-search/
gemini $GEMINI_CLI_HOME/.gemini/skills/code-search/ when set; otherwise ~/.gemini/skills/code-search/
opencode $OPENCODE_CONFIG_DIR/skills/code-search/ when set; otherwise ${XDG_CONFIG_HOME:-~/.config}/opencode/skills/code-search/
github-copilot $COPILOT_HOME/skills/code-search/ when set; otherwise ~/.copilot/skills/code-search/
kiro ~/.kiro/skills/code-search/

Agent-specific environment overrides must be absolute paths; a relative XDG_CONFIG_HOME is ignored as required by the XDG base-directory specification. An existing legacy Codex installation under ~/.codex/skills/code-search/ is updated and removed in place instead of being silently migrated.

detected is a best-effort convenience selector based on known commands, configuration directories, environment overrides, and an already-installed target. It does not launch a client or verify that the client can load the skill. Cursor detection deliberately relies on ~/.cursor rather than the ambiguous agent executable name. Because some clients also scan another client's compatibility directories, prefer an explicit target and use one if the same skill appears more than once.

Every selected destination is preflighted before writing or removing files. A small hidden manifest records hashes of the managed files; it is installer metadata, not another instruction loaded by the agent. This lets an untouched older installation upgrade without treating it as a user edit. Uninstall removes only managed files whose content is still recognized and leaves extra user files in place. Use --force only when you intentionally want to replace or remove a modified managed file. --dry-run performs the same checks and reports the planned action without changing files.

Prewarm, inspect, or remove the per-repository index:

code-search index --repo /path/to/repository
code-search status --repo /path/to/repository
code-search clean --repo /path/to/repository

Benchmark

The repository publishes two recorded development comparisons. Both measure Code Search, Semble, code-review-graph, BM25, Probe, and ripgrep. They use different datasets and adapters, so their scores must not be merged into one leaderboard. The shared Java runner supports all six methods; this publication reruns Code Search on the same pinned inputs and retains the other five recorded rows. The multilingual public runner currently reproduces BM25, Probe, and ripgrep, while the product rows retain their recorded implementation identities and per-task output. Both Code Search rows measure the same current source fingerprint, recorded in the machine-readable results.

Shared Java comparison

The primary comparison uses the same 61 public queries and relevance annotations over pinned Gson, Apache Commons Lang, and Jackson Databind revisions.

Six retrieval methods compared across quality, coverage, latency, and payload

Method NDCG@10 Recall@10 MRR@10 Setup Query p50 / p95 Mean Top-10 payload
Code Search 0.8468 0.9672 0.8207 1.908 s 16.75 / 57.18 ms 2,235 tok
Semble 0.8250 0.9754 0.7852 1.550 s 5.83 / 22.41 ms 1,803 tok
code-review-graph 0.7634 0.8607 0.7670 23.744 s 103.55 / 230.24 ms 16,161 tok
BM25 0.5686 0.7623 0.5398 1.449 s 1.47 / 3.16 ms 1,752 tok
Probe 0.2271 0.4754 0.1649 586.82 / 952.48 ms 4,295 tok
ripgrep 0.1977 0.2377 0.1904 32.52 / 61.40 ms 28,605 tok

No row wins every dimension. On these 61 queries, Code Search has the highest NDCG and MRR. Its mean payload is smaller than Probe, code-review-graph, and ripgrep, while Semble has slightly higher Recall, lower query latency, and a smaller payload; BM25 has the lowest query latency and payload.

NDCG@10 also changes by query type:

Query type Tasks Code Search Semble code-review-graph BM25 Probe ripgrep
Conceptual 33 0.8288 0.7869 0.7607 0.4855 0.1794 0.0000
Architecture 12 0.7044 0.7068 0.4877 0.5819 0.3044 0.0000
Symbol 16 0.9906 0.9923 0.9758 0.7301 0.2678 0.7539

The shared Java methodology and machine-readable results record exact tool commits, model revisions, repository revisions, adapter definitions, p95 values, per-query rows, and reproduction commands.

Multilingual diagnostic

The second comparison uses 30 fixed pre-fix tasks from eight public repositories and eight languages. Each language has only three or four tasks, so the heatmap locates weaknesses in this sample; it does not establish broad language support.

NDCG, Recall, and MRR by language for six retrieval methods

Method NDCG@10 Recall@10 MRR@10 Warm p50 Payload p50
Code Search 0.5093 0.7311 0.4603 28.2 ms 3,661 tok
Semble 0.5620 0.6700 0.5609 13.5 ms 1,750 tok
code-review-graph 0.3603 0.3800 0.3944 69.7 ms 734 tok
BM25 0.4973 0.7644 0.4663 0.9 ms 70,558 tok
Probe 0.3084 0.6133 0.2380 1,262.0 ms 6,982 tok
ripgrep 0.3954 0.7200 0.3009 473.0 ms 100,974 tok

Code Search is second on NDCG in this sample; its MRR is 0.0060 below BM25, and its payload is much smaller than the whole-file BM25 and ripgrep rows and the Probe row. Semble and code-review-graph still return less source per query. Probe returns AST blocks; its file order was identical across five repeated queries on 25 of 30 tasks. See the multilingual methodology and per-language results for the adapter definitions and complete records.

The aggregate hides a rough edge. Code Search records 0.0000 NDCG on the three Ruby tasks and 0.3499 on the three Rust tasks; its returned spans overlap 12 of 81 annotated line ranges. With only three or four tasks per language, these are debugging signals, not language-wide conclusions. The benchmark also cannot tell whether a miss began in query wording, file ranking, or structural extraction.

Both datasets are retrieval-only development data that have already been inspected. They do not generate patches, run project tests, or run agents. Native result units also differ—evidence spans, chunks, graph nodes, AST blocks, and whole files—so setup and payload describe the recorded adapters, not every capability of each product. Held-out product claims still require untouched tasks, executable patch tests, and repeated agent runs.

How Code Search fits

No retrieval approach is best for every query. The first four rows below generate candidates or index source relationships. Code Search builds on lexical candidates, applies lightweight structural inference, and organizes selected source as task evidence. It is an evidence layer, not a same-level replacement for every retrieval method.

Approach Typical question Typical output Main trade-off
Exact text or regex search Where does this identifier, error string, or literal occur? Matching lines or small windows Fast and deterministic, but depends on exact wording and does not infer missing behavior on its own
Lexical or full-text retrieval Which files share this vocabulary or path context? Ranked files or spans with lexical scores Explainable and model-free, but weaker on paraphrases and cross-file relationships
Embedding or hybrid chunk retrieval Which code expresses this natural-language concept? Semantically ranked code chunks Designed to recover conceptual matches, but adds model and index cost; chunk boundaries may omit surrounding evidence
Structural graph or symbol index Where is this symbol defined, referenced, or related? Definitions, references, relations, or traversals Strong for explicit relations, but depends on parser coverage, edge accuracy, and a correct starting anchor
Code Search task-evidence bundle Which evidence belongs in this bug, change, or review? De-duplicated source spans with task roles, reasons, provenance, confidence, and payload Task-role inference is lightweight and rule-based, and the result is not a compiler-grade program graph

These approaches complement each other. Exact search remains the right first tool for a known literal. Semantic retrieval helps with conceptual discovery, while a structural index is better for deep relation queries. Code Search focuses on deciding which implementation, test, configuration, registration, comparison, or repair site belongs in the evidence set for the task.

How it works

The engine incrementally caches source terms and structural boundaries, splits identifiers, expands engineering aliases, scores paths and content, identifies task-specific structural obligations, contrasts related sibling methods when a callback path is missing expected behavior, detects missing subscriber-initialization and dependency edges, expands selected anchors, packs non-duplicate evidence, and only then focuses long selected spans into query-aware output windows. The differentiating thesis is:

Return not only similar code, but the evidence subgraph required to answer the engineering task.

The retrieval path is a transparent lexical/structural engine. For an exact symbol-only query, a compact window is promoted only when the literal symbol appears directly after a common declaration keyword. The result remains a medium-confidence exact-text anchor, not a parser-verified definition. Task roles and structural conclusions are rule-based. Only Python structure extraction uses a parser today—the standard-library ast module. Java, Kotlin, Scala, JavaScript, and TypeScript use conservative declaration and brace rules; other indexed languages fall back to overlapping 48-line windows. Tree-sitter is not part of the current runtime, and these structural signals are not compiler-verified facts.

Documentation

Current limits

  • Structural depth varies by language. Indexing a source format does not mean Code Search has a complete AST or symbol model for it. Python uses ast; several JVM and JavaScript-family formats use lightweight rules; the remaining formats use line windows. References, overloads, and dynamic calls can therefore be ambiguous.
  • Long, narrative tasks remain uneven. The multilingual diagnostic shows that model-free lexical signals can find the right vocabulary without always ranking the right file or source range. This is separate from parser accuracy, so a stronger parser alone would not close every gap.
  • The public comparisons stop at retrieval. Both datasets are development data already inspected during retrieval work. They do not measure whether an agent produces the right patch or passes the project test suite.
  • The CLI lifecycle is stronger than the long-lived Python API. Each CLI command loads a fresh snapshot. A reused RetrievalEngine instance does not yet expose refresh or invalidate, and a moving historical branch or tag still causes a full revision rebuild.
  • Refresh cost still grows with repository size. Worktree commands verify eligible files with content hashes on every scan. Only changed files are decoded and reindexed, but there is no background watcher.

Possible evolution

These are experiment directions, not release promises. Each one must improve the same-input development measurements and then hold up on untouched tasks.

  1. Measure task success, not only retrieval. Publish at least 30 untouched, license-compatible tasks with executable patch tests and repeated agent runs, reporting ranking, latency, payload, and patch success together.
  2. Deepen structure one language family at a time. Evaluate parser-backed boundaries and a normalized symbol layer while retaining the current fallback. Tree-sitter is one candidate; it should be adopted only if boundary accuracy and retrieval improve enough to justify dependency, indexing, licensing, and distribution costs.
  3. Handle long tasks without hiding the reasoning. Test explainable query decomposition and path-, symbol-, and reference-aware ranking. Reduce warm-query tails and fixed Top-10 payload without lowering Recall or MRR; this is not a configurable token-budget feature.
  4. Add relations only where parsing is reliable. Definition, import, call, and inheritance edges can precede carefully measured multi-hop or impact analysis. A graph database is not a goal by itself.
  5. Harden non-CLI use. Add an explicit refresh lifecycle for long-lived Python callers and investigate incremental updates when a historical ref moves. Additional Agent integrations, MCP, and signed binaries remain conditional on a concrete, tested use case.

Status and independent implementation

This is a testable experimental MVP, not a production release. The public development benchmark measures retrieval, while the deterministic fixtures and tests cover output behavior and package quality. None of them proves held-out retrieval superiority or executable patch success. The implementation and bundled Agent Skill are independently designed around the task-evidence workflow.

License

Licensed under the Apache License 2.0.

Download files

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

Source Distribution

code_search_cli-0.3.1.tar.gz (145.4 kB view details)

Uploaded Source

Built Distribution

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

code_search_cli-0.3.1-py3-none-any.whl (45.9 kB view details)

Uploaded Python 3

File details

Details for the file code_search_cli-0.3.1.tar.gz.

File metadata

  • Download URL: code_search_cli-0.3.1.tar.gz
  • Upload date:
  • Size: 145.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for code_search_cli-0.3.1.tar.gz
Algorithm Hash digest
SHA256 e9a0c0983d2f36225efc6240c92cfa3279534d88f937e07d3761e0d48b912c80
MD5 dd27f45b2ad3eaf12c92cfda6bd51720
BLAKE2b-256 c569e62c75dd85a5c95cbb518115bcaad8cff1e9ccde1862e80be18313b06c84

See more details on using hashes here.

File details

Details for the file code_search_cli-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: code_search_cli-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 45.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for code_search_cli-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2711a1a8fda65e925d65927bd379694addda0a352549d2606c6aa6a8a3c6eb9b
MD5 496cf09e32610ac715eaa424408108f6
BLAKE2b-256 52e8aecaa84dd0b4898c00fd8a7d1d0457afa26e43f3ca2a8d5d8d13b10f9203

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page