Skip to content

Commit fa94df0

Browse files
authored
Merge pull request #31 from mtrdesign/feature/docs-site
docs: Material for MkDocs site published to GitHub Pages
2 parents 54ef0be + 69e23c7 commit fa94df0

26 files changed

Lines changed: 2024 additions & 316 deletions

.github/workflows/docs.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: docs
2+
3+
# Builds the Material for MkDocs site and deploys it to GitHub Pages.
4+
# Pages "Source" must be set to "GitHub Actions" once in repo Settings.
5+
on:
6+
push:
7+
branches: [main]
8+
paths: # only rebuild when docs inputs change
9+
- docs/**
10+
- mkdocs.yml
11+
- .github/workflows/docs.yml
12+
- pyproject.toml
13+
workflow_dispatch: # allow manual rebuilds
14+
15+
permissions:
16+
contents: read
17+
pages: write
18+
id-token: write
19+
20+
concurrency: # never run two deploys at once
21+
group: pages
22+
cancel-in-progress: false
23+
24+
jobs:
25+
build:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
with:
30+
fetch-depth: 0 # full history → correct "last updated" dates
31+
- name: Install Cairo/Pango for social cards
32+
run: |
33+
sudo apt-get update
34+
sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev \
35+
libjpeg-dev libpng-dev libz-dev libpango-1.0-0 libpangocairo-1.0-0
36+
- uses: astral-sh/setup-uv@v5
37+
with: { enable-cache: true }
38+
- run: uv sync --group docs
39+
- run: uv run mkdocs build --strict # CI=true ⇒ social cards generate; --strict fails on broken links
40+
- uses: actions/upload-pages-artifact@v3
41+
with: { path: site }
42+
43+
deploy:
44+
needs: build
45+
runs-on: ubuntu-latest
46+
environment:
47+
name: github-pages
48+
url: ${{ steps.deployment.outputs.page_url }}
49+
steps:
50+
- id: deployment
51+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,9 @@ whygraph.toml
2626

2727
# Local scratch space for in-progress plan markdown (not version-controlled).
2828
plans/
29+
30+
# MkDocs build output (the site is built and deployed by CI, never committed).
31+
site/
32+
33+
# Material social-plugin font/image cache.
34+
.cache/

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ IMAGE ?= whygraph:dev
1313
# Name of the long-running container started by `make image-debug`.
1414
DEBUG_NAME ?= whygraph-debug
1515

16-
.PHONY: help sync test scan db db-down inspect image image-test image-inspect image-debug image-debug-down
16+
.PHONY: help sync test scan docs docs-build db db-down inspect image image-test image-inspect image-debug image-debug-down
1717

1818
help: ## List available targets
1919
@grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | sort | awk 'BEGIN{FS=":.*?## "}{printf " %-10s %s\n", $$1, $$2}'
@@ -27,6 +27,12 @@ test: ## Run the test suite
2727
scan: ## Re-scan this repo so WhyGraph is tested against itself
2828
uv run whygraph scan
2929

30+
docs: ## Serve the docs site locally with live reload (social cards skipped — no Cairo needed)
31+
uv run mkdocs serve
32+
33+
docs-build: ## Build the static docs site into ./site (strict; cards skipped unless CI=true)
34+
uv run mkdocs build --strict
35+
3036
db: ## Start the DBGate database viewer (http://localhost:8081)
3137
@test -f docker-compose.yml || { echo "error: docker-compose.yml missing - run: cp docker-compose.example.yml docker-compose.yml"; exit 1; }
3238
@test -f .whygraph/whygraph.db || echo "warning: .whygraph/whygraph.db missing - run 'make scan' first"

README.md

Lines changed: 13 additions & 315 deletions
Large diffs are not rendered by default.

docs/deploy/docker.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Run with Docker
2+
3+
Don't want Python, Node, `gh`, and CodeGraph on your machine? WhyGraph ships as a self-contained
4+
image. Your host needs **only Docker**. Install a tiny shim, then it's the same `init` and `scan` as a
5+
native install.
6+
7+
```bash
8+
curl -fsSL https://raw.githubusercontent.com/mtrdesign/whygraph/main/scripts/install.sh | sh
9+
10+
cd your-repo
11+
whygraph init # bootstrap the WhyGraph DB + write config
12+
whygraph scan # crawl history + refresh CodeGraph + LLM descriptions
13+
```
14+
15+
## How the shim works
16+
17+
`install.sh` drops `whygraph` and `whygraph-mcp` shims on your `PATH`. Each one runs the published
18+
image against the current directory:
19+
20+
```bash
21+
docker run --rm -v "$PWD:/workspace" -w /workspace ghcr.io/mtrdesign/whygraph whygraph "$@"
22+
```
23+
24+
The container is **ephemeral per command** - no compose, no `docker exec`, nothing to start or stop.
25+
Each invocation is a fresh process against the repo you're standing in.
26+
27+
- **Everything's in the image** - Python and WhyGraph, `git`, the GitHub CLI, and Node with the
28+
CodeGraph CLI. CodeGraph indexes from the in-image binary, so there's no docker-in-docker.
29+
- **Per-project config just works.** Each command reads the current repo's own `whygraph.toml`,
30+
`.whygraph/`, and `.codegraph/`.
31+
- **Files come back as yours.** The shim runs as your host user, so generated files aren't
32+
root-owned and git sees matching ownership.
33+
34+
## Credentials
35+
36+
The shim passes your environment through. A GitHub token goes in `[scan].token` of the repo's
37+
`whygraph.toml` (gitignored), and the shim also forwards `GH_TOKEN` / `GITHUB_TOKEN` plus
38+
`ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `DEEPSEEK_API_KEY` from your environment.
39+
40+
!!! warning "Never bake a token into the image"
41+
Pass credentials at run time, never at build time. The repo's gitignored `whygraph.toml` is the
42+
right home for a pinned token.
43+
44+
## Wire your editor, still only Docker
45+
46+
The MCP server is containerized too. `install.sh` drops a `whygraph-mcp` shim alongside `whygraph`, so
47+
there's nothing extra to install. Wire your editor from inside the repo:
48+
49+
```bash
50+
whygraph init --agent claude # writes .mcp.json (also: --agent cursor / vscode / codex)
51+
```
52+
53+
The generated config launches `whygraph-mcp` by bare command name. Your editor resolves it to the
54+
shim, which starts a per-session container speaking MCP over stdio. It reads the repo's `.whygraph/`
55+
and `.codegraph/` over the same `/workspace` mount the scan writes to - so the editor and the scan
56+
share one source of truth on disk.
57+
58+
## Build the image yourself
59+
60+
Building locally instead of pulling - say, while developing:
61+
62+
```bash
63+
docker build -f docker/whygraph/Dockerfile -t whygraph:latest .
64+
WHYGRAPH_IMAGE=whygraph:latest whygraph scan
65+
```
66+
67+
`WHYGRAPH_IMAGE` overrides the image the shim runs, so you can test a local build without touching the
68+
install.

docs/deploy/index.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Docker & Self-Hosting
2+
3+
WhyGraph ships as a self-contained image, so there are two ways to run it. Both use the same image;
4+
they differ in who's driving.
5+
6+
<div class="grid cards" markdown>
7+
8+
- :material-laptop:{ .lg .middle } __As a local dev tool__
9+
10+
---
11+
12+
Install the Docker shim, then `init` and `scan` your repos and wire your editor - no Python or
13+
Node on the host. This is the default install.
14+
15+
[:octicons-arrow-right-24: Run with Docker](docker.md)
16+
17+
- :material-server-network:{ .lg .middle } __As a service__
18+
19+
---
20+
21+
A containerized `whygraph-mcp` endpoint that real applications - not just editors - connect to
22+
for git-based analysis of a target repo.
23+
24+
[:octicons-arrow-right-24: WhyGraph as a service](service.md)
25+
26+
</div>
27+
28+
Most people start with the local tool. Reach for the service model when you're building an
29+
application that needs the *why* behind code - a review bot, an onboarding assistant, an internal
30+
portal.

docs/deploy/service.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# WhyGraph as a service
2+
3+
Editors aren't the only thing that can talk to WhyGraph. The MCP server is a plain stdio program, so
4+
any application that speaks MCP can connect to it for git-based analysis of a target repo. Think of a
5+
review bot, an onboarding assistant, or an internal dev portal that needs the *why* behind a chunk of
6+
code - not just the code.
7+
8+
This page covers that model: a containerized `whygraph-mcp` endpoint a third-party app drives over
9+
MCP, reading the same on-disk data your scan produces.
10+
11+
## The shape of it
12+
13+
A consuming app launches the WhyGraph image, mounts the target repo at `/workspace`, and speaks MCP
14+
over stdio. The scan **writes** the databases; the MCP server **reads** them. One repo on disk is the
15+
single source of truth.
16+
17+
```mermaid
18+
flowchart LR
19+
app["Consuming app<br/>(bot · portal · assistant)"]
20+
mcp["whygraph-mcp<br/>(container)"]
21+
repo[("/workspace mount<br/>.whygraph + .codegraph")]
22+
23+
app -- "MCP over stdio" --> mcp
24+
mcp -- "reads cached evidence + rationale" --> repo
25+
scan["whygraph scan"] -- "writes" --> repo
26+
```
27+
28+
The consuming app gets the full read surface over MCP:
29+
30+
- **Evidence** - `whygraph_evidence_for` and `whygraph_area_history` for the commits, PRs, and issues
31+
behind a path or symbol.
32+
- **Rationale** - `whygraph_rationale_brief` for a structured why-this-exists card.
33+
- **Resources** - `whygraph://commit/{sha}`, `whygraph://pr/{number}`, `whygraph://issue/{number}`,
34+
and `whygraph://repo/overview`.
35+
36+
See the [MCP surface reference](../reference/mcp.md) for exact signatures.
37+
38+
## Scan first
39+
40+
The server reads cached data - it doesn't crawl on demand. So the target repo must be scanned before
41+
an app connects, or the tools have nothing to return.
42+
43+
```bash
44+
cd /path/to/target-repo
45+
whygraph scan
46+
```
47+
48+
!!! warning "An unscanned repo returns nothing"
49+
`whygraph_rationale_brief` raises an error when a target maps to no scanned commit, and the
50+
evidence tools come back empty. Run `whygraph scan` (and keep it fresh with
51+
[git hooks](../guide/scanning.md#keep-it-fresh)) before pointing an app at the server.
52+
53+
## Launch the endpoint
54+
55+
The MCP server runs from the same image as everything else. Mount the target repo and run
56+
`whygraph-mcp`:
57+
58+
```bash
59+
docker run --rm -i \
60+
-v "/path/to/target-repo:/workspace" -w /workspace \
61+
ghcr.io/mtrdesign/whygraph whygraph-mcp
62+
```
63+
64+
The `-i` flag keeps stdin open for the MCP stdio transport. Your app spawns this command and talks
65+
JSON-RPC to it, exactly as an editor would. The [`install.sh` shim](docker.md) wraps the same call as
66+
a bare `whygraph-mcp` on `PATH`.
67+
68+
## Credentials
69+
70+
What the app needs depends on what it asks for:
71+
72+
- **Reading cached evidence and rationale needs no credentials.** It's all in the mounted databases.
73+
- **Generating a *new* rationale card needs an LLM key.** `whygraph_rationale_brief` calls the
74+
configured provider on a cache miss. Supply the key through the environment
75+
(`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `DEEPSEEK_API_KEY`) or the repo's `whygraph.toml`
76+
`[llm.*]` table.
77+
78+
!!! info "Tokens never live in the image"
79+
Pass credentials at run time via env or the gitignored `whygraph.toml` - never bake them into a
80+
built image. This matches WhyGraph's own invariant for the Docker shim.
81+
82+
## Current scope
83+
84+
Today the server speaks MCP over **stdio, one session per process**. There's no long-running HTTP
85+
endpoint yet - each connection is its own `docker run`. A persistent server mode with an HTTP MCP
86+
transport is on the [roadmap](../roadmap.md), not built.
87+
88+
For now, model your integration as "spawn a session, run the tools you need, let it exit" - the same
89+
lifecycle an editor uses, driven by your app instead.

docs/getting-started/index.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Getting Started
2+
3+
WhyGraph is a rationale layer over [CodeGraph](https://github.com/colbymchenry/codegraph). CodeGraph
4+
maps what your code *is* - symbols, callers, callees. WhyGraph adds *why* it exists, drawn from the
5+
history around it.
6+
7+
For each chunk of code, it collects evidence from git and GitHub - commits, blame, pull requests, the
8+
issues those PRs closed - and links it together. Then it exposes that evidence to your AI editor over
9+
MCP, plus an on-demand rationale card (purpose, why, constraints, tradeoffs, risks) that it caches.
10+
11+
You install WhyGraph once, then wire it into each repo you want it to analyze. It speaks MCP, so any
12+
editor that does too can use it.
13+
14+
## CodeGraph vs WhyGraph
15+
16+
The two tools stay in their lanes:
17+
18+
| Layer | Answers | Examples |
19+
|---|---|---|
20+
| **CodeGraph** | "What's connected to what?" | callers, callees, symbol resolution, type hierarchy |
21+
| **WhyGraph** | "Why does this exist, and when did it change?" | evidence, rationale cards, area history |
22+
23+
Run both. WhyGraph reads CodeGraph's index to resolve a symbol to a file and line range, then layers
24+
its own history on top.
25+
26+
## Prerequisites
27+
28+
You don't need all of these - most are optional, and the phases that depend on them skip cleanly when
29+
they're missing.
30+
31+
- **[uv](https://docs.astral.sh/uv/)** *or* **Docker** - uv for a native install, or Docker alone for
32+
the [container install](installation.md). With Docker, you need nothing else on your host.
33+
- **git** - your repo history is the primary evidence source.
34+
- **Docker** *(native installs only)* - when no `codegraph` binary is on `PATH`, `whygraph scan` runs
35+
CodeGraph inside the WhyGraph image to index the repo.
36+
- **[`gh` CLI](https://cli.github.com/)**, authenticated - only for GitHub repos, and only if you
37+
enable the remote crawl. Without it, the GitHub phase is skipped.
38+
- **`claude` CLI** *or* an LLM API key - for per-commit descriptions and rationale cards. Both phases
39+
skip cleanly if neither is available.
40+
41+
Ready to install?
42+
43+
<div class="grid cards" markdown>
44+
45+
- :material-download:{ .lg .middle } __Installation__
46+
47+
---
48+
49+
Docker, PyPI, GitHub, or a local checkout - pick the path that fits.
50+
51+
[:octicons-arrow-right-24: Install WhyGraph](installation.md)
52+
53+
- :material-rocket-launch:{ .lg .middle } __Quickstart__
54+
55+
---
56+
57+
Init, scan, wire an editor - the happy path in four commands.
58+
59+
[:octicons-arrow-right-24: Quickstart](quickstart.md)
60+
61+
</div>

0 commit comments

Comments
 (0)