Skip to content

Feature: expose connected components and cycles — networkx is already bundled #2489

Description

@luliaz0601

Version: graphify 0.9.33 (pipx, Python 3.14.5, Windows)

The gap

graphify already builds a directed graph and already ships networkx 3.6.1, but never
calls its connectivity primitives. Searching the installed package (80 .py files):

symbol files containing it
connected_component 0
strongly_connected 0
in_degree / out_degree 0
dijkstra 0
leiden / louvain 7 / 6
betweenness 2

So community detection and centrality are covered, but connectivity is not — even though
nx.weakly_connected_components and nx.strongly_connected_components would run on the
graph already in memory, with no new dependency and no LLM.

Two questions this would answer

1. Weakly connected components → orphaned code.
Nodes that no path reaches from the rest of the project. Running this externally on a
graphify graph of a Next.js repo (229 nodes) surfaced a component of 3 containing a React
component that nothing imports, and an isolated script — neither visible from god-nodes
or from community labels, because both metrics describe nodes that are connected.

2. Strongly connected components → circular dependencies.
A cycle means no member can be read, tested or replaced on its own. On a markdown-heavy
repo the same external run found a 9-file cycle spanning docs and automation:

STATUS.md -> fila.yml -> fila.py -> POST_02.md -> PAUTA_01.md -> CONTA.md -> STATUS.md

Five of the six edges were EXTRACTED. This is the kind of finding an onboarding agent
benefits from, and GRAPH_REPORT.md is the natural place for it.

Suggested shape

graphify components         # weakly connected; flags the ones with no source files
graphify cycles             # strongly connected components of size > 1

and a short section in GRAPH_REPORT.md:

Components: 7 (largest 150 nodes, 66%)
Circular dependencies: 0

One caveat worth designing around

Config files distort the count. In the Next.js repo above, 4 of the 7 components were
package.json, tsconfig.json, eslint.config.mjs and postcss.config.mjs — each parses
into its own tree with no edge to source code, so they read as "orphans" while being
nothing of the sort. A component containing no file_type: code node could be labelled as
config rather than counted as orphaned code.

Context

This came out of building a small external layer that post-processes graph.json for
exactly these questions, and then checking whether graphify already answered them. It does
not, but it is one import away from doing so — the extraction quality is already there, and
these would be a thin analysis pass on top rather than new machinery.

Happy to send a PR if the direction is welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions