feat(sleep-guard): keep the host device awake while IDBots is working - #13
Open
WuFenG-Hub wants to merge 2 commits into
Open
feat(sleep-guard): keep the host device awake while IDBots is working#13WuFenG-Hub wants to merge 2 commits into
WuFenG-Hub wants to merge 2 commits into
Conversation
added 2 commits
August 12, 2026 13:39
Prevents OS sleep from interrupting running harness work. The main process engages Electron's powerSaveBlocker (prevent-app-suspension) only while at least one work source is active — cowork sessions, running scheduled tasks, nightly dreams — and releases it as soon as everything is idle. - src/main/sleepGuard.ts: pure DI policy + stateful guard (unit-testable) - main.ts wiring: singleton, 20s self-healing refresh, instant triggers on session start/stop and runner complete/error, IPC powerGuard:status and powerGuard:changed broadcast, dispose on cleanup - preload + electron.d.ts: powerGuard API for the harness frontend - Sidebar SleepGuardBadge: shown while engaged, hidden when idle - tests/sleepGuard.test.mjs: 8/8 pass (fake blocker, pure DI) - scripts/sleep-guard-real-host-check.cjs: real-Electron closed loop, 7/7 pass incl. macOS pmset assertion PreventUserIdleSystemSleep (both directions) Also removes a stale unused eslint-disable directive in MetaBotEditTabs.tsx that broke npm run lint on the main baseline (lint-blocker fix).
- keep powerGuard:status IPC handler alongside upstream store:changed broadcast - keep startSleepGuardRefresh() in window ready-to-show; upstream moved tray/scheduler init into didInitAppOnce single-run block - keep both Sidebar imports (SleepGuardBadge + upstream BackgroundTasksBadge) - drop redundant eslint-disable in opcatInscribe.ts (upstream baseline lint blocker)
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.
What
Keep the host device awake while IDBots is actively working, so OS sleep never
interrupts running harness work (bot/cowork sessions, scheduled tasks, nightly
dreams). The main process engages Electron's
powerSaveBlocker(
prevent-app-suspension) only while at least one work source is active,and releases it as soon as everything is idle — the OS sleep policy is
untouched outside actual work.
Changes
src/main/sleepGuard.ts(new) — pure, dependency-injected guard: policy(
evaluateSleepGuardWork) + idempotent statefulSleepGuardclass. No directelectronimport, fully unit-testable.src/main/main.ts— wiring: singletongetSleepGuard(),recomputeSleepGuard()over the live work sources (cowork sessions via
getActiveSessionIds(),scheduled tasks via new
Scheduler.getActiveTaskIds(), dreams viagetDreamingBotIds()), instant triggers on cowork session start/stop andrunner complete/error, a 20s periodic safety refresh (self-heal), IPC
powerGuard:statushandle +powerGuard:changedbroadcast, and release onapp cleanup.
src/main/preload.ts+src/renderer/types/electron.d.ts—powerGuardAPI surface for the harness frontend.
src/renderer/components/SleepGuardBadge.tsx(new) +Sidebar.tsx— amber"防休眠中" badge shown while the guard is engaged, hidden when idle, tooltip
lists the active sources.
tests/sleepGuard.test.mjs(new) — 8 unit tests, all pass (fake blocker,pure DI, no Electron stub needed).
scripts/sleep-guard-real-host-check.cjs(new) — real-Electron closed-loopcheck driving the compiled module with the real
powerSaveBlocker.Also fixes a pre-existing lint blocker on
main: a stale unusedeslint-disable-next-line react-hooks/exhaustive-depsinMetaBotEditTabs.tsxthat failednpm run lint(0-warnings gate).Verification (all actually run, not code-assertion only)
npm run lint— 0 errors, 0 warningsnpm run compile:electron+npm run build— passnode --test tests/sleepGuard.test.mjs— 8/8 passnode_modules/.bin/electron scripts/sleep-guard-real-host-check.cjson macOS):pmset -g assertionsshows the OS-levelPreventUserIdleSystemSleepassertion — system-level evidence, not anin-process self-report
Notes / honest scope
cowork,scheduledTask,dream. A dedicatedgroupTasksource (orchestration daemon) has no ready API onmain(only a raw DB query in
cognitiveOrchestrator); orchestration turns mostlyrun inside cowork sessions, which are already covered. An
agentGamesourceis not applicable: that module does not exist on the
mainbaseline. The20s refresh self-heals anything event-driven updates miss.
live session) was not performed in this pass; the closed-loop script drives
the same code path against the real runtime, and the badge is a thin
renderer subscription to the verified IPC surface.