Cal Hacks 12.0 in San Francisco, with Marcus Lee

Argus

A video surveillance platform Marcus Lee and I built in 37 sleepless hours at Cal Hacks 12.0 in San Francisco. It streams cameras through Mux, finds events with Gemini and Roboflow, and makes them searchable. It took home two first places.

Type
Hackathon project, 2 first places
Timeline
October 24 to 26, 2025
Stack
TypeScriptNext.jsSupabasePostgreSQLMuxGeminiRoboflowElasticsearch
Links
Result
2 first places, 2 internship offers
System
Mux → Supabase → worker → models
My focus
Detection, stats, landing page
Argus key art

Cal Hacks 12.0

Two students from Montreal at the largest collegiate hackathon

Marcus Lee and I applied to Cal Hacks 12.0 kind of out of the blue, and we got in. It ran October 24 to 26, 2025 at the Palace of Fine Arts in San Francisco. It's North America's largest hackathon, and supposedly the largest collegiate hackathon in the world.

We were blown away. Montreal has a good tech scene, but nothing like what we saw there. There were thousands of students in one hall, a lot of them from schools I'd only ever heard about from Canada, and it really hit me that this is where things are happening.

Carson and Marcus at the Cal Hacks 12.0 photo booth, one holding an 'I paused my game to be here' sign, the other in a green wig and fake moustache
Marcus and me at the photo booth.
A hangar-sized hall filled with rows of tables and hackers at laptops, seen from a balcony
The main hall, from the balcony.

San Francisco

Seeing as much of the city as we could

I flew direct from Montreal to San Francisco and came home through Vancouver. It was my first time in a city like SF, so between building sessions we tried to take in as much as we could: walking downtown, hanging around the Palace of Fine Arts, and some seriously good Vietnamese food a few blocks from the hotel.

Map of North America: a solid line from Montreal direct to San Francisco, and a dashed line home from San Francisco to Vancouver to Montreal
Direct on the way out, through Vancouver on the way home.
Map of San Francisco marking the Palace of Fine Arts, the Golden Gate Bridge, downtown, and our hotel area between the Tenderloin and Nob Hill, with a dashed line from the hotel to the venue
The venue, the hotel, and the rides between them.

The venue's Wi-Fi had issues from the start, so everyone switched to their phone hotspots, and with three thousand-plus hotspots in one room, pretty much nobody could get online. Argus streams video to Mux and calls three model providers, so we needed internet. We packed up and went back to our hotel in the Tenderloin and Nob Hill area, which was definitely an environment, and built from there.

Every few hours I'd head out to the corner store to grab more energy drinks, and neither of us slept the whole time.

The Waymo

Our Waymo got stuck

We took a Waymo for the first time, and it ended up getting stuck in a parking lot by the Palace of Fine Arts, right next to another Waymo that was also stuck. For two kids who don't have Waymo back home, that was pretty much our worst nightmare.

A bunch of people started recording us sitting there stuck in the Waymo, a few minutes from the Golden Gate Bridge, on my first trip to a city like San Francisco. So that was awesome.

What it does

Surveillance footage you can search and question

Argus is named after Argus Panoptes, the many-eyed watchman from Greek myth. It takes live camera feeds and uploaded recordings, figures out what happened in them, and lets an operator search those events, ask questions about them, and turn them into incident reports.

Gemini 2.5 describes each clip as a set of events, each with a severity, a type, a time, and the people and objects involved. Roboflow draws a box around every person, eight frames a second. Both land on the recording's timeline, so clicking an event jumps the player right to it.

Argus watch page: doorbell camera footage with a green Roboflow box around a man reaching toward the camera, above a scrubber with event markers
A recording with Roboflow's person box and event markers. Image: Devpost.
Argus AI chat answering 'Has anyone shoplifted recently?' with a Medium severity event card: item selected and concealed, at 0:23
The chat finds the event and links to the moment. Image: Devpost.

The chat defaults to Claude Haiku 4.5, and you can switch to Claude Sonnet 4.5, Kimi K2 on Groq, or a Letta agent. It searches the database through tools and shows events as cards. From a conversation, it can draft an incident report that opens in a Tiptap editor.

System

Four services and one Postgres queue

A browser camera streams WebM over a WebSocket to a Node server running next to Next.js. That server pipes it through FFmpeg and pushes RTMPS to Mux, which runs the live stream, records it, and cuts clips on demand.

When a recording is ready, Mux calls a Supabase Edge Function, which drops analysis jobs into ai_analysis_jobs. That Postgres table is the only queue in the whole system. Every minute, a scheduler in the worker also adds 20-second windows for live streams and 60-second windows for recordings.

Architecture: camera over WebSocket to a Node relay running FFmpeg, RTMPS to Mux, webhook to Supabase, which feeds an analysis worker calling Gemini and Roboflow, then Elasticsearch and a Next.js dashboard with Claude, Groq and Letta chat
Ingest along the top; analysis and the interface along the bottom.

Supabase Realtime pushes new events, jobs and reports to the dashboard, so nothing polls. Every event also gets synced into Elasticsearch, where ELSER semantic search plus lexical matching powers both the search page and the stats.

Pipeline

One recording, start to finish

The worker checks the queue every five seconds and runs up to three jobs at once. For each one, it asks Mux for an instant clip of that window, transmuxes the HLS segments to MP4 with FFmpeg, and sends the MP4 off to the models.

Live windows only go to Gemini. Recordings go to Gemini and Roboflow in parallel. If Roboflow fails, the job still succeeds, just without boxes. If Gemini fails, the job retries up to three times, waiting 10 seconds and doubling each time.

Animation of a 60-second recording moving through seven steps, from Mux webhook to job queue, worker, FFmpeg clip, Gemini and Roboflow, saved results and Elasticsearch, while worker log lines print and a timeline event card appears
The log lines are the worker's own; job numbers and counts are illustrative.

My part

Detection, stats and the landing page

Marcus owned the backend: video processing, the worker and the AI features. I owned the frontend and the pipelines feeding it, and made 49 of the 93 commits in those 37 hours.

I wrote the Roboflow detector. FFmpeg pulls 8 frames a second, each one goes to Roboflow's hosted person-detection model, and anything under 0.3 confidence gets dropped. I drew the boxes over the player and wrote the tracking stats that follow people from frame to frame.

Argus statistics page with totals for events, critical events, event types and entities, a severity donut, an event-type bar chart and an entity-type donut
The stats page, built on Elasticsearch aggregations. Image: Devpost.
Argus landing page: the word ARGUS beside a large eye drawn in red dot characters on black
The landing page, built on the last night. Image: Devpost.

I built the stats page on Elasticsearch aggregations: severity, event types, entities, recording lengths and occupancy, with date filters and chart colours interpolated in HCL. On the last night I built the landing page, then GitHub sign-in and the mobile nav.

Results

Two first places and two offers

We demoed at a table in a huge open space with thousands of other teams presenting all around us. You could tell people had built really good projects, and a lot of them were from the Ivy League schools you hear so much about where I'm from in Canada. Then Argus ended up winning two first places: Conway's Most Data-Intensive Application and a37's Best Use of A37.

Two photos of 'Winner: Argus' on projector screens in the hall, beside cards for Conway's Most Data-Intensive Application prize and a37's Best Use of A37 prize
Both prize announcements, from our seats.

Both are cool companies working on really interesting problems. Conway trains predictive models on event streams for Fortune 500 engineering teams, and a37 builds Forge, which finds, governs and polices the AI agents running inside a company. We got internship offers from both of them, which was super cool.

Takeaways

What I took away from it

Argus is the most complete hackathon project Marcus and I have built. It used eight outside services, and running it locally took four terminals: ngrok for Mux's webhooks, Next.js, the worker, and Supabase in Docker.

But the bigger thing for me was the people. We met so many smart people and saw so many cool projects. I'm confident, without a shadow of a doubt, that a lot of the people we saw there, and so many more that we didn't, are going to do amazing things and shape the world, so getting to be in that space with them was a crazy opportunity.

All case studies