All releases
v0.1.5·24th July 2026

Tempest v0.1.5

Tempest v0.1.5

The Isolation release. An agent you have to supervise line by line is not saving you much. This release is about the boundaries that let you stop watching: its own database, its own sandbox, its own quotas — and a config file the repo carries so those boundaries travel with the code.

What's in this release

Database Branches

Each agent session can get its own isolated clone of your Postgres. Migrations, seed data, and schema changes happen in the branch — the shared database is never touched.

A new dbiso crate (built on bollard) snapshots your Postgres into a base Docker image, then cuts a fresh branch container per session and injects DATABASE_URL, PGHOST, and PGPORT into the PTY environment. The agent connects to its clone without knowing anything changed.

StrategyWhat it captures
pgdumpFull logical dump — Supabase-compatible
basebackupPhysical base backup
schema-onlyStructure without rows

Base images are named per project, so multiple projects can hold snapshots side by side. The whole subsystem is a silent no-op when Docker is unavailable or no base image exists — nothing breaks, sessions just open against your real database as before.

Isolation is toggled per project in Project Settings → Database, not globally. Different projects, different risk.

Project Settings — Now Enforced

The Project Settings panel previously only had teeth for database isolation. Every other section was decorative: sessions spawned against a hardcoded allow-list regardless of what the panel said. Now every session reads the project's settings blob.

SectionGoverns
SandboxOff / Monitor / Enforce posture for the session
NetworkPermissive or restrictive policy, allow-list and block-list of hosts
FilesystemRead & Write and Read Only path lists
PermissionsWhether the skip-permissions bypass may be used
ResourcesMemory, process count, disk write, and CPU weight quotas
AgentsWhich agent types may launch in this project
DatabasePer-session isolated database branch

Plain terminals are governed identically to agents. A shell reaches the network either way, so treating it as trusted was a hole rather than a convenience.

Launch policy checked in Rust. Non-permitted agents and blocked skip-permission flags are refused before the PTY opens, with the reason surfaced in the UI. Filtering the new-session menu is presentation; the refusal is the enforcement.

Sandbox fixes underneath. The host matcher was replaced with one where a block-list beats an allow-list, hosts are normalized for ports and IPv6 brackets, and suffix impersonation is fixed — evil.com no longer matches an allow of api.anthropic.com merely by ending with it. Windows now starts the CONNECT proxy, injects http_proxy/NO_PROXY, and maps CPU weight onto Job Object rate control. Proxy denials return 403 with the blocked host echoed instead of 407, which had been making curl prompt for proxy credentials.

tempest.yml — Config That Ships With The Repo

A project can now commit a tempest.yml at its root, and the conventions travel with the code:

instructions: |
  This service talks to Stripe. Never write to the live keys.

preview:
  port: 5173

env:
  RAILS_ENV: development

sandbox:
  mode: enforce
network:
  policy: restrictive
  allowHosts: ["api.anthropic.com"]
  • instructions becomes the Chat system prompt for the project — the file wins over whatever this machine had saved.
  • preview.port opens Live Preview straight at your dev server instead of the port picker.
  • env is injected into every agent session's environment.
  • Security fields merge over your panel settings.

The file may only tighten. A checked-in config arrives with code you may not have written, so security fields merge in the tightening direction only: a stricter sandbox mode wins, block-lists union, allow-lists intersect, quotas take the lower value, and the skip-permissions bypass can be revoked but never granted. A repo can lock itself down further than your panel allows. It can never loosen it.

env cannot become code execution. Loader variables (PATH, NODE_OPTIONS, LD_PRELOAD, DYLD_INSERT_LIBRARIES, PYTHONSTARTUP, BASH_ENV, and the rest) are stripped, as are the DB-isolation variables — a repo must not be able to point an isolated session at some other database. Rejected keys are reported in the console rather than silently dropped.

The clamp is applied for display and enforcement but never persisted, so editing or deleting the file takes effect on the next session with nothing stuck in your settings.

A malformed tempest.yml degrades to "no config" plus a warning. A typo must not stop a terminal from opening.

SQLite Persistence

All persistence moved from runtime-state.json and localStorage to a single SQLite database (tempest.db).

Sessions gained real UUID identity with project, branch, and parent foreign keys, replacing the composite path-string keys that had been standing in for identity. Projects, branches, sessions, recents, tabs, and chat history now live in relational tables; app-global preferences live in an app_state key/value table. Each store keeps a synchronous in-memory mirror hydrated at startup with async write-through, so reads stay instant.

BYOK API keys and the GitHub PR token deliberately stay in localStorage — credentials belong in an OS keychain, not in an application database, and that is the next move for them.

Right Sidebar — Bottom Panel

A tabbed panel now sits at the bottom of the right sidebar.

TabWhat
DB ClonesLive view of the database branches for this project
RunDetected package.json scripts plus custom commands saved per project
TerminalStreams output from whatever the Run tab started, with a stop button

Scripts are read from the project's package.json automatically. Custom commands are stored per project, so the ones you actually use are one click away in the project that uses them.

In-App Updates

Releases have been signing update artifacts and publishing latest.json since the release workflow landed — but no client ever read them. The updater is now wired up: Tempest checks on startup and once every 24 hours.

The notice takes whichever surface is already there:

  • On Overview, where there is no footer, one drops in over 550 ms carrying the line on the left, Update and dismiss on the right. retracts it and the canvas glides down into the space.
  • Inside a session, the status bar becomes a one-row viewport over a two-row track and rotates the update line in alongside Indexed and Isolated every 7 s. Nothing is displaced, and the bar never changes height.

Two targets, deliberately. The sentence opens the release notes; only the word Update starts the upgrade. From a workspace, that word opens a confirmation naming the sessions that will close and warning separately about agents mid-turn — those turns are the only work that cannot be resumed afterwards. Overview installs directly, since nothing is running there to interrupt. Dismissing hides the notice until the next 24-hour check.

Performance — The UI Freezes Are Gone

Tauri v2 runs a plain #[tauri::command] fn on the main event loop; only async fn gets a worker thread. 68 of 80 commands were synchronous, so every git subprocess, SQLite query, and directory scan froze the UI for its full duration.

Worst offenders, both now fixed:

  • Branch deletion hanggit_delete_branch with deleteRemote runs git push origin --delete, putting a network round-trip on the UI thread. An unbounded freeze whenever auth was slow.
  • Workspace deleteclose_and_remove_worktree kills the PTY, waits in a 40×25 ms loop, then retries worktree removal 6 times with 500 ms sleeps: roughly 4 seconds of deliberate main-thread sleeping per delete.

The 68 blocking commands are now marked (async). Attribute-only — no command logic changed.

Startup got three cuts as well: project .tempest/ scanning moved from a sequential await loop to one Promise.all; db_load ran three separate times with chat serialized behind the rest and now shares one in-flight snapshot across all six stores; and applyTheme moved from a passive useEffect (after first paint) to useLayoutEffect.

The Diff pane's "all files" view renders every hunk of every changed file — content-visibility: auto now lets off-screen blocks skip layout and paint entirely.

Global MCP Configs

Agents that read MCP servers from a global config file can now be wired to Atlas in one click, from Settings → Token Intelligence:

AgentWrites to
Goose~/.config/goose/profiles.yaml
Codex CLI~/.codex/config.toml

Each row checks whether the config is already present and shows its state, so a second click is never needed.

Fixes and Polish

Tooltip stacking — tooltips moved to a portal with viewport clamping, so they no longer get trapped under adjacent stacking contexts or clipped at window edges.

New-session menu clipping — the menu now clamps horizontally and flips above its anchor when there is no room below; the nine-agent submenu scrolls within whatever space it has.

Themes renamed — the origin-dark and origin-light theme folders are now tempest-dark and tempest-light. Documentation updated to match.

Global settings — the Database tab is gone (isolation is per project now), the modal is wider at 800×580, and the About section shows the correct version.

Filesystem "Always Denied" list removed — with the allow-lists exhaustive under Enforce, a separate deny-list was UI that governed nothing.

Platform Support

PlatformStatus
Windows 11 (x64)Supported. Pre-built binary available. MSI and NSIS installers.
macOSSupported
LinuxSupported

Windows requires WebView2 (bundled automatically when necessary).

Database Branches additionally require Docker. Without it, the feature stays dormant and everything else works normally.

What's next

In priority order.

1. Worktree setup and teardown. A fresh git worktree has no node_modules and none of your ignored files — no .env, no local config. Right now you fix that by hand every time. tempest.yml gains setup and teardown: setup runs once after the worktree is created, teardown runs before it is removed. Install dependencies, copy secrets across from the source checkout, migrate a database, and drop it again on the way out.

2. Live quota. Your agent CLIs already know how close you are to your rate limits — your Claude subscription window, your Codex quota — and none of that is visible while you work. A dynamic island in the title bar will surface it: quiet when you have room, expanding as you approach a limit, showing which window is filling and when it resets. Read using the credentials the CLIs already hold on your machine. Tempest never proxies a model call and never sees a token of yours.

3. Automations. Workflows you build as a visual graph, running your CLI tools underneath. They trigger and execute like background agents — you draw the flow once, and it runs without you sitting in front of it. Graphs, runs, and history live in the same SQLite database everything else moved to this release.

4. Service proxy. Two worktrees both running a dev server both want port 3000. Each workspace's services will get an allocated port and a stable hostname, so parallel branches stop colliding and every one of them stays reachable at a URL that says which branch it is.