gitea: the plugin, rendering Gitea's own interface

Eleventh plugin out, and the first that is not a move. The seventeen files that
reimplemented a fraction of Gitea's interface were deleted rather than carried
across — each one a promise to keep pace with a project that moves faster than
this plugin will.

That removed a platform change nobody now has to build. useGiteaLocation read
:owner/:name/:tab/:item from five route patterns and a plugin gets two, so
extracting as-is would have needed the plugin system to declare extra routes.
Nothing inside an iframe needs a route, so the requirement went with the screen.

No regression window: gitea's router had been commented out of hono.ts since
2026-08-13 with api: [], and officer-gitea was running nowhere. The screen
rendered and every request 404'd.

The proxy is what makes the iframe possible, not decoration. Officer and Gitea
are different registrable domains, so a frame pointed straight at the instance
gets a login page whose cookie the browser drops as third-party. Through
Officer's origin it is first-party and survives; X-Frame-Options and CSP are
stripped, safe only because the frame is the origin the browser already
authenticated.

/_web/* forwards the browser's own cookies and injects NOTHING. The sidecar
holds an API token and injecting it there would show every user the owner's
view of every repository. It is used only by /_api/*.

Two doors, because an iframe's sub-resources carry no Authorization header:
the ordinary routes go through the platform's gate, and /_web/* is declared
unauthenticated and authenticates itself with a minted, path-scoped cookie —
32 random bytes against the user who asked, not dev-proxy's constant =1 which
anyone knowing the cookie name can set. Verifying it also sets `user`, because
createSidecarProxy fills X-Officer-User from it and the sidecar refuses a
request without one.

Ships an affordance: git for what git does, tea for pull requests and issues.
Nothing copies it into capabilities/ yet — gitea is that mechanism's first
customer.
This commit is contained in:
officer
2026-08-19 07:58:55 +00:00
parent fbc85acaca
commit f680e25f82
10 changed files with 867 additions and 17 deletions
+23 -17
View File
@@ -1,26 +1,32 @@
# Gitea
Gitea inside Officer — repositories, issues and pull requests.
Your own [Gitea](https://about.gitea.com) inside Officer — repositories, issues and pull requests,
rendered as the real thing rather than a copy of it.
**Not built yet.** This repository exists so artwork can land before the code does.
## What you get
## Assets
Gitea's own web interface, in an Officer panel. Not a reimplementation: the actual application, proxied
through Officer so it stays signed in, with an **open in a new tab** button for anything the frame
handles badly.
```
assets/icon.png the dock tile
assets/splash.png the launch scene, for the mobile app and the credits screen
```
## Requirements
Presence is the declaration — no manifest field. `discover.ts` reads those two exact paths, and
installing publishes the whole directory to `/plugins/gitea/`. A shipped `icon.png` wins over the
manifest's lucide glyph automatically.
A Gitea instance Officer can reach.
## What this plugin will be
## Setup
Unlike the other plugins, the UI is not a set of panels over a JSON API. Gitea already has a web
interface, so Officer proxies it and renders it in an iframe — same-origin, because a third-party iframe
cannot keep a session cookie.
Install the plugin, open **/gitea**, and set the instance URL and an API token in the connection panel.
Then sign in to Gitea inside the frame, once — the frame shows **your** Gitea account, not the owner's.
It will also ship an affordance telling agents to use plain `git` for what git already does, and `tea`
for pull requests, issues and comments — `tea` being logged in as the current user, with that user's own
permissions.
The stored token is used only for the small things around the frame. Everything you see in it is your own
session.
## For agents
This plugin ships an affordance: use plain `git` for clone, fetch, pull and push; use `tea` for pull
requests, issues, comments and releases. `tea` is logged in as you, with your permissions.
## Permissions
One permission, `gitea`, grantable per role like any other app permission. Each account reaches its own
Gitea identity.