Skip to content

phillsatellite/SideKick

Repository files navigation

Sidekick

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.

Features

Voice Recording & Transcription

  • 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

Authentication

  • 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

Export

  • File formats: PDF, DOCX, TXT, Markdown
  • Destinations: Save to computer or upload directly to Google Drive
  • Google Drive integration via OAuth 2.0

Settings

  • 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

Additional

  • 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)

Tech Stack

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

Project Structure

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)

Getting Started

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;
}

Development

  1. Clone the repository

    git clone https://github.com/phillsatellite/SideKick.git
    cd SideKick
  2. Install dependencies

    npm install
  3. Start the dev server

    npm run dev

    The app will be available at http://localhost:5173.

Testing

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:run

The dev server must be running on http://localhost:5173 before launching tests.

How It Works

  1. Onboarding — First-time users see a welcome page explaining the app
  2. Account — Users create an account (email/password or Google) stored in Firebase Auth
  3. API Key — Users enter their own OpenAI API key (stored securely in Firebase Firestore, scoped per user)
  4. Record — Tap the mic button to start recording; a waveform visualizes audio input
  5. Transcribe — Audio is sent to OpenAI Whisper for transcription
  6. Format — The transcript is cleaned up and formatted by GPT-4o-mini
  7. Output — Formatted text appears on screen with options to copy, read aloud, or export
  8. Export — Save as PDF, DOCX, TXT, or Markdown — locally or to Google Drive

Design

  • 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

Privacy

  • 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.

License

This project is for personal/educational use.

About

Voice-to-text PWA — tap the mic, speak naturally, get formatted notes.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors