/ Burrow / The Burrow Team only
Burrow

The Burrow: features, how they function, and backend config

Last updated 5 June 2026. Sources: hedgehog-client-portal README and CLAUDE.md.

1

What it is

The Burrow is Hedgehog Marketing's client portal: AI-powered marketing tools for clients, powered by Claude and the Hedgehog skill library. Each client gets access to 35 marketing tools across 5 categories, persistent conversations, deliverables, tasks, and autopilot approvals.

Repo: teddi-coder/hedgehog-client-portal. Live at theburrow.hedgehogmarketing.com.au.

Stack: Next.js 16 (App Router) + React 19 + TypeScript, Supabase (Auth, Postgres, RLS; project zfmraowvqigcagscdive), Anthropic Claude (claude-sonnet-4) with streaming, Tailwind with HH brand colours, deployed on Vercel. AI chat proxies to nearly-headless-hilda (NHH) on Fly.io.

2

Surfaces

Surface Route Auth Purpose
Public demo /preview/burrow/* None Sales/demo surface using Klaylife fixtures. Never break; shown to prospects.
Authenticated portal /burrow/* Supabase session Each client sees their own RLS-constrained data. Internal users get a client picker.
Login /login n/a Email + password. Accepts full email or business-name slug (e.g. klaylife).
Admin /admin/* and /burrow/admin/* Internal only Per-client access controls, SoT review.
Legacy /dashboard, /advisor, /tools/[slug], /channels/* Mixed Pre-Burrow pages. Don't touch without reason.
3

Features and how they function

Hilda chat

The chat page calls /api/hilda/chat, which calls Anthropic directly with MCP tools wired into the portal route (Phase 3b decision, 6 Jun 2026). There is no NHH proxy in the path. A context block built by hildaClientContext() is sent on the first message of each thread only: client name and slug, connector IDs (Google Ads, GA4, Meta, GSC, GBP, Slack, WhatConverts, Shopify), and strategy/plan/report sections for the demo client only. Drive and Sheets tools are excluded from the portal's tool set. /api/hilda/status probes connectivity.

35 config-driven tools

All tools share one chat UI and API route. The tool registry (src/lib/tools/registry.ts) plus SKILL.md files under /skills/ define the differences. System prompt layering: Identity, then Client Brief, then Skill Instructions, then Behavioural Rules. Adding a tool means one skill folder plus one registry entry; the chat page, sidebar, and dashboard pick it up automatically.

Tool-chat MCP integration

Separate from Hilda chat: when CHAT_MCP_ENABLED=true, the tool chat handler loads read-only tools from the hedgehog-google-ads and hedgehog-semrush MCP servers (Fly.io, Streamable HTTP). Every call goes through withClientScope(), which enforces the active client's account IDs to prevent cross-client data access. CHAT_MCP_CLIENT_ALLOWLIST limits which client slugs get MCP access.

Conversations

Message-per-row Postgres storage. When history exceeds 50 messages, older messages are summarised to manage tokens. Responses stream via ReadableStream. Agent portraits render in AgentBubble; messages carry an agent_id column.

Deliverables

The deliverables table holds typed deliverables rendered by per-type renderers in src/components/deliverables/renderers/: monthly reports, quarterly plans, a 13-section zod-schema audit renderer, prose types (campaign_build, content_piece), and creative_asset (iframe-style preview, copy panel, brief metadata, Download PNG via html2canvas). The deliverables folder is unified: all types appear in one view with type labels. Unique constraint on (client_id, type, period_label); all inserts must use INSERT ... ON CONFLICT ... DO UPDATE SET content = EXCLUDED.content, updated_at = NOW().

Creative Studio

AI-generated ad creatives via the generate-creative Supabase edge function (v4). Logo URL auto-populates from SoT brand data into the generation prompt. "Save to Burrow" stores outputs as creative_asset deliverables.

Source of Truth (SoT) review

Brand voice and persona data for all HH and MM clients across three tables: clients (core fields plus sot_completeness_pct, strategic_context, key_decisions), client_brand_voice (one row per client), and client_personas (multiple rows per client). Every record has hilda_confidence: draft then reviewed then approved. The review UI at /burrow/admin/sot-review (internal only) shows completeness bars, pending counts, and one-click approval. The index page is a server component calling createAdminSupabaseClient() directly; SUPABASE_SERVICE_ROLE_KEY must be set in Vercel or it silently shows 0 clients.

Autopilot approvals

Pending Google Ads and Meta Ads autopilot actions surface in the Burrow; clients approve or reject via /api/autopilot routes, with badge counts on the sidebar nav.

ClickUp tasks

/api/tasks fetches from multiple ClickUp lists in parallel (per-client clickup_list_ids), deduplicates, and groups team vs client tasks with list-name pills. Card-based layout with status bands and overdue de-emphasis. Internal users get an inline status dropdown backed by a PATCH route (/api/clickup/tasks/[taskId]) with optimistic UI updates. Client to-dos are checkable; HH internal tasks are read-only for clients.

Inbox

/api/inbox builds a unified notification feed from four Supabase tables, rendered at /burrow/inbox with skeleton loading and empty states.

Onboarding and welcome emails

Self-serve 4-step onboarding wizard, token-gated, firing an NHH webhook on completion, with an admin link generator. Completion triggers a transactional welcome email via Resend (sending domain hedgehogmarketing.com.au, must be verified in Resend; emails silently skip if RESEND_API_KEY is unset).

Auth and client scoping

Supabase email and password; slug logins map to <slug>@burrow.hedgehogmarketing.com.au. /burrow/layout.tsx calls resolveBurrowBootstrap() server-side, then BurrowClientBootstrap picks the active client from ?client=<slug> and provides it via useBurrowClient(). Internal users switch clients; clients are locked to their own profile (URL-hacking ?client= does nothing for them). Every internal link must use useBurrowHref() to preserve the slug across navigation. Only Klaylife is the demo client; isDemoClient() gates all fixture content so non-Klaylife clients never see Klaylife data. Password reset flows live at /auth/callback and /auth/reset-password. Internal users also get a "Preview mode" toggle in the sidebar.

4

Report ingest

  • Monthly planning reports are converted to Burrow-ready JSON and inserted into Supabase project zfmraowvqigcagscdive via the burrow-report-ingest workflow.
  • The deliverables table has a unique constraint on (client_id, type, period_label).
  • All inserts MUST use INSERT ... ON CONFLICT ... DO UPDATE SET content = EXCLUDED.content, updated_at = NOW() — re-ingesting is always safe and never duplicates.
  • Renderer types are documented on /burrow-components.
5

Client ID resolution

  • HH and MM internal client workspaces resolve via hardcoded overrides in NHH burrow-proposals.js (BURROW_CLIENT_ID_OVERRIDES, PR #125): HH → c63e6cc5-333e-4033-af9f-4be578e9e26a, MM → 858637a4-7e23-4a73-9b72-5e5ea983f493.
  • All other clients resolve dynamically from the database.
6

Hilda chat architecture (June 2026)

  • The portal's /api/hilda/chat calls Anthropic directly — there is NO NHH proxy in the path.
  • MCP tools are wired directly into the portal route (Phase 3b decision, 6 Jun 2026). Two-stack parity with NHH is accepted.
  • Drive and Sheets tools are excluded from the portal's tool set.
  • Orphaned code on the cleanup list: NHH /api/chat and the portal's streamHilda().
7

Backend config

Core env vars (required)

NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, ANTHROPIC_API_KEY, ADMIN_EMAILS.

Email (optional)

RESEND_API_KEY.

MCP tool-use (optional)

CHAT_MCP_ENABLED, CHAT_MCP_CLIENT_ALLOWLIST, NHH_AUTH_TOKEN, NHH_URL (defaults to https://nearly-headless-hilda.fly.dev), MCP_TOKEN_PRIMARY + MCP_SERVER_HEDGEHOG_GOOGLE_ADS_URL, MCP_TOKEN_SEMRUSH + MCP_SERVER_HEDGEHOG_SEMRUSH_URL.

All values live in Vercel → hedgehog-client-portal → Settings → Environment Variables. Vercel's VERCEL_GIT_COMMIT_SHA feeds the /burrow/* build banner; a mismatched SHA means the deploy hasn't landed.

Seeding

npm run seed:clients upserts the client roster from the ClickUp HH Client Tasks folder (id 90160957776); each client list contains a Client Config task holding platform IDs. npm run seed:admin creates the internal admin user. Runbook: docs/client-auth-seeding.md.

Git and deploy

Never commit to main (pre-commit hook plus Vercel rejection). Feature branches named feature/burrow-iter-N-<desc>, committed as teddi-coder; Teddi merges and Vercel auto-deploys from main.

8

Known limitations (June 2026)

  • MCP tools are now wired directly into the portal route (Phase 3b, Jun 2026). NHH's /api/chat is orphaned and on the cleanup list.
  • Passwords equal slugs. Preview-grade; harden with magic links or forced reset before real client onboarding.
  • Deliverables are empty for most non-Klaylife clients until the pipeline populates them.
  • 22 ClickUp clients have no Config task and aren't seeded (likely inactive).
  • /api/burrow/metrics/[slug]/snapshot returns stored data only; live-fetch blocks are stubbed as not-connected.
  • NHH's /api/onboarding endpoint isn't built yet; the wizard webhook graceful-fails.