{"id":28749195,"url":"https://github.com/mostafa-drz/spotify-companion","last_synced_at":"2026-05-08T10:36:03.727Z","repository":{"id":297101281,"uuid":"995569066","full_name":"mostafa-drz/spotify-companion","owner":"mostafa-drz","description":"🎵 Spotify Companion - An AI-powered web app that enhances your music experience by providing educational insights about your Spotify tracks. Features include customizable learning styles, multiple intro templates, and both text/audio versions of track insights. Built with Next.js, Firebase, and Google's GenKit.","archived":false,"fork":false,"pushed_at":"2025-06-12T11:46:43.000Z","size":37050,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-12T12:42:56.208Z","etag":null,"topics":["ai","firebase","genkit","nextjs","spotify","vertex-ai"],"latest_commit_sha":null,"homepage":"https://spotifycompanion.mostafa.xyz/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mostafa-drz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-03T17:22:15.000Z","updated_at":"2025-06-12T11:46:47.000Z","dependencies_parsed_at":"2025-06-04T05:29:00.075Z","dependency_job_id":"47171de6-d82b-4ac9-9bc1-36f35760ca8f","html_url":"https://github.com/mostafa-drz/spotify-companion","commit_stats":null,"previous_names":["mostafa-drz/spotify-companion"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mostafa-drz/spotify-companion","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mostafa-drz%2Fspotify-companion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mostafa-drz%2Fspotify-companion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mostafa-drz%2Fspotify-companion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mostafa-drz%2Fspotify-companion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mostafa-drz","download_url":"https://codeload.github.com/mostafa-drz/spotify-companion/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mostafa-drz%2Fspotify-companion/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32776932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"ssl_error","status_checked_at":"2026-05-08T08:22:45.650Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","firebase","genkit","nextjs","spotify","vertex-ai"],"created_at":"2025-06-16T20:00:58.492Z","updated_at":"2026-05-08T10:36:03.714Z","avatar_url":"https://github.com/mostafa-drz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎵 Spotify Companion\n\nA minimal web application that enhances your music listening experience by providing educational insights about your Spotify playlist tracks.\n\n## 🚀 Features\n\n- Connect your Spotify account\n- Select any of your playlists\n- Get AI-generated educational blurbs about each track\n- Simple credit system:\n  - Start with demo credits\n  - Clear credit balance display\n  - Low credit warnings\n  - Easy credit top-up via email\n- Customize your learning experience:\n  - Select preferred language\n  - Pick from different tones (casual, academic, storytelling, etc.)\n  - Control intro duration\n  - Select a prompt template (e.g., \"About the Artist\", \"Track Story\") to guide the AI intro\n- Manage your intro templates (create, edit, delete, select) directly from the Now Playing page—no separate templates section.\n- All feedback (loading, errors, success) is handled via minimal inline messages—no toast notifications or popups, in line with the product's minimalism philosophy.\n- Each track can have multiple intros, one per template, and switching templates instantly loads or generates the relevant intro.\n- Enjoy both text and audio versions of the insights\n\n## 🎬 Product Demo\n\n[![Watch the demo](./public/step-2-play-your-music.gif)](https://youtu.be/5wtlfmVnRYg)\n\n[Watch on YouTube](https://youtu.be/5wtlfmVnRYg)\n\n## 🛠 Tech Stack\n\n- **Frontend**: Next.js 15, TypeScript, TailwindCSS\n- **Server Components**: Next.js 15 server components for improved performance\n- **Server Actions**: Next.js server actions for form submissions\n- **Authentication**: NextAuth.js with Spotify provider\n- **Database**: Firebase Firestore (client SDK)\n- **AI**: Google Vertex AI via Firebase client SDK\n- **APIs**: Spotify Web API\n- **Prompt System**: Dotprompt for structured AI interactions\n\n## 🧠 GenKit Integration (AI-Powered Features)\n\nThis project uses [Genkit](https://github.com/firebase/genkit), an open-source framework by Google for building full-stack AI-powered apps. It provides a streamlined way to integrate models like **Google Gemini**, **OpenAI**, **Anthropic**, and others—abstracting away the complexity of prompt engineering, model selection, and output structuring.\n\n### ✨ Why Genkit?\n\n- **Unified Interface**: One SDK, many model providers\n- **Prompt System**: `.prompt` files with structured inputs/outputs and templating\n- **Tooling**: Visual Developer UI for live prompt testing and debugging\n- **Serverless Ready**: Pairs well with Firebase and frontend-first architectures\n\n### ⚙️ Implementation Details\n\n1. **Prompt Definition** (`app/lib/prompts/intro.prompt`):\n\n   ```yaml\n   ---\n   model: googleai/gemini-2.0-flash\n   input:\n     schema:\n       trackDetailsJSON: string\n       templatePrompt: string\n       language?: string\n       tone?: string\n       length?: number\n     default:\n       tone: 'conversational'\n       length: 60\n   output:\n     schema:\n       markdown: string\n       ssml: string\n       duration: number\n   ---\n   ```\n\n2. **GenKit Configuration** (`app/lib/genKit.ts`):\n\n   ```typescript\n   const ai = genkit({\n     plugins: [googleAI()],\n     model: gemini15Flash,\n     promptDir: './app/lib/prompts',\n   });\n   ```\n\n3. **Service Layer** (`app/lib/ai.ts`):\n\n   - Single entry point for AI interactions\n   - Parameter-based caching with Firestore\n   - Type-safe input/output handling\n\n4. **Caching Strategy**:\n   - Cache invalidation based on:\n     - Language\n     - Tone\n     - Length\n     - Template prompt\n     - Automatic regeneration when parameters change\n     - Firestore for persistent storage\n\n### 🧪 Local Dev Guide\n\n1. **Get API Access**\n\n   - [Generate a Gemini API key](https://makersuite.google.com/app/apikey)\n   - Set it in `.env.local` as `GEMINI_API_KEY`\n\n2. **Start Genkit Dev UI**\n\n   ```bash\n   genkit start -- tsx --watch src/app.ts\n   ```\n\n3. **Test \u0026 Export Prompts**\n   - Modify and test `.prompt` files interactively\n   - Export finalized versions to `prompts/`\n\n\u003e Schema validation is powered by **Picoschema**, a concise YAML schema format optimized for AI inputs/outputs.\n\n### 🔗 Helpful Resources\n\n- 📘 [Genkit Docs](https://firebaseopensource.com/projects/firebase/genkit/)\n- 🧪 [Genkit by Example](https://firebaseopensource.com/projects/firebase/genkit/examples/)\n- 🧠 [Dotprompt Spec](https://firebaseopensource.com/projects/firebase/genkit/docs/prompts/)\n\n## 🏗️ Development Setup\n\n1. **Clone the repository**\n\n   ```bash\n   git clone https://github.com/yourusername/playlist-companion.git\n   cd playlist-companion\n   ```\n\n2. **Install dependencies**\n\n   ```bash\n   npm install\n   ```\n\n3. **Set up environment variables**\n   Create a `.env.local` file in the root directory with the following variables:\n\n   ```env\n   # Google Cloud Service Account (used in all environments)\n   GCP_PROJECT_ID=your-gcp-project-id\n   GCP_CLIENT_EMAIL=service-account@your-gcp-project-id.iam.gserviceaccount.com\n   # If pasting as a single line, keep \\n escapes; the code converts them\n   GCP_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBK...\\n-----END PRIVATE KEY-----\\n\n   # Firebase Client Config\n   NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key\n   NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-auth-domain\n   NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id\n   NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-storage-bucket\n   NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your-messaging-sender-id\n   NEXT_PUBLIC_FIREBASE_APP_ID=your-app-id\n\n   # NextAuth\n   NEXTAUTH_URL=http://localhost:3000\n   NEXTAUTH_SECRET=your-nextauth-secret\n\n   # Spotify\n   SPOTIFY_CLIENT_ID=your-spotify-client-id\n   SPOTIFY_CLIENT_SECRET=your-spotify-client-secret\n   SPOTIFY_REDIRECT_URI=http://localhost:3000/api/auth/callback/spotify\n\n   # JWT\n   JWT_SECRET=your-jwt-secret\n\n   # Google AI (GenKit)\n   GEMINI_API_KEY=your-gemini-api-key\n   ```\n\n   ### Setting up Firebase Admin SDK\n\n   The app uses a single service account across environments via env vars:\n\n   1. Go to Firebase Console \u003e Project Settings \u003e Service Accounts\n   2. Click \"Generate New Private Key\" and download the JSON\n   3. Set `GCP_PROJECT_ID`, `GCP_CLIENT_EMAIL`, and `GCP_PRIVATE_KEY` in `.env.local`\n      - If you paste the private key in one line, keep `\\n` escapes; the code converts them at runtime\n   4. Do not commit secrets; prefer your platform's secret manager for production\n\n   ### Setting up Firebase Client\n\n   1. Go to Firebase Console \u003e Project Settings \u003e General\n   2. Scroll down to \"Your apps\" section\n   3. If no web app exists, click \"Add app\" and choose Web\n   4. Register your app and copy the configuration values\n\n   ### Setting up NextAuth\n\n   Generate a secure random string for `NEXTAUTH_SECRET`:\n\n   ```bash\n   openssl rand -base64 32\n   ```\n\n   ### Setting up Spotify\n\n   1. Go to Spotify Developer Dashboard\n   2. Create a new application or select existing one\n   3. Add the redirect URI in the app settings\n\n   ### Setting up JWT\n\n   Generate a secure random string for `JWT_SECRET`:\n\n   ```bash\n   openssl rand -base64 32\n   ```\n\n   ### Setting up Google AI (GenKit)\n\n   1. Go to Google AI Studio (https://makersuite.google.com/app/apikey)\n   2. Create a new API key\n   3. Copy the API key to `GEMINI_API_KEY`\n   4. Ensure your service account has the necessary permissions:\n      - Vertex AI User\n      - Vertex AI Service Agent\n\n4. **Run the development server**\n\n   ```bash\n   npm run dev\n   ```\n\n5. **Open [http://localhost:3000](http://localhost:3000)**\n\n## 🔒 Security Notes\n\n- Never commit `.env.local` to version control\n- Keep your private keys and secrets secure\n- Rotate secrets periodically\n- Use different values for development and production\n- Consider using a secrets manager for production\n\n## 📚 Documentation\n\n- [Product Plan](docs/PRODUCT_PLAN.md)\n\n## 🔒 Privacy \u0026 Security\n\n- We only request necessary Spotify permissions\n- Your data is stored securely in Firebase\n- We don't share your information with third parties\n- Credit system is transparent and user-friendly\n\n## 📝 License\n\nMIT License - see [LICENSE](LICENSE) for details\n\n## Developer Tooling \u0026 Workflow\n\nThis project uses automated tooling to ensure code quality and consistency:\n\n### Available Commands\n\n- `npm run lint` — Run ESLint on the codebase\n- `npm run format` — Format code with Prettier\n- `npm run ts:check` — Run TypeScript type checking\n\n### Pre-commit Hooks\n\n- Pre-commit hooks are set up with Husky and lint-staged.\n- On every commit, staged files are automatically linted and formatted. Commits will be blocked if there are any errors.\n\n### Editor Integration\n\n- VSCode users: Format-on-save and ESLint auto-fix are enabled by default (see `.vscode/settings.json`).\n\n### Configuration Files\n\n- ESLint: `eslint.config.mjs`\n- Prettier: `.prettierrc`\n- lint-staged: in `package.json`\n- Husky: `.husky/` directory\n\nFor more details, see the user story in `docs/userStories/dev-experience-tooling.md`.\n\n## ⚡️ Environment Variables\n\n### Local Development\n\n- Use a `.env.local` file in the root directory to provide all required environment variables (see below for a template).\n- This is sufficient for running the app locally.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmostafa-drz%2Fspotify-companion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmostafa-drz%2Fspotify-companion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmostafa-drz%2Fspotify-companion/lists"}