> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basemode.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Navigating code

> Querying your codebase by name, caller, file and import instead of grepping it. Mapping a new app, where the map lives, and how it stays current.

base keeps a map of your code built by tree-sitter, and `base ast query` asks it questions. The difference from grep is that the map knows what a call is, so "everything that calls this" is an answer rather than a text match that also finds the comments.

## Map an app once

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base sync --ast --target apps/portal
```

Run it from anywhere with `--target`, or from inside the app without it. Tree-sitter covers more than thirty-five languages.

**Why it works.** The extraction walks the directory, parses each file, and writes entities and relationships to that app's own map at `<app>/.base-ast/ast.ttl`. One map per app, not one shared index, which is why two apps in one workspace never overwrite each other's.

**The gotcha.** Until an app has been mapped once, nothing queries it and nothing will map it for you. That first run is manual by design.

## The four questions

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base ast query --contains "auth"
base ast query --file "main.rs"
base ast query --calls "validate"
base ast query --imports "config.rs"
```

| Flag         | Answers                                                             |
| ------------ | ------------------------------------------------------------------- |
| `--contains` | Which entities have this in their name? Case-insensitive substring. |
| `--file`     | What is defined in this file, and what does it relate to?           |
| `--calls`    | What calls this function?                                           |
| `--imports`  | Which files import from this one?                                   |

**Why it works.** Each of these is a different edge in the map rather than a different search. `--calls` is walking call edges, which is why it finds the caller in a file that never mentions the function by the name you typed.

**Next rung.** Everything has a short form: `base a q -c "auth"` is `base ast query --contains "auth"`. `-f`, `-i` and `-t` cover file, imports and target. `--calls` has no short form.

## Querying another app

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base ast query --target apps/portal --contains "auth"
```

**The gotcha worth remembering.** Without `--target`, the query reads the map belonging to where you are standing. Asking about `apps/portal` from the workspace root returns nothing rather than an error, which reads exactly like "there is no such function". If a query comes back empty, check where you are before you conclude anything.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base ast list
```

This prints every registered map with its app name, entity count, path and last-synced time. An app with no row has never been mapped.

## Staying current

Once an app has a map, it refreshes on its own after each turn: a hook re-runs the sync for the app you are in and any app you edited.

**The gotcha.** The refresh is debounced by twenty seconds and never waited on, so a burst of fast turns can skip one. Nothing is lost when that happens, because skipped apps are queued for the next one, but a map can be a few seconds behind mid-burst. Force it with `base sync --ast` if that matters.

An app that has never been synced stays unmapped forever. The refresh only maintains maps that already exist.

## Where the map lives

`<app>/.base-ast/ast.ttl`, beside the app, outside both tiers, never merged into `graph.nq`.

`.base-ast/` writes its own `.gitignore`, so the map excludes itself from version control. Whoever clones the repository has no map until they run `base sync --ast` themselves, which takes seconds and produces paths that are right for their machine.

<Note>
  If you have seen an "AST graph not yet populated" hint on a workspace you know is mapped, that was a real bug: the hint checked the pre-migration path while queries checked the correct one, so it fired forever no matter what you did. It is fixed as of the shipped release, and the check now resolves the same way queries do. Verified from source at `4866996`.

  A current hint means the workspace genuinely has no map. `base ast list` settles it either way.
</Note>

## Repairing the graph's view of a map

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base sync --repair
```

Use this when entities exist but their links do not: tasks that do not show up under their project, a decision a domain-scoped search cannot find. It backfills the missing edges and changes nothing else.

## Next

<CardGroup cols={2}>
  <Card title="Querying the graph" icon="magnifying-glass" href="/guides/querying-the-graph">
    Asking open questions, and walking the graph node by node.
  </Card>

  <Card title="Code reference" icon="code" href="/reference/code">
    Every `base ast` and `base sync` flag.
  </Card>
</CardGroup>
