feat(launchd): durable LaunchAgent for codex_session daemon#1
Conversation
Mirrors the conductor-tick launchd pattern (home-lab launchd/): - plist template with __REPO_ROOT__/__HOME__/__PYTHON3__ placeholders - install script resolves python3, expands template, bootstrap/enable/verify - uninstall script is idempotent bootout + plist removal - README explains KeepAlive (long-running daemon) vs StartInterval (one-shot every N seconds) — codex_session is the former, conductor- tick is the latter Smoke verified: install bootstraps cleanly, daemon respawns on kill, signal files appear at ~/.cache/claude-tab-status/codex-*.json.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 27e4b71a97
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| -e "s|__REPO_ROOT__|${REPO_ROOT}|g" \ | ||
| -e "s|__HOME__|${HOME}|g" \ | ||
| -e "s|__PYTHON3__|${PYTHON3}|g" \ |
There was a problem hiding this comment.
Escape paths before substituting the plist template
When the checkout or home directory contains sed replacement metacharacters (for example a path like /Users/me/R&D/iterm2-tab-status or a volume/folder name containing |), these raw replacements either expand & back to the matched placeholder or break the sed expression, so the installed plist points at a non-existent script/log path or fails to bootstrap. Escape the replacement strings (and XML string content) before writing the LaunchAgent plist.
Useful? React with 👍 / 👎.
Summary
Brings the codex tab status signal producer under launchd supervision, mirroring the conductor-tick launchd pattern in
~/code/home-lab/launchd/.Three new files in
launchd/:com.local.codex-tab-status.plist— template with__REPO_ROOT__/__HOME__/__PYTHON3__placeholdersinstall-codex-tab-status-launchd.sh— resolves python3, expands template,launchctl bootstrap gui/$UID, verifiesuninstall-codex-tab-status-launchd.sh— idempotent bootout + plist rmREADME.md— manage / status / why-KeepAlive-not-StartIntervalWhy KeepAlive
codex_session.py --daemonis a long-running poll loop.KeepAlive=true(respawn on crash) is the right primitive. Compare conductor-tick which is one-shot per 120s and usesStartInterval=120instead.Test plan
launchctl)KeepAliveverified)~/.cache/claude-tab-status/codex-*.jsonwithin seconds