Voice-to-text, formatted for you.
Sidekick is a progressive web app that turns your voice into clean, structured notes. Tap the mic, speak naturally, and get formatted text back instantly.
- One-tap recording with real-time waveform animation
- Audio transcription via OpenAI Whisper API
- AI-powered formatting and cleanup via GPT-4o-mini
- Built-in guardrails — Sidekick is strictly a note-taking tool and will not generate content, answer questions, or assist with academic dishonesty
- Email/password account creation and sign-in
- Google SSO (sign up and sign in with Google)
- Password reset via email
- Account deletion with re-authentication
- File formats: PDF, DOCX, TXT, Markdown
- Destinations: Save to computer or upload directly to Google Drive
- Google Drive integration via OAuth 2.0
- Account — Profile overview, password reset, Google Drive connection status, dark/light mode toggle, sign out, delete account
- Formats — Voice command presets (e.g., say "new paragraph", "bullet point", or "heading" while recording to trigger formatting)
- About — App info, privacy notice, and credits
- Dark and light mode (dark by default, persisted across sessions)
- Copy to clipboard with visual confirmation
- Read aloud via Web Speech Synthesis API
- Collapsible sidebar with conversation history
- History of recent transcriptions
- First-launch onboarding walkthrough
- Installable as a PWA (standalone mode)
| Technology | Purpose |
|---|---|
| React 18 | UI framework |
| Vite 5 | Build tool and dev server |
| Firebase 12 | Authentication and Firestore database |
| OpenAI API | Whisper (transcription) + GPT-4o-mini (formatting) |
| jsPDF | PDF generation |
| docx | DOCX generation |
| Google Identity Services | Google Drive OAuth |
| vite-plugin-pwa | Service worker and PWA support |
SideKick/
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions — runs tests on PRs
├── cypress/
│ ├── e2e/
│ │ ├── auth.cy.js # Authentication tests (A-1 – A-11)
│ │ ├── welcome.cy.js # Onboarding tests (W-1 – W-4)
│ │ ├── apikey.cy.js # API key setup tests (K-1 – K-6)
│ │ ├── main-app.cy.js # Mic, output, history tests (M/O/H)
│ │ ├── export.cy.js # Export modal tests (E-1 – E-7)
│ │ ├── settings.cy.js # Settings modal tests (S/SA/SF/SB)
│ │ └── theme-header.cy.js # Theme and header tests (T/HD)
│ └── support/
│ └── e2e.js # Custom commands and test helpers
├── docs/
│ └── TEST_PLAN.md # Full test plan (71 cases)
├── public/
│ ├── icons/ # PWA icons (192px, 512px, SVG)
│ └── manifest.json # PWA manifest
├── src/
│ ├── main.jsx # React entry point
│ ├── App.jsx # Root component, auth state, routing
│ ├── App.css
│ ├── index.css # Global styles, CSS variables, themes
│ ├── components/
│ │ ├── AuthScreen.jsx # Sign in / Create account UI
│ │ ├── ApiKeySetup.jsx # OpenAI API key input
│ │ ├── Welcome.jsx # First-launch onboarding
│ │ ├── Header.jsx # Logo bar (pre-auth screens)
│ │ ├── Sidebar.jsx # Collapsible sidebar (main app)
│ │ ├── MicButton.jsx # Voice recorder with waveform
│ │ ├── OutputBox.jsx # Transcription display + actions
│ │ ├── History.jsx # Recent transcription list
│ │ ├── ExportModal.jsx # Format picker + export destinations
│ │ ├── SettingsModal.jsx # Account / Formats / About tabs
│ │ ├── Icons.jsx # Shared SVG icon components
│ │ └── *.css # Component-scoped styles
│ └── utils/
│ ├── firebase.js # Firebase app, auth, Firestore init
│ ├── openai.js # Whisper + GPT-4o-mini API calls
│ ├── exportFile.js # PDF/DOCX/TXT/MD file generation
│ ├── googleDrive.js # Google Drive OAuth + upload
│ └── mockData.js # Mock data for development/testing
├── cypress.config.js # Cypress configuration
├── index.html
├── vite.config.js
├── package.json
└── .env # Environment variables (not committed)
All you need is an OpenAI API key. Create an account in the app, enter your key, and start recording.
Firestore Security Rules — If you're self-hosting, make sure your Firestore rules restrict API key access to the owning user:
match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; }
-
Clone the repository
git clone https://github.com/phillsatellite/SideKick.git cd SideKick -
Install dependencies
npm install
-
Start the dev server
npm run dev
The app will be available at
http://localhost:5173.
Sidekick uses Cypress for end-to-end testing. Tests run automatically on every pull request via GitHub Actions.
# Open Cypress UI
npm run cy:open
# Run all tests headlessly
npm run cy:runThe dev server must be running on http://localhost:5173 before launching tests.
- Onboarding — First-time users see a welcome page explaining the app
- Account — Users create an account (email/password or Google) stored in Firebase Auth
- API Key — Users enter their own OpenAI API key (stored securely in Firebase Firestore, scoped per user)
- Record — Tap the mic button to start recording; a waveform visualizes audio input
- Transcribe — Audio is sent to OpenAI Whisper for transcription
- Format — The transcript is cleaned up and formatted by GPT-4o-mini
- Output — Formatted text appears on screen with options to copy, read aloud, or export
- Export — Save as PDF, DOCX, TXT, or Markdown — locally or to Google Drive
- Fonts: Syne (UI) and Instrument Serif (display)
- Theming: CSS custom properties with smooth transitions between dark and light modes
- Layout: Mobile-first, responsive design with collapsible sidebar and touch-friendly controls
- Modals: Rendered via React Portals to avoid stacking context issues
- OpenAI API keys are stored in Firebase Firestore, scoped per user and protected by security rules so only the key owner can read or write their own key. Keys are never sent to any server other than OpenAI's API.
- Audio is sent directly from the browser to OpenAI for transcription — no intermediary server.
- Firebase stores minimal account data (username, email, creation date) and the user's encrypted API key. No transcription data is stored in the cloud.
This project is for personal/educational use.