Inspiration

Most focus tools measure time: how long you worked, how many Pomodoros you finished, or which apps you opened. But the thing we actually care about is harder to see: when your eyes are still on the page, but your attention has already drifted.

Flow was built around that moment. We wanted a focus tracker that could notice physiological and behavioral signals during a work session, intervene gently when it matters, and then turn the session into useful insights afterward.

What it does

Flow is a webcam-based focus and physiology coach. During a tracker session, a local agent reads derived signals like pulse, breathing rate, HRV, blink activity, confidence, and screen context. It classifies the session into states like focused, zoned out, spiraling, warmup, and no signal.

When Flow notices a problem, it can intervene live with a soft chime or a guided breathing widget. For example, if breathing rises above 20 breaths per minute, Flow can trigger a calming breathing loop. After the session ends, the data is saved and shown on the Sessions dashboard, where Flow summarizes past sessions and highlights patterns a person can actually act on next time.

Examples of insights Flow is designed to surface include:

  • which apps cause the longest refocus latency
  • what time of day produces the best focus quality
  • when longer sessions start producing diminishing returns
  • whether breaks and breathing interventions actually helped

How we built it

Flow is a TypeScript monorepo with three main apps:

  • apps/agent: a local webcam sensing agent using Presage SmartSpectra for camera-based rPPG signals like pulse and breathing
  • apps/api: a Fastify API that stores sessions, samples, events, and generated summaries
  • apps/web: a Next.js dashboard with the live Tracker page, Sessions history, Insights, and Validation views

The live Tracker page talks to the local agent over WebSocket, while persisted session data is uploaded in batches to the API and stored in Tiger Cloud / TimescaleDB. Gemini generates session narratives and next-session recommendations from computed session metrics. ElevenLabs powers speech for breathing/reset flows. The public app is deployed with Docker, Caddy, and Vultr at tryflow.study.

Raw camera frames stay local. The dashboard only stores derived measurements and context fields.

Challenges we ran into

The hardest part was making the system feel live without making it fragile. The webcam agent streams frequent sensor data, while the web dashboard renders charts and state changes in real time. We had to smooth noisy readings, avoid stale values pretending to be fresh, recover from camera/SDK stalls, and make sure ending a session reliably flushed data into the database.

Another challenge was turning raw physiology into something useful instead of overwhelming. A number like “breathing 21/min” is not enough by itself. Flow has to translate that into a clear next action, like taking a guided breathing reset, while still being honest about confidence and missing signal.

What we learned

We learned that focus tracking is most useful when it becomes specific. “You were distracted” is not very helpful. “Slack checks caused the longest refocus delay” or “your deep work usually drops after 50 minutes” is actionable.

We also learned how important it is to separate local sensing from persisted analytics. Keeping the raw camera path local made the product safer and simpler, while still allowing session history and insights to work from derived data.

What's next

Next, we want Flow to improve its recommendations across many sessions: better refocus-latency modeling per app, stronger time-of-day focus quality insights, and more personalized break timing. We also want to make the breathing intervention smarter, so it can adapt its pacing based on the user’s current breathing instead of using one fixed loop.

Built With

Share this project:

Updates

Submission history