S291.3 Vitto Desktop V2 Improvements
Documentation for Sessions
S291.3 — Vitto Desktop v2: Second Round of Improvements
For non-developers: This document explains what was changed in the Vitto Desktop app, why each change matters, and what's coming next. Written in plain language.
What Is This About?
Vitto Desktop is our AI companion that lives on your Mac as a floating avatar. In the first round (S291.1-S291.2), we built the entire 4-layer system from scratch: avatar overlay, command sidebar, deep hub, and visual canvas. This second round (S291.3) is about polish and real-world usability — fixing the issues found during hands-on testing.
Timeline of Changes
1. Fixed "Quit Vitto" Not Working
Problem: Clicking "Quit Vitto" in the right-click menu did nothing. The app refused to close.
Why it happened: Vitto is designed to stay alive in the background (like Slack or Dropbox) even when you close windows. But the "quit" button was using the same exit mechanism that the background-stay-alive system was blocking. A deadlock — Vitto told macOS "I want to quit," macOS asked Vitto "are you sure?", and Vitto's background system said "no, stay alive."
What we did: Made the quit command bypass the background system entirely. When you explicitly click "Quit Vitto," it now exits immediately.
2. Fixed Context Menu Blocking Desktop Clicks
Problem: The area around Vitto's avatar was "dead space" — you couldn't click on anything behind it, even though it looked transparent. This made the avatar annoying to have on screen.
Why it happened: The avatar window was 300x400 pixels (much larger than the 120x120 avatar) to make room for the right-click context menu. But on macOS, transparent windows still capture ALL mouse clicks within their area — there's no CSS trick to let clicks "pass through."
What we did: Shrunk the avatar window to 160x160 (just the avatar). When you right-click, the window temporarily expands to 300x400 to show the menu, then shrinks back when you close it. Now the avatar only blocks the small area it actually occupies.
Bonus: The context menu now also closes when you click anywhere outside the Vitto window (it detects when the window loses focus).
3. Added Close Buttons to Panels
Problem: Once you opened the command sidebar or the full hub, there was no visible way to close them. The only option was pressing Escape or switching apps.
What we did: Added X close buttons to the header of both the command sidebar and the hub. The close button turns red on hover (consistent with macOS conventions for destructive/dismiss actions).
4. Fixed Conscience & Knowledge Graph Layout
Problem: In the hub, the "Conscience" view had all its content stuck at the bottom of the screen with a huge empty space above. The Knowledge Graph also didn't properly fill the available space.
Why it happened: A subtle Angular layout bug. The hub uses a "sidebar + content area" layout. Inside the content area, Angular's routing system places an invisible <router-outlet> element. This invisible element was accidentally consuming 50% of the vertical space, pushing the real content to the bottom half.
What we did: Made the invisible element take zero space, giving all the room to the actual content.
5. Modernized the Chat UI
Problem: The chat in the command sidebar looked basic and unappealing compared to our web chat and VSCode extension chat. Plain grey bubbles, no visual personality.
What we did: Redesigned the chat to match Vitto's visual identity:
- User messages: Gradient purple bubbles (aligned right)
- Vitto's replies: Frosted glass effect with a purple accent line (aligned left, with a small "V" avatar indicator)
- Typing indicator: Blinking purple caret (like a text cursor) instead of generic bouncing dots
- Copy button: Appears on hover over Vitto's messages
- Empty state: Shows Vitto's branded orb with helpful hints
- Quick action pills: Purple-tinted to match the overall theme
- Send button: Gradient purple with a subtle glow
6. Fixed the App Icon
Problem: The app icon had an ugly white border/box around it that no other Mac app shows.
Why it happened: macOS wraps all app icons in a "squircle" shape and adds a subtle white border. This border is nearly invisible on light icons but very noticeable on dark backgrounds. Our original icon had a dark gradient background.
What we did: After three attempts (dark gradient, full-bleed dark, white background), we settled on a clean white background with the navy GoGrab symbol. This is how most professional Mac apps handle their icons — it looks crisp and native.
7. Improved the Perception Controls
Problem: The "Perception: Active" button in the context menu was confusing. Users didn't know what "perception" means, what "active" means vs alternatives, or what clicking it would do.
What perception does: It controls how much Vitto can "see" about your desktop activity:
- Passive: Vitto only knows the time. No awareness of what you're doing.
- Active: Vitto can see which app you're using, your window title, and clipboard changes. This lets it offer contextual help.
- Full: Vitto periodically takes screenshots and analyzes what's on screen. This is the most helpful but also the most privacy-sensitive.
What we did: Replaced the single confusing button with 3 clearly labeled options, each showing its name and a brief description. The currently active tier is highlighted. Users can now make informed privacy choices at a glance.
Technical Summary
| # | Issue | Root Cause | Fix | Files Changed |
|---|---|---|---|---|
| 1 | Quit not working | api.prevent_exit() blocks app.exit() |
std::process::exit(0) |
lib.rs |
| 2 | Click-through broken | 300x400 native window captures all clicks | Dynamic 160x160 ↔ 300x400 resize | window_manager.rs, desktop_commands.rs, desktop-avatar-shell.component.ts |
| 3 | No close buttons | Missing UI elements | Added X buttons + closePanel() / onCloseHub() |
desktop-command-shell.*, hub-sidebar.* |
| 4 | Layout broken | router-outlet steals flex space |
::ng-deep > router-outlet { display: none } |
desktop-hub-shell.component.scss |
| 5 | Chat UI basic | No design work done yet | Full redesign with glassmorphism + purple theme | command-message-stream.*, command-chat-input.*, quick-actions-bar.* |
| 6 | Icon ugly | Dark bg + macOS white border | White bg + navy symbol | icons/* |
| 7 | Perception confusing | Single cycling toggle, no labels | 3 radio options with descriptions | avatar-context-menu.*, desktop-avatar-shell.* |
What's Next
Remaining Work
- Chat connected to real backend: Currently the command surface chat hits
localhost:3003with no auth token. Needs to be wired to the actual Vitto API with proper authentication. - Hub route completeness: Some hub views (like Settings) need real implementations beyond basic wiring.
- Hetzner VNC integration (Task 14): Deferred from S291.1 — needs backend wiring to stream live VM sessions into the visual canvas.
- Avatar transparency: The avatar still shows the WebView's background in some edge cases. Needs further testing on production DMG installs.
- Tray icon: Should reflect the current perception tier visually (different colors for passive/active/full).
- Auto-update flow: The updater checks for updates but the banner notification in the Angular frontend needs testing.
- Windows/Linux support: Current implementation is macOS-focused (AppleScript for window titles, macOS-specific transparency APIs).
Quality Metrics
- Angular build: Clean (0 errors, 0 warnings)
- Rust build: Clean (1 warning: unused
hide_windowfunction — can be cleaned up) - All 7 fixes verified: Compiled, built into production .app, tested on macOS
Related Documents
- Spec:
docs/superpowers/specs/2026-03-31-vitto-desktop-v2-design.md - Plan:
docs/superpowers/plans/2026-03-31-vitto-desktop-v2.md - S291.1-S291.2 Memory:
~/.claude/projects/.../memory/s291-vitto-desktop-v2.md - MCP Decision IDs:
dev_1774982699319_48znjn1(quit fix),dev_1774982710829_v7hnj8z(click-through),dev_1774982719827_8t5di0m(layout),dev_1774982740578_oepldi1(chat UI),dev_1774982751027_2ly86pu(icon),dev_1774982759616_rqpjm7d(perception UX)