Revert "Move brainstorm server metadata to .meta/ subdirectory"

This reverts commit ab500dade6.
This commit is contained in:
Jesse Vincent
2026-03-24 10:58:33 -07:00
parent ab500dade6
commit ed4103ab91
6 changed files with 29 additions and 34 deletions

View File

@@ -77,7 +77,6 @@ const PORT = process.env.BRAINSTORM_PORT || (49152 + Math.floor(Math.random() *
const HOST = process.env.BRAINSTORM_HOST || '127.0.0.1';
const URL_HOST = process.env.BRAINSTORM_URL_HOST || (HOST === '127.0.0.1' ? 'localhost' : HOST);
const SCREEN_DIR = process.env.BRAINSTORM_DIR || '/tmp/brainstorm';
const META_DIR = path.join(SCREEN_DIR, '.meta');
const OWNER_PID = process.env.BRAINSTORM_OWNER_PID ? Number(process.env.BRAINSTORM_OWNER_PID) : null;
const MIME_TYPES = {
@@ -231,7 +230,7 @@ function handleMessage(text) {
touchActivity();
console.log(JSON.stringify({ source: 'user-event', ...event }));
if (event.choice) {
const eventsFile = path.join(META_DIR, '.events');
const eventsFile = path.join(SCREEN_DIR, '.events');
fs.appendFileSync(eventsFile, JSON.stringify(event) + '\n');
}
}
@@ -260,7 +259,6 @@ const debounceTimers = new Map();
function startServer() {
if (!fs.existsSync(SCREEN_DIR)) fs.mkdirSync(SCREEN_DIR, { recursive: true });
if (!fs.existsSync(META_DIR)) fs.mkdirSync(META_DIR, { recursive: true });
// Track known files to distinguish new screens from updates.
// macOS fs.watch reports 'rename' for both new files and overwrites,
@@ -285,7 +283,7 @@ function startServer() {
if (!knownFiles.has(filename)) {
knownFiles.add(filename);
const eventsFile = path.join(META_DIR, '.events');
const eventsFile = path.join(SCREEN_DIR, '.events');
if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile);
console.log(JSON.stringify({ type: 'screen-added', file: filePath }));
} else {
@@ -299,10 +297,10 @@ function startServer() {
function shutdown(reason) {
console.log(JSON.stringify({ type: 'server-stopped', reason }));
const infoFile = path.join(META_DIR, '.server-info');
const infoFile = path.join(SCREEN_DIR, '.server-info');
if (fs.existsSync(infoFile)) fs.unlinkSync(infoFile);
fs.writeFileSync(
path.join(META_DIR, '.server-stopped'),
path.join(SCREEN_DIR, '.server-stopped'),
JSON.stringify({ reason, timestamp: Date.now() }) + '\n'
);
watcher.close();
@@ -329,7 +327,7 @@ function startServer() {
screen_dir: SCREEN_DIR
});
console.log(info);
fs.writeFileSync(path.join(META_DIR, '.server-info'), info + '\n');
fs.writeFileSync(path.join(SCREEN_DIR, '.server-info'), info + '\n');
});
}

View File

@@ -83,12 +83,11 @@ else
SCREEN_DIR="/tmp/brainstorm-${SESSION_ID}"
fi
META_DIR="${SCREEN_DIR}/.meta"
PID_FILE="${META_DIR}/.server.pid"
LOG_FILE="${META_DIR}/.server.log"
PID_FILE="${SCREEN_DIR}/.server.pid"
LOG_FILE="${SCREEN_DIR}/.server.log"
# Create fresh session directory and metadata subdirectory
mkdir -p "$SCREEN_DIR" "$META_DIR"
# Create fresh session directory
mkdir -p "$SCREEN_DIR"
# Kill any existing server
if [[ -f "$PID_FILE" ]]; then

View File

@@ -13,8 +13,7 @@ if [[ -z "$SCREEN_DIR" ]]; then
exit 1
fi
META_DIR="${SCREEN_DIR}/.meta"
PID_FILE="${META_DIR}/.server.pid"
PID_FILE="${SCREEN_DIR}/.server.pid"
if [[ -f "$PID_FILE" ]]; then
pid=$(cat "$PID_FILE")
@@ -43,7 +42,7 @@ if [[ -f "$PID_FILE" ]]; then
exit 1
fi
rm -f "$PID_FILE" "${META_DIR}/.server.log"
rm -f "$PID_FILE" "${SCREEN_DIR}/.server.log"
# Only delete ephemeral /tmp directories
if [[ "$SCREEN_DIR" == /tmp/* ]]; then

View File

@@ -26,7 +26,7 @@ A question *about* a UI topic is not automatically a visual question. "What kind
## How It Works
The server watches a directory for HTML files and serves the newest one to the browser. You write HTML content, the user sees it in their browser and can click to select options. Selections are recorded to `$SCREEN_DIR/.meta/.events` that you read on your next turn.
The server watches a directory for HTML files and serves the newest one to the browser. You write HTML content, the user sees it in their browser and can click to select options. Selections are recorded to a `.events` file that you read on your next turn.
**Content fragments vs full documents:** If your HTML file starts with `<!DOCTYPE` or `<html`, the server serves it as-is (just injects the helper script). Otherwise, the server automatically wraps your content in the frame template — adding the header, CSS theme, selection indicator, and all interactive infrastructure. **Write content fragments by default.** Only write full documents when you need complete control over the page.
@@ -42,7 +42,7 @@ scripts/start-server.sh --project-dir /path/to/project
Save `screen_dir` from the response. Tell user to open the URL.
**Finding connection info:** The server writes its startup JSON to `$SCREEN_DIR/.meta/.server-info`. If you launched the server in the background and didn't capture stdout, read that file to get the URL and port. When using `--project-dir`, check `<project>/.superpowers/brainstorm/` for the session directory.
**Finding connection info:** The server writes its startup JSON to `$SCREEN_DIR/.server-info`. If you launched the server in the background and didn't capture stdout, read that file to get the URL and port. When using `--project-dir`, check `<project>/.superpowers/brainstorm/` for the session directory.
**Note:** Pass the project root as `--project-dir` so mockups persist in `.superpowers/brainstorm/` and survive server restarts. Without it, files go to `/tmp` and get cleaned up. Remind the user to add `.superpowers/` to `.gitignore` if it's not already there.
@@ -61,7 +61,7 @@ scripts/start-server.sh --project-dir /path/to/project
# across conversation turns.
scripts/start-server.sh --project-dir /path/to/project
```
When calling this via the Bash tool, set `run_in_background: true`. Then read `$SCREEN_DIR/.meta/.server-info` on the next turn to get the URL and port.
When calling this via the Bash tool, set `run_in_background: true`. Then read `$SCREEN_DIR/.server-info` on the next turn to get the URL and port.
**Codex:**
```bash
@@ -93,7 +93,7 @@ Use `--url-host` to control what hostname is printed in the returned URL JSON.
## The Loop
1. **Check server is alive**, then **write HTML** to a new file in `screen_dir`:
- Before each write, check that `$SCREEN_DIR/.meta/.server-info` exists. If it doesn't (or `.meta/.server-stopped` exists), the server has shut down — restart it with `start-server.sh` before continuing. The server auto-exits after 30 minutes of inactivity.
- Before each write, check that `$SCREEN_DIR/.server-info` exists. If it doesn't (or `.server-stopped` exists), the server has shut down — restart it with `start-server.sh` before continuing. The server auto-exits after 30 minutes of inactivity.
- Use semantic filenames: `platform.html`, `visual-style.html`, `layout.html`
- **Never reuse filenames** — each screen gets a fresh file
- Use Write tool — **never use cat/heredoc** (dumps noise into terminal)
@@ -105,9 +105,9 @@ Use `--url-host` to control what hostname is printed in the returned URL JSON.
- Ask them to respond in the terminal: "Take a look and let me know what you think. Click to select an option if you'd like."
3. **On your next turn** — after the user responds in the terminal:
- Read `$SCREEN_DIR/.meta/.events` if it exists — this contains the user's browser interactions (clicks, selections) as JSON lines
- Read `$SCREEN_DIR/.events` if it exists — this contains the user's browser interactions (clicks, selections) as JSON lines
- Merge with the user's terminal text to get the full picture
- The terminal message is the primary feedback; `.meta/.events` provides structured interaction data
- The terminal message is the primary feedback; `.events` provides structured interaction data
4. **Iterate or advance** — if feedback changes current screen, write a new file (e.g., `layout-v2.html`). Only move to the next question when the current step is validated.
@@ -244,7 +244,7 @@ The frame template provides these CSS classes for your content:
## Browser Events Format
When the user clicks options in the browser, their interactions are recorded to `$SCREEN_DIR/.meta/.events` (one JSON object per line). The file is cleared automatically when you push a new screen.
When the user clicks options in the browser, their interactions are recorded to `$SCREEN_DIR/.events` (one JSON object per line). The file is cleared automatically when you push a new screen.
```jsonl
{"type":"click","choice":"a","text":"Option A - Simple Layout","timestamp":1706000101}
@@ -254,7 +254,7 @@ When the user clicks options in the browser, their interactions are recorded to
The full event stream shows the user's exploration path — they may click multiple options before settling. The last `choice` event is typically the final selection, but the pattern of clicks can reveal hesitation or preferences worth asking about.
If `.meta/.events` doesn't exist, the user didn't interact with the browser — use only their terminal text.
If `.events` doesn't exist, the user didn't interact with the browser — use only their terminal text.
## Design Tips