# 阿德拉菲尼尔：仅在AI agent工作时阻止Mac睡眠的菜单栏工具

- 来源：Hacker News 热门（buzzing.cc 中文翻译）
- 作者：kageroumado
- 发布时间：2026-06-28 11:55
- AIHOT 分数：72
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.virxact.com/items/cmqx9k72u0425slp05ijlfezl
- 原文链接：https://github.com/kageroumado/adrafinil

## 精选理由

阿德拉菲尼尔对macOS唤醒工具做了一次有趣的重新思考，不是一直醒着，而是只在AI代理工作时醒着，合盖也能跑长任务，对用Claude Code或Cursor的开发者是实用的开源伴侣。

## AI 摘要

Adrafinil 是一款 macOS 菜单栏应用，仅在 Claude Code、Codex、Cursor、Gemini CLI、Aider、Hermes、OpenCode、Cline、Pi 等 9 种 AI coding agent 持有活跃会话时阻止系统睡眠（包括合盖睡眠）。无 agent 工作时，合盖后 Mac 正常睡眠。它通过各 agent 的钩子系统调用 CLI，往返延迟低于 50ms，支持引用计数断言、热切出（温度阈值强制释放）、空闲释放及进程嗅探。需要 macOS Tahoe 26.4，Xcode 26+ 构建，以签名公证的磁盘映像提供。

## 正文

阿屈非尼

处方编号 006 ・ 阿·屈·非·尼 /əˈdræfɪnɪl/ ・ 一种用于机器的优觉药 ♡

清醒 ・ 智能体正在工作 睡眠 ・ 无智能体，正常睡眠

服用注意 ・ 适用于你入睡后仍需值守的机器。

凌晨三点。你正在熟睡。智能体却没有——它仍在你数小时前启动的会话中思考，而你已经合上了笔记本盖，就像一只无法完全闭合的眼睑。caffeinate 和 Amphetamine 是兴奋剂：它们让机器永远保持通电状态，无论是否有人在用。阿屈非尼是优觉药。它本身不做任何事，直到智能体获取它；它只在任务存续期间让你的 Mac 在合盖状态下保持清醒，并在最后一个会话释放时立即清除。它只为工作而唤醒——然后你们一同安睡。♡

仅在 AI 智能体工作时保持 Mac 清醒。

Adrafinil 是一款 macOS 菜单栏应用，它能阻止系统进入睡眠——包括合盖睡眠——但仅限于 AI 编程智能体有活跃会话时。当没有智能体工作时，睡眠行为不受影响：合上盖子，Mac 正常进入睡眠。

它与 caffeinate 或 Amphetamine 这类始终唤醒的实用工具相反。Adrafinil 仅在智能体（Claude Code、Codex、Cursor……）处于任务中时介入，并在任务完成的那一刻退出。

⚠️ 特权级睡眠控制。覆盖合盖睡眠需要 root 权限。Adrafinil 将此功能隔离在一个小巧且经过审计的辅助程序中，该程序仅暴露 setSleepBlocked(Bool) 接口——所有策略逻辑运行在无特权的守护进程中。它持有标准的 IOPMAssertion 用于空闲睡眠，并在验证设备上更干净的私有 IOPMrootDomain 路径无法让无显示器的合盖 Mac 保持清醒后，使用 pmset disablesleep 来控制合盖睡眠。详见 Docs/ARCHITECTURE.md §2。

功能特性

智能体感知，而非始终开启。仅当 ≥1 个智能体会话持有断言时才会阻止睡眠。零会话 → 正常睡眠，包括合盖睡眠。

支持 9 种智能体的钩子集成。一键安装程序将 Adrafinil 接入 Claude Code、Codex、Cursor、Gemini CLI、Aider、Hermes、OpenCode、Cline 和 Pi 的钩子系统。

亚 50 毫秒 CLI。adrafinil acquire / release 通过智能体钩子调用，与守护进程往返耗时低于 50 毫秒，因此绝不会阻塞智能体的工作流程。

引用计数式断言。重叠会话可干净地堆叠；仅当最后一个会话释放时，休眠状态才会解除。

过热切断保护。若合盖状态下皮肤/CPU 温度超过阈值，所有断言将被强制释放，防止装在包里的 Mac 因过热自毁。

空闲释放。若拥有断言的进程已终止或 CPU 空闲超过 N 分钟，该断言将自动丢弃。

进程嗅探（可选）。即使未安装钩子，守护进程在检测到已知智能体二进制文件运行时，也可自动获取断言。

合盖提示音 + 开盖摘要。合盖时（屏幕已关闭，故无通知）会发出提示音确认断言已持有；重新开盖时则显示您离开期间运行的内容、峰值温度以及过热切断是否触发。

干净卸载。移除其在所有智能体配置中添加的每条钩子条目。

系统要求

macOS Tahoe 26.4。这是本人构建和测试所用的版本；它很可能也能在更早的 26.x 版本上运行，但本人尚未在这些版本上测试过。

需 Xcode 26+ 进行构建，并启用 Swift 6 严格并发。

标准安装需要管理员权限（特权助手通过 SMAppService 安装）。非管理员安装路径会将 CLI 放置于 ~/.local/bin 而非 /usr/local/bin。

下载

下载 Adrafinil —— 一份已签名并公证的磁盘映像。打开它，将 Adrafinil 拖入"应用程序"文件夹，然后启动。首次启动时会请求一次管理员权限以注册特权助手。需 macOS 26.4 或更高版本。

更倾向于自行构建？请参阅"构建"部分。

构建

git clone https://github.com/kageroumado/adrafinil.git cd adrafinil open Adrafinil.xcodeproj

在 Xcode 中，选择 Adrafinil 方案并运行。您需要设置一个开发团队用于代码签名——守护进程（LaunchAgent）和助手（LaunchDaemon）嵌入到应用包中，并在应用启动时向系统注册。（源代码中未内置团队 ID；XPC 调用方检查会在运行时读取您自己的签名团队，因此使用任何开发者 ID 重新构建后，其自身组件无需修改代码即可获得授权。）

如需在本地无签名身份的情况下进行无界面编译检查：

xcodebuild -project Adrafinil.xcodeproj -scheme Adrafinil -configuration Debug \ -destination 'generic/platform=macOS' \ CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY='' build

共享逻辑作为 Swift 包独立构建和测试：

cd AdrafinilShared swift test

工作原理

智能体不会直接与 Adrafinil 通信。每个智能体的钩子系统会调用捆绑的 CLI：

adrafinil acquire <session-key> --tool claude-code --reason "long build" # when a turn starts adrafinil release <session-key> # when the agent goes idle

保持锁定的作用域是活动级别，而非会话级别：Claude Code 在用户提交提示词时获取锁定，在停止时释放锁定，因此 Mac 仅在智能体实际工作时保持唤醒状态——如果会话处于打开但空闲的提示词等待状态，Mac 可以正常休眠。

守护进程按会话键进行引用计数，并在计数非零时请求辅助程序阻止休眠。

智能体也可以通过限时锁定，让 Mac 在后台任务（如长时间构建或部署）期间保持唤醒状态，即使该任务超出了其回复的生存周期——方法是直接调用 `adrafinil hold`，或者对于支持 MCP 的智能体，通过 Adrafinil 的 `adrafinil mcp serve` 提供的捆绑 MCP 工具来实现：

adrafinil hold --for 30m --reason "deploy" # keep awake up to 30 min, then auto-release adrafinil mcp # speak the Model Context Protocol on stdio (for agents)

其他子命令：status、install-hooks、uninstall-hooks、daemon-status、version。

架构

四个产品，分属三个权限层级（完整细节，包括 Xcode 项目布局，见 Docs/ARCHITECTURE.md）：

┌──────────────────────────────────────────────────────────────┐ │ Adrafinil.app (menu bar app, user-facing) │ │ • Status item, settings, installer GUI, lid-open summary │ └─────────────────────────────┬────────────────────────────────┘ │ XPC ▼ ┌──────────────────────────────────────────────────────────────┐ │ AdrafinilDaemon (LaunchAgent, runs as user, always-on) │ │ • Reference-counted assertion registry │ │ • Process watchers (kqueue NOTE_EXIT + periodic sweep) │ │ • Thermal monitor (SMC) • Lid-state monitor (IORegistry) │ │ • Lid-close chime • CLI socket at …/Adrafinil/cli.sock │ └─────────────────────────────┬────────────────────────────────┘ │ XPC (privileged Mach service) ▼ ┌──────────────────────────────────────────────────────────────┐ │ AdrafinilHelper (SMAppService LaunchDaemon, root) │ │ • The ONLY component that touches sleep-blocking APIs │ │ • setSleepBlocked(Bool) + read-only state/version │ │ • Verifies caller's code-signing requirement │ └──────────────────────────────────────────────────────────────┘

adrafinil (CLI, ships inside the .app, symlinked onto PATH) • acquire / release / hold / mcp / status / install-hooks / uninstall-hooks • Connects to the daemon socket; <50ms round-trip

AdrafinilShared —— 一个在所有目标间共享的 Swift 包：包含数据模型（AgentKind、Assertion）、IPC 线格式、AssertionRegistry、CallerVerifier、钩子安装规范以及 CLI 参数解析器。单元测试也位于此包中。

辅助程序保持极简，便于审计。它不持有任何策略——引用计数、温度、空闲和屏幕开合逻辑全部位于守护进程中。其特权接口仅包含一个可变端点以及只读内省功能。

守护进程是数据权威来源。应用是纯粹的视图层；它可以自由退出和重新启动，而不会影响已持有的断言。

值得了解的注意事项

公共 IOPM 断言无法阻止合盖休眠。使用公共类型（以及 `caffeinate` 命令）的 `IOPMAssertionCreateWithName` 无法让合上屏幕的 Mac 保持唤醒。Adrafinil 的 v1 版本使用 `pmset disablesleep 1`，这种方法比较粗暴（它也会禁用空闲休眠），并且必须在关机前清除，否则会泄漏——辅助程序在重新启动时会先重置为 `disablesleep 0`，然后再重新应用状态。

守护进程的处理程序在任意队列上运行。XPC 和套接字回调可能到达任何调度队列，因此断言注册表和共享状态会相应地进行同步。在修改守护进程时，需谨慎处理并发问题。

CLI 有严格的延迟预算。acquire/release 操作位于每个智能体会话的热路径上，因此采用静态查找（例如 `AgentKind.allBinaryNames`）以及一个精简的套接字协议（而非完整的 XPC）来实现 CLI 与守护进程之间的通信。

许可证

MIT 许可证。你可以随意使用，不提供任何担保。

致谢

由 @kageroumado 构建，发布于 kagerou.glass。其名称灵感来源于阿屈非尼（adrafinil）——一种促进觉醒的前体药物——因为这款应用只会在机器确实有任务需要处理时，才保持其唤醒状态。

关于

仅在 AI 编程智能体工作时，让你的 Mac 保持唤醒状态

kagerou.glass/adrafinil/
