Metadata-Version: 2.4
Name: yigraf
Version: 0.1.12
Summary: A harness primitive for AI coding agents: one connected graph over code, intent, plan, and memory — legible (token-cheap retrieval) and enforceable (intent↔code drift checks).
Project-URL: Homepage, https://github.com/mansilla/yigraf
Project-URL: Repository, https://github.com/mansilla/yigraf
Project-URL: Issues, https://github.com/mansilla/yigraf/issues
Author-email: Ricardo Mansilla <rick.mansilla@gmail.com>
License: MIT
License-File: LICENSE
Keywords: agents,ai,claude,code-intelligence,knowledge-graph,llm,tree-sitter
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.11
Requires-Dist: fastembed>=0.5
Requires-Dist: mcp>=1.2
Requires-Dist: networkx>=3.4
Requires-Dist: numpy>=1.24
Requires-Dist: pyyaml>=6.0
Requires-Dist: tree-sitter-bash<0.25,>=0.23
Requires-Dist: tree-sitter-c-sharp<0.25,>=0.23
Requires-Dist: tree-sitter-c<0.25,>=0.23
Requires-Dist: tree-sitter-cpp<0.25,>=0.23
Requires-Dist: tree-sitter-go<0.26,>=0.23
Requires-Dist: tree-sitter-java<0.25,>=0.23
Requires-Dist: tree-sitter-javascript<0.26,>=0.23
Requires-Dist: tree-sitter-kotlin<2.0,>=1.0
Requires-Dist: tree-sitter-php<0.25,>=0.23
Requires-Dist: tree-sitter-python<0.26,>=0.23
Requires-Dist: tree-sitter-ruby<0.25,>=0.23
Requires-Dist: tree-sitter-rust<0.25,>=0.23
Requires-Dist: tree-sitter-scala<0.27,>=0.23
Requires-Dist: tree-sitter-sql<0.4,>=0.3
Requires-Dist: tree-sitter-swift<0.9,>=0.7
Requires-Dist: tree-sitter-typescript<0.25,>=0.23
Requires-Dist: tree-sitter<0.26,>=0.25
Requires-Dist: typer>=0.12
Provides-Extra: embeddings-torch
Requires-Dist: sentence-transformers>=2.2; extra == 'embeddings-torch'
Description-Content-Type: text/markdown

<p align="center">
  <img src="https://raw.githubusercontent.com/mansilla/yigraf/main/assets/logo.png" alt="yigraf" width="120" height="120">
</p>

# yigraf

> **yigraf — "Why I Graph?"** A tool **for AI coding agents, not for humans.** It answers, *for the
> agent*, the **why's** and **what-for's** of its current state — the questions an agent can't recover
> from source alone and loses on every `/clear`. A human is the *principal* whose intent it carries; the
> agent is the operator and the audience.

## What is yigraf?

yigraf is a **harness primitive** for AI coding agents: it projects your repo into one connected graph
over four kinds of knowledge —

- **structure** — the code itself (*what is this?*)
- **intent** — specs/requirements (*what is it for?*)
- **plan** — goals and tasks (*what's left?*)
- **memory** — decisions and their reasoning (*why is it this way?*)

— and keeps them linked, so the right slice of an agent's work is both **legible** (scoped, token-cheap
retrieval instead of re-reading files) and **enforceable** (an intent↔code *drift check* that fires when
code and the thing governing it diverge). It retrofits onto an existing repo — `yigraf init` and go.

The problem it solves: an agent's working memory is wiped on every `/clear`, and source code doesn't
record *why* it's the way it is or *what* it's supposed to do. yigraf persists that context as a
queryable graph and re-surfaces the relevant piece exactly when the agent needs it.

### Capabilities

- **Structure index** — tree-sitter parsing into file/module/symbol nodes with a reformatting-stable
  content hash, across **16 languages** (see [`docs/language-support.md`](docs/language-support.md)).
- **Intent & plan** — author specs and task plans as Markdown; link a task to the symbols that implement
  it, **anchored** to their current content.
- **Drift detection** — when anchored code changes, yigraf surfaces *"re-verify this still holds, then
  re-link or supersede."* A pure rename re-anchors automatically; a body change is honest drift. (This is
  the part that makes yigraf governance, not just an index.)
- **Memory** — capture decisions + the reasoning behind them; recall by **meaning** (optional embeddings)
  or lexically; a decision earns `settled` after surviving K commits un-superseded; `gc` archives churn.
- **Token-cheap retrieval** — `yigraf context "<topic>"` returns a scoped, budgeted slice (locators +
  signatures, not file dumps) — measured ≈2.5× cheaper than reading the file.
- **Agent integration (any host)** — an **MCP server** (`yigraf mcp`) exposes the graph as tools
  (`context`/`status`/`link`/`remember`) to *any* MCP host (Codex, Antigravity, Cursor, Claude Code);
  where a host has lifecycle hooks (Claude Code, Codex) those also **push** governing intent + drift on
  edit and re-inject the plan after a reset. The `yigraf` CLI works with any agent. See
  [`docs/hosts.md`](docs/hosts.md).

### Requirements (and what each is for)

| Requirement | Why |
|---|---|
| **Python ≥ 3.11** | yigraf runs as a Python CLI |
| **A git repo** | drift anchoring and git-derived maturity read git history (degrades gracefully without git) |
| **Tree-sitter grammars** | structure extraction — **bundled**, no setup |
| **An agent harness** | the MCP server (`yigraf mcp`) reaches any MCP host; Claude Code & Codex also get push hooks; any agent can drive the CLI |
| **MCP SDK** | **bundled** (core dep) — powers `yigraf mcp`, the universal pull channel `yigraf install` wires by default |
| **An embeddings backend** | **bundled** (core dep, fastembed/ONNX — no torch) — semantic recall of memory/intent by meaning, **on by default**; **falls back to lexical** retrieval if disabled |

## Quickstart — just tell your agent

yigraf is a tool *for agents*, so the install is too. In any repo, tell your coding agent:

> **"Please install github.com/mansilla/yigraf in this project."**

Your agent should then run the plan probe, **show you a menu**, and only wire what you pick:

```bash
yigraf install --plan          # inspect the host + repo, print the menu, apply NOTHING
yigraf install --plan --json   # same, machine-readable (the agent parses this)
```

The plan reports your environment (Python, git, detected hosts), the **core capabilities** you get
for free (**including semantic recall** — the lightweight fastembed backend is bundled, no torch), and
any **optional plugins** with their real cost — so *you* decide, before anything is installed. Then the
agent applies your choice:

```bash
pip install yigraf                  # or: pipx / uv tool install  (see Installation)
# full power out of the box — semantic recall included; no extras needed for it
cd your-repo
yigraf init                         # create the yigraf/ workspace
yigraf build                        # index the code into the graph
yigraf install                      # wire the host(s): auto-detects Claude Code / Codex / Antigravity, else MCP
```

> **Agent recipe** (what a well-behaved agent does when asked to install yigraf):
> 1. Install the CLI (`pipx`/`uv tool` preferred; **do not** add yigraf to `requirements.txt` — it's a
>    dev/agent tool, not a runtime dependency), then `yigraf init && yigraf build`.
> 2. Run `yigraf install --plan --json` and **present the menu to the human** — core capabilities
>    (semantic recall is on by default), detected hosts, and any optional plugin with its cost.
> 3. Let the human confirm; install any chosen extras; then run `yigraf install` to wire the hosts.
> 4. Never silently install a heavy plugin (the torch backend) or silently disable a core one — surface it.

Then use it:

```bash
yigraf context "session expiry"          # a scoped, token-cheap slice for a topic
yigraf intent session-expiry -s "The system SHALL expire a session after 30m idle."
yigraf link task:auth/1 sym:src/auth/session.py#refresh   # anchor a task to its code
yigraf remember "chose monotonic clock" --why "wall-clock skews under NTP"
yigraf drift                             # report any intent↔code drift
```

## Installation

yigraf is on **PyPI**. It needs **Python ≥ 3.11**; the tree-sitter grammars are bundled, so there's
nothing else to set up. For a CLI you use across repos, an isolated install (pipx or `uv tool`) is nicest.

**Any platform — pick one:**

```bash
pip install yigraf                 # into the current environment (semantic recall included)
pipx install yigraf                # isolated CLI (recommended)
uv tool install yigraf             # isolated CLI, via uv

# optional: the torch/sentence-transformers backend (Apple-Silicon MPS or exact fp32) — NOT
# needed for semantic recall, which is already on by default:
pip install "yigraf[embeddings-torch]"
```

### Capabilities & plugins (the menu)

Everything in the **core** block ships with a plain `pip install yigraf` — no extras, no setup,
semantic recall included. The one plugin is opt-in because it carries a real cost; `yigraf install
--plan` prints this same menu tailored to your machine so you (via your agent) can choose.

| | Capability | Included? | Cost / note |
|---|---|:---:|---|
| **core** | Structure index (16 languages, tree-sitter) | ✓ default | grammars bundled |
| **core** | Intent + plan authoring, intent↔code **drift** | ✓ default | — |
| **core** | Memory (decisions + *why*) | ✓ default | — |
| **core** | Token-cheap `yigraf context` retrieval | ✓ default | — |
| **core** | MCP server + host push hooks | ✓ default | `mcp` SDK is a core dep |
| **core** | **Semantic recall** (fastembed / ONNX) | ✓ default | onnxruntime ~68MB, **no torch**; downloads a small model from HuggingFace on first use |
| *plugin* | Torch embeddings backend (`[embeddings-torch]`) | opt-in | pulls **torch ~1GB+**; only for MPS throughput / exact fp32 |

**About semantic recall and HuggingFace.** Semantic recall lets you find memory/intent *by meaning*
instead of keywords, and it's **on by default** — the bundled **fastembed** backend runs the
`bge-small` model on ONNX Runtime (~68 MB, no torch). On first `yigraf build` it downloads that small
model from the **HuggingFace Hub** — that's the only reason HuggingFace is ever involved, and the
one-time "unauthenticated Hugging Face Hub" notice you may see is harmless (set `HF_TOKEN` only if you
hit download rate limits). Set `embeddings.backend: none` in `yigraf/config.yaml` to disable it —
retrieval then **degrades gracefully to lexical recall** (nothing breaks, search is just keyword-based).

The `[embeddings-torch]` plugin swaps in the `sentence-transformers` (torch) backend. You do **not**
need it for semantic recall — install it only for Apple-Silicon MPS throughput on large corpora or the
exact fp32 model, then set `embeddings.backend: sentence-transformers`. Measured cosine agreement
between the two backends on this workload is ≈0.9999, so retrieval quality is effectively identical.

### macOS

```bash
brew install python@3.12 pipx     # Python 3.11+ and pipx
pipx install yigraf
```

### Linux

```bash
# Debian/Ubuntu — ensure Python 3.11+ and git
sudo apt-get update && sudo apt-get install -y python3 python3-pip pipx git
pipx install yigraf
```

### Windows

```powershell
winget install Python.Python.3.12    # Python 3.11+
winget install Git.Git               # drift anchoring uses git; install Git for Windows
pip install yigraf                   # or: pipx install yigraf
```

### From source (development)

```bash
git clone https://github.com/mansilla/yigraf.git
cd yigraf
uv sync                  # create the venv + install deps (incl. dev tools)
uv run yigraf --help
uv run pytest
```

## How yigraf works

yigraf projects your repo into one graph and keeps it in sync with the *why*:

1. **Index** — `yigraf build` parses your code into file/module/symbol nodes, each with an
   AST-normalized content hash (so reformatting and comments don't count as change).
2. **Author** — write **intents** (specs) and **plans** (tasks) as Markdown; capture **memory**
   (a decision + its reasoning) with `yigraf remember`.
3. **Link** — `yigraf link <task> <symbol>` records which code implements a task and **anchors** the
   link to that symbol's current content hash.
4. **Retrieve** — `yigraf context "<topic>"` returns a scoped, token-budgeted slice: the governing
   intents, the implementing symbols (as locators + signatures), prior decisions, open tasks, and any
   drift — a small map, not a pile of file dumps.
5. **Enforce** — when a symbol's anchored content changes, yigraf reports **drift** so the change gets
   re-verified against what governs it (or the link re-anchored / the decision superseded).

With Claude Code wired up (`yigraf install-claude-hooks`), steps 4–5 happen automatically: a
**PostToolUse** hook injects governing intent + drift the moment the agent edits a governed file, and a
**SessionStart** hook re-injects the active plan after a `/clear` — so a flow interrupted by a context
reset resumes instead of restarting. The hook stays silent on ungoverned, undrifted edits (no nagging).
It also wires a **statusline** — the spinning `[Yigraf]` graph-health bar (symbols, intents, open tasks,
drift, freshness) plus a **context-window gauge** (`ctx ▰▰▱▱ 42%`) — so you see the graph's shape and how
full the window is on every refresh, without spending the agent's context. It's a dependency-free Python
adapter (`yigraf statusline`), so the gauge works out of the box (no `jq`, no shell). The statusline is a
Claude Code surface; an existing statusLine of yours is left untouched.

The statusline also checks PyPI **at most once a day** (cached in the gitignored `.local/` sidecar,
fail-open) and shows an `⬆ <version>` marker when a newer yigraf is released — `yigraf status` in a
terminal then prints the one-line update command. No background job, no scheduler.

### Works with any host (two channels)

yigraf reaches an agent through **pull** (the agent calls a tool) and/or **push** (yigraf injects at the
moment of action). **MCP is the universal floor** — `yigraf mcp` exposes the graph as tools to any
MCP host. **Push hooks are a thin complement where a host has them** (Claude Code, Codex). They're not
exclusive: on Claude Code/Codex you can run both. The full per-host matrix and wiring is in
[`docs/hosts.md`](docs/hosts.md); MCP config per host is in [`docs/mcp.md`](docs/mcp.md).

| Host | Pull (MCP) | Push (hooks) | Wire it |
|------|:---------:|:------------:|---------|
| Claude Code | ✓ | ✓ | `yigraf install-claude-hooks` |
| Codex CLI | ✓ | ✓ | `yigraf install-codex-hooks` |
| Antigravity IDE | ✓ | — | `yigraf install-antigravity` |
| Cursor / Windsurf / other MCP | ✓ | — | point at `yigraf mcp` (`docs/mcp.md`) |

## Files yigraf creates

`yigraf init` lays down a `yigraf/` workspace at your repo root:

```
yigraf/
├── config.yaml                 # committed — enabled languages, ignore globs, retrieval tunables
├── intents/<slug>.md           # committed — requirement / goal / capability specs
├── plans/{active,completed}/   # committed — plans + tasks (the filesystem is the state)
├── memory/<id>-<slug>.md       # committed — decisions / constraints + the "why"
├── graph.json                  # committed — the graph projection (recomputable state only)
├── index/                      # gitignored — embedding index (rebuildable)
├── cache/                      # gitignored — extraction cache
└── .local/                     # gitignored — volatile telemetry (usage / last_seen)
```

The **committed** artifacts (`intents/`, `plans/`, `memory/`, `graph.json`, `config.yaml`) are the
shareable record — they travel with the repo, so the next agent or teammate inherits the *why*. Derived
and volatile state stays gitignored and rebuilds from source. yigraf also writes a self-contained
`yigraf/.gitignore`, so nothing extra needs to be added to your repo's ignore rules.

Opt-in installers wire yigraf into your tooling (machine-specific wiring is gitignored; the shareable
SKILL/AGENTS/rules are committed):

- **`yigraf install`** — **auto-detects** your host (Claude Code / Codex / Antigravity) and wires each;
  falls back to the universal MCP server for anything else. `--host <name>` targets one explicitly.
- **`yigraf install-claude-hooks`** — `.claude/settings.local.json` (machine-local hooks) + `SKILL.md`.
- **`yigraf install-codex-hooks`** — `.codex/hooks.json` (SessionStart + best-effort PostToolUse).
- **`yigraf install-antigravity`** — `.agents/rules/yigraf.md` + prints the MCP-server config to add.
- **`yigraf install-hooks`** — a git **post-commit** hook that keeps `graph.json` synced to `HEAD`.

For any other MCP host, run `yigraf mcp` as the configured server (see [`docs/mcp.md`](docs/mcp.md)).

## Language support

16 languages, indexed at two depths (bespoke extractors for Python/Go/JS-TS, a generic tags-query tier
for the rest). The full **tested** capability matrix — symbols / calls / imports / inheritance / drift,
per language — is in **[`docs/language-support.md`](docs/language-support.md)**.
