# Project export: Speakeasy

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: UC Berkeley AI Hackathon 2025
- Tagline: Speakeasy is a social networking platform that integrates AI-driven mental health awareness directly into social interactions, enhancing empathy and sensitivity in digital communications.
- Devpost: https://devpost.com/software/speakeasy-cr64ed
- GitHub: https://github.com/spicylemonade/Speakeasy
- Video: https://www.youtube.com/embed/5PCr0fIk7RA?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — spicylemonade (6 commits)

## Devpost submission (written by the team)

### Inspiration

Speakeasy was inspired by a desire to better connect and empathize with our friends in both in person and online interactions. Often, we share a large portion of our lives online, but don't have time to stay updated with our friends. We were looking for a way to be able to talk to our friends without missing any critical updates to their situation.

### What it does

To stay in touch with our friends and family, our users will run our application on their desktop device, and later through wearable electronics. With the consent of both parties, we source public data from their social networks such as X.com (formerly Twitter) and collect essential information they have shared with the internet. This includes light hearted posts like puppy pictures, milestones like graduation, but also serious events like a death in the family. Our goal is to support our users through conversation guidance and empathetic warnings. In this way our social network can help our users connect in a closer and meaningful way when spending time with each other, online and in person.

### How we built it

We built our demonstration application with a front end using Cursor for a palatable interface with functioning interactions and room for scaling with HTML and CSS. In our back end, we divided the work, from AI integration, web scraping, and natural language processing. This ranges from understanding the images and messages in different tweets to sending sending the audible AI message through a simulated voice. We used PyTorch, LMNT, playwright, and JavaScript. Additionally, we also planned for the future with integrating wearable electronics, where we have a homemade heartbeat sensor to connect to our AI and share when a conversation may cause significant stress to users.

### Challenges we ran into

The project held key concerns from the start, especially in privacy and scalability. Thus we were careful to structure our product where all parties would consent to the service, to work in tandem to better understand and communicate with each other. We knew that if our users could feel safe with their privacy protected, then they would be comfortable using our service to have a two way smart communication with their friends and family.

### Accomplishments we're proud of

We are proud to showcase a strong product that will support an unvaluable human trait, communication. With an intuitive UI, safe web scraping, understandable text-to-speech, and a strong user experience, our platform can help guide our users into a safer, closer, and open social interactions.

### What we learned

Aside from the technical skills in web scraping, natural language processing, and image recognition, we learned to work as a team. This project was essential to work together, because we wanted to build something meant for interpersonal conversations. Thus we learned the importance of collective input, listening to each other, and working towards building a great product. We are happy to have worked together to build this product.

### What's next

Speakeasy may find a future in wearable and consumer electronics, where we can transcribe live conversations, input the text into our engine, and return an AI speech of audible warnings or hints during a conversation through an earpiece or even AR glasses integration.

## README (from the GitHub repository)

# Speakeasy

**AI-powered conversation companion that helps you stay connected with friends and family through empathetic social insights.**


https://github.com/user-attachments/assets/cc916d80-f4f4-4028-985b-839f5bc1187a


## Overview

Speakeasy bridges the gap between our online and offline social lives by intelligently analyzing public social media data to provide contextual conversation guidance. Never miss important updates about your friends again.

## Features

- **Smart Social Monitoring**: Analyzes public posts from platforms like X (Twitter) with mutual consent
- **Empathetic Insights**: Identifies important life events from casual posts to serious milestones
- **Conversation Guidance**: Provides real-time suggestions and empathetic warnings during interactions
- **Multi-modal Analysis**: Processes both text and images from social media posts
- **Privacy-First**: Requires explicit consent from all parties before data collection

## How It Works

1. Users install the desktop application and grant permission to analyze their social media
2. AI processes public posts to identify key life events and emotional context
3. During conversations, the system provides subtle guidance and context about recent updates
4. Future integration with wearables will enable real-time conversation assistance

## Tech Stack

- **Frontend**: HTML, CSS, JavaScript (built with Cursor)
- **Backend**: Python, PyTorch, Playwright
- **AI/ML**: Natural language processing, image recognition
- **Audio**: LMNT for text-to-speech synthesis
- **Hardware**: Custom heartbeat sensor for stress detection

## Future Vision

- Wearable integration (earpieces, AR glasses)
- Real-time conversation transcription and analysis
- Stress monitoring through biometric sensors
- Enhanced privacy controls and data encryption


## Detected evidence (automated analysis)

Indexed codebase: 30 recognized source files, 183 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code

## Codebase structure (from repository index)

### Files (38 of 38)

```
CareAware/backend/biometric-monitor.js
CareAware/backend/package.json
CareAware/backend/README-CDP.md
CareAware/backend/scrape.py
CareAware/backend/server.js
CareAware/backend/speechToText.py
CareAware/backend/start-chrome-debug.bat
CareAware/backend/test.py
CareAware/backend/textToSpeech.py
CareAware/frontend/.gitignore
CareAware/frontend/package.json
CareAware/frontend/public/index.html
CareAware/frontend/public/manifest.json
CareAware/frontend/public/robots.txt
CareAware/frontend/README.md
CareAware/frontend/src/App.css
CareAware/frontend/src/App.js
CareAware/frontend/src/App.test.js
CareAware/frontend/src/components/CallPage.js
CareAware/frontend/src/components/ComposePost.js
CareAware/frontend/src/components/Dashboard.js
CareAware/frontend/src/components/Feed.js
CareAware/frontend/src/components/Icon.js
CareAware/frontend/src/components/Messages.js
CareAware/frontend/src/components/Navbar.js
CareAware/frontend/src/components/Profile.js
CareAware/frontend/src/components/Settings.js
CareAware/frontend/src/components/UserSwitcher.js
CareAware/frontend/src/config.js
CareAware/frontend/src/index.css
CareAware/frontend/src/index.js
CareAware/frontend/src/reportWebVitals.js
CareAware/frontend/src/setupTests.js
CareAware/NETWORK-SETUP.md
CareAware/README.md
CareAware/setup-firewall.bat
CareAware/setup-network.ps1
README.md
```

### Dependencies

- CareAware/backend/package.json: @serialport/parser-readline@^13.0.0, axios@^1.6.2, cors@^2.8.5, express@^4.18.2, nodemon@^3.0.2, serialport@^12.0.0
- CareAware/frontend/package.json: @testing-library/dom@^10.4.0, @testing-library/jest-dom@^6.6.3, @testing-library/react@^16.3.0, @testing-library/user-event@^13.5.0, axios@^1.6.0, react@^19.1.0, react-dom@^19.1.0, react-router-dom@^7.6.2, react-scripts@5.0.1, web-vitals@^2.1.4

### Recent commits (newest first)

- Create README.md
- end
- Merge branch 'main' of https://github.com/spicylemonade/Speakeasy
- full
- Update README.md
- Create textToSpeech.py
- Create speechToText.py
- Update README.md
- Update README.md
- Update scrape.py
- Update scrape.py
- Create scrape.py
- UI
- call
- init
- CareAware MVP - Mental health-aware social network with AI empathy features

## Key source files (fetched from GitHub, selected and truncated for size)

### CareAware/NETWORK-SETUP.md

```markdown
# 🌐 CareAware Network Setup Guide

## Quick Setup (3 Steps)

### 1. **Run Firewall Setup** (Run as Administrator)
```bash
# Right-click PowerShell -> "Run as Administrator"
.\setup-firewall.bat
```

### 2. **Auto-Configure Network IP**
```bash
.\setup-network.ps1
```

### 3. **Start Your Servers**
```bash
# Terminal 1 - Backend
cd backend
npm start

# Terminal 2 - Frontend  
cd frontend
npm start
```

## 🔥 Switch Users

Edit `frontend/src/App.js` and change:
```javascript
const currentUserId = 1; // Change this number
```

- `1` = Geby
- `2` = Connie  
- `3` = William

## 📱 Connect Other Devices

1. Make sure all devices are on the **same Wi-Fi/hotspot**
2. Open browser and go to: `http://YOUR_IP:3000`
3. Each person changes their `currentUserId` to be different users

## 🛠️ Manual Setup (if scripts don't work)

### Find Your IP:
```bash
ipconfig
```
Look for "IPv4 Address" (usually `192.168.x.x` or `10.0.x.x`)

### Update Config Manually:
Edit `frontend/src/config.js` and replace:
```javascript
return 'localhost'; // Replace with your IP
```

## 🚨 Troubleshooting

- **Can't connect?** → Check Windows Firewall
- **Posts not saving?** → Make sure backend is running on port 5000
- **Different users?** → Each device needs different `currentUserId` 
```

### CareAware/backend/README-CDP.md

```markdown
# CareAware Social Media Scraping with Chrome DevTools Protocol (CDP)

This document explains how to use the new Chrome DevTools Protocol (CDP) approach for scraping social media data in CareAware.

## Why CDP?

The CDP approach is more reliable than launching a new browser instance because:
- **Uses your existing login sessions** - No need to handle authentication programmatically
- **More stable** - Connects to a browser you control
- **Better for debugging** - You can see exactly what's happening
- **Avoids detection** - Uses your real browser session

## Setup Instructions

### 1. Start Chrome in Debug Mode

#### Option A: Use the provided batch file (Windows)
```bash
# Double-click or run:
start-chrome-debug.bat
```

#### Option B: Manual command (Windows)
```bash
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="%TEMP%\chrome-debug-profile"
```

#### Option C: MacOS
```bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir="/tmp/chrome-debug-profile"
```

#### Option D: Linux
```bash
google-chrome --remote-debugging-port=9222 --user-data-dir="/tmp/chrome-debug-profile"
```

### 2. Verify Chrome Debug Mode

Visit: http://localhost:9222/json/version

You should see a JSON response with Chrome version information.

### 3. Log in to X.com

1. In the Chrome instance you just started, navigate to https://x.com
2. Log in with your credentials
3. Navigate to any profile to test that you're logged in

### 4. Test the Scraper

#### Command Line Test
```bash
cd CareAware/backend
python scrape.py [twitter-username]
```

#### Via CareAware App
1. Start the backend server: `node server.js`
2. Open the CareAware frontend
3. Go to Settings → Platform Integration
4. Enter the Twitter username you want to scrape
5. Save settings - this will automatically trigger scraping

## Configuration

### Environment Variables

- `CDP_PORT`: Chrome DevTools Protocol port (default: 9222)

### Server Configuration

The backend automatically uses CDP when calling the scraper. No additional configuration needed.

## Troubleshooting

### "Could not connect to Chrome browser"
- Make sure Chrome is running with the `--remote-debugging-port=9222` flag
- Check that port 9222 is not blocked by firewall
- Try visiting http://localhost:9222/json/version to test the connection

### "It appears you are not logged in to X.com"
- Log in to X.com in the Chrome debug session
- Make sure you're not in incognito mode
- Clear browser cache and try again

### "No browser contexts found"
- Open at least one tab in the Chrome debug session
- Navigate to any webpage before running the scraper

### Chrome won't start in debug mode
- Close all existing Chrome instances first
- Check that Chrome is installed in the expected location
- Try using a different port: `--remote-debugging-port=9223`

## Security Notes

- The debug port (9222) allows full control over your browser
- Don't expose t
[truncated — 1243 more characters]
```

### CareAware/backend/package.json

```
{
  "name": "careaware-backend",
  "version": "1.0.0",
  "description": "Backend for CareAware social network",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "social",
    "health",
    "ai",
    "empathy"
  ],
  "author": "CareAware Team",
  "license": "MIT",
  "dependencies": {
    "@serialport/parser-readline": "^13.0.0",
    "axios": "^1.6.2",
    "cors": "^2.8.5",
    "express": "^4.18.2",
    "serialport": "^12.0.0"
  },
  "devDependencies": {
    "nodemon": "^3.0.2"
  }
}

```

### CareAware/frontend/package.json

```
{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/dom": "^10.4.0",
    "@testing-library/jest-dom": "^6.6.3",
    "@testing-library/react": "^16.3.0",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^1.6.0",
    "react": "^19.1.0",
    "react-dom": "^19.1.0",
    "react-router-dom": "^7.6.2",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

```

### CareAware/frontend/src/index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

```

### CareAware/backend/server.js

```javascript
const express = require('express');
const cors = require('cors');
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 5000;
const axios = require('axios');
const BiometricMonitor = require('./biometric-monitor');

const OPENROUTER_API_KEY = process.env.OPENROUTER_API_KEY || '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';

// Initialize Geby's biometric monitor
const gebyMonitor = new BiometricMonitor();

// Middleware
app.use(cors());
app.use(express.json());

// Serve static files from pfps directory
app.use('/pfps', express.static(path.join(__dirname, 'pfps')));

// Mock data for demo purposes
let users = [
  {
    id: 1,
    name: "Geby",
    username: "geby",
    avatar: "http://localhost:5000/pfps/Geby.png",
    bio: "CS student at the University of Illinois. Building cool things for hackathons.",
    interests: ["Coding", "AI", "Hackathons", "Music"],
    integrationSettings: {
      twitter: { username: 'GebyCodes' },
      reddit: { username: 'geby_on_reddit' }
    },
    recentActivity: {
      mood: "focused",
      heartRate: 75,
      lastActive: new Date().toISOString()
    },
    socialData: {
      reddit: ["Active in r/programming and r/UIUC"],
      instagram: ["Posted about a new coding project"],
      discord: ["Talking about hackathon ideas"]
    }
  },
  {
    id: 2,
    name: "Connie",
    username: "connie_c",
    avatar: "https://i.pravatar.cc/100?img=5",
    bio: "Designer, artist, and professional vibe checker.",
    interests: ["Graphic Design", "Art History", "Photography", "Books"],
    integrationSettings: {
      instagram: { username: 'connie_designs' }
    },
    recentActivity: {
      mood: "calm",
      heartRate: 68,
      lastActive: new Date().toISOString()
    },
    socialData: {
      reddit: ["Posted in r/design"],
      instagram: ["Shared new digital art"],
      discord: ["Discussing color theory in a design server"]
    }
  },
  {
    id: 3,
    name: "William",
    username: "will_w",
    avatar: "http://localhost:5000/pfps/William.jpg",
    bio: "Explorer of mountains and code. Always looking for the next adventure.",
    interests: ["Hiking", "Rock Climbing", "Tech", "Travel"],
    integrationSettings: {},
    recentActivity: {
      mood: "energetic",
      heartRate: 80,
      lastActive: new Date().toISOString()
    },
    socialData: {
      reddit: ["Asking for trail recommendations in r/hiking"],
      instagram: ["Posted photos from a recent climbing trip"],
      discord: ["Planning a weekend trip with friends"]
    }
  },
  {
    id: 4,
    name: "Caeden",
    username: "caeden_sigma",
    avatar: "https://i.pravatar.cc/100?img=12",
    bio: "CEO @ Sigma | Building the future of agentic AI for education.",
    interests: ["AI", "EdTech", "Startups", "Machine Learning"],
    integrationSettings: {
      twitter: { username: 'caedensigma' }
    },
    recentActivity: {
      mood: "excited",
      heartRate: 82,
      lastActive: new Date().toISOString()
    },
    socialData: {
      reddit: ["Discussing the future of AI in r/futurology"],
      instagram: ["Posted team photos from the office"],
      discord: ["Hosting an AMA on AI in education"]
    }
  },
  {
    id: 5,
    name: "Laura Miller",
    username: "laura_m",
    avatar: "https://i.pravatar.cc/100?img=15",
    bio: "Photographer and nature lover.",
    interests: ["Photography", "Nature", "Hiking"],
    integrationSettings: {},
    recentActivity: { mood: "calm", heartRate: 65, lastActive: new Date().toISOString() },
    socialData: { reddit: [], instagram: ["Posting sunset photos"], discord: [] }
  },
  {
    id: 6,
    name: "David Kim",
    username: "david_k",
    avatar: "https://i.pravatar.cc/100?img=18",
    bio: "Software engineer focused on open source.",
    interests: ["Open Source", "Linux", "DevOps"],
    integrationSettings: {},
    recentActivity: { mood: "focused", heartRate: 70, lastActive: new Date().toISOString() },
    socialData: { reddit: ["Active in r/opensource"], instagram: [], discord: [] }
  }
];

let posts = [
  {
    id: 1,
    userId: 4,
    content: "Excited to announce Sigma's new platform for personalized, agentic learning. The future of education is here. #AI #EdTech #Innovation",
    timestamp: new Date(Date.now() - 120000).toISOString(),
    likes: 152,
    comments: 45
  },
  {
    id: 2,
    userId: 1,
    content: "Hackathon mode: ON. Let's see what we can build this weekend! #coding #hackathon",
    timestamp: new Date(Date.now() - 3600000).toISOString(),
    likes: 25,
    comments: 10
  },
  {
    id: 3,
    userId: 5,
    content: "The golden hour light was perfect this evening. Capturing moments like these is why I love photography. #photography #sunset",
    timestamp: new Date(Date.now() - 7200000).toISOString(),
    likes: 58,
    comments: 12
  },
  {
    id: 4,
    userId: 2,
    content: "Just finished a new piece of digital art. The autumn color palette was so inspiring! #art #design #autumn",
    timestamp: new Date(Date.now() - 14400000).toISOString(),
    likes: 78,
    comments: 22
  },
  {
    id: 5,
    userId: 3,
    content: "Found an incredible hiking trail today. Nothing beats the fresh mountain air. #hiking #adventure #nature",
    timestamp: new Date(Date.now() - 86400000).toISOString(),
    likes: 42,
    comments: 9
  },
  {
    id: 6,
    userId: 6,
    content: "Just contributed to a really interesting open-source project. Love the collaborative spirit of the community. #opensource #programming",
    timestamp: new Date(Date.now() - 172800000).toISOString(),
    likes: 31,
    comments: 7
  }
];

let conversations = [
  {
    id: 1,
    participants: [1, 2], // Geby and Connie
    messages: [
      {
        id: 1,
        senderId: 2,
        content: "Hey Geby, you ready to win this hackathon?",
        timestamp: new Date(Date.now() - 3600000).toISOString(),
        
[truncated — 15882 more characters]
```

### CareAware/frontend/src/App.js

```javascript
import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import './App.css';
import { getApiUrl } from './config';

// Components
import Navbar from './components/Navbar';
import Dashboard from './components/Dashboard';
import Feed from './components/Feed';
import Messages from './components/Messages';
import Profile from './components/Profile';
import Settings from './components/Settings';
import ComposePost from './components/ComposePost';
import CallPage from './components/CallPage';
import UserSwitcher from './components/UserSwitcher';

function App() {
  const [darkMode, setDarkMode] = useState(false);
  const [currentUser, setCurrentUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [currentUserId, setCurrentUserId] = useState(1); // Default to Geby

  useEffect(() => {
    const fetchCurrentUser = async () => {
      try {
        const response = await fetch(getApiUrl(`/api/users/${currentUserId}`));
        if (!response.ok) {
          throw new Error('Failed to fetch user data');
        }
        const userData = await response.json();
        setCurrentUser(userData);
      } catch (error) {
        console.error("Error fetching current user:", error);
      } finally {
        setLoading(false);
      }
    };

    fetchCurrentUser();
  }, [currentUserId]);

  const toggleDarkMode = () => {
    setDarkMode(!darkMode);
  };

  const handleUserChange = (userId) => {
    setLoading(true);
    setCurrentUserId(userId);
  };

  if (loading) {
    return (
      <div className="loading">
        <div className="spinner"></div>
        <p>Loading CareAware...</p>
      </div>
    );
  }

  return (
    <Router>
      <div className={`app ${darkMode ? 'dark' : ''}`}>
        <Navbar 
          currentUser={currentUser}
          darkMode={darkMode}
          toggleDarkMode={toggleDarkMode}
        />
        
        <div className="user-switcher-container">
          <UserSwitcher 
            currentUserId={currentUserId}
            onUserChange={handleUserChange}
          />
        </div>
        
        <div className="app-content">
          <Routes>
            <Route path="/" element={<Navigate to="/dashboard" replace />} />
            <Route path="/dashboard" element={<Dashboard currentUser={currentUser} />} />
            <Route path="/feed" element={<Feed currentUser={currentUser} />} />
            <Route path="/messages" element={<Messages currentUser={currentUser} />} />
            <Route path="/profile" element={<Profile currentUser={currentUser} />} />
            <Route path="/profile/:userId" element={<Profile currentUser={currentUser} />} />
            <Route path="/settings" element={
              <Settings 
                currentUser={currentUser}
                darkMode={darkMode}
                toggleDarkMode={toggleDarkMode}
              />
            } />
            <Route path="/compose" element={<ComposePost currentUser={currentUser} />} />
            <Route path="/call/:userId" element={<CallPage />} />
          </Routes>
        </div>
    </div>
    </Router>
  );
}

export default App;

```

### CareAware/backend/textToSpeech.py

```python
import asyncio
import json
from lmnt.api import Speech

LMNT_API_KEY = "ak_GkxGopYg9FwhJaQkJ9huMC"  # Fill in your API key
JSON_INPUT_PATH = "input.json"  # Change if needed

def load_text_from_json(path):
    with open(path, 'r') as f:
        data = json.load(f)
        return data.get("text", "")  # Default to empty string if "text" not found

async def main():
    input_text = load_text_from_json(JSON_INPUT_PATH)

    if not input_text:
        print("No 'text' key found in the JSON.")
        return

    async with Speech(LMNT_API_KEY) as speech:
        synthesis = await speech.synthesize(input_text, voice='lily', format='wav')
        with open('output.wav', 'wb') as f:
            f.write(synthesis['audio'])

asyncio.run(main())

```

### CareAware/backend/speechToText.py

```python
import speech_recognition as sr
import pyaudio
import json
import datetime

r = sr.Recognizer()

with sr.Microphone() as source:
    print("Say something!")
    try:
        # Optional: reduce noise
        r.adjust_for_ambient_noise(source, duration=1)

        audio = r.listen(source)
        print("Recognizing...")
        text = r.recognize_google(audio)

        print(f"You said: {text}")

        # Create JSON structure
        result = {
            "timestamp": datetime.datetime.now().isoformat(),
            "transcription": text
        }

        # Save to JSON file
        with open("result.json", "w") as f:
            json.dump(result, f, indent=4)

        print("Saved to result.json")

    except sr.UnknownValueError:
        print("Could not understand audio")
    except sr.RequestError as e:
        print(f"Could not request results from Google Speech Recognition service; {e}")

```

### CareAware/backend/test.py

```python
import serial
import time

PORT = "COM5"     # ← your working USB-Serial port
BAUD = 115200

def main():
    try:
        ser = serial.Serial(PORT, BAUD, timeout=1)
        print(f"Listening on {PORT} @ {BAUD} baud. Press Ctrl-C to quit.\n")
    except serial.SerialException as e:
        print(f"❌ Could not open {PORT}: {e}")
        return

    try:
        while True:
            line = ser.readline().decode("utf-8", errors="ignore").strip()
            if not line:
                continue
            # Expect CSV: BPM,Temp,Hum
            parts = line.split(",")
            if len(parts) == 3:
                bpm, temp, hum = parts
                print(f"❤️ {bpm} BPM | 🌡️ {temp}°C | 💧 {hum}%")
            else:
                print(f"⚠️  Unparsed: {line}")
    except KeyboardInterrupt:
        print("\nExiting…")
    finally:
        ser.close()

if __name__ == "__main__":
    main()

```

[19 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]