pidlyse — a native macOS menu-bar app that hunts down stray dev processes (orphaned test runners, idle servers, zombie playwright-mcp instances) and Docker containers, and clears them in one click. Ri
Developer toolsSwift · MakefileGitHub @fakeneuronOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Native macOS menu bar app that spots stray dev processes — orphaned test runners, idle servers, zombie helpers — and clears them in one click.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Native macOS menu bar app that spots stray dev processes and clears them in one click.
Sits beside the clock. Periodically scans for known process junk — orphaned test runners, idle servers, stale playwright-mcp instances, zombie Chrome helpers — and badges the icon when it finds them. Click to expand: a categorised list with per-row CPU%, RAM, and age; risk-tier color dots; kill buttons for obvious strays; and a "Needs review" section for anything that warrants a second look.Read the full README ↗Native macOS menu bar app that spots stray dev processes and clears them in one click.
Sits beside the clock. Periodically scans for known process junk — orphaned test runners, idle servers, stale playwright-mcp instances, zombie Chrome helpers — and badges the icon with how many look forgotten. Click to expand: likely strays first, grouped by why (session ended, idle, duplicate), with risk-tier color dots and kill buttons; everything still in use folds into one "Running" line you can open by project.
pytest, vitest, vite, jest, npm, docker, uvicorn, playwright, playwright-mcp, Chrome (playwright-mcp), bun, node, Next.js, Astro, cargo, go run, Electron (dev), LLM server, MCP serverVite dev server, wrangler dev, import-scraper.js), the owning project (the git repo / working directory the process runs in, e.g. bidviz or bidviz/frontend; full path on hover), the PID, and a risk-tier color dot (green / orange / red). Click a row for the "why is this here?" inspector (CPU%, RAM, age, tty status, orphan flag, age criteria, why it reads as a stray or as in use, the full command line, and provenance hints: the registered port it listens on, its full parent chain up to launchd, the Docker container that owns it, and its open files + sockets)npm run dev → vite, uv run → uvicorn, next dev → next-server, playwright-mcp → its Chrome helpers) show as a single row with a ×N count; its kill takes down and verifies every member, and the row inspector lists themkilling…, then what actually happened: gone, respawned, didn't die, can't kill, or skipped. "Clean all" reports the tally (e.g. Cleaned 4 of 6 · 1 respawned · 1 didn't die · 1.2 GB reclaimed), and the URL scheme, Shortcuts, and pidlyse clean use the same line.kill <pid>, and reveal the process's working directory in Finder (clipboard / Finder only, no extra shell-out)docker stop when you kill it there @ ~/path), custom detection rules (one command substring → a friendly label; always Needs Review), protected projects (kept out of "Clean all"), per-kind scan toggles (switch off whole process categories), launch at login, notification alerts (opt-in)Open Pidlyse.xcodeproj in Xcode and run (⌘R). The app lives in the menu bar — no Dock icon (LSUIElement = YES). Left-click the icon to open the popover; right-click (or two-finger tap) for a quick Quit menu.
Run the test suite from the command line with make test. The same suite runs automatically on every push to main via GitHub Actions (.github/workflows/test.yml).
Build a Release .app with ad-hoc signing: make build-release (output: build/Release/Pidlyse.app). Copy it to /Applications with make install. Package a distributable DMG (drag-install, with /Applications symlink): make dmg (output: build/Pidlyse.dmg). Push a v* tag to trigger the release workflow (.github/workflows/release.yml), which builds the Release app, packages the DMG, and attaches it to a GitHub Release automatically.
A terminal companion, pidlyse, builds from the same core: make build-cli (output: Packages/PidlyseCore/.build/release/pidlyse), install with make install-cli. pidlyse list [--all] prints the likely strays the popover leads with (name first, then the reason each reads as one; --all adds the processes in use), pidlyse clean runs the same "Clean all" sweep (likely strays that aren't high-risk, minus protected projects, registered-port listeners, and other users' processes) and exits with status 1 if any swept item is not verified gone, and pidlyse kill <pid> kills one listed candidate — all with the app's settings and kill safeguards, and CLI cleans land in the app's "Cleaned" tab.
Pidlyse exposes its clean/scan actions to external launchers (PID-EPIC-58):
open pidlyse://clean sweeps likely strays that aren't high-risk, protected, on a registered port, or another user's, and posts a result notification; open pidlyse://scan re-enumerates. Any launcher that opens a URL can drive it.pidlyse://clean and pidlyse clean.integrations/raycast/ wrap the installed pidlyse CLI for users who prefer the terminal companion (make install-cli first).AppleScript is intentionally not supported — osascript users can do shell script "pidlyse clean" via the CLI.
| State | Icon | Badge |
|---|---|---|
| Clean | ghost outline | none |
| Safe kills available | filled icon | red count |
| Review items only | filled icon | yellow count |
| Scanning | spinner overlay | — |
The icon pulses once when a new stray appears (suppressed under Reduce Motion).
Pidlyse sends real kill signals, so its trust story matters. The source is public precisely so you can verify all of the below:
Darwin.kill(pid, …) and only succeed against your own processes; anything owned by another user (e.g. the root Docker daemon) returns EPERM and is left untouched — and because the owner is read at scan time, such rows show an "unkillable" badge in place of the kill button and are left out of "Clean all". Pidlyse never escalates, never asks for an admin password.~/Library/Application Support/Pidlyse/ports.json if the user-created file exists (the app never writes it). Its only disk writes are the settings plist via UserDefaults (~/Library/Preferences/com.fakeneuron.pidlyse.plist), the clean log ~/Library/Application Support/Pidlyse/clean-log.json — one entry per confirmed kill (process kind, short project label, memory size, timestamp; never a command line), capped at the newest 1,000 events, written by both the app and the pidlyse CLI — and that log's empty sibling lock file clean-log.json.lock, which serializes those two writers.SMAppService. The registration persists until the app is removed or you disable the option in Settings.lsof times out), the sweep pauses for that scan: "Clean all" and pidlyse clean take nothing until a scan reads ports again, so an unreadable port can't let a port-bound stray through, and every easy row reads as needs-review until then./bin/ps, /usr/sbin/lsof, and docker (/usr/local/bin/docker or /opt/homebrew/bin/docker) — always with arguments passed as an array, never via a shell string. There is no , no lookup of the binary, and no user input interpolated into a command. The resolved binary is also verified before exec — owned by root or you, and not world-writable — so a trojan planted in a world-writable or foreign-owned location won't run on a docker-kill. (Residual: is group-writable by on Intel by design, so a same-group attacker could still replace it there; closing that would silently break Docker detection on those machines, so it's left as a documented gap.) Read it for yourself in (the one place a subprocess is spawned, each under a hard deadline), , , , and .Release DMGs are ad-hoc signed, not yet Apple-notarized, so on first launch macOS Gatekeeper shows "Apple could not verify…". To open it: right-click the app → Open (once), or clear the quarantine flag with xattr -d com.apple.quarantine /Applications/Pidlyse.app. Because the source is public, you can also just build it yourself (make build-release). Each release publishes a SHA-256 checksum alongside the DMG — verify with shasum -a 256 Pidlyse.dmg and compare.
Drag Pidlyse.app to the Trash. The residue is ~/Library/Preferences/com.fakeneuron.pidlyse.plist (tiny settings file), the ~/Library/Application Support/Pidlyse/ folder (the clean log, plus your ports.json if you created one) and, if "Launch at login" was enabled, a login-item registration. Remove them manually with rm ~/Library/Preferences/com.fakeneuron.pidlyse.plist and rm -r ~/Library/Application\ Support/Pidlyse; the login-item clears on its own once the app is gone.
See SPEC.md for the full technical specification, scan logic, classification rules, and project structure.
See .flaitron/PLAN.md.
sh -c$PATHdockerdocker/usr/local/binadmin