Join the Agent Deck Discord Server!
Discord에서 Agent Deck 커뮤니티 확인, 357명과 자유 음성·텍스트 채팅 이용
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Stop scrolling. Start living.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Anti-doomscrolling · Stop scrolling, start living.
Click Web extends the same philosophy as the mobile app: fewer infinite feeds, more real-world presence. The dashboard and APIs exist to support verified connection, venue intelligence, and voice—not to recreate doomscroll loops in the browser.
The insights, graph validation, and web-calling companion for Click.README 전문 보기 ↗Anti-doomscrolling · Stop scrolling, start living.
Click Web extends the same philosophy as the mobile app: fewer infinite feeds, more real-world presence. The dashboard and APIs exist to support verified connection, venue intelligence, and voice—not to recreate doomscroll loops in the browser.
The insights, graph validation, and web-calling companion for Click.
Click Web is the Next.js companion to the Kotlin Multiplatform (KMP) mobile app. It brings authenticated users a dashboard with real-time chat, optional WebRTC voice through LiveKit, B2B analytics for venues and promoters, and secure auth redirects (including email verification).
<@) so “is this set of user IDs a fully connected clique under verified edges?” stays a single indexed lookup, not an exploratory graph crawl.| Area | What it does |
|---|---|
| Web-based VoIP (dormant) | Calling controls are removed from the web UI (as on iOS). The LiveKit token route, livekit-client integration, and push payload shapes remain in place for future work. |
| Real-time chat | Chat UI syncs with Supabase-backed data; API routes under app/api/chat/ support messages, reactions, and related flows. |
| Home recap | GET /api/me/recap?window=day|week returns a zeroed 200 payload when the caller has no active handshake records in the window (archived / hidden connections and missing columns do not 500). |
| Map beacons | GET/POST /api/beacons, plus POST /api/beacons/image for unencrypted beacon photos (max 2 MB; optional, as on mobile). Pin/popup and card identity uses lib/ui/generateCardVisual.ts + components/ui/CardVisualSurface.tsx (mirrors mobile). |
| Events | Public /events directory and /e/{id} microsite (guest RSVP, no account). Create from dashboard Events tab, /events/new, or Insights Events (not Vibe Radar deploy). |
| Business insights & heatmaps | Insights under app/insights/ (heatmap, live metrics, vibe stream, tribes, social activity) with APIs under app/api/insights/. |
| Secure auth callbacks | Email verification, PKCE, token-hash, and legacy hash flows—see app/auth/callback/page.tsx and app/api/auth/callback/route.ts. |
Click for Business is the monetization layer for local venues, promoters, and event operators who care about who actually showed up together, not just raw door counts.
Because Click verifies physical group cliques (not assumed friend graphs), venues see verified social factions—cohorts that arrived and connected as real groups. Example narrative: “30% of attendees arrived as part of a verified Indie Rock micro-community.” That is foot traffic plus social topology, grounded in handshake integrity.
The dashboard surfaces a Social Sticky Score: composite metrics for connection density (how often verified cliques form on-site) and connection survival (whether those connections persist and re-engage after the event). It is designed to prove real-world community ROI—sticky social outcomes venues can cite beyond impressions or check-ins.
"use client" only where needed (hooks, window, LiveKit, Framer Motion).@supabase/ssr, @supabase/supabase-js), Postgres, Edge Functions (push, proximity clustering, validation-adjacent workflows).app/api/livekit/token/route.ts). Custom React on the JS client.Other libraries include Framer Motion, MapLibre GL, Recharts, SWR, Lucide, and Radix.
app/ — App Router pages, layouts, and Route Handlers (app/api/**).components/ — Dashboard, chat, insights, modals.lib/ — Supabase clients, auth helpers, config.middleware.ts — Session refresh / auth cookies.cd click-web
npm install
Create .env.local in the click-web directory (never commit secrets). .env.example and .env.local.example list every documented variable and are committed so GitHub Actions and Cloudflare Workers Builds can materialize a complete env (scripts/materialize-ci-env.sh) without empty keys. Overlay real values from repo/dashboard secrets when they are set.
Required (core app + Supabase client)
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase anonymous (public) key |
Server-only (recommended for production APIs)
| Variable | Purpose |
|---|---|
SUPABASE_SERVICE_ROLE_KEY | Elevated access for select API routes when anon scope is insufficient |
LiveKit (Web calling)
| Variable | Purpose |
|---|---|
LIVEKIT_API_KEY | LiveKit API key |
LIVEKIT_API_SECRET | LiveKit API secret |
LIVEKIT_WS_URL or LIVEKIT_URL | WebSocket URL for the LiveKit server. Host-only values from the LiveKit Cloud dashboard (click-….livekit.cloud) are normalized to wss://. |
These must be set on the Cloudflare Worker click-web (Workers dashboard → Settings → Variables and secrets), not GitHub Actions Variables. GitHub Actions env does not reach production. Deploy with npm run deploy (opennextjs-cloudflare deploy -- --keep-vars) so dashboard secrets are not wiped.
Unauthenticated POST /api/livekit/token returns 401 and does not prove these vars are set. After deploy:
GET /api/health/env with x-click-health-secret: <HEALTH_DIAGNOSTICS_SECRET> — keys.LIVEKIT_API_KEY / LIVEKIT_API_SECRET / LIVEKIT_WS_URL should be true (presence only; values are never returned). Without that header the endpoint returns coarse liveness only.curl -i -X POST https://joinclick.co/api/livekit/token \
-H "Authorization: Bearer <SUPABASE_ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"connection_id":"<id>","room_name":"click-<id>-x","participant_name":"probe"}'
500 LiveKit environment is not configured means the Worker still cannot see the vars (wrong surface, or deploy without --keep-vars). 200 + JWT means minting works; remaining call failures are client-side.
Optional
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_BASE_URL | Canonical site URL (https://joinclick.co); falls back to VERCEL_URL in some routes |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | Google OAuth if enabled |
NEXT_PUBLIC_IOS_STORE_URL / NEXT_PUBLIC_ANDROID_STORE_URL | Store links (lib/config.ts) |
NEXT_PUBLIC_APP_LAUNCHED | Set to true when the app is publicly launched |
HEALTH_DIAGNOSTICS_SECRET | Protects detailed /api/health/env diagnostics; without the matching x-click-health-secret header callers receive coarse liveness only |
CLICK_ENABLE_SIMULATOR_MOCK + CLICK_APP_ENV | Nonproduction-only proximity fixture gate. Set CLICK_ENABLE_SIMULATOR_MOCK=true only when CLICK_APP_ENV is not production. |
npm run dev
Open http://localhost:3000.
Unit / component (Jest):
npm test
End-to-end UI (Maestro, Chromium; Beta). Install the CLI (Java 17+), start the app, then:
curl -fsSL "https://get.maestro.mobile.dev" | bash
npm run dev # or npm run build && npm start
npm run test:e2e
Flows set a literal url: http://localhost:3000 (Maestro 2.8 leaves ${BASE_URL} unexpanded in the url: field, which opens Chromium at data:). They then launchApp.appId=${BASE_URL} (same-tab CDP navigation). Do not use openLink on web (second window; Maestro reads the leftover blank tab) or launchApp.clearState (wipes the tab back to data:). Text asserts must match accessibility-tree nodes: styled spans split strings such as "About Click", so smoke flows use unsplit copy (Stop scrolling. Start living.) and heading ids.
Override the origin after that with -e BASE_URL=https://joinclick.co (or a preview URL). Authenticated dashboard chrome:
maestro test .maestro/auth --include-tags auth \
-e BASE_URL=http://localhost:3000 \
-e [email protected] \
-e TEST_PASSWORD=secret
Flows live in .maestro/. Jest stays the unit suite; Maestro covers real browser journeys (landing — including not showing Loading your connections for anonymous / — legal pages, playground). CI: .github/workflows/e2e.yml pins Chrome 152 to match Maestro's bundled ChromeDriver, wraps /usr/bin/google-chrome with prepended --no-sandbox, and runs Maestro headed under Xvfb (maestro test --headless makes Chrome --headless=new, which leaves Maestro querying an empty CDP target). Local npm run test:e2e stays headed. Do not Maestro LiveKit rooms. Cloudflare deploys need npm run build:worker. GitHub build-worker proves the artifact. Workers Builds production uses dashboard npm run deploy (empty build command). npm run build must stay next build because OpenNext invokes it; do not switch it to OpenNext when WORKERS_CI=1.
click-web is the browser companion to the KMP mobile app (click/). Mobile owns in-room discovery (Tri-Factor, sensors, native push); web owns the authenticated dashboard, B2B Click Insights, and HTTP BFF routes mobile calls over CLICK_WEB_BASE_URL.
Yes for most post-connection experiences: connections inbox, map, timeline, E2EE chat (pins, mutes, plans, scheduled messages), event chat, QR identity, availability intents, stats, and collaboration hooks (components/DashboardView.tsx).
No for hardware-native flows: BLE + ultrasonic + progressive GPS orchestration, Multi-Tap initiation in a physical room, sensor capture at handshake time, CallKit/PushKit/FCM wake, App Clip, and device calendar integration. Web can display Memory Capsule data captured on mobile but cannot produce the same sensor readings.
click (KMP) ──Tri-Factor/QR──► Supabase Edge + Postgres
│ ▲
│ CLICK_WEB_BASE_URL │ aggregates
▼ │
click-web ──dashboard/chat/insights──┘
Mobile is the primary data producer for B2B insights (connections, encounters, availability intents with include_in_business_insights). Web is the operator surface for /insights/* and the consumer dashboard for browser users.
| Category | Mobile | click-web |
|---|---|---|
| Tri-Factor / Multi-Tap initiation | Primary | Not achievable (hardware) |
| QR connect | Via web HTTP APIs | Full parity |
| Dashboard (table, map, timeline) | Yes | Full parity — lib/dashboard/README.md |
| E2EE chat | MessageCrypto | Full parity — lib/chat/README.md |
| Voice/video | LiveKit native | Web parity — /api/livekit/token |
| Availability intents | Yes | Partial (UI yes; match pushes mobile-first) |
| Memory Capsules | Capture + display | Display only |
| Prior Connections | On-device contact hashing + skippable onboarding | Discover / request / respond APIs + profile badge |
| Community Hubs | Mobile UI | Hubs tab: discovery, create/join/leave, text and encrypted attachments — lib/hub/README.md |
| Home connection insights | ReconnectHelper | Insights, reconnect suggestions and archive warning |
| Home recap and saved events | Day/week recap + bookmarks | Day/week recap and saved-event links |
| B2B Click Insights | widget-vibe consumer | Web-only — lib/insights/README.md |
Detailed matrices live in colocated module READMEs: lib/dashboard/README.md, lib/connections/README.md, lib/insights/README.md. Mobile companion context: click/README.md § Monorepo note.
Web actions that wake mobile or mirror app contracts—especially incoming call push payloads—must stay aligned with the KMP app. Example: DashboardView.tsx documents parity with CallPushNotifier.kt for the send-push-notification Edge Function and incoming_call data shape. E2EE wire format must match KMP MessageCrypto (lib/chat/README.md). When changing call, notification, or crypto flows, update both clients and any Edge Function schema. See AI.md §2 for field-name rules.
The browser calls Supabase Edge Functions with supabase.functions.invoke(). CORS applies. Each invoked function must respond correctly to OPTIONS preflight and return appropriate Access-Control-* headers for your web origin.
Production is the Cloudflare Worker click-web. Set runtime variables on the Workers dashboard (not GitHub Actions Variables). npm run deploy uses --keep-vars so dashboard secrets survive the upload. Ensure Supabase Auth → URL configuration (site URL, redirect URLs) includes https://joinclick.co.
This package is part of the broader Click Platforms workspace. For the KMP client and shared product context, see click/README.md and any workspace root docs.