Add systemd --user backend for WorkSweep scheduling on Linux - #1692
Open
takanorinishida wants to merge 2 commits into
Open
Add systemd --user backend for WorkSweep scheduling on Linux#1692takanorinishida wants to merge 2 commits into
takanorinishida wants to merge 2 commits into
Conversation
InstallWorkSweep.ts only supported launchd, so the hourly WorkSweep sub-sweeps (session catch-up, stale flagging, project checks, TELOS goal derivation) had no way to run on Linux even though WorkSweep.ts itself is already platform-neutral (existsSync/readFileSync/Bun.spawn, no macOS-specific calls). Adds a systemd --user code path selected via process.platform, mirroring the pattern PULSE/manage.sh already uses for Pulse itself (launchd on darwin, systemd --user on linux). Two new unit templates (com.lifeos.worksweep.service.template + .timer.template) pair with the existing plist template; OnBootSec=2min + OnUnitActiveSec=60min + Persistent=true reproduce the plist's RunAtLoad + StartInterval 3600 behavior. Enables linger for the user so the timer survives logout, same requirement documented for com.lifeos.pulse. Verified end-to-end on a Linux host: install/--status/--uninstall all work via `systemctl --user`, and a live run of WorkSweep.ts under the resulting timer created labeled issues successfully. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
process.env.USER isn't guaranteed to be set in every environment that might invoke this installer (some non-interactive shells don't inherit it), which would pass an empty string to `loginctl enable-linger ""` and fail. Adds a `username()` helper (id -un, mirroring the existing uid() helper's `id -u`) and uses it instead — reliable regardless of the calling environment. Verified on the same Linux host as the original PR: re-ran `install` and `--status` after the change, both succeeded, and `loginctl show-user` confirmed `Linger=yes`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WorkSweep.ts(the hourly Work System sweep — session catch-up, stale-issue flagging, project checks, TELOS-goal derivation) is already platform-neutral: it only usesexistsSync/readFileSync/Bun.spawn, no macOS-specific calls. ButInstallWorkSweep.ts, the script that schedules it, only knew how to talk to launchd. On Linux there was no way to get WorkSweep running on a recurring cadence at all.This PR adds a
systemd --userbackend selected viaprocess.platform, mirroring the patternLIFEOS/PULSE/manage.shalready uses for Pulse itself (launchd on darwin,systemctl --useron linux). Two new unit templates pair with the existing plist template:com.lifeos.worksweep.service.template— oneshot service that runsWorkSweep.ts, same log target (MEMORY/STATE/com.lifeos.worksweep.log) as the launchdStandardOutPath/StandardErrorPathcom.lifeos.worksweep.timer.template—OnBootSec=2min+OnUnitActiveSec=60min+Persistent=true, reproducing the plist'sRunAtLoad+StartInterval 3600behaviorInstallWorkSweep.tsnow branches onprocess.platform: the existing darwin/launchd code path is untouched, and a new linux/systemd path materializes both templates into~/.config/systemd/user/, runsdaemon-reload, callsloginctl enable-linger(same survives-logout requirement already documented forcom.lifeos.pulse), andenable --nows the timer.--uninstalland--statusget matching linux branches.Update: a code review caught that the
loginctl enable-lingercall originally read the username fromprocess.env.USER, which isn't guaranteed to be set in every invoking environment (some non-interactive shells don't inherit it) — an empty string would make the call fail. Fixed by adding ausername()helper (id -un, mirroring the existinguid()helper'sid -u) and using that instead. Re-verified end to end after the fix (see testing evidence below).Testing evidence
Verified end-to-end on a real Linux host (Ubuntu, systemd):
Also confirmed
--uninstallcleanly disables + removes both unit files and--statusreports the timer's next-run time. The macOS/launchd path is unchanged — only newif (IS_LINUX)branches were added, so no risk of regression for existing darwin installs.After the
username()fix: re-raninstalland--status, both succeeded, andloginctl show-userconfirmedLinger=yes.🤖 Generated with Claude Code