feat(daemon): launchd plist + install/uninstall 脚本(tsk_nqvOyIZkd1Dn)

提供三个文件让 maestrod 作为 macOS User Agent 开机自启、崩溃自拉:

- scripts/com.maestro.maestrod.plist  — launchd plist 模板
    KeepAlive=true(崩溃自拉)、RunAtLoad=true(登录即启)
    stdout+stderr 统一写入 ~/.maestro/maestrod.log
    ThrottleInterval=10s 防崩溃风暴;ProcessType=Background
    占位符:__NODE__ / __PROJ_DIR__ / __HOME__ / __PATH__

- scripts/install-daemon.sh  — 安装脚本
    1. 检测 node(>= 20)
    2. npm run build 构建项目
    3. sed 替换占位符,生成真实 plist 并用 plutil 校验
    4. launchctl bootstrap gui/$UID(回退 load -w)加载服务

- scripts/uninstall-daemon.sh  — 卸载脚本
    launchctl bootout / unload -w 卸载,删除 plist

shellcheck 通过(两个脚本);现有 77 个单元测试全部通过。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-13 09:24:04 +08:00
parent fcca3f95e0
commit 2c4140a1a2
3 changed files with 230 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
maestrod launchd User Agent 模板
============================================================
此文件为模板,占位符由 install-daemon.sh 在安装时替换后写入:
~/Library/LaunchAgents/com.maestro.maestrod.plist
占位符说明:
__NODE__ - node 可执行文件的绝对路径(如 /opt/homebrew/bin/node
__PROJ_DIR__ - 项目根目录绝对路径
__HOME__ - 用户家目录绝对路径
__PATH__ - 环境变量 PATH(含 node 所在目录)
管理命令:
安装/重装:bash scripts/install-daemon.sh
卸载: bash scripts/uninstall-daemon.sh
查看状态: launchctl list com.maestro.maestrod
实时日志: tail -f ~/.maestro/maestrod.log
-->
<plist version="1.0">
<dict>
<!-- 服务标识符,必须全局唯一 -->
<key>Label</key>
<string>com.maestro.maestrod</string>
<!-- 启动命令:node <项目>/dist/daemon/index.js -->
<key>ProgramArguments</key>
<array>
<string>__NODE__</string>
<string>__PROJ_DIR__/dist/daemon/index.js</string>
</array>
<!-- 崩溃 / 退出后自动拉起 -->
<key>KeepAlive</key>
<true/>
<!-- 用户登录后立即启动(开机常驻) -->
<key>RunAtLoad</key>
<true/>
<!-- 日志:stdout + stderr 合并写入同一文件 -->
<key>StandardOutPath</key>
<string>__HOME__/.maestro/maestrod.log</string>
<key>StandardErrorPath</key>
<string>__HOME__/.maestro/maestrod.log</string>
<!-- 工作目录 -->
<key>WorkingDirectory</key>
<string>__PROJ_DIR__</string>
<!-- 最小运行环境(launchd 默认环境极简,HOME/PATH 必须显式注入) -->
<key>EnvironmentVariables</key>
<dict>
<key>HOME</key>
<string>__HOME__</string>
<key>PATH</key>
<string>__PATH__</string>
</dict>
<!-- 两次崩溃拉起之间的最短冷却时间(秒),防止崩溃风暴 -->
<key>ThrottleInterval</key>
<integer>10</integer>
<!-- 标记为后台进程 -->
<key>ProcessType</key>
<string>Background</string>
</dict>
</plist>