CodeVetter · Repo Unpack · System map
Graphify-Labs/graphify
A single-package Python CLI (`graphifyy`) structured as a staged pipeline: detect -> extract -> build -> cluster -> analyze -> report -> export, with each stage in its own module communicating through plain dicts and NetworkX graphs. The same library is driven two ways: headless via `graphify extract` subcommands in cli.py, or by an AI assistant following the packaged skill.md runbook that shells out to the library. Persistence is entirely file-based under graphify-out/ (graph.json, manifest.json, cache/, sidecars). Deployment surfaces are the PyPI wheel, per-platform skill files, and a Docker image that runs the MCP HTTP server.
- The canonical pipeline is detect() -> extract() -> build() -> cluster() -> analyze helpers -> report.generate() -> export.to_*(); each stage is a separate module exchanging plain dicts/NetworkX graphs with no shared state outside graphify-out/.
- Two console entry points ship in the wheel: `graphify` -> graphify.__main__:main and `graphify-mcp` -> graphify.serve:_main.
- graphify/__main__.py is a thin dispatcher: it re-exports the install subsystem from graphify/install.py (~90 names) and dispatch_command from graphify/cli.py, then main() wraps _run_cli() with broken-pipe handling.
- dispatch_command(cmd) in graphify/cli.py is the single command table for all non-install subcommands: provider, prs, hook, query, affected, god-nodes, save-result, reflect, path, explain, diagnose, add, watch, cluster-only/label, update, hook-check, hook-guard, check-update, tree, merge-driver, merge-graphs, clone, export, benchmark, global, extract, cache-check, merge-chunks, merge-semantic.
- All persistent state lives under the output directory `graphify-out`, overridable via the GRAPHIFY_OUT env var, centralized in graphify/paths.py (GRAPHIFY_OUT, out_path, default_graph_json) so security/path guards honor the same override.
- graph.json is a NetworkX node-link JSON file; serve.py _load_graph rehydrates it with json_graph.node_link_graph, forces directed=True for rendering, and attaches a work-memory overlay sidecar.
- AST extraction scales via concurrent.futures.ProcessPoolExecutor (_extract_parallel -> _extract_single_file worker, module-level for pickling), capped by cpu_count or GRAPHIFY_MAX_WORKERS, clamped to 61 on Windows, with sequential fallback on BrokenProcessPool/OSError.
- The MCP server is built once by serve.py::_build_server and served over stdio (serve()) or Streamable HTTP via starlette/uvicorn (serve_http), with optional X-API-Key/Bearer auth and a warning when binding 0.0.0.0 unauthenticated.
- The Dockerfile builds a python:3.12-slim image installing the [mcp] extra, runs as non-root uid 10001, and launches `python -m graphify.serve` with an HTTP transport default; graph.json is mounted at runtime, never baked in.
- Core dependencies are networkx, numpy, rapidfuzz, tree-sitter plus ~26 tree-sitter grammar packages; optional extras (pdf, office, video, mcp, neo4j, falkordb, sql, postgres, terraform, pascal, ocaml, commonlisp, robot, llm backends, all) gate niche extractors and integrations.
- Per-assistant skill bundles are generated artifacts: tools/skillgen/gen.py renders graphify/skill*.md, graphify/skills/<host>/references/, and graphify/always_on/*.md from tools/skillgen/fragments/, with CI drift guards (--check, --audit-coverage, --monolith-roundtrip).
- Publishing is trusted-publishing OIDC to PyPI on GitHub release (publish.yml), with a version==tag guard; release-graph.yml dogfoods the tool by building a graph of graphify itself and uploading graphify-self-graph.tar.gz as a release asset.
- The repo's own AGENTS.md instructs agents to read graphify-out/GRAPH_REPORT.md and run `graphify update .` after code changes — the project dogfoods its own graph.