Skip to content

Repository files navigation

PawDOS 95 icon

PawDOS 95

PawDOS 95 is a retro browser desktop built for dogs. It tracks squirrels, monitors mail carriers, manages treats, translates humans, and gives Gemini a small set of safe ways to operate the desktop.

Open DogPrompt in the demo and try:

emergency there is a squirrel outside

When Gemini is online, PawDOS can answer in character, open Squirrel Tracker, add a radar target, show a warning, and trigger the bark driver.

PawDOS 95 desktop with DogPrompt and Squirrel Tracker open

Features

  • BIOS-style boot sequence and a complete desktop shell
  • Draggable, focusable, minimizable, and maximizable windows
  • Start menu, taskbar, clock, dialogs, notifications, and nap mode
  • Synthesized sound effects with sound disabled by default
  • Random squirrel, mailman, treat, and idle events
  • About 25 local terminal commands with history and Easter eggs
  • Gemini function calling for approved desktop actions
  • Structured Gemini responses for translations, dossiers, and diagnostics
  • Clearly labeled offline responses when Gemini is unavailable
  • Full-screen app views and touch-friendly controls on mobile
  • Keyboard navigation, focus management, reduced-motion support, and labeled meters

Applications

PawDOS includes nine applications:

  • DogPrompt runs local DOS-style commands and sends normal sentences to Gemini.
  • Squirrel Tracker 2.0 shows moving radar contacts, threat levels, controls, and AI-generated dossiers.
  • HUMAN.EXE translates human phrases into a dog's interpretation, emotional state, confidence, and recommended action.
  • Treat Manager tracks four food categories, low supplies, treat requests, and increasingly desperate begging.
  • Mailman Monitor provides a CSS security camera, a suspicion meter, and three barking strategies.
  • My Kennel reports happiness, uptime, system details, and an AI-generated hardware diagnostic.
  • My Documents contains a small fake filesystem with six readable files.
  • Notepad opens those documents in separate windows.
  • Settings controls sound, scanlines, and the AI status display.

Known commands such as help, dir, and whoami run entirely in the browser. Only unrecognized terminal input and requests from AI panels reach the Worker.

How Gemini Works

DogPrompt uses the Gemini Interactions API with function calling. The Worker exposes eight functions:

open_app
close_app
show_dialog
spawn_squirrel
bark
nap_mode
request_treat
set_mood

Gemini cannot access browser APIs, application state, or arbitrary code execution. It can only request one of these functions.

The Worker validates each request with toSystemAction() before it reaches the desktop. The validator checks function names, application ids, enum values, string lengths, and numeric ranges. PawDOS drops invalid calls and accepts no more than six actions from one command.

If Gemini requests an action, DogPrompt sends a function_result for each call. This lets the model explain which actions PawDOS accepted. The client waits for the terminal response to finish typing, then replays the approved actions with a short delay.

HUMAN.EXE, squirrel dossiers, and hardware diagnostics request structured data. The Worker normalizes and validates every field before React renders it. Confidence and threat values stay within their meter ranges. Diagnostic status is limited to OK, WARN, or FAIL.

Offline Behavior

PawDOS remains usable without a Gemini key. Missing credentials, upstream failures, timeouts, and rate limits produce an in-character local response.

The interface labels each result as either GEMINI SUBSYSTEM or LOCAL ROM (AI OFFLINE). A local response never presents itself as Gemini output.

Architecture

The project uses React 19, TypeScript, Vite 7, Zustand, a Cloudflare Worker, and the Gemini Interactions API.

shared/
  protocol.ts          Shared request, response, and system-action types
worker/
  index.ts             Routing, validation, headers, and offline responses
  gemini.ts            Gemini Interactions API client
  limits.ts            Per-visitor limit and optional usage counter
  tools.ts             Function declarations and action validation
  routes/              DogPrompt and structured panel handlers
src/
  apps/                The nine PawDOS applications
  components/          Windows, taskbar, menus, dialogs, and shared UI
  data/                Fake files and dialog presets
  lib/                 API, audio, drag, version, and viewport helpers
  os/                  Zustand slices and the system-action bridge
  styles/              Design tokens and retro interface styles
public/
  fonts/               Self-hosted VT323 and Silkscreen files
  icons/               Pixel icons and the favicon
scripts/
  verify-ai.mjs        Live Gemini smoke check

One Zustand store combines window, system, and UI slices. Window state owns focus, position, minimized state, maximized state, and z-order. System state owns treats, happiness, mood, squirrels, and effect counters. UI state owns dialogs, notifications, settings, boot state, and nap mode.

Desktop applications are singletons. Opening an application again focuses its existing window. Notepad documents use ids such as notepad:SECRET.TXT, so several documents can remain open at once.

Requirements

Use one of these Node.js versions:

  • Node.js 22.22.2 or newer in the 22.x release line
  • Node.js 24.15.0 or newer in the 24.x release line
  • Node.js 26 or newer

Local Development

Install the locked dependencies and start Vite:

npm ci
npm run dev

Open http://localhost:5173.

The desktop and all local commands work without a Gemini key. AI routes return clearly labeled local ROM responses until you add a key.

Add Gemini Locally

Get an API key from Google AI Studio. Then copy the example environment file:

cp .dev.vars.example .dev.vars

Add the key:

GEMINI_API_KEY=your-key-here

Do not commit .dev.vars. The repository ignores it. Restart the development server after you add the key.

To verify the real AI path, keep the server open and run this command in another terminal:

npm run verify:ai

This command sends real requests to Gemini. It checks all four AI routes and fails if any response uses the offline path.

Model Configuration

The default Worker configuration uses gemini-2.5-flash-lite for DogPrompt and the structured utility panels:

"vars": {
  "GEMINI_MODEL_TERMINAL": "gemini-2.5-flash-lite",
  "GEMINI_MODEL_UTILITY": "gemini-2.5-flash-lite"
}

Change these values in wrangler.jsonc. The terminal model must support function calling. The utility model must support structured JSON output.

You can override either model during local development:

GEMINI_MODEL_TERMINAL="gemini-2.5-flash-lite"
GEMINI_MODEL_UTILITY="gemini-2.5-flash-lite"

The Settings app reads the resolved model names from /api/health.

Available Commands

npm run dev          # Start the local app and Worker
npm test             # Run the Vitest suite
npm run typecheck    # Generate Worker types and run TypeScript checks
npm run build        # Create a production build
npm run preview      # Preview the production build
npm run verify:ai    # Check the four routes with real Gemini requests
npm run cf-typegen   # Rebuild Cloudflare binding types
npm run deploy       # Build and deploy with Wrangler

The test suite covers the Worker contract, request limits, security headers, system-action validation, OS state, local commands, terminal behavior, focus handling, dialog containment, and package-derived version display.

AI Input and Privacy

Local DogPrompt commands stay in the browser. Unrecognized terminal input and requests from the three AI panels go through the Worker to Gemini.

DogPrompt uses previous_interaction_id to continue a terminal conversation without sending the full transcript again. Gemini stores those stateful interactions. Review Google's Interactions API retention documentation before you deploy your own public copy.

HUMAN.EXE, squirrel dossiers, and diagnostics do not need conversation state. Their requests set store: false.

Do not send secrets or sensitive personal information through DogPrompt or HUMAN.EXE.

Deploy to Cloudflare

One Cloudflare Worker serves the built app and every /api/* route. The Gemini key stays in a Worker secret.

Log in, add the secret, and deploy:

npx wrangler login
npx wrangler secret put GEMINI_API_KEY
npm run deploy

After deployment, verify the live AI path:

npm run verify:ai https://your-worker.example

The deployed configuration limits each visitor to 12 AI requests per minute. You can bind a Workers KV namespace as PAWDOS_KV for an optional, approximate daily usage guard. KV is eventually consistent, so this counter is not a precise billing ledger or a guaranteed spending cap.

Mobile and Accessibility

Below 720px, application windows fill the available screen and dragging and resizing turn off. The start menu stacks its submenu, taskbar labels collapse, and DogPrompt does not open automatically on a fresh mobile load. Safe-area insets protect controls around notches and home indicators.

PawDOS also includes visible focus styles, keyboard-operable controls, focus-managed windows, modal focus containment, labeled meters, and reduced-motion rules. The window resize grip is one of those keyboard-operable controls: tab to it and the arrow keys resize the window without a pointer.

Known Limitations

  • Windows resize from the bottom-right grip only, not from their edges or other corners.
  • DogPrompt waits for the complete model response before it starts the typewriter effect.
  • Sound starts disabled and needs a click or tap before playback.
  • Local ROM responses come from a small fixed set and eventually repeat.
  • The optional KV usage counter is approximate during concurrent traffic.

Credits

PawDOS, its pixel icons, and its favicon were made by Pink Pixel.

The interface uses VT323 and Silkscreen. Both fonts are self-hosted under the SIL Open Font License 1.1. Their copyright and license files are included beside the font files.

License

PawDOS is available under the Apache License 2.0.

Made with 💖 by Pink Pixel

About

A retro browser desktop for dogs, with squirrel radar, treat management, mailman monitoring, and a Gemini-powered terminal.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages