Getting started
Install
| Command | |
|---|---|
| Desktop app, macOS | brew install --cask irooftop/tap/irooftop |
| Desktop app, Windows | Installer (.exe) or .msi |
| Desktop app, Linux | AppImage, .deb or .rpm |
| Server, macOS and Linux | brew install irooftop/tap/rooftop (then brew services start rooftop) |
| Server, anywhere with Rust ≥ 1.88 | cargo install rooftop |
| Server, container | docker pull ghcr.io/irooftop/rooftop (Docker) |
The desktop app needs no terminal: see Desktop app.
Run
sh
export OPENAI_BASE_URL=https://openrouter.ai/api/v1 # the default; any OpenAI-compatible API works
export OPENAI_API_KEY=…
export OPENAI_MODEL=openai/gpt-6-luna # must support tool calling
rooftop # http://127.0.0.1:8080The variables can also live in a .env file next to where you start rooftop, or be set later in Settings. Test in Settings sends a tiny request and tells you in plain words what is wrong, for example "openrouter.ai rejected the API key (401)".
Want nothing to leave your computer? Use a local model and Offline mode.
Your first chat
┌──────────────┐ ┌────────────────────┐ ┌──────────────────────┐
│ 1. Export │ ──▶ │ 2. Drop it onto │ ──▶ │ 3. New chat: pick │
│ the chat │ │ the page │ │ who the AI plays │
└──────────────┘ └────────────────────┘ └──────────────────────┘- Export a chat from Telegram Desktop or WhatsApp.
- Drop the folder,
.zipor WhatsApp.txtonto the page (or start withrooftop --import <folder>). - Press New chat and choose the persona: the other person, or yourself ("chat with myself in their style").
Try it without your own chats
The repository has two fictional exports in examples/: Jonas and Priya cook a lasagna on Telegram, Sofia and Daniel spend a weekend on WhatsApp.
sh
git clone https://github.com/irooftop/rooftop && cd rooftop
rooftop --import ./examples/telegramWhat's in the window
| Button | What it does |
|---|---|
| Share | Links for friends to talk to the persona |
| Media library | Every sticker, GIF, photo and voice message with what the AI knows about it |
| Notes | Things about the person the export doesn't say. The persona reads them, visitors never do |
{ } | The exact JSON sent to the model, and the tokens used |
| Rewrite | Drops the persona's last answer and writes it again |
| Let them write first | The persona starts the conversation |