← All posts

Nine Projects, One Developer, Zero Excuses

An ESP32 busy light, a flaky test detective, a GitHub dashboard on a Pi, a parenting app, generative art, a prank for my wife, a screaming boot, and a local AI server. All at once. Here's the full inventory.

Last week my son Vasco and I wired a DFPlayer Mini to an Arduino on a breadboard. The plan: hide it in a kitchen cupboard so that when my wife opens the door, James Brown sings "I Feel Good" at full volume. It's a terrible idea. We can't wait.

That same week I was debugging Electron IPC handlers, flashing firmware to an ESP32 over USB-C, and deploying a React dashboard to a Raspberry Pi running in kiosk mode behind nginx.

This is what my evenings look like. I build things. Some of them useful, some of them absurd, most of them unfinished at any given moment. This blog is where I'll document all of it.

The Inventory

I've got nine active projects right now. Some are products under a brand I'm calling Today we Dream. Others are weekend experiments with my kids. Here's the full list, roughly ordered by how much code I've written for each.

SubCat: Flaky Test Detective

SubCat mascot: a cat-submarine hybrid with sunglasses

Stack: Electron 35, plain JS, better-sqlite3, electron-builder
Status: v1.1.1, code-signed and notarized, 246 tests. GitHub

SubCat started as a simple GitHub Actions notification app. Paste a workflow run URL, get a native macOS notification when it finishes. Useful, but Gitify already does most of that for free.

The pivot came when I realized the real pain point isn't knowing a run failed. It's proving a test is flaky. You re-run a workflow 20 times, watch half of them, lose track, and then try to explain to your team which test failed 3 out of 20 runs.

SubCat's repeat mode lets you fire N runs of a workflow and generates a flakiness report: Markdown with pass/fail counts per test, labeled Stable, Probably Flaky, or Flaky. No scripts, no spreadsheets, no "I swear it failed yesterday."

The next step is a local stress test mode: run your test suite N times inside a Docker container that matches your CI runner's constraints (2 vCPU, 7 GB RAM). Fix a flaky test locally, verify it locally, skip the CI bill.

No framework. No build step. Vanilla JS all the way down. I know that sounds insane in 2026 but I don't want to fight a bundler when I'm debugging Electron IPC at midnight.

ObviouslyBusy: The "Do Not Disturb" Light

Stack: Electron (macOS), ESP32 (Arduino/C++), WiFi + BLE
Status: v0.2.0, software complete, hardware partially assembled

I have a home office. Closed door, desk, the works. Doesn't matter. When I'm on a Teams call, my kids walk straight in like the door isn't there.

ObviouslyBusy fixes this. A macOS app detects when my microphone is active (using a native Swift binary) and sends an HTTP request to an ESP32 on my local network. The ESP32 drives two LEDs: red for busy, green for free.

The architecture is simple enough that I can explain it in one sentence: Electron polls a Swift child process, updates a state machine, and POSTs /on or /off to an ESP32 running a basic HTTP server.

What made this interesting:

  • WiFi + BLE simultaneously on the ESP32 required a non-default partition scheme (No OTA, 2MB APP/2MB SPIFFS) because both stacks don't fit in the standard flash layout.
  • Network discovery scans the local subnet and tries mDNS before falling back to a stored config, so the ESP32 doesn't need a static IP.
  • The tray icon is animated generative art (more on that below).

Hardware is still in progress. The original plan was a retro ON AIR sign. The new plan is a 3D-printed enclosure with two plain LEDs. Less romantic, more likely to actually ship.

Ship Happens: GitHub Dashboard on a Pi

Stack: Node.js, React, Vite, Tailwind, SSE
Status: Running in production on a Raspberry Pi

A dashboard that shows open PRs, requested reviews, and CI pipeline status for a GitHub repo. It runs on a Raspberry Pi connected to a monitor in kiosk mode: Chromium on X11 with openbox, no desktop environment.

The backend polls the GitHub API and pushes updates to the frontend via Server-Sent Events. PRs refresh every 60 seconds, workflow runs every 15. Merged PRs roll in every 5 minutes.

Deploy is automated: push to main triggers a GitHub Actions workflow that builds the client, commits the dist, and then a self-hosted runner on the Pi pulls and restarts the systemd service. The screen turns off at midnight and back on at 8am via cron.

LevelMind: Parenting Through Gamification

LevelMind UI: credit balance, study/exercise/gaming timers

Stack: Node.js, Express, React, Vite, better-sqlite3, PWA
Status: v0.3.0, deployed on my NAS via Docker

My son Vasco is 10 and loves gaming. We made a deal: earn screen time by reading, studying, or doing sports. 1 minute of reading = 2 minutes of gaming credit. 20 minutes of exercise unlocks gaming for the day. Cap at 90 minutes. No gaming on Mondays and Tuesdays.

I could have tracked this on paper. Instead I built a full-stack app with persistent timers, JWT auth, a parent dashboard with Recharts graphs, and PWA support so Vasco can launch it from his phone's home screen.

The timers are timestamp-based, not interval-based, so they survive the phone going to sleep, the browser tab getting killed, or Vasco switching to check something "real quick" (it's never quick). Active timers persist in SQLite and sync across devices.

Is it over-engineered for a family of four? Absolutely. Did Vasco design the rules himself? Also yes. Does he check his credit balance before asking to play? Every single time.

GenArt: Generative Art That Ships as UI

Stack: canvas-sketch, Node.js
Status: Active, integrated into ObviouslyBusy

A set of generative art sketches built with canvas-sketch. The main one generates grids of horizontal bars with configurable color palettes (teal and red) and film grain.

This isn't just decorative. The same generation algorithm produces:

  • The tray icon for ObviouslyBusy: 8 animation frames in red (busy) and a static teal frame (free), generated with fixed seeds for consistency.
  • An SVG export for laser cutting or printing.
  • App icons at 1024x1024.

I like when art has a job. These sketches earn their keep.

I Feel Good: The Cupboard Prank

Vasco wiring the I Feel Good breadboard

Stack: Arduino Uno, DFPlayer Mini, LDR, 8 ohm speaker
Status: Breadboard wired, ready to flash

This one's simple. A light-dependent resistor detects when the cupboard door opens (light floods in). The Arduino triggers the DFPlayer Mini to blast James Brown through a small speaker hidden behind the cereal boxes.

Vasco and I built this together on a Saturday afternoon. He did most of the wiring. I only had to fix the voltage divider placement once. He put the resistor on the wrong side of the LDR, which meant the analog reading was inverted. Debugging electronics with a 10-year-old is slower than debugging alone, and about ten times more fun.

Next step: flash the sketch, test it, and wait for the right moment.

samuelfialho.com: This Blog

Stack: Analog.js, Cloudflare Workers
Status: Live, you're reading it

Built with Analog.js (Angular's meta-framework), deployed as a static site via Cloudflare Workers. Blog posts are Markdown files with frontmatter. No CMS, no database, no admin panel.

I chose Analog because Angular is what I use at work and I wanted to explore the SSG side. The deploy pipeline is zero-config: push to main, Cloudflare builds it, done.

Today we Dream: The Umbrella

Today we Dream isn't a project. It's the brand that ties SubCat, ObviouslyBusy, Ship Happens, and LevelMind together. The idea is simple: these aren't side projects. They're products. Small, opinionated, built by one person, but products nonetheless.

Each one scratches an itch I had at work or at home. SubCat came from weeks of manually re-running flaky workflows. ObviouslyBusy came from my family interrupting calls they couldn't see. Ship Happens came from constantly switching tabs to check CI. LevelMind came from a parenting negotiation that needed a system.

I'm not pretending this is a startup with a pitch deck and a runway. It's a solo developer shipping tools under a name that means something to him. If one of them takes off, great. If not, I'll have built things I actually use every day. And that's enough.

Why All at Once

I get asked this a lot. Why not focus on one project?

Because they feed each other. SubCat exists because I kept running into flaky tests at work. Ship Happens exists because I wanted to see my team's PR status without opening GitHub. ObviouslyBusy exists because I work from home and my family needs a signal. LevelMind exists because my son needs structure and I need data.

And the kids' projects (I Feel Good, the wiring sessions, the soldering) exist because I want Vasco to grow up thinking building things is normal. Not special. Not reserved for engineers. Just something you do on a Saturday when you have an idea and a breadboard.

The Real Reason This Is Happening Now

I've had most of these ideas for years. The busy light, the flaky test tool, the gaming tracker. They lived in a notes app, waiting for a weekend that never came. A solo developer can only ship so much in the evenings between dinner and sleep.

Then AI happened. Not the hype cycle. The actual, practical, "I can build a full Electron app in a week" kind of AI.

I haven't felt this way about technology since the first iPhone. That same feeling of everything is about to change and I need to be inside it, not watching from the sideline. AI isn't replacing my engineering. It's removing the friction that kept ideas stuck in my head. The boilerplate, the Stack Overflow rabbit holes, the "I know what I want but I'd need three hours just to set up the project" problem. That's gone now.

So I'm learning by building. Not tutorials, not courses. Actual products that solve actual problems I have. Every project in this list is a way to explore what it means to be an AI-native engineer. How far can one person go when the bottleneck shifts from typing speed to taste and judgment?

Turns out, pretty far.

Crazy Shoe: The Boot That Feels Pain

Stack: Arduino Uno, DFPlayer Mini, FSR406, 8 ohm speaker
Status: Complete. Paraded at Science Week.

Vicente is 3. His school asked for a "crazy shoe." The original plan was a boot that teaches gravity facts in his voice. The reality: he can barely finish a sentence. So we pivoted. The boot complains every time it touches the ground. "Ai!" "Ui!" "Estás a pisar-me!"

Same hardware as I Feel Good, different trigger (pressure sensor instead of light sensor). Wrapped in aluminium foil, strapped with red tape, wires everywhere. It looked like a bomb. But it was just a cute little boot.

Vicente loved the idea, then felt sorry for the boot and didn't want to wear it. We convinced him. He walked a parade in it. The other kids lost it.

Titan: Local AI Server

Stack: Ryzen 7 3700X, RTX 3090, Ubuntu 24.04, Ollama, Hermes Agent
Status: Running 24/7, wiki ingestion pipeline operational

A hand-me-down PC from a family member, Frankensteined with a new GPU and PSU. Runs four language models locally (Gemma 4 26B, Qwen 2.5 Coder 32B, Qwen 2.5 72B, nomic-embed-text) and processes knowledge bases into my Obsidian vault while I sleep. Total hardware investment: €688. After that, every inference is electricity only.

What's Next

I'll write deeper posts about each project: the technical decisions, the dead ends, the architecture diagrams I should have drawn before I started coding. I'll also write about what it's like to build with AI as a genuine collaborator, because at this point Claude is involved in most of what I ship and I have a lot to say about where that's headed.

If you're a developer who builds things outside of work, or a parent who does hardware projects with their kids, or just someone who thinks shipping beats perfecting: you're in the right place.

Let's make stuff.