Przeglądaj źródła

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"
Jesse Vincent 7 miesięcy temu
rodzic
commit
b98afbd74f

+ 13 - 6
lib/brainstorm-server/CLAUDE-INSTRUCTIONS.md

@@ -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

+ 7 - 1
lib/brainstorm-server/index.js

@@ -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
+  }));
 });

+ 7 - 3
lib/brainstorm-server/start-server.sh

@@ -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"
 

+ 11 - 4
lib/brainstorm-server/stop-server.sh

@@ -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"}'

+ 23 - 12
skills/brainstorming/SKILL.md

@@ -68,17 +68,22 @@ Only proceed with visual companion if they agree. Otherwise, describe options in
 ### Starting the Visual Companion
 
 ```bash
-# Start server (outputs JSON with URL)
+# Start server (creates unique session directory)
 ${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/start-server.sh
 
-# Output looks like: {"type":"server-started","port":52341,"url":"http://localhost:52341"}
+# Output looks like:
+# {"type":"server-started","port":52341,"url":"http://localhost:52341",
+#  "screen_dir":"/tmp/brainstorm-12345-1234567890",
+#  "screen_file":"/tmp/brainstorm-12345-1234567890/screen.html"}
 ```
 
+**Save the `screen_dir` and `screen_file` paths from the response** - you'll need them throughout the session.
+
 Tell the user to open the URL in their browser.
 
 ### Showing Content
 
-Write complete HTML to `/tmp/brainstorm/screen.html`. The browser auto-refreshes.
+Write complete HTML to the session's `screen_file` path. The browser auto-refreshes.
 
 Use the frame template structure from `${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/frame-template.html`:
 - Keep the header and feedback-footer intact
@@ -89,31 +94,37 @@ See `${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/CLAUDE-INSTRUCTIONS.md` for det
 
 ### Waiting for User Feedback
 
-Run the watcher as a background bash command:
+Start the watcher as a background bash command, then use TaskOutput with block=true to wait:
 
 ```bash
-${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-event.sh /tmp/brainstorm/.server.log
+# 1. Start watcher in background
+${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-event.sh $SCREEN_DIR/.server.log
+
+# 2. Call TaskOutput(task_id, block=true, timeout=600000) to wait
+# 3. If timeout, call TaskOutput again (watcher is still running)
+# 4. After 3 timeouts (30 min), say "Let me know when you want to continue" and stop looping
 ```
 
-When the user clicks Send in the browser, the watcher exits and you receive their feedback as JSON:
+When the user clicks Send in the browser, the watcher exits and TaskOutput returns with feedback:
 ```json
 {"choice": "a", "feedback": "I like this but make the header smaller"}
 ```
 
 ### The Loop
 
-1. Write screen HTML
+1. Write screen HTML to `screen_file`
 2. Start watcher (background bash)
-3. Watcher completes when user sends feedback
-4. Read feedback, respond with new screen
-5. Repeat until done
+3. Call TaskOutput(task_id, block=true) to wait
+4. TaskOutput returns with feedback
+5. Respond with new screen
+6. Repeat until done
 
 ### Cleaning Up
 
-When the visual brainstorming session is complete:
+When the visual brainstorming session is complete, pass the screen_dir to stop:
 
 ```bash
-${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh
+${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh $SCREEN_DIR
 ```
 
 ### Tips

+ 18 - 16
skills/brainstorming/visual-companion.md

@@ -6,32 +6,34 @@ Quick reference for using the visual brainstorming companion.
 
 | File | Purpose |
 |------|---------|
-| `lib/brainstorm-server/start-server.sh` | Start server, outputs JSON with URL |
-| `lib/brainstorm-server/stop-server.sh` | Stop server and clean up |
+| `lib/brainstorm-server/start-server.sh` | Start server, outputs JSON with URL and session paths |
+| `lib/brainstorm-server/stop-server.sh` | Stop server and clean up session directory |
 | `lib/brainstorm-server/wait-for-event.sh` | Wait for user feedback |
 | `lib/brainstorm-server/frame-template.html` | Base HTML template with CSS |
 | `lib/brainstorm-server/CLAUDE-INSTRUCTIONS.md` | Detailed usage guide |
-| `/tmp/brainstorm/screen.html` | Write your screens here |
-| `/tmp/brainstorm/.server.log` | Server output (for watcher) |
 
 ## Quick Start
 
 ```bash
-# 1. Start server
+# 1. Start server (creates unique session directory)
 ${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/start-server.sh
-# Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341"}
-
-# 2. Write screen
-# Write HTML to /tmp/brainstorm/screen.html
-
-# 3. Wait for feedback (background)
-${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-event.sh /tmp/brainstorm/.server.log
-
-# 4. Read watcher output when it completes
+# Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341",
+#           "screen_dir":"/tmp/brainstorm-12345-1234567890",
+#           "screen_file":"/tmp/brainstorm-12345-1234567890/screen.html"}
+
+# 2. Write screen to the session's screen_file
+# Use Bash with heredoc to write HTML
+
+# 3. Wait for feedback using TaskOutput with block=true
+# Start watcher in background:
+${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-event.sh $SCREEN_DIR/.server.log
+# Then call TaskOutput(task_id, block=true, timeout=600000) to wait
+# If timeout, call TaskOutput again (watcher still running)
+# After 3 timeouts (30 min), say "Let me know when you want to continue"
 # Returns: {"choice":"a","feedback":"user notes"}
 
-# 5. Clean up when done
-${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh
+# 4. Clean up when done (pass screen_dir as argument)
+${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh $SCREEN_DIR
 ```
 
 ## CSS Classes