Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
5000017
docs(spec,plan): add boop-pdf-skills design and implementation plan
lakunle Apr 29, 2026
92b51dc
feat(skills): move boop-design to .claude/skills/ and sharpen trigger…
lakunle Apr 29, 2026
6e2f85c
feat(deps): add puppeteer for PDF rendering
lakunle Apr 30, 2026
7d9c738
feat(convex): add pdfArtifacts table
lakunle Apr 30, 2026
c183e04
feat(convex): add pdfArtifacts module (generate action + queries)
lakunle Apr 30, 2026
b39b5f1
feat(server): add boop-pdf MCP with Puppeteer-backed generate_pdf tool
lakunle Apr 30, 2026
e64ab01
feat(server): register boop-pdf MCP and update execution agent system…
lakunle Apr 30, 2026
b010c84
feat(scripts): add pdf:smoke for offline render-and-upload verification
lakunle Apr 30, 2026
f74dfaf
feat(skills): add pdf-invoice for invoice / receipt / expense PDFs
lakunle Apr 30, 2026
76250ef
feat(sendblue): accept optional mediaUrl with text-URL fallback
lakunle Apr 30, 2026
dd23488
feat(sendblue): pick up latest pdfArtifact post-turn and attach via m…
lakunle Apr 30, 2026
4df5534
feat(scripts): add pdf:smoke:sendblue for end-to-end iMessage verific…
lakunle Apr 30, 2026
f2ebdb7
feat(skills): add pdf-brief for daily/meeting/research summaries
lakunle Apr 30, 2026
99d4743
feat(skills): add pdf-itinerary for trip plans, agendas, schedules
lakunle Apr 30, 2026
d6ff3cb
feat(skills): add pdf-resume for resumes, CVs, one-pagers
lakunle Apr 30, 2026
40bcd87
feat(skills): add pdf-newsletter for digests, roundups, weekly recaps
lakunle Apr 30, 2026
7569258
feat(skills): add pdf-reference for cheatsheets, glossaries, quick re…
lakunle Apr 30, 2026
7187836
feat(debug): add FilesPanel for browsing pdfArtifacts with thumbnails
lakunle Apr 30, 2026
022ef4b
feat(debug): wire Files tab into dashboard navigation
lakunle Apr 30, 2026
e8a0232
docs: add manual trigger checklist for pdf-* skills
lakunle Apr 30, 2026
9cd7925
fix(interaction-agent): teach dispatcher about pdf-* skills
lakunle Apr 30, 2026
773f1cd
fix: address final code-review issues
lakunle Apr 30, 2026
36a887a
chore(skills): refresh Convex agent skill descriptions
lakunle Apr 30, 2026
6b5f85e
chore: ignore .claude/*.lock runtime locks
lakunle Apr 30, 2026
5276b10
chore(dev): force IPv4 DNS resolution for child processes
lakunle Apr 30, 2026
bf42125
feat(composio): add Confluence as BYO toolkit
lakunle Apr 30, 2026
785e020
chore(pdf-skills): use fully fictional persona in template examples
lakunle Apr 30, 2026
0fa2e59
docs: add Telegram channel design spec + implementation plan
lakunle Apr 30, 2026
7de56bd
channels: add Channel interface and shared text helpers
lakunle Apr 30, 2026
bf8f594
channels: add Sendblue adapter implementing Channel interface
lakunle Apr 30, 2026
08484e7
channels: add registry, dispatch, and shared runTurn
lakunle Apr 30, 2026
d6ee5f8
sendblue: delegate webhook to channels/runTurn
lakunle Apr 30, 2026
60b0c2e
channels: migrate three outbound sites to dispatch
lakunle Apr 30, 2026
d864266
channels: mount channels via registry instead of direct Sendblue mount
lakunle Apr 30, 2026
c2c51ba
convex: add Telegram dedup, pending-allowlist, allowed-chat-id tables
lakunle Apr 30, 2026
60c2564
convex: add telegramDedup.claim mutation
lakunle Apr 30, 2026
eeeebea
convex: add telegramAllowlist queries and mutations
lakunle Apr 30, 2026
e4f809e
convex: add messages.recentAcrossChannels query
lakunle Apr 30, 2026
2841be2
convex: allow source=transcribe in usageRecords
lakunle Apr 30, 2026
553920b
convex: also add transcribe to usageRecords schema source union
lakunle Apr 30, 2026
98c6711
runtime-config: add active-channel helpers
lakunle Apr 30, 2026
56be02c
channels: record channel-primary on every inbound turn
lakunle Apr 30, 2026
bc130c2
self-tools: add set_active_channel + channel info in get_config
lakunle Apr 30, 2026
8875dab
channels: add getChannelById helper; use it from self-tools
lakunle Apr 30, 2026
a8f5b27
interaction-agent: surface set_active_channel to the dispatcher
lakunle Apr 30, 2026
7172a7d
interaction-agent: union recent history across channels
lakunle Apr 30, 2026
452b147
automations: float to active channel when notifyConversationId is null
lakunle Apr 30, 2026
54bc256
automation-tools: default notifyConversationId to null
lakunle Apr 30, 2026
6e23794
proactive-email: route through resolveActiveChannel
lakunle Apr 30, 2026
091cfe4
server: warn at boot when active channel is misconfigured
lakunle Apr 30, 2026
a9cbdd1
channels/telegram: skeleton with send + typing loop
lakunle Apr 30, 2026
92ea487
channels/telegram: implement webhook (text-only) with dedup + allowlist
lakunle Apr 30, 2026
1399bc5
channels: register the Telegram channel
lakunle Apr 30, 2026
8b95c4f
scripts: add telegram:webhook for auto-registration
lakunle Apr 30, 2026
45b1079
scripts: add telegram:approve interactive CLI
lakunle Apr 30, 2026
948125c
scripts: add telegram:smoke for end-to-end verification
lakunle Apr 30, 2026
a559668
dev: auto-register Telegram webhook and show it in the banner
lakunle Apr 30, 2026
26477e5
setup: add optional Telegram block
lakunle Apr 30, 2026
a60c0e7
env: add Telegram vars; remove BOOP_USER_PHONE
lakunle Apr 30, 2026
94d8bf4
add server/transcribe.ts wrapping OpenAI Whisper API
lakunle Apr 30, 2026
1d7366e
channels/telegram: support inbound voice notes
lakunle Apr 30, 2026
c477e6d
smoke: add voice-note path (opt-in via TELEGRAM_SMOKE_FILE_ID)
lakunle Apr 30, 2026
94d532c
docs: add Telegram channel manual verification checklist
lakunle Apr 30, 2026
023b484
docs: add Telegram setup walkthrough to README
lakunle Apr 30, 2026
4c2169d
automations: restore notify=false for silent automations
lakunle Apr 30, 2026
283aa6a
docs: TELEGRAM_WEBHOOK_SECRET is strongly recommended, not optional
lakunle Apr 30, 2026
1c8e510
docs: CHANGELOG entry for Telegram channel branch
lakunle Apr 30, 2026
82fccc5
pdf: add pdf-pitch skill + landscape/full-bleed render options
lakunle May 1, 2026
40d531b
docs: design spec for inbound file attachments (photos, PDFs, text docs)
lakunle May 1, 2026
5bb7f67
docs: implementation plan for inbound file attachments
lakunle May 1, 2026
6a1fa6b
chore: add pdfjs-dist, @napi-rs/canvas, mammoth for inbound attachments
lakunle May 1, 2026
c2fd935
chore: bump mammoth to 1.12 (security) and @napi-rs/canvas to 0.1.100…
lakunle May 1, 2026
069f624
test: add node:test runner via tsx
lakunle May 1, 2026
4856797
test: add fixture generator + committed binary fixtures
lakunle May 1, 2026
1b4124d
fix: prevent puppeteer browser leak + mark fixture binaries explicitly
lakunle May 1, 2026
d71655d
feat(convex): add optional attachments[] to messages table
lakunle May 1, 2026
b009de5
feat(convex): attachmentStorage upload + sign helpers
lakunle May 1, 2026
06f5500
fix(convex): guard recordUploaded against invalid sizeBytes/mimeType
lakunle May 1, 2026
3862338
feat(convex): messages:send accepts optional attachments[]
lakunle May 1, 2026
c688f49
refactor(convex): extract shared attachments validator to validators.ts
lakunle May 1, 2026
113038c
feat(server): vision.ts — gpt-4o describeImage with cost tracking
lakunle May 1, 2026
e8e23bd
fix(server): vision.ts test env isolation + warn on unknown PRICING m…
lakunle May 1, 2026
c931322
feat(server): docx-extract.ts — mammoth-based .docx → text
lakunle May 2, 2026
562565a
docs(server): correct docx-extract truncation comment + derive marker…
lakunle May 2, 2026
ba9fd23
feat(server): pdf-extract.ts — pdfjs text + selective per-page vision
lakunle May 2, 2026
2fc9783
refactor(server): tighten pdf-extract types + add vision reset for tests
lakunle May 2, 2026
8fe5d0c
feat(server): attachments.ts — single resolver for all inbound files
lakunle May 2, 2026
31c8f7b
refactor(server): tighten attachments resolver — exports, kind dispat…
lakunle May 2, 2026
f503d6c
feat(channels/telegram): handle photos, documents, and unsupported media
lakunle May 2, 2026
1138a18
fix: caption ordering, surface vision model, name extractor tools in …
lakunle May 2, 2026
9a0fe3d
feat(channels/sendblue): handle inbound MMS media + extract shared he…
lakunle May 2, 2026
6b671b0
fix(channels/sendblue): preserve caption on partial-failure + handle …
lakunle May 2, 2026
dd4859d
test: extend telegram smoke with photo, pdf, and unsupported-media ch…
lakunle May 2, 2026
66b04a1
fix(smoke): time-guard photo/pdf/sticker assertions to prevent stale-…
lakunle May 2, 2026
40e133f
docs: env + CHANGELOG for inbound attachments feature
lakunle May 2, 2026
a2388b1
docs: section header for vision env block + clean CHANGELOG bullet + …
lakunle May 2, 2026
1e1f959
fix: wire BOOP_VISION_COST_CAP_USD env + populate messages.attachment…
lakunle May 2, 2026
7cb4df4
Merge feat/inbound-attachments: inbound photo + PDF + .txt/.md/.docx …
lakunle May 2, 2026
658d488
fix(attachments): sniff magic bytes when channel reports application/…
lakunle May 2, 2026
7716c83
feat: native integrations + self-hosted Convex
lakunle May 15, 2026
9557897
feat(browser): credential vault + Steel.dev sessions + login/2FA auto…
lakunle May 15, 2026
ae12bbd
Merge pull request #1 from lakunle/feat/browser-actions
lakunle May 15, 2026
cbc2755
Merge upstream/main: intent-driven dispatcher + local embeddings fall…
lakunle May 15, 2026
ebaeca6
feat(ios): native iOS channel — pairing, bearer auth, SSE streaming
lakunle May 15, 2026
043338c
feat(ios): wire iOS into channel registry + active-channel routing
lakunle May 15, 2026
f2eb94e
feat(ios-app): SwiftUI app M1 — pairing, chat, SSE streaming, history
lakunle May 15, 2026
07400a3
fix(ios): bypass system proxy + SSE delegate rewrite — chat now match…
lakunle May 15, 2026
d3f1c3f
docs: iOS redesign design brief (multi-thread, files, watcher, sleek …
lakunle May 15, 2026
522e6bc
plan(ios): Plan A — Foundation implementation plan
lakunle May 15, 2026
eae5d69
feat(threads): convex threads table + CRUD helpers
lakunle May 15, 2026
68395dc
fix(threads): use .take() for bounded reads, server-side timestamps, …
lakunle May 15, 2026
29910be
feat(threads): messages table tracks threadId
lakunle May 15, 2026
b6caca2
feat(channels): parse ios:<deviceId>:<threadId> conversation ids
lakunle May 15, 2026
32e5e2d
feat(ios): thread-aware endpoints (/threads, /inbound, /messages, /st…
lakunle May 15, 2026
1b0009c
feat(ios): set_thread_icon self-tool + dispatcher prompt addendum
lakunle May 15, 2026
268db98
test(ios): HTTP smoke for /channels/ios/threads
lakunle May 15, 2026
15ac679
feat(ios): bundle Inter + JetBrains Mono fonts
lakunle May 15, 2026
02dcaa5
feat(ios): design-system tokens — Colors, Typography, Spacing
lakunle May 15, 2026
de5dfca
feat(ios): 8-color per-thread tint palette w/ FNV-1a hash
lakunle May 15, 2026
797f152
feat(ios): bundle Lucide icons as vector PDF assets + LucideIcon view
lakunle May 15, 2026
76407b7
feat(ios): thread-aware Models / ThreadsStore / ChatStore / BoopClient
lakunle May 15, 2026
762268c
feat(ios): TypingBubble component matching design
lakunle May 15, 2026
32a3084
feat(ios): MarkdownView — block-level + AttributedString inline
lakunle May 15, 2026
7d7f9fb
feat(ios): MessageBubble (markdown) + FileCard components
lakunle May 15, 2026
3f4653b
feat(ios): SubAgentPill component
lakunle May 15, 2026
0527de0
feat(ios): Dock — composer + thread bar in one glass surface
lakunle May 15, 2026
ff204c7
feat(ios): MenuSheet — bottom sheet 2x2 cards
lakunle May 15, 2026
4bdf8d7
feat(ios): FilePreviewScreen — full-screen viewer with action bar
lakunle May 15, 2026
3513505
feat(ios): redesigned ChatView + RootView wiring + Pairing/Settings r…
lakunle May 15, 2026
34ddf52
docs: changelog for iOS redesign Plan A
lakunle May 15, 2026
5dcccb5
feat(ios): Files screen, Live Agents, and attachment streaming
lakunle May 19, 2026
c49a78e
feat(ios): archived UI + APNs push + permanent thread deletion
lakunle May 20, 2026
2701f45
docs: design spec for iOS local message cache
lakunle May 20, 2026
201326a
docs: implementation plan for iOS message cache
lakunle May 20, 2026
825625e
feat(ios): /inbound returns userMessageId for optimistic-send reconci…
lakunle May 20, 2026
3762079
fix(ios): plumb turnId through precomputed-message persist path
lakunle May 20, 2026
64be54c
feat(ios): CachedModels — Codable on-disk shapes for message cache
lakunle May 20, 2026
bc8ad9d
feat(ios): MessageCache actor — debounced JSON-file disk cache
lakunle May 20, 2026
5450b3b
fix(ios): use debounceNanos constant + log write failures in MessageC…
lakunle May 20, 2026
de40312
feat(ios): stamp optimistic user-send with server userMessageId
lakunle May 20, 2026
95af052
refactor(ios): ChatStore — perThread dict, computed messages
lakunle May 20, 2026
60910bf
fix(ios): target sending thread for userMessageId stamp
lakunle May 20, 2026
265f97b
feat(ios): cache-first switchTo + background refreshFromServer
lakunle May 20, 2026
9bb3e92
fix(ios): cache merge correctness — synthetic ids, switch race, attac…
lakunle May 20, 2026
1d1d782
feat(ios): ThreadsStore hydrates from + writes back to MessageCache
lakunle May 20, 2026
d7b0081
fix(ios): debounce threads-list writes + close activeThreadId crash w…
lakunle May 20, 2026
b6b07f5
feat(ios): wire cache hydration into RootView + scenePhase flush
lakunle May 20, 2026
827a07f
docs(ios): clarify cache-purge race semantics in PairingStore.reset
lakunle May 20, 2026
0341c98
docs: iOS message cache — CHANGELOG + README updates
lakunle May 20, 2026
9606531
feat(ios): top-fade gradient on ChatView so chat feels taller
lakunle May 20, 2026
5d63892
chore(ios): bump CURRENT_PROJECT_VERSION to 5
lakunle May 21, 2026
83e7515
docs(ios): add dock redesign + chat UX polish spec
lakunle May 21, 2026
67712a7
docs(ios): add dock redesign + chat UX polish implementation plan
lakunle May 21, 2026
f5b0ab8
feat(ios): add DraftAttachment model for composer chips
lakunle May 21, 2026
ff79c23
feat(ios): ChatStore draft-attachment chip state + send stub
lakunle May 21, 2026
a683eb4
feat(ios): add ToastView for non-error transient banners
lakunle May 21, 2026
d5c6bcc
feat(ios): add AttachmentChipRow component
lakunle May 21, 2026
2cd3fb1
feat(ios): add AttachPicker view modifier
lakunle May 21, 2026
eca2d6a
feat(ios): dock rewrite — composer + welded active tab geometry
lakunle May 21, 2026
ada4159
feat(ios): dock — sliding welded tab + bare inactive icons
lakunle May 21, 2026
6cd3ef2
feat(ios): dock — collapse slot row when keyboard is up
lakunle May 21, 2026
8f0aa00
feat(ios): dock — wire attach picker + chip row
lakunle May 21, 2026
6ba44ef
fix(ios): host Dock in safeAreaInset so chat auto-scroll lands above it
lakunle May 21, 2026
c56636e
chore(ios): hoist attachments-toast text to ChatStore static
lakunle May 21, 2026
080f108
fix(ios): dock — chips-only send + active-tab archive + reduce-motion
lakunle May 21, 2026
71a1d77
chore(ios): silence PDFKit Sendable warning via @preconcurrency import
lakunle May 21, 2026
06a4de4
chore(ios): bump CURRENT_PROJECT_VERSION to 6 for TestFlight build
lakunle May 21, 2026
1c74f55
fix(ios): make dock buttons fully hit-testable + surface threads errors
lakunle May 22, 2026
5202b89
docs(ios): M2 voice mode design spec (interactive HTML)
lakunle May 23, 2026
976b762
docs(ios): M2 voice mode implementation plan (interactive HTML)
lakunle May 23, 2026
0571ee2
feat(server): thread source+voiceTurnId through ParsedInbound and run…
lakunle May 23, 2026
4b86862
refactor(server): clarify ParsedInbound.voiceTurnId coupling in JSDoc
lakunle May 23, 2026
9179f49
feat(server): voice-mode system prompt addendum, conditional on source
lakunle May 23, 2026
9adba7c
test(server): collapse misleading 'sms source' test into honest 'abse…
lakunle May 23, 2026
5bbc4df
feat(server/ios): accept source+voiceTurnId on /inbound; pass to runTurn
lakunle May 23, 2026
5b327c5
fix(server/ios): reject whitespace-only voiceTurnId on /inbound
lakunle May 23, 2026
38e5918
feat(server/voice): SentenceBuffer for token-stream-to-sentence chunking
lakunle May 23, 2026
6d9724a
fix(server/voice): SentenceBuffer ignores push/flush after dispose
lakunle May 23, 2026
639a371
feat(server/voice): markdown-strip for AVSpeech fallback path
lakunle May 23, 2026
1cda743
fix(server/voice): markdown-strip preserves underscores in identifiers
lakunle May 23, 2026
6578a5b
feat(server/voice): ElevenLabs WS adapter (Flash v2.5 streaming)
lakunle May 23, 2026
81effa2
fix(server/voice): guard send() after end() + clear zombie close-timeout
lakunle May 23, 2026
f08aaf2
feat(server/voice): TtsSidecar orchestrator (ElevenLabs + fallback)
lakunle May 23, 2026
5c17aca
fix(server/voice): TtsSidecar — sticky fallback on mid-turn error + d…
lakunle May 23, 2026
0d967db
feat(server): spawn TtsSidecar for voice-source turns; allowlist tts_…
lakunle May 23, 2026
e3e99ab
docs(env): document ELEVENLABS_* vars for voice mode
lakunle May 23, 2026
90d5740
test(voice): e2e integration covers fallback + ElevenLabs paths
lakunle May 23, 2026
538f594
feat(ios): add lottie-ios SPM + LottieOrbView SwiftUI wrapper
lakunle May 23, 2026
a37ddf9
feat(ios): VoiceModeSheet skeleton + wire dock voiceModeButton
lakunle May 23, 2026
c9370d1
fix(ios): voice mode sheet full-screen detent + dock.voice id + MainA…
lakunle May 23, 2026
f36f171
feat(ios): voice permissions card + mic/speech consent flow
lakunle May 23, 2026
841de13
feat(ios): VoiceSession actor — AVAudioSession + engine lifecycle
lakunle May 23, 2026
00507d8
feat(ios): SFSpeechRecognizer + VAD wired into VoiceSession
lakunle May 23, 2026
166231c
feat(ios): SSE StreamEvent gains tts_chunk/done/error/use_local cases
lakunle May 23, 2026
1350721
feat(ios): AudioQueue actor — chunk reassembly + AVAudioPlayerNode
lakunle May 23, 2026
b36755e
feat(ios): wire VoiceModeStore state machine + Lottie orbs
lakunle May 23, 2026
bd53907
fix(ios): voice store lifecycle — hoist to @State + idempotency + tea…
lakunle May 23, 2026
db4eba1
feat(ios): controls polish + Reduce Motion fallback + UI smoke test
lakunle May 23, 2026
11382ed
docs(ios): voice mode README + Boop IOS Design M2 status block
lakunle May 23, 2026
6c8580f
chore(ios): bump CURRENT_PROJECT_VERSION to 8 for M2 TestFlight
lakunle May 23, 2026
acf43bb
fix(ios): voice mode error copy reflects actual UX (no tap-to-retry yet)
lakunle May 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .agents/skills/convex-create-component/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: convex-create-component
description: Designs and builds Convex components with isolated tables, clear boundaries, and app-facing wrappers. Use this skill when creating a new Convex component, extracting reusable backend logic into a component, building a third-party integration that owns its own tables, packaging Convex functionality for reuse, or when the user mentions defineComponent, app.use, ComponentApi, ctx.runQuery/runMutation across component boundaries, or wants to separate concerns into isolated Convex modules.
description: Builds reusable Convex components with isolated tables and app-facing APIs. Use for new components, reusable backend modules, integrations, or component boundary work.
---

# Convex Create Component
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/convex-migration-helper/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: convex-migration-helper
description: Plans and executes safe Convex schema and data migrations using the widen-migrate-narrow workflow and the @convex-dev/migrations component. Use this skill when a deployment fails schema validation, existing documents need backfilling, fields need adding or removing or changing type, tables need splitting or merging, or a zero-downtime migration strategy is needed. Also use when the user mentions breaking schema changes, multi-deploy rollouts, or data transformations on existing Convex tables.
description: Plans Convex schema and data migrations with widen-migrate-narrow and @convex-dev/migrations. Use for breaking schema changes, backfills, table reshaping, or zero-downtime rollouts.
---

# Convex Migration Helper
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/convex-performance-audit/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: convex-performance-audit
description: Audits and optimizes Convex application performance across hot-path reads, write contention, subscription cost, and function limits. Use this skill when a Convex feature is slow or expensive, npx convex insights shows high bytes or documents read, OCC conflict errors or mutation retries appear, subscriptions or UI updates are costly, functions hit execution or transaction limits, or the user mentions performance, latency, read amplification, or invalidation problems in a Convex app.
description: Audits Convex performance for reads, subscriptions, write contention, and function limits. Use for slow features, insights findings, OCC conflicts, or read amplification.
---

# Convex Performance Audit
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/convex-quickstart/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: convex-quickstart
description: Initializes a new Convex project from scratch or adds Convex to an existing app. Use this skill when starting a new project with Convex, scaffolding with npm create convex@latest, adding Convex to an existing React, Next.js, Vue, Svelte, or other frontend, wiring up ConvexProvider, configuring environment variables for the deployment URL, or running npx convex dev for the first time, even if the user just says "set up Convex" or "add a backend."
description: Creates or adds Convex to an app. Use for new Convex projects, npm create convex@latest, frontend setup, env vars, or the first npx convex dev run.
---

# Convex Quickstart
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/convex-setup-auth/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: convex-setup-auth
description: Sets up Convex authentication with user management, identity mapping, and access control. Use this skill when adding login or signup to a Convex app, configuring Convex Auth, Clerk, WorkOS AuthKit, Auth0, or custom JWT providers, wiring auth.config.ts, protecting queries and mutations with ctx.auth.getUserIdentity(), creating a users table with identity mapping, or setting up role-based access control, even if the user just says "add auth" or "make it require login."
description: Sets up Convex auth, identity mapping, and access control. Use for login, auth providers, users tables, protected functions, or roles in a Convex app.
---

# Convex Authentication Setup
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/convex/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: convex
description: Routing skill for Convex work in this repo. Use when the user explicitly invokes the `convex` skill, asks which Convex workflow or skill to use, or says they are working on a Convex app without naming a specific task yet. Do not prefer this skill when the request is clearly about setting up Convex, authentication, components, migrations, or performance.
description: Routes general Convex requests to the right project skill. Use when the user asks which Convex skill to use or gives an underspecified Convex app task.
---

# Convex
Expand Down
312 changes: 312 additions & 0 deletions .claude/skills/boop-design/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
---
name: boop-design
description: Boop's design law book. Use when generating any visual artifact (PDFs, HTML, slide layouts) to enforce typography, color (OKLCH), spacing, and motion rules. Required reading before producing visual output.
user-invocable: false
---

# Boop Design Skill

When any design task arrives — a screenshot, a Figma link, a PRD, a question about UI — load this skill first. It defines how to think, what to check, and what to produce.

---

## 1. Design Laws

These are non-negotiable. Violations are always flagged, regardless of task type.

### Color
- Use **OKLCH** color space exclusively for any color specification. Never hex-first, never HSL-first.
- All color values must have **semantic names** (`color-action-primary`, `color-feedback-error`) — never bare values in specs.
- **One Voice Rule**: one accent color, ≤10% surface coverage. A page with three "accent" colors has no accent.
- Surfaces should be near-neutral. Color earns meaning through restraint.
- Status must never be communicated by color alone (WCAG 1.4.1). Always pair with icon, label, or pattern.

### Typography
- Body line length: **65–75 characters maximum**. Beyond that, the eye loses the return trip.
- Weight contrast between heading and body: **≥1.25 stops** on the type scale. If the hierarchy isn't visible, it isn't hierarchy.
- **Never use Inter without a reason.** Inter is a default, not a choice. If a product is using Inter, ask: *why this face, not another?* If the answer is "it was the default," flag it.
- Minimum body text: **16px / 1rem**. No exceptions for "secondary" or "supporting" copy.
- Line-height for body: **1.5–1.6**. For headings: **1.1–1.25**.

### Layout
- **Vary spacing deliberately.** Uniform 16px everywhere is not a spacing system — it's an absence of one. Use a scale (4/8/12/16/24/32/48/64) and choose intentionally.
- **No card nesting.** A card inside a card creates depth without meaning. Flatten.
- **No identical card grids.** If all cards are the same size, weight, and content shape, you have a list with padding. That's fine — call it a list.
- Whitespace is not empty space. It is the loudest element on the page.

### Motion
- **Easing: ease-out exponential** for entrances. Things that arrive should decelerate, as if placing an object down.
- **Never animate layout properties** (height, width, top, left, margin, padding). Animate transform and opacity only.
- **No bounce easing in product UI.** Bounce belongs in games and onboarding celebrations, not in data tables.
- Duration: 150–250ms for micro-interactions, 300–400ms for page-level transitions.

### Absolute Bans
These patterns are blocked. If found, flag as **blocking severity** regardless of execution quality.

| Anti-Pattern | Why Banned |
|---|---|
| Side-stripe "accent" borders (left-border as visual interest) | Decoration masquerading as structure |
| Gradient text | Legibility hazard; WCAG failure risk; visual noise |
| Decorative glassmorphism | Backdrop blur without functional meaning is pixel waste |
| Hero-metric card templates (big number, label, sparkline, repeated ×6) | Copy-paste dashboards that communicate nothing |
| Modal-first thinking | Modals interrupt. Use inline, drawer, or contextual disclosure first |

---

## 2. Design Critique Protocol

Use this when asked to review a design, screenshot, or Figma output.

### Step 1: Load Context
Before scoring anything, establish:
- **What product is this?** (tool, consumer app, dashboard, marketing site)
- **Who is the user?** (technical, non-technical, high-frequency, occasional)
- **What platform?** (iOS, Android, web desktop, web mobile, cross-platform)
- **What moment in the journey?** (first use, habitual use, recovery, offboarding)

If context is missing, ask for it before proceeding. A critique without context is noise.

### Step 2: Heuristic Scan

Score each dimension **1–5** with at least one specific piece of evidence. Do not give 3s without explanation — "average" is not an observation.

| Dimension | What to Evaluate |
|---|---|
| **Typography** | Scale, weight contrast, line length, font choice, hierarchy legibility |
| **Color** | Palette restraint, semantic clarity, contrast ratios, One Voice compliance |
| **Layout** | Spacing system, alignment, information density, visual rhythm |
| **Hierarchy** | Can you tell what to look at first, second, third? |
| **Interaction** | Are affordances visible? Are states (hover, active, disabled, loading) defined? |
| **UX Writing** | Are labels clear, buttons action-object, errors recoverable? |

### Step 3: Anti-Pattern Scan
Cross-reference against the Anti-Pattern Detector (Section 5). List every hit with its severity.

### Step 4: Flag and Prioritize
Severity levels:
- **Blocking** — ships broken (WCAG failure, missing states, absolute ban violation)
- **Major** — ships diminished (hierarchy failure, unclear affordances, copy-paste template)
- **Minor** — ships slightly worse (spacing inconsistency, weight could be stronger)

### Step 5: Output

Produce:
1. **Scores** — 6 dimensions, 1–5, one-line evidence each
2. **Anti-patterns found** — list with severity
3. **Top 3 Fixes** — ordered by impact, written as actionable instructions, not observations

> ✅ Format: Score table → Anti-pattern list → 3 numbered fixes. No more than 400 words total unless depth was requested.

---

## 3. PRD Design Review Protocol

Use this when asked to review a product spec, requirements doc, or feature brief for design gaps.

### Gate Check
First: is this a PRD (requirements/spec) or a design (visual artifact)? If it's a design, use Section 2 instead.

### The Six Gap Checks

Run each check in order. For each: **pass**, **partial**, or **missing** — and if partial or missing, write the specific gap.

**Check 1: Are user flows described visually or only textually?**
- Pass: flows are diagrammed, or steps are numbered with explicit branching logic
- Partial: flows are described in prose but branching is implicit
- Missing: "the user navigates to the settings page" with no entry/exit/error path

**Check 2: Are edge cases covered?**
Specifically look for:
- Empty state (first use, zero results, cleared data)
- Error state (network failure, validation failure, permission denied)
- Loading state (initial load, pagination, async action in progress)
- Partial data (one item, one character, maximum limits)

Flag each missing state by name.

**Check 3: Is the interaction model explicit?**
- Tap target sizes specified (minimum 44×44pt / 48×48dp)?
- Gestures named and fallback defined?
- Transitions described (what animates, how, when)?
- Keyboard/focus order considered?

**Check 4: Is UX writing specified?**
- Button labels defined (not just "CTA")?
- Error messages written out, not described?
- Empty state copy provided?
- Confirmation dialogs written?

If UX writing is deferred ("copy TBD"), flag it — copy is not a finishing step, it is a structural decision.

**Check 5: Are accessibility requirements present?**
- WCAG level target stated (AA minimum)?
- Screen reader behavior described for custom components?
- Color contrast requirements referenced?
- Focus management for modals/drawers specified?

**Check 6: Are design system constraints referenced?**
- Does the spec reference existing components or invent new ones?
- Are new components justified?
- Is the spec consistent with platform conventions (iOS HIG, Material, etc.)?

### Output Format
```
PRD Design Gap Report

✅ Pass | ⚠️ Partial | ❌ Missing

[Check 1–6 results]

Priority Gaps:
1. [Highest impact gap] — [suggested resolution]
2. ...
3. ...
```

---

## 4. UX Writing Rules

Apply these when writing copy in specs, or when critiquing copy in designs.

### Error Messages
**Formula: [What happened] + [Why] + [What to do next]**

- ❌ "Something went wrong."
- ❌ "Error 403."
- ✅ "We couldn't save your changes. Your session expired — sign in again to continue."

Every error message must answer: *can the user recover from this, and do they know how?*

### Buttons
**Format: Action + Object**

- ❌ "OK", "Submit", "Continue", "Yes"
- ✅ "Save changes", "Delete project", "Send invite", "Try again"

The button label should be readable as a sentence fragment the user is authorizing: *I want to [button label].*

Exception: secondary/cancel actions may be single words ("Cancel", "Dismiss") when the primary action is fully labeled.

### Empty States
**Treat as onboarding, not as absence.**

An empty state is the first touchpoint for a feature. It should:
1. Name what would be here when it's not empty
2. Explain why it's empty (first use vs. cleared vs. filtered)
3. Give a single clear action to fill it

- ❌ "No results found."
- ✅ "No projects yet. Create your first project to get started." + [Create project] button

### Microcopy
**Specific beats generic.**

- ❌ "Are you sure?"
- ✅ "Delete 'Q4 Campaign'? This can't be undone."

- ❌ "Loading..."
- ✅ "Loading your projects..." or (better) a skeleton screen with no copy at all

### Tone Calibration
Match the product's register:
- **Tool/productivity**: direct, minimal, never cute
- **Consumer/social**: warm, human, allowed to have personality
- **Health/finance/legal**: calm, confident, never breezy
- **Developer tool**: precise, no hand-holding, trust the user

---

## 5. Anti-Pattern Detector

Run this scan on any design artifact. Flag every hit.

### Visual Anti-Patterns

| Pattern | Severity | How to Spot |
|---|---|---|
| **Gradient text** | Blocking | `background-clip: text` on headings; multi-stop colored gradients on any label |
| **Side-stripe borders** | Blocking | `border-left: 4px solid accent` used as decoration, not status |
| **Hero metric cards × N** | Major | Dashboard with 4–8 identical cards: big number, label, tiny sparkline |
| **Decorative glassmorphism** | Major | `backdrop-filter: blur` on elements with no layering purpose |
| **Rainbow palette** | Major | More than 3 distinct hues in the UI chrome (excluding data visualization) |
| **Flat flat flat** | Minor | Zero elevation, zero contrast between surface levels — everything reads as one plane |

### Typography Anti-Patterns

| Pattern | Severity | How to Spot |
|---|---|---|
| **Inter by default** | Minor–Major | Inter used with no explicit rationale; no alternate considered |
| **Weak hierarchy** | Major | Heading and body differ by ≤1 weight step and ≤2px size |
| **Tiny body text** | Blocking | Any readable body copy below 16px |
| **Measure overflow** | Minor | Text columns wider than ~75 characters |
| **All-caps body** | Major | Paragraphs or sentences in uppercase |

### Interaction Anti-Patterns

| Pattern | Severity | How to Spot |
|---|---|---|
| **Hover-only affordance** | Blocking | Actions only revealed on hover — invisible on touch, keyboard, or first glance |
| **Confirmation modals for simple actions** | Major | "Are you sure?" modal for reversible or low-stakes actions |
| **Missing loading states** | Major | Async actions with no spinner, skeleton, or progress indicator |
| **Disabled buttons without explanation** | Minor | Greyed button with no tooltip or inline copy explaining why |
| **Infinite scroll without escape** | Major | No pagination fallback, no "back to top", no way to link to position |

### Accessibility Anti-Patterns

| Pattern | Severity | How to Spot |
|---|---|---|
| **Color-only status** | Blocking | Red/green used alone to indicate error/success with no icon or label |
| **WCAG AA failure** | Blocking | Text contrast ratio below 4.5:1 (normal), 3:1 (large/bold) |
| **Missing focus styles** | Blocking | `outline: none` or `outline: 0` without a custom visible replacement |
| **Icon-only buttons** | Major | Clickable icons with no accessible label (`aria-label` or visible text) |
| **Motion without respect** | Major | Animations that do not respect `prefers-reduced-motion` |

---

## 6. Commands

When a message matches one of these intents, map it to the corresponding protocol.

### "critique this design" / "give me feedback on this" / "review this UI"
→ Run **Section 2: Design Critique Protocol** in full.
→ Deliver: scores, anti-patterns, top 3 fixes.
→ Ask for context (product, user, platform) if not provided.

### "review PRD for design gaps" / "does this spec cover design?" / "what's missing from this PRD?"
→ Run **Section 3: PRD Design Review Protocol** in full.
→ Deliver: six-check gap report, priority gaps with resolutions.

### "is this good design?" / "what do you think of this?"
→ Quick 3-point assessment only:
1. Strongest element (what's working and why)
2. Biggest single problem (most impactful fix)
3. One anti-pattern flag if found, or "none detected"
→ Under 150 words. Offer full critique if they want more.

### "what's wrong with this?" / "find the problems" / "roast this"
→ Run **Section 5: Anti-Pattern Detector** only.
→ List every hit, sorted by severity (blocking first).
→ No scores, no positives — they asked for problems.

### "write a design spec for X"
→ Produce a structured spec with these sections:
1. **Overview** — what this feature is, who it's for, what platform
2. **User flows** — numbered steps with explicit branching (happy path + error path + empty state)
3. **States** — enumerate every state: default, loading, empty, error, success, disabled, edge cases
4. **UX writing** — all visible copy: headings, labels, buttons, errors, empty states, confirmations
5. **Interaction notes** — transitions, tap targets, gestures, keyboard behavior
6. **Accessibility requirements** — contrast targets, ARIA roles for custom components, focus order
7. **Open questions** — unresolved decisions that need product/engineering input
→ Apply Section 4 UX Writing Rules throughout.

---

## Boop's Design Voice

When delivering design feedback over iMessage:
- **Short verdict first.** One sentence. Then evidence.
- **Name the problem specifically.** Not "hierarchy could be better" — "the page title and section headers are the same weight, so there's no hierarchy."
- **Give the fix, not just the diagnosis.** Every flag should end with a direction.
- **Don't soften blocking issues.** "This fails WCAG AA" is accurate and kind. Softening it ("might want to consider contrast") makes it ignorable.
- **Celebrate what works.** Good design decisions deserve acknowledgment. It sharpens the credibility of the critique.
Loading