From skillry-runtime-and-local-app
Use when you need to design local launchers, shortcuts, browser opening, logs, and shutdown behavior across macOS, Windows, and Linux.
How this skill is triggered — by the user, by Claude, or both
Slash command
/skillry-runtime-and-local-app:10-local-launcher-shortcutsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Design local launchers and shortcuts that give a non-technical user a double-click experience: start the app, wait for readiness, open the browser, and stop cleanly — with no orphaned ports or stale processes — across macOS, Windows, and Linux. The launcher must use relative-to-itself paths (never a hardcoded home directory), gate the browser-open on a health signal, write timestamped logs to a...
Design local launchers and shortcuts that give a non-technical user a double-click experience: start the app, wait for readiness, open the browser, and stop cleanly — with no orphaned ports or stale processes — across macOS, Windows, and Linux. The launcher must use relative-to-itself paths (never a hardcoded home directory), gate the browser-open on a health signal, write timestamped logs to a stable path, and trap signals so shutdown frees the port every time.
.command, .bat/.ps1, .desktop) so non-developers can start it without a terminal.systemd/launchd/a service manager than a double-click script.cds to its own directory, starts the process and records its PID, polls a readiness signal, opens the browser only after ready, tees logs to a timestamped file, and traps EXIT INT TERM for clean shutdown..command (chmod +x), Windows .bat (cmd) or .ps1 (PowerShell, optionally a .lnk with an icon), Linux .desktop with Terminal=false.open (macOS), xdg-open (Linux), start "" <url> (Windows cmd), Start-Process <url> (PowerShell).logs/ directory or the org log root per policy — with a timestamp in the filename.lsof -i :PORT empty afterward).open (macOS) · xdg-open (Linux) · start "" <url> (Windows cmd) · Start-Process <url> (PowerShell).*.command file with chmod +x; the first run may need right-click → Open to clear Gatekeeper..bat for cmd or .ps1 for PowerShell; a .lnk shortcut can point at it and carry an icon.*.desktop entry with Exec= and Terminal=false; mark it executable and "Allow launching".sleep.trap/kill the process (group), then confirm the port is free.$(dirname "$0")-relative or absolute-derived paths, never another machine's home directory.set -euo pipefail..desktop uses an absolute or %k-relative Exec, not a bare relative path.# macOS run.command (chmod +x run.command; double-clickable)
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
mkdir -p logs
LOG="logs/app-$(date +%Y%m%d-%H%M%S).log"
npm run start >"$LOG" 2>&1 &
echo $! > .app.pid
trap 'kill "$(cat .app.pid)" 2>/dev/null; rm -f .app.pid' EXIT INT TERM
for i in $(seq 1 60); do
curl -fsS http://localhost:3000/health >/dev/null 2>&1 && break
sleep 0.5
[ "$i" = 60 ] && { echo "not ready, see $LOG"; exit 1; }
done
open http://localhost:3000
wait
:: Windows run.bat
@echo off
if not exist logs mkdir logs
start "" /b cmd /c "npm run start > logs\app.log 2>&1"
:wait
timeout /t 1 >nul
curl -fsS http://localhost:3000/health >nul 2>&1 || goto wait
start "" http://localhost:3000
# Windows run.ps1 (health-gated, opens default browser)
$ErrorActionPreference = "Stop"
New-Item -ItemType Directory -Force logs | Out-Null
$p = Start-Process npm -ArgumentList "run","start" -PassThru `
-RedirectStandardOutput "logs\app.log" -RedirectStandardError "logs\err.log"
try {
do { Start-Sleep -Milliseconds 500 }
until (try { Invoke-WebRequest http://localhost:3000/health -UseBasicParsing | Out-Null; $true } catch { $false })
Start-Process "http://localhost:3000"
Wait-Process -Id $p.Id
} finally { Stop-Process -Id $p.Id -ErrorAction SilentlyContinue }
# Linux app.desktop (mark executable, "Allow launching")
[Desktop Entry]
Type=Application
Name=My Local App
Exec=/bin/bash -c "cd %k/.. && ./run.sh"
Terminal=false
Icon=my-local-app
# Kill the whole process tree on shutdown (server may spawn children)
trap 'kill -- -$$ 2>/dev/null' EXIT INT TERM # negative PID = process group
# Verify clean shutdown after Ctrl-C
lsof -i :3000 || echo "port 3000 released"
chmod +x run.command # make the macOS launcher double-clickable
# Simple log rotation: keep the 5 most recent run logs
ls -t logs/app-*.log 2>/dev/null | tail -n +6 | xargs -r rm --
# Create a clickable Windows .lnk pointing at run.bat (with an icon), via PowerShell
powershell -Command "\$s=(New-Object -ComObject WScript.Shell).CreateShortcut('My App.lnk'); \
\$s.TargetPath='run.bat'; \$s.IconLocation='app.ico'; \$s.Save()"
# macOS: clear the quarantine attribute so the first double-click is not blocked
xattr -d com.apple.quarantine run.command 2>/dev/null || true
# Confirm the launcher script is actually executable on macOS/Linux
test -x run.command && echo "executable" || chmod +x run.command
# Confirm the port is truly free before the launcher starts (avoid a confusing failure)
lsof -i :3000 >/dev/null && echo "BUSY: stop the other instance first" || echo "free"
cds into an absolute home-directory path breaks on every other machine. Use cd "$(dirname "$0")" so it works wherever the folder lives.sleep before opening. sleep 3; open ... races startup; on a slow boot the browser hits connection-refused. Poll health instead.trap leaves the port held; the next launch fails with EADDRINUSE. Trap signals and kill on exit.set -euo pipefail.open on Linux (it does something else) or xdg-open on macOS (not present). Branch on uname or ship per-OS launchers..bat/.command. Read it from the environment or a gitignored config file.kill -- -$$)..desktop with a relative Exec. Launched from a file manager, the working directory is unpredictable, so a relative Exec=./run.sh fails. Use %k or an absolute path.Return: the launcher file(s) per target OS, the open command used, the log path, the readiness gate, the shutdown mechanism, and the cold-start verification (started → browser opened after ready → clean stop, port freed). Note any OS left uncovered and why.
$(dirname "$0")-relative paths; never hardcode another machine's home path.set -euo pipefail in bash launchers.Done means a double-click launcher exists for each target OS, it starts the process and opens the UI only after readiness, logs to the policy path without secrets, and stops cleanly with the port verified free — with any uncovered OS noted.
npx claudepluginhub fluxonlab/skillry --plugin skillry-runtime-and-local-appCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.