Superpowers 可视化头脑风暴伴侣:从实施计划到零依赖本地服务器的完整实现解析
Superpowers 可视化头脑风暴伴侣从实施计划到零依赖本地服务器的完整实现解析【免费下载链接】superpowersAn agentic skills framework software development methodology that works.项目地址: https://gitcode.com/GitHub_Trending/su/superpowers本文以 Superpowers 仓库中的实施计划 2026-01-17-visual-brainstorming.md 为主线解析可视化头脑风暴伴侣Visual Brainstorming Companion的设计目标、架构与任务拆解一个本地 Node.js 服务器监视 HTML 文件变更并向浏览器推送界面用户的点击、表单与输入通过 WebSocket 回流到服务器标准输出供 Claude或其他编码 Agent在下一轮对话中读取。读完本文你将掌握该功能的完整数据流、服务端与客户端关键代码、测试验证方式以及当前仓库中该方案演进的零依赖实现细节。目标与总体架构计划文档开篇明确了三个核心要素Goal为 Claude 的头脑风暴会话提供一个基于浏览器的视觉伴侣——在终端对话旁边展示 mockup、原型和交互式选项ArchitectureClaude 把 HTML 写入临时文件一个本地 Node.js 服务器监视该文件并附带自动注入的 helper 库提供服务用户的交互通过 WebSocket 流向服务器 stdoutClaude 在后台任务输出中看到这些事件Tech StackNode.js、Express、wsWebSocket、chokidar文件监视。用数据流描述就是Agent 写 HTML 文件 ── chokidar 检测到变更 ── 向所有浏览器推送 reload 浏览器展示最新 HTMLhelper.js 已注入 用户点击/提交/输入 ── helper.js 自动捕获 ── WebSocket ── 服务器 stdout 输出 JSON 事件 Agent 读取后台任务输出 ── 获得结构化的用户反馈终端始终是主对话界面浏览器只是视觉辅助The terminal remains the primary conversation interface. The browser is a visual aid.。Task 1服务器基础Server Foundation计划中的第一个任务创建lib/brainstorm-server/含package.json与index.js。package.json声明了三个依赖{ name: brainstorm-server, version: 1.0.0, description: Visual brainstorming companion server for Claude Code, main: index.js, dependencies: { chokidar: ^3.5.3, express: ^4.18.2, ws: ^8.14.2 } }最小可运行的index.js实现了五件关键事情每一处都值得展开1. 环境变量驱动的端口与屏幕文件const PORT process.env.BRAINSTORM_PORT || 3333; const SCREEN_FILE process.env.BRAINSTORM_SCREEN || /tmp/brainstorm/screen.html; const SCREEN_DIR path.dirname(SCREEN_FILE);端口默认 3333被监视的屏幕文件默认/tmp/brainstorm/screen.html。服务器启动时会自动创建目录并写入一个等待中默认页面Waiting for Claude to push a screen...。2. WebSocket 客户端集合与事件转发const clients new Set(); wss.on(connection, (ws) { clients.add(ws); ws.on(close, () clients.delete(ws)); ws.on(message, (data) { // User interaction event - write to stdout for Claude const event JSON.parse(data.toString()); console.log(JSON.stringify({ type: user-event, ...event })); }); });注意事件被包裹为{ type: user-event, ...event }后写到 stdout——这是 Agent 消费用户反馈的唯一通道。3. 页面路由与 helper 注入app.get(/, (req, res) { let html fs.readFileSync(SCREEN_FILE, utf-8); const helperScript fs.readFileSync(path.join(__dirname, helper.js), utf-8); const injection script\n${helperScript}\n/script; if (html.includes(/body)) { html html.replace(/body, ${injection}\n/body); } else { html injection; } res.type(html).send(html); });每次请求都重新读取屏幕文件并在/body前注入 helper 脚本——Agent 无需在 HTML 中写任何交互代码。4. 文件变更监视与浏览器刷新chokidar.watch(SCREEN_FILE).on(change, () { console.log(JSON.stringify({ type: screen-updated, file: SCREEN_FILE })); clients.forEach(ws { if (ws.readyState WebSocket.OPEN) { ws.send(JSON.stringify({ type: reload })); } }); });5. 绑定回环地址并输出结构化启动信息server.listen(PORT, 127.0.0.1, () { console.log(JSON.stringify({ type: server-started, port: PORT, url: http://localhost:${PORT} })); });服务器只绑定127.0.0.1所有 stdout 输出都是单行 JSONserver-started/screen-updated/user-event让 Agent 可以可靠地解析。计划要求运行cd lib/brainstorm-server npm install安装依赖再用timeout 3 node index.js验证能收到server-startedJSON。Task 2浏览器 Helper 库自动事件捕获helper.js是一个自执行 IIFE服务器注入后它完成了三件事建立 WebSocket 连接、自动捕获用户交互、暴露显式 API。连接与断线重连(function() { const WS_URL ws:// window.location.host; let ws null; let eventQueue []; function connect() { ws new WebSocket(WS_URL); ws.onopen () { // Send any queued events eventQueue.forEach(e ws.send(JSON.stringify(e))); eventQueue []; }; ws.onmessage (msg) { const data JSON.parse(msg.data); if (data.type reload) { window.location.reload(); } }; ws.onclose () { // Reconnect after 1 second setTimeout(connect, 1000); }; } // ...要点收到reload消息即整页刷新断线 1 秒后自动重连连接未就绪时事件进入eventQueue重连后补发——保证用户交互不因瞬时断连丢失。三类自动捕获// Auto-capture clicks on interactive elements document.addEventListener(click, (e) { const target e.target.closest(button, a, [data-choice], [rolebutton], input[typesubmit]); if (!target) return; // Dont capture regular link navigation if (target.tagName A !target.dataset.choice) return; e.preventDefault(); send({ type: click, text: target.textContent.trim(), choice: target.dataset.choice || null, id: target.id || null, className: target.className || null }); });点击捕获用事件委托 closest()匹配button, a, [data-choice], [rolebutton], input[typesubmit]普通链接导航被排除命中目标则preventDefault()后发送click事件其中data-choice是选项标识符约定。表单提交捕获document.addEventListener(submit, (e) { e.preventDefault(); const form e.target; const formData new FormData(form); const data {}; formData.forEach((value, key) { data[key] value; }); send({ type: submit, formId: form.id || null, formName: form.name || null, data: data }); });输入变更捕获带 500ms 防抖let inputTimeout null; document.addEventListener(input, (e) { const target e.target; if (!target.matches(input, textarea, select)) return; clearTimeout(inputTimeout); inputTimeout setTimeout(() { send({ type: input, name: target.name || null, id: target.id || null, value: target.value, inputType: target.type || target.tagName.toLowerCase() }); }, 500); // 500ms debounce });显式 APIwindow.brainstorm { send: send, choice: (value, metadata {}) send({ type: choice, value, ...metadata }) };除了全自动捕获页面作者也可以显式调用brainstorm.send(...)或brainstorm.choice(custom, {extra: data})发送任意结构化事件。计划要求用node -c lib/brainstorm-server/helper.js校验语法后提交。Task 3集成测试计划为服务器编写位于tests/brainstorm-server/server.test.js的集成测试思路是用child_process.spawn拉起真实服务器BRAINSTORM_PORT3334、BRAINSTORM_SCREEN/tmp/brainstorm-test/screen.html采集其 stdout然后依次断言启动消息stdout 包含server-started与端口号HTML 服务与注入GET /返回 200body 含brainstorm内容且注入了 helperbody 中出现WebSocket字样事件中继通过真实 WebSocket 客户端发送{ type: click, text: Test Button }断言 stdout 出现user-event与Test Button文件变更通知修改屏幕文件后断言第二个 WebSocket 客户端收到{ type: reload }消息。测试用自写的fetch封装基于http.get、sleep与cleanup()删除测试目录辅助finally块中server.kill()并清理失败时process.exit(1)。运行方式cd tests/brainstorm-server npm install ws node server.test.js。当前仓库中该目录已扩展为更完整的测试套件除server.test.js外还有 auth.test.js、lifecycle.test.js、ws-protocol.test.js、branding.test.js、helper.test.js 以及 start/stop 脚本的 shell 测试——可见测试面从服务器基本行为扩展到了认证、生命周期与 WebSocket 协议层。Task 4接入 Brainstorming Skill计划将可视化伴侣作为 brainstorming skill 的可选能力新建skills/brainstorming/visual-companion.md参考文档覆盖启动服务器、推送屏幕、读取用户响应三类操作在 SKILL.md 的 Key Principles 之后追加 Visual Companion (Optional) 小节给出适用场景UI/UX 选项对比、线框图、结构化反馈、点击原型与四步用法。计划文档中给出的参考文档草案包含以下关键内容都值得完整保留启动服务器作为后台任务node ${PLUGIN_ROOT}/lib/brainstorm-server/index.js然后告知用户Ive started a visual companion at http://localhost:3333 - open it in a browser.推送屏幕把 HTML 写入/tmp/brainstorm/screen.html服务器监视该文件并自动刷新浏览器。读取用户响应在后台任务输出中检查 JSON 事件例如{type:user-event,type:click,text:Option A,choice:optionA,timestamp:1234567890} {type:user-event,type:submit,data:{notes:My feedback},timestamp:1234567891}事件类型共三种click点击按钮或data-choice元素、submit表单提交含全部表单数据、input字段输入500ms 防抖。HTML 模式Patterns选项卡Choice Cardsdiv classoptions button>div classmockup header>form labelPriority: input typerange namepriority min1 max5/label textarea namenotes placeholderAdditional thoughts.../textarea button typesubmitSubmit/button /form显式 JavaScriptbutton onclickbrainstorm.choice(custom, {extra: data})Custom/button验证步骤是grep -A5 Visual Companion skills/brainstorming/SKILL.md确认新小节存在后提交。Task 5 与 Summary收尾最后一个可选任务是确保.gitignore排除lib/brainstorm-server/node_modules/。计划文档的 Summary 部分归纳了完成后的四个产物lib/brainstorm-server/下的服务器、自动注入的 helper 库、tests/brainstorm-server/下的测试以及更新了 visual companion 小节与参考文档的 brainstorming skill。使用方法四步走后台启动服务器node lib/brainstorm-server/index.js 让用户打开http://localhost:3333把 HTML 写入/tmp/brainstorm/screen.html检查任务输出中的用户事件从源码看当前仓库的演进实现上面的计划描述的是 v1 形态Express ws chokidar固定端口 3333单文件监视。当前仓库中的实际实现已演进为零依赖版本位置在 skills/brainstorming/scripts/server.cjs配套 start-server.sh、stop-server.sh、frame-template.html 与 helper.js用法详见 visual-companion.md。对照计划文档演进点如下1. 手写 RFC 6455 协议替代 ws 库server.cjs顶部直接实现了 WebSocket 帧编解码computeAcceptKeySHA1 魔数258EAFA5-...、encodeFrame/decodeFrame支持 7/16/64 位长度、客户端掩码校验、10MB 帧上限handleUpgrade中手动返回101 Switching Protocols。decodeFrame强制要求客户端帧带掩码Client frames must be masked并处理 TEXT / CLOSE / PING / PONG 帧与未知 opcode 的 1003 关闭。这使服务器在无任何 npm 依赖的情况下即可运行。2. 单文件监视升级为目录 最新文件语义计划中的chokidar.watch(SCREEN_FILE)单文件监视演进为对CONTENT_DIR$SESSION_DIR/content的原生fs.watch目录监视并维护knownFiles集合区分新屏幕与更新if (!knownFiles.has(filename)) { knownFiles.add(filename); console.log(JSON.stringify({ type: screen-added, file: filePath })); maybeOpenBrowser(); } else { console.log(JSON.stringify({ type: screen-updated, file: filePath })); } broadcast({ type: reload });服务器始终提供按修改时间最新的 HTML 文件getNewestScreen()每个屏幕一个语义化文件名、永不复用——这与计划中一个屏幕文件的模型相比让 Agent 可以积累一组屏幕而互不覆盖。代码注释还解释了为何不依赖事件类型macOS 的fs.watch对新文件和覆盖都报rename所以靠已知文件集合判断。3. 会话密钥与内容片段/完整文档双模计划版 URL 是裸的http://localhost:3333现行实现要求 URL 携带?key…会话密钥32 字节随机十六进制HTTP 与 WebSocket 升级都经过isAuthorized()的常量时间比较crypto.timingSafeEqual首次访问后密钥写入 HttpOnly SameSiteStrict 的 cookiecookie 名带实际绑定端口brainstorm-key-port以避免本地多服务器共享 cookie 串扰。未授权的请求收到 403 页提示需要完整 URL。内容侧也升级了屏幕文件以!DOCTYPE/html开头则原样服务否则自动包进 frame 模板——即 visual-companion.md 中默认写内容片段content fragments的规则。frame 模板frame-template.html提供明暗主题、头部连接状态灯以及.options/.option/.cards/.card/.mockup/.split/.pros-cons/.mock-nav/.mock-input/.placeholder等 CSS 类替代了计划版自己写全部 HTML/CSS的要求。4. 客户端 helper 的健壮性增强现行 helper.js 保留了计划版的核心语义data-choice点击捕获、window.brainstorm显式 API、事件队列补发但增强了指数退避重连500ms 起、翻倍、30s 封顶nextReconnectDelay为纯函数并导出供单测、15 秒未恢复则显示 Companion paused 墓碑层tombstone并在服务器同端口重启后自动恢复刷新、WebSocket 升级请求上带会话密钥/?key...。同时toggleSelect实现了单选/多选data-multiselect的选中态管理。5. 生命周期守护、闲置超时与优雅停机计划版的服务器需要 Agent 自己管理进程存活现行实现内置了完整生命周期start-server.sh为每个会话生成独立目录/tmp/brainstorm-$$-ts或--project-dir下的.superpowers/brainstorm/...用nohupdisown后台启动并写 PID 文件轮询日志等待server-startedJSON且验证进程在短暂窗口后仍存活捕获进程回收器服务器接收BRAINSTORM_OWNER_PIDharness 的祖先进程 PID周期性检查宿主是否死亡——死了就自杀start-server.sh还处理了 WSL/Tailscale/Windows MSYS2 下 PID 不可见的情形owner-pid-invalid日志后降级为纯闲置超时默认 4 小时无活动自动关闭--idle-timeout-minutes可调关闭时先销毁所有已升级的 WebSocket socket再server.close()——否则进程会挂在打开的连接上这正是 lifecycle.test.js 明确验证的行为启动的server-startedJSON 写入$STATE_DIR/server-info0600 权限含 URL 与密钥shutdown时写server-stopped标记stop-server.sh用每次启动生成的--brainstorm-server-id参数核对 PID 属于本服务器才肯发信号防止 PID 复用误杀且只清理/tmp下的临时会话--project-dir的 mockup 文件保留供后续查看。6. 端口策略计划版固定 3333 端口现行实现按BRAINSTORM_PORT→ 上次绑定端口BRAINSTORM_PORT_FILE让重启复用同端口、已打开的标签页自动重连→ 随机高端口49152 起的顺序选取EADDRINUSE时一次性回退随机端口但若设了BRAINSTORM_TOKEN环境变量则拒绝回退直接失败退出避免密钥与端口错配。事件模型对照计划版与现行版维度计划版本文主体文档现行仓库实现传输依赖Express ws chokidar零依赖手写 RFC 6455 fs.watch屏幕来源单文件/tmp/brainstorm/screen.htmlcontent/目录中最新的 HTML 文件内容要求完整 HTML注入 helper内容片段自动包 frame或完整文档访问控制无仅绑定 127.0.0.1?key会话密钥 HttpOnly cookie 常量时间比较事件输出stdout{type:user-event, ...}stdout{source:user-event, ...}且含choice的事件追加到$STATE_DIR/eventsJSON Lines新屏幕推入时清空刷新机制chokidar 变更 → 广播 reload目录监视 100ms 防抖 → 广播 reload区分 screen-added/updated进程管理Agent 自行后台运行start/stop 脚本、owner PID 守护、闲置超时、端口/密钥持久化值得注意的一个细节现行版把含choice字段的事件额外落盘到state_dir/events文件见 server.cjs 的handleMessageAgent 在下一轮直接读文件即可拿到浏览器交互的 JSON Lines 记录与终端文本反馈合并——这比盯着 stdout 滚动更可靠也是 visual-companion.md 中主循环The Loop的标准操作每轮先确认server-info存在且server-stopped不存在 → 写新的语义化命名屏幕文件 → 提示用户查看并结束本轮 → 下一轮读取events与终端回复。实践要点小结计划文档的价值2026-01-17-visual-brainstorming.md 展示了 Superpowers 自身的工程方法——每个任务带 Files / Steps / 验证命令 / commit 信息可直接交给 Agent 逐任务执行文档开头即声明需用executing-plansskill可复制的架构HTML 文件作为屏幕单一事实源、文件变更作为推送触发器、stdout JSON 作为 Agent 可读的事件总线——三者解耦使 Agent 侧不需要理解 WebSocket当前仓库的演进从固定 3333 端口的单文件服务器到带会话密钥、零依赖、可自愈的多屏幕会话服务演进路径本身由 tests/brainstorm-server/ 下的测试与 docs/superpowers/plans/2026-03-11-zero-dep-brainstorm-server.md、docs/superpowers/plans/2026-06-10-visual-companion-auth-hardening.md 等后续计划文档记录可继续沿仓库内的计划/规格文档追溯。【免费下载链接】superpowersAn agentic skills framework software development methodology that works.项目地址: https://gitcode.com/GitHub_Trending/su/superpowers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考