Furst/GUIDE.md
nak0x 2b017197d0 Add a usage guide and an install script
GUIDE.md covers the parts a README does not: what happens when you click a
link, making the proxy stick, the handful of commands worth knowing, and
what to do when a page comes out wrong — which it will, since extraction is
heuristic.

install.sh builds the workspace, installs the four binaries, writes starter
configs, fetches the blocklists, sets up a systemd user service for the
proxy, and offers to register furst as the default browser. Every
system-changing step can be skipped, and the default-browser change is
prompted rather than assumed; a non-interactive run declines it.

Re-running never overwrites a config that already exists, so it is safe
after editing rules. --uninstall removes binaries, service and desktop
entry while keeping configs, and --purge takes those too.

The script passes --workspace to cargo, which is the mistake to avoid here:
the root package is only furst, so a bare build silently skips the other
three binaries.
2026-09-06 23:19:34 +02:00

226 lines
6.3 KiB
Markdown

# Using furst
A practical walkthrough. For what each piece *is*, see [README.md](README.md)
and the per-tool READMEs.
---
## Install
```sh
./install.sh
```
That builds the workspace, installs four binaries to `~/.local/bin`, writes
starter configs, fetches the blocklists, and offers to register furst as your
default browser. It is safe to re-run; it never overwrites a config you have
edited.
```
./install.sh --help # all options
./install.sh --prefix /usr/local/bin
./install.sh --no-default-browser --no-service
./install.sh --uninstall
```
Then install the handlers the rules refer to:
```sh
sudo pacman -S mpv yt-dlp zathura zathura-pdf-mupdf nsxiv surf
```
Nothing breaks if you skip some — a rule whose command is missing falls through
to the next one. `furst --list` shows which are absent.
---
## What happens when you click a link
Nothing to launch. The router is your default browser, and **the reader starts
itself on demand.** Only the proxy runs as a service.
```
click a link, anywhere
furst ─── youtube, vimeo, twitch ──► mpv, H.264 forced, no browser at all
│ *.pdf ──► zathura
│ *.png *.jpg *.gif ──► nsxiv
│ meet, figma, netflix ──► firefox
│ mailto: magnet: ──► xdg-email, transmission
└────── everything else ────────► furst-serve ──► surf
(reader, minimal HTML)
```
Every reader page has a bar: **refresh · original · browser**. Links inside an
article stay in the reader. When a page genuinely needs the real web, click
**browser** and it opens in Firefox.
Two URLs worth bookmarking:
| | |
|---|---|
| http://127.0.0.1:7714/ | reader home — your links, feeds, search box |
| http://furst.proxy/ | proxy status — rules, requests, share blocked |
---
## Making the proxy stick
The proxy is the one piece that must already be running. `install.sh` sets up a
systemd user service for it:
```sh
systemctl --user status furst-proxy
```
Programs find it through the environment, so add this to `~/.zshrc`:
```sh
eval "$(furst-proxy --env)"
```
`surf`, `curl`, `wget` and most CLI tools read those variables. **Firefox does
not** — set its proxy manually in *Settings → Network Settings → Manual*, to
`127.0.0.1` port `8228`, and tick *Also use this proxy for HTTPS*.
Check it is working: `curl -s -x http://127.0.0.1:8228 http://furst.proxy/`
should return the status page.
---
## Commands worth knowing
```sh
furst --explain <url> # why did that open there? ← the one you'll use most
furst --list # every rule, and what isn't installed
furst-read --text <url> # article as plain text; pipe it to less
furst-read --html <url> # article as minimal HTML
furst-serve --status # is the reader running?
furst-serve --clear # drop cached pages
furst-proxy --test <host> # would this host be blocked?
furst-proxy --update # refresh blocklists (weekly is automatic)
```
`furst --explain` is the habit that makes everything else legible:
```
$ furst --explain https://youtu.be/abc123
scheme https
host youtu.be
path /abc123
-> [video] mpv --ytdl-format=bestvideo[vcodec^=avc1][height<=?720]+... https://youtu.be/abc123
[reader] furst-serve --open https://youtu.be/abc123
[default] surf https://youtu.be/abc123
```
The arrow marks what will actually run. Anything above it that is missing from
`$PATH` is skipped, and marked as such.
---
## Fixing things
Extraction is heuristic, so some pages will come out wrong. In order of effort:
**An article looks truncated or empty.** Click **original** in the bar, or add
`&fresh=1` to the URL to bypass the cache.
**A site consistently extracts badly.** Look at what it kept:
```sh
curl -s https://site.example/article | furst-read --stdin --text https://site.example/article
```
The knobs are `POSITIVE` and `NEGATIVE` in `furst-read/src/extract.rs` — lists
of substrings matched against `class` and `id`. Adding the site's content
wrapper class to `POSITIVE` usually fixes it. Rebuild and reinstall with
`./install.sh`.
**A site should never go to the reader.** Add its host to the `heavy` rule in
`~/.config/furst/rules.toml`.
**Something legitimate is blocked.** Confirm it, then allow it:
```sh
furst-proxy --test cdn.example.com
# add to ~/.config/furst/proxy.toml:
# allow = ["cdn.example.com"]
systemctl --user restart furst-proxy
```
Allow rules win over everything, at any subdomain depth.
**Search says the engine refused.** DuckDuckGo rate-limits repeat visitors.
Point `[search] url` in `~/.config/furst/home.toml` at a SearXNG instance:
```toml
[search]
url = "https://searx.be/search?q={q}"
```
**A page renders blank in the reader.** It is probably client-rendered. There is
no JavaScript here by design — use **browser**.
---
## Tuning the rules
`~/.config/furst/rules.toml` is matched top to bottom, first match wins, and a
rule whose command is missing falls through to the next.
```toml
[[rule]]
name = "my-forum"
hosts = ["forum.example.com"]
run = ["furst-serve", "--open", "{url}"]
[[rule]]
name = "hn-in-terminal"
hosts = ["news.ycombinator.com"]
terminal = true # wraps in $TERMINAL -e
run = ["my-tui-client", "{url}"]
```
| host pattern | matches |
|---|---|
| `example.com` | the apex **and** every subdomain |
| `*.example.com` | the same thing |
| `=example.com` | that exact host only |
| `*` | anything |
Placeholders: `{url}` `{url_enc}` `{host}` `{path}` `{scheme}`. If no argument
mentions `{url}` or `{url_enc}`, the URL is appended last.
Order matters — put specific rules above the catch-all `reader` rule at the
bottom.
---
## Where things live
| | |
|---|---|
| `~/.config/furst/rules.toml` | routing rules |
| `~/.config/furst/home.toml` | reader home links, feeds, search engine |
| `~/.config/furst/proxy.toml` | proxy port, blocklists, block/allow |
| `~/.cache/furst/pages` | rendered pages — `furst-serve --clear` |
| `~/.cache/furst/lists` | blocklists, refreshed weekly |
| `~/.local/share/applications/furst.desktop` | the default-browser registration |
---
## Ports
| | |
|---|---|
| 7714 | reader (`FURST_PORT`) |
| 8228 | proxy (`port` in `proxy.toml`) |
Both bind `127.0.0.1` only. Neither is a network service; do not expose them.