Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Turn ideas into validated designs and specs through collaborative dialogue before any code is written
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/stop-server.sh
1#!/usr/bin/env bash2# Stop the brainstorm server and clean up3# Usage: stop-server.sh <session_dir>4#5# Kills the server process. Only deletes session directory if it's6# under /tmp (ephemeral). Persistent directories (.superpowers/) are7# kept so mockups can be reviewed later.89SESSION_DIR="$1"1011if [[ -z "$SESSION_DIR" ]]; then12echo '{"error": "Usage: stop-server.sh <session_dir>"}'13exit 114fi1516STATE_DIR="${SESSION_DIR}/state"17PID_FILE="${STATE_DIR}/server.pid"18SERVER_ID_FILE="${STATE_DIR}/server-instance-id"1920mark_stopped() {21local reason="$1"22rm -f "${STATE_DIR}/server-info"23printf '{"reason":"%s","timestamp":%s}\n' "$reason" "$(date +%s)" > "${STATE_DIR}/server-stopped"24}2526read_expected_server_id() {27[[ -f "$SERVER_ID_FILE" ]] || return 128local id29id="$(tr -d '\r\n' < "$SERVER_ID_FILE" 2>/dev/null || true)"30[[ "$id" =~ ^[A-Za-z0-9_-]{32,64}$ ]] || return 131printf '%s\n' "$id"32}3334command_line_for_pid() {35local pid="$1"36if [[ -r "/proc/$pid/cmdline" ]]; then37tr '\0' '\n' < "/proc/$pid/cmdline" 2>/dev/null || true38return 039fi40ps -ww -p "$pid" -o command= 2>/dev/null || ps -f -p "$pid" 2>/dev/null | sed '1d' || true41}4243command_has_server_id() {44local pid="$1"45local expected="$2"46local expected_arg="--brainstorm-server-id=$expected"47if [[ -r "/proc/$pid/cmdline" ]]; then48local arg49while IFS= read -r -d '' arg || [[ -n "$arg" ]]; do50[[ "$arg" == "$expected_arg" ]] && return 051done < "/proc/$pid/cmdline"52return 153fi54local command_line55command_line="$(command_line_for_pid "$pid")"56[[ -n "$command_line" ]] || return 157case " $command_line " in58*" $expected_arg "*) return 0 ;;59*) return 1 ;;60esac61}6263# Confirm a PID has this session's per-start instance id, not just a familiar64# process name. Ambiguous or legacy metadata fails closed as stale_pid.65is_brainstorm_server() {66kill -0 "$1" 2>/dev/null || return 167local expected_id68expected_id="$(read_expected_server_id)" || return 169command_has_server_id "$1" "$expected_id" || return 170return 071}7273if [[ -f "$PID_FILE" ]]; then74pid=$(cat "$PID_FILE")7576# Refuse to signal a PID we can't prove is our server. A stale pid file may77# point at an unrelated process after a reboot/PID wraparound.78if ! is_brainstorm_server "$pid"; then79rm -f "$PID_FILE" "$SERVER_ID_FILE"80mark_stopped "stale_pid"81echo '{"status": "stale_pid"}'82exit 083fi8485# Try to stop gracefully, fallback to force if still alive86kill "$pid" 2>/dev/null || true8788# Wait for graceful shutdown (up to ~2s)89for _ in {1..20}; do90if ! kill -0 "$pid" 2>/dev/null; then91break92fi93sleep 0.194done9596# If still running, escalate to SIGKILL97if kill -0 "$pid" 2>/dev/null; then98kill -9 "$pid" 2>/dev/null || true99100# Give SIGKILL a moment to take effect101sleep 0.1102fi103104if kill -0 "$pid" 2>/dev/null; then105echo '{"status": "failed", "error": "process still running"}'106exit 1107fi108109rm -f "$PID_FILE" "$SERVER_ID_FILE" "${STATE_DIR}/server.log"110mark_stopped "stop-server.sh"111112# Only delete ephemeral /tmp directories113if [[ "$SESSION_DIR" == /tmp/* ]]; then114rm -rf "$SESSION_DIR"115fi116117echo '{"status": "stopped"}'118else119echo '{"status": "not_running"}'120fi121