{"id":50850078,"url":"https://github.com/techouse/patholog","last_synced_at":"2026-06-14T13:05:46.888Z","repository":{"id":362892237,"uuid":"1218698051","full_name":"techouse/patholog","owner":"techouse","description":"Diagnose and fix PATH problems across macOS, Linux, and Windows.","archived":false,"fork":false,"pushed_at":"2026-06-06T12:54:51.000Z","size":2124,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-06T13:08:45.672Z","etag":null,"topics":["cli","cli-tool","linux","macos","path","rust","utility","windows"],"latest_commit_sha":null,"homepage":"https://techouse.github.io/patholog/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/techouse.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"techouse","custom":["https://paypal.me/ktusar"]}},"created_at":"2026-04-23T06:06:04.000Z","updated_at":"2026-06-06T12:54:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/techouse/patholog","commit_stats":null,"previous_names":["techouse/patholog"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/techouse/patholog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techouse%2Fpatholog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techouse%2Fpatholog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techouse%2Fpatholog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techouse%2Fpatholog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/techouse","download_url":"https://codeload.github.com/techouse/patholog/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techouse%2Fpatholog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34172196,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","cli-tool","linux","macos","path","rust","utility","windows"],"created_at":"2026-06-14T13:05:46.223Z","updated_at":"2026-06-14T13:05:46.883Z","avatar_url":"https://github.com/techouse.png","language":"Rust","funding_links":["https://github.com/sponsors/techouse","https://paypal.me/ktusar"],"categories":[],"sub_categories":[],"readme":"# patholog\n\nDiagnose and fix PATH problems across macOS, Linux, and Windows.\n\n[![GitHub Release](https://img.shields.io/github/v/release/techouse/patholog?logo=github)](https://github.com/techouse/patholog/releases/latest)\n[![Crates.io Version](https://img.shields.io/crates/v/patholog?logo=rust)](https://crates.io/crates/patholog)\n[![Crates.io MSRV](https://img.shields.io/crates/msrv/patholog?logo=rust)](https://crates.io/crates/patholog)\n[![Test](https://github.com/techouse/patholog/actions/workflows/test.yml/badge.svg)](https://github.com/techouse/patholog/actions/workflows/test.yml)\n[![codecov](https://codecov.io/gh/techouse/patholog/graph/badge.svg?token=qsdPHsjKcq)](https://codecov.io/gh/techouse/patholog)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/44b97859730f460c82a22c72ee21f8ed)](https://app.codacy.com/gh/techouse/patholog/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade)\n[![GitHub](https://img.shields.io/github/license/techouse/patholog)](https://github.com/techouse/patholog/blob/main/LICENSE)\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/techouse?logo=github)](https://github.com/sponsors/techouse)\n[![GitHub Repo stars](https://img.shields.io/github/stars/techouse/patholog)](https://github.com/techouse/patholog/stargazers)\n\n`patholog` explains why a command resolves to a particular executable, shows competing matches, diagnoses common PATH problems, scans shell startup files read-only, prints cleaned PATH proposals, and applies tightly scoped shell profile repairs through a managed block.\n\n\u003cimg src=\"https://raw.githubusercontent.com/techouse/patholog/refs/heads/main/docs/assets/patholog-demo.gif\" alt=\"patholog terminal demo\" width=\"920\"\u003e\n\n## Why It Exists\n\nPATH problems are usually invisible until the wrong tool runs. `patholog` is built for cases like:\n\n- `python`, `node`, or `cargo` resolving to an unexpected executable.\n- duplicate PATH entries hiding the real search order.\n- missing directories left behind by old installers.\n- unreadable PATH entries or shadowed command candidates.\n- Cargo, Homebrew, pyenv, nvm, or system directories appearing in surprising order.\n- shell config drift between machines.\n\nThe goal is to explain before changing anything.\n\n## Quick Examples\n\n```sh\npatholog doctor\npatholog health --json\npatholog doctor --command python\npatholog why python\npatholog why-not poetry\npatholog conflicts cargo\npatholog scan\npatholog clean --stdout\npatholog clean --stdout --drop /sw/bin\npatholog clean --export --var manpath --shell zsh\npatholog clean --export --shell zsh\npatholog apply --dry-run --shell zsh\npatholog apply --shell zsh --yes\npatholog config check --config patholog.toml\npatholog completions zsh\n```\n\n## Installation\n\nInstall the latest GitHub release on Linux or macOS:\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/techouse/patholog/refs/heads/main/install.sh | sh\n```\n\nThe installer downloads the matching release archive, verifies its SHA-256\nchecksum, installs `patholog` to `~/.local/bin`, and installs bash, zsh, and fish\ncompletions. Set `PATHOLOG_INSTALL_DIR` to choose another install directory, set\n`PATHOLOG_VERSION` to install a specific release, set `PATHOLOG_LINUX_LIBC=musl`\nor `gnu` to override Linux libc detection, and set\n`PATHOLOG_INSTALL_COMPLETIONS=0` to skip completions.\n\nInstall with Homebrew:\n\n```sh\nbrew install techouse/patholog/patholog\n```\n\nOr tap the repository first:\n\n```sh\nbrew tap techouse/patholog\nbrew install patholog\n```\n\nInstall from crates.io:\n\n```sh\ncargo install patholog\n```\n\nOr download a release artifact from\n[GitHub Releases](https://github.com/techouse/patholog/releases). Linux releases\ninclude GNU/glibc and musl `.tar.gz` archives for x86_64 and ARM64, plus\nGNU/glibc `.deb` and `.rpm` packages for x86_64 and ARM64. Windows releases\ninclude a `.zip` archive for x86_64 MSVC. macOS releases include a signed and\nnotarized universal `.zip` archive for Apple Silicon and Intel Macs. Archives\ninclude the `patholog` binary, shell completions, `README.md`, `LICENSE`, and\n`THIRD-PARTY-LICENSES.md`. Verify downloads with the release `SHA256SUMS.txt`\nfile or the per-artifact `.sha256` sidecar.\n\n### Shell Completions\n\nThe `install.sh` installer installs bash, zsh, and fish completions by default.\nSet `PATHOLOG_INSTALL_COMPLETIONS=0` to skip completion installation.\n\nInstall shell completions manually by writing the generated script to your\nshell's completion directory.\n\nBash:\n\n```sh\nmkdir -p ~/.local/share/bash-completion/completions\npatholog completions bash \u003e ~/.local/share/bash-completion/completions/patholog\n```\n\nZsh:\n\n```sh\nmkdir -p ~/.zfunc\npatholog completions zsh \u003e ~/.zfunc/_patholog\n```\n\nAdd this to `.zshrc` if `~/.zfunc` is not already in `fpath`:\n\n```zsh\nfpath=(~/.zfunc $fpath)\nautoload -Uz compinit\ncompinit\n```\n\nFish:\n\n```fish\nmkdir -p ~/.config/fish/completions\npatholog completions fish \u003e ~/.config/fish/completions/patholog.fish\n```\n\nPowerShell:\n\n```powershell\nNew-Item -ItemType Directory -Force (Split-Path $PROFILE) | Out-Null\npatholog completions pwsh | Add-Content $PROFILE\n```\n\n## Command Surface\n\n```sh\npatholog print [--json] [--platform auto|posix|windows] [--var path|manpath]\npatholog doctor [--json] [--platform auto|posix|windows] [--var path|manpath] [--drop \u003centry\u003e] [--preset homebrew|cargo|pyenv|fink] [--fail-on=missing,duplicate,...] [--command \u003ccommand\u003e] [--config \u003cfile|auto\u003e]\npatholog health [--json] [--platform auto|posix|windows] [--var path|manpath] [--drop \u003centry\u003e] [--preset homebrew|cargo|pyenv|fink] [--config \u003cfile|auto\u003e]\npatholog why \u003ccommand\u003e [--json] [--platform auto|posix|windows]\npatholog why-not \u003ccommand\u003e [--json] [--platform auto|posix|windows]\npatholog conflicts \u003ccommand\u003e [--json] [--platform auto|posix|windows]\npatholog scan [--json] [--platform auto|posix|windows] [--home \u003cdir\u003e]\npatholog clean --stdout [--platform auto|posix|windows] [--var path|manpath] [--drop \u003centry\u003e] [--preset homebrew|cargo|pyenv|fink] [--config \u003cfile|auto\u003e]\npatholog clean --export --shell zsh|bash|fish|pwsh [--platform auto|posix|windows] [--var path|manpath] [--drop \u003centry\u003e] [--preset homebrew|cargo|pyenv|fink] [--config \u003cfile|auto\u003e]\npatholog apply --dry-run --shell zsh|bash|fish|pwsh [--json] [--platform auto|posix|windows] [--home \u003cdir\u003e] [--profile \u003cfile\u003e] [--drop \u003centry\u003e] [--preset homebrew|cargo|pyenv|fink] [--config \u003cfile|auto\u003e]\npatholog apply --shell zsh|bash|fish|pwsh --yes [--no-backup] [--json] [--platform auto|posix|windows] [--home \u003cdir\u003e] [--profile \u003cfile\u003e] [--drop \u003centry\u003e] [--preset homebrew|cargo|pyenv|fink] [--config \u003cfile|auto\u003e]\npatholog config check --config \u003cfile|auto\u003e\npatholog config print --config \u003cfile|auto\u003e [--json]\npatholog completions zsh|bash|fish|pwsh\n```\n\n`patholog` mutates files only for `apply --yes`. Other commands do not edit shell profiles, environment variables, or files.\n\n## Read-Only Diagnostics\n\n`doctor` reports duplicate, missing, non-directory, unreadable, empty, explicitly unwanted, and suspiciously ordered PATH entries. With `--command`, it also reports executable candidates shadowed by an earlier winner:\n\n```sh\npatholog doctor --command python\npatholog doctor --drop /sw/bin --fail-on=unwanted\n```\n\n`health` summarizes those diagnostics as an advisory deterministic score, issue counts, worst severity, and the diagnostics used to compute the score:\n\n```sh\npatholog health --json\npatholog health --var manpath\n```\n\nExample JSON excerpt:\n\n```json\n{\n  \"score\": 85,\n  \"healthy\": false,\n  \"worst_severity\": \"error\",\n  \"counts\": {\n    \"missing\": 1\n  }\n}\n```\n\nUse `doctor --fail-on` when you need a CI gate; `health` always exits `0` when the summary is calculated successfully.\n\n`--var manpath` switches `print`, `doctor`, `health`, and `clean` to `MANPATH`. Command resolution and profile planning stay PATH-only. `clean --var manpath` preserves empty MANPATH components because common man implementations use them to include the system default manpath.\n\n`scan` reads known shell startup profiles under the home directory and reports likely PATH mutation lines. It does not source or edit those files:\n\n```sh\npatholog scan\npatholog scan --home /tmp/example-home\n```\n\n## Output Modes\n\nHuman output is the default. JSON output is available for `print`, `doctor`, `health`, `why`, `why-not`, `conflicts`, `scan`, and `apply`:\n\n```sh\npatholog doctor --json\npatholog health --json\npatholog why python --json\npatholog why-not poetry --json\npatholog scan --json\n```\n\n`why-not` explains missing-command cases by combining exact PATH lookup, related executable hints, PATH health diagnostics, and safe advisory next checks. It is read-only and does not run package managers or edit shell configuration.\n\n`clean --stdout` prints a raw PATH or MANPATH string suitable for review or manual export. `clean --export` prints a shell-ready assignment snippet for `zsh`, `bash`, `fish`, or `pwsh`:\n\n```sh\npatholog clean --export --shell zsh\npatholog clean --export --var manpath --shell zsh\n```\n\n`completions` prints shell completion scripts to stdout:\n\n```sh\npatholog completions zsh\n```\n\n`apply --dry-run` plans a shell profile edit without writing files. `apply --yes` writes the same managed block, creates backups for existing profiles by default, and never rewrites arbitrary PATH lines outside the patholog block:\n\n```sh\npatholog apply --dry-run --shell zsh\npatholog apply --dry-run --shell zsh --json\npatholog apply --dry-run --shell zsh --drop /sw/bin\npatholog apply --shell zsh --yes\npatholog apply --shell zsh --yes --no-backup\n```\n\n`--preset fink` marks `/sw/bin` and `/sw/sbin` as unwanted for PATH, and `/sw/share/man` as unwanted for MANPATH. `homebrew`, `cargo`, and `pyenv` presets enable ecosystem policy checks without automatically reordering entries.\n\n## Config Files\n\n`--config \u003cfile\u003e` lets `doctor`, `health`, `clean`, and `apply` load declarative policy defaults. CLI flags append after config values:\n\n```toml\nversion = 1\n\n[path]\ndrop = [\"/sw/bin\"]\npreset = [\"homebrew\", \"cargo\"]\nfail_on = [\"duplicate\", \"unwanted\"]\n\n[manpath]\ndrop = [\"/sw/share/man\"]\npreset = [\"fink\"]\nfail_on = [\"duplicate\"]\n```\n\nUse `patholog config check --config patholog.toml` to validate a file, or `patholog config print --config patholog.toml --json` to inspect normalized policy. `--config auto` searches only the current working directory for `patholog.toml`, then `.patholog.toml`.\n\n`health` uses config `drop` and `preset` policy for scoring, but `fail_on` remains specific to `doctor`.\n\n## Exit Codes\n\n- `0`: success\n- `1`: usage or runtime error\n- `2`: `doctor --fail-on` matched selected diagnostics\n- `3`: command not found for `why`, `why-not`, or `conflicts`\n\n## Platform Model\n\n- `auto` uses host platform rules.\n- `posix` uses `:` separators and case-sensitive comparison keys.\n- `windows` uses `;` separators, case-insensitive comparison keys, and PATHEXT modeling.\n\nWindows command resolution differs from POSIX lookup because file extensions and `PATHEXT` affect which executable wins. `patholog --platform windows` models that behavior for tests and cross-platform inspection.\n\nPATH values are handled as UTF-8 strings to preserve v0.1 parity. Symlinks, inode identity, and canonical-file identity are not analyzed.\n\n## Safety\n\nAll commands are read-only except `apply --yes`, which writes only the patholog-managed block in the selected shell\nprofile. When the selected target is `~/.zshrc`, `~/.bashrc`, `~/.profile`, or a PowerShell profile, `patholog` may\ncreate, append, or replace that managed block, but it does not rewrite arbitrary profile content outside the block or\nedit system environment configuration.\n\n`clean --stdout`, `clean --export`, `apply --dry-run`, and `completions` only print generated text. Mutating `apply` requires `--yes` and backs up existing profiles unless `--no-backup` is passed.\n\n## Development\n\n```sh\nmake ci\nmake install-smoke\nmake v1-contract-check\nmake pre-release\n```\n\nUse `make ci` for normal local checks, `make install-smoke` to test the packaged crate in a temporary install root,\n`make v1-contract-check` for the v1 contract audit, and `make pre-release` as the full gate before tagging a\nrelease.\n\nGolden parity fixtures are vendored in `tests/fixtures/golden`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechouse%2Fpatholog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechouse%2Fpatholog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechouse%2Fpatholog/lists"}