Multi-Language Repo
Canopy indexes every supported language in a single pass. A repo with a TypeScript frontend, a Python backend, and Rust services gets one unified index — and one tool, canopy_answer, that answers the same question shapes across all of it.
What gets indexed
Section titled “What gets indexed”Canopy’s AST extractors cover 55+ languages and formats — symbols and imports are extracted for each. The set includes Rust, TypeScript/TSX, JavaScript, Python, Go, Java, Kotlin, C, C++, C#, Swift, Ruby, PHP, Lua, Perl, Objective-C, shell/PowerShell/batch, HTML/CSS, GraphQL, Protobuf, Prisma, Dockerfile, CMake/Make/Gradle/MSBuild, YAML/TOML/INI/JSON, GDScript/Godot, Jupyter, Markdown, and more.
Language detection is automatic, by file content and extension. Files outside the extractor set are still indexed for full-text search.
Index a mixed-language repo
Section titled “Index a mixed-language repo”No special flags. Run canopy index at the repo root:
canopy index /path/to/repoIndexing is incremental by default and builds the full-text search index and vector embeddings automatically; git history is ingested whenever a .git/ directory is present. That’s everything canopy_answer needs across every language in the tree.
Same questions, any language
Section titled “Same questions, any language”Phrasing picks the recipe regardless of language. Name the entity type and backtick paths and symbols:
# Pythoncanopy answer "where is the function `create_payment_route` defined?"
# TypeScriptcanopy answer "what does `frontend/src/api/client.ts` import?"
# Anywhere in the treecanopy answer "list functions defined in `backend/app/routes/`"canopy answer "what depends on `backend/app/services/payment.py`?"canopy answer "architecture overview"The architecture overview spans the whole repo — frontend, backend, and services in one answer.
Example: TypeScript frontend + Python backend
Section titled “Example: TypeScript frontend + Python backend”A common structure:
repo/├── frontend/ (TypeScript/React)│ └── src/│ └── api/│ └── client.ts└── backend/ (Python/FastAPI) └── app/ └── routes/ └── payments.pyIndex once at the root, then ask on either side of the boundary:
canopy answer "what depends on `frontend/src/api/client.ts`?"canopy answer "public surface of `backend/app/routes/payments.py`"canopy answer "what tests cover `backend/app/routes/payments.py`?"One index, one tool, both languages.
Cross-language boundaries
Section titled “Cross-language boundaries”Dependency edges follow each language’s module system. A TypeScript frontend calling a Python REST API over HTTP is not a static import, so it doesn’t appear as a graph edge — Canopy works at the source level, not the network level. Cover the boundary from both sides:
- “what depends on
frontend/src/api/client.ts?” — every frontend caller of the API client. - “what depends on
backend/app/routes/payments.py?” — everything wired to the endpoint on the backend.
Verify coverage
Section titled “Verify coverage”To confirm a directory or language made it into the index, check what the walker includes and skips — without running an index:
canopy index --list-ignoredThis prints what would be indexed vs skipped, grouped by top-level directory. For a structural sanity check, canopy answer "architecture overview" should reflect every major language area of the repo; canopy doctor reports overall index status.
Common pitfalls
Section titled “Common pitfalls”A language is missing from answers
The files are almost always being skipped by an ignore layer: the bundled defaults (build artifacts and vendored dependencies), .gitignore, .canopyignore, or an --ignore-pattern glob. Run canopy index --list-ignored to see the skip list; re-run with --no-default-ignore, --no-gitignore, or --no-canopyignore to attribute a specific file to a layer.
First-party code inside a default-ignored directory
If first-party code lives somewhere the default ignore set excludes (unusual, but it happens), --no-default-ignore indexes it — at the cost of also indexing build artifacts. Prefer restructuring or a narrower .canopyignore where possible.
Stale answers after adding a new service
Re-run canopy index (incremental) after large structural additions, or run canopy serve --watch so the index tracks changes automatically during development.