pi-keepawake1.0.2
Keep the host from idle sleeping while a pi process is running. Blocks system sleep only — display sleep and the lock screen still work.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-keepawake
English | 简体中文
一个 pi 扩展:只要还有 pi 进程在运行,电脑就不会进入睡眠/休眠。 熄屏(显示器休眠)和锁屏照常工作,不做任何干预。
零配置:装好就生效。MIT 许可。
特性
- 进程级语义:从
session_start持有到session_shutdown,也就是「pi 还开着就拦睡眠」。 每个 pi 进程各持一把独立的 OS 断言,由操作系统聚合 —— 开 3 个 pi,关掉 2 个,机器照样不睡。 - 只拦系统睡眠:不加
ES_DISPLAY_REQUIRED(Windows)、不加-d(macOS)、 不拦idle/handle-lid-switch(Linux)。熄屏可以,锁屏可以。 - 零配置:无 flag、无环境变量、无命令。
- fail-safe:容器里、没有 PowerShell、平台不支持时,pi 照常运行,只在 TUI 里警告一次。
- 跨平台:Windows / macOS / Linux 都走系统自带机制,不需要管理员权限、没有 native addon、不需要 node-gyp。
- 可观测:TUI footer 显示
☕ keep-awake;底层 helper 进程和命令行都能直接查(见下文)。 - 不残留:正常退出、Ctrl-C、
process.exit()都会释放;OS 原语被杀后会自动重挂。每次 reload / 会话切换之后的session_start会先清扫「同一 pi 进程内上一个运行时」遗留的 helper, 所以 reload 不会多留一把锁。
安装
需要 Node.js ≥ 20(pi 自带)。
1. 从 npm 安装(推荐)
pi install npm:pi-keepawake
2. 从 Gitee 安装
pi install git:gitee.com/zxh126/pi-keepaware
以上两种方式 pi 都会自动安装依赖(pervigil)。装完 pi list 能看到它,/reload 生效。
需要钉死版本时写全:pi install npm:pi-keepawake@1.0.0。
3. 手动放进用户扩展目录
git clone https://gitee.com/zxh126/pi-keepaware "$HOME/.pi/agent/extensions/keep-awake"
cd "$HOME/.pi/agent/extensions/keep-awake" && npm install
Windows 对应路径是 %USERPROFILE%\.pi\agent\extensions\keep-awake。
pi 会自动发现 extensions/ 下所有含 index.ts 的子目录。
本地目录形式的包 pi 不会替你装依赖,所以这一步的
npm install不能省。
4. 只试用一次
pi -e npm:pi-keepawake
pi -e git:gitee.com/zxh126/pi-keepaware
pi -e ./pi-keepawake # 本地路径,需先 npm install
卸载
pi remove npm:pi-keepawake
pi remove git:gitee.com/zxh126/pi-keepaware
或者直接删掉 ~/.pi/agent/extensions/keep-awake 目录。
它到底做了什么
扩展本身只负责「什么时候持有/释放」;真正和操作系统打交道的是 pervigil(零依赖、无 native addon、MIT)。
| 平台 | 机制 | 具体参数 |
|---|---|---|
| Windows | 一个 PowerShell 子进程调用 SetThreadExecutionState,然后阻塞住保住该线程 |
ES_CONTINUOUS | ES_SYSTEM_REQUIRED(没有 ES_DISPLAY_REQUIRED) |
| macOS | caffeinate(1) |
-i(没有 -d) |
| Linux | systemd-inhibit(1),没有 systemd 时退回 /sys/power/wake_lock |
--what=sleep --mode=block(没有 idle、handle-lid-switch) |
生命周期:
session_start ──▶ acquire ──▶ [ 整段会话都持有 ] ──▶ session_shutdown ──▶ release
│
└─ helper 意外死亡 ⇒ primitiveDied ⇒ 自动重挂(最多 5 次)
补充说明:
- 不用改电源计划(
powercfg)、不用 presentation mode、不模拟输入 —— 所以锁屏和屏保都不会被顶掉。 - 用户主动点「睡眠/休眠」不会被阻止,这是系统断言的语义,也是本扩展刻意保留的行为。
- 容器里(
/.dockerenv、container环境变量等)pervigil 直接 no-op,不会报错。
验证它在工作
最直观的:pi 的 footer 出现 ☕ keep-awake。
命令行验证(用系统自身的视角看断言是否存在):
Windows(PowerShell,无需管理员)
Get-CimInstance Win32_Process -Filter "Name='powershell.exe' OR Name='pwsh.exe'" |
Where-Object { $_.CommandLine -like '*Pervigil*' } |
Select-Object ProcessId, ParentProcessId,
@{ n = 'flags'; e = {
@(
if ($_.CommandLine -match 'ES_SYSTEM_REQUIRED') { 'ES_SYSTEM_REQUIRED' }
if ($_.CommandLine -match 'ES_DISPLAY_REQUIRED') { 'ES_DISPLAY_REQUIRED' }
) -join ','
} }
pi 运行期间应该恰好出现一个 helper,flags 为 ES_SYSTEM_REQUIRED(不含 ES_DISPLAY_REQUIRED);
pi 退出后它应该消失。
powercfg /requests也能看到 request,但它需要管理员权限,普通终端里跑会直接报错。
macOS
pmset -g assertions | grep -i caffeinate
Linux
systemd-inhibit --list | grep -i pi
已知限制
- Windows 上常驻一个 PowerShell 进程(实测 WorkingSet ≈ 74 MB / Private ≈ 59 MB)—— 这是「整个会话都持有」这个语义的直接成本,pi 退出时回收。
- Linux 需要 systemd 用户会话(
systemd-inhibit)或可写的/sys/power/wake_lock;否则降级为 no-op 并警告一次。 - 不阻止合盖休眠(Linux 的
handle-lid-switch未加入 inhibitor)、不阻止用户主动睡眠。 - 仅本仓库在 Windows 11 实机上验证过(helper 出现/释放、多进程聚合、helper 被杀后重挂、硬杀不残留)。 macOS / Linux 的代码路径按 pervigil 的语义核对过,但没有实机运行记录。
- pi 被以无法被捕获的方式强杀(TerminateProcess / OOM)时,扩展自身的清理钩子不会执行;
本机上实测 helper 会随父进程一起消失,另外扩展在每次
session_start时会顺手清理 「父进程是本进程」的遗留 helper(reload 未能走session_shutdown的情况)以及「父进程已死」的 历史 helper 作为兜底;其他存活进程的 helper 一律不动。
开发
pi-keepawake/
├── index.ts # 扩展本体(唯一源码)
├── package.json # pi 清单:pi.extensions -> ./index.ts,依赖 pervigil
├── LICENSE # MIT
├── README.md # 英文版
└── README.zh-CN.md # 本文件
- 扩展运行在 pi 进程内,走 pi 的 jiti loader,不需要编译。
- 只有
pervigil一个运行时依赖;pi 提供的@earendil-works/*包只用import type,不进dependencies。 - 改完在 pi 里
/reload即可生效;想临时试装可以pi -e <本地路径>。
涉及的关键 pi 事件:session_start(创建 wake lock 控制器并 acquire)、
session_shutdown(释放并清 footer 状态)。运行期复用 pervigil 的
primitiveDied / degraded 事件做重挂与告警。
发布流程(维护者):改 package.json 的 version → 提交 → 推 Gitee → npm publish --registry=https://registry.npmjs.org
(本机 .npmrc 的默认 registry 指向 npmmirror 镜像,只影响安装、发布必须显式指定官方源)。
依赖与致谢
License
MIT © 2026 zxh126