@ikhrustalev/tsquery
v0.2.0
Published
Semantic TypeScript queries for LLM agents
Downloads
42
Readme
tsquery
Semantic TypeScript queries for LLM coding agents.
Instead of grep, give your LLM the type graph.
Why
LLM coding agents (Claude Code, Cursor, Windsurf) navigate TypeScript codebases with grep and find — text-level tools blind to types, call graphs, and module boundaries. TypeScript's compiler already knows the full semantic structure. tsquery exposes it as simple CLI commands.
v2 uses a persistent tsserver daemon — zero dependencies, instant queries after first load.
Install
npm install -g @ikhrustalev/tsqueryRequires typescript (>=5.0) installed in your project's node_modules — it uses your project's own tsserver.
Commands
| Command | What it does | Example |
|---------|-------------|---------|
| map | Project overview: files, exports, imports | tsquery map |
| find <symbol> | Locate symbol definitions | tsquery find getByUser |
| callers <symbol> | Who calls this function? | tsquery callers archive |
| callees <symbol> | What does this function call? | tsquery callees archive |
| refs <symbol> | All references to a symbol | tsquery refs UserConfig |
| type <symbol> | Detailed type information | tsquery type UserConfig |
| context <symbol> | Full context bundle for a symbol | tsquery context archive |
| exports <file> | What a file exports | tsquery exports src/auth.ts |
| deps <file> | What a file imports | tsquery deps src/auth.ts |
Daemon management
| Command | What it does |
|---------|-------------|
| notify <file> | Tell daemon a file changed (refresh after edits) |
| status | Show daemon status |
| restart | Restart daemon |
| stop | Stop daemon |
Symbol scoping
When multiple symbols share a name, scope with file.ts:symbolName:
tsquery callers getOrThrow # finds first match
tsquery callers src/model/users.ts:getOrThrow # specific fileJSON output
Add --json for machine-readable output:
tsquery find getByUser --jsonThe context command
This is the key command for LLM agents. Given a symbol, it assembles everything needed to understand and modify it:
$ tsquery context archive
# Context: function archive
# File: src/model/conversations.ts:43
## Definition
```typescript
export async function archive(ctx: MutationCtx, id: string): Promise<void> {
const conv = await getOrThrow(ctx, id);
if (conv.status !== "completed") {
throw new Error("Can only archive completed conversations");
}
await ctx.db.patch(id, { status: "archived" });
}Type Dependencies
type MutationCtx — src/model/conversations.ts:11
Calls (outgoing)
-> getOrThrow — src/model/conversations.ts:23
Called by (incoming)
<- archiveConversation (mutation) — src/conversations.ts:41
Related Code
src/model/conversations.ts: getOrThrow
export async function getOrThrow(ctx: QueryCtx, id: string): Promise<Conversation> {
const conv = await ctx.db.get(id);
if (!conv) throw new Error("Conversation not found");
return conv;
}
One command gives the LLM: the function, its types, what it calls, who calls it, and the source of its dependencies.
## How it works
The first `tsquery` command spawns a background daemon that loads your project's type graph via `tsserver`. Subsequent queries are instant. The daemon auto-stops after 10 minutes of inactivity.
tsquery callers archive <- one-shot CLI client | +- Is daemon running? | Check for /tmp/tsquery-.sock | +- NO -> spawn daemon, wait for ready, then query +- YES -> connect, send query, print result, exit
## Setup for LLM agents
### Claude Code — CLAUDE.md
Add to your project's `CLAUDE.md` (create it in the project root if it doesn't exist):
```markdown
## Code Navigation
`tsquery` is available for semantic TypeScript navigation.
Use it instead of grep for understanding code structure.
tsquery map — project overview
tsquery find <symbol> — locate definitions
tsquery callers <symbol> — who calls this
tsquery callees <symbol> — what it calls
tsquery refs <symbol> — all references
tsquery type <symbol> — type details
tsquery context <symbol> — full context bundle
tsquery exports <file> — file's public API
tsquery deps <file> — file's imports
tsquery notify <file> — refresh after editing
Always run `tsquery context <function>` before modifying a function.
Always run `tsquery callers <function>` before changing a function signature.
Always run `tsquery refs <Type>` before changing a type's shape.Multi-agent setups — AGENTS.md
For projects using multiple agents or agentic sub-tasks, add to AGENTS.md:
## Code Navigation
All agents working with TypeScript code MUST use `tsquery` for semantic navigation.
### Required workflows
1. **Before modifying a function:**
Run `tsquery context <function>` to understand its full dependency chain,
callers, and type dependencies.
2. **Before changing a function's signature:**
Run `tsquery callers <function>` to identify every call site that needs updating.
3. **Before changing a type/interface:**
Run `tsquery refs <Type>` to find all usages across the project.
4. **After editing a file:**
Run `tsquery notify <file>` so subsequent queries reflect your changes.
5. **To understand a new area of code:**
Run `tsquery map` for the project overview, then `tsquery exports <file>`
for specific files.
### Command reference
tsquery map — project overview
tsquery find <symbol> — locate definitions
tsquery callers <symbol> — who calls this function
tsquery callees <symbol> — what this function calls
tsquery refs <symbol> — all references to a symbol
tsquery type <symbol> — type details
tsquery context <symbol> — full context bundle
tsquery exports <file> — file's public API
tsquery deps <file> — file's imports
tsquery notify <file> — refresh after editing a file
### Notes
- Symbol scoping: use `file.ts:symbolName` when multiple symbols share a name.
- Add `--json` for structured output.
- The daemon auto-starts on first query and stops after 10 minutes of inactivity.Options
--tsconfig <path> Path to tsconfig.json (auto-detected by default)
--json Output raw JSON instead of formatted text
--help Show helpEnvironment variables
| Variable | Default | Description |
|----------|---------|-------------|
| TSQUERY_IDLE_TIMEOUT | 600000 | Daemon idle timeout in milliseconds |
License
MIT
