Skip to main content

chrome-navtree

Turn a Chrome profile's browsing history into a cleaned navigation forest: the tree of pages you actually visited, with single-page-app churn collapsed, auth redirects spliced out, and junk destinations pruned.

Chrome's on-disk history already records how you got from page to page (referrer and tab-opener edges, plus a transition type per visit). This reconstructs that into a forest of trees, then cleans it so what is left is the shape of your actual journeys instead of every redirect and tab refresh.

This package is the engine. What you build on top of it (a viewer, an archiver, a note-taking integration) is yours to write. A self-contained HTML viewer ships in the box so you can see the result immediately.

Install

Run it with no install at all (needs uv):

uvx --from git+https://github.com/technicalpickles/chrome-navtree chrome-navtree profiles

Or install it as a CLI and library:

pip install chrome-navtree      # or: uv add chrome-navtree
uv tool install chrome-navtree  # isolated, on your PATH

Python 3.11+ (uses stdlib tomllib). No runtime dependencies.

Quick start

# List the Chrome profiles on this machine
chrome-navtree profiles

# Open an HTML viewer of the last 7 days for your "work" profile
chrome-navtree preview --profile work --since 7d --open

# Emit the cleaned tree as JSON for something else to consume
chrome-navtree dump --profile work --since 24h > forest.json

--since takes 7d, 24h, or an ISO date like 2026-07-01. --profile takes a profile key (from chrome-navtree profiles) or a raw directory name like Default.

The live Chrome database is never touched. It gets copied to a temp file and opened read-only, so it is safe to run while Chrome is open.

Library

Every consumer goes through the same three steps, so the viewer and the JSON output can never drift:

from datetime import timedelta
from chrome_navtree import discover_profiles, load_visits, build_forest, clean, Rules

prof   = discover_profiles()["work"]
visits = load_visits(prof.history_path, since=timedelta(days=7))
raw    = build_forest(visits)                      # faithful, unfiltered
forest = clean(raw, Rules.load("rules.toml"))      # collapsed / spliced / pruned

forest.to_dict()   # JSON-serializable: {"roots": [...], "stats": {...}}

clean is a pure function: it returns a new forest and never mutates its input.

What cleaning does

Three passes, in order:

  • collapse folds churn to one node. A single-page app that keeps rewriting its URL, or a GitHub PR you clicked through 40 tabs of, becomes one node with a visit_count. Folding is driven by rules (drop query and fragment, plus per-host path folds).
  • splice removes auth interstitials and reconnects their children to the parent, so a real page -> SSO -> real page chain stays one unbroken path instead of three.
  • prune drops junk destinations along with their whole subtree.

Rules

The engine carries no knowledge of your specific tools or workplace. What counts as junk, what counts as auth plumbing, and how paths fold all live in TOML.

The package ships default_rules.toml with generic defaults: query/fragment dropping, GitHub PR/issue folding, and common SSO providers (Google, Microsoft, Okta, WorkOS). Your own rules.toml layers on top, where list values append to the defaults so you only list your own additions:

[prune]
junk_hosts = ["calendar.example.com", "internal-dashboard.example.com"]

[splice]
auth_hosts = ["sso.mycorp.example"]

[[collapse.fold]]
host = "tickets.example.com"
pattern = "^(/browse/[A-Z]+-[0-9]+)"

See examples/rules.example.toml for a fuller template. Pass it with --rules rules.toml or Rules.load("rules.toml").

Data model

  • Visit is one row from Chrome's visits table, joined to its URL, with the timestamp and transition decoded.
  • NavNode is a node in the tree: url, title, host, transition, dwell_s, visit_count, key, children.
  • NavForest is roots plus summary stats (raw vs cleaned node counts, distinct hosts, spliced and pruned tallies).

Notes and limits

  • Chrome expires history after about 90 days, so that is the practical window. Archiving beyond it is a job for a consumer built on this engine, not the engine itself.
  • Auth detection is deliberately aggressive: anything titled "sign in" or "log in", plus common auth URL shapes and identity-provider hosts, gets spliced. For a work browsing corpus that is the right trade. If a real page ever vanishes, narrow the splice rules.

Development

uv sync --extra dev     # ruff, mypy, pytest
uv run --extra dev pytest
mise run check          # ruff + ruff format + mypy + pytest (what CI runs)

Tooling is pinned with mise and git hooks run through hk. After cloning, mise install then hk install gives you ruff + mypy on every commit. If you would rather not use mise, the checks are plain uv run --extra dev ... commands.

Test data, isolated from your real Chrome

The live Chrome database is never touched (it is copied to a temp file and opened read-only), and none of the dev tooling reads or writes a real Chrome profile. Tests build synthetic Chrome databases in a temp dir and assert an exact cleaned forest, so they are deterministic and need no real browser data.

To poke at the CLI by hand, scaffold a fake Chrome profile (--chrome-root goes after the subcommand):

python scripts/fake_chrome.py /tmp/fake-chrome
chrome-navtree profiles --chrome-root /tmp/fake-chrome
chrome-navtree dump --chrome-root /tmp/fake-chrome --profile work

For realistic data, scripts/seed_realistic.py drives a throwaway Chromium profile (its own --user-data-dir, never your real one) with Playwright and snapshots the history into tests/fixtures/realistic/:

uv sync --extra playwright
uv run playwright install chromium
uv run python scripts/seed_realistic.py --scripted   # or --manual to click around yourself

Playwright is an opt-in extra and never runs in CI.

License

MIT. See LICENSE.

Release files for chrome-navtree 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chrome-navtree 0.2.0
File Size Uploaded
chrome_navtree-0.2.0.tar.gz 75.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for chrome-navtree 0.2.0
File Interpreter ABI Platform
chrome_navtree-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 101.8 kB

Release files / chrome_navtree-0.2.0.tar.gz

Download URL chrome_navtree-0.2.0.tar.gz
Size 75.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6a953ab94576397aa09e2c8981bc8d01dd3c8337781ecf73f04036efac59bfcd
BLAKE2b-256 checksum
How to use checksums
cd5779f2bb3bb2d47ed0b4aa180a9151c426d66e5dc05b6073f0e66112667032
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.

Transparency log

Release files / chrome_navtree-0.2.0-py3-none-any.whl

Download URL chrome_navtree-0.2.0-py3-none-any.whl
Size 26.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e8e8ff2f3ded47b0a3fc6a3fe01268e9e36c4df98d48ae20187948b97607d1f
BLAKE2b-256 checksum
How to use checksums
63de82e163e02f679846c4b1cc23c79df2374e4df857e044cbe97678e5910e66
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page