尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證crate lfg
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Crate helps DJs work with the records they own. You sign in with Discogs,
Crate syncs your collection, and from there you can search it, play tracks
through YouTube, and build playlists you can share with a public link.
Live at cr8.audio.
Crate is moving toward an MCP server, so you can search your collection and
build playlists from any agent harness (Claude, ChatGPT, …). The app has no
built-in assistant: the harness is the chat, and it runs on the user's own
model subscription.
You need Node 20+, pnpm 9+ and a Convex account.檢視完整 README ↗Crate helps DJs work with the records they own. You sign in with Discogs, Crate syncs your collection, and from there you can search it, play tracks through YouTube, and build playlists you can share with a public link.
Live at cr8.audio.
Crate is moving toward an MCP server, so you can search your collection and build playlists from any agent harness (Claude, ChatGPT, …). The app has no built-in assistant: the harness is the chat, and it runs on the user's own model subscription.
| Layer | What |
|---|---|
| App | React 18, TanStack Start and Router (file routes in app/), Tailwind CSS 4, Zustand |
| Backend | Convex: database, queries and mutations, Convex Auth |
| Hosting | Cloudflare Workers, built with @cloudflare/vite-plugin |
| Discogs | @cr8.audio/discogs-sdk |
You need Node 20+, pnpm 9+ and a Convex account.
pnpm install
pnpm dev
pnpm dev runs Vite on localhost:1995 and
convex dev side by side. The first run asks you to create or pick a Convex
dev deployment and writes its URL to .env.local.
On a new Convex deployment, generate the auth keys once:
npx @convex-dev/auth
Then set the variables below.
| Variable | Where | Used for |
|---|---|---|
DISCOGS_CONSUMER_KEY, DISCOGS_CONSUMER_SECRET | Convex deployment | Discogs sign-in, collection sync and search |
JWT_PRIVATE_KEY, JWKS, SITE_URL | Convex deployment | Convex Auth (set by npx @convex-dev/auth) |
YOUTUBE_API_KEY | Worker secret (.dev.vars locally) | /api/external/youtube/* track lookup |
YOUTUBE_API_KEY | Convex deployment | Matching audio for shared playlists (convex/playlistAudio.ts) |
VITE_CONVEX_URL | Build (.env.local locally) | The Convex deployment the app talks to |
VITE_BASE_URL | Build, optional | Base URL for the YouTube API routes (defaults to http://localhost:1995) |
Set Convex variables with npx convex env set NAME value or in the Convex
dashboard. The Discogs secret only lives on Convex, never in the browser
bundle.
Discogs sign-in only redirects back to known origins: cr8.audio,
www.cr8.audio, localhost:1995, pr-<n>.cr8.audio and the crate-app
Workers on workers.dev. See convex/lib/discogsOAuth.ts.
A playlist is private, unlisted (anyone with the link or embed) or public
(also listed on /listen/<username>). Shared playlists live at
/p/<share_id>, and /embed/<share_id> is a compact player for other sites.
Only /embed/* may be framed by other origins (start.ts).
When a playlist is shared, convex/playlistAudio.ts matches each track to a
YouTube video on the server and saves it, so listeners never spend YouTube
search quota from their browsers. Without YOUTUBE_API_KEY on Convex, shared
tracks with a stored video still play and the rest are skipped.
| Command | What it does |
|---|---|
pnpm dev | App and Convex in watch mode |
pnpm build | Production build into dist/ |
pnpm test | Vitest |
pnpm format:check, pnpm lint:warn, pnpm type-check, pnpm test | What CI runs on every PR |
pnpm pre-pr | Format check, lint and tests before opening a PR |
app/ routes (TanStack file routes); app/api/ holds server routes
convex/ backend: schema, auth, Discogs, playlists
lib/ components, hooks, stores (player), API clients
__tests__/ Vitest suites (convex, features, hooks)
.github/ CI and deploy workflows
| Target | Trigger | URL |
|---|---|---|
| Production | Push to main | cr8.audio and www |
| PR preview | Every push to a PR | https://pr-<number>.cr8.audio, deleted when the PR closes |
| Staging | Push to stage | crate-app on workers.dev (still on the previous Cloudflare account) |
Production and previews deploy to the cr8.audio Cloudflare account with the
CLOUDFLARE_PRODUCTION_API_TOKEN secret. The preview bot comments on the PR
with its link.
A push to main deploys Convex first (convex deploy with the
CONVEX_DEPLOY_KEY secret), then builds the frontend against it and ships
the Worker. PR previews and staging only build the frontend.
Migrations don't run on deploy. If a change adds one in
convex/migrations.ts, run it once after it reaches production, for example:
npx convex run --prod migrations:run '{"fn": "migrations:backfillPlaylistVisibility"}'
Production, staging and previews all use the Convex deployment in the
VITE_CONVEX_URL secret, so previews read and write production data.
To copy data from another deployment (for example a teammate's dev data) into yours:
In the source deployment's Convex dashboard, open Settings → URL & Deploy Key and generate a development deploy key.
Save it to .env.source, which is gitignored:
echo "CONVEX_DEPLOY_KEY=dev:source-deployment-name|YOUR_FULL_TOKEN" > .env.source
Export, then import:
| Command | What it does |
|---|---|
pnpm convex:export:from | Downloads the source data to convex-data.zip |
pnpm convex:import | Imports it, appending to existing data |
pnpm convex:import:replace | Imports it, replacing all existing data |