# ty-find

> LSP adapter for AI coding agents — symbol name in, structured code intelligence out.

ty-find (`tyf`) lets AI coding agents query Python's type system by symbol name.
It wraps ty's LSP server so that `tyf show MyClass` returns the definition
location, type signature, and all references — without requiring file paths or
line numbers. A background daemon keeps responses under 100ms.

Also useful for humans who want fast, precise Python navigation from the terminal.

## Commands

### show — Definition, type signature, and usages of a symbol by name

The most useful command. Given a symbol name, it shows:
- Where it's defined (file + line)
- Its type signature
- Optionally, docstring (`--doc`) and every place it's used (`--references`)
- Or everything at once with `--all` (doc + refs + test refs)

No file path needed — it searches the whole project by name.
`inspect` still works as a hidden alias for backward compatibility.

```
tyf show MyClass
tyf show calculate_sum UserService       # multiple symbols at once
tyf show MyClass --references            # also list all usages
tyf show MyClass --doc                   # include docstring
tyf show MyClass --all                   # show everything: doc + refs + test refs
tyf show MyClass --file src/models.py    # narrow to one file
tyf --format json show MyClass           # JSON output for scripting
```

### find — Find where a symbol is defined by name

Given a symbol name, returns the file and line where it's defined.
Searches the whole project — no need to know which file it's in.
Use `--fuzzy` for partial/prefix matching with richer output (kind + container).

```
tyf find calculate_sum
tyf find calculate_sum multiply divide      # multiple symbols at once
tyf find handler --file src/routes.py       # narrow to one file
tyf find handle_ --fuzzy                    # fuzzy/prefix match
```

### refs — All usages of a symbol across the codebase

Find every location in the codebase that references a symbol. Supports both
name-based and position-based lookup. Essential before renaming or removing
code — tells you exactly what will break.

```
tyf refs my_func my_class                   # by name
tyf refs -f myfile.py -l 10 -c 5           # by position
tyf refs file.py:10:5 my_func              # mixed
... | tyf refs --stdin                      # piped input
```

### members — Public interface of a class

Shows the public interface of a class: methods with signatures, properties,
and class variables with types. Like `list` scoped to a class, with type info.
Excludes private/dunder members by default; `--all` includes everything.
Only shows directly-defined members, not inherited ones.

```
tyf members MyClass
tyf members MyClass UserService          # multiple classes at once
tyf members MyClass --all                # include __init__, __repr__, etc
tyf members MyClass --file src/models.py # narrow to one file
```

### list — All functions, classes, and variables defined in a file

Shows all functions, classes, and variables defined in a file — like a table
of contents. Useful for getting an overview of a file you haven't seen before.

```
tyf list src/services/user.py
```

### daemon — Manage the background server

The daemon starts automatically on first use and shuts down after 5 minutes
of inactivity. You usually don't need these commands.

```
tyf daemon start     # start manually
tyf daemon status    # check if running, uptime, cache info
tyf daemon stop      # stop the daemon
```

## Output Formats

All commands support `--format` (placed before the subcommand):
- `human` — default, readable text with source context
- `json` — structured JSON, good for piping to jq or scripting
- `csv` — tabular, good for spreadsheets or further processing
- `paths` — just file paths, one per line (for xargs, editors, etc.)

```
tyf --format json show MyClass
tyf --format paths find calculate_sum | head -1 | xargs code
```

## Why tyf?

**vs grep/ripgrep:**
- grep matches text; tyf understands Python's type system
- grep returns hits in comments, strings, and docstrings; tyf returns only real symbol references

**vs raw LSP (in editors):**
- LSP requires file:line:col positions to answer queries
- An LLM doesn't know positions without searching first — it would need to grep, which is imprecise
- tyf accepts symbol names directly, resolves positions internally, and returns structured results

Use **grep** for: string literals, config values, TODOs, non-Python files.

## Performance Tips

Install [ripgrep](https://github.com/BurntSushi/ripgrep) (`rg`) to speed up lookups for non-existent symbols. When a symbol isn't found on the first LSP attempt, tyf uses `rg` to quickly check if the symbol text exists in any `.py` file. If not, it skips the retry chain (~3 seconds) and returns immediately.

## Installation

Requires [ty](https://github.com/astral-sh/ty) (`uv add --dev ty`).
Optional: [ripgrep](https://github.com/BurntSushi/ripgrep) for faster non-existent symbol lookups.

```
pip install ty-find
# or
uv add --dev ty-find
```
