Too Lazy to Click, Too Active to Text: Meet 'I Am Groot'
When running on ice with gloves and a buried phone, typing is not an option. So I gave Groot ears and a voice — and built an Android voice assistant in five hours without touching Android Studio.
Too Lazy to Click, Too Active to Text: Meet ‘I Am Groot’
I was lying on the couch, the TV was playing in the background, and instead of processing what just happened on that run — alone, 6 km through ice, heart rate spiking with no one to ask “am I pushing too hard?” — I typed a single sentence on Telegram:
“Groot, I need to be able to talk to you while I’m running.”
That sentence connected two things I hadn’t connected before.
The first: I’m too lazy to click. You’ve read about that. I delegate groceries, calculators, and anything else that involves opening an app and doing something with my hands. That’s what this series is about.
The second: I’m too active to text. When I’m running, the phone is in a deep pocket, my hands are moving, and on a bad day there’s ice underfoot. Typing is not an option. Voice is the only interface that makes sense.
These are the same problem. One is about convenience. The other is about physical impossibility. Both end up in the same place: if you can’t delegate it to a voice assistant, it doesn’t get done.
This is the post where those two things collide. And where a new series begins.
The Run That Started This
Earlier that day I ran 6.35 km.
It wasn’t supposed to be hard. I had a strategy — built with Groot a few days earlier, based on my Garmin history. I had a playlist, created by Groot, synced to Spotify, tuned to my target pace of 5:50/min.
I had a plan.
The plan did not survive contact with reality.
The snow was packed and uneven. Patches of ice. My heart rate hit 181 bpm by kilometer two — not because I was pushing, but because the conditions were fighting back. I kept the pace conservative, saving something for the finish. The last stretch came in at 5:35 — I had legs left, but I didn’t know it. No one was watching the fatigue curve. No one to do a quick data check and say “you’re fine, you can push now.”
That’s not an app problem. That’s a coaching problem.
My Garmin saw tempo and heart rate. It did not see the ice. It did not know I was working harder just to stay upright. That gap — between sensor data and real context — is exactly what a live coach bridges.
What I needed wasn’t better data. I needed someone to interpret it. In real time. While I was moving.
What I had was Groot — but only on Telegram.
And Telegram, while running, with gloves, with a phone buried in a pocket, is effectively useless.
I needed Groot to have ears. And a voice. Turns out, he was happy to give himself both.
Observation:
The tools we use on the couch don’t work on the road. Not because they’re bad tools — because the interface doesn’t fit the context. That mismatch is the whole problem. And the whole opportunity.
One Sentence, One Repo, One Problem
I got home, opened Telegram, described the problem.
Groot’s first response wasn’t “sure, here’s the code.” It was a reality check:
“Brutal truth: pure Web Speech API won’t work reliably on Android with the screen locked. The OS kills audio and JS in the background. The plan needs to be: web UI + native Android service.”
That was the moment I realized this was going to be a real project, not a five-minute hack.
I created a repo: live-coach-vibed. Pushed it to GitHub.
That was my only technical contribution to the codebase.
Why didn’t Groot create the repo himself? He could have — technically. But repositories connect to accounts, and accounts have access to other things. I’m not in the habit of handing over broad GitHub tokens for convenience. Scoped access, deliberate boundaries. The blast radius should always be small.
So I created the repo. Groot did everything else.
Observation:
Autonomy works best when the boundaries are explicit. Inside those boundaries: full delegation. Outside them: human checkpoint. That’s not a limitation of the tool — it’s a design principle.
From Empty Repo to Working App
Forty-five minutes later I had a working web UI.
WebSocket server, OpenClaw bridge — the same runtime I wrote about here — PTT button, audio flowing from browser to backend and back. Basic but real. The data flow at this point:
Phone → WebSocket → Node.js server → Bridge → OpenClaw → LLM → TTS → back to phone
But web on a locked Android screen is a dead end — the OS suspends it. So Groot kept going.
I asked how to test the Android app. He told me to open it in Android Studio.
I said: “I don’t have Android Studio. I only have you.”
He set up GitHub Actions. On every push to main, a signed APK gets built automatically — ready to install, no local toolchain needed. Six minutes after a code change, I had a new version on my phone. I never opened Android Studio. I never touched Gradle.
Observation: “I only have you” is not a limitation. It’s a delegation pattern. The question stopped being “how do I build this” and became “what do I want this to do.” That shift is the whole point.
Five Hours of Walls
What followed was not smooth. It was iterative — and honestly, that’s the interesting part.
The first real deployment behind Nginx hit a 502. Backend and proxy were fighting over the same port. One config change, five minutes, done. Then Android blocked the WebSocket connection entirely — cleartext traffic not permitted by default. One line added to the manifest, tradeoff explained (fine for dev, not for production), pushed.
Then the first voice response came through. And it said: “asterisk asterisk here’s what I found asterisk asterisk.” Groot’s responses contain markdown. TTS reads it literally.
Groot fixed it immediately — added a sanitizer on the client side, pushed. I tested it, then said: the backend should handle this, not the client. One fix in one place, and every future version of the app gets it for free without a rebuild. Groot moved the sanitization to the bridge layer, pushed again. That back-and-forth mattered more than the bug itself. He knew how to fix it. I knew where it should live.
This was the pattern throughout the day. Something felt off, I said what was wrong, Groot fixed it. The buttons take up half the screen — settings moved to a separate screen. I can’t tell if the service is running — color-coded status dots added. When Groot talks, Spotify pauses and stutters — replaced with audio focus ducking, where music lowers during the response and comes back after.
My call on all of these as a user. Groot’s call on how to implement each one. None of it was “change function X to do Y.” Just: this is broken, fix it.
Before

After


Observation:
Every one of these was reported as a user experience problem, not a technical specification. I describe what’s broken from the outside. Groot figures out what’s broken on the inside. That separation is the whole workflow.
”Hej Gród”
There are two ways to start a conversation with the assistant. The first is a button — long press on the headphone control, Groot announces himself, you talk, he responds. Simple and reliable. The second is a wake phrase — say “Hej Groot” anywhere, the app picks it up, same flow without touching anything. The second one is what you actually want when you’re running with gloves and a phone buried in a pocket.
Both modes were working. The button trigger worked first try — long press, tone, talk, response. No surprises. So I moved on to the wake phrase.
I said “Hej Groot.”
The app heard: “hej gród.”
Nothing happened. Wake check: not matched (heard: "hej gród"). STT was transcribing a Polish approximation of an English name — which is completely reasonable, because that’s exactly how it sounds when a Polish speaker says it.
I told Groot. He added fuzzy matching across the likely variants — grod, grut, grot, gród — and a debug line that shows exactly what was heard and whether it matched, so we wouldn’t have to guess next time.
Next test: Wake check: matched (heard: "hej gród") — Groot here.
And then I talked. And Groot responded. In my earphones. Standing in my apartment, pretending to run.
It worked.
Observation:
“Works” and “works for how humans actually speak” are two different things. The gap between them is usually small technically and enormous experientially. Bridging it is not an afterthought. It’s the product.
The Name
By evening the app was working, tested, and had gone through enough iterations to feel like something real. At some point during one of those tests I said to Groot:
“Change the app name. This isn’t live-coach anymore. It’s ‘I am Groot.’ And give it Groot’s icon.”
He pushed the commit. The app on my phone updated. The icon changed.
live-coach-vibed stayed as the repo name. But what was installed on my phone, running in the background, waiting for “hej gród” — that was I am Groot.
Somewhere in those commits, Groot gave himself ears and a voice. I’m not sure he noticed.

The conversation was triggered by a long press on the headphone button — the same gesture that normally activates Google Assistant. From the moment Groot says “Groot here,” a continuous conversation mode is active — I can keep talking naturally until either a few seconds of silence ends the session, or I press the button again. You’ll hear a system sound toggling the listening state in the background — still a rough edge, but the conversation flow already feels right.
What “I Am Groot” Is
An Android voice communicator. Foreground service that stays alive with the screen locked. Wake phrase — “Hej Groot” (or “hej gród,” it handles both). Two-way voice conversation without touching the screen. Session history. Spotify integration that ducks instead of pauses.
Groot’s commit history by the end of the day:
- The Android app (Kotlin)
- The WebSocket server (Node.js)
- The OpenClaw bridge
- The CI/CD pipeline that builds APKs on every push to
main - The audio pipeline (PCM → WAV → Whisper)
- The session persistence with local history
- The markdown sanitizer in the bridge layer
- The fuzzy wake phrase matching
I created one empty repository and spent five hours describing problems.
Observation:
There’s a version of this story where I say “Groot built everything.” That’s technically accurate and completely misses the point. Every decision about what to build, how it should feel, where the boundaries are — those were mine. What Groot eliminated was the translation layer between decision and implementation. That’s not a small thing. That’s most of the time in software development.
Where This Goes
The app exists. The wake phrase works. The voice loop works.
What doesn’t exist yet: Groot actually watching my run and reacting to it. Live Garmin data. The moment where he says “your heart rate has been elevated for two minutes — ease up” without me asking. The moment where he changes the playlist tempo because I told him the snow is bad today.
But running is just the beginning. Cooking dinner and talking through a recipe. Riding a bike trainer and pair-programming by voice. Any moment where your hands are busy but your mind isn’t.
That’s what #TooActiveToText is about. Using AI when your hands are busy, your breath is short, and the only interface available is your voice.
The couch series got me here. The voice series starts now.
I was lying on the couch, the TV was playing in the background, and Groot had already reminded me earlier that day to write a blog post. I hadn’t written it yet. I was too busy describing problems to an AI that was turning them into commits.
He’s still not sure which one of us is more productive.
Neither am I.