MyGo 云音乐
Go와 MyGo로 만든 서드파티 네이버 클라우드 뮤직 데스크톱 클라이언트
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Live, multi-user karaoke songbook synced to Supabase.
This is the one and only app in active use — an earlier separate project
(karaoke-app, a React rebuild on Vercel) was retired in favor of adding
multi-user support directly to this app instead. Nothing else reads or
writes this database going forward.
index.html — markup and sheet layouts, including the sign-in gatestyles.css — all stylingapp.js — app logic (auth, Supabase calls, rendering, vocal range math,
recommendations, venue search)authClient/onSignedIn flow at the top and bottom of app.js.songs and performances are scoped per-user via a user_id column
and RLS policies (auth.uid() = user_id). Each signed-in user only
ever sees their own songbook.profiles holds each user's vocal range: either range_mode = 'auto'
(computed from the widest span among Solid-status songs with a known
range) or 'manual' (typed in directly under Settings > Vocal Range).karafun_catalog (~84k songs) and song_ranges (shared vocal-range
lookup, matched by normalized title+artist) are shared reference data,
open to all signed-in users — not scoped per-user.songs.in_karafun (drives the "K" badge) is computed server-side by a
before insert or update of title, artist trigger
(songs_karafun_check → check_karafun_match), not checked client-side
on load. After importing a refreshed KaraFun catalog CSV into
karafun_catalog, run select public.refresh_all_karafun_matches();
to re-check every existing song — otherwise only newly added/edited
songs pick up the new catalog data.setlists (name, optional gig date/venue/notes) and setlist_songs
(join table with a position column for ordering) let a user build
named, ordered song lists — either a reusable collection or one tied
to a specific gig date. Both are scoped per-user via user_id and RLS,
same pattern as songs/performances. Songs are added manually —
either from a setlist's own "Add songs" search, or via a "+ Setlist"
button on every song card in the main songbook list, which opens a
picker to add that song straight to an existing setlist or a
newly-named one (openAddToSetlist in app.js). Reordering
re-numbers every row's position rather than patching just the two
swapped rows, since positions can develop gaps after a song is removed.renderSetlistsList) splits into Upcoming
(gig_date today-or-later, ascending; undated/reusable lists included,
sorted last within the group) and Past (visually de-emphasized) via
splitSetlistsByGigDate. Tapping a setlist opens Perform mode
(openPerformView/renderPerformSongs) by default — a read-mostly view
with a "Mark as sung" button per song (logs to performances, same shape
as manual logging, dated today and defaulting to the setlist's venue) and
no reorder/remove controls. The full planning sheet (openSetlistDetail
— reorder, add/remove songs, gig date/venue/notes) is reachable via an
Edit button on each row or inside Perform itself. Both views show a
readiness banner (computeReadinessBannerHtml) when the gig is within 14
days and any song in it isn't yet Solid.sb_publishable_...), not
the legacy anon key.The Recs tab (loadRecommendations in app.js — a view-switcher tab, not
a sheet, since promoting it out from behind a header icon in build 71)
searches karafun_catalog for songs by artists related
to your Solid songs, gates every candidate on vocal range via
song_ranges, and groups results into in-range / would-need-a-key-change
/ range-unconfirmed. Seed artists come from three tiers (buildSeedArtists
in app.js), each with a smaller per-artist cap the further it gets from
a proven Solid artist:
artist.getsimilar
API, for your top 8 Solid artists by song count (cap 4). Only runs if a
free Last.fm API key is saved under Settings > Recommendations; the key
lives in localStorage only, not Supabase.tests.js unit-tests the pure logic in app.js (note/semitone math, range fit scoring, transpose suggestions, string normalization) by extracting those functions straight from the shipped source — not a hand-copied duplicate, so it can't silently drift out of sync. It does not test DOM/UI behavior, Supabase calls, or auth.
Run with:
node tests.js
tests.js must pass before every push. Also bump the cache-busting ?v=
query param on app.js and styles.css in index.html, and match it to
BUILD_VERSION at the top of app.js — GitHub Pages/browsers (especially
iOS home-screen icons) can otherwise keep serving a stale cached bundle
after a deploy, silently undoing whatever just shipped.
public/PWA install are still placeholder/empty.karafun_catalog
entry due to text normalization gaps (e.g. "and" vs "&" in artist
names) — catalog-dependent features (autocomplete, range auto-fill)
just won't fire for those specific songs.friendships
table (requester_id, addressee_id, status: pending/accepted/declined,
unique index on the unordered pair so requests can't be duplicated or
crossed). All writes go through security-definer RPCs, not direct REST
— the table itself has only a SELECT policy, so a raw REST call can't
mutate it: send_friend_request(username) (creates a request, or
auto-accepts if the other person already requested you, or revives a
declined one), accept_friend_request / decline_friend_request /
remove_friendship (also doubles as cancel-outgoing and unfriend),
list_friendships() (joined view with the other person's username,
since profiles RLS wouldn't otherwise let you read it).
friendsSheet, opened via
the new Friends icon in the marquee), not Settings — friending is a
mainstream social feature that'll keep growing, not app config, and
burying it in Settings was the wrong call from when it was first
built (build 58). Settings keeps just the Username field.pending_friend_request_count(), refreshed on sign-in and
after any action that changes it. It's a request counter, not a
push notification — still requires opening the app to see it.get_friend_setlists(friend_id), gated on
an accepted friendship existing. Setlists were picked over the full
songbook as the first share surface — a setlist is inherently
"here's what I'm bringing to a gig," already meant to be seen,
versus the songbook's more private in-progress status tracking.usersSheet) — full
roster with last-active time via admin-list-users, expandable
read-only details via admin-view-as, and real full impersonation via
admin-impersonate. Impersonation works by minting a genuine session
for the target user through Supabase's own generateLink +
verifyOtp (no service-role key ever reaches the client), so once
switched, everything the admin sees is governed by the target's own
RLS — not a bypass. The admin's own session is stashed in
sessionStorage before switching so the "Exit" banner can restore it.https://kiplingm.github.io/caterwauler/
to Supabase Dashboard → Authentication → URL Configuration → Redirect
URLs (repo/Pages URL renamed from setlist-sherpa in build 51). Until
this is added, magic-link email redirects may fail on the new URL —
the emailed code fallback still works regardless (the auth code field
accepts up to 10 digits — Supabase's project Auth settings currently
issue 8, not the 6 originally assumed; found and fixed 2026-09-19 after
it silently broke sign-in via the fallback path entirely).loadRecommendations in app.js) still does the old
sequential-ish chunked candidate search against karafun_catalog for
new song suggestions — this is a live search so it wasn't touched by
the in_karafun trigger work, but it'd benefit from the same
Promise.all-parallelized chunking pattern used in the old
fetchKarafunMatches if opening the Recs tab ever feels slow.songs.user_id if the table grows a lot — fine at
current scale (~200 rows total across users) but not indexed today.public.lastfm_popularity_cache and
public.artist_similarity_cache have RLS disabledSELECT policies for anon/authenticated so
the app's read paths keep working. No write policies added — both
tables are written only server-side (Edge Function / pg_cron) via
the service-role key, which bypasses RLS entirely, so direct writes
via the anon key are no longer possible. Confirmed via get_advisors
that both tables have dropped off the security lint list.