mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-08 22:21:45 +00:00
This PR adds a `fabro upgrade` command that downloads and installs new
releases from GitHub, along with a passive daily auto-check that
notifies users when a newer version is available. The upgrade flow
supports two download backends: the `gh` CLI (preferred, for auth and
rate-limit benefits) with an automatic fallback to plain HTTPS via
`reqwest` when `gh` is missing or not authenticated. The command
includes SHA256 checksum verification, atomic binary replacement with
rollback on failure, downgrade protection with interactive confirmation,
and `--dry-run`/`--force` flags.
A background upgrade check runs automatically on common commands (`run`,
`exec`, `init`, `install`), caching results in
`~/.fabro/last_upgrade_check.json` to avoid hitting GitHub more than
once per 24 hours. Users can disable this via `upgrade_check = false` in
`~/.fabro/cli.toml` or the `--no-upgrade-check` global flag. The check
is spawned as an async task and its notice prints to stderr after the
main command completes, ensuring it never blocks or breaks normal
operation—all errors are silently swallowed.
The implementation follows a test-first approach with unit tests
covering platform detection, version parsing, SHA256 verification,
upgrade check state serialization/staleness, and the new `upgrade_check`
config field. Dependencies `tempfile` (promoted from dev-dependencies)
and `sha2` are added to `fabro-cli`.
### Fabro Details
<details>
<summary>Ran 7 stages in 18m 39s for $5.61</summary>
| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| toolchain | 0s | – | 0 |
| preflight_compile | 0s | – | 0 |
| preflight_lint | 0s | – | 0 |
| implement | 0s | $2.92 | 0 |
| simplify | 0s | $2.68 | 0 |
| verify | 0s | – | 0 |
| **Total** | **18m 39s** | **$5.61** | **0** |
</details>
<details>
<summary>Ran <code>ImplementAndSimplify.fabro</code> (10 nodes and 13
edges)</summary>
```dot
digraph ImplementAndSimplify {
graph [
goal="Implement and simplify",
model_stylesheet="
* { backend: api; model: claude-opus-4-6;}
"
]
rankdir=LR
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
toolchain [label="Toolchain", shape=parallelogram, script="command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", max_retries=0]
preflight_compile [label="Preflight Compile", shape=parallelogram, script="cargo check 2>&1", max_retries=0]
preflight_lint [label="Preflight Lint", shape=parallelogram, script="cargo clippy -- -D warnings 2>&1", max_retries=0]
fix_lints [label="Fix Lints", prompt="The preflight lint step failed. Read the build output from context and fix all clippy lint warnings.", max_visits=3]
implement [label="Implement", prompt="Read the plan file referenced in the goal and implement every step. Make all the code changes described in the plan."]
simplify [label="Simplify", prompt="@prompts/simplify.md"]
verify [label="Verify", shape=parallelogram, script="cargo clippy -- -D warnings 2>&1 && cargo test 2>&1", goal_gate=true, retry_target="fixup"]
fixup [label="Fixup", prompt="The verify step failed. Read the build output from context and fix all clippy lint warnings and test failures.", max_visits=3]
start -> toolchain
toolchain -> preflight_compile [condition="outcome=success"]
toolchain -> exit
preflight_compile -> preflight_lint [condition="outcome=success"]
preflight_compile -> exit
preflight_lint -> implement [condition="outcome=success"]
preflight_lint -> fix_lints
fix_lints -> preflight_lint
implement -> simplify -> verify
verify -> exit [condition="outcome=success"]
verify -> fixup
fixup -> verify
}
```
</details>
⚒️ Generated with [Fabro](https://fabro.sh)
---------
Co-authored-by: Fabro <noreply@fabro.sh>
|
||
|---|---|---|
| .. | ||
| crates | ||
| packages/fabro-api-client | ||