Documentation Index
Fetch the complete documentation index at: https://help.hoopai.com/llms.txt
Use this file to discover all available pages before exploring further.
HoopAI AI Chat Widget Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: UseGoal: Replace the broken VoiceGlow/ConvoCore widget with a fully custom Claude Haiku 4.5 chat panel backed by a Cloudflare Worker proxy that keeps all API keys off the client. Architecture: A Cloudflare Worker (superpowers:subagent-driven-development(recommended) orsuperpowers:executing-plansto implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.
worker/src/index.js) receives chat requests from the browser, runs an agentic tool loop (web search, support ticket creation), then streams the final Claude response back via SSE. The browser widget (theme/chat-widget.js) is a self-contained IIFE that renders a right-side panel matching Mintlify’s native AI drawer — slides in and pushes page content left.
Tech Stack: Cloudflare Workers, Wrangler CLI v3, OpenRouter API (anthropic/claude-haiku-4-5), Vanilla JS (ES5-compatible IIFE), CSS custom properties (--ds-* tokens already in theme/custom.css).
File Map
| File | Action | Responsibility |
|---|---|---|
worker/package.json | Create | Wrangler dev dependency |
worker/wrangler.toml | Create | Worker name, compat date, var stubs |
worker/src/index.js | Create | CORS, routing, agentic loop, tool execution, SSE streaming |
theme/chat-widget.js | Rewrite | Panel UI, streaming client, Ask AI button injections |
theme/custom.css | Modify | Panel layout, push-content rule, message bubbles, dark mode |
docs.json | Verify/fix | Confirm JS path is "theme/chat-widget.js" (not bare "chat-widget.js") |
Task 1: Worker — Project Scaffold
Files:-
Create:
worker/package.json -
Create:
worker/wrangler.toml -
Create:
worker/src/index.js(skeleton only) -
Step 1.1 — Create
worker/package.json
- Step 1.2 — Create
worker/wrangler.toml
- Step 1.3 — Create skeleton
worker/src/index.js
- Step 1.4 — Install Wrangler and verify scaffold
3.x.x (Wrangler version number)
- Step 1.5 — Commit scaffold
Task 2: Worker — CORS + Routing + OpenRouter Streaming Proxy
Files:-
Modify:
worker/src/index.js(replace skeleton with full implementation) - Step 2.1 — Smoke-test the current skeleton locally
hoopai-chat-api ok
Stop the dev server (Ctrl+C).
- Step 2.2 — Replace
worker/src/index.jswith full implementation
- Step 2.3 — Start worker dev server and test CORS preflight
HTTP/1.1 204 and access-control-allow-origin: http://localhost:3000
- Step 2.4 — Test blocked origin
HTTP/1.1 403
- Step 2.5 — Test basic streaming (requires OPENROUTER_API_KEY as local secret)
worker/.dev.vars (gitignored, local only):
.dev.vars is automatically gitignored by Wrangler — it’s the Wrangler equivalent of .env for local dev.
Restart the dev server, then:
data: {"type":"token","content":"..."} lines ending with data: {"type":"done"}
- Step 2.6 — Commit worker implementation
Task 3: Deploy Worker and Set Secrets
Files: No code changes — deployment and secret configuration only.- Step 3.1 — Deploy to Cloudflare
- Step 3.2 — Set the OpenRouter API key secret
✓ Success! Uploaded secret OPENROUTER_API_KEY
- Step 3.3 — Verify deployed worker responds
<WORKER_URL> with the URL from Step 3.1:
{"type":"done"}
- Step 3.4 — Commit deployment artifacts
worker/.dev.vars to .gitignore if not already covered by .env.* rule:
Open .gitignore and add under the secrets section:
Task 4: Widget CSS — Panel Styles
Files:-
Modify:
theme/custom.css(append at end of file) -
Step 4.1 — Append panel CSS to
theme/custom.css
theme/custom.css to find the last line number, then append:
- Step 4.2 — Commit CSS
Task 5: Widget JS — Complete Rewrite
Files:- Rewrite:
theme/chat-widget.js
toggleWidget() is replaced by togglePanel().
- Step 5.1 — Replace
theme/chat-widget.jswith the full widget
- Step 5.2 — Commit widget
Task 6: Wire Worker URL and Verify docs.json
Files:-
Modify:
theme/chat-widget.js(replace placeholder URL) -
Verify:
docs.json(ensure JS path is correct) - Step 6.1 — Replace the WORKER_URL placeholder
theme/chat-widget.js, line 22, replace:
- Step 6.2 — Verify docs.json JS reference
docs.json line ~143 references the correct path. Open docs.json and look for the "js" array. It should read:
theme/ prefix (e.g. "chat-widget.js"), update them to include theme/:
"theme/chat-widget.js", no change needed. If it shows "chat-widget.js", update it in docs.json.
- Step 6.3 — Commit URL + docs.json fix
Task 7: Integration Smoke Test
No file changes — verification only.- Step 7.1 — Kill any stale Node processes and start dev server
localhost:3000 to be ready.
- Step 7.2 — Open browser at localhost:3000 and verify Ask AI button appears
http://localhost:3000. Confirm:
- Navbar shows the sparkle “Ask AI” button to the right of the search bar
- No JavaScript console errors
- Step 7.3 — Open panel and verify layout
- Panel slides in from the right
- Page content shifts left
- Empty state shows sparkle icon, title, and 3 suggestion chips
- Dark/light mode matches site theme (toggle dark mode to verify)
- Step 7.4 — Send a message and verify streaming
- User bubble appears immediately
- Typing indicator shows
- Response streams in token by token
- Send button shows stop icon during streaming
- Input is disabled during streaming
- After completion: send button resets, input re-enables
- Step 7.5 — Test expand and clear
- Step 7.6 — Test code block Ask AI button
/api-reference/introduction). Confirm:
- Sparkle icon appears in code block toolbar on hover
- Clicking it opens the panel with the code pre-loaded in input
- Step 7.7 — Commit final state if all checks pass
Self-Review Checklist
- CORS security — Worker blocks all origins except
help.hoopai.comandlocalhost:3000 - API key never in browser —
OPENROUTER_API_KEYis a Wrangler secret, not in any file - Streaming — SSE handled with ReadableStream + TransformStream in Worker, ReadableStream in widget
- Tool loop — max 4 iterations prevents infinite loops; each tool fires
tool_start/tool_endSSE events - Web search gracefully disabled — if
BRAVE_SEARCH_API_KEYsecret absent, returns fallback message (no crash) - Support ticket gracefully disabled — if
SUPPORT_WEBHOOK_URLabsent, returns helpful message - Dark mode — all panel CSS uses
--ds-*tokens; no hardcoded colours - Mobile — panel goes full-width on
≤768px, no content push (avoids broken layout) - Existing Ask AI IDs preserved —
#assistant-entry,#assistant-entry-mobile,data-ask-ai-injected,#page-ask-ai-btnall identical - No VoiceGlow CDN calls —
cdn.voiceglow.orgscript removed entirely - Branding — system prompt explicitly blocks GoHighLevel / Marketing Muse / WhoPayI
- Keyboard shortcut — Ctrl+I / Cmd+I preserved