{"id":48821496,"url":"https://github.com/parisgroup-ai/graphify","last_synced_at":"2026-05-11T05:02:56.161Z","repository":{"id":350934591,"uuid":"1208743013","full_name":"parisgroup-ai/graphify","owner":"parisgroup-ai","description":"Rust CLI for architectural analysis of codebases — extracts dependencies via tree-sitter AST, builds knowledge graphs, identifies hotspots and circular dependencies","archived":false,"fork":false,"pushed_at":"2026-05-02T19:47:45.000Z","size":348375,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-02T21:32:10.014Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/parisgroup-ai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-12T17:30:03.000Z","updated_at":"2026-05-02T19:47:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/parisgroup-ai/graphify","commit_stats":null,"previous_names":["parisgroup-ai/graphify"],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/parisgroup-ai/graphify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parisgroup-ai%2Fgraphify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parisgroup-ai%2Fgraphify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parisgroup-ai%2Fgraphify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parisgroup-ai%2Fgraphify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/parisgroup-ai","download_url":"https://codeload.github.com/parisgroup-ai/graphify/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parisgroup-ai%2Fgraphify/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32806692,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-14T15:00:52.923Z","updated_at":"2026-05-09T04:01:35.277Z","avatar_url":"https://github.com/parisgroup-ai.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Graphify\n\nArchitectural analysis of codebases. Extracts dependencies via tree-sitter AST parsing, builds knowledge graphs with petgraph, and generates structured reports identifying hotspots, circular dependencies, and community clusters.\n\nDistributed as a single static binary — no runtime dependencies. macOS + Linux.\n\n## Install\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/parisgroup-ai/graphify/main/install.sh | sh\n```\n\nOr download from [Releases](https://github.com/parisgroup-ai/graphify/releases).\n\nBuild from source:\n\n```bash\ncargo install --path crates/graphify-cli\n```\n\n## Quick Start\n\n```bash\ngraphify init                                 # generate graphify.toml only\ngraphify install-integrations --project-local # install slash commands, skills, agents, MCP config\n# edit graphify.toml to point at your project(s)\ngraphify run                                  # extract → analyze → report\n```\n\n## Configuration\n\n```toml\n[settings]\noutput = \"./report\"\nweights = [0.4, 0.2, 0.2, 0.2]  # betweenness, pagerank, in_degree, in_cycle\nexclude = [\"__pycache__\", \"node_modules\", \".git\", \"dist\", \"tests\"]\nformat = [\"json\", \"csv\", \"md\", \"html\"]  # also: neo4j, graphml, obsidian\n\n[[project]]\nname = \"my-app\"\nrepo = \"./apps/my-app\"\nlang = [\"python\"]\nlocal_prefix = \"app\"\n\n[[policy.group]]\nname = \"feature\"\nmatch = [\"src.features.*\"]\npartition_by = \"segment:2\"\n\n[[policy.group]]\nname = \"infra\"\nmatch = [\"src.infra.*\", \"app.infra.*\"]\n\n[[policy.rule]]\nname = \"no-cross-feature-imports\"\nkind = \"deny\"\nfrom = [\"group:feature\"]\nto = [\"group:feature\"]\nallow_same_partition = true\n\n[[policy.rule]]\nname = \"infra-is-restricted\"\nkind = \"deny\"\nfrom = [\"project:*\"]\nto = [\"group:infra\"]\nexcept_from = [\"group:app\", \"group:bootstrap\"]\n```\n\nMultiple `[[project]]` sections enable monorepo analysis. Each project gets its own output subdirectory.\n\nPolicy selectors support:\n- `group:\u003cname\u003e` for named namespace groups\n- `project:\u003cglob\u003e` for configured project names\n\n`partition_by = \"segment:N\"` lets a group derive peer partitions from dotted node IDs, so rules like feature-to-feature isolation can allow imports within the same feature while blocking cross-feature imports.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `graphify init` | Generate a `graphify.toml` template only (integrations are separate) |\n| `graphify extract` | Extract dependency graph (produces `graph.json`) |\n| `graphify analyze` | Extract + compute metrics (produces `analysis.json`, CSV) |\n| `graphify report` | Full pipeline with all outputs |\n| `graphify run` | Alias for `report` |\n| `graphify query \"pattern\"` | Search nodes by glob pattern |\n| `graphify explain \u003cnode\u003e` | Module profile card + impact analysis |\n| `graphify path \u003csource\u003e \u003ctarget\u003e` | Find dependency paths between modules |\n| `graphify diff` | Detect architectural drift between snapshots |\n| `graphify compare` | Compare two existing analysis outputs head-to-head |\n| `graphify trend` | Aggregate historical trends from stored snapshots |\n| `graphify check` | Validate CI quality gates and declarative policy rules |\n| `graphify pr-summary` | Render a PR-ready Markdown summary of architectural change |\n| `graphify consolidation` | Emit consolidation candidates (shared-leaf symbol groups) as JSON or Markdown |\n| `graphify watch` | Auto-rebuild on file changes (300ms debounce) |\n| `graphify shell` | Interactive graph exploration REPL |\n\n### Flags\n\n| Flag | Applies to | Description |\n|------|-----------|-------------|\n| `--config \u003cpath\u003e` | all | Path to `graphify.toml` (default: `./graphify.toml`) |\n| `--force` | extract, analyze, report, run, check | Bypass extraction cache, full rebuild |\n| `--json` | query, explain, check | Output as JSON |\n| `--project \u003cname\u003e` | query, explain, path, diff, check | Filter to a specific project |\n| `--all` | path | Show all paths (not just shortest) |\n| `--max-depth \u003cn\u003e` | path | Limit path search depth |\n| `--threshold \u003cf\u003e` | diff, compare | Minimum score delta to report (default: 0.05) |\n\n## Output Formats\n\nEach project produces a subdirectory under the configured output path:\n\n| File | Format | Description |\n|------|--------|-------------|\n| `graph.json` | JSON | Dependency graph (NetworkX `node_link_data` format) |\n| `analysis.json` | JSON | Metrics, communities, cycles, confidence summary |\n| `graph_nodes.csv` | CSV | Node metrics (betweenness, PageRank, score, community) |\n| `graph_edges.csv` | CSV | Edge list with weights and confidence |\n| `architecture_report.md` | Markdown | Human-readable report with hotspots, cycles, communities |\n| `architecture_graph.html` | HTML | Interactive D3.js force-directed graph visualization |\n| `graph.cypher` | Cypher | Neo4j import script (`CREATE` nodes + relationships) |\n| `graph.graphml` | GraphML | XML export (compatible with yEd, Gephi) |\n| `obsidian_vault/` | Markdown | Obsidian vault with one `.md` per node and `[[wikilinks]]` |\n| `drift-report.json` | JSON | Drift detection results (via `graphify diff`) |\n| `drift-report.md` | Markdown | Drift detection report |\n| `compare-report.json` | JSON | Head-to-head comparison results (via `graphify compare`) |\n| `compare-report.md` | Markdown | Head-to-head comparison report |\n| `check-report.json` | JSON | Unified check result (rules + contract drift); written by `graphify check` |\n| `history/*.json` | JSON | Per-run historical snapshots used by `graphify trend` |\n| `trend-report.json` | JSON | Aggregated trend report across stored snapshots |\n| `trend-report.md` | Markdown | Human-readable architecture trend report |\n\nWhen 2+ projects are configured, a `graphify-summary.json` with aggregate stats is also generated.\n\n## Incremental Builds\n\nGraphify caches extraction results per file using SHA256 content hashing. On subsequent runs, only changed files are re-parsed.\n\n```bash\ngraphify run              # first run: full extraction\ngraphify run              # second run: cache hit, skips unchanged files\ngraphify run --force      # bypass cache, full rebuild\n```\n\nThe cache is stored as `.graphify-cache.json` in each project's output directory. It auto-invalidates on version upgrades or `local_prefix` changes.\n\n## Drift Detection\n\nCompare analysis snapshots to detect architectural drift:\n\n```bash\n# File vs file\ngraphify diff --before report/v1/analysis.json --after report/v2/analysis.json\n\n# Baseline vs live project\ngraphify diff --baseline report/baseline/analysis.json --config graphify.toml --project my-app\n```\n\nDetects changes across 5 dimensions: node additions/removals, hotspot score shifts, cycle introduction/resolution, community membership moves, and degree changes.\n\n## Comparing Existing Outputs\n\nUse `graphify compare` when both sides already produced Graphify artifacts, such as two CI runs, two branch snapshots, or two PR artifact directories. Each input can be an `analysis.json` file or a directory containing one.\n\n```bash\n# Compare two branch snapshots\ngraphify compare report/main/my-app report/feature/my-app \\\n  --left-label main \\\n  --right-label feature \\\n  --output report/compare-main-feature\n\n# Compare two CI artifacts directly\ngraphify compare artifacts/pr-123/analysis.json artifacts/pr-456/analysis.json \\\n  --left-label PR-123 \\\n  --right-label PR-456\n```\n\nThe command writes `compare-report.json` and `compare-report.md`, and prints a concise stdout summary. It uses the same diff engine as `graphify diff`; labels only change the report framing.\n\n## Historical Trends\n\n`graphify run` and `graphify report` now persist a compact historical snapshot for each project under `report/\u003cproject\u003e/history/`.\n\nAggregate those snapshots into a trend report with:\n\n```bash\ngraphify trend --config graphify.toml --project my-app\ngraphify trend --config graphify.toml --project my-app --limit 10 --json\n```\n\nV1 trend reports include:\n- node, edge, community, and cycle totals over time\n- hotspot entrants/exits and score movement between adjacent snapshots\n- community churn between adjacent snapshots\n- JSON and Markdown outputs written next to the project report directory by default\n\n## Contract Drift (v0.5.0+)\n\nDetects structural drift between ORM schemas and TypeScript contract types across a monorepo — e.g. a Drizzle table in `packages/db` vs the DTO interface the API layer exports in `packages/api`. Graphify normalizes both sides into a shared `Contract` model, aligns fields (with snake_case \u003c-\u003e camelCase handling), and flags missing fields, type mismatches, nullability differences, and relation cardinality drift.\n\nDeclare one or more `[[contract.pair]]` entries in `graphify.toml`:\n\n```toml\n[[project]]\nname = \"db\"\nrepo = \"./packages/db\"\nlang = [\"typescript\"]\n\n[[project]]\nname = \"api\"\nrepo = \"./packages/api\"\nlang = [\"typescript\"]\n\n[[contract.pair]]\nname = \"user\"\norm  = { source = \"drizzle\", file = \"packages/db/src/schema/user.ts\", table = \"users\" }\nts   = { file   = \"packages/api/src/types/user.ts\", export = \"UserDto\" }\n\n[[contract.pair]]\nname = \"post\"\norm  = { source = \"drizzle\", file = \"packages/db/src/schema/post.ts\", table = \"posts\" }\nts   = { file   = \"packages/api/src/types/post.ts\", export = \"PostDto\" }\n```\n\nThen run the standard gate command:\n\n```bash\ngraphify check --config graphify.toml\n```\n\nThe contract drift gate runs automatically when one or more `[[contract.pair]]` entries are declared. Opt-out with `--no-contracts`; promote warnings to hard failures with `--contracts-warnings-as-errors`. The gate is included in both human and `--json` output of `graphify check`.\n\nSupported in v1:\n- Drizzle ORM (Postgres, MySQL, SQLite variants) on the ORM side\n- TypeScript `interface` and `type` declarations on the TS side\n\nV1 limitations:\n- Prisma schemas are not yet supported\n- Zod schemas and tRPC router inputs/outputs are not supported\n- `target_contract` on the ORM side is accepted in config but not compared (advisory for now)\n- Relation nullability comparison is deferred\n- Pair-level `line` in JSON output is hardcoded to `1` (editor integration will address this in FEAT-015)\n\nSee [`docs/TaskNotes/Tasks/FEAT-016-contract-drift-detection-between-orm-and-typescript.md`](docs/TaskNotes/Tasks/FEAT-016-contract-drift-detection-between-orm-and-typescript.md) for the full task record.\n\n## Quality Gates (CI)\n\nUse `graphify check` in CI pipelines to enforce architectural constraints:\n\n```bash\ngraphify check --config graphify.toml --max-cycles 0 --max-hotspot-score 0.5\ngraphify check --config graphify.toml --max-cycles 0 --json  # machine-readable output\ngraphify check --config graphify.toml --json                 # policy-only checks\n```\n\nExit code 0 = all checks pass, non-zero = violations found.\n\n### Per-project threshold overrides (v0.12.2+)\n\nWhen a workspace wants a strict default gate but one project is a legitimate exception (a theme provider, an i18n context, a shared router hook), declare a `[project.check]` sub-table under the `[[project]]` block to override the CLI flags for that project only:\n\n```toml\n[[project]]\nname = \"pageshell-native\"\nrepo = \"./pageshell-native/src\"\nlang = [\"typescript\"]\nlocal_prefix = \"@parisgroup-ai/pageshell-native\"\n\n[project.check]\nmax_hotspot_score = 0.75\nmax_cycles = 0\n# Rationale: NativeThemeContext is a legitimate 48-consumer facade.\n```\n\n**Precedence per field:** `[project.check]` \u003e CLI flag \u003e None (no gate).\n\n| Scenario | CLI flag | `[project.check]` | Effective gate |\n|---|---|---|---|\n| Workspace default only | `--max-hotspot-score 0.70` | (absent) | 0.70 |\n| Project override in place | `--max-hotspot-score 0.70` | `max_hotspot_score = 0.75` | 0.75 |\n| Override on CLI-less run | (omitted) | `max_hotspot_score = 0.75` | 0.75 |\n| No limits at all | (omitted) | (absent) | no gate (passes) |\n\nThe project-wins rule lets a workspace CI keep `graphify check --max-cycles 0 --max-hotspot-score 0.70` as the default for every project, while specific exceptions opt out inline with a committed, version-controlled comment. Typos inside `[project.check]` (e.g. `max_hoptspot_score`) fail the parse rather than silently disabling the gate.\n\nExample policy recipes:\n\n```toml\n[[policy.group]]\nname = \"feature\"\nmatch = [\"src.features.*\"]\npartition_by = \"segment:2\"\n\n[[policy.rule]]\nname = \"no-cross-feature-imports\"\nkind = \"deny\"\nfrom = [\"group:feature\"]\nto = [\"group:feature\"]\nallow_same_partition = true\n\n[[policy.group]]\nname = \"config\"\nmatch = [\"app.config*\", \"src.config*\"]\n\n[[policy.rule]]\nname = \"config-is-restricted\"\nkind = \"deny\"\nfrom = [\"project:*\"]\nto = [\"group:config\"]\nexcept_from = [\"group:app\", \"group:bootstrap\"]\n```\n\n`graphify check --json` now returns both limit violations and policy violations. Policy entries include `type = \"policy\"`, `rule`, `source_node`, `target_node`, `source_project`, and `target_project`.\n\n### Render a PR summary for GitHub Actions\n\nAfter `graphify run` + `graphify diff` + `graphify check` populate the project output directory, append a concise Markdown summary to the GitHub Actions job summary:\n\n```yaml\n- run: graphify run --config graphify.toml\n- run: graphify diff --baseline ./baseline/analysis.json --config graphify.toml --project my-app\n- run: graphify check --config graphify.toml || true\n- run: graphify pr-summary ./report/my-app \u003e\u003e \"$GITHUB_STEP_SUMMARY\"\n```\n\n`graphify pr-summary \u003cDIR\u003e` is a pure renderer: it reads existing JSON artifacts (`analysis.json` required; `drift-report.json` and `check-report.json` optional) and prints Markdown to stdout. Exit code is 0 regardless of findings — gate with `graphify check` separately if you want CI to fail on violations.\n\nOutput is optimized for solo-dev + AI-authored PR review: each finding carries an inline `graphify explain` / `graphify path` hint so the next investigation step is one copy-paste away.\n\nHotspot rows in the `Drift in this PR` section are tail-annotated when the project has a `[consolidation]` section configured:\n\n- `[allowlisted]` — the node's id appears in `analysis.json`'s `allowlisted_symbols` (i.e. its leaf symbol matched a `[consolidation].allowlist` pattern). Reviewers can safely deprioritize these entries.\n- `[intentional mirror]` — the node is declared under `[consolidation.intentional_mirrors]` in `graphify.toml` (FEAT-023). Takes precedence over `[allowlisted]` when both apply.\n\nBoth annotations are tail-appended so the row's primary content (symbol name, score, delta) stays leftmost and scannable.\n\n### Suggest external_stubs additions\n\n`graphify suggest stubs` analyses each project's `graph.json` and recommends prefixes to add to `[settings].external_stubs` (cross-project) or `[[project]].external_stubs` (single-project). Run after `graphify run`:\n\n```bash\n# Print suggestions as Markdown (default)\ngraphify suggest stubs --config graphify.toml\n\n# JSON for tooling\ngraphify suggest stubs --format json\n\n# Apply directly to graphify.toml (preserves comments via toml_edit)\ngraphify suggest stubs --apply\n\n# Higher signal — only suggest prefixes with ≥10 edges in any project\ngraphify suggest stubs --min-edges 10\n```\n\nAuto-classification: a prefix that survives the `--min-edges` filter in **2 or more** projects is suggested for `[settings].external_stubs`; a single-project survivor lands in that project's `[[project]] external_stubs`. Prefixes already covered by current stubs (or that collide with a project's `local_prefix`) are skipped and listed separately for visibility.\n\n## Hotspot Classification (v0.7+)\n\nEvery top-20 hotspot in `architecture_report.md`, `analysis.json`, and `pr-summary` is tagged with a classification that dictates which refactor fits best:\n\n| Type | Signal | Recommended fix |\n|------|--------|-----------------|\n| **hub** | `in_degree \u003e hub_threshold` (default: 50) | Split the module into submodules, or invert the dependency on its largest consumers. |\n| **bridge** | `betweenness / max(in_degree, 1) \u003e bridge_ratio` (default: 3000) | Inject the cross-layer dependency instead of calling through. Reduces chokepoints. |\n| **mixed** | Both thresholds fire, or neither | Human judgment: inspect the call graph before choosing. |\n\nTune per-repo via CLI or config:\n\n```bash\ngraphify run --config graphify.toml --hub-threshold 80 --bridge-ratio 5000\ngraphify check --config graphify.toml --hub-threshold 20 --bridge-ratio 1500\n```\n\n```toml\n[hotspots]\nhub_threshold = 80\nbridge_ratio = 5000\n```\n\nWhy classify at all? Two nodes can share a composite score of 0.6 for completely different reasons — a 200-module hub needs a different refactor than an 80-line chokepoint that bridges four layers. See FEAT-017 for the motivating evidence.\n\n## MCP Server\n\nGraphify includes an MCP server (`graphify-mcp`) that exposes graph queries to AI assistants like Claude:\n\n```bash\ncargo install --path crates/graphify-mcp\n```\n\nAdd to your Claude Code MCP config:\n\n```json\n{\n  \"mcpServers\": {\n    \"graphify\": {\n      \"command\": \"graphify-mcp\",\n      \"args\": [\"--config\", \"graphify.toml\"]\n    }\n  }\n}\n```\n\nExposes 9 tools: `graphify_stats`, `graphify_search`, `graphify_explain`, `graphify_dependents`, `graphify_dependencies`, `graphify_shortest_path`, `graphify_all_paths`, `graphify_suggest`, `graphify_hotspots`.\n\n## Confidence Scoring\n\nEvery edge carries a confidence score (0.0–1.0) indicating extraction certainty:\n\n| Source | Confidence | Kind |\n|--------|-----------|------|\n| Direct import | 1.0 | Extracted |\n| Python relative import | 0.9 | Extracted |\n| TS relative import | 0.9 | Extracted |\n| TS path alias | 0.85 | Extracted |\n| Bare function call | 0.7 | Inferred |\n| Non-local target | ≤0.5 | Ambiguous |\n\nUse `--json` with `query` or `explain` to see confidence data. The MCP server supports `min_confidence` filtering.\n\n## Consolidation Candidates\n\nWhen the same symbol name lives in multiple places (e.g. a `TokenUsage` class duplicated across services), `graphify consolidation` emits a structured list of candidates for a consolidation refactor:\n\n```bash\ngraphify run --config graphify.toml          # first, generate analysis.json + graph.json\ngraphify consolidation --config graphify.toml\n# → ./report/\u003cproject\u003e/consolidation-candidates.json per project\n# → ./report/consolidation-candidates.json (aggregate) when 2+ projects\n```\n\nSymbols declared under `[consolidation].allowlist` in `graphify.toml` (regex patterns anchored against the *leaf* symbol name) are filtered out by default. Use `--ignore-allowlist` to inspect the unfiltered grouping while debugging. `--min-group-size \u003cN\u003e` tightens the threshold (default `2`). `--format md` produces a tabular Markdown report instead of JSON.\n\n### Migrating from pre-FEAT-020 exclusion lists\n\nBefore the `[consolidation]` section existed, teams tracked \"known-duplicate\" symbols in whatever place was at hand: the `graphify-consolidation-scan.sh` shell script bundled with the `code-consolidation` skill, `grep -v` filters in CI workflows, or ad-hoc `.consolidation-ignore`-style convention files kept next to the config. None of these are understood by `graphify consolidation`, `graphify check`, or `graphify diff` — move them into `graphify.toml` so every subcommand sees the same truth.\n\nTwo canonical destinations:\n\n- `[consolidation].allowlist` — regex patterns anchored (`^…$`) against the *leaf* symbol name. Use it for shapes duplicated by design across many sites, like `TokenUsage`, `LessonType`, or any `*Response`/`*Dto` family. Invalid patterns are rejected at config load (fail-fast).\n- `[consolidation.intentional_mirrors]` — explicit `LeafName = [\"project:node.id\", …]` map, for shared-contract DTOs that legitimately co-exist at *specific* endpoints across projects. Drift reports suppress cross-project hotspot noise for these exact node pairs (see `graphify diff` output and the `pr-summary` annotations).\n\n**Before** — grep-exclude buried in a scan script or CI step:\n\n```bash\n# graphify-consolidation-scan.sh (legacy)\ngrep -E \"class (TokenUsage|LessonType)\" -r src/ \\\n  | grep -v -E \"(TokenUsage|LessonType)Adapter\"\n```\n\n**After** — same intent, expressed once in `graphify.toml`:\n\n```toml\n[consolidation]\nallowlist = [\n  \"TokenUsage\",\n  \"LessonType\",\n]\n```\n\nThe regex is matched against the leaf name only, so `TokenUsage` hits `app.models.TokenUsage` but not `app.models.TokenUsageAdapter` — the legacy `grep -v` for `*Adapter` becomes redundant.\n\n**Before** — hand-written ignore list for a shared DTO mirrored across services:\n\n```text\n# .consolidation-ignore (ad-hoc, not understood by graphify)\nTokenUsage  # mirrored in ana-service and pkg-types by design\n```\n\n**After** — pinned to the exact endpoints in `graphify.toml`:\n\n```toml\n[consolidation.intentional_mirrors]\nTokenUsage = [\"ana-service:app.models.tokens\", \"pkg-types:src.tokens\"]\n```\n\nOnce migrated, `graphify consolidation`, `graphify check`, and the `graphify diff` / `pr-summary` pipeline all honour the same list — delete the shell script, drop the CI `grep -v`, and remove any local ignore files. Use `--ignore-allowlist` on `run` / `report` / `check` when you want to double-check that the allowlist isn't masking a real regression.\n\nThis subcommand supersedes the `graphify-consolidation-scan.sh` shipped in the `code-consolidation` skill — the native command is faster, typed, and honors the same `[consolidation]` config used by `graphify check` and the PR summary.\n\n## Common Monorepo Recipes\n\n### 1. Refresh the full graph before research\n\n```bash\ngraphify run --config graphify.toml\n```\n\nUse this after config changes, before architecture review, or after a large refactor.\n\n### 2. Find a namespace, route group, or bounded context\n\n```bash\ngraphify query 'src.app.*study-chat*' --config graphify.toml --project web\ngraphify query 'app.api.*' --config graphify.toml --project api --json\n```\n\nStart with `query` when you know roughly what area you want but not the exact node ID.\n\n### 3. Investigate a hotspot before refactoring it\n\n```bash\ngraphify explain 'src.shared.domain.errors' --config graphify.toml --project pkg-api\ngraphify explain 'src.shared.domain.errors' --config graphify.toml --project pkg-api --json\n```\n\nUse `explain` before touching a high fan-in module to assess blast radius.\n\n### 4. Trace why one module depends on another\n\n```bash\ngraphify path 'src.hooks' 'src.trpc.react' --config graphify.toml --project web\ngraphify path 'src.hooks' 'src.trpc.react' --config graphify.toml --project web --all --max-depth 6\n```\n\nUse the default shortest path first. Rerun with `--all` to inspect alternate routes.\n\n### 5. Compare drift before and after a refactor\n\n```bash\ncp report/web/analysis.json /tmp/web-before.json\ngraphify run --config graphify.toml\ngraphify diff --baseline /tmp/web-before.json --config graphify.toml --project web\n```\n\n### 6. Watch mode during development\n\n```bash\ngraphify watch --config graphify.toml\n```\n\nMonitors source files and auto-rebuilds only affected projects on changes (300ms debounce). Useful during active refactoring.\n\n### 7. CI quality gate\n\n```yaml\n# .github/workflows/arch.yml\n- run: graphify check --config graphify.toml --max-cycles 0 --max-hotspot-score 0.8\n```\n\nFails the build if architectural constraints are violated.\n\n## AI Integrations\n\nGraphify ships ready-to-install integrations for Claude Code and Codex: 5 slash commands, 3 skills, 2 agents, and the MCP server, all registered in one command.\n\n### Solo install\n\n```bash\ngraphify install-integrations\n```\n\nRun this after `graphify init` if you want Graphify's slash commands, skills, agents, and MCP registration. `init` only creates `graphify.toml`.\n\nAuto-detects `~/.claude/` and `~/.agents/skills/`. Then restart the client and run `/gf-setup` from inside it to verify and finish onboarding.\n\n### Team install (shared repo)\n\nCommit the `.claude/` directory so every teammate gets the skills on `git clone`:\n\n```bash\n# Maintainer, once\ngraphify install-integrations --project-local\ngit add .claude/ .mcp.json\ngit commit -m \"chore: install graphify AI integrations\"\n\n# Teammates — inside Claude Code after pulling\n/gf-setup\n```\n\nThe `/gf-setup` slash command is the single entry point for install, upgrade, and diagnostics. It drives the AI through 6 checks: binary on PATH, `graphify.toml` present, artifacts installed, MCP registered, reload notice, and a compact status report.\n\nFull team flow (patterns, CI, troubleshooting): [`docs/01-Getting-Started/AI Integrations.md`](docs/01-Getting-Started/AI%20Integrations.md).\n\n### Flags\n\n| Flag | Purpose |\n|---|---|\n| `--claude-code` / `--codex` | Target one client explicitly |\n| `--project-local` | Install Claude Code artifacts to `./.claude/` (Codex ignores this flag) |\n| `--skip-mcp` | Don't touch the client's MCP config |\n| `--dry-run` | Preview changes |\n| `--force` | Overwrite edited files |\n| `--uninstall` | Reverse manifest-tracked changes |\n\n### What gets installed\n\n| Kind | Name | Purpose |\n|---|---|---|\n| Agent | `graphify-analyst` | Polyvalent analyst (MCP-preferred) |\n| Agent | `graphify-ci-guardian` | Deterministic CI gate (CLI-only) |\n| Skill | `graphify-onboarding` | Architecture tour |\n| Skill | `graphify-refactor-plan` | Phased refactor plan |\n| Skill | `graphify-drift-check` | CI drift gate |\n| Command | `/gf-setup` | Self-configure + diagnose + upgrade |\n| Command | `/gf-analyze` | Full-pipeline summary |\n| Command | `/gf-onboard` | Invoke onboarding skill |\n| Command | `/gf-refactor-plan` | Invoke refactor plan skill |\n| Command | `/gf-drift-check` | Invoke drift check skill |\n\n\u003e [!note]\n\u003e Slash commands and skills hot-reload, but the **MCP server loads only at client boot** — restart Claude Code / Codex after running `install-integrations` for the first time.\n\n### CI usage (drift gate)\n\n```yaml\n- run: graphify install-integrations --claude-code --skip-mcp\n- run: graphify run --config graphify.toml\n- run: graphify check --config graphify.toml --json\n- run: graphify diff --before report/baseline/analysis.json --after report/\u003cproject\u003e/analysis.json\n- run: graphify pr-summary report/\u003cproject\u003e \u003e\u003e $GITHUB_STEP_SUMMARY\n```\n\nFor interactive flows, invoke `/gf-onboard` or `/gf-refactor-plan` in Claude Code / Codex.\n\n## Supported Languages\n\n- Python\n- TypeScript / JavaScript\n\n## Architecture\n\nCargo workspace with 5 crates:\n\n| Crate | Role |\n|---|---|\n| `graphify-core` | Graph model, metrics, community detection, cycles, query engine, diff |\n| `graphify-extract` | tree-sitter AST parsing, file discovery, module resolution, caching |\n| `graphify-report` | JSON, CSV, Markdown, HTML, Neo4j, GraphML, Obsidian output |\n| `graphify-cli` | CLI, config parsing, pipeline orchestration, watch mode |\n| `graphify-mcp` | MCP server for AI assistant integration |\n\n---\n\n## AI Assistant Instructions (copy to your CLAUDE.md)\n\nCopy the block below into your project's `CLAUDE.md` to make Claude Code use Graphify as the primary source for codebase research.\n\n````markdown\n## Architectural Research with Graphify\n\nThis project uses [Graphify](https://github.com/parisgroup-ai/graphify) for architectural analysis. **Use Graphify as the primary source for understanding the codebase structure before reading individual files.**\n\n### Setup (run once)\n\nIf `graphify.toml` does not exist yet:\n\n```bash\ngraphify init\n# `init` only creates graphify.toml\ngraphify install-integrations --project-local\n# Then edit graphify.toml with the correct project settings\ngraphify run --config graphify.toml\n```\n\n### Workflow: graph-first, code-second\n\nWhen you need to understand the architecture or the impact of a change, **always query the graph before reading source files**:\n\n1. **Find modules** — `graphify query \"app.services.*\" --config graphify.toml`\n2. **Understand a module** — `graphify explain app.services.llm --config graphify.toml --json`\n3. **Trace dependencies** — `graphify path app.main app.services.llm --config graphify.toml`\n4. **Check drift after changes** — `graphify diff --baseline report/analysis.json --config graphify.toml`\n\n### When to use each command\n\n| Situation | Command |\n|-----------|---------|\n| \"What modules exist in this area?\" | `graphify query \"pattern.*\" --config graphify.toml` |\n| \"What depends on this module? What will break if I change it?\" | `graphify explain \u003cmodule\u003e --config graphify.toml --json` |\n| \"How does module A reach module B?\" | `graphify path \u003cA\u003e \u003cB\u003e --config graphify.toml` |\n| \"What are the architectural hotspots / God modules?\" | Read `report/\u003cproject\u003e/architecture_report.md` or `analysis.json` |\n| \"Are there circular dependencies?\" | Read `analysis.json` → `cycles` array |\n| \"Did my changes introduce drift?\" | `graphify diff --baseline report/analysis.json --config graphify.toml` |\n| \"Does this pass CI quality gates?\" | `graphify check --config graphify.toml --max-cycles 0` |\n\n### Rules\n\n- Before modifying a module with high fan-in (in_degree \u003e 20), run `graphify explain \u003cmodule\u003e` to understand the blast radius.\n- After significant refactoring, run `graphify run --config graphify.toml` to regenerate the analysis and check for new cycles or hotspot changes.\n- Use `--json` flag when you need structured data for programmatic reasoning.\n- Module IDs use dot notation matching the file path: `app/services/llm/base.py` → `app.services.llm.base`.\n- The `analysis.json` file contains pre-computed metrics (betweenness, PageRank, community clusters, cycles) — read it directly for aggregate questions instead of re-running the pipeline.\n````\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparisgroup-ai%2Fgraphify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparisgroup-ai%2Fgraphify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparisgroup-ai%2Fgraphify/lists"}