Changelog
Release history for Watchfire.
[3.0.0] Blaze
Added
- GitHub Copilot CLI backend — Copilot joins Claude Code, OpenAI Codex, opencode, and Gemini CLI as a fifth first-class backend, selectable per project or per task like any other agent. Sessions run in yolo mode (
--allow-all); the Watchfire system prompt is delivered viaAGENTS.mdin a per-sessionCOPILOT_HOME, while the user's real~/.copilot/{config.json,mcp-config.json,session-store.db}are symlinked in so existing GitHub login, MCP config, and session history are reused. Transcripts render in the same User/Assistant format as the other backends
Fixed
watchfire updateacross filesystems on Linux (#25) — updating from/tmp(oftentmpfson Fedora/Ubuntu) into~/.local/binused to fail withEXDEV: invalid cross-device link. The updater now stages the download inside the install directory itself, so the final atomic rename is always same-filesystem. A belt-and-suspenders fallback copies, fsyncs, and renames if a caller ever stages elsewhere- Task list rotation with many tasks (#28) — projects with mixed-status tasks (e.g. 16 done + 31 ready) could render the task list rotated (
0017…0047then wrapping to0001…0016). Sorting is now canonical everywhere: the task manager returns tasks strictly descending bytask_number, and CLI, TUI, and GUI all rely on that order without re-sorting - GUI prompted to update the CLI on every launch (#30) — version comparison tripped on trailing whitespace, pre-release suffixes, and ANSI hyperlinks, and on Linux read the wrong binary because the search order put
/usr/local/binahead of~/.local/bin. Version parsing is now semver-aware, ANSI-stripping is broader (CSI + OSC + other ESC), and the search order matches the install target with a PATH fallback for rpm/deb/Linuxbrew installs - Newly-installed agents invisible in GUI/TUI pickers (#29) — installing Codex (or any agent) while Watchfire was running used to hide it from the agent picker until
project.yamlwas hand-edited. The backend registry is now the sole source of truth for pickers: every registered backend always appears, with a(not installed)suffix when unavailable, so users can select a backend they're mid-installing and get a clear error at spawn time rather than a silent absence. Linux fallback paths also broadened to cover/usr/bin/<name>and~/.npm-global/bin/<name>
Migration
- Existing projects and tasks are unaffected — Copilot is purely additive. To opt a project into Copilot, switch
project.default_agent(or a specific task'sagentfield) tocopilot. A custom Copilot binary path can be set in the global settings UI or by hand in~/.watchfire/settings.yaml
[2.0.1] Spark
Fixed
- Silently discarded work when an agent forgot to commit — if an agent edited files in its worktree and set
status: donewithout runninggit commit, Watchfire saw no diff on the branch, skipped the merge, and deleted the branch and worktree — losing everything the agent did. The merge step now runsgit add -A && git commit --no-verifyinside the worktree as a safety net before the diff check, so uncommitted edits are always captured even when the agent skips the commit step - Codex commit reminder — Codex sessions' per-session
AGENTS.mdnow includes an explicitCRITICAL: Commit before marking a task doneaddendum at the end, making the rule the last thing Codex reads before starting work
[2.0.0] Spark
Watchfire is no longer Claude Code only. Spark introduces a pluggable agent backend and ships first-class support for Claude Code, OpenAI Codex, opencode, and Gemini CLI — selectable per project or per task.
Added
- Pluggable agent backend interface — any CLI coding agent can now be plugged into Watchfire through a single
AgentBackendcontract (executable resolution, command construction, sandbox extras, system-prompt delivery, transcript discovery and formatting). All existing surfaces — chat, task, start-all, wildfire — work against the backend registry unchanged - Four first-class backends — Claude Code, OpenAI Codex, opencode, and Gemini CLI ship out of the box and are interchangeable across every agent mode
- Project default agent —
watchfire initnow asks which agent to use and seedsdefault_agentinproject.yaml - Per-task agent override — each task can pin itself to a specific backend via a new optional
agentfield in its YAML, letting you mix and match agents within a single project (e.g. Claude Code for architecture work, Codex for trivial edits, or re-running a failed task under a different agent without touching project settings). An empty value defers to the project default, keeping existing tasks behaving exactly as before - Agent picker in
watchfire init— the init wizard prompts for the coding agent to use when the global "Ask per project" setting is active - Agent selector in project settings (TUI + GUI) — switch an existing project's agent without re-running
watchfire init. The GUI populates its selector from the daemon via a newSettingsService.ListAgentsRPC, reaching parity with the TUI - Global settings UI for agent paths — new settings overlay registers custom binary paths per backend and picks the global default agent, including an "Ask per project" option that forces
watchfire initto prompt every time - Agent badge on task lists — TUI and GUI render a compact agent badge next to a task's title whenever
task.agentis set and differs from the project default. Tasks that defer to the project default render no badge, keeping the list visually quiet for the common case - Per-session homes for Codex, opencode, and Gemini — each backend runs inside its own per-session home so the Watchfire system prompt stays isolated from your personal configuration, while auth and global settings keep flowing from your real
~/.codex,~/.config/opencode, and~/.gemini - Transcripts for every backend — the log viewer now renders JSONL transcripts for Codex, opencode, and Gemini sessions in the same User/Assistant format as Claude Code. Transcript discovery is owned by each backend, so any future agent automatically gets the full log viewer experience
Changed
- Agent resolution chain — the daemon resolves the backend for each session through a predictable four-step chain:
task.agent→project.default_agent→settings.defaults.default_agent→claude-code. Empty strings defer to the next level, and chat / wildfire-refine / wildfire-generate sessions (which aren't scoped to a single task) skip the task step and start from the project default - Backend-owned transcript discovery — JSONL transcript location and formatting moved out of the agent manager and into each backend's implementation
- Backend-contributed sandbox paths — writable paths, cache patterns, and stripped environment variables are now contributed by each backend instead of being hardcoded, keeping new agents self-contained
Fixed
- Agent auth failure when launched from GUI — macOS GUI apps inherit a minimal environment (
PATH=/usr/bin:/bin:/usr/sbin:/sbin) missing user-installed tool paths like~/.local/bin. This caused Claude Code to misroute API calls through "extra usage" billing instead of the user's subscription, producing spurious "You're out of extra usage" errors in Task, Run All, and Wildfire modes while Chat worked fine. The Electron daemon spawner now resolves the user's full login-shellPATHbefore launchingwatchfired, and the macOS sandbox enrichment adds~/.local/binalongside the usual Homebrew prefixes - GUI blank window on macOS — the production renderer is now served over a custom
app://protocol instead offile://, restoring execution of thecrossoriginES-module entry bundle that Chromium was silently blocking. Globalerror/unhandledrejectionhandlers in the renderer entry now surface any future module-init failure in the window instead of rendering blank
Migration
- Existing projects without
default_agentcontinue to use Claude Code — no action required - Existing tasks without an
agentfield continue to use the project default — no action required - Custom
codex,opencode, andgeminibinary paths can be configured via the new global settings UI or by hand in~/.watchfire/settings.yaml
[1.0.0] Ember
Added
- JSONL transcript logs — session logs now capture Claude Code's structured JSONL transcripts (
~/.claude/projects/) instead of raw PTY scrollback, producing clean readable User/Assistant conversation logs - Transcript auto-discovery — daemon locates Claude Code's transcript files by matching session names and copies them to
~/.watchfire/logs/alongside the existing.logfile
Changed
- Log viewer — TUI and GUI now display formatted conversation transcripts (User/Assistant messages, tool call summaries) instead of garbled terminal output; falls back to PTY scrollback when no transcript is available
Fixed
- Agent restart loop — wildfire/start-all now stops after 3 consecutive restarts of the same task and transitions to chat mode, preventing infinite loops on rate limits, crashes, or auth expiry
- Sandbox blocks ~/Desktop projects (#17) — macOS Seatbelt sandbox no longer denies read access to protected directories (Desktop, Documents, Downloads, etc.) when the project is located inside one of them
- TUI task list scroll with 100+ tasks (#18) — fixed height accounting for section header blank lines and scroll indicators that caused the last few tasks to be invisible
- Install script "tmp_dir: unbound variable" (#20) — moved temp directory variable to global scope so the cleanup trap can access it after function returns
- Desktop always thinks CLI tools are outdated (#21) — version check now strips ANSI escape codes before parsing and logs the actual error when the CLI binary can't be executed
- Can't edit already created tasks in GUI (#23) — task editor no longer resets form contents when background polling refreshes the task list
- Duplicate terminal headers in GUI — Chat panel no longer accumulates repeated Claude Code banners when switching projects or during wildfire phase transitions; terminal is properly cleared before each new subscription, and raw output subscriptions use their own abort map instead of colliding with screen subscriptions
[0.9.0] Ember
Added
- Linux GUI — AppImage and
.debpackages for x64 Linux, built in GitHub Actions onubuntu-latest. Bundled CLI + daemon binaries installed to~/.local/binon first launch withpkexecfallback for admin privileges. - Windows GUI — NSIS installer (
Watchfire-Setup-x.y.z.exe) for x64 Windows, built in GitHub Actions onwindows-latest. Bundled CLI + daemon binaries installed to%LOCALAPPDATA%\Watchfireon first launch with PowerShell elevation fallback. - Cross-platform auto-update for GUI —
electron-updaternow checkslatest-linux.yml(Linux) andlatest.yml(Windows) in addition tolatest-mac.yml(macOS). All three update manifests are generated and uploaded as release artifacts. - Linux GUI CI verification —
gui-build-linuxjob in CI workflow verifies Electron builds onubuntu-lateston every PR.
Changed
- CLI installer is cross-platform —
cli-installer.tsdetects OS and uses platform-appropriate install directories (/usr/local/binon macOS,~/.local/binon Linux,%LOCALAPPDATA%\Watchfireon Windows) with platform-specific privilege elevation (osascript,pkexec, PowerShell) - Window chrome adapts to platform — macOS uses
hiddenInsettitle bar with traffic lights; Linux and Windows use native window frames - electron-builder.yml — added
linux(AppImage + deb) andwin(NSIS) targets with platform-specificextraResourcesfor correct binary bundling (.exeon Windows) - Release workflow — added
build-gui-linuxandbuild-gui-windowsjobs; release job collects AppImage, deb, NSIS exe, and all update YAMLs as assets
[0.8.0] Ember
Fixed
watchfire updatenow works on Windows —stopDaemonForUpdateusesKill()instead ofSIGTERMfindDaemonBinary()handles Windows.exeextension correctly (was producingwatchfire.exed)- Build directory fallback uses platform-appropriate binary name
[0.7.0] Ember
Added
- Linux and Windows binaries in GitHub Releases — release workflow now builds amd64 + arm64 for darwin, linux, and windows (6 platform targets total)
- Cross-platform CI — CI workflow verifies builds on macOS, Linux, and Windows
- Install scripts —
scripts/install.sh(macOS/Linux) andscripts/install.ps1(Windows) for one-line installation from GitHub Releases - No-CGO tray fallback — daemon runs headless when built without CGO (enables Linux/Windows cross-compilation)
[0.6.0] Ember
Added
watchfire chatCLI command — dedicated command to start an interactive chat session with full project context- Cross-platform sandbox abstraction — shared
SandboxPolicywith platform-specific backends: macOS Seatbelt, Linux Landlock (kernel 5.13+) / bubblewrap (fallback) - Landlock sandbox (Linux) — zero-dependency kernel-based sandboxing using
go-landlock, daemon re-invokes itself as helper to apply restrictions before exec - Bubblewrap sandbox (Linux) — namespace-based isolation with read-only root, writable project dir, hidden credential dirs
--sandbox <backend>and--no-sandboxCLI flags onrun,chat,plan,generate,wildfirecommands- Sandbox backend configurable per-project (
project.yaml) and globally (settings.yaml) - System tray icon abstraction for Linux —
setTrayIcon()helper dispatches between macOS template icons and Linux standard icons - Windows build support — CLI and daemon compile and run on Windows (unsandboxed, no POSIX signal dependencies)
- Windows notifications — toast notifications via
beeeplibrary - Platform-aware updater asset names — supports
watchfire-<os>-<arch>[.exe]format
Fixed
- Agent chaining not stopping on auth (401) or rate-limit (429) errors — start-all/wildfire mode now checks for active issues before spawning the next agent
- Linux notification double-close bug —
notify_linux.gonow properly handles file close errors
Changed
- Default sandbox changed from
"sandbox-exec"to"auto"— platform auto-detects best backend - Sandbox setting priority: CLI flag > project setting > global default
[0.5.0] Ember
Added
- Integrated terminal in the GUI — footer bar that expands into a resizable bottom panel with tabbed shell sessions via node-pty, Cmd+` toggle, Nerd Font support
- Version display in system tray menu below "Watchfire Daemon" header for easy version identification
Fixed
- Status indicator dots in sidebar/dashboard now only pulse for projects with an autonomous agent (task, wildfire, start-all) — chat mode no longer triggers pulsing
- Dashboard project card X button overlapping chevron arrow on hover
- GUI crash ("Object has been destroyed") when PTY emits data after BrowserWindow is closed —
onData/onExitcallbacks now checkisDestroyed()before sending IPC messages
[0.4.0] Ember
Fixed
- Daemon crash (exit code 2) when macOS notification fires outside
.appbundle —hasAppBundle()pre-check and@try/@catchpreventNSInternalInconsistencyException - Agent subprocess inheriting
CLAUDECODEenv var — stripped from child process environment to prevent Claude Code nesting issues - Project color not updating in sidebar/dashboard after changing in settings — optimistic local store update now re-renders immediately
- Tasks not updating in GUI when chat agent creates them on disk — removed flawed shallow comparison that suppressed store updates from protobuf-es objects
- CLI wildfire/start-all crashing with "stream error: no agent running" during task transitions — stream errors are now handled gracefully in chaining mode
- System tray concurrent update crashes — serialized Cocoa API calls through a single goroutine with debouncing
- Agent manager deadlock when
onChangeFncallsListAgents()during state persist — moved callback to a goroutine
[0.3.0] Ember
Added
- Daemon health check (
PingRPC) for lightweight connection verification
Fixed
- Daemon startup race condition —
daemon.yamlis now written only after the gRPC server is accepting connections, eliminating "connection refused" errors on startup - GUI no longer shows "Failed to fetch" when starting tasks immediately after daemon launch
- TUI no longer shows "connection refused" on first connect attempt
- GUI settings page (and all views) no longer vanish during brief daemon disconnects — disconnect message now shows as an overlay
- CLI and GUI daemon startup now verify port readiness before proceeding
[0.2.0] Ember
Added
- Agent memory file (
.watchfire/memory.md) — agents can persist project-specific knowledge (conventions, preferences, patterns) across sessions
Changed
- Removed configurable "default branch" setting — tasks now merge into whatever branch is currently checked out in the project root
Fixed
- macOS notifications now display the Watchfire icon instead of a generic system icon
- GUI terminal no longer duplicates output in an infinite loop when an agent stops
[0.1.3] Ember
Fixed
- Homebrew Cask download URL now includes
-universalsuffix to match the actual DMG release asset name, fixingbrew install --cask watchfire - GUI now polls tasks and agent status continuously so the interface updates when task files change
- GUI project settings color changes now apply immediately without needing a restart
[0.1.2] Ember
Fixed
- GUI auto-updater no longer fails with
ENOENT: app-update.yml— the--prepackagedelectron-builder flag skips generating this file; it is now created explicitly in the build workflow
[0.1.1] Ember
Fixed
- GUI now detects Homebrew-installed binaries in
/opt/homebrew/bin/on Apple Silicon Macs - CLI installer checks both
/opt/homebrew/binand/usr/local/binbefore prompting to install - Daemon discovery finds
watchfiredin Homebrew prefix when Electron's PATH is limited
[0.1.0] Ember — Initial Release
Watchfire orchestrates coding agent sessions (starting with Claude Code) based on project specs and tasks. Define what you want built, break it into tasks (or have agents do it), and let agents work through them autonomously — with full visibility into what's happening. Or just turn on wildfire mode and let your agents do it all for you.
Daemon (watchfired)
The always-on backend that manages everything:
- Agent orchestration — Spawns coding agents in sandboxed PTYs with terminal emulation, one task per project, multiple projects in parallel
- Git worktree isolation — Each task runs in its own worktree (
watchfire/<task_number>), auto-merged back on completion with conflict detection - macOS sandbox — Agents run inside
sandbox-execwith restricted filesystem/network access - File watching — Real-time detection of task completion and phase signals via fsnotify, with polling fallback for reliability
- Session logs — Every agent session recorded to
~/.watchfire/logs/with YAML metadata - System tray — Menu bar icon showing daemon status, active agents with colored project dots, and quick stop/quit actions
- Secrets folder —
.watchfire/secrets/instructions.mdfor providing agents with external service credentials and setup instructions, injected into the system prompt - Issue detection — Monitors agent output for auth errors (401, expired tokens) and rate limits (429), with real-time notifications to clients
- gRPC + gRPC-Web — Single port serves both native gRPC (CLI/TUI) and gRPC-Web (Electron GUI)
- Auto-discovery — Writes connection info to
~/.watchfire/daemon.yamlso clients find it automatically
CLI (watchfire)
Project-scoped command-line interface:
watchfire init— Initialize a project (git setup,.watchfire/structure,.gitignore, interactive config)watchfire task add|list|edit|delete|restore— Full task CRUD with soft delete/restorewatchfire definition— Edit project definition in$EDITORwatchfire settings— Configure project settings interactivelywatchfire agent start [task|all]— Start agent in chat, single-task, or run-all-ready modewatchfire agent wildfire— Autonomous three-phase loop: execute ready tasks → refine drafts → generate new tasks → repeatwatchfire agent generate definition|tasks— One-shot generation commandswatchfire daemon start|status|stop— Daemon lifecycle managementwatchfire update— Self-update from GitHub Releases- Terminal attach — Raw PTY streaming with resize handling and Ctrl+C forwarding
- Self-healing project index — Auto-registers projects, updates moved paths, reactivates archived projects
TUI (watchfire with no args)
Interactive split-view terminal interface:
- Split layout — Task list (left) + agent terminal (right) with draggable divider
- Left panel tabs — Tasks (grouped by status), Definition (read-only +
$EDITOR), Settings (inline form) - Right panel tabs — Chat (live agent terminal), Logs (session history viewer)
- Agent modes — Chat, task, start-all, and wildfire with phase display (Execute/Refine/Generate)
- Issue banners — Auth required and rate limit detection with recovery guidance
- Keyboard navigation — Vim-style (
j/k), arrows, tab switching (1/2/3), panel focus (Tab) - Mouse support — Click to focus/select, scroll, drag divider to resize
- Task management — Add, edit, status transitions (draft/ready/done), soft delete — all from the keyboard
- Auto-reconnect — Reconnects to daemon on disconnect with status indicator
- Help overlay —
Ctrl+hfor full keybinding reference
GUI (Electron)
Multi-project desktop application:
- Dashboard — Project cards with task counts, status dots, active task display
- Project view — Tasks, Definition, Secrets, Trash, Settings tabs with collapsible right panel (Chat, Branches, Logs)
- Add Project wizard — Three-step flow: project info → git config → definition
- Branch management — View, merge, delete, and bulk-manage worktree branches
- Agent terminal — Live streaming via gRPC-Web with input support
- Global settings — Defaults, appearance (system/light/dark theme), agent path config, update preferences
- Daemon lifecycle — Auto-restarts daemon if it dies, handles binary updates gracefully
Agent Modes
| Mode | Description |
|---|---|
| Chat | Free-form conversation with the agent at project root |
| Task | Work on a specific task in an isolated worktree |
| Start All | Run all ready tasks in sequence, one at a time |
| Wildfire | Fully autonomous loop: execute → refine → generate → repeat until done |
| Generate Definition | One-shot: agent analyzes codebase and writes project definition |
| Generate Tasks | One-shot: agent reads definition and creates task files |
Task Lifecycle
draft → ready → done (success ✓ or failure ✗)
- Tasks are YAML files in
.watchfire/tasks/ - Agents detect completion by writing
status: doneto the task file - Daemon auto-merges the worktree branch, cleans up, and chains to the next task
- Merge conflicts abort the chain to prevent cascading failures
Build & Distribution
- macOS DMG — Universal binary (arm64 + amd64) with GUI, CLI, and daemon bundled
- Code signing & notarization — Developer ID certificate with hardened runtime
- Homebrew —
brew tap watchfire/tap && brew install watchfire - Auto-update — GUI via
electron-updater, CLI viawatchfire update, daemon checks on startup - CI/CD — GitHub Actions: lint, test, build matrix (arm64/amd64), sign, notarize, draft release