# Code exploration for agents

`occ code` builds an in-memory code graph (no database, no daemon) for JS/TS
and Vue SFC (type-accurate) plus Python, Go, Rust, Java, C/C++, C#, Kotlin,
Scala, Swift, Ruby, and PHP (tree-sitter). Shared flags on every `code` subcommand: `--path
<repo-root>` (default cwd), `--format json`, `-o <file>`, `--exclude-dir`,
`--no-gitignore`, `--content-mode none|excerpt|full`, `--max-file-size-bytes
<n>`, `--max-lines <n>`.

## Orientation — `occ code map` / `occ code pack`

Token-budgeted, PageRank-ranked output. `map` emits top symbol _signatures_ per
file; `pack` emits file _content_ (optionally compressed). This is the primary
"understand this repo cheaply" tool.

```bash
occ code map  --path . --map-tokens 8000 --tokenizer o200k_base -o map.md
occ code pack --path . --map-tokens 8000 --tokenizer o200k_base -o pack.md
```

Shared map/pack flags: `--map-tokens <n>` (default 4096; alias `--token-budget`),
`--tokenizer heuristic|o200k_base|cl100k_base`, `--map-format markdown|xml|json|plain`,
`--mode map|pack`, `--compress` (pack), `--max-symbols <n>`, `--no-bias-exports`.

Focus the map toward a task (boost relevant files/symbols):
`--query "<text>"`, `--focus-path <path>` (repeatable), `--focus-depth <n>`,
`--changed-from <ref>`, `--changed-to <ref>`, `--staged`.

```bash
occ code map --path . --query "auth token refresh" --focus-path src/auth --map-tokens 4096
occ code map --path . --changed-from main --map-tokens 4096   # diff-focused map
```

## Directory tree — `occ code dirtree`

Bounded, ignore-aware tree derived from the built code index, not from a raw
filesystem walk. Use this when you need package/folder shape plus truncation
breadcrumbs for drill-in.

```bash
occ code dirtree --path . --format json
occ code dirtree --path . --mode map --map-tokens 4096 --tokenizer o200k_base
occ code dirtree --path . --focus-path src/code --depth 4 --max-entries 25
```

Modes: `compact` (default, collapses single-child directory chains), `verbose`,
and `map` (compact plus top symbol signatures from the highest-ranked file per
directory). JSON output includes `truncatedPaths`; call again with
`--focus-path <path>` and higher caps to drill into an elided subtree.

## Search — `occ code find <mode>`

- `occ code find fused "<query>"` — combines name + pattern + content search with
  rank fusion (`--weights name:3,pattern:2,content:1`). Best when unsure.
- `occ code find name <name>` — exact symbol name. `--file <path>` to disambiguate, `--type <node-type>`.
- `occ code find pattern <substr>` — substring match on names.
- `occ code find type <nodeType>` — list all nodes of a type (`file|module|function|class|interface|type-alias|enum|variable`).
- `occ code find content <text>` — full-text search (auto-upgrades to `--content-mode full`).

All accept `--limit <n>` (default 50) and `--format json`.

## Source reads — `occ code source`

Use `source` when you already know the symbol and need its exact body without
reading the whole file. Prefer this for named symbols; use `rg`/shell reads for
text, config, and quick facts.

```bash
occ code map --path . --map-format json --map-tokens 4096 -o map.json
occ code source --path . --node-id "<nodeId>" --format json
occ code source bootstrap --path . --file src/main.ts --type function --format json
```

JSON repo-map symbols include `nodeId`, `endLine`, and `containerName`. The
current node-id contract is OCC's existing graph id derived from the indexed
node: `<type>:<absolute-path>:<name>:<line>[:<containerName>]`. The line number
is part of the address, so ids can change after edits; re-run `code map` or
`code find name` after moving a symbol.

## Syntax checks — `occ code check`

Use `check` as a lightweight post-edit parse gate before wider tests. It supports
TS/JS, Vue SFCs, Python, and the vendored tree-sitter languages (Go, Rust, Java,
C/C++, C#, Kotlin, Scala, Swift, Ruby, PHP); unsupported files exit 0 with
`status: "unsupported"` so they do not fail CI accidentally.

```bash
occ code check src/main.ts --format json
occ code check src/App.vue --format json
```

`occ code check` exits nonzero only when `valid` is `false`.

## Relationships — `occ code analyze <kind>`

- `occ code analyze calls <fn>` — what a function calls (outgoing).
- `occ code analyze callers <fn>` — what calls a function (incoming, impact analysis).
- `occ code analyze chain <fromFn> <toFn>` — call paths between two functions (`--depth <n>`, default 5).
- `occ code analyze deps <target>` — module/file import relationships (local/external/unresolved).
- `occ code analyze coupling <target>` — module-level coupling metrics.
- `occ code analyze tree <className>` — class/interface inheritance.

`calls`/`callers`/`tree` accept `--file <path>` to disambiguate. Relationships
report `resolved` / `ambiguous` / `unresolved` status explicitly.

## Change-aware — `occ code diff` / `occ code history`

```bash
occ code diff --base main --map-tokens 4096 --format json   # which symbols changed
occ code history buildRepoMap --format json                 # git line history for a symbol
```

`code diff` flags: `--base <ref>`, `--head <ref>`, `--staged`, `--map-tokens
<n>` (default 4096), `--tokenizer`. See also [git.md](git.md) for raw patches.

## Full index — `occ code index`

Build/dump the full codebase index (files, symbols, edges, capabilities). Heavy;
prefer `map`/`find`/`analyze` for targeted questions. Each `files[].symbols[]`
entry carries a `nodeId`, so a consumer can jump from a file symbol straight to
its graph node (and to `occ code source --node-id <id>`) without scanning
`nodes`.

## Programmatic surface — for long-running hosts

Editor/agent integrations that embed `occ` — holding an index or a
`CodeQuerySession` across turns instead of shelling out per call — have
in-process equivalents for the verbs above, plus a few probes with no CLI:

- **`searchSymbols(index, query, { limit, kinds, pathFilter })`** /
  `session.searchSymbols(...)` — fuzzy symbol search across name,
  container-qualified name, and file path. Each result carries a `score`, the
  matched `positions`/`span` (for highlighting), and a `nodeId` for a follow-up
  source read. The corpus is memoized per index, so repeated queries in a
  long-lived host pay the build once. Facade: `createOcc().code.searchSymbols`.
  From the shell, reach for `occ code find` instead.
- **`buildCodeContext(index)`** / `session.projectContext()` — project a full or
  slim index down to per-file exported symbols, a deduplicated local import
  graph, and external dependency roots. Pure and synchronous; the shape hosts
  hand to a model or a graph view. Facade: `createOcc().code.context`.
- **`buildChangedRepoMap(index, { changed: { base, head } | { staged: true }, ...mapOptions })`**
  — the `--changed-from` map on the API: changed files join the focus set and
  admitted entries carry `changed`/`churn`. `toRepoMapChangeContext` /
  `stampRepoMapChanges` are exported for callers that already hold a diff
  summary. Facade: `createOcc().code.mapChanged`.
- **`buildDirectoryTree(index, options)`** / `session.getDirectoryTree(options)`
  / `createOcc().code.directoryTree(index, options)` — bounded directory tree
  over indexed files, with `compact`/`verbose`/`map` modes and
  `truncatedPaths` drill-in hints.
- **`store.peekMetadata()` / `store.isFresh()`** — probe a persisted
  `CodeIndexStore` without deserializing or parsing. `peekMetadata()` returns the
  on-disk metadata (available before the first `getSession()` of a process);
  `isFresh()` stat-diffs the working tree against the persisted manifest
  (`added`/`modified`/`deleted` counts). Both validate the cache entry belongs to
  this repo, options, and occ version — use them to decide whether to rebuild
  before serving a session.
- **`health().features`** — a map of stable feature identifiers (e.g.
  `code.searchSymbols`, `code.directoryTree`, `store.isFresh`, `code.map.changed`). Feature-detect
  against it (`health.features?.['store.isFresh'] === true`) instead of
  `typeof`-probing when a host must support multiple occ versions.

`createCodeQuerySession(options, onProgress?, signal?)` and
`session.refresh(onProgress?, signal?)` accept an `AbortSignal` for cancellation.
