Files
platform/ecosystem.light.config.cjs
T
pastilhasandClaude Opus 5 9c353f5f0d move host setup into scripts/setup/
scripts/ was holding two unrelated kinds of thing: install-this-machine, and run-this-occasionally. The
eight installers now live in scripts/setup/; what stays at the top level is the build steps (gen-index,
prebuild, build/) and the two maintenance scripts (reindex-music, rebuild-soulseek-tree).

The move is not just a rename. Three of these derive the repo root from their own location:

  setup.sh:51            PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
  setup_mac_light.sh:51  same
  cleanup-desktop.sh:134 ENV_FILE="$(dirname "$0")/../.env"

Left alone, all three would now resolve to scripts/ — and nothing downstream complains. PROJECT_DIR is
where .env is written, where `bun install`, `gen:index` and `db:push` run, and what pm2 is pointed at, so
a fresh install would have quietly provisioned scripts/ and reported success. cleanup-desktop.sh fails
the other way: it would find no .env, print "No .env — skipping", and leave the real VNC_PASSWORD in the
real file. All three are now `../..` with a comment saying why the level matters.

provision-user-dirs.ts imports data-path.ts relatively; that one tsgo caught.

Also disambiguated `setup.sh` where it had become two files. app-store/templates/<name>/setup.sh is a
per-sidecar installer with its own contract, and preflight.ts + docs/sidecar-app-store.md discussed both
in the same paragraph. The host one is now spelled with its full path at those sites.

Verified: bash -n on all six shell scripts, tsgo clean, os-user tests pass, both derivations resolve to
the repo root, starship.toml still resolves from os-user-shell.ts, and provision-user-dirs.ts runs under
DRY_RUN.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 04:02:19 +00:00

56 lines
3.2 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/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: {
// Was in the baseline until 2026-08-11, on the reasoning that it fronts a REMOTE instance and so needs
// nothing installed locally. True, and beside the point: a baseline process appears in the Permissions
// screen and the dock whether or not anyone has given it a URL, so a fresh server offered to grant Gitea
// access to an instance that did not exist. It is installable now — `existing` mode, URL and token — which
// makes "is Gitea here" one question with one answer instead of two that disagree.
'officer-gitea': 'fronts a remote instance; installed from the app store with its URL and token',
'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',
},
});