cookbook
100% freeAgent lifecycle status (Thinking… → idle)
Make your notch show, automatically and in perfect sync, when an AI agent is working vs done, with zero per-message effort.
This is the exact recipe that powers the "Thinking… ✨ Claude" line on the author's own notch. Paste the Claude Code block below and you have it in under a minute: no code, no restart.
The problem
Marking "working" is easy: an agent fires update as its first tool call. Marking "done/idle" is hard: an agent's last act is streaming text to you, with no tool call after it, so it can't cleanly signal "I finished." The notch ends up showing a stale state ("Standing by" while still talking).
The principle
Idle/done detection belongs in the agent's harness (the runtime around the model), not in the agent's own output and not in Tellie. The harness knows exactly when a turn starts and ends. So:
- Turn starts → tell Tellie the agent is working.
- Turn ends → clear the agent's line (or set it to idle).
Most harnesses already expose these as lifecycle hooks.
Claude Code
Claude Code has UserPromptSubmit (turn start) and Stop (turn end) hooks. Add this to ~/.claude/settings.json (global) or a project's .claude/settings.local.json (personal, per-project):
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{ "type": "command", "command": "open -g \"tellie://update?text=Thinking%E2%80%A6&source=Claude&icon=sparkles\"" }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "open -g \"tellie://clear?source=Claude\"" }
]
}
]
}
}
Now every prompt flips the notch to "Thinking… ✨ Claude" and every finished turn clears it, perfectly synced to the model's actual generation. Hooks reload on the next turn; no restart needed.
What's that %E2%80%A6? Just the URL-encoding of the ellipsis character "…". You can write Thinking... with three plain dots if you prefer; both work. (sparkles is an SF Symbol name; swap in any symbol or an emoji.)
Why open -g? The -g flag opens Tellie in the background. Without it, open would activate Tellie and pull keyboard focus away from whatever you are typing in (and stray keystrokes would beep). Always use -g for hooks and scripts so the notch stays ambient. (The tellie CLI does this for you.)
(Prefer the CLI? Use tellie update "Thinking…" --source Claude --icon sparkles and tellie clear --source Claude as the hook commands instead.)
OpenClaw / any harness
Same pattern, wherever your harness lets you run a command on turn start/end (a lifecycle hook, middleware, or wrapper):
- on receive / turn start:
open -g "tellie://update?text=Working%E2%80%A6&source=OpenClaw&icon=bolt" - on stream finish / turn end:
open -g "tellie://clear?source=OpenClaw"
That takes the burden off the model to manage its own idle state and keeps the notch 100% in sync with the engine.
Heartbeat alternative (no harness hook)
If you can't hook the harness, have the agent re-update every few seconds while it works (it's probably pushing progress anyway). Tellie's roster auto-expires a source that goes quiet (~5 min), so a crashed agent fades on its own. The harness hook is cleaner, but this works in a pinch.
Bonus: richer states
update carries icon and attention, so you can do more than working/idle:
tellie update "Running tests… (12/40)" --source Claude --icon hammer
tellie update "Needs your review" --source Claude --icon checkmark.circle --attention
tellie flash "PR #149 opened" --source Claude --icon bolt
--attention (CLI) / attention: true (MCP) is your alert: the line shows as a pulsing orange highlight so it actually grabs the eye. Use it sparingly, for "I'm done" or "I'm blocked, look at me."