* feat: detect circular import dependencies at file level
- Add find_import_cycles() to analyze.py
- Collapses symbol nodes to parent files, builds directed file graph
- Uses nx.simple_cycles() bounded by max_cycle_length (default 5)
- Deduplicates rotations, returns shortest cycles first
- Considers both imports_from and re_exports edges
Tested on a 976-file Next.js codebase: found 4 cycles including
a known utils↔barrel circular dependency and a 4-file API cycle.
* fix: resolve import-cycle merge blockers
- use source_file-only endpoint resolution (no label fallback)
- support Graph/DiGraph orientation via edge source_file
- return structured cycle records and include self-loops
- integrate Import Cycles section into GRAPH_REPORT.md
- expand cycle tests for real-schema IDs, undirected input,
missing source_file nodes, and non-import relations
* fix(analyze): exclude npm dep-block keys from god-node selection
Extends _JSON_NOISE_LABELS in graphify/analyze.py with the six npm
package.json dependency-block keys (dependencies, devDependencies,
peerDependencies, optionalDependencies, bundledDependencies,
bundleDependencies — lowercased to match the existing .strip().lower()
comparison in _is_json_key_node).
On JS/TS corpora with non-trivial dependency counts, the dep-block key
node accumulates contains+imports edges to every package entry and was
surfacing as the top god-node in the report. The fix is a one-line
extension of the existing frozenset; no new helpers or code paths.
Includes a parametrized regression test in tests/test_analyze.py
covering all five npm keys: dependencies, devDependencies,
peerDependencies, optionalDependencies, bundledDependencies.
Validated live against rsl-siege-manager @ 6085fd66 — zero npm dep-block
keys in the top-10 god-nodes after the fix. Pre-existing failures
(Windows symlink + SQL tree-sitter): 17, unchanged.
Closes#2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* style: drop fork-local issue refs from analyze comments
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
In Python+TypeScript monorepos, the call and import resolvers match by
label across language boundaries (AuthError -> Member), producing false
positives that dominate 'Surprising Connections' due to cross-dir (+2)
and cross-community (+1) bonuses.
Expand the existing calls guard to also cover uses edges, and zero the
cross-dir and cross-community bonuses for these pairs — not just conf_bonus.
Leaves semantically_similar_to, EXTRACTED, and AMBIGUOUS edges unaffected.
5 new tests: calls suppressed, uses suppressed, semantically_similar_to
preserved, same-language INFERRED preserved, cross-language EXTRACTED preserved.