taco-bot
Tinqs meeting assistant: AWS App Runner + Chrome extension for Google Meet (wake phrase “Hey Taco”, chat prefix 🌮 Taco:). Git Studio: tinqs-ltd/taco-bot.
The in-meeting persona is still Taco (wake phrase “Hey Taco”, chat prefix 🌮 Taco:). This repository's name is taco-bot.
Production domain: https://taco.arikigame.com (Cloudflare CNAME → App Runner, DNS-only).
Architecture
Next.js 16 (App Router) on AWS App Runner (eu-west-1). Docker standalone build. The Chrome extension in extension/ calls:
| Route | Purpose |
|---|---|
GET /api/meeting/status |
Extension config (selectors, triggers, version) |
POST /api/meeting/transcript |
Append live captions (auth required) |
POST /api/meeting/ask |
Ask Taco (Bedrock Mistral + optional docs search) |
GET|POST /api/meeting/calendar |
Cron placeholder |
Backend: AWS Bedrock (Mistral Ministral 8B, set LLM_PROVIDER=claude to switch to Anthropic), Gitea docs search on tinqs-ltd/docs (Git Studio API), in-memory store (Redis planned).
Repository layout
| Path | Purpose |
|---|---|
app/api/meeting/ |
Next.js route handlers (transcript, ask, status, calendar) |
lib/ |
Shared server code (Claude, GitHub docs search, KV, CORS) |
extension/ |
Chrome extension (Manifest V3) — load unpacked for development |
public/ |
Static files (e.g. taco-status.html) |
planning.md |
Architecture decisions, product vision |
Hosting
- Production URL: https://taco.arikigame.com
- App Runner URL:
https://ytre5eznhp.eu-west-1.awsapprunner.com - ECR:
149751500842.dkr.ecr.eu-west-1.amazonaws.com/taco-bot - Region: eu-west-1
- DNS:
taco.arikigame.comCNAME (DNS-only) → App Runner. ACM cert for SSL.
Deploy
# Build, push, deploy
docker build --platform linux/amd64 -t taco-bot .
aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin 149751500842.dkr.ecr.eu-west-1.amazonaws.com
docker tag taco-bot:latest 149751500842.dkr.ecr.eu-west-1.amazonaws.com/taco-bot:latest
docker push 149751500842.dkr.ecr.eu-west-1.amazonaws.com/taco-bot:latest
aws apprunner start-deployment --service-arn "arn:aws:apprunner:eu-west-1:149751500842:service/taco-bot/7825a8030fce4f038e075018d700f489" --region eu-west-1
Full deploy workflow: devops/pipelines/taco-bot-apprunner.md.
Environment variables
Set in App Runner → taco-bot → Configuration → Environment variables.
| Variable | Required | Purpose |
|---|---|---|
LLM_PROVIDER |
Yes | bedrock (default) or claude |
TACO_API_SECRET |
Yes | Extension sends Authorization: Bearer … or x-taco-key |
GITEA_TOKEN |
Yes | Gitea API token for docs search on Git Studio |
GITEA_DOCS_REPO |
No | Default: tinqs-ltd/docs (Git Studio) |
AWS_REGION |
No | Default: eu-west-1 |
BEDROCK_MODEL |
No | Default: mistral.ministral-3-8b-instruct |
ANTHROPIC_API_KEY |
Only if LLM_PROVIDER=claude |
Deprecated — use Bedrock |
Without Redis configured, transcript/rate-limit uses in-memory fallback (fine for dev, not production).
Team access
Jeremy (owner)
- Git Studio: Push access on
tinqs-ltd/taco-bot. - AWS: IAM user
jeremywith AdministratorAccess. Can deploy via ECR + App Runner CLI.
CTO
Organization Admin. Direct push to main.
Custom domain
taco.arikigame.com — Cloudflare CNAME (DNS-only) → ytre5eznhp.eu-west-1.awsapprunner.com. ACM cert handles SSL. Three ACM validation CNAME records in Cloudflare (added 8 Apr 2026).
Security — Tailscale auth (8 Apr 2026)
This service is protected by Tailscale identity — ported from admin.arikigame. The Next.js middleware (middleware.ts) runs on every request and requires one of:
| Auth path | How it works |
|---|---|
| Bearer token | Extension sends Authorization: Bearer <TACO_API_SECRET> — works from any network |
| Tailscale headers | tailscale serve injects tailscale-user-login header — tailnet only |
| Tailscale IP + whois | Direct 100.x access → whois proxy resolves to @tinqs.com user — tailnet only |
| Dev bypass | ALLOW_DEV_AUTH=true or NODE_ENV=development — local dev only |
Unauthenticated browser requests → redirect to /connect-tailscale (landing page).
Unauthenticated API requests → 401 JSON.
For Lightsail deployment (bot.arikigame.com)
All three auth paths work. Set TAILSCALE_WHOIS_PROXY_URL=http://127.0.0.1:8380 to enable IP-based identity resolution.
For App Runner deployment (taco.arikigame.com)
Bearer token is the primary auth path — the extension sends it with every request. Tailscale headers/IP won't be present since App Runner is public internet. Unauthenticated browser hits get the Tailscale required page.
Jeremy — important
The middleware is now active in production. The Chrome extension already sends the Bearer token, so it continues to work. But if you curl the API without -H "Authorization: Bearer $TACO_API_SECRET", you'll get 401. Add the header or set ALLOW_DEV_AUTH=true locally.
Chrome extension
- Open
chrome://extensions→ enable Developer mode → Load unpacked → select this repo’sextension/folder. - Click the Taco icon → set Gateway base URL to
https://taco.arikigame.com(no trailing slash) → TACO API secret (same asTACO_API_SECRET) → Save. - Use Test connection to verify
/api/meeting/status. - Join a Google Meet with captions on. Say “Hey Taco, …” or type “Taco, …” in in-meeting chat.
Permissions: The manifest allows https://*/* so the extension can call your chosen gateway host without a separate build per domain. For production, narrow host_permissions in extension/manifest.json to https://taco.arikigame.com/*.
Local development
npm ci
# create .env.local with your secrets (see env vars table above)
npm run dev
API base: http://localhost:3000/api/meeting/… (dev), http://localhost:5500/… (Docker/prod)
Timeouts: /api/meeting/ask can exceed 10s (Bedrock + Gitea docs search). App Runner has no function timeout limit — the maxDuration in route.ts is a Next.js hint only.