Changelog
[1.1.1] — 2026-05-24
Added
- Search by module or function/class name — results show the containing
module as a faint suffix; selecting a callable jumps to its module and flashes
the callable in the detail panel
- Same-module link label in the Callables section — palegoldenrod links scroll
within the open modal instead of navigating; now labelled
- Dead callable highlighting — dead callable names and left border use the
accent colour; live callables remain neutral
Changed
- Visual redesign: colour palette aligned with the project design language —
black canvas, whitesmoke text, salmon accent for dead code, palegoldenrod for
selection and same-module links, Wiphala-derived blue→green→red
commit-frequency gradient at lower lightness for readability
- Fit-to-screen now offsets the graph centre by half the legend width so the
graph clears the legend panel
- No external font requests — the output HTML is fully self-contained; system
monospace font used instead of a Google Fonts CDN call
[1.1.0] — 2026-05-24
Added
- Callable graph layer — function/method/class-level dependency tracking
alongside the existing module graph, joined by canonical prefix (
mod::Name
belongs to module mod) ast.Attribute chain walker — resolves qualified calls
(np.linalg.norm()-style) by trying every split point against project
definitions- Extended alias mapper — every import shape (
import x, import a.b,
import a as b, from . import x, etc.) now contributes a
local_name → canonical entry; local definitions are added too so same-module
calls resolve - Inheritance edges from
ClassDef.bases — class B(A) produces an edge
B → A - Decorator edges from
decorator_list — handles bare @dec and parameterized
@dec(arg) the same way - Synthetic
mod::<module> source for module-scope calls — entry points like
cli() in __main__.py are no longer falsely dead - Scoped naive name-matching fallback for
obj.method() when obj has no type
info - Call-aware dead-callable detection — a callable is dead when callable-graph
fan-in is zero AND its canonical doesn’t appear in the project import set
- Per-module “Callables” section in the modal — every function/method/class with
its fan-in, fan-out, calls, called-by, and dead flag
- Function references passed as
Call arguments / keyword arguments tracked as
edges — covers callbacks handed to executors, sorted(key=...), map,
decorators-by-name - Dashed red ring around any module circle that contains at least one dead
callable
Changed
- Single-pass file parsing — each module is now read and AST-parsed once instead
of three times; ~30% wall-clock speedup on a 1 354-file project (3.48s →
2.44s)
parse_calls is now caller-scoped — returns
call_edges: dict[source, set[target]] instead of a flat call setsymbols_to_review_detector replaced by project-wide
dead_callables_detector- Module payload field
symbols_to_review replaced by with_symbols_to_review
(boolean)
Fixed
discover() no longer emits duplicate Package entries for directories with
many .py files- Property getter / setter / deleter no longer collapse into one canonical —
each role gets a distinct canonical (
mod::Class.bar@get, @set, @del)
Known limitations
obj.method() resolution falls back to naive name matching when obj is a
local variable without type information — precise resolution via type
annotations is slated for v1.2- Reference tracking covers callable-as-argument; other reference contexts
(assignment, list literals, returns) are still missed — full reference
tracking is a v1.2 item
[1.0.3] — 2026-04-05
Added
- Hierarchical circle packing layout — packages contain sub-packages with no
node overlap
- Color encoding — node fill by commit frequency (blue→red), package border
brightness by nesting depth
- Test filter toggle — hide/show all nodes, edges, and packages with “test” in
the name
- Click node to select and open detail modal; click package circle to zoom into
it
- Fuzzy search bar — type a module name, jump to and highlight it (
/ to focus) - Keyboard shortcuts:
F zoom to fit, / focus search, Esc deselect/close
Changed
- Middle-click to pan canvas
- Escape closes modal and deselects node in one press
- Minimum arrow length to avoid invisible edges between close nodes
Fixed
- Panning and zoom now rAF-throttled — smooth at any display refresh rate
- Package draw order precomputed once instead of sorted on every frame
[1.0.2] — 2026-03-26
Fixed
- git stats now run from the correct project root (
cwd=root) module.full_path used for file reading so CLI works from any directory
[1.0.1] — 2026-03-26
Fixed
- HTML and JS template files now included in the wheel
- git stats no longer crash on repos with no commits (graceful fallback)
- CLI entry point now correctly reads
sys.argv via cli() function
[1.0.0] — 2026-03-25
Added
- Initial release
- Dependency graph visualization
- Dead code detection, cycle detection, hotspot analysis
- Git integration (commit frequency, churn, last author)
- Unused symbol detection
- CLI and Python API
- GIL-aware parallel processing