brainstorm-companion 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -68,10 +68,9 @@ brainstorm-companion stop
68
68
  ```
69
69
 
70
70
  **Key behaviors:**
71
- - `start` with no args works immediately (stores in `/tmp/brainstorm-companion/`)
71
+ - `start` with no args works immediately auto-isolates by working directory
72
72
  - `start` reuses an existing session — never opens duplicate browsers
73
73
  - `push` auto-reloads the browser every time — no restart or refresh needed
74
- - Add `--project-dir .` for project-local storage
75
74
 
76
75
  ### Quick Start (MCP / Agent) — 3 calls, zero config
77
76
 
@@ -90,7 +89,7 @@ brainstorm-companion stop
90
89
  5. brainstorm_stop_session({})
91
90
  ```
92
91
 
93
- **No arguments required.** `brainstorm_start_session()` works with zero config. Pass `project_dir` for project-local storage or when multiple agents run simultaneously. Sessions persist until `brainstorm_stop_session()` — use `idle_timeout_minutes` for auto-cleanup.
92
+ **No arguments required.** Sessions auto-isolate by working directory different projects never collide. Sessions persist until `brainstorm_stop_session()` — use `idle_timeout_minutes` for auto-cleanup.
94
93
 
95
94
  ---
96
95
 
@@ -231,7 +230,7 @@ graph TD
231
230
 
232
231
  | Tool | Description |
233
232
  |------|-------------|
234
- | `brainstorm_start_session` | Start server (or reuse existing). Returns URL. Always pass `project_dir`. |
233
+ | `brainstorm_start_session` | Start server (or reuse existing). No args needed. Returns URL. |
235
234
  | `brainstorm_push_screen` | Push HTML content. Browser auto-reloads. Use `slot` + `label` for comparison. |
236
235
  | `brainstorm_read_events` | Read user interaction events. Option to clear after reading. |
237
236
  | `brainstorm_clear_screen` | Clear a specific slot or all content. |
@@ -244,7 +243,7 @@ graph TD
244
243
  ### Single Decision
245
244
 
246
245
  ```
247
- 1. brainstorm_start_session({ project_dir: "..." })
246
+ 1. brainstorm_start_session()
248
247
  2. brainstorm_push_screen({ html: "...options with data-choice..." })
249
248
  3. → Tell user to make their selection in the browser
250
249
  4. brainstorm_read_events({})
@@ -255,7 +254,7 @@ graph TD
255
254
  ### A/B/C Comparison
256
255
 
257
256
  ```
258
- 1. brainstorm_start_session({ project_dir: "..." })
257
+ 1. brainstorm_start_session()
259
258
  2. brainstorm_push_screen({ html: "...", slot: "a", label: "Option A" })
260
259
  3. brainstorm_push_screen({ html: "...", slot: "b", label: "Option B" })
261
260
  4. → Tell user to compare and pick a preference
@@ -267,7 +266,7 @@ graph TD
267
266
  ### Multi-Round Brainstorming
268
267
 
269
268
  ```
270
- 1. brainstorm_start_session({ project_dir: "..." })
269
+ 1. brainstorm_start_session()
271
270
 
272
271
  // Round 1: Layout
273
272
  2. brainstorm_push_screen({ html: "...", slot: "a", label: "Grid" })
@@ -290,7 +289,7 @@ graph TD
290
289
  ### Progressive Refinement
291
290
 
292
291
  ```
293
- 1. brainstorm_start_session({ project_dir: "..." })
292
+ 1. brainstorm_start_session()
294
293
 
295
294
  // Show initial mockup
296
295
  2. brainstorm_push_screen({ html: "...v1 mockup..." })
@@ -383,26 +382,25 @@ Shows Session ID, URL, uptime, event count, and active slots.
383
382
 
384
383
  ## Best Practices
385
384
 
386
- 1. **Always pass `project_dir`** to `brainstorm_start_session` avoids cross-agent conflicts
387
- 2. **Never restart to update content** — just call `brainstorm_push_screen` again; the browser auto-reloads
388
- 3. **One `brainstorm_start_session` per workflow** — it reuses the existing session automatically
389
- 4. **Push fragments, not full documents** — the frame template handles `<html>`, theming, and scroll
390
- 5. **Start with a heading** — `<h2>` describes what the user is looking at
391
- 6. **Add a `.subtitle`** — describes the decision being made
392
- 7. **One decision per screen** — don't combine unrelated choices
393
- 8. **Use slot labels** — `label` makes comparison tabs readable
394
- 9. **Use `data-choice` for interaction** — the built-in `toggleSelect` emits events automatically
395
- 10. **Tell the user to interact** — after pushing content, let them know the browser is ready
396
- 11. **Read events after user has time** — don't immediately read; wait for user to respond
397
- 12. **Clean up with `brainstorm_stop_session`**frees the port and removes temp files
385
+ 1. **Zero config** `brainstorm_start_session()` and `brainstorm-companion start` work with no arguments; sessions auto-isolate by working directory
386
+ 3. **Never restart to update content** — just call `push_screen` / `push` again; the browser auto-reloads
387
+ 4. **One start per workflow** — `start` reuses the existing session automatically
388
+ 5. **Push fragments, not full documents** — the frame template handles `<html>`, theming, and scroll
389
+ 6. **Start with a heading** — `<h2>` describes what the user is looking at
390
+ 7. **Add a `.subtitle`** — describes the decision being made
391
+ 8. **One decision per screen** — don't combine unrelated choices
392
+ 9. **Use slot labels** — `label` makes comparison tabs readable
393
+ 10. **Use `data-choice` for interaction** — the built-in `toggleSelect` emits events automatically
394
+ 11. **Tell the user to interact** — after pushing content, let them know the browser is ready
395
+ 12. **Read events after user has time** — don't immediately read; wait for user to respond
396
+ 13. **Use `--timeout <min>` for auto-cleanup** or call `stop` / `brainstorm_stop_session` when done
398
397
 
399
398
  ## Common Mistakes
400
399
 
401
400
  - **Starting a new session for each update** — DON'T. Call `push_screen` to update the existing browser.
402
- - **Omitting `project_dir`** — leads to `/tmp` collisions between agents.
403
401
  - **Pushing full HTML documents** — push fragments; the frame template adds theming and structure.
404
402
  - **Reading events immediately after push** — give the user time to interact first.
405
- - **Forgetting to stop** — always call `brainstorm_stop_session` when done.
403
+ - **Forgetting to stop** — always call `brainstorm_stop_session` / `stop` when done, or use `--timeout`.
406
404
 
407
405
  ## Author
408
406
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainstorm-companion",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "AI-assisted visual brainstorming companion",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
package/skill/SKILL.md CHANGED
@@ -53,7 +53,7 @@ brainstorm_start_session({
53
53
  })
54
54
  ```
55
55
 
56
- **`project_dir` is optional.** Without it, sessions go to `/tmp/brainstorm-companion/`. Pass the current working directory for project-local storage or when multiple agents may run simultaneously.
56
+ **No arguments required.** Sessions are auto-isolated by working directory different projects never collide, even without `project_dir`. Pass `project_dir` only if you want session files stored inside the project folder.
57
57
 
58
58
  **Calling it multiple times is safe** — returns the existing session. Just call `brainstorm_push_screen` to update content.
59
59
 
@@ -344,7 +344,7 @@ All events include a `timestamp` field (Unix ms).
344
344
  ### Single Decision
345
345
 
346
346
  ```
347
- 1. brainstorm_start_session({ project_dir: "..." })
347
+ 1. brainstorm_start_session()
348
348
  2. brainstorm_push_screen({ html: "...options with data-choice..." })
349
349
  3. → Tell user to make their selection in the browser
350
350
  4. brainstorm_read_events({})
@@ -355,7 +355,7 @@ All events include a `timestamp` field (Unix ms).
355
355
  ### A/B/C Comparison
356
356
 
357
357
  ```
358
- 1. brainstorm_start_session({ project_dir: "..." })
358
+ 1. brainstorm_start_session()
359
359
  2. brainstorm_push_screen({ html: "...", slot: "a", label: "Option A" })
360
360
  3. brainstorm_push_screen({ html: "...", slot: "b", label: "Option B" })
361
361
  4. → Tell user to compare and pick a preference
@@ -367,7 +367,7 @@ All events include a `timestamp` field (Unix ms).
367
367
  ### Multi-Round Brainstorming
368
368
 
369
369
  ```
370
- 1. brainstorm_start_session({ project_dir: "..." })
370
+ 1. brainstorm_start_session()
371
371
 
372
372
  // Round 1: Layout
373
373
  2. brainstorm_push_screen({ html: "...", slot: "a", label: "Grid" })
@@ -390,7 +390,7 @@ All events include a `timestamp` field (Unix ms).
390
390
  ### Progressive Refinement
391
391
 
392
392
  ```
393
- 1. brainstorm_start_session({ project_dir: "..." })
393
+ 1. brainstorm_start_session()
394
394
 
395
395
  // Show initial mockup
396
396
  2. brainstorm_push_screen({ html: "...v1 mockup..." })
@@ -407,23 +407,22 @@ All events include a `timestamp` field (Unix ms).
407
407
 
408
408
  ## Best Practices
409
409
 
410
- 1. **Always pass `project_dir`** to `brainstorm_start_session` avoids cross-agent conflicts
411
- 2. **Never restart to update content** — just call `brainstorm_push_screen` again; the browser auto-reloads
412
- 3. **One `brainstorm_start_session` per workflow** — it reuses the existing session automatically
413
- 4. **Push fragments, not full documents** — the frame template handles `<html>`, theming, and scroll
414
- 5. **Start with a heading** — `<h2>` describes what the user is looking at
415
- 6. **Add a `.subtitle`** — describes the decision being made
416
- 7. **One decision per screen** — don't combine unrelated choices
417
- 8. **Use slot labels** — `label` makes comparison tabs readable
418
- 9. **Use `data-choice` for interaction** — the built-in `toggleSelect` emits events automatically
419
- 10. **Tell the user to interact** — after pushing content, let them know the browser is ready
420
- 11. **Read events after user has time** — don't immediately read; wait for user to respond
421
- 12. **Clean up with `brainstorm_stop_session`** — frees the port and removes temp files
410
+ 1. **Zero config** `brainstorm_start_session()` works with no arguments; isolation is automatic
411
+ 3. **Never restart to update content** — just call `brainstorm_push_screen` again; the browser auto-reloads
412
+ 4. **One `brainstorm_start_session` per workflow** — it reuses the existing session automatically
413
+ 5. **Push fragments, not full documents** — the frame template handles `<html>`, theming, and scroll
414
+ 6. **Start with a heading** — `<h2>` describes what the user is looking at
415
+ 7. **Add a `.subtitle`** — describes the decision being made
416
+ 8. **One decision per screen** — don't combine unrelated choices
417
+ 9. **Use slot labels** — `label` makes comparison tabs readable
418
+ 10. **Use `data-choice` for interaction** — the built-in `toggleSelect` emits events automatically
419
+ 11. **Tell the user to interact** — after pushing content, let them know the browser is ready
420
+ 12. **Read events after user has time** — don't immediately read; wait for user to respond
421
+ 13. **Clean up with `brainstorm_stop_session`** — or use `idle_timeout_minutes` for auto-cleanup
422
422
 
423
423
  ## Common Mistakes
424
424
 
425
425
  - **Starting a new session for each update** — DON'T. Call `push_screen` to update the existing browser.
426
- - **Omitting `project_dir`** — leads to `/tmp` collisions between agents.
427
426
  - **Pushing full HTML documents** — push fragments; the frame template adds theming and structure.
428
427
  - **Reading events immediately after push** — give the user time to interact first.
429
- - **Forgetting to stop** — always call `brainstorm_stop_session` when done.
428
+ - **Forgetting to stop** — always call `brainstorm_stop_session` when done, or use `idle_timeout_minutes`.
@@ -152,9 +152,9 @@ brainstorm_read_events()
152
152
  When running multi-round comparisons, clear events between rounds to avoid stale data:
153
153
 
154
154
  ```
155
- brainstorm_read_events() // read current events
156
- brainstorm_clear_screen({ target: "events" }) // clear event queue
157
- brainstorm_push_screen({ html: "Round 2..." }) // push next round
155
+ brainstorm_read_events({ clear_after_read: true }) // read and clear in one call
156
+ brainstorm_clear_screen({}) // clear content for next round
157
+ brainstorm_push_screen({ html: "Round 2..." }) // push next round
158
158
  ```
159
159
 
160
160
  ### Interpreting Events
@@ -250,10 +250,10 @@ stateDiagram-v2
250
250
 
251
251
  This example shows a full workflow for choosing a navigation pattern for a new app.
252
252
 
253
- ### Step 1: Present the question
253
+ ### Step 1: Start session and present the question
254
254
 
255
255
  ```
256
- brainstorm_start_session()
256
+ brainstorm_start_session() // no args needed — opens browser automatically
257
257
 
258
258
  brainstorm_push_screen({
259
259
  html: `
package/src/cli.js CHANGED
@@ -185,6 +185,18 @@ function printHelp(command) {
185
185
  // Helpers
186
186
  // ---------------------------------------------------------------------------
187
187
 
188
+ function printNextSteps() {
189
+ console.log(`
190
+ Next steps:
191
+ brainstorm-companion push --html '<h2>Your content</h2>' Push content to browser
192
+ brainstorm-companion push file.html --slot a --label "A" Comparison mode
193
+ brainstorm-companion events Read user interactions
194
+ brainstorm-companion stop Stop when done
195
+
196
+ Full docs: https://www.npmjs.com/package/brainstorm-companion
197
+ Run: brainstorm-companion push --help for all CSS classes and options`);
198
+ }
199
+
188
200
  function sleep(ms) {
189
201
  return new Promise(resolve => setTimeout(resolve, ms));
190
202
  }
@@ -272,6 +284,7 @@ async function start(argv) {
272
284
  const url = existing.serverInfo.url;
273
285
  console.log(`Server already running: ${url}`);
274
286
  console.log(`Session ID: ${existing.sessionId}`);
287
+ printNextSteps();
275
288
  if (!noOpen) {
276
289
  openBrowser(url);
277
290
  }
@@ -294,6 +307,7 @@ async function start(argv) {
294
307
  instance.server.once('listening', () => {
295
308
  console.log(`Server started: ${instance.url}`);
296
309
  console.log(`Session ID: ${path.basename(sessionDir)}`);
310
+ printNextSteps();
297
311
  if (!noOpen) {
298
312
  openBrowser(instance.url);
299
313
  }
@@ -338,6 +352,7 @@ async function start(argv) {
338
352
 
339
353
  console.log(`Server started: ${serverInfo.url}`);
340
354
  console.log(`Session ID: ${path.basename(sessionDir)}`);
355
+ printNextSteps();
341
356
 
342
357
  if (!noOpen) {
343
358
  openBrowser(serverInfo.url);
package/src/mcp.js CHANGED
@@ -1,10 +1,15 @@
1
1
  'use strict';
2
2
 
3
+ const crypto = require('node:crypto');
3
4
  const fs = require('node:fs');
4
5
  const path = require('node:path');
5
6
  const { exec } = require('node:child_process');
6
7
  const { startServer } = require('./server');
7
8
 
9
+ function cwdHash() {
10
+ return crypto.createHash('md5').update(process.cwd()).digest('hex').slice(0, 8);
11
+ }
12
+
8
13
  class McpServer {
9
14
  constructor() {
10
15
  this.sessionDir = null; // absolute path once session is started
@@ -170,7 +175,7 @@ RULES:
170
175
  inputSchema: {
171
176
  type: 'object',
172
177
  properties: {
173
- project_dir: { type: 'string', description: 'Project directory for session storage. Optional — defaults to /tmp/brainstorm-companion/. Pass cwd for project-local storage.' },
178
+ project_dir: { type: 'string', description: 'Optional. Stores session files under <dir>/.superpowers/brainstorm/. If omitted, auto-isolates by working directory.' },
174
179
  port: { type: 'number', description: 'Port to bind to (default: random ephemeral)' },
175
180
  open_browser: { type: 'boolean', description: 'Open browser automatically (default: true)' },
176
181
  idle_timeout_minutes: { type: 'number', description: 'Auto-stop after N minutes idle (default: 0 = no timeout)' }
@@ -247,7 +252,7 @@ Give the user time to interact before reading — don't read immediately after p
247
252
  // Determine base directory and create session dir
248
253
  const baseDir = project_dir
249
254
  ? path.join(project_dir, '.superpowers', 'brainstorm')
250
- : '/tmp/brainstorm-companion';
255
+ : path.join('/tmp', 'brainstorm-companion', cwdHash());
251
256
  const sessionId = `${process.pid}-${Date.now()}`;
252
257
  const sessionDir = path.join(baseDir, sessionId);
253
258
  fs.mkdirSync(sessionDir, { recursive: true });
package/src/session.js CHANGED
@@ -1,13 +1,18 @@
1
1
  'use strict';
2
2
 
3
+ const crypto = require('node:crypto');
3
4
  const fs = require('node:fs');
4
5
  const path = require('node:path');
5
6
 
7
+ function cwdHash() {
8
+ return crypto.createHash('md5').update(process.cwd()).digest('hex').slice(0, 8);
9
+ }
10
+
6
11
  class SessionManager {
7
12
  constructor(projectDir, targetSessionId) {
8
13
  this.baseDir = projectDir
9
- ? `${projectDir}/.superpowers/brainstorm/`
10
- : `/tmp/brainstorm-companion/`;
14
+ ? path.join(projectDir, '.superpowers', 'brainstorm')
15
+ : path.join('/tmp', 'brainstorm-companion', cwdHash());
11
16
  this.targetSessionId = targetSessionId || null;
12
17
  }
13
18