Blog Dashboard
Start or stop the local Flask dashboard that visualizes the blog pipeline Kanban board. The dashboard itself never runs skills directly — it just watches blog-output/ and dashboard/state.json and spawns agents via queue.json. See dashboard/README.md for the full architecture.
Resolve <plugin-root> the same way other dashboard-touching skills do: the directory containing dashboard/app.py, either the current plugin root or CLAUDE_PLUGIN_ROOT if set.
The action is the first argument (start or stop). If missing or not one of those two, ask the user which one they meant — do not guess.
start
Check if it's already running:
lsof -i :5001 -sTCP:LISTEN -tIf this returns a PID, tell the user the dashboard is already running at http://localhost:5001 and stop — do not start a second instance.
Ensure the virtualenv exists. If
<plugin-root>/dashboard/.venvis missing, create it and install deps:cd <plugin-root>/dashboard && python3 -m venv .venv && .venv/bin/pip install -r requirements.txtLaunch the app in the background, logging output and capturing its PID so
stopcan find it later. Put thecdon its own line — chaining it ascd dir && nohup ... &backgrounds the wholecd && nohuppair in a subshell, so the followingecho $!line runs in the wrong directory and writes the pidfile to the wrong place:cd <plugin-root>/dashboard nohup .venv/bin/python app.py > .dashboard.log 2>&1 & echo $! > .dashboard.pidRun this with the Bash tool's
run_in_backgroundunset (it's already detached vianohup ... &) — just run it and move on, don't block on it.Give the server a moment to bind, then confirm:
sleep 1 && lsof -i :5001 -sTCP:LISTEN -tIf a PID comes back, tell the user the dashboard is running at http://localhost:5001. If not, read the last ~20 lines of
dashboard/.dashboard.logand show the user what went wrong (commonly: missing venv deps, or missingWP_APP_PASSWORD/GEMINI_API_KEYenv vars — seedashboard/README.mdprerequisites).
stop
Find the listening process:
lsof -i :5001 -sTCP:LISTEN -tIf nothing is returned, tell the user the dashboard isn't running and stop.
Kill it:
kill $(lsof -i :5001 -sTCP:LISTEN -t)Clean up the pidfile if present:
rm -f <plugin-root>/dashboard/.dashboard.pidConfirm to the user that the dashboard has been stopped.
Notes
- Always resolve the port (5001) by checking
lsof, not just the pidfile — the pidfile can go stale if the process was killed out-of-band or the machine restarted. - Never touch
dashboard/state.json,queue.json, orblog-output/from this skill — that's/blog-dashboard-cleanup's job, and normal pipeline operation otherwise.