This is a submission for Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady.

What I Built

Pomodoro timers have a dirty secret: the 25 minutes isn't the hard part. Deciding what to do with them is. You hit Start, stare at "my history essay," and burn 10 minutes reorganizing your desktop.

So I built Tuck: a tiny 3D acorn in a leaf hat who sits next to your timer and does the deciding for you.

  1. Type what you're working on ("my history essay") and hit Start.
  2. Tuck, running on open-weight gpt-oss-20b, shrinks it to one goal that fits the session: "Draft the intro paragraph. Just that."
  3. He sits down and works quietly next to you. No notifications. No streaks. No guilt.
  4. When time's up he asks "Did you finish?" Tap Yes, Almost or Not yet. He hops, nods or tilts his head kindly, then hands you the next small step.

Tuck asks

Stuck mid-session? Ask Tuck has four one-tap buttons: Plan this session, I'm stuck, I'm distracted and Quiz me. Replies are a sentence or two, on purpose. A focus buddy that writes you an essay is just another tab.

Demo

Live: https://pocket-pal-teal.vercel.app

Type a task and hit Start. Don't want to wait 25 minutes for the check-in? Set Focus to 1 minute in Settings.

Every screenshot here is the live app with real gpt-oss replies.

1. Type four words.
The timer reads 25:00 with

2. Tuck turns them into one goal, then sits down and works with you.
Mid-session at 18:38: the goal line reads

3. Time's up, he checks in. No verdict until you answer.
Short break:

4. Tap Yes and he jumps.
Tuck mid-hop with his shadow on the floor, saying

5. Your next step is already waiting, with zero extra AI calls.
Tuck smiling,

He fits in your pocket too.
Phone layout: the timer at 15:15 on top, Tuck in the middle saying

Code

GitHub logo UribeJr / pocket-pal

Pocket Pal: a tiny 3D desk companion PWA (Phase 1)

Meet Tuck: your focus partner

Meet Tuck. He'll sit with you till it's done.

Tuck is a calm Pomodoro timer with a focus partner: a tiny 3D acorn who keeps you company. Tell him what you're working on and he turns it into one small goal that fits your session. When the timer ends he asks "Did you finish?" and reacts: a hop for a win, a nod for "almost", a kind head tilt for "not yet". Then he suggests the next step.

Live: https://pocket-pal-teal.vercel.app

How it works

  1. Start with an intention. Type "my history essay" and press Start. The timer starts at once, and Tuck replies with a goal like Draft the intro paragraph. It's sized to your real focus length (25 minutes by default, or whatever you set).
  2. Focus. Tuck sits and works quietly beside you. If you get stuck, open Ask Tuck and tap I'm stuck, I'm distracted or Plan this session. Each…

How I Built It

Tuck is a real 3D character, not a sticker. I modelled and rigged him in Blender, exported a GLB, and render him with React Three Fiber on Next.js 15, React 19 and TypeScript.

  • He lives in a soft "infinity cove" studio. The camera uses a view offset so the room flows behind the timer as one space.
  • A small emotion system drives his faces, blink rate, and an allowlist of clips: hop, stretch, sit, wave.

The timer is pure timestamps. Reload, background the tab, close your laptop for three hours. It never loses or double-counts a session.

The AI loop is tiny on purpose. About two calls to openai/gpt-oss-20b on Groq per Pomodoro: one at Start (the goal), one at the check-in (reaction plus next goal).

  • Replies follow a strict JSON schema: line, goal, emotion, action.
  • The server validates them with zod. Nothing the model writes ever becomes HTML.

The model suggests. The app decides the body. Whether Tuck hops, nods or tilts at check-in comes from your answer, never the model. The model only gets to pick from a short list of safe moods.

Guardrails live in the prompt:

  • Quiz me asks one question and grades your answer in your own words.
  • "Write my essay" becomes "let's outline it together."
  • Stress gets a warm acknowledgement before any advice.
  • Time questions are answered from the real timer ("You've been focusing for 12 minutes").

Ask Tuck:

Ask Tuck:

The bug that gaslit me

After two good replies, every message said "Ask Tuck isn't connected. It needs its AI key." The key was right there.

Production logs said otherwise: Groq was returning 400 tool_use_failed. gpt-oss sometimes decides to call a tool, even when you define zero tools. My error handling lumped every weird 400 into "misconfigured," and the UI translated that to "no key." So the app was confidently lying to me about the wrong problem.

The fix:

  • Treat it as a bad sample. Resample once, cooler, as a forced call to a single tuck_reply function. The model wants to call a tool? Fine. It gets exactly one.
  • Fail fast on rate limits instead of retrying into a wall.
  • Fall back to gpt-oss-120b, which has its own rate-limit bucket.

Every error now shows an in-character line, like "Phew, I need a quick breather. One minute?", with a Try again button.

Building for a free tier

Groq's free tier for gpt-oss-20b is 8,000 tokens a minute, shared by everyone using the app. That constraint designed half the product:

  • Short goals, not long tutoring answers.
  • A slim prompt of about 900 tokens.
  • The goal Tuck suggests at check-in becomes your next Start, no extra call.
  • No AI where none is needed. Timer lines and reactions stay local.

Why Does Open Innovation Matter?

  • I'm not locked in. gpt-oss-20b is open-weight under Apache 2.0. Today Groq serves it fast and free. The same code points at any OpenAI-compatible server with one env var, AI_BASE_URL, including Ollama or LM Studio on your own laptop. (Haven't tested a local server yet.) For a focus app, that means your tasks could stay on your machine.
  • Swapping models is config, not a rewrite. Falling back from 20b to 120b took zero code changes.
  • Open weights come with open docs. When the model did something weird, like reaching for a tool that didn't exist, I could read how it formats responses and design around it instead of guessing at a black box.
  • Where open beat closed for me: cost and control. You don't need the biggest closed model on earth to say "Draft the intro paragraph. Just that."

The Lazy Payoff

You type four words. Tuck picks the one thing worth doing in the next 25 minutes, sits with you while you do it, and checks in after. Slow and steady: one small goal at a time, no to-do list required.

Go say hi: https://pocket-pal-teal.vercel.app 🌰