Skip to content

feat: whygraph serve — the Explorer playground panel - #36

Merged
cvetty merged 3 commits into
mainfrom
feat/whygraph-serve-playground
Jul 24, 2026
Merged

feat: whygraph serve — the Explorer playground panel#36
cvetty merged 3 commits into
mainfrom
feat/whygraph-serve-playground

Conversation

@cvetty

@cvetty cvetty commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

What

Adds whygraph serve — a read-only, loopback-only web Explorer playground served from the existing Docker image as its own long-lived container. Browse the code graph CodeGraph built, jump to any symbol, and read its rationale, evidence, relationships, and history side by side.

The web API is a thin second adapter over the exact service functions the MCP tools call (whygraph_rationale_brief, whygraph_evidence_for, whygraph_area_history, the resource readers), so the panel's cards can never drift from what an editor sees over MCP. Replaces the old viewer that was slow/glitchy on large graphs.

Why this design

  • Same image, separate container — no second image to publish/version, no card drift.
  • Never render the whole graph — bounded ego-graph + directory→file→symbol LOD, layered layout with coordinates computed server-side (the client never runs a force sim — the fix for the old viewer's jank).
  • Rationale is button-triggered — passive viewing makes no LLM call (GET is cache-only); the explicit Generate button runs the same MCP generate-and-cache flow. It reuses the [rationale] + [llm.<provider>] config from whygraph.toml — same provider, key, and cache as the MCP tool.
  • Read-only except that one Generate action; localhost-only, no auth (single-user dev tool).

What's in it

Backend (src/whygraph/serve/, FastAPI):

  • graphdata — ego graph + lazy containment tree with server coordinates.
  • routes/api search, tree, graph/ego, node detail, evidence, history, commit/pr/issue. Rationale split into cache-only GET and generate POST.
  • lifting + coverage + /api/graph/overview — Phase-2 weighted/directional edge roll-up to dir/file super-nodes + a coverage heatmap (the LOD landing view).
  • app — SPA fallback; degrades to an API-only "UI not built" page when the bundle is absent.

CodeGraph (services/codegraph/graph.py): generalized _calls_relationsrelations(kind, incoming); added imports_/container/children/files + Phase-2 file_edges/definition_ranges. Confirmed the contains edge direction empirically against real data.

Playground (src/playground/): Vite + React + TS, Tailwind (shadcn-style), @xyflow/react ego graph + elkjs overview, TanStack Query, cmdk palette, and a single canonical openNode() used by search, graph clicks, and relationship rows.

Delivery: multi-stage Dockerfile (arch-independent playground-build stage); the whygraph shim's serve branch (loopback -p, WHYGRAPH_PORT, --detach/--stop/--logs); a hatch build hook that packs the bundle into the wheel via artifacts. Makefile gains playground, playground-dev, and a dev HMR loop.

Deps: fastapi>=0.110, uvicorn>=0.27 (lockfile updated).

Docs: new "Explorer playground" guide page + nav; whygraph serve added to the CLI reference (it was missing); README + Quickstart mentions.

Try it

whygraph init && whygraph scan   # scan first — builds the index + evidence
whygraph serve                   # → http://localhost:8765

Testing

  • 558 Python tests pass; ruff check + ruff format --check clean.
  • New tests: CodeGraph traversal + Phase-2 lifting (the 3 cases) + coverage; FastAPI TestClient integration incl. the rationale split (GET makes no LLM call; POST equals whygraph_rationale_brief verbatim — proves zero drift).
  • Verified end-to-end against this repo's real .codegraph data (tree, Cmd-K, ego graph, node detail, overview) and the shim lifecycle against a stubbed docker; wheel packs the bundle with no src/playground leak; the frontend Docker stage builds.

Notes for reviewers

  • Deferred (one §11 item): frontend component tests (vitest). CI gates only on ruff + pytest; the SPA was verified via a real production build + manual end-to-end smoke.
  • The mkdocs build --strict gate runs in CI (the material theme isn't installable in the dev sandbox); links/nav/anchors were validated mechanically here.

cvetty added 3 commits July 24, 2026 18:16
A read-only, loopback-only web UI served from the existing Docker image as
its own long-lived container, launched with `whygraph serve`. The web API is
a thin second adapter over the exact service functions the MCP tools call, so
the panel's rationale/evidence/history can never drift from the MCP's.

Backend (src/whygraph/serve/, FastAPI):
- graphdata: bounded ego-graph with server-computed layered coordinates + a
  lazy dir→file→symbol containment tree (no client-side force layout — the fix
  for the old viewer being slow/glitchy).
- routes: /api search, tree, graph/ego, node detail, evidence, history,
  commit/pr/issue. Rationale is split — GET is cache-only (never calls an LLM);
  POST runs whygraph_rationale_brief verbatim (the explicit Generate action).
- Phase 2: lifting (weighted, directional edge roll-up to dir/file super-nodes)
  + coverage heatmap + /api/graph/overview (the LOD landing view).
- app: SPA fallback; degrades gracefully to an API-only "UI not built" page.

CodeGraph: generalize _calls_relations into relations(kind, incoming); add
imports_/container/children/files + Phase-2 file_edges/definition_ranges.
Empirically confirmed the `contains` edge direction against real data.

Playground (src/playground/): Vite + React + TS, Tailwind (shadcn-style),
@xyflow/react ego graph + elkjs overview, TanStack Query, cmdk palette, and a
single canonical openNode() used by search, graph clicks, and relationship rows.

Delivery: multi-stage Dockerfile (arch-independent playground-build stage) +
the `whygraph` shim's `serve` branch (loopback -p, WHYGRAPH_PORT, --detach/
--stop/--logs) + a hatch build hook that packs the bundle into the wheel via
`artifacts`. Makefile gains `playground`, `playground-dev`, and a `dev` HMR loop.

Deps: fastapi>=0.110, uvicorn>=0.27. 558 tests pass; ruff clean.
- New User Guide page: what the panel is, how to run it, the container
  lifecycle (--detach/--stop/--logs, WHYGRAPH_PORT), the tree/graph/detail
  layout, button-triggered rationale + the "scan first" caveat, the coverage
  heatmap, and the `make dev` HMR loop.
- Add it to the mkdocs nav and a card on the User Guide + Quickstart index.
- CLI reference: add the `whygraph serve` command (it was missing) with its
  --port/--host flags and the shim-level lifecycle verbs; fix the count.
- Short mentions in README and the Quickstart.
…M config

Clarify that the Generate button uses the [rationale] provider + [llm.<provider>]
api_key from whygraph.toml (what `whygraph init` sets up), with the provider env
var only as a fallback — not an env-first requirement.
@cvetty
cvetty merged commit 82e0e69 into main Jul 24, 2026
2 checks passed
@cvetty
cvetty deleted the feat/whygraph-serve-playground branch July 28, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant