Tool
query
Everything is a table, and tables compose: joins, CTEs, window functions, recursive traversals. Reach for query when the question is a count, a list, a join, or a traversal — the shapes that explore and read are not for.
The size and shape of a codebase in 58 tokens. The same join reaches git history, lint findings, and parsed spreadsheets, because they are all tables in the same database.
Run it yourself
Or say it to your agent
“how big is this codebase, broken down by language?”
Parameters
| Parameter | What it does | |
|---|---|---|
| sql | required | DuckDB SQL. DESCRIBE SELECT * FROM <view> LIMIT 0 introspects any view or macro's columns. |
| tokenBudget | optional | Results summarise themselves past this — set it to the most the answer is worth. |
| timeoutMs | optional | A hard deadline. Five minutes by default. |
The views
| View | What is in it |
|---|---|
| Files | Every indexed file: uri, path, extension, media type, size, headline, summary, structure, token count, mtime. |
| Functions | Every function and method: qualified name, declaring type, visibility, signature, return type, parameters, language, span. |
| Types | Every type: qualified name, kind, namespace, signature, what it extends and implements, span. |
| Annotations | Lint and SARIF findings, joinable straight onto the files and symbols they point at. |
| Language views | Per-language detail — csharp_types, python_imports, markdown_headings and their siblings. |
The functions
Table functions and macros that do the work you would otherwise write by hand.
| Function | What it gives you |
|---|---|
| search_pipeline(...) | Hybrid semantic and lexical search, returning scored rows you can join against anything. |
| glob_files(...) · matches_glob(...) | The address grammar, as SQL. |
| grep_matches(...) · regex_matches(...) | Streaming line-level search — no need to write your own scan. |
| git_status() · git_diff() · git_blame() | Live git, read on demand rather than indexed. |
| git_hotspots() · git_patches() | Change frequency and patch content, as tables. |
| parse(text) · xlsx(uri, sheet) | CSV, JSON, YAML, and spreadsheets, turned into rows. |
| ask(rows, intent, maxTokens) | Language-model synthesis over a result set, inside the query. |
A failed query is cheap
Guessing at a shape costs one round trip, and errors name the columns that do exist. Run
SUMMARIZE <view> or DESCRIBE first when you are unsure, and iterate.
This page names what exists. The depth behind every name — the bounds, the failure modes, how they compose — ships inside the binary at help:///, and answers to explore and read exactly like your code does. Install it, and your agent has the manual.