Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Turn ideas into validated designs and specs through collaborative dialogue before any code is written
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/helper.js
1(function() {2const WS_URL = 'ws://' + window.location.host;3let ws = null;4let eventQueue = [];56function connect() {7ws = new WebSocket(WS_URL);89ws.onopen = () => {10eventQueue.forEach(e => ws.send(JSON.stringify(e)));11eventQueue = [];12};1314ws.onmessage = (msg) => {15const data = JSON.parse(msg.data);16if (data.type === 'reload') {17window.location.reload();18}19};2021ws.onclose = () => {22setTimeout(connect, 1000);23};24}2526function sendEvent(event) {27event.timestamp = Date.now();28if (ws && ws.readyState === WebSocket.OPEN) {29ws.send(JSON.stringify(event));30} else {31eventQueue.push(event);32}33}3435// Capture clicks on choice elements36document.addEventListener('click', (e) => {37const target = e.target.closest('[data-choice]');38if (!target) return;3940sendEvent({41type: 'click',42text: target.textContent.trim(),43choice: target.dataset.choice,44id: target.id || null45});4647// Update indicator bar (defer so toggleSelect runs first)48setTimeout(() => {49const indicator = document.getElementById('indicator-text');50if (!indicator) return;51const container = target.closest('.options') || target.closest('.cards');52const selected = container ? container.querySelectorAll('.selected') : [];53if (selected.length === 0) {54indicator.textContent = 'Click an option above, then return to the terminal';55} else if (selected.length === 1) {56const label = selected[0].querySelector('h3, .content h3, .card-body h3')?.textContent?.trim() || selected[0].dataset.choice;57indicator.innerHTML = '<span class="selected-text">' + label + ' selected</span> — return to terminal to continue';58} else {59indicator.innerHTML = '<span class="selected-text">' + selected.length + ' selected</span> — return to terminal to continue';60}61}, 0);62});6364// Frame UI: selection tracking65window.selectedChoice = null;6667window.toggleSelect = function(el) {68const container = el.closest('.options') || el.closest('.cards');69const multi = container && container.dataset.multiselect !== undefined;70if (container && !multi) {71container.querySelectorAll('.option, .card').forEach(o => o.classList.remove('selected'));72}73if (multi) {74el.classList.toggle('selected');75} else {76el.classList.add('selected');77}78window.selectedChoice = el.dataset.choice;79};8081// Expose API for explicit use82window.brainstorm = {83send: sendEvent,84choice: (value, metadata = {}) => sendEvent({ type: 'choice', value, ...metadata })85};8687connect();88})();89