From 9084fabbf69b0538860b54eeefe90d480b967003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Mon, 10 Aug 2026 18:17:05 +0000 Subject: [PATCH] app store: note where a real PNG icon's bytes will have to live MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real icons are coming and the manifest field already exists — slskd uses it. What is not decided is where the bytes come from for a sidecar that ships from its own repository: /slskd.png works only because it sits in the platform's public/, which a marketplace plugin cannot write to. Records the three options and their trade — marketplace URL (loses icons offline), served by us from the sidecar's directory (works offline, needs a route and caching), or a data URI (no fetch, but bloats every manifest) — so the next person meets the question instead of assuming the current path generalises. Co-Authored-By: Claude Opus 5 --- src/servers/app-store/catalogue.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/servers/app-store/catalogue.ts b/src/servers/app-store/catalogue.ts index ed2c6511..ddb3392c 100644 --- a/src/servers/app-store/catalogue.ts +++ b/src/servers/app-store/catalogue.ts @@ -53,7 +53,19 @@ export type UiManifest = { name: string; /** A lucide icon name, resolved at render. */ icon?: string; - /** An image asset instead of a glyph, for a service with its own mark. */ + /** + * An image asset instead of a glyph, for a service with its own mark. Real PNGs are coming, and this + * is the field they arrive in. + * + * `/slskd.png` works today because it sits in the platform's `public/`. A marketplace plugin cannot + * put a file there, so one thing has to be decided before third-party icons ship: whether the bytes + * are fetched from the marketplace (simple, but the dock loses its icons offline), served by us from + * the sidecar's own directory (works offline, needs a route and a cache header), or inlined as a data + * URI (no fetch, but every manifest carries it and it is unpleasant at 512px). + * + * Whichever wins, this stays a STRING the renderer resolves — never an import — for the same reason + * `icon` is a name: a manifest has to survive being JSON. + */ image?: string; /** Tile colour. */ color: string;