Adapting to your Mac

Edward ran for months for one person in one home. Here is how to fit him to yours.

Most of what was specific to that home is now a setting. A few places still assume the first host, and each is marked in the code with an ADAPT: note. The full list, with file and line, is docs/ADAPTING.md.

Settings, not code

WhatWhere it is readSettings
Who you arebackend/services/owner.pyEDWARD_OWNER_NAME, _FULL_NAME, _ALIASES, _HANDLES, _EMAILS, EDWARD_HOUSEHOLD
Where Edward runsbackend/services/host_config.pyEDWARD_PUBLIC_BASE_URL, EDWARD_LAUNCHD_PREFIX, EDWARD_TUNNEL_LABEL, EDWARD_BACKUP_DIR, and more
What the shell scripts seescripts/lib/edward-env.shThe environment, then .env, then the default

See Configuration for the settings themselves.

Finding the seams

grep -rn "ADAPT:" --include='*.py' --include='*.ts' --include='*.tsx' --include='*.sh' \
  --include='*.swift' --include='*.js' \
  backend frontend scripts companion chrome-extension scriptable | grep -v node_modules

Each note has the same three parts:

# ADAPT: <what is specific to the original host, in one line>
#   How it works here: <what the code assumes>
#   To adapt: <the setting to change, or what to build>

The ones you are most likely to meet:

  • iMessage as you. Edward sends and reads as the Apple ID Messages on the Mac is signed into, so “from me” means you. An Apple ID of his own means reworking the echo checks.
  • Mail.app’s index lives under ~/Library/Mail/V10, which changes between macOS releases (EDWARD_MAIL_ENVELOPE_INDEX).
  • Calendar’s and Reminders’ stores are private Apple databases, checked on one macOS version; when they can’t be read he says so (the calendar falls back to apple-mcp when it is set up).
  • The protected Homebrew kegs ([email protected] and postgresql@16) and HOMEBREW_PREFIX, which the sandbox rails name.
  • The screen is a Google Chrome tab sized over AppleScript when the hands are on; any browser works when they are off.
  • The hub is laid out for one 7″ kiosk, and its pets come from a seed file with no editor in the app.
  • Alexa inbound is not signature-verified.
  • Ports: :8000 and :3000 are also written into the Chrome extension and the shell’s denied ports, so moving one means changing those too.

macOS permissions

Almost every grant goes to the backend’s python: the real path of the python3.12 behind backend/.venv, which setup.sh and the LaunchAgent installer print. To grant it: System Settings → Privacy & Security → the list → + → Cmd + Shift + G → paste the path. Started by hand from a terminal, macOS charges the terminal app instead.

PermissionWhat needs it
Full Disk AccessiMessage, contact names, Mail’s index, the Calendar and Reminders stores, and backups to a removable drive
AutomationSending an iMessage; with the Chrome hands on, Chrome, Finder and System Events. Answer the first prompt at the Mac
AccessibilitySizing Chrome’s window for /screen (hands on only)
Screen Recordinglook at the screen
Calendars, RemindersChanging them when you ask: bash backend/scripts/eventkit_request_access.sh, at the Mac

Grants follow the binary’s path. brew upgrade [email protected] moves Python and every grant silently stops applying: grant the new path, re-run bash scripts/install-launchagents.sh and the EventKit script. A brew install of something that depends on Python can upgrade it along the way, which is why Edward’s media handling avoids ffmpeg.

Prompts for the bigger changes

Open Claude Code in your checkout: CLAUDE.md loads by itself and carries the house rules (a fix lands with the test that pins it, backend tests only on the test database, the architecture doc of anything you change). ADAPTING.md has a prompt for each of these, ready to paste:

Change
AA pets-and-care editor in the Edward tab, so the hub needs no seed file
BLinux, starting with a sandbox for the bash tool (bubblewrap)
Csystemd units instead of LaunchAgents
DA separate Apple ID (or number) for Edward, so people text him, not you
EAmazon’s signature verification for inbound Alexa requests
FYour own browser (Safari, Arc) for the screen
GEdward under his own macOS user, for real isolation of his shell. The reference install never ran this way: treat it as a project (his own logged-in session, his own copies of your data, Postgres with passwords)

When you add code that assumes something about your own host, mark it the same way, and add a row to ADAPTING.md.