Brave Bookmarks Sync

A small Python script keeps a edmd.me Services folder in Brave’s bookmarks bar automatically synced with the services defined in the CT103 Caddyfile.

Why
Every time a service gets added to the Caddyfile, we want it in the bookmarks bar without manual work. The Caddyfile is the source of truth โ€” if it’s routed through Caddy, it should be a bookmark.
How it works

The script reads /Users/bee/tmp-immich-stack/caddy-ct103-Caddyfile, extracts every @matcher host ... entry, and rebuilds a flat alphabetical list inside a folder named edmd.me Services in Brave’s bookmarks bar.

Item Value
Script /Users/bee/tmp-immich-stack/sync-bookmarks.py
Reads /Users/bee/tmp-immich-stack/caddy-ct103-Caddyfile
Writes ~/Library/Application Support/BraveSoftware/Brave-Browser/Default/Bookmarks
Backup Same dir, .bak.YYYYMMDD-HHMMSS files
Folder name edmd.me Services
Structure Flat alphabetical list (aliases included as separate entries)

The script quits Brave before editing (Brave overwrites the file in memory), makes a timestamped backup, removes any existing folder with that name, rebuilds it, and relaunches Brave.

Running it
# Normal run (quits Brave, edits, relaunches)
python3 /Users/bee/tmp-immich-stack/sync-bookmarks.py

# Dry run โ€” show what would happen without touching anything
python3 /Users/bee/tmp-immich-stack/sync-bookmarks.py --dry-run

# Edit without relaunching (useful for cron)
python3 /Users/bee/tmp-immich-stack/sync-bookmarks.py --no-restart
Scheduling

To keep bookmarks auto-updated without manual runs, add to crontab -e:

0 */6 * * * /usr/bin/python3 /Users/bee/tmp-immich-stack/sync-bookmarks.py --no-restart >> ~/Library/Logs/sync-bookmarks.log 2>&1

That runs every 6 hours. The --no-restart flag means Brave isn’t interrupted โ€” the bookmarks file is edited in place and Brave picks up the changes on its next read (typically the next launch, or within a minute for the current session).

Adding a new service
  1. Add the @matcher host newservice.edmd.me + handle @matcher block to /Users/bee/tmp-immich-stack/caddy-ct103-Caddyfile
  2. Push to CT103: scp caddy-ct103-Caddyfile root@192.168.8.221:/tmp/ && ssh root@192.168.8.221 'pct push 103 /tmp/caddy-ct103-Caddyfile /etc/caddy/Caddyfile && pct exec 103 -- systemctl reload caddy'
  3. Add the Cloudflare A record (script at /Users/bee/tmp-immich-stack/add-cf-records.sh handles multiple at once)
  4. Run python3 /Users/bee/tmp-immich-stack/sync-bookmarks.py โ€” or let the cron catch it within 6 hours
Implementation notes
  • Brave’s bookmark file is Chrome’s format โ€” this same script works unchanged against Chrome/Chromium/Arc with only the path changed
  • Brave assigns its own guid and checksum values on load, so the script doesn’t generate them โ€” it lets Brave rebuild them
  • IDs are allocated by scanning the entire JSON for the max existing ID and incrementing from there
  • Timestamps use Chrome’s “microseconds since 1601-01-01 UTC” format โ€” the script converts Unix epoch to this
  • If you manually rearrange/delete items in the folder, the next sync run will wipe your changes and rebuild from the Caddyfile. The folder is machine-managed โ€” use other bookmark folders for ad-hoc bookmarks