ecosystem.mac.config.cjs was written on 2026-07-28 and broken within days by two
changes it never caught up with, leaving two of its four processes dead:
- it ran `officer-claude` against src/servers/sidecar/claude/index.ts. That file
is the Anthropic credential proxy; the process that actually spawns `claude`
is user-instance.ts, which was never started. Chat had a credential holder and
nothing driving it. Split into officer-anthropic-proxy + officer-agent to
match the host, and retired the `officer-claude` name that caused it.
- officer-pty pointed at src/servers/api/terminal/pty-sidecar.mjs, which no
longer exists; the sidecar moved to src/servers/sidecar/pty/index.mjs. The
terminal could not start at all.
No startup ordering is needed between the proxy and the agent: the agent reads
the proxy secret from disk and, when it is not there yet, warns and re-reads
before the next spawn.
Five sidecars have been added since the file was written (memos, caldav, photos,
notify, wallet). All are excluded, and every exclusion is now listed with its
reason so the next reader can tell "not applicable on macOS" from "forgotten" —
which is the failure this commit is fixing.
setup_mac.sh needed no path corrections; its verification loop derives the
process names from the ecosystem file, so it picks the new list up on its own.
Two gaps closed there:
- it called `pm2 save` without `pm2 startup`, writing a process list that
nothing reads — a reboot left the machine with nothing running. Added the
launchd equivalent behind SETUP_BOOT, optional because a laptop is not a
server, and non-fatal because pm2's launchd integration can want a prompt.
- the closing "not installed on macOS" note listed four omissions when there are
now fourteen.
Both files parse and every ecosystem entry point resolves to a file that exists.
The launchd path is the one thing not verified here — it cannot be exercised
from the Linux host.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
setup.sh targets an ubuntu server and is left untouched. this is the
laptop equivalent: file browser, claude/opencode chat, terminal. no go,
rust, cliamp, pulseaudio, neovim, shell dotfiles, vnc desktop, sudoers
grant or power management — 510 lines against 1033.
every step is optional, prompted, and presettable non-interactively with
SETUP_* variables, so it also works as a repair tool for one piece.
nothing calls sudo. node@22 goes on PATH with brew link --force, pm2 into
~/.local, and the claude cli no longer needs a /usr/local/bin symlink now
that the sidecar resolves it.
postgres is detected before anything is installed — a server already
listening on 5432 (docker) is used as-is.
notes on the differences from setup.sh:
- set -e is on, but every optional step is guarded, so a failure warns and
the run continues to a summary instead of aborting mid-way.
- .env is written 0600 and the generated JWT_SECRET is length-checked
before use, since jwt.ts throws on anything under 32 chars.
- PUBLIC_BUILD_ENV=development, which is what lets plain http://localhost
work with no reverse proxy in front.
- xcode command line tools are not required to build: node-pty and argon2
both ship darwin prebuilds. they still matter for git on a fresh mac.
ecosystem.mac.config.cjs drops officer-vnc (x11vnc needs xorg),
officer-email and officer-music, and pins cwd on every app so bun picks
up .env wherever pm2 is started from.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>