omesser/fidget

🧙 AI desktop character for rich dilly-dallying... I mean "productivity enhancement"

Rust

4

921 commits

updated Oct 12, 2026

See the code

See what people are saying

SourceMessageScoreDate

I recently built Fidget - A modern open-source, AI-powered, desktop pet (inspired by old win95 era ones) (r/coolgithubprojects)

https://preview.redd.it/j4253vua42vh1.jpg?width=2000&format=pjpg&auto=webp&s=624b56197e5ca270e6fab9ea1e53d260de33b2fb A desktop pet that has that "old" 8-bit nostalgic aesthetic and "physical" desktop interactions but also hooks up to your AI of choice and can actually speak/act in…

1

Oct 12, 2026

README

Fidget is a desktop pet that keeps you company, and pitches in when you ask

An AI character that lives on your screen. It walks, talks, naps, and can assist in whatever you are up to. Pick it up, throw it around, let it nap, or talk to it. Attach the AI harness you already use, and it can do anything that an AI agent can.

Each character has a personality and a life of its own.

An AI harness is optional. Attach the one you already use and it can talk and pitch in with tools; leave it off and the pet still works. It doesn't read your screen without consent and never takes screenshots.

https://github.com/user-attachments/assets/31bf24c7-7fe7-43d0-92d7-a4a3bd6d4c11

Try the gestures in your browser: Fidget Cues

What It Does

  • Keeps you company: It walks, naps, and reacts to your open windows. It works offline, with no AI account or subscription, for presence and play; hook it up to an AI and it takes on a life of its own, with full conversation and tool use.
  • Pick a built-in character, or build your own: Each character has its own sprites, animation loops, and personality. Edit any character's prompt or behavior using a plain-text personality file and a simple manifest format. Create your own characters, or import and convert one from the Pets Codex and Shimeji Shop galleries.
  • Personalize your Fidget's behavior: Write your own text for any fidget's behavior through its Instance Prompt. It holds on top of its Character's personality, and changes how that fidget reacts. See Give It an Instance Prompt for examples.
  • Pitches in: Double-click to chat with the agent you already use (Claude Code, Codex, Cursor, or any ACP harness); it acts on your machine and answers in speech and motion.
  • Knows what you're up to: It can see and react to your open windows - titles only, and only with consent, for context-aware chatter. It never reads screen pixels and never takes screenshots; Reading titles and application names needs your explicit consent.
  • Gets out of your way when you ask it to: Automatically fades away when in fullscreen, hides at will on hotkey, and comes back when you want it to.

Get It

On macOS (Apple Silicon) with Homebrew:

brew install --cask omesser/fidget/fidget

That taps omesser/homebrew-fidget and installs Fidget.app. Later Releases arrive with brew update and brew upgrade --cask fidget.

Or download a build from GitHub Releases: a .dmg for macOS (Apple Silicon), an AppImage and a .deb for Linux (x86_64), or an NSIS installer for Windows (x86_64). The builds are not signed yet, so the first open warns. On macOS, open Fidget.app from the disk image, dismiss the Gatekeeper dialog, then System Settings → Privacy & Security → Open Anyway. On Windows, choose More info → Run anyway in SmartScreen.

macOS may block /Applications/Fidget.app after a Homebrew or download install. Removing its quarantine attribute bypasses a macOS security check. Run the command at your own risk. Never run it on an app you do not trust. Fidget is open source, so you can inspect its code, but that alone does not verify the downloaded app. To remove the quarantine attribute, run:

xattr -d com.apple.quarantine /Applications/Fidget.app

Or clone and run from the repo root (macOS, Linux, Windows):

git clone https://github.com/omesser/fidget.git fidget
cd fidget
cargo run -p fidget

It works offline with no key. With nothing configured, Static weights pick idle Behaviors from the Character.

Right-click the fidget, or click the tray icon, and choose Settings….

Settings → Character picks which character it wears. Buddy Bot is the default. The others are under Characters.

Settings → AI chooses who answers. Under AI source, pick Harness · claude or another name from Harness Support. The Harness signs in on its own. Model under Harness names the model it runs on, and blank keeps the Harness's own default. For a Model API, pick Model API in AI source, then set Base URL, Model, and API key under Model / API. Presets fill the Base URL for OpenAI, Anthropic, xAI, and Ollama. Type any other OpenAI-compatible endpoint into Base URL. Apply saves the choice.

Developers and CI can override Settings with optional environment variables:

# Optional. Overrides Settings → AI → AI source.
FIDGET_HARNESS=claude cargo run -p fidget

# Optional. Overrides Settings → Character.
# Any of: buddy-bot (default), black-mage, bmo, cat, jotaro-kujo, nim, timber-wolf, trump
FIDGET_CHARACTER=nim cargo run -p fidget

The full variable list, including FIDGET_DIRECTOR_*, is in harness.md. Character packages are in DEVELOPMENT.md. Keychain dialogs an unsigned build costs are in harness.md. Full support for window Perches and edges via X11/XWayland (the normal Linux desktop path). Pure Wayland sessions without an X server fall back to screen edges only. Linux packages and the AppImage's FUSE dependency are in DEVELOPMENT.md.

Interact

Buddy Bot react

  • Poke - click once for a react, then it resumes.
  • Summon - double-click to open a chat window for that fidget.
  • Pick up - click and drag; the pressed point stays under the pointer.
  • Throw - release while moving; it flies on an arc and lands.
  • Perch - let it settle on a window's top edge; drag slowly to ride, fling to drop.
  • Hide - Control-Option-Command-B (the default; change it in Settings) toggles the fidget instantly.
  • Fullscreen - fades out for fullscreen apps, fades back when you exit.

Talk to It

Summon opens that fidget's chat window. What you type joins the same conversation that decides what it does on your desktop, so an answer arrives as speech and a Behavior, not only as text. Lines it says unprompted appear here too, labelled with what it was reacting to.

The chat surface: a line labelled WHEN SUMMONED, a typed question, and BMO's answer, over a status bar naming the Behavior, State and next wake

The bar at the bottom says what the fidget is doing and when it next thinks. Advanced opens the ladder: Behavior, Primitive, Animation, State, Facing, and the Director's countdown. Answers need a Director; see Get It.

Give It an Instance Prompt

An Instance Prompt is your own text for one fidget, layered on top of its Character's personality. To write one, double-click the fidget to summon it, open the Prompt tab, and type in the Your own layer box. That box is the Instance Prompt. Paste one of the examples below and edit it to fit. Saving starts a new conversation, and the Instance Prompt stays with that fidget if you switch its Character.

Every example below assumes this setup:

  • A Harness is attached. A Model API can't run tools.
  • The Harness is allowed to use its own tools.
  • The Window and application names consent is on in Settings → Privacy. Fidget then reads app names and window titles only, never pixels, and it never takes screenshots.
Paste and editHow it reacts on a wake
If my editor stays in front for a long stretch, ask me to explain the bug to you, like a rubber duck.Sees the editor in front on a wake and asks you to walk it through the bug.
You're a theatre critic. When you're perched on a window, review that app in one dramatic line.Perch it on a window and it reviews the app it's standing on.
When I ask you to check something on my machine, do it, then report back in one line, in character.Does the check with your Harness's tools and reports back in one line, in character.

Characters

Buddy Bot is the default. Eight Characters ship; each moves and speaks differently. A name links to its full prompt.

Buddy Bot
Buddy Bot
Friendly and curious; he's your helpful assistant.
Black Mage
Black Mage
Cynical spellcaster, cryptic and theatrical.
BMO
BMO
Earnest, childlike, delighted to be here.
Cat
Cat
Every window is furniture. Never helpful.
Jotaro Kujo
Jotaro Kujo
Terse, perpetually bored, tougher than he lets on.
Nim
Nim
Sleeps eleven hours a day. Soft-spoken.
Timber Wolf
Timber Wolf
Patrol mech. Clan warriors don't waste words.
Trump
Trump
The desktop is his rally. Bombastic.

Characters are packages of art, personality, and tuning. See DEVELOPMENT.md; the format is still evolving.

Harness Support

Which Harness you attach changes what Fidget can do with it.

HarnessCommandStanding
 claudenpx -y @agentclientprotocol/claude-agent-acp@latestZed's adapter over the Claude Agent SDK; no first-party ACP mode. Fresh and resumed sessions both work.
 codexnpx -y @agentclientprotocol/codex-acp@latestZed's adapter (codex-acp); no first-party ACP mode. Fresh and resumed sessions both work.
 copilotcopilot --acpFirst-party, GitHub. copilot alone is the interactive TUI. Fresh and resumed sessions both work, smoked on copilot 1.0.88 (#1016).
 cursor-agentcursor-agent acpFirst-party. cursor-agent alone is the interactive TUI. Every attach opens a fresh session, because it advertises no loadSession.
 grokgrok agent stdioFirst-party, Grok Build. grok alone is the interactive TUI. Fresh and resumed sessions both work.
 goosegoose acpFirst-party, Block. goose alone is the interactive CLI. Fresh and resumed sessions both work, smoked on goose 1.51.0.
 opencodeopencode acpFirst-party. Fresh and resumed sessions both work.
 hermeshermes acpFirst-party. Fresh sessions work; a resume that cannot restore the session reopens (#448).
 pinpx -y pi-acp@latestZed-registry adapter (pi-acp); no first-party ACP. Fresh and resumed sessions both work.
 antigravityagy_acp_server.par (agy_acp_server.exe on Windows)First-party, Google's ACP server; agy itself has no ACP mode. Fresh and resumed sessions both work, smoked on agy_acp_server 1.2.1 (#604).
anything elseas typed, split on whitespaceUnnamed, and it works: any command that speaks ACP on stdio attaches.

Tools each harness keeps under ACP, session and auth behavior, and per-harness setup notes are in docs/harness.md.

Harness ↔ MCP

Fidget attaches to a Harness over ACP on stdio. The Harness calls back over MCP, on the route the MCP transport column describes. harness.md has the transport details.

Eight tools from crates/core/src/dispatch.rs. The opening turn of the Character Prompt tells the model to use the tools it has, without naming them, so this table stays the only catalog (#917):

ToolCategoryWhat it does
speakExpressionMake the Character speak dialogue
play_behaviorExpressionPlay a named Behavior
list_windowsSensingList visible windows with bounds, and their names under consent
describe_screenSensingDescribe screen (v1: window metadata only)
recallMemoryRead everything Memory holds
rememberMemoryWrite one fact under a heading
list_instancesIdentityList Character Instances and their names
whereaboutsPlacementWhich display each Instance is on, the other displays, and its feet in that display. Each display includes its name when the platform has one, its origin, and its size, in logical points

Three readonly resources (resources/list, resources/read; no write, no subscribe):

URIWhat it is
fidget://windowsVisible windows, frontmost first, with the owning application and the title. Empty without the window-names consent, which covers both (ADR-0032). Same excluded applications as list_windows.
fidget://memoryThe Memory Manifest file every Character Instance shares.
fidget://action-logThe current Action Log file only. Rotated siblings are not this resource. A large current file is tailed to complete JSONL lines.

Explicitly not served: mouse/keyboard/Executor tools (ADR-0003). No click, no type, no input events by design.

Computer Use

Fidget never reads screen pixels. Sensing is OS window metadata: bounds and idle for free, plus the owning application, the title and the frontmost app under one consent (ADR-0032). So describe_screen describes the window layout, not what is on screen. Decline it and the fidget still knows where the windows are, and not what they are. The fidget takes no screenshots, runs no OCR, and embeds no vision model for desktop content. The "Appear in screenshots and screen shares" setting is the other direction: whether the sprite shows up in captures you take.

That bounds Fidget's own code, not the agent you attach to it. An agent that needs to see and act on your desktop still can. The capability comes from the Harness itself, or from a computer-use MCP server you attach to the Harness, never through Fidget, whose MCP serves no input events.

The portable option across the Harnesses above is cua-driver (MIT; macOS, Windows, Linux), attached over stdio MCP. Connect your agent to Cua Driver carries the per-client registration, and MCP tools lists what it exposes. Attach it deliberately: it drives the real desktop with your signed-in sessions, and its permission mode is chosen by the process that owns the driver runtime, not by the agent asking. Some Harnesses bring computer use of their own instead; the Capture decision note has the per-Harness table and the other drivers surveyed.

Platform Support

What works today on each OS.

CapabilitymacOSLinuxWindows
Overlay that never takes focusyesyesyes
Click-through off the spriteyesyesyes
Grab, Throw and Pokeyesyesyes
Perch on window edgesyesyesyes
Dock or panel as a Perchyesdegraded¹degraded²
Fade out for a fullscreen appyesdegraded⁵degraded³
Capturable; opt-out in settingsyesdegraded⁴yes
Settings windowyesyesyes
  • yes - implemented.
  • degraded - runs in reduced form. A supported mode, not an error.

Degraded cell notes:

  1. Linux desktop panels: Desktop panels come from each display's work area, as on Windows: a bottom one is the floor, a side one is a wall, and a top one is the ceiling. Under a window manager that publishes no per-monitor work area (xfwm4), a desktop panel on a display that isn't primary is ignored. Tracked in #1300.
  2. Windows Dock/panel: Taskbar from work area (full-width strip) rather than exact island bounds. Taskbar spans the edge by design; no Windows API equivalent to macOS's CoreDockGetRect.
  3. Windows fullscreen: Fades for true fullscreen and properly-sized borderless windowed modes. Apps using non-standard fullscreen or leaving gaps may not trigger fade.
  4. Linux Capturable: Always capturable. Linux has no platform API to exclude windows from capture tools (ADR-0024).
  5. Linux fullscreen: X11 and XWayland work for all apps. Pure Wayland without XWayland: native Wayland fullscreen apps do not trigger fade or move; XWayland clients still trigger correctly (#1360).

Detailed investigation: docs/research/platform-support-degraded-cells.md.

Linux support is full on normal desktops (X11 or XWayland under GNOME/KDE). Rare pure Wayland sessions without an X server fall back to screen edges only - no window Perches, Grab, Throw, or fullscreen fade. See DEVELOPMENT.md.

Developing

Want to help? Open issues welcome bugs, ideas, and PRs. Start with DEVELOPMENT.md for toolchains, hooks, verification, character writing, and imports. See how Fidget compares to other desktop pets in alternatives.md.

Design and decisions:

Prior Art and Attribution

Harness brand marks identify each Harness and belong to their owners. The Grok logomark is xAI's own file from their brand guidelines, used unaltered to refer to Grok, which those guidelines permit and may revoke. The Nous Research mark (docs/readme/nous.svg) identifies the Hermes Harness. The Codex row uses the OpenAI mark from Simple Icons, kept in the repo because the CDN no longer serves that slug (CC0, trademark reserved to OpenAI). docs/readme/openai-on-light.svg is that glyph in near-black; docs/readme/openai-on-dark.svg is the same path in white, so it stays visible on a dark README. The Goose mark is the Goose icon from Lobe Icons (MIT), split the same way (docs/readme/goose-on-light.svg, docs/readme/goose-on-dark.svg); the trademark stays with Block. Every other mark is served from Simple Icons (CC0, with each brand's trademark reserved to its owner).

WindowPet (MIT) inspired the Tauri desktop-pet shape. Fidget is a greenfield build, not a fork (ADR-0001). Overlay code is independent; tray, launch-at-login, and updater follow WindowPet's MIT-licensed patterns.

The Chat window's mind mark - the small brain beside what answers - is the brain glyph from Font Awesome Free 6.x, used under CC BY 4.0 and inlined as a path in src/chat.html. The license asks for the credit; this is it.

Character provenance is in each Character Package manifest, under [source], and on the Character Gallery. In short: Buddy Bot and Nim are this project's own art. Timber Wolf derives, with the creator's permission, from MekaRamen's Sketchfab model. BMO is cut from the shimejishop BMO pack. Cat, Jotaro Kujo and Trump are cut from petscodex pets. Black Mage is sliced from GigaGuy's sprite sheet on The Spriters Resource. A package is prose, a manifest and art: the personality and the manifest - animations, Behaviors, Director and cursor tuning - are this project's work and MIT throughout. The art is not always ours. Some characters adapt art that declares no license, and each manifest names what it adapts and whose IP the character is.

License

MIT.

agent
agentic-ai
ai
ai-agents
buddy
desktop-application
desktop-pet
desktop-tools
game
javascript
leisure
linux
macos
rust
windows

omesser/fidget

🧙 AI desktop character for rich dilly-dallying... I mean "productivity enhancement"

Rust

4

921 commits

updated Oct 12, 2026

See the code

See what people are saying

SourceMessageScoreDate

I recently built Fidget - A modern open-source, AI-powered, desktop pet (inspired by old win95 era ones) (r/coolgithubprojects)

https://preview.redd.it/j4253vua42vh1.jpg?width=2000&format=pjpg&auto=webp&s=624b56197e5ca270e6fab9ea1e53d260de33b2fb A desktop pet that has that "old" 8-bit nostalgic aesthetic and "physical" desktop interactions but also hooks up to your AI of choice and can actually speak/act in…

1

Oct 12, 2026

README

Fidget is a desktop pet that keeps you company, and pitches in when you ask

An AI character that lives on your screen. It walks, talks, naps, and can assist in whatever you are up to. Pick it up, throw it around, let it nap, or talk to it. Attach the AI harness you already use, and it can do anything that an AI agent can.

Each character has a personality and a life of its own.

An AI harness is optional. Attach the one you already use and it can talk and pitch in with tools; leave it off and the pet still works. It doesn't read your screen without consent and never takes screenshots.

https://github.com/user-attachments/assets/31bf24c7-7fe7-43d0-92d7-a4a3bd6d4c11

Try the gestures in your browser: Fidget Cues

What It Does

  • Keeps you company: It walks, naps, and reacts to your open windows. It works offline, with no AI account or subscription, for presence and play; hook it up to an AI and it takes on a life of its own, with full conversation and tool use.
  • Pick a built-in character, or build your own: Each character has its own sprites, animation loops, and personality. Edit any character's prompt or behavior using a plain-text personality file and a simple manifest format. Create your own characters, or import and convert one from the Pets Codex and Shimeji Shop galleries.
  • Personalize your Fidget's behavior: Write your own text for any fidget's behavior through its Instance Prompt. It holds on top of its Character's personality, and changes how that fidget reacts. See Give It an Instance Prompt for examples.
  • Pitches in: Double-click to chat with the agent you already use (Claude Code, Codex, Cursor, or any ACP harness); it acts on your machine and answers in speech and motion.
  • Knows what you're up to: It can see and react to your open windows - titles only, and only with consent, for context-aware chatter. It never reads screen pixels and never takes screenshots; Reading titles and application names needs your explicit consent.
  • Gets out of your way when you ask it to: Automatically fades away when in fullscreen, hides at will on hotkey, and comes back when you want it to.

Get It

On macOS (Apple Silicon) with Homebrew:

brew install --cask omesser/fidget/fidget

That taps omesser/homebrew-fidget and installs Fidget.app. Later Releases arrive with brew update and brew upgrade --cask fidget.

Or download a build from GitHub Releases: a .dmg for macOS (Apple Silicon), an AppImage and a .deb for Linux (x86_64), or an NSIS installer for Windows (x86_64). The builds are not signed yet, so the first open warns. On macOS, open Fidget.app from the disk image, dismiss the Gatekeeper dialog, then System Settings → Privacy & Security → Open Anyway. On Windows, choose More info → Run anyway in SmartScreen.

macOS may block /Applications/Fidget.app after a Homebrew or download install. Removing its quarantine attribute bypasses a macOS security check. Run the command at your own risk. Never run it on an app you do not trust. Fidget is open source, so you can inspect its code, but that alone does not verify the downloaded app. To remove the quarantine attribute, run:

xattr -d com.apple.quarantine /Applications/Fidget.app

Or clone and run from the repo root (macOS, Linux, Windows):

git clone https://github.com/omesser/fidget.git fidget
cd fidget
cargo run -p fidget

It works offline with no key. With nothing configured, Static weights pick idle Behaviors from the Character.

Right-click the fidget, or click the tray icon, and choose Settings….

Settings → Character picks which character it wears. Buddy Bot is the default. The others are under Characters.

Settings → AI chooses who answers. Under AI source, pick Harness · claude or another name from Harness Support. The Harness signs in on its own. Model under Harness names the model it runs on, and blank keeps the Harness's own default. For a Model API, pick Model API in AI source, then set Base URL, Model, and API key under Model / API. Presets fill the Base URL for OpenAI, Anthropic, xAI, and Ollama. Type any other OpenAI-compatible endpoint into Base URL. Apply saves the choice.

Developers and CI can override Settings with optional environment variables:

# Optional. Overrides Settings → AI → AI source.
FIDGET_HARNESS=claude cargo run -p fidget

# Optional. Overrides Settings → Character.
# Any of: buddy-bot (default), black-mage, bmo, cat, jotaro-kujo, nim, timber-wolf, trump
FIDGET_CHARACTER=nim cargo run -p fidget

The full variable list, including FIDGET_DIRECTOR_*, is in harness.md. Character packages are in DEVELOPMENT.md. Keychain dialogs an unsigned build costs are in harness.md. Full support for window Perches and edges via X11/XWayland (the normal Linux desktop path). Pure Wayland sessions without an X server fall back to screen edges only. Linux packages and the AppImage's FUSE dependency are in DEVELOPMENT.md.

Interact

Buddy Bot react

  • Poke - click once for a react, then it resumes.
  • Summon - double-click to open a chat window for that fidget.
  • Pick up - click and drag; the pressed point stays under the pointer.
  • Throw - release while moving; it flies on an arc and lands.
  • Perch - let it settle on a window's top edge; drag slowly to ride, fling to drop.
  • Hide - Control-Option-Command-B (the default; change it in Settings) toggles the fidget instantly.
  • Fullscreen - fades out for fullscreen apps, fades back when you exit.

Talk to It

Summon opens that fidget's chat window. What you type joins the same conversation that decides what it does on your desktop, so an answer arrives as speech and a Behavior, not only as text. Lines it says unprompted appear here too, labelled with what it was reacting to.

The chat surface: a line labelled WHEN SUMMONED, a typed question, and BMO's answer, over a status bar naming the Behavior, State and next wake

The bar at the bottom says what the fidget is doing and when it next thinks. Advanced opens the ladder: Behavior, Primitive, Animation, State, Facing, and the Director's countdown. Answers need a Director; see Get It.

Give It an Instance Prompt

An Instance Prompt is your own text for one fidget, layered on top of its Character's personality. To write one, double-click the fidget to summon it, open the Prompt tab, and type in the Your own layer box. That box is the Instance Prompt. Paste one of the examples below and edit it to fit. Saving starts a new conversation, and the Instance Prompt stays with that fidget if you switch its Character.

Every example below assumes this setup:

  • A Harness is attached. A Model API can't run tools.
  • The Harness is allowed to use its own tools.
  • The Window and application names consent is on in Settings → Privacy. Fidget then reads app names and window titles only, never pixels, and it never takes screenshots.
Paste and editHow it reacts on a wake
If my editor stays in front for a long stretch, ask me to explain the bug to you, like a rubber duck.Sees the editor in front on a wake and asks you to walk it through the bug.
You're a theatre critic. When you're perched on a window, review that app in one dramatic line.Perch it on a window and it reviews the app it's standing on.
When I ask you to check something on my machine, do it, then report back in one line, in character.Does the check with your Harness's tools and reports back in one line, in character.

Characters

Buddy Bot is the default. Eight Characters ship; each moves and speaks differently. A name links to its full prompt.

Buddy Bot
Buddy Bot
Friendly and curious; he's your helpful assistant.
Black Mage
Black Mage
Cynical spellcaster, cryptic and theatrical.
BMO
BMO
Earnest, childlike, delighted to be here.
Cat
Cat
Every window is furniture. Never helpful.
Jotaro Kujo
Jotaro Kujo
Terse, perpetually bored, tougher than he lets on.
Nim
Nim
Sleeps eleven hours a day. Soft-spoken.
Timber Wolf
Timber Wolf
Patrol mech. Clan warriors don't waste words.
Trump
Trump
The desktop is his rally. Bombastic.

Characters are packages of art, personality, and tuning. See DEVELOPMENT.md; the format is still evolving.

Harness Support

Which Harness you attach changes what Fidget can do with it.

HarnessCommandStanding
 claudenpx -y @agentclientprotocol/claude-agent-acp@latestZed's adapter over the Claude Agent SDK; no first-party ACP mode. Fresh and resumed sessions both work.
 codexnpx -y @agentclientprotocol/codex-acp@latestZed's adapter (codex-acp); no first-party ACP mode. Fresh and resumed sessions both work.
 copilotcopilot --acpFirst-party, GitHub. copilot alone is the interactive TUI. Fresh and resumed sessions both work, smoked on copilot 1.0.88 (#1016).
 cursor-agentcursor-agent acpFirst-party. cursor-agent alone is the interactive TUI. Every attach opens a fresh session, because it advertises no loadSession.
 grokgrok agent stdioFirst-party, Grok Build. grok alone is the interactive TUI. Fresh and resumed sessions both work.
 goosegoose acpFirst-party, Block. goose alone is the interactive CLI. Fresh and resumed sessions both work, smoked on goose 1.51.0.
 opencodeopencode acpFirst-party. Fresh and resumed sessions both work.
 hermeshermes acpFirst-party. Fresh sessions work; a resume that cannot restore the session reopens (#448).
 pinpx -y pi-acp@latestZed-registry adapter (pi-acp); no first-party ACP. Fresh and resumed sessions both work.
 antigravityagy_acp_server.par (agy_acp_server.exe on Windows)First-party, Google's ACP server; agy itself has no ACP mode. Fresh and resumed sessions both work, smoked on agy_acp_server 1.2.1 (#604).
anything elseas typed, split on whitespaceUnnamed, and it works: any command that speaks ACP on stdio attaches.

Tools each harness keeps under ACP, session and auth behavior, and per-harness setup notes are in docs/harness.md.

Harness ↔ MCP

Fidget attaches to a Harness over ACP on stdio. The Harness calls back over MCP, on the route the MCP transport column describes. harness.md has the transport details.

Eight tools from crates/core/src/dispatch.rs. The opening turn of the Character Prompt tells the model to use the tools it has, without naming them, so this table stays the only catalog (#917):

ToolCategoryWhat it does
speakExpressionMake the Character speak dialogue
play_behaviorExpressionPlay a named Behavior
list_windowsSensingList visible windows with bounds, and their names under consent
describe_screenSensingDescribe screen (v1: window metadata only)
recallMemoryRead everything Memory holds
rememberMemoryWrite one fact under a heading
list_instancesIdentityList Character Instances and their names
whereaboutsPlacementWhich display each Instance is on, the other displays, and its feet in that display. Each display includes its name when the platform has one, its origin, and its size, in logical points

Three readonly resources (resources/list, resources/read; no write, no subscribe):

URIWhat it is
fidget://windowsVisible windows, frontmost first, with the owning application and the title. Empty without the window-names consent, which covers both (ADR-0032). Same excluded applications as list_windows.
fidget://memoryThe Memory Manifest file every Character Instance shares.
fidget://action-logThe current Action Log file only. Rotated siblings are not this resource. A large current file is tailed to complete JSONL lines.

Explicitly not served: mouse/keyboard/Executor tools (ADR-0003). No click, no type, no input events by design.

Computer Use

Fidget never reads screen pixels. Sensing is OS window metadata: bounds and idle for free, plus the owning application, the title and the frontmost app under one consent (ADR-0032). So describe_screen describes the window layout, not what is on screen. Decline it and the fidget still knows where the windows are, and not what they are. The fidget takes no screenshots, runs no OCR, and embeds no vision model for desktop content. The "Appear in screenshots and screen shares" setting is the other direction: whether the sprite shows up in captures you take.

That bounds Fidget's own code, not the agent you attach to it. An agent that needs to see and act on your desktop still can. The capability comes from the Harness itself, or from a computer-use MCP server you attach to the Harness, never through Fidget, whose MCP serves no input events.

The portable option across the Harnesses above is cua-driver (MIT; macOS, Windows, Linux), attached over stdio MCP. Connect your agent to Cua Driver carries the per-client registration, and MCP tools lists what it exposes. Attach it deliberately: it drives the real desktop with your signed-in sessions, and its permission mode is chosen by the process that owns the driver runtime, not by the agent asking. Some Harnesses bring computer use of their own instead; the Capture decision note has the per-Harness table and the other drivers surveyed.

Platform Support

What works today on each OS.

CapabilitymacOSLinuxWindows
Overlay that never takes focusyesyesyes
Click-through off the spriteyesyesyes
Grab, Throw and Pokeyesyesyes
Perch on window edgesyesyesyes
Dock or panel as a Perchyesdegraded¹degraded²
Fade out for a fullscreen appyesdegraded⁵degraded³
Capturable; opt-out in settingsyesdegraded⁴yes
Settings windowyesyesyes
  • yes - implemented.
  • degraded - runs in reduced form. A supported mode, not an error.

Degraded cell notes:

  1. Linux desktop panels: Desktop panels come from each display's work area, as on Windows: a bottom one is the floor, a side one is a wall, and a top one is the ceiling. Under a window manager that publishes no per-monitor work area (xfwm4), a desktop panel on a display that isn't primary is ignored. Tracked in #1300.
  2. Windows Dock/panel: Taskbar from work area (full-width strip) rather than exact island bounds. Taskbar spans the edge by design; no Windows API equivalent to macOS's CoreDockGetRect.
  3. Windows fullscreen: Fades for true fullscreen and properly-sized borderless windowed modes. Apps using non-standard fullscreen or leaving gaps may not trigger fade.
  4. Linux Capturable: Always capturable. Linux has no platform API to exclude windows from capture tools (ADR-0024).
  5. Linux fullscreen: X11 and XWayland work for all apps. Pure Wayland without XWayland: native Wayland fullscreen apps do not trigger fade or move; XWayland clients still trigger correctly (#1360).

Detailed investigation: docs/research/platform-support-degraded-cells.md.

Linux support is full on normal desktops (X11 or XWayland under GNOME/KDE). Rare pure Wayland sessions without an X server fall back to screen edges only - no window Perches, Grab, Throw, or fullscreen fade. See DEVELOPMENT.md.

Developing

Want to help? Open issues welcome bugs, ideas, and PRs. Start with DEVELOPMENT.md for toolchains, hooks, verification, character writing, and imports. See how Fidget compares to other desktop pets in alternatives.md.

Design and decisions:

Prior Art and Attribution

Harness brand marks identify each Harness and belong to their owners. The Grok logomark is xAI's own file from their brand guidelines, used unaltered to refer to Grok, which those guidelines permit and may revoke. The Nous Research mark (docs/readme/nous.svg) identifies the Hermes Harness. The Codex row uses the OpenAI mark from Simple Icons, kept in the repo because the CDN no longer serves that slug (CC0, trademark reserved to OpenAI). docs/readme/openai-on-light.svg is that glyph in near-black; docs/readme/openai-on-dark.svg is the same path in white, so it stays visible on a dark README. The Goose mark is the Goose icon from Lobe Icons (MIT), split the same way (docs/readme/goose-on-light.svg, docs/readme/goose-on-dark.svg); the trademark stays with Block. Every other mark is served from Simple Icons (CC0, with each brand's trademark reserved to its owner).

WindowPet (MIT) inspired the Tauri desktop-pet shape. Fidget is a greenfield build, not a fork (ADR-0001). Overlay code is independent; tray, launch-at-login, and updater follow WindowPet's MIT-licensed patterns.

The Chat window's mind mark - the small brain beside what answers - is the brain glyph from Font Awesome Free 6.x, used under CC BY 4.0 and inlined as a path in src/chat.html. The license asks for the credit; this is it.

Character provenance is in each Character Package manifest, under [source], and on the Character Gallery. In short: Buddy Bot and Nim are this project's own art. Timber Wolf derives, with the creator's permission, from MekaRamen's Sketchfab model. BMO is cut from the shimejishop BMO pack. Cat, Jotaro Kujo and Trump are cut from petscodex pets. Black Mage is sliced from GigaGuy's sprite sheet on The Spriters Resource. A package is prose, a manifest and art: the personality and the manifest - animations, Behaviors, Director and cursor tuning - are this project's work and MIT throughout. The art is not always ours. Some characters adapt art that declares no license, and each manifest names what it adapts and whose IP the character is.

License

MIT.

agent
agentic-ai
ai
ai-agents
buddy
desktop-application
desktop-pet
desktop-tools
game
javascript
leisure
linux
macos
rust
windows