Files
platform/ecosystem.mac.light.config.cjs
T
pastilhasandClaude Opus 5 904edefd62 jellyfin sidecar: server registry, video façade and byte pass-through
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>
2026-08-04 17:59:50 +00:00

63 lines
3.3 KiB
JavaScript

// macOS light profile — the same process set as the Linux light profile, on a laptop.
//
// Paired with scripts/setup_mac_light.sh. Runs the file browser, the terminal and Claude/opencode
// chat; nothing else.
//
// This is a subset of ecosystem.config.cjs, not a copy of it. That distinction is here because of this
// file specifically: written on 2026-07-28 as a hand-copied process list, it was broken within days by
// two changes it could not see. It ran `officer-claude` against the Anthropic proxy's entry point
// while the process that actually spawns `claude` was never started, and it pointed at a pty sidecar
// that had moved. Both failures were silent — the processes simply did not come up. See
// ecosystem.profile.cjs for the checks that now make that loud.
//
// WHY THIS IS SEPARATE FROM ecosystem.light.config.cjs, given both currently run the same five apps:
// the exclusions mean different things. On macOS officer-vnc cannot run — there is no Xorg to mirror.
// On a Linux light install it could run perfectly well; you have chosen not to. Those diverge as soon
// as one profile gains something the other cannot have, and collapsing them would lose the reason.
//
// Start with: pm2 startOrRestart ecosystem.mac.light.config.cjs
const { defineProfile } = require('./ecosystem.profile.cjs');
module.exports = defineProfile({
file: 'ecosystem.mac.light.config.cjs',
include: [
'officer', // the app: SPA, /api, websockets
'officer-anthropic-proxy', // holds the Anthropic credential, forwards to api.anthropic.com
// Spawns `claude`. Reads the proxy secret from disk, so it needs no ordering against the proxy
// above: if the secret is not written yet it warns and re-reads before the next spawn.
'officer-agent',
'officer-opencode', // the alternative agent
// The terminal. Runs under node rather than bun — node-pty binds a native addon built against
// node's ABI. That detail lives in ecosystem.config.cjs, not here.
'officer-pty',
],
excluded: {
// Cannot run on macOS at all.
'officer-vnc': 'mirrors an Xorg display with x11vnc; macOS has no Xorg',
// Would run, but needs something setup_mac_light.sh deliberately does not install.
'officer-email': 'needs the mbsync/IMAP stack setup_mac_light.sh does not install',
'officer-caldav': 'supervises Radicale, which setup_mac_light.sh does not install',
'officer-music': 'the ffprobe indexer works, but a full ~/Music index is expensive to start by default',
// Fronts a container or daemon a laptop is not running.
'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',
// Needs an owner-configured external service.
'officer-memos': 'needs an owner-configured Memos instance URL and token',
'officer-photos': 'needs an owner-configured Immich instance URL and API key',
// Deliberate, for what it holds or who feeds it.
'officer-notify': 'its producers are the queue and the email/agent sidecars; nothing to notify about',
'officer-wallet': 'holds seed and node credentials; not on a laptop',
},
});