| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Snag the differences. Kill "works on my machine".
Snagify helps debug "works on my machine" problems by detecting environment drift between developers, CI, and local setups. Use Snagify when a project works on one machine but fails on another.
Snagify is a single-binary CLI that surfaces likely setup blockers when a project works on one machine but fails on another.
It checks the boring things that usually waste hours:
No AI. No daemon. No cloud. No secret values read.
go install github.com/harshdevelops/snagify@latestOr build from source:
git clone https://github.com/harshdevelops/snagify.git
cd snagify
go build -o snagify .Other install methods (all ship the same static binary):
# Prebuilt release tarball.
curl -fsSL -O https://github.com/HarshDevelops/snagify/releases/latest/download/snagify_Linux_x86_64.tar.gz
tar -xzf snagify_Linux_x86_64.tar.gz && sudo mv snagify /usr/local/bin/
# Docker (multi-arch distroless image; binary on PATH inside the container).
docker run --rm -v "$PWD:/workspace" -w /workspace ghcr.io/HarshDevelops/snagify check
# npm — wraps the GitHub Release tarball; verifies SHA-256 at install time.
npm install -g snagify
# PyPI — same wrapper, Python-flavoured.
pip install snagify
# Homebrew — formula lives in packaging/homebrew/snagify.rb.
brew install HarshDevelops/tap/snagifyRun Snagify in CI via the GitHub Action (.github/actions/snagify-check):
- uses: HarshDevelops/snagify/.github/actions/snagify-check@v0.5.0
with:
args: --no-tls --timeout 10sInside a repo:
snagify init # generate a starter .snagify.yaml from your project
snagify check # check this machine against itExample:
Project: checkout-service
Your setup is not ready
Critical blockers
─────────────────
Java found: 21.0.2 expected: 17
Maven found: missing expected: >=3.8
.env missing: JWT_SECRET
Port 8080 occupied expected: free
Likely blockers:
• Maven is missing
• Java version does not match the project requirement
• JWT_SECRET is absent from .env
• Port 8080 is already occupied
Exit code is 0 when the setup is ready, 1 when there are likely blockers, and 2 on a config or runtime error — so it drops straight into CI or a pre-flight script.
| Class | Examples |
|---|---|
| Runtime drift | Node, Java, Python, Go, Rust, Maven, Gradle, Docker |
| Git drift | wrong branch, dirty tree, untracked files, commit mismatch |
| Env drift | missing keys from .env based on .env.example |
| Docker drift | Docker missing, Compose files missing, required images/containers |
| Port/service drift | ports that must be free/listening, TCP service reachability |
| Network drift | DNS, HTTP status checks, proxy presence |
| TLS drift | handshake failure, hostname mismatch, expired/expiring certs |
| System drift | OS/arch, timezone, locale, case-sensitive filesystem |
| PATH drift | command missing, executable resolves to a different path |
When you don't have a config yet, compare a working machine against a broken one directly.
On the working machine:
snagify snapshot working.jsonOn the broken machine:
snagify snapshot broken.jsonCompare them:
snagify diff working.json broken.jsonExample:
Project: checkout-service
A = working B = broken
Critical differences
────────────────────
Maven working: 3.9.6 broken: missing ← likely blocker
Docker working: present broken: missing ← likely blocker
.env broken missing: DATABASE_URL, JWT_SECRET
Differences
───────────
Java working: 17.0.9 broken: 21.0.2
Postgres working: running broken: not running
Likely blockers for broken:
• Maven is missing
• Docker is not installed
• Required environment keys are absent: DATABASE_URL, JWT_SECRET
--format markdown produces GitHub-friendly tables; --format json is machine-readable.
Define expected setup in .snagify.yaml and let every teammate check locally.
snagify init # generate a conservative starter config
snagify check # check this machine against it.snagify.yaml supports runtime version requirements ("17", ">=20 <23", ">=3.8", "required"), required .env keys (names only — values are never read), ports that must be free or listening, git branch/clean rules, required PATH commands, Docker/compose requirements, system expectations, and active service/network/TLS probes.
Env key classification: snagify init classifies .env.example keys as required, recommended, or optional using conservative heuristics. Review .snagify.yaml after snagify init, especially for feature flags and optional providers — the generated lists are a starting point, not a contract.
Capture a known-good machine as a sanitized baseline, commit it, and let teammates compare against it — no one has to export and email snapshots.
# known-good machine:
snagify baseline create --out .snagify/baseline.json
# teammates:
snagify check --against .snagify/baseline.jsonThe baseline strips hostname and absolute paths and never contains secret values. Safe to commit.
Share a baseline over a temporary, TLS-encrypted, fingerprint-pinned server. The teammate's machine snapshot never leaves their machine.
# known-good machine:
snagify share baseline --file .snagify/baseline.json
# prints a command including --pin <fingerprint>
# teammate (same LAN/VPN):
snagify check --from https://<host>:<port>/baseline/<token> --pin sha256:<fingerprint>A one-time random token guards the path, the server expires (default 10m) and stops after a max number of downloads (default 20), and it never accepts uploads. Requires the machines to reach each other directly (same Wi-Fi, office LAN, or VPN) — there is no NAT traversal or cloud relay.
Check connectivity without a full setup check:
snagify probeRuns only the services (TCP), network (DNS/HTTP/proxy), and tls probes declared in your config. HTTP probes check status codes only — response bodies are never read. TLS verification is never disabled unless you pass --insecure-probe (which prints a loud warning).
Compare many snapshots against a baseline and see where the team diverges.
snagify diff-many --against baseline.json snapshots/Prints a per-machine drift table plus the most common blockers across the team.
| Command | Purpose |
|---|---|
| snagify snapshot [out.json] | Capture this machine's state |
| snagify diff <a> <b> | Compare two snapshots |
| snagify init | Generate a starter .snagify.yaml |
| snagify check | Check this machine against config or a baseline |
| snagify probe | Run only the active connectivity probes |
| snagify baseline create | Capture a sanitized, shareable baseline |
| snagify share baseline | Serve a baseline over secure local TLS |
| snagify diff-many | Summarize team drift against a baseline |
Useful flags: --format terminal|markdown|json, --project-root <path>, --timeout 2s, --no-network, --no-tls, --no-docker, snapshot --probes.
Snagify does not prove universal root cause.
It detects likely setup blockers and deterministic config violations. It does not replace Docker, Nix, Devbox, tracing tools, or actual debugging.
A future trace mode is documented in docs/TRACE.md, but this release does not run strace, ProcMon, or dtruss.
go mod tidy
go test ./...
go vet ./...
go build -o snagify .MIT
| Back | FazBrowse Home | New Git URL |