Files
gitea/manifest.ts
pastilhasandClaude Opus 5 0049ab5d55 release 2026.08.27.01
first dated version. plugins were all sitting on 1.0.0, which said nothing about
when a build was made or which of two copies is newer — the platform already
uses YYYY.MM.DD.NN and this follows it.

the version lives in manifest.ts because a plugin has no package.json; that is
the field the marketplace publishes and the installer compares.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 07:36:22 +00:00

79 lines
3.5 KiB
TypeScript

import type { PluginManifest } from '@@/plugins/manifest';
/**
* Gitea — repositories, issues and pull requests, inside Officer.
*
* ── This one renders Gitea's own web interface ──
*
* Every other plugin is panels over a JSON API. Gitea already HAS a web interface, and a good one, so
* reimplementing it was seventeen files of screen that could only ever be a worse Gitea. The panel is an
* iframe, and the platform proxies the real thing into it.
*
* The proxy is not decoration, it is what makes the iframe possible at all. Officer and Gitea are
* different registrable domains, so an iframe pointed straight at gitea.officer.dev gets a login page
* whose session cookie the browser drops as third-party. Served through Officer's own origin the cookie
* is first-party and survives — and Gitea's `X-Frame-Options` is stripped on the way through, which is
* safe only because the frame is the same origin the browser already authenticated.
*
* ── Whose Gitea account ──
*
* The person's own. The web proxy injects NOTHING and forwards the browser's own cookies, so whoever is
* looking at the frame is signed in to Gitea as themselves. The stored API token is used only by
* `/_api/*`, which the panel uses for the small things around the frame.
*
* That distinction is the one thing not to get wrong here: injecting the stored token into the web proxy
* would show every user the owner's view of every repository.
*
* ── `unauthenticatedPaths` ──
*
* `/_web/*` is served above the platform's gate because an iframe's sub-resources carry no Authorization
* header. It authenticates with a minted, path-scoped cookie instead — see `api/router.ts`. Gitea
* authenticates the person itself regardless, so the worst an unauthenticated caller sees is a login
* page.
*
* ── `tea` ──
*
* The affordance in `affordances/` tells agents to use plain `git` for what git already does, and `tea`
* for pull requests, issues and comments. Provisioning `tea` per user is not built yet.
*/
export const manifest: PluginManifest = {
publisher: 'officerdev',
version: '2026.08.27.01',
platform: '>=1.0.0',
label: 'Gitea',
summary: 'Repositories, issues and pull requests — your own Gitea, rendered in Officer',
/** your own forge, on your own box. */
tags: ['Development', 'Homelab'],
icon: 'GitBranch',
color: '#609926',
unauthenticatedPaths: ['/_web/*'],
// `tea` is not in any distribution, and Debian has an UNRELATED package of that name — a graphical
// text editor. So this is a release binary with an identity check: `Bun.which('tea')` cannot tell the
// two apart, and reporting the wrong one as satisfied is worse than reporting it missing.
osDependencies: [
{
binary: 'tea',
reason: 'Pull requests, issues and comments. Plain git handles clones and pushes without it.',
// Empty on purpose. Every entry here would install the text editor.
packages: {},
release: {
url: 'https://dl.gitea.com/tea/0.15.1/tea-0.15.1-{os}-{arch}',
// Gitea's tea prints `Version: 0.9.2 golang: … go-sdk: …`. The text editor prints nothing of
// the sort, and `go-sdk` is the least likely of those to appear in an unrelated tool.
identify: { args: ['--version'], contains: 'go-sdk' },
},
},
],
permissions: [
{
key: 'gitea',
label: 'Gitea',
description: 'Repositories, issues, pull requests and notifications from your own Gitea account',
},
],
};