SIGN IN SIGN UP

feat(forge): support Gitea (and Forgejo) in the repository panel

Adds a third `ForgeProvider` and the `/api/v1` client behind it, so the
repository panel, the trigger flow and the delivery path work against a Gitea
or Forgejo instance the same way they do against GitHub and GitLab.

Gitea models a repository the way GitHub does — a pull request IS an issue, one
comment collection serves both — so the new client follows `github.rs` rather
than `gitlab.rs`. Where it cannot, each difference is a silent wrong answer if
assumed away:

- The issue list takes no `sort` (Gitea hard-codes newest-first), so the order
  is ignored and the panel HIDES the control rather than showing a choice the
  server discards.
- A new issue's labels are IDs, not names, so they are resolved against the
  repository's vocabulary first — exact match before loose.
- The file list carries no patch, so the change's own `.diff` is streamed under
  a 2 MiB cap and split per file, keyed off `+++ b/<path>` (the path AFTER a
  rename, which is the one the file list reports).
- The comment collection is unpaginated, so the page is cut client-side.
- `status`, not `state`, on a commit status; `deleted`, not `removed`, on a
  changed file; `pulls`, not `pull`, in the web URL.
- Gitea's three "join it as it is" merge styles all map to one method, with the
  difference carried by the existing merge strategy, so a repository that
  permits only `rebase-merge` or `fast-forward-only` merges instead of taking a
  405 on every press.

Host detection asks the public, unauthenticated `/api/v1/version` FIRST and
concludes from its body, so a self-hosted instance whose name says nothing
identifies itself before a credential is spent. Probe bodies are now read to a
4 KiB cap instead of whole.

`find_pulls` is the one place this client can be incomplete: Gitea's `/pulls`
has no head filter and its base/head lookup answers with an arbitrary row when
a branch has both a closed and an open change, so the match is local over a
bounded scan. It fails safe — an unseen pull request reads as no match, and the
create that follows is refused by Gitea itself rather than duplicating anything.

Settings gain a Gitea accounts section with its own token validation
(`validate_gitea_token`, Tauri command plus HTTP route), and the
unsupported-host explanation now names three forges across all ten locales.
X
xintaofei committed
221d54404feed7709ca261aae304f54723d0b161
Parent: ccc420c