{"id":49076319,"url":"https://github.com/al-nemirov/portman","last_synced_at":"2026-04-26T07:01:14.035Z","repository":{"id":352576109,"uuid":"1215596161","full_name":"al-nemirov/portman","owner":"al-nemirov","description":"Retro CRT-styled Windows dispatcher for localhost dev servers. See whats listening, kill duplicates, auto-clean idle dev servers. One-click desktop launcher.","archived":false,"fork":false,"pushed_at":"2026-04-20T08:08:06.000Z","size":348,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-20T09:13:25.548Z","etag":null,"topics":["astro","cli","crt","dev-server","developer-tools","devtools","idle-killer","kill-process","localhost","netstat","nextjs","nodejs","port-manager","ports","process-manager","retro","system-utility","task-manager","vite","windows"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/al-nemirov.png","metadata":{"files":{"readme":"README.de.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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}},"created_at":"2026-04-20T04:25:18.000Z","updated_at":"2026-04-20T08:07:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/al-nemirov/portman","commit_stats":null,"previous_names":["al-nemirov/portman"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/al-nemirov/portman","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/al-nemirov%2Fportman","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/al-nemirov%2Fportman/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/al-nemirov%2Fportman/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/al-nemirov%2Fportman/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/al-nemirov","download_url":"https://codeload.github.com/al-nemirov/portman/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/al-nemirov%2Fportman/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32042293,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"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":["astro","cli","crt","dev-server","developer-tools","devtools","idle-killer","kill-process","localhost","netstat","nextjs","nodejs","port-manager","ports","process-manager","retro","system-utility","task-manager","vite","windows"],"created_at":"2026-04-20T10:01:35.166Z","updated_at":"2026-04-26T07:01:14.028Z","avatar_url":"https://github.com/al-nemirov.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.png\" alt=\"PORTMAN\" width=\"180\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003ePORTMAN\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"README.md\"\u003eEnglish\u003c/a\u003e ·\n  \u003ca href=\"README.ko.md\"\u003e한국어\u003c/a\u003e ·\n  \u003cb\u003eDeutsch\u003c/b\u003e ·\n  \u003ca href=\"README.es.md\"\u003eEspañol\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Retro CRT-Stil Windows-Dispatcher für lokale Dev-Server.\u003cbr\u003e\n  Sehen, was lauscht, was leerläuft, Duplikate töten, abgestandene\u003cbr\u003e\n  Dev-Server automatisch aufräumen. Ein-Klick-Desktop-Launcher.\u003cbr\u003e\n  UI in EN / KO / DE / ES.\n\u003c/p\u003e\n\n[![Platform](https://img.shields.io/badge/platform-Windows-0a84ff)](https://github.com/al-nemirov/portman)\n[![Node](https://img.shields.io/badge/node-%3E%3D18-339933)](https://nodejs.org)\n[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n\n---\n\n## Warum\n\nWenn du täglich zwischen Next.js, Vite, Astro, Express, Python-Servern und PHP\nhin- und herspringst, sammelst du **einen Friedhof vergessener `npm run dev`-Prozesse**,\ndie still RAM fressen und Ports belegen. Der Windows-Task-Manager hilft nicht —\ner zeigt zehn Mal `node.exe` ohne Hinweis darauf, welcher zu welchem Projekt gehört.\n\n`portman` löst genau das:\n\n- Ein Bildschirm zeigt **jeden TCP-LISTEN-Prozess** auf deiner Maschine, gruppiert\n  und farbcodiert.\n- Sagt dir, **welche tatsächlich genutzt werden** (offene Verbindungen) und welche\n  **leerlaufen** (lauschen, aber niemand spricht mit ihnen).\n- Ein Klick zum **Töten** eines leerlaufenden Dev-Servers. Systemprozesse sind\n  physisch nicht klickbar.\n- Ein optionaler **Auto-Modus** wischt leerlaufende Dev-Server älter als N Minuten —\n  einstellen und vergessen.\n- Der Wrapper-Befehl `portman run -- npm run dev` registriert deinen Dev-Server\n  mit einem Label und **tötet die vorherige Instanz desselben Projekts automatisch**\n  beim Start einer neuen.\n- **Live-RAM und -CPU pro Prozess** — sortiere nach RAM ↓, um den Dev-Server\n  zu finden, der heimlich 2 GB frisst.\n- **Klickbare `localhost:PORT`-Links** — öffne jeden Dev-Server in einem neuen Tab\n  direkt aus der Tabelle.\n- **Filter-Chips** (ALL / DEV / ACTIVE / IDLE / PROTECTED) und **Sofort-Suche**\n  nach PID / Name / Port / Label / Befehl.\n\n## Screenshots\n\nDas UI ist absichtlich retro: Phosphor-grünes CRT, Scanlines, gepunktete Ränder,\nein einzelner großer AUTO-Schalter. Keine Menüs. Keine Tabs. Keine unnötigen Modale.\n\n```\n▎PORTMAN        PROC 26   IDLE 4   PROT 23      [● AUTO · AN]   [⚙]\n\nPID    NAME              PORTS           CONN  STATUS    AGE · IDLE     ACTION\n◈ 4    System            445 5357 139    0     PROTECTED — · —          ◈ LOCKED\n◆ 4152 php.exe           8000            0     IDLE      — · 12m        ▸ KILL\n● 9234 [moandanang] node 3000            2     ACTIVE    47m · 2s       ▸ KILL\n◆ 7710 node.exe          5173            0     IDLE      — · 38m        ▸ KILL\n◈ 6428 mysqld.exe        3306            0     PROTECTED — · —          ◈ LOCKED\n```\n\nLegende:\n- `●` über `portman run` registriert (du weißt, was es ist)\n- `◆` unbekannt, aber im Dev-Port-Bereich (3000–9999)\n- `◈` Systemprozess — gesperrt, KILL-Button ausgeblendet\n\n---\n\n## Installation\n\n### Voraussetzungen\n- **Windows 10 oder 11**\n- **Node.js ≥ 18** ([nodejs.org](https://nodejs.org))\n\n### Code holen\n```powershell\ngit clone https://github.com/al-nemirov/portman.git C:\\Tools\\portman\ncd C:\\Tools\\portman\n```\n(Kein `npm install` nötig — null Abhängigkeiten)\n\n### Global verfügbar machen (optional)\n```powershell\nnpm link\n```\nDanach kannst du `portman` von überall eingeben.\n\n---\n\n## Ausführen\n\n### Ein-Klick-Start (empfohlen)\n\nDoppelklicke einmal **`install-shortcut.bat`** — es erstellt ein `PORTMAN.lnk`-Symbol\nauf deinem Desktop. Danach Doppelklick auf das Desktop-Symbol zum Starten. Der Server\nläuft still im Hintergrund; dein Standardbrowser öffnet\n[http://127.0.0.1:9876](http://127.0.0.1:9876).\n\nDu kannst die Verknüpfung ins Startmenü ziehen oder an die Taskleiste anheften.\n\n### Andere Startoptionen\n\n| Datei / Befehl | Was es macht |\n|---|---|\n| `portman.bat` | Mit **Konsolenfenster** ausführen (Logs sichtbar, mit `Ctrl+C` stoppen) |\n| `portman-silent.vbs` | Still im Hintergrund, kein Fenster |\n| `portman ui` | Dasselbe (nach `npm link`) |\n| `portman ui --port=9000` | Eigener UI-Port |\n| `portman ui --no-open` | Browser nicht automatisch öffnen |\n\n---\n\n## Web-UI\n\nBesuche [http://127.0.0.1:9876](http://127.0.0.1:9876).\n\nDie Tabelle aktualisiert sich alle 3 Sekunden. Es gibt **nur zwei Steuerelemente** im Header:\n\n1. **AUTO-Schalter** — automatisches Töten leerlaufender Dev-Server an/aus.\n2. **⚙ Zahnrad** — öffnet eine Seitenschublade mit Einstellungen.\n\nJede Zeile hat höchstens einen Button: `▸ KILL`. Für geschützte Prozesse wird der\nButton durch `◈ LOCKED` ersetzt — du kannst sie buchstäblich nicht versehentlich töten.\n\n### Töten-Verhalten\n- **Dev-Bereich-Port + 0 Verbindungen** → `KILL` klicken = sofortiges Töten ohne Bestätigung.\n- **Außerhalb des Dev-Bereichs ODER mit offenen Verbindungen** → rotes Modal fragt\n  nach Bestätigung mit ausgedrucktem Grund.\n- **Geschützter Prozess** → kein Button überhaupt. Selbst wenn du eine HTTP-Anfrage\n  an `/api/kill` bastelst, gibt der Server `403 protected` zurück.\n\n### Status-Bedeutungen\n- `ACTIVE`  — hat gerade offene ESTABLISHED-Verbindungen (jemand nutzt es)\n- `IDLE`    — lauscht, aber letzte Aktivität war vor mehr als 60 Sekunden\n- `LISTEN`  — kürzlich gestartet, noch keine Aktivitätshistorie\n- `PROTECTED` — Systemprozess oder Whitelist-Port\n\n### Auto-Modus\nWährend AUTO AN ist, wischt `portman` alle 60 Sekunden die Registry. Ein Prozess\nwird getötet, wenn **alle** dieser Bedingungen wahr sind:\n- er ist **nicht** geschützt,\n- sein Port liegt im **Dev-Bereich** (Standard `3000–9999`),\n- er hat im Moment **0 offene Verbindungen**,\n- er war für **≥ N Minuten** im Leerlauf (Standard `30`, in der Zahnrad-Schublade einstellen).\n\nSystemprozesse und Ports außerhalb des Dev-Bereichs werden **niemals** vom AUTO\nberührt, egal was.\n\n---\n\n## Sicherheit / Geschützte Prozesse\n\nDrei Schutzschichten verhindern versehentliche Schäden:\n\n### 1. Hartcodierte geschützte Namen\n\nDefiniert in [`lib/server.js`](lib/server.js):\n```\nSystem, svchost.exe, lsass.exe, services.exe, wininit.exe,\nspoolsv.exe, csrss.exe, smss.exe, winlogon.exe, explorer.exe,\ndwm.exe, fontdrvhost.exe, mDNSResponder.exe, AcrylicService.exe,\nAnyDesk.exe, TeamViewer_Service.exe, GoogleDriveFS.exe,\nmysqld.exe, postgres.exe, redis-server.exe, mongod.exe,\nvmware-authd.exe, vpnclient_x64.exe, sabycenter.exe,\nss_conn_service.exe, ss_conn_service2.exe, Spotify.exe,\nCode.exe, cursor.exe, idea64.exe, pycharm64.exe, webstorm64.exe\n```\n\n### 2. Hartcodierte geschützte Ports\n\nAlles unter `1024` plus gängige Service-Ports:\n```\n22, 25, 53, 80, 110, 135, 139, 143, 443, 445, 465, 587, 993, 995,\n1433, 3306, 5432, 6379, 8080, 8443, 27017, 5984, 9200, 11211\n```\n\n### 3. Eigene Whitelist\n\nEigene Prozessnamen und Ports über die **⚙ Zahnrad → Zusatz geschützte Namen /\nZusatz geschützte Ports**-Felder hinzufügen. Gespeichert in `~/.portman/settings.json`.\n\n### Server-seitige Durchsetzung\nSelbst wenn ein bösartiges Skript in deinem Browser versucht, an `/api/kill` mit\neiner geschützten PID zu POSTen, prüft der Node-Server den Snapshot erneut und\ngibt `403 { error: \"protected\", reason: \"system\" }` zurück. **Vertraue dem Frontend\nnicht** — das Backend hat das letzte Wort.\n\n---\n\n## CLI\n\nNach `npm link`:\n\n```bash\nportman ui                                # Web-UI (Standard)\nportman ps                                # Prozessliste im Terminal\nportman kill 12345                        # Nach PID töten\nportman kill :3000                        # Prozess auf Port 3000 töten\nportman kill idle                         # Alle registrierten leerlaufenden Prozesse töten\nportman kill all                          # Alles in der Registry töten\nportman run --label=mysite --port=3000 -- npm run dev\nportman auto --interval=60 --idle=120     # CLI-only Watcher\n```\n\n### `portman run` — Dev-Server umhüllen\n```bash\nportman run --label=mysite --port=3000 -- npm run dev\n```\nWas es tut:\n1. Sucht nach zuvor registrierten Prozessen mit demselben `label`, `cwd` oder Hinweis-Port.\n2. **Tötet leerlaufende automatisch** (keine offenen Verbindungen).\n3. Lässt beschäftigte in Ruhe (gibt eine Warnung aus).\n4. Registriert den neuen Prozess in `~/.portman/registry.json`, sodass das UI das Label,\n   den cwd, die Startzeit und den ursprünglichen Befehl anzeigt.\n\nDies ist der sauberste Weg, `portman` langfristig zu nutzen: du bekommst einen\nDev-Server pro Projekt, und das Starten eines neuen räumt den vorherigen kostenlos auf.\n\n---\n\n## Zustandsdateien\n\nAller Zustand lebt in `~/.portman/`:\n\n| Datei | Zweck |\n|---|---|\n| `registry.json` | Prozesse, registriert über `portman run` |\n| `activity.json` | Verbindungs-Historie-Snapshots (zur Berechnung von `idle`) |\n| `settings.json` | UI-Einstellungen: AUTO-Status, Leerlauf-Schwelle, Port-Bereich, eigene Whitelists |\n\nPlain JSON. Sicher per Hand zu bearbeiten. Ordner löschen zum Zurücksetzen.\n\n---\n\n## Über die SmartScreen-Warnung\n\nDie `portman.exe` ist (noch) nicht code-signiert — Code-Signing-Zertifikate kosten $300+/Jahr. Beim ersten Start zeigt Windows eine gelbe Warnung. Klicke **Weitere Informationen → Trotzdem ausführen**.\n\nUm zu prüfen, ob die Binary mit dem Quellcode in diesem Repo übereinstimmt:\n```powershell\nGet-FileHash portman.exe -Algorithm SHA256\n```\nVergleiche mit dem Hash in den Release-Notes. Oder selbst bauen: `npm install \u0026\u0026 npm run build`.\n\nVollständige Erklärung: [English README — SmartScreen FAQ](README.md#why-does-windows-warn-me-about-portmanexe).\n\n## Lizenz\n\n[MIT](LICENSE) © Alexander Nemirov\n\n## Mitwirken\n\nAlleiniger Maintainer: [@al-nemirov](https://github.com/al-nemirov).\n**Pull Requests werden nicht akzeptiert.** Siehe [CONTRIBUTING.md](CONTRIBUTING.md).\nForke frei unter MIT-Lizenz.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fal-nemirov%2Fportman","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fal-nemirov%2Fportman","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fal-nemirov%2Fportman/lists"}