Uh oh!
There was an error while loading. Please reload this page.
feat(plans): 保持系统唤醒 — real powerSaveBlocker capability for scheduled tasks - #1207
Merged
Conversation
Scheduled reminders run off an in-process timer that freezes when the
machine sleeps, so tasks silently never fire. Add a keepSystemAwake
setting that holds an Electron powerSaveBlocker to keep background
scheduled work running.
- core: add SystemSettings { keepSystemAwake } to AppSettings, mirroring
notifications.runComplete end to end (default, merge, patch surface,
fail-closed boolean coercion in normalizeSettings) + contract tests.
- main: keep-system-awake controller wraps powerSaveBlocker with
'prevent-app-suspension' (system stays awake WITHOUT forcing the
display on) — Electron-free + injected blocker so it unit-tests under
node --test, with a double-start guard on the blocker id.
- wiring: apply on launch if enabled, start/stop the instant the toggle
flips via applySettingsRuntimeEffects (rides the existing settings
channel), and reconcile on external settings.json edits.Replace the placeholder-honesty gap (designer audit P1-5) with the real control: an informational row above the plan list — Info icon + 定时任务 仅在电脑保持唤醒时运行 copy, right-aligned 保持系统唤醒 label + switch. - Status-color restraint: neutral passive surface (settingsNotice passive recipe: --foreground-5 / --muted-foreground, hairline border, radius-surface), NOT the reference's saturated blue banner. Replaces the old maka-plan-system-alert accent recipe. - Switch reflects reality: optimistic local state initialized from the persisted snapshot, revert-on-error + Chinese toast, useMountedRef + pending-ref guard so a slow IPC write can't double-fire or set state after unmount. - Fail-soft: the row hides entirely unless the host wires both the value and the setter (bridge present). - Re-pin the panel async-action contract with the new toggle invariants.
- use-keep-system-awake hook reads/writes settings.system.keepSystemAwake over the existing settings:get/update bridge (no new IPC channel), gating on runtime bridge presence for fail-soft on older mains. - app-shell threads the value + setter into AutomationsPage; the panel hides the row when the capability is unavailable. - AutomationsPage forwards the keepSystemAwake props to PlanReminderPanel.
Uh oh!
There was an error while loading. Please reload this page.
jackwener added a commit
that referenced
this pull request
Jul 19, 2026
…ain.ts (arch R5) (#1248) * chore(main): extract settings-runtime-effects from main.ts (arch R5) Pure move of main.ts's settings runtime-effects cluster into settings-runtime-effects.ts, exporting createSettingsRuntimeEffects(deps) → { normalizeSettingsPatch, applySettingsRuntimeEffects, handleExternalSettingsChange } (syncDefaultPermissionModeToSessions stays internal). Follows the R4 tool-assembly / tool-artifact-persistence DI precedent: settingsStore / botRegistry / openGateway / keepSystemAwake / runtime / safeSendToRenderer / emitSessionsChanged are injected, bodies byte-identical. keep-awake runtime-effect (#1207) rides applySettingsRuntimeEffects unchanged. Contract mechanics: add settings-runtime-effects.ts to the main-process-contract-source-helpers aggregator; allowlist the moved [config-watcher] console.error at its new path in check-console.mjs. No source-pin test targeted these functions in main.ts directly. * chore(main): extract session-stream core from main.ts (arch R5) Pure move of main.ts's session-stream cluster into session-stream.ts: - createAiSdkBackendFactory(deps): BackendFactory — the whole backends.register('ai-sdk', …) closure plus the internal modelSupportsVision. Two seams resolved after the registration point are injected as accessors: getRuntime (SessionManager built later) and getLookupPricing (mutable pricing lookup, read live per recordLlmCall / snapshotted once for the lookupPricing field — matching the original module-let closure semantics exactly). - createSessionStreamer(deps): StreamEvents — streamEvents + its two event-classifier helpers and the StreamEventsOptions/Result types. main.ts keeps the module-scoped seams it owns (backends.register call site, sessionActivities, lookupPricing let, runtime, the fake/e2e backend registers) and every streamEvents call site. Contract re-pins (maintainer-authorized): add session-stream.ts to the main-process-contract-source-helpers aggregator; switch three direct-main.ts readers to the combined source keeping every assertion — attachment-frontend-contract (modelSupportsVision + supportsVision vision pin), ipc-surface-contract (memoryPromptSnapshot + buildBackendSystemPrompt), web-search-telemetry-scrub-contract (argsSummary scrub). registerIpc / main-process-wiring-contract untouched. main.ts 1656 → 1372 (−284 across both R5 clusters). * docs(arch): mark R5 shipped (main.ts −284, settings-runtime-effects + session-stream)
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 freeto 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.
User-requested: the 定时任务 page lacked the keep-system-awake notice + toggle + capability (a 即将支持 placeholder was removed earlier for placeholder honesty — this ships the real thing).
End-to-end
system.keepSystemAwakeon AppSettings (default false), modeled on notifications.runComplete — merge/patch/fail-closed coercion + core tests.prevent-app-suspension(system stays awake, display may sleep — the right mode for background scheduled work). Double-start guard, re-acquire after out-of-band release; 7 unit tests with mocked electron.Verification
Live CDP: click → aria-checked true → stayed true (full path exercised: optimistic → settings:update → powerSaveBlocker.start). Light+dark captures both states, accepted by maintainer. plan-reminder-panel contract extended (new pins for duplicate-guard/revert/unmount-release), nothing deleted.
Gates (merged tree with main incl. #1205)
desktop 2709/2709 · ui 183/183 · core green · typecheck · check-dead-css · knip no new debt · alignment auditor all fixtures clean. Implemented by an opus worktree agent.