fix: session isolation and blocking wait for visual companion

- Each session gets unique temp directory (/tmp/brainstorm-{pid}-{timestamp})
- Server outputs screen_dir and screen_file in startup JSON
- stop-server.sh takes screen_dir arg and cleans up session directory
- Document blocking TaskOutput pattern: 10-min timeouts, retry up to 3x,
  then prompt user "let me know when you want to continue"
This commit is contained in:
Jesse Vincent
2026-01-17 17:25:45 -08:00
parent 2a61167b02
commit b98afbd74f
6 changed files with 77 additions and 40 deletions

View File

@@ -15,18 +15,25 @@ Use the visual companion when you need to show:
## Lifecycle
```bash
# Start server (returns JSON with URL)
# Start server (returns JSON with URL and session paths)
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/start-server.sh
# Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341",
# "screen_dir":"/tmp/brainstorm-12345-1234567890",
# "screen_file":"/tmp/brainstorm-12345-1234567890/screen.html"}
# Save screen_dir and screen_file from response!
# Tell user to open the URL in their browser
# Write screens to /tmp/brainstorm/screen.html (auto-refreshes)
# Write screens to screen_file (auto-refreshes)
# Wait for user feedback
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-event.sh /path/to/server.log
# Wait for user feedback:
# 1. Start watcher in background
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-event.sh $SCREEN_DIR/.server.log
# 2. Immediately call TaskOutput(task_id, block=true) to wait for completion
# When done, stop server
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh
# When done, stop server (pass screen_dir)
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh $SCREEN_DIR
```
## Writing Screens

View File

@@ -81,5 +81,11 @@ chokidar.watch(SCREEN_FILE).on('change', () => {
});
server.listen(PORT, '127.0.0.1', () => {
console.log(JSON.stringify({ type: 'server-started', port: PORT, url: `http://localhost:${PORT}` }));
console.log(JSON.stringify({
type: 'server-started',
port: PORT,
url: `http://localhost:${PORT}`,
screen_dir: SCREEN_DIR,
screen_file: SCREEN_FILE
}));
});

View File

@@ -3,15 +3,19 @@
# Usage: start-server.sh
#
# Starts server on a random high port, outputs JSON with URL
# Each session gets its own temp directory to avoid conflicts
# Server runs in background, PID saved for cleanup
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SCREEN_DIR="${BRAINSTORM_SCREEN_DIR:-/tmp/brainstorm}"
# Generate unique session directory
SESSION_ID="$$-$(date +%s)"
SCREEN_DIR="/tmp/brainstorm-${SESSION_ID}"
SCREEN_FILE="${SCREEN_DIR}/screen.html"
PID_FILE="${SCREEN_DIR}/.server.pid"
LOG_FILE="${SCREEN_DIR}/.server.log"
# Ensure screen directory exists
# Create fresh session directory
mkdir -p "$SCREEN_DIR"
# Kill any existing server
@@ -23,7 +27,7 @@ fi
# Start server, capturing output to log file
cd "$SCRIPT_DIR"
node index.js > "$LOG_FILE" 2>&1 &
BRAINSTORM_SCREEN="$SCREEN_FILE" node index.js > "$LOG_FILE" 2>&1 &
SERVER_PID=$!
echo "$SERVER_PID" > "$PID_FILE"

View File

@@ -1,14 +1,21 @@
#!/bin/bash
# Stop the brainstorm server and clean up
# Usage: stop-server.sh
# Stop the brainstorm server and clean up session directory
# Usage: stop-server.sh <screen_dir>
SCREEN_DIR="$1"
if [[ -z "$SCREEN_DIR" ]]; then
echo '{"error": "Usage: stop-server.sh <screen_dir>"}'
exit 1
fi
SCREEN_DIR="${BRAINSTORM_SCREEN_DIR:-/tmp/brainstorm}"
PID_FILE="${SCREEN_DIR}/.server.pid"
if [[ -f "$PID_FILE" ]]; then
pid=$(cat "$PID_FILE")
kill "$pid" 2>/dev/null
rm -f "$PID_FILE"
# Clean up session directory
rm -rf "$SCREEN_DIR"
echo '{"status": "stopped"}'
else
echo '{"status": "not_running"}'