From 80661712bfdfc64844ee6f6e280d062e53d5fae5 Mon Sep 17 00:00:00 2001 From: KellyMichels Date: Fri, 24 Jul 2026 13:24:20 -0500 Subject: [PATCH] feat(zkill): support 'all' to stop every project's dev server zkill now accepts 'all', expanding to every project that has a ports.dev (edge/docker stacks with no local dev server are skipped) - matching zdeploy all / zbackup all. Ported to both the PowerShell (ZKillOnly.ps1) and bash (bash/zkill) versions; README + CHANGELOG updated. --- CHANGELOG.md | 5 +++++ README.md | 7 ++++--- ZKillOnly.ps1 | 17 ++++++++++++++++- bash/zkill | 15 ++++++++++++++- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebc3d52..f575982 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,11 @@ Notable changes to the Evomedia.net Token Savers. credentials and RSA signing keys. ### Added +- **`zkill all`** — `zkill` now accepts `all`, stopping the dev server of + every project that has a `ports.dev` (edge/docker stacks with no local dev + server are skipped). Brings it in line with `zdeploy all` / `zbackup all`; + the one-shot "stop everything I've got running locally". Ported to both the + PowerShell and bash versions. - **`zdeploy` server-side health verification (`verify` block)** — projects not published through the edge proxy can declare `"verify": { "port": ..., "path": "/health", "expect": "..." }` and the diff --git a/README.md b/README.md index 2e38dc3..ccc29b2 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ The `.cmd` wrappers are the everyday interface. Every command takes one or more |---|---| | `zstart ...` | Start local dev server(s) | | `zstartd ...` | Same, detached (new window, returns immediately) | -| `zkill ...` | Kill local dev server(s) by port | +| `zkill ... \| all` | Kill local dev server(s) by port | | `zrestart ...` | Kill + start in one step | | `zrestartd ...` | Kill + start detached | | `zdeploy ... \| all` | Zip → upload → rebuild → verify a project on the server | @@ -147,14 +147,15 @@ zstartd nextapp # detached: window opens, prompt returns #### `zkill` — stop dev servers ``` -zkill [ ...] [-Port N] [-KillAll] +zkill [ ...] | all [-Port N] [-KillAll] ``` -Finds whatever is LISTENING on each project's dev port and kills it — along with its whole process tree, children first. That matters for auto-reloading servers (uvicorn/watchfiles, nodemon): their worker processes inherit the listening socket and would otherwise survive as orphans, serving stale code. `-KillAll` also hunts down stray `node`/`python`/`next-server` processes whose command line references the project folder. +Finds whatever is LISTENING on each project's dev port and kills it — along with its whole process tree, children first. That matters for auto-reloading servers (uvicorn/watchfiles, nodemon): their worker processes inherit the listening socket and would otherwise survive as orphans, serving stale code. `-KillAll` also hunts down stray `node`/`python`/`next-server` processes whose command line references the project folder. `all` targets every project that has a dev port — the one-shot "stop everything I've got running locally". ```powershell zkill viteapp # free the port zkill pyapp viteapp nextapp # nuke everything +zkill all # stop every project's dev server zkill nextapp -KillAll # also kill orphaned runtime processes ``` diff --git a/ZKillOnly.ps1 b/ZKillOnly.ps1 index bdb8947..e4a2f1e 100644 --- a/ZKillOnly.ps1 +++ b/ZKillOnly.ps1 @@ -26,11 +26,26 @@ Start-ZTracking if ($Projects.Count -eq 0) { $keys = (Get-ZProjectKeys) -join ', ' Write-Host "" - Write-Host "Usage: zkill [ ...] [-Port N] [-KillAll]" -ForegroundColor Yellow + Write-Host "Usage: zkill [ ...] | all [-Port N] [-KillAll]" -ForegroundColor Yellow Write-Host " Projects in zconfig.json: $keys" -ForegroundColor Gray + Write-Host " 'all' stops the dev server of every project that has one." -ForegroundColor Gray Stop-ZTracking; exit 1 } +# Tolerate switch-style args (zkill -myproject) from muscle memory. +$Projects = @($Projects | ForEach-Object { $_.TrimStart('-') }) + +# 'all' -> every project that actually has a local dev server (a ports.dev). +if ($Projects -contains 'all') { + $cfg = Get-ZConfig + $Projects = @(Get-ZProjectKeys | Where-Object { $cfg.projects.$_.ports -and $cfg.projects.$_.ports.dev }) + if ($Projects.Count -eq 0) { + Write-Host "No projects have a dev port to kill." -ForegroundColor Yellow + Stop-ZTracking; exit 0 + } + Write-Host "Killing dev servers for: $($Projects -join ', ')" -ForegroundColor Cyan +} + foreach ($key in $Projects) { $proj = Get-ZProject -Key $key $devPort = if ($Port -gt 0) { $Port } elseif ($proj.ports -and $proj.ports.dev) { [int]$proj.ports.dev } else { 0 } diff --git a/bash/zkill b/bash/zkill index eed91fd..0d7e5d8 100644 --- a/bash/zkill +++ b/bash/zkill @@ -26,11 +26,24 @@ while [ $# -gt 0 ]; do done if [ "${#projects[@]}" -eq 0 ]; then - warn "Usage: zkill [ ...] [--port N] [--kill-all]" + warn "Usage: zkill [ ...] | all [--port N] [--kill-all]" dim " Projects in zconfig.json: $(zproj_csv)" + dim " 'all' stops the dev server of every project that has one." exit 1 fi +# 'all' -> every project that actually has a local dev server (a ports.dev). +if printf '%s\n' "${projects[@]}" | grep -qx 'all'; then + dev_keys=(); while IFS= read -r _zl || [ -n "$_zl" ]; do dev_keys+=("$_zl"); done \ + < <(jq -r '.projects | to_entries[] | select((.key | startswith("_") | not) and .value.ports.dev != null) | .key' "$ZCONFIG") + if [ "${#dev_keys[@]}" -eq 0 ]; then + warn "No projects have a dev port to kill." + exit 0 + fi + projects=("${dev_keys[@]}") + info "Killing dev servers for: $(printf '%s ' "${projects[@]}")" +fi + # --kill-all (kill stray project processes beyond the dev-port listener) isn't # ported yet; announce it rather than silently accepting the flag and doing nothing. [ "$kill_all" -eq 1 ] && warn "Note: --kill-all isn't implemented in the bash port yet - killing dev-port listeners only."