tags are how the marketplace is browsed rather than scrolled: a list of them on the left, the plugins that carry one on the right. a closed vocabulary (PLUGIN_TAGS in the platform) because free text becomes homelab, home-lab, Home Lab and selfhosted inside a month, and a filter list of synonyms is worse than no filter at all. declared here rather than curated in the catalogue, so a plugin can say what it is and nobody edits a table when one ships. the marketplace caches it on sync, exactly as it already does for label and summary.
51 lines
2.5 KiB
TypeScript
51 lines
2.5 KiB
TypeScript
import type { PluginManifest } from '@@/plugins/manifest';
|
|
|
|
// Browser — your own Chrome, driven from Officer, through an extension you install yourself.
|
|
//
|
|
// Extracted 2026-08-21, having been switched off since 2026-08-13. It was never a scraper: it attaches to
|
|
// the browser the person is already using, with their sessions, their logins and their tabs. That is the
|
|
// whole difference from `/scrape`, which stays in the platform and launches a headless chromium that
|
|
// knows nobody.
|
|
//
|
|
// extension/ the Chrome extension — the half that runs in the browser
|
|
// sidecar/ the relay it connects to, on a FIXED port, plus the CDP bridge
|
|
// api/ pairing, status, and the target verbs
|
|
// db/ one table: the salt each pairing's token is derived from
|
|
// web/ the tab list and preview panels
|
|
//
|
|
// ── Why the relay is a sidecar ──
|
|
//
|
|
// It listens on its own port, which is why it was switched off: the platform serves one. A sidecar is a
|
|
// process with its own listeners, so the objection disappears rather than being argued with.
|
|
export const manifest: PluginManifest = {
|
|
publisher: 'officerdev',
|
|
version: '1.0.0',
|
|
platform: '>=1.0.0',
|
|
|
|
label: 'Browser',
|
|
summary: 'Drive your own browser from Officer — your tabs, your sessions, your logins',
|
|
/** your own sessions; also how agents drive a page. */
|
|
tags: ['Personal', 'Development'],
|
|
icon: 'Globe',
|
|
color: '#38bdf8',
|
|
|
|
permissions: [
|
|
{
|
|
key: 'browser-relay',
|
|
label: 'Browser',
|
|
description: 'Pair a browser and drive its tabs — screenshots, navigation, evaluated scripts',
|
|
// NOT owner-only, unlike desktop, and the difference is real: every route here is scoped by the
|
|
// caller's own pairing. A member pairs THEIR browser, and the relay resolves an extension's token
|
|
// to the account that minted it — so two accounts on one server drive two different browsers.
|
|
//
|
|
// That is also why this is not the platform's `browser` permission, which is `kind: 'execution'`
|
|
// and covers `/scrape`. Those are different things wearing the same word: one runs a headless
|
|
// chromium as the owner, this one attaches to whoever is holding the keyboard.
|
|
},
|
|
],
|
|
|
|
// Nothing to declare. The extension is installed by the person, into their own browser, and the relay
|
|
// is Bun — there is no host binary in the path at all. Chrome itself is deliberately NOT declared: it
|
|
// does not have to be on this machine, and on a remote pairing it is not.
|
|
};
|