Desktop Pet: Visualizing AI Coding Task Status on Your Desktop

    This article explains how to turn long-running AI coding agent tasks into glanceable desktop status indicators. It covers task-state modeling, unified event streams, a three-part architecture, desktop overlay implementation details, custom asset design, UX principles, rollout stages, and metrics.

    1. Problem Background: The “Waiting Blind Spot” Created by Long Tasks

    AI coding assistants are shifting from question-answering completion toward agentic execution. Instead of only suggesting code snippets, they can read repositories, modify multiple files, run tests, execute commands, and commit changes. A single task may now take from a few minutes to more than ten minutes.

    This creates an underrated user experience problem: the user often does not know whether they need to wait.

    While a task is running, users usually have only two practical options:

    • Keep watching logs scroll in a terminal or editor window, which consumes sustained attention.
    • Switch to another app and periodically return to check progress, which introduces repeated context switching.

    Both options have costs. The first locks attention for a long time. The second creates switching overhead: every time the user returns to the coding environment, they must reconstruct a mental model of “what was I doing, and how far has the task progressed?”

    If the task eventually raises a question that requires human input—missing parameters, command confirmation, or choosing a test-fix strategy—and the user discovers it minutes later, that waiting time is effectively wasted.

    Traditional solutions are not good enough. Terminal logs are too information-dense and require active reading. System notifications are triggered only at a single moment, usually when the task finishes, so they cannot express progress. Progress bars inside editors can be hidden when windows overlap, and they stop being useful once the task is moved out of focus.

    A more appropriate information carrier is an ambient display: a UI element that stays at the edge of the visual field, does not require active attention, and lets users quickly determine whether intervention is needed. A pixel-style desktop pet is one product of this idea. It is not merely decoration; it acts as a cross-application status indicator.

    2. Core Abstraction: Mapping Task Lifecycle to Visual States

    To build a useful desktop pet, the first requirement is to abstract “what the AI is doing” into a finite, distinguishable, and prioritized set of states. Three layers are recommended.

    2.1 State Layer: Define a Finite State Machine

    A typical agentic task can be normalized into the following states:

    State Meaning User Action Visual Intensity
    idle No task running None Lowest; slow idle animation
    queued Submitted and waiting in queue None Low
    thinking Model reasoning or planning None Medium; looping thinking animation
    tool_running Calling a tool, such as reading files, searching, or executing commands None Medium; action-style animation
    waiting_input Blocked and waiting for a user answer Respond immediately High; accent color plus speech bubble
    awaiting_review Changes generated and waiting for review Review and approve or reject High; waving reminder
    failed Error or rejected task Check the reason Highest; alert state
    done Completed Spot-check results Medium; one-time notification, then return to a calmer state

    The key constraint is that states requiring human intervention must be distinguishable at a glance. waiting_input, awaiting_review, and failed are high-value interruptions. The other states are low-value progress indicators. If all states are rendered with the same visual intensity, the desktop pet becomes noise, and users will quickly learn to ignore it.

    2.2 Event Layer: Use a Unified Event Model

    The desktop pet should not parse raw log text. Instead, it should consume a structured event stream.

    Most agentic tools emit subscribable events, such as message blocks, tool call start/end events, patch applications, command exit codes, and so on. These should be normalized into a unified model:

    1. {
    2. "taskId": "t-8f21",
    3. "seq": 42,
    4. "type": "tool_end",
    5. "tool": "run_tests",
    6. "state": "awaiting_review",
    7. "summary": "Modified 3 files; tests passed 18/19",
    8. "needUserAction": true,
    9. "ts": 1770000000000
    10. }

    The normalization layer has three responsibilities: compress high-frequency events, derive the current state, and generate a short human-readable summary.

    Summary generation requires careful length truncation and sensitive-information redaction. Command output may contain tokens, secrets, or internal paths. A desktop pet is a semi-public visual element: it may appear in screen recordings, presentations, or shared screens. By default, it should display only conclusion-oriented descriptions.

    2.3 Rendering Layer: Mapping States to Animations

    The rendering layer only cares about the current state, whether human input is required, and the summary text. A debounced mapping implementation is shown below:

    1. type PetState = 'idle' | 'thinking' | 'tool_running'
    2. | 'waiting_input' | 'awaiting_review' | 'failed' | 'done';
    3. const PRIORITY: Record<PetState, number> = {
    4. failed: 5, waiting_input: 4, awaiting_review: 4, done: 2, tool_running: 1,
    5. thinking: 1, idle: 0,
    6. };
    7. let current: PetState = 'idle';
    8. let pending: { state: PetState; at: number } | null = null;
    9. export function reduce(prev: PetState, next: PetState): PetState {
    10. // Debounce lower-priority state changes: they must remain stable for 800 ms before taking effect
    11. if (PRIORITY[next] < PRIORITY[prev]) {
    12. if (!pending || pending.state !== next) pending = { state: next, at: Date.now() };
    13. return Date.now() - pending.at > 800 ? next : prev;
    14. }
    15. pending = null;
    16. return next;
    17. }

    State debouncing is often overlooked, but it matters. Agentic tasks frequently switch between states such as “thinking → reading files → thinking.” Without throttling, the desktop pet may appear to twitch, while also causing many unnecessary redraws.

    3. Architecture: Three Loosely Coupled Parts

    It is better to split the system into three independently evolvable processes instead of embedding rendering logic directly into the AI coding tool.

    1. [Agent Runner / headless] ──events──▶ [Status Hub] ──push──▶ [Desktop Overlay]
    2. The real executor of tasks State machine + subscription broadcast Floating window rendering + interaction

    The Status Hub is the core. It maintains the task registry, runs the state machine, generates summaries, and broadcasts updates to subscribers.

    There are two reasons to keep it separate. First, it allows the desktop pet to restart without losing task context. Task state can be persisted to a local file and restored after restart. Second, it allows multiple front ends to reuse the same status source: desktop pet, web mini window, terminal status line, and system notifications can coexist without each one parsing logs independently.

    Inter-process communication can use a local WebSocket, Unix Domain Socket, or named pipe. If tasks run in a remote container, events can be pushed back to a local Status Hub through a message queue or long-lived connection, and the hub can then distribute them.

    This “event bus plus multi-client subscription” structure is similar to the common cloud combination of logging services, monitoring alerts, and message queues: collection, aggregation, and distribution are separated into distinct layers.

    4. Key Implementation Details for the Desktop Overlay

    This part determines whether the desktop pet is merely cute or actually usable.

    Window level and click-through. The overlay must remain always-on-top, but it should not steal input focus. Otherwise, it will interfere with the user’s current operations. A common approach is to create a frameless, marginless top-layer window, enable mouse event pass-through outside the pet body, and exclude the window from the taskbar or application switcher to avoid polluting Alt-Tab.

    Multi-monitor and DPI. Position should be persisted as normalized coordinates relative to a monitor workspace, not absolute pixels. Otherwise, the pet may move off-screen after the user changes external displays. On high-DPI systems, bitmap assets should be prepared at 1x and 2x resolutions, or vector graphics should be used, to avoid blurriness.

    Energy control. The desktop pet is a long-running resident process, so resource usage must be limited. Idle animations should reduce frame rate or pause. Rendering should be suspended when the page is not visible. Timers should be avoided in favor of event-driven updates. A transparent window redrawing 60 frames per second continuously can create a noticeable battery drain on laptops.

    Opening the main interface. Clicking the desktop pet should quickly focus the input box of the AI coding tool. This is one of its highest-frequency use cases. The implementation should preserve task context and support deep linking instead of forcing users to search for the right window.

    Closing and minimizing. Provide both a right-click menu and a settings page. Distinguish between “temporary hide,” which should automatically restore after the task ends, and “permanent close,” which should remember the user preference. These two semantics are often confused.

    Platform differences. Desktop floating windows depend heavily on each operating system’s window management capabilities. Behavior can vary significantly across platforms, including always-on-top levels, full-screen app occlusion policies, hiding during screen saver or lock screen, auto-start registration methods, and the timing of system notification permission requests. These must be adapted separately.

    Mobile devices usually do not provide the same type of floating widget because background process and persistent overlay restrictions are strict. In that environment, push notifications plus live activity cards are a more suitable carrier.

    Headless and remote scenarios. When tasks run on servers or containers, there may be no desktop. In that case, use a terminal status line—for example, an ANSI-updated single-line progress indicator—plus a system notification when the task ends, or open a small browser window subscribing to the same event stream. Unifying the status source is the only design decision that must be made in advance.

    5. Custom Assets and Community Sharing

    Appearance customization is key to retaining users, but it is also the easiest place to introduce engineering risks.

    Asset specification. Define a clear asset format: a sprite sheet plus a descriptor file that declares frame size, frame ranges for each state, playback frame rate, looping behavior, and speech-bubble anchor position. Limit individual image size and total package size to prevent someone from submitting 100 MB of assets and slowing down startup.

    Validation and sandboxing. This is the most important security consideration: accept only image files and pure data descriptor files; do not execute any user-provided scripts. Major incidents in desktop pet software historically came from allowing custom assets to include executable content or read arbitrary local paths. Sharing channels should validate uploaded formats, validate dimensions, re-encode images to remove potential payloads in metadata, and apply basic content moderation.

    Distribution. Asset packs are suitable for object storage plus a CDN. Filenames should include content hashes for versioning, and clients should cache assets by hash to avoid full downloads on every startup. Installing an asset should require explicit confirmation and display package size and source.

    Interaction design. Hover-triggered action animations, instant click feedback, and a waving animation when a task completes are low-cost details with strong perceptual impact. They turn “status display” into “something is watching my task for me.” This sense of companionship is part of why this type of feature is popular.

    6. Experience Design Principles: Four Rules for Ambient Information

    Beyond a specific product, this kind of glanceable status display can be summarized by four design principles:

    1. Glanceable: Users should reach a conclusion within 0.5 seconds without reading text.
    2. Ignorable: It should not interrupt users when intervention is not required. Avoid sound or aggressive motion.
    3. Prioritized: Only states that require human decisions should escalate to highlights or system notifications.
    4. Progressive disclosure: Keep the default minimal, and expand to show summaries or diff previews only when needed.

    These principles explain why purely character-based status expressions often provide a weaker experience: characters require reading, lack color and motion-based priority distinction, and have insufficient visual presence in GUI environments. Pixel-style desktop pets work not because they are cute, but because they satisfy both glanceability and ignorability.

    7. Rollout Plan and Metrics

    A four-stage rollout is recommended. Each stage can be released and validated independently.

    • P0: Unify the status source. Implement event collection and the state machine, output a structured event stream, and first integrate it with a terminal status line. This stage has no UI cost, but it immediately solves the problem of “a task failed and nobody noticed.”
    • P1: Desktop pet. Implement an always-on-top floating window, basic state mapping, click-to-open behavior, and right-click minimize.
    • P2: Customization and sharing. Open asset specifications, atlas validation, and local imports. Consider a community gallery later.
    • P3: Multi-task aggregation. When tasks can run in parallel, a single pet is insufficient. Add a task-group view with queueing, parallel progress, and priority sorting.

    For metrics, do not only measure “how many people set a pet.” More meaningful indicators include:

    • Median confirmation latency: time from task completion to the user viewing the result.
    • Context switches per hour.
    • Missed intervention rate: tasks requiring human input that were not noticed in time.

    These metrics better reflect whether the waiting blind spot has actually been solved.

    8. Common Pitfalls Checklist

    • Not filtering state jitter, causing animations to look twitchy.
    • Inferring states from log text, which creates fragile and hard-to-maintain rules.
    • Leaking secrets or internal paths from command output in summaries.
    • Allowing the overlay window to steal focus and interfere with user input.
    • Keeping a long-running process awake and hurting laptop battery life.
    • Allowing scripts in custom assets, creating a supply-chain risk.
    • Storing window position as absolute pixels, causing the pet to move off-screen after changing displays.
    • Handling only “completed,” while ignoring “waiting for user input,” which is the highest-value state.
    • Treating “temporary hide” and “permanent close” as the same toggle.

    9. Summary

    At first glance, a “desktop pet” appears to be an appearance feature. In essence, it moves agentic AI task status out of windows and into the user’s peripheral vision.

    The technical complexity is concentrated in three areas: normalizing tool events into a finite state machine, rendering states as prioritized and ignorable ambient cues, and balancing energy usage and security across long-running and customizable extensions.

    If you are building your own coding assistant or automation pipeline, this “event bus + state machine + multi-client subscription” design can be adopted incrementally. The P0 terminal status line often removes most of the waiting cost, while the desktop pet is simply a better-looking outlet for the same status source.