Code indexing
Raggie parses your project with tree-sitter and stores the result in a SQLite database at .raggie/.code_index.raggie. The index is what lets the agent ask "what calls this?" instead of grepping and guessing.
It holds:
- Symbols: functions, methods, classes, structs, interfaces, enums, variables, type aliases, with their locations
- Imports per file
- Dependencies: which function calls or references which symbol, resolved across files, in both directions (dependencies and dependents)
- Complexity data: branch counts used by code health
The tools built on it are GetFileCodeSemantics, GetSymbolSourceCode, WalkCallTree and EditSymbol. See Tools.
When indexing runs#
| Moment | What runs |
|---|---|
| Chat start | Incremental index |
| Before each message | Incremental index |
| After a file-modifying tool or a shell command | Incremental index |
/reindex |
Incremental index on demand |
/reindex --force |
Full rebuild |
Incremental means only new files, changed files, and the files that depend on a changed file are parsed again, so on an unchanged project it costs almost nothing. Changes are detected by modification time first, then confirmed with a content hash. Pressing Ctrl+C during indexing keeps the existing index and continues.
Supported languages#
| Language | Extensions | What gets indexed |
|---|---|---|
| Python | .py |
Functions, classes, methods, imports, variables, type aliases, docstrings |
| Go | .go |
Functions, methods with receivers, structs, interfaces, type aliases, imports |
| C# | .cs |
Methods, constructors, classes, records, interfaces, structs, enums, namespaces, properties, using directives |
| JavaScript | .js, .jsx |
Functions, generators, classes, methods, imports, variables |
| TypeScript | .ts |
Functions, classes, interfaces, type aliases, enums, public fields, imports |
| TSX | .tsx |
Same as TypeScript, with JSX |
| Rust | .rs |
Functions, structs, enums, traits, impl blocks, constants, statics, type aliases, use declarations, macro_rules! |
| Zig | .zig |
Functions, const / var declarations, @import |
| Elixir | .ex, .exs |
def / defp / defmacro, modules, aliases, assignments |
| C | .c, .h |
Functions, structs, enums, typedefs, #include, macros |
| C++ | .cpp, .cc, .cxx, .hpp, .h, .hxx |
Functions, classes, structs, enums, type aliases, #include, macros |
| PHP | .php |
Functions, methods, classes, interfaces, use / include / require |
| Dart | .dart |
Functions, getters and setters, constructors, classes, mixins, extensions, imports |
| Java | .java |
Methods, constructors, classes, records, annotation types, interfaces, enums, imports |
| Kotlin | .kt, .kts |
Functions, classes, objects, interfaces, enums, type aliases, imports |
A language is skipped if its tree-sitter grammar is not installed.
Frontend files#
Markup and styles are indexed too, so the agent can connect components, selectors and the elements they apply to:
| Kind | Extensions |
|---|---|
| HTML | .html, .htm |
| CSS | .css |
| Vue single-file components | .vue |
| Svelte components | .svelte |
| JSX / TSX components | .jsx, .tsx |
Defaults can be overridden in .raggie/frontend_config.json:
{
"enabled_languages": ["html", "css", "javascript", "tsx", "vue", "svelte"],
"generated_dir_exclusions": ["dist", "build", "node_modules", ".next", ".nuxt", "out"],
"parse_inline_scripts": true,
"parse_inline_styles": true,
"include_text_nodes": false,
"css_module_resolution": true,
"generated_css_threshold": 100000,
"max_frontend_file_size": 500000
}
What is skipped#
- Files matched by
.aiignore, or.gitignorewhen there is no.aiignore. See Configuration. - Generated directories:
dist,build,node_modules,.next,.nuxt,out(thegenerated_dir_exclusionslist above). - Directories named
testortests. Test code is left out of the index and the call graph. The agent can still read and edit those files with the file tools.
Project detection#
Before the terminal agent starts, Raggie checks for a .raggie/ folder in the working directory.
| Situation | Result |
|---|---|
.raggie/ exists |
Starts normally |
No .raggie/, and the directory has no subdirectories |
Starts normally. A flat directory is cheap to scan |
No .raggie/, and the directory has subdirectories |
Warns that this does not look like a Raggie project and asks whether to create one here. Declining exits with a hint to cd into your project |
This prevents scanning something huge by accident, for example when you run raggie code . in your home directory.
Performance#
Parsing runs in parallel worker processes with a sliding-window scheduler, and a dedicated writer thread does batched inserts. Dependencies are resolved in a pass after parsing.
Benchmark: Linux kernel 7.1.1 (27,844,648 lines across 62,875 files)
| Phase | Time |
|---|---|
| File collection | ~4s |
| Changed-file detection | ~1.5s |
| Parse and insert (parallel) | ~521s |
| Dependency resolution | ~66s |
| Total | ~10m37s |
Symbols indexed: 750K functions, 5.9M macros, 367K classes, 909K structs, 84K enums, 266K variables.
A typical project of a few hundred files indexes in seconds, and re-indexing after an edit only touches the changed files.
Going deeper#
Indexer internals documents the indexer modules, database schema, extraction pipeline and per-language handling.