Serein
Rust로 만든 가볍고 성능 좋은 Discord 전용 네이티브 클라이언트
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A private, invite-only place for a group of friends to recommend songs and albums to each other.
Built with Next.js 16, Supabase and Tailwind. It's a mobile-first web app you can install to your home screen.
npx supabase link then npx supabase db push,
or paste each file in supabase/migrations/ into the SQL editor, in order.https://your-domain/** to Redirect URLs (the /** matters).SUPABASE_ACCESS_TOKEN, run npm run auth:push-emails. It installs
supabase/templates/sign-in.html, which carries a code plus a one-tap
link that works on any device, and switches to 6-digit codes..env.example to .env.local and fill in the URL, the anon key and
the service-role key.npm install
npm run dev
npm run invite -- --admin
Open the printed link, enter your name and email, and type the code we email you (or tap the button in the email). After that, admins invite friends in the app (Me → Manage invites): add their name and, optionally, their email, then share the link. Someone whose email was invited can also just sign in from the login page. Invites last 30 days and can be renewed.
Deploy to Vercel and give it the Supabase URL and anon key. There are two ways:
NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY (or
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY).The URL is optional: without NEXT_PUBLIC_SUPABASE_URL the app uses
SUPABASE_URL (set by the integration), then the group's project URL
(DEFAULT_SUPABASE_URL in src/lib/env.ts). Only the key is required.
Either way, redeploy afterwards, because these values are baked in at
build time. Optional variables: NEXT_PUBLIC_SITE_URL and ODESLI_API_KEY.
Don't set the service-role key in Vercel; only the local scripts use it.
Run this whenever you like, e.g. weekly. In Claude Code in this repo:
/refresh
The refresh skill runs three steps:
npm run ai:pull snapshots the room into .ai-work/<batch>/. It writes
items that need summaries, a taste profile per member (loved, disliked,
and things to exclude), and INSTRUCTIONS.md.summaries.json and suggestions.json following those
instructions.npm run ai:push -- --dry-run, then npm run ai:push, validates the files
and looks up every pick in the Apple Music catalog. Made-up or
already-seen records are dropped. It then writes summaries and picks to
Supabase. Pushing twice is safe.You can also run the steps by hand. .ai-work/ is gitignored because it
contains your friends' activity.
With an ODESLI_API_KEY, song.link is rate limited, so push spaces out its
calls and a batch of 25 picks takes a few minutes. Without a key, push skips
song.link and runs quickly.
| command | what |
|---|---|
npm test | unit tests (link parsing, metadata normalization, batch logic) |
npm run lint / npm run typecheck | static checks |
npx supabase start | local Supabase (Docker) |
npm run test:rls | row-level security tests against local Supabase |
npm run seed | three fake friends and some recs (local only) |
npm run test:e2e | Playwright smoke test (sign-in via local Mailpit, rate, react, comment) |
Local sign-in emails are delivered to Mailpit at http://127.0.0.1:54324.
supabase/migrations/ schema, RLS policies, invite + item functions
supabase/tests/ RLS tests (SQL)
src/app/ pages (feed, add, r/[id], for-you, me, admin/invites), server actions
src/lib/music/ link parsing, iTunes search, link resolution
src/lib/ai/ batch file contract + pull/push logic
scripts/ai/ ai:pull, ai:push
.claude/skills/refresh/ the /refresh skill for Claude Code