Skip to content

Code search and the index

Each committed snapshot is indexed into an index generation. Search reads only the active generation of each connected source.

  • Text chunks. Code is split at blank lines into pieces of at most 60 lines. Markdown is split at headings. Every chunk keeps its file path and line range.
  • Symbols. Function, class and type definitions in Python, JavaScript, TypeScript, Go, Java, Kotlin, C#, Rust, PHP, Ruby, Swift, Scala, Dart, C and C++, found by line patterns, without running a parser. Names can be written in any script, for example müşteri_bul or 注文を探す. Files in other languages are still covered by full-text and semantic search.
  • Dependency facts. Declared packages and versions, read from package.json, package-lock.json, pyproject.toml, requirements*.txt, uv.lock and poetry.lock. Node and Python versions are read from engines, .nvmrc, .node-version, .python-version and .tool-versions.

The index reports what it could not use; these files are never silently skipped:

Gap Meaning
Manifest could not be parsed A package.json or pyproject.toml is malformed. Facts for that ecosystem are unknown, not “none”.
Not evaluated The file needs execution to read, for example setup.py.
Not analyzed yet Go and Rust manifests, yarn.lock and pnpm-lock.yaml are recorded but not analyzed yet.
Very long lines Lines longer than 2,000 characters usually mean minified or generated code, which is not indexed.
State Meaning
Indexing A new generation is being built. The previous one, if any, stays searchable.
Partial Exact and full-text search work. Semantic search is not available for this generation.
Current All search lanes are available.
Stale A newer snapshot is being indexed. Results still come from the older one.
Failed Indexing stopped. The previous generation, if any, stays active.

A new generation replaces the old one in a single step, and only if its snapshot is still the newest and its source is still connected. If two snapshots are committed quickly, only the newer one becomes active.

Search runs up to three independent lanes and combines their rankings (reciprocal-rank fusion):

  1. Exact. Symbol names and file paths. Search lookupOrder or tools.ts.
  2. Full text. Words in the code and documents, in any language:
    • Search terms of three or more characters also match longer words, so iade finds iadeleri.
    • Text written without spaces between words, such as Chinese, Japanese or Thai, is matched by overlapping pairs of characters, so a word inside a sentence is found.
  3. Semantic. Meaning-based matches, so a plain-language question can find the code that answers it. Accepted text is embedded with Google’s Gemini embedding model (gemini-embedding-2, 768 dimensions). If embedding is unavailable, the index stays partial and the other two lanes still work.

Every result names its source, file path, line range, snapshot and commit (when known), so you can open the exact lines.

Code search has a page of its own. It is not in the sidebar: you reach it from Tracing’s Find in code (on the function or file a step ran, at its line), from a session’s work panel (Context → Open Code search), and from a coding host over MCP (context_search, code_refs, context_read).

  • Search by: All (the three lanes above), Meaning (semantic only; full text when embeddings are not available), Path (file paths that contain the words) or Symbol (names that are, or start with, what you type). Under a path narrows any of them, for example to src/.
  • Ref: the branch or commit of a GitHub repository, or an upload, that you search. An application also offers the refs of the sessions an owner or admin linked to it. Members, admins and owners can index another branch or commit of the application’s GitHub repository (up to six refs) and re-index a ref to read it again.
  • Freshness: each ref says which commit it indexed and when, and whether the branch has moved on since (the head WeHarness last read from GitHub). Opened from a trace, the page also says when the trace ran another commit than the index reads, or did not say which one.
  • Open file shows the file read-only, with line numbers and the result’s lines marked.
  • Add to a session puts the lines (up to 200) in a session’s message box as a reference, with the commit. Nothing is sent until you send the message; the agent reads them as repository content.

Search answers only for members of the workspace. When a source is disconnected, its results disappear from the next query, before any data is purged. If the index changes in the middle of a search, the search returns an error and asks you to search again; it never mixes old and new results.