diff --git a/frontend/src/pages/BotProfilePage.vue b/frontend/src/pages/BotProfilePage.vue index f6d2a13..c2b9100 100644 --- a/frontend/src/pages/BotProfilePage.vue +++ b/frontend/src/pages/BotProfilePage.vue @@ -106,12 +106,16 @@ const webhookTestResult = ref<{ reachable: boolean; validResponse: boolean; late const webhookError = ref('') const webhookSuccess = ref('') -// Setup guide download +// Setup guide const showSetupGuide = ref(false) const isRegenerating = ref(false) const regeneratedSecret = ref('') const regeneratedBotId = ref('') const regenError = ref('') +const guideContent = ref('') +const guideLoading = ref(false) +const guideCopied = ref(false) +const guideMode = ref<'webhook' | 'polling'>('webhook') const ARCHETYPES = [ 'standard', 'lobster', 'sheep', 'cyborg', 'blob', 'tank', 'dog', 'cat', @@ -290,26 +294,28 @@ async function handleRegenerateSecret() { isRegenerating.value = false } -async function downloadGuide(mode: 'webhook' | 'polling') { +async function loadGuide(mode: 'webhook' | 'polling') { + guideMode.value = mode + guideLoading.value = true + guideContent.value = '' + guideCopied.value = false const path = mode === 'polling' ? '/docs/BOTFIGHTS-POLLING.md' : '/docs/BOTFIGHTS-WEBHOOK.md' - const fileName = mode === 'polling' ? 'BOTFIGHTS-POLLING.md' : 'BOTFIGHTS-WEBHOOK.md' try { const res = await fetch(path) let content = await res.text() content = content.replace(/YOUR_BOT_ID/g, regeneratedBotId.value) content = content.replace(/YOUR_BOT_SECRET/g, regeneratedSecret.value) - const blob = new Blob([content], { type: 'text/markdown' }) - const url = URL.createObjectURL(blob) - const a = document.createElement('a') - a.href = url - a.download = fileName - document.body.appendChild(a) - a.click() - document.body.removeChild(a) - URL.revokeObjectURL(url) + guideContent.value = content } catch { - window.open(path, '_blank') + guideContent.value = '# Failed to load setup guide' } + guideLoading.value = false +} + +function copyGuide() { + navigator.clipboard.writeText(guideContent.value) + guideCopied.value = true + setTimeout(() => { guideCopied.value = false }, 2000) } onMounted(async () => { @@ -835,11 +841,11 @@ const tierClass = (t: number) => `tier-${t}`
- Download the setup guide with your credentials embedded. + Get the setup guide with your credentials embedded. This requires regenerating your bot secret (your old secret will stop working).
- +NEW SECRET GENERATED
@@ -850,24 +856,53 @@ const tierClass = (t: number) => `tier-${t}`Save this now. It will not be shown again after you leave this page.
{{ guideContent }}
+ Loading...
++ Choose webhook or polling above to view the setup guide. +
@@ -882,7 +917,7 @@ const tierClass = (t: number) => `tier-${t}` @click="handleRegenerateSecret" > - {{ isRegenerating ? 'REGENERATING...' : 'REGENERATE SECRET & DOWNLOAD' }} + {{ isRegenerating ? 'REGENERATING...' : 'REGENERATE SECRET' }}Your current bot secret will be invalidated and replaced with a new one. diff --git a/frontend/src/pages/JoinBoutPage.vue b/frontend/src/pages/JoinBoutPage.vue index f009ad3..6479a1f 100644 --- a/frontend/src/pages/JoinBoutPage.vue +++ b/frontend/src/pages/JoinBoutPage.vue @@ -527,6 +527,11 @@ async function confirmPolling() { } } +const showSetupContent = ref(false) +const setupContent = ref('') +const setupContentLoading = ref(false) +const setupContentCopied = ref(false) + function setupDocPath() { return connectionMode.value === 'polling' ? '/docs/BOTFIGHTS-POLLING.md' : '/docs/BOTFIGHTS-WEBHOOK.md' } @@ -535,29 +540,42 @@ function setupDocName() { return connectionMode.value === 'polling' ? 'BOTFIGHTS-POLLING.md' : 'BOTFIGHTS-WEBHOOK.md' } -async function downloadSetupGuide() { - try { - const res = await fetch(setupDocPath()) - let content = await res.text() - content = content.replace(/YOUR_BOT_ID/g, botId.value) - content = content.replace(/YOUR_BOT_SECRET/g, botSecret.value) - const blob = new Blob([content], { type: 'text/markdown' }) - const url = URL.createObjectURL(blob) - const a = document.createElement('a') - a.href = url - a.download = setupDocName() - document.body.appendChild(a) - a.click() - document.body.removeChild(a) - URL.revokeObjectURL(url) - } catch { - window.open(setupDocPath(), '_blank') +async function toggleSetupContent() { + showSetupContent.value = !showSetupContent.value + if (showSetupContent.value && !setupContent.value) { + setupContentLoading.value = true + try { + const res = await fetch(setupDocPath()) + let content = await res.text() + content = content.replace(/YOUR_BOT_ID/g, botId.value) + content = content.replace(/YOUR_BOT_SECRET/g, botSecret.value) + setupContent.value = content + } catch { + setupContent.value = '# Failed to load setup guide' + } + setupContentLoading.value = false } } -function copyFullPrompt() { - const docName = setupDocName() - const text = `Read ${docName} and follow the setup instructions. Here are my credentials:\nBOT_ID=${botId.value}\nBOT_SECRET=${botSecret.value}` +function copySetupContent() { + navigator.clipboard.writeText(setupContent.value) + setupContentCopied.value = true + setTimeout(() => { setupContentCopied.value = false }, 2000) +} + +async function copyFullPrompt() { + if (!setupContent.value) { + try { + const res = await fetch(setupDocPath()) + let content = await res.text() + content = content.replace(/YOUR_BOT_ID/g, botId.value) + content = content.replace(/YOUR_BOT_SECRET/g, botSecret.value) + setupContent.value = content + } catch { /* fall through with empty content */ } + } + const text = setupContent.value + ? setupContent.value + : `Read ${setupDocName()} and follow the setup instructions.\n\nBOT_ID=${botId.value}\nBOT_SECRET=${botSecret.value}` navigator.clipboard.writeText(text) setupGuideCopied.value = true setTimeout(() => { setupGuideCopied.value = false }, 2000) @@ -991,20 +1009,37 @@ function handleSignOut() {
- Put this file in your workspace — your AI reads it to build the bot -
+ +Loading...
+{{ setupContent }}
+ - 2 STEPS — THEN YOU'RE FIGHTING + COPY THIS TO YOUR AI
- -Download {{ setupDocName() }} into your workspace
- -Tell your AI this:
-Read {{ setupDocName() }} and follow the setup instructions. Here are my credentials:
-- Your AI reads the guide, creates the bot, and starts it for you. +
+ Paste this into your AI (Claude, ChatGPT, etc.) — it includes the full setup guide with your credentials. Save these credentials — the secret won't be shown again.