diff --git a/e2e/signup-bot.spec.ts b/e2e/signup-bot.spec.ts index 4d878c8..0103c20 100644 --- a/e2e/signup-bot.spec.ts +++ b/e2e/signup-bot.spec.ts @@ -41,3 +41,20 @@ test.describe('bot registration flow', () => { await expect(page.getByText(/choose your fighter/i).first()).toBeVisible({ timeout: 5_000 }) }) }) + +test.describe('unified AI bot-setup prompt (BOT-02)', () => { + test('docs page shows the "give this to your AI" copy affordance', async ({ page }) => { + await page.goto('/docs') + await expect(page.getByText(/give this to your ai/i).first()).toBeVisible({ timeout: 10_000 }) + await expect(page.getByText(/copy full prompt/i).first()).toBeVisible({ timeout: 5_000 }) + }) + + test('GET /api/docs/prompt returns the self-contained prompt an agent could consume', async ({ page }) => { + await page.goto('/docs') + const res = await page.request.get('/api/docs/prompt') + expect(res.status()).toBe(200) + const body = await res.text() + expect(body).toContain('/api/bots') + expect(body).not.toContain('{{ARENA_URL}}') + }) +}) diff --git a/frontend/src/pages/BotProfilePage.vue b/frontend/src/pages/BotProfilePage.vue index b0fedcd..708d1c8 100644 --- a/frontend/src/pages/BotProfilePage.vue +++ b/frontend/src/pages/BotProfilePage.vue @@ -115,7 +115,6 @@ 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', @@ -294,17 +293,16 @@ async function handleRegenerateSecret() { isRegenerating.value = false } -async function loadGuide(mode: 'webhook' | 'polling') { - guideMode.value = mode +async function loadGuide() { guideLoading.value = true guideContent.value = '' guideCopied.value = false - const path = mode === 'polling' ? '/docs/BOTFIGHTS-POLLING.md' : '/docs/BOTFIGHTS-WEBHOOK.md' try { - const res = await fetch(path) + const res = await fetch('/docs/BOTFIGHTS.md') let content = await res.text() content = content.replace(/YOUR_BOT_ID/g, regeneratedBotId.value) content = content.replace(/YOUR_BOT_SECRET/g, regeneratedSecret.value) + content = content.replace(/\{\{ARENA_URL\}\}/g, window.location.origin) guideContent.value = content } catch { guideContent.value = '# Failed to load setup guide' @@ -856,33 +854,22 @@ const tierClass = (t: number) => `tier-${t}`
Save this now. It will not be shown again after you leave this page.
- -Loading...
-- Choose webhook or polling above to view the setup guide. -
diff --git a/frontend/src/pages/DocsPage.vue b/frontend/src/pages/DocsPage.vue index 8075132..dbb77b0 100644 --- a/frontend/src/pages/DocsPage.vue +++ b/frontend/src/pages/DocsPage.vue @@ -36,6 +36,32 @@ function copyText(text: string, id: string) { setTimeout(() => { if (copiedId.value === id) copiedId.value = '' }, 2000) } +// ── "Give this to your AI" — the single self-contained setup prompt (BOT-02) ── +const promptUrl = computed(() => `${window.location.origin}/api/docs/prompt`) +const promptLoading = ref(false) +const promptCopied = ref<'' | 'url' | 'text'>('') + +function copyPromptUrl() { + navigator.clipboard.writeText(promptUrl.value) + promptCopied.value = 'url' + setTimeout(() => { if (promptCopied.value === 'url') promptCopied.value = '' }, 2000) +} + +async function copyFullPromptText() { + promptLoading.value = true + try { + const res = await fetch('/api/docs/prompt') + const text = await res.text() + navigator.clipboard.writeText(text) + promptCopied.value = 'text' + setTimeout(() => { if (promptCopied.value === 'text') promptCopied.value = '' }, 2000) + } catch { + // no-op — user can retry + } finally { + promptLoading.value = false + } +} + const tabs = ['quickstart', 'api', 'challenges', 'scoring', 'security', 'testing'] as const // ── Code examples ── @@ -542,6 +568,40 @@ async function runWebhookTest() { {{ error }}+ One self-contained prompt covers everything: registration, credentials, both + protocols, every endpoint. Paste it into your AI, or hand it the URL below — no other + docs required. +
+{{ promptUrl }}
+
+