SuperPowers 的 Visual Companion 是一个零依赖的本地 HTTP/WebSocket 服务器,它允许 AI 编码代理在头脑风暴过程中,将 mockup、布局选项等视觉内容实时推送到用户的浏览器,并接收用户点击选择作为结构化反馈。本文将详细解释其工作原理、启动方式、内容编写规范以及跨平台注意事项。

SuperPowers 可视化 Brainstorming Companion 使用指南:在浏览器里展示 mockup 与选项

Visual Companion 是 SuperPowers brainstorming 技能 的一个可选工具,专门用于在需要视觉比较的对话环节中展示交互式设计。它并非一个独立的“模式”,而是一个按需使用的工具,其使用与否完全取决于当前问题是否需要视觉呈现。

何时使用:判断标准

在头脑风暴流程中,决定是否使用浏览器展示内容,核心标准是一个问题:用户是看到它比读到它更容易理解吗?

使用浏览器展示的情况:

  • UI Mockups: 线框图、布局、导航结构、组件设计。
  • 架构图: 系统组件、数据流、关系图。
  • 视觉对比: 并排比较两种布局、配色方案或设计方向。
  • 设计细节: 问题涉及外观、间距、视觉层次。
  • 空间关系: 状态机、流程图、实体关系图。

使用终端(纯文本)的情况:

  • 需求与范围问题: “X代表什么功能?”、“哪些特性在范围内?”。
  • 概念性 A/B/C 选择: 用文字描述的方案选择。
  • 利弊权衡列表: 优缺点对比表格。
  • 技术决策: API 设计、数据模型、架构方案选择。
  • 澄清性问题: 答案是文字而非视觉偏好的任何问题。

一个关于 UI 的问题并不自动是视觉问题。“你想要什么样的向导流程?”是概念问题,应在终端提问。“这两个向导布局哪个感觉更好?”才是视觉问题,应使用浏览器展示。

核心工作流程

Visual Companion 的工作流是一个闭环,由服务器、浏览器和终端对话三部分组成。

graph LR
    A[启动服务器] --> B[写入 HTML 片段到屏幕目录];
    B --> C[服务器自动服务最新页面];
    C --> D[用户在浏览器查看并点击选项];
    D --> E[点击事件记录到状态目录];
    E --> F[代理在终端读取事件并整合反馈];
    F --> B;

详细步骤:

  1. 启动服务器:代理调用 start-server.sh 脚本,获取一个本地 URL 和会话目录路径(screen_dir, state_dir)。
  2. 写入内容:代理将 HTML 内容片段写入 screen_dir。服务器会自动监视该目录,并将最新文件的完整内容(注入交互脚本 helper.js)通过 HTTP 服务出来。
  3. 用户交互:用户在浏览器中打开返回的 URL,查看 mockup 并点击选项。
  4. 事件记录helper.js 脚本捕获点击事件(包含 data-choice 属性的元素),通过 WebSocket 发送给服务器。服务器将事件作为 JSON Lines 写入 $STATE_DIR/events 文件。
  5. 反馈整合:在用户的下一次终端输入后,代理会读取 $STATE_DIR/events 文件,将用户的浏览器点击数据与终端文字描述结合起来,获得完整的反馈。
  6. 循环或前进:根据反馈,代理可以迭代当前屏幕(写入新版本文件),或进入下一个问题。

安装与启动

Visual Companion 作为 SuperPowers brainstorming 技能的一部分存在。你需要确保已正确安装并加载了 SuperPowers 技能。其核心是 start-server.shstop-server.sh 脚本。

启动服务器

在头脑风暴过程中,当代理判断即将讨论的内容适合视觉展示时,它会(按 checklist 要求)单独发送一条消息,提供 Visual Companion 的使用选项。用户同意后,代理才会启动服务器。

启动命令示例:

# 推荐方式:将 mockup 文件持久化到项目目录下
scripts/start-server.sh --project-dir /path/to/your/project

命令执行后,会返回一个包含连接信息的 JSON:

{
  "type": "server-started",
  "port": 52341,
  "url": "http://localhost:52341",
  "screen_dir": "/path/to/your/project/.superpowers/brainstorm/12345-1706000000/content",
  "state_dir": "/path/to/your/project/.superpowers/brainstorm/12345-1706000000/state"
}

关键参数说明:

  • --project-dir <path>: 将会话文件存储在 <path>/.superpowers/brainstorm/ 下,而非 /tmp。这样 mockup 文件会在服务器停止后依然保留,便于后续参考。重要提示: 请务必将 .superpowers/ 目录加入 .gitignore
  • --host <bind-host>: 绑定的网络接口(默认 127.0.0.1)。在远程或容器化环境中,若浏览器无法访问,可设置为 0.0.0.0
  • --url-host <display-host>: 控制返回的 JSON 中显示的主机名(例如,当绑定 0.0.0.0 时,可设置为 localhost 或实际 IP)。
  • --foreground: 在当前终端前台运行服务器,不进行后台化。某些环境需要此选项。

各平台启动注意事项:

  • Claude Code (macOS/Linux): 默认模式即可,脚本会自动后台化。
  • Claude Code (Windows): 需要在工具调用中设置 run_in_background: true,然后读取 $STATE_DIR/server-info 获取连接信息。
  • Codex: 脚本会自动检测 CODEX_CI 环境并切换到前台模式,无需特殊标志。
  • Gemini CLI: 需要使用 --foreground 参数,并确保 shell 工具调用设置了 is_background: true
  • 其他环境: 确保服务器能在会话间保持运行。如果环境会回收分离的进程,请使用 --foreground 并配合平台的后台执行机制。

停止服务器

会话结束后,应停止服务器:

scripts/stop-server.sh $SESSION_DIR

如果会话使用了 --project-dir,mockup 文件会保留在 .superpowers/brainstorm/ 目录中。只有临时目录(/tmp)下的会话文件会被删除。

编写展示内容(HTML 片段)

代理将 HTML 内容片段写入 screen_dir 中的文件。服务器会自动将其包裹在一个完整的框架页面(frame-template.html)中,提供主题、CSS 类、选择指示栏和所有交互基础设施。因此,默认情况下只需编写内容片段

可用的 CSS 类

框架模板提供了以下 CSS 类,用于快速构建常见的展示模式:

1. 选项(A/B/C 选择)

<div class="options">
  <div class="option" data-choice="a" onclick="toggleSelect(this)">
    <div class="letter">A</div>
    <div class="content">
      <h3>单栏布局</h3>
      <p>简洁、专注的阅读体验</p>
    </div>
  </div>
  <!-- 更多选项... -->
</div>
  • 多选: 在容器上添加 data-multiselect 属性,允许用户选择多个选项。

2. 卡片(视觉设计展示)

<div class="cards">
  <div class="card" data-choice="design1" onclick="toggleSelect(this)">
    <div class="card-image"><!-- mockup 内容 --></div>
    <div class="card-body">
      <h3>设计名称</h3>
      <p>设计描述</p>
    </div>
  </div>
  <!-- 更多卡片... -->
</div>

3. Mockup 容器

<div class="mockup">
  <div class="mockup-header">预览:仪表盘布局</div>
  <div class="mockup-body"><!-- 你的 mockup HTML --></div>
</div>

4. 分屏视图(左右对比)

<div class="split">
  <div class="mockup"><!-- 左侧内容 --></div>
  <div class="mockup"><!-- 右侧内容 --></div>
</div>

5. 优缺点对比

<div class="pros-cons">
  <div class="pros"><h4>优点</h4><ul><li>好处</li></ul></div>
  <div class="cons"><h4>缺点</h4><ul><li>缺点</li></ul></div>
</div>

6. 模拟元素(线框图构建块) 包括 .mock-nav, .mock-sidebar, .mock-content, .mock-button, .mock-input, .placeholder 等类,用于快速搭建线框图。

写入流程

  1. 检查服务器状态:每次写入前,确认 $STATE_DIR/server-info 文件存在且 $STATE_DIR/server-stopped 不存在。若服务器已关闭,需重启。
  2. 使用语义文件名:例如 platform.htmllayout-v2.html切勿重用文件名,每个新屏幕都应使用新文件。
  3. 使用 Write 工具:将 HTML 片段写入文件。避免使用 cat 或 heredoc,以免将内容噪音输出到终端。
  4. 通知用户:在终端中提醒用户浏览器的 URL,并简要描述屏幕上的内容(例如:“我展示了三个主页布局选项,请在浏览器中查看。”)。

接收与整合用户反馈

浏览器事件格式

当用户在浏览器中点击带有 data-choice 属性的元素时,交互会被记录到 $STATE_DIR/events 文件中,格式为 JSON Lines:

{"type":"click","choice":"a","text":"选项 A - 简洁布局","timestamp":1706000101}
{"type":"click","choice":"c","text":"选项 C - 复杂网格","timestamp":1706000108}

事件流显示了用户的探索路径。通常,最后一个 choice 事件是最终选择,但点击模式可能揭示犹豫或偏好,值得在终端中进一步探讨。

在终端中获取反馈

在用户的下一次终端输入后,代理的处理逻辑是:

  1. 读取 $STATE_DIR/events 文件(如果存在)。
  2. 将用户的终端文字消息作为主要反馈。
  3. 将浏览器事件作为结构化的补充数据。
  4. 综合两者来理解用户的完整意图。

如果 $STATE_DIR/events 文件不存在,说明用户没有在浏览器中进行交互,此时应仅依赖终端文本。

清理与最佳实践

  • 卸载视觉内容:当后续问题不再需要浏览器时,应推送一个“等待”页面,避免用户看着已解决的选项发呆。
    <!-- 文件名:waiting.html -->
    <div style="display:flex;align-items:center;justify-content:center;min-height:60vh">
      <p class="subtitle">正在返回终端继续对话...</p>
    </div>
  • 设计保真度:根据问题调整保真度。布局问题用线框图,外观问题用精细设计。
  • 在页面上解释问题:明确说明“哪个布局感觉更专业?”而不仅仅是“选一个”。
  • 迭代优于前进:如果反馈改变了当前屏幕,就写一个新版本(如 layout-v2.html),直到当前步骤验证通过再进入下一个问题。

FAQ

Q: 服务器启动失败怎么办? A: 首先检查是否有端口冲突。start-server.sh 默认使用随机高端口,但若被占用会失败。可以尝试使用 --host 0.0.0.0--foreground 模式重试。在 Windows 环境下,确保设置了 run_in_background: true

Q: 用户在浏览器中打不开页面? A: 最常见的原因是服务器绑定在 127.0.0.1,但用户从另一台机器(或容器内)访问。此时需要在启动时使用 --host 0.0.0.0 并绑定所有接口,并使用 --url-host 指定用户可访问的主机名或 IP。

Q: 用户点击了选项,但我在终端看不到反馈? A: 确保你的代码(即 AI 代理)在读取终端消息后,也读取了 $STATE_DIR/events 文件。浏览器事件是补充数据,主要的用户沟通仍在终端进行。同时检查服务器日志 ($STATE_DIR/server.log) 是否有报错。

Q: 如何知道服务器是否还在运行? A: 检查 $STATE_DIR/server-info 文件是否存在,以及 $STATE_DIR/server-stopped 文件是否不存在。服务器在空闲 30 分钟或所有者进程退出后会自动关闭。