docs
Concepts

Code intelligence

How nima indexes your repositories and what search_code, blast_radius and get_data_model can tell an agent, with their freshness limits.

Code intelligence is nima's index of your connected GitHub repositories. It powers three read-only tools: search_code (where something lives), blast_radius (what a change touches) and get_data_model (what the data looks like). Specs, the Slack assistant and coding agents use the same index to ground their answers in your code.

Availability

On for every workspace. Indexing starts by itself once GitHub is connected. The three tools are declared under the plan feature code_intelligence; a workspace whose plan lacks it can get 403 INSUFFICIENT_PERMISSIONS with details.feature set to code_intelligence, so handle that response.

The index returns file paths, summaries, symbol names and line ranges. It never returns file contents. Read the file itself from your checkout. Tool parameters are on Knowledge tools; the HTTP routes are on Code API.

When nima indexes a repository

nima indexes a repository when GitHub is connected, when a repository is added to the installation, and on every push to the repository's default branch. Pushes to any other branch never trigger indexing, so work on a feature branch is invisible until it merges.

EventWhat nima does
GitHub connectedQueues a full index for every repository the installation can see.
Repository added to the installationQueues a full index for that repository.
Push to the default branchQueues an incremental index from the last indexed commit, if the repository's index is ready. A repository whose index is still pending, indexing or failed is skipped until a full index succeeds.
Push to any other branch, or a tagIgnored.

Only a repository whose index is ready is searched. A repository that is still pending, indexing or failed appears in the repository list of a search_code response but returns no hits.

A repository added after GitHub was connected is set up to index a branch named main, and nima indexes pushes to main only. If the repository's default branch has another name, its index fails, or it indexes a stale main. A re-index does not change the branch. Ask the nima team to correct it.

Index failures and the manual re-index route

After 2 consecutive failed index runs, the next push to the default branch runs a full index instead of an incremental one. After 3 consecutive failures, nima stops indexing on push for that repository until someone re-indexes it by hand.

The manual route is POST /v1/code-intel/repositories/:id/reindex. It needs a signed-in owner or admin session: API keys and OAuth tokens are refused, and the admin panel has no button for it, so ask the nima team if you need one. It accepts one re-index per repository per 24 hours. A second call returns 429 with retryAfterSeconds and nextAllowedAt. The response is { "status": "queued" }, or { "status": "already_queued" } when a job is already waiting, which does not use up the daily slot.

Languages and files in the code index

The code index covers 22 file extensions and a fixed set of documentation files. Everything else is skipped.

Code files, parsed for symbols and imports:

.ts .tsx .js .jsx .mjs .cjs .py .go .java .swift .php .cs .rs .c .h .cpp .cc .cxx .hpp .hh .hxx .sol

That is TypeScript, JavaScript, Python, Go, Java, Swift, PHP, C#, Rust, C, C++ and Solidity. Symbol kinds in results are function, class, interface, type, enum, route, entity and decorator.

Documentation files, indexed with a summary but no symbols:

  • README.md, ARCHITECTURE.md, CONTRIBUTING.md, CHANGELOG.md, CLAUDE.md, AGENTS.md and GEMINI.md anywhere in the repository.
  • MANIFEST.md and ROADMAP.md at the repository root only.
  • Markdown under the top-level docs/ directory.
  • Files under .cursor/rules/.

nima skips these directories everywhere: node_modules, dist, build, .git, .next, coverage, vendor, __pycache__ and .turbo. Documentation discovery also ignores the top-level directories .claude, .github, .husky, .vscode, research, worked, terraform and infrastructure.

nima also skips any file larger than 500 KB and any file that looks binary, whatever its extension.

nima writes a file's summary when it first indexes the file and rewrites it whenever the file's content changes. The summary is built from the first 300 lines of a code file or the first 2,000 lines of a documentation file, so a long file is summarized from its head only.

Index freshness and lastCommitSha

Every repository entry in a search_code response carries lastCommitSha and lastSyncedAt. Compare lastCommitSha with your own HEAD before you trust counts, file layout or "this symbol does not exist". If the index is behind, say so and fall back to your checkout for anything structural.

get_data_model stamps each repository with commitSha and extractedAt. A repository with extractedAt: null has had no data model extracted yet.

blast_radius has no commit stamp in its response. It answers about the indexed commit, so read lastCommitSha from a search_code call on the same repository to know how old that is.

Finding where code lives with search_code

search_code answers "where is this?" It searches every ready repository, or the one you name, and returns ranked files with a summary, the matching symbols and their line ranges.

nima combines several channels and merges them: keyword, vector, a vector search over an imagined answer, symbol name, file path, import-graph expansion and recent git activity. Each hit lists the channels that matched in matchedChannels.

Each hit also carries a match field that says how far to trust it:

matchMeaning
exactThe path you typed equals the hit's path, or a symbol with the name you typed is in the file.
semanticA path or symbol channel matched loosely, or the query was natural language.
noneNo channel confirmed the path or symbol you named. The thing you asked for may not exist.

A missing hit from a repository that is not ready, or that appears in droppedRepositories, is not proof that the code is absent. Parameters, the per-repository time budget and metering are on the search_code tool.

Seeing what a change touches with blast_radius

blast_radius answers "what breaks if I change this?" You give it file paths, symbol names or both, and it walks the import graph backwards from them. It reads the existing index and calls no model.

For the targets you name it returns:

  • Dependent modules and dependent files, each with the depth at which they were reached (depth 1 imports the target directly).
  • Callers, with the calling symbol and line range, for TypeScript and JavaScript files.
  • Covering tests: files under a __tests__/, tests/ or test/ directory, and JavaScript or TypeScript files named *.spec.* or *.test.*.
  • Governing specs: the specs the knowledge graph ties to the touched files or modules.
  • unresolved: names that matched nothing in the index.

Call edges exist only for .ts, .tsx, .js, .jsx, .mjs and .cjs. For every other language you get import-level dependents and an empty callers list. That means nima has no parser for calls in that language, not that nothing calls the code. When the walk is cut short, truncated is true and the answer is a prefix, not the whole set. Input limits, depth and the impacted-file cap are on the blast_radius tool.

Reading the data model with get_data_model

get_data_model answers "what tables and columns does this repository define?" It reads a model that nima extracts during indexing, without running a model call.

nima extracts from these ORMs and schema formats:

LanguageSupported
TypeScript, JavaScriptPrisma, Drizzle, TypeORM, Sequelize, MikroORM, Mongoose
PythonSQLAlchemy, SQLModel, Django, Peewee, Tortoise
GoGORM, Ent, Bun
AnySQL DDL (CREATE TABLE and ALTER TABLE) in .sql files, and SQL strings inside TypeScript, JavaScript, Go or Python files under a migrations directory. Down-migrations and test fixtures are skipped.

nima does not extract ORMs for Ruby, Java, Rust or C# (ActiveRecord, Hibernate, Diesel, Entity Framework). An empty model means nima found no supported ORM or DDL, not that the application stores no data.

When you ask for one table, matchedBy says how far to trust the result: exact (a table name, schema-qualified name or class name equals the query), substring (tables whose name contains it) or none (nothing matched). Summary and detail modes and their caps are on the get_data_model tool.

Plan feature for code tools

search_code, blast_radius and get_data_model are declared under the plan feature code_intelligence, and so are the repository routes on Code API. A workspace whose plan lacks it can get 403 INSUFFICIENT_PERMISSIONS with details.feature set to code_intelligence. The MCP tools call the same routes, so they return the same error.

ask_knowledge_graph has no plan feature. It answers from the knowledge graph, which also holds facts learned from the code index. Use it for why and who; use search_code for where. See Availability for how each feature is turned on, and GitHub for connecting repositories.

On this page