Octant is a local-first macOS workspace for Chat, Work, and Code across many AI providers. One authoritative local server owns your Projects, threads, memory, approvals, and history; the desktop app (and optionally an authenticated browser or remote client) is a renderer over it. Octant runs the providers you already have — local coding CLIs, agent SDKs, Ollama, or any OpenAI- or Anthropic-compatible HTTP endpoint — and no core capability requires a specific vendor or an Octant-operated cloud service.
- Chat — conversations in virtual Projects with scoped memory and no implicit filesystem or shell authority.
- Work — knowledge work confined to one user-approved folder: research with citations, artifacts, previews, and Goals.
- Code — engineering confined to one user-approved folder: approval-gated access, managed worktrees, terminals, an editor, tests, and a thread board.
Modes are enforced on the server, not toggled in the renderer. Work never silently becomes Code; promotion to a linked Code thread requires explicit approval.
- Durable append-only event journal in SQLite; every projection is rebuildable by replay, and recovery and backup go through a verified boundary.
- Provider-neutral runtime: capabilities are reported honestly per provider and mode, and unsupported operations fail closed instead of pretending.
- Provider handoff mid-thread: change provider or model for the next turn with a recorded provenance trail.
- Context manifests and budgets with per-provider limits.
- Shared, Project-scoped memory across threads.
- Chat turn editing, thread branching, and Markdown export that states what it could not include.
- Managed subagents that run as in-process provider sessions with narrowed authority.
- Native harness for API-key and local models: Octant's own tools, authority
checks, and journal around any OpenAI- or Anthropic-compatible endpoint, with
model slots so a strong model can lead and review while cheaper ones read and
implement, an advisor that can redirect or pause a run, and the same session
view in the app, on the phone, and in
octant agent. - Approval-gated Code threads with a read-only Plan mode, repository test discovery, Git worktrees, PR view, and a runtime-derived Code board.
- Plugin and skill marketplace: packages are quarantined on install, disabled by default, and contribute no context until enabled.
- App-managed browser and computer-use runtime with server-authoritative policy.
- Optional authenticated remote access (LAN or Tailscale) to a single host with
device pairing, key rotation, and revocation, administered from Settings →
Remote access on the host or the
octant listener/octant pair/octant authcommands. - Semantic themes, presets, and font controls.
- Native macOS shell: borderless window, a split-tree workspace with one surface per pane, translucent sidebar, command palette, and slash commands. The right dock holds live thread-owned tools and restores them per window and thread; Environment is a transient disclosure; context usage sits on the composer meter.
Not everything above is equally polished; this is a technical preview. See the
user guide in apps/docs for the current honest boundaries of each area.
Local CLIs and SDKs (Octant discovers installed runtimes and registers them disabled until you enable them):
- Codex CLI
- Claude Code (Claude Agent SDK)
- OpenCode CLI
- Kimi Code CLI
- Devin ACP
- Kilo ACP
- Pi RPC
- Oh My Pi (discovery only: Octant lists its models but cannot start turns on it yet, so Settings reports it as unavailable and no picker offers it)
- Mistral Vibe ACP
- Grok Build ACP
- Goose ACP
- GLM Agent ACP
- Gemini CLI ACP
- GitHub Copilot ACP
- Cline ACP
- Qwen Code ACP
- Ollama (local HTTP)
Direct API endpoints:
- OpenAI-compatible HTTP (
responsesorchat-completions) - Anthropic-compatible HTTP (
messages) - Azure AI Foundry (OpenAI-compatible v1 profile, API key)
Credentials are stored in the macOS Keychain (the Linux dogfood build uses the desktop's Secret Service), resolved by the desktop broker, and never written to the event journal or returned to the renderer.
Octant is an Apple Silicon technical preview. Releases are signed with a Developer ID, notarized, and update themselves — you choose when an update applies, and it never replaces a running app or interrupts work in flight. It ships no signed Intel, Windows, or Linux desktop builds; a Linux x64 AppImage can be built locally as an unsigned dogfood artifact (see below). An AppImage launch can update itself from the signed feed when the file is writable. Expect rough edges and breaking changes to local data formats between previews. Remote clients, the Expo mobile app, and packaged native checks are separate evidence gates from the local test suite.
- Apple Silicon Mac (M1 or later) running a recent macOS
- Bun 1.3.x for building from source (
packageManagerinpackage.jsonpins the exact version) - Node 26 only for the optional Node SQLite portability smoke
- x64 Linux host (Ubuntu is the dogfood target)
- Bun 1.3.x for building from source
- Bubblewrap and a live Secret Service session for Work/Code on the host
- Node 26 only for the optional Node SQLite portability smoke
There are no prebuilt binaries yet. Build the app from source:
git clone https://github.com/Ogard-Labs/octant.git
cd octant
bun install --frozen-lockfile
bun run build
bun run package:desktopPackaging produces out/Octant.app. A build you package yourself is unsigned,
so macOS Gatekeeper will warn on first launch; right-click the app and choose
Open, or allow it under System Settings > Privacy & Security. An unsigned build
also does not update itself — the updater installs a replacement only when it
satisfies the running app's code signature. Signed releases carry that
signature and update in place.
Packaging uses the same release version in the native bundle and Electron runtime manifest, so the updater and What’s new identify the build on disk consistently.
Local data lives in ~/Library/Application Support/Octant/ (override with
OCTANT_DATA_DIR).
On x64 Linux the same command produces
out/Octant-<version>-linux-x64.AppImage (plus out/Octant-linux-x64/ for
inspection). That AppImage is not code-signed. When you launch it, Octant
checks the signed <ring>/linux-x64.json feed, verifies the signature and
hash before writing, replaces the image in place, and relaunches. A package,
an unpacked archive, or a location Octant cannot write is refused, and the
reason is shown in Settings. Mark the AppImage executable and launch it
directly. AppRun
keeps the Chromium sandbox when unprivileged user namespaces work, and only
adds --no-sandbox when that probe fails (AppImage mounts are nosuid).
Ubuntu 24.04+ AppArmor may still restrict Chromium userns; a dedicated profile
is out of scope for this dogfood path.
Local data uses the XDG layout (~/.local/share/octant/ by default; override
with OCTANT_DATA_DIR).
On first run, the welcome surface offers an optional name and workspace choices. Skip setup is available from the first step. The readiness view reports provider, Project, and a mode-valid default model separately. One action starts a real thread when those facts are true; a missing prerequisite opens its exact setup surface and returns to the same draft.
bun install --frozen-lockfile
bun run devbun run dev starts the Vite renderer for apps/web with hot reload and
launches Electron against it. Electron attaches to the canonical host or starts
it from source when absent: renderer edits hot-reload, server edits take effect
on the next app relaunch when Electron started the host — an already-running
host that Electron attached to must be restarted separately — and
apps/desktop/src edits are rebuilt automatically
the next time you start bun run dev. The Canvas preview page an agent's
preview screenshots is built the same way, whenever apps/web or the contracts,
domain or theme packages are newer than it, so previews return a picture on a development host too.
Computer use requires the packaged macOS Octant application with its own bundle
identity and permissions. The source-run Electron shell is not that identity and
is refused by the native driver startup check. bun run computer-use:prepare
downloads and verifies the pinned CuaDriver for local builds; desktop packaging
includes this step automatically. In the packaged app, select Computer from a
composer's @ picker and use Settings → Computer use for permissions and
automatic driver updates.
To run the host without Electron and attach a browser client:
bun --cwd packages/cli src/bin.ts server run # http://127.0.0.1:13773/Open http://127.0.0.1:13773/ directly, or run
bun --cwd packages/cli src/bin.ts web as a convenience. Electron and every
local browser attach to this same canonical Machine, data store, Projects, and
threads.
For browser UI development with hot reload, use the development launcher instead of pairing a hand-started server with Vite:
bun --cwd packages/cli src/bin.ts web --dev --no-openIt starts the Vite renderer and attaches it to the canonical host, starting that
host from source when none is running; a running host that does not admit the
renderer's origin is refused with an explanation. It also builds the Canvas
preview page when apps/web or the contracts, domain or theme packages are
newer than it and points the host it starts at apps/web/dist, so an agent's
preview returns a picture. A running host it attaches to keeps the environment
it started with, so one started without the web build is named in a warning
and must be restarted. Renderer
mode never selects another data directory: browser QA, Electron, and Vite show
the same Projects and threads. Tests that need an isolated store must set an
explicit OCTANT_DATA_DIR.
Common checks:
| Command | Purpose |
|---|---|
bun run fmt |
Format with oxfmt (fmt:check to verify) |
bun run lint |
oxlint |
bun run typecheck |
Typecheck all workspaces |
bun run test |
Run workspace tests (Vitest) |
bun run build |
Build all buildable workspaces |
bun run verify |
Full local chain: wiring, decisions, format, lint, types, test, build |
Credentialed provider smokes, packaged app smokes, and browser QA are opt-in
scripts (bun run smoke:*) and are not part of verify.
| Path | Responsibility |
|---|---|
apps/desktop |
Electron lifecycle, native windows, Keychain broker, helpers, packaging |
apps/server |
Authoritative API, event journal, providers, tools, Projects, recovery |
apps/web |
Shared React renderer for desktop and authenticated browser clients |
apps/mobile |
Expo remote-control client (device distribution is a separate gate) |
apps/docs |
VitePress user guide, independently deployable |
packages/contracts |
Versioned schemas, commands, events, and RPC contracts (schema-only) |
packages/domain |
Pure policy and state transitions |
packages/provider-sdk |
Provider driver interface, normalized runtime events, discovery, conformance |
packages/client-runtime |
Authenticated, prioritized transport, reconnect, and replay synchronization |
packages/host-runtime |
Host identity, paths, ownership, service and artifact lifecycle |
packages/plugin-host |
Extension and skill packages, trust, and activation policy |
packages/theme |
Semantic theme schema and projections |
packages/cli |
octant server and browser launcher |
scripts |
Dev loop, packaging, smokes, and repository checks |
Dependencies point inward: apps consume packages; contracts and domain never import apps; provider-specific payloads stop at adapters.
- Architecture
- Current design and maintenance
- Workspace behavior
- Visual design system
- Historical decision rationale
- User guide (VitePress;
bun run --cwd apps/docs dev) - Contributing
- Security policy
- Code of conduct
MIT. See LICENSE.