A native macOS floating assistant for the Titan household agent — a red jellybean that lives on your screen, expands into a chat, and answers from your own on-prem AI.
Jellybean is a SwiftUI/AppKit menu-bar app. A draggable bean floats above everything; click it and it morphs open into a chat backed by the Titan household agent (a local Qwen3-8B model plus a fleet of knowledge/graph/vision runtimes running on your GPU host). Nothing goes to a third-party LLM — the brain is yours.
● floating bean ──click──▶ chat unfurls from the bean
│ (the bean becomes the send button)
└─ menu bar item · J global hotkeyWhat it does
- Chat with your household agent — recall facts, run calculations, read files, fetch links.
- Knowledge base browser — search and read everything the agent knows, organized by category (general · local · household · personal · workload · project), and tag items as context that ride along on your next message.
- Drop / paste anything — images (described via vision), files (ingested), links (fetched), text (into the field).
- Expressive bean — the floating icon changes color, glow, and a status tag to show state (idle · thinking · uploading · done · error), with an unread badge + TL;DR peek when closed.
- Device control (in progress) — calendar, reminders, alarms, files, Shortcuts, and a skills system, executed natively on the Mac with per-action confirmation and backups. See docs/ARCHITECTURE.md.
- Live, persisted settings — tune the animation/appearance from a Settings window; saved to
~/.config/jellybean/config.json.
Requirements
- macOS 14+ (built/tested on macOS 26, Apple Silicon)
- Swift 6 / Xcode 16+
- SSH access to the Titan host as the
titanalias (~/.ssh/config), and the titan-node repo at~/Projects/titan-node(the app shells its CLI). Override withTITAN_CLI/TITAN_SSH_HOST.
Build & run
cd mac
swift run # dev: launches the app directly
# or package a proper accessory .app:
./build-app.sh # mac/Jellybean.app (LSUIElement, ad-hoc signed)
open ./Jellybean.appThe app has no Dock tile (it's an accessory). It appears as the floating bean (bottom-right) and a bean in the menu bar.
Using it
| Action | How |
|---|---|
| Open / close chat | Click the bean · menu-bar bean · J (global) · Esc to close |
| Move the bean | Drag it |
| Send | Return, or click the bean-turned-send-button |
| Attach | Paperclip, drag-drop, or paste an image/file |
| Browse knowledge | Books icon in the input, or right-click bean Knowledge base |
| Tag context | Check items in the KB browser they appear as chips above the input |
| Settings | Right-click bean Settings (live; persisted) |
| Edit | C / V / X / A / Z all work; reply text is selectable |
How it connects
The app talks to the agent through the titan-node CLI over SSH (AgentClient shells
titan.sh agent prompt --tools). The agent loop runs on the host (where the runtimes live); the
Mac is the UI and the "hands" for device actions. See
docs/ARCHITECTURE.md for the full picture and
the host-side integration docs (titan-node,
docs/jellybean-integration.md).
Project layout
mac/
Package.swift Swift package (executable, macOS 14)
build-app.sh package the binary into Jellybean.app
make-icon.sh regenerate both icons from icon/jellybean.svg
Info.plist LSUIElement accessory app
icon/
jellybean.svg the bean — single source of truth for all icons
AppIcon.icns app/Dock icon (generated)
Sources/Jellybean/
main.swift NSApplication bootstrap (accessory policy)
AppShell.swift AppDelegate, panels, menu bar item, command bar, hotkey, windows
IconView.swift the floating bean: states, doze-to-dot, beansend morph
ChatView.swift the chat UI: welcome, bubbles, input, paste/drop, confirm card
ChatViewModel.swift chat state, send loop, fast-path, KB context, device handling
DeviceExecutor.swift native device actions (calendar/reminders/files/automation/skills)
DeviceBridge.swift device protocol parsing + local risk derivation
AgentClient.swift Process bridge to titan.sh (chat / device / kb); host upload
KnowledgeBase.swift KB model + master-detail browser (search, categories, edit)
CommandBar.swift Spotlight-style launcher
AppSettings.swift live tunables + ~/.config persistence + Settings window
MarkdownText.swift block markdown renderer (headings, lists, code, inline)
PeekView.swift TL;DR card that pops from the bean on a reply
Models.swift ChatMessage
Resources/jellybean.png the floating bean (generated)
docs/ARCHITECTURE.md system design
CLAUDE.md dev guide (auto-loaded by Claude Code)Changing the bean
The bean is one SVG. Edit mac/icon/jellybean.svg and run ./make-icon.sh to regenerate
the floating bean (Resources/jellybean.png) and the app icon (icon/AppIcon.icns).
This is a fully native app. The earlier Electron/React build has been removed.
License
Personal project — © Zach Shallbetter.