{"_id":"@ashhitch/portctl","_rev":"2-b54b6adea16df447da279bfb0652d200","name":"@ashhitch/portctl","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@ashhitch/portctl","version":"0.1.0","_id":"@ashhitch/portctl@0.1.0","maintainers":[{"name":"ashhitch","email":"hello@ashleyhitchcock.co.uk"}],"bin":{"portctl":"dist/index.js"},"dist":{"shasum":"776450aed9ec01c68b6624219cd393de4af21000","tarball":"https://registry.npmjs.org/@ashhitch/portctl/-/portctl-0.1.0.tgz","fileCount":3,"integrity":"sha512-UFd5/WeySQnJGG/TVwWW+Pv5mZ65XpzuvMY624c9ollT4Et6UJ0yIz6I58js/pwEf+g798eVNMB6dxBSN52TLg==","signatures":[{"sig":"MEQCIBa6sfOdRHaYb1NhBEq1ChpCSGgRcusfPhqm0YTl+W7jAiBjl5dKeH2LSdG7G9j0IBCEqJcB+hzlmDeabx5ViMfRJw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16546},"main":"dist/index.js","type":"module","gitHead":"6e5f565440c89a6f8fc6be3f79c8aadb6ba0be15","scripts":{"build":"bun build index.ts --outfile=dist/index.js --target=node --external @opentui/core --banner \"#!/usr/bin/env node\" && chmod +x dist/index.js","start":"bun index.ts"},"_npmUser":{"name":"ashhitch","email":"hello@ashleyhitchcock.co.uk"},"_npmVersion":"10.9.2","description":"A cross-platform terminal UI for listing TCP listening ports and killing the processes that own them. Useful for quickly freeing up a port that's stuck occupied by a runaway or background process.","directories":{},"_nodeVersion":"22.15.1","dependencies":{"@opentui/core":"^0.4.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/portctl_0.1.0_1782479888210_0.04808197472602682","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ashhitch/portctl","version":"0.1.1","type":"module","bin":{"portctl":"dist/index.js"},"main":"dist/index.js","scripts":{"start":"bun index.ts","build":"bun build index.ts --outfile=dist/index.js --target=bun --external @opentui/core --banner \"#!/usr/bin/env bun\" && chmod +x dist/index.js"},"dependencies":{"@opentui/core":"^0.4.2"},"_id":"@ashhitch/portctl@0.1.1","gitHead":"dba0ae1027da184659f65bd7429a5cde2f3a9adc","description":"A cross-platform terminal UI for listing TCP listening ports and killing the processes that own them. Useful for quickly freeing up a port that's stuck occupied by a runaway or background process.","_nodeVersion":"22.15.1","_npmVersion":"10.9.2","dist":{"integrity":"sha512-1lLgkq5yy2VAvmcBHhEBuXlMOXCvvETLRyzXFRryem/mKcZb65426ERxWOcNhuEcGoxR91Ymf3/AsA0hMDgtfA==","shasum":"3dfa7c1739da96e14319bad90b850fdc7c43a41c","tarball":"https://registry.npmjs.org/@ashhitch/portctl/-/portctl-0.1.1.tgz","fileCount":3,"unpackedSize":16858,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD1hDhv+f4cxzos6qT9QGdcdXdQlmUUU2dn7qIXq88nWAIgWGicSLcI4N1YLM/RFVhPJcdl+z7207ZtqLtKY+qMbT8="}]},"_npmUser":{"name":"ashhitch","email":"hello@ashleyhitchcock.co.uk"},"directories":{},"maintainers":[{"name":"ashhitch","email":"hello@ashleyhitchcock.co.uk"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/portctl_0.1.1_1782480333638_0.9316401362373035"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-26T13:18:08.005Z","modified":"2026-06-26T13:25:33.986Z","0.1.0":"2026-06-26T13:18:08.331Z","0.1.1":"2026-06-26T13:25:33.866Z"},"description":"A cross-platform terminal UI for listing TCP listening ports and killing the processes that own them. Useful for quickly freeing up a port that's stuck occupied by a runaway or background process.","maintainers":[{"name":"ashhitch","email":"hello@ashleyhitchcock.co.uk"}],"readme":"# portctl\n\nA cross-platform terminal UI for listing TCP listening ports and killing the\nprocesses that own them. Useful for quickly freeing up a port that's stuck\noccupied by a runaway or background process.\n\nBuilt with [Bun](https://bun.sh) and\n[`@opentui/core`](https://github.com/sst/opentui). No other dependencies.\n\n## Features\n\n- Lists all TCP `LISTEN` sockets with owning PID and process name\n- Cross-platform: macOS, Linux, and Windows\n- Sortable by port number\n- Auto-refresh every 5 seconds, plus manual refresh on demand\n- Inline `y/N` confirmation before killing — no accidental terminations\n- IPv4, IPv6, and wildcard (`*`) addresses supported\n- Alternate-screen TUI that restores your terminal on exit\n\n## Requirements\n\n- [Bun](https://bun.sh) runtime\n- Platform-specific CLI tools available on `PATH`:\n  - **macOS**: `lsof`\n  - **Linux**: `ss` (preferred), falls back to `netstat`, then `lsof`\n  - **Windows**: `netstat` and `tasklist`\n\n> Some system-owned ports (e.g. ports < 1024) may not appear or may refuse to\n> be killed without elevated privileges. Run with appropriate permissions if\n> you need to manage those.\n\n## Install\n\nThe CLI is built on [Bun](https://bun.sh) and OpenTUI's native renderer, so\nBun must be installed and on your `PATH` to run it.\n\n```bash\n# from npm\nnpm install -g @ashhitch/portctl\n# or run once without installing\nnpx @ashhitch/portctl\n```\n\n> `npx`/`npm` only fetch the package — they don't install Bun. If you don't have\n> it yet, install it first: `curl -fsSL https://bun.sh/install | bash`\n\nFor local development:\n\n```bash\nbun install\n```\n\n## Run\n\n```bash\n# via the installed binary\nportctl\n\n# from source\nbun index.ts\n# or\nbun run start\n```\n\n## Controls\n\n| Key            | Action                                  |\n| -------------- | --------------------------------------- |\n| `↑` / `↓`      | Move selection                          |\n| `Enter`        | Prompt to kill the selected process     |\n| `y` / `n`      | Confirm / cancel the kill prompt        |\n| `r`            | Refresh the port list                   |\n| `q`            | Quit                                    |\n| `Ctrl`+`C`     | Quit                                    |\n\nThe list refreshes automatically every 5 seconds. Manual refresh with `r`\npreserves your current selection when possible.\n\n## How it works\n\n`src/ports.ts` shells out to the platform's native networking tools, parses\ntheir output into a common `PortEntry` shape, and exposes two functions:\n\n- `listListeningPorts()` — returns TCP listeners sorted by port\n- `killProcess(pid)` — sends `SIGTERM` (then `SIGKILL` on failure) on Unix, or\n  runs `taskkill /F /PID` on Windows\n\n`index.ts` renders the TUI using OpenTUI's imperative `Renderable` API. The\nlayout is a header (title + help), a scrollable `Select` of ports, and a footer\nshowing port count, last refresh time, and the active confirmation prompt.\n\n## Project layout\n\n```\nportctl/\n├── index.ts          # TUI: layout, key handling, refresh + kill flow\n├── src/\n│   └── ports.ts      # Cross-platform port detection and process killing\n├── package.json\n└── bun.lock\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}