Files
ozan a81a450e7e feat: monorepo consolidation — merge CLI, bot, admin, team-tool, website, docs, runner, proxy
Merged into tinqs/studio:
- cmd/tinqs-cli/    — tinqs-cli (Go binary, from bot/cli)
- cmd/tea/          — Gitea CLI tool (from tinqs/cli-tea)
- services/bot/     — Bot service (from tinqs-ltd/bot on git.arikigame.com)
- services/admin/   — Admin panel (from tinqs/admin)
- services/team-tool/ — Team Tool (from tinqs/team-tool)
- services/proxy/   — tinqs-proxy (from bot/proxy)
- web/landing/      — tinqs.com website (from tinqs/website)
- web/docs/         — Platform docs (from tinqs/docs)
- web/blog/         — Blog (placeholder)
- runner/           — Ephemeral CI runner (from tinqs/runner)

All source repos will be deleted after verification.
2026-05-22 04:55:50 +00:00

18 KiB

CLAUDE.md — Claude Code context for bot.arikigame

Unified bot platform — Meet assistant + docs MCP + team messaging.

On session start

  1. Read ../docs/ai/SOUL.md for hub identity (if on Kraken).
  2. Read ../docs/ai/handoff.md for pending tasks.

Language

Always respond in English.

Branch

Always main. Pull before working.

Secrets

Never commit API keys, tokens, or .env files. Use .env.local (gitignored).

Architecture

  • Next.js 16 on Lightsail :5500 (internal port 3000 if Docker, or PORT=5500 native)
  • tinqs-proxy (Go binary) at bot.arikigame.com — replaces Caddy. Source: proxy/
  • Tailscale auth via whois proxy at :39139
  • MCP endpoint at /api/mcp — serves hub identity, glossaries, skills, CLI tool proxies
  • Gitea API for fetching docs content (cached 5 min)
  • AWS Bedrock for LLM (Mistral 8B via taco-bot-bedrock IAM user)

Key endpoints

Path Auth Purpose
/ Public Landing page
/api/ping Public Health check + Tailscale status
/api/mcp Tailscale MCP JSON-RPC 2.0 endpoint
/api/meeting/* Tailscale Meeting assistant APIs

Project

Tinqs Team Tool — macOS Edition

A native macOS version of the Tinqs Team Tool — a live transcription and meeting productivity app for the Tinqs game development team. It captures audio via mic, runs dual-engine speech recognition (Apple Speech Framework for real-time free transcription + ElevenLabs Scribe V2 for high-accuracy speaker-diarized chunks), and serves an embedded web UI from a local Go HTTP server wrapped in a Swift/AppKit shell. After a session, it can generate formatted meeting notes from the transcript and save them directly into the PM repo.

Core Value: Team members on Mac can record, transcribe, and produce structured meeting notes with the same workflow as the existing Windows tool — no feature gap between platforms.

Constraints

  • Platform: macOS 13+ (Ventura) — ScreenCaptureKit requires 12.3+, Apple Speech Framework mature on 13+
  • Architecture: arm64 (Apple Silicon) primary, Intel support if straightforward
  • Build: Go cross-compilation for darwin/arm64 + Swift/Xcode build for the .app shell
  • Code sharing: Maximize shared Go code between Windows and Mac — platform-specific code behind build tags
  • Install: Must work via curl | sh for non-technical team members
  • Permissions: macOS requires explicit permission grants for microphone, screen recording — tool must guide users through this

Technology Stack

Languages

  • TypeScript 5.7.0 - Application code, type safety throughout
  • JavaScript (ES2022) - Browser runtime, client-side code
  • Go - External proxy binary (tinqs-proxy at proxy/)
  • Shell - CLI installation scripts (PowerShell, Bash)

Runtime

  • Node.js >=20 (required per package.json engines)
  • npm (lockfile: package-lock.json present)
  • Next.js 16.1.6 with output: 'standalone' — containerizable standalone build
  • AWS Lightsail (internal port 3000, external port 5500)
  • Docker-ready via standalone Next.js output

Frameworks

  • Next.js 16.1.6 - Full-stack React framework (App Router, API routes, middleware)
  • React 19.2.3 - UI library
  • React DOM 19.2.3 - DOM rendering
  • @assistant-ui/react 0.12.24 - Chat UI components for assistant interface
  • @assistant-ui/react-markdown 0.12.8 - Markdown rendering for assistant messages
  • PeerJS 1.5.5 - WebRTC peer-to-peer communication (for call/video features)
  • Tailwind CSS 4.2.2 - Utility-first CSS framework
  • PostCSS 8.5.9 - CSS processing
  • TanStack React Query 5.99.0 - Server state management, caching, synchronization
  • pg 8.20.0 - PostgreSQL client for Node.js
  • ioredis 5.10.1 - Redis client for pub/sub and caching
  • @anthropic-ai/sdk 0.39.0 - Anthropic Claude API (Bedrock fallback available)
  • @aws-sdk/client-bedrock-runtime 3.1026.0 - AWS Bedrock LLM inference (Mistral 8B)
  • @aws-sdk/client-s3 3.1029.0 - AWS S3 for object storage
  • Langfuse 3.38.20 - LLM observability, trace tracking
  • TypeScript 5.7.0 - Type checking
  • @types/node 22.10.0 - Node.js type definitions
  • @types/react 19 - React type definitions
  • @types/react-dom 19 - React DOM type definitions
  • @types/pg 8.20.0 - PostgreSQL client types
  • @tailwindcss/postcss 4.2.2 - Tailwind PostCSS plugin

Key Dependencies

  • Next.js 16.1.6 - Server-side rendering, API routes, middleware (auth layer)
  • @anthropic-ai/sdk - Main LLM provider for meeting assistant (Claude Sonnet 4)
  • pg - PostgreSQL for persistent hub state (posts, sessions, scores, switches)
  • ioredis - Redis for real-time pub/sub channels and presence data
  • @aws-sdk/client-bedrock-runtime - Fallback LLM provider (Mistral 8B, cheaper for taco-bot responses)
  • @aws-sdk/client-s3 - File storage for audio, transcripts, binary assets
  • Langfuse - Distributed tracing for LLM observability and cost tracking

Configuration

  • DATABASE_URL - PostgreSQL connection string (default: postgresql://admin:admin@localhost:5432/tinqs_hub)
  • REDIS_URL - Redis connection (default: redis://localhost:6379)
  • ANTHROPIC_API_KEY - Claude API key (required for primary LLM)
  • ANTHROPIC_MODEL - Claude model override (default: claude-sonnet-4-20250514)
  • AWS_REGION - AWS region (default: eu-west-1)
  • BEDROCK_MODEL - Mistral model on Bedrock (default: mistral.ministral-3-8b-instruct)
  • BEDROCK_JUDGE_MODEL - Judge model for eval (default: mistral.mistral-large-2402-v1:0)
  • GITEA_TOKEN - Git Studio authentication token (required for docs access)
  • GITHUB_TOKEN - GitHub API token (optional, for GitHub integration)
  • LANGFUSE_PUBLIC_KEY - Langfuse observability (default: pk-tinqs-agents)
  • LANGFUSE_SECRET_KEY - Langfuse auth (default: sk-tinqs-agents-secret)
  • LANGFUSE_BASE_URL - Langfuse instance (default: http://localhost:3100)
  • LANGFUSE_ENABLED - Toggle tracing (default: true)
  • TACO_API_SECRET - API secret for meeting extension auth
  • .env.local - Git-ignored local overrides
  • tsconfig.json - TypeScript configuration (ES2022 target, strict mode, path aliases @/*)
  • next.config.ts - Next.js config (standalone output, custom headers for /cli/install.ps1 and /cli/install.sh)
  • postcss.config.mjs - PostCSS with Tailwind
  • package.json - Scripts: dev, build, start, typecheck

Platform Requirements

  • Node.js >=20
  • PostgreSQL >=12 (local or remote)
  • Redis (optional, gracefully degrades if unavailable)
  • Git for repo access via Gitea API
  • Tailscale (for auth on protected endpoints)
  • Node.js >=20
  • PostgreSQL (managed)
  • Redis (managed)
  • AWS Account (Bedrock, S3, IAM for taco-bot-bedrock service account)
  • Tailscale network access
  • Lightsail instance (or equivalent containerized host)
  • Domain: bot.arikigame.com

Conventions

Naming Patterns

  • React components: PascalCase, collocated with feature (e.g., NavBar.tsx, TailscaleStatus.tsx)
  • Library/utility files: kebab-case (e.g., redis-pubsub.ts, tailscale-ip.ts, docs-search.ts)
  • API routes: follow Next.js convention at app/api/v1/{resource}/{action}/route.ts
  • Pages: follow Next.js convention at app/{feature}/page.tsx
  • camelCase for all functions and variables
  • Exported functions: descriptive names like callTacoClaude(), publishMessage(), checkRateLimit()
  • Handler functions: prefix with action like loadSpaces(), sendMessage(), toggleMic()
  • Refs: suffix with Ref (e.g., messagesEndRef, inputRef, sseRef, micWsRef)
  • Event handlers: prefix with handler name like onopen, onmessage, onerror
  • PascalCase for interfaces and types
  • Props interfaces: suffix with Props (e.g., UserCardProps)
  • API response shapes: explicit named interfaces (e.g., Space, Message)
  • Union types: use string literals (e.g., type UserRole = 'admin' | 'member')
  • Environment variables: SCREAMING_SNAKE_CASE (checked from process.env)
  • Local constants: camelCase (e.g., DEFAULT_MODEL, CACHE_TTL)
  • Configuration objects: camelCase (e.g., tokenCache, memoryTranscripts)

Code Style

  • No explicit ESLint or Prettier config found in root — uses Next.js defaults
  • TypeScript strict mode enabled: strict: true in tsconfig.json
  • No unused locals or parameters: noUnusedLocals: true, noUnusedParameters: true
  • ES2022 target with DOM + ES2022 lib
  • Named imports preferred: import { pool, redis } from '@/lib/db'
  • Type imports: import type { NextRequest, NextResponse } from 'next/server'
  • Path alias: @/ maps to root directory
  • Organize in order: external packages, internal absolute imports (@/), then relative imports
  • File-level comments explain purpose (e.g., "Database clients — PostgreSQL + Redis")
  • API endpoint comments document HTTP methods and query parameters
  • Function comments rare unless non-obvious (convention over explanation)
  • Inline comments for complex logic or workarounds
  • Some tactical comments like // dev bypass, // Close previous SSE connection

Error Handling

  • Wrap async operations in try-catch blocks
  • Narrow unknown errors safely: e instanceof Error ? e.message : String(e)
  • Return JSON error responses with status: 500 or appropriate code
  • Silent .catch(() => {}) used for non-critical side effects (optional async operations)
  • Empty catch blocks acceptable when error is intentionally ignored
  • No global error boundary — errors propagate to Next.js error handling

Function Design

  • Use explicit parameter objects for functions with multiple parameters
  • Document parameter shapes with interfaces
  • Example: callTacoClaude(params: { liveTranscriptBlock: string; docsBlock: string; question: string; source: 'voice' | 'chat' })
  • API handlers return NextResponse or Response
  • Async utilities return Promise<T>
  • Use Promise<T | null> for optional results (e.g., verifyToken())
  • Component functions return JSX

Module Design

  • Each library file exports utility functions and types
  • Single default export for React components
  • Named exports for utilities (e.g., export { pool, redis } from db.ts)
  • Barrel files not observed — each module directly imported
  • pool.query() used directly; no ORM layer
  • Raw SQL with parameterized queries ($1, $2, etc.)
  • Connection pooling via pg Package
  • lib/db.ts: PostgreSQL pool + Redis client setup
  • lib/auth.ts: Auth header/cookie verification
  • lib/cors.ts: CORS headers + JSON response helpers
  • lib/claude.ts: Anthropic SDK integration
  • lib/bedrock.ts: AWS Bedrock integration
  • lib/gitea.ts: Gitea API client
  • app/api/v1/{resource}/route.ts: Route handlers

Type Checking

  • Strict mode enforced
  • No any — use unknown or generics
  • Path aliases: @/* maps to ./* (root)
  • Incremental builds enabled
  • Define interface for props (not inline)
  • Example from app/chat/page.tsx:

Inline Styles & State Management

  • useState for local component state
  • useRef for DOM refs and persistent values (not state)
  • useCallback for event handlers to maintain referential equality
  • useEffect for side effects (data fetching, subscriptions, cleanup)
  • usePathname from Next.js for route awareness
  • Inline style objects preferred in this codebase (no CSS modules or Tailwind detected)
  • Color palette: #0a0a0a (bg), #e0e0e0 (text), #c9935a (accent)
  • No CSS classes — all dynamic via style prop
  • Optimistic updates common: apply state before server confirmation, rollback on failure
  • Polling fallbacks for real-time features (SSE with 30s fallback)
  • In-memory caches for performance (see store.ts)

Data Fetching

Logging

  • Prefixed logs: [taco] prefix for diagnostic logs
  • Only in non-production code paths or explicitly debug contexts
  • No structured logging library observed

Next.js Specifics

Security Patterns

  • Token-based auth from Gitea API
  • Cookie-based session: tinqs-token
  • Bearer header support: Authorization: Bearer {token}
  • Tailscale IP verification for admin routes
  • Query parameter extraction with .get() and type coercion
  • Type assertions for external data: as { login?: string; is_admin?: boolean }
  • No explicit schema validation library (Zod) found
  • Environment variables: process.env.ANTHROPIC_API_KEY, process.env.DATABASE_URL, process.env.REDIS_URL
  • Checked at startup or gracefully fallback

Architecture

Pattern Overview

  • Next.js 16 App Router for pages and API routes
  • Middleware-based authentication with Gitea token verification
  • PostgreSQL (source of truth) + Redis (presence/caching)
  • Real-time messaging via Redis pub/sub with SSE streams
  • Multi-feature platform: chat, voice calls (WebRTC/PeerJS), vision, transcription, MCP server

Layers

  • Purpose: React client components and pages
  • Location: app/ (page.tsx, chat/page.tsx, call/page.tsx, etc.)
  • Contains: Server-side pages, client components with hooks, UI layout
  • Depends on: Providers (QueryClient), API routes
  • Used by: Browser clients, Tailscale mesh users
  • Purpose: HTTP endpoints for all features (chat, calls, auth, MCP, admin)
  • Location: app/api/ (organized by feature: v1/chat/, v1/admin/, auth/, call/, meeting/, mcp/)
  • Contains: Next.js route handlers (GET/POST), SSE streams, webhooks
  • Depends on: Middleware, lib utilities, database
  • Used by: Frontend, CLI, external integrations, MCP clients
  • Purpose: Request authentication, authorization, rate limiting prep
  • Location: middleware.ts (root)
  • Contains: Gitea token verification, Tailscale IP detection, admin route guards, cookie-based session
  • Depends on: Gitea API, Tailscale whois proxy, environment config
  • Used by: All protected routes (skips public: /, /api/ping, /api/auth/, /cli/)
  • Purpose: Shared business logic, integrations, data access
  • Location: lib/ (db.ts, auth.ts, bedrock.ts, gitea.ts, mcp-handler.ts, etc.)
  • Contains: Database clients (Pool, Redis), API clients (Gitea, AWS Bedrock, Anthropic), handlers
  • Depends on: Environment config, external services
  • Used by: All API routes and utilities
  • Purpose: Persistence and real-time messaging
  • Technologies: PostgreSQL (posts, sessions, scores, switches, inferences), Redis (pub/sub, TTL presence)
  • Connection: lib/db.ts manages Pool and Redis instances
  • Used by: Hub query, chat persistence, session tracking

Data Flow

  • Server state: PostgreSQL (immutable source of truth)
  • Session state: Gitea token in httpOnly cookie + middleware header
  • Real-time events: Redis pub/sub channels per space/room
  • Client state: TanStack Query (React Query) with 5s stale time, refetch disabled
  • Caching: In-memory maps in middleware (token cache), lib functions (Gitea file cache)

Key Abstractions

  • Purpose: Fetch files from Git Studio (tinqs-ltd/docs, tinqs-ltd/bot, etc.)
  • Examples: fetchFile(repo, path), listDir(), searchCode()
  • Pattern: In-memory LRU cache with TTL; fails gracefully if Gitea unreachable
  • Used by: MCP handler, hub query, identity docs
  • Purpose: PostgreSQL pool and Redis client initialization
  • Tables: posts, sessions, scores, switches, inferences (schema not in code — external)
  • Pattern: Singleton instances; Redis is optional (graceful degradation)
  • Used by: Chat routes, hub query, inference logging
  • Purpose: Streamable HTTP transport for MCP JSON-RPC 2.0
  • Tools: get_identity, get_glossary, get_repo_file, list_skills, search_docs, gitea_api
  • Resources: tinqs://identity/soul, tinqs://glossary/[user], tinqs://handoff
  • Pattern: Request parsing → tool dispatch → Gitea/DB fetch → JSON-RPC response
  • Purpose: Gather context from DB + Gitea, invoke Bedrock for answer
  • Contexts: Recent posts, sessions, switches, inferences
  • Pattern: Query DB → format markdown context → call Bedrock → log cost
  • Used by: Agent endpoints, hand-off inference
  • Purpose: Token verification against Gitea API
  • Pattern: Gitea token → fetch /api/v1/user → cache 5 min → set header
  • Fallbacks: TACO_API_SECRET legacy header, Tailscale IP whois
  • Headers: x-tinqs-user set by middleware for downstream use

Entry Points

  • Location: / (root path)
  • Triggers: Browser navigation; Tailscale or guest entry
  • Responsibilities: Auth check, Gitea login form, gateway page listing
  • Location: /chat
  • Triggers: User clicks "Chat" from nav
  • Responsibilities: SSE stream subscription, message render, form submission
  • Location: /call and /call/[room]
  • Triggers: Room creation, room join
  • Responsibilities: List active rooms, initialize PeerJS, signal relay
  • /api/auth/check — GET, public, returns auth state
  • /api/auth/login — POST, public, Gitea token login
  • /api/ping — GET, public, health check + Tailscale status
  • /api/v1/chat — POST/GET, authenticated, message CRUD
  • /api/v1/chat/sse — GET, authenticated, SSE stream
  • /api/v1/admin/* — Requires Gitea admin + Tailscale IP
  • /api/mcp — POST, authenticated, MCP JSON-RPC handler
  • Location: /cli (setup guide), /cli/install.sh, /cli/install.ps1
  • Triggers: New user setup
  • Responsibilities: Display token registration, shell script download

Error Handling

  • Database: Query errors throw; Redis errors degrade gracefully (SSE falls back to polling)
  • External APIs: Gitea unreachable → cached data used; timeout is 3-10 sec with abort signal
  • Auth: Invalid token → 401 JSON response; no token on protected route → redirect to / or 401
  • Middleware: Tailscale IP detection fails → continue (non-blocking)
  • Chat: Missing space param → 400 with error; Redis unavailable → client reconnects

Cross-Cutting Concerns

Project Skills

No project skills found. Add skills to any of: .claude/skills/, .agents/skills/, .cursor/skills/, or .github/skills/ with a SKILL.md index file.

GSD Workflow Enforcement

Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync.

Use these entry points:

  • /gsd-quick for small fixes, doc updates, and ad-hoc tasks
  • /gsd-debug for investigation and bug fixing
  • /gsd-execute-phase for planned phase work

Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it.

Developer Profile

Profile not yet configured. Run /gsd-profile-user to generate your developer profile. This section is managed by generate-claude-profile -- do not edit manually.