This reverts 061e2137.
The artwork is right, the location is not: gitea is about to become a plugin,
and a plugin carries its own icon in assets/ — published to /plugins/<name>/ on
install, and removed when it is uninstalled. Putting it in the platform's
public/icons/ makes it the one plugin whose tile the platform ships, and it
would keep being served after an uninstall.
Added here only because the plugin repository did not exist yet. It does not
yet, either — this goes back in as plugins/gitea/assets/icon.png once it does.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
git + tea, drawn to the icon brief: a green voxel teacup with the branch diagram
pressed into the glaze as a maker's emblem, and Officer Duck on the rim.
Core dock item with no phone app behind it, so there is an icon and no splash —
a splash belongs to something that launches.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both were redrawn to the icon brief today, so the dock shows the same voxel mark
the phone apps do rather than a lucide CalendarDays and Contact.
tile: 'bare' for the same reason a plugin's artwork gets it — the art brings its
own frame, and a coloured square behind it reads as a mistake. color stays
because the active glow, the indicator dot and the settings tint all still use
it.
These two are core rather than plugins, so the files live in public/icons/
alongside the duck rather than arriving through publishAssets.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Seventh extraction, and the first of something that was already dead. Soulseek
had been switched off since 2026-08-13: hono.ts carried the router import and
its PROTECTED_MOUNTS entry commented out, so createSidecarProxy never ran and
registerProxiedPrefix was never called; officer-slskd was not in the ecosystem
at all. Because the permission entry had been reduced to api: [], the totality
check was satisfied and the server booted clean — the UI rendered and every
request 404'd. Worth naming: the boot check proves every MOUNTED prefix has a
permission, and is silent about a feature that mounts nothing.
Also closes a live data hazard: schema.ts had the soulseek export commented
out, so the three tables were absent from the drizzle barrel and bun db:push
would have dropped soulseek_favorites, soulseek_browse_snapshots and
soulseek_browse_dirs on any server holding them. rebuild-soulseek-tree.ts
documented the workaround rather than the problem; deleted with the rest.
The connection stays in core service_connections under service 'slskd' while
the mount is now /api/soulseek. Those differ on purpose.
Test fixtures: slskd was canonical in three app-store tests, the third
extraction running to break them. installer.test.ts now builds a literal
fixture instead of reaching into the catalogue — it pins planSteps, which is
installer logic, and no catalogue entry is both provisioned and members:'none'
any more. catalogue.test.ts and members.test.ts re-anchored to vnc/notify/gitea.
Unrelated but mine: check:theme caught 5 palette classes I introduced in
CommandHQ earlier tonight against a baseline of 0. Converted to bg-success /
bg-warning. check:theme is not part of bun test, which is why the green suite
never showed it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
public/novnc is unbundled noVNC source. The dynamic import pointed at rfb.js, so the browser walked
the module graph natively: fetch a file, parse it, discover its imports, fetch those, repeat. The
graph is 42 modules and six levels deep, so opening the desktop cost six SEQUENTIAL round trips and
42 requests before the VNC handshake could even start — and a hard refresh pays it in full every
time. Over the tailnet that is the "takes a long time to load", not the pixels.
Bundled with bun: 52 modules to one 190 KB file, 56 KB gzipped, one request. The regeneration
command is in a comment next to the constant so a future noVNC bump does not silently keep serving
a stale bundle.
The source tree stays: it is what gets bundled, and keeping it makes the diff of a version bump
readable.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- add types for transfers, private conversations, users, rooms, and server state
- add formatClock / folderLabel / formatDuration helpers and the groupResponses shaper
- move the per-panel zoom key into the persisted screens/ namespace
- extract shared dark-theme Card / SubCard / RowList primitives used by the panels
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two panels (search + transfers) via WorkspaceView, coordinating over the
soulseek:refresh channel. Adds the page-title rule and documents the
route conventions in CLAUDE.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- relay accepts new extension connections by closing old one (last wins, code 4000)
- extension recognizes code 4000 and stops auto-reconnect (shows "replaced" badge)
- fix ping interval race where old WS close handler killed new connection's pings
- retry CDP commands on "Session with given id not found" by re-attaching debugger
- describeError() maps known errors to user-friendly badge tooltips
- persisted relay tokens restored on server start
- user-scoped token salts, token regeneration/deletion endpoints
- extension download endpoint, integrations UI for browser relay setup
- browser relay env vars passed to pi-bridge sandboxes
- browser screen layout with chat panel and prompt prefix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>