---
title: "Auto-merge for PRs, three new lifecycle hooks, and styled workflow graphs"
date: "2026-03-16"
---

## Auto-merge for workflow-created pull requests

Workflows that create pull requests can now automatically merge them once CI passes. Set `auto_merge = true` in your `[pull_request]` config and Fabro enables GitHub's auto-merge via the GraphQL API. You can control the merge method with `merge_strategy` — squash (default), merge, or rebase. If the target repo doesn't have auto-merge enabled in its settings, Fabro warns but doesn't fail the run.

```toml
[pull_request]
auto_merge = true
merge_strategy = "squash"
```

## Three new lifecycle hooks

Three new hook events are now available — `stage_retrying`, `parallel_start`, and `parallel_complete`. `stage_retrying` fires immediately before backoff sleep on both error-retry and explicit-retry paths, and the parallel hooks fire when parallel node groups start and finish execution.

## More

<Accordion title="CLI">
- Added `-q`/`--quiet` flag to `fabro ps`, mirroring `docker ps -q` — outputs only run IDs, one per line, composable with `-a` (e.g., `fabro ps -qa`)
</Accordion>

<Accordion title="Improvements">
- Agent sessions now retry up to 3 times when an LLM provider drops a stream mid-response, preserving conversation history and replaying partial output
- Workflow graph SVGs from `fabro graph` and the API now render with styled defaults (teal nodes, clean typography) and automatic dark mode support
- Crash reporting via Sentry — CLI panics are now captured and uploaded in a detached subprocess so they survive parent exit
- Added `install.md` for AI-agent-driven installation (Claude Code, Codex, etc.), with platform detection, binary download, and PATH setup
- Installer now skips shell config modification in non-interactive mode, printing the manual PATH export instead
</Accordion>

<Accordion title="Fixes">
- Fixed stage durations always showing `0s` in PR descriptions due to a key mismatch between node labels and node IDs
- Fixed OpenAI OAuth callback showing a deserialization error when the provider returns an error response (e.g. `invalid_scope`) — now displays a styled error page and propagates the error to the CLI
</Accordion>
