`caffeinate -i` blocks system idle sleep but lets the display blank, so the
screen still slept and the extension looked broken. The "Also Prevent Display
Sleep" preference that fixes this defaulted to off.
Flip it to on, and guard it with a manifest test that reads package.json and
asserts the shipped defaults map to `-i -d`. Verified on macOS: `caffeinate -i`
yields PreventUserIdleDisplaySleep 0, `caffeinate -i -d` yields 1.
Durations were the only thing keeping a lot of machinery alive, so drop
them and let the dead code go with them.
Removed:
- The "Caffeinate for a Duration" command.
- lib/duration.ts entirely (parseDuration / formatDuration /
formatRemaining / normalizeDuration / DURATION_PRESETS) plus its test
file. Every export was reachable only from duration paths.
- The 30s setInterval re-render in the status view. It existed only to
keep a "27m left" countdown honest, and with no timed sessions there is
nothing to count down.
- The duration-preset actions in the status view.
- describeOptions(), which only the duration form used to explain itself.
- durationSeconds / expiresAt from the options, state and command
builder, along with the `-t <seconds>` and `sleep <n>` branches. Both
platforms now hold the assertion until signalled, which is what "on"
means here.
- The unused "restarted" member of ToggleResult.
The status view now reports "since <time>" instead of a countdown, and
keeps a Refresh action.
Also fixes a type error the narrower helper surfaced: the status view's
run() helper was typed () => Promise<void> while startCaffeination
returns Promise<CaffeinateState> and stopCaffeination returns
Promise<boolean>.
407 deletions against 57 insertions.
Verified: vici lint, tsc --noEmit, eslint, 8/8 vitest, vici build, and
live in Vicinae — toggle on spawns `caffeinate -i`, toggle off stops it,
and a pre-existing user-owned `caffeinate -u -dmi` is left untouched
throughout.
Keeps the computer awake from Vicinae. Written against @vicinae/api
directly because the Raycast `coffee` extension cannot work here:
- Its `index` command is `menu-bar` mode, which Vicinae does not support.
- Its `status` command crashes on `Cannot read properties of null
(reading 'IsManuallyDecafed')` because it gates on
`LocalStorage.getItem(key) === undefined`. Vicinae resolves a missing
key to `null`, not `undefined` (verified with a runtime probe).
Sleep prevention is an OS-level assertion, so the extension delegates and
gets out of the way:
- macOS: caffeinate -i [-d] [-s] [-t <seconds>]
- Linux: systemd-inhibit --what=idle:sleep --why=<reason> sleep <n|infinity>
The process is spawned detached + unref'd, because Vicinae unloads a
no-view command as soon as its function returns. Timed sessions need no
babysitter: `caffeinate -t` and `sleep <n>` self-terminate.
Commands: toggle (no-view), status (view), caffeinate-for (view).
Two deliberate safety choices:
- Stopping signals the recorded PID rather than running `killall
caffeinate`, so a caffeinate the user started themselves survives.
Verified against a real concurrent `caffeinate -u -dmi` process.
- The PID's name is re-checked with `ps -o comm=` before signalling, since
PIDs get recycled and a stale entry could otherwise kill something
unrelated.
Also: display-sleep prevention is macOS-only, and the UI says so on Linux
rather than pretending systemd-inhibit can hold the display awake.
Verified: vici lint, tsc --noEmit, eslint, 23/23 vitest, vici build, and
live in Vicinae — toggle starts `caffeinate -i` which survives the
command unloading, toggle again stops only ours, both view commands load
with clean stdout/stderr.