MindOS_CLI/mindcli/service.py
lidf 69dd868e2f init: MindOS CLI 本地执行体(从 mindOSv2/mindos-cli 独立)
- 独立 pyproject.toml(pip install -e .)
- vendor_hermes.sh 已改为显式路径模式(不再依赖相对目录)
- 包含 hermes vendor 快照
2026-04-28 13:12:54 +08:00

117 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Mind CLI — macOS Service 注册。
通过 launchd plist 实现 `mind start` 开机自启。
"""
import os
import platform
import shutil
import subprocess
import sys
import textwrap
_LABEL = "club.brainwork.mindcli"
_PLIST_DIR = os.path.expanduser("~/Library/LaunchAgents")
_PLIST_PATH = os.path.join(_PLIST_DIR, f"{_LABEL}.plist")
_LOG_PATH = os.path.expanduser("~/Library/Logs/mindcli.log")
def _find_mind_executable() -> str:
"""定位 mind 可执行文件路径。"""
# 优先使用 which
result = shutil.which("mind")
if result:
return result
# 回退:当前 Python 的 scripts 目录
scripts_dir = os.path.join(os.path.dirname(sys.executable), "mind")
if os.path.isfile(scripts_dir):
return scripts_dir
raise FileNotFoundError(
"找不到 mind 可执行文件。请确认已运行 `pip install -e .` 安装 mindos-cli。"
)
def install_service() -> None:
"""
注册 Mind CLI 为 macOS launchd 服务。
生成 plist → launchctl load → 开机自启。
"""
if platform.system() != "Darwin":
print("⚠️ install-service 目前仅支持 macOS。")
print(" Linux 用户请手动创建 systemd unit。")
return
mind_path = _find_mind_executable()
os.makedirs(_PLIST_DIR, exist_ok=True)
plist_content = textwrap.dedent(f"""\
<?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">
<plist version="1.0">
<dict>
<key>Label</key>
<string>{_LABEL}</string>
<key>ProgramArguments</key>
<array>
<string>{mind_path}</string>
<string>start</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>{_LOG_PATH}</string>
<key>StandardErrorPath</key>
<string>{_LOG_PATH}</string>
<key>ThrottleInterval</key>
<integer>10</integer>
</dict>
</plist>
""")
with open(_PLIST_PATH, "w") as f:
f.write(plist_content)
# launchctl load
subprocess.run(["launchctl", "load", _PLIST_PATH], check=True)
print(f"✅ Mind CLI 已注册为 launchd 服务")
print(f" Plist: {_PLIST_PATH}")
print(f" Log: {_LOG_PATH}")
print(f" Binary: {mind_path}")
print(f"\n 服务将在登录时自动启动。")
print(f" 手动启动launchctl start {_LABEL}")
print(f" 手动停止launchctl stop {_LABEL}")
def uninstall_service() -> None:
"""
注销 Mind CLI launchd 服务。
launchctl unload → 删除 plist。
"""
if platform.system() != "Darwin":
print("⚠️ uninstall-service 目前仅支持 macOS。")
return
if not os.path.isfile(_PLIST_PATH):
print(f"⚠️ 未找到 plist: {_PLIST_PATH}")
print(f" Mind CLI 可能未注册为服务。")
return
subprocess.run(["launchctl", "unload", _PLIST_PATH], check=False)
os.remove(_PLIST_PATH)
print(f"✅ Mind CLI 服务已注销")
print(f" 已删除: {_PLIST_PATH}")