officer-jellyfin owns the whole Jellyfin contract: the instance URL, the access token, the Jellyfin user it belongs to and the DeviceId its sessions are keyed by. The platform side is a 17-line proxy holding no credentials. Servers are a registry, not a single row — this machine runs four instances and the owner switches between them. The password is never stored: it is traded once for an access token through AuthenticateByName, and only that token is persisted, encrypted. Two doors. /_officer/* is a hand-written JSON façade for the things the browser should not have to know — the user id in the path, the Fields lists that decide whether a grid has posters, the PlaybackInfo negotiation. /_jf/* is a GET-only, allow-listed byte pass-through for images, video, HLS and subtitles; it keeps Jellyfin's own paths because a master playlist references its segments relatively, so any renaming would mean rewriting m3u8 bodies. TranscodingUrl arrives with api_key=<access token> in its query string and would otherwise be handed straight to a video element. It is stripped before anything is returned; the pass-through re-adds the credential as a header. Video only — Officer's own player owns audio, so music collections are filtered out of the library list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
50 lines
2.6 KiB
JavaScript
50 lines
2.6 KiB
JavaScript
// Linux light profile — the platform without the self-hosted estate around it.
|
|
//
|
|
// For a machine that should run the file browser, the terminal and Claude/opencode chat, and nothing
|
|
// else. Paired with `OFFICER_PROFILE=light bash scripts/setup.sh`, which installs only what these
|
|
// processes need: node, bun, ffmpeg, Postgres, pm2 and the two agent CLIs.
|
|
//
|
|
// This is a subset of ecosystem.config.cjs, not a copy of it — see ecosystem.profile.cjs for why, and
|
|
// for the two checks that make a drifted profile fail loudly instead of silently starting less than it
|
|
// claims. To change what runs, edit INCLUDE. To change HOW something runs, edit ecosystem.config.cjs
|
|
// and every profile follows.
|
|
//
|
|
// The app itself is unchanged: every API route stays mounted, so features whose sidecars are absent
|
|
// report themselves unavailable rather than disappearing. A profile decides which processes start, not
|
|
// which code ships.
|
|
//
|
|
// Start with: pm2 startOrRestart ecosystem.light.config.cjs
|
|
|
|
const { defineProfile } = require('./ecosystem.profile.cjs');
|
|
|
|
module.exports = defineProfile({
|
|
file: 'ecosystem.light.config.cjs',
|
|
|
|
include: [
|
|
'officer', // the app: SPA, /api, websockets
|
|
'officer-anthropic-proxy', // holds the Anthropic credential, forwards upstream
|
|
'officer-agent', // spawns `claude` — chat is dead without it
|
|
'officer-opencode', // the alternative agent
|
|
'officer-pty', // the terminal
|
|
],
|
|
|
|
// Excluded by CHOICE rather than by platform limits — every one of these would run on a Linux host.
|
|
// A light install simply is not running the thing behind it.
|
|
excluded: {
|
|
'officer-vnc': 'no desktop to mirror on a light install',
|
|
'officer-email': 'needs the mbsync/IMAP stack the light profile does not install',
|
|
'officer-music': 'the ffprobe indexer works, but a full library index is not a light-install concern',
|
|
'officer-vault': 'reverse-proxies a self-hosted Vaultwarden container',
|
|
'officer-slskd': 'supervises the slskd daemon',
|
|
'officer-headscale': 'fronts a headscale server',
|
|
'officer-transmission': 'fronts a transmission daemon',
|
|
'officer-invoiceshelf': 'fronts an InvoiceShelf container',
|
|
'officer-jellyfin': 'fronts a Jellyfin container',
|
|
'officer-memos': 'needs an owner-configured Memos instance URL and token',
|
|
'officer-photos': 'needs an owner-configured Immich instance URL and API key',
|
|
'officer-caldav': 'supervises Radicale, which the light profile does not install',
|
|
'officer-notify': 'its producers are the queue and the email/agent sidecars; nothing to notify about',
|
|
'officer-wallet': 'holds seed and node credentials',
|
|
},
|
|
});
|