Metadata-Version: 2.4
Name: yigraf
Version: 0.1.10
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: networkx>=3.4
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
Requires-Dist: numpy>=1.24; extra == 'embeddings'
Requires-Dist: sentence-transformers>=2.2; extra == 'embeddings'
Provides-Extra: mcp
Requires-Dist: mcp>=1.2; extra == 'mcp'
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** *(optional, `[mcp]` extra)* | only needed to run `yigraf mcp` (the pull channel); the CLI + hooks work without it |
| **An embeddings backend** *(optional, `[embeddings]` extra)* | semantic recall of memory/intent by meaning; **falls back to lexical** retrieval if absent — never required |

## Quickstart

```bash
# 1. install (now on PyPI)
pip install yigraf

# 2. in your repo: create the workspace and index the code
cd your-repo
yigraf init
yigraf build

# 3. wire it into your agent host — auto-detects Claude Code / Codex / Antigravity, else MCP
yigraf install
# target one explicitly with: yigraf install --host claude|codex|antigravity|mcp

# 4. use it
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
pipx install yigraf                # isolated CLI (recommended)
uv tool install yigraf             # isolated CLI, via uv

# with semantic recall (numpy + sentence-transformers):
pip install "yigraf[embeddings]"
```

### 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)**.
