How the Brainstorming Skill Integrates with External Visual Companion Servers in OpenAI Plugins
The brainstorming skill hands off visual rendering tasks to a lightweight Node.js companion server by executing shell scripts that manage the server's lifecycle, with connection details exchanged via a JSON state file in the project's .superpowers/brainstorm/ directory.
The brainstorming skill in the openai/plugins repository supports two distinct modes of operation: pure-text brainstorming within the LLM chat interface, and visual-companion mode that leverages external scripts to generate mock-ups and diagrams. This article examines how the skill orchestrates seamless integration with external processes without requiring manual code changes, using specification files and shell scripts to manage a temporary Node.js server.
Understanding the Brainstorming Skill Architecture
Located under plugins/superpowers/skills/brainstorming, the skill is designed to run in two distinct modes. In pure-text brainstorming, all interaction stays inside the LLM chat. In visual-companion mode, the skill hands off the session to a lightweight companion server that renders mock-ups, diagrams, and other visual assets. The hand-off is orchestrated entirely by the skill's specification files found in SKILL.md and visual-companion.md, requiring no manual code modifications to enable external script integration.
Step-by-Step Integration Flow
The integration follows a strict lifecycle managed through shell scripts and state files. Each step is governed by specific source files in the repository.
Step 1: User Accepts Visual Help
The skill initiates visual mode by sending a single-message offer containing the visual-companion invitation, as defined in plugins/superpowers/skills/brainstorming/SKILL.md. The user must explicitly reply "yes" to trigger the external server launch. This explicit opt-in ensures that external script execution only occurs with user consent.
Step 2: Companion Server Startup
Upon user agreement, the skill executes plugins/superpowers/skills/brainstorming/scripts/start-server.sh. This bash wrapper spawns a Node.js server (scripts/server.cjs) in the background. The script receives --project-dir (the root of the current LLM project) as a parameter, establishing the working context for the session.
Step 3: State Directory Preparation
The startup script prepares a dedicated state directory under .superpowers/brainstorm/<session-id>/ within the project root. All generated files are stored here, ensuring they survive restarts and remain scoped to the specific brainstorming session. According to plugins/superpowers/skills/brainstorming/visual-companion.md, this directory structure allows the server to maintain persistence without interfering with the host project's version control.
Step 4: Server Publishes Connection Info
On startup, the server writes a JSON blob to $STATE_DIR/server-info containing the host, port, and optional secret token. This file serves as the single source of truth for the LLM to determine how to reach the companion. The server dynamically selects an available port at runtime rather than using hard-coded values, preventing conflicts with other services.
Step 5: LLM-to-Server Communication
Subsequent brainstorming turns include HTTP GET and POST requests to the URL read from server-info. The server returns HTML frames based on plugins/superpowers/skills/brainstorming/scripts/frame-template.html, embedding mock-ups, SVG diagrams, or static images generated by downstream skills. Each request contains sufficient context (session ID, token) to enable stateless communication.
Step 6: Session Cleanup
When the user signals the end of brainstorming or the LLM transitions to the writing-plans skill, the skill executes plugins/superpowers/skills/brainstorming/scripts/stop-server.sh. This script terminates the background Node process and removes the temporary state directory, unless a persistent --project-dir was specified to retain visual assets.
Key Integration Mechanisms
The integration relies on four architectural principles that ensure reliable operation:
- Dynamic Port Allocation: The server selects an available port at runtime and publishes it via
server-info, eliminating port conflicts and manual configuration. - Project-Scoped Persistence: By passing
--project-dir, visual assets are stored in the project's.superpowers/brainstorm/folder, which should be added to.gitignoreto prevent accidental commits of generated files. - Stateless Communication: Each HTTP call contains enough context (session ID, token) for the server to serve correct assets without maintaining long-lived in-process state.
- Skill Isolation: After brainstorming, the only permitted next skill is
writing-plans; the visual companion cannot be invoked again unless a new brainstorming round starts.
Practical Implementation Examples
The following examples demonstrate how to interact with the visual companion server manually, though the skill handles these operations automatically.
Start the visual companion from the skill runner:
PROJECT_ROOT="/path/to/your/project"
scripts/start-server.sh --project-dir "$PROJECT_ROOT"
Read the server connection details (LLM-side implementation pattern):
import json
import pathlib
state_dir = pathlib.Path(".superpowers/brainstorm") / "<session-id>"
info_path = state_dir / "server-info"
with open(info_path) as f:
info = json.load(f)
base_url = f"http://{info['host']}:{info['port']}"
Request a visual asset rendering via the server's REST API:
curl -X POST "$BASE_URL/render" \
-H "Content-Type: application/json" \
-d '{"type":"mockup","data":{...}}'
Terminate the server and clean up resources:
scripts/stop-server.sh --project-dir "$PROJECT_ROOT"
Summary
- The brainstorming skill in
openai/pluginssupports visual-companion mode through automated shell script execution. scripts/start-server.shlaunches a Node.js server (scripts/server.cjs) that publishes connection details to.superpowers/brainstorm/<session-id>/server-info.- Communication occurs via stateless HTTP requests to dynamically assigned ports, with HTML frames rendered using
scripts/frame-template.html. scripts/stop-server.shhandles graceful shutdown and cleanup, whileagents/openai.yamlconfigures the LLM's decision-making during the brainstorming session.- Visual assets persist in project-scoped directories when
--project-diris specified, enabling seamless integration with external diagram and mock-up generation tools.
Frequently Asked Questions
What happens if the visual companion server crashes during a session?
If the Node.js process terminates unexpectedly, the server-info file remains in the state directory, but subsequent HTTP requests from the LLM will fail. The skill specification in SKILL.md does not currently define automatic restart behavior; the user must manually restart the session or the skill runner must re-execute scripts/start-server.sh to recreate the server process and regenerate the connection file.
Can I configure a fixed port for the visual companion server?
No, the implementation in scripts/server.cjs intentionally avoids hard-coded ports. The server binds to an available ephemeral port at runtime and publishes this information to $STATE_DIR/server-info. This design prevents port conflicts when multiple brainstorming sessions run concurrently or when other services occupy standard ports.
How do I persist visual assets between brainstorming sessions?
Pass the --project-dir argument when running scripts/start-server.sh, pointing to your project's root directory. Generated files are stored under .superpowers/brainstorm/<session-id>/ within that directory. To retain assets indefinitely, avoid running scripts/stop-server.sh with cleanup flags, or copy files from the state directory before initiating the stop script. Remember to add .superpowers/ to your .gitignore file.
Is the communication between the LLM and the visual companion server secure?
The server writes an optional secret token to the server-info JSON file alongside the host and port. Subsequent HTTP requests from the LLM should include this token in headers for authentication. However, as implemented in plugins/superpowers/skills/brainstorming, the server runs on localhost by default, minimizing exposure to external networks. For production deployments, additional reverse proxy configuration or TLS termination would be required beyond the basic start-server.sh implementation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →