Swarm v0.3.0
The coordination release: rules you can configure, runtime resources agents can hold, and the merge queue at the end of the loop.
Added
- Config system —
~/.swarm/config.toml(global) deep-merged with an optional<repo>/.swarm.toml. Lenient validation: bad config can never take the daemon down. Daemon port preference isSWARM_PORT> config > 7777. Seedocs/13-config.md. - Rule engine v2 — every rule is per-repo configurable as
ask | deny | off:shared_tree,destructive_git,pattern_kill, and the newprotected_ports(kill/free of a configured port —lsof | kill,fuser -k,kill-port— is asked or denied).denyis returned to Claude Code as a real permission denial. - Incidents — every non-allow decision is recorded (
incident.opened: rule, action, command, reason), exposed atGET /v1/incidents, included in/v1/state, and shown on the Board. - Runtime resources (Phase 1) — named singletons for what agents fight over at runtime (dev servers, databases, ports). Fail-closed acquire: holdings live while their pid runs or their lease hasn't expired; the same owner refreshes; dead holdings reap instead of blocking. Release is fail-closed too (owner required,
--forceoverrides). Held ports automatically join the protected-ports rule — acquiringdbon 5432 guardslsof -ti:5432 | xargs killfor every other agent, no config needed. HTTPGET/POST /v1/resources,DELETE /v1/resources/:name; MCPswarm_acquire_resource/swarm_release_resource/swarm_resources; CLIswarm res ls|acquire|release. - PRs view — one merge queue across GitHub and GitLab. Forge detection from the git remote (ssh/https, GitLab subgroups, self-hosted), polled through the locally-authenticated
gh/glabCLIs with the project root as cwd — no tokens stored, 2-minute per-project cache floor.GET /v1/prs,POST /v1/prs/merge(squash). Merge is offered only on green, mergeable, non-draft rows, behind a confirm. - Board view — Claims, Worktrees, Resources, and Incidents move out of Fleet into their own view; Fleet shows sessions only (Live + Earlier). Last view and project selection persist across reloads.
- Stats view —
GET /v1/stats; activity line, calendar heatmap, and streaks (daily buckets in local time, DST-immune).swarm statson the CLI. - Data-grid everywhere — Claims, Worktrees, Resources, Incidents, PRs, and all six Spend tables render through the same sortable / resizable / reorderable grid with per-column filters, a column-visibility menu, and persisted layouts. Header ticks and tooltips make the affordances discoverable.
- Desktop: Check for Updates… in the tray menu, wired to the Tauri updater with native dialogs (available / up-to-date / failed) and install-and-restart on accept.
- Agent badge on every Fleet and session row, so mixed-agent fleets are labelled consistently.
- Website — getswarm.vercel.app: OS-detected downloads from the latest GitHub release, the
bunxone-liner, sharing tags with hero art, and (this release) rendered docs and release notes. - Design tokens — the dashboard's CSS contains zero raw hex / rgba / font-size / duration values; the system is documented in
docs/12-design-tokens.mdwith a drift grep. - Swarm now dogfoods its own rules via the repo's
.swarm.toml(shared_tree/destructive_gitdeny, daemon port protected).
Fixed
- Hook resilience — the PreToolUse hook falls back to the default port when
daemon.jsonpoints at a dead daemon, so a crashed daemon no longer silently disables the guard (this was the gap behind a realgit add -Acollision). - Resource liveness: pid 0 was treated as a live process (
kill(0)addresses the process group), so those holdings never reaped; tracked pids are now> 0.heldPorts()is one SELECT on the hook path; lazy reap on acquire, sweep on the 5 s tick. Unknown session IDs on acquire no longer mint phantom sessions. - Session view is two equal columns again (a bare
asideselector in the sidebar-collapse CSS captured the session side panel); the log keeps your scroll position across live updates and follows the tail only when pinned to the bottom. - A pinned project whose root vanished is merged into the live same-name entry (repo renames produced duplicate sidebar rows); the sidebar
⋯appears on hover in the count's slot and reserves no space. - Desktop: quit actually quits, window close hides (macOS convention) and the dock icon restores it, and the
swarmdsidecar dies with the app. Dev builds serve the repo's live dashboard instead of a stale staged snapshot. - Release pipeline: npm publish is skipped cleanly when
NPM_TOKENis absent.
Install: bunx @ra3orblade/swarm setup · Docs: https://getswarm.vercel.app/docs/ · Full changelog: v0.2.2...v0.3.0