开源项目 GitHub Trending 2026-10-26T12:02 正文 ok 7951 words

🔥 nightly-labs/openbot:面向常驻 AI 队友的本地优先桌面工作空间

英文标题:🔥 nightly-labs/openbot

OpenBot 是一款采用本地优先架构的桌面工作空间应用,旨在让多个持久化 AI 队友协同工作。它支持本地 Codex App Server、Claude Code、Grok CLI 以及通过 ACP 协议接入的 OpenCode、Gemini、Cursor CLI 和 Cline CLI 等工具,为每个智能体分配专属工作区和会话。应用内置了本地任务队列、文件传输、内置浏览器控制以及 Agent 之间的点对点通信协作机制,为开发者打造了一个高度集成的多智能体本地开发与自动化环境。
打开原文相关 8 · 机会 3
media1.8 KB media2.2 KB media1.4 KB media63.5 KB

中文

CI License

OpenBot 是一个面向持久化 AI 队友的本地优先(local-first)桌面工作空间。它支持本地 Codex App Server 和 Claude Code,并可通过 ACP 支持 Grok CLI、OpenCode、Gemini、Cursor CLI 和 Cline CLI。它为每个 Agent 分配专属的工作空间和会话,并在单一桌面应用内提供本地队列、文件传输、内置浏览器以及 Agent 之间的相互通信协作能力。

警告

OpenBot 目前处于开发预览阶段。智能体目前以 danger-full-access 和 approvalPolicy: never 权限运行。在用户首次启动时明确同意后,它们即可读取并修改文件、执行命令、访问网络并控制内置浏览器,而无需每次操作逐一确认。请仅运行您信任的 Agent 和任务,做好数据备份,并在使用前仔细查阅安全相关说明。

  • 支持在桌面端和移动端通过 Prompt 驱动创建和编辑 Agent,支持编辑指令、头像并在保存前进行分段预览 review。
  • 持久化 Agent,由独立的 Codex、Claude、Grok、OpenCode、Gemini、Cursor 或 Cline 会话以及本地工作空间提供支持。
  • 支持自定义兼容 OpenAI 的端点以及自定义 ACP Agent,并可自动检测本地模型服务器(Ollama、LM Studio)和已安装的 Agent。
  • 单 Agent 级别的上下文监控,在长对话耗尽模型窗口之前自动进行压缩(compaction)。
  • 先进先出(FIFO)消息队列,具备暂停、恢复、取消以及崩溃安全的持久化特性。
  • 支持 Agent 间消息发送、回复、互动表情反应(reactions)、图片传输及托管文件传输。
  • 桌面共享频道聊天,支持单一任务所有者、显式授权委托、共享历史记录,以及停止(Stop)、恢复(Resume)、重新分配(Reassign)、归档(Archive)和恢复(Restore)控制。
  • 持久化的内置浏览器,Agent 可对其进行打开、检查和控制。
  • 在 macOS、Windows 和 Linux 上提供可选的 Computer Use 支持,通过发行版中附带的 cua-driver 二进制文件实现;OpenBot 会将其作为子进程启动并提供给各个 Provider。
  • 针对每个 Agent 独立配置模型、推理、配置文件、通知、浏览器和面板状态。
  • 可直接从账户菜单导出本地数据与保护隐私的诊断信息。
  • 可选的 OpenBot 账户体系,通过一次性邮箱验证码登录。账户 API 运行于 Cloudflare Workers 和 D1 之上。

OpenBot 是本地优先的,但并非仅限完全离线使用。Codex 连接到 OpenAI,Claude 连接到 Anthropic,Grok 连接到 xAI,Gemini 连接到 Google,Cursor 连接到 Cursor,Cline 连接到 Cline,访问的网页会使用网络,已安装的插件也可能会连接到它们自己的服务。

OpenBot 支持搭载 Apple Silicon 或 Intel 芯片且运行 macOS 13 或更高版本的设备、x64 架构且运行 Windows 10 或更高版本的系统,以及提供 x64 或 arm64 架构 AppImage 的 Linux 系统。

  1. 从 GitHub Releases 下载最新的 OpenBot-*-arm64.dmg(Intel Mac 用户请下载 OpenBot-*-x64.dmg)。

  2. 将 OpenBot 拖入 Applications 目录并打开。

  3. 从 GitHub Releases 下载最新的 OpenBot-*-x64.exe。

  4. 运行安装程序并打开 OpenBot。

  5. 从 GitHub Releases 下载最新的 OpenBot-*-x86_64.AppImage(arm64 用户请下载 OpenBot-*-arm64.AppImage)。

  6. 通过 chmod +x OpenBot-*.AppImage 赋予可执行权限,然后运行。

该 AppImage 不需要 libfuse2,因此它也可以在 Arch Linux 和 Omarchy 上运行。它会使用 fuse3 软件包中的 fusermount3 进行挂载。

在 Ubuntu 23.10 或更高版本以及 Debian 13 上,非特权用户命名空间受到 AppArmor 的限制,OpenBot 在启动过程中会退出,直到您安装 AppArmor 配置文件:

bash sudo install -m 0644 build/linux/openbot.apparmor /etc/apparmor.d/openbot sudo systemctl reload apparmor

AppImage 内部的 resources/linux/openbot.apparmor 位置也附带了相同的文件。如果您将 AppImage 放置在非常规路径下,请修改配置文件中的挂载路径。请勿使用 --no-sandbox 启动 OpenBot:这会移除渲染进程与计算机其余部分之间的隔离边界。

首次从 AppImage 启动时,OpenBot 会写入 ~/.local/share/applications/openbot.desktop 和 ~/.local/share/icons/openbot.png,这使得 openbot:// 协议链接(例如邀请链接或插件列表)能够调起应用,并在应用退出后依然在启动器中保留图标。删除这两个文件即可恢复原状。

远程桌面可在 Linux x64 的 X11 会话(如 Xorg 或 Xvfb)下工作。它不支持 Wayland,且 arm64 AppImage 中不包含该功能。

对于 Gemini 登录,请安装桌面浏览器和 xdg-utils。在同一台主机或虚拟机的桌面会话中打开登录页面。Google 会通过 127.0.0.1 向该主机发送回调;没有桌面的服务器无法完成此登录流程。详见 Gemini setup。

无屏幕的 Linux 服务器

要在 VPS 或家庭服务器(基于 systemd 的 Ubuntu 24.04 或 26.04)上将 OpenBot 作为账户的常驻服务器运行,可通过终端进行安装并使用邮箱验证码登录:

bash curl -fsSL https://raw.githubusercontent.com/nightly-labs/openbot/main/scripts/install-server.sh | sudo bash sudo openbot login

随后即可通过桌面端应用、iPhone 应用或 openbot.run/app 进行使用。更多选项和 openbot 命令请参阅自建服务器文档。

相同的服务器端也可以容器形式运行(支持 linux/amd64 和 linux/arm64)。其中的 seccomp 配置文件可确保 Electron 沙箱保持开启:

bash curl -fsSLO https://raw.githubusercontent.com/nightly-labs/openbot/main/docker/seccomp.json docker run -d --name openbot --restart unless-stopped
--security-opt seccomp=seccomp.json --security-opt no-new-privileges:true
--shm-size 1g --stop-timeout 60 -v openbot-data:/data
ghcr.io/nightly-labs/openbot:latest docker exec -it openbot openbot login

有关 Compose 配置、数据卷、升级和安全限制的内容请参阅 Docker。有关 Amazon ECS 的内容,请参阅 AWS ECS。

Flake 会在 x64 或 arm64 Linux 以及 Apple Silicon 上从最新 Release 安装桌面应用:

bash nix run github:nightly-labs/openbot nix profile install github:nightly-labs/openbot

overlays.default 会添加 pkgs.openbot。OpenBot 不是自由软件,因此您的 nixpkgs 必须允许非自由软件,例如配置 nixpkgs.config.allowUnfreePredicate = pkg: lib.getName pkg == "openbot";。Nix 会负责安装 OpenBot 的更新。OpenBot 不会通过 Nix store 自行更新。在 Linux 上,Nix 包不包含远程桌面运行时,因为 nixpkgs 缺少其所需的相关库。

重要提示

Windows 版本由 SYNTHETIFY LABS SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ 进行代码签名。较旧的版本未进行代码签名。SmartScreen 仍可能对新版本发出安全警告。在运行安装程序之前,请务必核对版本校验和或 GitHub 构建证明(build attestation)。

当你在入门引导、设置(Settings)、Agent 配置或模型选择器中点击 Download 时,OpenBot 可以自动下载受支持的 Provider 运行时。OpenBot 优先使用其统一管理的 CLI。显式配置的 OPENBOT_*_PATH 环境变量覆盖具有最高优先级;当没有托管副本可用时,会使用系统内兼容的 CLI。OpenBot 会在启动时以及之后每小时检查是否有更新的 Provider CLI 版本,点击 Provider 操作菜单中的 Check for updates 即可立即检查。更新时会安装最新的上游版本,而不会更改用户的系统 CLI;native-runtime.lock.json 中的版本仅作为首次安装时的回退保底版本。

你也可以选择自行安装 CLI。

在 macOS 上安装 Codex CLI:

bash curl -fsSL https://chatgpt.com/codex/install.sh | sh

在 macOS 上安装 Claude CLI:

bash curl -fsSL https://claude.ai/install.sh | bash

按照 Grok Build 文档 安装 Grok CLI,然后使用 grok login 进行身份验证,或者在启动 OpenBot 的环境中设置 XAI_API_KEY。

与 Codex、Claude 和 Grok 类似,OpenBot 会自动下载并锁定 OpenCode CLI。OpenCode 的免费模型无需账户,也无需登录:选择 OpenCode,点击 Connect,OpenBot 就会读取该 CLI 声明支持的模型。若要使用付费的 OpenCode Go 模型,请在 OpenCode 行点击 Sign in 并粘贴来自 opencode.ai/auth 的 Go key。OpenBot 会在当前计算机上对该密钥进行加密,并仅提供给本地 CLI 使用。OpenBot 仅支持 OpenCode Go:Go key 无法购买的 Zen 模型不会显示在选择器中。模型选择器中带有 Free 标签的模型无需登录即可使用。其他模型则需要登录对应的 Provider:对于 opencode-go/ 系列模型需要 Go key,对于 OpenCode Zen 和第三方 Provider 则需在终端中执行 opencode auth login。若未登录,该轮交互将会失败,并弹出提示具体 Provider 名称的错误。如果您是自行安装的 OpenCode,OpenBot 将保留该安装版本且不提供下载选项。设置 OPENBOT_OPENCODE_PATH 可以指定位于 shell 搜索路径之外的可执行文件。远程 OpenCode Agent 需要 Team API v4;旧版客户端将不会显示这些 Agent。

Gemini 需要使用 Google AI Pro 或 Ultra 订阅方案。当你在 Gemini 行点击 Download 时,OpenBot 会在当前计算机上下载 Google 的 Antigravity ACP 服务器,因为 Google 的许可证不允许 OpenBot 直接打包分发该组件。点击 Sign in 会在浏览器中打开 Google 的登录页面。OpenBot 绝不会使用你环境变量搜索路径中的 antigravity 命令,因为 Antigravity 编辑器会安装同名命令。你可以设置 OPENBOT_ANTIGRAVITY_PATH 手动指定服务器可执行文件。请将其放置在 bin/ 目录中,并在 bin/ 的上级目录中放置包含其 version 字段的 antigravity-package.json 文件。同时确保 localharness_external 存放在服务器旁边。一旦设置了该路径,OpenBot 将仅使用它。Connect 按钮在宿主机的本地 Settings > Providers 界面中始终可用。远程设置无法执行 Google 登录;请使用宿主机上的浏览器操作。有关必需的目录结构、已知的 IPv6 下载失败问题以及不改变宿主机网络的检查方法,请参阅 Gemini 设置与下载恢复。

Cursor 需要 Cursor 订阅方案或 Cursor API Key。当在 More providers 中点击 Cursor 行的 Download 时,OpenBot 会下载并锁定 Cursor CLI(cursor-agent),并通过 cursor-agent acp 启动它。点击 Sign in 会在浏览器中打开 Cursor 的登录页面。您也可以在启动 OpenBot 的环境中设置 CURSOR_API_KEY。如果您已自行安装了 cursor-agent,在下载可用前 OpenBot 会使用它。OpenBot 绝不会调用用于启动 Cursor 编辑器的 cursor 命令。设置 OPENBOT_CURSOR_PATH 可手动指定可执行文件。Cursor Agent 仅保留在当前计算机上:团队成员无法查看。

Cline 需要 Cline 账户,提供有配额限制的免费模型。免费模型的提供方可能会使用你的提示词来训练模型。当在 More providers 中点击 Cline 行的 Download 时,OpenBot 会下载并锁定 Cline CLI(cline),并通过 cline --acp 启动它。点击 Sign in 会在浏览器中打开 Cline 的登录页面。你也可以在启动 OpenBot 的环境中设置 CLINE_API_KEY。如果您已自行安装了 cline 3.0.68 或更高版本,在下载完成前 OpenBot 会使用它。设置 OPENBOT_CLINE_PATH 可手动指定可执行文件。Cline Agent 同样仅保留在当前计算机上:团队成员无法查看。

在 Windows 上,请安装原生 CLI 并确保在 PowerShell 中可以访问 codex、claude 或 grok。Claude Code 还需要安装 Git for Windows。随后完成已安装 CLI 的认证并重启 OpenBot。

使用已安装的发行版时无需安装 Bun 和 Node.js。可选的 Computer Use 功能支持 macOS、Windows 和 Linux,且安装包已内置驱动,因此无需额外安装任何内容。只有 macOS 会为此请求相应权限:屏幕录制与辅助功能。

OpenBot 直接复用现有的本地 CLI 登录凭据,不会复制 Provider 凭证。Grok 的 XAI_API_KEY 和每会话 MCP bearer token 绝不会被持久化或记录到日志中。各个 Provider 的服务条款均适用于你的登录行为。关于 Claude 订阅的详情请参阅 provider terms。

有关安装排错、数据重置和卸载说明,请参阅 Troubleshooting。OpenBot 的数据存储与网络行为说明可在 Privacy 中查阅。

开发环境需要稳定的 Bun 1.4.2、Node.js 24(即 .nvmrc 中指定的版本,与 Electron 内置的 Node 版本一致——可运行 nvm use 切换),以及至少一个受支持的 Agent CLI。

在 macOS 或 Linux 上安装指定版本的 Bun:

bash curl -fsSL https://bun.com/install | bash -s "bun-v1.4.2"

在 Windows 的 PowerShell 中进行安装:

powershell iex "& {$(irm https://bun.com/install.ps1)} -Version 1.4.2"

从源码运行项目:

bash git clone https://github.com/nightly-labs/openbot.git cd openbot bun install --frozen-lockfile bun run codex:doctor bun run dev

codex:doctor 命令用于检查 CLI 版本、App Server 握手状态以及 ChatGPT 登录情况,期间不会发起模型对话。bun run cua-driver:doctor 则单独报告 Computer Use 驱动的状态。

在新的 git worktree 中,请运行 bun run dev:bootstrap。当缺失文件时,它会从主检出目录中复制 .worktreeinclude 列出的文件、安装依赖项、迁移本地 API,并预置隔离的环境配置。可以将其设置为 Agent harness 的 worktree setup 命令。

English / 原文

CI License

OpenBot is a local-first desktop workspace for persistent AI teammates. It supports the local Codex App Server and Claude Code, plus Grok CLI, OpenCode, Gemini, Cursor CLI, and Cline CLI through ACP. It gives every agent its own workspace and conversation, and provides local queues, file transfers, an embedded browser, and agent-to-agent messaging in one desktop app.

Warning

OpenBot is a development preview. Agents currently run with danger-full-access and approvalPolicy: never. They can read and modify files, run commands, use the network, and control the embedded browser without per-action confirmations after the explicit first-launch consent. Run only agents and tasks you trust, keep backups, and review Security before use.

  • Prompt-driven agent creation and editing on desktop and mobile, with editable instructions, avatar, and section review before saving.
  • Persistent agents backed by independent Codex, Claude, Grok, OpenCode, Gemini, Cursor, or Cline sessions and local workspaces.
  • Custom OpenAI-compatible endpoints and custom ACP agents, with detection of local model servers (Ollama, LM Studio) and installed agents.
  • Per-agent context monitoring with automatic compaction before long threads exhaust the model window.
  • FIFO message queues with pause, resume, cancellation, and crash-safe persistence.
  • Agent-to-agent messages, replies, reactions, images, and managed file transfers.
  • Shared desktop channel chats with one task owner, explicit delegation, shared history, and Stop, Resume, Reassign, Archive, and Restore controls.
  • A persistent embedded browser that agents can open, inspect, and control.
  • Optional Computer Use on macOS, Windows and Linux through the cua-driver binary in the release, which OpenBot starts as its own child process and gives to every provider.
  • Per-agent model, reasoning, profile, notification, browser, and panel state.
  • Local data and privacy-safe diagnostics exports from the account menu.
  • Optional OpenBot accounts through one-time email codes. The account API runs on Cloudflare Workers and D1.

OpenBot is local-first, not offline-only. Codex connects to OpenAI, Claude connects to Anthropic, Grok connects to xAI, Gemini connects to Google, Cursor connects to Cursor, Cline connects to Cline, visited pages use the network, and installed plugins may connect to their own services.

OpenBot supports macOS 13 or newer on Apple silicon or Intel, Windows 10 or newer on x64 systems, and x64 or arm64 Linux as an AppImage.

  1. Download the latest OpenBot-*-arm64.dmg (or OpenBot-*-x64.dmg on an Intel Mac) from GitHub Releases.

  2. Drag OpenBot to Applications and open it.

  3. Download the latest OpenBot-*-x64.exe from GitHub Releases.

  4. Run the installer and open OpenBot.

  5. Download the latest OpenBot-*-x86_64.AppImage (or OpenBot-*-arm64.AppImage on arm64) from GitHub Releases.

  6. Make it executable with chmod +x OpenBot-*.AppImage, then run it.

The AppImage does not need libfuse2, so it also runs on Arch Linux and Omarchy. It mounts itself with fusermount3 from the fuse3 package.

On Ubuntu 23.10 or newer and on Debian 13, unprivileged user namespaces are restricted by AppArmor and OpenBot exits during launch until you install an AppArmor profile:

sudo install -m 0644 build/linux/openbot.apparmor /etc/apparmor.d/openbot
sudo systemctl reload apparmor

The same file ships inside the AppImage at resources/linux/openbot.apparmor. Edit the attachment path in the profile if you keep the AppImage outside the usual locations. Do not start OpenBot with --no-sandbox: that removes the boundary between a renderer and the rest of the computer.

On the first start from an AppImage, OpenBot writes ~/.local/share/applications/openbot.desktop and ~/.local/share/icons/openbot.png, which is what lets an openbot:// link - an invitation, or a plugin listing - open the app and gives the launcher an icon that stays after the app exits. Delete the two files to undo it.

Remote desktop works on Linux x64 in an X11 session, such as Xorg or Xvfb. It does not work under Wayland, and the arm64 AppImage does not include it.

For Gemini sign-in, install a desktop browser and xdg-utils. Open the sign-in page in a desktop session on the same host or VM. Google sends the callback to that host through 127.0.0.1; a server with no desktop cannot complete this sign-in. See Gemini setup.

Linux server with no screen

To run OpenBot as an always-on server of your account on a VPS or home server (Ubuntu 24.04 or 26.04 with systemd), install it from a terminal and sign in with an email code:

curl -fsSL https://raw.githubusercontent.com/nightly-labs/openbot/main/scripts/install-server.sh | sudo bash
sudo openbot login

Then use it from the desktop app, the iPhone app or openbot.run/app. See self-hosted servers for the options and the openbot commands.

The same server runs as a container (linux/amd64 and linux/arm64). The seccomp profile lets the Electron sandbox stay on:

curl -fsSLO https://raw.githubusercontent.com/nightly-labs/openbot/main/docker/seccomp.json
docker run -d --name openbot --restart unless-stopped \
  --security-opt seccomp=seccomp.json --security-opt no-new-privileges:true \
  --shm-size 1g --stop-timeout 60 -v openbot-data:/data \
  ghcr.io/nightly-labs/openbot:latest
docker exec -it openbot openbot login

See Docker for Compose, the data volume, upgrades and the security limits. For Amazon ECS, see AWS ECS.

The flake installs the desktop app from the latest release on x64 or arm64 Linux and on Apple silicon:

nix run github:nightly-labs/openbot
nix profile install github:nightly-labs/openbot

overlays.default adds pkgs.openbot. OpenBot is not free software, so your nixpkgs must allow it, for example with nixpkgs.config.allowUnfreePredicate = pkg: lib.getName pkg == "openbot";. Nix installs OpenBot updates. OpenBot does not update itself from the Nix store. On Linux, the Nix package does not include the remote desktop runtime, because nixpkgs does not have a library that it needs.

Important

Windows releases are signed by SYNTHETIFY LABS SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ. Older releases are not code-signed. SmartScreen can still warn about a new release. Check the release checksum or GitHub build attestation before you run the installer.

OpenBot can download a supported provider runtime when you select Download in onboarding, Settings, agent setup, or the model picker. OpenBot prefers its managed CLI. Explicit OPENBOT_*_PATH overrides take precedence; a compatible system CLI is used when no managed copy is available. OpenBot checks for a newer provider CLI release at startup and every hour, and Check for updates in a provider's actions menu checks at once. Updates install the latest upstream release without changing the user’s system CLI; the version in native-runtime.lock.json is only the first-install fallback.

You can also install a CLI yourself.

Codex CLI on macOS:

curl -fsSL https://chatgpt.com/codex/install.sh | sh

Claude CLI on macOS:

curl -fsSL https://claude.ai/install.sh | bash

Install Grok CLI following the Grok Build documentation, then authenticate with grok login or set XAI_API_KEY in the environment used to launch OpenBot.

OpenBot downloads and pins the OpenCode CLI, like Codex, Claude, and Grok. OpenCode's free models need no account and no sign-in: select OpenCode, click Connect, and OpenBot reads the models that the CLI advertises. To use the paid OpenCode Go models, click Sign in on the OpenCode row and paste a Go key from opencode.ai/auth. OpenBot encrypts the key on this computer and gives it only to the local CLI. OpenBot supports OpenCode Go only: the Zen models a Go key does not buy stay out of the picker. Models with the Free label in the model picker need no sign-in. Other models need a sign-in with their provider: a Go key for the opencode-go/ models, or opencode auth login in a terminal for OpenCode Zen and third-party providers. Without it, the turn fails with an error that names the provider. If you installed OpenCode yourself, OpenBot keeps that install and offers no download. Set OPENBOT_OPENCODE_PATH to select an executable outside your shell's search path. Remote OpenCode agents require Team API v4; older clients do not show these agents.

Gemini uses a Google AI Pro or Ultra plan. OpenBot downloads Google's Antigravity ACP server on this computer when you select Download on the Gemini row, because Google's license does not let OpenBot include it. Sign in opens Google's sign-in page in your browser. OpenBot never uses an antigravity command on your search path, because the Antigravity editor installs a command with that name. Set OPENBOT_ANTIGRAVITY_PATH to select a server executable yourself. Put it in a bin/ folder, and put an antigravity-package.json file with its version in the folder above bin/. Keep localharness_external beside the server. When that path is set, OpenBot uses only it. Connect remains available in the host's local Settings > Providers screen. Remote settings cannot perform Google sign-in; use a browser on the host. See Gemini setup and download recovery for the required layout, the reported IPv6 download failure, and checks that do not change host networking.

Cursor uses a Cursor plan or a Cursor API key. OpenBot downloads and pins the Cursor CLI (cursor-agent) when you select Download on the Cursor row in More providers, and starts it with cursor-agent acp. Sign in opens Cursor's sign-in page in your browser. You can also set CURSOR_API_KEY in the environment used to launch OpenBot. If you installed cursor-agent yourself, OpenBot uses it until a download exists. OpenBot never uses the cursor command, which starts the Cursor editor. Set OPENBOT_CURSOR_PATH to select an executable yourself. Cursor agents stay on this computer: team members do not see them.

Cline uses a Cline account, which has free models with limits for each model. The provider of a free model can use your prompts to train models. OpenBot downloads and pins the Cline CLI (cline) when you select Download on the Cline row in More providers, and starts it with cline --acp. Sign in opens Cline's sign-in page in your browser. You can also set CLINE_API_KEY in the environment used to launch OpenBot. If you installed cline 3.0.68 or newer yourself, OpenBot uses it until a download exists. Set OPENBOT_CLINE_PATH to select an executable yourself. Cline agents stay on this computer: team members do not see them.

On Windows, install the native CLI and make sure codex, claude, or grok is available in PowerShell. Claude Code also requires Git for Windows. Then authenticate the installed CLI and restart OpenBot.

Bun and Node.js are not required when using an installed release. Optional Computer Use works on macOS, Windows and Linux, and the release carries the driver, so there is nothing to install. Only macOS asks for a permission for it: Screen Recording and Accessibility.

OpenBot uses the existing local CLI login. It does not copy provider credentials. Grok's XAI_API_KEY and per-session MCP bearer tokens are never persisted or logged. Each provider's terms apply to your sign-in. See provider terms for Claude subscriptions.

For setup problems, data reset, and uninstall instructions, see Troubleshooting. OpenBot's data and network behavior is documented in Privacy.

Development requires stable Bun 1.4.2, Node.js 24 (the version in .nvmrc, matching the Node that Electron bundles - run nvm use), and at least one supported agent CLI.

Install the exact Bun version on macOS or Linux:

curl -fsSL https://bun.com/install | bash -s "bun-v1.4.2"

Install it on Windows in PowerShell:

iex "& {$(irm https://bun.com/install.ps1)} -Version 1.4.2"


git clone https://github.com/nightly-labs/openbot.git
cd openbot
bun install --frozen-lockfile
bun run codex:doctor
bun run dev

codex:doctor checks the CLI version, App Server handshake, and ChatGPT login without starting a model turn. bun run cua-driver:doctor reports the Computer Use driver separately.

In a new git worktree, run bun run dev:bootstrap. It copies the files that .worktreeinclude lists from the main checkout when they are missing, installs dependencies, migrates the local API, and seeds the isolated profile. Set it as the worktree setup command of your agent harness.

On macOS, a worktree's node_modules uses almost no new disk space. Bun clones packages from its cache, and the root postinstall clones Electron from ~/Library/Caches/OpenBot/electron-dist. du still shows the full size of each clone. The first install of an Electron version extracts it once and saves it there. Delete the directory to clear the cache; an entry that nobody used for 30 days is removed by the next save.

To reset only the local development state, quit the dev app and test client, then run bun run dev:reset. The command deletes the app and test-client development profiles plus the legacy host profile, including openbot.db and its WAL files. It prints each profile before it deletes it, and it deletes nothing while a dev app has one of them open. It does not change the production profile, the worktree profiles that bun run dev opens (OpenBot Dev wt-<hash>), agent workspaces, ~/.codex, or ~/.claude.

bun run dev seeds a development profile it creates, so a first start already shows this data. bun run dev:seed replaces the shared OpenBot Dev profile. To use it, quit the dev app, then run:

bun run dev:seed
bun run dev --shared

The seeded agents run on opencode-go/muse-spark-1.3-contributor at medium effort while this computer's OpenCode CLI lists it, and on gpt-6-luna at low effort otherwise. A dev build starts a new agent on the same pair, so a seeded agent and one you create agree; a packaged build always uses gpt-6-luna.

The seed adds agents, rich conversations, managed files and references, reactions, completed agent exchanges, two channels with a delegated task run, channel memories and routines, and local team chat data. It dates every record backwards from the run, so the transcripts read Today and Yesterday. It does not add live queue items, open routine runs, or queued channel tasks, so it starts no model turn. Use bun run dev:seed --dry-run to inspect the target and fixture counts without changing files. dev:seed, dev:reset, dev:verify, dev:bench, and dev:automation print their usage for --help and change nothing. They stop with exit code 2 on an option that they do not know.

Marketplace launch catalog

Seed the approved OpenBot team catalog locally with bun run marketplace:seed:local, then start or reuse bun run dev. Search OpenBot in Marketplace to review its Skills and Agents. This seed adds catalog records without resetting app data.

bun run marketplace:build creates the launch bundles. bun run marketplace:publish:production is a dry run; production writes require explicit flags and admin credentials. See the catalog and publication guide.

Skill authors can add optional example-prompt text to the YAML frontmatter in SKILL.md:

example-prompt: Turn the latest commits into release notes.

The skill preview shows this text. Try skill appends it and a skill reference to the selected agent's draft. It does not send the message. The field accepts up to 1,000 characters after trimming. Missing or invalid values use a default example. No new package format or database migration is required.

Ask an agent to create a skill from a reusable workflow. It prepares a folder with SKILL.md and calls create_skill. The skill is saved in a shared local library and enabled for that agent. Other agents can add it through Settings → Skills → Local skills.

Agents can use list_local_skills, read_local_skill, revise_skill, and install_local_skill. Revisions require the version read by the agent and retain previous versions. Updating a library skill does not update installed copies: use the Update chip or install an exact revision. Modified installed files are protected. To publish a local skill, submit its folder separately through the marketplace.

Optional scripts, references, and assets follow the Codex skill folder structure. A PNG at assets/icon.png supplies the local preview logo. The built-in openbot-skill-creator guide explains the format and validation limits. Registration does not run scripts.

Import agents from Grok Bot

Open Server settings → Import on this computer, or on a joined server in the desktop app or the browser client. Every member of a server can import, not only an owner or admin. Add the OpenBot export agent to Grok Bot and say "Export my agents for OpenBot". It saves one .zip file to Downloads. Choose that file in OpenBot, select the agents, and import them.

The import adds each agent's name, instructions, avatar, skills, routines, and memories. Workspace files are copied to imported/ in the agent's workspace if you included them. Chat history is not copied: the export agent keeps the important facts as memories. For this computer, the file is read here and is not uploaded. For a joined server, the file (at most 100 MB) goes to the computer that runs that server through the encrypted host connection. A member's import uses a skill that the server already has instead of changing it. The export skill and its format are in resources/agent-import/grok-bot/SKILL.md.

The browser client is served at /app by the public web app. For local development, run bun run dev:api and open /app on the API URL printed by the supervisor. Use bun run dev when a desktop host is also needed. Use bun run storybook and Web → Workspace → Connected for shared UI test data. See web client delivery for the release gate and focused checks.

Command Purpose
bun run dev Start the local Auth API, Signal service, and Electron client with renderer HMR on its app profile. Ports are allocated through the dev registry, so a sibling worktree never takes one this stack won. It refuses a second stack in the same worktree unless you pass --force. Each worktree opens a profile of its own, keyed to its path; --shared opens the shared OpenBot Dev profile instead. --isolated is still accepted and changes nothing. A profile that you used before stays on disk unchanged. --hosting=test signs the app in to the test account Worker, on a profile that all worktrees share, so that a hosted server is a real VM; see docs/hosted-servers.md. A profile that does not exist yet is seeded with the showcase data of bun run dev:seed before the client starts, so a first start never opens an empty app; an existing profile is left as it is. An isolated profile still shares the computer's provider CLI store, so it does not download the pinned CLIs again. Before it starts, it runs bun install --frozen-lockfile and bun run api:migrate:local only when bun.lock, a workspace package.json, a patch, or a migration changed since their last successful run. The stamps are in node_modules and apps/auth-api/.wrangler/state/v3/d1, and each bun install writes the install stamp too; delete one to run its step again.
bun run preview Preview the built Electron client with the green preview icon.
bun run mobile:go Start the mobile app in Expo Go and clear the Metro cache.
bun mobile:ios Build and launch the iOS simulator app without RocketSim.
bun run dev:mobile Start or reuse this worktree's bun run dev stack, build and launch the iOS simulator app, and pair them without a QR scan. The desktop issues a Mobile Connect ticket over CDP, and simctl openurl opens the link in the development build, which accepts only loopback or private-network account services. Other arguments go to bun mobile:ios. --pair-only pairs an app that already runs; --simulator=<udid> chooses one of several booted simulators. It stops when the Metro port is already in use, because another worktree's Metro would serve the same app id; pass --port=<n> then.
bun run mobile:ios:build:local Build a production iOS .ipa locally for upload with Transporter. See TestFlight setup.
bun run mobile:ios:release:testflight Start the GitHub Actions iOS build from main and upload to TestFlight. Requires authenticated GitHub CLI. See iOS release setup.
bun mobile:ios:rocketsim Start RocketSim and build and launch the iOS simulator app with RocketSim Connect. See mobile setup.
bun run mobile:go:tunnel Start the mobile app in Expo Go through a Metro tunnel and clear the cache. The OpenBot API and Signal still need their own reachable addresses.
bun run dev:api Start the TanStack Start API and its local D1 database on 127.0.0.1:3100.
bun run dev:apns-key -- <AuthKey_ID.p8> [KEY_ID] Save an Apple Push Notification service key in ignored development state, so the local Auth API sends iPhone Live Activity updates. The local server forwards them to Apple over HTTP/2. Restart bun run dev after it.
bun run api:start Build and preview the Cloudflare Worker locally.
bun run api:images Draw the article artwork into apps/auth-api/content-art/ after you add an article or change a title. Commit the result; the site build fails until it matches. Needs Electron and a GPU, so run it on your own machine.
bun run api:migrate:local Apply D1 migrations to the local development database.
bun run api:migrate:remote Apply D1 migrations to the configured remote database.
bun run api:deploy Build and deploy the account API to Cloudflare Workers. It sets the Stripe, boat, claim and OpenPanel secret sets that are in the production environment. A set that is not there keeps the value that the Worker has.
bun run api:stripe:bootstrap Create or update the Stripe plan catalog and the Customer Portal settings from STRIPE_SECRET_KEY in the encrypted apps/auth-api/.env.dev (shell values replace it). It refuses a live key unless you add --live. For local webhooks, run stripe listen --forward-to localhost:<API port>/v1/stripe/webhook and set the signing secret in STRIPE_WEBHOOK_SECRET. See Billing.
`bun run hosting:setup --target=production test`
bun run hosting:template Build the boat named snapshot that new hosted servers start from. Needs BOAT_TEMPLATE_API_KEY and --version, --appimage-url, --appimage-sha256 and --auth-api-url. See hosted servers.
bun run status:build Build the public status page in apps/status/dist. The status-page workflow adds status.json and feed.xml and publishes it to GitHub Pages at status.openbot.run.
bun run status:smoke Run the status page smoke test: update runs against a local fake service, the status webhooks against a local receiver, one read-only run against the live checks, and the built page in Chrome. It writes .openbot-build/status-page/report.json.
bun run remote:up Build and start the self-hosted Signal, coturn, and ACME stack.
bun run remote:check Check the Remote API and both Docker Compose configurations.
bun run remote:check:compose Validate both Docker Compose configurations alone, without a running daemon.
bun run remote:update Update Signal, then drain and update the single coturn instance.
bun run dev:all Start the Auth API, Signal service, and single local Electron instance.
bun run dev:slack Start the same stack as bun run dev, with two cloudflared quick tunnels, one to Signal and one to the local account API, so that Slack can send the development Slack app's events and install return to the agents on this computer. It reads OPENBOT_DEV_SLACK_SIGNING_SECRET from the ignored .env.slack-dev, and needs SLACK_ROUTE_PRIVATE_JWK and SLACK_ROUTE_KEY_ID in the shell environment. Takes the same options as bun run dev, such as --shared. See docs/messaging.md.
bun run dev:test-client Start the Auth API, Signal service, local instance, and an isolated second client for team testing.
bun run dev:seed Replace only the app development profile with durable showcase data. --if-missing keeps an existing profile, which is how bun run dev seeds a first start. --scale=agents:N,messages:M,channels:C,channelMessages:K,attachments:A adds generated agents, chat history, channel history and large images to the showcase data, for memory and CPU measurements.
bun run dev:reset Delete the local app, test-client, and legacy host development state. It refuses while a dev app has one of these profiles open.
bun run dev:status Print, as JSON, every dev stack and dev app instance live on this machine: services, ports, pids, which of them belong to this worktree, and which are orphaned - a supervisor that is gone with its children still holding the ports. Each recorded process carries the state a stop command acts on: live, gone with groupLive for a survivor of a dead leader, and unverified for a pid this machine cannot date. registryDirectory is the directory it read: ~/Library/Caches/OpenBot/dev on macOS, $XDG_RUNTIME_DIR/openbot-dev (else ~/.cache/openbot/dev) on Linux, %LOCALAPPDATA%\OpenBot\openbot-dev-instances on Windows, or OPENBOT_DEV_REGISTRY_DIR when set. It does not depend on TMPDIR.
bun run dev:verify Print a stable JSON verification plan for this worktree: ready/reasons for safe checks, setup state, changed files and affected surfaces, nearby tests, runtime state, qa.required/qa.ready/qa.reasons, the renderer QA loop, safe runnableCommands, and all suggested commands. Add --run to execute only the safe non-mutating checks in the plan. Renderer QA follows snapshot → action with --wait-for → snapshot → screenshot when appearance matters.
bun run dev:stop Stop this worktree's dev stack, children included, using the pids in the registry rather than a process-name pattern. It signals only a pid whose start time still matches the record, so a recycled pid is never sent SIGTERM; anything it cannot confirm is reported, left running and kept in the registry, and the command exits non-zero. --pid=<supervisor pid> stops one other stack, --all stops every stack on the machine.
bun run dev:forget Drop this worktree's stack record without signalling anything, for the one case dev:stop refuses to resolve on its own. It is also the only command that reads a dead record: nothing else deletes one, because a reader that removes what it judged can remove a record the supervisor rewrote in between. Takes the same --pid= and --all.
bun run storybook Start Storybook on a port allocated through the same registry, so two worktrees never announce one port. OPENBOT_STORYBOOK_PORT moves where the search starts; --port is refused.
bun run build-storybook Build static Storybook. CI sets OPENBOT_STORYBOOK_CHECK=true to skip automatic prop documentation during its build check.
bun run dev:automation Drive the running dev app over CDP: instances, pages, snapshot, screenshot, click/type by accessible role. `--page=<target-id
bun run dev:cpu Measure idle CPU on the running dev app, per process kind and per page. --duration=<ms> (default 60000), --interval=<ms> (default 5000), --label=<name>, --out=<name>.json (always under .openbot-build/dev-automation/cpu/, and refused if it would leave that directory or pass through a symbolic link) and --compare=<file> for a before/after delta. Read-only. Take a baseline before a change and a second run after it: only the difference between two runs on the same machine is a result, because a dev build carries the Vite server and the source maps as well.
bun run dev:memory Measure the running dev app's memory once: resident memory per process kind (main, renderer, GPU, provider CLIs and their MCP servers), with the dev tooling kept out of the app total, plus JS heap and DOM counters per page. --label=<name>, --out=<name>.json (always under .openbot-build/dev-automation/memory/) and `--heap-snapshot=<target-id
bun run dev:bench Run repeatable RAM and CPU scenarios on the built app (bun run build first). Each run seeds a bench profile of its own, starts the built app, samples the process tree every second (resident memory, macOS physical footprint and CPU per process kind, provider memory per CLI) with the main-process and page heaps, drives the scenario, and reads a settled state after garbage collection. `--scenario=<id
bun run check Run Biome, both typechecks, offline tests, the browser smoke test, and the production build.
bun run typecheck Check all 15 projects in parallel with a separate incremental cache for each project in this worktree.
bun run knip:check Find unused files, exports, and types, unused or unlisted dependencies, and unresolved imports in all workspaces. CI runs it.
bun run check:ui Check the renderer against the design system: shared primitives, Kobalte and Lucide confined to @openbot/ui, palette tokens instead of colour, size, radius and transition literals. Checks renderer and shared UI source.
bun run check:assets Fail when a tracked image or video file is outside the product asset directories. Pull request screenshots go in the pull request body.
bun run check:doc-links Fail when a link in a tracked Markdown file names a Markdown file that does not exist, or an anchor that the file does not have.
bun run verify:preload After bun run build, run the built preload with a fake Electron. Fail when it loads a module that a sandboxed preload cannot load, uses import(), or exposes a method that IPC_ENDPOINTS does not name.
bun run types:ratchet Hold each TypeScript option in tools/typescript/type-baseline.json to its error count per file in every project that extends tsconfig.base.json. A new error fails. Add --write after a fix to lower the baseline, or --add=<option> to start an option at its current counts.
bun run i18n:check Check the translation catalogs: key prefixes, placeholders, plural forms, ambiguous source text, and unused keys. --fix puts translated keys in the English order. --json writes .openbot-build/i18n-report.json. See docs/i18n.md.
bun run test:backend Run backend tests only.
bun run test:changed Run, on one worker, only the desktop and mobile test files that import a file changed since origin/main, including staged, unstaged and untracked files. It stops with an error when origin/main is missing. A change to a vitest config, a setup file or package.json selects no test. See docs/development-checks.md.
bun run test:related -- <source>... Run, on one worker, only the test files that import the named source files.
bun run test:browser-agent-session Check that an agent with its own browser session, and the agents of a named browser profile, keep their cookies and storage apart, across popups, a restart, a deleted profile, and a clear.
bun run test:browser-profile-agents Check that the shared profile, an agent's own session, a named profile, and the delete of a named profile change the stored browser profile of an agent, and that the choice stays after a restart.
bun run test:browser Run the complete local embedded-browser smoke test, including cross-process persistence. Use --scenario=controls, --scenario=tool-boundary, --scenario=evaluation, --scenario=wait-deadlines, or --scenario=popups for one isolated scenario.
bun run test:codex Probe the real CLI handshake and account without starting a paid turn.
bun run test:durations Re-record how long each desktop test file takes. CI splits its shards by this table, so run it when the two shards stop finishing together.
bun run cua-driver:doctor Print, as JSON, which cua-driver binary OpenBot would use for Computer Use, and the driver's own doctor report. Read-only, and it starts no daemon. OPENBOT_CUA_DRIVER_PATH selects a different binary in a checkout; an installed application runs only the driver it was released with.
bun run prepare:cua-driver Write the pinned Computer Use driver to build/cua-driver/<platform>/<arch>, verifying every SHA-256 in native-runtime.lock.json. Name another target with bun scripts/install-cua-driver.ts <platform> <arch>. Every packaging command runs this first.
bun run pin:cua-driver <version> Print a new cuaDriver block for native-runtime.lock.json from a published cua-driver release. Downloads the release assets of all five targets and hashes each shipped file.
bun run package Build an unpacked local application for the architecture of this Mac.
bun run package:verify Build and verify the real app bundle for this Mac, icon, metadata, ASAR, and fuses.
bun run package:win Build an unpacked local Windows x64 application on Windows.
bun run package:win:verify Build and verify the Windows x64 application on Windows.
bun run package:linux Build an unpacked local Linux x64 application on Linux.
bun run package:linux:arm64 Build an unpacked local Linux arm64 application on arm64 Linux.
bun run package:linux:verify Build and verify the Linux x64 application on Linux. Run it under xvfb-run -a without a display.
bun scripts/create-github-app.ts [--org <org>] Create the OpenBot GitHub App from scripts/github-app/manifest.json with the manifest flow. Prints the Client ID for src/main/github-connector-config.ts and writes the app secrets to ~/.config/openbot/github-app-<slug>.json (mode 0600). Enable Device Flow in the app settings after the run.
bun run release:preflight Verify version, Git state, and GitHub release secrets before tagging.
bun run dist:mac Build unsigned local DMG and ZIP update artifacts for this Mac.
bun run dist:win Build an unsigned Windows x64 NSIS installer on Windows.
bun run dist:linux Build an unsigned Linux x64 AppImage on Linux.
bun run dist:linux:arm64 Build an unsigned Linux arm64 AppImage on arm64 Linux.
bun run release:patch Create the next patch version commit and tag.
bun run mobile:release:patch Move the iPhone app notes from apps/mobile/changelog.d into apps/mobile/CHANGELOG.md and set the next patch version in app.json. Also mobile:release:minor and mobile:release:major.
`bun run mobile:release:published <ios android
bun run test:acp-directories Run three fake ACP agents through the acp provider driver: new, load and resume requests carry the workspace roots as additionalDirectories only when the agent advertises them. Offline; writes .openbot-build/acp-additional-directories-e2e/report.json.
bun run test:custom-agents Run two fake ACP agents through the agent store, Check agent (with its model list) and the acp provider router: equal session ids, restart and resume, switch, and delete. Offline; writes .openbot-build/custom-acp-agent-e2e/report.json.
bun run test:mcp-tool-consent Run the real Codex app-server with a fake model, a real MCP server and the real attention registry: tool consent at Ask first and Full access, Always allow and a restart, refusals, and the requests that stay with the user (forms, sign-in, look-alikes). Needs a Codex CLI; offline; writes .openbot-build/mcp-tool-consent-e2e/report.json.
bun run test:ui-blocks Run the real attention registry and Team API codecs on ask_ui blocks: answers from the owner, an admin, a member and a released client, the member refusal for privileged actions, a secret form value that is never stored, skip and expiry, and the ui-blocks-v1 wire on protocols 6 and 7. Offline; writes .openbot-build/ui-blocks-e2e/report.json.
bun run test:filesystem Online/manual: run real full-access Codex and Claude filesystem turns across private and shared workspaces.
bun run test:imagegen Online/manual: run a real full-access image-generation turn.
bun run test:workspace-only Online/manual: run real Workspace only Codex, Claude, Grok and OpenCode turns that try to write outside; writes a JSON report per provider to .openbot-build/workspace-only-smoke/. Add --provider <id> for one, and --model <id> to choose its model.
bun run test:provider-detection Run local detection, Load models and endpoint Edit against fake OpenAI-compatible servers on this computer: no key in a scan, no redirect, the stored key only to its own origin. Offline; writes .openbot-build/provider-detection-e2e/report.json.
bun run test:storage-live Online/manual: verify isolated Codex and Claude turns in a temporary SQLite database.

Publishing never creates a second OpenBot instance. The host keeps its Team API on loopback. A hidden, sandboxed Electron page connects it to invited clients through WebRTC. Signal carries only connection setup messages. Team data uses direct DataChannels when possible and the project coturn service when direct ICE fails. Cloudflare stores accounts, configuration, memberships, invitations, logical session records, and public assets. It does not carry chats, files, commands, or remote desktop media.

The development runner advertises both Mobile Connect and its Signal service on the preferred private LAN interface. Restart the runner after changing networks so newly generated QR codes contain the current address.

Production mobile analytics setup and required OpenPanel credentials are documented in OpenBot Mobile.

mobile:go:tunnel exposes only the Expo development server. It does not expose the local account API, Signal, or TURN. A phone on 5G cannot use the default LAN addresses. For a test across networks, use a VPN that connects both devices, or provide HTTPS and WSS endpoints that forward to this dev stack's account API and Signal ports. Set OPENBOT_MOBILE_AUTH_API_URL to the reachable account API origin and REMOTE_SIGNAL_URL to the reachable Signal URL, including /v1/signal, before starting bun run dev. Use the ports reported by bun run dev:status; they can differ between worktrees. If direct WebRTC cannot connect, TURN_HOST must name a reachable coturn service and TURN_SHARED_SECRET must match that service. An HTTP tunnel cannot forward TURN traffic. Generate and scan a new Mobile Connect code after changing the account API address; an existing mobile session retains its original address.

Mobile sign-out removes the local login even when the account API is unavailable. The app keeps only the credential in secure storage for revocation retries at startup, on return to the foreground, and on the next connection attempt. Remote revocation completes when the account API is reachable.

For manual team testing, bun run dev:test-client starts a complete two-client harness. The second client uses the OpenBot Dev Test Client wt-<hash> profile of this worktree (OpenBot Dev Test Client with --shared) and renderer port 5174. dev:reset removes the shared one and the legacy OpenBot Dev Host profile. It does not remove the downloaded provider CLIs, which the whole computer shares. Press Ctrl+C in the runner terminal to stop only the processes started by that runner, or run bun run dev:stop from the worktree once that terminal is gone. Never stop a dev stack with pkill -f electron or pkill -f bun: on a machine running several worktrees those kill the other checkouts' work mid-write, which is what dev:status and dev:stop exist to make unnecessary.

Set OPENBOT_DEV_ICE_TRANSPORT_POLICY=relay before this command to force Team API traffic through coturn. This test option works only with the development renderer. Production always starts with all.

The normal check command is offline and uses a fake App Server. Manual smoke scripts may use the signed-in subscription and must not run in CI.

Local agents run with the providers' unrestricted execution modes. Each agent starts in its own persistent ~/OpenBot/Agents/<agent-id> workspace and also receives ~/OpenBot/Shared; routine command and filesystem work in both locations runs without OpenBot adding another permission boundary. Because these modes are intentionally unrestricted, they also permit host access outside those directories when the provider and operating system allow it.

macOS remote desktop permissions

For each macOS account, log in to its GUI session and open Server Settings → Remote desktop access. Select Check again to read Sunshine's Screen Recording and Accessibility permissions, display availability, and GUI session status. The panel names the Mac and the account that runs Sunshine. Grant permissions in that account, including when the account was created with the tenant setup script.

After you publish a server on a Mac, an optional Set up remote desktop prompt opens this panel. Select Later to keep using the published server without remote desktop setup.

Use the permission buttons to open System Settings → Privacy & Security on the host. If Sunshine is missing from a list, select Show Sunshine in Finder and add the bundled Sunshine.app with the + button. macOS can attribute access to the application that starts Sunshine; enable the application named by the system prompt. Return to OpenBot to check again. If a restart is required, end remote sessions first. A check never restarts an active session.

Select Test on this Mac for a local test. If native checks are unavailable, it tests video only and disables viewer input. After the checks pass, it can test mouse and keyboard too. Select Test remote desktop from another computer for a remote test. The test requires an otherwise unused remote desktop host. It opens a temporary host panel, keeps remote input inside that panel, and asks you to click a target and type a four-digit code. Confirm that the picture is visible, then select Finish test. Local input does not pass the mouse or keyboard test. The panel expires after two minutes. Older hosts or native runtimes require an update before these checks are available.

The native runtime source change invalidates prior artifact pins. The Remote desktop runtime CI workflow builds and tests the new source, then publishes and pins verified artifacts through its existing release flow. Do not reuse old artifact hashes with the new source digest.

Electron main
├── local Codex App Server process over stdio JSONL
├── local Claude Agent SDK session over stream JSON
├── SQLite command log and read projections
├── secure typed IPC handlers
└── sandboxed WebContentsView browser host
    ↕ typed preload bridge
SolidJS renderer

Cloudflare Workers
└── TanStack Start + Solid 2 account API
    ├── D1 accounts, email challenges, hashed sessions, and team tunnels
    └── R2 account avatars
  • src/main owns the Electron lifecycle, window security, local protocol, and IPC registration.
  • src/backend owns provider adapters, persistence, message scheduling, transfers, and the browser host.
  • src/preload exposes only the typed window.openbot API.
  • src/renderer contains the SolidJS interface.
  • apps/auth-api contains the TanStack Start account API, one-time email codes, rate limits, and D1 migrations. It also serves the public site: the landing page, /news, /guides, and the plugin pages at /plugins and /plugins/<slug>.
  • apps/status contains the public status page at status.openbot.run, the script that the status-page workflow runs to check the services, and the script that sends the status webhooks of the team. GitHub hosts it, so it stays up when Cloudflare does not.
  • packages/contracts contains process-boundary contracts, shared limits, and pure validation.
  • packages/i18n contains the interface text in English, French, Japanese, Brazilian Portuguese and Turkish for desktop, web and mobile. See docs/i18n.md to add text or a language.

See docs/ARCHITECTURE.md for dependency direction, state ownership, and rules for new modules.

Attach MP3 audio and MOV video through the file picker or drag and drop. The limits are 100 MB per file, 250 MB per message, and 10 files per message. OpenBot gives the agent the original file; it does not play, decode, transcribe, or validate the recording during import. Damaged recordings can be attached for inspection. Analysis depends on the tools available to the agent. For other audio or video formats, export as MP3 or MOV, or attach a text transcript. Remote hosts must advertise the media-attachments capability; update the host if this feature is unavailable.

ZIP archives use the same limits. OpenBot does not extract or inspect an archive: the agent gets the original file and extracts it with its own tools. An agent sends a ZIP archive back with openbot.attach_files_to_response, and the user downloads it from the chat. Open shows a ZIP archive in the file manager instead of opening it. Remote hosts must advertise the zip-attachments capability.

Local data and network boundaries

  • ~/OpenBot/Agents/<agent-id> — one working directory per agent. A profile written before the bot-to-agent rename holds them under ~/OpenBot/Bots; the app moves them on first launch, and a workspace whose move could not run stays readable where it is.
  • ~/OpenBot/Shared — files intentionally shared between agents.
  • ~/OpenBot/Shared/Transfers — managed message snapshots and generated files. Each transfer has an .openbot-transfer.json manifest with ownership, recipients, size, and SHA-256 metadata.
  • ~/OpenBot/Downloads — embedded-browser downloads.
  • Electron userData/openbot.db — the canonical OpenBot event log and projections for agents, conversations, provider session bindings, queues, reactions, and attachment indexes.
  • Electron userData/legacy-backup-v1 — unchanged copies of imported bots.json and mailbox.json files, when these files existed before the SQLite migration.
  • ~/Library/Application Support/OpenBot/provider-runtimes — the provider CLIs OpenBot downloads and pins. One store for the whole computer, outside any one profile, so every development profile and the packaged app read the same download. --user-data-dir keeps the store in that directory instead, so an explicitly named profile stays self-contained.
  • ~/.codex — login and thread history managed exclusively by Codex CLI.
  • ~/.claude — login and session history managed exclusively by Claude CLI.
  • ~/.grok — login and session history managed exclusively by Grok CLI.
  • ~/.gemini (or $GEMINI_HOME) — login and session history managed exclusively by the Antigravity ACP server that Gemini uses.
  • ~/.cursor — login and session history managed exclusively by the Cursor CLI. A confined Cursor process keeps its settings in ~/.cursor/openbot-confined, so it never changes yours.
  • ~/.cline (or $CLINE_DIR) — login and session history managed exclusively by the Cline CLI.

Deleting an agent removes its workspace, owned generated attachments, and deliveries addressed only to that agent. A transfer remains when another agent still uses the same message.

OpenBot keeps one stable local conversation when an agent changes between Codex, Grok, and Claude. Native provider session identifiers stay private and are used only to resume provider runtime state.

The Electron renderer is never exposed as a public website. It communicates with local CLI processes over stdio. When the owner publishes OpenBot, its authenticated Team API stays on localhost. WebRTC protocol v3 carries RPC, events, and binary files to desktop and mobile clients. Expo Go hosts the mobile RTCPeerConnection in a hidden Expo DOM component, so mobile uses the same encrypted transport without a custom native development build. The account flow connects to the configured HTTPS Cloudflare API. The client stores only an encrypted OpenBot session token. One-time codes expire after 10 minutes and are stored only as hashes. A daily maintenance task removes expired or consumed authentication records from D1. The embedded browser uses a separate sandboxed Electron session and cannot access window.openbot or managed local attachments.

To run your own account service, Signal and TURN, see Self-hosted remote access.

To trigger routines from external services, see Webhooks. Public webhook requests require the host to be online.

Read SECURITY.md before reporting a vulnerability. Do not put credentials, private files, conversation contents, or sensitive diagnostics in a public issue.

Full local access is an explicit current product decision, not a security boundary. Reports are especially useful when remote content can reach Electron privileges, managed attachment paths can escape their roots, IPC sender validation can be bypassed, or an agent can act outside the access described above.

Releases are tag-driven. bun run release:patch, release:minor, or release:major prepares the version and changelog. After review, commit, preflight, and tag the release; pushing the tag builds a signed and notarized macOS ARM64 and x64 release, a signed Windows x64 release, and unsigned Linux x64 and arm64 AppImages in GitHub Actions. After the release is published, the workflow pushes the Docker image to ghcr.io/nightly-labs/openbot. Installed builds check GitHub Releases for updates and expose download/restart controls in the account popover. Release signing secrets and the complete procedure are documented in docs/RELEASING.md.

See CONTRIBUTING.md. Before we merge a contribution, each author from outside the organization signs the Contributor Assignment Agreement, which assigns its copyright to Synthetify Labs. Community behavior is governed by the Code of Conduct.

Copyright 2026 Synthetify Labs spółka z ograniczoną odpowiedzialnością.

Licensed under the PolyForm Noncommercial License 1.0.0. You may use, modify, and distribute the code for permitted noncommercial purposes. Commercial use requires a separate license from the copyright owner. For a commercial license, contact licenses@openbot.run. Versions up to and including 0.1.11 remain available under Apache-2.0. See NOTICE for attribution and third-party notices.

OpenBot is an independent source-available project and is not affiliated with, endorsed by, or sponsored by OpenAI. OpenAI, ChatGPT, and Codex are used only to describe compatibility with their respective products and services.

For one native Standard user per tenant, install the normal OpenBot DMG and the optional OpenBot-Host-<VERSION>-arm64.pkg from the same release. The Host package provides sudo openbot-host setup --create-user client-acme --create-user client-bravo and sudo openbot-host verify. sudo openbot-host status [--json] and sudo openbot-host watch show the update phase, the staged version, and each tenant's work state. No Git checkout, Bun, or compilation is required on the host. Normal desktop users need only the DMG. See the host deployment guide for existing-user enrollment, password handling, package upgrades, and required target-host checks.