Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b9ebac3
feat(unification): Phase 1 — unified packages.json + parity harness (…
ulises-c Jun 10, 2026
21061bf
fix(setup): empty pnpm tier no longer aborts --optional runs under se…
ulises-c Jun 10, 2026
a40fa60
feat(unification): Phase 2 — lib/core.sh engine + platform modules + …
ulises-c Jun 10, 2026
a6303d8
chore: add execute permission to new setup scripts
ulises-c Jun 10, 2026
36d5a60
docs(todo): generalize ghostty item into dotfiles consolidation plan
ulises-c Jun 10, 2026
a8d4149
feat(unification): Phase 3 — shared verify engine + root verify.sh (#36)
ulises-c Jun 10, 2026
95e7425
feat(unification): Phase 4 — per-folder scripts become thin shims + r…
ulises-c Jun 10, 2026
8286bb9
fix(unification): harden Phase 4 shims + replace deleted gates with a…
ulises-c Jun 10, 2026
0ba9c22
feat(unification): Phase 5 — delete legacy package JSONs, fold server…
ulises-c Jun 10, 2026
54e1b1e
feat(unification): Phase 6 — merge main, port p10k + lact into the un…
ulises-c Jun 10, 2026
56bdd45
feat(unification): Phase 7 — dotfiles/ for shared configs, macOS gain…
ulises-c Jun 10, 2026
de7e43a
feat(unification): Phase 7 cont. — shared zshrc base in dotfiles/ wit…
ulises-c Jun 10, 2026
a95fbc2
feat(unification): cross-platform zshrc — macOS joins the dotfiles zs…
ulises-c Jun 10, 2026
2a6d5a1
fix(dotfiles): damp Ghostty scroll reporting for high-res wheels
ulises-c Jun 10, 2026
41cdef1
fix(hooks): post-test-runner portability (macOS) and uv venv support
ulises-c Jun 10, 2026
cf960ed
feat(packages): add uv; adopt pre-existing casks; claude-code via cur…
ulises-c Jun 10, 2026
01e0480
fix(packages): gh apt-repo migration, rustup on Arch, macOS tailscale…
ulises-c Jun 10, 2026
6504553
fix(packages): install-method cleanup from the #39 audit (high-confid…
ulises-c Jun 10, 2026
fe5999f
fix(server): micro/nvtop via snap — the server is Ubuntu Server LTS, …
ulises-c Jun 10, 2026
2fb881b
feat(packages): track Mac brew leaves; server zsh plugins via antidote
ulises-c Jun 10, 2026
6cf0057
fix(server): harden antidote migration; verify probes for fj/zen — re…
ulises-c Jun 10, 2026
eb0fe49
fix(server): zsh-antidote via apt — noble ships it after all
ulises-c Jun 10, 2026
a6d54ae
docs(todo): Ubuntu desktop live-run notes — first machine validated live
ulises-c Jun 10, 2026
16b2e9c
fix(zsh): p10k via antidote on all desktops — Ubuntu live-run miss
ulises-c Jun 10, 2026
c09fab5
fix(claude): resolve node at runtime in claude-hud statusline
ulises-c Jun 10, 2026
423e4b8
feat(claude): deploy settings.json as a copy, not a symlink
ulises-c Jun 10, 2026
83459c7
refactor(core): single RELATED_SCRIPTS list for all platforms
ulises-c Jun 10, 2026
0e6e77e
fix(macos): neutralize all conflicting Ghostty configs, deploy plain …
ulises-c Jun 10, 2026
945203c
0.25 is too slow
ulises-c Jun 10, 2026
ff71305
fix(macos): survive partial brew failures, unify p10k, fix verify fal…
ulises-c Jun 11, 2026
f73d354
refactor(ssh): generalize self-hosted Git server option
ulises-c Jun 11, 2026
f62f985
`cf` alias added - clear && fastfetch
ulises-c Jun 14, 2026
fe58625
feat(packages): add xcodegen to macOS tooling
ulises-c Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ jobs:
with:
scandir: .
severity: warning
ignore_paths: macOS

json-validate:
runs-on: ubuntu-latest
Expand All @@ -36,6 +35,14 @@ jobs:
done
exit $failed

dryrun-smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Root setup.sh dry-run on every platform
run: bash scripts/dryrun-smoke.sh

zsh-syntax:
runs-on: ubuntu-latest
steps:
Expand All @@ -47,7 +54,7 @@ jobs:
- name: Run zsh -n on zsh scripts
run: |
failed=0
for f in $(find . -not -path './.git/*' \( \( -name '*.sh' -path '*/macOS/*' \) -o -name '*.zsh' -o -name 'zshrc.example' \)); do
for f in $(find . -not -path './.git/*' \( -name '*.zsh' -o -name 'zshrc.example' \)); do
if zsh -n "$f" 2>&1; then
echo "✓ $f"
else
Expand Down
3 changes: 1 addition & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ repos:
hooks:
- id: shellcheck
args: [--severity=warning]
exclude: ^macOS/

- repo: local
hooks:
Expand All @@ -13,7 +12,7 @@ repos:
language: system
entry: zsh -n
types: [file]
files: (^macOS/.*\.sh$|\.zsh$|zshrc\.example$)
files: (\.zsh$|zshrc\.example$)

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
Expand Down
56 changes: 56 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Computer-Setup

Personal machine-provisioning repo: one unified installer for macOS, Linux
desktop (Ubuntu/Arch), and an Ubuntu Server LTS home server, plus per-platform
configs and docs. (A Raspberry Pi — Debian proper — is a future target,
tracked in TODO.md.)

## Entrypoints

- `setup.sh` — installs everything for the detected platform.
Flags: `--optional --work --personal --dry-run --platform <macos|ubuntu|arch|server> --profile <desktop|server>`.
The server platform is never auto-detected (`--profile server` or `--platform server` required).
- `verify.sh` — read-only health check mirroring `setup.sh`'s selection logic.
Flags: `--optional --work --personal --all --platform <macos|ubuntu|arch>`
(no `--dry-run`; `--platform server`/`--profile server` is rejected — nothing
legacy existed to port). Unknown flags warn and are ignored, they don't abort.

## Architecture

- `packages.json` — single source of truth for all package data. Managers are
keyed by platform (`{macos, ubuntu, arch, server}`); `<platform>_name`
overrides the install token; `environment` tags gate on `--work`/`--personal`;
`custom` managers carry `install_command` (string or per-platform object) —
run by the engine when `handled_by_setup` is true, otherwise printed as a
manual-install reminder.
- `lib/core.sh` — shared engine: arg parsing, platform detection, env filter,
jq selection, install loops, config deploys. `lib/verify.sh` — check engine.
- `platforms/<platform>.sh` — per-platform quirks only (bootstrap, manager
invocations).
- `dotfiles/` — configs shared across platforms (`tmux.conf`,
`ghostty.config`, `zshrc.example`, `zsh_plugins.txt`); the engine deploys
them from here. The zshrc base is cross-platform — macOS-specific bits are
guarded on `/opt/homebrew` or `$OSTYPE` — and has an override system
(`deploy_zshrc`): a platform folder shipping its own `zshrc.example` wins
over the dotfiles base. Only `linux-server/` does (headless: no
Ghostty/fastfetch/notification hooks).
- `macOS/`, `linux-desktop/`, `linux-server/` — platform-specific configs
(server zshrc override, p10k), docs, and thin shim scripts that exec the
root entrypoints.
- `scripts/dryrun-smoke.sh` — runs `setup.sh --dry-run` for every platform and
asserts it exits clean with install actions; also run in CI.

`UNIFICATION.md` is the design doc for this layout; `TODO.md` tracks remaining
phases.

## Conventions

- Pre-commit runs `shellcheck --severity=warning` on all shell scripts;
`zsh -n` checks `.zsh` files and `zshrc.example`.
- Probe semantics in `lib/verify.sh` are platform-faithful ports — macOS has no
`command -v` fallback for casks/pipx/app-store, Linux falls back everywhere.
Don't "fix" the asymmetry without checking `UNIFICATION.md` history.
- `--dry-run` must print every command without executing anything; it is the
primary cross-platform test mechanism (only one platform can run live).
- App-store packages and `priority: "none"` entries are reminders only — never
auto-installed.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

Useful programs and packages for a computer.

## Setup

One entrypoint installs everything on macOS, Linux desktop (Ubuntu/Arch), and the
Linux server; the platform is auto-detected:

```bash
bash setup.sh [--optional] [--work] [--personal] [--dry-run]
bash setup.sh --profile server # headless server (never auto-detected)
bash setup.sh --platform <macos|ubuntu|arch|server> # force platform
```

Afterwards, check what's installed (read-only):

```bash
bash verify.sh [--optional] [--work] [--personal] [--all]
```

Package data lives in [`packages.json`](packages.json); the engine is
[`lib/core.sh`](lib/core.sh) with per-platform quirks in
[`platforms/`](platforms/). The per-folder `setup.sh` scripts (and the
macOS/linux-desktop `verify.sh`) are thin shims onto these root scripts. See
[UNIFICATION.md](UNIFICATION.md) for the design.

For OS-specific software and install instructions, see:
- [macOS/README.md](macOS/README.md)
- [linux-desktop/README.md](linux-desktop/README.md) — CachyOS
Expand Down
8 changes: 4 additions & 4 deletions SSH_and_GPG/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ NAME="Jane Doe" EMAIL="jane@example.com" EXPIRY="1y" bash create_gpg_key.sh

### `create_ssh_key.sh`

Creates an Ed25519 SSH key for authenticating to a Git host (GitHub, GitLab, Bitbucket, Hugging Face, Forgejo, or custom).
Creates an Ed25519 SSH key for authenticating to a Git host (GitHub, GitLab, Bitbucket, Hugging Face, self-hosted, or custom).

**What it does:**
- Prompts for an email (used as the key comment), Git host, key filename, and optional passphrase
- Generates the key in `~/.ssh/` (skips generation if the key already exists, with an overwrite prompt)
- Adds the key to `ssh-agent` and updates `~/.ssh/config` with a `Host` block (idempotent)
- For Forgejo: writes a `forgejo` alias with `HostName`, `Port 2222`, and `User git` so you can clone as `git clone forgejo:<user>/<repo>.git`
- For self-hosted servers: writes an alias with `HostName`, `Port 2222`, and `User git` so you can clone as `git clone <alias>:<user>/<repo>.git`
- Prints the public key for pasting into the Git host's settings
- Tests the SSH connection after you confirm the key has been added

Expand All @@ -43,8 +43,8 @@ Creates an Ed25519 SSH key for authenticating to a Git host (GitHub, GitLab, Bit
bash create_ssh_key.sh
# or pre-fill inputs via env vars:
EMAIL="jane@example.com" GIT_HOST="github.com" KEY_NAME="github" bash create_ssh_key.sh
# Forgejo (self-hosted):
EMAIL="jane@example.com" IS_FORGEJO=true FORGEJO_HOSTNAME="hostname.ts.net" bash create_ssh_key.sh
# Self-hosted Git server:
EMAIL="jane@example.com" IS_SELF_HOSTED=true GIT_HOSTNAME="hostname.ts.net" GIT_HOST="gitserver" bash create_ssh_key.sh
```

---
Expand Down
29 changes: 16 additions & 13 deletions SSH_and_GPG/create_ssh_key.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ prompt() {
prompt EMAIL "Email (comment in key)"

# ---- Git host selection ----
IS_FORGEJO="${IS_FORGEJO:-}"
FORGEJO_HOSTNAME="${FORGEJO_HOSTNAME:-}"
IS_SELF_HOSTED="${IS_SELF_HOSTED:-}"
GIT_HOSTNAME="${GIT_HOSTNAME:-}"

if [[ -z "$GIT_HOST" ]]; then
echo ""
Expand All @@ -38,7 +38,7 @@ if [[ -z "$GIT_HOST" ]]; then
echo " 2) gitlab.com"
echo " 3) bitbucket.org"
echo " 4) hf.co"
echo " 5) Forgejo (self-hosted)"
echo " 5) Self-Hosted Git Server"
echo " 0) Custom"
read -r -p "Choice [1]: " host_choice
case "${host_choice:-1}" in
Expand All @@ -47,15 +47,18 @@ if [[ -z "$GIT_HOST" ]]; then
3) GIT_HOST="bitbucket.org" ;;
4) GIT_HOST="hf.co" ;;
5)
IS_FORGEJO=true
GIT_HOST="forgejo"
if [[ -z "$FORGEJO_HOSTNAME" ]]; then
read -r -p "Forgejo server hostname (e.g. hostname.ts.net): " FORGEJO_HOSTNAME
if [[ -z "$FORGEJO_HOSTNAME" ]]; then
echo "Error: FORGEJO_HOSTNAME cannot be empty." >&2
IS_SELF_HOSTED=true
if [[ -z "$GIT_HOSTNAME" ]]; then
read -r -p "Server hostname (e.g. hostname.ts.net): " GIT_HOSTNAME
if [[ -z "$GIT_HOSTNAME" ]]; then
echo "Error: GIT_HOSTNAME cannot be empty." >&2
exit 1
fi
fi
if [[ -z "$GIT_HOST" ]]; then
read -r -p "SSH alias for this server [gitserver]: " GIT_HOST
GIT_HOST="${GIT_HOST:-gitserver}"
fi
;;
0)
read -r -p "Git host: " GIT_HOST
Expand Down Expand Up @@ -148,11 +151,11 @@ awk -v host="$GIT_HOST" '
' "$CFG_PATH" > "$tmp_cfg"
mv "$tmp_cfg" "$CFG_PATH"

if [[ -n "$IS_FORGEJO" ]]; then
if [[ -n "$IS_SELF_HOSTED" ]]; then
{
echo ""
echo "Host $GIT_HOST"
echo " HostName $FORGEJO_HOSTNAME"
echo " HostName $GIT_HOSTNAME"
echo " Port 2222"
echo " User git"
echo " AddKeysToAgent yes"
Expand Down Expand Up @@ -182,8 +185,8 @@ read -r -p "Press [Enter] after adding the public key to your $GIT_HOST account.
# ---- Test SSH connection ----
# -T avoids trying to open a shell; -v optional for debugging.
echo ""
if [[ -n "$IS_FORGEJO" ]]; then
echo "Testing SSH connection to Forgejo ($FORGEJO_HOSTNAME:2222) ..."
if [[ -n "$IS_SELF_HOSTED" ]]; then
echo "Testing SSH connection to self-hosted server ($GIT_HOSTNAME:2222) ..."
ssh -T "$GIT_HOST" || true
else
echo "Testing SSH connection to git@$GIT_HOST ..."
Expand Down
130 changes: 94 additions & 36 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TODO

## Setup-script unification (separate PR)
## Setup-script unification (separate PR) — [#36](https://github.com/ulises-c/Computer-Setup/issues/36)

Collapse the three diverged setup stacks (`macOS/`, `linux-desktop/`, `linux-server/`)
into one root `setup.sh` + one `packages.json`, with platform quirks in `platforms/`
Expand All @@ -9,27 +9,103 @@ and a shared `lib/core.sh`. Full spec, schema, and phased breakdown in
keyed by `{macos,ubuntu,arch,server}`), root dispatcher + platform modules, incremental
migration gated on dry-run parity.

- [ ] Phase 1 — Author unified root `packages.json`; build `scripts/parity-check.sh`
- [x] Phase 1 — Author unified root `packages.json`; build `scripts/parity-check.sh`
proving per-platform install lists match the current per-folder scripts
- [ ] Phase 2 — Extract `lib/core.sh` + `platforms/{macos,arch,ubuntu,server}.sh`; add
— 231 checks passed (platform × manager × priority × work/personal combos;
gate deleted in Phase 5 along with its legacy-JSON inputs)
- [x] Phase 2 — Extract `lib/core.sh` + `platforms/{macos,arch,ubuntu,server}.sh`; add
root `setup.sh` dispatcher; gate on `--dry-run` parity vs old scripts
- [ ] Phase 3 — Unify `verify.sh` the same way (shared core + platform checks)
- [ ] Phase 4 — Convert per-folder `setup.sh`/`verify.sh` into thin shims; update
— `scripts/dryrun-parity.sh` passed 22/22 platform × flag combos (gate deleted in Phase 4)
- [x] Phase 3 — Unify `verify.sh` the same way (shared core + platform checks)
— `scripts/verify-parity.sh` passed 21/21 platform × flag combos (gate deleted in Phase 4)
- [x] Phase 4 — Convert per-folder `setup.sh`/`verify.sh` into thin shims; update
`README.md` / `CLAUDE.md` for the root entrypoint
- [ ] Phase 5 — Delete the three old per-folder package JSONs once parity is proven
- [ ] Resolve open questions: server-as-platform vs profile; `install_command`
— shim output diffed byte-identical vs direct root invocation; the script-level
gates (`dryrun-parity.sh`, `verify-parity.sh`) self-compare post-shim and were
deleted (last green run at a8d4149); `scripts/dryrun-smoke.sh` (root dry-run on
all four platforms, also in CI) took their place; `parity-check.sh` stayed
through Phase 5's final green run
- [x] Phase 5 — Delete the three old per-folder package JSONs once parity is proven
— legacy JSONs + `scripts/parity-check.sh` (whose inputs they were) deleted;
server claude-code install folded into `packages.json` (`server: custom`,
`handled_by_setup: true`); custom-package reminders generalized into
`lib/core.sh`, so ubuntu now prints manual-install commands for `git-xet` /
`claude-desktop` instead of silently skipping them (the legacy gap);
dry-run output diffed vs pre-Phase-5 baseline — identical except that addition
- [x] Resolve open questions: server-as-platform vs profile; `install_command`
string vs object; keep `priority: "none"` tier? (see UNIFICATION.md)

## Ghostty config standardization

The ghostty config lives in two places (`macOS/ghostty.config`, `linux-desktop/ghostty.config`)
with identical content. Consider extracting a universal `cross-platform/ghostty.config` for shared
settings (`term = xterm-256color`, `theme`, `shell-integration`) and keeping OS-specific
configs additive-only (e.g., macOS font settings, Linux-specific tweaks).

- [ ] Create `cross-platform/ghostty.config` (universal base)
- [ ] Refactor OS configs to extend/override the universal base
- [ ] Update both `setup.sh` scripts to deploy the new layout (universal + OS overlay)
— resolved: server is a platform key (option A, locked in Phase 1);
`install_command` supports both string and per-platform object (`icfor`);
`priority: "none"` tier kept — reminder/`--all`-only, never auto-installs
- [x] Phase 6 — Merge main (PRs #28 p10k/LACT, #35 railguard, #38 claude-hud) into
the branch; port the features that landed on the legacy stack into the unified
one: `zsh-theme-powerlevel10k` + `lact` entries into root `packages.json`,
`~/.p10k.zsh` deploy (`deploy_config`) into the shared desktop flow.
Legacy `linux-desktop/setup.sh` stayed a shim; the legacy JSON stayed deleted.
Gate: per-platform dry-run diff vs pre-merge baseline — only the intended
additions (two arch packages, p10k deploy lines)
- [x] Phase 7 — Dotfiles consolidation (details in the section below): shared
`tmux.conf`/`ghostty.config` moved to `dotfiles/`, all engine deploys
repointed, macOS gains the previously missing tmux deploy.
Gate: per-platform dry-run diff vs pre-change baseline — identical except
macOS's new tmux step

## Dotfiles consolidation — DONE as unification Phase 7 (PR #37)

Shared configs were duplicated per-folder and could drift silently across devices.
Folded into #37 once the root engine owned all deploys.

- [x] Create `dotfiles/` and move the byte-identical files: `tmux.conf`, `ghostty.config`
- [x] Point the root engine's deploy steps (`lib/core.sh`, `platforms/macos.sh`,
`platforms/server.sh`) at the new paths; drop the per-folder copies
- [x] Deploy tmux.conf on macOS too (was the missing platform — Macs showed the
default green bottom bar while Linux boxes got the blue top bar)
- [x] Ghostty: single universal config in `dotfiles/` (the two copies were already
byte-identical); no overlay mechanism until an OS-specific setting actually
exists
- [x] zshrc: `dotfiles/zshrc.example` is the shared base (`deploy_zshrc`); a platform
folder shipping its own `zshrc.example` overrides it — only `linux-server/`
does, because it's headless (no Ghostty/fastfetch/notification hooks)
- [x] macOS zsh unification: the dotfiles zshrc is cross-platform (macOS bits guarded
on `/opt/homebrew`/`$OSTYPE` — Homebrew PATH+FPATH, brew p10k/antidote/fzf
paths, `ls -G`, `brewup`, `PIPX_DEFAULT_PYTHON`, nvm `--delete-prefix`); macOS
deploys it + `dotfiles/zsh_plugins.txt` via the engine instead of appending
lines to `~/.zshrc` (`add_to_zshrc` deleted). antidote/zoxide/fzf/bat/fd/
terminal-notifier gained `macos: brew` entries; the brew
zsh-autosuggestions/zsh-syntax-highlighting entries were dropped (antidote
manages the plugins now — `brew uninstall` them on the Mac after migrating).
`macOS/zshrc.example` + `zshrc-upgrade.md` deleted (plan absorbed)
(e.g., macOS font settings, Linux-specific tweaks)
- [ ] Mac mini live-run cleanup (from the 2026-06 `brew leaves` audit): `brew
uninstall` the testing leftovers `forgejo`, `tea`, and `python@3.12`
(project Pythons come from pyenv/uv), plus `zsh-autosuggestions` /
`zsh-syntax-highlighting` / `powerlevel10k` (antidote manages them now),
and `brew uninstall --cask claude-code` (repo installs it via curl)
- [ ] MBP live-run cleanup (same audit): `brew uninstall tea python-tk@3.11
python@3.11 zsh-autosuggestions zsh-syntax-highlighting powerlevel10k`;
pre-existing casks (anki, ghostty, obsidian) get picked up by the cask
`--adopt` flag
- [x] Ubuntu desktop live run (2026-06, at `eb0fe49`): gh migrated to the
official cli.github.com apt repo, micro/obsidian snaps in, uv via pipx,
shared zshrc + p10k + ghostty deployed (zshrc auto-backup worked).
`verify.sh --work` green except the by-design manual installs
(forgejo-cli, opencode, zen-browser, anki)
- [x] Ubuntu live-run follow-up: p10k never loaded — the only installer was the
arch-only `zsh-theme-powerlevel10k` yay entry, so Ubuntu/macOS fell back to
vcs_info. Dropped the entry; `romkatv/powerlevel10k` is now an antidote
plugin on all desktops and the zshrc guards the fallback on
`$+functions[p10k]`
- [ ] Dropped when PR #38 auto-closed #34: track the claude-hud display config
(`~/.claude/plugins/claude-hud/config.json`) under `agentic-ai/Claude/` and
symlink it from `install.sh` (#34 task 2). Task 3 — the statusLine
`/usr/bin/node` hardcode — is fixed on this branch (runtime `command -v
node` with an nvm-glob fallback)
- [ ] Ubuntu desktop leftover: `sudo apt remove micro` — the stale apt 2.0.13
still shadows the snap (`/usr/bin` precedes `/snap/bin` in PATH)
- [ ] Caveat for the remaining live runs (CachyOS, both Macs): setup migrates
install methods but never uninstalls the old copy — after each run,
`command -v` every migrated tool to catch shadowed binaries
- [ ] Later: consider base + per-platform overlay for zshrc (desktop vs server vs macOS)

## OpenCode local models

Expand All @@ -45,24 +121,6 @@ Still to explore:
- [ ] Consider `small_model` for lightweight tasks (title gen, etc.)
- [ ] Install `opencode-local` via install.sh and verify PATH

## macOS zshrc modernization

Port the linux-desktop zsh enhancements to the macOS config. See
[macOS/zshrc-upgrade.md](macOS/zshrc-upgrade.md) for the full plan.

- [ ] Switch from manual Homebrew plugin sourcing to antidote
- [ ] Add eza aliases with `--icons --group-directories-first`
- [ ] Add RPROMPT with command duration
- [ ] Add colorized man pages via bat
- [ ] Add zsh-notify for desktop notifications on long commands
- [ ] Add fish-style abbreviations via zsh-abbr
- [ ] Add zsh-history-substring-search with Up/Down keybindings
- [ ] Add grouped completion descriptions
- [ ] Add path underlining in syntax highlighting
- [ ] Add zoxide init
- [ ] Add FZF keybindings and completion (Homebrew paths)
- [ ] Create macOS zsh_plugins.txt

## linux-desktop (personal) — CachyOS / Arch

Test and validate the linux-desktop setup on the personal CachyOS desktop
Expand Down
Loading
Loading