Skip to main content

Seamcheck

Your AI wrote 400 lines. Which of them are actually wired to anything?

Seamcheck reads a Django + JavaScript project and tells you what connects to what — which fetch() lands on which view, which template element the JS is reaching for, which CSS rule nothing has referenced since 2023. Then it tells you what it couldn't work out, which turns out to be the part that matters.

No SaaS. No upload. One command, one HTML file, and an exit code for CI.

The four answers

Every dead-code tool ever written has told you something was unused and been wrong, and you stopped trusting it. Seamcheck has a fourth answer:

connected something reaches this — here's the file and line
unresolved something reaches for this and it isn't there
unused both ends are observable and nothing uses it
uncertain no evidence either way. Not a claim it's dead.

That last row is the whole product. A page reached by an <a href> looks exactly like a dead one if you only parse fetch() calls. Seamcheck says so instead of guessing. On a 700-URL project that's the difference between a report you act on and 668 lies.

It also reports its own coverage — how much of each file it actually reasoned about. No other tool I've found will tell you where it wasn't looking.

What it found in the project it was built on

Not hypotheticals. Real bugs, in a real 36,000-symbol codebase, found while writing this:

  • Five CSS custom properties in a loaded stylesheet that resolve to nothing — --text-primary, --border-color and friends. Those declarations render nothing today.
  • An endpoint reported missing that turned out to be <str:division_id> matching a deliberate 'all' sentinel — so I fixed the matcher instead of "fixing" the code.
  • 65 API routes whose path appears in no source file at all.
  • 46 DOM elements written by more than one module — the reason a display bug survives being "fixed" in one of them.

Install

pip install seamcheck

Then two things in settings.py:

INSTALLED_APPS = [..., "seamcheck"]

SEAMCHECK_CONFIG = {
    "urlconf_module": "myproject.urls",
    "templates_root": "myapp/templates",
    "js_source_root": "myapp/static/js",
    "css_source_root": "myapp/static/css",
    "first_party_prefixes": ["myapp", "myproject"],
}

Every project-specific path lives in that dict. Nothing is hardcoded anywhere in the extractors — which is how this was lifted out of the project it grew in without touching a line of it.

You need Node on PATH. The JS and CSS parsers run on it. You do not need npm or node_modules — acorn and postcss ship inlined in the wheel. If Node is missing, Seamcheck says so and gives you the Python half rather than dying.

Use

python manage.py seamcheck                 # scan, summary, write the map
python manage.py seamcheck --check         # exit 1 on new findings. This is the CI one.
python manage.py seamcheck --format map    # the UI, one self-contained HTML file
python manage.py seamcheck --explain <id>  # one symbol, with the code around it

The UI

One file, no network, opens on a phone. A left rail of views; a canvas that draws every symbol a page touches at once — 1,366 of them on the biggest page here — with the broken ones filled in red so they find you rather than the other way round.

Click any node and it lights the line through it: page → module → fetch() → URL → view, each hop with the real source, and a button to show the whole enclosing function. Or isolate that one chain and drop everything else.

There's a Files view too — your actual folder tree, with a bar per file showing how many of its declarations Seamcheck reasoned about. Because "no findings" and "never looked" are not the same sentence.

python manage.py seamcheck --format map --serve            # open it from your phone
python manage.py seamcheck --format map --serve --tunnel   # ...from anywhere

Nothing is uploaded. --serve is a socket on your machine that dies with the command.

Per-commit

python manage.py seamcheck --backfill 20     # scan the last 20 commits

Now the map has a commit picker. Pick one and see what that commit changed — added, removed, status flipped — including things it deleted, which no longer exist to be drawn and get named instead.

CI

python manage.py seamcheck --check --since $BASE_SHA

1 = new findings. 2 = no baseline, so the gate didn't run. 0 = clean. That distinction matters: a gate that never ran is not a gate that passed.

Agents

seamcheck_check, seamcheck_report, seamcheck_explain, seamcheck_triage over MCP, and an AGENTS.md that tells your agent the one rule that matters: never delete something because it's uncertain.

What it can't do

Written down because a tool that hides its blind spots is worse than no tool:

  • Django + vanilla JS. No React, Vue, or TypeScript yet.
  • Celery, Redis, WebSockets and Stripe aren't traced. Anything reached only through those is invisible, and the UI says so rather than showing a confident zero.
  • A URL built at runtime stays uncertain. The prefix is recorded, never a guess.
  • It has been run against one real project. Mine. That's one more than most tools at this stage and far fewer than you'd want.

Contributing

Issues and PRs welcome. One house rule, and it's the reason the tool is worth anything: never make a claim the scan can't evidence. If you can't prove it, it's uncertain, and the note says which evidence source was missing.

License

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

seamcheck-0.1.0.tar.gz (219.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

seamcheck-0.1.0-py3-none-any.whl (192.9 kB view details)

Uploaded Python 3

File details

Details for the file seamcheck-0.1.0.tar.gz.

File metadata

  • Download URL: seamcheck-0.1.0.tar.gz
  • Upload date:
  • Size: 219.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for seamcheck-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6b2fff2e3206aad086afaf6480994962b80913495bd88a5a038a326bcaa0e6c6
MD5 3878f49ec7e42a1376cb0d24e24a6775
BLAKE2b-256 52be16d91f34f2a7bb6c71235753661fa2b83aef4470b813136ecc39d3d82605

See more details on using hashes here.

Provenance

The following attestation bundles were made for seamcheck-0.1.0.tar.gz:

Publisher: release.yml on dardameiz/seamcheck

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seamcheck-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: seamcheck-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 192.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for seamcheck-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b6344cb3c2625cf92b909438494d35ee4543a6f02a7e6a3892dde5448d337b89
MD5 bce6057659188d180197bbfa0089c713
BLAKE2b-256 8d6aa41e95d3bb02ce999927977865a6d4e43a7ed53ed458d54743bf2d31fe7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for seamcheck-0.1.0-py3-none-any.whl:

Publisher: release.yml on dardameiz/seamcheck

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.6.0

2 files

0.5.0

2 files

0.3.0

2 files

This release

0.1.0 This release

2 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